Skip to content

WEB-477: Re-amortization:- Preview Schedule API during re-amortization#2855

Merged
adamsaghy merged 1 commit intoopenMF:dev-angular-19from
mariiaKraievska:WEB-477/re-amortization-preview-schedule
Dec 5, 2025
Merged

WEB-477: Re-amortization:- Preview Schedule API during re-amortization#2855
adamsaghy merged 1 commit intoopenMF:dev-angular-19from
mariiaKraievska:WEB-477/re-amortization-preview-schedule

Conversation

@mariiaKraievska
Copy link
Contributor

@mariiaKraievska mariiaKraievska commented Dec 4, 2025

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

  • Added Preview button to the loan re-amortization form, enabling users to preview the updated repayment schedule in a dialog before submitting the re-amortization.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Dec 4, 2025

Note

.coderabbit.yaml has unrecognized properties

CodeRabbit is using all valid settings from your configuration. Unrecognized properties (listed below) have been ignored and may indicate typos or deprecated fields that can be removed.

⚠️ Parsing warnings (1)
Validation error: Unrecognized key(s) in object: 'pre_merge_checks'
⚙️ Configuration instructions
  • Please see the configuration documentation for more information.
  • You can also validate your configuration using the online YAML validator.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Walkthrough

This pull request adds a Preview feature to the loan re-amortization workflow. It introduces a Preview button on the loan reamortize form, a new dialog component to display the repayment schedule preview, updated component logic to fetch preview data from a new service method, and integration with Angular Material Dialog for preview display.

Changes

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
Loading

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 getReAgePreview pattern, but both the data: any parameter and Observable<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.error statements (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

📥 Commits

Reviewing files that changed from the base of the PR and between a0bf474 and 9fbdf0c.

📒 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.html
  • src/app/loans/loans-view/loan-account-actions/loan-reamortize/loan-reamortize.component.html
  • src/app/loans/loans.service.ts
  • src/app/loans/loans-view/loan-account-actions/loan-reamortize/re-amortize-preview-dialog/re-amortize-preview-dialog.component.ts
  • src/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 the preview() 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 submit method now calls prepareReAmortizeData, 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 id property with a fallback to the index, optimizing Angular's change detection for the *ngFor directives 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 reAmortizationInterestHandling handling inconsistency between prepareReAmortizeData and prepareReAmortizePreviewData cannot be fully verified without examining:

  1. The actual implementation of prepareReAmortizePreviewData (referenced at lines 71-94) to confirm it extracts the id property
  2. The form control definition for reAmortizationInterestHandling to determine if it holds an object or primitive value
  3. The API endpoint expectations for the reAmortize submit call

The hypothesis assumes reAmortizationInterestHandling is an object with an id property 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 treats reAmortizationInterestHandling: '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 ReAgePreviewDialogComponent pattern (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.

@adamsaghy adamsaghy changed the base branch from dev to dev-angular-19 December 5, 2025 14:53
@adamsaghy adamsaghy merged commit 3b3f8df into openMF:dev-angular-19 Dec 5, 2025
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants