2

Hello i need to use magento to sell a product that will have custom price rules.
the rule will depend by the quantity of this product sold.
I know that magento can make special rule, if a customer by ++ quantity of this product, but me i need to apply different rule and i cant find the way.
For example, product bought from customers first 100 times, price is :100$
product bought 200-500 times, price is 400$
500-1000times, product is 800$
1000 - > product is fixed price 1000$
is it possible for magento to do this?



Thank you

Josh Pennington
  • 6,418
  • 13
  • 60
  • 93
spanakorizo
  • 81
  • 4
  • 18

2 Answers2

8

You can do this by creating a module that uses the checkout_cart_product_add_after and checkout_cart_update_items_after observers.

Then inside your observer class you can put the following function in to set the price:

public function yourAddToCartFunction($observer) {

    if ($p = $observer->getQuoteItem()->getParentItem()) {
        $discount_amount = $your_discount_logic;
        $p->setCustomPrice($discount_amount)->setOriginalCustomPrice($discount_amount); #configs
    } else  {
        $p = $observer->getQuoteItem();
        $discount_amount = $your_discount_logic;
        $p->setCustomPrice($discount_amount)->setOriginalCustomPrice($discount_amount); #simple products
    }
}

You will more than likely need a different function for the cart update observer call. The one above is for the cart_add_after event. The function for the cart update is nearly identical except you have to go through the cart object to get the logic.

public function yourCartUpdateFunction($observer) {
    $cart = $observer->cart;
    $quote = $cart->getQuote();

    foreach($quote->getAllVisibleItems() as $item) {
        if ($p = $item->getParentItem()) {
            $discount_amount = $your_discount_logic;
            $p->setCustomPrice($discount_amount)->setOriginalCustomPrice($discount_amount); #configs
        } else {
            $discount_amount = $your_discount_logic;
            $item->setCustomPrice($discount_amount)->setOriginalCustomPrice($discount_amount); #simple products
        }
    }
}

The reason you would want the second function is if the logic needs to happen again if the cart is updated. If the price is going to stick forever no matter what happens once it is in the cart, you can probably exclude the second function.

MASSIVE EDIT:

Ok this is how I would do this. I am assuming you are starting with a basic, functional module.

The first thing you want to do is setup your observers in your modules config.xml file. In this case you are going to use be using the checkout_cart_product_add_after and checkout_cart_update_items_after observers. You will set that up by adding the following to your config.xml file:

<config>
    ...
    <global>
        ...
        <events>
            <checkout_cart_product_add_after>
                <observers>
                    <call_this_something_unique>
                        <type>singleton</type>
                        <class>Ocaff_Custompricing_Model_Cart_Observer</class>
                        <method>calculateAddToCart</method>
                    </call_this_something_unique>
                </observers>
            </checkout_cart_product_add_after>

            <checkout_cart_update_items_after>
                <observers>
                    <call_this_something_unique_2>
                        <type>singleton</type>
                        <class>Ocaff_Custompricing_Model_Cart_Observer</class>
                        <method>calculateCartUpdate</method>
                    </call_this_something_unique_2>
                </observers>
            </checkout_cart_update_items_after>
        </events>
        ...
    </global>
    ...
</config>

Basically what this does is it tells Magento that when the checkout_cart_product_add_after event is triggered, run the calculateAddToCart method of the Ocaff_Custompricing_Model_Cart_Observer class and also to run the calculateCartUpdate when the checkout_cart_update_items_after event is triggered.

Ok now that you have your configuration put together you can create your model. In the case of this example the class would be located in the /app/code/local/Ocaff/Custompricing/Model/Cart/Observer.php file (however you will put the class that matches your module)

Ok now in your Observer.php file you are going to put the following code:

<?php

class Ocaff_Custompricing_Model_Cart_Observer {

    public function calculateAddToCart($observer) {
        if ($p = $observer->getQuoteItem()->getParentItem()) {
        $discount_amount = Mage::helper('custompricing')->calculatePrice($p);
        $p->setCustomPrice($discount_amount)->setOriginalCustomPrice($discount_amount); #configs
    } else  {
        $p = $observer->getQuoteItem();
        $discount_amount = Mage::helper('custompricing')->calculatePrice($p);
        $p->setCustomPrice($discount_amount)->setOriginalCustomPrice($discount_amount); #simple products
    }
    }

    public function calculateCartUpdate($observer) {
        $cart = $observer->cart;
    $quote = $cart->getQuote();

    foreach($quote->getAllVisibleItems() as $item) {
        if ($p = $item->getParentItem()) {
            $discount_amount = Mage::helper('custompricing')->calculatePrice($prpoduct);
            $p->setCustomPrice($discount_amount)->setOriginalCustomPrice($discount_amount); #configs
        } else {
            $discount_amount = Mage::helper('custompricing')->calculatePrice($p);
            $item->setCustomPrice($discount_amount)->setOriginalCustomPrice($discount_amount); #simple products
        }
    }
    }

}

Ok a few notes here. both functions take a single paramater that I have called observer (and pretty much everywhere else calls it that too). This is a single variable that holds all the information that Magento passes along to all the functions that handle the event. In the case of the calculateAddToCart function we are only grabbing the Quote Item (which is confusing since in checkout with Magento there are quite a few different objects that kind of all represent the same thing if you are looking at it from 50,000 feet). What this function does is takes the quote item and determines if the product that was added to cart is a simple or configurable product and takes that appropiate action.

The calculateCartUpdate function basically does the exact same thing, but it has to instead iterate through all the products in the cart since in Magento you update the entire cart all at once, not every line item.

In both functions you will notice that I am updating the Custom Price and the Original Custom Price field. I am not 100% sure why you have to update both (and really why ask questions if it works :))

Ok now you may or may not notice that I have done something a little less than conventional for figuring out the $discount_amount variable. I am calling a helper function to get the price that the product should be set to. I put this into a helper because you may want to access that logic elsewhere in the system and I generally prefer to put that kind of logic into a Helper (in fact I am pretty sure you are going to want to use this on the product and category pages since you are modifying the way pricing is working for some products and customers get mad when prices change up unexpectadly).

Ok now onto the helper function. Since I am not 100% sure what logic you really want in the end, we are just going to keep this function simple and have it return $2. This will make everything that goes into the cart $2 no matter what its price actually is. This is going to be where you figure out your logic for pricing.

<?php 

class Ocaff_Custompricing_Helper_Data {

    public function calculatePrice($product=null) {

        // Your custom logic will go here. Whatever number you come up with and return will be the price that the item is set to

        return 2;

    }

}

For the most part this should get you about 90% of where you want to be. Try this out and post questions and I'll do my best to help you.

Another Edit: Activating Helpers in config.xml

Put this code inside your config.xml file right after your observers block detailed above. This will tell Magento the location of the helper files for your module.

<helpers>
    <custompricing>
    <class>Ocaff_Custompricing_Helper</class>
    </custompricing>
</helpers>
Josh Pennington
  • 6,418
  • 13
  • 60
  • 93
  • hello Josh and thanks for your reply. I was thinking maybe do something more simple. make 4 identical products ,different quantitys and different prices. When the product with lower price and quantity 100 goes out of stock then automatically product 2 with quantity 300 and price 400$ will be active etc.But is there any way for magento to do this, maynbe a cronjob?If you can explain a little more also your 1st method i would be glad. – spanakorizo Oct 18 '11 at 15:47
  • You could write a script that checks a products isSaleable() attribute and if that comes back as false, set the product status to inactive and then activate the next product in the series. You would want to have that run every few minutes depending on traffic. The method I proposed would not require a script and you would only need to create 1 product. – Josh Pennington Oct 18 '11 at 18:30
  • Can you be a little more specific about the module and how to create?i follow this guide (http://www.magentocommerce.com/wiki/5_-_modules_and_development/0_-_module_development_in_magento/customizing_magento_using_event-observer_method) and inside the observer.php, i paste your code but i see no change in my product. Thank you. – spanakorizo Oct 19 '11 at 15:55
  • How much do you know about creating a Magento module? Do you know how to create a module and just need to know how to get the observer running? Or do you need to know how to get this going from scratch? – Josh Pennington Oct 19 '11 at 18:30
  • Josh i know the basic,actually maybe less for creating a module. I would be super glad if you can point me from scratch. Is the link i post in magento identical or is it an outdated version? Cause i follow all the steps but nothing changed in the product. Thank you once again. – spanakorizo Oct 19 '11 at 19:36
  • Your link is fairly recent. So I would imagine that it should work (however I did not follow through the entire thing so I cannot vouch for that code). To get you going on the basics I would recommend this article http://www.magentocommerce.com/knowledge-base/entry/magento-for-dev-part-1-introduction-to-magento. It is written by Alan Storm who I would have to say is a legend when it comes to Magento. Read that and get the basics down and I will try to post something to help you here later tonight/tomorrow. It could be a long post so it will take some time. – Josh Pennington Oct 19 '11 at 19:53
  • Thank you so much again, Josh. I will read the basics and i will look forward for your next post here :) – spanakorizo Oct 19 '11 at 20:48
  • Diglin, i opened this discussion cause i needed some help. Sometimes everything is not about money in this world. People have the knowledge and can trully help each other, with no other advance. I need this for non commercial purpose, so i don't have to hire nobody. If Josh can spare some of his free time, whenever he feels like helping more i will kindly wait for his answer. – spanakorizo Oct 20 '11 at 21:24
  • Josh for once again much appreciated. However there is problem when adding any product to the cart. The page stays blank (not even header) when parsing the url: checkout/cart/add/uenc/(product_long)...Cache is disabled, pages are indexed and i see no error in /var/report to figure out the problem. Steps for the module: I create app/etc/modules/Ocaff.xml and app/code/local/Ocaff/Custompricing/etc/config.xml | Ocaff/Custompricing/Helper/Data.php | Ocaff/Custompricing/Model/Observer.php.Inside the files i paste your code. Do i need something else? Thanks again for all your efforts. – spanakorizo Oct 21 '11 at 02:40
  • The good news is it sounds like the observer is being picked up. The bad news is there is an error somewhere in the code. Follow the instructions in this blog post http://inchoo.net/ecommerce/magento/configuring-magento-for-development/ and it should start showing the errors (you can probably skip the last 3 things on that list for now). Once you get an error to display we will have a better idea where the problem is. – Josh Pennington Oct 21 '11 at 10:09
  • Now the page doesnt stay blank, instead there is an error in the frontend that cannot add items to cart. I made the logs and uploaded to pastebin.com/Ga1YjsRR .Strange is that in first lines it complains that cannot find file or directory. All the files are identical with your code. I uploaded my etc/modules/config.xml here: pastebin.com/7p4PY9AC .The other files are in app/code/local/Ocaff/Custompricing (etc/config.xml)(Helper/Data.php)(Model/Cart/Observer.php)as you point me. Magento version is 1.6, Snow leopard local server with rewrites on. Thank you! – spanakorizo Oct 21 '11 at 14:33
  • It looks like in your modules config.xml file you do not have Helpers "activated". Look in the post for the latest edit how to get that in there. – Josh Pennington Oct 21 '11 at 14:43
  • same error Josh. But why the log starts with: Warning: include(Mage/Custompricing/Helper/Data.php): failed to open stream: No such file or directory ? I have everything in app/code/local/Ocaff/Custompricing/ ,no Mage.i posted my config.xml now in http://pastebin.com/PYQ3Ljgz . The error log is the same,here is after adding the helpers: http://pastebin.com/ZZamMArG . I double checked all my folders for a typo or Uppercase error,but everything looks ok. – spanakorizo Oct 21 '11 at 16:10
  • Perfect!now it gives price 2$.(can i do this only for virtual products?) So i guess now we need to edit the Helper/Data.php so we will set a rule like: if>item quantity:0-100 =return 2 , else>item quantity:101-300=return 10 (for price) ,and if quantity=500 until 9999 return allways 100. I will need 4 stages of quantity. It sounds difficult, you think it will be possible? Also, would it be possible after adding to cart and showing the custom_price to echo a message like "special price for the first 100 products" , under the product name, or under the price? – spanakorizo Oct 21 '11 at 16:46
  • 2
    I think we have gotten about as far as we should for doing this on StackOverflow. Anything beyond this will likely not be useful to others and constant editing is going to make this complicated. I would recommend that you put the checkbox for my answer email me your contact info and we continue on. You can email me at jpenn@bouncr.com – Josh Pennington Oct 21 '11 at 16:58
  • yeah you are right. I will google and if there is something i'll need to ask i will contact you.Thank you very much for all your efforts! – spanakorizo Oct 21 '11 at 17:16
1

This is a tier prices feature, you don't need to create a catalog price rule. Check in the product edit page when you manage your products in the backend, the tab Prices and see the option "Tier Prices"

Sylvain Rayé
  • 2,456
  • 16
  • 23
  • It seems that your question was not very clear for me. But I think I begin to understand more the "nuance". If a customer buy at the same time a certain quantity of products, you can use the tier prices to provide to a customer price higher or lower depending on the quantity. But it seems that you are looking for a solution for a returned customer who has already bought the product which has a rule that you wish. Magento doesn't support it without doing by yourself a module using the events like Josh Pennington wrote to you. I let you with him. – Sylvain Rayé Oct 19 '11 at 21:50