PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 2.3
Booking for Appointments and Events Calendar – Amelia v2.3
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 / Services / Notification / AppointmentNotificationService.php
ameliabooking / src / Application / Services / Notification Last commit date
AbstractNotificationService.php 2 months ago AbstractWhatsAppNotificationService.php 4 months ago ApplicationNotificationService.php 2 months ago AppointmentNotificationService.php 2 months ago BasicWhatsAppNotificationService.php 6 months ago EmailNotificationService.php 6 months ago NotificationHelperService.php 6 months ago SMSAPIService.php 2 months ago SMSNotificationService.php 2 months ago
AppointmentNotificationService.php
511 lines
1 <?php
2
3 /**
4 * @copyright © Melograno Ventures. All rights reserved.
5 * @licence See LICENCE.md for license details.
6 */
7
8 namespace AmeliaBooking\Application\Services\Notification;
9
10 use AmeliaBooking\Application\Common\Exceptions\AccessDeniedException;
11 use AmeliaBooking\Application\Services\Invoice\AbstractInvoiceApplicationService;
12 use AmeliaBooking\Application\Services\Payment\PaymentApplicationService;
13 use AmeliaBooking\Domain\Collection\Collection;
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\Booking\Event\Event;
19 use AmeliaBooking\Domain\Entity\Entities;
20 use AmeliaBooking\Domain\Entity\Notification\Notification;
21 use AmeliaBooking\Domain\Entity\Payment\Payment;
22 use AmeliaBooking\Domain\Entity\User\Customer;
23 use AmeliaBooking\Domain\Services\Settings\SettingsService;
24 use AmeliaBooking\Domain\ValueObjects\String\BookingStatus;
25 use AmeliaBooking\Domain\ValueObjects\String\NotificationStatus;
26 use AmeliaBooking\Infrastructure\Common\Container;
27 use AmeliaBooking\Infrastructure\Common\Exceptions\NotFoundException;
28 use AmeliaBooking\Infrastructure\Common\Exceptions\QueryExecutionException;
29 use AmeliaBooking\Infrastructure\Repository\Bookable\Service\ServiceRepository;
30 use AmeliaBooking\Infrastructure\Repository\User\CustomerRepository;
31
32 /**
33 * Class AppointmentNotificationService
34 *
35 * @package AmeliaBooking\Application\Services\Notification
36 */
37 class AppointmentNotificationService
38 {
39 protected $container;
40
41 /**
42 * AppointmentNotificationService constructor.
43 *
44 * @param Container $container
45 */
46 public function __construct(Container $container)
47 {
48 $this->container = $container;
49 }
50
51 /**
52 * @param AbstractNotificationService $notificationService
53 * @param Appointment $appointment
54 * @param bool $logNotification
55 *
56 * @throws InvalidArgumentException
57 * @throws QueryExecutionException
58 */
59 public function sendProviderStatusNotifications(
60 $notificationService,
61 $appointment,
62 $logNotification = true
63 ) {
64 /** @var Collection $providerNotifications */
65 $providerNotifications = $notificationService->getByNameAndType(
66 "provider_appointment_{$appointment->getStatus()->getValue()}",
67 $notificationService->getType()
68 );
69
70 $sendDefault = $notificationService->sendDefault($providerNotifications, $appointment->toArray());
71
72 /** @var Notification $providerNotification */
73 foreach ($providerNotifications->getItems() as $providerNotification) {
74 if (
75 $providerNotification->getStatus()->getValue() === NotificationStatus::ENABLED &&
76 $notificationService->checkCustom($providerNotification, $appointment->toArray(), $sendDefault)
77 ) {
78 $notificationService->sendNotification(
79 $appointment->toArray(),
80 $providerNotification,
81 $logNotification
82 );
83 }
84 }
85 }
86
87 /**
88 * @param AbstractNotificationService $notificationService
89 * @param Appointment $appointment
90 * @param Collection $bookings
91 * @param bool $logNotification
92 * @param bool $isBackend
93 * @param bool $sendInvoice
94 *
95 * @throws InvalidArgumentException
96 * @throws QueryExecutionException
97 * @throws NotFoundException
98 * @throws AccessDeniedException
99 */
100 public function sendCustomersStatusNotifications(
101 $notificationService,
102 $appointment,
103 $bookings,
104 $logNotification = true,
105 $isBackend = true,
106 $sendInvoice = false,
107 $notifyCustomers = true
108 ) {
109 /** @var AbstractInvoiceApplicationService $invoiceService */
110 $invoiceService = $this->container->get('application.invoice.service');
111
112 /** @var Collection $statusNotifications */
113 $statusNotifications = new Collection();
114
115 /** @var CustomerBooking $booking */
116 foreach ($bookings->getItems() as $bookingKey => $booking) {
117 if ($booking->isChangedStatus() && $booking->isChangedStatus()->getValue()) {
118 $notificationStatus = $appointment->getStatus()->getValue() === BookingStatus::PENDING &&
119 (
120 $booking->getStatus()->getValue() === BookingStatus::APPROVED ||
121 $booking->getStatus()->getValue() === BookingStatus::PENDING
122 )
123 ? BookingStatus::PENDING
124 : $booking->getStatus()->getValue();
125
126 if (!$statusNotifications->keyExists($notificationStatus)) {
127 $statusNotifications->addItem(
128 $notificationService->getByNameAndType(
129 "customer_appointment_{$notificationStatus}",
130 $notificationService->getType()
131 ),
132 $notificationStatus
133 );
134 }
135
136 /** @var Collection $customerNotifications */
137 $customerNotifications = $statusNotifications->getItem($notificationStatus);
138
139 $sendDefault = $notificationService->sendDefault($customerNotifications, $appointment->toArray());
140
141 /** @var Notification $customerNotification */
142 foreach ($customerNotifications->getItems() as $customerNotification) {
143 if (
144 $customerNotification->getStatus()->getValue() === NotificationStatus::ENABLED &&
145 $notificationService->checkCustom(
146 $customerNotification,
147 $appointment->toArray(),
148 $sendDefault
149 ) && $notifyCustomers
150 ) {
151 if (
152 $customerNotification->getContent() &&
153 $customerNotification->getContent()->getValue() &&
154 strpos($customerNotification->getContent()->getValue(), '%payment_link_') !== false
155 ) {
156 $this->setPaymentLink($appointment, $bookingKey);
157 }
158
159 $notificationService->sendNotification(
160 array_merge(
161 $appointment->toArray(),
162 [
163 'bookings' => $bookings->toArray(),
164 'isBackend' => $isBackend,
165 ]
166 ),
167 $customerNotification,
168 $logNotification,
169 $bookingKey,
170 null,
171 (
172 $sendInvoice &&
173 $booking->getPayments()->length() &&
174 $booking->getPayments()->keyExists(0) &&
175 $booking->getStatus()->getValue() !== BookingStatus::WAITING
176 )
177 ? $invoiceService->generateInvoice(
178 $booking->getPayments()->getItem(0)->getId()->getValue()
179 )
180 : null
181 );
182 }
183 }
184 }
185 }
186 }
187
188 /**
189 * @param AbstractNotificationService $notificationService
190 * @param Appointment $appointment
191 * @param bool $notifyProvider
192 * @param bool $notifyCustomers
193 *
194 * @throws QueryExecutionException
195 * @throws InvalidArgumentException
196 * @throws NotFoundException
197 */
198 public function sendRescheduledNotifications(
199 $notificationService,
200 $appointment,
201 $notifyProvider = true,
202 $notifyCustomers = true
203 ) {
204 if ($notifyProvider) {
205 /** @var Collection $providerNotifications */
206 $providerNotifications = $notificationService->getByNameAndType(
207 "provider_appointment_rescheduled",
208 $notificationService->getType()
209 );
210
211 $sendDefault = $notificationService->sendDefault($providerNotifications, $appointment->toArray());
212
213 /** @var Notification $providerNotification */
214 foreach ($providerNotifications->getItems() as $providerNotification) {
215 if (
216 $providerNotification->getStatus()->getValue() === NotificationStatus::ENABLED &&
217 $notificationService->checkCustom($providerNotification, $appointment->toArray(), $sendDefault)
218 ) {
219 $notificationService->sendNotification(
220 $appointment->toArray(),
221 $providerNotification,
222 true
223 );
224 }
225 }
226 }
227
228 if ($notifyCustomers && $appointment->isNotifyParticipants()) {
229 /** @var Collection $customerNotifications */
230 $customerNotifications = $notificationService->getByNameAndType(
231 "customer_appointment_rescheduled",
232 $notificationService->getType()
233 );
234
235 $sendDefault = $notificationService->sendDefault($customerNotifications, $appointment->toArray());
236
237 /** @var Notification $customerNotification */
238 foreach ($customerNotifications->getItems() as $customerNotification) {
239 if (
240 $customerNotification->getStatus()->getValue() === NotificationStatus::ENABLED &&
241 $notificationService->checkCustom($customerNotification, $appointment->toArray(), $sendDefault)
242 ) {
243 /** @var CustomerBooking $booking */
244 foreach ($appointment->getBookings()->getItems() as $bookingKey => $booking) {
245 if (
246 (!$booking->isNew() || !$booking->isNew()->getValue()) &&
247 (
248 $booking->getStatus()->getValue() === BookingStatus::APPROVED ||
249 $booking->getStatus()->getValue() === BookingStatus::PENDING
250 )
251 ) {
252 if (
253 $customerNotification->getContent() &&
254 $customerNotification->getContent()->getValue() &&
255 strpos($customerNotification->getContent()->getValue(), '%payment_link_') !== false
256 ) {
257 $this->setPaymentLink($appointment, $bookingKey);
258 }
259
260 $notificationService->sendNotification(
261 $appointment->toArray(),
262 $customerNotification,
263 true,
264 $bookingKey
265 );
266 }
267 }
268 }
269 }
270 }
271 }
272
273 /**
274 * Send waiting list available spot notifications.
275 * Triggered when a booking for an approved appointment is canceled and there are waiting bookings.
276 * Sends one notification to provider and one to each waiting customer.
277 *
278 * @param AbstractNotificationService $notificationService
279 * @param Appointment $appointment
280 * @param Collection $waitingBookings Collection of CustomerBooking objects with status 'waiting'
281 *
282 * @throws InvalidArgumentException
283 * @throws QueryExecutionException
284 */
285 public function sendWaitingListAvailableSpotNotification(
286 $notificationService,
287 $appointment,
288 $waitingBookings
289 ) {
290 if (!$waitingBookings->length()) {
291 return;
292 }
293
294 // Provider notification (single)
295 /** @var Collection $providerNotifications */
296 $providerNotifications = $notificationService->getByNameAndType(
297 'provider_appointment_waiting_available_spot',
298 $notificationService->getType()
299 );
300 $sendDefaultProvider = $notificationService->sendDefault($providerNotifications, $appointment->toArray());
301 foreach ($providerNotifications->getItems() as $providerNotification) {
302 if (
303 $providerNotification->getStatus()->getValue() === NotificationStatus::ENABLED &&
304 $notificationService->checkCustom($providerNotification, $appointment->toArray(), $sendDefaultProvider)
305 ) {
306 $notificationService->sendNotification(
307 $appointment->toArray(),
308 $providerNotification,
309 true
310 );
311 }
312 }
313
314 // Customer notifications (each waiting booking)
315 /** @var Collection $customerNotifications */
316 $customerNotifications = $notificationService->getByNameAndType(
317 'customer_appointment_waiting_available_spot',
318 $notificationService->getType()
319 );
320 $sendDefaultCustomer = $notificationService->sendDefault($customerNotifications, $appointment->toArray());
321 foreach ($customerNotifications->getItems() as $customerNotification) {
322 if (
323 $customerNotification->getStatus()->getValue() === NotificationStatus::ENABLED &&
324 $notificationService->checkCustom($customerNotification, $appointment->toArray(), $sendDefaultCustomer)
325 ) {
326 foreach ($waitingBookings->getItems() as $waitingBooking) {
327 $bookingKey = null;
328 foreach ($appointment->getBookings()->getItems() as $appBookingKey => $appBooking) {
329 if ($appBooking->getId()->getValue() === $waitingBooking->getId()->getValue()) {
330 $bookingKey = $appBookingKey;
331 break;
332 }
333 }
334 if ($bookingKey !== null) {
335 $notificationService->sendNotification(
336 array_merge($appointment->toArray(), [
337 'bookings' => $appointment->getBookings()->toArray(),
338 ]),
339 $customerNotification,
340 true,
341 $bookingKey
342 );
343 }
344 }
345 }
346 }
347 }
348
349 /**
350 * @param AbstractNotificationService $notificationService
351 * @param Appointment $appointment
352 * @param bool $notifyProvider
353 * @param bool $notifyCustomers
354 *
355 * @throws QueryExecutionException
356 * @throws InvalidArgumentException
357 */
358 public function sendUpdatedNotifications(
359 $notificationService,
360 $appointment,
361 $notifyProvider,
362 $notifyCustomers
363 ) {
364 if ($notifyProvider) {
365 /** @var Collection $providerNotifications */
366 $providerNotifications = $notificationService->getByNameAndType(
367 "provider_appointment_updated",
368 $notificationService->getType()
369 );
370
371 $sendDefault = $notificationService->sendDefault($providerNotifications, $appointment->toArray());
372
373 /** @var Notification $providerNotification */
374 foreach ($providerNotifications->getItems() as $providerNotification) {
375 if (
376 $providerNotification->getStatus()->getValue() === NotificationStatus::ENABLED &&
377 $notificationService->checkCustom($providerNotification, $appointment->toArray(), $sendDefault)
378 ) {
379 $appointmentArray = $appointment->toArray();
380 $appointmentArray['sendForAllBookings'] = true;
381
382 $notificationService->sendNotification(
383 $appointmentArray,
384 $providerNotification,
385 true
386 );
387 }
388 }
389 }
390
391 if ($notifyCustomers && $appointment->isNotifyParticipants()) {
392 /** @var Collection $customerNotifications */
393 $customerNotifications = $notificationService->getByNameAndType(
394 "customer_appointment_updated",
395 $notificationService->getType()
396 );
397
398 $sendDefault = $notificationService->sendDefault($customerNotifications, $appointment->toArray());
399
400 /** @var Notification $customerNotification */
401 foreach ($customerNotifications->getItems() as $customerNotification) {
402 if (
403 $customerNotification->getStatus()->getValue() === NotificationStatus::ENABLED &&
404 $notificationService->checkCustom($customerNotification, $appointment->toArray(), $sendDefault)
405 ) {
406 /** @var CustomerBooking $booking */
407 foreach ($appointment->getBookings()->getItems() as $bookingKey => $booking) {
408 if (
409 $booking->getStatus()->getValue() === BookingStatus::APPROVED &&
410 (!$booking->isNew() || !$booking->isNew()->getValue()) &&
411 $booking->isUpdated() &&
412 $booking->isUpdated()->getValue()
413 ) {
414 $notificationService->sendNotification(
415 $appointment->toArray(),
416 $customerNotification,
417 true,
418 $bookingKey
419 );
420 }
421 }
422 }
423 }
424 }
425 }
426
427 /**
428 * @param AbstractNotificationService $notificationService
429 * @param Event $event
430 * @param bool $logNotification
431 * @param int $bookingKey
432 *
433 *
434 * @throws InvalidArgumentException
435 * @throws QueryExecutionException
436 */
437 public function sendQrNotifications(
438 $notificationService,
439 $event,
440 $bookingKey,
441 $logNotification = true
442 ) {
443 $notifications = $notificationService->getByNameAndType(
444 "customer_event_qr_code",
445 $notificationService->getType()
446 );
447
448 $qrNotification = $notifications->getItem($notifications->keys()[0]);
449
450 if ($qrNotification->getStatus()->getValue() === NotificationStatus::ENABLED) {
451 $notificationService->sendNotification(
452 $event->toArray(),
453 $qrNotification,
454 $logNotification,
455 $bookingKey
456 );
457 }
458 }
459
460 /**
461 * @param Appointment $appointment
462 * @param int $bookingKey
463 *
464 *
465 * @throws InvalidArgumentException
466 * @throws QueryExecutionException
467 * @throws NotFoundException
468 */
469 private function setPaymentLink($appointment, $bookingKey)
470 {
471 /** @var CustomerBooking $booking */
472 $booking = $appointment->getBookings()->getItem($bookingKey);
473
474 /** @var Payment $payment */
475 $payment = $booking->getPayments() && $booking->getPayments()->keyExists(0)
476 ? $booking->getPayments()->getItem(0)
477 : null;
478
479 if ($payment && $payment->getId() && !$payment->getPaymentLinks()) {
480 /** @var PaymentApplicationService $paymentAS */
481 $paymentAS = $this->container->get('application.payment.service');
482
483 /** @var ServiceRepository $serviceRepository */
484 $serviceRepository = $this->container->get('domain.bookable.service.repository');
485
486 /** @var CustomerRepository $customerRepository */
487 $customerRepository = $this->container->get('domain.users.customers.repository');
488
489 /** @var Service $service */
490 $service = $appointment->getService() ?: $serviceRepository->getById($appointment->getServiceId()->getValue());
491
492 /** @var Customer $customer */
493 $customer = $booking->getCustomer() ?: $customerRepository->getById($booking->getCustomerId()->getValue());
494
495 $payment->setPaymentLinks(
496 $paymentAS->createPaymentLink(
497 [
498 'type' => Entities::APPOINTMENT,
499 'booking' => $booking->toArray(),
500 'appointment' => $appointment->toArray(),
501 'paymentId' => $payment->getId()->getValue(),
502 'bookable' => $service->toArray(),
503 'customer' => $customer->toArray(),
504 ],
505 $bookingKey
506 )
507 );
508 }
509 }
510 }
511