Lines
94.44%
68 / 72
Methods
66.66%
6 / 9
Classes
0.00%
0 / 1
| Name | Lines | Methods | CRAP | ||||
|---|---|---|---|---|---|---|---|
| __construct | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | ||
| processConfirm | 91.30% | 21 / 23 | 0.00% | 0 / 1 | 10.07 | ||
| extractClientData | 100.00% | 15 / 15 | 100.00% | 1 / 1 | 11 | ||
| isRebookingConfirm | 100.00% | 2 / 2 | 100.00% | 1 / 1 | 2 | ||
| validateClientData | 100.00% | 4 / 4 | 100.00% | 1 / 1 | 3 | ||
| loadSourceProcessForRebooking | 100.00% | 7 / 7 | 100.00% | 1 / 1 | 2 | ||
| getReservedProcess | 92.30% | 12 / 13 | 0.00% | 0 / 1 | 3.00 | ||
| confirmProcess | 80.00% | 4 / 5 | 0.00% | 0 / 1 | 3.07 | ||
| sendConfirmationEmail | 100.00% | 2 / 2 | 100.00% | 1 / 1 | 1 | ||
| 14 | class AppointmentConfirmService | |
| 15 | { | |
| 16 | private CaptchaService $captchaService; | |
| 17 | ||
| 18 | public function __construct() | |
| 19 | { | |
| 20 | $this->captchaService = new CaptchaService(); | |
| 21 | } | |
| 22 | ||
| 23 | public function processConfirm(array $body, ?AuthenticatedUser $authenticatedUser): ThinnedProcess|array | |
| 24 | { | |
| 25 | $clientData = $this->extractClientData($body); | |
| 26 | $errors = $this->validateClientData($clientData); | |
| 27 | if (!empty($errors['errors'])) { | |
| 28 | return $errors; | |
| 29 | } | |
| 30 | ||
| 31 | $sourceProcess = $this->loadSourceProcessForRebooking($clientData); | |
| 32 | if (is_array($sourceProcess) && ($sourceProcess['errors'] ?? []) !== []) { | |
| 33 | return $sourceProcess; | |
| 34 | } | |
| 35 | ||
| 36 | $reservedProcess = $this->getReservedProcess( | |
| 37 | $clientData->processId, | |
| 38 | $clientData->authKey, | |
| 39 | $authenticatedUser, | |
| 40 | $sourceProcess instanceof ThinnedProcess ? $sourceProcess : null | |
| 41 | ); | |
| 42 | if (is_array($reservedProcess) && !empty($reservedProcess['errors'])) { | |
| 43 | return $reservedProcess; | |
| 44 | } | |
| 45 | ||
| 46 | // Todo: check if the email template confirmed exists for the scope before submitting and sending | |
| 47 | $result = $this->confirmProcess($reservedProcess); | |
| 48 | if (is_array($result) && !empty($result['errors'])) { | |
| 49 | return $result; | |
| 50 | } | |
| 51 | ||
| 52 | $token = $this->captchaService->generateToken(); | |
| 53 | $result->setCaptchaToken($token); | |
| 54 | ||
| 55 | if ($result->status === 'confirmed') { | |
| 56 | $this->sendConfirmationEmail($result); | |
| 57 | } | |
| 58 | ||
| 59 | return $result; | |
| 60 | } | |
| 61 | ||
| 62 | ||
| 63 | private function extractClientData(array $body): object | |
| 64 | { | |
| 65 | return (object) [ | |
| 66 | 'processId' => isset($body['processId']) && is_numeric($body['processId']) | |
| 67 | ? (int) $body['processId'] | |
| 68 | : null, | |
| 69 | 'authKey' => isset($body['authKey']) && is_string($body['authKey']) && trim($body['authKey']) !== '' | |
| 70 | ? htmlspecialchars(trim($body['authKey']), ENT_QUOTES, 'UTF-8') | |
| 71 | : null, | |
| 72 | 'sourceProcessId' => isset($body['sourceProcessId']) && is_numeric($body['sourceProcessId']) | |
| 73 | ? (int) $body['sourceProcessId'] | |
| 74 | : null, | |
| 75 | 'sourceAuthKey' => isset($body['sourceAuthKey']) && is_string($body['sourceAuthKey']) | |
| 76 | && trim($body['sourceAuthKey']) !== '' | |
| 77 | ? htmlspecialchars(trim($body['sourceAuthKey']), ENT_QUOTES, 'UTF-8') | |
| 78 | : null, | |
| 79 | ]; | |
| 80 | } | |
| 81 | ||
| 82 | private function isRebookingConfirm(object $data): bool | |
| 83 | { | |
| 84 | return ($data->sourceProcessId ?? null) !== null | |
| 85 | && ($data->sourceAuthKey ?? null) !== null; | |
| 86 | } | |
| 87 | ||
| 88 | private function validateClientData(object $data): array | |
| 89 | { | |
| 90 | $errors = ValidationService::validateGetProcessById($data->processId, $data->authKey); | |
| 91 | if ($errors['errors'] !== [] || !$this->isRebookingConfirm($data)) { | |
| 92 | return $errors; | |
| 93 | } | |
| 94 | ||
| 95 | return ValidationService::validateGetProcessById($data->sourceProcessId, $data->sourceAuthKey); | |
| 96 | } | |
| 97 | ||
| 98 | /** | |
| 99 | * @return ThinnedProcess|array{errors: array}|null | |
| 100 | */ | |
| 101 | private function loadSourceProcessForRebooking(object $clientData): ThinnedProcess|array|null | |
| 102 | { | |
| 103 | if (!$this->isRebookingConfirm($clientData)) { | |
| 104 | return null; | |
| 105 | } | |
| 106 | ||
| 107 | return ZmsApiFacadeService::getThinnedProcessById( | |
| 108 | $clientData->sourceProcessId, | |
| 109 | $clientData->sourceAuthKey, | |
| 110 | null | |
| 111 | ); | |
| 112 | } | |
| 113 | ||
| 114 | private function getReservedProcess( | |
| 115 | int $processId, | |
| 116 | ?string $authKey, | |
| 117 | ?AuthenticatedUser $user, | |
| 118 | ?ThinnedProcess $sourceProcess | |
| 119 | ): ThinnedProcess|array { | |
| 120 | $process = ZmsApiFacadeService::getProcessById($processId, $authKey, $user); | |
| 121 | $notFound = ValidationService::validateGetProcessNotFound($process); | |
| 122 | if (!empty($notFound['errors'])) { | |
| 123 | return $notFound; | |
| 124 | } | |
| 125 | ||
| 126 | $thinned = MapperService::processToThinnedProcess($process); | |
| 127 | $confirmErrors = ValidationService::validateAppointmentConfirm( | |
| 128 | $thinned, | |
| 129 | $process->getExternalUserId(), | |
| 130 | $sourceProcess | |
| 131 | ); | |
| 132 | if ($confirmErrors['errors'] !== []) { | |
| 133 | return $confirmErrors; | |
| 134 | } | |
| 135 | ||
| 136 | return $thinned; | |
| 137 | } | |
| 138 | ||
| 139 | private function confirmProcess(ThinnedProcess $process): ThinnedProcess|array | |
| 140 | { | |
| 141 | $processEntity = MapperService::thinnedProcessToProcess($process); | |
| 142 | $result = ZmsApiFacadeService::confirmAppointment($processEntity); | |
| 143 | if (is_array($result) && !empty($result['errors'])) { | |
| 144 | return $result; | |
| 145 | } | |
| 146 | ||
| 147 | return MapperService::processToThinnedProcess($result); | |
| 148 | } | |
| 149 | ||
| 150 | private function sendConfirmationEmail(ThinnedProcess $process): void | |
| 151 | { | |
| 152 | $processEntity = MapperService::thinnedProcessToProcess($process); | |
| 153 | ZmsApiFacadeService::sendConfirmationEmail($processEntity); | |
| 154 | } | |
| 155 | } |