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