@@ -, +, @@ --- C4/Circulation.pm | 60 ++++++++++++++++++++ C4/SIP/ILS/Transaction/Checkout.pm | 10 +++- installer/data/mysql/sysprefs.sql | 3 + .../en/modules/admin/preferences/circulation.pref | 16 ++++++ .../prog/en/modules/circ/circulation.tt | 11 ++++ 5 files changed, 97 insertions(+), 3 deletions(-) --- a/C4/Circulation.pm +++ a/C4/Circulation.pm @@ -941,9 +941,69 @@ sub CanBookBeIssued { } } } + + ## check for high holds decreasing loan period + my $decrease_loan = C4::Context->preference('decreaseLoanHighHolds'); + if ( $decrease_loan && $decrease_loan == 1 ) { + my ( $reserved, $num, $duration, $returndate ) = + checkHighHolds( $item, $borrower ); + + if ( $num >= C4::Context->preference('decreaseLoanHighHoldsValue') ) { + $needsconfirmation{HIGHHOLDS} = { + num_holds => $num, + duration => $duration, + returndate => output_pref($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 = $dbh->prepare( +'select count(borrowernumber) as num_holds from reserves where biblionumber=?' + ); + $sth->execute( $item->{'biblionumber'} ); + my ($holds) = $sth->fetchrow_array; + if ($holds) { + my $issuedate = DateTime->now( time_zone => C4::Context->tz() ); + + my $calendar = Koha::Calendar->new( branchcode => $branch ); + + my $itype = + ( C4::Context->preference('item-level_itypes') ) + ? $biblio->{'itype'} + : $biblio->{'itemtype'}; + my $orig_due = + C4::Circulation::CalcDateDue( $issuedate, $itype, $branch, + $borrower ); + + my $reduced_datedue = + $calendar->addDate( $issuedate, + C4::Context->preference('decreaseLoanHighHoldsDuration') ); + + if ( DateTime->compare( $reduced_datedue, $orig_due ) == -1 ) { + return ( 1, $holds, + C4::Context->preference('decreaseLoanHighHoldsDuration'), + $reduced_datedue ); + } + } + return ( 0, 0, 0, undef ); +} + =head2 AddIssue &AddIssue($borrower, $barcode, [$datedue], [$cancelreserve], [$issuedate]) --- a/C4/SIP/ILS/Transaction/Checkout.pm +++ a/C4/SIP/ILS/Transaction/Checkout.pm @@ -54,6 +54,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; @@ -72,7 +73,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') { @@ -87,6 +88,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; @@ -118,10 +122,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 { --- 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/admin/preferences/circulation.pref +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref @@ -377,6 +377,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 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt @@ -289,8 +289,19 @@ function validate1(date) { [% 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 [% HIGHHOLDS.duration %] days (due [% HIGHHOLDS.returndate %]). Check out anyway?
  • +[% END %] +[% IF HIGHHOLDS %] + +[% END %]
    [% IF ( RESERVED ) %] --