PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 1.2.31
Booking for Appointments and Events Calendar – Amelia v1.2.31
2.4.9 2.4.8 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 / Infrastructure / Repository / Booking / Appointment / CustomerBookingRepository.php
ameliabooking / src / Infrastructure / Repository / Booking / Appointment Last commit date
AppointmentRepository.php 1 year ago CustomerBookingExtraRepository.php 1 year ago CustomerBookingRepository.php 1 year ago
CustomerBookingRepository.php
1053 lines
1 <?php
2
3 namespace AmeliaBooking\Infrastructure\Repository\Booking\Appointment;
4
5 use AmeliaBooking\Domain\Collection\Collection;
6 use AmeliaBooking\Domain\Common\Exceptions\InvalidArgumentException;
7 use AmeliaBooking\Domain\Entity\Booking\Appointment\CustomerBooking;
8 use AmeliaBooking\Domain\Factory\Booking\Appointment\CustomerBookingFactory;
9 use AmeliaBooking\Domain\Repository\Booking\Appointment\CustomerBookingRepositoryInterface;
10 use AmeliaBooking\Domain\Services\DateTime\DateTimeService;
11 use AmeliaBooking\Infrastructure\Common\Exceptions\QueryExecutionException;
12 use AmeliaBooking\Infrastructure\Repository\AbstractRepository;
13 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Booking\AppointmentsTable;
14 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Booking\CustomerBookingsToEventsPeriodsTable;
15 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Booking\CustomerBookingToEventsTicketsTable;
16 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Booking\EventsPeriodsTable;
17 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Booking\EventsProvidersTable;
18 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Booking\EventsTable;
19 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Booking\EventsTicketsTable;
20 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Coupon\CouponsTable;
21 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Payment\PaymentsTable;
22 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\User\UsersTable;
23 use Exception;
24
25 /**
26 * Class CustomerBookingRepository
27 *
28 * @package AmeliaBooking\Infrastructure\Repository\Booking\Appointment
29 */
30 class CustomerBookingRepository extends AbstractRepository implements CustomerBookingRepositoryInterface
31 {
32 public const FACTORY = CustomerBookingFactory::class;
33
34 /**
35 * @param CustomerBooking $entity
36 *
37 * @return mixed
38 * @throws QueryExecutionException
39 */
40 public function add($entity)
41 {
42 $data = $entity->toArray();
43
44 $couponId = !empty($data['coupon']) ? $data['coupon']['id'] : null;
45 if (!$couponId && !empty($data['couponId'])) {
46 $couponId = $data['couponId'];
47 }
48
49 $params = [
50 ':appointmentId' => $data['appointmentId'],
51 ':customerId' => $data['customerId'],
52 ':status' => $data['status'],
53 ':price' => $data['price'],
54 ':tax' => !empty($data['tax']) ? json_encode($data['tax']) : null,
55 ':persons' => $data['persons'],
56 ':couponId' => $couponId,
57 ':token' => $data['token'],
58 ':customFields' => $data['customFields'] && json_decode($data['customFields']) !== false ?
59 $data['customFields'] : null,
60 ':info' => $data['info'],
61 ':aggregatedPrice' => $data['aggregatedPrice'] ? 1 : 0,
62 ':utcOffset' => $data['utcOffset'],
63 ':packageCustomerServiceId' => !empty($data['packageCustomerService']['id']) ?
64 $data['packageCustomerService']['id'] : null,
65 ':duration' => !empty($data['duration']) ? $data['duration'] : null,
66 ':created' => !empty($data['created']) ?
67 DateTimeService::getCustomDateTimeInUtc($data['created']) : DateTimeService::getNowDateTimeInUtc(),
68 ':actionsCompleted' => $data['actionsCompleted'] ? 1 : 0,
69 ];
70
71 try {
72 $statement = $this->connection->prepare(
73 "INSERT INTO {$this->table}
74 (
75 `appointmentId`,
76 `customerId`,
77 `status`,
78 `price`,
79 `tax`,
80 `persons`,
81 `couponId`,
82 `token`,
83 `customFields`,
84 `info`,
85 `aggregatedPrice`,
86 `utcOffset`,
87 `packageCustomerServiceId`,
88 `duration`,
89 `created`,
90 `actionsCompleted`
91 )
92 VALUES (
93 :appointmentId,
94 :customerId,
95 :status,
96 :price,
97 :tax,
98 :persons,
99 :couponId,
100 :token,
101 :customFields,
102 :info,
103 :aggregatedPrice,
104 :utcOffset,
105 :packageCustomerServiceId,
106 :duration,
107 :created,
108 :actionsCompleted
109 )"
110 );
111
112 $res = $statement->execute($params);
113
114 if (!$res) {
115 throw new QueryExecutionException('Unable to add data in ' . __CLASS__);
116 }
117
118 return $this->connection->lastInsertId();
119 } catch (Exception $e) {
120 throw new QueryExecutionException('Unable to add data in ' . __CLASS__, $e->getCode(), $e);
121 }
122 }
123
124 /**
125 * @param int $id
126 * @param CustomerBooking $entity
127 *
128 * @return mixed
129 * @throws QueryExecutionException
130 */
131 public function update($id, $entity)
132 {
133 $data = $entity->toArray();
134
135 $params = [
136 ':id' => $id,
137 ':customerId' => $data['customerId'],
138 ':status' => $data['status'],
139 ':duration' => !empty($data['duration']) ? $data['duration'] : null,
140 ':persons' => $data['persons'],
141 ':couponId' => !empty($data['coupon']) ? $data['coupon']['id'] : null,
142 ':customFields' => $data['customFields'],
143 ];
144
145 try {
146 $statement = $this->connection->prepare(
147 "UPDATE {$this->table} SET
148 `customerId` = :customerId,
149 `status` = :status,
150 `duration` = :duration,
151 `persons` = :persons,
152 `couponId` = :couponId,
153 `customFields` = :customFields
154 WHERE id = :id"
155 );
156
157 $res = $statement->execute($params);
158
159 if (!$res) {
160 throw new QueryExecutionException('Unable to save data in ' . __CLASS__);
161 }
162
163 return $res;
164 } catch (Exception $e) {
165 throw new QueryExecutionException('Unable to save data in ' . __CLASS__, $e->getCode(), $e);
166 }
167 }
168
169 /**
170 * @param int $id
171 * @param CustomerBooking $entity
172 *
173 * @return mixed
174 * @throws QueryExecutionException
175 */
176 public function updatePrice($id, $entity)
177 {
178 $data = $entity->toArray();
179
180 $params = [
181 ':id' => $id,
182 ':price' => $data['price'],
183 ];
184
185 try {
186 $statement = $this->connection->prepare(
187 "UPDATE {$this->table} SET
188 `price` = :price
189 WHERE id = :id"
190 );
191
192 $res = $statement->execute($params);
193
194 if (!$res) {
195 throw new QueryExecutionException('Unable to save data in ' . __CLASS__);
196 }
197
198 return $res;
199 } catch (Exception $e) {
200 throw new QueryExecutionException('Unable to save data in ' . __CLASS__, $e->getCode(), $e);
201 }
202 }
203
204 /**
205 * @param int $id
206 * @param CustomerBooking $entity
207 *
208 * @return bool
209 * @throws QueryExecutionException
210 */
211 public function updateTax($id, $entity)
212 {
213 $data = $entity->toArray();
214
215 $params = [
216 ':id' => $id,
217 ':tax' => !empty($data['tax']) ? (is_array($data['tax']) ? json_encode($data['tax']) : $data['tax']) : null,
218 ];
219
220 try {
221 $statement = $this->connection->prepare(
222 "UPDATE {$this->table} SET
223 `tax` = :tax
224 WHERE id = :id"
225 );
226
227 $res = $statement->execute($params);
228
229 if (!$res) {
230 throw new QueryExecutionException('Unable to save data in ' . __CLASS__);
231 }
232
233 return $res;
234 } catch (Exception $e) {
235 throw new QueryExecutionException('Unable to save data in ' . __CLASS__, $e->getCode(), $e);
236 }
237 }
238
239 /**
240 * @param int $id
241 * @param int $status
242 *
243 * @return mixed
244 * @throws QueryExecutionException
245 */
246 public function updateStatusByAppointmentId($id, $status)
247 {
248 $params = [
249 ':appointmentId' => $id,
250 ':status' => $status
251 ];
252
253 try {
254 $statement = $this->connection->prepare(
255 "UPDATE {$this->table} SET
256 `status` = :status
257 WHERE appointmentId = :appointmentId"
258 );
259
260 $res = $statement->execute($params);
261
262 if (!$res) {
263 throw new QueryExecutionException('Unable to save data in ' . __CLASS__);
264 }
265
266 return $res;
267 } catch (Exception $e) {
268 throw new QueryExecutionException('Unable to save data in ' . __CLASS__, $e->getCode(), $e);
269 }
270 }
271
272 /**
273 * @param int $id
274 * @param int $status
275 *
276 * @return mixed
277 * @throws QueryExecutionException
278 */
279 public function updateStatusById($id, $status)
280 {
281 $params = [
282 ':id' => $id,
283 ':status' => $status
284 ];
285
286 try {
287 $statement = $this->connection->prepare(
288 "UPDATE {$this->table} SET
289 `status` = :status
290 WHERE id = :id"
291 );
292
293 $res = $statement->execute($params);
294
295 if (!$res) {
296 throw new QueryExecutionException('Unable to save data in ' . __CLASS__);
297 }
298
299 return $res;
300 } catch (Exception $e) {
301 throw new QueryExecutionException('Unable to save data in ' . __CLASS__, $e->getCode(), $e);
302 }
303 }
304
305 /**
306 * Returns an array of Customers Id's who have at least one booking until passed date
307 *
308 * @param $criteria
309 *
310 * @return array
311 * @throws QueryExecutionException
312 * @throws InvalidArgumentException
313 */
314 public function getReturningCustomers($criteria)
315 {
316 $appointmentTable = AppointmentsTable::getTableName();
317
318 $params = [];
319
320 $where = [];
321
322 if ($criteria['dates']) {
323 $where[] = "(a.bookingStart < :bookingFrom)";
324
325 $params[':bookingFrom'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
326 }
327
328 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
329
330 try {
331 $statement = $this->connection->prepare(
332 "SELECT
333 customerId,
334 COUNT(*) AS occurrences
335 FROM {$this->table} cb
336 INNER JOIN {$appointmentTable} a ON a.id = cb.appointmentId
337 $where
338 GROUP BY customerId"
339 );
340
341 $statement->execute($params);
342
343 $rows = $statement->fetchAll();
344 } catch (Exception $e) {
345 throw new QueryExecutionException('Unable to return customer bookings from' . __CLASS__, $e->getCode(), $e);
346 }
347
348 return $rows;
349 }
350
351 /**
352 * Returns an array of Customers Id's bookings in selected period
353 *
354 * @param $criteria
355 *
356 * @return array
357 * @throws QueryExecutionException
358 * @throws InvalidArgumentException
359 */
360 public function getFilteredDistinctCustomersIds($criteria)
361 {
362 $appointmentTable = AppointmentsTable::getTableName();
363
364 $params = [];
365
366 $where = [];
367
368 if ($criteria['dates']) {
369 $where[] = "(a.bookingStart BETWEEN :bookingFrom AND :bookingTo)";
370
371 $params[':bookingFrom'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
372
373 $params[':bookingTo'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][1]);
374 }
375
376 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
377
378 try {
379 $statement = $this->connection->prepare(
380 "SELECT DISTINCT
381 cb.customerId
382 FROM {$this->table} cb
383 INNER JOIN {$appointmentTable} a ON a.id = cb.appointmentId
384 $where"
385 );
386
387 $statement->execute($params);
388
389 $rows = $statement->fetchAll();
390 } catch (Exception $e) {
391 throw new QueryExecutionException('Unable to return customer bookings from' . __CLASS__, $e->getCode(), $e);
392 }
393
394 return $rows;
395 }
396
397 /**
398 * Returns token for given id
399 *
400 * @param $id
401 *
402 * @return array
403 * @throws QueryExecutionException
404 */
405 public function getToken($id)
406 {
407 try {
408 $statement = $this->connection->prepare(
409 "SELECT cb.token
410 FROM {$this->table} cb
411 WHERE cb.id = :id"
412 );
413
414 $statement->execute([':id' => $id]);
415
416 $row = $statement->fetch();
417 } catch (Exception $e) {
418 throw new QueryExecutionException('Unable to return customer booking from' . __CLASS__, $e->getCode(), $e);
419 }
420
421 return $row;
422 }
423
424 /**
425 * Returns tokens for given event id
426 *
427 * @param $id
428 *
429 * @return array
430 * @throws QueryExecutionException
431 * @throws InvalidArgumentException
432 */
433 public function getTokensByEventId($id)
434 {
435 $eventsPeriodsTable = EventsPeriodsTable::getTableName();
436
437 $customerBookingsEventsPeriods = CustomerBookingsToEventsPeriodsTable::getTableName();
438
439 try {
440 $statement = $this->connection->prepare(
441 "SELECT
442 cb.id, cb.token
443 FROM {$this->table} cb
444 INNER JOIN {$customerBookingsEventsPeriods} cbep ON cbep.customerBookingId = cb.id
445 INNER JOIN {$eventsPeriodsTable} ep ON ep.id = cbep.eventPeriodId
446 WHERE ep.eventId = :id"
447 );
448
449 $statement->execute([':id' => $id]);
450
451 $rows = $statement->fetchAll();
452 } catch (Exception $e) {
453 throw new QueryExecutionException('Unable to return customer booking from' . __CLASS__, $e->getCode(), $e);
454 }
455
456 return $rows;
457 }
458
459 /**
460 * @param int $customerId
461 * @param string $info
462 *
463 * @return mixed
464 * @throws QueryExecutionException
465 */
466 public function updateInfoByCustomerId($customerId, $info)
467 {
468 $params = [
469 ':customerId' => $customerId,
470 ':info' => $info
471 ];
472
473 try {
474 $statement = $this->connection->prepare(
475 "UPDATE {$this->table} SET
476 `info` = :info
477 WHERE customerId = :customerId"
478 );
479
480 $res = $statement->execute($params);
481
482 if (!$res) {
483 throw new QueryExecutionException('Unable to save data in ' . __CLASS__);
484 }
485
486 return $res;
487 } catch (Exception $e) {
488 throw new QueryExecutionException('Unable to save data in ' . __CLASS__, $e->getCode(), $e);
489 }
490 }
491
492 /**
493 * @param int $id
494 *
495 * @return mixed
496 * @throws QueryExecutionException
497 * @throws InvalidArgumentException
498 */
499 public function getById($id)
500 {
501 $params = [
502 ':id' => $id,
503 ];
504
505 $paymentsTable = PaymentsTable::getTableName();
506
507 $usersTable = UsersTable::getTableName();
508
509 $couponsTable = CouponsTable::getTableName();
510
511 try {
512 $statement = $this->connection->prepare(
513 "SELECT
514 cb.id AS booking_id,
515 cb.appointmentId AS booking_appointmentId,
516 cb.customerId AS booking_customerId,
517 cb.status AS booking_status,
518 cb.price AS booking_price,
519 cb.persons AS booking_persons,
520 cb.couponId AS booking_couponId,
521 cb.customFields AS booking_customFields,
522 cb.info AS booking_info,
523 cb.utcOffset AS booking_utcOffset,
524 cb.aggregatedPrice AS booking_aggregatedPrice,
525 cb.duration AS booking_duration,
526 cb.created AS booking_created,
527
528 cu.id AS customer_id,
529 cu.firstName AS customer_firstName,
530 cu.lastName AS customer_lastName,
531 cu.email AS customer_email,
532 cu.note AS customer_note,
533 cu.phone AS customer_phone,
534 cu.gender AS customer_gender,
535 cu.birthday AS customer_birthday,
536
537 p.id AS payment_id,
538 p.amount AS payment_amount,
539 p.dateTime AS payment_dateTime,
540 p.status AS payment_status,
541 p.gateway AS payment_gateway,
542 p.gatewayTitle AS payment_gatewayTitle,
543 p.transactionId AS payment_transactionId,
544 p.data AS payment_data,
545
546 c.id AS coupon_id,
547 c.code AS coupon_code,
548 c.discount AS coupon_discount,
549 c.deduction AS coupon_deduction,
550 c.expirationDate AS coupon_expirationDate,
551 c.limit AS coupon_limit,
552 c.customerLimit AS coupon_customerLimit,
553 c.status AS coupon_status
554 FROM {$this->table} cb
555 INNER JOIN {$usersTable} cu ON cu.id = cb.customerId
556 LEFT JOIN {$couponsTable} c ON c.id = cb.couponId
557 LEFT JOIN {$paymentsTable} p ON p.customerBookingId = cb.id
558 WHERE cb.id = :id"
559 );
560
561 $statement->execute($params);
562
563 $rows = $statement->fetchAll();
564 } catch (Exception $e) {
565 throw new QueryExecutionException('Unable to find booking by id in ' . __CLASS__, $e->getCode(), $e);
566 }
567
568 $reformattedData = call_user_func([static::FACTORY, 'reformat'], $rows);
569
570 return !empty($reformattedData[$id]) ?
571 call_user_func([static::FACTORY, 'create'], $reformattedData[$id]) : null;
572 }
573
574 /**
575 * Returns a collection of bookings where actions on booking are not completed
576 *
577 * @return Collection
578 * @throws InvalidArgumentException
579 * @throws QueryExecutionException
580 * @throws \Exception
581 */
582 public function getUncompletedActionsForBookings()
583 {
584 $params = [];
585
586 $currentDateTime = "STR_TO_DATE('" . DateTimeService::getNowDateTimeInUtc() . "', '%Y-%m-%d %H:%i:%s')";
587
588 $pastDateTime =
589 "STR_TO_DATE('" .
590 DateTimeService::getNowDateTimeObjectInUtc()->modify('-1 day')->format('Y-m-d H:i:s') .
591 "', '%Y-%m-%d %H:%i:%s')";
592
593 try {
594 $statement = $this->connection->prepare(
595 "SELECT * FROM {$this->table}
596 WHERE
597 actionsCompleted = 0 AND
598 {$currentDateTime} > DATE_ADD(created, INTERVAL 300 SECOND) AND
599 {$pastDateTime} < created"
600 );
601
602 $statement->execute($params);
603
604 $rows = $statement->fetchAll();
605 } catch (\Exception $e) {
606 throw new QueryExecutionException('Unable to get data from ' . __CLASS__, $e->getCode(), $e);
607 }
608
609 $items = [];
610
611 foreach ($rows as $row) {
612 $items[] = call_user_func([static::FACTORY, 'create'], $row);
613 }
614
615 return new Collection($items);
616 }
617
618 /**
619 * @param array $ids
620 *
621 * @return array
622 * @throws QueryExecutionException
623 */
624 public function countByNoShowStatus($ids)
625 {
626 $idsString = implode(', ', $ids);
627
628 try {
629 $statement = $this->connection->prepare(
630 "SELECT customerId, COUNT(*) AS count
631 FROM {$this->table} cb
632 WHERE customerId IN ($idsString) AND status = 'no-show'
633 GROUP BY customerId"
634 );
635
636 $statement->execute();
637
638 $rows = $statement->fetchAll();
639
640 $result = [];
641 foreach ($ids as $id) {
642 $count = 0;
643 foreach ($rows as $row) {
644 if ($row['customerId'] == $id) {
645 $count = $row['count'];
646 break;
647 }
648 }
649 $result[] = [
650 'id' => $id,
651 'count' => $count,
652 ];
653 }
654 } catch (Exception $e) {
655 throw new QueryExecutionException('Unable to find booking by id in ' . __CLASS__, $e->getCode(), $e);
656 }
657
658 return $result;
659 }
660
661 /**
662 * @param array $criteria
663 *
664 * @return Collection
665 * @throws QueryExecutionException
666 * @throws InvalidArgumentException
667 */
668 public function getByCriteria($criteria)
669 {
670 try {
671 $params = [];
672
673 $where = [];
674
675 if (!empty($criteria['appointmentIds'])) {
676 $queryAppointments = [];
677
678 foreach ($criteria['appointmentIds'] as $index => $value) {
679 $param = ':appointmentId' . $index;
680
681 $queryAppointments[] = $param;
682
683 $params[$param] = $value;
684 }
685
686 $where[] = 'cb.appointmentId IN (' . implode(', ', $queryAppointments) . ')';
687 }
688
689 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
690
691 $statement = $this->connection->prepare(
692 "SELECT
693 cb.id AS id,
694 cb.appointmentId AS appointmentId,
695 cb.customerId AS customerId,
696 cb.status AS status,
697 cb.price AS price,
698 cb.tax AS tax,
699 cb.persons AS persons,
700 cb.customFields AS customFields,
701 cb.info AS info,
702 cb.aggregatedPrice AS aggregatedPrice,
703 cb.packageCustomerServiceId AS packageCustomerServiceId,
704 cb.duration AS duration,
705 cb.created AS created,
706 cb.tax AS tax
707 FROM {$this->table} cb
708 {$where}"
709 );
710
711 $statement->execute($params);
712
713 $rows = $statement->fetchAll();
714 } catch (\Exception $e) {
715 throw new QueryExecutionException('Unable to find by id in ' . __CLASS__, $e->getCode(), $e);
716 }
717
718 $result = new Collection();
719
720 foreach ($rows as $row) {
721 $result->addItem(
722 call_user_func([static::FACTORY, 'create'], $row),
723 $row['id']
724 );
725 }
726
727 return $result;
728 }
729
730 /**
731 * @param array $criteria
732 * @param int $itemsPerPageBackEnd
733 *
734 * @return array
735 * @throws QueryExecutionException
736 * @throws InvalidArgumentException
737 */
738 public function getEventBookingIdsByCriteria($criteria = [], $itemsPerPageBackEnd = 0)
739 {
740 $eventsPeriodsTable = EventsPeriodsTable::getTableName();
741 $customerBookingsEventsPeriods = CustomerBookingsToEventsPeriodsTable::getTableName();
742 $eventsTable = EventsTable::getTableName();
743 $eventProvidersTable = EventsProvidersTable::getTableName();
744
745 $params = [];
746
747 $where = [];
748
749 $joins = '';
750
751 if (!empty($criteria['customers'])) {
752 $queryIds = [];
753
754 foreach ($criteria['customers'] as $index => $value) {
755 $param = ':customerId' . $index;
756
757 $queryIds[] = $param;
758
759 $params[$param] = $value;
760 }
761
762 $where[] = '(cb.customerId IN (' . implode(', ', $queryIds) . '))';
763 }
764
765
766 if (!empty($criteria['dates'])) {
767 if (isset($criteria['dates'][0], $criteria['dates'][1])) {
768 $where[] = "(ep.periodStart BETWEEN :eventFrom AND :eventTo)";
769 $params[':eventFrom'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
770 $params[':eventTo'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][1]);
771 }
772 }
773
774 if (!empty($criteria['search'])) {
775 $params[':search1'] = $params[':search2'] = "%{$criteria['search']}%";
776
777 $where[] = '(e.name LIKE :search1 OR SUBSTR(cb.token, 1, 5) LIKE :search2)';
778 }
779
780 if (!empty($criteria['providers'])) {
781 $queryIds1 = [];
782 $queryIds2 = [];
783
784 foreach ($criteria['providers'] as $index => $value) {
785 $param1 = ':providerId' . $index;
786 $param2 = ':organizerId' . $index;
787
788 $queryIds1[] = $param1;
789 $queryIds2[] = $param2;
790
791 $params[$param1] = $value;
792 $params[$param2] = $value;
793 }
794
795 $where[] = '(epr.userId IN (' . implode(', ', $queryIds1) . ') OR e.organizerId IN (' . implode(', ', $queryIds2) . '))';
796
797 $joins .= "LEFT JOIN {$eventProvidersTable} epr ON epr.eventId = e.id";
798 }
799
800 if (!empty($criteria['statuses'])) {
801 $queryIds = [];
802
803 foreach ($criteria['statuses'] as $index => $value) {
804 $param = ':status' . $index;
805
806 $queryIds[] = $param;
807
808 $params[$param] = $value;
809 }
810
811 $where[] = '(cb.status IN (' . implode(', ', $queryIds) . '))';
812 }
813
814 if (!empty($criteria['events'])) {
815 $queryIds = [];
816
817 foreach ($criteria['events'] as $index => $value) {
818 $param = ':eventId' . $index;
819
820 $queryIds[] = $param;
821
822 $params[$param] = $value;
823 }
824
825 $where[] = '(e.id IN (' . implode(', ', $queryIds) . '))';
826 }
827
828 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
829
830 $groupBy = 'GROUP BY cb.id';
831 $limit = $this->getLimit(
832 !empty($criteria['page']) ? (int)$criteria['page'] : 0,
833 $itemsPerPageBackEnd
834 );
835
836 $orderBy = 'ORDER BY MIN(ep.periodStart), cb.id';
837
838 if (!empty($criteria['sort'])) {
839 $column = $criteria['sort'][0] === '-' ? substr($criteria['sort'], 1) : $criteria['sort'];
840 $orderColumn = '';
841 if ($column === 'attendee') {
842 $orderColumn = ', CONCAT(cu.firstName, " ", cu.lastName)';
843 } elseif ($column === 'event') {
844 $orderColumn = ', e.name';
845 }
846 $orderDir = $orderColumn ? ($criteria['sort'][0] === '-' ? 'DESC' : 'ASC') : '';
847 $orderBy = "ORDER BY MIN(DATE(ep.periodStart)) {$orderColumn} {$orderDir}, cb.id";
848 }
849
850 try {
851 $statement = $this->connection->prepare(
852 "SELECT cb.id
853 FROM {$this->table} cb
854 INNER JOIN {$customerBookingsEventsPeriods} cbe ON cbe.customerBookingId = cb.id
855 LEFT JOIN {$eventsPeriodsTable} ep ON ep.id = cbe.eventPeriodId
856 LEFT JOIN {$eventsTable} e ON e.id = ep.eventId
857
858 {$joins}
859 {$where}
860 {$groupBy}
861 {$orderBy}
862 {$limit}"
863 );
864
865 $statement->execute($params);
866
867 $rows = $statement->fetchAll(\PDO::FETCH_COLUMN);
868 } catch (\Exception $e) {
869 throw new QueryExecutionException('Unable to find event by id in ' . __CLASS__, $e->getCode(), $e);
870 }
871
872 return $rows;
873 }
874
875
876 /**
877 * @param array $criteria
878 *
879 * @return array
880 * @throws QueryExecutionException
881 * @throws InvalidArgumentException
882 */
883 public function getEventBookingsByIds($ids, $criteria)
884 {
885 $eventsPeriodsTable = EventsPeriodsTable::getTableName();
886 $customerBookingsEventsPeriods = CustomerBookingsToEventsPeriodsTable::getTableName();
887 $usersTable = UsersTable::getTableName();
888 $eventsTable = EventsTable::getTableName();
889 $eventProvidersTable = EventsProvidersTable::getTableName();
890 $bookingsTicketsTable = CustomerBookingToEventsTicketsTable::getTableName();
891
892 $params = [];
893
894 $where = [];
895
896 $fields = '';
897
898 $joins = '';
899
900 if (!empty($criteria['dates'])) {
901 if (isset($criteria['dates'][0], $criteria['dates'][1])) {
902 $where[] = "(ep.periodStart BETWEEN :eventFrom AND :eventTo)";
903 $params[':eventFrom'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
904 $params[':eventTo'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][1]);
905 }
906 }
907
908 if (!empty($ids)) {
909 $queryIds = [];
910
911 foreach ($ids as $index => $value) {
912 $param = ':id' . $index;
913
914 $queryIds[] = $param;
915
916 $params[$param] = $value;
917 }
918
919 $where[] = '(cb.id IN (' . implode(', ', $queryIds) . '))';
920 }
921
922 if (!empty($criteria['fetchBookingsCoupons'])) {
923 $couponsTable = CouponsTable::getTableName();
924
925 $fields .= '
926 c.id AS coupon_id,
927 c.code AS coupon_code,
928 c.discount AS coupon_discount,
929 c.deduction AS coupon_deduction,
930 c.limit AS coupon_limit,
931 c.customerLimit AS coupon_customerLimit,
932 c.status AS coupon_status,
933 ';
934
935 $joins .= "
936 LEFT JOIN {$couponsTable} c ON c.id = cb.couponId
937 ";
938 }
939
940 if (!empty($criteria['fetchBookingsPayments'])) {
941 $paymentsTable = PaymentsTable::getTableName();
942
943 $fields .= '
944 p.id AS payment_id,
945 p.amount AS payment_amount,
946 p.dateTime AS payment_dateTime,
947 p.status AS payment_status,
948 p.gateway AS payment_gateway,
949 p.gatewayTitle AS payment_gatewayTitle,
950 p.transactionId AS payment_transactionId,
951 p.data AS payment_data,
952 p.wcOrderId AS payment_wcOrderId,
953 p.wcOrderItemId AS payment_wcOrderItemId,
954 ';
955
956 $joins .= "
957 LEFT JOIN {$paymentsTable} p ON p.customerBookingId = cb.id
958 ";
959 }
960
961 if (!empty($criteria['fetchProviders'])) {
962 $fields .= '
963 pu.id AS provider_id,
964 pu.firstName AS provider_firstName,
965 pu.lastName AS provider_lastName,
966 pu.pictureThumbPath AS provider_pictureThumbPath,
967 ';
968 $joins .= "
969 LEFT JOIN {$eventProvidersTable} epr ON epr.eventId = e.id
970 LEFT JOIN {$usersTable} pu ON epr.userId = pu.id or pu.id = e.organizerId
971 ";
972 }
973
974 if (!empty($criteria['fetchCustomers'])) {
975 $fields .= '
976 cu.id AS customer_id,
977 cu.type AS customer_type,
978 cu.firstName AS customer_firstName,
979 cu.lastName AS customer_lastName,
980 cu.email AS customer_email,
981 cu.note AS customer_note,
982 cu.phone AS customer_phone,
983 cu.gender AS customer_gender,
984 cu.birthday AS customer_birthday,
985 ';
986
987 $joins .= "
988 INNER JOIN {$usersTable} cu ON cu.id = cb.customerId
989 ";
990 }
991
992
993 $fields .= '
994 cb.id AS booking_id,
995 cb.appointmentId AS booking_appointmentId,
996 cb.customerId AS booking_customerId,
997 cb.status AS booking_status,
998 cb.price AS booking_price,
999 cb.tax AS booking_tax,
1000 cb.persons AS booking_persons,
1001 cb.couponId AS booking_couponId,
1002 cb.customFields AS booking_customFields,
1003 cb.info AS booking_info,
1004 cb.utcOffset AS booking_utcOffset,
1005 cb.token AS booking_token,
1006 cb.aggregatedPrice AS booking_aggregatedPrice,
1007
1008 ep.id as event_periodId,
1009 ep.periodStart as event_periodStart,
1010 ep.zoomMeeting as event_zoomMeeting,
1011 ep.googleMeetUrl as event_googleMeetUrl,
1012
1013 cbt.id AS booking_ticket_id,
1014 cbt.eventTicketId AS booking_ticket_eventTicketId,
1015 cbt.price AS booking_ticket_price,
1016 cbt.persons AS booking_ticket_persons,
1017
1018 e.id AS event_id,
1019 e.name AS event_name,
1020 e.customPricing AS event_customPricing,
1021 e.status AS event_status,
1022 e.organizerId AS event_organizerId,
1023 e.settings AS event_settings
1024 ';
1025
1026 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
1027
1028 try {
1029 $statement = $this->connection->prepare(
1030 "SELECT
1031 {$fields}
1032 FROM {$this->table} cb
1033 INNER JOIN {$customerBookingsEventsPeriods} cbe ON cbe.customerBookingId = cb.id
1034 LEFT JOIN {$bookingsTicketsTable} cbt ON cbt.customerBookingId = cb.id
1035 LEFT JOIN {$eventsPeriodsTable} ep ON ep.id = cbe.eventPeriodId
1036 LEFT JOIN {$eventsTable} e ON e.id = ep.eventId
1037
1038 {$joins}
1039 {$where}
1040 "
1041 );
1042
1043 $statement->execute($params);
1044
1045 $rows = $statement->fetchAll();
1046 } catch (\Exception $e) {
1047 throw new QueryExecutionException('Unable to find event by id in ' . __CLASS__, $e->getCode(), $e);
1048 }
1049
1050 return CustomerBookingFactory::reformat($rows);
1051 }
1052 }
1053