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