PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 1.2.20
Booking for Appointments and Events Calendar – Amelia v1.2.20
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 / Application / Commands / Booking / Event / GetEventsCommandHandler.php
ameliabooking / src / Application / Commands / Booking / Event Last commit date
AddEventCommand.php 7 years ago AddEventCommandHandler.php 2 years ago DeleteEventBookingCommand.php 7 years ago DeleteEventBookingCommandHandler.php 1 year ago DeleteEventCommand.php 7 years ago DeleteEventCommandHandler.php 2 years ago GetCalendarEventsCommand.php 4 years ago GetCalendarEventsCommandHandler.php 1 year ago GetEventBookingsCommand.php 1 year ago GetEventBookingsCommandHandler.php 1 year ago GetEventCommand.php 7 years ago GetEventCommandHandler.php 1 year ago GetEventDeleteEffectCommand.php 7 years ago GetEventDeleteEffectCommandHandler.php 2 years ago GetEventsCommand.php 7 years ago GetEventsCommandHandler.php 1 year ago UpdateEventBookingCommand.php 7 years ago UpdateEventBookingCommandHandler.php 1 year ago UpdateEventCommand.php 7 years ago UpdateEventCommandHandler.php 1 year ago UpdateEventStatusCommand.php 7 years ago UpdateEventStatusCommandHandler.php 2 years ago
GetEventsCommandHandler.php
348 lines
1 <?php
2
3 namespace AmeliaBooking\Application\Commands\Booking\Event;
4
5 use AmeliaBooking\Application\Commands\CommandHandler;
6 use AmeliaBooking\Application\Commands\CommandResult;
7 use AmeliaBooking\Application\Common\Exceptions\AccessDeniedException;
8 use AmeliaBooking\Application\Services\Booking\EventApplicationService;
9 use AmeliaBooking\Application\Services\Reservation\EventReservationService;
10 use AmeliaBooking\Application\Services\User\UserApplicationService;
11 use AmeliaBooking\Domain\Collection\Collection;
12 use AmeliaBooking\Domain\Common\Exceptions\AuthorizationException;
13 use AmeliaBooking\Domain\Common\Exceptions\InvalidArgumentException;
14 use AmeliaBooking\Domain\Entity\Booking\Appointment\CustomerBooking;
15 use AmeliaBooking\Domain\Entity\Booking\Event\CustomerBookingEventTicket;
16 use AmeliaBooking\Domain\Entity\Booking\Event\Event;
17 use AmeliaBooking\Domain\Entity\Booking\Event\EventPeriod;
18 use AmeliaBooking\Domain\Entity\Booking\Event\EventTicket;
19 use AmeliaBooking\Domain\Entity\Entities;
20 use AmeliaBooking\Domain\Entity\User\AbstractUser;
21 use AmeliaBooking\Domain\Factory\Booking\Event\EventPeriodFactory;
22 use AmeliaBooking\Domain\Services\DateTime\DateTimeService;
23 use AmeliaBooking\Domain\Services\Settings\SettingsService;
24 use AmeliaBooking\Domain\ValueObjects\Number\Integer\IntegerValue;
25 use AmeliaBooking\Domain\ValueObjects\String\BookingStatus;
26 use AmeliaBooking\Infrastructure\Common\Exceptions\QueryExecutionException;
27 use AmeliaBooking\Infrastructure\Repository\Booking\Appointment\CustomerBookingRepository;
28 use AmeliaBooking\Infrastructure\Repository\Booking\Event\EventRepository;
29 use DateTimeZone;
30 use Exception;
31
32 /**
33 * Class GetEventsCommandHandler
34 *
35 * @package AmeliaBooking\Application\Commands\Booking\Event
36 */
37 class GetEventsCommandHandler extends CommandHandler
38 {
39 /**
40 * @param GetEventsCommand $command
41 *
42 * @return CommandResult
43 *
44 * @throws AccessDeniedException
45 * @throws InvalidArgumentException
46 * @throws QueryExecutionException
47 * @throws Exception
48 */
49 public function handle(GetEventsCommand $command)
50 {
51 $result = new CommandResult();
52
53 /** @var SettingsService $settingsDS */
54 $settingsDS = $this->container->get('domain.settings.service');
55 /** @var EventReservationService $reservationService */
56 $reservationService = $this->container->get('application.reservation.service')->get(Entities::EVENT);
57 /** @var EventRepository $eventRepository */
58 $eventRepository = $this->container->get('domain.booking.event.repository');
59 /** @var UserApplicationService $userAS */
60 $userAS = $this->container->get('application.user.service');
61 /** @var EventApplicationService $eventAS */
62 $eventAS = $this->container->get('application.booking.event.service');
63
64 $params = $command->getField('params');
65
66 /** @var AbstractUser $user */
67 $user = null;
68
69 $isFrontEnd = isset($params['page']) && empty($params['group']);
70
71 $isCalendarPage = $isFrontEnd && (int)$params['page'] === 0;
72
73 $isCabinetPage = $command->getPage() === 'cabinet';
74
75 if (!$isFrontEnd) {
76 try {
77 /** @var AbstractUser $user */
78 $user = $command->getUserApplicationService()->authorization(
79 $isCabinetPage ? $command->getToken() : null,
80 $command->getCabinetType()
81 );
82 } catch (AuthorizationException $e) {
83 $result->setResult(CommandResult::RESULT_ERROR);
84 $result->setData(
85 [
86 'reauthorize' => true
87 ]
88 );
89
90 return $result;
91 }
92
93 if ($userAS->isAmeliaUser($user) && $userAS->isCustomer($user)) {
94 $params['customerId'] = $user->getId()->getValue();
95 }
96
97 if ($user && $user->getType() === AbstractUser::USER_ROLE_PROVIDER) {
98 $params['providers'] = [$user->getId()->getValue()];
99 }
100 }
101
102 if ($isFrontEnd && !empty($params['providers'])) {
103 $params['providers'] = array_values($params['providers']);
104 }
105
106 if (isset($params['dates'][0])) {
107 $params['dates'][0] ? $params['dates'][0] .= ' 00:00:00' : null;
108 }
109
110 if (isset($params['dates'][1])) {
111 $params['dates'][1] ? $params['dates'][1] .= ' 23:59:59' : null;
112 }
113
114 if ($isFrontEnd) {
115 $params['show'] = 1;
116
117 if (!empty($params['tag'])) {
118 $params['tag'] = str_replace('___', ' ', $params['tag']);
119 }
120 }
121
122 /** @var Collection $events */
123 $events = $eventAS->getEventsByCriteria(
124 $params,
125 [
126 'fetchEventsPeriods' => true,
127 'fetchEventsTickets' => true,
128 'fetchEventsTags' => $isFrontEnd,
129 'fetchEventsProviders' => ($isFrontEnd || $command->getPage() === 'calendar'),
130 'fetchEventsImages' => $isFrontEnd,
131 'fetchBookings' => true,
132 'fetchBookingsTickets' => true,
133 'fetchBookingsCoupons' => $isCabinetPage,
134 'fetchBookingsPayments' => $isCabinetPage,
135 'fetchBookingsUsers' => $isCabinetPage,
136 ],
137 $isFrontEnd
138 ? (!empty($params['limit']) ? $params['limit'] : $settingsDS->getSetting('general', 'itemsPerPage'))
139 : $settingsDS->getSetting('general', 'itemsPerPageBackEnd')
140 );
141
142 $currentDateTime = DateTimeService::getNowDateTimeObject();
143
144 $eventsArray = [];
145
146 $customersNoShowCountIds = [];
147
148 $noShowTagEnabled = $settingsDS->getSetting('roles', 'enableNoShowTag');
149
150 /** @var Event $event */
151 foreach ($events->getItems() as $event) {
152 if ($isFrontEnd && !$event->getShow()->getValue()) {
153 continue;
154 }
155
156 $persons = 0;
157
158 if ($event->getCustomPricing()->getValue()) {
159 /** @var CustomerBooking $booking */
160 foreach ($event->getBookings()->getItems() as $booking) {
161 /** @var CustomerBookingEventTicket $bookedTicket */
162 foreach ($booking->getTicketsBooking()->getItems() as $bookedTicket) {
163 /** @var EventTicket $ticket */
164 $ticket = $event->getCustomTickets()->getItem($bookedTicket->getEventTicketId()->getValue());
165
166 $ticket->setSold(
167 new IntegerValue(
168 ($ticket->getSold() ? $ticket->getSold()->getValue() : 0) +
169 ($booking->getStatus()->getValue() === BookingStatus::APPROVED || $booking->getStatus()->getValue() === BookingStatus::PENDING ?
170 $bookedTicket->getPersons()->getValue() : 0)
171 )
172 );
173
174 $ticket->setWaiting(
175 new IntegerValue(
176 ($ticket->getWaiting() ? $ticket->getWaiting()->getValue() : 0) +
177 ($booking->getStatus()->getValue() === BookingStatus::WAITING ?
178 $bookedTicket->getPersons()->getValue() : 0)
179 )
180 );
181 }
182
183 if ($noShowTagEnabled) {
184 $customersNoShowCountIds[] = $booking->getCustomerId()->getValue();
185 }
186 }
187
188 $maxCapacity = 0;
189
190 $event->setCustomTickets($eventAS->getTicketsPriceByDateRange($event->getCustomTickets()));
191
192 /** @var EventTicket $ticket */
193 foreach ($event->getCustomTickets()->getItems() as $ticket) {
194 $maxCapacity += $ticket->getSpots()->getValue();
195
196 $persons += ($ticket->getSold() ? $ticket->getSold()->getValue() : 0);
197 }
198
199 $event->setMaxCapacity($event->getMaxCustomCapacity() ?: new IntegerValue($maxCapacity));
200 } else {
201 /** @var CustomerBooking $booking */
202 foreach ($event->getBookings()->getItems() as $booking) {
203 if ($booking->getStatus()->getValue() === BookingStatus::APPROVED || $booking->getStatus()->getValue() === BookingStatus::PENDING) {
204 $persons += $booking->getPersons()->getValue();
205 }
206
207 if ($noShowTagEnabled) {
208 $customersNoShowCountIds[] = $booking->getCustomerId()->getValue();
209 }
210 }
211 }
212
213 if (($isFrontEnd && $settingsDS->getSetting('general', 'showClientTimeZone')) ||
214 $isCabinetPage || ($user && $user->getType() === AbstractUser::USER_ROLE_PROVIDER)
215 ) {
216 $timeZone = 'UTC';
217
218 if (!empty($params['timeZone'])) {
219 $timeZone = $params['timeZone'];
220 } elseif ($user && $user->getType() === AbstractUser::USER_ROLE_PROVIDER &&
221 empty($user->getTimeZone()) && !empty(get_option('timezone_string'))) {
222 $timeZone = get_option('timezone_string');
223 }
224
225 /** @var EventPeriod $period */
226 foreach ($event->getPeriods()->getItems() as $period) {
227 $period->getPeriodStart()->getValue()->setTimezone(new DateTimeZone($timeZone));
228 $period->getPeriodEnd()->getValue()->setTimezone(new DateTimeZone($timeZone));
229 }
230 }
231
232 $bookingOpens = $event->getBookingOpens() ?
233 $event->getBookingOpens()->getValue() : $event->getCreated()->getValue();
234
235 $bookingCloses = $event->getBookingCloses() ?
236 $event->getBookingCloses()->getValue() : $event->getPeriods()->getItem(0)->getPeriodStart()->getValue();
237
238 $minimumCancelTimeInSeconds = $settingsDS
239 ->getEntitySettings($event->getSettings())
240 ->getGeneralSettings()
241 ->getMinimumTimeRequirementPriorToCanceling();
242
243 $minimumCancelTime = DateTimeService::getCustomDateTimeObject(
244 $event->getPeriods()->getItem(0)->getPeriodStart()->getValue()->format('Y-m-d H:i:s')
245 )->modify("-{$minimumCancelTimeInSeconds} seconds");
246
247 $minimumReached = null;
248 if ($event->getCloseAfterMin() !== null && $event->getCloseAfterMinBookings() !== null) {
249 if ($event->getCloseAfterMinBookings()->getValue()) {
250 $approvedBookings = array_filter(
251 $event->getBookings()->toArray(),
252 function ($value) {
253 return $value['status'] === 'approved';
254 }
255 );
256 $minimumReached = count($approvedBookings) >= $event->getCloseAfterMin()->getValue();
257 } else {
258 $minimumReached = $persons >= $event->getCloseAfterMin()->getValue();
259 }
260 }
261
262 $peopleWaiting = false;
263 $eventSettings = $event->getSettings() ? json_decode($event->getSettings()->getValue(), true) : null;
264
265 if ($eventSettings && !empty($eventSettings['waitingList']) && $eventSettings['waitingList']['enabled']) {
266 foreach ($event->getBookings()->getItems() as $booking) {
267 if ($booking->getStatus()->getValue() === BookingStatus::WAITING) {
268 $peopleWaiting = true;
269 break;
270 }
271 }
272 }
273
274 $eventsInfo = [
275 'bookable' => $reservationService->isBookable($event, null, $currentDateTime) && !$minimumReached,
276 'cancelable' => $currentDateTime <= $minimumCancelTime && ($event->getStatus()->getValue() === BookingStatus::APPROVED || $event->getStatus()->getValue() === BookingStatus::PENDING),
277 'opened' => ($currentDateTime > $bookingOpens) && ($currentDateTime < $bookingCloses),
278 'closed' => $currentDateTime > $bookingCloses || $minimumReached,
279 'places' => $event->getMaxCapacity()->getValue() - $persons,
280 'upcoming' => $currentDateTime < $bookingOpens && $event->getStatus()->getValue() === BookingStatus::APPROVED,
281 'full' => ($event->getMaxCapacity()->getValue() <= $persons
282 && $currentDateTime < $event->getPeriods()->getItem(0)->getPeriodStart()->getValue())
283 || ($peopleWaiting && !($currentDateTime > $bookingCloses || $minimumReached))
284 ];
285
286 if ($isFrontEnd) {
287 $event->setBookings(new Collection());
288
289 /** @var EventPeriod $eventPeriod */
290 foreach ($event->getPeriods()->getItems() as $key => $eventPeriod) {
291 /** @var EventPeriod $newEventPeriod **/
292 $newEventPeriod = EventPeriodFactory::create(
293 array_merge(
294 $eventPeriod->toArray(),
295 ['zoomMeeting' => null]
296 )
297 );
298
299 $event->getPeriods()->placeItem($newEventPeriod, $key, true);
300 }
301 }
302
303 $ameliaUserId = $userAS->isAmeliaUser($user) && $user->getId() ? $user->getId()->getValue() : null;
304
305 // Delete other bookings if user is customer
306 if ($userAS->isCustomer($user)) {
307 /** @var CustomerBooking $booking */
308 foreach ($event->getBookings()->getItems() as $bookingKey => $booking) {
309 if ($booking->getCustomerId()->getValue() !== $ameliaUserId) {
310 $event->getBookings()->deleteItem($bookingKey);
311 }
312 }
313 }
314
315 if (!$isFrontEnd && $userAS->isCustomer($user) && $event->getBookings()->length() === 0) {
316 continue;
317 }
318
319 $eventsArray[] = array_merge($event->toArray(), $eventsInfo);
320 }
321
322 $customersNoShowCount = [];
323
324 if ($noShowTagEnabled && $customersNoShowCountIds) {
325 /** @var CustomerBookingRepository $bookingRepository */
326 $bookingRepository = $this->container->get('domain.booking.customerBooking.repository');
327
328 $customersNoShowCount = $bookingRepository->countByNoShowStatus($customersNoShowCountIds);
329 }
330
331 $eventsArray = apply_filters('amelia_get_events_filter', $eventsArray);
332
333 do_action('amelia_get_events', $eventsArray);
334
335 $result->setResult(CommandResult::RESULT_SUCCESS);
336 $result->setMessage('Successfully retrieved events');
337 $result->setData(
338 [
339 Entities::EVENTS => $eventsArray,
340 'count' => !$isCalendarPage && empty($params['skipCount']) ? (int)$eventRepository->getFilteredIdsCount($params) : null,
341 'customersNoShowCount' => $customersNoShowCount
342 ]
343 );
344
345 return $result;
346 }
347 }
348