Recently, I needed to create an order programmaticaly.
Here's my code :
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
$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->getProduct($item['product_id']);
// $product->setPrice($item['price']);
$product->setPrice(0);
$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
$this->quoteRepository->save($quote);
// $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();
$this->quoteRepository->save($quote);
// 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;
This code is perfecty working, the quote is well created.
Now, I need to load items from the last created quote and then fill the cart with this items.
To do this, I tried this :
$customerId = $this->_customerSession->getCustomer()->getId();
$collection = $this->collection->create();
$collection->addFieldToFilter('customer_id', $customerId);
$collection->addOrder('customer_id');
$quoteId = $collection->getLastItem()->getData('entity_id'); //get id of last quote
$quote = $this->_quoteRepository->get($quoteId);
if ($quoteId) {
try {
$quote->setIsActive(1)->setReservedOrderId(null);
$this->_quoteRepository->save($quote);
} catch (\Exception $e) {
}
$this->_checkoutsession->replaceQuote($quote);
}
This is almost working. If a choose to create a "regular" quote (thanks to my first function), it's working. But if I reload the last quote and then create a quote, the quote is creating twice, the first is an error (it has no item, quantity...) and the second is good.
Does anyone ever face this issue ?