SupportTicketController.php 4.5 KB

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