PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 1.2.20
Booking for Appointments and Events Calendar – Amelia v1.2.20
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 / Coupon / CouponRepository.php
ameliabooking / src / Infrastructure / Repository / Coupon Last commit date
CouponEventRepository.php 6 years ago CouponPackageRepository.php 3 years ago CouponRepository.php 1 year ago CouponServiceRepository.php 6 years ago
CouponRepository.php
718 lines
1 <?php
2 /**
3 * @copyright © TMS-Plugins. All rights reserved.
4 * @licence See LICENCE.md for license details.
5 */
6
7 namespace AmeliaBooking\Infrastructure\Repository\Coupon;
8
9 use AmeliaBooking\Domain\Collection\Collection;
10 use AmeliaBooking\Domain\Common\Exceptions\InvalidArgumentException;
11 use AmeliaBooking\Domain\Entity\Coupon\Coupon;
12 use AmeliaBooking\Domain\Entity\Entities;
13 use AmeliaBooking\Domain\Factory\Coupon\CouponFactory;
14 use AmeliaBooking\Domain\Services\DateTime\DateTimeService;
15 use AmeliaBooking\Domain\ValueObjects\Number\Integer\WholeNumber;
16 use AmeliaBooking\Infrastructure\Common\Exceptions\NotFoundException;
17 use AmeliaBooking\Infrastructure\Connection;
18 use AmeliaBooking\Infrastructure\Repository\AbstractRepository;
19 use AmeliaBooking\Domain\Repository\Coupon\CouponRepositoryInterface;
20 use AmeliaBooking\Infrastructure\Common\Exceptions\QueryExecutionException;
21
22 /**
23 * Class CouponRepository
24 *
25 * @package AmeliaBooking\Infrastructure\Repository\Coupon
26 */
27 class CouponRepository extends AbstractRepository implements CouponRepositoryInterface
28 {
29
30 const FACTORY = CouponFactory::class;
31
32 /** @var string */
33 protected $servicesTable;
34
35 /** @var string */
36 protected $couponToServicesTable;
37
38 /** @var string */
39 protected $eventsTable;
40
41 /** @var string */
42 protected $couponToEventsTable;
43
44 /** @var string */
45 protected $packagesTable;
46
47 /** @var string */
48 protected $couponToPackagesTable;
49
50 /** @var string */
51 protected $bookingsTable;
52
53 /**
54 * @param Connection $connection
55 * @param string $table
56 * @param string $servicesTable
57 * @param string $couponToServicesTable
58 * @param string $eventsTable
59 * @param string $couponToEventsTable
60 * @param string $packagesTable
61 * @param string $couponToPackagesTable
62 * @param string $bookingsTable
63 */
64 public function __construct(
65 Connection $connection,
66 $table,
67 $servicesTable,
68 $couponToServicesTable,
69 $eventsTable,
70 $couponToEventsTable,
71 $packagesTable,
72 $couponToPackagesTable,
73 $bookingsTable
74 ) {
75 parent::__construct($connection, $table);
76
77 $this->servicesTable = $servicesTable;
78 $this->couponToServicesTable = $couponToServicesTable;
79 $this->eventsTable = $eventsTable;
80 $this->couponToEventsTable = $couponToEventsTable;
81 $this->packagesTable = $packagesTable;
82 $this->couponToPackagesTable = $couponToPackagesTable;
83 $this->bookingsTable = $bookingsTable;
84 }
85
86 /**
87 * @param Coupon $entity
88 *
89 * @return bool
90 * @throws QueryExecutionException
91 */
92 public function add($entity)
93 {
94 $data = $entity->toArray();
95
96 $params = [
97 ':code' => $data['code'],
98 ':discount' => $data['discount'],
99 ':deduction' => $data['deduction'],
100 ':limit' => (int)$data['limit'],
101 ':customerLimit' => (int)$data['customerLimit'],
102 ':status' => $data['status'],
103 ':notificationInterval' => $data['notificationInterval'],
104 ':notificationRecurring' => $data['notificationRecurring'] ? 1 : 0,
105 ':expirationDate' => $data['expirationDate'],
106 ':allServices' => $data['allServices'],
107 ':allEvents' => $data['allEvents'],
108 ':allPackages' => $data['allPackages']
109 ];
110
111 try {
112 $statement = $this->connection->prepare(
113 "INSERT INTO
114 {$this->table}
115 (
116 `code`, `discount`, `deduction`, `limit`, `customerLimit`, `status`, `notificationInterval`, `notificationRecurring`, `expirationDate`, `allServices`, `allEvents`, `allPackages`
117 ) VALUES (
118 :code, :discount, :deduction, :limit, :customerLimit, :status, :notificationInterval, :notificationRecurring, :expirationDate, :allServices, :allEvents, :allPackages
119 )"
120 );
121
122
123 $response = $statement->execute($params);
124 } catch (\Exception $e) {
125 throw new QueryExecutionException('Unable to add data in ' . __CLASS__, $e->getCode(), $e);
126 }
127
128 if (!$response) {
129 throw new QueryExecutionException('Unable to add data in ' . __CLASS__);
130 }
131
132 return $this->connection->lastInsertId();
133 }
134
135 /**
136 * @param int $id
137 * @param Coupon $entity
138 *
139 * @return bool
140 * @throws QueryExecutionException
141 */
142 public function update($id, $entity)
143 {
144 $data = $entity->toArray();
145
146 $params = [
147 ':code' => $data['code'],
148 ':discount' => $data['discount'],
149 ':deduction' => $data['deduction'],
150 ':limit' => (int)$data['limit'],
151 ':customerLimit' => (int)$data['customerLimit'],
152 ':status' => $data['status'],
153 ':notificationInterval' => $data['notificationInterval'],
154 ':notificationRecurring' => $data['notificationRecurring'] ? 1 : 0,
155 ':id' => $id,
156 ':expirationDate' => $data['expirationDate'],
157 ':allServices' => $data['allServices'],
158 ':allEvents' => $data['allEvents'],
159 ':allPackages' => $data['allPackages']
160 ];
161
162 try {
163 $statement = $this->connection->prepare(
164 "UPDATE {$this->table}
165 SET
166 `code` = :code,
167 `discount` = :discount,
168 `deduction` = :deduction,
169 `limit` = :limit,
170 `customerLimit` = :customerLimit,
171 `status` = :status,
172 `notificationInterval` = :notificationInterval,
173 `notificationRecurring` = :notificationRecurring,
174 `expirationDate` = :expirationDate,
175 `allServices` = :allServices,
176 `allEvents` = :allEvents,
177 `allPackages` = :allPackages
178 WHERE
179 id = :id"
180 );
181
182 $response = $statement->execute($params);
183 } catch (\Exception $e) {
184 throw new QueryExecutionException('Unable to save data in ' . __CLASS__ . $e->getMessage());
185 }
186
187 if (!$response) {
188 throw new QueryExecutionException('Unable to save data in ' . __CLASS__);
189 }
190
191 return $response;
192 }
193
194 /**
195 * @param int $id
196 *
197 * @return Coupon
198 * @throws QueryExecutionException
199 * @throws NotFoundException
200 */
201 public function getById($id)
202 {
203 try {
204 $statement = $this->connection->prepare(
205 "SELECT
206 c.id AS coupon_id,
207 c.code AS coupon_code,
208 c.discount AS coupon_discount,
209 c.deduction AS coupon_deduction,
210 c.limit AS coupon_limit,
211 c.customerLimit AS coupon_customerLimit,
212 c.notificationInterval AS coupon_notificationInterval,
213 c.notificationRecurring AS coupon_notificationRecurring,
214 c.status AS coupon_status,
215 c.expirationDate AS coupon_expirationDate,
216 c.allServices AS coupon_allServices,
217 c.allEvents AS coupon_allEvents,
218 c.allPackages AS coupon_allPackages,
219 s.id AS service_id,
220 s.price AS service_price,
221 s.minCapacity AS service_minCapacity,
222 s.maxCapacity AS service_maxCapacity,
223 s.name AS service_name,
224 s.description AS service_description,
225 s.color AS service_color,
226 s.status AS service_status,
227 s.categoryId AS service_categoryId,
228 s.duration AS service_duration,
229 e.id AS event_id,
230 e.price AS event_price,
231 e.name AS event_name,
232 p.id AS package_id,
233 p.price AS package_price,
234 p.name AS package_name
235 FROM {$this->table} c
236 LEFT JOIN {$this->couponToServicesTable} cs ON cs.couponId = c.id
237 LEFT JOIN {$this->couponToEventsTable} ce ON ce.couponId = c.id
238 LEFT JOIN {$this->couponToPackagesTable} cp ON cp.couponId = c.id
239 LEFT JOIN {$this->servicesTable} s ON cs.serviceId = s.id
240 LEFT JOIN {$this->eventsTable} e ON ce.eventId = e.id
241 LEFT JOIN {$this->packagesTable} p ON cp.packageId = p.id
242 WHERE c.id = :couponId"
243 );
244
245 $statement->bindParam(':couponId', $id);
246
247 $statement->execute();
248
249 $rows = $statement->fetchAll();
250 } catch (\Exception $e) {
251 throw new QueryExecutionException('Unable to find by id in ' . __CLASS__, $e->getCode(), $e);
252 }
253
254 if (!$rows) {
255 throw new NotFoundException('Data not found in ' . __CLASS__);
256 }
257
258 return call_user_func([static::FACTORY, 'createCollection'], $rows)->getItem($id);
259 }
260
261 /**
262 * @param array $criteria
263 * @param int $itemsPerPage
264 *
265 * @return Collection
266 * @throws QueryExecutionException
267 */
268 public function getFiltered($criteria, $itemsPerPage)
269 {
270 try {
271 $params = [];
272
273 $where = [];
274
275 if (!empty($criteria['search'])) {
276 $params[':search'] = "%{$criteria['search']}%";
277
278 $where[] = 'UPPER(c.code) LIKE UPPER(:search)';
279 }
280
281 if (!empty($criteria['ids'])) {
282 $queryIds = [];
283
284 foreach ((array)$criteria['ids'] as $index => $value) {
285 $param = ':id' . $index;
286 $queryIds[] = $param;
287 $params[$param] = $value;
288 }
289
290 $where[] = "c.id IN (" . implode(', ', $queryIds) . ')';
291 }
292
293 if (!empty($criteria['services'])) {
294 $queryServices = [];
295
296 foreach ((array)$criteria['services'] as $index => $value) {
297 $param = ':service' . $index;
298 $queryServices[] = $param;
299 $params[$param] = $value;
300 }
301
302 $where[] = "c.id IN (
303 SELECT couponId FROM {$this->couponToServicesTable}
304 WHERE serviceId IN (" . implode(', ', $queryServices) . ')
305 )';
306 }
307
308 if (!empty($criteria['events'])) {
309 $queryEvents = [];
310
311 foreach ((array)$criteria['events'] as $index => $value) {
312 $param = ':event' . $index;
313 $queryEvents[] = $param;
314 $params[$param] = $value;
315 }
316
317 $where[] = "c.id IN (
318 SELECT couponId FROM {$this->couponToEventsTable}
319 WHERE eventId IN (" . implode(', ', $queryEvents) . ')
320 )';
321 }
322
323 if (!empty($criteria['packages'])) {
324 $queryPackages = [];
325
326 foreach ((array)$criteria['packages'] as $index => $value) {
327 $param = ':package' . $index;
328 $queryPackages[] = $param;
329 $params[$param] = $value;
330 }
331
332 $where[] = "c.id IN (
333 SELECT couponId FROM {$this->couponToPackagesTable}
334 WHERE packageId IN (" . implode(', ', $queryPackages) . ')
335 )';
336 }
337
338
339 $where = $where ? ' WHERE ' . implode(' AND ', $where) : '';
340
341 $limit = $this->getLimit(
342 !empty($criteria['page']) ? (int)$criteria['page'] : 0,
343 (int)$itemsPerPage
344 );
345
346 $statement = $this->connection->prepare(
347 "SELECT
348 c.id AS coupon_id,
349 c.code AS coupon_code,
350 c.discount AS coupon_discount,
351 c.deduction AS coupon_deduction,
352 c.limit AS coupon_limit,
353 c.customerLimit AS coupon_customerLimit,
354 c.notificationInterval AS coupon_notificationInterval,
355 c.notificationRecurring AS coupon_notificationRecurring,
356 c.status AS coupon_status,
357 c.expirationDate AS coupon_expirationDate,
358 c.allServices AS coupon_allServices,
359 c.allEvents AS coupon_allEvents,
360 c.allPackages AS coupon_allPackages
361 FROM {$this->table} c
362 {$where}
363 {$limit}"
364 );
365
366 $statement->execute($params);
367
368 $rows = $statement->fetchAll();
369 } catch (\Exception $e) {
370 throw new QueryExecutionException('Unable to get data from ' . __CLASS__, $e->getCode(), $e);
371 }
372
373 return call_user_func([static::FACTORY, 'createCollection'], $rows);
374 }
375
376 /**
377 * @param array $criteria
378 *
379 * @return mixed
380 * @throws QueryExecutionException
381 */
382 public function getCount($criteria)
383 {
384 try {
385 $params = [];
386
387 $where = [];
388
389 if (!empty($criteria['search'])) {
390 $params[':search'] = "%{$criteria['search']}%";
391
392 $where[] = 'c.code LIKE :search';
393 }
394
395 if (!empty($criteria['services'])) {
396 $queryServices = [];
397
398 foreach ((array)$criteria['services'] as $index => $value) {
399 $param = ':service' . $index;
400 $queryServices[] = $param;
401 $params[$param] = $value;
402 }
403
404 $where[] = "c.id IN (SELECT couponId FROM {$this->couponToServicesTable}
405 WHERE serviceId IN (" . implode(', ', $queryServices) . '))';
406 }
407
408 $where = $where ? ' WHERE ' . implode(' AND ', $where) : '';
409
410 $statement = $this->connection->prepare(
411 "SELECT COUNT(*) AS count
412 FROM {$this->table} c
413 $where"
414 );
415
416 $statement->execute($params);
417
418 $row = $statement->fetch()['count'];
419 } catch (\Exception $e) {
420 throw new QueryExecutionException('Unable to get data from ' . __CLASS__, $e->getCode(), $e);
421 }
422
423 return $row;
424 }
425
426 /**
427 * @param int $id
428 * @param string $status
429 *
430 * @return mixed
431 * @throws QueryExecutionException
432 */
433 public function updateStatusById($id, $status)
434 {
435 $params = [
436 ':id' => $id,
437 ':status' => $status
438 ];
439
440 try {
441 $statement = $this->connection->prepare(
442 "UPDATE {$this->table}
443 SET
444 `status` = :status
445 WHERE id = :id"
446 );
447
448 $res = $statement->execute($params);
449
450 if (!$res) {
451 throw new QueryExecutionException('Unable to save data in ' . __CLASS__);
452 }
453
454 return $res;
455 } catch (\Exception $e) {
456 throw new QueryExecutionException('Unable to save data in ' . __CLASS__, $e->getCode(), $e);
457 }
458 }
459
460 /**
461 * @param array $criteria
462 *
463 * @return Collection
464 * @throws QueryExecutionException
465 * @throws InvalidArgumentException
466 * @throws InvalidArgumentException
467 */
468 public function getAllByCriteria($criteria)
469 {
470 try {
471 $params = [];
472
473 $where = [];
474
475 if (isset($criteria['code'])) {
476 $where[] = $criteria['couponsCaseInsensitive'] ? 'LOWER(c.code) = LOWER(:code)' : 'c.code = :code';
477
478 $params[':code'] = $criteria['code'];
479 }
480
481 if (!empty($criteria['notificationInterval'])) {
482 $where[] = 'c.notificationInterval != 0';
483 }
484
485 if (!empty($criteria['notExpired'])) {
486 $currentDateTime = "STR_TO_DATE('" . DateTimeService::getNowDateTimeInUtc() . "', '%Y-%m-%d %H:%i:%s')";
487
488 $where[] = "(c.expirationDate IS NULL OR c.expirationDate >= {$currentDateTime})";
489 }
490
491 if (!empty($criteria['couponIds'])) {
492 $couponIdsParams = [];
493
494 foreach ((array)$criteria['couponIds'] as $key => $id) {
495 $couponIdsParams[":id$key"] = $id;
496 }
497
498 if ($couponIdsParams) {
499 $where[] = '(c.id IN ( ' . implode(', ', array_keys($couponIdsParams)) . '))';
500
501 $params = array_merge($params, $couponIdsParams);
502 }
503 }
504
505 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
506
507 $statement = $this->connection->prepare(
508 "SELECT
509 c.id AS coupon_id,
510 c.code AS coupon_code,
511 c.discount AS coupon_discount,
512 c.deduction AS coupon_deduction,
513 c.limit AS coupon_limit,
514 c.customerLimit AS coupon_customerLimit,
515 c.notificationInterval AS coupon_notificationInterval,
516 c.notificationRecurring AS coupon_notificationRecurring,
517 c.status AS coupon_status,
518 c.expirationDate AS coupon_expirationDate,
519 c.allServices AS coupon_allServices,
520 c.allEvents AS coupon_allEvents,
521 c.allPackages AS coupon_allPackages
522 FROM {$this->table} c
523 {$where}"
524 );
525
526 $statement->execute($params);
527
528 $rows = $statement->fetchAll();
529 } catch (\Exception $e) {
530 throw new QueryExecutionException('Unable to find by id in ' . __CLASS__, $e->getCode(), $e);
531 }
532
533 /** @var Collection $coupons */
534 $coupons = call_user_func([static::FACTORY, 'createCollection'], $rows);
535
536 if (!$coupons->length()) {
537 return $coupons;
538 }
539
540 $params = [];
541
542 foreach ($coupons->keys() as $key => $id) {
543 $params[":id$key"] = $id;
544 }
545
546 $where = 'WHERE cb.couponId IN ( ' . implode(', ', array_keys($params)) . ')';
547
548 try {
549 $statement = $this->connection->prepare(
550 "SELECT
551 DISTINCT(cb.couponId) AS couponId,
552 COUNT(*) AS used
553 FROM {$this->bookingsTable} cb
554 {$where}
555 GROUP BY cb.couponId"
556 );
557
558 $statement->execute($params);
559
560 $rows = $statement->fetchAll();
561 } catch (\Exception $e) {
562 throw new QueryExecutionException('Unable to find by id in ' . __CLASS__, $e->getCode(), $e);
563 }
564
565 foreach ($rows as $row) {
566 if ($coupons->keyExists($row['couponId'])) {
567 /** @var Coupon $coupon */
568 $coupon = $coupons->getItem($row['couponId']);
569
570 $coupon->setUsed(new WholeNumber($row['used']));
571 }
572 }
573
574 return $coupons;
575 }
576
577 /**
578 * @param array $couponIds
579 * @param array $serviceIds
580 *
581 * @return array
582 *
583 * @throws QueryExecutionException
584 */
585 public function getCouponsServicesIds($couponIds, $serviceIds = [])
586 {
587 $couponsParams = [];
588
589 $servicesParams = [];
590
591 $where = [];
592
593 if ($couponIds) {
594 foreach ($couponIds as $key => $couponId) {
595 $couponsParams[":id$key"] = $couponId;
596 }
597
598 $where[] = '(couponId IN (' . implode(', ', array_keys($couponsParams)) . '))';
599 }
600
601 if ($serviceIds) {
602 foreach ($serviceIds as $key => $serviceId) {
603 $servicesParams[":serviceId$key"] = $serviceId;
604 }
605
606 $where[] = '(serviceId IN (' . implode(', ', array_keys($servicesParams)) . '))';
607 }
608
609 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
610
611 try {
612 $statement = $this->connection->prepare(
613 "SELECT serviceId, couponId FROM {$this->couponToServicesTable} {$where} GROUP BY serviceId, couponId"
614 );
615
616 $statement->execute(array_merge($couponsParams, $servicesParams));
617
618 return $statement->fetchAll();
619 } catch (\Exception $e) {
620 throw new QueryExecutionException('Unable to get data from ' . __CLASS__, $e->getCode(), $e);
621 }
622 }
623
624 /**
625 * @param array $couponIds
626 * @param array $eventIds
627 *
628 * @return array
629 *
630 * @throws QueryExecutionException
631 */
632 public function getCouponsEventsIds($couponIds, $eventIds = [])
633 {
634 $couponsParams = [];
635
636 $eventsParams = [];
637
638 $where = [];
639
640 if ($couponIds) {
641 foreach ($couponIds as $key => $couponId) {
642 $couponsParams[":id$key"] = $couponId;
643 }
644
645 $where[] = '(couponId IN (' . implode(', ', array_keys($couponsParams)) . '))';
646 }
647
648 if ($eventIds) {
649 foreach ($eventIds as $key => $eventId) {
650 $eventsParams[":eventId$key"] = $eventId;
651 }
652
653 $where[] = '(eventId IN (' . implode(', ', array_keys($eventsParams)) . '))';
654 }
655
656 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
657
658 try {
659 $statement = $this->connection->prepare(
660 "SELECT eventId, couponId FROM {$this->couponToEventsTable} {$where} GROUP BY eventId, couponId"
661 );
662
663 $statement->execute(array_merge($couponsParams, $eventsParams));
664
665 return $statement->fetchAll();
666 } catch (\Exception $e) {
667 throw new QueryExecutionException('Unable to get data from ' . __CLASS__, $e->getCode(), $e);
668 }
669 }
670
671 /**
672 * @param array $couponIds
673 * @param array $packageIds
674 *
675 * @return array
676 *
677 * @throws QueryExecutionException
678 */
679 public function getCouponsPackagesIds($couponIds, $packageIds = [])
680 {
681 $couponsParams = [];
682
683 $packagesParams = [];
684
685 $where = [];
686
687 if ($couponIds) {
688 foreach ($couponIds as $key => $couponId) {
689 $couponsParams[":id$key"] = $couponId;
690 }
691
692 $where[] = '(couponId IN (' . implode(', ', array_keys($couponsParams)) . '))';
693 }
694
695 if ($packageIds) {
696 foreach ($packageIds as $key => $packageId) {
697 $packagesParams[":packageId$key"] = $packageId;
698 }
699
700 $where[] = '(packageId IN (' . implode(', ', array_keys($packagesParams)) . '))';
701 }
702
703 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
704
705 try {
706 $statement = $this->connection->prepare(
707 "SELECT packageId, couponId FROM {$this->couponToPackagesTable} {$where} GROUP BY packageId, couponId"
708 );
709
710 $statement->execute(array_merge($couponsParams, $packagesParams));
711
712 return $statement->fetchAll();
713 } catch (\Exception $e) {
714 throw new QueryExecutionException('Unable to get data from ' . __CLASS__, $e->getCode(), $e);
715 }
716 }
717 }
718