Sylius / InvoicingPlugin

Generate an Invoice for every placed order
MIT License
79 stars 82 forks source link

Configure plugin to send invoice when order is placed #179

Open aleksmark opened 4 years ago

aleksmark commented 4 years ago

Is this possible to achieve this by overriding the default behavior of the state machine https://github.com/Sylius/InvoicingPlugin#extension-points

or I would need to override classes and extend the plugin myself?

TELLO0815 commented 3 years ago

I did like this:

service.yml

    app.listener.send_invoice_on_order:
        class: App\EventListener\SendInvoiceOnOrderListener
        arguments: ['@sylius_invoicing_plugin.creator.invoice', '@sylius_invoicing_plugin.custom_repository.invoice', '@sylius_invoicing_plugin.email.invoice_email_sender', '@sylius.repository.order']
        tags:
            - { name: messenger.message_handler, event: sylius_invoicing_plugin.event_bus }
<?php

declare(strict_types=1);

namespace App\EventListener;

use Sylius\Component\Core\Model\CustomerInterface;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\Repository\OrderRepositoryInterface;
use Sylius\InvoicingPlugin\Creator\InvoiceCreatorInterface;
use Sylius\InvoicingPlugin\Email\InvoiceEmailSenderInterface;
use Sylius\InvoicingPlugin\Entity\InvoiceInterface;
use Sylius\InvoicingPlugin\Event\OrderPlaced;
use Sylius\InvoicingPlugin\Exception\InvoiceAlreadyGenerated;
use Sylius\InvoicingPlugin\Repository\InvoiceRepository;

final class SendInvoiceOnOrderListener
{
    /** @var InvoiceCreatorInterface */
    private $invoiceCreator;

    /** @var InvoiceRepository */
    private $invoiceRepository;

    /** @var OrderRepositoryInterface */
    private $orderRepository;

    /** @var InvoiceEmailSenderInterface */
    private $invoiceEmailSender;

    public function __construct(
        InvoiceCreatorInterface $invoiceCreator,
        InvoiceRepository $invoiceRepository,
        InvoiceEmailSenderInterface $invoiceEmailSender,
        OrderRepositoryInterface $orderRepository
    )
    {
        $this->invoiceCreator = $invoiceCreator;
        $this->invoiceRepository = $invoiceRepository;
        $this->invoiceEmailSender = $invoiceEmailSender;
        $this->orderRepository = $orderRepository;
    }

    public function __invoke(OrderPlaced $event): void
    {
        try {
            $this->invoiceCreator->__invoke($event->orderNumber(), $event->date());
        } catch (InvoiceAlreadyGenerated $exception) {
            return;
        }
        /** @var InvoiceInterface $invoice */
        $invoice = $this->invoiceRepository->findOneByOrderNumber($event->orderNumber());

        /** @var OrderInterface $order */
        $order = $this->orderRepository->findOneBy(['number' => $event->orderNumber()]);

        /** @var CustomerInterface $customer */
        $customer = $order->getCustomer();

        $this->invoiceEmailSender->sendInvoiceEmail($invoice, $customer->getEmail());

    }
}