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

(-)a/C4/Circulation.pm (+120 lines)
Lines 99-104 BEGIN { Link Here
99
                &CreateBranchTransferLimit
99
                &CreateBranchTransferLimit
100
                &DeleteBranchTransferLimits
100
                &DeleteBranchTransferLimits
101
	);
101
	);
102
103
    # subs to deal with offline circulation
104
    push @EXPORT, qw(
105
      &GetOfflineOperations
106
      &GetOfflineOperation
107
      &AddOfflineOperation
108
      &DeleteOfflineOperation
109
      &ProcessOfflineOperation
110
    );
102
}
111
}
103
112
104
=head1 NAME
113
=head1 NAME
Lines 2943-2948 sub DeleteBranchTransferLimits { Link Here
2943
   $sth->execute();
2952
   $sth->execute();
2944
}
2953
}
2945
2954
2955
sub GetOfflineOperations {
2956
	my $dbh = C4::Context->dbh;
2957
	my $sth = $dbh->prepare("SELECT * FROM pending_offline_operations WHERE branchcode=? ORDER BY timestamp");
2958
	$sth->execute(C4::Context->userenv->{'branch'});
2959
	my $results = $sth->fetchall_arrayref({});
2960
	$sth->finish;
2961
	return $results;
2962
}
2963
2964
sub GetOfflineOperation {
2965
	my $dbh = C4::Context->dbh;
2966
	my $sth = $dbh->prepare("SELECT * FROM pending_offline_operations WHERE operationid=?");
2967
	$sth->execute( shift );
2968
	my $result = $sth->fetchrow_hashref;
2969
	$sth->finish;
2970
	return $result;
2971
}
2972
2973
sub AddOfflineOperation {
2974
	my $dbh = C4::Context->dbh;
2975
	warn Data::Dumper::Dumper(@_);
2976
	my $sth = $dbh->prepare("INSERT INTO pending_offline_operations VALUES('',?,?,?,?,?,?)");
2977
	$sth->execute( @_ );
2978
	return "Added.";
2979
}
2980
2981
sub DeleteOfflineOperation {
2982
	my $dbh = C4::Context->dbh;
2983
	my $sth = $dbh->prepare("DELETE FROM pending_offline_operations WHERE operationid=?");
2984
	$sth->execute( shift );
2985
	return "Deleted.";
2986
}
2987
2988
sub ProcessOfflineOperation {
2989
	my $operation = shift;
2990
2991
    my $report;
2992
	if ( $operation->{action} eq 'return' ) {
2993
        $report = ProcessOfflineReturn( $operation );
2994
	} elsif ( $operation->{action} eq 'issue' ) {
2995
	    $report = ProcessOfflineIssue( $operation );
2996
	}
2997
	
2998
	DeleteOfflineOperation( $operation->{operationid} ) if $operation->{operationid};
2999
	
3000
	return $report;
3001
}
3002
3003
sub ProcessOfflineReturn {
3004
    my $operation = shift;
3005
3006
    my $itemnumber = C4::Items::GetItemnumberFromBarcode( $operation->{barcode} );
3007
    
3008
    if ( $itemnumber ) {
3009
        my $issue = GetOpenIssue( $itemnumber );
3010
        if ( $issue ) {
3011
            MarkIssueReturned(
3012
                $issue->{borrowernumber},
3013
                $itemnumber,
3014
                undef,
3015
                $operation->{timestamp},
3016
            );
3017
            ModItem(
3018
                { renewals => 0, onloan => undef },
3019
                $issue->{'biblionumber'},
3020
                $itemnumber
3021
            );
3022
            return "Success.";
3023
        } else {
3024
            return "Item not issued.";
3025
        }
3026
    } else {
3027
        return "Item not found.";
3028
    }
3029
}
3030
3031
sub ProcessOfflineIssue {
3032
    my $operation = shift;
3033
3034
    my $borrower = C4::Members::GetMemberDetails( undef, $operation->{cardnumber} ); # Get borrower from operation cardnumber
3035
    
3036
    if ( $borrower->{borrowernumber} ) { 
3037
        my $itemnumber = C4::Items::GetItemnumberFromBarcode( $operation->{barcode} );
3038
        unless ($itemnumber) {
3039
            return "barcode not found";
3040
        }
3041
        my $issue = GetOpenIssue( $itemnumber );
3042
        
3043
        if ( $issue and ( $issue->{borrowernumber} ne $borrower->{borrowernumber} ) ) { # Item already issued to another borrower, mark it returned
3044
            MarkIssueReturned(
3045
                $issue->{borrowernumber},
3046
                $itemnumber,
3047
                undef,
3048
                $operation->{timestamp},
3049
            );
3050
        }
3051
        AddIssue(
3052
            $borrower,
3053
            $operation->{'barcode'},
3054
            undef,
3055
            1,
3056
            $operation->{timestamp},
3057
            undef,
3058
        );
3059
        return "Success.";
3060
    } else {
3061
        return "Borrower not found.";
3062
    }
3063
}
3064
3065
2946
3066
2947
  1;
3067
  1;
2948
3068
(-)a/installer/data/mysql/kohastructure.sql (+17 lines)
Lines 1463-1468 CREATE TABLE `patronimage` ( Link Here
1463
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
1463
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
1464
1464
1465
--
1465
--
1466
-- Table structure for table `pending_offline_operations`
1467
--
1468
-- this table is MyISAM, InnoDB tables are growing only and this table is filled/emptied/filled/emptied...
1469
-- so MyISAM is better in this case
1470
1471
CREATE TABLE `pending_offline_operations` (
1472
  `operationid` int(11) NOT NULL AUTO_INCREMENT,
1473
  `userid` varchar(30) NOT NULL,
1474
  `branchcode` varchar(10) NOT NULL,
1475
  `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
1476
  `action` varchar(10) NOT NULL,
1477
  `barcode` varchar(20) NOT NULL,
1478
  `cardnumber` varchar(16) DEFAULT NULL,
1479
  PRIMARY KEY (`operationid`)
1480
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
1481
1482
--
1466
-- Table structure for table `printers`
1483
-- Table structure for table `printers`
1467
--
1484
--
1468
1485
(-)a/installer/data/mysql/updatedatabase.pl (+6 lines)
Lines 4446-4451 if (C4::Context->preference("Version") < TransformToNum($DBversion)) { Link Here
4446
    SetVersion($DBversion);
4446
    SetVersion($DBversion);
4447
}
4447
}
4448
4448
4449
$DBversion = "3.05.00.XXX";
4450
if (C4::Context->preference("Version") < TransformToNum($DBversion)) {
4451
    $dbh->do("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;");
4452
    print "Upgrade to $DBversion done ( adding offline operations table )\n";
4453
    SetVersion($DBversion);
4454
}
4449
4455
4450
=head1 FUNCTIONS
4456
=head1 FUNCTIONS
4451
4457
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation-home.tt (+1 lines)
Lines 53-58 Link Here
53
		<h5>Offline Circulation</h5>
53
		<h5>Offline Circulation</h5>
54
		<ul>
54
		<ul>
55
			<li><a href="/cgi-bin/koha/offline_circ/process_koc.pl">Offline Circulation File (.koc) Uploader</a></li>
55
			<li><a href="/cgi-bin/koha/offline_circ/process_koc.pl">Offline Circulation File (.koc) Uploader</a></li>
56
			<li><a href="/cgi-bin/koha/offline_circ/list.pl">Offline Circulation</a> (Firefox module: https://addons.mozilla.org/fr/firefox/addon/koct/)</li>
56
		</ul>
57
		</ul>
57
	</div>
58
	</div>
58
</div>
59
</div>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/offline_circ/list.tt (+97 lines)
Line 0 Link Here
1
    [% INCLUDE "doc-head-open.inc" %]
2
    <title>Koha &rsaquo; Circulation &rsaquo; Offline Circulation</title>
3
    [% INCLUDE "doc-head-close.inc" %]
4
    <script type="text/javascript" src="[% themelang %]/lib/jquery/plugins/jquery.tablesorter.min.js"></script>
5
    <script type="text/javascript" language="javascript">
6
        $(document).ready(function() {
7
            $('#checkall').click(function() {
8
                $(":checkbox").attr('checked', $('#checkall').is(':checked')); 
9
            });
10
            $('#process,#delete').click(function() {
11
                var action = $(this).attr("id");
12
                $(":checkbox[name=operationid]:checked").each(function() {
13
                    var cb = $(this);
14
                    $.ajax({
15
                        url: "process.pl", 
16
                        data: { 'action': action, 'operationid': this.value },
17
                        async: false,
18
                        dataType: "text",
19
                        success: function(data) {
20
                            cb.replaceWith(data);
21
                        }});
22
                });
23
                if( $('#operations tbody :checkbox').size() == 0 ) {
24
                    $('#actions').hide();
25
                }
26
            });
27
        });
28
    </script>
29
</head>
30
<body>
31
    [% INCLUDE 'header.inc' %]
32
    [% INCLUDE 'circ-search.inc' %]
33
34
    <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; Offline Circulation</div>
35
36
    <div id="doc" class="yui-t7">
37
       
38
	    <div id="bd">
39
40
	    <h2>Offline Circulation</h2>
41
	
42
	    [% IF ( pending_operations ) %]
43
	
44
	        <form>
45
46
	        <table id="operations">
47
	            <thead>
48
		            <tr>
49
		                <th><input type="checkbox" name="checkall" id="checkall" /></th>
50
			            <th>Date</th>
51
			            <th>Action</th>
52
			            <th>Barcode</th>
53
			            <th>Cardnumber</th>
54
		            </tr>
55
		        </thead>
56
		        <tbody>
57
		            [% FOREACH operation IN pending_operations %]
58
		                <tr class="oc-[% operation.action %]">
59
		                    <td><input type="checkbox" name="operationid" value="[% operation.operationid %]" /></td>
60
			                <td>[% operation.timestamp %]</td>
61
			                <td>[% operation.action %]</td>
62
			                <td>
63
			                    [% IF ( biblionumber ) %]
64
			                        <a href="/cgi-bin/koha/catalogue/detail.pl?biblionumber=[% operation.biblionumber %]" title="[% operation.bibliotitle %]">[% operation.barcode %]</a>
65
			                    [% ELSE %]
66
			                        <span class="error">[% operation.barcode %]</span>
67
			                    [% END %]
68
			                </td>
69
			                <td>
70
			                [% IF ( operation.actionissue ) %]
71
		                        [% IF ( operation.borrowernumber ) %]
72
		                            <a href="/cgi-bin/koha/members/moremember.pl?borrowernumber=[% operation.borrowernumber %]" title="[% operation.borrower %]">[% operation.cardnumber %]</a>
73
		                        [% ELSE %]
74
		                            <span class="error">[% operation.cardnumber %]</span>
75
		                        [% END %]
76
			                [% END %]
77
			                </td>
78
		                </tr>
79
		            [% END %]
80
		        </tbody>
81
	        </table>
82
83
            <p id="actions">For the selected operations:
84
            <input type="button" id="process" value="Process" />
85
            <input type="button" id="delete" value="Delete" /></p>
86
            
87
            </form>
88
89
        [% ELSE %]
90
        
91
            <p>There is no pending offline operations.</p>
92
            
93
        [% END %]
94
        
95
    </div>
96
97
    [% INCLUDE 'intranet-bottom.inc' %]
(-)a/offline_circ/list.pl (+56 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
# 2009 BibLibre <jeanandre.santoni@biblibre.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 with
17
# Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
18
# Suite 330, Boston, MA  02111-1307 USA
19
#
20
21
use CGI;
22
use C4::Output;
23
use C4::Auth;
24
use C4::Koha;
25
use C4::Context;
26
use C4::Circulation;
27
use C4::Branch;
28
use C4::Members;
29
use C4::Biblio;
30
31
my $query = CGI->new;
32
33
my ($template, $loggedinuser, $cookie) = get_template_and_user({ 
34
    template_name => "offline_circ/list.tmpl",
35
    query => $query,
36
    type => "intranet",
37
    authnotrequired => 0,
38
    flagsrequired   => { circulate => "circulate_remaining_permissions" },
39
});
40
41
my $operations = GetOfflineOperations;
42
43
for (@$operations) {
44
	my $biblio             = GetBiblioFromItemNumber(undef, $_->{'barcode'});
45
	$_->{'bibliotitle'}    = $biblio->{'title'};
46
	$_->{'biblionumber'}   = $biblio->{'biblionumber'};
47
	my $borrower           = GetMemberDetails(undef,$_->{'cardnumber'});
48
	$_->{'borrowernumber'} = $borrower->{'borrowernumber'};
49
	$_->{'borrower'}       = join(' ', $borrower->{'firstname'}, $borrower->{'surname'});
50
	$_->{'actionissue'}    = $_->{'action'} eq 'issue';
51
	$_->{'actionreturn'}   = $_->{'action'} eq 'return';
52
}
53
$template->param(pending_operations => $operations);
54
55
output_html_with_http_headers $query, $cookie, $template->output;
56
(-)a/offline_circ/process.pl (+48 lines)
Line 0 Link Here
1
#!/usr/bin/perl
2
3
# 2009 BibLibre <jeanandre.santoni@biblibre.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 with
17
# Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
18
# Suite 330, Boston, MA  02111-1307 USA
19
#
20
21
use CGI;
22
use C4::Auth;
23
use C4::Circulation;
24
25
my $query = CGI->new;
26
27
my ($template, $loggedinuser, $cookie) = get_template_and_user({ 
28
    template_name => "offline_circ/list.tmpl",
29
    query => $query,
30
    type => "intranet",
31
    authnotrequired => 0,
32
    flagsrequired   => { circulate => "circulate_remaining_permissions" },
33
});
34
35
my $operationid = $query->param('operationid');
36
my $action = $query->param('action');
37
my $result;
38
39
if ( $action eq 'process' ) {
40
    my $operation = GetOfflineOperation( $operationid );
41
    $result = ProcessOfflineOperation( $operation );
42
} elsif ( $action eq 'delete' ) {
43
    $result = DeleteOfflineOperation( $operationid );
44
}
45
46
print CGI::header('-type'=>'text/plain', '-charset'=>'utf-8');
47
print $result;
48
(-)a/offline_circ/service.pl (-1 / +60 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/perl
2
3
# 2009 BibLibre <jeanandre.santoni@biblibre.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 with
17
# Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
18
# Suite 330, Boston, MA  02111-1307 USA
19
#
20
21
use CGI;
22
use C4::Auth;
23
use C4::Circulation;
24
25
my $cgi = CGI->new;
26
27
# get the status of the user, this will check his credentials and rights
28
my ($status, $cookie, $sessionId) = C4::Auth::check_api_auth($cgi, undef);
29
30
my $result;
31
32
if ($status eq 'ok') { # if authentication is ok
33
	if ( $cgi->param('pending') eq 'true' ) { # if the 'pending' flag is true, we store the operation in the db instead of directly processing them
34
		$result = AddOfflineOperation(
35
	        $cgi->param('userid')     || '',
36
            $cgi->param('branchcode') || '',
37
            $cgi->param('timestamp')  || '',
38
            $cgi->param('action')     || '',
39
            $cgi->param('barcode')    || '',
40
            $cgi->param('cardnumber') || '',
41
		);
42
	} else {
43
		$result = ProcessOfflineOperation(
44
            {
45
                'userid'      => $cgi->param('userid'),
46
                'branchcode'  => $cgi->param('branchcode'),
47
                'timestamp'   => $cgi->param('timestamp'),
48
                'action'      => $cgi->param('action'),
49
                'barcode'     => $cgi->param('barcode'),
50
                'cardnumber'  => $cgi->param('cardnumber'),
51
            }
52
		);
53
	}
54
} else {
55
    $result = "Authentication failed."
56
}
57
58
print CGI::header('-type'=>'text/plain', '-charset'=>'utf-8');
59
print $result;
60

Return to bug 5877