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

(-)a/Koha/Charges/Sales.pm (+285 lines)
Line 0 Link Here
1
package Koha::Charges::Sales;
2
3
# Copyright 2019 PTFS Europe
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it
8
# under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Koha is distributed in the hope that it will be useful, but
13
# WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with Koha; if not, see <http://www.gnu.org/licenses>.
19
20
use Modern::Perl;
21
22
use Koha::Account::Lines;
23
use Koha::Account::Offsets;
24
use Koha::DateUtils qw( dt_from_string );
25
use Koha::Exceptions;
26
27
=head1 NAME
28
29
Koha::Charges::Sale - Module for collecting sales in Koha
30
31
=head1 SYNOPSIS
32
33
  use Koha::Charges::Sale;
34
35
  my $sale =
36
    Koha::Charges::Sale->new( { cash_register => $register, staff_id => $staff_id } );
37
  $sale->add_item($item);
38
  $sale->purchase( { payment_type => 'CASH' } );
39
40
=head2 Class methods
41
42
=head3 new
43
44
  Koha::Charges::Sale->new(
45
    {
46
        cash_register  => $cash_register,
47
        staff_id        => $staff_id,
48
        [ payment_type => $payment_type ],
49
        [ items        => $items ],
50
        [ patron       => $patron ],
51
    }
52
  );
53
54
=cut
55
56
sub new {
57
    my ( $class, $params ) = @_;
58
59
    Koha::Exceptions::MissingParameter->throw(
60
        "Missing mandatory parameter: cash_register")
61
      unless $params->{cash_register};
62
63
    Koha::Exceptions::MissingParameter->throw(
64
        "Missing mandatory parameter: staff_id")
65
      unless $params->{staff_id};
66
67
    Carp::confess("Key 'cash_register' is not a Koha::Cash::Register object!")
68
      unless $params->{cash_register}->isa('Koha::Cash::Register');
69
70
    return bless( $params, $class );
71
}
72
73
=head3 payment_type
74
75
  my $payment_type = $sale->payment_type( $payment_type );
76
77
A getter/setter for this instances associated payment type.
78
79
=cut
80
81
sub payment_type {
82
    my ( $self, $payment_type ) = @_;
83
84
    if ($payment_type) {
85
        Koha::Exceptions::Account::UnrecognisedType->throw(
86
            error => 'Type of payment not recognised' )
87
          unless ( exists( $self->_get_valid_payments->{$payment_type} ) );
88
89
        $self->{payment_type} = $payment_type;
90
    }
91
92
    return $self->{payment_type};
93
}
94
95
=head3 _get_valid_payments
96
97
  my $valid_payments = $sale->_get_valid_payments;
98
99
A getter which returns a hashref whose keys represent valid payment types.
100
101
=cut
102
103
sub _get_valid_payments {
104
    my $self = shift;
105
106
    $self->{valid_payments} //= {
107
        map { $_ => 1 } Koha::AuthorisedValues->search(
108
            {
109
                category   => 'PAYMENT_TYPE',
110
                branchcode => $self->{cash_register}->branch
111
            }
112
        )->get_column('authorised_value')
113
    };
114
115
    return $self->{valid_payments};
116
}
117
118
=head3 add_item
119
120
  my $item = { price => 0.25, quantity => 1, code => 'COPY' };
121
  $sale->add_item( $item );
122
123
=cut
124
125
sub add_item {
126
    my ( $self, $item ) = @_;
127
128
    Koha::Exceptions::MissingParameter->throw(
129
        "Missing mandatory parameter: code")
130
      unless $item->{code};
131
132
    Koha::Exceptions::Account::UnrecognisedType->throw(
133
        error => 'Type of debit not recognised' )
134
      unless ( exists( $self->_get_valid_items->{ $item->{code} } ) );
135
136
    Koha::Exceptions::MissingParameter->throw(
137
        "Missing mandatory parameter: price")
138
      unless $item->{price};
139
140
    Koha::Exceptions::MissingParameter->throw(
141
        "Missing mandatory parameter: quantity")
142
      unless $item->{quantity};
143
144
    push @{ $self->{items} }, $item;
145
    return $self;
146
}
147
148
=head3 _get_valid_items
149
150
  my $valid_items = $sale->_get_valid_items;
151
152
A getter which returns a hashref whose keys represent valid sale items.
153
154
=cut
155
156
sub _get_valid_items {
157
    my $self = shift;
158
159
    $self->{valid_items} //= {
160
        map { $_ => 1 } Koha::AuthorisedValues->search(
161
            {
162
                category   => 'MANUAL_INV',
163
                branchcode => $self->{cash_register}->branch
164
            }
165
        )->get_column('authorised_value')
166
    };
167
168
    return $self->{valid_items};
169
}
170
171
=head3 purchase
172
173
  my $credit_line = $sale->purchase;
174
175
=cut
176
177
sub purchase {
178
    my ( $self, $params ) = @_;
179
180
    if ( $params->{payment_type} ) {
181
        Koha::Exceptions::Account::UnrecognisedType->throw(
182
            error => 'Type of payment not recognised' )
183
          unless (
184
            exists( $self->_get_valid_payments->{ $params->{payment_type} } ) );
185
186
        $self->{payment_type} = $params->{payment_type};
187
    }
188
189
    Koha::Exceptions::MissingParameter->throw(
190
        "Missing mandatory parameter: payment_type")
191
      unless $self->{payment_type};
192
193
    Koha::Exceptions::NoChanges->throw(
194
        "Cannot purchase before calling add_item")
195
      unless $self->{items};
196
197
    my $schema     = Koha::Database->new->schema;
198
    my $dt         = dt_from_string();
199
    my $total_owed = 0;
200
    my $credit;
201
202
    $schema->txn_do(
203
        sub {
204
205
            # Add accountlines for each item being purchased
206
            my $debits;
207
            for my $item ( @{ $self->{items} } ) {
208
209
                my $amount = $item->{quantity} * $item->{price};
210
                $total_owed = $total_owed + $amount;
211
212
                # Insert the account line
213
                my $debit = Koha::Account::Line->new(
214
                    {
215
                        amount            => $amount,
216
                        accounttype       => $item->{code},
217
                        amountoutstanding => 0,
218
                        note              => $item->{quantity},
219
                        manager_id        => $self->{staff_id},
220
                        interface         => 'intranet',
221
                        branchcode        => $self->{cash_register}->branch,
222
                        date              => $dt
223
                    }
224
                )->store();
225
                push @{$debits}, $debit;
226
227
                # Record the account offset
228
                my $account_offset = Koha::Account::Offset->new(
229
                    {
230
                        debit_id => $debit->id,
231
                        type     => 'Purchase',
232
                        amount   => $amount
233
                    }
234
                )->store();
235
            }
236
237
            # Add accountline for payment
238
            $credit = Koha::Account::Line->new(
239
                {
240
                    amount            => 0 - $total_owed,
241
                    accounttype       => 'Purchase',
242
                    payment_type      => $self->{payment_type},
243
                    amountoutstanding => 0,
244
                    manager_id        => $self->{staff_id},
245
                    interface         => 'intranet',
246
                    branchcode        => $self->{cash_register}->branch,
247
                    register_id       => $self->{cash_register}->id,
248
                    date              => $dt,
249
                    note              => "POS SALE"
250
                }
251
            )->store();
252
253
            # Record the account offset
254
            my $credit_offset = Koha::Account::Offset->new(
255
                {
256
                    credit_id => $credit->id,
257
                    type      => 'Purchase',
258
                    amount    => $credit->amount
259
                }
260
            )->store();
261
262
            # Link payment to debits
263
            for my $debit ( @{$debits} ) {
264
                Koha::Account::Offset->new(
265
                    {
266
                        credit_id => $credit->accountlines_id,
267
                        debit_id  => $debit->id,
268
                        amount    => $debit->amount * -1,
269
                        type      => 'Payment',
270
                    }
271
                )->store();
272
            }
273
        }
274
    );
275
276
    return $credit;
277
}
278
279
=head1 AUTHOR
280
281
Martin Renvoize <martin.renvoize@ptfs-europe.com>
282
283
=cut
284
285
1;
(-)a/installer/data/mysql/account_offset_types.sql (+1 lines)
Lines 1-6 Link Here
1
INSERT INTO account_offset_types ( type ) VALUES
1
INSERT INTO account_offset_types ( type ) VALUES
2
('Writeoff'),
2
('Writeoff'),
3
('Payment'),
3
('Payment'),
4
('Purchase'),
4
('Lost Item'),
5
('Lost Item'),
5
('Processing Fee'),
6
('Processing Fee'),
6
('Manual Credit'),
7
('Manual Credit'),
(-)a/installer/data/mysql/atomicupdate/bug_23354.perl (+10 lines)
Line 0 Link Here
1
$DBversion = 'XXX'; # will be replaced by the RM
2
if( CheckVersion( $DBversion ) ) {
3
4
    $dbh->do(q{
5
        INSERT IGNORE INTO account_offset_types ( type ) VALUES ( 'Purchase' );
6
    });
7
8
    SetVersion( $DBversion );
9
    print "Upgrade to $DBversion done (Bug 23354 - Add 'Purchase' account offset type)\n";
10
}
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/pos-menu.inc (+16 lines)
Line 0 Link Here
1
<div id="navmenu">
2
    <div id="navmenulist">
3
        [% IF ( CAN_user_cash_management_manage_cash_registers || CAN_user_parameters_manage_auth_values) %]
4
        <h5>Administration</h5>
5
        <ul>
6
            [% IF ( CAN_user_cash_management_manage_cash_registers ) %]
7
                <li><a href="/cgi-bin/koha/admin/cash_registers.pl">Cash registers</a></li>
8
            [% END %]
9
10
            [% IF ( CAN_user_parameters_manage_auth_values ) %]
11
                <li><a href="/cgi-bin/koha/admin/authorised_values.pl?searchfield=MANUAL_INV">Purchase items</a></li>
12
            [% END %]
13
        </ul>
14
        [% END %]
15
    </div>
16
</div>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt (+4 lines)
Lines 80-85 Link Here
80
                    <div class="col-xs-6">
80
                    <div class="col-xs-6">
81
                        <ul class="biglinks-list">
81
                        <ul class="biglinks-list">
82
82
83
                            <li>
84
                                <a class="icon_general icon_pos" href="/cgi-bin/koha/pos/pay.pl">Point of sale</a>
85
                            </li>
86
83
                            [% IF ( CAN_user_editcatalogue_edit_catalogue || CAN_user_editcatalogue_edit_items ) %]
87
                            [% IF ( CAN_user_editcatalogue_edit_catalogue || CAN_user_editcatalogue_edit_items ) %]
84
                            <li>
88
                            <li>
85
                                <a class="icon_general icon_cataloging" href="/cgi-bin/koha/cataloguing/addbooks.pl"><i class="fa fa-tag"></i>Cataloging</a>
89
                                <a class="icon_general icon_cataloging" href="/cgi-bin/koha/cataloguing/addbooks.pl"><i class="fa fa-tag"></i>Cataloging</a>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/pos/pay.tt (+319 lines)
Line 0 Link Here
1
[% USE raw %]
2
[% USE Asset %]
3
[% USE Koha %]
4
[% USE AuthorisedValues %]
5
[% USE Price %]
6
[% SET footerjs = 1 %]
7
[% INCLUDE 'doc-head-open.inc' %]
8
<title>Koha &rsaquo; Payments</title>
9
[% INCLUDE 'doc-head-close.inc' %]
10
</head>
11
12
<body id="payments" class="pos">
13
[% INCLUDE 'header.inc' %]
14
[% INCLUDE 'circ-search.inc' %]
15
16
<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> &rsaquo; Point of sale</div>
17
18
<div class="main container-fluid">
19
    <div class="row">
20
        <div class="col-sm-10 col-sm-push-2">
21
22
        [% IF ( error_registers ) %]
23
        <div id="error_message" class="dialog alert">
24
            You must have at least one cash register associated with this branch before you can record payments.
25
        </div>
26
        [% ELSE %]
27
        <form name="payForm" id="payForm" method="post" action="/cgi-bin/koha/pos/pay.pl">
28
            <div class="row">
29
30
                <div class="col-sm-6">
31
32
                    <fieldset class="rows">
33
                        <legend>This sale</legend>
34
                        <p>Click to edit item cost or quantities</p>
35
                        <table id="sale" class="table_sale">
36
                            <thead>
37
                                <tr>
38
                                    <th>Item</th>
39
                                    <th>Cost</th>
40
                                    <th>Quantity</th>
41
                                    <th>Total</th>
42
                                </tr>
43
                            </thead>
44
                            <tbody>
45
                            </tbody>
46
                            <tfoot>
47
                                <tr>
48
                                    <td colspan="3">Total payable:</td>
49
                                    <td></td>
50
                                </tr>
51
                            </tfoot>
52
                        </table>
53
                    </fieldset>
54
55
                    <fieldset class="rows">
56
                        <legend>Collect payment</legend>
57
                        <ol>
58
                            <li>
59
                                <label for="paid">Amount being paid: </label>
60
                                <input name="paid" id="paid" value="[% amountoutstanding | $Price on_editing => 1 %]"/>
61
                            </li>
62
                            <li>
63
                                <label for="collected">Collected from patron: </label>
64
                                <input id="collected" value="[% amountoutstanding | $Price on_editing => 1 %]"/>
65
                            </li>
66
                            <li>
67
                                <label>Change to give: </label>
68
                                <span id="change">0.00</span>
69
                            </li>
70
71
                            [% SET payment_types = AuthorisedValues.GetAuthValueDropbox('PAYMENT_TYPE') %]
72
                            [% IF payment_types %]
73
                            <li>
74
                                <label for="payment_type">Payment type: </label>
75
                                <select name="payment_type" id="payment_type">
76
                                    [% FOREACH pt IN payment_types %]
77
                                        <option value="[% pt.authorised_value | html %]">[% pt.lib | html %]</option>
78
                                    [% END %]
79
                                </select>
80
                            </li>
81
                            [% END %]
82
83
                            [% IF Koha.Preference('UseCashRegisters') %]
84
                            <li>
85
                                <label for="cash_register">Cash register: </label>
86
                                <select name="cash_register" id="cash_register">
87
                                    [% FOREACH register IN registers %]
88
                                      [% IF register.id == registerid %]
89
                                    <option value="[% register.id %]" selected="selected">[% register.name | html %]</option>
90
                                      [% ELSE %]
91
                                    <option value="[% register.id %]">[% register.name | html %]</option>
92
                                      [% END %]
93
                                    [% END %]
94
                                </select>
95
                            </li>
96
                            [% END %]
97
                        </ol>
98
99
                    </fieldset>
100
                </div>
101
102
                <div class="col-sm-6">
103
                    <fieldset class="rows">
104
                        <legend>Items for purchase</legend>
105
                            [% SET invoice_types = AuthorisedValues.GetAuthValueDropbox('MANUAL_INV') %]
106
                            [% IF invoice_types %]
107
                            <table id="invoices">
108
                            <thead>
109
                                <tr>
110
                                    <th>Code</th>
111
                                    <th>Description</th>
112
                                    <th>Cost</th>
113
                                    <th>Action</th>
114
                                </tr>
115
                            </thead>
116
                            <tbody>
117
                            [% FOREACH invoice IN invoice_types %]
118
                                <tr>
119
                                    <td>[% invoice.authorised_value | html %]</td>
120
                                    <td>[% invoice.lib_opac | html %]</td>
121
                                    <td>[% invoice.lib | html %]</td>
122
                                    <td>
123
                                        <button class="add_button" data-invoice-code="[% invoice.lib_opac %]" data-invoice-title="[% invoice.authorised_value | html %]" data-invoice-price="[% invoice.lib | html %]"><i class="fa fa-plus"></i> Add</button>
124
                                    </td>
125
                                </tr>
126
                            [% END %]
127
                            </table>
128
                            [% ELSE %]
129
                            You have no manual invoice types defined
130
                            [% END %]
131
                    </fieldset>
132
                </div>
133
134
                <div class="action">
135
                    <input type="submit" name="submitbutton" value="Confirm" />
136
                    <a class="cancel" href="/cgi-bin/koha/pos/pay.pl">Cancel</a>
137
                </div>
138
            </div>
139
        </form>
140
        [% END %]
141
    </div>
142
143
    <div class="col-sm-2 col-sm-pull-10">
144
        <aside>
145
            [% INCLUDE 'pos-menu.inc' %]
146
        </aside>
147
    </div>
148
149
</div> <!-- /.row -->
150
151
[% MACRO jsinclude BLOCK %]
152
    [% Asset.js("js/admin-menu.js") | $raw %]
153
    [% INCLUDE 'datatables.inc' %]
154
    [% Asset.js("lib/jquery/plugins/jquery.jeditable.mini.js") | $raw %]
155
    <script>
156
    function fnClickAddRow( table, invoiceTitle, invoicePrice ) {
157
      table.fnAddData( [
158
        invoiceTitle,
159
        invoicePrice,
160
        1,
161
        null
162
         ]
163
      );
164
    }
165
166
    function moneyFormat(textObj) {
167
        var newValue = textObj.value;
168
        var decAmount = "";
169
        var dolAmount = "";
170
        var decFlag   = false;
171
        var aChar     = "";
172
173
        for(i=0; i < newValue.length; i++) {
174
            aChar = newValue.substring(i, i+1);
175
            if (aChar >= "0" && aChar <= "9") {
176
                if(decFlag) {
177
                    decAmount = "" + decAmount + aChar;
178
                }
179
                else {
180
                    dolAmount = "" + dolAmount + aChar;
181
                }
182
            }
183
            if (aChar == ".") {
184
                if (decFlag) {
185
                    dolAmount = "";
186
                    break;
187
                }
188
                decFlag = true;
189
            }
190
        }
191
192
        if (dolAmount == "") {
193
            dolAmount = "0";
194
        }
195
    // Strip leading 0s
196
        if (dolAmount.length > 1) {
197
            while(dolAmount.length > 1 && dolAmount.substring(0,1) == "0") {
198
                dolAmount = dolAmount.substring(1,dolAmount.length);
199
            }
200
        }
201
        if (decAmount.length > 2) {
202
            decAmount = decAmount.substring(0,2);
203
        }
204
    // Pad right side
205
        if (decAmount.length == 1) {
206
           decAmount = decAmount + "0";
207
        }
208
        if (decAmount.length == 0) {
209
           decAmount = decAmount + "00";
210
        }
211
212
        textObj.value = dolAmount + "." + decAmount;
213
    }
214
215
    function updateChangeValues() {
216
        var change = $('#change')[0];
217
        change.innerHTML = Math.round(($('#collected')[0].value - $('#paid')[0].value) * 100) / 100;
218
        if (change.innerHTML <= 0) {
219
            change.innerHTML = "0.00";
220
        } else {
221
            change.value = change.innerHTML;
222
            moneyFormat(change);
223
            change.innerHTML = change.value;
224
        }
225
        $('#modal_change').html(change.innerHTML);
226
    }
227
228
    $(document).ready(function() {
229
        var sale_table = $("#sale").dataTable($.extend(true, {}, dataTablesDefaults, {
230
            "bPaginate": false,
231
            "bFilter": false,
232
            "bInfo": false,
233
            "bAutoWidth": false,
234
            "aoColumnDefs": [{
235
                "aTargets": [-2],
236
                "bSortable": false,
237
                "bSearchable": false,
238
            }, {
239
                "aTargets": [-1],
240
                "mRender": function ( data, type, full ) {
241
                    var price = Number.parseFloat(data).toFixed(2);
242
                    return '£'+price;
243
                }
244
            }, {
245
                "aTargets": [-2, -3],
246
                "sClass" : "editable",
247
            }],
248
            "aaSorting": [
249
                [1, "asc"]
250
            ],
251
            "fnDrawCallback": function (oSettings) {
252
                var local = this;
253
                local.$('.editable').editable( function(value, settings) {
254
                    var aPos = local.fnGetPosition( this );
255
                    local.fnUpdate( value, aPos[0], aPos[1], true, false );
256
                    return value;
257
                },{
258
                    type    : 'text'
259
                })
260
            },
261
            "fnRowCallback": function( nRow, aData, iDisplayIndex, iDisplayIndexFull ) {
262
                var iTotal = aData[1] * aData[2];
263
                this.fnUpdate( iTotal, nRow, 3, false, false );
264
            },
265
            "fnFooterCallback": function(nFoot, aData, iStart, iEnd, aiDisplay) {
266
                var iTotalPrice = 0;
267
                for ( var i=0 ; i<aData.length ; i++ )
268
			    {
269
				    iTotalPrice += aData[i][3]*1;
270
			    }
271
272
                iTotalPrice = Number.parseFloat(iTotalPrice).toFixed(2);
273
                nFoot.getElementsByTagName('td')[1].innerHTML = iTotalPrice;
274
                $('#paid').val(iTotalPrice);
275
            }
276
        }));
277
278
        var items_table = $("#invoices").dataTable($.extend(true,{}, dataTablesDefaults, {
279
               "aoColumnDefs": [
280
                  { "aTargets": [ -1, -2 ], "bSortable": false, "bSearchable":false },
281
               ],
282
               "aaSorting": [[ 0, "asc" ]],
283
               "paginationType": "full",
284
        }));
285
286
        $(".add_button").on("click", function(ev) {
287
            ev.preventDefault();
288
            fnClickAddRow(sale_table, $( this ).data('invoiceTitle'), $( this ).data('invoicePrice') );
289
            items_table.fnFilter( '' );
290
        });
291
292
        $("#paid, #collected").on("change",function() {
293
            moneyFormat( this );
294
            if (change != undefined) {
295
                updateChangeValues();
296
            }
297
        });
298
299
        $("#payForm").submit(function(e){
300
            var rows = sale_table.fnGetData();
301
            rows.forEach(function (row, index) {
302
                var sale = {
303
                    code: row[0],
304
                    price: row[1],
305
                    quantity: row[2]
306
                };
307
                $('<input>').attr({
308
                    type: 'hidden',
309
                    name: 'sales',
310
                    value: JSON.stringify(sale)
311
                }).appendTo('#payForm');
312
            });
313
            return true;
314
        });
315
    });
316
    </script>
317
[% END %]
318
319
[% INCLUDE 'intranet-bottom.inc' %]
(-)a/pos/pay.pl (-1 / +79 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/perl
2
3
use Modern::Perl;
4
5
use CGI;
6
use JSON qw( from_json );
7
8
use C4::Auth qw/:DEFAULT get_session/;
9
use C4::Output;
10
use C4::Context;
11
12
use Koha::AuthorisedValues;
13
use Koha::Cash::Registers;
14
use Koha::Charges::Sales;
15
use Koha::Database;
16
use Koha::Libraries;
17
18
my $q         = CGI->new();
19
my $sessionID = $q->cookie('CGISESSID');
20
my $session   = get_session($sessionID);
21
22
my ( $template, $loggedinuser, $cookie, $user_flags ) = get_template_and_user(
23
    {
24
        template_name   => 'pos/pay.tt',
25
        query           => $q,
26
        type            => 'intranet',
27
        authnotrequired => 0,
28
    }
29
);
30
my $logged_in_user = Koha::Patrons->find($loggedinuser) or die "Not logged in";
31
32
my $library_id = C4::Context->userenv->{'branch'};
33
my $registerid = $q->param('registerid');
34
my $registers  = Koha::Cash::Registers->search(
35
    { branch   => $library_id, archived => 0 },
36
    { order_by => { '-asc' => 'name' } }
37
);
38
39
if ( !$registers->count ) {
40
    $template->param( error_registers => 1 );
41
}
42
else {
43
    if ( !$registerid ) {
44
        my $default_register = Koha::Cash::Registers->find(
45
            { branch => $library_id, branch_default => 1 } );
46
        $registerid = $default_register->id if $default_register;
47
    }
48
    $registerid = $registers->next->id if !$registerid;
49
50
    $template->param(
51
        registerid => $registerid,
52
        registers  => $registers,
53
    );
54
}
55
56
my $total_paid = $q->param('paid');
57
if ( $total_paid and $total_paid ne '0.00' ) {
58
    warn "total_paid: $total_paid\n";
59
    my $cash_register = Koha::Cash::Registers->find( { id => $registerid } );
60
    my $payment_type  = $q->param('payment_type');
61
    my $sale          = Koha::Charges::Sales->new(
62
        {
63
            cash_register => $cash_register,
64
            staff_id      => $logged_in_user->id
65
        }
66
    );
67
68
    my @sales = $q->multi_param('sales');
69
    for my $item (@sales) {
70
        $item = from_json $item;
71
        $sale->add_item($item);
72
    }
73
74
    $sale->purchase( { payment_type => $payment_type } );
75
}
76
77
output_html_with_http_headers( $q, $cookie, $template->output );
78
79
1;

Return to bug 23354