@@ -, +, @@ --- C4/Circulation.pm | 46 ++++++++++++++++- C4/ILSDI/Services.pm | 5 +- circ/circulation.pl | 8 ++- installer/data/mysql/sysprefs.sql | 1 + installer/data/mysql/updatedatabase.pl | 8 +++ .../en/modules/admin/preferences/circulation.pref | 8 +++ .../prog/en/modules/circ/circulation.tt | 53 ++++++++++++++----- .../prog/en/modules/members/moremember.tt | 30 ++++++++++- koha-tmpl/opac-tmpl/prog/en/modules/opac-user.tt | 6 ++- members/moremember.pl | 7 ++- opac/opac-renew.pl | 6 ++- opac/opac-user.pl | 11 ++++- reserve/renewscript.pl | 5 +- 13 files changed, 160 insertions(+), 34 deletions(-) --- a/C4/Circulation.pm +++ a/C4/Circulation.pm @@ -75,6 +75,7 @@ BEGIN { push @EXPORT, qw( &CanBookBeIssued &CanBookBeRenewed + &HasWhateverRenewalToBeBlocked &AddIssue &AddRenewal &GetRenewCount @@ -2441,7 +2442,7 @@ already renewed the loan. $error will contain the reason the renewal can not pro sub CanBookBeRenewed { # check renewal status - my ( $borrowernumber, $itemnumber, $override_limit ) = @_; + my ( $borrowernumber, $itemnumber, $override_limit, $overduesblockrenew ) = @_; my $dbh = C4::Context->dbh; my $renews = 1; my $renewokay = 0; @@ -2450,13 +2451,15 @@ sub CanBookBeRenewed { my $borrower = C4::Members::GetMemberDetails( $borrowernumber, 0 ) or return; my $item = GetItem($itemnumber) or return; my $itemissue = GetItemIssue($itemnumber) or return; + my $overdue = $itemissue->{'overdue'}; my $branchcode = _GetCircControlBranch($item, $borrower); my $issuingrule = GetIssuingRule($borrower->{categorycode}, $item->{itype}, $branchcode); if ( ( $issuingrule->{renewalsallowed} > $itemissue->{renewals} ) || $override_limit ) { - $renewokay = 1; + $renewokay = ( $overduesblockrenew eq 'blockitem' and $overdue and !$override_limit ) ? 0 : 1; + $error = 'overdue' unless $renewokay; } else { $error = "too_many"; } @@ -2466,10 +2469,47 @@ sub CanBookBeRenewed { $renewokay = 0; $error = "on_reserve"; } - return ( $renewokay, $error ); } +=head2 HasWhateverRenewalToBeBlocked + + ($blockallitems, $reasonwhy, $overduesblockrenew) = &HasWhateverRenewalToBeBlocked($borrowernumber, $override_limit); + +Check whether whatever renewal must be blocked in the case patron is restricted or any of his documents are late. + +C<$blockallitems> if true, causes the renewal to be blocked for every items. + +C<$reasonwhy> if $blockallitems is true, will be an information displayed in checkouts table on patron page. + +C<$overduesblockrenew> is the value of the syspref OverduesBlockRenew. + +=cut + +sub HasWhateverRenewalToBeBlocked { + my $borrowernumber = shift; + my $override_limit = shift; + # get the option selected for the syspref OverduesBlockRenew + my $overduesblockrenew = C4::Context->preference('OverduesBlockRenew'); + my $blockallitems; + my $reasonwhy; + unless ( $override_limit ) { + # check if patron is restricted or if any of his documents are late + my ($memberblocked) = C4::Members::IsMemberBlocked($borrowernumber); + if ($memberblocked == 1) { + $reasonwhy = 'restriction'; + $blockallitems = 1; + } elsif ($memberblocked == -1) { + # check if renewal must be blocked for all the patron's documents on loan + if ( $overduesblockrenew eq 'blockall' ) { + $blockallitems = 1; + $reasonwhy = 'overdue'; + } + } + } + return($blockallitems,$reasonwhy,$overduesblockrenew); +} + =head2 AddRenewal &AddRenewal($borrowernumber, $itemnumber, $branch, [$datedue], [$lastreneweddate]); --- a/C4/ILSDI/Services.pm +++ a/C4/ILSDI/Services.pm @@ -561,11 +561,10 @@ sub RenewLoan { return { code => 'RecordNotFound' } unless $$item{itemnumber}; # Add renewal if possible - my @renewal = CanBookBeRenewed( $borrowernumber, $itemnumber ); + my ($blockallitems,$reasonwhy,$overduesblockrenew) = HasAnyRenewalToBeBlocked($borrowernumber,undef); + my @renewal = $blockallitems ? (0, $reasonwhy) : CanBookBeRenewed( $borrowernumber, $itemnumber, undef, $overduesblockrenew ); if ( $renewal[0] ) { AddRenewal( $borrowernumber, $itemnumber ); } - my $issue = GetItemIssue($itemnumber); - # Hashref building my $out; $out->{'renewals'} = $issue->{'renewals'}; --- a/circ/circulation.pl +++ a/circ/circulation.pl @@ -435,6 +435,8 @@ my $displayrelissues; our $totalprice = 0; +my ($blockallitems, $reasonwhy, $overduesblockrenew) = HasWhateverRenewalToBeBlocked($borrowernumber, undef); + sub build_issue_data { my $issueslist = shift; my $relatives = shift; @@ -450,10 +452,10 @@ sub build_issue_data { $it->{'itemnumber'}, $it->{'borrowernumber'} ); $it->{'charge'} = sprintf("%.2f", $it->{'charge'}); - my ($can_renew, $can_renew_error) = CanBookBeRenewed( - $it->{'borrowernumber'},$it->{'itemnumber'} - ); + my ($can_renew, $can_renew_error) = $blockallitems ? (0, $reasonwhy) : CanBookBeRenewed( + $it->{'borrowernumber'},$it->{'itemnumber'}, undef, $overduesblockrenew); $it->{"renew_error_${can_renew_error}"} = 1 if defined $can_renew_error; + $it->{'blockrenewal'} = ($can_renew_error=~/overdue|restriction/) ? 1 : 0; my $restype = C4::Reserves::GetReserveStatus( $it->{'itemnumber'} ); $it->{'can_renew'} = $can_renew; $it->{'can_confirm'} = !$can_renew && !$restype; --- a/installer/data/mysql/sysprefs.sql +++ a/installer/data/mysql/sysprefs.sql @@ -424,3 +424,4 @@ INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES(' INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES ('HighlightOwnItemsOnOPAC','0','','If on, and a patron is logged into the OPAC, items from his or her home library will be emphasized and shown first in search results and item details.','YesNo'); INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES ('HighlightOwnItemsOnOPACWhich','PatronBranch','PatronBranch|OpacURLBranch','Decides which branch''s items to emphasize. If PatronBranch, emphasize the logged in user''s library''s items. If OpacURLBranch, highlight the items of the Apache var BRANCHCODE defined in Koha''s Apache configuration file.','Choice'); INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('UniqueItemFields', 'barcode', 'Space-separated list of fields that should be unique (used in acquisition module for item creation). Fields must be valid SQL column names of items table', '', 'Free'); +INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('OverduesBlockRenew','allow','If any of patron checked out documents is late, should renewal be allowed, blocked only on overdue items or blocked on whatever checked out document','allow|blockitem|blockall','Choice'); --- a/installer/data/mysql/updatedatabase.pl +++ a/installer/data/mysql/updatedatabase.pl @@ -6834,6 +6834,14 @@ if (C4::Context->preference("Version") < TransformToNum($DBversion)) { SetVersion($DBversion); } +$DBversion = "3.11.00.XXX"; +if ( CheckVersion($DBversion) ) { + $dbh->do("INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES ('OverduesBlockRenew','allow','If any of a patron checked out documents is late, should renewal be allowed, blocked only on overdue items or blocked on whatever checked out document','allow|blockitem|blockall','Choice')"); + print "Upgrade to $DBversion done (Add system preference OverduesBlockRenew)\n"; + SetVersion($DBversion); +} + + =head1 FUNCTIONS =head2 TableExists($table) --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/circulation.pref @@ -298,6 +298,14 @@ Circulation: confirmation: Ask for confirmation - when checking out to a borrower that has overdues outstanding - + - If any of a patron's checked out items are late, + - pref: OverduesBlockRenew + type: choice + choices: + allow: allow renewing of items. + blockall: block renewing for all items. + blockitem: block renewing only for overdue items. + - - On checkin route the returned item to - pref: HomeOrHoldingBranchReturn type: choice --- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt @@ -20,10 +20,12 @@ @@ -841,15 +862,13 @@ No patron matched [% message %] [% IF ( todayissue.renewals ) %][% todayissue.renewals %][% ELSE %]0[% END %] [% IF ( todayissue.can_renew ) %] - [% IF ( todayissue.od ) %] + [% IF ( todayissue.od) %] - [% ELSE %] - [% END %] [% ELSE %] [% IF ( todayissue.can_confirm ) %] [% END %] @@ -932,13 +955,11 @@ No patron matched [% message %] [% IF ( previssue.od ) %] - [% ELSE %] - [% END %] [% ELSE %] [% 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 @@ -18,6 +18,7 @@ @@ -496,7 +516,7 @@ function validate1(date) { [% IF ( issueloo.norenew ) %] [% IF ( issueloo.can_confirm ) %] [% END %] --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-user.tt +++ a/koha-tmpl/opac-tmpl/prog/en/modules/opac-user.tt @@ -195,8 +195,11 @@ $.tablesorter.addParser({ [% IF ( OpacRenewalAllowed ) %] [% IF ( ISSUE.status ) %][% IF ( canrenew ) %] Renew[% END %] ([% ISSUE.renewsleft %] of [% ISSUE.renewsallowed %] renewals remaining) [% ELSE %] + [% IF ( ISSUE.norenew_overdue ) %] + Renewal not allowed (overdue on a document) + [% ELSE %] Not renewable[% IF ( ISSUE.too_many ) %] ([% ISSUE.renewsleft %] of [% ISSUE.renewsallowed %] renewals remaining)[% ELSE %][% IF ( ISSUE.on_reserve ) %] (On hold)[% END %][% END %] - [% END %] + [% END %][% END %] [% END %] [% IF ( OPACFinesTab ) %] [% IF ( ISSUE.charges ) %]Yes[% ELSE %]No[% END %] @@ -339,6 +342,7 @@ $.tablesorter.addParser({ [% ELSIF ( OVERDUE.status ) %] [% IF ( canrenew ) %]Renew[% END %] ([% OVERDUE.renewsleft %] of [% OVERDUE.renewsallowed %] renewals remaining) [% ELSIF ( OVERDUE.onreserve ) %]On hold +[% ELSIF ( OVERDUE.norenew_overdue ) %]Renewal not allowed(overdue on a document) [% ELSE %]No renewals left [% END %] [% END %] --- a/members/moremember.pl +++ a/members/moremember.pl @@ -251,6 +251,8 @@ my @borrowers_with_issues; my $overdues_exist = 0; my $totalprice = 0; +my ($blockallitems, $reasonwhy, $overduesblockrenew) = HasWhateverRenewalToBeBlocked($borrowernumber, $override_limit); + my @issuedata = build_issue_data($issue); my @relissuedata = build_issue_data($relissue); @@ -502,12 +504,11 @@ sub build_issue_data { $row{'charge'} = sprintf( "%.2f", $charge ); - my ( $renewokay, $renewerror ) = - CanBookBeRenewed( $borrowernumber, $issue->{itemnumber}, - $override_limit ); + my ( $renewokay, $renewerror ) = $blockallitems ? (0, $reasonwhy) : CanBookBeRenewed( $borrowernumber, $issue->{itemnumber}, $override_limit, $overduesblockrenew ); $row{'norenew'} = !$renewokay; $row{'can_confirm'} = ( !$renewokay && $renewerror ne 'on_reserve' ); $row{"norenew_reason_$renewerror"} = 1 if $renewerror; + $row{'blockrenewal'} = ($renewerror=~ /overdue|restriction/) ? 1 : 0; $row{renew_failed} = $renew_failed{ $issue->{itemnumber} }; $row{return_failed} = $return_failed{ $issue->{barcode} }; push( @{$localissue}, \%row ); --- a/opac/opac-renew.pl +++ a/opac/opac-renew.pl @@ -46,8 +46,12 @@ my @items = $query->param('item'); my $opacrenew = C4::Context->preference("OpacRenewalAllowed"); my $errorstring=''; + +my ($blockallitems, $reasonwhy, $overduesblockrenew) = HasWhateverRenewalToBeBlocked($borrowernumber, $override_limit); + for my $itemnumber ( @items ) { - my ($status,$error) = CanBookBeRenewed( $borrowernumber, $itemnumber ); + + my ($status,$error) = $blockallitems ? (0, $reasonwhy) : CanBookBeRenewed( $borrowernumber, $itemnumber, undef, $overduesblockrenew ); if ( $status == 1 && $opacrenew == 1 ) { my $renewalbranch = C4::Context->preference('OpacRenewalBranch'); my $branchcode; --- a/opac/opac-user.pl +++ a/opac/opac-user.pl @@ -155,6 +155,10 @@ my @overdues; my @issuedat; my $itemtypes = GetItemTypes(); my $issues = GetPendingIssues($borrowernumber); + + +my ($blockallitems, $reasonwhy, $overduesblockrenew) = HasWhateverRenewalToBeBlocked($borrowernumber, undef); + if ($issues){ foreach my $issue ( sort { $b->{date_due}->datetime() cmp $a->{date_due}->datetime() } @{$issues} ) { # check for reserves @@ -178,11 +182,12 @@ if ($issues){ $issue->{'charges'} = $charges; # check if item is renewable - my ($status,$renewerror) = CanBookBeRenewed( $borrowernumber, $issue->{'itemnumber'} ); + my ($status,$renewerror) = $blockallitems ? (0, $reasonwhy) : CanBookBeRenewed( $borrowernumber, $issue->{'itemnumber'}, undef, $overduesblockrenew); ($issue->{'renewcount'},$issue->{'renewsallowed'},$issue->{'renewsleft'}) = GetRenewCount($borrowernumber, $issue->{'itemnumber'}); if($status && C4::Context->preference("OpacRenewalAllowed")){ $issue->{'status'} = $status; } + $issue->{'norenew_overdue'} = 1 if $renewerror and $renewerror eq 'overdue'; $issue->{'too_many'} = 1 if $renewerror and $renewerror eq 'too_many'; $issue->{'on_reserve'} = 1 if $renewerror and $renewerror eq 'on_reserve'; @@ -218,12 +223,16 @@ if ($issues){ } } } + +$canrenew = 0 if ($overduesblockrenew ne 'allow' and $overdues_count == $count); + $template->param( ISSUES => \@issuedat ); $template->param( issues_count => $count ); $template->param( canrenew => $canrenew ); $template->param( OVERDUES => \@overdues ); $template->param( overdues_count => $overdues_count ); + my $show_barcode = C4::Members::AttributeTypes::AttributeTypeExists( ATTRIBUTE_SHOW_BARCODE ); if ($show_barcode) { my $patron_show_barcode = GetBorrowerAttributeValue($borrowernumber, ATTRIBUTE_SHOW_BARCODE); --- a/reserve/renewscript.pl +++ a/reserve/renewscript.pl @@ -81,11 +81,12 @@ my $borrowernumber = $input->param("borrowernumber"); my $exemptfine = $input->param("exemptfine") || 0; my $override_limit = $input->param("override_limit") || 0; my $failedrenews = q{}; +my ($blockallitems, $reasonwhy, $overduesblockrenew) = HasWhateverRenewalToBeBlocked($borrowernumber, $override_limit); + foreach my $itemno (@data) { # check status before renewing issue - my ( $renewokay, $error ) = - CanBookBeRenewed( $borrowernumber, $itemno, $override_limit ); + my ( $renewokay, $error ) = $blockallitems ? (0, $reasonwhy) : CanBookBeRenewed( $borrowernumber, $itemno, $override_limit, $overduesblockrenew ); if ($renewokay) { AddRenewal( $borrowernumber, $itemno, $branch, $datedue ); } --