From 9a113663820634d2d718c8a979e8e70f64b8744a Mon Sep 17 00:00:00 2001 From: Martin Renvoize Date: Thu, 22 Oct 2020 16:26:03 +0100 Subject: [PATCH] Bug 12656: Allow --reason to be passed to cancel_expired_holds This patch adds the --reason option to cancel_expired_holds which allows the library to optionally set a reason for cancellation when running the cronjob. This will prompt the HOLD_CANCELLED notice to be sent to the patron. To test: 1/ Ensure the unit tests continue to pass after the patch (t/db_dependent/Reserves/CancelExpiredReserves.t) Also: 1 - Add an expired hold for a patron: INSERT INTO RESERVES (borrowernumber, biblionumber, expirationdate, found,branchcode,itemnumber) VALUES (5,5,'2020-01-01','W','CPL',983); 2 - Set ExpireReservesMaxPickUpDelay to Allow 3 - Run the cronjob: perl misc/cronjobs/hold/cancel_expired_holds.pl --reason EXPIRED 4 - Visit the patron's notices tab 5 - Confirm they have been sent a cancellation notice Signed-off-by: Lisette Scheer Signed-off-by: Nick Clemens Signed-off-by: Jonathan Druart --- C4/Reserves.pm | 4 +- misc/cronjobs/holds/cancel_expired_holds.pl | 52 +++++++++++++++++-- .../Reserves/CancelExpiredReserves.t | 26 +++++++++- 3 files changed, 77 insertions(+), 5 deletions(-) diff --git a/C4/Reserves.pm b/C4/Reserves.pm index dabce115d2..1432501930 100644 --- a/C4/Reserves.pm +++ b/C4/Reserves.pm @@ -913,6 +913,7 @@ Cancels all reserves with an expiration date from before today. =cut sub CancelExpiredReserves { + my $cancellation_reason = shift; my $today = dt_from_string(); my $cancel_on_holidays = C4::Context->preference('ExpireReservesOnHolidays'); my $expireWaiting = C4::Context->preference('ExpireReservesMaxPickUpDelay'); @@ -930,7 +931,8 @@ sub CancelExpiredReserves { next if !$cancel_on_holidays && $calendar->is_holiday( $today ); my $cancel_params = {}; - if ( $hold->found eq 'W' ) { + $cancel_params->{cancellation_reason} = $cancellation_reason if defined($cancellation_reason); + if ( defined($hold->found) && $hold->found eq 'W' ) { $cancel_params->{charge_cancel_fee} = 1; } $hold->cancel( $cancel_params ); diff --git a/misc/cronjobs/holds/cancel_expired_holds.pl b/misc/cronjobs/holds/cancel_expired_holds.pl index 463c6b2ba5..4932bbf346 100755 --- a/misc/cronjobs/holds/cancel_expired_holds.pl +++ b/misc/cronjobs/holds/cancel_expired_holds.pl @@ -1,6 +1,7 @@ #!/usr/bin/perl # Copyright 2009-2010 Kyle Hall +# Copyright 2020 PTFS Europe # # This file is part of Koha. # @@ -17,7 +18,29 @@ # You should have received a copy of the GNU General Public License # along with Koha; if not, see . +=head1 NAME + +cancel_expired_holds.pl - cron script to cancel holds as they expire + +=head1 SYNOPSIS + + ./cancel_expired_holds.pl + ./cancel_expired_holds.pl --reason="EXPIRED" + +or, in crontab: + + 0 1 * * * cancel_expired_holds.pl + 0 1 * * * cancel_expired_holds.pl --reason="EXPIRED" + +=head1 DESCRIPTION + +This script calls C4::Reserves::CancelExpiredReserves which will find and cancel all expired reseves in the system. + +=cut + use Modern::Perl; +use Getopt::Long; +use Pod::Usage; BEGIN { # find Koha's Perl modules @@ -26,12 +49,35 @@ BEGIN { eval { require "$FindBin::Bin/../kohalib.pl" }; } -# cancel all expired hold requests - use Koha::Script -cron; use C4::Reserves; use C4::Log; +=head1 OPTIONS + +=over 8 + +=item B<--help> + +Print a brief help message and exits. + +=item B<--reason> + +Optionally adds a reason for cancellation (which will trigger a notice to be sent to the patron) + +=back + +=cut + +my $help = 0; +my $reason; + +GetOptions( + 'help|?' => \$help, + 'reason=s' => \$reason +) or pod2usage(1); +pod2usage(1) if $help; + cronlogaction(); -CancelExpiredReserves(); +CancelExpiredReserves($reason); diff --git a/t/db_dependent/Reserves/CancelExpiredReserves.t b/t/db_dependent/Reserves/CancelExpiredReserves.t index 51cb2b05c2..6822a04358 100755 --- a/t/db_dependent/Reserves/CancelExpiredReserves.t +++ b/t/db_dependent/Reserves/CancelExpiredReserves.t @@ -1,7 +1,7 @@ #!/usr/bin/perl use Modern::Perl; -use Test::More tests => 3; +use Test::More tests => 4; use t::lib::Mocks; use t::lib::TestBuilder; @@ -199,4 +199,28 @@ subtest 'Test handling of in transit reserves by CancelExpiredReserves' => sub { }; +subtest 'Test handling of cancellation reason if passed' => sub { + plan tests => 2; + + my $builder = t::lib::TestBuilder->new(); + + my $expdate = dt_from_string->add( days => -2 ); + my $reserve = $builder->build({ + source => 'Reserve', + value => { + expirationdate => '2018-01-01', + found => 'T', + cancellationdate => undef, + suspend => 0, + suspend_until => undef + } + }); + my $reserve_id = $reserve->{reserve_id}; + my $count = Koha::Holds->search->count; + CancelExpiredReserves("EXPIRED"); + is(Koha::Holds->search->count, $count-1, "Hold is cancelled when reason is passed"); + my $old_reserve = Koha::Old::Holds->find($reserve_id); + is($old_reserve->cancellation_reason, 'EXPIRED', "Hold cancellation_reason was set correctly"); +}; + $schema->storage->txn_rollback; -- 2.39.5