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