Bugzilla – Attachment 111149 Details for
Bug 24083
Koha should support "seen" vs "unseen" renewals
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 24083: Add support for unseen_renewals
Bug-24083-Add-support-for-unseenrenewals.patch (text/plain), 42.14 KB, created by
Andrew Isherwood
on 2020-10-02 12:45:46 UTC
(
hide
)
Description:
Bug 24083: Add support for unseen_renewals
Filename:
MIME Type:
Creator:
Andrew Isherwood
Created:
2020-10-02 12:45:46 UTC
Size:
42.14 KB
patch
obsolete
>From 9fc00f6b4e48adc0364f53cf146cd5a1b5ab07b9 Mon Sep 17 00:00:00 2001 >From: Andrew Isherwood <andrew.isherwood@ptfs-europe.com> >Date: Fri, 22 Nov 2019 11:08:53 +0000 >Subject: [PATCH] Bug 24083: Add support for unseen_renewals > >This patch adds support for unseen renewals. > >Here we retrofit knowledge of unseen renewals and add the display of unseen >renewal counts and warnings, in addition to adding the ability to >specify a renewal as being "unseen". > >The functionality added here is goverened by the UnseenRenewals syspref. > >Signed-off-by: Sally Healey <sally.Healey@cheshirewestandchester.gov.uk> >--- > C4/Circulation.pm | 172 +++++++++++++++++- > C4/ILSDI/Services.pm | 2 +- > C4/SIP/ILS/Transaction/Renew.pm | 1 + > Koha/CirculationRules.pm | 3 + > Koha/REST/V1/Checkouts.pm | 11 +- > api/v1/swagger/definitions/checkout.json | 4 + > api/v1/swagger/parameters.json | 3 + > api/v1/swagger/parameters/checkout.json | 7 + > api/v1/swagger/paths/checkouts.json | 7 +- > circ/renew.pl | 11 +- > .../prog/css/src/staff-global.scss | 12 ++ > .../prog/en/includes/checkouts-table.inc | 4 + > .../prog/en/modules/circ/circulation.tt | 1 + > .../prog/en/modules/circ/renew.tt | 38 +++- > .../prog/en/modules/members/moremember.tt | 1 + > koha-tmpl/intranet-tmpl/prog/js/checkouts.js | 24 ++- > .../bootstrap/en/modules/opac-user.tt | 44 ++++- > misc/cronjobs/automatic_renewals.pl | 2 +- > offline_circ/download.pl | 1 + > opac/opac-renew.pl | 2 +- > opac/opac-user.pl | 10 +- > svc/checkouts | 12 +- > svc/renew | 3 +- > 23 files changed, 340 insertions(+), 35 deletions(-) > >diff --git a/C4/Circulation.pm b/C4/Circulation.pm >index 5c05326123..67bec9bd45 100644 >--- a/C4/Circulation.pm >+++ b/C4/Circulation.pm >@@ -2671,6 +2671,7 @@ sub CanBookBeRenewed { > 'no_auto_renewal_after_hard_limit', > 'lengthunit', > 'norenewalbefore', >+ 'unseen_renewals_allowed' > ] > } > ); >@@ -2849,12 +2850,124 @@ sub CanBookBeRenewed { > > return ( 0, "auto_renew" ) if $auto_renew eq "ok" && !$override_limit; # 0 if auto-renewal should not succeed > >+ return ( 1, undef ) if $override_limit; >+ >+ my $branchcode = _GetCircControlBranch( $item->unblessed, $patron->unblessed ); >+ my $issuing_rule = Koha::CirculationRules->get_effective_rules( >+ { >+ categorycode => $patron->categorycode, >+ itemtype => $item->effective_itemtype, >+ branchcode => $branchcode, >+ rules => [ >+ 'renewalsallowed', >+ 'no_auto_renewal_after', >+ 'no_auto_renewal_after_hard_limit', >+ 'lengthunit', >+ 'norenewalbefore', >+ 'unseen_renewals_allowed' >+ ] >+ } >+ ); >+ >+ return ( 0, "too_many" ) >+ if not $issuing_rule->{renewalsallowed} or $issuing_rule->{renewalsallowed} <= $issue->renewals; >+ >+ return ( 0, "too_unseen" ) >+ if C4::Context->preference('UnseenRenewals') && >+ $issuing_rule->{unseen_renewals_allowed} && >+ $issuing_rule->{unseen_renewals_allowed} <= $issue->unseen_renewals; >+ >+ my $overduesblockrenewing = C4::Context->preference('OverduesBlockRenewing'); >+ my $restrictionblockrenewing = C4::Context->preference('RestrictionBlockRenewing'); >+ $patron = Koha::Patrons->find($borrowernumber); # FIXME Is this really useful? >+ my $restricted = $patron->is_debarred; >+ my $hasoverdues = $patron->has_overdues; >+ >+ if ( $restricted and $restrictionblockrenewing ) { >+ return ( 0, 'restriction'); >+ } elsif ( ($hasoverdues and $overduesblockrenewing eq 'block') || ($issue->is_overdue and $overduesblockrenewing eq 'blockitem') ) { >+ return ( 0, 'overdue'); >+ } >+ >+ if ( $issue->auto_renew ) { >+ >+ if ( $patron->category->effective_BlockExpiredPatronOpacActions and $patron->is_expired ) { >+ return ( 0, 'auto_account_expired' ); >+ } >+ >+ if ( defined $issuing_rule->{no_auto_renewal_after} >+ and $issuing_rule->{no_auto_renewal_after} ne "" ) { >+ # Get issue_date and add no_auto_renewal_after >+ # If this is greater than today, it's too late for renewal. >+ my $maximum_renewal_date = dt_from_string($issue->issuedate, 'sql'); >+ $maximum_renewal_date->add( >+ $issuing_rule->{lengthunit} => $issuing_rule->{no_auto_renewal_after} >+ ); >+ my $now = dt_from_string; >+ if ( $now >= $maximum_renewal_date ) { >+ return ( 0, "auto_too_late" ); >+ } >+ } >+ if ( defined $issuing_rule->{no_auto_renewal_after_hard_limit} >+ and $issuing_rule->{no_auto_renewal_after_hard_limit} ne "" ) { >+ # If no_auto_renewal_after_hard_limit is >= today, it's also too late for renewal >+ if ( dt_from_string >= dt_from_string( $issuing_rule->{no_auto_renewal_after_hard_limit} ) ) { >+ return ( 0, "auto_too_late" ); >+ } >+ } >+ >+ if ( C4::Context->preference('OPACFineNoRenewalsBlockAutoRenew') ) { >+ my $fine_no_renewals = C4::Context->preference("OPACFineNoRenewals"); >+ my $amountoutstanding = >+ C4::Context->preference("OPACFineNoRenewalsIncludeCredit") >+ ? $patron->account->balance >+ : $patron->account->outstanding_debits->total_outstanding; >+ if ( $amountoutstanding and $amountoutstanding > $fine_no_renewals ) { >+ return ( 0, "auto_too_much_oweing" ); >+ } >+ } >+ } >+ >+ if ( defined $issuing_rule->{norenewalbefore} >+ and $issuing_rule->{norenewalbefore} ne "" ) >+ { >+ >+ # Calculate soonest renewal by subtracting 'No renewal before' from due date >+ my $soonestrenewal = dt_from_string( $issue->date_due, 'sql' )->subtract( >+ $issuing_rule->{lengthunit} => $issuing_rule->{norenewalbefore} ); >+ >+ # Depending on syspref reset the exact time, only check the date >+ if ( C4::Context->preference('NoRenewalBeforePrecision') eq 'date' >+ and $issuing_rule->{lengthunit} eq 'days' ) >+ { >+ $soonestrenewal->truncate( to => 'day' ); >+ } >+ >+ if ( $soonestrenewal > DateTime->now( time_zone => C4::Context->tz() ) ) >+ { >+ return ( 0, "auto_too_soon" ) if $issue->auto_renew; >+ return ( 0, "too_soon" ); >+ } >+ elsif ( $issue->auto_renew ) { >+ return ( 0, "auto_renew" ); >+ } >+ } >+ >+ # Fallback for automatic renewals: >+ # If norenewalbefore is undef, don't renew before due date. >+ if ( $issue->auto_renew ) { >+ my $now = dt_from_string; >+ return ( 0, "auto_renew" ) >+ if $now >= dt_from_string( $issue->date_due, 'sql' ); >+ return ( 0, "auto_too_soon" ); >+ } >+ > return ( 1, undef ); > } > > =head2 AddRenewal > >- &AddRenewal($borrowernumber, $itemnumber, $branch, [$datedue], [$lastreneweddate]); >+ &AddRenewal($borrowernumber, $itemnumber, $branch, [$datedue], [$lastreneweddate], [$seen]); > > Renews a loan. > >@@ -2879,6 +2992,10 @@ syspref) > If C<$datedue> is the empty string, C<&AddRenewal> will calculate the due date automatically > from the book's item type. > >+C<$seen> is a boolean flag indicating if the item was seen or not during the renewal. This >+informs the incrementing of the unseen_renewals column. If this flag is not supplied, we >+fallback to a true value >+ > =cut > > sub AddRenewal { >@@ -2888,6 +3005,10 @@ sub AddRenewal { > my $datedue = shift; > my $lastreneweddate = shift || dt_from_string(); > my $skipfinecalc = shift; >+ my $seen = shift; >+ >+ # Fallback on a 'seen' renewal >+ $seen = defined $seen && $seen == 0 ? 0 : 1; > > my $item_object = Koha::Items->find($itemnumber) or return; > my $biblio = $item_object->biblio; >@@ -2940,15 +3061,35 @@ sub AddRenewal { > } > ); > >+ # Increment the unseen renewals, if appropriate >+ # We only do so if the syspref is enabled and >+ # a maximum value has been set in the circ rules >+ my $unseen_renewals = $issue->unseen_renewals; >+ if (C4::Context->preference('UnseenRenewals')) { >+ my $rule = Koha::CirculationRules->get_effective_rule( >+ { categorycode => $patron->categorycode, >+ itemtype => $item_object->effective_itemtype, >+ branchcode => $circ_library->branchcode, >+ rule_name => 'unseen_renewals_allowed' >+ } >+ ); >+ if (!$seen && $rule && $rule->rule_value) { >+ $unseen_renewals++; >+ } else { >+ # If the renewal is seen, unseen should revert to 0 >+ $unseen_renewals = 0; >+ } >+ } >+ > # Update the issues record to have the new due date, and a new count > # of how many times it has been renewed. > my $renews = ( $issue->renewals || 0 ) + 1; >- my $sth = $dbh->prepare("UPDATE issues SET date_due = ?, renewals = ?, lastreneweddate = ? >+ my $sth = $dbh->prepare("UPDATE issues SET date_due = ?, renewals = ?, unseen_renewals = ?, lastreneweddate = ? > WHERE borrowernumber=? > AND itemnumber=?" > ); > >- $sth->execute( $datedue->strftime('%Y-%m-%d %H:%M'), $renews, $lastreneweddate, $borrowernumber, $itemnumber ); >+ $sth->execute( $datedue->strftime('%Y-%m-%d %H:%M'), $renews, $unseen_renewals, $lastreneweddate, $borrowernumber, $itemnumber ); > > # Update the renewal count on the item, and tell zebra to reindex > $renews = ( $item_object->renewals || 0 ) + 1; >@@ -3035,8 +3176,11 @@ sub GetRenewCount { > my ( $bornum, $itemno ) = @_; > my $dbh = C4::Context->dbh; > my $renewcount = 0; >+ my $unseencount = 0; > my $renewsallowed = 0; >+ my $unseenallowed = 0; > my $renewsleft = 0; >+ my $unseenleft = 0; > > my $patron = Koha::Patrons->find( $bornum ); > my $item = Koha::Items->find($itemno); >@@ -3055,22 +3199,34 @@ sub GetRenewCount { > $sth->execute( $bornum, $itemno ); > my $data = $sth->fetchrow_hashref; > $renewcount = $data->{'renewals'} if $data->{'renewals'}; >+ $unseencount = $data->{'unseen_renewals'} if $data->{'unseen_renewals'}; > # $item and $borrower should be calculated > my $branchcode = _GetCircControlBranch($item->unblessed, $patron->unblessed); > >- my $rule = Koha::CirculationRules->get_effective_rule( >+ my $rules = Koha::CirculationRules->get_effective_rules( > { > categorycode => $patron->categorycode, > itemtype => $item->effective_itemtype, > branchcode => $branchcode, >- rule_name => 'renewalsallowed', >+ rules => [ 'renewalsallowed', 'unseen_renewals_allowed' ] > } > ); >- >- $renewsallowed = $rule ? $rule->rule_value : 0; >+ $renewsallowed = $rules ? $rules->{renewalsallowed} : 0; >+ $unseenallowed = $rules->{unseen_renewals_allowed} ? >+ $rules->{unseen_renewals_allowed} : >+ 0; > $renewsleft = $renewsallowed - $renewcount; >+ $unseenleft = $unseenallowed - $unseencount; > if($renewsleft < 0){ $renewsleft = 0; } >- return ( $renewcount, $renewsallowed, $renewsleft ); >+ if($unseenleft < 0){ $unseenleft = 0; } >+ return ( >+ $renewcount, >+ $renewsallowed, >+ $renewsleft, >+ $unseencount, >+ $unseenallowed, >+ $unseenleft >+ ); > } > > =head2 GetSoonestRenewDate >diff --git a/C4/ILSDI/Services.pm b/C4/ILSDI/Services.pm >index 5ebba3435d..e0d54914c3 100644 >--- a/C4/ILSDI/Services.pm >+++ b/C4/ILSDI/Services.pm >@@ -655,7 +655,7 @@ sub RenewLoan { > > # Add renewal if possible > my @renewal = CanBookBeRenewed( $borrowernumber, $itemnumber ); >- if ( $renewal[0] ) { AddRenewal( $borrowernumber, $itemnumber ); } >+ if ( $renewal[0] ) { AddRenewal( $borrowernumber, $itemnumber, undef, undef, undef, 0 ); } > > my $issue = $item->checkout; > return unless $issue; # FIXME should be handled >diff --git a/C4/SIP/ILS/Transaction/Renew.pm b/C4/SIP/ILS/Transaction/Renew.pm >index 7a21c89144..e950424d74 100644 >--- a/C4/SIP/ILS/Transaction/Renew.pm >+++ b/C4/SIP/ILS/Transaction/Renew.pm >@@ -51,6 +51,7 @@ sub do_renew_for { > } else { > $renewerror=~s/on_reserve/Item unavailable due to outstanding holds/; > $renewerror=~s/too_many/Item has reached maximum renewals/; >+ $renewerror=~s/too_unseen/Item has reached maximum consecutive renewals without being seen/; > $renewerror=~s/item_denied_renewal/Item renewal is not allowed/; > $self->screen_msg($renewerror); > $self->renewal_ok(0); >diff --git a/Koha/CirculationRules.pm b/Koha/CirculationRules.pm >index 87062f541a..283cc1bcc0 100644 >--- a/Koha/CirculationRules.pm >+++ b/Koha/CirculationRules.pm >@@ -148,6 +148,9 @@ our $RULE_KINDS = { > renewalsallowed => { > scope => [ 'branchcode', 'categorycode', 'itemtype' ], > }, >+ unseen_renewals_allowed => { >+ scope => [ 'branchcode', 'categorycode', 'itemtype' ], >+ }, > rentaldiscount => { > scope => [ 'branchcode', 'categorycode', 'itemtype' ], > }, >diff --git a/Koha/REST/V1/Checkouts.pm b/Koha/REST/V1/Checkouts.pm >index 9d5e5b42a1..93feeaeb24 100644 >--- a/Koha/REST/V1/Checkouts.pm >+++ b/Koha/REST/V1/Checkouts.pm >@@ -146,6 +146,7 @@ sub renew { > my $c = shift->openapi->valid_input or return; > > my $checkout_id = $c->validation->param('checkout_id'); >+ my $seen = $c->validation->param('seen') || 1; > my $checkout = Koha::Checkouts->find( $checkout_id ); > > unless ($checkout) { >@@ -169,7 +170,14 @@ sub renew { > ); > } > >- AddRenewal($borrowernumber, $itemnumber, $checkout->branchcode); >+ AddRenewal( >+ $borrowernumber, >+ $itemnumber, >+ $checkout->branchcode, >+ undef, >+ undef, >+ $seen >+ ); > $checkout = Koha::Checkouts->find($checkout_id); > > $c->res->headers->location( $c->req->url->to_string ); >@@ -223,6 +231,7 @@ sub allows_renewal { > allows_renewal => $renewable, > max_renewals => $rule->rule_value, > current_renewals => $checkout->renewals, >+ unseen_renewals => $checkout->unseen_renewals, > error => $error > } > ); >diff --git a/api/v1/swagger/definitions/checkout.json b/api/v1/swagger/definitions/checkout.json >index 42b9598843..fb98afd28e 100644 >--- a/api/v1/swagger/definitions/checkout.json >+++ b/api/v1/swagger/definitions/checkout.json >@@ -35,6 +35,10 @@ > "type": ["integer", "null"], > "description": "Number of renewals" > }, >+ "unseen_renewals": { >+ "type": ["integer", "null"], >+ "description": "Number of consecutive unseen renewals" >+ }, > "auto_renew": { > "type": "boolean", > "description": "Auto renewal" >diff --git a/api/v1/swagger/parameters.json b/api/v1/swagger/parameters.json >index cab2d53b47..7d1e13b385 100644 >--- a/api/v1/swagger/parameters.json >+++ b/api/v1/swagger/parameters.json >@@ -35,6 +35,9 @@ > "checkout_id_pp": { > "$ref": "parameters/checkout.json#/checkout_id_pp" > }, >+ "seen_pp": { >+ "$ref": "parameters/checkout.json#/seen_pp" >+ }, > "match": { > "name": "_match", > "in": "query", >diff --git a/api/v1/swagger/parameters/checkout.json b/api/v1/swagger/parameters/checkout.json >index 2bdb20ab84..3b802f0c30 100644 >--- a/api/v1/swagger/parameters/checkout.json >+++ b/api/v1/swagger/parameters/checkout.json >@@ -5,5 +5,12 @@ > "description": "Internal checkout identifier", > "required": true, > "type": "integer" >+ }, >+ "seen_pp": { >+ "name": "seen", >+ "in": "query", >+ "description": "Item was seen flag", >+ "required": false, >+ "type": "integer" > } > } >diff --git a/api/v1/swagger/paths/checkouts.json b/api/v1/swagger/paths/checkouts.json >index ca6d970dbb..a97b9f0572 100644 >--- a/api/v1/swagger/paths/checkouts.json >+++ b/api/v1/swagger/paths/checkouts.json >@@ -81,9 +81,10 @@ > "x-mojo-to": "Checkouts#renew", > "operationId": "renewCheckout", > "tags": ["patrons", "checkouts"], >- "parameters": [{ >- "$ref": "../parameters.json#/checkout_id_pp" >- }], >+ "parameters": [ >+ { "$ref": "../parameters.json#/checkout_id_pp" }, >+ { "$ref": "../parameters.json#/seen_pp" } >+ ], > "produces": ["application/json"], > "responses": { > "201": { >diff --git a/circ/renew.pl b/circ/renew.pl >index 29824187a8..58a16f8538 100755 >--- a/circ/renew.pl >+++ b/circ/renew.pl >@@ -43,6 +43,7 @@ my ( $template, $librarian, $cookie, $flags ) = get_template_and_user( > my $schema = Koha::Database->new()->schema(); > > my $barcode = $cgi->param('barcode'); >+my $unseen = $cgi->param('unseen') || 0; > $barcode =~ s/^\s*|\s*$//g; # remove leading/trailing whitespae > $barcode = barcodedecode($barcode) if( $barcode && C4::Context->preference('itemBarcodeInputFilter')); > my $override_limit = $cgi->param('override_limit'); >@@ -102,7 +103,15 @@ if ($barcode) { > if ( C4::Context->preference('SpecifyDueDate') && $hard_due_date ) { > $date_due = dt_from_string( $hard_due_date ); > } >- $date_due = AddRenewal( undef, $item->itemnumber(), $branchcode, $date_due ); >+ $date_due = AddRenewal( >+ undef, >+ $item->itemnumber(), >+ $branchcode, >+ $date_due, >+ undef, >+ undef, >+ !$unseen >+ ); > $template->param( date_due => $date_due ); > } > } >diff --git a/koha-tmpl/intranet-tmpl/prog/css/src/staff-global.scss b/koha-tmpl/intranet-tmpl/prog/css/src/staff-global.scss >index 6ad62428ed..d75de368bf 100644 >--- a/koha-tmpl/intranet-tmpl/prog/css/src/staff-global.scss >+++ b/koha-tmpl/intranet-tmpl/prog/css/src/staff-global.scss >@@ -1025,6 +1025,10 @@ div { > width: auto; > } > >+ .renew_formfield { >+ margin-bottom: 1em; >+ } >+ > .circmessage { > margin-bottom: .3em; > padding: 0 .4em .4em; >@@ -2481,6 +2485,14 @@ li { > position: relative; > } > >+#renew_as_unseen_label { >+ margin-left: 1em; >+} >+ >+#renew_as_unseen_checkbox { >+ margin-right: 1em; >+} >+ > #clearscreen { > position: absolute; > right: 0; >diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/checkouts-table.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/checkouts-table.inc >index 1efa03b568..f2e622af5b 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/includes/checkouts-table.inc >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/checkouts-table.inc >@@ -48,6 +48,10 @@ > [% END %] > [% END %] > [% IF ( CAN_user_circulate_circulate_remaining_permissions ) %] >+ [% IF Koha.Preference( 'UnseenRenewals' ) %] >+ <label id="renew_as_unseen_label" for="override_limit">Renew as "unseen" if appropriate:</label> >+ <input type="checkbox" name="renew_as_unseen" id="renew_as_unseen_checkbox" value="1" /> >+ [% END %] > <button class="btn btn-default" id="RenewCheckinChecked"><i class="fa fa-check"></i> Renew or check in selected items</button> > <button class="btn btn-default" id="RenewAll"><i class="fa fa-book"></i> Renew all</button> > [% END %] >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 778cdb3d9f..68531cf2fe 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt >@@ -1063,6 +1063,7 @@ > var logged_in_user_borrowernumber = "[% logged_in_user.borrowernumber | html %]"; > var ClaimReturnedLostValue = "[% Koha.Preference('ClaimReturnedLostValue') | html %]"; > var ClaimReturnedChargeFee = "[% Koha.Preference('ClaimReturnedChargeFee') | html %]"; >+ var UnseenRenewals = "[% Koha.Preference('UnseenRenewals') | html %]"; > var ClaimReturnedWarningThreshold = "[% Koha.Preference('ClaimReturnedWarningThreshold') | html %]"; > var interface = "[% interface | html %]"; > var theme = "[% theme | html %]"; >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/renew.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/renew.tt >index 717b815fd2..4fc969661d 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/renew.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/renew.tt >@@ -52,6 +52,18 @@ > </form> > [% END %] > >+ [% ELSIF error == "too_unseen" %] >+ >+ <p>[% INCLUDE 'biblio-title.inc' biblio=item.biblio %] ( [% item.barcode | html %] ) has been renewed the maximum number of consecutive times without being seen by the library )</p> >+ >+ [% IF Koha.Preference('AllowRenewalLimitOverride') %] >+ <form method="post" action="/cgi-bin/koha/circ/renew.pl"> >+ <input type="hidden" name="barcode" value="[% item.barcode | html %]"/> >+ <input type="hidden" name="override_limit" value="1" /> >+ <button type="submit" class="approve"><i class="fa fa-check"></i> Override limit and renew</button> >+ </form> >+ [% END %] >+ > [% ELSIF error == "too_soon" %] > > <p>[% INCLUDE 'biblio-title.inc' biblio=item.biblio %] ( [% item.barcode | html %] ) cannot be renewed before [% soonestrenewdate | $KohaDates %]. </p> >@@ -169,12 +181,25 @@ > <fieldset> > <h2>Renew</h2> > >- <div> >- <label for="barcode" class="hint">Enter item barcode: </label> >- </div> >- >- <input name="barcode" id="barcode" size="14" class="barcode focus" type="text" /> >- >+ [% IF Koha.Preference('UnseenRenewals') %] >+ <div class="renew_formfield"> >+ <div> >+ <label for="barcode" class="hint">Enter item barcode: </label> >+ </div> >+ <input name="barcode" id="barcode" size="14" class="barcode focus" type="text" /> >+ </div> >+ <div class="renew_formfield"> >+ <label for="unseen" class="hint">Record renewal as unseen if appropriate: </label> >+ <input value="1" name="unseen" id="unseen" type="checkbox" /> >+ </div> >+ [% ELSE %] >+ <div> >+ <label for="barcode" class="hint">Enter item barcode: </label> >+ </div> >+ >+ <input name="barcode" id="barcode" size="14" class="barcode focus" type="text" /> >+ >+ [% END %] > <button type="submit" class="btn btn-default">Submit</button> > > <div class="circ-settings show"> >@@ -184,7 +209,6 @@ > <button type="button" class="action btn btn-default btn-xs" id="cleardate" name="cleardate">Clear</button> > </div> <!-- /.date-select --> > </div> >- > </fieldset> > > >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt >index 4bf7ba95f7..bd277ac9a3 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/members/moremember.tt >@@ -924,6 +924,7 @@ > var ClaimReturnedLostValue = "[% Koha.Preference('ClaimReturnedLostValue') | html %]"; > var ClaimReturnedChargeFee = "[% Koha.Preference('ClaimReturnedChargeFee') | html %]"; > var ClaimReturnedWarningThreshold = "[% Koha.Preference('ClaimReturnedWarningThreshold') | html %]"; >+ var UnseenRenewals = "[% Koha.Preference('UnseenRenewals') | html %]"; > var interface = "[% interface | html %]"; > var theme = "[% theme | html %]"; > var borrowernumber = "[% patron.borrowernumber | html %]"; >diff --git a/koha-tmpl/intranet-tmpl/prog/js/checkouts.js b/koha-tmpl/intranet-tmpl/prog/js/checkouts.js >index 1b576b5b37..48c13db3cf 100644 >--- a/koha-tmpl/intranet-tmpl/prog/js/checkouts.js >+++ b/koha-tmpl/intranet-tmpl/prog/js/checkouts.js >@@ -152,9 +152,15 @@ $(document).ready(function() { > itemnumber: itemnumber, > borrowernumber: borrowernumber, > branchcode: branchcode, >- override_limit: override_limit, >+ override_limit: override_limit > }; > >+ if (UnseenRenewals) { >+ var ren = $("#renew_as_unseen_checkbox"); >+ var renew_unseen = ren.length > 0 && ren.is(':checked') ? 1 : 0; >+ params.seen = renew_unseen === 1 ? 0 : 1; >+ } >+ > // Determine which due date we need to use > var dueDate = isOnReserve ? > $("#newonholdduedate input").val() : >@@ -177,6 +183,8 @@ $(document).ready(function() { > content += __("not checked out"); > } else if ( data.error == "too_many" ) { > content += __("too many renewals"); >+ } else if ( data.error == "too_unseen" ) { >+ content += __("too many consecutive renewals without being seen by the library"); > } else if ( data.error == "on_reserve" ) { > content += __("on hold"); > } else if ( data.error == "restriction" ) { >@@ -440,6 +448,13 @@ $(document).ready(function() { > + __("Not renewable") > + "</span>"; > >+ span_style = "display: none"; >+ span_class = "renewals-allowed"; >+ } else if ( oObj.can_renew_error == "too_unseen" ) { >+ msg += "<span class='renewals-disabled'>" >+ + __("Must be renewed at the library") >+ + "</span>"; >+ > span_style = "display: none"; > span_class = "renewals-allowed"; > } else if ( oObj.can_renew_error == "restriction" ) { >@@ -536,8 +551,11 @@ $(document).ready(function() { > } > content += msg; > if ( can_renew || can_force_renew ) { >- content += "<span class='renewals'>(" >- + __("%s of %s renewals remaining").format(oObj.renewals_remaining, oObj.renewals_allowed) >+ content += "<span class='renewals'>("; >+ content + __("%s of %s renewals remaining").format(oObj.renewals_remaining, oObj.renewals_allowed); >+ if (UnseenRenewals && oObj.unseen_allowed) { >+ content += __(" / %s of %s unseen renewals remaining").format(oObj.unseen_remaining, oObj.unseen_allowed); >+ } > + ")</span>"; > } > >diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-user.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-user.tt >index 493a59d030..af1e809035 100644 >--- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-user.tt >+++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-user.tt >@@ -95,6 +95,8 @@ > <li>Your account has expired. Please contact the library for more information.</li> > [% ELSIF error == 'too_many' %] > <li>You have renewed this item the maximum number of times allowed.</li> >+ [% ELSIF error == 'too_unseen' %] >+ <li>You have renewed this item the maximum number of consecutive times without it being seen by the library.</li> > [% ELSIF error == 'too_soon' %] > <li>It is too soon after the checkout date for this item to be renewed.</li> > [% ELSIF error == 'on_reserve' %] >@@ -364,7 +366,12 @@ > [% IF ISSUE.itemtype_object.rentalcharge_hourly > 0 %] > <span class="renewalfee label label-warning">[% ISSUE.itemtype_object.rentalcharge_hourly | $Price %] per hour</span> > [% END %] >- <span class="renewals">([% ISSUE.renewsleft | html %] of [% ISSUE.renewsallowed | html %] renewals remaining)</span> >+ <span class="renewals">( >+ [% ISSUE.renewsleft | html %] of [% ISSUE.renewsallowed | html %] renewals remaining >+ [% IF Koha.Preference('UnseenRenewals') && ISSUE.unseenallowed %] >+ / [% ISSUE.unseenleft | html %] of [% ISSUE.unseenallowed | html %] renewals left before the item must be seen by the library >+ [% END %] >+ )</span> > [% ELSIF ( ISSUE.on_reserve ) %] > Not renewable <span class="renewals">(on hold)</span> > [% ELSIF ( ISSUE.too_many ) %] >@@ -375,16 +382,36 @@ > No longer renewable > [% ELSIF ISSUE.auto_too_much_oweing %] > Automatic renewal failed, you have unpaid fines. >- <span class="renewals">([% ISSUE.renewsleft | html %] of [% ISSUE.renewsallowed | html %] renewals remaining)</span> >+ <span class="renewals">( >+ [% ISSUE.renewsleft | html %] of [% ISSUE.renewsallowed | html %] renewals remaining >+ [% IF Koha.Preference('UnseenRenewals') && ISSUE.unseenallowed %] >+ / [% ISSUE.unseenleft | html %] of [% ISSUE.unseenallowed | html %] renewals left before the item must be seen by the library >+ [% END %] >+ )</span> > [% ELSIF ISSUE.auto_account_expired %] > Automatic renewal failed, your account is expired. >- <span class="renewals">([% ISSUE.renewsleft | html %] of [% ISSUE.renewsallowed | html %] renewals remaining)</span> >+ <span class="renewals">( >+ [% ISSUE.renewsleft | html %] of [% ISSUE.renewsallowed | html %] renewals remaining >+ [% IF Koha.Preference('UnseenRenewals') && ISSUE.unseenallowed %] >+ / [% ISSUE.unseenleft | html %] of [% ISSUE.unseenallowed | html %] renewals left before the item must be seen by the library >+ [% END %] >+ )</span> > [% ELSIF ( ISSUE.too_soon ) %] > No renewal before [% ISSUE.soonestrenewdate | html %] >- <span class="renewals">([% ISSUE.renewsleft | html %] of [% ISSUE.renewsallowed | html %] renewals remaining)</span> >+ <span class="renewals">( >+ [% ISSUE.renewsleft | html %] of [% ISSUE.renewsallowed | html %] renewals remaining >+ [% IF Koha.Preference('UnseenRenewals') && ISSUE.unseenallowed %] >+ / [% ISSUE.unseenleft | html %] of [% ISSUE.unseenallowed | html %] renewals left before the item must be seen by the library >+ [% END %] >+ )</span> > [% ELSIF ( ISSUE.auto_renew || ISSUE.auto_too_soon ) %] > Automatic renewal >- <span class="renewals">([% ISSUE.renewsleft | html %] of [% ISSUE.renewsallowed | html %] renewals remaining)</span> >+ <span class="renewals">( >+ [% ISSUE.renewsleft | html %] of [% ISSUE.renewsallowed | html %] renewals remaining >+ [% IF Koha.Preference('UnseenRenewals') && ISSUE.unseenallowed %] >+ / [% ISSUE.unseenleft | html %] of [% ISSUE.unseenallowed | html %] renewals left before the item must be seen by the library >+ [% END %] >+ )</span> > [% ELSIF ( ISSUE.item_denied_renewal ) %] > Renewal not allowed > [% END %] >@@ -639,7 +666,12 @@ > [% IF ( canrenew ) %] > <a href="/cgi-bin/koha/opac-renew.pl?from=opac_user&item=[% OVERDUE.itemnumber | uri %]&bornum=[% OVERDUE.borrowernumber | uri %]">Renew</a> > [% END %] >- <span class="renewals">([% OVERDUE.renewsleft | html %] of [% OVERDUE.renewsallowed | html %] renewals remaining)</span> >+ <span class="renewals">( >+ [% OVERDUE.renewsleft | html %] of [% OVERDUE.renewsallowed | html %] renewals remaining >+ [% IF Koha.Preference('UnseenRenewals') && ISSUE.unseenallowed %] >+ / [% OVERDUE.unseenleft | html %] of [% OVERDUE.unseenallowed | html %] renewals left before the item must be seen by the library >+ [% END %] >+ )</span> > [% ELSIF ( OVERDUE.norenew_overdue ) %] > Not allowed<span class="renewals">(overdue)</span> > [% ELSIF ( OVERDUE.onreserve ) %] >diff --git a/misc/cronjobs/automatic_renewals.pl b/misc/cronjobs/automatic_renewals.pl >index 1c47cfd680..a1027848ad 100755 >--- a/misc/cronjobs/automatic_renewals.pl >+++ b/misc/cronjobs/automatic_renewals.pl >@@ -95,7 +95,7 @@ while ( my $auto_renew = $auto_renews->next ) { > $auto_renew->issue_id, $auto_renew->borrowernumber, $auto_renew->itemnumber; > } > if ($confirm){ >- my $date_due = AddRenewal( $auto_renew->borrowernumber, $auto_renew->itemnumber, $auto_renew->branchcode ); >+ my $date_due = AddRenewal( $auto_renew->borrowernumber, $auto_renew->itemnumber, $auto_renew->branchcode, undef, undef, 0 ); > $auto_renew->auto_renew_error(undef)->store; > } > push @{ $report{ $auto_renew->borrowernumber } }, $auto_renew; >diff --git a/offline_circ/download.pl b/offline_circ/download.pl >index 386faebf41..1c3f0f2d79 100755 >--- a/offline_circ/download.pl >+++ b/offline_circ/download.pl >@@ -67,6 +67,7 @@ my $issues_query = q{SELECT > issues.date_due AS date_due, > issues.issuedate AS issuedate, > issues.renewals AS renewals, >+ issues.unseen_renewals AS unseen_renewals, > borrowers.cardnumber AS cardnumber, > CONCAT(borrowers.surname, ', ', borrowers.firstname) AS borrower_name > FROM issues >diff --git a/opac/opac-renew.pl b/opac/opac-renew.pl >index b1111d0e07..9fa3bdd56f 100755 >--- a/opac/opac-renew.pl >+++ b/opac/opac-renew.pl >@@ -62,7 +62,7 @@ else { > my ( $status, $error ) = > CanBookBeRenewed( $borrowernumber, $itemnumber ); > if ( $status == 1 && $opacrenew == 1 ) { >- AddRenewal( $borrowernumber, $itemnumber, undef, undef, undef ); >+ AddRenewal( $borrowernumber, $itemnumber, undef, undef, undef, undef, 0 ); > push( @renewed, $itemnumber ); > } > else { >diff --git a/opac/opac-user.pl b/opac/opac-user.pl >index a380d88f01..da2d030cde 100755 >--- a/opac/opac-user.pl >+++ b/opac/opac-user.pl >@@ -223,7 +223,14 @@ if ( $pending_checkouts->count ) { # Useless test > > # check if item is renewable > my ($status,$renewerror) = CanBookBeRenewed( $borrowernumber, $issue->{'itemnumber'} ); >- ($issue->{'renewcount'},$issue->{'renewsallowed'},$issue->{'renewsleft'}) = GetRenewCount($borrowernumber, $issue->{'itemnumber'}); >+ ( >+ $issue->{'renewcount'}, >+ $issue->{'renewsallowed'}, >+ $issue->{'renewsleft'}, >+ $issue->{'unseencount'}, >+ $issue->{'unseenallowed'}, >+ $issue->{'unseenleft'} >+ ) = GetRenewCount($borrowernumber, $issue->{'itemnumber'}); > ( $issue->{'renewalfee'}, $issue->{'renewalitemtype'} ) = GetIssuingCharges( $issue->{'itemnumber'}, $borrowernumber ); > $issue->{itemtype_object} = Koha::ItemTypes->find( Koha::Items->find( $issue->{itemnumber} )->effective_itemtype ); > if($status && C4::Context->preference("OpacRenewalAllowed")){ >@@ -235,6 +242,7 @@ if ( $pending_checkouts->count ) { # Useless test > > if ($renewerror) { > $issue->{'too_many'} = 1 if $renewerror eq 'too_many'; >+ $issue->{'too_unseen'} = 1 if $renewerror eq 'too_unseen'; > $issue->{'on_reserve'} = 1 if $renewerror eq 'on_reserve'; > $issue->{'norenew_overdue'} = 1 if $renewerror eq 'overdue'; > $issue->{'auto_renew'} = 1 if $renewerror eq 'auto_renew'; >diff --git a/svc/checkouts b/svc/checkouts >index 3e92e40198..05cc7d8a44 100755 >--- a/svc/checkouts >+++ b/svc/checkouts >@@ -162,7 +162,14 @@ while ( my $c = $sth->fetchrow_hashref() ) { > ) > : undef; > >- my ( $renewals_count, $renewals_allowed, $renewals_remaining ) = >+ my ( >+ $renewals_count, >+ $renewals_allowed, >+ $renewals_remaining, >+ $unseen_count, >+ $unseen_allowed, >+ $unseen_remaining >+ ) = > GetRenewCount( $c->{borrowernumber}, $c->{itemnumber} ); > > my ( $itemtype, $recordtype, $type_for_stat ); >@@ -240,6 +247,9 @@ while ( my $c = $sth->fetchrow_hashref() ) { > renewals_count => $renewals_count, > renewals_allowed => $renewals_allowed, > renewals_remaining => $renewals_remaining, >+ unseen_count => $unseen_count, >+ unseen_allowed => $unseen_allowed, >+ unseen_remaining => $unseen_remaining, > > return_claim_id => $c->{return_claim_id}, > return_claim_notes => $c->{return_claim_notes}, >diff --git a/svc/renew b/svc/renew >index 51b915b004..98d7498a7c 100755 >--- a/svc/renew >+++ b/svc/renew >@@ -46,6 +46,7 @@ my $borrowernumber = $input->param('borrowernumber'); > my $override_limit = $input->param('override_limit'); > my $branchcode = $input->param('branchcode') > || C4::Context->userenv->{'branch'}; >+my $seen = $input->param('seen'); > my $date_due; > if ( $input->param('date_due') ) { > $date_due = dt_from_string( scalar $input->param('date_due') ); >@@ -66,7 +67,7 @@ if ( $data->{error} && $data->{error} eq 'on_reserve' && C4::Context->preference > } > > if ( $data->{renew_okay} ) { >- $date_due = AddRenewal( $borrowernumber, $itemnumber, $branchcode, $date_due ); >+ $date_due = AddRenewal( $borrowernumber, $itemnumber, $branchcode, $date_due, undef, $seen ); > $data->{date_due} = output_pref( { dt => $date_due, as_due_date => 1 } ); > } > >-- >2.20.1
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 24083
:
95861
|
95862
|
95863
|
95864
|
95865
|
95866
|
95867
|
95868
|
98749
|
98750
|
98751
|
98752
|
98765
|
98766
|
98767
|
98768
|
100244
|
100245
|
100246
|
100247
|
100380
|
100381
|
100382
|
100383
|
100392
|
110607
|
110608
|
110609
|
110610
|
110611
|
111147
|
111148
|
111149
|
111150
|
111151
|
111152
|
111283
|
111284
|
111285
|
111286
|
111287
|
111288
|
111289
|
111290
|
111291
|
111292
|
111293
|
111849
|
111850
|
111851
|
111852
|
111853
|
111854
|
111855
|
111856
|
111857
|
111858
|
111859
|
111860
|
112230
|
112231
|
112232
|
112233
|
112234
|
112235
|
112236
|
112237
|
112238
|
112239
|
112240
|
112241
|
112242
|
112243
|
112410
|
112411
|
112412
|
112413
|
112414
|
112415
|
112416
|
112417
|
112418
|
112419
|
112420
|
112421
|
112422
|
112423
|
113073
|
113074
|
113075
|
113076
|
113077
|
113078
|
113079
|
113080
|
113314
|
113315
|
113484
|
113485
|
113486
|
113487
|
113488
|
113489
|
113490
|
113491
|
113492
|
113493
|
113494
|
113546
|
113556
|
113557
|
113814