4

I try to create an order programmatically in magento2 using this code snippet found on webkul.com

this is the order that i want to create:

$tempOrder=[
     'currency_id'=> 'USD',
     'email'=> 'test@webkul.com', //buyer email id
     'shipping_address' =>[
            'firstname'=> 'jhon', //address Details
            'lastname'=> 'Deo',
                    'street' => 'xxxxx',
                    'city' => 'xxxxx',
            'country_id' => 'IN',
            'region' => 'xxx',
            'postcode' => '43244',
            'telephone' => '52332',
            'fax' => '32423',
            'save_in_address_book' => 1
             ],
   'items'=> [ //array of product which order you want to create
              ['product_id'=>'1','qty'=>1],
              ['product_id'=>'2','qty'=>2]
            ]
];

and this is where i processed it

<?php
namespace YourNameSpace\ModuleName\Helper;
 
class Data extends \Magento\Framework\App\Helper\AbstractHelper
{
     /**
    * @param Magento\Framework\App\Helper\Context $context
    * @param Magento\Store\Model\StoreManagerInterface $storeManager
    * @param Magento\Catalog\Model\Product $product
    * @param Magento\Framework\Data\Form\FormKey $formKey $formkey,
    * @param Magento\Quote\Model\Quote $quote,
    * @param Magento\Customer\Model\CustomerFactory $customerFactory,
    * @param Magento\Sales\Model\Service\OrderService $orderService,
    */
    public function __construct(
        \Magento\Framework\App\Helper\Context $context,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Catalog\Model\Product $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  
    ) {
        $this->_storeManager = $storeManager;
        $this->_product = $product;
        $this->_formkey = $formkey;
        $this->quote = $quote;
        $this->quoteManagement = $quoteManagement;
        $this->customerFactory = $customerFactory;
        $this->customerRepository = $customerRepository;
        $this->orderService = $orderService;
        parent::__construct($context);
    }
 
    /**
     * Create Order On Your Store
     * 
     * @param array $orderData
     * @return array
     * 
    */
    public function createMageOrder($orderData) {
        $store=$this->_storeManager->getStore();
        $websiteId = $this->_storeManager->getStore()->getWebsiteId();
        $customer=$this->customerFactory->create();
        $customer->setWebsiteId($websiteId);
        $customer->loadByEmail($orderData['email']);// load customet by email address
        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();
        }
        $quote=$this->quote->create(); //Create object of quote
        $quote->setStore($store); //set store for which you create quote
        // if you have allready buyer id then you can load customer directly 
        $customer= $this->customerRepository->getById($customer->getEntityId());
        $quote->setCurrency();
        $quote->assignCustomer($customer); //Assign quote to customer
 
        //add items in quote
        foreach($orderData['items'] as $item){
            $product=$this->_product->load($item['product_id']);
            $product->setPrice($item['price']);
            $quote->addProduct(
                $product,
                intval($item['qty'])
            );
        }
 
        //Set Address to quote
        $quote->getBillingAddress()->addData($orderData['shipping_address']);
        $quote->getShippingAddress()->addData($orderData['shipping_address']);
 
        // Collect Rates and Set Shipping & Payment Method
 
        $shippingAddress=$quote->getShippingAddress();
        $shippingAddress->setCollectShippingRates(true)
                        ->collectShippingRates()
                        ->setShippingMethod('freeshipping_freeshipping'); //shipping method
        $quote->setPaymentMethod('checkmo'); //payment method
        $quote->setInventoryProcessed(false); //not effetc inventory
        $quote->save(); //Now Save quote and your quote is ready
 
        // Set Sales Order Payment
        $quote->getPayment()->importData(['method' => 'checkmo']);
 
        // Collect Totals & Save Quote
        $quote->collectTotals()->save();
 
        // Create Order From Quote
        $order = $this->quoteManagement->submit($quote);
        
        $order->setEmailSent(0);
        $increment_id = $order->getRealOrderId();
        if($order->getEntityId()){
            $result['order_id']= $order->getRealOrderId();
        }else{
            $result=['error'=>1,'msg'=>'Your custom message'];
        }
        return $result;
    }
}
 
?>

code work fine, but i messed around with method $quote->addProduct. I don't know why that adding more than one product create an order with just one product and all quantity summed to this

2

Solved

the issues was that i use Magento\Catalog\Model\Product instead of Magento\Catalog\Model\ProductFactory in the constructor.

and so foreach became

foreach($orderData['items'] as $item){
     $product = $this->_product->create()->load($item['product_id']);
     $product->setPrice($item['price']);
     $quote->addProduct(
           $product,
           intval($item['qty'])
     );
}
1
<?php    
use Magento\Framework\App\Action\Action;

class OrderCreateTest extends Action {
    protected $_quoteFactory;
    protected $_orderModel;
    protected $_productModel;
    protected $_customerRepository;
    protected $_quoteManagementModel;

    public function __construct(
        \Magento\Quote\Model\QuoteFactory $quoteFactory,
        \Magento\Sales\Model\Order $orderModel,
        \Magento\Catalog\Model\Product $productModel,
        \Magento\Framework\App\Action\Context $context,
        \Magento\Quote\Model\QuoteManagement $quoteManagementModel,
        \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository
    ) {
        $this->_quoteFactory         = $quoteFactory;
        $this->_orderModel           = $orderModel;
        $this->_productModel         = $productModel;
        $this->_customerRepository   = $customerRepository;
        $this->_quoteManagementModel = $quoteManagementModel;

        parent::__construct($context);
    }

    public function execute() {
        try {
            $customerId = $storeId = 1;
            $customer   = $this->_customerRepository->getById($customerId);
            $quote      = $this->_quoteFactory->create();
            $product    = $this->_productModel->load(1);

            $quote->setStoreId($storeId);
            $quote->assignCustomer($customer);
            $quote->addProduct($product);
            $quote->setCustomerEmail('roni_cost@example.com');

            $addressData = [
                "firstname"  => "Test",
                "lastname"   => "Test",
                "street"     => "Sample Street 10",
                "city"       => "Somewhere",
                "postcode"   => "123456",
                "telephone"  => "123456",
                "country_id" => "US",
                "region_id"  => 12, // id from directory_country_region table
            ];

            $billingAddress  = $quote->getBillingAddress()->addData($addressData);
            $shippingAddress = $quote->getShippingAddress()->addData($addressData);

            $shippingAddress->setCollectShippingRates(true)->collectShippingRates()
                            ->setShippingMethod('flatrate_flatrate')
                            ->setPaymentMethod('checkmo');

            $quote->getShippingAddress()->setShippingMethod('flatrate_flatrate');
            $quote->setPaymentMethod('checkmo');
            $quote->getPayment()->setQuote($quote);
            $quote->getPayment()->importData(['method' => 'checkmo']);
            $quote->setInventoryProcessed(false);
            $quote->save();

            $order = $this->_quoteManagementModel->submit($quote);

            echo "<pre>ORDER DATA";
            echo $order->getId();
            exit;

            exit;
        } catch (\Exception $ex) {
            echo $ex->getMessage();
            exit;
        }
    }
}

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.