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 // Check parameters
if ($this->product_type < 0) return -1; if ($this->product_type < 0) 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 ($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')
if (($result = $this->defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product)) < 0) $result = $this->defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product);
{ if ($result < 0) {
return $result; return $result;
} else { } else {
$this->pa_ht = $result; $this->pa_ht = $result;
@ -5214,7 +5214,7 @@ class FactureLigne extends CommonInvoiceLine
$sql .= ", total_localtax2=".price2num($this->total_localtax2); $sql .= ", total_localtax2=".price2num($this->total_localtax2);
} }
$sql .= ", fk_product_fournisseur_price=".(!empty($this->fk_fournprice) ? "'".$this->db->escape($this->fk_fournprice)."'" : "null"); $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"); $sql .= ", fk_parent_line=".($this->fk_parent_line > 0 ? $this->fk_parent_line : "null");
if (!empty($this->rang)) $sql .= ", rang=".$this->rang; if (!empty($this->rang)) $sql .= ", rang=".$this->rang;
$sql .= ", situation_percent=".$this->situation_percent; $sql .= ", situation_percent=".$this->situation_percent;

View File

@ -7122,7 +7122,7 @@ abstract class CommonObject
$buyPrice = 0; $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); $buyPrice = $unitPrice * (1 - $discountPercent / 100);
} else { } else {

View File

@ -91,8 +91,10 @@ class FormMargin
if ($product->fetch_product_fournisseur_price($line->fk_fournprice)) if ($product->fetch_product_fournisseur_price($line->fk_fournprice))
$line->pa_ht = $product->fourn_unitprice * (1 - $product->fourn_remise_percent / 100); $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)); $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 AllProducts=All products and services
ChooseProduct/Service=Choose product or service ChooseProduct/Service=Choose product or service
ForceBuyingPriceIfNull=Force buying/cost price to selling price if not defined 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 MARGIN_METHODE_FOR_DISCOUNT=Margin method for global discounts
UseDiscountAsProduct=As a product UseDiscountAsProduct=As a product
UseDiscountAsService=As a service UseDiscountAsService=As a service

View File

@ -170,7 +170,11 @@ if (!empty($startdate))
if (!empty($enddate)) if (!empty($enddate))
$sql .= " AND f.datef <= '".$db->idate($enddate)."'"; $sql .= " AND f.datef <= '".$db->idate($enddate)."'";
$sql .= " AND d.buy_price_ht IS NOT NULL"; $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"; //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"; //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"; $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)) if (!empty($enddate))
$sql .= " AND f.datef <= '".$db->idate($enddate)."'"; $sql .= " AND f.datef <= '".$db->idate($enddate)."'";
$sql .= " AND d.buy_price_ht IS NOT NULL"; $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.
$sql .= " AND d.buy_price_ht <> 0"; // 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"; 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"; else $sql .= " GROUP BY s.rowid, s.nom, s.code_client, s.client";
$sql .= $db->order($sortfield, $sortorder); $sql .= $db->order($sortfield, $sortorder);

View File

@ -197,8 +197,11 @@ if (!empty($startdate))
if (!empty($enddate)) if (!empty($enddate))
$sql .= " AND f.datef <= '".$db->idate($enddate)."'"; $sql .= " AND f.datef <= '".$db->idate($enddate)."'";
$sql .= " AND d.buy_price_ht IS NOT NULL"; $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 .= " 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"; 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"; else $sql .= " GROUP BY p.label, p.rowid, p.fk_product_type, p.ref, p.entity";
$sql .= $db->order($sortfield, $sortorder); $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 (!$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"; if (!empty($socid)) $sql .= " AND f.fk_soc = $socid";
$sql .= " AND d.buy_price_ht IS NOT NULL"; $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 .= " 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"; if (!$user->rights->societe->client->voir && !$socid) $sql .= ", sc.fk_soc, sc.fk_user";
$sql .= $db->order($sortfield, $sortorder); $sql .= $db->order($sortfield, $sortorder);

View File

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