diff --git a/htdocs/takepos/invoice.php b/htdocs/takepos/invoice.php index de780d92a64..3a55d82b8ad 100644 --- a/htdocs/takepos/invoice.php +++ b/htdocs/takepos/invoice.php @@ -49,6 +49,8 @@ if (!defined('INCLUDE_PHONEPAGE_FROM_PUBLIC_PAGE')) { require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/paiement/class/paiement.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.form.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php'; +$hookmanager->initHooks(array('takeposinvoice')); global $mysoc; @@ -168,11 +170,6 @@ if ($invoice->socid > 0) { $soc->fetch(getDolGlobalString("$constforcompanyid")); } - -/* - * Actions - */ - // Change the currency of invoice if it was modified if (!empty($conf->multicurrency->enabled) && !empty($_SESSION["takeposcustomercurrency"])) { if ($invoice->multicurrency_code != $_SESSION["takeposcustomercurrency"]) { @@ -180,730 +177,738 @@ if (!empty($conf->multicurrency->enabled) && !empty($_SESSION["takeposcustomercu } } +/* + * Actions + */ -// Action to record a payment on a TakePOS invoice -if ($action == 'valid' && $user->rights->facture->creer) { - $bankaccount = 0; - $error = 0; +$parameters=array(); +$reshook=$hookmanager->executeHooks('doActions', $parameters, $invoice, $action); // Note that $action and $object may have been modified by some hooks +if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); - if (!empty($conf->global->TAKEPOS_CAN_FORCE_BANK_ACCOUNT_DURING_PAYMENT)) { - $bankaccount = GETPOST('accountid', 'int'); - } else { - if ($pay == 'LIQ') { - $bankaccount = $conf->global->{'CASHDESK_ID_BANKACCOUNT_CASH'.$_SESSION["takeposterminal"]}; // For backward compatibility - } elseif ($pay == "CHQ") { - $bankaccount = $conf->global->{'CASHDESK_ID_BANKACCOUNT_CHEQUE'.$_SESSION["takeposterminal"]}; // For backward compatibility +if (empty($reshook)) { + // Action to record a payment on a TakePOS invoice + if ($action == 'valid' && $user->rights->facture->creer) { + $bankaccount = 0; + $error = 0; + + if (!empty($conf->global->TAKEPOS_CAN_FORCE_BANK_ACCOUNT_DURING_PAYMENT)) { + $bankaccount = GETPOST('accountid', 'int'); } else { - $accountname = "CASHDESK_ID_BANKACCOUNT_".$pay.$_SESSION["takeposterminal"]; - $bankaccount = $conf->global->$accountname; + if ($pay == 'LIQ') { + $bankaccount = $conf->global->{'CASHDESK_ID_BANKACCOUNT_CASH'.$_SESSION["takeposterminal"]}; // For backward compatibility + } elseif ($pay == "CHQ") { + $bankaccount = $conf->global->{'CASHDESK_ID_BANKACCOUNT_CHEQUE'.$_SESSION["takeposterminal"]}; // For backward compatibility + } else { + $accountname = "CASHDESK_ID_BANKACCOUNT_".$pay.$_SESSION["takeposterminal"]; + $bankaccount = $conf->global->$accountname; + } } - } - if ($bankaccount <= 0 && $pay != "delayed") { - $errormsg = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("BankAccount")); - $error++; - } + if ($bankaccount <= 0 && $pay != "delayed") { + $errormsg = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("BankAccount")); + $error++; + } - $now = dol_now(); - $res = 0; + $now = dol_now(); + $res = 0; - $invoice = new Facture($db); - $invoice->fetch($placeid); + $invoice = new Facture($db); + $invoice->fetch($placeid); - if ($invoice->total_ttc < 0) { - $invoice->type = $invoice::TYPE_CREDIT_NOTE; + if ($invoice->total_ttc < 0) { + $invoice->type = $invoice::TYPE_CREDIT_NOTE; - $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."facture WHERE"; - $sql .= " fk_soc = ".((int) $invoice->socid); - $sql .= " AND type <> ".Facture::TYPE_CREDIT_NOTE; - $sql .= " AND fk_statut >= ".$invoice::STATUS_VALIDATED; - $sql .= " ORDER BY rowid DESC"; + $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."facture WHERE"; + $sql .= " fk_soc = ".((int) $invoice->socid); + $sql .= " AND type <> ".Facture::TYPE_CREDIT_NOTE; + $sql .= " AND fk_statut >= ".$invoice::STATUS_VALIDATED; + $sql .= " ORDER BY rowid DESC"; - $resql = $db->query($sql); - if ($resql) { - $obj = $db->fetch_object($resql); - $fk_source = $obj->rowid; - if ($fk_source == null) { + $resql = $db->query($sql); + if ($resql) { + $obj = $db->fetch_object($resql); + $fk_source = $obj->rowid; + if ($fk_source == null) { + fail($langs->transnoentitiesnoconv("NoPreviousBillForCustomer")); + } + } else { fail($langs->transnoentitiesnoconv("NoPreviousBillForCustomer")); } - } else { - fail($langs->transnoentitiesnoconv("NoPreviousBillForCustomer")); - } - $invoice->fk_facture_source = $fk_source; - $invoice->update($user); - } - - //$sav_FACTURE_ADDON = ''; - //if (!empty($conf->global->TAKEPOS_ADDON)) { - // $sav_FACTURE_ADDON = $conf->global->FACTURE_ADDON; - // if ($conf->global->TAKEPOS_ADDON == "terminal") $conf->global->FACTURE_ADDON = $conf->global->{'TAKEPOS_ADDON'.$_SESSION["takeposterminal"]}; - // else $conf->global->FACTURE_ADDON = $conf->global->TAKEPOS_ADDON; - //} - - $constantforkey = 'CASHDESK_NO_DECREASE_STOCK'.$_SESSION["takeposterminal"]; - if ($error) { - dol_htmloutput_errors($errormsg, null, 1); - } elseif ($invoice->statut != Facture::STATUS_DRAFT) { - //If invoice is validated but it is not fully paid is not error and make the payment - if ($invoice->getRemainToPay() > 0) { - $res = 1; - } else { - dol_syslog("Sale already validated"); - dol_htmloutput_errors($langs->trans("InvoiceIsAlreadyValidated", "TakePos"), null, 1); - } - } elseif (count($invoice->lines) == 0) { - $error++; - dol_syslog('Sale without lines'); - dol_htmloutput_errors($langs->trans("NoLinesToBill", "TakePos"), null, 1); - } elseif (!empty($conf->stock->enabled) && $conf->global->$constantforkey != "1") { - $savconst = $conf->global->STOCK_CALCULATE_ON_BILL; - $conf->global->STOCK_CALCULATE_ON_BILL = 1; - - $constantforkey = 'CASHDESK_ID_WAREHOUSE'.$_SESSION["takeposterminal"]; - dol_syslog("Validate invoice with stock change into warehouse defined into constant ".$constantforkey." = ".$conf->global->$constantforkey); - $batch_rule = 0; - if (!empty($conf->productbatch->enabled) && !empty($conf->global->CASHDESK_FORCE_DECREASE_STOCK)) { - require_once DOL_DOCUMENT_ROOT.'/product/class/productbatch.class.php'; - $batch_rule = Productbatch::BATCH_RULE_SELLBY_EATBY_DATES_FIRST; - } - $res = $invoice->validate($user, '', $conf->global->$constantforkey, 0, $batch_rule); - - $conf->global->STOCK_CALCULATE_ON_BILL = $savconst; - } else { - $res = $invoice->validate($user); - if ($res < 0) { - $error++; - dol_htmloutput_errors($invoice->error, $invoice->errors, 1); - } - } - - // Restore save values - //if (!empty($sav_FACTURE_ADDON)) - //{ - // $conf->global->FACTURE_ADDON = $sav_FACTURE_ADDON; - //} - - // Add the payment - if (!$error && $res >= 0) { - $remaintopay = $invoice->getRemainToPay(); - if ($remaintopay > 0) { - $payment = new Paiement($db); - $payment->datepaye = $now; - $payment->fk_account = $bankaccount; - $payment->amounts[$invoice->id] = $amountofpayment; - if ($pay == 'LIQ') { - $payment->pos_change = price2num(GETPOST('excess', 'alpha')); - } - - // If user has not used change control, add total invoice payment - // Or if user has used change control and the amount of payment is higher than remain to pay, add the remain to pay - if ($amountofpayment == 0 || $amountofpayment > $remaintopay) { - $payment->amounts[$invoice->id] = $remaintopay; - } - - $payment->paiementid = $paiementid; - $payment->num_payment = $invoice->ref; - - if ($pay != "delayed") { - $payment->create($user); - $payment->addPaymentToBank($user, 'payment', '(CustomerInvoicePayment)', $bankaccount, '', ''); - $remaintopay = $invoice->getRemainToPay(); // Recalculate remain to pay after the payment is recorded - } + $invoice->fk_facture_source = $fk_source; + $invoice->update($user); } - if ($remaintopay == 0) { - dol_syslog("Invoice is paid, so we set it to status Paid"); - $result = $invoice->setPaid($user); - if ($result > 0) { - $invoice->paye = 1; - } - // set payment method - $invoice->setPaymentMethods($paiementid); - } else { - dol_syslog("Invoice is not paid, remain to pay = ".$remaintopay); - } - } else { - dol_htmloutput_errors($invoice->error, $invoice->errors, 1); - } -} + //$sav_FACTURE_ADDON = ''; + //if (!empty($conf->global->TAKEPOS_ADDON)) { + // $sav_FACTURE_ADDON = $conf->global->FACTURE_ADDON; + // if ($conf->global->TAKEPOS_ADDON == "terminal") $conf->global->FACTURE_ADDON = $conf->global->{'TAKEPOS_ADDON'.$_SESSION["takeposterminal"]}; + // else $conf->global->FACTURE_ADDON = $conf->global->TAKEPOS_ADDON; + //} -if ($action == 'creditnote' && $user->rights->facture->creer) { - $creditnote = new Facture($db); - $creditnote->socid = $invoice->socid; - $creditnote->date = dol_now(); - $creditnote->module_source = 'takepos'; - $creditnote->pos_source = isset($_SESSION["takeposterminal"]) ? $_SESSION["takeposterminal"] : '' ; - $creditnote->type = Facture::TYPE_CREDIT_NOTE; - $creditnote->fk_facture_source = $placeid; - $creditnote->remise_absolue = $invoice->remise_absolue; - $creditnote->remise_percent = $invoice->remise_percent; - $creditnote->create($user); - - foreach ($invoice->lines as $line) { - // Extrafields - if (method_exists($line, 'fetch_optionals')) { - // load extrafields - $line->fetch_optionals(); - } - // Reset fk_parent_line for no child products and special product - if (($line->product_type != 9 && empty($line->fk_parent_line)) || $line->product_type == 9) { - $fk_parent_line = 0; - } - if ($invoice->type == Facture::TYPE_SITUATION) { - $source_fk_prev_id = $line->fk_prev_id; // temporary storing situation invoice fk_prev_id - $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 - if (!empty($invoice->tab_previous_situation_invoice)) { - // search the last standard invoice in cycle and the possible credit note between this last and invoice - // TODO Move this out of loop of $invoice->lines - $tab_jumped_credit_notes = array(); - $lineIndex = count($invoice->tab_previous_situation_invoice) - 1; - $searchPreviousInvoice = true; - while ($searchPreviousInvoice) { - if ($invoice->tab_previous_situation_invoice[$lineIndex]->type == Facture::TYPE_SITUATION || $lineIndex < 1) { - $searchPreviousInvoice = false; // find, exit; - break; - } else { - if ($invoice->tab_previous_situation_invoice[$lineIndex]->type == Facture::TYPE_CREDIT_NOTE) { - $tab_jumped_credit_notes[$lineIndex] = $invoice->tab_previous_situation_invoice[$lineIndex]->id; - } - $lineIndex--; // go to previous invoice in cycle - } - } - - $maxPrevSituationPercent = 0; - foreach ($invoice->tab_previous_situation_invoice[$lineIndex]->lines as $prevLine) { - if ($prevLine->id == $source_fk_prev_id) { - $maxPrevSituationPercent = max($maxPrevSituationPercent, $prevLine->situation_percent); - - //$line->subprice = $line->subprice - $prevLine->subprice; - $line->total_ht = $line->total_ht - $prevLine->total_ht; - $line->total_tva = $line->total_tva - $prevLine->total_tva; - $line->total_ttc = $line->total_ttc - $prevLine->total_ttc; - $line->total_localtax1 = $line->total_localtax1 - $prevLine->total_localtax1; - $line->total_localtax2 = $line->total_localtax2 - $prevLine->total_localtax2; - - $line->multicurrency_subprice = $line->multicurrency_subprice - $prevLine->multicurrency_subprice; - $line->multicurrency_total_ht = $line->multicurrency_total_ht - $prevLine->multicurrency_total_ht; - $line->multicurrency_total_tva = $line->multicurrency_total_tva - $prevLine->multicurrency_total_tva; - $line->multicurrency_total_ttc = $line->multicurrency_total_ttc - $prevLine->multicurrency_total_ttc; - } - } - - // prorata - $line->situation_percent = $maxPrevSituationPercent - $line->situation_percent; - - //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.'
'; - - // If there is some credit note between last situation invoice and invoice used for credit note generation (note: credit notes are stored as delta) - $maxPrevSituationPercent = 0; - foreach ($tab_jumped_credit_notes as $index => $creditnoteid) { - foreach ($invoice->tab_previous_situation_invoice[$index]->lines as $prevLine) { - if ($prevLine->fk_prev_id == $source_fk_prev_id) { - $maxPrevSituationPercent = $prevLine->situation_percent; - - $line->total_ht -= $prevLine->total_ht; - $line->total_tva -= $prevLine->total_tva; - $line->total_ttc -= $prevLine->total_ttc; - $line->total_localtax1 -= $prevLine->total_localtax1; - $line->total_localtax2 -= $prevLine->total_localtax2; - - $line->multicurrency_subprice -= $prevLine->multicurrency_subprice; - $line->multicurrency_total_ht -= $prevLine->multicurrency_total_ht; - $line->multicurrency_total_tva -= $prevLine->multicurrency_total_tva; - $line->multicurrency_total_ttc -= $prevLine->multicurrency_total_ttc; - } - } - } - - // prorata - $line->situation_percent += $maxPrevSituationPercent; - - //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.'
'; - } - } - - $line->fk_facture = $creditnote->id; - $line->fk_parent_line = $fk_parent_line; - - $line->subprice = -$line->subprice; // invert price for object - $line->pa_ht = $line->pa_ht; // we choosed to have buy/cost price always positive, so no revert of sign here - $line->total_ht = -$line->total_ht; - $line->total_tva = -$line->total_tva; - $line->total_ttc = -$line->total_ttc; - $line->total_localtax1 = -$line->total_localtax1; - $line->total_localtax2 = -$line->total_localtax2; - - $line->multicurrency_subprice = -$line->multicurrency_subprice; - $line->multicurrency_total_ht = -$line->multicurrency_total_ht; - $line->multicurrency_total_tva = -$line->multicurrency_total_tva; - $line->multicurrency_total_ttc = -$line->multicurrency_total_ttc; - - $result = $line->insert(0, 1); // When creating credit note with same lines than source, we must ignore error if discount alreayd linked - - $creditnote->lines[] = $line; // insert new line in current object - - // Defined the new fk_parent_line - if ($result > 0 && $line->product_type == 9) { - $fk_parent_line = $result; - } - } - $creditnote->update_price(1); - - $constantforkey = 'CASHDESK_NO_DECREASE_STOCK'.$_SESSION["takeposterminal"]; - if (!empty($conf->stock->enabled) && $conf->global->$constantforkey != "1") { - $savconst = $conf->global->STOCK_CALCULATE_ON_BILL; - $conf->global->STOCK_CALCULATE_ON_BILL = 1; - $constantforkey = 'CASHDESK_ID_WAREHOUSE'.$_SESSION["takeposterminal"]; - dol_syslog("Validate invoice with stock change into warehouse defined into constant ".$constantforkey." = ".$conf->global->$constantforkey); - $batch_rule = 0; - if (!empty($conf->productbatch->enabled) && !empty($conf->global->CASHDESK_FORCE_DECREASE_STOCK)) { - require_once DOL_DOCUMENT_ROOT.'/product/class/productbatch.class.php'; - $batch_rule = Productbatch::BATCH_RULE_SELLBY_EATBY_DATES_FIRST; - } - $res = $creditnote->validate($user, '', $conf->global->$constantforkey, 0, $batch_rule); - $conf->global->STOCK_CALCULATE_ON_BILL = $savconst; - } else { - $res = $creditnote->validate($user); - } -} - -if ($action == 'history' || $action == 'creditnote') { - if ($action == 'creditnote') { - $placeid = $creditnote->id; - } else { - $placeid = (int) GETPOST('placeid', 'int'); - } - $invoice = new Facture($db); - $invoice->fetch($placeid); -} - -if (($action == "addline" || $action == "freezone") && $placeid == 0) { - $invoice->socid = getDolGlobalString("$constforcompanyid"); - $invoice->date = dol_now(); - $invoice->module_source = 'takepos'; - $invoice->pos_source = isset($_SESSION["takeposterminal"]) ? $_SESSION["takeposterminal"] : '' ; - $invoice->entity = !empty($_SESSION["takeposinvoiceentity"]) ? $_SESSION["takeposinvoiceentity"] : $conf->entity; - - if ($invoice->socid <= 0) { - $langs->load('errors'); - dol_htmloutput_errors($langs->trans("ErrorModuleSetupNotComplete", "TakePos"), null, 1); - } else { - $placeid = $invoice->create($user); - if ($placeid < 0) { - dol_htmloutput_errors($invoice->error, $invoice->errors, 1); - } - $sql = "UPDATE ".MAIN_DB_PREFIX."facture set ref='(PROV-POS".$_SESSION["takeposterminal"]."-".$place.")' where rowid = ".((int) $placeid); - $db->query($sql); - } -} - -if ($action == "addline") { - $prod = new Product($db); - $prod->fetch($idproduct); - - $customer = new Societe($db); - $customer->fetch($invoice->socid); - - $datapriceofproduct = $prod->getSellPrice($mysoc, $customer, 0); - - $qty = GETPOSTISSET('qty') ? GETPOST('qty', 'int') : 1; - $price = $datapriceofproduct['pu_ht']; - $price_ttc = $datapriceofproduct['pu_ttc']; - //$price_min = $datapriceofproduct['price_min']; - $price_base_type = $datapriceofproduct['price_base_type']; - $tva_tx = $datapriceofproduct['tva_tx']; - $tva_npr = $datapriceofproduct['tva_npr']; - - // Local Taxes - $localtax1_tx = get_localtax($tva_tx, 1, $customer, $mysoc, $tva_npr); - $localtax2_tx = get_localtax($tva_tx, 2, $customer, $mysoc, $tva_npr); - - if (!empty($conf->global->TAKEPOS_SUPPLEMENTS)) { - require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; - $cat = new Categorie($db); - $categories = $cat->containing($idproduct, 'product'); - $found = (array_search($conf->global->TAKEPOS_SUPPLEMENTS_CATEGORY, array_column($categories, 'id'))); - if ($found !== false) { // If this product is a supplement - $sql = "SELECT fk_parent_line FROM ".MAIN_DB_PREFIX."facturedet where rowid=$selectedline"; - $resql = $db->query($sql); - $row = $db->fetch_array($resql); - if ($row[0] == null) { - $parent_line = $selectedline; + $constantforkey = 'CASHDESK_NO_DECREASE_STOCK'.$_SESSION["takeposterminal"]; + if ($error) { + dol_htmloutput_errors($errormsg, null, 1); + } elseif ($invoice->statut != Facture::STATUS_DRAFT) { + //If invoice is validated but it is not fully paid is not error and make the payment + if ($invoice->getRemainToPay() > 0) { + $res = 1; } else { - $parent_line = $row[0]; //If the parent line is already a supplement, add the supplement to the main product + dol_syslog("Sale already validated"); + dol_htmloutput_errors($langs->trans("InvoiceIsAlreadyValidated", "TakePos"), null, 1); + } + } elseif (count($invoice->lines) == 0) { + $error++; + dol_syslog('Sale without lines'); + dol_htmloutput_errors($langs->trans("NoLinesToBill", "TakePos"), null, 1); + } elseif (!empty($conf->stock->enabled) && $conf->global->$constantforkey != "1") { + $savconst = $conf->global->STOCK_CALCULATE_ON_BILL; + $conf->global->STOCK_CALCULATE_ON_BILL = 1; + + $constantforkey = 'CASHDESK_ID_WAREHOUSE'.$_SESSION["takeposterminal"]; + dol_syslog("Validate invoice with stock change into warehouse defined into constant ".$constantforkey." = ".$conf->global->$constantforkey); + $batch_rule = 0; + if (!empty($conf->productbatch->enabled) && !empty($conf->global->CASHDESK_FORCE_DECREASE_STOCK)) { + require_once DOL_DOCUMENT_ROOT.'/product/class/productbatch.class.php'; + $batch_rule = Productbatch::BATCH_RULE_SELLBY_EATBY_DATES_FIRST; + } + $res = $invoice->validate($user, '', $conf->global->$constantforkey, 0, $batch_rule); + + $conf->global->STOCK_CALCULATE_ON_BILL = $savconst; + } else { + $res = $invoice->validate($user); + if ($res < 0) { + $error++; + dol_htmloutput_errors($invoice->error, $invoice->errors, 1); } } - } - $idoflineadded = 0; - // Group if enabled. Skip group if line already sent to the printer - if (!empty($conf->global->TAKEPOS_GROUP_SAME_PRODUCT) && $line->special_code != "4") { - foreach ($invoice->lines as $line) { - if ($line->product_ref == $prod->ref) { - if ($line->special_code==4) continue; // If this line is sended to printer create new line - $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); - if ($result < 0) { - dol_htmloutput_errors($invoice->error, $invoice->errors, 1); - } else { - $idoflineadded = $line->id; + // Restore save values + //if (!empty($sav_FACTURE_ADDON)) + //{ + // $conf->global->FACTURE_ADDON = $sav_FACTURE_ADDON; + //} + + // Add the payment + if (!$error && $res >= 0) { + $remaintopay = $invoice->getRemainToPay(); + if ($remaintopay > 0) { + $payment = new Paiement($db); + $payment->datepaye = $now; + $payment->fk_account = $bankaccount; + $payment->amounts[$invoice->id] = $amountofpayment; + if ($pay == 'LIQ') { + $payment->pos_change = price2num(GETPOST('excess', 'alpha')); } - break; + + // If user has not used change control, add total invoice payment + // Or if user has used change control and the amount of payment is higher than remain to pay, add the remain to pay + if ($amountofpayment == 0 || $amountofpayment > $remaintopay) { + $payment->amounts[$invoice->id] = $remaintopay; + } + + $payment->paiementid = $paiementid; + $payment->num_payment = $invoice->ref; + + if ($pay != "delayed") { + $payment->create($user); + $payment->addPaymentToBank($user, 'payment', '(CustomerInvoicePayment)', $bankaccount, '', ''); + $remaintopay = $invoice->getRemainToPay(); // Recalculate remain to pay after the payment is recorded + } + } + + if ($remaintopay == 0) { + dol_syslog("Invoice is paid, so we set it to status Paid"); + $result = $invoice->setPaid($user); + if ($result > 0) { + $invoice->paye = 1; + } + // set payment method + $invoice->setPaymentMethods($paiementid); + } else { + dol_syslog("Invoice is not paid, remain to pay = ".$remaintopay); + } + } else { + dol_htmloutput_errors($invoice->error, $invoice->errors, 1); + } + } + + if ($action == 'creditnote' && $user->rights->facture->creer) { + $creditnote = new Facture($db); + $creditnote->socid = $invoice->socid; + $creditnote->date = dol_now(); + $creditnote->module_source = 'takepos'; + $creditnote->pos_source = isset($_SESSION["takeposterminal"]) ? $_SESSION["takeposterminal"] : '' ; + $creditnote->type = Facture::TYPE_CREDIT_NOTE; + $creditnote->fk_facture_source = $placeid; + $creditnote->remise_absolue = $invoice->remise_absolue; + $creditnote->remise_percent = $invoice->remise_percent; + $creditnote->create($user); + + foreach ($invoice->lines as $line) { + // Extrafields + if (method_exists($line, 'fetch_optionals')) { + // load extrafields + $line->fetch_optionals(); + } + // Reset fk_parent_line for no child products and special product + if (($line->product_type != 9 && empty($line->fk_parent_line)) || $line->product_type == 9) { + $fk_parent_line = 0; + } + if ($invoice->type == Facture::TYPE_SITUATION) { + $source_fk_prev_id = $line->fk_prev_id; // temporary storing situation invoice fk_prev_id + $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 + if (!empty($invoice->tab_previous_situation_invoice)) { + // search the last standard invoice in cycle and the possible credit note between this last and invoice + // TODO Move this out of loop of $invoice->lines + $tab_jumped_credit_notes = array(); + $lineIndex = count($invoice->tab_previous_situation_invoice) - 1; + $searchPreviousInvoice = true; + while ($searchPreviousInvoice) { + if ($invoice->tab_previous_situation_invoice[$lineIndex]->type == Facture::TYPE_SITUATION || $lineIndex < 1) { + $searchPreviousInvoice = false; // find, exit; + break; + } else { + if ($invoice->tab_previous_situation_invoice[$lineIndex]->type == Facture::TYPE_CREDIT_NOTE) { + $tab_jumped_credit_notes[$lineIndex] = $invoice->tab_previous_situation_invoice[$lineIndex]->id; + } + $lineIndex--; // go to previous invoice in cycle + } + } + + $maxPrevSituationPercent = 0; + foreach ($invoice->tab_previous_situation_invoice[$lineIndex]->lines as $prevLine) { + if ($prevLine->id == $source_fk_prev_id) { + $maxPrevSituationPercent = max($maxPrevSituationPercent, $prevLine->situation_percent); + + //$line->subprice = $line->subprice - $prevLine->subprice; + $line->total_ht = $line->total_ht - $prevLine->total_ht; + $line->total_tva = $line->total_tva - $prevLine->total_tva; + $line->total_ttc = $line->total_ttc - $prevLine->total_ttc; + $line->total_localtax1 = $line->total_localtax1 - $prevLine->total_localtax1; + $line->total_localtax2 = $line->total_localtax2 - $prevLine->total_localtax2; + + $line->multicurrency_subprice = $line->multicurrency_subprice - $prevLine->multicurrency_subprice; + $line->multicurrency_total_ht = $line->multicurrency_total_ht - $prevLine->multicurrency_total_ht; + $line->multicurrency_total_tva = $line->multicurrency_total_tva - $prevLine->multicurrency_total_tva; + $line->multicurrency_total_ttc = $line->multicurrency_total_ttc - $prevLine->multicurrency_total_ttc; + } + } + + // prorata + $line->situation_percent = $maxPrevSituationPercent - $line->situation_percent; + + //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.'
'; + + // If there is some credit note between last situation invoice and invoice used for credit note generation (note: credit notes are stored as delta) + $maxPrevSituationPercent = 0; + foreach ($tab_jumped_credit_notes as $index => $creditnoteid) { + foreach ($invoice->tab_previous_situation_invoice[$index]->lines as $prevLine) { + if ($prevLine->fk_prev_id == $source_fk_prev_id) { + $maxPrevSituationPercent = $prevLine->situation_percent; + + $line->total_ht -= $prevLine->total_ht; + $line->total_tva -= $prevLine->total_tva; + $line->total_ttc -= $prevLine->total_ttc; + $line->total_localtax1 -= $prevLine->total_localtax1; + $line->total_localtax2 -= $prevLine->total_localtax2; + + $line->multicurrency_subprice -= $prevLine->multicurrency_subprice; + $line->multicurrency_total_ht -= $prevLine->multicurrency_total_ht; + $line->multicurrency_total_tva -= $prevLine->multicurrency_total_tva; + $line->multicurrency_total_ttc -= $prevLine->multicurrency_total_ttc; + } + } + } + + // prorata + $line->situation_percent += $maxPrevSituationPercent; + + //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.'
'; + } + } + + $line->fk_facture = $creditnote->id; + $line->fk_parent_line = $fk_parent_line; + + $line->subprice = -$line->subprice; // invert price for object + $line->pa_ht = $line->pa_ht; // we choosed to have buy/cost price always positive, so no revert of sign here + $line->total_ht = -$line->total_ht; + $line->total_tva = -$line->total_tva; + $line->total_ttc = -$line->total_ttc; + $line->total_localtax1 = -$line->total_localtax1; + $line->total_localtax2 = -$line->total_localtax2; + + $line->multicurrency_subprice = -$line->multicurrency_subprice; + $line->multicurrency_total_ht = -$line->multicurrency_total_ht; + $line->multicurrency_total_tva = -$line->multicurrency_total_tva; + $line->multicurrency_total_ttc = -$line->multicurrency_total_ttc; + + $result = $line->insert(0, 1); // When creating credit note with same lines than source, we must ignore error if discount alreayd linked + + $creditnote->lines[] = $line; // insert new line in current object + + // Defined the new fk_parent_line + if ($result > 0 && $line->product_type == 9) { + $fk_parent_line = $result; } } - } - if ($idoflineadded <= 0) { - $invoice->fetch_thirdparty(); - $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, '', '', 0, 100, '', null, 0); - if (!empty($conf->global->TAKEPOS_CUSTOMER_DISPLAY)) { - $CUSTOMER_DISPLAY_line1 = $prod->label; - $CUSTOMER_DISPLAY_line2 = price($price_ttc); + $creditnote->update_price(1); + + $constantforkey = 'CASHDESK_NO_DECREASE_STOCK'.$_SESSION["takeposterminal"]; + if (!empty($conf->stock->enabled) && $conf->global->$constantforkey != "1") { + $savconst = $conf->global->STOCK_CALCULATE_ON_BILL; + $conf->global->STOCK_CALCULATE_ON_BILL = 1; + $constantforkey = 'CASHDESK_ID_WAREHOUSE'.$_SESSION["takeposterminal"]; + dol_syslog("Validate invoice with stock change into warehouse defined into constant ".$constantforkey." = ".$conf->global->$constantforkey); + $batch_rule = 0; + if (!empty($conf->productbatch->enabled) && !empty($conf->global->CASHDESK_FORCE_DECREASE_STOCK)) { + require_once DOL_DOCUMENT_ROOT.'/product/class/productbatch.class.php'; + $batch_rule = Productbatch::BATCH_RULE_SELLBY_EATBY_DATES_FIRST; + } + $res = $creditnote->validate($user, '', $conf->global->$constantforkey, 0, $batch_rule); + $conf->global->STOCK_CALCULATE_ON_BILL = $savconst; + } else { + $res = $creditnote->validate($user); } } - $invoice->fetch($placeid); -} - -if ($action == "freezone") { - $customer = new Societe($db); - $customer->fetch($invoice->socid); - - $tva_tx = GETPOST('tva_tx', 'alpha'); - if ($tva_tx != '') { - if (!preg_match('/\((.*)\)/', $tva_tx)) { - $tva_tx = price2num($tva_tx); + if ($action == 'history' || $action == 'creditnote') { + if ($action == 'creditnote') { + $placeid = $creditnote->id; + } else { + $placeid = (int) GETPOST('placeid', 'int'); } - } else { - $tva_tx = get_default_tva($mysoc, $customer); - } - - // Local Taxes - $localtax1_tx = get_localtax($tva_tx, 1, $customer, $mysoc, $tva_npr); - $localtax2_tx = get_localtax($tva_tx, 2, $customer, $mysoc, $tva_npr); - - $invoice->addline($desc, $number, 1, $tva_tx, $localtax1_tx, $localtax2_tx, 0, 0, '', 0, 0, 0, '', 'TTC', $number, 0, -1, 0, '', 0, 0, null, '', '', 0, 100, '', null, 0); - $invoice->fetch($placeid); -} - -if ($action == "addnote") { - $desc = GETPOST('addnote', 'alpha'); - if ($idline==0) { - $invoice->update_note($desc, '_public'); - } else foreach ($invoice->lines as $line) { - if ($line->id == $idline) { - $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); - } - } - $invoice->fetch($placeid); -} - -if ($action == "deleteline") { - if ($idline > 0 and $placeid > 0) { // If invoice exists and line selected. To avoid errors if deleted from another device or no line selected. - $invoice->deleteline($idline); - $invoice->fetch($placeid); - } elseif ($placeid > 0) { // If invoice exists but no line selected, proceed to delete last line. - $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."facturedet where fk_facture = ".((int) $placeid)." ORDER BY rowid DESC"; - $resql = $db->query($sql); - $row = $db->fetch_array($resql); - $deletelineid = $row[0]; - $invoice->deleteline($deletelineid); + $invoice = new Facture($db); $invoice->fetch($placeid); } - if (count($invoice->lines) == 0) { - $invoice->delete($user); - header("Location: ".DOL_URL_ROOT."/takepos/invoice.php"); - exit; + + if (($action == "addline" || $action == "freezone") && $placeid == 0) { + $invoice->socid = getDolGlobalString("$constforcompanyid"); + $invoice->date = dol_now(); + $invoice->module_source = 'takepos'; + $invoice->pos_source = isset($_SESSION["takeposterminal"]) ? $_SESSION["takeposterminal"] : '' ; + $invoice->entity = !empty($_SESSION["takeposinvoiceentity"]) ? $_SESSION["takeposinvoiceentity"] : $conf->entity; + + if ($invoice->socid <= 0) { + $langs->load('errors'); + dol_htmloutput_errors($langs->trans("ErrorModuleSetupNotComplete", "TakePos"), null, 1); + } else { + $placeid = $invoice->create($user); + if ($placeid < 0) { + dol_htmloutput_errors($invoice->error, $invoice->errors, 1); + } + $sql = "UPDATE ".MAIN_DB_PREFIX."facture set ref='(PROV-POS".$_SESSION["takeposterminal"]."-".$place.")' where rowid = ".((int) $placeid); + $db->query($sql); + } } -} -// Action to delete or discard an invoice -if ($action == "delete") { - // $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. - if ($placeid > 0) { - $result = $invoice->fetch($placeid); + if ($action == "addline") { + $prod = new Product($db); + $prod->fetch($idproduct); - if ($result > 0 && $invoice->statut == Facture::STATUS_DRAFT) { - $db->begin(); + $customer = new Societe($db); + $customer->fetch($invoice->socid); - // We delete the lines - $resdeletelines = 1; + $datapriceofproduct = $prod->getSellPrice($mysoc, $customer, 0); + + $qty = GETPOSTISSET('qty') ? GETPOST('qty', 'int') : 1; + $price = $datapriceofproduct['pu_ht']; + $price_ttc = $datapriceofproduct['pu_ttc']; + //$price_min = $datapriceofproduct['price_min']; + $price_base_type = $datapriceofproduct['price_base_type']; + $tva_tx = $datapriceofproduct['tva_tx']; + $tva_npr = $datapriceofproduct['tva_npr']; + + // Local Taxes + $localtax1_tx = get_localtax($tva_tx, 1, $customer, $mysoc, $tva_npr); + $localtax2_tx = get_localtax($tva_tx, 2, $customer, $mysoc, $tva_npr); + + if (!empty($conf->global->TAKEPOS_SUPPLEMENTS)) { + require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; + $cat = new Categorie($db); + $categories = $cat->containing($idproduct, 'product'); + $found = (array_search($conf->global->TAKEPOS_SUPPLEMENTS_CATEGORY, array_column($categories, 'id'))); + if ($found !== false) { // If this product is a supplement + $sql = "SELECT fk_parent_line FROM ".MAIN_DB_PREFIX."facturedet where rowid=$selectedline"; + $resql = $db->query($sql); + $row = $db->fetch_array($resql); + if ($row[0] == null) { + $parent_line = $selectedline; + } else { + $parent_line = $row[0]; //If the parent line is already a supplement, add the supplement to the main product + } + } + } + + $idoflineadded = 0; + // Group if enabled. Skip group if line already sent to the printer + if (!empty($conf->global->TAKEPOS_GROUP_SAME_PRODUCT) && $line->special_code != "4") { foreach ($invoice->lines as $line) { - $tmpres = $invoice->deleteline($line->id); - if ($tmpres < 0) { - $resdeletelines = 0; + if ($line->product_ref == $prod->ref) { + if ($line->special_code==4) continue; // If this line is sended to printer create new line + $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); + if ($result < 0) { + dol_htmloutput_errors($invoice->error, $invoice->errors, 1); + } else { + $idoflineadded = $line->id; + } break; } } - - $sql = "UPDATE ".MAIN_DB_PREFIX."facture"; - $varforconst = 'CASHDESK_ID_THIRDPARTY'.$_SESSION["takeposterminal"]; - $sql .= " SET fk_soc = ".((int) $conf->global->$varforconst).", "; - $sql .= " datec = '".$db->idate(dol_now())."'"; - $sql .= " WHERE ref = '(PROV-POS".$db->escape($_SESSION["takeposterminal"]."-".$place).")'"; - $resql1 = $db->query($sql); - - if ($resdeletelines && $resql1) { - $db->commit(); - } else { - $db->rollback(); + } + if ($idoflineadded <= 0) { + $invoice->fetch_thirdparty(); + $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, '', '', 0, 100, '', null, 0); + if (!empty($conf->global->TAKEPOS_CUSTOMER_DISPLAY)) { + $CUSTOMER_DISPLAY_line1 = $prod->label; + $CUSTOMER_DISPLAY_line2 = price($price_ttc); } + } + $invoice->fetch($placeid); + } + + if ($action == "freezone") { + $customer = new Societe($db); + $customer->fetch($invoice->socid); + + $tva_tx = GETPOST('tva_tx', 'alpha'); + if ($tva_tx != '') { + if (!preg_match('/\((.*)\)/', $tva_tx)) { + $tva_tx = price2num($tva_tx); + } + } else { + $tva_tx = get_default_tva($mysoc, $customer); + } + + // Local Taxes + $localtax1_tx = get_localtax($tva_tx, 1, $customer, $mysoc, $tva_npr); + $localtax2_tx = get_localtax($tva_tx, 2, $customer, $mysoc, $tva_npr); + + $invoice->addline($desc, $number, 1, $tva_tx, $localtax1_tx, $localtax2_tx, 0, 0, '', 0, 0, 0, '', 'TTC', $number, 0, -1, 0, '', 0, 0, null, '', '', 0, 100, '', null, 0); + $invoice->fetch($placeid); + } + + if ($action == "addnote") { + $desc = GETPOST('addnote', 'alpha'); + if ($idline==0) { + $invoice->update_note($desc, '_public'); + } else foreach ($invoice->lines as $line) { + if ($line->id == $idline) { + $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); + } + } + $invoice->fetch($placeid); + } + + if ($action == "deleteline") { + if ($idline > 0 and $placeid > 0) { // If invoice exists and line selected. To avoid errors if deleted from another device or no line selected. + $invoice->deleteline($idline); + $invoice->fetch($placeid); + } elseif ($placeid > 0) { // If invoice exists but no line selected, proceed to delete last line. + $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."facturedet where fk_facture = ".((int) $placeid)." ORDER BY rowid DESC"; + $resql = $db->query($sql); + $row = $db->fetch_array($resql); + $deletelineid = $row[0]; + $invoice->deleteline($deletelineid); $invoice->fetch($placeid); } + if (count($invoice->lines) == 0) { + $invoice->delete($user); + header("Location: ".DOL_URL_ROOT."/takepos/invoice.php"); + exit; + } } -} -if ($action == "updateqty") { - foreach ($invoice->lines as $line) { - if ($line->id == $idline) { - if (!$user->rights->takepos->editlines || (!$user->rights->takepos->editorderedlines && $line->special_code == "4")) { - dol_htmloutput_errors($langs->trans("NotEnoughPermissions", "TakePos"), null, 1); - } else { - $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); + // Action to delete or discard an invoice + if ($action == "delete") { + // $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. + if ($placeid > 0) { + $result = $invoice->fetch($placeid); + + if ($result > 0 && $invoice->statut == Facture::STATUS_DRAFT) { + $db->begin(); + + // We delete the lines + $resdeletelines = 1; + foreach ($invoice->lines as $line) { + $tmpres = $invoice->deleteline($line->id); + if ($tmpres < 0) { + $resdeletelines = 0; + break; + } + } + + $sql = "UPDATE ".MAIN_DB_PREFIX."facture"; + $varforconst = 'CASHDESK_ID_THIRDPARTY'.$_SESSION["takeposterminal"]; + $sql .= " SET fk_soc = ".((int) $conf->global->$varforconst).", "; + $sql .= " datec = '".$db->idate(dol_now())."'"; + $sql .= " WHERE ref = '(PROV-POS".$db->escape($_SESSION["takeposterminal"]."-".$place).")'"; + $resql1 = $db->query($sql); + + if ($resdeletelines && $resql1) { + $db->commit(); + } else { + $db->rollback(); + } + + $invoice->fetch($placeid); } } } - $invoice->fetch($placeid); -} - -if ($action == "updateprice") { - $customer = new Societe($db); - $customer->fetch($invoice->socid); - - foreach ($invoice->lines as $line) { - if ($line->id == $idline) { - $prod = new Product($db); - $prod->fetch($line->fk_product); - $datapriceofproduct = $prod->getSellPrice($mysoc, $customer, 0); - $price_min = $datapriceofproduct['price_min']; - $usercanproductignorepricemin = ((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->produit->ignore_price_min_advance)) || empty($conf->global->MAIN_USE_ADVANCED_PERMS)); - $pu_ht = price2num($number / (1 + ($line->tva_tx / 100)), 'MU'); - //Check min price - if ($usercanproductignorepricemin && (!empty($price_min) && (price2num($pu_ht) * (1 - price2num($line->remise_percent) / 100) < price2num($price_min)))) { - echo $langs->trans("CantBeLessThanMinPrice"); - } else { - if (empty($user->rights->takepos->editlines) || (empty($user->rights->takepos->editorderedlines) && $line->special_code == "4")) { + if ($action == "updateqty") { + foreach ($invoice->lines as $line) { + if ($line->id == $idline) { + if (!$user->rights->takepos->editlines || (!$user->rights->takepos->editorderedlines && $line->special_code == "4")) { dol_htmloutput_errors($langs->trans("NotEnoughPermissions", "TakePos"), null, 1); - } elseif (getDolGlobalInt('TAKEPOS_CHANGE_PRICE_HT') == 1) { - $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); } else { - $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); + $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); } } } + + $invoice->fetch($placeid); } - // Reload data - $invoice->fetch($placeid); -} + if ($action == "updateprice") { + $customer = new Societe($db); + $customer->fetch($invoice->socid); -if ($action == "updatereduction") { - $customer = new Societe($db); - $customer->fetch($invoice->socid); - - foreach ($invoice->lines as $line) { - if ($line->id == $idline) { - dol_syslog("updatereduction Process line ".$line->id.' to apply discount of '.$number.'%'); - - $prod = new Product($db); - $prod->fetch($line->fk_product); - - $datapriceofproduct = $prod->getSellPrice($mysoc, $customer, 0); - $price_min = $datapriceofproduct['price_min']; - $usercanproductignorepricemin = ((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->produit->ignore_price_min_advance)) || empty($conf->global->MAIN_USE_ADVANCED_PERMS)); - - $pu_ht = price2num($line->subprice / (1 + ($line->tva_tx / 100)), 'MU'); - - // Check min price - if ($usercanproductignorepricemin && (!empty($price_min) && (price2num($line->subprice) * (1 - price2num($number) / 100) < price2num($price_min)))) { - echo $langs->trans("CantBeLessThanMinPrice"); - } else { - if (empty($user->rights->takepos->editlines) || (empty($user->rights->takepos->editorderedlines) && $line->special_code == "4")) { - dol_htmloutput_errors($langs->trans("NotEnoughPermissions", "TakePos"), null, 1); + foreach ($invoice->lines as $line) { + if ($line->id == $idline) { + $prod = new Product($db); + $prod->fetch($line->fk_product); + $datapriceofproduct = $prod->getSellPrice($mysoc, $customer, 0); + $price_min = $datapriceofproduct['price_min']; + $usercanproductignorepricemin = ((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->produit->ignore_price_min_advance)) || empty($conf->global->MAIN_USE_ADVANCED_PERMS)); + $pu_ht = price2num($number / (1 + ($line->tva_tx / 100)), 'MU'); + //Check min price + if ($usercanproductignorepricemin && (!empty($price_min) && (price2num($pu_ht) * (1 - price2num($line->remise_percent) / 100) < price2num($price_min)))) { + echo $langs->trans("CantBeLessThanMinPrice"); } else { - $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); + if (empty($user->rights->takepos->editlines) || (empty($user->rights->takepos->editorderedlines) && $line->special_code == "4")) { + dol_htmloutput_errors($langs->trans("NotEnoughPermissions", "TakePos"), null, 1); + } elseif (getDolGlobalInt('TAKEPOS_CHANGE_PRICE_HT') == 1) { + $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); + } else { + $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); + } } } } + + // Reload data + $invoice->fetch($placeid); } - // Reload data - $invoice->fetch($placeid); -} elseif ($action == 'update_reduction_global') { - foreach ($invoice->lines as $line) { - $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); - } + if ($action == "updatereduction") { + $customer = new Societe($db); + $customer->fetch($invoice->socid); - $invoice->fetch($placeid); -} + foreach ($invoice->lines as $line) { + if ($line->id == $idline) { + dol_syslog("updatereduction Process line ".$line->id.' to apply discount of '.$number.'%'); -if ($action == "order" and $placeid != 0) { - include_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; - if ($conf->global->TAKEPOS_PRINT_METHOD == "receiptprinter" || $conf->global->TAKEPOS_PRINT_METHOD == "takeposconnector") { - require_once DOL_DOCUMENT_ROOT.'/core/class/dolreceiptprinter.class.php'; - $printer = new dolReceiptPrinter($db); - } + $prod = new Product($db); + $prod->fetch($line->fk_product); - $sql = "SELECT label FROM ".MAIN_DB_PREFIX."takepos_floor_tables where rowid=".((int) $place); - $resql = $db->query($sql); - $row = $db->fetch_object($resql); - $headerorder = '
'.$langs->trans('Place').' '.$row->label.'
'; - $footerorder = '
'.$langs->trans("Label").''.$langs->trans("Qty").'
'.dol_print_date(dol_now(), 'dayhour').'
'; - $order_receipt_printer1 = ""; - $order_receipt_printer2 = ""; - $order_receipt_printer3 = ""; - $catsprinter1 = explode(';', $conf->global->TAKEPOS_PRINTED_CATEGORIES_1); - $catsprinter2 = explode(';', $conf->global->TAKEPOS_PRINTED_CATEGORIES_2); - $catsprinter3 = explode(';', $conf->global->TAKEPOS_PRINTED_CATEGORIES_3); - $linestoprint = 0; - foreach ($invoice->lines as $line) { - if ($line->special_code == "4") { - continue; + $datapriceofproduct = $prod->getSellPrice($mysoc, $customer, 0); + $price_min = $datapriceofproduct['price_min']; + $usercanproductignorepricemin = ((!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->produit->ignore_price_min_advance)) || empty($conf->global->MAIN_USE_ADVANCED_PERMS)); + + $pu_ht = price2num($line->subprice / (1 + ($line->tva_tx / 100)), 'MU'); + + // Check min price + if ($usercanproductignorepricemin && (!empty($price_min) && (price2num($line->subprice) * (1 - price2num($number) / 100) < price2num($price_min)))) { + echo $langs->trans("CantBeLessThanMinPrice"); + } else { + if (empty($user->rights->takepos->editlines) || (empty($user->rights->takepos->editorderedlines) && $line->special_code == "4")) { + dol_htmloutput_errors($langs->trans("NotEnoughPermissions", "TakePos"), null, 1); + } else { + $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); + } + } + } } - $c = new Categorie($db); - $existing = $c->containing($line->fk_product, Categorie::TYPE_PRODUCT, 'id'); - $result = array_intersect($catsprinter1, $existing); - $count = count($result); - if (!$line->fk_product) { - $count++; // Print Free-text item (Unassigned printer) to Printer 1 + + // Reload data + $invoice->fetch($placeid); + } elseif ($action == 'update_reduction_global') { + foreach ($invoice->lines as $line) { + $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); } - if ($count > 0) { - $linestoprint++; - $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet set special_code='1' where rowid=".$line->id; //Set to print on printer 1 - $db->query($sql); - $order_receipt_printer1 .= ''; - if ($line->fk_product) { - $order_receipt_printer1 .= $line->product_label; + + $invoice->fetch($placeid); + } + + if ($action == "order" and $placeid != 0) { + include_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; + if ($conf->global->TAKEPOS_PRINT_METHOD == "receiptprinter" || $conf->global->TAKEPOS_PRINT_METHOD == "takeposconnector") { + require_once DOL_DOCUMENT_ROOT.'/core/class/dolreceiptprinter.class.php'; + $printer = new dolReceiptPrinter($db); + } + + $sql = "SELECT label FROM ".MAIN_DB_PREFIX."takepos_floor_tables where rowid=".((int) $place); + $resql = $db->query($sql); + $row = $db->fetch_object($resql); + $headerorder = '
'.$langs->trans('Place').' '.$row->label.'
'; + $footerorder = '
'.$langs->trans("Label").''.$langs->trans("Qty").'
'.dol_print_date(dol_now(), 'dayhour').'
'; + $order_receipt_printer1 = ""; + $order_receipt_printer2 = ""; + $order_receipt_printer3 = ""; + $catsprinter1 = explode(';', $conf->global->TAKEPOS_PRINTED_CATEGORIES_1); + $catsprinter2 = explode(';', $conf->global->TAKEPOS_PRINTED_CATEGORIES_2); + $catsprinter3 = explode(';', $conf->global->TAKEPOS_PRINTED_CATEGORIES_3); + $linestoprint = 0; + foreach ($invoice->lines as $line) { + if ($line->special_code == "4") { + continue; + } + $c = new Categorie($db); + $existing = $c->containing($line->fk_product, Categorie::TYPE_PRODUCT, 'id'); + $result = array_intersect($catsprinter1, $existing); + $count = count($result); + if (!$line->fk_product) { + $count++; // Print Free-text item (Unassigned printer) to Printer 1 + } + if ($count > 0) { + $linestoprint++; + $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet set special_code='1' where rowid=".$line->id; //Set to print on printer 1 + $db->query($sql); + $order_receipt_printer1 .= ''; + if ($line->fk_product) { + $order_receipt_printer1 .= $line->product_label; + } else { + $order_receipt_printer1 .= $line->description; + } + $order_receipt_printer1 .= ''.$line->qty; + if (!empty($line->array_options['options_order_notes'])) { + $order_receipt_printer1 .= "
(".$line->array_options['options_order_notes'].")"; + } + $order_receipt_printer1 .= ''; + } + } + if (($conf->global->TAKEPOS_PRINT_METHOD == "receiptprinter" || $conf->global->TAKEPOS_PRINT_METHOD == "takeposconnector") && $linestoprint > 0) { + $invoice->fetch($placeid); //Reload object before send to printer + $printer->orderprinter = 1; + echo ""; + } + $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet set special_code='4' where special_code='1' and fk_facture=".$invoice->id; // Set as printed + $db->query($sql); + $invoice->fetch($placeid); //Reload object after set lines as printed + $linestoprint = 0; + + foreach ($invoice->lines as $line) { + if ($line->special_code == "4") { + continue; + } + $c = new Categorie($db); + $existing = $c->containing($line->fk_product, Categorie::TYPE_PRODUCT, 'id'); + $result = array_intersect($catsprinter2, $existing); + $count = count($result); + if ($count > 0) { + $linestoprint++; + $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet set special_code='2' where rowid=".$line->id; //Set to print on printer 2 + $db->query($sql); + $order_receipt_printer2 .= ''.$line->product_label.''.$line->qty; + if (!empty($line->array_options['options_order_notes'])) { + $order_receipt_printer2 .= "
(".$line->array_options['options_order_notes'].")"; + } + $order_receipt_printer2 .= ''; + } + } + if (($conf->global->TAKEPOS_PRINT_METHOD == "receiptprinter" || $conf->global->TAKEPOS_PRINT_METHOD == "takeposconnector") && $linestoprint > 0) { + $invoice->fetch($placeid); //Reload object before send to printer + $printer->orderprinter = 2; + echo ""; + } + $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet set special_code='4' where special_code='2' and fk_facture=".$invoice->id; // Set as printed + $db->query($sql); + $invoice->fetch($placeid); //Reload object after set lines as printed + $linestoprint = 0; + + foreach ($invoice->lines as $line) { + if ($line->special_code == "4") { + continue; + } + $c = new Categorie($db); + $existing = $c->containing($line->fk_product, Categorie::TYPE_PRODUCT, 'id'); + $result = array_intersect($catsprinter3, $existing); + $count = count($result); + if ($count > 0) { + $linestoprint++; + $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet set special_code='3' where rowid=".$line->id; //Set to print on printer 3 + $db->query($sql); + $order_receipt_printer3 .= ''.$line->product_label.''.$line->qty; + if (!empty($line->array_options['options_order_notes'])) { + $order_receipt_printer3 .= "
(".$line->array_options['options_order_notes'].")"; + } + $order_receipt_printer3 .= ''; + } + } + if (($conf->global->TAKEPOS_PRINT_METHOD == "receiptprinter" || $conf->global->TAKEPOS_PRINT_METHOD == "takeposconnector") && $linestoprint > 0) { + $invoice->fetch($placeid); //Reload object before send to printer + $printer->orderprinter = 3; + echo ""; + } + $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet set special_code='4' where special_code='3' and fk_facture=".$invoice->id; // Set as printed + $db->query($sql); + $invoice->fetch($placeid); //Reload object after set lines as printed + } + + $sectionwithinvoicelink = ''; + if ($action == "valid" || $action == "history" || $action == 'creditnote') { + $sectionwithinvoicelink .= ''."\n"; + $sectionwithinvoicelink .= ''; + $sectionwithinvoicelink .= $invoice->getNomUrl(1, '', 0, 0, '', 0, 0, -1, '_backoffice')." - "; + $remaintopay = $invoice->getRemainToPay(); + if ($remaintopay > 0) { + $sectionwithinvoicelink .= $langs->trans('RemainToPay').': '.price($remaintopay, 1, $langs, 1, -1, -1, $conf->currency).''; + } else { + if ($invoice->paye) { + $sectionwithinvoicelink .= ''.$langs->trans("Paid").''; } else { - $order_receipt_printer1 .= $line->description; + $sectionwithinvoicelink .= $langs->trans('BillShortStatusValidated'); } - $order_receipt_printer1 .= ''.$line->qty; - if (!empty($line->array_options['options_order_notes'])) { - $order_receipt_printer1 .= "
(".$line->array_options['options_order_notes'].")"; + } + $sectionwithinvoicelink .= '

'; + if (getDolGlobalString('TAKEPOS_PRINT_METHOD') == "takeposconnector") { + if (getDolGlobalString('TAKEPOS_PRINT_SERVER') && filter_var($conf->global->TAKEPOS_PRINT_SERVER, FILTER_VALIDATE_URL) == true) { + $sectionwithinvoicelink .= ' '; + } else { + $sectionwithinvoicelink .= ' '; } - $order_receipt_printer1 .= ''; - } - } - if (($conf->global->TAKEPOS_PRINT_METHOD == "receiptprinter" || $conf->global->TAKEPOS_PRINT_METHOD == "takeposconnector") && $linestoprint > 0) { - $invoice->fetch($placeid); //Reload object before send to printer - $printer->orderprinter = 1; - echo ""; - } - $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet set special_code='4' where special_code='1' and fk_facture=".$invoice->id; // Set as printed - $db->query($sql); - $invoice->fetch($placeid); //Reload object after set lines as printed - $linestoprint = 0; - - foreach ($invoice->lines as $line) { - if ($line->special_code == "4") { - continue; - } - $c = new Categorie($db); - $existing = $c->containing($line->fk_product, Categorie::TYPE_PRODUCT, 'id'); - $result = array_intersect($catsprinter2, $existing); - $count = count($result); - if ($count > 0) { - $linestoprint++; - $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet set special_code='2' where rowid=".$line->id; //Set to print on printer 2 - $db->query($sql); - $order_receipt_printer2 .= ''.$line->product_label.''.$line->qty; - if (!empty($line->array_options['options_order_notes'])) { - $order_receipt_printer2 .= "
(".$line->array_options['options_order_notes'].")"; - } - $order_receipt_printer2 .= ''; - } - } - if (($conf->global->TAKEPOS_PRINT_METHOD == "receiptprinter" || $conf->global->TAKEPOS_PRINT_METHOD == "takeposconnector") && $linestoprint > 0) { - $invoice->fetch($placeid); //Reload object before send to printer - $printer->orderprinter = 2; - echo ""; - } - $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet set special_code='4' where special_code='2' and fk_facture=".$invoice->id; // Set as printed - $db->query($sql); - $invoice->fetch($placeid); //Reload object after set lines as printed - $linestoprint = 0; - - foreach ($invoice->lines as $line) { - if ($line->special_code == "4") { - continue; - } - $c = new Categorie($db); - $existing = $c->containing($line->fk_product, Categorie::TYPE_PRODUCT, 'id'); - $result = array_intersect($catsprinter3, $existing); - $count = count($result); - if ($count > 0) { - $linestoprint++; - $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet set special_code='3' where rowid=".$line->id; //Set to print on printer 3 - $db->query($sql); - $order_receipt_printer3 .= ''.$line->product_label.''.$line->qty; - if (!empty($line->array_options['options_order_notes'])) { - $order_receipt_printer3 .= "
(".$line->array_options['options_order_notes'].")"; - } - $order_receipt_printer3 .= ''; - } - } - if (($conf->global->TAKEPOS_PRINT_METHOD == "receiptprinter" || $conf->global->TAKEPOS_PRINT_METHOD == "takeposconnector") && $linestoprint > 0) { - $invoice->fetch($placeid); //Reload object before send to printer - $printer->orderprinter = 3; - echo ""; - } - $sql = "UPDATE ".MAIN_DB_PREFIX."facturedet set special_code='4' where special_code='3' and fk_facture=".$invoice->id; // Set as printed - $db->query($sql); - $invoice->fetch($placeid); //Reload object after set lines as printed -} - -$sectionwithinvoicelink = ''; -if ($action == "valid" || $action == "history" || $action == 'creditnote') { - $sectionwithinvoicelink .= ''."\n"; - $sectionwithinvoicelink .= ''; - $sectionwithinvoicelink .= $invoice->getNomUrl(1, '', 0, 0, '', 0, 0, -1, '_backoffice')." - "; - $remaintopay = $invoice->getRemainToPay(); - if ($remaintopay > 0) { - $sectionwithinvoicelink .= $langs->trans('RemainToPay').': '.price($remaintopay, 1, $langs, 1, -1, -1, $conf->currency).''; - } else { - if ($invoice->paye) { - $sectionwithinvoicelink .= ''.$langs->trans("Paid").''; + } elseif (getDolGlobalString('TAKEPOS_PRINT_METHOD') == "receiptprinter") { + $sectionwithinvoicelink .= ' '; } else { - $sectionwithinvoicelink .= $langs->trans('BillShortStatusValidated'); + $sectionwithinvoicelink .= ' '; + if (getDolGlobalString('TAKEPOS_PRINT_WITHOUT_DETAILS')) { + $sectionwithinvoicelink .= ' '; + } + if (getDolGlobalString('TAKEPOS_GIFT_RECEIPT')) { + $sectionwithinvoicelink .= ' '; + } } - } - $sectionwithinvoicelink .= '
'; - if (getDolGlobalString('TAKEPOS_PRINT_METHOD') == "takeposconnector") { - if (getDolGlobalString('TAKEPOS_PRINT_SERVER') && filter_var($conf->global->TAKEPOS_PRINT_SERVER, FILTER_VALIDATE_URL) == true) { - $sectionwithinvoicelink .= ' '; - } else { - $sectionwithinvoicelink .= ' '; + if (getDolGlobalString('TAKEPOS_EMAIL_TEMPLATE_INVOICE') && $conf->global->TAKEPOS_EMAIL_TEMPLATE_INVOICE > 0) { + $sectionwithinvoicelink .= ' '; } - } elseif (getDolGlobalString('TAKEPOS_PRINT_METHOD') == "receiptprinter") { - $sectionwithinvoicelink .= ' '; - } else { - $sectionwithinvoicelink .= ' '; - if (getDolGlobalString('TAKEPOS_PRINT_WITHOUT_DETAILS')) { - $sectionwithinvoicelink .= ' '; - } - if (getDolGlobalString('TAKEPOS_GIFT_RECEIPT')) { - $sectionwithinvoicelink .= ' '; - } - } - if (getDolGlobalString('TAKEPOS_EMAIL_TEMPLATE_INVOICE') && $conf->global->TAKEPOS_EMAIL_TEMPLATE_INVOICE > 0) { - $sectionwithinvoicelink .= ' '; - } - if ($remaintopay <= 0 && getDolGlobalString('TAKEPOS_AUTO_PRINT_TICKETS')) { - $sectionwithinvoicelink .= ''; + if ($remaintopay <= 0 && getDolGlobalString('TAKEPOS_AUTO_PRINT_TICKETS')) { + $sectionwithinvoicelink .= ''; + } } } - /* * View */