1

I want to create a custom module which creates duplicate order from the existing order.

I want to show a simple button (like Reorder default Magento) which create current order duplicate order in Magento.

Now I have created a simple script like below -

as per this tutorial

<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
error_reporting(E_ALL | E_STRICT);
set_time_limit(0);
require_once '/var/www/html/app/Mage.php';
umask(0);
Mage::app('default');

$order_id = 1200001726;
$order = Mage::getModel('sales/order')->loadByIncrementId($order_id);
$payment = $order->getPayment()->getMethodInstance()->getTitle();
echo "\nPayment Method - ". $payment;

$quote_id = $order->getQuoteId();
$quote = Mage::getModel('sales/quote')->load($quote_id);
$convert = Mage::getModel('sales/convert_quote');
$order = $convert->toOrder($quote);
$order->addressToOrder($quote->getAddress(),$order);

foreach($quote->getAllItems() as $item){
    $orderItem = $convert->itemToOrderItem($item);
    if ($item->getParentItem()) {
       $orderItem->setParentItem($order->getItemByQuoteItemId($item->getParentItem()->getId()));
    }
    $order->addItem($orderItem);
}

$quote->getShippingAddress()->setPaymentMethod('free');
$quote->getShippingAddress()->setCollectShippingRates(true);

//$payment = $quote->getPayment();
$payment = $convert->paymentToOrderPayment($quote->getPayment());
//$payment->importData($data);
$payment->importData(array('method' => 'free'));
$quote->save();

$payment = $convert->paymentToOrderPayment($quote->getPayment());
$order->setPayment($payment);

$message = '[Notice] - Order converted from quote manually';
$order->addStatusToHistory($order->getStatus(), $message);
$order->place();
$order->save();

$quote->setIsActive(false)->save();

echo 'New Order '.$order->getIncrementId().' Create Successfully';


?>

It is showing below error. I have enabled Payment method as free for this store still it is showing this error.

PHP Fatal error: Uncaught exception 'Mage_Core_Exception' witthe h message 'The requested Payment Method is not available.' in /var/www/html/app/Mage.php:594

Please let me know if any suggestions.

New Code -

<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
error_reporting(E_ALL | E_STRICT);
set_time_limit(0);
require_once 'app/Mage.php';
umask(0);
Mage::app('default');

class PlaceOrder
{
    public function place()
    {
        $orderId = 1200001816;
        $order = Mage::getModel('sales/order')->loadByIncrementId($orderId);
        $payment = $order->getPayment()->getMethodInstance()->getTitle();
        echo "\nPayment Method - ". $payment;

        $quote = $this->createQuote($order);
        echo "\nQuote id - ". $quote->getId();

        $quote->getPayment()->setMethod('free');
        $quote->getShippingAddress()->setCollectShippingRates(true);
        $quote->setTotalsCollectedFlag(false);
        $quote->collectTotals();
        $quote->save();

        // set billing address
        $orderBillingAddress = $order->getBillingAddress();
        $quoteBillingAddress = $quote->getBillingAddress();

        $quoteBillingAddress->setCustomerAddressId('');

        Mage::helper('core')->copyFieldset(
            'sales_copy_order_billing_address',
            'to_order',
            $orderBillingAddress,
            $quoteBillingAddress
        );

        //if (!$quote->isVirtual()) {
            // set shipping address
            $orderShippingAddress = $order->getShippingAddress();
            $quoteShippingAddress = $quote->getShippingAddress();

            $quoteShippingAddress->setCustomerAddressId('')
                ->setSameAsBilling($orderShippingAddress && $orderShippingAddress->getSameAsBilling());

            Mage::helper('core')->copyFieldset(
                'sales_copy_order_shipping_address',
                'to_order',
                $orderShippingAddress,
                $quoteShippingAddress
            );

            // Make collect rates when user click "Get shipping methods and rates" in order creating
            $quoteShippingAddress->setCollectShippingRates(true);
            $quoteShippingAddress->collectShippingRates();

            // Set shipping method from order
            $quoteShippingAddress->setShippingMethod($order->getShippingMethod());
            $quoteShippingAddress->setShippingDescription($order->getShippingDescription());

            // Set shipping method others
            //$quoteShippingAddress->setShippingMethod('Free');
            //$quoteShippingAddress->setShippingRate(0);
            //$quoteShippingAddress->setShippingDescription('TEST DESC');
        //}

        $quote->collectTotals();
        $quote->save();

        //$service = Mage::getModel('sales/service_quote', $quote);
        $service = Mage::getModel('sales/service_quote', $this->_quote);

        $service->submitAll();
        $order = $service->getOrder();

        $message = '[Notice] - Order converted from quote manually';
        $order->addStatusToHistory($order->getStatus(), $message);
        $order->save();

        echo 'New Order '.$order->getIncrementId().' Create Successfully';
    }

    /**
     * @param Mage_Sales_Model_Order $order
     * @return Mage_Sales_Model_Quote
     */
    public function createQuote($order)
    {
        // prepare empty quote for the customer
        $quote = Mage::getModel('sales/quote');
        $customer = $this->getCustomer($order);
        $quote->setStoreId($order->getStoreId())
            ->setCustomerGroupId($customer->getGroupId())
            ->assignCustomer($customer)
            ->setIsActive(false)
            ->save();

        $quote->setIgnoreOldQty(true);
        $quote->setIsSuperMode(true);
        $storeId = $order->getStoreId();
        foreach ($order->getItemsCollection(
            array_keys(Mage::getConfig()->getNode('adminhtml/sales/order/create/available_product_types')->asArray()),
            true
        ) as $orderItem) {
            /* @var $orderItem Mage_Sales_Model_Order_Item */
            if (!$orderItem->getParentItem()) {
                if ($order->getReordered()) {
                    $qty = $orderItem->getQtyOrdered();
                } else {
                    $qty = $orderItem->getQtyOrdered() - $orderItem->getQtyShipped() - $orderItem->getQtyInvoiced();
                }

                if ($qty > 0) {
                    $item = $this->initFromOrderItem($quote, $storeId, $orderItem, $qty);
                    if (is_string($item)) {
                        Mage::throwException($item);
                    }
                }
            }
        }

        return $quote;
    }

    /**
     * @param Mage_Sales_Model_Order $order
     * @return Mage_Customer_Model_Customer
     */
    public function getCustomer($order)
    {
        $customer = Mage::getModel('customer/customer');
        if ($order->getStore()) {
            $customer->setStore($order->getStore());
        }
        if ($customerId = $order->getCustomerId()) {
            $customer->load($customerId);
        }

        return $customer;
    }

    /**
     * Initialize creation data from existing order Item
     *
     * @param Mage_Sales_Model_Quote $quote
     * @param int $storeId
     * @param Mage_Sales_Model_Order_Item $orderItem
     * @param int $qty
     * @return Mage_Sales_Model_Quote_Item|string
     */
    public function initFromOrderItem($quote, $storeId, $orderItem, $qty = null)
    {
        if (!$orderItem->getId()) {
            return $this;
        }

        $product = Mage::getModel('catalog/product')
            ->setStoreId($storeId)
            ->load($orderItem->getProductId());

        if ($product->getId()) {
            $product->setSkipCheckRequiredOption(true);
            $buyRequest = $orderItem->getBuyRequest();
            if (is_numeric($qty)) {
                $buyRequest->setQty($qty);
            }
            $item = $quote->addProduct($product, $buyRequest);
            if (is_string($item)) {
                return $item;
            }

            if ($additionalOptions = $orderItem->getProductOptionByCode('additional_options')) {
                $item->addOption(new Varien_Object(
                    array(
                        'product' => $item->getProduct(),
                        'code' => 'additional_options',
                        'value' => serialize($additionalOptions)
                    )
                ));
            }

            return $item;
        }

        return $this;
    }
}

$placeObj = new PlaceOrder();
$placeObj->place();

?>

Quote.php

<?php

class TM_FireCheckout_Model_Service_Quote extends Mage_Sales_Model_Service_Quote
{
    // removed address validation
    protected function _validate()
    {
        $helper = Mage::helper('sales');
        if (!$this->getQuote()->isVirtual()) {

            Mage::logException(new Exception("Check 1")); 
            /*if($this->getQuote()->isVirtual()){
                echo "value " . $this->getQuote()->isVirtual();
            }else{
                echo "value2 " . $this->getQuote()->isVirtual();
            }*/
            $address = $this->getQuote()->getShippingAddress();
            $addressValidation = Mage::getSingleton('firecheckout/type_standard')->validateAddress($address);
            if ($addressValidation !== true) {
                Mage::throwException(
                    $helper->__('Please check shipping address information. %s', implode(' ', $addressValidation))
                );
            }
            $method = $address->getShippingMethod();
            $rate = $address->getShippingRateByCode($method);

            if(!$method){
                Mage::logException(new Exception("Empty shipping method.Rahul")); 
            }
            if(!$rate){
                Mage::logException(new Exception("Rate was empty inside quote validate method, trying to forcefully recalculate"));
                $this->getQuote()->getShippingAddress()->setCollectShippingRates(true);
                $this->getQuote()->setTotalsCollectedFlag(false);
                $this->getQuote()->collectTotals();
                $rate  = $address->getShippingRateByCode($method);
            }
            if(!$this->getQuote()->isVirtual()){
                Mage::logException(new Exception("Empty isVirtual1"));
            }
            if (!$this->getQuote()->isVirtual() && (!$method || !$rate)) {
                Mage::logException(new Exception("Please specify a shipping method."));
            }
        }

        $addressValidation = Mage::getSingleton('firecheckout/type_standard')
            ->validateAddress($this->getQuote()->getBillingAddress());

        if ($addressValidation !== true) {
            Mage::throwException(
                $helper->__('Please check billing address information. %s', implode(' ', $addressValidation))
            );
        }

        if (!($this->getQuote()->getPayment()->getMethod())) {
            Mage::throwException($helper->__('Please select a valid payment method.'));
        }

        return $this;
    }
}
1

Try following script:


<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
error_reporting(E_ALL | E_STRICT);
set_time_limit(0);
require_once 'app/Mage.php';
umask(0);
Mage::app('default');

class PlaceOrder
{
    public function place()
    {
        $orderId = 145000021;
        $order = Mage::getModel('sales/order')->loadByIncrementId($orderId);
        $payment = $order->getPayment()->getMethodInstance()->getTitle();
        echo "\nPayment Method - ". $payment;

        $quote = $this->createQuote($order);
        $quote->getPayment()->setMethod('free');
        $quote->getShippingAddress()->setCollectShippingRates(true);
        $quote->collectTotals();
        $quote->save();

        // set billing address
        $orderBillingAddress = $order->getBillingAddress();
        $quoteBillingAddress = $quote->getBillingAddress();

        $quoteBillingAddress->setCustomerAddressId('');

        Mage::helper('core')->copyFieldset(
            'sales_copy_order_billing_address',
            'to_order',
            $orderBillingAddress,
            $quoteBillingAddress
        );

        if (!$quote->isVirtual()) {
            // set shipping address
            $orderShippingAddress = $order->getShippingAddress();
            $quoteShippingAddress = $quote->getShippingAddress();

            $quoteShippingAddress->setCustomerAddressId('')
                ->setSameAsBilling($orderShippingAddress && $orderShippingAddress->getSameAsBilling());

            Mage::helper('core')->copyFieldset(
                'sales_copy_order_shipping_address',
                'to_order',
                $orderShippingAddress,
                $quoteShippingAddress
            );

            // Make collect rates when user click "Get shipping methods and rates" in order creating
            $quoteShippingAddress->setCollectShippingRates(true);
            $quoteShippingAddress->collectShippingRates();

            // Set shipping method from order
            //$quoteShippingAddress->setShippingMethod($order->getShippingMethod());

            // Set shipping method others
            $quoteShippingAddress->setShippingMethod('flatrate_flatrate');
            //$quoteShippingAddress->setShippingDescription($order->getShippingDescription());
            $quoteShippingAddress->setShippingDescription('TEST DESC');
        }

        $quote->collectTotals();
        $quote->save();

        $service = Mage::getModel('sales/service_quote', $quote);
        $service->submitAll();
        $order = $service->getOrder();

        $message = '[Notice] - Order converted from quote manually';
        $order->addStatusToHistory($order->getStatus(), $message);
        $order->save();

        echo 'New Order '.$order->getIncrementId().' Create Successfully';
    }

    /**
     * @param Mage_Sales_Model_Order $order
     * @return Mage_Sales_Model_Quote
     */
    public function createQuote($order)
    {
        // prepare empty quote for the customer
        $quote = Mage::getModel('sales/quote');
        $customer = $this->getCustomer($order);
        $quote->setStoreId($order->getStoreId())
            ->setCustomerGroupId($customer->getGroupId())
            ->assignCustomer($customer)
            ->setIsActive(false)
            ->save();

        $quote->setIgnoreOldQty(true);
        $quote->setIsSuperMode(true);
        $storeId = $order->getStoreId();
        foreach ($order->getItemsCollection(
            array_keys(Mage::getConfig()->getNode('adminhtml/sales/order/create/available_product_types')->asArray()),
            true
        ) as $orderItem) {
            /* @var $orderItem Mage_Sales_Model_Order_Item */
            if (!$orderItem->getParentItem()) {
                if ($order->getReordered()) {
                    $qty = $orderItem->getQtyOrdered();
                } else {
                    $qty = $orderItem->getQtyOrdered() - $orderItem->getQtyShipped() - $orderItem->getQtyInvoiced();
                }

                if ($qty > 0) {
                    $item = $this->initFromOrderItem($quote, $storeId, $orderItem, $qty);
                    if (is_string($item)) {
                        Mage::throwException($item);
                    }
                }
            }
        }

        return $quote;
    }

    /**
     * @param Mage_Sales_Model_Order $order
     * @return Mage_Customer_Model_Customer
     */
    public function getCustomer($order)
    {
        $customer = Mage::getModel('customer/customer');
        if ($order->getStore()) {
            $customer->setStore($order->getStore());
        }
        if ($customerId = $order->getCustomerId()) {
            $customer->load($customerId);
        }

        return $customer;
    }

    /**
     * Initialize creation data from existing order Item
     *
     * @param Mage_Sales_Model_Quote $quote
     * @param int $storeId
     * @param Mage_Sales_Model_Order_Item $orderItem
     * @param int $qty
     * @return Mage_Sales_Model_Quote_Item|string
     */
    public function initFromOrderItem($quote, $storeId, $orderItem, $qty = null)
    {
        if (!$orderItem->getId()) {
            return $this;
        }

        $product = Mage::getModel('catalog/product')
            ->setStoreId($storeId)
            ->load($orderItem->getProductId());

        if ($product->getId()) {
            $product->setSkipCheckRequiredOption(true);
            $buyRequest = $orderItem->getBuyRequest();
            if (is_numeric($qty)) {
                $buyRequest->setQty($qty);
            }
            $item = $quote->addProduct($product, $buyRequest);
            if (is_string($item)) {
                return $item;
            }

            if ($additionalOptions = $orderItem->getProductOptionByCode('additional_options')) {
                $item->addOption(new Varien_Object(
                    array(
                        'product' => $item->getProduct(),
                        'code' => 'additional_options',
                        'value' => serialize($additionalOptions)
                    )
                ));
            }

            return $item;
        }

        return $this;
    }
}

$placeObj = new PlaceOrder();
$placeObj->place();

This is working fine with Magento ver. 1.9.4.0

  • I want reorder with zero grand total so I am using free payment method. I want all other items from previous order with customer details. How can I correct my script. I have tried your way but still I am bit confused. Thanks in advance. – Rahul Feb 19 at 15:29
  • 1
    Try updated script – Sohel Rana Feb 19 at 16:34
  • I am getting error PHP Fatal error: Uncaught exception 'Mage_Core_Exception' with message 'Please specify a shipping method.' in /var/www/html/app/Mage.php:594 while creating order. – Rahul Feb 20 at 6:05
  • As per this question I have tried solution as well but not working. magento.stackexchange.com/questions/7623/… – Rahul Feb 20 at 6:13
  • What is your shipping method? – Sohel Rana Feb 20 at 6:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.