Jump to content

Combination Multistore not working properly


NIKESLB

Recommended Posts

Hi,

I'm using PS 1.6.1.17 and I got a problem with the combinations. I have two multistore. When I select "All stores" and I want to change one product combination, If i change the reference, the weight or the EAN-13, the product combination get a reset and the price become 0. 

 

Is it normal? Any solution please?

Link to comment
Share on other sites

Hello, I tryed this at my 1.6.1.17 and there is also problem.

I have 2 stores in 2 store categories. They have 1 stock but they are not sharing customers and orders. When I try to change ean13 or reference in "All stores" mode and Save, it delete this combination.

Formore when I configure prices for combination, my "increased price" does not show on product page, olny in cart (but only in second shop, in main shop it is ok).

I think the multistore does not work properly, but many merchants does not using it, so bugs are not squashed. 

 

Link to comment
Share on other sites

So I'm trying to solve this myself and did some progress but it's really hard to fix it. The problem is prestashop save every field from a combination. Instead update just the field where it was modified, it updates everything. 

In the file adminProductsController at  the function "processProductAttribute" and the edit section we can find:

$this->isProductFieldUpdated('attribute_weight_impact') ? Tools::getValue('attribute_weight') * Tools::getValue('attribute_weight_impact') : null,

 So if there is no update at this field then the value is null. All attributes are sent to the file Product.php at updateAttribute function. The first code is:

$combination = new Combination($id_product_attribute);

At this moment it fetchs every attributes from database where id is equal to id_product_attribute. At this point it's no sense to fetch this data if we going to update over it. Then we get this code:

 $combination->weight = (float)$weight;

The $weight come from the "processProductAttribute" function and if the result is null then the property $combination->weight become null. So when  saves to the database the weight will be 0 for this combination in every stores. I tried to unset the property, but null or unset will always save 0 to the database.

 

EDIT:

Better fix

if (Shop::isFeatureActive() && Shop::getContext() != Shop::CONTEXT_SHOP) {     

                        if(get_class($this) == "Combination")
                        { 
                            foreach ($this->update_fields as $key => $val) {
                                if($val == null)
                                {
                                    unset($fields[$key]);
                                }
                            }
                        }
                        else  
                        {
                            foreach ($fields as $key => $val) {
                                if (!array_key_exists($key, $this->update_fields)) {
                                    unset($fields[$key]);
                                }
                            }
                        }                        
                        
                    }

 

Edited by NIKESLB (see edit history)
Link to comment
Share on other sites

Well I think I found finally the fix. At ObjectModel.php function update I added those line (At "//START FIX"):

foreach ($id_shop_list as $id_shop) {
                $fields['id_shop'] = (int)$id_shop;
                $all_fields['id_shop'] = (int)$id_shop;
                $where = $this->def['primary'].' = '.(int)$this->id.' AND id_shop = '.(int)$id_shop;

                // A little explanation of what we do here : we want to create multishop entry when update is called, but
                // only if we are in a shop context (if we are in all context, we just want to update entries that alread exists)
                $shop_exists = Db::getInstance()->getValue('SELECT '.$this->def['primary'].' FROM '._DB_PREFIX_.$this->def['table'].'_shop WHERE '.$where);
                if ($shop_exists) {

                //START FIX
                 if(get_class($this) == "Combination")
                 {
                    foreach ($fields as $key => $val) {
                        if($val == 0)
                            unset($fields[$key]);                
                    }       
                 }

				//END FIX

                    $result &= Db::getInstance()->update($this->def['table'].'_shop', $fields, $where, 0, $null_values);
                } elseif (Shop::getContext() == Shop::CONTEXT_SHOP) {

                    $result &= Db::getInstance()->insert($this->def['table'].'_shop', $all_fields, $null_values);
                }
            }

I unset all property where value is equal to 0, so it will ignore all fields where there is no modification.

I spent some days on it, I'm pretty sure some people have the same as me, because it's happening to me in diferents stores. 

I really hope this fix will help someone.

Link to comment
Share on other sites

  • 1 year later...

Found a fix that works for me,

Fix for me in PS 1.7.5.1

Table ps_attribute_group rename field "is_color_group" to anything you like > Save >

Then rename the field back to "is_color_group"

Not sure why this works, I assume it is related to a bad index.

Link to comment
Share on other sites

  • 2 months later...

Hi, I have tried the exposed solutions but they do not work for me,

According to my evaluation the problem is given because the allshops parameter is being sent in true without evaluating if we are in an allshops context, what I have done is to verify if we are in the context of allshops and pass that result as a variable to the method productAttributeExists since by default it is always being sent to true, with this it works correctly.

the modifications are:

 

Quote

$allShops = true;
if (Shop::isFeatureActive()) {
    if(Shop::getContext() != Shop::CONTEXT_ALL) {
        $allShops = false;
    }
}

and

Quote

if (($id_product_attribute = (int)Tools::getValue('id_product_attribute')) || ($id_product_attribute = $product->productAttributeExists(Tools::getValue('attribute_combination_list'), false, null, $allShops, true))) {

and the complety file is: 

 

Place this file in /override/controllers/admin/AdminProductsController.php and then delete the file /cache/class_index.php as usual

<?php
/*
* 2007-2017 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Open Software License (OSL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/osl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to [email protected] so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
*  @author PrestaShop SA <[email protected]>
*  @copyright  2007-2017 PrestaShop SA
*  @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
*  International Registered Trademark & Property of PrestaShop SA
*/

class AdminProductsController extends AdminProductsControllerCore
{
    public function processProductAttribute()
    {
        // Don't process if the combination fields have not been submitted
        if (!Combination::isFeatureActive() || !Tools::getValue('attribute_combination_list')) {
            return;
        }

        if (Validate::isLoadedObject($product = $this->object)) {
            if ($this->isProductFieldUpdated('attribute_price') && (!Tools::getIsset('attribute_price') || Tools::getIsset('attribute_price') == null)) {
                $this->errors[] = Tools::displayError('The price attribute is required.');
            }
            if (!Tools::getIsset('attribute_combination_list') || Tools::isEmpty(Tools::getValue('attribute_combination_list'))) {
                $this->errors[] = Tools::displayError('You must add at least one attribute.');
            }

            $array_checks = array(
                'reference' => 'isReference',
                'supplier_reference' => 'isReference',
                'location' => 'isReference',
                'ean13' => 'isEan13',
                'upc' => 'isUpc',
                'wholesale_price' => 'isPrice',
                'price' => 'isPrice',
                'ecotax' => 'isPrice',
                'quantity' => 'isInt',
                'weight' => 'isUnsignedFloat',
                'unit_price_impact' => 'isPrice',
                'default_on' => 'isBool',
                'minimal_quantity' => 'isUnsignedInt',
                'available_date' => 'isDateFormat'
            );
            foreach ($array_checks as $property => $check) {
                if (Tools::getValue('attribute_'.$property) !== false && !call_user_func(array('Validate', $check), Tools::getValue('attribute_'.$property))) {
                    $this->errors[] = sprintf(Tools::displayError('Field %s is not valid'), $property);
                }
            }

            if (!count($this->errors)) {
                if (!isset($_POST['attribute_wholesale_price'])) {
                    $_POST['attribute_wholesale_price'] = 0;
                }
                if (!isset($_POST['attribute_price_impact'])) {
                    $_POST['attribute_price_impact'] = 0;
                }
                if (!isset($_POST['attribute_weight_impact'])) {
                    $_POST['attribute_weight_impact'] = 0;
                }
                if (!isset($_POST['attribute_ecotax'])) {
                    $_POST['attribute_ecotax'] = 0;
                }
                if (Tools::getValue('attribute_default')) {
                    $product->deleteDefaultAttributes();
                }

                $allShops = true;
                if (Shop::isFeatureActive()) {
                    if(Shop::getContext() != Shop::CONTEXT_ALL) {
                        $allShops = false;
                    }
                }

                // Change existing one
                if (($id_product_attribute = (int)Tools::getValue('id_product_attribute')) || ($id_product_attribute = $product->productAttributeExists(Tools::getValue('attribute_combination_list'), false, null, $allShops, true))) {
                    if ($this->tabAccess['edit'] === '1') {
                        if ($this->isProductFieldUpdated('available_date_attribute') && (Tools::getValue('available_date_attribute') != '' &&!Validate::isDateFormat(Tools::getValue('available_date_attribute')))) {
                            $this->errors[] = Tools::displayError('Invalid date format.');
                        } else {
                            $product->updateAttribute((int)$id_product_attribute,
                                $this->isProductFieldUpdated('attribute_wholesale_price') ? Tools::getValue('attribute_wholesale_price') : null,
                                $this->isProductFieldUpdated('attribute_price_impact') ? Tools::getValue('attribute_price') * Tools::getValue('attribute_price_impact') : null,
                                $this->isProductFieldUpdated('attribute_weight_impact') ? Tools::getValue('attribute_weight') * Tools::getValue('attribute_weight_impact') : null,
                                $this->isProductFieldUpdated('attribute_unit_impact') ? Tools::getValue('attribute_unity') * Tools::getValue('attribute_unit_impact') : null,
                                $this->isProductFieldUpdated('attribute_ecotax') ? Tools::getValue('attribute_ecotax') : null,
                                Tools::getValue('id_image_attr'),
                                Tools::getValue('attribute_reference'),
                                Tools::getValue('attribute_ean13'),
                                $this->isProductFieldUpdated('attribute_default') ? Tools::getValue('attribute_default') : null,
                                Tools::getValue('attribute_location'),
                                Tools::getValue('attribute_upc'),
                                $this->isProductFieldUpdated('attribute_minimal_quantity') ? Tools::getValue('attribute_minimal_quantity') : null,
                                $this->isProductFieldUpdated('available_date_attribute') ? Tools::getValue('available_date_attribute') : null, false);
                            StockAvailable::setProductDependsOnStock((int)$product->id, $product->depends_on_stock, null, (int)$id_product_attribute);
                            StockAvailable::setProductOutOfStock((int)$product->id, $product->out_of_stock, null, (int)$id_product_attribute);
                        }
                    } else {
                        $this->errors[] = Tools::displayError('You do not have permission to add this.');
                    }
                }
                // Add new
                else {
                    if ($this->tabAccess['add'] === '1') {
                        if ($product->productAttributeExists(Tools::getValue('attribute_combination_list'))) {
                            $this->errors[] = Tools::displayError('This combination already exists.');
                        } else {
                            $id_product_attribute = $product->addCombinationEntity(
                                Tools::getValue('attribute_wholesale_price'),
                                Tools::getValue('attribute_price') * Tools::getValue('attribute_price_impact'),
                                Tools::getValue('attribute_weight') * Tools::getValue('attribute_weight_impact'),
                                Tools::getValue('attribute_unity') * Tools::getValue('attribute_unit_impact'),
                                Tools::getValue('attribute_ecotax'),
                                0,
                                Tools::getValue('id_image_attr'),
                                Tools::getValue('attribute_reference'),
                                null,
                                Tools::getValue('attribute_ean13'),
                                Tools::getValue('attribute_default'),
                                Tools::getValue('attribute_location'),
                                Tools::getValue('attribute_upc'),
                                Tools::getValue('attribute_minimal_quantity'),
                                array(),
                                Tools::getValue('available_date_attribute')
                            );
                            StockAvailable::setProductDependsOnStock((int)$product->id, $product->depends_on_stock, null, (int)$id_product_attribute);
                            StockAvailable::setProductOutOfStock((int)$product->id, $product->out_of_stock, null, (int)$id_product_attribute);
                        }
                    } else {
                        $this->errors[] = Tools::displayError('You do not have permission to').'<hr>'.Tools::displayError('edit here.');
                    }
                }
                if (!count($this->errors)) {
                    $combination = new Combination((int)$id_product_attribute);
                    $combination->setAttributes(Tools::getValue('attribute_combination_list'));

                    // images could be deleted before
                    $id_images = Tools::getValue('id_image_attr');
                    if (!empty($id_images)) {
                        $combination->setImages($id_images);
                    }

                    $product->checkDefaultAttributes();
                    if (Tools::getValue('attribute_default')) {
                        Product::updateDefaultAttribute((int)$product->id);
                        if (isset($id_product_attribute)) {
                            $product->cache_default_attribute = (int)$id_product_attribute;
                        }

                        if ($available_date = Tools::getValue('available_date_attribute')) {
                            $product->setAvailableDate($available_date);
                        } else {
                            $product->setAvailableDate();
                        }
                    }
                }
            }
        }
    }

}

 

Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...