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>
- 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>
- 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>
Replaced checked in package-lock.json by regenerated one.
Ran ng update @angular/core@20 @angular/cli@20
Ran npm install @angular-builders/jest@^20.0.0 @fortawesome/angular-fontawesome@^3.0.0 @swimlane/ngx-graph@^11
Ran npm install ngx-mat-select-search@^8.0.2.
Ran ng update @angular/material@20.
Updated all eslint and typescript to the latest versions.
Removed @angular-devkit/schematics.
Updated fontawesome.
Updated rxjs and tslib.
Moved required node version from 16 to 20.
Updated jest-preset-angular.
Set preserveWhitespaces to false.
Corrected two type declarations in two typescript files to make ng serve run without errors.
Removed unused angular-devkit/schematics from view-user.component.ts .
Updated list of supported browsers.
Upgraded prettier.
Ran prettier . --write the first time.
Ran prettier . --write the second time.
Ran ng generate @angular/core:inject with defaults, excepted a handful of files.
Fixed remaining eslint problems.
Added dist directory to ignores in eslint.config.js.
Let prettier fix formatting, almost everything is just line breaks.
Made htmlhint ignore @if and @for Angular constructs.
Updated node version in Github workflow to 22.12.0 (build.yml).
Updated .env.ts.
Updated Angular datetime format strings from YYYY-MM-DD to yyyy-MM-dd.
Merged changes from dev into angular20 branch.