From 06fb80f42abee1b140bd39cde8cce193e084023b Mon Sep 17 00:00:00 2001 From: Jonathan Druart Date: Wed, 13 Jan 2016 19:17:49 +0000 Subject: [PATCH] Bug 15581: Add a circ rule to limit the auto renewals given a delay This patch adds a new circulation rule (no_auto_renewal_after) to block/allow auto renewals after a given delay. For instance, if the issue date is 10 days before today, and no_auto_renewal_after is set to 10, tomorrow the issue won't be auto renewed. Test plan: 0/ Execute the update DB entry Note: You will have to manually change data in your DB, make sure you have access to the sql cli. 1/ Define a rule with no_auto_renewal_after (10 for instance) and norenewalbefore (5 for instance). (This new rule will behave the same as norenewalbefore: the unit depends on the lengthunit value). The automatic renewals will be done from 5 to 10 days ahead. 2/ Modify the issues.issuedate, to simulate a checkout in the past: UPDATE issues SET issuedate = "yyyy-mm-dd hh:mm:ss" WHERE itemnumber = YOUR_ITEMNUMBER; with issuedate = 2 days before for instance 3/ Execute the automatic renewals cronjob script (misc/cronjobs/automatic_renewals.pl) Confirm that the issue has not been renewed (too soon) 4/ Repeat step 2 with a due date set as 11 days before 5/ Execute the automatic renewals cronjob script (misc/cronjobs/automatic_renewals.pl) Confirm that the issue has not been renewed (too late) 6/ Repeat step 2 with a due date set as 7 days before 7/ Execute the automatic renewals cronjob script (misc/cronjobs/automatic_renewals.pl) Confirm that the issue has been renewed (issues.renewals has been incremented and date_due has been updated according your circ rules). Sponsored-by: University of the Arts London Signed-off-by: Jonathan Field --- C4/Circulation.pm | 18 ++++++++- admin/smart-rules.pl | 3 ++ installer/data/mysql/atomicupdate/bug_15581.sql | 1 + installer/data/mysql/kohastructure.sql | 1 + .../prog/en/modules/admin/smart-rules.tt | 4 ++ .../intranet-tmpl/prog/en/modules/circ/renew.tt | 12 ++++++ t/db_dependent/Circulation.t | 43 +++++++++++++++++++++- 7 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 installer/data/mysql/atomicupdate/bug_15581.sql diff --git a/C4/Circulation.pm b/C4/Circulation.pm index b2a4802..1b4179c 100644 --- a/C4/Circulation.pm +++ b/C4/Circulation.pm @@ -2984,6 +2984,22 @@ sub CanBookBeRenewed { return ( 0, 'overdue'); } + if ( $itemissue->{auto_renew} + and defined $issuingrule->{no_auto_renewal_after} + and $issuingrule->{no_auto_renewal_after} ne "" ) { + + # Get issue_date and add no_auto_renewal_after + # If this is greater than today, it's too late for renewal. + my $maximum_renewal_date = dt_from_string($itemissue->{issuedate}); + $maximum_renewal_date->add( + $issuingrule->{lengthunit} => $issuingrule->{no_auto_renewal_after} + ); + my $now = dt_from_string; + if ( $now >= $maximum_renewal_date ) { + return ( 0, "auto_too_late" ); + } + } + if ( defined $issuingrule->{norenewalbefore} and $issuingrule->{norenewalbefore} ne "" ) { @@ -3013,7 +3029,7 @@ sub CanBookBeRenewed { # Fallback for automatic renewals: # If norenewalbefore is undef, don't renew before due date. - elsif ( $itemissue->{auto_renew} ) { + if ( $itemissue->{auto_renew} ) { my $now = dt_from_string; return ( 0, "auto_renew" ) if $now >= $itemissue->{date_due}; diff --git a/admin/smart-rules.pl b/admin/smart-rules.pl index 9d2d0fd..52b3e18 100755 --- a/admin/smart-rules.pl +++ b/admin/smart-rules.pl @@ -136,6 +136,8 @@ elsif ($op eq 'add') { my $norenewalbefore = $input->param('norenewalbefore'); $norenewalbefore = undef if $norenewalbefore =~ /^\s*$/; my $auto_renew = $input->param('auto_renew') eq 'yes' ? 1 : 0; + my $no_auto_renewal_after = $input->param('no_auto_renewal_after'); + $no_auto_renewal_after = undef if $no_auto_renewal_after =~ /^\s*$/; my $reservesallowed = $input->param('reservesallowed'); my $onshelfholds = $input->param('onshelfholds') || 0; $maxissueqty =~ s/\s//g; @@ -171,6 +173,7 @@ elsif ($op eq 'add') { renewalperiod => $renewalperiod, norenewalbefore => $norenewalbefore, auto_renew => $auto_renew, + no_auto_renewal_after => $no_auto_renewal_after, reservesallowed => $reservesallowed, issuelength => $issuelength, lengthunit => $lengthunit, diff --git a/installer/data/mysql/atomicupdate/bug_15581.sql b/installer/data/mysql/atomicupdate/bug_15581.sql new file mode 100644 index 0000000..8548968 --- /dev/null +++ b/installer/data/mysql/atomicupdate/bug_15581.sql @@ -0,0 +1 @@ +ALTER TABLE issuingrules ADD COLUMN no_auto_renewal_after INT(4) DEFAULT NULL AFTER auto_renew; diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql index ded442c..208576b 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -858,6 +858,7 @@ CREATE TABLE `issuingrules` ( -- circulation and fine rules `renewalperiod` int(4) default NULL, -- renewal period in the unit set in issuingrules.lengthunit `norenewalbefore` int(4) default NULL, -- no renewal allowed until X days or hours before due date. `auto_renew` BOOLEAN default FALSE, -- automatic renewal + `no_auto_renewal_after` int(4) default NULL, -- no auto renewal allowed after X days or hours after the issue date `reservesallowed` smallint(6) NOT NULL default "0", -- how many holds are allowed `branchcode` varchar(10) NOT NULL default '', -- the branch this rule is for (branches.branchcode) overduefinescap decimal(28,6) default NULL, -- the maximum amount of an overdue fine diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt index 8d197af..c13087d 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/smart-rules.tt @@ -176,6 +176,7 @@ for="tobranch">Clone these rules to: Clone these rules to: Clone these rules to: Yes + [% item.biblio.title %] [% item.biblioitem.subtitle %] ( [% item.barcode %] ) has been scheduled for automatic renewal and cannot be renewed since [% latestrenewdate | $KohaDates %].

+ + [% IF Koha.Preference('AllowRenewalLimitOverride') %] +
+ + + +
+ [% END %] + [% ELSIF error == "auto_renew" %]

[% item.biblio.title %] [% item.biblioitem.subtitle %] ( [% item.barcode %] ) has been scheduled for automatic renewal.

diff --git a/t/db_dependent/Circulation.t b/t/db_dependent/Circulation.t index f06e4d5..79ab901 100755 --- a/t/db_dependent/Circulation.t +++ b/t/db_dependent/Circulation.t @@ -30,7 +30,7 @@ use Koha::Database; use t::lib::TestBuilder; -use Test::More tests => 86; +use Test::More tests => 87; BEGIN { use_ok('C4::Circulation'); @@ -532,6 +532,47 @@ C4::Context->dbh->do("DELETE FROM accountlines"); 'Bug 14101: Cannot renew, renewal is automatic (returned code is auto_renew)' ); + subtest "too_late_renewal / no_auto_renewal_after" => sub { + plan tests => 8; + my $item_to_auto_renew = $builder->build( + { source => 'Item', + value => { + biblionumber => $biblionumber, + homebranch => $branch, + holdingbranch => $branch, + } + } + ); + + my $ten_days_before = dt_from_string->add( days => -10 ); + my $ten_days_ahead = dt_from_string->add( days => 10 ); + AddIssue( $renewing_borrower, $item_to_auto_renew->{barcode}, $ten_days_ahead, undef, $ten_days_before, undef, { auto_renew => 1 } ); + + $dbh->do('UPDATE issuingrules SET norenewalbefore = 7, no_auto_renewal_after = 9'); + ( $renewokay, $error ) = + CanBookBeRenewed( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} ); + is( $renewokay, 0, 'Do not renew, renewal is automatic' ); + is( $error, 'auto_too_late', 'Cannot renew, too late(returned code is auto_too_late)' ); + + $dbh->do('UPDATE issuingrules SET norenewalbefore = 7, no_auto_renewal_after = 10'); + ( $renewokay, $error ) = + CanBookBeRenewed( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} ); + is( $renewokay, 0, 'Do not renew, renewal is automatic' ); + is( $error, 'auto_too_late', 'Cannot auto renew, too late - no_auto_renewal_after is inclusive(returned code is auto_too_late)' ); + + $dbh->do('UPDATE issuingrules SET norenewalbefore = 7, no_auto_renewal_after = 11'); + ( $renewokay, $error ) = + CanBookBeRenewed( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} ); + is( $renewokay, 0, 'Do not renew, renewal is automatic' ); + is( $error, 'auto_too_soon', 'Cannot auto renew, too soon - no_auto_renewal_after is defined(returned code is auto_too_soon)' ); + + $dbh->do('UPDATE issuingrules SET norenewalbefore = 10, no_auto_renewal_after = 11'); + ( $renewokay, $error ) = + CanBookBeRenewed( $renewing_borrowernumber, $item_to_auto_renew->{itemnumber} ); + is( $renewokay, 0, 'Do not renew, renewal is automatic' ); + is( $error, 'auto_renew', 'Cannot renew, renew is automatic' ); + }; + # Too many renewals # set policy to forbid renewals -- 2.8.1