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