|
|
|
@ -422,12 +422,35 @@ export function ClientDetail() {
|
|
|
|
<StatCard label="Advance on account" value={formatINR(ledger.data.advancePaise)} hint="unallocated payments" />
|
|
|
|
<StatCard label="Advance on account" value={formatINR(ledger.data.advancePaise)} hint="unallocated payments" />
|
|
|
|
</Stats>
|
|
|
|
</Stats>
|
|
|
|
)}
|
|
|
|
)}
|
|
|
|
|
|
|
|
{ledger.data !== undefined && ledger.data.outstanding.length > 0 && (
|
|
|
|
|
|
|
|
<div className="wf-card">
|
|
|
|
|
|
|
|
<h3 style={{ display: 'flex', alignItems: 'center', gap: 8, margin: '0 0 10px' }}>
|
|
|
|
|
|
|
|
Outstanding
|
|
|
|
|
|
|
|
<Badge tone="warn">{inr(ledger.data.outstanding.reduce((s, o) => s + o.outstandingPaise, 0))} due</Badge>
|
|
|
|
|
|
|
|
</h3>
|
|
|
|
|
|
|
|
<div className="cdr-out">
|
|
|
|
|
|
|
|
<div className="oh"><span style={{ fontWeight: 700, fontSize: 13 }}>Open documents</span>
|
|
|
|
|
|
|
|
<span style={{ color: 'var(--text-dim)', fontSize: 12 }}>— oldest settles first</span></div>
|
|
|
|
|
|
|
|
{ledger.data.outstanding.map((o) => (
|
|
|
|
|
|
|
|
<div key={o.docId} className="orow" onClick={() => nav(`/documents/${o.docId}`)} style={{ cursor: 'pointer' }}>
|
|
|
|
|
|
|
|
<span className="mono" style={{ minWidth: 78 }}>{o.docNo ?? 'draft'}</span>
|
|
|
|
|
|
|
|
<span className="doc-pill">{DOC_TYPE_LABEL[o.docType as keyof typeof DOC_TYPE_LABEL] ?? o.docType}</span>
|
|
|
|
|
|
|
|
<span style={{ color: 'var(--text-dim)' }}>{o.label}</span>
|
|
|
|
|
|
|
|
<span className="due">{inr(o.outstandingPaise)}</span>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
))}
|
|
|
|
|
|
|
|
<div className="ofoot"><span style={{ color: 'var(--text-dim)', fontSize: 12 }}>Advance on account</span>
|
|
|
|
|
|
|
|
<span className="mono" style={{ marginLeft: 'auto', fontWeight: 600 }}>{formatINR(ledger.data.advancePaise)}</span></div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
)}
|
|
|
|
<PaymentForm clientId={id} onDone={() => { ledger.reload(); cms.reload(); amc.reload() }} />
|
|
|
|
<PaymentForm clientId={id} onDone={() => { ledger.reload(); cms.reload(); amc.reload() }} />
|
|
|
|
{ledger.data !== undefined && ledger.data.payments.length > 0 && (
|
|
|
|
{ledger.data !== undefined && ledger.data.payments.length > 0 && (
|
|
|
|
<DataTable
|
|
|
|
<DataTable
|
|
|
|
columns={[
|
|
|
|
columns={[
|
|
|
|
{ key: 'on', label: 'Received' }, { key: 'mode', label: 'Mode' },
|
|
|
|
{ key: 'on', label: 'Received' }, { key: 'mode', label: 'Mode' },
|
|
|
|
{ key: 'ref', label: 'Reference', mono: true },
|
|
|
|
{ key: 'ref', label: 'Reference', mono: true },
|
|
|
|
|
|
|
|
{ key: 'settled', label: 'Settled' },
|
|
|
|
{ key: 'amount', label: 'Amount', numeric: true },
|
|
|
|
{ key: 'amount', label: 'Amount', numeric: true },
|
|
|
|
{ key: 'tds', label: 'TDS', numeric: true },
|
|
|
|
{ key: 'tds', label: 'TDS', numeric: true },
|
|
|
|
]}
|
|
|
|
]}
|
|
|
|
@ -435,6 +458,9 @@ export function ClientDetail() {
|
|
|
|
.sort((a, b) => (a.receivedOn === b.receivedOn ? (a.id < b.id ? 1 : -1) : b.receivedOn.localeCompare(a.receivedOn)))
|
|
|
|
.sort((a, b) => (a.receivedOn === b.receivedOn ? (a.id < b.id ? 1 : -1) : b.receivedOn.localeCompare(a.receivedOn)))
|
|
|
|
.map((p) => ({
|
|
|
|
.map((p) => ({
|
|
|
|
on: p.receivedOn, mode: p.mode, ref: p.reference !== '' ? p.reference : '—',
|
|
|
|
on: p.receivedOn, mode: p.mode, ref: p.reference !== '' ? p.reference : '—',
|
|
|
|
|
|
|
|
settled: p.allocations.length === 0
|
|
|
|
|
|
|
|
? <span style={{ color: 'var(--text-dim)' }}>advance</span>
|
|
|
|
|
|
|
|
: <span style={{ color: 'var(--text-dim)', fontSize: 12 }}>→ {p.allocations.map((a) => a.docNo).join(', ')}</span>,
|
|
|
|
amount: inr(p.amountPaise), tds: p.tdsPaise > 0 ? inr(p.tdsPaise) : '—',
|
|
|
|
amount: inr(p.amountPaise), tds: p.tdsPaise > 0 ? inr(p.tdsPaise) : '—',
|
|
|
|
}))}
|
|
|
|
}))}
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
|