Magento 2 - 以编程方式创建订单并添加带有自定义选项的产品

时间:2017-06-19 07:27:28

标签: magento magento2

这里我使用magento 2.1.6并尝试以编程方式创建订单。

public function __construct(
    \Magento\Framework\App\Helper\Context $context,
    \Magento\Store\Model\StoreManagerInterface $storeManager,
    \Magento\Catalog\Model\ProductFactory $product,
    \Magento\Framework\Data\Form\FormKey $formkey,
    \Magento\Quote\Model\QuoteFactory $quote,
    \Magento\Quote\Model\QuoteManagement $quoteManagement,
    \Magento\Customer\Model\CustomerFactory $customerFactory,
    \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository,
    \Magento\Sales\Model\Service\OrderService $orderService,
    \Magento\Sales\Api\OrderRepositoryInterface $orderRepository,
    \Magento\Sales\Model\Service\InvoiceService $invoiceService,
    \Magento\Framework\DB\Transaction $transaction,
    \Magento\Sales\Api\Data\OrderInterface $order,
    \Magento\Framework\ObjectManagerInterface $objectmanager,
    \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productFactory,
    \Magento\Quote\Api\CartRepositoryInterface $cartRepositoryInterface,
    \Magento\Quote\Api\CartManagementInterface $cartManagementInterface,
    \Magento\Quote\Model\Quote\Address\Rate $shippingRate  
) {
    $this->_storeManager = $storeManager;
    $this->_productFactory = $product;
    $this->_formkey = $formkey;
    $this->quote = $quote;
    $this->quoteManagement = $quoteManagement;
    $this->customerFactory = $customerFactory;
    $this->customerRepository = $customerRepository;
    $this->orderService = $orderService;
    $this->_orderRepository = $orderRepository;
    $this->_invoiceService = $invoiceService;
    $this->_transaction = $transaction;
    $this->order = $order;
    $this->_objectManager = $objectmanager;
    $this->productFactory = $productFactory;
    $this->cartRepositoryInterface = $cartRepositoryInterface;
    $this->cartManagementInterface = $cartManagementInterface;
    $this->shippingRate = $shippingRate;
    parent::__construct($context);
}

创建新订单功能

public function createOrderNew($orderData) {
    //init the store id and website id @todo pass from array
    $store = $this->_storeManager->getStore();
    $websiteId = $this->_storeManager->getStore()->getWebsiteId();
    //init the customer
    $customer=$this->customerFactory->create();
    $customer->setWebsiteId($websiteId);
    $customer->loadByEmail($orderData['email']);// load customet by email address
    //check the customer
    if(!$customer->getEntityId()){
        //If not avilable then create this customer
        $customer->setWebsiteId($websiteId)
            ->setStore($store)
            ->setFirstname($orderData['shipping_address']['firstname'])
            ->setLastname($orderData['shipping_address']['lastname'])
            ->setEmail($orderData['email'])
            ->setPassword($orderData['email']);
        $customer->save();
    }
    //init the quote
    $cart_id = $this->cartManagementInterface->createEmptyCart();
    $cart = $this->cartRepositoryInterface->get($cart_id);
    $cart->setStore($store);
    // if you have already buyer id then you can load customer directly
    $customer= $this->customerRepository->getById($customer->getEntityId());
    $cart->setCurrency();
    $cart->assignCustomer($customer); //Assign quote to customer
    $cart->save();
    //add items in quote
    ob_start();
    foreach($orderData['items'] as $item){
        foreach($item as $item) {
            //echo $item['product_id'];
            $product = $this->_productFactory->create()->load($item['product_id']);
            $customOptions = $this->_objectManager->get('Magento\Catalog\Model\Product\Option')->getProductOptionCollection($product);
            try {
                // print_r($item); die();
                $params = array('product' => $item['product_id'], 'qty' => $item['qty']);
                if (array_key_exists('options', $item) && $item['options']) {
                    $params['options'] = json_decode(json_encode($item['options']), True);
                }
                if ($product->getTypeId() == 'configurable') {
                    $params['super_attribute'] = $item['super_attribute'];
                } elseif ($product->getTypeId() == 'bundle') {
                    $params['bundle_option'] = $item['bundle_option'];
                    $params['bundle_option_qty'] = $item['bundle_option_qty'];
                } elseif ($product->getTypeId() == 'grouped') {
                    $params['super_group'] = $item['super_group'];
                }

                $objParam = new \Magento\Framework\DataObject();
                $objParam->setData($params);
                $cart->addProduct($product, $objParam);

            } catch (Exception $e) {
                $response[$item['product_id']]= $e->getMessage();
            }
            unset($product);    
        }

    }
    $cart->save();
    ob_flush();
    $cart->getBillingAddress()->addData($orderData['shipping_address']);
    $cart->getShippingAddress()->addData($orderData['shipping_address']);
    // Collect Rates and Set Shipping & Payment Method
    $this->shippingRate
        ->setCode('freeshipping_freeshipping')
        ->getPrice(1);
    $shippingAddress = $cart->getShippingAddress();
    //@todo set in order data
    $shippingAddress->setCollectShippingRates(true)
        ->collectShippingRates()
        ->setShippingMethod('flatrate_flatrate'); //shipping method
    //$cart->getShippingAddress()->addShippingRate($this->rate);
    $cart->setPaymentMethod('checkmo'); //payment method
    //@todo insert a variable to affect the invetory
    $cart->setInventoryProcessed(false);
    // Set sales order payment
    $cart->getPayment()->importData(['method' => 'checkmo']);
    // Collect total and saeve
    $cart->collectTotals();
    // Submit the quote and create the order
    $cart->save();
    $cart = $this->cartRepositoryInterface->get($cart->getId());
    $order_id = $this->cartManagementInterface->placeOrder($cart->getId());
    if($orderData['status'] == 4) {
        return $this->createInvoice($order_id);
    }
    return $order_id;
}

订单详情数组

array(5) {
  ["currency_id"]=>
  string(3) "USD"
  ["email"]=>
  string(16) "xxx@gmail.com"
  ["shipping_address"]=>
  array(10) {
    ["firstname"]=>
    string(7) "xxx"
    ["lastname"]=>
    string(10) "xxx"
    ["street"]=>
    string(14) "xxx"
    ["city"]=>
    string(10) "Manchester"
    ["country_id"]=>
    string(2) "GB"
    ["region"]=>
    string(10) "Lancashire"
    ["postcode"]=>
    string(7) "M23 2GF"
    ["telephone"]=>
    string(11) "xxx"
    ["fax"]=>
    string(0) ""
    ["save_in_address_book"]=>
    int(1)
  }
  ["items"]=>
  array(1) {
    [0]=>
    array(1) {
      [0]=>
      array(3) {
        ["product_id"]=>
        string(4) "4694"
        ["qty"]=>
        string(1) "1"
        ["options"]=>
        array(1) {
          [3658]=>
          string(4) "test"
        }
      }
    }
  }
  ["status"]=>
  string(1) "4"
}

我为产品添加了自定义选项

  • 名称:测试
  • 键入:下拉列表
  • 值:测试
  • 价格: $ 10
  • ID: 3658

使用此代码成功创建订单。分配给正确但定制选项的产品不是分配给产品。

寻求帮助。

1 个答案:

答案 0 :(得分:4)

向产品添加自定义选项,然后将其添加到购物车

$customOptions = [];

$customOptions[] = [
        'label'       => __('custom option title'),
        'value'       => 'Value',
        'print_value' => 'Print Value'
    ];
$product->addCustomOption('additional_options', serialize($customOptions));
$cart->addProduct($product, $objParam);

为报价项添加选项
重写Magento ToOrderItem类(在di.xml中添加以下行),以便为订单添加自定义选项

<preference for="Magento\Quote\Model\Quote\Item\ToOrderItem" type="CustomCompany\CustomModule\Observer\AddOrderDeliveryDate"/>

AddOrderDeliveryDate.php

<?php
namespace CustomCompany\CustomModule\Observer;
use Magento\Framework\DataObject\Copy;
use Magento\Quote\Model\Quote\Item;
use Magento\Quote\Model\Quote\Address\Item as AddressItem;
use Magento\Sales\Api\Data\OrderItemInterfaceFactory as OrderItemFactory;
use Magento\Sales\Api\Data\OrderItemInterface;
class AddOrderDeliveryDate  extends \Magento\Quote\Model\Quote\Item\ToOrderItem
{
   /**
     * @var Copy
     */
    protected $objectCopyService;

    /**
     * @var OrderItemFactory
     */
    protected $orderItemFactory;

    /**
     * @var \Magento\Framework\Api\DataObjectHelper
     */
    protected $dataObjectHelper;

    /**
     * @param OrderItemFactory $orderItemFactory
     * @param Copy $objectCopyService
     * @param \Magento\Framework\Api\DataObjectHelper $dataObjectHelper
     */
    public function __construct(
        OrderItemFactory $orderItemFactory,
        Copy $objectCopyService,
        \Magento\Framework\Api\DataObjectHelper $dataObjectHelper
    ) {
        $this->orderItemFactory = $orderItemFactory;
        $this->objectCopyService = $objectCopyService;
        $this->dataObjectHelper = $dataObjectHelper;
    }


    public function convert($item, $data = [])
    {

        $options = $item->getProductOrderOptions();
        if (!$options) {
            $options = $item->getProduct()->getTypeInstance()->getOrderOptions($item->getProduct());
        }
        $orderItemData = $this->objectCopyService->getDataFromFieldset(
            'quote_convert_item',
            'to_order_item',
            $item
        );
        if (!$item->getNoDiscount()) {
            $data = array_merge(
                $data,
                $this->objectCopyService->getDataFromFieldset(
                    'quote_convert_item',
                    'to_order_item_discount',
                    $item
                )
            );
        }

        $orderItem = $this->orderItemFactory->create();
        $this->dataObjectHelper->populateWithArray(
            $orderItem,
            array_merge($orderItemData, $data),
            '\Magento\Sales\Api\Data\OrderItemInterface'
        );

        /**Setting custom options to item **/
        if($item->getOptionByCode('additional_options'))
            $options['additional_options'] = unserialize($item->getOptionByCode('additional_options')->getValue());

        $orderItem->setProductOptions($options);
        if ($item->getParentItem()) {
            $orderItem->setQtyOrdered(
                $orderItemData[OrderItemInterface::QTY_ORDERED] * $item->getParentItem()->getQty()
            );
        }
        return $orderItem;

    }



}