dolibarr 22.0.5
invoice.php
Go to the documentation of this file.
1<?php
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('NOTOKENRENEWAL')) {
35 define('NOTOKENRENEWAL', '1');
36}
37if (!defined('NOREQUIREMENU')) {
38 define('NOREQUIREMENU', '1');
39}
40if (!defined('NOREQUIREHTML')) {
41 define('NOREQUIREHTML', '1');
42}
43if (!defined('NOREQUIREAJAX')) {
44 define('NOREQUIREAJAX', '1');
45}
46
47// Load Dolibarr environment
48if (!defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE')) {
49 require '../main.inc.php';
50}
51require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
52require_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
53require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
54require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php';
55require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
65$hookmanager->initHooks(array('takeposinvoice'));
66
67$langs->loadLangs(array("companies", "commercial", "bills", "cashdesk", "stocks", "banks"));
68
69$action = GETPOST('action', 'aZ09');
70$idproduct = GETPOSTINT('idproduct');
71$place = (GETPOST('place', 'aZ09') ? GETPOST('place', 'aZ09') : 0); // $place is id of table for Bar or Restaurant
72$placeid = 0; // $placeid is ID of invoice
73$mobilepage = GETPOST('mobilepage', 'alpha');
74
75// Terminal is stored into $_SESSION["takeposterminal"];
76
77if (!$user->hasRight('takepos', 'run') && !defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE')) {
78 accessforbidden('No permission to use the TakePOS');
79}
80
81if ((getDolGlobalString('TAKEPOS_PHONE_BASIC_LAYOUT') == 1 && $conf->browser->layout == 'phone') || defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE')) {
82 // DIRECT LINK TO THIS PAGE FROM MOBILE AND NO TERMINAL SELECTED
83 if ($_SESSION["takeposterminal"] == "") {
84 if (getDolGlobalString('TAKEPOS_NUM_TERMINALS') == "1") {
85 $_SESSION["takeposterminal"] = 1;
86 } else {
87 header("Location: ".DOL_URL_ROOT."/takepos/index.php");
88 exit;
89 }
90 }
91}
92
93
94$takeposterminal = isset($_SESSION["takeposterminal"]) ? $_SESSION["takeposterminal"] : '';
95
96// When session has expired (selected terminal has been lost from session), redirect to the terminal selection.
97if (empty($takeposterminal)) {
98 if (getDolGlobalInt('TAKEPOS_NUM_TERMINALS') == 1) {
99 $_SESSION["takeposterminal"] = 1; // Use terminal 1 if there is only 1 terminal
100 $takeposterminal = 1;
101 } elseif (!empty($_COOKIE["takeposterminal"])) {
102 $_SESSION["takeposterminal"] = preg_replace('/[^a-zA-Z0-9_\-]/', '', $_COOKIE["takeposterminal"]); // Restore takeposterminal from previous session
103 $takeposterminal = $_SESSION["takeposterminal"];
104 } else {
105 print <<<SCRIPT
106<script language="javascript">
107 $( document ).ready(function() {
108 ModalBox('ModalTerminal');
109 });
110</script>
111SCRIPT;
112 exit;
113 }
114}
115
116
123function fail($message)
124{
125 header($_SERVER['SERVER_PROTOCOL'].' 500 Internal Server Error', true, 500);
126 die($message);
127}
128
129
130
131$number = (float) GETPOST('number', 'alpha');
132$idline = GETPOSTINT('idline');
133$selectedline = GETPOSTINT('selectedline');
134$desc = GETPOST('desc', 'alphanohtml');
135$pay = GETPOST('pay', 'aZ09');
136$amountofpayment = GETPOSTFLOAT('amount');
137
138$invoiceid = GETPOSTINT('invoiceid');
139
140$paycode = $pay;
141if ($pay == 'cash') {
142 $paycode = 'LIQ'; // For backward compatibility
143}
144if ($pay == 'card') {
145 $paycode = 'CB'; // For backward compatibility
146}
147if ($pay == 'cheque') {
148 $paycode = 'CHQ'; // For backward compatibility
149}
150
151// Retrieve paiementid
152$paiementid = 0;
153if ($paycode) {
154 $sql = "SELECT id FROM ".MAIN_DB_PREFIX."c_paiement";
155 $sql .= " WHERE entity IN (".getEntity('c_paiement').")";
156 $sql .= " AND code = '".$db->escape($paycode)."'";
157 $resql = $db->query($sql);
158 if ($resql) {
159 $obj = $db->fetch_object($resql);
160 if ($obj) {
161 $paiementid = $obj->id;
162 }
163 }
164}
165
166$invoice = new Facture($db);
167if ($invoiceid > 0) {
168 $ret = $invoice->fetch($invoiceid);
169} else {
170 $ret = $invoice->fetch(0, '(PROV-POS'.$takeposterminal.'-'.$place.')');
171}
172if ($ret > 0) {
173 $placeid = $invoice->id;
174}
175
176$constforcompanyid = 'CASHDESK_ID_THIRDPARTY'.$takeposterminal;
177
178$soc = new Societe($db);
179if ($invoice->socid > 0) {
180 $soc->fetch($invoice->socid);
181} else {
182 $soc->fetch(getDolGlobalInt($constforcompanyid));
183}
184
185// Assign a default project, if relevant
186if (isModEnabled('project') && getDolGlobalInt("CASHDESK_ID_PROJECT".$takeposterminal)) {
187 $invoice->fk_project = getDolGlobalInt("CASHDESK_ID_PROJECT".$takeposterminal);
188}
189
190// Change the currency of invoice if it was modified
191if (isModEnabled('multicurrency') && !empty($_SESSION["takeposcustomercurrency"])) {
192 if ($invoice->multicurrency_code != $_SESSION["takeposcustomercurrency"]) {
193 $invoice->setMulticurrencyCode($_SESSION["takeposcustomercurrency"]);
194 }
195}
196
197$term = empty($_SESSION["takeposterminal"]) ? 1 : $_SESSION["takeposterminal"];
198
199
200/*
201 * Actions
202 */
203$error = 0;
204$parameters = array();
205$reshook = $hookmanager->executeHooks('doActions', $parameters, $invoice, $action); // Note that $action and $object may have been modified by some hooks
206if ($reshook < 0) {
207 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
208}
209
210$sectionwithinvoicelink = '';
211$CUSTOMER_DISPLAY_line1 = '';
212$CUSTOMER_DISPLAY_line2 = '';
213$headerorder = '';
214$footerorder = '';
215$printer = null;
216$idoflineadded = 0;
217if (empty($reshook)) {
218 // Action to record a payment on a TakePOS invoice
219 if ($action == 'valid' && $user->hasRight('facture', 'creer')) {
220 $bankaccount = 0;
221 $error = 0;
222
223 if (getDolGlobalString('TAKEPOS_CAN_FORCE_BANK_ACCOUNT_DURING_PAYMENT')) {
224 $bankaccount = GETPOSTINT('accountid');
225 } else {
226 if ($pay == 'LIQ') {
227 $bankaccount = getDolGlobalInt('CASHDESK_ID_BANKACCOUNT_CASH'.$_SESSION["takeposterminal"]); // For backward compatibility
228 } elseif ($pay == "CHQ") {
229 $bankaccount = getDolGlobalInt('CASHDESK_ID_BANKACCOUNT_CHEQUE'.$_SESSION["takeposterminal"]); // For backward compatibility
230 } else {
231 $accountname = "CASHDESK_ID_BANKACCOUNT_".$pay.$_SESSION["takeposterminal"];
232 $bankaccount = getDolGlobalInt($accountname);
233 }
234 }
235
236 if ($bankaccount <= 0 && $pay != "delayed" && isModEnabled("bank")) {
237 $errormsg = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("BankAccount"));
238 $error++;
239 }
240
241 $now = dol_now();
242 $res = 0;
243
244 $invoice = new Facture($db);
245 $invoice->fetch($placeid);
246
247 $db->begin();
248
249 if ($invoice->total_ttc < 0) {
250 $invoice->type = $invoice::TYPE_CREDIT_NOTE;
251
252 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."facture";
253 $sql .= " WHERE entity IN (".getEntity('invoice').")";
254 $sql .= " AND fk_soc = ".((int) $invoice->socid);
255 $sql .= " AND type <> ".Facture::TYPE_CREDIT_NOTE;
256 $sql .= " AND fk_statut >= ".$invoice::STATUS_VALIDATED;
257 $sql .= " ORDER BY rowid DESC";
258
259 $fk_source = 0;
260 $resql = $db->query($sql);
261 if ($resql) {
262 $obj = $db->fetch_object($resql);
263 $fk_source = $obj->rowid;
264 if ((int) $fk_source == 0) {
265 fail($langs->transnoentitiesnoconv("NoPreviousBillForCustomer"));
266 }
267 } else {
268 fail($langs->transnoentitiesnoconv("NoPreviousBillForCustomer"));
269 }
270 $invoice->fk_facture_source = $fk_source;
271 $invoice->update($user);
272 }
273
274 $constantforkey = 'CASHDESK_NO_DECREASE_STOCK'.(isset($_SESSION["takeposterminal"]) ? $_SESSION["takeposterminal"] : '');
275 $allowstockchange = (getDolGlobalString($constantforkey) != "1");
276
277 if ($error) {
278 dol_htmloutput_errors($errormsg, [], 1);
279 } elseif ($invoice->status != Facture::STATUS_DRAFT) {
280 //If invoice is validated but it is not fully paid is not error and make the payment
281 $remaintopay = $invoice->getRemainToPay();
282 if (($remaintopay > 0 && $invoice->type != Facture::TYPE_CREDIT_NOTE) || ($remaintopay < 0 && $invoice->type == Facture::TYPE_CREDIT_NOTE)) {
283 $res = 1;
284 } else {
285 dol_syslog("Sale already validated");
286 dol_htmloutput_errors($langs->trans("InvoiceIsAlreadyValidated", "TakePos"), [], 1);
287 }
288 } elseif (count($invoice->lines) == 0) {
289 $error++;
290 dol_syslog('Sale without lines');
291 dol_htmloutput_errors($langs->trans("NoLinesToBill", "TakePos"), [], 1);
292 } elseif (isModEnabled('stock') && !isModEnabled('productbatch') && $allowstockchange) {
293 // Validation of invoice with change into stock when produt/lot module is NOT enabled and stock change NOT disabled.
294 // The case for isModEnabled('productbatch') is processed few lines later.
295 $savconst = getDolGlobalString('STOCK_CALCULATE_ON_BILL');
296
297 $conf->global->STOCK_CALCULATE_ON_BILL = 1; // To force the change of stock during invoice validation
298
299 $constantforkey = 'CASHDESK_ID_WAREHOUSE'.(isset($_SESSION["takeposterminal"]) ? $_SESSION["takeposterminal"] : '');
300 dol_syslog("Validate invoice with stock change. Warehouse defined into constant ".$constantforkey." = ".getDolGlobalString($constantforkey));
301
302 // Validate invoice with stock change into warehouse getDolGlobalInt($constantforkey)
303 // Label of stock movement will be the same as when we validate invoice "Invoice XXXX validated"
304 $batch_rule = 0; // Module productbatch is disabled here, so no need for a batch_rule.
305 $res = $invoice->validate($user, '', getDolGlobalInt($constantforkey), 0, $batch_rule);
306
307 // Restore setup
308 $conf->global->STOCK_CALCULATE_ON_BILL = $savconst;
309 } else {
310 // Validation of invoice with no change into stock (because param $idwarehouse is not fill)
311 $res = $invoice->validate($user);
312 if ($res < 0) {
313 $error++;
314 $langs->load("admin");
315 dol_htmloutput_errors($invoice->error == 'NotConfigured' ? $langs->trans("NotConfigured").' (TakePos numbering module)' : $invoice->error, $invoice->errors, 1);
316 }
317 }
318
319 // Add the payment
320 if (!$error && $res >= 0) {
321 $remaintopay = $invoice->getRemainToPay();
322 // Credit notes have negative remaintopay; regular invoices have positive
323 if (($remaintopay > 0 && $invoice->type != Facture::TYPE_CREDIT_NOTE) || ($remaintopay < 0 && $invoice->type == Facture::TYPE_CREDIT_NOTE)) {
324 $payment = new Paiement($db);
325
326 $payment->datepaye = $now;
327 $payment->fk_account = $bankaccount;
328 if ($pay == 'LIQ') {
329 $payment->pos_change = GETPOSTFLOAT('excess');
330 }
331
332 $payment->amounts[$invoice->id] = $amountofpayment;
333 // If user has not used change control, add total invoice payment
334 // Or if user has used change control and the amount of payment is higher than remain to pay, add the remain to pay
335 if ($amountofpayment <= 0 || $amountofpayment > $remaintopay) {
336 $payment->amounts[$invoice->id] = $remaintopay;
337 }
338 // We do not set $payments->multicurrency_amounts because we want payment to be in main currency.
339
340 $payment->paiementid = $paiementid;
341 $payment->num_payment = $invoice->ref;
342
343 if ($pay != "delayed") {
344 $res = $payment->create($user);
345 if ($res < 0) {
346 $error++;
347 dol_htmloutput_errors($langs->trans('Error').' '.$payment->error, $payment->errors, 1);
348 } else {
349 $res = $payment->addPaymentToBank($user, 'payment', '(CustomerInvoicePayment)', $bankaccount, '', '');
350 if ($res < 0) {
351 $error++;
352 dol_htmloutput_errors($langs->trans('ErrorNoPaymentDefined').' '.$payment->error, $payment->errors, 1);
353 }
354 }
355 $remaintopay = $invoice->getRemainToPay(); // Recalculate remain to pay after the payment is recorded
356 } elseif (getDolGlobalInt("TAKEPOS_DELAYED_TERMS")) {
357 $invoice->setPaymentTerms(getDolGlobalInt("TAKEPOS_DELAYED_TERMS"));
358 }
359 }
360
361 if ($remaintopay == 0) {
362 dol_syslog("Invoice is paid, so we set it to status Paid");
363 $result = $invoice->setPaid($user);
364 if ($result > 0) {
365 $invoice->paye = 1;
366 $invoice->status = $invoice::STATUS_CLOSED;
367 }
368 // set payment method
369 $invoice->setPaymentMethods($paiementid);
370 } else {
371 dol_syslog("Invoice is not paid, remain to pay = ".$remaintopay);
372 }
373 } else {
374 dol_htmloutput_errors($invoice->error, $invoice->errors, 1);
375 }
376
377 $warehouseid = 0;
378 // Update stock for batch products
379 if (!$error && $res >= 0) {
380 if (isModEnabled('stock') && isModEnabled('productbatch') && $allowstockchange) {
381 // Update stocks
382 dol_syslog("Now we record the stock movement for each qualified line");
383
384 // The case !isModEnabled('productbatch') was processed few lines before.
385 require_once DOL_DOCUMENT_ROOT . "/product/stock/class/mouvementstock.class.php";
386 $constantforkey = 'CASHDESK_ID_WAREHOUSE'.$_SESSION["takeposterminal"];
387 $inventorycode = dol_print_date(dol_now(), 'dayhourlog');
388 // Label of stock movement will be "TakePOS - Invoice XXXX"
389 $labeltakeposmovement = 'TakePOS - '.$langs->trans("Invoice").' '.$invoice->ref;
390
391 foreach ($invoice->lines as $line) {
392 // Use the warehouse id defined on invoice line else in the setup
393 $warehouseid = ($line->fk_warehouse ? $line->fk_warehouse : getDolGlobalInt($constantforkey));
394
395 // var_dump('fk_product='.$line->fk_product.' batch='.$line->batch.' warehouse='.$line->fk_warehouse.' qty='.$line->qty);
396 if ($line->batch != '' && $warehouseid > 0) {
397 $prod_batch = new Productbatch($db);
398 $prod_batch->find(0, '', '', $line->batch, $warehouseid);
399
400 $mouvP = new MouvementStock($db);
401 $mouvP->setOrigin($invoice->element, $invoice->id);
402
403 $res = $mouvP->livraison($user, $line->fk_product, $warehouseid, $line->qty, $line->price, $labeltakeposmovement, '', '', '', $prod_batch->batch, $prod_batch->id, $inventorycode);
404 if ($res < 0) {
405 dol_htmloutput_errors($mouvP->error, $mouvP->errors, 1);
406 $error++;
407 }
408 } else {
409 $mouvP = new MouvementStock($db);
410 $mouvP->setOrigin($invoice->element, $invoice->id);
411
412 $res = $mouvP->livraison($user, $line->fk_product, $warehouseid, $line->qty, $line->price, $labeltakeposmovement, '', '', '', '', 0, $inventorycode);
413 if ($res < 0) {
414 dol_htmloutput_errors($mouvP->error, $mouvP->errors, 1);
415 $error++;
416 }
417 }
418 }
419 }
420 }
421
422 if (!$error && $res >= 0) {
423 $db->commit();
424 } else {
425 $db->rollback();
426 }
427 }
428 $creditnote = null;
429 if ($action == 'creditnote' && $user->hasRight('facture', 'creer')) {
430 $db->begin();
431
432 $creditnote = new Facture($db);
433 $creditnote->socid = $invoice->socid;
434 $creditnote->date = dol_now();
435 $creditnote->module_source = 'takepos';
436 $creditnote->pos_source = isset($_SESSION["takeposterminal"]) ? $_SESSION["takeposterminal"] : '' ;
437 $creditnote->type = Facture::TYPE_CREDIT_NOTE;
438 $creditnote->fk_facture_source = $placeid;
439 //$creditnote->remise_absolue = $invoice->remise_absolue;
440 //$creditnote->remise_percent = $invoice->remise_percent;
441 $creditnote->create($user);
442
443 $fk_parent_line = 0; // Initialise
444
445 foreach ($invoice->lines as $line) {
446 // Reset fk_parent_line for no child products and special product
447 if (($line->product_type != 9 && empty($line->fk_parent_line)) || $line->product_type == 9) {
448 $fk_parent_line = 0;
449 }
450
451 if (getDolGlobalInt('INVOICE_USE_SITUATION')) {
452 if (!empty($invoice->situation_counter)) {
453 $source_fk_prev_id = $line->fk_prev_id; // temporary storing situation invoice fk_prev_id
454 $line->fk_prev_id = $line->id; // The new line of the new credit note we are creating must be linked to the situation invoice line it is created from
455 if (!empty($invoice->tab_previous_situation_invoice)) {
456 // search the last standard invoice in cycle and the possible credit note between this last and invoice
457 // TODO Move this out of loop of $invoice->lines
458 $tab_jumped_credit_notes = array();
459 $lineIndex = count($invoice->tab_previous_situation_invoice) - 1;
460 $searchPreviousInvoice = true;
461 while ($searchPreviousInvoice) {
462 if ($invoice->tab_previous_situation_invoice[$lineIndex]->situation_cycle_ref || $lineIndex < 1) {
463 $searchPreviousInvoice = false; // find, exit;
464 break;
465 } else {
466 if ($invoice->tab_previous_situation_invoice[$lineIndex]->type == Facture::TYPE_CREDIT_NOTE) {
467 $tab_jumped_credit_notes[$lineIndex] = $invoice->tab_previous_situation_invoice[$lineIndex]->id;
468 }
469 $lineIndex--; // go to previous invoice in cycle
470 }
471 }
472
473 $maxPrevSituationPercent = 0;
474 foreach ($invoice->tab_previous_situation_invoice[$lineIndex]->lines as $prevLine) {
475 if ($prevLine->id == $source_fk_prev_id) {
476 $maxPrevSituationPercent = max($maxPrevSituationPercent, $prevLine->situation_percent);
477
478 //$line->subprice = $line->subprice - $prevLine->subprice;
479 $line->total_ht -= $prevLine->total_ht;
480 $line->total_tva -= $prevLine->total_tva;
481 $line->total_ttc -= $prevLine->total_ttc;
482 $line->total_localtax1 -= $prevLine->total_localtax1;
483 $line->total_localtax2 -= $prevLine->total_localtax2;
484
485 $line->multicurrency_subprice -= $prevLine->multicurrency_subprice;
486 $line->multicurrency_total_ht -= $prevLine->multicurrency_total_ht;
487 $line->multicurrency_total_tva -= $prevLine->multicurrency_total_tva;
488 $line->multicurrency_total_ttc -= $prevLine->multicurrency_total_ttc;
489 }
490 }
491
492 // prorata
493 $line->situation_percent = $maxPrevSituationPercent - $line->situation_percent;
494
495 //print 'New line based on invoice id '.$invoice->tab_previous_situation_invoice[$lineIndex]->id.' fk_prev_id='.$source_fk_prev_id.' will be fk_prev_id='.$line->fk_prev_id.' '.$line->total_ht.' '.$line->situation_percent.'<br>';
496
497 // If there is some credit note between last situation invoice and invoice used for credit note generation (note: credit notes are stored as delta)
498 $maxPrevSituationPercent = 0;
499 foreach ($tab_jumped_credit_notes as $index => $creditnoteid) {
500 foreach ($invoice->tab_previous_situation_invoice[$index]->lines as $prevLine) {
501 if ($prevLine->fk_prev_id == $source_fk_prev_id) {
502 $maxPrevSituationPercent = $prevLine->situation_percent;
503
504 $line->total_ht -= $prevLine->total_ht;
505 $line->total_tva -= $prevLine->total_tva;
506 $line->total_ttc -= $prevLine->total_ttc;
507 $line->total_localtax1 -= $prevLine->total_localtax1;
508 $line->total_localtax2 -= $prevLine->total_localtax2;
509
510 $line->multicurrency_subprice -= $prevLine->multicurrency_subprice;
511 $line->multicurrency_total_ht -= $prevLine->multicurrency_total_ht;
512 $line->multicurrency_total_tva -= $prevLine->multicurrency_total_tva;
513 $line->multicurrency_total_ttc -= $prevLine->multicurrency_total_ttc;
514 }
515 }
516 }
517
518 // prorata
519 $line->situation_percent += $maxPrevSituationPercent;
520
521 //print 'New line based on invoice id '.$invoice->tab_previous_situation_invoice[$lineIndex]->id.' fk_prev_id='.$source_fk_prev_id.' will be fk_prev_id='.$line->fk_prev_id.' '.$line->total_ht.' '.$line->situation_percent.'<br>';
522 }
523 }
524 }
525
526 // We update field for credit notes
527 $line->fk_facture = $creditnote->id;
528 $line->fk_parent_line = $fk_parent_line;
529
530 $line->subprice = -$line->subprice; // invert price for object
531 // $line->pa_ht = $line->pa_ht; // we chose to have the buy/cost price always positive, so no inversion of the sign here
532 $line->total_ht = -$line->total_ht;
533 $line->total_tva = -$line->total_tva;
534 $line->total_ttc = -$line->total_ttc;
535 $line->total_localtax1 = -$line->total_localtax1;
536 $line->total_localtax2 = -$line->total_localtax2;
537
538 $line->multicurrency_subprice = -$line->multicurrency_subprice;
539 $line->multicurrency_total_ht = -$line->multicurrency_total_ht;
540 $line->multicurrency_total_tva = -$line->multicurrency_total_tva;
541 $line->multicurrency_total_ttc = -$line->multicurrency_total_ttc;
542
543 $result = $line->insert(0, 1); // When creating credit note with same lines than source, we must ignore error if discount already linked
544
545 $creditnote->lines[] = $line; // insert new line in current object
546
547 // Defined the new fk_parent_line
548 if ($result > 0 && $line->product_type == 9) {
549 $fk_parent_line = $result;
550 }
551 }
552 $creditnote->update_price(1);
553
554 // The credit note is create here. We must now validate it.
555
556 $constantforkey = 'CASHDESK_NO_DECREASE_STOCK'.(isset($_SESSION["takeposterminal"]) ? $_SESSION["takeposterminal"] : '');
557 $allowstockchange = getDolGlobalString($constantforkey) != "1";
558
559 if (isModEnabled('stock') && !isModEnabled('productbatch') && $allowstockchange) {
560 // If module stock is enabled and we do not setup takepo to disable stock decrease
561 // The case for isModEnabled('productbatch') is processed few lines later.
562 $savconst = getDolGlobalString('STOCK_CALCULATE_ON_BILL');
563 $conf->global->STOCK_CALCULATE_ON_BILL = 1; // We force setup to have update of stock on invoice validation/unvalidation
564
565 $constantforkey = 'CASHDESK_ID_WAREHOUSE'.(isset($_SESSION["takeposterminal"]) ? $_SESSION["takeposterminal"] : '');
566
567 dol_syslog("Validate invoice with stock change into warehouse defined into constant ".$constantforkey." = ".getDolGlobalString($constantforkey)." or warehouseid= ".$warehouseid." if defined.");
568
569 // Validate invoice with stock change into warehouse getDolGlobalInt($constantforkey)
570 // Label of stock movement will be the same as when we validate invoice "Invoice XXXX validated"
571 $batch_rule = 0; // Module productbatch is disabled here, so no need for a batch_rule.
572 $res = $creditnote->validate($user, '', getDolGlobalInt($constantforkey), 0, $batch_rule);
573 if ($res < 0) {
574 $error++;
575 dol_htmloutput_errors($creditnote->error, $creditnote->errors, 1);
576 }
577
578 // Restore setup
579 $conf->global->STOCK_CALCULATE_ON_BILL = $savconst;
580 } else {
581 $res = $creditnote->validate($user);
582 }
583
584 // Update stock for batch products
585 if (!$error && $res >= 0) {
586 if (isModEnabled('stock') && isModEnabled('productbatch') && $allowstockchange) {
587 // Update stocks
588 dol_syslog("Now we record the stock movement for each qualified line");
589
590 // The case !isModEnabled('productbatch') was processed few lines before.
591 require_once DOL_DOCUMENT_ROOT . "/product/stock/class/mouvementstock.class.php";
592 $constantforkey = 'CASHDESK_ID_WAREHOUSE'.$_SESSION["takeposterminal"];
593 $inventorycode = dol_print_date(dol_now(), 'dayhourlog');
594 // Label of stock movement will be "TakePOS - Invoice XXXX"
595 $labeltakeposmovement = 'TakePOS - '.$langs->trans("CreditNote").' '.$creditnote->ref;
596
597 foreach ($creditnote->lines as $line) {
598 // Use the warehouse id defined on invoice line else in the setup
599 $warehouseid = ($line->fk_warehouse ? $line->fk_warehouse : getDolGlobalInt($constantforkey));
600 //var_dump('fk_product='.$line->fk_product.' batch='.$line->batch.' warehouse='.$line->fk_warehouse.' qty='.$line->qty);exit;
601
602 if ($line->batch != '' && $warehouseid > 0) {
603 //$prod_batch = new Productbatch($db);
604 //$prod_batch->find(0, '', '', $line->batch, $warehouseid);
605
606 $mouvP = new MouvementStock($db);
607 $mouvP->setOrigin($creditnote->element, $creditnote->id);
608
609 $res = $mouvP->reception($user, $line->fk_product, $warehouseid, $line->qty, $line->price, $labeltakeposmovement, '', '', $line->batch, '', 0, $inventorycode);
610 if ($res < 0) {
611 dol_htmloutput_errors($mouvP->error, $mouvP->errors, 1);
612 $error++;
613 }
614 } else {
615 $mouvP = new MouvementStock($db);
616 $mouvP->setOrigin($creditnote->element, $creditnote->id);
617
618 $res = $mouvP->reception($user, $line->fk_product, $warehouseid, $line->qty, $line->price, $labeltakeposmovement, '', '', '', '', 0, $inventorycode);
619 if ($res < 0) {
620 dol_htmloutput_errors($mouvP->error, $mouvP->errors, 1);
621 $error++;
622 }
623 }
624 }
625 }
626 }
627
628 if (!$error && $res >= 0) {
629 $db->commit();
630 } else {
631 $creditnote->id = $placeid; // Creation has failed, we reset to ID of source invoice so we go back to this one in action=history
632 $db->rollback();
633 }
634 }
635
636 if (($action == 'history' || $action == 'creditnote') && $user->hasRight('takepos', 'run')) {
637 if ($action == 'creditnote' && $creditnote !== null && $creditnote->id > 0) { // Test on permission already done
638 $placeid = $creditnote->id;
639 } else {
640 $placeid = GETPOSTINT('placeid');
641 }
642
643 $invoice = new Facture($db);
644 $invoice->fetch($placeid);
645 }
646
647 // If we add a line and no invoice yet, we create the invoice
648 if (($action == "addline" || $action == "freezone") && $placeid == 0 && ($user->hasRight('takepos', 'run') || defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE'))) {
649 $invoice->socid = getDolGlobalInt($constforcompanyid);
650
651 $dolnowtzuserrel = dol_now('tzuserrel'); // If user is 02 january 22:00, we want to store '02 january'
652 $monthuser = dol_print_date($dolnowtzuserrel, '%m', 'gmt');
653 $dayuser = dol_print_date($dolnowtzuserrel, '%d', 'gmt');
654 $yearuser = dol_print_date($dolnowtzuserrel, '%Y', 'gmt');
655 $dateinvoice = dol_mktime(0, 0, 0, (int) $monthuser, (int) $dayuser, (int) $yearuser, 'tzserver'); // If we enter the 02 january, we need to save the 02 january for server
656
657 include_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
658 $invoice->date = $dateinvoice; // Invoice::create() needs a date with no hours
659
660 /*
661 print "monthuser=".$monthuser." dayuser=".$dayuser." yearuser=".$yearuser.'<br>';
662 print '---<br>';
663 print 'TZSERVER: '.dol_print_date(dol_now('tzserver'), 'dayhour', 'gmt').'<br>';
664 print 'TZUSER: '.dol_print_date(dol_now('tzuserrel'), 'dayhour', 'gmt').'<br>';
665 print 'GMT: '.dol_print_date(dol_now('gmt'), 'dayhour', 'gmt').'<br>'; // Hour in greenwich
666 print '---<br>';
667 print dol_print_date($invoice->date, 'dayhour', 'gmt').'<br>';
668 print "IN SQL, we will got: ".dol_print_date($db->idate($invoice->date), 'dayhour', 'gmt').'<br>';
669 print dol_print_date($db->idate($invoice->date, 'gmt'), 'dayhour', 'gmt').'<br>';
670 */
671
672 $invoice->module_source = 'takepos';
673 $invoice->pos_source = isset($_SESSION["takeposterminal"]) ? $_SESSION["takeposterminal"] : '' ;
674 $invoice->entity = !empty($_SESSION["takeposinvoiceentity"]) ? $_SESSION["takeposinvoiceentity"] : $conf->entity;
675
676 if ($invoice->socid <= 0) {
677 $langs->load('errors');
678 dol_htmloutput_errors($langs->trans("ErrorModuleSetupNotComplete", "TakePos"), [], 1);
679 } else {
680 $db->begin();
681
682 // Create invoice
683 $placeid = $invoice->create($user);
684
685 if ($placeid < 0) {
686 dol_htmloutput_errors($invoice->error, $invoice->errors, 1);
687 }
688 $sql = "UPDATE ".MAIN_DB_PREFIX."facture";
689 $sql .= " SET ref='(PROV-POS".$_SESSION["takeposterminal"]."-".$place.")'";
690 $sql .= " WHERE rowid = ".((int) $placeid);
691 $resql = $db->query($sql);
692 if (!$resql) {
693 $error++;
694 }
695
696 if (!$error) {
697 $db->commit();
698 } else {
699 $db->rollback();
700 }
701 }
702 }
703
704 $tva_npr = 0;
705 // If we add a line by click on product (invoice exists here because it was created juste before if it didn't exists)
706 if ($action == "addline" && ($user->hasRight('takepos', 'run') || defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE'))) {
707 $prod = new Product($db);
708 $prod->fetch($idproduct);
709
710 $customer = new Societe($db);
711 $customer->fetch($invoice->socid);
712
713 $datapriceofproduct = $prod->getSellPrice($mysoc, $customer, 0);
714
715 $qty = GETPOSTISSET('qty') ? GETPOSTFLOAT('qty') : 1;
716 $price = $datapriceofproduct['pu_ht'];
717 $price_ttc = $datapriceofproduct['pu_ttc'];
718 //$price_min = $datapriceofproduct['price_min'];
719 $price_base_type = empty($datapriceofproduct['price_base_type']) ? 'HT' : $datapriceofproduct['price_base_type'];
720 $tva_tx = $datapriceofproduct['tva_tx'];
721 $tva_npr = (int) $datapriceofproduct['tva_npr'];
722
723 // Local Taxes
724 $localtax1_tx = get_localtax($tva_tx, 1, $customer, $mysoc, $tva_npr);
725 $localtax2_tx = get_localtax($tva_tx, 2, $customer, $mysoc, $tva_npr);
726
727
728 if (isModEnabled('productbatch') && isModEnabled('stock')) {
729 $batch = GETPOST('batch', 'alpha');
730
731 if (!empty($batch)) { // We have just clicked on a batch number, we will execute action=setbatch later...
732 $action = "setbatch";
733 } elseif ($prod->status_batch > 0) {
734 // If product need a lot/serial, we show the list of lot/serial available for the product...
735
736 // Set nb of suggested with nb of batch into the warehouse of the terminal
737 $nbofsuggested = 0;
738 $prod->load_stock('warehouseopen');
739
740 $constantforkey = 'CASHDESK_ID_WAREHOUSE'.$_SESSION["takeposterminal"];
741 $warehouseid = getDolGlobalInt($constantforkey);
742
743 //var_dump($prod->stock_warehouse);
744 foreach ($prod->stock_warehouse as $tmpwarehouseid => $tmpval) {
745 if (getDolGlobalInt($constantforkey) && $tmpwarehouseid != getDolGlobalInt($constantforkey)) {
746 // Product to select is not on the warehouse configured for terminal, so we ignore this warehouse
747 continue;
748 }
749 if (!empty($prod->stock_warehouse[$tmpwarehouseid]) && is_array($prod->stock_warehouse[$tmpwarehouseid]->detail_batch)) {
750 if (is_object($prod->stock_warehouse[$tmpwarehouseid]) && count($prod->stock_warehouse[$tmpwarehouseid]->detail_batch)) {
751 foreach ($prod->stock_warehouse[$tmpwarehouseid]->detail_batch as $dbatch) {
752 $nbofsuggested++;
753 }
754 }
755 }
756 }
757 //var_dump($prod->stock_warehouse);
758
759 echo "<script>\n";
760 echo "function addbatch(batch, warehouseid) {\n";
761 echo "console.log('We add batch '+batch+' from warehouse id '+warehouseid);\n";
762 echo '$("#poslines").load("'.DOL_URL_ROOT.'/takepos/invoice.php?action=addline&batch="+encodeURI(batch)+"&warehouseid="+warehouseid+"&place='.$place.'&idproduct='.$idproduct.'&token='.newToken().'", function() {});'."\n";
763 echo "}\n";
764 echo "</script>\n";
765
766 $suggestednb = 1;
767 echo "<center>".$langs->trans("SearchIntoBatch").": <b> $nbofsuggested </b></center><br><table>";
768 foreach ($prod->stock_warehouse as $tmpwarehouseid => $tmpval) {
769 if (getDolGlobalInt($constantforkey) && $tmpwarehouseid != getDolGlobalInt($constantforkey)) {
770 // Not on the forced warehouse, so we ignore this warehouse
771 continue;
772 }
773 if (!empty($prod->stock_warehouse[$tmpwarehouseid]) && is_array($prod->stock_warehouse[$tmpwarehouseid]->detail_batch)) {
774 foreach ($prod->stock_warehouse[$tmpwarehouseid]->detail_batch as $dbatch) { // $dbatch is instance of Productbatch
775 $batchStock = + $dbatch->qty; // To get a numeric
776 $quantityToBeDelivered = 1;
777 $deliverableQty = min($quantityToBeDelivered, $batchStock);
778 print '<tr>';
779 print '<!-- subj='.$suggestednb.'/'.$nbofsuggested.' -->';
780 print '<!-- Show details of lot/serial in warehouseid='.$tmpwarehouseid.' -->';
781 print '<td class="left">';
782 $detail = '';
783 $detail .= '<span class="opacitymedium">'.$langs->trans("LotSerial").':</span> '.$dbatch->batch;
784 //if (!getDolGlobalString('PRODUCT_DISABLE_SELLBY')) {
785 //$detail .= ' - '.$langs->trans("SellByDate").': '.dol_print_date($dbatch->sellby, "day");
786 //}
787 //if (!getDolGlobalString('PRODUCT_DISABLE_EATBY')) {
788 //$detail .= ' - '.$langs->trans("EatByDate").': '.dol_print_date($dbatch->eatby, "day");
789 //}
790 $detail .= '</td><td>';
791 $detail .= '<span class="opacitymedium">'.$langs->trans("Qty").':</span> '.$dbatch->qty;
792 $detail .= '</td><td>';
793 $detail .= ' <button class="marginleftonly" onclick="addbatch(\''.dol_escape_js($dbatch->batch).'\', '.$tmpwarehouseid.')">'.$langs->trans("Select")."</button>";
794 $detail .= '<br>';
795 print $detail;
796
797 $quantityToBeDelivered -= $deliverableQty;
798 if ($quantityToBeDelivered < 0) {
799 $quantityToBeDelivered = 0;
800 }
801 $suggestednb++;
802 print '</td></tr>';
803 }
804 }
805 }
806 print "</table>";
807
808 print '</body></html>';
809 exit;
810 }
811 }
812
813
814 if (getDolGlobalString('TAKEPOS_SUPPLEMENTS')) {
815 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
816 $cat = new Categorie($db);
817 $categories = $cat->containing($idproduct, 'product');
818 $found = (array_search(getDolGlobalInt('TAKEPOS_SUPPLEMENTS_CATEGORY'), array_column($categories, 'id')));
819 if ($found !== false) { // If this product is a supplement
820 $sql = "SELECT fk_parent_line FROM ".MAIN_DB_PREFIX."facturedet where rowid = ".((int) $selectedline);
821 $resql = $db->query($sql);
822 $row = $db->fetch_array($resql);
823 if ($row[0] == null) {
824 $parent_line = $selectedline;
825 } else {
826 $parent_line = $row[0]; //If the parent line is already a supplement, add the supplement to the main product
827 }
828 }
829 }
830
831 $err = 0;
832 // Group if enabled. Skip group if line already sent to the printer
833 if (getDolGlobalString('TAKEPOS_GROUP_SAME_PRODUCT')) {
834 foreach ($invoice->lines as $line) {
835 if ($line->product_ref == $prod->ref) {
836 if ($line->special_code == 4) {
837 continue;
838 } // If this line is sended to printer create new line
839 // check if qty in stock
840 if (getDolGlobalString('TAKEPOS_QTY_IN_STOCK') && (($line->qty + $qty) > $prod->stock_reel)) {
841 $invoice->error = $langs->trans("ErrorStockIsNotEnough");
842 dol_htmloutput_errors($invoice->error, $invoice->errors, 1);
843 $err++;
844 break;
845 }
846 $result = $invoice->updateline($line->id, $line->desc, $line->subprice, $line->qty + $qty, $line->remise_percent, $line->date_start, $line->date_end, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->product_type, $line->fk_parent_line, 0, $line->fk_fournprice, $line->pa_ht, $line->label, $line->special_code, $line->array_options, $line->situation_percent, $line->fk_unit);
847 if ($result < 0) {
848 dol_htmloutput_errors($invoice->error, $invoice->errors, 1);
849 } else {
850 $idoflineadded = $line->id;
851 }
852 break;
853 }
854 }
855 }
856 if ($idoflineadded <= 0 && empty($err)) {
857 $invoice->fetch_thirdparty();
858 $array_options = array();
859
860 $line = array('description' => $prod->description, 'price' => $price, 'tva_tx' => $tva_tx, 'localtax1_tx' => $localtax1_tx, 'localtax2_tx' => $localtax2_tx, 'remise_percent' => $customer->remise_percent, 'price_ttc' => $price_ttc, 'array_options' => $array_options);
861
862 /* setup of margin calculation */
863 if (getDolGlobalString('MARGIN_TYPE')) {
864 if (getDolGlobalString('MARGIN_TYPE') == 'pmp' && !empty($prod->pmp)) {
865 $line['fk_fournprice'] = null;
866 $line['pa_ht'] = $prod->pmp;
867 } elseif (getDolGlobalString('MARGIN_TYPE') == 'costprice' && !empty($prod->cost_price)) {
868 $line['fk_fournprice'] = null;
869 $line['pa_ht'] = $prod->cost_price;
870 } else {
871 // default is fournprice
872 require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php';
873 $pf = new ProductFournisseur($db);
874 if ($pf->find_min_price_product_fournisseur($idproduct, $qty) > 0) {
875 $line['fk_fournprice'] = $pf->product_fourn_price_id;
876 $line['pa_ht'] = $pf->fourn_unitprice_with_discount;
877 if (getDolGlobalString('PRODUCT_CHARGES') && $pf->fourn_charges > 0) {
878 $line['pa_ht'] += (float) $pf->fourn_charges / $pf->fourn_qty;
879 }
880 }
881 }
882 }
883
884 // complete line by hook
885 $parameters = array('prod' => $prod, 'line' => $line);
886 $reshook = $hookmanager->executeHooks('completeTakePosAddLine', $parameters, $invoice, $action); // Note that $action and $line may have been modified by some hooks
887 if ($reshook < 0) {
888 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
889 }
890
891
892 if (empty($reshook)) {
893 if (!empty($hookmanager->resArray)) {
894 $line = $hookmanager->resArray;
895 }
896
897 // check if qty in stock
898 if (getDolGlobalString('TAKEPOS_QTY_IN_STOCK') && $qty > $prod->stock_reel) {
899 $invoice->error = $langs->trans("ErrorStockIsNotEnough");
900 dol_htmloutput_errors($invoice->error, $invoice->errors, 1);
901 $err++;
902 }
903
904 if (empty($err)) {
905 $idoflineadded = $invoice->addline($line['description'], $line['price'], $qty, $line['tva_tx'], $line['localtax1_tx'], $line['localtax2_tx'], $idproduct, (float) $line['remise_percent'], '', 0, 0, 0, 0, $price_base_type, $line['price_ttc'], $prod->type, -1, 0, '', 0, (empty($parent_line) ? '' : $parent_line), (empty($line['fk_fournprice']) ? 0 : $line['fk_fournprice']), (empty($line['pa_ht']) ? '' : $line['pa_ht']), '', $line['array_options'], 100, 0, null, 0);
906 }
907 }
908
909 if (getDolGlobalString('TAKEPOS_CUSTOMER_DISPLAY')) {
910 $CUSTOMER_DISPLAY_line1 = $prod->label;
911 $CUSTOMER_DISPLAY_line2 = price($price_ttc);
912 }
913 }
914
915 $invoice->fetch($placeid);
916 }
917
918 // If we add a line by submitting freezone form (invoice exists here because it was created just before if it didn't exist)
919 if ($action == "freezone" && $user->hasRight('takepos', 'run')) {
920 $customer = new Societe($db);
921 $customer->fetch($invoice->socid);
922
923 $tva_tx = GETPOST('tva_tx', 'alpha');
924 if ($tva_tx != '') {
925 if (!preg_match('/\‍((.*)\‍)/', $tva_tx)) {
926 $tva_tx = price2num($tva_tx);
927 }
928 } else {
929 $tva_tx = get_default_tva($mysoc, $customer);
930 }
931
932 // Local Taxes
933 $localtax1_tx = get_localtax($tva_tx, 1, $customer, $mysoc, $tva_npr);
934 $localtax2_tx = get_localtax($tva_tx, 2, $customer, $mysoc, $tva_npr);
935
936 $res = $invoice->addline($desc, $number, 1, $tva_tx, $localtax1_tx, $localtax2_tx, 0, 0, '', 0, 0, 0, 0, getDolGlobalInt('TAKEPOS_DISCOUNT_TTC') ? ($number >= 0 ? 'HT' : 'TTC') : (getDolGlobalInt('TAKEPOS_CHANGE_PRICE_HT') ? 'HT' : 'TTC'), $number, 0, -1, 0, '', 0, 0, 0, 0, '', array(), 100, 0, null, 0);
937 if ($res < 0) {
938 dol_htmloutput_errors($invoice->error, $invoice->errors, 1);
939 }
940 $invoice->fetch($placeid);
941 }
942
943 if ($action == "addnote" && ($user->hasRight('takepos', 'run') || defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE'))) {
944 $desc = GETPOST('addnote', 'alpha');
945 if ($idline == 0) {
946 $invoice->update_note($desc, '_public');
947 } else {
948 foreach ($invoice->lines as $line) {
949 if ($line->id == $idline) {
950 $result = $invoice->updateline($line->id, $desc, $line->subprice, $line->qty, $line->remise_percent, $line->date_start, $line->date_end, $line->tva_tx, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->product_type, $line->fk_parent_line, 0, $line->fk_fournprice, $line->pa_ht, $line->label, $line->special_code, $line->array_options, $line->situation_percent, $line->fk_unit);
951 }
952 }
953 }
954 $invoice->fetch($placeid);
955 }
956
957 if ($action == "deleteline" && ($user->hasRight('takepos', 'run') || defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE'))) {
958 /*
959 $permissiontoupdateline = ($user->hasRight('takepos', 'editlines') && ($user->hasRight('takepos', 'editorderedlines') || $line->special_code != "4"));
960 if (defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE')) {
961 if ($invoice->status == $invoice::STATUS_DRAFT && $invoice->pos_source && $invoice->module_source == 'takepos') {
962 $permissiontoupdateline = true;
963 // TODO Add also a test on $_SESSION('publicobjectid'] defined at creation of object
964 // TODO Check also that invoice->ref is (PROV-POS1-2) with 1 = terminal and 2, the table ID
965 }
966 }*/
967
968 if ($idline > 0 && $placeid > 0) { // If invoice exists and line selected. To avoid errors if deleted from another device or no line selected.
969 $invoice->deleteLine($idline);
970 $invoice->fetch($placeid);
971 } elseif ($placeid > 0) { // If invoice exists but no line selected, proceed to delete last line.
972 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."facturedet where fk_facture = ".((int) $placeid)." ORDER BY rowid DESC";
973 $resql = $db->query($sql);
974 $row = $db->fetch_array($resql);
975 $deletelineid = $row[0];
976 $invoice->deleteLine($deletelineid);
977 $invoice->fetch($placeid);
978 }
979
980 if (count($invoice->lines) == 0) {
981 $invoice->delete($user);
982
983 if (defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE')) {
984 header("Location: ".DOL_URL_ROOT."/takepos/public/auto_order.php");
985 } else {
986 header("Location: ".DOL_URL_ROOT."/takepos/invoice.php");
987 }
988 exit;
989 }
990 }
991
992 // Action to delete or discard an invoice
993 if ($action == "delete" && ($user->hasRight('takepos', 'run') || defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE'))) {
994 // $placeid is the invoice id (it differs from place) and is defined if the place is set and
995 // the ref of invoice is '(PROV-POS'.$_SESSION["takeposterminal"].'-'.$place.')', so the fetch at beginning of page works.
996 if ($placeid > 0) {
997 $result = $invoice->fetch($placeid);
998
999 if ($result > 0 && $invoice->status == Facture::STATUS_DRAFT) {
1000 $db->begin();
1001
1002 // We delete the lines
1003 $resdeletelines = 1;
1004 foreach ($invoice->lines as $line) {
1005 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
1006 $tmpres = $invoice->deleteLine($line->id);
1007 if ($tmpres < 0) {
1008 $resdeletelines = 0;
1009 break;
1010 }
1011 }
1012
1013 $sql = "UPDATE ".MAIN_DB_PREFIX."facture";
1014 $varforconst = 'CASHDESK_ID_THIRDPARTY'.$_SESSION["takeposterminal"];
1015 $sql .= " SET fk_soc = ".((int) getDolGlobalString($varforconst)).", ";
1016 $sql .= " datec = '".$db->idate(dol_now())."'";
1017 $sql .= " WHERE entity IN (".getEntity('invoice').")";
1018 $sql .= " AND ref = '(PROV-POS".$db->escape($_SESSION["takeposterminal"]."-".$place).")'";
1019 $resql1 = $db->query($sql);
1020
1021 if ($resdeletelines && $resql1) {
1022 $db->commit();
1023 } else {
1024 $db->rollback();
1025 }
1026
1027 $invoice->fetch($placeid);
1028 }
1029 }
1030 }
1031
1032 if ($action == "updateqty") { // Test on permission is done later
1033 foreach ($invoice->lines as $line) {
1034 if ($line->id == $idline) {
1035 $permissiontoupdateline = ($user->hasRight('takepos', 'editlines') && ($user->hasRight('takepos', 'editorderedlines') || $line->special_code != "4"));
1036 if (defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE')) {
1037 if ($invoice->status == $invoice::STATUS_DRAFT && $invoice->pos_source && $invoice->module_source == 'takepos') {
1038 $permissiontoupdateline = true;
1039 // TODO Add also a test on $_SESSION('publicobjectid'] defined at creation of object
1040 // TODO Check also that invoice->ref is (PROV-POS1-2) with 1 = terminal and 2, the table ID
1041 }
1042 }
1043 if (!$permissiontoupdateline) {
1044 dol_htmloutput_errors($langs->trans("NotEnoughPermissions", "TakePos").' - No permission to updateqty', [], 1);
1045 } else {
1046 $vatratecode = $line->tva_tx;
1047 if ($line->vat_src_code) {
1048 $vatratecode .= ' ('.$line->vat_src_code.')';
1049 }
1050
1051 $result = $invoice->updateline($line->id, $line->desc, $line->subprice, $number, $line->remise_percent, $line->date_start, $line->date_end, $vatratecode, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->product_type, $line->fk_parent_line, 0, $line->fk_fournprice, $line->pa_ht, $line->label, $line->special_code, $line->array_options, $line->situation_percent, $line->fk_unit);
1052 }
1053 }
1054 }
1055
1056 $invoice->fetch($placeid);
1057 }
1058
1059 if ($action == "updateprice") { // Test on permission is done later
1060 $customer = new Societe($db);
1061 $customer->fetch($invoice->socid);
1062
1063 foreach ($invoice->lines as $line) {
1064 if ($line->id == $idline) {
1065 $prod = new Product($db);
1066 $prod->fetch($line->fk_product);
1067 $datapriceofproduct = $prod->getSellPrice($mysoc, $customer, 0);
1068 $price_min = $datapriceofproduct['price_min'];
1069 $usercanproductignorepricemin = ((getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && !$user->hasRight('produit', 'ignore_price_min_advance')) || !getDolGlobalString('MAIN_USE_ADVANCED_PERMS'));
1070
1071 $vatratecleaned = $line->tva_tx;
1072 $reg = array();
1073 if (preg_match('/^(.*)\s*\‍((.*)\‍)$/', (string) $line->tva_tx, $reg)) { // If vat is "xx (yy)"
1074 $vatratecleaned = trim($reg[1]);
1075 //$vatratecode = $reg[2];
1076 }
1077
1078 $pu_ht = price2num((float) price2num($number, 'MU') / (1 + ((float) $vatratecleaned / 100)), 'MU');
1079 // Check min price
1080 if ($usercanproductignorepricemin && (!empty($price_min) && ((float) price2num($pu_ht) * (1 - (float) price2num($line->remise_percent) / 100) < price2num($price_min)))) {
1081 $langs->load("products");
1082 dol_htmloutput_errors($langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, -1, $conf->currency)));
1083 // echo $langs->trans("CantBeLessThanMinPrice");
1084 } else {
1085 $permissiontoupdateline = ($user->hasRight('takepos', 'editlines') && ($user->hasRight('takepos', 'editorderedlines') || $line->special_code != "4"));
1086 if (defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE')) {
1087 if ($invoice->status == $invoice::STATUS_DRAFT && $invoice->pos_source && $invoice->module_source == 'takepos') {
1088 $permissiontoupdateline = true;
1089 // TODO Add also a test on $_SESSION('publicobjectid'] defined at creation of object
1090 // TODO Check also that invoice->ref is (PROV-POS1-2) with 1 = terminal and 2, the table ID
1091 }
1092 }
1093
1094 $vatratecode = $line->tva_tx;
1095 if ($line->vat_src_code) {
1096 $vatratecode .= ' ('.$line->vat_src_code.')';
1097 }
1098
1099 if (!$permissiontoupdateline) {
1100 dol_htmloutput_errors($langs->trans("NotEnoughPermissions", "TakePos").' - No permission to updateprice', [], 1);
1101 } elseif (getDolGlobalInt('TAKEPOS_CHANGE_PRICE_HT') == 1) {
1102 $result = $invoice->updateline($line->id, $line->desc, $number, $line->qty, $line->remise_percent, $line->date_start, $line->date_end, $vatratecode, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->product_type, $line->fk_parent_line, 0, $line->fk_fournprice, $line->pa_ht, $line->label, $line->special_code, $line->array_options, $line->situation_percent, $line->fk_unit);
1103 } else {
1104 $result = $invoice->updateline($line->id, $line->desc, $number, $line->qty, $line->remise_percent, $line->date_start, $line->date_end, $vatratecode, $line->localtax1_tx, $line->localtax2_tx, 'TTC', $line->info_bits, $line->product_type, $line->fk_parent_line, 0, $line->fk_fournprice, $line->pa_ht, $line->label, $line->special_code, $line->array_options, $line->situation_percent, $line->fk_unit);
1105 }
1106 }
1107 }
1108 }
1109
1110 // Reload data
1111 $invoice->fetch($placeid);
1112 }
1113
1114 if ($action == "updatereduction") { // Test on permission is done later
1115 $customer = new Societe($db);
1116 $customer->fetch($invoice->socid);
1117
1118 foreach ($invoice->lines as $line) {
1119 if ($line->id == $idline) {
1120 dol_syslog("updatereduction Process line ".$line->id.' to apply discount of '.$number.'%');
1121
1122 $prod = new Product($db);
1123 $prod->fetch($line->fk_product);
1124
1125 $datapriceofproduct = $prod->getSellPrice($mysoc, $customer, 0);
1126 $price_min = $datapriceofproduct['price_min'];
1127 $usercanproductignorepricemin = ((getDolGlobalString('MAIN_USE_ADVANCED_PERMS') && !$user->hasRight('produit', 'ignore_price_min_advance')) || !getDolGlobalString('MAIN_USE_ADVANCED_PERMS'));
1128
1129 $pu_ht = price2num($line->subprice / (1 + ($line->tva_tx / 100)), 'MU');
1130
1131 // Check min price
1132 if ($usercanproductignorepricemin && (!empty($price_min) && ((float) price2num($line->subprice) * (1 - (float) price2num($number) / 100) < (float) price2num($price_min)))) {
1133 $langs->load("products");
1134 dol_htmloutput_errors($langs->trans("CantBeLessThanMinPrice", price(price2num($price_min, 'MU'), 0, $langs, 0, 0, -1, $conf->currency)));
1135 } else {
1136 $permissiontoupdateline = ($user->hasRight('takepos', 'editlines') && ($user->hasRight('takepos', 'editorderedlines') || $line->special_code != "4"));
1137 if (defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE')) {
1138 if ($invoice->status == $invoice::STATUS_DRAFT && $invoice->pos_source && $invoice->module_source == 'takepos') {
1139 $permissiontoupdateline = true;
1140 // TODO Add also a test on $_SESSION('publicobjectid'] defined at creation of object
1141 // TODO Check also that invoice->ref is (PROV-POS1-2) with 1 = terminal and 2, the table ID
1142 }
1143 }
1144 if (!$permissiontoupdateline) {
1145 dol_htmloutput_errors($langs->trans("NotEnoughPermissions", "TakePos"), [], 1);
1146 } else {
1147 $vatratecode = $line->tva_tx;
1148 if ($line->vat_src_code) {
1149 $vatratecode .= ' ('.$line->vat_src_code.')';
1150 }
1151 $result = $invoice->updateline($line->id, $line->desc, $line->subprice, $line->qty, $number, $line->date_start, $line->date_end, $vatratecode, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->product_type, $line->fk_parent_line, 0, $line->fk_fournprice, $line->pa_ht, $line->label, $line->special_code, $line->array_options, $line->situation_percent, $line->fk_unit);
1152 }
1153 }
1154 }
1155 }
1156
1157 // Reload data
1158 $invoice->fetch($placeid);
1159 } elseif ($action == 'update_reduction_global' && $user->hasRight('takepos', 'editlines')) {
1160 foreach ($invoice->lines as $line) {
1161 $vatratecode = $line->tva_tx;
1162 if ($line->vat_src_code) {
1163 $vatratecode .= ' ('.$line->vat_src_code.')';
1164 }
1165 $result = $invoice->updateline($line->id, $line->desc, $line->subprice, $line->qty, $number, $line->date_start, $line->date_end, $vatratecode, $line->localtax1_tx, $line->localtax2_tx, 'HT', $line->info_bits, $line->product_type, $line->fk_parent_line, 0, $line->fk_fournprice, $line->pa_ht, $line->label, $line->special_code, $line->array_options, $line->situation_percent, $line->fk_unit);
1166 }
1167
1168 $invoice->fetch($placeid);
1169 }
1170
1171 if ($action == "setbatch" && ($user->hasRight('takepos', 'run') || defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE'))) {
1172 $constantforkey = 'CASHDESK_ID_WAREHOUSE'.$_SESSION["takeposterminal"];
1173 $warehouseid = (GETPOSTINT('warehouseid') > 0 ? GETPOSTINT('warehouseid') : getDolGlobalInt($constantforkey)); // Get the warehouse id from GETPOSTINT('warehouseid'), otherwise use default setup.
1174 $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet SET batch = '".$db->escape($batch)."', fk_warehouse = ".((int) $warehouseid);
1175 $sql .= " WHERE rowid=".((int) $idoflineadded);
1176 $db->query($sql);
1177 }
1178
1179 if ($action == "order" && $placeid != 0 && ($user->hasRight('takepos', 'run') || defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE'))) {
1180 include_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
1181 if ((isModEnabled('receiptprinter') && getDolGlobalInt('TAKEPOS_PRINTER_TO_USE'.$term) > 0) || getDolGlobalString('TAKEPOS_PRINT_METHOD') == "receiptprinter" || getDolGlobalString('TAKEPOS_PRINT_METHOD') == "takeposconnector") {
1182 require_once DOL_DOCUMENT_ROOT.'/core/class/dolreceiptprinter.class.php';
1183 $printer = new dolReceiptPrinter($db);
1184 }
1185
1186 $sql = "SELECT label FROM ".MAIN_DB_PREFIX."takepos_floor_tables where rowid=".((int) $place);
1187 $resql = $db->query($sql);
1188 $row = $db->fetch_object($resql);
1189 $headerorder = '<html><br><b>'.$langs->trans('Place').' '.$row->label.'<br><table width="65%"><thead><tr><th class="left">'.$langs->trans("Label").'</th><th class="right">'.$langs->trans("Qty").'</th></tr></thead><tbody>';
1190 $footerorder = '</tbody></table>'.dol_print_date(dol_now(), 'dayhour').'<br></html>';
1191 $order_receipt_printer1 = "";
1192 $order_receipt_printer2 = "";
1193 $order_receipt_printer3 = "";
1194 $catsprinter1 = explode(';', getDolGlobalString('TAKEPOS_PRINTED_CATEGORIES_1'));
1195 $catsprinter2 = explode(';', getDolGlobalString('TAKEPOS_PRINTED_CATEGORIES_2'));
1196 $catsprinter3 = explode(';', getDolGlobalString('TAKEPOS_PRINTED_CATEGORIES_3'));
1197 $linestoprint = 0;
1198 foreach ($invoice->lines as $line) {
1199 if ($line->special_code == "4") {
1200 continue;
1201 }
1202 $c = new Categorie($db);
1203 $existing = $c->containing($line->fk_product, Categorie::TYPE_PRODUCT, 'id');
1204 $result = array_intersect($catsprinter1, $existing);
1205 $count = count($result);
1206 if (!$line->fk_product) {
1207 $count++; // Print Free-text item (Unassigned printer) to Printer 1
1208 }
1209 if ($count > 0) {
1210 $linestoprint++;
1211 $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet set special_code='1' where rowid=".$line->id; //Set to print on printer 1
1212 $db->query($sql);
1213 $order_receipt_printer1 .= '<tr><td class="left">';
1214 if ($line->fk_product) {
1215 $order_receipt_printer1 .= $line->product_label;
1216 } else {
1217 $order_receipt_printer1 .= $line->description;
1218 }
1219 $order_receipt_printer1 .= '</td><td class="right">'.$line->qty;
1220 if (!empty($line->array_options['options_order_notes'])) {
1221 $order_receipt_printer1 .= "<br>(".$line->array_options['options_order_notes'].")";
1222 }
1223 $order_receipt_printer1 .= '</td></tr>';
1224 }
1225 }
1226 if (((isModEnabled('receiptprinter') && getDolGlobalInt('TAKEPOS_PRINTER_TO_USE'.$term) > 0) || getDolGlobalString('TAKEPOS_PRINT_METHOD') == "receiptprinter" || getDolGlobalString('TAKEPOS_PRINT_METHOD') == "takeposconnector") && $linestoprint > 0 && $printer !== null) {
1227 $invoice->fetch($placeid); //Reload object before send to printer
1228 $printer->orderprinter = 1;
1229 echo "<script>";
1230 echo "var orderprinter1esc='";
1231 $ret = $printer->sendToPrinter($invoice, getDolGlobalInt('TAKEPOS_TEMPLATE_TO_USE_FOR_ORDERS'.$_SESSION["takeposterminal"]), getDolGlobalInt('TAKEPOS_ORDER_PRINTER1_TO_USE'.$_SESSION["takeposterminal"])); // PRINT TO PRINTER 1
1232 echo "';</script>";
1233 }
1234 $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet set special_code='4' where special_code='1' and fk_facture=".$invoice->id; // Set as printed
1235 $db->query($sql);
1236 $invoice->fetch($placeid); //Reload object after set lines as printed
1237 $linestoprint = 0;
1238
1239 foreach ($invoice->lines as $line) {
1240 if ($line->special_code == "4") {
1241 continue;
1242 }
1243 $c = new Categorie($db);
1244 $existing = $c->containing($line->fk_product, Categorie::TYPE_PRODUCT, 'id');
1245 $result = array_intersect($catsprinter2, $existing);
1246 $count = count($result);
1247 if ($count > 0) {
1248 $linestoprint++;
1249 $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet set special_code='2' where rowid=".$line->id; //Set to print on printer 2
1250 $db->query($sql);
1251 $order_receipt_printer2 .= '<tr>'.$line->product_label.'<td class="right">'.$line->qty;
1252 if (!empty($line->array_options['options_order_notes'])) {
1253 $order_receipt_printer2 .= "<br>(".$line->array_options['options_order_notes'].")";
1254 }
1255 $order_receipt_printer2 .= '</td></tr>';
1256 }
1257 }
1258 if (((isModEnabled('receiptprinter') && getDolGlobalInt('TAKEPOS_PRINTER_TO_USE'.$term) > 0) || getDolGlobalString('TAKEPOS_PRINT_METHOD') == "receiptprinter" || getDolGlobalString('TAKEPOS_PRINT_METHOD') == "takeposconnector") && $linestoprint > 0) {
1259 $invoice->fetch($placeid); //Reload object before send to printer
1260 $printer->orderprinter = 2;
1261 echo "<script>";
1262 echo "var orderprinter2esc='";
1263 $ret = $printer->sendToPrinter($invoice, getDolGlobalInt('TAKEPOS_TEMPLATE_TO_USE_FOR_ORDERS'.$_SESSION["takeposterminal"]), getDolGlobalInt('TAKEPOS_ORDER_PRINTER2_TO_USE'.$_SESSION["takeposterminal"])); // PRINT TO PRINTER 2
1264 echo "';</script>";
1265 }
1266 $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet set special_code='4' where special_code='2' and fk_facture=".$invoice->id; // Set as printed
1267 $db->query($sql);
1268 $invoice->fetch($placeid); //Reload object after set lines as printed
1269 $linestoprint = 0;
1270
1271 foreach ($invoice->lines as $line) {
1272 if ($line->special_code == "4") {
1273 continue;
1274 }
1275 $c = new Categorie($db);
1276 $existing = $c->containing($line->fk_product, Categorie::TYPE_PRODUCT, 'id');
1277 $result = array_intersect($catsprinter3, $existing);
1278 $count = count($result);
1279 if ($count > 0) {
1280 $linestoprint++;
1281 $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet set special_code='3' where rowid=".$line->id; //Set to print on printer 3
1282 $db->query($sql);
1283 $order_receipt_printer3 .= '<tr>'.$line->product_label.'<td class="right">'.$line->qty;
1284 if (!empty($line->array_options['options_order_notes'])) {
1285 $order_receipt_printer3 .= "<br>(".$line->array_options['options_order_notes'].")";
1286 }
1287 $order_receipt_printer3 .= '</td></tr>';
1288 }
1289 }
1290 if (((isModEnabled('receiptprinter') && getDolGlobalInt('TAKEPOS_PRINTER_TO_USE'.$term) > 0) || getDolGlobalString('TAKEPOS_PRINT_METHOD') == "receiptprinter" || getDolGlobalString('TAKEPOS_PRINT_METHOD') == "takeposconnector") && $linestoprint > 0 && $printer !== null) {
1291 $invoice->fetch($placeid); //Reload object before send to printer
1292 $printer->orderprinter = 3;
1293 echo "<script>";
1294 echo "var orderprinter3esc='";
1295 $ret = $printer->sendToPrinter($invoice, getDolGlobalInt('TAKEPOS_TEMPLATE_TO_USE_FOR_ORDERS'.$_SESSION["takeposterminal"]), getDolGlobalInt('TAKEPOS_ORDER_PRINTER3_TO_USE'.$_SESSION["takeposterminal"])); // PRINT TO PRINTER 3
1296 echo "';</script>";
1297 }
1298 $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet set special_code='4' where special_code='3' and fk_facture=".$invoice->id; // Set as printed
1299 $db->query($sql);
1300 $invoice->fetch($placeid); //Reload object after set lines as printed
1301 }
1302
1303 $sectionwithinvoicelink = '';
1304 if (($action == "valid" || $action == "history" || $action == 'creditnote' || ($action == 'addline' && $invoice->status == $invoice::STATUS_CLOSED)) && $user->hasRight('takepos', 'run')) {
1305 $sectionwithinvoicelink .= '<!-- Section with invoice link -->'."\n";
1306 $sectionwithinvoicelink .= '<span style="font-size:120%;" class="center inline-block marginbottomonly">';
1307 $sectionwithinvoicelink .= $invoice->getNomUrl(1, '', 0, 0, '', 0, 0, -1, '_backoffice')." - ";
1308 $remaintopay = $invoice->getRemainToPay();
1309 if ($remaintopay > 0) {
1310 $sectionwithinvoicelink .= $langs->trans('RemainToPay').': <span class="amountremaintopay" style="font-size: unset">'.price($remaintopay, 1, $langs, 1, -1, -1, $conf->currency).'</span>';
1311 } else {
1312 $sectionwithinvoicelink .= $invoice->getLibStatut(2);
1313 }
1314
1315 $sectionwithinvoicelink .= '</span><br>';
1316 if (getDolGlobalInt('TAKEPOS_PRINT_INVOICE_DOC_INSTEAD_OF_RECEIPT')) {
1317 $sectionwithinvoicelink .= ' <a target="_blank" class="button" href="' . DOL_URL_ROOT . '/document.php?token=' . newToken() . '&modulepart=facture&file=' . $invoice->ref . '/' . $invoice->ref . '.pdf">Invoice</a>';
1318 } elseif (getDolGlobalString('TAKEPOS_PRINT_METHOD') == "takeposconnector") {
1319 if (getDolGlobalString('TAKEPOS_PRINT_SERVER') && filter_var(getDolGlobalString('TAKEPOS_PRINT_SERVER'), FILTER_VALIDATE_URL) == true) {
1320 $sectionwithinvoicelink .= ' <button id="buttonprint" type="button" onclick="TakeposConnector('.$placeid.')">'.$langs->trans('PrintTicket').'</button>';
1321 } else {
1322 $sectionwithinvoicelink .= ' <button id="buttonprint" type="button" onclick="TakeposPrinting('.$placeid.')">'.$langs->trans('PrintTicket').'</button>';
1323 }
1324 } elseif ((isModEnabled('receiptprinter') && getDolGlobalInt('TAKEPOS_PRINTER_TO_USE'.$term) > 0) || getDolGlobalString('TAKEPOS_PRINT_METHOD') == "receiptprinter") {
1325 $sectionwithinvoicelink .= ' <button id="buttonprint" type="button" onclick="DolibarrTakeposPrinting('.$placeid.')">'.$langs->trans('PrintTicket').'</button>';
1326 } else {
1327 $sectionwithinvoicelink .= ' <button id="buttonprint" type="button" onclick="Print('.$placeid.')">'.$langs->trans('PrintTicket').'</button>';
1328 if (getDolGlobalString('TAKEPOS_PRINT_WITHOUT_DETAILS')) {
1329 $sectionwithinvoicelink .= ' <button id="buttonprint" type="button" onclick="PrintBox('.$placeid.', \'without_details\')">'.$langs->trans('PrintWithoutDetails').'</button>';
1330 }
1331 if (getDolGlobalString('TAKEPOS_GIFT_RECEIPT')) {
1332 $sectionwithinvoicelink .= ' <button id="buttonprint" type="button" onclick="Print('.$placeid.', 1)">'.$langs->trans('GiftReceipt').'</button>';
1333 }
1334 }
1335 if (getDolGlobalString('TAKEPOS_EMAIL_TEMPLATE_INVOICE') && getDolGlobalInt('TAKEPOS_EMAIL_TEMPLATE_INVOICE') > 0) {
1336 $sectionwithinvoicelink .= ' <button id="buttonsend" type="button" onclick="SendTicket('.$placeid.')">'.$langs->trans('SendTicket').'</button>';
1337 }
1338
1339 if ($remaintopay <= 0 && getDolGlobalString('TAKEPOS_AUTO_PRINT_TICKETS') && $action != "history") {
1340 $sectionwithinvoicelink .= '<script type="text/javascript">$("#buttonprint").click();</script>';
1341 }
1342 }
1343}
1344
1345
1346/*
1347 * View
1348 */
1349
1350$form = new Form($db);
1351
1352// llxHeader
1353if ((getDolGlobalString('TAKEPOS_PHONE_BASIC_LAYOUT') == 1 && $conf->browser->layout == 'phone') || defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE')) {
1354 $title = 'TakePOS - Dolibarr '.DOL_VERSION;
1355 if (getDolGlobalString('MAIN_APPLICATION_TITLE')) {
1356 $title = 'TakePOS - ' . getDolGlobalString('MAIN_APPLICATION_TITLE');
1357 }
1358 $head = '<meta name="apple-mobile-web-app-title" content="TakePOS"/>
1359 <meta name="apple-mobile-web-app-capable" content="yes">
1360 <meta name="mobile-web-app-capable" content="yes">
1361 <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>';
1362 $arrayofcss = array(
1363 '/takepos/css/pos.css.php',
1364 );
1365 $arrayofjs = array('/takepos/js/jquery.colorbox-min.js');
1366 $disablejs = 0;
1367 $disablehead = 0;
1368 top_htmlhead($head, $title, $disablejs, $disablehead, $arrayofjs, $arrayofcss);
1369
1370 print '<body>'."\n";
1371} else {
1372 top_httphead('text/html', 1);
1373}
1374
1375?>
1376<!-- invoice.php -->
1377<script type="text/javascript">
1378var selectedline=0;
1379var selectedtext="";
1380<?php if ($action == "valid") {
1381 echo "var place=0;";
1382}?> // Set to default place after close sale
1383var placeid=<?php echo($placeid > 0 ? $placeid : 0); ?>;
1384$(document).ready(function() {
1385 var idoflineadded = <?php echo(empty($idoflineadded) ? 0 : $idoflineadded); ?>;
1386
1387 $('.posinvoiceline').click(function(){
1388 console.log("Click done on "+this.id);
1389 $('.posinvoiceline').removeClass("selected");
1390 $(this).addClass("selected");
1391 if (!this.id) {
1392 return;
1393 }
1394 if (selectedline == this.id) {
1395 return; // If is already selected
1396 } else {
1397 selectedline = this.id;
1398 }
1399 selectedtext=$('#'+selectedline).find("td:first").html();
1400 <?php
1401 if (defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE')) {
1402 print '$("#phonediv1").load("'.DOL_URL_ROOT.'/takepos/public/auto_order.php?action=editline&token='.newToken().'&placeid="+placeid+"&selectedline="+selectedline, function() {
1403 });';
1404 }
1405 ?>
1406 });
1407
1408 /* Autoselect the line */
1409 if (idoflineadded > 0)
1410 {
1411 console.log("Auto select "+idoflineadded);
1412 $('.posinvoiceline#'+idoflineadded).click();
1413 }
1414<?php
1415
1416if ($action == "order" && !empty($order_receipt_printer1)) {
1417 if (filter_var(getDolGlobalString('TAKEPOS_PRINT_SERVER'), FILTER_VALIDATE_URL) == true) {
1418 ?>
1419 $.ajax({
1420 type: "POST",
1421 url: '<?php print getDolGlobalString('TAKEPOS_PRINT_SERVER'); ?>/printer/index.php',
1422 data: 'invoice='+orderprinter1esc
1423 });
1424 <?php
1425 } else {
1426 ?>
1427 $.ajax({
1428 type: "POST",
1429 url: 'http://<?php print getDolGlobalString('TAKEPOS_PRINT_SERVER'); ?>:8111/print',
1430 data: '<?php
1431 print $headerorder.$order_receipt_printer1.$footerorder; ?>'
1432 });
1433 <?php
1434 }
1435}
1436
1437if ($action == "order" && !empty($order_receipt_printer2)) {
1438 if (filter_var(getDolGlobalString('TAKEPOS_PRINT_SERVER'), FILTER_VALIDATE_URL) == true) {
1439 ?>
1440 $.ajax({
1441 type: "POST",
1442 url: '<?php print getDolGlobalString('TAKEPOS_PRINT_SERVER'); ?>/printer/index.php?printer=2',
1443 data: 'invoice='+orderprinter2esc
1444 });
1445 <?php
1446 } else {
1447 ?>
1448 $.ajax({
1449 type: "POST",
1450 url: 'http://<?php print getDolGlobalString('TAKEPOS_PRINT_SERVER'); ?>:8111/print2',
1451 data: '<?php
1452 print $headerorder.$order_receipt_printer2.$footerorder; ?>'
1453 });
1454 <?php
1455 }
1456}
1457
1458if ($action == "order" && !empty($order_receipt_printer3)) {
1459 if (filter_var(getDolGlobalString('TAKEPOS_PRINT_SERVER'), FILTER_VALIDATE_URL) == true) {
1460 ?>
1461 $.ajax({
1462 type: "POST",
1463 url: '<?php print getDolGlobalString('TAKEPOS_PRINT_SERVER'); ?>/printer/index.php?printer=3',
1464 data: 'invoice='+orderprinter3esc
1465 });
1466 <?php
1467 }
1468}
1469
1470// Set focus to search field
1471if ($action == "search" || $action == "valid") {
1472 ?>
1473 parent.ClearSearch(true);
1474 <?php
1475}
1476
1477
1478if ($action == "temp" && !empty($ticket_printer1)) {
1479 ?>
1480 $.ajax({
1481 type: "POST",
1482 url: 'http://<?php print getDolGlobalString('TAKEPOS_PRINT_SERVER'); ?>:8111/print',
1483 data: '<?php
1484 print $header_soc.$header_ticket.$body_ticket.$ticket_printer1.$ticket_total.$footer_ticket; ?>'
1485 });
1486 <?php
1487}
1488
1489if ($action == "search") {
1490 ?>
1491 $('#search').focus();
1492 <?php
1493}
1494
1495?>
1496
1497});
1498
1499function SendTicket(id)
1500{
1501 console.log("Open box to select the Print/Send form");
1502 $.colorbox({href:"send.php?facid="+id, width:"70%", height:"30%", transition:"none", iframe:"true", title:'<?php echo dol_escape_js($langs->trans("SendTicket")); ?>'});
1503 return true;
1504}
1505
1506function PrintBox(id, action) {
1507 console.log("Open box before printing");
1508 $.colorbox({href:"printbox.php?facid="+id+"&action="+action+"&token=<?php echo newToken(); ?>", width:"80%", height:"200px", transition:"none", iframe:"true", title:"<?php echo $langs->trans("PrintWithoutDetails"); ?>"});
1509 return true;
1510}
1511
1512function Print(id, gift){
1513 console.log("Call Print() to generate the receipt.");
1514 $.colorbox({href:"receipt.php?facid="+id+"&gift="+gift, width:"40%", height:"90%", transition:"none", iframe:"true", title:'<?php echo dol_escape_js($langs->trans("PrintTicket")); ?>'});
1515 return true;
1516}
1517
1518function TakeposPrinting(id){
1519 var receipt;
1520 console.log("TakeposPrinting" + id);
1521 $.get("receipt.php?facid="+id, function(data, status) {
1522 receipt=data.replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '');
1523 $.ajax({
1524 type: "POST",
1525 url: 'http://<?php print getDolGlobalString('TAKEPOS_PRINT_SERVER'); ?>:8111/print',
1526 data: receipt
1527 });
1528 });
1529 return true;
1530}
1531
1532function TakeposConnector(id){
1533 console.log("TakeposConnector" + id);
1534 $.get("<?php echo DOL_URL_ROOT; ?>/takepos/ajax/ajax.php?action=printinvoiceticket&token=<?php echo newToken(); ?>&term=<?php echo urlencode(isset($_SESSION["takeposterminal"]) ? $_SESSION["takeposterminal"] : ''); ?>&id="+id+"&token=<?php echo currentToken(); ?>", function(data, status) {
1535 $.ajax({
1536 type: "POST",
1537 url: '<?php print getDolGlobalString('TAKEPOS_PRINT_SERVER'); ?>/printer/index.php',
1538 data: 'invoice='+data
1539 });
1540 });
1541 return true;
1542}
1543
1544// Call the ajax to execute the print.
1545// With some external module another method may be called.
1546function DolibarrTakeposPrinting(id) {
1547 console.log("DolibarrTakeposPrinting Printing invoice ticket " + id);
1548 $.ajax({
1549 type: "GET",
1550 data: { token: '<?php echo currentToken(); ?>' },
1551 url: "<?php print DOL_URL_ROOT.'/takepos/ajax/ajax.php?action=printinvoiceticket&token='.newToken().'&term='.urlencode(isset($_SESSION["takeposterminal"]) ? $_SESSION["takeposterminal"] : '').'&id='; ?>" + id,
1552
1553 });
1554 return true;
1555}
1556
1557// Call url to generate a credit note (with same lines) from existing invoice
1558function CreditNote() {
1559 $("#poslines").load("<?php print DOL_URL_ROOT; ?>/takepos/invoice.php?action=creditnote&token=<?php echo newToken() ?>&invoiceid="+placeid, function() { });
1560 return true;
1561}
1562
1563// Call url to add notes
1564function SetNote() {
1565 $("#poslines").load("<?php print DOL_URL_ROOT; ?>/takepos/invoice.php?action=addnote&token=<?php echo newToken() ?>&invoiceid="+placeid+"&idline="+selectedline, { "addnote": $("#textinput").val() });
1566 return true;
1567}
1568
1569
1570$( document ).ready(function() {
1571 console.log("Set customer info and sales in header placeid=<?php echo $placeid; ?> status=<?php echo $invoice->statut; ?>");
1572
1573 <?php
1574 $s = $langs->trans("Customer");
1575 if ($invoice->id > 0 && ($invoice->socid != getDolGlobalString($constforcompanyid))) {
1576 $s = $soc->name;
1577 if (getDolGlobalInt('TAKEPOS_CHOOSE_CONTACT')) {
1578 $contactids = $invoice->getIdContact('external', 'BILLING');
1579 $contactid = $contactids[0];
1580 if ($contactid > 0) {
1581 $contact = new Contact($db);
1582 $contact->fetch($contactid);
1583 $s .= " - " . $contact->getFullName($langs);
1584 }
1585 }
1586 } elseif (getDolGlobalInt("TAKEPOS_NO_GENERIC_THIRDPARTY")) {
1587 print '$("#idcustomer").val("");';
1588 }
1589 ?>
1590
1591 $("#customerandsales").html('');
1592 $("#shoppingcart").html('');
1593
1594 <?php if (getDolGlobalInt('TAKEPOS_CHOOSE_CONTACT') == 0) { ?>
1595 $("#customerandsales").append('<a class="valignmiddle tdoverflowmax100 minwidth100" id="customer" onclick="Customer();" title="<?php print dol_escape_js(dol_escape_htmltag((string) $s)); ?>"><span class="fas fa-building paddingrightonly"></span><?php print dol_escape_js((string) $s); ?></a>');
1596 <?php } else { ?>
1597 $("#customerandsales").append('<a class="valignmiddle tdoverflowmax300 minwidth100" id="contact" onclick="Contact();" title="<?php print dol_escape_js(dol_escape_htmltag((string) $s)); ?>"><span class="fas fa-building paddingrightonly"></span><?php print dol_escape_js((string) $s); ?></a>');
1598 <?php } ?>
1599
1600 <?php
1601 $sql = "SELECT rowid, datec, ref FROM ".MAIN_DB_PREFIX."facture";
1602 $sql .= " WHERE entity IN (".getEntity('invoice').")";
1603 if (!getDolGlobalString('TAKEPOS_CAN_EDIT_IF_ALREADY_VALIDATED')) {
1604 // By default, only invoices with a ref not already defined can in list of open invoice we can edit.
1605 $sql .= " AND ref LIKE '(PROV-POS".$db->escape(isset($_SESSION["takeposterminal"]) ? $_SESSION["takeposterminal"] : '')."-0%'";
1606 } else {
1607 // If TAKEPOS_CAN_EDIT_IF_ALREADY_VALIDATED set, we show also draft invoice that already has a reference defined
1608 $sql .= " AND pos_source = '".$db->escape((string) $_SESSION["takeposterminal"])."'";
1609 $sql .= " AND module_source = 'takepos'";
1610 }
1611
1612 $sql .= $db->order('datec', 'ASC');
1613 $resql = $db->query($sql);
1614 if ($resql) {
1615 $max_sale = 0;
1616 while ($obj = $db->fetch_object($resql)) {
1617 echo '$("#shoppingcart").append(\'';
1618 echo '<a class="valignmiddle" title="'.dol_escape_js($langs->trans("SaleStartedAt", dol_print_date($db->jdate($obj->datec), '%H:%M', 'tzuser')).' - '.$obj->ref).'" onclick="place=\\\'';
1619 $num_sale = str_replace(")", "", str_replace("(PROV-POS".$_SESSION["takeposterminal"]."-", "", $obj->ref));
1620 echo $num_sale;
1621 if (str_replace("-", "", $num_sale) > $max_sale) {
1622 $max_sale = str_replace("-", "", $num_sale);
1623 }
1624 echo '\\\'; invoiceid=\\\'';
1625 echo $obj->rowid;
1626 echo '\\\'; Refresh();">';
1627 if ($placeid == $obj->rowid) {
1628 echo '<span class="basketselected">';
1629 } else {
1630 echo '<span class="basketnotselected">';
1631 }
1632 echo '<span class="fa fa-shopping-cart paddingright"></span>'.dol_print_date($db->jdate($obj->datec), '%H:%M', 'tzuser');
1633 echo '</span>';
1634 echo '</a>\');';
1635 }
1636 echo '$("#shoppingcart").append(\'<a onclick="place=\\\'0-';
1637 echo $max_sale + 1;
1638 echo '\\\'; invoiceid=0; Refresh();"><div><span class="fa fa-plus" title="'.dol_escape_htmltag($langs->trans("StartAParallelSale")).'"><span class="fa fa-shopping-cart"></span></div></a>\');';
1639 } else {
1640 dol_print_error($db);
1641 }
1642
1643 $s = '';
1644
1645 $idwarehouse = 0;
1646 $constantforkey = 'CASHDESK_NO_DECREASE_STOCK'. (isset($_SESSION["takeposterminal"]) ? $_SESSION["takeposterminal"] : '');
1647 if (isModEnabled('stock')) {
1648 if (getDolGlobalString($constantforkey) != "1") {
1649 $constantforkey = 'CASHDESK_ID_WAREHOUSE'. (isset($_SESSION["takeposterminal"]) ? $_SESSION["takeposterminal"] : '');
1650 $idwarehouse = getDolGlobalInt($constantforkey);
1651 if ($idwarehouse > 0) {
1652 $s = '<span class="small">';
1653 $warehouse = new Entrepot($db);
1654 $warehouse->fetch($idwarehouse);
1655 $s .= '<span class="hideonsmartphone">'.$langs->trans("Warehouse").'<br></span>'.$warehouse->ref;
1656 if ($warehouse->statut == Entrepot::STATUS_CLOSED) {
1657 $s .= ' ('.$langs->trans("Closed").')';
1658 }
1659 $s .= '</span>';
1660 print "$('#infowarehouse').html('".dol_escape_js($s)."');";
1661 print '$("#infowarehouse").css("display", "inline-block");';
1662 } else {
1663 $s = '<span class="small hideonsmartphone">';
1664 $s .= $langs->trans("StockChangeDisabled").'<br>'.$langs->trans("NoWarehouseDefinedForTerminal");
1665 $s .= '</span>';
1666 print "$('#infowarehouse').html('".dol_escape_js($s)."');";
1667 if (!empty($conf->dol_optimize_smallscreen)) {
1668 print '$("#infowarehouse").css("display", "none");';
1669 }
1670 }
1671 } else {
1672 $s = '<span class="small hideonsmartphone">'.$langs->trans("StockChangeDisabled").'</span>';
1673 print "$('#infowarehouse').html('".dol_escape_js($s)."');";
1674 if (!empty($conf->dol_optimize_smallscreen)) {
1675 print '$("#infowarehouse").css("display", "none");';
1676 }
1677 }
1678 }
1679
1680
1681 // Module Adherent
1682 $s = '';
1683 if (isModEnabled('member') && $invoice->socid > 0 && $invoice->socid != getDolGlobalInt($constforcompanyid)) {
1684 $s = '<span class="small">';
1685 require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
1686 $langs->load("members");
1687 $s .= $langs->trans("Member").': ';
1688 $adh = new Adherent($db);
1689 $result = $adh->fetch(0, '', $invoice->socid);
1690 if ($result > 0) {
1691 $adh->ref = $adh->getFullName($langs);
1692 if (empty($adh->statut) || $adh->statut == Adherent::STATUS_EXCLUDED) {
1693 $s .= "<s>";
1694 }
1695 $s .= $adh->getFullName($langs);
1696 $s .= ' - '.$adh->type;
1697 if ($adh->datefin) {
1698 $s .= '<br>'.$langs->trans("SubscriptionEndDate").': '.dol_print_date($adh->datefin, 'day');
1699 if ($adh->hasDelay()) {
1700 $s .= " ".img_warning($langs->trans("Late"));
1701 }
1702 } else {
1703 $s .= '<br>'.$langs->trans("SubscriptionNotReceived");
1704 if ($adh->statut > 0) {
1705 $s .= " ".img_warning($langs->trans("Late")); // displays delay Pictogram only if not a draft and not terminated
1706 }
1707 }
1708 if (empty($adh->statut) || $adh->statut == Adherent::STATUS_EXCLUDED) {
1709 $s .= "</s>";
1710 }
1711 } else {
1712 $s .= '<br>'.$langs->trans("ThirdpartyNotLinkedToMember");
1713 }
1714 $s .= '</span>';
1715 }
1716 ?>
1717 $("#moreinfo").html('<?php print dol_escape_js($s); ?>');
1718
1719});
1720
1721
1722<?php
1723if (getDolGlobalString('TAKEPOS_CUSTOMER_DISPLAY')) {
1724 echo "function CustomerDisplay(){";
1725 echo "var line1='".$CUSTOMER_DISPLAY_line1."'.substring(0,20);";
1726 echo "line1=line1.padEnd(20);";
1727 echo "var line2='".$CUSTOMER_DISPLAY_line2."'.substring(0,20);";
1728 echo "line2=line2.padEnd(20);";
1729 echo "$.ajax({
1730 type: 'GET',
1731 data: { text: line1+line2 },
1732 url: '".getDolGlobalString('TAKEPOS_PRINT_SERVER')."/display/index.php',
1733 });";
1734 echo "}";
1735}
1736?>
1737
1738</script>
1739
1740<?php
1741// Add again js for footer because this content is injected into index.php page so all init
1742// for tooltip and other js beautifiers must be reexecuted too.
1743if (!empty($conf->use_javascript_ajax)) {
1744 print "\n".'<!-- Includes JS Footer of Dolibarr -->'."\n";
1745 print '<script src="'.DOL_URL_ROOT.'/core/js/lib_foot.js.php?lang='.$langs->defaultlang.'"></script>'."\n";
1746}
1747
1748$usediv = (GETPOST('format') == 'div');
1749
1750print '<!-- invoice.php place='.(int) $place.' invoice='.$invoice->ref.' usediv='.json_encode($usediv).', mobilepage='.(empty($mobilepage) ? '' : $mobilepage).' $_SESSION["basiclayout"]='.(empty($_SESSION["basiclayout"]) ? '' : $_SESSION["basiclayout"]).' conf TAKEPOS_BAR_RESTAURANT='.getDolGlobalString('TAKEPOS_BAR_RESTAURANT').' -->'."\n";
1751print '<div class="div-table-responsive-no-min invoice">';
1752if ($usediv) {
1753 print '<div id="tablelines">';
1754} else {
1755 print '<table id="tablelines" class="noborder noshadow postablelines centpercent">';
1756}
1757
1758$buttontocreatecreditnote = '';
1759if (($action == "valid" || $action == "history" || ($action == "addline" && $invoice->status == $invoice::STATUS_CLOSED)) && $invoice->type != Facture::TYPE_CREDIT_NOTE && !getDolGlobalString('TAKEPOS_NO_CREDITNOTE')) {
1760 $buttontocreatecreditnote .= ' &nbsp; <!-- Show button to create a credit note -->'."\n";
1761 $buttontocreatecreditnote .= '<button id="buttonprint" type="button" onclick="ModalBox(\'ModalCreditNote\')">'.$langs->trans('CreateCreditNote').'</button>';
1762 if (getDolGlobalInt('TAKEPOS_PRINT_INVOICE_DOC_INSTEAD_OF_RECEIPT')) {
1763 $buttontocreatecreditnote .= ' <a target="_blank" class="button" href="' . DOL_URL_ROOT . '/document.php?token=' . newToken() . '&modulepart=facture&file=' . urlencode($invoice->ref . '/' . $invoice->ref . '.pdf').'">'.$langs->trans("Invoice").'</a>';
1764 }
1765}
1766
1767// Show the ref of invoice
1768if ($sectionwithinvoicelink && ($mobilepage == "invoice" || $mobilepage == "")) {
1769 print '<!-- Print table line with link to invoice ref -->';
1770 if (getDolGlobalString('TAKEPOS_SHOW_HT')) {
1771 print '<tr><td colspan="5" class="paddingtopimp paddingbottomimp" style="padding-top: 10px !important; padding-bottom: 10px !important;">';
1772 print $sectionwithinvoicelink;
1773 print $buttontocreatecreditnote;
1774 print '</td></tr>';
1775 } else {
1776 print '<tr><td colspan="4" class="paddingtopimp paddingbottomimp" style="padding-top: 10px !important; padding-bottom: 10px !important;">';
1777 print $sectionwithinvoicelink;
1778 print $buttontocreatecreditnote;
1779 print '</td></tr>';
1780 }
1781}
1782
1783// Show the list of selected product
1784if (!$usediv) {
1785 print '<tr class="liste_titre nodrag nodrop">';
1786 print '<td class="linecoldescription">';
1787}
1788// In phone version only show when it is invoice page
1789if (empty($mobilepage) || $mobilepage == "invoice") {
1790 print '<!-- hidden var used by some js functions -->';
1791 print '<input type="hidden" name="invoiceid" id="invoiceid" value="'.$invoice->id.'">';
1792 print '<input type="hidden" name="thirdpartyid" id="thirdpartyid" value="'.$invoice->socid.'">';
1793}
1794if (!$usediv) {
1795 if (getDolGlobalString('TAKEPOS_BAR_RESTAURANT')) {
1796 $sql = "SELECT floor, label FROM ".MAIN_DB_PREFIX."takepos_floor_tables where rowid=".((int) $place);
1797 $resql = $db->query($sql);
1798 $obj = $db->fetch_object($resql);
1799 if ($obj) {
1800 $label = $obj->label;
1801 $floor = $obj->floor;
1802 }
1803 if ($mobilepage == "invoice" || $mobilepage == "") {
1804 // If not on smartphone version or if it is the invoice page
1805 //print 'mobilepage='.$mobilepage;
1806 print '<span class="opacitymedium">'.$langs->trans('Place')."</span> <b>".(empty($label) ? '?' : $label)."</b><br>";
1807 print '<span class="opacitymedium">'.$langs->trans('Floor')."</span> <b>".(empty($floor) ? '?' : $floor)."</b>";
1808 }
1809 }
1810 print '</td>';
1811}
1812
1813// Complete header by hook
1814$parameters = array();
1815$reshook = $hookmanager->executeHooks('completeTakePosInvoiceHeader', $parameters, $invoice, $action); // Note that $action and $object may have been modified by some hooks
1816if ($reshook < 0) {
1817 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1818}
1819print $hookmanager->resPrint;
1820
1821if (empty($_SESSION["basiclayout"]) || $_SESSION["basiclayout"] != 1) {
1822 if (getDolGlobalInt("TAKEPOS_SHOW_SUBPRICE")) {
1823 print '<td class="linecolqty right">'.$langs->trans('PriceUHT').'</td>';
1824 }
1825 print '<td class="linecolqty right">'.$langs->trans('ReductionShort').'</td>';
1826 print '<td class="linecolqty right">'.$langs->trans('Qty').'</td>';
1827 if (getDolGlobalString('TAKEPOS_SHOW_HT')) {
1828 print '<td class="linecolht right nowraponall">';
1829 print '<span class="opacitymedium small">' . $langs->trans('TotalHTShort') . '</span><br>';
1830 // In phone version only show when it is invoice page
1831 if (empty($mobilepage) || $mobilepage == "invoice") {
1832 print '<span id="linecolht-span-total" style="font-size:1.3em; font-weight: bold;">' . price($invoice->total_ht, 1, '', 1, -1, -1, $conf->currency) . '</span>';
1833 if (isModEnabled('multicurrency') && !empty($_SESSION["takeposcustomercurrency"]) && $conf->currency != $_SESSION["takeposcustomercurrency"]) {
1834 //Only show customer currency if multicurrency module is enabled, if currency selected and if this currency selected is not the same as main currency
1835 include_once DOL_DOCUMENT_ROOT . '/multicurrency/class/multicurrency.class.php';
1836 $multicurrency = new MultiCurrency($db);
1837 $multicurrency->fetch(0, $_SESSION["takeposcustomercurrency"]);
1838 print '<br><span id="linecolht-span-total" style="font-size:0.9em; font-style:italic;">(' . price($invoice->total_ht * $multicurrency->rate->rate) . ' ' . $_SESSION["takeposcustomercurrency"] . ')</span>';
1839 }
1840 }
1841 print '</td>';
1842 }
1843 print '<td class="linecolht right nowraponall">';
1844 print '<span class="opacitymedium small">'.$langs->trans('TotalTTCShort').'</span><br>';
1845 // In phone version only show when it is invoice page
1846 if (empty($mobilepage) || $mobilepage == "invoice") {
1847 print '<span id="linecolht-span-total" style="font-size:1.3em; font-weight: bold;">'.price($invoice->total_ttc, 1, '', 1, -1, -1, $conf->currency).'</span>';
1848 if (isModEnabled('multicurrency') && !empty($_SESSION["takeposcustomercurrency"]) && $conf->currency != $_SESSION["takeposcustomercurrency"]) {
1849 //Only show customer currency if multicurrency module is enabled, if currency selected and if this currency selected is not the same as main currency
1850 include_once DOL_DOCUMENT_ROOT.'/multicurrency/class/multicurrency.class.php';
1851 $multicurrency = new MultiCurrency($db);
1852 $multicurrency->fetch(0, $_SESSION["takeposcustomercurrency"]);
1853 print '<br><span id="linecolht-span-total" style="font-size:0.9em; font-style:italic;">('.price($invoice->total_ttc * $multicurrency->rate->rate).' '.$_SESSION["takeposcustomercurrency"].')</span>';
1854 }
1855 }
1856 print '</td>';
1857} elseif ($mobilepage == "invoice") {
1858 print '<td class="linecolqty right">'.$langs->trans('Qty').'</td>';
1859}
1860if (!$usediv) {
1861 print "</tr>\n";
1862}
1863
1864if (!empty($_SESSION["basiclayout"]) && $_SESSION["basiclayout"] == 1) {
1865 if ($mobilepage == "cats") {
1866 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
1867 $categorie = new Categorie($db);
1868 $categories = $categorie->get_full_arbo('product');
1869 $htmlforlines = '';
1870 foreach ($categories as $row) {
1871 if (defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE')) {
1872 $htmlforlines .= '<div class="leftcat"';
1873 } else {
1874 $htmlforlines .= '<tr class="drag drop oddeven posinvoiceline"';
1875 }
1876 $htmlforlines .= ' onclick="LoadProducts('.$row['id'].');">';
1877 if (defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE')) {
1878 $htmlforlines .= '<img class="imgwrapper" width="33%" src="'.DOL_URL_ROOT.'/takepos/public/auto_order.php?genimg=cat&query=cat&id='.$row['id'].'"><br>';
1879 } else {
1880 $htmlforlines .= '<td class="left">';
1881 }
1882 $htmlforlines .= $row['label'];
1883 if (defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE')) {
1884 $htmlforlines .= '</div>'."\n";
1885 } else {
1886 $htmlforlines .= '</td></tr>'."\n";
1887 }
1888 }
1889 print $htmlforlines;
1890 }
1891
1892 if ($mobilepage == "products") {
1893 require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
1894 $object = new Categorie($db);
1895 $catid = GETPOSTINT('catid');
1896 $result = $object->fetch($catid);
1897 $prods = $object->getObjectsInCateg("product");
1898 $htmlforlines = '';
1899 foreach ($prods as $row) {
1900 if (defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE')) {
1901 $htmlforlines .= '<div class="leftcat"';
1902 } else {
1903 $htmlforlines .= '<tr class="drag drop oddeven posinvoiceline"';
1904 }
1905 $htmlforlines .= ' onclick="AddProduct(\''.$place.'\', '.$row->id.')"';
1906 $htmlforlines .= '>';
1907 if (defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE')) {
1908 $htmlforlines .= '<img class="imgwrapper" width="33%" src="'.DOL_URL_ROOT.'/takepos/public/auto_order.php?genimg=pro&query=pro&id='.$row->id.'"><br>';
1909 $htmlforlines .= $row->label.' '.price($row->price_ttc, 1, $langs, 1, -1, -1, $conf->currency);
1910 $htmlforlines .= '</div>'."\n";
1911 } else {
1912 $htmlforlines .= '<td class="left">';
1913 $htmlforlines .= $row->label;
1914 $htmlforlines .= '<div class="right">'.price($row->price_ttc, 1, $langs, 1, -1, -1, $conf->currency).'</div>';
1915 $htmlforlines .= '</td>';
1916 $htmlforlines .= '</tr>'."\n";
1917 }
1918 }
1919 print $htmlforlines;
1920 }
1921
1922 if ($mobilepage == "places") {
1923 $sql = "SELECT rowid, entity, label, leftpos, toppos, floor FROM ".MAIN_DB_PREFIX."takepos_floor_tables";
1924 $resql = $db->query($sql);
1925
1926 $rows = array();
1927 $htmlforlines = '';
1928 while ($row = $db->fetch_array($resql)) {
1929 $rows[] = $row;
1930 $htmlforlines .= '<tr class="drag drop oddeven posinvoiceline';
1931 $htmlforlines .= '" onclick="LoadPlace(\''.$row['label'].'\')">';
1932 $htmlforlines .= '<td class="left">';
1933 $htmlforlines .= $row['label'];
1934 $htmlforlines .= '</td>';
1935 $htmlforlines .= '</tr>'."\n";
1936 }
1937 print $htmlforlines;
1938 }
1939}
1940
1941if ($placeid > 0) {
1942 //In Phone basic layout hide some content depends situation
1943 if (!empty($_SESSION["basiclayout"]) && $_SESSION["basiclayout"] == 1 && $mobilepage != "invoice" && $action != "order") {
1944 return;
1945 }
1946
1947 // Loop on each lines on invoice
1948 if (is_array($invoice->lines) && count($invoice->lines)) {
1949 print '<!-- invoice.php show lines of invoices -->'."\n";
1950 $tmplines = array_reverse($invoice->lines);
1951 $htmlsupplements = array();
1952 foreach ($tmplines as $line) {
1953 if ($line->fk_parent_line != false) {
1954 $htmlsupplements[$line->fk_parent_line] .= '<tr class="drag drop oddeven posinvoiceline';
1955 if ($line->special_code == "4") {
1956 $htmlsupplements[$line->fk_parent_line] .= ' order';
1957 }
1958 $htmlsupplements[$line->fk_parent_line] .= '" id="'.$line->id.'"';
1959 if ($line->special_code == "4") {
1960 $htmlsupplements[$line->fk_parent_line] .= ' title="'.dol_escape_htmltag($langs->trans("AlreadyPrinted")).'"';
1961 }
1962 $htmlsupplements[$line->fk_parent_line] .= '>';
1963 $htmlsupplements[$line->fk_parent_line] .= '<td class="left">';
1964 $htmlsupplements[$line->fk_parent_line] .= img_picto('', 'rightarrow');
1965 if ($line->product_label) {
1966 $htmlsupplements[$line->fk_parent_line] .= $line->product_label;
1967 }
1968 if ($line->product_label && $line->desc) {
1969 $htmlsupplements[$line->fk_parent_line] .= '<br>';
1970 }
1971 if ($line->product_label != $line->desc) {
1972 $firstline = dolGetFirstLineOfText($line->desc);
1973 if ($firstline != $line->desc) {
1974 $htmlsupplements[$line->fk_parent_line] .= $form->textwithpicto(dolGetFirstLineOfText($line->desc), $line->desc);
1975 } else {
1976 $htmlsupplements[$line->fk_parent_line] .= $line->desc;
1977 }
1978 }
1979 $htmlsupplements[$line->fk_parent_line] .= '</td>';
1980
1981 // complete line by hook
1982 $parameters = array('line' => $line);
1983 $reshook = $hookmanager->executeHooks('completeTakePosInvoiceParentLine', $parameters, $invoice, $action); // Note that $action and $object may have been modified by some hooks
1984 if ($reshook < 0) {
1985 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1986 }
1987 $htmlsupplements[$line->fk_parent_line] .= $hookmanager->resPrint;
1988
1989 if (empty($_SESSION["basiclayout"]) || $_SESSION["basiclayout"] != 1) {
1990 $htmlsupplements[$line->fk_parent_line] .= '<td class="right">'.vatrate(price2num($line->remise_percent), true).'</td>';
1991 $htmlsupplements[$line->fk_parent_line] .= '<td class="right">'.$line->qty.'</td>';
1992 $htmlsupplements[$line->fk_parent_line] .= '<td class="right">'.price($line->total_ttc).'</td>';
1993 }
1994 $htmlsupplements[$line->fk_parent_line] .= '</tr>'."\n";
1995 continue;
1996 }
1997 $htmlforlines = '';
1998
1999 $htmlforlines .= '<tr class="drag drop oddeven posinvoiceline';
2000 if ($line->special_code == "4") {
2001 $htmlforlines .= ' order';
2002 }
2003 $htmlforlines .= '" id="'.$line->id.'"';
2004 if ($line->special_code == "4") {
2005 $htmlforlines .= ' title="'.dol_escape_htmltag($langs->trans("AlreadyPrinted")).'"';
2006 }
2007 $htmlforlines .= '>';
2008 $htmlforlines .= '<td class="left">';
2009 if (!empty($_SESSION["basiclayout"]) && $_SESSION["basiclayout"] == 1) {
2010 $htmlforlines .= '<span class="phoneqty">'.$line->qty."</span> x ";
2011 }
2012 if (isset($line->product_type)) {
2013 if (empty($line->product_type)) {
2014 $htmlforlines .= img_object('', 'product').' ';
2015 } else {
2016 $htmlforlines .= img_object('', 'service').' ';
2017 }
2018 }
2019 $tooltiptext = '';
2020 if (!getDolGlobalString('TAKEPOS_SHOW_N_FIRST_LINES')) {
2021 if ($line->product_ref) {
2022 $tooltiptext .= '<b>'.$langs->trans("Ref").'</b> : '.$line->product_ref.'<br>';
2023 $tooltiptext .= '<b>'.$langs->trans("Label").'</b> : '.$line->product_label.'<br>';
2024 if (!empty($line->batch)) {
2025 $tooltiptext .= '<br><b>'.$langs->trans("LotSerial").'</b> : '.$line->batch.'<br>';
2026 }
2027 if (!empty($line->fk_warehouse)) {
2028 $tooltiptext .= '<b>'.$langs->trans("Warehouse").'</b> : '.$line->fk_warehouse.'<br>';
2029 }
2030 if ($line->product_label != $line->desc) {
2031 if ($line->desc) {
2032 $tooltiptext .= '<br>';
2033 }
2034 $tooltiptext .= $line->desc;
2035 }
2036 }
2037 if (getDolGlobalInt('TAKEPOS_SHOW_PRODUCT_REFERENCE') == 1) {
2038 $htmlforlines .= $form->textwithpicto($line->product_label ? '<b>' . $line->product_ref . '</b> - ' . $line->product_label : dolGetFirstLineOfText($line->desc, 1), $tooltiptext);
2039 } elseif (getDolGlobalInt('TAKEPOS_SHOW_PRODUCT_REFERENCE') == 2) {
2040 $htmlforlines .= $form->textwithpicto($line->product_ref ? '<b>'.$line->product_ref.'<b>' : dolGetFirstLineOfText($line->desc, 1), $tooltiptext);
2041 } else {
2042 $htmlforlines .= $form->textwithpicto($line->product_label ? $line->product_label : ($line->product_ref ? $line->product_ref : dolGetFirstLineOfText($line->desc, 1)), $tooltiptext);
2043 }
2044 } else {
2045 if ($line->product_ref) {
2046 $tooltiptext .= '<b>'.$langs->trans("Ref").'</b> : '.$line->product_ref.'<br>';
2047 $tooltiptext .= '<b>'.$langs->trans("Label").'</b> : '.$line->product_label.'<br>';
2048 }
2049 if (!empty($line->batch)) {
2050 $tooltiptext .= '<br><b>'.$langs->trans("LotSerial").'</b> : '.$line->batch.'<br>';
2051 }
2052 if (!empty($line->fk_warehouse)) {
2053 $tooltiptext .= '<b>'.$langs->trans("Warehouse").'</b> : '.$line->fk_warehouse.'<br>';
2054 }
2055
2056 if ($line->product_label) {
2057 $htmlforlines .= $line->product_label;
2058 }
2059 if ($line->product_label != $line->desc) {
2060 if ($line->product_label && $line->desc) {
2061 $htmlforlines .= '<br>';
2062 }
2063 $firstline = dolGetFirstLineOfText($line->desc, getDolGlobalInt('TAKEPOS_SHOW_N_FIRST_LINES'));
2064 if ($firstline != $line->desc) {
2065 $htmlforlines .= $form->textwithpicto(dolGetFirstLineOfText($line->desc), $line->desc);
2066 } else {
2067 $htmlforlines .= $line->desc;
2068 }
2069 }
2070 }
2071 if (!empty($line->array_options['options_order_notes'])) {
2072 $htmlforlines .= "<br>(".$line->array_options['options_order_notes'].")";
2073 }
2074 if (!empty($_SESSION["basiclayout"]) && $_SESSION["basiclayout"] == 1) {
2075 $htmlforlines .= '</td><td class="right phonetable"><button type="button" onclick="SetQty(place, '.$line->rowid.', '.($line->qty - 1).');" class="publicphonebutton2 phonered">-</button>&nbsp;&nbsp;<button type="button" onclick="SetQty(place, '.$line->rowid.', '.($line->qty + 1).');" class="publicphonebutton2 phonegreen">+</button>';
2076 }
2077 if (empty($_SESSION["basiclayout"]) || $_SESSION["basiclayout"] != 1) {
2078 $moreinfo = '';
2079 $moreinfo .= $langs->transcountry("TotalHT", $mysoc->country_code).': '.price($line->total_ht);
2080 if ($line->vat_src_code) {
2081 $moreinfo .= '<br>'.$langs->trans("VATCode").': '.$line->vat_src_code;
2082 }
2083 $moreinfo .= '<br>'.$langs->transcountry("TotalVAT", $mysoc->country_code).': '.price($line->total_tva);
2084 $moreinfo .= '<br>'.$langs->transcountry("TotalLT1", $mysoc->country_code).': '.price($line->total_localtax1);
2085 $moreinfo .= '<br>'.$langs->transcountry("TotalLT2", $mysoc->country_code).': '.price($line->total_localtax2);
2086 $moreinfo .= '<hr>';
2087 $moreinfo .= $langs->transcountry("TotalTTC", $mysoc->country_code).': '.price($line->total_ttc);
2088 //$moreinfo .= $langs->trans("TotalHT").': '.$line->total_ht;
2089 if ($line->date_start || $line->date_end) {
2090 $htmlforlines .= '<br><div class="clearboth nowraponall">'.get_date_range($line->date_start, $line->date_end).'</div>';
2091 }
2092 $htmlforlines .= '</td>';
2093
2094 // complete line by hook
2095 $parameters = array('line' => $line);
2096 $reshook = $hookmanager->executeHooks('completeTakePosInvoiceLine', $parameters, $invoice, $action); // Note that $action and $object may have been modified by some hooks
2097 if ($reshook < 0) {
2098 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
2099 }
2100 $htmlforlines .= $hookmanager->resPrint;
2101
2102 if (getDolGlobalInt("TAKEPOS_SHOW_SUBPRICE")) {
2103 $htmlforlines .= '<td class="right">'.price($line->subprice).'</td>';
2104 }
2105 $htmlforlines .= '<td class="right">'.vatrate(price2num($line->remise_percent), true).'</td>';
2106 $htmlforlines .= '<td class="right">';
2107 $htmlforlines .= $line->qty;
2108 if (isModEnabled('stock') && $user->hasRight('stock', 'mouvement', 'lire')) {
2109 $constantforkey = 'CASHDESK_ID_WAREHOUSE'.$_SESSION["takeposterminal"];
2110 if (getDolGlobalString($constantforkey) && $line->fk_product > 0 && !getDolGlobalString('TAKEPOS_HIDE_STOCK_ON_LINE')) {
2111 $productChildrenNb = 0;
2112 if (getDolGlobalInt('PRODUIT_SOUSPRODUITS')) {
2113 if (empty($line->product) || !($line->product->id > 0)) {
2114 $line->fetch_product();
2115 }
2116 if (!empty($line->product)) {
2117 $productChildrenNb = $line->product->hasFatherOrChild(1);
2118 }
2119 }
2120 if ($productChildrenNb == 0) {
2121 $sql = "SELECT e.rowid, e.ref, e.lieu, e.fk_parent, e.statut, ps.reel, ps.rowid as product_stock_id, p.pmp";
2122 $sql .= " FROM ".MAIN_DB_PREFIX."entrepot as e,";
2123 $sql .= " ".MAIN_DB_PREFIX."product_stock as ps";
2124 $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON p.rowid = ps.fk_product";
2125 $sql .= " WHERE ps.reel != 0";
2126 $sql .= " AND ps.fk_entrepot = ".((int) getDolGlobalString($constantforkey));
2127 $sql .= " AND e.entity IN (".getEntity('stock').")";
2128 $sql .= " AND ps.fk_product = ".((int) $line->fk_product);
2129 $resql = $db->query($sql);
2130 if ($resql) {
2131 $stock_real = 0;
2132 $obj = $db->fetch_object($resql);
2133 if ($obj) {
2134 $stock_real = price2num($obj->reel, 'MS');
2135 }
2136 $htmlforlines .= '&nbsp; ';
2137 $htmlforlines .= '<span class="opacitylow" title="'.$langs->trans("Stock").' '.price($stock_real, 1, '', 1, 0).'">';
2138 $htmlforlines .= '(';
2139 if ($line->qty && $line->qty > $stock_real) {
2140 $htmlforlines .= '<span style="color: var(--amountremaintopaycolor)">';
2141 }
2142 $htmlforlines .= img_picto('', 'stock', 'class="pictofixedwidth"').price($stock_real, 1, '', 1, 0);
2143 if ($line->qty && $line->qty > $stock_real) {
2144 $htmlforlines .= "</span>";
2145 }
2146 $htmlforlines .= ')';
2147 $htmlforlines .= '</span>';
2148 } else {
2149 dol_print_error($db);
2150 }
2151 }
2152 }
2153 }
2154
2155 $htmlforlines .= '</td>';
2156 if (getDolGlobalInt('TAKEPOS_SHOW_HT')) {
2157 $htmlforlines .= '<td class="right classfortooltip" title="'.$moreinfo.'">';
2158 $htmlforlines .= price($line->total_ht, 1, '', 1, -1, -1, $conf->currency);
2159 if (isModEnabled('multicurrency') && !empty($_SESSION["takeposcustomercurrency"]) && $conf->currency != $_SESSION["takeposcustomercurrency"]) {
2160 //Only show customer currency if multicurrency module is enabled, if currency selected and if this currency selected is not the same as main currency
2161 include_once DOL_DOCUMENT_ROOT.'/multicurrency/class/multicurrency.class.php';
2162 $multicurrency = new MultiCurrency($db);
2163 $multicurrency->fetch(0, $_SESSION["takeposcustomercurrency"]);
2164 $htmlforlines .= '<br><span id="linecolht-span-total" style="font-size:0.9em; font-style:italic;">('.price($line->total_ht * $multicurrency->rate->rate).' '.$_SESSION["takeposcustomercurrency"].')</span>';
2165 }
2166 $htmlforlines .= '</td>';
2167 }
2168 $htmlforlines .= '<td class="right classfortooltip" title="'.$moreinfo.'">';
2169 $htmlforlines .= price($line->total_ttc, 1, '', 1, -1, -1, $conf->currency);
2170 if (isModEnabled('multicurrency') && !empty($_SESSION["takeposcustomercurrency"]) && $conf->currency != $_SESSION["takeposcustomercurrency"]) {
2171 //Only show customer currency if multicurrency module is enabled, if currency selected and if this currency selected is not the same as main currency
2172 include_once DOL_DOCUMENT_ROOT.'/multicurrency/class/multicurrency.class.php';
2173 $multicurrency = new MultiCurrency($db);
2174 $multicurrency->fetch(0, $_SESSION["takeposcustomercurrency"]);
2175 $htmlforlines .= '<br><span id="linecolht-span-total" style="font-size:0.9em; font-style:italic;">('.price($line->total_ttc * $multicurrency->rate->rate).' '.$_SESSION["takeposcustomercurrency"].')</span>';
2176 }
2177 $htmlforlines .= '</td>';
2178 }
2179 $htmlforlines .= '</tr>'."\n";
2180 $htmlforlines .= empty($htmlsupplements[$line->id]) ? '' : $htmlsupplements[$line->id];
2181
2182 print $htmlforlines;
2183 }
2184 } else {
2185 print '<tr class="drag drop oddeven"><td class="left"><span class="opacitymedium">'.$langs->trans("Empty").'</span></td><td></td>';
2186 if (empty($_SESSION["basiclayout"]) || $_SESSION["basiclayout"] != 1) {
2187 print '<td></td><td></td>';
2188 if (getDolGlobalString('TAKEPOS_SHOW_HT')) {
2189 print '<td></td>';
2190 }
2191 }
2192 print '</tr>';
2193 }
2194} else { // No invoice generated yet
2195 print '<tr class="drag drop oddeven"><td class="left"><span class="opacitymedium">'.$langs->trans("Empty").'</span></td><td></td>';
2196 if (empty($_SESSION["basiclayout"]) || $_SESSION["basiclayout"] != 1) {
2197 print '<td></td><td></td>';
2198 if (getDolGlobalString('TAKEPOS_SHOW_HT')) {
2199 print '<td></td>';
2200 }
2201 }
2202 print '</tr>';
2203}
2204
2205if ($usediv) {
2206 print '</div>';
2207} else {
2208 print '</table>';
2209}
2210
2211if ($action == "search") {
2212 print '<center>
2213 <input type="text" id="search" class="input-nobottom" name="search" onkeyup="Search2(\'\', null);" style="width: 80%; font-size: 150%;" placeholder="'.dol_escape_htmltag($langs->trans('Search')).'">
2214 </center>';
2215}
2216
2217print '</div>';
2218
2219// llxFooter
2220if ((getDolGlobalString('TAKEPOS_PHONE_BASIC_LAYOUT') == 1 && $conf->browser->layout == 'phone') || defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE')) {
2221 print '</body></html>';
2222}
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:67
$object ref
Definition info.php:90
Class to manage members of a foundation.
const STATUS_EXCLUDED
Excluded.
Class to manage categories.
Class to manage contact/addresses.
Class to manage warehouses.
const STATUS_CLOSED
Warehouse closed, inactive.
Class to manage invoices.
const STATUS_DRAFT
Draft status.
const TYPE_CREDIT_NOTE
Credit note invoice.
Class to manage generation of HTML components Only common components must be here.
Class to manage stock movements.
Class Currency.
Class to manage payments of customer invoices.
Class to manage products or services.
Manage record for batch number management.
Class to manage third parties objects (customers, suppliers, prospects...)
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:171
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
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.
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
newToken()
Return the value of token currently saved into session with name 'newtoken'.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
GETPOSTFLOAT($paramname, $rounding='')
Return the value of a $_GET or $_POST supervariable, converted into float.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
dol_htmloutput_errors($mesgstring='', $mesgarray=array(), $keepembedded=0)
Print formatted error messages to output (Used to show messages on html output).
get_localtax($vatrate, $local, $thirdparty_buyer=null, $thirdparty_seller=null, $vatnpr=0)
Return localtax rate for a particular vat, when selling a product with vat $vatrate,...
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
treeview li table
No Email.
ui state ui widget content ui state ui widget header ui state a ui button
0 = Do not include form tag and submit button -1 = Do not include form tag but include submit button
top_htmlhead($head, $title='', $disablejs=0, $disablehead=0, $arrayofjs=array(), $arrayofcss=array(), $disableforlogin=0, $disablenofollow=0, $disablenoindex=0)
Output html header of a page.
if(!defined( 'NOREQUIREMENU')) if(!empty(GETPOST('seteventmessages', 'alpha'))) if(!function_exists("llxHeader")) top_httphead($contenttype='text/html', $forcenocache=0)
Show HTTP header.
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79
if(preg_match('/(crypted|dolcrypt):/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition repair.php:158
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.
if(empty( $takeposterminal)) fail($message)
Abort invoice creation with a given error message.
Definition invoice.php:123