Magento 1.9 – Apply Coupon Code to Programmatically Create Reorder

coupon-codesmagento-1.9sales-order

I want to apply previous order coupon code for second recurring cycle. My code is as below which is running for second recurring cycle.

       $order = Mage::getModel('sales/order');

        $billingInfo = $this->getSubscription()->getBillingAddressInfo();
        $billingAddress = Mage::getModel('sales/order_address')->setData($billingInfo)->setId(null);

        $shippingInfo = $this->getSubscription()->getShippingAddressInfo();
        $shippingAddress = Mage::getModel('sales/order_address')->setData($shippingInfo)->setId(null);

        $payment = Mage::getModel('sales/order_payment')->setMethod($this->getSubscription()->getMethodCode());

        $transferDataKeys = array(
            'store_id',
            'store_name',
            'customer_id',
            'customer_email',
            'customer_firstname',
            'customer_lastname',
            'customer_middlename',
            'customer_prefix',
            'customer_suffix',
            'customer_taxvat',
            'customer_gender',
            'customer_is_guest',
            'customer_note_notify',
            'customer_group_id',
            'customer_note',
            'shipping_method',
            'shipping_description',
            'base_currency_code',
            'global_currency_code',
            'order_currency_code',
            'store_currency_code',
            'base_to_global_rate',
            'base_to_order_rate',
            'store_to_base_rate',
            'store_to_order_rate'
        );

        $orderInfo = $this->getSubscription()->getOrderInfo();
        foreach ($transferDataKeys as $key) {
            if (isset($orderInfo[$key])) {
                $order->setData($key, $orderInfo[$key]);
            }
            elseif (isset($shippingInfo[$key])) {
                $order->setData($key, $shippingInfo[$key]);
            }
        }

        $order->setStoreId($this->getSubscription()->getStoreId())->setState(Mage_Sales_Model_Order::STATE_NEW, true)->setBaseToOrderRate(
                $this->getSubscription()->getInfoValue('order_info', 'base_to_order_rate'))->setStoreToOrderRate(
                $this->getSubscription()->getInfoValue('order_info', 'store_to_order_rate'))->setOrderCurrencyCode(
                $this->getSubscription()->getInfoValue('order_info', 'order_currency_code'))->setBaseSubtotal($billingAmount)->setSubtotal(
                $billingAmount)->setBaseShippingAmount($shippingAmount)->setShippingAmount($shippingAmount)->setBaseTaxAmount($taxAmount)->setTaxAmount(
                $taxAmount)->setBaseGrandTotal($grandTotal)->setGrandTotal($grandTotal)->setIsVirtual($isVirtual)->setWeight($weight)->setTotalQtyOrdered(
                $this->getSubscription()->getInfoValue('order_info', 'items_qty'))->setBillingAddress($billingAddress)->setShippingAddress(
                $shippingAddress)->setPayment($payment);

        foreach ($items as $item) {
            $order->addItem($item);
        }

        $transaction = Mage::getModel('core/resource_transaction');
        $transaction->addObject($order);
        $transaction->addCommitCallback(array($order, 'place'));
        $transaction->addCommitCallback(array($order, 'save'));
        $transaction->save();

        $orderCreateModel = Mage::getModel('adminhtml/sales_order_create');
        $orderCreateModel->initFromOrder($order);
        $quote = $orderCreateModel->getQuote();

        Mage::dispatchEvent('checkout_submit_all_after', array('order' => $order, 'quote' => $quote));

Also I have found coupon code in function initFromOrder() of Model 'adminhtml/sales_order_create'.But in collect total my coupon code set null in below function of "Mage_Sales_Model_Quote".

protected function _validateCouponCode()
{
    $code = $this->_getData('coupon_code');
    if (strlen($code)) {
        $addressHasCoupon = false;
        $addresses = $this->getAllAddresses();
        if (count($addresses)>0) {
            foreach ($addresses as $address) {
                if ($address->hasCouponCode()) {
                    $addressHasCoupon = true;
                }
            }
        //$address->hasCouponCode() my coupon code not working here 
            if (!$addressHasCoupon) {
                $this->setCouponCode('');
            }
        }
    }
    return $this;
}

And also i have try to apply coupon code from "sales_convert_order_to_quote" event. Below is my observer code

public function orderToQuote(Varien_Event_Observer $observer)
     {
                Mage::log('orderToQuote data:',null,'mylog.log');
                $quote         =  $observer->getEvent()->getQuote();
                $quoteid       =  $quote->getId();      

                $cartItems = $quote->getAllItems();
                foreach ($cartItems as $item) {
                    $productId = $item->getProductId();
                    Mage::log('orderToQuote product id data:'.$productId,null,'mylog.log');
                    if ($productId  == 195) {
                            $couponCode = "testdata";                           
                            $quote->setCouponCode($couponCode); 
                    }
                }       
     }

I have found product id in log from observer but not successful to applying coupon code.any help would be greatly appreciated.

Best Answer

Please add your code as below

$order->setStoreId($this->getSubscription()->getStoreId())
    ->setState(Mage_Sales_Model_Order::STATE_NEW, true)
    ->setBaseToOrderRate($this->getSubscription()->getInfoValue('order_info', 'base_to_order_rate'))
    ->setStoreToOrderRate($this->getSubscription()->getInfoValue('order_info', 'store_to_order_rate'))
    ->setOrderCurrencyCode($this->getSubscription()->getInfoValue('order_info', 'order_currency_code'))
    ->setBaseSubtotal($billingAmount)
    ->setSubtotal($billingAmount)
    ->setBaseShippingAmount($shippingAmount)
    ->setShippingAmount($shippingAmount)
    ->setBaseTaxAmount($taxAmount)
    ->setTaxAmount($taxAmount)
    ->setBaseGrandTotal($grandTotal)
    ->setGrandTotal($grandTotal)
    ->setIsVirtual($isVirtual)
    ->setWeight($weight)
    ->setTotalQtyOrdered($this->getSubscription()->getInfoValue('order_info', 'items_qty'))
    ->setBillingAddress($billingAddress)
    ->setShippingAddress($shippingAddress)
    ->setPayment($payment)
    ->setCouponCode('set your coupon code here')
    ->setDiscountAmount('your-discount-price')
    ->setBaseDiscountAmount('your-discount-price')
    ->setDiscountDescription('your-discount-description');
Related Topic