Вопрос

I am trying to trigger the customer invoice mail after an order has been paid and the invoice has been created. The payment gateways are PayPal Plus (iways) and Amazon Pay. If I understood correctly, these gateways automatically create the invoice as soon as the order has been processed successfully.

This is the module I wrote, but nothing happens after activating it and clearing cache:

app/code/Vendor/AutoSendInvoice/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_order_invoice_register">
        <observer name="VendorAutoSendInvoice" instance="Vendor\AutoSendInvoice\Observer\AutoSendInvoice" />
    </event>
</config>

This is the Observer app/code/Vendor/AutoSendInvoice/Observer/AutoSendInvoice.php

<?php
namespace Vendor\AutoSendInvoice\Observer;

use Magento\Framework\Event\ObserverInterface;
use Magento\Sales\Model\Order;
use Magento\Sales\Model\Order\Email\Sender\InvoiceSender;
use \Magento\Framework\Exception\LocalizedException;
use \Psr\Log\LoggerInterface;

class AutoSendInvoice implements ObserverInterface
{
    /**
     * @var \Magento\Sales\Model\OrderFactory
     */
    protected $orderModel;

    /**
     * @var \Magento\Sales\Model\Order\Email\Sender\InvoiceSender
     */
    protected $invoiceSender;

    /**
     * Logger
     * @var LoggerInterface
     */
    protected $logger;


    /**
     * @param \Magento\Sales\Model\OrderFactory $orderModel
     * @param InvoiceSender $invoiceSender
     * @param LoggerInterface $logger
     */
    public function __construct(
        \Magento\Sales\Model\OrderFactory $orderModel,
        \Magento\Sales\Model\Order\Email\Sender\InvoiceSender $invoiceSender,
        LoggerInterface $logger
    )
    {
        $this->orderModel = $orderModel;
        $this->invoiceSender = $invoiceSender;
        $this->logger = $logger;
    }

    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        // get the corresponding order & invoice
        $invoice = $observer->getEvent()->getInvoice(); 
$order = $invoice->getOrder();


        if (!$order->getId()) {
            throw new LocalizedException(__('The order no longer exists.'));
        }

        // send invoice email only for PayPal Plus and Amazon Pay AND if order status is "new" or "processing"
        if ( $this->checkPaymentMethod($order ) && $this->checkStateOrder($order )
            ) {
                try {
                    // check if order is allowed to create invoice
                    $this->checkOrder($order);

                    // send invoice email
                    try {
                        $this->invoiceSender->send($invoice);
                    } catch (\Exception $e) {
                        $this->logger->error($e->getMessage());
                    }

                    // add order comment
                    $order->addStatusHistoryComment(
                        'Automatically Invoiced by Vendor',
                        true
                    )->save();


                } catch (\Exception $e) {
                    $this->logger->error($e->getMessage());
                }
            }
        }


    /**
     * @param $order
     * @throws LocalizedException
     */
    protected function checkOrder($order)
    {
        if (!$order->canInvoice()
        ) {
            throw new LocalizedException(
                __('The order does not allow an invoice to be created.')
            );
        }
    }

    protected function checkPaymentMethod($order) {
        // get the payment method for corresponding order
        $payment = $order->getPayment()->getMethodInstance()->getCode();

        if ( $payment == 'iways_paypalplus_payment' || $payment == 'amazon_payment' ) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * Check State Order
     *
     * @param $order
     * @return bool
     */
    protected function checkStateOrder($order)
    {
        if ($order->getState() == Order::STATE_NEW || $order->getState() == Order::STATE_PROCESSING) {
            return true;
        } else {
            return false;
        }
    }
}

I am not getting any error.

Это было полезно?

Решение

If you need the entity_id of the new created invoice you have to choose a later event. For example sales_order_invoice_save_after. Here you will always have the entity_id. Downside of this approach: An invoice is usually saved more than once in the lifecycle.

But you can check for $invoice->getEmailSent() in your code and send the email only if it not has been send earlier.

So changing the event in your xml file to sales_order_invoice_save_after and the condition in your code as follows should give you what you need:

if ( $this->checkPaymentMethod($order) 
     && $this->checkStateOrder($order)
     && !$invoice->getEmailSent()
     ){

    //your other code here...
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с magento.stackexchange
scroll top