feat(cashier): full double-entry journal view + Excel export for Cash/Clearing/Transfer Summary

Transaction Details now renders each voucher as a paired Dr/Cr journal entry with a
derived contra account and a Balanced status chip, so both sides of a transaction are
visible at a glance for reconciliation. Adds a shared cashier-export.ts (mirrors the
Investment module's exporter) and an Export to Excel button producing a Summary +
Transaction Details workbook, plus a Branch Breakup sheet for Head Office consolidated view.
This commit is contained in:
2026-08-01 20:32:31 +05:30
parent 0832017508
commit 1317a93838
4 changed files with 428 additions and 16 deletions
@@ -31,6 +31,9 @@
<button type="button" class="pg-btn" [class.pg-btn--active]="showDetails" (click)="toggleDetails()">
{{ showDetails ? 'Summary View' : 'Transaction Details' }}
</button>
<button type="button" class="pg-btn pg-btn--ghost" [disabled]="generating" (click)="exportExcel()">
{{ generating ? 'Exporting…' : 'Export to Excel' }}
</button>
</div>
</header>
@@ -209,43 +212,61 @@
? 'Clearing'
: 'Digital'
}}
— Transaction Details
— Transaction Details (Full Double Entry)
@if (glFilter !== null) {
· {{ glFilter }}
}
</div>
<table class="pg-table">
<table class="pg-table cctr-journal">
<thead>
<tr>
<th>Date</th>
<th>Voucher / Ref No</th>
<th>Account No</th>
<th>Account Name / Reference</th>
<th>Particulars</th>
<th>Dr / Cr</th>
<th>GL / Account</th>
<th class="num col-out">Debit</th>
<th class="num col-in">Credit</th>
<th>Status</th>
</tr>
</thead>
<tbody>
@for (t of filteredTxns; track t.voucherNo) {
<tr>
<tr class="cctr-journal-row cctr-journal-row--first">
<td>{{ asOnDate }}</td>
<td>
<span class="pg-chip">{{ display(t.voucherNo) }}</span>
</td>
<td>{{ display(t.accountNo) }}</td>
<td>{{ t.accountName }}</td>
<td>{{ t.particulars }}</td>
<td class="num col-out">
<td><span class="cctr-drcr cctr-drcr--dr">Dr</span></td>
<td>
@if (t.debit > 0) {
₹{{ t.debit | number: '1.2-2' }}
<span class="pg-chip">{{ t.glCode }}</span> {{ glName(t.glCode) }} — {{ display(t.accountNo) }} ({{
t.accountName
}})
} @else {
<span class="cctr-contra">{{ contraLabel(t) }}</span>
}
</td>
<td class="num col-in">
<td class="num col-out">₹{{ legAmount(t) | number: '1.2-2' }}</td>
<td class="num"></td>
<td rowspan="2">
<span class="cctr-balanced-chip">✓ Balanced</span>
</td>
</tr>
<tr class="cctr-journal-row cctr-journal-row--second">
<td></td>
<td></td>
<td><span class="cctr-drcr cctr-drcr--cr">Cr</span></td>
<td>
@if (t.credit > 0) {
₹{{ t.credit | number: '1.2-2' }}
<span class="pg-chip">{{ t.glCode }}</span> {{ glName(t.glCode) }} — {{ display(t.accountNo) }} ({{
t.accountName
}})
} @else {
<span class="cctr-contra">{{ contraLabel(t) }}</span>
}
</td>
<td class="num"></td>
<td class="num col-in">₹{{ legAmount(t) | number: '1.2-2' }}</td>
</tr>
} @empty {
<tr>
@@ -255,9 +276,14 @@
</tbody>
<tfoot>
<tr class="cctr-total-row">
<td colspan="5">Total</td>
<td class="num">₹{{ txnTotal(filteredTxns, 'debit') | number: '1.2-2' }}</td>
<td class="num">₹{{ txnTotal(filteredTxns, 'credit') | number: '1.2-2' }}</td>
<td colspan="4">Total ({{ filteredTxns.length }} vouchers)</td>
<td class="num">
₹{{ txnTotal(filteredTxns, 'debit') + txnTotal(filteredTxns, 'credit') | number: '1.2-2' }}
</td>
<td class="num">
₹{{ txnTotal(filteredTxns, 'debit') + txnTotal(filteredTxns, 'credit') | number: '1.2-2' }}
</td>
<td></td>
</tr>
</tfoot>
</table>