0

I've created a bundled product which contains only one bundle items witch a default QTY of 3 (so you buy 3 times the same item). I've set it up like this: http://cloud.philippspiess.com/image/1j2J2z0R0y0M

Now I want to use M2E Pro to list this item on eBay and it calculates the QTY based on the total quantity of the items. So if I have 3 bundle items it will also give me 3 bundled products - although this should only be one.

Where can I change the stock calculation for a bundled product? I've found out that Mage_Bundle_Model_Resource_Indexer_Stock uses the MIN aggregation on an SQL query but as I'm very new to Magento I don't know if this is the right file to change this behavior.

Also: If one bundle is sold - will it subtract 3 instances of the bundle item or just one?

1

But...This isn't a bundle.

Here's some reading on grouped versus bundle:

But for real, this is a sales rule, with minimum cart quantity and discount.

| improve this answer | |
  • The thing is that this bundle is only for Ebay (using the M2E pro plugin) and I can't really set a sales rule there. My idea was to create an auction of this bundle which contains three products. If a bundle can has the option to contain more than one item in multiple quantity the sql MIN can be considered a bug because you can't sell the product 2 times only having 2 items when you would need 3 for a sale. – Philipp Spiess Jan 16 '15 at 11:20
  • What's keeping you from making it a grouped product? Remember, this isn't something configurable by the user, like a gaming system, which is what bundles are made for. I suppose you really need a different complex product, which can only be ordered as one product and does the stock mutations for several simple products behind the scenes. Key being that the quantities of the simples are not user controllable. – Melvyn Jan 16 '15 at 16:51
  • Thanks for the input. I will try it out early next week! :) – Philipp Spiess Jan 17 '15 at 11:57
0

I had to solve the same problem. I don't remember all the reasons why as it was several years ago, but neither bundle or grouped product types worked correctly. My first solution was to create a new product type similar to bundle. I called it Assembly. Would allow multiple items to be combined into a single item to create... an assembly. You could then build or break up an assembly. Building an assembly would remove all the included items from their simple product qty and increase the assembly qty, and vice versa. This actually worked great inside magento. Unfortunately, m2epro is very limited and can only work with a couple product types, and not a custom product type.

I had an additional requirement you may or may not need that added some complexity. I wanted the qty on ebay to be different from my instock qty. I wanted it to include qty available from my mfg that I could get overnight or drop ship. I can provide more detail and any code you can't figure out, but its a lot in a lot of different places so message me if you need still need help.

Here are the steps:

Created an attribute for the following:

  • eBayQty -> you'll set m2epro to use this attribute for qty
  • MfgQty -> I wrote a cron job that updates this from the mfg website
  • AssemblyID (1-5) -> Magento ID of product you wish to include in the assembly
  • AssemblyQty (1-5) -> Qty of Magento ID to include in the assembly
  • isAssembly -> Flag to easily identify if you need to update the qty on save

Then create an observer for catalog_product_prepare_save that calculates the qty you want listed on ebay, and set eBayQty. For my purposes, I also set the assembly item qty to the available number of items I could build based on the qty of simple products I have in stock. This has to be done in catalog_product_save_after.

Here is the core code to perform most of what I'm doing.

config.xml
<?xml version="1.0" encoding="UTF-8"?>
<config>
    <modules>
        <Vampower_UpdateEbayQty>
            <version>0.0.1</version>
        </Vampower_UpdateEbayQty>
    </modules>

    <!-- Configure our module's behavior in the global scope -->
    <global>
        <!-- Defining models -->
        <models>
            <!--
                Unique identifier in the model's node.
                By convention, we put the module's name in lowercase.
            -->
            <vampower_UpdateEbayQty>
                <!--
                    The path to our models directory, with directory
                    separators replaced by underscores
                -->
                <class>Vampower_UpdateEbayQty_Model</class>
            </vampower_UpdateEbayQty>
        </models>
        <events>
          <catalog_product_prepare_save>
            <observers>
                <vampower_UpdateEbayQty>
                    <class>vampower_UpdateEbayQty/observer</class>
                    <method>UpdateEBayInfo</method>
                    <type>singleton</type>
                </vampower_UpdateEbayQty>
            </observers>
          </catalog_product_prepare_save>
            <catalog_product_save_after>
                <observers>
                    <vampower_UpdateEbayQty>
                        <class>vampower_UpdateEbayQty/observer</class>
                        <method>qtyUpdate</method>
                        <type>singleton</type>
                    </vampower_UpdateEbayQty>
                </observers>
            </catalog_product_save_after>
        </events>
    </global>
</config>

Observer.php
public function UpdateEBayInfo(Varien_Event_Observer $observer)
{
    $_newProduct = $observer->getProduct();
    $this->ebayQtyUpdate($_newProduct);
}

public function ebayQtyUpdate($_newProduct)
{
    $isAssembly = $_newProduct->getData("is_assembly");
    $ProductID = $_newProduct->getId();
    $Name = $_newProduct->getName();

    if ($isAssembly)
    {
        $PossibleQty = $this->GetAssemblyQty($_newProduct);
    }
    else
    {
        $PossibleQty = $_newProduct->getStockItem()->getQty();
    }

    $EBayQty = $this->GetEBayQty($_newProduct, $PossibleQty);
    $_newProduct->setData('ebay_qty', $EBayQty);
}

public function qtyUpdate(Varien_Event_Observer $observer)
{
    $_newProduct = $observer->getEvent()->getProduct();

    $isAssembly = $_newProduct->getData("is_assembly");
    $ProductID = $_newProduct->getId();
    $Name = $_newProduct->getName();

    if ($isAssembly)
    {
        $NewQty = $this->GetAssemblyQty($_newProduct);
        $_stock->getStockItem();
        $_stock->setQty($NewQty);
        $_stock->save();
    }
    else
    {
        $this->UpdateAssembliesFromSimple($ProductID);
    }
}

private function UpdateAssembliesFromSimple($ProductID)
{
    Mage::log("--------- UPDATE ASSEMBLIES FROM SIMPLE -------", null, 'Update-Qty-EBayDescription.log');
    $collection = Mage::getModel('catalog/product')->getCollection();
    $collection->addAttributeToSelect('name');
    $collection->addAttributeToSelect('assembly_item_1');  
    $collection->addAttributeToSelect('assembly_item_2');
    $collection->addAttributeToSelect('assembly_item_3');
    $collection->addAttributeToSelect('assembly_item_4');
    $collection->addAttributeToSelect('assembly_item_5');
    $collection->addAttributeToSelect('assembly_qty_1');  
    $collection->addAttributeToSelect('assembly_qty_2');
    $collection->addAttributeToSelect('assembly_qty_3');
    $collection->addAttributeToSelect('assembly_qty_4');
    $collection->addAttributeToSelect('assembly_qty_5');
    $collection->addAttributeToSelect('mfg_qty');
    $collection->addAttributeToSelect('ebay_max_qty');
    $collection->addAttributeToSelect('ebay_use_mfgqty');

    $collection->addAttributeToFilter(array(
                                        array("attribute"=>"assembly_item_1","eq"=>$ProductID)
//                                          array("attribute"=>"assembly_item_2","eq"=>$ProductID),
//                                          array("attribute"=>"assembly_item_3","eq"=>$ProductID),
//                                          array("attribute"=>"assembly_item_4","eq"=>$ProductID),
//                                          array("attribute"=>"assembly_item_5","eq"=>$ProductID)
                                    ));

    foreach ($collection as $product) 
    {
        $PossibleQty = $this->GetAssemblyQty($product);
        $_stock = Mage::getModel('cataloginventory/stock_item')->loadByProduct($product);
        $_stock->setQty($PossibleQty);
        $_stock->save();

        $EBayQty = $this->GetEBayQty($product, $PossibleQty);
        $product->setData('ebay_qty', $EBayQty);
        $product->save();
    }
}

private function GetAssemblyQty($product)
{
    $PossibleQty = 0;

    $AssemblyItems = $this->GetAssemblyItems($product);

    $i=0;
    foreach ($AssemblyItems as $AssemblyItem)
    {
        $AssemblyID = $AssemblyItem["ProductID"];
        $AssemblyItemCount = $AssemblyItem["ProductQty"];

        $_assemblyProduct = Mage::getModel('catalog/product')->load($AssemblyID);
        $_assemblyStock = Mage::getModel('cataloginventory/stock_item')->loadByProduct($_assemblyProduct);
        $assemblyQty = $_assemblyStock->getQty();

        $TempPossibleQty = round(($assemblyQty / $AssemblyItemCount)-0.5, 0);

        if (($i>0) && ($TempPossibleQty < $PossibleQty))
            $PossibleQty = $TempPossibleQty;
        else if ($i == 0)
            $PossibleQty = $TempPossibleQty;

        $i++;
    }

    Mage::log("PossibleQty: " . $PossibleQty, null, 'Update-Qty-EBayDescription.log');

    return($PossibleQty);


}

private function GetAssemblyItems($product)
{
    $ID = $product->getId();

    $AssemblyItems = Array();
    $nAssemblyItems = 5;
    for ($i=1; $i<count($nAssemblyItems)+1; $i++)
    {
        $var1 = "assembly_item_".$i;
        $var2 = "assembly_qty_".$i;
        if ($product->getData("assembly_item_".$i) > 0)
        {
            $AssemblyItems[$i]["ProductID"] = $product->getData("assembly_item_".$i);
            $AssemblyItems[$i]["ProductQty"] = $product->getData("assembly_qty_".$i);
        }
    }
    return($AssemblyItems);
}

Its still a work in progress solution, so test everything well. The only known bug at the moment is when you update the qty in a simple product, it needs to find all assemblies that contain that simple product and update the qty for that item also. I do this in UpdateAssembliesFromSimple(). The code I've found to filter by an attribute works fine for a single attribute, but wasn't working for multiple attributes. Currently I'm only using a single simple product per assembly, so I haven't fixed that issue yet. You'll see it commented out in the code.

Hope this helps. Its been a work in progress for several years. Some of the steps were very difficult to find documentation about.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.