FIX inconsistency in margin recording with option "Force to sale price"

This commit is contained in:
Laurent Destailleur 2021-03-24 21:49:45 +01:00
parent debcef9b55
commit 21a9779fe2
9 changed files with 36 additions and 16 deletions

View File

@ -5171,11 +5171,11 @@ class FactureLigne extends CommonInvoiceLine
// Check parameters
if ($this->product_type < 0) return -1;
// if buy price not defined, 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)
{
// if buy price not provided, define buyprice as configured in margin admin
if ($this->pa_ht == 0 && $pa_ht_isemptystring) {
// 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;
@ -5214,7 +5214,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;
$sql .= ", situation_percent=".$this->situation_percent;

View File

@ -7122,7 +7122,7 @@ 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)) // In most cases, test here is false
{
$buyPrice = $unitPrice * (1 - $discountPercent / 100);
} else {

View File

@ -91,8 +91,10 @@ class FormMargin
if ($product->fetch_product_fournisseur_price($line->fk_fournprice))
$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));
}

View File

@ -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", margin will be equal to the value suggested by default (and 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

View File

@ -170,7 +170,11 @@ if (!empty($startdate))
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) $sql .= " AND d.buy_price_ht <> 0";
// 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";
//else $sql.= " GROUP BY u.rowid, u.login, u.lastname, u.firstname";
$sql .= " GROUP BY s.rowid, s.nom, s.code_client, s.client, u.rowid, u.login, u.lastname, u.firstname";

View File

@ -234,8 +234,11 @@ $sql .= " AND f.datef >= '".$db->idate($startdate)."'";
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)
$sql .= " AND d.buy_price_ht <> 0";
// 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) $sql .= " GROUP BY s.rowid, s.nom, s.code_client, s.client, f.rowid, f.ref, f.total, f.datef, f.paye, f.fk_statut";
else $sql .= " GROUP BY s.rowid, s.nom, s.code_client, s.client";
$sql .= $db->order($sortfield, $sortorder);

View File

@ -197,8 +197,11 @@ if (!empty($startdate))
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) $sql .= " GROUP BY p.label, p.rowid, p.fk_product_type, p.ref, p.entity, d.fk_product, f.rowid, f.ref, f.total, f.datef, f.paye, f.fk_statut";
else $sql .= " GROUP BY p.label, p.rowid, p.fk_product_type, p.ref, p.entity";
$sql .= $db->order($sortfield, $sortorder);

View File

@ -150,7 +150,11 @@ if ($id > 0 || !empty($ref))
if (!$user->rights->societe->client->voir && !$socid) $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".$user->id;
if (!empty($socid)) $sql .= " AND f.fk_soc = $socid";
$sql .= " AND d.buy_price_ht IS NOT NULL";
if (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 1) $sql .= " AND d.buy_price_ht <> 0";
// 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";
if (!$user->rights->societe->client->voir && !$socid) $sql .= ", sc.fk_soc, sc.fk_user";
$sql .= $db->order($sortfield, $sortorder);

View File

@ -163,7 +163,11 @@ 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) $sql .= " AND d.buy_price_ht <> 0";
// 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";
$sql .= $db->order($sortfield, $sortorder);
// TODO: calculate total to display then restore pagination