]> Raphaël G. Git Repositories - airbundle/blob - Entity/Session.php
Rename rapsysair:calendar2 command to rapsysair:calendar
[airbundle] / Entity / Session.php
1 <?php declare(strict_types=1);
2
3 /*
4 * This file is part of the Rapsys AirBundle 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 * Create 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
127 //Set collections
128 $this->applications = new ArrayCollection();
129 }
130
131 /**
132 * Get id
133 *
134 * @return integer
135 */
136 public function getId(): ?int {
137 return $this->id;
138 }
139
140 /**
141 * Set date
142 *
143 * @param \DateTime $date
144 *
145 * @return Session
146 */
147 public function setDate(\DateTime $date): Session {
148 $this->date = $date;
149
150 return $this;
151 }
152
153 /**
154 * Get date
155 *
156 * @return \DateTime
157 */
158 public function getDate(): \DateTime {
159 return $this->date;
160 }
161
162 /**
163 * Set begin
164 *
165 * @param \DateTime $begin
166 *
167 * @return Session
168 */
169 public function setBegin(?\DateTime $begin): Session {
170 $this->begin = $begin;
171
172 return $this;
173 }
174
175 /**
176 * Get begin
177 *
178 * @return \DateTime
179 */
180 public function getBegin(): ?\DateTime {
181 return $this->begin;
182 }
183
184 /**
185 * Get start
186 *
187 * @return \DateTime
188 */
189 public function getStart(): \DateTime {
190 //With start
191 if ($this->start !== null) {
192 return $this->start;
193 }
194
195 //Clone date
196 $this->start = clone $this->date;
197
198 //Check if after slot
199 //XXX: id=4 <=> title=After
200 if ($this->slot->getId() == 4) {
201 //Add one day
202 $this->start->add(new \DateInterval('P1D'));
203 }
204
205 //With begin
206 if ($this->begin !== null) {
207 //Set start time
208 $this->start->setTime(intval($this->begin->format('H')), intval($this->begin->format('i')), intval($this->begin->format('s')));
209 }
210
211 //Return start
212 return $this->start;
213 }
214
215 /**
216 * Set length
217 *
218 * @param \DateTime $length
219 *
220 * @return Session
221 */
222 public function setLength(?\DateTime $length): Session {
223 $this->length = $length;
224
225 return $this;
226 }
227
228 /**
229 * Get length
230 *
231 * @return \DateTime
232 */
233 public function getLength(): ?\DateTime {
234 return $this->length;
235 }
236
237 /**
238 * Get stop
239 *
240 * @return \DateTime
241 */
242 public function getStop(): \DateTime {
243 //Check start
244 if ($this->stop !== null) {
245 return $this->stop;
246 }
247
248 //Get start clone
249 $this->stop = clone $this->getStart();
250
251 //With length
252 if ($this->length !== null) {
253 //Set stop time
254 $this->stop->add(new \DateInterval('PT'.$this->length->format('H').'H'.$this->length->format('i').'M'.$this->length->format('s').'S'));
255 }
256
257 //Return date
258 return $this->stop;
259 }
260
261 /**
262 * Set premium
263 *
264 * @param bool $premium
265 *
266 * @return Session
267 */
268 public function setPremium(?bool $premium): Session {
269 $this->premium = $premium;
270
271 return $this;
272 }
273
274 /**
275 * Get premium
276 *
277 * @return bool
278 */
279 public function getPremium(): ?bool {
280 return $this->premium;
281 }
282
283 /**
284 * Set rainfall
285 *
286 * @param float $rainfall
287 *
288 * @return Session
289 */
290 public function setRainfall(?float $rainfall): Session {
291 $this->rainfall = $rainfall;
292
293 return $this;
294 }
295
296 /**
297 * Get rainfall
298 *
299 * @return float
300 */
301 public function getRainfall(): ?float {
302 return $this->rainfall;
303 }
304
305 /**
306 * Set rainrisk
307 *
308 * @param float $rainrisk
309 *
310 * @return Session
311 */
312 public function setRainrisk(?float $rainrisk): Session {
313 $this->rainrisk = $rainrisk;
314
315 return $this;
316 }
317
318 /**
319 * Get rainrisk
320 *
321 * @return float
322 */
323 public function getRainrisk(): ?float {
324 return $this->rainrisk;
325 }
326
327 /**
328 * Set realfeel
329 *
330 * @param float $realfeel
331 *
332 * @return Session
333 */
334 public function setRealfeel(?float $realfeel): Session {
335 $this->realfeel = $realfeel;
336
337 return $this;
338 }
339
340 /**
341 * Get realfeel
342 *
343 * @return float
344 */
345 public function getRealfeel(): ?float {
346 return $this->realfeel;
347 }
348
349 /**
350 * Set realfeelmin
351 *
352 * @param float $realfeelmin
353 *
354 * @return Session
355 */
356 public function setRealfeelmin(?float $realfeelmin): Session {
357 $this->realfeelmin = $realfeelmin;
358
359 return $this;
360 }
361
362 /**
363 * Get realfeelmin
364 *
365 * @return float
366 */
367 public function getRealfeelmin(): ?float {
368 return $this->realfeelmin;
369 }
370
371 /**
372 * Set realfeelmax
373 *
374 * @param float $realfeelmax
375 *
376 * @return Session
377 */
378 public function setRealfeelmax(?float $realfeelmax): Session {
379 $this->realfeelmax = $realfeelmax;
380
381 return $this;
382 }
383
384 /**
385 * Get realfeelmax
386 *
387 * @return float
388 */
389 public function getRealfeelmax(): ?float {
390 return $this->realfeelmax;
391 }
392
393 /**
394 * Set temperature
395 *
396 * @param float $temperature
397 *
398 * @return Session
399 */
400 public function setTemperature(?float $temperature): Session {
401 $this->temperature = $temperature;
402
403 return $this;
404 }
405
406 /**
407 * Get temperature
408 *
409 * @return float
410 */
411 public function getTemperature(): ?float {
412 return $this->temperature;
413 }
414
415 /**
416 * Set temperaturemin
417 *
418 * @param float $temperaturemin
419 *
420 * @return Session
421 */
422 public function setTemperaturemin(?float $temperaturemin): Session {
423 $this->temperaturemin = $temperaturemin;
424
425 return $this;
426 }
427
428 /**
429 * Get temperaturemin
430 *
431 * @return float
432 */
433 public function getTemperaturemin(): ?float {
434 return $this->temperaturemin;
435 }
436
437 /**
438 * Set temperaturemax
439 *
440 * @param float $temperaturemax
441 *
442 * @return Session
443 */
444 public function setTemperaturemax(?float $temperaturemax): Session {
445 $this->temperaturemax = $temperaturemax;
446
447 return $this;
448 }
449
450 /**
451 * Get temperaturemax
452 *
453 * @return float
454 */
455 public function getTemperaturemax(): ?float {
456 return $this->temperaturemax;
457 }
458
459 /**
460 * Set locked
461 *
462 * @param \DateTime $locked
463 *
464 * @return Session
465 */
466 public function setLocked(?\DateTime $locked): Session {
467 $this->locked = $locked;
468
469 return $this;
470 }
471
472 /**
473 * Get locked
474 *
475 * @return \DateTime
476 */
477 public function getLocked(): ?\DateTime {
478 return $this->locked;
479 }
480
481 /**
482 * Set created
483 *
484 * @param \DateTime $created
485 *
486 * @return Session
487 */
488 public function setCreated(\DateTime $created): Session {
489 $this->created = $created;
490
491 return $this;
492 }
493
494 /**
495 * Get created
496 *
497 * @return \DateTime
498 */
499 public function getCreated(): \DateTime {
500 return $this->created;
501 }
502
503 /**
504 * Set updated
505 *
506 * @param \DateTime $updated
507 *
508 * @return Session
509 */
510 public function setUpdated(\DateTime $updated): Session {
511 $this->updated = $updated;
512
513 return $this;
514 }
515
516 /**
517 * Get updated
518 *
519 * @return \DateTime
520 */
521 public function getUpdated(): \DateTime {
522 return $this->updated;
523 }
524
525 /**
526 * Add application
527 *
528 * @param Application $application
529 *
530 * @return Session
531 */
532 public function addApplication(Application $application): Session {
533 $this->applications[] = $application;
534
535 return $this;
536 }
537
538 /**
539 * Remove application
540 *
541 * @param Application $application
542 */
543 public function removeApplication(Application $application): bool {
544 return $this->applications->removeElement($application);
545 }
546
547 /**
548 * Get applications
549 *
550 * @return ArrayCollection
551 */
552 public function getApplications(): ArrayCollection {
553 return $this->applications;
554 }
555
556 /**
557 * Set location
558 *
559 * @param Location $location
560 *
561 * @return Session
562 */
563 public function setLocation(Location $location): Session {
564 $this->location = $location;
565
566 return $this;
567 }
568
569 /**
570 * Get location
571 *
572 * @return Location
573 */
574 public function getLocation(): Location {
575 return $this->location;
576 }
577
578 /**
579 * Set slot
580 *
581 * @param Slot $slot
582 *
583 * @return Session
584 */
585 public function setSlot(Slot $slot): Session {
586 $this->slot = $slot;
587
588 return $this;
589 }
590
591 /**
592 * Get slot
593 *
594 * @return Slot
595 */
596 public function getSlot(): Slot {
597 return $this->slot;
598 }
599
600 /**
601 * Set application
602 *
603 * @param Application $application
604 *
605 * @return Session
606 */
607 public function setApplication(?Application $application): Session {
608 $this->application = $application;
609
610 return $this;
611 }
612
613 /**
614 * Get application
615 *
616 * @return Application
617 */
618 public function getApplication(): ?Application {
619 return $this->application;
620 }
621
622 /**
623 * {@inheritdoc}
624 */
625 public function preUpdate(PreUpdateEventArgs $eventArgs) {
626 //Check that we have a session instance
627 if (($session = $eventArgs->getObject()) instanceof Session) {
628 //Set updated value
629 $session->setUpdated(new \DateTime('now'));
630 }
631 }
632
633 /**
634 * Wether if session is a premium day
635 *
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
638 *
639 * @TODO improve by moving day off computation in IntlUtil or HolidayUtil class ?
640 *
641 * @return bool Whether the date is day off or not
642 */
643 public function isPremium(): bool {
644 //Without date
645 if (empty($date = $this->date)) {
646 throw new \LogicException('Property date is empty');
647 }
648
649 //Without slot
650 if (empty($slot = $this->slot) || empty($slotTitle = $slot->getTitle())) {
651 throw new \LogicException('Property slot is empty');
652 }
653
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'));
658 }
659
660 //Get day number
661 $w = $date->format('w');
662
663 //Check if weekend day
664 if ($w == 0 || $w == 6) {
665 //With afternoon and evening slot
666 if ($slotTitle == 'Afternoon' || $slotTitle == 'Evening') {
667 //Save premium
668 $this->premium = true;
669 }
670
671 //Date is weekend day
672 return true;
673 }
674
675 //Get date day
676 $d = $date->format('d');
677
678 //Get date month
679 $m = $date->format('m');
680
681 //Check if fixed holiday
682 if (
683 //Check if 1st january
684 ($d == 1 && $m == 1) ||
685 //Check if 1st may
686 ($d == 1 && $m == 5) ||
687 //Check if 8st may
688 ($d == 8 && $m == 5) ||
689 //Check if 14st july
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)
699 ) {
700 //With afternoon and evening slot
701 if ($slotTitle == 'Afternoon' || $slotTitle == 'Evening') {
702 //Save premium
703 $this->premium = true;
704 }
705
706 //Date is a fixed holiday
707 return true;
708 }
709
710 //Get eastern
711 $eastern = (new IntlUtil())->getEastern($date->format('Y'));
712
713 //Check dynamic holidays
714 if (
715 (clone $eastern)->add(new \DateInterval('P1D')) == $date ||
716 (clone $eastern)->add(new \DateInterval('P39D')) == $date ||
717 (clone $eastern)->add(new \DateInterval('P50D')) == $date
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 dynamic holiday
726 return true;
727 }
728
729 //With afternoon and evening slot
730 if ($slotTitle == 'Afternoon' || $slotTitle == 'Evening') {
731 //Save premium
732 $this->premium = false;
733 }
734
735 //Date is not a holiday and week day
736 return false;
737 }
738 }