@@ -, +, @@ --- C4/Circulation.pm | 63 ++++++++++++++++++++ installer/data/mysql/sysprefs.sql | 3 + .../prog/en/modules/circ/circulation.tt | 11 ++++ 3 files changed, 77 insertions(+), 0 deletions(-) --- a/C4/Circulation.pm +++ a/C4/Circulation.pm @@ -931,9 +931,72 @@ sub CanBookBeIssued { } } } + + ## check for high holds decreasing loan period + if (C4::Context->preference("decreaseLoanHighHolds") == 1) + { + my ($reserved,$num,$duration,$returndate)=checkHighHolds($item,$borrower); + #print "reserved: $reserved\n".Dumper($num); + if ($num>=C4::Context->preference("decreaseLoanHighHoldsValue")) + { + $needsconfirmation{HIGHHOLDS} = 1; + $needsconfirmation{'num_holds'} = $num; + $needsconfirmation{'duration'} = $duration; + $needsconfirmation{'returndate'} = format_date($returndate); + } + } + return ( \%issuingimpossible, \%needsconfirmation, \%alerts ); } +=head2 CheckHighHolds + + used when syspref decreaseLoanHighHolds is active. Returns 1 or 0 to define whether the minimum value held in + decreaseLoanHighHoldsValue is exceeded, the total number of outstanding holds, the number of days the loan + has been decreased to (held in syspref decreaseLoanHighHoldsValue), and the new due date + +=cut + +sub checkHighHolds { + my ($item,$borrower) = @_; + my $biblio = GetBiblioFromItemNumber($item->{itemnumber}); + my $branch = _GetCircControlBranch($item,$borrower); + my $dbh = C4::Context->dbh; + my $sth; + $sth = $dbh->prepare("select count(borrowernumber) as num_holds from reserves where biblionumber=?"); + $sth->execute($item->{'biblionumber'}); + my $holds = $sth->fetchrow_array; + if ($holds>0) + { + my $issuedate = strftime( "%Y-%m-%d", localtime ); + my $startdate=C4::Dates->new( $issuedate, 'iso' ); + my $calendar = C4::Calendar->new( branchcode => $branch ); + + my $itype = ( C4::Context->preference('item-level_itypes') ) ? $biblio->{'itype'} : $biblio->{'itemtype'}; + my $due = C4::Circulation::CalcDateDue( C4::Dates->new( $issuedate, 'iso' ), $itype, $branch, $borrower ); + my $normaldue = sprintf("%04d-%02d-%02d",($due->{'dmy_arrayref'}[5]+1900),($due->{'dmy_arrayref'}[4]+1), + $due->{'dmy_arrayref'}[3]); + + my $datedue = $calendar->addDate($startdate, C4::Context->preference("decreaseLoanHighHoldsDuration")); + my $returndate = sprintf("%04d-%02d-%02d",($datedue->{'dmy_arrayref'}[5]+1900),($datedue->{'dmy_arrayref'}[4]+1), + $datedue->{'dmy_arrayref'}[3]); + + my $daysBetween = $calendar->daysBetween($datedue, $due); + if ($daysBetween>0) + { + return (1,$holds,C4::Context->preference("decreaseLoanHighHoldsDuration"),$returndate); + } + else + { + return (0,0,0,0); + } + } + else + { + return (0,0,0,0); + } +} + =head2 AddIssue &AddIssue($borrower, $barcode, [$datedue], [$cancelreserve], [$issuedate]) --- a/installer/data/mysql/sysprefs.sql +++ a/installer/data/mysql/sysprefs.sql @@ -364,6 +364,9 @@ INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES ( INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('OpacStarRatings','all',NULL,'disable|all|details','Choice'); INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpacBrowseResults','1','Disable/enable browsing and paging search results from the OPAC detail page.',NULL,'YesNo'); INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('SvcMaxReportRows','10','Maximum number of rows to return via the report web service.',NULL,'Integer'); +INSERT INTO `systempreferences` (`variable`,`value`,`options`,`explanation`,`type`) VALUES ('decreaseLoanHighHolds', NULL, '', 'Decreases the loan period for items with number of holds above the threshold specified in decreaseLoanHighHoldsValue', 'YesNo'); +INSERT INTO `systempreferences` (`variable`,`value`,`options`,`explanation`,`type`) VALUES ('decreaseLoanHighHoldsValue', NULL, '', 'Specifies a threshold for the minimum number of holds needed to trigger a reduction in loan duration (used with decreaseLoanHighHolds)', 'Integer'); +INSERT INTO `systempreferences` (`variable`,`value`,`options`,`explanation`,`type`) VALUES ('decreaseLoanHighHoldsDuration', NULL, '', 'Specifies a number of days that a loan is reduced to when used in conjunction with decreaseLoanHighHolds', 'Integer'); INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES ('ReservesControlBranch','PatronLibrary','ItemHomeLibrary|PatronLibrary','Branch checked for members reservations rights','Choice'); INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('IssueLostItem', 'alert', 'alert|confirm|nothing', 'Defines what should be done when an attempt is made to issue an item that has been marked as lost.', 'Choice'); INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('SuspendHoldsIntranet', '1', NULL , 'Allow holds to be suspended from the intranet.', 'YesNo'); --- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt @@ -288,8 +288,19 @@ function refocus(calendar) { [% IF ( ITEM_LOST ) %]
  • This item has been lost with a status of "[% ITEM_LOST %]". Check out anyway?
  • [% END %] + +[% IF ( HIGHHOLDS ) %] +
  • High demand item. Loan period shortened to [% duration %] days (due [% returndate %]). Check out anyway?
  • +[% END %] +[% IF ( HIGHHOLDS ) %] + +[% END %]
    [% IF ( RESERVED ) %] -- --- C4/Circulation.pm | 9 +++++---- .../prog/en/modules/circ/circulation.tt | 8 ++++---- 2 files changed, 9 insertions(+), 8 deletions(-) --- a/C4/Circulation.pm +++ a/C4/Circulation.pm @@ -939,10 +939,11 @@ sub CanBookBeIssued { #print "reserved: $reserved\n".Dumper($num); if ($num>=C4::Context->preference("decreaseLoanHighHoldsValue")) { - $needsconfirmation{HIGHHOLDS} = 1; - $needsconfirmation{'num_holds'} = $num; - $needsconfirmation{'duration'} = $duration; - $needsconfirmation{'returndate'} = format_date($returndate); + $needsconfirmation{HIGHHOLDS} = { + num_holds => $num, + duration => $duration, + returndate => format_date($returndate), + }; } } --- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt @@ -289,15 +289,15 @@ function refocus(calendar) {
  • This item has been lost with a status of "[% ITEM_LOST %]". Check out anyway?
  • [% END %] -[% IF ( HIGHHOLDS ) %] -
  • High demand item. Loan period shortened to [% duration %] days (due [% returndate %]). Check out anyway?
  • +[% IF HIGHHOLDS %] +
  • High demand item. Loan period shortened to [% HIGHHOLDS.duration %] days (due [% HIGHHOLDS.returndate %]). Check out anyway?
  • [% END %] -[% IF ( HIGHHOLDS ) %] +[% IF HIGHHOLDS %] [% END %] -- --- C4/SIP/ILS/Transaction/Checkout.pm | 10 +++++++--- 1 files changed, 7 insertions(+), 3 deletions(-) --- a/C4/SIP/ILS/Transaction/Checkout.pm +++ a/C4/SIP/ILS/Transaction/Checkout.pm @@ -55,6 +55,7 @@ sub do_checkout { my $shelf = $self->{item}->hold_shelf; my $barcode = $self->{item}->id; my $patron_barcode = $self->{patron}->id; + my $overridden_duedate; # usually passed as undef to AddIssue $debug and warn "do_checkout: patron (" . $patron_barcode . ")"; my $borrower = $self->{patron}->getmemberdetails_object(); $debug and warn "do_checkout borrower: . " . Dumper $borrower; @@ -73,7 +74,7 @@ sub do_checkout { $noerror = 0; } } else { - foreach my $confirmation (keys %$needsconfirmation) { + foreach my $confirmation (keys %{$needsconfirmation}) { if ($confirmation eq 'RENEW_ISSUE'){ $self->screen_msg("Item already checked out to you: renewing item."); } elsif ($confirmation eq 'RESERVED' or $confirmation eq 'RESERVE_WAITING') { @@ -88,6 +89,9 @@ sub do_checkout { $self->screen_msg("Item already checked out to another patron. Please return item for check-in."); $noerror = 0; } elsif ($confirmation eq 'DEBT') { # don't do anything, it's the minor debt, and alarms fire elsewhere + } elsif ($confirmation eq 'HIGHHOLDS') { + $overridden_duedate = $needsconfirmation->{$confirmation}->{returndate}; + $self->screen_msg('Loan period reduced for high-demand item'); } else { $self->screen_msg($needsconfirmation->{$confirmation}); $noerror = 0; @@ -119,10 +123,10 @@ sub do_checkout { # TODO: adjust representation in $self->item } # can issue - $debug and warn "do_checkout: calling AddIssue(\$borrower,$barcode, undef, 0)\n" + $debug and warn "do_checkout: calling AddIssue(\$borrower,$barcode, $overridden_duedate, 0)\n" # . "w/ \$borrower: " . Dumper($borrower) . "w/ C4::Context->userenv: " . Dumper(C4::Context->userenv); - my $due_dt = AddIssue($borrower, $barcode, undef, 0); + my $due_dt = AddIssue($borrower, $barcode, $overridden_duedate, 0); if ($due_dt) { $self->{due} = $due_dt->clone(); } else { -- --- .../en/modules/admin/preferences/circulation.pref | 16 ++++++++++++++++ 1 files changed, 16 insertions(+), 0 deletions(-) --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref @@ -370,6 +370,22 @@ Circulation: yes: Allow no: "Don't allow" - holds to be suspended from the OPAC. + - + - pref: decreaseLoanHighHolds + choices: + yes: Enable + no: "Don't enable" + - the reduction of loan period for items with number of holds above the threshold specified in decreaseLoanHighHoldsValue + - + - A loan should be reduced by + - pref: decreaseLoanHighHoldsDuration + class: integer + - days, when decreaseLoanHighHoldsValue threshold is reached (if decreaseLoanHighHolds is enabled) + - + - A loan should be reduced by decreaseLoanHighHoldsDuration when + - pref: decreaseLoanHighHoldsValue + class: integer + - holds have been places (if decreaseLoanHighHolds is enables) Fines Policy: - - Calculate fines based on days overdue -- --- C4/Circulation.pm | 34 ++++++++++++++-------------------- 1 files changed, 14 insertions(+), 20 deletions(-) --- a/C4/Circulation.pm +++ a/C4/Circulation.pm @@ -931,7 +931,7 @@ sub CanBookBeIssued { } } } - + ## check for high holds decreasing loan period if (C4::Context->preference("decreaseLoanHighHolds") == 1) { @@ -942,7 +942,7 @@ sub CanBookBeIssued { $needsconfirmation{HIGHHOLDS} = { num_holds => $num, duration => $duration, - returndate => format_date($returndate), + returndate => output_pref($returndate), }; } } @@ -963,38 +963,32 @@ sub checkHighHolds { my $biblio = GetBiblioFromItemNumber($item->{itemnumber}); my $branch = _GetCircControlBranch($item,$borrower); my $dbh = C4::Context->dbh; - my $sth; - $sth = $dbh->prepare("select count(borrowernumber) as num_holds from reserves where biblionumber=?"); + my $sth = $dbh->prepare('select count(borrowernumber) as num_holds from reserves where biblionumber=?'); $sth->execute($item->{'biblionumber'}); - my $holds = $sth->fetchrow_array; - if ($holds>0) + my ($holds) = $sth->fetchrow_array; + if ($holds) { - my $issuedate = strftime( "%Y-%m-%d", localtime ); - my $startdate=C4::Dates->new( $issuedate, 'iso' ); - my $calendar = C4::Calendar->new( branchcode => $branch ); + my $issuedate = DateTime->new( time_zone => C4::Context->tz()); + # my $startdate=C4::Dates->new( $issuedate, 'iso' ); + my $calendar = Koha::Calendar->new( branchcode => $branch ); my $itype = ( C4::Context->preference('item-level_itypes') ) ? $biblio->{'itype'} : $biblio->{'itemtype'}; - my $due = C4::Circulation::CalcDateDue( C4::Dates->new( $issuedate, 'iso' ), $itype, $branch, $borrower ); - my $normaldue = sprintf("%04d-%02d-%02d",($due->{'dmy_arrayref'}[5]+1900),($due->{'dmy_arrayref'}[4]+1), - $due->{'dmy_arrayref'}[3]); + my $orig_due = C4::Circulation::CalcDateDue( $issuedate, $itype, $branch, $borrower ); - my $datedue = $calendar->addDate($startdate, C4::Context->preference("decreaseLoanHighHoldsDuration")); - my $returndate = sprintf("%04d-%02d-%02d",($datedue->{'dmy_arrayref'}[5]+1900),($datedue->{'dmy_arrayref'}[4]+1), - $datedue->{'dmy_arrayref'}[3]); + my $reduced_datedue = $calendar->addDate($issuedate, C4::Context->preference("decreaseLoanHighHoldsDuration")); - my $daysBetween = $calendar->daysBetween($datedue, $due); - if ($daysBetween>0) + if (DateTime->compare($reduced_datedue,$orig_due) == -1 ) { - return (1,$holds,C4::Context->preference("decreaseLoanHighHoldsDuration"),$returndate); + return (1,$holds,C4::Context->preference("decreaseLoanHighHoldsDuration"),$reduced_datedue); } else { - return (0,0,0,0); + return (0,0,0,undef); } } else { - return (0,0,0,0); + return (0,0,0,undef); } } -- --- C4/Circulation.pm | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) --- a/C4/Circulation.pm +++ a/C4/Circulation.pm @@ -933,11 +933,12 @@ sub CanBookBeIssued { } ## check for high holds decreasing loan period - if (C4::Context->preference("decreaseLoanHighHolds") == 1) + my $decrease_loan = C4::Context->preference('decreaseLoanHighHolds'); + if ($decrease_loan && $decrease_loan == 1) { my ($reserved,$num,$duration,$returndate)=checkHighHolds($item,$borrower); #print "reserved: $reserved\n".Dumper($num); - if ($num>=C4::Context->preference("decreaseLoanHighHoldsValue")) + if ($num >= C4::Context->preference("decreaseLoanHighHoldsValue")) { $needsconfirmation{HIGHHOLDS} = { num_holds => $num, --