X-Git-Url: https://git.rapsys.eu/airbundle/blobdiff_plain/af2a5ccc05e664274d24ee8711d398d7dec8808d..HEAD:/Entity/Session.php diff --git a/Entity/Session.php b/Entity/Session.php index 6a0f138..f74963c 100644 --- a/Entity/Session.php +++ b/Entity/Session.php @@ -1,66 +1,131 @@ - + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ namespace Rapsys\AirBundle\Entity; +use Doctrine\Common\Collections\Collection; +use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\ORM\Event\PreUpdateEventArgs; + +use Rapsys\PackBundle\Util\IntlUtil; + /** * Session */ class Session { /** - * @var integer + * Primary key */ - private $id; + private ?int $id = null; /** - * @var \DateTime + * Begin time */ - private $date; + private ?\DateTime $begin = null; /** - * @var \DateTime + * Computed start datetime */ - private $begin; + private ?\DateTime $start = null; /** - * @var \DateTime + * Length time */ - private $length; + private ?\DateTime $length = null; /** - * @var \DateTime + * Computed stop datetime */ - private $created; + private ?\DateTime $stop = null; /** - * @var \DateTime + * Premium */ - private $updated; + private ?bool $premium = null; /** - * @var \Rapsys\AirBundle\Entity\Application + * Rain mm */ - private $application; + private ?float $rainfall = null; /** - * @var \Rapsys\AirBundle\Entity\Location + * Rain chance */ - private $location; + private ?float $rainrisk = null; /** - * @var \Rapsys\AirBundle\Entity\Slot + * Real feel temperature */ - private $slot; + private ?float $realfeel = null; /** - * @var \Doctrine\Common\Collections\Collection + * Real feel minimum temperature */ - private $applications; + private ?float $realfeelmin = null; + + /** + * Real feel maximum temperature + */ + private ?float $realfeelmax = null; + + /** + * Temperature + */ + private ?float $temperature = null; + + /** + * Minimum temperature + */ + private ?float $temperaturemin = null; + + /** + * Maximum temperature + */ + private ?float $temperaturemax = null; + + /** + * Lock datetime + */ + private ?\DateTime $locked = null; + + /** + * Create datetime + */ + private \DateTime $created; + + /** + * Update datetime + */ + private \DateTime $updated; + + /** + * Application instance + */ + private ?Application $application = null; + + /** + * Applications collection + */ + private Collection $applications; /** * Constructor */ - public function __construct() { - $this->applications = new \Doctrine\Common\Collections\ArrayCollection(); + public function __construct(private \DateTime $date, private Location $location, private Slot $slot) { + //Set defaults + $this->created = new \DateTime('now'); + $this->updated = new \DateTime('now'); + + //Set collections + $this->applications = new ArrayCollection(); } /** @@ -68,7 +133,7 @@ class Session { * * @return integer */ - public function getId() { + public function getId(): ?int { return $this->id; } @@ -79,7 +144,7 @@ class Session { * * @return Session */ - public function setDate($date) { + public function setDate(\DateTime $date): Session { $this->date = $date; return $this; @@ -90,7 +155,7 @@ class Session { * * @return \DateTime */ - public function getDate() { + public function getDate(): \DateTime { return $this->date; } @@ -101,7 +166,7 @@ class Session { * * @return Session */ - public function setBegin($begin) { + public function setBegin(?\DateTime $begin): Session { $this->begin = $begin; return $this; @@ -112,10 +177,41 @@ class Session { * * @return \DateTime */ - public function getBegin() { + public function getBegin(): ?\DateTime { return $this->begin; } + /** + * Get start + * + * @return \DateTime + */ + public function getStart(): \DateTime { + //With start + if ($this->start !== null) { + return $this->start; + } + + //Clone date + $this->start = clone $this->date; + + //Check if after slot + //XXX: id=4 <=> title=After + if ($this->slot->getId() == 4) { + //Add one day + $this->start->add(new \DateInterval('P1D')); + } + + //With begin + if ($this->begin !== null) { + //Set start time + $this->start->setTime(intval($this->begin->format('H')), intval($this->begin->format('i')), intval($this->begin->format('s'))); + } + + //Return start + return $this->start; + } + /** * Set length * @@ -123,7 +219,7 @@ class Session { * * @return Session */ - public function setLength($length) { + public function setLength(?\DateTime $length): Session { $this->length = $length; return $this; @@ -134,10 +230,254 @@ class Session { * * @return \DateTime */ - public function getLength() { + public function getLength(): ?\DateTime { return $this->length; } + /** + * Get stop + * + * @return \DateTime + */ + public function getStop(): \DateTime { + //Check start + if ($this->stop !== null) { + return $this->stop; + } + + //Get start clone + $this->stop = clone $this->getStart(); + + //With length + if ($this->length !== null) { + //Set stop time + $this->stop->add(new \DateInterval('PT'.$this->length->format('H').'H'.$this->length->format('i').'M'.$this->length->format('s').'S')); + } + + //Return date + return $this->stop; + } + + /** + * Set premium + * + * @param bool $premium + * + * @return Session + */ + public function setPremium(?bool $premium): Session { + $this->premium = $premium; + + return $this; + } + + /** + * Get premium + * + * @return bool + */ + public function getPremium(): ?bool { + return $this->premium; + } + + /** + * Set rainfall + * + * @param float $rainfall + * + * @return Session + */ + public function setRainfall(?float $rainfall): Session { + $this->rainfall = $rainfall; + + return $this; + } + + /** + * Get rainfall + * + * @return float + */ + public function getRainfall(): ?float { + return $this->rainfall; + } + + /** + * Set rainrisk + * + * @param float $rainrisk + * + * @return Session + */ + public function setRainrisk(?float $rainrisk): Session { + $this->rainrisk = $rainrisk; + + return $this; + } + + /** + * Get rainrisk + * + * @return float + */ + public function getRainrisk(): ?float { + return $this->rainrisk; + } + + /** + * Set realfeel + * + * @param float $realfeel + * + * @return Session + */ + public function setRealfeel(?float $realfeel): Session { + $this->realfeel = $realfeel; + + return $this; + } + + /** + * Get realfeel + * + * @return float + */ + public function getRealfeel(): ?float { + return $this->realfeel; + } + + /** + * Set realfeelmin + * + * @param float $realfeelmin + * + * @return Session + */ + public function setRealfeelmin(?float $realfeelmin): Session { + $this->realfeelmin = $realfeelmin; + + return $this; + } + + /** + * Get realfeelmin + * + * @return float + */ + public function getRealfeelmin(): ?float { + return $this->realfeelmin; + } + + /** + * Set realfeelmax + * + * @param float $realfeelmax + * + * @return Session + */ + public function setRealfeelmax(?float $realfeelmax): Session { + $this->realfeelmax = $realfeelmax; + + return $this; + } + + /** + * Get realfeelmax + * + * @return float + */ + public function getRealfeelmax(): ?float { + return $this->realfeelmax; + } + + /** + * Set temperature + * + * @param float $temperature + * + * @return Session + */ + public function setTemperature(?float $temperature): Session { + $this->temperature = $temperature; + + return $this; + } + + /** + * Get temperature + * + * @return float + */ + public function getTemperature(): ?float { + return $this->temperature; + } + + /** + * Set temperaturemin + * + * @param float $temperaturemin + * + * @return Session + */ + public function setTemperaturemin(?float $temperaturemin): Session { + $this->temperaturemin = $temperaturemin; + + return $this; + } + + /** + * Get temperaturemin + * + * @return float + */ + public function getTemperaturemin(): ?float { + return $this->temperaturemin; + } + + /** + * Set temperaturemax + * + * @param float $temperaturemax + * + * @return Session + */ + public function setTemperaturemax(?float $temperaturemax): Session { + $this->temperaturemax = $temperaturemax; + + return $this; + } + + /** + * Get temperaturemax + * + * @return float + */ + public function getTemperaturemax(): ?float { + return $this->temperaturemax; + } + + /** + * Set locked + * + * @param \DateTime $locked + * + * @return Session + */ + public function setLocked(?\DateTime $locked): Session { + $this->locked = $locked; + + return $this; + } + + /** + * Get locked + * + * @return \DateTime + */ + public function getLocked(): ?\DateTime { + return $this->locked; + } + /** * Set created * @@ -145,7 +485,7 @@ class Session { * * @return Session */ - public function setCreated($created) { + public function setCreated(\DateTime $created): Session { $this->created = $created; return $this; @@ -156,7 +496,7 @@ class Session { * * @return \DateTime */ - public function getCreated() { + public function getCreated(): \DateTime { return $this->created; } @@ -167,7 +507,7 @@ class Session { * * @return Session */ - public function setUpdated($updated) { + public function setUpdated(\DateTime $updated): Session { $this->updated = $updated; return $this; @@ -178,18 +518,18 @@ class Session { * * @return \DateTime */ - public function getUpdated() { + public function getUpdated(): \DateTime { return $this->updated; } /** * Add application * - * @param \Rapsys\AirBundle\Entity\Application $application + * @param Application $application * * @return Session */ - public function addApplication(\Rapsys\AirBundle\Entity\Application $application) { + public function addApplication(Application $application): Session { $this->applications[] = $application; return $this; @@ -198,29 +538,29 @@ class Session { /** * Remove application * - * @param \Rapsys\AirBundle\Entity\Application $application + * @param Application $application */ - public function removeApplication(\Rapsys\AirBundle\Entity\Application $application) { - $this->applications->removeElement($application); + public function removeApplication(Application $application): bool { + return $this->applications->removeElement($application); } /** * Get applications * - * @return \Doctrine\Common\Collections\Collection + * @return ArrayCollection */ - public function getApplications() { + public function getApplications(): ArrayCollection { return $this->applications; } /** * Set location * - * @param \Rapsys\AirBundle\Entity\Location $location + * @param Location $location * * @return Session */ - public function setLocation(\Rapsys\AirBundle\Entity\Location $location = null) { + public function setLocation(Location $location): Session { $this->location = $location; return $this; @@ -229,20 +569,20 @@ class Session { /** * Get location * - * @return \Rapsys\AirBundle\Entity\Location + * @return Location */ - public function getLocation() { + public function getLocation(): Location { return $this->location; } /** * Set slot * - * @param \Rapsys\AirBundle\Entity\Slot $slot + * @param Slot $slot * * @return Session */ - public function setSlot(\Rapsys\AirBundle\Entity\Slot $slot = null) { + public function setSlot(Slot $slot): Session { $this->slot = $slot; return $this; @@ -251,20 +591,20 @@ class Session { /** * Get slot * - * @return \Rapsys\AirBundle\Entity\Slot + * @return Slot */ - public function getSlot() { + public function getSlot(): Slot { return $this->slot; } /** * Set application * - * @param \Rapsys\AirBundle\Entity\Application $application + * @param Application $application * * @return Session */ - public function setApplication(\Rapsys\AirBundle\Entity\Application $application = null) { + public function setApplication(?Application $application): Session { $this->application = $application; return $this; @@ -273,9 +613,126 @@ class Session { /** * Get application * - * @return \Rapsys\AirBundle\Entity\Application + * @return Application */ - public function getApplication() { + public function getApplication(): ?Application { return $this->application; } + + /** + * {@inheritdoc} + */ + public function preUpdate(PreUpdateEventArgs $eventArgs) { + //Check that we have a session instance + if (($session = $eventArgs->getObject()) instanceof Session) { + //Set updated value + $session->setUpdated(new \DateTime('now')); + } + } + + /** + * Wether if session is a premium day + * + * Consider as premium a day off for afternoon, the eve for evening and after + * Store computed result in premium member for afternoon and evening + * + * @TODO improve by moving day off computation in IntlUtil or HolidayUtil class ? + * + * @return bool Whether the date is day off or not + */ + public function isPremium(): bool { + //Without date + if (empty($date = $this->date)) { + throw new \LogicException('Property date is empty'); + } + + //Without slot + if (empty($slot = $this->slot) || empty($slotTitle = $slot->getTitle())) { + throw new \LogicException('Property slot is empty'); + } + + //With evening and after slot + if ($slotTitle == 'Evening' || $slotTitle == 'After') { + //Evening and after session is considered premium when the eve is a day off + $date = (clone $date)->add(new \DateInterval('P1D')); + } + + //Get day number + $w = $date->format('w'); + + //Check if weekend day + if ($w == 0 || $w == 6) { + //With afternoon and evening slot + if ($slotTitle == 'Afternoon' || $slotTitle == 'Evening') { + //Save premium + $this->premium = true; + } + + //Date is weekend day + return true; + } + + //Get date day + $d = $date->format('d'); + + //Get date month + $m = $date->format('m'); + + //Check if fixed holiday + if ( + //Check if 1st january + ($d == 1 && $m == 1) || + //Check if 1st may + ($d == 1 && $m == 5) || + //Check if 8st may + ($d == 8 && $m == 5) || + //Check if 14st july + ($d == 14 && $m == 7) || + //Check if 15st august + ($d == 15 && $m == 8) || + //Check if 1st november + ($d == 1 && $m == 11) || + //Check if 11st november + ($d == 11 && $m == 11) || + //Check if 25st december + ($d == 25 && $m == 12) + ) { + //With afternoon and evening slot + if ($slotTitle == 'Afternoon' || $slotTitle == 'Evening') { + //Save premium + $this->premium = true; + } + + //Date is a fixed holiday + return true; + } + + //Get eastern + $eastern = (new IntlUtil())->getEastern($date->format('Y')); + + //Check dynamic holidays + if ( + (clone $eastern)->add(new \DateInterval('P1D')) == $date || + (clone $eastern)->add(new \DateInterval('P39D')) == $date || + (clone $eastern)->add(new \DateInterval('P50D')) == $date + ) { + //With afternoon and evening slot + if ($slotTitle == 'Afternoon' || $slotTitle == 'Evening') { + //Save premium + $this->premium = true; + } + + //Date is a dynamic holiday + return true; + } + + //With afternoon and evening slot + if ($slotTitle == 'Afternoon' || $slotTitle == 'Evening') { + //Save premium + $this->premium = false; + } + + //Date is not a holiday and week day + return false; + } }