src/EventSubscriber/InvoiceSubscriber.php line 130
<?phpnamespace App\EventSubscriber;use App\Entity\CheckInformation;use App\Entity\InvoiceReview;use App\Entity\InvoiceSupportTicket;use App\Entity\LatePaymentChargeLogs;use App\Entity\Municipality;use App\Entity\MunicipalityFeePeriod;use App\Entity\MunicipalityLateFees;use App\Entity\MunicipalityLateFeesPeriod;use App\Entity\RegistrationForm;use App\Entity\RenewalForm;use App\Entity\SupportTicket;use App\Entity\User;use App\Event\AppEvents;use App\Event\FormCreatedEvent;use App\Event\FormsDeletedEvent;use App\Event\Support\InvoiceEvent as InvoiceSupportEvent;use App\Event\InvoiceEvent;use App\Helper\PropertyHelper;use App\Repository\LatePaymentChargeLogsRepository;use App\ValueObject\MunicipalityLateFeesType;use App\ValueObject\SearchCriteria\MunicipalityFeeSearchCriteria;use App\ValueObject\InvoicePaymentTypes;use App\ValueObject\InvoiceStatuses;use Doctrine\ORM\EntityManagerInterface;use App\Entity\Form;use App\Entity\Invoice;use App\Entity\MunicipalityFee;use App\ValueObject\InvoiceTypes;use App\ValueObject\SearchCriteria\RenewalFormSearchCriteria;use App\Lib\EmailSenderInterface;use Symfony\Component\EventDispatcher\EventSubscriberInterface;/*** Class InvoiceListener*/class InvoiceSubscriber implements EventSubscriberInterface{/*** @var EntityManagerInterface*/private $em;/*** @var EmailSenderInterface*/private $emailSender;private LatePaymentChargeLogsRepository $latePaymentChargeLogsRepository;public function __construct(EntityManagerInterface $entityManager,EmailSenderInterface $emailSender,LatePaymentChargeLogsRepository $latePaymentChargeLogsRepository){$this->em = $entityManager;$this->emailSender = $emailSender;$this->latePaymentChargeLogsRepository = $latePaymentChargeLogsRepository;}/*** {@inheritdoc}*/public static function getSubscribedEvents(): array{return [AppEvents::FORMS_DELETED => 'onFormsDeleted',AppEvents::INVOICE_CREATED => 'onInvoiceCreated',AppEvents::INVOICE_DISPUTE_CREATED => 'onDisputeCreated',AppEvents::FORM_CREATED => 'onFormCreated'];}/*** @param FormsDeletedEvent $event*/public function onFormsDeleted(FormsDeletedEvent $event): void{$formIds = $event->getForms();if (count($formIds)) {//Delete Invoices for the forms.$invoiceIds = $this->em->getRepository(Invoice::class)->deleteInIds($formIds);if (count($invoiceIds)) {//Delete Invoices Reviews.$this->em->getRepository(InvoiceReview::class)->deleteInIds($invoiceIds);//Delete Invoices Dispute and Support.$invoiceTicketIds = $this->em->getRepository(InvoiceSupportTicket::class)->getTicketsInIds($invoiceIds);if (count($invoiceTicketIds)) {$this->em->getRepository(SupportTicket::class)->deleteInIds($invoiceTicketIds);}}}}/*** @param InvoiceEvent $event*/public function onInvoiceCreated(InvoiceEvent $event): void{$invoice = $event->getInvoice();/** @var Form $form */$form = $invoice->getForm();$form->setFeeAmount($invoice->getInvoiceAmount());$form->setDueAmount($invoice->getInvoiceAmount());$this->em->persist($form);$this->em->flush();}/*** @param InvoiceSupportEvent $event*/public function onDisputeCreated(InvoiceSupportEvent $event): void{//Set Invoice In Dispute.$invoice = $event->getTicket()->getInvoice();$invoice->inDispute();$this->em->persist($invoice);$this->em->flush();}public function onFormCreated(FormCreatedEvent $event): void{// try {// 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;$checkInformation = $event->getCheckInformation();$usedPayByCheck = $event->getUsedPayByCheck();$form = $event->getForm();$property = $form->getProperty();$municipality = $property->getMunicipality();$lateFeesTriggerType = '';if ($event->getType() == InvoiceTypes::VPR_REGISTRATION) {$zone = $form->getZonesPropertyUse()[0];} elseif ($event->getType() == InvoiceTypes::VPR_RENEWAL) {$zone = $form->getProperty()->getZonesPropertyUse()->first();}$criteria = new MunicipalityFeeSearchCriteria();$criteria->industrialType = strtolower($zone ? $zone->getName() : '');$criteria->municipalityId = $municipality->getId();$municipalityFee = null;$municipalityFees = $this->em->getRepository(MunicipalityFee::class)->search($criteria);$municipalityFee = $municipalityFees[0];$amount = 0;$invoiceDate = new \DateTime('now');$dueDate = new \DateTime('now');$description = '';$nextRenewalNumber = $property->getRenewalNumber();if ($event->getType() == InvoiceTypes::VPR_REGISTRATION) {$dueDate = new \DateTime($property->getRegistrationDate() ? $property->getRegistrationDate()->format('Y-m-d H:i:s') : 'now'); // Y-m-d$amount = $municipalityFee->getRegistrationFee();$description = 'Registration Invoice for '.$property->getAddress().' registered on '.$invoiceDate->format('Y-m-d H:i:s');} elseif ($event->getType() == InvoiceTypes::VPR_RENEWAL) {// count past renewals$criteria = new RenewalFormSearchCriteria();$criteria->property = $property;$countRenewals = $this->em->getRepository(RenewalForm::class)->countByCriteria($criteria);if (count($municipalityFee->getPeriods()) && $countRenewals > 1) {// count total periods including base charge for renewal$feesIndex = $countRenewals - 1;$nextRenewalNumber = $countRenewals + 1;/** @var MunicipalityFee $municipalityFee*/$feesArray = [$municipalityFee->getRenewalBaseFee()];if (count($municipalityFee->getPeriods())) {foreach ($municipalityFee->getPeriods() as $period) {$feesArray[] = $period->getTotalFee();}}$type = '';switch ($municipalityFee->getPeriodFixedRecurrenceType()) {case 'year':$type = 'Y';break;case 'month':$type = 'M';break;case 'day':$type = 'D';break;}$invoiceDate = new \DateTime();$dueDate = new \DateTime();if ($type == 'Y') {$dueDate->modify('+'.PropertyHelper::DUE_YEAR_RENEW.' day');}else if ($type == 'M') {$dueDate->modify('+'.PropertyHelper::DUE_MONTH_RENEW.' day');}$renewalDate = $property->getRenewalDate() ? $property->getRenewalDate()->format('Y-m-d H:i:s') : (new \DateTime())->format('Y-m-d H:i:s');$description = 'Renewal Invoice for '.$property->getAddress().' registered on '.$renewalDate;if (array_key_exists($feesIndex, $feesArray)) {$amount = $feesArray[$feesIndex];} else {$amount = end($feesArray);}} else {$dueDate = new \DateTime($property->getRegistrationDate() ? $property->getRegistrationDate()->format('Y-m-d H:i:s') : 'now'); // Y-m-d$description = 'Renewal Invoice for '.$property->getAddress().' registered on '.$invoiceDate->format('Y-m-d H:i:s');$amount = $municipalityFee->getRenewalBaseFee();$nextRenewalNumber = $property->getRenewalNumber() + 1;}$municipalityLateFees = $this->em->getRepository(MunicipalityLateFees::class)->findOneBy(['municipality' => $municipality->getId(), 'type' => MunicipalityLateFeesType::RENEWAL_TYPE]);$currentUser = $this->em->getRepository(User::class)->findOneBy(['email' => $form->getCreatedBy()]);if ($municipalityLateFees instanceof MunicipalityLateFees) {$lateFeesTriggerType = $municipalityLateFees->getFeesTriggerType();$lateFeesTriggerAfter = $municipalityLateFees->getFeesTriggerAfter();$nextRenewalDate = $property->getNextRenewalDate();$currentDate = new \DateTime();$dateDiff = $currentDate->diff($nextRenewalDate);$charge = '';$usersLatePaymentChargeLogsCount = count($this->latePaymentChargeLogsRepository->findBy(['user' => $currentUser, 'municipality' => $municipality]));$lateFeeBaseCharge = $municipalityLateFees->getFeesAmount();$lateChargesArray = [];$periods = $municipalityLateFees->getPeriods()->getValues();if (!empty($periods)) {/**@var MunicipalityLateFeesPeriod $period */foreach ($periods as $period) {$municipalityLateFeesId = $period->getMunicipalityLateFees()->getId();$lateChargesArray[(int) $municipalityLateFeesId][] = (float) $period->getTotalFee();}if (array_key_exists($municipalityLateFees->getId(), $lateChargesArray)) {array_unshift($lateChargesArray[$municipalityLateFees->getId()], $municipalityLateFees->getFeesAmount());}if ($usersLatePaymentChargeLogsCount == 0) {$charge = (float) $municipalityLateFees->getFeesAmount();} elseif (array_key_exists($municipalityLateFees->getId(), $lateChargesArray) && array_key_exists($usersLatePaymentChargeLogsCount, $lateChargesArray[$municipalityLateFees->getId()])) {$charge = $lateChargesArray[$municipalityLateFees->getId()][$usersLatePaymentChargeLogsCount];} else {$charge = end($lateChargesArray[$municipalityLateFees->getId()]);}}}}$property->setRenewalNumber($nextRenewalNumber);$this->em->persist($property);$this->em->flush();$totalAmount = $dueAmount = $amount;$invoice = new Invoice($form->getRegistrant(),$event->getType(),$invoiceDate,$dueDate,$amount,);$invoice->setPaymentType(InvoicePaymentTypes::CREDIT_CARD);$invoice->setDescription($description);$invoice->setForm($form);if ($checkInformation instanceof CheckInformation) {$invoice->setCheckInformation($checkInformation);$checkAmount = $checkInformation->getAmount();if ($checkAmount >= $totalAmount) {$invoiceStatus = InvoiceStatuses::PAID;$dueAmount = 0;} else {$invoiceStatus = InvoiceStatuses::UNPAID;$dueAmount = $totalAmount - $checkAmount;}$invoice->setStatus($invoiceStatus);$invoice->setPaymentDate(new \DateTime());$invoice->setPaymentType(InvoicePaymentTypes::CHECK);$form->setPaidAmount($checkAmount);}if ($usedPayByCheck) {$invoice->setPaymentType(InvoicePaymentTypes::CHECK);}$this->em->persist($invoice);$this->em->flush();if ($lateFeesTriggerType == 'day') {$daysDiff = $dateDiff->days;if ($daysDiff >= $lateFeesTriggerAfter) {$this->generateLatePaymentLog($currentUser, $municipality, $invoice, $charge);}} else if ($lateFeesTriggerType == 'month') {$monthsDiff = $dateDiff->m;if ($monthsDiff >= $lateFeesTriggerAfter) {$this->generateLatePaymentLog($currentUser, $municipality, $invoice, $charge);}}if ($form instanceof RegistrationForm || $form instanceof RenewalForm) {$form->setFeeAmount($totalAmount);$form->setDueAmount($dueAmount);$this->em->persist($form);}$this->em->flush();}public function generateLatePaymentLog(User $user,Municipality $municipality,Invoice $invoice, $charge): void{$latePaymentChargeLog = $this->latePaymentChargeLogsRepository->findOneBy(['invoice' => $invoice]);if (!$latePaymentChargeLog instanceof LatePaymentChargeLogs) {$latePaymentChargeLog = new LatePaymentChargeLogs();$latePaymentChargeLog->setUser($user);$latePaymentChargeLog->setMunicipality($municipality);$latePaymentChargeLog->setInvoice($invoice);$latePaymentChargeLog->setMunicipalityLateFeesCharge($charge);$this->em->persist($latePaymentChargeLog);$this->em->flush();}}}