From af0d71b7479432aeaf65dd61225b0d20c84cd360 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: <>" -- [% USE AuthorisedValues %] Reason: [% AuthorisedValues.GetByCode( 'CANCELLATION_REASON', hold.cancellation_reason, 'IS_OPAC' ) %] [% IF hold.cancellation_reason == "MY_AV_VALUE" %] IF perhaps you'd like to have a much longer explanation than just the one sentence in the AV description, you can use IF blocks using Template Toolkit markup! [% END %] -- 6) Place a hold for a patron 7) On request.pl, select the 'del' option for the hold 8) Select a cancellation 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 your authorised values, not the feature is disabled 12) Reinstate the authorised values, but delete the notice, you should now be able to cancel a hold with a reason, but no email will be generated Signed-off-by: Andrew Fuerste-Henry Signed-off-by: Rebecca Coert Signed-off-by: Katrin Fischer Signed-off-by: Jonathan Druart --- C4/Reserves.pm | 9 ++--- Koha/Hold.pm | 33 +++++++++++++++++++ .../prog/en/includes/holds_table.inc | 8 +++-- .../prog/en/modules/circ/circulation.tt | 10 ++++++ .../prog/en/modules/members/moremember.tt | 10 ++++++ .../prog/en/modules/reserve/request.tt | 17 ++++++++++ reserve/modrequest.pl | 2 ++ 7 files changed, 82 insertions(+), 7 deletions(-) diff --git a/C4/Reserves.pm b/C4/Reserves.pm index 076b6f7baa..eb1a6f88f7 100644 --- a/C4/Reserves.pm +++ b/C4/Reserves.pm @@ -983,6 +983,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"; @@ -1000,7 +1001,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) ) @@ -1185,7 +1186,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 @@ -1194,12 +1195,12 @@ 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 ) = @_; #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 8969e32839..67e8d53757 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; @@ -365,6 +367,37 @@ 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->store(); + + 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', + } + ); + } + } + $self->_move_to_old; $self->SUPER::delete(); # Do not add a DELETE log 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 600977a054..53c87ba027 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 %] +[% SET hold_cancellation = AuthorisedValues.GetAuthValueDropbox('HOLD_CANCELLATION') %] +[% USE AuthorisedValues %] [% IF ( CAN_user_reserveforothers_modify_holds_priority ) %] @@ -31,10 +33,10 @@ [% IF Koha.Preference('HoldsSplitQueue') == "nothing" && !hold.found %] - [% ELSE %] - - + + + [% 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 38ab8d2562..e2c758486e 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt @@ -846,6 +846,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 e15d468fcc..dda14d2f85 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt @@ -909,6 +909,23 @@ [% END # /IF biblioloo.reserveloop %] [% END # FOREACH biblioloo %] +
+ [% SET hold_cancellation = AuthorisedValues.GetAuthValueDropbox('HOLD_CANCELLATION') %] + [% IF hold_cancellation %] + + + [% END %] +
+ +
+ +
+ [% END # IF reserveloop %] [% END # UNLESS patron %] diff --git a/reserve/modrequest.pl b/reserve/modrequest.pl index 6c134efe3a..83196ff33c 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"); 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.39.5