fix(cashier): tag GL-entry denomination to the vault, show both voucher legs

- Transaction Entry's manual GL-entry screen was recording its denomination
  breakdown against whichever GL account the teller selected, not the vault
  account whose physical notes actually moved -- resolve and use the Cash
  Vault GL's own code/name dynamically instead
- Closing Cash Report's GL Entries table showed only the one account its
  denomination row knew about; now shows both the debit and credit account
  of each voucher (backend now returns debitParty/creditParty), matching
  what My Vouchers already shows for the same entries

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-14 07:19:50 +05:30
co-authored by Claude Sonnet 5
parent 7b77166b19
commit ab58d7f74c
2 changed files with 36 additions and 6 deletions
@@ -1617,6 +1617,13 @@ export class TransactionEntryComponent implements OnInit, OnDestroy {
private lastLoadedAcNo = '';
private acNoInput$ = new Subject<{ row: TxnRow; index: number; value: string }>();
cashVaultGlId: number | null = null;
/** The Cash Vault GL account's own code and name — the denomination breakdown for a manual GL
* entry has to be filed against THIS account, not whichever account the teller typed in, since
* that account is never the one physical notes actually moved through (see submitGlJournalEntry).
* Both resolved dynamically off whatever this tenant's own financial-activity mapping names as
* its cash/vault account (see loadCashVaultGl) — never a literal account name or code. */
cashVaultGlCode: string | null = null;
cashVaultGlName: string | null = null;
// Joint holder expanded details (keyed by index)
expandedHolder: number | null = null;
@@ -3121,6 +3128,8 @@ export class TransactionEntryComponent implements OnInit, OnDestroy {
byName(/vault/i) ?? byName(/cash/i) ?? items.find((a: any) => a.glAccountData?.type?.value === 'ASSET');
if (found?.glAccountData?.id) {
this.cashVaultGlId = found.glAccountData.id;
this.cashVaultGlCode = found.glAccountData.glCode ?? null;
this.cashVaultGlName = found.glAccountData.name ?? found.financialActivityData?.name ?? null;
}
});
}
@@ -5648,11 +5657,15 @@ export class TransactionEntryComponent implements OnInit, OnDestroy {
count: this.countFor(d),
subtotal: this.subtotalFor(d)
}));
// Filed against the Cash Vault GL, not the account the teller selected on screen: that
// selected account (e.g. Sundry Creditors) is the other leg of the journal entry, and
// never the one whose physical notes actually changed hands. Tagging the breakdown to it
// instead of the vault is why this cash never reached the cashier/vault position.
this.http
.post('/cashier/gl-denomination', {
txnId: res.transactionId ?? res.resourceId,
accountNo: this.accountDetails?.glCode ?? row.acNo,
accountName: this.accountDetails?.name ?? '',
accountNo: this.cashVaultGlCode ?? row.acNo,
accountName: this.cashVaultGlName ?? 'Cash at Vault',
txnType: isDeposit ? 'DEPOSIT' : 'WITHDRAWAL',
txnDate: txnDateIso,
paymentTypeName: selectedPt?.name ?? 'Cash',