0

I'm trying to hide a payment method if a customer has more than one processing order, so I created a module call KgPayMethod and in this module, I added this line on events.xml

<event name="payment_method_is_active">
<observer name="custom_payment" instance="Ab\KgPayMethod\Observer\PaymentMethodAvailable" />
</event>

and my class like this :

<?php

namespace Ab\KgPayMethod\Observer;

use Magento\Framework\Event\ObserverInterface;

class PaymentMethodAvailable implements ObserverInterface
{
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        if( $observer->getEvent()->getMethodInstance()->getCode() == "banktransfer" )
        {
            $checkResult = $observer->getEvent()->getResult();
            $checkResult->setData('is_available', false);
        }
    }
}

Now, I don't know how to get all customers orders and if he had one processing order, that hides the payment method only in this case.

Maybe use $observer->getEvent()->getQuote() ?

Thanks for the help!

3

You are on a good path. To understand what is and isn't available it is helpful to check how the event is dispatched and used.

You have already found the event itself payment_method_is_active - searching for it in the codebase will reveal how it is called:

        $this->eventManager->dispatch(
            'payment_method_is_active',
            [
                'result' => $checkResult,
                'method_instance' => $this,
                'quote' => $quote
            ]
        );

        return $checkResult->getData('is_available');

The second parameter to the dispatch method shows what objects will be passed into the event. In this case you would have access to result, method_instance and the quote.

$observer->getEvent()->getOrder() would not yield anything.

For your use case I suggest utilising $observer->getEvent()->getQuote(). Then use the customer_id to run a search for any outstanding orders.

  • @RobertS. Kristof is given u the hint. From quote object $observer->getEvent()->getQuote() using you can get customer id $observer->getEvent()->getQuote()->getCustomerId(). – Amit Bera Aug 20 at 8:07
  • Now, you have to get order collection of that customer using customer id – Amit Bera Aug 20 at 8:08
2

In addition to @Kristof at Fooman

First, you get customer id of the current quote using $observer->getEvent()->getQuote()->getCustomerId().

After that get Order COllection of that customer id.

Observer code

<?php
namespace Ops\KgPayMethod\Observer;

use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\Event\Observer;
use Magento\Framework\Api\Filter;
use Magento\Framework\Api\FilterBuilder;
use Magento\Framework\Api\SearchCriteriaBuilder;
use Magento\Sales\Api\OrderRepositoryInterface;

class PaymentMethodAvailable implements ObserverInterface
{

    /**
     * @var \Magento\Framework\Api\SearchCriteriaBuilder
     */
    private $searchCriteriaBuilder;

    /**
     * @var \Magento\Framework\Api\FilterBuilder
     */
    private $filterBuilder;

    /**
     * @var \Magento\Sales\Api\OrderRepositoryInterface
     */
    private $orderRepository;

    public function __construct(
        OrderRepositoryInterface $orderRepository,
        SearchCriteriaBuilder $searchCriteriaBuilder,
        FilterBuilder $filterBuilder       
    ) {
        $this->orderRepository = $orderRepository;
        $this->filterBuilder = $filterBuilder;
        $this->searchCriteriaBuilder = $searchCriteriaBuilder;
    }

    public function execute(Observer $observer)
    {
        $quote = $observer->getEvent()->getQuote();

        if($quote === null){
            return $this;
        }
        // return immedia when Customer id does not exits on Guest Checkout
        if($quote->getCustomerId() === null  || $quote->getCustomerId() < 1 ){
            return $this;
        }
        $hasCustomerProcessingOrders = $this
                ->getOrderCollectionByCustomerId($quote->getCustomerId());
        if($hasCustomerProcessingOrders  && 
                $observer->getEvent()->getMethodInstance()->getCode() == "banktransfer" )
        {
            $checkResult = $observer->getEvent()->getResult();
            $checkResult->setData('is_available', false);
        }
    }

    /**
     * Get Customer List of Processing order 
     * 
     * @param int $customerId
     * @return boolean
     */
    private function getOrderCollectionByCustomerId($customerId)
    {
        $filterBuilder1 =[]; $filterBuilder2 = [];

        $filterBuilder1[] = $this->filterBuilder->setField('status')
                ->setConditionType('eq')
                ->setValue('processing')->create(); 

        $filterBuilder2[] = $this->filterBuilder
            ->setField('customer_id')
             ->setConditionType('eq')
            ->setValue($customerId)->create();

        $searchCriteria = $this->searchCriteriaBuilder
                ->addFilters($filterBuilder1)
                ->addFilters($filterBuilder2)
                ->setCurrentPage(1)
                ->setPageSize(1)
                ->create();
        $orders = $this->orderRepository->getList($searchCriteria);
        if($orders->getTotalCount() >= 1 ){
            return  true;
        }
        return false;

    }

}
  • Thanks for the help, but I have this error now.. "Aucune entité avec OrderId = 2" in French... – Robert S. Aug 20 at 8:52
  • I think the bug is on this line : $orders = $this->orderRepository->getList($searchCriteria); – Robert S. Aug 20 at 9:09
  • might be... i have checking this.. – Amit Bera Aug 20 at 9:14
  • if i change the criteria, it change the order id – Robert S. Aug 20 at 9:24
  • the condition was wrong, it is modified now. – Amit Bera Aug 20 at 9:34

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.