Home / Tutorials / PrestaShop 1.7 Tutorials / Amazing PrestaShop Project: Disable attribute out of stock with currently attribute in product prestashop 1.7

Amazing PrestaShop Project: Disable attribute out of stock with currently attribute in product prestashop 1.7

1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading...

You know, Leotheme is one of the best provider marketplace in PrestaShop for PrestaShop Themes, PrestaShop Module & Custom Work.

At present, we have a lot of power customization projects in PrestaShop. And today, we are pleased to introduce about our project and we would like to share tips for all. Hope that this blog will help you well.

Firstly, in the fact that Prestashop have option to hide attribute don’t exist.
For example: You have size (36,37,38,39) and color (red, blue).
If you don’t input size 36 with red color. Prestashop have option PS_DISP_UNAVAILABLE_ATTR, if you turn on it, red color will not display when you click on size 36.
That is very good, but that is not enough.

3 days ago, i got this request of my customer.

So far, all of our products have had only one variation, the shoe size. In the back office I have activated that only existing variants are displayed on the article page. This works even if the Product have only one variant.

Now we have products with two variants (color and size) and unfortunately the automatic filtering does not work anymore.
If the customer chooses a color, then only the available sizes should be displayed, but also unavailable sizes are displayed. If the customer then selects, he jumps to another hue. Not existing sizes are not filtered out. The customer should only see existing variationsAnother possibility is that non-existent combinations are deactivated by a cross.

So i use 3 days to research it.
And i have to add my code to Prestashop core to solver it.
If you are a developer, you can follow my code to add this function, it will help your site run perfect.
I edit function assignAttributesGroups in controller/font/ProductController.php.


protected function assignAttributesGroups($product_for_template = null)
{
$colors = array();
$groups = array();
$this->combinations = array();
$selected_quantities = array();

// @todo (RM) should only get groups and not all declination ?
$attributes_groups = $this->product->getAttributesGroups($this->context->language->id);
if (is_array($attributes_groups) && $attributes_groups) {
$combination_images = $this->product->getCombinationImages($this->context->language->id);
$combination_prices_set = array();
foreach ($attributes_groups as $k => $row) {
// Color management
if (isset($row[‘is_color_group’]) && $row[‘is_color_group’] && (isset($row[‘attribute_color’]) && $row[‘attribute_color’]) || (file_exists(_PS_COL_IMG_DIR_ . $row[‘id_attribute’] . ‘.jpg’))) {
$colors[$row[‘id_attribute’]][‘value’] = $row[‘attribute_color’];
$colors[$row[‘id_attribute’]][‘name’] = $row[‘attribute_name’];
if (!isset($colors[$row[‘id_attribute’]][‘attributes_quantity’])) {
$colors[$row[‘id_attribute’]][‘attributes_quantity’] = 0;
}
$colors[$row[‘id_attribute’]][‘attributes_quantity’] += (int) $row[‘quantity’];
}
if (!isset($groups[$row[‘id_attribute_group’]])) {
$groups[$row[‘id_attribute_group’]] = array(
‘group_name’ => $row[‘group_name’],
‘name’ => $row[‘public_group_name’],
‘group_type’ => $row[‘group_type’],
‘default’ => -1,
);
}

$groups[$row[‘id_attribute_group’]][‘attributes’][$row[‘id_attribute’]] = array(
‘name’ => $row[‘attribute_name’],
‘html_color_code’ => $row[‘attribute_color’],
‘texture’ => (@filemtime(_PS_COL_IMG_DIR_ . $row[‘id_attribute’] . ‘.jpg’)) ? _THEME_COL_DIR_ . $row[‘id_attribute’] . ‘.jpg’ : ”,
‘selected’ => (isset($product_for_template[‘attributes’][$row[‘id_attribute_group’]][‘id_attribute’]) && $product_for_template[‘attributes’][$row[‘id_attribute_group’]][‘id_attribute’] == $row[‘id_attribute’]) ? true : false,
);

if((isset($product_for_template[‘attributes’][$row[‘id_attribute_group’]][‘id_attribute’]) && $product_for_template[‘attributes’][$row[‘id_attribute_group’]][‘id_attribute’] == $row[‘id_attribute’])) {
$selected_quantities[$row[‘id_attribute_group’]][$row[‘id_product_attribute’]] = $row[‘quantity’];
}

//$product.attributes.$id_attribute_group.id_attribute eq $id_attribute
if ($row[‘default_on’] && $groups[$row[‘id_attribute_group’]][‘default’] == -1) {
$groups[$row[‘id_attribute_group’]][‘default’] = (int) $row[‘id_attribute’];
}
if (!isset($groups[$row[‘id_attribute_group’]][‘attributes_quantity’][$row[‘id_attribute’]])) {
$groups[$row[‘id_attribute_group’]][‘attributes_quantity’][$row[‘id_attribute’]] = 0;
}
$groups[$row[‘id_attribute_group’]][‘attributes_quantity’][$row[‘id_attribute’]] += (int) $row[‘quantity’];

$this->combinations[$row[‘id_product_attribute’]][‘attributes_values’][$row[‘id_attribute_group’]] = $row[‘attribute_name’];
$this->combinations[$row[‘id_product_attribute’]][‘attributes’][] = (int) $row[‘id_attribute’];
$this->combinations[$row[‘id_product_attribute’]][‘price’] = (float) $row[‘price’];

// Call getPriceStatic in order to set $combination_specific_price
if (!isset($combination_prices_set[(int) $row[‘id_product_attribute’]])) {
$combination_specific_price = null;
Product::getPriceStatic((int) $this->product->id, false, $row[‘id_product_attribute’], 6, null, false, true, 1, false, null, null, null, $combination_specific_price);
$combination_prices_set[(int) $row[‘id_product_attribute’]] = true;
$this->combinations[$row[‘id_product_attribute’]][‘specific_price’] = $combination_specific_price;
}
$this->combinations[$row[‘id_product_attribute’]][‘ecotax’] = (float) $row[‘ecotax’];
$this->combinations[$row[‘id_product_attribute’]][‘weight’] = (float) $row[‘weight’];
$this->combinations[$row[‘id_product_attribute’]][‘quantity’] = (int) $row[‘quantity’];
$this->combinations[$row[‘id_product_attribute’]][‘reference’] = $row[‘reference’];
$this->combinations[$row[‘id_product_attribute’]][‘unit_impact’] = $row[‘unit_price_impact’];
$this->combinations[$row[‘id_product_attribute’]][‘minimal_quantity’] = $row[‘minimal_quantity’];
if ($row[‘available_date’] != ‘0000-00-00’ && Validate::isDate($row[‘available_date’])) {
$this->combinations[$row[‘id_product_attribute’]][‘available_date’] = $row[‘available_date’];
$this->combinations[$row[‘id_product_attribute’]][‘date_formatted’] = Tools::displayDate($row[‘available_date’]);
} else {
$this->combinations[$row[‘id_product_attribute’]][‘available_date’] = $this->combinations[$row[‘id_product_attribute’]][‘date_formatted’] = ”;
}

if (!isset($combination_images[$row[‘id_product_attribute’]][0][‘id_image’])) {
$this->combinations[$row[‘id_product_attribute’]][‘id_image’] = -1;
} else {
$this->combinations[$row[‘id_product_attribute’]][‘id_image’] = $id_image = (int) $combination_images[$row[‘id_product_attribute’]][0][‘id_image’];
if ($row[‘default_on’]) {
foreach ($this->context->smarty->tpl_vars[‘product’]->value[‘images’] as $image) {
if ($image[‘cover’] == 1) {
$current_cover = $image;
}
}
if (!isset($current_cover)) {
$current_cover = array_values($this->context->smarty->tpl_vars[‘product’]->value[‘images’])[0];
}

if (is_array($combination_images[$row[‘id_product_attribute’]])) {
foreach ($combination_images[$row[‘id_product_attribute’]] as $tmp) {
if ($tmp[‘id_image’] == $current_cover[‘id_image’]) {
$this->combinations[$row[‘id_product_attribute’]][‘id_image’] = $id_image = (int) $tmp[‘id_image’];
break;
}
}
}

if ($id_image > 0) {
if (isset($this->context->smarty->tpl_vars[‘images’]->value)) {
$product_images = $this->context->smarty->tpl_vars[‘images’]->value;
}
if (isset($product_images) && is_array($product_images) && isset($product_images[$id_image])) {
$product_images[$id_image][‘cover’] = 1;
$this->context->smarty->assign(‘mainImage’, $product_images[$id_image]);
if (count($product_images)) {
$this->context->smarty->assign(‘images’, $product_images);
}
}

$cover = $current_cover;

if (isset($cover) && is_array($cover) && isset($product_images) && is_array($product_images)) {
$product_images[$cover[‘id_image’]][‘cover’] = 0;
if (isset($product_images[$id_image])) {
$cover = $product_images[$id_image];
}
$cover[‘id_image’] = (Configuration::get(‘PS_LEGACY_IMAGES’) ? ($this->product->id . ‘-‘ . $id_image) : (int) $id_image);
$cover[‘id_image_only’] = (int) $id_image;
$this->context->smarty->assign(‘cover’, $cover);
}
}
}
}
}

foreach ($attributes_groups as $k => $row) {
foreach ($selected_quantities as $key_q => $value_q) {
if(array_key_exists($row[‘id_product_attribute’], $value_q)){
if(isset($groups[$row[‘id_attribute_group’]][‘attributes’][$row[‘id_attribute’]])) {
$groups[$row[‘id_attribute_group’]][‘attributes’][$row[‘id_attribute’]][‘quantity’] = $value_q[$row[‘id_product_attribute’]];
}
}
}
}

// wash attributes list depending on available attributes depending on selected preceding attributes
$current_selected_attributes = array();
$count = 0;
foreach ($groups as &$group) {
++$count;
if ($count > 1) {
//find attributes of current group, having a possible combination with current selected
$id_product_attributes = array(0);
$query = ‘SELECT pac.`id_product_attribute`
FROM `’ . _DB_PREFIX_ . ‘product_attribute_combination` pac
INNER JOIN `’ . _DB_PREFIX_ . ‘product_attribute` pa ON pa.id_product_attribute = pac.id_product_attribute
WHERE id_product = ‘ . $this->product->id . ‘ AND id_attribute IN (‘ . implode(‘,’, array_map(‘intval’, $current_selected_attributes)) . ‘)
GROUP BY id_product_attribute
HAVING COUNT(id_product) = ‘ . count($current_selected_attributes);
if ($results = Db::getInstance()->executeS($query)) {
foreach ($results as $row) {
$id_product_attributes[] = $row[‘id_product_attribute’];
}
}
$id_attributes = Db::getInstance()->executeS(‘SELECT `id_attribute` FROM `’ . _DB_PREFIX_ . ‘product_attribute_combination` pac2
WHERE `id_product_attribute` IN (‘ . implode(‘,’, array_map(‘intval’, $id_product_attributes)) . ‘)
AND id_attribute NOT IN (‘ . implode(‘,’, array_map(‘intval’, $current_selected_attributes)) . ‘)’);
foreach ($id_attributes as $k => $row) {
$id_attributes[$k] = (int) $row[‘id_attribute’];
}
foreach ($group[‘attributes’] as $key => $attribute) {
if (!in_array((int) $key, $id_attributes)) {
unset($group[‘attributes’][$key]);
unset($group[‘attributes_quantity’][$key]);
}
}
}
//find selected attribute or first of group
$index = 0;
$current_selected_attribute = 0;
foreach ($group[‘attributes’] as $key => $attribute) {
if ($index === 0) {
$current_selected_attribute = $key;
}
if ($attribute[‘selected’]) {
$current_selected_attribute = $key;
break;
}
}
if ($current_selected_attribute > 0) {
$current_selected_attributes[] = $current_selected_attribute;
}
}
// wash attributes list (if some attributes are unavailables and if allowed to wash it)
if (!Product::isAvailableWhenOutOfStock($this->product->out_of_stock) && Configuration::get(‘PS_DISP_UNAVAILABLE_ATTR’) == 0) {
foreach ($groups as &$group) {
foreach ($group[‘attributes_quantity’] as $key => &$quantity) {
if ($quantity <= 0) {
unset($group[‘attributes’][$key]);
}
}
}

foreach ($colors as $key => $color) {
if ($color[‘attributes_quantity’] <= 0) {
unset($colors[$key]);
}
}
}

foreach ($this->combinations as $id_product_attribute => $comb) {
$attribute_list = ”;
foreach ($comb[‘attributes’] as $id_attribute) {
$attribute_list .= ‘\” . (int) $id_attribute . ‘\’,’;
}
$attribute_list = rtrim($attribute_list, ‘,’);
$this->combinations[$id_product_attribute][‘list’] = $attribute_list;
}

$this->context->smarty->assign(array(
‘groups’ => $groups,
‘colors’ => (count($colors)) ? $colors : false,
‘combinations’ => $this->combinations,
‘combinationImages’ => $combination_images,
));
} else {
$this->context->smarty->assign(array(
‘groups’ => array(),
‘colors’ => false,
‘combinations’ => array(),
‘combinationImages’ => array(),
));
}
}

and in the file /themes/YOURTHEME/templates/catalog/_partials/product-variants.tpl

i added this code:

 


{**
* 2007-2017 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License 3.0 (AFL-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:
* https://opensource.org/licenses/AFL-3.0
* 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 license@prestashop.com 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 <contact@prestashop.com>
* @copyright PrestaShop SA
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License 3.0 (AFL-3.0)
* International Registered Trademark & Property of PrestaShop SA
*}

{foreach from=$groups key=id_attribute_group item=group} {if !empty($group.attributes)}

{$group.name} {if $group.group_type == ‘select’}

{elseif $group.group_type == ‘color’}

    • {foreach from=$group.attributes key=id_attribute item=group_attribute}

{/foreach}

{elseif $group.group_type == ‘radio’}

    • {foreach from=$group.attributes key=id_attribute item=group_attribute}

{/foreach}

{/if}

{/if} {/foreach}

 

you can see, i add class=”disable” for attribue have quanlity =0

In theme.css file

you only need add code in end of file

 

.product-variants > .product-variants-item ul li label.disable{display:none}

 

YOu can see demo of my customer website

leotheme custom work

DEMO

 

If you are a developer i can make sure you can do it.

If you are business man, please send all your requirements to us via: leotheme@gmail.com

SEND REQUIREMENT

Skype: trandinhnghiait

Go to top

About admin@leotheme.com

Check Also

install prestashop page builder

Ap Page Builder: Install PrestaShop Page Builder – Leotheme Tutorial

Are you looking for the best solution of your website? Ease of use for any …

Leave a Reply

Your email address will not be published. Required fields are marked *