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