121 lines
3.7 KiB
PHP
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(),
|
|
]);
|
|
}
|
|
}
|