feat(cashier): integrate expected balance, settlement verification, and reconciliation checks
This commit is contained in:
@@ -83,7 +83,7 @@
|
||||
<td>{{ r.fromParty }}</td>
|
||||
<td>{{ r.toParty }}</td>
|
||||
<td class="num">₹{{ r.amount | number: '1.2-2' }}</td>
|
||||
<td>{{ r.note || '—' }}</td>
|
||||
<td class="td-note">{{ r.note || '—' }}</td>
|
||||
<td>{{ r.performedByUsername || '—' }}</td>
|
||||
<td style="text-align: center">
|
||||
<span class="badge" [class.badge-active]="!r.isReversed" [class.badge-reversed]="r.isReversed">
|
||||
@@ -91,11 +91,21 @@
|
||||
</span>
|
||||
</td>
|
||||
<td style="text-align: center">
|
||||
@if (!r.isReversed) {
|
||||
<button type="button" class="pg-btn pg-btn--ghost btn-sm" (click)="startReverse(r)">
|
||||
<mat-icon>undo</mat-icon>
|
||||
<div class="action-btns">
|
||||
<button
|
||||
type="button"
|
||||
class="pg-btn pg-btn--ghost btn-sm btn-view"
|
||||
title="View details"
|
||||
(click)="viewDetail(r)"
|
||||
>
|
||||
<mat-icon>visibility</mat-icon>
|
||||
</button>
|
||||
}
|
||||
@if (!r.isReversed) {
|
||||
<button type="button" class="pg-btn pg-btn--ghost btn-sm" title="Reverse" (click)="startReverse(r)">
|
||||
<mat-icon>undo</mat-icon>
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
@@ -104,3 +114,126 @@
|
||||
</div>
|
||||
}
|
||||
</ng-template>
|
||||
|
||||
<!-- ── Detail Overlay ── -->
|
||||
@if (detail) {
|
||||
<div class="detail-overlay" (click)="closeDetail()">
|
||||
<div class="detail-panel" (click)="$event.stopPropagation()">
|
||||
<!-- Header -->
|
||||
<div class="detail-panel__head">
|
||||
<div class="detail-panel__title">
|
||||
<mat-icon>{{ detail.row.type === 'settlement' ? 'account_balance_wallet' : 'swap_horiz' }}</mat-icon>
|
||||
<div>
|
||||
<span class="detail-panel__type">{{ typeLabel(detail.row.type) }}</span>
|
||||
<span class="detail-panel__id">#{{ detail.row.id }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" class="detail-panel__close" (click)="closeDetail()">
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Meta grid -->
|
||||
<div class="detail-meta">
|
||||
<div class="detail-meta__item">
|
||||
<span class="detail-meta__label">From</span>
|
||||
<span class="detail-meta__val">{{ detail.row.fromParty || '—' }}</span>
|
||||
</div>
|
||||
<div class="detail-meta__item">
|
||||
<span class="detail-meta__label">To</span>
|
||||
<span class="detail-meta__val">{{ detail.row.toParty || '—' }}</span>
|
||||
</div>
|
||||
<div class="detail-meta__item">
|
||||
<span class="detail-meta__label">Date</span>
|
||||
<span class="detail-meta__val">{{ detail.row.date }}</span>
|
||||
</div>
|
||||
<div class="detail-meta__item">
|
||||
<span class="detail-meta__label">Total Amount</span>
|
||||
<span class="detail-meta__val detail-meta__val--amount">₹{{ detail.row.amount | number: '1.2-2' }}</span>
|
||||
</div>
|
||||
<div class="detail-meta__item">
|
||||
<span class="detail-meta__label">Performed By</span>
|
||||
<span class="detail-meta__val">{{ detail.row.performedByUsername || '—' }}</span>
|
||||
</div>
|
||||
<div class="detail-meta__item">
|
||||
<span class="detail-meta__label">Created At</span>
|
||||
<span class="detail-meta__val">{{ detail.row.createdAt || '—' }}</span>
|
||||
</div>
|
||||
<div class="detail-meta__item detail-meta__item--full">
|
||||
<span class="detail-meta__label">Note</span>
|
||||
<span class="detail-meta__val">{{ detail.row.note || '—' }}</span>
|
||||
</div>
|
||||
<div class="detail-meta__item">
|
||||
<span class="detail-meta__label">Status</span>
|
||||
<span
|
||||
class="badge"
|
||||
[class.badge-active]="!detail.row.isReversed"
|
||||
[class.badge-reversed]="detail.row.isReversed"
|
||||
>
|
||||
{{ detail.row.isReversed ? 'Reversed' : 'Active' }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Reversal info (if reversed) -->
|
||||
@if (detail.row.isReversed) {
|
||||
<div class="detail-reversal">
|
||||
<mat-icon>undo</mat-icon>
|
||||
<div>
|
||||
<strong>Reversed</strong>
|
||||
@if (detail.row.reversedAt) {
|
||||
<span> on {{ detail.row.reversedAt }}</span>
|
||||
}
|
||||
@if (detail.row.reverseReason) {
|
||||
<span class="detail-reversal__reason"> — {{ detail.row.reverseReason }}</span>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<!-- Denomination breakdown -->
|
||||
<div class="detail-denom-head">
|
||||
<mat-icon>payments</mat-icon>
|
||||
Denomination Breakdown
|
||||
</div>
|
||||
|
||||
@if (detail.loading) {
|
||||
<div class="pg-empty" style="padding: 20px 0">Loading denomination details…</div>
|
||||
} @else if (detail.denominations.length === 0) {
|
||||
<div class="pg-empty" style="padding: 20px 0">No denomination data recorded.</div>
|
||||
} @else {
|
||||
<table class="pg-table detail-denom-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Denomination</th>
|
||||
<th style="text-align: center">Count</th>
|
||||
<th class="num">Total</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@for (d of detail.denominations; track d.denominationValue) {
|
||||
<tr>
|
||||
<td>
|
||||
<span class="pg-chip">₹{{ d.denominationValue }}</span>
|
||||
</td>
|
||||
<td style="text-align: center; font-weight: 600">{{ d.count }}</td>
|
||||
<td class="num">₹{{ d.totalAmount | number: '1.2-2' }}</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr class="detail-denom-total">
|
||||
<td><strong>Total</strong></td>
|
||||
<td style="text-align: center">
|
||||
<strong>{{ totalCount(detail.denominations) }}</strong>
|
||||
</td>
|
||||
<td class="num">
|
||||
<strong>₹{{ detail.row.amount | number: '1.2-2' }}</strong>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user