From a818e07b64c6e0e0a8e1b984223617bd1ff43fba Mon Sep 17 00:00:00 2001 From: Nick Clemens Date: Tue, 26 Sep 2023 17:29:28 +0000 Subject: [PATCH] Bug 34924: Handle final renewal errors This patch updates Koha::Checkout->attempt_auto_renew to renew when the 'final' errors are passed, and to pass the error value back to the cronjob for processing The sample notice for AUTO_RENEW and AUTO_RENEW_DGST are both updated to handle the new error On the next cron the error will be updated to too_many or too_unseen, but a notice will not be sent. To test: 0 - Run reset_all to install the updated sample notices or copy the text 1 - Set system preference UnseenRenewals to 'Allow' 2 - Setup a circ rule to allow 2 renewals, 2 unseen renewals 3 - Checkout an item to a patron who has an email defined and auto renewals selected in messaging preferences 4 - Update the issue to be due/overdue: UPDATE issues SET date_due=DATE_SUB(NOW(), INTERVAL 1 DAYS); 5 - perl misc/cronjobs/automatic_renewals.pl -v -c 6 - Confirm patron notified and issue renewed 7 - Set issue due/overdue again 8 - perl misc/cronjobs/automatic_renewals.pl -v -c 9 - Confirm patron notified of final unseen renewal 10 - perl misc/cronjobs/automatic_renewals.pl -v -c 11 - Confirm issue not renewed, patron not notified 12 - Update circ rules t all 4 renewals total 13 - Force renewal on staff side to clear unseen 14 - perl misc/cronjobs/automatic_renewals.pl -v -c 15 - Confirm patron notified of final renewal (allowed 4, 2 unseen from cron, 1 manual, this unseen from cron) 16 - perl misc/cronjobs/automatic_renewals.pl -v -c 17 - Confirm patron not notified, issue not renewed Signed-off-by: Martin Renvoize Signed-off-by: Emily Lamancusa --- Koha/Checkout.pm | 15 +++++-- .../mysql/en/mandatory/sample_notices.yml | 12 ++++++ t/db_dependent/Koha/Checkouts.t | 39 +++++++++++++++++-- 3 files changed, 59 insertions(+), 7 deletions(-) diff --git a/Koha/Checkout.pm b/Koha/Checkout.pm index dab86db7b2..a63ec71ab8 100644 --- a/Koha/Checkout.pm +++ b/Koha/Checkout.pm @@ -168,7 +168,8 @@ sub attempt_auto_renew { # CanBookBeRenewed returns 'auto_renew' when the renewal should be done by this script my ( $ok, $error ) = C4::Circulation::CanBookBeRenewed( $self->patron, $self, undef, 1 ); - if ( $error eq 'auto_renew' ) { + my $store_error; + if ( $error eq 'auto_renew' || $error eq 'auto_renew_final' || $error eq 'auto_unseen_final' ) { if ($confirm) { my $date_due = C4::Circulation::AddRenewal( { @@ -179,14 +180,20 @@ sub attempt_auto_renew { automatic => 1, } ); - $self->auto_renew_error(undef)->store; + $store_error = $error eq 'auto_renew' ? undef : $error; + $self->auto_renew_error($store_error)->store; } - return ( 1, undef, 1 ); + return ( 1, $store_error, 1 ); } else { my $updated = 0; if ( !$self->auto_renew_error || $error ne $self->auto_renew_error ) { + $updated = 1 + unless ( + $self->auto_renew_error + && ( $self->auto_renew_error eq 'auto_renew_final' && $error eq 'too_many' + || $self->auto_renew_error eq 'auto_unseen_final' && $error eq 'too_unseen' ) + ); $self->auto_renew_error($error)->store if $confirm; - $updated = 1; } return ( 0, $error, $updated ); } diff --git a/installer/data/mysql/en/mandatory/sample_notices.yml b/installer/data/mysql/en/mandatory/sample_notices.yml index 3410210476..9b0880679d 100644 --- a/installer/data/mysql/en/mandatory/sample_notices.yml +++ b/installer/data/mysql/en/mandatory/sample_notices.yml @@ -2163,6 +2163,12 @@ tables: - "This item must be renewed at the library." - "[% ELSIF checkout.auto_renew_error == 'auto_account_expired' %]" - "Your account has expired." + - "[% ELSIF checkout.auto_renew_error == 'auto_renew_final' %]" + - "The following item, [% biblio.title %], has correctly been renewed and is now due on [% checkout.date_due | $KohaDates as_due_date => 1 %]" + - "This item has reached the maximum number of automatic renewals and will no longer be renewed." + - "[% ELSIF checkout.auto_renew_error == 'auto_unseen_final' %]" + - "The following item, [% biblio.title %], has correctly been renewed and is now due on [% checkout.date_due | $KohaDates as_due_date => 1 %]" + - "This item has reached the maximum number of unseen renewals and will need to be renewed at the library." - "[% END %]" - "[% ELSE %]" - "The following item, [% biblio.title %], has correctly been renewed and is now due on [% checkout.date_due | $KohaDates as_due_date => 1 %]" @@ -2237,6 +2243,12 @@ tables: - "Your total unpaid fines are too high." - "[% ELSIF checkout.auto_renew_error == 'too_unseen' %]" - "This item must be renewed at the library." + - "[% ELSIF checkout.auto_renew_error == 'auto_renew_final' %]" + - "was renewed until [% checkout.date_due | $KohaDates as_due_date => 1%]" + - "This item has reached the maximum number of automatic renewals and will no longer be renewed." + - "[% ELSIF checkout.auto_renew_error == 'auto_unseen_final' %]" + - "was renewed until [% checkout.date_due | $KohaDates as_due_date => 1%]" + - "This item has reached the maximum number of unseen renewals and will need to be renewed at the library." - "[% END %]" - "[% END %]" diff --git a/t/db_dependent/Koha/Checkouts.t b/t/db_dependent/Koha/Checkouts.t index 35ab5214ce..d696aca921 100755 --- a/t/db_dependent/Koha/Checkouts.t +++ b/t/db_dependent/Koha/Checkouts.t @@ -487,15 +487,14 @@ subtest 'automatic_checkin' => sub { subtest 'attempt_auto_renew' => sub { - plan tests => 17; + plan tests => 33; $schema->storage->txn_begin; my $renew_error = 'auto_renew'; my $module = Test::MockModule->new('C4::Circulation'); $module->mock( 'CanBookBeRenewed', sub { return ( 1, $renew_error ) } ); - my $around_now = dt_from_string(); - $module->mock( 'AddRenewal', sub { warn "AddRenewal called" } ); + $module->mock( 'AddRenewal', sub { warn "AddRenewal called" } ); my $checkout = $builder->build_object( { class => 'Koha::Checkouts', @@ -527,6 +526,8 @@ subtest 'attempt_auto_renew' => sub { is( $error, undef, "No error when renewed" ); ok( $updated, "Issue reported as updated when renewed" ); + $module->mock( 'AddRenewal', sub { return; } ); + $renew_error = 'anything_else'; ( $success, $error, $updated ) = $checkout->attempt_auto_renew(); ok( !$success, "Success is untrue for any other status" ); @@ -546,5 +547,37 @@ subtest 'attempt_auto_renew' => sub { ( $success, $error, $updated ) = $checkout->attempt_auto_renew(); ok( !$updated, "Issue not reported as updated when status has not changed" ); + $renew_error = "auto_unseen_final"; + ( $success, $error, $updated ) = $checkout->attempt_auto_renew( { confirm => 1 } ); + ok( $success, "Issue is renewed when error is 'auto_unseen_final'" ); + is( $error, 'auto_unseen_final', "Error of finality reported when renewed" ); + ok( $updated, "Issue reported as updated when renewed" ); + $checkout->discard_changes(); + is( $checkout->auto_renew_error, 'auto_unseen_final', "Error updated" ); + + $renew_error = "too_unseen"; + ( $success, $error, $updated ) = $checkout->attempt_auto_renew( { confirm => 1 } ); + ok( !$success, "Issue is not renewed when error is 'too_unseen'" ); + is( $error, 'too_unseen', "Error reported correctly" ); + ok( !$updated, "Issue not reported as updated when moved from final to too unseen" ); + $checkout->discard_changes(); + is( $checkout->auto_renew_error, 'too_unseen', "Error updated" ); + + $renew_error = "auto_renew_final"; + ( $success, $error, $updated ) = $checkout->attempt_auto_renew( { confirm => 1 } ); + ok( $success, "Issue is renewed when error is 'auto_renew_final'" ); + is( $error, 'auto_renew_final', "Error of finality reported when renewed" ); + ok( $updated, "Issue reported as updated when renewed" ); + $checkout->discard_changes(); + is( $checkout->auto_renew_error, 'auto_renew_final', "Error updated" ); + + $renew_error = "too_many"; + ( $success, $error, $updated ) = $checkout->attempt_auto_renew( { confirm => 1 } ); + ok( !$success, "Issue is not renewed when error is 'too_many'" ); + is( $error, 'too_many', "Error reported correctly" ); + ok( !$updated, "Issue not reported as updated when moved from final to too many" ); + $checkout->discard_changes(); + is( $checkout->auto_renew_error, 'too_many', "Error updated" ); + $schema->storage->txn_rollback; }; -- 2.34.1