-
-
Save TheFrankman/0f342e07500ba126297ff01d09b3aa07 to your computer and use it in GitHub Desktop.
<?php | |
/** | |
* @author Frank Clark | |
*/ | |
namespace Vendor\Namespace\Model\Subscription\Order; | |
class Create | |
{ | |
public function __construct( | |
\Magento\Framework\App\Helper\Context $context, | |
\Magento\Store\Model\StoreManagerInterface $storeManager, | |
\Magento\Catalog\Model\Product $product, | |
\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\Quote\Api\CartRepositoryInterface $cartRepositoryInterface, | |
\Magento\Quote\Api\CartManagementInterface $cartManagementInterface | |
) { | |
$this->_storeManager = $storeManager; | |
$this->_product = $product; | |
$this->quote = $quote; | |
$this->quoteManagement = $quoteManagement; | |
$this->customerFactory = $customerFactory; | |
$this->customerRepository = $customerRepository; | |
$this->orderService = $orderService; | |
$this->cartRepositoryInterface = $cartRepositoryInterface; | |
$this->cartManagementInterface = $cartManagementInterface; | |
} | |
/** | |
* Create Order On Your Store | |
* | |
* @param array $orderData | |
* @return array | |
* | |
*/ | |
public function createOrder($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 | |
$quote=$this->quote->create(); | |
$quote->setStore($store); | |
// if you have already buyer id then you can load customer directly | |
$customer= $this->customerRepository->getById($customer->getEntityId()); | |
$quote->setCurrency(); | |
$this->cartRepositoryInterface->save($quote); | |
$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(22); | |
$quote->addProduct( | |
$product, | |
intval($item['qty']) | |
); | |
} | |
//Set Address to quote @todo add section in order data for seperate billing and handle it | |
$quote->getBillingAddress()->addData($orderData['shipping_address']); | |
$quote->getShippingAddress()->addData($orderData['shipping_address']); | |
// Collect Rates and Set Shipping & Payment Method | |
$shippingAddress = $quote->getShippingAddress(); | |
//@todo set in order data | |
$shippingAddress->setCollectShippingRates(true) | |
->collectShippingRates() | |
->setShippingMethod('flatrate_flatrate'); //shipping method | |
$quote->setPaymentMethod('checkmo'); //payment method | |
//@todo insert a variable to affect the invetory | |
$quote->setInventoryProcessed(false); | |
// Set sales order payment | |
$quote->getPayment()->importData(['method' => 'checkmo']); | |
//$quote->save(); | |
$this->cartRepositoryInterface->save($quote); | |
// Collect total and saeve | |
$quote->collectTotals(); | |
// Submit the quote and create the order | |
$quote = $this->cartRepositoryInterface->get($quote->getId()); | |
$order = $this->cartManagementInterface->submit($quote); | |
//do not send the email | |
$order->setEmailSent(0); | |
//give a result back | |
if($order->getEntityId()){ | |
$result['order_id'] = $order->getEntityId(); | |
}else{ | |
$result=['error'=>1,'msg'=>'Your custom message']; | |
} | |
return $result; | |
} | |
} | |
?> |
Hi nimila and Frank,
I got the same problems with yours and I managed to solve them. The full code piece is at here.
Here are my explanation to my solution:
1.Multiple products are not getting added, only first product in the loop will get added.
Instead of using \Magento\Catalog\Model\Product
in __construct
parameter, I used \Magento\Catalog\Model\ProductFactory
. Then I create product
object by doing $product=$this->_product->create()->load($item['product_id']);
. Here is the snippet that add products to quote:
//add items in quote
foreach($orderData['items'] as $item){
$product=$this->_product->create()->load($item['product_id']);
$quote->addProduct(
$product,
intval($item['qty'])
);
}
2.Product price will be 0.00 always.
I'm not saving the order by $this->cartRepositoryInterface->save($quote);
. Instead, I used $quote->save();
. (In fact my code is a little different. I used the following code to create a $cart
, which is the interface of $quote
:
$cart_id = $this->cartManagementInterface->createEmptyCart();
$cart = $this->cartRepogitoryInterface->get($cart_id);
3.Shipping method is not getting saved.
I find my flatrate_flatrate
shipping method is saved properly with Frank's code. But when I want to use freeshipping_freeshipping
, I have to give the __construct
a \Magento\Quote\Model\Quote\Address\Rate $shippingRate
parameter and added some code like this:
// 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
It's does not work with Table rate - Weight and Destination. Please give me an advice?
Thanks
How can we call the function from phtml file ?
@godriccao Thanks a lot! Life saver.
I am using this code and order is creating but order total is 0 (zero).
`<?php
namespace Vendor\Module\Model\ReOrder;
class ReOrder extends \Magento\Framework\Model\AbstractModel
{
public function __construct(
\Magento\Framework\App\Helper\Context $context,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Catalog\Model\ProductFactory $product,
\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\Quote\Api\CartRepositoryInterface $cartRepositoryInterface,
\Magento\Quote\Api\CartManagementInterface $cartManagementInterface,
\DocResearch\Customer\Block\Customer\LastOrder $lastorder
) {
$this->_storeManager = $storeManager;
$this->_product = $product;
$this->quote = $quote;
$this->quoteManagement = $quoteManagement;
$this->customerFactory = $customerFactory;
$this->customerRepository = $customerRepository;
$this->orderService = $orderService;
$this->cartRepositoryInterface = $cartRepositoryInterface;
$this->cartManagementInterface = $cartManagementInterface;
$this->lastorder = $lastorder;
}
public function createOrder($orderData = null) {
$_orderDetails = $this->lastorder->getOrders();
$orderData = array();
foreach ($_orderDetails as $_order){
$lid = $_order->getId();
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$order = $objectManager->create('Magento\Sales\Model\Order')->load($lid);
$storeManager = $objectManager->get('Magento\Store\Model\StoreManagerInterface');
$store = $storeManager->getStore();
$mediaUrl = $store->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA);
$items = $order->getAllItems();
/* foreach($items as $k => $i){
echo "<pre>".$lid; print_r($i->getData()); die();
$_product = $this->_product->create()->load($i->getProductId());
$orderData['items'][$k]['product_id'] = $i->getProductId();
$orderData['items'][$k]['qty'] = $i->getData('qty_ordered');
}*/
$shippingAddress = $_order->getShippingAddress();
$orderData['shipping_address']['firstname'] = $shippingAddress->getFirstname();
$orderData['shipping_address']['lastname'] = $shippingAddress->getLastname();
$orderData['shipping_address']['street'] = $shippingAddress->getStreet();
$orderData['shipping_address']['city'] = $shippingAddress->getCity();
$orderData['shipping_address']['region'] = $shippingAddress->getRegion();
$orderData['shipping_address']['region_id'] = $shippingAddress->getRegion_id();
$orderData['shipping_address']['postcode'] = $shippingAddress->getPostcode();
$orderData['shipping_address']['telephone'] = $shippingAddress->getTelephone();
$orderData['shipping_address']['fax'] = $shippingAddress->getFax();
$orderData['shipping_address']['country_id'] = $shippingAddress->getCountry_id();
$orderData['shipping_address']['save_in_address_book'] = $shippingAddress->getCity();
$orderData['email'] = $shippingAddress->getEmail();
$orderData['shipping_method'] = $_order->getShippingMethod();
$orderData['payment_method'] = $_order->getPayment()->getMethod();
}
//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
$quote=$this->quote->create();
$quote->setStore($store);
// if you have already buyer id then you can load customer directly
$customer= $this->customerRepository->getById($customer->getEntityId());
$quote->setCurrency();
$this->cartRepositoryInterface->save($quote);
$quote->assignCustomer($customer); //Assign quote to customer
//add items in quote
foreach($items as $key => $value){
$product = $this->_product->create()->load($value->getProductId());
$product->setPrice(29.0000);
//echo '<pre>';print_r($product->getPrice());
$quote->addProduct(
$product,
intval($value->getQtyOrdered())
);
}
$itemsq = $quote->getAllItems();
// foreach($itemsq as $k => $i){
// //echo "<pre>"; print_r($i->getData('price')); die();
// $_product = $this->_product->create()->load($i->getProductId());
// $i->setCustomPrice(29.0000);
// $i->setOriginalCustomPrice(29.0000);
// $i->setPrice(29.0000);
// $i->setOrginalCustomPrice(29.0000);
// $i->setBasePrice(29.0000);
// $i->setBaseOriginalPrice(29.0000);
// }
//Set Address to quote @todo add section in order data for seperate billing and handle it
$quote->getBillingAddress()->addData($orderData['shipping_address']);
$quote->getShippingAddress()->addData($orderData['shipping_address']);
// Collect Rates and Set Shipping & Payment Method
$shippingAddress = $quote->getShippingAddress();
//@todo set in order data
$shippingAddress->setCollectShippingRates(true)
->collectShippingRates()
->setShippingMethod($orderData['shipping_method']); //shipping method
$quote->setPaymentMethod($orderData['payment_method']); //payment method
//@todo insert a variable to affect the invetory
$quote->setInventoryProcessed(false);
// Set sales order payment
$quote->getPayment()->importData(['method' => $orderData['payment_method']]);
//$quote->save();
$this->cartRepositoryInterface->save($quote);
// Collect total and saeve
$quote->collectTotals();
// Submit the quote and create the order
$quote = $this->cartRepositoryInterface->get($quote->getId());
$order = $this->cartManagementInterface->submit($quote);
//do not send the email
$order->setEmailSent(0);
if(empty($order->getEntityId())) {
return false;
}
return $order->getEntityId();
}
}`
Creates order but all prices sets to 0 after adding line $this->cartRepositoryInterface->save($quote); after $quote->setCurrency();
@godriccao your solution works, thanks a lot.
@godriccao , shipment is not getting saved
Hi Frank,
Thank you for your code. It saved my time a lot.. but when I tried the code "Cart %1 does not contain item %2" has gone but facing other issues now..
Can you please guide me to resolve the issue.