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

(-)a/C4/Circulation.pm (+117 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 2942-2947 sub DeleteBranchTransferLimits { Link Here
2942
   $sth->execute();
2951
   $sth->execute();
2943
}
2952
}
2944
2953
2954
sub GetOfflineOperations {
2955
	my $dbh = C4::Context->dbh;
2956
	my $sth = $dbh->prepare("SELECT * FROM pending_offline_operations WHERE branchcode=? ORDER BY timestamp");
2957
	$sth->execute(C4::Context->userenv->{'branch'});
2958
	my $results = $sth->fetchall_arrayref({});
2959
	$sth->finish;
2960
	return $results;
2961
}
2962
2963
sub GetOfflineOperation {
2964
	my $dbh = C4::Context->dbh;
2965
	my $sth = $dbh->prepare("SELECT * FROM pending_offline_operations WHERE operationid=?");
2966
	$sth->execute( shift );
2967
	my $result = $sth->fetchrow_hashref;
2968
	$sth->finish;
2969
	return $result;
2970
}
2971
2972
sub AddOfflineOperation {
2973
	my $dbh = C4::Context->dbh;
2974
	warn Data::Dumper::Dumper(@_);
2975
	my $sth = $dbh->prepare("INSERT INTO pending_offline_operations VALUES('',?,?,?,?,?,?)");
2976
	$sth->execute( @_ );
2977
	return "Added.";
2978
}
2979
2980
sub DeleteOfflineOperation {
2981
	my $dbh = C4::Context->dbh;
2982
	my $sth = $dbh->prepare("DELETE FROM pending_offline_operations WHERE operationid=?");
2983
	$sth->execute( shift );
2984
	return "Deleted.";
2985
}
2986
2987
sub ProcessOfflineOperation {
2988
	my $operation = shift;
2989
2990
    my $report;
2991
	if ( $operation->{action} eq 'return' ) {
2992
        $report = ProcessOfflineReturn( $operation );
2993
	} elsif ( $operation->{action} eq 'issue' ) {
2994
	    $report = ProcessOfflineIssue( $operation );
2995
	}
2996
	
2997
	DeleteOfflineOperation( $operation->{operationid} ) if $operation->{operationid};
2998
	
2999
	return $report;
3000
}
3001
3002
sub ProcessOfflineReturn {
3003
    my $operation = shift;
3004
3005
    my $itemnumber = C4::Items::GetItemnumberFromBarcode( $operation->{barcode} );
3006
    
3007
    if ( $itemnumber ) {
3008
        my $issue = GetOpenIssue( $itemnumber );
3009
        if ( $issue ) {
3010
            MarkIssueReturned(
3011
                $issue->{borrowernumber},
3012
                $itemnumber,
3013
                undef,
3014
                $operation->{timestamp},
3015
            );
3016
            ModItem(
3017
                { renewals => 0, onloan => undef },
3018
                $issue->{'biblionumber'},
3019
                $itemnumber
3020
            );
3021
            return "Success.";
3022
        } else {
3023
            return "Item not issued.";
3024
        }
3025
    } else {
3026
        return "Item not found.";
3027
    }
3028
}
3029
3030
sub ProcessOfflineIssue {
3031
    my $operation = shift;
3032
3033
    my $borrower = C4::Members::GetMemberDetails( undef, $operation->{cardnumber} ); # Get borrower from operation cardnumber
3034
    
3035
    if ( $borrower->{borrowernumber} ) { 
3036
        my $itemnumber = C4::Items::GetItemnumberFromBarcode( $operation->{barcode} );
3037
        my $issue = GetOpenIssue( $itemnumber );
3038
        
3039
        if ( $issue and ( $issue->{borrowernumber} ne $borrower->{borrowernumber} ) ) { # Item already issued to another borrower, mark it returned
3040
            MarkIssueReturned(
3041
                $issue->{borrowernumber},
3042
                $itemnumber,
3043
                undef,
3044
                $operation->{timestamp},
3045
            );
3046
        }
3047
        AddIssue(
3048
            $borrower,
3049
            $operation->{'barcode'},
3050
            undef,
3051
            1,
3052
            $operation->{timestamp},
3053
            undef,
3054
        );
3055
        return "Success.";
3056
    } else {
3057
        return "Borrower not found.";
3058
    }
3059
}
3060
3061
2945
3062
2946
  1;
3063
  1;
2947
3064
(-)a/installer/data/mysql/kohastructure.sql (+17 lines)
Lines 1457-1462 CREATE TABLE `patronimage` ( Link Here
1457
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
1457
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
1458
1458
1459
--
1459
--
1460
-- Table structure for table `pending_offline_operations`
1461
--
1462
-- this table is MyISAM, InnoDB tables are growing only and this table is filled/emptied/filled/emptied...
1463
-- so MyISAM is better in this case
1464
1465
CREATE TABLE `pending_offline_operations` (
1466
  `operationid` int(11) NOT NULL AUTO_INCREMENT,
1467
  `userid` varchar(30) NOT NULL,
1468
  `branchcode` varchar(10) NOT NULL,
1469
  `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
1470
  `action` varchar(10) NOT NULL,
1471
  `barcode` varchar(20) NOT NULL,
1472
  `cardnumber` varchar(16) DEFAULT NULL,
1473
  PRIMARY KEY (`operationid`)
1474
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
1475
1476
--
1460
-- Table structure for table `printers`
1477
-- Table structure for table `printers`
1461
--
1478
--
1462
1479
(-)a/installer/data/mysql/updatedatabase.pl (+6 lines)
Lines 4399-4404 if (C4::Context->preference("Version") < TransformToNum($DBversion)) { Link Here
4399
    SetVersion($DBversion);
4399
    SetVersion($DBversion);
4400
}
4400
}
4401
4401
4402
$DBversion = "3.05.00.XXX";
4403
if (C4::Context->preference("Version") < TransformToNum($DBversion)) {
4404
    $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;");
4405
    print "Upgrade to $DBversion done ( adding offline operations table )\n";
4406
    SetVersion($DBversion);
4407
}
4402
=head1 FUNCTIONS
4408
=head1 FUNCTIONS
4403
4409
4404
=head2 DropAllForeignKeys($table)
4410
=head2 DropAllForeignKeys($table)
(-)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/kohaversion.pl (-1 / +1 lines)
Lines 16-22 the kohaversion is divided in 4 parts : Link Here
16
use strict;
16
use strict;
17
17
18
sub kohaversion {
18
sub kohaversion {
19
    our $VERSION = '3.05.00.008';
19
    our $VERSION = '3.05.00.XXX';
20
    # version needs to be set this way
20
    # version needs to be set this way
21
    # so that it can be picked up by Makefile.PL
21
    # so that it can be picked up by Makefile.PL
22
    # during install
22
    # during install
(-)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