Bugzilla – Attachment 92873 Details for
Bug 23354
Add a 'Point of sale' screen to allow anonymous payments
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 23354: Add a Point Of Sale 'pay' screen
Bug-23354-Add-a-Point-Of-Sale-pay-screen.patch (text/plain), 25.89 KB, created by
Martin Renvoize (ashimema)
on 2019-09-17 11:15:29 UTC
(
hide
)
Description:
Bug 23354: Add a Point Of Sale 'pay' screen
Filename:
MIME Type:
Creator:
Martin Renvoize (ashimema)
Created:
2019-09-17 11:15:29 UTC
Size:
25.89 KB
patch
obsolete
>From b168a008ad6a989ef48d6a384f73611d5f0235f6 Mon Sep 17 00:00:00 2001 >From: Martin Renvoize <martin.renvoize@ptfs-europe.com> >Date: Tue, 23 Jul 2019 17:23:55 +0100 >Subject: [PATCH] Bug 23354: Add a Point Of Sale 'pay' screen > >This patch adds a new Point Of Sale module to Koha's staff client front >page. The module button leads directly to a 'Pay' page giving the staff >user the ability to record anonymous payments for items that would not >normally require a patron to be registered at the library. > >Test plan: >1) Enable `UseCashRegisters` via the system preferences. >2) Ensure your user has the 'manage_cash_registers' permission. >3) Add a cash register for your current branch. >4) Add at least one 'MANUAL_INV' authorized value. >5) Navigate to the new 'POS' pay page via the main menu. >6) Add an item to the 'sale' by clicking 'add' from the right side of > the screen. >7) Note that said item was added to the table of items this sale on the > left. >8) At this point you should be able to 'click to edit' the quantity or > price of the item in the table on the left. >9) Enter an amount greater than the price of the item into the 'amount > collected from patron' box. >10) Click 'Confirm' >11) Varify that the same change to give modal from the paycollect pages > appears here. >12) Click 'Confirm' >13) Payment will have been recorded (check the database) and you will be > back at a fresh 'Pay' page ready for the next transaction. >14) Signoff >--- > Koha/Charges/Sales.pm | 267 +++++++++++++++ > .../prog/en/includes/pos-menu.inc | 16 + > .../prog/en/modules/intranet-main.tt | 4 + > .../intranet-tmpl/prog/en/modules/pos/pay.tt | 319 ++++++++++++++++++ > pos/pay.pl | 79 +++++ > 5 files changed, 685 insertions(+) > create mode 100644 Koha/Charges/Sales.pm > create mode 100644 koha-tmpl/intranet-tmpl/prog/en/includes/pos-menu.inc > create mode 100644 koha-tmpl/intranet-tmpl/prog/en/modules/pos/pay.tt > create mode 100755 pos/pay.pl > >diff --git a/Koha/Charges/Sales.pm b/Koha/Charges/Sales.pm >new file mode 100644 >index 0000000000..f3805f1382 >--- /dev/null >+++ b/Koha/Charges/Sales.pm >@@ -0,0 +1,267 @@ >+package Koha::Charges::Sales; >+ >+# Copyright 2019 PTFS Europe >+# >+# This file is part of Koha. >+# >+# Koha is free software; you can redistribute it and/or modify it >+# under the terms of the GNU General Public License as published by >+# the Free Software Foundation; either version 3 of the License, or >+# (at your option) any later version. >+# >+# Koha is distributed in the hope that it will be useful, but >+# WITHOUT ANY WARRANTY; without even the implied warranty of >+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+# GNU General Public License for more details. >+# >+# You should have received a copy of the GNU General Public License >+# along with Koha; if not, see <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+ >+use Koha::Account::Lines; >+use Koha::Account::Offsets; >+use Koha::DateUtils qw( dt_from_string ); >+use Koha::Exceptions; >+ >+=head1 NAME >+ >+Koha::Charges::Sale - Module for collecting sales in Koha >+ >+=head1 SYNOPSIS >+ >+ use Koha::Charges::Sale; >+ >+ my $sale = >+ Koha::Charges::Sale->new( { cash_register => $register, staff_id => $staff_id } ); >+ $sale->add_item($item); >+ $sale->purchase( { payment_type => 'CASH' } ); >+ >+=head2 Class methods >+ >+=head3 new >+ >+ Koha::Charges::Sale->new( >+ { >+ cash_register => $cash_register, >+ staff_id => $staff_id, >+ [ payment_type => $payment_type ], >+ [ items => $items ], >+ [ patron => $patron ], >+ } >+ ); >+ >+=cut >+ >+sub new { >+ my ( $class, $params ) = @_; >+ >+ Koha::Exceptions::MissingParameter->throw( >+ "Missing mandatory parameter: cash_register") >+ unless $params->{cash_register}; >+ >+ Koha::Exceptions::MissingParameter->throw( >+ "Missing mandatory parameter: staff_id") >+ unless $params->{staff_id}; >+ >+ Carp::confess("Key 'cash_register' is not a Koha::Cash::Register object!") >+ unless $params->{cash_register}->isa('Koha::Cash::Register'); >+ >+ return bless( $params, $class ); >+} >+ >+=head3 payment_type >+ >+ my $payment_type = $sale->payment_type( $payment_type ); >+ >+A getter/setter for this instances associated payment type. >+ >+=cut >+ >+sub payment_type { >+ my ( $self, $payment_type ) = @_; >+ >+ if ($payment_type) { >+ Koha::Exceptions::Account::UnrecognisedType->throw( >+ error => 'Type of payment not recognised' ) >+ unless ( exists( $self->_get_valid_payments->{$payment_type} ) ); >+ >+ $self->{payment_type} = $payment_type; >+ } >+ >+ return $self->{payment_type}; >+} >+ >+=head3 _get_valid_payments >+ >+ my $valid_payments = $sale->_get_valid_payments; >+ >+A getter which returns a hashref whose keys represent valid payment types. >+ >+=cut >+ >+sub _get_valid_payments { >+ my $self = shift; >+ >+ $self->{valid_payments} //= { >+ map { $_ => 1 } Koha::AuthorisedValues->search( >+ { >+ category => 'PAYMENT_TYPE', >+ branchcode => $self->{cash_register}->branch >+ } >+ )->get_column('authorised_value') >+ }; >+ >+ return $self->{valid_payments}; >+} >+ >+=head3 add_item >+ >+ my $item = { price => 0.25, quantity => 1, code => 'COPY' }; >+ $sale->add_item( $item ); >+ >+=cut >+ >+sub add_item { >+ my ( $self, $item ) = @_; >+ >+ Koha::Exceptions::MissingParameter->throw( >+ "Missing mandatory parameter: code") >+ unless $item->{code}; >+ >+ Koha::Exceptions::Account::UnrecognisedType->throw( >+ error => 'Type of debit not recognised' ) >+ unless ( exists( $self->_get_valid_items->{ $item->{code} } ) ); >+ >+ Koha::Exceptions::MissingParameter->throw( >+ "Missing mandatory parameter: price") >+ unless $item->{price}; >+ >+ Koha::Exceptions::MissingParameter->throw( >+ "Missing mandatory parameter: quantity") >+ unless $item->{quantity}; >+ >+ push @{ $self->{items} }, $item; >+ return $self; >+} >+ >+=head3 _get_valid_items >+ >+ my $valid_items = $sale->_get_valid_items; >+ >+A getter which returns a hashref whose keys represent valid sale items. >+ >+=cut >+ >+sub _get_valid_items { >+ my $self = shift; >+ >+ $self->{valid_items} //= { >+ map { $_ => 1 } Koha::AuthorisedValues->search( >+ { >+ category => 'MANUAL_INV', >+ branchcode => $self->{cash_register}->branch >+ } >+ )->get_column('authorised_value') >+ }; >+ >+ return $self->{valid_items}; >+} >+ >+=head3 purchase >+ >+ my $credit_line = $sale->purchase; >+ >+=cut >+ >+sub purchase { >+ my ( $self, $params ) = @_; >+ >+ if ( $params->{payment_type} ) { >+ Koha::Exceptions::Account::UnrecognisedType->throw( >+ error => 'Type of payment not recognised' ) >+ unless ( >+ exists( $self->_get_valid_payments->{ $params->{payment_type} } ) ); >+ >+ $self->{payment_type} = $params->{payment_type}; >+ } >+ >+ Koha::Exceptions::MissingParameter->throw( >+ "Missing mandatory parameter: payment_type") >+ unless $self->{payment_type}; >+ >+ Koha::Exceptions::NoChanges->throw( >+ "Cannot purchase before calling add_item") >+ unless $self->{items}; >+ >+ my $schema = Koha::Database->new->schema; >+ my $dt = dt_from_string(); >+ my $total_owed = 0; >+ my $credit; >+ >+ $schema->txn_do( >+ sub { >+ >+ my $debit_offsets; >+ for my $item ( @{ $self->{items} } ) { >+ >+ my $amount = $item->{quantity} * $item->{price}; >+ $total_owed = $total_owed + $amount; >+ >+ # Insert the account line >+ my $line = Koha::Account::Line->new( >+ { >+ amount => $amount, >+ accounttype => $item->{code}, >+ amountoutstanding => 0, >+ note => $item->{quantity}, >+ manager_id => $self->{staff_id}, >+ interface => 'intranet', >+ branchcode => $self->{cash_register}->branch, >+ date => $dt >+ } >+ )->store(); >+ >+ # Record the account offset >+ my $account_offset = Koha::Account::Offset->new( >+ { >+ debit_id => $line->id, >+ type => 'Payment', >+ amount => $amount * -1 >+ } >+ )->store(); >+ >+ push @{$debit_offsets}, $account_offset; >+ } >+ >+ $credit = Koha::Account::Line->new( >+ { >+ amount => 0 - $total_owed, >+ accounttype => 'Purchase', >+ payment_type => $self->{payment_type}, >+ amountoutstanding => 0, >+ manager_id => $self->{staff_id}, >+ interface => 'intranet', >+ branchcode => $self->{cash_register}->branch, >+ register_id => $self->{cash_register}->id, >+ date => $dt, >+ note => "POS SALE" >+ } >+ )->store(); >+ >+ for my $offset ( @{$debit_offsets} ) { >+ $offset->credit_id( $credit->accountlines_id )->store(); >+ } >+ } >+ ); >+ >+ return $credit; >+} >+ >+=head1 AUTHOR >+ >+Martin Renvoize <martin.renvoize@ptfs-europe.com> >+ >+=cut >+ >+1; >diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/pos-menu.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/pos-menu.inc >new file mode 100644 >index 0000000000..e8e51bab53 >--- /dev/null >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/pos-menu.inc >@@ -0,0 +1,16 @@ >+<div id="navmenu"> >+ <div id="navmenulist"> >+ [% IF ( CAN_user_cash_management_manage_cash_registers || CAN_user_parameters_manage_auth_values) %] >+ <h5>Administration</h5> >+ <ul> >+ [% IF ( CAN_user_cash_management_manage_cash_registers ) %] >+ <li><a href="/cgi-bin/koha/admin/cash_registers.pl">Cash registers</a></li> >+ [% END %] >+ >+ [% IF ( CAN_user_parameters_manage_auth_values ) %] >+ <li><a href="/cgi-bin/koha/admin/authorised_values.pl?searchfield=MANUAL_INV">Purchase items</a></li> >+ [% END %] >+ </ul> >+ [% END %] >+ </div> >+</div> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt >index ab04abbcd9..9257968a09 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/intranet-main.tt >@@ -80,6 +80,10 @@ > <div class="col-xs-6"> > <ul class="biglinks-list"> > >+ <li> >+ <a class="icon_general icon_pos" href="/cgi-bin/koha/pos/pay.pl">POS</a> >+ </li> >+ > [% IF ( CAN_user_editcatalogue_edit_catalogue || CAN_user_editcatalogue_edit_items ) %] > <li> > <a class="icon_general icon_cataloging" href="/cgi-bin/koha/cataloguing/addbooks.pl">Cataloging</a> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/pos/pay.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/pos/pay.tt >new file mode 100644 >index 0000000000..33e0fb0687 >--- /dev/null >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/pos/pay.tt >@@ -0,0 +1,319 @@ >+[% USE raw %] >+[% USE Asset %] >+[% USE Koha %] >+[% USE AuthorisedValues %] >+[% USE Price %] >+[% SET footerjs = 1 %] >+[% INCLUDE 'doc-head-open.inc' %] >+<title>Koha › Payments</title> >+[% INCLUDE 'doc-head-close.inc' %] >+</head> >+ >+<body id="payments" class="pos"> >+[% INCLUDE 'header.inc' %] >+[% INCLUDE 'circ-search.inc' %] >+ >+<div id="breadcrumbs"><a href="/cgi-bin/koha/mainpage.pl">Home</a> › Point of sale</div> >+ >+<div class="main container-fluid"> >+ <div class="row"> >+ <div class="col-sm-10 col-sm-push-2"> >+ >+ [% IF ( error_registers ) %] >+ <div id="error_message" class="dialog alert"> >+ You must have at least one cash register associated with this branch before you can record payments. >+ </div> >+ [% ELSE %] >+ <form name="payForm" id="payForm" method="post" action="/cgi-bin/koha/pos/pay.pl"> >+ <div class="row"> >+ >+ <div class="col-sm-6"> >+ >+ <fieldset class="rows"> >+ <legend>This sale</legend> >+ <p>Click to edit item cost or quantities</p> >+ <table id="sale" class="table_sale"> >+ <thead> >+ <tr> >+ <th>Item</th> >+ <th>Cost</th> >+ <th>Quantity</th> >+ <th>Total</th> >+ </tr> >+ </thead> >+ <tbody> >+ </tbody> >+ <tfoot> >+ <tr> >+ <td colspan="3">Total payable:</td> >+ <td></td> >+ </tr> >+ </tfoot> >+ </table> >+ </fieldset> >+ >+ <fieldset class="rows"> >+ <legend>Collect payment</legend> >+ <ol> >+ <li> >+ <label for="paid">Amount being paid: </label> >+ <input name="paid" id="paid" value="[% amountoutstanding | $Price on_editing => 1 %]"/> >+ </li> >+ <li> >+ <label for="collected">Collected from patron: </label> >+ <input id="collected" value="[% amountoutstanding | $Price on_editing => 1 %]"/> >+ </li> >+ <li> >+ <label>Change to give: </label> >+ <span id="change">0.00</span> >+ </li> >+ >+ [% SET payment_types = AuthorisedValues.GetAuthValueDropbox('PAYMENT_TYPE') %] >+ [% IF payment_types %] >+ <li> >+ <label for="payment_type">Payment type: </label> >+ <select name="payment_type" id="payment_type"> >+ [% FOREACH pt IN payment_types %] >+ <option value="[% pt.authorised_value | html %]">[% pt.lib | html %]</option> >+ [% END %] >+ </select> >+ </li> >+ [% END %] >+ >+ [% IF Koha.Preference('UseCashRegisters') %] >+ <li> >+ <label for="cash_register">Cash register: </label> >+ <select name="cash_register" id="cash_register"> >+ [% FOREACH register IN registers %] >+ [% IF register.id == registerid %] >+ <option value="[% register.id %]" selected="selected">[% register.name | html %]</option> >+ [% ELSE %] >+ <option value="[% register.id %]">[% register.name | html %]</option> >+ [% END %] >+ [% END %] >+ </select> >+ </li> >+ [% END %] >+ </ol> >+ >+ </fieldset> >+ </div> >+ >+ <div class="col-sm-6"> >+ <fieldset class="rows"> >+ <legend>Items for purchase</legend> >+ [% SET invoice_types = AuthorisedValues.GetAuthValueDropbox('MANUAL_INV') %] >+ [% IF invoice_types %] >+ <table id="invoices"> >+ <thead> >+ <tr> >+ <th>Code</th> >+ <th>Description</th> >+ <th>Cost</th> >+ <th>Action</th> >+ </tr> >+ </thead> >+ <tbody> >+ [% FOREACH invoice IN invoice_types %] >+ <tr> >+ <td>[% invoice.authorised_value | html %]</td> >+ <td>[% invoice.lib_opac | html %]</td> >+ <td>[% invoice.lib | html %]</td> >+ <td> >+ <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> >+ </td> >+ </tr> >+ [% END %] >+ </table> >+ [% ELSE %] >+ You have no manual invoice types defined >+ [% END %] >+ </fieldset> >+ </div> >+ >+ <div class="action"> >+ <input type="submit" name="submitbutton" value="Confirm" /> >+ <a class="cancel" href="/cgi-bin/koha/pos/pay.pl">Cancel</a> >+ </div> >+ </div> >+ </form> >+ [% END %] >+ </div> >+ >+ <div class="col-sm-2 col-sm-pull-10"> >+ <aside> >+ [% INCLUDE 'pos-menu.inc' %] >+ </aside> >+ </div> >+ >+</div> <!-- /.row --> >+ >+[% MACRO jsinclude BLOCK %] >+ [% Asset.js("js/admin-menu.js") | $raw %] >+ [% INCLUDE 'datatables.inc' %] >+ [% Asset.js("lib/jquery/plugins/jquery.jeditable.mini.js") | $raw %] >+ <script> >+ function fnClickAddRow( table, invoiceTitle, invoicePrice ) { >+ table.fnAddData( [ >+ invoiceTitle, >+ invoicePrice, >+ 1, >+ null >+ ] >+ ); >+ } >+ >+ function moneyFormat(textObj) { >+ var newValue = textObj.value; >+ var decAmount = ""; >+ var dolAmount = ""; >+ var decFlag = false; >+ var aChar = ""; >+ >+ for(i=0; i < newValue.length; i++) { >+ aChar = newValue.substring(i, i+1); >+ if (aChar >= "0" && aChar <= "9") { >+ if(decFlag) { >+ decAmount = "" + decAmount + aChar; >+ } >+ else { >+ dolAmount = "" + dolAmount + aChar; >+ } >+ } >+ if (aChar == ".") { >+ if (decFlag) { >+ dolAmount = ""; >+ break; >+ } >+ decFlag = true; >+ } >+ } >+ >+ if (dolAmount == "") { >+ dolAmount = "0"; >+ } >+ // Strip leading 0s >+ if (dolAmount.length > 1) { >+ while(dolAmount.length > 1 && dolAmount.substring(0,1) == "0") { >+ dolAmount = dolAmount.substring(1,dolAmount.length); >+ } >+ } >+ if (decAmount.length > 2) { >+ decAmount = decAmount.substring(0,2); >+ } >+ // Pad right side >+ if (decAmount.length == 1) { >+ decAmount = decAmount + "0"; >+ } >+ if (decAmount.length == 0) { >+ decAmount = decAmount + "00"; >+ } >+ >+ textObj.value = dolAmount + "." + decAmount; >+ } >+ >+ function updateChangeValues() { >+ var change = $('#change')[0]; >+ change.innerHTML = Math.round(($('#collected')[0].value - $('#paid')[0].value) * 100) / 100; >+ if (change.innerHTML <= 0) { >+ change.innerHTML = "0.00"; >+ } else { >+ change.value = change.innerHTML; >+ moneyFormat(change); >+ change.innerHTML = change.value; >+ } >+ $('#modal_change').html(change.innerHTML); >+ } >+ >+ $(document).ready(function() { >+ var sale_table = $("#sale").dataTable($.extend(true, {}, dataTablesDefaults, { >+ "bPaginate": false, >+ "bFilter": false, >+ "bInfo": false, >+ "bAutoWidth": false, >+ "aoColumnDefs": [{ >+ "aTargets": [-2], >+ "bSortable": false, >+ "bSearchable": false, >+ }, { >+ "aTargets": [-1], >+ "mRender": function ( data, type, full ) { >+ var price = Number.parseFloat(data).toFixed(2); >+ return '£'+price; >+ } >+ }, { >+ "aTargets": [-2, -3], >+ "sClass" : "editable", >+ }], >+ "aaSorting": [ >+ [1, "asc"] >+ ], >+ "fnDrawCallback": function (oSettings) { >+ var local = this; >+ local.$('.editable').editable( function(value, settings) { >+ var aPos = local.fnGetPosition( this ); >+ local.fnUpdate( value, aPos[0], aPos[1], true, false ); >+ return value; >+ },{ >+ type : 'text' >+ }) >+ }, >+ "fnRowCallback": function( nRow, aData, iDisplayIndex, iDisplayIndexFull ) { >+ var iTotal = aData[1] * aData[2]; >+ this.fnUpdate( iTotal, nRow, 3, false, false ); >+ }, >+ "fnFooterCallback": function(nFoot, aData, iStart, iEnd, aiDisplay) { >+ var iTotalPrice = 0; >+ for ( var i=0 ; i<aData.length ; i++ ) >+ { >+ iTotalPrice += aData[i][3]*1; >+ } >+ >+ iTotalPrice = Number.parseFloat(iTotalPrice).toFixed(2); >+ nFoot.getElementsByTagName('td')[1].innerHTML = iTotalPrice; >+ $('#paid').val(iTotalPrice); >+ } >+ })); >+ >+ var items_table = $("#invoices").dataTable($.extend(true,{}, dataTablesDefaults, { >+ "aoColumnDefs": [ >+ { "aTargets": [ -1, -2 ], "bSortable": false, "bSearchable":false }, >+ ], >+ "aaSorting": [[ 0, "asc" ]], >+ "paginationType": "full", >+ })); >+ >+ $(".add_button").on("click", function(ev) { >+ ev.preventDefault(); >+ fnClickAddRow(sale_table, $( this ).data('invoiceTitle'), $( this ).data('invoicePrice') ); >+ items_table.fnFilter( '' ); >+ }); >+ >+ $("#paid, #collected").on("change",function() { >+ moneyFormat( this ); >+ if (change != undefined) { >+ updateChangeValues(); >+ } >+ }); >+ >+ $("#payForm").submit(function(e){ >+ var rows = sale_table.fnGetData(); >+ rows.forEach(function (row, index) { >+ var sale = { >+ code: row[0], >+ price: row[1], >+ quantity: row[2] >+ }; >+ $('<input>').attr({ >+ type: 'hidden', >+ name: 'sales', >+ value: JSON.stringify(sale) >+ }).appendTo('#payForm'); >+ }); >+ return true; >+ }); >+ }); >+ </script> >+[% END %] >+ >+[% INCLUDE 'intranet-bottom.inc' %] >diff --git a/pos/pay.pl b/pos/pay.pl >new file mode 100755 >index 0000000000..18d968df8d >--- /dev/null >+++ b/pos/pay.pl >@@ -0,0 +1,79 @@ >+#!/usr/bin/perl >+ >+use Modern::Perl; >+ >+use CGI; >+use JSON qw( from_json ); >+ >+use C4::Auth qw/:DEFAULT get_session/; >+use C4::Output; >+use C4::Context; >+ >+use Koha::AuthorisedValues; >+use Koha::Cash::Registers; >+use Koha::Charges::Sales; >+use Koha::Database; >+use Koha::Libraries; >+ >+my $q = CGI->new(); >+my $sessionID = $q->cookie('CGISESSID'); >+my $session = get_session($sessionID); >+ >+my ( $template, $loggedinuser, $cookie, $user_flags ) = get_template_and_user( >+ { >+ template_name => 'pos/pay.tt', >+ query => $q, >+ type => 'intranet', >+ authnotrequired => 0, >+ } >+); >+my $logged_in_user = Koha::Patrons->find($loggedinuser) or die "Not logged in"; >+ >+my $library_id = C4::Context->userenv->{'branch'}; >+my $registerid = $q->param('registerid'); >+my $registers = Koha::Cash::Registers->search( >+ { branch => $library_id, archived => 0 }, >+ { order_by => { '-asc' => 'name' } } >+); >+ >+if ( !$registers->count ) { >+ $template->param( error_registers => 1 ); >+} >+else { >+ if ( !$registerid ) { >+ my $default_register = Koha::Cash::Registers->find( >+ { branch => $library_id, branch_default => 1 } ); >+ $registerid = $default_register->id if $default_register; >+ } >+ $registerid = $registers->next->id if !$registerid; >+ >+ $template->param( >+ registerid => $registerid, >+ registers => $registers, >+ ); >+} >+ >+my $total_paid = $q->param('paid'); >+if ( $total_paid and $total_paid ne '0.00' ) { >+ warn "total_paid: $total_paid\n"; >+ my $cash_register = Koha::Cash::Registers->find( { id => $registerid } ); >+ my $payment_type = $q->param('payment_type'); >+ my $sale = Koha::Charges::Sales->new( >+ { >+ cash_register => $cash_register, >+ staff_id => $logged_in_user->id >+ } >+ ); >+ >+ my @sales = $q->multi_param('sales'); >+ for my $item (@sales) { >+ $item = from_json $item; >+ $sale->add_item($item); >+ } >+ >+ $sale->purchase( { payment_type => $payment_type } ); >+} >+ >+output_html_with_http_headers( $q, $cookie, $template->output ); >+ >+1; >-- >2.20.1
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 23354
:
92066
|
92431
|
92432
|
92433
|
92502
|
92830
|
92831
|
92832
|
92833
|
92834
|
92873
|
92874
|
92875
|
92876
|
92877
|
92878
|
92890
|
92891
|
92892
|
92893
|
92894
|
92895
|
93116
|
93117
|
93118
|
93119
|
93120
|
93121
|
93122
|
93123
|
93124
|
93465
|
93466
|
93467
|
93468
|
93469
|
93470
|
93471
|
93472
|
93473
|
93604
|
93605
|
93606
|
93607
|
93608
|
93609
|
93610
|
93611
|
93612
|
94689
|
94690
|
94691
|
94692
|
94693
|
94694
|
94695
|
94696
|
94697
|
94698
|
94699
|
95678
|
95679
|
95680
|
95681
|
95682
|
95683
|
95684
|
95685
|
95686
|
95687
|
95688
|
95689
|
95690
|
95691
|
95692
|
95693
|
97013
|
97014
|
97015
|
97016
|
97017
|
97018
|
97019
|
97020
|
97021
|
97022
|
97023
|
97024
|
97025
|
97026
|
97027
|
97028
|
97029
|
97169
|
97170
|
97171
|
97188
|
97189
|
97200
|
97201
|
97202
|
97203
|
97204
|
97205
|
97206
|
97207
|
97208
|
97209
|
97210
|
97211
|
97212
|
97213
|
97214
|
97215
|
97216
|
97217
|
97218
|
97219
|
97271
|
97272
|
97273
|
97274
|
97275
|
97276
|
97277
|
97278
|
97279
|
97280
|
97281
|
97282
|
97283
|
97284
|
97285
|
97286
|
97287
|
97288
|
97289
|
97290
|
97291
|
97292
|
97725
|
97726
|
100167