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 / Payment / PaymentRepository.php
ameliabooking / src / Infrastructure / Repository / Payment Last commit date
PaymentRepository.php 1 year ago
PaymentRepository.php
1311 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 (!empty($data['invoiceNumber'])) {
137 $params[':invoiceNumber'] = $data['invoiceNumber'];
138
139 $invoiceNumberText = ":invoiceNumber";
140 } else {
141 $invoiceNumberText = "(SELECT MAX(CASE WHEN invoiceNumber IS NULL THEN 0 ELSE invoiceNumber END)+1 FROM {$this->table} p)";
142 }
143
144 if ($data['parentId']) {
145 $params[':actionsCompleted'] = null;
146 } else {
147 $params[':actionsCompleted'] = !empty($data['actionsCompleted']) ? 1 : 0;
148 }
149
150 try {
151 $statement = $this->connection->prepare(
152 "INSERT INTO
153 {$this->table}
154 (
155 `customerBookingId`, `packageCustomerId`, `parentId`, `amount`, `dateTime`, `status`, `gateway`, `gatewayTitle`, `data`, `entity`, `actionsCompleted`, `created`, `wcOrderId`, `wcOrderItemId`, `transactionId`, `invoiceNumber`
156 ) VALUES (
157 :customerBookingId, :packageCustomerId, :parentId, :amount, :dateTime, :status, :gateway, :gatewayTitle, :data, :entity, :actionsCompleted, :created, :wcOrderId, :wcOrderItemId, :transactionId, {$invoiceNumberText}
158 )"
159 );
160
161 $response = $statement->execute($params);
162 } catch (\Exception $e) {
163 throw new QueryExecutionException('Unable to add data in ' . __CLASS__, $e->getCode(), $e);
164 }
165
166 if (!$response) {
167 throw new QueryExecutionException('Unable to add data in ' . __CLASS__);
168 }
169
170 return $this->connection->lastInsertId();
171 }
172
173 /**
174 * @param int $id
175 * @param Payment $entity
176 *
177 * @return bool
178 * @throws QueryExecutionException
179 */
180 public function update($id, $entity)
181 {
182 $data = $entity->toArray();
183
184 $params = [
185 ':customerBookingId' => $data['customerBookingId'] ? $data['customerBookingId'] : null,
186 ':packageCustomerId' => $data['packageCustomerId'] ? $data['packageCustomerId'] : null,
187 ':parentId' => $data['parentId'] ? $data['parentId'] : null,
188 ':amount' => $data['amount'],
189 ':dateTime' => DateTimeService::getCustomDateTimeInUtc($data['dateTime']),
190 ':status' => $data['status'],
191 ':gateway' => $data['gateway'],
192 ':gatewayTitle' => $data['gatewayTitle'],
193 ':data' => $data['data'],
194 ':transactionId' => $data['transactionId'],
195 ':id' => $id,
196 ];
197
198 try {
199 $statement = $this->connection->prepare(
200 "UPDATE {$this->table}
201 SET
202 `customerBookingId` = :customerBookingId,
203 `packageCustomerId` = :packageCustomerId,
204 `parentId` = :parentId,
205 `amount` = :amount,
206 `dateTime` = :dateTime,
207 `status` = :status,
208 `gateway` = :gateway,
209 `gatewayTitle` = :gatewayTitle,
210 `data` = :data,
211 `transactionId` = :transactionId
212 WHERE
213 id = :id"
214 );
215
216 $response = $statement->execute($params);
217 } catch (\Exception $e) {
218 throw new QueryExecutionException('Unable to save data in ' . __CLASS__, $e->getCode(), $e);
219 }
220
221 if (!$response) {
222 throw new QueryExecutionException('Unable to save data in ' . __CLASS__);
223 }
224
225 return $response;
226 }
227
228 /**
229 * @param array $criteria
230 *
231 * @return Collection
232 * @throws QueryExecutionException
233 */
234 public function getByCriteria($criteria)
235 {
236 $result = new Collection();
237
238 $params = [];
239
240 $where = [];
241
242 if (!empty($criteria['bookingIds'])) {
243 $queryBookings = [];
244
245 foreach ($criteria['bookingIds'] as $index => $value) {
246 $param = ':id' . $index;
247
248 $queryBookings[] = $param;
249
250 $params[$param] = $value;
251 }
252
253 $where[] = 'customerBookingId IN (' . implode(', ', $queryBookings) . ')';
254 }
255
256
257 if (!empty($criteria['packageCustomerId'])) {
258 $params[':packageCustomerId'] = $criteria['packageCustomerId'];
259 $where[] = 'packageCustomerId = :packageCustomerId';
260 }
261
262 if (!empty($criteria['ids'])) {
263 $queryIds = [];
264
265 foreach ($criteria['ids'] as $index => $value) {
266 $param = ':id' . $index;
267
268 $queryIds[] = $param;
269
270 $params[$param] = $value;
271 }
272
273 $where[] = 'id IN (' . implode(', ', $queryIds) . ')';
274 }
275
276 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
277
278 try {
279 $statement = $this->connection->prepare(
280 "SELECT
281 id AS id,
282 customerBookingId AS customerBookingId,
283 packageCustomerId AS packageCustomerId,
284 parentId AS parentId,
285 invoiceNumber AS invoiceNumber,
286 amount AS amount,
287 dateTime AS dateTime,
288 status AS status,
289 gateway AS gateway,
290 gatewayTitle AS gatewayTitle,
291 data AS data
292 FROM {$this->table}
293 {$where}"
294 );
295
296 $statement->execute($params);
297
298 while ($row = $statement->fetch()) {
299 $result->addItem(call_user_func([static::FACTORY, 'create'], $row), $row['id']);
300 }
301 } catch (\Exception $e) {
302 throw new QueryExecutionException('Unable to find by id in ' . __CLASS__, $e->getCode(), $e);
303 }
304
305 return $result;
306 }
307
308 /**
309 * @param array $ids
310 * @param boolean $invoice
311 *
312 * @return array
313 * @throws QueryExecutionException
314 * @throws InvalidArgumentException
315 */
316 public function getFiltered($ids, $invoice = false)
317 {
318 $params = [];
319 $appointmentParams1 = [];
320 $appointmentParams2 = [];
321 $eventParams = [];
322 $whereAppointment1 = [];
323 $whereAppointment2 = [];
324 $whereEvent = [];
325
326 $basedOnDate = $invoice ? 'created' : 'dateTime';
327
328 if (!empty($ids['appointment'])) {
329 $appointment1PaymentsIds = [];
330
331 foreach ($ids['appointment'] as $index => $value) {
332 $param = ':sId' . $index;
333
334 $appointment1PaymentsIds[] = $param;
335
336 $params[$param] = $value;
337 }
338
339 $whereAppointment1[] = 'p.id IN (' . implode(', ', $appointment1PaymentsIds) . ')';
340 }
341
342 if (!empty($ids['package'])) {
343 $appointment2PaymentsIds = [];
344
345 foreach ($ids['package'] as $index => $value) {
346 $param = ':pId' . $index;
347
348 $appointment2PaymentsIds[] = $param;
349
350 $params[$param] = $value;
351 }
352
353 $whereAppointment2[] = 'p.id IN (' . implode(', ', $appointment2PaymentsIds) . ')';
354 }
355
356 if (!empty($ids['event'])) {
357 $eventsIds = [];
358
359 foreach ($ids['event'] as $index => $value) {
360 $param = ':eId' . $index;
361
362 $eventsIds[] = $param;
363
364 $params[$param] = $value;
365 }
366
367 $whereEvent[] = 'p.id IN (' . implode(', ', $eventsIds) . ')';
368 }
369
370 $whereAppointment1 = $whereAppointment1 ? ' AND ' . implode(' AND ', $whereAppointment1) : '';
371 $whereAppointment2 = $whereAppointment2 ? ' AND ' . implode(' AND ', $whereAppointment2) : '';
372 $whereEvent = $whereEvent ? ' AND ' . implode(' AND ', $whereEvent) : '';
373
374 $customerBookingsExtrasTable = CustomerBookingsToExtrasTable::getTableName();
375 $couponsTable = CouponsTable::getTableName();
376 $locationsTable = LocationsTable::getTableName();
377
378 $appointmentQuery1 = "SELECT
379 p.id AS id,
380 p.customerBookingId AS customerBookingId,
381 NULL AS packageCustomerId,
382 p.amount AS amount,
383 p.invoiceNumber AS invoiceNumber,
384 p.dateTime AS dateTime,
385 p.created AS created,
386 p.status AS status,
387 p.wcOrderId AS wcOrderId,
388 p.wcOrderItemId AS wcOrderItemId,
389 p.gateway AS gateway,
390 p.gatewayTitle AS gatewayTitle,
391 p.transactionId AS transactionId,
392 p.parentId AS parentId,
393 p.entity AS type,
394
395 NULL AS packageId,
396 cb.id AS bookingId,
397 cb.price AS bookedPrice,
398 cb.tax AS bookedTax,
399 a.providerId AS providerId,
400 cb.customerId AS customerId,
401 cb.persons AS persons,
402 cb.aggregatedPrice AS aggregatedPrice,
403 cb.info AS info,
404
405 cbe.id AS bookingExtra_id,
406 cbe.quantity AS bookingExtra_quantity,
407 cbe.price AS bookingExtra_price,
408 cbe.aggregatedPrice AS bookingExtra_aggregatedPrice,
409 cbe.tax AS bookingExtra_tax,
410
411 c.id AS coupon_id,
412 c.discount AS coupon_discount,
413 c.deduction AS coupon_deduction,
414 c.code AS coupon_code,
415
416 a.serviceId AS serviceId,
417 a.id AS appointmentId,
418 a.bookingStart AS bookingStart,
419 s.name AS bookableName,
420 cu.firstName AS customerFirstName,
421 cu.lastName AS customerLastName,
422 cu.email AS customerEmail,
423 cu.status AS customerStatus,
424 pu.firstName AS providerFirstName,
425 pu.lastName AS providerLastName,
426 pu.email AS providerEmail,
427 l.id AS locationId,
428 l.name AS location_name,
429 l.address AS location_address
430 FROM {$this->table} p
431 INNER JOIN {$this->bookingsTable} cb ON cb.id = p.customerBookingId
432 LEFT JOIN {$customerBookingsExtrasTable} cbe ON cbe.customerBookingId = cb.id
433 LEFT JOIN {$couponsTable} c ON c.id = cb.couponId
434 INNER JOIN {$this->appointmentsTable} a ON a.id = cb.appointmentId
435 INNER JOIN {$this->servicesTable} s ON s.id = a.serviceId
436 INNER JOIN {$this->usersTable} cu ON cu.id = cb.customerId
437 INNER JOIN {$this->usersTable} pu ON pu.id = a.providerId
438 LEFT JOIN {$locationsTable} l ON l.id = a.locationId
439 WHERE 1=1 {$whereAppointment1} GROUP BY p.customerBookingId ORDER BY p.id ASC";
440
441 $appointmentQuery2 = "SELECT
442 p.id AS id,
443 NULL AS customerBookingId,
444 p.packageCustomerId AS packageCustomerId,
445 p.amount AS amount,
446 p.invoiceNumber AS invoiceNumber,
447 p.dateTime AS dateTime,
448 p.created AS created,
449 p.status AS status,
450 p.wcOrderId AS wcOrderId,
451 p.wcOrderItemId AS wcOrderItemId,
452 p.gateway AS gateway,
453 p.gatewayTitle AS gatewayTitle,
454 p.transactionId AS transactionId,
455 p.parentId AS parentId,
456 p.entity AS type,
457
458 pc.packageId AS packageId,
459 pc.id AS bookingId,
460 pc.price AS bookedPrice,
461 pc.tax AS bookedTax,
462 NULL AS providerId,
463 pc.customerId AS customerId,
464 NULL AS persons,
465 NULL AS aggregatedPrice,
466 cb.info AS info,
467
468 NULL AS bookingExtra_id,
469 NULL AS bookingExtra_quantity,
470 NULL AS bookingExtra_price,
471 NULL AS bookingExtra_aggregatedPrice,
472 NULL AS bookingExtra_tax,
473
474 c.id AS coupon_id,
475 c.discount AS coupon_discount,
476 c.deduction AS coupon_deduction,
477 c.code AS coupon_code,
478
479 NULL AS serviceId,
480 NULL AS appointmentId,
481 NULL AS bookingStart,
482 pa.name AS bookableName,
483 cu.firstName AS customerFirstName,
484 cu.lastName AS customerLastName,
485 cu.email AS customerEmail,
486 cu.status AS customerStatus,
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} 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.invoiceNumber AS invoiceNumber,
509 p.dateTime AS dateTime,
510 p.created AS created,
511 p.status AS status,
512 p.wcOrderId AS wcOrderId,
513 p.wcOrderItemId AS wcOrderItemId,
514 p.gateway AS gateway,
515 p.gatewayTitle AS gatewayTitle,
516 p.transactionId AS transactionId,
517 p.parentId AS parentId,
518 p.entity AS type,
519
520 NULL AS packageId,
521 cb.id AS bookingId,
522 cb.price AS bookedPrice,
523 cb.tax AS bookedTax,
524 NULL AS providerId,
525 cb.customerId AS customerId,
526 cb.persons AS persons,
527 cb.aggregatedPrice AS aggregatedPrice,
528 cb.info AS info,
529
530 NULL AS bookingExtra_id,
531 NULL AS bookingExtra_quantity,
532 NULL AS bookingExtra_price,
533 NULL AS bookingExtra_aggregatedPrice,
534 NULL AS bookingExtra_tax,
535
536 c.id AS coupon_id,
537 c.discount AS coupon_discount,
538 c.deduction AS coupon_deduction,
539 c.code AS coupon_code,
540
541 NULL AS serviceId,
542 NULL AS appointmentId,
543 NULL AS bookingStart,
544 NULL AS bookableName,
545 cu.firstName AS customerFirstName,
546 cu.lastName AS customerLastName,
547 cu.email AS customerEmail,
548 cu.status AS customerStatus,
549 NULL AS providerFirstName,
550 NULL AS providerLastName,
551 NULL AS providerEmail,
552 l.id AS locationId,
553 l.name AS location_name,
554 (CASE WHEN e.customlocation IS NOT NULL THEN e.customlocation ELSE l.address END) AS location_address
555 FROM {$this->table} p
556 INNER JOIN {$this->bookingsTable} cb ON cb.id = p.customerBookingId
557 LEFT JOIN {$couponsTable} c ON c.id = cb.couponId
558 INNER JOIN {$this->usersTable} cu ON cu.id = cb.customerId
559 INNER JOIN {$this->customerBookingsToEventsPeriodsTable} cbe ON cbe.customerBookingId = cb.id
560 INNER JOIN {$this->eventsPeriodsTable} ep ON ep.id = cbe.eventPeriodId
561 INNER JOIN {$this->eventsTable} e ON e.id = ep.eventId
562 LEFT JOIN {$this->eventsProvidersTable} epu ON epu.eventId = ep.eventId
563 LEFT JOIN {$locationsTable} l ON l.id = e.locationId
564 WHERE 1=1 {$whereEvent} ORDER BY p.id ASC";
565
566 $paymentQuery = '';
567
568 if (!empty($ids['appointment'])) {
569 $paymentQuery = "({$appointmentQuery1})";
570
571 $params = array_merge($params, $appointmentParams1);
572 }
573
574 if (!empty($ids['package'])) {
575 $paymentQuery = $paymentQuery ? $paymentQuery . " UNION ALL ({$appointmentQuery2})" : "({$appointmentQuery2})";
576
577 $params = array_merge($params, $appointmentParams2);
578 }
579
580 if (!empty($ids['event'])) {
581 $paymentQuery = $paymentQuery ? $paymentQuery . " UNION ALL ({$eventQuery})" : "({$eventQuery})";
582
583 $params = array_merge($params, $eventParams);
584 }
585
586 try {
587 $statement = $this->connection->prepare(
588 "SELECT * FROM ({$paymentQuery}) payments
589 ORDER BY {$basedOnDate}, id"
590 );
591
592 $statement->execute($params);
593
594 $rows = $statement->fetchAll();
595 } catch (\Exception $e) {
596 throw new QueryExecutionException('Unable to get data from ' . __CLASS__, $e->getCode(), $e);
597 }
598
599 $result = [];
600
601 foreach ($rows as &$row) {
602 $customerInfo = $row['info'] ? json_decode($row['info'], true) : null;
603
604 $result[(int)$row['id']] = [
605 'id' => (int)$row['id'],
606 'dateTime' => DateTimeService::getCustomDateTimeFromUtc($row['dateTime']),
607 'created' => DateTimeService::getCustomDateTimeFromUtc($row['created']),
608 'bookingStart' => $row['bookingStart'] ?
609 DateTimeService::getCustomDateTimeFromUtc($row['bookingStart']) : null,
610 'status' => $row['status'],
611 'parentId' => $row['parentId'],
612 'wcOrderId' => $row['wcOrderId'],
613 'wcOrderItemId' => $row['wcOrderItemId'],
614 'gateway' => $row['gateway'],
615 'gatewayTitle' => $row['gatewayTitle'],
616 'transactionId' => $row['transactionId'],
617 'type' => $row['type'],
618 'name' => $row['bookableName'],
619 'customerBookingId' => (int)$row['customerBookingId'] ? (int)$row['customerBookingId'] : null,
620 'packageCustomerId' => (int)$row['packageCustomerId'] ? (int)$row['packageCustomerId'] : null,
621 'amount' => (float)$row['amount'],
622 'invoiceNumber' => $row['invoiceNumber'],
623 'providers' => (int)$row['providerId'] ? [
624 [
625 'id' => (int)$row['providerId'],
626 'fullName' => $row['providerFirstName'] . ' ' . $row['providerLastName'],
627 'email' => $row['providerEmail'],
628 ]
629 ] : [],
630 'location' => (int)$row['locationId'] || $row['location_address'] ?
631 [
632 'id' => (int)$row['locationId'],
633 'location_name' => $row['location_name'],
634 'location_address' => $row['location_address'],
635 ]
636 : null,
637 'customerId' => (int)$row['customerId'],
638 'serviceId' => (int)$row['serviceId'] ? (int)$row['serviceId'] : null,
639 'appointmentId' => (int)$row['appointmentId'] ? (int)$row['appointmentId'] : null,
640 'packageId' => (int)$row['packageId'] ? (int)$row['packageId'] : null,
641 'bookedPrice' => $row['bookedPrice'] ? $row['bookedPrice'] : null,
642 'bookedTax' => $row['bookedTax'] ? $row['bookedTax'] : null,
643 'bookingId' => !empty($row['bookingId']) ? (int)$row['bookingId'] : null,
644 'bookableName' => $row['bookableName'],
645 'customerFirstName' => $customerInfo ? $customerInfo['firstName'] : $row['customerFirstName'],
646 'customerLastName' => $customerInfo ? $customerInfo['lastName'] : $row['customerLastName'],
647 'info' => $row['info'],
648 'customerEmail' => $row['customerEmail'],
649 'customerStatus' => $row['customerStatus'],
650 'coupon' => !empty($row['coupon_id']) ? [
651 'id' => $row['coupon_id'],
652 'discount' => $row['coupon_discount'],
653 'deduction' => $row['coupon_deduction'],
654 'code' => $row['coupon_code']
655 ] : null,
656 'persons' => $row['persons'],
657 'aggregatedPrice' => $row['aggregatedPrice'],
658 'extras' => (int)$row['bookingExtra_id'] ? [
659 [
660 'id' => (int)$row['bookingExtra_id'],
661 'quantity' => $row['bookingExtra_quantity'],
662 'price' =>$row['bookingExtra_price'],
663 'aggregatedPrice' => $row['bookingExtra_aggregatedPrice'],
664 'tax' => $row['bookingExtra_tax'] ?: null
665 ]
666 ] : [],
667 ];
668 }
669
670 return $result;
671 }
672
673 /**
674 * @param array $criteria
675 * @param int $itemsPerPage
676 * @param boolean $invoice
677 *
678 * @return array
679 * @throws QueryExecutionException
680 */
681 public function getFilteredIds($criteria, $itemsPerPage = null, $invoice = false)
682 {
683 $params = [];
684 $appointmentParams1 = [];
685 $appointmentParams2 = [];
686 $eventParams = [];
687 $whereAppointment1 = [];
688 $whereAppointment2 = [];
689 $whereEvent = [];
690
691 $basedOnDate = $invoice ? 'created' : 'dateTime';
692
693 if (!empty($criteria['dates'])) {
694 $whereAppointment1[] = "(DATE_FORMAT(p.{$basedOnDate}, '%Y-%m-%d %H:%i:%s') BETWEEN :paymentAppointmentFrom1 AND :paymentAppointmentTo1)";
695 $whereAppointment2[] = "(DATE_FORMAT(p.{$basedOnDate}, '%Y-%m-%d %H:%i:%s') BETWEEN :paymentAppointmentFrom2 AND :paymentAppointmentTo2)";
696 $appointmentParams1[':paymentAppointmentFrom1'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
697 $appointmentParams2[':paymentAppointmentFrom2'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
698 $appointmentParams1[':paymentAppointmentTo1'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][1]);
699 $appointmentParams2[':paymentAppointmentTo2'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][1]);
700
701 $whereEvent[] = "(DATE_FORMAT(p.{$basedOnDate}, '%Y-%m-%d %H:%i:%s') BETWEEN :paymentEventFrom AND :paymentEventTo)";
702 $eventParams[':paymentEventFrom'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
703 $eventParams[':paymentEventTo'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][1]);
704 }
705
706 if (!empty($criteria['customerId'])) {
707 $appointmentParams1[':customerAppointmentId1'] = $criteria['customerId'];
708 $appointmentParams2[':customerAppointmentId2'] = $criteria['customerId'];
709 $whereAppointment1[] = 'cb.customerId = :customerAppointmentId1';
710 $whereAppointment2[] = 'pc.customerId = :customerAppointmentId2';
711
712 $eventParams[':customerEventId'] = $criteria['customerId'];
713 $whereEvent[] = 'cb.customerId = :customerEventId';
714 }
715
716 $eventsProvidersJoin = '';
717
718 if (!empty($criteria['providerId'])) {
719 $appointmentParams1[':providerAppointmentId1'] = $criteria['providerId'];
720 $appointmentParams1[':providerAppointmentId2'] = $criteria['providerId'];
721 $whereAppointment1[] = 'a.providerId = :providerAppointmentId1';
722 $whereAppointment2[] = 'a.providerId = :providerAppointmentId2';
723
724 $eventParams[':providerEventId'] = $criteria['providerId'];
725 $whereEvent[] = 'epu.userId = :providerEventId';
726
727 $eventsProvidersJoin = "
728 INNER JOIN {$this->eventsPeriodsTable} ep ON ep.id = cbe.eventPeriodId
729 INNER JOIN {$this->eventsProvidersTable} epu ON epu.eventId = ep.eventId
730 ";
731 }
732
733 if (!empty($criteria['services'])) {
734 $queryServices1 = [];
735 $queryServices2 = [];
736
737 foreach ((array)$criteria['services'] as $index => $value) {
738 $param1 = ':service0' . $index;
739 $param2 = ':service1' . $index;
740 $queryServices1[] = $param1;
741 $queryServices2[] = $param2;
742 $appointmentParams1[$param1] = $value;
743 $appointmentParams2[$param2] = $value;
744 }
745
746 $whereAppointment1[] = 'a.serviceId IN (' . implode(', ', $queryServices1) . ')';
747 $whereAppointment2[] = 'a.serviceId IN (' . implode(', ', $queryServices2) . ')';
748 }
749
750 $appointments2ProvidersServicesJoin = '';
751
752 if (!empty($criteria['providerId']) || !empty($criteria['services'])) {
753 $appointments2ProvidersServicesJoin = "
754 INNER JOIN {$this->packagesCustomersServiceTable} pcs ON pc.id = pcs.packageCustomerId
755 INNER JOIN {$this->bookingsTable} cb ON cb.packageCustomerServiceId = pcs.id
756 INNER JOIN {$this->appointmentsTable} a ON a.id = cb.appointmentId
757 ";
758 }
759
760 if (!empty($criteria['status'])) {
761 $appointmentParams1[':statusAppointment1'] = $criteria['status'];
762 $appointmentParams2[':statusAppointment2'] = $criteria['status'];
763 $whereAppointment1[] = 'p.status = :statusAppointment1';
764 $whereAppointment2[] = 'p.status = :statusAppointment2';
765
766 $eventParams[':statusEvent'] = $criteria['status'];
767 $whereEvent[] = 'p.status = :statusEvent';
768 }
769
770 if (!empty($criteria['packages'])) {
771 $queryPackages = [];
772
773 foreach ((array)$criteria['packages'] as $index => $value) {
774 $param = ':package' . $index;
775 $queryPackages[] = $param;
776 $appointmentParams2[$param] = $value;
777 }
778
779 $whereAppointment2[] = "p.packageCustomerId IN (SELECT pc.id
780 FROM {$this->packagesCustomersTable} pc
781 WHERE pc.packageId IN (" . implode(', ', $queryPackages) . '))';
782 }
783
784 if (!empty($criteria['events'])) {
785 $queryEvents = [];
786
787 foreach ((array)$criteria['events'] as $index => $value) {
788 $param = ':event' . $index;
789 $queryEvents[] = $param;
790 $eventParams[$param] = $value;
791 }
792
793 $whereEvent[] = "p.customerBookingId IN (SELECT cbe.customerBookingId
794 FROM {$this->eventsTable} e
795 INNER JOIN {$this->eventsPeriodsTable} ep ON ep.eventId = e.id
796 INNER JOIN {$this->customerBookingsToEventsPeriodsTable} cbe ON cbe.eventPeriodId = ep.id
797 WHERE e.id IN (" . implode(', ', $queryEvents) . '))';
798 }
799
800 $whereAppointment1 = $whereAppointment1 ? ' AND ' . implode(' AND ', $whereAppointment1) : '';
801 $whereAppointment2 = $whereAppointment2 ? ' AND ' . implode(' AND ', $whereAppointment2) : '';
802 $whereEvent = $whereEvent ? ' AND ' . implode(' AND ', $whereEvent) : '';
803
804 $groupBy = '';
805 if ($invoice) {
806 $groupBy = 'GROUP BY IFNULL(invoiceNumber, id)';
807 }
808
809 $appointmentQuery1 = "SELECT
810 p.id AS id,
811 p.dateTime AS dateTime,
812 p.created AS created,
813 p.invoiceNumber AS invoiceNumber,
814 'appointment' AS type
815 FROM {$this->table} p
816 INNER JOIN {$this->bookingsTable} cb ON cb.id = p.customerBookingId
817 INNER JOIN {$this->appointmentsTable} a ON a.id = cb.appointmentId
818 WHERE 1=1 {$whereAppointment1} GROUP BY p.customerBookingId ORDER BY p.id ASC";
819
820 $appointmentQuery2 = "SELECT
821 p.id AS id,
822 p.dateTime AS dateTime,
823 p.created AS created,
824 p.invoiceNumber AS invoiceNumber,
825 'package' AS type
826 FROM {$this->table} p
827 INNER JOIN {$this->packagesCustomersTable} pc ON p.packageCustomerId = pc.id
828 {$appointments2ProvidersServicesJoin}
829 WHERE 1=1 {$whereAppointment2} GROUP BY p.packageCustomerId ORDER BY p.id ASC";
830
831 $eventQuery = "SELECT
832 p.id AS id,
833 p.dateTime AS dateTime,
834 p.created AS created,
835 p.invoiceNumber AS invoiceNumber,
836 'event' AS type
837 FROM {$this->table} p
838 INNER JOIN {$this->bookingsTable} cb ON cb.id = p.customerBookingId
839 INNER JOIN {$this->customerBookingsToEventsPeriodsTable} cbe ON cbe.customerBookingId = cb.id
840 {$eventsProvidersJoin}
841 WHERE 1=1 {$whereEvent} GROUP BY p.customerBookingId ORDER BY p.id ASC";
842
843 $result = [
844 'appointment' => [],
845 'event' => [],
846 'package' => [],
847 ];
848
849 if (isset($criteria['events'], $criteria['services'])) {
850 return $result;
851 } elseif (isset($criteria['services'])) {
852 $paymentQuery = "({$appointmentQuery1}) UNION ALL ({$appointmentQuery2})";
853 $params = array_merge($params, $appointmentParams1, $appointmentParams2);
854 } elseif (isset($criteria['events'])) {
855 $paymentQuery = "({$eventQuery})";
856 $params = array_merge($params, $eventParams);
857 } elseif (isset($criteria['packages'])) {
858 $paymentQuery = "({$appointmentQuery2})";
859 $params = array_merge($params, $appointmentParams2);
860 } else {
861 $paymentQuery = "({$appointmentQuery1}) UNION ALL ({$appointmentQuery2}) UNION ALL ({$eventQuery})";
862 $params = array_merge($params, $appointmentParams1, $appointmentParams2, $eventParams);
863 }
864
865 $limit = $this->getLimit(
866 !empty($criteria['page']) ? (int)$criteria['page'] : 0,
867 (int)$itemsPerPage
868 );
869
870 try {
871 $statement = $this->connection->prepare(
872 "SELECT * FROM ({$paymentQuery}) payments
873 {$groupBy}
874 ORDER BY {$basedOnDate}, id
875 {$limit}"
876 );
877
878 $statement->execute($params);
879
880 $rows = $statement->fetchAll();
881 } catch (\Exception $e) {
882 throw new QueryExecutionException('Unable to get data from ' . __CLASS__, $e->getCode(), $e);
883 }
884
885 foreach ($rows as $row) {
886 $result[$row['type']][] = (int)$row['id'];
887 }
888
889 return $result;
890 }
891
892 /**
893 * @param array $criteria
894 * @param boolean $invoice
895 *
896 * @return array
897 * @throws QueryExecutionException
898 */
899 public function getFilteredIdsCount($criteria, $invoice = false)
900 {
901 $params = [];
902 $appointmentParams1 = [];
903 $appointmentParams2 = [];
904 $eventParams = [];
905 $whereAppointment1 = [];
906 $whereAppointment2 = [];
907 $whereEvent = [];
908
909 $basedOnDate = $invoice ? 'created' : 'dateTime';
910
911 if (!empty($criteria['dates'])) {
912 $whereAppointment1[] = "(DATE_FORMAT(p.{$basedOnDate}, '%Y-%m-%d %H:%i:%s') BETWEEN :paymentAppointmentFrom1 AND :paymentAppointmentTo1)";
913 $whereAppointment2[] = "(DATE_FORMAT(p.{$basedOnDate}, '%Y-%m-%d %H:%i:%s') BETWEEN :paymentAppointmentFrom2 AND :paymentAppointmentTo2)";
914 $appointmentParams1[':paymentAppointmentFrom1'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
915 $appointmentParams2[':paymentAppointmentFrom2'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
916 $appointmentParams1[':paymentAppointmentTo1'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][1]);
917 $appointmentParams2[':paymentAppointmentTo2'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][1]);
918
919 $whereEvent[] = "(DATE_FORMAT(p.{$basedOnDate}, '%Y-%m-%d %H:%i:%s') BETWEEN :paymentEventFrom AND :paymentEventTo)";
920 $eventParams[':paymentEventFrom'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
921 $eventParams[':paymentEventTo'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][1]);
922 }
923
924 if (!empty($criteria['customerId'])) {
925 $appointmentParams1[':customerAppointmentId1'] = $criteria['customerId'];
926 $appointmentParams2[':customerAppointmentId2'] = $criteria['customerId'];
927 $whereAppointment1[] = 'cb.customerId = :customerAppointmentId1';
928 $whereAppointment2[] = 'pc.customerId = :customerAppointmentId2';
929
930 $eventParams[':customerEventId'] = $criteria['customerId'];
931 $whereEvent[] = 'cb.customerId = :customerEventId';
932 }
933
934 $eventsProvidersJoin = '';
935
936 if (!empty($criteria['providerId'])) {
937 $appointmentParams1[':providerAppointmentId1'] = $criteria['providerId'];
938 $appointmentParams1[':providerAppointmentId2'] = $criteria['providerId'];
939 $whereAppointment1[] = 'a.providerId = :providerAppointmentId1';
940 $whereAppointment2[] = 'a.providerId = :providerAppointmentId2';
941
942 $eventParams[':providerEventId'] = $criteria['providerId'];
943 $whereEvent[] = 'epu.userId = :providerEventId';
944
945 $eventsProvidersJoin = "
946 INNER JOIN {$this->eventsPeriodsTable} ep ON ep.id = cbe.eventPeriodId
947 INNER JOIN {$this->eventsProvidersTable} epu ON epu.eventId = ep.eventId
948 ";
949 }
950
951 if (!empty($criteria['services'])) {
952 $queryServices1 = [];
953 $queryServices2 = [];
954
955 foreach ((array)$criteria['services'] as $index => $value) {
956 $param1 = ':service0' . $index;
957 $param2 = ':service1' . $index;
958 $queryServices1[] = $param1;
959 $queryServices2[] = $param2;
960 $appointmentParams1[$param1] = $value;
961 $appointmentParams2[$param2] = $value;
962 }
963
964 $whereAppointment1[] = 'a.serviceId IN (' . implode(', ', $queryServices1) . ')';
965 $whereAppointment2[] = 'a.serviceId IN (' . implode(', ', $queryServices2) . ')';
966 }
967
968 $appointments2ProvidersServicesJoin = '';
969
970 if (!empty($criteria['providerId']) || !empty($criteria['services'])) {
971 $appointments2ProvidersServicesJoin = "
972 INNER JOIN {$this->packagesCustomersServiceTable} pcs ON pc.id = pcs.packageCustomerId
973 INNER JOIN {$this->bookingsTable} cb ON cb.packageCustomerServiceId = pcs.id
974 INNER JOIN {$this->appointmentsTable} a ON a.id = cb.appointmentId
975 ";
976 }
977
978 if (!empty($criteria['status'])) {
979 $appointmentParams1[':statusAppointment1'] = $criteria['status'];
980 $appointmentParams2[':statusAppointment2'] = $criteria['status'];
981 $whereAppointment1[] = 'p.status = :statusAppointment1';
982 $whereAppointment2[] = 'p.status = :statusAppointment2';
983
984 $eventParams[':statusEvent'] = $criteria['status'];
985 $whereEvent[] = 'p.status = :statusEvent';
986 }
987
988 if (!empty($criteria['events'])) {
989 $queryEvents = [];
990
991 foreach ((array)$criteria['events'] as $index => $value) {
992 $param = ':event' . $index;
993 $queryEvents[] = $param;
994 $eventParams[$param] = $value;
995 }
996
997 $whereEvent[] = "p.customerBookingId IN (SELECT cbe.customerBookingId
998 FROM {$this->eventsTable} e
999 INNER JOIN {$this->eventsPeriodsTable} ep ON ep.eventId = e.id
1000 INNER JOIN {$this->customerBookingsToEventsPeriodsTable} cbe ON cbe.eventPeriodId = ep.id
1001 WHERE e.id IN (" . implode(', ', $queryEvents) . '))';
1002 }
1003
1004 if (!empty($criteria['packages'])) {
1005 $queryPackages = [];
1006
1007 foreach ((array)$criteria['packages'] as $index => $value) {
1008 $param = ':package' . $index;
1009 $queryPackages[] = $param;
1010 $appointmentParams2[$param] = $value;
1011 }
1012
1013 $whereAppointment2[] = "p.packageCustomerId IN (SELECT pc.id
1014 FROM {$this->packagesCustomersTable} pc
1015 WHERE pc.packageId IN (" . implode(', ', $queryPackages) . '))';
1016 }
1017
1018 $whereAppointment1 = $whereAppointment1 ? ' AND ' . implode(' AND ', $whereAppointment1) : '';
1019 $whereAppointment2 = $whereAppointment2 ? ' AND ' . implode(' AND ', $whereAppointment2) : '';
1020 $whereEvent = $whereEvent ? ' AND ' . implode(' AND ', $whereEvent) : '';
1021
1022 $groupBy = '';
1023 if ($invoice) {
1024 $groupBy = 'GROUP BY IFNULL(invoiceNumber, id)';
1025 }
1026
1027
1028 $appointmentQuery1 = "SELECT
1029 COUNT(DISTINCT(p.customerBookingId)) AS appointmentsCount1,
1030 0 AS appointmentsCount2,
1031 0 AS eventsCount,
1032 p.id AS id,
1033 p.invoiceNumber AS invoiceNumber,
1034 p.created AS created,
1035 p.dateTime AS dateTime
1036 FROM {$this->table} p
1037 INNER JOIN {$this->bookingsTable} cb ON cb.id = p.customerBookingId
1038 INNER JOIN {$this->appointmentsTable} a ON a.id = cb.appointmentId
1039 WHERE 1=1 {$whereAppointment1} GROUP BY p.customerBookingId ORDER BY p.id ASC";
1040
1041 $appointmentQuery2 = "SELECT
1042 0 AS appointmentsCount1,
1043 COUNT(DISTINCT(p.packageCustomerId)) AS appointmentsCount2,
1044 0 AS eventsCount,
1045 p.id AS id,
1046 p.invoiceNumber AS invoiceNumber,
1047 p.created AS created,
1048 p.dateTime AS dateTime
1049 FROM {$this->table} p
1050 INNER JOIN {$this->packagesCustomersTable} pc ON p.packageCustomerId = pc.id
1051 {$appointments2ProvidersServicesJoin}
1052 WHERE 1=1 {$whereAppointment2} GROUP BY p.packageCustomerId ORDER BY p.id ASC";
1053
1054 $eventQuery = "SELECT
1055 0 AS appointmentsCount1,
1056 0 AS appointmentsCount2,
1057 COUNT(DISTINCT(p.customerBookingId)) AS eventsCount,
1058 p.id AS id,
1059 p.invoiceNumber AS invoiceNumber,
1060 p.created AS created,
1061 p.dateTime AS dateTime
1062 FROM {$this->table} p
1063 INNER JOIN {$this->bookingsTable} cb ON cb.id = p.customerBookingId
1064 INNER JOIN {$this->customerBookingsToEventsPeriodsTable} cbe ON cbe.customerBookingId = cb.id
1065 {$eventsProvidersJoin}
1066 WHERE 1=1 {$whereEvent} GROUP BY p.customerBookingId ORDER BY p.id ASC";
1067
1068 if (isset($criteria['events'], $criteria['services'])) {
1069 return [];
1070 } elseif (isset($criteria['services'])) {
1071 $paymentQuery = "({$appointmentQuery1}) UNION ALL ({$appointmentQuery2})";
1072 $params = array_merge($params, $appointmentParams1, $appointmentParams2);
1073 } elseif (isset($criteria['events'])) {
1074 $paymentQuery = "({$eventQuery})";
1075 $params = array_merge($params, $eventParams);
1076 } elseif (isset($criteria['packages'])) {
1077 $paymentQuery = "({$appointmentQuery2})";
1078 $params = array_merge($params, $appointmentParams2);
1079 } else {
1080 $paymentQuery = "({$appointmentQuery1}) UNION ALL ({$appointmentQuery2}) UNION ALL ({$eventQuery})";
1081 $params = array_merge($params, $appointmentParams1, $appointmentParams2, $eventParams);
1082 }
1083
1084 try {
1085 $statement = $this->connection->prepare(
1086 "SELECT * FROM ({$paymentQuery}) payments
1087 {$groupBy}
1088 ORDER BY {$basedOnDate}, id"
1089 );
1090
1091 $statement->execute($params);
1092
1093 $statements = $statement->fetchAll();
1094
1095 $appointmentsCount1 = 0;
1096 $appointmentsCount2 = 0;
1097 $eventsCount = 0;
1098
1099 foreach ($statements as $st) {
1100 $appointmentsCount1 += !empty($st['appointmentsCount1']) ? $st['appointmentsCount1'] : 0;
1101 $appointmentsCount2 += !empty($st['appointmentsCount2']) ? $st['appointmentsCount2'] : 0;
1102 $eventsCount += !empty($st['eventsCount']) ? $st['eventsCount'] : 0;
1103 }
1104 } catch (\Exception $e) {
1105 throw new QueryExecutionException('Unable to get data from ' . __CLASS__, $e->getCode(), $e);
1106 }
1107
1108 return $appointmentsCount1 + $appointmentsCount2 + $eventsCount;
1109 }
1110
1111 /**
1112 * Returns a collection of customers that have birthday on today's date and where notification is not sent
1113 *
1114 * @return Collection
1115 * @throws InvalidArgumentException
1116 * @throws QueryExecutionException
1117 * @throws \Exception
1118 */
1119 public function getUncompletedActionsForPayments()
1120 {
1121 $params = [];
1122
1123 $currentDateTime = "STR_TO_DATE('" . DateTimeService::getNowDateTimeInUtc() . "', '%Y-%m-%d %H:%i:%s')";
1124
1125 $pastDateTime =
1126 "STR_TO_DATE('" .
1127 DateTimeService::getNowDateTimeObjectInUtc()->modify('-1 day')->format('Y-m-d H:i:s') .
1128 "', '%Y-%m-%d %H:%i:%s')";
1129
1130 try {
1131 $statement = $this->connection->prepare(
1132 "SELECT * FROM {$this->table}
1133 WHERE
1134 actionsCompleted = 0 AND
1135 {$currentDateTime} > DATE_ADD(created, INTERVAL 300 SECOND) AND
1136 {$pastDateTime} < created AND
1137 entity IS NOT NULL"
1138 );
1139
1140 $statement->execute($params);
1141
1142 $rows = $statement->fetchAll();
1143 } catch (\Exception $e) {
1144 throw new QueryExecutionException('Unable to get data from ' . __CLASS__, $e->getCode(), $e);
1145 }
1146
1147 $items = [];
1148
1149 foreach ($rows as $row) {
1150 $items[] = call_user_func([static::FACTORY, 'create'], $row);
1151 }
1152
1153 return new Collection($items);
1154 }
1155
1156 /**
1157 * @param int $status
1158 */
1159 public function findByStatus($status)
1160 {
1161 // TODO: Implement findByStatus() method.
1162 }
1163
1164 /**
1165 * @param array $data
1166 * @param boolean $invoice
1167 *
1168 * @return array
1169 * @throws QueryExecutionException
1170 */
1171 public function getSecondaryPaymentIds($data, $invoice)
1172 {
1173 $rows = [];
1174
1175 $params = [];
1176
1177 $where = [];
1178
1179 foreach ($data as $index => $item) {
1180 $paymentIdParam1 = ':paymentId1' . $index;
1181 $params[$paymentIdParam1] = $item['paymentId'];
1182
1183 if ($invoice) {
1184 if (!empty($item['parentId'])) {
1185 $parentIdParam1 = ':parentId1' . $index;
1186 $params[$parentIdParam1] = $item['parentId'];
1187 $parentIdParam2 = ':parentId2' . $index;
1188 $params[$parentIdParam2] = $item['parentId'];
1189 }
1190 $paymentIdParam2 = ':paymentId2' . $index;
1191 $params[$paymentIdParam2] = $item['paymentId'];
1192 }
1193
1194 $relationParam = ':' . $item['columnName'] . $index;
1195
1196 $params[$relationParam] = $item['columnId'];
1197
1198 // change in the future to simply retrieve by invoiceNumber when on invoice page since all the related payments will have the same invoiceNumber
1199 // cannot be done immediately since invoiceNumber is NULL for existing payments
1200 if ($invoice) {
1201 $where[] = "((id <> $paymentIdParam1 AND " . $item['columnName'] . " = $relationParam) OR parentId = $paymentIdParam2" . (!empty($item['parentId']) ? " OR id = $parentIdParam1 OR parentId = $parentIdParam2)" : ")");
1202 } else {
1203 $where[] = "(id <> $paymentIdParam1 AND " . $item['columnName'] . " = $relationParam)";
1204 }
1205 }
1206
1207 $where = $where ? 'WHERE ' . implode(' OR ', $where) : '';
1208
1209 try {
1210 $statement = $this->connection->prepare(
1211 "SELECT
1212 p.id AS id,
1213 p.entity AS entity
1214 FROM {$this->table} p
1215 {$where}"
1216 );
1217
1218 $statement->execute($params);
1219
1220 $rows = $statement->fetchAll();
1221 } catch (\Exception $e) {
1222 throw new QueryExecutionException('Unable to find by id in ' . __CLASS__, $e->getCode(), $e);
1223 }
1224
1225 $result = [
1226 'appointment' => [],
1227 'event' => [],
1228 'package' => []
1229 ];
1230
1231 foreach ($rows as $row) {
1232 $result[$row['entity']][] = (int)$row['id'];
1233 }
1234
1235 return $result;
1236 }
1237
1238 /**
1239 * @param int $paymentId
1240 * @param string $transactionId
1241 *
1242 * @throws QueryExecutionException
1243 */
1244 public function updateTransactionId($paymentId, $transactionId)
1245 {
1246 $params = [
1247 ':transactionId' => $transactionId,
1248 ':paymentId1' => $paymentId,
1249 ':paymentId2' => $paymentId
1250 ];
1251
1252 try {
1253 $statement = $this->connection->prepare(
1254 "UPDATE {$this->table} SET `transactionId` = :transactionId WHERE id = :paymentId1 OR parentId = :paymentId2"
1255 );
1256
1257 $response = $statement->execute($params);
1258 } catch (\Exception $e) {
1259 throw new QueryExecutionException('Unable to update data in ' . __CLASS__, $e->getCode(), $e);
1260 }
1261
1262 if (!$response) {
1263 throw new QueryExecutionException('Unable to update data in ' . __CLASS__);
1264 }
1265
1266 return $response;
1267 }
1268
1269
1270
1271 /**
1272 * @param array $data
1273 *
1274 * @return bool
1275 * @throws QueryExecutionException
1276 */
1277 public function setInvoiceNumber($data)
1278 {
1279 $params = [
1280 ':id1' => $data['id'],
1281 ':id2' => $data['id'],
1282 ":{$data['columnName']}" => $data['columnValue']
1283 ];
1284
1285 $where = "WHERE id = :id1 OR parentId = :id2 OR {$data['columnName']} = :{$data['columnName']}";
1286
1287 if (!empty($data['parentId'])) {
1288 $params[':parentId1'] = $params[':parentId2'] = $data['parentId'];
1289 $where = ' OR id = :parentId1 OR parentId = :parentId2';
1290 }
1291
1292 try {
1293 $statement = $this->connection->prepare(
1294 "UPDATE {$this->table}
1295 SET `invoiceNumber` = (SELECT MAX(CASE WHEN invoiceNumber IS NULL THEN 0 ELSE invoiceNumber END)+1 FROM (SELECT * FROM {$this->table}) AS p)
1296 {$where}"
1297 );
1298
1299 $response = $statement->execute($params);
1300 } catch (\Exception $e) {
1301 throw new QueryExecutionException('Unable to save invoice number in ' . __CLASS__, $e->getCode(), $e);
1302 }
1303
1304 if (!$response) {
1305 throw new QueryExecutionException('Unable to save invoice number in ' . __CLASS__);
1306 }
1307
1308 return $response;
1309 }
1310 }
1311