validateAllocation($request); return response()->json([ 'error' => false, 'data' => $allocation->previewAllocation($data['ids'], $this->allocationCustomer($data), $data), ]); } public function allocate(Request $request, IpAllocationService $allocation): JsonResponse { $data = $this->validateAllocation($request); $count = $allocation->allocate($data['ids'], $this->allocationCustomer($data), $data, $request->user('admin')); return response()->json(['error' => false, 'message' => "Đã cấp phát {$count} IP và gửi email cho khách hàng"]); } public function revocationPreview(Request $request, IpAllocationService $allocation): JsonResponse { $data = $this->validateRevocation($request); return response()->json(['error' => false, 'data' => $allocation->previewRevocation($data['ids'], $data)]); } public function revoke(Request $request, IpAllocationService $allocation): JsonResponse { $data = $this->validateRevocation($request, withRecipients: true); $recipients = collect($data['recipients'])->keyBy('key')->all(); $count = $allocation->revoke($data['ids'], $data, $recipients, $request->user('admin')); return response()->json(['error' => false, 'message' => "Đã thu hồi {$count} IP và gửi email thông báo"]); } public function logs(int $id): JsonResponse { $pool = IpPool::withTrashed()->findOrFail($id); return response()->json([ 'error' => false, 'data' => $pool->logs()->with('user:id,username,fullname')->limit(200)->get(), ]); } private function validateAllocation(Request $request): array { return $request->validate([ 'ids' => 'required|array|min:1|max:1000', 'ids.*' => 'integer', 'customer_uuid' => 'required|string|exists:customers,uuid', 'to' => ['required', 'string', 'max:1000', $this->multiEmailRule()], 'cc' => ['nullable', 'string', 'max:1000', $this->multiEmailRule()], 'date' => 'required|date', 'service_name' => 'nullable|string|max:255', 'services' => 'nullable|array', 'services.*' => 'nullable|string|max:255', 'note' => 'nullable|string|max:2000', 'subject' => 'nullable|string|max:255', ...MailAttachments::rules(), ]); } private function validateRevocation(Request $request, bool $withRecipients = false): array { return $request->validate([ 'ids' => 'required|array|min:1|max:1000', 'ids.*' => 'integer', 'date' => 'required|date', 'note' => 'nullable|string|max:2000', 'recipients' => $withRecipients ? 'required|array|min:1' : 'prohibited', 'recipients.*.key' => 'required|string', 'recipients.*.to' => ['nullable', 'string', 'max:1000', $this->multiEmailRule()], 'recipients.*.cc' => ['nullable', 'string', 'max:1000', $this->multiEmailRule()], 'recipients.*.subject' => 'nullable|string|max:255', ]); } private function allocationCustomer(array $data): Customer { return Customer::where('uuid', $data['customer_uuid'])->firstOrFail(); } }