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