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 / Event / EventRepository.php
ameliabooking / src / Infrastructure / Repository / Booking / Event Last commit date
CustomerBookingEventPeriodRepository.php 6 years ago CustomerBookingEventTicketRepository.php 1 year ago EventPeriodsRepository.php 4 years ago EventProvidersRepository.php 6 years ago EventRepository.php 1 year ago EventTagsRepository.php 6 years ago EventTicketRepository.php 1 year ago
EventRepository.php
1886 lines
1 <?php
2
3 namespace AmeliaBooking\Infrastructure\Repository\Booking\Event;
4
5 use AmeliaBooking\Domain\Collection\Collection;
6 use AmeliaBooking\Domain\Common\Exceptions\InvalidArgumentException;
7 use AmeliaBooking\Domain\Entity\Booking\Event\Event;
8 use AmeliaBooking\Domain\Factory\Booking\Appointment\CustomerBookingFactory;
9 use AmeliaBooking\Domain\Factory\Booking\Event\EventFactory;
10 use AmeliaBooking\Domain\Repository\Booking\Event\EventRepositoryInterface;
11 use AmeliaBooking\Domain\Services\DateTime\DateTimeService;
12 use AmeliaBooking\Domain\ValueObjects\String\Status;
13 use AmeliaBooking\Infrastructure\Common\Exceptions\QueryExecutionException;
14 use AmeliaBooking\Infrastructure\Licence;
15 use AmeliaBooking\Infrastructure\Repository\AbstractRepository;
16 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Booking\CustomerBookingsTable;
17 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Booking\CustomerBookingsToEventsPeriodsTable;
18 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Booking\CustomerBookingToEventsTicketsTable;
19 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Booking\EventsPeriodsTable;
20 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Booking\EventsProvidersTable;
21 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Booking\EventsTagsTable;
22 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Booking\EventsTicketsTable;
23 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Coupon\CouponsTable;
24 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Coupon\CouponsToEventsTable;
25 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Gallery\GalleriesTable;
26 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Payment\PaymentsTable;
27 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\User\Provider\ProvidersGoogleCalendarTable;
28 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\User\Provider\ProvidersOutlookCalendarTable;
29 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\User\UsersTable;
30
31 /**
32 * Class EventRepository
33 *
34 * @package AmeliaBooking\Infrastructure\Repository\Booking\Event
35 */
36 class EventRepository extends AbstractRepository implements EventRepositoryInterface
37 {
38
39 const FACTORY = EventFactory::class;
40
41 /**
42 * @param Event $entity
43 *
44 * @return bool
45 * @throws QueryExecutionException
46 */
47 public function add($entity)
48 {
49 $data = $entity->toArray();
50
51 $params = [
52 ':bookingOpens' => $data['bookingOpens'] ? DateTimeService::getCustomDateTimeInUtc($data['bookingOpens']) : null,
53 ':bookingCloses' => $data['bookingCloses'] ? DateTimeService::getCustomDateTimeInUtc($data['bookingCloses']) : null,
54 ':bookingOpensRec' => $data['bookingOpensRec'],
55 ':bookingClosesRec' => $data['bookingClosesRec'],
56 ':status' => $data['status'],
57 ':name' => $data['name'],
58 ':description' => $data['description'],
59 ':color' => $data['color'],
60 ':price' => $data['price'],
61 ':bringingAnyone' => $data['bringingAnyone'] ? 1 : 0,
62 ':bookMultipleTimes' => $data['bookMultipleTimes'] ? 1 : 0,
63 ':maxCapacity' => $data['maxCapacity'],
64 ':maxCustomCapacity' => $data['maxCustomCapacity'],
65 ':maxExtraPeople' => $data['maxExtraPeople'],
66 ':show' => $data['show'] ? 1 : 0,
67 ':notifyParticipants' => $data['notifyParticipants'],
68 ':customLocation' => $data['customLocation'],
69 ':parentId' => $data['parentId'],
70 ':created' => $data['created'],
71 ':closeAfterMin' => $data['closeAfterMin'],
72 ':closeAfterMinBookings' => $data['closeAfterMinBookings'] ? 1 : 0,
73 ':aggregatedPrice' => $data['aggregatedPrice'] ? 1 : 0,
74 ':error' => '',
75 ];
76
77 $additionalData = Licence\DataModifier::getEventRepositoryData($data);
78
79 $params = array_merge($params, $additionalData['values'], $additionalData['addValues']);
80
81 try {
82 $statement = $this->connection->prepare(
83 "INSERT INTO {$this->table}
84 (
85 {$additionalData['columns']}
86 `bookingOpens`,
87 `bookingCloses`,
88 `bookingOpensRec`,
89 `bookingClosesRec`,
90 `status`,
91 `name`,
92 `description`,
93 `color`,
94 `price`,
95 `bringingAnyone`,
96 `bookMultipleTimes`,
97 `maxCapacity`,
98 `maxCustomCapacity`,
99 `maxExtraPeople`,
100 `show`,
101 `notifyParticipants`,
102 `customLocation`,
103 `parentId`,
104 `created`,
105 `closeAfterMin`,
106 `closeAfterMinBookings`,
107 `aggregatedPrice`,
108 `error`
109 )
110 VALUES (
111 {$additionalData['placeholders']}
112 :bookingOpens,
113 :bookingCloses,
114 :bookingOpensRec,
115 :bookingClosesRec,
116 :status,
117 :name,
118 :description,
119 :color,
120 :price,
121 :bringingAnyone,
122 :bookMultipleTimes,
123 :maxCapacity,
124 :maxCustomCapacity,
125 :maxExtraPeople,
126 :show,
127 :notifyParticipants,
128 :customLocation,
129 :parentId,
130 :created,
131 :closeAfterMin,
132 :closeAfterMinBookings,
133 :aggregatedPrice,
134 :error
135 )"
136 );
137
138 $res = $statement->execute($params);
139
140 if (!$res) {
141 throw new QueryExecutionException('Unable to add data in ' . __CLASS__);
142 }
143
144 return $this->connection->lastInsertId();
145 } catch (\Exception $e) {
146 throw new QueryExecutionException('Unable to add data in ' . __CLASS__, $e->getCode(), $e);
147 }
148 }
149
150 /**
151 * @param int $id
152 * @param Event $entity
153 *
154 * @return mixed
155 * @throws QueryExecutionException
156 */
157 public function update($id, $entity)
158 {
159 $data = $entity->toArray();
160
161 $params = [
162 ':id' => $id,
163 ':bookingOpens' => $data['bookingOpens'] ? DateTimeService::getCustomDateTimeInUtc($data['bookingOpens']) : null,
164 ':bookingCloses' => $data['bookingCloses'] ? DateTimeService::getCustomDateTimeInUtc($data['bookingCloses']) : null,
165 ':bookingOpensRec' => $data['bookingOpensRec'],
166 ':bookingClosesRec' => $data['bookingClosesRec'],
167 ':status' => $data['status'],
168 ':name' => $data['name'],
169 ':description' => $data['description'],
170 ':color' => $data['color'],
171 ':price' => $data['price'],
172 ':bringingAnyone' => $data['bringingAnyone'] ? 1 : 0,
173 ':bookMultipleTimes' => $data['bookMultipleTimes'] ? 1 : 0,
174 ':maxCapacity' => $data['maxCapacity'],
175 ':maxCustomCapacity' => $data['maxCustomCapacity'],
176 ':maxExtraPeople' => $data['maxExtraPeople'],
177 ':show' => $data['show'] ? 1 : 0,
178 ':notifyParticipants' => $data['notifyParticipants'] ? 1 : 0,
179 ':customLocation' => $data['customLocation'],
180 ':parentId' => $data['parentId'],
181 ':closeAfterMin' => $data['closeAfterMin'],
182 ':closeAfterMinBookings' => $data['closeAfterMinBookings'] ? 1 : 0,
183 ':aggregatedPrice' => $data['aggregatedPrice'] ? 1 : 0
184 ];
185
186 $additionalData = Licence\DataModifier::getEventRepositoryData($data);
187
188 $params = array_merge($params, $additionalData['values']);
189
190 try {
191 $statement = $this->connection->prepare(
192 "UPDATE {$this->table}
193 SET
194 {$additionalData['columnsPlaceholders']}
195 `bookingOpens` = :bookingOpens,
196 `bookingCloses` = :bookingCloses,
197 `bookingOpensRec` = :bookingOpensRec,
198 `bookingClosesRec` = :bookingClosesRec,
199 `status` = :status,
200 `name` = :name,
201 `description` = :description,
202 `color` = :color,
203 `price` = :price,
204 `bringingAnyone` = :bringingAnyone,
205 `bookMultipleTimes` = :bookMultipleTimes,
206 `maxCapacity` = :maxCapacity,
207 `maxCustomCapacity` = :maxCustomCapacity,
208 `maxExtraPeople` = :maxExtraPeople,
209 `show` = :show,
210 `notifyParticipants` = :notifyParticipants,
211 `customLocation` = :customLocation,
212 `parentId` = :parentId,
213 `closeAfterMin` = :closeAfterMin,
214 `closeAfterMinBookings` = :closeAfterMinBookings,
215 `aggregatedPrice` = :aggregatedPrice
216 WHERE id = :id"
217 );
218
219 $res = $statement->execute($params);
220
221 if (!$res) {
222 throw new QueryExecutionException('Unable to save data in ' . __CLASS__);
223 }
224
225 return $res;
226 } catch (\Exception $e) {
227 throw new QueryExecutionException('Unable to save data in ' . __CLASS__, $e->getCode(), $e);
228 }
229 }
230
231 /**
232 * @param int $id
233 * @param int $status
234 *
235 * @return mixed
236 * @throws QueryExecutionException
237 */
238 public function updateStatusById($id, $status)
239 {
240 $params = [
241 ':id' => $id,
242 ':status' => $status
243 ];
244
245 try {
246 $statement = $this->connection->prepare(
247 "UPDATE {$this->table}
248 SET
249 `status` = :status
250 WHERE id = :id"
251 );
252
253 $res = $statement->execute($params);
254
255 if (!$res) {
256 throw new QueryExecutionException('Unable to save data in ' . __CLASS__);
257 }
258
259 return $res;
260 } catch (\Exception $e) {
261 throw new QueryExecutionException('Unable to save data in ' . __CLASS__, $e->getCode(), $e);
262 }
263 }
264
265 /**
266 * @param int $id
267 * @param int|null $parentId
268 *
269 * @return mixed
270 * @throws QueryExecutionException
271 */
272 public function updateParentId($id, $parentId)
273 {
274 $params = [
275 ':id' => $id,
276 ':parentId' => $parentId,
277 ];
278
279 try {
280 $statement = $this->connection->prepare(
281 "UPDATE {$this->table}
282 SET
283 `parentId` = :parentId
284 WHERE id = :id"
285 );
286
287 $res = $statement->execute($params);
288
289 if (!$res) {
290 throw new QueryExecutionException('Unable to save data in ' . __CLASS__);
291 }
292
293 return $res;
294 } catch (\Exception $e) {
295 throw new QueryExecutionException('Unable to save data in ' . __CLASS__, $e->getCode(), $e);
296 }
297 }
298
299 /**
300 * @param array $criteria
301 *
302 * @return Collection
303 * @throws QueryExecutionException
304 * @throws InvalidArgumentException
305 */
306 public function getProvidersEvents($criteria)
307 {
308 $eventsPeriodsTable = EventsPeriodsTable::getTableName();
309 $eventsProvidersTable = EventsProvidersTable::getTableName();
310 $usersTable = UsersTable::getTableName();
311
312 $params = [];
313 $where = [];
314
315 if (!empty($criteria['dates'])) {
316 if (isset($criteria['dates'][0], $criteria['dates'][1])) {
317 $whereStart = "(ep.periodStart BETWEEN :eventFrom AND :eventTo)";
318 $params[':eventFrom'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
319 $params[':eventTo'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][1]);
320
321 $whereEnd = "(ep.periodEnd BETWEEN :bookingFrom2 AND :bookingTo2)";
322 $params[':bookingFrom2'] = $params[':eventFrom'];
323 $params[':bookingTo2'] = $params[':eventTo'];
324
325 $where[] = "({$whereStart} OR {$whereEnd})";
326 } elseif (isset($criteria['dates'][0])) {
327 $where[] = "(ep.periodStart >= :eventFrom)";
328 $params[':eventFrom'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
329 } elseif (isset($criteria['dates'][1])) {
330 $where[] = "(ep.periodStart <= :eventTo)";
331 $params[':eventTo'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][1]);
332 } else {
333 $where[] = "(ep.periodStart > :eventFrom)";
334 $params[':eventFrom'] = DateTimeService::getNowDateTimeInUtc();
335 }
336 }
337
338 if (!empty($criteria['providers'])) {
339 $queryProviders = [];
340
341 foreach ((array)$criteria['providers'] as $index => $value) {
342 $param = ':provider' . $index;
343 $queryProviders[] = $param;
344 $params[$param] = $value;
345 }
346
347 $where[] = 'epr.userId IN (' . implode(', ', $queryProviders) . ')';
348 }
349
350 if (!empty($criteria['status'])) {
351 $params[':status'] = $criteria['status'];
352
353 $where[] = 'e.status = :status';
354 }
355
356 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
357
358 try {
359 $statement = $this->connection->prepare(
360 "SELECT
361 e.id AS event_id,
362 e.name AS event_name,
363 e.status AS event_status,
364 e.bookingOpens AS event_bookingOpens,
365 e.bookingCloses AS event_bookingCloses,
366 e.recurringCycle AS event_recurringCycle,
367 e.recurringOrder AS event_recurringOrder,
368 e.recurringInterval AS event_recurringInterval,
369 e.recurringUntil AS event_recurringUntil,
370 e.recurringMonthly AS event_recurringMonthly,
371 e.monthlyDate AS event_monthlyDate,
372 e.monthlyOnRepeat AS event_monthlyOnRepeat,
373 e.monthlyOnDay AS event_monthlyOnDay,
374 e.bringingAnyone AS event_bringingAnyone,
375 e.bookMultipleTimes AS event_bookMultipleTimes,
376 e.maxCapacity AS event_maxCapacity,
377 e.maxCustomCapacity AS event_maxCustomCapacity,
378 e.maxExtraPeople AS event_maxExtraPeople,
379 e.price AS event_price,
380 e.description AS event_description,
381 e.color AS event_color,
382 e.show AS event_show,
383 e.locationId AS event_locationId,
384 e.customLocation AS event_customLocation,
385 e.parentId AS event_parentId,
386 e.created AS event_created,
387 e.notifyParticipants AS event_notifyParticipants,
388 e.translations AS event_translations,
389 e.deposit AS event_deposit,
390 e.depositPayment AS event_depositPayment,
391 e.depositPerPerson AS event_depositPerPerson,
392 e.fullPayment AS event_fullPayment,
393 e.customPricing AS event_customPricing,
394 e.aggregatedPrice AS event_aggregatedPrice,
395
396 ep.id AS event_periodId,
397 ep.periodStart AS event_periodStart,
398 ep.periodEnd AS event_periodEnd,
399
400 pu.id AS provider_id,
401 pu.firstName AS provider_firstName,
402 pu.lastName AS provider_lastName,
403 pu.email AS provider_email,
404 pu.note AS provider_note,
405 pu.description AS provider_description,
406 pu.phone AS provider_phone,
407 pu.gender AS provider_gender,
408 pu.pictureFullPath AS provider_pictureFullPath,
409 pu.pictureThumbPath AS provider_pictureThumbPath,
410 pu.translations AS provider_translations
411 FROM {$this->table} e
412 INNER JOIN {$eventsPeriodsTable} ep ON ep.eventId = e.id
413 INNER JOIN {$eventsProvidersTable} epr ON epr.eventId = e.id
414 INNER JOIN {$usersTable} pu ON pu.id = epr.userId
415 {$where}
416 ORDER BY ep.periodStart"
417 );
418
419 $statement->execute($params);
420
421 $rows = $statement->fetchAll();
422 } catch (\Exception $e) {
423 throw new QueryExecutionException('Unable to find by id in ' . __CLASS__, $e->getCode(), $e);
424 }
425
426 return call_user_func([static::FACTORY, 'createCollection'], $rows);
427 }
428
429 /**
430 * @param array $criteria
431 * @param int $itemsPerPage
432 *
433 * @return array
434 * @throws QueryExecutionException
435 * @throws InvalidArgumentException
436 */
437 public function getFilteredIds($criteria, $itemsPerPage)
438 {
439 $eventsPeriodsTable = EventsPeriodsTable::getTableName();
440 $eventsTagsTable = EventsTagsTable::getTableName();
441 $customerBookingsTable = CustomerBookingsTable::getTableName();
442 $customerBookingsEventsPeriods = CustomerBookingsToEventsPeriodsTable::getTableName();
443 $eventsProvidersTable = EventsProvidersTable::getTableName();
444 $usersTable = UsersTable::getTableName();
445
446 $params = [];
447
448 $where = [];
449
450 if (isset($criteria['parentId'])) {
451 $params[':parentId'] = $criteria['parentId'];
452
453 $params[':originParentId'] = $criteria['parentId'];
454
455 $where[] = 'e.parentId = :parentId OR e.id = :originParentId';
456 }
457
458 if (!empty($criteria['search'])) {
459 $where[] = "(e.name LIKE '%" . $criteria['search'] . "%'
460 OR e.translations LIKE '{\"name\":{%" . $criteria['search'] . "%\"description\":{%'
461 OR e.translations LIKE '{\"description\":{%\"name\":{%" . $criteria['search'] . "%'
462 OR (e.translations LIKE '{\"name\":{%" . $criteria['search'] . "%' AND e.translations NOT LIKE '%\"description\":{%'))";
463 }
464
465
466 if (isset($criteria['show'])) {
467 $where[] = 'e.show = 1';
468 }
469
470 if (!empty($criteria['dates'])) {
471 if (isset($criteria['dates'][0], $criteria['dates'][1])) {
472 $where[] = "((ep.periodStart BETWEEN :eventFrom1 AND :eventTo1)
473 OR (ep.periodEnd BETWEEN :eventFrom2 AND :eventTo2)
474 OR (:eventFrom3 BETWEEN ep.periodStart AND ep.periodEnd)
475 OR (:eventTo3 BETWEEN ep.periodStart AND ep.periodEnd))";
476
477 $params[':eventFrom1'] = $params[':eventFrom2'] = $params[':eventFrom3'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
478 $params[':eventTo1'] = $params[':eventTo2'] = $params[':eventTo3'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][1]);
479 } elseif (isset($criteria['dates'][0])) {
480 $where[] = "(ep.periodStart >= :eventFrom OR (ep.periodEnd >= :eventTo))";
481 $params[':eventFrom'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
482 $params[':eventTo'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
483 } elseif (isset($criteria['dates'][1])) {
484 $where[] = "(ep.periodStart <= :eventTo)";
485
486 $params[':eventTo'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][1]);
487 } else {
488 $where[] = "(ep.periodStart > :eventFrom)";
489 $params[':eventFrom'] = DateTimeService::getNowDateTimeInUtc();
490 }
491 }
492
493 $tagJoin = '';
494
495 if (isset($criteria['tag'])) {
496 $queryTags = [];
497
498 $tags = $criteria['tag'];
499 foreach ((array)$tags as $index => $value) {
500 $param = ':tag' . $index;
501
502 $queryTags[] = $param;
503
504 $params[$param] = $value;
505 }
506
507 $where[] = 'et.name IN (' . implode(', ', $queryTags) . ')';
508
509 $tagJoin = "INNER JOIN {$eventsTagsTable} et ON et.eventId = e.id";
510 }
511
512 if (!empty($criteria['id'])) {
513 if (!empty($criteria['recurring'])) {
514 $whereOr = [];
515 foreach ((array)$criteria['id'] as $index => $value) {
516 $param = 'id' . $index;
517
518 $params[':rec1' . $param] = (int)$value;
519 $params[':rec2' . $param] = (int)$value;
520 $params[':rec3' . $param] = (int)$value;
521 $params[':rec4' . $param] = (int)$value;
522
523 $whereOr[] = "((e.id = :rec1id" . $index . " AND e.parentId IS NULL) OR
524 (e.parentId IN (SELECT parentId FROM {$this->table} WHERE parentId = :rec2id" . $index . ")) OR
525 (e.id >= :rec3id" . $index . " AND e.parentId IN (SELECT parentId FROM {$this->table} WHERE id = :rec4id" . $index . ")))";
526 }
527 $where[] = implode(' OR ', $whereOr);
528 } else {
529 $queryIds = [];
530
531 foreach ((array)$criteria['id'] as $index => $value) {
532 $param = ':id' . $index;
533
534 $queryIds[] = $param;
535
536 $params[$param] = (int)$value;
537 }
538
539 $where[] = 'e.id IN (' . implode(', ', $queryIds) . ')';
540 }
541 }
542
543 $customerJoin = '';
544
545 if (!empty($criteria['customerId']) || !empty($criteria['customerBookingsIds'])) {
546 $customerJoin = "
547 LEFT JOIN {$customerBookingsEventsPeriods} cbe ON cbe.eventPeriodId = ep.id
548 LEFT JOIN {$customerBookingsTable} cb ON cb.id = cbe.customerBookingId";
549
550 if (!empty($criteria['customerId'])) {
551 $params[':customerId'] = $criteria['customerId'];
552
553 $where[] = 'cb.customerId = :customerId';
554 }
555
556 if (!empty($criteria['customerBookingsIds'])) {
557 $queryBookingsIds = [];
558
559 foreach ($criteria['customerBookingsIds'] as $index => $value) {
560 $param = ':customerBookingId' . $index;
561
562 $queryBookingsIds[] = $param;
563
564 $params[$param] = $value;
565 }
566
567 $where[] = 'cb.id IN (' . implode(', ', $queryBookingsIds) . ')';
568 }
569
570 if (!empty($criteria['customerBookingStatus'])) {
571 $params[':customerBookingStatus'] = $criteria['customerBookingStatus'];
572
573 $where[] = 'cb.status = :customerBookingStatus';
574 }
575
576 if (!empty($criteria['customerBookingCouponId'])) {
577 $params[':customerBookingCouponId'] = $criteria['customerBookingCouponId'];
578
579 $where[] = 'cb.couponId = :customerBookingCouponId';
580 }
581 }
582
583 if (!empty($criteria['locationId'])) {
584 $params[':locationId'] = $criteria['locationId'];
585
586 $where[] = 'e.locationId = :locationId';
587 }
588
589 if (!empty($criteria['locations'])) {
590 foreach ((array)$criteria['locations'] as $index => $value) {
591 $param = ':location' . $index;
592 $queryLocations[] = $param;
593 $params[$param] = $value;
594 }
595
596 $where3 = 'e.locationId IN (' . implode(', ', $queryLocations) . ')';
597
598 $where[] = '(' . $where3 . ')';
599 }
600
601 $providerJoin = '';
602
603 if (!empty($criteria['providers'])) {
604 $providerJoin = "
605 LEFT JOIN {$eventsProvidersTable} epr ON epr.eventId = e.id
606 INNER JOIN {$usersTable} pu ON pu.id = epr.userId OR pu.id = e.organizerId";
607 $queryProviders = [];
608
609 foreach ((array)$criteria['providers'] as $index => $value) {
610 $param = ':provider' . $index;
611 $queryProviders[] = $param;
612 $params[$param] = $value;
613 }
614
615 $where1 = 'epr.userId IN (' . implode(', ', $queryProviders) . ')';
616
617 $queryProviders = [];
618 foreach ((array)$criteria['providers'] as $index => $value) {
619 $param = ':organizer' . $index;
620 $queryProviders[] = $param;
621 $params[$param] = $value;
622 }
623
624 $where2 = 'e.organizerId IN (' . implode(', ', $queryProviders) . ')';
625
626 $where[] = '(' . $where1 . ' OR ' . $where2 . ')';
627
628 }
629
630 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
631
632 $limit = $this->getLimit(
633 !empty($criteria['page']) ? (int)$criteria['page'] : 0,
634 (int)$itemsPerPage
635 );
636
637 try {
638 $statement = $this->connection->prepare(
639 "SELECT
640 e.id
641 FROM {$this->table} e
642 INNER JOIN {$eventsPeriodsTable} ep ON ep.eventId = e.id
643 {$tagJoin}
644 {$providerJoin}
645 {$customerJoin}
646 {$where}
647 GROUP BY e.id
648 ORDER BY ep.periodStart, e.id
649 {$limit}"
650 );
651
652 $statement->execute($params);
653
654 $rows = $statement->fetchAll();
655 } catch (\Exception $e) {
656 throw new QueryExecutionException('Unable to find by id in ' . __CLASS__, $e->getCode(), $e);
657 }
658
659 return array_column($rows, 'id');
660 }
661
662 /**
663 * @param array $criteria
664 *
665 * @return int
666 * @throws QueryExecutionException
667 * @throws InvalidArgumentException
668 */
669 public function getFilteredIdsCount($criteria)
670 {
671 $eventsPeriodsTable = EventsPeriodsTable::getTableName();
672 $eventsTagsTable = EventsTagsTable::getTableName();
673 $eventsProvidersTable = EventsProvidersTable::getTableName();
674 $usersTable = UsersTable::getTableName();
675
676
677 $params = [];
678 $where = [];
679
680 if (isset($criteria['parentId'])) {
681 $params[':parentId'] = $criteria['parentId'];
682
683 $params[':originParentId'] = $criteria['parentId'];
684
685 $where[] = 'e.parentId = :parentId OR e.id = :originParentId';
686 }
687
688 if (!empty($criteria['search'])) {
689 $where[] = "(e.name LIKE '%" . $criteria['search'] . "%'
690 OR e.translations LIKE '{\"name\":{%" . $criteria['search'] . "%\"description\":{%'
691 OR e.translations LIKE '{\"description\":{%\"name\":{%" . $criteria['search'] . "%'
692 OR (e.translations LIKE '{\"name\":{%" . $criteria['search'] . "%' AND e.translations NOT LIKE '%\"description\":{%'))";
693 }
694
695 if (isset($criteria['show'])) {
696 $where[] = 'e.show = 1';
697 }
698
699 if (!empty($criteria['dates'])) {
700 if (isset($criteria['dates'][0], $criteria['dates'][1])) {
701 $where[] = "((ep.periodStart BETWEEN :eventFrom1 AND :eventTo1)
702 OR (ep.periodEnd BETWEEN :eventFrom2 AND :eventTo2)
703 OR (:eventFrom3 BETWEEN ep.periodStart AND ep.periodEnd)
704 OR (:eventTo3 BETWEEN ep.periodStart AND ep.periodEnd))";
705
706 $params[':eventFrom1'] = $params[':eventFrom2'] = $params[':eventFrom3'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
707 $params[':eventTo1'] = $params[':eventTo2'] = $params[':eventTo3'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][1]);
708 } elseif (isset($criteria['dates'][0])) {
709 $where[] = "(ep.periodStart >= :eventFrom OR (ep.periodEnd >= :eventTo))";
710
711 $params[':eventFrom'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
712
713 $params[':eventTo'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
714 } elseif (isset($criteria['dates'][1])) {
715 $where[] = "(ep.periodStart <= :eventTo)";
716
717 $params[':eventTo'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][1]);
718 } else {
719 $where[] = "(ep.periodStart > :eventFrom)";
720
721 $params[':eventFrom'] = DateTimeService::getNowDateTimeInUtc();
722 }
723 }
724
725 if (!empty($criteria['locationId'])) {
726 $params[':locationId'] = $criteria['locationId'];
727
728 $where[] = 'e.locationId = :locationId';
729 }
730
731 if (!empty($criteria['locations'])) {
732 foreach ((array)$criteria['locations'] as $index => $value) {
733 $param = ':location' . $index;
734 $queryLocations[] = $param;
735 $params[$param] = $value;
736 }
737
738 $where3 = 'e.locationId IN (' . implode(', ', $queryLocations) . ')';
739
740 $where[] = '(' . $where3 . ')';
741 }
742
743
744 $tagJoin = '';
745
746 if (isset($criteria['tag'])) {
747 $queryTags = [];
748
749 $tags = $criteria['tag'];//explode(',', $criteria['tag']);
750 foreach ((array)$tags as $index => $value) {
751 $param = ':tag' . $index;
752
753 $queryTags[] = $param;
754
755 $params[$param] = $value;//trim($value, '{}');
756 }
757
758 $where[] = 'et.name IN (' . implode(', ', $queryTags) . ')';
759
760 $tagJoin = "INNER JOIN {$eventsTagsTable} et ON et.eventId = e.id";
761 }
762
763 if (!empty($criteria['id'])) {
764 if (!empty($criteria['recurring'])) {
765 $whereOr = [];
766 foreach ((array)$criteria['id'] as $index => $value) {
767 $param = 'id' . $index;
768
769 $params[':rec1' . $param] = (int)$value;
770 $params[':rec2' . $param] = (int)$value;
771 $params[':rec3' . $param] = (int)$value;
772 $params[':rec4' . $param] = (int)$value;
773
774 $whereOr[] = "((e.id = :rec1id" . $index . " AND e.parentId IS NULL) OR
775 (e.parentId IN (SELECT parentId FROM {$this->table} WHERE parentId = :rec2id" . $index . ")) OR
776 (e.id >= :rec3id" . $index . " AND e.parentId IN (SELECT parentId FROM {$this->table} WHERE id = :rec4id" . $index . ")))";
777 }
778 $where[] = implode(' OR ', $whereOr);
779 } else {
780 $queryIds = [];
781
782 foreach ((array)$criteria['id'] as $index => $value) {
783 $param = ':id' . $index;
784
785 $queryIds[] = $param;
786
787 $params[$param] = (int)$value;
788 }
789
790 $where[] = 'e.id IN (' . implode(', ', $queryIds) . ')';
791 }
792 }
793
794 $providerJoin = '';
795
796 if (!empty($criteria['providers'])) {
797 $providerJoin = "
798 LEFT JOIN {$eventsProvidersTable} epr ON epr.eventId = e.id
799 INNER JOIN {$usersTable} pu ON pu.id = epr.userId OR pu.id = e.organizerId";
800
801 $queryProviders = [];
802
803 foreach ((array)$criteria['providers'] as $index => $value) {
804 $param = ':provider' . $index;
805 $queryProviders[] = $param;
806 $params[$param] = $value;
807 }
808 $where1 = 'epr.userId IN (' . implode(', ', $queryProviders) . ')';
809
810 $queryProviders = [];
811 foreach ((array)$criteria['providers'] as $index => $value) {
812 $param = ':organizer' . $index;
813 $queryProviders[] = $param;
814 $params[$param] = $value;
815 }
816 $where2 = 'e.organizerId IN (' . implode(', ', $queryProviders) . ')';
817
818 $where[] = '(' . $where1 . ' OR ' . $where2 . ')';
819 }
820
821 $customerJoin = '';
822
823 $customerBookingsTable = CustomerBookingsTable::getTableName();
824 $customerBookingsEventsPeriods = CustomerBookingsToEventsPeriodsTable::getTableName();
825
826 if (!empty($criteria['customerId']) || !empty($criteria['customerBookingsIds'])) {
827 $customerJoin = "
828 LEFT JOIN {$customerBookingsEventsPeriods} cbe ON cbe.eventPeriodId = ep.id
829 LEFT JOIN {$customerBookingsTable} cb ON cb.id = cbe.customerBookingId";
830
831 if (!empty($criteria['customerId'])) {
832 $params[':customerId'] = $criteria['customerId'];
833
834 $where[] = 'cb.customerId = :customerId';
835 }
836
837 if (!empty($criteria['customerBookingsIds'])) {
838 $queryBookingsIds = [];
839
840 foreach ($criteria['customerBookingsIds'] as $index => $value) {
841 $param = ':customerBookingId' . $index;
842
843 $queryBookingsIds[] = $param;
844
845 $params[$param] = $value;
846 }
847
848 $where[] = 'cb.id IN (' . implode(', ', $queryBookingsIds) . ')';
849 }
850
851 if (!empty($criteria['customerBookingStatus'])) {
852 $params[':customerBookingStatus'] = $criteria['customerBookingStatus'];
853
854 $where[] = 'cb.status = :customerBookingStatus';
855 }
856
857 if (!empty($criteria['customerBookingCouponId'])) {
858 $params[':customerBookingCouponId'] = $criteria['customerBookingCouponId'];
859
860 $where[] = 'cb.couponId = :customerBookingCouponId';
861 }
862 }
863
864 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
865
866 try {
867 $statement = $this->connection->prepare(
868 "SELECT e.id
869 FROM {$this->table} e
870 INNER JOIN {$eventsPeriodsTable} ep ON ep.eventId = e.id
871 {$tagJoin}
872 {$providerJoin}
873 {$customerJoin}
874 {$where}
875 GROUP BY e.id
876 ORDER BY ep.periodStart"
877 );
878
879 $statement->execute($params);
880
881 $rows = $statement->fetchAll();
882 } catch (\Exception $e) {
883 throw new QueryExecutionException('Unable to find by id in ' . __CLASS__, $e->getCode(), $e);
884 }
885
886 return sizeOf($rows);
887 }
888
889 /**
890 * @param int $id
891 *
892 * @return Event
893 * @throws QueryExecutionException
894 * @throws InvalidArgumentException
895 */
896 public function getById($id)
897 {
898 $eventsPeriodsTable = EventsPeriodsTable::getTableName();
899 $eventsTagsTable = EventsTagsTable::getTableName();
900 $eventsTicketTable = EventsTicketsTable::getTableName();
901
902 $customerBookingsTable = CustomerBookingsTable::getTableName();
903 $paymentsTable = PaymentsTable::getTableName();
904 $usersTable = UsersTable::getTableName();
905 $customerBookingsEventsPeriods = CustomerBookingsToEventsPeriodsTable::getTableName();
906 $galleriesTable = GalleriesTable::getTableName();
907 $eventsProvidersTable = EventsProvidersTable::getTableName();
908 $couponsTable = CouponsTable::getTableName();
909
910 try {
911 $statement = $this->connection->prepare(
912 "SELECT
913 e.id AS event_id,
914 e.name AS event_name,
915 e.status AS event_status,
916 e.bookingOpens AS event_bookingOpens,
917 e.bookingCloses AS event_bookingCloses,
918 e.bookingOpensRec AS event_bookingOpensRec,
919 e.bookingClosesRec AS event_bookingClosesRec,
920 e.ticketRangeRec AS event_ticketRangeRec,
921 e.recurringCycle AS event_recurringCycle,
922 e.recurringOrder AS event_recurringOrder,
923 e.recurringInterval AS event_recurringInterval,
924 e.recurringMonthly AS event_recurringMonthly,
925 e.monthlyDate AS event_monthlyDate,
926 e.monthlyOnRepeat AS event_monthlyOnRepeat,
927 e.monthlyOnDay AS event_monthlyOnDay,
928 e.recurringUntil AS event_recurringUntil,
929 e.bringingAnyone AS event_bringingAnyone,
930 e.bookMultipleTimes AS event_bookMultipleTimes,
931 e.maxCapacity AS event_maxCapacity,
932 e.maxCustomCapacity AS event_maxCustomCapacity,
933 e.maxExtraPeople AS event_maxExtraPeople,
934 e.price AS event_price,
935 e.description AS event_description,
936 e.color AS event_color,
937 e.show AS event_show,
938 e.notifyParticipants AS event_notifyParticipants,
939 e.locationId AS event_locationId,
940 e.customLocation AS event_customLocation,
941 e.parentId AS event_parentId,
942 e.created AS event_created,
943 e.settings AS event_settings,
944 e.zoomUserId AS event_zoomUserId,
945 e.organizerId AS event_organizerId,
946 e.translations AS event_translations,
947 e.deposit AS event_deposit,
948 e.depositPayment AS event_depositPayment,
949 e.depositPerPerson AS event_depositPerPerson,
950 e.fullPayment AS event_fullPayment,
951 e.customPricing AS event_customPricing,
952 e.aggregatedPrice AS event_aggregatedPrice,
953
954 ep.id AS event_periodId,
955 ep.periodStart AS event_periodStart,
956 ep.periodEnd AS event_periodEnd,
957 ep.zoomMeeting AS event_periodZoomMeeting,
958 ep.lessonSpace AS event_periodLessonSpace,
959 ep.googleCalendarEventId AS event_googleCalendarEventId,
960 ep.googleMeetUrl AS event_googleMeetUrl,
961 ep.outlookCalendarEventId AS event_outlookCalendarEventId,
962 ep.microsoftTeamsUrl AS event_microsoftTeamsUrl,
963 ep.appleCalendarEventId AS event_appleCalendarEventId,
964
965 et.id AS event_tagId,
966 et.name AS event_tagName,
967
968 cb.id AS booking_id,
969 cb.customerId AS booking_customerId,
970 cb.status AS booking_status,
971 cb.price AS booking_price,
972 cb.persons AS booking_persons,
973 cb.customFields AS booking_customFields,
974 cb.info AS booking_info,
975 cb.aggregatedPrice AS booking_aggregatedPrice,
976 cb.token AS booking_token,
977 cb.utcOffset AS booking_utcOffset,
978 cb.couponId AS booking_couponId,
979
980 cu.id AS customer_id,
981 cu.firstName AS customer_firstName,
982 cu.lastName AS customer_lastName,
983 cu.email AS customer_email,
984 cu.note AS customer_note,
985 cu.phone AS customer_phone,
986 cu.gender AS customer_gender,
987 cu.birthday AS customer_birthday,
988
989 p.id AS payment_id,
990 p.amount AS payment_amount,
991 p.dateTime AS payment_dateTime,
992 p.status AS payment_status,
993 p.gateway AS payment_gateway,
994 p.gatewayTitle AS payment_gatewayTitle,
995 p.transactionId AS payment_transactionId,
996 p.data AS payment_data,
997 p.wcOrderId AS payment_wcOrderId,
998 p.wcOrderItemId AS payment_wcOrderItemId,
999 p.invoiceNumber AS payment_invoiceNumber,
1000
1001 pu.id AS provider_id,
1002 pu.firstName AS provider_firstName,
1003 pu.lastName AS provider_lastName,
1004 pu.email AS provider_email,
1005 pu.note AS provider_note,
1006 pu.description AS provider_description,
1007 pu.phone AS provider_phone,
1008 pu.gender AS provider_gender,
1009 pu.translations AS provider_translations,
1010 pu.timeZone AS provider_timeZone,
1011
1012 g.id AS gallery_id,
1013 g.pictureFullPath AS gallery_picture_full,
1014 g.pictureThumbPath AS gallery_picture_thumb,
1015 g.position AS gallery_position,
1016
1017 c.id AS coupon_id,
1018 c.code AS coupon_code,
1019 c.discount AS coupon_discount,
1020 c.deduction AS coupon_deduction,
1021 c.limit AS coupon_limit,
1022 c.customerLimit AS coupon_customerLimit,
1023 c.status AS coupon_status,
1024
1025 t.id AS ticket_id,
1026 t.name AS ticket_name,
1027 t.enabled AS ticket_enabled,
1028 t.price AS ticket_price,
1029 t.spots AS ticket_spots,
1030 t.waitingListSpots AS ticket_waiting_list_spots,
1031 t.dateRanges AS ticket_dateRanges,
1032 t.translations AS ticket_translations
1033
1034 FROM {$this->table} e
1035 INNER JOIN {$eventsPeriodsTable} ep ON ep.eventId = e.id
1036 LEFT JOIN {$eventsTagsTable} et ON et.eventId = e.id
1037 LEFT JOIN {$customerBookingsEventsPeriods} cbe ON cbe.eventPeriodId = ep.id
1038 LEFT JOIN {$customerBookingsTable} cb ON cb.id = cbe.customerBookingId
1039 LEFT JOIN {$usersTable} cu ON cu.id = cb.customerId
1040 LEFT JOIN {$eventsProvidersTable} epr ON epr.eventId = e.id
1041 LEFT JOIN {$usersTable} pu ON pu.id = epr.userId
1042 LEFT JOIN {$paymentsTable} p ON p.customerBookingId = cb.id
1043 LEFT JOIN {$galleriesTable} g ON g.entityId = e.id AND g.entityType = 'event'
1044 LEFT JOIN {$couponsTable} c ON c.id = cb.couponId
1045 LEFT JOIN {$eventsTicketTable} t ON t.eventId = e.id
1046
1047 WHERE e.id = :eventId"
1048 );
1049
1050 $statement->bindParam(':eventId', $id);
1051
1052 $statement->execute();
1053
1054 $rows = $statement->fetchAll();
1055 } catch (\Exception $e) {
1056 throw new QueryExecutionException('Unable to find event by id in ' . __CLASS__, $e->getCode(), $e);
1057 }
1058
1059 return call_user_func([static::FACTORY, 'createCollection'], $rows)->getItem($id);
1060 }
1061
1062
1063 /**
1064 * @param int $id
1065 *
1066 * @return mixed
1067 * @throws QueryExecutionException
1068 */
1069 public function isRecurring($id)
1070 {
1071 try {
1072 $statement = $this->connection->prepare(
1073 "SELECT
1074 e.recurringOrder AS event_recurringOrder,
1075 e.parentId AS event_parentId
1076 FROM {$this->table} e
1077 WHERE e.id = :eventId"
1078 );
1079
1080 $statement->bindParam(':eventId', $id);
1081
1082 $statement->execute();
1083
1084 return $statement->fetch();
1085 } catch (\Exception $e) {
1086 throw new QueryExecutionException('Unable to find event by id in ' . __CLASS__, $e->getCode(), $e);
1087 }
1088 }
1089
1090
1091 /**
1092 * @param int $id
1093 * @param int $parentId
1094 *
1095 * @return mixed
1096 * @throws QueryExecutionException
1097 */
1098 public function getRecurringIds($id, $parentId)
1099 {
1100 $whereParent = empty($parentId) ? '' : ' OR e.parentId = :parentId';
1101 try {
1102 $statement = $this->connection->prepare(
1103 "SELECT
1104 e.id AS eventId
1105 FROM {$this->table} e
1106 WHERE e.parentId = :eventId" . $whereParent
1107 );
1108
1109 $statement->bindParam(':eventId', $id);
1110 if ($parentId) {
1111 $statement->bindParam(':parentId', $parentId);
1112 }
1113
1114 $statement->execute();
1115
1116 $events = $statement->fetchAll();
1117
1118 return array_column($events, 'eventId');
1119 } catch (\Exception $e) {
1120 throw new QueryExecutionException('Unable to find event by id in ' . __CLASS__, $e->getCode(), $e);
1121 }
1122 }
1123
1124 /**
1125 * @param $criteria
1126 *
1127 * @return Collection
1128 * @throws InvalidArgumentException
1129 * @throws QueryExecutionException
1130 * @throws InvalidArgumentException
1131 */
1132 public function getWithCoupons($criteria)
1133 {
1134 $couponToEventsTable = CouponsToEventsTable::getTableName();
1135 $couponsTable = CouponsTable::getTableName();
1136 $eventsProvidersTable = EventsProvidersTable::getTableName();
1137 $usersTable = UsersTable::getTableName();
1138 $eventsTicketTable = EventsTicketsTable::getTableName();
1139
1140 $params = [];
1141
1142 $where = [];
1143
1144 foreach ((array)$criteria as $index => $value) {
1145 $params[':event' . $index] = $value['eventId'];
1146
1147 if ($value['couponId']) {
1148 $params[':coupon' . $index] = $value['couponId'];
1149 $params[':couponStatus' . $index] = Status::VISIBLE;
1150 }
1151
1152 $where[] = "(e.id = :event$index"
1153 . ($value['couponId'] ? " AND c.id = :coupon$index AND c.status = :couponStatus$index" : '') . ')';
1154 }
1155
1156 $where = $where ? 'WHERE ' . implode(' OR ', $where) : '';
1157
1158 try {
1159 $statement = $this->connection->prepare(
1160 "SELECT
1161 e.id AS event_id,
1162 e.name AS event_name,
1163 e.status AS event_status,
1164 e.bookingOpens AS event_bookingOpens,
1165 e.bookingCloses AS event_bookingCloses,
1166 e.recurringCycle AS event_recurringCycle,
1167 e.recurringOrder AS event_recurringOrder,
1168 e.recurringInterval AS event_recurringInterval,
1169 e.recurringUntil AS event_recurringUntil,
1170 e.bringingAnyone AS event_bringingAnyone,
1171 e.bookMultipleTimes AS event_bookMultipleTimes,
1172 e.maxCapacity AS event_maxCapacity,
1173 e.maxCustomCapacity AS event_maxCustomCapacity,
1174 e.maxExtraPeople AS event_maxExtraPeople,
1175 e.price AS event_price,
1176 e.description AS event_description,
1177 e.color AS event_color,
1178 e.show AS event_show,
1179 e.notifyParticipants AS event_notifyParticipants,
1180 e.locationId AS event_locationId,
1181 e.customLocation AS event_customLocation,
1182 e.parentId AS event_parentId,
1183 e.created AS event_created,
1184 e.translations AS event_translations,
1185 e.deposit AS event_deposit,
1186 e.depositPayment AS event_depositPayment,
1187 e.depositPerPerson AS event_depositPerPerson,
1188 e.fullPayment AS event_fullPayment,
1189 e.customPricing AS event_customPricing,
1190 e.aggregatedPrice AS event_aggregatedPrice,
1191
1192 pu.id AS provider_id,
1193 pu.firstName AS provider_firstName,
1194 pu.lastName AS provider_lastName,
1195 pu.email AS provider_email,
1196 pu.note AS provider_note,
1197 pu.description AS provider_description,
1198 pu.phone AS provider_phone,
1199 pu.gender AS provider_gender,
1200 pu.translations AS provider_translations,
1201
1202 t.id AS ticket_id,
1203 t.name AS ticket_name,
1204 t.enabled AS ticket_enabled,
1205 t.price AS ticket_price,
1206 t.spots AS ticket_spots,
1207 t.waitingListSpots AS ticket_waiting_list_spots,
1208 t.dateRanges AS ticket_dateRanges,
1209 t.translations AS ticket_translations,
1210
1211 c.id AS coupon_id,
1212 c.code AS coupon_code,
1213 c.discount AS coupon_discount,
1214 c.deduction AS coupon_deduction,
1215 c.limit AS coupon_limit,
1216 c.customerLimit AS coupon_customerLimit,
1217 c.status AS coupon_status
1218 FROM {$this->table} e
1219 LEFT JOIN {$couponToEventsTable} ce ON ce.eventId = e.id
1220 LEFT JOIN {$couponsTable} c ON c.id = ce.couponId
1221 LEFT JOIN {$eventsProvidersTable} epr ON epr.eventId = e.id
1222 LEFT JOIN {$usersTable} pu ON pu.id = epr.userId
1223 LEFT JOIN {$eventsTicketTable} t ON t.eventId = e.id
1224 {$where}"
1225 );
1226
1227 $statement->execute($params);
1228
1229 $rows = $statement->fetchAll();
1230 } catch (\Exception $e) {
1231 throw new QueryExecutionException('Unable to find by id in ' . __CLASS__, $e->getCode(), $e);
1232 }
1233
1234 return call_user_func([static::FACTORY, 'createCollection'], $rows);
1235 }
1236
1237 /**
1238 * @param int $bookingId
1239 * @param array $criteria
1240 *
1241 * @return Event
1242 * @throws QueryExecutionException
1243 * @throws InvalidArgumentException
1244 */
1245 public function getByBookingId($bookingId, $criteria = [])
1246 {
1247 $eventsPeriodsTable = EventsPeriodsTable::getTableName();
1248
1249 $customerBookingsEventsPeriods = CustomerBookingsToEventsPeriodsTable::getTableName();
1250
1251 $fields = '';
1252
1253 $joins = '';
1254
1255 if (!empty($criteria['fetchEventsCoupons'])) {
1256 $couponsTable = CouponsTable::getTableName();
1257
1258 $fields .= '
1259 ec.id AS coupon_id,
1260 ec.code AS coupon_code,
1261 ec.discount AS coupon_discount,
1262 ec.deduction AS coupon_deduction,
1263 ec.limit AS coupon_limit,
1264 ec.customerLimit AS coupon_customerLimit,
1265 ec.status AS coupon_status,
1266 ';
1267
1268 $joins .= "
1269 LEFT JOIN {$couponsTable} ec ON ec.id = cb.couponId
1270 ";
1271 }
1272
1273 if (!empty($criteria['fetchEventsTickets'])) {
1274 $ticketsTable = EventsTicketsTable::getTableName();
1275
1276 $fields .= '
1277 eti.id AS ticket_id,
1278 eti.name AS ticket_name,
1279 eti.enabled AS ticket_enabled,
1280 eti.price AS ticket_price,
1281 eti.spots AS ticket_spots,
1282 eti.waitingListSpots AS ticket_waiting_list_spots,
1283 eti.dateRanges AS ticket_dateRanges,
1284 eti.translations AS ticket_translations,
1285 ';
1286
1287 $joins .= "
1288 LEFT JOIN {$ticketsTable} eti ON eti.eventId = e.id
1289 ";
1290 }
1291
1292 if (!empty($criteria['fetchEventsTags'])) {
1293 $tagsTable = EventsTagsTable::getTableName();
1294
1295 $fields .= '
1296 eta.id AS event_tagId,
1297 eta.name AS event_tagName,
1298 ';
1299
1300 $joins .= "
1301 LEFT JOIN {$tagsTable} eta ON eta.eventId = e.id
1302 ";
1303 }
1304
1305 if (!empty($criteria['fetchEventsImages'])) {
1306 $galleriesTable = GalleriesTable::getTableName();
1307
1308 $fields .= '
1309 eg.id AS gallery_id,
1310 eg.pictureFullPath AS gallery_picture_full,
1311 eg.pictureThumbPath AS gallery_picture_thumb,
1312 eg.position AS gallery_position,
1313 ';
1314
1315 $joins .= "
1316 LEFT JOIN {$galleriesTable} eg ON eg.entityId = e.id AND eg.entityType = 'event'
1317 ";
1318 }
1319
1320 if (!empty($criteria['fetchEventsProviders'])) {
1321 $eventsProvidersTable = EventsProvidersTable::getTableName();
1322
1323 $usersTable = UsersTable::getTableName();
1324
1325 $joins .= "
1326 LEFT JOIN {$eventsProvidersTable} epr ON epr.eventId = e.id
1327 LEFT JOIN {$usersTable} pu ON pu.id = epr.userId
1328 ";
1329
1330 $fields .= '
1331 pu.id AS provider_id,
1332 pu.firstName AS provider_firstName,
1333 pu.lastName AS provider_lastName,
1334 pu.email AS provider_email,
1335 pu.note AS provider_note,
1336 pu.description AS provider_description,
1337 pu.phone AS provider_phone,
1338 pu.gender AS provider_gender,
1339 pu.pictureFullPath AS provider_pictureFullPath,
1340 pu.pictureThumbPath AS provider_pictureThumbPath,
1341 pu.translations AS provider_translations,
1342 pu.timeZone AS provider_timeZone,
1343 ';
1344 }
1345
1346 $fields .= "
1347 e.id AS event_id,
1348 e.name AS event_name,
1349 e.status AS event_status,
1350 e.bookingOpens AS event_bookingOpens,
1351 e.bookingCloses AS event_bookingCloses,
1352 e.recurringCycle AS event_recurringCycle,
1353 e.recurringOrder AS event_recurringOrder,
1354 e.recurringInterval AS event_recurringInterval,
1355 e.recurringUntil AS event_recurringUntil,
1356 e.bringingAnyone AS event_bringingAnyone,
1357 e.bookMultipleTimes AS event_bookMultipleTimes,
1358 e.maxCapacity AS event_maxCapacity,
1359 e.maxCustomCapacity AS event_maxCustomCapacity,
1360 e.maxExtraPeople AS event_maxExtraPeople,
1361 e.price AS event_price,
1362 e.description AS event_description,
1363 e.color AS event_color,
1364 e.show AS event_show,
1365 e.notifyParticipants AS event_notifyParticipants,
1366 e.locationId AS event_locationId,
1367 e.customLocation AS event_customLocation,
1368 e.customPricing AS event_customPricing,
1369 e.parentId AS event_parentId,
1370 e.created AS event_created,
1371 e.settings AS event_settings,
1372 e.zoomUserId AS event_zoomUserId,
1373 e.translations AS event_translations,
1374 e.deposit AS event_deposit,
1375 e.depositPayment AS event_depositPayment,
1376 e.depositPerPerson AS event_depositPerPerson,
1377 e.fullPayment AS event_fullPayment,
1378 e.organizerId AS event_organizerId,
1379 e.aggregatedPrice AS event_aggregatedPrice,
1380
1381 ep.id AS event_periodId,
1382 ep.periodStart AS event_periodStart,
1383 ep.periodEnd AS event_periodEnd,
1384 ep.zoomMeeting AS event_periodZoomMeeting,
1385 ep.lessonSpace AS event_periodLessonSpace,
1386 ep.googleCalendarEventId AS event_googleCalendarEventId,
1387 ep.googleMeetUrl AS event_googleMeetUrl,
1388 ep.outlookCalendarEventId AS event_outlookCalendarEventId,
1389 ep.microsoftTeamsUrl AS event_microsoftTeamsUrl,
1390 ep.appleCalendarEventId AS event_appleCalendarEventId
1391 ";
1392
1393 $params = [
1394 ':customerBookingId' => $bookingId,
1395 ];
1396
1397 try {
1398 $statement = $this->connection->prepare(
1399 "SELECT
1400 {$fields}
1401 FROM {$customerBookingsEventsPeriods} cbe
1402 INNER JOIN {$eventsPeriodsTable} ep ON ep.id = cbe.eventPeriodId
1403 INNER JOIN {$this->table} e ON e.id = ep.eventId
1404 {$joins}
1405 WHERE cbe.customerBookingId = :customerBookingId"
1406 );
1407
1408 $statement->execute($params);
1409
1410 $rows = $statement->fetchAll();
1411 } catch (\Exception $e) {
1412 throw new QueryExecutionException('Unable to find event by booking id in ' . __CLASS__, $e->getCode(), $e);
1413 }
1414
1415 /** @var Collection $events */
1416 $events = call_user_func([static::FACTORY, 'createCollection'], $rows);
1417
1418 return $events->length() ? $events->getItem($events->keys()[0]) : null;
1419 }
1420
1421 /**
1422 * @param array $ids
1423 * @param array $criteria
1424 *
1425 * @return Collection
1426 * @throws QueryExecutionException
1427 * @throws InvalidArgumentException
1428 */
1429 public function getByIdsWithEntities($ids, $criteria = [])
1430 {
1431 $params = [];
1432
1433 $where = [];
1434
1435 $fields = '';
1436
1437 $joins = '';
1438
1439 $orderBy = '';
1440
1441 if (!empty($criteria['fetchEventsPeriods'])) {
1442 $eventsPeriodsTable = EventsPeriodsTable::getTableName();
1443
1444 $fields .= '
1445 ep.id AS event_periodId,
1446 ep.periodStart AS event_periodStart,
1447 ep.periodEnd AS event_periodEnd,
1448 ep.zoomMeeting AS event_periodZoomMeeting,
1449 ep.lessonSpace AS event_periodLessonSpace,
1450 ep.googleCalendarEventId AS event_googleCalendarEventId,
1451 ep.googleMeetUrl AS event_googleMeetUrl,
1452 ep.outlookCalendarEventId AS event_outlookCalendarEventId,
1453 ep.microsoftTeamsUrl AS event_microsoftTeamsUrl,
1454 ep.appleCalendarEventId AS event_appleCalendarEventId,
1455 ';
1456
1457 $joins .= "
1458 INNER JOIN {$eventsPeriodsTable} ep ON ep.eventId = e.id
1459 ";
1460
1461 $orderBy = !empty($criteria['ordered']) ? 'ORDER BY e.id, ep.periodStart' : 'ORDER BY ep.periodStart';
1462 }
1463
1464 if (!empty($criteria['fetchEventsCoupons'])) {
1465 $couponsTable = CouponsTable::getTableName();
1466
1467 $fields .= '
1468 ec.id AS coupon_id,
1469 ec.code AS coupon_code,
1470 ec.discount AS coupon_discount,
1471 ec.deduction AS coupon_deduction,
1472 ec.limit AS coupon_limit,
1473 ec.customerLimit AS coupon_customerLimit,
1474 ec.status AS coupon_status,
1475 ';
1476
1477 $joins .= "
1478 LEFT JOIN {$couponsTable} ec ON ec.id = cb.couponId
1479 ";
1480 }
1481
1482 if (!empty($criteria['fetchEventsTickets'])) {
1483 $ticketsTable = EventsTicketsTable::getTableName();
1484
1485 $fields .= '
1486 eti.id AS ticket_id,
1487 eti.name AS ticket_name,
1488 eti.enabled AS ticket_enabled,
1489 eti.price AS ticket_price,
1490 eti.spots AS ticket_spots,
1491 eti.waitingListSpots AS ticket_waiting_list_spots,
1492 eti.dateRanges AS ticket_dateRanges,
1493 eti.translations AS ticket_translations,
1494 ';
1495
1496 $joins .= "
1497 LEFT JOIN {$ticketsTable} eti ON eti.eventId = e.id
1498 ";
1499 }
1500
1501 if (!empty($criteria['fetchEventsTags'])) {
1502 $tagsTable = EventsTagsTable::getTableName();
1503
1504 $fields .= '
1505 eta.id AS event_tagId,
1506 eta.name AS event_tagName,
1507 ';
1508
1509 $joins .= "
1510 LEFT JOIN {$tagsTable} eta ON eta.eventId = e.id
1511 ";
1512 }
1513
1514 if (!empty($criteria['fetchEventsImages'])) {
1515 $galleriesTable = GalleriesTable::getTableName();
1516
1517 $fields .= '
1518 eg.id AS gallery_id,
1519 eg.pictureFullPath AS gallery_picture_full,
1520 eg.pictureThumbPath AS gallery_picture_thumb,
1521 eg.position AS gallery_position,
1522 ';
1523
1524 $joins .= "
1525 LEFT JOIN {$galleriesTable} eg ON eg.entityId = e.id AND eg.entityType = 'event'
1526 ";
1527 }
1528
1529 if (!empty($criteria['fetchEventsProviders'])) {
1530 $eventsProvidersTable = EventsProvidersTable::getTableName();
1531
1532 $usersTable = UsersTable::getTableName();
1533
1534 $joins .= "
1535 LEFT JOIN {$eventsProvidersTable} epr ON epr.eventId = e.id
1536 LEFT JOIN {$usersTable} pu ON pu.id = epr.userId
1537 ";
1538
1539 $fields .= '
1540 pu.id AS provider_id,
1541 pu.firstName AS provider_firstName,
1542 pu.lastName AS provider_lastName,
1543 pu.email AS provider_email,
1544 pu.note AS provider_note,
1545 pu.description AS provider_description,
1546 pu.phone AS provider_phone,
1547 pu.gender AS provider_gender,
1548 pu.pictureFullPath AS provider_pictureFullPath,
1549 pu.pictureThumbPath AS provider_pictureThumbPath,
1550 pu.translations AS provider_translations,
1551 pu.timeZone AS provider_timeZone,
1552 ';
1553 }
1554
1555 $fields .= "
1556 e.id AS event_id,
1557 e.name AS event_name,
1558 e.status AS event_status,
1559 e.bookingOpens AS event_bookingOpens,
1560 e.bookingCloses AS event_bookingCloses,
1561 e.bookingOpensRec AS event_bookingOpensRec,
1562 e.bookingClosesRec AS event_bookingClosesRec,
1563 e.ticketRangeRec AS event_ticketRangeRec,
1564 e.recurringCycle AS event_recurringCycle,
1565 e.recurringOrder AS event_recurringOrder,
1566 e.recurringInterval AS event_recurringInterval,
1567 e.recurringMonthly AS event_recurringMonthly,
1568 e.monthlyDate AS event_monthlyDate,
1569 e.monthlyOnRepeat AS event_monthlyOnRepeat,
1570 e.monthlyOnDay AS event_monthlyOnDay,
1571 e.recurringUntil AS event_recurringUntil,
1572 e.bringingAnyone AS event_bringingAnyone,
1573 e.bookMultipleTimes AS event_bookMultipleTimes,
1574 e.maxCapacity AS event_maxCapacity,
1575 e.maxCustomCapacity AS event_maxCustomCapacity,
1576 e.maxExtraPeople AS event_maxExtraPeople,
1577 e.price AS event_price,
1578 e.description AS event_description,
1579 e.color AS event_color,
1580 e.show AS event_show,
1581 e.notifyParticipants AS event_notifyParticipants,
1582 e.locationId AS event_locationId,
1583 e.customLocation AS event_customLocation,
1584 e.parentId AS event_parentId,
1585 e.created AS event_created,
1586 e.settings AS event_settings,
1587 e.zoomUserId AS event_zoomUserId,
1588 e.organizerId AS event_organizerId,
1589 e.translations AS event_translations,
1590 e.deposit AS event_deposit,
1591 e.depositPayment AS event_depositPayment,
1592 e.depositPerPerson AS event_depositPerPerson,
1593 e.fullPayment AS event_fullPayment,
1594 e.customPricing AS event_customPricing,
1595 e.closeAfterMin AS event_closeAfterMin,
1596 e.closeAfterMinBookings AS event_closeAfterMinBookings,
1597 e.aggregatedPrice AS event_aggregatedPrice
1598 ";
1599
1600 if (!empty($ids)) {
1601 $queryIds = [];
1602
1603 foreach ($ids as $index => $value) {
1604 $param = ':id' . $index;
1605
1606 $queryIds[] = $param;
1607
1608 $params[$param] = $value;
1609 }
1610
1611 $where[] = 'e.id IN (' . implode(', ', $queryIds) . ')';
1612 }
1613
1614 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
1615
1616 try {
1617 $statement = $this->connection->prepare(
1618 "SELECT
1619 {$fields}
1620 FROM {$this->table} e
1621 {$joins}
1622 {$where}
1623 {$orderBy}"
1624 );
1625
1626 $statement->execute($params);
1627
1628 $rows = $statement->fetchAll();
1629 } catch (\Exception $e) {
1630 throw new QueryExecutionException('Unable to find event by id in ' . __CLASS__, $e->getCode(), $e);
1631 }
1632
1633 return call_user_func([static::FACTORY, 'createCollection'], $rows);
1634 }
1635
1636 /**
1637 * @param array $criteria
1638 *
1639 * @return Collection
1640 * @throws QueryExecutionException
1641 * @throws InvalidArgumentException
1642 */
1643 public function getBookingsByCriteria($criteria = [])
1644 {
1645 $params = [];
1646
1647 $where = [];
1648
1649 $fields = '';
1650
1651 $joins = '';
1652
1653 $eventsPeriodsTable = EventsPeriodsTable::getTableName();
1654
1655 $customerBookingsEventsPeriods = CustomerBookingsToEventsPeriodsTable::getTableName();
1656
1657 $customerBookingsTable = CustomerBookingsTable::getTableName();
1658
1659 if (!empty($criteria['fetchApprovedBookings'])) {
1660 $where[] = "cb.status = 'approved'";
1661 }
1662
1663 if (!empty($criteria['customerBookingId'])) {
1664 $params[':customerBookingId'] = $criteria['customerBookingId'];
1665
1666 $where[] = 'cb.id = :customerBookingId';
1667 }
1668
1669 if (!empty($criteria['fetchBookingsPayments'])) {
1670 $paymentsTable = PaymentsTable::getTableName();
1671
1672 $fields .= '
1673 p.id AS payment_id,
1674 p.amount AS payment_amount,
1675 p.dateTime AS payment_dateTime,
1676 p.created AS payment_created,
1677 p.status AS payment_status,
1678 p.gateway AS payment_gateway,
1679 p.gatewayTitle AS payment_gatewayTitle,
1680 p.transactionId AS payment_transactionId,
1681 p.data AS payment_data,
1682 p.wcOrderId AS payment_wcOrderId,
1683 p.wcOrderItemId AS payment_wcOrderItemId,
1684 p.invoiceNumber AS payment_invoiceNumber,
1685 ';
1686
1687 $joins .= "
1688 LEFT JOIN {$paymentsTable} p ON p.customerBookingId = cb.id
1689 ";
1690 }
1691
1692 if (!empty($criteria['fetchBookingsCoupons'])) {
1693 $couponsTable = CouponsTable::getTableName();
1694
1695 $fields .= '
1696 c.id AS coupon_id,
1697 c.code AS coupon_code,
1698 c.discount AS coupon_discount,
1699 c.deduction AS coupon_deduction,
1700 c.limit AS coupon_limit,
1701 c.customerLimit AS coupon_customerLimit,
1702 c.status AS coupon_status,
1703 ';
1704
1705 $joins .= "
1706 LEFT JOIN {$couponsTable} c ON c.id = cb.couponId
1707 ";
1708 }
1709
1710 if (!empty($criteria['fetchBookingsUsers'])) {
1711 $usersTable = UsersTable::getTableName();
1712
1713 $fields .= '
1714 cu.id AS customer_id,
1715 cu.type AS customer_type,
1716 cu.firstName AS customer_firstName,
1717 cu.lastName AS customer_lastName,
1718 cu.email AS customer_email,
1719 cu.note AS customer_note,
1720 cu.phone AS customer_phone,
1721 cu.gender AS customer_gender,
1722 cu.birthday AS customer_birthday,
1723 ';
1724
1725 $joins .= "
1726 INNER JOIN {$usersTable} cu ON cu.id = cb.customerId
1727 ";
1728 }
1729
1730 if (!empty($criteria['fetchBookingsTickets'])) {
1731 $bookingsTicketsTable = CustomerBookingToEventsTicketsTable::getTableName();
1732
1733 $fields .= '
1734 cbt.id AS booking_ticket_id,
1735 cbt.eventTicketId AS booking_ticket_eventTicketId,
1736 cbt.price AS booking_ticket_price,
1737 cbt.persons AS booking_ticket_persons,
1738 ';
1739
1740 $joins .= "
1741 LEFT JOIN {$bookingsTicketsTable} cbt ON cbt.customerBookingId = cb.id
1742 ";
1743 }
1744
1745 $fields .= '
1746 ep.eventId AS eventId,
1747 cb.id AS booking_id,
1748 cb.appointmentId AS booking_appointmentId,
1749 cb.customerId AS booking_customerId,
1750 cb.status AS booking_status,
1751 cb.price AS booking_price,
1752 cb.tax AS booking_tax,
1753 cb.persons AS booking_persons,
1754 cb.couponId AS booking_couponId,
1755 cb.customFields AS booking_customFields,
1756 cb.info AS booking_info,
1757 cb.utcOffset AS booking_utcOffset,
1758 cb.token AS booking_token,
1759 cb.aggregatedPrice AS booking_aggregatedPrice,
1760 cb.tax AS booking_tax
1761 ';
1762
1763 if (!empty($criteria['ids'])) {
1764 $queryIds = [];
1765
1766 foreach ($criteria['ids'] as $index => $value) {
1767 $param = ':id' . $index;
1768
1769 $queryIds[] = $param;
1770
1771 $params[$param] = $value;
1772 }
1773
1774 $where[] = 'ep.eventId IN (' . implode(', ', $queryIds) . ')';
1775 }
1776
1777 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
1778
1779 try {
1780 $statement = $this->connection->prepare(
1781 "SELECT
1782 {$fields}
1783 FROM {$eventsPeriodsTable} ep
1784 INNER JOIN {$customerBookingsEventsPeriods} cbe ON cbe.eventPeriodId = ep.id
1785 INNER JOIN {$customerBookingsTable} cb ON cb.id = cbe.customerBookingId
1786 {$joins}
1787 {$where}
1788 ORDER BY cb.id"
1789 );
1790
1791 $statement->execute($params);
1792
1793 $rows = $statement->fetchAll();
1794 } catch (\Exception $e) {
1795 throw new QueryExecutionException('Unable to find event by id in ' . __CLASS__, $e->getCode(), $e);
1796 }
1797
1798 $reformattedData = [];
1799
1800 foreach ($rows as $row) {
1801 if (empty($reformattedData[$row['eventId']])) {
1802 $reformattedData[$row['eventId']] = [];
1803 }
1804
1805 $reformattedData[$row['eventId']][] = $row;
1806 }
1807
1808 $result = new Collection();
1809
1810 foreach ($reformattedData as $eventId => $bookingsData) {
1811 $reformattedBookingsData = CustomerBookingFactory::reformat($bookingsData);
1812
1813 $eventBookings = new Collection();
1814
1815 foreach ($reformattedBookingsData as $bookingId => $data) {
1816 $eventBookings->addItem(CustomerBookingFactory::create($data), $bookingId);
1817 }
1818
1819 $result->addItem($eventBookings, $eventId);
1820 }
1821
1822 return $result;
1823 }
1824
1825
1826 /**
1827 * @param Event $event
1828 * @param array $booking
1829 * @param array $limitPerCustomer
1830 * @return int
1831 * @throws QueryExecutionException
1832 * @throws InvalidArgumentException
1833 */
1834 public function getRelevantBookingsCount($event, $booking, $limitPerCustomer)
1835 {
1836 $eventsPeriodsTable = EventsPeriodsTable::getTableName();
1837
1838 $customerBookingsEventsPeriods = CustomerBookingsToEventsPeriodsTable::getTableName();
1839
1840 $customerBookingsTable = CustomerBookingsTable::getTableName();
1841
1842 $params = [
1843 ':customerId' => $booking['customerId']
1844 ];
1845
1846 $paymentTableJoin = '';
1847 $compareToDate = 'ep.periodStart';
1848
1849 if ($limitPerCustomer['from'] === 'bookingDate') {
1850 $eventStartDate = (clone $event->getPeriods()->getItems()[0]->getPeriodStart()->getValue())->setTimezone(new \DateTimeZone('UTC'))->format('Y-m-d H:i');
1851 } else {
1852 $paymentTableJoin = 'INNER JOIN ' . PaymentsTable::getTableName() . ' p ON p.customerBookingId = cb.id';
1853 $eventStartDate = DateTimeService::getNowDateTimeObject()->setTimezone(new \DateTimeZone('UTC'))->format('Y-m-d H:i');
1854 $compareToDate = 'p.created';
1855 }
1856
1857 $intervalString = "interval " . $limitPerCustomer['period'] . " " . $limitPerCustomer['timeFrame'];
1858
1859 $where = "(STR_TO_DATE('". $eventStartDate ."', '%Y-%m-%d %H:%i:%s') BETWEEN " .
1860 "(" . $compareToDate . " - " . $intervalString . " + interval 1 second)" .
1861 " AND (".
1862 $compareToDate . " + " . $intervalString . " - interval 1 second))";
1863
1864 try {
1865 $statement = $this->connection->prepare(
1866 "SELECT COUNT(DISTINCT cb.id) AS count FROM
1867 {$this->table} e
1868 INNER JOIN {$eventsPeriodsTable} ep ON ep.eventId = e.id
1869 INNER JOIN {$customerBookingsEventsPeriods} cbep ON cbep.eventPeriodId = ep.id
1870 INNER JOIN {$customerBookingsTable} cb ON cb.id = cbep.customerBookingId
1871 {$paymentTableJoin}
1872 WHERE cb.customerId = :customerId AND {$where} AND e.status = 'approved' AND cb.status = 'approved'
1873 "
1874 );
1875
1876 $statement->execute($params);
1877
1878 $rows = $statement->fetch()['count'];
1879 } catch (\Exception $e) {
1880 throw new QueryExecutionException('Unable to find by id in ' . __CLASS__, $e->getCode(), $e);
1881 }
1882
1883 return $rows;
1884 }
1885 }
1886