From 38cf1fd318fc856dd4c167d00382570f946add07 Mon Sep 17 00:00:00 2001 From: Kyle Hall Date: Wed, 20 Aug 2008 11:21:44 -0500 Subject: [PATCH] Integrated version of the Koha Offline Circulation file uploader. It needs some testing and cleanup, but it works. Signed-off-by: Andrew Moore Signed-off-by: Galen Charlton --- C4/Circulation.pm | 128 +++++++++++++ .../en/modules/circ/circulation-home.tmpl | 7 + .../en/modules/offline_circ/process_koc.tmpl | 19 ++ .../en/modules/offline_circ/upload_koc.tmpl | 22 +++ offline_circ/process_koc.pl | 171 ++++++++++++++++++ offline_circ/upload_koc.pl | 43 +++++ 6 files changed, 390 insertions(+) create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/offline_circ/process_koc.tmpl create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/offline_circ/upload_koc.tmpl create mode 100755 offline_circ/process_koc.pl create mode 100755 offline_circ/upload_koc.pl diff --git a/C4/Circulation.pm b/C4/Circulation.pm index 9e97d47077..5b2043f692 100644 --- a/C4/Circulation.pm +++ b/C4/Circulation.pm @@ -63,9 +63,12 @@ BEGIN { &CanBookBeIssued &CanBookBeRenewed &AddIssue + &ForceIssue &AddRenewal + &ForceRenewal &GetRenewCount &GetItemIssue + &GetOpenIssue &GetItemIssues &GetBorrowerIssues &GetIssuingCharges @@ -78,6 +81,7 @@ BEGIN { # subs to deal with returns push @EXPORT, qw( &AddReturn + &ForceReturn &MarkIssueReturned ); @@ -1015,6 +1019,29 @@ sub AddIssue { } } +=head2 ForceIssue + +ForceIssue() + +Issues an item to a member, ignoring any problems that would normally dissallow the issue. + +=cut + +sub ForceIssue { + my ( $borrowernumber, $itemnumber, $date_due, $branchcode, $date ) = @_; +warn "ForceIssue( $borrowernumber, $itemnumber, $date_due, $branchcode, $date );"; + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare( "INSERT INTO `issues` ( `borrowernumber`, `itemnumber`, `date_due`, `branchcode`, `issuingbranch`, `returndate`, `lastreneweddate`, `return`, `renewals`, `timestamp`, `issuedate` ) + VALUES ( ?, ?, ?, ?, ?, NULL, NULL, NULL, NULL, NOW(), ? )" ); + $sth->execute( $borrowernumber, $itemnumber, $date_due, $branchcode, $branchcode, $date ); + $sth->finish(); + + my $item = GetBiblioFromItemNumber( $itemnumber ); + + UpdateStats( $branchcode, 'issue', undef, undef, $itemnumber, $item->{ 'itemtype' }, $borrowernumber ); +} + + =head2 GetLoanLength Get loan length for an itemtype, a borrower type and a branch @@ -1437,6 +1464,51 @@ sub AddReturn { return ( $doreturn, $messages, $iteminformation, $borrower ); } +=head2 ForceReturn + +ForceReturn( $barcode, $date, $branchcode ); + +Returns an item is if it were returned on C<$date>. + +This function is non-interactive and does not check for reserves. + +C<$barcode> is the barcode of the item being returned. + +C<$date> is the date of the actual return, in the format YYYY-MM-DD. + +C<$branchcode> is the branchcode for the library the item was returned to. + +=cut + +sub ForceReturn { + my ( $barcode, $date, $branchcode ) = @_; + my $dbh = C4::Context->dbh; + + my $item = GetBiblioFromItemNumber( undef, $barcode ); + + ## FIXME: Is there a way to get the borrower of an item through the Koha API? + my $sth=$dbh->prepare( "SELECT borrowernumber FROM issues WHERE itemnumber = ? AND returndate IS NULL"); + $sth->execute( $item->{'itemnumber'} ); + my ( $borrowernumber ) = $sth->fetchrow; + $sth->finish(); + + ## Move the issue from issues to old_issues + $sth = $dbh->prepare( "INSERT INTO old_issues ( SELECT * FROM issues WHERE itemnumber = ? AND returndate IS NULL )" ); + $sth->execute( $item->{'itemnumber'} ); + $sth->finish(); + ## Delete the row in issues + $sth = $dbh->prepare( "DELETE FROM issues WHERE itemnumber = ? AND returndate IS NULL" ); + $sth->execute( $item->{'itemnumber'} ); + $sth->finish(); + ## Now set the returndate + $sth = $dbh->prepare( 'UPDATE old_issues SET returndate = ? WHERE itemnumber = ? AND returndate IS NULL' ); + $sth->execute( $date, $item->{'itemnumber'} ); + $sth->finish(); + + UpdateStats( $branchcode, 'return', my $amount, my $other, $item->{ 'itemnumber' }, $item->{ 'itemtype' }, $borrowernumber ); +} + + =head2 MarkIssueReturned =over 4 @@ -1677,6 +1749,28 @@ sub GetItemIssue { return ($data); } +=head2 GetOpenIssue + +$issue = GetOpenIssue( $itemnumber ); + +Returns the row from the issues table if the item is currently issued, undef if the item is not currently issued + +C<$itemnumber> is the item's itemnumber + +Returns a hashref + +=cut + +sub GetOpenIssue { + my ( $itemnumber ) = @_; + + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare( "SELECT * FROM issues WHERE itemnumber = ? AND returndate IS NULL" ); + $sth->execute( $itemnumber ); + my $issue = $sth->fetchrow_hashref(); + return $issue; +} + =head2 GetItemIssues $issues = &GetItemIssues($itemnumber, $history); @@ -1973,6 +2067,40 @@ sub AddRenewal { UpdateStats( $branch, 'renew', $charge, '', $itemnumber, $item->{itype}, $borrowernumber); } + +=head2 ForceRenewal + +ForRenewal( $itemnumber, $date, $date_due ); + +Renews an item for the given date. This function should only be used to update renewals that have occurred in the past. + +C<$itemnumber> is the itemnumber of the item being renewed. + +C<$date> is the date the renewal took place, in the format YYYY-MM-DD + +C<$date_due> is the date the item is now due to be returned, in the format YYYY-MM-DD + +=cut + +sub ForceRenewal { + my ( $itemnumber, $date, $date_due ) = @_; + my $dbh = C4::Context->dbh; + + my $sth = $dbh->prepare("SELECT * FROM issues WHERE itemnumber = ? AND returndate IS NULL"); + $sth->execute( $itemnumber ); + my $issue = $sth->fetchrow_hashref(); + $sth->finish(); + + + $sth = $dbh->prepare('UPDATE issues SET renewals = ?, lastreneweddate = ?, date_due = ? WHERE itemnumber = ? AND returndate IS NULL'); + $sth->execute( $issue->{'renewals'} + 1, $date, $date_due, $itemnumber ); + $sth->finish(); + + my $item = GetBiblioFromItemNumber( $itemnumber ); + UpdateStats( $issue->{'branchcode'}, 'renew', undef, undef, $itemnumber, $item->{ 'itemtype' }, $issue->{'borrowernumber'} ); +} + + sub GetRenewCount { # check renewal status my ($bornum,$itemno)=@_; diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation-home.tmpl b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation-home.tmpl index ecf58ffe5d..dc673a9266 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation-home.tmpl +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation-home.tmpl @@ -43,6 +43,13 @@ + + diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/offline_circ/process_koc.tmpl b/koha-tmpl/intranet-tmpl/prog/en/modules/offline_circ/process_koc.tmpl new file mode 100644 index 0000000000..aa7c063630 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/offline_circ/process_koc.tmpl @@ -0,0 +1,19 @@ + +Koha › Circulation › Offline Circulation File Processing + + + + + + + + +

Koha Offline Circulation

+

Your data was processed. Here are the results.

+ + +

+ + + + \ No newline at end of file diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/offline_circ/upload_koc.tmpl b/koha-tmpl/intranet-tmpl/prog/en/modules/offline_circ/upload_koc.tmpl new file mode 100644 index 0000000000..bb16238b40 --- /dev/null +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/offline_circ/upload_koc.tmpl @@ -0,0 +1,22 @@ + +Koha › Circulation › Offline Circulation File Upload + + + + + + + + +

Upload Offline Circulation Data

+
+ + + +
+ + +
+ + + \ No newline at end of file diff --git a/offline_circ/process_koc.pl b/offline_circ/process_koc.pl new file mode 100755 index 0000000000..d15fb44455 --- /dev/null +++ b/offline_circ/process_koc.pl @@ -0,0 +1,171 @@ +#!/usr/bin/perl + +# 2008 Kyle Hall + +# 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., 59 Temple Place, +# Suite 330, Boston, MA 02111-1307 USA +# + +use strict; +require Exporter; + +use CGI; +use C4::Output; +use C4::Auth; +use C4::Koha; +use C4::Context; +use C4::Biblio; +use C4::Accounts; +use C4::Circulation; +use C4::Members; +use C4::Stats; + +use Date::Calc qw( Add_Delta_Days Date_to_Days ); + +use constant DEBUG => 0; + +our $query = new CGI; + +my ($template, $loggedinuser, $cookie) + = get_template_and_user( { template_name => "offline_circ/process_koc.tmpl", + query => $query, + type => "intranet", + authnotrequired => 1, + debug => 1, + }); + +## 'Local' globals. +our $dbh = C4::Context->dbh(); + +our $branchcode = C4::Context->userenv->{branch}; + +warn "Branchcode: $branchcode"; + +our @output; ## For storing messages to be displayed to the user + +$query::POST_MAX = 1024 * 10000; + +my $file = $query->param("kocfile"); +$file=~m/^.*(\\|\/)(.*)/; # strip the remote path and keep the filename +my $name = $file; + +my $header = <$file>; + +while ( my $line = <$file> ) { + my ( $type, $cardnumber, $barcode, $datetime ) = split( /\t/, $line ); + ( $datetime ) = split( /\+/, $datetime ); + my ( $date ) = split( / /, $datetime ); + + my $circ; + $circ->{ 'type' } = $type; + $circ->{ 'cardnumber' } = $cardnumber; + $circ->{ 'barcode' } = $barcode; + $circ->{ 'datetime' } = $datetime; + $circ->{ 'date' } = $date; + + if ( $circ->{ 'type' } eq 'issue' ) { + kocIssueItem( $circ, $branchcode ); + } elsif ( $circ->{ 'type' } eq 'return' ) { + kocReturnItem( $circ ); + } elsif ( $circ->{ 'type' } eq 'payment' ) { + kocMakePayment( $circ ); + } +} + +$template->param( + intranetcolorstylesheet => C4::Context->preference("intranetcolorstylesheet"), + intranetstylesheet => C4::Context->preference("intranetstylesheet"), + IntranetNav => C4::Context->preference("IntranetNav"), + + messages => \@output, + ); +output_html_with_http_headers $query, $cookie, $template->output; + +sub kocIssueItem { + my ( $circ, $branchcode ) = @_; + + my $borrower = GetMember( $circ->{ 'cardnumber' }, 'cardnumber' ); + my $item = GetBiblioFromItemNumber( undef, $circ->{ 'barcode' } ); + my $issue = GetItemIssue( $item->{'itemnumber'} ); + + my $issuingrule = GetIssuingRule( $borrower->{ 'categorycode' }, $item->{ 'itemtype' }, $branchcode ); + my $issuelength = $issuingrule->{ 'issuelength' }; + my ( $year, $month, $day ) = split( /-/, $circ->{'date'} ); + ( $year, $month, $day ) = Add_Delta_Days( $year, $month, $day, $issuelength ); + my $date_due = "$year-$month-$day"; + + if ( $issue->{ 'date_due' } ) { ## Item is currently checked out to another person. +warn "Item Currently Issued."; + my $issue = GetOpenIssue( $item->{'itemnumber'} ); + + if ( $issue->{'borrowernumber'} eq $borrower->{'borrowernumber'} ) { ## Issued to this person already, renew it. +warn "Item issued to this member already, renewing."; + + my $renewals = $issue->{'renewals'} + 1; + ForceRenewal( $item->{'itemnumber'}, $circ->{'date'}, $date_due ) unless ( DEBUG ); + + push( @output, { message => "Renewed $item->{ 'title' } ( $item->{ 'barcode' } ) to $borrower->{ 'firstname' } $borrower->{ 'surename' } ( $borrower->{'cardnumber'} ) : $circ->{ 'datetime' }\n" } ); + + } else { +warn "Item issued to a different member."; +warn "Date of previous issue: $issue->{'issuedate'}"; +warn "Date of this issue: $circ->{'date'}"; + my ( $i_y, $i_m, $i_d ) = split( /-/, $issue->{'issuedate'} ); + my ( $c_y, $c_m, $c_d ) = split( /-/, $circ->{'date'} ); + + if ( Date_to_Days( $i_y, $i_m, $i_d ) < Date_to_Days( $c_y, $c_m, $c_d ) ) { ## Current issue to a different persion is older than this issue, return and issue. +warn "Current issue to another member is older, returning and issuing"; + push( @output, { message => "$item->{ 'title' } ( $item->{'barcode'} ) currently issued, returning item.\n" } ); + ## AddReturnk() should be replaced with a custom function, as it will make the return date today, should be before the issue date of the current circ + AddReturn( $circ->{ 'barcode' }, $branchcode ) unless ( DEBUG ); + + ForceIssue( $borrower->{ 'borrowernumber' }, $item->{ 'itemnumber' }, $date_due, $branchcode, $circ->{'date'} ) unless ( DEBUG ); + + push( @output, { message => "Issued $item->{ 'title' } ( $item->{ 'barcode' } ) to $borrower->{ 'firstname' } $borrower->{ 'surename' } ( $borrower->{'cardnumber'} ) : $circ->{ 'datetime' }\n" } ); + + } else { ## Current issue is *newer* than this issue, write a 'returned' issue, as the item is most likely in the hands of someone else now. +warn "Current issue to another member is newer. Doing nothing"; + ## This situation should only happen of the Offline Circ data is *really* old. + ## FIXME: write line to old_issues and statistics + } + + } + } else { ## Item is not checked out to anyone at the moment, go ahead and issue it + ForceIssue( $borrower->{ 'borrowernumber' }, $item->{ 'itemnumber' }, $date_due, $branchcode, $circ->{'date'} ) unless ( DEBUG ); + push( @output, { message => "Issued $item->{ 'title' } ( $item->{ 'barcode' } ) to $borrower->{ 'firstname' } $borrower->{ 'surename' } ( $borrower->{'cardnumber'} ) : $circ->{ 'datetime' }\n" } ); + } +} + +sub kocReturnItem { + my ( $circ ) = @_; + ForceReturn( $circ->{'barcode'}, $circ->{'date'}, $branchcode ); + + my $item = GetBiblioFromItemNumber( undef, $circ->{'barcode'} ); + + ## FIXME: Is there a way to get the borrower of an item through the Koha API? + my $sth=$dbh->prepare( "SELECT borrowernumber FROM issues WHERE itemnumber = ? AND returndate IS NULL"); + $sth->execute( $item->{'itemnumber'} ); + my ( $borrowernumber ) = $sth->fetchrow; + $sth->finish(); + + push( @output, { message => "Returned $item->{ 'title' } ( $item->{ 'barcode' } ) From borrower number $borrowernumber : $circ->{ 'datetime' }\n" } ); +} + +sub kocMakePayment { + my ( $circ ) = @_; + my $borrower = GetMember( $circ->{ 'cardnumber' }, 'cardnumber' ); + recordpayment( my $env, $borrower->{'borrowernumber'}, $circ->{'barcode'} ); +} + diff --git a/offline_circ/upload_koc.pl b/offline_circ/upload_koc.pl new file mode 100755 index 0000000000..700d7cd2c1 --- /dev/null +++ b/offline_circ/upload_koc.pl @@ -0,0 +1,43 @@ +#!/usr/bin/perl + +# 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., 59 Temple Place, +# Suite 330, Boston, MA 02111-1307 USA +# + +use strict; +require Exporter; + +use C4::Output; +use C4::Auth; +use C4::Koha; + +use CGI; + +my $query = new CGI; + +my ($template, $loggedinuser, $cookie) += get_template_and_user({template_name => "offline_circ/upload_koc.tmpl", + query => $query, + type => "intranet", + authnotrequired => 1, + debug => 1, + }); + +$template->param( + intranetcolorstylesheet => C4::Context->preference("intranetcolorstylesheet"), + intranetstylesheet => C4::Context->preference("intranetstylesheet"), + IntranetNav => C4::Context->preference("IntranetNav"), + ); +output_html_with_http_headers $query, $cookie, $template->output; -- 2.39.2