AppointmentController.php 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. <?php
  2. namespace App\Http\Controllers;
  3. use App\Http\Requests\AppointmentApproveRequest;
  4. use App\Http\Requests\AppointmentRequest;
  5. use App\Http\Resources\AppointmentResource;
  6. use App\Models\Appointment;
  7. use App\Services\AppointmentGuideService;
  8. use App\Services\AppointmentService;
  9. use App\Enums\AppointmentStatusEnum;
  10. use App\Enums\UserStatusEnum;
  11. use Illuminate\Http\JsonResponse;
  12. use Illuminate\Http\Request;
  13. use Illuminate\Http\Response;
  14. use Illuminate\Support\Facades\Auth;
  15. class AppointmentController extends Controller
  16. {
  17. public function __construct(
  18. protected AppointmentService $service,
  19. protected AppointmentGuideService $guideService,
  20. ) {}
  21. public function index(): JsonResponse
  22. {
  23. $items = $this->service->getAll();
  24. return $this->successResponse(payload: AppointmentResource::collection($items));
  25. }
  26. public function myAppointments(): JsonResponse
  27. {
  28. $items = $this->service->getAllByUser(Auth::id());
  29. return $this->successResponse(payload: AppointmentResource::collection($items));
  30. }
  31. public function partnerAppointments(): JsonResponse
  32. {
  33. $items = $this->service->getAllByPartnerUser(Auth::id());
  34. return $this->successResponse(payload: AppointmentResource::collection($items));
  35. }
  36. public function getByUser(int $id): JsonResponse
  37. {
  38. $items = $this->service->getAllByUser($id);
  39. return $this->successResponse(payload: AppointmentResource::collection($items));
  40. }
  41. public function store(AppointmentRequest $request): JsonResponse
  42. {
  43. $data = $request->validated();
  44. $authUser = Auth::user();
  45. $creatingForOther = isset($data['user_id']) && (int) $data['user_id'] !== $authUser->id;
  46. if ($creatingForOther) {
  47. $data['status'] = AppointmentStatusEnum::CONFIRMADO;
  48. $data['auto_approved'] = true;
  49. } elseif ($authUser->status === UserStatusEnum::ACTIVE) {
  50. $data['status'] = AppointmentStatusEnum::CONFIRMADO;
  51. $data['auto_approved'] = true;
  52. }
  53. $item = $this->service->create($data);
  54. if ($creatingForOther) {
  55. $this->service->notifyCreation($item);
  56. }
  57. return $this->successResponse(
  58. payload: new AppointmentResource($item),
  59. message: __('messages.created'),
  60. code: 201,
  61. );
  62. }
  63. public function show(int $id): JsonResponse
  64. {
  65. $item = $this->service->findById($id);
  66. return $this->successResponse(payload: new AppointmentResource($item));
  67. }
  68. public function update(AppointmentRequest $request, int $id): JsonResponse
  69. {
  70. $item = $this->service->update($id, $request->validated(), Auth::id());
  71. return $this->successResponse(
  72. payload: new AppointmentResource($item),
  73. message: __('messages.updated'),
  74. );
  75. }
  76. public function destroy(int $id): JsonResponse
  77. {
  78. $this->service->delete($id);
  79. return $this->successResponse(message: __('messages.deleted'), code: 204);
  80. }
  81. public function getAdminCounters(): JsonResponse
  82. {
  83. return $this->successResponse(payload: $this->service->getAdminCounters());
  84. }
  85. public function getAdminAppointmentsPaginated(Request $request): JsonResponse
  86. {
  87. $filters = $request->only(['status', 'search']);
  88. $perPage = (int) $request->input('per_page', 10);
  89. $paginator = $this->service->getAllPaginated($filters, $perPage);
  90. $items = collect($paginator->items())->map(fn($a) => [
  91. 'id' => $a->id,
  92. 'order_number' => $a->order_number,
  93. 'registration' => $a->user?->registration,
  94. 'user_name' => $a->user?->name,
  95. 'dependent_name' => $a->userDependent?->name,
  96. 'is_for_dependent' => $a->user_dependent_id !== null,
  97. 'partner_name' => $a->partnerAgreement?->company_name,
  98. 'service_name' => $a->partnerAgreementService?->name,
  99. 'requested_at' => $a->requested_at?->format('d/m/Y'),
  100. 'status' => $a->status?->value,
  101. 'can_issue_guide' => $this->guideService->canIssue($a),
  102. ]);
  103. return $this->successResponse(payload: [
  104. 'data' => $items,
  105. 'total' => $paginator->total(),
  106. 'per_page' => $paginator->perPage(),
  107. 'current_page' => $paginator->currentPage(),
  108. 'from' => $paginator->firstItem(),
  109. 'to' => $paginator->lastItem(),
  110. ]);
  111. }
  112. public function approve(AppointmentApproveRequest $request, int $id): JsonResponse
  113. {
  114. $item = $this->service->approve($id, $request->date, $request->time, Auth::id());
  115. return $this->successResponse(payload: new AppointmentResource($item), message: __('messages.updated'));
  116. }
  117. public function reject(int $id): JsonResponse
  118. {
  119. $item = $this->service->reject($id);
  120. return $this->successResponse(payload: new AppointmentResource($item), message: __('messages.updated'));
  121. }
  122. public function approveByPartner(AppointmentApproveRequest $request, int $id): JsonResponse
  123. {
  124. $item = $this->service->approveByPartner($id, Auth::id(), $request->date, $request->time);
  125. if (!$item) return $this->errorResponse(message: __('messages.not_found'), code: 404);
  126. return $this->successResponse(payload: new AppointmentResource($item), message: __('messages.updated'));
  127. }
  128. public function rejectByPartner(int $id): JsonResponse
  129. {
  130. $item = $this->service->rejectByPartner($id, Auth::id());
  131. if (!$item) return $this->errorResponse(message: __('messages.not_found'), code: 404);
  132. return $this->successResponse(payload: new AppointmentResource($item), message: __('messages.updated'));
  133. }
  134. public function guide(int $id): Response|JsonResponse
  135. {
  136. return $this->buildGuide($this->service->findById($id));
  137. }
  138. public function myGuide(int $id): Response|JsonResponse
  139. {
  140. $item = $this->service->findById($id);
  141. if ($item && $item->user_id !== Auth::id()) {
  142. return $this->errorResponse(message: __('messages.unauthorized'), code: 403);
  143. }
  144. return $this->buildGuide($item);
  145. }
  146. public function partnerGuide(int $id): Response|JsonResponse
  147. {
  148. $item = $this->service->findByIdForPartnerUser($id, Auth::id());
  149. return $this->buildGuide($item);
  150. }
  151. private function buildGuide(?Appointment $appointment): Response|JsonResponse
  152. {
  153. if (!$appointment) {
  154. return $this->errorResponse(message: __('messages.not_found'), code: 404);
  155. }
  156. if (!$this->guideService->canIssue($appointment)) {
  157. return $this->errorResponse(message: __('messages.guide_unavailable'), code: 422);
  158. }
  159. return $this->guideService
  160. ->pdf($appointment, Auth::id())
  161. ->download($this->guideService->fileName($appointment));
  162. }
  163. }