feat(cashier): GL Entries view in Closing Cash Report
- New 'GL View' toggle button in header — switches between denomination report and GL entries table - GL table: Voucher No, A/C No, A/C Name (customer), DR (red), CR (green) - Filters: Teller Head dropdown → Cashier dropdown (cascading) - Load button resets to denomination view (showGl = false) - Header shows Total DR / Total CR summary - DR rows: light red bg; CR rows: light green bg Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
1aa46397a6
commit
3be2f96210
@@ -21,10 +21,13 @@
|
||||
<button type="button" class="pg-btn pg-btn--primary" (click)="load()" [disabled]="loading">
|
||||
<mat-icon>search</mat-icon> Load
|
||||
</button>
|
||||
<button type="button" class="pg-btn" [class.pg-btn--active]="showGl" (click)="toggleGl()">
|
||||
<mat-icon>account_balance</mat-icon> GL View
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
@if (rows.length > 0) {
|
||||
@if (!showGl && rows.length > 0) {
|
||||
<!-- Summary totals bar -->
|
||||
<div class="closing-summary">
|
||||
<div class="closing-summary__item closing-summary__item--in">
|
||||
@@ -48,98 +51,205 @@
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="pg-card">
|
||||
@if (noteRows.length > 0) {
|
||||
<div class="pos-section-label">Notes</div>
|
||||
<table class="pg-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Denomination</th>
|
||||
<th class="num col-in">Deposit Pcs</th>
|
||||
<th class="num col-in">Deposit Amt</th>
|
||||
<th class="num col-out">Withdrawal Pcs</th>
|
||||
<th class="num col-out">Withdrawal Amt</th>
|
||||
<th class="num col-net">Net Pcs</th>
|
||||
<th class="num col-net">Net Amount</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@for (r of noteRows; track r.denominationId) {
|
||||
@if (!showGl) {
|
||||
<div class="pg-card">
|
||||
@if (noteRows.length > 0) {
|
||||
<div class="pos-section-label">Notes</div>
|
||||
<table class="pg-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<td>
|
||||
<span class="pg-chip">₹{{ r.denominationValue }}</span>
|
||||
</td>
|
||||
<td class="num col-in">{{ r.depositCount }}</td>
|
||||
<td class="num col-in">₹{{ r.depositAmount | number: '1.2-2' }}</td>
|
||||
<td class="num col-out">{{ r.withdrawalCount }}</td>
|
||||
<td class="num col-out">₹{{ r.withdrawalAmount | number: '1.2-2' }}</td>
|
||||
<td
|
||||
class="num col-net"
|
||||
[style.color]="r.netCount > 0 ? '#16a34a' : r.netCount < 0 ? '#dc2626' : '#94a3b8'"
|
||||
>
|
||||
{{ r.netCount > 0 ? '+' : '' }}{{ r.netCount }}
|
||||
</td>
|
||||
<td
|
||||
class="num col-net"
|
||||
[style.color]="r.netCount > 0 ? '#16a34a' : r.netCount < 0 ? '#dc2626' : '#94a3b8'"
|
||||
>
|
||||
{{ r.netCount >= 0 ? '' : '−' }}₹{{ (r.netAmount < 0 ? -r.netAmount : r.netAmount) | number: '1.2-2' }}
|
||||
</td>
|
||||
<th>Denomination</th>
|
||||
<th class="num col-in">Deposit Pcs</th>
|
||||
<th class="num col-in">Deposit Amt</th>
|
||||
<th class="num col-out">Withdrawal Pcs</th>
|
||||
<th class="num col-out">Withdrawal Amt</th>
|
||||
<th class="num col-net">Net Pcs</th>
|
||||
<th class="num col-net">Net Amount</th>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
</thead>
|
||||
<tbody>
|
||||
@for (r of noteRows; track r.denominationId) {
|
||||
<tr>
|
||||
<td>
|
||||
<span class="pg-chip">₹{{ r.denominationValue }}</span>
|
||||
</td>
|
||||
<td class="num col-in">{{ r.depositCount }}</td>
|
||||
<td class="num col-in">₹{{ r.depositAmount | number: '1.2-2' }}</td>
|
||||
<td class="num col-out">{{ r.withdrawalCount }}</td>
|
||||
<td class="num col-out">₹{{ r.withdrawalAmount | number: '1.2-2' }}</td>
|
||||
<td
|
||||
class="num col-net"
|
||||
[style.color]="r.netCount > 0 ? '#16a34a' : r.netCount < 0 ? '#dc2626' : '#94a3b8'"
|
||||
>
|
||||
{{ r.netCount > 0 ? '+' : '' }}{{ r.netCount }}
|
||||
</td>
|
||||
<td
|
||||
class="num col-net"
|
||||
[style.color]="r.netCount > 0 ? '#16a34a' : r.netCount < 0 ? '#dc2626' : '#94a3b8'"
|
||||
>
|
||||
{{ r.netCount >= 0 ? '' : '−' }}₹{{
|
||||
(r.netAmount < 0 ? -r.netAmount : r.netAmount) | number: '1.2-2'
|
||||
}}
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
|
||||
@if (coinRows.length > 0) {
|
||||
<div class="pos-section-label pos-section-label--coin">Coins</div>
|
||||
<table class="pg-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Denomination</th>
|
||||
<th class="num col-in">Deposit Pcs</th>
|
||||
<th class="num col-in">Deposit Amt</th>
|
||||
<th class="num col-out">Withdrawal Pcs</th>
|
||||
<th class="num col-out">Withdrawal Amt</th>
|
||||
<th class="num col-net">Net Pcs</th>
|
||||
<th class="num col-net">Net Amount</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@for (r of coinRows; track r.denominationId) {
|
||||
@if (coinRows.length > 0) {
|
||||
<div class="pos-section-label pos-section-label--coin">Coins</div>
|
||||
<table class="pg-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<td>
|
||||
<span class="pg-chip pg-chip--coin">₹{{ r.denominationValue }}</span>
|
||||
</td>
|
||||
<td class="num col-in">{{ r.depositCount }}</td>
|
||||
<td class="num col-in">₹{{ r.depositAmount | number: '1.2-2' }}</td>
|
||||
<td class="num col-out">{{ r.withdrawalCount }}</td>
|
||||
<td class="num col-out">₹{{ r.withdrawalAmount | number: '1.2-2' }}</td>
|
||||
<td
|
||||
class="num col-net"
|
||||
[style.color]="r.netCount > 0 ? '#16a34a' : r.netCount < 0 ? '#dc2626' : '#94a3b8'"
|
||||
>
|
||||
{{ r.netCount > 0 ? '+' : '' }}{{ r.netCount }}
|
||||
</td>
|
||||
<td
|
||||
class="num col-net"
|
||||
[style.color]="r.netCount > 0 ? '#16a34a' : r.netCount < 0 ? '#dc2626' : '#94a3b8'"
|
||||
>
|
||||
{{ r.netCount >= 0 ? '' : '−' }}₹{{ (r.netAmount < 0 ? -r.netAmount : r.netAmount) | number: '1.2-2' }}
|
||||
</td>
|
||||
<th>Denomination</th>
|
||||
<th class="num col-in">Deposit Pcs</th>
|
||||
<th class="num col-in">Deposit Amt</th>
|
||||
<th class="num col-out">Withdrawal Pcs</th>
|
||||
<th class="num col-out">Withdrawal Amt</th>
|
||||
<th class="num col-net">Net Pcs</th>
|
||||
<th class="num col-net">Net Amount</th>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
</thead>
|
||||
<tbody>
|
||||
@for (r of coinRows; track r.denominationId) {
|
||||
<tr>
|
||||
<td>
|
||||
<span class="pg-chip pg-chip--coin">₹{{ r.denominationValue }}</span>
|
||||
</td>
|
||||
<td class="num col-in">{{ r.depositCount }}</td>
|
||||
<td class="num col-in">₹{{ r.depositAmount | number: '1.2-2' }}</td>
|
||||
<td class="num col-out">{{ r.withdrawalCount }}</td>
|
||||
<td class="num col-out">₹{{ r.withdrawalAmount | number: '1.2-2' }}</td>
|
||||
<td
|
||||
class="num col-net"
|
||||
[style.color]="r.netCount > 0 ? '#16a34a' : r.netCount < 0 ? '#dc2626' : '#94a3b8'"
|
||||
>
|
||||
{{ r.netCount > 0 ? '+' : '' }}{{ r.netCount }}
|
||||
</td>
|
||||
<td
|
||||
class="num col-net"
|
||||
[style.color]="r.netCount > 0 ? '#16a34a' : r.netCount < 0 ? '#dc2626' : '#94a3b8'"
|
||||
>
|
||||
{{ r.netCount >= 0 ? '' : '−' }}₹{{
|
||||
(r.netAmount < 0 ? -r.netAmount : r.netAmount) | number: '1.2-2'
|
||||
}}
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
|
||||
@if (loaded && rows.length === 0 && exchangeRows.length === 0) {
|
||||
<div class="pg-empty">No cash denomination data for this date.</div>
|
||||
}
|
||||
</div>
|
||||
@if (loaded && rows.length === 0 && exchangeRows.length === 0) {
|
||||
<div class="pg-empty">No cash denomination data for this date.</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
<!-- end !showGl -->
|
||||
|
||||
<!-- Cash Exchange section — separate from deposits/withdrawals (net monetary = ₹0) -->
|
||||
@if (exchangeRows.length > 0) {
|
||||
<!-- GL View Panel -->
|
||||
@if (showGl) {
|
||||
<div class="gl-card">
|
||||
<!-- Card Header -->
|
||||
<div class="gl-card__header">
|
||||
<div class="gl-card__header-left">
|
||||
<div class="gl-card__icon">
|
||||
<mat-icon>account_balance</mat-icon>
|
||||
</div>
|
||||
<div>
|
||||
<div class="gl-card__title">GL Entries</div>
|
||||
<div class="gl-card__sub">Cashier transaction ledger for {{ date }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="gl-card__totals">
|
||||
<div class="gl-card__total gl-card__total--dr">
|
||||
<span class="gl-card__total-label">Total DR</span>
|
||||
<span class="gl-card__total-value">₹{{ glTotalDr | number: '1.2-2' }}</span>
|
||||
</div>
|
||||
<div class="gl-card__total-sep">|</div>
|
||||
<div class="gl-card__total gl-card__total--cr">
|
||||
<span class="gl-card__total-label">Total CR</span>
|
||||
<span class="gl-card__total-value">₹{{ glTotalCr | number: '1.2-2' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Filters Bar -->
|
||||
<div class="gl-card__filters">
|
||||
<label class="pg-field">
|
||||
<span>Teller Head</span>
|
||||
<select class="pg-select" [(ngModel)]="selectedTellerId" (change)="onTellerChange()">
|
||||
<option [ngValue]="null">All Tellers</option>
|
||||
@for (t of tellers; track t.id) {
|
||||
<option [ngValue]="t.id">{{ t.name }}</option>
|
||||
}
|
||||
</select>
|
||||
</label>
|
||||
@if (selectedTellerId) {
|
||||
<label class="pg-field">
|
||||
<span>Cashier</span>
|
||||
<select class="pg-select" [(ngModel)]="selectedCashierId" (change)="onCashierChange()">
|
||||
<option [ngValue]="null">All Cashiers</option>
|
||||
@for (c of cashiers; track c.id) {
|
||||
<option [ngValue]="c.id">{{ c.staffName }}</option>
|
||||
}
|
||||
</select>
|
||||
</label>
|
||||
}
|
||||
<button type="button" class="pg-btn pg-btn--primary" (click)="loadGl()" [disabled]="glLoading">
|
||||
<mat-icon>refresh</mat-icon> Refresh
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Table -->
|
||||
@if (glLoading) {
|
||||
<div class="pg-empty">Loading...</div>
|
||||
} @else if (glRows.length === 0 && glLoaded) {
|
||||
<div class="pg-empty">No entries found for this date and filter.</div>
|
||||
} @else if (glRows.length > 0) {
|
||||
<table class="pg-table gl-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="gl-th--voucher">Voucher No</th>
|
||||
<th>A/C No</th>
|
||||
<th>A/C Name</th>
|
||||
<th class="num gl-th--dr">DR (₹)</th>
|
||||
<th class="num gl-th--cr">CR (₹)</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@for (r of glRows; track $index) {
|
||||
<tr [class.gl-row--dr]="r.dr > 0" [class.gl-row--cr]="r.cr > 0">
|
||||
<td class="gl-voucher">{{ r.voucherNo }}</td>
|
||||
<td class="gl-acno">{{ r.acNo }}</td>
|
||||
<td class="gl-acname">{{ r.acName }}</td>
|
||||
<td class="num gl-amt--dr">
|
||||
@if (r.dr > 0) {
|
||||
₹{{ r.dr | number: '1.2-2' }}
|
||||
}
|
||||
</td>
|
||||
<td class="num gl-amt--cr">
|
||||
@if (r.cr > 0) {
|
||||
₹{{ r.cr | number: '1.2-2' }}
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr class="gl-foot">
|
||||
<td colspan="3" class="gl-foot__label">Total</td>
|
||||
<td class="num gl-amt--dr gl-foot__val">₹{{ glTotalDr | number: '1.2-2' }}</td>
|
||||
<td class="num gl-amt--cr gl-foot__val">₹{{ glTotalCr | number: '1.2-2' }}</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (!showGl && exchangeRows.length > 0) {
|
||||
<div class="pg-card">
|
||||
<div class="closing-exchange-head">
|
||||
<mat-icon>swap_horiz</mat-icon>
|
||||
|
||||
@@ -36,6 +36,20 @@ export class ClosingCashReportComponent implements OnInit {
|
||||
loading = false;
|
||||
loaded = false;
|
||||
|
||||
// GL View
|
||||
showGl = false;
|
||||
glRows: any[] = [];
|
||||
glTotalDr = 0;
|
||||
glTotalCr = 0;
|
||||
glLoading = false;
|
||||
glLoaded = false;
|
||||
|
||||
// Filters for GL
|
||||
tellers: any[] = [];
|
||||
cashiers: any[] = [];
|
||||
selectedTellerId: number | null = null;
|
||||
selectedCashierId: number | null = null;
|
||||
|
||||
get noteRows(): any[] {
|
||||
return this.rows.filter((r) => r.kind !== 'coin');
|
||||
}
|
||||
@@ -53,9 +67,11 @@ export class ClosingCashReportComponent implements OnInit {
|
||||
const d = new Date();
|
||||
this.date = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
|
||||
this.load();
|
||||
this.service.getTellers().subscribe({ next: (t: any[]) => (this.tellers = t || []), error: () => {} });
|
||||
}
|
||||
|
||||
load(): void {
|
||||
this.showGl = false;
|
||||
this.loading = true;
|
||||
this.service.closingCashReport(this.date).subscribe({
|
||||
next: (res: any) => {
|
||||
@@ -78,4 +94,51 @@ export class ClosingCashReportComponent implements OnInit {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
toggleGl(): void {
|
||||
this.showGl = !this.showGl;
|
||||
if (this.showGl && !this.glLoaded) {
|
||||
this.loadGl();
|
||||
}
|
||||
}
|
||||
|
||||
onTellerChange(): void {
|
||||
this.selectedCashierId = null;
|
||||
this.cashiers = [];
|
||||
if (this.selectedTellerId) {
|
||||
this.service.getCashiersForTeller(this.selectedTellerId).subscribe({
|
||||
next: (res: any) => (this.cashiers = res?.cashiers || res || []),
|
||||
error: () => {}
|
||||
});
|
||||
}
|
||||
this.glLoaded = false;
|
||||
this.loadGl();
|
||||
}
|
||||
|
||||
onCashierChange(): void {
|
||||
this.glLoaded = false;
|
||||
this.loadGl();
|
||||
}
|
||||
|
||||
loadGl(): void {
|
||||
this.glLoading = true;
|
||||
this.service
|
||||
.getGlEntries(this.date, this.selectedCashierId || undefined, this.selectedTellerId || undefined)
|
||||
.subscribe({
|
||||
next: (res: any) => {
|
||||
this.glRows = res?.rows || [];
|
||||
this.glTotalDr = Number(res?.totalDr || 0);
|
||||
this.glTotalCr = Number(res?.totalCr || 0);
|
||||
this.glLoading = false;
|
||||
this.glLoaded = true;
|
||||
},
|
||||
error: () => {
|
||||
this.glRows = [];
|
||||
this.glTotalDr = 0;
|
||||
this.glTotalCr = 0;
|
||||
this.glLoading = false;
|
||||
this.glLoaded = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user