From f2a2d596671ab7af63850f6842b4fc007e3547a5 Mon Sep 17 00:00:00 2001 From: Kyle M Hall Date: Wed, 19 Jun 2013 05:28:01 -0400 Subject: [PATCH] [PASSED QA] Bug 10493 - Add renewal script Koha needs a renewal tool that functions similar to the returns where a librarian can continuously scan items for renewal. This script should block renewals that are impossible, and allow the same renewal overrides as circulation.pl Test plan: 1) Apply the patches for bug 8798 2) Apply this patch 3) Browse to /cgi-bin/koha/circ/renew.pl 4) Enter an invalid barcode, you should get an error message 5) Enter a valid, but not checked out barcode, you should get an error message. 6) Enter a valid barcode that is checkout out and should be renewable, you should get a success message. 7) Enable AllowRenewalLimitOverride 8) Enter a barcode for an item that has been renewed too many times 9) You should get a warning which you can override. 10) Disable AllowRenewalLimitOverride 11) Repeat steap 8 12) You should get a blocking error message 11) Enter a barcode for an item with unfilled holds on it, you should get an overridable warning Signed-off-by: Owen Leonard Signed-off-by: Katrin Fischer Passes all tests and QA script, some issues have been addressed in follow-ups. --- C4/Circulation.pm | 37 ++++-- C4/Items.pm | 4 + C4/Reserves.pm | 7 +- Koha/Schema/Result/Issue.pm | 7 +- Koha/Schema/Result/Item.pm | 6 +- circ/renew.pl | 102 ++++++++++++++++ .../prog/en/modules/circ/circulation-home.tt | 1 + .../intranet-tmpl/prog/en/modules/circ/renew.tt | 131 +++++++++++++++++++++ 8 files changed, 278 insertions(+), 17 deletions(-) create mode 100755 circ/renew.pl create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/circ/renew.tt diff --git a/C4/Circulation.pm b/C4/Circulation.pm index d74b97f..4a5103f 100644 --- a/C4/Circulation.pm +++ b/C4/Circulation.pm @@ -2463,17 +2463,19 @@ already renewed the loan. $error will contain the reason the renewal can not pro =cut sub CanBookBeRenewed { - - # check renewal status my ( $borrowernumber, $itemnumber, $override_limit ) = @_; + my $dbh = C4::Context->dbh; my $renews = 1; my $renewokay = 0; my $error; - my $borrower = C4::Members::GetMemberDetails( $borrowernumber, 0 ) or return; - my $item = GetItem($itemnumber) or return; - my $itemissue = GetItemIssue($itemnumber) or return; + my $item = GetItem($itemnumber) or return ( 0, 'no_item' ); + my $itemissue = GetItemIssue($itemnumber) or return ( 0, 'no_checkout' ); + + $borrowernumber ||= $itemissue->{borrowernumber}; + my $borrower = C4::Members::GetMemberDetails($borrowernumber) + or return; my $branchcode = _GetCircControlBranch($item, $borrower); @@ -2492,6 +2494,12 @@ sub CanBookBeRenewed { $error = "on_reserve"; } + if ( ( $issuingrule->{renewalsallowed} > $itemissue->{renewals} ) || $override_limit ) { + $renewokay = 1; + } else { + $error = "too_many"; + } + return ( $renewokay, $error ); } @@ -2520,27 +2528,32 @@ from the book's item type. =cut sub AddRenewal { - my $borrowernumber = shift or return; + my $borrowernumber = shift; my $itemnumber = shift or return; my $branch = shift; my $datedue = shift; my $lastreneweddate = shift || DateTime->now(time_zone => C4::Context->tz)->ymd(); + my $item = GetItem($itemnumber) or return; my $biblio = GetBiblioFromItemNumber($itemnumber) or return; my $dbh = C4::Context->dbh; + # Find the issues record for this book my $sth = - $dbh->prepare("SELECT * FROM issues - WHERE borrowernumber=? - AND itemnumber=?" - ); - $sth->execute( $borrowernumber, $itemnumber ); + $dbh->prepare("SELECT * FROM issues WHERE itemnumber = ?"); + $sth->execute( $itemnumber ); my $issuedata = $sth->fetchrow_hashref; - if(defined $datedue && ref $datedue ne 'DateTime' ) { + + return unless ( $issuedata ); + + $borrowernumber ||= $issuedata->{borrowernumber}; + + if ( defined $datedue && ref $datedue ne 'DateTime' ) { carp 'Invalid date passed to AddRenewal.'; return; } + # If the due date wasn't specified, calculate it by adding the # book's loan length to today's date or the current due date # based on the value of the RenewalPeriodBase syspref. diff --git a/C4/Items.pm b/C4/Items.pm index 8116c22..67d8736 100644 --- a/C4/Items.pm +++ b/C4/Items.pm @@ -145,6 +145,7 @@ sub GetItem { my ($itemnumber,$barcode, $serial) = @_; my $dbh = C4::Context->dbh; my $data; + if ($itemnumber) { my $sth = $dbh->prepare(" SELECT * FROM items @@ -159,6 +160,9 @@ sub GetItem { $sth->execute($barcode); $data = $sth->fetchrow_hashref; } + + return unless ( $data ); + if ( $serial) { my $ssth = $dbh->prepare("SELECT serialseq,publisheddate from serialitems left join serial on serialitems.serialid=serial.serialid where serialitems.itemnumber=?"); $ssth->execute($data->{'itemnumber'}) ; diff --git a/C4/Reserves.pm b/C4/Reserves.pm index bf1e398..f8666a3 100644 --- a/C4/Reserves.pm +++ b/C4/Reserves.pm @@ -800,10 +800,11 @@ sub GetReserveStatus { if(defined $found) { return 'Waiting' if $found eq 'W' and $priority == 0; return 'Finished' if $found eq 'F'; - return 'Reserved' if $priority > 0; } - return ''; - #empty string here will remove need for checking undef, or less log lines + + return 'Reserved' if $priority > 0; + + return ''; # empty string here will remove need for checking undef, or less log lines } =head2 CheckReserves diff --git a/Koha/Schema/Result/Issue.pm b/Koha/Schema/Result/Issue.pm index 3bf4545..282c802 100644 --- a/Koha/Schema/Result/Issue.pm +++ b/Koha/Schema/Result/Issue.pm @@ -183,6 +183,11 @@ __PACKAGE__->belongs_to( # Created by DBIx::Class::Schema::Loader v0.07025 @ 2013-10-14 20:56:21 # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:ZEh31EKBmURMKxDxI+H3EA +__PACKAGE__->belongs_to( + "borrower", + "Koha::Schema::Result::Borrower", + { borrowernumber => "borrowernumber" }, + { join_type => "LEFT", on_delete => "CASCADE", on_update => "CASCADE" }, +); -# You can replace this text with custom content, and it will be preserved on regeneration 1; diff --git a/Koha/Schema/Result/Item.pm b/Koha/Schema/Result/Item.pm index b65e7d5..055f801 100644 --- a/Koha/Schema/Result/Item.pm +++ b/Koha/Schema/Result/Item.pm @@ -588,6 +588,10 @@ __PACKAGE__->might_have( # Created by DBIx::Class::Schema::Loader v0.07025 @ 2013-10-14 20:56:21 # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:JV1Q/UVlKQ6QgVFMGBIZCw +__PACKAGE__->belongs_to( + "biblio", + "Koha::Schema::Result::Biblio", + { "foreign.biblionumber" => "self.biblionumber" } +); -# You can replace this text with custom content, and it will be preserved on regeneration 1; diff --git a/circ/renew.pl b/circ/renew.pl new file mode 100755 index 0000000..6634c0c --- /dev/null +++ b/circ/renew.pl @@ -0,0 +1,102 @@ +#!/usr/bin/perl + +# Copyright 2013 ByWater Solutions +# +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# Koha is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with Koha; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +use Modern::Perl; + +use CGI; +use C4::Context; +use C4::Auth qw/:DEFAULT get_session/; +use C4::Output; +use C4::Circulation; +use Koha::DateUtils; +use Koha::Database; + +my $cgi = new CGI; + +my ( $template, $librarian, $cookie ) = get_template_and_user( + { + template_name => "circ/renew.tmpl", + query => $cgi, + type => "intranet", + authnotrequired => 0, + flagsrequired => { circulate => "circulate_remaining_permissions" }, + } +); + +my $schema = Koha::Database->new()->schema(); + +my $barcode = $cgi->param('barcode'); +my $override_limit = $cgi->param('override_limit'); +my $override_holds = $cgi->param('override_holds'); + +my ( $item, $issue, $borrower, $error ); + +if ($barcode) { + $item = $schema->resultset("Item")->single( { barcode => $barcode } ); + + if ($item) { + + $issue = $item->issues()->single(); + + if ($issue) { + + $borrower = $issue->borrower(); + + if ( $borrower->debarred() lt dt_from_string()->ymd() ) { + my $can_renew; + ( $can_renew, $error ) = + CanBookBeRenewed( $borrower->borrowernumber(), + $item->itemnumber(), $override_limit ); + + if ( $error eq 'on_reserve' ) { + if ($override_holds) { + $can_renew = 1; + $error = undef; + } + else { + $can_renew = 0; + } + } + + if ($can_renew) { + my $date_due = AddRenewal( undef, $item->itemnumber() ); + $template->param( date_due => $date_due ); + } + } + else { + $error = "patron_restricted"; + } + } + else { + $error = "no_checkout"; + } + } + else { + $error = "no_item"; + } + + $template->param( + item => $item, + issue => $issue, + borrower => $borrower, + error => $error + ); +} + +output_html_with_http_headers( $cgi, $cookie, $template->output ); diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation-home.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation-home.tt index 72abd1f..e5eaddc 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation-home.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation-home.tt @@ -19,6 +19,7 @@
  • Check out
  • Check in
  • +
  • Renew
  • [% IF ( display_transfer ) %]
  • Transfer
  • [% END %] diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/renew.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/renew.tt new file mode 100644 index 0000000..eba8892 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/renew.tt @@ -0,0 +1,131 @@ +[% USE Koha %] +[% USE KohaDates %] +[% USE KohaBranchName %] + +[% INCLUDE 'doc-head-open.inc' %] + +Koha › Circulation › Renew [% title |html %] + +[% INCLUDE 'doc-head-close.inc' %] + + + + + + + +[% INCLUDE 'header.inc' %] +[% INCLUDE 'circ-search.inc' %] + + + +
    +
    +
    + +
    + [% IF error %] +
    +

    Cannot renew:

    +

    + [% IF error == "no_item" %] + + No item matches this barcode + + [% ELSIF error == "no_checkout" %] + + [% item.biblio.title %] [% item.biblioitem.subtitle %] + ( [% item.barcode %] ) + is not checked out to a patron. + + [% ELSIF error == "too_many" %] + + [% item.biblio.title %] [% item.biblioitem.subtitle %] ( [% item.barcode %] ) + has been renewed the maximum number of times by + [% borrower.firstname %] [% borrower.surname %] ( [% borrower.cardnumber %] ) + + [% IF Koha.Preference('AllowRenewalLimitOverride') %] +

    + + + +
    + [% END %] + + [% ELSIF error == "on_reserve" %] + + This item is on hold for other patrons. + +
    + + + + +
    + + [% ELSIF error == "patron_restricted" %] + + [% borrower.firstname %] [% borrower.surname %] ( [% borrower.cardnumber %] ) + is currently restricted. + + [% ELSE %] + + [% error %] + + [% END %] + + Ignore & continue +

    +
    + [% END %] + + [% IF date_due %] +
    +

    +

    Item renewed:

    + + [% item.biblio.title %] [% item.biblioitem.subtitle %] + ( [% item.barcode %] ) + renewed for + [% borrower.firstname %] [% borrower.surname %] ( [% borrower.cardnumber %] ) + now due on [% date_due | $KohaDates %] +

    +
    + [% END %] +
    + +
    + + [% UNLESS error %] +
    + +
    +
    + Renew + + + + + + +
    +
    + +
    + [% END %] + +
    + +
    + +
    + +[% INCLUDE 'intranet-bottom.inc' %] -- 1.8.1.2