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