PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 1.2.32
Booking for Appointments and Events Calendar – Amelia v1.2.32
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 10 months ago
CustomerBookingRepository.php
1054 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 cb.token AS booking_token,
528
529 cu.id AS customer_id,
530 cu.firstName AS customer_firstName,
531 cu.lastName AS customer_lastName,
532 cu.email AS customer_email,
533 cu.note AS customer_note,
534 cu.phone AS customer_phone,
535 cu.gender AS customer_gender,
536 cu.birthday AS customer_birthday,
537
538 p.id AS payment_id,
539 p.amount AS payment_amount,
540 p.dateTime AS payment_dateTime,
541 p.status AS payment_status,
542 p.gateway AS payment_gateway,
543 p.gatewayTitle AS payment_gatewayTitle,
544 p.transactionId AS payment_transactionId,
545 p.data AS payment_data,
546
547 c.id AS coupon_id,
548 c.code AS coupon_code,
549 c.discount AS coupon_discount,
550 c.deduction AS coupon_deduction,
551 c.expirationDate AS coupon_expirationDate,
552 c.limit AS coupon_limit,
553 c.customerLimit AS coupon_customerLimit,
554 c.status AS coupon_status
555 FROM {$this->table} cb
556 INNER JOIN {$usersTable} cu ON cu.id = cb.customerId
557 LEFT JOIN {$couponsTable} c ON c.id = cb.couponId
558 LEFT JOIN {$paymentsTable} p ON p.customerBookingId = cb.id
559 WHERE cb.id = :id"
560 );
561
562 $statement->execute($params);
563
564 $rows = $statement->fetchAll();
565 } catch (Exception $e) {
566 throw new QueryExecutionException('Unable to find booking by id in ' . __CLASS__, $e->getCode(), $e);
567 }
568
569 $reformattedData = call_user_func([static::FACTORY, 'reformat'], $rows);
570
571 return !empty($reformattedData[$id]) ?
572 call_user_func([static::FACTORY, 'create'], $reformattedData[$id]) : null;
573 }
574
575 /**
576 * Returns a collection of bookings where actions on booking are not completed
577 *
578 * @return Collection
579 * @throws InvalidArgumentException
580 * @throws QueryExecutionException
581 * @throws \Exception
582 */
583 public function getUncompletedActionsForBookings()
584 {
585 $params = [];
586
587 $currentDateTime = "STR_TO_DATE('" . DateTimeService::getNowDateTimeInUtc() . "', '%Y-%m-%d %H:%i:%s')";
588
589 $pastDateTime =
590 "STR_TO_DATE('" .
591 DateTimeService::getNowDateTimeObjectInUtc()->modify('-1 day')->format('Y-m-d H:i:s') .
592 "', '%Y-%m-%d %H:%i:%s')";
593
594 try {
595 $statement = $this->connection->prepare(
596 "SELECT * FROM {$this->table}
597 WHERE
598 actionsCompleted = 0 AND
599 {$currentDateTime} > DATE_ADD(created, INTERVAL 300 SECOND) AND
600 {$pastDateTime} < created"
601 );
602
603 $statement->execute($params);
604
605 $rows = $statement->fetchAll();
606 } catch (\Exception $e) {
607 throw new QueryExecutionException('Unable to get data from ' . __CLASS__, $e->getCode(), $e);
608 }
609
610 $items = [];
611
612 foreach ($rows as $row) {
613 $items[] = call_user_func([static::FACTORY, 'create'], $row);
614 }
615
616 return new Collection($items);
617 }
618
619 /**
620 * @param array $ids
621 *
622 * @return array
623 * @throws QueryExecutionException
624 */
625 public function countByNoShowStatus($ids)
626 {
627 $idsString = implode(', ', $ids);
628
629 try {
630 $statement = $this->connection->prepare(
631 "SELECT customerId, COUNT(*) AS count
632 FROM {$this->table} cb
633 WHERE customerId IN ($idsString) AND status = 'no-show'
634 GROUP BY customerId"
635 );
636
637 $statement->execute();
638
639 $rows = $statement->fetchAll();
640
641 $result = [];
642 foreach ($ids as $id) {
643 $count = 0;
644 foreach ($rows as $row) {
645 if ($row['customerId'] == $id) {
646 $count = $row['count'];
647 break;
648 }
649 }
650 $result[] = [
651 'id' => $id,
652 'count' => $count,
653 ];
654 }
655 } catch (Exception $e) {
656 throw new QueryExecutionException('Unable to find booking by id in ' . __CLASS__, $e->getCode(), $e);
657 }
658
659 return $result;
660 }
661
662 /**
663 * @param array $criteria
664 *
665 * @return Collection
666 * @throws QueryExecutionException
667 * @throws InvalidArgumentException
668 */
669 public function getByCriteria($criteria)
670 {
671 try {
672 $params = [];
673
674 $where = [];
675
676 if (!empty($criteria['appointmentIds'])) {
677 $queryAppointments = [];
678
679 foreach ($criteria['appointmentIds'] as $index => $value) {
680 $param = ':appointmentId' . $index;
681
682 $queryAppointments[] = $param;
683
684 $params[$param] = $value;
685 }
686
687 $where[] = 'cb.appointmentId IN (' . implode(', ', $queryAppointments) . ')';
688 }
689
690 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
691
692 $statement = $this->connection->prepare(
693 "SELECT
694 cb.id AS id,
695 cb.appointmentId AS appointmentId,
696 cb.customerId AS customerId,
697 cb.status AS status,
698 cb.price AS price,
699 cb.tax AS tax,
700 cb.persons AS persons,
701 cb.customFields AS customFields,
702 cb.info AS info,
703 cb.aggregatedPrice AS aggregatedPrice,
704 cb.packageCustomerServiceId AS packageCustomerServiceId,
705 cb.duration AS duration,
706 cb.created AS created,
707 cb.tax AS tax
708 FROM {$this->table} cb
709 {$where}"
710 );
711
712 $statement->execute($params);
713
714 $rows = $statement->fetchAll();
715 } catch (\Exception $e) {
716 throw new QueryExecutionException('Unable to find by id in ' . __CLASS__, $e->getCode(), $e);
717 }
718
719 $result = new Collection();
720
721 foreach ($rows as $row) {
722 $result->addItem(
723 call_user_func([static::FACTORY, 'create'], $row),
724 $row['id']
725 );
726 }
727
728 return $result;
729 }
730
731 /**
732 * @param array $criteria
733 * @param int $itemsPerPageBackEnd
734 *
735 * @return array
736 * @throws QueryExecutionException
737 * @throws InvalidArgumentException
738 */
739 public function getEventBookingIdsByCriteria($criteria = [], $itemsPerPageBackEnd = 0)
740 {
741 $eventsPeriodsTable = EventsPeriodsTable::getTableName();
742 $customerBookingsEventsPeriods = CustomerBookingsToEventsPeriodsTable::getTableName();
743 $eventsTable = EventsTable::getTableName();
744 $eventProvidersTable = EventsProvidersTable::getTableName();
745
746 $params = [];
747
748 $where = [];
749
750 $joins = '';
751
752 if (!empty($criteria['customers'])) {
753 $queryIds = [];
754
755 foreach ($criteria['customers'] as $index => $value) {
756 $param = ':customerId' . $index;
757
758 $queryIds[] = $param;
759
760 $params[$param] = $value;
761 }
762
763 $where[] = '(cb.customerId IN (' . implode(', ', $queryIds) . '))';
764 }
765
766
767 if (!empty($criteria['dates'])) {
768 if (isset($criteria['dates'][0], $criteria['dates'][1])) {
769 $where[] = "(ep.periodStart BETWEEN :eventFrom AND :eventTo)";
770 $params[':eventFrom'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
771 $params[':eventTo'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][1]);
772 }
773 }
774
775 if (!empty($criteria['search'])) {
776 $params[':search1'] = $params[':search2'] = "%{$criteria['search']}%";
777
778 $where[] = '(e.name LIKE :search1 OR SUBSTR(cb.token, 1, 5) LIKE :search2)';
779 }
780
781 if (!empty($criteria['providers'])) {
782 $queryIds1 = [];
783 $queryIds2 = [];
784
785 foreach ($criteria['providers'] as $index => $value) {
786 $param1 = ':providerId' . $index;
787 $param2 = ':organizerId' . $index;
788
789 $queryIds1[] = $param1;
790 $queryIds2[] = $param2;
791
792 $params[$param1] = $value;
793 $params[$param2] = $value;
794 }
795
796 $where[] = '(epr.userId IN (' . implode(', ', $queryIds1) . ') OR e.organizerId IN (' . implode(', ', $queryIds2) . '))';
797
798 $joins .= "LEFT JOIN {$eventProvidersTable} epr ON epr.eventId = e.id";
799 }
800
801 if (!empty($criteria['statuses'])) {
802 $queryIds = [];
803
804 foreach ($criteria['statuses'] as $index => $value) {
805 $param = ':status' . $index;
806
807 $queryIds[] = $param;
808
809 $params[$param] = $value;
810 }
811
812 $where[] = '(cb.status IN (' . implode(', ', $queryIds) . '))';
813 }
814
815 if (!empty($criteria['events'])) {
816 $queryIds = [];
817
818 foreach ($criteria['events'] as $index => $value) {
819 $param = ':eventId' . $index;
820
821 $queryIds[] = $param;
822
823 $params[$param] = $value;
824 }
825
826 $where[] = '(e.id IN (' . implode(', ', $queryIds) . '))';
827 }
828
829 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
830
831 $groupBy = 'GROUP BY cb.id';
832 $limit = $this->getLimit(
833 !empty($criteria['page']) ? (int)$criteria['page'] : 0,
834 $itemsPerPageBackEnd
835 );
836
837 $orderBy = 'ORDER BY MIN(ep.periodStart), cb.id';
838
839 if (!empty($criteria['sort'])) {
840 $column = $criteria['sort'][0] === '-' ? substr($criteria['sort'], 1) : $criteria['sort'];
841 $orderColumn = '';
842 if ($column === 'attendee') {
843 $orderColumn = ', CONCAT(cu.firstName, " ", cu.lastName)';
844 } elseif ($column === 'event') {
845 $orderColumn = ', e.name';
846 }
847 $orderDir = $orderColumn ? ($criteria['sort'][0] === '-' ? 'DESC' : 'ASC') : '';
848 $orderBy = "ORDER BY MIN(DATE(ep.periodStart)) {$orderColumn} {$orderDir}, cb.id";
849 }
850
851 try {
852 $statement = $this->connection->prepare(
853 "SELECT cb.id
854 FROM {$this->table} cb
855 INNER JOIN {$customerBookingsEventsPeriods} cbe ON cbe.customerBookingId = cb.id
856 LEFT JOIN {$eventsPeriodsTable} ep ON ep.id = cbe.eventPeriodId
857 LEFT JOIN {$eventsTable} e ON e.id = ep.eventId
858
859 {$joins}
860 {$where}
861 {$groupBy}
862 {$orderBy}
863 {$limit}"
864 );
865
866 $statement->execute($params);
867
868 $rows = $statement->fetchAll(\PDO::FETCH_COLUMN);
869 } catch (\Exception $e) {
870 throw new QueryExecutionException('Unable to find event by id in ' . __CLASS__, $e->getCode(), $e);
871 }
872
873 return $rows;
874 }
875
876
877 /**
878 * @param array $criteria
879 *
880 * @return array
881 * @throws QueryExecutionException
882 * @throws InvalidArgumentException
883 */
884 public function getEventBookingsByIds($ids, $criteria)
885 {
886 $eventsPeriodsTable = EventsPeriodsTable::getTableName();
887 $customerBookingsEventsPeriods = CustomerBookingsToEventsPeriodsTable::getTableName();
888 $usersTable = UsersTable::getTableName();
889 $eventsTable = EventsTable::getTableName();
890 $eventProvidersTable = EventsProvidersTable::getTableName();
891 $bookingsTicketsTable = CustomerBookingToEventsTicketsTable::getTableName();
892
893 $params = [];
894
895 $where = [];
896
897 $fields = '';
898
899 $joins = '';
900
901 if (!empty($criteria['dates'])) {
902 if (isset($criteria['dates'][0], $criteria['dates'][1])) {
903 $where[] = "(ep.periodStart BETWEEN :eventFrom AND :eventTo)";
904 $params[':eventFrom'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
905 $params[':eventTo'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][1]);
906 }
907 }
908
909 if (!empty($ids)) {
910 $queryIds = [];
911
912 foreach ($ids as $index => $value) {
913 $param = ':id' . $index;
914
915 $queryIds[] = $param;
916
917 $params[$param] = $value;
918 }
919
920 $where[] = '(cb.id IN (' . implode(', ', $queryIds) . '))';
921 }
922
923 if (!empty($criteria['fetchBookingsCoupons'])) {
924 $couponsTable = CouponsTable::getTableName();
925
926 $fields .= '
927 c.id AS coupon_id,
928 c.code AS coupon_code,
929 c.discount AS coupon_discount,
930 c.deduction AS coupon_deduction,
931 c.limit AS coupon_limit,
932 c.customerLimit AS coupon_customerLimit,
933 c.status AS coupon_status,
934 ';
935
936 $joins .= "
937 LEFT JOIN {$couponsTable} c ON c.id = cb.couponId
938 ";
939 }
940
941 if (!empty($criteria['fetchBookingsPayments'])) {
942 $paymentsTable = PaymentsTable::getTableName();
943
944 $fields .= '
945 p.id AS payment_id,
946 p.amount AS payment_amount,
947 p.dateTime AS payment_dateTime,
948 p.status AS payment_status,
949 p.gateway AS payment_gateway,
950 p.gatewayTitle AS payment_gatewayTitle,
951 p.transactionId AS payment_transactionId,
952 p.data AS payment_data,
953 p.wcOrderId AS payment_wcOrderId,
954 p.wcOrderItemId AS payment_wcOrderItemId,
955 ';
956
957 $joins .= "
958 LEFT JOIN {$paymentsTable} p ON p.customerBookingId = cb.id
959 ";
960 }
961
962 if (!empty($criteria['fetchProviders'])) {
963 $fields .= '
964 pu.id AS provider_id,
965 pu.firstName AS provider_firstName,
966 pu.lastName AS provider_lastName,
967 pu.pictureThumbPath AS provider_pictureThumbPath,
968 ';
969 $joins .= "
970 LEFT JOIN {$eventProvidersTable} epr ON epr.eventId = e.id
971 LEFT JOIN {$usersTable} pu ON epr.userId = pu.id or pu.id = e.organizerId
972 ";
973 }
974
975 if (!empty($criteria['fetchCustomers'])) {
976 $fields .= '
977 cu.id AS customer_id,
978 cu.type AS customer_type,
979 cu.firstName AS customer_firstName,
980 cu.lastName AS customer_lastName,
981 cu.email AS customer_email,
982 cu.note AS customer_note,
983 cu.phone AS customer_phone,
984 cu.gender AS customer_gender,
985 cu.birthday AS customer_birthday,
986 ';
987
988 $joins .= "
989 INNER JOIN {$usersTable} cu ON cu.id = cb.customerId
990 ";
991 }
992
993
994 $fields .= '
995 cb.id AS booking_id,
996 cb.appointmentId AS booking_appointmentId,
997 cb.customerId AS booking_customerId,
998 cb.status AS booking_status,
999 cb.price AS booking_price,
1000 cb.tax AS booking_tax,
1001 cb.persons AS booking_persons,
1002 cb.couponId AS booking_couponId,
1003 cb.customFields AS booking_customFields,
1004 cb.info AS booking_info,
1005 cb.utcOffset AS booking_utcOffset,
1006 cb.token AS booking_token,
1007 cb.aggregatedPrice AS booking_aggregatedPrice,
1008
1009 ep.id as event_periodId,
1010 ep.periodStart as event_periodStart,
1011 ep.zoomMeeting as event_zoomMeeting,
1012 ep.googleMeetUrl as event_googleMeetUrl,
1013
1014 cbt.id AS booking_ticket_id,
1015 cbt.eventTicketId AS booking_ticket_eventTicketId,
1016 cbt.price AS booking_ticket_price,
1017 cbt.persons AS booking_ticket_persons,
1018
1019 e.id AS event_id,
1020 e.name AS event_name,
1021 e.customPricing AS event_customPricing,
1022 e.status AS event_status,
1023 e.organizerId AS event_organizerId,
1024 e.settings AS event_settings
1025 ';
1026
1027 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
1028
1029 try {
1030 $statement = $this->connection->prepare(
1031 "SELECT
1032 {$fields}
1033 FROM {$this->table} cb
1034 INNER JOIN {$customerBookingsEventsPeriods} cbe ON cbe.customerBookingId = cb.id
1035 LEFT JOIN {$bookingsTicketsTable} cbt ON cbt.customerBookingId = cb.id
1036 LEFT JOIN {$eventsPeriodsTable} ep ON ep.id = cbe.eventPeriodId
1037 LEFT JOIN {$eventsTable} e ON e.id = ep.eventId
1038
1039 {$joins}
1040 {$where}
1041 "
1042 );
1043
1044 $statement->execute($params);
1045
1046 $rows = $statement->fetchAll();
1047 } catch (\Exception $e) {
1048 throw new QueryExecutionException('Unable to find event by id in ' . __CLASS__, $e->getCode(), $e);
1049 }
1050
1051 return CustomerBookingFactory::reformat($rows);
1052 }
1053 }
1054