From 537c746dc41748a5045f9c60dd4d32b8abdef07c Mon Sep 17 00:00:00 2001 From: Colin Campbell Date: Fri, 17 Aug 2012 17:25:47 +0100 Subject: [PATCH] Bug 7751: Decrease Loans for Items in Demand for Holds Rebase and merge based on Mark Gavillet's patch to reduce the loan period given to items on renewal when they are in high demand for holds Signed-off-by: Chris Cormack --- C4/Circulation.pm | 60 +++++++++++++++++++ C4/SIP/ILS/Transaction/Checkout.pm | 10 +++- installer/data/mysql/sysprefs.sql | 3 + .../admin/preferences/circulation.pref | 16 +++++ .../prog/en/modules/circ/circulation.tt | 11 ++++ 5 files changed, 97 insertions(+), 3 deletions(-) diff --git a/C4/Circulation.pm b/C4/Circulation.pm index dd5d843a94..8f60d80a4d 100644 --- a/C4/Circulation.pm +++ b/C4/Circulation.pm @@ -1005,6 +1005,22 @@ 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 ); } @@ -1057,6 +1073,50 @@ sub CanBookBeReturned { return ($allowed, $message); } +=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]) diff --git a/C4/SIP/ILS/Transaction/Checkout.pm b/C4/SIP/ILS/Transaction/Checkout.pm index 38951fcf70..da7a1b0957 100644 --- a/C4/SIP/ILS/Transaction/Checkout.pm +++ b/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 { diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql index 4b4bf777f3..7b33ce6ae5 100644 --- a/installer/data/mysql/sysprefs.sql +++ b/installer/data/mysql/sysprefs.sql @@ -358,6 +358,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'); diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref index 9ff3056449..531b8783c4 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref @@ -407,6 +407,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 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 5f8fb9904e..db17ced812 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt @@ -364,8 +364,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 ) %] -- 2.20.1