PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 1.2.31
Booking for Appointments and Events Calendar – Amelia v1.2.31
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 / Entities / GetEntitiesCommandHandler.php
ameliabooking / src / Application / Commands / Entities Last commit date
GetEntitiesCommand.php 1 year ago GetEntitiesCommandHandler.php 1 year ago
GetEntitiesCommandHandler.php
645 lines
1 <?php
2
3 namespace AmeliaBooking\Application\Commands\Entities;
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\Bookable\BookableApplicationService;
9 use AmeliaBooking\Application\Services\Bookable\AbstractPackageApplicationService;
10 use AmeliaBooking\Application\Services\Booking\EventApplicationService;
11 use AmeliaBooking\Application\Services\Coupon\AbstractCouponApplicationService;
12 use AmeliaBooking\Application\Services\CustomField\AbstractCustomFieldApplicationService;
13 use AmeliaBooking\Application\Services\Helper\HelperService;
14 use AmeliaBooking\Application\Services\Location\AbstractLocationApplicationService;
15 use AmeliaBooking\Application\Services\Resource\AbstractResourceApplicationService;
16 use AmeliaBooking\Application\Services\Tax\TaxApplicationService;
17 use AmeliaBooking\Application\Services\User\ProviderApplicationService;
18 use AmeliaBooking\Application\Services\User\UserApplicationService;
19 use AmeliaBooking\Domain\Collection\Collection;
20 use AmeliaBooking\Domain\Common\Exceptions\AuthorizationException;
21 use AmeliaBooking\Domain\Common\Exceptions\InvalidArgumentException;
22 use AmeliaBooking\Domain\Entity\Bookable\Service\Package;
23 use AmeliaBooking\Domain\Entity\Bookable\Service\Service;
24 use AmeliaBooking\Domain\Entity\Booking\Event\Event;
25 use AmeliaBooking\Domain\Entity\Coupon\Coupon;
26 use AmeliaBooking\Domain\Entity\CustomField\CustomField;
27 use AmeliaBooking\Domain\Entity\Entities;
28 use AmeliaBooking\Domain\Entity\User\AbstractUser;
29 use AmeliaBooking\Domain\Entity\User\Customer;
30 use AmeliaBooking\Domain\Entity\User\Provider;
31 use AmeliaBooking\Domain\Services\Booking\EventDomainService;
32 use AmeliaBooking\Domain\Services\DateTime\DateTimeService;
33 use AmeliaBooking\Domain\Services\Settings\SettingsService;
34 use AmeliaBooking\Domain\Services\User\ProviderService;
35 use AmeliaBooking\Domain\ValueObjects\String\Status;
36 use AmeliaBooking\Infrastructure\Common\Exceptions\NotFoundException;
37 use AmeliaBooking\Infrastructure\Common\Exceptions\QueryExecutionException;
38 use AmeliaBooking\Infrastructure\Licence\Licence as Licence;
39 use AmeliaBooking\Infrastructure\Repository\Bookable\Service\CategoryRepository;
40 use AmeliaBooking\Infrastructure\Repository\Bookable\Service\PackageRepository;
41 use AmeliaBooking\Infrastructure\Repository\Bookable\Service\ServiceRepository;
42 use AmeliaBooking\Infrastructure\Repository\Booking\Appointment\AppointmentRepository;
43 use AmeliaBooking\Infrastructure\Repository\Booking\Appointment\CustomerBookingRepository;
44 use AmeliaBooking\Infrastructure\Repository\Booking\Event\EventRepository;
45 use AmeliaBooking\Infrastructure\Repository\Booking\Event\EventTagsRepository;
46 use AmeliaBooking\Infrastructure\Repository\Coupon\CouponRepository;
47 use AmeliaBooking\Infrastructure\Repository\User\ProviderRepository;
48 use AmeliaBooking\Infrastructure\Repository\User\UserRepository;
49 use AmeliaBooking\Infrastructure\Services\LessonSpace\AbstractLessonSpaceService;
50 use AmeliaBooking\Infrastructure\Services\Payment\SquareService;
51 use Interop\Container\Exception\ContainerException;
52
53 /**
54 * Class GetEntitiesCommandHandler
55 *
56 * @package AmeliaBooking\Application\Commands\Entities
57 */
58 class GetEntitiesCommandHandler extends CommandHandler
59 {
60 /**
61 * @param GetEntitiesCommand $command
62 *
63 * @return CommandResult
64 * @throws AccessDeniedException
65 * @throws ContainerException
66 * @throws InvalidArgumentException
67 * @throws NotFoundException
68 * @throws QueryExecutionException
69 */
70 public function handle(GetEntitiesCommand $command)
71 {
72 /** @var UserApplicationService $userAS */
73 $userAS = $this->container->get('application.user.service');
74
75 /** @var EventDomainService $eventDS */
76 $eventDS = $this->container->get('domain.booking.event.service');
77
78 /** @var ProviderApplicationService $providerAS */
79 $providerAS = $this->container->get('application.user.provider.service');
80
81 /** @var AbstractCustomFieldApplicationService $customFieldAS */
82 $customFieldAS = $this->container->get('application.customField.service');
83
84 /** @var AbstractLocationApplicationService $locationAS */
85 $locationAS = $this->container->get('application.location.service');
86
87 /** @var AbstractCouponApplicationService $couponAS */
88 $couponAS = $this->container->get('application.coupon.service');
89
90 /** @var ProviderService $providerService */
91 $providerService = $this->container->get('domain.user.provider.service');
92
93 try {
94 /** @var AbstractUser $currentUser */
95 $currentUser = $command->getUserApplicationService()->authorization(
96 $command->getPage() === 'cabinet' ? $command->getToken() : null,
97 $command->getCabinetType()
98 );
99 } catch (AuthorizationException $e) {
100 $currentUser = null;
101 }
102
103 $params = $command->getField('params');
104
105 $params['types'] = !empty($params['types']) ? $params['types'] : [];
106
107 $result = new CommandResult();
108
109 $this->checkMandatoryFields($command);
110
111 /** @var Collection $allServices */
112 $allServices = new Collection();
113
114 /** @var Collection $services */
115 $services = new Collection();
116
117 /** @var Collection $locations */
118 $locations = new Collection();
119
120 /** @var Collection $categories */
121 $categories = new Collection();
122
123 /** @var Collection $events */
124 $events = new Collection();
125
126 $resultData = [];
127
128 /** @var SettingsService $settingsDS */
129 $settingsDS = $this->container->get('domain.settings.service');
130
131
132 /** Events */
133 if (in_array(Entities::EVENTS, $params['types'], true)) {
134 /** @var EventApplicationService $eventAS */
135 $eventAS = $this->container->get('application.booking.event.service');
136
137 /** @var Collection $events */
138 $events = $eventAS->getEventsByCriteria(
139 [
140 'dates' => [DateTimeService::getNowDateTime()],
141 'page' => 1,
142 ],
143 [
144 'fetchEventsPeriods' => true,
145 ],
146 $settingsDS->getSetting('general', 'eventsFilterLimit') ?: 1000
147 );
148
149 $resultData['events'] = $eventDS->getShortcodeForEventList($this->container, $events->toArray());
150 }
151
152 /** Event Tags */
153 if (in_array(Entities::TAGS, $params['types'], true)) {
154 /** @var EventTagsRepository $eventTagsRepository */
155 $eventTagsRepository = $this->container->get('domain.booking.event.tag.repository');
156
157 /** @var Collection $eventsTags */
158 $eventsTags = $eventTagsRepository->getAllDistinctByCriteria(
159 $events->length() ? ['eventIds' => array_column($events->toArray(), 'id')] : []
160 );
161
162 $resultData['tags'] = $eventsTags->toArray();
163 }
164
165 if (
166 in_array(Entities::LOCATIONS, $params['types'], true) ||
167 in_array(Entities::EMPLOYEES, $params['types'], true)
168 ) {
169 /** @var Collection $locations */
170 $locations = $locationAS->getAllOrderedByName();
171 }
172
173 /** Locations */
174 if (in_array(Entities::LOCATIONS, $params['types'], true)) {
175 $resultData['locations'] = $locations->toArray();
176 }
177
178 if (
179 in_array(Entities::CATEGORIES, $params['types'], true) ||
180 in_array(Entities::EMPLOYEES, $params['types'], true) ||
181 in_array(Entities::COUPONS, $params['types'], true)
182 ) {
183 /** @var ServiceRepository $serviceRepository */
184 $serviceRepository = $this->container->get('domain.bookable.service.repository');
185 /** @var CategoryRepository $categoryRepository */
186 $categoryRepository = $this->container->get('domain.bookable.category.repository');
187 /** @var BookableApplicationService $bookableAS */
188 $bookableAS = $this->container->get('application.bookable.service');
189
190 /** @var Collection $allServices */
191 $allServices = $serviceRepository->getAllArrayIndexedById();
192
193 /** @var Service $service */
194 foreach ($allServices->getItems() as $service) {
195 if (
196 $service->getStatus()->getValue() === Status::VISIBLE ||
197 Licence::$premium ||
198 ($currentUser && $currentUser->getType() === AbstractUser::USER_ROLE_ADMIN)
199 ) {
200 $services->addItem($service, $service->getId()->getValue());
201 }
202 }
203
204 /** @var Collection $categories */
205 $categories = $categoryRepository->getAllIndexedById();
206
207 $bookableAS->addServicesToCategories($categories, $services);
208 }
209
210 /** Categories */
211 if (in_array(Entities::CATEGORIES, $params['types'], true)) {
212 $resultData['categories'] = $categories->toArray();
213 }
214
215
216 $resultData['customers'] = [];
217
218 /** Customers */
219 if (in_array(Entities::CUSTOMERS, $params['types'], true)) {
220 /** @var UserRepository $userRepo */
221 $userRepo = $this->getContainer()->get('domain.users.repository');
222
223 $resultData['customers'] = [];
224
225 if ($currentUser) {
226 switch ($currentUser->getType()) {
227 case (AbstractUser::USER_ROLE_CUSTOMER):
228 if ($currentUser->getId()) {
229 /** @var Customer $customer */
230 $customer = $userRepo->getById($currentUser->getId()->getValue());
231
232 $resultData['customers'] = [$customer->toArray()];
233 }
234
235 break;
236
237 case (AbstractUser::USER_ROLE_PROVIDER):
238 $resultData['customers'] = $providerAS->getAllowedCustomers($currentUser)->toArray();
239
240 break;
241
242 default:
243 /** @var Collection $customers */
244 $customers = $userRepo->getAllWithAllowedBooking();
245
246 $resultData['customers'] = $customers->toArray();
247 }
248 }
249
250 $noShowTagEnabled = $settingsDS->getSetting('roles', 'enableNoShowTag');
251
252 if ($noShowTagEnabled && $resultData['customers']) {
253 /** @var CustomerBookingRepository $bookingRepository */
254 $bookingRepository = $this->container->get('domain.booking.customerBooking.repository');
255
256 $usersIds = array_map(
257 function ($user) {
258 return $user['id'];
259 },
260 $resultData['customers']
261 );
262
263 $customersNoShowCount = $bookingRepository->countByNoShowStatus($usersIds);
264
265 foreach ($resultData['customers'] as $key => $customer) {
266 $resultData['customers'][$key]['noShowCount'] = $customersNoShowCount[$key]['count'];
267 }
268 }
269 }
270
271 /** Providers */
272 if (in_array(Entities::EMPLOYEES, $params['types'], true)) {
273 /** @var ProviderRepository $providerRepository */
274 $providerRepository = $this->container->get('domain.users.providers.repository');
275
276 /** @var Collection $providers */
277 $providers = $providerRepository->getWithSchedule(
278 [
279 'dates' => [
280 DateTimeService::getNowDateTimeObject()->modify('-1 days')->format('Y-m-d H:i:s')
281 ],
282 'fetchCalendars' => $currentUser && $currentUser->getType() === AbstractUser::USER_ROLE_ADMIN,
283 ]
284 );
285
286 /** @var Provider $provider */
287 foreach ($providers->getItems() as $provider) {
288 $providerService->setProviderServices($provider, $services, true);
289 }
290
291 if (
292 array_key_exists('page', $params) &&
293 in_array($params['page'], [Entities::CALENDAR, Entities::APPOINTMENTS]) &&
294 $userAS->isAdminAndAllowedToBookAtAnyTime()
295 ) {
296 $providerService->setProvidersAlwaysAvailable($providers);
297 }
298
299 $resultData['entitiesRelations'] = [];
300
301 /** @var Provider $provider */
302 foreach ($providers->getItems() as $providerId => $provider) {
303 if ($data = $providerAS->getProviderServiceLocations($provider, $locations, $services)) {
304 $resultData['entitiesRelations'][$providerId] = $data;
305 }
306 }
307
308
309 $resultData['employees'] = $providerAS->removeAllExceptUser(
310 $providers->toArray(),
311 (array_key_exists('page', $params) && $params['page'] === Entities::BOOKING) ?
312 null : $currentUser
313 );
314
315 if (
316 $currentUser === null ||
317 $currentUser->getType() === AbstractUser::USER_ROLE_CUSTOMER ||
318 !$command->getPermissionService()->currentUserCanRead(Entities::EMPLOYEES)
319 ) {
320 foreach ($resultData['employees'] as &$employee) {
321 unset(
322 $employee['appleCalendarId'],
323 $employee['googleCalendar'],
324 $employee['outlookCalendar'],
325 $employee['stripeConnect'],
326 $employee['birthday'],
327 $employee['email'],
328 $employee['externalId'],
329 $employee['phone'],
330 $employee['note'],
331 $employee['employeeAppleCalendar'],
332 );
333
334 if (isset($params['page']) && $params['page'] !== Entities::CALENDAR) {
335 unset(
336 $employee['weekDayList'],
337 $employee['specialDayList'],
338 $employee['dayOffList']
339 );
340 }
341 }
342 }
343 }
344
345 $resultData[Entities::APPOINTMENTS] = [
346 'futureAppointments' => [],
347 ];
348
349 if (in_array(Entities::APPOINTMENTS, $params['types'], true)) {
350 $userParams = [
351 'dates' => [null, null]
352 ];
353
354 if (!$command->getPermissionService()->currentUserCanReadOthers(Entities::APPOINTMENTS)) {
355 if ($currentUser->getId() === null) {
356 $userParams[$currentUser->getType() . 'Id'] = 0;
357 } else {
358 $userParams[$currentUser->getType() . 'Id'] =
359 $currentUser->getId()->getValue();
360 }
361 }
362
363 /** @var AppointmentRepository $appointmentRepo */
364 $appointmentRepo = $this->container->get('domain.booking.appointment.repository');
365
366 /** @var Collection $appointments */
367 $appointments = $appointmentRepo->getFiltered($userParams);
368
369 $resultData[Entities::APPOINTMENTS] = [
370 'futureAppointments' => $appointments->toArray(),
371 ];
372 }
373
374 /** Custom Fields */
375 if (
376 in_array(Entities::CUSTOM_FIELDS, $params['types'], true) ||
377 in_array('customFields', $params['types'], true)
378 ) {
379 /** @var Collection $customFields */
380 $customFields = $customFieldAS->getAll();
381
382 if (!empty($params['lite'])) {
383 $resultData['customFields'] = [];
384
385 /** @var CustomField $customField */
386 foreach ($customFields->getItems() as $customField) {
387 $item = array_merge(
388 $customField->toArray(),
389 [
390 'services' => [],
391 'events' => [],
392 ]
393 );
394
395 /** @var Service $service */
396 foreach ($customField->getServices()->getItems() as $service) {
397 $item['services'][] = [
398 'id' => $service->getId()->getValue()
399 ];
400 }
401
402 /** @var Event $event */
403 foreach ($customField->getEvents()->getItems() as $event) {
404 $item['events'][] = [
405 'id' => $event->getId()->getValue()
406 ];
407 }
408
409 $resultData['customFields'][] = $item;
410 }
411 } else {
412 $resultData['customFields'] = $customFields->toArray();
413 }
414 }
415
416 /** Coupons */
417 if (
418 in_array(Entities::COUPONS, $params['types'], true) &&
419 $this->getContainer()->getPermissionsService()->currentUserCanRead(Entities::COUPONS)
420 ) {
421 /** @var Collection $coupons */
422 $coupons = $couponAS->getAll();
423
424 /** @var CouponRepository $couponRepository */
425 $couponRepository = $this->container->get('domain.coupon.repository');
426
427 /** @var EventRepository $eventRepository */
428 $eventRepository = $this->container->get('domain.booking.event.repository');
429
430 /** @var PackageRepository $packageRepository */
431 $packageRepository = $this->container->get('domain.bookable.package.repository');
432
433 if ($coupons->length()) {
434 foreach ($couponRepository->getCouponsServicesIds($coupons->keys()) as $ids) {
435 /** @var Coupon $coupon */
436 $coupon = $coupons->getItem($ids['couponId']);
437
438 if ($coupon->getAllServices() && $coupon->getAllServices()->getValue()) {
439 $coupon->setServiceList(new Collection($allServices->getItems()));
440 continue;
441 }
442
443 $coupon->getServiceList()->addItem(
444 $allServices->getItem($ids['serviceId']),
445 $ids['serviceId']
446 );
447 }
448
449 /** @var Collection $allEvents */
450 $allEvents = $eventRepository->getAllIndexedById();
451
452 foreach ($couponRepository->getCouponsEventsIds($coupons->keys()) as $ids) {
453 /** @var Coupon $coupon */
454 $coupon = $coupons->getItem($ids['couponId']);
455
456 if ($coupon->getAllEvents() && $coupon->getAllEvents()->getValue()) {
457 $coupon->setEventList(new Collection($allEvents->getItems()));
458 continue;
459 }
460
461 $coupon->getEventList()->addItem(
462 $allEvents->getItem($ids['eventId']),
463 $ids['eventId']
464 );
465 }
466
467 /** @var Collection $allPackages */
468 $allPackages = $packageRepository->getAllIndexedById();
469
470 foreach ($couponRepository->getCouponsPackagesIds($coupons->keys()) as $ids) {
471 /** @var Coupon $coupon */
472 $coupon = $coupons->getItem($ids['couponId']);
473
474 if ($coupon->getAllPackages() && $coupon->getAllPackages()->getValue()) {
475 $coupon->setPackageList(new Collection($allPackages->getItems()));
476 continue;
477 }
478
479 $coupon->getPackageList()->addItem(
480 $allPackages->getItem($ids['packageId']),
481 $ids['packageId']
482 );
483 }
484 }
485
486 if (!empty($params['lite'])) {
487 $resultData['coupons'] = [];
488
489 /** @var Coupon $coupon */
490 foreach ($coupons->getItems() as $coupon) {
491 $item = array_merge(
492 $coupon->toArray(),
493 [
494 'serviceList' => [],
495 'eventList' => [],
496 'packageList' => [],
497 ]
498 );
499
500 /** @var Service $service */
501 foreach ($coupon->getServiceList()->getItems() as $service) {
502 $item['serviceList'][] = [
503 'id' => $service->getId()->getValue()
504 ];
505 }
506
507 /** @var Event $event */
508 foreach ($coupon->getEventList()->getItems() as $event) {
509 $item['eventList'][] = [
510 'id' => $event->getId()->getValue()
511 ];
512 }
513
514 /** @var Package $package */
515 foreach ($coupon->getPackageList()->getItems() as $package) {
516 $item['packageList'][] = [
517 'id' => $package->getId()->getValue()
518 ];
519 }
520
521 $resultData['coupons'][] = $item;
522 }
523 } else {
524 $resultData['coupons'] = $coupons->toArray();
525 }
526 }
527
528 /** Settings */
529 if (in_array(Entities::SETTINGS, $params['types'], true)) {
530 /** @var HelperService $helperService */
531 $helperService = $this->container->get('application.helper.service');
532
533 $languages = $helperService->getLanguages();
534
535 usort(
536 $languages,
537 function ($x, $y) {
538 return strcasecmp($x['name'], $y['name']);
539 }
540 );
541
542 $languagesSorted = [];
543
544 foreach ($languages as $language) {
545 $languagesSorted[$language['wp_locale']] = $language;
546 }
547
548 /** @var \AmeliaBooking\Application\Services\Settings\SettingsService $settingsAS*/
549 $settingsAS = $this->container->get('application.settings.service');
550
551 $daysOff = $settingsAS->getDaysOff();
552
553 $squareLocations = [];
554 if (
555 !empty($settingsDS->getSetting('payments', 'square')['accessToken']['access_token'])
556 && in_array('squareLocations', $params['types'])
557 ) {
558 /** @var SquareService $squareService */
559 $squareService = $this->container->get('infrastructure.payment.square.service');
560
561 try {
562 $squareLocations = $squareService->getLocations();
563 } catch (\Exception $e) {
564 }
565 }
566
567 $resultData['settings'] = [
568 'general' => [
569 'usedLanguages' => $settingsDS->getSetting('general', 'usedLanguages'),
570 ],
571 'languages' => $languagesSorted,
572 'daysOff' => $daysOff,
573 'squareLocations' => $squareLocations
574 ];
575 }
576
577 /** Packages */
578 if (in_array(Entities::PACKAGES, $params['types'], true)) {
579 /** @var AbstractPackageApplicationService $packageApplicationService */
580 $packageApplicationService = $this->container->get('application.bookable.package');
581
582 $resultData['packages'] = $packageApplicationService->getPackagesArray();
583 }
584
585 /** Resources */
586 if (in_array(Entities::RESOURCES, $params['types'], true)) {
587 /** @var AbstractResourceApplicationService $resourceApplicationService */
588 $resourceApplicationService = $this->container->get('application.resource.service');
589
590 /** @var Collection $resources */
591 $resources = $resourceApplicationService->getAll([]);
592
593 $resultData['resources'] = $resources->toArray();
594 }
595
596 /** Taxes */
597 if (in_array(Entities::TAXES, $params['types'], true)) {
598 /** @var TaxApplicationService $taxApplicationService */
599 $taxApplicationService = $this->container->get('application.tax.service');
600
601 /** @var Collection $taxes */
602 $taxes = $taxApplicationService->getAll();
603
604 $resultData['taxes'] = $taxes->toArray();
605 }
606
607 /** Lesson Spaces */
608 if (
609 in_array('lessonSpace_spaces', $params['types'], true) ||
610 in_array('spaces', $params['types'], true)
611 ) {
612 $lessonSpaceApiKey = $settingsDS->getSetting('lessonSpace', 'apiKey');
613 $lessonSpaceEnabled = $settingsDS->getSetting('lessonSpace', 'enabled');
614 $lessonSpaceCompanyId = $settingsDS->getSetting('lessonSpace', 'companyId');
615
616 if ($lessonSpaceEnabled && $lessonSpaceApiKey) {
617 /** @var AbstractLessonSpaceService $lessonSpaceService */
618 $lessonSpaceService = $this->container->get('infrastructure.lesson.space.service');
619
620 if (empty($lessonSpaceCompanyId)) {
621 $companyDetails = $lessonSpaceService->getCompanyId($lessonSpaceApiKey);
622 $lessonSpaceCompanyId = !empty($companyDetails) && !empty($companyDetails['id']) ? $companyDetails['id'] : null;
623 }
624
625 $resultData['spaces'] = $lessonSpaceService->getAllSpaces(
626 $lessonSpaceApiKey,
627 $lessonSpaceCompanyId,
628 !empty($params['lessonSpaceSearch']) ? $params['lessonSpaceSearch'] : null
629 );
630 }
631 }
632
633
634 $resultData = apply_filters('amelia_get_entities_filter', $resultData);
635
636 do_action('amelia_get_entities', $resultData);
637
638 $result->setResult(CommandResult::RESULT_SUCCESS);
639 $result->setMessage('Successfully retrieved entities');
640 $result->setData($resultData);
641
642 return $result;
643 }
644 }
645