1 <?php 
declare(strict_types
=1); 
   4  * This file is part of the Rapsys AirBundle package. 
   6  * (c) Raphaël Gertz <symfony@rapsys.eu> 
   8  * For the full copyright and license information, please view the LICENSE 
   9  * file that was distributed with this source code. 
  12 namespace Rapsys\AirBundle\Entity
; 
  14 use Doctrine\Common\Collections\Collection
; 
  15 use Doctrine\Common\Collections\ArrayCollection
; 
  16 use Doctrine\ORM\Event\PreUpdateEventArgs
; 
  18 use Rapsys\PackBundle\Util\IntlUtil
; 
  27         private ?int $id = null; 
  32         private ?\DateTime 
$begin = null; 
  35          * Computed start datetime 
  37         private ?\DateTime 
$start = null; 
  42         private ?\DateTime 
$length = null; 
  45          * Computed stop datetime 
  47         private ?\DateTime 
$stop = null; 
  52         private ?bool $premium = null; 
  57         private ?float $rainfall = null; 
  62         private ?float $rainrisk = null; 
  65          * Real feel temperature 
  67         private ?float $realfeel = null; 
  70          * Real feel minimum temperature 
  72         private ?float $realfeelmin = null; 
  75          * Real feel maximum temperature 
  77         private ?float $realfeelmax = null; 
  82         private ?float $temperature = null; 
  87         private ?float $temperaturemin = null; 
  92         private ?float $temperaturemax = null; 
  97         private ?\DateTime 
$locked = null; 
 102         private \DateTime 
$created; 
 107         private \DateTime 
$updated; 
 110          * Application instance 
 112         private ?Application 
$application = null; 
 115          * Applications collection 
 117         private Collection 
$applications; 
 122         public function __construct(private \DateTime 
$date, private Location 
$location, private Slot 
$slot) { 
 124                 $this->created 
= new \
DateTime('now'); 
 125                 $this->updated 
= new \
DateTime('now'); 
 128                 $this->applications 
= new ArrayCollection(); 
 136         public function getId(): ?int { 
 143          * @param \DateTime $date 
 147         public function setDate(\DateTime 
$date): Session 
{ 
 158         public function getDate(): \DateTime 
{ 
 165          * @param \DateTime $begin 
 169         public function setBegin(?\DateTime 
$begin): Session 
{ 
 170                 $this->begin 
= $begin; 
 180         public function getBegin(): ?\DateTime 
{ 
 189         public function getStart(): \DateTime 
{ 
 191                 if ($this->start 
!== null) { 
 196                 $this->start 
= clone $this->date
; 
 198                 //Check if after slot 
 199                 //XXX: id=4 <=> title=After 
 200                 if ($this->slot
->getId() == 4) { 
 202                         $this->start
->add(new \
DateInterval('P1D')); 
 206                 if ($this->begin 
!== null) { 
 208                         $this->start
->setTime(intval($this->begin
->format('H')), intval($this->begin
->format('i')), intval($this->begin
->format('s'))); 
 218          * @param \DateTime $length 
 222         public function setLength(?\DateTime 
$length): Session 
{ 
 223                 $this->length 
= $length; 
 233         public function getLength(): ?\DateTime 
{ 
 234                 return $this->length
; 
 242         public function getStop(): \DateTime 
{ 
 244                 if ($this->stop 
!== null) { 
 249                 $this->stop 
= clone $this->getStart(); 
 252                 if ($this->length 
!== null) { 
 254                         $this->stop
->add(new \
DateInterval('PT'.$this->length
->format('H').'H'.$this->length
->format('i').'M'.$this->length
->format('s').'S')); 
 264          * @param bool $premium 
 268         public function setPremium(?bool $premium): Session 
{ 
 269                 $this->premium 
= $premium; 
 279         public function getPremium(): ?bool { 
 280                 return $this->premium
; 
 286          * @param float $rainfall 
 290         public function setRainfall(?float $rainfall): Session 
{ 
 291                 $this->rainfall 
= $rainfall; 
 301         public function getRainfall(): ?float { 
 302                 return $this->rainfall
; 
 308          * @param float $rainrisk 
 312         public function setRainrisk(?float $rainrisk): Session 
{ 
 313                 $this->rainrisk 
= $rainrisk; 
 323         public function getRainrisk(): ?float { 
 324                 return $this->rainrisk
; 
 330          * @param float $realfeel 
 334         public function setRealfeel(?float $realfeel): Session 
{ 
 335                 $this->realfeel 
= $realfeel; 
 345         public function getRealfeel(): ?float { 
 346                 return $this->realfeel
; 
 352          * @param float $realfeelmin 
 356         public function setRealfeelmin(?float $realfeelmin): Session 
{ 
 357                 $this->realfeelmin 
= $realfeelmin; 
 367         public function getRealfeelmin(): ?float { 
 368                 return $this->realfeelmin
; 
 374          * @param float $realfeelmax 
 378         public function setRealfeelmax(?float $realfeelmax): Session 
{ 
 379                 $this->realfeelmax 
= $realfeelmax; 
 389         public function getRealfeelmax(): ?float { 
 390                 return $this->realfeelmax
; 
 396          * @param float $temperature 
 400         public function setTemperature(?float $temperature): Session 
{ 
 401                 $this->temperature 
= $temperature; 
 411         public function getTemperature(): ?float { 
 412                 return $this->temperature
; 
 418          * @param float $temperaturemin 
 422         public function setTemperaturemin(?float $temperaturemin): Session 
{ 
 423                 $this->temperaturemin 
= $temperaturemin; 
 433         public function getTemperaturemin(): ?float { 
 434                 return $this->temperaturemin
; 
 440          * @param float $temperaturemax 
 444         public function setTemperaturemax(?float $temperaturemax): Session 
{ 
 445                 $this->temperaturemax 
= $temperaturemax; 
 455         public function getTemperaturemax(): ?float { 
 456                 return $this->temperaturemax
; 
 462          * @param \DateTime $locked 
 466         public function setLocked(?\DateTime 
$locked): Session 
{ 
 467                 $this->locked 
= $locked; 
 477         public function getLocked(): ?\DateTime 
{ 
 478                 return $this->locked
; 
 484          * @param \DateTime $created 
 488         public function setCreated(\DateTime 
$created): Session 
{ 
 489                 $this->created 
= $created; 
 499         public function getCreated(): \DateTime 
{ 
 500                 return $this->created
; 
 506          * @param \DateTime $updated 
 510         public function setUpdated(\DateTime 
$updated): Session 
{ 
 511                 $this->updated 
= $updated; 
 521         public function getUpdated(): \DateTime 
{ 
 522                 return $this->updated
; 
 528          * @param Application $application 
 532         public function addApplication(Application 
$application): Session 
{ 
 533                 $this->applications
[] = $application; 
 541          * @param Application $application 
 543         public function removeApplication(Application 
$application): bool { 
 544                 return $this->applications
->removeElement($application); 
 550          * @return ArrayCollection 
 552         public function getApplications(): ArrayCollection 
{ 
 553                 return $this->applications
; 
 559          * @param Location $location 
 563         public function setLocation(Location 
$location): Session 
{ 
 564                 $this->location 
= $location; 
 574         public function getLocation(): Location 
{ 
 575                 return $this->location
; 
 585         public function setSlot(Slot 
$slot): Session 
{ 
 596         public function getSlot(): Slot 
{ 
 603          * @param Application $application 
 607         public function setApplication(?Application 
$application): Session 
{ 
 608                 $this->application 
= $application; 
 616          * @return Application 
 618         public function getApplication(): ?Application 
{ 
 619                 return $this->application
; 
 625         public function preUpdate(PreUpdateEventArgs 
$eventArgs) { 
 626                 //Check that we have a session instance 
 627                 if (($session = $eventArgs->getObject()) instanceof Session
) { 
 629                         $session->setUpdated(new \
DateTime('now')); 
 634          * Wether if session is a premium day 
 636          * Consider as premium a day off for afternoon, the eve for evening and after 
 637          * Store computed result in premium member for afternoon and evening 
 639          * @TODO improve by moving day off computation in IntlUtil or HolidayUtil class ? 
 641          * @return bool Whether the date is day off or not 
 643         public function isPremium(): bool { 
 645                 if (empty($date = $this->date
)) { 
 646                         throw new \
LogicException('Property date is empty'); 
 650                 if (empty($slot = $this->slot
) || empty($slotTitle = $slot->getTitle())) { 
 651                         throw new \
LogicException('Property slot is empty'); 
 654                 //With evening and after slot 
 655                 if ($slotTitle == 'Evening' || $slotTitle == 'After') { 
 656                         //Evening and after session is considered premium when the eve is a day off 
 657                         $date = (clone $date)->add(new \
DateInterval('P1D')); 
 661                 $w = $date->format('w'); 
 663                 //Check if weekend day 
 664                 if ($w == 0 || $w == 6) { 
 665                         //With afternoon and evening slot 
 666                         if ($slotTitle == 'Afternoon' || $slotTitle == 'Evening') { 
 668                                 $this->premium 
= true; 
 671                         //Date is weekend day 
 676                 $d = $date->format('d'); 
 679                 $m = $date->format('m'); 
 681                 //Check if fixed holiday 
 683                         //Check if 1st january 
 684                         ($d == 1 && $m == 1) || 
 686                         ($d == 1 && $m == 5) || 
 688                         ($d == 8 && $m == 5) || 
 690                         ($d == 14 && $m == 7) || 
 691                         //Check if 15st august 
 692                         ($d == 15 && $m == 8) || 
 693                         //Check if 1st november 
 694                         ($d == 1 && $m == 11) || 
 695                         //Check if 11st november 
 696                         ($d == 11 && $m == 11) || 
 697                         //Check if 25st december 
 698                         ($d == 25 && $m == 12) 
 700                         //With afternoon and evening slot 
 701                         if ($slotTitle == 'Afternoon' || $slotTitle == 'Evening') { 
 703                                 $this->premium 
= true; 
 706                         //Date is a fixed holiday 
 711                 $eastern = (new IntlUtil())->getEastern($date->format('Y')); 
 713                 //Check dynamic holidays 
 715                         (clone $eastern)->add(new \
DateInterval('P1D')) == $date || 
 716                         (clone $eastern)->add(new \
DateInterval('P39D')) == $date || 
 717                         (clone $eastern)->add(new \
DateInterval('P50D')) == $date 
 719                         //With afternoon and evening slot 
 720                         if ($slotTitle == 'Afternoon' || $slotTitle == 'Evening') { 
 722                                 $this->premium 
= true; 
 725                         //Date is a dynamic holiday 
 729                 //With afternoon and evening slot 
 730                 if ($slotTitle == 'Afternoon' || $slotTitle == 'Evening') { 
 732                         $this->premium 
= false; 
 735                 //Date is not a holiday and week day