121 lines
3.7 KiB
PHP

<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Http\Resources\PaymentResource;
use App\Models\Invoice;
use App\Models\Payment;
use App\Services\LedgerService;
use Illuminate\Http\Request;
class PaymentController extends Controller
{
public function index(Request $request)
{
$query = Payment::with(['invoice.patient', 'receivedBy']);
if ($request->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(),
]);
}
}