<?php
namespace App\EventSubscriber;
use App\Entity\Event;
use App\Event\PriceInquiryPriceUpdateEvent;
use App\Event\PriceInquiryVerifiedEvent;
use App\Repository\UserRepository;
use App\Security\Voters\PriceInquiryVoter;
use App\Service\Shipment\ShipmentService;
use App\Service\Constants\LogEvents;
use App\Service\Helpers\StringHelper;
use App\Service\Log\QuotationLogService;
use App\Service\Mailing\MailContentPriceInquiry;
use App\Service\Mailing\MailingService;
use App\Service\PriceInquiry\PriceInquiryService;
use App\Service\Subscription\SubscriptionService;
use App\Service\UserLog;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Contracts\HttpClient\Exception\DecodingExceptionInterface;
use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
class PriceInquirySubscriber implements EventSubscriberInterface
{
protected Security $security;
protected UserRepository $userRepo;
protected SubscriptionService $subscriptionService;
private ShipmentService $shipmentService;
private EntityManagerInterface $em;
private QuotationLogService $logService;
private UserLog $userLog;
private PriceInquiryService $inquiryService;
public function __construct(
SubscriptionService $subscriptionService,
Security $security,
ShipmentService $shipmentService,
EntityManagerInterface $em,
UserRepository $userRepo,
QuotationLogService $logService,
PriceInquiryService $inquiryService,
UserLog $userLog
)
{
$this->security = $security;
$this->subscriptionService = $subscriptionService;
$this->userRepo = $userRepo;
$this->shipmentService = $shipmentService;
$this->em = $em;
$this->logService = $logService;
$this->userLog = $userLog;
$this->inquiryService = $inquiryService;
}
public static function getSubscribedEvents(): array
{
return [
PriceInquiryPriceUpdateEvent::PRICE_OFFER_UPDATED => [
['updateDeliveryPrices'],
['updateFieldsWithAmounts'],
],
PriceInquiryPriceUpdateEvent::CUSTOMS_PRICES_UPDATED => [
['logCustomsPricesChange']
],
PriceInquiryPriceUpdateEvent::PRICES_UPDATED => [
['createPriceUpdateNotification'],
['logPricesChange'],
['updateCustomerDeliveryPricesCommission']
],
PriceInquiryVerifiedEvent::VERIFIED_MFM => [
['logOfferVerifiedMfm'],
['setCustomerPrices'],
],
PriceInquiryVerifiedEvent::VERIFIED_SM => [
['logOfferVerifiedSm'],
['setCustomsPrices'],
['createNoCustomsNotification'],
],
];
}
public function createPriceUpdateNotification(PriceInquiryPriceUpdateEvent $event)
{
$inquiry = $event->getInquiry();
$this->subscriptionService->proceedEvent(
Event::INQUIRY_PRICES_UPDATED,
$inquiry,
['data' => ['uuid' => $inquiry->getUuid()]]
);
}
public function updateDeliveryPrices(PriceInquiryPriceUpdateEvent $event)
{
$inquiry = $event->getInquiry();
$deliveryPrices = $inquiry->getDeliveryPrices();
$isNewAmount = false;
foreach ($inquiry->getPriceOffer() as $amount => $price) {
if ($isNewAmount = !isset($deliveryPrices[$amount])) {
break;
}
}
if ($isNewAmount) {
$newPrices = $this->shipmentService->getDeliveryPrices($inquiry);
foreach ($inquiry->getPriceOffer() as $amount => $price) {
if (!isset($deliveryPrices[$amount])) {
$deliveryPrices[$amount] = $newPrices[$amount] ?? 0;
}
}
$inquiry->setDeliveryPrices($deliveryPrices);
$this->em->flush();
}
}
public function updateFieldsWithAmounts(PriceInquiryPriceUpdateEvent $event)
{
$inquiry = $event->getInquiry();
$this->inquiryService->updateCustomerPriceOfferAmounts($inquiry);
$this->inquiryService->updateDeliveryPricesAmounts($inquiry);
$this->inquiryService->updateCustomerDeliveryPricesAmounts($inquiry);
$this->inquiryService->updateCustomsPricesAmounts($inquiry);
}
public function setCustomerPrices(PriceInquiryVerifiedEvent $event)
{
$inquiry = $event->getInquiry();
$this->inquiryService->updateDeliveryPricesAmounts($inquiry);
$this->inquiryService->updateCustomsPricesAmounts($inquiry);
//AFTER MFM APPROVE -> SET CUSTOMER PRICES
if ( !$inquiry->getCustomerPriceOffer() ) {
$this->inquiryService->addCustomerPrices($inquiry);
} else {
$this->inquiryService->updateCustomerPriceOfferAmounts($inquiry);
$this->inquiryService->updateCustomerDeliveryPricesAmounts($inquiry);
}
}
/**
* @throws TransportExceptionInterface
* @throws DecodingExceptionInterface
*/
public function setCustomsPrices(PriceInquiryVerifiedEvent $event)
{
$inquiry = $event->getInquiry();
$this->inquiryService->autoUpdateCustomsPrices($inquiry);
}
public function createNoCustomsNotification(PriceInquiryVerifiedEvent $event)
{
$inquiry = $event->getInquiry();
if ($this->security->isGranted(PriceInquiryVoter::CAN_UPDATE_CUSTOMS_PRICES, $inquiry)) {
if (!$this->inquiryService->areCustomsSet($inquiry)) {
$this->subscriptionService->proceedEvent(
Event::INQUIRY_CUSTOMS_WERE_NOT_ADDED,
$inquiry,
['data' => ['uuid' => $inquiry->getUuid()]]
);
}
}
}
/**
* @param PriceInquiryVerifiedEvent $event
*/
public function logOfferVerifiedSm(PriceInquiryVerifiedEvent $event)
{
$inquiry = $event->getInquiry();
$this->logService->logAction(
$inquiry->getQuotation(),
'log.inquiry.verified_sm',
$inquiry->getInquiryNumber()
);
$this->userLog->log(
'inquiry',
LogEvents::INQUIRY_UPDATED_VERIFY_SM,
$inquiry->getId(),
$inquiry->getFullInquiryNumber()
);
}
/**
* @param PriceInquiryVerifiedEvent $event
*/
public function logOfferVerifiedMfm(PriceInquiryVerifiedEvent $event)
{
$inquiry = $event->getInquiry();
$this->logService->logAction(
$inquiry->getQuotation(),
'log.inquiry.verified_mfm',
$inquiry->getInquiryNumber()
);
$this->userLog->log(
'inquiry',
LogEvents::INQUIRY_UPDATED_VERIFY_MFM,
$inquiry->getId(),
$inquiry->getFullInquiryNumber()
);
}
public function logPricesChange(PriceInquiryPriceUpdateEvent $event)
{
$inquiry = $event->getInquiry();
$changeSet = $event->getChangeSet();
$changed = array_key_first($changeSet[0]);
$this->logService->logAction(
$inquiry->getQuotation(),
'log.inquiry.' . ($changeSet[0][$changed] ? 'updated' : 'added') . '.' . StringHelper::fromCamelCase($changeSet[2]),
$inquiry->getFullInquiryNumber() . '; ' . $changed . ': CHANGED ' . ($changeSet[0][$changed] ?? 0) . ' -> ' . ($changeSet[1][$changed] ?? 0)
);
$this->userLog->log(
'inquiry',
'inquiry.' . ($changeSet[0][$changed] ? 'updated' : 'added') . '.' . StringHelper::fromCamelCase($changeSet[2]),
$inquiry->getId(),
$inquiry->getFullInquiryNumber() . '; ' . $changed . ': CHANGED ' . ($changeSet[0][$changed] ?? 0) . ' -> ' . ($changeSet[1][$changed] ?? 0)
);
}
public function updateCustomerDeliveryPricesCommission(PriceInquiryPriceUpdateEvent $event)
{
$inquiry = $event->getInquiry();
$changeSet = $event->getChangeSet();
if ($changeSet[2] == 'deliveryPrices') {
foreach ($changeSet[1] as $amount => $deliveryPrice ) {
if (isset($inquiry->getCustomerDeliveryPrices()[$amount])) {
$customerDeliveryPrices = $inquiry->getCustomerDeliveryPrices();
$commission = 0;
if ($deliveryPrice < $customerDeliveryPrices[$amount]) {
$difference = $customerDeliveryPrices[$amount] - $deliveryPrice;
$commission = $deliveryPrice ? ($difference / $deliveryPrice) * 100 : 100;
}
if ($commission < 25) {
$customerDeliveryPrices[$amount] = $deliveryPrice + ($deliveryPrice * 0.25);
$this->logService->logAction(
$inquiry->getQuotation(),
'log.inquiry.updated.customer_delivery_prices',
$inquiry->getFullInquiryNumber() . '; ' . $amount . ': CHANGED ' . $inquiry->getCustomerDeliveryPrices()[$amount] . ' -> ' . $customerDeliveryPrices[$amount]
);
$inquiry->setCustomerDeliveryPrices($customerDeliveryPrices);
}
}
}
}
}
public function logCustomsPricesChange(PriceInquiryPriceUpdateEvent $event)
{
$inquiry = $event->getInquiry();
$changeSet = $event->getChangeSet();
$amount = $changeSet ? array_key_first($changeSet[0]) : null;
$this->logService->logAction(
$inquiry->getQuotation(),
LogEvents::INQUIRY_UPDATED_CUSTOMS,
$inquiry->getFullInquiryNumber() . '; ' . $amount . ': CHANGED ' . ($changeSet[0][$amount] ?? 0) . ' -> ' . ($changeSet[1][$amount] ?? 0)
);
$this->userLog->log(
'inquiry',
LogEvents::INQUIRY_UPDATED_CUSTOMS,
$inquiry->getId(),
$inquiry->getFullInquiryNumber() . '; ' . ($changeSet ? ('; ' . $amount . ': CHANGED ' . ($changeSet[0][$amount] ?? 0) . ' -> ' . ($changeSet[1][$amount] ?? 0)) : '')
);
}
}