From f19853dd43e1ac89fe9a01b8b5d60dfe6f5f5368 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 --- C4/Letters.pm | 2 +- C4/Reserves.pm | 9 +++--- Koha/Hold.pm | 33 ++++++++++++++++++++++ .../intranet-tmpl/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 | 13 +++++++++ reserve/modrequest.pl | 2 ++ 8 files changed, 79 insertions(+), 8 deletions(-) diff --git a/C4/Letters.pm b/C4/Letters.pm index 1036c461f3..b6766891c2 100644 --- a/C4/Letters.pm +++ b/C4/Letters.pm @@ -1519,7 +1519,7 @@ sub _get_tt_params { module => 'Koha::Holds', singular => 'hold', plural => 'holds', - fk => [ 'borrowernumber', 'biblionumber' ], + pk => 'reserve_id', }, serial => { module => 'Koha::Serials', diff --git a/C4/Reserves.pm b/C4/Reserves.pm index 9f8d31637a..b2af4b6bd1 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,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 e8d9e0cc2c..62252b83d9 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,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 a10e281d3b..00b777c526 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 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..2da776f128 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt @@ -907,6 +907,19 @@ [% END # FOREACH biblioloo %]
+ [% SET hold_cancellation = AuthorisedValues.GetAuthValueDropbox('HOLD_CANCELLATION') %] + [% IF hold_cancellation %] + + + [% END %] +
+ +
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.11.0