bdesprez Posted November 22, 2017 Share Posted November 22, 2017 Recently I discovered a problem with combinations in multishop context. First of all, the error : Duplicate entry '339-1' for key 'product_default' UPDATE ps_product_attribute a INNER JOIN ps_product_attribute_shop product_attribute_shop ON (product_attribute_shop.id_product_attribute = a.id_product_attribute AND product_attribute_shop.id_shop = 2) SET a.default_on = '1', product_attribute_shop.default_on = '1' WHERE a.id_product_attribute = 932 Now, I will explain how I did it : Prerequisites : Multishop option activated At least 2 shops Combinations enabled Steps to producing error again : Context : All shops Create a product Context : a specific shop Associate the product to a shop's category Add a combination for this product This combination is now the default one Context : another specific shop Associate the product to a shop's category Add another combination Doh! ERROR! Indeed, the product already has a default attribute but it does not exist in the actual context. Code side now : In ProductCose class (Product.php), the error is raised when «checkDefaultAttributes» is called. Searching default attribute in associated shop table. If it exists it's ok, the method return TRUE. If product does not have attributes, ok, it's returning FALSE. «ObjectModel::updateMultishopTable» is called but there is an index «product_default» in the DB table «product_attribute». It's impossible to have two different default attribute for a product attribute. It sounds like we cannot have different combinations for the same product in different shops. If it is the wanted purpose, I am wondering why the «product_attribute» table has an associated shop table… If it is not, the index «product default» may be on the «product_attribute_shop» table. Oh! wait, there is an index called «id_product» ( cols: id_product, id_shop, default_on). Link to comment Share on other sites More sharing options...
bdesprez Posted November 22, 2017 Author Share Posted November 22, 2017 There is a reported non fixed issue since 2015 … The issue Link to comment Share on other sites More sharing options...
giuliopowa Posted March 12, 2018 Share Posted March 12, 2018 the problem has not been solved and is still open here http://forge.prestashop.com/browse/PSCSX-7372 , it is marked "NEED MORE INFOS" I think the description above is very helpful to try to solve Link to comment Share on other sites More sharing options...
Lokij1414 Posted September 6, 2021 Share Posted September 6, 2021 I do some hardcode to fix it myself. In file classes/Combination.php , edit the add function and update function. line 131 public function add($autodate = true, $null_values = false) { $lokijDefaultOn = $this->default_on; if ($this->default_on) { $this->default_on = 1; } else { $this->default_on = null; } if (!parent::add($autodate, $null_values)) { return false; } if(!$lokijDefaultOn){ Db::getInstance()->executeS('UPDATE `xxx_main`.`ps_product_attribute` SET `default_on` = NULL WHERE `id_product_attribute` = '.$this->id); } $product = new Product((int)$this->id_product); if ($product->getType() == Product::PTYPE_VIRTUAL) { StockAvailable::setProductOutOfStock((int)$this->id_product, 1, null, (int)$this->id); } else { StockAvailable::setProductOutOfStock((int)$this->id_product, StockAvailable::outOfStock((int)$this->id_product), null, $this->id); } SpecificPriceRule::applyAllRules(array((int)$this->id_product)); Product::updateDefaultAttribute($this->id_product); if(!$lokijDefaultOn){ Db::getInstance()->executeS('UPDATE `xxx_main`.`ps_product_attribute_shop` SET `default_on` = NULL WHERE `id_product_attribute` = '.$this->id); } return true; } public function update($null_values = false) { $lokijDefaultOn = $this->default_on; if ($this->default_on) { $this->default_on = 1; } else { $this->default_on = null; } $return = parent::update($null_values); if(!$lokijDefaultOn){ Db::getInstance()->executeS('UPDATE `xxx_main`.`ps_product_attribute` SET `default_on` = NULL WHERE `id_product_attribute` = '.$this->id); } Product::updateDefaultAttribute($this->id_product); if(!$lokijDefaultOn){ Db::getInstance()->executeS('UPDATE `xxx_main`.`ps_product_attribute_shop` SET `default_on` = NULL WHERE `id_product_attribute` = '.$this->id); } return $return; } See the table 'product_attribute' ,the expected value of default_on is null or 1 , but it actually got 0 or 1 after insert data into database. and it cause the error "Duplicate entry 'xxx' for key 'product_default' " . product_default is a unique indexes of table 'product_attribute' . product_default( id_product, default_on ) . if the default_on's value can only be 0 or 1 , then a product can only create two combination . I don't find any code logic error in it . the code try to set the default_on value to null but fail. I think maybe it was cause by php setting or database setting or ObjectModel.php . Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now