diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index cb7d0ce6e6f..f8c57d7cc94 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -1126,7 +1126,7 @@ class CommandeFournisseur extends CommonOrder // insert products details into database for ($i=0;$i<$num;$i++) { - $result = $this->addline( + $result = $this->addline( // This include test on qty if option SUPPLIERORDER_WITH_NOPRICEDEFINED is not set $this->lines[$i]->desc, $this->lines[$i]->subprice, $this->lines[$i]->qty, @@ -1306,11 +1306,11 @@ class CommandeFournisseur extends CommonOrder */ function addline($desc, $pu_ht, $qty, $txtva, $txlocaltax1=0.0, $txlocaltax2=0.0, $fk_product=0, $fk_prod_fourn_price=0, $fourn_ref='', $remise_percent=0.0, $price_base_type='HT', $pu_ttc=0.0, $type=0, $info_bits=0, $notrigger=false, $date_start=null, $date_end=null, $array_options=0, $fk_unit=null) { - global $langs,$mysoc, $conf; + global $langs,$mysoc,$conf; $error = 0; - dol_syslog(get_class($this)."::addline $desc, $pu_ht, $qty, $txtva, $txlocaltax1, $txlocaltax2. $fk_product, $fk_prod_fourn_price, $fourn_ref, $remise_percent, $price_base_type, $pu_ttc, $type, $fk_unit"); + dol_syslog(get_class($this)."::addline $desc, $pu_ht, $qty, $txtva, $txlocaltax1, $txlocaltax2, $fk_product, $fk_prod_fourn_price, $fourn_ref, $remise_percent, $price_base_type, $pu_ttc, $type, $fk_unit"); include_once DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php'; // Clean parameters @@ -1350,40 +1350,45 @@ class CommandeFournisseur extends CommonOrder { $this->db->begin(); - if ($fk_prod_fourn_price > 0) + if ($fk_product > 0) { - $prod = new Product($this->db, $fk_product); - if ($prod->fetch($fk_product) > 0) + if (empty($conf->global->SUPPLIERORDER_WITH_NOPRICEDEFINED)) { - $result=$prod->get_buyprice($fk_prod_fourn_price,$qty,$fk_product,$fourn_ref); - if ($result > 0) + // Check quantity is enough + dol_syslog(get_class($this)."::addline we check supplier prices fk_product=".$fk_product." fk_prod_fourn_price=".$fk_prod_fourn_price." qty=".$qty." fourn_ref=".$fourn_ref); + $prod = new Product($this->db, $fk_product); + if ($prod->fetch($fk_product) > 0) { - $label = $prod->libelle; - $pu = $prod->fourn_pu; - $ref = $prod->ref_fourn; - $product_type = $prod->type; + $result=$prod->get_buyprice($fk_prod_fourn_price, $qty, $fk_product, $fourn_ref); // Search on couple $fk_prod_fourn_price/$qty first, then on triplet $qty/$fk_product/$fourn_ref + if ($result > 0) + { + $label = $prod->libelle; + $pu = $prod->fourn_pu; + $ref = $prod->ref_fourn; + $product_type = $prod->type; + } + if ($result == 0 || $result == -1) + { + $langs->load("errors"); + $this->error = "Ref " . $prod->ref . " " . $langs->trans("ErrorQtyTooLowForThisSupplier"); + $this->db->rollback(); + dol_syslog(get_class($this)."::addline result=".$result." - ".$this->error, LOG_DEBUG); + return -1; + } + if ($result < -1) + { + $this->error=$prod->error; + $this->db->rollback(); + dol_syslog(get_class($this)."::addline result=".$result." - ".$this->error, LOG_ERR); + return -1; + } } - if ($result == 0 || $result == -1) - { - $langs->load("errors"); - $this->error = "Ref " . $prod->ref . " " . $langs->trans("ErrorQtyTooLowForThisSupplier"); - $this->db->rollback(); - dol_syslog(get_class($this)."::addline result=".$result." - ".$this->error, LOG_DEBUG); - return -1; - } - if ($result < -1) - { + else + { $this->error=$prod->error; - $this->db->rollback(); - dol_syslog(get_class($this)."::addline result=".$result." - ".$this->error, LOG_ERR); return -1; } } - else - { - $this->error=$prod->error; - return -1; - } } else { @@ -1449,7 +1454,6 @@ class CommandeFournisseur extends CommonOrder $sql.= ", ".$multicurrency_total_ttc; $sql.= ")"; - dol_syslog(get_class($this)."::addline", LOG_DEBUG); $resql=$this->db->query($sql); //print $sql; if ($resql) diff --git a/htdocs/fourn/class/fournisseur.product.class.php b/htdocs/fourn/class/fournisseur.product.class.php index 48896689dce..05024f9991a 100644 --- a/htdocs/fourn/class/fournisseur.product.class.php +++ b/htdocs/fourn/class/fournisseur.product.class.php @@ -216,7 +216,7 @@ class ProductFournisseur extends Product $this->db->begin(); - if ($this->product_fourn_price_id) + if ($this->product_fourn_price_id > 0) { $sql = "UPDATE ".MAIN_DB_PREFIX."product_fournisseur_price"; $sql.= " SET fk_user = " . $user->id." ,"; @@ -237,7 +237,7 @@ class ProductFournisseur extends Product $sql.= " WHERE rowid = ".$this->product_fourn_price_id; // TODO Add price_base_type and price_ttc - dol_syslog(get_class($this).'::update_buyprice', LOG_DEBUG); + dol_syslog(get_class($this).'::update_buyprice update knowing id of line = product_fourn_price_id = '.$this->product_fourn_price_id, LOG_DEBUG); $resql = $this->db->query($sql); if ($resql) { @@ -249,7 +249,7 @@ class ProductFournisseur extends Product if (empty($error)) { $this->db->commit(); - return 0; + return $this->product_fourn_price_id; } else { @@ -267,94 +267,88 @@ class ProductFournisseur extends Product else { - // Delete price for this quantity - $sql = "DELETE FROM ".MAIN_DB_PREFIX."product_fournisseur_price"; - $sql.= " WHERE fk_soc = ".$fourn->id." AND ref_fourn = '".$this->db->escape($ref_fourn)."' AND quantity = ".$qty." AND entity = ".$conf->entity; - dol_syslog(get_class($this).'::update_buyprice', LOG_DEBUG); - $resql=$this->db->query($sql); - if ($resql) - { - // Add price for this quantity to supplier - $sql = "INSERT INTO ".MAIN_DB_PREFIX."product_fournisseur_price("; - $sql.= "datec, fk_product, fk_soc, ref_fourn, fk_user, price, quantity, remise_percent, remise, unitprice, tva_tx, charges, unitcharges, fk_availability, info_bits, entity, delivery_time_days,supplier_reputation)"; - $sql.= " values('".$this->db->idate($now)."',"; - $sql.= " ".$this->id.","; - $sql.= " ".$fourn->id.","; - $sql.= " '".$this->db->escape($ref_fourn)."',"; - $sql.= " ".$user->id.","; - $sql.= " ".$buyprice.","; - $sql.= " ".$qty.","; - $sql.= " ".$remise_percent.","; - $sql.= " ".$remise.","; - $sql.= " ".$unitBuyPrice.","; - $sql.= " ".$tva_tx.","; - $sql.= " ".$charges.","; - $sql.= " ".$unitCharges.","; - $sql.= " ".$availability.","; - $sql.= " ".$newnpr.","; - $sql.= $conf->entity.","; - $sql.= $delivery_time_days.","; - $sql.= (empty($supplier_reputation) ? 'NULL' : "'".$this->db->escape($supplier_reputation)."'"); - $sql.=")"; - - dol_syslog(get_class($this)."::update_buyprice", LOG_DEBUG); - if (! $this->db->query($sql)) - { - $error++; - } - - if (! $error && !empty($conf->global->PRODUCT_PRICE_SUPPLIER_NO_LOG)) - { - // Add record into log table - $sql = "INSERT INTO ".MAIN_DB_PREFIX."product_fournisseur_price_log("; - $sql.= "datec, fk_product_fournisseur,fk_user,price,quantity)"; - $sql.= "values('".$this->db->idate($now)."',"; - $sql.= " ".$this->product_fourn_id.","; - $sql.= " ".$user->id.","; - $sql.= " ".price2num($buyprice).","; - $sql.= " ".$qty; - $sql.=")"; - - $resql=$this->db->query($sql); - if (! $resql) - { - $error++; - } - } - - - if (! $error) - { - // Call trigger - $result=$this->call_trigger('SUPPLIER_PRODUCT_BUYPRICE_CREATE',$user); - if ($result < 0) $error++; + dol_syslog(get_class($this) . '::update_buyprice without knowing id of line, so we delete from company, quantity and supplier_ref and insert again', LOG_DEBUG); + + // Delete price for this quantity + $sql = "DELETE FROM " . MAIN_DB_PREFIX . "product_fournisseur_price"; + $sql .= " WHERE fk_soc = " . $fourn->id . " AND ref_fourn = '" . $this->db->escape($ref_fourn) . "' AND quantity = " . $qty . " AND entity = " . $conf->entity; + $resql = $this->db->query($sql); + if ($resql) { + // Add price for this quantity to supplier + $sql = "INSERT INTO " . MAIN_DB_PREFIX . "product_fournisseur_price("; + $sql .= "datec, fk_product, fk_soc, ref_fourn, fk_user, price, quantity, remise_percent, remise, unitprice, tva_tx, charges, unitcharges, fk_availability, info_bits, entity, delivery_time_days,supplier_reputation)"; + $sql .= " values('" . $this->db->idate($now) . "',"; + $sql .= " " . $this->id . ","; + $sql .= " " . $fourn->id . ","; + $sql .= " '" . $this->db->escape($ref_fourn) . "',"; + $sql .= " " . $user->id . ","; + $sql .= " " . $buyprice . ","; + $sql .= " " . $qty . ","; + $sql .= " " . $remise_percent . ","; + $sql .= " " . $remise . ","; + $sql .= " " . $unitBuyPrice . ","; + $sql .= " " . $tva_tx . ","; + $sql .= " " . $charges . ","; + $sql .= " " . $unitCharges . ","; + $sql .= " " . $availability . ","; + $sql .= " " . $newnpr . ","; + $sql .= $conf->entity . ","; + $sql .= $delivery_time_days . ","; + $sql .= (empty($supplier_reputation) ? 'NULL' : "'" . $this->db->escape($supplier_reputation) . "'"); + $sql .= ")"; + + $idinserted = 0; + + $resql = $this->db->query($sql); + if ($resql) { + $idinserted = $this->db->last_insert_id(MAIN_DB_PREFIX . "product_fournisseur_price"); + } + else { + $error++; + } + + if (! $error && ! empty($conf->global->PRODUCT_PRICE_SUPPLIER_NO_LOG)) { + // Add record into log table + $sql = "INSERT INTO " . MAIN_DB_PREFIX . "product_fournisseur_price_log("; + $sql .= "datec, fk_product_fournisseur,fk_user,price,quantity)"; + $sql .= "values('" . $this->db->idate($now) . "',"; + $sql .= " " . $this->product_fourn_id . ","; + $sql .= " " . $user->id . ","; + $sql .= " " . price2num($buyprice) . ","; + $sql .= " " . $qty; + $sql .= ")"; + + $resql = $this->db->query($sql); + if (! $resql) { + $error++; + } + } + + if (! $error) { + // Call trigger + $result = $this->call_trigger('SUPPLIER_PRODUCT_BUYPRICE_CREATE', $user); + if ($result < 0) + $error++; // End call triggers - - if (empty($error)) - { - $this->db->commit(); - return 0; - } - else - { - $this->db->rollback(); - return -1; - } - } - else - { - $this->error=$this->db->error()." sql=".$sql; - $this->db->rollback(); - return -2; - } - } - else - { - $this->error=$this->db->error()." sql=".$sql; - $this->db->rollback(); - return -1; - } - } + + if (empty($error)) { + $this->db->commit(); + return $idinserted; + } else { + $this->db->rollback(); + return -1; + } + } else { + $this->error = $this->db->lasterror() . " sql=" . $sql; + $this->db->rollback(); + return -2; + } + } else { + $this->error = $this->db->lasterror() . " sql=" . $sql; + $this->db->rollback(); + return - 1; + } + } } /** diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 98684d5f980..d242a343ce9 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -1315,21 +1315,21 @@ class Product extends CommonObject * @param double $qty Quantity asked * @param int $product_id Filter on a particular product id * @param string $fourn_ref Filter on a supplier ref - * @return int <-1 if KO, -1 if qty not enough, 0 si ok mais rien trouve, id_product si ok et trouve. May also initialize some properties like (->ref_supplier, buyprice, fourn_pu, vatrate_supplier...) + * @return int <-1 if KO, -1 if qty not enough, 0 if OK but nothing found, id_product if OK and found. May also initialize some properties like (->ref_supplier, buyprice, fourn_pu, vatrate_supplier...) */ function get_buyprice($prodfournprice,$qty,$product_id=0,$fourn_ref=0) { global $conf; $result = 0; - // We do select by searching with qty and prodfournprice + // We do a first seach with a select by searching with couple prodfournprice and qty only (later we will search on triplet qty/product_id/fourn_ref) $sql = "SELECT pfp.rowid, pfp.price as price, pfp.quantity as quantity,"; $sql.= " pfp.fk_product, pfp.ref_fourn, pfp.fk_soc, pfp.tva_tx, pfp.fk_supplier_price_expression"; $sql.= " FROM ".MAIN_DB_PREFIX."product_fournisseur_price as pfp"; $sql.= " WHERE pfp.rowid = ".$prodfournprice; if ($qty) $sql.= " AND pfp.quantity <= ".$qty; - dol_syslog(get_class($this)."::get_buyprice", LOG_DEBUG); + dol_syslog(get_class($this)."::get_buyprice first search by prodfournprice/qty", LOG_DEBUG); $resql = $this->db->query($sql); if ($resql) { @@ -1358,9 +1358,9 @@ class Product extends CommonObject $result=$obj->fk_product; return $result; } - else + else // If not found { - // We do same select again but searching with qty, ref and id product + // We do a second search by doing a select again but searching with qty, ref and id product $sql = "SELECT pfp.rowid, pfp.price as price, pfp.quantity as quantity, pfp.fk_soc,"; $sql.= " pfp.fk_product, pfp.ref_fourn as ref_supplier, pfp.tva_tx, pfp.fk_supplier_price_expression"; $sql.= " FROM ".MAIN_DB_PREFIX."product_fournisseur_price as pfp"; @@ -1370,7 +1370,7 @@ class Product extends CommonObject $sql.= " ORDER BY pfp.quantity DESC"; $sql.= " LIMIT 1"; - dol_syslog(get_class($this)."::get_buyprice", LOG_DEBUG); + dol_syslog(get_class($this)."::get_buyprice second search from qty/ref/product_id", LOG_DEBUG); $resql = $this->db->query($sql); if ($resql) { @@ -2656,6 +2656,8 @@ class Product extends CommonObject $now=dol_now(); + dol_syslog(get_class($this)."::add_fournisseur id_fourn = ".$id_fourn." ref_fourn=".$ref_fourn." quantity=".$quantity, LOG_DEBUG); + if ($ref_fourn) { $sql = "SELECT rowid, fk_product"; @@ -2665,7 +2667,6 @@ class Product extends CommonObject $sql.= " AND fk_product != ".$this->id; $sql.= " AND entity = ".$conf->entity; - dol_syslog(get_class($this)."::add_fournisseur", LOG_DEBUG); $resql=$this->db->query($sql); if ($resql) { @@ -2689,7 +2690,6 @@ class Product extends CommonObject $sql.= " AND fk_product = ".$this->id; $sql.= " AND entity = ".$conf->entity; - dol_syslog(get_class($this)."::add_fournisseur", LOG_DEBUG); $resql=$this->db->query($sql); if ($resql) { @@ -2718,7 +2718,6 @@ class Product extends CommonObject $sql.= ", 0"; $sql.= ")"; - dol_syslog(get_class($this)."::add_fournisseur", LOG_DEBUG); if ($this->db->query($sql)) { $this->product_fourn_price_id = $this->db->last_insert_id(MAIN_DB_PREFIX."product_fournisseur_price"); diff --git a/test/phpunit/CommandeFournisseurTest.php b/test/phpunit/CommandeFournisseurTest.php index 67c120a2bb8..03880a56eca 100644 --- a/test/phpunit/CommandeFournisseurTest.php +++ b/test/phpunit/CommandeFournisseurTest.php @@ -145,7 +145,7 @@ class CommandeFournisseurTest extends PHPUnit_Framework_TestCase // Create supplier price $result=$product->add_fournisseur($user, $societe->id, $ref_fourn, $quantity); // This insert record with no value for price. Values are update later with update_buyprice $this->assertGreaterThanOrEqual(1, $result); - $result=$product->update_buyprice($quantity, 10, $user, 'HT', $societe, '', $ref_fourn, $tva_tx, 0, 0); + $result=$product->update_buyprice($quantity, 20, $user, 'HT', $societe, '', $ref_fourn, $tva_tx, 0, 0); $this->assertGreaterThanOrEqual(0, $result); // Create supplier order with a too low quantity