<?php
namespace Aqarmap\Bundle\ListingBundle\EventListener;
use Aqarmap\Bundle\ListingBundle\Constant\ListingStatus;
use Aqarmap\Bundle\ListingBundle\Entity\Listing;
use Aqarmap\Bundle\ListingBundle\Event\ListingEvent;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class CompoundFieldListener implements EventSubscriberInterface
{
public const PRIORITY_ONE = 1;
/**
* Doctrine entity manager.
*
* @var EntityManager
*/
protected $entityManager;
public function __construct(EntityManagerInterface $entityManager)
{
$this->entityManager = $entityManager;
}
/**
* Update compound minimun Price upon changs in its units prices.
*
* @throws \Doctrine\ORM\ORMException
* @throws \Doctrine\ORM\OptimisticLockException
*/
public function postSaveProjectUnitEvent(ListingEvent $event): void
{
$listing = $event->getListing();
$parentListing = $listing->getParent();
if ($parentListing && $parentListing->getCompoundField()) {
$listingHasCompoundFieldRecord = $parentListing->getCompoundField();
$listingHasNullMinPrice = $listingHasCompoundFieldRecord && null === $listingHasCompoundFieldRecord->getMinPrice();
$listingHasNullMinArea = $listingHasCompoundFieldRecord && null === $listingHasCompoundFieldRecord->getMinArea();
$isEqualToPrice = !$this->isLiveListing($listing) && $listing->getPrice() == $this->getMinimumPrice($parentListing);
$isLiveListing = $this->isLiveListing($listing);
$listingChildrenCount = $this->entityManager->getRepository(Listing::class)->getListingChildrenCount($parentListing);
$this->setMinArea($listing, $listingHasNullMinArea, $parentListing);
$parentListing->getCompoundField()->setUpdatedAt(new \DateTime());
if ($listingHasNullMinPrice || $isLiveListing || $isEqualToPrice) {
$this->setMinimumPrice($listing);
}
if (!$isLiveListing && 0 == $listingChildrenCount) {
$this->resetCompoundFieldData($parentListing);
}
$this->entityManager->persist($parentListing);
$this->entityManager->flush();
}
}
public static function getSubscribedEvents()
{
return [
'aqarmap.project.re_calculate.min_price_area' => ['postSaveProjectUnitEvent', self::PRIORITY_ONE],
];
}
/**
* @return int
*/
private function getMinimumPrice($parentListing)
{
$minimumPrice = null;
if (null !== $parentListing->getCompoundField()) {
$minimumPrice = $parentListing->getCompoundField()->getMinPrice();
}
return $minimumPrice;
}
/**
* @param Listing
*
* @return Listing
*/
private function setMinimumPrice($listing)
{
$projectUntistMinPrice = $this->entityManager->getRepository(Listing::class)->getProjectUnitsMinPrice($listing);
$parentListing = $listing->getParent();
$parentListing->getCompoundField()->setMinPrice($projectUntistMinPrice);
return $parentListing;
}
/**
* @return int
*/
private function getMinimumArea($parentListing)
{
$minimumArea = null;
if (null !== $parentListing->getCompoundField()) {
$minimumArea = $parentListing->getCompoundField()->getMinArea();
}
return $minimumArea;
}
/**
* @param Listing
*
* @return Listing
*/
private function setMinimumArea($listing)
{
$projectUntistMinArea = $this->entityManager->getRepository(Listing::class)->getProjectUnitsMinArea($listing);
$parentListing = $listing->getParent();
$parentListing->getCompoundField()->setMinArea($projectUntistMinArea);
return $parentListing;
}
/**
* @return bool
*/
private function isLiveListing($listing)
{
return ListingStatus::LIVE == $listing->getStatus();
}
/**
* @param Listing
*
* @return Listing
*/
private function setMinArea($listing, $listingHasNullMinArea, $parentListing)
{
$isEqualToArea = !$this->isLiveListing($listing) && $listing->getArea() == $this->getMinimumArea($parentListing);
$isLiveListing = $this->isLiveListing($listing);
if ($listingHasNullMinArea || $isEqualToArea || $isLiveListing) {
$parentListing = $this->setMinimumArea($listing);
}
return $parentListing;
}
/**
* @param Listing
*
* @return Listing
*/
private function resetCompoundFieldData($listing)
{
$listing->getCompoundField()->setMinArea(null);
$listing->getCompoundField()->setMinPrice(null);
return $listing;
}
}