WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,15 @@ import androidx.compose.material.icons.filled.VisibilityOff
import androidx.compose.material.icons.filled.WifiOff
import androidx.compose.material.icons.outlined.AccountCircle
import androidx.compose.material.icons.outlined.CheckCircle
import androidx.compose.material.icons.outlined.ContentCopy
import androidx.compose.material.icons.outlined.DateRange
import androidx.compose.material.icons.outlined.DeleteOutline
import androidx.compose.material.icons.outlined.DocumentScanner
import androidx.compose.material.icons.outlined.Draw
import androidx.compose.material.icons.outlined.EventRepeat
import androidx.compose.material.icons.outlined.FileCopy
import androidx.compose.material.icons.outlined.FileUpload
import androidx.compose.material.icons.outlined.FolderCopy
import androidx.compose.material.icons.outlined.Group
import androidx.compose.material.icons.outlined.Groups
import androidx.compose.material.icons.outlined.Home
Expand Down Expand Up @@ -242,4 +245,5 @@ object MifosIcons {
val Refresh = Icons.Outlined.Refresh
val Undo = Icons.AutoMirrored.Outlined.Undo
val Redo = Icons.AutoMirrored.Outlined.Redo
val Copy = Icons.Outlined.ContentCopy
}
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,9 @@ private fun ClientLoanAccountsScreen(
},
onActionClicked = { actions ->
when (actions) {
is Actions.ViewAccount -> onAction(ClientLoanAccountsAction.ViewAccount)
is Actions.ViewAccount -> onAction(
ClientLoanAccountsAction.ViewAccount(loan.id ?: 0),
)
Comment on lines +182 to +184
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# First, let's understand the codebase structure
find . -name "*.kt" -path "*/client/*" | head -20

Repository: openMF/android-client

Length of output: 1933


🏁 Script executed:

#!/bin/bash
# Find ViewAccount event/action handling in the codebase
rg -n "ViewAccount" --type=kt -B 2 -A 5

Repository: openMF/android-client

Length of output: 91


🏁 Script executed:

#!/bin/bash
# Check for loan ID validation patterns
rg -n "loanId.*==.*0|id.*==.*0|loanId.*!=.*null|id.*!=.*null" --type=kt -C 3

Repository: openMF/android-client

Length of output: 91


🏁 Script executed:

#!/bin/bash
# Look for repository or API calls that use loan ID as parameter
rg -n "fun.*getLoan|fun.*viewLoan|fun.*fetchLoan" --type=kt -A 3

Repository: openMF/android-client

Length of output: 91


🏁 Script executed:

#!/bin/bash
# Search for ViewAccount in Kotlin files (using extension pattern)
rg -n "ViewAccount" --include="*.kt" -B 2 -A 5

Repository: openMF/android-client

Length of output: 506


🏁 Script executed:

#!/bin/bash
# Look at the specific file mentioned in the review
cat -n ./feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientLoanAccounts/ClientLoanAccountsScreen.kt | sed -n '175,195p'

Repository: openMF/android-client

Length of output: 1397


🏁 Script executed:

#!/bin/bash
# Search for loan ID validation or special handling of ID 0
rg -n "(loanId|loan\.id).*(==.*0|!=.*0|validate|check)" --include="*.kt" -C 3

Repository: openMF/android-client

Length of output: 506


🏁 Script executed:

#!/bin/bash
# Find where the ViewAccount action leads to (handlers, navigation, etc)
rg -n "ClientLoanAccountsAction.ViewAccount" --include="*.kt" -B 2 -A 5

Repository: openMF/android-client

Length of output: 506


🏁 Script executed:

#!/bin/bash
# Search for ViewAccount pattern across Kotlin files
fd '\.kt$' | xargs grep -l "ViewAccount" | head -20

Repository: openMF/android-client

Length of output: 1969


🏁 Script executed:

#!/bin/bash
# Look for ClientLoanAccountsAction class definition
fd '\.kt$' | xargs grep -n "class ClientLoanAccountsAction\|sealed class ClientLoanAccountsAction\|object ClientLoanAccountsAction"

Repository: openMF/android-client

Length of output: 49


🏁 Script executed:

#!/bin/bash
# Find where ViewAccount action is handled (look for when/case statements)
fd '\.kt$' | xargs grep -n "ClientLoanAccountsAction.ViewAccount" -A 3 -B 1

Repository: openMF/android-client

Length of output: 1799


🏁 Script executed:

#!/bin/bash
# Search for any loan ID validation or special handling
fd '\.kt$' | xargs grep -n "id.*==.*0\|loanId.*==.*0\|loanId.*!=.*null"

Repository: openMF/android-client

Length of output: 495


🏁 Script executed:

#!/bin/bash
# Find the ClientLoanAccountsAction definition
fd '\.kt$' | xargs grep -n "sealed class\|data class.*ViewAccount\|class.*ViewAccount" | grep -i "loanaccounts"

Repository: openMF/android-client

Length of output: 583


🏁 Script executed:

#!/bin/bash
# Look for the event handler - where ViewAccount event is processed
fd '\.kt$' | xargs grep -n "ClientLoanAccountsEvent.ViewAccount\|is.*ViewAccount.*->.*navigate\|is.*ViewAccount.*->"

Repository: openMF/android-client

Length of output: 4533


🏁 Script executed:

#!/antml/bin
# Check ClientLoanAccountsRoute for navigation handling
cat -n ./feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientLoanAccounts/ClientLoanAccountsRoute.kt

Repository: openMF/android-client

Length of output: 1620


🏁 Script executed:

#!/bin/bash
# Look for LaunchedEffect or collectAsState in the ViewModel to see event handling
fd 'ClientLoanAccountsViewModel.kt$' | xargs cat -n | grep -A 20 "LaunchedEffect\|collectAsState\|event"

Repository: openMF/android-client

Length of output: 47


🏁 Script executed:

#!/bin/bash
# Find where navigateToViewAccount is called/implemented (loan detail screen)
fd '\.kt$' | xargs grep -n "navigateToViewAccount\|LoanDetail\|LoanAccount.*Screen" | grep -v "ClientLoanAccounts"

Repository: openMF/android-client

Length of output: 12981


🏁 Script executed:

#!/bin/bash
# Check the full ClientLoanAccountsScreen to see the viewAccount callback
cat -n ./feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientLoanAccounts/ClientLoanAccountsScreen.kt | head -100

Repository: openMF/android-client

Length of output: 4925


🏁 Script executed:

#!/bin/bash
# Look for loan detail loading/fetching logic
fd '\.kt$' | xargs grep -n "fun.*getLoan\|suspend.*getLoan\|repository.*getLoan\|loanId.*Int" | grep -i "loan.*detail\|loan.*account" | head -20

Repository: openMF/android-client

Length of output: 3313


🏁 Script executed:

#!/bin/bash
# Check if there are any data model definitions for loans
fd '\.kt$' | xargs grep -n "data class.*Loan\|class.*Loan" | grep -i "id.*Int\|loanId" | head -15

Repository: openMF/android-client

Length of output: 797


🏁 Script executed:

#!/bin/bash
# Check LoanAccountSummaryScreen for state handling
cat -n ./feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountSummary/LoanAccountSummaryScreen.kt | sed -n '100,200p'

Repository: openMF/android-client

Length of output: 4812


🏁 Script executed:

#!/bin/bash
# Check LoanAccountSummaryViewModel initialization and error handling
fd 'LoanAccountSummaryViewModel.kt' | xargs cat -n | head -80

Repository: openMF/android-client

Length of output: 3000


🏁 Script executed:

#!/bin/bash
# Look for the ClientLoanAccountsScreen data model - check if loan.id can actually be null
fd '\.kt$' | xargs grep -n "data class.*Loan\|class.*Loan" -A 3 | grep -E "loan|id.*Int|nullable" | head -30

Repository: openMF/android-client

Length of output: 5069


🏁 Script executed:

#!/bin/bash
# Check if there are any null checks or validations for loan data in the summary screen
fd 'LoanAccountSummary' | xargs grep -n "if.*null\|?.let\|?:\|!!" | head -20

Repository: openMF/android-client

Length of output: 3474


🏁 Script executed:

#!/bin/bash
# Find the loan model/entity definition used in ClientLoanAccountsScreen
fd '\.kt$' | xargs grep -l "LoanWithAssociationsEntity\|LoanEntity" | head -5

Repository: openMF/android-client

Length of output: 550


🏁 Script executed:

#!/bin/bash
# Get the structure of loan entity to see if id is nullable
fd 'LoanWithAssociationsEntity.kt$' | xargs cat -n | head -50

Repository: openMF/android-client

Length of output: 2470


🏁 Script executed:

#!/bin/bash
# Check what data flows into ClientLoanAccountsScreen - the list of loans
cat -n ./feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientLoanAccounts/ClientLoanAccountsViewModel.kt | sed -n '90,120p'

Repository: openMF/android-client

Length of output: 1384


🏁 Script executed:

#!/bin/bash
# Get more of the LoanWithAssociationsEntity definition to see if id is nullable
fd 'LoanWithAssociationsEntity.kt$' | xargs cat -n | sed -n '50,150p'

Repository: openMF/android-client

Length of output: 3486


🏁 Script executed:

#!/bin/bash
# Check how loans are displayed in the ClientLoanAccountsScreen to understand the data
cat -n ./feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientLoanAccounts/ClientLoanAccountsScreen.kt | sed -n '140,185p'

Repository: openMF/android-client

Length of output: 3519


🏁 Script executed:

#!/bin/bash
# Look at the full loan accounts fetching to see if null IDs are filtered earlier
cat -n ./feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientLoanAccounts/ClientLoanAccountsViewModel.kt | sed -n '100,125p'

Repository: openMF/android-client

Length of output: 1274


🏁 Script executed:

#!/bin/bash
# Check the type definition of the loanAccounts list in ClientLoanAccountsState
fd 'ClientLoanAccountsViewModel.kt$' | xargs grep -n "data class ClientLoanAccountsState\|loanAccounts.*List" -A 3

Repository: openMF/android-client

Length of output: 421


🏁 Script executed:

#!/bin/bash
# Check if there's a LoansWithAssociations type that wraps the loan list
fd '\.kt$' | xargs grep -n "class.*Loans\|data class.*Loans" | grep -i "loanaccounts\|getClientAccounts" | head -10

Repository: openMF/android-client

Length of output: 47


🏁 Script executed:

#!/bin/bash
# Look for the repository's getClientAccounts return type
fd '\.kt$' | xargs grep -n "fun getClientAccounts\|getClientAccounts.*:" -A 2 | head -20

Repository: openMF/android-client

Length of output: 2304


🏁 Script executed:

#!/bin/bash
# Find LoanAccountEntity definition
fd 'LoanAccountEntity.kt$' | xargs cat -n | head -100

Repository: openMF/android-client

Length of output: 3294


🏁 Script executed:

#!/bin/bash
# Search for LoanAccountEntity to see its id field
fd '\.kt$' | xargs grep -n "data class LoanAccountEntity\|class LoanAccountEntity" -A 10 | head -30

Repository: openMF/android-client

Length of output: 1367


🏁 Script executed:

#!/bin/bash
# Check the actual data flow - what entity type contains the loan.id in the screen
fd '\.kt$' | xargs grep -n "LoanAccountEntity" | grep -i "id.*Int\|id.*nullable" | head -15

Repository: openMF/android-client

Length of output: 213


Handle null loan ID properly instead of defaulting to 0.

loan.id is nullable (defined as Int? in LoanAccountEntity), and defaulting to 0 when null masks data quality issues:

  • Loans with null IDs should not appear in the list; defaulting to 0 silently hides this problem
  • Attempting to load a loan with ID 0 will return no results, displaying an empty loan with all default values
  • This masks legitimate data integrity issues that should be surfaced to the user

Consider filtering out loans with null IDs earlier in the data flow, or validate that loan.id is not null before enabling the ViewAccount action.

🤖 Prompt for AI Agents
In
feature/client/src/commonMain/kotlin/com/mifos/feature/client/clientLoanAccounts/ClientLoanAccountsScreen.kt
around lines 182-184, the code currently calls ViewAccount using loan.id ?: 0
which masks null IDs; instead ensure you never call ViewAccount with a null id
by either (A) filtering out LoanAccountEntity items with null id earlier (e.g.,
when mapping/collecting the loan list) so the UI only binds non-null ids, or (B)
check loan.id before invoking onAction and only call
onAction(ClientLoanAccountsAction.ViewAccount(id)) when id != null, otherwise
disable/hide the view button or show a validation/error state informing the user
of a data integrity problem; pick one approach and apply it consistently so a 0
id is never used as a fallback.

is Actions.MakeRepayment -> onAction(
ClientLoanAccountsAction.MakeRepayment,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class ClientLoanAccountsViewModel(

is ClientLoanAccountsAction.ViewAccount -> sendEvent(
ClientLoanAccountsEvent.ViewAccount(
state.clientId,
action.loanId,
),
)

Expand Down Expand Up @@ -158,7 +158,7 @@ sealed interface ClientLoanAccountsAction {
data object ToggleFilter : ClientLoanAccountsAction
data object Refresh : ClientLoanAccountsAction
data object MakeRepayment : ClientLoanAccountsAction
data object ViewAccount : ClientLoanAccountsAction
data class ViewAccount(val loanId: Int) : ClientLoanAccountsAction
data class UpdateSearchValue(val query: String) : ClientLoanAccountsAction
data object OnSearchClick : ClientLoanAccountsAction
data object CloseDialog : ClientLoanAccountsAction
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@
<string name="feature_loan_total">Total</string>
<string name="feature_loan_make_Repayment">Make Repayment</string>
<string name="feature_loan_closed">Loan Closed</string>
<string name="feature_loan_total_loan">Total Loan</string>

<string name="feature_loan_failed_to_load_loan_repayment">Failed to load loan repayment</string>
<string name="feature_loan_repayment_make_sure_every_field_has_a_value">Make sure every field has a value</string>
Expand All @@ -132,6 +133,14 @@
<string name="feature_loan_id">Id</string>
<string name="feature_loan_office">Office</string>
<string name="feature_loan_break_down">Break Down</string>
<string name="feature_loan_outstanding_balance">Outstanding Balance</string>
<string name="feature_loan_loan_overview">Loan Overview</string>
<string name="feature_loan_loan_id">Loan ID: #</string>
<string name="feature_loan_loan_id_copied">Copied to clipboard</string>
<string name="feature_loan_copy">Copy</string>
<string name="feature_loan_info">Info</string>
<string name="feature_loan_arrears">Arrears</string>


<string name="feature_loan_unknown_error_occured">An Unknown Error Occured</string>
<string name="feature_loan_payment_success_message">Payment Successful, Transaction ID = </string>
Expand Down
Loading
Loading