From 065926d224005f03c6730f8fb62dfcaddb1ab0a0 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Holger=20Mei=C3=9Fner?= Date: Thu, 13 Feb 2014 17:05:08 +0100 Subject: [PATCH] Bug 7413: Code and intranet template changes MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This patch modifies CanBookBeRenewed, so that based on issuingrules.norenewalbefore a new error "too_soon" can be returned. Also adds a new subroutine GetSoonestRenewDate. To test: 1) Create an issuing rule with "No renewal before" set to value X and "Unit" set to days. 2) Test the following steps for both: Home > Patron > Patron details Home > Circulation > Checkouts 3) On the checkout page, test for today's issues as well as previous issues. (Check something out on one day and something else on the next day, then do the testing.) 4) Confirm that items can't be renewed if current date is more than X days before due date. 5) Confirm that the date and time of the soonest possible renewal are displayed in the format specified by global sysprefs "dateformat" and "TimeFormat". 6) Confirm that items can be renewed if "No renewal before" is undefined or current date is X or less days before due date. 7) Confirm that if the number of allowed renewals is exceeded "Not renewable" is displayed, no matter what "No renewal before" is set to. 8) Test the same things with "Unit" set to hours. Sponsored-by: Hochschule für Gesundheit (hsg), Germany Signed-off-by: Martin Renvoize Signed-off-by: Brendan Gallagher --- C4/Circulation.pm | 73 ++++++++++++++++++- circ/circulation.pl | 6 ++ .../prog/en/modules/circ/circulation.tt | 32 ++++---- .../prog/en/modules/members/moremember.tt | 12 +-- members/moremember.pl | 8 ++ 5 files changed, 108 insertions(+), 23 deletions(-) diff --git a/C4/Circulation.pm b/C4/Circulation.pm index f8b204abbd..39c1fadff3 100644 --- a/C4/Circulation.pm +++ b/C4/Circulation.pm @@ -79,6 +79,7 @@ BEGIN { &AddIssue &AddRenewal &GetRenewCount + &GetSoonestRenewDate &GetItemIssue &GetItemIssues &GetIssuingCharges @@ -2472,7 +2473,7 @@ sub CanBookBeRenewed { my $dbh = C4::Context->dbh; my $renews = 1; - my $renewokay = 0; + my $renewokay = 1; my $error; my $item = GetItem($itemnumber) or return ( 0, 'no_item' ); @@ -2486,12 +2487,30 @@ sub CanBookBeRenewed { my $issuingrule = GetIssuingRule($borrower->{categorycode}, $item->{itype}, $branchcode); - if ( ( $issuingrule->{renewalsallowed} > $itemissue->{renewals} ) || $override_limit ) { - $renewokay = 1; - } else { + if ( $issuingrule->{norenewalbefore} ) { + + # Get current time and add norenewalbefore. If this is smaller than date_due, it's too soon for renewal. + if ( + DateTime->now( time_zone => C4::Context->tz() )->add( + $issuingrule->{lengthunit} => $issuingrule->{norenewalbefore} + ) < $itemissue->{date_due} + ) + { + $renewokay = 0; + $error = "too_soon"; + } + } + + if ( $issuingrule->{renewalsallowed} <= $itemissue->{renewals} ) { + $renewokay = 0; $error = "too_many"; } + if ( $override_limit ) { + $renewokay = 1; + $error = undef; + } + my ( $resfound, $resrec, undef ) = C4::Reserves::CheckReserves( $itemnumber ); if ( $resfound ) { # '' when no hold was found @@ -2668,6 +2687,52 @@ sub GetRenewCount { return ( $renewcount, $renewsallowed, $renewsleft ); } +=head2 GetSoonestRenewDate + + $NoRenewalBeforeThisDate = &GetSoonestRenewDate($borrowernumber, $itemnumber); + +Find out the soonest possible renew date of a borrowed item. + +C<$borrowernumber> is the borrower number of the patron who currently +has the item on loan. + +C<$itemnumber> is the number of the item to renew. + +C<$GetSoonestRenewDate> returns the DateTime of the soonest possible renew date, +based on the value "No renewal before" of the applicable issuing rule. Returns the +current date if the item can already be renewed. + +=cut + +sub GetSoonestRenewDate { + my ( $borrowernumber, $itemnumber ) = @_; + + my $dbh = C4::Context->dbh; + + my $item = GetItem($itemnumber) or return ( 0, 'no_item' ); + my $itemissue = GetItemIssue($itemnumber) or return ( 0, 'no_checkout' ); + + $borrowernumber ||= $itemissue->{borrowernumber}; + my $borrower = C4::Members::GetMemberDetails($borrowernumber) + or return; + + my $branchcode = _GetCircControlBranch( $item, $borrower ); + my $issuingrule = + GetIssuingRule( $borrower->{categorycode}, $item->{itype}, $branchcode ); + + my $now = DateTime->now( time_zone => C4::Context->tz() ); + + if ( $issuingrule->{norenewalbefore} ) { + my $soonestrenewal = + $itemissue->{date_due}->subtract( + $issuingrule->{lengthunit} => $issuingrule->{norenewalbefore} ); + + $soonestrenewal = $now > $soonestrenewal ? $now : $soonestrenewal; + return $soonestrenewal; + } + return $now; +} + =head2 GetIssuingCharges ($charge, $item_type) = &GetIssuingCharges($itemnumber, $borrowernumber); diff --git a/circ/circulation.pl b/circ/circulation.pl index cdc40e38f5..e02b5696b7 100755 --- a/circ/circulation.pl +++ b/circ/circulation.pl @@ -513,6 +513,12 @@ sub build_issue_data { (!$relatives) ? push @previousissues, $it : push @relprevissues, $it; } ($it->{'renewcount'},$it->{'renewsallowed'},$it->{'renewsleft'}) = C4::Circulation::GetRenewCount($it->{'borrowernumber'},$it->{'itemnumber'}); #Add renewal count to item data display + + $it->{'soonestrenewdate'} = output_pref( + C4::Circulation::GetSoonestRenewDate( + $it->{borrowernumber}, $it->{itemnumber} + ) + ); } } diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt index 7c611dd1c0..d5cfc6d332 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt @@ -782,17 +782,19 @@ No patron matched [% message %] [% END %] - [% IF todayissue.renewsallowed && todayissue.renewsleft %] + [% IF todayissue.renewsallowed && todayissue.renewsleft && !todayissue.renew_error_too_soon %] ([% todayissue.renewsleft %] of [% todayissue.renewsallowed %] renewals remaining) [% END %] [% END %] - [% IF ( todayissue.renew_error_on_reserve ) %] - On hold - [% END %] - [% IF ( todayissue.renew_error_too_many ) %] - Not renewable - [% END %] + [% IF ( todayissue.renew_error_on_reserve ) %] + On hold + [% ELSIF ( todayissue.renew_error_too_many ) %] + Not renewable + [% ELSIF ( todayissue.renew_error_too_soon ) %] + No renewal before [% todayissue.soonestrenewdate %] + ([% todayissue.renewsleft %] of [% todayissue.renewsallowed %] renewals remaining) + [% END %] [% IF ( todayissue.can_confirm ) %] [% END %] @@ -877,17 +879,19 @@ No patron matched [% message %] [% END %] - [% IF previssue.renewsallowed && previssue.renewsleft %] + [% IF previssue.renewsallowed && previssue.renewsleft && !previssue.renew_error_too_soon %] ([% previssue.renewsleft %] of [% previssue.renewsallowed %] renewals remaining) [% END %] [% END %] - [% IF ( previssue.renew_error_on_reserve ) %] - On hold - [% END %] - [% IF ( previssue.renew_error_too_many ) %] - Not renewable - [% END %] + [% IF ( previssue.renew_error_on_reserve ) %] + On Hold + [% ELSIF ( previssue.renew_error_too_many ) %] + Not renewable + [% ELSIF ( previssue.renew_error_too_soon ) %] + No renewal before [% previssue.soonestrenewdate %] + ([% previssue.renewsleft %] of [% previssue.renewsallowed %] renewals remaining) + [% END %] [% IF ( previssue.can_confirm ) %] [% 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 c4705d1af3..9cd6a9049c 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt @@ -497,17 +497,19 @@ function validate1(date) { [% END %] - [% IF issueloo.renewsallowed && issueloo.renewsleft %] + [% IF issueloo.renewsallowed && issueloo.renewsleft && !issueloo.norenew_reason_too_soon %] ([% issueloo.renewsleft %] of [% issueloo.renewsallowed %] renewals remaining) [% END %] [% END %] [% IF ( issueloo.norenew_reason_on_reserve ) %] - On Hold + On Hold + [% ELSIF ( issueloo.norenew_reason_too_many ) %] + Not renewable + [% ELSIF ( issueloo.norenew_reason_too_soon ) %] + No renewal before [% issueloo.soonestrenewdate %] + ([% issueloo.renewsleft %] of [% issueloo.renewsallowed %] renewals remaining) [% END %] - [% IF ( issueloo.norenew_reason_too_many ) %] - Not renewable - [% END %] [% IF ( issueloo.can_confirm ) %] [% END %] diff --git a/members/moremember.pl b/members/moremember.pl index e794efa790..40f6d432c9 100755 --- a/members/moremember.pl +++ b/members/moremember.pl @@ -521,6 +521,14 @@ sub build_issue_data { $row{renew_failed} = $renew_failed{ $issue->{itemnumber} }; $row{return_failed} = $return_failed{ $issue->{barcode} }; ($row{'renewcount'},$row{'renewsallowed'},$row{'renewsleft'}) = C4::Circulation::GetRenewCount($issue->{'borrowernumber'},$issue->{'itemnumber'}); #Add renewal count to item data display + + $row{'soonestrenewdate'} = output_pref( + C4::Circulation::GetSoonestRenewDate( + $issue->{borrowernumber}, + $issue->{itemnumber} + ) + ); + push( @{$localissue}, \%row ); } return $localissue; -- 2.39.5