Skip to content

WEB-889: WC - Discount#3436

Merged
alberto-art3ch merged 1 commit intoopenMF:devfrom
mariiaKraievska:WEB-889/working-capital-loan-discount
Apr 2, 2026
Merged

WEB-889: WC - Discount#3436
alberto-art3ch merged 1 commit intoopenMF:devfrom
mariiaKraievska:WEB-889/working-capital-loan-discount

Conversation

@mariiaKraievska
Copy link
Copy Markdown
Contributor

@mariiaKraievska mariiaKraievska commented Mar 23, 2026

Description

User should be able to add the discount fee to the loan account even after disbursement.
Discount can be added only as of disbursement date only.
Discount can be added only one time at the time of disbursement.
User cannot add discount after disbursement if the discount was added at the loan creation/approval state.

Related issues and discussion

https://mifosforge.jira.com/browse/WEB-889

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 "Update discount" action for working-capital loans with a validated discount form (numeric amount, optional note up to 500 chars), cancel/submit flow, permission‑gated submit and loading state.
    • Submission shows success or error feedback and returns to the loan view on success.
    • Added translations for the new UI and validation messages across multiple locales.
  • Bug Fixes

    • Resolver now correctly loads working-capital loan details for the "Update discount" action.

@mariiaKraievska mariiaKraievska marked this pull request as draft March 23, 2026 11:05
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 23, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

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

Adds an "Update discount" working-capital loan action: new UpdateDiscount component and template, resolver branch to load working-capital loan details, LoansService API method to update discount, loan-view button wiring, and translations across multiple locales.

Changes

Cohort / File(s) Summary
New Update Discount Component
src/app/loans/loans-view/loan-account-actions/update-discount/update-discount.component.ts, src/app/loans/loans-view/loan-account-actions/update-discount/update-discount.component.html
New standalone mifosx-update-discount component with reactive form (discountAmount, note), validations (required, min 0, numeric, maxlength 500), submit flow calling LoansService.updateWorkingCapitalLoanDiscount(), success/error handling and navigation.
Resolver & Action Integration
src/app/loans/common-resolvers/loan-action-button.resolver.ts, src/app/loans/loans-view/loan-account-actions/loan-account-actions.component.ts, src/app/loans/loans-view/loan-account-actions/loan-account-actions.component.html
Resolver gains branch for "Update discount" to return working-capital loan details; component imports UpdateDiscountComponent; adds 'Update discount' action flag and conditional template rendering.
Loan view button logic
src/app/loans/loans-view/loans-view.component.ts
Adds conditional "Update discount" action in setConditionalButtons() and new helper canShowWorkingCapitalDiscountUpdate() that requires working-capital product and active loan status.
Service API
src/app/loans/loans.service.ts
Adds exported WorkingCapitalLoanDiscountUpdateRequest interface and updateWorkingCapitalLoanDiscount(loanId, data) method performing PUT to /working-capital-loans/{loanId}/discount.
Translations (multiple locales)
src/assets/translations/...
cs-CS.json, de-DE.json, en-US.json, es-CL.json, es-MX.json, fr-FR.json, it-IT.json, ko-KO.json, lt-LT.json, lv-LV.json, ne-NE.json, pt-PT.json, sw-SW.json
Adds validation labels (Discount must be greater than or equal to 0, Note is too long, Please enter a valid number), action label Update discount, and messages workingCapitalDiscountUpdated / unableToUpdateDiscount; adjusts messages.validationSaved punctuation in several locales.

Sequence Diagram

sequenceDiagram
    participant User as User
    participant UI as Loan Account Actions UI
    participant Resolver as LoanActionButtonResolver
    participant UpdateComp as UpdateDiscountComponent
    participant LoansService as LoansService
    participant API as Backend API

    User->>UI: Click "Update discount"
    UI->>Resolver: resolve(action="Update discount", loanId)
    Resolver->>LoansService: getWorkingCapitalLoanDetails(loanId)
    LoansService->>API: GET /working-capital-loans/{loanId}
    API-->>LoansService: 200 Loan details
    LoansService-->>Resolver: loan details
    Resolver-->>UI: actionButtonData
    UI->>UpdateComp: render with actionButtonData
    UpdateComp->>UpdateComp: init form with discount
    User->>UpdateComp: submit form (discountAmount, note)
    UpdateComp->>LoansService: updateWorkingCapitalLoanDiscount(loanId, payload)
    LoansService->>API: PUT /working-capital-loans/{loanId}/discount
    alt Success
        API-->>LoansService: 200 OK
        LoansService-->>UpdateComp: success
        UpdateComp->>User: show success & navigate back
    else Error
        API-->>LoansService: HTTP error
        LoansService-->>UpdateComp: error details
        UpdateComp->>User: display mapped error message
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • alberto-art3ch
  • adamsaghy
  • IOhacker
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'WEB-889: WC - Discount' is vague and generic, using abbreviations and minimal context that don't convey the specific change being made. Consider a more descriptive title like 'Add ability to update working capital loan discount after disbursement' that clearly explains what functionality is being added.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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
Copy Markdown

@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: 6

🧹 Nitpick comments (5)
src/assets/translations/it-IT.json (1)

2978-2978: Use a more natural Italian phrasing on Line 2978.

"Aggiorna sconto" is understandable, but "Aggiorna lo sconto" is more idiomatic for a menu action label.

✏️ Suggested wording tweak
-      "Update discount": "Aggiorna sconto",
+      "Update discount": "Aggiorna lo sconto",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/assets/translations/it-IT.json` at line 2978, Replace the current Italian
value for the translation key "Update discount" with a more natural phrase;
locate the JSON entry with the key "Update discount" and change its value from
"Aggiorna sconto" to "Aggiorna lo sconto" so the menu/action label reads
idiomatically in Italian.
src/assets/translations/es-CL.json (1)

2262-2262: Consider wording consistency with existing es-CL prompts.

Line 2262 uses “introduzca”, while much of this locale file uses “ingrese”. Consider aligning phrasing for a more consistent UX tone.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/assets/translations/es-CL.json` at line 2262, The translation for the key
"Please enter a valid number" in the es-CL locale uses "introduzca" which is
inconsistent with the rest of the file that prefers "ingrese"; update the value
to "Por favor, ingrese un número válido" to match existing phrasing and maintain
a consistent UX tone (locate the string by the exact key "Please enter a valid
number" in the es-CL translations).
src/app/loans/loans-view/loan-account-actions/update-discount/update-discount.component.html (1)

47-47: Use 8px-grid spacing token/class instead of gap-5px.

gap-5px breaks the project spacing convention. Please switch this action-row gap to an 8px-grid-compliant spacing utility/style token.

As per coding guidelines src/**/*.{scss,html}: Stick to the 8px grid system for visual design and spacing.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/app/loans/loans-view/loan-account-actions/update-discount/update-discount.component.html`
at line 47, The mat-card-actions element currently uses a non-compliant class
"gap-5px" (see the element with classes layout-row align-center gap-5px
responsive-column); replace "gap-5px" with the project's 8px-grid spacing
utility/token (for example the approved class such as gap-8 or spacing-8px
depending on your stylesheet) so the action row follows the 8px grid spacing
convention used across src/**/*.scss and .html.
src/app/loans/loans-view/loan-account-actions/update-discount/update-discount.component.ts (1)

12-13: Migrate to typed reactive forms for compile-time type safety.

The component currently uses UntypedFormBuilder and UntypedFormGroup, which lose type safety for the discountAmount and note form fields. Migrating to typed forms will enable the TypeScript compiler to catch shape/type drift errors.

♻️ Suggested refactor
-import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
+import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
...
-  private formBuilder = inject(UntypedFormBuilder);
+  private formBuilder = inject(FormBuilder);
...
-  updateDiscountForm: UntypedFormGroup;
+  updateDiscountForm!: FormGroup<{
+    discountAmount: FormControl<number | null>;
+    note: FormControl<string>;
+  }>;

Aligns with coding guideline: src/app/**/*.ts — "Use TypeScript for all application code with strict typing conventions."

Also applies to lines 33–39, 46–59, 70–73.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/app/loans/loans-view/loan-account-actions/update-discount/update-discount.component.ts`
around lines 12 - 13, The component currently uses untyped reactive forms;
define a typed interface (e.g., UpdateDiscountForm { discountAmount: number;
note: string }) and replace UntypedFormBuilder/UntypedFormGroup with Angular's
typed FormBuilder and FormGroup<UpdateDiscountForm> in the
UpdateDiscountComponent, changing the injected UntypedFormBuilder to FormBuilder
and the discountForm property to FormGroup<UpdateDiscountForm>; update the form
creation (where discountAmount and note are initialized—likely in ngOnInit or
createForm) to use the typed form controls and keep the existing Validators, and
adjust any code that reads/writes discountForm.value or controls to use the
typed names so the compiler enforces the form shape.
src/app/loans/loans-view/loan-account-actions/loan-account-actions.component.ts (1)

139-139: Prefer a shared action-name constant to avoid string drift.

'Update discount' is now repeated in multiple places. A shared typed constant keeps routing/action matching safer and easier to maintain.

♻️ Suggested refactor
+// e.g. src/app/loans/loan-action.constants.ts
+export const LOAN_ACTION_UPDATE_DISCOUNT = 'Update discount' as const;
-    'Update discount': boolean;
+    [LOAN_ACTION_UPDATE_DISCOUNT]: boolean;
-    'Update discount': false
+    [LOAN_ACTION_UPDATE_DISCOUNT]: false
-@if (actions['Update discount']) {
+@if (actions[LOAN_ACTION_UPDATE_DISCOUNT]) {
-} else if (loanActionButton === 'Update discount') {
+} else if (loanActionButton === LOAN_ACTION_UPDATE_DISCOUNT) {

Also applies to: 180-181

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/app/loans/loans-view/loan-account-actions/loan-account-actions.component.ts`
at line 139, Replace the repeated literal "Update discount" with a single
exported constant and use that constant everywhere it appears; e.g., define
export const ACTION_UPDATE_DISCOUNT = 'Update discount' in a shared constants
file or at top of LoanAccountActionsComponent, change the mapped key from the
literal ('Update discount': boolean) to a computed property
([ACTION_UPDATE_DISCOUNT]: boolean) and replace the other occurrences (the
comparisons/uses around the 180–181 area) to reference ACTION_UPDATE_DISCOUNT so
routing/action matching uses the single source of truth.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@src/app/loans/loans-view/loan-account-actions/update-discount/update-discount.component.ts`:
- Around line 24-31: The `@Component` metadata for the UpdateDiscount component is
missing standalone: true which is required when using the imports array; update
the `@Component` decorator (in update-discount.component.ts for the
UpdateDiscountComponent) to include standalone: true alongside selector,
templateUrl and imports so Angular recognizes this as a standalone component and
compilation succeeds.

In `@src/app/loans/loans-view/loans-view.component.ts`:
- Around line 260-266: canShowWorkingCapitalDiscountUpdate() currently only
checks product type and active status; extend it to also (1) validate the loan
disbursement date meets the required window, (2) enforce one-time-only discount
(check existing discount records/flags so discounts cannot be updated more than
once), and (3) block the action when a discount was already added during
creation or approval workflows; update the buttonConfig.addButton call to rely
on this enhanced guard. Additionally, in the UpdateDiscountComponent.submit()
method, add the same three validations (disbursement date, one-time-only, and
creation/approval-added check) and abort submission with an appropriate
error/notification if any fail so the backend/UX cannot apply the update when
the action should be unavailable.

In `@src/app/loans/loans.service.ts`:
- Around line 563-569: Define a typed request payload interface (e.g.,
WorkingCapitalLoanDiscountPayload) and use it for the two methods instead of
data: any; specifically create an interface with the expected properties (for
example: discountAmount: number, currency?: string, reason?: string,
effectiveDate?: string, approverId?: string — adjust names/types to match the
API contract) and update updateWorkingCapitalLoanDiscount(loanId: string |
number, data: WorkingCapitalLoanDiscountPayload) and
updateWorkingCapitalLoanDiscountByExternalId(loanExternalId: string, data:
WorkingCapitalLoanDiscountPayload) while keeping the return type Observable<any>
unchanged.
- Around line 567-568: The new method
updateWorkingCapitalLoanDiscountByExternalId is currently unused; either remove
it or, if you intend to enable it, make the URL construction defensive by
URL-encoding loanExternalId (use encodeURIComponent) before interpolating into
the path in updateWorkingCapitalLoanDiscountByExternalId and apply the same
approach consistently as used in remittances.service.ts; ensure the http.put
call uses the encoded id so special characters won’t break the request.

In `@src/assets/translations/fr-FR.json`:
- Line 1805: Several French translation entries use "remise" while the base
label and nearby keys use "rabais"; update the translation value for the key
"Discount must be greater than or equal to 0" (and the other affected keys noted
in the comment) to use "rabais" instead of "remise" so the UI uses a single
consistent term; locate the JSON entries by their exact message keys (e.g.,
"Discount must be greater than or equal to 0") and replace "remise" with
"rabais" in each affected value, then run your i18n/string-consistency check to
confirm no other keys still use the old term.

In `@src/assets/translations/pt-PT.json`:
- Line 2260: The pt-PT translations use Brazilian variants; update the two
translation values for the English keys "Please enter a valid number" and the
string at the other mention (line with "capital de giro") to pt-PT-consistent
wording: replace "Por favor, insira um número válido" with "Por favor, introduza
um número válido" and replace the "capital de giro" phrasing with "O desconto do
empréstimo de fundo de maneio foi atualizado com sucesso." so both translations
consistently use European Portuguese; locate these by their English source
strings in src/assets/translations/pt-PT.json and update the values accordingly.

---

Nitpick comments:
In
`@src/app/loans/loans-view/loan-account-actions/loan-account-actions.component.ts`:
- Line 139: Replace the repeated literal "Update discount" with a single
exported constant and use that constant everywhere it appears; e.g., define
export const ACTION_UPDATE_DISCOUNT = 'Update discount' in a shared constants
file or at top of LoanAccountActionsComponent, change the mapped key from the
literal ('Update discount': boolean) to a computed property
([ACTION_UPDATE_DISCOUNT]: boolean) and replace the other occurrences (the
comparisons/uses around the 180–181 area) to reference ACTION_UPDATE_DISCOUNT so
routing/action matching uses the single source of truth.

In
`@src/app/loans/loans-view/loan-account-actions/update-discount/update-discount.component.html`:
- Line 47: The mat-card-actions element currently uses a non-compliant class
"gap-5px" (see the element with classes layout-row align-center gap-5px
responsive-column); replace "gap-5px" with the project's 8px-grid spacing
utility/token (for example the approved class such as gap-8 or spacing-8px
depending on your stylesheet) so the action row follows the 8px grid spacing
convention used across src/**/*.scss and .html.

In
`@src/app/loans/loans-view/loan-account-actions/update-discount/update-discount.component.ts`:
- Around line 12-13: The component currently uses untyped reactive forms; define
a typed interface (e.g., UpdateDiscountForm { discountAmount: number; note:
string }) and replace UntypedFormBuilder/UntypedFormGroup with Angular's typed
FormBuilder and FormGroup<UpdateDiscountForm> in the UpdateDiscountComponent,
changing the injected UntypedFormBuilder to FormBuilder and the discountForm
property to FormGroup<UpdateDiscountForm>; update the form creation (where
discountAmount and note are initialized—likely in ngOnInit or createForm) to use
the typed form controls and keep the existing Validators, and adjust any code
that reads/writes discountForm.value or controls to use the typed names so the
compiler enforces the form shape.

In `@src/assets/translations/es-CL.json`:
- Line 2262: The translation for the key "Please enter a valid number" in the
es-CL locale uses "introduzca" which is inconsistent with the rest of the file
that prefers "ingrese"; update the value to "Por favor, ingrese un número
válido" to match existing phrasing and maintain a consistent UX tone (locate the
string by the exact key "Please enter a valid number" in the es-CL
translations).

In `@src/assets/translations/it-IT.json`:
- Line 2978: Replace the current Italian value for the translation key "Update
discount" with a more natural phrase; locate the JSON entry with the key "Update
discount" and change its value from "Aggiorna sconto" to "Aggiorna lo sconto" so
the menu/action label reads idiomatically in Italian.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 1e76f89a-3ca3-4353-8293-7138afd4b117

📥 Commits

Reviewing files that changed from the base of the PR and between 7886c79 and b9f1565.

📒 Files selected for processing (20)
  • src/app/loans/common-resolvers/loan-action-button.resolver.ts
  • src/app/loans/loans-view/loan-account-actions/loan-account-actions.component.html
  • src/app/loans/loans-view/loan-account-actions/loan-account-actions.component.ts
  • src/app/loans/loans-view/loan-account-actions/update-discount/update-discount.component.html
  • src/app/loans/loans-view/loan-account-actions/update-discount/update-discount.component.ts
  • src/app/loans/loans-view/loans-view.component.ts
  • src/app/loans/loans.service.ts
  • src/assets/translations/cs-CS.json
  • src/assets/translations/de-DE.json
  • src/assets/translations/en-US.json
  • src/assets/translations/es-CL.json
  • src/assets/translations/es-MX.json
  • src/assets/translations/fr-FR.json
  • src/assets/translations/it-IT.json
  • src/assets/translations/ko-KO.json
  • src/assets/translations/lt-LT.json
  • src/assets/translations/lv-LV.json
  • src/assets/translations/ne-NE.json
  • src/assets/translations/pt-PT.json
  • src/assets/translations/sw-SW.json

Comment on lines +260 to +266
if (this.canShowWorkingCapitalDiscountUpdate()) {
this.buttonConfig.addButton({
name: 'Update discount',
icon: 'edit',
taskPermissionName: 'DISBURSE_LOAN'
});
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Locate discount action wiring =="
rg -n --type ts -C3 "Update discount|canShowWorkingCapitalDiscountUpdate|workingCapital.*discount|discount.*update" src/app/loans

echo
echo "== Inspect resolver for action payload =="
fd 'loan-action-button.resolver.ts$' src/app --exec sed -n '1,260p' {}

echo
echo "== Inspect update-discount component for date/one-time/pre-existing checks =="
fd 'update-discount.component.ts$' src/app --exec sed -n '1,320p' {}

echo
echo "== Inspect loans service methods used by resolver/component =="
fd 'loans.service.ts$' src/app --exec rg -n -C4 "getWorkingCapital|updateWorkingCapital|discount|disbursement|businessDate|already" {}

Repository: openMF/web-app

Length of output: 19810


🏁 Script executed:

# Get full implementation of canShowWorkingCapitalDiscountUpdate
sed -n '582,600p' src/app/loans/loans-view/loans-view.component.ts

echo "---"

# Check for any eligibility-related fields or conditions
rg -n "discount.*eligible|eligible.*discount|one.*time|disbursement.*date|discount.*created|discount.*approval" src/app/loans/loans-view --type ts

echo "---"

# Look at the loanDetailsData structure and what it contains
rg -n -A5 "loanDetailsData" src/app/loans/loans-view/loans-view.component.ts | head -60

echo "---"

# Check the update-discount template for any additional checks
fd 'update-discount.component.html$' src/app --exec cat {}

Repository: openMF/web-app

Length of output: 6507


Update discount action visibility is missing full eligibility checks.

The guard at line 582 checks only working-capital product type and active status, but the PR rules require additional constraints: disbursement date validation, one-time-only enforcement, and blocking when already added during creation/approval. The update-discount component's submit() method (lines 42–65) does not validate these constraints either, exposing the action when it should be unavailable. Ensure all three eligibility criteria are enforced before showing the action and before allowing submission.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/loans/loans-view/loans-view.component.ts` around lines 260 - 266,
canShowWorkingCapitalDiscountUpdate() currently only checks product type and
active status; extend it to also (1) validate the loan disbursement date meets
the required window, (2) enforce one-time-only discount (check existing discount
records/flags so discounts cannot be updated more than once), and (3) block the
action when a discount was already added during creation or approval workflows;
update the buttonConfig.addButton call to rely on this enhanced guard.
Additionally, in the UpdateDiscountComponent.submit() method, add the same three
validations (disbursement date, one-time-only, and creation/approval-added
check) and abort submission with an appropriate error/notification if any fail
so the backend/UX cannot apply the update when the action should be unavailable.

Comment on lines +567 to +568
updateWorkingCapitalLoanDiscountByExternalId(loanExternalId: string, data: any): Observable<any> {
return this.http.put(`/working-capital-loans/external-id/${loanExternalId}/discount`, data);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Verify call sites and whether external IDs are constrained/sanitized before use.
rg -nP --type=ts -C3 '\bupdateWorkingCapitalLoanDiscountByExternalId\s*\('
rg -nP --type=ts -C2 '\b(externalId|loanExternalId|encodeURIComponent|encodeURI)\b'

Repository: openMF/web-app

Length of output: 50370


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Find callers of updateWorkingCapitalLoanDiscountByExternalId
rg -nP --type=ts 'updateWorkingCapitalLoanDiscountByExternalId' --max-count=20

# Check other external ID path parameter patterns in loans.service.ts
echo "=== Checking loans.service.ts for external ID patterns ==="
sed -n '1,100p' src/app/loans/loans.service.ts | grep -n "external-id\|externalId" || echo "No matches in first 100 lines"

# Check remittances.service.ts which has a similar pattern
echo "=== Checking remittances.service.ts pattern ==="
sed -n '70,75p' src/app/remittances/remittances.service.ts

# Look for other methods with external IDs in URLs across services
echo "=== Searching for other external ID URL patterns ==="
rg -nP "external-id/\$\{" --type=ts -A2 -B2

Repository: openMF/web-app

Length of output: 661


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Search for working-capital-loans references (method might be unused or indirectly referenced)
echo "=== Searching for working-capital-loans references ==="
rg -nP "working-capital-loans" --type=ts

# Check if external IDs have format validation anywhere
echo "=== Checking for external ID validation patterns ==="
rg -nP "externalId.*validat|validat.*externalId" --type=ts -i | head -20

# Search for how external IDs are used in form validators
echo "=== Form validators for externalId ==="
rg -nP "externalId.*Validat" --type=ts -A2 | head -30

Repository: openMF/web-app

Length of output: 1042


🏁 Script executed:

#!/bin/bash
set -euoripefail

# Get context around the method
echo "=== Context around updateWorkingCapitalLoanDiscountByExternalId ==="
sed -n '560,575p' src/app/loans/loans.service.ts

# Check file structure to see if method is new or part of broader pattern
echo "=== Methods with 'Discount' in loans.service.ts ==="
grep -n "Discount" src/app/loans/loans.service.ts

# Check if there's any test file that might reference this method
echo "=== Looking for test files ==="
find . -name "*loans*.service.spec.ts" -type f

# Search more carefully for any string-based method calls (dynamic invocation)
echo "=== Checking for dynamic method invocations ==="
rg -nP "\[.*updateWorkingCapitalLoanDiscountByExternalId|\"updateWorkingCapitalLoanDiscountByExternalId" --type=ts

Repository: openMF/web-app

Length of output: 732


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Get context around the method
echo "=== Context around updateWorkingCapitalLoanDiscountByExternalId ==="
sed -n '560,575p' src/app/loans/loans.service.ts

# Check file structure to see if method is new or part of broader pattern
echo "=== Methods with 'Discount' in loans.service.ts ==="
grep -n "Discount" src/app/loans/loans.service.ts

# Check if there's any test file that might reference this method
echo "=== Looking for test files ==="
find . -name "*loans*.service.spec.ts" -type f 2>/dev/null || echo "No spec files found"

# Search for any indirect references
echo "=== Checking for any string-based method references ==="
rg -nP "updateWorkingCapitalLoanDiscount" --type=ts | head -20

Repository: openMF/web-app

Length of output: 1629


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Check the update-discount component to understand usage context
echo "=== update-discount.component.ts context ==="
sed -n '70,85p' src/app/loans/loans-view/loan-account-actions/update-discount/update-discount.component.ts

# Check if there are other variants being prepared
grep -n "externalId\|updateWorkingCapitalLoanDiscount" src/app/loans/loans-view/loan-account-actions/update-discount/update-discount.component.ts

# Check remittances service to see if the unencoded externalId pattern works
echo "=== Remittances service full context ==="
sed -n '65,85p' src/app/remittances/remittances.service.ts

# Look for any Fineract API documentation or type definitions that mention externalId format
echo "=== Checking model files for externalId type hints ==="
grep -n "externalId.*:" src/app/loans/models/loan-account.model.ts | head -5

Repository: openMF/web-app

Length of output: 1578


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Search for Fineract API documentation or comments about externalId format
echo "=== Searching for externalId format documentation ==="
rg -nP "externalId.*format|externalId.*constraint|externalId.*[A-Za-z0-9\-]{" --type=ts -B2 -A2 | head -30

# Check if there are URL encoding utilities already in use elsewhere
echo "=== Looking for encodeURIComponent usage patterns ==="
rg -nP "encodeURIComponent" --type=ts -B3 -A1 | head -40

# Check the Fineract API path pattern - check a few working methods to see if they encode
echo "=== Checking other path parameters that might contain user input ==="
grep -n "http\.\(get\|put\|post\)\(\`.*\${" src/app/loans/loans.service.ts | head -10

Repository: openMF/web-app

Length of output: 111


Method appears unused—if activated, consider encoding the external ID for URL safety.

Line 568 interpolates loanExternalId directly into the path. While a similar unencoded pattern exists in remittances.service.ts (line 73) and works in production, encoding the parameter is defensively sound if the Fineract API could receive special characters. However, this method has no call sites in the codebase; if it's new or will be activated, apply the suggested fix consistently with the encoding approach chosen elsewhere.

Suggested fix
  updateWorkingCapitalLoanDiscountByExternalId(loanExternalId: string, data: any): Observable<any> {
-   return this.http.put(`/working-capital-loans/external-id/${loanExternalId}/discount`, data);
+   const encodedExternalId = encodeURIComponent(loanExternalId);
+   return this.http.put(`/working-capital-loans/external-id/${encodedExternalId}/discount`, data);
  }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/loans/loans.service.ts` around lines 567 - 568, The new method
updateWorkingCapitalLoanDiscountByExternalId is currently unused; either remove
it or, if you intend to enable it, make the URL construction defensive by
URL-encoding loanExternalId (use encodeURIComponent) before interpolating into
the path in updateWorkingCapitalLoanDiscountByExternalId and apply the same
approach consistently as used in remittances.service.ts; ensure the http.put
call uses the encoded id so special characters won’t break the request.

@mariiaKraievska mariiaKraievska force-pushed the WEB-889/working-capital-loan-discount branch 2 times, most recently from 4cca692 to c54fbf6 Compare March 30, 2026 07:55
@mariiaKraievska mariiaKraievska force-pushed the WEB-889/working-capital-loan-discount branch from c54fbf6 to b1dae9c Compare March 31, 2026 06:50
@mariiaKraievska mariiaKraievska marked this pull request as ready for review April 1, 2026 07:58
@adamsaghy adamsaghy requested a review from alberto-art3ch April 1, 2026 08:11
@mariiaKraievska mariiaKraievska force-pushed the WEB-889/working-capital-loan-discount branch from b1dae9c to ed72c07 Compare April 1, 2026 17:40
Copy link
Copy Markdown

@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.

♻️ Duplicate comments (2)
src/app/loans/loans-view/loan-account-actions/update-discount/update-discount.component.ts (1)

64-80: ⚠️ Potential issue | 🟠 Major

Block submit when discount eligibility constraints are not met.

Line 65 validates form and state, but it does not enforce the PR constraints (disbursement-date only, one-time only, and no prior creation/approval discount). This allows disallowed requests to still be submitted from the action component.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/app/loans/loans-view/loan-account-actions/update-discount/update-discount.component.ts`
around lines 64 - 80, The submit() method currently only checks form validity,
isWorkingCapital, and isSubmitting; add explicit pre-submit guard checks for the
PR constraints: verify the loan is disbursement-date only, is one-time only, and
has no existing or approved discount before calling
loanService.updateWorkingCapitalLoanDiscount; if any check fails set
submitErrorMessage to a clear user-facing message, leave isSubmitting false, and
return early. Locate these checks in update-discount.component.ts inside
submit() (referencing updateDiscountForm, isWorkingCapital, isSubmitting,
loanId, and loanService.updateWorkingCapitalLoanDiscount) and source the
constraint data from the component’s loan model or service methods (e.g., loan
object flags or a validation helper) to enforce the three conditions prior to
performing the API call.
src/app/loans/loans-view/loans-view.component.ts (1)

260-266: ⚠️ Potential issue | 🟠 Major

Enforce full eligibility rules before showing “Update discount”.

Line 582 currently checks only working-capital type and active status, so Line 260 can still expose this action when PR rules should block it (disbursement-date only, one-time only, and not allowed if already added during creation/approval).

Also applies to: 582-587

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/loans/loans-view/loans-view.component.ts` around lines 260 - 266, The
current conditional around buttonConfig.addButton relies on
canShowWorkingCapitalDiscountUpdate() which only checks type/active status;
update the conditional (or extend canShowWorkingCapitalDiscountUpdate()) so it
enforces the full eligibility rules used elsewhere: require
disbursement-date-only, one-time-only discount, and disallow if the discount was
already added during creation/approval (reuse the same eligibility logic used
for showing the action elsewhere instead of the simple type/active check).
Ensure buttonConfig.addButton is only called when that comprehensive eligibility
function returns true.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In
`@src/app/loans/loans-view/loan-account-actions/update-discount/update-discount.component.ts`:
- Around line 64-80: The submit() method currently only checks form validity,
isWorkingCapital, and isSubmitting; add explicit pre-submit guard checks for the
PR constraints: verify the loan is disbursement-date only, is one-time only, and
has no existing or approved discount before calling
loanService.updateWorkingCapitalLoanDiscount; if any check fails set
submitErrorMessage to a clear user-facing message, leave isSubmitting false, and
return early. Locate these checks in update-discount.component.ts inside
submit() (referencing updateDiscountForm, isWorkingCapital, isSubmitting,
loanId, and loanService.updateWorkingCapitalLoanDiscount) and source the
constraint data from the component’s loan model or service methods (e.g., loan
object flags or a validation helper) to enforce the three conditions prior to
performing the API call.

In `@src/app/loans/loans-view/loans-view.component.ts`:
- Around line 260-266: The current conditional around buttonConfig.addButton
relies on canShowWorkingCapitalDiscountUpdate() which only checks type/active
status; update the conditional (or extend canShowWorkingCapitalDiscountUpdate())
so it enforces the full eligibility rules used elsewhere: require
disbursement-date-only, one-time-only discount, and disallow if the discount was
already added during creation/approval (reuse the same eligibility logic used
for showing the action elsewhere instead of the simple type/active check).
Ensure buttonConfig.addButton is only called when that comprehensive eligibility
function returns true.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 90498839-c217-4c73-98a8-c7aa60d3890e

📥 Commits

Reviewing files that changed from the base of the PR and between b1dae9c and ed72c07.

📒 Files selected for processing (20)
  • src/app/loans/common-resolvers/loan-action-button.resolver.ts
  • src/app/loans/loans-view/loan-account-actions/loan-account-actions.component.html
  • src/app/loans/loans-view/loan-account-actions/loan-account-actions.component.ts
  • src/app/loans/loans-view/loan-account-actions/update-discount/update-discount.component.html
  • src/app/loans/loans-view/loan-account-actions/update-discount/update-discount.component.ts
  • src/app/loans/loans-view/loans-view.component.ts
  • src/app/loans/loans.service.ts
  • src/assets/translations/cs-CS.json
  • src/assets/translations/de-DE.json
  • src/assets/translations/en-US.json
  • src/assets/translations/es-CL.json
  • src/assets/translations/es-MX.json
  • src/assets/translations/fr-FR.json
  • src/assets/translations/it-IT.json
  • src/assets/translations/ko-KO.json
  • src/assets/translations/lt-LT.json
  • src/assets/translations/lv-LV.json
  • src/assets/translations/ne-NE.json
  • src/assets/translations/pt-PT.json
  • src/assets/translations/sw-SW.json
✅ Files skipped from review due to trivial changes (4)
  • src/app/loans/loans-view/loan-account-actions/loan-account-actions.component.html
  • src/assets/translations/ne-NE.json
  • src/assets/translations/de-DE.json
  • src/assets/translations/it-IT.json
🚧 Files skipped from review as they are similar to previous changes (9)
  • src/app/loans/loans-view/loan-account-actions/loan-account-actions.component.ts
  • src/assets/translations/fr-FR.json
  • src/assets/translations/cs-CS.json
  • src/assets/translations/es-MX.json
  • src/assets/translations/sw-SW.json
  • src/assets/translations/en-US.json
  • src/assets/translations/lt-LT.json
  • src/assets/translations/pt-PT.json
  • src/app/loans/loans-view/loan-account-actions/update-discount/update-discount.component.html

Copy link
Copy Markdown
Collaborator

@alberto-art3ch alberto-art3ch left a comment

Choose a reason for hiding this comment

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

Few small comments, please review

[
Validators.required,
Validators.min(0),
Validators.pattern(/^\d+(\.\d+)?$/)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please use the next custom validator for positive amount amountValueValidator() It must be imported

That replace the pattern Validator

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done

<div class="layout-column">
<mat-form-field>
<mat-label>{{ 'labels.inputs.Discount' | translate }}</mat-label>
<input matInput type="number" min="0" step="0.01" formControlName="discountAmount" />
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

use the directive mifosxPositiveNumber

Like:

        <input
              type="number"
              matInput
              required
              mifosxPositiveNumber
              formControlName="breachFrequency"
              min="1"
              step="1"
        />

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done

mat-raised-button
color="primary"
[disabled]="!updateDiscountForm.valid || isSubmitting"
*mifosxHasPermission="'DISBURSE_LOAN'"
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Just double checking the right permission

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done

}

submit(): void {
if (!this.updateDiscountForm.valid || !this.isWorkingCapital || this.isSubmitting) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think this is not needed It

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done

@mariiaKraievska mariiaKraievska force-pushed the WEB-889/working-capital-loan-discount branch from ed72c07 to 95cff71 Compare April 2, 2026 08:28
@mariiaKraievska
Copy link
Copy Markdown
Contributor Author

@alberto-art3ch Please take another look

Copy link
Copy Markdown

@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: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/app/loans/common-resolvers/loan-action-button.resolver.ts`:
- Around line 102-103: The "Update discount" branch in the resolver calls a
misspelled service method getWorkingCapitalLoannDetails which doesn't exist;
change the call in the loanActionButton === 'Update discount' branch to use the
correct service method name getWorkingCapitalLoanDetails on this.loansService
(ensure the argument loanId remains unchanged) so the resolver invokes the real
method.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a8ba5537-de0b-4282-96cc-c6433562b3e1

📥 Commits

Reviewing files that changed from the base of the PR and between ed72c07 and 95cff71.

📒 Files selected for processing (20)
  • src/app/loans/common-resolvers/loan-action-button.resolver.ts
  • src/app/loans/loans-view/loan-account-actions/loan-account-actions.component.html
  • src/app/loans/loans-view/loan-account-actions/loan-account-actions.component.ts
  • src/app/loans/loans-view/loan-account-actions/update-discount/update-discount.component.html
  • src/app/loans/loans-view/loan-account-actions/update-discount/update-discount.component.ts
  • src/app/loans/loans-view/loans-view.component.ts
  • src/app/loans/loans.service.ts
  • src/assets/translations/cs-CS.json
  • src/assets/translations/de-DE.json
  • src/assets/translations/en-US.json
  • src/assets/translations/es-CL.json
  • src/assets/translations/es-MX.json
  • src/assets/translations/fr-FR.json
  • src/assets/translations/it-IT.json
  • src/assets/translations/ko-KO.json
  • src/assets/translations/lt-LT.json
  • src/assets/translations/lv-LV.json
  • src/assets/translations/ne-NE.json
  • src/assets/translations/pt-PT.json
  • src/assets/translations/sw-SW.json
✅ Files skipped from review due to trivial changes (7)
  • src/app/loans/loans-view/loan-account-actions/loan-account-actions.component.html
  • src/app/loans/loans-view/loan-account-actions/loan-account-actions.component.ts
  • src/app/loans/loans-view/loans-view.component.ts
  • src/assets/translations/es-MX.json
  • src/assets/translations/it-IT.json
  • src/app/loans/loans-view/loan-account-actions/update-discount/update-discount.component.html
  • src/assets/translations/ko-KO.json
🚧 Files skipped from review as they are similar to previous changes (9)
  • src/assets/translations/pt-PT.json
  • src/app/loans/loans.service.ts
  • src/assets/translations/fr-FR.json
  • src/assets/translations/en-US.json
  • src/assets/translations/de-DE.json
  • src/assets/translations/cs-CS.json
  • src/assets/translations/sw-SW.json
  • src/assets/translations/lt-LT.json
  • src/assets/translations/lv-LV.json

@mariiaKraievska mariiaKraievska force-pushed the WEB-889/working-capital-loan-discount branch from 95cff71 to 52d2595 Compare April 2, 2026 08:50
Copy link
Copy Markdown

@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.

♻️ Duplicate comments (1)
src/app/loans/loans-view/loans-view.component.ts (1)

582-587: ⚠️ Potential issue | 🟠 Major

Enforce full discount eligibility in the guard, not just product type + active status.

Line 583-Line 586 currently allows the action when the loan is working-capital and active, but the feature rules also require: disbursement-date-only, one-time-only, and “not already added during creation/approval”. This incomplete guard can surface an invalid action path (used at Line 260).

[suggested fix] Centralize eligibility into one backend-driven flag (preferred) or explicit checks for all three constraints before returning true.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/app/loans/loans-view/loans-view.component.ts` around lines 582 - 587, The
current guard canShowWorkingCapitalDiscountUpdate only checks
loanProductService.isWorkingCapital and loanDetailsData.status.active; update it
to enforce full working-capital discount eligibility by either: 1) preferring a
single backend-driven boolean (e.g.,
loanDetailsData.fullWorkingCapitalDiscountEligible) and returning that &&
loanDetailsData.status.active, or 2) if backend flag is unavailable, add
explicit checks inside canShowWorkingCapitalDiscountUpdate for
disbursement-date-only (e.g., loanDetailsData.discount?.disbursementDateOnly),
one-time-only (e.g., loanDetailsData.discount?.oneTimeOnly), and that the
discount was not already added during creation/approval (e.g.,
!loanDetailsData.discount?.addedDuringCreationOrApproval) in addition to
loanProductService.isWorkingCapital and loanDetailsData.status.active; ensure
the same consolidated guard is used wherever the feature is invoked (notably the
caller that currently relies on this guard).
🧹 Nitpick comments (1)
src/app/loans/loans-view/loan-account-actions/update-discount/update-discount.component.ts (1)

12-13: Use typed reactive forms instead of Untyped* APIs to improve type safety.

This component uses UntypedFormBuilder and UntypedFormGroup, which bypasses compile-time checks for the form's shape. Since the form structure is static with clearly defined fields, typed forms would provide better IDE support and type safety.

♻️ Suggested typed-form refactor
-import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
+import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
@@
-  private formBuilder = inject(UntypedFormBuilder);
+  private formBuilder = inject(FormBuilder);
@@
-  updateDiscountForm: UntypedFormGroup;
+  updateDiscountForm: FormGroup<{
+    discountAmount: FormControl<number | null>;
+    note: FormControl<string>;
+  }>;
@@
-    this.updateDiscountForm = this.formBuilder.group({
+    this.updateDiscountForm = this.formBuilder.nonNullable.group({
       discountAmount: [
         this.discountValue,
         [
           Validators.required,
           Validators.min(0),
           amountValueValidator()
         ]
       ],
       note: [
         '',
         Validators.maxLength(this.maxNoteLength)
       ]
     });
@@
-    const formValue = this.updateDiscountForm.value;
+    const formValue = this.updateDiscountForm.getRawValue();

Aligns with coding guideline src/app/**/*.ts: "Use TypeScript for all application code with strict typing conventions."

Also applies to: 38, 44, 75

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/app/loans/loans-view/loan-account-actions/update-discount/update-discount.component.ts`
around lines 12 - 13, The component is using UntypedFormBuilder/UntypedFormGroup
which removes compile-time shape checks; replace them with typed Reactive Forms:
import FormBuilder and FormGroup (not Untyped*), declare an interface for the
form model (e.g. UpdateDiscountForm { discountAmount: number; reason?: string;
... } matching the component's form fields), update the constructor injection to
use FormBuilder, and change the form property type to
FormGroup<UpdateDiscountForm> and initialize it via this.fb.group(...) with
typed controls and Validators so all usages (e.g. in update-discount.component
class methods that reference the form) are type-checked and the imports updated
accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@src/app/loans/loans-view/loans-view.component.ts`:
- Around line 582-587: The current guard canShowWorkingCapitalDiscountUpdate
only checks loanProductService.isWorkingCapital and
loanDetailsData.status.active; update it to enforce full working-capital
discount eligibility by either: 1) preferring a single backend-driven boolean
(e.g., loanDetailsData.fullWorkingCapitalDiscountEligible) and returning that &&
loanDetailsData.status.active, or 2) if backend flag is unavailable, add
explicit checks inside canShowWorkingCapitalDiscountUpdate for
disbursement-date-only (e.g., loanDetailsData.discount?.disbursementDateOnly),
one-time-only (e.g., loanDetailsData.discount?.oneTimeOnly), and that the
discount was not already added during creation/approval (e.g.,
!loanDetailsData.discount?.addedDuringCreationOrApproval) in addition to
loanProductService.isWorkingCapital and loanDetailsData.status.active; ensure
the same consolidated guard is used wherever the feature is invoked (notably the
caller that currently relies on this guard).

---

Nitpick comments:
In
`@src/app/loans/loans-view/loan-account-actions/update-discount/update-discount.component.ts`:
- Around line 12-13: The component is using UntypedFormBuilder/UntypedFormGroup
which removes compile-time shape checks; replace them with typed Reactive Forms:
import FormBuilder and FormGroup (not Untyped*), declare an interface for the
form model (e.g. UpdateDiscountForm { discountAmount: number; reason?: string;
... } matching the component's form fields), update the constructor injection to
use FormBuilder, and change the form property type to
FormGroup<UpdateDiscountForm> and initialize it via this.fb.group(...) with
typed controls and Validators so all usages (e.g. in update-discount.component
class methods that reference the form) are type-checked and the imports updated
accordingly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b0fd95cd-1590-4cf4-befe-3aa6fa1cf4f9

📥 Commits

Reviewing files that changed from the base of the PR and between 95cff71 and 52d2595.

📒 Files selected for processing (20)
  • src/app/loans/common-resolvers/loan-action-button.resolver.ts
  • src/app/loans/loans-view/loan-account-actions/loan-account-actions.component.html
  • src/app/loans/loans-view/loan-account-actions/loan-account-actions.component.ts
  • src/app/loans/loans-view/loan-account-actions/update-discount/update-discount.component.html
  • src/app/loans/loans-view/loan-account-actions/update-discount/update-discount.component.ts
  • src/app/loans/loans-view/loans-view.component.ts
  • src/app/loans/loans.service.ts
  • src/assets/translations/cs-CS.json
  • src/assets/translations/de-DE.json
  • src/assets/translations/en-US.json
  • src/assets/translations/es-CL.json
  • src/assets/translations/es-MX.json
  • src/assets/translations/fr-FR.json
  • src/assets/translations/it-IT.json
  • src/assets/translations/ko-KO.json
  • src/assets/translations/lt-LT.json
  • src/assets/translations/lv-LV.json
  • src/assets/translations/ne-NE.json
  • src/assets/translations/pt-PT.json
  • src/assets/translations/sw-SW.json
✅ Files skipped from review due to trivial changes (5)
  • src/assets/translations/ne-NE.json
  • src/assets/translations/it-IT.json
  • src/assets/translations/sw-SW.json
  • src/assets/translations/lt-LT.json
  • src/assets/translations/ko-KO.json
🚧 Files skipped from review as they are similar to previous changes (10)
  • src/app/loans/common-resolvers/loan-action-button.resolver.ts
  • src/app/loans/loans-view/loan-account-actions/loan-account-actions.component.html
  • src/app/loans/loans.service.ts
  • src/assets/translations/pt-PT.json
  • src/assets/translations/cs-CS.json
  • src/assets/translations/es-CL.json
  • src/assets/translations/de-DE.json
  • src/app/loans/loans-view/loan-account-actions/update-discount/update-discount.component.html
  • src/assets/translations/en-US.json
  • src/assets/translations/fr-FR.json

Copy link
Copy Markdown
Collaborator

@alberto-art3ch alberto-art3ch left a comment

Choose a reason for hiding this comment

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

LGTM

@alberto-art3ch alberto-art3ch merged commit d0f15c4 into openMF:dev Apr 2, 2026
6 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