]> Raphaël G. Git Repositories - airbundle/blob - Entity/Session.php
Add premium as nullable
[airbundle] / Entity / Session.php
1 <?php declare(strict_types=1);
2
3 /*
4 * this file is part of the rapsys packbundle package.
5 *
6 * (c) raphaël gertz <symfony@rapsys.eu>
7 *
8 * for the full copyright and license information, please view the license
9 * file that was distributed with this source code.
10 */
11
12 namespace Rapsys\AirBundle\Entity;
13
14 use Doctrine\Common\Collections\ArrayCollection;
15 use Doctrine\ORM\Event\PreUpdateEventArgs;
16
17 /**
18 * Session
19 */
20 class Session {
21 /**
22 * @var integer
23 */
24 private $id;
25
26 /**
27 * @var \DateTime
28 */
29 private $date;
30
31 /**
32 * @var \DateTime
33 */
34 private $begin;
35
36 /**
37 * @var \DateTime
38 */
39 private $start;
40
41 /**
42 * @var \DateTime
43 */
44 private $length;
45
46 /**
47 * @var \DateTime
48 */
49 private $stop;
50
51 /**
52 * @var boolean
53 */
54 private $premium;
55
56 /**
57 * @var float
58 */
59 private $rainfall;
60
61 /**
62 * @var float
63 */
64 private $rainrisk;
65
66 /**
67 * @var float
68 */
69 private $realfeel;
70
71 /**
72 * @var float
73 */
74 private $realfeelmin;
75
76 /**
77 * @var float
78 */
79 private $realfeelmax;
80
81 /**
82 * @var float
83 */
84 private $temperature;
85
86 /**
87 * @var float
88 */
89 private $temperaturemin;
90
91 /**
92 * @var float
93 */
94 private $temperaturemax;
95
96 /**
97 * @var \DateTime
98 */
99 private $locked;
100
101 /**
102 * @var \DateTime
103 */
104 private $created;
105
106 /**
107 * @var \DateTime
108 */
109 private $updated;
110
111 /**
112 * @var Application
113 */
114 private $application;
115
116 /**
117 * @var Location
118 */
119 private $location;
120
121 /**
122 * @var Slot
123 */
124 private $slot;
125
126 /**
127 * @var ArrayCollection
128 */
129 private $applications;
130
131 /**
132 * Constructor
133 */
134 public function __construct() {
135 $this->begin = null;
136 $this->start = null;
137 $this->length = null;
138 $this->stop = null;
139 $this->rainfall = null;
140 $this->rainrisk = null;
141 $this->realfeel = null;
142 $this->realfeelmin = null;
143 $this->realfeelmax = null;
144 $this->temperature = null;
145 $this->temperaturemin = null;
146 $this->temperaturemax = null;
147 $this->locked = null;
148 $this->premium = null;
149 $this->applications = new ArrayCollection();
150 }
151
152 /**
153 * Get id
154 *
155 * @return integer
156 */
157 public function getId(): int {
158 return $this->id;
159 }
160
161 /**
162 * Set date
163 *
164 * @param \DateTime $date
165 *
166 * @return Session
167 */
168 public function setDate(\DateTime $date): Session {
169 $this->date = $date;
170
171 return $this;
172 }
173
174 /**
175 * Get date
176 *
177 * @return \DateTime
178 */
179 public function getDate(): \DateTime {
180 return $this->date;
181 }
182
183 /**
184 * Set begin
185 *
186 * @param \DateTime $begin
187 *
188 * @return Session
189 */
190 public function setBegin(?\DateTime $begin): Session {
191 $this->begin = $begin;
192
193 return $this;
194 }
195
196 /**
197 * Get begin
198 *
199 * @return \DateTime
200 */
201 public function getBegin(): ?\DateTime {
202 return $this->begin;
203 }
204
205 /**
206 * Get start
207 *
208 * @return \DateTime
209 */
210 public function getStart(): \DateTime {
211 //With start
212 if ($this->start !== null) {
213 return $this->start;
214 }
215
216 //Clone date
217 $this->start = clone $this->date;
218
219 //Check if after slot
220 //XXX: id=4 <=> title=After
221 if ($this->slot->getId() == 4) {
222 //Add one day
223 $this->start->add(new \DateInterval('P1D'));
224 }
225
226 //With begin
227 if ($this->begin !== null) {
228 //Set start time
229 $this->start->setTime(intval($this->begin->format('H')), intval($this->begin->format('i')), intval($this->begin->format('s')));
230 }
231
232 //Return start
233 return $this->start;
234 }
235
236 /**
237 * Set length
238 *
239 * @param \DateTime $length
240 *
241 * @return Session
242 */
243 public function setLength(?\DateTime $length): Session {
244 $this->length = $length;
245
246 return $this;
247 }
248
249 /**
250 * Get length
251 *
252 * @return \DateTime
253 */
254 public function getLength(): ?\DateTime {
255 return $this->length;
256 }
257
258 /**
259 * Get stop
260 *
261 * @return \DateTime
262 */
263 public function getStop(): \DateTime {
264 //Check start
265 if ($this->stop !== null) {
266 return $this->stop;
267 }
268
269 //Get start clone
270 $this->stop = clone $this->getStart();
271
272 //With length
273 if ($this->length !== null) {
274 //Set stop time
275 $this->stop->add(new \DateInterval('PT'.$this->length->format('H').'H'.$this->length->format('i').'M'.$this->length->format('s').'S'));
276 }
277
278 //Return date
279 return $this->stop;
280 }
281
282 /**
283 * Set premium
284 *
285 * @param boolean $premium
286 *
287 * @return Session
288 */
289 public function setPremium(bool $premium): Session {
290 $this->premium = $premium;
291
292 return $this;
293 }
294
295 /**
296 * Get premium
297 *
298 * @return bool
299 */
300 public function getPremium(): bool {
301 return $this->premium;
302 }
303
304 /**
305 * Set rainfall
306 *
307 * @param float $rainfall
308 *
309 * @return Session
310 */
311 public function setRainfall(?float $rainfall): Session {
312 $this->rainfall = $rainfall;
313
314 return $this;
315 }
316
317 /**
318 * Get rainfall
319 *
320 * @return float
321 */
322 public function getRainfall(): ?float {
323 return $this->rainfall;
324 }
325
326 /**
327 * Set rainrisk
328 *
329 * @param float $rainrisk
330 *
331 * @return Session
332 */
333 public function setRainrisk(?float $rainrisk): Session {
334 $this->rainrisk = $rainrisk;
335
336 return $this;
337 }
338
339 /**
340 * Get rainrisk
341 *
342 * @return float
343 */
344 public function getRainrisk(): ?float {
345 return $this->rainrisk;
346 }
347
348 /**
349 * Set realfeel
350 *
351 * @param float $realfeel
352 *
353 * @return Session
354 */
355 public function setRealfeel(?float $realfeel): Session {
356 $this->realfeel = $realfeel;
357
358 return $this;
359 }
360
361 /**
362 * Get realfeel
363 *
364 * @return float
365 */
366 public function getRealfeel(): ?float {
367 return $this->realfeel;
368 }
369
370 /**
371 * Set realfeelmin
372 *
373 * @param float $realfeelmin
374 *
375 * @return Session
376 */
377 public function setRealfeelmin(?float $realfeelmin): Session {
378 $this->realfeelmin = $realfeelmin;
379
380 return $this;
381 }
382
383 /**
384 * Get realfeelmin
385 *
386 * @return float
387 */
388 public function getRealfeelmin(): ?float {
389 return $this->realfeelmin;
390 }
391
392 /**
393 * Set realfeelmax
394 *
395 * @param float $realfeelmax
396 *
397 * @return Session
398 */
399 public function setRealfeelmax(?float $realfeelmax): Session {
400 $this->realfeelmax = $realfeelmax;
401
402 return $this;
403 }
404
405 /**
406 * Get realfeelmax
407 *
408 * @return float
409 */
410 public function getRealfeelmax(): ?float {
411 return $this->realfeelmax;
412 }
413
414 /**
415 * Set temperature
416 *
417 * @param float $temperature
418 *
419 * @return Session
420 */
421 public function setTemperature(?float $temperature): Session {
422 $this->temperature = $temperature;
423
424 return $this;
425 }
426
427 /**
428 * Get temperature
429 *
430 * @return float
431 */
432 public function getTemperature(): ?float {
433 return $this->temperature;
434 }
435
436 /**
437 * Set temperaturemin
438 *
439 * @param float $temperaturemin
440 *
441 * @return Session
442 */
443 public function setTemperaturemin(?float $temperaturemin): Session {
444 $this->temperaturemin = $temperaturemin;
445
446 return $this;
447 }
448
449 /**
450 * Get temperaturemin
451 *
452 * @return float
453 */
454 public function getTemperaturemin(): ?float {
455 return $this->temperaturemin;
456 }
457
458 /**
459 * Set temperaturemax
460 *
461 * @param float $temperaturemax
462 *
463 * @return Session
464 */
465 public function setTemperaturemax(?float $temperaturemax): Session {
466 $this->temperaturemax = $temperaturemax;
467
468 return $this;
469 }
470
471 /**
472 * Get temperaturemax
473 *
474 * @return float
475 */
476 public function getTemperaturemax(): ?float {
477 return $this->temperaturemax;
478 }
479
480 /**
481 * Set locked
482 *
483 * @param \DateTime $locked
484 *
485 * @return Session
486 */
487 public function setLocked(?\DateTime $locked): Session {
488 $this->locked = $locked;
489
490 return $this;
491 }
492
493 /**
494 * Get locked
495 *
496 * @return \DateTime
497 */
498 public function getLocked(): ?\DateTime {
499 return $this->locked;
500 }
501
502 /**
503 * Set created
504 *
505 * @param \DateTime $created
506 *
507 * @return Session
508 */
509 public function setCreated(\DateTime $created): Session {
510 $this->created = $created;
511
512 return $this;
513 }
514
515 /**
516 * Get created
517 *
518 * @return \DateTime
519 */
520 public function getCreated(): \DateTime {
521 return $this->created;
522 }
523
524 /**
525 * Set updated
526 *
527 * @param \DateTime $updated
528 *
529 * @return Session
530 */
531 public function setUpdated(\DateTime $updated): Session {
532 $this->updated = $updated;
533
534 return $this;
535 }
536
537 /**
538 * Get updated
539 *
540 * @return \DateTime
541 */
542 public function getUpdated(): \DateTime {
543 return $this->updated;
544 }
545
546 /**
547 * Add application
548 *
549 * @param Application $application
550 *
551 * @return Session
552 */
553 public function addApplication(Application $application): Session {
554 $this->applications[] = $application;
555
556 return $this;
557 }
558
559 /**
560 * Remove application
561 *
562 * @param Application $application
563 */
564 public function removeApplication(Application $application): bool {
565 return $this->applications->removeElement($application);
566 }
567
568 /**
569 * Get applications
570 *
571 * @return ArrayCollection
572 */
573 public function getApplications(): ArrayCollection {
574 return $this->applications;
575 }
576
577 /**
578 * Set location
579 *
580 * @param Location $location
581 *
582 * @return Session
583 */
584 public function setLocation(Location $location): Session {
585 $this->location = $location;
586
587 return $this;
588 }
589
590 /**
591 * Get location
592 *
593 * @return Location
594 */
595 public function getLocation(): Location {
596 return $this->location;
597 }
598
599 /**
600 * Set slot
601 *
602 * @param Slot $slot
603 *
604 * @return Session
605 */
606 public function setSlot(Slot $slot): Session {
607 $this->slot = $slot;
608
609 return $this;
610 }
611
612 /**
613 * Get slot
614 *
615 * @return Slot
616 */
617 public function getSlot(): Slot {
618 return $this->slot;
619 }
620
621 /**
622 * Set application
623 *
624 * @param Application $application
625 *
626 * @return Session
627 */
628 public function setApplication(Application $application): Session {
629 $this->application = $application;
630
631 return $this;
632 }
633
634 /**
635 * Get application
636 *
637 * @return Application
638 */
639 public function getApplication(): ?Application {
640 return $this->application;
641 }
642
643 /**
644 * {@inheritdoc}
645 */
646 public function preUpdate(PreUpdateEventArgs $eventArgs) {
647 //Check that we have a session instance
648 if (($session = $eventArgs->getEntity()) instanceof Session) {
649 //Set updated value
650 $session->setUpdated(new \DateTime('now'));
651 }
652 }
653
654 /**
655 * Wether if session is a premium day
656 *
657 * Consider as premium a day off for afternoon, the eve for evening and after
658 * Store computed result in premium member for afternoon and evening
659 *
660 * @return bool Whether the date is day off or not
661 */
662 public function isPremium(): bool {
663 //Without date
664 if (empty($date = $this->date)) {
665 throw new \LogicException('Property date is empty');
666 }
667
668 //Without slot
669 if (empty($slot = $this->slot) || empty($slotTitle = $slot->getTitle())) {
670 throw new \LogicException('Property slot is empty');
671 }
672
673 //With evening and after slot
674 if ($slotTitle == 'Evening' || $slotTitle == 'After') {
675 //Evening and after session is considered premium when the eve is a day off
676 $date = (clone $date)->add(new \DateInterval('P1D'));
677 }
678
679 //Get day number
680 $w = $date->format('w');
681
682 //Check if weekend day
683 if ($w == 0 || $w == 6) {
684 //With afternoon and evening slot
685 if ($slotTitle == 'Afternoon' || $slotTitle == 'Evening') {
686 //Save premium
687 $this->premium = true;
688 }
689
690 //Date is weekend day
691 return true;
692 }
693
694 //Get date day
695 $d = $date->format('d');
696
697 //Get date month
698 $m = $date->format('m');
699
700 //Check if fixed holiday
701 if (
702 //Check if 1st january
703 ($d == 1 && $m == 1) ||
704 //Check if 1st may
705 ($d == 1 && $m == 5) ||
706 //Check if 8st may
707 ($d == 8 && $m == 5) ||
708 //Check if 14st july
709 ($d == 14 && $m == 7) ||
710 //Check if 15st august
711 ($d == 15 && $m == 8) ||
712 //Check if 1st november
713 ($d == 1 && $m == 11) ||
714 //Check if 11st november
715 ($d == 11 && $m == 11) ||
716 //Check if 25st december
717 ($d == 25 && $m == 12)
718 ) {
719 //With afternoon and evening slot
720 if ($slotTitle == 'Afternoon' || $slotTitle == 'Evening') {
721 //Save premium
722 $this->premium = true;
723 }
724
725 //Date is a fixed holiday
726 return true;
727 }
728
729 //Get eastern
730 $eastern = $this->getEastern($date->format('Y'));
731
732 //Check dynamic holidays
733 if (
734 (clone $eastern)->add(new \DateInterval('P1D')) == $date ||
735 (clone $eastern)->add(new \DateInterval('P39D')) == $date ||
736 (clone $eastern)->add(new \DateInterval('P50D')) == $date
737 ) {
738 //With afternoon and evening slot
739 if ($slotTitle == 'Afternoon' || $slotTitle == 'Evening') {
740 //Save premium
741 $this->premium = true;
742 }
743
744 //Date is a dynamic holiday
745 return true;
746 }
747
748 //With afternoon and evening slot
749 if ($slotTitle == 'Afternoon' || $slotTitle == 'Evening') {
750 //Save premium
751 $this->premium = false;
752 }
753
754 //Date is not a holiday and week day
755 return false;
756 }
757
758 /**
759 * Compute eastern for selected year
760 *
761 * @param string $year The eastern year
762 *
763 * @return DateTime The eastern date
764 */
765 private function getEastern(string $year): \DateTime {
766 //Set static
767 static $data = null;
768
769 //Check if already computed
770 if (isset($data[$year])) {
771 //Return computed eastern
772 return $data[$year];
773 //Check if data is null
774 } elseif (is_null($data)) {
775 //Init data array
776 $data = [];
777 }
778
779 $d = (19 * ($year % 19) + 24) % 30;
780
781 $e = (2 * ($year % 4) + 4 * ($year % 7) + 6 * $d + 5) % 7;
782
783 $day = 22 + $d + $e;
784
785 $month = 3;
786
787 if ($day > 31) {
788 $day = $d + $e - 9;
789 $month = 4;
790 } elseif ($d == 29 && $e == 6) {
791 $day = 10;
792 $month = 4;
793 } elseif ($d == 28 && $e == 6) {
794 $day = 18;
795 $month = 4;
796 }
797
798 //Store eastern in data
799 return ($data[$year] = new \DateTime(sprintf('%04d-%02d-%02d', $year, $month, $day)));
800 }
801 }