feat(loans): add quick-create modal for loan products (#326) - #543
feat(loans): add quick-create modal for loan products (#326)#543vaishaldsouza wants to merge 1 commit into
Conversation
- Add standalone LoanProductQuickCreateDialogComponent with a 6-field form merged with fixed defaults. - Integrate LoanProductQuickCreateDialogComponent with LoanFormComponent via DialogService for in-context creation. - Add comprehensive unit tests covering validation, creation, dismissal, and error handling.
E2E — mocked backend🎭 E2E Tests✅ All green — 352 passed · 0 failed · 1 skipped, across 28 spec files in 6m 52s. By spec file
All 353 tests — click to expand
Slowest 10 — what the shard counts should be tuned against
📼 Download the HTML report, videos and traces — see the Generated by run 34636580186 from |
E2E — real Fineract🎭 E2E Tests✅ All green — 78 passed · 0 failed · 0 skipped · 1 flaky, across 24 spec files in 7m 4s.
|
| Spec | ✅ | ❌ | ⏭️ | Time |
|---|---|---|---|---|
| backend.setup.ts | 3 | 0 | 0 | 5.6s |
| batch-api-operations.spec.ts | 5 | 0 | 0 | 31.3s |
| center-servicing.spec.ts | 2 | 0 | 0 | 18.3s |
| client-legal-form-search.spec.ts | 1 | 0 | 0 | 5.1s |
| client-transfer.spec.ts | 4 | 0 | 0 | 46.7s |
| deposit-account-servicing.spec.ts | 3 | 0 | 0 | 24.2s |
| deposit-product-configuration.spec.ts | 3 | 0 | 0 | 15.8s |
| group-membership.spec.ts | 3 | 0 | 0 | 47.0s |
| loan-account-actions.spec.ts | 3 | 0 | 0 | 23.3s |
| loan-charge-off.spec.ts | 2 | 0 | 0 | 19.7s |
| loan-product-accounting.spec.ts | 1 | 0 | 0 | 27.1s |
| loan-servicing.spec.ts | 2 | 0 | 0 | 15.7s |
| login.spec.ts | 4 | 0 | 0 | 4.7s |
| parity-screens.spec.ts | 8 | 0 | 0 | 37.7s |
| rbac-backend-restricted-user.spec.ts | 7 | 0 | 0 | 31.8s |
| rbac-multi-permission.spec.ts | 9 | 0 | 0 | 52.7s |
| full-demo.spec.ts | 1 | 0 | 0 | 1m 6s |
| loan-lifecycle.spec.ts | 4 | 0 | 0 | 2m 7s |
| loan-schedule-type.spec.ts | 3 | 0 | 0 | 36.3s |
| report-parameter-backend.spec.ts | 4 | 0 | 0 | 22.6s |
| savings-transaction-correction.spec.ts | 1 | 0 | 0 | 5.9s |
| share-account-servicing.spec.ts | 2 | 0 | 0 | 17.9s |
| share-product-accounting.spec.ts | 1 | 0 | 0 | 23.8s |
| teller-cash-management.spec.ts | 2 | 0 | 0 | 36.0s |
All 78 tests — click to expand
backend.setup.ts
- ✅ seed backend reference data —
2.2s - ✅ seed backend reference data —
1.6s - ✅ seed backend reference data —
1.8s
batch-api-operations.spec.ts
- ✅ Batch API Operations against Fineract › runs the sample batch scenario — create client, create loan, add and read back a charge —
6.4s - ✅ Batch API Operations against Fineract › shows a parse error instead of submitting when the batch input is not valid JSON —
6.3s - ✅ Batch API enclosingTransaction semantics against Fineract › rolls back the earlier steps when enclosingTransaction is true and a later step fails —
8.8s(retried 1×) - ✅ Batch API enclosingTransaction semantics against Fineract › does not roll back the earlier steps when enclosingTransaction is false and a later step fails —
5.2s - ✅ Batch API Operations on a mobile viewport against Fineract › the sample batch scenario is reachable and works by touch at mobile width —
4.5s
center-servicing.spec.ts
- ✅ Center servicing › a center is activated, staffed and given a group —
12.9s - ✅ Center servicing › notes are recorded against the center —
5.4s
client-legal-form-search.spec.ts
- ✅ Client list: legal form filtering › an entity client appears in the main client list —
5.1s
client-transfer.spec.ts
- ✅ Client transfer between offices › a proposed transfer is held until the destination accepts, and then the client moves —
11.5s - ✅ Client transfer between offices › a rejected transfer leaves the client on hold, and withdrawing is the way back —
12.9s - ✅ Client transfer between offices › a client can be transferred in one step when the user may act for both offices —
10.1s - ✅ Client staff assignment › an officer can be assigned and then removed —
12.2s
deposit-account-servicing.spec.ts
- ✅ Term deposit account servicing › an account is approved, activated and closed before maturity —
10.3s - ✅ Term deposit account servicing › a deposit is recorded, listed, and reversed without leaving the list —
8.5s - ✅ Term deposit account servicing › an application can be rejected instead of approved —
5.3s
deposit-product-configuration.spec.ts
- ✅ Deposit product configuration › a fixed deposit product survives being edited —
5.6s - ✅ Deposit product configuration › a recurring deposit product can be created at all —
4.2s - ✅ Deposit product configuration › a savings product carries its accounting configuration —
6.0s
group-membership.spec.ts
- ✅ Group membership and lifecycle › a group is activated, staffed, given members and a committee, then emptied —
19.7s - ✅ Group membership and lifecycle › notes are recorded against the group and can be removed again —
8.6s - ✅ Group membership and lifecycle › an empty group is closed with a reason, and a group with members is refused —
18.6s
loan-account-actions.spec.ts
- ✅ Loan account lifecycle actions › new action menu items appear only for active loans —
6.4s - ✅ Loan account lifecycle actions › undo disbursal shows a confirm dialog and reverts the loan to Approved —
9.0s - ✅ Loan account lifecycle actions › write off requires confirmation and moves the loan out of Active status —
7.9s
loan-charge-off.spec.ts
- ✅ Loan servicing commands › charges a loan off through the UI and reverses it —
10.6s - ✅ Loan servicing commands › records a goodwill credit through the shared transaction form —
9.1s
loan-product-accounting.spec.ts
- ✅ Loan product accounting › a cash-accounting product is configured, round-trips on edit, and posts to the ledger —
27.1s
loan-servicing.spec.ts
- ✅ Loan servicing: notes and transaction adjustment › notes can be added and removed, with a confirm dialog on delete —
7.1s - ✅ Loan servicing: notes and transaction adjustment › a repayment transaction can be viewed and adjusted with a corrected amount —
8.6s
login.spec.ts
- ✅ Login › login page displays correctly —
1.2s - ✅ Login › login form has required fields —
1.2s - ✅ Login › submit button is disabled when form is empty —
1.2s - ✅ Login › submit button is enabled when form is filled —
1.2s
parity-screens.spec.ts
- ✅ Screens added for platform parity › a manual journal entry can be read whole and reversed —
4.8s - ✅ Screens added for platform parity › an entry that is already reversed is not offered again —
3.7s - ✅ Screens added for platform parity › a report definition can be created, edited and deleted; a core one cannot —
5.4s - ✅ Screens added for platform parity › a core report opens read-only with only its in-use setting —
3.6s - ✅ Screens added for platform parity › a pending loan is approved from the queue, in a batch —
6.2s - ✅ Screens added for platform parity › a fixed deposit is listed as a deposit, not as a savings account —
3.7s - ✅ Screens added for platform parity › an office has a screen, and it carries its custom fields —
4.7s - ✅ Screens added for platform parity › a savings account carries notes, and the note survives a reload —
5.5s
rbac-backend-restricted-user.spec.ts
- ✅ a genuinely restricted Fineract user › holds exactly the permissions their role was granted —
199ms - ✅ a genuinely restricted Fineract user › reaches the screen their permission covers —
4.6s - ✅ a genuinely restricted Fineract user › is refused a screen their permission does not cover, by URL and by the backend —
4.2s - ✅ a genuinely restricted Fineract user › is refused a write screen they can read the list for, and the write itself —
6.6s - ✅ a genuinely restricted Fineract user › is not offered the actions it would be refused for —
3.3s - ✅ a genuinely restricted Fineract user › is shown an action it cannot take, disabled and saying what it needs —
5.5s - ✅ a genuinely restricted Fineract user › the superuser the rest of the suite uses is unaffected —
7.4s
rbac-multi-permission.spec.ts
- ✅ a route declaring more than one permission code (OR semantics) › is admitted by either declared code alone —
4.3s - ✅ a route declaring more than one permission code (OR semantics) › is admitted by the other declared code alone —
4.0s - ✅ a route declaring more than one permission code (OR semantics) › is refused when holding neither declared code, by the router and by the backend —
5.0s - ✅ ALL_FUNCTIONS_READ, against the real Fineract permission catalogue › reaches read screens across modules it holds no specific code for —
8.2s - ✅ ALL_FUNCTIONS_READ, against the real Fineract permission catalogue › is refused every write screen, and the writes themselves —
6.6s - ✅ a restricted session across a real page reload › keeps the same permission boundary after reloading, not just after a fresh login —
9.4s - ✅ a second real action-level gate, distinct from loan repayment › is shown the Approve action disabled and naming what it needs, refused by the backend too —
5.6s - ✅ Security module writes (users, roles), against the real backend › reaches the list screens but is refused the write screens —
9.4s - ✅ Security module writes (users, roles), against the real backend › is refused creating a user and modifying a role, by the backend itself —
243ms
full-demo.spec.ts
- ✅ Full feature demo recording › walk through loan schedule type, lifecycle, custom fields, collateral, and disbursement —
1m 6s
loan-lifecycle.spec.ts
- ✅ Loan lifecycle: creation, approval, disbursement › create, approve, and disburse a Cumulative loan —
33.7s - ✅ Loan lifecycle: creation, approval, disbursement › create, approve, and disburse a Progressive loan —
34.6s - ✅ Loan lifecycle: creation, approval, disbursement › an approved loan can be returned to pending approval —
30.2s - ✅ Loan lifecycle: creation, approval, disbursement › the delinquency tab reads a real loan, and the empty data tabs stay hidden —
28.3s
loan-schedule-type.spec.ts
- ✅ Loan Schedule Type (Cumulative vs Progressive) › loan products list shows a schedule type chip per product —
9.8s - ✅ Loan Schedule Type (Cumulative vs Progressive) › create a Progressive loan product end-to-end and verify it round-trips —
15.5s - ✅ Loan Schedule Type (Cumulative vs Progressive) › loan creation shows the schedule type badge for a Progressive product —
10.9s
report-parameter-backend.spec.ts
- ✅ Dynamic report parameters against Fineract › keeps the parameter form available when a report has cascading lookups —
4.5s - ✅ Dynamic report parameters against Fineract › changing Office changes the Client Listing row set —
6.5s - ✅ Cascading report parameters against Fineract › sends the parent value to the child lookup and clears the child when it changes —
6.6s - ✅ Chart reports against Fineract › renders a chart report as a chart rather than a table —
5.0s
savings-transaction-correction.spec.ts
- ✅ Savings transaction correction › a deposit is reversed and a hold is released —
5.9s
share-account-servicing.spec.ts
- ✅ Share account servicing › an account is approved, activated, traded and closed —
12.5s - ✅ Share account servicing › an application can be rejected —
5.4s
share-product-accounting.spec.ts
- ✅ Share product accounting › a share product is mapped to equity and round-trips on edit —
23.8s
teller-cash-management.spec.ts
- ✅ Teller cash management › a cashier is listed, receives an allocation, and settles cash back —
24.7s - ✅ Teller cash management › settling more than the cashier holds is refused and the form stays usable —
11.3s
Slowest 10 — what the shard counts should be tuned against
| Test | Spec | Time |
|---|---|---|
| Full feature demo recording › walk through loan schedule type, lifecycle, custom fields, collateral, and disbursement | full-demo.spec.ts |
1m 6s |
| Loan lifecycle: creation, approval, disbursement › create, approve, and disburse a Progressive loan | loan-lifecycle.spec.ts |
34.6s |
| Loan lifecycle: creation, approval, disbursement › create, approve, and disburse a Cumulative loan | loan-lifecycle.spec.ts |
33.7s |
| Loan lifecycle: creation, approval, disbursement › an approved loan can be returned to pending approval | loan-lifecycle.spec.ts |
30.2s |
| Loan lifecycle: creation, approval, disbursement › the delinquency tab reads a real loan, and the empty data tabs stay hidden | loan-lifecycle.spec.ts |
28.3s |
| Loan product accounting › a cash-accounting product is configured, round-trips on edit, and posts to the ledger | loan-product-accounting.spec.ts |
27.1s |
| Teller cash management › a cashier is listed, receives an allocation, and settles cash back | teller-cash-management.spec.ts |
24.7s |
| Share product accounting › a share product is mapped to equity and round-trips on edit | share-product-accounting.spec.ts |
23.8s |
| Group membership and lifecycle › a group is activated, staffed, given members and a committee, then emptied | group-membership.spec.ts |
19.7s |
| Group membership and lifecycle › an empty group is closed with a reason, and a group with members is refused | group-membership.spec.ts |
18.6s |
📼 Download the HTML report, videos and traces — see the playwright-report-backend artifact.
Generated by run 34636580186 from 2b4f981. The run executed a fork branch, so treat its contents as unverified.
Add standalone LoanProductQuickCreateDialogComponent with a 6-field form merged with fixed defaults.
Integrate LoanProductQuickCreateDialogComponent with LoanFormComponent via DialogService for in-context creation.
Add comprehensive unit tests covering validation, creation, dismissal, and error handling.
What and why
Adds an in-context "+ Create Loan Product" modal to the New Loan Application form so users can create a missing Loan Product without losing form progress, instead of navigating away to Admin settings.
Closes #326
Verification
npm run lint,format:check,test -- --watch=false,build,check:icons,i18n:check, and./scripts/check-license.sh— all pass.Screenshots
AI assistance (optional)
Checklist
src/app/api/.src/app/core/adapters/instead of direct browser globals or imperative third-party APIs.