简体   繁体   English

在Magento中以编程方式创建订单

[英]Create order programmatically in Magento

I'm using these two methods to create orders programmatically in Magento. 我正在使用这两种方法在Magento中以编程方式创建订单。

The first one creates a Quote: 第一个创建一个Quote:

 public function prepareCustomerOrder($customerId, array $shoppingCart, array  $shippingAddress, array $billingAddress, 
        $shippingMethod, $couponCode = null) 
    {
        $customerObj = Mage::getModel('customer/customer')->load($customerId);
        $storeId = $customerObj->getStoreId();
        $quoteObj = Mage::getModel('sales/quote')->assignCustomer($customerObj);
        $storeObj = $quoteObj->getStore()->load($storeId);
        $quoteObj->setStore($storeObj);

        // add products to quote
        foreach($shoppingCart as $part) {
            $productModel = Mage::getModel('catalog/product');
            $productObj = $productModel->setStore($storeId)->setStoreId($storeId)->load($part['PartId']);

            $productObj->setSkipCheckRequiredOption(true);

            try{
                $quoteItem = $quoteObj->addProduct($productObj);
                $quoteItem->setPrice(20);
                $quoteItem->setQty(3);
                $quoteItem->setQuote($quoteObj);                                    
                $quoteObj->addItem($quoteItem);

            } catch (exception $e) {
            return false;
            }

            $productObj->unsSkipCheckRequiredOption();
            $quoteItem->checkData();
        }

        // addresses
        $quoteShippingAddress = new Mage_Sales_Model_Quote_Address();
        $quoteShippingAddress->setData($shippingAddress);
        $quoteBillingAddress = new Mage_Sales_Model_Quote_Address();
        $quoteBillingAddress->setData($billingAddress);
        $quoteObj->setShippingAddress($quoteShippingAddress);
        $quoteObj->setBillingAddress($quoteBillingAddress);

        // coupon code
        if(!empty($couponCode)) $quoteObj->setCouponCode($couponCode); 


        // shipping method an collect
        $quoteObj->getShippingAddress()->setShippingMethod($shippingMethod);
        $quoteObj->getShippingAddress()->setCollectShippingRates(true);
        $quoteObj->getShippingAddress()->collectShippingRates();
        $quoteObj->collectTotals(); // calls $address->collectTotals();
        $quoteObj->setIsActive(0);
        $quoteObj->save();

        return $quoteObj->getId();

    }

And the second one uses that Quote to create Order: 第二个使用Quote来创建Order:

 public function createOrder($quoteId, $paymentMethod, $paymentData) 
    {
        $quoteObj = Mage::getModel('sales/quote')->load($quoteId); // Mage_Sales_Model_Quote
        $items = $quoteObj->getAllItems();                  

        $quoteObj->reserveOrderId();

          // set payment method 
        $quotePaymentObj = $quoteObj->getPayment(); // Mage_Sales_Model_Quote_Payment
        $quotePaymentObj->setMethod($paymentMethod);
        $quoteObj->setPayment($quotePaymentObj);

        // convert quote to order
        $convertQuoteObj = Mage::getSingleton('sales/convert_quote');
        $orderObj = $convertQuoteObj->addressToOrder($quoteObj->getShippingAddress());
        $orderPaymentObj = $convertQuoteObj->paymentToOrderPayment($quotePaymentObj);

        // convert quote addresses
        $orderObj->setBillingAddress($convertQuoteObj->addressToOrderAddress($quoteObj->getBillingAddress()));
        $orderObj->setShippingAddress($convertQuoteObj->addressToOrderAddress($quoteObj->getShippingAddress()));

        // set payment options
        $orderObj->setPayment($convertQuoteObj->paymentToOrderPayment($quoteObj->getPayment()));
        if ($paymentData) {
        $orderObj->getPayment()->setCcNumber($paymentData->ccNumber);
        $orderObj->getPayment()->setCcType($paymentData->ccType);
        $orderObj->getPayment()->setCcExpMonth($paymentData->ccExpMonth);
        $orderObj->getPayment()->setCcExpYear($paymentData->ccExpYear);
        $orderObj->getPayment()->setCcLast4(substr($paymentData->ccNumber,-4));
        }
        // convert quote items
        foreach ($items as $item) {
            // @var $item Mage_Sales_Model_Quote_Item
            $orderItem = $convertQuoteObj->itemToOrderItem($item);

            $options = array();
        if ($productOptions = $item->getProduct()->getTypeInstance(true)->getOrderOptions($item->getProduct())) {

            $options = $productOptions;
        }
        if ($addOptions = $item->getOptionByCode('additional_options')) {
            $options['additional_options'] = unserialize($addOptions->getValue());
        }
        if ($options) {
            $orderItem->setProductOptions($options);
        }
            if ($item->getParentItem()) {
                $orderItem->setParentItem($orderObj->getItemByQuoteItemId($item->getParentItem()->getId()));
            }
            $orderObj->addItem($orderItem);
        }

        $orderObj->setCanShipPartiallyItem(false);

        try {
            $orderObj->place();
        } catch (Exception $e){     
            Mage::log($e->getMessage());
            Mage::log($e->getTraceAsString());
        }

        $orderObj->save(); 
        //$orderObj->sendNewOrderEmail(); 
        return $orderObj->getId();

    }

The process works fine, no errors, and the order is created. 该过程正常,没有错误,订单已创建。 But the total is 0 and there are no products in it no matter what I put. 但总数是0,无论我放什么,都没有产品。

I've traced it and I can confirm that the rows are added to the sales_flat_quote and sales_flat_quote_item tables, so that is ok. 我已跟踪它,我可以确认行已添加到sales_flat_quotesales_flat_quote_item表中,这样就可以了。 But when running the createOrder and calling 但是在运行createOrder并调用时

     $items = $quoteObj->getAllItems();

an empty array is always returned, and I have no idea why. 总是返回一个空数组,我不知道为什么。 I have configurable and simple products in my shop. 我店里有可配置的简单产品。 This happens when I add simple, when I add configurable the error appears as the method 这种情况发生在我添加简单时,当我添加可配置时,错误显示为方法

    $quoteItem = $quoteObj->addProduct($productObj);

returns null. 返回null。

It seems to me, you didn't load product collection, therefore, the cart always return empty. 在我看来,你没有加载产品集合,因此,购物车总是返回空。 Try this link, it will give you more clear help. 试试这个链接,它会给你更清晰的帮助。 Create order programmatically 以编程方式创建订单

// this is get only one product, you can refactor the code
$this->_product = Mage::getModel('catalog/product')->getCollection()
  ->addAttributeToFilter('sku', 'Some value here...')
  ->addAttributeToSelect('*')
  ->getFirstItem();

// load product data
$this->_product->load($this->_product->getId());

This code worked for me, 这段代码对我有用,

public function createorder(array $orderdata)
 {
   $quoteId = $orderdata['quoteId'];
   $paymentMethod = $orderdata['paymentMethod'];
   $paymentData = $orderdata['paymentData'];       
   $quoteObj = Mage::getModel('sales/quote')->load($quoteId); 
   $items = $quoteObj->getAllItems();        
   $quoteObj->reserveOrderId();

    $quotePaymentObj = $quoteObj->getPayment(); 
    $quotePaymentObj->setMethod($paymentMethod);
    $quoteObj->setPayment($quotePaymentObj); 

    $convertQuoteObj = Mage::getSingleton('sales/convert_quote');
    $orderObj = $convertQuoteObj->addressToOrder($quoteObj->getShippingAddress());
    $orderPaymentObj = $convertQuoteObj->paymentToOrderPayment($quotePaymentObj);

    $orderObj->setBillingAddress($convertQuoteObj->addressToOrderAddress($quoteObj->getBillingAddress()));
    $orderObj->setShippingAddress($convertQuoteObj->addressToOrderAddress($quoteObj->getShippingAddress()));
    $orderObj->setPayment($convertQuoteObj->paymentToOrderPayment($quoteObj->getPayment()));

    foreach ($items as $item) 
    {
        $orderItem = $convertQuoteObj->itemToOrderItem($item);        
        $options = array();
       if ($productOptions = $item->getProduct()->getTypeInstance(true)->getOrderOptions($item->getProduct())) 
       {
         $options = $productOptions;
       }
       if ($addOptions = $item->getOptionByCode('additional_options')) 
       {
        $options['additional_options'] = unserialize($addOptions->getValue());
       }
       if ($options) 
       {
          $orderItem->setProductOptions($options);
       }
       if ($item->getParentItem())
       {
            $orderItem->setParentItem($orderObj->getItemByQuoteItemId($item->getParentItem()->getId()));
       }
       $orderObj->addItem($orderItem);
    }
     $quoteObj->collectTotals();
     $service = Mage::getModel('sales/service_quote', $quoteObj);
     $service->submitAll();
     $orderObj->setCanShipPartiallyItem(false);         
    try 
    {

         $last_order_increment_id = Mage::getModel("sales/order")->getCollection()->getLastItem()->getIncrementId();
         return $last_order_increment_id;            
    } 
    catch (Exception $e)
    {     
        Mage::log($e->getMessage());
        Mage::log($e->getTraceAsString());
        return "Exception:".$e;
    } }

I had the same problem and delved into the API to find a solution. 我遇到了同样的问题,并深入研究API以找到解决方案。 I changed the way that I loaded a product by using : 我改变了使用以下方式加载产品的方式:

$productEntityId = '123456';   
$store_code = 'my_store_code';

$product = Mage::helper('catalog/product')->getProduct($productEntityId,Mage::app()->getStore($store_code)->getId());

I found this tutorial to be very useful too : 我发现本教程也很有用:

http://www.classyllama.com/content/unravelling-magentos-collecttotals http://www.classyllama.com/content/unravelling-magentos-collecttotals

If you are looking for a script on order creation this is a very good start : 如果您正在寻找订单创建的脚本,这是一个非常好的开始:

http://pastebin.com/8cft4d8v http://pastebin.com/8cft4d8v

Hope that this helps someone ;) 希望这有助于某人;)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM