From fee6f09f5b6a3fba90486ac9d90bb072a27187f8 Mon Sep 17 00:00:00 2001 From: Kyle M Hall Date: Mon, 18 May 2020 13:32:45 -0400 Subject: [PATCH] Bug 25534: Add ability to send an email specifying a reason when canceling a hold Some libraries would like to be able to cancel a hold with the option to specify a reason. Providing a reason would generate an email to that patron. Test Plan: 1) Apply this patch 2) Run updatedatabase.pl 3) Restart all the things! 4) Create new AV category "HOLD_CANCELLATION", add some cancelation reasons 5) Add new Holds module notice "HOLD_CANCELLATION", add an email version. A quick test version would be "Reason: <>" 6) Place a hold for a patron 7) On request.pl, select the 'del' option for the hold, not the reason pulldown appears. 8) Select a reason and choose "Update hold(s)" 9) Note a new message has been queue for the patron with the cancelation reason 11) Test again from circulation.pl 12) Test again from moremember.pl 10) Cancel a hold with no reason, note no email is generated 11) Delete you authorised values, not the feature is disabled --- C4/Reserves.pm | 10 +++--- Koha/Hold.pm | 31 +++++++++++++++++++ .../prog/en/includes/holds_table.inc | 17 ++++++++-- .../prog/en/modules/circ/circulation.tt | 10 ++++++ .../prog/en/modules/members/moremember.tt | 10 ++++++ .../prog/en/modules/reserve/request.tt | 10 ++++++ reserve/modrequest.pl | 2 ++ 7 files changed, 83 insertions(+), 7 deletions(-) diff --git a/C4/Reserves.pm b/C4/Reserves.pm index 9f8d31637a..2614badf8e 100644 --- a/C4/Reserves.pm +++ b/C4/Reserves.pm @@ -970,6 +970,7 @@ sub ModReserve { my $suspend_until = $params->{'suspend_until'}; my $borrowernumber = $params->{'borrowernumber'}; my $biblionumber = $params->{'biblionumber'}; + my $cancellation_reason = $params->{'cancellation_reason'}; return if $rank eq "W"; return if $rank eq "n"; @@ -987,7 +988,7 @@ sub ModReserve { $hold ||= Koha::Holds->find($reserve_id); if ( $rank eq "del" ) { - $hold->cancel; + $hold->cancel({ cancellation_reason => $cancellation_reason }); } elsif ($rank =~ /^\d+/ and $rank > 0) { logaction( 'HOLDS', 'MODIFY', $hold->reserve_id, Dumper($hold->unblessed) ) @@ -1172,7 +1173,7 @@ sub ModReserveAffect { =head2 ModReserveCancelAll - ($messages,$nextreservinfo) = &ModReserveCancelAll($itemnumber,$borrowernumber); + ($messages,$nextreservinfo) = &ModReserveCancelAll($itemnumber,$borrowernumber,$reason); function to cancel reserv,check other reserves, and transfer document if it's necessary @@ -1181,12 +1182,13 @@ function to cancel reserv,check other reserves, and transfer document if it's ne sub ModReserveCancelAll { my $messages; my $nextreservinfo; - my ( $itemnumber, $borrowernumber ) = @_; + my ( $itemnumber, $borrowernumber, $cancellation_reason ) = @_; + warn "RESON: $cancellation_reason"; #step 1 : cancel the reservation my $holds = Koha::Holds->search({ itemnumber => $itemnumber, borrowernumber => $borrowernumber }); return unless $holds->count; - $holds->next->cancel; + $holds->next->cancel({ cancellation_reason => $cancellation_reason }); #step 2 launch the subroutine of the others reserves ( $messages, $nextreservinfo ) = GetOtherReserves($itemnumber); diff --git a/Koha/Hold.pm b/Koha/Hold.pm index 6896f5e94d..c8f6cf87f9 100644 --- a/Koha/Hold.pm +++ b/Koha/Hold.pm @@ -24,8 +24,10 @@ use Carp; use Data::Dumper qw(Dumper); use C4::Context qw(preference); +use C4::Letters; use C4::Log; +use Koha::AuthorisedValues; use Koha::DateUtils qw(dt_from_string output_pref); use Koha::Patrons; use Koha::Biblios; @@ -356,6 +358,7 @@ sub cancel { sub { $self->cancellationdate( dt_from_string->strftime( '%Y-%m-%d %H:%M:%S' ) ); $self->priority(0); + $self->cancellation_reason( $params->{cancellation_reason} ); $self->_move_to_old; $self->SUPER::delete(); # Do not add a DELETE log @@ -379,6 +382,34 @@ sub cancel { ); } + if ( $params->{cancellation_reason} ) { + my $letter = C4::Letters::GetPreparedLetter( + module => 'reserves', + letter_code => 'HOLD_CANCELLATION', + message_transport_type => 'email', + branchcode => $self->borrower->branchcode, + lang => $self->borrower->lang, + tables => { + branches => $self->borrower->branchcode, + borrowers => $self->borrowernumber, + items => $self->itemnumber, + biblio => $self->biblionumber, + biblioitems => $self->biblionumber, + reserves => $self->unblessed, + } + ); + + if ($letter) { + C4::Letters::EnqueueLetter( + { + letter => $letter, + borrowernumber => $self->borrowernumber, + message_transport_type => 'email', + } + ); + } + } + C4::Log::logaction( 'HOLDS', 'CANCEL', $self->reserve_id, Dumper($self->unblessed) ) if C4::Context->preference('HoldsLog'); } diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/holds_table.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/holds_table.inc index a10e281d3b..1aca64d09f 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/includes/holds_table.inc +++ b/koha-tmpl/intranet-tmpl/prog/en/includes/holds_table.inc @@ -1,4 +1,6 @@ [% USE Koha %] +[% USE AuthorisedValues %] +[% SET hold_cancellation = AuthorisedValues.GetAuthValueDropbox('HOLD_CANCELLATION') %] [% IF ( CAN_user_reserveforothers_modify_holds_priority ) %] @@ -31,10 +33,10 @@ [% IF Koha.Preference('HoldsSplitQueue') == "nothing" && !hold.found %] - [% ELSE %] - - + + + [% IF hold_cancellation %] + + [% END %] [% IF ( CAN_user_reserveforothers_modify_holds_priority ) %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt index b8ec599508..1845f0012a 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt @@ -939,6 +939,16 @@
+ + [% SET hold_cancellation = AuthorisedValues.GetAuthValueDropbox('HOLD_CANCELLATION') %] + [% IF hold_cancellation %] + + [% END %]
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt index a6016d68d1..68370a176a 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt @@ -819,6 +819,16 @@
+ + [% SET hold_cancellation = AuthorisedValues.GetAuthValueDropbox('HOLD_CANCELLATION') %] + [% IF hold_cancellation %] + + [% END %]
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt index 2f5f0ebdb7..4ff7245b29 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt @@ -961,6 +961,16 @@ columns_settings_borrowers_table = [% ColumnsSettings.GetColumns( 'circ', 'circulation', 'table_borrowers', 'json' ) | $raw %] $(document).ready(function() { + $(".cancellation-reason").hide(); + $(".rank-request").on("change", function(){ + const reserve_id = $(this).data('hold-id'); + if ( $(this).val() == "del" ) { + $(`#cancellation-reason-${reserve_id}`).show(); + } else { + $(`#cancellation-reason-${reserve_id}`).hide(); + } + }); + [% SET active = clubs ? 1 : 0 %] $('#circ_holds_select').tabs({ active: [% active | $raw %], diff --git a/reserve/modrequest.pl b/reserve/modrequest.pl index 6c134efe3a..f4bc708e2b 100755 --- a/reserve/modrequest.pl +++ b/reserve/modrequest.pl @@ -71,6 +71,7 @@ else { for (my $i=0;$i<$count;$i++){ undef $itemnumber[$i] if !$itemnumber[$i]; my $suspend_until = $query->param( "suspend_until_" . $reserve_id[$i] ); + my $cancellation_reason = $query->param("cancellation-reason-$reserve_id[$i]") || $query->param("cancellation-reason"); my $params = { rank => $rank[$i], reserve_id => $reserve_id[$i], @@ -78,6 +79,7 @@ else { branchcode => $branch[$i], itemnumber => $itemnumber[$i], defined $suspend_until ? ( suspend_until => $suspend_until ) : (), + cancellation_reason => $cancellation_reason, }; if (C4::Context->preference('AllowHoldDateInFuture')) { $params->{reservedate} = $reservedates[$i] ? dt_from_string($reservedates[$i]) : undef; -- 2.24.2 (Apple Git-127)