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