Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
42 / 42
100.00% covered (success)
100.00%
11 / 11
CRAP
100.00% covered (success)
100.00%
1 / 1
Day
100.00% covered (success)
100.00%
42 / 42
100.00% covered (success)
100.00%
11 / 11
20
100.00% covered (success)
100.00%
1 / 1
 getDefaults
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
1
 __toString
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 setDateTime
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 toDateTime
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 hasAppointmentsByType
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 isBookable
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasAppointments
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
 getWithStatus
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
6
 withAddedDay
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 getDayHash
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getCalculatedDayHash
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace BO\Zmsentities;
4
5class Day extends Schema\Entity
6{
7    const PRIMARY = 'day';
8
9    const FULL = 'full';
10
11    const BOOKABLE = 'bookable';
12
13    const NOTBOOKABLE = 'notBookable';
14
15    const RESTRICTED = 'restricted';
16
17    const DETAIL = 'detail';
18
19    public static $schema = "day.json";
20
21    public function getDefaults()
22    {
23        return [
24            'year' => '',
25            'month' => '',
26            'day' => '',
27            'status' => self::NOTBOOKABLE,
28            'freeAppointments' => new Slot(),
29            'allAppointments' => new Slot()
30        ];
31    }
32
33    //@todo freeAppointments could be an array, should be slot entity
34    public function __toString()
35    {
36        $this->freeAppointments = new Slot($this->freeAppointments);
37        return "Day {$this->status}@{$this->year}-{$this->month}-{$this->day} with " . $this->freeAppointments;
38    }
39
40    public function setDateTime(\DateTimeInterface $dateTime)
41    {
42        $this['year'] = $dateTime->format('Y');
43        $this['month'] = $dateTime->format('m');
44        $this['day'] = $dateTime->format('d');
45        return $this;
46    }
47
48    public function toDateTime()
49    {
50        $date = Helper\DateTime::createFromFormat('Y-m-d', $this['year'] . '-' . $this['month'] . '-' . $this['day']);
51        return Helper\DateTime::create($date);
52    }
53
54    /**
55     * @return bool TRUE or FALSE if one or more appointments, if no appointments for $slotType were defined, than NULL
56     */
57    public function hasAppointmentsByType($slotType)
58    {
59        $freeAppointmentCount = $this->toProperty()->freeAppointments->{$slotType}->get();
60        $allAppointmentCount = $this->toProperty()->allAppointments->{$slotType}->get();
61        if (null !== $allAppointmentCount && $allAppointmentCount <= 0) {
62            return null;
63        }
64        return (0 < $freeAppointmentCount);
65    }
66
67    public function isBookable()
68    {
69        return ($this->status == self::BOOKABLE);
70    }
71
72    public function hasAppointments()
73    {
74        return ($this->status == self::BOOKABLE || $this->status == self::FULL);
75    }
76
77    /**
78     * Check if day is bookable
79     * The return self or status
80     *
81     * @return \ArrayObject or String
82     */
83    public function getWithStatus($slotType, \DateTimeInterface $now)
84    {
85        $hasAppointments = $this->hasAppointmentsByType($slotType);
86        if ($this->status != self::RESTRICTED && $hasAppointments !== null) {
87            $this->status = ($hasAppointments) ? self::BOOKABLE : self::FULL;
88        } elseif (null === $hasAppointments) {
89            $this->status = self::NOTBOOKABLE;
90        }
91        // if dayend < todays time + half an hour, it is restricted
92        if ($this->toDateTime()->getTimestamp() + 86400 <= $now->getTimestamp() + 1800) {
93            $this->status =  self::RESTRICTED;
94        }
95        return $this;
96    }
97
98    public function withAddedDay(Day $day)
99    {
100        $merged = clone $this;
101        if (!$merged->freeAppointments instanceof Slot) {
102            $merged->freeAppointments = new Slot($merged->freeAppointments);
103        }
104        $merged->freeAppointments = $merged->freeAppointments->withAddedSlot($day->freeAppointments);
105        return $merged;
106    }
107
108    /**
109     * Returns an unique string hash per day optimized for b-trees
110     */
111    public function getDayHash()
112    {
113        return $this::getCalculatedDayHash($this->day, $this->month, $this->year);
114    }
115
116    public static function getCalculatedDayHash($dayNumber, $month, $year)
117    {
118        $dateHash = str_pad($dayNumber, 2, '0', STR_PAD_LEFT)
119            . "-"
120            . str_pad($month, 2, '0', STR_PAD_LEFT)
121            . "-$year";
122        return $dateHash;
123    }
124}