dolibarr  16.0.5
invoice.php
Go to the documentation of this file.
1 <?php
26 // if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER', '1'); // Not disabled cause need to load personalized language
27 // if (! defined('NOREQUIREDB')) define('NOREQUIREDB', '1'); // Not disabled cause need to load personalized language
28 // if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC', '1');
29 // if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN', '1');
30 if (!defined('NOCSRFCHECK')) {
31  define('NOCSRFCHECK', '1');
32 }
33 if (!defined('NOTOKENRENEWAL')) {
34  define('NOTOKENRENEWAL', '1');
35 }
36 if (!defined('NOREQUIREMENU')) {
37  define('NOREQUIREMENU', '1');
38 }
39 if (!defined('NOREQUIREHTML')) {
40  define('NOREQUIREHTML', '1');
41 }
42 if (!defined('NOREQUIREAJAX')) {
43  define('NOREQUIREAJAX', '1');
44 }
45 
46 if (!defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE')) {
47  require '../main.inc.php';
48 }
49 require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
50 require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php';
51 require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php';
52 require_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
53 $hookmanager->initHooks(array('takeposinvoice'));
54 
55 global $mysoc;
56 
57 $langs->loadLangs(array("companies", "commercial", "bills", "cashdesk", "stocks", "banks"));
58 
59 $id = GETPOST('id', 'int');
60 $action = GETPOST('action', 'aZ09');
61 $idproduct = GETPOST('idproduct', 'int');
62 $place = (GETPOST('place', 'aZ09') ? GETPOST('place', 'aZ09') : 0); // $place is id of table for Bar or Restaurant
63 $placeid = 0; // $placeid is ID of invoice
64 $mobilepage = GETPOST('mobilepage', 'alpha');
65 
66 // Terminal is stored into $_SESSION["takeposterminal"];
67 
68 if (empty($user->rights->takepos->run) && !defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE')) {
70 }
71 
72 
73 /*
74  * View
75  */
76 
77 if ((getDolGlobalString('TAKEPOS_PHONE_BASIC_LAYOUT') == 1 && $conf->browser->layout == 'phone') || defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE')) {
78  // DIRECT LINK TO THIS PAGE FROM MOBILE AND NO TERMINAL SELECTED
79  if ($_SESSION["takeposterminal"] == "") {
80  if (getDolGlobalString('TAKEPOS_NUM_TERMINALS') == "1") {
81  $_SESSION["takeposterminal"] = 1;
82  } else {
83  header("Location: ".DOL_URL_ROOT."/takepos/index.php");
84  exit;
85  }
86  }
87  $title = 'TakePOS - Dolibarr '.DOL_VERSION;
88  if (!empty($conf->global->MAIN_APPLICATION_TITLE)) {
89  $title = 'TakePOS - '.$conf->global->MAIN_APPLICATION_TITLE;
90  }
91  $head = '<meta name="apple-mobile-web-app-title" content="TakePOS"/>
92  <meta name="apple-mobile-web-app-capable" content="yes">
93  <meta name="mobile-web-app-capable" content="yes">
94  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>';
95  $arrayofcss = array(
96  '/takepos/css/pos.css.php',
97  '/takepos/js/jquery.colorbox-min.js'
98  );
99  $arrayofjs = array('/takepos/js/jquery.colorbox-min.js');
100  $disablejs = 0;
101  $disablehead = 0;
102  top_htmlhead($head, $title, $disablejs, $disablehead, $arrayofjs, $arrayofcss);
103 }
104 
111 function fail($message)
112 {
113  header($_SERVER['SERVER_PROTOCOL'].' 500 Internal Server Error', true, 500);
114  die($message);
115 }
116 
117 
118 
119 $number = GETPOST('number', 'alpha');
120 $idline = GETPOST('idline', 'int');
121 $selectedline = GETPOST('selectedline', 'int');
122 $desc = GETPOST('desc', 'alphanohtml');
123 $pay = GETPOST('pay', 'aZ09');
124 $amountofpayment = price2num(GETPOST('amount', 'alpha'));
125 
126 $invoiceid = GETPOST('invoiceid', 'int');
127 
128 $paycode = $pay;
129 if ($pay == 'cash') {
130  $paycode = 'LIQ'; // For backward compatibility
131 }
132 if ($pay == 'card') {
133  $paycode = 'CB'; // For backward compatibility
134 }
135 if ($pay == 'cheque') {
136  $paycode = 'CHQ'; // For backward compatibility
137 }
138 
139 // Retrieve paiementid
140 $paiementid = 0;
141 if ($paycode) {
142  $sql = "SELECT id FROM ".MAIN_DB_PREFIX."c_paiement";
143  $sql .= " WHERE entity IN (".getEntity('c_paiement').")";
144  $sql .= " AND code = '".$db->escape($paycode)."'";
145  $resql = $db->query($sql);
146  if ($resql) {
147  $obj = $db->fetch_object($resql);
148  if ($obj) {
149  $paiementid = $obj->id;
150  }
151  }
152 }
153 
154 $invoice = new Facture($db);
155 if ($invoiceid > 0) {
156  $ret = $invoice->fetch($invoiceid);
157 } else {
158  $ret = $invoice->fetch('', '(PROV-POS'. (isset($_SESSION["takeposterminal"]) ? $_SESSION["takeposterminal"] : '') .'-'.$place.')');
159 }
160 if ($ret > 0) {
161  $placeid = $invoice->id;
162 }
163 
164 $constforcompanyid = 'CASHDESK_ID_THIRDPARTY'. (isset($_SESSION["takeposterminal"]) ? $_SESSION["takeposterminal"] : '');
165 
166 $soc = new Societe($db);
167 if ($invoice->socid > 0) {
168  $soc->fetch($invoice->socid);
169 } else {
170  $soc->fetch(getDolGlobalString("$constforcompanyid"));
171 }
172 
173 // Change the currency of invoice if it was modified
174 if (isModEnabled('multicurrency') && !empty($_SESSION["takeposcustomercurrency"])) {
175  if ($invoice->multicurrency_code != $_SESSION["takeposcustomercurrency"]) {
176  $invoice->setMulticurrencyCode($_SESSION["takeposcustomercurrency"]);
177  }
178 }
179 
180 
181 /*
182  * Actions
183  */
184 
185 $parameters=array();
186 $reshook=$hookmanager->executeHooks('doActions', $parameters, $invoice, $action); // Note that $action and $object may have been modified by some hooks
187 if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
188 
189 if (empty($reshook)) {
190  // Action to record a payment on a TakePOS invoice
191  if ($action == 'valid' && $user->rights->facture->creer) {
192  $bankaccount = 0;
193  $error = 0;
194 
195  if (!empty($conf->global->TAKEPOS_CAN_FORCE_BANK_ACCOUNT_DURING_PAYMENT)) {
196  $bankaccount = GETPOST('accountid', 'int');
197  } else {
198  if ($pay == 'LIQ') {
199  $bankaccount = $conf->global->{'CASHDESK_ID_BANKACCOUNT_CASH'.$_SESSION["takeposterminal"]}; // For backward compatibility
200  } elseif ($pay == "CHQ") {
201  $bankaccount = $conf->global->{'CASHDESK_ID_BANKACCOUNT_CHEQUE'.$_SESSION["takeposterminal"]}; // For backward compatibility
202  } else {
203  $accountname = "CASHDESK_ID_BANKACCOUNT_".$pay.$_SESSION["takeposterminal"];
204  $bankaccount = $conf->global->$accountname;
205  }
206  }
207 
208  if ($bankaccount <= 0 && $pay != "delayed" && isModEnabled('banque')) {
209  $errormsg = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("BankAccount"));
210  $error++;
211  }
212 
213  $now = dol_now();
214  $res = 0;
215 
216  $invoice = new Facture($db);
217  $invoice->fetch($placeid);
218 
219  if ($invoice->total_ttc < 0) {
220  $invoice->type = $invoice::TYPE_CREDIT_NOTE;
221 
222  $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."facture WHERE";
223  $sql .= " fk_soc = ".((int) $invoice->socid);
224  $sql .= " AND type <> ".Facture::TYPE_CREDIT_NOTE;
225  $sql .= " AND fk_statut >= ".$invoice::STATUS_VALIDATED;
226  $sql .= " ORDER BY rowid DESC";
227 
228  $resql = $db->query($sql);
229  if ($resql) {
230  $obj = $db->fetch_object($resql);
231  $fk_source = $obj->rowid;
232  if ($fk_source == null) {
233  fail($langs->transnoentitiesnoconv("NoPreviousBillForCustomer"));
234  }
235  } else {
236  fail($langs->transnoentitiesnoconv("NoPreviousBillForCustomer"));
237  }
238  $invoice->fk_facture_source = $fk_source;
239  $invoice->update($user);
240  }
241 
242  //$sav_FACTURE_ADDON = '';
243  //if (!empty($conf->global->TAKEPOS_ADDON)) {
244  // $sav_FACTURE_ADDON = $conf->global->FACTURE_ADDON;
245  // if ($conf->global->TAKEPOS_ADDON == "terminal") $conf->global->FACTURE_ADDON = $conf->global->{'TAKEPOS_ADDON'.$_SESSION["takeposterminal"]};
246  // else $conf->global->FACTURE_ADDON = $conf->global->TAKEPOS_ADDON;
247  //}
248 
249  $constantforkey = 'CASHDESK_NO_DECREASE_STOCK'.$_SESSION["takeposterminal"];
250  if ($error) {
251  dol_htmloutput_errors($errormsg, null, 1);
252  } elseif ($invoice->statut != Facture::STATUS_DRAFT) {
253  //If invoice is validated but it is not fully paid is not error and make the payment
254  if ($invoice->getRemainToPay() > 0) {
255  $res = 1;
256  } else {
257  dol_syslog("Sale already validated");
258  dol_htmloutput_errors($langs->trans("InvoiceIsAlreadyValidated", "TakePos"), null, 1);
259  }
260  } elseif (count($invoice->lines) == 0) {
261  $error++;
262  dol_syslog('Sale without lines');
263  dol_htmloutput_errors($langs->trans("NoLinesToBill", "TakePos"), null, 1);
264  } elseif (isModEnabled('stock') && $conf->global->$constantforkey != "1") {
265  $savconst = $conf->global->STOCK_CALCULATE_ON_BILL;
266  $conf->global->STOCK_CALCULATE_ON_BILL = 1;
267 
268  $constantforkey = 'CASHDESK_ID_WAREHOUSE'.$_SESSION["takeposterminal"];
269  dol_syslog("Validate invoice with stock change into warehouse defined into constant ".$constantforkey." = ".$conf->global->$constantforkey);
270  $batch_rule = 0;
271  if (isModEnabled('productbatch') && !empty($conf->global->CASHDESK_FORCE_DECREASE_STOCK)) {
272  require_once DOL_DOCUMENT_ROOT.'/product/class/productbatch.class.php';
274  }
275  $res = $invoice->validate($user, '', $conf->global->$constantforkey, 0, $batch_rule);
276 
277  $conf->global->STOCK_CALCULATE_ON_BILL = $savconst;
278  } else {
279  $res = $invoice->validate($user);
280  if ($res < 0) {
281  $error++;
282  $langs->load("admin");
283  dol_htmloutput_errors($invoice->error == 'NotConfigured' ? $langs->trans("NotConfigured").' (TakePos numbering module)': $invoice->error, $invoice->errors, 1);
284  }
285  }
286 
287  // Restore save values
288  //if (!empty($sav_FACTURE_ADDON))
289  //{
290  // $conf->global->FACTURE_ADDON = $sav_FACTURE_ADDON;
291  //}
292 
293  // Add the payment
294  if (!$error && $res >= 0) {
295  $remaintopay = $invoice->getRemainToPay();
296  if ($remaintopay > 0) {
297  $payment = new Paiement($db);
298  $payment->datepaye = $now;
299  $payment->fk_account = $bankaccount;
300  $payment->amounts[$invoice->id] = $amountofpayment;
301  if ($pay == 'LIQ') {
302  $payment->pos_change = price2num(GETPOST('excess', 'alpha'));
303  }
304 
305  // If user has not used change control, add total invoice payment
306  // Or if user has used change control and the amount of payment is higher than remain to pay, add the remain to pay
307  if ($amountofpayment == 0 || $amountofpayment > $remaintopay) {
308  $payment->amounts[$invoice->id] = $remaintopay;
309  }
310 
311  $payment->paiementid = $paiementid;
312  $payment->num_payment = $invoice->ref;
313 
314  if ($pay != "delayed") {
315  $payment->create($user);
316  $payment->addPaymentToBank($user, 'payment', '(CustomerInvoicePayment)', $bankaccount, '', '');
317  $remaintopay = $invoice->getRemainToPay(); // Recalculate remain to pay after the payment is recorded
318  }
319  }
320 
321  if ($remaintopay == 0) {
322  dol_syslog("Invoice is paid, so we set it to status Paid");
323  $result = $invoice->setPaid($user);
324  if ($result > 0) {
325  $invoice->paye = 1;
326  }
327  // set payment method
328  $invoice->setPaymentMethods($paiementid);
329  } else {
330  dol_syslog("Invoice is not paid, remain to pay = ".$remaintopay);
331  }
332  } else {
333  dol_htmloutput_errors($invoice->error, $invoice->errors, 1);
334  }
335  }
336 
337  if ($action == 'creditnote' && $user->rights->facture->creer) {
338  $creditnote = new Facture($db);
339  $creditnote->socid = $invoice->socid;
340  $creditnote->date = dol_now();
341  $creditnote->module_source = 'takepos';
342  $creditnote->pos_source = isset($_SESSION["takeposterminal"]) ? $_SESSION["takeposterminal"] : '' ;
343  $creditnote->type = Facture::TYPE_CREDIT_NOTE;
344  $creditnote->fk_facture_source = $placeid;
345  $creditnote->remise_absolue = $invoice->remise_absolue;
346  $creditnote->remise_percent = $invoice->remise_percent;
347  $creditnote->create($user);
348 
349  foreach ($invoice->lines as $line) {
350  // Extrafields
351  if (method_exists($line, 'fetch_optionals')) {
352  // load extrafields
353  $line->fetch_optionals();
354  }
355  // Reset fk_parent_line for no child products and special product
356  if (($line->product_type != 9 && empty($line->fk_parent_line)) || $line->product_type == 9) {
357  $fk_parent_line = 0;
358  }
359  if ($invoice->type == Facture::TYPE_SITUATION) {
360  $source_fk_prev_id = $line->fk_prev_id; // temporary storing situation invoice fk_prev_id
361  $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
362  if (!empty($invoice->tab_previous_situation_invoice)) {
363  // search the last standard invoice in cycle and the possible credit note between this last and invoice
364  // TODO Move this out of loop of $invoice->lines
365  $tab_jumped_credit_notes = array();
366  $lineIndex = count($invoice->tab_previous_situation_invoice) - 1;
367  $searchPreviousInvoice = true;
368  while ($searchPreviousInvoice) {
369  if ($invoice->tab_previous_situation_invoice[$lineIndex]->type == Facture::TYPE_SITUATION || $lineIndex < 1) {
370  $searchPreviousInvoice = false; // find, exit;
371  break;
372  } else {
373  if ($invoice->tab_previous_situation_invoice[$lineIndex]->type == Facture::TYPE_CREDIT_NOTE) {
374  $tab_jumped_credit_notes[$lineIndex] = $invoice->tab_previous_situation_invoice[$lineIndex]->id;
375  }
376  $lineIndex--; // go to previous invoice in cycle
377  }
378  }
379 
380  $maxPrevSituationPercent = 0;
381  foreach ($invoice->tab_previous_situation_invoice[$lineIndex]->lines as $prevLine) {
382  if ($prevLine->id == $source_fk_prev_id) {
383  $maxPrevSituationPercent = max($maxPrevSituationPercent, $prevLine->situation_percent);
384 
385  //$line->subprice = $line->subprice - $prevLine->subprice;
386  $line->total_ht = $line->total_ht - $prevLine->total_ht;
387  $line->total_tva = $line->total_tva - $prevLine->total_tva;
388  $line->total_ttc = $line->total_ttc - $prevLine->total_ttc;
389  $line->total_localtax1 = $line->total_localtax1 - $prevLine->total_localtax1;
390  $line->total_localtax2 = $line->total_localtax2 - $prevLine->total_localtax2;
391 
392  $line->multicurrency_subprice = $line->multicurrency_subprice - $prevLine->multicurrency_subprice;
393  $line->multicurrency_total_ht = $line->multicurrency_total_ht - $prevLine->multicurrency_total_ht;
394  $line->multicurrency_total_tva = $line->multicurrency_total_tva - $prevLine->multicurrency_total_tva;
395  $line->multicurrency_total_ttc = $line->multicurrency_total_ttc - $prevLine->multicurrency_total_ttc;
396  }
397  }
398 
399  // prorata
400  $line->situation_percent = $maxPrevSituationPercent - $line->situation_percent;
401 
402  //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>';
403 
404  // If there is some credit note between last situation invoice and invoice used for credit note generation (note: credit notes are stored as delta)
405  $maxPrevSituationPercent = 0;
406  foreach ($tab_jumped_credit_notes as $index => $creditnoteid) {
407  foreach ($invoice->tab_previous_situation_invoice[$index]->lines as $prevLine) {
408  if ($prevLine->fk_prev_id == $source_fk_prev_id) {
409  $maxPrevSituationPercent = $prevLine->situation_percent;
410 
411  $line->total_ht -= $prevLine->total_ht;
412  $line->total_tva -= $prevLine->total_tva;
413  $line->total_ttc -= $prevLine->total_ttc;
414  $line->total_localtax1 -= $prevLine->total_localtax1;
415  $line->total_localtax2 -= $prevLine->total_localtax2;
416 
417  $line->multicurrency_subprice -= $prevLine->multicurrency_subprice;
418  $line->multicurrency_total_ht -= $prevLine->multicurrency_total_ht;
419  $line->multicurrency_total_tva -= $prevLine->multicurrency_total_tva;
420  $line->multicurrency_total_ttc -= $prevLine->multicurrency_total_ttc;
421  }
422  }
423  }
424 
425  // prorata
426  $line->situation_percent += $maxPrevSituationPercent;
427 
428  //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>';
429  }
430  }
431 
432  $line->fk_facture = $creditnote->id;
433  $line->fk_parent_line = $fk_parent_line;
434 
435  $line->subprice = -$line->subprice; // invert price for object
436  $line->pa_ht = $line->pa_ht; // we choosed to have buy/cost price always positive, so no revert of sign here
437  $line->total_ht = -$line->total_ht;
438  $line->total_tva = -$line->total_tva;
439  $line->total_ttc = -$line->total_ttc;
440  $line->total_localtax1 = -$line->total_localtax1;
441  $line->total_localtax2 = -$line->total_localtax2;
442 
443  $line->multicurrency_subprice = -$line->multicurrency_subprice;
444  $line->multicurrency_total_ht = -$line->multicurrency_total_ht;
445  $line->multicurrency_total_tva = -$line->multicurrency_total_tva;
446  $line->multicurrency_total_ttc = -$line->multicurrency_total_ttc;
447 
448  $result = $line->insert(0, 1); // When creating credit note with same lines than source, we must ignore error if discount alreayd linked
449 
450  $creditnote->lines[] = $line; // insert new line in current object
451 
452  // Defined the new fk_parent_line
453  if ($result > 0 && $line->product_type == 9) {
454  $fk_parent_line = $result;
455  }
456  }
457  $creditnote->update_price(1);
458 
459  $constantforkey = 'CASHDESK_NO_DECREASE_STOCK'.$_SESSION["takeposterminal"];
460  if (isModEnabled('stock') && $conf->global->$constantforkey != "1") {
461  $savconst = $conf->global->STOCK_CALCULATE_ON_BILL;
462  $conf->global->STOCK_CALCULATE_ON_BILL = 1;
463  $constantforkey = 'CASHDESK_ID_WAREHOUSE'.$_SESSION["takeposterminal"];
464  dol_syslog("Validate invoice with stock change into warehouse defined into constant ".$constantforkey." = ".$conf->global->$constantforkey);
465  $batch_rule = 0;
466  if (isModEnabled('productbatch') && !empty($conf->global->CASHDESK_FORCE_DECREASE_STOCK)) {
467  require_once DOL_DOCUMENT_ROOT.'/product/class/productbatch.class.php';
469  }
470  $res = $creditnote->validate($user, '', $conf->global->$constantforkey, 0, $batch_rule);
471  $conf->global->STOCK_CALCULATE_ON_BILL = $savconst;
472  } else {
473  $res = $creditnote->validate($user);
474  }
475  }
476 
477  if ($action == 'history' || $action == 'creditnote') {
478  if ($action == 'creditnote') {
479  $placeid = $creditnote->id;
480  } else {
481  $placeid = (int) GETPOST('placeid', 'int');
482  }
483  $invoice = new Facture($db);
484  $invoice->fetch($placeid);
485  }
486 
487  if (($action == "addline" || $action == "freezone") && $placeid == 0) {
488  $invoice->socid = getDolGlobalString("$constforcompanyid");
489  $invoice->date = dol_now();
490  $invoice->module_source = 'takepos';
491  $invoice->pos_source = isset($_SESSION["takeposterminal"]) ? $_SESSION["takeposterminal"] : '' ;
492  $invoice->entity = !empty($_SESSION["takeposinvoiceentity"]) ? $_SESSION["takeposinvoiceentity"] : $conf->entity;
493 
494  if ($invoice->socid <= 0) {
495  $langs->load('errors');
496  dol_htmloutput_errors($langs->trans("ErrorModuleSetupNotComplete", "TakePos"), null, 1);
497  } else {
498  $placeid = $invoice->create($user);
499  if ($placeid < 0) {
500  dol_htmloutput_errors($invoice->error, $invoice->errors, 1);
501  }
502  $sql = "UPDATE ".MAIN_DB_PREFIX."facture set ref='(PROV-POS".$_SESSION["takeposterminal"]."-".$place.")' where rowid = ".((int) $placeid);
503  $db->query($sql);
504  }
505  }
506 
507  if ($action == "addline") {
508  $prod = new Product($db);
509  $prod->fetch($idproduct);
510 
511  $customer = new Societe($db);
512  $customer->fetch($invoice->socid);
513 
514  $datapriceofproduct = $prod->getSellPrice($mysoc, $customer, 0);
515 
516  $qty = GETPOSTISSET('qty') ? GETPOST('qty', 'int') : 1;
517  $price = $datapriceofproduct['pu_ht'];
518  $price_ttc = $datapriceofproduct['pu_ttc'];
519  //$price_min = $datapriceofproduct['price_min'];
520  $price_base_type = empty($datapriceofproduct['price_base_type']) ? 'HT' : $datapriceofproduct['price_base_type'];
521  $tva_tx = $datapriceofproduct['tva_tx'];
522  $tva_npr = $datapriceofproduct['tva_npr'];
523 
524  // Local Taxes
525  $localtax1_tx = get_localtax($tva_tx, 1, $customer, $mysoc, $tva_npr);
526  $localtax2_tx = get_localtax($tva_tx, 2, $customer, $mysoc, $tva_npr);
527 
528  if (!empty($conf->global->TAKEPOS_SUPPLEMENTS)) {
529  require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
530  $cat = new Categorie($db);
531  $categories = $cat->containing($idproduct, 'product');
532  $found = (array_search($conf->global->TAKEPOS_SUPPLEMENTS_CATEGORY, array_column($categories, 'id')));
533  if ($found !== false) { // If this product is a supplement
534  $sql = "SELECT fk_parent_line FROM ".MAIN_DB_PREFIX."facturedet where rowid=$selectedline";
535  $resql = $db->query($sql);
536  $row = $db->fetch_array($resql);
537  if ($row[0] == null) {
538  $parent_line = $selectedline;
539  } else {
540  $parent_line = $row[0]; //If the parent line is already a supplement, add the supplement to the main product
541  }
542  }
543  }
544 
545  $idoflineadded = 0;
546  // Group if enabled. Skip group if line already sent to the printer
547  if (!empty($conf->global->TAKEPOS_GROUP_SAME_PRODUCT) && $line->special_code != "4") {
548  foreach ($invoice->lines as $line) {
549  if ($line->product_ref == $prod->ref) {
550  if ($line->special_code==4) continue; // If this line is sended to printer create new line
551  $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);
552  if ($result < 0) {
553  dol_htmloutput_errors($invoice->error, $invoice->errors, 1);
554  } else {
555  $idoflineadded = $line->id;
556  }
557  break;
558  }
559  }
560  }
561  if ($idoflineadded <= 0) {
562  $invoice->fetch_thirdparty();
563  $array_options = array();
564 
565  // complete line by hook
566  $parameters = array('prod' => $prod);
567  $reshook=$hookmanager->executeHooks('completeTakePosAddLine', $parameters, $invoice, $action);
568  if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
569 
570  if (empty($reshook)) {
571  $idoflineadded = $invoice->addline($prod->description, $price, $qty, $tva_tx, $localtax1_tx, $localtax2_tx, $idproduct, $customer->remise_percent, '', 0, 0, 0, '', $price_base_type, $price_ttc, $prod->type, -1, 0, '', 0, (!empty($parent_line)) ? $parent_line : '', null, '', '', $array_options, 100, '', null, 0);
572  }
573 
574  if (!empty($conf->global->TAKEPOS_CUSTOMER_DISPLAY)) {
575  $CUSTOMER_DISPLAY_line1 = $prod->label;
576  $CUSTOMER_DISPLAY_line2 = price($price_ttc);
577  }
578  }
579 
580  $invoice->fetch($placeid);
581  }
582 
583  if ($action == "freezone") {
584  $customer = new Societe($db);
585  $customer->fetch($invoice->socid);
586 
587  $tva_tx = GETPOST('tva_tx', 'alpha');
588  if ($tva_tx != '') {
589  if (!preg_match('/\((.*)\)/', $tva_tx)) {
590  $tva_tx = price2num($tva_tx);
591  }
592  } else {
593  $tva_tx = get_default_tva($mysoc, $customer);
594  }
595 
596  // Local Taxes
597  $localtax1_tx = get_localtax($tva_tx, 1, $customer, $mysoc, $tva_npr);
598  $localtax2_tx = get_localtax($tva_tx, 2, $customer, $mysoc, $tva_npr);
599 
600  $invoice->addline($desc, $number, 1, $tva_tx, $localtax1_tx, $localtax2_tx, 0, 0, '', 0, 0, 0, '', getDolGlobalInt('TAKEPOS_CHANGE_PRICE_HT') ? 'HT' : 'TTC', $number, 0, -1, 0, '', 0, 0, null, '', '', 0, 100, '', null, 0);
601  $invoice->fetch($placeid);
602  }
603 
604  if ($action == "addnote") {
605  $desc = GETPOST('addnote', 'alpha');
606  if ($idline==0) {
607  $invoice->update_note($desc, '_public');
608  } else foreach ($invoice->lines as $line) {
609  if ($line->id == $idline) {
610  $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);
611  }
612  }
613  $invoice->fetch($placeid);
614  }
615 
616  if ($action == "deleteline") {
617  if ($idline > 0 and $placeid > 0) { // If invoice exists and line selected. To avoid errors if deleted from another device or no line selected.
618  $invoice->deleteline($idline);
619  $invoice->fetch($placeid);
620  } elseif ($placeid > 0) { // If invoice exists but no line selected, proceed to delete last line.
621  $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."facturedet where fk_facture = ".((int) $placeid)." ORDER BY rowid DESC";
622  $resql = $db->query($sql);
623  $row = $db->fetch_array($resql);
624  $deletelineid = $row[0];
625  $invoice->deleteline($deletelineid);
626  $invoice->fetch($placeid);
627  }
628  if (count($invoice->lines) == 0) {
629  $invoice->delete($user);
630  header("Location: ".DOL_URL_ROOT."/takepos/invoice.php");
631  exit;
632  }
633  }
634 
635  // Action to delete or discard an invoice
636  if ($action == "delete") {
637  // $placeid is the invoice id (it differs from place) and is defined if the place is set and the ref of invoice is '(PROV-POS'.$_SESSION["takeposterminal"].'-'.$place.')', so the fetch at begining of page works.
638  if ($placeid > 0) {
639  $result = $invoice->fetch($placeid);
640 
641  if ($result > 0 && $invoice->statut == Facture::STATUS_DRAFT) {
642  $db->begin();
643 
644  // We delete the lines
645  $resdeletelines = 1;
646  foreach ($invoice->lines as $line) {
647  $tmpres = $invoice->deleteline($line->id);
648  if ($tmpres < 0) {
649  $resdeletelines = 0;
650  break;
651  }
652  }
653 
654  $sql = "UPDATE ".MAIN_DB_PREFIX."facture";
655  $varforconst = 'CASHDESK_ID_THIRDPARTY'.$_SESSION["takeposterminal"];
656  $sql .= " SET fk_soc = ".((int) $conf->global->$varforconst).", ";
657  $sql .= " datec = '".$db->idate(dol_now())."'";
658  $sql .= " WHERE ref = '(PROV-POS".$db->escape($_SESSION["takeposterminal"]."-".$place).")'";
659  $resql1 = $db->query($sql);
660 
661  if ($resdeletelines && $resql1) {
662  $db->commit();
663  } else {
664  $db->rollback();
665  }
666 
667  $invoice->fetch($placeid);
668  }
669  }
670  }
671 
672  if ($action == "updateqty") {
673  foreach ($invoice->lines as $line) {
674  if ($line->id == $idline) {
675  if (!$user->rights->takepos->editlines || (!$user->rights->takepos->editorderedlines && $line->special_code == "4")) {
676  dol_htmloutput_errors($langs->trans("NotEnoughPermissions", "TakePos"), null, 1);
677  } else {
678  $result = $invoice->updateline($line->id, $line->desc, $line->subprice, $number, $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);
679  }
680  }
681  }
682 
683  $invoice->fetch($placeid);
684  }
685 
686  if ($action == "updateprice") {
687  $customer = new Societe($db);
688  $customer->fetch($invoice->socid);
689 
690  foreach ($invoice->lines as $line) {
691  if ($line->id == $idline) {
692  $prod = new Product($db);
693  $prod->fetch($line->fk_product);
694  $datapriceofproduct = $prod->getSellPrice($mysoc, $customer, 0);
695  $price_min = $datapriceofproduct['price_min'];
696  $usercanproductignorepricemin = ((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->produit->ignore_price_min_advance)) || empty($conf->global->MAIN_USE_ADVANCED_PERMS));
697  $pu_ht = price2num($number / (1 + ($line->tva_tx / 100)), 'MU');
698  //Check min price
699  if ($usercanproductignorepricemin && (!empty($price_min) && (price2num($pu_ht) * (1 - price2num($line->remise_percent) / 100) < price2num($price_min)))) {
700  echo $langs->trans("CantBeLessThanMinPrice");
701  } else {
702  if (empty($user->rights->takepos->editlines) || (empty($user->rights->takepos->editorderedlines) && $line->special_code == "4")) {
703  dol_htmloutput_errors($langs->trans("NotEnoughPermissions", "TakePos"), null, 1);
704  } elseif (getDolGlobalInt('TAKEPOS_CHANGE_PRICE_HT') == 1) {
705  $result = $invoice->updateline($line->id, $line->desc, $number, $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);
706  } else {
707  $result = $invoice->updateline($line->id, $line->desc, $number, $line->qty, $line->remise_percent, $line->date_start, $line->date_end, $line->tva_tx, $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);
708  }
709  }
710  }
711  }
712 
713  // Reload data
714  $invoice->fetch($placeid);
715  }
716 
717  if ($action == "updatereduction") {
718  $customer = new Societe($db);
719  $customer->fetch($invoice->socid);
720 
721  foreach ($invoice->lines as $line) {
722  if ($line->id == $idline) {
723  dol_syslog("updatereduction Process line ".$line->id.' to apply discount of '.$number.'%');
724 
725  $prod = new Product($db);
726  $prod->fetch($line->fk_product);
727 
728  $datapriceofproduct = $prod->getSellPrice($mysoc, $customer, 0);
729  $price_min = $datapriceofproduct['price_min'];
730  $usercanproductignorepricemin = ((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->produit->ignore_price_min_advance)) || empty($conf->global->MAIN_USE_ADVANCED_PERMS));
731 
732  $pu_ht = price2num($line->subprice / (1 + ($line->tva_tx / 100)), 'MU');
733 
734  // Check min price
735  if ($usercanproductignorepricemin && (!empty($price_min) && (price2num($line->subprice) * (1 - price2num($number) / 100) < price2num($price_min)))) {
736  echo $langs->trans("CantBeLessThanMinPrice");
737  } else {
738  if (empty($user->rights->takepos->editlines) || (empty($user->rights->takepos->editorderedlines) && $line->special_code == "4")) {
739  dol_htmloutput_errors($langs->trans("NotEnoughPermissions", "TakePos"), null, 1);
740  } else {
741  $result = $invoice->updateline($line->id, $line->desc, $line->subprice, $line->qty, $number, $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);
742  }
743  }
744  }
745  }
746 
747  // Reload data
748  $invoice->fetch($placeid);
749  } elseif ($action == 'update_reduction_global') {
750  foreach ($invoice->lines as $line) {
751  $result = $invoice->updateline($line->id, $line->desc, $line->subprice, $line->qty, $number, $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);
752  }
753 
754  $invoice->fetch($placeid);
755  }
756 
757  if ($action == "order" and $placeid != 0) {
758  include_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
759  if ($conf->global->TAKEPOS_PRINT_METHOD == "receiptprinter" || $conf->global->TAKEPOS_PRINT_METHOD == "takeposconnector") {
760  require_once DOL_DOCUMENT_ROOT.'/core/class/dolreceiptprinter.class.php';
761  $printer = new dolReceiptPrinter($db);
762  }
763 
764  $sql = "SELECT label FROM ".MAIN_DB_PREFIX."takepos_floor_tables where rowid=".((int) $place);
765  $resql = $db->query($sql);
766  $row = $db->fetch_object($resql);
767  $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>';
768  $footerorder = '</tbody></table>'.dol_print_date(dol_now(), 'dayhour').'<br></html>';
769  $order_receipt_printer1 = "";
770  $order_receipt_printer2 = "";
771  $order_receipt_printer3 = "";
772  $catsprinter1 = explode(';', $conf->global->TAKEPOS_PRINTED_CATEGORIES_1);
773  $catsprinter2 = explode(';', $conf->global->TAKEPOS_PRINTED_CATEGORIES_2);
774  $catsprinter3 = explode(';', $conf->global->TAKEPOS_PRINTED_CATEGORIES_3);
775  $linestoprint = 0;
776  foreach ($invoice->lines as $line) {
777  if ($line->special_code == "4") {
778  continue;
779  }
780  $c = new Categorie($db);
781  $existing = $c->containing($line->fk_product, Categorie::TYPE_PRODUCT, 'id');
782  $result = array_intersect($catsprinter1, $existing);
783  $count = count($result);
784  if (!$line->fk_product) {
785  $count++; // Print Free-text item (Unassigned printer) to Printer 1
786  }
787  if ($count > 0) {
788  $linestoprint++;
789  $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet set special_code='1' where rowid=".$line->id; //Set to print on printer 1
790  $db->query($sql);
791  $order_receipt_printer1 .= '<tr><td class="left">';
792  if ($line->fk_product) {
793  $order_receipt_printer1 .= $line->product_label;
794  } else {
795  $order_receipt_printer1 .= $line->description;
796  }
797  $order_receipt_printer1 .= '</td><td class="right">'.$line->qty;
798  if (!empty($line->array_options['options_order_notes'])) {
799  $order_receipt_printer1 .= "<br>(".$line->array_options['options_order_notes'].")";
800  }
801  $order_receipt_printer1 .= '</td></tr>';
802  }
803  }
804  if (($conf->global->TAKEPOS_PRINT_METHOD == "receiptprinter" || $conf->global->TAKEPOS_PRINT_METHOD == "takeposconnector") && $linestoprint > 0) {
805  $invoice->fetch($placeid); //Reload object before send to printer
806  $printer->orderprinter = 1;
807  echo "<script>";
808  echo "var orderprinter1esc='";
809  $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
810  echo "';</script>";
811  }
812  $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet set special_code='4' where special_code='1' and fk_facture=".$invoice->id; // Set as printed
813  $db->query($sql);
814  $invoice->fetch($placeid); //Reload object after set lines as printed
815  $linestoprint = 0;
816 
817  foreach ($invoice->lines as $line) {
818  if ($line->special_code == "4") {
819  continue;
820  }
821  $c = new Categorie($db);
822  $existing = $c->containing($line->fk_product, Categorie::TYPE_PRODUCT, 'id');
823  $result = array_intersect($catsprinter2, $existing);
824  $count = count($result);
825  if ($count > 0) {
826  $linestoprint++;
827  $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet set special_code='2' where rowid=".$line->id; //Set to print on printer 2
828  $db->query($sql);
829  $order_receipt_printer2 .= '<tr>'.$line->product_label.'<td class="right">'.$line->qty;
830  if (!empty($line->array_options['options_order_notes'])) {
831  $order_receipt_printer2 .= "<br>(".$line->array_options['options_order_notes'].")";
832  }
833  $order_receipt_printer2 .= '</td></tr>';
834  }
835  }
836  if (($conf->global->TAKEPOS_PRINT_METHOD == "receiptprinter" || $conf->global->TAKEPOS_PRINT_METHOD == "takeposconnector") && $linestoprint > 0) {
837  $invoice->fetch($placeid); //Reload object before send to printer
838  $printer->orderprinter = 2;
839  echo "<script>";
840  echo "var orderprinter2esc='";
841  $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
842  echo "';</script>";
843  }
844  $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet set special_code='4' where special_code='2' and fk_facture=".$invoice->id; // Set as printed
845  $db->query($sql);
846  $invoice->fetch($placeid); //Reload object after set lines as printed
847  $linestoprint = 0;
848 
849  foreach ($invoice->lines as $line) {
850  if ($line->special_code == "4") {
851  continue;
852  }
853  $c = new Categorie($db);
854  $existing = $c->containing($line->fk_product, Categorie::TYPE_PRODUCT, 'id');
855  $result = array_intersect($catsprinter3, $existing);
856  $count = count($result);
857  if ($count > 0) {
858  $linestoprint++;
859  $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet set special_code='3' where rowid=".$line->id; //Set to print on printer 3
860  $db->query($sql);
861  $order_receipt_printer3 .= '<tr>'.$line->product_label.'<td class="right">'.$line->qty;
862  if (!empty($line->array_options['options_order_notes'])) {
863  $order_receipt_printer3 .= "<br>(".$line->array_options['options_order_notes'].")";
864  }
865  $order_receipt_printer3 .= '</td></tr>';
866  }
867  }
868  if (($conf->global->TAKEPOS_PRINT_METHOD == "receiptprinter" || $conf->global->TAKEPOS_PRINT_METHOD == "takeposconnector") && $linestoprint > 0) {
869  $invoice->fetch($placeid); //Reload object before send to printer
870  $printer->orderprinter = 3;
871  echo "<script>";
872  echo "var orderprinter3esc='";
873  $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
874  echo "';</script>";
875  }
876  $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet set special_code='4' where special_code='3' and fk_facture=".$invoice->id; // Set as printed
877  $db->query($sql);
878  $invoice->fetch($placeid); //Reload object after set lines as printed
879  }
880 
881  $sectionwithinvoicelink = '';
882  if ($action == "valid" || $action == "history" || $action == 'creditnote') {
883  $sectionwithinvoicelink .= '<!-- Section with invoice link -->'."\n";
884  $sectionwithinvoicelink .= '<span style="font-size:120%;" class="center">';
885  $sectionwithinvoicelink .= $invoice->getNomUrl(1, '', 0, 0, '', 0, 0, -1, '_backoffice')." - ";
886  $remaintopay = $invoice->getRemainToPay();
887  if ($remaintopay > 0) {
888  $sectionwithinvoicelink .= $langs->trans('RemainToPay').': <span class="amountremaintopay" style="font-size: unset">'.price($remaintopay, 1, $langs, 1, -1, -1, $conf->currency).'</span>';
889  } else {
890  if ($invoice->paye) {
891  $sectionwithinvoicelink .= '<span class="amountpaymentcomplete" style="font-size: unset">'.$langs->trans("Paid").'</span>';
892  } else {
893  $sectionwithinvoicelink .= $langs->trans('BillShortStatusValidated');
894  }
895  }
896  $sectionwithinvoicelink .= '</span><br>';
897  if (getDolGlobalString('TAKEPOS_PRINT_METHOD') == "takeposconnector") {
898  if (getDolGlobalString('TAKEPOS_PRINT_SERVER') && filter_var($conf->global->TAKEPOS_PRINT_SERVER, FILTER_VALIDATE_URL) == true) {
899  $sectionwithinvoicelink .= ' <button id="buttonprint" type="button" onclick="TakeposConnector('.$placeid.');">'.$langs->trans('PrintTicket').'</button>';
900  } else {
901  $sectionwithinvoicelink .= ' <button id="buttonprint" type="button" onclick="TakeposPrinting('.$placeid.');">'.$langs->trans('PrintTicket').'</button>';
902  }
903  } elseif (getDolGlobalString('TAKEPOS_PRINT_METHOD') == "receiptprinter") {
904  $sectionwithinvoicelink .= ' <button id="buttonprint" type="button" onclick="DolibarrTakeposPrinting('.$placeid.');">'.$langs->trans('PrintTicket').'</button>';
905  } else {
906  $sectionwithinvoicelink .= ' <button id="buttonprint" type="button" onclick="Print('.$placeid.');">'.$langs->trans('PrintTicket').'</button>';
907  if (getDolGlobalString('TAKEPOS_PRINT_WITHOUT_DETAILS')) {
908  $sectionwithinvoicelink .= ' <button id="buttonprint" type="button" onclick="PrintBox('.$placeid.', \'without_details\');">'.$langs->trans('PrintWithoutDetails').'</button>';
909  }
910  if (getDolGlobalString('TAKEPOS_GIFT_RECEIPT')) {
911  $sectionwithinvoicelink .= ' <button id="buttonprint" type="button" onclick="Print('.$placeid.', 1);">'.$langs->trans('GiftReceipt').'</button>';
912  }
913  }
914  if (getDolGlobalString('TAKEPOS_EMAIL_TEMPLATE_INVOICE') && $conf->global->TAKEPOS_EMAIL_TEMPLATE_INVOICE > 0) {
915  $sectionwithinvoicelink .= ' <button id="buttonsend" type="button" onclick="SendTicket('.$placeid.');">'.$langs->trans('SendTicket').'</button>';
916  }
917 
918  if ($remaintopay <= 0 && getDolGlobalString('TAKEPOS_AUTO_PRINT_TICKETS') && $action != "history") {
919  $sectionwithinvoicelink .= '<script type="text/javascript">$("#buttonprint").click();</script>';
920  }
921  }
922 }
923 
924 /*
925  * View
926  */
927 
928 $form = new Form($db);
929 
930 ?>
931 <script type="text/javascript">
932 var selectedline=0;
933 var selectedtext="";
934 <?php if ($action=="valid") echo "var place=0;";?> // Set to default place after close sale
935 var placeid=<?php echo ($placeid > 0 ? $placeid : 0); ?>;
936 $(document).ready(function() {
937  var idoflineadded = <?php echo (empty($idoflineadded) ? 0 : $idoflineadded); ?>;
938 
939  $('.posinvoiceline').click(function(){
940  console.log("Click done on "+this.id);
941  $('.posinvoiceline').removeClass("selected");
942  $(this).addClass("selected");
943  if (selectedline==this.id) return; // If is already selected
944  else selectedline=this.id;
945  selectedtext=$('#'+selectedline).find("td:first").html();
946  <?php
947  if (defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE')) {
948  print '$("#phonediv1").load("auto_order.php?action=editline&token='.newToken().'&placeid="+placeid+"&selectedline="+selectedline, function() {
949  });';
950  }
951  ?>
952  });
953 
954  /* Autoselect the line */
955  if (idoflineadded > 0)
956  {
957  console.log("Auto select "+idoflineadded);
958  $('.posinvoiceline#'+idoflineadded).click();
959  }
960 <?php
961 
962 if ($action == "order" && !empty($order_receipt_printer1)) {
963  if (filter_var($conf->global->TAKEPOS_PRINT_SERVER, FILTER_VALIDATE_URL) == true) {
964  ?>
965  $.ajax({
966  type: "POST",
967  url: '<?php print $conf->global->TAKEPOS_PRINT_SERVER; ?>/printer/index.php',
968  data: 'invoice='+orderprinter1esc
969  });
970  <?php
971  } else {
972  ?>
973  $.ajax({
974  type: "POST",
975  url: 'http://<?php print $conf->global->TAKEPOS_PRINT_SERVER; ?>:8111/print',
976  data: '<?php
977  print $headerorder.$order_receipt_printer1.$footerorder; ?>'
978  });
979  <?php
980  }
981 }
982 
983 if ($action == "order" && !empty($order_receipt_printer2)) {
984  if (filter_var($conf->global->TAKEPOS_PRINT_SERVER, FILTER_VALIDATE_URL) == true) {
985  ?>
986  $.ajax({
987  type: "POST",
988  url: '<?php print $conf->global->TAKEPOS_PRINT_SERVER; ?>/printer/index.php?printer=2',
989  data: 'invoice='+orderprinter2esc
990  });
991  <?php
992  } else {
993  ?>
994  $.ajax({
995  type: "POST",
996  url: 'http://<?php print $conf->global->TAKEPOS_PRINT_SERVER; ?>:8111/print2',
997  data: '<?php
998  print $headerorder.$order_receipt_printer2.$footerorder; ?>'
999  });
1000  <?php
1001  }
1002 }
1003 
1004 if ($action == "order" && !empty($order_receipt_printer3)) {
1005  if (filter_var($conf->global->TAKEPOS_PRINT_SERVER, FILTER_VALIDATE_URL) == true) {
1006  ?>
1007  $.ajax({
1008  type: "POST",
1009  url: '<?php print $conf->global->TAKEPOS_PRINT_SERVER; ?>/printer/index.php?printer=3',
1010  data: 'invoice='+orderprinter3esc
1011  });
1012  <?php
1013  }
1014 }
1015 
1016 // Set focus to search field
1017 if ($action == "search" || $action == "valid") {
1018  ?>
1019  parent.setFocusOnSearchField();
1020  <?php
1021 }
1022 
1023 
1024 if ($action == "temp" && !empty($ticket_printer1)) {
1025  ?>
1026  $.ajax({
1027  type: "POST",
1028  url: 'http://<?php print $conf->global->TAKEPOS_PRINT_SERVER; ?>:8111/print',
1029  data: '<?php
1030  print $header_soc.$header_ticket.$body_ticket.$ticket_printer1.$ticket_total.$footer_ticket; ?>'
1031  });
1032  <?php
1033 }
1034 
1035 if ($action == "search") {
1036  ?>
1037  $('#search').focus();
1038  <?php
1039 }
1040 
1041 ?>
1042 
1043 });
1044 
1045 function SendTicket(id)
1046 {
1047  console.log("Open box to select the Print/Send form");
1048  $.colorbox({href:"send.php?facid="+id, width:"70%", height:"30%", transition:"none", iframe:"true", title:'<?php echo dol_escape_js($langs->trans("SendTicket")); ?>'});
1049 }
1050 
1051 function PrintBox(id, action) {
1052  console.log("Open box before printing");
1053  $.colorbox({href:"printbox.php?facid="+id+"&action="+action, width:"80%", height:"200px", transition:"none", iframe:"true", title:"<?php echo $langs->trans("PrintWithoutDetails"); ?>"});
1054 }
1055 
1056 function Print(id, gift){
1057  console.log("Call Print() to generate the receipt.");
1058  $.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")); ?>'});
1059 }
1060 
1061 function TakeposPrinting(id){
1062  var receipt;
1063  console.log("TakeposPrinting" + id);
1064  $.get("receipt.php?facid="+id, function(data, status){
1065  receipt=data.replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '');
1066  $.ajax({
1067  type: "POST",
1068  url: 'http://<?php print getDolGlobalString('TAKEPOS_PRINT_SERVER'); ?>:8111/print',
1069  data: receipt
1070  });
1071  });
1072 }
1073 
1074 function TakeposConnector(id){
1075  console.log("TakeposConnector" + id);
1076  $.get("<?php echo DOL_URL_ROOT; ?>/takepos/ajax/ajax.php?action=printinvoiceticket&term=<?php echo urlencode(isset($_SESSION["takeposterminal"]) ? $_SESSION["takeposterminal"] : ''); ?>&id="+id+"&token=<?php echo currentToken(); ?>", function(data, status) {
1077  $.ajax({
1078  type: "POST",
1079  url: '<?php print getDolGlobalString('TAKEPOS_PRINT_SERVER'); ?>/printer/index.php',
1080  data: 'invoice='+data
1081  });
1082  });
1083 }
1084 
1085 function DolibarrTakeposPrinting(id) {
1086  console.log("DolibarrTakeposPrinting Printing invoice ticket " + id)
1087  $.ajax({
1088  type: "GET",
1089  data: { token: '<?php echo currentToken(); ?>' },
1090  url: "<?php print DOL_URL_ROOT.'/takepos/ajax/ajax.php?action=printinvoiceticket&term='.urlencode(isset($_SESSION["takeposterminal"]) ? $_SESSION["takeposterminal"] : '').'&id='; ?>" + id,
1091  });
1092 }
1093 
1094 function CreditNote() {
1095  $("#poslines").load("invoice.php?action=creditnote&token=<?php echo newToken() ?>&invoiceid="+placeid, function() {
1096  });
1097 }
1098 
1099 function SetNote() {
1100  $("#poslines").load("invoice.php?action=addnote&token=<?php echo newToken() ?>&invoiceid="+placeid+"&idline="+selectedline, { "addnote": $("#textinput").val() });
1101 }
1102 
1103 
1104 $( document ).ready(function() {
1105  console.log("Set customer info and sales in header placeid=<?php echo $placeid; ?> status=<?php echo $invoice->statut; ?>");
1106 
1107  <?php
1108  $s = $langs->trans("Customer");
1109  if ($invoice->id > 0 && ($invoice->socid != $conf->global->$constforcompanyid)) {
1110  $s = $soc->name;
1111  }
1112  ?>
1113 
1114  $("#customerandsales").html('');
1115  $("#shoppingcart").html('');
1116 
1117  $("#customerandsales").append('<a class="valignmiddle tdoverflowmax100 minwidth100" id="customer" onclick="Customer();" title="<?php print dol_escape_js($s); ?>"><span class="fas fa-building paddingrightonly"></span><?php print dol_escape_js($s); ?></a>');
1118 
1119  <?php
1120  $sql = "SELECT rowid, datec, ref FROM ".MAIN_DB_PREFIX."facture";
1121  if (empty($conf->global->TAKEPOS_CAN_EDIT_IF_ALREADY_VALIDATED)) {
1122  // By default, only invoices with a ref not already defined can in list of open invoice we can edit.
1123  $sql .= " WHERE ref LIKE '(PROV-POS".$db->escape(isset($_SESSION["takeposterminal"]) ? $_SESSION["takeposterminal"] : '')."-0%' AND entity IN (".getEntity('invoice').")";
1124  } else {
1125  // If TAKEPOS_CAN_EDIT_IF_ALREADY_VALIDATED set, we show also draft invoice that already has a reference defined
1126  $sql .= " WHERE pos_source = '".$db->escape($_SESSION["takeposterminal"])."'";
1127  $sql .= " AND module_source = 'takepos'";
1128  $sql .= " AND entity IN (".getEntity('invoice').")";
1129  }
1130 
1131  $sql .= $db->order('datec', 'ASC');
1132  $resql = $db->query($sql);
1133  if ($resql) {
1134  $max_sale = 0;
1135  while ($obj = $db->fetch_object($resql)) {
1136  echo '$("#shoppingcart").append(\'';
1137  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=\\\'';
1138  $num_sale = str_replace(")", "", str_replace("(PROV-POS".$_SESSION["takeposterminal"]."-", "", $obj->ref));
1139  echo $num_sale;
1140  if (str_replace("-", "", $num_sale) > $max_sale) {
1141  $max_sale = str_replace("-", "", $num_sale);
1142  }
1143  echo '\\\'; invoiceid=\\\'';
1144  echo $obj->rowid;
1145  echo '\\\'; Refresh();">';
1146  if ($placeid == $obj->rowid) {
1147  echo "<b>";
1148  }
1149  echo '<span class="fa fa-shopping-cart paddingright"></span>'.dol_print_date($db->jdate($obj->datec), '%H:%M', 'tzuser');
1150  if ($placeid == $obj->rowid) {
1151  echo "</b>";
1152  }
1153  echo '</a>\');';
1154  }
1155  echo '$("#shoppingcart").append(\'<a onclick="place=\\\'0-';
1156  echo $max_sale + 1;
1157  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>\');';
1158  } else {
1159  dol_print_error($db);
1160  }
1161 
1162  $s = '';
1163 
1164  $idwarehouse = 0;
1165  $constantforkey = 'CASHDESK_NO_DECREASE_STOCK'. (isset($_SESSION["takeposterminal"]) ? $_SESSION["takeposterminal"] : '');
1166  if (isModEnabled('stock')) {
1167  if (getDolGlobalString("$constantforkey") != "1") {
1168  $constantforkey = 'CASHDESK_ID_WAREHOUSE'. (isset($_SESSION["takeposterminal"]) ? $_SESSION["takeposterminal"] : '');
1169  $idwarehouse = getDolGlobalString($constantforkey);
1170  if ($idwarehouse > 0) {
1171  $s = '<span class="small">';
1172  $warehouse = new Entrepot($db);
1173  $warehouse->fetch($idwarehouse);
1174  $s .= '<span class="hideonsmartphone">'.$langs->trans("Warehouse").'<br></span>'.$warehouse->ref;
1175  if ($warehouse->statut == Entrepot::STATUS_CLOSED) {
1176  $s .= ' ('.$langs->trans("Closed").')';
1177  }
1178  $s .= '</span>';
1179  print "$('#infowarehouse').html('".dol_escape_js($s)."');";
1180  print '$("#infowarehouse").css("display", "inline-block");';
1181  } else {
1182  $s = '<span class="small hideonsmartphone">';
1183  $s .= $langs->trans("StockChangeDisabled").'<br>'.$langs->trans("NoWarehouseDefinedForTerminal");
1184  $s .= '</span>';
1185  print "$('#infowarehouse').html('".dol_escape_js($s)."');";
1186  if (!empty($conf->dol_optimize_smallscreen)) {
1187  print '$("#infowarehouse").css("display", "none");';
1188  }
1189  }
1190  } else {
1191  $s = '<span class="small hideonsmartphone">'.$langs->trans("StockChangeDisabled").'</span>';
1192  print "$('#infowarehouse').html('".dol_escape_js($s)."');";
1193  if (!empty($conf->dol_optimize_smallscreen)) {
1194  print '$("#infowarehouse").css("display", "none");';
1195  }
1196  }
1197  }
1198 
1199 
1200  // Module Adherent
1201  $s = '';
1202  if (isModEnabled('adherent') && $invoice->socid > 0 && $invoice->socid != $conf->global->$constforcompanyid) {
1203  $s = '<span class="small">';
1204  require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
1205  $langs->load("members");
1206  $s .= $langs->trans("Member").': ';
1207  $adh = new Adherent($db);
1208  $result = $adh->fetch('', '', $invoice->socid);
1209  if ($result > 0) {
1210  $adh->ref = $adh->getFullName($langs);
1211  if (empty($adh->statut) || $adh->statut == Adherent::STATUS_EXCLUDED ) {
1212  $s .= "<s>";
1213  }
1214  $s .= $adh->getFullName($langs);
1215  $s .= ' - '.$adh->type;
1216  if ($adh->datefin) {
1217  $s .= '<br>'.$langs->trans("SubscriptionEndDate").': '.dol_print_date($adh->datefin, 'day');
1218  if ($adh->hasDelay()) {
1219  $s .= " ".img_warning($langs->trans("Late"));
1220  }
1221  } else {
1222  $s .= '<br>'.$langs->trans("SubscriptionNotReceived");
1223  if ($adh->statut > 0) {
1224  $s .= " ".img_warning($langs->trans("Late")); // displays delay Pictogram only if not a draft and not terminated
1225  }
1226  }
1227  if (empty($adh->statut) || $adh->statut == Adherent::STATUS_EXCLUDED) {
1228  $s .= "</s>";
1229  }
1230  } else {
1231  $s .= '<br>'.$langs->trans("ThirdpartyNotLinkedToMember");
1232  }
1233  $s .= '</span>';
1234  }
1235  ?>
1236  $("#moreinfo").html('<?php print dol_escape_js($s); ?>');
1237 
1238 });
1239 
1240 
1241 <?php
1242 if (!empty($conf->global->TAKEPOS_CUSTOMER_DISPLAY)) {
1243  echo "function CustomerDisplay(){";
1244  echo "var line1='".$CUSTOMER_DISPLAY_line1."'.substring(0,20);";
1245  echo "line1=line1.padEnd(20);";
1246  echo "var line2='".$CUSTOMER_DISPLAY_line2."'.substring(0,20);";
1247  echo "line2=line2.padEnd(20);";
1248  echo "$.ajax({
1249  type: 'GET',
1250  data: { text: line1+line2 },
1251  url: '".getDolGlobalString('TAKEPOS_PRINT_SERVER')."/display/index.php',
1252  });";
1253  echo "}";
1254 }
1255 ?>
1256 
1257 </script>
1258 
1259 <?php
1260 // Add again js for footer because this content is injected into index.php page so all init
1261 // for tooltip and other js beautifiers must be reexecuted too.
1262 if (!empty($conf->use_javascript_ajax)) {
1263  print "\n".'<!-- Includes JS Footer of Dolibarr -->'."\n";
1264  print '<script src="'.DOL_URL_ROOT.'/core/js/lib_foot.js.php?lang='.$langs->defaultlang.'"></script>'."\n";
1265 }
1266 
1267 print '<!-- invoice.php place='.(int) $place.' invoice='.$invoice->ref.' mobilepage='.(empty($mobilepage) ? '' : $mobilepage).' $_SESSION["basiclayout"]='.(empty($_SESSION["basiclayout"])?'':$_SESSION["basiclayout"]).' conf->global->TAKEPOS_BAR_RESTAURANT='.getDolGlobalString('TAKEPOS_BAR_RESTAURANT').' -->'."\n";
1268 print '<div class="div-table-responsive-no-min invoice">';
1269 print '<table id="tablelines" class="noborder noshadow postablelines" width="100%">';
1270 if ($sectionwithinvoicelink && ($mobilepage == "invoice" || $mobilepage == "")) {
1271  if (!empty($conf->global->TAKEPOS_SHOW_HT)) {
1272  print '<tr><td colspan="5">'.$sectionwithinvoicelink.'</td></tr>';
1273  } else {
1274  print '<tr><td colspan="4">'.$sectionwithinvoicelink.'</td></tr>';
1275  }
1276 }
1277 print '<tr class="liste_titre nodrag nodrop">';
1278 print '<td class="linecoldescription">';
1279 // In phone version only show when it is invoice page
1280 if (empty($mobilepage) || $mobilepage == "invoice") {
1281  print '<input type="hidden" name="invoiceid" id="invoiceid" value="'.$invoice->id.'">';
1282 }
1283 if (getDolGlobalString('TAKEPOS_BAR_RESTAURANT')) {
1284  $sql = "SELECT floor, label FROM ".MAIN_DB_PREFIX."takepos_floor_tables where rowid=".((int) $place);
1285  $resql = $db->query($sql);
1286  $obj = $db->fetch_object($resql);
1287  if ($obj) {
1288  $label = $obj->label;
1289  $floor = $obj->floor;
1290  }
1291  if ($mobilepage == "invoice" || $mobilepage == "") {
1292  // If not on smartphone version or if it is the invoice page
1293  //print 'mobilepage='.$mobilepage;
1294  print '<span class="opacitymedium">'.$langs->trans('Place')."</span> <b>".(empty($label) ? '?' : $label)."</b><br>";
1295  print '<span class="opacitymedium">'.$langs->trans('Floor')."</span> <b>".(empty($floor) ? '?' : $floor)."</b>";
1296  } elseif (defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE')) {
1297  print $mysoc->name;
1298  } elseif ($mobilepage == "cats") {
1299  print $langs->trans('Category');
1300  } elseif ($mobilepage == "products") {
1301  print $langs->trans('Label');
1302  }
1303 } else {
1304  print $langs->trans("Products");
1305 }
1306 print '</td>';
1307 
1308 // complete header by hook
1309 $parameters=array();
1310 $reshook=$hookmanager->executeHooks('completeTakePosInvoiceHeader', $parameters, $invoice, $action); // Note that $action and $object may have been modified by some hooks
1311 if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1312 print $hookmanager->resPrint;
1313 
1314 if (empty($_SESSION["basiclayout"]) || $_SESSION["basiclayout"] != 1) {
1315  print '<td class="linecolqty right">'.$langs->trans('ReductionShort').'</td>';
1316  print '<td class="linecolqty right">'.$langs->trans('Qty').'</td>';
1317  if (getDolGlobalString('TAKEPOS_SHOW_HT')) {
1318  print '<td class="linecolht right nowraponall">';
1319  print '<span class="opacitymedium small">' . $langs->trans('TotalHTShort') . '</span><br>';
1320  // In phone version only show when it is invoice page
1321  if (empty($mobilepage) || $mobilepage == "invoice") {
1322  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>';
1323  if (isModEnabled('multicurrency') && $_SESSION["takeposcustomercurrency"] != "" && $conf->currency != $_SESSION["takeposcustomercurrency"]) {
1324  //Only show customer currency if multicurrency module is enabled, if currency selected and if this currency selected is not the same as main currency
1325  include_once DOL_DOCUMENT_ROOT . '/multicurrency/class/multicurrency.class.php';
1326  $multicurrency = new MultiCurrency($db);
1327  $multicurrency->fetch(0, $_SESSION["takeposcustomercurrency"]);
1328  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>';
1329  }
1330  print '</td>';
1331  }
1332  print '</td>';
1333  }
1334  print '<td class="linecolht right nowraponall">';
1335  print '<span class="opacitymedium small">'.$langs->trans('TotalTTCShort').'</span><br>';
1336  // In phone version only show when it is invoice page
1337  if (empty($mobilepage) || $mobilepage == "invoice") {
1338  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>';
1339  if (isModEnabled('multicurrency') && !empty($_SESSION["takeposcustomercurrency"]) && $conf->currency != $_SESSION["takeposcustomercurrency"]) {
1340  //Only show customer currency if multicurrency module is enabled, if currency selected and if this currency selected is not the same as main currency
1341  include_once DOL_DOCUMENT_ROOT.'/multicurrency/class/multicurrency.class.php';
1342  $multicurrency = new MultiCurrency($db);
1343  $multicurrency->fetch(0, $_SESSION["takeposcustomercurrency"]);
1344  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>';
1345  }
1346  print '</td>';
1347  }
1348  print '</td>';
1349 } elseif ($mobilepage == "invoice") {
1350  print '<td class="linecolqty right">'.$langs->trans('Qty').'</td>';
1351 }
1352 print "</tr>\n";
1353 
1354 
1355 if (!empty($_SESSION["basiclayout"]) && $_SESSION["basiclayout"] == 1) {
1356  if ($mobilepage == "cats") {
1357  require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
1358  $categorie = new Categorie($db);
1359  $categories = $categorie->get_full_arbo('product');
1360  $htmlforlines = '';
1361  foreach ($categories as $row) {
1362  if (defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE')) {
1363  $htmlforlines .= '<div class="leftcat';
1364  } else {
1365  $htmlforlines .= '<tr class="drag drop oddeven posinvoiceline';
1366  }
1367  $htmlforlines .= '" onclick="LoadProducts('.$row['id'].');">';
1368  if (defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE')) {
1369  $htmlforlines .= '<img class="imgwrapper" width="33%" src="'.DOL_URL_ROOT.'/takepos/public/auto_order.php?genimg=cat&query=cat&id='.$row['id'].'"><br>';
1370  } else {
1371  $htmlforlines .= '<td class="left">';
1372  }
1373  $htmlforlines .= $row['label'];
1374  if (defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE')) {
1375  $htmlforlines .= '</div>'."\n";
1376  } else {
1377  $htmlforlines .= '</td></tr>'."\n";
1378  }
1379  }
1380  $htmlforlines .= '</table>';
1381  $htmlforlines .= '</table>';
1382  print $htmlforlines;
1383  }
1384 
1385  if ($mobilepage == "products") {
1386  require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
1387  $object = new Categorie($db);
1388  $catid = GETPOST('catid', 'int');
1389  $result = $object->fetch($catid);
1390  $prods = $object->getObjectsInCateg("product");
1391  $htmlforlines = '';
1392  foreach ($prods as $row) {
1393  if (defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE')) {
1394  $htmlforlines .= '<div class="leftcat';
1395  } else {
1396  $htmlforlines .= '<tr class="drag drop oddeven posinvoiceline';
1397  }
1398  $htmlforlines .= '" onclick="AddProduct(\''.$place.'\', '.$row->id.')">';
1399  if (defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE')) {
1400  $htmlforlines .= '<img class="imgwrapper" width="33%" src="'.DOL_URL_ROOT.'/takepos/public/auto_order.php?genimg=pro&query=pro&id='.$row->id.'"><br>';
1401  $htmlforlines .= $row->label.''.price($row->price_ttc, 1, $langs, 1, -1, -1, $conf->currency);
1402  $htmlforlines .= '</div>'."\n";
1403  } else {
1404  $htmlforlines .= '<td class="left">';
1405  $htmlforlines .= $row->label;
1406  $htmlforlines .= '<div class="right">'.price($row->price_ttc, 1, $langs, 1, -1, -1, $conf->currency).'</div>';
1407  $htmlforlines .= '</tr>'."\n";
1408  }
1409  }
1410  $htmlforlines .= '</table>';
1411  print $htmlforlines;
1412  }
1413 
1414  if ($mobilepage == "places") {
1415  $sql = "SELECT rowid, entity, label, leftpos, toppos, floor FROM ".MAIN_DB_PREFIX."takepos_floor_tables";
1416  $resql = $db->query($sql);
1417  $rows = array();
1418  $htmlforlines = '';
1419  while ($row = $db->fetch_array($resql)) {
1420  $rows[] = $row;
1421  $htmlforlines .= '<tr class="drag drop oddeven posinvoiceline';
1422  $htmlforlines .= '" onclick="LoadPlace(\''.$row['label'].'\')">';
1423  $htmlforlines .= '<td class="left">';
1424  $htmlforlines .= $row['label'];
1425  $htmlforlines .= '</td>';
1426  $htmlforlines .= '</tr>'."\n";
1427  }
1428  $htmlforlines .= '</table>';
1429  print $htmlforlines;
1430  }
1431 }
1432 
1433 if ($placeid > 0) {
1434  //In Phone basic layout hide some content depends situation
1435  if (!empty($_SESSION["basiclayout"]) && $_SESSION["basiclayout"] == 1 && $mobilepage != "invoice" && $action != "order") {
1436  return;
1437  }
1438 
1439  if (is_array($invoice->lines) && count($invoice->lines)) {
1440  print '<!-- invoice.php show lines of invoices -->'."\n";
1441  $tmplines = array_reverse($invoice->lines);
1442  $htmlsupplements = array();
1443  foreach ($tmplines as $line) {
1444  if ($line->fk_parent_line != false) {
1445  $htmlsupplements[$line->fk_parent_line] .= '<tr class="drag drop oddeven posinvoiceline';
1446  if ($line->special_code == "4") {
1447  $htmlsupplements[$line->fk_parent_line] .= ' order';
1448  }
1449  $htmlsupplements[$line->fk_parent_line] .= '" id="'.$line->id.'"';
1450  if ($line->special_code == "4") {
1451  $htmlsupplements[$line->fk_parent_line] .= ' title="'.dol_escape_htmltag($langs->trans("AlreadyPrinted")).'"';
1452  }
1453  $htmlsupplements[$line->fk_parent_line] .= '>';
1454  $htmlsupplements[$line->fk_parent_line] .= '<td class="left">';
1455  $htmlsupplements[$line->fk_parent_line] .= img_picto('', 'rightarrow');
1456  if ($line->product_label) {
1457  $htmlsupplements[$line->fk_parent_line] .= $line->product_label;
1458  }
1459  if ($line->product_label && $line->desc) {
1460  $htmlsupplements[$line->fk_parent_line] .= '<br>';
1461  }
1462  if ($line->product_label != $line->desc) {
1463  $firstline = dolGetFirstLineOfText($line->desc);
1464  if ($firstline != $line->desc) {
1465  $htmlsupplements[$line->fk_parent_line] .= $form->textwithpicto(dolGetFirstLineOfText($line->desc), $line->desc);
1466  } else {
1467  $htmlsupplements[$line->fk_parent_line] .= $line->desc;
1468  }
1469  }
1470  $htmlsupplements[$line->fk_parent_line] .= '</td>';
1471 
1472  // complete line by hook
1473  $parameters=array('line' => $line);
1474  $reshook=$hookmanager->executeHooks('completeTakePosInvoiceParentLine', $parameters, $invoice, $action); // Note that $action and $object may have been modified by some hooks
1475  if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1476  $htmlsupplements[$line->fk_parent_line] .= $hookmanager->resPrint;
1477 
1478  if (empty($_SESSION["basiclayout"]) || $_SESSION["basiclayout"] != 1) {
1479  $htmlsupplements[$line->fk_parent_line] .= '<td class="right">'.vatrate($line->remise_percent, true).'</td>';
1480  $htmlsupplements[$line->fk_parent_line] .= '<td class="right">'.$line->qty.'</td>';
1481  $htmlsupplements[$line->fk_parent_line] .= '<td class="right">'.price($line->total_ttc).'</td>';
1482  }
1483  $htmlsupplements[$line->fk_parent_line] .= '</tr>'."\n";
1484  continue;
1485  }
1486  $htmlforlines = '';
1487 
1488  $htmlforlines .= '<tr class="drag drop oddeven posinvoiceline';
1489  if ($line->special_code == "4") {
1490  $htmlforlines .= ' order';
1491  }
1492  $htmlforlines .= '" id="'.$line->id.'"';
1493  if ($line->special_code == "4") {
1494  $htmlforlines .= ' title="'.dol_escape_htmltag($langs->trans("AlreadyPrinted")).'"';
1495  }
1496  $htmlforlines .= '>';
1497  $htmlforlines .= '<td class="left">';
1498  if (!empty($_SESSION["basiclayout"]) && $_SESSION["basiclayout"] == 1) {
1499  $htmlforlines .= '<span class="phoneqty">'.$line->qty."</span> x ";
1500  }
1501  if (isset($line->product_type)) {
1502  if (empty($line->product_type)) {
1503  $htmlforlines .= img_object('', 'product').' ';
1504  } else {
1505  $htmlforlines .= img_object('', 'service').' ';
1506  }
1507  }
1508  if (empty($conf->global->TAKEPOS_SHOW_N_FIRST_LINES)) {
1509  $tooltiptext = '';
1510  if ($line->product_ref) {
1511  $tooltiptext .= '<b>'.$langs->trans("Ref").'</b> : '.$line->product_ref.'<br>';
1512  $tooltiptext .= '<b>'.$langs->trans("Label").'</b> : '.$line->product_label.'<br>';
1513  if ($line->product_label != $line->desc) {
1514  if ($line->desc) {
1515  $tooltiptext .= '<br>';
1516  }
1517  $tooltiptext .= $line->desc;
1518  }
1519  }
1520  if ($conf->global->TAKEPOS_SHOW_PRODUCT_REFERENCE == 1) {
1521  $htmlforlines .= $form->textwithpicto($line->product_label ? '<b>' . $line->product_ref . '</b> - ' . $line->product_label : dolGetFirstLineOfText($line->desc, 1), $tooltiptext);
1522  } else {
1523  $htmlforlines .= $form->textwithpicto($line->product_label ? $line->product_label : ($line->product_ref ? $line->product_ref : dolGetFirstLineOfText($line->desc, 1)), $tooltiptext);
1524  }
1525  } else {
1526  if ($line->product_label) {
1527  $htmlforlines .= $line->product_label;
1528  }
1529  if ($line->product_label != $line->desc) {
1530  if ($line->product_label && $line->desc) {
1531  $htmlforlines .= '<br>';
1532  }
1533  $firstline = dolGetFirstLineOfText($line->desc, $conf->global->TAKEPOS_SHOW_N_FIRST_LINES);
1534  if ($firstline != $line->desc) {
1535  $htmlforlines .= $form->textwithpicto(dolGetFirstLineOfText($line->desc), $line->desc);
1536  } else {
1537  $htmlforlines .= $line->desc;
1538  }
1539  }
1540  }
1541  if (!empty($line->array_options['options_order_notes'])) {
1542  $htmlforlines .= "<br>(".$line->array_options['options_order_notes'].")";
1543  }
1544  if (!empty($_SESSION["basiclayout"]) && $_SESSION["basiclayout"] == 1) {
1545  $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>';
1546  }
1547  if (empty($_SESSION["basiclayout"]) || $_SESSION["basiclayout"] != 1) {
1548  $moreinfo = '';
1549  $moreinfo .= $langs->transcountry("TotalHT", $mysoc->country_code).': '.price($line->total_ht);
1550  if ($line->vat_src_code) {
1551  $moreinfo .= '<br>'.$langs->trans("VATCode").': '.$line->vat_src_code;
1552  }
1553  $moreinfo .= '<br>'.$langs->transcountry("TotalVAT", $mysoc->country_code).': '.price($line->total_tva);
1554  $moreinfo .= '<br>'.$langs->transcountry("TotalLT1", $mysoc->country_code).': '.price($line->total_localtax1);
1555  $moreinfo .= '<br>'.$langs->transcountry("TotalLT2", $mysoc->country_code).': '.price($line->total_localtax2);
1556  $moreinfo .= '<br>'.$langs->transcountry("TotalTTC", $mysoc->country_code).': '.price($line->total_ttc);
1557  //$moreinfo .= $langs->trans("TotalHT").': '.$line->total_ht;
1558  if ($line->date_start || $line->date_end) {
1559  $htmlforlines .= '<br><div class="clearboth nowraponall">'.get_date_range($line->date_start, $line->date_end).'</div>';
1560  }
1561  $htmlforlines .= '</td>';
1562 
1563  // complete line by hook
1564  $parameters=array('line' => $line);
1565  $reshook=$hookmanager->executeHooks('completeTakePosInvoiceLine', $parameters, $invoice, $action); // Note that $action and $object may have been modified by some hooks
1566  if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
1567  $htmlforlines .= $hookmanager->resPrint;
1568 
1569  $htmlforlines .= '<td class="right">'.vatrate($line->remise_percent, true).'</td>';
1570  $htmlforlines .= '<td class="right">';
1571  if (isModEnabled('stock') && !empty($user->rights->stock->mouvement->lire)) {
1572  $constantforkey = 'CASHDESK_ID_WAREHOUSE'.$_SESSION["takeposterminal"];
1573  if (!empty($conf->global->$constantforkey) && $line->fk_product > 0 && empty($conf->global->TAKEPOS_HIDE_STOCK_ON_LINE)) {
1574  $sql = "SELECT e.rowid, e.ref, e.lieu, e.fk_parent, e.statut, ps.reel, ps.rowid as product_stock_id, p.pmp";
1575  $sql .= " FROM ".MAIN_DB_PREFIX."entrepot as e,";
1576  $sql .= " ".MAIN_DB_PREFIX."product_stock as ps";
1577  $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON p.rowid = ps.fk_product";
1578  $sql .= " WHERE ps.reel != 0";
1579  $sql .= " AND ps.fk_entrepot = ".((int) $conf->global->$constantforkey);
1580  $sql .= " AND e.entity IN (".getEntity('stock').")";
1581  $sql .= " AND ps.fk_product = ".((int) $line->fk_product);
1582  $resql = $db->query($sql);
1583  if ($resql) {
1584  $obj = $db->fetch_object($resql);
1585  $stock_real = price2num($obj->reel, 'MS');
1586  $htmlforlines .= $line->qty;
1587  if ($line->qty && $line->qty > $stock_real) {
1588  $htmlforlines .= '<span style="color: var(--amountremaintopaycolor)">';
1589  }
1590  $htmlforlines .= ' <span class="posstocktoolow">('.$langs->trans("Stock").' '.$stock_real.')</span>';
1591  if ($line->qty && $line->qty > $stock_real) {
1592  $htmlforlines .= "</span>";
1593  }
1594  } else {
1595  dol_print_error($db);
1596  }
1597  } else {
1598  $htmlforlines .= $line->qty;
1599  }
1600  } else {
1601  $htmlforlines .= $line->qty;
1602  }
1603 
1604  $htmlforlines .= '</td>';
1605  if (getDolGlobalString('TAKEPOS_SHOW_HT')) {
1606  $htmlforlines .= '<td class="right classfortooltip" title="'.$moreinfo.'">';
1607  $htmlforlines .= price($line->total_ht, 1, '', 1, -1, -1, $conf->currency);
1608  if (isModEnabled('multicurrency') && !empty($_SESSION["takeposcustomercurrency"]) && $conf->currency != $_SESSION["takeposcustomercurrency"]) {
1609  //Only show customer currency if multicurrency module is enabled, if currency selected and if this currency selected is not the same as main currency
1610  include_once DOL_DOCUMENT_ROOT.'/multicurrency/class/multicurrency.class.php';
1611  $multicurrency = new MultiCurrency($db);
1612  $multicurrency->fetch(0, $_SESSION["takeposcustomercurrency"]);
1613  $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>';
1614  }
1615  $htmlforlines .= '</td>';
1616  }
1617  $htmlforlines .= '<td class="right classfortooltip" title="'.$moreinfo.'">';
1618  $htmlforlines .= price($line->total_ttc, 1, '', 1, -1, -1, $conf->currency);
1619  if (isModEnabled('multicurrency') && !empty($_SESSION["takeposcustomercurrency"]) && $conf->currency != $_SESSION["takeposcustomercurrency"]) {
1620  //Only show customer currency if multicurrency module is enabled, if currency selected and if this currency selected is not the same as main currency
1621  include_once DOL_DOCUMENT_ROOT.'/multicurrency/class/multicurrency.class.php';
1622  $multicurrency = new MultiCurrency($db);
1623  $multicurrency->fetch(0, $_SESSION["takeposcustomercurrency"]);
1624  $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>';
1625  }
1626  $htmlforlines .= '</td>';
1627  }
1628  $htmlforlines .= '</tr>'."\n";
1629  $htmlforlines .= empty($htmlsupplements[$line->id]) ? '' : $htmlsupplements[$line->id];
1630 
1631  print $htmlforlines;
1632  }
1633  } else {
1634  print '<tr class="drag drop oddeven"><td class="left"><span class="opacitymedium">'.$langs->trans("Empty").'</span></td><td></td><td></td><td></td>';
1635  if (!empty($conf->global->TAKEPOS_SHOW_HT)) {
1636  print '<td></td>';
1637  }
1638  print '</tr>';
1639  }
1640 } else { // No invoice generated yet
1641  print '<tr class="drag drop oddeven"><td class="left"><span class="opacitymedium">'.$langs->trans("Empty").'</span></td><td></td><td></td><td></td>';
1642 
1643  if (!empty($conf->global->TAKEPOS_SHOW_HT)) {
1644  print '<td></td>';
1645  }
1646  print '</tr>';
1647 }
1648 
1649 print '</table>';
1650 
1651 if (($action == "valid" || $action == "history") && $invoice->type != Facture::TYPE_CREDIT_NOTE) {
1652  print '<button id="buttonprint" type="button" onclick="ModalBox(\'ModalCreditNote\')">'.$langs->trans('CreateCreditNote').'</button>';
1653 }
1654 
1655 
1656 if ($action == "search") {
1657  print '<center>
1658  <input type="text" id="search" class="input-search-takepos" name="search" onkeyup="Search2(\'\', null);" style="width: 80%; font-size: 150%;" placeholder="'.dol_escape_htmltag($langs->trans('Search')).'">
1659  </center>';
1660 }
1661 
1662 print '</div>';
Facture\STATUS_DRAFT
const STATUS_DRAFT
Draft status.
Definition: facture.class.php:412
Societe
Class to manage third parties objects (customers, suppliers, prospects...)
Definition: societe.class.php:48
dol_htmloutput_errors
dol_htmloutput_errors($mesgstring='', $mesgarray=array(), $keepembedded=0)
Print formated error messages to output (Used to show messages on html output).
Definition: functions.lib.php:8352
dolReceiptPrinter
Class to manage Receipt Printers.
Definition: dolreceiptprinter.class.php:119
GETPOST
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
Definition: functions.lib.php:484
dol_print_error
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
Definition: functions.lib.php:4830
fail
if(empty($user->rights->takepos->run) &&!defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE')) if((getDolGlobalString('TAKEPOS_PHONE_BASIC_LAYOUT')==1 && $conf->browser->layout=='phone')||defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE')) fail($message)
Abort invoice creationg with a given error message.
Definition: invoice.php:111
top_htmlhead
top_htmlhead($head, $title='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $disableforlogin=0, $disablenofollow=0, $disablenoindex=0)
Ouput html header of a page.
Definition: main.inc.php:1482
$form
if($cancel &&! $id) if($action=='add' &&! $cancel) if($action=='delete') if($id) $form
Actions.
Definition: card.php:142
rowid
print *****$script_file(".$version.") pid c cd cd cd description as p label as s rowid
Definition: email_expire_services_to_representatives.php:79
Categorie
Class to manage categories.
Definition: categorie.class.php:47
Facture
Class to manage invoices.
Definition: facture.class.php:60
price2num
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
Definition: functions.lib.php:5647
dol_print_date
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
Definition: functions.lib.php:2500
MultiCurrency
Class Currency.
Definition: multicurrency.class.php:39
getEntity
getEntity($element, $shared=1, $currentobject=null)
Get list of entity id to use.
Definition: functions.lib.php:148
get_localtax
get_localtax($vatrate, $local, $thirdparty_buyer="", $thirdparty_seller="", $vatnpr=0)
Return localtax rate for a particular vat, when selling a product with vat $vatrate,...
Definition: functions.lib.php:5823
dol_syslog
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
Definition: functions.lib.php:1589
Adherent
Class to manage members of a foundation.
Definition: adherent.class.php:46
getDolGlobalString
if(!function_exists('utf8_encode')) if(!function_exists('utf8_decode')) getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
Definition: functions.lib.php:80
Adherent\STATUS_EXCLUDED
const STATUS_EXCLUDED
Excluded.
Definition: adherent.class.php:361
get_default_tva
get_default_tva(Societe $thirdparty_seller, Societe $thirdparty_buyer, $idprod=0, $idprodfournprice=0)
Function that return vat rate of a product line (according to seller, buyer and product vat rate) VAT...
Definition: functions.lib.php:6290
isModEnabled
isModEnabled($module)
Is Dolibarr module enabled.
Definition: functions.lib.php:105
Facture\TYPE_CREDIT_NOTE
const TYPE_CREDIT_NOTE
Credit note invoice.
Definition: facture.class.php:392
Paiement
Class to manage payments of customer invoices.
Definition: paiement.class.php:41
GETPOSTISSET
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
Definition: functions.lib.php:386
Entrepot\STATUS_CLOSED
const STATUS_CLOSED
Warehouse closed, inactive.
Definition: entrepot.class.php:151
Product
Class to manage products or services.
Definition: product.class.php:46
Form
Class to manage generation of HTML components Only common components must be here.
Definition: html.form.class.php:52
Entrepot
Class to manage warehouses.
Definition: entrepot.class.php:35
dol_now
dol_now($mode='auto')
Return date for now.
Definition: functions.lib.php:2831
$resql
if(isModEnabled('facture') &&!empty($user->rights->facture->lire)) if((isModEnabled('fournisseur') &&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->rights->fournisseur->facture->lire)||(isModEnabled('supplier_invoice') && $user->rights->supplier_invoice->lire)) if(isModEnabled('don') &&!empty($user->rights->don->lire)) if(isModEnabled('tax') &&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture') &&isModEnabled('commande') && $user->rights->commande->lire &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $resql
Social contributions to pay.
Definition: index.php:742
price
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.
Definition: functions.lib.php:5527
setEventMessages
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='')
Set event messages in dol_events session object.
Definition: functions.lib.php:8122
accessforbidden
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program Calling this function terminate execution ...
Definition: security.lib.php:933
getDolGlobalInt
getDolGlobalInt($key, $default=0)
Return dolibarr global constant int value.
Definition: functions.lib.php:93
Facture\TYPE_SITUATION
const TYPE_SITUATION
Situation invoice.
Definition: facture.class.php:407
type
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition: repair.php:119
Productbatch\BATCH_RULE_SELLBY_EATBY_DATES_FIRST
const BATCH_RULE_SELLBY_EATBY_DATES_FIRST
Batches rules.
Definition: productbatch.class.php:36