PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 1.2.31
Booking for Appointments and Events Calendar – Amelia v1.2.31
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 / Bookable / Service / PackageCustomerRepository.php
ameliabooking / src / Infrastructure / Repository / Bookable / Service Last commit date
CategoryRepository.php 1 year ago ExtraRepository.php 1 year ago PackageCustomerRepository.php 1 year ago PackageCustomerServiceRepository.php 1 year ago PackageRepository.php 1 year ago PackageServiceLocationRepository.php 1 year ago PackageServiceProviderRepository.php 1 year ago PackageServiceRepository.php 1 year ago ProviderServiceRepository.php 1 year ago ResourceEntitiesRepository.php 1 year ago ResourceRepository.php 1 year ago ServiceRepository.php 1 year ago
PackageCustomerRepository.php
389 lines
1 <?php
2
3 namespace AmeliaBooking\Infrastructure\Repository\Bookable\Service;
4
5 use AmeliaBooking\Domain\Collection\Collection;
6 use AmeliaBooking\Domain\Entity\Bookable\Service\Package;
7 use AmeliaBooking\Domain\Entity\Bookable\Service\PackageCustomer;
8 use AmeliaBooking\Domain\Factory\Bookable\Service\PackageCustomerFactory;
9 use AmeliaBooking\Domain\Services\DateTime\DateTimeService;
10 use AmeliaBooking\Infrastructure\Common\Exceptions\QueryExecutionException;
11 use AmeliaBooking\Infrastructure\Repository\AbstractRepository;
12 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Bookable\PackagesCustomersServicesTable;
13 use AmeliaBooking\Infrastructure\Connection;
14 use AmeliaBooking\Domain\Common\Exceptions\InvalidArgumentException;
15 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Booking\CustomerBookingsTable;
16
17 /**
18 * Class PackageCustomerRepository
19 *
20 * @package AmeliaBooking\Infrastructure\Repository\Bookable\Service
21 */
22 class PackageCustomerRepository extends AbstractRepository
23 {
24 public const FACTORY = PackageCustomerFactory::class;
25
26 /** @var string */
27 protected $packagesCustomersServicesTable;
28
29 /**
30 * @param Connection $connection
31 * @param string $table
32 *
33 * @throws InvalidArgumentException
34 */
35 public function __construct(
36 Connection $connection,
37 $table
38 ) {
39 parent::__construct($connection, $table);
40
41 $this->packagesCustomersServicesTable = PackagesCustomersServicesTable::getTableName();
42 }
43
44 /**
45 * @param PackageCustomer $entity
46 *
47 * @return int
48 * @throws QueryExecutionException
49 */
50 public function add($entity)
51 {
52 $data = $entity->toArray();
53
54 $params = [
55 ':packageId' => $data['packageId'],
56 ':customerId' => $data['customerId'],
57 ':price' => $data['price'],
58 ':tax' => !empty($data['tax']) ? json_encode($data['tax']) : null,
59 ':start' => $data['start'],
60 ':end' => $data['end'],
61 ':purchased' => $data['purchased'],
62 ':bookingsCount' => $data['bookingsCount'],
63 ':couponId' => $data['couponId'],
64 ];
65
66 try {
67 $statement = $this->connection->prepare(
68 "INSERT INTO {$this->table}
69 (`packageId`, `customerId`, `price`, `tax`, `start`, `end`, `purchased`, `status`, `bookingsCount`, `couponId`)
70 VALUES
71 (:packageId, :customerId, :price, :tax, :start, :end, :purchased, 'approved', :bookingsCount, :couponId)"
72 );
73
74 $res = $statement->execute($params);
75
76 if (!$res) {
77 throw new QueryExecutionException('Unable to add data in ' . __CLASS__);
78 }
79 } catch (\Exception $e) {
80 throw new QueryExecutionException('Unable to add data in ' . __CLASS__, $e->getCode(), $e);
81 }
82
83 return $this->connection->lastInsertId();
84 }
85
86
87 /**
88 * @param Package $package
89 * @param int $customerId
90 * @param array $limitPerCustomer
91 * @param boolean $packageSpecific
92 * @return int
93 * @throws QueryExecutionException
94 */
95 public function getUserPackageCount($package, $customerId, $limitPerCustomer, $packageSpecific)
96 {
97 $params = [
98 ':customerId' => $customerId
99 ];
100
101 $startDate = DateTimeService::getNowDateTimeObject()->setTimezone(new \DateTimeZone('UTC'))->format('Y-m-d H:i');
102
103 $intervalString = "interval " . $limitPerCustomer['period'] . " " . $limitPerCustomer['timeFrame'];
104
105 $where = "(STR_TO_DATE('" . $startDate . "', '%Y-%m-%d %H:%i:%s') BETWEEN " .
106 "(pc.purchased - " . $intervalString . " + interval 1 second) AND " .
107 "(pc.purchased + " . $intervalString . " - interval 1 second))"; //+ interval 2 day
108
109 if ($packageSpecific) {
110 $where .= " AND pc.packageId = :packageId";
111 $params[':packageId'] = $package->getId()->getValue();
112 }
113
114 try {
115 $statement = $this->connection->prepare(
116 "SELECT COUNT(DISTINCT pc.id) AS count
117 FROM {$this->table} pc
118 WHERE pc.customerId = :customerId AND {$where} AND pc.status = 'approved'
119 "
120 );
121
122 $statement->execute($params);
123
124 $rows = $statement->fetch()['count'];
125 } catch (\Exception $e) {
126 throw new QueryExecutionException('Unable to find by id in ' . __CLASS__, $e->getCode(), $e);
127 }
128
129 return $rows;
130 }
131
132 /**
133 * @param array $criteria
134 *
135 * @return Collection
136 * @throws QueryExecutionException
137 * @throws InvalidArgumentException
138 */
139 public function getFiltered($criteria)
140 {
141 $params = [];
142
143 $where = [];
144
145 if (!empty($criteria['customerId'])) {
146 $params[':customerId'] = $criteria['customerId'];
147
148 $where[] = 'pc.customerId = :customerId';
149 }
150
151 if (array_key_exists('bookingStatus', $criteria)) {
152 $where[] = 'pc.status = :bookingStatus';
153 $params[':bookingStatus'] = $criteria['bookingStatus'];
154 }
155
156 if (!empty($criteria['packages'])) {
157 $queryPackages = [];
158
159 foreach ($criteria['packages'] as $index => $value) {
160 $param = ':package' . $index;
161
162 $queryPackages[] = $param;
163
164 $params[$param] = $value;
165 }
166
167 $where[] = 'pc.packageId IN (' . implode(', ', $queryPackages) . ')';
168 }
169
170 if (isset($criteria['couponId'])) {
171 $where[] = "pc.couponId = {$criteria['couponId']}";
172 }
173
174 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
175
176 try {
177 $statement = $this->connection->prepare(
178 "SELECT
179 pc.id AS id
180 FROM {$this->table} pc
181 {$where}"
182 );
183
184 $statement->execute($params);
185
186 $rows = $statement->fetchAll();
187 } catch (\Exception $e) {
188 throw new QueryExecutionException('Unable to find by id in ' . __CLASS__, $e->getCode(), $e);
189 }
190
191 $entities = new Collection();
192
193 foreach ($rows as $row) {
194 $entities->addItem(
195 call_user_func([static::FACTORY, 'create'], $row),
196 $row['id']
197 );
198 }
199
200 return $entities;
201 }
202
203 /**
204 * @return array
205 * @throws QueryExecutionException
206 */
207 public function getIds($criteria = [])
208 {
209 $bookingsTable = CustomerBookingsTable::getTableName();
210
211 $where = [];
212
213 $params = [];
214
215 if (!empty($criteria['purchased'])) {
216 $where[] = "(pc.purchased BETWEEN :purchasedFrom AND :purchasedTo)";
217
218 $params[':purchasedFrom'] = DateTimeService::getCustomDateTimeInUtc($criteria['purchased'][0]);
219
220 $params[':purchasedTo'] = DateTimeService::getCustomDateTimeInUtc($criteria['purchased'][1]);
221 }
222
223 if (!empty($criteria['packages'])) {
224 $queryServices = [];
225
226 foreach ($criteria['packages'] as $index => $value) {
227 $param = ':package' . $index;
228
229 $queryServices[] = $param;
230
231 $params[$param] = $value;
232 }
233
234 $where[] = 'pc.packageId IN (' . implode(', ', $queryServices) . ')';
235 }
236
237 if (!empty($criteria['packageStatus'])) {
238 switch ($criteria['packageStatus']) {
239 case 'expired':
240 $where[] = "(pc.end IS NOT NULL && pc.end < NOW())";
241 break;
242 case 'approved':
243 $where[] = "(pc.end > NOW() OR pc.end IS NULL)";
244 $where[] = "(pc.status = :packageStatus)";
245 $params[':packageStatus'] = $criteria['packageStatus'];
246 break;
247 case 'canceled':
248 $where[] = "(pc.status = :packageStatus)";
249 $params[':packageStatus'] = $criteria['packageStatus'];
250 break;
251 default:
252 break;
253 }
254 }
255
256 if (!empty($criteria['customerId'])) {
257 $params[':customerId'] = $criteria['customerId'];
258
259 $where[] = 'pc.customerId = :customerId';
260 }
261
262 $limit = $this->getLimit(
263 !empty($criteria['page']) ? (int)$criteria['page'] : 0,
264 !empty($criteria['itemsPerPage']) ? (int)$criteria['itemsPerPage'] : 0
265 );
266
267 $where = $where ? ' WHERE ' . implode(' AND ', $where) : '';
268
269 try {
270 $statement = $this->connection->prepare(
271 "SELECT
272 pc.id AS id,
273 pc.packageId AS package_customer_packageId,
274 pc.purchased AS package_customer_purchased,
275 pc.end AS package_customer_end,
276 pc.status AS package_customer_status,
277 pc.customerId AS package_customer_customerId,
278 pc.bookingsCount AS package_customer_bookingsCount,
279
280 pcs.id AS package_customer_service_id,
281 pcs.packageCustomerId AS package_customer_customerId,
282 pcs.bookingsCount AS service_bookingsCount
283 FROM {$this->table} pc
284 INNER JOIN {$this->packagesCustomersServicesTable} AS pcs ON pc.id = pcs.packageCustomerId
285 LEFT JOIN $bookingsTable cb ON pcs.id = cb.packageCustomerServiceId
286 {$where}
287 GROUP BY pc.id
288 {$limit}"
289 );
290
291 $statement->execute($params);
292
293 $rows = $statement->fetchAll();
294 } catch (\Exception $e) {
295 throw new QueryExecutionException('Unable to get data from ' . __CLASS__, $e->getCode(), $e);
296 }
297
298 return array_map('intval', array_column($rows, 'id'));
299 }
300
301 /**
302 * @param array $criteria
303 * @return int
304 * @throws QueryExecutionException
305 */
306 public function getPackagePurchasedCount($criteria = [])
307 {
308 $params = [];
309
310 $where = [];
311
312 if (!empty($criteria['purchased'])) {
313 $where[] = "(pc.purchased BETWEEN :purchasedFrom AND :purchasedTo)";
314
315 $params[':purchasedFrom'] = DateTimeService::getCustomDateTimeInUtc($criteria['purchased'][0]);
316
317 $params[':purchasedTo'] = DateTimeService::getCustomDateTimeInUtc($criteria['purchased'][1]);
318 }
319
320 if (!empty($criteria['customerId'])) {
321 $params[':customerId'] = $criteria['customerId'];
322
323 $where[] = 'pc.customerId = :customerId';
324 }
325
326 if (!empty($criteria['packages'])) {
327 $queryServices = [];
328
329 foreach ($criteria['packages'] as $index => $value) {
330 $param = ':package' . $index;
331
332 $queryServices[] = $param;
333
334 $params[$param] = $value;
335 }
336
337 $where[] = 'pc.packageId IN (' . implode(', ', $queryServices) . ')';
338 }
339
340 if (!empty($criteria['packageStatus'])) {
341 switch ($criteria['packageStatus']) {
342 case 'expired':
343 $where[] = "(pc.end IS NOT NULL && pc.end < NOW())";
344 break;
345 case 'approved':
346 $where[] = "(pc.end > NOW() OR pc.end IS NULL)";
347 $where[] = "(pc.status = :packageStatus)";
348 $params[':packageStatus'] = $criteria['packageStatus'];
349 break;
350 case 'canceled':
351 $where[] = "(pc.status = :packageStatus)";
352 $params[':packageStatus'] = $criteria['packageStatus'];
353 break;
354 default:
355 break;
356 }
357 }
358
359 $where = $where ? ' WHERE ' . implode(' AND ', $where) : '';
360
361 try {
362 $statement = $this->connection->prepare(
363 "SELECT
364 pc.id AS id,
365 pc.packageId AS package_customer_packageId,
366 pc.purchased AS package_customer_purchased,
367 pc.end AS package_customer_end,
368 pc.status AS package_customer_status,
369 pc.customerId AS package_customer_customerId,
370 COUNT(DISTINCT pc.id) AS count,
371
372 pcs.id AS package_customer_service_id,
373 pcs.packageCustomerId AS package_customer_customerId
374 FROM {$this->table} pc
375 INNER JOIN {$this->packagesCustomersServicesTable} AS pcs ON pc.id = pcs.packageCustomerId
376 {$where}"
377 );
378
379 $statement->execute($params);
380
381 $rows = $statement->fetch()['count'];
382 } catch (\Exception $e) {
383 throw new QueryExecutionException('Unable to find by id in ' . __CLASS__, $e->getCode(), $e);
384 }
385
386 return $rows;
387 }
388 }
389