<?php
declare(strict_types=0);
/*
* WellCommerce Foundation
*
* This file is part of the WellCommerce package.
*
* (c) Adam Piotrowski <adam@wellcommerce.org>, Adrian Potepa <adrian@wellcommerce.org>
*
* For the full copyright and license information,
* please view the LICENSE file that was distributed with this source code.
*/
namespace WellCommerce\Bundle\OrderBundle\EventListener;
use Doctrine\Common\Collections\Criteria;
use Psr\Container\ContainerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Messenger\Stamp\DelayStamp;
use WellCommerce\Bundle\AppBundle\Entity\Client;
use WellCommerce\Bundle\AppBundle\Entity\NewsletterSubscriber;
use WellCommerce\Bundle\AppBundle\Manager\NewsletterSubscriberManager;
use WellCommerce\Bundle\CoreBundle\DependencyInjection\AbstractServiceSubscriber;
use WellCommerce\Bundle\CoreBundle\Doctrine\Event\EntityEvent;
use WellCommerce\Bundle\OrderBundle\Entity\Invoice;
use WellCommerce\Bundle\OrderBundle\Entity\Order;
use WellCommerce\Bundle\OrderBundle\Entity\OrderProduct;
use WellCommerce\Bundle\OrderBundle\Manager\InvoiceManager;
use WellCommerce\Bundle\OrderBundle\Manager\OrderManager;
use WellCommerce\Bundle\OrderBundle\Service\Messenger\MissingCartMessage;
use WellCommerce\Bundle\OrderBundle\Service\Messenger\OrderDuplicateMessage;
use WellCommerce\Bundle\OrderBundle\Service\Order\Visitor\OrderVisitorTraverser;
use WellCommerce\Component\Form\Elements\Fieldset\FieldsetInterface;
use WellCommerce\Component\Form\Event\FormEvent;
/**
* Class OrderSubscriber
*
* @author Adam Piotrowski <adam@wellcommerce.org>
*/
class OrderSubscriber extends AbstractServiceSubscriber implements EventSubscriberInterface
{
protected OrderManager $manager;
protected InvoiceManager $invoiceManager;
protected OrderVisitorTraverser $orderVisitorTraverser;
protected NewsletterSubscriberManager $newsletterSubscriberManager;
public function __construct(
ContainerInterface $locator,
OrderManager $manager,
InvoiceManager $invoiceManager,
OrderVisitorTraverser $orderVisitorTraverser,
NewsletterSubscriberManager $newsletterSubscriberManager
) {
parent::__construct($locator);
$this->manager = $manager;
$this->invoiceManager = $invoiceManager;
$this->orderVisitorTraverser = $orderVisitorTraverser;
$this->newsletterSubscriberManager = $newsletterSubscriberManager;
}
public static function getSubscribedEvents()
{
return [
'order.pre_create' => ['onOrderChangedEvent', 0],
'order.pre_update' => ['onOrderChangedEvent', 0],
'order.post_confirm' => ['onOrderConfirmEvent', 0],
'admin.client.pre_form_init' => ['onClientAdminFormInit', 10],
];
}
protected function queueMissingCart(Order $order)
{
if (false === $order->isMissingCartQueued() && false === $order->isConfirmed() && (int)$order->getId() > 0) {
$interval = $order->getShop()->getMissingCartInterval() * 60 * 1000;
$email = $order->getContactDetails()->getEmail();
if ($this->getMailerHelper()->isEmailValid($email) && $interval > 0) {
$this->getMessageBus()->dispatch(new MissingCartMessage($order->getId()), [
new DelayStamp($interval),
]);
$order->setMissingCartQueued(true);
}
}
}
public function onOrderConfirmEvent(EntityEvent $event)
{
$order = $event->getEntity();
if ($order instanceof Order) {
$configuration = $this->getShopStorage()->getCurrentShop()->getMailerConfiguration();
$email = $order->getContactDetails()->getEmail();
$shop = $order->getShop();
$title = $this->getTranslatorHelper()->trans('order.email.title.order_created', [
'%orderNumber%' => $order->getNumber(),
]);
$this->getMailerHelper()->sendEmail([
'recipient' => [$order->getContactDetails()->getEmail(), $configuration->getTo()],
'subject' => $title,
'template' => 'WellCommerceOrderBundle:Email:order_created.html.twig',
'parameters' => [
'order' => $order,
],
'configuration' => $this->getShopStorage()->getCurrentShop()->getMailerConfiguration(),
]);
$message = $this->getCurrencyHelper()->convertAndFormat($order->getSummary()->getGrossAmount(), $order->getCurrency());
$this->getPusherHelper()->redirect(
'Nowe zamówienie ' . $order->getNumber(),
'Klient: ' . $order->getContactDetails()->getEmail() . ' o wartości ' . $message,
'admin.order.edit',
['id' => $order->getId()]
);
if ($order->getClientDetails()->isNewsletterAccepted()) {
$subscriber = $this->newsletterSubscriberManager->getRepository()->findOneBy([
'email' => $email,
'shop' => $shop,
]);
if (!$subscriber instanceof NewsletterSubscriber) {
/** @var NewsletterSubscriber $subscriber */
$subscriber = $this->newsletterSubscriberManager->initResource();
$subscriber->setEnabled($order->getClientDetails()->isNewsletterAccepted());
$subscriber->setEmail($email);
$subscriber->setConditionsAccepted($order->getClientDetails()->isNewsletterAccepted());
$subscriber->setClient($order->getClient());
$subscriber->setShop($shop);
if (false === $subscriber->getShop()->getNewsletterSettings()->isSendConfirmationEmail()) {
$subscriber->setEnabled(true);
}
$this->newsletterSubscriberManager->createResource($subscriber);
}
}
$this->getMessageBus()->dispatch(new OrderDuplicateMessage($order->getId()), [
new DelayStamp(500),
]);
}
}
public function onOrderChangedEvent(EntityEvent $event)
{
$order = $event->getEntity();
if ($order instanceof Order) {
if ('' === $order->getShippingAddress()->getCountry()) {
$order->getShippingAddress()->setCountry($order->getShop()->getDefaultCountry());
}
if ('' === $order->getBillingAddress()->getCountry()) {
$order->getBillingAddress()->setCountry($order->getShop()->getDefaultCountry());
}
$this->orderVisitorTraverser->traverse($order);
$this->queueMissingCart($order);
}
}
public function onClientAdminFormInit(FormEvent $event)
{
$resource = $event->getResource();
if ($resource instanceof Client) {
$form = $event->getForm();
$builder = $event->getFormBuilder();
/** @var FieldsetInterface $ordersFieldset */
$ordersFieldset = $form->addChild(
$builder->getElement('nested_fieldset', [
'name' => 'orders',
'label' => 'Zamówienia',
])
);
/** @var FieldsetInterface $ordersFieldset */
$invoiceFieldset = $form->addChild(
$builder->getElement('nested_fieldset', [
'name' => 'invoices',
'label' => 'Faktury',
])
);
/** @var FieldsetInterface $cartsFieldset */
$cartsFieldset = $form->addChild(
$builder->getElement('nested_fieldset', [
'name' => 'carts',
'label' => 'Koszyk',
])
);
$invoices = $resource->getInvoices();
$orders = $resource->getOrders()->filter(function (Order $order) {
return $order->isConfirmed();
});
$criteria = new Criteria();
$criteria->andWhere($criteria->expr()->eq('client', $resource));
$criteria->andWhere($criteria->expr()->eq('confirmed', false));
$carts = $this->manager->getCollection($criteria);
if ($orders->count() === 0) {
$ordersFieldset->addChild(
$builder->getElement('tip', [
'tip' => 'Klient nie złożył jeszcze żadnych zamówień.',
])
);
} else {
$html = '<ul class="changes-detailed">';
$orders->map(function (Order $order) use ($form, $builder, &$html) {
$orderUrl = $this->getRouterHelper()->generateUrl('admin.order.edit', ['id' => $order->getId()]);
$currency = $order->getCurrency();
$amount = $this->getCurrencyHelper()->format($order->getSummary()->getGrossAmount(), $currency, $currency);
$html .= '<li style="border-bottom: 1px solid #dfdfdf;list-style: none;margin-bottom: 15px;">';
$html .= ' <p><a href="' . $orderUrl . '"><strong>#' . $order->getNumber() . '</strong></a></p>';
$html .= ' <p>Data: ' . $order->getCreatedAt()->format('Y-m-d H:i:s') . '</p>';
$html .= ' <p>Kwota zamówienia: ' . $amount . '</p>';
$html .= '</li > ';
});
$html .= '</ul > ';
$ordersFieldset->addChild(
$builder->getElement('static_text', [
'text' => $html,
])
);
}
if ($invoices->count() === 0) {
$invoiceFieldset->addChild(
$builder->getElement('tip', [
'tip' => 'Dla klienta nie zostały wystawione żadne faktury.',
])
);
} else {
$html = '<ul class="changes-detailed">';
$invoices->map(function (Invoice $invoice) use ($form, $builder, &$html) {
$invoiceUrl = $this->getRouterHelper()->generateUrl('admin.invoice.edit', ['id' => $invoice->getId()]);
$html .= '<li style="border-bottom: 1px solid #dfdfdf;list-style: none;margin-bottom: 15px;">';
$html .= ' <p><a href="' . $invoiceUrl . '"><strong>#' . $invoice->getNumber() . '</strong></a></p>';
$html .= ' <p>Data: ' . $invoice->getCreatedAt()->format('Y-m-d H:i:s') . '</p>';
$html .= '</li > ';
});
$html .= '</ul > ';
$invoiceFieldset->addChild(
$builder->getElement('static_text', [
'text' => $html,
])
);
}
if ($carts->count() === 0) {
$cartsFieldset->addChild(
$builder->getElement('tip', [
'tip' => 'Klient nie posiada żadnych koszyków',
])
);
} else {
/** @var Order $cart */
$cart = $carts->first();
if ($cart instanceof Order) {
$products = $cart->getProducts();
if ($products->count() === 0) {
$cartsFieldset->addChild(
$builder->getElement('tip', [
'tip' => 'Koszyk klienta jest pusty.',
])
);
} else {
$html = '<ul class="changes-detailed">';
$products->map(function (OrderProduct $orderProduct) use ($form, $builder, &$html) {
$product = $orderProduct->getProduct();
$productUrl = $this->getRouterHelper()->generateUrl('admin.product.edit', ['id' => $product->getId()]);
$photo = (null !== $product->getPhoto()) ? $product->getPhoto()->getPath() : '';
$image = $this->getImageHelper()->getImage($photo, 'small');
$html .= '<li style="border-bottom: 1px solid #dfdfdf;list-style: none;margin-bottom: 15px;">';
$html .= ' <p><img style="width: 100px;" src="' . $image . '" /></p>';
$html .= ' <p><a href="' . $productUrl . '"><strong>' . $orderProduct->getQuantity() . ' x ' . sprintf(
'%s (%s)',
$product->translate()->getName(),
$product->getSku()
) . '</strong></a></p>';
$html .= ' <p>Dodany: ' . $orderProduct->getCreatedAt()->format('Y-m-d H:i:s') . ' </p > ';
$html .= '</li > ';
});
$html .= '</ul > ';
$cartsFieldset->addChild(
$builder->getElement('static_text', [
'text' => $html,
])
);
}
} else {
$cartsFieldset->addChild(
$builder->getElement('tip', [
'tip' => 'Klient nie posiada jeszcze koszyka.',
])
);
}
}
}
}
}