Change subtotal with given price & quantity (custom attribute) - magento

My price is for example 10,00 €
this price is for 100 g
the customer can add any g in the quantity field for example 300
magento has now a subtotal of 3000, its ok but not for my needs here.
i need to do:
if price & quantity is set, get subtotal / price quantity, set new subtotal
where can i put my modifications for this?
Thank you very much!
Dennis
Edit
and the third try of observer (not working atm, no error, nothing happens):
class Xyz_Catalog_Model_Price_Observer
{
public function __construct()
{
}
public function apply_quantity_order($observer)
{
$order = $observer->getEvent()->getOrder();
$pricequantity = $order->getPricequantity();
if($pricequantity != ''){
$old_sub_total = $order->getTotals();
$new_sub_total = $old_sub_total / 100;
$order->setTotals($new_sub_total);
} else {}
return $this;
}
public function apply_quantity_quote($observer)
{
$quote = $observer->getEvent()->getQuote();
$pricequantity = $quote->getPricequantity();
if($pricequantity != ''){
$old_sub_total = $quote->getTotals();
$new_sub_total = $old_sub_total / 100;
$quote->setTotals($new_sub_total);
} else {}
return $this;
}
}
XML:
<?xml version="1.0"?>
<config>
<global>
<models>
<xyzcatalog>
<class>Xyz_Catalog_Model</class>
</xyzcatalog>
</models>
<events>
<sales_order_save_after>
<observers>
<xyz_catalog_price_observer>
<class>Xyz_Catalog_Model_Price_Observer</class>
<method>apply_quantity_order</method>
</xyz_catalog_price_observer>
</observers>
</sales_order_save_after>
<sales_quote_save_after>
<observers>
<xyz_catalog_price_observer>
<class>Xyz_Catalog_Model_Price_Observer</class>
<method>apply_quantity_quote</method>
</xyz_catalog_price_observer>
</observers>
</sales_quote_save_after>
</events>
</global>
</config>

Rather than overriding sub-total calculation function, I suggest to try events - sales_quote_save_after and sales_order_save_after.
You can get quote and sales in observer method by
$observer->getEvent()->getOrder() //for order
$observer->getEvent()->getQuote() //for quote
Then modify the subtotal accordingly.
Edit: It might be just hint how can you modify sub total.
Edit2: You have to add event observer in your config as shown:
<sales_order_save_after>
<observers>
<yourext>
<class>yourext/observer</class>
<method>observerMethod</method>
</yourext>
</observers>
</sales_order_save_after>
For detail, have look on Customize Magento using Event/Observer

Take a look # Programmatically add product to cart with price change
public function applyDiscount(Varien_Event_Observer $observer)
{
/* #var $item Mage_Sales_Model_Quote_Item */
$item = $observer->getQuoteItem();
if ($item->getParentItem()) {
$item = $item->getParentItem();
}
// calc special price
$percentDiscount = 5;
$specialPrice = $item->getOriginalPrice() - $percentDiscount;
// Make sure we don't have a negative
if ($specialPrice > 0) {
$item->setCustomPrice($specialPrice);
$item->setOriginalCustomPrice($specialPrice);
$item->getProduct()->setIsSuperMode(true);
}
}

Related

Change price while adding to cart page in magento

I have written a customized code to add different price of product on product page:
Code in: app/code/local/custom/price/etc/config.xml
<?xml version="1.0"?>
<config>
<global>
<models>
<price>
<class>custom_price_Model</class>
</price>
</models>
<events>
<checkout_cart_product_add_after>
<observers>
<custom_price_observer>
<class>price/observer</class>
<method>modifyPrice</method>
</custom_price_observer>
</observers>
</checkout_cart_product_add_after>
</events>
</global>
</config>
Code in : app/code/local/custom/price/Model/Observer.php
class custom_price_Model_Observer
{
public function modifyPrice(Varien_Event_Observer $obs)
{
// Get the quote item
$item = $obs->getQuoteItem();
// Ensure we have the parent item, if it has one
$item = ( $item->getParentItem() ? $item->getParentItem() : $item );
// Load the custom price
$price = "30";
// Set the custom price
$item->setCustomPrice($price);
$item->setOriginalCustomPrice($price);
// Enable super mode on the product.
$item->getProduct()->setIsSuperMode(true);
}
Still its not working. Kindly Help.
You have to do following way to save your custom price.
class custom_price_Model_Observer
{
public function modifyPrice(Varien_Event_Observer $obs)
{
// Get the quote item
$item = $obs->getQuoteItem();
// Ensure we have the parent item, if it has one
$item = ( $item->getParentItem() ? $item->getParentItem() : $item );
// Load the custom price
$price = "30";
// Set the custom price
$item->setCustomPrice($price);
$item->setOriginalCustomPrice($price);
// Enable super mode on the product.
$item->getProduct()->setIsSuperMode(true);
$item>save();
}
}
below is the code i used for apply discount for products after added to cart,i have applied 50% discount for products added to cart and it works for me.
function modifyPrice(Varien_Event_Observer $observer){
$event = $observer->getEvent();
$quote_item = $event->getQuoteItem();
$product_id=$quote_item->getProductId();
$product_price = Mage::getModel('catalog/product')
->load($product_id)
->getPrice();
if($product_price != 0){
$percentDiscount = 0.50;
$specialPrice = $product_price - ($product_price * $percentDiscount);
$quote_item->setOriginalCustomPrice($specialPrice);
}
}

Show cash on delivery methods for some specific cities

HOW to display/hide "Cash on delivery" payment method for some specific cities.
I have tired this link also but not working
This is my observer.php located in app/code/local/MagePsycho/Paymentfilter/Model
class MagePsycho_Paymentfilter_Model_Observer {
public function paymentMethodIsActive(Varien_Event_Observer $observer) {
$event = $observer->getEvent();
$method = $event->getMethodInstance();
$result = $event->getResult();
$currencyCode = Mage::app()->getStore()->getCurrentCurrencyCode();
$checkout = Mage::getSingleton('checkout/session')->getQuote();
$shipping = $checkout->getShippingAddress();
$cashOnDeliveryCities = array('test1','test3');
if(in_array($shipping->getCity(), $cashOnDeliveryCities)){
$result->isAvailable = true;
}else{
$result->isAvailable = false;
}
}
}
This is my config.php located in app/code/local/MagePsycho/Paymentfilter/etc
<frontend>
<events>
<payment_method_is_active>
<observers>
<paymentfilter_payment_method_is_active>
<type>singleton</type>
<class>paymentfilter/observer</class>
<method>paymentMethodIsActive</method>
</paymentfilter_payment_method_is_active>
</observers>
</payment_method_is_active>
</events>
</frontend>
Where i am missing, It showing cash on delivery for all cities not filtering
Thanks
It works for me.
Firstly check, that your observer method is executing. Put something like exit() or die();
As you have already said you'd like to add city restriction only for cash_on_delivery - add following code after $currencyCode = ...
if(!($method instanceof Mage_Payment_Model_Method_Cashondelivery))
{
return;
}
Try to debug Mage_Payment_Model_Method_Abstract::isAvailable. Put some Mage::log in this method and determine at which moment which walue have $checkResult->isAvailable

Magento payment method according to product options

I need to perform the next action when a customer is making the purchase of products:
If there is a product with custom options to display only a method of payment and if no other method.
how to do this ... I'm going crazy
thanks
You can do this event observer
create an extension under app/code/local
Bh_ZeroSubtotalpaymentmethod_Model
File of extension are config.xml under
app/code/local/Bh/ZeroSubtotalpaymentmethod/etc
and it code is
<?xml version="1.0" ?>
<config>
<modules>
<Bh_ZeroSubtotalpaymentmethod>
<version>1.0.1</version>
</Bh_ZeroSubtotalpaymentmethod>
</modules>
<global>
<models>
<zerosubtotalpaymentmethod>
<class>Bh_ZeroSubtotalpaymentmethod_Model</class>
</zerosubtotalpaymentmethod>
</models>
</global>
<frontend>
<events>
<payment_method_is_active>
<observers>
<paymentfilter_payment_method_is_active>
<type>singleton</type>
<class>zerosubtotalpaymentmethod/observer</class>
<method>filterpaymentmethod</method>
</paymentfilter_payment_method_is_active>
</observers>
</payment_method_is_active>
</events>
</frontend>
</config>
and Observer file code
is
<?php
class Bh_ZeroSubtotalpaymentmethod_Model_Observer {
public function filterpaymentmethod(Varien_Event_Observer $observer) {
/* call get payment method */
$method = $observer->getEvent()->getMethodInstance();
if($method->getCode()=='paypal_standard')
{ $quote = $observer->getEvent()->getQuote();
if($this->checkcustomoption()==true){
$result = $observer->getEvent()->getResult();
$result->isAvailable = false;
}
return;
}
if($method->getCode()=='free'){
$quote = $observer->getEvent()->getQuote();
if($this->checkcustomoption()==false){
$result = $observer->getEvent()->getResult();
$result->isAvailable = false;
return;
}
}
return;
}
public function checkcustomoption(){
//To get your cart object (in session) :
$quote = Mage::getSingleton('checkout/session')->getQuote();
//Then, to get the list of items in the cart :
$cartItems = $quote->getAllVisibleItems();
//Then, to get the count for each item :
foreach ($cartItems as $item)
{ // check $item->getProduct() give cart item
$item->getProduct();
if(your_logic_match){
return true;
break;
}
}
retrun false;
}
}
?>
for check and custom option used https://magento.stackexchange.com/questions/17867/get-custom-option-price-in-order blog Gavin answer

Change product price on all pages by using observer Magento

I am learning Magento and I have start learning events and observers. A percentage of amount is added to product by setting in admin product area.
It works fine but the discounted price shows only on product page. Can anybody suggest me how can I change the price through out Magento. I mean change price should go to cart, order etc.
Below is the code for observer
<?php
class Xyz_Catalog_Model_Price_Observer
{
public function __construct()
{
}
/**
* Applies the special price percentage discount
* #param Varien_Event_Observer $observer
* #return Xyz_Catalog_Model_Price_Observer
*/
public function apply_discount_percent($observer)
{
$event = $observer->getEvent();
$product = $event->getProduct();
// process percentage discounts only for simple products
if ($product->getSuperProduct() && $product->getSuperProduct()->isConfigurable()) {
} else {
$percentDiscount = $product->getPercentDiscount();
if (is_numeric($percentDiscount)) {
$today = floor(time()/86400)*86400;
$from = floor(strtotime($product->getSpecialFromDate())/86400)*86400;
$to = floor(strtotime($product->getSpecialToDate())/86400)*86400;
if ($product->getSpecialFromDate() && $today < $from) {
} elseif ($product->getSpecialToDate() && $today > $to) {
} else {
$price = $product->getPrice();
$finalPriceNow = $product->getData('final_price');
$specialPrice = $price - $price * $percentDiscount / 100;
// if special price is negative - negate the discount - this may be a mistake in data
if ($specialPrice < 0)
$specialPrice = $finalPriceNow;
if ($specialPrice < $finalPriceNow)
$product->setFinalPrice($specialPrice); // set the product final price
}
}
}
return $this;
}
}
config.xml
<?xml version="1.0"?>
<config>
<global>
<models>
<xyzcatalog>
<class>Xyz_Catalog_Model</class>
</xyzcatalog>
</models>
<events>
<catalog_product_get_final_price>
<observers>
<xyz_catalog_price_observer>
<type>singleton</type>
<class>Xyz_Catalog_Model_Price_Observer</class>
<method>apply_discount_percent</method>
</xyz_catalog_price_observer>
</observers>
</catalog_product_get_final_price>
</events>
</global>
</config>
Please advise how I can use the new discounted price throughout Magento. Thanks
Here is solution
config.xml
<?xml version="1.0"?>
<config>
<modules>
<Seta_DiscountPrice>
<version>0.1.0</version> <!-- Version number of your module -->
</Seta_DiscountPrice>
</modules>
<global>
<models>
<setadiscountprice>
<class>Seta_DiscountPrice_Model</class>
</setadiscountprice>
</models>
<events>
<catalog_product_get_final_price>
<observers>
<seta_discountprice_price_observer>
<type>singleton</type>
<class>Seta_DiscountPrice_Model_Price_Observer</class>
<method>apply_10</method>
</seta_discountprice_price_observer>
</observers>
</catalog_product_get_final_price>
<catalog_product_collection_load_after>
<observers>
<seta_discountprice_price_observer>
<type>singleton</type>
<class>Seta_DiscountPrice_Model_Price_Observer</class>
<method>apply_view</method>
</seta_discountprice_price_observer>
</observers>
</catalog_product_collection_load_after>
</events>
</global>
</config>
Observer.php
<?php
class Seta_DiscountPrice_Model_Price_Observer
{
public function __construct()
{
}
/**
* Applies the special price percentage discount
* #param Varien_Event_Observer $observer
* #return Seta_DiscountPrice_Model_Price_Observer
*/
public function apply_10($observer)
{
$event = $observer->getEvent();
$product = $event->getProduct();
// process percentage discounts only for simple products
if ($product->getSuperProduct() && $product->getSuperProduct()->isConfigurable()) {
} else {
$product->setFinalPrice(10);
}
return $this;
}
public function apply_view($observer)
{
$event = $observer->getEvent();
$myCustomPrice = 10;
$products = $observer->getCollection();
foreach( $products as $product )
{
$product->setPrice( $myCustomPrice );
$product->setFinalPrice( $myCustomPrice );
}
return $this;
}
}
Why not using 'catalog price rules' or 'special price' function of products? These are inbuilt functions to do this kind of stuff.
For add to cart price change, you need another event to observe. Crash course:
You have to build an observer that catches the add-to-cart event sales_quote_add_item and then you can do the php-stuff in the observer like you did on the product page to change the price for the product added to card with:
$observer->getEvent()->getQuoteItem()->setOriginalCustomPrice([your price])
Exactly for this task it's better to use Catalog Price Rules from Promotions menu.
But as I understand you are making this with learning purposes. So when you are not sure for an event you could just log the dispatched events. In app/Mage.php you have a method called dispatchEvent. Then you could just log every dispatched event:
public static function dispatchEvent($name, array $data = array())
{
if(strpos($name, 'product') || strpos($name, 'price')) { // optional
Mage::log($name, null, 'events.log', true);
}
Varien_Profiler::start('DISPATCH EVENT:'.$name);
$result = self::app()->dispatchEvent($name, $data);
Varien_Profiler::stop('DISPATCH EVENT:'.$name);
return $result;
}
Your log file will be created in var/log folder. Of course don't forget to revert Mage.php to it's original version when you're done. It's not a good idea to change core files.

How to add a product under the specified category on the check out page?

I want to do the following on the checkout/cart/ page:
When a visitor buy goods which order over $100, then I will add a free product to it. The free product is from a specified category. It will shows under the bought product. How to do it?
You can take a look at the MageWorld Free Gift extension. From your description, I believe that will do what you need. However, the extension is not free.
http://www.mage-world.com/free-gift-magento-extension.html
If you want to develop this functionality yourself, I'd suggest you extend the shopping cart promo rules. The rule itself will check whether the order is over $100. You just have to develop the part which will select a free product from a category you specify.
The easiest way is to listen on a quote save with an observer and add / remove the free product that way. First, setup a new module named Yrcrz/AddFreeProduct. In the config.xml, add:
<?xml version="1.0"?>
<config>
<modules>
<Yrcrz_AddFreeProduct>
<version>0.0.1</version>
</Yrcrz_AddFreeProduct>
</modules>
<global>
<events>
<sales_quote_save_before>
<observers>
<Yrcrz_AddFreeProduct_Observer>
<type>singleton</type>
<class>Yrcrz_AddFreeProduct_Model_Observer</class>
<method>sales_quote_save_before</method>
</Yrcrz_AddFreeProduct_Observer>
</observers>
</sales_quote_save_before>
</events>
</global>
</config>
This defines the event sales_quote_save_before that we will be listening for. Then, add an Observer.php file and add this:
<?php
class Yrcrz_AddFreeProduct_Model_Observer
{
public function sales_quote_save_before(Varien_Event_Observer $observer)
{
$quote = $observer->getQuote();
$freeProductId = 182;
$threshold = 100;
$freeProductExists = false;
$items = $quote->getAllItems();
foreach ($items as $item) {
if ($item->getProduct()->getId() == $freeProductId) {
$realGrandTotal = $quote->getGrandTotal() - $item->getRowTotalInclTax();
if ($realGrandTotal < $threshold) {
$quote->removeItem($item->getId());
return false;
}
$freeProductExists = true;
}
}
if ($freeProductExists || !$items) {
return false;
}
$cart = Mage::getSingleton('checkout/cart');
if ($quote->getGrandTotal() >= $threshold) {
$product = Mage::getModel('catalog/product')->load($freeProductId);
if ($product && $product->getId()) {
$params = array();
$cart->addProduct($product, $params);
$cart->save();
Mage::getSingleton('checkout/session')->setCartWasUpdated(true);
}
}
}
}
This code checks to see if the threshold ($100) is reached, and if so it adds a product. It will also remove the free product if the grand total is under the threshold or there are no products. Note that you will need to define the ID of the free product with $freeProductId.

Resources