PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 1.2.11
Booking for Appointments and Events Calendar – Amelia v1.2.11
2.4.4 2.4.3 2.4.2 2.4.1 2.4 trunk 1.2.1 1.2.10 1.2.11 1.2.12 1.2.13 1.2.14 1.2.15 1.2.16 1.2.17 1.2.18 1.2.19 1.2.2 1.2.20 1.2.21 1.2.22 1.2.23 1.2.24 1.2.25 1.2.26 1.2.27 1.2.28 1.2.29 1.2.3 1.2.30 1.2.31 1.2.32 1.2.33 1.2.34 1.2.35 1.2.36 1.2.37 1.2.38 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 2.0 2.0.1 2.0.2 2.1 2.1.1 2.1.2 2.1.3 2.2 2.2.1 2.3
ameliabooking / src / Infrastructure / Repository / Booking / Appointment / CustomerBookingRepository.php
ameliabooking / src / Infrastructure / Repository / Booking / Appointment Last commit date
AppointmentRepository.php 1 year ago CustomerBookingExtraRepository.php 2 years ago CustomerBookingRepository.php 1 year ago
CustomerBookingRepository.php
652 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\EventsPeriodsTable;
16 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Coupon\CouponsTable;
17 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Payment\PaymentsTable;
18 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\User\UsersTable;
19 use Exception;
20
21 /**
22 * Class CustomerBookingRepository
23 *
24 * @package AmeliaBooking\Infrastructure\Repository\Booking\Appointment
25 */
26 class CustomerBookingRepository extends AbstractRepository implements CustomerBookingRepositoryInterface
27 {
28
29 const FACTORY = CustomerBookingFactory::class;
30
31 /**
32 * @param CustomerBooking $entity
33 *
34 * @return mixed
35 * @throws QueryExecutionException
36 */
37 public function add($entity)
38 {
39 $data = $entity->toArray();
40
41 $params = [
42 ':appointmentId' => $data['appointmentId'],
43 ':customerId' => $data['customerId'],
44 ':status' => $data['status'],
45 ':price' => $data['price'],
46 ':tax' => !empty($data['tax']) ? json_encode($data['tax']) : null,
47 ':persons' => $data['persons'],
48 ':couponId' => !empty($data['coupon']) ? $data['coupon']['id'] : null,
49 ':token' => $data['token'],
50 ':customFields' => $data['customFields'] && json_decode($data['customFields']) !== false ?
51 $data['customFields'] : null,
52 ':info' => $data['info'],
53 ':aggregatedPrice' => $data['aggregatedPrice'] ? 1 : 0,
54 ':utcOffset' => $data['utcOffset'],
55 ':packageCustomerServiceId' => !empty($data['packageCustomerService']['id']) ?
56 $data['packageCustomerService']['id'] : null,
57 ':duration' => !empty($data['duration']) ? $data['duration'] : null,
58 ':created' => !empty($data['created']) ?
59 DateTimeService::getCustomDateTimeInUtc($data['created']) : DateTimeService::getNowDateTimeInUtc(),
60 ':actionsCompleted' => $data['actionsCompleted'] ? 1 : 0,
61 ];
62
63 try {
64 $statement = $this->connection->prepare(
65 "INSERT INTO {$this->table}
66 (
67 `appointmentId`,
68 `customerId`,
69 `status`,
70 `price`,
71 `tax`,
72 `persons`,
73 `couponId`,
74 `token`,
75 `customFields`,
76 `info`,
77 `aggregatedPrice`,
78 `utcOffset`,
79 `packageCustomerServiceId`,
80 `duration`,
81 `created`,
82 `actionsCompleted`
83 )
84 VALUES (
85 :appointmentId,
86 :customerId,
87 :status,
88 :price,
89 :tax,
90 :persons,
91 :couponId,
92 :token,
93 :customFields,
94 :info,
95 :aggregatedPrice,
96 :utcOffset,
97 :packageCustomerServiceId,
98 :duration,
99 :created,
100 :actionsCompleted
101 )"
102 );
103
104 $res = $statement->execute($params);
105
106 if (!$res) {
107 throw new QueryExecutionException('Unable to add data in ' . __CLASS__);
108 }
109
110 return $this->connection->lastInsertId();
111 } catch (Exception $e) {
112 throw new QueryExecutionException('Unable to add data in ' . __CLASS__, $e->getCode(), $e);
113 }
114 }
115
116 /**
117 * @param int $id
118 * @param CustomerBooking $entity
119 *
120 * @return mixed
121 * @throws QueryExecutionException
122 */
123 public function update($id, $entity)
124 {
125 $data = $entity->toArray();
126
127 $params = [
128 ':id' => $id,
129 ':customerId' => $data['customerId'],
130 ':status' => $data['status'],
131 ':duration' => !empty($data['duration']) ? $data['duration'] : null,
132 ':persons' => $data['persons'],
133 ':couponId' => !empty($data['coupon']) ? $data['coupon']['id'] : null,
134 ':customFields' => $data['customFields'],
135 ];
136
137 try {
138 $statement = $this->connection->prepare(
139 "UPDATE {$this->table} SET
140 `customerId` = :customerId,
141 `status` = :status,
142 `duration` = :duration,
143 `persons` = :persons,
144 `couponId` = :couponId,
145 `customFields` = :customFields
146 WHERE id = :id"
147 );
148
149 $res = $statement->execute($params);
150
151 if (!$res) {
152 throw new QueryExecutionException('Unable to save data in ' . __CLASS__);
153 }
154
155 return $res;
156 } catch (Exception $e) {
157 throw new QueryExecutionException('Unable to save data in ' . __CLASS__, $e->getCode(), $e);
158 }
159 }
160
161 /**
162 * @param int $id
163 * @param CustomerBooking $entity
164 *
165 * @return mixed
166 * @throws QueryExecutionException
167 */
168 public function updatePrice($id, $entity)
169 {
170 $data = $entity->toArray();
171
172 $params = [
173 ':id' => $id,
174 ':price' => $data['price'],
175 ];
176
177 try {
178 $statement = $this->connection->prepare(
179 "UPDATE {$this->table} SET
180 `price` = :price
181 WHERE id = :id"
182 );
183
184 $res = $statement->execute($params);
185
186 if (!$res) {
187 throw new QueryExecutionException('Unable to save data in ' . __CLASS__);
188 }
189
190 return $res;
191 } catch (Exception $e) {
192 throw new QueryExecutionException('Unable to save data in ' . __CLASS__, $e->getCode(), $e);
193 }
194 }
195
196 /**
197 * @param int $id
198 * @param CustomerBooking $entity
199 *
200 * @return bool
201 * @throws QueryExecutionException
202 */
203 public function updateTax($id, $entity)
204 {
205 $data = $entity->toArray();
206
207 $params = [
208 ':id' => $id,
209 ':tax' => !empty($data['tax']) ? (is_array($data['tax']) ? json_encode($data['tax']) : $data['tax']) : null,
210 ];
211
212 try {
213 $statement = $this->connection->prepare(
214 "UPDATE {$this->table} SET
215 `tax` = :tax
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 updateStatusByAppointmentId($id, $status)
239 {
240 $params = [
241 ':appointmentId' => $id,
242 ':status' => $status
243 ];
244
245 try {
246 $statement = $this->connection->prepare(
247 "UPDATE {$this->table} SET
248 `status` = :status
249 WHERE appointmentId = :appointmentId"
250 );
251
252 $res = $statement->execute($params);
253
254 if (!$res) {
255 throw new QueryExecutionException('Unable to save data in ' . __CLASS__);
256 }
257
258 return $res;
259 } catch (Exception $e) {
260 throw new QueryExecutionException('Unable to save data in ' . __CLASS__, $e->getCode(), $e);
261 }
262 }
263
264 /**
265 * @param int $id
266 * @param int $status
267 *
268 * @return mixed
269 * @throws QueryExecutionException
270 */
271 public function updateStatusById($id, $status)
272 {
273 $params = [
274 ':id' => $id,
275 ':status' => $status
276 ];
277
278 try {
279 $statement = $this->connection->prepare(
280 "UPDATE {$this->table} SET
281 `status` = :status
282 WHERE id = :id"
283 );
284
285 $res = $statement->execute($params);
286
287 if (!$res) {
288 throw new QueryExecutionException('Unable to save data in ' . __CLASS__);
289 }
290
291 return $res;
292 } catch (Exception $e) {
293 throw new QueryExecutionException('Unable to save data in ' . __CLASS__, $e->getCode(), $e);
294 }
295 }
296
297 /**
298 * Returns an array of Customers Id's who have at least one booking until passed date
299 *
300 * @param $criteria
301 *
302 * @return array
303 * @throws QueryExecutionException
304 * @throws InvalidArgumentException
305 */
306 public function getReturningCustomers($criteria)
307 {
308 $appointmentTable = AppointmentsTable::getTableName();
309
310 $params = [];
311
312 $where = [];
313
314 if ($criteria['dates']) {
315 $where[] = "(DATE_FORMAT(a.bookingStart, '%Y-%m-%d') < :bookingFrom)";
316 $params[':bookingFrom'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
317 }
318
319 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
320
321 try {
322 $statement = $this->connection->prepare(
323 "SELECT
324 customerId,
325 COUNT(*) AS occurrences
326 FROM {$this->table} cb
327 INNER JOIN {$appointmentTable} a ON a.id = cb.appointmentId
328 $where
329 GROUP BY customerId"
330 );
331
332 $statement->execute($params);
333
334 $rows = $statement->fetchAll();
335 } catch (Exception $e) {
336 throw new QueryExecutionException('Unable to return customer bookings from' . __CLASS__, $e->getCode(), $e);
337 }
338
339 return $rows;
340 }
341
342 /**
343 * Returns an array of Customers Id's bookings in selected period
344 *
345 * @param $criteria
346 *
347 * @return array
348 * @throws QueryExecutionException
349 * @throws InvalidArgumentException
350 */
351 public function getFilteredDistinctCustomersIds($criteria)
352 {
353 $appointmentTable = AppointmentsTable::getTableName();
354
355 $params = [];
356
357 $where = [];
358
359 if ($criteria['dates']) {
360 $where[] = "(DATE_FORMAT(a.bookingStart, '%Y-%m-%d') BETWEEN :bookingFrom AND :bookingTo)";
361
362 $params[':bookingFrom'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
363
364 $params[':bookingTo'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][1]);
365 }
366
367 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
368
369 try {
370 $statement = $this->connection->prepare(
371 "SELECT DISTINCT
372 cb.customerId
373 FROM {$this->table} cb
374 INNER JOIN {$appointmentTable} a ON a.id = cb.appointmentId
375 $where"
376 );
377
378 $statement->execute($params);
379
380 $rows = $statement->fetchAll();
381 } catch (Exception $e) {
382 throw new QueryExecutionException('Unable to return customer bookings from' . __CLASS__, $e->getCode(), $e);
383 }
384
385 return $rows;
386 }
387
388 /**
389 * Returns token for given id
390 *
391 * @param $id
392 *
393 * @return array
394 * @throws QueryExecutionException
395 */
396 public function getToken($id)
397 {
398 try {
399 $statement = $this->connection->prepare(
400 "SELECT cb.token
401 FROM {$this->table} cb
402 WHERE cb.id = :id"
403 );
404
405 $statement->execute([':id' => $id]);
406
407 $row = $statement->fetch();
408 } catch (Exception $e) {
409 throw new QueryExecutionException('Unable to return customer booking from' . __CLASS__, $e->getCode(), $e);
410 }
411
412 return $row;
413 }
414
415 /**
416 * Returns tokens for given event id
417 *
418 * @param $id
419 *
420 * @return array
421 * @throws QueryExecutionException
422 * @throws InvalidArgumentException
423 */
424 public function getTokensByEventId($id)
425 {
426 $eventsPeriodsTable = EventsPeriodsTable::getTableName();
427
428 $customerBookingsEventsPeriods = CustomerBookingsToEventsPeriodsTable::getTableName();
429
430 try {
431 $statement = $this->connection->prepare(
432 "SELECT
433 cb.id, cb.token
434 FROM {$this->table} cb
435 INNER JOIN {$customerBookingsEventsPeriods} cbep ON cbep.customerBookingId = cb.id
436 INNER JOIN {$eventsPeriodsTable} ep ON ep.id = cbep.eventPeriodId
437 WHERE ep.eventId = :id"
438 );
439
440 $statement->execute([':id' => $id]);
441
442 $rows = $statement->fetchAll();
443 } catch (Exception $e) {
444 throw new QueryExecutionException('Unable to return customer booking from' . __CLASS__, $e->getCode(), $e);
445 }
446
447 return $rows;
448 }
449
450 /**
451 * @param int $customerId
452 * @param string $info
453 *
454 * @return mixed
455 * @throws QueryExecutionException
456 */
457 public function updateInfoByCustomerId($customerId, $info)
458 {
459 $params = [
460 ':customerId' => $customerId,
461 ':info' => $info
462 ];
463
464 try {
465 $statement = $this->connection->prepare(
466 "UPDATE {$this->table} SET
467 `info` = :info
468 WHERE customerId = :customerId"
469 );
470
471 $res = $statement->execute($params);
472
473 if (!$res) {
474 throw new QueryExecutionException('Unable to save data in ' . __CLASS__);
475 }
476
477 return $res;
478 } catch (Exception $e) {
479 throw new QueryExecutionException('Unable to save data in ' . __CLASS__, $e->getCode(), $e);
480 }
481 }
482
483 /**
484 * @param int $id
485 *
486 * @return mixed
487 * @throws QueryExecutionException
488 * @throws InvalidArgumentException
489 */
490 public function getById($id)
491 {
492 $params = [
493 ':id' => $id,
494 ];
495
496 $paymentsTable = PaymentsTable::getTableName();
497
498 $usersTable = UsersTable::getTableName();
499
500 $couponsTable = CouponsTable::getTableName();
501
502 try {
503 $statement = $this->connection->prepare(
504 "SELECT
505 cb.id AS booking_id,
506 cb.appointmentId AS booking_appointmentId,
507 cb.customerId AS booking_customerId,
508 cb.status AS booking_status,
509 cb.price AS booking_price,
510 cb.persons AS booking_persons,
511 cb.couponId AS booking_couponId,
512 cb.customFields AS booking_customFields,
513 cb.info AS booking_info,
514 cb.utcOffset AS booking_utcOffset,
515 cb.aggregatedPrice AS booking_aggregatedPrice,
516 cb.duration AS booking_duration,
517 cb.created AS booking_created,
518
519 cu.id AS customer_id,
520 cu.firstName AS customer_firstName,
521 cu.lastName AS customer_lastName,
522 cu.email AS customer_email,
523 cu.note AS customer_note,
524 cu.phone AS customer_phone,
525 cu.gender AS customer_gender,
526 cu.birthday AS customer_birthday,
527
528 p.id AS payment_id,
529 p.amount AS payment_amount,
530 p.dateTime AS payment_dateTime,
531 p.status AS payment_status,
532 p.gateway AS payment_gateway,
533 p.gatewayTitle AS payment_gatewayTitle,
534 p.transactionId AS payment_transactionId,
535 p.data AS payment_data,
536
537 c.id AS coupon_id,
538 c.code AS coupon_code,
539 c.discount AS coupon_discount,
540 c.deduction AS coupon_deduction,
541 c.expirationDate AS coupon_expirationDate,
542 c.limit AS coupon_limit,
543 c.customerLimit AS coupon_customerLimit,
544 c.status AS coupon_status
545 FROM {$this->table} cb
546 INNER JOIN {$usersTable} cu ON cu.id = cb.customerId
547 LEFT JOIN {$couponsTable} c ON c.id = cb.couponId
548 LEFT JOIN {$paymentsTable} p ON p.customerBookingId = cb.id
549 WHERE cb.id = :id"
550 );
551
552 $statement->execute($params);
553
554 $rows = $statement->fetchAll();
555 } catch (Exception $e) {
556 throw new QueryExecutionException('Unable to find booking by id in ' . __CLASS__, $e->getCode(), $e);
557 }
558
559 $reformattedData = call_user_func([static::FACTORY, 'reformat'], $rows);
560
561 return !empty($reformattedData[$id]) ?
562 call_user_func([static::FACTORY, 'create'], $reformattedData[$id]) : null;
563 }
564
565 /**
566 * Returns a collection of bookings where actions on booking are not completed
567 *
568 * @return Collection
569 * @throws InvalidArgumentException
570 * @throws QueryExecutionException
571 * @throws \Exception
572 */
573 public function getUncompletedActionsForBookings()
574 {
575 $params = [];
576
577 $currentDateTime = "STR_TO_DATE('" . DateTimeService::getNowDateTimeInUtc() . "', '%Y-%m-%d %H:%i:%s')";
578
579 $pastDateTime =
580 "STR_TO_DATE('" .
581 DateTimeService::getNowDateTimeObjectInUtc()->modify('-1 day')->format('Y-m-d H:i:s') .
582 "', '%Y-%m-%d %H:%i:%s')";
583
584 try {
585 $statement = $this->connection->prepare(
586 "SELECT * FROM {$this->table}
587 WHERE
588 actionsCompleted = 0 AND
589 {$currentDateTime} > DATE_ADD(created, INTERVAL 300 SECOND) AND
590 {$pastDateTime} < created"
591 );
592
593 $statement->execute($params);
594
595 $rows = $statement->fetchAll();
596 } catch (\Exception $e) {
597 throw new QueryExecutionException('Unable to get data from ' . __CLASS__, $e->getCode(), $e);
598 }
599
600 $items = [];
601
602 foreach ($rows as $row) {
603 $items[] = call_user_func([static::FACTORY, 'create'], $row);
604 }
605
606 return new Collection($items);
607 }
608
609 /**
610 * @param array $ids
611 *
612 * @return array
613 * @throws QueryExecutionException
614 */
615 public function countByNoShowStatus($ids)
616 {
617 $idsString = implode(', ', $ids);
618
619 try {
620 $statement = $this->connection->prepare(
621 "SELECT customerId, COUNT(*) AS count
622 FROM {$this->table} cb
623 WHERE customerId IN ($idsString) AND status = 'no-show'
624 GROUP BY customerId"
625 );
626
627 $statement->execute();
628
629 $rows = $statement->fetchAll();
630
631 $result = [];
632 foreach ($ids as $id) {
633 $count = 0;
634 foreach ($rows as $row) {
635 if ($row['customerId'] == $id) {
636 $count = $row['count'];
637 break;
638 }
639 }
640 $result[] = [
641 'id' => $id,
642 'count' => $count,
643 ];
644 }
645 } catch (Exception $e) {
646 throw new QueryExecutionException('Unable to find booking by id in ' . __CLASS__, $e->getCode(), $e);
647 }
648
649 return $result;
650 }
651 }
652