PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 1.2.5
Booking for Appointments and Events Calendar – Amelia v1.2.5
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 / Payment / PaymentRepository.php
ameliabooking / src / Infrastructure / Repository / Payment Last commit date
PaymentRepository.php 1 year ago
PaymentRepository.php
954 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\Payment;
8
9 use AmeliaBooking\Domain\Collection\Collection;
10 use AmeliaBooking\Domain\Common\Exceptions\InvalidArgumentException;
11 use AmeliaBooking\Domain\Entity\Payment\Payment;
12 use AmeliaBooking\Domain\Factory\Payment\PaymentFactory;
13 use AmeliaBooking\Domain\Services\DateTime\DateTimeService;
14 use AmeliaBooking\Infrastructure\Repository\AbstractRepository;
15 use AmeliaBooking\Domain\Repository\Payment\PaymentRepositoryInterface;
16 use AmeliaBooking\Infrastructure\Common\Exceptions\QueryExecutionException;
17 use AmeliaBooking\Infrastructure\Connection;
18 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Bookable\PackagesCustomersServicesTable;
19 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Booking\CustomerBookingsToExtrasTable;
20 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Coupon\CouponsTable;
21 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Location\LocationsTable;
22
23 /**
24 * Class PaymentRepository
25 *
26 * @package AmeliaBooking\Infrastructure\Repository\Payment
27 */
28 class PaymentRepository extends AbstractRepository implements PaymentRepositoryInterface
29 {
30 /** @var string */
31 protected $appointmentsTable;
32
33 /** @var string */
34 protected $bookingsTable;
35
36 /** @var string */
37 protected $servicesTable;
38
39 /** @var string */
40 protected $usersTable;
41
42 /** @var string */
43 protected $eventsTable;
44
45 /** @var string */
46 protected $eventsProvidersTable;
47
48 /** @var string */
49 protected $eventsPeriodsTable;
50
51 /** @var string */
52 protected $customerBookingsToEventsPeriodsTable;
53
54 /** @var string */
55 protected $packagesTable;
56
57 /** @var string */
58 protected $packagesCustomersTable;
59
60 /** @var string */
61 protected $packagesCustomersServiceTable;
62
63
64 /**
65 * @param Connection $connection
66 * @param string $table
67 * @param string $appointmentsTable
68 * @param string $bookingsTable
69 * @param string $servicesTable
70 * @param string $usersTable
71 * @param string $eventsTable
72 * @param string $eventsProvidersTable
73 * @param string $eventsPeriodsTable
74 * @param string $customerBookingsToEventsPeriodsTable
75 * @param string $packagesTable
76 * @param string $packagesCustomersTable
77 */
78 public function __construct(
79 Connection $connection,
80 $table,
81 $appointmentsTable,
82 $bookingsTable,
83 $servicesTable,
84 $usersTable,
85 $eventsTable,
86 $eventsProvidersTable,
87 $eventsPeriodsTable,
88 $customerBookingsToEventsPeriodsTable,
89 $packagesTable,
90 $packagesCustomersTable
91 ) {
92 parent::__construct($connection, $table);
93
94 $this->appointmentsTable = $appointmentsTable;
95 $this->bookingsTable = $bookingsTable;
96 $this->servicesTable = $servicesTable;
97 $this->usersTable = $usersTable;
98 $this->eventsTable = $eventsTable;
99 $this->eventsProvidersTable = $eventsProvidersTable;
100 $this->eventsPeriodsTable = $eventsPeriodsTable;
101 $this->customerBookingsToEventsPeriodsTable = $customerBookingsToEventsPeriodsTable;
102 $this->packagesTable = $packagesTable;
103 $this->packagesCustomersTable = $packagesCustomersTable;
104 $this->packagesCustomersServiceTable = PackagesCustomersServicesTable::getTableName();
105 }
106
107 const FACTORY = PaymentFactory::class;
108
109 /**
110 * @param Payment $entity
111 *
112 * @return bool
113 * @throws QueryExecutionException
114 */
115 public function add($entity)
116 {
117 $data = $entity->toArray();
118
119 $params = [
120 ':customerBookingId' => $data['customerBookingId'] ? $data['customerBookingId'] : null,
121 ':packageCustomerId' => $data['packageCustomerId'] ? $data['packageCustomerId'] : null,
122 ':parentId' => $data['parentId'] ? $data['parentId'] : null,
123 ':amount' => $data['amount'],
124 ':dateTime' => DateTimeService::getCustomDateTimeInUtc($data['dateTime']),
125 ':status' => $data['status'],
126 ':gateway' => $data['gateway'],
127 ':gatewayTitle' => $data['gatewayTitle'],
128 ':data' => $data['data'],
129 ':entity' => $data['entity'],
130 ':created' => DateTimeService::getNowDateTimeInUtc(),
131 ':wcOrderId' => !empty($data['wcOrderId']) ? $data['wcOrderId'] : null,
132 ':transactionId' => !empty($data['transactionId']) ? $data['transactionId'] : null,
133 ':wcOrderItemId' => !empty($data['wcOrderItemId']) ? $data['wcOrderItemId'] : null,
134 ];
135
136 if ($data['parentId']) {
137 $params[':actionsCompleted'] = null;
138 } else {
139 $params[':actionsCompleted'] = !empty($data['actionsCompleted']) ? 1 : 0;
140 }
141
142 try {
143 $statement = $this->connection->prepare(
144 "INSERT INTO
145 {$this->table}
146 (
147 `customerBookingId`, `packageCustomerId`, `parentId`, `amount`, `dateTime`, `status`, `gateway`, `gatewayTitle`, `data`, `entity`, `actionsCompleted`, `created`, `wcOrderId`, `wcOrderItemId`, `transactionId`
148 ) VALUES (
149 :customerBookingId, :packageCustomerId, :parentId, :amount, :dateTime, :status, :gateway, :gatewayTitle, :data, :entity, :actionsCompleted, :created, :wcOrderId, :wcOrderItemId, :transactionId
150 )"
151 );
152
153 $response = $statement->execute($params);
154 } catch (\Exception $e) {
155 throw new QueryExecutionException('Unable to add data in ' . __CLASS__, $e->getCode(), $e);
156 }
157
158 if (!$response) {
159 throw new QueryExecutionException('Unable to add data in ' . __CLASS__);
160 }
161
162 return $this->connection->lastInsertId();
163 }
164
165 /**
166 * @param int $id
167 * @param Payment $entity
168 *
169 * @return bool
170 * @throws QueryExecutionException
171 */
172 public function update($id, $entity)
173 {
174 $data = $entity->toArray();
175
176 $params = [
177 ':customerBookingId' => $data['customerBookingId'] ? $data['customerBookingId'] : null,
178 ':packageCustomerId' => $data['packageCustomerId'] ? $data['packageCustomerId'] : null,
179 ':parentId' => $data['parentId'] ? $data['parentId'] : null,
180 ':amount' => $data['amount'],
181 ':dateTime' => DateTimeService::getCustomDateTimeInUtc($data['dateTime']),
182 ':status' => $data['status'],
183 ':gateway' => $data['gateway'],
184 ':gatewayTitle' => $data['gatewayTitle'],
185 ':data' => $data['data'],
186 ':transactionId' => $data['transactionId'],
187 ':id' => $id,
188 ];
189
190 try {
191 $statement = $this->connection->prepare(
192 "UPDATE {$this->table}
193 SET
194 `customerBookingId` = :customerBookingId,
195 `packageCustomerId` = :packageCustomerId,
196 `parentId` = :parentId,
197 `amount` = :amount,
198 `dateTime` = :dateTime,
199 `status` = :status,
200 `gateway` = :gateway,
201 `gatewayTitle` = :gatewayTitle,
202 `data` = :data,
203 `transactionId` = :transactionId
204 WHERE
205 id = :id"
206 );
207
208 $response = $statement->execute($params);
209 } catch (\Exception $e) {
210 throw new QueryExecutionException('Unable to save data in ' . __CLASS__, $e->getCode(), $e);
211 }
212
213 if (!$response) {
214 throw new QueryExecutionException('Unable to save data in ' . __CLASS__);
215 }
216
217 return $response;
218 }
219
220 /**
221 * @param array $criteria
222 *
223 * @return Collection
224 * @throws QueryExecutionException
225 */
226 public function getByCriteria($criteria)
227 {
228 $result = new Collection();
229
230 $params = [];
231
232 $where = [];
233
234 if (!empty($criteria['bookingIds'])) {
235 $queryBookings = [];
236
237 foreach ($criteria['bookingIds'] as $index => $value) {
238 $param = ':id' . $index;
239
240 $queryBookings[] = $param;
241
242 $params[$param] = $value;
243 }
244
245 $where[] = 'customerBookingId IN (' . implode(', ', $queryBookings) . ')';
246 }
247
248
249 if (!empty($criteria['packageCustomerId'])) {
250 $params[':packageCustomerId'] = $criteria['packageCustomerId'];
251 $where[] = 'packageCustomerId = :packageCustomerId';
252 }
253
254 if (!empty($criteria['ids'])) {
255 $queryIds = [];
256
257 foreach ($criteria['ids'] as $index => $value) {
258 $param = ':id' . $index;
259
260 $queryIds[] = $param;
261
262 $params[$param] = $value;
263 }
264
265 $where[] = 'id IN (' . implode(', ', $queryIds) . ')';
266 }
267
268 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
269
270 try {
271 $statement = $this->connection->prepare(
272 "SELECT
273 id AS id,
274 customerBookingId AS customerBookingId,
275 packageCustomerId AS packageCustomerId,
276 parentId AS parentId,
277 amount AS amount,
278 dateTime AS dateTime,
279 status AS status,
280 gateway AS gateway,
281 gatewayTitle AS gatewayTitle,
282 data AS data
283 FROM {$this->table}
284 {$where}"
285 );
286
287 $statement->execute($params);
288
289 while ($row = $statement->fetch()) {
290 $result->addItem(call_user_func([static::FACTORY, 'create'], $row), $row['id']);
291 }
292 } catch (\Exception $e) {
293 throw new QueryExecutionException('Unable to find by id in ' . __CLASS__, $e->getCode(), $e);
294 }
295
296 return $result;
297 }
298
299 /**
300 * @param array $criteria
301 * @param int $itemsPerPage
302 *
303 * @return array
304 * @throws QueryExecutionException
305 */
306 public function getFiltered($criteria, $itemsPerPage = null)
307 {
308 $params = [];
309 $appointmentParams1 = [];
310 $appointmentParams2 = [];
311 $eventParams = [];
312 $whereAppointment1 = [];
313 $whereAppointment2 = [];
314 $whereEvent = [];
315
316 if (!empty($criteria['dates'])) {
317 $whereAppointment1[] = "(DATE_FORMAT(p.dateTime, '%Y-%m-%d %H:%i:%s') BETWEEN :paymentAppointmentFrom1 AND :paymentAppointmentTo1)";
318 $whereAppointment2[] = "(DATE_FORMAT(p.dateTime, '%Y-%m-%d %H:%i:%s') BETWEEN :paymentAppointmentFrom2 AND :paymentAppointmentTo2)";
319 $appointmentParams1[':paymentAppointmentFrom1'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
320 $appointmentParams2[':paymentAppointmentFrom2'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
321 $appointmentParams1[':paymentAppointmentTo1'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][1]);
322 $appointmentParams2[':paymentAppointmentTo2'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][1]);
323
324 $whereEvent[] = "(DATE_FORMAT(p.dateTime, '%Y-%m-%d %H:%i:%s') BETWEEN :paymentEventFrom AND :paymentEventTo)";
325 $eventParams[':paymentEventFrom'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
326 $eventParams[':paymentEventTo'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][1]);
327 }
328
329 if (!empty($criteria['customerId'])) {
330 $appointmentParams1[':customerAppointmentId1'] = $criteria['customerId'];
331 $appointmentParams2[':customerAppointmentId2'] = $criteria['customerId'];
332 $whereAppointment1[] = 'cb.customerId = :customerAppointmentId1';
333 $whereAppointment2[] = 'pc.customerId = :customerAppointmentId2';
334
335 $eventParams[':customerEventId'] = $criteria['customerId'];
336 $whereEvent[] = 'cb.customerId = :customerEventId';
337 }
338
339 if (!empty($criteria['providerId'])) {
340 $appointmentParams1[':providerAppointmentId1'] = $criteria['providerId'];
341 $appointmentParams1[':providerAppointmentId2'] = $criteria['providerId'];
342 $whereAppointment1[] = 'a.providerId = :providerAppointmentId1';
343 $whereAppointment2[] = 'a.providerId = :providerAppointmentId2';
344
345 $eventParams[':providerEventId'] = $criteria['providerId'];
346 $whereEvent[] = 'epu.userId = :providerEventId';
347 }
348
349 if (!empty($criteria['services'])) {
350 $queryServices1 = [];
351 $queryServices2 = [];
352
353 foreach ((array)$criteria['services'] as $index => $value) {
354 $param1 = ':service0' . $index;
355 $param2 = ':service1' . $index;
356 $queryServices1[] = $param1;
357 $queryServices2[] = $param2;
358 $appointmentParams1[$param1] = $value;
359 $appointmentParams2[$param2] = $value;
360 }
361
362 $whereAppointment1[] = 'a.serviceId IN (' . implode(', ', $queryServices1) . ')';
363 $whereAppointment2[] = 'a.serviceId IN (' . implode(', ', $queryServices2) . ')';
364 }
365
366 if (!empty($criteria['status'])) {
367 $appointmentParams1[':statusAppointment1'] = $criteria['status'];
368 $appointmentParams2[':statusAppointment2'] = $criteria['status'];
369 $whereAppointment1[] = 'p.status = :statusAppointment1';
370 $whereAppointment2[] = 'p.status = :statusAppointment2';
371
372 $eventParams[':statusEvent'] = $criteria['status'];
373 $whereEvent[] = 'p.status = :statusEvent';
374 }
375
376 if (!empty($criteria['events'])) {
377 $queryEvents = [];
378
379 foreach ((array)$criteria['events'] as $index => $value) {
380 $param = ':event' . $index;
381 $queryEvents[] = $param;
382 $eventParams[$param] = $value;
383 }
384
385 $whereEvent[] = "p.customerBookingId IN (SELECT cbe.customerBookingId
386 FROM {$this->eventsTable} e
387 INNER JOIN {$this->eventsPeriodsTable} ep ON ep.eventId = e.id
388 INNER JOIN {$this->customerBookingsToEventsPeriodsTable} cbe ON cbe.eventPeriodId = ep.id
389 WHERE e.id IN (" . implode(', ', $queryEvents) . '))';
390 }
391
392 $whereAppointment1 = $whereAppointment1 ? ' AND ' . implode(' AND ', $whereAppointment1) : '';
393 $whereAppointment2 = $whereAppointment2 ? ' AND ' . implode(' AND ', $whereAppointment2) : '';
394 $whereEvent = $whereEvent ? ' AND ' . implode(' AND ', $whereEvent) : '';
395
396 $customerBookingsExtrasTable = CustomerBookingsToExtrasTable::getTableName();
397 $couponsTable = CouponsTable::getTableName();
398 $locationsTable = LocationsTable::getTableName();
399
400 $appointmentQuery1 = "SELECT
401 p.id AS id,
402 p.customerBookingId AS customerBookingId,
403 NULL AS packageCustomerId,
404 p.amount AS amount,
405 p.dateTime AS dateTime,
406 p.created AS created,
407 p.status AS status,
408 p.wcOrderId AS wcOrderId,
409 p.wcOrderItemId AS wcOrderItemId,
410 p.gateway AS gateway,
411 p.gatewayTitle AS gatewayTitle,
412 p.transactionId AS transactionId,
413 NULL AS packageId,
414 cb.price AS bookedPrice,
415 NULL AS bookedTax,
416 a.providerId AS providerId,
417 cb.customerId AS customerId,
418 cb.persons AS persons,
419 cb.aggregatedPrice AS aggregatedPrice,
420 cb.info AS info,
421 (SUM(CASE WHEN cbe.aggregatedPrice = 1 THEN cb.persons*cbe.quantity*cbe.price ELSE cbe.quantity*cbe.price END)/COUNT(DISTINCT p.id)) as bookingExtrasSum,
422
423 c.id AS coupon_id,
424 c.discount AS coupon_discount,
425 c.deduction AS coupon_deduction,
426 c.code AS coupon_code,
427
428 a.serviceId AS serviceId,
429 a.id AS appointmentId,
430 a.bookingStart AS bookingStart,
431 s.name AS bookableName,
432 cu.firstName AS customerFirstName,
433 cu.lastName AS customerLastName,
434 cu.email AS customerEmail,
435 pu.firstName AS providerFirstName,
436 pu.lastName AS providerLastName,
437 pu.email AS providerEmail,
438 l.id AS locationId,
439 l.name AS location_name,
440 l.address AS location_address
441 FROM {$this->table} p
442 INNER JOIN {$this->bookingsTable} cb ON cb.id = p.customerBookingId
443 LEFT JOIN {$customerBookingsExtrasTable} cbe ON cbe.customerBookingId = cb.id
444 LEFT JOIN {$couponsTable} c ON c.id = cb.couponId
445 INNER JOIN {$this->appointmentsTable} a ON a.id = cb.appointmentId
446 INNER JOIN {$this->servicesTable} s ON s.id = a.serviceId
447 INNER JOIN {$this->usersTable} cu ON cu.id = cb.customerId
448 INNER JOIN {$this->usersTable} pu ON pu.id = a.providerId
449 LEFT JOIN {$locationsTable} l ON l.id = a.locationId
450 WHERE 1=1 {$whereAppointment1} GROUP BY p.customerBookingId ORDER BY p.id ASC";
451
452 $appointmentQuery2 = "SELECT
453 p.id AS id,
454 NULL AS customerBookingId,
455 p.packageCustomerId AS packageCustomerId,
456 p.amount AS amount,
457 p.dateTime AS dateTime,
458 p.created AS created,
459 p.status AS status,
460 p.wcOrderId AS wcOrderId,
461 p.wcOrderItemId AS wcOrderItemId,
462 p.gateway AS gateway,
463 p.gatewayTitle AS gatewayTitle,
464 p.transactionId AS transactionId,
465 pc.packageId AS packageId,
466 pc.price AS bookedPrice,
467 pc.tax AS bookedTax,
468 NULL AS providerId,
469 pc.customerId AS customerId,
470 NULL AS persons,
471 NULL AS aggregatedPrice,
472 cb.info AS info,
473 NULL as bookingExtrasSum,
474
475 c.id AS coupon_id,
476 c.discount AS coupon_discount,
477 c.deduction AS coupon_deduction,
478 c.code AS coupon_code,
479
480 NULL AS serviceId,
481 NULL AS appointmentId,
482 NULL AS bookingStart,
483 pa.name AS bookableName,
484 cu.firstName AS customerFirstName,
485 cu.lastName AS customerLastName,
486 cu.email AS customerEmail,
487 '' AS providerFirstName,
488 '' AS providerLastName,
489 '' AS providerEmail,
490 '' AS locationId,
491 '' AS location_name,
492 '' AS location_address
493 FROM {$this->table} p
494 INNER JOIN {$this->packagesCustomersTable} pc ON p.packageCustomerId = pc.id
495 INNER JOIN {$this->usersTable} cu ON cu.id = pc.customerId
496 LEFT JOIN {$couponsTable} c ON c.id = pc.couponId
497 INNER JOIN {$this->packagesTable} pa ON pa.id = pc.packageId
498 INNER JOIN {$this->packagesCustomersServiceTable} pcs ON pc.id = pcs.packageCustomerId
499 LEFT JOIN {$this->bookingsTable} cb ON cb.packageCustomerServiceId = pcs.id
500 LEFT JOIN {$this->appointmentsTable} a ON a.id = cb.appointmentId
501 WHERE 1=1 {$whereAppointment2} GROUP BY p.packageCustomerId ORDER BY p.id ASC";
502
503 $eventQuery = "SELECT
504 p.id AS id,
505 p.customerBookingId AS customerBookingId,
506 NULL AS packageCustomerId,
507 p.amount AS amount,
508 p.dateTime AS dateTime,
509 p.created AS created,
510 p.status AS status,
511 p.wcOrderId AS wcOrderId,
512 p.wcOrderItemId AS wcOrderItemId,
513 p.gateway AS gateway,
514 p.gatewayTitle AS gatewayTitle,
515 p.transactionId AS transactionId,
516 NULL AS packageId,
517 cb.price AS bookedPrice,
518 NULL AS bookedTax,
519 NULL AS providerId,
520 cb.customerId AS customerId,
521 cb.persons AS persons,
522 cb.aggregatedPrice AS aggregatedPrice,
523 cb.info AS info,
524 NULL as bookingExtrasSum,
525
526 c.id AS coupon_id,
527 c.discount AS coupon_discount,
528 c.deduction AS coupon_deduction,
529 c.code AS coupon_code,
530
531 NULL AS serviceId,
532 NULL AS appointmentId,
533 NULL AS bookingStart,
534 NULL AS bookableName,
535 cu.firstName AS customerFirstName,
536 cu.lastName AS customerLastName,
537 cu.email AS customerEmail,
538 NULL AS providerFirstName,
539 NULL AS providerLastName,
540 NULL AS providerEmail,
541 l.id AS locationId,
542 l.name AS location_name,
543 (CASE WHEN e.customlocation IS NOT NULL THEN e.customlocation ELSE l.address END) AS location_address
544 FROM {$this->table} p
545 INNER JOIN {$this->bookingsTable} cb ON cb.id = p.customerBookingId
546 LEFT JOIN {$couponsTable} c ON c.id = cb.couponId
547 INNER JOIN {$this->usersTable} cu ON cu.id = cb.customerId
548 INNER JOIN {$this->customerBookingsToEventsPeriodsTable} cbe ON cbe.customerBookingId = cb.id
549 INNER JOIN {$this->eventsPeriodsTable} ep ON ep.id = cbe.eventPeriodId
550 INNER JOIN {$this->eventsTable} e ON e.id = ep.eventId
551 LEFT JOIN {$this->eventsProvidersTable} epu ON epu.eventId = ep.eventId
552 LEFT JOIN {$locationsTable} l ON l.id = e.locationId
553 WHERE 1=1 {$whereEvent} GROUP BY p.customerBookingId ORDER BY p.id ASC";
554
555 if (isset($criteria['events'], $criteria['services'])) {
556 return [];
557 } elseif (isset($criteria['services'])) {
558 $paymentQuery = "({$appointmentQuery1}) UNION ALL ({$appointmentQuery2})";
559 $params = array_merge($params, $appointmentParams1, $appointmentParams2);
560 } elseif (isset($criteria['events'])) {
561 $paymentQuery = "({$eventQuery})";
562 $params = array_merge($params, $eventParams);
563 } else {
564 $paymentQuery = "({$appointmentQuery1}) UNION ALL ({$appointmentQuery2}) UNION ALL ({$eventQuery})";
565 $params = array_merge($params, $appointmentParams1, $appointmentParams2, $eventParams);
566 }
567
568 $limit = $this->getLimit(
569 !empty($criteria['page']) ? (int)$criteria['page'] : 0,
570 (int)$itemsPerPage
571 );
572
573 try {
574 $statement = $this->connection->prepare(
575 "{$paymentQuery}
576 ORDER BY dateTime, id
577 {$limit}"
578 );
579
580 $statement->execute($params);
581
582 $rows = $statement->fetchAll();
583 } catch (\Exception $e) {
584 throw new QueryExecutionException('Unable to get data from ' . __CLASS__, $e->getCode(), $e);
585 }
586
587 $result = [];
588
589 foreach ($rows as &$row) {
590 $customerInfo = $row['info'] ? json_decode($row['info'], true) : null;
591
592 $result[(int)$row['id']] = [
593 'id' => (int)$row['id'],
594 'dateTime' => DateTimeService::getCustomDateTimeFromUtc($row['dateTime']),
595 'created' => DateTimeService::getCustomDateTimeFromUtc($row['created']),
596 'bookingStart' => $row['bookingStart'] ?
597 DateTimeService::getCustomDateTimeFromUtc($row['bookingStart']) : null,
598 'status' => $row['status'],
599 'wcOrderId' => $row['wcOrderId'],
600 'wcOrderItemId' => $row['wcOrderItemId'],
601 'gateway' => $row['gateway'],
602 'gatewayTitle' => $row['gatewayTitle'],
603 'transactionId' => $row['transactionId'],
604 'name' => $row['bookableName'],
605 'customerBookingId' => (int)$row['customerBookingId'] ? (int)$row['customerBookingId'] : null,
606 'packageCustomerId' => (int)$row['packageCustomerId'] ? (int)$row['packageCustomerId'] : null,
607 'amount' => (float)$row['amount'],
608 'providers' => (int)$row['providerId'] ? [
609 [
610 'id' => (int)$row['providerId'],
611 'fullName' => $row['providerFirstName'] . ' ' . $row['providerLastName'],
612 'email' => $row['providerEmail'],
613 ]
614 ] : [],
615 'location' => (int)$row['locationId'] || $row['location_address'] ?
616 [
617 'id' => (int)$row['locationId'],
618 'location_name' => $row['location_name'],
619 'location_address' => $row['location_address'],
620 ]
621 : null,
622 'customerId' => (int)$row['customerId'],
623 'serviceId' => (int)$row['serviceId'] ? (int)$row['serviceId'] : null,
624 'appointmentId' => (int)$row['appointmentId'] ? (int)$row['appointmentId'] : null,
625 'packageId' => (int)$row['packageId'] ? (int)$row['packageId'] : null,
626 'bookedPrice' => $row['bookedPrice'] ? $row['bookedPrice'] : null,
627 'bookedTax' => $row['bookedTax'] ? $row['bookedTax'] : null,
628 'bookableName' => $row['bookableName'],
629 'customerFirstName' => $customerInfo ? $customerInfo['firstName'] : $row['customerFirstName'],
630 'customerLastName' => $customerInfo ? $customerInfo['lastName'] : $row['customerLastName'],
631 'info' => $row['info'],
632 'customerEmail' => $row['customerEmail'],
633 'coupon' => !empty($row['coupon_id']) ? [
634 'id' => $row['coupon_id'],
635 'discount' => $row['coupon_discount'],
636 'deduction' => $row['coupon_deduction'],
637 'code' => $row['coupon_code']
638 ] : null,
639 'persons' => $row['persons'],
640 'aggregatedPrice' => $row['aggregatedPrice'],
641 //calculated extras sum in the backend with aggregate so that the number of rows(payments) returned will be equal to the set limit per page
642 'bookingExtrasSum' => $row['bookingExtrasSum'] ?: 0
643 ];
644 }
645
646 return $result;
647 }
648
649 /**
650 * @param array $criteria
651 *
652 * @return mixed
653 * @throws QueryExecutionException
654 */
655 public function getCount($criteria)
656 {
657 $params = [];
658 $appointmentParams1 = [];
659 $appointmentParams2 = [];
660 $eventParams = [];
661 $whereAppointment1 = [];
662 $whereAppointment2 = [];
663 $whereEvent = [];
664
665 if (isset($criteria['dates'])) {
666 $whereAppointment1[] = "(DATE_FORMAT(p.dateTime, '%Y-%m-%d %H:%i:%s') BETWEEN :paymentAppointmentFrom1 AND :paymentAppointmentTo1)";
667 $whereAppointment2[] = "(DATE_FORMAT(p.dateTime, '%Y-%m-%d %H:%i:%s') BETWEEN :paymentAppointmentFrom2 AND :paymentAppointmentTo2)";
668 $appointmentParams1[':paymentAppointmentFrom1'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
669 $appointmentParams1[':paymentAppointmentTo1'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][1]);
670 $appointmentParams2[':paymentAppointmentFrom2'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
671 $appointmentParams2[':paymentAppointmentTo2'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][1]);
672
673 $whereEvent[] = "(DATE_FORMAT(p.dateTime, '%Y-%m-%d %H:%i:%s') BETWEEN :paymentEventFrom AND :paymentEventTo)";
674 $eventParams[':paymentEventFrom'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
675 $eventParams[':paymentEventTo'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][1]);
676 }
677
678 if (!empty($criteria['customerId'])) {
679 $appointmentParams1[':customerAppointmentId1'] = $criteria['customerId'];
680 $appointmentParams2[':customerAppointmentId2'] = $criteria['customerId'];
681 $whereAppointment1[] = 'cb.customerId = :customerAppointmentId1';
682 $whereAppointment2[] = 'pc.customerId = :customerAppointmentId2';
683
684 $eventParams[':customerEventId'] = $criteria['customerId'];
685 $whereEvent[] = 'cb.customerId = :customerEventId';
686 }
687
688 if (!empty($criteria['providerId'])) {
689 $appointmentParams1[':providerAppointmentId'] = $criteria['providerId'];
690 $whereAppointment1[] = 'a.providerId = :providerAppointmentId';
691
692 $eventParams[':providerEventId'] = $criteria['providerId'];
693 $whereEvent[] = 'epu.userId = :providerEventId';
694 }
695
696 if (!empty($criteria['services'])) {
697 $queryServices = [];
698
699 foreach ((array)$criteria['services'] as $index => $value) {
700 $param = ':service' . $index;
701 $queryServices[] = $param;
702 $appointmentParams1[$param] = $value;
703 }
704
705 $whereAppointment1[] = 'a.serviceId IN (' . implode(', ', $queryServices) . ')';
706 }
707
708 if (!empty($criteria['status'])) {
709 $appointmentParams1[':statusAppointment1'] = $criteria['status'];
710 $appointmentParams2[':statusAppointment2'] = $criteria['status'];
711 $whereAppointment1[] = 'p.status = :statusAppointment1';
712 $whereAppointment2[] = 'p.status = :statusAppointment2';
713
714 $eventParams[':statusEvent'] = $criteria['status'];
715 $whereEvent[] = 'p.status = :statusEvent';
716 }
717
718 if (!empty($criteria['events'])) {
719 $queryEvents = [];
720
721 foreach ((array)$criteria['events'] as $index => $value) {
722 $param = ':event' . $index;
723 $queryEvents[] = $param;
724 $eventParams[$param] = $value;
725 }
726
727 $whereEvent[] = "p.customerBookingId IN (SELECT cbe.customerBookingId
728 FROM {$this->eventsTable} e
729 INNER JOIN {$this->eventsPeriodsTable} ep ON ep.eventId = e.id
730 INNER JOIN {$this->customerBookingsToEventsPeriodsTable} cbe ON cbe.eventPeriodId = ep.id
731 WHERE e.id IN (" . implode(', ', $queryEvents) . '))';
732 }
733
734 $whereAppointment1 = $whereAppointment1 ? ' AND ' . implode(' AND ', $whereAppointment1) : '';
735 $whereAppointment2 = $whereAppointment2 ? ' AND ' . implode(' AND ', $whereAppointment2) : '';
736 $whereEvent = $whereEvent ? ' AND ' . implode(' AND ', $whereEvent) : '';
737
738 $appointmentQuery1 = "SELECT
739 COUNT(DISTINCT(p.customerBookingId)) AS appointmentsCount1,
740 0 AS appointmentsCount2,
741 0 AS eventsCount
742 FROM {$this->table} p
743 INNER JOIN {$this->bookingsTable} cb ON cb.id = p.customerBookingId
744 INNER JOIN {$this->appointmentsTable} a ON a.id = cb.appointmentId
745 INNER JOIN {$this->servicesTable} s ON s.id = a.serviceId
746 INNER JOIN {$this->usersTable} cu ON cu.id = cb.customerId
747 INNER JOIN {$this->usersTable} pu ON pu.id = a.providerId
748 WHERE 1=1 $whereAppointment1";
749
750 $appointmentQuery2 = "SELECT
751 0 AS appointmentsCount1,
752 COUNT(DISTINCT(p.packageCustomerId)) AS appointmentsCount2,
753 0 AS eventsCount
754 FROM {$this->table} p
755 INNER JOIN {$this->packagesCustomersTable} pc ON p.packageCustomerId = pc.id
756 INNER JOIN {$this->usersTable} cu ON cu.id = pc.customerId
757 INNER JOIN {$this->packagesTable} pa ON pa.id = pc.packageId
758 WHERE 1=1 $whereAppointment2";
759
760 $eventQuery = "SELECT
761 0 AS appointmentsCount1,
762 0 AS appointmentsCount2,
763 COUNT(DISTINCT(p.customerBookingId)) AS eventsCount
764 FROM {$this->table} p
765 INNER JOIN {$this->bookingsTable} cb ON cb.id = p.customerBookingId
766 INNER JOIN {$this->usersTable} cu ON cu.id = cb.customerId
767 INNER JOIN {$this->customerBookingsToEventsPeriodsTable} cbe ON cbe.customerBookingId = cb.id
768 INNER JOIN {$this->eventsPeriodsTable} ep ON ep.id = cbe.eventPeriodId
769 LEFT JOIN {$this->eventsProvidersTable} epu ON epu.eventId = ep.eventId
770 WHERE 1=1 $whereEvent";
771
772 if (isset($criteria['events'], $criteria['services'])) {
773 return [];
774 } elseif (isset($criteria['services'])) {
775 $paymentQuery = "({$appointmentQuery1}) UNION ALL ({$appointmentQuery2})";
776 $params = array_merge($params, $appointmentParams1, $appointmentParams2);
777 } elseif (isset($criteria['events'])) {
778 $paymentQuery = "{$eventQuery}";
779 $params = array_merge($params, $eventParams);
780 } else {
781 $paymentQuery = "({$appointmentQuery1}) UNION ALL ({$appointmentQuery2}) UNION ALL ({$eventQuery})";
782 $params = array_merge($params, $appointmentParams1, $appointmentParams2, $eventParams);
783 }
784
785 try {
786 $statement = $this->connection->prepare(
787 "{$paymentQuery}"
788 );
789
790 $statement->execute($params);
791
792 $statements = $statement->fetchAll();
793
794 $appointmentsCount1 = 0;
795 $appointmentsCount2 = 0;
796 $eventsCount = 0;
797
798 foreach ($statements as $st) {
799 $appointmentsCount1 += !empty($st['appointmentsCount1']) ? $st['appointmentsCount1'] : 0;
800 $appointmentsCount2 += !empty($st['appointmentsCount2']) ? $st['appointmentsCount2'] : 0;
801 $eventsCount += !empty($st['eventsCount']) ? $st['eventsCount'] : 0;
802 }
803 } catch (\Exception $e) {
804 throw new QueryExecutionException('Unable to get data from ' . __CLASS__, $e->getCode(), $e);
805 }
806
807 return $appointmentsCount1 + $appointmentsCount2 + $eventsCount;
808 }
809
810 /**
811 * Returns a collection of customers that have birthday on today's date and where notification is not sent
812 *
813 * @return Collection
814 * @throws InvalidArgumentException
815 * @throws QueryExecutionException
816 * @throws \Exception
817 */
818 public function getUncompletedActionsForPayments()
819 {
820 $params = [];
821
822 $currentDateTime = "STR_TO_DATE('" . DateTimeService::getNowDateTimeInUtc() . "', '%Y-%m-%d %H:%i:%s')";
823
824 $pastDateTime =
825 "STR_TO_DATE('" .
826 DateTimeService::getNowDateTimeObjectInUtc()->modify('-1 day')->format('Y-m-d H:i:s') .
827 "', '%Y-%m-%d %H:%i:%s')";
828
829 try {
830 $statement = $this->connection->prepare(
831 "SELECT * FROM {$this->table}
832 WHERE
833 actionsCompleted = 0 AND
834 {$currentDateTime} > DATE_ADD(created, INTERVAL 300 SECOND) AND
835 {$pastDateTime} < created AND
836 entity IS NOT NULL"
837 );
838
839 $statement->execute($params);
840
841 $rows = $statement->fetchAll();
842 } catch (\Exception $e) {
843 throw new QueryExecutionException('Unable to get data from ' . __CLASS__, $e->getCode(), $e);
844 }
845
846 $items = [];
847
848 foreach ($rows as $row) {
849 $items[] = call_user_func([static::FACTORY, 'create'], $row);
850 }
851
852 return new Collection($items);
853 }
854
855 /**
856 * @param int $status
857 */
858 public function findByStatus($status)
859 {
860 // TODO: Implement findByStatus() method.
861 }
862
863 /**
864 * @param int $bookingId
865 * @param int $firstPaymentId
866 * @param bool $isPackage
867 *
868 * @return array
869 * @throws QueryExecutionException
870 */
871 public function getSecondaryPayments($bookingId, $firstPaymentId, $isPackage)
872 {
873 $result = [];
874
875 $params = [
876 ':paymentId' => $firstPaymentId,
877 ':bookingId' => $bookingId
878 ];
879
880 $where = 'WHERE id <> :paymentId AND ' . ($isPackage ? 'packageCustomerId' : 'customerBookingId') . ' = :bookingId';
881
882 try {
883 $statement = $this->connection->prepare(
884 "SELECT
885 id AS id,
886 customerBookingId AS customerBookingId,
887 packageCustomerId AS packageCustomerId,
888 parentId AS parentId,
889 amount AS amount,
890 entity AS entity,
891 created AS created,
892 dateTime AS dateTime,
893 status AS status,
894 gateway AS gateway,
895 gatewayTitle AS gatewayTitle,
896 data AS data,
897 transactionId AS transactionId,
898 wcOrderId AS wcOrderId
899 FROM {$this->table}
900 {$where}"
901 );
902
903 $statement->execute($params);
904
905 $rows = $statement->fetchAll();
906
907 foreach ($rows as $row) {
908 //getting wc tax
909 /** @var Payment $paymentObject **/
910 $paymentObject = call_user_func([static::FACTORY, 'create'], $row);
911 if ($paymentObject) {
912 $paymentArray = $paymentObject->toArray();
913 $paymentArray['dateTime'] = DateTimeService::getCustomDateTimeFromUtc($paymentArray['dateTime']);
914 $result[] = $paymentArray;
915 }
916 }
917 } catch (\Exception $e) {
918 throw new QueryExecutionException('Unable to find by id in ' . __CLASS__, $e->getCode(), $e);
919 }
920 return $result;
921 }
922
923 /**
924 * @param int $paymentId
925 * @param string $transactionId
926 *
927 * @throws QueryExecutionException
928 */
929 public function updateTransactionId($paymentId, $transactionId)
930 {
931 $params = [
932 ':transactionId' => $transactionId,
933 ':paymentId1' => $paymentId,
934 ':paymentId2' => $paymentId
935 ];
936
937 try {
938 $statement = $this->connection->prepare(
939 "UPDATE {$this->table} SET `transactionId` = :transactionId WHERE id = :paymentId1 OR parentId = :paymentId2"
940 );
941
942 $response = $statement->execute($params);
943 } catch (\Exception $e) {
944 throw new QueryExecutionException('Unable to update data in ' . __CLASS__, $e->getCode(), $e);
945 }
946
947 if (!$response) {
948 throw new QueryExecutionException('Unable to update data in ' . __CLASS__);
949 }
950
951 return $response;
952 }
953 }
954