MeetService.php
1 <?php 2 3 namespace App\Http\Services; 4 5 use App\Enums\MeetClassEnum; 6 use App\Enums\MeetTypeEnum; 7 use App\Enums\StatusEnum; 8 use App\Events\ParticipantsAddedToMeetEvent; 9 use App\Models\Dossier; 10 use App\Models\Meet; 11 use App\Models\MeetCheck; 12 use App\Models\MeetCheckTemplate; 13 use App\Models\Task; 14 use Exception; 15 use Illuminate\Contracts\Pagination\LengthAwarePaginator; 16 use Illuminate\Database\Eloquent\Builder; 17 use Illuminate\Support\Collection; 18 use Illuminate\Support\Facades\DB; 19 use Log; 20 21 class MeetService 22 { 23 /** 24 * Display a listing of the resource. 25 * 26 * @param int $meetId 27 * @return Meet|null 28 */ 29 public static function find(int $meetId): ?Meet 30 { 31 return Meet::where('id', $meetId)->first(); 32 } 33 34 /** 35 * Display a listing of the resource. 36 * 37 * @param int $dossierId 38 * @return LengthAwarePaginator 39 */ 40 public static function index(int $dossierId) 41 { 42 return Meet::where('dossier_id', $dossierId)->orderBy('name', 'asc')->paginate(10); 43 } 44 45 /** 46 * Display a listing of the resource. 47 * 48 * @param Meet $meet 49 * @return LengthAwarePaginator 50 */ 51 public static function participants(Meet $meet): LengthAwarePaginator 52 { 53 return $meet->participants() 54 ->orderBy('created_at', 'desc') 55 ->paginate(5, ['*'], 'participantsPage'); 56 } 57 58 /** 59 * Create search query for resources 60 * 61 * @param int $dossierId 62 * @param string $searchString 63 * @param string $sortField 64 * @param string $sortDirection 65 * @param array|null $filters 66 * @return Builder 67 */ 68 public static function searchMeets(int $dossierId, string $searchString, string $sortField, string $sortDirection, array|null $filters): Builder 69 { 70 /* 71 match ($filter) { 72 'All' => $meetsQuery = Meet::withTrashed(), 73 'Disabled' => $meetsQuery = Meet::onlyTrashed(), 74 'Active' => $meetsQuery = Meet::query(), 75 default => $meetsQuery = Meet::query(), 76 }; 77 */ 78 $meetsQuery = Meet::query() 79 ->where('dossier_id', $dossierId); 80 81 if ($filters && $filters['withTrashed']) { 82 $meetsQuery->withTrashed(); 83 } 84 85 $meetsQuery 86 ->where(function ($query) use ($searchString) { 87 $query->where('name', 'like', '%' . $searchString . '%'); 88 }); 89 90 if ($filters && $filters['created_at_since']) { 91 $meetsQuery->where('created_at', '>=', $filters['created_at_since']); 92 } 93 94 if ($filters && $filters['created_at_to']) { 95 $meetsQuery->where('created_at', '<=', $filters['created_at_to']); 96 } 97 98 if ($filters && $filters['status']) { 99 $meetsQuery->whereIn('meet_status_id', $filters['status']); 100 } 101 102 if ($sortField && $sortDirection) { 103 $meetsQuery->orderBy($sortField, $sortDirection); 104 } 105 106 return $meetsQuery; 107 } 108 109 /** 110 * Create a resource 111 * 112 * @param array $meetData 113 * @param array $relation 114 * @return bool|Exception 115 * @throws \Throwable 116 */ 117 public static function create(array $meetData, array $participants): Meet 118 { 119 try { 120 DB::beginTransaction(); 121 $meet = Meet::create($meetData); 122 $meet->participants()->sync($participants); 123 if ($participants) 124 ParticipantsAddedToMeetEvent::dispatch($meet); 125 126 $meet->save(); 127 128 $meet = self::addCheckList($meet); 129 130 if (self::needsFormTask($meet)) { 131 $userId = $meet->dossier->principalCertifier?->id; 132 $stageId = $meet->dossier->stage->id; 133 TaskService::createSendPreResolutionHearingForm($userId, $stageId); 134 } 135 136 DB::commit(); 137 138 return $meet; 139 } catch (Exception $e) { 140 DB::rollBack(); 141 logger()->error($e->getMessage()); 142 throw $e; 143 } 144 } 145 146 private static function needsFormTask(Meet $meet): bool 147 { 148 if ($meet->class !== MeetClassEnum::email()->value) { 149 return false; 150 } 151 152 if ($meet->meet_type_id !== MeetTypeEnum::estimationHearingMeeting()->value) { 153 return false; 154 } 155 156 return true; 157 } 158 159 public static function addCheckList(Meet $meet): Meet 160 { 161 $checkTemplates = MeetCheckTemplate::where('meet_type_id', $meet->meet_type_id)->get(); 162 163 foreach ($checkTemplates as $checkTemplate) { 164 $meet->meetChecks()->create([ 165 'meet_check_template_id' => $checkTemplate->id, 166 'requirement' => $checkTemplate->requirement, 167 'pass' => false, 168 'rationale' => '', 169 'point' => $checkTemplate->point, 170 ]); 171 } 172 return $meet; 173 } 174 175 /** 176 * Update a resource 177 * 178 * @param array $data 179 * @param int $meetId 180 * @return true 181 * @throws \Throwable 182 */ 183 public static function update(Meet $meet, array $data, array $participants): Meet 184 { 185 DB::beginTransaction(); 186 187 try { 188 $meet->update($data); 189 $meet->save(); 190 $meet->participants()->sync($participants); 191 } catch (Exception $e) { 192 DB::rollBack(); 193 logger()->error($e->getMessage()); 194 throw new Exception(__('meets.meet.notifications.update.error.message')); 195 } 196 197 DB::commit(); 198 return $meet; 199 } 200 201 /** 202 * Destroy a resource 203 * @param int $meetId 204 * @return true 205 * @throws \Throwable 206 */ 207 208 public static function remove(int $meetId) 209 { 210 try { 211 212 DB::beginTransaction(); 213 Meet::destroy($meetId); 214 DB::commit(); 215 216 return true; 217 } catch (Exception $e) { 218 DB::rollBack(); 219 throw new Exception(__('meets.meet.notifications.remove.error.message')); 220 } 221 } 222 223 public static function restore(int $meetId) 224 { 225 try { 226 DB::beginTransaction(); 227 228 Meet::withTrashed()->find($meetId)->restore(); 229 230 DB::commit(); 231 } catch (Exception $e) { 232 DB::rollBack(); 233 throw new Exception(__('meets.meet.notifications.restore.error.message')); 234 } 235 } 236 237 public static function getStatusMessage($statusId) 238 { 239 return match ($statusId) { 240 StatusEnum::pending()->value => __('meets.meet.cards.actions.statuses.finished'), 241 StatusEnum::finished()->value => __('meets.meet.cards.actions.statuses.pending'), 242 default => "", 243 }; 244 } 245 246 public static function addParticipants(array $data) 247 { 248 try { 249 250 DB::beginTransaction(); 251 252 $meet = Meet::findOrFail($data['meet_id']); 253 $meet->participants()->sync($data['users_id']); 254 if ($data['users_id']) 255 ParticipantsAddedToMeetEvent::dispatch($meet); 256 257 DB::commit(); 258 259 return true; 260 } catch (Exception $e) { 261 DB::rollBack(); 262 //throw new Exception($e->getMessage()); 263 logger($e); 264 throw new Exception(__('meets.participant.notifications.create.error.message')); 265 } 266 } 267 268 public static function removeParticipant(int $meetsUsersId) 269 { 270 try { 271 272 DB::beginTransaction(); 273 $meet = DB::table('meet_user')->find($meetsUsersId); 274 275 if ($meet) { 276 DB::table('meet_user')->where('id', $meet->id)->delete(); 277 } 278 279 DB::commit(); 280 281 return true; 282 } catch (Exception $e) { 283 DB::rollBack(); 284 //throw new Exception($e->getMessage()); 285 throw new Exception(__('meets.participant.notifications.remove.error.message')); 286 } 287 } 288 289 public static function getMeetCheck(int $meetCheckId) 290 { 291 return MeetCheck::find($meetCheckId); 292 } 293 294 public static function createMeetCheck(array $data, int $meetId) 295 { 296 try { 297 298 DB::beginTransaction(); 299 300 $lastPoint = MeetCheck::where('meet_id', $meetId)->latest('id')->first()?->point; 301 302 MeetCheck::create([ 303 'meet_id' => $meetId, 304 'meet_check_template_id' => null, 305 'requirement' => $data['requirement'], 306 'rationale' => $data['rationale'], 307 'pass' => $data['pass'], 308 'point' => self::generatePoint($lastPoint), 309 ]); 310 311 DB::commit(); 312 313 return true; 314 } catch (Exception $e) { 315 DB::rollBack(); 316 Log::error($e); 317 //throw new Exception($e->getMessage()); 318 throw new Exception(__('meets.meet-check.notifications.create.error.message')); 319 } 320 } 321 322 public static function updateMeetCheck(array $data, int $meetCheckId) 323 { 324 try { 325 326 DB::beginTransaction(); 327 $meetCheck = MeetCheck::find($meetCheckId); 328 $meetCheck->rationale = $data['rationale']; 329 $meetCheck->pass = $data['pass']; 330 $meetCheck->save(); 331 332 DB::commit(); 333 334 return true; 335 } catch (Exception $e) { 336 DB::rollBack(); 337 Log::error($e); 338 //throw new Exception($e->getMessage()); 339 throw new Exception(__('meets.meet-check.notifications.update.error.message')); 340 } 341 } 342 343 public static function generatePoint(?string $lastPoint): string 344 { 345 if (empty($lastPoint)) { 346 return 'a'; 347 } 348 349 $length = strlen($lastPoint); 350 $lastChar = $lastPoint[$length - 1]; 351 352 if ($lastChar !== 'z') { 353 return substr($lastPoint, 0, $length - 1) . ++$lastChar; 354 } 355 356 $nextPoint = str_repeat('a', $length + 1); 357 for ($i = $length - 1; $i >= 0; $i--) { 358 if ($lastPoint[$i] === 'z') { 359 $nextPoint[$i] = 'a'; 360 } else { 361 $nextPoint[$i] = ++$lastPoint[$i]; 362 break; 363 } 364 } 365 366 return $nextPoint; 367 } 368 }