Fix bill payment forms to use major currency units.
Deploy Ladill Care / deploy (push) Successful in 56s
Deploy Ladill Care / deploy (push) Successful in 56s
Cashiers saw pesewa integers (e.g. 4000) while history showed GHS 40.00; accept and prefill major amounts and convert to minor on record/checkout. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -226,15 +226,20 @@ class BillController extends Controller
|
||||
|
||||
$manualMethods = array_keys(collect(config('care.payment_methods', []))->except(['gateway'])->all());
|
||||
|
||||
$validated = $request->validate([
|
||||
'amount' => ['required', 'numeric', 'min:0.01'],
|
||||
'method' => ['required', 'string', 'in:'.implode(',', $manualMethods)],
|
||||
'reference' => ['nullable', 'string', 'max:100'],
|
||||
'notes' => ['nullable', 'string', 'max:500'],
|
||||
]);
|
||||
|
||||
$validated['amount_minor'] = max(1, (int) round(((float) $validated['amount']) * 100));
|
||||
unset($validated['amount']);
|
||||
|
||||
$this->bills->recordPayment(
|
||||
$bill,
|
||||
$this->ownerRef($request),
|
||||
$request->validate([
|
||||
'amount_minor' => ['required', 'integer', 'min:1'],
|
||||
'method' => ['required', 'string', 'in:'.implode(',', $manualMethods)],
|
||||
'reference' => ['nullable', 'string', 'max:100'],
|
||||
'notes' => ['nullable', 'string', 'max:500'],
|
||||
]),
|
||||
$validated,
|
||||
$this->ownerRef($request),
|
||||
);
|
||||
|
||||
@@ -247,10 +252,12 @@ class BillController extends Controller
|
||||
$this->authorizeBill($request, $bill);
|
||||
|
||||
$validated = $request->validate([
|
||||
'amount_minor' => ['nullable', 'integer', 'min:1'],
|
||||
'amount' => ['nullable', 'numeric', 'min:0.01'],
|
||||
]);
|
||||
|
||||
$amount = (int) ($validated['amount_minor'] ?? $bill->balance_minor);
|
||||
$amount = isset($validated['amount'])
|
||||
? max(1, (int) round(((float) $validated['amount']) * 100))
|
||||
: (int) $bill->balance_minor;
|
||||
|
||||
try {
|
||||
$result = $this->bills->startGatewayPayment(
|
||||
|
||||
@@ -78,11 +78,18 @@
|
||||
@endif
|
||||
|
||||
@if ($canPay && $bill->balance_minor > 0 && $bill->status !== \App\Models\Bill::STATUS_VOID)
|
||||
@php
|
||||
$balanceMajor = number_format($bill->balance_minor / 100, 2, '.', '');
|
||||
$currency = config('care.billing.currency');
|
||||
@endphp
|
||||
<section class="rounded-2xl border border-slate-200 bg-white p-6">
|
||||
<h2 class="text-sm font-semibold uppercase text-slate-500">Record payment</h2>
|
||||
<form method="POST" action="{{ route('care.bills.payments.store', $bill) }}" class="mt-4 space-y-3">
|
||||
@csrf
|
||||
<input type="number" name="amount_minor" value="{{ $bill->balance_minor }}" min="1" required class="w-full rounded-lg border-slate-300 text-sm">
|
||||
<label class="block text-sm text-slate-600">
|
||||
Amount ({{ $currency }})
|
||||
<input type="number" name="amount" value="{{ old('amount', $balanceMajor) }}" min="0.01" step="0.01" max="{{ $balanceMajor }}" required class="mt-1 w-full rounded-lg border-slate-300 text-sm tabular-nums">
|
||||
</label>
|
||||
<select name="method" class="w-full rounded-lg border-slate-300 text-sm">@foreach ($manualPaymentMethods as $k => $v)<option value="{{ $k }}">{{ $v }}</option>@endforeach</select>
|
||||
<input type="text" name="reference" placeholder="Reference" class="w-full rounded-lg border-slate-300 text-sm">
|
||||
<button type="submit" class="btn-primary w-full">Record payment</button>
|
||||
@@ -101,7 +108,10 @@
|
||||
@if ($gatewayConfigured)
|
||||
<form method="POST" action="{{ route('care.bills.payments.gateway', $bill) }}" class="mt-4 space-y-3">
|
||||
@csrf
|
||||
<input type="number" name="amount_minor" value="{{ $bill->balance_minor }}" min="1" max="{{ $bill->balance_minor }}" required class="w-full rounded-lg border-slate-300 text-sm" aria-label="Amount (minor units)">
|
||||
<label class="block text-sm text-slate-600">
|
||||
Amount ({{ $currency }})
|
||||
<input type="number" name="amount" value="{{ old('amount', $balanceMajor) }}" min="0.01" step="0.01" max="{{ $balanceMajor }}" required class="mt-1 w-full rounded-lg border-slate-300 text-sm tabular-nums" aria-label="Amount ({{ $currency }})">
|
||||
</label>
|
||||
<button type="submit" class="btn-primary w-full">Open checkout</button>
|
||||
</form>
|
||||
@else
|
||||
|
||||
@@ -125,7 +125,7 @@ class CareBillTest extends TestCase
|
||||
|
||||
$this->actingAs($this->user)
|
||||
->post(route('care.bills.payments.store', $bill), [
|
||||
'amount_minor' => 3000,
|
||||
'amount' => 30.00,
|
||||
'method' => 'cash',
|
||||
])
|
||||
->assertRedirect();
|
||||
@@ -136,7 +136,7 @@ class CareBillTest extends TestCase
|
||||
|
||||
$this->actingAs($this->user)
|
||||
->post(route('care.bills.payments.store', $bill), [
|
||||
'amount_minor' => $bill->balance_minor,
|
||||
'amount' => $bill->balance_minor / 100,
|
||||
'method' => 'momo',
|
||||
'reference' => 'MOMO-123',
|
||||
])
|
||||
@@ -209,10 +209,15 @@ class CareBillTest extends TestCase
|
||||
->assertSee('Pay')
|
||||
->assertSee('Actions');
|
||||
|
||||
$balanceMajor = number_format($bill->balance_minor / 100, 2, '.', '');
|
||||
|
||||
$this->actingAs($this->user)
|
||||
->get(route('care.bills.show', $bill))
|
||||
->assertOk()
|
||||
->assertSee('Record payment');
|
||||
->assertSee('Record payment')
|
||||
->assertSee('name="amount"', false)
|
||||
->assertSee('value="'.$balanceMajor.'"', false)
|
||||
->assertDontSee('value="'.$bill->balance_minor.'"', false);
|
||||
}
|
||||
|
||||
public function test_call_next_empty_booth_explains_walk_up_invoices(): void
|
||||
|
||||
@@ -175,7 +175,7 @@ class CarePaymentGatewayTest extends TestCase
|
||||
|
||||
$this->actingAs($this->user)
|
||||
->post(route('care.bills.payments.gateway', $this->bill), [
|
||||
'amount_minor' => $balance,
|
||||
'amount' => $balance / 100,
|
||||
])
|
||||
->assertRedirect('https://checkout.paystack.com/care-test');
|
||||
|
||||
@@ -224,7 +224,7 @@ class CarePaymentGatewayTest extends TestCase
|
||||
|
||||
$this->actingAs($this->user)
|
||||
->post(route('care.bills.payments.gateway', $this->bill), [
|
||||
'amount_minor' => 5000,
|
||||
'amount' => 50.00,
|
||||
])
|
||||
->assertRedirect('https://checkout.flutterwave.com/v3/hosted/pay/test');
|
||||
|
||||
@@ -258,7 +258,7 @@ class CarePaymentGatewayTest extends TestCase
|
||||
|
||||
$this->actingAs($this->user)
|
||||
->post(route('care.bills.payments.gateway', $this->bill), [
|
||||
'amount_minor' => 2500,
|
||||
'amount' => 25.00,
|
||||
])
|
||||
->assertRedirect('https://pay.hubtel.com/checkout/test');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user