feat(cashier+checker): add cashier deposit maker-checker flow and voucher system

- Add cashier deposit service and submit flow via maker-checker
- New CashierDepositService: submit, approve, reject, list endpoints
- Transaction-entry: cashier SD deposit goes to deposit-requests instead of direct credit
- Checker inbox: new Deposit Requests tab with approve/reject review dialog
- Cashier nav: My Deposit Requests tracking page
- Withdrawal requests: show voucher_no from backend instead of JS-padded id
- clerk-withdrawal.service: disburse denominationData accepts null for non-cash
- Role-based checker enforcement: only manager/head-cashier can approve/reject
- Maker cannot approve own request (self-approval blocked at backend)
- Denomination total validation: breakdown must match transaction amount

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Jaanu423
2026-06-12 10:52:35 +05:30
co-authored by Claude Sonnet 4.6
parent 61cb09f352
commit e5d6cd32dc
18 changed files with 2360 additions and 18 deletions
@@ -1415,9 +1415,9 @@
class="te-confirm-header"
[class.te-confirm-header--deposit]="confirmData.type === 'DEPOSIT'"
[class.te-confirm-header--withdrawal]="confirmData.type === 'WITHDRAWAL'"
[class.te-confirm-header--disbursement]="confirmData.isDisbursement"
[class.te-confirm-header--disbursement]="confirmData.isDisbursement || confirmData.isDepositRequest"
>
<span class="te-confirm-icon">{{ confirmData.type === 'DEPOSIT' ? '⬇' : '⬆' }}</span>
<span class="te-confirm-icon">{{ confirmData.type === 'WITHDRAWAL' ? '⬆' : '⬇' }}</span>
<span>Confirm {{ confirmData.isDisbursement ? 'CASH DISBURSEMENT' : confirmData.type }}</span>
</div>
<div class="te-confirm-body">
@@ -1465,6 +1465,25 @@
>Balance already deducted at manager approval — no further deduction</span
>
</div>
} @else if (confirmData.isDepositRequest) {
<!-- Maker-checker deposit: balance credits only after manager approval -->
<div class="te-confirm-row">
<span class="te-confirm-label">Current Balance</span>
<span class="te-confirm-val"
>{{ confirmData.symbol }}{{ confirmData.currentBalance | number: '1.2-2' }}</span
>
</div>
<div class="te-confirm-row te-confirm-row--amount">
<span class="te-confirm-label">Deposit Amount</span>
<span class="te-confirm-val te-cr"
>+{{ confirmData.symbol }}{{ confirmData.amount | number: '1.2-2' }}</span
>
</div>
<div class="te-confirm-row te-confirm-disbursed-note">
<span class="te-confirm-disbursed-badge"
>Sent for manager approval — balance will be credited only after approval</span
>
</div>
} @else {
<div class="te-confirm-row">
<span class="te-confirm-label">Current Balance</span
@@ -1499,7 +1518,13 @@
<button class="te-btn" type="button" (click)="showConfirmDialog = false">Cancel</button>
<button class="te-btn te-btn--primary" type="button" [disabled]="saving" (click)="confirmSubmit()">
{{
saving ? 'Posting…' : confirmData.isDisbursement ? 'Confirm DISBURSEMENT' : 'Confirm ' + confirmData.type
saving
? 'Posting…'
: confirmData.isDisbursement
? 'Confirm DISBURSEMENT'
: confirmData.isDepositRequest
? 'Submit for Approval'
: 'Confirm ' + confirmData.type
}}
</button>
</div>