SupportTicketController.php 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. <?php
  2. namespace App\Http\Controllers;
  3. use App\Services\SupportTicketService;
  4. use App\Http\Requests\SupportTicketRequest;
  5. use App\Http\Resources\SupportTicketResource;
  6. use Illuminate\Http\JsonResponse;
  7. class SupportTicketController extends Controller
  8. {
  9. public function __construct(
  10. protected SupportTicketService $service,
  11. ) {}
  12. public function index(): JsonResponse
  13. {
  14. $user = auth()->user();
  15. $query = \App\Models\SupportTicket::query()
  16. ->with(['applicantUnit', 'targetUnit'])
  17. ->orderBy('created_at', 'desc');
  18. if ($this->isMatriz($user)) {
  19. $query->where(fn($q) => $q->where('origin', '!=', 'unit')->orWhere('scope', '!=', 'internal'));
  20. } else {
  21. $query->visibleToUnit($user->units()->first()?->id);
  22. }
  23. return $this->successResponse(
  24. payload: SupportTicketResource::collection($query->get())
  25. );
  26. }
  27. public function store(SupportTicketRequest $request): JsonResponse
  28. {
  29. $data = $request->validated();
  30. $user = auth()->user();
  31. $isMatriz = $this->isMatriz($user);
  32. $data['origin'] = $isMatriz ? 'matriz' : 'unit';
  33. $data['applicant_user_id'] = $user->id;
  34. $data['responsable_user_id'] = $user->id;
  35. $data['applicant_unit_id'] = $isMatriz ? null : $user->units()->first()?->id;
  36. $data['status'] = 'in_progress';
  37. // Broadcast: Matriz para todas as unidades
  38. if ($isMatriz && ($data['scope'] ?? null) === 'all') {
  39. $batchId = (string) \Illuminate\Support\Str::uuid();
  40. $unitIds = \App\Models\Unit::query()->pluck('id');
  41. $created = [];
  42. foreach ($unitIds as $unitId) {
  43. $created[] = $this->service->create(array_merge($data, [
  44. 'target_unit_id' => $unitId,
  45. 'batch_id' => $batchId,
  46. ]));
  47. }
  48. return $this->successResponse(
  49. payload: SupportTicketResource::collection($created),
  50. message: __('messages.created'),
  51. code: 201
  52. );
  53. }
  54. // Resolução de target_unit_id por cenário
  55. if ($isMatriz) {
  56. if (($data['scope'] ?? null) === 'internal') {
  57. $data['target_unit_id'] = null;
  58. }
  59. // scope='specific' → target_unit_id já veio do request
  60. } else {
  61. // Franchisee
  62. $data['target_unit_id'] = (($data['scope'] ?? null) === 'internal')
  63. ? $user->units()->first()?->id
  64. : null; // 'specific' do Franchisee = "para Matriz"
  65. }
  66. $item = $this->service->create($data);
  67. return $this->successResponse(
  68. payload: new SupportTicketResource($item),
  69. message: __('messages.created'),
  70. code: 201
  71. );
  72. }
  73. public function show(int $id): JsonResponse
  74. {
  75. $item = $this->service->findById($id);
  76. return $this->successResponse(payload: new SupportTicketResource($item));
  77. }
  78. public function update(SupportTicketRequest $request, int $id): JsonResponse
  79. {
  80. $user = auth()->user();
  81. $item = $this->service->findById($id);
  82. if (!$this->canManage($user, $item)) {
  83. return $this->errorResponse(message: __('messages.unauthorized'), code: 403);
  84. }
  85. $item = $this->service->update($id, $request->validated());
  86. return $this->successResponse(payload: new SupportTicketResource($item), message: __('messages.updated'));
  87. }
  88. public function destroy(int $id): JsonResponse
  89. {
  90. $user = auth()->user();
  91. $item = $this->service->findById($id);
  92. if (!$this->canManage($user, $item)) {
  93. return $this->errorResponse(message: __('messages.unauthorized'), code: 403);
  94. }
  95. $this->service->delete($id);
  96. return $this->successResponse(message: __('messages.deleted'), code: 204);
  97. }
  98. private function isMatriz(\App\Models\User $user): bool
  99. {
  100. return $user->user_type === 'ADMIN';
  101. }
  102. private function canManage(\App\Models\User $user, \App\Models\SupportTicket $ticket): bool
  103. {
  104. if ($this->isMatriz($user)) {
  105. return true;
  106. }
  107. // Franchisee só pode gerenciar tickets internos que ela mesma criou
  108. return $ticket->origin === 'unit'
  109. && $ticket->scope === 'internal'
  110. && $ticket->applicant_unit_id === $user->units()->first()?->id;
  111. }
  112. }