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 / Bookable / Service / PackageCustomerServiceRepository.php
ameliabooking / src / Infrastructure / Repository / Bookable / Service Last commit date
CategoryRepository.php 3 months ago ExtraRepository.php 3 months ago PackageCustomerRepository.php 1 month ago PackageCustomerServiceRepository.php 2 weeks ago PackageRepository.php 2 months ago PackageServiceLocationRepository.php 3 months ago PackageServiceProviderRepository.php 3 months ago PackageServiceRepository.php 3 months ago ProviderServiceRepository.php 3 months ago ResourceEntitiesRepository.php 3 months ago ResourceRepository.php 3 months ago ServiceRepository.php 2 weeks ago
PackageCustomerServiceRepository.php
335 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 pc.ivyEntryId AS package_customer_ivyEntryId,
240
241 pa.name as package_name,
242
243 pcs.id AS package_customer_service_id,
244 pcs.serviceId AS package_customer_service_serviceId,
245 pcs.providerId AS package_customer_service_providerId,
246 pcs.locationId AS package_customer_service_locationId,
247 pcs.bookingsCount AS package_customer_service_bookingsCount,
248
249 p.id AS payment_id,
250 p.packageCustomerId AS payment_packageCustomerId,
251 p.amount AS payment_amount,
252 p.dateTime AS payment_dateTime,
253 p.status AS payment_status,
254 p.gateway AS payment_gateway,
255 p.gatewayTitle AS payment_gatewayTitle,
256 p.transactionId AS payment_transactionId,
257 p.data AS payment_data,
258 p.wcOrderId AS payment_wcOrderId,
259 p.wcOrderItemId AS payment_wcOrderItemId,
260 p.invoiceNumber AS payment_invoiceNumber,
261 p.created AS payment_created,
262
263 cu.firstName AS customer_firstName,
264 cu.lastName AS customer_lastName,
265 cu.email AS customer_email,
266 cu.phone AS customer_phone,
267 cu.countryPhoneIso AS customer_countryPhoneIso,
268 cu.status AS customer_status
269 FROM {$this->table} pcs
270 INNER JOIN {$this->packagesCustomersTable} pc ON pcs.packageCustomerId = pc.id
271 INNER JOIN {$packagesTable} pa ON pa.id = pc.packageId
272 INNER JOIN {$usersTable} cu ON cu.id = pc.customerId
273 LEFT JOIN {$this->paymentsTable} p ON p.packageCustomerId = pc.id
274 {$where}"
275 );
276
277 $statement->execute($params);
278
279 $rows = $statement->fetchAll();
280 } catch (\Exception $e) {
281 throw new QueryExecutionException('Unable to find by id in ' . __CLASS__ . '. ' . $e->getMessage(), $e->getCode(), $e);
282 }
283
284 return call_user_func([static::FACTORY, 'createCollection'], $rows);
285 }
286
287 /**
288 * Get available service IDs for a package customer
289 *
290 * @param int $packageCustomerId
291 * @return array
292 * @throws QueryExecutionException
293 */
294 public function getAvailableServiceIds($packageCustomerId)
295 {
296 $bookingsTable = CustomerBookingsTable::getTableName();
297
298 $packagesCustomersTable = PackagesCustomersTable::getTableName();
299
300 try {
301 $statement = $this->connection->prepare(
302 "SELECT
303 pcs.id,
304 pcs.serviceId
305 FROM {$packagesCustomersTable} pc
306 INNER JOIN {$this->table} pcs ON pc.id = pcs.packageCustomerId
307 LEFT JOIN (
308 SELECT packageCustomerServiceId, COUNT(*) as booking_count
309 FROM {$bookingsTable}
310 WHERE status IN ('approved', 'pending')
311 GROUP BY packageCustomerServiceId
312 ) cb ON cb.packageCustomerServiceId = pcs.id
313 WHERE pc.id = :packageCustomerId AND (
314 (pc.bookingsCount = 0 AND (cb.booking_count IS NULL OR cb.booking_count < pcs.bookingsCount)) OR
315 (pc.bookingsCount != 0 AND (cb.booking_count IS NULL OR cb.booking_count < pc.bookingsCount))
316 )
317 GROUP BY pcs.id, pcs.serviceId"
318 );
319
320 $params = [
321 ':packageCustomerId' => $packageCustomerId
322 ];
323
324 $statement->execute($params);
325
326 $results = $statement->fetchAll();
327
328 // Convert results to associative array with id as key and serviceId as value
329 return array_column($results, 'serviceId', 'id');
330 } catch (\Exception $e) {
331 throw new QueryExecutionException('Unable to get available service ids in ' . __CLASS__ . '. ' . $e->getMessage(), $e->getCode(), $e);
332 }
333 }
334 }
335