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 / User / ProviderRepository.php
ameliabooking / src / Infrastructure / Repository / User Last commit date
CustomerRepository.php 10 months ago ProviderRepository.php 10 months ago UserRepository.php 1 year ago WPUserRepository.php 1 year ago
ProviderRepository.php
1660 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\Entity\User\Provider;
9 use AmeliaBooking\Domain\Factory\User\ProviderFactory;
10 use AmeliaBooking\Domain\Repository\User\ProviderRepositoryInterface;
11 use AmeliaBooking\Domain\Services\DateTime\DateTimeService;
12 use AmeliaBooking\Domain\ValueObjects\String\Status;
13 use AmeliaBooking\Infrastructure\Common\Exceptions\QueryExecutionException;
14 use AmeliaBooking\Infrastructure\Connection;
15 use AmeliaBooking\Infrastructure\Licence\Licence;
16 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Bookable\ExtrasTable;
17 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Booking\AppointmentsTable;
18 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Coupon\CouponsTable;
19 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\Coupon\CouponsToServicesTable;
20 use AmeliaBooking\Infrastructure\WP\InstallActions\DB\User\WPUsersTable;
21
22 /**
23 * Class ProviderRepository
24 *
25 * @package AmeliaBooking\Infrastructure\Repository
26 */
27 class ProviderRepository extends UserRepository implements ProviderRepositoryInterface
28 {
29 public const FACTORY = ProviderFactory::class;
30
31 /** @var string */
32 protected $providerWeekDayTable;
33
34 /** @var string */
35 protected $providerPeriodTable;
36
37 /** @var string */
38 protected $providerPeriodServiceTable;
39
40 /** @var string */
41 protected $providerPeriodLocationTable;
42
43 /** @var string */
44 protected $providerTimeOutTable;
45
46 /** @var string */
47 protected $providerSpecialDayTable;
48
49 /** @var string */
50 protected $providerSpecialDayPeriodTable;
51
52 /** @var string */
53 protected $providerSpecialDayPeriodServiceTable;
54
55 /** @var string */
56 protected $providerSpecialDayPeriodLocationTable;
57
58 /** @var string */
59 protected $providerDayOffTable;
60
61 /** @var string */
62 protected $providerServicesTable;
63
64 /** @var string */
65 protected $providerLocationTable;
66
67 /** @var string */
68 protected $serviceTable;
69
70 /** @var string */
71 protected $locationTable;
72
73 /** @var string */
74 protected $providerViewsTable;
75
76 /** @var string */
77 protected $providersGoogleCalendarTable;
78
79 /** @var string */
80 protected $providersOutlookCalendarTable;
81
82 /**
83 * @param Connection $connection
84 * @param string $table
85 * @param string $providerWeekDayTable
86 * @param string $providerPeriodTable
87 * @param string $providerPeriodServiceTable
88 * @param string $providerPeriodLocationTable
89 * @param string $providerTimeOutTable
90 * @param string $providerSpecialDayTable
91 * @param string $providerSpecialDayPeriodTable
92 * @param string $providerSpecialDayPeriodServiceTable
93 * @param string $providerSpecialDayPeriodLocationTable
94 * @param string $providerDayOffTable
95 * @param string $providerServicesTable
96 * @param string $providerLocationTable
97 * @param string $serviceTable
98 * @param string $locationTable
99 * @param string $providerViewsTable
100 * @param string $providersGoogleCalendarTable
101 * @param string $providersOutlookCalendarTable
102 */
103 public function __construct(
104 Connection $connection,
105 $table,
106 $providerWeekDayTable,
107 $providerPeriodTable,
108 $providerPeriodServiceTable,
109 $providerPeriodLocationTable,
110 $providerTimeOutTable,
111 $providerSpecialDayTable,
112 $providerSpecialDayPeriodTable,
113 $providerSpecialDayPeriodServiceTable,
114 $providerSpecialDayPeriodLocationTable,
115 $providerDayOffTable,
116 $providerServicesTable,
117 $providerLocationTable,
118 $serviceTable,
119 $locationTable,
120 $providerViewsTable,
121 $providersGoogleCalendarTable,
122 $providersOutlookCalendarTable
123 ) {
124 parent::__construct($connection, $table);
125
126 $this->providerWeekDayTable = $providerWeekDayTable;
127
128 $this->providerPeriodTable = $providerPeriodTable;
129
130 $this->providerPeriodServiceTable = $providerPeriodServiceTable;
131
132 $this->providerPeriodLocationTable = $providerPeriodLocationTable;
133
134 $this->providerTimeOutTable = $providerTimeOutTable;
135
136 $this->providerSpecialDayTable = $providerSpecialDayTable;
137
138 $this->providerSpecialDayPeriodTable = $providerSpecialDayPeriodTable;
139
140 $this->providerSpecialDayPeriodServiceTable = $providerSpecialDayPeriodServiceTable;
141
142 $this->providerSpecialDayPeriodLocationTable = $providerSpecialDayPeriodLocationTable;
143
144 $this->providerDayOffTable = $providerDayOffTable;
145
146 $this->providerServicesTable = $providerServicesTable;
147
148 $this->providerLocationTable = $providerLocationTable;
149
150 $this->serviceTable = $serviceTable;
151
152 $this->locationTable = $locationTable;
153
154 $this->providerViewsTable = $providerViewsTable;
155
156 $this->providersGoogleCalendarTable = $providersGoogleCalendarTable;
157
158 $this->providersOutlookCalendarTable = $providersOutlookCalendarTable;
159 }
160
161 /**
162 * @param int $id
163 *
164 * @return Provider
165 * @throws QueryExecutionException
166 */
167 public function getById($id)
168 {
169 try {
170 $statement = $this->connection->prepare(
171 "SELECT
172 u.id AS user_id,
173 u.status AS user_status,
174 u.externalId AS external_id,
175 u.firstName AS user_firstName,
176 u.lastName AS user_lastName,
177 u.email AS user_email,
178 u.note AS note,
179 u.phone AS phone,
180 u.pictureFullPath AS picture_full_path,
181 u.pictureThumbPath AS picture_thumb_path,
182 u.zoomUserId AS user_zoom_user_id,
183 u.appleCalendarId as user_apple_calendar_id,
184 u.employeeAppleCalendar as user_employee_apple_calendar,
185 u.stripeConnect AS user_stripeConnect,
186 u.translations AS user_translations,
187 u.timeZone AS user_timeZone,
188 u.badgeId AS badge_id,
189 gd.id AS google_calendar_id,
190 gd.token AS google_calendar_token,
191 gd.calendarId AS google_calendar_calendar_id,
192 od.id AS outlook_calendar_id,
193 od.token AS outlook_calendar_token,
194 od.calendarId AS outlook_calendar_calendar_id
195 FROM {$this->table} u
196 LEFT JOIN {$this->providersGoogleCalendarTable} gd ON gd.userId = u.id
197 LEFT JOIN {$this->providersOutlookCalendarTable} od ON od.userId = u.id
198 WHERE u.type = :type AND u.id = :userId
199 ORDER BY u.id"
200 );
201
202 $type = AbstractUser::USER_ROLE_PROVIDER;
203
204 $statement->bindParam(':type', $type);
205 $statement->bindParam(':userId', $id);
206
207 $statement->execute();
208
209 $providerRows = [];
210 $serviceRows = [];
211 $providerServiceRows = [];
212
213 if ($statement->rowCount() === 0) {
214 return null;
215 }
216
217 while ($row = $statement->fetch()) {
218 $this->parseUserRow($row, $providerRows, $serviceRows, $providerServiceRows);
219 }
220 } catch (\Exception $e) {
221 throw new QueryExecutionException('Unable to find by id in ' . __CLASS__, $e->getCode(), $e);
222 }
223
224 return call_user_func([static::FACTORY, 'createCollection'], $providerRows, $serviceRows, $providerServiceRows)->getItem($id);
225 }
226
227 /**
228 *
229 * @return Collection
230 * @throws QueryExecutionException
231 */
232 public function getAll()
233 {
234 try {
235 $statement = $this->connection->prepare(
236 "SELECT
237 u.id AS user_id,
238 u.status AS user_status,
239 u.externalId AS external_id,
240 u.firstName AS user_firstName,
241 u.lastName AS user_lastName,
242 u.email AS user_email,
243 u.note AS note,
244 u.phone AS phone,
245 u.pictureFullPath AS picture_full_path,
246 u.pictureThumbPath AS picture_thumb_path,
247 u.translations AS user_translations,
248 u.badgeId AS user_badge_id,
249 lt.locationId AS user_locationId
250 FROM {$this->table} u
251 LEFT JOIN {$this->providerLocationTable} lt ON lt.userId = u.id
252 WHERE u.type = :type
253 ORDER BY CONCAT(u.firstName, ' ', u.lastName)"
254 );
255
256 $type = AbstractUser::USER_ROLE_PROVIDER;
257
258 $statement->bindParam(':type', $type);
259
260 $statement->execute();
261
262 $providerRows = [];
263 $serviceRows = [];
264 $providerServiceRows = [];
265
266 while ($row = $statement->fetch()) {
267 $this->parseUserRow($row, $providerRows, $serviceRows, $providerServiceRows);
268 }
269 } catch (\Exception $e) {
270 throw new QueryExecutionException('Unable to find by id in ' . __CLASS__, $e->getCode(), $e);
271 }
272
273 return call_user_func([static::FACTORY, 'createCollection'], $providerRows, $serviceRows, $providerServiceRows);
274 }
275
276 /**
277 * @param array $criteria
278 * @param int $itemsPerPage
279 *
280 * @return Collection
281 * @throws QueryExecutionException
282 * @throws InvalidArgumentException
283 */
284 public function getFiltered($criteria, $itemsPerPage)
285 {
286 try {
287 $wpUserTable = WPUsersTable::getTableName();
288
289 $params[':type'] = AbstractUser::USER_ROLE_PROVIDER;
290
291 $order = '';
292 if (!empty($criteria['sort'])) {
293 $orderColumn = 'CONCAT(u.firstName, " ", u.lastName)';
294 $orderDirection = $criteria['sort'][0] === '-' ? 'DESC' : 'ASC';
295 $order = "ORDER BY {$orderColumn} {$orderDirection}";
296 }
297
298 $where = [];
299
300 if (!empty($criteria['search'])) {
301 $params[':search1'] = $params[':search2'] = $params[':search3'] = $params[':search4'] =
302 "%{$criteria['search']}%";
303
304 $where[] = "u.id IN(
305 SELECT DISTINCT(user.id)
306 FROM {$this->table} user
307 LEFT JOIN {$wpUserTable} wpUser ON user.externalId = wpUser.ID
308 WHERE (CONCAT(user.firstName, ' ', user.lastName) LIKE :search1
309 OR wpUser.display_name LIKE :search2
310 OR user.email LIKE :search3
311 OR user.note LIKE :search4)
312 )";
313 }
314
315 if (!empty($criteria['services'])) {
316 $queryServices = [];
317
318 foreach ((array)$criteria['services'] as $index => $value) {
319 $param = ':service' . $index;
320 $queryServices[] = $param;
321 $params[$param] = $value;
322 }
323
324 $where[] = "u.id IN (
325 SELECT pst.userId FROM {$this->providerServicesTable} pst
326 WHERE pst.userId = u.id AND pst.serviceId IN (" . implode(', ', $queryServices) . ')
327 )';
328 }
329
330 if (!empty($criteria['providers'])) {
331 $queryProviders = [];
332
333 foreach ((array)$criteria['providers'] as $index => $value) {
334 $param = ':provider' . $index;
335 $queryProviders[] = $param;
336 $params[$param] = $value;
337 }
338
339 $where[] = 'u.id IN (' . implode(', ', $queryProviders) . ')';
340 }
341
342 if (!empty($criteria['location'])) {
343 $queryLocations = [];
344
345 foreach ((array)$criteria['location'] as $index => $value) {
346 $param = ':location' . $index;
347 $queryLocations[] = $param;
348 $params[$param] = $value;
349 }
350
351 $where[] = "u.id IN (
352 SELECT plt.userId FROM {$this->providerLocationTable} plt
353 WHERE plt.userId = u.id AND plt.locationId IN ( " . implode(', ', $queryLocations) . "))";
354 }
355
356 $where[] = "u.status NOT LIKE 'disabled'";
357
358 $where = $where ? ' AND ' . implode(' AND ', $where) : '';
359
360 $limit = $this->getLimit(
361 !empty($criteria['page']) ? (int)$criteria['page'] : 0,
362 (int)$itemsPerPage
363 );
364
365 $statement = $this->connection->prepare(
366 "SELECT u.*
367 FROM {$this->table} u
368 WHERE u.type = :type $where
369 {$order}
370 {$limit}"
371 );
372
373 $statement->execute($params);
374
375 $rows = $statement->fetchAll();
376 } catch (\Exception $e) {
377 throw new QueryExecutionException('Unable to get data from ' . __CLASS__, $e->getCode(), $e);
378 }
379
380 $items = new Collection();
381
382 foreach ($rows as $row) {
383 $items->addItem(call_user_func([static::FACTORY, 'create'], $row), $row['id']);
384 }
385
386 return $items;
387 }
388
389 /**
390 *
391 * @param array $criteria
392 *
393 * @return Collection
394 * @throws QueryExecutionException
395 * @throws InvalidArgumentException
396 */
397 public function getWithSchedule($criteria)
398 {
399 $providerRows = [];
400
401 $serviceRows = [];
402
403 $providerServiceRows = [];
404
405 $where = ['u.type = :type'];
406
407 $userParams = [];
408
409 $params[':type'] = AbstractUser::USER_ROLE_PROVIDER;
410
411 $queryProviders = [];
412
413 if (!empty($criteria['dates'][0])) {
414 $criteria['dates'][0] = explode(' ', $criteria['dates'][0])[0];
415 }
416
417 if (!empty($criteria['dates'][1])) {
418 $criteria['dates'][1] = explode(' ', $criteria['dates'][1])[0];
419 }
420
421 if (!empty($criteria['providerStatus'])) {
422 $params[':providerStatus'] = $criteria['providerStatus'];
423
424 $where[] = 'u.status = :providerStatus';
425 }
426
427 if (isset($criteria['show'])) {
428 $params[':show'] = $criteria['show'];
429
430 $where[] = 'u.show = :show';
431 }
432
433 if (!empty($criteria['providers'])) {
434 foreach ($criteria['providers'] as $index => $value) {
435 $param = ':provider' . $index;
436
437 $queryProviders[] = $param;
438
439 $userParams[$param] = $value;
440 }
441 }
442
443 $calendarJoin = '';
444
445 $calendarFields = '';
446
447 if (!empty($criteria['fetchCalendars'])) {
448 $calendarJoin = "
449 LEFT JOIN {$this->providersGoogleCalendarTable} gd ON gd.userId = u.id
450 LEFT JOIN {$this->providersOutlookCalendarTable} od ON od.userId = u.id
451 ";
452
453 $calendarFields = '
454 gd.id AS google_calendar_id,
455 gd.token AS google_calendar_token,
456 gd.calendarId AS google_calendar_calendar_id,
457 od.id AS outlook_calendar_id,
458 od.token AS outlook_calendar_token,
459 od.calendarId AS outlook_calendar_calendar_id,
460 ';
461 }
462
463 if ($queryProviders) {
464 $where[] = 'u.id IN (' . implode(', ', $queryProviders) . ')';
465 }
466
467 $dotJoinQuery = '';
468
469 if (isset($criteria['dates'][0], $criteria['dates'][1])) {
470 $dotJoinQuery = "AND (dot.repeat = 1 OR (
471 dot.startDate BETWEEN :from1 AND :to1 OR
472 dot.endDate BETWEEN :from2 AND :to2 OR
473 (dot.startDate <= :from3 AND dot.endDate >= :to3)
474 ))";
475
476 $userParams[':from1'] = $userParams[':from2'] = $userParams[':from3'] = $criteria['dates'][0];
477
478 $userParams[':to1'] = $userParams[':to2'] = $userParams[':to3'] = $criteria['dates'][1];
479 } elseif (isset($criteria['dates'][0])) {
480 $dotJoinQuery = "AND (dot.repeat = 1 OR dot.startDate >= :from1 OR dot.endDate >= :from2)";
481
482 $userParams[':from1'] = $userParams[':from2'] = $criteria['dates'][0];
483 }
484
485 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
486
487 try {
488 $statement = $this->connection->prepare(
489 "SELECT
490 u.id AS user_id,
491 u.status AS user_status,
492 u.externalId AS external_id,
493 u.firstName AS user_firstName,
494 u.lastName AS user_lastName,
495 u.email AS user_email,
496 u.zoomUserId AS user_zoom_user_id,
497 u.appleCalendarId AS user_apple_calendar_id,
498 u.employeeAppleCalendar AS user_employee_apple_calendar,
499 u.stripeConnect AS user_stripeConnect,
500 u.countryPhoneIso AS user_countryPhoneIso,
501 u.note AS note,
502 u.description AS description,
503 u.phone AS phone,
504 u.pictureFullPath AS picture_full_path,
505 u.pictureThumbPath AS picture_thumb_path,
506 u.translations AS user_translations,
507 u.timeZone AS user_timeZone,
508 u.badgeId AS badge_id,
509 u.show AS user_show,
510 plt.locationId AS user_locationId,
511 pst.serviceId AS service_id,
512 pst.price AS service_price,
513 pst.customPricing AS service_customPricing,
514 pst.minCapacity AS service_minCapacity,
515 pst.maxCapacity AS service_maxCapacity,
516 {$calendarFields}
517 dot.id AS dayOff_id,
518 dot.name AS dayOff_name,
519 dot.startDate AS dayOff_startDate,
520 dot.endDate AS dayOff_endDate,
521 dot.repeat AS dayOff_repeat
522 FROM {$this->table} u
523 LEFT JOIN {$this->providerServicesTable} pst ON pst.userId = u.id
524 LEFT JOIN {$this->providerLocationTable} plt ON plt.userId = u.id
525 {$calendarJoin}
526 LEFT JOIN {$this->providerDayOffTable} dot ON dot.userId = u.id {$dotJoinQuery}
527 {$where}
528 ORDER BY CONCAT(u.firstName, ' ', u.lastName), u.id"
529 );
530
531 $statement->execute(array_merge($params, $userParams));
532
533 while ($row = $statement->fetch()) {
534 $this->parseUserRow($row, $providerRows, $serviceRows, $providerServiceRows);
535 }
536 } catch (\Exception $e) {
537 throw new QueryExecutionException('Unable to find by id in ' . __CLASS__, $e->getCode(), $e);
538 }
539
540 /** @var Collection $providers */
541 $providers = call_user_func(
542 [static::FACTORY, 'createCollection'],
543 $providerRows,
544 $serviceRows,
545 $providerServiceRows
546 );
547
548 if (!$providers->length()) {
549 return new Collection();
550 }
551
552 $where = 'WHERE wdt.userId IN (' . implode(', ', $providers->keys()) . ')';
553
554 try {
555 $statement = $this->connection->prepare(
556 "SELECT
557 wdt.id AS weekDay_id,
558 wdt.userId AS user_id,
559 wdt.dayIndex AS weekDay_dayIndex,
560 wdt.startTime AS weekDay_startTime,
561 wdt.endTime As weekDay_endTime,
562 tot.id AS timeOut_id,
563 tot.startTime AS timeOut_startTime,
564 tot.endTime AS timeOut_endTime,
565 pt.id AS period_id,
566 pt.startTime AS period_startTime,
567 pt.endTime AS period_endTime,
568 pt.locationId AS period_locationId,
569 pst.id AS periodService_id,
570 pst.serviceId AS periodService_serviceId,
571 plt.id AS periodLocation_id,
572 plt.locationId AS periodLocation_locationId
573 FROM {$this->providerWeekDayTable} wdt
574 LEFT JOIN {$this->providerTimeOutTable} tot ON tot.weekDayId = wdt.id
575 LEFT JOIN {$this->providerPeriodTable} pt ON pt.weekDayId = wdt.id
576 LEFT JOIN {$this->providerPeriodServiceTable} pst ON pst.periodId = pt.id
577 LEFT JOIN {$this->providerPeriodLocationTable} plt ON plt.periodId = pt.id
578 {$where}"
579 );
580
581 $statement->execute();
582
583 while ($row = $statement->fetch()) {
584 $this->parseUserRow($row, $providerRows, $serviceRows, $providerServiceRows);
585 }
586 } catch (\Exception $e) {
587 throw new QueryExecutionException('Unable to find by id in ' . __CLASS__, $e->getCode(), $e);
588 }
589
590 /** @var Collection $providersWithWeekDays */
591 $providersWithWeekDays = call_user_func(
592 [static::FACTORY, 'createCollection'],
593 $providerRows,
594 $serviceRows,
595 $providerServiceRows
596 );
597
598 /** @var Provider $provider */
599 foreach ($providersWithWeekDays->getItems() as $provider) {
600 $providers->getItem(
601 $provider->getId()->getValue()
602 )->setWeekDayList($provider->getWeekDayList());
603 }
604
605 $where = ['sdt.userId IN (' . implode(', ', $providers->keys()) . ')'];
606
607 $sdtParams = [];
608
609 if (isset($criteria['dates'][0], $criteria['dates'][1])) {
610 $where[] = "(
611 sdt.startDate BETWEEN :from1 AND :to1 OR
612 sdt.endDate BETWEEN :from2 AND :to2 OR
613 (sdt.startDate <= :from3 AND sdt.endDate >= :to3)
614 )";
615
616 $sdtParams[':from1'] = $sdtParams[':from2'] = $sdtParams[':from3'] = $criteria['dates'][0];
617
618 $sdtParams[':to1'] = $sdtParams[':to2'] = $sdtParams[':to3'] = $criteria['dates'][1];
619 } elseif (isset($criteria['dates'][0])) {
620 $where[] = "(
621 sdt.startDate >= :from1 OR
622 sdt.endDate >= :from2
623 )";
624
625 $sdtParams[':from1'] = $sdtParams[':from2'] = $criteria['dates'][0];
626 }
627
628 $where = 'WHERE ' . implode(' AND ', $where);
629
630 try {
631 $statement = $this->connection->prepare(
632 "SELECT
633 sdt.id AS specialDay_id,
634 sdt.userId AS user_id,
635 sdt.startDate AS specialDay_startDate,
636 sdt.endDate As specialDay_endDate,
637 sdpt.id AS specialDayPeriod_id,
638 sdpt.startTime AS specialDayPeriod_startTime,
639 sdpt.endTime AS specialDayPeriod_endTime,
640 sdpt.locationId AS specialDayPeriod_locationId,
641 sdpst.id AS specialDayPeriodService_id,
642 sdpst.serviceId AS specialDayPeriodService_serviceId,
643 sdplt.id AS specialDayPeriodLocation_id,
644 sdplt.locationId AS specialDayPeriodLocation_locationId
645 FROM {$this->providerSpecialDayTable} sdt
646 LEFT JOIN {$this->providerSpecialDayPeriodTable} sdpt ON sdpt.specialDayId = sdt.id
647 LEFT JOIN {$this->providerSpecialDayPeriodServiceTable} sdpst ON sdpst.periodId = sdpt.id
648 LEFT JOIN {$this->providerSpecialDayPeriodLocationTable} sdplt ON sdplt.periodId = sdpt.id
649 {$where}"
650 );
651
652 $statement->execute($sdtParams);
653
654 while ($row = $statement->fetch()) {
655 $this->parseUserRow($row, $providerRows, $serviceRows, $providerServiceRows);
656 }
657 } catch (\Exception $e) {
658 throw new QueryExecutionException('Unable to find by id in ' . __CLASS__, $e->getCode(), $e);
659 }
660
661 /** @var Collection $providersWithSpecialDays */
662 $providersWithSpecialDays = call_user_func(
663 [static::FACTORY, 'createCollection'],
664 $providerRows,
665 $serviceRows,
666 $providerServiceRows
667 );
668
669 /** @var Provider $provider */
670 foreach ($providersWithSpecialDays->getItems() as $provider) {
671 $providers->getItem(
672 $provider->getId()->getValue()
673 )->setSpecialDayList($provider->getSpecialDayList());
674 }
675
676 return Licence::getEmployees($providers);
677 }
678
679 /**
680 * @param array $criteria
681 *
682 * @return mixed
683 * @throws QueryExecutionException
684 */
685 public function getCount($criteria)
686 {
687 $params = [
688 ':type' => AbstractUser::USER_ROLE_PROVIDER,
689 ':visibleStatus' => Status::VISIBLE,
690 ':hiddenStatus' => Status::HIDDEN,
691 ];
692
693 try {
694 $wpUserTable = WPUsersTable::getTableName();
695
696 $where = [];
697
698 if (!empty($criteria['search'])) {
699 $params[':search1'] = $params[':search2'] = $params[':search3'] = $params[':search4'] =
700 "%{$criteria['search']}%";
701
702 $where[] = "u.id IN(
703 SELECT DISTINCT(user.id)
704 FROM {$this->table} user
705 LEFT JOIN {$wpUserTable} wpUser ON user.externalId = wpUser.ID
706 WHERE (CONCAT(user.firstName, ' ', user.lastName) LIKE :search1
707 OR wpUser.display_name LIKE :search2
708 OR user.email LIKE :search3
709 OR user.note LIKE :search4)
710 )";
711 }
712
713 if (!empty($criteria['services'])) {
714 $queryServices = [];
715
716 foreach ((array)$criteria['services'] as $index => $value) {
717 $param = ':service' . $index;
718 $queryServices[] = $param;
719 $params[$param] = $value;
720 }
721
722 $where[] = "u.id IN (
723 SELECT pst.userId FROM {$this->providerServicesTable} pst
724 WHERE pst.userId = u.id AND pst.serviceId IN (" . implode(', ', $queryServices) . ')
725 )';
726 }
727
728 if (!empty($criteria['location'])) {
729 $queryLocations = [];
730
731 foreach ((array)$criteria['location'] as $index => $value) {
732 $param = ':location' . $index;
733 $queryLocations[] = $param;
734 $params[$param] = $value;
735 }
736
737 $where[] = "u.id IN (
738 SELECT plt.userId FROM {$this->providerLocationTable} plt
739 WHERE plt.userId = u.id AND plt.locationId IN ( " . implode(', ', $queryLocations) . "))";
740 }
741
742 $where = $where ? ' AND ' . implode(' AND ', $where) : '';
743
744 $statement = $this->connection->prepare(
745 "SELECT COUNT(*) AS count
746 FROM {$this->table} u
747 WHERE u.type = :type AND u.status IN (:visibleStatus, :hiddenStatus) $where"
748 );
749
750 $statement->execute($params);
751
752 $row = $statement->fetch()['count'];
753 } catch (\Exception $e) {
754 throw new QueryExecutionException('Unable to get data from ' . __CLASS__, $e->getCode(), $e);
755 }
756
757 return $row;
758 }
759
760 /**
761 * @param $criteria
762 *
763 * @return Collection
764 * @throws InvalidArgumentException
765 * @throws QueryExecutionException
766 */
767 public function getWithServicesAndExtras($criteria)
768 {
769 $extrasTable = ExtrasTable::getTableName();
770
771 $params = [
772 ':type' => AbstractUser::USER_ROLE_PROVIDER,
773 ':userStatus' => Status::VISIBLE,
774 ':serviceStatus' => Status::VISIBLE
775 ];
776
777 $where = [];
778
779 foreach ((array)$criteria as $index => $value) {
780 $params[':service' . $index] = $value['serviceId'];
781 $params[':provider' . $index] = $value['providerId'];
782
783 $where[] = "(s.id = :service$index AND u.id = :provider$index)";
784 }
785
786 $where = $where ? ' AND ' . implode(' OR ', $where) : '';
787
788 try {
789 $statement = $this->connection->prepare(
790 "SELECT
791 u.id AS user_id,
792 u.firstName AS user_firstName,
793 u.lastName AS user_lastName,
794 u.email AS user_email,
795 u.timeZone AS user_timeZone,
796 u.translations AS user_translations,
797 st.serviceId AS service_id,
798 st.price AS service_price,
799 st.customPricing AS service_customPricing,
800 st.minCapacity AS service_minCapacity,
801 st.maxCapacity AS service_maxCapacity,
802 s.name AS service_name,
803 s.description AS service_description,
804 s.color AS service_color,
805 s.status AS service_status,
806 s.categoryId AS service_categoryId,
807 s.duration AS service_duration,
808 s.bringingAnyone AS service_bringingAnyone,
809 s.pictureFullPath AS service_picture_full,
810 s.pictureThumbPath AS service_picture_thumb,
811 s.aggregatedPrice AS service_aggregatedPrice,
812 s.recurringPayment AS service_recurringPayment,
813 s.translations AS service_translations,
814 s.timeBefore AS service_timeBefore,
815 s.timeAfter AS service_timeAfter,
816 s.deposit AS service_deposit,
817 s.depositPayment AS service_depositPayment,
818 s.depositPerPerson AS service_depositPerPerson,
819 e.id AS extra_id,
820 e.name AS extra_name,
821 e.price AS extra_price,
822 e.maxQuantity AS extra_maxQuantity,
823 e.duration AS extra_duration,
824 e.description AS extra_description,
825 e.position AS extra_position,
826 e.aggregatedPrice AS extra_aggregatedPrice
827 FROM {$this->table} u
828 INNER JOIN {$this->providerServicesTable} st ON st.userId = u.id
829 INNER JOIN {$this->serviceTable} s ON s.id = st.serviceId
830 LEFT JOIN {$extrasTable} e ON e.serviceId = s.id
831 WHERE u.status = :userStatus AND s.status = :serviceStatus AND u.type = :type $where"
832 );
833
834 $statement->execute($params);
835
836 $providerRows = [];
837 $serviceRows = [];
838 $providerServiceRows = [];
839
840 while ($row = $statement->fetch()) {
841 $this->parseUserRow($row, $providerRows, $serviceRows, $providerServiceRows);
842 }
843 } catch (\Exception $e) {
844 throw new QueryExecutionException('Unable to find by id in ' . __CLASS__, $e->getCode(), $e);
845 }
846
847 return call_user_func([static::FACTORY, 'createCollection'], $providerRows, $serviceRows, $providerServiceRows);
848 }
849
850 /**
851 * Returns array of available (currently working) Providers where keys are Provider ID's and array values are
852 * Working Hours Data
853 *
854 * @param $dayIndex
855 *
856 * @return array
857 * @throws QueryExecutionException
858 */
859 public function getAvailable($dayIndex, $providerTimeZone)
860 {
861 $currentDateTime = DateTimeService::getNowDateTime();
862 $currentDateTimeInTimeZone = DateTimeService::getCustomDateTimeObjectInTimeZone($currentDateTime, $providerTimeZone);
863 $currentDateTimeSQL = "STR_TO_DATE('" . $currentDateTimeInTimeZone->format('Y-m-d H:i:s') . "', '%Y-%m-%d %H:%i:%s')";
864
865 $params = [
866 ':dayIndex' => $dayIndex === 0 ? 7 : $dayIndex,
867 ':type' => AbstractUser::USER_ROLE_PROVIDER,
868 ':providerTimeZone' => $providerTimeZone,
869 ':WPtimeZone' => DateTimeService::getTimeZone()->getName()
870 ];
871
872 try {
873 $statement = $this->connection->prepare(
874 "SELECT
875 u.id AS user_id,
876 u.firstName AS user_firstName,
877 u.lastName AS user_lastName,
878 u.translations AS user_translations,
879 u.timeZone AS user_timeZone,
880 wdt.id AS weekDay_id,
881 wdt.dayIndex AS weekDay_dayIndex,
882 wdt.startTime AS weekDay_startTime,
883 wdt.endTime AS weekDay_endTime,
884 pt.id AS period_id,
885 pt.startTime AS period_startTime,
886 pt.endTime AS period_endTime
887 FROM {$this->table} u
888 LEFT JOIN {$this->providerWeekDayTable} wdt ON wdt.userId = u.id
889 LEFT JOIN {$this->providerPeriodTable} pt ON pt.weekDayId = wdt.id
890 WHERE u.type = :type AND
891 wdt.dayIndex = :dayIndex AND
892 (COALESCE(u.timeZone, :WPtimeZone) = :providerTimeZone) AND
893 ((
894 {$currentDateTimeSQL} >= wdt.startTime AND
895 {$currentDateTimeSQL} <= wdt.endTime AND
896 pt.startTime IS NULL AND
897 pt.endTime IS NULL
898 ) OR (
899 {$currentDateTimeSQL} >= pt.startTime AND
900 {$currentDateTimeSQL} <= pt.endTime AND
901 pt.startTime IS NOT NULL AND
902 pt.endTime IS NOT NULL
903 ))"
904 );
905
906 $statement->execute($params);
907
908 $rows = $statement->fetchAll();
909 } catch (\Exception $e) {
910 throw new QueryExecutionException('Unable to find by id in ' . __CLASS__, $e->getCode(), $e);
911 }
912
913 $result = [];
914
915 foreach ($rows as $row) {
916 if (!array_key_exists($row['user_id'], $result)) {
917 $result[$row['user_id']] = $row;
918 }
919
920 $result[$row['user_id']]['periods'][$row['period_id']] = [
921 'startTime' => $row['period_startTime'],
922 'endTime' => $row['period_endTime']
923 ];
924 }
925
926 return $result;
927 }
928
929 /**
930 * Returns array of available (currently working) Providers where keys are Provider ID's and array values are
931 * Working Hours Data on special day
932 *
933 * @return array
934 * @throws QueryExecutionException
935 */
936 public function getOnSpecialDay()
937 {
938 $dateTimeNowString = DateTimeService::getNowDateTime();
939 $currentDateTime = "STR_TO_DATE('" . $dateTimeNowString . "', '%Y-%m-%d %H:%i:%s')";
940 $currentDateString = DateTimeService::getNowDate();
941
942 $params = [
943 ':type' => AbstractUser::USER_ROLE_PROVIDER
944 ];
945
946 try {
947 $statement = $this->connection->prepare(
948 "SELECT
949 u.id AS user_id,
950 u.firstName AS user_firstName,
951 u.lastName AS user_lastName,
952 sdpt.startTime AS sdp_startTime,
953 sdpt.endTime AS sdp_endTime,
954 IF (
955 {$currentDateTime} >= STR_TO_DATE(CONCAT(sdt.startDate, ' 00:00:00'), '%Y-%m-%d %H:%i:%s') AND
956 {$currentDateTime} <= DATE_ADD(STR_TO_DATE(CONCAT(sdt.endDate, ' 00:00:00'), '%Y-%m-%d %H:%i:%s'), INTERVAL 1 DAY) AND
957 {$currentDateTime} >= STR_TO_DATE(CONCAT('{$currentDateString}', ' ', sdpt.startTime), '%Y-%m-%d %H:%i:%s') AND
958 {$currentDateTime} <= STR_TO_DATE(CONCAT('{$currentDateString}', ' ', sdpt.endTime), '%Y-%m-%d %H:%i:%s'),
959 1,
960 0
961 ) AS available
962 FROM {$this->table} u
963 INNER JOIN {$this->providerSpecialDayTable} sdt ON sdt.userId = u.id
964 INNER JOIN {$this->providerSpecialDayPeriodTable} sdpt ON sdpt.specialDayId = sdt.id
965 WHERE u.type = :type AND
966 STR_TO_DATE('{$currentDateString}', '%Y-%m-%d') BETWEEN sdt.startDate AND sdt.endDate
967 "
968 );
969
970 $statement->execute($params);
971
972 $rows = $statement->fetchAll();
973 } catch (\Exception $e) {
974 throw new QueryExecutionException('Unable to find by id in ' . __CLASS__, $e->getCode(), $e);
975 }
976
977 $result = [];
978
979 $dateTimeNow = DateTimeService::getNowDateTimeObject();
980 foreach ($rows as $row) {
981 $dateTimeEnd = DateTimeService::getCustomDateTimeObject($currentDateString . " " . $row['sdp_endTime']);
982 if (!array_key_exists($row['user_id'], $result) && $dateTimeNow <= $dateTimeEnd) {
983 $result[$row['user_id']] = $row;
984 }
985 }
986
987 return $result;
988 }
989
990 /**
991 * @param $dayIndex
992 *
993 * @return array
994 * @throws QueryExecutionException
995 */
996 public function getOnBreak($dayIndex)
997 {
998 $currentDateTime = "STR_TO_DATE('" . DateTimeService::getNowDateTime() . "', '%Y-%m-%d %H:%i:%s')";
999
1000 $params = [
1001 ':dayIndex' => $dayIndex === 0 ? 7 : $dayIndex,
1002 ':type' => AbstractUser::USER_ROLE_PROVIDER
1003 ];
1004
1005 try {
1006 $statement = $this->connection->prepare(
1007 "SELECT
1008 u.id AS user_id,
1009 u.firstName AS user_firstName,
1010 u.lastName AS user_lastName,
1011 wdt.id AS weekDay_id,
1012 wdt.dayIndex AS weekDay_dayIndex,
1013 wdt.startTime AS weekDay_startTime,
1014 wdt.endTime As weekDay_endTime,
1015 tot.id AS timeOut_id,
1016 tot.startTime AS timeOut_startTime,
1017 tot.endTime AS timeOut_endTime
1018 FROM {$this->table} u
1019 LEFT JOIN {$this->providerWeekDayTable} wdt ON wdt.userId = u.id
1020 LEFT JOIN {$this->providerTimeOutTable} tot ON tot.weekDayId = wdt.id
1021 WHERE u.type = :type AND
1022 wdt.dayIndex = :dayIndex AND
1023 {$currentDateTime} >= wdt.startTime AND
1024 {$currentDateTime} <= wdt.endTime AND
1025 {$currentDateTime} >= tot.startTime AND
1026 {$currentDateTime} <= tot.endTime"
1027 );
1028
1029 $statement->execute($params);
1030
1031 $rows = $statement->fetchAll();
1032 } catch (\Exception $e) {
1033 throw new QueryExecutionException('Unable to find by id in ' . __CLASS__, $e->getCode(), $e);
1034 }
1035
1036 $result = [];
1037
1038 foreach ($rows as $row) {
1039 $result[$row['user_id']] = $row;
1040 }
1041
1042 return $result;
1043 }
1044
1045 /**
1046 * @return array
1047 * @throws QueryExecutionException
1048 */
1049 public function getOnVacation()
1050 {
1051 $currentDateTime = explode(' ', DateTimeService::getNowDateTime())[0];
1052
1053 $params = [
1054 ':type' => AbstractUser::USER_ROLE_PROVIDER
1055 ];
1056
1057 try {
1058 $statement = $this->connection->prepare(
1059 "SELECT
1060 u.id,
1061 u.firstName,
1062 u.lastName,
1063 dot.startDate,
1064 dot.endDate,
1065 dot.name
1066 FROM {$this->table} u
1067 LEFT JOIN {$this->providerDayOffTable} dot ON dot.userId = u.id
1068 WHERE u.type = :type AND
1069 $currentDateTime BETWEEN dot.startDate AND dot.endDate"
1070 );
1071
1072 $statement->execute($params);
1073
1074 $rows = $statement->fetchAll();
1075 } catch (\Exception $e) {
1076 throw new QueryExecutionException('Unable to find by id in ' . __CLASS__, $e->getCode(), $e);
1077 }
1078
1079 $result = [];
1080
1081 foreach ($rows as $row) {
1082 $result[$row['id']] = $row;
1083 }
1084
1085 return $result;
1086 }
1087
1088 /**
1089 * Return an array of providers with the number of appointments for the given date period.
1090 * Keys of the array are Provider IDs.
1091 *
1092 * @param $criteria
1093 *
1094 * @return array
1095 * @throws InvalidArgumentException
1096 * @throws QueryExecutionException
1097 */
1098 public function getAllNumberOfAppointments($criteria)
1099 {
1100 $appointmentTable = AppointmentsTable::getTableName();
1101
1102 $params = [];
1103
1104 $where = [];
1105
1106 if ($criteria['dates']) {
1107 $where[] = "(a.bookingStart BETWEEN :bookingFrom AND :bookingTo)";
1108
1109 $params[':bookingFrom'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][0]);
1110
1111 $params[':bookingTo'] = DateTimeService::getCustomDateTimeInUtc($criteria['dates'][1]);
1112 }
1113
1114 if (isset($criteria['status'])) {
1115 $where[] = 'u.status = :status';
1116
1117 $params[':status'] = $criteria['status'];
1118 }
1119
1120 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
1121
1122 try {
1123 $statement = $this->connection->prepare(
1124 "SELECT
1125 u.id,
1126 CONCAT(u.firstName, ' ', u.lastName) AS name,
1127 COUNT(a.providerId) AS appointments
1128 FROM {$this->table} u
1129 INNER JOIN {$appointmentTable} a ON u.id = a.providerId
1130 $where
1131 GROUP BY providerId"
1132 );
1133
1134 $statement->execute($params);
1135
1136 $rows = $statement->fetchAll();
1137 } catch (\Exception $e) {
1138 throw new QueryExecutionException('Unable to get data from ' . __CLASS__, $e->getCode(), $e);
1139 }
1140
1141 $result = [];
1142
1143 foreach ($rows as $row) {
1144 $result[$row['id']] = $row;
1145 }
1146
1147 return $result;
1148 }
1149
1150 /**
1151 * Return an array of providers with the number of views for the given date period.
1152 * Keys of the array are Providers IDs.
1153 *
1154 * @param $criteria
1155 *
1156 * @return array
1157 * @throws QueryExecutionException
1158 */
1159 public function getAllNumberOfViews($criteria)
1160 {
1161 $params = [];
1162
1163 $where = [];
1164
1165 if ($criteria['dates']) {
1166 $where[] = "(pv.date BETWEEN :bookingFrom AND :bookingTo)";
1167
1168 $params[':bookingFrom'] = explode(' ', $criteria['dates'][0])[0];
1169
1170 $params[':bookingTo'] = explode(' ', $criteria['dates'][1])[0];
1171 }
1172
1173 if (isset($criteria['status'])) {
1174 $where[] = 'u.status = :status';
1175
1176 $params[':status'] = $criteria['status'];
1177 }
1178
1179 $where = $where ? 'WHERE ' . implode(' AND ', $where) : '';
1180
1181 try {
1182 $statement = $this->connection->prepare(
1183 "SELECT
1184 u.id,
1185 CONCAT(u.firstName, ' ', u.lastName) as name,
1186 SUM(pv.views) AS views
1187 FROM {$this->table} u
1188 INNER JOIN {$this->providerViewsTable} pv ON pv.userId = u.id
1189 $where
1190 GROUP BY u.id"
1191 );
1192
1193 $statement->execute($params);
1194
1195 $rows = $statement->fetchAll();
1196 } catch (\Exception $e) {
1197 throw new QueryExecutionException('Unable to get data from ' . __CLASS__, $e->getCode(), $e);
1198 }
1199
1200 $result = [];
1201
1202 foreach ($rows as $row) {
1203 $result[$row['id']] = $row;
1204 }
1205
1206 return $result;
1207 }
1208
1209 /**
1210 * @param $providerId
1211 *
1212 * @return string
1213 * @throws QueryExecutionException
1214 */
1215 public function addViewStats($providerId)
1216 {
1217 $date = DateTimeService::getNowDate();
1218
1219 $params = [
1220 ':userId' => $providerId,
1221 ':date' => $date,
1222 ':views' => 1
1223 ];
1224
1225 try {
1226 // Check if there is already data for this provider for this date
1227 $statement = $this->connection->prepare(
1228 "SELECT COUNT(*) AS count
1229 FROM {$this->providerViewsTable} AS pv
1230 WHERE pv.userId = :userId
1231 AND pv.date = :date"
1232 );
1233
1234 $statement->bindParam(':userId', $providerId);
1235 $statement->bindParam(':date', $date);
1236 $statement->execute();
1237 $count = $statement->fetch()['count'];
1238
1239 if (!$count) {
1240 $statement = $this->connection->prepare(
1241 "INSERT INTO {$this->providerViewsTable}
1242 (`userId`, `date`, `views`)
1243 VALUES
1244 (:userId, :date, :views)"
1245 );
1246 } else {
1247 $statement = $this->connection->prepare(
1248 "UPDATE {$this->providerViewsTable} pv SET pv.views = pv.views + :views
1249 WHERE pv.userId = :userId
1250 AND pv.date = :date"
1251 );
1252 }
1253
1254 $response = $statement->execute($params);
1255 } catch (\Exception $e) {
1256 throw new QueryExecutionException('Unable to add data in ' . __CLASS__, $e->getCode(), $e);
1257 }
1258
1259 if (!$response) {
1260 throw new QueryExecutionException('Unable to add data in ' . __CLASS__);
1261 }
1262
1263 return true;
1264 }
1265
1266 /**
1267 *
1268 * @return array
1269 * @throws QueryExecutionException
1270 */
1271 public function getProvidersServices()
1272 {
1273 try {
1274 $statement = $this->connection->prepare(
1275 "SELECT
1276 u.id AS user_id,
1277 st.serviceId AS service_id,
1278 st.price AS service_price,
1279 st.customPricing AS service_customPricing,
1280 st.minCapacity AS service_minCapacity,
1281 st.maxCapacity AS service_maxCapacity
1282 FROM {$this->table} u
1283 INNER JOIN {$this->providerServicesTable} st ON st.userId = u.id
1284 WHERE u.type = :type
1285 ORDER BY CONCAT(u.firstName, ' ', u.lastName)"
1286 );
1287
1288 $type = AbstractUser::USER_ROLE_PROVIDER;
1289
1290 $statement->bindParam(':type', $type);
1291
1292 $statement->execute();
1293
1294 $rows = $statement->fetchAll();
1295 } catch (\Exception $e) {
1296 throw new QueryExecutionException('Unable to find by id in ' . __CLASS__, $e->getCode(), $e);
1297 }
1298
1299 $result = [];
1300
1301 foreach ($rows as $row) {
1302 $userId = (int)$row['user_id'];
1303
1304 $serviceId = (int)$row['service_id'];
1305
1306 if (!array_key_exists($userId, $result) || !array_key_exists($serviceId, $result[$userId])) {
1307 $result[$userId][$serviceId] = [
1308 'price' => $row['service_price'],
1309 'customPricing' => $row['service_customPricing'],
1310 'minCapacity' => (int)$row['service_minCapacity'],
1311 'maxCapacity' => (int)$row['service_maxCapacity'],
1312 ];
1313 }
1314 }
1315
1316 return $result;
1317 }
1318
1319 /** @noinspection MoreThanThreeArgumentsInspection */
1320 /**
1321 * @param array $row
1322 * @param array $providerRows
1323 * @param array $serviceRows
1324 * @param array $providerServiceRows
1325 *
1326 * @return void
1327 */
1328 private function parseUserRow($row, &$providerRows, &$serviceRows, &$providerServiceRows)
1329 {
1330 $userId = (int)$row['user_id'];
1331 $serviceId = isset($row['service_id']) ? (int)$row['service_id'] : null;
1332 $extraId = isset($row['extra_id']) ? $row['extra_id'] : null;
1333 $couponId = isset($row['coupon_id']) ? $row['coupon_id'] : null;
1334 $googleCalendarId = isset($row['google_calendar_id']) ? $row['google_calendar_id'] : null;
1335 $outlookCalendarId = isset($row['outlook_calendar_id']) ? $row['outlook_calendar_id'] : null;
1336 $weekDayId = isset($row['weekDay_id']) ? $row['weekDay_id'] : null;
1337 $timeOutId = isset($row['timeOut_id']) ? $row['timeOut_id'] : null;
1338 $periodId = isset($row['period_id']) ? $row['period_id'] : null;
1339 $periodServiceId = isset($row['periodService_id']) ? $row['periodService_id'] : null;
1340 $periodLocationId = isset($row['periodLocation_id']) ? $row['periodLocation_id'] : null;
1341 $specialDayId = isset($row['specialDay_id']) ? $row['specialDay_id'] : null;
1342 $specialDayPeriodId = isset($row['specialDayPeriod_id']) ? $row['specialDayPeriod_id'] : null;
1343 $specialDayPeriodServiceId = isset($row['specialDayPeriodService_id'])
1344 ? $row['specialDayPeriodService_id'] : null;
1345 $specialDayPeriodLocationId = isset($row['specialDayPeriodLocation_id'])
1346 ? $row['specialDayPeriodLocation_id'] : null;
1347 $dayOffId = isset($row['dayOff_id']) ? $row['dayOff_id'] : null;
1348
1349 if (!array_key_exists($userId, $providerRows)) {
1350 $providerRows[$userId] = [
1351 'id' => $userId,
1352 'type' => 'provider',
1353 'status' => isset($row['user_status']) ? $row['user_status'] : null,
1354 'externalId' => isset($row['external_id']) ? $row['external_id'] : null,
1355 'firstName' => $row['user_firstName'],
1356 'lastName' => $row['user_lastName'],
1357 'email' => $row['user_email'],
1358 'note' => isset($row['note']) ? $row['note'] : null,
1359 'description' => isset($row['description']) ? $row['description'] : null,
1360 'phone' => isset($row['phone']) ? $row['phone'] : null,
1361 'zoomUserId' => isset($row['user_zoom_user_id']) ? $row['user_zoom_user_id'] : null,
1362 'stripeConnect' => isset($row['user_stripeConnect']) ? $row['user_stripeConnect'] : null,
1363 'countryPhoneIso' => isset($row['user_countryPhoneIso']) ? $row['user_countryPhoneIso'] : null,
1364 'locationId' => isset($row['user_locationId']) ? $row['user_locationId'] : null,
1365 'pictureFullPath' => isset($row['picture_full_path']) ? $row['picture_full_path'] : null,
1366 'pictureThumbPath' => isset($row['picture_thumb_path']) ? $row['picture_thumb_path'] : null,
1367 'translations' => $row['user_translations'],
1368 'googleCalendar' => [],
1369 'weekDayList' => [],
1370 'dayOffList' => [],
1371 'specialDayList' => [],
1372 'serviceList' => [],
1373 'timeZone' => isset($row['user_timeZone']) ? $row['user_timeZone'] : null,
1374 'badgeId' => isset($row['badge_id']) ? $row['badge_id'] : null,
1375 'appleCalendarId' => isset($row['user_apple_calendar_id']) ? $row['user_apple_calendar_id'] : null,
1376 'employeeAppleCalendar' => isset($row['user_employee_apple_calendar']) ? $row['user_employee_apple_calendar'] : null,
1377 'show' => isset($row['user_show']) ? $row['user_show'] : 0,
1378 ];
1379 }
1380
1381 if (
1382 $googleCalendarId &&
1383 array_key_exists($userId, $providerRows) &&
1384 empty($providerRows[$userId]['googleCalendar'])
1385 ) {
1386 $providerRows[$userId]['googleCalendar']['id'] = $row['google_calendar_id'];
1387 $providerRows[$userId]['googleCalendar']['token'] = $row['google_calendar_token'];
1388 $providerRows[$userId]['googleCalendar']['calendarId'] = isset($row['google_calendar_calendar_id']) ? $row['google_calendar_calendar_id'] : null;
1389 }
1390
1391 if (
1392 $outlookCalendarId &&
1393 array_key_exists($userId, $providerRows) &&
1394 empty($providerRows[$userId]['outlookCalendar'])
1395 ) {
1396 $providerRows[$userId]['outlookCalendar']['id'] = $row['outlook_calendar_id'];
1397 $providerRows[$userId]['outlookCalendar']['token'] = $row['outlook_calendar_token'];
1398 $providerRows[$userId]['outlookCalendar']['calendarId'] = isset($row['outlook_calendar_calendar_id']) ? $row['outlook_calendar_calendar_id'] : null;
1399 }
1400
1401 if (
1402 $weekDayId &&
1403 array_key_exists($userId, $providerRows) &&
1404 !array_key_exists($weekDayId, $providerRows[$userId]['weekDayList'])
1405 ) {
1406 $providerRows[$userId]['weekDayList'][$weekDayId] = [
1407 'id' => $weekDayId,
1408 'dayIndex' => $row['weekDay_dayIndex'],
1409 'startTime' => $row['weekDay_startTime'],
1410 'endTime' => $row['weekDay_endTime'],
1411 'timeOutList' => [],
1412 'periodList' => [],
1413 ];
1414 }
1415
1416 if (
1417 $periodId &&
1418 $weekDayId &&
1419 array_key_exists($userId, $providerRows) &&
1420 array_key_exists($weekDayId, $providerRows[$userId]['weekDayList']) &&
1421 !array_key_exists($periodId, $providerRows[$userId]['weekDayList'][$weekDayId]['periodList'])
1422 ) {
1423 $providerRows[$userId]['weekDayList'][$weekDayId]['periodList'][$periodId] = [
1424 'id' => $periodId,
1425 'startTime' => $row['period_startTime'],
1426 'endTime' => $row['period_endTime'],
1427 'locationId' => $row['period_locationId'],
1428 'periodServiceList' => [],
1429 'periodLocationList' => [],
1430 ];
1431 }
1432
1433 if (
1434 $periodServiceId &&
1435 $periodId &&
1436 $weekDayId &&
1437 array_key_exists($userId, $providerRows) &&
1438 array_key_exists($weekDayId, $providerRows[$userId]['weekDayList']) &&
1439 array_key_exists($periodId, $providerRows[$userId]['weekDayList'][$weekDayId]['periodList']) &&
1440 !array_key_exists($periodServiceId, $providerRows[$userId]['weekDayList'][$weekDayId]['periodList'][$periodId]['periodServiceList'])
1441 ) {
1442 $providerRows[$userId]['weekDayList'][$weekDayId]['periodList'][$periodId]['periodServiceList'][$periodServiceId] = [
1443 'id' => $periodServiceId,
1444 'serviceId' => $row['periodService_serviceId'],
1445 ];
1446 }
1447
1448 if (
1449 $periodLocationId &&
1450 $periodId &&
1451 $weekDayId &&
1452 array_key_exists($userId, $providerRows) &&
1453 array_key_exists($weekDayId, $providerRows[$userId]['weekDayList']) &&
1454 array_key_exists($periodId, $providerRows[$userId]['weekDayList'][$weekDayId]['periodList']) &&
1455 !array_key_exists($periodLocationId, $providerRows[$userId]['weekDayList'][$weekDayId]['periodList'][$periodId]['periodLocationList'])
1456 ) {
1457 $providerRows[$userId]['weekDayList'][$weekDayId]['periodList'][$periodId]['periodLocationList'][$periodLocationId] = [
1458 'id' => $periodLocationId,
1459 'locationId' => $row['periodLocation_locationId'],
1460 ];
1461 }
1462
1463 if (
1464 $timeOutId &&
1465 $weekDayId &&
1466 array_key_exists($userId, $providerRows) &&
1467 array_key_exists($weekDayId, $providerRows[$userId]['weekDayList']) &&
1468 !array_key_exists($timeOutId, $providerRows[$userId]['weekDayList'][$weekDayId]['timeOutList'])
1469 ) {
1470 $providerRows[$userId]['weekDayList'][$weekDayId]['timeOutList'][$timeOutId] = [
1471 'id' => $timeOutId,
1472 'startTime' => $row['timeOut_startTime'],
1473 'endTime' => $row['timeOut_endTime'],
1474 ];
1475 }
1476
1477 if (
1478 $specialDayId &&
1479 array_key_exists($userId, $providerRows) &&
1480 !array_key_exists($specialDayId, $providerRows[$userId]['specialDayList'])
1481 ) {
1482 $providerRows[$userId]['specialDayList'][$specialDayId] = [
1483 'id' => $specialDayId,
1484 'startDate' => $row['specialDay_startDate'],
1485 'endDate' => $row['specialDay_endDate'],
1486 'periodList' => [],
1487 ];
1488 }
1489
1490 if (
1491 $specialDayPeriodId &&
1492 $specialDayId &&
1493 array_key_exists($userId, $providerRows) &&
1494 array_key_exists($specialDayId, $providerRows[$userId]['specialDayList']) &&
1495 !array_key_exists($specialDayPeriodId, $providerRows[$userId]['specialDayList'][$specialDayId]['periodList'])
1496 ) {
1497 $providerRows[$userId]['specialDayList'][$specialDayId]['periodList'][$specialDayPeriodId] = [
1498 'id' => $specialDayPeriodId,
1499 'startTime' => $row['specialDayPeriod_startTime'],
1500 'endTime' => $row['specialDayPeriod_endTime'],
1501 'locationId' => $row['specialDayPeriod_locationId'],
1502 'periodServiceList' => [],
1503 'periodLocationList' => [],
1504 ];
1505 }
1506
1507 if (
1508 $specialDayPeriodServiceId &&
1509 $specialDayPeriodId &&
1510 $specialDayId &&
1511 array_key_exists($userId, $providerRows) &&
1512 array_key_exists($specialDayId, $providerRows[$userId]['specialDayList']) &&
1513 array_key_exists($specialDayPeriodId, $providerRows[$userId]['specialDayList'][$specialDayId]['periodList']) &&
1514 !array_key_exists(
1515 $specialDayPeriodServiceId,
1516 $providerRows[$userId]['specialDayList'][$specialDayId]['periodList'][$specialDayPeriodId]['periodServiceList']
1517 )
1518 ) {
1519 $providerRows[$userId]['specialDayList'][$specialDayId]['periodList'][$specialDayPeriodId]['periodServiceList'][$specialDayPeriodServiceId] = [
1520 'id' => $specialDayPeriodServiceId,
1521 'serviceId' => $row['specialDayPeriodService_serviceId'],
1522 ];
1523 }
1524
1525 if (
1526 $specialDayPeriodLocationId &&
1527 $specialDayPeriodId &&
1528 $specialDayId &&
1529 array_key_exists($userId, $providerRows) &&
1530 array_key_exists($specialDayId, $providerRows[$userId]['specialDayList']) &&
1531 array_key_exists($specialDayPeriodId, $providerRows[$userId]['specialDayList'][$specialDayId]['periodList']) &&
1532 !array_key_exists(
1533 $specialDayPeriodLocationId,
1534 $providerRows[$userId]['specialDayList'][$specialDayId]['periodList'][$specialDayPeriodId]['periodLocationList']
1535 )
1536 ) {
1537 $providerRows[$userId]['specialDayList'][$specialDayId]['periodList'][$specialDayPeriodId]['periodLocationList'][$specialDayPeriodLocationId] = [
1538 'id' => $specialDayPeriodLocationId,
1539 'locationId' => $row['specialDayPeriodLocation_locationId'],
1540 ];
1541 }
1542
1543 if (
1544 $dayOffId &&
1545 array_key_exists($userId, $providerRows) &&
1546 !array_key_exists($dayOffId, $providerRows[$userId]['dayOffList'])
1547 ) {
1548 $providerRows[$userId]['dayOffList'][$dayOffId] = [
1549 'id' => $dayOffId,
1550 'name' => $row['dayOff_name'],
1551 'startDate' => $row['dayOff_startDate'],
1552 'endDate' => $row['dayOff_endDate'],
1553 'repeat' => $row['dayOff_repeat'],
1554 ];
1555 }
1556
1557 if (
1558 $serviceId &&
1559 !array_key_exists($serviceId, $serviceRows)
1560 ) {
1561 $serviceRows[$serviceId] = [
1562 'id' => $serviceId,
1563 'customPricing' => isset($row['service_customPricing']) ? $row['service_customPricing'] : null,
1564 'price' => $row['service_price'],
1565 'minCapacity' => $row['service_minCapacity'],
1566 'maxCapacity' => $row['service_maxCapacity'],
1567 'name' => isset($row['service_name']) ? $row['service_name'] : null,
1568 'description' => isset($row['service_description']) ? $row['service_description'] : null,
1569 'color' => isset($row['service_color']) ? $row['service_color'] : null,
1570 'status' => isset($row['service_status']) ? $row['service_status'] : null,
1571 'categoryId' => isset($row['service_categoryId']) ? (int)$row['service_categoryId'] : null,
1572 'duration' => isset($row['service_duration']) ? $row['service_duration'] : null,
1573 'bringingAnyone' => isset($row['service_bringingAnyone']) ? $row['service_bringingAnyone'] : null,
1574 'show' => isset($row['service_show']) ? $row['service_show'] : null,
1575 'aggregatedPrice' => isset($row['service_aggregatedPrice']) ? $row['service_aggregatedPrice'] : null,
1576 'pictureFullPath' => isset($row['service_picture_full']) ? $row['service_picture_full'] : null,
1577 'pictureThumbPath' => isset($row['service_picture_thumb']) ? $row['service_picture_thumb'] : null,
1578 'timeBefore' => isset($row['service_timeBefore']) ? $row['service_timeBefore'] : null,
1579 'timeAfter' => isset($row['service_timeAfter']) ? $row['service_timeAfter'] : null,
1580 'extras' => [],
1581 'coupons' => [],
1582 'settings' => isset($row['service_settings']) ? $row['service_settings'] : null,
1583 'recurringCycle' => isset($row['service_recurringCycle']) ? $row['service_recurringCycle'] : null,
1584 'recurringSub' => isset($row['service_recurringSub']) ? $row['service_recurringSub'] : null,
1585 'recurringPayment' => isset($row['service_recurringPayment']) ? $row['service_recurringPayment'] : null,
1586 'translations' => isset($row['service_translations']) ? $row['service_translations'] : null,
1587 'deposit' => isset($row['service_deposit']) ? $row['service_deposit'] : 0,
1588 'depositPayment' => isset($row['service_depositPayment']) ? $row['service_depositPayment'] : 'disabled',
1589 'depositPerPerson' => isset($row['service_depositPerPerson']) ? $row['service_depositPerPerson'] : 1,
1590 ];
1591 }
1592
1593 if (
1594 $extraId &&
1595 $serviceId &&
1596 array_key_exists($serviceId, $serviceRows) &&
1597 !array_key_exists($extraId, $serviceRows[$serviceId]['extras'])
1598 ) {
1599 $serviceRows[$serviceId]['extras'][$extraId] = [
1600 'id' => $extraId,
1601 'name' => $row['extra_name'],
1602 'price' => $row['extra_price'],
1603 'maxQuantity' => $row['extra_maxQuantity'],
1604 'position' => $row['extra_position'],
1605 'aggregatedPrice' => $row['extra_aggregatedPrice'],
1606 'description' => $row['extra_description']
1607 ];
1608 }
1609
1610 if (
1611 $couponId &&
1612 $serviceId &&
1613 array_key_exists($serviceId, $serviceRows) &&
1614 !array_key_exists($couponId, $serviceRows[$serviceId]['coupons'])
1615 ) {
1616 $serviceRows[$serviceId]['coupons'][$couponId] = [
1617 'id' => $couponId,
1618 'code' => $row['coupon_code'],
1619 'discount' => $row['coupon_discount'],
1620 'deduction' => $row['coupon_deduction'],
1621 'limit' => $row['coupon_limit'],
1622 'customerLimit' => $row['coupon_customerLimit'],
1623 'status' => $row['coupon_status']
1624 ];
1625 }
1626
1627 if ($serviceId && (!array_key_exists($userId, $providerServiceRows) || !array_key_exists($serviceId, $providerServiceRows[$userId]))) {
1628 $providerServiceRows[$userId][$serviceId] = [
1629 'price' => $row['service_price'],
1630 'customPricing' => $row['service_customPricing'],
1631 'minCapacity' => (int)$row['service_minCapacity'],
1632 'maxCapacity' => (int)$row['service_maxCapacity']
1633 ];
1634 }
1635 }
1636
1637 /**
1638 * @param int $userId
1639 *
1640 * @return mixed
1641 * @throws QueryExecutionException
1642 */
1643 public function deleteViewStats($userId)
1644 {
1645 $params = [
1646 ':userId' => $userId,
1647 ];
1648
1649 try {
1650 $statement = $this->connection->prepare(
1651 "DELETE FROM {$this->providerViewsTable} WHERE userId = :userId"
1652 );
1653
1654 return $statement->execute($params);
1655 } catch (\Exception $e) {
1656 throw new QueryExecutionException('Unable to delete data from ' . __CLASS__, $e->getCode(), $e);
1657 }
1658 }
1659 }
1660