';
+ dol_syslog('Failed to read file: '.$file_check_arr['path'], LOG_WARNING);
+ }
+ continue;
}
}
diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php
index acb7d5b5f2a..75f35e39bec 100644
--- a/htdocs/core/class/html.formfile.class.php
+++ b/htdocs/core/class/html.formfile.class.php
@@ -7,7 +7,7 @@
* Copyright (C) 2014 Marcos García
* Copyright (C) 2015 Bahfir Abbes
* Copyright (C) 2016-2017 Ferran Marcet
- * Copyright (C) 2019-2021 Frédéric France
+ * Copyright (C) 2019-2022 Frédéric France
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -986,6 +986,8 @@ class FormFile
$out .= '
';
// Fields for situation invoice
if (isset($this->situation_cycle_ref) && $this->situation_cycle_ref) {
diff --git a/htdocs/install/mysql/tables/llx_webhook_target-webhook.key.sql b/htdocs/install/mysql/tables/llx_webhook_target-webhook.key.sql
new file mode 100644
index 00000000000..04a0dbb306a
--- /dev/null
+++ b/htdocs/install/mysql/tables/llx_webhook_target-webhook.key.sql
@@ -0,0 +1,27 @@
+-- Copyright (C) ---Put here your own copyright and developer email---
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program. If not, see https://www.gnu.org/licenses/.
+
+
+-- BEGIN MODULEBUILDER INDEXES
+ALTER TABLE llx_webhook_target ADD INDEX idx_webhook_target_rowid (rowid);
+ALTER TABLE llx_webhook_target ADD INDEX idx_webhook_target_ref (ref);
+ALTER TABLE llx_webhook_target ADD CONSTRAINT llx_webhook_target_fk_user_creat FOREIGN KEY (fk_user_creat) REFERENCES llx_user(rowid);
+ALTER TABLE llx_webhook_target ADD INDEX idx_webhook_target_status (status);
+-- END MODULEBUILDER INDEXES
+
+--ALTER TABLE llx_webhook_target ADD UNIQUE INDEX uk_webhook_target_fieldxy(fieldx, fieldy);
+
+--ALTER TABLE llx_webhook_target ADD CONSTRAINT llx_webhook_target_fk_field FOREIGN KEY (fk_field) REFERENCES llx_webhook_myotherobject(rowid);
+
diff --git a/htdocs/install/mysql/tables/llx_webhook_target-webhook.sql b/htdocs/install/mysql/tables/llx_webhook_target-webhook.sql
new file mode 100644
index 00000000000..1e0cc0fdbac
--- /dev/null
+++ b/htdocs/install/mysql/tables/llx_webhook_target-webhook.sql
@@ -0,0 +1,34 @@
+-- Copyright (C) ---Put here your own copyright and developer email---
+--
+-- This program is free software: you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation, either version 3 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program. If not, see https://www.gnu.org/licenses/.
+
+
+CREATE TABLE llx_webhook_target(
+ -- BEGIN MODULEBUILDER FIELDS
+ rowid integer AUTO_INCREMENT PRIMARY KEY NOT NULL,
+ ref varchar(128) NOT NULL,
+ label varchar(255),
+ description text,
+ note_public text,
+ note_private text,
+ date_creation datetime NOT NULL,
+ tms timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ fk_user_creat integer NOT NULL,
+ fk_user_modif integer,
+ import_key varchar(14),
+ status integer DEFAULT 0 NOT NULL,
+ url varchar(255) NOT NULL,
+ trigger_codes text NOT NULL
+ -- END MODULEBUILDER FIELDS
+) ENGINE=innodb;
diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang
index b39124c7c53..530f3b6af0e 100644
--- a/htdocs/langs/en_US/main.lang
+++ b/htdocs/langs/en_US/main.lang
@@ -621,6 +621,7 @@ MonthVeryShort11=N
MonthVeryShort12=D
AttachedFiles=Attached files and documents
JoinMainDoc=Join main document
+JoinMainDocOrLastGenerated=Send the main document or the last generated one if not found
DateFormatYYYYMM=YYYY-MM
DateFormatYYYYMMDD=YYYY-MM-DD
DateFormatYYYYMMDDHHMM=YYYY-MM-DD HH:SS
@@ -1172,4 +1173,4 @@ AddLineOnPosition=Add line on position (at the end if empty)
ConfirmAllocateCommercial=Assign sales representative confirmation
ConfirmAllocateCommercialQuestion=Are you sure you want to assign the %s selected record(s)?
CommercialsAffected=Sales representatives affected
-CommercialAffected=Sales representative affected
\ No newline at end of file
+CommercialAffected=Sales representative affected
diff --git a/htdocs/langs/fr_FR/main.lang b/htdocs/langs/fr_FR/main.lang
index 12778f337dd..53ff7d545b3 100644
--- a/htdocs/langs/fr_FR/main.lang
+++ b/htdocs/langs/fr_FR/main.lang
@@ -620,6 +620,7 @@ MonthVeryShort11=N
MonthVeryShort12=D
AttachedFiles=Fichiers et documents joints
JoinMainDoc=Joindre le document principal
+JoinMainDocOrLastGenerated=Joindre le document principal ou le dernier généré s'il n'a pas été trouvé
DateFormatYYYYMM=YYYY-MM
DateFormatYYYYMMDD=YYYY-MM-DD
DateFormatYYYYMMDDHHMM=YYYY-MM-DD HH:SS
diff --git a/htdocs/public/ticket/create_ticket.php b/htdocs/public/ticket/create_ticket.php
index dff6a0b2484..371789edc62 100644
--- a/htdocs/public/ticket/create_ticket.php
+++ b/htdocs/public/ticket/create_ticket.php
@@ -264,7 +264,7 @@ if (empty($reshook) && $action == 'create_ticket' && GETPOST('save', 'alpha')) {
$infos_new_ticket .= $langs->transnoentities('TicketNewEmailBodyInfosTrackUrl').'
';
$message .= $infos_new_ticket;
- $message .= getDolGlobalString('TICKET_MESSAGE_MAIL_SIGNATURE') ? getDolGlobalString('TICKET_MESSAGE_MAIL_SIGNATURE') : $langs->transnoentities('TicketMessageMailSignatureText', $mysoc->name);
+ $message .= getDolGlobalString('TICKET_MESSAGE_MAIL_SIGNATURE', $langs->transnoentities('TicketMessageMailSignatureText', $mysoc->name));
$sendto = GETPOST('email', 'alpha');
diff --git a/htdocs/takepos/index.php b/htdocs/takepos/index.php
index 4621423eb02..244386a8180 100644
--- a/htdocs/takepos/index.php
+++ b/htdocs/takepos/index.php
@@ -361,6 +361,13 @@ function LoadProducts(position, issubcat) {
$("#prodiv"+ishow).attr("class","wrapper2");
$("#prowatermark"+ishow).hide();
ishow++; //Next product to show after print data product
+ executeHooks('completeJSProductDisplay', $parameters);
+ print $hookmanager->resPrint;
+ ?>
}
//console.log("Hide the prowatermark for ishow="+ishow);
idata++; //Next data everytime
@@ -627,6 +634,15 @@ function Search2(keyCodeForEnter, moreorless) {
}
$("#prodiv" + i).data("rowid", data[i]['rowid']);
$("#prodiv" + i).data("iscat", 0);
+
+ executeHooks('completeJSProductDisplay', $parameters);
+ print $hookmanager->resPrint;
+ ?>
+
nbsearchresults++;
}
}).always(function (data) {
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.'