PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / trunk
Booking for Appointments and Events Calendar – Amelia vtrunk
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 / Tax / TaxRepository.php
ameliabooking / src / Infrastructure / Repository / Tax Last commit date
TaxEntityRepository.php 3 months ago TaxRepository.php 2 months ago
TaxRepository.php
545 lines
1 <?php
2
3 /**
4 * @copyright © Melograno Ventures. All rights reserved.
5 * @licence See LICENCE.md for license details.
6 */
7
8 namespace AmeliaBooking\Infrastructure\Repository\Tax;
9
10 use AmeliaBooking\Domain\Collection\Collection;
11 use AmeliaBooking\Domain\Common\Exceptions\InvalidArgumentException;
12 use AmeliaBooking\Domain\Entity\Booking\Event\Event;
13 use AmeliaBooking\Domain\Entity\Tax\Tax;
14 use AmeliaBooking\Domain\Factory\Booking\Event\EventFactory;
15 use AmeliaBooking\Domain\Factory\Tax\TaxFactory;
16 use AmeliaBooking\Infrastructure\Common\Exceptions\NotFoundException;
17 use AmeliaBooking\Infrastructure\Connection;
18 use AmeliaBooking\Infrastructure\Common\Exceptions\QueryExecutionException;
19 use AmeliaBooking\Infrastructure\Repository\AbstractRepository;
20 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Bookable\PackagesTable;
21 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Bookable\ServicesTable;
22 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Booking\EventsTable;
23 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Tax\TaxesToEntitiesTable;
24
25 /**
26 * Class TaxRepository
27 *
28 * @package AmeliaBooking\Infrastructure\Repository\Tax
29 */
30 class TaxRepository extends AbstractRepository
31 {
32 public const FACTORY = TaxFactory::class;
33
34 /** @var string */
35 protected $taxesToEntitiesTable;
36
37 /**
38 * @param Connection $connection
39 * @param string $table
40 * @throws InvalidArgumentException
41 */
42 public function __construct(
43 Connection $connection,
44 $table
45 ) {
46 parent::__construct($connection, $table);
47
48 $this->taxesToEntitiesTable = TaxesToEntitiesTable::getTableName();
49 }
50
51 /**
52 * @param Tax $entity
53 *
54 * @return int
55 * @throws QueryExecutionException
56 */
57 public function add($entity)
58 {
59 $data = $entity->toArray();
60
61 $params = [
62 ':name' => $data['name'],
63 ':amount' => $data['amount'],
64 ':type' => $data['type'],
65 ':status' => $data['status'],
66 ':allServices' => !empty($data['allServices']) ? 1 : 0,
67 ':allEvents' => !empty($data['allEvents']) ? 1 : 0,
68 ':allPackages' => !empty($data['allPackages']) ? 1 : 0,
69 ':allExtras' => !empty($data['allExtras']) ? 1 : 0,
70 ];
71
72 try {
73 $statement = $this->connection->prepare(
74 "INSERT INTO
75 {$this->table}
76 (
77 `name`, `amount`, `type`, `status`, `allServices`, `allEvents`, `allPackages`, `allExtras`
78 ) VALUES (
79 :name, :amount, :type, :status, :allServices, :allEvents, :allPackages, :allExtras
80 )"
81 );
82
83
84 $statement->execute($params);
85 } catch (\Exception $e) {
86 throw new QueryExecutionException('Unable to add data in ' . __CLASS__ . '. ' . $e->getMessage(), $e->getCode(), $e);
87 }
88
89 return $this->connection->lastInsertId();
90 }
91
92 /**
93 * @param int $id
94 * @param Tax $entity
95 *
96 * @return bool
97 * @throws QueryExecutionException
98 */
99 public function update($id, $entity)
100 {
101 $data = $entity->toArray();
102
103 $params = [
104 ':name' => $data['name'],
105 ':amount' => $data['amount'],
106 ':type' => $data['type'],
107 ':status' => $data['status'],
108 ':allServices' => !empty($data['allServices']) ? 1 : 0,
109 ':allEvents' => !empty($data['allEvents']) ? 1 : 0,
110 ':allPackages' => !empty($data['allPackages']) ? 1 : 0,
111 ':allExtras' => !empty($data['allExtras']) ? 1 : 0,
112 ':id' => $id,
113 ];
114
115 try {
116 $statement = $this->connection->prepare(
117 "UPDATE {$this->table}
118 SET
119 `name` = :name,
120 `amount` = :amount,
121 `type` = :type,
122 `status` = :status,
123 `allServices` = :allServices,
124 `allEvents` = :allEvents,
125 `allPackages` = :allPackages,
126 `allExtras` = :allExtras
127 WHERE
128 id = :id"
129 );
130
131 $statement->execute($params);
132 } catch (\Exception $e) {
133 throw new QueryExecutionException('Unable to save data in ' . __CLASS__ . '. ' . $e->getMessage(), $e->getCode(), $e);
134 }
135
136 return true;
137 }
138
139 /**
140 * @param int $id
141 *
142 * @return Tax
143 * @throws QueryExecutionException
144 * @throws NotFoundException
145 * @throws InvalidArgumentException
146 */
147 public function getById($id)
148 {
149 try {
150 $statement = $this->connection->prepare(
151 "SELECT
152 t.id AS tax_id,
153 t.name AS tax_name,
154 t.amount AS tax_amount,
155 t.type AS tax_type,
156 t.status AS tax_status,
157 t.allServices AS tax_allServices,
158 t.allEvents AS tax_allEvents,
159 t.allPackages AS tax_allPackages,
160 t.allExtras AS tax_allExtras,
161 te.entityId AS tax_entityId,
162 te.entityType AS tax_entityType
163 FROM {$this->table} t
164 LEFT JOIN {$this->taxesToEntitiesTable} te ON te.taxId = t.id AND te.entityType != 'event'
165 WHERE t.id = :taxId"
166 );
167
168 $statement->bindParam(':taxId', $id);
169
170 $statement->execute();
171
172 $rows = $statement->fetchAll();
173 } catch (\Exception $e) {
174 throw new QueryExecutionException('Unable to find by id in ' . __CLASS__ . '. ' . $e->getMessage(), $e->getCode(), $e);
175 }
176
177 if (!$rows) {
178 throw new NotFoundException('Data not found in ' . __CLASS__);
179 }
180
181 $eventsTable = EventsTable::getTableName();
182
183 /** @var Tax $tax */
184 $tax = call_user_func([static::FACTORY, 'createCollection'], $rows)->getItem($id);
185
186 $statement = $this->connection->prepare(
187 "SELECT
188 e.id AS id,
189 e.name AS name
190 FROM {$eventsTable} e
191 INNER JOIN {$this->taxesToEntitiesTable} te ON te.entityId = e.id AND te.entityType = 'event'
192 WHERE te.taxId = :taxId"
193 );
194
195 $statement->bindParam(':taxId', $id);
196
197 $statement->execute();
198
199 $rows = $statement->fetchAll();
200
201 $tax->setEventList(new Collection());
202
203 foreach ($rows as $row) {
204 $tax->getEventList()->addItem(EventFactory::create($row));
205 }
206
207 return $tax;
208 }
209
210 /**
211 * @param array $criteria
212 *
213 * @return Collection
214 * @throws QueryExecutionException
215 * @throws InvalidArgumentException
216 */
217 public function getWithEntities($criteria)
218 {
219 $where = !empty($criteria['ids']) ? "WHERE t.id IN (" . implode(', ', $criteria['ids']) . ")" : '';
220
221 $allowedSortFields = ['id', 'name', 'type'];
222 $field = 'id';
223 $direction = 'ASC';
224 if (!empty($criteria['sort'])) {
225 $candidateField = (string)($criteria['sort']['field'] ?? '');
226 $candidateDirection = strtoupper((string)($criteria['sort']['order'] ?? 'ASC'));
227 $field = in_array($candidateField, $allowedSortFields, true) ? $candidateField : 'id';
228 $direction = $candidateDirection === 'DESC' ? 'DESC' : 'ASC';
229 }
230 $order = "ORDER BY t.`{$field}` {$direction}, t.id ASC";
231
232 try {
233 $statement = $this->connection->prepare(
234 "SELECT
235 t.id AS tax_id,
236 t.name AS tax_name,
237 t.amount AS tax_amount,
238 t.type AS tax_type,
239 t.status AS tax_status,
240 t.allServices AS tax_allServices,
241 t.allEvents AS tax_allEvents,
242 t.allPackages AS tax_allPackages,
243 t.allExtras AS tax_allExtras,
244 te.entityId AS tax_entityId,
245 te.entityType AS tax_entityType
246 FROM {$this->table} t
247 LEFT JOIN {$this->taxesToEntitiesTable} te ON te.taxId = t.id
248 {$where}
249 {$order}"
250 );
251
252 $statement->execute();
253
254 $rows = $statement->fetchAll();
255 } catch (\Exception $e) {
256 throw new QueryExecutionException('Unable to get data from ' . __CLASS__ . '. ' . $e->getMessage(), $e->getCode(), $e);
257 }
258
259 /** @var Collection $taxes */
260 $taxes = call_user_func([static::FACTORY, 'createCollection'], $rows);
261
262 $taxesIds = array_column($taxes->toArray(), 'id');
263
264 if ($taxesIds && !empty($criteria['events'])) {
265 $eventsTable = EventsTable::getTableName();
266
267 $statement = $this->connection->prepare(
268 "SELECT
269 e.id AS id,
270 e.name AS name
271 FROM {$this->taxesToEntitiesTable} te
272 INNER JOIN {$eventsTable} e ON te.entityId = e.id AND te.entityType = 'event'
273 WHERE te.taxId IN (" . implode(', ', $taxesIds) . ")"
274 );
275
276 $statement->execute();
277
278 $rows = $statement->fetchAll();
279
280 /** @var Collection $events */
281 $events = new Collection();
282
283 foreach ($rows as $row) {
284 if (!$events->keyExists($row['id'])) {
285 $events->addItem(EventFactory::create($row), $row['id']);
286 }
287 }
288
289 /** @var Tax $tax */
290 foreach ($taxes->getItems() as $tax) {
291 /** @var Tax $taxEvent */
292 foreach ($tax->getEventList()->getItems() as $taxEvent) {
293 if ($events->keyExists($taxEvent->getId()->getValue())) {
294 /** @var Event $event */
295 $event = $events->getItem($taxEvent->getId()->getValue());
296
297 $taxEvent->setName($event->getName());
298 }
299 }
300 }
301 }
302
303 return $taxes;
304 }
305
306 /**
307 * @param array $criteria
308 * @param int $itemsPerPage
309 *
310 * @return Collection
311 * @throws QueryExecutionException
312 */
313 public function getFiltered($criteria, $itemsPerPage)
314 {
315 $params = [];
316
317 $where = [];
318
319 if (!empty($criteria['search'])) {
320 $params[':search'] = "%{$criteria['search']}%";
321
322 $where[] = 'UPPER(t.name) LIKE UPPER(:search)';
323 }
324
325 if (!empty($criteria['services'])) {
326 $queryServices = [];
327
328 foreach ($criteria['services'] as $index => $value) {
329 $param = ':service' . $index;
330
331 $queryServices[] = $param;
332
333 $params[$param] = $value;
334 }
335
336 $where[] = "(t.id IN (
337 SELECT taxId FROM {$this->taxesToEntitiesTable}
338 WHERE entityId IN (" . implode(', ', $queryServices) . ") AND entityType = 'service'
339 ) OR t.allServices = 1)";
340 }
341
342 if (!empty($criteria['extras'])) {
343 $queryExtras = [];
344
345 foreach ($criteria['extras'] as $index => $value) {
346 $param = ':extra' . $index;
347
348 $queryExtras[] = $param;
349
350 $params[$param] = $value;
351 }
352
353 $where[] = "(t.id IN (
354 SELECT taxId FROM {$this->taxesToEntitiesTable}
355 WHERE entityId IN (" . implode(', ', $queryExtras) . ") AND entityType = 'extra'
356 ) OR t.allExtras = 1)";
357 }
358
359 if (!empty($criteria['events'])) {
360 $queryEvents = [];
361
362 foreach ($criteria['events'] as $index => $value) {
363 $param = ':event' . $index;
364
365 $queryEvents[] = $param;
366
367 $params[$param] = $value;
368 }
369
370 $where[] = "(t.id IN (
371 SELECT taxId FROM {$this->taxesToEntitiesTable}
372 WHERE entityId IN (" . implode(', ', $queryEvents) . ") AND entityType = 'event'
373 ) OR t.allEvents = 1)";
374 }
375
376 if (!empty($criteria['packages'])) {
377 $queryPackages = [];
378
379 foreach ((array)$criteria['packages'] as $index => $value) {
380 $param = ':package' . $index;
381
382 $queryPackages[] = $param;
383
384 $params[$param] = $value;
385 }
386
387 $where[] = "(t.id IN (
388 SELECT taxId FROM {$this->taxesToEntitiesTable}
389 WHERE entityId IN (" . implode(', ', $queryPackages) . ") AND entityType = 'package'
390 ) OR t.allPackages = 1)";
391 }
392
393
394 $where = $where ? ' WHERE ' . implode(' AND ', $where) : '';
395
396 $limit = $this->getLimit(
397 !empty($criteria['page']) ? (int)$criteria['page'] : 0,
398 (int)$itemsPerPage
399 );
400
401 $allowedSortFieldsFiltered = ['id', 'name', 'type'];
402 $filteredField = 'id';
403 $filteredDirection = 'ASC';
404 if (!empty($criteria['sort'])) {
405 $candidateField = (string)($criteria['sort']['field'] ?? '');
406 $candidateDirection = strtoupper((string)($criteria['sort']['order'] ?? 'ASC'));
407 $filteredField = in_array($candidateField, $allowedSortFieldsFiltered, true) ? $candidateField : 'id';
408 $filteredDirection = $candidateDirection === 'DESC' ? 'DESC' : 'ASC';
409 }
410 $order = "ORDER BY t.`{$filteredField}` {$filteredDirection}, t.id ASC";
411
412 try {
413 $statement = $this->connection->prepare(
414 "SELECT
415 t.id AS tax_id,
416 t.name AS tax_name,
417 t.amount AS tax_amount,
418 t.type AS tax_type,
419 t.status AS tax_status,
420 t.allServices AS tax_allServices,
421 t.allEvents AS tax_allEvents,
422 t.allPackages AS tax_allPackages,
423 t.allExtras AS tax_allExtras
424 FROM {$this->table} t
425 {$where}
426 {$order}
427 {$limit}"
428 );
429
430 $statement->execute($params);
431
432 $rows = $statement->fetchAll();
433 } catch (\Exception $e) {
434 throw new QueryExecutionException('Unable to get data from ' . __CLASS__ . '. ' . $e->getMessage(), $e->getCode(), $e);
435 }
436
437 return call_user_func([static::FACTORY, 'createCollection'], $rows);
438 }
439
440 /**
441 * @param array $criteria
442 *
443 * @return mixed
444 * @throws QueryExecutionException
445 */
446 public function getCount($criteria)
447 {
448 $params = [];
449
450 $where = [];
451
452 if (!empty($criteria['search'])) {
453 $params[':search'] = "%{$criteria['search']}%";
454
455 $where[] = 't.name LIKE :search';
456 }
457
458 if (!empty($criteria['services'])) {
459 $queryServices = [];
460
461 foreach ((array)$criteria['services'] as $index => $value) {
462 $param = ':service' . $index;
463
464 $queryServices[] = $param;
465
466 $params[$param] = $value;
467 }
468
469 $where[] = "(t.id IN (
470 SELECT taxId FROM {$this->taxesToEntitiesTable}
471 WHERE entityId IN (" . implode(', ', $queryServices) . ") AND entityType = 'service'
472 ) OR t.allServices = 1)";
473 }
474
475 if (!empty($criteria['extras'])) {
476 $queryExtras = [];
477
478 foreach ($criteria['extras'] as $index => $value) {
479 $param = ':extra' . $index;
480
481 $queryExtras[] = $param;
482
483 $params[$param] = $value;
484 }
485
486 $where[] = "(t.id IN (
487 SELECT taxId FROM {$this->taxesToEntitiesTable}
488 WHERE entityId IN (" . implode(', ', $queryExtras) . ") AND entityType = 'extra'
489 ) OR t.allExtras = 1)";
490 }
491
492 if (!empty($criteria['events'])) {
493 $queryEvents = [];
494
495 foreach ((array)$criteria['events'] as $index => $value) {
496 $param = ':event' . $index;
497
498 $queryEvents[] = $param;
499
500 $params[$param] = $value;
501 }
502
503 $where[] = "(t.id IN (
504 SELECT taxId FROM {$this->taxesToEntitiesTable}
505 WHERE entityId IN (" . implode(', ', $queryEvents) . ") AND entityType = 'event'
506 ) OR t.allEvents = 1)";
507 }
508
509 if (!empty($criteria['packages'])) {
510 $queryPackages = [];
511
512 foreach ((array)$criteria['packages'] as $index => $value) {
513 $param = ':package' . $index;
514
515 $queryPackages[] = $param;
516
517 $params[$param] = $value;
518 }
519
520 $where[] = "(t.id IN (
521 SELECT taxId FROM {$this->taxesToEntitiesTable}
522 WHERE entityId IN (" . implode(', ', $queryPackages) . ") AND entityType = 'package'
523 ) OR t.allPackages = 1)";
524 }
525
526 $where = $where ? ' WHERE ' . implode(' AND ', $where) : '';
527
528 try {
529 $statement = $this->connection->prepare(
530 "SELECT COUNT(*) AS count
531 FROM {$this->table} t
532 {$where}"
533 );
534
535 $statement->execute($params);
536
537 $row = $statement->fetch()['count'];
538 } catch (\Exception $e) {
539 throw new QueryExecutionException('Unable to get data from ' . __CLASS__ . '. ' . $e->getMessage(), $e->getCode(), $e);
540 }
541
542 return $row;
543 }
544 }
545