json(['ok' => true, 'plans' => $this->service->list($request->query())]); } public function store(InstallmentPlanRequest $request, int $invoice): JsonResponse { return response()->json(['ok' => true, 'plan' => $this->service->createForInvoice($invoice, $request->validated(), optional($request->user())->id)], 201); } public function show(int $plan): JsonResponse { return response()->json(['ok' => true, 'plan' => $this->service->show($plan)]); } public function activate(Request $request, int $plan): JsonResponse { return response()->json(['ok' => true, 'plan' => $this->service->activate($plan, optional($request->user())->id)]); } public function cancel(int $plan): JsonResponse { return response()->json(['ok' => true, 'plan' => $this->service->cancel($plan)]); } public function restructure(InstallmentPlanRequest $request, int $plan): JsonResponse { $old = $this->service->cancel($plan); return response()->json(['ok' => true, 'old_plan' => $old, 'message' => 'Old plan cancelled. Create a replacement plan against the invoice to preserve audit history.']); } public function allocatePayment(PaymentAllocationRequest $request, int $payment): JsonResponse { return response()->json(['ok' => true, 'result' => $this->service->allocatePayment($payment, $request->validated())]); } public function due(): JsonResponse { return response()->json(['ok' => true, 'installments' => $this->service->due(false)]); } public function overdue(): JsonResponse { $this->service->markOverdue(); return response()->json(['ok' => true, 'installments' => $this->service->due(true)]); } }