dolibarr 23.0.3
pay.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2018 Andreu Bisquerra <jove@bisquerra.com>
3 * Copyright (C) 2021-2022 Thibault FOUCART <support@ptibogxiv.net>
4 * Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
5 * Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it 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 * This program is distributed in the hope that it will be useful,
13 * but 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 this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
27// if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER', '1'); // Not disabled cause need to load personalized language
28// if (! defined('NOREQUIREDB')) define('NOREQUIREDB', '1'); // Not disabled cause need to load personalized language
29// if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC', '1');
30// if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN', '1');
31
32if (!defined('NOTOKENRENEWAL')) {
33 define('NOTOKENRENEWAL', '1');
34}
35if (!defined('NOREQUIREMENU')) {
36 define('NOREQUIREMENU', '1');
37}
38if (!defined('NOREQUIREHTML')) {
39 define('NOREQUIREHTML', '1');
40}
41
42// Load Dolibarr environment
43require '../main.inc.php'; // Load $user and permissions
52require_once DOL_DOCUMENT_ROOT.'/blockedlog/lib/blockedlog.lib.php';
53require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
54require_once DOL_DOCUMENT_ROOT.'/stripe/class/stripe.class.php';
55
56// Load translation files required by the page
57$langs->loadLangs(array("main", "bills", "cashdesk", "banks"));
58
59$action = GETPOST('action', 'aZ09');
60
61$place = (GETPOST('place', 'aZ09') ? GETPOST('place', 'aZ09') : '0'); // $place is id of table for Bar or Restaurant
62
63$invoiceid = GETPOSTINT('invoiceid');
64
65$hookmanager->initHooks(array('takepospay'));
66
67if (!$user->hasRight('takepos', 'run')) {
69}
70
71
72/*
73 * View
74 */
75
76$arrayofcss = array('/takepos/css/pos.css.php');
77$arrayofjs = array();
78
79$head = '';
80$title = '';
81$disablejs = 0;
82$disablehead = 0;
83
84$head = '<link rel="stylesheet" href="css/pos.css.php">';
85if (getDolGlobalInt('TAKEPOS_COLOR_THEME') == 1) {
86 $head .= '<link rel="stylesheet" href="css/colorful.css">';
87}
88
89top_htmlhead($head, $title, $disablejs, $disablehead, $arrayofjs, $arrayofcss);
90
91?>
92<body>
93<?php
94
95$usestripeterminals = 0;
96$keyforstripeterminalbank = '';
97$stripe = null;
98$servicestatus = 0;
99$stripeacc = null;
100
101if (isModEnabled('stripe')) {
102 $service = 'StripeTest';
103
104 if (getDolGlobalString('STRIPE_LIVE')/* && !GETPOST('forcesandbox', 'alpha') */) {
105 $service = 'StripeLive';
106 $servicestatus = 1;
107 }
108
109 // Force to use the correct API key
110 global $stripearrayofkeysbyenv;
111 $site_account = $stripearrayofkeysbyenv[$servicestatus]['publishable_key'];
112
113 $stripe = new Stripe($db);
114 $stripeacc = $stripe->getStripeAccount($service); // Get Stripe OAuth connect account (no remote access to Stripe here)
115
116 include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
117 $invoicetmp = new Facture($db);
118 $invoicetmp->fetch($invoiceid);
119 $stripecu = $stripe->getStripeCustomerAccount($invoicetmp->socid, $servicestatus, $site_account); // Get remote Stripe customer 'cus_...' (no remote access to Stripe here)
120 $keyforstripeterminalbank = "CASHDESK_ID_BANKACCOUNT_STRIPETERMINAL".(empty($_SESSION['takeposterminal']) ? '' : $_SESSION['takeposterminal']);
121
122 $usestripeterminals = getDolGlobalString('STRIPE_LOCATION');
123
124 if ($usestripeterminals) {
125 ?>
126<script src="https://js.stripe.com/terminal/v1/"></script>
127<script>
128var terminal = StripeTerminal.create({
129 onFetchConnectionToken: fetchConnectionToken,
130 onUnexpectedReaderDisconnect: unexpectedDisconnect,
131});
132
133function unexpectedDisconnect() {
134 // In this function, your app should notify the user that the reader disconnected.
135 // You can also include a way to attempt to reconnect to a reader.
136 console.log("Disconnected from reader")
137}
138
139function fetchConnectionToken() {
140 <?php
141 $urlconnexiontoken = DOL_URL_ROOT.'/stripe/ajax/ajax.php?action=getConnexionToken&token='.newToken().'&servicestatus='.urlencode((string) ($servicestatus));
142 if (getDolGlobalString('STRIPE_LOCATION')) {
143 $urlconnexiontoken .= '&location='.urlencode(getDolGlobalString('STRIPE_LOCATION'));
144 }
145 if (!empty($stripeacc)) {
146 $urlconnexiontoken .= '&stripeacc='.urlencode($stripeacc);
147 } ?>
148 // Do not cache or hardcode the ConnectionToken. The SDK manages the ConnectionToken's lifecycle.
149 return fetch('<?php echo $urlconnexiontoken; ?>', { method: "POST" })
150 .then(function(response) {
151 return response.json();
152 })
153 .then(function(data) {
154 return data.secret;
155 });
156}
157
158</script>
159 <?php
160 }
161}
162
163if (isModEnabled('stripe') && isset($keyforstripeterminalbank) && (!getDolGlobalString('STRIPE_LIVE')/* || GETPOST('forcesandbox', 'alpha') */)) {
164 dol_htmloutput_mesg($langs->trans('YouAreCurrentlyInSandboxMode', 'Stripe'), [], 'warning', 1);
165}
166
167$invoice = new Facture($db);
168if ($invoiceid > 0) {
169 $invoice->fetch($invoiceid);
170} else {
171 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."facture";
172 $sql .= " WHERE entity IN (".getEntity('invoice').")";
173 $sql .= " AND ref = '(PROV-POS".$_SESSION["takeposterminal"]."-".$place.")'";
174 $resql = $db->query($sql);
175 $obj = $db->fetch_object($resql);
176 if ($obj) {
177 $invoiceid = $obj->rowid;
178 }
179 if (!$invoiceid) {
180 $invoiceid = 0; // Invoice does not exist yet
181 } else {
182 $invoice->fetch($invoiceid);
183 }
184}
185
186?>
187<script>
188<?php
189if ($usestripeterminals && $invoice->type != $invoice::TYPE_CREDIT_NOTE) {
190 if (!getDolGlobalString((string) $keyforstripeterminalbank) || $stripeacc === null) { ?>
191 const config = {
192 simulated: <?php if (empty($servicestatus) && getDolGlobalString('STRIPE_TERMINAL_SIMULATED')) { ?> true <?php } else { ?> false <?php } ?>
193 <?php if (getDolGlobalString('STRIPE_LOCATION')) { ?>, location: '<?php echo dol_escape_js(getDolGlobalString('STRIPE_LOCATION')); ?>'<?php } ?>
194 }
195 terminal.discoverReaders(config).then(function(discoverResult) {
196 if (discoverResult.error) {
197 console.log('Failed to discover: ', discoverResult.error);
198 } else if (discoverResult.discoveredReaders.length === 0) {
199 console.log('No available readers.');
200 } else {
201 // You should show the list of discoveredReaders to the
202 // cashier here and let them select which to connect to (see below).
203 selectedReader = discoverResult.discoveredReaders[0];
204 //console.log('terminal.discoverReaders', selectedReader); // only active for development
205
206 terminal.connectReader(selectedReader).then(function(connectResult) {
207 if (connectResult.error) {
208 document.getElementById("card-present-alert").innerHTML = '<div class="error">'+connectResult.error.message+'</div>';
209 console.log('Failed to connect: ', connectResult.error);
210 } else {
211 document.getElementById("card-present-alert").innerHTML = '';
212 console.log('Connected to reader: ', connectResult.reader.label);
213 if (document.getElementById("StripeTerminal")) {
214 document.getElementById("StripeTerminal").innerHTML = '<button type="button" class="calcbutton2" onclick="ValidateStripeTerminal();"><span class="fa fa-2x fa-credit-card iconwithlabel"></span><br>'+connectResult.reader.label+'</button>';
215 }
216 }
217 });
218 }
219 });
220 <?php } else { ?>
221 terminal.connectReader(<?php echo json_encode($stripe->getSelectedReader(getDolGlobalString((string) $keyforstripeterminalbank), $stripeacc, $servicestatus)); ?>).then(function(connectResult) {
222 if (connectResult.error) {
223 document.getElementById("card-present-alert").innerHTML = '<div class="error clearboth">'+connectResult.error.message+'</div>';
224 console.log('Failed to connect: ', connectResult.error);
225 } else {
226 document.getElementById("card-present-alert").innerHTML = '';
227 console.log('Connected to reader: ', connectResult.reader.label);
228 if (document.getElementById("StripeTerminal")) {
229 document.getElementById("StripeTerminal").innerHTML = '<button type="button" class="calcbutton2" onclick="ValidateStripeTerminal();"><span class="fa fa-2x fa-credit-card iconwithlabel"></span><br>'+connectResult.reader.label+'</button>';
230 }
231 }
232 });
233
234 <?php }
235} ?>
236</script>
237<?php
238
239// Define list of possible payments
240$arrayOfValidPaymentModes = array();
241$arrayOfValidBankAccount = array();
242
243$sql = "SELECT code, libelle as label FROM ".MAIN_DB_PREFIX."c_paiement";
244$sql .= " WHERE entity IN (".getEntity('c_paiement').")";
245$sql .= " AND active = 1";
246if (isALNERunningVersion() && $mysoc->country_code == 'FR') {
247 // In certified version, we can use only 3 payments modes in POS because
248 // the cash control feature support only this 3 payment modes
249 $sql .= " AND code IN ('LIQ', 'CB', 'CHQ')";
250}
251$sql .= " ORDER BY libelle";
252$resql = $db->query($sql);
253
254if ($resql) {
255 while ($obj = $db->fetch_object($resql)) {
256 $paycode = $obj->code;
257 if ($paycode == 'LIQ') {
258 $paycode = 'CASH';
259 }
260 if ($paycode == 'CB') {
261 $paycode = 'CB';
262 }
263 if ($paycode == 'CHQ') {
264 $paycode = 'CHEQUE';
265 }
266
267 $accountname = "CASHDESK_ID_BANKACCOUNT_".$paycode.$_SESSION["takeposterminal"];
268 if (getDolGlobalInt($accountname) > 0) {
269 $arrayOfValidBankAccount[getDolGlobalInt($accountname)] = getDolGlobalInt($accountname);
270 $arrayOfValidPaymentModes[] = $obj;
271 }
272 if (!isModEnabled('bank')) {
273 if ($paycode == 'CASH' || $paycode == 'CB') {
274 $arrayOfValidPaymentModes[] = $obj;
275 }
276 }
277 }
278}
279
280?>
281
282<script>
283<?php
284$remaintopay = 0;
285if ($invoice->id > 0) {
286 $remaintopay = $invoice->getRemainToPay();
287}
288$alreadypayed = (is_object($invoice) ? ($invoice->total_ttc - $remaintopay) : 0);
289
290if (!getDolGlobalInt("TAKEPOS_NUMPAD")) {
291 print "var received='';";
292} else {
293 print "var received=0;";
294}
295
296?>
297 var alreadypayed = <?php echo $alreadypayed ?>;
298
299 function addreceived(price)
300 {
301 <?php
302 if (!getDolGlobalInt("TAKEPOS_NUMPAD")) {
303 print 'received+=String(price);'."\n";
304 } else {
305 print 'received+=parseFloat(price);'."\n";
306 }
307 ?>
308 $('.change1').html(pricejs(parseFloat(received), 'MT'));
309 $('.change1').val(parseFloat(received));
310 console.log(alreadypayed);
311 console.log(received);
312 alreadypaydplusreceived = price2numjs(alreadypayed + parseFloat(received));
313 //console.log("already+received = "+alreadypaydplusreceived);
314 //console.log("total_ttc = "+<?php echo (float) $invoice->total_ttc; ?>);
315 if (alreadypaydplusreceived > <?php echo (float) $invoice->total_ttc; ?>)
316 {
317 var change=parseFloat(alreadypayed + parseFloat(received) - <?php echo (float) $invoice->total_ttc; ?>);
318 $('.change2').html(pricejs(change, 'MT'));
319 $('.change2').val(change);
320 $('.change1').removeClass('colorred');
321 $('.change1').addClass('colorgreen');
322 $('.change2').removeClass('colorwhite');
323 $('.change2').addClass('colorred');
324 }
325 else
326 {
327 $('.change2').html(pricejs(0, 'MT'));
328 $('.change2').val(0);
329 if (alreadypaydplusreceived == <?php echo (float) $invoice->total_ttc; ?>) {
330 $('.change1').removeClass('colorred');
331 $('.change1').addClass('colorgreen');
332 $('.change2').removeClass('colorred');
333 $('.change2').addClass('colorwhite');
334 } else {
335 $('.change1').removeClass('colorgreen');
336 $('.change1').addClass('colorred');
337 $('.change2').removeClass('colorred');
338 $('.change2').addClass('colorwhite');
339 }
340 }
341
342 return true;
343 }
344
345 function reset()
346 {
347 received=0;
348 $('.change1').html(pricejs(received, 'MT'));
349 $('.change1').val(price2numjs(received));
350 $('.change2').html(pricejs(received, 'MT'));
351 $('.change2').val(price2numjs(received));
352 $('.change1').removeClass('colorgreen');
353 $('.change1').addClass('colorred');
354 $('.change2').removeClass('colorred');
355 $('.change2').addClass('colorwhite');
356 }
357
358 function Validate(payment)
359 {
360 console.log("Launch Validate");
361
362 var invoiceid = <?php echo($invoiceid > 0 ? $invoiceid : 0); ?>;
363 var accountid = $("#selectaccountid").val();
364 var amountpayed = $("#change1").val();
365 var excess = $("#change2").val();
366 if (amountpayed > <?php echo (float) $invoice->total_ttc; ?>) {
367 amountpayed = <?php echo (float) $invoice->total_ttc; ?>;
368 }
369 console.log("We click on the payment mode to pay amount = "+amountpayed);
370 parent.$("#poslines").load("invoice.php?place=<?php echo $place; ?>&action=valid&token=<?php echo newToken(); ?>&pay="+payment+"&amount="+amountpayed+"&excess="+excess+"&invoiceid="+invoiceid+"&accountid="+accountid, function() {
371 if (amountpayed > <?php echo (float) $remaintopay; ?> || amountpayed == <?php echo (float) $remaintopay; ?> || amountpayed == 0 ) {
372 console.log("Close popup");
373 parent.$('#invoiceid').val("");
374 parent.$.colorbox.close();
375 } else {
376 console.log("Amount is not complete, so we do NOT close popup and reload it.");
377 location.reload();
378 }
379 });
380
381 return true;
382 }
383
384 function fetchPaymentIntentClientSecret(amount, invoiceid) {
385 const bodyContent = JSON.stringify({ amount : amount, invoiceid : invoiceid });
386 <?php
387 $urlpaymentintent = DOL_URL_ROOT.'/stripe/ajax/ajax.php?action=createPaymentIntent&token='.newToken().'&servicestatus='.urlencode((string) $servicestatus);
388 if (!empty($stripeacc)) {
389 $urlpaymentintent .= '&stripeacc='.$stripeacc;
390 }
391 ?>
392 return fetch('<?php echo $urlpaymentintent; ?>', {
393 method: "POST",
394 headers: {
395 'Content-Type': 'application/json'
396 },
397 body: bodyContent
398 })
399 .then(function(response) {
400 return response.json();
401 })
402 .then(function(data) {
403 return data.client_secret;
404 });
405 }
406
407
408 function capturePaymentIntent(paymentIntentId) {
409 const bodyContent = JSON.stringify({"id": paymentIntentId})
410 <?php
411 $urlpaymentintent = DOL_URL_ROOT.'/stripe/ajax/ajax.php?action=capturePaymentIntent&token='.newToken().'&servicestatus='.urlencode((string) ($servicestatus));
412 if (!empty($stripeacc)) {
413 $urlpaymentintent .= '&stripeacc='.urlencode($stripeacc);
414 }
415 ?>
416 return fetch('<?php echo $urlpaymentintent; ?>', {
417 method: "POST",
418 headers: {
419 'Content-Type': 'application/json'
420 },
421 body: bodyContent
422 })
423 .then(function(response) {
424 return response.json();
425 })
426 .then(function(data) {
427 return data.client_secret;
428 });
429 }
430
431
432 function ValidateStripeTerminal() {
433 console.log("Launch ValidateStripeTerminal");
434 var invoiceid = <?php echo($invoiceid > 0 ? $invoiceid : 0); ?>;
435 var accountid = $("#selectaccountid").val();
436 var amountpayed = $("#change1").val();
437 var excess = $("#change2").val();
438 if (amountpayed > <?php echo (float) $invoice->getRemainToPay(); ?>) {
439 amountpayed = <?php echo (float) $invoice->getRemainToPay(); ?>;
440 }
441 if (amountpayed == 0) {
442 amountpayed = <?php echo (float) $invoice->getRemainToPay(); ?>;
443 }
444
445 console.log("Pay with terminal ", amountpayed);
446
447 fetchPaymentIntentClientSecret(amountpayed, invoiceid).then(function(client_secret) {
448 <?php if (empty($servicestatus) && getDolGlobalString('STRIPE_TERMINAL_SIMULATED')) { ?>
449 terminal.setSimulatorConfiguration({testCardNumber: '<?php echo dol_escape_js(getDolGlobalString('STRIPE_TERMINAL_SIMULATED')); ?>'});
450 <?php } ?>
451 document.getElementById("card-present-alert").innerHTML = '<div class="warning clearboth"><?php echo $langs->trans('PaymentSendToStripeTerminal'); ?></div>';
452 terminal.collectPaymentMethod(client_secret).then(function(result) {
453 if (result.error) {
454 // Placeholder for handling result.error
455 document.getElementById("card-present-alert").innerHTML = '<div class="error clearboth">'+result.error.message+'</div>';
456 } else {
457 document.getElementById("card-present-alert").innerHTML = '<div class="warning clearboth"><?php echo $langs->trans('PaymentBeingProcessed'); ?></div>';
458 console.log('terminal.collectPaymentMethod', result.paymentIntent);
459 terminal.processPayment(result.paymentIntent).then(function(result) {
460 if (result.error) {
461 document.getElementById("card-present-alert").innerHTML = '<div class="error clearboth">'+result.error.message+'</div>';
462 console.log(result.error)
463 } else if (result.paymentIntent) {
464 paymentIntentId = result.paymentIntent.id;
465 console.log('terminal.processPayment', result.paymentIntent);
466 capturePaymentIntent(paymentIntentId).then(function(client_secret) {
467 if (result.error) {
468 // Placeholder for handling result.error
469 document.getElementById("card-present-alert").innerHTML = '<div class="error clearboth">'+result.error.message+'</div>';
470 console.log("error when capturing paymentIntent", result.error);
471 } else {
472 document.getElementById("card-present-alert").innerHTML = '<div class="warning clearboth"><?php echo $langs->trans('PaymentValidated'); ?></div>';
473 console.log("Capture paymentIntent successful "+paymentIntentId);
474 parent.$("#poslines").load("invoice.php?place=<?php echo $place; ?>&action=valid&token=<?php echo newToken(); ?>&pay=CB&amount="+amountpayed+"&excess="+excess+"&invoiceid="+invoiceid+"&accountid="+accountid, function() {
475 if (amountpayed > <?php echo (float) $remaintopay; ?> || amountpayed == <?php echo (float) $remaintopay; ?> || amountpayed == 0 ) {
476 console.log("Close popup");
477 parent.$.colorbox.close();
478 }
479 else {
480 console.log("Amount is not comple, so we do NOT close popup and reload it.");
481 location.reload();
482 }
483 });
484
485 }
486 });
487 }
488 });
489 }
490 });
491 });
492 }
493
494 function ValidateSumup() {
495 console.log("Launch ValidateSumup");
496 <?php $_SESSION['SMP_CURRENT_PAYMENT'] = "NEW" ?>
497 var invoiceid = <?php echo ($invoiceid > 0 ? $invoiceid : 0); ?>;
498 var amountpayed = $("#change1").val();
499 if (amountpayed > <?php echo (float) $invoice->total_ttc; ?>) {
500 amountpayed = <?php echo (float) $invoice->total_ttc; ?>;
501 }
502 if (amountpayed == 0) {
503 amountpayed = <?php echo (float) $invoice->total_ttc; ?>;
504 }
505 var currencycode = "<?php echo $invoice->multicurrency_code; ?>";
506
507 // Starting sumup app
508 window.open('sumupmerchant://pay/1.0?affiliate-key=<?php echo urlencode(getDolGlobalString('TAKEPOS_SUMUP_AFFILIATE')) ?>&app-id=<?php echo urlencode(getDolGlobalString('TAKEPOS_SUMUP_APPID')) ?>&amount=' + amountpayed + '&currency=' + currencycode + '&title=' + invoiceid + '&callback=<?php echo DOL_MAIN_URL_ROOT ?>/takepos/smpcb.php');
509
510 var loop = window.setInterval(function () {
511 $.ajax({
512 method: 'POST',
513 data: { token: '<?php echo currentToken(); ?>' },
514 url: '<?php echo DOL_URL_ROOT ?>/takepos/smpcb.php?status' }).done(function (data) {
515 console.log(data);
516 if (data === "SUCCESS") {
517 parent.$("#poslines").load("invoice.php?place=<?php echo urlencode($place); ?>&action=valid&token=<?php echo newToken(); ?>&pay=CB&amount=" + amountpayed + "&invoiceid=" + invoiceid, function () {
518 //parent.$("#poslines").scrollTop(parent.$("#poslines")[0].scrollHeight);
519 parent.$.colorbox.close();
520 //parent.setFocusOnSearchField(); // This does not have effect
521 });
522 clearInterval(loop);
523 } else if (data === "FAILED") {
524 parent.$.colorbox.close();
525 clearInterval(loop);
526 }
527 });
528 }, 2500);
529 }
530
531<?php
532if (getDolGlobalString('TAKEPOS_CUSTOMER_DISPLAY')) {
533 echo "var line1='".$langs->trans('TotalTTC')."'.substring(0,20);";
534 echo "line1=line1.padEnd(20);";
535 echo "var line2='".price($invoice->total_ttc, 1, '', 1, -1, -1)."'.substring(0,20);";
536 echo "line2=line2.padEnd(20);";
537 echo "$.ajax({
538 type: 'GET',
539 data: { text: line1+line2 },
540 url: '".getDolGlobalString('TAKEPOS_PRINT_SERVER')."/display/index.php',
541 });";
542}
543?>
544</script>
545
546<?php
547$sessioncurrency = $_SESSION["takeposcustomercurrency"] ?? '';
548print '<!-- conf->currency = '.$conf->currency.' - sessioncurrency = '.$sessioncurrency.' -->'."\n";
549$multicurrency = null;
550if (isModEnabled('multicurrency') && $sessioncurrency != "" && $conf->currency != $sessioncurrency) {
551 // Only show customer currency if multicurrency module is enabled, if currency selected and if this currency selected is not the same as main currency
552 include_once DOL_DOCUMENT_ROOT . '/multicurrency/class/multicurrency.class.php';
553 $multicurrency = new MultiCurrency($db);
554 $multicurrency->fetch(0, $sessioncurrency);
555}
556?>
557
558<div style="position:relative; padding-top: 20px; left:5%; height:140px; width:90%;">
559 <div class="paymentbordline paymentbordlinetotal center">
560 <span class="takepospay colorwhite"><?php echo $langs->trans('TotalTTC'); ?>: <span id="totaldisplay" class="colorwhite"><?php
561 echo price($invoice->total_ttc, 1, '', 1, -1, -1, $conf->currency);
562 if ($multicurrency !== null) {
563 print ' &nbsp; <span id="linecolht-span-total opacitymedium" style="font-size:0.9em; font-style:italic;">(' . price($invoice->total_ht * $multicurrency->rate->rate) . ' ' . $sessioncurrency . ')</span>';
564 }
565 ?></span></span>
566 </div>
567 <?php if ($remaintopay != $invoice->total_ttc) { ?>
568 <div class="paymentbordline paymentbordlineremain center">
569 <span class="takepospay colorwhite"><?php echo $langs->trans('RemainToPay'); ?>: <span id="remaintopaydisplay" class="colorwhite"><?php
570 echo price($remaintopay, 1, '', 1, -1, -1, $conf->currency);
571 if ($multicurrency !== null) {
572 print ' &nbsp; <span id="linecolht-span-total opacitymedium" style="font-size:0.9em; font-style:italic;">(' . price($remaintopay * $multicurrency->rate->rate) . ' ' . $sessioncurrency . ')</span>';
573 }
574 ?></span></span>
575 </div>
576 <?php } ?>
577 <div class="paymentbordline paymentbordlinereceived center">
578 <span class="takepospay colorwhite"><?php echo $langs->trans("Received"); ?>: <span class="change1 colorred"><?php
579 echo price(0, 1, '', 1, -1, -1, $conf->currency);
580 if ($multicurrency !== null) {
581 print ' &nbsp; <span id="linecolht-span-total opacitymedium" style="font-size:0.9em; font-style:italic;">(' . price(0 * $multicurrency->rate->rate) . ' ' . $sessioncurrency . ')</span>';
582 }
583 ?></span><input type="hidden" id="change1" class="change1" value="0"></span>
584 </div>
585 <div class="paymentbordline paymentbordlinechange center">
586 <span class="takepospay colorwhite"><?php echo $langs->trans("Change"); ?>: <span class="change2 colorwhite"><?php
587 echo price(0, 1, '', 1, -1, -1, $conf->currency);
588 if ($multicurrency !== null) {
589 print ' &nbsp; <span id="linecolht-span-total opacitymedium" style="font-size:0.9em; font-style:italic;">(' . price(0 * $multicurrency->rate->rate) . ' ' . $sessioncurrency . ')</span>';
590 }
591 ?></span><input type="hidden" id="change2" class="change2" value="0"></span>
592 </div>
593 <?php
594 if (getDolGlobalString('TAKEPOS_CAN_FORCE_BANK_ACCOUNT_DURING_PAYMENT')) {
595 require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
596 print '<div class="paymentbordline paddingtop paddingbottom center">';
597 $filter = '';
598 $form = new Form($db);
599 print '<span class="takepospay colorwhite">'.$langs->trans("BankAccount").': </span>';
600 $form->select_comptes(0, 'accountid', 0, $filter, 1, '');
601 print ajax_combobox('selectaccountid');
602 print '</div>';
603 }
604 ?>
605</div>
606<div style="position:absolute; left:5%; height:52%; width:90%;">
607<?php
608$action_buttons = array(
609array(
610"function" => "reset()",
611"span" => "style='font-size: 150%;'",
612"text" => "C",
613"class" => "poscolorblue"
614),
615array(
616"function" => "parent.$.colorbox.close();",
617"span" => "id='printtext' style='font-weight: bold; font-size: 18pt;'",
618"text" => "X",
619"class" => "poscolordelete"
620),
621);
622$numpad = getDolGlobalInt('TAKEPOS_NUMPAD');
623if (isModEnabled('stripe') && isset($keyforstripeterminalbank) && getDolGlobalString('STRIPE_CARD_PRESENT')) {
624 print '<span id="card-present-alert">';
625 dol_htmloutput_mesg($langs->trans('ConnectingToStripeTerminal', 'Stripe'), [], 'warning', 1);
626 print '</span>';
627}
628print '<button type="button" class="calcbutton" onclick="addreceived('.($numpad == 0 ? '7' : '10').')">'.($numpad == 0 ? '7' : '10').'</button>';
629print '<button type="button" class="calcbutton" onclick="addreceived('.($numpad == 0 ? '8' : '20').')">'.($numpad == 0 ? '8' : '20').'</button>';
630print '<button type="button" class="calcbutton" onclick="addreceived('.($numpad == 0 ? '9' : '50').')">'.($numpad == 0 ? '9' : '50').'</button>';
631?>
632<?php if (count($arrayOfValidPaymentModes) > 0) {
633 $paycode = $arrayOfValidPaymentModes[0]->code;
634 $payIcon = '';
635 if ($paycode == 'LIQ') {
636 if (!isset($conf->global->TAKEPOS_NUMPAD_USE_PAYMENT_ICON) || getDolGlobalString('TAKEPOS_NUMPAD_USE_PAYMENT_ICON')) {
637 $payIcon = 'coins';
638 }
639 } elseif ($paycode == 'CB') {
640 if (!isset($conf->global->TAKEPOS_NUMPAD_USE_PAYMENT_ICON) || getDolGlobalString('TAKEPOS_NUMPAD_USE_PAYMENT_ICON')) {
641 $payIcon = 'credit-card';
642 }
643 } elseif ($paycode == 'CHQ') {
644 if (!isset($conf->global->TAKEPOS_NUMPAD_USE_PAYMENT_ICON) || getDolGlobalString('TAKEPOS_NUMPAD_USE_PAYMENT_ICON')) {
645 $payIcon = 'money-check';
646 }
647 }
648
649 print '<button type="button" class="calcbutton2" onclick="Validate(\''.dol_escape_js($paycode).'\')">'.(!empty($payIcon) ? '<span class="fa fa-2x fa-'.$payIcon.' iconwithlabel"></span><span class="hideonsmartphone"><br>'.$langs->trans("PaymentTypeShort".$arrayOfValidPaymentModes[0]->code) : $langs->trans("PaymentTypeShort".$arrayOfValidPaymentModes[0]->code)).'</span></button>';
650} else {
651 print '<button type="button" class="calcbutton2">'.$langs->trans("NoPaimementModesDefined").'</button>';
652}
653
654print '<button type="button" class="calcbutton" onclick="addreceived('.($numpad == 0 ? '4' : '1').')">'.($numpad == 0 ? '4' : '1').'</button>';
655print '<button type="button" class="calcbutton" onclick="addreceived('.($numpad == 0 ? '5' : '2').')">'.($numpad == 0 ? '5' : '2').'</button>';
656print '<button type="button" class="calcbutton" onclick="addreceived('.($numpad == 0 ? '6' : '5').')">'.($numpad == 0 ? '6' : '5').'</button>';
657?>
658<?php if (count($arrayOfValidPaymentModes) > 1) {
659 $paycode = $arrayOfValidPaymentModes[1]->code;
660 $payIcon = '';
661 if ($paycode == 'LIQ') {
662 if (!isset($conf->global->TAKEPOS_NUMPAD_USE_PAYMENT_ICON) || getDolGlobalString('TAKEPOS_NUMPAD_USE_PAYMENT_ICON')) {
663 $payIcon = 'coins';
664 }
665 } elseif ($paycode == 'CB') {
666 if (!isset($conf->global->TAKEPOS_NUMPAD_USE_PAYMENT_ICON) || getDolGlobalString('TAKEPOS_NUMPAD_USE_PAYMENT_ICON')) {
667 $payIcon = 'credit-card';
668 }
669 } elseif ($paycode == 'CHQ') {
670 if (!isset($conf->global->TAKEPOS_NUMPAD_USE_PAYMENT_ICON) || getDolGlobalString('TAKEPOS_NUMPAD_USE_PAYMENT_ICON')) {
671 $payIcon = 'money-check';
672 }
673 }
674
675 print '<button type="button" class="calcbutton2" onclick="Validate(\''.dol_escape_js($paycode).'\')">'.(!empty($payIcon) ? '<span class="fa fa-2x fa-'.$payIcon.' iconwithlabel"></span><br> '.$langs->trans("PaymentTypeShort".$arrayOfValidPaymentModes[1]->code) : $langs->trans("PaymentTypeShort".$arrayOfValidPaymentModes[1]->code)).'</button>';
676} else {
677 $button = array_pop($action_buttons);
678 print '<button type="button" class="calcbutton2" onclick="'.$button["function"].'"><span '.$button["span"].'>'.$button["text"].'</span></button>';
679}
680
681print '<button type="button" class="calcbutton" onclick="addreceived('.($numpad == 0 ? '1' : '0.10').')">'.($numpad == 0 ? '1' : '0.10').'</button>';
682print '<button type="button" class="calcbutton" onclick="addreceived('.($numpad == 0 ? '2' : '0.20').')">'.($numpad == 0 ? '2' : '0.20').'</button>';
683print '<button type="button" class="calcbutton" onclick="addreceived('.($numpad == 0 ? '3' : '0.50').')">'.($numpad == 0 ? '3' : '0.50').'</button>';
684?>
685<?php if (count($arrayOfValidPaymentModes) > 2) {
686 $paycode = $arrayOfValidPaymentModes[2]->code;
687 $payIcon = '';
688 if ($paycode == 'LIQ') {
689 if (!isset($conf->global->TAKEPOS_NUMPAD_USE_PAYMENT_ICON) || getDolGlobalString('TAKEPOS_NUMPAD_USE_PAYMENT_ICON')) {
690 $payIcon = 'coins';
691 }
692 } elseif ($paycode == 'CB') {
693 if (!isset($conf->global->TAKEPOS_NUMPAD_USE_PAYMENT_ICON) || getDolGlobalString('TAKEPOS_NUMPAD_USE_PAYMENT_ICON')) {
694 $payIcon = 'credit-card';
695 }
696 } elseif ($paycode == 'CHQ') {
697 if (!isset($conf->global->TAKEPOS_NUMPAD_USE_PAYMENT_ICON) || getDolGlobalString('TAKEPOS_NUMPAD_USE_PAYMENT_ICON')) {
698 $payIcon = 'money-check';
699 }
700 }
701
702 print '<button type="button" class="calcbutton2" onclick="Validate(\''.dol_escape_js($paycode).'\')">'.(!empty($payIcon) ? '<span class="fa fa-2x fa-'.$payIcon.' iconwithlabel"></span><br>'.$langs->trans("PaymentTypeShort".$arrayOfValidPaymentModes[2]->code) : $langs->trans("PaymentTypeShort".$arrayOfValidPaymentModes[2]->code)).'</button>';
703} else {
704 $button = array_pop($action_buttons);
705 print '<button type="button" class="calcbutton2" onclick="'.$button["function"].'"><span '.$button["span"].'>'.$button["text"].'</span></button>';
706}
707
708print '<button type="button" class="calcbutton" onclick="addreceived('.($numpad == 0 ? '0' : '0.01').')">'.($numpad == 0 ? '0' : '0.01').'</button>';
709print '<button type="button" class="calcbutton" onclick="addreceived('.($numpad == 0 ? '\'000\'' : '0.02').')">'.($numpad == 0 ? '000' : '0.02').'</button>';
710print '<button type="button" class="calcbutton" onclick="addreceived('.($numpad == 0 ? '\'.\'' : '0.05').')">'.($numpad == 0 ? '.' : '0.05').'</button>';
711
712$i = 3;
713while ($i < count($arrayOfValidPaymentModes)) {
714 $paycode = $arrayOfValidPaymentModes[$i]->code;
715 $payIcon = '';
716 if ($paycode == 'LIQ') {
717 if (!isset($conf->global->TAKEPOS_NUMPAD_USE_PAYMENT_ICON) || getDolGlobalString('TAKEPOS_NUMPAD_USE_PAYMENT_ICON')) {
718 $payIcon = 'coins';
719 }
720 } elseif ($paycode == 'CB') {
721 if (!isset($conf->global->TAKEPOS_NUMPAD_USE_PAYMENT_ICON) || getDolGlobalString('TAKEPOS_NUMPAD_USE_PAYMENT_ICON')) {
722 $payIcon = 'credit-card';
723 }
724 } elseif ($paycode == 'CHQ') {
725 if (!isset($conf->global->TAKEPOS_NUMPAD_USE_PAYMENT_ICON) || getDolGlobalString('TAKEPOS_NUMPAD_USE_PAYMENT_ICON')) {
726 $payIcon = 'money-check';
727 }
728 }
729
730 print '<button type="button" class="calcbutton2" onclick="Validate(\''.dol_escape_js($paycode).'\')">'.(!empty($payIcon) ? '<span class="fa fa-2x fa-'.$payIcon.' iconwithlabel"></span><br>'.$langs->trans("PaymentTypeShort".$arrayOfValidPaymentModes[$i]->code) : $langs->trans("PaymentTypeShort".$arrayOfValidPaymentModes[$i]->code)).'</button>';
731 $i += 1;
732}
733
734if (isModEnabled('stripe') && isset($keyforstripeterminalbank) && getDolGlobalString('STRIPE_CARD_PRESENT')) {
735 $keyforstripeterminalbank = "CASHDESK_ID_BANKACCOUNT_STRIPETERMINAL".$_SESSION["takeposterminal"];
736 print '<span id="StripeTerminal"></span>';
737 if (getDolGlobalString((string) $keyforstripeterminalbank)) {
738 // Nothing
739 } else {
740 $langs->loadLangs(array("errors", "admin"));
741 //print '<button type="button" class="calcbutton2 disabled" title="'.$langs->trans("SetupNotComplete").'">TerminalOff</button>';
742 }
743}
744
745$keyforsumupbank = "CASHDESK_ID_BANKACCOUNT_SUMUP".$_SESSION["takeposterminal"];
746if (getDolGlobalInt("TAKEPOS_ENABLE_SUMUP")) {
747 if (getDolGlobalString($keyforsumupbank)) {
748 print '<button type="button" class="calcbutton2" onclick="ValidateSumup();">Sumup</button>';
749 } else {
750 $langs->loadLangs(array("errors", "admin"));
751 print '<button type="button" class="calcbutton2 disabled" title="'.$langs->trans("SetupNotComplete").'">Sumup</button>';
752 }
753}
754
755$parameters = array('action_buttons' => $action_buttons);
756$reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $invoice, $action); // Note that $action and $invoice may have been modified by hook
757if ($reshook < 0) {
758 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
759} elseif ($reshook == 0) {
760 $action_buttons = array_merge($action_buttons, $hookmanager->resArray);
761} elseif ($reshook > 0) {
762 $action_buttons = $hookmanager->resArray;
763}
764
765$class = ($i == 3) ? "calcbutton3" : "calcbutton2";
766foreach ($action_buttons as $button) {
767 $newclass = $class.($button["class"] ? " ".$button["class"] : "");
768 print '<button type="button" class="'.$newclass.'" onclick="'.$button["function"].'"><span '.$button["span"].'>'.$button["text"].'</span></button>';
769}
770
771if (getDolGlobalString('TAKEPOS_DELAYED_PAYMENT')) {
772 print '<button type="button" class="calcbutton2" onclick="Validate(\'delayed\')">'.$langs->trans("Reported").'</button>';
773}
774?>
775
776<?php
777// Add code from hooks
778$parameters = array();
779$hookmanager->executeHooks('completePayment', $parameters, $invoice);
780print $hookmanager->resPrint;
781?>
782
783</div>
784
785</body>
786</html>
ajax_combobox($htmlname, $events=array(), $minLengthToAutocomplete=0, $forcefocus=0, $widthTypeOfAutocomplete='resolve', $idforemptyvalue='-1', $morecss='')
Convert a html select field into an ajax combobox.
Definition ajax.lib.php:475
isALNERunningVersion($blockedlogtestalreadydone=0)
Return if the application is executed with the LNE requirements on.
Class to manage invoices.
Class to manage generation of HTML components Only common components must be here.
Class Currency.
Stripe class @TODO No reason to extend CommonObject.
Class toolbox to validate values.
global $mysoc
pricejs(amount, mode='MT', currency_code='', force_locale='')
Function similar to PHP price()
price2numjs(amount)
Function similar to PHP price2num()
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_escape_js($stringtoescape, $mode=0, $noescapebackslashn=0)
Returns text escaped for inclusion into javascript code.
newToken()
Return the value of token currently saved into session with name 'newtoken'.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_htmloutput_mesg($mesgstring='', $mesgarray=array(), $style='ok', $keepembedded=0)
Print formatted messages to output (Used to show messages on html output).
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
multi select button
0 = Do not include form tag and submit button -1 = Do not include form tag but include submit button
a disabled
if(!defined( 'CSRFCHECK_WITH_TOKEN'))
Abort invoice creation with a given error message.
top_htmlhead($head, $title='', $disablejs=0, $disablehead=0, $arrayofjs=array(), $arrayofcss=array(), $disableforlogin=0, $disablenofollow=0, $disablenoindex=0)
Output html header of a page.
if(getDolGlobalString( 'TAKEPOS_SHOW_CUSTOMER')) print $langs trans('Date')." left Label right Qty right Price right TotalHT right TotalTTC right right right right right right right right right centpercent right TotalHT right n right VAT right n right TotalVAT right n No sujeto a RE IRPF right TotalLT1 right n right TotalLT2 right n right TotalTTC right n takeposcustomercurrency takeposcustomercurrency takeposcustomercurrency takeposcustomercurrency right TotalTTC takeposcustomercurrency right takeposcustomercurrency n right PaymentTypeShortLIQ right SELECT p pos_change as p datep as p p num_paiement as f pf amount as amount
Definition receipt.php:466
if(preg_match('/(crypted|dolcrypt):/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
'integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]',...
Definition repair.php:125
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.