dolibarr 24.0.0-beta
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 var invoicetype = <?php echo $invoice->type ?>;
299
300 function addreceived(price)
301 {
302 <?php
303 if (!getDolGlobalInt("TAKEPOS_NUMPAD")) {
304 print 'received+=String(price);'."\n";
305 } else {
306 print 'received+=parseFloat(price);'."\n";
307 }
308 ?>
309 $('.change1').html(pricejs(parseFloat(received), 'MT'));
310 $('.change1').val(parseFloat(received));
311 console.log("invoicetype="+invoicetype);
312 console.log("alreadyreceived="+alreadypayed);
313 console.log("received="+received);
314 if (invoicetype == 2) {
315 alreadypaydplusreceived = price2numjs(alreadypayed - parseFloat(received));
316 } else {
317 alreadypaydplusreceived = price2numjs(alreadypayed + parseFloat(received));
318 }
319 console.log("already+received = "+alreadypaydplusreceived);
320 //console.log("total_ttc = "+<?php echo (float) $invoice->total_ttc; ?>);
321 if (Math.abs(alreadypaydplusreceived) > Math.abs(<?php echo ((float) $invoice->total_ttc); ?>)) {
322 if (invoicetype == 2) {
323 var change = parseFloat(alreadypayed + parseFloat(received) + <?php echo (float) $invoice->total_ttc; ?>);
324 } else {
325 var change = parseFloat(alreadypayed + parseFloat(received) - <?php echo (float) $invoice->total_ttc; ?>);
326 }
327 $('.change2').html(pricejs(change, 'MT'));
328 $('.change2').val(change);
329 $('.change1').removeClass('colorred');
330 $('.change1').addClass('colorgreen');
331 $('.change2').removeClass('colorwhite');
332 $('.change2').addClass('colorred');
333 } else {
334 $('.change2').html(pricejs(0, 'MT'));
335 $('.change2').val(0);
336 if (alreadypaydplusreceived == <?php echo (float) $invoice->total_ttc; ?>) {
337 $('.change1').removeClass('colorred');
338 $('.change1').addClass('colorgreen');
339 $('.change2').removeClass('colorred');
340 $('.change2').addClass('colorwhite');
341 } else {
342 $('.change1').removeClass('colorgreen');
343 $('.change1').addClass('colorred');
344 $('.change2').removeClass('colorred');
345 $('.change2').addClass('colorwhite');
346 }
347 }
348
349 return true;
350 }
351
352 function reset()
353 {
354 received=0;
355 $('.change1').html(pricejs(received, 'MT'));
356 $('.change1').val(price2numjs(received));
357 $('.change2').html(pricejs(received, 'MT'));
358 $('.change2').val(price2numjs(received));
359 $('.change1').removeClass('colorgreen');
360 $('.change1').addClass('colorred');
361 $('.change2').removeClass('colorred');
362 $('.change2').addClass('colorwhite');
363 }
364
365 function Validate(payment)
366 {
367 console.log("Launch Validate");
368
369 var invoiceid = <?php echo($invoiceid > 0 ? $invoiceid : 0); ?>;
370 var accountid = $("#selectaccountid").val();
371 var amountpayed = $("#change1").val();
372 var excess = $("#change2").val();
373 if (amountpayed > <?php echo (float) $invoice->total_ttc; ?>) {
374 amountpayed = <?php echo (float) $invoice->total_ttc; ?>;
375 }
376 console.log("We click on the payment mode to pay amount = "+amountpayed);
377 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() {
378 if (amountpayed > <?php echo (float) $remaintopay; ?> || amountpayed == <?php echo (float) $remaintopay; ?> || amountpayed == 0 ) {
379 console.log("Close popup");
380 parent.$('#invoiceid').val("");
381 parent.$.colorbox.close();
382 } else {
383 console.log("Amount is not complete, so we do NOT close popup and reload it.");
384 location.reload();
385 }
386 });
387
388 return true;
389 }
390
391 function fetchPaymentIntentClientSecret(amount, invoiceid) {
392 const bodyContent = JSON.stringify({ amount : amount, invoiceid : invoiceid });
393 <?php
394 $urlpaymentintent = DOL_URL_ROOT.'/stripe/ajax/ajax.php?action=createPaymentIntent&token='.newToken().'&servicestatus='.urlencode((string) $servicestatus);
395 if (!empty($stripeacc)) {
396 $urlpaymentintent .= '&stripeacc='.$stripeacc;
397 }
398 ?>
399 return fetch('<?php echo $urlpaymentintent; ?>', {
400 method: "POST",
401 headers: {
402 'Content-Type': 'application/json'
403 },
404 body: bodyContent
405 })
406 .then(function(response) {
407 return response.json();
408 })
409 .then(function(data) {
410 return data.client_secret;
411 });
412 }
413
414
415 function capturePaymentIntent(paymentIntentId) {
416 const bodyContent = JSON.stringify({"id": paymentIntentId})
417 <?php
418 $urlpaymentintent = DOL_URL_ROOT.'/stripe/ajax/ajax.php?action=capturePaymentIntent&token='.newToken().'&servicestatus='.urlencode((string) ($servicestatus));
419 if (!empty($stripeacc)) {
420 $urlpaymentintent .= '&stripeacc='.urlencode($stripeacc);
421 }
422 ?>
423 return fetch('<?php echo $urlpaymentintent; ?>', {
424 method: "POST",
425 headers: {
426 'Content-Type': 'application/json'
427 },
428 body: bodyContent
429 })
430 .then(function(response) {
431 return response.json();
432 })
433 .then(function(data) {
434 return data.client_secret;
435 });
436 }
437
438
439 function ValidateStripeTerminal() {
440 console.log("Launch ValidateStripeTerminal");
441 var invoiceid = <?php echo($invoiceid > 0 ? $invoiceid : 0); ?>;
442 var accountid = $("#selectaccountid").val();
443 var amountpayed = $("#change1").val();
444 var excess = $("#change2").val();
445 if (amountpayed > <?php echo (float) $invoice->getRemainToPay(); ?>) {
446 amountpayed = <?php echo (float) $invoice->getRemainToPay(); ?>;
447 }
448 if (amountpayed == 0) {
449 amountpayed = <?php echo (float) $invoice->getRemainToPay(); ?>;
450 }
451
452 console.log("Pay with terminal ", amountpayed);
453
454 fetchPaymentIntentClientSecret(amountpayed, invoiceid).then(function(client_secret) {
455 <?php if (empty($servicestatus) && getDolGlobalString('STRIPE_TERMINAL_SIMULATED')) { ?>
456 terminal.setSimulatorConfiguration({testCardNumber: '<?php echo dol_escape_js(getDolGlobalString('STRIPE_TERMINAL_SIMULATED')); ?>'});
457 <?php } ?>
458 document.getElementById("card-present-alert").innerHTML = '<div class="warning clearboth"><?php echo $langs->trans('PaymentSendToStripeTerminal'); ?></div>';
459 terminal.collectPaymentMethod(client_secret).then(function(result) {
460 if (result.error) {
461 // Placeholder for handling result.error
462 document.getElementById("card-present-alert").innerHTML = '<div class="error clearboth">'+result.error.message+'</div>';
463 } else {
464 document.getElementById("card-present-alert").innerHTML = '<div class="warning clearboth"><?php echo $langs->trans('PaymentBeingProcessed'); ?></div>';
465 console.log('terminal.collectPaymentMethod', result.paymentIntent);
466 terminal.processPayment(result.paymentIntent).then(function(result) {
467 if (result.error) {
468 document.getElementById("card-present-alert").innerHTML = '<div class="error clearboth">'+result.error.message+'</div>';
469 console.log(result.error)
470 } else if (result.paymentIntent) {
471 paymentIntentId = result.paymentIntent.id;
472 console.log('terminal.processPayment', result.paymentIntent);
473 capturePaymentIntent(paymentIntentId).then(function(client_secret) {
474 if (result.error) {
475 // Placeholder for handling result.error
476 document.getElementById("card-present-alert").innerHTML = '<div class="error clearboth">'+result.error.message+'</div>';
477 console.log("error when capturing paymentIntent", result.error);
478 } else {
479 document.getElementById("card-present-alert").innerHTML = '<div class="warning clearboth"><?php echo $langs->trans('PaymentValidated'); ?></div>';
480 console.log("Capture paymentIntent successful "+paymentIntentId);
481 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() {
482 if (amountpayed > <?php echo (float) $remaintopay; ?> || amountpayed == <?php echo (float) $remaintopay; ?> || amountpayed == 0 ) {
483 console.log("Close popup");
484 parent.$.colorbox.close();
485 }
486 else {
487 console.log("Amount is not comple, so we do NOT close popup and reload it.");
488 location.reload();
489 }
490 });
491
492 }
493 });
494 }
495 });
496 }
497 });
498 });
499 }
500
501 function ValidateSumup() {
502 console.log("Launch ValidateSumup");
503 <?php $_SESSION['SMP_CURRENT_PAYMENT'] = "NEW" ?>
504 var invoiceid = <?php echo ($invoiceid > 0 ? $invoiceid : 0); ?>;
505 var amountpayed = $("#change1").val();
506 if (amountpayed > <?php echo (float) $invoice->total_ttc; ?>) {
507 amountpayed = <?php echo (float) $invoice->total_ttc; ?>;
508 }
509 if (amountpayed == 0) {
510 amountpayed = <?php echo (float) $invoice->total_ttc; ?>;
511 }
512 var currencycode = "<?php echo $invoice->multicurrency_code; ?>";
513
514 // Starting sumup app
515 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');
516
517 var loop = window.setInterval(function () {
518 $.ajax({
519 method: 'POST',
520 data: { token: '<?php echo currentToken(); ?>' },
521 url: '<?php echo DOL_URL_ROOT ?>/takepos/smpcb.php?status' }).done(function (data) {
522 console.log(data);
523 if (data === "SUCCESS") {
524 parent.$("#poslines").load("invoice.php?place=<?php echo urlencode($place); ?>&action=valid&token=<?php echo newToken(); ?>&pay=CB&amount=" + amountpayed + "&invoiceid=" + invoiceid, function () {
525 //parent.$("#poslines").scrollTop(parent.$("#poslines")[0].scrollHeight);
526 parent.$.colorbox.close();
527 //parent.setFocusOnSearchField(); // This does not have effect
528 });
529 clearInterval(loop);
530 } else if (data === "FAILED") {
531 parent.$.colorbox.close();
532 clearInterval(loop);
533 }
534 });
535 }, 2500);
536 }
537
538<?php
539if (getDolGlobalString('TAKEPOS_CUSTOMER_DISPLAY')) {
540 echo "var line1='".$langs->trans('TotalTTC')."'.substring(0,20);";
541 echo "line1=line1.padEnd(20);";
542 echo "var line2='".price($invoice->total_ttc, 1, '', 1, -1, -1)."'.substring(0,20);";
543 echo "line2=line2.padEnd(20);";
544 if (getDolGlobalString('TAKEPOS_CONNECTOR_TO_WHB_CUSTOMER_DISPLAY')) {
545 echo 'webSocketCustomerDisplay.onOpen(function() {';
546 echo ' webSocketCustomerDisplay.send(line1);';
547 echo ' webSocketCustomerDisplay.send(line2);';
548 echo '});';
549 } else {
550 echo "$.ajax({
551 type: 'GET',
552 data: { text: line1+line2 },
553 url: '".getDolGlobalString('TAKEPOS_PRINT_SERVER')."/display/index.php',
554 });";
555 }
556}
557?>
558</script>
559
560<?php
561$sessioncurrency = $_SESSION["takeposcustomercurrency"] ?? '';
562print '<!-- conf->currency = '.$conf->currency.' - sessioncurrency = '.$sessioncurrency.' -->'."\n";
563$multicurrency = null;
564if (isModEnabled('multicurrency') && $sessioncurrency != "" && $conf->currency != $sessioncurrency) {
565 // Only show customer currency if multicurrency module is enabled, if currency selected and if this currency selected is not the same as main currency
566 include_once DOL_DOCUMENT_ROOT . '/multicurrency/class/multicurrency.class.php';
567 $multicurrency = new MultiCurrency($db);
568 $multicurrency->fetch(0, $sessioncurrency);
569}
570?>
571
572<div style="position:relative; padding-top: 20px; left:5%; height:140px; width:90%;">
573 <div class="paymentbordline paymentbordlinetotal center">
574 <span class="takepospay colorwhite"><?php echo $langs->trans('TotalTTC'); ?>: <span id="totaldisplay" class="colorwhite"><?php
575 echo price($invoice->total_ttc, 1, '', 1, -1, -1, $conf->currency);
576 if ($multicurrency !== null) {
577 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>';
578 }
579 ?></span></span>
580 </div>
581 <?php if ($remaintopay != $invoice->total_ttc) { ?>
582 <div class="paymentbordline paymentbordlineremain center">
583 <span class="takepospay colorwhite"><?php echo $langs->trans('RemainToPay'); ?>: <span id="remaintopaydisplay" class="colorwhite"><?php
584 echo price($remaintopay, 1, '', 1, -1, -1, $conf->currency);
585 if ($multicurrency !== null) {
586 print ' &nbsp; <span id="linecolht-span-total opacitymedium" style="font-size:0.9em; font-style:italic;">(' . price($remaintopay * $multicurrency->rate->rate) . ' ' . $sessioncurrency . ')</span>';
587 }
588 ?></span></span>
589 </div>
590 <?php } ?>
591 <div class="paymentbordline paymentbordlinereceived center">
592 <span class="takepospay colorwhite"><?php echo $invoice->type == $invoice::TYPE_CREDIT_NOTE ? $langs->trans("Refunded") : $langs->trans("Received"); ?>: <span class="change1 colorred"><?php
593 echo price(0, 1, '', 1, -1, -1, $conf->currency);
594 if ($multicurrency !== null) {
595 print ' &nbsp; <span id="linecolht-span-total opacitymedium" style="font-size:0.9em; font-style:italic;">(' . price(0 * $multicurrency->rate->rate) . ' ' . $sessioncurrency . ')</span>';
596 }
597 ?></span><input type="hidden" id="change1" class="change1" value="0"></span>
598 </div>
599 <div class="paymentbordline paymentbordlinechange center">
600 <span class="takepospay colorwhite"><?php echo $langs->trans("Change"); ?>: <span class="change2 colorwhite"><?php
601 echo price(0, 1, '', 1, -1, -1, $conf->currency);
602 if ($multicurrency !== null) {
603 print ' &nbsp; <span id="linecolht-span-total opacitymedium" style="font-size:0.9em; font-style:italic;">(' . price(0 * $multicurrency->rate->rate) . ' ' . $sessioncurrency . ')</span>';
604 }
605 ?></span><input type="hidden" id="change2" class="change2" value="0"></span>
606 </div>
607 <?php
608 if (getDolGlobalString('TAKEPOS_CAN_FORCE_BANK_ACCOUNT_DURING_PAYMENT')) {
609 require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
610 print '<div class="paymentbordline paddingtop paddingbottom center">';
611 $filter = '';
612 $form = new Form($db);
613 print '<span class="takepospay colorwhite">'.$langs->trans("BankAccount").': </span>';
614 $form->select_comptes(0, 'accountid', 0, $filter, 1, '');
615 print ajax_combobox('selectaccountid');
616 print '</div>';
617 }
618 ?>
619</div>
620<div style="position:absolute; left:5%; height:52%; width:90%;">
621<?php
622$action_buttons = array(
623array(
624"function" => "reset()",
625"span" => "style='font-size: 150%;'",
626"text" => "C",
627"class" => "poscolorblue"
628),
629array(
630"function" => "parent.$.colorbox.close();",
631"span" => "id='printtext' style='font-weight: bold; font-size: 18pt;'",
632"text" => "X",
633"class" => "poscolordelete"
634),
635);
636$numpad = getDolGlobalInt('TAKEPOS_NUMPAD');
637if (isModEnabled('stripe') && isset($keyforstripeterminalbank) && getDolGlobalString('STRIPE_CARD_PRESENT')) {
638 print '<span id="card-present-alert">';
639 dol_htmloutput_mesg($langs->trans('ConnectingToStripeTerminal', 'Stripe'), [], 'warning', 1);
640 print '</span>';
641}
642print '<button type="button" class="calcbutton" onclick="addreceived('.($numpad == 0 ? '7' : '10').')">'.($numpad == 0 ? '7' : '10').'</button>';
643print '<button type="button" class="calcbutton" onclick="addreceived('.($numpad == 0 ? '8' : '20').')">'.($numpad == 0 ? '8' : '20').'</button>';
644print '<button type="button" class="calcbutton" onclick="addreceived('.($numpad == 0 ? '9' : '50').')">'.($numpad == 0 ? '9' : '50').'</button>';
645?>
646<?php if (count($arrayOfValidPaymentModes) > 0) {
647 $paycode = $arrayOfValidPaymentModes[0]->code;
648 $payIcon = '';
649 if ($paycode == 'LIQ') {
650 if (!isset($conf->global->TAKEPOS_NUMPAD_USE_PAYMENT_ICON) || getDolGlobalString('TAKEPOS_NUMPAD_USE_PAYMENT_ICON')) {
651 $payIcon = 'coins';
652 }
653 } elseif ($paycode == 'CB') {
654 if (!isset($conf->global->TAKEPOS_NUMPAD_USE_PAYMENT_ICON) || getDolGlobalString('TAKEPOS_NUMPAD_USE_PAYMENT_ICON')) {
655 $payIcon = 'credit-card';
656 }
657 } elseif ($paycode == 'CHQ') {
658 if (!isset($conf->global->TAKEPOS_NUMPAD_USE_PAYMENT_ICON) || getDolGlobalString('TAKEPOS_NUMPAD_USE_PAYMENT_ICON')) {
659 $payIcon = 'money-check';
660 }
661 }
662
663 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>';
664} else {
665 print '<button type="button" class="calcbutton2">'.$langs->trans("NoPaimementModesDefined").'</button>';
666}
667
668print '<button type="button" class="calcbutton" onclick="addreceived('.($numpad == 0 ? '4' : '1').')">'.($numpad == 0 ? '4' : '1').'</button>';
669print '<button type="button" class="calcbutton" onclick="addreceived('.($numpad == 0 ? '5' : '2').')">'.($numpad == 0 ? '5' : '2').'</button>';
670print '<button type="button" class="calcbutton" onclick="addreceived('.($numpad == 0 ? '6' : '5').')">'.($numpad == 0 ? '6' : '5').'</button>';
671?>
672<?php if (count($arrayOfValidPaymentModes) > 1) {
673 $paycode = $arrayOfValidPaymentModes[1]->code;
674 $payIcon = '';
675 if ($paycode == 'LIQ') {
676 if (!isset($conf->global->TAKEPOS_NUMPAD_USE_PAYMENT_ICON) || getDolGlobalString('TAKEPOS_NUMPAD_USE_PAYMENT_ICON')) {
677 $payIcon = 'coins';
678 }
679 } elseif ($paycode == 'CB') {
680 if (!isset($conf->global->TAKEPOS_NUMPAD_USE_PAYMENT_ICON) || getDolGlobalString('TAKEPOS_NUMPAD_USE_PAYMENT_ICON')) {
681 $payIcon = 'credit-card';
682 }
683 } elseif ($paycode == 'CHQ') {
684 if (!isset($conf->global->TAKEPOS_NUMPAD_USE_PAYMENT_ICON) || getDolGlobalString('TAKEPOS_NUMPAD_USE_PAYMENT_ICON')) {
685 $payIcon = 'money-check';
686 }
687 }
688
689 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>';
690} else {
691 $button = array_pop($action_buttons);
692 print '<button type="button" class="calcbutton2" onclick="'.$button["function"].'"><span '.$button["span"].'>'.$button["text"].'</span></button>';
693}
694
695print '<button type="button" class="calcbutton" onclick="addreceived('.($numpad == 0 ? '1' : '0.10').')">'.($numpad == 0 ? '1' : '0.10').'</button>';
696print '<button type="button" class="calcbutton" onclick="addreceived('.($numpad == 0 ? '2' : '0.20').')">'.($numpad == 0 ? '2' : '0.20').'</button>';
697print '<button type="button" class="calcbutton" onclick="addreceived('.($numpad == 0 ? '3' : '0.50').')">'.($numpad == 0 ? '3' : '0.50').'</button>';
698?>
699<?php if (count($arrayOfValidPaymentModes) > 2) {
700 $paycode = $arrayOfValidPaymentModes[2]->code;
701 $payIcon = '';
702 if ($paycode == 'LIQ') {
703 if (!isset($conf->global->TAKEPOS_NUMPAD_USE_PAYMENT_ICON) || getDolGlobalString('TAKEPOS_NUMPAD_USE_PAYMENT_ICON')) {
704 $payIcon = 'coins';
705 }
706 } elseif ($paycode == 'CB') {
707 if (!isset($conf->global->TAKEPOS_NUMPAD_USE_PAYMENT_ICON) || getDolGlobalString('TAKEPOS_NUMPAD_USE_PAYMENT_ICON')) {
708 $payIcon = 'credit-card';
709 }
710 } elseif ($paycode == 'CHQ') {
711 if (!isset($conf->global->TAKEPOS_NUMPAD_USE_PAYMENT_ICON) || getDolGlobalString('TAKEPOS_NUMPAD_USE_PAYMENT_ICON')) {
712 $payIcon = 'money-check';
713 }
714 }
715
716 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>';
717} else {
718 $button = array_pop($action_buttons);
719 print '<button type="button" class="calcbutton2" onclick="'.$button["function"].'"><span '.$button["span"].'>'.$button["text"].'</span></button>';
720}
721
722print '<button type="button" class="calcbutton" onclick="addreceived('.($numpad == 0 ? '0' : '0.01').')">'.($numpad == 0 ? '0' : '0.01').'</button>';
723print '<button type="button" class="calcbutton" onclick="addreceived('.($numpad == 0 ? '\'000\'' : '0.02').')">'.($numpad == 0 ? '000' : '0.02').'</button>';
724print '<button type="button" class="calcbutton" onclick="addreceived('.($numpad == 0 ? '\'.\'' : '0.05').')">'.($numpad == 0 ? '.' : '0.05').'</button>';
725
726$i = 3;
727while ($i < count($arrayOfValidPaymentModes)) {
728 $paycode = $arrayOfValidPaymentModes[$i]->code;
729 $payIcon = '';
730 if ($paycode == 'LIQ') {
731 if (!isset($conf->global->TAKEPOS_NUMPAD_USE_PAYMENT_ICON) || getDolGlobalString('TAKEPOS_NUMPAD_USE_PAYMENT_ICON')) {
732 $payIcon = 'coins';
733 }
734 } elseif ($paycode == 'CB') {
735 if (!isset($conf->global->TAKEPOS_NUMPAD_USE_PAYMENT_ICON) || getDolGlobalString('TAKEPOS_NUMPAD_USE_PAYMENT_ICON')) {
736 $payIcon = 'credit-card';
737 }
738 } elseif ($paycode == 'CHQ') {
739 if (!isset($conf->global->TAKEPOS_NUMPAD_USE_PAYMENT_ICON) || getDolGlobalString('TAKEPOS_NUMPAD_USE_PAYMENT_ICON')) {
740 $payIcon = 'money-check';
741 }
742 }
743
744 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>';
745 $i += 1;
746}
747
748if (isModEnabled('stripe') && isset($keyforstripeterminalbank) && getDolGlobalString('STRIPE_CARD_PRESENT')) {
749 $keyforstripeterminalbank = "CASHDESK_ID_BANKACCOUNT_STRIPETERMINAL".$_SESSION["takeposterminal"];
750 print '<span id="StripeTerminal"></span>';
751 if (getDolGlobalString((string) $keyforstripeterminalbank)) {
752 // Nothing
753 } else {
754 $langs->loadLangs(array("errors", "admin"));
755 //print '<button type="button" class="calcbutton2 disabled" title="'.$langs->trans("SetupNotComplete").'">TerminalOff</button>';
756 }
757}
758
759$keyforsumupbank = "CASHDESK_ID_BANKACCOUNT_SUMUP".$_SESSION["takeposterminal"];
760if (getDolGlobalInt("TAKEPOS_ENABLE_SUMUP")) {
761 if (getDolGlobalString($keyforsumupbank)) {
762 print '<button type="button" class="calcbutton2" onclick="ValidateSumup();">Sumup</button>';
763 } else {
764 $langs->loadLangs(array("errors", "admin"));
765 print '<button type="button" class="calcbutton2 disabled" title="'.$langs->trans("SetupNotComplete").'">Sumup</button>';
766 }
767}
768
769$parameters = array('action_buttons' => $action_buttons);
770$reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $invoice, $action); // Note that $action and $invoice may have been modified by hook
771if ($reshook < 0) {
772 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
773} elseif ($reshook == 0) {
774 $action_buttons = array_merge($action_buttons, $hookmanager->resArray);
775} elseif ($reshook > 0) {
776 $action_buttons = $hookmanager->resArray;
777}
778
779$class = ($i == 3) ? "calcbutton3" : "calcbutton2";
780foreach ($action_buttons as $button) {
781 $newclass = $class.($button["class"] ? " ".$button["class"] : "");
782 print '<button type="button" class="'.$newclass.'" onclick="'.$button["function"].'"><span '.$button["span"].'>'.$button["text"].'</span></button>';
783}
784
785if (getDolGlobalString('TAKEPOS_DELAYED_PAYMENT')) {
786 print '<button type="button" class="calcbutton2" onclick="Validate(\'delayed\')">'.$langs->trans("Reported").'</button>';
787}
788?>
789
790<?php
791// Add code from hooks
792$parameters = array();
793$hookmanager->executeHooks('completePayment', $parameters, $invoice);
794print $hookmanager->resPrint;
795?>
796
797</div>
798
799</body>
800</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:476
isALNERunningVersion($blockedlogtestalreadydone=0, $blockedlogmodulealreadydone=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()
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $db
API class for accounts.
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.
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.
print $langs trans('Date')." left Ref 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 Paid right PaymentTypeShortLIQ right SELECT p pos_change as p datep as p p num_paiement as f pf amount as amount
Definition receipt.php:489
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:130
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.