json(['error' => false, 'data' => $this->payload(Invoice::with('customer')->findOrFail($id))]); } public function update(Request $request, int $id): JsonResponse { $invoice = Invoice::with('customer')->findOrFail($id); $data = $request->validate([ 'vat_serial' => 'nullable|string|max:20|required_with:vat_number', 'vat_number' => [ 'nullable', 'string', 'max:30', 'required_with:vat_serial', Rule::unique('invoices', 'vat_number') ->where('vat_serial', $request->input('vat_serial')) ->ignore($invoice->id), ], 'vat_issued_at' => 'nullable|date|required_with:vat_number', 'refresh_buyer' => 'sometimes|boolean', ]); $invoice->fill([ 'vat_serial' => $data['vat_serial'] ?? null, 'vat_number' => $data['vat_number'] ?? null, 'vat_issued_at' => $data['vat_issued_at'] ?? null, ]); if (!$invoice->vat_number) { $invoice->buyer_snapshot = null; } elseif (!$invoice->buyer_snapshot || ($data['refresh_buyer'] ?? false)) { $invoice->buyer_snapshot = InvoiceBuyer::fromCustomer($invoice->customer); } $invoice->save(); return response()->json(['error' => false, 'message' => 'Đã lưu thông tin hóa đơn VAT', 'data' => $this->payload($invoice)]); } public function issue(int $id): JsonResponse { $invoice = Invoice::findOrFail($id); if ($invoice->vat_number) { return response()->json(['error' => true, 'message' => 'Hóa đơn đã có số VAT'], 422); } if ((int) $invoice->status === InvoiceStatus::CANCELLED->value) { return response()->json(['error' => true, 'message' => 'Không thể cấp số VAT cho hóa đơn đã huỷ'], 422); } $invoice = VatNumbering::issue($invoice); return response()->json(['error' => false, 'message' => 'Đã cấp số hóa đơn VAT', 'data' => $this->payload($invoice)]); } private function payload(Invoice $invoice): array { return [ 'lookup_code' => $invoice->lookup_code, 'vat_serial' => $invoice->vat_serial, 'vat_number' => $invoice->vat_number, 'vat_issued_at' => $invoice->vat_issued_at?->toDateString(), 'buyer' => InvoiceBuyer::forInvoice($invoice), 'buyer_locked' => (bool) $invoice->buyer_snapshot, ]; } }