Skip to content

WEB-657: Working Capital Loan - Write-Off - #3798

Open
alberto-art3ch wants to merge 1 commit into
openMF:devfrom
alberto-art3ch:WEB-657/working-capital-loan-write-off
Open

WEB-657: Working Capital Loan - Write-Off#3798
alberto-art3ch wants to merge 1 commit into
openMF:devfrom
alberto-art3ch:WEB-657/working-capital-loan-write-off

Conversation

@alberto-art3ch

@alberto-art3ch alberto-art3ch commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Description

Adds Write-Off and Undo Write-Off actions for Working Capital loans, mirroring the term-loan flow with dedicated typed components wired into the shared loan action switch. Write-Off posts to POST /working-capital-loans/{id}/transactions?command=writeOff (reason dropdown sourced from the "WriteOffReasons" code values, since WC has no write-off template) and Undo Write-Off to command=undoWriteOff; both gated by the WRITEOFF_WORKINGCAPITALLOAN / UNDOWRITEOFF_WORKINGCAPITALLOAN permissions and the loan status. Includes the terminal-state button config, the written-off date/reason display in the general tab, and the Reversal External Id

Related issues and discussion

WEB-657

Screenshots, if any

Screen.Recording.2026-08-04.at.2.26.33.PM.mov

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 write-off and undo write-off workflows for working-capital loans.
    • Added validated forms for dates, reasons, notes, and external IDs.
    • Added working-capital loan states and actions for writing off and reversing write-offs.
    • Added written-off status badges, dates, and optional reasons to loan details.
  • Enhancements

    • Standard and working-capital loans now use the appropriate write-off experience.
    • Added localized labels and statuses across supported languages.
    • Added permission-aware action controls and submission validation.

@alberto-art3ch
alberto-art3ch requested a review from a team August 4, 2026 19:30
@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Review Change Stack

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: "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

Working-capital loans now have dedicated write-off and undo-write-off forms, action routing, request models, permissions, status displays, styling, and translations. Standard loan write-off behavior remains separate.

Changes

Working-capital write-off workflow

Layer / File(s) Summary
Request contracts and template data
src/app/loans/models/working-capital/..., src/app/loans/loans.service.ts
Added request interfaces and loading of WriteOffReasons options.
Write-off form
src/app/loans/loans-view/working-capital/loan-account-actions/write-off/*
Added validated write-off fields, payload construction, submission, error handling, and navigation.
Undo write-off form
src/app/loans/loans-view/working-capital/loan-account-actions/undo-write-off/*
Added reversal fields, validation, submission, error handling, and navigation.
Loan action routing and status actions
src/app/loans/common-resolvers/..., src/app/loans/loans-view/loan-accounts-button-config.ts, src/app/loans/loans-view/loan-account-actions/*, src/app/loans/loans-view/general-tab/*
Working-capital loans now select dedicated components and expose write-off or undo-write-off actions by state and permission.
Loan status and write-off display
src/app/loans/loans-view/loans-view.component.*
Added written-off metadata and status badge styling.
Write-off translations
src/assets/translations/*.json
Added labels for reversal external ID, written-off dates, write-off actions, and written-off statuses across supported locales.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

  • openMF/web-app#3740: Shares loan-view service and translation changes but targets the loans list.
  • openMF/web-app#3790: Uses similar working-capital loan action patterns for charge-off flows.

Suggested reviewers: adamsaghy

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely identifies the main change: adding write-off support for working-capital loans.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 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.

@alberto-art3ch
alberto-art3ch force-pushed the WEB-657/working-capital-loan-write-off branch from bd4ff1b to 44b0eb9 Compare August 4, 2026 19:37

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/app/loans/loans-view/working-capital/loan-account-actions/undo-write-off/undo-write-off.component.html (1)

14-14: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use the 8px spacing scale.

m-b-20 and gap-5px encode 20px and 5px spacing. Replace them with existing 8px-grid utilities or shared theme variables.

As per coding guidelines, src/**/*.{scss,html} must use the 8px grid and shared styling variables instead of explicit pixel spacing.

Also applies to: 35-35

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/app/loans/loans-view/working-capital/loan-account-actions/undo-write-off/undo-write-off.component.html`
at line 14, Replace the m-b-20 and gap-5px spacing utilities in the
undo-write-off template with existing 8px-grid utilities or shared theme
variables, preserving the current layout spacing without explicit non-grid pixel
values.

Source: Coding guidelines

src/app/loans/loans.service.ts (1)

681-694: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Type the write-off template response.

getWorkingCapitalWriteOffTemplate() returns Observable<any> and the WriteOffReasons code/codevalue responses use any[]. Move WriteOffReasonOption, the code record, the code value shape used here, and { writeOffReasonOptions } out of WorkingCapitalWriteOffComponent into src/app/loans/models/working-capital/working-capital-loan-account.model.ts so the service can return a typed shareable response.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/loans/loans.service.ts` around lines 681 - 694, Move the
write-off-related interfaces currently defined in
WorkingCapitalWriteOffComponent into working-capital-loan-account.model.ts,
including WriteOffReasonOption, the code record, the code value shape, and the {
writeOffReasonOptions } response. Update getWorkingCapitalWriteOffTemplate() to
use these shared types instead of any/any[], and update the component imports
and references to consume the relocated models.

Sources: Coding guidelines, Learnings

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/app/loans/loans-view/general-tab/general-tab.component.html`:
- Around line 114-117: Update the translation key in the write-off reason label
within the general-tab template from “labels.inputs.Write-off Reason” to
“labels.inputs.WriteOff Reason”; leave the surrounding
loanDetails.writeOffReason rendering unchanged.

---

Nitpick comments:
In
`@src/app/loans/loans-view/working-capital/loan-account-actions/undo-write-off/undo-write-off.component.html`:
- Line 14: Replace the m-b-20 and gap-5px spacing utilities in the
undo-write-off template with existing 8px-grid utilities or shared theme
variables, preserving the current layout spacing without explicit non-grid pixel
values.

In `@src/app/loans/loans.service.ts`:
- Around line 681-694: Move the write-off-related interfaces currently defined
in WorkingCapitalWriteOffComponent into working-capital-loan-account.model.ts,
including WriteOffReasonOption, the code record, the code value shape, and the {
writeOffReasonOptions } response. Update getWorkingCapitalWriteOffTemplate() to
use these shared types instead of any/any[], and update the component imports
and references to consume the relocated models.
🪄 Autofix

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 Plus

Run ID: 06613eb3-de9e-4266-af81-504a67c6be2e

📥 Commits

Reviewing files that changed from the base of the PR and between e842bba and bd4ff1b.

📒 Files selected for processing (26)
  • src/app/loans/common-resolvers/loan-action-button.resolver.ts
  • src/app/loans/loans-view/general-tab/general-tab.component.html
  • 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-accounts-button-config.ts
  • src/app/loans/loans-view/working-capital/loan-account-actions/undo-write-off/undo-write-off.component.html
  • src/app/loans/loans-view/working-capital/loan-account-actions/undo-write-off/undo-write-off.component.scss
  • src/app/loans/loans-view/working-capital/loan-account-actions/undo-write-off/undo-write-off.component.ts
  • src/app/loans/loans-view/working-capital/loan-account-actions/write-off/write-off.component.html
  • src/app/loans/loans-view/working-capital/loan-account-actions/write-off/write-off.component.scss
  • src/app/loans/loans-view/working-capital/loan-account-actions/write-off/write-off.component.ts
  • src/app/loans/loans.service.ts
  • src/app/loans/models/working-capital/working-capital-loan-account.model.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 thread src/app/loans/loans-view/general-tab/general-tab.component.html Outdated
@alberto-art3ch
alberto-art3ch force-pushed the WEB-657/working-capital-loan-write-off branch from 44b0eb9 to 137d69f Compare August 5, 2026 03:17
@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/app/loans/loans-view/loans-view.component.scss`:
- Around line 34-80: Update the working-capital status mapping used by
iconLoanStatusColor so loanStatusType.closed.written.off resolves to the
status-writtenoff pill modifier instead of status-unknown. Add the corresponding
status-writtenoff styling under account-status-pill using the dedicated error
colour.

In `@src/assets/translations/fr-FR.json`:
- Line 3157: Update the French translations for “Written Off On” at all three
occurrences to use the file’s existing “radiation” terminology instead of “passé
en perte”, while preserving the intended date-label meaning.

In `@src/assets/translations/ko-KO.json`:
- Around line 3425-3426: Update the "Withdrawn" translation in the Korean locale
to "철회됨", matching the existing "Withdrawn by Client" wording and expressing it
as a status.

In `@src/assets/translations/lt-LT.json`:
- Line 3153: Update the lt-LT translation for the “Written Off On” key to use
the date-specific label “Nurašymo data”, matching the existing “Write Off Date”
translation rather than the status wording.

In `@src/assets/translations/lv-LV.json`:
- Around line 3296-3297: Update the Latvian translation entries for Charge-Off
and Write-Off so they use distinct descriptive labels, preserving the existing
translation for one action and replacing the duplicate Norakstīšana value for
the other.

In `@src/assets/translations/sw-SW.json`:
- Line 3294: Update the “Write-Off” and “Written Off” translation entries in the
Swahili locale, including the related entry near line 3423, to use the same
approved Swahili write-off term consistently with the other same-meaning keys.
Remove the inconsistent “Ufutaji” value and preserve the surrounding translation
structure.
🪄 Autofix

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 Plus

Run ID: 038a7081-0680-4a8c-bd4d-646a73115386

📥 Commits

Reviewing files that changed from the base of the PR and between e842bba and 137d69f.

📒 Files selected for processing (29)
  • src/app/loans/common-resolvers/loan-action-button.resolver.ts
  • src/app/loans/loans-view/general-tab/general-tab.component.html
  • 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-accounts-button-config.ts
  • src/app/loans/loans-view/loans-view.component.html
  • src/app/loans/loans-view/loans-view.component.scss
  • src/app/loans/loans-view/loans-view.component.ts
  • src/app/loans/loans-view/working-capital/loan-account-actions/undo-write-off/undo-write-off.component.html
  • src/app/loans/loans-view/working-capital/loan-account-actions/undo-write-off/undo-write-off.component.scss
  • src/app/loans/loans-view/working-capital/loan-account-actions/undo-write-off/undo-write-off.component.ts
  • src/app/loans/loans-view/working-capital/loan-account-actions/write-off/write-off.component.html
  • src/app/loans/loans-view/working-capital/loan-account-actions/write-off/write-off.component.scss
  • src/app/loans/loans-view/working-capital/loan-account-actions/write-off/write-off.component.ts
  • src/app/loans/loans.service.ts
  • src/app/loans/models/working-capital/working-capital-loan-account.model.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 as they are similar to previous changes (14)
  • 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-accounts-button-config.ts
  • src/app/loans/loans-view/working-capital/loan-account-actions/undo-write-off/undo-write-off.component.scss
  • src/app/loans/loans-view/loan-account-actions/loan-account-actions.component.html
  • src/app/loans/loans-view/working-capital/loan-account-actions/write-off/write-off.component.scss
  • src/app/loans/loans-view/working-capital/loan-account-actions/undo-write-off/undo-write-off.component.html
  • src/app/loans/loans-view/working-capital/loan-account-actions/undo-write-off/undo-write-off.component.ts
  • src/app/loans/loans-view/working-capital/loan-account-actions/write-off/write-off.component.ts
  • src/app/loans/loans-view/working-capital/loan-account-actions/write-off/write-off.component.html
  • src/app/loans/models/working-capital/working-capital-loan-account.model.ts
  • src/assets/translations/en-US.json
  • src/app/loans/loans.service.ts
  • src/assets/translations/es-MX.json

Comment on lines +34 to +80
.account-status-pill {
display: inline-block;
margin-left: 12px;
padding: 2px 10px;
border-radius: 12px;
font-size: 0.72rem;
font-weight: 600;
line-height: 1.6;
letter-spacing: 0.04em;
text-transform: uppercase;
vertical-align: middle;
color: #fff;
background-color: $status-inactive;

&.status-active {
background-color: $status-active;
}

&.status-active-overdue,
&.status-block {
background-color: $status-active-overdue;
}

&.status-pending {
background-color: $status-pending;
}

&.status-approved {
background-color: $status-approved;
}

&.status-overpaid {
background-color: $status-overpaid;
}

&.status-chargeoff {
background-color: $status-chargeoff;
}

&.status-matured {
background-color: $status-matured;
}

&.subStatus-contract-termination {
background-color: $subStatus-contract-termination;
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate the statusLookup pipe implementation
fd -i 'status-lookup' --type f

# Inspect its mapping logic
fd -i 'status-lookup.pipe.ts' --type f -x cat -n {}

Repository: openMF/web-app

Length of output: 3559


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== candidate files =="
fd -i 'translations|loans-view|status-lookup|written' --type f | sed -n '1,120p'

echo
echo "== written off references =="
rg -n "Written Off|written[- ]?off|writtenoff|loanStatusType" src/app -g '!**/*.map' | sed -n '1,220p'

echo
echo "== loans-view scss relevant section =="
fd -i '^loans-view\.component\.scss$' --type f -x sh -c 'echo "--- $1"; wc -l "$1"; sed -n "1,140p" "$1"' sh {}

echo
echo "== loans-view ts relevant section =="
fd -i '^loans-view\.component\.ts$' --type f -x sh -c 'echo "--- $1"; wc -l "$1"; rg -n "accountStatus|statusLookup|written|class|template" "$1" -A4 -B4; sed -n "1,220p" "$1"' sh {}

Repository: openMF/web-app

Length of output: 18297


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '520,625p' src/app/loans/loans-view/loans-view.component.ts
echo
sed -n '55,105p' src/app/loans/loans-view/loans-view.component.html
echo
sed -n '1,35p' src/app/loans/loans-view/loans-view.component.scss
echo
python3 - <<'PY'
from pathlib import Path
import re
lookup = {}
for m in re.finditer(r"['\"].*?['\"]:\s['\"](.*)['\"]", Path('src/app/pipes/status-lookup.pipe.ts').read_text()):
    key, value = m.groups()
    if value in ('status-unknown',):
       lookup[key] = 'status-unknown'
    else:
       lookup[key] = value.split("'")[0]

pill_classes = re.findall(r"&\.([A-Za-z0-9_-]+)", Path('src/app/loans/loans-view/loans-view.component.scss').read_text())
print('unknown keys:', sorted([k for k in lookup if 'written' in k.lower() or 'close' in k.lower() or 'with' in k.lower()]))
print('status-unknown pipeline:', sorted([k for k,v in lookup.items() if 'unknown' in v]))
print('pill modifiers:', pill_classes)
PY

Repository: openMF/web-app

Length of output: 6863


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
import re

scm = Path('src/app/pipes/status-lookup.pipe.ts').read_text()
lookup = {}
for key, value in re.findall(r"['\"]([^'\"]+)['\"]\\s*:\\s*['\"]([^'\"]+)['\"]", scm):
    lookup.setdefault(key, value)

# Extract exact .class-name selectors from .account-status-pill block.
scss = Path('src/app/loans/loans-view/loans-view.component.scss').read_text()
block = re.search(r'\\.account-status-pill\\s*\\{(?P<body>[^}]*(?:\\{[^}]*\\}[^}]*)*)\\}\\s*\\n', scss)
modifiers = []
if block:
    modifiers = re.findall(r'^[[:space:]]*\\&\\.([A-Za-z0-9_-]+)', block.group('body'), re.M)

print("pipe mapping keys containing written/off/charge/close/with or status unknown:")
for key in sorted(lookup):
    if any(token in key.lower() for token in ['written', 'off', 'charge', 'close', 'with', 'withdraw']) or lookup[key] == 'status-unknown':
        print(f"{key!r} => {lookup[key]!r}")
print("\naccount-status-pill modifiers:")
print(", ".join(modifiers))

# Find computed status code for a written-off working-capital loan by inspecting code paths.
ts = Path('src/app/loans/loans-view/loans-view.component.ts').read_text()
m = re.search(r'iconLoanStatusColor\\([\\s\\S]*?return this\\.loanDetailsData\\.status\\?\\.code;', ts)
print("\niconLoanStatusColor tail containing return:", bool(m))
if m:
    print(m.group(0)[-500:])
PY

Repository: openMF/web-app

Length of output: 1087


Map the written-off working-capital status to a pill modifier.

iconLoanStatusColor() returns loanDetailsData.status?.code for working-capital loans, and the missing lookup key falls back to status-unknown; account-status-pill then uses the inactive colour instead of the dedicated error-coloured written-off badge. Add a mapped loanStatusType.closed.written.off.status-writtenoff path for the pill.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app/loans/loans-view/loans-view.component.scss` around lines 34 - 80,
Update the working-capital status mapping used by iconLoanStatusColor so
loanStatusType.closed.written.off resolves to the status-writtenoff pill
modifier instead of status-unknown. Add the corresponding status-writtenoff
styling under account-status-pill using the dedicated error colour.

Source: Coding guidelines

"Write-off": "Radier",
"WriteOff Reason": "Motif de radiation",
"Written Off": "Radié",
"Written Off On": "Passé en perte le",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Use consistent French terminology for write-off states.

Lines 3157, 3301, and 3430 use “passé en perte”, while this file already uses “radiation” and “radié” for the same concept. Use the existing terminology.

Proposed change
-      "Written Off On": "Passé en perte le",
+      "Written Off On": "Radié le",

-      "Write-Off": "Passer en perte",
+      "Write-Off": "Radier",

-      "Written Off": "Passé en perte"
+      "Written Off": "Radié"

Also applies to: 3301-3301, 3430-3430

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/assets/translations/fr-FR.json` at line 3157, Update the French
translations for “Written Off On” at all three occurrences to use the file’s
existing “radiation” terminology instead of “passé en perte”, while preserving
the intended date-label meaning.

Comment on lines +3425 to +3426
"Withdrawn": "빼는",
"Written Off": "상각됨"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Use a status-form translation for Withdrawn.

"빼는" means “taking out” and does not read as a loan status. Use "철회됨" to match the existing Withdrawn by Client translation and the status context.

Proposed fix
-      "Withdrawn": "빼는",
+      "Withdrawn": "철회됨",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"Withdrawn": "빼는",
"Written Off": "상각됨"
"Withdrawn": "철회됨",
"Written Off": "상각됨"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/assets/translations/ko-KO.json` around lines 3425 - 3426, Update the
"Withdrawn" translation in the Korean locale to "철회됨", matching the existing
"Withdrawn by Client" wording and expressing it as a status.

"Write-off": "Nusirašinėti",
"WriteOff Reason": "Nurašymo priežastis",
"Written Off": "Nurašytas",
"Written Off On": "Nurašyta",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Use a date label for Written Off On.

Nurašyta describes the status and does not identify a date. Use Nurašymo data, which matches the existing Write Off Date translation.

Based on the PR objective, this label displays the written-off date in the General tab.

Proposed fix
-      "Written Off On": "Nurašyta",
+      "Written Off On": "Nurašymo data",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"Written Off On": "Nurašyta",
"Written Off On": "Nurašymo data",
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/assets/translations/lt-LT.json` at line 3153, Update the lt-LT
translation for the “Written Off On” key to use the date-specific label
“Nurašymo data”, matching the existing “Write Off Date” translation rather than
the status wording.

Comment on lines 3296 to +3297
"Charge-Off": "Norakstīšana",
"Write-Off": "Norakstīšana",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

What is the standard Latvian financial term to distinguish "charge-off" from "write-off" in loan management systems?

💡 Result:

In Latvian financial and accounting contexts, the term "norakstīšana" (write-off) is the standard terminology used to describe the process of removing an uncollectible asset or debt from the balance sheet [1][2][3]. Latvian financial systems and regulatory documents, such as those issued by Latvijas Banka (the central bank), consistently refer to the accounting of loan losses and asset removals using the term "norakstīšana" or "zaudējumu norakstīšana" (write-off/write-down) [4][5][6]. While English terminology distinguishes between "charge-off" (a status often used in consumer credit to signal a formal declaration of uncollectibility and an accounting write-off) [7][8] and "write-off" (the broader accounting action) [7][8][9], Latvian financial terminology typically does not utilize a separate, distinct technical term equivalent to the English "charge-off." Instead, both concepts are generally subsumed under "norakstīšana." If a distinction is necessary in a loan management system to reflect the specific nature of a charge-off (e.g., as a regulatory milestone for non-performing loans), institutions typically use descriptive phrasing rather than a single specialized noun. Commonly used descriptive terms include: 1. Zaudējumu norakstīšana: Used to specify that the write-off is explicitly recognized as a financial loss [1][3]. 2. Bezcerīgā parāda norakstīšana: Used to denote the writing off of "hopeless" or bad debt that is deemed uncollectible [2][3]. For technical implementation in loan management systems, "norakstīšana" serves as the primary functional term, often qualified by context (e.g., status flags or category labels) to differentiate between internal administrative actions and formal loss recognition.

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== file excerpt around keys =="
sed -n '3288,3302p' src/assets/translations/lv-L V.json 2>/dev/null || sed -n '3288,3302p' src/assets/translations/lv-LV.json

echo
echo "== exact key occurrences in lv translation =="
python3 - <<'PY'
from pathlib import Path
import json
p = Path("src/assets/translations/lv-LV.json")
data = json.load(p.open(encoding="utf-8"))
def walk(o, path=None):
    for k,v in o.items() if isinstance(o, dict) else []:
        yield path + [k], k, v
        yield from walk(v, path+[k])
    for i,v in enumerate(o) if isinstance(o, list) else []:
        yield path + [str(i)], str(i), v
        yield from walk(v, path+[str(i)])
for k,v in walk(data):
    if k in ("Charge-Off","Write-Off","Norakstīšana"):
        continue
    if k == "Charge-Off" or k == "Write-Off":
        print(f"{path_to_json(k, k)} {v}")
PY

echo
echo "== keys containing Charge or Write in all translation files =="
rg -n '"(Charge-Off|Write-Off)"' src/assets/translations || true

echo
echo "== local term occurrences =="
rg -n '"Norakstīšana"' src/assets/translations || true

Repository: openMF/web-app

Length of output: 1111


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
import json
from pathlib import Path

p = Path("src/assets/translations/lv-LV.json")
data = json.load(p.open(encoding="utf-8"))

def walk(o, path=None):
    for k, v in ((k, v) for k, v in o.items()) if isinstance(o, dict) else []:
        yield "+".join(path) + ":" + str(k), k, v
        yield from walk(v, path + [k])
    for i, v in enumerate(o) if isinstance(o, list) else []:
        yield "+".join(path) + ":" + str(i), str(i), v
        yield from walk(v, path + [str(i)])

print("lv-LV entries:")
for path_key, key, value in walk(data):
    if key in ("Charge-Off", "Write-Off"):
        print(f"{path_key}: {value}")

print()
print("all translation files Charge-Off / Write-Off:")
for trans in sorted(Path("src/assets/translations").glob("*.json")):
    jd = json.load(trans.open(encoding="utf-8"))
    # simple recursive traversal without dependency libraries
    def scan(o, spath=""):
        hits = []
        if isinstance(o, dict):
            for k,v in o.items():
                if k in ("Charge-Off", "Write-Off"):
                    hits.append((trans.name, f"{spath}:{k}", v))
                hits.extend(scan(v, f"{spath}:{k}" if spath else str(k)))
        elif isinstance(o, list):
            for i,v in enumerate(o):
                hits.extend(scan(v, f"{spath}:{i}" if spath else str(i)))
        return hits
    for h in scan(jd):
        print(" ".join(h))
PY

Repository: openMF/web-app

Length of output: 312


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== exact key occurrences in lv-LV.json =="
python3 - <<'PY'
import json
from pathlib import Path

p = Path("src/assets/translations/lv-LV.json")
data = json.load(p.open(encoding="utf-8"))

def walk(o, path=None):
    if path is None:
        path = []
    for k, v in ((k, v) for k, v in o.items()) if isinstance(o, dict) else []:
        yield path + [k], k, v
        yield from walk(v, path + [k])
    for i, v in enumerate(o) if isinstance(o, list) else []:
        yield path + [str(i)], str(i), v
        yield from walk(v, path + [str(i)])

for path, key, value in walk(data):
    if key in ("Charge-Off", "Write-Off"):
        print(f"{':' .join(str(x) for x in path)}: {value}")
PY

echo
echo "== keys containing Charge or Write in all translation files =="
rg -n '"(Charge-Off|Write-Off)"' src/assets/translations || true

echo
echo "== local term occurrences =="
rg -n '"Norakstīšana"' src/assets/translations || true

Repository: openMF/web-app

Length of output: 2468


Use separate Latvian labels for Charge-Off and Write-Off.

Charge-Off and Write-Off both translate to Norakstīšana in src/assets/translations/lv-LV.json, so Latvian users cannot distinguish these separate menu actions. Use one term for Charge-Off and a different descriptive term for Write-Off.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/assets/translations/lv-LV.json` around lines 3296 - 3297, Update the
Latvian translation entries for Charge-Off and Write-Off so they use distinct
descriptive labels, preserving the existing translation for one action and
replacing the duplicate Norakstīšana value for the other.

"Centers": "Vituo",
"Change Loan Officer": "Badilisha Afisa Mikopo",
"Charge-Off": "Chaji-Zima",
"Write-Off": "Ufutaji",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Locate translation file and relevant keys"
if [ -f src/assets/translations/sw-SW.json ]; then
  python3 - <<'PY'
import json, re
from pathlib import Path
path = Path("src/assets/translations/sw-SW.json")
data = json.loads(path.read_text(encoding="utf-8"))

def walk(obj, prefix=""):
    if isinstance(obj, dict):
        for k, v in obj.items():
            if isinstance(v, dict):
                yield from walk(v, f"{prefix}.{k}" if prefix else k)
            else:
                yield f"{prefix}.{k}" if prefix else k, v
    elif isinstance(obj, list):
        for i, v in enumerate(obj):
            yield from walk(v, f"{prefix}[{i}]")

matches = {}
for key, val in walk(data):
    if isinstance(val, str) and re.search(r'Write-?Off|Written Off|Kufuta|futa|Andika|Imeandikwa|Ufutaji|Imefutwa', val, re.I):
        matches[key] = val

print("Relevant matches:")
for key, val in sorted(matches.items()):
    print(f"{key}: {val}")

# Print a numeric-ish range around the reported line by locating newline count in raw JSON approximation for nested keys is hard; use textual search in raw.
text = path.read_text(encoding="utf-8").splitlines()
print("\nRaw context around lines 3280-3435:")
for n in range(3280, min(3436, len(text)) + 1):
    if n <= len(text):
        line = text[n-1]
        if "Write-Off" in line or "Written Off" in line or "Andika" in line or "Ufutaji" in line or "Imeandikwa" in line or "Kufuta" in line:
            print(f"{n}: {line}")
else:
    print("No translation file or context found.")
PY
else
  echo "src/assets/translations/sw-SW.json not found"
fi

Repository: openMF/web-app

Length of output: 8464


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Neighborhood of write-off/write-off status translations"
python3 - <<'PY'
from pathlib import Path
path = Path("src/assets/translations/sw-SW.json")
lines = path.read_text(encoding="utf-8").splitlines()
for n in range(3284, min(3428, len(lines)) + 1):
    print(f"{n}: {lines[n-1]}")
PY

echo
echo "Compare related label keys"
python3 - <<'PY'
from pathlib import Path
import json
path = Path("src/assets/translations/sw-SW.json")
data = json.loads(path.read_text(encoding="utf-8"))

def walk(obj, prefix=""):
    if isinstance(obj, dict):
        for k, v in obj.items():
            if isinstance(v, dict):
                yield from walk(v, f"{prefix}.{k}" if prefix else k)
            else:
                yield f"{prefix}.{k}" if prefix else k, v
    elif isinstance(obj, list):
        for i, v in enumerate(obj):
            yield from walk(v, f"{prefix}[{i}]")

terms = ["Write Off", "Write-Off", "Written Off", "Closed (written off)", "Write off on", "Writeoff", "Writtenoff", "Reason for Write-Off", "WriteOff", "Undo Write-off"]
print("Target/related term translations:")
for key, val in walk(data):
    if val in terms or any(s in key for s in ["Write Off", "Write-Off", "Written Off", "writeoff", "Writtenoff", "Write off", "Undo Write-off"]):
        print(f"{key}: {val}")
# Also show nearby JSON key names by raw text scan for exact English keys.
for i, line in enumerate(path.read_text(encoding="utf-8").splitlines(), 1):
    if "Write" in line or "Write-Off" in line or "Write-off" in line or "Written Off" in line or "writeoff" in line or "Writtenoff" in line:
        print(f"raw {i}: {line}")
PY

Repository: openMF/web-app

Length of output: 9140


Use one Swahili term for write-off everywhere.

Write-Off is translated as Ufutaji, while same-meaning keys use Andika, Kuandika-mbali, or Imeandikwa Mbali. Apply the same approved term to Write-Off and Written Off consistently in this file.

Also applies to line 3423.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/assets/translations/sw-SW.json` at line 3294, Update the “Write-Off” and
“Written Off” translation entries in the Swahili locale, including the related
entry near line 3423, to use the same approved Swahili write-off term
consistently with the other same-meaning keys. Remove the inconsistent “Ufutaji”
value and preserve the surrounding translation structure.

@alberto-art3ch
alberto-art3ch force-pushed the WEB-657/working-capital-loan-write-off branch from 137d69f to 83396ff Compare August 6, 2026 23:27
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@alberto-art3ch
alberto-art3ch force-pushed the WEB-657/working-capital-loan-write-off branch from 83396ff to 3770c43 Compare August 7, 2026 13:49

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 13

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (7)
src/assets/translations/de-DE.json (1)

829-829: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Replace the loan charge-off translations with a financial charge-off term.

Abladen means unloading and conflicts with the existing Write-Off Abschreibung. Use a consistent charge-off/charged-off term such as Ausbuchung/Ausgebucht for these labels, for example at catalogs, labels.menus, and labels.dialogContext.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/assets/translations/de-DE.json` at line 829, Update the German charge-off
translations in catalogs, labels.menus, and labels.dialogContext to use the
financial terms Ausbuchung/Ausgebucht instead of Abladen, while preserving the
existing Write-Off translation Abschreibung.
src/assets/translations/pt-PT.json (1)

827-827: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Use accounting terminology for Charge-Off.

These entries translate Charge-Off as Cobrança or Cobrado. These terms describe collection or charging. They do not describe an accounting write-off. Use terminology consistent with Write-Off: Baixa, Montante da baixa, Data da baixa, Baixado em, and desfazer a baixa.

Proposed terminology fixes
-      "Charge-off": "Cobrança",
+      "Charge-off": "Baixa",
-      "Charge-Off Amount": "Montante da cobrança",
+      "Charge-Off Amount": "Montante da baixa",
-      "Charge-Off Date": "Data da cobrança",
+      "Charge-Off Date": "Data da baixa",
-      "Charged Off On": "Cobrado em",
+      "Charged Off On": "Baixado em",
-      "Charged Off": "Cobrado",
+      "Charged Off": "Baixado",
-      "Are you sure you want to undo the charge-off": "Tem a certeza de que pretende desfazer a cobrança?",
+      "Are you sure you want to undo the charge-off": "Tem a certeza de que pretende desfazer a baixa?",

Also applies to: 1836-1837, 1841-1841, 3430-3430, 3486-3486

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/assets/translations/pt-PT.json` at line 827, Update the Portuguese
translations for all `Charge-Off` entries, including the referenced entries, to
use accounting write-off terminology consistent with the existing `Write-Off`
translations, replacing collection-related terms such as “Cobrança” and
“Cobrado” with the appropriate “Baixa” forms while preserving each string’s
grammatical context.
src/assets/translations/fr-FR.json (2)

1147-1147: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Correct the French grammar for Mark as Fraud.

Marquer comme fraude is not a valid action label. Use Marquer comme frauduleux and Marquer ce prêt comme frauduleux ?.

Also applies to: 3283-3283, 3468-3468

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/assets/translations/fr-FR.json` at line 1147, Update the French
translations for the `Mark as Fraud` action and its related confirmation prompt
to use “Marquer comme frauduleux” and “Marquer ce prêt comme frauduleux ?”
respectively, including all occurrences identified in the translation file.

827-827: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Use the established French terminology for charge-off.

The changed values use amortir, amortissement, and Amorti. These terms mean amortization. This file uses radiation and radié for charge-off states. Use consistent charge-off terminology for the action, amount, date, status, and undo confirmation.

Also applies to: 1840-1841, 1845-1845, 3434-3434, 3490-3490

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/assets/translations/fr-FR.json` at line 827, Update the French charge-off
translation entries, including “Charge-off” and the referenced action, amount,
date, status, and undo-confirmation keys, to use the established
“radiation”/“radié” terminology instead of “amortir”, “amortissement”, or
“Amorti”.
src/assets/translations/it-IT.json (1)

3434-3434: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Correct the written-off status translation.

"Chiuso (scritto)" means “closed (written)”, not “closed (written off)”. Use the existing write-off terminology from this file.

Proposed fix
-      "Closed (written off)": "Chiuso (scritto)",
+      "Closed (written off)": "Chiuso (stralciato)",
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/assets/translations/it-IT.json` at line 3434, Update the “Closed (written
off)” entry in the Italian translations to use the file’s existing write-off
terminology, replacing “Chiuso (scritto)” while preserving the key and JSON
structure.
src/assets/translations/lt-LT.json (1)

827-827: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Replace the incorrect Lithuanian Charge-Off translations.

Atsakingas už means “responsible for”. It does not describe a charge-off. Use charge-off terminology for the action and status. Use date-specific text for Charge-Off Date and Charged Off On. Use amount-specific text for Charge-Off Amount.

Proposed fix
-      "Charge-off": "Atsakingas už",
+      "Charge-off": "Nurašymas",
-      "Charge-Off Amount": "Atsakingas už suma",
+      "Charge-Off Amount": "Nurašymo suma",
-      "Charge-Off Date": "Atsakingas už data",
+      "Charge-Off Date": "Nurašymo data",
-      "Charged Off On": "Atsakingas už",
+      "Charged Off On": "Nurašymo data",
-      "Charged Off": "Atsakingas už",
+      "Charged Off": "Nurašyta",
-      "Are you sure you want to undo the charge-off": "Ar tikrai norite anuliuoti Atsakingas už?",
+      "Are you sure you want to undo the charge-off": "Ar tikrai norite anuliuoti nurašymą?",

Also applies to: 1836-1837, 1841-1841, 3430-3430, 3486-3486

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/assets/translations/lt-LT.json` at line 827, Replace the Lithuanian
translations for “Charge-off” and all referenced variants with accurate
charge-off terminology: use action/status wording for “Charge-Off,”
date-specific wording for “Charge-Off Date” and “Charged Off On,” and
amount-specific wording for “Charge-Off Amount.” Update every occurrence
identified by the comment, including the entries near the existing “Charge-off”
translation.
src/assets/translations/lv-LV.json (1)

1839-1841: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Use “norakstīšana” for these charge-off labels.

"Charge-off reason" and "ChargeOff Expense" currently use Izmaksas, which means costs/expenses and not charge-offs. "ChargeOff Fraud Expense" is also translated as “leave fraud expenses”. Use the existing Latvian charge-off term Norakstīšana for consistency, e.g. reason as Norakstīšanas iemesls.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/assets/translations/lv-LV.json` around lines 1839 - 1841, Update the
three charge-off translation entries in the Latvian locale: use “Norakstīšanas
iemesls” for “Charge-off reason” and apply the existing “Norakstīšana”
terminology to both “ChargeOff Expense” and “ChargeOff Fraud Expense”, replacing
the incorrect expense and fraud wording.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/assets/translations/cs-CS.json`:
- Line 2154: Remove the duplicate “Reversal External Id” entry from the
translation object, keeping the existing definition already present in inputs
and preserving its translation value.

In `@src/assets/translations/de-DE.json`:
- Line 2156: Remove the duplicate "Reversal External Id" entry from the later
declaration in the inputs object, while retaining the existing entry near the
earlier translation declaration.

In `@src/assets/translations/en-US.json`:
- Line 2182: Remove the duplicate “Reversal External Id” entry from the
translation object near the shown declaration, retaining the existing
declaration in the inputs object and preserving its value.

In `@src/assets/translations/es-CL.json`:
- Line 2154: Remove the duplicate “Reversal External Id” entry from the inputs
object, keeping the existing entry at the later location around line 2871 and
preserving its translation value.

In `@src/assets/translations/es-MX.json`:
- Line 2161: Remove the duplicate “Reversal External Id” entry from the inputs
object, retaining the existing entry near the earlier declaration and deleting
only the later duplicate.

In `@src/assets/translations/fr-FR.json`:
- Line 2157: Remove the duplicate “Reversal External Id” entry from the
labels.inputs translations, keeping a single declaration with the canonical
French translation.

In `@src/assets/translations/it-IT.json`:
- Line 2154: Remove one of the duplicate "Reversal External Id" entries from the
translation JSON, preserving a single declaration with its existing Italian
value so the inputs object remains valid and deterministic.

In `@src/assets/translations/ko-KO.json`:
- Line 2155: Remove one of the duplicate "Reversal External Id" entries in the
translation object, keeping a single definition with its existing value so the
object has no repeated keys.

In `@src/assets/translations/lt-LT.json`:
- Line 2153: Remove one duplicate “Reversal External Id” entry from the
translations JSON, keeping a single declaration and its existing Lithuanian
translation so the later value no longer overrides the earlier one.

In `@src/assets/translations/lv-LV.json`:
- Line 2154: Remove one of the duplicate “Reversal External Id” entries in the
translations inputs object, retaining a single declaration and its intended
value so JSON parsing and Biome no longer encounter duplicate keys.

In `@src/assets/translations/ne-NE.json`:
- Line 2153: Remove the duplicate "Reversal External Id" entry from the
translation object at the earlier declaration, keeping the existing declaration
later in the object unchanged so noDuplicateObjectKeys is satisfied.

In `@src/assets/translations/pt-PT.json`:
- Line 2153: Remove one of the duplicate “Reversal External Id” entries from the
labels.inputs translation object in pt-PT.json, keeping exactly one declaration
with the existing translation value.

In `@src/assets/translations/sw-SW.json`:
- Line 2151: Remove the duplicate “Reversal External Id” entry from the
labels.inputs translations, keeping one canonical key and its existing value so
the object contains no repeated key.

---

Outside diff comments:
In `@src/assets/translations/de-DE.json`:
- Line 829: Update the German charge-off translations in catalogs, labels.menus,
and labels.dialogContext to use the financial terms Ausbuchung/Ausgebucht
instead of Abladen, while preserving the existing Write-Off translation
Abschreibung.

In `@src/assets/translations/fr-FR.json`:
- Line 1147: Update the French translations for the `Mark as Fraud` action and
its related confirmation prompt to use “Marquer comme frauduleux” and “Marquer
ce prêt comme frauduleux ?” respectively, including all occurrences identified
in the translation file.
- Line 827: Update the French charge-off translation entries, including
“Charge-off” and the referenced action, amount, date, status, and
undo-confirmation keys, to use the established “radiation”/“radié” terminology
instead of “amortir”, “amortissement”, or “Amorti”.

In `@src/assets/translations/it-IT.json`:
- Line 3434: Update the “Closed (written off)” entry in the Italian translations
to use the file’s existing write-off terminology, replacing “Chiuso (scritto)”
while preserving the key and JSON structure.

In `@src/assets/translations/lt-LT.json`:
- Line 827: Replace the Lithuanian translations for “Charge-off” and all
referenced variants with accurate charge-off terminology: use action/status
wording for “Charge-Off,” date-specific wording for “Charge-Off Date” and
“Charged Off On,” and amount-specific wording for “Charge-Off Amount.” Update
every occurrence identified by the comment, including the entries near the
existing “Charge-off” translation.

In `@src/assets/translations/lv-LV.json`:
- Around line 1839-1841: Update the three charge-off translation entries in the
Latvian locale: use “Norakstīšanas iemesls” for “Charge-off reason” and apply
the existing “Norakstīšana” terminology to both “ChargeOff Expense” and
“ChargeOff Fraud Expense”, replacing the incorrect expense and fraud wording.

In `@src/assets/translations/pt-PT.json`:
- Line 827: Update the Portuguese translations for all `Charge-Off` entries,
including the referenced entries, to use accounting write-off terminology
consistent with the existing `Write-Off` translations, replacing
collection-related terms such as “Cobrança” and “Cobrado” with the appropriate
“Baixa” forms while preserving each string’s grammatical context.
🪄 Autofix

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 Plus

Run ID: 1a6452de-591f-46fd-9810-1aba51b7f3aa

📥 Commits

Reviewing files that changed from the base of the PR and between 83396ff and 3770c43.

📒 Files selected for processing (21)
  • src/app/loans/common-resolvers/loan-action-button.resolver.ts
  • src/app/loans/loans-view/general-tab/general-tab.component.html
  • 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.html
  • src/app/loans/loans-view/loans-view.component.scss
  • src/app/loans/loans.service.ts
  • src/app/loans/models/working-capital/working-capital-loan-account.model.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 as they are similar to previous changes (8)
  • 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/loans-view.component.html
  • src/app/loans/loans-view/general-tab/general-tab.component.html
  • src/app/loans/loans-view/loans-view.component.scss
  • src/app/loans/models/working-capital/working-capital-loan-account.model.ts
  • src/app/loans/loans.service.ts

"External ID not found": "Externí ID nenalezeno",
"External ID verified successfully": "Externí ID úspěšně ověřeno",
"External Id": "Externí id",
"Reversal External Id": "Externí ID storna",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Remove the duplicate translation key.

inputs already defines Reversal External Id at Line [2868]. The duplicate at Line [2154] triggers Biome noDuplicateObjectKeys and can fail the lint check.

Proposed fix
-      "Reversal External Id": "Externí ID storna",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"Reversal External Id": "Externí ID storna",
🧰 Tools
🪛 Biome (2.5.6)

[error] 2154-2154: The key Reversal External Id was already declared.

(lint/suspicious/noDuplicateObjectKeys)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/assets/translations/cs-CS.json` at line 2154, Remove the duplicate
“Reversal External Id” entry from the translation object, keeping the existing
definition already present in inputs and preserving its translation value.

Source: Linters/SAST tools

"External ID not found": "Externe ID nicht gefunden",
"External ID verified successfully": "Externe ID erfolgreich verifiziert",
"External Id": "Externe ID",
"Reversal External Id": "Externe Storno-ID",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Remove the duplicate Reversal External Id key.

The inputs object declares this key at Line 2156 and again at Line 2870. Biome reports lint/suspicious/noDuplicateObjectKeys. Keep the declaration near Line 2156 and remove the duplicate at Line 2870.

Proposed fix
-      "Reversal External Id": "Externe Storno-ID",
       "Reversed": "Umgedreht",

Also applies to: 2870-2870

🧰 Tools
🪛 Biome (2.5.6)

[error] 2156-2156: The key Reversal External Id was already declared.

(lint/suspicious/noDuplicateObjectKeys)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/assets/translations/de-DE.json` at line 2156, Remove the duplicate
"Reversal External Id" entry from the later declaration in the inputs object,
while retaining the existing entry near the earlier translation declaration.

Source: Linters/SAST tools

"External ID not found": "External ID not found",
"External ID verified successfully": "External ID verified successfully",
"External Id": "External Id",
"Reversal External Id": "Reversal External Id",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Remove the duplicate Reversal External Id key.

The inputs object already defines this key at Line 2914. Keep one declaration, preferably the existing declaration, and remove the new declaration at Line 2182. Biome reports this duplicate key as an error.

Proposed fix
-      "Reversal External Id": "Reversal External Id",

Also applies to: 2914-2914

🧰 Tools
🪛 Biome (2.5.6)

[error] 2182-2182: The key Reversal External Id was already declared.

(lint/suspicious/noDuplicateObjectKeys)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/assets/translations/en-US.json` at line 2182, Remove the duplicate
“Reversal External Id” entry from the translation object near the shown
declaration, retaining the existing declaration in the inputs object and
preserving its value.

Source: Linters/SAST tools

"External ID not found": "Id externo no encontrado",
"External ID verified successfully": "Id externo verificado exitosamente",
"External Id": "Id externo",
"Reversal External Id": "Id externo de reversión",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Remove the duplicate Reversal External Id key.

The inputs object declares this key at Line 2154 and Line 2871. Biome reports Line 2154 as a duplicate. Keep one entry, preferably the existing entry at Line 2871. Duplicate keys can fail linting and produce last-key-wins behavior in JSON consumers.

Proposed fix
-      "Reversal External Id": "Id externo de reversión",

Also applies to: 2871-2871

🧰 Tools
🪛 Biome (2.5.6)

[error] 2154-2154: The key Reversal External Id was already declared.

(lint/suspicious/noDuplicateObjectKeys)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/assets/translations/es-CL.json` at line 2154, Remove the duplicate
“Reversal External Id” entry from the inputs object, keeping the existing entry
at the later location around line 2871 and preserving its translation value.

Source: Linters/SAST tools

"External ID not found": "Id externo no encontrado",
"External ID verified successfully": "Id externo verificado exitosamente",
"External Id": "Id externo",
"Reversal External Id": "Id externo de reversión",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Remove the duplicate Reversal External Id key.

The inputs object declares this key at Line 2161 and again at Line 2877. Biome reports lint/suspicious/noDuplicateObjectKeys. JSON parsers can silently retain only one duplicate value, and the lint gate can fail.

Keep the entry at Line 2161 and delete the duplicate at Line 2877.

Proposed fix
       "Results": "Resultados",
-      "Reversal External Id": "Id externo de reversión",
       "Reversed": "invertido",

Also applies to: 2877-2877

🧰 Tools
🪛 Biome (2.5.6)

[error] 2161-2161: The key Reversal External Id was already declared.

(lint/suspicious/noDuplicateObjectKeys)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/assets/translations/es-MX.json` at line 2161, Remove the duplicate
“Reversal External Id” entry from the inputs object, retaining the existing
entry near the earlier declaration and deleting only the later duplicate.

Source: Linters/SAST tools

"External ID not found": "Išorinis ID nerastas",
"External ID verified successfully": "Išorinis ID sėkmingai patvirtintas",
"External Id": "Išorinis ID",
"Reversal External Id": "Atšaukimo išorinis ID",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Remove the duplicate Reversal External Id key.

The inputs object declares this key at Line 2153 and Line 2867. The later JSON value overrides the earlier value, so one translation is unreachable. Biome also reports this duplicate key. Keep one declaration.

Also applies to: 2867-2867

🧰 Tools
🪛 Biome (2.5.6)

[error] 2153-2153: The key Reversal External Id was already declared.

(lint/suspicious/noDuplicateObjectKeys)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/assets/translations/lt-LT.json` at line 2153, Remove one duplicate
“Reversal External Id” entry from the translations JSON, keeping a single
declaration and its existing Lithuanian translation so the later value no longer
overrides the earlier one.

Source: Linters/SAST tools

"External ID not found": "Ārējais ID nav atrasts",
"External ID verified successfully": "Ārējais ID veiksmīgi verificēts",
"External Id": "Ārējais ID",
"Reversal External Id": "Storno ārējais ID",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Remove the duplicate Reversal External Id key.

The inputs object declares this key at Lines 2154 and 2868 with different values. The later value overwrites the earlier value during JSON parsing. Biome also reports noDuplicateObjectKeys. Keep one declaration.

Also applies to: 2868-2868

🧰 Tools
🪛 Biome (2.5.6)

[error] 2154-2154: The key Reversal External Id was already declared.

(lint/suspicious/noDuplicateObjectKeys)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/assets/translations/lv-LV.json` at line 2154, Remove one of the duplicate
“Reversal External Id” entries in the translations inputs object, retaining a
single declaration and its intended value so JSON parsing and Biome no longer
encounter duplicate keys.

Source: Linters/SAST tools

"External ID not found": "बाह्य आईडी फेला परेन",
"External ID verified successfully": "बाह्य आईडी सफलतापूर्वक प्रमाणित भयो",
"External Id": "बाह्य आईडी",
"Reversal External Id": "उल्टाउने बाह्य आईडी",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Remove the duplicate translation key before merge.

The inputs object declares "Reversal External Id" at Line 2153 and Line 2867. Biome reports this as lint/suspicious/noDuplicateObjectKeys. Keep the existing declaration at Line 2867 and remove the added declaration at Line 2153.

Proposed fix
-      "Reversal External Id": "उल्टाउने बाह्य आईडी",

Also applies to: 2867-2867

🧰 Tools
🪛 Biome (2.5.6)

[error] 2153-2153: The key Reversal External Id was already declared.

(lint/suspicious/noDuplicateObjectKeys)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/assets/translations/ne-NE.json` at line 2153, Remove the duplicate
"Reversal External Id" entry from the translation object at the earlier
declaration, keeping the existing declaration later in the object unchanged so
noDuplicateObjectKeys is satisfied.

Source: Linters/SAST tools

"External ID not found": "ID externo não encontrado",
"External ID verified successfully": "ID externo verificado com sucesso",
"External Id": "ID externo",
"Reversal External Id": "ID externo de estorno",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Remove the duplicate Reversal External Id key.

labels.inputs declares this key at Lines 2153 and 2867. Biome reports lint/suspicious/noDuplicateObjectKeys. Keep one declaration to avoid lint failure and parser-dependent key resolution.

Proposed fix
       "Retry": "Tentar novamente",
-      "Reversal External Id": "ID externo de estorno",
       "Reversed": "Invertido",

Also applies to: 2867-2867

🧰 Tools
🪛 Biome (2.5.6)

[error] 2153-2153: The key Reversal External Id was already declared.

(lint/suspicious/noDuplicateObjectKeys)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/assets/translations/pt-PT.json` at line 2153, Remove one of the duplicate
“Reversal External Id” entries from the labels.inputs translation object in
pt-PT.json, keeping exactly one declaration with the existing translation value.

Source: Linters/SAST tools

"External ID not found": "Kitambulisho cha Nje hakijapatikana",
"External ID verified successfully": "Kitambulisho cha Nje kimethibitishwa kwa mafanikio",
"External Id": "Kitambulisho cha Nje",
"Reversal External Id": "Kitambulisho cha nje cha ubatilishaji",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Remove the duplicate Reversal External Id key.

labels.inputs declares this key at Line 2151 and again at Line 2865. Biome reports lint/suspicious/noDuplicateObjectKeys. Keep one canonical entry and remove the duplicate to prevent silent value overriding.

🧰 Tools
🪛 Biome (2.5.6)

[error] 2151-2151: The key Reversal External Id was already declared.

(lint/suspicious/noDuplicateObjectKeys)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/assets/translations/sw-SW.json` at line 2151, Remove the duplicate
“Reversal External Id” entry from the labels.inputs translations, keeping one
canonical key and its existing value so the object contains no repeated key.

Source: Linters/SAST tools

@alberto-art3ch
alberto-art3ch force-pushed the WEB-657/working-capital-loan-write-off branch from 3770c43 to e002e94 Compare August 11, 2026 15:07
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.

1 participant