PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 2.1.3
Booking for Appointments and Events Calendar – Amelia v2.1.3
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 / PackageCustomerServiceRepository.php
ameliabooking / src / Infrastructure / Repository / Bookable / Service Last commit date
CategoryRepository.php 5 months ago ExtraRepository.php 5 months ago PackageCustomerRepository.php 5 months ago PackageCustomerServiceRepository.php 5 months ago PackageRepository.php 5 months ago PackageServiceLocationRepository.php 5 months ago PackageServiceProviderRepository.php 5 months ago PackageServiceRepository.php 5 months ago ProviderServiceRepository.php 5 months ago ResourceEntitiesRepository.php 5 months ago ResourceRepository.php 5 months ago ServiceRepository.php 5 months ago
PackageCustomerServiceRepository.php
333 lines
1 <?php
2
3 namespace AmeliaBooking\Infrastructure\Repository\Bookable\Service;
4
5 use AmeliaBooking\Domain\Collection\Collection;
6 use AmeliaBooking\Domain\Common\Exceptions\InvalidArgumentException;
7 use AmeliaBooking\Domain\Entity\Bookable\Service\PackageCustomerService;
8 use AmeliaBooking\Domain\Factory\Bookable\Service\PackageCustomerServiceFactory;
9 use AmeliaBooking\Domain\Services\DateTime\DateTimeService;
10 use AmeliaBooking\Infrastructure\Common\Exceptions\QueryExecutionException;
11 use AmeliaBooking\Infrastructure\Connection;
12 use AmeliaBooking\Infrastructure\Repository\AbstractRepository;
13 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Bookable\PackagesCustomersTable;
14 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Bookable\PackagesTable;
15 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Booking\CustomerBookingsTable;
16 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Payment\PaymentsTable;
17 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\User\UsersTable;
18
19 /**
20 * Class PackageCustomerServiceRepository
21 *
22 * @package AmeliaBooking\Infrastructure\Repository\Bookable\Service
23 */
24 class PackageCustomerServiceRepository extends AbstractRepository
25 {
26 public const FACTORY = PackageCustomerServiceFactory::class;
27
28 /** @var string */
29 protected $packagesCustomersTable;
30
31 /** @var string */
32 protected $paymentsTable;
33
34 /**
35 * @param Connection $connection
36 * @param string $table
37 *
38 * @throws InvalidArgumentException
39 */
40 public function __construct(
41 Connection $connection,
42 $table
43 ) {
44 parent::__construct($connection, $table);
45
46 $this->packagesCustomersTable = PackagesCustomersTable::getTableName();
47
48 $this->paymentsTable = PaymentsTable::getTableName();
49 }
50
51 /**
52 * @param PackageCustomerService $entity
53 *
54 * @return int
55 * @throws QueryExecutionException
56 */
57 public function add($entity)
58 {
59 $data = $entity->toArray();
60
61 $params = [
62 ':packageCustomerId' => $data['packageCustomer']['id'],
63 ':serviceId' => $data['serviceId'],
64 ':providerId' => $data['providerId'],
65 ':locationId' => $data['locationId'],
66 ':bookingsCount' => $data['bookingsCount'],
67 ];
68
69 try {
70 $statement = $this->connection->prepare(
71 "INSERT INTO {$this->table}
72 (`packageCustomerId`, `serviceId`, `providerId`, `locationId`, `bookingsCount`)
73 VALUES
74 (:packageCustomerId, :serviceId, :providerId, :locationId, :bookingsCount)"
75 );
76
77 $statement->execute($params);
78 } catch (\Exception $e) {
79 throw new QueryExecutionException('Unable to add data in ' . __CLASS__ . '. ' . $e->getMessage(), $e->getCode(), $e);
80 }
81
82 return $this->connection->lastInsertId();
83 }
84
85 /**
86 * @param array $criteria
87 * @param bool $empty
88 * @return Collection
89 * @throws InvalidArgumentException
90 * @throws QueryExecutionException
91 */
92 public function getByCriteria($criteria, $empty = false)
93 {
94 $bookingsTable = CustomerBookingsTable::getTableName();
95 $packagesTable = PackagesTable::getTableName();
96
97 $params = [];
98
99 $where = [];
100
101 if (!empty($criteria['ids'])) {
102 $queryIds = [];
103
104 foreach ($criteria['ids'] as $index => $value) {
105 $param = ':id' . $index;
106
107 $queryIds[] = $param;
108
109 $params[$param] = $value;
110 }
111
112 $where[] = 'pcs.id IN (' . implode(', ', $queryIds) . ')';
113 }
114
115 if (!empty($criteria['packageCustomerIds'])) {
116 $queryIds = [];
117
118 foreach ($criteria['packageCustomerIds'] as $index => $value) {
119 $param = ':id' . $index;
120
121 $queryIds[] = $param;
122
123 $params[$param] = $value;
124 }
125
126 $where[] = 'pc.id IN (' . implode(', ', $queryIds) . ')';
127 }
128
129 if (!empty($criteria['purchased'])) {
130 $where[] = "(pc.purchased BETWEEN :purchasedFrom AND :purchasedTo)";
131
132 $params[':purchasedFrom'] = DateTimeService::getCustomDateTimeInUtc($criteria['purchased'][0]);
133
134 $params[':purchasedTo'] = DateTimeService::getCustomDateTimeInUtc($criteria['purchased'][1]);
135 }
136
137 if (!empty($criteria['dates'])) {
138 $where[] = "((:from1 >= pc.start AND :from2 <= pc.end) OR (:from3 <= pc.start AND :to1 >= pc.start)) ";
139
140 $params[':from1'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
141 $params[':from2'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
142 $params[':from3'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
143
144 $params[':to1'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][1]);
145 }
146
147 if (!empty($criteria['customers'])) {
148 $queryCustomers = [];
149
150 foreach ($criteria['customers'] as $index => $value) {
151 $param = ':customer' . $index;
152
153 $queryCustomers[] = $param;
154
155 $params[$param] = $value;
156 }
157
158 $where[] = 'cu.id IN (' . implode(', ', $queryCustomers) . ')';
159 }
160
161 if (!empty($criteria['status'])) {
162 $queryStatus = [];
163
164 foreach ($criteria['status'] as $index => $value) {
165 $param = ':status' . $index;
166
167 $queryStatus[] = $param;
168
169 $params[$param] = $value;
170 }
171
172 $where[] = 'pc.status IN (' . implode(', ', $queryStatus) . ')';
173 }
174
175 if (!empty($criteria['services'])) {
176 $queryServices = [];
177
178 foreach ($criteria['services'] as $index => $value) {
179 $param = ':service' . $index;
180
181 $queryServices[] = $param;
182
183 $params[$param] = $value;
184 }
185
186 $where[] = 'pcs.serviceId IN (' . implode(', ', $queryServices) . ')';
187 }
188
189 if (!empty($criteria['packages'])) {
190 $queryServices = [];
191
192 foreach ($criteria['packages'] as $index => $value) {
193 $param = ':package' . $index;
194
195 $queryServices[] = $param;
196
197 $params[$param] = $value;
198 }
199
200 $where[] = 'pc.packageId IN (' . implode(', ', $queryServices) . ')';
201 }
202
203 if (!empty($criteria['packagesCustomers'])) {
204 $queryServices = [];
205
206 foreach ($criteria['packagesCustomers'] as $index => $value) {
207 $param = ':packageCustomerId' . $index;
208
209 $queryServices[] = $param;
210
211 $params[$param] = $value;
212 }
213
214 $where[] = 'pc.id IN (' . implode(', ', $queryServices) . ')';
215 }
216
217 if ($empty) {
218 $where[] = 'pcs.id NOT IN (SELECT packageCustomerServiceId FROM ' . $bookingsTable . ' WHERE packageCustomerServiceId IS NOT NULL)';
219 }
220
221 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
222
223 $usersTable = UsersTable::getTableName();
224
225 try {
226 $statement = $this->connection->prepare(
227 "SELECT
228 pc.id AS package_customer_id,
229 pc.packageId AS package_customer_packageId,
230 pc.customerId AS package_customer_customerId,
231 pc.tax AS package_customer_tax,
232 pc.price AS package_customer_price,
233 pc.end AS package_customer_end,
234 pc.start AS package_customer_start,
235 pc.purchased AS package_customer_purchased,
236 pc.status AS package_customer_status,
237 pc.bookingsCount AS package_customer_bookingsCount,
238 pc.couponId AS package_customer_couponId,
239
240 pa.name as package_name,
241
242 pcs.id AS package_customer_service_id,
243 pcs.serviceId AS package_customer_service_serviceId,
244 pcs.providerId AS package_customer_service_providerId,
245 pcs.locationId AS package_customer_service_locationId,
246 pcs.bookingsCount AS package_customer_service_bookingsCount,
247
248 p.id AS payment_id,
249 p.packageCustomerId AS payment_packageCustomerId,
250 p.amount AS payment_amount,
251 p.dateTime AS payment_dateTime,
252 p.status AS payment_status,
253 p.gateway AS payment_gateway,
254 p.gatewayTitle AS payment_gatewayTitle,
255 p.transactionId AS payment_transactionId,
256 p.data AS payment_data,
257 p.wcOrderId AS payment_wcOrderId,
258 p.wcOrderItemId AS payment_wcOrderItemId,
259 p.invoiceNumber AS payment_invoiceNumber,
260 p.created AS payment_created,
261
262 cu.firstName AS customer_firstName,
263 cu.lastName AS customer_lastName,
264 cu.email AS customer_email,
265 cu.phone AS customer_phone,
266 cu.status AS customer_status
267 FROM {$this->table} pcs
268 INNER JOIN {$this->packagesCustomersTable} pc ON pcs.packageCustomerId = pc.id
269 INNER JOIN {$packagesTable} pa ON pa.id = pc.packageId
270 INNER JOIN {$usersTable} cu ON cu.id = pc.customerId
271 LEFT JOIN {$this->paymentsTable} p ON p.packageCustomerId = pc.id
272 {$where}"
273 );
274
275 $statement->execute($params);
276
277 $rows = $statement->fetchAll();
278 } catch (\Exception $e) {
279 throw new QueryExecutionException('Unable to find by id in ' . __CLASS__ . '. ' . $e->getMessage(), $e->getCode(), $e);
280 }
281
282 return call_user_func([static::FACTORY, 'createCollection'], $rows);
283 }
284
285 /**
286 * Get available service IDs for a package customer
287 *
288 * @param int $packageCustomerId
289 * @return array
290 * @throws QueryExecutionException
291 */
292 public function getAvailableServiceIds($packageCustomerId)
293 {
294 $bookingsTable = CustomerBookingsTable::getTableName();
295
296 $packagesCustomersTable = PackagesCustomersTable::getTableName();
297
298 try {
299 $statement = $this->connection->prepare(
300 "SELECT
301 pcs.id,
302 pcs.serviceId
303 FROM {$packagesCustomersTable} pc
304 INNER JOIN {$this->table} pcs ON pc.id = pcs.packageCustomerId
305 LEFT JOIN (
306 SELECT packageCustomerServiceId, COUNT(*) as booking_count
307 FROM {$bookingsTable}
308 WHERE status IN ('approved', 'pending')
309 GROUP BY packageCustomerServiceId
310 ) cb ON cb.packageCustomerServiceId = pcs.id
311 WHERE pc.id = :packageCustomerId AND (
312 (pc.bookingsCount = 0 AND (cb.booking_count IS NULL OR cb.booking_count < pcs.bookingsCount)) OR
313 (pc.bookingsCount != 0 AND (cb.booking_count IS NULL OR cb.booking_count < pc.bookingsCount))
314 )
315 GROUP BY pcs.id, pcs.serviceId"
316 );
317
318 $params = [
319 ':packageCustomerId' => $packageCustomerId
320 ];
321
322 $statement->execute($params);
323
324 $results = $statement->fetchAll();
325
326 // Convert results to associative array with id as key and serviceId as value
327 return array_column($results, 'serviceId', 'id');
328 } catch (\Exception $e) {
329 throw new QueryExecutionException('Unable to get available service ids in ' . __CLASS__ . '. ' . $e->getMessage(), $e->getCode(), $e);
330 }
331 }
332 }
333