Magento – Custom options operations

custom-options

My client needs to make an operation on products custom options.

Using Magento CE, I create a product, and give it some custom options from within the built-in left hand side menu in "Manage products" > "Add new product", such as "mm" (millimeters) and "mt" (meters)

This product will have both radio options and a textbot input.

Let's say we have

Base price: 0 

MM:
Radio option A which costs 0,9
Radio option B which costs 1,2
Radio option C which costs 2,3 

MT:
Textbox value = unknown yet

Let's say user chooses Radio option B and enters 10 in the textfield

Price should be updates as such:

1,2 * 10 + 0

Which is

radio value cost * textbox value + base price 

Is there any way to tell the code to take the value of the radio button, multiply it for the value of the textbox and sum it all to the base price?

Where could I look to see the current behavior of a product's custom options?

Thanks in advance

Best Answer

In this case,you can use magento event/observer. Basically there are two events,by which you can change the cart price of that products:

  1. checkout_cart_product_add_after
  2. checkout_cart_update_items_after
  3. checkout_cart_product_update_after

This 3 event is need because of:

Event1:checkout_cart_product_add_after

This event is fire when first time a product is cart for current session of current input values from frontend

Event2:checkout_cart_product_update_after

This event is fire when a current exiting cart item edited from edit link of cart item.

Event3:checkout_cart_update_items_after

This event is fire whenever cart items update from cart page.

As per as magento system, a cart item price change using setter functions setCustomPrice(), setOriginalCustomPrice of cart item Object.

Just like:

$EachCartitem->setCustomPrice($price);
$EachCartitem->setOriginalCustomPrice($price);
// Enable super mode on the product.
$EachCartitem->getProduct()->setIsSuperMode(true);

And using events fire an observer which is calculate price basic of your input fields.

enter image description here

Suppose: The radio button field name is My Checkbox and Text Box field Name is MyTestext.

Config.xml code like:

  <global>
    <models>
      <magento65569>
        <class>Stackexchange_Magento65569_Model</class>
      </magento65569>
    </models>
    <events>
      <checkout_cart_product_add_after> <!-- identifier of the event we want to catch -->
        <observers>
          <checkout_cart_product_add_after_handler> <!-- identifier of the event handler -->
            <type>singleton</type> <!-- class method call type; valid are model, object and singleton -->
            <class>magento65569/observer</class> <!-- observers class alias -->
            <method>CalculatePrice</method>  <!-- observer's method to be called -->
            <args></args> <!-- additional arguments passed to observer -->
          </checkout_cart_product_add_after_handler>
        </observers>
      </checkout_cart_product_add_after>
      <checkout_cart_update_items_after> <!-- identifier of the event we want to catch -->
        <observers>
          <checkout_cart_update_items_after_handler> <!-- identifier of the event handler -->
            <type>singleton</type> <!-- class method call type; valid are model, object and singleton -->
            <class>magento65569/observer</class> <!-- observers class alias -->
            <method>UpdateCalculatePrice</method>  <!-- observer's method to be called -->
          </checkout_cart_update_items_after_handler>
        </observers>
      </checkout_cart_update_items_after>
        <checkout_cart_product_update_after> <!-- identifier of the event we want to catch -->
        <observers>
          <checkout_cart_product_update_after_handler> <!-- identifier of the event handler -->
            <type>singleton</type> <!-- class method call type; valid are model, object and singleton -->
            <class>magento65569/observer</class> <!-- observers class alias -->
            <method>ExitingcartItemUpdate</method>  <!-- observer's method to be called -->
          </checkout_cart_product_update_after_handler>
        </observers>
        </checkout_cart_product_update_after>
            </events>
  </global>

Observer code like this:

<?php
class Stackexchange_Magento65569_Model_Observer
{

        /* This function will work when product will cart */ 
            public function CalculatePrice(Varien_Event_Observer $observer)
            {
                //Mage::dispatchEvent('checkout_cart_product_add_after', array('quote_item' => $result, 'product' => $product));
                $RadioVal=0;
                $TextVal=0;
                $resultParams=array();
                $Event = $observer->getEvent();
                $product=$Event->getProduct();
                $quote_item=$Event->getQuoteItem();
                $item = ($quote_item->getParentItem()?$quote_item->getParentItem():$quote_item );
                $this->getOptiondata($item,$product);

            }
            /*  This function will work when cart item  will   qty  update */
            public function UpdateCalculatePrice(Varien_Event_Observer $observer){
                 // Mage::dispatchEvent('checkout_cart_update_items_before', array('cart'=>$this, 'info'=>$data));
                 $cart=$observer->getEvent()->getCart();
                 $data=$observer->getEvent()->getInfo();
                 foreach ($data as $itemId => $itemInfo) {
                 $quote_item = $cart->getQuote()->getItemById($itemId);
                    if (!$quote_item) {
                        continue;
                    }

                    $item = ($quote_item->getParentItem()?$quote_item->getParentItem():$quote_item );
                    $customOptions = $quote_item->getBuyRequest()->getOptions();
                    Mage::log(print_r($customOptions,1),null,'UpdateCalculatePrice.log');
                    $this->getOptiondata($item,$item->getProduct());
                 }


            }
            public function ExitingcartItemUpdate($observer){
              /*Mage::dispatchEvent('checkout_cart_product_update_after', array(
                        'quote_item' => $result,
                        'product' => $product
                    ));*/
                $Event = $observer->getEvent();
                $product=$Event->getProduct();
                $quote_item=$Event->getQuoteItem();
                $item = ($quote_item->getParentItem()?$quote_item->getParentItem():$quote_item );
                $this->getOptiondata($item,$product);



            }


            private function getOptiondata($item,$product){
                $RadioVal=0;
                $TextVal=0;
                $resultParams=array();

                $customOptions = $item->getBuyRequest()->getOptions();
                Mage::log(print_r($customOptions,1),null,'Customoption.log');

                if(is_array($customOptions)){
                    foreach ($customOptions as $key => $value) {
                        if ($value != '') {
                            $resultParams[]=$this->Recalculate($key,$value,$product);
                        }
                    }


                    if(!empty($resultParams)):
                        foreach($resultParams as $Each):
                            foreach($Each as $key=>$val):
                                if($key=='radio'):
                                $RadioVal=$val;
                                elseif($key=='mytext'):
                                $TextVal=$val;
                                else:
                                endif;

                            Mage::log(print_r($val,1),null,'new.log');
                            endforeach;
                        endforeach;

                        /* Now need price calcalute */
                        if($RadioVal!=0 && $TextVal!=0){
                            //radio value cost * textbox value + base price 
                            $price=($RadioVal*$TextVal)+($product->getPrice());
                            Mage::log($RadioVal.'ddddd'.$TextVal.'sss'.$price,null,'trrr.log');
                            $item->setCustomPrice($price);
                            $item->setOriginalCustomPrice($price);
                            // Enable super mode on the product.
                            $item->getProduct()->setIsSuperMode(true);


                        }
                    endif;

                }



            }
            public function Recalculate($optionId=null,$SelectVal,$product){
                $Array=array();
                if($optionId):
                $option = Mage::getModel('catalog/product_option')->load($optionId);


                 if ($option = $product->getOptionById($optionId)) {
                             // Set additional fields to each type group
                            switch ($option->getGroupByType()) {
                                    case Mage_Catalog_Model_Product_Option::OPTION_GROUP_TEXT:
                                        if($option->getTitle()=='MyTestext'):
                                            $Array['mytext']=$SelectVal;
                                            Mage::log(print_r($Array,1),null,'Customoptionr.log');
                                        endif;

                                    break;
                                case Mage_Catalog_Model_Product_Option::OPTION_GROUP_SELECT:
                                    if($option->getTitle()=='My Checkbox'):
                                        foreach ($option->getValuesCollection() as $value) {
    /*                                      'value_id' => $value->getId(),
                                            'title' => $value->getTitle(),
                                            'price' => $value->getPrice(),
                                            'price_type' => $value->getPriceType(),
                                            'sku' => $value->getSku(),
                                            'sort_order' => $value->getSortOrder()
    */                                      if($value->getId()==$SelectVal){
                                                $Array['radio']=$value->getPrice();
                                            Mage::log(print_r($Array,1),null,'Customoptionr.log');


                                            }

                                        }
                                    endif;  
                                    break;
                                default:
                                    break;
                            }
                 }
                 /* end of $option = $product->getOptionById($optionId) */
                endif;
                return $Array;
            }



}

Full Module:

As per as your request, i have put full module:

File1: create config file at app/code/local/Stackexchange/Magento65569/etc/config.xml

Code:

<?xml version="1.0"?>
<config>
  <modules>
    <Stackexchange_Magento65569>
      <version>0.1.0</version>
    </Stackexchange_Magento65569>
  </modules>
  <global>
    <models>
      <magento65569>
        <class>Stackexchange_Magento65569_Model</class>
      </magento65569>
    </models>
    <events>
      <checkout_cart_product_add_after> <!-- identifier of the event we want to catch -->
        <observers>
          <checkout_cart_product_add_after_handler> <!-- identifier of the event handler -->
            <type>singleton</type> <!-- class method call type; valid are model, object and singleton -->
            <class>magento65569/observer</class> <!-- observers class alias -->
            <method>CalculatePrice</method>  <!-- observer's method to be called -->
            <args></args> <!-- additional arguments passed to observer -->
          </checkout_cart_product_add_after_handler>
        </observers>
      </checkout_cart_product_add_after>
      <checkout_cart_update_items_after> <!-- identifier of the event we want to catch -->
        <observers>
          <checkout_cart_update_items_after_handler> <!-- identifier of the event handler -->
            <type>singleton</type> <!-- class method call type; valid are model, object and singleton -->
            <class>magento65569/observer</class> <!-- observers class alias -->
            <method>UpdateCalculatePrice</method>  <!-- observer's method to be called -->
          </checkout_cart_update_items_after_handler>
        </observers>
      </checkout_cart_update_items_after>
        <checkout_cart_product_update_after> <!-- identifier of the event we want to catch -->
        <observers>
          <checkout_cart_product_update_after_handler> <!-- identifier of the event handler -->
            <type>singleton</type> <!-- class method call type; valid are model, object and singleton -->
            <class>magento65569/observer</class> <!-- observers class alias -->
            <method>ExitingcartItemUpdate</method>  <!-- observer's method to be called -->
          </checkout_cart_product_update_after_handler>
        </observers>
        </checkout_cart_product_update_after>
            </events>
  </global>
</config> 

File2: location app/code/local/Stackexchange/Magento65569/Model/Observer.php

Code:

<?php
class Stackexchange_Magento65569_Model_Observer
{

            public function CalculatePrice(Varien_Event_Observer $observer)
            {
                $RadioVal=0;
                $TextVal=0;
                $resultParams=array();
                $Event = $observer->getEvent();
                $product=$Event->getProduct();
                $quote_item=$Event->getQuoteItem();
                $item = ($quote_item->getParentItem()?$quote_item->getParentItem():$quote_item );
                $this->getOptiondata($item,$product);

            }
            /*  This function will work when cart item  will   qty  update */
            public function UpdateCalculatePrice(Varien_Event_Observer $observer){
                 $cart=$observer->getEvent()->getCart();
                 $data=$observer->getEvent()->getInfo();
                 foreach ($data as $itemId => $itemInfo) {
                 $quote_item = $cart->getQuote()->getItemById($itemId);
                    if (!$quote_item) {
                        continue;
                    }

                    $item = ($quote_item->getParentItem()?$quote_item->getParentItem():$quote_item );
                    $customOptions = $quote_item->getBuyRequest()->getOptions();
                    Mage::log(print_r($customOptions,1),null,'UpdateCalculatePrice.log');
                    $this->getOptiondata($item,$item->getProduct());
                 }


            }
            public function ExitingcartItemUpdate($observer){
                $Event = $observer->getEvent();
                $product=$Event->getProduct();
                $quote_item=$Event->getQuoteItem();
                $item = ($quote_item->getParentItem()?$quote_item->getParentItem():$quote_item );
                $this->getOptiondata($item,$product);

            }


            private function getOptiondata($item,$product){
                $RadioVal=0;
                $TextVal=0;
                $resultParams=array();

                $customOptions = $item->getBuyRequest()->getOptions();

                if(is_array($customOptions)){
                    foreach ($customOptions as $key => $value) {
                        if ($value != '') {
                            $resultParams[]=$this->Recalculate($key,$value,$product);
                        }
                    }


                    if(!empty($resultParams)):
                        foreach($resultParams as $Each):
                            foreach($Each as $key=>$val):
                                if($key=='radio'):
                                $RadioVal=$val;
                                elseif($key=='mytext'):
                                $TextVal=$val;
                                else:
                                endif;

                            Mage::log(print_r($val,1),null,'new.log');
                            endforeach;
                        endforeach;

                        /* Now need price calcalute */
                        if($RadioVal!=0 && $TextVal!=0){
                            //radio value cost * textbox value + base price 
                            $price=($RadioVal*$TextVal)+($product->getPrice());
                            Mage::log($RadioVal.'ddddd'.$TextVal.'sss'.$price,null,'trrr.log');
                            $item->setCustomPrice($price);
                            $item->setOriginalCustomPrice($price);
                            // Enable super mode on the product.
                            $item->getProduct()->setIsSuperMode(true);


                        }
                    endif;

                }



            }
            public function Recalculate($optionId=null,$SelectVal,$product){
                $Array=array();
                if($optionId):
                $option = Mage::getModel('catalog/product_option')->load($optionId);


                 if ($option = $product->getOptionById($optionId)) {
                             // Set additional fields to each type group
                            switch ($option->getGroupByType()) {
                                    case Mage_Catalog_Model_Product_Option::OPTION_GROUP_TEXT:
                                        if($option->getTitle()=='MyTestext'):
                                            $Array['mytext']=$SelectVal;
                                            Mage::log(print_r($Array,1),null,'Customoptionr.log');
                                        endif;

                                    break;
                                case Mage_Catalog_Model_Product_Option::OPTION_GROUP_SELECT:
                                    if($option->getTitle()=='My Checkbox'):
                                        foreach ($option->getValuesCollection() as $value) {
                                            if($value->getId()==$SelectVal){
                                                $Array['radio']=$value->getPrice();
                                            Mage::log(print_r($Array,1),null,'Customoptionr.log');


                                            }

                                        }
                                    endif;  
                                    break;
                                default:
                                    break;
                            }
                 }
                 /* end of $option = $product->getOptionById($optionId) */
                endif;
                return $Array;
            }



}

File3: Module Main file at app/etc/modules/Stackexchange_Magento65569.xml

code:

<?xml version="1.0"?>
<config>
  <modules>
    <Stackexchange_Magento65569>
      <active>true</active>
      <codePool>local</codePool>
      <version>0.1.0</version>
    </Stackexchange_Magento65569>
  </modules>
</config>
Related Topic