]> git.koha-community.org Git - koha.git/blob - koha-tmpl/intranet-tmpl/prog/en/modules/pos/pay.tt
Bug 34478: op-cud - Rename op with op-cud in templates
[koha.git] / koha-tmpl / intranet-tmpl / prog / en / modules / pos / pay.tt
1 [% USE raw %]
2 [% USE AdditionalContents %]
3 [% USE Asset %]
4 [% USE Branches %]
5 [% USE Koha %]
6 [% USE Price %]
7 [% USE TablesSettings %]
8 [% USE Registers %]
9 [% PROCESS 'i18n.inc' %]
10 [% SET footerjs = 1 %]
11 [% INCLUDE 'doc-head-open.inc' %]
12 [% SET registers = Registers.all( filters => { current_branch => 1 } ) %]
13 <title>[% FILTER collapse %]
14     [% t("Point of sale") | html %] &rsaquo;
15     [% t("Koha") | html %]
16 [% END %]</title>
17 [% INCLUDE 'doc-head-close.inc' %]
18 </head>
19
20 <body id="payments" class="pos">
21 [% WRAPPER 'header.inc' %]
22     [% INCLUDE 'circ-search.inc' %]
23 [% END %]
24
25 [% WRAPPER 'sub-header.inc' %]
26     [% WRAPPER breadcrumbs %]
27         [% WRAPPER breadcrumb_item bc_active= 1 %]
28             <span>Point of sale</span>
29         [% END %]
30     [% END #/ WRAPPER breadcrumbs %]
31 [% END #/ WRAPPER sub-header.inc %]
32
33 <div class="main container-fluid">
34     <div class="row">
35         <div class="col-md-10 col-md-push-2">
36             [% INCLUDE 'messages.inc' %]
37
38             <h1>Point of sale</h1>
39
40         [% IF ( registers.size == 0 ) %]
41             <div id="error_message" class="dialog message">
42                 <p>
43                     You must have at least one cash register associated with the library before you can record payments.
44                 </p>
45                 [% IF ( CAN_user_parameters_manage_cash_registers ) %]
46                     <form action="/cgi-bin/koha/admin/cash_registers.pl" method="post">
47                         [% INCLUDE 'csrf-token.inc' %]
48                         <input type="hidden" name="op-cud" value="add_form" />
49                         <button class="new" type="submit"><i class="fa fa-plus"></i> Create a new cash register</button>
50                     </form>
51                 [% END %]
52             </div>
53         [% ELSE %]
54
55         [% IF payment_id && !Koha.Preference('FinePaymentAutoPopup') %]
56         <div class="dialog message audio-alert-action">
57             <p>Payment received</p>
58             <p>
59                 <a target="_blank" href="/cgi-bin/koha/pos/printreceipt.pl?action=print&accountlines_id=[% payment_id | uri %]&collected=[% collected | uri %]&change=[% change | uri %]" class="btn btn-default"><i class="fa fa-print"></i> Print receipt</a>
60                 <a href="#" data-toggle="modal" data-target="#emailReceiptModal" class="btn btn-default"><i class="fa-solid fa-envelope"></i> Email receipt</a>
61
62             </p>
63         </div>
64         [% END %]
65
66         <form name="payForm" id="payForm" method="post" action="/cgi-bin/koha/pos/pay.pl">
67             [% INCLUDE 'csrf-token.inc' %]
68             <div class="row">
69
70                 <div class="col-md-6">
71                     <fieldset class="rows">
72                         <legend>Items for purchase</legend>
73                             Please select items from below to add to this transaction:
74                             [% IF invoice_types %]
75                             <table id="invoices">
76                             <thead>
77                                 <tr>
78                                     <th>Code</th>
79                                     <th>Description</th>
80                                     <th class="NoSort">Cost</th>
81                                     <th class="NoSort">Action</th>
82                                 </tr>
83                             </thead>
84                             <tbody>
85                             [% FOREACH invoice IN invoice_types %]
86                                 <tr>
87                                     <td>[% invoice.code | html %]</td>
88                                     <td>[% invoice.description | html %]</td>
89                                     <td>[% invoice.default_amount | $Price %]</td>
90                                     <td>
91                                         <button type="button" class="btn btn-default btn-xs add_button" data-invoice-code="[% invoice.code | html %]" data-invoice-title="[% invoice.description | html %]" data-invoice-price="[% invoice.default_amount | html %]"><i class="fa fa-plus"></i> Add</button>
92                                     </td>
93                                 </tr>
94                             [% END %]
95                             </table>
96                             [% ELSE %]
97                             You have no manual invoice types defined
98                             [% END %]
99                     </fieldset>
100                 </div>
101
102                 <div class="col-md-6">
103
104                     <fieldset class="rows">
105                         <legend>This sale</legend>
106                         <p>Click to edit item cost or quantities</p>
107                         <table id="sale" class="table_sale">
108                             <thead>
109                                 <tr>
110                                     <th>Item</th>
111                                     <th>Cost</th>
112                                     <th>Quantity</th>
113                                     <th>Total</th>
114                                     <th>Action</th>
115                                     <th>CODE</th>
116                                 </tr>
117                             </thead>
118                             <tbody>
119                             </tbody>
120                             <tfoot>
121                                 <tr>
122                                     <td colspan="3">Total payable:</td>
123                                     <td></td>
124                                     <td></td>
125                                     <td></td>
126                                 </tr>
127                             </tfoot>
128                         </table>
129                     </fieldset>
130
131                     <fieldset class="rows">
132                         <legend>Collect payment</legend>
133                         <ol>
134                             <li>
135                                 <label for="paid">Amount being paid: </label>
136                                 <input type="text" inputmode="none" pattern="[0-9]*" name="paid" id="paid" value="" readonly/>
137                             </li>
138                             <li>
139                                 <label for="collected" class="required">Amount tendered: </label>
140                                 <input type="text" inputmode="numeric" pattern="[0-9]*" name="collected" id="collected" value="" class="required" required="required" />
141                                 <span class="required">Required</span>
142                             </li>
143                             <li>
144                                 <label>Change to give: </label>
145                                 <span id="change">[% 0 | $Price %]</span>
146                                 <input type="hidden" name="change" value="[% 0 | $Price %]"/>
147                             </li>
148
149                             [% INCLUDE 'transaction_types.inc' type="payment" %]
150
151                             <li>
152                                 <label for="registerid" class="required">Cash register: </label>
153                                 <select name="registerid" id="registerid" class="required" required="required">
154                                     <option id="noregister" disabled="disabled" value="">-- Select an option--</option>
155                                     [% PROCESS options_for_registers %]
156                                 </select>
157                                 <span class="required">Required</span>
158                             </li>
159                         </ol>
160
161                     </fieldset>
162
163                     <fieldset class="action">
164                         <input type="submit" id="submitbutton" name="submitbutton" class="btn btn-primary" value="Confirm" />
165                         <a class="cancel" href="/cgi-bin/koha/pos/pay.pl">Cancel</a>
166                     </fieldset>
167                 </div>
168             </div>
169         </form>
170         [% END %]
171
172         [%- SET StaffPOSHome = AdditionalContents.get( location => "StaffPOSHome", lang => lang, library => logged_in_user.branchcode ) -%]
173         [%- FOREACH block IN StaffPOSHome.content -%]
174         <div class="page-section">
175             [%- block.content | $raw -%]
176         </div>
177         [%- END -%]
178
179     </div>
180
181     <div class="col-md-2 col-md-pull-10">
182         <aside>
183             [% INCLUDE 'pos-menu.inc' %]
184         </aside>
185     </div>
186 </div> <!-- /.row -->
187
188 <!-- Email receipt modal -->
189 <div class="modal" id="emailReceiptModal" tabindex="-1" role="dialog" aria-labelledby="emailReceiptLabel">
190     <form id="email_form" action="/cgi-bin/koha/pos/pay.pl" method="get" enctype="multipart/form-data" class="validated">
191         <input type="hidden" name="payment_id" value="[% payment_id | uri %]">
192         <input type="hidden" name="collected" value="[% collected | uri %]">
193         <input type="hidden" name="change" value="[% change | uri %]">"
194         <div class="modal-dialog" role="document">
195             <div class="modal-content">
196                 <div class="modal-header">
197                     <button type="button" class="closebtn" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
198                     <h4 class="modal-title" id="emailReceiptLabel">Email receipt</h4>
199                 </div>
200                 <div class="modal-body">
201                     <fieldset class="rows">
202                         <ol>
203                             <li>
204                                 <label class="required" for="toaddr">Email address: </label>
205                                 <input type="email" id="toaddr" name="toaddr" required="required">
206                                 <span class="required">Required</span>
207                             </li>
208                         </ol>
209                     </fieldset> <!-- /.rows -->
210                 </div> <!-- /.modal-body -->
211                 <div class="modal-footer">
212                     <input type="hidden" name="action" value="send">
213                     <button type="submit" class="btn btn-default">Confirm</button>
214                     <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
215                 </div> <!-- /.modal-footer -->
216             </div> <!-- /.modal-content -->
217         </div> <!-- /.modal-dialog -->
218     </form> <!-- /#email_form -->
219 </div> <!-- /#emailReceiptModal -->
220
221 <!-- Change modal -->
222 <div id="confirm_change_form" class="modal" tabindex="-1" role="dialog" aria-hidden="true">
223     <div class="modal-dialog">
224         <div class="modal-content">
225             <div class="modal-header">
226                 <h3>The amount collected is more than the outstanding charge</h3>
227             </div>
228             <div class="modal-body">
229                 <p>The amount collected from the patron is higher than the amount to be paid.</p>
230                 <p>The change to give is <strong><span id="modal_change">[% 0 | $Price %]</span></strong>.</p>
231                 <p>Confirm this payment?</p>
232             </div>
233             <div class="modal-footer">
234                 <button class="btn btn-default approve" id="modal_submit" type="button"><i class="fa fa-check"></i> Yes</button>
235                 <button class="btn btn-default deny cancel" data-dismiss="modal" aria-hidden="true" type="button"><i class="fa fa-times"></i> No</button>
236             </div>
237         </div>
238     </div>
239 </div>
240
241 [% IF payment_id && Koha.Preference('FinePaymentAutoPopup') %]
242     <!-- Automatic Print Receipt -->
243     <a id="printReceipt" style="display: none" href="#"></a>
244 [% END %]
245
246 [% MACRO jsinclude BLOCK %]
247     [% INCLUDE 'format_price.inc' %]
248     [% INCLUDE 'datatables.inc' %]
249     [% INCLUDE 'columns_settings.inc' %]
250     [% Asset.js("lib/jquery/plugins/jquery.jeditable.mini.js") | $raw %]
251     <script>
252     function moneyFormat(textObj) {
253         var newValue = textObj.value;
254         var decAmount = "";
255         var dolAmount = "";
256         var dolFlag   = false;
257         var aChar     = "";
258
259         for(var i = newValue.length; 0 < i; i--) {
260             aChar = newValue.substring(i-1, i);
261             if ("0" <= aChar && aChar <= "9") {
262                 if(dolFlag) {
263                     dolAmount = "" + aChar + dolAmount;
264                 }
265                 else {
266                     decAmount = "" + aChar + decAmount;
267                 }
268             }
269             if (aChar == "." || aChar == ",") {
270                 dolFlag = true;
271             }
272         }
273
274         if (!dolFlag) {
275             dolAmount = decAmount;
276             decAmount = "";
277         }
278
279         if (dolAmount == "") {
280             dolAmount = "0";
281         }
282     // Strip leading 0s
283         if (dolAmount.length > 1) {
284             while(dolAmount.length > 1 && dolAmount.substring(0,1) == "0") {
285                 dolAmount = dolAmount.substring(1,dolAmount.length);
286             }
287         }
288         if (decAmount.length > 2) {
289             decAmount = decAmount.substring(0,2);
290         }
291     // Pad right side
292         if (decAmount.length == 1) {
293            decAmount = decAmount + "0";
294         }
295         if (decAmount.length == 0) {
296            decAmount = decAmount + "00";
297         }
298
299         textObj.value = dolAmount + "." + decAmount;
300     }
301
302     function fnClickAddRow( table, invoiceCode, invoiceTitle, invoicePrice ) {
303       var defaultPrice = { value: invoicePrice };
304       moneyFormat(defaultPrice);
305       table.fnAddData( [
306         invoiceTitle,
307         defaultPrice.value,
308         1,
309         null,
310         '<button class="btn btn-default btn-xs drop" type="button"><i class="fa fa-trash-can"></i> ' + _("Remove") + '</button>',
311         invoiceCode
312         ]
313       );
314     }
315
316     function updateChangeValues() {
317         var change = $('#change')[0];
318         var zero_formatted = "[% 0 | $Price %]";
319         change.innerHTML = Math.round(($('#collected')[0].value - $('#paid')[0].value) * 100) / 100;
320         if (change.innerHTML <= 0) {
321             var paid = $('#paid')[0];
322             moneyFormat(paid);
323             $('#collected').rules( "add", { min: Number(paid.value) });
324             change.innerHTML = zero_formatted;
325             $(':input[name="change"]').val(zero_formatted);
326         } else {
327             change.value = change.innerHTML;
328             moneyFormat(change);
329             change.innerHTML = change.value;
330             $(':input[name="change"]').val(change.value);
331         }
332
333         $('#modal_change').html(change.innerHTML);
334     }
335
336     $(document).ready(function() {
337         var sale_table = $("#sale").dataTable($.extend(true, {}, dataTablesDefaults, {
338             "paginate": false,
339             "searching": false,
340             "info": false,
341             "columnDefs": [{
342                 "targets": [-2],
343                 "orderable": false,
344                 "searchable":  false,
345             }, {
346                 "targets": [-3],
347                 "render": function ( data, type, full ) {
348                     var price = Number.parseFloat(data);
349                     return price.format_price();
350                 }
351             }, {
352                 "targets": [-5],
353                 "className":  "editable",
354             }, {
355                 "targets": [-4],
356                 "className":  "editable_int",
357             }, {
358                 "targets": [-1],
359                 "visible": false,
360                 "searchable": false
361             }],
362             "order": [],
363             "drawCallback": function (oSettings) {
364                 var local = this;
365                 local.$('.editable').editable( function(value, settings) {
366                     var aPos = local.fnGetPosition( this );
367                     local.fnUpdate( value, aPos[0], aPos[1], true, false );
368                     return value;
369                 },{
370                     type    : 'text',
371                     pattern : "^\\d+(\.\\d{2})?$",
372                     onblur  : 'submit',
373                     width   : "8em",
374                     tooltip : _("Click to edit")
375                 });
376                 local.$('.editable_int').editable( function(value, settings) {
377                     var aPos = local.fnGetPosition( this );
378                     local.fnUpdate( value, aPos[0], aPos[1], true, false );
379                     return value;
380                 },{
381                     type    : 'text',
382                     pattern : "[0-9]*",
383                     onblur  : 'submit',
384                     width   : "4em",
385                     tooltip : _("Click to edit")
386                 });
387             },
388             "rowCallback": function( nRow, aData, iDisplayIndex, iDisplayIndexFull ) {
389                 var iTotal = aData[1] * aData[2];
390                 this.fnUpdate( iTotal, nRow, 3, false, false );
391             },
392             "footerCallback": function(nFoot, aData, iStart, iEnd, aiDisplay) {
393                 var iTotalPrice = 0;
394                 for ( var i=0 ; i<aData.length ; i++ )
395                 {
396                     iTotalPrice += aData[i][3]*1;
397                 }
398                 iTotalPrice = iTotalPrice.format_price();
399                 nFoot.getElementsByTagName('td')[1].innerHTML = iTotalPrice;
400                 $('#paid').val(iTotalPrice);
401                 $('#paid').trigger('change');
402             },
403             "autoWidth": false
404         }));
405
406         $("#sale").on("click", "button.drop", function(){
407                 sale_table.DataTable().row($(this).parents('tr')).remove().draw(false);
408         });
409
410         var items_table_settings = [% TablesSettings.GetTableSettings('pos', 'pay', 'invoices', 'json') | $raw %];
411         var items_table = KohaTable("invoices", {
412                "pagingType": "full",
413                "order": [[ 0, "asc" ]],
414                "autoWidth": false
415         }, items_table_settings, false);
416
417         $("#invoices").on("click", ".add_button", function(e) {
418             e.preventDefault();
419             fnClickAddRow(sale_table, $( this ).data('invoiceCode'), $( this ).data('invoiceTitle'), $( this ).data('invoicePrice') );
420             if($('#invoices_filter').find('input[type=search]').val() !== ''){
421                 items_table.fnFilter( '' );
422             }
423         });
424
425         // Change calculation and modal
426         var change = $('#change')[0];
427         $("#paid, #collected").on("change",function() {
428             moneyFormat( this );
429             if (change != undefined) {
430                 updateChangeValues();
431             }
432         });
433
434         var checked = false;
435         $('#modal_submit').click(function() {
436             checked = true;
437             $('#payForm').submit();
438         });
439
440         $('#payForm').validate({
441             rules: {
442                 paid: {
443                     required: true
444                 },
445                 collected: {
446                     required: true
447                 },
448                 payment_type: {
449                     required: true
450                 },
451                 registerid: {
452                     required: true
453                 }
454             }
455         });
456
457         $('#payForm').submit(function(e){
458             // first, clear stale sales 'rows' from the payForm
459             if($('input[name="sales"]').length > 0) {
460                 $('input[name="sales"]').each(function() {
461                     $(this).remove();
462                 });
463             }
464
465             // now, process the current & fresh contents of the sale_table
466             if (change != undefined && change.innerHTML > 0.00 && !checked) {
467                 e.preventDefault();
468                 $("#confirm_change_form").modal("show");
469             } else {
470                 var rows = sale_table.fnGetData();
471                 rows.forEach(function (row, index) {
472                     var sale = {
473                         code: row[5],
474                         price: row[1],
475                         quantity: row[2]
476                     };
477                     $('<input>').attr({
478                         type: 'hidden',
479                         name: 'sales',
480                         value: JSON.stringify(sale)
481                     }).appendTo('#payForm');
482                 });
483                 return true;
484             }
485         });
486
487         [% IF payment_id && Koha.Preference('FinePaymentAutoPopup') %]
488             $("#printReceipt").click(function() {
489                 var win = window.open('/cgi-bin/koha/pos/printreceipt.pl?action=print&accountlines_id=[% payment_id | uri %]&collected=[% collected | uri %]&change=[% change | uri %]', '_blank');
490                 win.focus();
491             });
492             $("#printReceipt").click();
493         [% END %]
494     });
495     </script>
496 [% END %]
497 [% INCLUDE 'intranet-bottom.inc' %]