Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Bug 8220 - Allow koc uploads to go to process queue instead of being …

…applied directly.

The primary advantage to the Firefox offline cirulation plugin when compared
to the offline circulation desktop application, is the ability to add offline
circulation actions to a queue so that multiple machines running offline
circ can have their circ actions combined and ordered chronologically before
being executed. This commit adds the ability to put actions from uploaded
KOC files into this queue. In this way, both the FF plugina and the desktop
application can be run side by side with no ill effects.

Signed-off-by: Bob Birchall <bob@calyx.net.au>
Signed-off-by: Katrin Fischer <Katrin.Fischer.83@web.de>
Signed-off-by: Jared Camins-Esakov <jcamins@cpbibliography.com>
  • Loading branch information...
commit 7224e47dfe433d94f19b14eade1abee5f5d5c964 1 parent 0fe805b
@kylemhall kylemhall authored jcamins committed
View
17 C4/Circulation.pm
@@ -3336,9 +3336,10 @@ sub GetOfflineOperation {
}
sub AddOfflineOperation {
+ my ( $userid, $branchcode, $timestamp, $action, $barcode, $cardnumber, $amount ) = @_;
my $dbh = C4::Context->dbh;
- my $sth = $dbh->prepare("INSERT INTO pending_offline_operations (userid, branchcode, timestamp, action, barcode, cardnumber) VALUES(?,?,?,?,?,?)");
- $sth->execute( @_ );
+ my $sth = $dbh->prepare("INSERT INTO pending_offline_operations (userid, branchcode, timestamp, action, barcode, cardnumber, amount) VALUES(?,?,?,?,?,?,?)");
+ $sth->execute( $userid, $branchcode, $timestamp, $action, $barcode, $cardnumber, $amount );
return "Added.";
}
@@ -3357,6 +3358,8 @@ sub ProcessOfflineOperation {
$report = ProcessOfflineReturn( $operation );
} elsif ( $operation->{action} eq 'issue' ) {
$report = ProcessOfflineIssue( $operation );
+ } elsif ( $operation->{action} eq 'payment' ) {
+ $report = ProcessOfflinePayment( $operation );
}
DeleteOfflineOperation( $operation->{operationid} ) if $operation->{operationid};
@@ -3426,6 +3429,16 @@ sub ProcessOfflineIssue {
}
}
+sub ProcessOfflinePayment {
+ my $operation = shift;
+
+ my $borrower = C4::Members::GetMemberDetails( undef, $operation->{cardnumber} ); # Get borrower from operation cardnumber
+ my $amount = $operation->{amount};
+
+ recordpayment( $borrower->{borrowernumber}, $amount );
+
+ return "Success."
+}
=head2 TransferSlip
View
18 installer/data/mysql/kohastructure.sql
@@ -1559,17 +1559,17 @@ CREATE TABLE `patronimage` ( -- information related to patron images
-- so MyISAM is better in this case
DROP TABLE IF EXISTS `pending_offline_operations`;
-CREATE TABLE `pending_offline_operations` (
- `operationid` int(11) NOT NULL AUTO_INCREMENT,
- `userid` varchar(30) NOT NULL,
- `branchcode` varchar(10) NOT NULL,
+CREATE TABLE pending_offline_operations (
+ operationid int(11) NOT NULL AUTO_INCREMENT,
+ userid varchar(30) NOT NULL,
+ branchcode varchar(10) NOT NULL,
`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`action` varchar(10) NOT NULL,
- `barcode` varchar(20) NOT NULL,
- `cardnumber` varchar(16) DEFAULT NULL,
- PRIMARY KEY (`operationid`)
-) ENGINE=MyISAM DEFAULT CHARSET=utf8;
-
+ barcode varchar(20) DEFAULT NULL,
+ cardnumber varchar(16) DEFAULT NULL,
+ amount decimal(28,6) DEFAULT NULL,
+ PRIMARY KEY (operationid)
+) ENGINE=MyISAM DEFAULT CHARSET=utf8;
--
View
9 installer/data/mysql/updatedatabase.pl
@@ -5828,8 +5828,6 @@ sub stocknumber_checker { #code reused later on
SetVersion($DBversion);
}
-
-
$DBversion = "3.09.00.050";
if (C4::Context->preference("Version") < TransformToNum($DBversion)) {
$dbh->do("ALTER TABLE authorised_values MODIFY category varchar(16) NOT NULL DEFAULT '';");
@@ -6528,6 +6526,13 @@ sub stocknumber_checker { #code reused later on
$DBversion = "3.11.00.100";
if (C4::Context->preference("Version") < TransformToNum($DBversion)) {
print "Upgrade to $DBversion done (3.12-alpha release)\n";
+}
+
+$DBversion = "3.11.00.XXX";
+if (C4::Context->preference("Version") < TransformToNum($DBversion)) {
+ $dbh->do("ALTER TABLE `pending_offline_operations` CHANGE `barcode` `barcode` VARCHAR( 20 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL");
+ $dbh->do("ALTER TABLE `pending_offline_operations` ADD `amount` DECIMAL( 28, 6 ) NULL DEFAULT NULL");
+ print "Upgrade to $DBversion done (Bug 8220 - Allow koc uploads to go to process queue)\n";
SetVersion ($DBversion);
}
View
8 koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation-home.tt
@@ -53,8 +53,12 @@
<div class="yui-u">
<h5>Offline circulation</h5>
<ul>
- <li><a href="/cgi-bin/koha/offline_circ/process_koc.pl">Offline circulation file (.koc) uploader</a></li>
- <li><a href="/cgi-bin/koha/offline_circ/list.pl">Offline circulation</a> (<a href="https://addons.mozilla.org/[% lang %]/firefox/addon/koct/">Firefox add-on</a>)</li>
+ <li><a href="/cgi-bin/koha/offline_circ/process_koc.pl">Upload offline circulation file (.koc)</a></li>
+ <li><a href="/cgi-bin/koha/offline_circ/list.pl">Pending offline circulation actions</a>
+ <ul>
+ <li><a href="http://kylehall.info/index.php/projects/koha/koha-offline-circulation/">Get desktop application</a></li>
+ <li><a href="https://addons.mozilla.org/[% lang %]/firefox/addon/koct/">Get Firefox add-on</a></li>
+ </ul>
</ul>
</div>
</div>
View
31 koha-tmpl/intranet-tmpl/prog/en/modules/offline_circ/enqueue_koc.tt
@@ -0,0 +1,31 @@
+[% INCLUDE 'doc-head-open.inc' %]
+<title>Koha &rsaquo; Circulation &rsaquo; Add offline circulations to queue</title>
+[% INCLUDE 'doc-head-close.inc' %]
+</head>
+<body>
+[% INCLUDE 'header.inc' %]
+[% INCLUDE 'circ-search.inc' %]
+
+<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; <a href="/cgi-bin/koha/circ/circulation-home.pl">Circulation</a> &rsaquo; <a href="/cgi-bin/koha/offline_circ/process_koc.pl">Add offline circulations to queue</a></div>
+
+<div id="doc" class="yui-t7">
+
+ <div id="bd">
+
+ <h2>Koha offline circulation</h2>
+ <p>Your file was processed.</p>
+
+[% FOREACH message IN messages %]
+ [% IF ( message.message ) %]
+ [% IF ( message.ERROR_file_version ) %]
+ <div class="dialog alert"><p>Warning: This file is version [% message.upload_version %], but I only know how to import version [% message.current_version %]. I'll try my best.</p>
+ [% END %]
+ [% END %]
+[% END %]
+
+<p><a href="process_koc.pl">Upload another KOC file</a></p>
+
+<p><a href="list.pl">View pending offline circulation actions</a></p>
+
+</div>
+[% INCLUDE 'intranet-bottom.inc' %]
View
6 koha-tmpl/intranet-tmpl/prog/en/modules/offline_circ/list.tt
@@ -78,7 +78,8 @@
<th>Date</th>
<th>Action</th>
<th>Barcode</th>
- <th>Card number</th>
+ <th>Card number</th>
+ <th>Amount</th>
</tr>
</thead>
<tbody>
@@ -95,7 +96,7 @@
[% END %]
</td>
<td>
- [% IF ( operation.actionissue ) %]
+ [% IF ( operation.actionissue || operation.actionpayment) %]
[% IF ( operation.borrowernumber ) %]
<a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% operation.borrowernumber %]" title="[% operation.borrower %]">[% operation.cardnumber %]</a>
[% ELSE %]
@@ -103,6 +104,7 @@
[% END %]
[% END %]
</td>
+ <td>[% operation.amount %]</td>
</tr>
[% END %]
</tbody>
View
34 koha-tmpl/intranet-tmpl/prog/en/modules/offline_circ/process_koc.tt
@@ -6,22 +6,25 @@
<script type="text/javascript">
//<![CDATA[
$(document).ready(function(){
- $("#processfile").hide();
+ $("#enqueuefile").hide();
+ $("#processfile").hide();
});
+
function CheckUpload(f){
- if(f.fileToUpload.value == ""){
- alert(_("Please choose a file to upload"));
- } else {
- return ajaxFileUpload()
- }
- return false;
+ if (f.fileToUpload.value == ""){
+ alert(_("Please choose a file to upload"));
+ } else {
+ return ajaxFileUpload()
+ }
+ return false;
}
+
function CheckForm(f) {
if (f.uploadedfileid.value == '') {
alert(_("Please upload a file first."));
} else {
- $("#fileuploadstatus").hide();
- $("#fileuploadform").slideUp();
+ $("#fileuploadstatus").hide();
+ $("#fileuploadform").slideUp();
return submitBackgroundJob(f);
}
return false;
@@ -60,7 +63,8 @@ function CheckForm(f) {
[% IF ( message.payment ) %]<p>Accepted payment ([% message.amount %]) from <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% message.borrowernumber %]">[% message.firstname %] [% message.surname %]</a> ([% message.cardnumber %]): [% message.datetime %]</p>[% END %]
[% END %]
[% ELSE %]
- <h2>Upload offline circulation data</h2>
+ <h2>Upload offline circulation data</h2>
+
<div id="fileuploadform">
<form method="post" action="[% SCRIPT_NAME %]" enctype="multipart/form-data">
<fieldset class="brief">
@@ -72,11 +76,17 @@ function CheckForm(f) {
<div id="fileuploadstatus" style="display:none">Upload progress: <div id="fileuploadprogress"></div> <span id="fileuploadpercent">0</span>%</div>
<div id="fileuploadfailed" style="display:none"></div>
</div>
- <form action="process_koc.pl" id="processfile" method="post" enctype="multipart/form-data">
+
+ <form action="enqueue_koc.pl" id="processfile" method="post" enctype="multipart/form-data">
+ <input type="hidden" name="uploadedfileid" id="uploadedfileid" value="" />
+ <input type="submit" value="Add to offline circulation queue" onclick="return CheckForm(this.form);" id="queueformsubmit" />
+ </form>
+
+ <form action="process_koc.pl" id="enqueuefile" method="post" enctype="multipart/form-data">
<input type="hidden" name="uploadedfileid" id="uploadedfileid" value="" />
<input type="hidden" name="runinbackground" id="runinbackground" value="" />
<input type="hidden" name="completedJobID" id="completedJobID" value="" />
- <input type="submit" value="Process offline circulation file" onclick="return CheckForm(this.form);" id="mainformsubmit" />
+ <input type="submit" value="Apply directly" onclick="return CheckForm(this.form);" id="mainformsubmit" />
<div id="jobstatus" style="display:none">Job progress: <div id="jobprogress"></div> <span id="jobprogresspercent">0</span>%</div>
<div id="jobfailed" style="display:none"></div>
</form>
View
197 offline_circ/enqueue_koc.pl
@@ -0,0 +1,197 @@
+#!/usr/bin/perl
+
+# 2008 Kyle Hall <kyle.m.hall@gmail.com>
+
+# 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 strict;
+use warnings;
+
+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::Items;
+use C4::Members;
+use C4::Stats;
+use C4::UploadedFile;
+
+use Date::Calc qw( Add_Delta_Days Date_to_Days );
+
+use constant DEBUG => 0;
+
+# this is the file version number that we're coded against.
+my $FILE_VERSION = '1.0';
+
+my $query = CGI->new;
+my @output;
+
+my ($template, $loggedinuser, $cookie) = get_template_and_user({
+ template_name => "offline_circ/enqueue_koc.tmpl",
+ query => $query,
+ type => "intranet",
+ authnotrequired => 0,
+ flagsrequired => { circulate => "circulate_remaining_permissions" },
+});
+
+
+my $fileID=$query->param('uploadedfileid');
+my %cookies = parse CGI::Cookie($cookie);
+my $sessionID = $cookies{'CGISESSID'}->value;
+## 'Local' globals.
+our $dbh = C4::Context->dbh();
+
+if ($fileID) {
+ my $uploaded_file = C4::UploadedFile->fetch($sessionID, $fileID);
+ my $fh = $uploaded_file->fh();
+ my @input_lines = <$fh>;
+
+ my $header_line = shift @input_lines;
+ my $file_info = parse_header_line($header_line);
+ if ($file_info->{'Version'} ne $FILE_VERSION) {
+ push @output, {
+ message => 1,
+ ERROR_file_version => 1,
+ upload_version => $file_info->{'Version'},
+ current_version => $FILE_VERSION
+ };
+ }
+
+ my $userid = C4::Context->userenv->{id};
+ my $branchcode = C4::Context->userenv->{branch};
+
+ foreach my $line (@input_lines) {
+ my $command_line = parse_command_line($line);
+ my $timestamp = $command_line->{'date'} . ' ' . $command_line->{'time'};
+ my $action = $command_line->{'command'};
+ my $barcode = $command_line->{'barcode'};
+ my $cardnumber = $command_line->{'cardnumber'};
+ my $amount = $command_line->{'amount'};
+
+ AddOfflineOperation( $userid, $branchcode, $timestamp, $action, $barcode, $cardnumber, $amount );
+ }
+
+}
+
+$template->param( messages => \@output );
+
+output_html_with_http_headers $query, $cookie, $template->output;
+
+=head1 FUNCTIONS
+
+=head2 parse_header_line
+
+parses the header line from a .koc file. This is the line that
+specifies things such as the file version, and the name and version of
+the offline circulation tool that generated the file. See
+L<http://wiki.koha-community.org/wiki/Koha_offline_circulation_file_format>
+for more information.
+
+pass in a string containing the header line (the first line from th
+file).
+
+returns a hashref containing the information from the header.
+
+=cut
+
+sub parse_header_line {
+ my $header_line = shift;
+ chomp($header_line);
+ $header_line =~ s/\r//g;
+
+ my @fields = split( /\t/, $header_line );
+ my %header_info = map { split( /=/, $_ ) } @fields;
+ return \%header_info;
+}
+
+=head2 parse_command_line
+
+=cut
+
+sub parse_command_line {
+ my $command_line = shift;
+ chomp($command_line);
+ $command_line =~ s/\r//g;
+
+ my ( $timestamp, $command, @args ) = split( /\t/, $command_line );
+ my ( $date, $time, $id ) = split( /\s/, $timestamp );
+
+ my %command = (
+ date => $date,
+ time => $time,
+ id => $id,
+ command => $command,
+ );
+
+ # set the rest of the keys using a hash slice
+ my $argument_names = arguments_for_command($command);
+ @command{@$argument_names} = @args;
+
+ return \%command;
+
+}
+
+=head2 arguments_for_command
+
+fetches the names of the columns (and function arguments) found in the
+.koc file for a particular command name. For instance, the C<issue>
+command requires a C<cardnumber> and C<barcode>. In that case this
+function returns a reference to the list C<qw( cardnumber barcode )>.
+
+parameters: the command name
+
+returns: listref of column names.
+
+=cut
+
+sub arguments_for_command {
+ my $command = shift;
+
+ # define the fields for this version of the file.
+ my %format = (
+ issue => [qw( cardnumber barcode )],
+ return => [qw( barcode )],
+ payment => [qw( cardnumber amount )],
+ );
+
+ return $format{$command};
+}
+
+=head2 _get_borrowernumber_from_barcode
+
+pass in a barcode
+get back the borrowernumber of the patron who has it checked out.
+undef if that can't be found
+
+=cut
+
+sub _get_borrowernumber_from_barcode {
+ my $barcode = shift;
+
+ return unless $barcode;
+
+ my $item = GetBiblioFromItemNumber( undef, $barcode );
+ return unless $item->{'itemnumber'};
+
+ my $issue = C4::Circulation::GetItemIssue( $item->{'itemnumber'} );
+ return unless $issue->{'borrowernumber'};
+ return $issue->{'borrowernumber'};
+}
View
1  offline_circ/list.pl
@@ -54,6 +54,7 @@
}
$_->{'actionissue'} = $_->{'action'} eq 'issue';
$_->{'actionreturn'} = $_->{'action'} eq 'return';
+ $_->{'actionpayment'} = $_->{'action'} eq 'payment';
}
$template->param(pending_operations => $operations);
Please sign in to comment.
Something went wrong with that request. Please try again.