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 / User / CustomerRepository.php
ameliabooking / src / Infrastructure / Repository / User Last commit date
CustomerRepository.php 1 year ago ProviderRepository.php 1 year ago UserRepository.php 1 year ago WPUserRepository.php 4 years ago
CustomerRepository.php
348 lines
1 <?php
2
3 namespace AmeliaBooking\Infrastructure\Repository\User;
4
5 use AmeliaBooking\Domain\Collection\Collection;
6 use AmeliaBooking\Domain\Common\Exceptions\InvalidArgumentException;
7 use AmeliaBooking\Domain\Entity\User\AbstractUser;
8 use AmeliaBooking\Domain\Repository\User\CustomerRepositoryInterface;
9 use AmeliaBooking\Domain\Services\DateTime\DateTimeService;
10 use AmeliaBooking\Domain\ValueObjects\String\BookingStatus;
11 use AmeliaBooking\Domain\ValueObjects\String\Status;
12 use AmeliaBooking\Infrastructure\Common\Exceptions\QueryExecutionException;
13 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Booking\AppointmentsTable;
14 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Booking\CustomerBookingsTable;
15 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\User\WPUsersTable;
16
17 /**
18 * Class UserRepository
19 *
20 * @package AmeliaBooking\Infrastructure\Repository
21 */
22 class CustomerRepository extends UserRepository implements CustomerRepositoryInterface
23 {
24 /**
25 * @param $criteria
26 * @param int $itemsPerPage
27 *
28 * @return array
29 * @throws QueryExecutionException
30 * @throws \Exception
31 */
32 public function getFiltered($criteria, $itemsPerPage = null)
33 {
34 try {
35 $wpUserTable = WPUsersTable::getTableName();
36 $bookingsTable = CustomerBookingsTable::getTableName();
37 $appointmentsTable = AppointmentsTable::getTableName();
38
39 $params = [
40 ':type_customer' => AbstractUser::USER_ROLE_CUSTOMER,
41 ':type_admin' => AbstractUser::USER_ROLE_ADMIN,
42 ];
43
44 $joinWithBookings = empty($criteria['ignoredBookings']);
45
46 $where = [
47 'u.type IN (:type_customer, :type_admin)',
48 ];
49
50 $order = '';
51 if (!empty($criteria['sort'])) {
52 $column = $criteria['sort'][0] === '-' ? substr($criteria['sort'], 1) : $criteria['sort'];
53 $orderColumn = $column === 'customer' ? 'CONCAT(u.firstName, " ", u.lastName)' : 'lastAppointment';
54 $orderDirection = $criteria['sort'][0] === '-' ? 'DESC' : 'ASC';
55 $order = "ORDER BY {$orderColumn} {$orderDirection}";
56
57 $joinWithBookings = $column !== 'customer' || $joinWithBookings;
58 }
59
60 if (!empty($criteria['search'])) {
61 $params[':search1'] = $params[':search2'] = $params[':search3'] = $params[':search4'] = $params[':search5'] =
62 "%{$criteria['search']}%";
63
64 $where[] = "((CONCAT(u.firstName, ' ', u.lastName) LIKE :search1
65 OR wpu.display_name LIKE :search2
66 OR u.email LIKE :search3
67 OR u.phone LIKE :search4
68 OR u.note LIKE :search5))";
69 }
70
71 if (!empty($criteria['customers'])) {
72 $customersCriteria = [];
73
74 foreach ((array)$criteria['customers'] as $key => $customerId) {
75 $params[":customerId$key"] = $customerId;
76 $customersCriteria[] = ":customerId$key";
77 }
78
79 $where[] = 'u.id IN (' . implode(', ', $customersCriteria) . ')';
80 }
81
82 $statsFields = '
83 NULL as lastAppointment,
84 0 as totalAppointments,
85 0 as countPendingAppointments,
86 0 as countAppointmentBookings,
87 0 as countEventBookings,
88 ';
89
90 $statsJoins = '';
91
92 $having = '';
93
94 if ($joinWithBookings) {
95 $params[':bookingPendingStatus'] = BookingStatus::PENDING;
96
97 $statsFields = "
98 MAX(app.bookingStart) as lastAppointment,
99 COUNT(cb.id) as totalAppointments,
100 SUM(case when cb.status = :bookingPendingStatus then 1 else 0 end) as countPendingAppointments,
101 COUNT(DISTINCT CASE WHEN cb.appointmentId IS NOT NULL THEN cb.id ELSE NULL END) as countAppointmentBookings,
102 COUNT(DISTINCT CASE WHEN cb.appointmentId IS NULL THEN cb.id ELSE NULL END) as countEventBookings,
103 ";
104
105 $statsJoins = "
106 LEFT JOIN {$bookingsTable} cb ON u.id = cb.customerId
107 LEFT JOIN {$appointmentsTable} app ON app.id = cb.appointmentId
108 ";
109
110 if (!empty($criteria['noShow'])) {
111 $having = "HAVING (SUM(case when cb.status = 'no-show' then 1 else 0 end)) " . ($criteria['noShow'] === "3" ? '>=' : '=') . ":noShow";
112
113 $params[':noShow'] = $criteria['noShow'];
114 }
115 }
116
117 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
118
119 $limit = $this->getLimit(
120 !empty($criteria['page']) ? (int)$criteria['page'] : 0,
121 (int)$itemsPerPage
122 );
123
124 $statement = $this->connection->prepare(
125 "SELECT
126 u.id as id,
127 u.status as status,
128 u.firstName as firstName,
129 u.lastName as lastName,
130 u.email as email,
131 u.phone as phone,
132 u.countryPhoneIso AS countryPhoneIso,
133 u.gender as gender,
134 u.externalId as externalId,
135 u.translations as translations,
136 IF(u.birthday IS NOT NULL, u.birthday , '') as birthday,
137 u.note as note,
138 {$statsFields}
139 IF(wpu.display_name IS NOT NULL, wpu.display_name , '') as wpName
140 FROM {$this->table} as u
141 LEFT JOIN {$wpUserTable} wpu ON u.externalId = wpu.id
142 {$statsJoins}
143 {$where}
144 GROUP BY u.id
145 {$having}
146 {$order}
147 {$limit}"
148 );
149
150 $statement->execute($params);
151
152 $rows = $statement->fetchAll();
153 } catch (\Exception $e) {
154 throw new QueryExecutionException('Unable to get data from ' . __CLASS__, $e->getCode(), $e);
155 }
156
157 $items = [];
158 foreach ($rows as $row) {
159 $row['id'] = (int)$row['id'];
160 $row['externalId'] = $row['externalId'] === null ? $row['externalId'] : (int)$row['externalId'];
161 $row['lastAppointment'] = $row['lastAppointment'] ?
162 DateTimeService::getCustomDateTimeFromUtc($row['lastAppointment']) : $row['lastAppointment'];
163 $items[(int)$row['id']] = $row;
164 }
165
166 return $items;
167 }
168
169 /**
170 * @param $criteria
171 *
172 * @return mixed
173 * @throws QueryExecutionException
174 */
175 public function getCount($criteria)
176 {
177 $wpUserTable = WPUsersTable::getTableName();
178
179 $params = [
180 ':type_customer' => AbstractUser::USER_ROLE_CUSTOMER,
181 ':type_admin' => AbstractUser::USER_ROLE_ADMIN,
182 ':statusVisible' => Status::VISIBLE,
183 ];
184
185 $where = [
186 'u.type IN (:type_customer, :type_admin)',
187 'u.status = :statusVisible'
188 ];
189
190 if (!empty($criteria['search'])) {
191 $params[':search1'] = $params[':search2'] = $params[':search3'] = $params[':search4'] =
192 "%{$criteria['search']}%";
193
194 $where[] = "((CONCAT(u.firstName, ' ', u.lastName) LIKE :search1
195 OR wpu.display_name LIKE :search2
196 OR u.email LIKE :search3
197 OR u.note LIKE :search4))";
198 }
199
200 if (!empty($criteria['customers'])) {
201 $customersCriteria = [];
202
203 foreach ((array)$criteria['customers'] as $key => $customerId) {
204 $params[":customerId$key"] = $customerId;
205 $customersCriteria[] = ":customerId$key";
206 }
207
208 $where[] = 'u.id IN (' . implode(', ', $customersCriteria) . ')';
209 }
210
211 if (!empty($criteria['noShow'])) {
212 $bookingsTable = CustomerBookingsTable::getTableName();
213
214 $params[':noShow'] = $criteria['noShow'];
215
216 $where[] = "(SELECT COUNT(*) FROM {$bookingsTable} cb WHERE cb.status='no-show' AND cb.customerId=u.id)" . ($criteria['noShow'] === "3" ? '>=' : '=') . " :noShow";
217 }
218
219 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
220
221 try {
222 $statement = $this->connection->prepare(
223 "SELECT COUNT(*) as count
224 FROM {$this->table} as u
225 LEFT JOIN {$wpUserTable} wpu ON u.externalId = wpu.id
226 $where
227 "
228 );
229
230 $statement->execute($params);
231
232 $rows = $statement->fetch()['count'];
233 } catch (\Exception $e) {
234 throw new QueryExecutionException('Unable to get data from ' . __CLASS__, $e->getCode(), $e);
235 }
236
237 return $rows;
238 }
239
240 /**
241 * @param string $phone
242 *
243 * @return array
244 * @throws QueryExecutionException
245 * @throws \Exception
246 */
247 public function getByPhoneNumber($phone)
248 {
249 try {
250 $params[':phone'] = '+' . $phone;
251
252 $statement = $this->connection->prepare(
253 "SELECT
254 u.id as id,
255 u.status as status,
256 u.firstName as firstName,
257 u.lastName as lastName,
258 u.email as email,
259 u.phone as phone,
260 u.countryPhoneIso AS countryPhoneIso,
261 u.gender as gender,
262 u.externalId as externalId,
263 IF(u.birthday IS NOT NULL, u.birthday , '') as birthday,
264 u.note as note
265 FROM {$this->table} as u
266 WHERE u.type = 'customer' AND phone = :phone"
267 );
268
269 $statement->execute($params);
270
271 $rows = $statement->fetchAll();
272 } catch (\Exception $e) {
273 throw new QueryExecutionException('Unable to get data from ' . __CLASS__, $e->getCode(), $e);
274 }
275
276 return $rows;
277 }
278
279 /**
280 * @param array $criteria
281 *
282 * @return Collection
283 * @throws QueryExecutionException
284 * @throws InvalidArgumentException
285 * @throws InvalidArgumentException
286 */
287 public function getByCriteria($criteria = [])
288 {
289 $params = [];
290
291 $where = [];
292
293 $fields = '
294 u.id AS id,
295 u.type AS type,
296 u.firstName AS firstName,
297 u.lastName AS lastName,
298 u.email AS email,
299 u.note AS note,
300 u.phone AS phone,
301 u.gender AS gender,
302 u.birthday AS birthday,
303 u.status AS status
304 ';
305
306 if (!empty($criteria['ids'])) {
307 $queryIds = [];
308
309 foreach ($criteria['ids'] as $index => $value) {
310 $param = ':id' . $index;
311
312 $queryIds[] = $param;
313
314 $params[$param] = $value;
315 }
316
317 $where[] = 'u.id IN (' . implode(', ', $queryIds) . ')';
318 }
319
320 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
321
322 try {
323 $statement = $this->connection->prepare(
324 "SELECT
325 {$fields}
326 FROM {$this->table} u
327 {$where}"
328 );
329
330 $statement->execute($params);
331
332 $rows = $statement->fetchAll();
333 } catch (\Exception $e) {
334 throw new QueryExecutionException('Unable to find event by id in ' . __CLASS__, $e->getCode(), $e);
335 }
336
337 $items = new Collection();
338
339 foreach ($rows as $row) {
340 $row['type'] = 'customer';
341
342 $items->addItem(call_user_func([static::FACTORY, 'create'], $row), $row['id']);
343 }
344
345 return $items;
346 }
347 }
348