diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 1afa9347f67..c3544ba214e 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -5367,9 +5367,11 @@ class FactureLigne extends CommonInvoiceLine return -1; } - // if buy price not defined, define buyprice as configured in margin admin + // if buy price not provided, define buyprice as configured in margin admin if ($this->pa_ht == 0 && $pa_ht_isemptystring) { - if (($result = $this->defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product)) < 0) { + // We call defineBuyPrice only if data was not provided (if input was '0', we will not go here and value will remaine '0') + $result = $this->defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product); + if ($result < 0) { return $result; } else { $this->pa_ht = $result; @@ -5410,7 +5412,7 @@ class FactureLigne extends CommonInvoiceLine $sql .= ", total_localtax2=".price2num($this->total_localtax2); } $sql .= ", fk_product_fournisseur_price=".(!empty($this->fk_fournprice) ? "'".$this->db->escape($this->fk_fournprice)."'" : "null"); - $sql .= ", buy_price_ht='".price2num($this->pa_ht)."'"; + $sql .= ", buy_price_ht=".(($this->pa_ht || $this->pa_ht === 0 || $this->pa_ht === '0') ? price2num($this->pa_ht) : "null"); // $this->pa_ht should always be defined (set to 0 or to sell price depending on option) $sql .= ", fk_parent_line=".($this->fk_parent_line > 0 ? $this->fk_parent_line : "null"); if (!empty($this->rang)) { $sql .= ", rang=".$this->rang; diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index d857a789df1..8fa0ad9c8a5 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -7688,7 +7688,8 @@ abstract class CommonObject $buyPrice = 0; - if (($unitPrice > 0) && (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 1)) { // In most cases, test here is false + if (($unitPrice > 0) && (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull > 0)) { + // When ForceBuyingPriceIfNull is set $buyPrice = $unitPrice * (1 - $discountPercent / 100); } else { // Get cost price for margin calculation diff --git a/htdocs/core/class/html.formmargin.class.php b/htdocs/core/class/html.formmargin.class.php index c58b0a4036a..f951a3dc198 100644 --- a/htdocs/core/class/html.formmargin.class.php +++ b/htdocs/core/class/html.formmargin.class.php @@ -90,8 +90,10 @@ class FormMargin $line->pa_ht = $product->fourn_unitprice * (1 - $product->fourn_remise_percent / 100); } } - // si prix d'achat non renseignĂ© et devrait l'ĂȘtre, alors prix achat = prix vente - if ((!isset($line->pa_ht) || $line->pa_ht == 0) && $line->subprice > 0 && (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 1)) { + + // If buy price is not defined (null), we will use the sell price. If defined to 0 (it means it was forced to 0 during insert, for example for a free to get product), we must still use 0. + //if ((!isset($line->pa_ht) || $line->pa_ht == 0) && $line->subprice > 0 && (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull > 0)) { + if ((!isset($line->pa_ht)) && $line->subprice > 0 && (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull > 0)) { $line->pa_ht = $line->subprice * (1 - ($line->remise_percent / 100)); } diff --git a/htdocs/langs/en_US/banks.lang b/htdocs/langs/en_US/banks.lang index f0f5dfd0a8e..8e2d828c12a 100644 --- a/htdocs/langs/en_US/banks.lang +++ b/htdocs/langs/en_US/banks.lang @@ -174,7 +174,7 @@ YourSEPAMandate=Your SEPA mandate FindYourSEPAMandate=This is your SEPA mandate to authorize our company to make direct debit order to your bank. Return it signed (scan of the signed document) or send it by mail to AutoReportLastAccountStatement=Automatically fill the field 'number of bank statement' with last statement number when making reconciliation CashControl=POS cash desk control -NewCashFence=New cash desk closing +NewCashFence=New cash desk opening or closing BankColorizeMovement=Colorize movements BankColorizeMovementDesc=If this function is enable, you can choose specific background color for debit or credit movements BankColorizeMovementName1=Background color for debit movement diff --git a/htdocs/langs/en_US/margins.lang b/htdocs/langs/en_US/margins.lang index 76ea8ad5c4d..ad5406409b4 100644 --- a/htdocs/langs/en_US/margins.lang +++ b/htdocs/langs/en_US/margins.lang @@ -22,7 +22,7 @@ ProductService=Product or Service AllProducts=All products and services ChooseProduct/Service=Choose product or service ForceBuyingPriceIfNull=Force buying/cost price to selling price if not defined -ForceBuyingPriceIfNullDetails=If buying/cost price not defined, and this option "ON", margin will be zero on line (buying/cost price = selling price), otherwise ("OFF"), marge will be equal to suggested default. +ForceBuyingPriceIfNullDetails=If buying/cost price not provided when we add a new line, and this option is "ON", the margin will be 0 on the new line (buying/cost price = selling price). If this option is "OFF" (recommended), margin will be equal to the value suggested by default (and may be 100% if no default value can be found). MARGIN_METHODE_FOR_DISCOUNT=Margin method for global discounts UseDiscountAsProduct=As a product UseDiscountAsService=As a service diff --git a/htdocs/margin/agentMargins.php b/htdocs/margin/agentMargins.php index a8db68d9fec..9042ed16dac 100644 --- a/htdocs/margin/agentMargins.php +++ b/htdocs/margin/agentMargins.php @@ -183,7 +183,9 @@ if (!empty($enddate)) { $sql .= " AND f.datef <= '".$db->idate($enddate)."'"; } $sql .= " AND d.buy_price_ht IS NOT NULL"; -if (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 1) { +// We should not use this here. Option ForceBuyingPriceIfNull should have effect only when inserting data. Once data is recorded, it must be used as it is for report. +// We keep it with value ForceBuyingPriceIfNull = 2 for retroactive effect but results are unpredicable. +if (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 2) { $sql .= " AND d.buy_price_ht <> 0"; } //if ($agentid > 0) $sql.= " GROUP BY s.rowid, s.nom, s.code_client, s.client, u.rowid, u.login, u.lastname, u.firstname"; diff --git a/htdocs/margin/customerMargins.php b/htdocs/margin/customerMargins.php index 1a1e83a2567..e24d318bafc 100644 --- a/htdocs/margin/customerMargins.php +++ b/htdocs/margin/customerMargins.php @@ -257,7 +257,9 @@ if (!empty($enddate)) { $sql .= " AND f.datef <= '".$db->idate($enddate)."'"; } $sql .= " AND d.buy_price_ht IS NOT NULL"; -if (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 1) { +// We should not use this here. Option ForceBuyingPriceIfNull should have effect only when inserting data. Once data is recorded, it must be used as it is for report. +// We keep it with value ForceBuyingPriceIfNull = 2 for retroactive effect but results are unpredicable. +if (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 2) { $sql .= " AND d.buy_price_ht <> 0"; } if ($client) { diff --git a/htdocs/margin/productMargins.php b/htdocs/margin/productMargins.php index 43afbaa0e92..a101848bfa1 100644 --- a/htdocs/margin/productMargins.php +++ b/htdocs/margin/productMargins.php @@ -210,7 +210,9 @@ if (!empty($enddate)) { $sql .= " AND f.datef <= '".$db->idate($enddate)."'"; } $sql .= " AND d.buy_price_ht IS NOT NULL"; -if (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 1) { +// We should not use this here. Option ForceBuyingPriceIfNull should have effect only when inserting data. Once data is recorded, it must be used as it is for report. +// We keep it with value ForceBuyingPriceIfNull = 2 for retroactive effect but results are unpredicable. +if (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 2) { $sql .= " AND d.buy_price_ht <> 0"; } if ($id > 0) { diff --git a/htdocs/margin/tabs/productMargins.php b/htdocs/margin/tabs/productMargins.php index 031c49e4cd0..9fff2866cab 100644 --- a/htdocs/margin/tabs/productMargins.php +++ b/htdocs/margin/tabs/productMargins.php @@ -164,7 +164,9 @@ if ($id > 0 || !empty($ref)) { $sql .= " AND f.fk_soc = $socid"; } $sql .= " AND d.buy_price_ht IS NOT NULL"; - if (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 1) { + // We should not use this here. Option ForceBuyingPriceIfNull should have effect only when inserting data. Once data is recorded, it must be used as it is for report. + // We keep it with value ForceBuyingPriceIfNull = 2 for retroactive effect but results are unpredicable. + if (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 2) { $sql .= " AND d.buy_price_ht <> 0"; } $sql .= " GROUP BY s.nom, s.rowid, s.code_client, f.rowid, f.ref, f.total, f.datef, f.paye, f.fk_statut, f.type"; diff --git a/htdocs/margin/tabs/thirdpartyMargins.php b/htdocs/margin/tabs/thirdpartyMargins.php index 0103bd03aca..e32f88cdc2e 100644 --- a/htdocs/margin/tabs/thirdpartyMargins.php +++ b/htdocs/margin/tabs/thirdpartyMargins.php @@ -174,7 +174,9 @@ if ($socid > 0) { $sql .= " AND d.fk_facture = f.rowid"; $sql .= " AND f.fk_soc = $socid"; $sql .= " AND d.buy_price_ht IS NOT NULL"; - if (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 1) { + // We should not use this here. Option ForceBuyingPriceIfNull should have effect only when inserting data. Once data is recorded, it must be used as it is for report. + // We keep it with value ForceBuyingPriceIfNull = 2 for retroactive effect but results are unpredicable. + if (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 2) { $sql .= " AND d.buy_price_ht <> 0"; } $sql .= " GROUP BY s.nom, s.rowid, s.code_client, f.rowid, f.ref, f.total, f.datef, f.paye, f.fk_statut, f.type";