ALM Time-Bucket Breakdown

Day-wise breakdown of FD / RD / Loan from the as-on date

@if (view === 'config') { }
@if (view === 'config') {

  Each line shows which bucket its money goes to. You can change the % and the rule. Changes are saved in this browser straight away. Hover over a line name to see why it is slotted that way.

@if (problemCount > 0) {

{{ problemCount }} line(s) have a % total that is not 100 or is not filled in yet. See the red or yellow totals below.

} } @if (view === 'config') {
@if (loading) { Loading data from accounts… } @else if (loadError) { {{ loadError }} } @else if (breakdown) { FD, RD and Loan data as on {{ breakdown.asOnDate }}. }
} @if (view === 'days') {

1. Select

@if (selectBy === 'types') {

Tick one or more. You can pick from both sides together.

@for (grp of pickGroups; track grp.side) {
{{ grp.title }}
@for (t of grp.items; track t.value) { }
}
} @else { @if (searching) {

Searching…

} @else if (searchError) {

{{ searchError }}

} @else if (searchText.trim().length < 2) {

Type at least 2 characters of an account number or a customer name.

} @else if (!searchResults.length) {

No accounts found.

} @if (searchResults.length) {
@for (hit of searchResults; track hit.kind + '-' + hit.id) { }
} @if (picked.length) {
Selected ({{ picked.length }}) @for (p of picked; track p.kind + '-' + p.id) { {{ p.kind }} {{ p.accountNo }} }
} }

2. Date and unit

@if (reportShown && selectBy === 'types') {

{{ typeColumns.length }} account {{ typeColumns.length === 1 ? 'type' : 'types' }} as on {{ asOnIso }} · Amounts in {{ unitWord }}

@if (loading) {

Loading data from accounts…

} @if (loadError) {

{{ loadError }}

} @if (breakdown) { @for (c of typeColumns; track c.value) { @if (c.notice) {

{{ c.label }}: {{ c.notice }}

} }
@for (c of typeColumns; track c.value) { } @if (typeHasLiability && typeHasAsset) { } @else if (typeColumns.length > 1) { } @for (r of typeMatrix; track r.label) { @for (v of r.cells; track $index) { } @if (typeHasLiability && typeHasAsset) { } @else if (typeColumns.length > 1) { } } @for (c of typeColumns; track c.value) { } @if (typeHasLiability && typeHasAsset) { } @else if (typeColumns.length > 1) { }
Bucket Days Dates {{ c.label }} Liabilities total Assets totalTotal
{{ r.label }} {{ r.days }} {{ r.dates }}{{ amountText(v) }}{{ amountText(r.liab) }} {{ amountText(r.asset) }}{{ amountText(r.liab + r.asset) }}
Total{{ amountText(c.total) }}{{ amountText(liabilityGrandTotal) }} {{ amountText(assetGrandTotal) }}{{ amountText(liabilityGrandTotal + assetGrandTotal) }}

Deposits and term loans are slotted by their own dates: a deposit once on its maturity date, a loan once for each unpaid instalment on its due date. Anything already due goes in the first bucket (a loan instalment follows the Overdue rule). CC / OD and NPA loans are divided by the bucket-wise % set for them in the Configuration table. Deposit amounts are balances, loan amounts are principal; interest is a separate line of the statement.

}
} @if (reportShown && selectBy === 'accounts') {

{{ picked.length }} {{ picked.length === 1 ? 'account' : 'accounts' }} as on {{ asOnIso }} · Amounts in {{ unitWord }}

@if (reportLoading) {

Loading…

} @if (reportError) {

{{ reportError }}

} @if (report; as rep) { @for (r of reportBuckets; track r.label) { }
Bucket Days Dates Amount % Entries
{{ r.label }} {{ r.days }} {{ r.dates }} {{ amountText(r.amount) }} {{ r.amount ? (r.pct | number: '1.0-1') + '%' : '' }} {{ r.count || '' }}
Total {{ amountText(rep.total) }} {{ rep.total ? '100%' : '' }} {{ rep.count }}

A deposit counts once, on its maturity date; a loan counts once for each unpaid instalment, on its due date. Anything already due goes in the first bucket (a loan instalment follows the Overdue rule). Deposit amounts are balances, loan amounts are the principal of each instalment; interest is a separate line of the statement.

Each entry

@for (r of rep.rows; track $index) { } @empty { }
Account Customer Product Due / maturity date Days Bucket Status Amount
{{ r.kind }} {{ r.accountNo }} @if (r.installment) { instalment {{ r.installment }} } {{ r.customer }} {{ r.product }} @if (r.note) {
{{ r.note }}
}
{{ r.date ? (r.date | date: 'dd-MMM-yyyy') : '—' }} {{ r.days === null ? '' : r.days }} {{ bucketName(r.bucket) }} {{ r.status }} {{ amountText(r.amount) }}
Nothing to show for these accounts on this date.
}
}
} @else {

Bucket ranges

@if (rangeEdit) { Change the Start / End of a bucket, or add and remove buckets. When you change the End of a bucket, the Start of the next one and its heading change with it. } @else { Start and End of each bucket. Click Edit to change, add or remove buckets. }

@if (rangeEdit) { } @for (b of cfg.buckets; track $index) { @if (rangeEdit) { } }
# Start End Heading Days / Dates
{{ $index + 1 }} @if (fromOf($index); as f) { @if (rangeEdit) { } @else { {{ f.n }} {{ unitLetter(f.unit) }} } } @if (b.upTo; as t) { @if (rangeEdit) { } @else { {{ t.n }} {{ unitLetter(t.unit) }} } } @else { end } {{ b.label }} @if (rangeProblem($index); as problem) {
{{ problem }}
}
@if (windows[$index]; as w) { {{ dayRange(w) }} · {{ dateRange(w) }} } @if (cfg.buckets.length > 2) { }
@if (rangeEdit) {
+ Add a bucket ending at: It is placed in the right position automatically and splits the bucket it falls inside into two.
}
@if (dayCheck; as c) {
@if (c.due) { Already due ({{ -c.days }} days ago) → {{ c.bucket }} } @else { {{ c.days }} days left → {{ c.bucket }} }
} @else {
Pick a maturity date and its bucket will show here.
}
@for (sec of sections; track sec.side) {
@if (editMode) { } @for (b of cfg.buckets; track $index) { } @for (item of itemsOf(sec.side); track item.id) { @if (item.header) { @if (editMode) { } } @else { @if (item.rule === 'maturity') { @if (autoAmounts(item); as amounts) { @for (v of amounts; track $index) { } } @else { } } @else if (item.rule === 'fixed') { @for (b of cfg.buckets; track $index) { } } @else { @for (b of cfg.buckets; track $index) { } } @if (editMode) { } } }
{{ sec.title }} RESIDUAL MATURITY TotalLine
{{ b.label }}
@if (editMode) { } @else { {{ item.ref }} } @if (editMode) { } @else { {{ item.name }} }
@if (editMode) { } @else { {{ item.ref }} } @if (editMode) { } @else { {{ item.name }} } @if (item.rule === 'maturity' || item.rule === 'behavioural') { } {{ amountText(v) }} {{ amountText(autoTotal(amounts)) }} @if (!item.source) { This line has to be filled by hand: it has no account source yet } @else if (loading) { Data aa raha hai… } @else { No data came from the accounts } — {{ share(item, $index) !== null ? '100%' : '' }} {{ rowState(item) === 'todo' ? 'fill in' : rowTotal(item) + '%' }}
@if (editMode) { }
} @if (editMode) {
Bucket names and day span
@for (b of cfg.buckets; track $index) {
{{ $index + 1 }}
@if (b.upTo) { } @else { No end }
} @if (cfg.overdue; as o) {
Overdue (due but not received): which bucket
}
} @if (breakdown; as b) {

Shown separately (not slotted by date)

    @for (n of b.notSlotted; track n.key) {
  • {{ n.label }} — {{ n.accounts }} loan, outstanding {{ amountText(n.outstanding) }}
    {{ n.why }}
  • }
    @for (note of b.notes; track note) {
  • {{ note }}
  • }
}

What the report will show

Statement of Structural Liquidity as on {{ asOnIso }}
( Amounts in {{ unitWord }} )
  • Two tables, OUTFLOWS and INFLOWS, with the lines above. Each line’s amount sits in its bucket, with a Total in the last column.
  • A. TOTAL OUTFLOWS — the sum of all outflow lines, bucket by bucket.
  • B. TOTAL INFLOWS — the sum of all inflow lines, bucket by bucket.
  • C. MISMATCH (B − A) — inflow minus outflow, in each bucket.
  • D. CUMULATIVE MISMATCH — running total of C, from the first bucket up to that bucket.
  • E. C as % to A — mismatch divided by outflow, times 100.
  • @for (l of cfg.limits; track $index) {
  • {{ cfg.buckets[l.bucket]?.label }}: negative mismatch must not exceed {{ l.pct }}%. The report shows it in red when it does.
  • }

Where the amount comes from: By due date lines take their data from FD, RD and Loan accounts. Fixed, Split and By study lines take the ledger (GL) balance and apply the % above. Lines with no register have to be filled in by hand.

}