@@ -, +, @@ and "Unit" set to days. Home > Patron > Patron details Home > Circulation > Checkouts issues. (Check something out on one day and something else on the next day, then do the testing.) X days before due date. displayed in the format specified by global sysprefs "dateformat" and "TimeFormat". undefined or current date is X or less days before due date. "Not renewable" is displayed, no matter what "No renewal before" is set to. --- 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(-) --- a/C4/Circulation.pm +++ a/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); --- a/circ/circulation.pl +++ a/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} + ) + ); } } --- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt @@ -779,17 +779,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 %] @@ -874,17 +876,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 %] --- a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt +++ a/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 %] --- a/members/moremember.pl +++ a/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; --