has('invoice_id')) { $query->where('invoice_id', $request->invoice_id); } if ($request->has('patient_id')) { $query->whereHas('invoice', function ($q) use ($request) { $q->where('patient_id', $request->patient_id); }); } if ($request->has('date_from')) { $query->whereDate('payment_date', '>=', $request->date_from); } if ($request->has('date_to')) { $query->whereDate('payment_date', '<=', $request->date_to); } $payments = $query->orderByDesc('payment_date')->paginate($request->per_page ?? 20); return PaymentResource::collection($payments); } public function store(Request $request) { $data = $request->validate([ 'invoice_id' => 'required|exists:invoices,id', 'payment_date' => 'required|date', 'amount' => 'required|numeric|min:0.01', 'payment_method' => 'required|in:cash,card,bank_transfer,check,insurance,other', 'reference_number' => 'nullable|string|max:255', 'notes' => 'nullable|string', ]); $invoice = Invoice::findOrFail($data['invoice_id']); // Check if payment exceeds balance if ($data['amount'] > $invoice->balance) { return response()->json([ 'message' => 'Payment amount exceeds invoice balance', 'balance' => $invoice->balance, ], 422); } $data['received_by'] = auth()->id(); // Generate payment number $lastId = Payment::max('id') ?? 0; $data['payment_number'] = 'PAY-' . date('Y') . '-' . str_pad($lastId + 1, 6, '0', STR_PAD_LEFT); $payment = Payment::create($data); // Update invoice $invoice->paid_amount += $data['amount']; $invoice->status = $invoice->paid_amount >= $invoice->total_amount ? 'paid' : 'partial'; $invoice->save(); // Create ledger entry $ledgerService = new LedgerService(); $ledgerService->recordPayment($payment); return new PaymentResource($payment); } public function show(Payment $payment) { return new PaymentResource($payment); } public function destroy(Payment $payment) { // Revert invoice payment $invoice = $payment->invoice; $invoice->paid_amount -= $payment->amount; $invoice->status = $invoice->paid_amount <= 0 ? 'sent' : 'partial'; $invoice->save(); $payment->delete(); return response()->json(['message' => 'Payment deleted successfully']); } public function summary(Request $request) { $query = Payment::query(); if ($request->has('date_from')) { $query->whereDate('payment_date', '>=', $request->date_from); } if ($request->has('date_to')) { $query->whereDate('payment_date', '<=', $request->date_to); } return response()->json([ 'total_payments' => $query->count(), 'total_amount' => $query->sum('amount'), 'by_method' => $query->selectRaw('payment_method, count(*) as count, sum(amount) as amount') ->groupBy('payment_method') ->get(), ]); } }