src/Evo/Infrastructure/DoctrineSubscriber/InvoiceSubscriber.php line 106

Open in your IDE?
  1. <?php
  2. namespace Evo\Infrastructure\DoctrineSubscriber;
  3. use App\Enum\ActivityLogCategoryEnum;
  4. use App\Enum\InvoiceStatusEnum;
  5. use App\Enum\InvoiceTypeEnum;
  6. use App\Enum\OrganizationStatusEnum;
  7. use App\Enum\OrganizationStatusPayedEnum;
  8. use App\Enum\PaymentStatusEnum;
  9. use App\Enum\PaymentTypeEnum;
  10. use App\Enum\ProductKeyEnum;
  11. use App\Enum\QuoteStatusEnum;
  12. use App\Repository\UserRepository;
  13. use App\Service\Invoices\InvoiceService;
  14. use App\Service\OrganizationUtils;
  15. use App\Service\SegmentAPI;
  16. use App\Traits\SentryNotifyTrait;
  17. use App\Utils\InvoiceUtils;
  18. use Doctrine\Common\EventSubscriber;
  19. use Doctrine\ORM\EntityManagerInterface;
  20. use Doctrine\ORM\Event\PreUpdateEventArgs;
  21. use Doctrine\Persistence\Event\LifecycleEventArgs;
  22. use Evo\Infrastructure\MappingORM\ActivityLog;
  23. use Evo\Infrastructure\MappingORM\DiscountCode;
  24. use Evo\Infrastructure\MappingORM\Invoice;
  25. use Evo\Infrastructure\MappingORM\Organization;
  26. use Evo\Infrastructure\MappingORM\Payment;
  27. use Evo\Infrastructure\MappingORM\PostalAddress;
  28. use Evo\Infrastructure\MappingORM\Product;
  29. use Evo\Infrastructure\MappingORM\PromoCodeHistory;
  30. use Evo\Infrastructure\MappingORM\User;
  31. use Evo\Infrastructure\Messenger\Message\SyncBillingReportMessage;
  32. use Evo\Infrastructure\Repository\InvoiceRepository;
  33. use Symfony\Component\HttpFoundation\Request;
  34. use Symfony\Component\HttpFoundation\RequestStack;
  35. use Symfony\Component\HttpFoundation\Response;
  36. use Symfony\Component\Mercure\HubInterface;
  37. use Symfony\Component\Mercure\Update;
  38. use Symfony\Component\Messenger\Bridge\AmazonSqs\Transport\AmazonSqsFifoStamp;
  39. use Symfony\Component\Messenger\Envelope;
  40. use Symfony\Component\Messenger\MessageBusInterface;
  41. use Symfony\Component\Security\Core\Security;
  42. use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
  43. use Symfony\Contracts\HttpClient\HttpClientInterface;
  44. class InvoiceSubscriber implements EventSubscriber
  45. {
  46.     use SentryNotifyTrait;
  47.     private EntityManagerInterface $em;
  48.     private OrganizationUtils $organizationUtils;
  49.     private SegmentAPI $segmentAPI;
  50.     private InvoiceUtils $invoiceUtils;
  51.     private HttpClientInterface $client;
  52.     private Security $security;
  53.     private HubInterface $hub;
  54.     private InvoiceRepository $invoiceRepository;
  55.     private MessageBusInterface $bus;
  56.     private RequestStack $request;
  57.     private InvoiceService $invoiceService;
  58.     public function __construct(
  59.         OrganizationUtils $organizationUtils,
  60.         SegmentAPI $segmentAPI,
  61.         InvoiceUtils $invoiceUtils,
  62.         HttpClientInterface $client,
  63.         Security $security,
  64.         EntityManagerInterface $em,
  65.         HubInterface $hub,
  66.         InvoiceRepository $invoiceRepository,
  67.         RequestStack $request,
  68.         MessageBusInterface $bus,
  69.         InvoiceService $invoiceService
  70.     ) {
  71.         $this->organizationUtils $organizationUtils;
  72.         $this->segmentAPI $segmentAPI;
  73.         $this->invoiceUtils $invoiceUtils;
  74.         $this->client $client;
  75.         $this->em $em;
  76.         $this->security $security;
  77.         $this->hub $hub;
  78.         $this->invoiceRepository $invoiceRepository;
  79.         $this->request $request;
  80.         $this->bus $bus;
  81.         $this->invoiceService $invoiceService;
  82.     }
  83.     public function getSubscribedEvents(): array
  84.     {
  85.         return [
  86.             'preUpdate',
  87.             'postUpdate',
  88.             'prePersist',
  89.             'postPersist',
  90.             'preRemove',
  91.         ];
  92.     }
  93.     /**
  94.      * @throws TransportExceptionInterface
  95.      */
  96.     public function postPersist(LifecycleEventArgs $args): void
  97.     {
  98.         $entity $args->getObject();
  99.         if (!$entity instanceof Invoice) {
  100.             return;
  101.         }
  102.         $quote $entity->getQuote();
  103.         if (InvoiceStatusEnum::PAID === $entity->getStatus() && ($quote && QuoteStatusEnum::VALID !== $quote->getStatus())) {
  104.             $quote->setStatus(QuoteStatusEnum::VALID);
  105.             $this->em->persist($quote);
  106.             $this->em->flush();
  107.         }
  108.         if (in_array($entity->getStatus(), [InvoiceStatusEnum::SENTInvoiceStatusEnum::PARTIALLY_PAIDInvoiceStatusEnum::PAID], true)) {
  109.             $this->invoiceUtils->generateInvoice($entity);
  110.         }
  111.         $request $this->request->getCurrentRequest();
  112.         if ($request instanceof Request) {
  113.             $data json_decode($request->getContent(), true);
  114.             $isAccountsSubmission $data['isAccountsSubmission'] ?? $request->get('isAccountsSubmission');
  115.             if ($isAccountsSubmission) {
  116.                 $payment = new Payment();
  117.                 $payment->setType(PaymentTypeEnum::GOCARDLESS);
  118.                 $payment->setPaidOutAt(new \DateTime($entity->getCreatedAt()->format('Y-m-d H:s:i')));
  119.                 $payment->setAmount($entity->getPrice());
  120.                 $payment->setInvoice($entity);
  121.                 $entity->addPayment($payment);
  122.                 $payment->setStatus(PaymentStatusEnum::WAITING);
  123.                 $this->em->persist($payment);
  124.                 $this->em->flush();
  125.             }
  126.         }
  127.         $this->invoiceUtils->generatePaymentGocardless($entity->getPrice(), $entity);
  128.         $this->createOrganizationPrescriber($entity);
  129.         $organization $entity->getOrganization();
  130.         if (null !== $organization) {
  131.             $items $entity->getItems();
  132.             foreach ($items as $itemPerInvoice) {
  133.                 $product $itemPerInvoice->getProduct();
  134.                 if (ProductKeyEnum::IMMATRICULATION === $product->getUniqueKey() && !$organization->getIsNewImmatriculation()) {
  135.                     $organization->setIsNewImmatriculation(true);
  136.                     $this->em->persist($organization);
  137.                     $this->em->flush();
  138.                 }
  139.             }
  140.             if (InvoiceStatusEnum::PAID === $entity->getStatus()) {
  141.                 $status $this->organizationUtils->checkStatusDomiciliation($organization);
  142.                 if ($status) {
  143.                     $organization->setStatus($status);
  144.                     $this->em->persist($organization);
  145.                     $this->em->flush();
  146.                 }
  147.             }
  148.             if (null !== $organization->getId()) {
  149.                 $this->invoiceUtils->checkUnpaid($organization);
  150.             }
  151.         }
  152.         if ($entity->isModel()) {
  153.             return;
  154.         }
  155.         /*
  156.          * Track segment
  157.          */
  158.         $this->segmentAPI->identifyNewInvoice($entity);
  159.         $this->segmentAPI->trackInvoiceStatus($entity);
  160.         $this->segmentAPI->trackInvoiceCreated($entity);
  161.         $this->segmentAPI->trackInvoicePaid($entity);
  162.         $this->segmentAPI->trackError($entity);
  163.         try {
  164.             $this->handleZapierHook($entity->getId(), $organization);
  165.         } catch (\Exception $e) {
  166.             $this->sendSentryMessage($e->getMessage());
  167.         }
  168.         $duplicatedInvoices $this->invoiceRepository->getDuplicatedInvoice(nulltrue);
  169.         if (\count($duplicatedInvoices) > 0) {
  170.             $update = new Update(
  171.                 'http://api.digidom.pro/signal/check/duplicated/invoice',
  172.                 json_encode([
  173.                     'status' => 'duplicated',
  174.                 ], JSON_THROW_ON_ERROR)
  175.             );
  176.             $this->hub->publish($update);
  177.         }
  178.         try {
  179.             $this->invoiceService->processInvoiceReactivationFee($entity);
  180.         } catch (\Exception $e) {
  181.             $this->sendSentryMessage($e->getMessage());
  182.         }
  183.         try {
  184.             if (null !== $entity->getNumber()) {
  185.                 $this->bus->dispatch((new Envelope(
  186.                     new SyncBillingReportMessage($entity->getId())
  187.                 ))->with(
  188.                     new AmazonSqsFifoStamp('SyncBillingReport'uniqid(''true))
  189.                 ));
  190.             }
  191.         } catch (\Exception $e) {
  192.             $this->sendSentryMessage($e->getMessage());
  193.         }
  194.         // create subscription if not exist
  195.         $this->invoiceService->createIfMissingFromInvoice($entity);
  196.     }
  197.     public function preRemove(LifecycleEventArgs $args): void
  198.     {
  199.         $entity $args->getObject();
  200.         if (!$entity instanceof Invoice) {
  201.             return;
  202.         }
  203.         if ($entity->isModel()) {
  204.             return;
  205.         }
  206.         $user $this->security->getUser();
  207.         $organization $entity->getOrganization();
  208.         $activityLog = new ActivityLog();
  209.         $activityLog->setOrganization($organization);
  210.         $user instanceof User $activityLog->setUser($user) : $activityLog->setUser(null);
  211.         $activityLog->setObject('SUPPRESSION FACTURE');
  212.         $activityLog->setMethod('CREATION');
  213.         $activityLog->setCategory(ActivityLogCategoryEnum::INCIDENT);
  214.         $activityLog->setNote($entity->getName());
  215.         $this->em->persist($activityLog);
  216.         $this->em->flush();
  217.     }
  218.     public function postUpdate(LifecycleEventArgs $args): void
  219.     {
  220.         $entity $args->getObject();
  221.         if (!$entity instanceof Invoice) {
  222.             return;
  223.         }
  224.         $uow $this->em->getUnitOfWork();
  225.         $uow->computeChangeSets();
  226.         $changeset $uow->getEntityChangeSet($entity);
  227.         if (=== count($changeset) && isset($changeset['updatedAt'])) {
  228.             return;
  229.         }
  230.         if (=== count($changeset) && isset($changeset['reference'])) {
  231.             return;
  232.         }
  233.         if (=== count($changeset) && isset($changeset['invoiceType'])) {
  234.             return;
  235.         }
  236.         if ((isset($changeset['path'], $changeset['updatedAt']) && === count($changeset)) || isset($changeset['isImported'])) {
  237.             return;
  238.         }
  239.         if (=== count($changeset) && isset($changeset['isDomiciliation'])) {
  240.             return;
  241.         }
  242.         $organization $entity->getOrganization();
  243.         if (isset($changeset['number'])) {
  244.             try {
  245.                 $this->invoiceUtils->generateInvoice($entity);
  246.             } catch (\Exception $e) {
  247.                 $this->sendSentryMessage($e->getMessage());
  248.             }
  249.         }
  250.         if (
  251.             isset($changeset['discountCode'])
  252.             && $changeset['discountCode'][1] &&
  253.             $organization
  254.         ) {
  255.             /** @var DiscountCode $discountCode */
  256.             $discountCode $changeset['discountCode'][1];
  257.             $promoCodeHistory = new PromoCodeHistory();
  258.             $promoCodeHistory->addDiscountCode($discountCode);
  259.             $promoCodeHistory->setPromoCode($discountCode->getPromoCode());
  260.             $promoCodeHistory->setDiscountCodeType($discountCode->getType());
  261.             $promoCodeHistory->setOrganizationId($organization->getId());
  262.             $promoCodeHistory->setAmount($discountCode->getFirstDiscountConfiguration()->getAmount());
  263.             $promoCodeHistory->setInvoice($entity);
  264.             $this->em->persist($promoCodeHistory);
  265.             $this->em->flush();
  266.         }
  267.         if (isset($changeset['status']) && InvoiceStatusEnum::PAID === $changeset['status'][1] && ($organization && OrganizationStatusPayedEnum::PAID === $organization->getStatusInvoicePayed() && false === $organization->getIsAuthorizedDebit())) {
  268.             $organization->setIsAuthorizedDebit(true);
  269.             $this->em->persist($organization);
  270.             $this->em->flush();
  271.         }
  272.         $this->setInvoiceType($entity);
  273.         if (isset($changeset['status']) && $organization) {
  274.             // check if organization status is LOST and the invoice is the first invoice of the organization with status PAID
  275.             $firstInvoiceId $this->invoiceRepository->getFirstInvoiceIdByOrganization($organization->getId());
  276.             if (OrganizationStatusEnum::LOST === $organization->getStatus()
  277.                 && $entity->getId() === $firstInvoiceId
  278.                 && InvoiceStatusEnum::PAID === $changeset['status'][1]) {
  279.                 // set the domiciliation start date before checkUnpaid
  280.                 $organization->setDomiciliationStartDate(new \DateTime());
  281.                 $organization->setStatus(OrganizationStatusEnum::NEW_PAYMENT);
  282.             }
  283.             // checkUnpaid && flush organization
  284.             $this->invoiceUtils->checkUnpaid($organization);
  285.             if (InvoiceStatusEnum::LATE === $changeset['status'][1]) {
  286.                 $this->segmentAPI->identifyInvoicesOrganization($organization);
  287.             }
  288.         }
  289.         $status null;
  290.         if (!$entity->getIsPackInvoice() && $organization) {
  291.             $status $this->organizationUtils->checkStatusDomiciliation($organization);
  292.         }
  293.         if ($status) {
  294.             $organization->setStatus($status);
  295.             $this->em->persist($organization);
  296.             $this->em->flush();
  297.         }
  298.         $quote $entity->getQuote();
  299.         if (InvoiceStatusEnum::PAID === $entity->getStatus() && ($quote && QuoteStatusEnum::VALID !== $quote->getStatus())) {
  300.             $quote->setStatus(QuoteStatusEnum::VALID);
  301.             $this->em->persist($quote);
  302.             $this->em->flush();
  303.         }
  304.         if ($entity->isModel()) {
  305.             return;
  306.         }
  307.         // check status of invoice to change status to organization
  308.         $this->segmentAPI->identifyNewInvoice($entity);
  309.         $this->segmentAPI->trackError($entity);
  310.         if (isset($changeset['status'])) {
  311.             $this->segmentAPI->trackInvoiceStatus($entity);
  312.             /*
  313.              * Track invoice PAID
  314.              */
  315.             if (InvoiceStatusEnum::PAID === $changeset['status'][1] && $entity->getOrganization()) {
  316.                 $this->segmentAPI->trackInvoicePaid($entity);
  317.             }
  318.         }
  319.         $cancelled false;
  320.         if ($entity->getCreditNotes()->count() > 0) {
  321.             $creditNotes $entity->getCreditNotes();
  322.             $sum 0;
  323.             foreach ($creditNotes as $creditNote) {
  324.                 $sum += $creditNote->getAmount();
  325.             }
  326.             // if sum of credit notes is equal to invoice price, set invoice status to rejected
  327.             if ($sum === $entity->getPrice()) {
  328.                 $cancelled true;
  329.             }
  330.         }
  331.     }
  332.     /**
  333.      * @throws \Exception
  334.      */
  335.     public function preUpdate(PreUpdateEventArgs $args): void
  336.     {
  337.         $entity $args->getObject();
  338.         if (!$entity instanceof Invoice) {
  339.             return;
  340.         }
  341.         $uow $this->em->getUnitOfWork();
  342.         $uow->computeChangeSets();
  343.         $changeset $uow->getEntityChangeSet($entity);
  344.         if (=== count($changeset) && isset($changeset['updatedAt'])) {
  345.             return;
  346.         }
  347.         if (isset($changeset['isImported']) || isset($changeset['invoiceType'])) {
  348.             return;
  349.         }
  350.         if (isset($changeset['path'], $changeset['updatedAt'])) {
  351.             return;
  352.         }
  353.         if (=== count($changeset) && isset($changeset['isDomiciliation'])) {
  354.             return;
  355.         }
  356.         $entity $this->invoiceUtils->checkInvoice($entity);
  357.         $changeSet $args->getEntityChangeSet();
  358.         if (isset($changeset['status']) && !$entity->getPaymentDeadline()) {
  359.             $paymentDeadline date('Y-m-d'strtotime('+1 months'$entity->getCreatedAt()->getTimestamp()));
  360.             $entity->setPaymentDeadline(new \DateTime($paymentDeadline));
  361.         }
  362.         if (!isset($changeset['reference']) && [] !== $changeSet) {
  363.             InvoiceUtils::setPrices($entity);
  364.             $this->createOrganization($entity);
  365.             if (isset($changeSet['isSent']) && true === $changeSet['isSent'][1] && [] !== $entity->getOrganization()->getUsers()) {
  366.                 $entity->setStatus(InvoiceStatusEnum::SENT);
  367.                 $entity->setSentDate(new \DateTime());
  368.                 $organization $entity->getOrganization();
  369.                 if ($organization && $organization->getUsers()) {
  370.                     $entity->setSentTo($organization->getUsers()[0]->getEmail());
  371.                 }
  372.             }
  373.         }
  374.     }
  375.     private function createOrganization(Invoice $entity): void
  376.     {
  377.         if ($entity->getIsNewOrganization()) {
  378.             if (null === $entity->getNewOrganizationAddress()) {
  379.                 $newAddress = (new PostalAddress())
  380.                     ->setAddressCountry('')
  381.                     ->setAddressLocality('')
  382.                     ->setStreetAddress('')
  383.                     ->setPostalCode('')
  384.                     ->setAddressRegion('');
  385.                 $entity->setNewOrganizationAddress($newAddress);
  386.             }
  387.             $organization = (new Organization())
  388.                 ->setLegalName($entity->getNewOrganizationLegalName())
  389.                 ->setVatID($entity->getNewOrganizationVATID())
  390.                 ->setAddress($entity->getNewOrganizationAddress())
  391.                 ->setTelephone($entity->getNewOrganizationPhoneNumber());
  392.             /** @var UserRepository $userRepo */
  393.             $userRepo $this->em->getRepository(User::class);
  394.             $user $userRepo->loadUserByUsername($entity->getNewOrganizationUserEmail());
  395.             if (null === $user) {
  396.                 $user = (new User())
  397.                     ->setPhoneNumber($entity->getNewOrganizationPhoneNumber())
  398.                     ->setEmail($entity->getNewOrganizationUserEmail())
  399.                     ->setPassword(uniqid().uniqid().uniqid());
  400.             }
  401.             /*  @phpstan-ignore-next-line */
  402.             $organization->addUser($user);
  403.             $entity->setOrganization($organization)
  404.                 ->setNewOrganizationAddress(null)
  405.                 ->setNewOrganizationLegalName(null)
  406.                 ->setNewOrganizationVATID(null)
  407.                 ->setIsNewOrganization(false)
  408.                 ->setNewOrganizationUserEmail(null)
  409.                 ->setNewOrganizationPhoneNumber(null);
  410.         }
  411.     }
  412.     private function createOrganizationPrescriber(Invoice $entity): void
  413.     {
  414.         if (!$entity->getIsNewOrganizationPrescribed()) {
  415.             return;
  416.         }
  417.         if (null === $entity->getPrescriber()) {
  418.             if (null === $entity->getNewPrescriberAddress()) {
  419.                 $newAddress = (new PostalAddress())
  420.                     ->setAddressCountry('')
  421.                     ->setAddressLocality('')
  422.                     ->setStreetAddress('')
  423.                     ->setPostalCode('')
  424.                     ->setAddressRegion('');
  425.                 $entity->setNewPrescriberAddress($newAddress);
  426.             }
  427.             $organization = (new Organization())
  428.                 ->setLegalName($entity->getNewPrescriberLegalName())
  429.                 ->setVatID($entity->getNewPrescriberVATID())
  430.                 ->setAddress($entity->getNewPrescriberAddress())
  431.                 ->setIsPrescriber(true);
  432.             /** @var UserRepository $userRepo */
  433.             $userRepo $this->em->getRepository(User::class);
  434.             $user $userRepo->loadUserByUsername($entity->getNewPrescriberUserEmail());
  435.             if (null === $user) {
  436.                 $user = (new User())
  437.                     ->setEmail($entity->getNewPrescriberUserEmail())
  438.                     ->setPassword(uniqid().uniqid().uniqid());
  439.             }
  440.             /** @var Organization $factOrganization */
  441.             $factOrganization $entity->getOrganization();
  442.             $factOrganization->setPrescriber($organization);
  443.             if ($entity->getIsAttachedToPrescriber()) {
  444.                 $entity->setOrganization($organization);
  445.             }
  446.             $this->em->persist($organization);
  447.             $this->em->flush();
  448.             $this->segmentAPI->identifyPrescriber($factOrganization->getPrescriber());
  449.         } else {
  450.             $organization $entity->getOrganization();
  451.             if (null !== $organization) {
  452.                 $organization->setPrescriber($entity->getPrescriber());
  453.                 $organization->getPrescriber()->addOrganizationsPrescribed($organization);
  454.                 if ($entity->getIsAttachedToPrescriber()) {
  455.                     $entity->setOrganization($organization->getPrescriber());
  456.                 }
  457.                 $this->em->persist($entity);
  458.                 $this->em->flush();
  459.                 $this->segmentAPI->identifyPrescriber($organization->getPrescriber());
  460.             }
  461.         }
  462.     }
  463.     /**
  464.      * @throws \Exception
  465.      */
  466.     public function prePersist(LifecycleEventArgs $args): void
  467.     {
  468.         $entity $args->getObject();
  469.         if (!$entity instanceof Invoice) {
  470.             return;
  471.         }
  472.         if (InvoiceStatusEnum::DRAFT !== $entity->getStatus() && !$entity->getPaymentDeadline()) {
  473.             $paymentDeadline date('Y-m-d'strtotime('+1 months'$entity->getCreatedAt()->getTimestamp()));
  474.             $entity->setPaymentDeadline(new \DateTime($paymentDeadline));
  475.         }
  476.         if ($entity->getIsDomiciliation()) {
  477.             foreach ($entity->getItems() as $item) {
  478.                 $item->setDescription($item->getDescription());
  479.             }
  480.         }
  481.         $this->createOrganization($entity);
  482.         InvoiceUtils::setPrices($entity);
  483.         if ($entity->isModel()) {
  484.             return;
  485.         }
  486.         $entity->setStatus(InvoiceStatusEnum::DRAFT);
  487.         if ($entity->getIsSent()) {
  488.             $entity->setStatus(InvoiceStatusEnum::SENT);
  489.         }
  490.         $entity $this->invoiceUtils->checkInvoice($entity);
  491.         $user $this->security->getUser();
  492.         if ($user instanceof User) {
  493.             $entity->setUser($user);
  494.         }
  495.         // Init IsNewTransfert for organization
  496.         if ($entity->isFlagTransfertToInit($entity)) {
  497.             $entity->getOrganization()->setIsNewTransfert(true);
  498.         }
  499.     }
  500.     /** this function set the InvoiceType using the organization, invoices, items and products.
  501.      */
  502.     public function setInvoiceType(Invoice $entity): void
  503.     {
  504.         $key = [
  505.             ProductKeyEnum::COLIS_FRAIS_DE_REEXPEDITION,
  506.             ProductKeyEnum::COLIS_FRAIS_DE_GARDE,
  507.             ProductKeyEnum::COLIS_FRAIS_DE_GESTION,
  508.             ProductKeyEnum::FRAIS_DE_REEXPEDITION_ETRANGER,
  509.             ProductKeyEnum::REEXPEDITION_COURRIER,
  510.             ProductKeyEnum::FRAIS_DE_STOCKAGE,
  511.         ];
  512.         $organization $entity->getOrganization();
  513.         if (!$organization instanceof Organization) {
  514.             return;
  515.         }
  516.         $isNewDomiciliation $entity->getIsDomiciliation();
  517.         /* @var Organization $organization */
  518.         if (true === $isNewDomiciliation) {
  519.             $entity->setInvoiceType(InvoiceTypeEnum::PERIODICAL);
  520.             $this->em->persist($organization);
  521.         } elseif (false === $isNewDomiciliation) {
  522.             $entity->setInvoiceType(null);
  523.             $this->em->persist($entity);
  524.         }
  525.         $items $entity->getItems();
  526.         foreach ($items as $itemPerInvoice) {
  527.             /** @var Product $product */
  528.             $product $itemPerInvoice->getProduct();
  529.             if (in_array($product->getUniqueKey(), $keytrue)) {
  530.                 $entity->setInvoiceType(InvoiceTypeEnum::RESHIPPING_COSTS);
  531.                 $this->em->persist($entity);
  532.             } elseif ($product->getCategory() && 'Formalités juridiques' === $product->getCategory()->getTitle()) {
  533.                 $entity->setInvoiceType(InvoiceTypeEnum::FORMALITY);
  534.                 $this->em->persist($entity);
  535.             } elseif ('frais_de_retard' === $product->getUniqueKey()) {
  536.                 $entity->setInvoiceType(InvoiceTypeEnum::REJECTED);
  537.                 $this->em->persist($entity);
  538.             }
  539.         }
  540.         $this->em->flush();
  541.     }
  542.     /**
  543.      * @throws TransportExceptionInterface
  544.      */
  545.     private function handleZapierHook(?int $invoiceId, ?Organization $organization): void
  546.     {
  547.         if ($organization && !empty($organization->getZapierHookUrl())) {
  548.             foreach ($organization->getZapierHookUrl() as $zapierHookUrl) {
  549.                 if (isset($zapierHookUrl['invoice']) && 'invoice' === array_keys($zapierHookUrl)[0]) {
  550.                     $params = [
  551.                         'organization' => $organization->getId(),
  552.                         'invoiceId' => $invoiceId,
  553.                     ];
  554.                     $response $this->client->request(
  555.                         'POST',
  556.                         $zapierHookUrl['invoice'],
  557.                         [
  558.                             'body' => $params,
  559.                         ]
  560.                     );
  561.                     if (Response::HTTP_GONE === $response->getStatusCode()) {
  562.                         $this->sendSentryMessage('[ZAPIER] Unsubscribe Zap 410 returned');
  563.                     }
  564.                 }
  565.             }
  566.         }
  567.     }
  568. }