PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 1.2.25
Booking for Appointments and Events Calendar – Amelia v1.2.25
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
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
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 $couponId = !empty($data['coupon']) ? $data['coupon']['id'] : null;
46 if (!$couponId && !empty($data['couponId'])) {
47 $couponId = $data['couponId'];
48 }
49
50 $params = [
51 ':appointmentId' => $data['appointmentId'],
52 ':customerId' => $data['customerId'],
53 ':status' => $data['status'],
54 ':price' => $data['price'],
55 ':tax' => !empty($data['tax']) ? json_encode($data['tax']) : null,
56 ':persons' => $data['persons'],
57 ':couponId' => $couponId,
58 ':token' => $data['token'],
59 ':customFields' => $data['customFields'] && json_decode($data['customFields']) !== false ?
60 $data['customFields'] : null,
61 ':info' => $data['info'],
62 ':aggregatedPrice' => $data['aggregatedPrice'] ? 1 : 0,
63 ':utcOffset' => $data['utcOffset'],
64 ':packageCustomerServiceId' => !empty($data['packageCustomerService']['id']) ?
65 $data['packageCustomerService']['id'] : null,
66 ':duration' => !empty($data['duration']) ? $data['duration'] : null,
67 ':created' => !empty($data['created']) ?
68 DateTimeService::getCustomDateTimeInUtc($data['created']) : DateTimeService::getNowDateTimeInUtc(),
69 ':actionsCompleted' => $data['actionsCompleted'] ? 1 : 0,
70 ];
71
72 try {
73 $statement = $this->connection->prepare(
74 "INSERT INTO {$this->table}
75 (
76 `appointmentId`,
77 `customerId`,
78 `status`,
79 `price`,
80 `tax`,
81 `persons`,
82 `couponId`,
83 `token`,
84 `customFields`,
85 `info`,
86 `aggregatedPrice`,
87 `utcOffset`,
88 `packageCustomerServiceId`,
89 `duration`,
90 `created`,
91 `actionsCompleted`
92 )
93 VALUES (
94 :appointmentId,
95 :customerId,
96 :status,
97 :price,
98 :tax,
99 :persons,
100 :couponId,
101 :token,
102 :customFields,
103 :info,
104 :aggregatedPrice,
105 :utcOffset,
106 :packageCustomerServiceId,
107 :duration,
108 :created,
109 :actionsCompleted
110 )"
111 );
112
113 $res = $statement->execute($params);
114
115 if (!$res) {
116 throw new QueryExecutionException('Unable to add data in ' . __CLASS__);
117 }
118
119 return $this->connection->lastInsertId();
120 } catch (Exception $e) {
121 throw new QueryExecutionException('Unable to add data in ' . __CLASS__, $e->getCode(), $e);
122 }
123 }
124
125 /**
126 * @param int $id
127 * @param CustomerBooking $entity
128 *
129 * @return mixed
130 * @throws QueryExecutionException
131 */
132 public function update($id, $entity)
133 {
134 $data = $entity->toArray();
135
136 $params = [
137 ':id' => $id,
138 ':customerId' => $data['customerId'],
139 ':status' => $data['status'],
140 ':duration' => !empty($data['duration']) ? $data['duration'] : null,
141 ':persons' => $data['persons'],
142 ':couponId' => !empty($data['coupon']) ? $data['coupon']['id'] : null,
143 ':customFields' => $data['customFields'],
144 ];
145
146 try {
147 $statement = $this->connection->prepare(
148 "UPDATE {$this->table} SET
149 `customerId` = :customerId,
150 `status` = :status,
151 `duration` = :duration,
152 `persons` = :persons,
153 `couponId` = :couponId,
154 `customFields` = :customFields
155 WHERE id = :id"
156 );
157
158 $res = $statement->execute($params);
159
160 if (!$res) {
161 throw new QueryExecutionException('Unable to save data in ' . __CLASS__);
162 }
163
164 return $res;
165 } catch (Exception $e) {
166 throw new QueryExecutionException('Unable to save data in ' . __CLASS__, $e->getCode(), $e);
167 }
168 }
169
170 /**
171 * @param int $id
172 * @param CustomerBooking $entity
173 *
174 * @return mixed
175 * @throws QueryExecutionException
176 */
177 public function updatePrice($id, $entity)
178 {
179 $data = $entity->toArray();
180
181 $params = [
182 ':id' => $id,
183 ':price' => $data['price'],
184 ];
185
186 try {
187 $statement = $this->connection->prepare(
188 "UPDATE {$this->table} SET
189 `price` = :price
190 WHERE id = :id"
191 );
192
193 $res = $statement->execute($params);
194
195 if (!$res) {
196 throw new QueryExecutionException('Unable to save data in ' . __CLASS__);
197 }
198
199 return $res;
200 } catch (Exception $e) {
201 throw new QueryExecutionException('Unable to save data in ' . __CLASS__, $e->getCode(), $e);
202 }
203 }
204
205 /**
206 * @param int $id
207 * @param CustomerBooking $entity
208 *
209 * @return bool
210 * @throws QueryExecutionException
211 */
212 public function updateTax($id, $entity)
213 {
214 $data = $entity->toArray();
215
216 $params = [
217 ':id' => $id,
218 ':tax' => !empty($data['tax']) ? (is_array($data['tax']) ? json_encode($data['tax']) : $data['tax']) : null,
219 ];
220
221 try {
222 $statement = $this->connection->prepare(
223 "UPDATE {$this->table} SET
224 `tax` = :tax
225 WHERE id = :id"
226 );
227
228 $res = $statement->execute($params);
229
230 if (!$res) {
231 throw new QueryExecutionException('Unable to save data in ' . __CLASS__);
232 }
233
234 return $res;
235 } catch (Exception $e) {
236 throw new QueryExecutionException('Unable to save data in ' . __CLASS__, $e->getCode(), $e);
237 }
238 }
239
240 /**
241 * @param int $id
242 * @param int $status
243 *
244 * @return mixed
245 * @throws QueryExecutionException
246 */
247 public function updateStatusByAppointmentId($id, $status)
248 {
249 $params = [
250 ':appointmentId' => $id,
251 ':status' => $status
252 ];
253
254 try {
255 $statement = $this->connection->prepare(
256 "UPDATE {$this->table} SET
257 `status` = :status
258 WHERE appointmentId = :appointmentId"
259 );
260
261 $res = $statement->execute($params);
262
263 if (!$res) {
264 throw new QueryExecutionException('Unable to save data in ' . __CLASS__);
265 }
266
267 return $res;
268 } catch (Exception $e) {
269 throw new QueryExecutionException('Unable to save data in ' . __CLASS__, $e->getCode(), $e);
270 }
271 }
272
273 /**
274 * @param int $id
275 * @param int $status
276 *
277 * @return mixed
278 * @throws QueryExecutionException
279 */
280 public function updateStatusById($id, $status)
281 {
282 $params = [
283 ':id' => $id,
284 ':status' => $status
285 ];
286
287 try {
288 $statement = $this->connection->prepare(
289 "UPDATE {$this->table} SET
290 `status` = :status
291 WHERE id = :id"
292 );
293
294 $res = $statement->execute($params);
295
296 if (!$res) {
297 throw new QueryExecutionException('Unable to save data in ' . __CLASS__);
298 }
299
300 return $res;
301 } catch (Exception $e) {
302 throw new QueryExecutionException('Unable to save data in ' . __CLASS__, $e->getCode(), $e);
303 }
304 }
305
306 /**
307 * Returns an array of Customers Id's who have at least one booking until passed date
308 *
309 * @param $criteria
310 *
311 * @return array
312 * @throws QueryExecutionException
313 * @throws InvalidArgumentException
314 */
315 public function getReturningCustomers($criteria)
316 {
317 $appointmentTable = AppointmentsTable::getTableName();
318
319 $params = [];
320
321 $where = [];
322
323 if ($criteria['dates']) {
324 $where[] = "(a.bookingStart < :bookingFrom)";
325
326 $params[':bookingFrom'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
327 }
328
329 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
330
331 try {
332 $statement = $this->connection->prepare(
333 "SELECT
334 customerId,
335 COUNT(*) AS occurrences
336 FROM {$this->table} cb
337 INNER JOIN {$appointmentTable} a ON a.id = cb.appointmentId
338 $where
339 GROUP BY customerId"
340 );
341
342 $statement->execute($params);
343
344 $rows = $statement->fetchAll();
345 } catch (Exception $e) {
346 throw new QueryExecutionException('Unable to return customer bookings from' . __CLASS__, $e->getCode(), $e);
347 }
348
349 return $rows;
350 }
351
352 /**
353 * Returns an array of Customers Id's bookings in selected period
354 *
355 * @param $criteria
356 *
357 * @return array
358 * @throws QueryExecutionException
359 * @throws InvalidArgumentException
360 */
361 public function getFilteredDistinctCustomersIds($criteria)
362 {
363 $appointmentTable = AppointmentsTable::getTableName();
364
365 $params = [];
366
367 $where = [];
368
369 if ($criteria['dates']) {
370 $where[] = "(a.bookingStart BETWEEN :bookingFrom AND :bookingTo)";
371
372 $params[':bookingFrom'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
373
374 $params[':bookingTo'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][1]);
375 }
376
377 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
378
379 try {
380 $statement = $this->connection->prepare(
381 "SELECT DISTINCT
382 cb.customerId
383 FROM {$this->table} cb
384 INNER JOIN {$appointmentTable} a ON a.id = cb.appointmentId
385 $where"
386 );
387
388 $statement->execute($params);
389
390 $rows = $statement->fetchAll();
391 } catch (Exception $e) {
392 throw new QueryExecutionException('Unable to return customer bookings from' . __CLASS__, $e->getCode(), $e);
393 }
394
395 return $rows;
396 }
397
398 /**
399 * Returns token for given id
400 *
401 * @param $id
402 *
403 * @return array
404 * @throws QueryExecutionException
405 */
406 public function getToken($id)
407 {
408 try {
409 $statement = $this->connection->prepare(
410 "SELECT cb.token
411 FROM {$this->table} cb
412 WHERE cb.id = :id"
413 );
414
415 $statement->execute([':id' => $id]);
416
417 $row = $statement->fetch();
418 } catch (Exception $e) {
419 throw new QueryExecutionException('Unable to return customer booking from' . __CLASS__, $e->getCode(), $e);
420 }
421
422 return $row;
423 }
424
425 /**
426 * Returns tokens for given event id
427 *
428 * @param $id
429 *
430 * @return array
431 * @throws QueryExecutionException
432 * @throws InvalidArgumentException
433 */
434 public function getTokensByEventId($id)
435 {
436 $eventsPeriodsTable = EventsPeriodsTable::getTableName();
437
438 $customerBookingsEventsPeriods = CustomerBookingsToEventsPeriodsTable::getTableName();
439
440 try {
441 $statement = $this->connection->prepare(
442 "SELECT
443 cb.id, cb.token
444 FROM {$this->table} cb
445 INNER JOIN {$customerBookingsEventsPeriods} cbep ON cbep.customerBookingId = cb.id
446 INNER JOIN {$eventsPeriodsTable} ep ON ep.id = cbep.eventPeriodId
447 WHERE ep.eventId = :id"
448 );
449
450 $statement->execute([':id' => $id]);
451
452 $rows = $statement->fetchAll();
453 } catch (Exception $e) {
454 throw new QueryExecutionException('Unable to return customer booking from' . __CLASS__, $e->getCode(), $e);
455 }
456
457 return $rows;
458 }
459
460 /**
461 * @param int $customerId
462 * @param string $info
463 *
464 * @return mixed
465 * @throws QueryExecutionException
466 */
467 public function updateInfoByCustomerId($customerId, $info)
468 {
469 $params = [
470 ':customerId' => $customerId,
471 ':info' => $info
472 ];
473
474 try {
475 $statement = $this->connection->prepare(
476 "UPDATE {$this->table} SET
477 `info` = :info
478 WHERE customerId = :customerId"
479 );
480
481 $res = $statement->execute($params);
482
483 if (!$res) {
484 throw new QueryExecutionException('Unable to save data in ' . __CLASS__);
485 }
486
487 return $res;
488 } catch (Exception $e) {
489 throw new QueryExecutionException('Unable to save data in ' . __CLASS__, $e->getCode(), $e);
490 }
491 }
492
493 /**
494 * @param int $id
495 *
496 * @return mixed
497 * @throws QueryExecutionException
498 * @throws InvalidArgumentException
499 */
500 public function getById($id)
501 {
502 $params = [
503 ':id' => $id,
504 ];
505
506 $paymentsTable = PaymentsTable::getTableName();
507
508 $usersTable = UsersTable::getTableName();
509
510 $couponsTable = CouponsTable::getTableName();
511
512 try {
513 $statement = $this->connection->prepare(
514 "SELECT
515 cb.id AS booking_id,
516 cb.appointmentId AS booking_appointmentId,
517 cb.customerId AS booking_customerId,
518 cb.status AS booking_status,
519 cb.price AS booking_price,
520 cb.persons AS booking_persons,
521 cb.couponId AS booking_couponId,
522 cb.customFields AS booking_customFields,
523 cb.info AS booking_info,
524 cb.utcOffset AS booking_utcOffset,
525 cb.aggregatedPrice AS booking_aggregatedPrice,
526 cb.duration AS booking_duration,
527 cb.created AS booking_created,
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 array $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 } else if ($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