<?php
namespace App\EventSubscriber;
use App\Event\SupplyEvent;
use App\Entity\SupplyActionHistory;
use DateTime;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class SupplySubscriber implements EventSubscriberInterface
{
private ManagerRegistry $managerRegistry;
public function __construct(ManagerRegistry $managerRegistry)
{
$this->managerRegistry = $managerRegistry;
}
/**
* @return float|int
*/
private function computeLost(int $qt, int $loss)
{
if ($loss < 0) { return $qt; }
$loss = ($qt * $loss) / 100;
$qt += $loss;
$qt = is_float($qt) ? round($qt) : $qt;
return $qt;
}
private function save($entity): void
{
$manager = $this->managerRegistry->getManager();
$manager->persist($entity);
$manager->flush();
}
public function updateSupplyQty(SupplyEvent $event): void
{
$supply = $event->getSupply();
$supplyHistory = $event->getSupplyHistory();
$oldQuantity = $event->getOldQuantity();
$supplyQuantity = $supply->getQuantityInStock();
$direction = $supplyHistory->getDirection();
$supplyHistoryQuantity = $supplyHistory->getQuantity();
$quantityWithLost = $this->computeLost($supplyHistoryQuantity, $supply->getLost());
if (!is_null($oldQuantity)) { # if $oldQuantity is not null, we edit an existing Supply Action History (SAH)
if (SupplyActionHistory::DIRECTION_OUT === $direction) { # if we remove quantity
$oldQuantityWithLost = $this->computeLost($oldQuantity, $supply->getLost()); # to edit this entry, we set the quantity to the initial state
$quantityBeforeEntry = $supplyQuantity + $oldQuantityWithLost;
$quantity = $quantityBeforeEntry - $quantityWithLost; # so the qt to remove will be the initial qt minus the new qt with lost
} else { # if we add quantity
$quantityBeforeEntry = $supplyQuantity - $oldQuantity; # as above, we set the quantity to the initial state
$quantity = $quantityBeforeEntry + $supplyHistoryQuantity; # then we simply remove the new quantity
}
} else { # in this case, a new SAH is created
if (SupplyActionHistory::DIRECTION_OUT === $direction) { # if we remove quantity
$quantity = $supplyQuantity - $quantityWithLost; # get supply qt and remove the quantity from the input form
} else { # otherwise, we add a new quantity in stock
$quantity = $supplyQuantity + $supplyHistoryQuantity; # so we add the quantity from the input form to the supply quantity
}
}
$supply->setQuantityInStock($quantity);
$supply->setUpdatedDate(new DateTime('now'));
$this->save($supply);
$event->stopPropagation();
}
public function updateSupplyQuantityWhenDeleteHistory(SupplyEvent $supplyEvent): void
{
$supply = $supplyEvent->getSupply();
$supplyHistory = $supplyEvent->getSupplyHistory();
$supplyQuantityInStock = $supply->getQuantityInStock();
$supplyActionHistoryQuantity = $supplyHistory->getQuantity();
switch ($supplyHistory->getDirection()) {
case SupplyActionHistory::DIRECTION_OUT:
$withdrawnQuantityWithLost = $this->computeLost($supplyActionHistoryQuantity, $supply->getLost());
$supply->setQuantityInStock($supplyQuantityInStock + $withdrawnQuantityWithLost);
break;
case SupplyActionHistory::DIRECTION_IN:
$supply->setQuantityInStock($supplyQuantityInStock - $supplyActionHistoryQuantity);
break;
}
$this->save($supply);
}
public static function getSubscribedEvents(): array
{
return [
SupplyEvent::UPDATE_SUPPLY_QT => 'updateSupplyQty',
SupplyEvent::UPDATE_QT_WHEN_DELETE_SUPPLY_HISTORY => 'updateSupplyQuantityWhenDeleteHistory'
];
}
}