Wednesday, July 17, 2013

Magento : Add New Order Total (fee or discount, like prepaid discount)

Here i consider that i need to give a discount when user make a order with prepaid method.

Consider, Bd_Prepaid is a custom module and prepaiddiscount_total is a variable,

First create a simple module
1. etc/modules/Bd_Prepaid
<?xml version="1.0"?>
<config>
  <modules>
    <Bd_Prepaid>
      <active>true</active>
      <codePool>local</codePool>
      <version>0.1.0</version>
    </Bd_Prepaid>
  </modules>
</config>

2.Then create a config file with following code
<?xml version="1.0"?>
<config>
  <modules>
    <Bd_Prepaid>
      <version>0.1.0</version>
    </Bd_Prepaid>
  </modules>
  <global>
    <helpers>
      <prepaid>
        <class>Bd_Prepaid_Helper</class>
      </prepaid>
    </helpers>
    <models>
      <prepaid>
        <class>Bd_Prepaid_Model</class>
        <resourceModel>prepaid_mysql4</resourceModel>
      </prepaid>
    </models>
    <resources>
      <salesattribute1374123678_setup>
        <setup>
          <module>Bd_Prepaid</module>
          <class>Mage_Sales_Model_Mysql4_Setup</class>
        </setup>
        <connection>
          <use>core_setup</use>
        </connection>
      </salesattribute1374123678_setup>
      <salesattribute1374123678_write>
        <connection>
          <use>core_write</use>
        </connection>
      </salesattribute1374123678_write>
      <salesattribute1374123678_read>
        <connection>
          <use>core_read</use>
        </connection>
      </salesattribute1374123678_read>
    </resources>
    <events>
    <checkout_type_onepage_save_order_after> <!-- identifier of the event we want to catch -->
        <observers>
          <checkout_type_onepage_save_order_after_prepaiddiscount_handler> <!-- identifier of the event handler -->
            <type>model</type> <!-- class method call type; valid are model, object and singleton -->
            <class>prepaid/newordertotalobserver</class> <!-- observers class alias -->
            <method>savePrepaiddiscountTotal</method>  <!-- observer's method to be called -->
            <args></args> <!-- additional arguments passed to observer -->
          </checkout_type_onepage_save_order_after_prepaiddiscount_handler>
        </observers>
      </checkout_type_onepage_save_order_after>       
    <checkout_type_multishipping_create_orders_single> <!-- identifier of the event we want to catch -->
        <observers>       
          <checkout_type_multishipping_create_orders_single_prepaiddiscount_handler> <!-- identifier of the event handler -->
            <type>model</type> <!-- class method call type; valid are model, object and singleton -->
            <class>prepaid/newordertotalobserver</class> <!-- observers class alias -->
            <method>savePrepaiddiscountTotalForMultishipping</method>  <!-- observer's method to be called -->
            <args></args> <!-- additional arguments passed to observer -->
          </checkout_type_multishipping_create_orders_single_prepaiddiscount_handler>       
        </observers>
      </checkout_type_multishipping_create_orders_single>
    </events>   
     <sales>
        <quote>
            <totals>               
                <prepaiddiscount_total>
                    <class>prepaid/quote_address_total_prepaiddiscount</class>
                    <after>subtotal,freeshipping,tax_subtotal,shipping</after>
                    <before>grand_total</before>
                </prepaiddiscount_total>
            </totals>
        </quote>
            <order_invoice>
                <totals>               
                <prepaiddiscount_total>
                    <class>prepaid/order_invoice_total_prepaiddiscount</class>
                    <after>subtotal,freeshipping,tax_subtotal,shipping</after>
                    <before>grand_total</before>
                </prepaiddiscount_total>
                </totals>
            </order_invoice>
            <order_creditmemo>
                <totals>               
                <prepaiddiscount_total>
                    <class>prepaid/order_invoice_total_prepaiddiscount</class>
                    <after>subtotal,freeshipping,tax_subtotal,shipping</after>
                    <before>grand_total</before>
                </prepaiddiscount_total>
                </totals>
            </order_creditmemo>
    </sales>
  </global>
</config>

3.Then create amysql file to create a order attribute
<?php
$installer = $this;
$installer->startSetup();

$installer->addAttribute("quote_address", "prepaiddiscount_total", array("type"=>"varchar"));
$installer->addAttribute("order", "prepaiddiscount_total", array("type"=>"varchar"));
$installer->endSetup();
    
4.Then create a observer as used in config file
Like Bd/Prepaid/Model/Newordertotalobserver.php
<?php
class Bd_Prepaid_Model_Newordertotalobserver
{
     public function savePrepaiddiscountTotal(Varien_Event_Observer $observer)
    {
         $order = $observer -> getEvent() -> getOrder();
         $quote = $observer -> getEvent() -> getQuote();
         $shippingAddress = $quote -> getShippingAddress();
         if($shippingAddress && $shippingAddress -> getData('prepaiddiscount_total')){
             $order -> setData('prepaiddiscount_total', $shippingAddress -> getData('prepaiddiscount_total'));
             }
        else{
             $billingAddress = $quote -> getBillingAddress();
             $order -> setData('prepaiddiscount_total', $billingAddress -> getData('prepaiddiscount_total'));
             }
         $order -> save();
     }
   
     public function savePrepaiddiscountTotalForMultishipping(Varien_Event_Observer $observer)
    {
         $order = $observer -> getEvent() -> getOrder();
         $address = $observer -> getEvent() -> getAddress();
         $order -> setData('prepaiddiscount_total', $shippingAddress -> getData('prepaiddiscount_total'));
         $order -> save();
     }
}

5.Then create a class file to collect the total (Bd/Prepaid/Model/Quote/Address/Total/Prepaiddiscount.php), which inherited from Mage_Sales_Model_Quote_Address_Total_Abstract with following code
<?php
class Bd_Prepaid_Model_Quote_Address_Total_Prepaiddiscount
extends Mage_Sales_Model_Quote_Address_Total_Abstract
{
     public function __construct()
    {
         $this -> setCode('prepaiddiscount_total');
         }
    /**
     * Collect totals information about prepaiddiscount
     *
     * @param Mage_Sales_Model_Quote_Address $address
     * @return Mage_Sales_Model_Quote_Address_Total_Shipping
     */
     public function collect(Mage_Sales_Model_Quote_Address $address)
    {
         parent :: collect($address);
         $items = $this->_getAddressItems($address);
         if (!count($items)) {
            return $this;
         }
         $quote= $address->getQuote();

         //amount definition

         $prepaiddiscountAmount = 0.01;

         //amount definition

         $prepaiddiscountAmount = $quote -> getStore() -> roundPrice($prepaiddiscountAmount);
         $this -> _setAmount($prepaiddiscountAmount) -> _setBaseAmount($prepaiddiscountAmount);
         $address->setData('prepaiddiscount_total',$prepaiddiscountAmount);

         return $this;
     }
   
    /**
     * Add prepaiddiscount totals information to address object
     *
     * @param Mage_Sales_Model_Quote_Address $address
     * @return Mage_Sales_Model_Quote_Address_Total_Shipping
     */
     public function fetch(Mage_Sales_Model_Quote_Address $address)
    {
         parent :: fetch($address);
         $amount = $address -> getTotalAmount($this -> getCode());
         if ($amount != 0){
             $address -> addTotal(array(
                     'code' => $this -> getCode(),
                     'title' => $this -> getLabel(),
                     'value' => $amount
                    ));
         }
       
         return $this;
     }
   
    /**
     * Get label
     *
     * @return string
     */
     public function getLabel()
    {
         return Mage :: helper('prepaid') -> __('Prepaid Discount');
    }
}

6.Then create a file to add this variable in invoice and an other file to add in memo
as
Bd/Prepaid/Model/Order/Invoice/Total/Prepaiddiscount.php
<?php
class Bd_Prepaid_Model_Order_Invoice_Total_Prepaiddiscount
extends Mage_Sales_Model_Order_Invoice_Total_Abstract
{
    public function collect(Mage_Sales_Model_Order_Invoice $invoice)
    {
        $order=$invoice->getOrder();
        $PrepaiddiscountTotal = $order->getPrepaiddiscountTotal();
        if ($PrepaiddiscountTotal&&count($order->getInvoiceCollection())==0) {
            $invoice->setGrandTotal($invoice->getGrandTotal()+$orderPrepaiddiscountTotal);
            $invoice->setBaseGrandTotal($invoice->getBaseGrandTotal()+$orderPrepaiddiscountTotal);
        }
        return $this;
    }
}

Bd/Prepaid/Model/Order/Creditmemo/Total/Prepaiddiscount.php
<?php
class Bd_Prepaid_Model_Order_Creditmemo_Total_Prepaiddiscount
extends Mage_Sales_Model_Order_Creditmemo_Total_Abstract
{
    public function collect(Mage_Sales_Model_Order_Creditmemo $creditmemo)
    {

        return $this;

        $order = $creditmemo->getOrder();
        $orderPrepaiddiscountTotal        = $order->getPrepaiddiscountTotal();

        if ($orderPrepaiddiscountTotal) {
            $creditmemo->setGrandTotal($creditmemo->getGrandTotal()+$orderPrepaiddiscountTotal);
            $creditmemo->setBaseGrandTotal($creditmemo->getBaseGrandTotal()+$orderPrepaiddiscountTotal);
        }

        return $this;
    }
}

7. At last add following code to app\code\core\Mage\Sales\Block\Order\Totals.php
${code}Total=$source->getprepaiddiscountTotal();

if($source->getOrderId()) {
    ${code}Total=$source->getOrder()->getprepaiddiscountTotal();
}

$this->_totals['prepaiddiscount_total'] = new Varien_Object(array(
    'code'  => 'prepaiddiscount_total',
    'field' => 'prepaiddiscount_total',
    'value' => $prepaiddiscountTotal,
    'label' => $this->__('Prepaid Discount')
));


And following code to app\code\core\Mage\Adminhtml\Block\Sales\Totals.php
$prepaiddiscountTotal=$this->getSource()->getprepaiddiscountTotal();

if($this->getSource()->getOrderId()) {
    $prepaiddiscountTotal=$this->getSource()->getOrder()->getprepaiddiscountTotal();
}
$this->_totals['prepaiddiscount_total'] = new Varien_Object(array(
        'code'      => 'prepaiddiscount_total',
        'value'     => $prepaiddiscountTotal,
        'base_value'=> $prepaiddiscountTotal,
        'label'     => $this->__('Prepaid Discount')
));



 

1 comment: