Skip to content

feat(loan): implement loan account actions screen#2660

Merged
revanthkumarJ merged 6 commits into
openMF:devfrom
Kartikey15dem:feature/loan-account-action
Jul 1, 2026
Merged

feat(loan): implement loan account actions screen#2660
revanthkumarJ merged 6 commits into
openMF:devfrom
Kartikey15dem:feature/loan-account-action

Conversation

@Kartikey15dem

@Kartikey15dem Kartikey15dem commented Apr 2, 2026

Copy link
Copy Markdown
Contributor

feat(feature/loan): loan account action screen

Fixes - Jira-#MIFOSAC-674

Description

This PR implements the UI for the new Loan Account Action screen.

UI

loanActions.webm

Key Changes

  • Built the Loan Account Action screen and mapped the the actions according to the loan status and flags.
  • Added the missing attributes in the LoanWithAssociationsEntity.
  • Also created a LoanActionPayments Screen to show paymemt actions but have not added any loading or error states as they are not required ibecause only hardcoded loan actions are being shown there without any network or db call.

Note : The permissions part mentioned in the ticket in not correctly implemented as it was asked to ignore it for now. Also the "More" actions are "Primary Actions" are combined in a single one and "Payments" are shown on another screen as it was discussed to follow this approach only.

Summary by CodeRabbit

  • New Features
    • Added a Loan Actions menu listing many loan operations (payments, charges, foreclosure, reschedule, officer/guarantor management, approvals, write‑offs, refunds, etc.).
    • New Payments Actions screen for goodwill credit, interest waiver, payment refund and merchant refund flows.
    • New icons and localized strings for all actions; header UI now links from loan profile to the actions screen.
  • UX
    • Action rows, navigation, and loading/error states improved for clearer workflow.

@Kartikey15dem Kartikey15dem requested review from a team and Copilot April 2, 2026 09:31
@coderabbitai

coderabbitai Bot commented Apr 2, 2026

Copy link
Copy Markdown

Important

Review skipped

Review was skipped due to path filters

⛔ Files ignored due to path filters (1)
  • .github/workflows/pr-check.yml is excluded by !.github/** and included by **/*

CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including **/dist/** will override the default block on the dist directory, by removing the pattern from both the lists.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 389b7ec6-1ac0-46a6-b567-3a0149065a8f

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ 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.

Copilot AI 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.

Pull request overview

Adds a new “Loan Account Actions” flow to the loan feature, wiring it into existing loan profile navigation and introducing supporting UI, view models, resources, and icons.

Changes:

  • Introduces loan action and payment-action screens (Compose UI + ViewModels) and integrates them into the loan navigation graph.
  • Adds a LoanAccountActionItem model plus action generation logic based on loan status/flags.
  • Extends loan model/entity fields and adds strings + a large set of new vector drawables for action icons.

Reviewed changes

Copilot reviewed 63 out of 63 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/navigation/LoanNavigation.kt Wires new loan actions/payment actions destinations into the loan navigation graph.
feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountProfile/LoanAccountProfileViewModel.kt Adds a new event/action to navigate from loan profile to the actions screen; minor refactors.
feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountProfile/LoanAccountProfileScreen.kt Adds an arrow-click pathway to open the actions screen from the top card.
feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountProfile/LoanAccountProfileNavigation.kt Threads navigateToLoanAction through the profile destination.
feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/payments/LoanActionPaymentsViewModel.kt Adds ViewModel/state/event/action for the payments action list.
feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/payments/LoanActionPaymentsScreen.kt Adds UI for listing payment-related loan actions.
feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/payments/LoanActionPaymentsNavigation.kt Adds navigation destination + NavController extension for payments actions screen.
feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/LoanAccountActionViewModel.kt Adds ViewModel that loads a loan and generates available actions based on status/flags.
feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/LoanAccountActionScreen.kt Adds UI for listing loan actions with loading/error/empty states.
feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/LoanAccountActionNavigation.kt Adds navigation destination and selection routing for loan actions.
feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/LoanAccountActionItem.kt Defines action items (title/subtitle/icon) used across action screens.
feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/di/LoanModule.kt Registers the new ViewModels with Koin.
feature/loan/src/commonMain/composeResources/values/strings.xml Adds strings for action headers, errors, and action item labels/subtitles.
core/ui/src/commonMain/composeResources/drawable/add_collateral.xml New vector icon for “add collateral”.
core/ui/src/commonMain/composeResources/drawable/add_interest_pause.xml New vector icon for “add interest pause”.
core/ui/src/commonMain/composeResources/drawable/add_loan_charge.xml New vector icon for “add loan charge”.
core/ui/src/commonMain/composeResources/drawable/approve.xml New vector icon for “approve”.
core/ui/src/commonMain/composeResources/drawable/assign_loan_officer.xml New vector icon for “assign loan officer”.
core/ui/src/commonMain/composeResources/drawable/buy_down_fee.xml New vector icon for “buy down fee”.
core/ui/src/commonMain/composeResources/drawable/cancel.xml New vector icon for “cancel”.
core/ui/src/commonMain/composeResources/drawable/capitalized_income.xml New vector icon for “capitalized income”.
core/ui/src/commonMain/composeResources/drawable/change_loan_officer.xml New vector icon for “change loan officer”.
core/ui/src/commonMain/composeResources/drawable/charge_off.xml New vector icon for “charge off”.
core/ui/src/commonMain/composeResources/drawable/close.xml New vector icon for “close”.
core/ui/src/commonMain/composeResources/drawable/close_as_rescheduled.xml New vector icon for “close as rescheduled”.
core/ui/src/commonMain/composeResources/drawable/contract_termination.xml New vector icon for “contract termination”.
core/ui/src/commonMain/composeResources/drawable/create_guarantors.xml New vector icon for “create guarantors”.
core/ui/src/commonMain/composeResources/drawable/credit_balance_refund.xml New vector icon for “credit balance refund”.
core/ui/src/commonMain/composeResources/drawable/delete.xml New vector icon for “delete”.
core/ui/src/commonMain/composeResources/drawable/disburse.xml New vector icon for “disburse”.
core/ui/src/commonMain/composeResources/drawable/disburse_to_savings.xml New vector icon for “disburse to savings”.
core/ui/src/commonMain/composeResources/drawable/edit_repayment_schedule.xml New vector icon for “edit repayment schedule”.
core/ui/src/commonMain/composeResources/drawable/foreclosure.xml New vector icon for “foreclosure”.
core/ui/src/commonMain/composeResources/drawable/goodwill_credit.xml New vector icon for “goodwill credit”.
core/ui/src/commonMain/composeResources/drawable/interest_payment_wavier.xml New vector icon for “interest payment waiver/wavier”.
core/ui/src/commonMain/composeResources/drawable/loan_screen_report.xml New vector icon for “loan screen report”.
core/ui/src/commonMain/composeResources/drawable/make_repayment.xml New vector icon for “make repayment”.
core/ui/src/commonMain/composeResources/drawable/merchant_issued_refund.xml New vector icon for “merchant issued refund”.
core/ui/src/commonMain/composeResources/drawable/modify_application.xml New vector icon for “modify application”.
core/ui/src/commonMain/composeResources/drawable/payment_refund.xml New vector icon for “payment refund”.
core/ui/src/commonMain/composeResources/drawable/payments.xml New vector icon for “payments”.
core/ui/src/commonMain/composeResources/drawable/prepay_loan.xml New vector icon for “prepay loan”.
core/ui/src/commonMain/composeResources/drawable/re_age.xml New vector icon for “re-age”.
core/ui/src/commonMain/composeResources/drawable/re_anortize.xml New vector icon for “re-amortize” (resource naming uses “anortize”).
core/ui/src/commonMain/composeResources/drawable/recover_from_guarantor.xml New vector icon for “recover from guarantor”.
core/ui/src/commonMain/composeResources/drawable/recovery_payment.xml New vector icon for “recovery payment”.
core/ui/src/commonMain/composeResources/drawable/reject.xml New vector icon for “reject”.
core/ui/src/commonMain/composeResources/drawable/request_quote.xml New vector icon for “request quote”.
core/ui/src/commonMain/composeResources/drawable/reschedule.xml New vector icon for “reschedule”.
core/ui/src/commonMain/composeResources/drawable/sell_loan.xml New vector icon for “sell loan”.
core/ui/src/commonMain/composeResources/drawable/transfer_funds.xml New vector icon for “transfer funds”.
core/ui/src/commonMain/composeResources/drawable/undo_approval.xml New vector icon for “undo approval”.
core/ui/src/commonMain/composeResources/drawable/undo_charge_off.xml New vector icon for “undo charge off”.
core/ui/src/commonMain/composeResources/drawable/undo_disbursal.xml New vector icon for “undo disbursal”.
core/ui/src/commonMain/composeResources/drawable/undo_re_age.xml New vector icon for “undo re-age”.
core/ui/src/commonMain/composeResources/drawable/undo_re_anortize.xml New vector icon for “undo re-amortize” (resource naming uses “anortize”).
core/ui/src/commonMain/composeResources/drawable/undo_write_off.xml New vector icon for “undo write off”.
core/ui/src/commonMain/composeResources/drawable/view_guarantors.xml New vector icon for “view guarantors”.
core/ui/src/commonMain/composeResources/drawable/waive_interest.xml New vector icon for “waive interest”.
core/ui/src/commonMain/composeResources/drawable/withdrawn_by_client.xml New vector icon for “withdrawn by client”.
core/ui/src/commonMain/composeResources/drawable/write_off.xml New vector icon for “write off”.
core/model/src/commonMain/kotlin/com/mifos/core/model/objects/account/loan/Type.kt Extends loan transaction “Type” to include additional boolean flags.
core/database/src/commonMain/kotlin/com/mifos/room/entities/accounts/loans/LoanWithAssociationsEntity.kt Extends persisted loan entity with additional feature/flag fields used by action generation.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread feature/loan/src/commonMain/composeResources/values/strings.xml
Comment thread feature/loan/src/commonMain/composeResources/values/strings.xml

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

🧹 Nitpick comments (9)
core/ui/src/commonMain/composeResources/drawable/cancel.xml (1)

16-18: Hardcoded fill color should be replaced with theme-aware approach.

The hardcoded android:fillColor="#999999" prevents proper theming and accessibility. Consider removing the fillColor attribute and applying tint at the usage site, or use a theme color reference.

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

In `@core/ui/src/commonMain/composeResources/drawable/cancel.xml` around lines 16
- 18, The path element in cancel.xml uses a hardcoded
android:fillColor="#999999"; remove that hardcoded fillColor (or replace it with
a theme attribute like ?attr/colorOnSurface or a color resource) so the drawable
can be tinted by the app theme or by usage; update the <path> element in
cancel.xml (the android:fillColor attribute) accordingly and ensure callers
apply tint (or use android:tint at the ImageView/Compose painter site) so the
icon respects theming and accessibility.
core/ui/src/commonMain/composeResources/drawable/payments.xml (1)

16-18: Hardcoded fill color should be replaced with theme-aware approach.

The hardcoded android:fillColor="#999999" prevents proper theming and accessibility. This issue is present across all 8 new drawable files in this PR. Consider refactoring to use runtime tinting or theme color references for all these icons.

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

In `@core/ui/src/commonMain/composeResources/drawable/payments.xml` around lines
16 - 18, The vector drawable hardcodes android:fillColor="#999999" in the <path>
element of payments.xml which breaks theming; replace the hardcoded value with a
theme attribute (e.g., android:fillColor="?attr/colorOnSurface" or another
appropriate color attr) or remove the fillColor and rely on runtime tinting (set
android:tint="?attr/colorOnSurface" on the VectorDrawable or apply
ImageView/AppCompatImageView tint via app:tint or setImageTintList at runtime).
Update the <path android:fillColor=...> usage across all eight new drawables to
use theme attributes or enable tinting so icons follow the app theme and
accessibility settings.
core/ui/src/commonMain/composeResources/drawable/edit_repayment_schedule.xml (1)

16-18: Hardcoded fill color should be replaced with theme-aware approach.

Same issue as in delete.xml: the hardcoded android:fillColor="#999999" should be replaced with either runtime tinting or theme color references for proper theming and accessibility support.

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

In `@core/ui/src/commonMain/composeResources/drawable/edit_repayment_schedule.xml`
around lines 16 - 18, The path element currently hardcodes
android:fillColor="#999999"; replace that hardcoded color with a theme-aware
color reference or tinting so the drawable follows app theming—e.g., set
android:fillColor="?attr/colorOnSurface" (or another appropriate theme
attribute) on the <path> or remove fillColor and apply a runtime tint (via
setTintList/app:srcCompat and android:tint) when the drawable is loaded; update
the <path> element that contains android:fillColor and ensure callers load the
drawable with tint support if you choose runtime tinting.
core/ui/src/commonMain/composeResources/drawable/undo_disbursal.xml (1)

16-18: Hardcoded fill color should be replaced with theme-aware approach.

The hardcoded android:fillColor="#999999" prevents proper theming. Consider removing the fillColor and applying tint at the usage site, or use a theme color reference.

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

In `@core/ui/src/commonMain/composeResources/drawable/undo_disbursal.xml` around
lines 16 - 18, Replace the hardcoded fill color on the VectorDrawable path by
removing the android:fillColor="#999999" and making the drawable theme-aware;
either remove the fillColor entirely so consumers can apply a tint at the usage
site, or replace it with a theme attribute reference (e.g.
?attr/colorControlNormal or ?attr/colorOnSurface) so the color follows the app
theme—update the path element that contains
android:pathData="M280,760v-80h284q63,0 109.5,-40T720,540q0,-60
-46.5,-100T564,400L312,400l104,104 -56,56 -200,-200 200,-200 56,56
-104,104h252q97,0 166.5,63T800,540q0,94 -69.5,157T564,760L280,760Z" accordingly.
core/ui/src/commonMain/composeResources/drawable/buy_down_fee.xml (1)

16-18: Hardcoded fill color should be replaced with theme-aware approach.

The hardcoded android:fillColor="#999999" should be replaced with runtime tinting or theme color references for consistency with modern theming practices.

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

In `@core/ui/src/commonMain/composeResources/drawable/buy_down_fee.xml` around
lines 16 - 18, Replace the hardcoded fill color in buy_down_fee.xml (the path
element with android:fillColor="#999999") with a theme-aware value and enable
runtime tinting; for example set android:fillColor to a theme attribute
reference (e.g. "?attr/colorOnSurface" or a custom attr like
"?attr/myIconColor") or point it to a color resource that in turn references
theme attributes, and ensure consumers can tint the drawable at runtime (via
android:tint or app:tint on the ImageView or by using DrawableCompat) so the
vector responds to light/dark and app theme changes.
core/ui/src/commonMain/composeResources/drawable/change_loan_officer.xml (1)

16-18: Hardcoded fill color should be replaced with theme-aware approach.

The hardcoded android:fillColor="#999999" should be replaced with runtime tinting or theme color references for consistency with theming best practices.

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

In `@core/ui/src/commonMain/composeResources/drawable/change_loan_officer.xml`
around lines 16 - 18, Replace the hardcoded color in the path element
(android:fillColor="#999999") with a theme-aware attribute and/or enable runtime
tinting: change android:fillColor to a theme attribute (for example
android:fillColor="?attr/colorOnSurface" or "?attr/colorControlNormal") and, if
you rely on view-level tinting, remove the fillColor and ensure the
ImageView/Compose Image uses android:tint or setTint with the theme color at
runtime; update the path element in change_loan_officer.xml accordingly so the
drawable respects app theming.
core/ui/src/commonMain/composeResources/drawable/request_quote.xml (1)

16-18: Hardcoded fill color should be replaced with theme-aware approach.

The hardcoded android:fillColor="#999999" should be replaced with runtime tinting or theme color references for proper theming and accessibility support.

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

In `@core/ui/src/commonMain/composeResources/drawable/request_quote.xml` around
lines 16 - 18, Replace the hardcoded fill color in the vector <path>
(android:fillColor="#999999") with a theme-aware value and/or enable runtime
tinting: change the fillColor to a theme attribute (e.g.,
android:fillColor="?attr/colorOnSurface" or another appropriate attr) or remove
the fillColor and rely on vector tint via android:tint so the drawable
(request_quote.xml) follows the app theme; if you need runtime control, ensure
the code that sets this drawable applies ImageView.setImageTintList or
AppCompatResources.getDrawable + DrawableCompat.setTintList to provide the
correct themed color.
core/ui/src/commonMain/composeResources/drawable/delete.xml (1)

16-18: Consider using theme-aware colors or applying tint at usage site instead of hardcoded fill color.

The android:fillColor="#999999" attribute uses a hardcoded gray color. While the codebase currently follows a pattern of hardcoding fill colors in drawables (e.g., #000000, #191C20, #ffffff), modern Compose Multiplatform apps benefit from:

  1. Omitting the fillColor attribute and applying tint at the usage site (preferred for dynamic theming), or
  2. Referencing theme color resources or attributes (e.g., ?attr/colorControlNormal)

Hardcoded colors reduce flexibility for light/dark mode support and complicate maintaining consistent color palettes. Consider refactoring existing drawables following this pattern as a future improvement.

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

In `@core/ui/src/commonMain/composeResources/drawable/delete.xml` around lines 16
- 18, The drawable uses a hardcoded fill color on the <path> element
(android:fillColor="#999999"); remove the hardcoded fillColor or replace it with
a theme-aware reference so the icon can be tinted at the usage site (e.g., omit
android:fillColor entirely or use a color attribute/reference like
?attr/colorControlNormal) and ensure consumers apply tint in Compose/Views
instead of relying on the bitmap color; update the <path> in delete.xml
accordingly and confirm usages apply tint or reference the desired theme color.
feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/payments/LoanActionPaymentsNavigation.kt (1)

40-41: Rename navigateToLaonPaymentsActionScreen before more call sites depend on it.

The typo is part of a new exported helper and has already propagated into LoanNavigation.kt. Renaming it to navigateToLoanPaymentsActionScreen now is much cheaper than carrying the misspelling forward.

♻️ Suggested rename
-fun NavController.navigateToLaonPaymentsActionScreen() {
+fun NavController.navigateToLoanPaymentsActionScreen() {
     this.navigate(LoanPaymentsActionRoute)
 }

Also update the import/method reference in feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/navigation/LoanNavigation.kt.

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

In
`@feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/payments/LoanActionPaymentsNavigation.kt`
around lines 40 - 41, Rename the exported helper function
navigateToLaonPaymentsActionScreen to navigateToLoanPaymentsActionScreen (fixing
the "Laon" typo) and update all call sites and imports that reference the old
name—specifically change the declaration in the function currently named
navigateToLaonPaymentsActionScreen and update its usage/import in
LoanNavigation.kt to the new navigateToLoanPaymentsActionScreen identifier so
callers compile and use the corrected name.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@core/database/src/commonMain/kotlin/com/mifos/room/entities/accounts/loans/LoanWithAssociationsEntity.kt`:
- Around line 188-204: The Room schema change added nine Boolean fields to
LoanWithAssociationsEntity (isEqualAmortization,
allowPartialPeriodInterestCalculation, interestRecognitionOnDisbursementDate,
enableDownPayment, enableIncomeCapitalization, enableBuyDownFee,
enableInstallmentLevelDelinquency, isInterestRecalculationEnabled, chargedOff)
which requires bumping the DB version and adding a migration; update the VERSION
constant in MifosDatabase (platform-specific copies) from 1 to 2 and then
provide either an `@AutoMigration` entry or a manual Room Migration object that
migrates schema 1→2 (ensuring new columns exist with default false), and
register that migration/auto-migration in the RoomDatabase builder used by
MifosDatabase so existing databases open without schema mismatch.

In `@core/ui/src/commonMain/composeResources/drawable/credit_balance_refund.xml`:
- Around line 1-19: The CreditBalanceRefund action is exposed in the UI
(drawable credit_balance_refund.xml) but the navigation mapping for
LoanAccountActionItem.CreditBalanceRefund in LoanAccountActionNavigation.kt
currently uses TODO(), which will crash at runtime; either implement the
navigation handler by replacing the TODO() with a concrete call (e.g., call a
new or existing navigateToCreditBalanceRefund(...) function or dispatch the
CreditBalanceRefund action) and wire up any required params/route, or prevent
the action from being visible/clickable by adding a guard (e.g., a
isImplemented/isEnabled check or feature flag) where the UI enumerates
LoanAccountActionItem so the icon is hidden/disabled until the handler exists.
Ensure you update the when branch for LoanAccountActionItem.CreditBalanceRefund
and any related tests.

In `@core/ui/src/commonMain/composeResources/drawable/undo_re_anortize.xml`:
- Line 1: Rename the drawable file from undo_re_anortize.xml to
undo_re_amortize.xml and update any references to it (e.g., in the
LoanAccountActionItem usage that currently refers to undo_re_anortize) so they
match the action class name UndoReAmortize and the string resource
feature_loan_action_undo_re_amortize; ensure resource names and references are
identical (undo_re_amortize) to restore consistency across the Drawable, the
action class, and string resources.

In `@feature/loan/src/commonMain/composeResources/values/strings.xml`:
- Around line 514-515: The user-visible typo is in the string value for
feature_loan_action_interest_payment_wavier (currently "Interest Payment
Wavier"); change the displayed text to "Interest Payment Waiver" (replace
"Wavier" with "Waiver") and scan for any other user-facing strings containing
"Wavier" (e.g., check feature_loan_interest_payment_wavier_sub) and correct
their displayed values as needed; keep the existing resource names unchanged to
avoid breaking references unless you intentionally want to rename keys
throughout the codebase.

In
`@feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/LoanAccountActionNavigation.kt`:
- Around line 32-79: The onActionSelected lambda in LoanAccountActionNavigation
currently leaves almost every LoanAccountActionItem branch as TODO(), which
throws NotImplementedError and crashes when ViewModel
(LoanAccountActionViewModel) emits those actions; replace each TODO() in the
when branches inside onActionSelected with real handlers: either call the
existing navigation functions (e.g., keep Payments ->
navigateToPaymentsActionScreen()), implement specific navigation helpers for
actions that should navigate (create functions like navigateToAddCollateral(),
navigateToDisburse(), etc.), or call a safe fallback such as
showUnsupportedAction(loanAccountActionItem, loanId) / logAndNoop to gracefully
handle unimplemented actions so no branch throws; ensure each unique enum case
in LoanAccountActionItem is handled explicitly rather than left as TODO().

In
`@feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/LoanAccountActionScreen.kt`:
- Around line 97-109: The Text in LoanAccountActionScreen's empty-state branch
currently uses the hardcoded English string "No actions available"; replace it
with the localized resource (feature_loan_action_empty) by calling
stringResource(...) (ensure androidx.compose.ui.res.stringResource is imported)
inside the Text for the state.actions.isEmpty branch so the empty state uses the
feature_loan_action_empty string resource and is translatable.

In
`@feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/LoanAccountActionViewModel.kt`:
- Around line 229-233: In the LoanStatus.APPROVED branch of generate actions
(where generatedActions is populated), replace the incorrect
LoanAccountActionItem.UndoDisbursal with LoanAccountActionItem.UndoApproval so
approved (pre-disbursement) loans expose the UndoApproval action; ensure the
branch still adds Disburse, DisburseToSavings and AddLoanCharge and remove or
stop adding UndoDisbursal from this branch to surface the existing UndoApproval
item instead.
- Around line 123-135: The canAssignLoanOfficer flag is inverted:
LoanAccountActionViewModel currently sets canAssignLoanOfficer =
loan.loanOfficerName.isNotBlank(), but generateActions() interprets true as
"show Assign Loan Officer"; change the assignment to reflect absence of an
officer (e.g., set canAssignLoanOfficer to loan.loanOfficerName.isBlank() or
!loan.loanOfficerName.isNotBlank()) so the Assign Loan Officer action only
appears when no officer is assigned.

In
`@feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/payments/LoanActionPaymentsViewModel.kt`:
- Around line 21-31: The init in LoanActionPaymentsViewModel currently sets a
fixed actions list (via mutableStateFlow.update) exposing GoodwillCredit,
InterestPaymentWavier, PaymentRefund, MerchantIssuedRefund without loan context;
instead, derive the available actions from the loan's status (mirror the logic
in LoanAccountActionViewModel) — e.g., only populate those four actions when the
loan's status equals LoanStatus.CLOSED_OBLIGATIONS_MET, otherwise leave actions
empty or compute per-status; locate the init block in
LoanActionPaymentsViewModel and replace the unconditional actions assignment
with a status-aware assignment that reads the loan/status input used elsewhere
(or accept a loan parameter) so active loans do not see refund/goodwill options.

In
`@feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountProfile/LoanAccountProfileScreen.kt`:
- Around line 282-286: The chevron Icon (MifosIcons.ChevronRight) currently uses
contentDescription = null but is interactive via Modifier.clickable {
onArrowClick() }, so update the control to be accessible by either wrapping it
in an IconButton or supplying a localized contentDescription string resource and
passing it to the Icon (replace contentDescription = null with
contentDescription = stringResource(R.string.loan_actions_chevron) or similar);
ensure the string resource key (e.g., R.string.loan_actions_chevron / "Open loan
actions") is added to resources and that onArrowClick remains the click handler
so screen readers announce the action before activation.

In
`@feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountProfile/LoanAccountProfileViewModel.kt`:
- Around line 140-142: In LoanAccountProfileViewModel locate the
mutableStateFlow.update call that sets dialogState =
Error(Res.string.feature_loan_profile_error_details_not_found) (the offline
retry path in the OnRetry handler) and change the resource to
Res.string.feature_loan_profile_error_network_not_available so the dialog shows
the network-unavailable message for connectivity failures; keep the update call
and Error wrapper unchanged, only replace the string resource identifier.

In
`@feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/navigation/LoanNavigation.kt`:
- Around line 111-118: The payments actions route is registered with empty
lambdas so LoanActionPaymentsScreen will silently no-op when users pick an
action; update the call to loanPaymentsActionDestination to pass real navigation
handlers (or disable/hide the route) instead of `{}`: replace the empty lambdas
for onGoodwillCreditClick, onInterestPaymentWaiverClick, onPaymentRefundClick
and onMerchantIssuedRefundClick with functions that call
navController.navigate(...) to the appropriate destinations (or conditionally
omit/register the route until those flows exist), referencing
loanPaymentsActionDestination, navController and the LoanActionPaymentsScreen
callbacks to locate the change.

---

Nitpick comments:
In `@core/ui/src/commonMain/composeResources/drawable/buy_down_fee.xml`:
- Around line 16-18: Replace the hardcoded fill color in buy_down_fee.xml (the
path element with android:fillColor="#999999") with a theme-aware value and
enable runtime tinting; for example set android:fillColor to a theme attribute
reference (e.g. "?attr/colorOnSurface" or a custom attr like
"?attr/myIconColor") or point it to a color resource that in turn references
theme attributes, and ensure consumers can tint the drawable at runtime (via
android:tint or app:tint on the ImageView or by using DrawableCompat) so the
vector responds to light/dark and app theme changes.

In `@core/ui/src/commonMain/composeResources/drawable/cancel.xml`:
- Around line 16-18: The path element in cancel.xml uses a hardcoded
android:fillColor="#999999"; remove that hardcoded fillColor (or replace it with
a theme attribute like ?attr/colorOnSurface or a color resource) so the drawable
can be tinted by the app theme or by usage; update the <path> element in
cancel.xml (the android:fillColor attribute) accordingly and ensure callers
apply tint (or use android:tint at the ImageView/Compose painter site) so the
icon respects theming and accessibility.

In `@core/ui/src/commonMain/composeResources/drawable/change_loan_officer.xml`:
- Around line 16-18: Replace the hardcoded color in the path element
(android:fillColor="#999999") with a theme-aware attribute and/or enable runtime
tinting: change android:fillColor to a theme attribute (for example
android:fillColor="?attr/colorOnSurface" or "?attr/colorControlNormal") and, if
you rely on view-level tinting, remove the fillColor and ensure the
ImageView/Compose Image uses android:tint or setTint with the theme color at
runtime; update the path element in change_loan_officer.xml accordingly so the
drawable respects app theming.

In `@core/ui/src/commonMain/composeResources/drawable/delete.xml`:
- Around line 16-18: The drawable uses a hardcoded fill color on the <path>
element (android:fillColor="#999999"); remove the hardcoded fillColor or replace
it with a theme-aware reference so the icon can be tinted at the usage site
(e.g., omit android:fillColor entirely or use a color attribute/reference like
?attr/colorControlNormal) and ensure consumers apply tint in Compose/Views
instead of relying on the bitmap color; update the <path> in delete.xml
accordingly and confirm usages apply tint or reference the desired theme color.

In
`@core/ui/src/commonMain/composeResources/drawable/edit_repayment_schedule.xml`:
- Around line 16-18: The path element currently hardcodes
android:fillColor="#999999"; replace that hardcoded color with a theme-aware
color reference or tinting so the drawable follows app theming—e.g., set
android:fillColor="?attr/colorOnSurface" (or another appropriate theme
attribute) on the <path> or remove fillColor and apply a runtime tint (via
setTintList/app:srcCompat and android:tint) when the drawable is loaded; update
the <path> element that contains android:fillColor and ensure callers load the
drawable with tint support if you choose runtime tinting.

In `@core/ui/src/commonMain/composeResources/drawable/payments.xml`:
- Around line 16-18: The vector drawable hardcodes android:fillColor="#999999"
in the <path> element of payments.xml which breaks theming; replace the
hardcoded value with a theme attribute (e.g.,
android:fillColor="?attr/colorOnSurface" or another appropriate color attr) or
remove the fillColor and rely on runtime tinting (set
android:tint="?attr/colorOnSurface" on the VectorDrawable or apply
ImageView/AppCompatImageView tint via app:tint or setImageTintList at runtime).
Update the <path android:fillColor=...> usage across all eight new drawables to
use theme attributes or enable tinting so icons follow the app theme and
accessibility settings.

In `@core/ui/src/commonMain/composeResources/drawable/request_quote.xml`:
- Around line 16-18: Replace the hardcoded fill color in the vector <path>
(android:fillColor="#999999") with a theme-aware value and/or enable runtime
tinting: change the fillColor to a theme attribute (e.g.,
android:fillColor="?attr/colorOnSurface" or another appropriate attr) or remove
the fillColor and rely on vector tint via android:tint so the drawable
(request_quote.xml) follows the app theme; if you need runtime control, ensure
the code that sets this drawable applies ImageView.setImageTintList or
AppCompatResources.getDrawable + DrawableCompat.setTintList to provide the
correct themed color.

In `@core/ui/src/commonMain/composeResources/drawable/undo_disbursal.xml`:
- Around line 16-18: Replace the hardcoded fill color on the VectorDrawable path
by removing the android:fillColor="#999999" and making the drawable theme-aware;
either remove the fillColor entirely so consumers can apply a tint at the usage
site, or replace it with a theme attribute reference (e.g.
?attr/colorControlNormal or ?attr/colorOnSurface) so the color follows the app
theme—update the path element that contains
android:pathData="M280,760v-80h284q63,0 109.5,-40T720,540q0,-60
-46.5,-100T564,400L312,400l104,104 -56,56 -200,-200 200,-200 56,56
-104,104h252q97,0 166.5,63T800,540q0,94 -69.5,157T564,760L280,760Z" accordingly.

In
`@feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/payments/LoanActionPaymentsNavigation.kt`:
- Around line 40-41: Rename the exported helper function
navigateToLaonPaymentsActionScreen to navigateToLoanPaymentsActionScreen (fixing
the "Laon" typo) and update all call sites and imports that reference the old
name—specifically change the declaration in the function currently named
navigateToLaonPaymentsActionScreen and update its usage/import in
LoanNavigation.kt to the new navigateToLoanPaymentsActionScreen identifier so
callers compile and use the corrected name.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 09baacc3-9414-4d88-ba97-590999ca85ad

📥 Commits

Reviewing files that changed from the base of the PR and between 8c7d2bf and d77f9e4.

📒 Files selected for processing (63)
  • core/database/src/commonMain/kotlin/com/mifos/room/entities/accounts/loans/LoanWithAssociationsEntity.kt
  • core/model/src/commonMain/kotlin/com/mifos/core/model/objects/account/loan/Type.kt
  • core/ui/src/commonMain/composeResources/drawable/add_collateral.xml
  • core/ui/src/commonMain/composeResources/drawable/add_interest_pause.xml
  • core/ui/src/commonMain/composeResources/drawable/add_loan_charge.xml
  • core/ui/src/commonMain/composeResources/drawable/approve.xml
  • core/ui/src/commonMain/composeResources/drawable/assign_loan_officer.xml
  • core/ui/src/commonMain/composeResources/drawable/buy_down_fee.xml
  • core/ui/src/commonMain/composeResources/drawable/cancel.xml
  • core/ui/src/commonMain/composeResources/drawable/capitalized_income.xml
  • core/ui/src/commonMain/composeResources/drawable/change_loan_officer.xml
  • core/ui/src/commonMain/composeResources/drawable/charge_off.xml
  • core/ui/src/commonMain/composeResources/drawable/close.xml
  • core/ui/src/commonMain/composeResources/drawable/close_as_rescheduled.xml
  • core/ui/src/commonMain/composeResources/drawable/contract_termination.xml
  • core/ui/src/commonMain/composeResources/drawable/create_guarantors.xml
  • core/ui/src/commonMain/composeResources/drawable/credit_balance_refund.xml
  • core/ui/src/commonMain/composeResources/drawable/delete.xml
  • core/ui/src/commonMain/composeResources/drawable/disburse.xml
  • core/ui/src/commonMain/composeResources/drawable/disburse_to_savings.xml
  • core/ui/src/commonMain/composeResources/drawable/edit_repayment_schedule.xml
  • core/ui/src/commonMain/composeResources/drawable/foreclosure.xml
  • core/ui/src/commonMain/composeResources/drawable/goodwill_credit.xml
  • core/ui/src/commonMain/composeResources/drawable/interest_payment_wavier.xml
  • core/ui/src/commonMain/composeResources/drawable/loan_screen_report.xml
  • core/ui/src/commonMain/composeResources/drawable/make_repayment.xml
  • core/ui/src/commonMain/composeResources/drawable/merchant_issued_refund.xml
  • core/ui/src/commonMain/composeResources/drawable/modify_application.xml
  • core/ui/src/commonMain/composeResources/drawable/payment_refund.xml
  • core/ui/src/commonMain/composeResources/drawable/payments.xml
  • core/ui/src/commonMain/composeResources/drawable/prepay_loan.xml
  • core/ui/src/commonMain/composeResources/drawable/re_age.xml
  • core/ui/src/commonMain/composeResources/drawable/re_anortize.xml
  • core/ui/src/commonMain/composeResources/drawable/recover_from_guarantor.xml
  • core/ui/src/commonMain/composeResources/drawable/recovery_payment.xml
  • core/ui/src/commonMain/composeResources/drawable/reject.xml
  • core/ui/src/commonMain/composeResources/drawable/request_quote.xml
  • core/ui/src/commonMain/composeResources/drawable/reschedule.xml
  • core/ui/src/commonMain/composeResources/drawable/sell_loan.xml
  • core/ui/src/commonMain/composeResources/drawable/transfer_funds.xml
  • core/ui/src/commonMain/composeResources/drawable/undo_approval.xml
  • core/ui/src/commonMain/composeResources/drawable/undo_charge_off.xml
  • core/ui/src/commonMain/composeResources/drawable/undo_disbursal.xml
  • core/ui/src/commonMain/composeResources/drawable/undo_re_age.xml
  • core/ui/src/commonMain/composeResources/drawable/undo_re_anortize.xml
  • core/ui/src/commonMain/composeResources/drawable/undo_write_off.xml
  • core/ui/src/commonMain/composeResources/drawable/view_guarantors.xml
  • core/ui/src/commonMain/composeResources/drawable/waive_interest.xml
  • core/ui/src/commonMain/composeResources/drawable/withdrawn_by_client.xml
  • core/ui/src/commonMain/composeResources/drawable/write_off.xml
  • feature/loan/src/commonMain/composeResources/values/strings.xml
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/di/LoanModule.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/LoanAccountActionItem.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/LoanAccountActionNavigation.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/LoanAccountActionScreen.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/LoanAccountActionViewModel.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/payments/LoanActionPaymentsNavigation.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/payments/LoanActionPaymentsScreen.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/payments/LoanActionPaymentsViewModel.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountProfile/LoanAccountProfileNavigation.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountProfile/LoanAccountProfileScreen.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountProfile/LoanAccountProfileViewModel.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/navigation/LoanNavigation.kt

Comment thread feature/loan/src/commonMain/composeResources/values/strings.xml Outdated
@Kartikey15dem Kartikey15dem force-pushed the feature/loan-account-action branch from d77f9e4 to 82bfe53 Compare April 2, 2026 12:55
@sonarqubecloud

sonarqubecloud Bot commented Apr 2, 2026

Copy link
Copy Markdown

@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 (4)
feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountProfile/LoanAccountProfileScreen.kt (1)

283-288: Accessibility improved but touch target may be small.

The contentDescription is now properly set with a localized string, which addresses the previous accessibility concern. However, using Modifier.clickable directly on an Icon may result in a touch target smaller than the recommended 48dp minimum. Consider wrapping in IconButton for better accessibility.

♻️ Wrap in IconButton for proper touch target
-                Icon(
-                    imageVector = MifosIcons.ChevronRight,
-                    contentDescription = stringResource(Res.string.feature_loan_profile_open_actions),
-                    modifier = Modifier.size(DesignToken.sizes.iconSmall)
-                        .clickable { onArrowClick() },
-                    tint = KptTheme.colorScheme.onPrimary.copy(alpha = 0.6f),
-                )
+                IconButton(onClick = onArrowClick) {
+                    Icon(
+                        imageVector = MifosIcons.ChevronRight,
+                        contentDescription = stringResource(Res.string.feature_loan_profile_open_actions),
+                        modifier = Modifier.size(DesignToken.sizes.iconSmall),
+                        tint = KptTheme.colorScheme.onPrimary.copy(alpha = 0.6f),
+                    )
+                }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountProfile/LoanAccountProfileScreen.kt`
around lines 283 - 288, The Icon currently uses Modifier.clickable which can
yield a touch target smaller than 48dp; replace the clickable Icon pattern by
wrapping the Icon in an IconButton (or use IconButton with onClick = {
onArrowClick() }) so the touch target meets accessibility guidelines, preserve
the contentDescription (stringResource(...)), keep the Icon imageVector
MifosIcons.ChevronRight and tint, and move any size modifiers appropriately (use
IconButton’s default sizing or ensure the visible icon size remains
DesignToken.sizes.iconSmall while the clickable area is at least 48dp).
feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/LoanAccountActionNavigation.kt (1)

32-80: Most action handlers are no-ops.

Only Payments has actual navigation (Line 60); all other 37 LoanAccountActionItem variants silently do nothing when tapped. While this won't crash (unlike the TODO() previously flagged), users will see no response for most actions.

Per the PR description, this is intentional scaffolding. Consider adding a TODO comment or opening an issue to track implementing the remaining action handlers.

Do you want me to open an issue to track implementing handlers for the remaining loan actions?

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

In
`@feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/LoanAccountActionNavigation.kt`
around lines 32 - 80, The when-handling in onActionSelected inside
LoanAccountActionNavigation.kt leaves 37 LoanAccountActionItem branches as
silent no-ops (only Payments calls navigateToPaymentsActionScreen); update each
empty branch to either (a) add a TODO comment referencing the specific
LoanAccountActionItem variant and a ticket/issue ID for future implementation,
or (b) call a single placeholder handler (e.g., navigateToNotImplemented or
showNotImplementedSnackbar) passing the LoanAccountActionItem and loanId so
users get feedback, and ensure Payments branch remains unchanged; place the
TODOs/placeholder calls in the onActionSelected lambda to make missing
implementations discoverable.
feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/LoanAccountActionScreen.kt (1)

133-148: Loading state logic has redundancy.

The condition state.dialogState == null && !state.isLoading (Line 84) and the fallback if (state.isLoading) MifosProgressIndicator() (Line 145) create overlapping logic. If dialogState is set to Loading, the loading indicator shows via Line 136. If isLoading is true but dialogState is null, Line 145 handles it. This works but could be simplified.

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

In
`@feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/LoanAccountActionScreen.kt`
around lines 133 - 148, Reduce redundant loading checks by consolidating the
loading logic: in the UI branch that inspects state.dialogState, treat loading
as a single condition by showing MifosProgressIndicator when either
state.dialogState is LoanAccountActionsState.DialogState.Loading OR
state.isLoading is true, otherwise handle Error and null cases; update the
when/if block that references state.dialogState, state.isLoading,
LoanAccountActionsState.DialogState.Loading,
LoanAccountActionsState.DialogState.Error and MifosProgressIndicator so there is
no separate fallback if (state.isLoading) — combine them into one explicit
branch.
feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/LoanAccountActionViewModel.kt (1)

334-344: Prefer boolean status flags over string matching for status determination.

toLoanStatus() relies on exact English string matches from the backend (e.g., "Submitted and pending approval"), which is fragile to backend changes. The codebase already uses LoanStatusEntity's boolean flags (pendingApproval, waitingForDisbursal, active, closedObligationsMet, closedWrittenOff, overpaid) throughout—LoanAccountProfileViewModel, LoanAccountSummaryViewModel, and UI screens all use this pattern. Refactor to use the same boolean flags instead of string matching for consistency and robustness.

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

In
`@feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/LoanAccountActionViewModel.kt`
around lines 334 - 344, The current String?.toLoanStatus() function is fragile;
replace string-based mapping with a boolean-flag based mapping using
LoanStatusEntity flags: add a new mapping function (e.g.,
LoanStatusEntity.toLoanStatus()) that checks pendingApproval,
waitingForDisbursal, active, closedObligationsMet, closedWrittenOff, overpaid in
that logical order and returns the corresponding LoanStatus (falling back to
UNKNOWN), update callers (LoanAccountProfileViewModel,
LoanAccountSummaryViewModel and UI screens) to use the new
LoanStatusEntity.toLoanStatus() (or pass LoanStatusEntity into view models)
instead of passing/using raw status strings, and remove or deprecate
String?.toLoanStatus() to ensure consistent, robust status determination.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/LoanAccountActionViewModel.kt`:
- Line 14: The import references a typo'd string resource name
feature_loan_action_failed_to_load_loam_actions; rename the resource to
feature_loan_action_failed_to_load_loan_actions in the resource file and update
this import to use the corrected identifier, then update any other usages (e.g.,
in LoanAccountActionViewModel or related callers) to the new name so all
references match.

---

Nitpick comments:
In
`@feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/LoanAccountActionNavigation.kt`:
- Around line 32-80: The when-handling in onActionSelected inside
LoanAccountActionNavigation.kt leaves 37 LoanAccountActionItem branches as
silent no-ops (only Payments calls navigateToPaymentsActionScreen); update each
empty branch to either (a) add a TODO comment referencing the specific
LoanAccountActionItem variant and a ticket/issue ID for future implementation,
or (b) call a single placeholder handler (e.g., navigateToNotImplemented or
showNotImplementedSnackbar) passing the LoanAccountActionItem and loanId so
users get feedback, and ensure Payments branch remains unchanged; place the
TODOs/placeholder calls in the onActionSelected lambda to make missing
implementations discoverable.

In
`@feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/LoanAccountActionScreen.kt`:
- Around line 133-148: Reduce redundant loading checks by consolidating the
loading logic: in the UI branch that inspects state.dialogState, treat loading
as a single condition by showing MifosProgressIndicator when either
state.dialogState is LoanAccountActionsState.DialogState.Loading OR
state.isLoading is true, otherwise handle Error and null cases; update the
when/if block that references state.dialogState, state.isLoading,
LoanAccountActionsState.DialogState.Loading,
LoanAccountActionsState.DialogState.Error and MifosProgressIndicator so there is
no separate fallback if (state.isLoading) — combine them into one explicit
branch.

In
`@feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/LoanAccountActionViewModel.kt`:
- Around line 334-344: The current String?.toLoanStatus() function is fragile;
replace string-based mapping with a boolean-flag based mapping using
LoanStatusEntity flags: add a new mapping function (e.g.,
LoanStatusEntity.toLoanStatus()) that checks pendingApproval,
waitingForDisbursal, active, closedObligationsMet, closedWrittenOff, overpaid in
that logical order and returns the corresponding LoanStatus (falling back to
UNKNOWN), update callers (LoanAccountProfileViewModel,
LoanAccountSummaryViewModel and UI screens) to use the new
LoanStatusEntity.toLoanStatus() (or pass LoanStatusEntity into view models)
instead of passing/using raw status strings, and remove or deprecate
String?.toLoanStatus() to ensure consistent, robust status determination.

In
`@feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountProfile/LoanAccountProfileScreen.kt`:
- Around line 283-288: The Icon currently uses Modifier.clickable which can
yield a touch target smaller than 48dp; replace the clickable Icon pattern by
wrapping the Icon in an IconButton (or use IconButton with onClick = {
onArrowClick() }) so the touch target meets accessibility guidelines, preserve
the contentDescription (stringResource(...)), keep the Icon imageVector
MifosIcons.ChevronRight and tint, and move any size modifiers appropriately (use
IconButton’s default sizing or ensure the visible icon size remains
DesignToken.sizes.iconSmall while the clickable area is at least 48dp).
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 07ae77b1-4ee8-4de6-9931-e6e4f3550ada

📥 Commits

Reviewing files that changed from the base of the PR and between d77f9e4 and 82bfe53.

📒 Files selected for processing (63)
  • core/database/src/commonMain/kotlin/com/mifos/room/entities/accounts/loans/LoanWithAssociationsEntity.kt
  • core/model/src/commonMain/kotlin/com/mifos/core/model/objects/account/loan/Type.kt
  • core/ui/src/commonMain/composeResources/drawable/add_collateral.xml
  • core/ui/src/commonMain/composeResources/drawable/add_interest_pause.xml
  • core/ui/src/commonMain/composeResources/drawable/add_loan_charge.xml
  • core/ui/src/commonMain/composeResources/drawable/approve.xml
  • core/ui/src/commonMain/composeResources/drawable/assign_loan_officer.xml
  • core/ui/src/commonMain/composeResources/drawable/buy_down_fee.xml
  • core/ui/src/commonMain/composeResources/drawable/cancel.xml
  • core/ui/src/commonMain/composeResources/drawable/capitalized_income.xml
  • core/ui/src/commonMain/composeResources/drawable/change_loan_officer.xml
  • core/ui/src/commonMain/composeResources/drawable/charge_off.xml
  • core/ui/src/commonMain/composeResources/drawable/close.xml
  • core/ui/src/commonMain/composeResources/drawable/close_as_rescheduled.xml
  • core/ui/src/commonMain/composeResources/drawable/contract_termination.xml
  • core/ui/src/commonMain/composeResources/drawable/create_guarantors.xml
  • core/ui/src/commonMain/composeResources/drawable/credit_balance_refund.xml
  • core/ui/src/commonMain/composeResources/drawable/delete.xml
  • core/ui/src/commonMain/composeResources/drawable/disburse.xml
  • core/ui/src/commonMain/composeResources/drawable/disburse_to_savings.xml
  • core/ui/src/commonMain/composeResources/drawable/edit_repayment_schedule.xml
  • core/ui/src/commonMain/composeResources/drawable/foreclosure.xml
  • core/ui/src/commonMain/composeResources/drawable/goodwill_credit.xml
  • core/ui/src/commonMain/composeResources/drawable/interest_payment_wavier.xml
  • core/ui/src/commonMain/composeResources/drawable/loan_screen_report.xml
  • core/ui/src/commonMain/composeResources/drawable/make_repayment.xml
  • core/ui/src/commonMain/composeResources/drawable/merchant_issued_refund.xml
  • core/ui/src/commonMain/composeResources/drawable/modify_application.xml
  • core/ui/src/commonMain/composeResources/drawable/payment_refund.xml
  • core/ui/src/commonMain/composeResources/drawable/payments.xml
  • core/ui/src/commonMain/composeResources/drawable/prepay_loan.xml
  • core/ui/src/commonMain/composeResources/drawable/re_age.xml
  • core/ui/src/commonMain/composeResources/drawable/re_anortize.xml
  • core/ui/src/commonMain/composeResources/drawable/recover_from_guarantor.xml
  • core/ui/src/commonMain/composeResources/drawable/recovery_payment.xml
  • core/ui/src/commonMain/composeResources/drawable/reject.xml
  • core/ui/src/commonMain/composeResources/drawable/request_quote.xml
  • core/ui/src/commonMain/composeResources/drawable/reschedule.xml
  • core/ui/src/commonMain/composeResources/drawable/sell_loan.xml
  • core/ui/src/commonMain/composeResources/drawable/transfer_funds.xml
  • core/ui/src/commonMain/composeResources/drawable/undo_approval.xml
  • core/ui/src/commonMain/composeResources/drawable/undo_charge_off.xml
  • core/ui/src/commonMain/composeResources/drawable/undo_disbursal.xml
  • core/ui/src/commonMain/composeResources/drawable/undo_re_age.xml
  • core/ui/src/commonMain/composeResources/drawable/undo_re_anortize.xml
  • core/ui/src/commonMain/composeResources/drawable/undo_write_off.xml
  • core/ui/src/commonMain/composeResources/drawable/view_guarantors.xml
  • core/ui/src/commonMain/composeResources/drawable/waive_interest.xml
  • core/ui/src/commonMain/composeResources/drawable/withdrawn_by_client.xml
  • core/ui/src/commonMain/composeResources/drawable/write_off.xml
  • feature/loan/src/commonMain/composeResources/values/strings.xml
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/di/LoanModule.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/LoanAccountActionItem.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/LoanAccountActionNavigation.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/LoanAccountActionScreen.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/LoanAccountActionViewModel.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/payments/LoanActionPaymentsNavigation.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/payments/LoanActionPaymentsScreen.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/payments/LoanActionPaymentsViewModel.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountProfile/LoanAccountProfileNavigation.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountProfile/LoanAccountProfileScreen.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountProfile/LoanAccountProfileViewModel.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/navigation/LoanNavigation.kt
✅ Files skipped from review due to trivial changes (46)
  • core/ui/src/commonMain/composeResources/drawable/recovery_payment.xml
  • core/ui/src/commonMain/composeResources/drawable/recover_from_guarantor.xml
  • core/ui/src/commonMain/composeResources/drawable/loan_screen_report.xml
  • core/ui/src/commonMain/composeResources/drawable/change_loan_officer.xml
  • core/ui/src/commonMain/composeResources/drawable/disburse.xml
  • core/ui/src/commonMain/composeResources/drawable/payment_refund.xml
  • core/ui/src/commonMain/composeResources/drawable/cancel.xml
  • core/ui/src/commonMain/composeResources/drawable/undo_re_age.xml
  • core/ui/src/commonMain/composeResources/drawable/assign_loan_officer.xml
  • core/ui/src/commonMain/composeResources/drawable/re_anortize.xml
  • core/ui/src/commonMain/composeResources/drawable/contract_termination.xml
  • core/ui/src/commonMain/composeResources/drawable/capitalized_income.xml
  • core/ui/src/commonMain/composeResources/drawable/withdrawn_by_client.xml
  • core/ui/src/commonMain/composeResources/drawable/close.xml
  • core/ui/src/commonMain/composeResources/drawable/undo_disbursal.xml
  • core/ui/src/commonMain/composeResources/drawable/payments.xml
  • core/ui/src/commonMain/composeResources/drawable/make_repayment.xml
  • core/ui/src/commonMain/composeResources/drawable/add_loan_charge.xml
  • core/ui/src/commonMain/composeResources/drawable/disburse_to_savings.xml
  • core/ui/src/commonMain/composeResources/drawable/undo_approval.xml
  • core/ui/src/commonMain/composeResources/drawable/reschedule.xml
  • core/ui/src/commonMain/composeResources/drawable/view_guarantors.xml
  • core/ui/src/commonMain/composeResources/drawable/merchant_issued_refund.xml
  • core/ui/src/commonMain/composeResources/drawable/sell_loan.xml
  • core/ui/src/commonMain/composeResources/drawable/write_off.xml
  • core/ui/src/commonMain/composeResources/drawable/credit_balance_refund.xml
  • core/ui/src/commonMain/composeResources/drawable/approve.xml
  • core/ui/src/commonMain/composeResources/drawable/charge_off.xml
  • core/ui/src/commonMain/composeResources/drawable/waive_interest.xml
  • core/ui/src/commonMain/composeResources/drawable/request_quote.xml
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/di/LoanModule.kt
  • core/ui/src/commonMain/composeResources/drawable/undo_write_off.xml
  • core/ui/src/commonMain/composeResources/drawable/reject.xml
  • core/ui/src/commonMain/composeResources/drawable/close_as_rescheduled.xml
  • core/ui/src/commonMain/composeResources/drawable/transfer_funds.xml
  • core/ui/src/commonMain/composeResources/drawable/create_guarantors.xml
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/payments/LoanActionPaymentsNavigation.kt
  • core/ui/src/commonMain/composeResources/drawable/interest_payment_wavier.xml
  • core/ui/src/commonMain/composeResources/drawable/prepay_loan.xml
  • core/ui/src/commonMain/composeResources/drawable/undo_charge_off.xml
  • core/ui/src/commonMain/composeResources/drawable/goodwill_credit.xml
  • core/ui/src/commonMain/composeResources/drawable/add_collateral.xml
  • core/ui/src/commonMain/composeResources/drawable/modify_application.xml
  • core/ui/src/commonMain/composeResources/drawable/foreclosure.xml
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/LoanAccountActionItem.kt
  • feature/loan/src/commonMain/composeResources/values/strings.xml
🚧 Files skipped from review as they are similar to previous changes (10)
  • core/ui/src/commonMain/composeResources/drawable/buy_down_fee.xml
  • core/ui/src/commonMain/composeResources/drawable/edit_repayment_schedule.xml
  • core/ui/src/commonMain/composeResources/drawable/undo_re_anortize.xml
  • core/ui/src/commonMain/composeResources/drawable/delete.xml
  • core/ui/src/commonMain/composeResources/drawable/add_interest_pause.xml
  • core/model/src/commonMain/kotlin/com/mifos/core/model/objects/account/loan/Type.kt
  • core/ui/src/commonMain/composeResources/drawable/re_age.xml
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountProfile/LoanAccountProfileNavigation.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/payments/LoanActionPaymentsViewModel.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/navigation/LoanNavigation.kt


import androidclient.feature.loan.generated.resources.Res
import androidclient.feature.loan.generated.resources.feature_loan_action_error_details_not_found
import androidclient.feature.loan.generated.resources.feature_loan_action_failed_to_load_loam_actions

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

Typo in string resource name.

The resource feature_loan_action_failed_to_load_loam_actions has a typo: "loam" should be "loan". This should be corrected in both the resource file and this import.

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

In
`@feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/LoanAccountActionViewModel.kt`
at line 14, The import references a typo'd string resource name
feature_loan_action_failed_to_load_loam_actions; rename the resource to
feature_loan_action_failed_to_load_loan_actions in the resource file and update
this import to use the corrected identifier, then update any other usages (e.g.,
in LoanAccountActionViewModel or related callers) to the new name so all
references match.

@Arinyadav1

Copy link
Copy Markdown
Member

@Kartikey15dem in this I thought you don't have more action
image

@Kartikey15dem

Copy link
Copy Markdown
Contributor Author

@Kartikey15dem in this I thought you don't have more action image

Sorry , forgot to mention in the description that the more actions are added in the primary actions only and the payments are supposed to be shown on another screen. It is not mentioned in the ticket but Biplab Sir told me later to do it this way.

@biplab1

biplab1 commented Apr 6, 2026

Copy link
Copy Markdown
Contributor

In the screen recording, I can see the following types: Active, Overpaid, and Unknown. Can you please show the other types that are listed in the ticket?

It seems to be missing these Actions screens: Approved Loan Status, Submitted, Pending Approval Loan Status, Closed (Written Off) and Closed (Obligations Met). The last two needs to verified with the back-end since I only found their reference in the ticket itself.

@biplab1 biplab1 changed the title feat(feature/loan): loan account action screen feat(loan): implement loan account actions screen Apr 6, 2026
@biplab1

biplab1 commented Apr 6, 2026

Copy link
Copy Markdown
Contributor

Also, please add the screenshots for each loan status types showing all the actions so that we can verify and keep track of all the actions that needs to be present.

@biplab1

biplab1 commented Apr 6, 2026

Copy link
Copy Markdown
Contributor

This is for Active Loan Status:

  1. Some actions seem to be missing, for example, I do not see Undo Disbursal.
  2. Is Interest Payment Waiver same as Waive Interest?

We should keep all the actions names same and in the same order as in the web-app. Please review.

<string name="feature_loan_action_payment_refund_schedule">Payout Refund</string>
<string name="feature_loan_action_edit_payment_refund_sub">Refund overpayments to customer</string>
<string name="feature_loan_merchant_issued_refund_schedule">Merchant Issued Refund</string>
<string name="feature_loan_action_merchant_issued_refund_sub">Process refund from the retailer</string>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

What is sub in the name?

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.

@biplab1 its the text which is shown below the action name or title to brief the action like all other ones.

@sonarqubecloud

sonarqubecloud Bot commented May 8, 2026

Copy link
Copy Markdown

@openMF openMF deleted a comment from coderabbitai Bot May 8, 2026
@biplab1

biplab1 commented May 11, 2026

Copy link
Copy Markdown
Contributor

@Kartikey15dem Please fix static checks error.

@niyajali niyajali left a comment

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.

Do the similar changes on all screens, VIewModel and all other required places properly

}

@Composable
private fun LoanAccountActionContent(

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.

Spilt this methods, create a sealed interface in ViewModel for Loading, Empty, Content state and use here properly, use LazyColumn, use proper state and key

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@niyajali I have implemented this change please check

import kotlinx.serialization.Serializable
import org.jetbrains.compose.resources.StringResource

internal class LoanAccountActionsViewModel(

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.

Update this ViewModel with the recommed approach and pattern, checkout slack threads for more info

Anshjn1411 added a commit to Anshjn1411/mifos-x-field-officer-app that referenced this pull request May 14, 2026
…penMF#2660)

* Move guarantor related models and DTOs to a dedicated `guarantor` sub-package for better modularity.
* Implement `CreatedGuarantor` domain model and `CreateGuarantorResponseDto` to handle guarantor creation responses.
* Update `LoanAccountSummaryRepository` and `CreateGuarantorUseCase` to return `CreatedGuarantor` instead of a generic response.
* Refactor `CreateGuarantorViewModel` to use renamed internal methods (`loadGuarantorForm`, `submitGuarantor`) and updated domain models.
* Prevent back navigation in `CreateGuarantorScreen` while a guarantor submission is in progress.
* Remove unused guarantor navigation events and actions from `LoanAccountSummaryViewModel` and related screen routes.
@sahilshivekar sahilshivekar force-pushed the feature/loan-account-action branch 2 times, most recently from fed7e0e to 0e86112 Compare June 20, 2026 12:41
@sahilshivekar sahilshivekar force-pushed the feature/loan-account-action branch from 2be62b4 to c33bdce Compare June 26, 2026 07:22
revanthkumarJ
revanthkumarJ previously approved these changes Jun 29, 2026
@revanthkumarJ

Copy link
Copy Markdown
Contributor

@sahilshivekar see why ios is failing here

@sahilshivekar

Copy link
Copy Markdown
Contributor

@sahilshivekar see why ios is failing here

@revanthkumarJ iOS build is working now


val isNPA: Boolean = false,

val isEqualAmortization: Boolean = false,

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.

you've modifier the DB entity consider increase the DB version otherwise the app will crash

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@niyajali I have increased the DB version now

@sahilshivekar sahilshivekar force-pushed the feature/loan-account-action branch from bfdf4c6 to 5c7f879 Compare July 1, 2026 07:38
@sonarqubecloud

sonarqubecloud Bot commented Jul 1, 2026

Copy link
Copy Markdown

@revanthkumarJ revanthkumarJ merged commit 525e6d1 into openMF:dev Jul 1, 2026
10 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.

7 participants