PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 2.2
Booking for Appointments and Events Calendar – Amelia v2.2
2.4.9 2.4.8 2.4.7 2.4.6 2.4.5 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 / Application / Commands / Booking / Appointment / GetAppointmentBookingsCommandHandler.php
ameliabooking / src / Application / Commands / Booking / Appointment Last commit date
AddAppointmentCommand.php 1 year ago AddAppointmentCommandHandler.php 4 months ago AddBookingCommand.php 1 year ago AddBookingCommandHandler.php 1 year ago ApproveBookingRemotelyCommand.php 1 year ago ApproveBookingRemotelyCommandHandler.php 6 months ago CancelBookingCommand.php 1 year ago CancelBookingCommandHandler.php 8 months ago CancelBookingRemotelyCommand.php 1 year ago CancelBookingRemotelyCommandHandler.php 6 months ago DeleteAppointmentCommand.php 1 year ago DeleteAppointmentCommandHandler.php 1 year ago DeleteBookingCommand.php 1 year ago DeleteBookingCommandHandler.php 1 year ago DeleteBookingRemotelyCommand.php 1 year ago DeleteBookingRemotelyCommandHandler.php 8 months ago GetAppointmentBookingsCommand.php 8 months ago GetAppointmentBookingsCommandHandler.php 5 months ago GetAppointmentCommand.php 7 years ago GetAppointmentCommandHandler.php 6 months ago GetAppointmentsCommand.php 1 year ago GetAppointmentsCommandHandler.php 6 months ago GetIcsCommand.php 8 months ago GetIcsCommandHandler.php 4 years ago GetTimeSlotsCommand.php 1 year ago GetTimeSlotsCommandHandler.php 6 months ago ReassignBookingCommand.php 1 year ago ReassignBookingCommandHandler.php 5 months ago RejectBookingRemotelyCommand.php 1 year ago RejectBookingRemotelyCommandHandler.php 6 months ago SuccessfulBookingCommand.php 1 year ago SuccessfulBookingCommandHandler.php 1 year ago UpdateAppointmentCommand.php 1 year ago UpdateAppointmentCommandHandler.php 4 months ago UpdateAppointmentNoteCommand.php 4 months ago UpdateAppointmentNoteCommandHandler.php 4 months ago UpdateAppointmentStatusCommand.php 1 year ago UpdateAppointmentStatusCommandHandler.php 7 months ago UpdateAppointmentTimeCommand.php 1 year ago UpdateAppointmentTimeCommandHandler.php 5 months ago UpdateBookingStatusCommand.php 1 year ago UpdateBookingStatusCommandHandler.php 7 months ago
GetAppointmentBookingsCommandHandler.php
353 lines
1 <?php
2
3 namespace AmeliaBooking\Application\Commands\Booking\Appointment;
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\AppointmentApplicationService;
9 use AmeliaBooking\Application\Services\Helper\HelperService;
10 use AmeliaBooking\Application\Services\Payment\PaymentApplicationService;
11 use AmeliaBooking\Application\Services\User\ProviderApplicationService;
12 use AmeliaBooking\Domain\Collection\Collection;
13 use AmeliaBooking\Domain\Common\Exceptions\AuthorizationException;
14 use AmeliaBooking\Domain\Common\Exceptions\InvalidArgumentException;
15 use AmeliaBooking\Domain\Entity\Bookable\Service\Service;
16 use AmeliaBooking\Domain\Entity\Booking\Appointment\Appointment;
17 use AmeliaBooking\Domain\Entity\Booking\Appointment\CustomerBooking;
18 use AmeliaBooking\Domain\Entity\Entities;
19 use AmeliaBooking\Domain\Entity\User\AbstractUser;
20 use AmeliaBooking\Domain\Services\Settings\SettingsService;
21 use AmeliaBooking\Infrastructure\Common\Exceptions\QueryExecutionException;
22 use AmeliaBooking\Infrastructure\Repository\Bookable\Service\ServiceRepository;
23 use AmeliaBooking\Infrastructure\Repository\Booking\Appointment\AppointmentRepository;
24 use AmeliaBooking\Infrastructure\Repository\Booking\Appointment\CustomerBookingRepository;
25 use AmeliaBooking\Infrastructure\Repository\User\ProviderRepository;
26 use DateTimeZone;
27
28 /**
29 * Class GetAppointmentBookingsCommandHandler
30 *
31 * @package AmeliaBooking\Application\Commands\Booking\Appointment
32 */
33 class GetAppointmentBookingsCommandHandler extends CommandHandler
34 {
35 /**
36 * @param GetAppointmentBookingsCommand $command
37 *
38 * @return CommandResult
39 *
40 * @throws InvalidArgumentException
41 * @throws QueryExecutionException
42 * @throws AccessDeniedException
43 */
44 public function handle(GetAppointmentBookingsCommand $command)
45 {
46 $result = new CommandResult();
47
48 /** @var HelperService $helperService */
49 $helperService = $this->container->get('application.helper.service');
50
51 /** @var AppointmentRepository $appointmentRepository */
52 $appointmentRepository = $this->container->get('domain.booking.appointment.repository');
53
54 /** @var ServiceRepository $serviceRepository */
55 $serviceRepository = $this->container->get('domain.bookable.service.repository');
56
57 /** @var SettingsService $settingsDS */
58 $settingsDS = $this->container->get('domain.settings.service');
59
60 /** @var PaymentApplicationService $paymentAS */
61 $paymentAS = $this->container->get('application.payment.service');
62
63 /** @var AppointmentApplicationService $appointmentAS */
64 $appointmentAS = $this->container->get('application.booking.appointment.service');
65
66 /** @var ProviderRepository $providerRepository */
67 $providerRepository = $this->container->get('domain.users.providers.repository');
68
69 /** @var ProviderApplicationService $providerAS */
70 $providerAS = $this->container->get('application.user.provider.service');
71
72
73 $params = $command->getField('params');
74
75 if (isset($params['dates']) && empty($params['dates'][0]) && empty($params['dates'][1])) {
76 unset($params['dates']);
77 }
78
79 try {
80 /** @var AbstractUser $user */
81 $user = $command->getUserApplicationService()->authorization(null, $command->getCabinetType());
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 $readOthers = $this->container->getPermissionsService()->currentUserCanReadOthers(Entities::APPOINTMENTS);
94
95 $providerCountParams = [];
96 if (
97 (!$readOthers) &&
98 $user && $user->getType() === Entities::PROVIDER
99 ) {
100 $providerCountParams['providerId'] = $user->getId()->getValue();
101 $params['providers'] = [$user->getId()->getValue()];
102 }
103
104 $customerCountParams = [];
105 if ($user && $user->getType() === Entities::CUSTOMER) {
106 $customerCountParams['customers'] = [$user->getId()->getValue()];
107 $params['customers'] = [$user->getId()->getValue()];
108 }
109
110 $entitiesIds = !empty($params['search']) ? $appointmentAS->getAppointmentEntitiesIdsBySearchString($params['search']) : [];
111
112 $appointmentsIds = [];
113
114 $helperService->convertDates($params);
115
116 /** @var Collection $periodAppointments */
117 $periodAppointments = $appointmentRepository->getPeriodAppointments(
118 array_merge(
119 $params,
120 ['search' => $entitiesIds, 'searchTerm' => !empty($params['search']) ? $params['search'] : ''],
121 ['skipBookings' => empty($params['customers']) && empty($entitiesIds['customers'])]
122 ),
123 $params['limit']
124 );
125
126 $serviceIds = [];
127
128 /** @var Appointment $appointment */
129 foreach ($periodAppointments->getItems() as $appointment) {
130 $appointmentsIds[] = $appointment->getId()->getValue();
131 $serviceIds[] = $appointment->getServiceId()->getValue();
132 }
133
134 /** @var Collection $appointments */
135 $appointments = new Collection();
136
137 $customersNoShowCountIds = [];
138
139 $noShowTagEnabled = $settingsDS->isFeatureEnabled('noShowTag');
140
141 if ($appointmentsIds) {
142 $appointments = $appointmentRepository->getFiltered(
143 [
144 'ids' => $appointmentsIds,
145 'withLocations' => true,
146 'sort' => !empty($params['sort']) ? $params['sort'] : null,
147 'customers' => $user && $user->getType() === Entities::CUSTOMER
148 ? [$user->getId()->getValue()]
149 : [],
150 ]
151 );
152 }
153
154 /** @var Collection $services */
155 $services = $serviceRepository->getAllArrayIndexedById($serviceIds);
156
157 $providersServices = $providerRepository->getProvidersServices($serviceIds);
158
159 $appointmentsArray = [];
160
161 /** @var Appointment $appointment */
162 foreach ($appointments->getItems() as $appointment) {
163 /** @var Service $service */
164 $service = $services->getItem($appointment->getServiceId()->getValue());
165
166 $providerId = $appointment->getProviderId()->getValue();
167
168 // skip appointments for other providers if user is provider
169 if (
170 (!$readOthers) &&
171 $user->getType() === Entities::PROVIDER &&
172 $user->getId()->getValue() !== $providerId
173 ) {
174 continue;
175 }
176
177 $appointmentAS->calculateAndSetAppointmentEnd($appointment, $service);
178
179 $timeZone = !empty($params['timeZone'])
180 ? $params['timeZone']
181 : ($user && $user->getType() === Entities::PROVIDER ? $providerAS->getTimeZone($user) : null);
182
183 if ($timeZone) {
184 $appointment->getBookingStart()->getValue()->setTimezone(new DateTimeZone($timeZone));
185
186 $appointment->getBookingEnd()->getValue()->setTimezone(new DateTimeZone($timeZone));
187 }
188
189 $bookedSpots = 0;
190 $bookings = [];
191
192 $isPackageAppointment = false;
193 $bookingPrice = 0;
194 $paidPrice = 0;
195 $bookingSource = 'backend';
196 $frontendBookings = 0;
197
198 $wcTax = 0;
199 $wcDiscount = 0;
200
201 /** @var CustomerBooking $booking */
202 foreach ($appointment->getBookings()->getItems() as $booking) {
203 // fix for wrongly saved JSON
204 if (
205 $booking->getCustomFields() &&
206 json_decode($booking->getCustomFields()->getValue(), true) === null
207 ) {
208 $booking->setCustomFields(null);
209 }
210
211 if ($noShowTagEnabled && !in_array($booking->getCustomerId()->getValue(), $customersNoShowCountIds)) {
212 $customersNoShowCountIds[] = $booking->getCustomerId()->getValue();
213 }
214
215 $bookedSpots += $booking->getPersons()->getValue();
216
217 $bookings[] = [
218 'id' => $booking->getId()->getValue(),
219 'status' => $booking->getStatus()->getValue(),
220 'customer' => $booking->getCustomer() ? $booking->getCustomer()->toArray() : null,
221 'payment' => [
222 'paymentMethods' => array_map(
223 function ($payment) {
224 return $payment['gateway'];
225 },
226 $booking->getPayments()->toArray()
227 ),
228 'status' => $paymentAS->getFullStatus($booking->toArray(), 'appointment'),
229 ],
230 'created' => $booking->getCreated() ?
231 $booking->getCreated()->getValue()->format('Y-m-d') : null,
232 ];
233
234 $isPackageAppointment = !empty($booking->getPackageCustomerService());
235
236 $bookingPrice += $paymentAS->calculateAppointmentPrice($booking->toArray(), 'appointment');
237
238 foreach ($booking->getPayments()->toArray() as $payment) {
239 if ($payment['status'] === 'paid' || $payment['status'] === 'partiallyPaid') {
240 $paidPrice += $payment['amount'];
241 }
242
243 $paymentAS->addWcFields($payment);
244
245 $wcTax += !empty($payment['wcItemTaxValue']) ? $payment['wcItemTaxValue'] : 0;
246
247 $wcDiscount += !empty($payment['wcItemCouponValue']) ? $payment['wcItemCouponValue'] : 0;
248 }
249
250 if ($booking->getInfo()) {
251 $bookingSource = 'frontendAndBackend';
252 $frontendBookings++;
253 }
254 }
255
256 if ($frontendBookings === $appointment->getBookings()->length()) {
257 $bookingSource = 'frontend';
258 }
259
260 $bookingStart = $appointment->getBookingStart() ? $appointment->getBookingStart()->getValue()->format('Y-m-d H:i:s') : null;
261 $bookingEnd = $appointment->getBookingEnd() ? $appointment->getBookingEnd()->getValue()->format('Y-m-d H:i:s') : null;
262
263 $appointmentsArray[] = [
264 'id' => $appointment->getId()->getValue(),
265 'bookedSpots' => $bookedSpots,
266 'bookingStartDateTime' => $bookingStart,
267 'bookingEndDateTime' => $bookingEnd,
268 'bookingStartDate' => $bookingStart ? explode(' ', $bookingStart)[0] : null,
269 'bookingSource' => $bookingSource,
270 'employee' => $appointment->getProvider() ? [
271 'id' => $appointment->getProvider()->getId()->getValue(),
272 'firstName' => $appointment->getProvider()->getFirstName() ? $appointment->getProvider()->getFirstName()->getValue() : null,
273 'lastName' => $appointment->getProvider()->getLastName() ? $appointment->getProvider()->getLastName()->getValue() : null,
274 'picture' => $appointment->getProvider()->getPicture() ? $appointment->getProvider()->getPicture()->getThumbPath() : null,
275 'badge' => $appointment->getProvider()->getBadgeId() ? $providerAS->getBadge($appointment->getProvider()->getBadgeId()->getValue()) : null,
276 ] : null,
277 'googleMeetLink' => $appointment->getGoogleMeetUrl(),
278 'zoomHostLink' => $appointment->getZoomMeeting() ? $appointment->getZoomMeeting()->getStartUrl()->getValue() : null,
279 'zoomJoinLink' => $appointment->getZoomMeeting() ? $appointment->getZoomMeeting()->getJoinUrl()->getValue() : null,
280 'lessonSpace' => $appointment->getLessonSpace() ? $appointment->getLessonSpace() : null,
281 'microsoftTeamsLink' => $appointment->getMicrosoftTeamsUrl() ? $appointment->getMicrosoftTeamsUrl() : null,
282 'location' => $appointment->getLocation() ? [
283 'id' => $appointment->getLocation()->getId()->getValue(),
284 'name' => $appointment->getLocation()->getName()->getValue(),
285 ] : null,
286 'service' => $appointment->getService() ? [
287 'id' => $appointment->getService()->getId()->getValue(),
288 'name' => $appointment->getService()->getName()->getValue(),
289 'color' => $appointment->getService()->getColor() ? $service->getColor()->getValue() : null,
290 'picture' => $appointment->getService()->getPicture() ? $appointment->getService()->getPicture()->getThumbPath() : null,
291 ] : null,
292 'bookings' => $bookings,
293 'type' => $appointment->getBookings()->length() > 1 ? 'groupBooking' : ($isPackageAppointment ? 'package' : 'standAlone'),
294 'maxCapacity' => !empty($providersServices[$providerId][$service->getId()->getValue()]) ?
295 $providersServices[$providerId][$service->getId()->getValue()]['maxCapacity'] :
296 $service->getMaxCapacity()->getValue(),
297 'status' => $appointment->getStatus() ? $appointment->getStatus()->getValue() : null,
298 'note' => $appointment->getInternalNotes() ? $appointment->getInternalNotes()->getValue() : null,
299 'price' => [
300 'total' => $bookingPrice + $wcTax - $wcDiscount,
301 ],
302 'paidPrice' => $paidPrice,
303 'cancelable' => $appointmentAS->isCancelable($appointment, $service, $user),
304 'reschedulable' => $appointmentAS->isReschedulable($appointment, $service, $user),
305 ];
306 }
307
308 $periodsAppointmentsCount = $appointmentRepository->getPeriodAppointments(
309 array_merge_recursive(
310 $params,
311 ['search' => $entitiesIds, 'searchTerm' => !empty($params['search']) ? $params['search'] : ''],
312 ['skipBookings' => empty($params['customers']) && empty($entitiesIds['customers'])]
313 )
314 );
315
316 $periodsAppointmentsTotalCount = $appointmentRepository->getPeriodAppointments(
317 array_merge($customerCountParams, $providerCountParams, ['skipBookings' => true])
318 );
319
320 if ($noShowTagEnabled && $customersNoShowCountIds) {
321 /** @var CustomerBookingRepository $bookingRepository */
322 $bookingRepository = $this->container->get('domain.booking.customerBooking.repository');
323
324 $customersNoShowCount = $bookingRepository->countByNoShowStatus($customersNoShowCountIds);
325
326 foreach ($appointmentsArray as &$appointmentArray) {
327 foreach ($appointmentArray['bookings'] as &$booking) {
328 if (!empty($customersNoShowCount[$booking['customer']['id']])) {
329 $booking['customer']['noShowCount'] = $customersNoShowCount[$booking['customer']['id']]['count'];
330 }
331 }
332 }
333 }
334
335 $appointmentsArray = apply_filters('amelia_get_appointments_filter', $appointmentsArray);
336
337 do_action('amelia_get_appointments', $appointmentsArray);
338
339 $result->setResult(CommandResult::RESULT_SUCCESS);
340 $result->setMessage('Successfully retrieved appointments');
341
342 $result->setData(
343 [
344 Entities::APPOINTMENTS => $appointmentsArray,
345 'totalCount' => $periodsAppointmentsTotalCount->length(),
346 'filteredCount' => $periodsAppointmentsCount->length(),
347 ]
348 );
349
350 return $result;
351 }
352 }
353