Domanda

Created a custom form where customer and product details filled with status of Active/Not active So for now I want to create an event and observer to place order programmatically when status is Active from admin panel, place order on the bases of customer, product

È stato utile?

Soluzione

Created custom event for this

events.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="trigger_order_place">
        <observer name="vtn_order_success" instance="Vtn\Investment\Observer\Orderplace" />
    </event>
</config>

Here I am getting data dynamically for place order programatically, you can use static values or get your data as per your collection observer -> Orderplace.php

<?php
namespace Vtn\Investment\Observer;

use \Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;

class Orderplace implements ObserverInterface
{
    /**
    * @param Magento\Store\Model\StoreManagerInterface $storeManager,
    * @param Magento\Customer\Model\CustomerFactory $customerFactory,
    * @param Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
    * @param Magento\Customer\Api\CustomerRepositoryInterface $customerRepository,
    * @param Magento\Quote\Model\QuoteFactory $quote,
    * @param Magento\Quote\Model\QuoteManagement $quoteManagement,
    * @param Magento\Sales\Model\Order\Email\Sender\OrderSender $orderSender,
    * @param Magento\Sales\Model\Order $orderCollectionFactory,
    * @param Vtn\Investment\Model\InvestmentFactory $investmentFactory
    */

    public function __construct(
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Customer\Model\CustomerFactory $customerFactory,
        \Magento\Catalog\Api\ProductRepositoryInterface $productRepository,
        \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository,
        \Magento\Quote\Model\QuoteFactory $quote,
        \Magento\Quote\Model\QuoteManagement $quoteManagement,
        \Magento\Sales\Model\Order\Email\Sender\OrderSender $orderSender,
        \Magento\Sales\Model\Order $orderCollectionFactory,
        \Vtn\Investment\Model\InvestmentFactory $investmentFactory
    ){
        $this->storeManager = $storeManager;
        $this->customerFactory = $customerFactory;
        $this->productRepository = $productRepository;
        $this->customerRepository = $customerRepository;
        $this->quote = $quote;
        $this->quoteManagement = $quoteManagement;
        $this->orderSender = $orderSender;
        $this->orderCollectionFactory = $orderCollectionFactory;
        $this->investmentFactory = $investmentFactory;
    }

    public function execute(Observer $observer)
    {
        $collection = $observer->getEvent()->getCollection();
        $collectionData = $collection->getData();
        $Approve = $collection->getActive();
        $investmentId = $collection->getId();
        $customerId = $collection->getCustomerId();
        $vtnOrderId = $collection->getOrderId();
        $customerModel = $this->customerRepository->getById($customerId);
        $currency = $this->storeManager->getStore()->getCurrentCurrency();

        // cencel order if investment discard
        if($Approve == '0' && $vtnOrderId != ''){
            $order = $this->orderCollectionFactory->load($vtnOrderId);
            $order->cancel()->save();

            $productInvest = $this->investmentFactory->create()->getCollection()->addFieldToFilter('id', $investmentId);
            foreach($productInvest as $data){
                $models = $this->investmentFactory->create()->load($data->getId());
                $models->setOrderId(''); 
                $models->save();
            }
        }

        // create order when user approve investment request
        if($Approve == '1' && $vtnOrderId == ''){            
            foreach ($customerModel->getAddresses() as $address) {
                $orderInfo =[
                    'currency_id'  => $currency,
                    'email'        => $collection->getCustomerEmail(),
                    'address' =>[
                        'firstname' => $address->getFirstname(),
                        'lastname' => $address->getLastname(),
                        'prefix' => $address->getPrefix(),
                        'suffix' => $address->getSuffix(),
                        'street' => $address->getStreet(),
                        'city' => $address->getCity(),
                        'country_id' => $address->getCountryId(),
                        'region' => $address->getRegion(),
                        'region_id' => $address->getRegionId(),
                        'postcode' => $address->getPostcode(),
                        'telephone' => $address->getTelephone(),
                        'fax' => $address->getFax(),
                        'save_in_address_book' => 1
                    ],
                    'items'=>
                        [
                            ['product_id'=> $collection->getProductId(),'qty'=>1],
                        ]
                ];
            }
            $store = $this->storeManager->getStore();
            $storeId = $store->getStoreId();
            $websiteId = $this->storeManager->getStore()->getWebsiteId();
            $customer = $this->customerFactory->create();
            $customer->setWebsiteId($websiteId);
            $customer->loadByEmail($orderInfo['email']);// load customet by email address
            
            $quote=$this->quote->create(); //Create object of quote
            $quote->setStore($store); //set store for our quote
            $customer= $this->customerRepository->getById($customer->getId());
            $quote->setCurrency();
            $quote->assignCustomer($customer); //Assign quote to customer
    
            //add items in quote
            foreach($orderInfo['items'] as $item){
                $product=$this->productRepository->getById($item['product_id']);
                if(!empty($item['super_attribute']) ) {
                    /* for configurable product */
                    $buyRequest = new \Magento\Framework\DataObject($item);
                    $quote->addProduct($product,$buyRequest);
                } else {
                    /* for simple product */
                    $quote->addProduct($product,intval($item['qty']));
                }
            }
    
            //Set Billing and shipping Address to quote
            $quote->getBillingAddress()->addData($orderInfo['address']);
            $quote->getShippingAddress()->addData($orderInfo['address']);
    
            // set shipping method
            $shippingAddress=$quote->getShippingAddress();
            $shippingAddress->setCollectShippingRates(true)
                            ->collectShippingRates()
                            ->setShippingMethod('freeshipping_freeshipping'); 
                            //shipping method, please verify free shipping must be enable
            $quote->setPaymentMethod('checkmo'); 
            //payment method, please verify checkmo must be enable from admin
            $quote->setInventoryProcessed(false); 
            //decrease item stock equal to qty
            $quote->save();  //quote save 
            // Set Sales Order Payment, We have taken check/money order
            $quote->getPayment()->importData(['method' => 'checkmo']);
    
            // Collect Quote Totals & Save
            $quote->collectTotals()->save();
            // Create Order From Quote Object
            $order = $this->quoteManagement->submit($quote);
            /* for send order email to customer email id */
            $this->orderSender->send($order);
            /* get order real id from order */
            $orderId = $order->getIncrementId();

            // Investment order column to yes 
            $order = $this->orderCollectionFactory->load($orderId);
            $order->setInvestmentOrder(1);
            $order->save();

            // save order id in vtn_investment_req table
            $productInvest = $this->investmentFactory->create()->getCollection()->addFieldToFilter('id', $investmentId);
            foreach($productInvest as $data){
                $models = $this->investmentFactory->create()->load($data->getId());
                $models->setOrderId($orderId); 
                $models->save();
            }

            if($orderId){
                $result['success']= $orderId;
            }else{
                $result=['error'=>true,'msg'=>'Something Went Wrong During Order Placement'];
            }
            return $result;
        }
        return $this;
    }
}

Controller where event is dispatch Save.php

public function __construct(
        \Magento\Backend\App\Action\Context $context,
        \Magento\Framework\View\Result\PageFactory $resultPageFactory,
        \Vtn\Investment\Model\InvestmentFactory $investmentFactory,
        EventManager $eventManager
    )
    {
        $this->resultPageFactory = $resultPageFactory;
        $this->investmentFactory = $investmentFactory;
        $this->eventManager = $eventManager;
        parent::__construct($context);
    }

    public function execute()
    {
        $resultRedirect = $this->resultRedirectFactory->create();
        $data = $this->getRequest()->getPostValue();
        $id = $data['id'];
        
        if($data)
        {
                $id = $data['id'];
                $investment = $this->investmentFactory->create()->load($id);
                $data = array_filter($data, function($value) {return $value !== ''; });
                $collection = $investment->setData($data);

                // dispatch custom event for order place
                $this->eventManager->dispatch('trigger_order_place',['collection' => $collection]);

                $investment->save();
                $this->messageManager->addSuccess(__('Successfully saved the item.'));
                $this->_objectManager->get('Magento\Backend\Model\Session')->setFormData(false);
                return $resultRedirect->setPath('*/*/');
            }

Altri suggerimenti

1)Create event.xml file:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="sales_order_place_after">
        <observer name="neo_ordercomment_observer_orderneo" instance="vendor\module\Observer\Orderneo" />
    </event>
</config>

2)Create PlaceOrder.php file in Observer directory:

<?php

namespace Vendor\Module\Observer;

class PlaceOrder implements \Magento\Framework\Event\ObserverInterface
{
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $order= $observer->getData('order');
        $comment = $this->getRequest()->getParams('comment');
        print_r("Catched event succssfully !"); exit;
    }
}

May be these articles can help you, as I think you have built a custom module already to fill the customer and product details, I know you asked for event, but if its custom module, you will have to create your own event using dispatch event:

https://webkul.com/blog/create-quote-and-order-programmatically-in-magento2/

https://www.mageplaza.com/devdocs/magento-2-create-order-programmatically.html

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a magento.stackexchange
scroll top