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

(-)a/C4/Circulation.pm (+120 lines)
Lines 100-105 BEGIN { Link Here
100
                &CreateBranchTransferLimit
100
                &CreateBranchTransferLimit
101
                &DeleteBranchTransferLimits
101
                &DeleteBranchTransferLimits
102
	);
102
	);
103
104
    # subs to deal with offline circulation
105
    push @EXPORT, qw(
106
      &GetOfflineOperations
107
      &GetOfflineOperation
108
      &AddOfflineOperation
109
      &DeleteOfflineOperation
110
      &ProcessOfflineOperation
111
    );
103
}
112
}
104
113
105
=head1 NAME
114
=head1 NAME
Lines 3027-3032 sub LostItem{ Link Here
3027
    }
3036
    }
3028
}
3037
}
3029
3038
3039
sub GetOfflineOperations {
3040
	my $dbh = C4::Context->dbh;
3041
	my $sth = $dbh->prepare("SELECT * FROM pending_offline_operations WHERE branchcode=? ORDER BY timestamp");
3042
	$sth->execute(C4::Context->userenv->{'branch'});
3043
	my $results = $sth->fetchall_arrayref({});
3044
	$sth->finish;
3045
	return $results;
3046
}
3047
3048
sub GetOfflineOperation {
3049
	my $dbh = C4::Context->dbh;
3050
	my $sth = $dbh->prepare("SELECT * FROM pending_offline_operations WHERE operationid=?");
3051
	$sth->execute( shift );
3052
	my $result = $sth->fetchrow_hashref;
3053
	$sth->finish;
3054
	return $result;
3055
}
3056
3057
sub AddOfflineOperation {
3058
	my $dbh = C4::Context->dbh;
3059
	warn Data::Dumper::Dumper(@_);
3060
	my $sth = $dbh->prepare("INSERT INTO pending_offline_operations VALUES('',?,?,?,?,?,?)");
3061
	$sth->execute( @_ );
3062
	return "Added.";
3063
}
3064
3065
sub DeleteOfflineOperation {
3066
	my $dbh = C4::Context->dbh;
3067
	my $sth = $dbh->prepare("DELETE FROM pending_offline_operations WHERE operationid=?");
3068
	$sth->execute( shift );
3069
	return "Deleted.";
3070
}
3071
3072
sub ProcessOfflineOperation {
3073
	my $operation = shift;
3074
3075
    my $report;
3076
	if ( $operation->{action} eq 'return' ) {
3077
        $report = ProcessOfflineReturn( $operation );
3078
	} elsif ( $operation->{action} eq 'issue' ) {
3079
	    $report = ProcessOfflineIssue( $operation );
3080
	}
3081
3082
	DeleteOfflineOperation( $operation->{operationid} ) if $operation->{operationid};
3083
3084
	return $report;
3085
}
3086
3087
sub ProcessOfflineReturn {
3088
    my $operation = shift;
3089
3090
    my $itemnumber = C4::Items::GetItemnumberFromBarcode( $operation->{barcode} );
3091
3092
    if ( $itemnumber ) {
3093
        my $issue = GetOpenIssue( $itemnumber );
3094
        if ( $issue ) {
3095
            MarkIssueReturned(
3096
                $issue->{borrowernumber},
3097
                $itemnumber,
3098
                undef,
3099
                $operation->{timestamp},
3100
            );
3101
            ModItem(
3102
                { renewals => 0, onloan => undef },
3103
                $issue->{'biblionumber'},
3104
                $itemnumber
3105
            );
3106
            return "Success.";
3107
        } else {
3108
            return "Item not issued.";
3109
        }
3110
    } else {
3111
        return "Item not found.";
3112
    }
3113
}
3114
3115
sub ProcessOfflineIssue {
3116
    my $operation = shift;
3117
3118
    my $borrower = C4::Members::GetMemberDetails( undef, $operation->{cardnumber} ); # Get borrower from operation cardnumber
3119
3120
    if ( $borrower->{borrowernumber} ) {
3121
        my $itemnumber = C4::Items::GetItemnumberFromBarcode( $operation->{barcode} );
3122
        unless ($itemnumber) {
3123
            return "barcode not found";
3124
        }
3125
        my $issue = GetOpenIssue( $itemnumber );
3126
3127
        if ( $issue and ( $issue->{borrowernumber} ne $borrower->{borrowernumber} ) ) { # Item already issued to another borrower, mark it returned
3128
            MarkIssueReturned(
3129
                $issue->{borrowernumber},
3130
                $itemnumber,
3131
                undef,
3132
                $operation->{timestamp},
3133
            );
3134
        }
3135
        AddIssue(
3136
            $borrower,
3137
            $operation->{'barcode'},
3138
            undef,
3139
            1,
3140
            $operation->{timestamp},
3141
            undef,
3142
        );
3143
        return "Success.";
3144
    } else {
3145
        return "Borrower not found.";
3146
    }
3147
}
3148
3149
3030
3150
3031
1;
3151
1;
3032
3152
(-)a/installer/data/mysql/kohastructure.sql (+17 lines)
Lines 1477-1482 CREATE TABLE `patronimage` ( Link Here
1477
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
1477
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
1478
1478
1479
--
1479
--
1480
-- Table structure for table `pending_offline_operations`
1481
--
1482
-- this table is MyISAM, InnoDB tables are growing only and this table is filled/emptied/filled/emptied...
1483
-- so MyISAM is better in this case
1484
1485
CREATE TABLE `pending_offline_operations` (
1486
  `operationid` int(11) NOT NULL AUTO_INCREMENT,
1487
  `userid` varchar(30) NOT NULL,
1488
  `branchcode` varchar(10) NOT NULL,
1489
  `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
1490
  `action` varchar(10) NOT NULL,
1491
  `barcode` varchar(20) NOT NULL,
1492
  `cardnumber` varchar(16) DEFAULT NULL,
1493
  PRIMARY KEY (`operationid`)
1494
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
1495
1496
--
1480
-- Table structure for table `printers`
1497
-- Table structure for table `printers`
1481
--
1498
--
1482
1499
(-)a/installer/data/mysql/updatedatabase.pl (+7 lines)
Lines 4712-4717 if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) { Link Here
4712
    SetVersion($DBversion);
4712
    SetVersion($DBversion);
4713
}
4713
}
4714
4714
4715
$DBversion = "3.07.00.XXX";
4716
if (C4::Context->preference("Version") < TransformToNum($DBversion)) {
4717
    $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;");
4718
    print "Upgrade to $DBversion done ( adding offline operations table )\n";
4719
    SetVersion($DBversion);
4720
}
4721
4715
=head1 FUNCTIONS
4722
=head1 FUNCTIONS
4716
4723
4717
=head2 DropAllForeignKeys($table)
4724
=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/offline_circ/list.pl (+55 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;
(-)a/offline_circ/process.pl (+47 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;
(-)a/offline_circ/service.pl (-1 / +59 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;

Return to bug 5877