<?php
/**
* @author Léo BANNHOLTZER (contact@scaledev.fr)
* @copyright 2021 - ScaleDEV SAS, 12 RUE CHARLES MORET, 10120 ST ANDRE LES VERGERS
* @license commercial
*/
declare(strict_types=1);
namespace Bluue\ShipmentsBundle\EventSubscriber\SalesBundle;
use App\Services\Configuration;
use Doctrine\ORM\EntityManagerInterface;
use Bluue\ShipmentsBundle\Entity\OrderOptions;
use Bluue\SalesBundle\Event\DeliveryNoteMovementsEvent;
use Bluue\ProductsBundle\Services\WeightProductListService;
use Bluue\ShipmentsBundle\Repository\OrderOptionsRepository;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class DeliveryNoteSubscriber implements EventSubscriberInterface
{
/**
* @var OrderOptionsRepository $orderOptionsRepo
*/
private OrderOptionsRepository $orderOptionsRepo;
/**
* @var WeightProductListService $weightProductListService
*/
private WeightProductListService $weightProductListService;
/**
* @var EntityManagerInterface $em
*/
private EntityManagerInterface $em;
/**
* @var Configuration $config
*/
private Configuration $config;
public function __construct(
OrderOptionsRepository $orderOptionsRepo,
WeightProductListService $weightProductListService,
EntityManagerInterface $em,
Configuration $config
) {
$this->orderOptionsRepo = $orderOptionsRepo;
$this->weightProductListService = $weightProductListService;
$this->em = $em;
$this->config = $config;
}
/**
* @return array
*/
public static function getSubscribedEvents(): array
{
return [
DeliveryNoteMovementsEvent::VALIDATE_DELIVERY => 'validateDelivery',
DeliveryNoteMovementsEvent::CANCEL_DELIVERY => 'cancelDelivery'
];
}
/**
* @param DeliveryNoteMovementsEvent $event
* @return void
*/
public function validateDelivery(DeliveryNoteMovementsEvent $event): void
{
$deliveryNote = $event->getDeliveryNote();
$order = $deliveryNote->getOrder();
if (!$order) {
return;
}
$deliveryNoteId = $deliveryNote->getId();
$order_options = $this->orderOptionsRepo->findOneBy(
['order' => $order, 'delivery_note' => null]
);
if (!$order_options) {
$order_options = $this->orderOptionsRepo->findOneBy(
['order' => $order, 'delivery_note' => $deliveryNote]
);
}
if ($order_options && $order_options->getBurst()) {
$order_options->setDeliveryNote($deliveryNote);
} else {
if (!$this->config->get('shipments_bundle__delivery_note_and_label_merged')) {
$order_options = $this->orderOptionsRepo->findOneBy(['delivery_note' => $deliveryNoteId]);
if (!$order_options) {
$order_options = new OrderOptions();
$order_options->setOrder($order);
$order_options->setDeliveryNote($deliveryNote);
}
} else {
if (!$order_options) {
$order_options = new OrderOptions();
$order_options->setOrder($order);
}
$order_options->setDeliveryNote($deliveryNote);
}
}
$product_list_element = [];
foreach ($deliveryNote->getProductLines() as $deliveryNoteLine) {
$quantity = $deliveryNoteLine->getQuantity();
$options = $deliveryNoteLine->getOptions();
$product = $options['product'];
$virtualQuantity = $product['virtual_quantity'] ?? 1;
if ($deliveryNoteLine->isDeclination()) {
$product_list_element[] = [
'quantity' => $quantity * $virtualQuantity,
'product_id' => $product['id'],
'declination_id' => $product['declination_id']
];
} elseif ($deliveryNoteLine->isProduct()) {
$product_list_element[] = [
'quantity' => $quantity,
'product_id' => $product['id']
];
}
}
if ($total_weight = $this->weightProductListService->getTotalWeight($product_list_element)) {
$order_options->setWeight((string) $total_weight);
}
if (
$orderOptions = $this->orderOptionsRepo->findOneBy(
['order' => $order->getId(), 'delivery_note' => null]
)
) {
if ($carrier = $orderOptions->getCarrier()) {
$order_options->setCarrier($carrier);
}
}
$order_options->setStatus(1);
$this->em->persist($order_options);
$this->em->flush();
}
/**
* @param DeliveryNoteMovementsEvent $event
* @return void
*/
public function cancelDelivery(DeliveryNoteMovementsEvent $event): void
{
$deliveryNote = $event->getDeliveryNote();
if (!$deliveryNote->getOrder()) {
return;
}
$deliveryNoteOrderOptions = $this->orderOptionsRepo->findOneBy(['delivery_note' => $deliveryNote]);
if ($deliveryNoteOrderOptions) {
$order_options = $this->orderOptionsRepo->createQueryBuilder('oo')
->select('COUNT(oo.id)')
->where('oo.order = :order_id')
->setParameter('order_id', $deliveryNote->getOrder()->getId()->toBinary())
->andWhere('oo.id != :oo_id')
->setParameter('oo_id', $deliveryNoteOrderOptions->getId()->toBinary())
->getQuery()->getSingleScalarResult();
if ($order_options) {
$this->em->remove($deliveryNoteOrderOptions);
} else {
$deliveryNoteOrderOptions->setDeliveryNote(null);
$deliveryNoteOrderOptions->setBurst(null);
$deliveryNoteOrderOptions->setStatus(0);
$this->em->persist($deliveryNoteOrderOptions);
}
$this->em->flush();
}
}
}