From 3aef39c64d720520774a744b99c76f0eed7ad3c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric?= <35066297+c3do@users.noreply.github.com> Date: Sat, 23 Nov 2019 13:45:58 +0100 Subject: [PATCH 01/15] New can customize the reference of a combination --- .../class/ProductCombination.class.php | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/htdocs/variants/class/ProductCombination.class.php b/htdocs/variants/class/ProductCombination.class.php index 1c09aae62df..6dfa1bf94c5 100644 --- a/htdocs/variants/class/ProductCombination.class.php +++ b/htdocs/variants/class/ProductCombination.class.php @@ -502,9 +502,10 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; * @param bool $price_var_percent Is the price variation a relative variation? * @param bool|float $forced_pricevar If the price variation is forced * @param bool|float $forced_weightvar If the weight variation is forced + * @param bool|string $forced_refvar If the reference is forced * @return int <0 KO, >0 OK */ - public function createProductCombination(User $user, Product $product, array $combinations, array $variations, $price_var_percent = false, $forced_pricevar = false, $forced_weightvar = false) + public function createProductCombination(User $user, Product $product, array $combinations, array $variations, $price_var_percent = false, $forced_pricevar = false, $forced_weightvar = false, $forced_refvar = false) { global $db, $conf; @@ -528,7 +529,11 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; if ($forced_pricevar === false) { $price_impact = 0; } - + + if ($forced_refvar !== false) { + $forced_refvar = trim($forced_refvar); + } + $newcomb = new ProductCombination($db); $existingCombination = $newcomb->fetchByProductCombination2ValuePairs($product->id, $combinations); @@ -572,11 +577,14 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; if ($forced_pricevar === false) { $price_impact += (float) price2num($variations[$currcombattr][$currcombval]['price']); } - - if (isset($conf->global->PRODUIT_ATTRIBUTES_SEPARATOR)) { - $newproduct->ref .= $conf->global->PRODUIT_ATTRIBUTES_SEPARATOR . $prodattrval->ref; + if (empty($forced_refvar)) { + if (isset($conf->global->PRODUIT_ATTRIBUTES_SEPARATOR)) { + $newproduct->ref .= $conf->global->PRODUIT_ATTRIBUTES_SEPARATOR . $prodattrval->ref; + } else { + $newproduct->ref .= '_'.$prodattrval->ref; + } } else { - $newproduct->ref .= '_'.$prodattrval->ref; + $newproduct->ref = $forced_refvar; } //The first one should not contain a linebreak From 76fd79455901f684b9d4511612075d5a7c561be0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric?= <35066297+c3do@users.noreply.github.com> Date: Sat, 23 Nov 2019 14:04:00 +0100 Subject: [PATCH 02/15] API New can customize reference when addvariant --- htdocs/product/class/api_products.class.php | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index 37c950e9956..b0ed902ffb3 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -1328,11 +1328,12 @@ class Products extends DolibarrApi * * "features" is a list of attributes pairs id_attribute=>id_value. Example: array(id_color=>id_Blue, id_size=>id_small, id_option=>id_val_a, ...) * - * @param int $id ID of Product - * @param float $weight_impact Weight impact of variant - * @param float $price_impact Price impact of variant - * @param bool $price_impact_is_percent Price impact in percent (true or false) - * @param array $features List of attributes pairs id_attribute->id_value. Example: array(id_color=>id_Blue, id_size=>id_small, id_option=>id_val_a, ...) + * @param int $id ID of Product + * @param float $weight_impact Weight impact of variant + * @param float $price_impact Price impact of variant + * @param bool $price_impact_is_percent Price impact in percent (true or false) + * @param array $features List of attributes pairs id_attribute->id_value. Example: array(id_color=>id_Blue, id_size=>id_small, id_option=>id_val_a, ...) + * @param bool|string $reference Customized reference of variant * @return int * * @throws RestException @@ -1341,7 +1342,7 @@ class Products extends DolibarrApi * * @url POST {id}/variants */ - public function addVariant($id, $weight_impact, $price_impact, $price_impact_is_percent, $features) + public function addVariant($id, $weight_impact, $price_impact, $price_impact_is_percent, $features, $reference = false) { if(! DolibarrApiAccess::$user->rights->produit->creer) { throw new RestException(401); @@ -1373,7 +1374,7 @@ class Products extends DolibarrApi $prodcomb = new ProductCombination($this->db); if (! $prodcomb->fetchByProductCombination2ValuePairs($id, $features)) { - $result = $prodcomb->createProductCombination(DolibarrApiAccess::$user, $this->product, $features, array(), $price_impact_is_percent, $price_impact, $weight_impact); + $result = $prodcomb->createProductCombination(DolibarrApiAccess::$user, $this->product, $features, array(), $price_impact_is_percent, $price_impact, $weight_impact, $reference); if ($result > 0) { return $result; From 6484ba10c52ac634c04f54fb24bae4243a470026 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric?= <35066297+c3do@users.noreply.github.com> Date: Sat, 23 Nov 2019 16:08:35 +0100 Subject: [PATCH 03/15] remove unecessary code already done by ::createProductCombination --- htdocs/product/class/api_products.class.php | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index b0ed902ffb3..40d50357dc2 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -1372,18 +1372,13 @@ class Products extends DolibarrApi } $prodcomb = new ProductCombination($this->db); - if (! $prodcomb->fetchByProductCombination2ValuePairs($id, $features)) - { - $result = $prodcomb->createProductCombination(DolibarrApiAccess::$user, $this->product, $features, array(), $price_impact_is_percent, $price_impact, $weight_impact, $reference); - if ($result > 0) - { - return $result; - } else { - throw new RestException(500, "Error creating new product variant"); - } - } else { - return $prodcomb->id; - } + $result = $prodcomb->createProductCombination(DolibarrApiAccess::$user, $this->product, $features, array(), $price_impact_is_percent, $price_impact, $weight_impact, $reference); + if ($result > 0) + { + return $result; + } else { + throw new RestException(500, "Error creating new product variant"); + } } /** From 6086ecef864353cb908c905aa790529f8b74388b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric?= <35066297+c3do@users.noreply.github.com> Date: Sat, 23 Nov 2019 16:14:21 +0100 Subject: [PATCH 04/15] Can add already existing product as variant ONLY if the reference is forced --- .../class/ProductCombination.class.php | 147 ++++++++++-------- 1 file changed, 82 insertions(+), 65 deletions(-) diff --git a/htdocs/variants/class/ProductCombination.class.php b/htdocs/variants/class/ProductCombination.class.php index 6dfa1bf94c5..a3646147101 100644 --- a/htdocs/variants/class/ProductCombination.class.php +++ b/htdocs/variants/class/ProductCombination.class.php @@ -514,7 +514,23 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; $db->begin(); - $newproduct = clone $product; + $forced_refvar = trim($forced_refvar); + + if (!empty($forced_refvar) && $forced_refvar != $product->ref) { + $existingProduct = new Product($db); + $result = $existingProduct->fetch('', $forced_refvar); + if ($result > 0) { + $newproduct = $existingProduct; + } else { + $existingProduct = false; + $newproduct = clone $product; + $newproduct->ref = $forced_refvar; + } + } else { + $forced_refvar = false; + $existingProduct = false; + $newproduct = clone $product; + } //Final weight impact $weight_impact = $forced_weightvar; @@ -529,11 +545,7 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; if ($forced_pricevar === false) { $price_impact = 0; } - - if ($forced_refvar !== false) { - $forced_refvar = trim($forced_refvar); - } - + $newcomb = new ProductCombination($db); $existingCombination = $newcomb->fetchByProductCombination2ValuePairs($product->id, $combinations); @@ -541,7 +553,6 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; $newcomb = $existingCombination; } else { $newcomb->fk_product_parent = $product->id; - if ($newcomb->create($user) < 0) { // Create 1 entry into product_attribute_combination (1 entry for all combinations) $db->rollback(); return -1; @@ -577,14 +588,13 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; if ($forced_pricevar === false) { $price_impact += (float) price2num($variations[$currcombattr][$currcombval]['price']); } - if (empty($forced_refvar)) { - if (isset($conf->global->PRODUIT_ATTRIBUTES_SEPARATOR)) { - $newproduct->ref .= $conf->global->PRODUIT_ATTRIBUTES_SEPARATOR . $prodattrval->ref; - } else { - $newproduct->ref .= '_'.$prodattrval->ref; - } - } else { - $newproduct->ref = $forced_refvar; + + if ($forced_refvar === false) { + if (isset($conf->global->PRODUIT_ATTRIBUTES_SEPARATOR)) { + $newproduct->ref .= $conf->global->PRODUIT_ATTRIBUTES_SEPARATOR . $prodattrval->ref; + } else { + $newproduct->ref .= '_'.$prodattrval->ref; + } } //The first one should not contain a linebreak @@ -600,58 +610,65 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; $newproduct->weight += $weight_impact; - //To avoid wrong information in price history log - $newproduct->price = 0; - $newproduct->price_ttc = 0; - $newproduct->price_min = 0; - $newproduct->price_min_ttc = 0; - - // A new variant must use a new barcode (not same product) - $newproduct->barcode = -1; - // Now create the product //print 'Create prod '.$newproduct->ref.'
'."\n"; - $newprodid = $newproduct->create($user); - if ($newprodid < 0) - { - //In case the error is not related with an already existing product - if ($newproduct->error != 'ErrorProductAlreadyExists') { - $this->error[] = $newproduct->error; - $this->errors = $newproduct->errors; - $db->rollback(); - return -1; - } - - /** - * If there is an existing combination, then we update the prices and weight - * Otherwise, we try adding a random number to the ref - */ - - if ($newcomb->fk_product_child) { - $res = $newproduct->fetch($existingCombination->fk_product_child); - } else { - $orig_prod_ref = $newproduct->ref; - $i = 1; - - do { - $newproduct->ref = $orig_prod_ref.$i; - $res = $newproduct->create($user); - - if ($newproduct->error != 'ErrorProductAlreadyExists') { - $this->errors[] = $newproduct->error; - break; - } - - $i++; - } while ($res < 0); - } - - if ($res < 0) { - $db->rollback(); - return -1; - } - - $newproduct->weight += $weight_impact; + if ($existingProduct === false) { + //To avoid wrong information in price history log + $newproduct->price = 0; + $newproduct->price_ttc = 0; + $newproduct->price_min = 0; + $newproduct->price_min_ttc = 0; + + // A new variant must use a new barcode (not same product) + $newproduct->barcode = -1; + $result = $newproduct->create($user); + + if ($result < 0) + { + //In case the error is not related with an already existing product + if ($newproduct->error != 'ErrorProductAlreadyExists') { + $this->error[] = $newproduct->error; + $this->errors = $newproduct->errors; + $db->rollback(); + return -1; + } + + /** + * If there is an existing combination, then we update the prices and weight + * Otherwise, we try adding a random number to the ref + */ + + if ($newcomb->fk_product_child) { + $res = $newproduct->fetch($existingCombination->fk_product_child); + } else { + $orig_prod_ref = $newproduct->ref; + $i = 1; + + do { + $newproduct->ref = $orig_prod_ref.$i; + $res = $newproduct->create($user); + + if ($newproduct->error != 'ErrorProductAlreadyExists') { + $this->errors[] = $newproduct->error; + break; + } + + $i++; + } while ($res < 0); + } + + if ($res < 0) { + $db->rollback(); + return -1; + } + } + } else { + $result = $newproduct->update($newproduct->id, $user); + if ($result < 0) + { + $db->rollback(); + return -1; + } } $newcomb->fk_product_child = $newproduct->id; From 7a3f6c362d52b516165217d4c6847afa6cd8810a Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Sat, 23 Nov 2019 15:23:31 +0000 Subject: [PATCH 05/15] Fixing style errors. --- .../class/ProductCombination.class.php | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/htdocs/variants/class/ProductCombination.class.php b/htdocs/variants/class/ProductCombination.class.php index a3646147101..fc58d338220 100644 --- a/htdocs/variants/class/ProductCombination.class.php +++ b/htdocs/variants/class/ProductCombination.class.php @@ -515,17 +515,17 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; $db->begin(); $forced_refvar = trim($forced_refvar); - + if (!empty($forced_refvar) && $forced_refvar != $product->ref) { - $existingProduct = new Product($db); - $result = $existingProduct->fetch('', $forced_refvar); - if ($result > 0) { - $newproduct = $existingProduct; - } else { - $existingProduct = false; - $newproduct = clone $product; - $newproduct->ref = $forced_refvar; - } + $existingProduct = new Product($db); + $result = $existingProduct->fetch('', $forced_refvar); + if ($result > 0) { + $newproduct = $existingProduct; + } else { + $existingProduct = false; + $newproduct = clone $product; + $newproduct->ref = $forced_refvar; + } } else { $forced_refvar = false; $existingProduct = false; @@ -588,12 +588,12 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; if ($forced_pricevar === false) { $price_impact += (float) price2num($variations[$currcombattr][$currcombval]['price']); } - + if ($forced_refvar === false) { if (isset($conf->global->PRODUIT_ATTRIBUTES_SEPARATOR)) { - $newproduct->ref .= $conf->global->PRODUIT_ATTRIBUTES_SEPARATOR . $prodattrval->ref; + $newproduct->ref .= $conf->global->PRODUIT_ATTRIBUTES_SEPARATOR . $prodattrval->ref; } else { - $newproduct->ref .= '_'.$prodattrval->ref; + $newproduct->ref .= '_'.$prodattrval->ref; } } @@ -618,11 +618,11 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; $newproduct->price_ttc = 0; $newproduct->price_min = 0; $newproduct->price_min_ttc = 0; - + // A new variant must use a new barcode (not same product) $newproduct->barcode = -1; $result = $newproduct->create($user); - + if ($result < 0) { //In case the error is not related with an already existing product @@ -632,31 +632,31 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; $db->rollback(); return -1; } - + /** * If there is an existing combination, then we update the prices and weight * Otherwise, we try adding a random number to the ref */ - + if ($newcomb->fk_product_child) { $res = $newproduct->fetch($existingCombination->fk_product_child); } else { $orig_prod_ref = $newproduct->ref; $i = 1; - + do { $newproduct->ref = $orig_prod_ref.$i; $res = $newproduct->create($user); - + if ($newproduct->error != 'ErrorProductAlreadyExists') { $this->errors[] = $newproduct->error; break; } - + $i++; } while ($res < 0); } - + if ($res < 0) { $db->rollback(); return -1; From 31cfc9cd3586d5a0f5485bc4e4492ff0996d12a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric?= <35066297+c3do@users.noreply.github.com> Date: Sat, 23 Nov 2019 17:04:14 +0100 Subject: [PATCH 06/15] Add field reference in form --- htdocs/variants/combinations.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/htdocs/variants/combinations.php b/htdocs/variants/combinations.php index f8a8b9cc9e5..c2067a28ee1 100644 --- a/htdocs/variants/combinations.php +++ b/htdocs/variants/combinations.php @@ -33,6 +33,7 @@ $ref = GETPOST('ref', 'alpha'); $weight_impact = GETPOST('weight_impact', 'alpha'); $price_impact = GETPOST('price_impact', 'alpha'); $price_impact_percent = (bool) GETPOST('price_impact_percent'); +$reference = GETPOST('reference', 'alpha'); $form = new Form($db); $action = GETPOST('action', 'alpha'); @@ -106,6 +107,10 @@ if ($_POST) { } else { + $reference = trim($reference); + if (empty($reference)) { + $reference = false; + } $weight_impact = price2num($weight_impact); $price_impact = price2num($price_impact); $sanit_features = array(); @@ -141,7 +146,7 @@ if ($_POST) { if (!$prodcomb->fetchByProductCombination2ValuePairs($id, $sanit_features)) { - $result = $prodcomb->createProductCombination($user, $object, $sanit_features, array(), $price_impact_percent, $price_impact, $weight_impact); + $result = $prodcomb->createProductCombination($user, $object, $sanit_features, array(), $price_impact_percent, $price_impact, $weight_impact, $reference); if ($result > 0) { setEventMessages($langs->trans('RecordSaved'), null, 'mesgs'); @@ -587,6 +592,10 @@ if (! empty($id) || ! empty($ref)) + + + + From d647479794f6f7e9b1f4ccc1947efd8d7258afed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric?= <35066297+c3do@users.noreply.github.com> Date: Sat, 23 Nov 2019 17:17:25 +0100 Subject: [PATCH 07/15] Do not delete product automaticaly (unlink only) --- htdocs/variants/combinations.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/htdocs/variants/combinations.php b/htdocs/variants/combinations.php index c2067a28ee1..e3993d02d3b 100644 --- a/htdocs/variants/combinations.php +++ b/htdocs/variants/combinations.php @@ -244,7 +244,7 @@ if ($action === 'confirm_deletecombination') { if ($prodcomb->fetch($valueid) > 0) { $db->begin(); - if ($prodcomb->delete($user) > 0 && $prodstatic->fetch($prodcomb->fk_product_child) > 0 && $prodstatic->delete($user) > 0) { + if ($prodcomb->delete($user) > 0) { $db->commit(); setEventMessages($langs->trans('RecordSaved'), null, 'mesgs'); header('Location: '.dol_buildpath('/variants/combinations.php?id='.$object->id, 2)); From 83de0fa7c19fee857fa9723da6fd6c449da674a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric?= <35066297+c3do@users.noreply.github.com> Date: Sat, 23 Nov 2019 18:03:46 +0100 Subject: [PATCH 08/15] Add the choice to delete the product linked --- htdocs/variants/combinations.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/htdocs/variants/combinations.php b/htdocs/variants/combinations.php index e3993d02d3b..adb2fa8b739 100644 --- a/htdocs/variants/combinations.php +++ b/htdocs/variants/combinations.php @@ -42,6 +42,7 @@ $show_files = GETPOST('show_files', 'int'); $confirm = GETPOST('confirm', 'alpha'); $toselect = GETPOST('toselect', 'array'); $cancel = GETPOST('cancel', 'alpha'); +$delete_product = GETPOST('delete_product', 'alpha'); // Security check $fieldvalue = (!empty($id) ? $id : $ref); @@ -244,7 +245,7 @@ if ($action === 'confirm_deletecombination') { if ($prodcomb->fetch($valueid) > 0) { $db->begin(); - if ($prodcomb->delete($user) > 0) { + if ($prodcomb->delete($user) > 0 && (empty($delete_product) || ($delete_product == 'on' && $prodstatic->fetch($prodcomb->fk_product_child) > 0 && $prodstatic->delete($user) > 0))) { $db->commit(); setEventMessages($langs->trans('RecordSaved'), null, 'mesgs'); header('Location: '.dol_buildpath('/variants/combinations.php?id='.$object->id, 2)); @@ -635,7 +636,7 @@ if (! empty($id) || ! empty($ref)) $langs->trans('Delete'), $langs->trans('ProductCombinationDeleteDialog', $prodstatic->ref), "confirm_deletecombination", - '', + array(array('label'=> $langs->trans('DeleteLinkedProduct'),'type'=> 'checkbox', 'name' => 'delete_product', 'value' => false)), 0, 1 ); From b959e595545d6b434122e52ac6fae05bf52804a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric?= <35066297+c3do@users.noreply.github.com> Date: Sat, 23 Nov 2019 18:09:17 +0100 Subject: [PATCH 09/15] Checkbox label delete child product EN --- htdocs/langs/en_US/products.lang | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/htdocs/langs/en_US/products.lang b/htdocs/langs/en_US/products.lang index 1ca335da637..103f13b7f75 100644 --- a/htdocs/langs/en_US/products.lang +++ b/htdocs/langs/en_US/products.lang @@ -347,4 +347,5 @@ ErrorDestinationProductNotFound=Destination product not found ErrorProductCombinationNotFound=Product variant not found ActionAvailableOnVariantProductOnly=Action only available on the variant of product ProductsPricePerCustomer=Product prices per customers -ProductSupplierExtraFields=Additional Attributes (Supplier Prices) \ No newline at end of file +ProductSupplierExtraFields=Additional Attributes (Supplier Prices) +DeleteLinkedProduct = Delete the child product linked to the combination From 950a32a433ae6f633eaabeb37cc5619bddc470fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric?= <35066297+c3do@users.noreply.github.com> Date: Sat, 23 Nov 2019 18:11:20 +0100 Subject: [PATCH 10/15] Checkbox label delete child product FR --- htdocs/langs/fr_FR/products.lang | 1 + 1 file changed, 1 insertion(+) diff --git a/htdocs/langs/fr_FR/products.lang b/htdocs/langs/fr_FR/products.lang index 0248f6470a9..d5465684736 100644 --- a/htdocs/langs/fr_FR/products.lang +++ b/htdocs/langs/fr_FR/products.lang @@ -347,3 +347,4 @@ ErrorDestinationProductNotFound=Produit destination non trouvé ErrorProductCombinationNotFound=Variante du produit non trouvé ActionAvailableOnVariantProductOnly=Action disponible uniquement sur la variante du produit ProductsPricePerCustomer=Prix produit par clients +DeleteLinkedProduct = Supprimer le produit enfant lié à la variante From 76c5a08242ec496c7d9a2b1ceefc33e1864e284e Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Thu, 28 Nov 2019 12:13:36 +0000 Subject: [PATCH 11/15] Fixing style errors. --- htdocs/product/class/api_products.class.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index 05e4fe3b1c6..8cb710ceab4 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -1373,13 +1373,13 @@ class Products extends DolibarrApi } $prodcomb = new ProductCombination($this->db); - + $result = $prodcomb->createProductCombination(DolibarrApiAccess::$user, $this->product, $features, array(), $price_impact_is_percent, $price_impact, $weight_impact, $reference); if ($result > 0) { - return $result; + return $result; } else { - throw new RestException(500, "Error creating new product variant"); + throw new RestException(500, "Error creating new product variant"); } } From 565a17dc47c6a032f21a42584c4ebda48fcec785 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric?= <35066297+c3do@users.noreply.github.com> Date: Sat, 30 Nov 2019 23:36:23 +0100 Subject: [PATCH 12/15] API New add purchase prices --- htdocs/product/class/api_products.class.php | 67 +++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index 8cb710ceab4..b9d21b481e2 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -631,6 +631,73 @@ class Products extends DolibarrApi 'prices_by_qty_list'=>$this->product->prices_by_qty_list[0] ); } + + /** + * Add purchase prices for a product. + * + * @param int $id ID of Product + * @param float $qty Min quantity for which price is valid + * @param float $buyprice Purchase price for the quantity min + * @param string $price_base_type HT or TTC + * @param int $fourn_id Supplier ID + * @param int $availability Product availability + * @param string $ref_fourn Supplier ref + * @param float $tva_tx New VAT Rate (For example 8.5. Should not be a string) + * @param string $charges costs affering to product + * @param float $remise_percent Discount regarding qty (percent) + * @param float $remise Discount regarding qty (amount) + * @param int $newnpr Set NPR or not + * @param int $delivery_time_days Delay in days for delivery (max). May be '' if not defined. + * @param string $supplier_reputation Reputation with this product to the defined supplier (empty, FAVORITE, DONOTORDER) + * @param array $localtaxes_array Array with localtaxes info array('0'=>type1,'1'=>rate1,'2'=>type2,'3'=>rate2) (loaded by getLocalTaxesFromRate(vatrate, 0, ...) function). + * @param string $newdefaultvatcode Default vat code + * @param float $multicurrency_buyprice Purchase price for the quantity min in currency + * @param string $multicurrency_price_base_type HT or TTC in currency + * @param float $multicurrency_tx Rate currency + * @param string $multicurrency_code Currency code + * @param string $desc_fourn Custom description for product_fourn_price + * @param string $barcode Barcode + * @param int $fk_barcode_type Barcode type + * @return int + * + * @throws RestException + * @throws 401 + * + * @url POST {id}/purchase_prices + */ + public function addPurchasePrice($id, $qty, $buyprice, $price_base_type, $fourn_id, $availability, $ref_fourn, $tva_tx, $charges = 0, $remise_percent = 0, $remise = 0, $newnpr = 0, $delivery_time_days = 0, $supplier_reputation = '', $localtaxes_array = array(), $newdefaultvatcode = '', $multicurrency_buyprice = 0, $multicurrency_price_base_type = 'HT', $multicurrency_tx = 1, $multicurrency_code = '', $desc_fourn = '', $barcode = '', $fk_barcode_type = null) + { + if(! DolibarrApiAccess::$user->rights->produit->creer) { + throw new RestException(401); + } + + $result = $this->productsupplier->fetch($id); + if (!$result) { + throw new RestException(404, 'Product not found'); + } + + if (!DolibarrApi::_checkAccessToResource('product', $this->productsupplier->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $result = $this->productsupplier->add_fournisseur(DolibarrApiAccess::$user, $fourn_id, $ref_fourn, $qty); + if ($result <= 0) { + throw new RestException(500, "Error adding supplier to product : ".$this->db->lasterror()); + } + + $fourn = new Fournisseur($this->db); + $result = $fourn->fetch($fourn_id); + if ($result <= 0) { + throw new RestException(404, 'Supplier not found'); + } + + $result = $this->productsupplier->update_buyprice($qty, $buyprice, DolibarrApiAccess::$user, $price_base_type, $fourn, $availability, $ref_fourn, $tva_tx, $charges, $remise_percent, $remise, $newnpr, $delivery_time_days, $supplier_reputation, $localtaxes_array, $newdefaultvatcode, $multicurrency_buyprice, $multicurrency_price_base_type, $multicurrency_tx, $multicurrency_code, $desc_fourn, $barcode, $fk_barcode_type); + + if ($result <= 0) { + throw new RestException(500, "Error updating buy price : ".$this->db->lasterror()); + } + return (int) $this->productsupplier->product_fourn_price_id; + } /** * Delete purchase price for a product From 1bad6f5c9c783dc97a4f5bb69708a997aa6c509e Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Sat, 30 Nov 2019 22:38:05 +0000 Subject: [PATCH 13/15] Fixing style errors. --- htdocs/product/class/api_products.class.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index b9d21b481e2..1bb5aed98f5 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -631,7 +631,7 @@ class Products extends DolibarrApi 'prices_by_qty_list'=>$this->product->prices_by_qty_list[0] ); } - + /** * Add purchase prices for a product. * @@ -670,29 +670,29 @@ class Products extends DolibarrApi if(! DolibarrApiAccess::$user->rights->produit->creer) { throw new RestException(401); } - + $result = $this->productsupplier->fetch($id); if (!$result) { throw new RestException(404, 'Product not found'); } - + if (!DolibarrApi::_checkAccessToResource('product', $this->productsupplier->id)) { throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - + $result = $this->productsupplier->add_fournisseur(DolibarrApiAccess::$user, $fourn_id, $ref_fourn, $qty); if ($result <= 0) { throw new RestException(500, "Error adding supplier to product : ".$this->db->lasterror()); } - + $fourn = new Fournisseur($this->db); $result = $fourn->fetch($fourn_id); if ($result <= 0) { throw new RestException(404, 'Supplier not found'); } - + $result = $this->productsupplier->update_buyprice($qty, $buyprice, DolibarrApiAccess::$user, $price_base_type, $fourn, $availability, $ref_fourn, $tva_tx, $charges, $remise_percent, $remise, $newnpr, $delivery_time_days, $supplier_reputation, $localtaxes_array, $newdefaultvatcode, $multicurrency_buyprice, $multicurrency_price_base_type, $multicurrency_tx, $multicurrency_code, $desc_fourn, $barcode, $fk_barcode_type); - + if ($result <= 0) { throw new RestException(500, "Error updating buy price : ".$this->db->lasterror()); } From 7b295bf738dc295cfd774871f7fdb54ea5708c17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric?= <35066297+c3do@users.noreply.github.com> Date: Sun, 1 Dec 2019 14:56:39 +0100 Subject: [PATCH 14/15] addPurchasePrice Update the price if already exist --- htdocs/product/class/api_products.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index 1bb5aed98f5..4ce7750fddd 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -633,7 +633,7 @@ class Products extends DolibarrApi } /** - * Add purchase prices for a product. + * Add/Update purchase prices for a product. * * @param int $id ID of Product * @param float $qty Min quantity for which price is valid @@ -681,7 +681,7 @@ class Products extends DolibarrApi } $result = $this->productsupplier->add_fournisseur(DolibarrApiAccess::$user, $fourn_id, $ref_fourn, $qty); - if ($result <= 0) { + if ($result < 0) { throw new RestException(500, "Error adding supplier to product : ".$this->db->lasterror()); } From c2677c0231f3bd4fb80e424279243d56871ae0ac Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Fri, 21 Feb 2020 19:44:02 +0100 Subject: [PATCH 15/15] Update api_products.class.php --- htdocs/product/class/api_products.class.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index 4ce7750fddd..ccfe30055f8 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -660,8 +660,8 @@ class Products extends DolibarrApi * @param int $fk_barcode_type Barcode type * @return int * - * @throws RestException - * @throws 401 + * @throws RestException 500 + * @throws RestException 401 * * @url POST {id}/purchase_prices */