WEB-477: Re-amortization:- Preview Schedule API during re-amortization#2855
Conversation
|
Note
|
| Cohort / File(s) | Summary |
|---|---|
Loan Re-amortization Form Component src/app/loans/loans-view/loan-account-actions/loan-reamortize/loan-reamortize.component.html, loan-reamortize.component.ts |
Added Preview button to form actions (type="button", accent mat-raised-button, disabled when form invalid, requires 'REAMORTIZE_LOAN' permission). Updated component constructor to inject SettingsService and MatDialog. Implemented new preview workflow with helper methods to prepare data and fetch preview via LoansService, opening ReAmortizePreviewDialogComponent with currency-aware data. |
Re-amortization Preview Dialog Component src/app/loans/loans-view/loan-account-actions/loan-reamortize/re-amortize-preview-dialog/re-amortize-preview-dialog.component.html, re-amortize-preview-dialog.component.ts |
Created new standalone dialog component with template displaying repayment schedule preview using mifosx-repayment-schedule-tab component. Accepts repaymentSchedule and currencyCode via MAT_DIALOG_DATA. Exports ReAmortizePreviewDialogData interface and provides close() method for dialog dismissal. |
Loans Service src/app/loans/loans.service.ts |
Added public method getReAmortizePreview(loanId: string, data: any): Observable to fetch preview data via GET request to /loans/{loanId}/transactions/reamortized-preview endpoint, following existing preview pattern. |
Sequence Diagram
sequenceDiagram
actor User
participant Form as LoanReamortize<br/>Component
participant Service as LoansService
participant Dialog as MatDialog
participant DialogComp as ReAmortizePreview<br/>DialogComponent
User->>Form: Click Preview Button
Form->>Form: prepareReAmortizePreviewData()
Form->>Service: getReAmortizePreview(loanId, data)
Service->>Service: Build HttpParams
Service-->>Form: Observable<{repaymentSchedule, currencyCode}>
Form->>Form: Extract currency (error if missing)
Form->>Dialog: open(DialogComponent, {repaymentSchedule, currencyCode})
Dialog->>DialogComp: Initialize with data
DialogComp-->>User: Display Repayment Schedule Preview
User->>DialogComp: Click Go Back
DialogComp->>DialogComp: close()
DialogComp-->>User: Close Dialog
Estimated code review effort
🎯 3 (Moderate) | ⏱️ ~20 minutes
- ReAmortizePreviewDialogComponent: New standalone dialog component with data binding and MAT_DIALOG_DATA injection—verify proper typing and integration with RepaymentScheduleTabComponent
- Component preview workflow: Verify currency extraction logic, error handling, and data preparation methods align with existing patterns
- Service method: Confirm getReAmortizePreview follows HttpParams construction pattern consistent with getReAgePreview
- Permission and form validation: Ensure Preview button permission checks ('REAMORTIZE_LOAN') and disabled state logic are correct
Possibly related PRs
- WEB-331: Introduce loan reaging preview #2691: Implements similar dialog-based Preview workflow for another loan schedule change operation using the same code-level pattern (MatDialog injection, LoansService preview method, repayment-schedule dialog display).
Suggested reviewers
- steinwinde
- gkbishnoi07
Pre-merge checks and finishing touches
✅ Passed checks (3 passed)
| Check name | Status | Explanation |
|---|---|---|
| Description Check | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled. |
| Title check | ✅ Passed | The title directly describes the main change: adding a Preview Schedule API feature during loan re-amortization, which matches the implemented functionality across all modified files. |
| Docstring Coverage | ✅ Passed | No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. |
✨ Finishing touches
- 📝 Generate docstrings
🧪 Generate unit tests (beta)
- Create PR with unit tests
- Post copyable unit tests in a comment
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Comment @coderabbitai help to get the list of available commands and usage tips.
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (2)
src/app/loans/loans.service.ts (1)
262-278: Consider improving type safety for the method parameters and return type.The implementation correctly mirrors the existing
getReAgePreviewpattern, but both thedata: anyparameter andObservable<any>return type reduce type safety. Consider defining interfaces for the request payload and response structure.Example refactor:
interface ReAmortizePreviewRequest { reAmortizationInterestHandling: string | number; reasonCodeValueId?: number; note?: string; externalId?: string; dateFormat: string; locale: string; } getReAmortizePreview(loanId: string, data: ReAmortizePreviewRequest): Observable<RepaymentSchedule> { let httpParams = new HttpParams(); Object.keys(data).forEach((key) => { if (data[key] !== null && data[key] !== undefined && data[key] !== '') { httpParams = httpParams.set(key, data[key].toString()); } }); return this.http.get<RepaymentSchedule>(`/loans/${loanId}/transactions/reamortized-preview`, { params: httpParams }); }As per coding guidelines, Angular code should maintain strict type safety.
src/app/loans/loans-view/loan-account-actions/loan-reamortize/loan-reamortize.component.ts (1)
96-125: Improve error handling with user-facing messages.The preview method handles errors with
console.errorstatements (lines 107, 122) but provides no feedback to the user. Consider displaying error messages via a snackbar or dialog to improve user experience.Example improvement:
preview(): void { if (this.reamortizeLoanForm.invalid) { return; } const data = this.prepareReAmortizePreviewData(); this.loanService.getReAmortizePreview(this.loanId, data).subscribe({ next: (response: RepaymentSchedule) => { const currencyCode = response.currency?.code; if (!currencyCode) { // Show user-facing error instead of just console.error this.snackBar.open( 'Unable to load preview: Currency information is missing', 'Close', { duration: 5000 } ); console.error('Currency code is not available in API response'); return; } this.dialog.open(ReAmortizePreviewDialogComponent, { data: { repaymentSchedule: response, currencyCode: currencyCode }, width: '95%', maxWidth: '1400px', height: '90vh' }); }, error: (error) => { this.snackBar.open( 'Failed to load re-amortization preview. Please try again.', 'Close', { duration: 5000 } ); console.error('Error loading re-amortize preview:', error); } }); }
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
src/app/loans/loans-view/loan-account-actions/loan-reamortize/loan-reamortize.component.html(1 hunks)src/app/loans/loans-view/loan-account-actions/loan-reamortize/loan-reamortize.component.ts(3 hunks)src/app/loans/loans-view/loan-account-actions/loan-reamortize/re-amortize-preview-dialog/re-amortize-preview-dialog.component.html(1 hunks)src/app/loans/loans-view/loan-account-actions/loan-reamortize/re-amortize-preview-dialog/re-amortize-preview-dialog.component.ts(1 hunks)src/app/loans/loans.service.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
src/app/**
⚙️ CodeRabbit configuration file
src/app/**: For Angular code: verify component separation, trackBy on *ngFor,
strict type safety, and clean observable patterns.
Files:
src/app/loans/loans-view/loan-account-actions/loan-reamortize/re-amortize-preview-dialog/re-amortize-preview-dialog.component.htmlsrc/app/loans/loans-view/loan-account-actions/loan-reamortize/loan-reamortize.component.htmlsrc/app/loans/loans.service.tssrc/app/loans/loans-view/loan-account-actions/loan-reamortize/re-amortize-preview-dialog/re-amortize-preview-dialog.component.tssrc/app/loans/loans-view/loan-account-actions/loan-reamortize/loan-reamortize.component.ts
🧬 Code graph analysis (1)
src/app/loans/loans-view/loan-account-actions/loan-reamortize/re-amortize-preview-dialog/re-amortize-preview-dialog.component.ts (4)
src/app/loans/models/loan-account.model.ts (1)
RepaymentSchedule(55-73)src/app/loans/loans-view/loan-account-actions/loan-reamortize/loan-reamortize.component.ts (1)
Component(13-141)src/app/standalone-shared.module.ts (1)
STANDALONE_SHARED_IMPORTS(21-51)src/app/loans/loans-view/loan-account-actions/loan-reaging/re-age-preview-dialog/re-age-preview-dialog.component.ts (1)
ReAgePreviewDialogComponent(25-40)
🔇 Additional comments (9)
src/app/loans/loans-view/loan-account-actions/loan-reamortize/loan-reamortize.component.html (1)
62-71: LGTM! Preview button implementation follows best practices.The Preview button correctly uses
type="button"to prevent form submission, matches the Submit button's validation and permission patterns, and is properly wired to thepreview()method.src/app/loans/loans-view/loan-account-actions/loan-reamortize/re-amortize-preview-dialog/re-amortize-preview-dialog.component.html (1)
1-16: LGTM! Dialog template follows Material Design patterns correctly.The template properly uses Angular Material Dialog components, binds the repayment schedule data correctly to the child component, and provides a clear close action.
src/app/loans/loans-view/loan-account-actions/loan-reamortize/loan-reamortize.component.ts (6)
4-11: LGTM! Imports are appropriate for the preview functionality.All imports are correctly added to support the preview workflow, including Material Dialog, RepaymentSchedule type, SettingsService, and the preview dialog component.
34-36: LGTM! Dependencies correctly injected for preview functionality.The SettingsService and MatDialog dependencies are properly added to support locale/date formatting and dialog presentation.
127-132: Verify the submit method uses the correct data preparation.The
submitmethod now callsprepareReAmortizeData, but this might be inconsistent with how the preview data is prepared. See the comment on lines 59-69 regarding data transformation.
134-140: LGTM! trackBy functions improve performance.The trackBy functions correctly use the
idproperty with a fallback to the index, optimizing Angular's change detection for the*ngFordirectives in the template.As per coding guidelines, trackBy functions are required for *ngFor directives in Angular code.
59-69: Verify data transformation consistency between preview and submit requires additional context.The concern about
reAmortizationInterestHandlinghandling inconsistency betweenprepareReAmortizeDataandprepareReAmortizePreviewDatacannot be fully verified without examining:
- The actual implementation of
prepareReAmortizePreviewData(referenced at lines 71-94) to confirm it extracts theidproperty- The form control definition for
reAmortizationInterestHandlingto determine if it holds an object or primitive value- The API endpoint expectations for the reAmortize submit call
The hypothesis assumes
reAmortizationInterestHandlingis an object with anidproperty that needs extraction, but this requires confirmation before applying the suggested transformation.
71-94: Clarify whether API expects 'default' string or parameter omission.The code sends
'default'as a string when no value is selected, but standard REST API practice suggests omitting the parameter entirely and letting the server apply its defaults. Verify with the API contract whether the reAmortize preview endpoint treatsreAmortizationInterestHandling: 'default'differently from omitting the parameter. If omission is acceptable, consider removing this parameter from the payload instead of sending a literal'default'string to align with typical API semantics and reduce coupling to magic string values.src/app/loans/loans-view/loan-account-actions/loan-reamortize/re-amortize-preview-dialog/re-amortize-preview-dialog.component.ts (1)
1-47: LGTM! Dialog component follows established patterns.The implementation correctly mirrors the
ReAgePreviewDialogComponentpattern (from relevant code snippets). The component is properly configured as standalone, includes all necessary imports, exports a type-safe data interface, and implements clean dialog functionality.As per coding guidelines, the component demonstrates good separation of concerns and strict type safety.
Description
Describe the changes made and why they were made instead of how they were made. List any dependencies that are required for this change.
Related issues and discussion
#{Issue Number}
Screenshots, if any
Checklist
Please make sure these boxes are checked before submitting your pull request - thanks!
If you have multiple commits please combine them into one commit by squashing them.
Read and understood the contribution guidelines at
web-app/.github/CONTRIBUTING.md.Summary by CodeRabbit
New Features
✏️ Tip: You can customize this high-level summary in your review settings.