View | Details | Raw Unified | Return to bug 8220
Collapse All | Expand All

(-)a/C4/Circulation.pm (-2 / +15 lines)
Lines 3152-3160 sub GetOfflineOperation { Link Here
3152
}
3152
}
3153
3153
3154
sub AddOfflineOperation {
3154
sub AddOfflineOperation {
3155
    my ( $userid, $branchcode, $timestamp, $action, $barcode, $cardnumber, $amount ) = @_;
3155
    my $dbh = C4::Context->dbh;
3156
    my $dbh = C4::Context->dbh;
3156
    my $sth = $dbh->prepare("INSERT INTO pending_offline_operations (userid, branchcode, timestamp, action, barcode, cardnumber) VALUES(?,?,?,?,?,?)");
3157
    my $sth = $dbh->prepare("INSERT INTO pending_offline_operations (userid, branchcode, timestamp, action, barcode, cardnumber, amount) VALUES(?,?,?,?,?,?,?)");
3157
    $sth->execute( @_ );
3158
    $sth->execute( $userid, $branchcode, $timestamp, $action, $barcode, $cardnumber, $amount );
3158
    return "Added.";
3159
    return "Added.";
3159
}
3160
}
3160
3161
Lines 3173-3178 sub ProcessOfflineOperation { Link Here
3173
        $report = ProcessOfflineReturn( $operation );
3174
        $report = ProcessOfflineReturn( $operation );
3174
    } elsif ( $operation->{action} eq 'issue' ) {
3175
    } elsif ( $operation->{action} eq 'issue' ) {
3175
        $report = ProcessOfflineIssue( $operation );
3176
        $report = ProcessOfflineIssue( $operation );
3177
    } elsif ( $operation->{action} eq 'payment' ) {
3178
        $report = ProcessOfflinePayment( $operation );
3176
    }
3179
    }
3177
3180
3178
    DeleteOfflineOperation( $operation->{operationid} ) if $operation->{operationid};
3181
    DeleteOfflineOperation( $operation->{operationid} ) if $operation->{operationid};
Lines 3242-3247 sub ProcessOfflineIssue { Link Here
3242
    }
3245
    }
3243
}
3246
}
3244
3247
3248
sub ProcessOfflinePayment {
3249
    my $operation = shift;
3250
3251
    my $borrower = C4::Members::GetMemberDetails( undef, $operation->{cardnumber} ); # Get borrower from operation cardnumber
3252
    my $amount = $operation->{amount};
3253
    
3254
    recordpayment( $borrower->{borrowernumber}, $amount );
3255
3256
    return "Success."
3257
}
3245
3258
3246
3259
3247
=head2 TransferSlip
3260
=head2 TransferSlip
(-)a/installer/data/mysql/kohastructure.sql (-9 / +9 lines)
Lines 1551-1567 CREATE TABLE `patronimage` ( -- information related to patron images Link Here
1551
-- so MyISAM is better in this case
1551
-- so MyISAM is better in this case
1552
1552
1553
DROP TABLE IF EXISTS `pending_offline_operations`;
1553
DROP TABLE IF EXISTS `pending_offline_operations`;
1554
CREATE TABLE `pending_offline_operations` (
1554
CREATE TABLE pending_offline_operations (
1555
  `operationid` int(11) NOT NULL AUTO_INCREMENT,
1555
  operationid int(11) NOT NULL AUTO_INCREMENT,
1556
  `userid` varchar(30) NOT NULL,
1556
  userid varchar(30) NOT NULL,
1557
  `branchcode` varchar(10) NOT NULL,
1557
  branchcode varchar(10) NOT NULL,
1558
  `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
1558
  `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
1559
  `action` varchar(10) NOT NULL,
1559
  `action` varchar(10) NOT NULL,
1560
  `barcode` varchar(20) NOT NULL,
1560
  barcode varchar(20) DEFAULT NULL,
1561
  `cardnumber` varchar(16) DEFAULT NULL,
1561
  cardnumber varchar(16) DEFAULT NULL,
1562
  PRIMARY KEY (`operationid`)
1562
  amount decimal(28,6) DEFAULT NULL,
1563
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
1563
  PRIMARY KEY (operationid)
1564
1564
) ENGINE=MyISAM  DEFAULT CHARSET=utf8;
1565
1565
1566
1566
1567
--
1567
--
(-)a/installer/data/mysql/updatedatabase.pl (+8 lines)
Lines 5635-5640 if(C4::Context->preference("Version") < TransformToNum($DBversion) ) { Link Here
5635
    SetVersion($DBversion);
5635
    SetVersion($DBversion);
5636
}
5636
}
5637
5637
5638
$DBversion = "3.09.00.XXX";
5639
if (C4::Context->preference("Version") < TransformToNum($DBversion)) {
5640
    $dbh->do("ALTER TABLE `pending_offline_operations` CHANGE `barcode` `barcode` VARCHAR( 20 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL");
5641
    $dbh->do("ALTER TABLE `pending_offline_operations` ADD `amount` DECIMAL( 28, 6 ) NULL DEFAULT NULL");
5642
    print "Upgrade to $DBversion done (redefine the field branchcode as PRIMARY KEY of branches)\n";
5643
    SetVersion ($DBversion);
5644
}
5645
5638
=head1 FUNCTIONS
5646
=head1 FUNCTIONS
5639
5647
5640
=head2 TableExists($table)
5648
=head2 TableExists($table)
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation-home.tt (-2 / +6 lines)
Lines 51-58 Link Here
51
	<div class="yui-u">
51
	<div class="yui-u">
52
        <h5>Offline circulation</h5>
52
        <h5>Offline circulation</h5>
53
		<ul>
53
		<ul>
54
            <li><a href="/cgi-bin/koha/offline_circ/process_koc.pl">Offline circulation file (.koc) uploader</a></li>
54
                    <li><a href="/cgi-bin/koha/offline_circ/process_koc.pl">Upload offline circulation file (.koc)</a></li>
55
            <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>
55
                    <li><a href="/cgi-bin/koha/offline_circ/list.pl">Pending offline circulation actions</a> 
56
                    <ul>
57
                        <li><a href="http://kylehall.info/index.php/projects/koha/koha-offline-circulation/">Get desktop application</a></li>
58
                        <li><a href="https://addons.mozilla.org/[% lang %]/firefox/addon/koct/">Get Firefox add-on</a></li>
59
                    </ul>
56
		</ul>
60
		</ul>
57
	</div>
61
	</div>
58
</div>
62
</div>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/offline_circ/enqueue_koc.tt (+31 lines)
Line 0 Link Here
1
[% INCLUDE 'doc-head-open.inc' %]
2
<title>Koha &rsaquo; Circulation &rsaquo; Add offline circulations to queue</title>
3
[% INCLUDE 'doc-head-close.inc' %]
4
</head>
5
<body>
6
[% INCLUDE 'header.inc' %]
7
[% INCLUDE 'circ-search.inc' %]
8
9
<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>
10
11
<div id="doc" class="yui-t7">
12
13
   <div id="bd">
14
15
  <h2>Koha offline circulation</h2>
16
  <p>Your file was processed.</p>
17
18
[% FOREACH message IN messages %]
19
  [% IF ( message.message ) %]	
20
      [% IF ( message.ERROR_file_version ) %]
21
          <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>
22
      [% END %]
23
  [% END %]
24
[% END %]
25
26
<p><a href="process_koc.pl">Upload another KOC file</a></p>
27
28
<p><a href="list.pl">View pending offline circulation actions</a></p>
29
30
</div>
31
[% INCLUDE 'intranet-bottom.inc' %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/offline_circ/list.tt (-2 / +4 lines)
Lines 78-84 Link Here
78
			            <th>Date</th>
78
			            <th>Date</th>
79
			            <th>Action</th>
79
			            <th>Action</th>
80
			            <th>Barcode</th>
80
			            <th>Barcode</th>
81
                        <th>Card number</th>
81
                                    <th>Card number</th>
82
                                    <th>Amount</th>
82
		            </tr>
83
		            </tr>
83
		        </thead>
84
		        </thead>
84
		        <tbody>
85
		        <tbody>
Lines 95-101 Link Here
95
			                    [% END %]
96
			                    [% END %]
96
			                </td>
97
			                </td>
97
			                <td>
98
			                <td>
98
			                [% IF ( operation.actionissue ) %]
99
			                [% IF ( operation.actionissue || operation.actionpayment) %]
99
		                        [% IF ( operation.borrowernumber ) %]
100
		                        [% IF ( operation.borrowernumber ) %]
100
		                            <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% operation.borrowernumber %]" title="[% operation.borrower %]">[% operation.cardnumber %]</a>
101
		                            <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% operation.borrowernumber %]" title="[% operation.borrower %]">[% operation.cardnumber %]</a>
101
		                        [% ELSE %]
102
		                        [% ELSE %]
Lines 103-108 Link Here
103
		                        [% END %]
104
		                        [% END %]
104
			                [% END %]
105
			                [% END %]
105
			                </td>
106
			                </td>
107
                                        <td>[% operation.amount %]</td>
106
		                </tr>
108
		                </tr>
107
		            [% END %]
109
		            [% END %]
108
		        </tbody>
110
		        </tbody>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/offline_circ/process_koc.tt (-12 / +22 lines)
Lines 6-27 Link Here
6
<script type="text/javascript">
6
<script type="text/javascript">
7
//<![CDATA[
7
//<![CDATA[
8
$(document).ready(function(){
8
$(document).ready(function(){
9
	$("#processfile").hide();
9
    $("#enqueuefile").hide();
10
    $("#processfile").hide();
10
});
11
});
12
11
function CheckUpload(f){
13
function CheckUpload(f){
12
	if(f.fileToUpload.value == ""){
14
    if (f.fileToUpload.value == ""){
13
		alert(_("Please choose a file to upload"));
15
        alert(_("Please choose a file to upload"));
14
	} else {
16
    } else {
15
		return ajaxFileUpload()
17
        return ajaxFileUpload()
16
	}
18
    }
17
		return false;
19
    return false;
18
}
20
}
21
19
function CheckForm(f) {
22
function CheckForm(f) {
20
    if (f.uploadedfileid.value == '') {
23
    if (f.uploadedfileid.value == '') {
21
        alert(_('Please upload a file first.'));
24
        alert(_('Please upload a file first.'));
22
    } else {
25
    } else {
23
		$("#fileuploadstatus").hide();
26
        $("#fileuploadstatus").hide();
24
		$("#fileuploadform").slideUp();
27
        $("#fileuploadform").slideUp();
25
        return submitBackgroundJob(f);
28
        return submitBackgroundJob(f);
26
    }
29
    }
27
    return false;
30
    return false;
Lines 60-66 function CheckForm(f) { Link Here
60
	[% 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 %]
63
	[% 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 %]
61
  [% END %]
64
  [% END %]
62
[% ELSE %]
65
[% ELSE %]
63
  <h2>Upload offline circulation data</h2>
66
   <h2>Upload offline circulation data</h2>
67
64
   <div id="fileuploadform">
68
   <div id="fileuploadform">
65
     <form method="post" action="[% SCRIPT_NAME %]" enctype="multipart/form-data">
69
     <form method="post" action="[% SCRIPT_NAME %]" enctype="multipart/form-data">
66
		<fieldset class="brief">
70
		<fieldset class="brief">
Lines 72-82 function CheckForm(f) { Link Here
72
     <div id="fileuploadstatus" style="display:none">Upload progress: <div id="fileuploadprogress"></div> <span id="fileuploadpercent">0</span>%</div>
76
     <div id="fileuploadstatus" style="display:none">Upload progress: <div id="fileuploadprogress"></div> <span id="fileuploadpercent">0</span>%</div>
73
     <div id="fileuploadfailed" style="display:none"></div>
77
     <div id="fileuploadfailed" style="display:none"></div>
74
   </div>
78
   </div>
75
   <form action="process_koc.pl" id="processfile" method="post" enctype="multipart/form-data">
79
80
   <form action="enqueue_koc.pl" id="processfile" method="post" enctype="multipart/form-data">
81
     <input type="hidden" name="uploadedfileid" id="uploadedfileid" value="" />
82
     <input type="submit" value="Add to offline circulation queue" onclick="return CheckForm(this.form);" id="queueformsubmit" />
83
   </form>
84
85
   <form action="process_koc.pl" id="enqueuefile" method="post" enctype="multipart/form-data">
76
     <input type="hidden" name="uploadedfileid" id="uploadedfileid" value="" />
86
     <input type="hidden" name="uploadedfileid" id="uploadedfileid" value="" />
77
     <input type="hidden" name="runinbackground" id="runinbackground" value="" />
87
     <input type="hidden" name="runinbackground" id="runinbackground" value="" />
78
     <input type="hidden" name="completedJobID" id="completedJobID" value="" />
88
     <input type="hidden" name="completedJobID" id="completedJobID" value="" />
79
     <input type="submit" value="Process offline circulation file" onclick="return CheckForm(this.form);" id="mainformsubmit" />
89
     <input type="submit" value="Apply directly" onclick="return CheckForm(this.form);" id="mainformsubmit" />
80
     <div id="jobstatus" style="display:none">Job progress: <div id="jobprogress"></div> <span id="jobprogresspercent">0</span>%</div>
90
     <div id="jobstatus" style="display:none">Job progress: <div id="jobprogress"></div> <span id="jobprogresspercent">0</span>%</div>
81
     <div id="jobfailed" style="display:none"></div>
91
     <div id="jobfailed" style="display:none"></div>
82
   </form>
92
   </form>
(-)a/koha-tmpl/opac-tmpl/prog/en/modules/opac-auth.tt (+9 lines)
Lines 53-59 Link Here
53
<p>Sorry, the CAS login failed.</p>
53
<p>Sorry, the CAS login failed.</p>
54
[% END %]
54
[% END %]
55
55
56
<<<<<<< HEAD
56
<p>If you have a <acronym title="Central Authentication Service">CAS</acronym> account, 
57
<p>If you have a <acronym title="Central Authentication Service">CAS</acronym> account, 
58
=======
59
<p><acronym title="Central Authentication Service">If you have a CAS account</acronym>, 
60
>>>>>>> Bug 5983 minor fix in html to improve translatability
57
[% IF ( casServerUrl ) %]
61
[% IF ( casServerUrl ) %]
58
    please <a href="[% casServerUrl %]">click here to login</a>.<p>
62
    please <a href="[% casServerUrl %]">click here to login</a>.<p>
59
[% END %]
63
[% END %]
Lines 61-68 Link Here
61
[% IF ( casServersLoop ) %]
65
[% IF ( casServersLoop ) %]
62
please choose against which one you would like to authenticate: </p>
66
please choose against which one you would like to authenticate: </p>
63
<ul>
67
<ul>
68
<<<<<<< HEAD
64
    [% FOREACH casServer IN casServersLoop %]
69
    [% FOREACH casServer IN casServersLoop %]
65
	<li><a href="[% casServer.value %]">[% casServer.name %]</a></li>
70
	<li><a href="[% casServer.value %]">[% casServer.name %]</a></li>
71
=======
72
    [% FOREACH casServersLoo IN casServersLoop %]
73
	<li><a href="[% searchdomainloo.value %]">[% searchdomainloo.name %]</a></li>
74
>>>>>>> Bug 5983 minor fix in html to improve translatability
66
    [% END %]
75
    [% END %]
67
[% END %]
76
[% END %]
68
</ul>
77
</ul>
(-)a/offline_circ/enqueue_koc.pl (+197 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
# 2008 Kyle Hall <kyle.m.hall@gmail.com>
4
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it under the
8
# terms of the GNU General Public License as published by the Free Software
9
# Foundation; either version 2 of the License, or (at your option) any later
10
# version.
11
#
12
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License along
17
# with Koha; if not, write to the Free Software Foundation, Inc.,
18
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
#
20
21
use strict;
22
use warnings;
23
24
use CGI;
25
use C4::Output;
26
use C4::Auth;
27
use C4::Koha;
28
use C4::Context;
29
use C4::Biblio;
30
use C4::Accounts;
31
use C4::Circulation;
32
use C4::Items;
33
use C4::Members;
34
use C4::Stats;
35
use C4::UploadedFile;
36
37
use Date::Calc qw( Add_Delta_Days Date_to_Days );
38
39
use constant DEBUG => 0;
40
41
# this is the file version number that we're coded against.
42
my $FILE_VERSION = '1.0';
43
44
my $query = CGI->new;
45
my @output;
46
47
my ($template, $loggedinuser, $cookie) = get_template_and_user({
48
    template_name => "offline_circ/enqueue_koc.tmpl",
49
    query => $query,
50
    type => "intranet",
51
    authnotrequired => 0,
52
     flagsrequired   => { circulate => "circulate_remaining_permissions" },
53
});
54
55
56
my $fileID=$query->param('uploadedfileid');
57
my %cookies = parse CGI::Cookie($cookie);
58
my $sessionID = $cookies{'CGISESSID'}->value;
59
## 'Local' globals.
60
our $dbh = C4::Context->dbh();
61
62
if ($fileID) {
63
    my $uploaded_file = C4::UploadedFile->fetch($sessionID, $fileID);
64
    my $fh = $uploaded_file->fh();
65
    my @input_lines = <$fh>;
66
67
    my $header_line = shift @input_lines;
68
    my $file_info   = parse_header_line($header_line);
69
    if ($file_info->{'Version'} ne $FILE_VERSION) {
70
        push @output, {
71
            message => 1,
72
            ERROR_file_version => 1,
73
            upload_version => $file_info->{'Version'},
74
            current_version => $FILE_VERSION
75
        };
76
    }
77
78
    my $userid = C4::Context->userenv->{id};
79
    my $branchcode = C4::Context->userenv->{branch};
80
    
81
    foreach  my $line (@input_lines)  {
82
        my $command_line = parse_command_line($line);
83
        my $timestamp = $command_line->{'date'} . ' ' . $command_line->{'time'};
84
        my $action = $command_line->{'command'};
85
        my $barcode = $command_line->{'barcode'};
86
        my $cardnumber = $command_line->{'cardnumber'};
87
        my $amount = $command_line->{'amount'};
88
        
89
        AddOfflineOperation( $userid, $branchcode, $timestamp, $action, $barcode, $cardnumber, $amount );
90
    }
91
92
}
93
94
$template->param( messages => \@output );
95
96
output_html_with_http_headers $query, $cookie, $template->output;
97
98
=head1 FUNCTIONS
99
100
=head2 parse_header_line
101
102
parses the header line from a .koc file. This is the line that
103
specifies things such as the file version, and the name and version of
104
the offline circulation tool that generated the file. See
105
L<http://wiki.koha-community.org/wiki/Koha_offline_circulation_file_format>
106
for more information.
107
108
pass in a string containing the header line (the first line from th
109
file).
110
111
returns a hashref containing the information from the header.
112
113
=cut
114
115
sub parse_header_line {
116
    my $header_line = shift;
117
    chomp($header_line);
118
    $header_line =~ s/\r//g;
119
120
    my @fields = split( /\t/, $header_line );
121
    my %header_info = map { split( /=/, $_ ) } @fields;
122
    return \%header_info;
123
}
124
125
=head2 parse_command_line
126
127
=cut
128
129
sub parse_command_line {
130
    my $command_line = shift;
131
    chomp($command_line);
132
    $command_line =~ s/\r//g;
133
134
    my ( $timestamp, $command, @args ) = split( /\t/, $command_line );
135
    my ( $date,      $time,    $id )   = split( /\s/, $timestamp );
136
137
    my %command = (
138
        date    => $date,
139
        time    => $time,
140
        id      => $id,
141
        command => $command,
142
    );
143
144
    # set the rest of the keys using a hash slice
145
    my $argument_names = arguments_for_command($command);
146
    @command{@$argument_names} = @args;
147
148
    return \%command;
149
150
}
151
152
=head2 arguments_for_command
153
154
fetches the names of the columns (and function arguments) found in the
155
.koc file for a particular command name. For instance, the C<issue>
156
command requires a C<cardnumber> and C<barcode>. In that case this
157
function returns a reference to the list C<qw( cardnumber barcode )>.
158
159
parameters: the command name
160
161
returns: listref of column names.
162
163
=cut
164
165
sub arguments_for_command {
166
    my $command = shift;
167
168
    # define the fields for this version of the file.
169
    my %format = (
170
        issue   => [qw( cardnumber barcode )],
171
        return  => [qw( barcode )],
172
        payment => [qw( cardnumber amount )],
173
    );
174
175
    return $format{$command};
176
}
177
178
=head2 _get_borrowernumber_from_barcode
179
180
pass in a barcode
181
get back the borrowernumber of the patron who has it checked out.
182
undef if that can't be found
183
184
=cut
185
186
sub _get_borrowernumber_from_barcode {
187
    my $barcode = shift;
188
189
    return unless $barcode;
190
191
    my $item = GetBiblioFromItemNumber( undef, $barcode );
192
    return unless $item->{'itemnumber'};
193
194
    my $issue = C4::Circulation::GetItemIssue( $item->{'itemnumber'} );
195
    return unless $issue->{'borrowernumber'};
196
    return $issue->{'borrowernumber'};
197
}
(-)a/offline_circ/list.pl (-1 / +1 lines)
Lines 54-59 for (@$operations) { Link Here
54
    }
54
    }
55
    $_->{'actionissue'}    = $_->{'action'} eq 'issue';
55
    $_->{'actionissue'}    = $_->{'action'} eq 'issue';
56
    $_->{'actionreturn'}   = $_->{'action'} eq 'return';
56
    $_->{'actionreturn'}   = $_->{'action'} eq 'return';
57
    $_->{'actionpayment'}  = $_->{'action'} eq 'payment';
57
}
58
}
58
$template->param(pending_operations => $operations);
59
$template->param(pending_operations => $operations);
59
60
60
- 

Return to bug 8220