Root cause of blank/clipped print output across the app: the document root
(html/body) is globally locked to one viewport height with overflow hidden,
and Angular Material's drawer/tab-body containers each add their own
on-screen scroll clip on top of that. main.scss now frees the full chain for
print (document root, CDK drawer/sidenav containers, mat-tab-body, and the
account-view's mat-tab-nav-bar which was rendering as a stray grey scrollable
strip since it isn't covered by the mat-tab-group header rule already hidden).
Also fixed both certificate print dialogs (share-certificate-dialog,
deposit-certificate-dialog) reusing a `::ng-deep body > :not(.cdk-overlay-
container)` rule to hide the shell during their own print: under Angular's
style encapsulation this style is emitted fully unscoped into the global
stylesheet and is never removed once the component has loaded once in a
session, silently blanking every other page's print output for the rest of
the session. Dropped `::ng-deep` from that one selector so it goes back to
being properly scoped (and therefore inert, matching the other two dialogs
that never had this bug) — the app shell is already hidden for every print
via the global main.scss rules, so no dialog needs its own global override.
- Certificate PDFs, the preview dialog, and both share-certificate list views
(demo + live) now pull bank name/address/reg no/seal text from the
Institution Profile instead of a hardcoded "Nexora" identity.
- Certificate preview dialog print CSS was clipped to the dialog's on-screen
scroll viewport (maxHeight config); switched to position:fixed + unclipped
overlay ancestors so the full certificate prints, not just a border sliver.
- Global print stylesheet now also hides the app shell's real 2-row nav menu
(.main-header/.kpi-ticker, not routed through <mifosx-toolbar>) and frees
the CDK sidenav/tab-body scroll clipping, so printing any page no longer
captures the nav chrome or gets cut off to one screen's height.
Same number in both fields defeats the point of having a second contact
route, and re-running DIP on an identical number is pointless. Added a
cross-field validator on alternateMobileNo, re-checked whenever mobileNo
changes, with a matching error message and the Verify-with-DIP button
disabled while the clash exists.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The CKYC tab's document cards now open a dedicated dialog (with client-side
preview) instead of expanding inline, collecting document type, number, and
issue/expiry dates the same way client creation does. Fixes several bugs
found along the way:
- Uploading a document type that's valid for both identity and address
(Aadhaar, Passport, etc.) no longer 404s or 500s — the "no such endpoint"
and case-sensitive ClientIdentifierStatus.valueOf("Active") crashes are
both resolved.
- Edit Client's Identity-proof and Address-proof steps no longer show each
other's document when both are dual-purpose OVD types, and no longer show
stale/mismatched front-back scans after a document type change.
- Address-proof's own document preview never showed a document at all when
no m_client_kyc record existed yet.
Document number and issue/expiry dates are persisted on the identifier
(documentKey + a shared "Issue date: ..., Expiry date: ..." description
convention) and read back by both the CKYC tab and Edit Client so the same
details appear everywhere.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- 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>
- Add Balance Sheet report and disabled-features accounting config
- Point menu-access tenant header and env.js/environment.ts tenant identifier
at env config instead of hardcoded 'default'/'lincpay' literals
- Surface the real backend error (not a generic "no reference id") when an
OTP send fails in contact-otp-block
- Fix branch-day "₹null" display bug (null vs undefined) and add a guard
blocking a branch's first-ever day open before cash denomination migration
- Dynamically size the denomination count input and block re-opening an
already-open business day from Migrate Cash Denomination
- Lock the denomination-managed cash GL row in Migrate Opening Balances
(read-only, with a link back to Migrate Cash Denomination)
- Remove duplicate Cancel/Submit action bars on the Share Product and
Savings Account creation preview steps; align Previous into the same row
- Hide "Apply Collection" on a share account once its advance collection
is already settled (further purchases go through Apply Additional Shares)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adds the frontend half of the per-tenant menu-access ceiling
(TenantMenuAccessApiResource on the backend): a bank cannot show a top-nav
section the platform operator has capped, no matter what any role inside
that tenant grants itself — closing the gap where a role carrying
ALL_FUNCTIONS (as "Clerk" was found to, in two tenants this session)
bypassed every ordinary MENU_.../SIDEBAR_... permission check.
- tenant-menu-access.service.ts: loads the current tenant's list once,
into a plain Set (not an Observable the directive would have to
subscribe to, since mifosxHasPermission's setter runs synchronously).
A failed load is treated as "nothing disabled" so a network hiccup on
login never hides the whole nav.
- has-permission.directive.ts: checks the tenant's ceiling first, ahead of
the ALL_FUNCTIONS bypass — that ordering is the actual fix.
- shell.component.ts/html: the nav now waits on the list being loaded
before rendering at all, so a disabled menu is never shown and then
hidden a moment later.
- New standalone platform-admin/menu-access screen (#/platform-admin/
menu-access), reachable without logging in — its own X-Api-Key is the
real boundary, checked on the backend, not this route. Lets the
operator pick any tenant and toggle its menu list. Redesigned per
request: full-width layout, icon-matched toggle tiles (same icon per
item as the real nav), live enabled-count, connection status.
- Loan Origination and Investment now use their own MENU_LOAN_ORIGINATION
/ MENU_INVESTMENT codes (see backend 0542) instead of sharing
MENU_ADVANCES / MENU_RBI, so all 27 nav items are independently
controllable from this screen.
Also: src/assets/env.js — restored 'socity_bank' to
fineractPlatformTenantIds. The tenant now exists in the tenant-store
database; the comment explaining its earlier removal was stale.
Brings in the Product Approval feature (anshul.rathore) — a unified Approvals
screen for Loan/Savings/Current/Share/FD/RD/Charge product requests:
- Merges two existing pending-request sources into one list: staged product
edits (m_saving_product_temp, via /{producttype}/pending) and native
maker-checker entries (/makercheckers) for product CREATE/DELETE and
LOANPRODUCT/CHARGE of any action.
- Checker Inbox no longer lists product requests at all — they now live only
in Product Approval, so a checker isn't checking two queues for the same
thing. Clicking a non-product row now navigates straight to that entity's
own view page when one exists, instead of always opening a detail dialog.
- View Checker Inbox dialog gains a caller-supplied heading (used when opened
from Product Approval) and a notice steering staged product edits back to
Product Approval instead of being actioned in place.
- Route renamed pending-savings-products -> product-approval, with the old
path kept as a redirect for existing bookmarks/links.
8 files conflicted with dev's own recent Checker Inbox work (popup-based
detail view, e8097bc2/63134f17) and were resolved by hand, keeping both
sides' real functionality rather than picking one branch wholesale:
- product-edit-diff-dialog.component.{ts,html,scss}: kept dev's diff dialog
(resolves GL account ids to names, aliases fields like currencyCode against
the stored product, normalises the two date shapes the API uses) over
maker-checker's simpler raw-value version.
- pending-savings-products.component.{ts,html}: kept maker-checker's full
isPendingEdit()-based dispatch (dev's version was a strict subset of it).
- view-checker-inbox.component.{ts,html,scss}: kept dev's per-entry Delete
action and maker-checker's recursive Command-payload tree renderer and
custom heading side by side.
Also recovered two regressions the merge introduced silently (no conflict
markers, so `git merge` gave no warning):
- tasks.service.ts lost deleteMakerChecker() entirely — restored.
- Checker Inbox's bulk Delete action (button, deleteChecker()/
bulkDeleteChecker(), and its .cv-btn-delete style) was dropped across three
files — restored to match dev's pre-merge behaviour exactly.
And one duplicate the merge produced without a conflict marker: two
independent viewEntry() implementations landed in checker-inbox.component.ts
(TS2393, caught at build). Kept maker-checker's entity-view-page-routing
version — a superset of dev's dialog-only version — and dropped the duplicate,
along with a leftover diagnostic console.log.
my-work.component (My Vouchers):
- The five summary tiles (Received/Payments/Journal/Entered/Approved) were
bound directly to the server's day-total fields, so they stayed fixed at
the combined "entered + approved" figure no matter what the Side/My part
dropdowns were set to. They're now pinned to this user's own entered rows
only (enteredRows), independent of both filters, so "how much did I
personally put through today" reads correctly regardless of what the table
below happens to be filtered to. The table and its dropdowns are unchanged
and still default to showing everything.
transaction-entry.component (Fund Transfer):
- onSave()'s plain bank-transfer branch (SD/CA/CB only) was catching every
'Fund Transfer' row before the GL-aware Disbursement/Collection branch
below it could see them, so a Fund Transfer against a GL account was always
rejected with "Invalid Account Type" even though that branch already
supports it under the same label. Fund Transfer rows that include a GL leg
now skip the plain-transfer branch and fall through correctly.
my-disbursement-requests.component (Disbursements & Transfer list):
- getCreditEntries() only read the stored credit_entries JSON, which holds
the full picture for Collection (its GL leg is one of the entries) but not
for Disbursement/Fund Transfer, whose GL is the request's own top-level
source (gl_account_no/dr_amount) and was never in that array. The DR/CR
breakdown for those two types showed only the credit side, looking like
half the entry was missing. The GL leg is now synthesised back in as the
first row for those two types, matching what actually posted.
- Renamed the clerk's "My Disbursements" / "My Disbursement Requests" screen
to "Disbursements & Transfer" throughout (nav tab, dropdown menu, route
title/breadcrumb, cashier counter link, page header) — the register covers
Disbursement, Collection, Fund Transfer and Bank Transfer requests, and the
old name read as disbursement-only. "My Requests" (Withdrawal Slip
requests, a separate register) is renamed to "Withdrawal Request" for the
same reason: neither name said what was actually inside.
Two share-account charge bugs found while chasing why a share account's
entry-fee charge wasn't showing up in the "Apply Share Advance
Collection" flow:
- create-shares-account.component.ts / edit-shares-account.component.ts:
the submit payload built charges as { chargeId: charge.id, amount }.
A charge seeded from the product's own default template arrives as
ShareAccountChargeData, where the real charge id lives in `chargeId`
and `id` is null (no saved ShareAccountCharge row yet); only a charge
picked from this step's own "Charge" dropdown (plain ChargeData) has
it in `id`. So `charge.id` alone silently produced chargeId: undefined
for the common case (accepting the product's own default charges),
Angular's JSON.stringify dropped the undefined field, and the backend
received a charge with no id to attach -- the account got created with
zero persisted charges no matter what the product had configured.
Verified via the actual submitted command JSON in the DB
(charges:[{"amount":200}], chargeId missing entirely). Fixed by
falling back to charge.chargeId || charge.id in both places.
- shares-account-charges-step.component.ts: on the "edit an existing
account" flow, the account's real saved charges (possibly a correctly
empty array) get patched into chargesDataSource once the shared
currencyCode control settles, but that patch never cleared the
`pristine` guard. ngOnChanges fires again on the same input-update
cycle (the sibling Terms step, declared earlier in the wizard, patches
currencyCode from its own ngOnChanges, which synchronously triggers
this component's currencyCode subscription, and Angular then runs
this component's own ngOnChanges right after) -- with `pristine` still
true, that re-seeded chargesDataSource from the product's *current*
default template, silently overwriting the real (possibly empty)
saved state. Set pristine = false once the real charges are patched
in, so a later ngOnChanges can't clobber it.
Also: offices.component.ts now distinguishes an office delete that
actually completed from one that was queued for checker approval
(response.rollbackTransaction, the same signal every other
maker-checker-eligible screen in this app already keys off), instead of
always claiming "Office Removed" regardless of which happened.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The tenant selector (mifosx-tenant-selector, already wired into the login
page) hides itself whenever fineractPlatformTenantIds resolves to a single
entry -- and env.js only ever listed 'abc_bank', so the dropdown never had
a reason to show even though Socity_bank and, as of this session, Default
Bank are all live, reachable tenants.
Lists all three identifiers exactly as registered in the tenants table
(default, abc_bank, socity_bank) so a user can actually pick which bank to
log into instead of being stuck on whichever one was hardcoded.
The manager's Closure Review dialog only showed the amount once the request
reached APPROVED or later -- closing_amount/rounding_amount/cashier_disbursed_amount
were null on a PENDING record, since the backend only filled them in at
approve() time. A manager reviewing a still-pending closure saw client name,
payout mode and token, but no figure to actually approve.
The backend now populates those columns at submission (interest is posted
for real at that point, so the figure is already known -- see the matching
backend commit), so this just stops gating the amount card on
closing_amount != null and moves it to the top of the dialog as "Payout
Amount", shown for every status.
Also added: Closure Date ("Interest Posted As On"), Transaction Id once
close() has run, and a "Handed Over By Cashier" section once disbursed --
so the full lifecycle of a closure is visible from one dialog instead of
needing to cross-reference the account's own transaction history.
Ticking "Close this account" on the Transaction Entry Action popup called
GET /clerk/closure-requests/preview/{id} -- a dry run that computed the
payout and immediately rolled it back, so the account's own balance stayed
unchanged until a manager later approved the closure.
Wired to the new POST /clerk/closure-requests/post-interest/{id} instead
(see the matching backend commit), which posts the interest for real and
returns the account's actual resulting balance. Renamed
ClerkClosureRequestService#preview to #postClosureInterest to match, and
reworded the popup copy and loading state so it no longer implies posting
happens later at Save ("posted to the account as of ..." instead of
"calculated to ... and posted the moment you press Save").
Also corrected a stale comment on the balance-check bypass for a pending
closure: it used to justify the bypass by saying interest was NOT YET
posted, which stopped being true the moment the checkbox itself started
posting it for real.
The dialog rendered but read badly: the heading appeared twice, and every field
ran together onto one line ("ID: 125Status: User: mifosAction: DELETE").
Cause was the global flex-40/flex-60/flex-fill utilities the template used --
they are sized for a full-width page, so inside a 680px dialog the label and
value columns collapsed and wrapped into each other. Replaced them with a
self-contained label-above-value grid that reflows to one column when narrow,
so the same markup reads correctly as a page and as a popup.
Also: moved the heading into the shared header so it is rendered once in both
modes, gave the actions real buttons instead of Material raised buttons styled
by two global overrides, put DELETE in a red tag so a destructive entry is
visible at a glance, and dropped MatDivider/MatDialogModule from imports now
that the markup no longer uses them.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Clicking a row navigated away to its own page, costing the checker the list and
whatever search they had set up. It now opens in a dialog over the list, the
same pattern the Disbursement and Closure Requests tabs already use.
ViewCheckerInboxComponent gained the optional MatDialogRef/MAT_DIALOG_DATA pair
rather than being duplicated, so the direct route still works for a bookmarked
link. Two differences follow from being a dialog:
- the list rows carry only summary fields, so the detail (which is what has
commandAsJson) is fetched here; by route it stays resolver-provided. The
template reads checkerInboxDetail.* unguarded, so it is now behind an @if
with a loading state -- otherwise a dialog would render against undefined.
- commandAsJson is absent on some entries (a DELETE carries no payload) and
JSON.parse(undefined) throws. By route that broke the page; in a dialog it
would have left an empty shell open. Parsing is now guarded.
The list only reloads when something was actually actioned, since reload()
re-navigates the route and would otherwise discard the checker's search on a
plain close.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Brings in the UI side of maker-checker for users and roles: a Pending User
Edits tab with a compare dialog, user/role create-edit-view wired to the
pending-request flow, plus keyboard shortcuts and inline-create dialogs.
Both conflicts resolved in dev's favour:
.env.ts — auto-generated build stamp; dev's (260901) is the newer one.
share-product-general-tab.component.html — dev had deliberately removed the
per-product Dividends button, leaving a comment explaining that dividends are
declared society-wide from Share Products -> Dividends because the board
resolves one rate for the year rather than one per product. The branch simply
predates that change, so taking its side would have resurrected a button that
was removed on purpose.
checker-inbox-and-tasks.component.html and tasks-routing.module.ts auto-merged
cleanly, with both the new Pending User Edits tab and the existing Closure
Requests tab intact.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The whole DD-against-cash path was already written and reachable only by a
cashier -- isDdCashGlRow() gates on a cash payment type against a GL account,
onSave() makes the cashier count Face Value + Charges + GST exactly and
enforces the admin DD limit at intake, and buildDepositPayload() persists that
breakdown so the Sponsor DD issuance screen reads it back after approval. None
of it could be selected, because DD was missing from cashierTypOptions.
Also adds the DD case to onTypChange, without which selecting DD set no
defaults at all: it needs Cr (a draft is bought with cash, so money comes in),
a cash payment type, and AC.TP = GL, which are the three things isDdCashGlRow()
looks for. Missing any of them, the DD Charges & GST panel never appears and
the row posts as an ordinary entry with the charges silently dropped.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Replaces the one-click Close action on the savings account page (removed from
the Danger Zone menu) with a maker-checker flow, since closing an account pays
real cash out of a teller's drawer.
Clerk: an Action button on Transaction Entry, shown once an ACTIVE savings
account is loaded. Ticking "Close this account" previews the payout -- balance
plus interest calculated to today by the same code the closure itself runs --
and Save drops that figure into the slip's AMOUNT. The clerk then fills
TOK. NO. on the slip and presses Save, which raises the request. Token and
narration deliberately live on the slip, not in the popup, so the closure is
entered like any other transaction.
Manager: a Closure Requests tab in the Approval Center, reviewed in a popup
dialog (matching Disbursement Requests) rather than a separate route.
Cashier: the closure token is recognised at the counter alongside withdrawal
and dividend tokens, auto-filling the rounded cash figure, locking it, and
closing the account once the denomination is counted.
Save-path fixes, all of which silently blocked a valid closure:
- amount came from the denomination total whenever clerkMode was false --
which it is for any route other than the Clerk Dashboard wrapper -- so the
calculated payout was replaced by zero
- the balance check rejected the payout because it legitimately exceeds
today's withdrawable amount: it includes interest close() posts before
withdrawing. Min-balance, withdrawal-facility and clerk-side denomination
checks do not apply to a closure either
- on the cashier side the account is already CLOSED, so accountDetails is a
stub with no balance and the same check reported "Withdrawable 0.00"
- the closure branch had to precede the plain clerk-withdrawal branch: a
closure is a full-balance withdrawal, so that branch would have swallowed
it and the account would never have closed
- onSave's one silent return now says what is missing, instead of leaving
Save looking like a broken button
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- Register the missing edit-details route so the Share Account "Edit Details"
maker-checker screen (already built) is actually reachable, and remove the
stale hardcoded disable on its menu entry.
- Fix Terms step race: Default Savings Account, Total Shares and Application
Date now display correctly in edit mode instead of racing an async
product-template fetch or reusing pending-application-only fields.
- Show a client's linked share account number on the Savings Account General
tab.
- Replace the inline diff panel on Pending Share Account Edits with a popup
compare dialog (mirrors the savings equivalent), showing only fields that
actually changed.
- Redesign Pending Share/Savings Account Edits, Share Withdrawal Requests,
Dividend Requests and Share Addition Requests with a consistent header,
search box and (where the data supports it) date-range filters, matching
the existing Withdrawal Requests screen.
- Savings account creation shows a required "Default Share Account" picker once Share Linking is
enabled, populated from the client's active share accounts; submits shareAccountId alongside it.
- Fixes a real data-loss bug on Share Account creation: the Charges step re-seeded its table from
the product's default charges on every ngOnChanges firing (e.g. stepping back to Details and
forward again), silently discarding a charge the clerk had already added, edited, or removed - a
pristine guard existed for exactly this but wasn't checked in ngOnChanges. Now it is.
- Removes the hard "required" on Share Account creation's Default Savings Account field, matching
the backend now accepting a share account with no linked savings account.
- New /accounting/migrate-cash-denomination screen: counts a branch's opening cash into notes and
coins, checks it against (or defines, if unset) the Cash GL account's balance, and opens the
branch's first business day with that same count - the vault-side counterpart to Migrate Opening
Balances, kept under Accounting rather than Branch Ops/Cashier so it isn't reachable by mistake.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Replaces the flat, hard-to-scan opening-balances form with a stepped layout: branch pick, a
clearly-explained contra account, a pinned Debit/Credit balance status (green "Balanced" vs red
"Out of balance by X"), and account rows grouped by type with a mobile-responsive grid. No
behavior change - same form controls, same validation, same submit flow.
- env.js: default/available tenant switched from default,socity_bank to abc_bank.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
'Fund Transfer' and 'Enter Bank Transfer' are the same flow under two TYPE labels -- onTypChange()
already defaults them identically and the auto-mirror-row logic already treats them as equivalent --
but the Resolution No./Meeting Date fields and onSave()'s clerk-transfer submission gate only checked
'Enter Bank Transfer'. Picking 'Fund Transfer' for a Share row silently hid the board-resolution
fields and skipped submitShareRedemptionTransfer() entirely, falling through to the wrong save path.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Add Approval Center tab "Share Addition Requests": lists every pending additional-share tranche
across all accounts (backed by the new /v1/shareadditionrequests endpoint), with a detail popup
showing the board resolution and the route-specific proof of funding (voucher(s) for cash, or the
linked savings account for savings). Approve/Reject call the same native
approveadditionalshares/rejectadditionalshares commands the account-page buttons already used.
- Remove "Debit from Savings" dialog/button and the "Share Savings Debit" Checker Inbox tab -- zero
rows ever recorded on either tenant since it was built.
- Remove "Approve Additional Shares"/"Reject Additional Shares" from the account-page menu now that
every tranche is reviewed from the centralized queue instead.
- Harden SharesButtonsConfiguration.removeButton(): a not-found name fed to splice(-1, 1) was quietly
deleting the LAST button in the array instead of doing nothing -- removing the two menu entries
above would otherwise have silently broken the rest of the Active-account button bar.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Apply Collection dialog: replace product-config auto-resolved GL account with a required GL +
voucher search (mirrored for Share and Entry Fee receipts). The entry-fee receipt is tracked
separately from the share receipts and sent as its own field so its amount is never swept into the
Sundry-side total or double-posted — it only verifies the fee was paid, since that money already
sits wherever the cashier deposited it.
- Shows the account's required total (share value + entry fee) and live coverage up front, instead of
only after a failed apply.
- Apply Additional Shares: same mandatory GL + voucher pattern for its by-voucher lookup, plus a GL
account picker fed by the new /shareadvancecollection/glaccounts endpoint.
- shares-account-charges-step: fixed a race where the currency-control subscription (meant only for
the edit-an-existing-application flow) wiped out product charges that ngOnChanges had just seeded
from the same product-selection event, leaving new accounts with no charges.
- shares-account-view: hide "Share Certificate" until collection_applied is true, so a certificate
can't be printed for shares nobody has actually paid for yet.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Account Statement is no longer a jsPDF file that downloads the moment the
dialog opens. It now shows a live, on-screen preview styled the same way
the working Passbook screen already is (bank header, branch line,
account-details band, balance strip, transaction table), with its own
date-range filter, and only prints via the browser's print dialog on an
explicit click -- exactly the same clone-into-a-popup-window mechanism
Passbook already uses, so "Save as PDF" is the reader's own choice rather
than something forced on open.
Both Passbook and the new Statement preview pull the bank name, license
number, and branch name/address/IFSC/MICR from Institution Profile and
Branch Profile instead of a hardcoded bank name -- a printed passbook or
statement now actually identifies which bank and branch issued it. Cheque
Book's own issuance detail screen gets a matching "Print" action, laying
out a one-page issuance-slip PDF from data already on that screen (which
book/series, leaf range, issued-to account, issue date).
Cash Hold and Clearing Hold on the Transaction Entry balance strip were
both hardcoded 0.00 placeholders; they now read the account's real
hold-category breakdown, and a stray "Freeze Amount" placeholder a few
rows up is wired to the working getter that was already sitting right
next to it.
A clerk withdrawal's own terminal status is WITHDRAWN, not APPROVED --
the Day Book screen had the same status-string gap the backend GL report
did: neither its running CR/DR totals nor its status badge recognized a
completed withdrawal, so real money that had gone out never moved the
totals off zero. The Closing Cash Report's GL Entries panel also never
refreshed for a newly picked date once it had already been opened once --
"Load" hid the panel instead of refreshing it, leaving a stale, wrong-date
table under a header that had already relabelled itself correctly.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The Day Open form's note/coin table started at zero even though the
branch's own closing count from the day before was already on record --
whoever opened the day had to re-key numbers that were already known.
It now auto-fills from that closing count, flags any row a manual edit
moves away from it, and shows a live Tallied/Short/Excess comparison
against it -- so a short or excess opening count is visible before the
day is opened, not discovered later. A reason is required once a mismatch
exists, matching the new backend enforcement.
Also fixes the register table's date chip wrapping onto two lines when
the column narrows.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Branch Day open/close now captures a denomination-wise count (carried
forward automatically to the next day), and shows an auto-fetched EOD
summary at close time -- vault + every cashier's position, a branch-total
reconciliation against the book figure, and each cashier's
reconciliation/settlement status and transaction count -- so closing the day
no longer means separately checking Vault Position and every cashier's own
screen by hand. New Vault Position screen (branch-ops menu) mirrors Cashier
Position for the teller/vault. Cash Transfer now shows the vault's live
per-denomination availability while counting a handout, with a client-side
warning before it can be over-counted.
New Organization screens for Bank Profile, Branch Profile and Clearing GL
Configuration, wired into the Organization landing page and the
previously-dead "Bank Profile" admin menu button.
Cashier Transaction Entry: TYPE is now Receipt/Payment only (cash-only TXN
TP.) on the cashier side, with no change to the clerk dashboard's own
Withdrawal Slip/Cheque/Disbursement/Enter Bank Transfer/DD flow beyond
adding a new Fund Transfer type alongside Disbursement for a GL credit that
isn't a loan payout. Neither TYPE nor TXN TP. offers a blank placeholder
option anymore -- a new row starts on a real default instead. Footer no
longer polls the business-date config for cashier/clerk roles, who never
have permission to read it.
Disbursement & Transfer Requests: "Review" now opens the review screen as a
popup instead of navigating to a separate route, refreshing the list on
close; the review screen recognises the new Fund Transfer request type
too, and its non-functional "+ Disbursement Review" tab-styled label is now
a plain heading.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>