src/EventSubscriber/InvoiceSubscriber.php line 130

Open in your IDE?
  1. <?php
  2. namespace App\EventSubscriber;
  3. use App\Entity\CheckInformation;
  4. use App\Entity\InvoiceReview;
  5. use App\Entity\InvoiceSupportTicket;
  6. use App\Entity\LatePaymentChargeLogs;
  7. use App\Entity\Municipality;
  8. use App\Entity\MunicipalityFeePeriod;
  9. use App\Entity\MunicipalityLateFees;
  10. use App\Entity\MunicipalityLateFeesPeriod;
  11. use App\Entity\RegistrationForm;
  12. use App\Entity\RenewalForm;
  13. use App\Entity\SupportTicket;
  14. use App\Entity\User;
  15. use App\Event\AppEvents;
  16. use App\Event\FormCreatedEvent;
  17. use App\Event\FormsDeletedEvent;
  18. use App\Event\Support\InvoiceEvent as InvoiceSupportEvent;
  19. use App\Event\InvoiceEvent;
  20. use App\Helper\PropertyHelper;
  21. use App\Repository\LatePaymentChargeLogsRepository;
  22. use App\ValueObject\MunicipalityLateFeesType;
  23. use App\ValueObject\SearchCriteria\MunicipalityFeeSearchCriteria;
  24. use App\ValueObject\InvoicePaymentTypes;
  25. use App\ValueObject\InvoiceStatuses;
  26. use Doctrine\ORM\EntityManagerInterface;
  27. use App\Entity\Form;
  28. use App\Entity\Invoice;
  29. use App\Entity\MunicipalityFee;
  30. use App\ValueObject\InvoiceTypes;
  31. use App\ValueObject\SearchCriteria\RenewalFormSearchCriteria;
  32. use App\Lib\EmailSenderInterface;
  33. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  34. /**
  35.  * Class InvoiceListener
  36.  */
  37. class InvoiceSubscriber implements EventSubscriberInterface
  38. {
  39.     /**
  40.      * @var EntityManagerInterface
  41.      */
  42.     private $em;
  43.     /**
  44.      * @var EmailSenderInterface
  45.      */
  46.     private $emailSender;
  47.     private LatePaymentChargeLogsRepository $latePaymentChargeLogsRepository;
  48.     public function __construct(
  49.         EntityManagerInterface $entityManager,
  50.         EmailSenderInterface $emailSender,
  51.         LatePaymentChargeLogsRepository $latePaymentChargeLogsRepository
  52.     )
  53.     {
  54.         $this->em $entityManager;
  55.         $this->emailSender $emailSender;
  56.         $this->latePaymentChargeLogsRepository $latePaymentChargeLogsRepository;
  57.     }
  58.     /**
  59.      * {@inheritdoc}
  60.      */
  61.     public static function getSubscribedEvents()
  62.     {
  63.         return [
  64.             AppEvents::FORMS_DELETED => 'onFormsDeleted',
  65.             AppEvents::INVOICE_CREATED => 'onInvoiceCreated',
  66.             AppEvents::INVOICE_DISPUTE_CREATED => 'onDisputeCreated',
  67.             AppEvents::FORM_CREATED => 'onFormCreated'
  68.         ];
  69.     }
  70.     /**
  71.      * @param FormsDeletedEvent $event
  72.      */
  73.     public function onFormsDeleted(FormsDeletedEvent $event)
  74.     {
  75.         $formIds $event->getForms();
  76.         if (count($formIds)) {
  77.             //Delete Invoices for the forms.
  78.             $invoiceIds $this->em->getRepository(Invoice::class)->deleteInIds($formIds);
  79.             if (count($invoiceIds)) {
  80.                 //Delete Invoices Reviews.
  81.                 $this->em->getRepository(InvoiceReview::class)->deleteInIds($invoiceIds);
  82.                 //Delete Invoices Dispute and Support.
  83.                 $invoiceTicketIds $this->em->getRepository(InvoiceSupportTicket::class)->getTicketsInIds($invoiceIds);
  84.                 if (count($invoiceTicketIds)) {
  85.                     $this->em->getRepository(SupportTicket::class)->deleteInIds($invoiceTicketIds);
  86.                 }
  87.             }
  88.         }
  89.     }
  90.     /**
  91.      * @param InvoiceEvent $event
  92.      */
  93.     public function onInvoiceCreated(InvoiceEvent $event)
  94.     {
  95.         $invoice $event->getInvoice();
  96.         /** @var Form $form */
  97.         $form $invoice->getForm();
  98.         $form->setFeeAmount($invoice->getInvoiceAmount());
  99.         $form->setDueAmount($invoice->getInvoiceAmount());
  100.         $this->em->persist($form);
  101.         $this->em->flush();
  102.     }
  103.     /**
  104.      * @param InvoiceSupportEvent $event
  105.      */
  106.     public function onDisputeCreated(InvoiceSupportEvent $event)
  107.     {
  108.         //Set Invoice In Dispute.
  109.         $invoice $event->getTicket()->getInvoice();
  110.         $invoice->inDispute();
  111.         $this->em->persist($invoice);
  112.         $this->em->flush();
  113.     }
  114.     public function onFormCreated(FormCreatedEvent $event)
  115.     {
  116.         // try {
  117.             // UPDATE property p JOIN ( SELECT f.property_id, COUNT(*) AS totalRenewal FROM `renewal_form` rf INNER JOIN form f ON f.id = rf.id GROUP BY f.property_id ) rc ON p.id = rc.property_id SET p.renewal_number = rc.totalRenewal + 1;
  118.             
  119.             $checkInformation $event->getCheckInformation();
  120.             $usedPayByCheck $event->getUsedPayByCheck();
  121.             $form $event->getForm();
  122.             $property $form->getProperty();
  123.             $municipality $property->getMunicipality();
  124.             $lateFeesTriggerType '';
  125.             if ($event->getType() == InvoiceTypes::VPR_REGISTRATION) {
  126.                 $zone $form->getZonesPropertyUse()[0];
  127.             } elseif ($event->getType() == InvoiceTypes::VPR_RENEWAL) {
  128.                 $zone $form->getProperty()->getZonesPropertyUse()->first();
  129.             }
  130.             $criteria = new MunicipalityFeeSearchCriteria();
  131.             $criteria->industrialType strtolower($zone $zone->getName() : '');
  132.             $criteria->municipalityId $municipality->getId();
  133.             $municipalityFee null;
  134.             $municipalityFees $this->em->getRepository(MunicipalityFee::class)->search($criteria);
  135.             $municipalityFee $municipalityFees[0];
  136.             $amount 0;
  137.             $invoiceDate = new \DateTime('now');
  138.             $dueDate = new \DateTime('now');
  139.             $description '';
  140.             $nextRenewalNumber $property->getRenewalNumber();
  141.             if ($event->getType() == InvoiceTypes::VPR_REGISTRATION) {
  142.                 $dueDate = new \DateTime($property->getRegistrationDate() ? $property->getRegistrationDate()->format('Y-m-d H:i:s') : 'now'); // Y-m-d
  143.                 $amount $municipalityFee->getRegistrationFee();
  144.                 $description 'Registration Invoice for '.$property->getAddress().' registered on '.$invoiceDate->format('Y-m-d H:i:s');
  145.             } elseif ($event->getType() == InvoiceTypes::VPR_RENEWAL) {
  146.                 // count past renewals
  147.                 $criteria = new RenewalFormSearchCriteria();
  148.                 $criteria->property $property;
  149.                 $countRenewals $this->em->getRepository(RenewalForm::class)->countByCriteria($criteria);
  150.                 if (count($municipalityFee->getPeriods()) && $countRenewals 1) {
  151.                     // count total periods including base charge for renewal
  152.                     $feesIndex $countRenewals 1;
  153.                     $nextRenewalNumber $countRenewals 1;
  154.                     /** @var MunicipalityFee $municipalityFee*/
  155.                     $feesArray = [$municipalityFee->getRenewalBaseFee()];
  156.                     if (count($municipalityFee->getPeriods())) {
  157.                         foreach ($municipalityFee->getPeriods() as $period) {
  158.                             $feesArray[] = $period->getTotalFee();
  159.                         }
  160.                     }
  161.                     $type '';
  162.                     switch ($municipalityFee->getPeriodFixedRecurrenceType()) {
  163.                         case 'year':
  164.                             $type 'Y';
  165.                             break;
  166.                         case 'month':
  167.                             $type 'M';
  168.                             break;
  169.                         case 'day':
  170.                             $type 'D';
  171.                             break;
  172.                     }
  173.                     $invoiceDate = new \DateTime();
  174.                     $dueDate = new \DateTime();
  175.                     if ($type == 'Y') {
  176.                         $dueDate->modify('+'.PropertyHelper::DUE_YEAR_RENEW.' day');
  177.                     }
  178.                     else if ($type == 'M') {
  179.                         $dueDate->modify('+'.PropertyHelper::DUE_MONTH_RENEW.' day');
  180.                     }
  181.                     $renewalDate $property->getRenewalDate() ? $property->getRenewalDate()->format('Y-m-d H:i:s') : (new \DateTime())->format('Y-m-d H:i:s');
  182.                     $description 'Renewal Invoice for '.$property->getAddress().' registered on '.$renewalDate;
  183.                     if (array_key_exists($feesIndex$feesArray)) {
  184.                         $amount $feesArray[$feesIndex];
  185.                     } else {
  186.                         $amount end($feesArray);
  187.                     }
  188.                 } else {
  189.                     $dueDate = new \DateTime($property->getRegistrationDate() ? $property->getRegistrationDate()->format('Y-m-d H:i:s') : 'now'); // Y-m-d
  190.                     $description 'Renewal Invoice for '.$property->getAddress().' registered on '.$invoiceDate->format('Y-m-d H:i:s');
  191.                     $amount $municipalityFee->getRenewalBaseFee();
  192.                     $nextRenewalNumber $property->getRenewalNumber() + 1;
  193.                 }
  194.                 $municipalityLateFees $this->em->getRepository(MunicipalityLateFees::class)->findOneBy(
  195.                     ['municipality' => $municipality->getId(), 'type' => MunicipalityLateFeesType::RENEWAL_TYPE]
  196.                 );
  197.                 $currentUser $this->em->getRepository(User::class)->findOneBy(['email' => $form->getCreatedBy()]);
  198.                 if ($municipalityLateFees instanceof MunicipalityLateFees) {
  199.                     $lateFeesTriggerType $municipalityLateFees->getFeesTriggerType();
  200.                     $lateFeesTriggerAfter $municipalityLateFees->getFeesTriggerAfter();
  201.                     $nextRenewalDate $property->getNextRenewalDate();
  202.                     $currentDate = new \DateTime();
  203.                     $dateDiff $currentDate->diff($nextRenewalDate);
  204.                     $charge '';
  205.                     $usersLatePaymentChargeLogsCount count($this->latePaymentChargeLogsRepository->findBy(['user' => $currentUser'municipality' => $municipality]));
  206.                     $lateFeeBaseCharge $municipalityLateFees->getFeesAmount();
  207.                     $lateChargesArray = [];
  208.                     $periods $municipalityLateFees->getPeriods()->getValues();
  209.                     if (!empty($periods)) {
  210.                         /**@var MunicipalityLateFeesPeriod $period */
  211.                         foreach ($periods as $period) {
  212.                             $municipalityLateFeesId $period->getMunicipalityLateFees()->getId();
  213.                             $lateChargesArray[(int) $municipalityLateFeesId][] = (float) $period->getTotalFee();
  214.                         }
  215.                         if (array_key_exists($municipalityLateFees->getId(), $lateChargesArray)) {
  216.                             array_unshift($lateChargesArray[$municipalityLateFees->getId()], $municipalityLateFees->getFeesAmount());
  217.                         }
  218.                         if ($usersLatePaymentChargeLogsCount == 0) {
  219.                             $charge = (float) $municipalityLateFees->getFeesAmount();
  220.                         } elseif (array_key_exists($municipalityLateFees->getId(), $lateChargesArray) && array_key_exists($usersLatePaymentChargeLogsCount$lateChargesArray[$municipalityLateFees->getId()])) {
  221.                             $charge $lateChargesArray[$municipalityLateFees->getId()][$usersLatePaymentChargeLogsCount];
  222.                         } else {
  223.                             $charge end($lateChargesArray[$municipalityLateFees->getId()]);
  224.                         }
  225.                     }
  226.                 }
  227.             }
  228.             $property->setRenewalNumber($nextRenewalNumber);
  229.             $this->em->persist($property);
  230.             $this->em->flush();
  231.             $totalAmount $dueAmount $amount;
  232.             $invoice = new Invoice(
  233.                 $form->getRegistrant(),
  234.                 $event->getType(),
  235.                 $invoiceDate,
  236.                 $dueDate,
  237.                 $amount,
  238.             );
  239.             $invoice->setPaymentType(InvoicePaymentTypes::CREDIT_CARD);
  240.             
  241.             $invoice->setDescription($description);
  242.             $invoice->setForm($form);
  243.             if ($checkInformation instanceof CheckInformation) {
  244.                 $invoice->setCheckInformation($checkInformation);
  245.                 $checkAmount $checkInformation->getAmount();
  246.                 if ($checkAmount >= $totalAmount) {
  247.                     $invoiceStatus InvoiceStatuses::PAID;
  248.                     $dueAmount 0;
  249.                 } else {
  250.                     $invoiceStatus InvoiceStatuses::UNPAID;
  251.                     $dueAmount $totalAmount $checkAmount;
  252.                 }
  253.                 $invoice->setStatus($invoiceStatus);
  254.                 $invoice->setPaymentDate(new \DateTime());
  255.                 $invoice->setPaymentType(InvoicePaymentTypes::CHECK);
  256.                 $form->setPaidAmount($checkAmount);
  257.             }
  258.             if ($usedPayByCheck) {
  259.                 $invoice->setPaymentType(InvoicePaymentTypes::CHECK);
  260.             }
  261.             $this->em->persist($invoice);
  262.             $this->em->flush();
  263.             if ($lateFeesTriggerType == 'day') {
  264.                 $daysDiff $dateDiff->days;
  265.                 if ($daysDiff >= $lateFeesTriggerAfter) {
  266.                     $this->generateLatePaymentLog($currentUser$municipality$invoice$charge);
  267.                 }
  268.             } else if ($lateFeesTriggerType == 'month') {
  269.                 $monthsDiff $dateDiff->m;
  270.                 if ($monthsDiff >= $lateFeesTriggerAfter) {
  271.                     $this->generateLatePaymentLog($currentUser$municipality$invoice$charge);
  272.                 }
  273.             }
  274.             if ($form instanceof RegistrationForm || $form instanceof RenewalForm) {
  275.                 $form->setFeeAmount($totalAmount);
  276.                 $form->setDueAmount($dueAmount);
  277.                 $this->em->persist($form);
  278.             }
  279.         $this->em->flush();
  280.     }
  281.     public function generateLatePaymentLog(User $user,Municipality $municipality,Invoice $invoice$charge)
  282.     {
  283.         $latePaymentChargeLog $this->latePaymentChargeLogsRepository->findOneBy(['invoice' => $invoice]);
  284.         if (!$latePaymentChargeLog instanceof LatePaymentChargeLogs) {
  285.             $latePaymentChargeLog = new LatePaymentChargeLogs();
  286.             $latePaymentChargeLog->setUser($user);
  287.             $latePaymentChargeLog->setMunicipality($municipality);
  288.             $latePaymentChargeLog->setInvoice($invoice);
  289.             $latePaymentChargeLog->setMunicipalityLateFeesCharge($charge);
  290.             $this->em->persist($latePaymentChargeLog);
  291.             $this->em->flush();
  292.         }
  293.     }
  294. }