PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 1.2.20
Booking for Appointments and Events Calendar – Amelia v1.2.20
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
1048 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[] = "(DATE_FORMAT(a.bookingStart, '%Y-%m-%d') < :bookingFrom)";
320 $params[':bookingFrom'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
321 }
322
323 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
324
325 try {
326 $statement = $this->connection->prepare(
327 "SELECT
328 customerId,
329 COUNT(*) AS occurrences
330 FROM {$this->table} cb
331 INNER JOIN {$appointmentTable} a ON a.id = cb.appointmentId
332 $where
333 GROUP BY customerId"
334 );
335
336 $statement->execute($params);
337
338 $rows = $statement->fetchAll();
339 } catch (Exception $e) {
340 throw new QueryExecutionException('Unable to return customer bookings from' . __CLASS__, $e->getCode(), $e);
341 }
342
343 return $rows;
344 }
345
346 /**
347 * Returns an array of Customers Id's bookings in selected period
348 *
349 * @param $criteria
350 *
351 * @return array
352 * @throws QueryExecutionException
353 * @throws InvalidArgumentException
354 */
355 public function getFilteredDistinctCustomersIds($criteria)
356 {
357 $appointmentTable = AppointmentsTable::getTableName();
358
359 $params = [];
360
361 $where = [];
362
363 if ($criteria['dates']) {
364 $where[] = "(DATE_FORMAT(a.bookingStart, '%Y-%m-%d') BETWEEN :bookingFrom AND :bookingTo)";
365
366 $params[':bookingFrom'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
367
368 $params[':bookingTo'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][1]);
369 }
370
371 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
372
373 try {
374 $statement = $this->connection->prepare(
375 "SELECT DISTINCT
376 cb.customerId
377 FROM {$this->table} cb
378 INNER JOIN {$appointmentTable} a ON a.id = cb.appointmentId
379 $where"
380 );
381
382 $statement->execute($params);
383
384 $rows = $statement->fetchAll();
385 } catch (Exception $e) {
386 throw new QueryExecutionException('Unable to return customer bookings from' . __CLASS__, $e->getCode(), $e);
387 }
388
389 return $rows;
390 }
391
392 /**
393 * Returns token for given id
394 *
395 * @param $id
396 *
397 * @return array
398 * @throws QueryExecutionException
399 */
400 public function getToken($id)
401 {
402 try {
403 $statement = $this->connection->prepare(
404 "SELECT cb.token
405 FROM {$this->table} cb
406 WHERE cb.id = :id"
407 );
408
409 $statement->execute([':id' => $id]);
410
411 $row = $statement->fetch();
412 } catch (Exception $e) {
413 throw new QueryExecutionException('Unable to return customer booking from' . __CLASS__, $e->getCode(), $e);
414 }
415
416 return $row;
417 }
418
419 /**
420 * Returns tokens for given event id
421 *
422 * @param $id
423 *
424 * @return array
425 * @throws QueryExecutionException
426 * @throws InvalidArgumentException
427 */
428 public function getTokensByEventId($id)
429 {
430 $eventsPeriodsTable = EventsPeriodsTable::getTableName();
431
432 $customerBookingsEventsPeriods = CustomerBookingsToEventsPeriodsTable::getTableName();
433
434 try {
435 $statement = $this->connection->prepare(
436 "SELECT
437 cb.id, cb.token
438 FROM {$this->table} cb
439 INNER JOIN {$customerBookingsEventsPeriods} cbep ON cbep.customerBookingId = cb.id
440 INNER JOIN {$eventsPeriodsTable} ep ON ep.id = cbep.eventPeriodId
441 WHERE ep.eventId = :id"
442 );
443
444 $statement->execute([':id' => $id]);
445
446 $rows = $statement->fetchAll();
447 } catch (Exception $e) {
448 throw new QueryExecutionException('Unable to return customer booking from' . __CLASS__, $e->getCode(), $e);
449 }
450
451 return $rows;
452 }
453
454 /**
455 * @param int $customerId
456 * @param string $info
457 *
458 * @return mixed
459 * @throws QueryExecutionException
460 */
461 public function updateInfoByCustomerId($customerId, $info)
462 {
463 $params = [
464 ':customerId' => $customerId,
465 ':info' => $info
466 ];
467
468 try {
469 $statement = $this->connection->prepare(
470 "UPDATE {$this->table} SET
471 `info` = :info
472 WHERE customerId = :customerId"
473 );
474
475 $res = $statement->execute($params);
476
477 if (!$res) {
478 throw new QueryExecutionException('Unable to save data in ' . __CLASS__);
479 }
480
481 return $res;
482 } catch (Exception $e) {
483 throw new QueryExecutionException('Unable to save data in ' . __CLASS__, $e->getCode(), $e);
484 }
485 }
486
487 /**
488 * @param int $id
489 *
490 * @return mixed
491 * @throws QueryExecutionException
492 * @throws InvalidArgumentException
493 */
494 public function getById($id)
495 {
496 $params = [
497 ':id' => $id,
498 ];
499
500 $paymentsTable = PaymentsTable::getTableName();
501
502 $usersTable = UsersTable::getTableName();
503
504 $couponsTable = CouponsTable::getTableName();
505
506 try {
507 $statement = $this->connection->prepare(
508 "SELECT
509 cb.id AS booking_id,
510 cb.appointmentId AS booking_appointmentId,
511 cb.customerId AS booking_customerId,
512 cb.status AS booking_status,
513 cb.price AS booking_price,
514 cb.persons AS booking_persons,
515 cb.couponId AS booking_couponId,
516 cb.customFields AS booking_customFields,
517 cb.info AS booking_info,
518 cb.utcOffset AS booking_utcOffset,
519 cb.aggregatedPrice AS booking_aggregatedPrice,
520 cb.duration AS booking_duration,
521 cb.created AS booking_created,
522
523 cu.id AS customer_id,
524 cu.firstName AS customer_firstName,
525 cu.lastName AS customer_lastName,
526 cu.email AS customer_email,
527 cu.note AS customer_note,
528 cu.phone AS customer_phone,
529 cu.gender AS customer_gender,
530 cu.birthday AS customer_birthday,
531
532 p.id AS payment_id,
533 p.amount AS payment_amount,
534 p.dateTime AS payment_dateTime,
535 p.status AS payment_status,
536 p.gateway AS payment_gateway,
537 p.gatewayTitle AS payment_gatewayTitle,
538 p.transactionId AS payment_transactionId,
539 p.data AS payment_data,
540
541 c.id AS coupon_id,
542 c.code AS coupon_code,
543 c.discount AS coupon_discount,
544 c.deduction AS coupon_deduction,
545 c.expirationDate AS coupon_expirationDate,
546 c.limit AS coupon_limit,
547 c.customerLimit AS coupon_customerLimit,
548 c.status AS coupon_status
549 FROM {$this->table} cb
550 INNER JOIN {$usersTable} cu ON cu.id = cb.customerId
551 LEFT JOIN {$couponsTable} c ON c.id = cb.couponId
552 LEFT JOIN {$paymentsTable} p ON p.customerBookingId = cb.id
553 WHERE cb.id = :id"
554 );
555
556 $statement->execute($params);
557
558 $rows = $statement->fetchAll();
559 } catch (Exception $e) {
560 throw new QueryExecutionException('Unable to find booking by id in ' . __CLASS__, $e->getCode(), $e);
561 }
562
563 $reformattedData = call_user_func([static::FACTORY, 'reformat'], $rows);
564
565 return !empty($reformattedData[$id]) ?
566 call_user_func([static::FACTORY, 'create'], $reformattedData[$id]) : null;
567 }
568
569 /**
570 * Returns a collection of bookings where actions on booking are not completed
571 *
572 * @return Collection
573 * @throws InvalidArgumentException
574 * @throws QueryExecutionException
575 * @throws \Exception
576 */
577 public function getUncompletedActionsForBookings()
578 {
579 $params = [];
580
581 $currentDateTime = "STR_TO_DATE('" . DateTimeService::getNowDateTimeInUtc() . "', '%Y-%m-%d %H:%i:%s')";
582
583 $pastDateTime =
584 "STR_TO_DATE('" .
585 DateTimeService::getNowDateTimeObjectInUtc()->modify('-1 day')->format('Y-m-d H:i:s') .
586 "', '%Y-%m-%d %H:%i:%s')";
587
588 try {
589 $statement = $this->connection->prepare(
590 "SELECT * FROM {$this->table}
591 WHERE
592 actionsCompleted = 0 AND
593 {$currentDateTime} > DATE_ADD(created, INTERVAL 300 SECOND) AND
594 {$pastDateTime} < created"
595 );
596
597 $statement->execute($params);
598
599 $rows = $statement->fetchAll();
600 } catch (\Exception $e) {
601 throw new QueryExecutionException('Unable to get data from ' . __CLASS__, $e->getCode(), $e);
602 }
603
604 $items = [];
605
606 foreach ($rows as $row) {
607 $items[] = call_user_func([static::FACTORY, 'create'], $row);
608 }
609
610 return new Collection($items);
611 }
612
613 /**
614 * @param array $ids
615 *
616 * @return array
617 * @throws QueryExecutionException
618 */
619 public function countByNoShowStatus($ids)
620 {
621 $idsString = implode(', ', $ids);
622
623 try {
624 $statement = $this->connection->prepare(
625 "SELECT customerId, COUNT(*) AS count
626 FROM {$this->table} cb
627 WHERE customerId IN ($idsString) AND status = 'no-show'
628 GROUP BY customerId"
629 );
630
631 $statement->execute();
632
633 $rows = $statement->fetchAll();
634
635 $result = [];
636 foreach ($ids as $id) {
637 $count = 0;
638 foreach ($rows as $row) {
639 if ($row['customerId'] == $id) {
640 $count = $row['count'];
641 break;
642 }
643 }
644 $result[] = [
645 'id' => $id,
646 'count' => $count,
647 ];
648 }
649 } catch (Exception $e) {
650 throw new QueryExecutionException('Unable to find booking by id in ' . __CLASS__, $e->getCode(), $e);
651 }
652
653 return $result;
654 }
655
656 /**
657 * @param array $criteria
658 *
659 * @return Collection
660 * @throws QueryExecutionException
661 * @throws InvalidArgumentException
662 */
663 public function getByCriteria($criteria)
664 {
665 try {
666 $params = [];
667
668 $where = [];
669
670 if (!empty($criteria['appointmentIds'])) {
671 $queryAppointments = [];
672
673 foreach ($criteria['appointmentIds'] as $index => $value) {
674 $param = ':appointmentId' . $index;
675
676 $queryAppointments[] = $param;
677
678 $params[$param] = $value;
679 }
680
681 $where[] = 'cb.appointmentId IN (' . implode(', ', $queryAppointments) . ')';
682 }
683
684 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
685
686 $statement = $this->connection->prepare(
687 "SELECT
688 cb.id AS id,
689 cb.appointmentId AS appointmentId,
690 cb.customerId AS customerId,
691 cb.status AS status,
692 cb.price AS price,
693 cb.tax AS tax,
694 cb.persons AS persons,
695 cb.customFields AS customFields,
696 cb.info AS info,
697 cb.aggregatedPrice AS aggregatedPrice,
698 cb.packageCustomerServiceId AS packageCustomerServiceId,
699 cb.duration AS duration,
700 cb.created AS created,
701 cb.tax AS tax
702 FROM {$this->table} cb
703 {$where}"
704 );
705
706 $statement->execute($params);
707
708 $rows = $statement->fetchAll();
709 } catch (\Exception $e) {
710 throw new QueryExecutionException('Unable to find by id in ' . __CLASS__, $e->getCode(), $e);
711 }
712
713 $result = new Collection();
714
715 foreach ($rows as $row) {
716 $result->addItem(
717 call_user_func([static::FACTORY, 'create'], $row),
718 $row['id']
719 );
720 }
721
722 return $result;
723 }
724
725 /**
726 * @param array $criteria
727 * @param array $itemsPerPageBackEnd
728 *
729 * @return array
730 * @throws QueryExecutionException
731 * @throws InvalidArgumentException
732 */
733 public function getEventBookingIdsByCriteria($criteria = [], $itemsPerPageBackEnd = 0)
734 {
735 $eventsPeriodsTable = EventsPeriodsTable::getTableName();
736 $customerBookingsEventsPeriods = CustomerBookingsToEventsPeriodsTable::getTableName();
737 $eventsTable = EventsTable::getTableName();
738 $eventProvidersTable = EventsProvidersTable::getTableName();
739
740 $params = [];
741
742 $where = [];
743
744 $joins = '';
745
746 if (!empty($criteria['customers'])) {
747 $queryIds = [];
748
749 foreach ($criteria['customers'] as $index => $value) {
750 $param = ':customerId' . $index;
751
752 $queryIds[] = $param;
753
754 $params[$param] = $value;
755 }
756
757 $where[] = '(cb.customerId IN (' . implode(', ', $queryIds) . '))';
758 }
759
760
761 if (!empty($criteria['dates'])) {
762 if (isset($criteria['dates'][0], $criteria['dates'][1])) {
763 $where[] = "(DATE_FORMAT(ep.periodStart, '%Y-%m-%d %H:%i:%s') BETWEEN :eventFrom AND :eventTo)";
764 $params[':eventFrom'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
765 $params[':eventTo'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][1]);
766 }
767 }
768
769 if (!empty($criteria['search'])) {
770 $params[':search1'] = $params[':search2'] = "%{$criteria['search']}%";
771
772 $where[] = '(e.name LIKE :search1 OR SUBSTR(cb.token, 1, 5) LIKE :search2)';
773 }
774
775 if (!empty($criteria['providers'])) {
776 $queryIds1 = [];
777 $queryIds2 = [];
778
779 foreach ($criteria['providers'] as $index => $value) {
780 $param1 = ':providerId' . $index;
781 $param2 = ':organizerId' . $index;
782
783 $queryIds1[] = $param1;
784 $queryIds2[] = $param2;
785
786 $params[$param1] = $value;
787 $params[$param2] = $value;
788 }
789
790 $where[] = '(epr.userId IN (' . implode(', ', $queryIds1) . ') OR e.organizerId IN (' . implode(', ', $queryIds2) . '))';
791
792 $joins .= "LEFT JOIN {$eventProvidersTable} epr ON epr.eventId = e.id";
793 }
794
795 if (!empty($criteria['statuses'])) {
796 $queryIds = [];
797
798 foreach ($criteria['statuses'] as $index => $value) {
799 $param = ':status' . $index;
800
801 $queryIds[] = $param;
802
803 $params[$param] = $value;
804 }
805
806 $where[] = '(cb.status IN (' . implode(', ', $queryIds) . '))';
807 }
808
809 if (!empty($criteria['events'])) {
810 $queryIds = [];
811
812 foreach ($criteria['events'] as $index => $value) {
813 $param = ':eventId' . $index;
814
815 $queryIds[] = $param;
816
817 $params[$param] = $value;
818 }
819
820 $where[] = '(e.id IN (' . implode(', ', $queryIds) . '))';
821 }
822
823 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
824
825 $groupBy = 'GROUP BY cb.id';
826 $limit = $this->getLimit(
827 !empty($criteria['page']) ? (int)$criteria['page'] : 0,
828 $itemsPerPageBackEnd
829 );
830
831 $orderBy = 'ORDER BY MIN(ep.periodStart), cb.id';
832
833 if (!empty($criteria['sort'])) {
834 $column = $criteria['sort'][0] === '-' ? substr($criteria['sort'], 1) : $criteria['sort'];
835 $orderColumn = '';
836 if ($column === 'attendee') {
837 $orderColumn = ', CONCAT(cu.firstName, " ", cu.lastName)';
838 } else if ($column === 'event') {
839 $orderColumn = ', e.name';
840 }
841 $orderDir = $orderColumn ? ($criteria['sort'][0] === '-' ? 'DESC' : 'ASC') : '';
842 $orderBy = "ORDER BY MIN(DATE(ep.periodStart)) {$orderColumn} {$orderDir}, cb.id";
843 }
844
845 try {
846 $statement = $this->connection->prepare(
847 "SELECT cb.id
848 FROM {$this->table} cb
849 INNER JOIN {$customerBookingsEventsPeriods} cbe ON cbe.customerBookingId = cb.id
850 LEFT JOIN {$eventsPeriodsTable} ep ON ep.id = cbe.eventPeriodId
851 LEFT JOIN {$eventsTable} e ON e.id = ep.eventId
852
853 {$joins}
854 {$where}
855 {$groupBy}
856 {$orderBy}
857 {$limit}"
858 );
859
860 $statement->execute($params);
861
862 $rows = $statement->fetchAll(\PDO::FETCH_COLUMN);
863 } catch (\Exception $e) {
864 throw new QueryExecutionException('Unable to find event by id in ' . __CLASS__, $e->getCode(), $e);
865 }
866
867 return $rows;
868 }
869
870
871 /**
872 * @param array $criteria
873 *
874 * @return array
875 * @throws QueryExecutionException
876 * @throws InvalidArgumentException
877 */
878 public function getEventBookingsByIds($ids, $criteria)
879 {
880 $eventsPeriodsTable = EventsPeriodsTable::getTableName();
881 $customerBookingsEventsPeriods = CustomerBookingsToEventsPeriodsTable::getTableName();
882 $usersTable = UsersTable::getTableName();
883 $eventsTable = EventsTable::getTableName();
884 $eventProvidersTable = EventsProvidersTable::getTableName();
885 $bookingsTicketsTable = CustomerBookingToEventsTicketsTable::getTableName();
886
887 $params = [];
888
889 $where = [];
890
891 $fields = '';
892
893 $joins = '';
894
895 if (!empty($criteria['dates'])) {
896 if (isset($criteria['dates'][0], $criteria['dates'][1])) {
897 $where[] = "(DATE_FORMAT(ep.periodStart, '%Y-%m-%d %H:%i:%s') BETWEEN :eventFrom AND :eventTo)";
898 $params[':eventFrom'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
899 $params[':eventTo'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][1]);
900 }
901 }
902
903 if (!empty($ids)) {
904 $queryIds = [];
905
906 foreach ($ids as $index => $value) {
907 $param = ':id' . $index;
908
909 $queryIds[] = $param;
910
911 $params[$param] = $value;
912 }
913
914 $where[] = '(cb.id IN (' . implode(', ', $queryIds) . '))';
915 }
916
917 if (!empty($criteria['fetchBookingsCoupons'])) {
918 $couponsTable = CouponsTable::getTableName();
919
920 $fields .= '
921 c.id AS coupon_id,
922 c.code AS coupon_code,
923 c.discount AS coupon_discount,
924 c.deduction AS coupon_deduction,
925 c.limit AS coupon_limit,
926 c.customerLimit AS coupon_customerLimit,
927 c.status AS coupon_status,
928 ';
929
930 $joins .= "
931 LEFT JOIN {$couponsTable} c ON c.id = cb.couponId
932 ";
933 }
934
935 if (!empty($criteria['fetchBookingsPayments'])) {
936 $paymentsTable = PaymentsTable::getTableName();
937
938 $fields .= '
939 p.id AS payment_id,
940 p.amount AS payment_amount,
941 p.dateTime AS payment_dateTime,
942 p.status AS payment_status,
943 p.gateway AS payment_gateway,
944 p.gatewayTitle AS payment_gatewayTitle,
945 p.transactionId AS payment_transactionId,
946 p.data AS payment_data,
947 p.wcOrderId AS payment_wcOrderId,
948 p.wcOrderItemId AS payment_wcOrderItemId,
949 ';
950
951 $joins .= "
952 LEFT JOIN {$paymentsTable} p ON p.customerBookingId = cb.id
953 ";
954 }
955
956 if (!empty($criteria['fetchProviders'])) {
957 $fields .= '
958 pu.id AS provider_id,
959 pu.firstName AS provider_firstName,
960 pu.lastName AS provider_lastName,
961 pu.pictureThumbPath AS provider_pictureThumbPath,
962 ';
963 $joins .= "
964 LEFT JOIN {$eventProvidersTable} epr ON epr.eventId = e.id
965 LEFT JOIN {$usersTable} pu ON epr.userId = pu.id or pu.id = e.organizerId
966 ";
967 }
968
969 if (!empty($criteria['fetchCustomers'])) {
970 $fields .= '
971 cu.id AS customer_id,
972 cu.type AS customer_type,
973 cu.firstName AS customer_firstName,
974 cu.lastName AS customer_lastName,
975 cu.email AS customer_email,
976 cu.note AS customer_note,
977 cu.phone AS customer_phone,
978 cu.gender AS customer_gender,
979 cu.birthday AS customer_birthday,
980 ';
981
982 $joins .= "
983 INNER JOIN {$usersTable} cu ON cu.id = cb.customerId
984 ";
985 }
986
987
988 $fields .= '
989 cb.id AS booking_id,
990 cb.appointmentId AS booking_appointmentId,
991 cb.customerId AS booking_customerId,
992 cb.status AS booking_status,
993 cb.price AS booking_price,
994 cb.tax AS booking_tax,
995 cb.persons AS booking_persons,
996 cb.couponId AS booking_couponId,
997 cb.customFields AS booking_customFields,
998 cb.info AS booking_info,
999 cb.utcOffset AS booking_utcOffset,
1000 cb.token AS booking_token,
1001 cb.aggregatedPrice AS booking_aggregatedPrice,
1002
1003 ep.id as event_periodId,
1004 ep.periodStart as event_periodStart,
1005 ep.zoomMeeting as event_zoomMeeting,
1006 ep.googleMeetUrl as event_googleMeetUrl,
1007
1008 cbt.id AS booking_ticket_id,
1009 cbt.eventTicketId AS booking_ticket_eventTicketId,
1010 cbt.price AS booking_ticket_price,
1011 cbt.persons AS booking_ticket_persons,
1012
1013 e.id AS event_id,
1014 e.name AS event_name,
1015 e.customPricing AS event_customPricing,
1016 e.status AS event_status,
1017 e.organizerId AS event_organizerId,
1018 e.settings AS event_settings
1019 ';
1020
1021 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
1022
1023 try {
1024 $statement = $this->connection->prepare(
1025 "SELECT
1026 {$fields}
1027 FROM {$this->table} cb
1028 INNER JOIN {$customerBookingsEventsPeriods} cbe ON cbe.customerBookingId = cb.id
1029 LEFT JOIN {$bookingsTicketsTable} cbt ON cbt.customerBookingId = cb.id
1030 LEFT JOIN {$eventsPeriodsTable} ep ON ep.id = cbe.eventPeriodId
1031 LEFT JOIN {$eventsTable} e ON e.id = ep.eventId
1032
1033 {$joins}
1034 {$where}
1035 "
1036 );
1037
1038 $statement->execute($params);
1039
1040 $rows = $statement->fetchAll();
1041 } catch (\Exception $e) {
1042 throw new QueryExecutionException('Unable to find event by id in ' . __CLASS__, $e->getCode(), $e);
1043 }
1044
1045 return CustomerBookingFactory::reformat($rows);
1046 }
1047 }
1048