Skip to content

Feat - CMP migration of feature/groups #2369

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Jun 10, 2025
2 changes: 1 addition & 1 deletion cmp-navigation/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ kotlin {
implementation(projects.feature.collectionSheet)
// implementation(projects.feature.dataTable)
// implementation(projects.feature.document)
// implementation(projects.feature.groups)
implementation(projects.feature.groups)
// implementation(projects.feature.loan)
implementation(projects.feature.note)
// implementation(projects.feature.offline)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import com.mifos.feature.activate.di.ActivateModule
import com.mifos.feature.auth.di.AuthModule
import com.mifos.feature.center.di.CenterModule
import com.mifos.feature.checker.inbox.task.di.CheckerInboxTaskModule
import com.mifos.feature.groups.di.GroupsModule
import com.mifos.feature.individualCollectionSheet.di.CollectionSheetModule
import com.mifos.feature.note.di.NoteModule
import com.mifos.feature.pathTracking.di.PathTrackingModule
Expand Down Expand Up @@ -63,7 +64,7 @@ object KoinModules {
CollectionSheetModule,
// DataTableModule,
// DocumentModule,
// GroupsModule,
GroupsModule,
// LoanModule,
NoteModule,
// OfflineModule,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,16 @@ import com.mifos.feature.about.navigation.aboutNavGraph
import com.mifos.feature.activate.navigation.activateScreen
import com.mifos.feature.activate.navigation.navigateToActivateScreen
import com.mifos.feature.center.navigation.centerNavGraph
import com.mifos.feature.center.navigation.navigateCreateCenterScreenRoute
import com.mifos.feature.checker.inbox.task.navigation.checkerInboxTaskNavGraph
import com.mifos.feature.groups.navigation.groupNavGraph
import com.mifos.feature.groups.navigation.navigateToCreateNewGroupScreen
import com.mifos.feature.individualCollectionSheet.navigation.individualCollectionSheetNavGraph
import com.mifos.feature.note.navigation.navigateToNoteScreen
import com.mifos.feature.note.navigation.noteNavGraph
import com.mifos.feature.pathTracking.navigation.pathTrackingNavGraph
import com.mifos.feature.savings.navigation.navigateToAddSavingsAccount
import com.mifos.feature.savings.navigation.navigateToSavingsAccountSummaryScreen
import com.mifos.feature.savings.navigation.savingsNavGraph
import com.mifos.feature.search.navigation.searchNavGraph
import com.mifos.feature.settings.navigation.settingsScreen
Expand All @@ -45,8 +50,8 @@ internal fun FeatureNavHost(
searchNavGraph(
paddingValues = padding,
onCreateClient = { println("Create Client") },
onCreateCenter = { println("Create Center") },
onCreateGroup = { println("Create Group") },
onCreateCenter = appState.navController::navigateCreateCenterScreenRoute,
onCreateGroup = appState.navController::navigateToCreateNewGroupScreen,
onClient = { id -> println("Client clicked: $id") },
onCenter = { id -> println("Center clicked: $id") },
onGroup = { id -> println("Group clicked: $id") },
Expand Down Expand Up @@ -76,6 +81,20 @@ internal fun FeatureNavHost(
},
)

groupNavGraph(
navController = appState.navController,
paddingValues = padding,
addGroupLoanAccount = {},
addSavingsAccount = appState.navController::navigateToAddSavingsAccount,
loadDocumentList = { _, _ -> },
clientListFragment = {},
loadSavingsAccountSummary = appState.navController::navigateToSavingsAccountSummaryScreen,
loadGroupDataTables = { _, _ -> },
loadNotes = appState.navController::navigateToNoteScreen,
loadLoanAccountSummary = { _ -> },
activateGroup = appState.navController::navigateToActivateScreen,
)

settingsScreen(
navigateBack = appState.navController::popBackStack,
navigateToLoginScreen = {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import androidx.compose.ui.graphics.vector.ImageVector
import com.mifos.core.designsystem.icon.MifosIcons
import com.mifos.feature.about.navigation.AboutScreens
import com.mifos.feature.checker.inbox.task.navigation.CheckerInboxTaskScreens
import com.mifos.feature.groups.navigation.GroupScreen
import com.mifos.feature.pathTracking.navigation.PathTrackingScreens
import com.mifos.feature.search.navigation.SearchScreens
import com.mifos.feature.settings.navigation.SettingsScreens
Expand Down Expand Up @@ -42,7 +43,7 @@ sealed class HomeDestinationsScreen(

data object GroupListScreen : HomeDestinationsScreen(
title = "Groups",
route = "",
route = GroupScreen.GroupListScreen.route,
icon = MifosIcons.Group,
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ import com.mifos.core.model.utils.Parcelable
import com.mifos.core.model.utils.Parcelize
import com.mifos.room.entities.accounts.loans.LoanAccountEntity
import com.mifos.room.entities.accounts.savings.SavingsAccountEntity
import kotlinx.serialization.Serializable

/**
* Created by mayankjindal on 11/07/17.
*/
@Parcelize
@Serializable
data class CenterAccounts(
val loanAccounts: List<LoanAccountEntity> = emptyList(),

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ import com.mifos.core.model.utils.Parcelable
import com.mifos.core.model.utils.Parcelize
import com.mifos.room.entities.accounts.loans.LoanAccountEntity
import com.mifos.room.entities.accounts.savings.SavingsAccountEntity
import kotlinx.serialization.Serializable

@Parcelize
@Serializable
data class GroupAccounts(
var loanAccounts: List<LoanAccountEntity> = emptyList(),

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import com.mifos.room.utils.PrimaryKey
import com.mifos.room.utils.UNDEFINED
import com.mifos.room.utils.UNSPECIFIED
import com.mifos.room.utils.VALUE_UNSPECIFIED
import kotlinx.serialization.Serializable

@Entity(
tableName = "LoanAccountEntity",
Expand Down Expand Up @@ -47,6 +48,7 @@ import com.mifos.room.utils.VALUE_UNSPECIFIED
ignoredColumns = [],
)
@Parcelize
@Serializable
data class LoanAccountEntity(
@PrimaryKey(autoGenerate = true)
val id: Int? = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ data class SavingAccountDepositTypeEntity(
val isRecurring: Boolean
get() = ServerTypes.RECURRING.id == id
val endpoint: String
get() = ServerTypes.fromId(id!!).endpoint
get() = ServerTypes.fromId(id).endpoint
val serverType: ServerTypes
get() = ServerTypes.fromId(id!!)
get() = ServerTypes.fromId(id)

enum class ServerTypes(val id: Int, val code: String, val endpoint: String) {
SAVINGS(100, "depositAccountType.savingsDeposit", APIEndPoint.SAVINGS_ACCOUNTS),
Expand All @@ -49,7 +49,7 @@ data class SavingAccountDepositTypeEntity(
;

companion object {
fun fromId(id: Int): ServerTypes {
fun fromId(id: Int?): ServerTypes {
for (type in entries) {
if (type.id == id) {
return type
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import com.mifos.room.utils.PrimaryKey
import com.mifos.room.utils.UNDEFINED
import com.mifos.room.utils.UNSPECIFIED
import com.mifos.room.utils.VALUE_UNSPECIFIED
import kotlinx.serialization.Serializable

@Entity(
tableName = "SavingsAccount",
Expand Down Expand Up @@ -55,6 +56,7 @@ import com.mifos.room.utils.VALUE_UNSPECIFIED
],
)
@Parcelize
@Serializable
data class SavingsAccountEntity(
@PrimaryKey(autoGenerate = true)
val id: Int? = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import com.mifos.core.model.utils.Parcelable
import com.mifos.core.model.utils.Parcelize
import com.mifos.room.utils.Entity
import com.mifos.room.utils.PrimaryKey
import kotlinx.serialization.Serializable

@Parcelize
@Entity(
Expand All @@ -23,6 +24,7 @@ import com.mifos.room.utils.PrimaryKey
ignoredColumns = [],
tableName = "GroupPayload",
)
@Serializable
data class GroupPayloadEntity(
@PrimaryKey(autoGenerate = true)
val id: Int = 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@ import com.mifos.core.model.utils.Parcelable
import com.mifos.core.model.utils.Parcelize
import com.mifos.room.entities.accounts.GroupAccounts
import com.mifos.room.entities.group.GroupEntity
import kotlinx.serialization.Serializable

/**
* Created by Rajan Maurya on 11/09/16.
*/
@Parcelize
@Serializable
data class GroupAndGroupAccounts(
var group: GroupEntity? = null,
var groupAccounts: GroupAccounts? = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ fun MifosTextFieldDropdown(
.padding(horizontal = 16.dp),
label: String? = null,
readOnly: Boolean = false,
errorMessage: String? = null,
) {
var isExpanded by remember { mutableStateOf(false) }

Expand All @@ -51,6 +52,15 @@ fun MifosTextFieldDropdown(
onExpandedChange = { isExpanded = !isExpanded },
) {
OutlinedTextField(
isError = errorMessage != null,
supportingText = {
errorMessage?.let {
Text(
text = it,
color = MaterialTheme.colorScheme.error,
)
}
},
value = value,
onValueChange = onValueChanged,
label = { label?.let { Text(it) } },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import androidx.compose.material.icons.filled.ChevronLeft
import androidx.compose.material.icons.filled.ChevronRight
import androidx.compose.material.icons.filled.Close
import androidx.compose.material.icons.filled.CloudDownload
import androidx.compose.material.icons.filled.DoneAll
import androidx.compose.material.icons.filled.Edit
import androidx.compose.material.icons.filled.Error
import androidx.compose.material.icons.filled.FilterList
Expand Down Expand Up @@ -59,7 +60,10 @@ import androidx.compose.material.icons.outlined.DateRange
import androidx.compose.material.icons.outlined.EventRepeat
import androidx.compose.material.icons.outlined.Group
import androidx.compose.material.icons.outlined.Home
import androidx.compose.material.icons.outlined.HomeWork
import androidx.compose.material.icons.outlined.Mail
import androidx.compose.material.icons.outlined.Numbers
import androidx.compose.material.icons.outlined.PersonOutline
import androidx.compose.material.icons.outlined.Visibility
import androidx.compose.material.icons.outlined.VisibilityOff
import androidx.compose.material.icons.outlined.Wallet
Expand Down Expand Up @@ -104,6 +108,7 @@ object MifosIcons {
val EventRepeat = Icons.Outlined.EventRepeat
val Date = Icons.Outlined.DateRange
val ArrowBack1 = Icons.Rounded.ArrowBackIosNew
val DoneAll = Icons.Default.DoneAll
val KeyboardArrowDown = Icons.Rounded.KeyboardArrowDown
val Link = Icons.Default.Link
val Server = Icons.Default
Expand Down Expand Up @@ -179,6 +184,9 @@ object MifosIcons {
val FlashOff = Icons.Default.FlashOff
val Error2 = Icons.Filled.Error
val Notifications = Icons.Filled.Notifications
val Numbers = Icons.Outlined.Numbers
val Homework = Icons.Outlined.HomeWork
val PersonOutline = Icons.Outlined.PersonOutline
val NavigationDrawer = Icons.Default.Menu
val Stop = Icons.Rounded.Stop

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,19 +46,22 @@ import com.mifos.core.domain.useCases.GetClientPinpointLocationsUseCase
import com.mifos.core.domain.useCases.GetClientSavingsAccountTemplateByProductUseCase
import com.mifos.core.domain.useCases.GetDataTableInfoUseCase
import com.mifos.core.domain.useCases.GetDocumentsListUseCase
import com.mifos.core.domain.useCases.GetGroupDetailsUseCase
import com.mifos.core.domain.useCases.GetGroupLoansAccountTemplateUseCase
import com.mifos.core.domain.useCases.GetGroupSavingsAccountTemplateByProductUseCase
import com.mifos.core.domain.useCases.GetGroupsByCenterUseCase
import com.mifos.core.domain.useCases.GetGroupsByOfficeUseCase
import com.mifos.core.domain.useCases.GetIndividualCollectionSheetUseCase
import com.mifos.core.domain.useCases.GetListOfLoanChargesUseCase
import com.mifos.core.domain.useCases.GetLoanAndLoanRepaymentUseCase
import com.mifos.core.domain.useCases.GetLoansAccountTemplateUseCase
import com.mifos.core.domain.useCases.GetReportCategoryUseCase
import com.mifos.core.domain.useCases.GetReportFullParameterListUseCase
import com.mifos.core.domain.useCases.GetReportParameterDetailsUseCase
import com.mifos.core.domain.useCases.GetRunReportOfficesUseCase
import com.mifos.core.domain.useCases.GetRunReportProductUseCase
import com.mifos.core.domain.useCases.GetRunReportWithQueryUseCase
import com.mifos.core.domain.useCases.GetSavingsAccountAndTemplateUseCase
import com.mifos.core.domain.useCases.GetStaffInOfficeUseCase
import com.mifos.core.domain.useCases.GetUserPathTrackingUseCase
import com.mifos.core.domain.useCases.GroupsListPagingDataSource
Expand Down Expand Up @@ -153,4 +156,7 @@ val UseCaseModule = module {
factoryOf(::ValidateServerEndPointUseCase)
factoryOf(::ValidateServerPortUseCase)
factoryOf(::ValidateServerTenantUseCase)
factoryOf(::GetGroupDetailsUseCase)
factoryOf(::GetLoanAndLoanRepaymentUseCase)
factoryOf(::GetSavingsAccountAndTemplateUseCase)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright 2025 Mifos Initiative
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* See https://github.com/openMF/android-client/blob/master/LICENSE.md
*/
package com.mifos.core.domain.useCases

import com.mifos.core.common.utils.DataState
import com.mifos.core.data.repository.GroupDetailsRepository
import com.mifos.room.entities.zipmodels.GroupAndGroupAccounts
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine

class GetGroupDetailsUseCase(
private val repository: GroupDetailsRepository,
) {
operator fun invoke(groupId: Int): Flow<DataState<GroupAndGroupAccounts>> =
combine(
repository.getGroup(groupId),
repository.getGroupAccounts(groupId),
) { group, groupAccounts ->
if (group is DataState.Success && groupAccounts is DataState.Success) {
DataState.Success(
GroupAndGroupAccounts(
group = group.data,
groupAccounts = groupAccounts.data,
),
)
} else if (group is DataState.Error || groupAccounts is DataState.Error) {
val exception = (group as? DataState.Error)?.exception
?: (groupAccounts as? DataState.Error)?.exception
?: Exception("Unknown error")
DataState.Error(exception)
} else {
DataState.Loading
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright 2025 Mifos Initiative
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* See https://github.com/openMF/android-client/blob/master/LICENSE.md
*/
package com.mifos.core.domain.useCases

import com.mifos.core.common.utils.DataState
import com.mifos.core.data.repository.SyncGroupsDialogRepository
import com.mifos.room.entities.zipmodels.LoanAndLoanRepayment
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine

class GetLoanAndLoanRepaymentUseCase(
private val repository: SyncGroupsDialogRepository,
) {
operator fun invoke(loanId: Int): Flow<DataState<LoanAndLoanRepayment>> =
combine(
repository.syncLoanById(loanId),
repository.syncLoanRepaymentTemplate(loanId),
) { loan, template ->
if (loan is DataState.Success && template is DataState.Success) {
DataState.Success(
LoanAndLoanRepayment(
loanWithAssociations = loan.data,
loanRepaymentTemplate = template.data,
),
)
} else if (loan is DataState.Error || template is DataState.Error) {
val exception = (loan as? DataState.Error)?.exception
?: (template as? DataState.Error)?.exception
?: Exception("Unknown error")
DataState.Error(exception)
} else {
DataState.Loading
}
}
}
Loading