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