<?php
declare(strict_types=1);
namespace Bluue\SalesBundle\EventSubscriber\ProductsBundle;
use Bluue\ProductsBundle\Entity\Declination;
use Bluue\ProductsBundle\Entity\Product;
use Bluue\ProductsBundle\Event\ProductDocumentEvent;
use Bluue\SalesBundle\Entity\CreditNote;
use Bluue\SalesBundle\Entity\DeliveryNote;
use Bluue\SalesBundle\Entity\Invoice;
use Bluue\SalesBundle\Entity\Order;
use Bluue\SalesBundle\Entity\Quotation;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityRepository;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Routing\RouterInterface;
class ProductDocumentEventSubscriber implements EventSubscriberInterface
{
/**
* @var EntityManagerInterface
*/
private EntityManagerInterface $em;
/**
* @var RouterInterface
*/
private RouterInterface $router;
/**
* @param EntityManagerInterface $em
* @param RouterInterface $router
*/
public function __construct(
EntityManagerInterface $em,
RouterInterface $router
) {
$this->em = $em;
$this->router = $router;
}
/**
* @return array
*/
public static function getSubscribedEvents(): array
{
return [
ProductDocumentEvent::PRODUCT => 'onProduct',
ProductDocumentEvent::DECLINATION => 'onDeclination'
];
}
/**
* @param object $object
* @return array
*/
private function getDocuments(object $object): array
{
$entities = ['Quotation', 'Order', 'Invoice', 'CreditNote', 'DeliveryNote'];
$documents = [];
foreach ($entities as $entity) {
if ($entity == 'Quotation') {
$repo = $this->em->getRepository(Quotation::class);
} elseif ($entity == 'Order') {
$repo = $this->em->getRepository(Order::class);
} elseif ($entity == 'Invoice') {
$repo = $this->em->getRepository(Invoice::class);
} elseif ($entity == 'CreditNote') {
$repo = $this->em->getRepository(CreditNote::class);
} elseif ($entity == 'DeliveryNote') {
$repo = $this->em->getRepository(DeliveryNote::class);
}
/** @var EntityRepository $repo */
$query = $repo->createQueryBuilder('u')
->select('u.id, u.reference')
->leftJoin('u.lines', 'lines')
->groupBy('u.id')
->andWhere('u.validatedAt IS NULL')
->setParameter('object_id', $object->getId()->toBinary());
if ($object instanceof Product) {
$query->andWhere('lines.product = :object_id');
} elseif ($object instanceof Declination) {
$query->andWhere('lines.declination = :object_id');
}
$results = $query->getQuery()->getResult();
if ($results) {
foreach ($results as &$result) {
if ($entity == 'Invoice' || $entity == 'CreditNote') {
if (!$result['reference']) {
$result['reference'] = $entity == 'Invoice' ? 'Facture' : 'Avoir';
}
}
if ($entity == 'CreditNote') {
$entityUrl = 'credit_note';
} elseif ($entity == 'DeliveryNote') {
$entityUrl = 'delivery_note';
} else {
$entityUrl = strtolower($entity);
}
$result['url'] = $this->router->generate(
'sales_bundle__' . $entityUrl . '_view',
['id' => $result['id']]
);
}
$documents = array_merge($documents, $results);
}
}
return $documents;
}
/**
* @param ProductDocumentEvent $event
* @return void
*/
public function onProduct(ProductDocumentEvent $event): void
{
$product = $event->getObject();
$documents = $event->getDocuments();
$documents[] = $this->getDocuments($product);
$event->setDocuments($documents);
}
/**
* @param ProductDocumentEvent $event
* @return void
*/
public function onDeclination(ProductDocumentEvent $event): void
{
$declination = $event->getObject();
$documents = $event->getDocuments();
$documents[] = $this->getDocuments($declination);
$event->setDocuments($documents);
}
}