From ae906270f324353f5e8c7e1a5c0bf440d0cf085a Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sun, 26 Nov 2017 18:43:43 +0100 Subject: [PATCH] Debug module variant --- htdocs/langs/en_US/errors.lang | 2 + htdocs/product/class/product.class.php | 13 ++-- .../variants/class/ProductAttribute.class.php | 12 ++- .../class/ProductCombination.class.php | 41 +++++++---- htdocs/variants/combinations.php | 73 ++++++++++++------- 5 files changed, 93 insertions(+), 48 deletions(-) diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index c36a3fad5ff..36e80586d2a 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -204,6 +204,8 @@ ErrorOnlyInvoiceValidatedCanBeSentInMassAction=Only validated invoices can be se ErrorChooseBetweenFreeEntryOrPredefinedProduct=You must choose if article is a predefined product or not ErrorDiscountLargerThanRemainToPaySplitItBefore=The discount you try to apply is larger than remain to pay. Split the discount in 2 smaller discounts before. ErrorFileNotFoundWithSharedLink=File was not found. May be the share key was modified or file was removed recently. +ErrorProductBarCodeAlreadyExists=The product barcode %s already exists on another product reference. + # Warnings WarningPasswordSetWithNoAccount=A password was set for this member. However, no user account was created. So this password is stored but can't be used to login to Dolibarr. It may be used by an external module/interface but if you don't need to define any login nor password for a member, you can disable option "Manage a login for each member" from Member module setup. If you need to manage a login but don't need any password, you can keep this field empty to avoid this warning. Note: Email can also be used as a login if the member is linked to a user. WarningMandatorySetupNotComplete=Mandatory setup parameters are not yet defined diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index 603f111e0b9..4c67a25962e 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -656,21 +656,23 @@ class Product extends CommonObject $result = -2; } - $rescode = $this->check_barcode($this->barcode,$this->barcode_type_code); - if ($rescode <> 0) + $rescode = $this->check_barcode($this->barcode, $this->barcode_type_code); + if ($rescode) { if ($rescode == -1) { $this->errors[] = 'ErrorBadBarCodeSyntax'; } - if ($rescode == -2) + elseif ($rescode == -2) { $this->errors[] = 'ErrorBarCodeRequired'; } - if ($rescode == -3) + elseif ($rescode == -3) { + // Note: Common usage is to have barcode unique. For variants, we should have a different barcode. $this->errors[] = 'ErrorBarCodeAlreadyUsed'; } + $result = -3; } @@ -997,6 +999,7 @@ class Product extends CommonObject { if ($this->db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS') { + $langs->load("errors"); if (empty($conf->barcode->enabled)) $this->error=$langs->trans("Error")." : ".$langs->trans("ErrorProductAlreadyExists",$this->ref); else $this->error=$langs->trans("Error")." : ".$langs->trans("ErrorProductBarCodeAlreadyExists",$this->barcode); $this->errors[]=$this->error; @@ -1119,7 +1122,7 @@ class Product extends CommonObject } //We also check if it is a child product - if (!$error && ($prodcomb->fetchByFkProductChild($id) > 0) && ($prodcomb->delete() < 0)) { + if (!$error && ($prodcomb->fetchByFkProductChild($id) > 0) && ($prodcomb->delete($user) < 0)) { $error++; $this->errors[] = 'Error deleting child combination'; } diff --git a/htdocs/variants/class/ProductAttribute.class.php b/htdocs/variants/class/ProductAttribute.class.php index 03440d0520b..0fa25cdba6e 100644 --- a/htdocs/variants/class/ProductAttribute.class.php +++ b/htdocs/variants/class/ProductAttribute.class.php @@ -224,6 +224,8 @@ class ProductAttribute */ protected function reorderLines() { + global $user; + $tmp_order = array(); $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.'product_attribute WHERE rang = 0'; @@ -244,7 +246,7 @@ class ProductAttribute $tmp->fetch($rowid); $tmp->rang = $order+1; - if ($tmp->update() < 0) { + if ($tmp->update($user) < 0) { return -1; } } @@ -260,6 +262,8 @@ class ProductAttribute */ private function moveLine($type) { + global $user; + if ($this->reorderLines() < 0) { return -1; } @@ -281,7 +285,7 @@ class ProductAttribute $this->rang = $newrang; - if ($this->update() < 0) { + if ($this->update($user) < 0) { $this->db->rollback(); return -1; } @@ -319,6 +323,8 @@ class ProductAttribute */ public static function bulkUpdateOrder(DoliDB $db, array $order) { + global $user; + $tmp = new ProductAttribute($db); foreach ($order as $key => $attrid) { @@ -328,7 +334,7 @@ class ProductAttribute $tmp->rang = $key; - if ($tmp->update() < 0) { + if ($tmp->update($user) < 0) { return -1; } } diff --git a/htdocs/variants/class/ProductCombination.class.php b/htdocs/variants/class/ProductCombination.class.php index 04b987192e1..4f647aa2cb3 100644 --- a/htdocs/variants/class/ProductCombination.class.php +++ b/htdocs/variants/class/ProductCombination.class.php @@ -199,9 +199,10 @@ class ProductCombination /** * Creates a product attribute combination * - * @return int + * @param User $user Object user + * @return int <0 if KO, >0 if OK */ - public function create() + public function create($user) { $sql = "INSERT INTO ".MAIN_DB_PREFIX."product_attribute_combination (fk_product_parent, fk_product_child, variation_price, variation_price_percentage, variation_weight, entity) @@ -223,9 +224,10 @@ class ProductCombination /** * Updates a product combination * - * @return int <0 KO, >0 OK + * @param User $user Object user + * @return int <0 KO, >0 OK */ - public function update() + public function update(User $user) { $sql = "UPDATE ".MAIN_DB_PREFIX."product_attribute_combination SET fk_product_parent = ".(int) $this->fk_product_parent.", fk_product_child = ".(int) $this->fk_product_child.", @@ -370,9 +372,9 @@ class ProductCombination /** * Retrieves the combination that matches the given features. * - * @param int $prodid Id of parent product - * @param array $features Format: [$attr] => $attr_val - * @return false|ProductCombination false if not found + * @param int $prodid Id of parent product + * @param array $features Format: [$attr] => $attr_val + * @return false|ProductCombination False if not found */ public function fetchByProductCombination2ValuePairs($prodid, array $features) { @@ -507,7 +509,7 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; } else { $newcomb->fk_product_parent = $product->id; - if ($newcomb->create() < 0) { + if ($newcomb->create($user) < 0) { // Create 1 entry into product_attribute_combination (1 entry for all combinations) $db->rollback(); return -1; } @@ -516,6 +518,8 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; $prodattr = new ProductAttribute($db); $prodattrval = new ProductAttributeValue($db); + // $combination contains list of attributes pairs key->value. Example: array('id Color'=>id Blue, 'id Size'=>id Small, 'id Option'=>id val a, ...) + //var_dump($combinations); foreach ($combinations as $currcombattr => $currcombval) { //This was checked earlier, so no need to double check @@ -529,7 +533,7 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; $tmp->fk_prod_attr_val = $currcombval; $tmp->fk_prod_combination = $newcomb->id; - if ($tmp->create() < 0) { + if ($tmp->create($user) < 0) { // Create 1 entry into product_attribute_combination2val $db->rollback(); return -1; } @@ -567,8 +571,14 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; $newproduct->price_min = 0; $newproduct->price_min_ttc = 0; - if ($newproduct->create($user) < 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; @@ -611,7 +621,8 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; $newcomb->fk_product_child = $newproduct->id; - if ($newcomb->update() < 0) { + if ($newcomb->update($user) < 0) + { $db->rollback(); return -1; } @@ -636,11 +647,10 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; return -1; } - $prodcomb = new ProductCombination($this->db); $prodcomb2val = new ProductCombination2ValuePair($this->db); //Retrieve all product combinations - $combinations = $prodcomb->fetchAllByFkProductParent($origProductId); + $combinations = $this->fetchAllByFkProductParent($origProductId); foreach ($combinations as $combination) { @@ -650,14 +660,15 @@ WHERE c.fk_product_parent = ".(int) $productid." AND p.tosell = 1"; $variations[$tmp_pc2v->fk_prod_attr] = $tmp_pc2v->fk_prod_attr_val; } - if (self::createProductCombination( + if ($this->createProductCombination( $destProduct, $variations, array(), $combination->variation_price_percentage, $combination->variation_price, $combination->variation_weight - ) < 0) { + ) < 0) + { return -1; } } diff --git a/htdocs/variants/combinations.php b/htdocs/variants/combinations.php index a15d4781500..3101d44ecf5 100644 --- a/htdocs/variants/combinations.php +++ b/htdocs/variants/combinations.php @@ -75,8 +75,12 @@ if (! $object->isProduct()) { header('Location: '.dol_buildpath('/product/card.php?id='.$object->id, 2)); exit(); } - -if (GETPOST('selectvariant')) +if ($action == 'add') +{ + unset($selectedvariant); + unset($_SESSION['addvariant_'.$object->id]); +} +if ($action == 'create' && GETPOST('selectvariant','alpha')) // We click on select combination { $action = 'add'; if (GETPOST('attribute') != '-1' && GETPOST('value') != '-1') @@ -94,8 +98,8 @@ $productCombination2ValuePairs1 = array(); if ($_POST) { - if (($action == 'add' || $action == 'create') && empty($massaction) && ! GETPOST('selectvariant')) { - + if (($action == 'add' || $action == 'create') && empty($massaction) && ! GETPOST('selectvariant', 'alpha')) // We click on Create all defined combinations + { //$features = GETPOST('features', 'array'); $features = $_SESSION['addvariant_'.$object->id]; @@ -121,7 +125,7 @@ if ($_POST) { continue; } - //Valuepair + // Valuepair $sanit_features[$explode[0]] = $explode[1]; $tmp = new ProductCombination2ValuePair($db); @@ -133,18 +137,28 @@ if ($_POST) { $db->begin(); - if (!$prodcomb->fetchByProductCombination2ValuePairs($id, $sanit_features)) { - if (ProductCombination::createProductCombination($object, $sanit_features, array(), $price_impact_percent, $price_impact, $weight_impact)) { - $db->commit(); + // sanit_feature is an array with 1 (and only 1) value per attribute. + // For example: Color->blue, Size->Small, Option->2 + //var_dump($sanit_features); + //var_dump($productCombination2ValuePairs1); exit; + + if (! $prodcomb->fetchByProductCombination2ValuePairs($id, $sanit_features)) + { + $result = $prodcomb->createProductCombination($object, $sanit_features, array(), $price_impact_percent, $price_impact, $weight_impact); + if ($result > 0) + { setEventMessage($langs->trans('RecordSaved')); unset($_SESSION['addvariant_'.$object->id]); + + $db->commit(); header('Location: '.dol_buildpath('/variants/combinations.php?id='.$id, 2)); exit(); } else { - setEventMessage($langs->trans('CoreErrorMessage'), 'errors'); + $langs->load("errors"); + setEventMessages('', $prodcomb->errors, 'errors'); } } else { - setEventMessage($langs->trans('ErrorRecordAlreadyExists'), 'errors'); + setEventMessages($langs->trans('ErrorRecordAlreadyExists'), null, 'errors'); } $db->rollback(); @@ -178,7 +192,7 @@ if ($_POST) { $prodstatic->status_buy = 0; $res = $prodstatic->update($prodstatic->id, $user); } elseif ($bulkaction == 'delete') { - $res = $prodstatic->delete($prodstatic->id); + $res = $prodstatic->delete($user, $prodstatic->id); } else { break; } @@ -193,9 +207,9 @@ if ($_POST) { $db->rollback(); if ($prodstatic->error) { - setEventMessage($langs->trans($prodstatic->error), 'errors'); + setEventMessages($prodstatic->error, $prodstatic->errors, 'errors'); } else { - setEventMessage($langs->trans('CoreErrorMessage'), 'errors'); + setEventMessages($langs->trans('CoreErrorMessage'), null, 'errors'); } } else { @@ -215,12 +229,12 @@ if ($_POST) { $prodcomb->variation_price = $price_impact; $prodcomb->variation_weight = $weight_impact; - if ($prodcomb->update() > 0) { + if ($prodcomb->update($user) > 0) { setEventMessage($langs->trans('RecordSaved')); header('Location: '.dol_buildpath('/variants/combinations.php?id='.$id, 2)); exit(); } else { - setEventMessage($langs->trans('CoreErrorMessage'), 'errors'); + setEventMessages($prodcomb->error, $prodcomb->errors, 'errors'); } } } @@ -408,9 +422,10 @@ if (! empty($id) || ! empty($ref)) '."\n"; + print '
'."\n"; + print ''; print ''."\n"; - print ''."\n"; + print ''."\n"; print dol_fiche_head(); @@ -467,12 +482,15 @@ if (! empty($id) || ! empty($ref)) +
- - +
-
@@ -614,7 +633,10 @@ if (! empty($id) || ! empty($ref)) // List of variants print ''; - + print ''; + print ''; + print ''; + print ''; // List of mass actions available /* @@ -639,7 +661,6 @@ if (! empty($id) || ! empty($ref)) $aaa .= ' '; $aaa .= ' '; $aaa .= ''; - $aaa .= ''; $aaa .= ''; } $massactionbutton = $aaa; @@ -670,7 +691,8 @@ if (! empty($id) || ! empty($ref)) if (count($productCombinations)) { - foreach ($productCombinations as $currcomb) { + foreach ($productCombinations as $currcomb) + { $prodstatic->fetch($currcomb->fk_product_child); ?> @@ -720,6 +742,7 @@ if (! empty($id) || ! empty($ref)) '; + print ''; } }