PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / trunk
Booking for Appointments and Events Calendar – Amelia vtrunk
2.4.4 2.4.3 2.4.2 2.4.1 2.4 trunk 1.2.1 1.2.10 1.2.11 1.2.12 1.2.13 1.2.14 1.2.15 1.2.16 1.2.17 1.2.18 1.2.19 1.2.2 1.2.20 1.2.21 1.2.22 1.2.23 1.2.24 1.2.25 1.2.26 1.2.27 1.2.28 1.2.29 1.2.3 1.2.30 1.2.31 1.2.32 1.2.33 1.2.34 1.2.35 1.2.36 1.2.37 1.2.38 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 2.0 2.0.1 2.0.2 2.1 2.1.1 2.1.2 2.1.3 2.2 2.2.1 2.3
ameliabooking / src / Domain / Services / Booking / AppointmentDomainService.php
ameliabooking / src / Domain / Services / Booking Last commit date
AppointmentDomainService.php 6 months ago EventDomainService.php 6 months ago
AppointmentDomainService.php
205 lines
1 <?php
2
3 namespace AmeliaBooking\Domain\Services\Booking;
4
5 use AmeliaBooking\Domain\Collection\Collection;
6 use AmeliaBooking\Domain\Common\Exceptions\InvalidArgumentException;
7 use AmeliaBooking\Domain\Entity\Bookable\Service\Service;
8 use AmeliaBooking\Domain\Entity\Booking\Appointment\Appointment;
9 use AmeliaBooking\Domain\Entity\Booking\Appointment\CustomerBooking;
10 use AmeliaBooking\Domain\Services\DateTime\DateTimeService;
11 use AmeliaBooking\Domain\ValueObjects\DateTime\DateTimeValue;
12 use AmeliaBooking\Domain\ValueObjects\String\BookingStatus;
13
14 /**
15 * Class AppointmentDomainService
16 *
17 * @package AmeliaBooking\Domain\Services\Booking
18 */
19 class AppointmentDomainService
20 {
21 /**
22 * Returns an array with bookings statuses count for passed appointment
23 *
24 * @param Appointment $appointment
25 *
26 * @return array
27 * @throws InvalidArgumentException
28 */
29 public function getBookingsStatusesCount($appointment)
30 {
31 $approvedBookings = 0;
32 $pendingBookings = 0;
33 $canceledBookings = 0;
34 $rejectedBookings = 0;
35 $noShowBookings = 0;
36 $waitingBookings = 0;
37
38 foreach ((array)$appointment->getBookings()->keys() as $customerBookingKey) {
39 /** @var CustomerBooking $booking */
40 $booking = $appointment->getBookings()->getItem($customerBookingKey);
41
42 switch ($booking->getStatus()->getValue()) {
43 case BookingStatus::PENDING:
44 $pendingBookings += $booking->getPersons()->getValue();
45 break;
46 case BookingStatus::CANCELED:
47 $canceledBookings += $booking->getPersons()->getValue();
48 break;
49 case BookingStatus::REJECTED:
50 $rejectedBookings += $booking->getPersons()->getValue();
51 break;
52 case BookingStatus::NO_SHOW:
53 $noShowBookings += $booking->getPersons()->getValue();
54 break;
55 case BookingStatus::WAITING:
56 $waitingBookings += $booking->getPersons()->getValue();
57 break;
58 default:
59 $approvedBookings += $booking->getPersons()->getValue();
60 break;
61 }
62 }
63
64 return [
65 'approvedBookings' => $approvedBookings,
66 'pendingBookings' => $pendingBookings,
67 'canceledBookings' => $canceledBookings,
68 'rejectedBookings' => $rejectedBookings,
69 'noShowBookings' => $noShowBookings,
70 'waitingBookings' => $waitingBookings
71 ];
72 }
73
74 /**
75 * @param Service $service
76 * @param array $bookingsCount
77 *
78 * @return string
79 */
80 public function getAppointmentStatusWhenEditAppointment($service, $bookingsCount)
81 {
82 $totalBookings = array_sum($bookingsCount);
83
84 if ($bookingsCount['canceledBookings'] === $totalBookings) {
85 return BookingStatus::CANCELED;
86 }
87
88 if ($bookingsCount['noShowBookings'] === $totalBookings) {
89 return BookingStatus::NO_SHOW;
90 }
91
92 if ($bookingsCount['waitingBookings'] === $totalBookings) {
93 return BookingStatus::PENDING;
94 }
95
96 if ($bookingsCount['rejectedBookings'] === $totalBookings) {
97 return BookingStatus::REJECTED;
98 }
99
100 if ($bookingsCount['approvedBookings'] === 0 && $bookingsCount['pendingBookings'] === 0) {
101 return BookingStatus::CANCELED;
102 }
103
104 return $bookingsCount['approvedBookings'] >= $service->getMinCapacity()->getValue() ?
105 BookingStatus::APPROVED : BookingStatus::PENDING;
106 }
107
108 /**
109 * When booking status is changed, find out appointment status.
110 *
111 * If there is no any more 'approved' and 'pending' bookings, set appointment status to 'canceled' or 'rejected'.
112 *
113 * If appointment status is 'approved' or 'pending' and minimum capacity condition is not satisfied,
114 * set appointment status to 'pending'.
115 *
116 * @param Service $service
117 * @param array $bookingsCount
118 * @param string $requestedStatus
119 *
120 * @return string
121 */
122 public function getAppointmentStatusWhenChangingBookingStatus($service, $bookingsCount, $requestedStatus)
123 {
124 if ($bookingsCount['approvedBookings'] === 0 && $bookingsCount['pendingBookings'] === 0) {
125 return $requestedStatus === BookingStatus::WAITING ? BookingStatus::PENDING : $requestedStatus;
126 }
127
128 return $bookingsCount['approvedBookings'] >= $service->getMinCapacity()->getValue() ?
129 BookingStatus::APPROVED : BookingStatus::PENDING;
130 }
131
132 /**
133 * sort and merge appointments by date-time
134 *
135 * @param Collection $appointments
136 *
137 * @return Collection
138 * @throws InvalidArgumentException
139 */
140 public function getSortedAndMergedAppointments($appointments)
141 {
142 $timeStampsData = [];
143
144 /** @var Appointment $appointment */
145 foreach ($appointments->getItems() as $index => $appointment) {
146 $timeStampStart = $appointment->getBookingStart()->getValue()->getTimestamp();
147
148 $timeStampEnd = $appointment->getBookingEnd()->getValue()->getTimestamp();
149
150 if (!isset($timeStampsData[$timeStampStart])) {
151 $timeStampsData[$timeStampStart] = [$timeStampEnd, $index];
152 } else {
153 /** @var Appointment $passedAppointment */
154 $passedAppointment = $appointments->getItem($timeStampsData[$timeStampStart][1]);
155
156 if ($appointment->getBookingEnd()->getValue() > $passedAppointment->getBookingEnd()->getValue()) {
157 $timeStampsData[$timeStampStart] = [$timeStampEnd, $index];
158 }
159 }
160 }
161
162 ksort($timeStampsData);
163
164 $mergedTimeStampsData = [];
165
166 $previousInterval = null;
167
168 foreach ($timeStampsData as $start => $currentInterval) {
169 if ($previousInterval !== null && $start <= $previousInterval[1]) {
170 if ($currentInterval[0] > $previousInterval[1]) {
171 $mergedTimeStampsData[$previousInterval[0]][0] = $currentInterval[0];
172 }
173 } else {
174 $mergedTimeStampsData[$start] = $currentInterval;
175
176 $previousInterval = [
177 $start,
178 $currentInterval[0],
179 $currentInterval[1]
180 ];
181 }
182 }
183
184 /** @var Collection $sortedAndMergedAppointments */
185 $sortedAndMergedAppointments = new Collection();
186
187 foreach ($mergedTimeStampsData as $start => $interval) {
188 /** @var Appointment $appointment */
189 $appointment = $appointments->getItem($interval[1]);
190
191 $appointment->setBookingStart(
192 new DateTimeValue(DateTimeService::getNowDateTimeObject()->setTimestamp($start))
193 );
194
195 $appointment->setBookingEnd(
196 new DateTimeValue(DateTimeService::getNowDateTimeObject()->setTimestamp($interval[0]))
197 );
198
199 $sortedAndMergedAppointments->addItem($appointment);
200 }
201
202 return $sortedAndMergedAppointments;
203 }
204 }
205