From 4d839eea60310811254b0dcf708a7259d55b2822 Mon Sep 17 00:00:00 2001 From: fappels Date: Mon, 26 Oct 2015 20:33:42 +0100 Subject: [PATCH 1/2] Fix #2591 Margin is incorrect used with POS if buy price not defined, define buyprice as configured in margin admin. If 'Force buying price if null' is off, marge will be equal to suggested default.(min supplier price or pmp) Updated all classes reading 'Force buying price if null' setting. --- .../class/askpricesupplier.class.php | 32 +++++++--- htdocs/comm/propal/class/propal.class.php | 55 ++++++++-------- htdocs/commande/class/commande.class.php | 52 +++++++--------- htdocs/compta/facture/class/facture.class.php | 49 +++++++-------- htdocs/contrat/class/contrat.class.php | 47 ++++++++++---- htdocs/core/class/commonobject.class.php | 62 +++++++++++++++++++ htdocs/langs/en_US/margins.lang | 2 +- 7 files changed, 193 insertions(+), 106 deletions(-) diff --git a/htdocs/comm/askpricesupplier/class/askpricesupplier.class.php b/htdocs/comm/askpricesupplier/class/askpricesupplier.class.php index 26d412e87ea..2f563a17b1b 100644 --- a/htdocs/comm/askpricesupplier/class/askpricesupplier.class.php +++ b/htdocs/comm/askpricesupplier/class/askpricesupplier.class.php @@ -2649,11 +2649,18 @@ class AskPriceSupplierLine extends CommonObject if (empty($this->pa_ht)) $this->pa_ht=0; - // si prix d'achat non renseigne et utilise pour calcul des marges alors prix achat = prix vente - if ($this->pa_ht == 0) { - if ($this->subprice > 0 && (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 1)) - $this->pa_ht = $this->subprice * (1 - $this->remise_percent / 100); - } + // if buy price not defined, define buyprice as configured in margin admin + if ($this->pa_ht == 0) + { + if (($result = $this->defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product)) < 0) + { + return $result; + } + else + { + $this->pa_ht = $result; + } + } // Check parameters if ($this->product_type < 0) return -1; @@ -2817,10 +2824,17 @@ class AskPriceSupplierLine extends CommonObject if (empty($this->pa_ht)) $this->pa_ht=0; - // si prix d'achat non renseigne et utilise pour calcul des marges alors prix achat = prix vente - if ($this->pa_ht == 0) { - if ($this->subprice > 0 && (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 1)) - $this->pa_ht = $this->subprice * (1 - $this->remise_percent / 100); + // if buy price not defined, define buyprice as configured in margin admin + if ($this->pa_ht == 0) + { + if (($result = $this->defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product)) < 0) + { + return $result; + } + else + { + $this->pa_ht = $result; + } } $this->db->begin(); diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index 4d632a84c54..8d4c91f097d 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -496,17 +496,7 @@ class Propal extends CommonObject $this->line->date_start=$date_start; $this->line->date_end=$date_end; - - // infos marge - if (!empty($fk_product) && empty($fk_fournprice) && empty($pa_ht)) { - // by external module, take lowest buying price - include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php'; - $productFournisseur = new ProductFournisseur($this->db); - $productFournisseur->find_min_price_product_fournisseur($fk_product); - $this->line->fk_fournprice = $productFournisseur->product_fourn_price_id; - } else { - $this->line->fk_fournprice = $fk_fournprice; - } + $this->line->fk_fournprice = $fk_fournprice; $this->line->pa_ht = $pa_ht; // Mise en option de la ligne @@ -660,16 +650,7 @@ class Propal extends CommonObject $this->line->skip_update_total = $skip_update_total; $this->line->fk_unit = $fk_unit; - // infos marge - if (!empty($fk_product) && empty($fk_fournprice) && empty($pa_ht)) { - // by external module, take lowest buying price - include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php'; - $productFournisseur = new ProductFournisseur($this->db); - $productFournisseur->find_min_price_product_fournisseur($fk_product); - $this->line->fk_fournprice = $productFournisseur->product_fourn_price_id; - } else { - $this->line->fk_fournprice = $fk_fournprice; - } + $this->line->fk_fournprice = $fk_fournprice; $this->line->pa_ht = $pa_ht; $this->line->date_start=$date_start; @@ -3124,11 +3105,18 @@ class PropaleLigne extends CommonObjectLine if (empty($this->pa_ht)) $this->pa_ht=0; - // si prix d'achat non renseigne et utilise pour calcul des marges alors prix achat = prix vente - if ($this->pa_ht == 0) { - if ($this->subprice > 0 && (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 1)) - $this->pa_ht = $this->subprice * (1 - $this->remise_percent / 100); - } + // if buy price not defined, define buyprice as configured in margin admin + if ($this->pa_ht == 0) + { + if (($result = $this->defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product)) < 0) + { + return $result; + } + else + { + $this->pa_ht = $result; + } + } // Check parameters if ($this->product_type < 0) return -1; @@ -3296,10 +3284,17 @@ class PropaleLigne extends CommonObjectLine if (empty($this->pa_ht)) $this->pa_ht=0; - // si prix d'achat non renseigne et utilise pour calcul des marges alors prix achat = prix vente - if ($this->pa_ht == 0) { - if ($this->subprice > 0 && (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 1)) - $this->pa_ht = $this->subprice * (1 - $this->remise_percent / 100); + // if buy price not defined, define buyprice as configured in margin admin + if ($this->pa_ht == 0) + { + if (($result = $this->defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product)) < 0) + { + return $result; + } + else + { + $this->pa_ht = $result; + } } $this->db->begin(); diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index d43314a8816..e3926603f86 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -1281,16 +1281,7 @@ class Commande extends CommonOrder $this->line->date_start=$date_start; $this->line->date_end=$date_end; - // infos marge - if (!empty($fk_product) && empty($fk_fournprice) && empty($pa_ht)) { - // by external module, take lowest buying price - include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php'; - $productFournisseur = new ProductFournisseur($this->db); - $productFournisseur->find_min_price_product_fournisseur($fk_product); - $this->line->fk_fournprice = $productFournisseur->product_fourn_price_id; - } else { - $this->line->fk_fournprice = $fk_fournprice; - } + $this->line->fk_fournprice = $fk_fournprice; $this->line->pa_ht = $pa_ht; // TODO Ne plus utiliser @@ -2509,16 +2500,7 @@ class Commande extends CommonOrder $this->line->skip_update_total=$skip_update_total; $this->line->fk_unit=$fk_unit; - // infos marge - if (!empty($fk_product) && empty($fk_fournprice) && empty($pa_ht)) { - //by external module, take lowest buying price - include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php'; - $productFournisseur = new ProductFournisseur($this->db); - $productFournisseur->find_min_price_product_fournisseur($fk_product); - $this->line->fk_fournprice = $productFournisseur->product_fourn_price_id; - } else { - $this->line->fk_fournprice = $fk_fournprice; - } + $this->line->fk_fournprice = $fk_fournprice; $this->line->pa_ht = $pa_ht; // TODO deprecated @@ -3550,10 +3532,17 @@ class OrderLine extends CommonOrderLine if (empty($this->pa_ht)) $this->pa_ht=0; - // si prix d'achat non renseigne et utilise pour calcul des marges alors prix achat = prix vente - if ($this->pa_ht == 0) { - if ($this->subprice > 0 && (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 1)) - $this->pa_ht = $this->subprice * (1 - $this->remise_percent / 100); + // if buy price not defined, define buyprice as configured in margin admin + if ($this->pa_ht == 0) + { + if (($result = $this->defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product)) < 0) + { + return $result; + } + else + { + $this->pa_ht = $result; + } } // Check parameters @@ -3677,10 +3666,17 @@ class OrderLine extends CommonOrderLine if (empty($this->fk_parent_line)) $this->fk_parent_line=0; if (empty($this->pa_ht)) $this->pa_ht=0; - // si prix d'achat non renseigné et utilisé pour calcul des marges alors prix achat = prix vente - if ($this->pa_ht == 0) { - if ($this->subprice > 0 && (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 1)) - $this->pa_ht = $this->subprice * (1 - $this->remise_percent / 100); + // if buy price not defined, define buyprice as configured in margin admin + if ($this->pa_ht == 0) + { + if (($result = $this->defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product)) < 0) + { + return $result; + } + else + { + $this->pa_ht = $result; + } } $this->db->begin(); diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index bd3e2dac6f0..bc286cd2a59 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -2361,16 +2361,7 @@ class Facture extends CommonInvoice $this->line->situation_percent = $situation_percent; $this->line->fk_unit = $fk_unit; - // infos marge - if (!empty($fk_product) && empty($fk_fournprice) && empty($pa_ht)) { - // POS or external module, take lowest buying price - include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php'; - $productFournisseur = new ProductFournisseur($this->db); - $productFournisseur->find_min_price_product_fournisseur($fk_product); - $this->line->fk_fournprice = $productFournisseur->product_fourn_price_id; - } else { - $this->line->fk_fournprice = $fk_fournprice; - } + $this->line->fk_fournprice = $fk_fournprice; $this->line->pa_ht = $pa_ht; if (is_array($array_options) && count($array_options)>0) { @@ -3883,10 +3874,17 @@ class FactureLigne extends CommonInvoiceLine if (empty($this->pa_ht)) $this->pa_ht=0; - // si prix d'achat non renseigne et utilise pour calcul des marges alors prix achat = prix vente - if ($this->pa_ht == 0) { - if ($this->subprice > 0 && (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 1)) - $this->pa_ht = $this->subprice * (1 - $this->remise_percent / 100); + // if buy price not defined, define buyprice as configured in margin admin + if ($this->pa_ht == 0) + { + if (($result = $this->defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product)) < 0) + { + return $result; + } + else + { + $this->pa_ht = $result; + } } // Check parameters @@ -3906,14 +3904,6 @@ class FactureLigne extends CommonInvoiceLine } } - // POS or by external module, take lowest buying price - if (!empty($this->fk_product) && empty($this->fk_fournprice) && empty($this->pa_ht)) { - include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php'; - $productFournisseur = new ProductFournisseur($this->db); - $productFournisseur->find_min_price_product_fournisseur($this->fk_product); - $this->fk_fournprice = $productFournisseur->product_fourn_price_id; - } - $this->db->begin(); // Insertion dans base de la ligne @@ -4081,10 +4071,17 @@ class FactureLigne extends CommonInvoiceLine if (empty($this->pa_ht)) $this->pa_ht=0; - // si prix d'achat non renseigne et utilise pour calcul des marges alors prix achat = prix vente - if ($this->pa_ht == 0) { - if ($this->subprice > 0 && (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 1)) - $this->pa_ht = $this->subprice * (1 - $this->remise_percent / 100); + // if buy price not defined, define buyprice as configured in margin admin + if ($this->pa_ht == 0) + { + if (($result = $this->defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product)) < 0) + { + return $result; + } + else + { + $this->pa_ht = $result; + } } $this->db->begin(); diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index 1d2bd9f4181..e38bb254f79 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -1283,10 +1283,18 @@ class Contrat extends CommonObject if (empty($pa_ht)) $pa_ht=0; - // si prix d'achat non renseigne et utilise pour calcul des marges alors prix achat = prix vente - if ($pa_ht == 0) { - if ($pu_ht > 0 && (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 1)) - $pa_ht = $pu_ht * (1 - $remise_percent / 100); + + // if buy price not defined, define buyprice as configured in margin admin + if ($this->pa_ht == 0) + { + if (($result = $this->defineBuyPrice($pu_ht, $remise_percent, $fk_product)) < 0) + { + return $result; + } + else + { + $pa_ht = $result; + } } // Insertion dans la base @@ -1456,10 +1464,17 @@ class Contrat extends CommonObject if (empty($pa_ht)) $pa_ht=0; - // si prix d'achat non renseigne et utilise pour calcul des marges alors prix achat = prix vente - if ($pa_ht == 0) { - if ($pu > 0 && (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 1)) - $pa_ht = $pu * (1 - $remise_percent / 100); + // if buy price not defined, define buyprice as configured in margin admin + if ($this->pa_ht == 0) + { + if (($result = $this->defineBuyPrice($pu_ht, $remise_percent)) < 0) + { + return $result; + } + else + { + $pa_ht = $result; + } } $sql = "UPDATE ".MAIN_DB_PREFIX."contratdet set description='".$this->db->escape($desc)."'"; @@ -2481,12 +2496,20 @@ class ContratLigne extends CommonObjectLine if (empty($this->pa_ht)) $this->pa_ht=0; - // si prix d'achat non renseigné et utilisé pour calcul des marges alors prix achat = prix vente - if ($this->pa_ht == 0) { - if ($this->subprice > 0 && (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 1)) - $this->pa_ht = $this->subprice * (1 - $this->remise_percent / 100); + // if buy price not defined, define buyprice as configured in margin admin + if ($this->pa_ht == 0) + { + if (($result = $this->defineBuyPrice($this->subprice, $this->remise_percent, $this->fk_product)) < 0) + { + return $result; + } + else + { + $this->pa_ht = $result; + } } + $this->db->begin(); // Update request diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index d5dac206e15..2aacad9a7ff 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -4176,4 +4176,66 @@ abstract class CommonObject return true; } + + /** + * define buy price if not defined + * set buy price = sell price if ForceBuyingPriceIfNull configured, + * else if calculation MARGIN_TYPE = 'pmp' and pmp is calculated, set pmp as buyprice + * else set min buy price as buy price + * + * @param float $unitPrice product unit price + * @param float $discountPercent line discount percent + * @param int $fk_product product id + * + * @return float <0 if ko, buyprice if ok + */ + public function defineBuyPrice($unitPrice = 0, $discountPercent = 0, $fk_product = 0) + { + global $conf; + + $buyPrice = 0; + + if (($unitPrice > 0) && (isset($conf->global->ForceBuyingPriceIfNull) && $conf->global->ForceBuyingPriceIfNull == 1)) + { + $buyPrice = $unitPrice * (1 - $discountPercent / 100); + } + else + { + require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; + // Get PMP + if (! empty($fk_product)) + { + if (isset($conf->global->MARGIN_TYPE) && $conf->global->MARGIN_TYPE == 'pmp') + { + $product = new Product($this->db); + $result = $product->fetch($fk_product); + if ($result <= 0) + { + $this->error='ErrorProductIdDoesNotExists'; + return -1; + } + if (($product->pmp > 0)) + { + $buyPrice = $product->pmp; + } + // TODO add option to set PMP of product + } + else if (isset($conf->global->MARGIN_TYPE) && $conf->global->MARGIN_TYPE == '1') + { + include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php'; + $productFournisseur = new ProductFournisseur($this->db); + if (($result = $productFournisseur->find_min_price_product_fournisseur($fk_product)) > 0) + { + $buyPrice = $productFournisseur->fourn_price; + } + else + { + $this->error = $productFournisseur->error; + return -1; + } + } + } + } + return $buyPrice; + } } diff --git a/htdocs/langs/en_US/margins.lang b/htdocs/langs/en_US/margins.lang index eb77ca9fe4c..9aeaf8d60e6 100644 --- a/htdocs/langs/en_US/margins.lang +++ b/htdocs/langs/en_US/margins.lang @@ -24,7 +24,7 @@ StartDate=Start date EndDate=End date Launch=Start ForceBuyingPriceIfNull=Force buying price if null -ForceBuyingPriceIfNullDetails=if "ON", margin will be zero on line (buying price = selling price), otherwise ("OFF"), marge will be equal to selling price (buying price = 0) +ForceBuyingPriceIfNullDetails=if "ON", margin will be zero on line (buying price = selling price), otherwise ("OFF"), marge will be equal to suggested default. MARGIN_METHODE_FOR_DISCOUNT=Margin method for global discounts UseDiscountAsProduct=As a product UseDiscountAsService=As a service From 8992cfaeb437cd26178906e07af2674c0d2297ca Mon Sep 17 00:00:00 2001 From: fappels Date: Tue, 27 Oct 2015 15:50:55 +0100 Subject: [PATCH 2/2] move require_once --- htdocs/core/class/commonobject.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 2aacad9a7ff..dbc9686002a 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -4201,12 +4201,12 @@ abstract class CommonObject } else { - require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; // Get PMP if (! empty($fk_product)) { if (isset($conf->global->MARGIN_TYPE) && $conf->global->MARGIN_TYPE == 'pmp') { + require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; $product = new Product($this->db); $result = $product->fetch($fk_product); if ($result <= 0) @@ -4222,7 +4222,7 @@ abstract class CommonObject } else if (isset($conf->global->MARGIN_TYPE) && $conf->global->MARGIN_TYPE == '1') { - include_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php'; + require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.product.class.php'; $productFournisseur = new ProductFournisseur($this->db); if (($result = $productFournisseur->find_min_price_product_fournisseur($fk_product)) > 0) {