dolibarr 25.0.0-alpha
index.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2018 Andreu Bisquerra <jove@bisquerra.com>
3 * Copyright (C) 2019 Josep Lluís Amador <joseplluis@lliuretic.cat>
4 * Copyright (C) 2020 Thibault FOUCART <support@ptibogxiv.net>
5 * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
6 * Copyright (C) 2024-2025 Frédéric France <frederic.france@free.fr>
7 * Copyright (C) 2026 Jose Martinez <jose.martinez@pichinov.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 */
22
29// if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1'); // Not disabled cause need to load personalized language
30// if (! defined('NOREQUIREDB')) define('NOREQUIREDB','1'); // Not disabled cause need to load personalized language
31// if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1');
32// if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1');
33
34if (!defined('NOREQUIREMENU')) {
35 define('NOREQUIREMENU', '1');
36}
37if (!defined('NOREQUIREHTML')) {
38 define('NOREQUIREHTML', '1');
39}
40if (!defined('NOREQUIREAJAX')) {
41 define('NOREQUIREAJAX', '1');
42}
43
44// Load Dolibarr environment
45require '../main.inc.php'; // Load $user and permissions
54require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
55require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
56require_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
57require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
58require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
59require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
60require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
61
62
63$langs->loadLangs(array("bills", "orders", "commercial", "cashdesk", "receiptprinter", "banks"));
64
65$place = (GETPOST('place', 'aZ09') ? GETPOST('place', 'aZ09') : 0); // $place is id of table for Bar or Restaurant or multiple sales
66$action = GETPOST('action', 'aZ09');
67$setterminal = GETPOSTINT('setterminal');
68$setcurrency = GETPOST('setcurrency', 'aZ09');
69
70$hookmanager->initHooks(array('takeposfrontend'));
71if (empty($_SESSION["takeposterminal"])) {
72 if (getDolGlobalInt('TAKEPOS_NUM_TERMINALS') == 1) {
73 $_SESSION["takeposterminal"] = 1; // Use terminal 1 if there is only 1 terminal
74 } elseif (!empty($_COOKIE["takeposterminal"])) {
75 $_SESSION["takeposterminal"] = preg_replace('/[^a-zA-Z0-9_\-]/', '', $_COOKIE["takeposterminal"]); // Restore takeposterminal from previous session
76 }
77}
78
79if ($setterminal > 0) {
80 $_SESSION["takeposterminal"] = (int) $setterminal;
81 dolSetCookie("takeposterminal", (string) $setterminal, -1); // takeposterminal var in a 1 year cookie
82}
83
84if ($setcurrency != "") {
85 $_SESSION["takeposcustomercurrency"] = $setcurrency;
86 // We will recalculate amount for foreign currency at next call of invoice.php when $_SESSION["takeposcustomercurrency"] differs from invoice->multicurrency_code.
87}
88
89
90$categorie = new Categorie($db);
91
92$maxcategbydefaultforthisdevice = 12;
93$maxproductbydefaultforthisdevice = 24;
94
95$MAXCATEG = getDolGlobalInt('TAKEPOS_NB_MAXCATEG', $maxcategbydefaultforthisdevice);
96$MAXPRODUCT = getDolGlobalInt('TAKEPOS_NB_MAXPRODUCT', $maxproductbydefaultforthisdevice);
97
98$term = empty($_SESSION['takeposterminal']) ? 1 : $_SESSION['takeposterminal'];
99
100$socid = getDolGlobalInt('CASHDESK_ID_THIRDPARTY' . $term);
101
102
103/*
104 $constforcompanyid = 'CASHDESK_ID_THIRDPARTY'.$_SESSION["takeposterminal"];
105 $soc = new Societe($db);
106 if ($invoice->socid > 0) $soc->fetch($invoice->socid);
107 else $soc->fetch(getDolGlobalInt($constforcompanyid));
108 */
109
110// Security check
111$result = restrictedArea($user, 'takepos', 0, '');
112
113
114
115/*
116 * View
117 */
118
119$form = new Form($db);
120
121$disablejs = 0;
122$disablehead = 0;
123$arrayofjs = array('/takepos/js/jquery.colorbox-min.js'); // TODO It seems we don't need this
124$arrayofcss = array('/takepos/css/pos.css.php', '/takepos/css/colorbox.css');
125
126if (getDolGlobalInt('TAKEPOS_COLOR_THEME') == 1) {
127 $arrayofcss[] = '/takepos/css/colorful.css';
128}
129
130
131// Title
132$title = 'TakePOS - Dolibarr '.DOL_VERSION;
133if (getDolGlobalString('MAIN_APPLICATION_TITLE')) {
134 $title = 'TakePOS - ' . getDolGlobalString('MAIN_APPLICATION_TITLE');
135}
136$head = '<meta name="apple-mobile-web-app-title" content="TakePOS"/>
137<meta name="apple-mobile-web-app-capable" content="yes">
138<meta name="mobile-web-app-capable" content="yes">
139<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>';
140
141top_htmlhead($head, $title, $disablejs, $disablehead, $arrayofjs, $arrayofcss);
142
143
144$categories = $categorie->get_full_arbo('product', getDolGlobalInt('TAKEPOS_ROOT_CATEGORY_ID'), 1);
145
146
147// Search root category to know its level
148//$conf->global->TAKEPOS_ROOT_CATEGORY_ID=0;
149$levelofrootcategory = 0;
150if (getDolGlobalInt('TAKEPOS_ROOT_CATEGORY_ID') > 0) {
151 foreach ($categories as $key => $categorycursor) {
152 // @phan-suppress-next-line PhanTypeInvalidDimOffset
153 if ($categorycursor['id'] == getDolGlobalInt('TAKEPOS_ROOT_CATEGORY_ID')) {
154 $levelofrootcategory = $categorycursor['level'];
155 break;
156 }
157 }
158}
159
160$levelofmaincategories = $levelofrootcategory + 1; // Main categories are categories just under the root categorie of POS products.
161
162$maincategories = array();
163$subcategories = array();
164foreach ($categories as $key => $categorycursor) {
165 if ($categorycursor['level'] == $levelofmaincategories) {
166 $maincategories[$key] = $categorycursor;
167 } elseif ($categorycursor['level'] > $levelofmaincategories) {
168 $subcategories[$key] = $categorycursor; // If category level 2 or 3 or ...
169 }
170}
171
172$maincategories = dol_sort_array($maincategories, 'label');
173$subcategories = dol_sort_array($subcategories, 'label');
174?>
175<?php
176$keyCodeForEnter = '';
177if (!empty($_SESSION['takeposterminal'])) {
178 $keyCodeForEnter = getDolGlobalInt('CASHDESK_READER_KEYCODE_FOR_ENTER'.$_SESSION['takeposterminal']) > 0 ? getDolGlobalString('CASHDESK_READER_KEYCODE_FOR_ENTER'.$_SESSION['takeposterminal']) : '';
179}
180?>
181
182<body class="bodytakepos" style="overflow: hidden;">
183
184<script>
185var categories = <?php echo json_encode($maincategories); ?>;
186var subcategories = <?php echo json_encode($subcategories); ?>;
187
188var currentcat;
189var pageproducts=0;
190var pagecategories=0;
191var pageactions=0;
192var place="<?php echo $place; ?>";
193var editaction="qty";
194var editnumber="";
195var invoiceid=0;
196var search2_timer=null;
197
198/*
199var app = this;
200app.hasKeyboard = false;
201this.keyboardPress = function() {
202 app.hasKeyboard = true;
203 $(window).unbind("keyup", app.keyboardPress);
204 localStorage.hasKeyboard = true;
205 console.log("has keyboard!")
206}
207$(window).on("keyup", app.keyboardPress)
208if(localStorage.hasKeyboard) {
209 app.hasKeyboard = true;
210 $(window).unbind("keyup", app.keyboardPress);
211 console.log("has keyboard from localStorage")
212}
213*/
214
215function ClearSearch(clearSearchResults) {
216 console.log("ClearSearch");
217 $("#search").val('');
218 $("#qty").html("<?php echo $langs->trans("Qty"); ?>").removeClass('clicked');
219 $("#price").html("<?php echo $langs->trans("Price"); ?>").removeClass('clicked');
220 $("#reduction").html("<?php echo $langs->trans("LineDiscountShort"); ?>").removeClass('clicked');
221 <?php if ($conf->browser->layout == 'classic') { ?>
222 setFocusOnSearchField();
223 <?php } ?>
224 if (clearSearchResults) {
225 $("#search").trigger('keyup');
226 }
227}
228
229// Set the focus on search field but only on desktop. On tablet or smartphone, we don't to avoid to have the keyboard open automatically
230function setFocusOnSearchField() {
231 console.log("Call setFocusOnSearchField in page index.php");
232 <?php if ($conf->browser->layout == 'classic') { ?>
233 console.log("has keyboard from localStorage, so we can force focus on search field");
234 $("#search").focus();
235 <?php } ?>
236}
237
238function PrintCategories(first) {
239 console.log("PrintCategories");
240 for (i = 0; i < <?php echo($MAXCATEG - 2); ?>; i++) {
241 if (typeof (categories[parseInt(i)+parseInt(first)]) == "undefined")
242 {
243 $("#catdivdesc"+i).hide();
244 $("#catdesc"+i).text("");
245 $("#catimg"+i).attr("src","genimg/empty.png");
246 $("#catwatermark"+i).hide();
247 $("#catdiv"+i).attr('class', 'wrapper divempty');
248 continue;
249 }
250 $("#catdivdesc"+i).show();
251 <?php
252 if (getDolGlobalString('TAKEPOS_SHOW_CATEGORY_DESCRIPTION') == 1) { ?>
253 $("#catdesc"+i).html(categories[parseInt(i)+parseInt(first)]['label'].bold() + ' - ' + categories[parseInt(i)+parseInt(first)]['description']);
254 <?php } else { ?>
255 $("#catdesc"+i).text(categories[parseInt(i)+parseInt(first)]['label']);
256 <?php } ?>
257 $("#catimg"+i).attr("src","genimg/index.php?query=cat&id="+categories[parseInt(i)+parseInt(first)]['rowid']);
258 $("#catdiv"+i).data("rowid",categories[parseInt(i)+parseInt(first)]['rowid']);
259 $("#catdiv"+i).attr("data-rowid",categories[parseInt(i)+parseInt(first)]['rowid']);
260 $("#catdiv"+i).attr('class', 'wrapper');
261 $("#catwatermark"+i).show();
262 }
263}
264
265function MoreCategories(moreorless) {
266 console.log("MoreCategories moreorless="+moreorless+" pagecategories="+pagecategories);
267 if (moreorless == "more") {
268 $('#catimg15').animate({opacity: '0.5'}, 1);
269 $('#catimg15').animate({opacity: '1'}, 100);
270 pagecategories=pagecategories+1;
271 }
272 if (moreorless == "less") {
273 $('#catimg14').animate({opacity: '0.5'}, 1);
274 $('#catimg14').animate({opacity: '1'}, 100);
275 if (pagecategories==0) return; //Return if no less pages
276 pagecategories=pagecategories-1;
277 }
278 if (typeof (categories[<?php echo($MAXCATEG - 2); ?> * pagecategories] && moreorless == "more") == "undefined") { // Return if no more pages
279 pagecategories=pagecategories-1;
280 return;
281 }
282
283 for (i = 0; i < <?php echo($MAXCATEG - 2); ?>; i++) {
284 if (typeof (categories[i+(<?php echo($MAXCATEG - 2); ?> * pagecategories)]) == "undefined") {
285 // complete with empty record
286 console.log("complete with empty record");
287 $("#catdivdesc"+i).hide();
288 $("#catdesc"+i).text("");
289 $("#catimg"+i).attr("src","genimg/empty.png");
290 $("#catwatermark"+i).hide();
291 continue;
292 }
293 $("#catdivdesc"+i).show();
294 <?php
295 if (getDolGlobalString('TAKEPOS_SHOW_CATEGORY_DESCRIPTION') == 1) { ?>
296 $("#catdesc"+i).html(categories[i+(<?php echo($MAXCATEG - 2); ?> * pagecategories)]['label'].bold() + ' - ' + categories[i+(<?php echo($MAXCATEG - 2); ?> * pagecategories)]['description']);
297 <?php } else { ?>
298 $("#catdesc"+i).text(categories[i+(<?php echo($MAXCATEG - 2); ?> * pagecategories)]['label']);
299 <?php } ?>
300 $("#catimg"+i).attr("src","genimg/index.php?query=cat&id="+categories[i+(<?php echo($MAXCATEG - 2); ?> * pagecategories)]['rowid']);
301 $("#catdiv"+i).data("rowid",categories[i+(<?php echo($MAXCATEG - 2); ?> * pagecategories)]['rowid']);
302 $("#catdiv"+i).attr("data-rowid",categories[i+(<?php echo($MAXCATEG - 2); ?> * pagecategories)]['rowid']);
303 $("#catwatermark"+i).show();
304 }
305
306 ClearSearch(false);
307}
308
309// LoadProducts
310function LoadProducts(position, issubcat) {
311 console.log("LoadProducts position="+position+" issubcat="+issubcat);
312 var maxproduct = <?php echo (int) ($MAXPRODUCT - 2); ?>;
313
314 if (position == "supplements") {
315 currentcat = "supplements";
316
317 if (subcategories.count == 0) {
318 alert("No product found into categories level 2 or more");
319 }
320 } else {
321 $('#catimg'+position).animate({opacity: '0.5'}, 1);
322 $('#catimg'+position).animate({opacity: '1'}, 100);
323 if (issubcat == true) {
324 currentcat = $('#prodiv'+position).data('rowid');
325 } else {
326 console.log('#catdiv'+position);
327 currentcat = $('#catdiv'+position).data('rowid');
328 console.log("currentcat="+currentcat);
329 }
330 }
331 if (currentcat == undefined) {
332 return;
333 }
334 pageproducts=0;
335 ishow=0; //product to show counter
336
337 if (currentcat != "supplements") {
338 console.log("Loop on each category level 2 or more");
339 jQuery.each(subcategories, function(i, val) {
340 if (currentcat == val.fk_parent) {
341 $("#prodivdesc"+ishow).show();
342 <?php if (getDolGlobalString('TAKEPOS_SHOW_CATEGORY_DESCRIPTION') == 1) { ?>
343 $("#prodesc"+ishow).html(val.label.bold() + ' - ' + val.description);
344 $("#probutton"+ishow).html(val.label);
345 <?php } else { ?>
346 $("#prodesc"+ishow).text(val.label);
347 $("#probutton"+ishow).text(val.label);
348 <?php } ?>
349 $("#probutton"+ishow).show();
350 $("#proprice"+ishow).attr("class", "hidden");
351 $("#proprice"+ishow).html("");
352 $("#proimg"+ishow).attr("src","genimg/index.php?query=cat&id="+val.rowid);
353 $("#prodiv"+ishow).data("rowid",val.rowid);
354 $("#prodiv"+ishow).attr("data-rowid",val.rowid);
355 $("#prodiv"+ishow).data("iscat", 1);
356 $("#prodiv"+ishow).attr("data-iscat", 1);
357 $("#prodiv"+ishow).removeClass("divempty");
358 $("#prowatermark"+ishow).show();
359 ishow++;
360 }
361 });
362 }
363
364 idata=0; //product data counter
365 var limit = 0;
366 if (maxproduct >= 1) {
367 limit = maxproduct - 1;
368 }
369
370 // Get socid
371 let socid = jQuery('#thirdpartyid').val();
372 if ((socid === undefined || socid === "") && parseInt("<?php echo dol_escape_js($socid) ?>") > 0) {
373 socid = parseInt("<?php echo dol_escape_js($socid); ?>");
374 }
375
376 // Only show products for sale (tosell=1)
377 $.getJSON('<?php echo DOL_URL_ROOT ?>/takepos/ajax/ajax.php?action=getProducts&token=<?php echo currentToken();?>&thirdpartyid=' + socid + '&category='+currentcat+'&tosell=1&limit='+limit+'&offset=0', function(data) {
378 /* Fill thumbs from ishow to end max of products with products loaded into data array */
379 console.log("Call ajax.php (in LoadProducts) to get Products of category "+currentcat+" then loop on result to fill image thumbs");
380 console.log("Found "+data.length+" record");
381
382 if (data.length == 0 && currentcat == "supplements") {
383 alert("No supplements found into the supplement category. Check the module setup and your product categories.");
384 }
385
386 while (ishow < maxproduct) {
387 console.log("ishow"+ishow+" idata="+idata);
388 console.log(data[idata]);
389
390 if (typeof (data[idata]) == "undefined") {
391 <?php if (!getDolGlobalString('TAKEPOS_HIDE_PRODUCT_IMAGES')) {
392 echo '$("#prodivdesc"+ishow).hide();';
393 echo '$("#prodesc"+ishow).text("");';
394 echo '$("#proimg"+ishow).attr("title","");';
395 echo '$("#proimg"+ishow).attr("src","genimg/empty.png");';
396 } else {
397 echo '$("#probutton"+ishow).hide();';
398 echo '$("#probutton"+ishow).text("");';
399 }?>
400 $("#proprice"+ishow).attr("class", "hidden");
401 $("#proprice"+ishow).html("");
402
403 $("#prodiv"+ishow).data("rowid","");
404 $("#prodiv"+ishow).attr("data-rowid","");
405
406 $("#prodiv"+ishow).data("iscat","0");
407 $("#prodiv"+ishow).attr("data-iscat","0");
408
409 $("#prodiv"+ishow).attr("class","wrapper2 divempty");
410 } else {
411 <?php
412 $titlestring = "'".dol_escape_js($langs->transnoentities('Ref').': ')."' + data[idata]['ref']";
413 $titlestring .= " + ' - ".dol_escape_js($langs->trans("Barcode").': ')."' + data[idata]['barcode']";
414 ?>
415 var titlestring = <?php echo $titlestring; ?>;
416 <?php if (!getDolGlobalString('TAKEPOS_HIDE_PRODUCT_IMAGES')) {
417 echo '$("#prodivdesc"+ishow).show();';
418 if (getDolGlobalInt('TAKEPOS_SHOW_PRODUCT_REFERENCE') == 1) {
419 echo '$("#prodesc"+ishow).html(data[parseInt(idata)][\'ref\'].bold() + \' - \' + data[parseInt(idata)][\'label\']);';
420 } elseif (getDolGlobalInt('TAKEPOS_SHOW_PRODUCT_REFERENCE') == 2) {
421 echo '$("#prodesc"+ishow).html(data[parseInt(idata)][\'ref\'].bold());';
422 } else {
423 echo '$("#prodesc"+ishow).html(data[parseInt(idata)][\'label\']);';
424 }
425 echo '$("#proimg"+ishow).attr("title", titlestring);';
426 echo '$("#proimg"+ishow).attr("src", "genimg/index.php?query=pro&id="+data[idata][\'id\']);';
427 } else {
428 echo '$("#probutton"+ishow).show();';
429 echo '$("#probutton"+ishow).html(data[parseInt(idata)][\'label\']);';
430 }
431 ?>
432 if (data[parseInt(idata)]['price_formated']) {
433 $("#proprice" + ishow).attr("class", "productprice");
434 <?php
435 if (getDolGlobalInt('TAKEPOS_CHANGE_PRICE_HT')) {
436 ?>
437 $("#proprice" + ishow).html(data[parseInt(idata)]['price_formated']);
438 <?php
439 } else {
440 ?>
441 $("#proprice" + ishow).html(data[parseInt(idata)]['price_ttc_formated']);
442 <?php
443 }
444 ?>
445 }
446 console.log("#prodiv"+ishow+".data(rowid)="+data[idata]['id']);
447
448 $("#prodiv"+ishow).data("rowid", data[idata]['id']);
449 $("#prodiv"+ishow).attr("data-rowid", data[idata]['id']);
450 console.log($('#prodiv4').data('rowid'));
451
452 $("#prodiv"+ishow).data("iscat", 0);
453 $("#prodiv"+ishow).attr("data-iscat", 0);
454
455 $("#prodiv"+ishow).attr("class","wrapper2");
456
457 <?php
458 // Add js from hooks
459 $parameters = array();
460 $parameters['caller'] = 'loadProducts';
461 $hookmanager->executeHooks('completeJSProductDisplay', $parameters);
462 print $hookmanager->resPrint;
463 ?>
464 }
465 $("#prowatermark"+ishow).hide();
466 ishow++; //Next product to show after print data product
467 idata++; //Next data every time
468 }
469 });
470
471 ClearSearch(false);
472}
473
474function MoreProducts(moreorless) {
475 console.log("MoreProducts");
476
477 if ($('#search_pagination').val() != '') {
478 return Search2('<?php echo(isset($keyCodeForEnter) ? $keyCodeForEnter : ''); ?>', moreorless);
479 }
480
481 var maxproduct = <?php echo($MAXPRODUCT - 2); ?>;
482
483 if (moreorless=="more"){
484 $('#proimg31').animate({opacity: '0.5'}, 1);
485 $('#proimg31').animate({opacity: '1'}, 100);
486 pageproducts=pageproducts+1;
487 }
488 if (moreorless=="less"){
489 $('#proimg30').animate({opacity: '0.5'}, 1);
490 $('#proimg30').animate({opacity: '1'}, 100);
491 if (pageproducts==0) return; //Return if no less pages
492 pageproducts=pageproducts-1;
493 }
494
495 ishow=0; //product to show counter
496 idata=0; //product data counter
497 var limit = 0;
498 if (maxproduct >= 1) {
499 limit = maxproduct-1;
500 }
501
502 var nb_cat_shown = $('.div5 div.wrapper2[data-iscat=1]').length;
503 var offset = <?php echo($MAXPRODUCT - 2); ?> * pageproducts - nb_cat_shown;
504
505 // Get socid
506 let socid = jQuery('#thirdpartyid').val();
507 if ((socid === undefined || socid === "") && parseInt("<?php echo dol_escape_js($socid) ?>") > 0) {
508 socid = parseInt("<?php echo dol_escape_js($socid); ?>");
509 }
510
511 // Only show products for sale (tosell=1)
512 $.getJSON('<?php echo DOL_URL_ROOT ?>/takepos/ajax/ajax.php?action=getProducts&token=<?php echo currentToken();?>&thirdpartyid=' + socid + '&category='+currentcat+'&tosell=1&limit='+limit+'&offset='+offset, function(data) {
513 console.log("Call ajax.php (in MoreProducts) to get Products of category "+currentcat);
514
515 if (typeof (data[0]) == "undefined" && moreorless=="more"){ // Return if no more pages
516 pageproducts=pageproducts-1;
517 return;
518 }
519
520 while (ishow < maxproduct) {
521 if (typeof (data[idata]) == "undefined") {
522 $("#prodivdesc"+ishow).hide();
523 $("#prodesc"+ishow).text("");
524 $("#probutton"+ishow).text("");
525 $("#probutton"+ishow).hide();
526 $("#proprice"+ishow).attr("class", "");
527 $("#proprice"+ishow).html("");
528 $("#proimg"+ishow).attr("src","genimg/empty.png");
529 $("#prodiv"+ishow).data("rowid","");
530 $("#prodiv"+ishow).attr("data-rowid","");
531 $("#prodiv"+ishow).addClass("divempty");
532 } else {
533 $("#prodivdesc"+ishow).show();
534 $("#prodiv"+ishow).removeClass("divempty");
535 <?php if (getDolGlobalInt('TAKEPOS_SHOW_PRODUCT_REFERENCE') == 1) { ?>
536 $("#prodesc"+ishow).html(data[parseInt(idata)]['ref'].bold() + ' - ' + data[parseInt(idata)]['label']);
537 <?php } elseif (getDolGlobalInt('TAKEPOS_SHOW_PRODUCT_REFERENCE') == 2) { ?>
538 $("#prodesc"+ishow).html(data[parseInt(idata)]['ref'].bold());
539 <?php } else { ?>
540 $("#prodesc"+ishow).html(data[parseInt(idata)]['label']);
541 <?php } ?>
542 $("#probutton"+ishow).html(data[parseInt(idata)]['label']);
543 $("#probutton"+ishow).show();
544 if (data[parseInt(idata)]['price_formated']) {
545 $("#proprice" + ishow).attr("class", "productprice");
546 <?php
547 if (getDolGlobalInt('TAKEPOS_CHANGE_PRICE_HT')) {
548 ?>
549 $("#proprice" + ishow).html(data[parseInt(idata)]['price_formated']);
550 <?php
551 } else {
552 ?>
553 $("#proprice" + ishow).html(data[parseInt(idata)]['price_ttc_formated']);
554 <?php
555 }
556 ?>
557 }
558 $("#proimg"+ishow).attr("src","genimg/index.php?query=pro&id="+data[idata]['id']);
559 $("#prodiv"+ishow).data("rowid",data[idata]['id']);
560 $("#prodiv"+ishow).attr("data-rowid",data[idata]['id']);
561 $("#prodiv"+ishow).data("iscat",0);
562 }
563 $("#prowatermark"+ishow).hide();
564 ishow++; //Next product to show after print data product
565 idata++; //Next data every time
566 }
567 });
568
569 ClearSearch(false);
570}
571
572function ClickProduct(position, qty = 1, qty_std = 0) {
573 console.log("ClickProduct at position"+position);
574 if ($('#invoiceid').val() == "") {
575 invoiceid = $('#invoiceid').val();
576 Refresh();
577 }
578 $('#proimg'+position).animate({opacity: '0.5'}, 1);
579 $('#proimg'+position).animate({opacity: '1'}, 100);
580 if ($('#prodiv'+position).data('iscat') == 1){
581 console.log("Click on a category at position "+position);
582 LoadProducts(position, true);
583 }
584 else{
585 invoiceid = $("#invoiceid").val();
586 idproduct=$('#prodiv'+position).data('rowid');
587 console.log("Click on product at position "+position+" for idproduct "+idproduct+", qty="+qty+" invoiceid="+invoiceid);
588 if (idproduct == "") {
589 return;
590 }
591
592 addInvoiceLine = function(qty, qty_std_inner = 0) {
593 // Call page invoice.php to generate the section with product lines
594 $("#poslines").load("invoice.php?action=addline&token=<?php echo currentToken(); ?>&place="+place+"&idproduct="+idproduct+"&selectedline="+selectedline+"&qty="+qty+"&invoiceid="+invoiceid+(qty_std_inner ? '&qty_std=1' : ''), function() {
595 idproduct = "";
596 <?php if (getDolGlobalString('TAKEPOS_CUSTOMER_DISPLAY')) {
597 echo "CustomerDisplay();";
598 }?>
599 });
600 };
601
602 // call WeighingScale() if product is a product that need to measure weight
603 <?php if (getDolGlobalString('TAKEPOS_WEIGHING_SCALE')) { ?>
604 if ($('#prodiv'+position).data('unit') == 2) {
605 WeighingScale(addInvoiceLine);
606 } else {
607 addInvoiceLine(qty, qty_std);
608 }
609 <?php } else { ?>
610 addInvoiceLine(qty, qty_std);
611 <?php } ?>
612 }
613
614 ClearSearch(false);
615}
616
617function ChangeThirdparty(idcustomer) {
618 console.log("ChangeThirdparty");
619 // Call page list.php to change customer
620 $("#poslines").load("<?php echo DOL_URL_ROOT ?>/societe/list.php?action=change&token=<?php echo currentToken();?>&type=t&contextpage=poslist&idcustomer="+idcustomer+"&place="+place+"", function() {
621 });
622
623 ClearSearch(false);
624}
625
626function deleteline() {
627 invoiceid = $("#invoiceid").val();
628 console.log("Delete line invoiceid="+invoiceid);
629 $("#poslines").load("invoice.php?action=deleteline&token=<?php echo currentToken(); ?>&place="+place+"&idline="+selectedline+"&invoiceid="+invoiceid, function() {
630 //$('#poslines').scrollTop($('#poslines')[0].scrollHeight);
631 });
632 ClearSearch(false);
633}
634
635function Customer() {
636 console.log("Open box to select the thirdparty place="+place);
637 $.colorbox({href:"../societe/list.php?type=t&contextpage=poslist&nomassaction=1&place="+place, width:"90%", height:"80%", transition:"none", iframe:"true", title:"<?php echo $langs->trans("Customer"); ?>"});
638}
639
640function Contact() {
641 console.log("Open box to select the contact place="+place);
642 $.colorbox({href:"../contact/list.php?type=c&contextpage=poslist&nomassaction=1&place="+place, width:"90%", height:"80%", transition:"none", iframe:"true", title:"<?php echo $langs->trans("Contact"); ?>"});
643}
644
645function History()
646{
647 console.log("Open box to select the history");
648 $.colorbox({href:"../compta/facture/list.php?contextpage=poslist&search_module_source=takepos", width:"90%", height:"80%", transition:"none", iframe:"true", title:"<?php echo $langs->trans("History"); ?>"});
649}
650
651function Reduction() {
652 invoiceid = $("#invoiceid").val();
653 console.log("Open popup to enter reduction on invoiceid="+invoiceid);
654 $.colorbox({href:"reduction.php?place="+place+"&invoiceid="+invoiceid, width:"80%", height:"90%", transition:"none", iframe:"true", title:""});
655}
656
657var closeBillParams="";
658function CloseBill() {
659 <?php
660 $parameters = array();
661 $reshook = $hookmanager->executeHooks('paramsForCloseBill', $parameters, $obj, $action);
662 if (getDolGlobalString('TAKEPOS_FORBID_SALES_TO_DEFAULT_CUSTOMER')) {
663 echo "customerAnchorTag = document.querySelector('a[id=\"customer\"]'); ";
664 echo "if (customerAnchorTag && customerAnchorTag.innerText.trim() === '".$langs->trans("Customer")."') { ";
665 echo "alert('".dol_escape_js($langs->trans("NoClientErrorMessage"))."'); ";
666 echo "return; } \n";
667 }
668 ?>
669 invoiceid = $("#invoiceid").val();
670 console.log("Open popup to enter payment on invoiceid="+invoiceid);
671 <?php if (getDolGlobalInt("TAKEPOS_NO_GENERIC_THIRDPARTY")) { ?>
672 if ($("#idcustomer").val() == "") {
673 alert("<?php echo $langs->trans('TakePosCustomerMandatory'); ?>");
674 <?php if (getDolGlobalString('TAKEPOS_CHOOSE_CONTACT')) { ?>
675 Contact();
676 <?php } else { ?>
677 Customer();
678 <?php } ?>
679 return;
680 }
681 <?php } ?>
682 <?php
683 $alternative_payurl = getDolGlobalString('TAKEPOS_ALTERNATIVE_PAYMENT_SCREEN');
684 if (empty($alternative_payurl)) {
685 $payurl = "pay.php";
686 } else {
687 $payurl = dol_buildpath($alternative_payurl, 1);
688 }
689 ?>
690 $.colorbox({href:"<?php echo $payurl; ?>?place="+place+"&invoiceid="+invoiceid+closeBillParams, width:"80%", height:"90%", transition:"none", iframe:"true", title:""});
691}
692
693function Split() {
694 invoiceid = $("#invoiceid").val();
695 console.log("Open popup to split on invoiceid="+invoiceid);
696 $.colorbox({href:"split.php?place="+place+"&invoiceid="+invoiceid, width:"80%", height:"90%", transition:"none", iframe:"true", title:""});
697}
698
699function Floors() {
700 console.log("Open box to select floor place="+place);
701 $.colorbox({href:"floors.php?place="+place, width:"90%", height:"90%", transition:"none", iframe:"true", title:"<?php echo $langs->trans("Floors"); ?>"});
702}
703
704function FreeZone() {
705 invoiceid = $("#invoiceid").val();
706 console.log("Open box to enter a free product on invoiceid="+invoiceid);
707 $.colorbox({href:"freezone.php?action=freezone&token=<?php echo newToken(); ?>&place="+place+"&invoiceid="+invoiceid, width:"80%", height:"40%", transition:"none", iframe:"true", title:"<?php echo $langs->trans("FreeZone"); ?>"});
708}
709
710function TakeposOrderNotes() {
711 console.log("Open box to order notes");
712 ModalBox('ModalNote');
713 $("#textinput").focus();
714}
715
716function Refresh() {
717 console.log("Refresh by reloading place="+place+" invoiceid="+invoiceid);
718 $("#poslines").load("invoice.php?place="+place+"&invoiceid="+invoiceid, function() {
719 //$('#poslines').scrollTop($('#poslines')[0].scrollHeight);
720 });
721}
722
723function New() {
724 // If we go here,it means $conf->global->TAKEPOS_BAR_RESTAURANT is not defined
725 invoiceid = $("#invoiceid").val(); // This is a hidden field added by invoice.php
726
727 console.log("New with place = <?php echo $place; ?>, js place="+place+", invoiceid="+invoiceid);
728
729 if (invoiceid == '') {
730 $("#poslines").load("invoice.php?action=delete&token=<?php echo currentToken(); ?>&place=" + place, function () {
731 //$('#poslines').scrollTop($('#poslines')[0].scrollHeight);
732 });
733
734 ClearSearch(false);
735 $("#idcustomer").val("");
736 return;
737 }
738
739 $.getJSON('<?php echo DOL_URL_ROOT ?>/takepos/ajax/ajax.php?action=getInvoice&token=<?php echo currentToken();?>&id='+invoiceid, function(data) {
740 var r;
741
742 if (parseInt(data['paye']) === 1) {
743 r = true;
744 } else {
745 r = confirm('<?php echo($place > 0 ? $langs->transnoentitiesnoconv("ConfirmDeletionOfThisPOSSale") : $langs->transnoentitiesnoconv("ConfirmDiscardOfThisPOSSale")); ?>');
746 }
747
748 if (r == true) {
749 // Reload section with invoice lines
750 $("#poslines").load("invoice.php?action=delete&token=<?php echo currentToken(); ?>&place=" + place, function () {
751 //$('#poslines').scrollTop($('#poslines')[0].scrollHeight);
752 });
753
754 ClearSearch(false);
755 $("#idcustomer").val("");
756 }
757 });
758}
764function DeleteSale() {
765 if (typeof place === 'undefined') {
766 return;
767 }
768 if (confirm('<?php echo dol_escape_js($langs->transnoentitiesnoconv("ConfirmDeletionOfThisPOSSale")); ?>')) {
769 // Fully remove the draft (its tab disappears), then switch to the main cart.
770 $("#poslines").load("invoice.php?action=discardsale&token=<?php echo newToken(); ?>&place=" + place, function () {
771 place = '0';
772 invoiceid = 0;
773 ClearSearch(false);
774 $("#idcustomer").val("");
775 Refresh();
776 });
777 }
778}
779
787function Search2(keyCodeForEnter, moreorless) {
788 var eventKeyCode = null;
789
790 if (window.event && window.event.keyCode) {
791 eventKeyCode = window.event.keyCode;
792 }
793 if (eventKeyCode === null && keyCodeForEnter !== '') {
794 // No key code available, exit early if a key code is required
795 return;
796 }
797
798 console.log("Search2 Call ajax search to replace products keyCodeForEnter="+keyCodeForEnter+", eventKeyCode="+eventKeyCode);
799
800 var search_term = $('#search').val();
801 var search_start = 0;
802 var search_limit = <?php echo $MAXPRODUCT - 2; ?>;
803 if (moreorless != null) {
804 search_term = $('#search_pagination').val();
805 search_start = $('#search_start_'+moreorless).val();
806 }
807
808 console.log("search_term="+search_term);
809
810 if (search_term == '') {
811 $("[id^=prowatermark]").html("");
812 $("[id^=prodesc]").text("");
813 $("[id^=probutton]").text("");
814 $("[id^=probutton]").hide();
815 $("[id^=proprice]").attr("class", "hidden");
816 $("[id^=proprice]").html("");
817 $("[id^=proimg]").attr("src", "genimg/empty.png");
818 $("[id^=prodiv]").data("rowid", "");
819 $("[id^=prodiv]").attr("data-rowid", "");
820 $("[id^=prodiv]").addClass("divempty");
821 return;
822 }
823
824 var search = false;
825 if (keyCodeForEnter == '' || eventKeyCode == keyCodeForEnter) {
826 search = true;
827 }
828
829 if (search === true) {
830 // if a timer has been already started (search2_timer is a global js variable), we cancel it now
831 // we click onto another key, we will restart another timer just after
832 if (search2_timer) {
833 clearTimeout(search2_timer);
834 }
835
836 // temporization time to give time to type
837 search2_timer = setTimeout(function(){
838 pageproducts = 0;
839 jQuery(".wrapper2 .catwatermark").hide();
840 var nbsearchresults = 0;
841
842 // Only show products for sale (tosell=1)
843 let socid = jQuery('#thirdpartyid').val();
844 if ((socid === undefined || socid === "") && parseInt("<?php echo dol_escape_js($socid) ?>") > 0) {
845 socid = parseInt("<?php echo dol_escape_js($socid); ?>");
846 }
847
848 $.getJSON('<?php echo DOL_URL_ROOT ?>/takepos/ajax/ajax.php?action=search&token=<?php echo currentToken();?>&search_term=' + search_term + '&thirdpartyid=' + socid + '&search_start=' + search_start + '&search_limit=' + search_limit, function (data) {
849 for (i = 0; i < <?php echo $MAXPRODUCT - 2; ?>; i++) { // the last 2 slots are the pager arrows, not product slots
850 if (typeof (data[i]) == "undefined") {
851 $("#prowatermark" + i).html("");
852 $("#prodesc" + i).text("");
853 $("#probutton" + i).text("");
854 $("#probutton" + i).hide();
855 $("#proprice" + i).attr("class", "hidden");
856 $("#proprice" + i).html("");
857 $("#proimg" + i).attr("src", "genimg/empty.png");
858 $("#prodiv" + i).data("rowid", "");
859 $("#prodiv" + i).attr("data-rowid", "");
860 continue;
861 }
862 <?php
863 $titlestring = "'".dol_escape_js($langs->transnoentities('Ref').': ')."' + data[i]['ref']";
864 $titlestring .= " + ' - ".dol_escape_js($langs->trans("Barcode").': ')."' + data[i]['barcode']";
865 ?>
866 var titlestring = <?php echo $titlestring; ?>;
867 <?php if (getDolGlobalInt('TAKEPOS_SHOW_PRODUCT_REFERENCE') == 1) { ?>
868 $("#prodesc" + i).html(data[i]['ref'].bold() + ' - ' + data[i]['label']);
869 <?php } elseif (getDolGlobalInt('TAKEPOS_SHOW_PRODUCT_REFERENCE') == 2) { ?>
870 $("#prodesc" + i).html(data[i]['ref'].bold());
871 <?php } else { ?>
872 $("#prodesc" + i).html(data[i]['label']);
873 <?php } ?>
874 $("#prodivdesc" + i).show();
875 $("#prodiv" + i).removeClass("divempty");
876 $("#probutton" + i).html(data[i]['label']);
877 $("#probutton" + i).show();
878 if (data[i]['price_formated']) {
879 $("#proprice" + i).attr("class", "productprice");
880 <?php
881 if (getDolGlobalInt('TAKEPOS_CHANGE_PRICE_HT')) {
882 ?>
883 $("#proprice" + i).html(data[i]['price_formated']);
884 <?php
885 } else {
886 ?>
887 $("#proprice" + i).html(data[i]['price_ttc_formated']);
888 <?php
889 }
890 ?>
891 }
892 $("#proimg" + i).attr("title", titlestring);
893 if( undefined !== data[i]['img']) {
894 $("#proimg" + i).attr("src", data[i]['img']);
895 }
896 else {
897 $("#proimg" + i).attr("src", "genimg/index.php?query=pro&id=" + data[i]['rowid']);
898 }
899 $("#prodiv" + i).data("rowid", data[i]['rowid']);
900 $("#prodiv" + i).attr("data-rowid", data[i]['rowid']);
901 $("#prodiv" + i).data("iscat", 0);
902 $("#prodiv" + i).attr("data-iscat", 0);
903
904 <?php
905 // Add js from hooks
906 $parameters = array();
907 $parameters['caller'] = 'search2';
908 $hookmanager->executeHooks('completeJSProductDisplay', $parameters);
909 print $hookmanager->resPrint;
910 ?>
911
912 nbsearchresults++;
913 }
914 }).always(function (data) {
915 // If there is only 1 answer
916 if ($('#search').val().length > 0 && data.length == 1) {
917 console.log($('#search').val()+' - '+data[0]['barcode']);
918 if ($('#search').val() == data[0]['barcode'] && 'thirdparty' == data[0]['object']) {
919 console.log("There is only 1 answer with barcode matching the search, so we change the thirdparty "+data[0]['rowid']);
920 ChangeThirdparty(data[0]['rowid']);
921 }
922 else if ('product' == data[0]['object'] && $('#search').val() == data[0]['barcode']) {
923 console.log("There is only 1 answer and we found search on a barcode, so we add the product in basket, qty="+data[0]['qty']);
924 ClickProduct(0, data[0]['qty'], 1);
925 }
926 }
927 if (eventKeyCode == keyCodeForEnter){
928 if (data.length == 0) {
929 $('#search').val('<?php
930 $langs->load('errors');
931 echo dol_escape_js($langs->transnoentitiesnoconv("ErrorRecordNotFoundShort"));
932 ?> ('+search_term+')');
933 $('#search').select();
934 }
935 else ClearSearch(false);
936 }
937 // memorize search_term and start for pagination
938 $("#search_pagination").val($("#search").val());
939 if (search_start == 0) {
940 $("#prodiv<?php echo $MAXPRODUCT - 2; ?> span").hide();
941 }
942 else {
943 $("#prodiv<?php echo $MAXPRODUCT - 2; ?> span").show();
944 var search_start_less = Math.max(0, parseInt(search_start) - parseInt(<?php echo $MAXPRODUCT - 2;?>));
945 $("#search_start_less").val(search_start_less);
946 }
947 if (nbsearchresults != <?php echo $MAXPRODUCT - 2; ?>) {
948 $("#prodiv<?php echo $MAXPRODUCT - 1; ?> span").hide();
949 }
950 else {
951 $("#prodiv<?php echo $MAXPRODUCT - 1; ?> span").show();
952 var search_start_more = parseInt(search_start) + parseInt(<?php echo $MAXPRODUCT - 2;?>);
953 $("#search_start_more").val(search_start_more);
954 }
955 });
956 }, 500); // 500ms delay
957 }
958
959}
960
961/* Function called on an action into the PAD */
962function Edit(number) {
963 console.log("We click on PAD on key="+number);
964
965 invoiceid = $("#invoiceid").val();
966
967 if (typeof(selectedtext) == "undefined") {
968 return; // We click on an action on the number pad but there is no line selected
969 }
970
971 var text=selectedtext+"<br> ";
972
973
974 if (number=='c') {
975 editnumber='';
976 Refresh();
977 $("#qty").html("<?php echo $langs->trans("Qty"); ?>").removeClass('clicked');
978 $("#price").html("<?php echo $langs->trans("Price"); ?>").removeClass('clicked');
979 $("#reduction").html("<?php echo $langs->trans("LineDiscountShort"); ?>").removeClass('clicked');
980 return;
981 } else if (number=='qty') {
982 if (editaction=='qty' && editnumber != '') {
983 $("#poslines").load("invoice.php?action=updateqty&token=<?php echo currentToken(); ?>&place="+place+"&idline="+selectedline+"&number="+editnumber+"&invoiceid="+invoiceid, function() {
984 editnumber="";
985 //$('#poslines').scrollTop($('#poslines')[0].scrollHeight);
986 $("#qty").html("<?php echo $langs->trans("Qty"); ?>").removeClass('clicked');
987 });
988
989 setFocusOnSearchField();
990 return;
991 }
992 else {
993 editaction="qty";
994 }
995 } else if (number=='p') {
996 if (editaction=='p' && editnumber!="") {
997 $("#poslines").load("invoice.php?action=updateprice&token=<?php echo currentToken(); ?>&place="+place+"&idline="+selectedline+"&number="+editnumber+"&invoiceid="+invoiceid, function() {
998 editnumber="";
999 //$('#poslines').scrollTop($('#poslines')[0].scrollHeight);
1000 $("#price").html("<?php echo $langs->trans("Price"); ?>").removeClass('clicked');
1001 });
1002
1003 ClearSearch(false);
1004 return;
1005 }
1006 else {
1007 editaction="p";
1008 }
1009 } else if (number=='r') {
1010 if (editaction=='r' && editnumber!="") {
1011 $("#poslines").load("invoice.php?action=updatereduction&token=<?php echo currentToken(); ?>&place="+place+"&idline="+selectedline+"&number="+editnumber+"&invoiceid="+invoiceid, function() {
1012 editnumber="";
1013 //$('#poslines').scrollTop($('#poslines')[0].scrollHeight);
1014 $("#reduction").html("<?php echo $langs->trans("LineDiscountShort"); ?>").removeClass('clicked');
1015 });
1016
1017 ClearSearch(false);
1018 return;
1019 }
1020 else {
1021 editaction="r";
1022 }
1023 }
1024 else {
1025 editnumber=editnumber+number;
1026 }
1027 if (editaction=='qty'){
1028 text=text+"<?php echo $langs->trans("Modify")." -> ".$langs->trans("Qty").": "; ?>";
1029 $("#qty").html("OK").addClass("clicked");
1030 $("#price").html("<?php echo $langs->trans("Price"); ?>").removeClass('clicked');
1031 $("#reduction").html("<?php echo $langs->trans("LineDiscountShort"); ?>").removeClass('clicked');
1032 }
1033 if (editaction=='p'){
1034 text=text+"<?php echo $langs->trans("Modify")." -> ".$langs->trans("Price").": "; ?>";
1035 $("#qty").html("<?php echo $langs->trans("Qty"); ?>").removeClass('clicked');
1036 $("#price").html("OK").addClass("clicked");
1037 $("#reduction").html("<?php echo $langs->trans("LineDiscountShort"); ?>").removeClass('clicked');
1038 }
1039 if (editaction=='r'){
1040 text=text+"<?php echo $langs->trans("Modify")." -> ".$langs->trans("LineDiscountShort").": "; ?>";
1041 $("#qty").html("<?php echo $langs->trans("Qty"); ?>").removeClass('clicked');
1042 $("#price").html("<?php echo $langs->trans("Price"); ?>").removeClass('clicked');
1043 $("#reduction").html("OK").addClass("clicked");
1044 }
1045 $('#'+selectedline).find("td:first").html(text+editnumber);
1046}
1047
1048
1049function TakeposPrintingOrder(){
1050 console.log("TakeposPrintingOrder output invoice to print order");
1051 $("#poslines").load("invoice.php?action=order&token=<?php echo currentToken();?>&place="+place, function() {
1052 //$('#poslines').scrollTop($('#poslines')[0].scrollHeight);
1053 });
1054}
1055
1056function TakeposPrintingTemp(){
1057 console.log("TakeposPrintingTemp");
1058 $("#poslines").load("invoice.php?action=temp&token=<?php echo currentToken();?>&place="+place, function() {
1059 //$('#poslines').scrollTop($('#poslines')[0].scrollHeight);
1060 });
1061}
1062
1063function OpenDrawer(){
1064 console.log("OpenDrawer call ajax url http://<?php print getDolGlobalString('TAKEPOS_PRINT_SERVER'); ?>:8111/print");
1065 $.ajax({
1066 type: "POST",
1067 data: { token: 'notrequired' },
1068 <?php
1069 if (getDolGlobalString('TAKEPOS_PRINT_SERVER') && filter_var($conf->global->TAKEPOS_PRINT_SERVER, FILTER_VALIDATE_URL) == true) {
1070 echo "url: '".getDolGlobalString('TAKEPOS_PRINT_SERVER', 'localhost')."/printer/drawer.php',";
1071 } else {
1072 echo "url: 'http://".getDolGlobalString('TAKEPOS_PRINT_SERVER', 'localhost').":8111/print',";
1073 }
1074 ?>
1075 data: "opendrawer"
1076 });
1077}
1078
1079/* Click on button to open drawer */
1080function DolibarrOpenDrawer() {
1081 console.log("DolibarrOpenDrawer call ajax url /takepos/ajax/ajax.php?action=opendrawer&token=<?php echo currentToken();?>&term=<?php print urlencode(empty($_SESSION["takeposterminal"]) ? '' : $_SESSION["takeposterminal"]); ?>");
1082 $.ajax({
1083 type: "GET",
1084 data: { token: '<?php echo currentToken(); ?>' },
1085 url: "<?php print DOL_URL_ROOT.'/takepos/ajax/ajax.php?action=opendrawer&token='.currentToken().'&term='.urlencode(empty($_SESSION["takeposterminal"]) ? '' : $_SESSION["takeposterminal"]); ?>",
1086 });
1087}
1088
1089function MoreActions(totalactions) {
1090 for (i = 0; i <= totalactions; i++) {
1091 $("#action" + i).toggle();
1092 }
1093 $("#actionnext").toggle();
1094 $("#actionprevious").toggle();
1095}
1096
1097function ControlCashOpening()
1098{
1099 $.colorbox({href:"../compta/cashcontrol/cashcontrol_card.php?action=create&contextpage=takepos", width:"90%", height:"60%", transition:"none", iframe:"true", title:"<?php echo $langs->trans("NewCashFence"); ?>"});
1100}
1101
1102function CloseCashFence(rowid)
1103{
1104 $.colorbox({href:"../compta/cashcontrol/cashcontrol_card.php?id="+rowid+"&contextpage=takepos", width:"90%", height:"90%", transition:"none", iframe:"true", title:"<?php echo $langs->trans("NewCashFence"); ?>"});
1105}
1106
1107function CashReport(rowid)
1108{
1109 $.colorbox({href:"../compta/cashcontrol/report.php?id="+rowid+"&contextpage=takepos", width:"60%", height:"90%", transition:"none", iframe:"true", title:"<?php echo $langs->trans("CashReport"); ?>"});
1110}
1111
1112/*
1113 * TakePOS Popup
1114 * Open the <div id='ModalID'>in a popup. Example with ModalID='ModalCreditNote'
1115 */
1116function ModalBox(ModalID)
1117{
1118 var modal = document.getElementById(ModalID);
1119 modal.style.display = "block";
1120}
1121
1122function DirectPayment(){
1123 console.log("DirectPayment");
1124 $("#poslines").load("invoice.php?place="+place+"&action=valid&token=<?php echo currentToken(); ?>&pay=LIQ", function() {
1125 $('#invoiceid').val("");
1126 });
1127}
1128
1129function FullScreen() {
1130 document.documentElement.requestFullscreen();
1131}
1132
1133function WeighingScale(callback) {
1134 console.log("Weighing Scale: invoiceid = " + placeid + ", lineid = " + selectedline);
1135 <?php if (getDolGlobalString('TAKEPOS_CONNECTOR_TO_WHB_SCALE')) {?>
1136 <?php if (getDolGlobalString('WEIGHINGSCALE_PROTOCOL') == "diag06") { ?>
1137 // Protocole Dialog-06, il a besoin du prix unitaire, le demander s'il manque
1138 var urlProduct;
1139 if (idproduct == "" && selectedline > 0) {
1140 urlProduct = "<?php echo DOL_URL_ROOT; ?>/api/index.php/takeposconnector/invoices/" + placeid + "/lines/" + selectedline + "/product";
1141 } else {
1142 urlProduct = "<?php echo DOL_URL_ROOT; ?>/api/index.php/products/" + idproduct;
1143 }
1144 $.ajax({
1145 type: "GET",
1146 headers: { "DOLAPIKEY": '<?php echo $user->api_key; ?>' },
1147 url: urlProduct,
1148 })
1149 .done(function(product) {
1150 if (callback === undefined) {
1151 callback = function(qty) {
1152 $("#poslines").load("invoice.php?token=<?php echo currentToken(); ?>&action=updateqty&place="+place+"&idline="+selectedline+"&number="+qty);
1153 };
1154 }
1155 if (product.fk_unit == "2") {
1156 askForWeight(product.multiprices_ttc[1], callback, function (errorMessage) {
1157 console.log("Erreur: " + errorMessage);
1158 });
1159 }
1160 });
1161 <?php } else { ?>
1162 // Default takeposconnector protocol: continuous reception of weight/stability
1163 editnumber = globalWeight;
1164 $("#poslines").load("invoice.php?token=<?php echo currentToken(); ?>&action=updateqty&place="+place+"&idline="+selectedline+"&number="+editnumber, function() {
1165 editnumber="";
1166 });
1167 <?php } ?>
1168 <?php } else { ?> // utilisation du new TakePOS-Connector PHP: envoie "$" à la balance pour avoir le poids
1169 $.ajax({
1170 type: "POST",
1171 data: { token: 'notrequired' },
1172 url: '<?php print getDolGlobalString('TAKEPOS_PRINT_SERVER'); ?>/scale/index.php',
1173 })
1174 .done(function( editnumber ) {
1175 $("#poslines").load("invoice.php?token=<?php echo currentToken(); ?>&action=updateqty&place="+place+"&idline="+selectedline+"&number="+editnumber, function() {
1176 editnumber="";
1177 });
1178 });
1179 <?php } ?>
1180}
1181
1182$( document ).ready(function() {
1183 PrintCategories(0);
1184 LoadProducts(0);
1185 Refresh();
1186 <?php
1187 // IF NO TERMINAL SELECTED
1188 if (empty($_SESSION["takeposterminal"]) || $_SESSION["takeposterminal"] == "") {
1189 print "ModalBox('ModalTerminal');";
1190 }
1191
1192 if (getDolGlobalString('TAKEPOS_CONTROL_CASH_OPENING')) {
1193 // Look for any cash control fence created today on this terminal, regardless of its status,
1194 // so the auto-open popup only fires on the first cash control of a calendar day. Without this,
1195 // refreshing the browser the same day after closing a fence used to immediately re-fire the
1196 // popup because the closed fences were filtered out by the status check (#38597).
1197 $sql = "SELECT rowid, status FROM ".MAIN_DB_PREFIX."pos_cash_fence WHERE";
1198 $sql .= " entity = ".((int) $conf->entity)." AND ";
1199 $sql .= " posnumber = ".((int) $_SESSION["takeposterminal"])." AND ";
1200 $sql .= " date_creation > '".$db->idate(dol_get_first_hour(dol_now()))."'";
1201 $resql = $db->query($sql);
1202 if ($resql) {
1203 $obj = $db->fetch_object($resql);
1204 // If there is no cash control from today open it
1205 if (!isset($obj->rowid) || is_null($obj->rowid)) {
1206 print "ControlCashOpening();";
1207 }
1208 }
1209 }
1210 ?>
1211
1212 /* For Header Scroll */
1213 var elem1 = $("#topnav-left")[0];
1214 var elem2 = $("#topnav-right")[0];
1215 var checkOverflow = function() {
1216 if (scrollBars().horizontal) $("#topnav").addClass("overflow");
1217 else $("#topnav").removeClass("overflow");
1218 }
1219
1220 var scrollBars = function(){
1221 var container= $('#topnav')[0];
1222 return {
1223 vertical:container.scrollHeight > container.clientHeight,
1224 horizontal:container.scrollWidth > container.clientWidth
1225 }
1226 }
1227
1228 $(window).resize(function(){
1229 checkOverflow();
1230 });
1231
1232 let resizeObserver = new ResizeObserver(() => {
1233 checkOverflow();
1234 });
1235 resizeObserver.observe(elem1);
1236 resizeObserver.observe(elem2);
1237 checkOverflow();
1238
1239 var pressTimer = [];
1240 var direction = 1;
1241 var step = 200;
1242
1243 $(".indicator").mousedown(function(){
1244 direction = $(this).hasClass("left") ? -1 : 1;
1245 scrollTo();
1246 pressTimer.push(setInterval(scrollTo, 100));
1247 });
1248
1249 $(".indicator").mouseup(function(){
1250 pressTimer.forEach(clearInterval);
1251 });
1252
1253 $("body").mouseup(function(){
1254 pressTimer.forEach(clearInterval);
1255 console.log("body mouseup");
1256 });
1257
1258 function scrollTo(){
1259 console.log("here");
1260 var pos = $("#topnav").scrollLeft();
1261 document.getElementById("topnav").scrollTo({ left: $("#topnav").scrollLeft() + direction * step, behavior: 'smooth' })
1262 }
1263
1264 $("#topnav").scroll(function(){
1265 if (($("#topnav").offsetWidth + $("#topnav").scrollLeft >= $("#topnav").scrollWidth)) {
1266 console.log("end");
1267 }
1268 });
1269 /* End Header Scroll */
1270});
1271</script>
1272
1273<div class="container">
1274
1275<?php
1276if (!getDolGlobalString('TAKEPOS_HIDE_HEAD_BAR')) {
1277 ?>
1278 <div class="header">
1279 <div id="topnav" class="topnav">
1280 <div id="topnav-left" class="topnav-left">
1281 <div class="inline-block valignmiddle">
1282 <a class="topnav-terminalhour" onclick="ModalBox('ModalTerminal')">
1283 <span class="fa fa-cash-register"></span>
1284 <span class="hideonsmartphone">
1285 <?php
1286 if (!empty($_SESSION["takeposterminal"])) {
1287 echo getDolGlobalString("TAKEPOS_TERMINAL_NAME_".$_SESSION["takeposterminal"], $langs->trans("TerminalName", $_SESSION["takeposterminal"]));
1288 }
1289 ?>
1290 </span>
1291 <?php
1292 echo '<span class="hideonsmartphone"> - '.dol_print_date(dol_now(), "day").'</span>'; ?>
1293 </a>
1294 <?php
1295 if (isModEnabled('multicurrency')) {
1296 print '<a class="valignmiddle tdoverflowmax100" id="multicurrency" onclick="ModalBox(\'ModalCurrency\')" title=""><span class="fas fa-coins paddingrightonly"></span>';
1297 print '<span class="hideonsmartphone">'.$langs->trans("Currency").'</span>';
1298 print '</a>';
1299 } ?>
1300 </div>
1301 <!-- section for customer -->
1302 <div class="inline-block valignmiddle" id="customerandsales"></div>
1303 <input type="hidden" id="idcustomer" value="">
1304 <!-- section for shopping carts -->
1305 <div class="inline-block valignmiddle" id="shoppingcart"></div>
1306 <!-- More info about customer -->
1307 <div class="inline-block valignmiddle tdoverflowmax150onsmartphone" id="moreinfo"></div>
1308 <?php
1309 if (isModEnabled('stock')) {
1310 ?>
1311 <!-- More info about warehouse -->
1312 <div class="inline-block valignmiddle tdoverflowmax150onsmartphone" id="infowarehouse"></div>
1313 <?php
1314 } ?>
1315 </div>
1316 <div id="topnav-right" class="topnav-right">
1317 <?php
1318 $reshook = $hookmanager->executeHooks('takepos_login_block_other');
1319 if ($reshook == 0) { //Search method
1320 ?>
1321 <div class="login_block_other takepos">
1322 <input type="text" id="search" name="search" class="input-nobottom" onkeyup="Search2('<?php echo dol_escape_js($keyCodeForEnter); ?>', null);" placeholder="<?php echo dol_escape_htmltag($langs->trans("Search")); ?>" autofocus>
1323 <a onclick="ClearSearch(false);" class="nohover"><span class="fa fa-backspace"></span></a>
1324 <a href="<?php echo DOL_URL_ROOT.'/'; ?>" target="backoffice" rel="opener"><!-- we need rel="opener" here, we are on same domain and we need to be able to reuse this tab several times -->
1325 <span class="fas fa-home"></span></a>
1326 <?php if (empty($conf->dol_use_jmobile)) { ?>
1327 <a class="hideonsmartphone" onclick="FullScreen();" title="<?php echo dol_escape_htmltag($langs->trans("ClickFullScreenEscapeToLeave")); ?>"><span class="fa fa-expand-arrows-alt"></span></a>
1328 <?php } ?>
1329 </div>
1330 <?php
1331 }
1332 ?>
1333 <div class="login_block_user">
1334 <?php
1335 print top_menu_user(1, DOL_URL_ROOT.'/user/logout.php?token='.newToken().'&urlfrom='.urlencode('/takepos/?setterminal='.((int) $term)));
1336 ?>
1337 </div>
1338 </div>
1339 <div class="arrows">
1340 <span class="indicator left"><i class="fa fa-arrow-left"></i></span>
1341 <span class="indicator right"><i class="fa fa-arrow-right"></i></span>
1342 </div>
1343 </div>
1344 </div>
1345 <?php
1346}
1347?>
1348
1349<!-- Modal terminal box -->
1350<div id="ModalTerminal" class="modal">
1351 <div class="modal-content">
1352 <div class="modal-header">
1353 <?php
1354 if (!getDolGlobalString('TAKEPOS_FORCE_TERMINAL_SELECT')) {
1355 ?>
1356 <span class="close" href="#" onclick="document.getElementById('ModalTerminal').style.display = 'none';">&times;</span>
1357 <?php
1358 } ?>
1359 <h3><?php print $langs->trans("TerminalSelect"); ?></h3>
1360 </div>
1361 <div class="modal-body">
1362 <button type="button" class="block" onclick="location.href='index.php?setterminal=1'"><?php print getDolGlobalString("TAKEPOS_TERMINAL_NAME_1", $langs->trans("TerminalName", 1)); ?></button>
1363 <?php
1364 $nbloop = getDolGlobalInt('TAKEPOS_NUM_TERMINALS');
1365 for ($i = 2; $i <= $nbloop; $i++) {
1366 print '<button type="button" class="block" onclick="location.href=\'index.php?setterminal='.$i.'\'">'.getDolGlobalString("TAKEPOS_TERMINAL_NAME_".$i, $langs->trans("TerminalName", $i)).'</button>';
1367 }
1368 ?>
1369 </div>
1370</div>
1371</div>
1372
1373<!-- Modal multicurrency box -->
1374<?php if (isModEnabled('multicurrency')) { ?>
1375<div id="ModalCurrency" class="modal">
1376 <div class="modal-content">
1377 <div class="modal-header">
1378 <span class="close" href="#" onclick="document.getElementById('ModalCurrency').style.display = 'none';">&times;</span>
1379 <h3><?php print $langs->trans("SetMultiCurrencyCode"); ?></h3>
1380 </div>
1381 <div class="modal-body">
1382 <?php
1383 $sql = 'SELECT code FROM '.MAIN_DB_PREFIX.'multicurrency';
1384 $sql .= " WHERE entity IN ('".getEntity('multicurrency')."')";
1385 $resql = $db->query($sql);
1386 if ($resql) {
1387 while ($obj = $db->fetch_object($resql)) {
1388 print '<button type="button" class="block" onclick="location.href=\'index.php?setcurrency='.urlencode($obj->code).'\'">'.$obj->code.'</button>';
1389 }
1390 }
1391 ?>
1392 </div>
1393 </div>
1394</div>
1395<?php } ?>
1396
1397<!-- Modal popup to create a Credit Note -->
1398<div id="ModalCreditNote" class="modal">
1399 <div class="modal-content">
1400 <div class="modal-header">
1401 <span class="close" href="#" onclick="document.getElementById('ModalCreditNote').style.display = 'none';">&times;</span>
1402 <h3><?php print $langs->trans("invoiceAvoirWithLines"); ?></h3>
1403 </div>
1404 <div class="modal-body">
1405 <button type="button" class="block" onclick="CreditNote(); document.getElementById('ModalCreditNote').style.display = 'none';"><?php print $langs->trans("Yes"); ?></button>
1406 <button type="button" class="block" onclick="document.getElementById('ModalCreditNote').style.display = 'none';"><?php print $langs->trans("No"); ?></button>
1407 </div>
1408</div>
1409</div>
1410
1411<!-- Modal Note -->
1412<div id="ModalNote" class="modal">
1413 <div class="modal-content">
1414 <div class="modal-header">
1415 <span class="close" href="#" onclick="document.getElementById('ModalNote').style.display = 'none';">&times;</span>
1416 <h3><?php print $langs->trans("Note"); ?></h3>
1417 </div>
1418 <div class="modal-body">
1419 <input type="text" class="block" id="textinput">
1420 <button type="button" class="block" onclick="SetNote(); document.getElementById('ModalNote').style.display = 'none';">OK</button>
1421 </div>
1422</div>
1423</div>
1424
1425 <div class="row1<?php if (!getDolGlobalString('TAKEPOS_HIDE_HEAD_BAR')) {
1426 print 'withhead';
1427 } ?>">
1428
1429 <div id="poslines" class="div1">
1430 </div>
1431
1432 <div class="div2">
1433 <button type="button" class="calcbutton" onclick="Edit(7);">7</button>
1434 <button type="button" class="calcbutton" onclick="Edit(8);">8</button>
1435 <button type="button" class="calcbutton" onclick="Edit(9);">9</button>
1436 <button type="button" id="qty" class="calcbutton2" onclick="Edit('qty')"><?php echo $langs->trans("Qty"); ?></button>
1437 <button type="button" class="calcbutton" onclick="Edit(4);">4</button>
1438 <button type="button" class="calcbutton" onclick="Edit(5);">5</button>
1439 <button type="button" class="calcbutton" onclick="Edit(6);">6</button>
1440 <button type="button" id="price" class="calcbutton2" onclick="Edit('p')"><?php echo $langs->trans("Price"); ?></button>
1441 <button type="button" class="calcbutton" onclick="Edit(1);">1</button>
1442 <button type="button" class="calcbutton" onclick="Edit(2);">2</button>
1443 <button type="button" class="calcbutton" onclick="Edit(3);">3</button>
1444 <button type="button" id="reduction" class="calcbutton2" onclick="Edit('r')"><?php echo $langs->trans("LineDiscountShort"); ?></button>
1445 <button type="button" class="calcbutton" onclick="Edit(0);">0</button>
1446 <button type="button" class="calcbutton" onclick="Edit('.')">.</button>
1447 <button type="button" class="calcbutton poscolorblue" onclick="Edit('c')">C</button>
1448 <?php if ($user->hasRight('takepos', 'editlines')) { ?>
1449 <button type="button" class="calcbutton2 poscolordelete" id="delete" onclick="deleteline()"><span class="fa fa-trash"></span></button>
1450 <?php } ?>
1451 </div>
1452
1453<?php
1454
1455// Dependency modulecheck
1456if (!isModEnabled('invoice')) {
1457 setEventMessages($langs->trans("ErrorModuleSetupNotComplete", $langs->transnoentitiesnoconv("Invoice")), null, 'errors');
1458}
1459
1460// TakePOS setup check
1461if (isset($_SESSION["takeposterminal"]) && $_SESSION["takeposterminal"]) {
1462 $sql = "SELECT code, libelle FROM " . MAIN_DB_PREFIX . "c_paiement";
1463 $sql .= " WHERE entity IN (" . getEntity('c_paiement') . ")";
1464 $sql .= " AND active = 1";
1465 $sql .= " ORDER BY libelle";
1466
1467 $resql = $db->query($sql);
1468 $paiementsModes = array();
1469 if ($resql) {
1470 while ($obj = $db->fetch_object($resql)) {
1471 $paycode = $obj->code;
1472 if ($paycode == 'LIQ') {
1473 $paycode = 'CASH';
1474 }
1475 if ($paycode == 'CHQ') {
1476 $paycode = 'CHEQUE';
1477 }
1478
1479 $constantforkey = "CASHDESK_ID_BANKACCOUNT_" . $paycode . $_SESSION["takeposterminal"];
1480 //var_dump($constantforkey.' '.getDolGlobalInt($constantforkey));
1481 if (getDolGlobalInt($constantforkey) > 0) {
1482 array_push($paiementsModes, $obj);
1483 }
1484 }
1485 }
1486
1487 if (empty($paiementsModes) && isModEnabled("bank")) {
1488 $langs->load('errors');
1489 setEventMessages($langs->trans("ErrorModuleSetupNotComplete", $langs->transnoentitiesnoconv("TakePOS")), null, 'errors');
1490 setEventMessages($langs->trans("ProblemIsInSetupOfTerminal", $_SESSION["takeposterminal"]), null, 'errors');
1491 }
1492}
1493
1494if (count($maincategories) == 0) {
1495 if (getDolGlobalInt('TAKEPOS_ROOT_CATEGORY_ID') > 0) {
1496 $tmpcategory = new Categorie($db);
1497 $tmpcategory->fetch(getDolGlobalInt('TAKEPOS_ROOT_CATEGORY_ID'));
1498 setEventMessages($langs->trans("TakeposNeedsAtLeastOnSubCategoryIntoParentCategory", $tmpcategory->label), null, 'errors');
1499 } else {
1500 setEventMessages($langs->trans("TakeposNeedsCategories"), null, 'errors');
1501 }
1502}
1503// User menu and external TakePOS modules
1504$menus = array();
1505$r = 0;
1506
1507if (! getDolGlobalString('TAKEPOS_HIDE_HISTORY')) {
1508 $menus[$r++] = array('title' => '<span class="fa fa-history paddingrightonly"></span><div class="trunc">'.$langs->trans("History").'</div>', 'action' => 'History();');
1509}
1510
1511if (getDolGlobalString('TAKEPOS_HIDE_HEAD_BAR')) {
1512 if (getDolGlobalString('TAKEPOS_CHOOSE_CONTACT')) {
1513 $menus[$r++] = array('title' => '<span class="far fa-building paddingrightonly"></span><div class="trunc">'.$langs->trans("Contact").'</div>', 'action' => 'Contact();');
1514 } else {
1515 $menus[$r++] = array('title' => '<span class="far fa-building paddingrightonly"></span><div class="trunc">'.$langs->trans("Customer").'</div>', 'action' => 'Customer();');
1516 }
1517}
1518
1519if (!getDolGlobalString('TAKEPOS_BAR_RESTAURANT')) {
1520 $menus[$r++] = array('title' => '<span class="fa fa-layer-group paddingrightonly"></span><div class="trunc">'.$langs->trans("New").'</div>', 'action' => 'New();');
1521} else {
1522 // BAR RESTAURANT specific menu
1523 $menus[$r++] = array('title' => '<span class="fa fa-layer-group paddingrightonly"></span><div class="trunc">'.$langs->trans("Place").'</div>', 'action' => 'Floors();');
1524}
1525
1526// Add a non predefined product
1527if (!getDolGlobalString('TAKEPOS_NO_FREE_ZONE_PRODUCT')) {
1528 $menus[$r++] = array('title' => '<span class="fa fa-cube paddingrightonly"></span><div class="trunc">'.$langs->trans("FreeZone").'</div>', 'action' => 'FreeZone();');
1529}
1530
1531// BAR RESTAURANT specific menu "Print on kitchen/order printer"
1532if (getDolGlobalString('TAKEPOS_BAR_RESTAURANT')) {
1533 if (getDolGlobalString('TAKEPOS_SUPPLEMENTS')) {
1534 $menus[$r++] = array('title' => '<span class="fa fa-cube paddingrightonly"></span><div class="trunc">'.$langs->trans("ProductSupplements").'</div>', 'action' => 'LoadProducts(\'supplements\');');
1535 }
1536
1537 if (getDolGlobalString('TAKEPOS_ORDER_PRINTERS')) {
1538 $menus[$r++] = array('title' => '<span class="fa fa-blender-phone paddingrightonly"></span><div class="trunc">'.$langs->trans("SentOrderToKitchen").'</span>', 'action' => 'TakeposPrintingOrder();');
1539 }
1540}
1541
1542// Add a discount
1543$menus[$r++] = array('title' => '<span class="fa fa-percent paddingrightonly"></span><div class="trunc">'.$langs->trans("InvoiceDiscountShort").'</div>', 'action' => 'Reduction();');
1544
1545if (!getDolGlobalString('TAKEPOS_NO_SPLIT_SALE')) {
1546 $menus[$r++] = array('title' => '<span class="fas fa-cut paddingrightonly"></span><div class="trunc">'.$langs->trans("SplitSale").'</div>', 'action' => 'Split();');
1547}
1548
1549// Last action that close the sell (payments)
1550$menus[$r++] = array('title' => '<span class="far fa-money-bill-alt paddingrightonly"></span><div class="trunc">'.$langs->trans("Payment").'</div>', 'action' => 'CloseBill();');
1551if (getDolGlobalString('TAKEPOS_DIRECT_PAYMENT')) {
1552 $menus[$r++] = array('title' => '<span class="far fa-money-bill-alt paddingrightonly"></span><div class="trunc">'.$langs->trans("DirectPayment").' <span class="opacitymedium">('.$langs->trans("Cash").')</span></div>', 'action' => 'DirectPayment();');
1553}
1554
1555$customprinterallowed = false;
1556$customprinttemplateallowed = true;
1557
1558// BAR RESTAURANT specific menu
1559if (getDolGlobalString('TAKEPOS_BAR_RESTAURANT')) {
1560 // Button to print receipt before payment
1561 $customprinterallowed = true;
1562 $customprinttemplateallowed = true;
1563}
1564
1565include_once DOL_DOCUMENT_ROOT.'/blockedlog/lib/blockedlog.lib.php';
1566if (isALNERunningVersion()) {
1567 // Custom printer may be allowed if mandatory information in template are guaranteed. For the moment, we prefer not allow this.
1568 $customprinttemplateallowed = false;
1569}
1570
1571// Button to print receipt
1572// This section should be same than into invoice.php
1573if (getDolGlobalString('TAKEPOS_PRINT_METHOD') == "takeposconnector") { // deprecated method
1574 if (getDolGlobalString('TAKEPOS_PRINT_SERVER') && filter_var(getDolGlobalString('TAKEPOS_PRINT_SERVER'), FILTER_VALIDATE_URL) == true) {
1575 // If TAKEPOS_PRINT_SERVER is an URL
1576 $menus[$r++] = array('title' => '<span class="fa fa-receipt paddingrightonly"></span><div class="trunc">'.$langs->trans("PrintTicket").'</div>', 'action' => 'PrintByESCPOSOld(placeid);');
1577 } else {
1578 // If TAKEPOS_PRINT_SERVER is an IP
1579 // Print by calling the receipt.php to get HTML content and send the HTML content to TAKEPOS_PRINT_SERVER:8111/print
1580 $menus[$r++] = array('title' => '<span class="fa fa-receipt paddingrightonly"></span><div class="trunc">'.$langs->trans("PrintTicket").'</div>', 'action' => 'PrintHTMLToSlashPrint(placeid);');
1581 }
1582} elseif ($customprinterallowed && $customprinttemplateallowed && (isModEnabled('receiptprinter') && getDolGlobalInt('TAKEPOS_PRINTER_TO_USE'.$term) > 0) || getDolGlobalString('TAKEPOS_PRINT_METHOD') == "receiptprinter") { // @phpstan-ignore-line
1583 // Button Print Receipt on special custom printer using custom template
1584 $nameOfPrinter = dol_getIdFromCode($db, getDolGlobalInt('TAKEPOS_PRINTER_TO_USE'.$term), 'printer_receipt', 'rowid', 'name', 1);
1585 $menus[$r++] = array('title' => '<div title="'.dolPrintHTMLForAttribute($langs->trans("PrintOn", $nameOfPrinter)).'"><span class="fa fa-receipt paddingrightonly"></span><div class="trunc">'.$langs->trans("PrintTicket").'</div></div>', 'action' => 'PrintByESCPOS(placeid);');
1586} else {
1587 // Button Print Receipt on browser
1588 $menus[$r++] = array('title' => '<span class="fa fa-receipt paddingrightonly"></span><div class="trunc">'.$langs->trans("PrintTicket").'</div>', 'action' => 'PrintByBrowser(placeid);');
1589}
1590
1591if (getDolGlobalString('TAKEPOS_PRINT_METHOD') == "takeposconnector" && getDolGlobalString('TAKEPOS_ORDER_NOTES') == 1) {
1592 $menus[$r++] = array('title' => '<span class="fa fa-sticky-note paddingrightonly"></span><div class="trunc">'.$langs->trans("OrderNotes").'</div>', 'action' => 'TakeposOrderNotes();');
1593}
1594
1595
1596if (getDolGlobalString('TAKEPOS_PRINT_METHOD') == "takeposconnector") {
1597 $menus[$r++] = array('title' => '<span class="fa fa-receipt paddingrightonly"></span><div class="trunc">'.$langs->trans("DOL_OPEN_DRAWER").'</div>', 'action' => 'OpenDrawer();');
1598}
1599if (getDolGlobalInt('TAKEPOS_ADD_BUTTON_OPEN_DRAWER'.$term) > 0) {
1600 $menus[$r++] = array(
1601 'title' => '<span class="fa fa-receipt paddingrightonly"></span><div class="trunc">'.$langs->trans("DOL_OPEN_DRAWER").'</div>',
1602 'action' => 'DolibarrOpenDrawer();',
1603 );
1604}
1605
1606// If there is an open cash control started
1607$sql = "SELECT rowid, status, entity FROM ".MAIN_DB_PREFIX."pos_cash_fence WHERE";
1608$sql .= " entity = ".((int) $conf->entity)." AND ";
1609$sql .= " posnumber = ".((int) empty($_SESSION["takeposterminal"]) ? 0 : $_SESSION["takeposterminal"])." AND ";
1610$sql .= " date_creation > '".$db->idate(dol_get_first_hour(dol_now()))."'";
1611$sql .= " AND status = 0";
1612
1613$resql = $db->query($sql);
1614if ($resql) {
1615 $num = $db->num_rows($resql);
1616 if ($num) {
1617 $obj = $db->fetch_object($resql);
1618 $menus[$r++] = array('title' => '<span class="fas fa-file-invoice-dollar paddingrightonly"></span><div class="trunc">'.$langs->trans("CashReport").'</div>', 'action' => 'CashReport('.$obj->rowid.');');
1619 if ($obj->status == 0) {
1620 $menus[$r++] = array('title' => '<span class="fas fa-cash-register paddingrightonly"></span><div class="trunc">'.$langs->trans("CloseCashFence").'</div>', 'action' => 'CloseCashFence('.$obj->rowid.');');
1621 }
1622 }
1623}
1624
1625if (getDolGlobalString('TAKEPOS_HIDE_HEAD_BAR')) {
1626 $menus[$r++] = array('title' => '<span class="fa fa-sign-out-alt pictofixedwidth"></span><div class="trunc">'.$langs->trans("Logout").'</div>', 'action' => 'window.location.href=\''.DOL_URL_ROOT.'/user/logout.php?token='.newToken().'\';');
1627}
1628
1629if (getDolGlobalString('TAKEPOS_WEIGHING_SCALE')) {
1630 $menus[$r++] = array('title' => '<span class="fa fa-balance-scale pictofixedwidth"></span><div class="trunc">'.$langs->trans("WeighingScale").'</div>', 'action' => 'WeighingScale();');
1631}
1632
1633// Button to delete (discard) the current sale
1634$menus[$r++] = array('title' => '<span class="fa fa-trash-alt paddingrightonly"></span><div class="trunc">'.$langs->trans("DeleteSale").'</div>', 'action' => 'DeleteSale();', 'style' => 'background-color: #d9534f !important; color: #000 !important;');
1635
1636$parameters = array('menus' => $menus);
1637$reshook = $hookmanager->executeHooks('ActionButtons', $parameters);
1638if ($reshook == 0) { //add buttons
1639 if (is_array($hookmanager->resArray)) {
1640 foreach ($hookmanager->resArray as $resArray) {
1641 foreach ($resArray as $butmenu) {
1642 $menus[$r++] = $butmenu;
1643 }
1644 }
1645 }
1646} elseif ($reshook == 1) {
1647 $r = 0; //replace buttons
1648 if (is_array($hookmanager->resArray)) {
1649 foreach ($hookmanager->resArray as $resArray) {
1650 foreach ($resArray as $butmenu) {
1651 $menus[$r++] = $butmenu;
1652 }
1653 }
1654 }
1655}
1656
1657?>
1658 <!-- Show buttons -->
1659 <div id="dialogforpopuptakepos"></div>
1660 <style>
1661 /* Style de la popup */
1662 #dialogforpopuptakepos {
1663 display: none;
1664 position: fixed;
1665 top: 20px;
1666 right: 20px;
1667 background: #333;
1668 color: #fff;
1669 padding: 15px 20px;
1670 border-radius: 8px;
1671 box-shadow: 0 0 10px rgba(0,0,0,0.3);
1672 z-index: 1000;
1673 font-family: sans-serif;
1674 }
1675 </style>
1676
1677 <div class="div3">
1678 <?php
1679 $i = 0;
1680 foreach ($menus as $menu) {
1681 $i++;
1682 if (count($menus) > 12 and $i == 12) {
1683 echo '<button style="'.(empty($menu['style']) ? '' : $menu['style']).'" type="button" id="actionnext" class="actionbutton" onclick="MoreActions('.count($menus).')">'.$langs->trans("Next").'</button>';
1684 echo '<button style="display: none;" type="button" id="actionprevious" class="actionbutton" onclick="MoreActions('.count($menus).')">'.$langs->trans("Previous").'</button>';
1685 echo '<button style="display: none;" type="button" id="action'.$i.'" class="actionbutton'.(empty($menu['class']) ? '' : ' '.dol_escape_htmltag($menu['class'])).'" onclick="'.(empty($menu['action']) ? '' : $menu['action']).'">'.$menu['title'].'</button>';
1686 } elseif ($i > 12) {
1687 echo '<button style="display: none;" type="button" id="action'.$i.'" class="actionbutton'.(empty($menu['class']) ? '' : ' '.dol_escape_htmltag($menu['class'])).'" onclick="'.(empty($menu['action']) ? '' : $menu['action']).'">'.$menu['title'].'</button>';
1688 // TODO keep style but hide button
1689 } else {
1690 echo '<button style="'.(empty($menu['style']) ? '' : $menu['style']).'" type="button" id="action'.$i.'" class="actionbutton'.(empty($menu['class']) ? '' : ' '.dol_escape_htmltag($menu['class'])).'" onclick="'.(empty($menu['action']) ? '' : $menu['action']).'">'.$menu['title'].'</button>';
1691 }
1692 }
1693
1694 if (getDolGlobalString('TAKEPOS_HIDE_HEAD_BAR') && !getDolGlobalString('TAKEPOS_HIDE_SEARCH')) {
1695 print '<!-- Show the search input text -->'."\n";
1696 print '<div class="margintoponly">';
1697 print '<input type="text" id="search" class="input-search-takepos input-nobottom" name="search" onkeyup="Search2(\''.dol_escape_js($keyCodeForEnter).'\', null);" style="width: 80%; width:calc(100% - 51px); font-size: 150%;" placeholder="'.dol_escape_htmltag($langs->trans("Search")).'" autofocus> ';
1698 print '<a class="marginleftonly hideonsmartphone" onclick="ClearSearch(false);">'.img_picto('', 'searchclear.png').'</a>';
1699 print '</div>';
1700 }
1701 ?>
1702 </div>
1703 </div>
1704
1705 <div class="row2<?php if (!getDolGlobalString('TAKEPOS_HIDE_HEAD_BAR')) {
1706 print 'withhead';
1707 } ?>">
1708
1709 <!-- Show categories -->
1710 <?php
1711 if (getDolGlobalInt('TAKEPOS_HIDE_CATEGORIES') == 1) {
1712 print '<div class="div4" style= "display: none;">';
1713 } else {
1714 print '<div class="div4">';
1715 }
1716
1717 $count = 0;
1718 while ($count < $MAXCATEG) {
1719 ?>
1720 <div class="wrapper" <?php if ($count == ($MAXCATEG - 2)) {
1721 echo 'onclick="MoreCategories(\'less\')"';
1722 } elseif ($count == ($MAXCATEG - 1)) {
1723 echo 'onclick="MoreCategories(\'more\')"';
1724 } else {
1725 echo 'onclick="LoadProducts('.$count.')"';
1726 } ?> id="catdiv<?php echo $count; ?>">
1727 <?php
1728 if ($count == ($MAXCATEG - 2)) {
1729 //echo '<img class="imgwrapper" src="img/arrow-prev-top.png" height="100%" id="catimg'.$count.'" />';
1730 echo '<span class="fa fa-chevron-left centerinmiddle" style="font-size: 5em; cursor: pointer;"></span>';
1731 } elseif ($count == ($MAXCATEG - 1)) {
1732 //echo '<img class="imgwrapper" src="img/arrow-next-top.png" height="100%" id="catimg'.$count.'" />';
1733 echo '<span class="fa fa-chevron-right centerinmiddle" style="font-size: 5em; cursor: pointer;"></span>';
1734 } else {
1735 if (!getDolGlobalString('TAKEPOS_HIDE_CATEGORY_IMAGES')) {
1736 echo '<img class="imgwrapper" id="catimg'.$count.'" />';
1737 }
1738 } ?>
1739 <?php if ($count != $MAXCATEG - 2 && $count != $MAXCATEG - 1) { ?>
1740 <div class="description" id="catdivdesc<?php echo $count; ?>">
1741 <div class="description_content" id="catdesc<?php echo $count; ?>"></div>
1742 </div>
1743 <?php } ?>
1744 <div class="catwatermark" id='catwatermark<?php echo $count; ?>'>...</div>
1745 </div>
1746 <?php
1747 $count++;
1748 }
1749 ?>
1750 </div>
1751
1752 <!-- Show product -->
1753 <div class="div5<?php if (getDolGlobalInt('TAKEPOS_HIDE_CATEGORIES') == 1) {
1754 print ' centpercent';
1755 } ?>">
1756 <?php
1757 $count = 0;
1758
1759 while ($count < $MAXPRODUCT) {
1760 print '<div class="wrapper2'.(($count >= ($MAXPRODUCT - 2)) ? ' arrow' : '').'" id="prodiv'.$count.'" '; ?>
1761 <?php if ($count == ($MAXPRODUCT - 2)) {
1762 ?> onclick="MoreProducts('less')" <?php
1763 }
1764 if ($count == ($MAXPRODUCT - 1)) {
1765 ?> onclick="MoreProducts('more')" <?php
1766 } else {
1767 echo 'onclick="ClickProduct('.((int) $count).')"';
1768 } ?>>
1769 <?php
1770 if ($count == ($MAXPRODUCT - 2)) {
1771 //echo '<img class="imgwrapper" src="img/arrow-prev-top.png" height="100%" id="proimg'.$count.'" />';
1772 print '<span class="fa fa-chevron-left centerinmiddle" style="font-size: 5em; cursor: pointer;"></span>';
1773 } elseif ($count == ($MAXPRODUCT - 1)) {
1774 //echo '<img class="imgwrapper" src="img/arrow-next-top.png" height="100%" id="proimg'.$count.'" />';
1775 print '<span class="fa fa-chevron-right centerinmiddle" style="font-size: 5em; cursor: pointer;"></span>';
1776 } else {
1777 if (!getDolGlobalString('TAKEPOS_HIDE_PRODUCT_PRICES')) {
1778 print '<div class="" id="proprice'.$count.'"></div>';
1779 }
1780 if (getDolGlobalString('TAKEPOS_HIDE_PRODUCT_IMAGES')) {
1781 print '<button type="button" id="probutton'.$count.'" class="productbutton" style="display: none;"></button>';
1782 } else {
1783 print '<img class="imgwrapper" title="" id="proimg'.$count.'">';
1784 }
1785 } ?>
1786 <?php if ($count != $MAXPRODUCT - 2 && $count != $MAXPRODUCT - 1 && !getDolGlobalString('TAKEPOS_HIDE_PRODUCT_IMAGES')) { ?>
1787 <div class="description" id="prodivdesc<?php echo $count; ?>">
1788 <div class="description_content" id="prodesc<?php echo $count; ?>"></div>
1789 </div>
1790 <?php } ?>
1791 <div class="catwatermark" id='prowatermark<?php echo $count; ?>'>...</div>
1792 </div>
1793 <?php
1794 $count++;
1795 }
1796 ?>
1797 <input type="hidden" id="search_start_less" value="0">
1798 <input type="hidden" id="search_start_more" value="0">
1799 <input type="hidden" id="search_pagination" value="">
1800 </div>
1801 </div>
1802</div>
1803</body>
1804<?php
1805
1806llxFooter();
1807
1808$db->close();
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
Definition wrapper.php:91
print $object position
Definition edit.php:206
Class to manage categories.
Class to manage contact/addresses.
Class to manage generation of HTML components Only common components must be here.
print $langs trans("Ref").' m titre as m m statut as status
Or an array listing all the potential status of the object: array: int of the status => translated la...
Definition index.php:169
dol_get_first_hour($date, $gm='tzserver')
Return GMT time for first hour of a given GMT date (it removes hours, min and second part)
Definition date.lib.php:665
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.
dol_now($mode='gmt')
Return date for now.
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.
dolSetCookie(string $cookiename, string $cookievalue, int $expire=-1)
Set a cookie.
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.
dol_sort_array(&$array, $index, $order='asc', $natsort=0, $case_sensitive=0, $keepindex=0)
Advanced sort array by the value of a given key, which produces ascending (default) or descending out...
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, $nodefault=0)
Return value of a param into GET or POST supervariable.
GETPOSTINT($paramname, $method=0, $nodefault=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
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
editval_textarea active
top_htmlhead($head, $title='', $disablejs=0, $disablehead=0, $arrayofjs=array(), $arrayofcss=array(), $disableforlogin=0, $disablenofollow=0, $disablenoindex=0)
Output html header of a page.
top_menu_user($hideloginname=0, $urllogout='')
Build the tooltip on user login.
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
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition repair.php:133
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $mode=0)
Check permissions of a user to show a page and an object.