Magento 2 – Exit Without Placing Order in sales_order_place_before Event Observer

event-observermagento2sales-order

In sales_order_place_before event i am loading all order collection which used po_number as the payment method .
From the collection I am getting customer id after loading order data using parent id in a for each loop .
Using customer id I am using a helper to get a salesforce id which is in a custom table .
and once I get all , I am checking the customer ids are same or saleseforce ids are same i am throwing a throw new CouldNotSaveException and returning false .
All these conditions are working except the return false part .
It is not preventing to place order, instead order is getting placed .
Is there any other way which I can achieve this ?
Please help .
My events.xml is inside etc/webapi_rest folder. I even tried placing it directly inside etc which also did not help.

Here is my code :

<?php

namespace Ecs\UniquePo\Observer;

use \Magento\Framework\Event\Observer;
use \Magento\Framework\Event\ObserverInterface;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Store\Model\ScopeInterface;
use Magento\Framework\Exception\CouldNotSaveException;
use \Ecs\SalesForceOverride\Helper\SalesforceHelper;

class UniquePo implements ObserverInterface
{
    private $_postData;
    private $_messageManager;
    private $_responseFactory;
    private $_url;
    protected $_customerSession;
    protected $_emailHelper;
    protected $_request;
    protected $salesforceHelper;
    protected $paymentCollectionFactory;
    protected $_order;


    public function __construct(
        \Magento\Framework\App\RequestInterface $request,
        \Magento\Framework\Message\ManagerInterface $messageManager,
        \Magento\Framework\App\ResponseFactory $responseFactory,
        \Magento\Framework\UrlInterface $url,
        ScopeConfigInterface $scopeConfig,
        \Magento\Customer\Model\Session $customerSession,
      \Magento\Customer\Model\CustomerFactory $customerFactory,
      \Magento\Sales\Model\ResourceModel\Order\Payment\CollectionFactory $paymentCollectionFactory,
      \Magento\Sales\Model\OrderFactory $_order,
      SalesforceHelper $salesforceHelper

    )
    {
        $this->_request = $request;
        $this->_postData = $this->_request->getPostValue();
        $this->_customerSession = $customerSession;
        $this->_messageManager = $messageManager;
        $this->_responseFactory = $responseFactory;
        $this->_url = $url;
        $this->scopeConfig = $scopeConfig;
    $this->_customerFactory = $customerFactory;
    $this->paymentCollectionFactory = $paymentCollectionFactory;
    $this->_order = $_order;
    $this->salesforceHelper = $salesforceHelper;

    }

    public function execute(Observer $observer)
    {

         //$method_instance = $observer->getEvent()->getMethodInstance();
         //$this->_logger->info($method_instance->getCode());

        $customerData = $this->_customerSession->getCustomer();
      $customerId = $customerData->getId();
        $paymentData = json_decode(file_get_contents('php://input'), true);
        $poNumber=$paymentData['paymentMethod']['po_number'];
        $type= 'Account';
         $salesforceid = $this->salesforceHelper->getSalesforceId($customerId, $type);
        $orderCollecion = $this->paymentCollectionFactory->create()->addFieldToSelect('*');    
        $orderCollecion->addAttributeToFilter('po_number', ['eq'=>$poNumber]); 
        foreach ($orderCollecion as $parentId) {
            $order_Id =  $parentId->getParentId();
            try
            {
                $order = $this->_order->create()->load($order_Id);  
                $cid =  $order->getCustomerId();

                 if($customerId==$cid)
                 {
                    throw new CouldNotSaveException(__('This PO Number is used already.'));
                    return false;
                 }
                 $salesforcecid = $this->salesforceHelper->getSalesforceId($cid, $type);
                if(isset($salesforcecid) == isset($salesforceid)){
                    throw new CouldNotSaveException(__('This PO Number is used already.'));
                    return false;
                }
            } catch (\Exception $e) {
                echo $e->getMessage();
            }
        }

        return;

    }

}

Best Answer

You can use sales_model_service_quote_submit_before event. I have tried example following way:

app/code/SR/StackExchange/etc/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="sales_model_service_quote_submit_before">
        <observer name="sr_sales_model_service_quote_submit_before" instance="SR\StackExchange\Observer\QuoteSubmitBefore" />
    </event>
</config>

app/code/SR/StackExchange/Observer/QuoteSubmitBefore.php


<?php
namespace SR\StackExchange\Observer;

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

class QuoteSubmitBefore implements ObserverInterface
{
    public function execute(Observer $observer)
    {
        throw new PaymentException(__('This PO Number is used already.'));
    }
}
Related Topic