From 590413127904dfa87f40210c4c7677f828845153 Mon Sep 17 00:00:00 2001 From: Jonathan Druart Date: Mon, 25 Apr 2016 21:52:27 +0100 Subject: [PATCH] Bug 16344: Add a circ rule to limit the auto renewals given a specific This patch adds a new circulation rule (no_auto_renewal_after_hard_limit) to block/allow auto renewals after a given date. The idea is to stop renewals at a given date. That way the library will have time to send overdues and get the books back before the students do on holiday. Test plan: 0/ Execute the update DB entry 1/ Define a rule with no_auto_renewal_after_hard_limit set to tomorrow 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 been renewed 4/ Modify the no_auto_renewal_after_hard_limit and set it to yesterday 5/ Execute the automatic renewals cronjob script (misc/cronjobs/automatic_renewals.pl) Confirm that the issue has not been renewed --- C4/Circulation.pm | 55 ++++++++++++++-------- admin/smart-rules.pl | 9 ++++ installer/data/mysql/atomicupdate/bug_16344.sql | 1 + installer/data/mysql/kohastructure.sql | 1 + .../prog/en/modules/admin/smart-rules.tt | 6 +++ t/db_dependent/Circulation.t | 44 ++++++++++++++--- 6 files changed, 90 insertions(+), 26 deletions(-) create mode 100644 installer/data/mysql/atomicupdate/bug_16344.sql diff --git a/C4/Circulation.pm b/C4/Circulation.pm index 26dd7d8..2635e50 100644 --- a/C4/Circulation.pm +++ b/C4/Circulation.pm @@ -2985,19 +2985,26 @@ sub CanBookBeRenewed { return ( 0, 'overdue'); } - if ( $itemissue->{auto_renew} - and defined $issuingrule->{no_auto_renewal_after} + if ( $itemissue->{auto_renew} ) { + if ( 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" ); + # 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->{no_auto_renewal_after_hard_limit} + and $issuingrule->{no_auto_renewal_after_hard_limit} ne "" ) { + # If no_auto_renewal_after_hard_limit is >= today, it's also too late for renewal + if ( dt_from_string >= dt_from_string( $issuingrule->{no_auto_renewal_after_hard_limit} ) ) { + return ( 0, "auto_too_late" ); + } } } @@ -3280,8 +3287,8 @@ has the item on loan. C<$itemnumber> is the number of the item to renew. C<$GetLatestAutoRenewDate> returns the DateTime of the latest possible -auto renew date, based on the value "No auto renewal after" of the applicable -issuing rule. +auto renew date, based on the value "No auto renewal after" and the "No auto +renewal after (hard limit) of the applicable issuing rule. Returns undef if there is no date specify in the circ rules or if the patron, loan, or item cannot be found. @@ -3305,14 +3312,22 @@ sub GetLatestAutoRenewDate { my $now = dt_from_string; - return if not $issuingrule->{no_auto_renewal_after} - or $issuingrule->{no_auto_renewal_after} eq ''; + return if ( not $issuingrule->{no_auto_renewal_after} or $issuingrule->{no_auto_renewal_after} eq '' ) + and ( not $issuingrule->{no_auto_renewal_after_hard_limit} or $issuingrule->{no_auto_renewal_after_hard_limit} eq '' ); - my $maximum_renewal_date = dt_from_string($itemissue->{issuedate}); - $maximum_renewal_date->add( - $issuingrule->{lengthunit} => $issuingrule->{no_auto_renewal_after} - ); + my $maximum_renewal_date; + if ( $issuingrule->{no_auto_renewal_after} ) { + $maximum_renewal_date = dt_from_string($itemissue->{issuedate}); + $maximum_renewal_date->add( + $issuingrule->{lengthunit} => $issuingrule->{no_auto_renewal_after} + ); + } + + if ( $issuingrule->{no_auto_renewal_after_hard_limit} ) { + my $dt = dt_from_string( $issuingrule->{no_auto_renewal_after_hard_limit} ); + $maximum_renewal_date = $dt if not $maximum_renewal_date or $maximum_renewal_date > $dt; + } return $maximum_renewal_date; } diff --git a/admin/smart-rules.pl b/admin/smart-rules.pl index 52b3e18..9c6913e 100755 --- a/admin/smart-rules.pl +++ b/admin/smart-rules.pl @@ -138,6 +138,9 @@ elsif ($op eq 'add') { 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 $no_auto_renewal_after_hard_limit = $input->param('no_auto_renewal_after_hard_limit') || undef; + $no_auto_renewal_after_hard_limit = eval { dt_from_string( $input->param('no_auto_renewal_after_hard_limit') ) } if ( $no_auto_renewal_after_hard_limit ); + $no_auto_renewal_after_hard_limit = output_pref( { dt => $no_auto_renewal_after_hard_limit, dateonly => 1, dateformat => 'iso' } ) if ( $no_auto_renewal_after_hard_limit ); my $reservesallowed = $input->param('reservesallowed'); my $onshelfholds = $input->param('onshelfholds') || 0; $maxissueqty =~ s/\s//g; @@ -174,6 +177,7 @@ elsif ($op eq 'add') { norenewalbefore => $norenewalbefore, auto_renew => $auto_renew, no_auto_renewal_after => $no_auto_renewal_after, + no_auto_renewal_after_hard_limit => $no_auto_renewal_after_hard_limit, reservesallowed => $reservesallowed, issuelength => $issuelength, lengthunit => $lengthunit, @@ -516,6 +520,11 @@ while (my $row = $sth2->fetchrow_hashref) { } else { $row->{'hardduedate'} = 0; } + if ($row->{no_auto_renewal_after_hard_limit}) { + my $dt = eval { dt_from_string( $row->{no_auto_renewal_after_hard_limit} ) }; + $row->{no_auto_renewal_after_hard_limit} = eval { output_pref( { dt => $dt, dateonly => 1 } ) } if $dt; + } + push @row_loop, $row; } $sth->finish; diff --git a/installer/data/mysql/atomicupdate/bug_16344.sql b/installer/data/mysql/atomicupdate/bug_16344.sql new file mode 100644 index 0000000..5be20e8 --- /dev/null +++ b/installer/data/mysql/atomicupdate/bug_16344.sql @@ -0,0 +1 @@ +ALTER TABLE issuingrules ADD COLUMN no_auto_renewal_after_hard_limit DATE DEFAULT NULL AFTER no_auto_renewal_after; diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql index 208576b..768a931 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -859,6 +859,7 @@ CREATE TABLE `issuingrules` ( -- circulation and fine rules `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 + `no_auto_renewal_after_hard_limit` date default NULL, -- no auto renewal allowed after a given 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 c13087d..405555e 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 @@ -177,6 +177,7 @@ for="tobranch">Clone these rules to: Clone these rules to: Clone these rules to: + + +
[% INCLUDE 'date-format.inc' %]
+