diff --git a/assets/admin/components/ServiceInsuranceModal.tsx b/assets/admin/components/ServiceInsuranceModal.tsx
index 045f9048..35b4119a 100644
--- a/assets/admin/components/ServiceInsuranceModal.tsx
+++ b/assets/admin/components/ServiceInsuranceModal.tsx
@@ -181,7 +181,7 @@ function ContractCard({ contract, item }: { contract: TenantInsurance; item: Ser
{!draft.covered && !isLoading && (
این خدمت تحت این بیمه پوشش ندارد
-
diff --git a/assets/admin/components/session/PaymentStep.tsx b/assets/admin/components/session/PaymentStep.tsx
index f54d2951..715f1deb 100644
--- a/assets/admin/components/session/PaymentStep.tsx
+++ b/assets/admin/components/session/PaymentStep.tsx
@@ -71,7 +71,8 @@ export default function PaymentStep({ recordUuid, session, walletBalance, onCont
const payMut = useMutation({
mutationFn: (body: object) => api.post(`/api/v1/session/${sessionUuid}/payments`, body),
- onSuccess: () => { invalidate(); setAmount(0); toast.success('پرداخت ثبت شد'); },
+ // بعد از ثبت، آکاردئون بسته میشود تا باز شدن بعدی ماندهی بهروزشده را پیشفرض بگذارد.
+ onSuccess: () => { invalidate(); setAmount(0); setExpanded(null); toast.success('پرداخت ثبت شد'); },
onError: (e: Error) => toast.error(e.message),
});
@@ -128,6 +129,17 @@ export default function PaymentStep({ recordUuid, session, walletBalance, onCont
: Math.max(0, finalPrice - discountRials);
const debt = session.remaining_rials ?? session.patient_debt_rials ?? 0;
+ /**
+ * مبلغ پیشفرض هنگام باز شدن هر روش پرداخت = ماندهی فعلی (تومان).
+ * چون `debt` از `remaining_rials` سرور میآید، بعد از هر پرداخت جزئی خودش کم میشود؛
+ * پس در پرداخت چندروشه، روش بعدی باقیماندهی درست را پیشفرض میگیرد.
+ * برای کیف پول سقفِ موجودی هم اعمال میشود.
+ */
+ const defaultAmountFor = (method: string) => {
+ const cap = method === 'wallet' ? Math.min(debt, walletBalance) : debt;
+ return rialToToman(Math.max(0, cap));
+ };
+
return (
<>
{/* هزینه سرویس */}
@@ -264,7 +276,7 @@ export default function PaymentStep({ recordUuid, session, walletBalance, onCont
{ setExpanded(open ? null : m.key); setAmount(0); }}
+ onClick={() => { setExpanded(open ? null : m.key); setAmount(open ? 0 : defaultAmountFor(m.key)); }}
style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', width: '100%', padding: '14px 4px', background: 'transparent', border: 'none', cursor: 'pointer' }}
>
{m.label}
diff --git a/assets/admin/pages/SessionPaymentPage.test.tsx b/assets/admin/pages/SessionPaymentPage.test.tsx
index 00289aac..974d0b91 100644
--- a/assets/admin/pages/SessionPaymentPage.test.tsx
+++ b/assets/admin/pages/SessionPaymentPage.test.tsx
@@ -97,6 +97,24 @@ describe('SessionPaymentPage (تکمیل پرداخت مراجعه)', () => {
expect(typeof (body as any).paid_at).toBe('number');
});
+ it('prefills the amount field with the remaining balance when a method is opened', async () => {
+ // مانده ۲,۳۰۰,۰۰۰ ریال → ۲۳۰,۰۰۰ تومان در فیلد مبلغ
+ mockGets([session({ remaining_rials: 2_300_000 })]);
+ renderPage();
+
+ fireEvent.click(await screen.findByText('پرداخت نقدی'));
+ expect(screen.getByPlaceholderText('مبلغ (تومان)')).toHaveValue('230,000');
+ });
+
+ it('caps the wallet prefill at the wallet balance', async () => {
+ // موجودی کیف پول ۳۰۰,۰۰۰ ریال < مانده ۲,۳۰۰,۰۰۰ ریال → ۳۰,۰۰۰ تومان
+ mockGets([session({ remaining_rials: 2_300_000 })]);
+ renderPage();
+
+ fireEvent.click(await screen.findByText('پرداخت از طریق کیف پول'));
+ expect(screen.getByPlaceholderText('مبلغ (تومان)')).toHaveValue('30,000');
+ });
+
it('applies and removes settlement discount (PATCH /session/{uuid})', async () => {
mockGets([session()]);
patch.mockResolvedValue({ success: true, data: session() });