Jump to content

Combination quantity


Recommended Posts

I'm not quite sure how to explain my issue so please feel free to ask me to clarify.

I am trying to sell custom earrings in my shop. I want to offer customers a choice of earring wire (since some people have sensitive ears). I add two wire attributes in a group called "Hook" using the combination tool.

Group: Hook | Attribute: Regular (price doesn't change) [*This is the default choice]
Group: Hook | Attribute: Sterling Silver (+$1.25)


Each pair of earrings is only made once, so the quantity of the product should always be "1". But after I add these as options the quantity in my back office says "2". It's like prestashop thinks that I have 2 pairs of this earring design, one with regular hooks and one with sterling silver hooks, when I actually have one pair of earrings with hooks to be determined by the customer.

Is there a way to get prestashop to understand that the product has an interchangeable part? I don't want my catalog to say that it has 2 of something it only has one of...but I'd still like to offer my customers a choice.

I'd use a custom text field, but I need to charge a little more for the sterling silver and I don't think I could do that with the text field.

Thanks in advance!

Link to comment
Share on other sites

  • 3 weeks later...

I've done a similar thing for my shop and I found the best thing to do is create a module that hooks on updateQuantity and sets the product to inactive. This makes it disappear from any product listing, but it will still appear in your catalogue on the backend.

Link to comment
Share on other sites

  • 4 weeks later...

Actually, you can change the way the attribute quantity is handled, so whenever any attribute is bought, the quantity of all of them gets reduced (as long as you start all the attributes with the same quantity, it should do what you want).

If you want to have this product specific, you'll have to do some more coding, but if you want to apply this to every product with attribute, just change the following lines in /classes/Product.php (#1427)

From

WHERE `id_product` = '.intval($product['id_product']).
($product['id_product_attribute'] ? ' AND `id_product_attribute` = '.intval($product['id_product_attribute']) : ''));



To

WHERE `id_product` = '.intval($product['id_product']));

Link to comment
Share on other sites

Thanks tomerg3,

That sounds just what I'm after. The only problem is the product page displays the quantity for all combinations doesn't it? How would I get around that?

(I have a DVD of a School show that I'm selling and they will be paid for on the website and collected at the school. My way of getting the student's class number to help with distributing them out at school is via the combinations as presta doesn't give me any other options really, so the overall quantity can only really be the overall amount (e.g. 45 DVDs). Does that make ant sense?!)

Link to comment
Share on other sites

the backoffice will show the total of all of them, but the front office will show the correct amount.
IF you change the code I sent, than you should set each attribute group to 45, and when 1 is bought, the quantity for all will be reduced.

Link to comment
Share on other sites

I should add that I was using the 'Moon' theme where I found the product.tpl file, under product qty had a span id of ‘availability_number’ compared to the default theme of ‘quantityAvailable’.

Thanks to tomerg3

Link to comment
Share on other sites

One more change to avoid the high quantity problem (it's caused when the quantity goes below 0)

Change

SET `quantity` = `quantity`-'.intval($product['quantity']).'



To

SET `quantity` = GREATEST(quantity-'.intval($product['quantity']).',0)

Link to comment
Share on other sites

  • 4 months later...
sorry, it's not permissions, for some reason a ' after after id_product, not sure why the forum is not showing it.

Try
intval($product['id_product']));


I did the change in version 1.3 in the line # 1614 of /classes/Product.php :

From
WHERE `id_product` = '.intval($product['id_product']).
($product['id_product_attribute'] ? ' AND `id_product_attribute` = '.intval($product['id_product_attribute']) : ''));



To

WHERE `id_product` = '.intval($product['id_product']));



I made sure" ' " was not missing. It is behaving still the same. I would appreciate any comment. Thanks
Link to comment
Share on other sites

Here's the complete function for PS 1.3, try it out and let me know (I did not test it)

   public static function updateQuantity($product)
   {
       if (!is_array($product))
           die (Tools::displayError());

       if (Pack::isPack(intval($product['id_product'])))
       {
           $products_pack = Pack::getItems(intval($product['id_product']), intval(Configuration::get('PS_LANG_DEFAULT')));
           foreach($products_pack AS $product_pack)
           {
               $tab_product_pack['id_product'] = intval($product_pack->id);
               $tab_product_pack['id_product_attribute'] = self::getDefaultAttribute($tab_product_pack['id_product'], 1);
               $tab_product_pack['cart_quantity'] = intval($product_pack->pack_quantity * $product['cart_quantity']);
               self::updateQuantity($tab_product_pack);
           }
       }

       $result = Db::getInstance()->getRow('
       SELECT `quantity`
       FROM `'._DB_PREFIX_.($product['id_product_attribute'] ? 'product_attribute' : 'product').'`
       WHERE `id_product` = '.intval($product['id_product']).($product['id_product_attribute'] ?
       ' AND `id_product_attribute` = '.intval($product['id_product_attribute']) : ''));

       if (!Configuration::get('PS_STOCK_MANAGEMENT'))
           return true;
       if (self::isAvailableWhenOutOfStock($product['out_of_stock']) AND intval($result['quantity']) == 0)
           return -1;

       if ($result['quantity'] < $product['cart_quantity'])
       {
           Db::getInstance()->Execute('
           UPDATE `'._DB_PREFIX_.($product['id_product_attribute'] ? 'product_attribute' : 'product').'`
           SET `quantity` = 0
           WHERE `id_product` = '.intval($product['id_product']));
           return false;
       }

       Db::getInstance()->Execute('
       UPDATE `'._DB_PREFIX_.'product'.($product['id_product_attribute'] ? '_attribute' : '').'`
       SET `quantity` = `quantity`-'.intval($product['cart_quantity']).'
       WHERE `id_product` = '.intval($product['id_product']));
       return true;
   }

Link to comment
Share on other sites

Here's the complete function for PS 1.3, try it out and let me know (I did not test it)

   public static function updateQuantity($product)
   {
       if (!is_array($product))
           die (Tools::displayError());

       if (Pack::isPack(intval($product['id_product'])))
       {
           $products_pack = Pack::getItems(intval($product['id_product']), intval(Configuration::get('PS_LANG_DEFAULT')));
           foreach($products_pack AS $product_pack)
           {
               $tab_product_pack['id_product'] = intval($product_pack->id);
               $tab_product_pack['id_product_attribute'] = self::getDefaultAttribute($tab_product_pack['id_product'], 1);
               $tab_product_pack['cart_quantity'] = intval($product_pack->pack_quantity * $product['cart_quantity']);
               self::updateQuantity($tab_product_pack);
           }
       }

       $result = Db::getInstance()->getRow('
       SELECT `quantity`
       FROM `'._DB_PREFIX_.($product['id_product_attribute'] ? 'product_attribute' : 'product').'`
       WHERE `id_product` = '.intval($product['id_product']).($product['id_product_attribute'] ?
       ' AND `id_product_attribute` = '.intval($product['id_product_attribute']) : ''));

       if (!Configuration::get('PS_STOCK_MANAGEMENT'))
           return true;
       if (self::isAvailableWhenOutOfStock($product['out_of_stock']) AND intval($result['quantity']) == 0)
           return -1;

       if ($result['quantity'] < $product['cart_quantity'])
       {
           Db::getInstance()->Execute('
           UPDATE `'._DB_PREFIX_.($product['id_product_attribute'] ? 'product_attribute' : 'product').'`
           SET `quantity` = 0
           WHERE `id_product` = '.intval($product['id_product']));
           return false;
       }

       Db::getInstance()->Execute('
       UPDATE `'._DB_PREFIX_.'product'.($product['id_product_attribute'] ? '_attribute' : '').'`
       SET `quantity` = `quantity`-'.intval($product['cart_quantity']).'
       WHERE `id_product` = '.intval($product['id_product']));
       return true;
   }



Thanks so much for taking time and helping me to fix the problem. It worked like a charm on the products that I do not offer size. (If I was offering one product without any option addition, battery yes no then it deducts the quantity perfectly). But in the t-shirts that comes with options it reduces the count for all of the sizes. I have small medium large sizes. And I also offer 2 different badges on them. If customer selects a small t-shirt with a premium badge(+$3) instead of default one, then it adds $3, otherwise dropdown box already set at default selection(original badge). In that case this code reduces all counts from all sizes. It should deduct the count only from small sizes count. I keep a stock for he shirts but not for the badges.

Thanks
Link to comment
Share on other sites

the easiest solution would be to use one of the existing product fields (like location), set it to 1 if you want to apply the special stock management.

You'll have to modify this code again and also /classes/Cart.php

in Cart.php, look for the following line (in the function getProducts()

p.`quantity`, p.`price`, p.`reduction_price`, p.`reduction_percent`, p.`reduction_from`, p.`reduction_to`, p.`weight`, p.`out_of_stock`, p.`active`, p.`date_add`, p.`date_upd`,


and change it to

p.`quantity`, p.`location`, p.`price`, p.`reduction_price`, p.`reduction_percent`, p.`reduction_from`, p.`reduction_to`, p.`weight`, p.`out_of_stock`, p.`active`, p.`date_add`, p.`date_upd`,



Now change Product.php to

   public static function updateQuantity($product)
   {
       if (!is_array($product))
           die (Tools::displayError());

       if (Pack::isPack(intval($product['id_product'])))
       {
           $products_pack = Pack::getItems(intval($product['id_product']), intval(Configuration::get('PS_LANG_DEFAULT')));
           foreach($products_pack AS $product_pack)
           {
               $tab_product_pack['id_product'] = intval($product_pack->id);
               $tab_product_pack['id_product_attribute'] = self::getDefaultAttribute($tab_product_pack['id_product'], 1);
               $tab_product_pack['cart_quantity'] = intval($product_pack->pack_quantity * $product['cart_quantity']);
               self::updateQuantity($tab_product_pack);
           }
       }

       $result = Db::getInstance()->getRow('
       SELECT `quantity`
       FROM `'._DB_PREFIX_.($product['id_product_attribute'] ? 'product_attribute' : 'product').'`
       WHERE `id_product` = '.intval($product['id_product']).($product['id_product_attribute'] ?
       ' AND `id_product_attribute` = '.intval($product['id_product_attribute']) : ''));

       if (!Configuration::get('PS_STOCK_MANAGEMENT'))
           return true;
       if (self::isAvailableWhenOutOfStock($product['out_of_stock']) AND intval($result['quantity']) == 0)
           return -1;

       if ($result['quantity'] < $product['cart_quantity'])
       {
           Db::getInstance()->Execute('
           UPDATE `'._DB_PREFIX_.($product['id_product_attribute'] ? 'product_attribute' : 'product').'`
           SET `quantity` = 0
           WHERE `id_product` = '.intval($product['id_product']).($product['location'] == 1 && $product['id_product_attribute'] ?
           ' AND `id_product_attribute` = '.intval($product['id_product_attribute']) : ''));
           return false;
       }

       Db::getInstance()->Execute('
       UPDATE `'._DB_PREFIX_.'product'.($product['id_product_attribute'] ? '_attribute' : '').'`
       SET `quantity` = `quantity`-'.intval($product['cart_quantity']).'
       WHERE `id_product` = '.intval($product['id_product']).
       ($product['location'] == 1 && $product['id_product_attribute'] ? ' AND `id_product_attribute` = '.intval($product['id_product_attribute']) : ''));
       return true;
   }

Link to comment
Share on other sites

I think we are almost there. This change deducted 1 from the ordered t-shirt. But it did not reduce 1 from the same size but with different attribute. When there is an order it should deduct 1 from both of the sizes, since I modify the same t-shirt. I can sell the same t-shirt with or without an option. In that case it should deduct 1 from all. I attached an image.

I really appreciate your help. Thanks

27982_5Bzyjxzc7g6Tq3OaMOBq_t

Link to comment
Share on other sites

I did not get "And set the location filed to 1 for product". May be that is why it did not work.

That is the most important part, otherwise how will prestashop know which should have the attribute based quantity and which will be product based...
Link to comment
Share on other sites

In the backoffice, go to edit the products that should have the new quantity change, and in the "location" field (at the the top there are 4 textboxes, reference, EAN supplier reference and location) enter 1
This will apply the new quantity change only to those products

Link to comment
Share on other sites

  • 1 month later...

tomerg3, I tried making the change you suggested in the post beginning: Here’s the complete function for PS 1.3, try it out and let me know (I did not test it).

I have an item that I want to have a qty of 2, regardless of how many combinations there are. I have 3 options, Atlas, Cigar and European (pen types). Each combination has a qty of 2. Even after making the suggested changes to Product.php, I can order 2 of each, rather than being limited to to 2 total.

The site is www.bluepigpens.com. It's turning into a bit of an inventory nightmare. Aside from having 79 different materials, each with their own inventory and ability to be made into several pen styles, there are also multiple trim options. I am thinking I'm going to have to force buyers to choose the material and pen type as one product and the trim style as another in order to allow the shop owner to use PrestaShop to keep accurate inventory.

Any suggestions?

Link to comment
Share on other sites

  • 1 month later...

I have also this problem. I have a shop selling football boots, each having 6 or 7 PM, and 4 types of personalization. For example I have 4 boots brand "Nike" and when the customer chooses to 4 units of size 42 with custom type 1, the amounts deducted from the combination, but not deduct the amount of all sizes. So I still have size 42 in another combination, and that's a lie! I have no stock of size 42.

Anyone have a solution? It is a serious problem ...

Thank you very much and sorry for my english

Link to comment
Share on other sites

  • 2 months later...

has this been solved? I sell chess boards. I have 10 of them. They can be sold in combination with a number of chess pieces. But If a customer buys a board with one set of pieces, i now have 9 boards available across several products. How can i reduce the quantity across the site for these boards which all appear as an attribute group?

Link to comment
Share on other sites

  • 4 months later...

This solution is perfect and is exactly what im looking for but it does not work with prestashop 1.4 as the products.php file looks way different. Tomer can you please help out? What kind of modifications are required to make this work in the 1.4?

many thanks, christian

Link to comment
Share on other sites

  • 2 weeks later...

The coding you provided will solve my biggest problem, which is tracking my tshirt designs, so THANK YOU! of course, it could also cause potential problems trying to sell other products where you may not want the inventory levels to drop in sync. An on/off checkbox for each item would be preferred obviously.

To completely solve my problem I would need something more complicated. Tell me if this is just a pipe dream and

a. They'll more than likely never add this functionality to the software.
b. It's too complicated to write, even as a mod and it's doubtful anyone ever would.
c. You have another idea of how I could achieve my goal.

I think this is what a lot of people are looking for. What I'm trying to do is very simple really. I've tried packs, the combinations... anything and everything i can think of and I'm tapped out on ideas.

Basically I have two items that I combine to make into one and I want to track inventory on both.

Item: Tshirt Design
Group: Shirt Size
Att: s, m, l

I might have 10 different tshirt designs, so I thought I would set each design up as it's own item, so someone would click on the design then select a size. The designs are NOT pre-printed however, meaning that I want the item number to drop with each purchase, but I also want the att number to drop with each purchase - basically I want to track two inventories. Is this possible?

To complicate it further, I would also love to have the same attribute inventory be used for different items, so whether they buy an octopus design, an elephant design, etc... the overall number of tshirts drops with each purchase; otherwise I have to dedicate a certain amount of shirts to each design. That way, I'm tracking how many thirts I have as well as how many of each design I have. So for this to totally work, I would need:

a. The attribute numbers not to override the item numbers, but intead, let inventory decrease/increase on both.

b. The same attribute inventory to be able to be used by multiple items.

To anyone who takes a moment to answer, THANK YOU SO MUCH! I know by helping me, you'll be helping hundreds of other people. I appreciate it.

Link to comment
Share on other sites

  • 1 month later...
  • 1 month later...
  • 1 month later...
  • 2 months later...
  • 4 weeks later...
  • 4 weeks later...

Hi,

 

I just faced the same problem. I worked out a partial solution for prestashop 1.4.x.

 

My products are custom "limited edition" tshirts with combinations for size (small, medium, large, etc) and style (men's, women's). Since the shirts are Limited Edition I needed the quantity to span ALL the attributes, like the OP. So if one customer buy's a men's Large shirt, even the small and medium quantities would decrease.

 

The code below will keep the quantity for all combinations the same for a product. i.e when someone buys it, or when you edit any combination on the combinations page, they all will change to the same quantitiy. I have no idea if this will create any other side effects, but it seems to work for me (so far).

 

Anyway, here is the code. Just place it in a file named StockMvt.php in <prestashop root>/overrides/classes/StockMvt.php

 

<?php
class StockMvt extends StockMvtCore {
   public function add($autodate = true, $nullValues = false, $update_quantity = true) {
    if (!$update_quantity)
	    return true;
    if ($this->id_product_attribute) {
	    $product = new Product((int) $this->id_product, false, Configuration::get('PS_LANG_DEFAULT'));
	    return (Db::getInstance()->Execute(
		    'UPDATE `' . _DB_PREFIX_ . 'product_attribute`
		    SET `quantity` = quantity+' . $this->quantity . ' WHERE `id_product` = ' . (int) $this->id_product) &&
	    $product->updateQuantityProductWithAttributeQuantity());
    }
    else
	    return Db::getInstance()->Execute('
   UPDATE `' . _DB_PREFIX_ . 'product`
   SET `quantity` = quantity+' . (int) $this->quantity . '
   WHERE `id_product` = ' . (int) $this->id_product);
   }
}
?>

 

 

If someone finds a better way, please post here because this is a much needed feature of presta!

  • Like 1
Link to comment
Share on other sites

  • 2 weeks later...
  • 10 months later...
Hi, I just faced the same problem. I worked out a partial solution for prestashop 1.4.x. My products are custom "limited edition" tshirts with combinations for size (small, medium, large, etc) and style (men's, women's). Since the shirts are Limited Edition I needed the quantity to span ALL the attributes, like the OP. So if one customer buy's a men's Large shirt, even the small and medium quantities would decrease. The code below will keep the quantity for all combinations the same for a product. i.e when someone buys it, or when you edit any combination on the combinations page, they all will change to the same quantitiy. I have no idea if this will create any other side effects, but it seems to work for me (so far). Anyway, here is the code. Just place it in a file named StockMvt.php in /overrides/classes/StockMvt.php
 id_product_attribute) { $product = new Product((int) $this->id_product, false, Configuration::get('PS_LANG_DEFAULT')); return (Db::getInstance()->Execute( 'UPDATE `' . _DB_PREFIX_ . 'product_attribute` SET `quantity` = quantity+' . $this->quantity . ' WHERE `id_product` = ' . (int) $this->id_product) && $product->updateQuantityProductWithAttributeQuantity()); } else return Db::getInstance()->Execute(' UPDATE `' . _DB_PREFIX_ . 'product` SET `quantity` = quantity+' . (int) $this->quantity . ' WHERE `id_product` = ' . (int) $this->id_product); } } ?> 

If someone finds a better way, please post here because this is a much needed feature of presta!

 

 

Yeah, I'm struggling with a similar issue and that doesn't appear to have fixed it.

 

Here's an outline of my problem:

I have 1 piece of art to sell. I want to offer it with or without a frame. So the combinations are:

Without a Frame

With a Black Frame

With a White Frame

That gives me 3 combinations of something that I only have one of.

And now I'm stumped. I'd call it 'sharing quantities between combinations'.

 

In truth I have 1 available in 4 different sizes (all with or without a black frame) so maybe mine is more complicated and might be why the above fix didn't work. Also I'm on Prestashop 1.5...could be why too.

 

Seems like a lot of others have had a similar problem. Has anyone got a fix yet?

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

  • 3 months later...

I've been searching the forums for a while and nothing like this exists... yet.

 

We do hats, with specific sizes - but the same design. so, we don't want six products with the same image - we have that already with Zencart! Each size has it's own quantity, but it's part of a main product. That's the issue - combinations but without the linkages so you don't end up with 40 x 6 x 10 x 3 products - when you have only 40.

 

*sigh* What ever happened to programmers that knew arrays and tables. *chuckle*

 

If we get a fix, or module made up, I'll post back.

 

Good luck.

 

The search goes on.

Link to comment
Share on other sites

  • 3 weeks later...

Looks like I just asked the same question:

 

http://www.prestashop.com/forums/topic/248085-stock-management-reduce-main-product-quantity-for-any-combination/page__p__1231576?do=findComment&comment=1231576

 

So if we assume there's no specific solution, how are people handling this?

 

One idea is not to have stock management at all. That is, you allow ordering and perhaps let customers know manually if you are out of stock and offer them a backorder.

Link to comment
Share on other sites

  • 4 months later...
  • 4 years later...

Very old topic, but the only one with a real solution.

I am looking for a 1.6 fix.

It's okay to update all the combination's stock when a customers bought just one combination.

But can't find this, because it is too old:
 

WHERE `id_product` = '.intval($product['id_product']).
($product['id_product_attribute'] ? ' AND `id_product_attribute` = '.intval($product['id_product_attribute']) : ''));



I found this:
 

            ), 'id_product = '.$this->id.' AND id_product_attribute = '.(int)$id_product_attribute);


I know there is a paid solution, 40 USD.. but don't want to spend it for this.

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...