PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 2.2
Booking for Appointments and Events Calendar – Amelia v2.2
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 3 months ago AbstractWhatsAppNotificationService.php 4 months ago ApplicationNotificationService.php 4 months ago AppointmentNotificationService.php 4 months ago BasicWhatsAppNotificationService.php 6 months ago EmailNotificationService.php 6 months ago NotificationHelperService.php 6 months ago SMSAPIService.php 4 months ago SMSNotificationService.php 3 months ago
AppointmentNotificationService.php
502 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 */
197 public function sendRescheduledNotifications(
198 $notificationService,
199 $appointment,
200 $notifyProvider = true,
201 $notifyCustomers = true
202 ) {
203 if ($notifyProvider) {
204 /** @var Collection $providerNotifications */
205 $providerNotifications = $notificationService->getByNameAndType(
206 "provider_appointment_rescheduled",
207 $notificationService->getType()
208 );
209
210 $sendDefault = $notificationService->sendDefault($providerNotifications, $appointment->toArray());
211
212 /** @var Notification $providerNotification */
213 foreach ($providerNotifications->getItems() as $providerNotification) {
214 if (
215 $providerNotification->getStatus()->getValue() === NotificationStatus::ENABLED &&
216 $notificationService->checkCustom($providerNotification, $appointment->toArray(), $sendDefault)
217 ) {
218 $notificationService->sendNotification(
219 $appointment->toArray(),
220 $providerNotification,
221 true
222 );
223 }
224 }
225 }
226
227 if ($notifyCustomers && $appointment->isNotifyParticipants()) {
228 /** @var Collection $customerNotifications */
229 $customerNotifications = $notificationService->getByNameAndType(
230 "customer_appointment_rescheduled",
231 $notificationService->getType()
232 );
233
234 $sendDefault = $notificationService->sendDefault($customerNotifications, $appointment->toArray());
235
236 /** @var Notification $customerNotification */
237 foreach ($customerNotifications->getItems() as $customerNotification) {
238 if (
239 $customerNotification->getStatus()->getValue() === NotificationStatus::ENABLED &&
240 $notificationService->checkCustom($customerNotification, $appointment->toArray(), $sendDefault)
241 ) {
242 /** @var CustomerBooking $booking */
243 foreach ($appointment->getBookings()->getItems() as $bookingKey => $booking) {
244 if (
245 (!$booking->isNew() || !$booking->isNew()->getValue()) &&
246 (
247 $booking->getStatus()->getValue() === BookingStatus::APPROVED ||
248 $booking->getStatus()->getValue() === BookingStatus::PENDING
249 )
250 ) {
251 $notificationService->sendNotification(
252 $appointment->toArray(),
253 $customerNotification,
254 true,
255 $bookingKey
256 );
257 }
258 }
259 }
260 }
261 }
262 }
263
264 /**
265 * Send waiting list available spot notifications.
266 * Triggered when a booking for an approved appointment is canceled and there are waiting bookings.
267 * Sends one notification to provider and one to each waiting customer.
268 *
269 * @param AbstractNotificationService $notificationService
270 * @param Appointment $appointment
271 * @param Collection $waitingBookings Collection of CustomerBooking objects with status 'waiting'
272 *
273 * @throws InvalidArgumentException
274 * @throws QueryExecutionException
275 */
276 public function sendWaitingListAvailableSpotNotification(
277 $notificationService,
278 $appointment,
279 $waitingBookings
280 ) {
281 if (!$waitingBookings->length()) {
282 return;
283 }
284
285 // Provider notification (single)
286 /** @var Collection $providerNotifications */
287 $providerNotifications = $notificationService->getByNameAndType(
288 'provider_appointment_waiting_available_spot',
289 $notificationService->getType()
290 );
291 $sendDefaultProvider = $notificationService->sendDefault($providerNotifications, $appointment->toArray());
292 foreach ($providerNotifications->getItems() as $providerNotification) {
293 if (
294 $providerNotification->getStatus()->getValue() === NotificationStatus::ENABLED &&
295 $notificationService->checkCustom($providerNotification, $appointment->toArray(), $sendDefaultProvider)
296 ) {
297 $notificationService->sendNotification(
298 $appointment->toArray(),
299 $providerNotification,
300 true
301 );
302 }
303 }
304
305 // Customer notifications (each waiting booking)
306 /** @var Collection $customerNotifications */
307 $customerNotifications = $notificationService->getByNameAndType(
308 'customer_appointment_waiting_available_spot',
309 $notificationService->getType()
310 );
311 $sendDefaultCustomer = $notificationService->sendDefault($customerNotifications, $appointment->toArray());
312 foreach ($customerNotifications->getItems() as $customerNotification) {
313 if (
314 $customerNotification->getStatus()->getValue() === NotificationStatus::ENABLED &&
315 $notificationService->checkCustom($customerNotification, $appointment->toArray(), $sendDefaultCustomer)
316 ) {
317 foreach ($waitingBookings->getItems() as $waitingBooking) {
318 $bookingKey = null;
319 foreach ($appointment->getBookings()->getItems() as $appBookingKey => $appBooking) {
320 if ($appBooking->getId()->getValue() === $waitingBooking->getId()->getValue()) {
321 $bookingKey = $appBookingKey;
322 break;
323 }
324 }
325 if ($bookingKey !== null) {
326 $notificationService->sendNotification(
327 array_merge($appointment->toArray(), [
328 'bookings' => $appointment->getBookings()->toArray(),
329 ]),
330 $customerNotification,
331 true,
332 $bookingKey
333 );
334 }
335 }
336 }
337 }
338 }
339
340 /**
341 * @param AbstractNotificationService $notificationService
342 * @param Appointment $appointment
343 * @param bool $notifyProvider
344 * @param bool $notifyCustomers
345 *
346 * @throws QueryExecutionException
347 * @throws InvalidArgumentException
348 */
349 public function sendUpdatedNotifications(
350 $notificationService,
351 $appointment,
352 $notifyProvider,
353 $notifyCustomers
354 ) {
355 if ($notifyProvider) {
356 /** @var Collection $providerNotifications */
357 $providerNotifications = $notificationService->getByNameAndType(
358 "provider_appointment_updated",
359 $notificationService->getType()
360 );
361
362 $sendDefault = $notificationService->sendDefault($providerNotifications, $appointment->toArray());
363
364 /** @var Notification $providerNotification */
365 foreach ($providerNotifications->getItems() as $providerNotification) {
366 if (
367 $providerNotification->getStatus()->getValue() === NotificationStatus::ENABLED &&
368 $notificationService->checkCustom($providerNotification, $appointment->toArray(), $sendDefault)
369 ) {
370 $appointmentArray = $appointment->toArray();
371 $appointmentArray['sendForAllBookings'] = true;
372
373 $notificationService->sendNotification(
374 $appointmentArray,
375 $providerNotification,
376 true
377 );
378 }
379 }
380 }
381
382 if ($notifyCustomers && $appointment->isNotifyParticipants()) {
383 /** @var Collection $customerNotifications */
384 $customerNotifications = $notificationService->getByNameAndType(
385 "customer_appointment_updated",
386 $notificationService->getType()
387 );
388
389 $sendDefault = $notificationService->sendDefault($customerNotifications, $appointment->toArray());
390
391 /** @var Notification $customerNotification */
392 foreach ($customerNotifications->getItems() as $customerNotification) {
393 if (
394 $customerNotification->getStatus()->getValue() === NotificationStatus::ENABLED &&
395 $notificationService->checkCustom($customerNotification, $appointment->toArray(), $sendDefault)
396 ) {
397 /** @var CustomerBooking $booking */
398 foreach ($appointment->getBookings()->getItems() as $bookingKey => $booking) {
399 if (
400 $booking->getStatus()->getValue() === BookingStatus::APPROVED &&
401 (!$booking->isNew() || !$booking->isNew()->getValue()) &&
402 $booking->isUpdated() &&
403 $booking->isUpdated()->getValue()
404 ) {
405 $notificationService->sendNotification(
406 $appointment->toArray(),
407 $customerNotification,
408 true,
409 $bookingKey
410 );
411 }
412 }
413 }
414 }
415 }
416 }
417
418 /**
419 * @param AbstractNotificationService $notificationService
420 * @param Event $event
421 * @param bool $logNotification
422 * @param int $bookingKey
423 *
424 *
425 * @throws InvalidArgumentException
426 * @throws QueryExecutionException
427 */
428 public function sendQrNotifications(
429 $notificationService,
430 $event,
431 $bookingKey,
432 $logNotification = true
433 ) {
434 $notifications = $notificationService->getByNameAndType(
435 "customer_event_qr_code",
436 $notificationService->getType()
437 );
438
439 $qrNotification = $notifications->getItem($notifications->keys()[0]);
440
441 if ($qrNotification->getStatus()->getValue() === NotificationStatus::ENABLED) {
442 $notificationService->sendNotification(
443 $event->toArray(),
444 $qrNotification,
445 $logNotification,
446 $bookingKey
447 );
448 }
449 }
450
451 /**
452 * @param Appointment $appointment
453 * @param int $bookingKey
454 *
455 *
456 * @throws InvalidArgumentException
457 * @throws QueryExecutionException
458 * @throws NotFoundException
459 */
460 private function setPaymentLink($appointment, $bookingKey)
461 {
462 /** @var CustomerBooking $booking */
463 $booking = $appointment->getBookings()->getItem($bookingKey);
464
465 /** @var Payment $payment */
466 $payment = $booking->getPayments() && $booking->getPayments()->keyExists(0)
467 ? $booking->getPayments()->getItem(0)
468 : null;
469
470 if ($payment && $payment->getId() && !$payment->getPaymentLinks()) {
471 /** @var PaymentApplicationService $paymentAS */
472 $paymentAS = $this->container->get('application.payment.service');
473
474 /** @var ServiceRepository $serviceRepository */
475 $serviceRepository = $this->container->get('domain.bookable.service.repository');
476
477 /** @var CustomerRepository $customerRepository */
478 $customerRepository = $this->container->get('domain.users.customers.repository');
479
480 /** @var Service $service */
481 $service = $appointment->getService() ?: $serviceRepository->getById($appointment->getServiceId()->getValue());
482
483 /** @var Customer $customer */
484 $customer = $booking->getCustomer() ?: $customerRepository->getById($booking->getCustomerId()->getValue());
485
486 $payment->setPaymentLinks(
487 $paymentAS->createPaymentLink(
488 [
489 'type' => Entities::APPOINTMENT,
490 'booking' => $booking->toArray(),
491 'appointment' => $appointment->toArray(),
492 'paymentId' => $payment->getId()->getValue(),
493 'bookable' => $service->toArray(),
494 'customer' => $customer->toArray(),
495 ],
496 $bookingKey
497 )
498 );
499 }
500 }
501 }
502