diff --git a/build-logic/convention/src/main/kotlin/org/mifos/Detekt.kt b/build-logic/convention/src/main/kotlin/org/mifos/Detekt.kt index f79b43d1354..902e98e0168 100644 --- a/build-logic/convention/src/main/kotlin/org/mifos/Detekt.kt +++ b/build-logic/convention/src/main/kotlin/org/mifos/Detekt.kt @@ -8,6 +8,7 @@ import org.gradle.kotlin.dsl.named internal fun Project.configureDetekt(extension: DetektExtension) = extension.apply { tasks.named("detekt") { + jvmTarget = "1.8" config.from(rootProject.file("config/detekt/detekt.yml")) reports { xml.required.set(true) diff --git a/feature/center/build.gradle.kts b/feature/center/build.gradle.kts index aacf44a8f62..a3e049075fe 100644 --- a/feature/center/build.gradle.kts +++ b/feature/center/build.gradle.kts @@ -1,3 +1,12 @@ +/* + * Copyright 2024 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 + */ plugins { alias(libs.plugins.mifos.android.feature) alias(libs.plugins.mifos.android.library.compose) diff --git a/feature/center/src/androidTest/java/com/mifos/feature/center/ExampleInstrumentedTest.kt b/feature/center/src/androidTest/java/com/mifos/feature/center/ExampleInstrumentedTest.kt index 3cad388852b..0fe0826179a 100644 --- a/feature/center/src/androidTest/java/com/mifos/feature/center/ExampleInstrumentedTest.kt +++ b/feature/center/src/androidTest/java/com/mifos/feature/center/ExampleInstrumentedTest.kt @@ -1,13 +1,20 @@ +/* + * Copyright 2024 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.feature.center -import androidx.test.platform.app.InstrumentationRegistry import androidx.test.ext.junit.runners.AndroidJUnit4 - +import androidx.test.platform.app.InstrumentationRegistry +import junit.framework.Assert.assertEquals import org.junit.Test import org.junit.runner.RunWith -import org.junit.Assert.* - /** * Instrumented test, which will execute on an Android device. * @@ -21,4 +28,4 @@ class ExampleInstrumentedTest { val appContext = InstrumentationRegistry.getInstrumentation().targetContext assertEquals("com.mifos.feature.center.test", appContext.packageName) } -} \ No newline at end of file +} diff --git a/feature/center/src/main/AndroidManifest.xml b/feature/center/src/main/AndroidManifest.xml index a5918e68abc..1dc76da0f7e 100644 --- a/feature/center/src/main/AndroidManifest.xml +++ b/feature/center/src/main/AndroidManifest.xml @@ -1,4 +1,13 @@ + \ No newline at end of file diff --git a/feature/center/src/main/java/com/mifos/feature/center/center_details/CenterDetailsScreen.kt b/feature/center/src/main/java/com/mifos/feature/center/centerDetails/CenterDetailsScreen.kt similarity index 81% rename from feature/center/src/main/java/com/mifos/feature/center/center_details/CenterDetailsScreen.kt rename to feature/center/src/main/java/com/mifos/feature/center/centerDetails/CenterDetailsScreen.kt index 0c1620d111d..b333769e3a6 100644 --- a/feature/center/src/main/java/com/mifos/feature/center/center_details/CenterDetailsScreen.kt +++ b/feature/center/src/main/java/com/mifos/feature/center/centerDetails/CenterDetailsScreen.kt @@ -1,6 +1,13 @@ -@file:OptIn(ExperimentalMaterial3Api::class) - -package com.mifos.feature.center.center_details +/* + * Copyright 2024 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.feature.center.centerDetails import androidx.compose.foundation.background import androidx.compose.foundation.isSystemInDarkTheme @@ -17,7 +24,6 @@ import androidx.compose.material.icons.filled.MoreVert import androidx.compose.material3.Button import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.DropdownMenu -import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.IconButton @@ -60,13 +66,12 @@ import com.mifos.core.objects.group.CenterWithAssociations import com.mifos.feature.center.R @Composable -fun CenterDetailsScreen( +internal fun CenterDetailsScreen( onBackPressed: () -> Unit, onActivateCenter: (Int) -> Unit, addSavingsAccount: (Int) -> Unit, - groupList: (Int) -> Unit + groupList: (Int) -> Unit, ) { - val viewModel: CenterDetailsViewModel = hiltViewModel() val centerId by viewModel.centerId.collectAsStateWithLifecycle() val state by viewModel.centerDetailsUiState.collectAsStateWithLifecycle() @@ -88,19 +93,18 @@ fun CenterDetailsScreen( onRetryClick = { viewModel.loadClientDetails(centerId) }, - onActivateCenter = { onActivateCenter(centerId) } + onActivateCenter = { onActivateCenter(centerId) }, ) } @Composable -fun CenterDetailsScreen( +internal fun CenterDetailsScreen( state: CenterDetailsUiState, onBackPressed: () -> Unit, onMenuClick: (MenuItems) -> Unit, onRetryClick: () -> Unit, - onActivateCenter: () -> Unit + onActivateCenter: () -> Unit, ) { - val snackbarHostState = remember { SnackbarHostState() } var showMenu by remember { mutableStateOf(false) } var centerActive by remember { mutableStateOf(true) } @@ -116,7 +120,7 @@ fun CenterDetailsScreen( DropdownMenu( modifier = Modifier.background(White), expanded = showMenu, - onDismissRequest = { showMenu = false } + onDismissRequest = { showMenu = false }, ) { MifosMenuDropDownItem(option = stringResource(id = R.string.feature_center_add_savings_account)) { onMenuClick(MenuItems.ADD_SAVINGS_ACCOUNT) @@ -138,20 +142,19 @@ fun CenterDetailsScreen( .heightIn(44.dp) .padding(start = 16.dp, end = 16.dp), colors = ButtonDefaults.buttonColors( - containerColor = if (isSystemInDarkTheme()) BluePrimaryDark else BluePrimary - ) + containerColor = if (isSystemInDarkTheme()) BluePrimaryDark else BluePrimary, + ), ) { Text( text = stringResource(id = R.string.feature_center_activate_center), - fontSize = 16.sp + fontSize = 16.sp, ) } - } - } + }, ) { paddingValues -> Column( - modifier = Modifier.padding(paddingValues) + modifier = Modifier.padding(paddingValues), ) { when (state) { is CenterDetailsUiState.Error -> { @@ -166,7 +169,7 @@ fun CenterDetailsScreen( CenterDetailsContent( centerWithAssociations = state.centerWithAssociations, centerInfo = state.centerInfo, - activateCenter = { centerActive = false } + activateCenter = { centerActive = false }, ) } } @@ -175,10 +178,10 @@ fun CenterDetailsScreen( } @Composable -fun CenterDetailsContent( +private fun CenterDetailsContent( centerWithAssociations: CenterWithAssociations, centerInfo: CenterInfo, - activateCenter: () -> Unit + activateCenter: () -> Unit, ) { if (centerWithAssociations.active == false) { activateCenter() @@ -195,34 +198,42 @@ fun CenterDetailsContent( fontWeight = FontWeight.SemiBold, ), color = Black, - textAlign = TextAlign.Center + textAlign = TextAlign.Center, ) } MifosCenterDetailsText( icon = MifosIcons.date, field = stringResource(id = R.string.feature_center_activation_date), - value = Utils.getStringOfDate(centerWithAssociations.activationDate) + value = Utils.getStringOfDate(centerWithAssociations.activationDate), ) MifosCenterDetailsText( icon = MifosIcons.date, field = stringResource(id = R.string.feature_center_next_meeting_on), - value = if (centerWithAssociations.collectionMeetingCalendar.calendarInstanceId == null) stringResource( - id = R.string.feature_center_unassigned - ) else Utils.getStringOfDate(centerWithAssociations.collectionMeetingCalendar.nextTenRecurringDates[0]) + value = if (centerWithAssociations.collectionMeetingCalendar.calendarInstanceId == null) { + stringResource( + id = R.string.feature_center_unassigned, + ) + } else { + Utils.getStringOfDate(centerWithAssociations.collectionMeetingCalendar.nextTenRecurringDates[0]) + }, ) centerWithAssociations.collectionMeetingCalendar.humanReadable?.let { MifosCenterDetailsText( icon = MifosIcons.eventRepeat, field = stringResource(id = R.string.feature_center_meeting_frequency), - value = it + value = it, ) } MifosCenterDetailsText( icon = MifosIcons.person, field = stringResource(id = R.string.feature_center_staff_name), - value = if (centerWithAssociations.staffName != null) centerWithAssociations.staffName.toString() else stringResource( - R.string.feature_center_no_staff - ) + value = if (centerWithAssociations.staffName != null) { + centerWithAssociations.staffName.toString() + } else { + stringResource( + R.string.feature_center_no_staff, + ) + }, ) Spacer(modifier = Modifier.height(16.dp)) @@ -238,60 +249,60 @@ fun CenterDetailsContent( fontWeight = FontWeight.SemiBold, ), color = Black, - textAlign = TextAlign.Center + textAlign = TextAlign.Center, ) MifosCenterDetailsText( icon = MifosIcons.person, field = stringResource(id = R.string.feature_center_active_client), - value = centerInfo.activeClients.toString() + value = centerInfo.activeClients.toString(), ) MifosCenterDetailsText( icon = MifosIcons.group, field = stringResource(id = R.string.feature_center_active_group_loan), - value = centerInfo.activeGroupLoans.toString() + value = centerInfo.activeGroupLoans.toString(), ) MifosCenterDetailsText( icon = MifosIcons.person, field = stringResource(id = R.string.feature_center_active_client_loans), - value = centerInfo.activeClientLoans.toString() + value = centerInfo.activeClientLoans.toString(), ) MifosCenterDetailsText( icon = MifosIcons.group, field = stringResource(id = R.string.feature_center_active_group_borrowers), - value = centerInfo.activeGroupBorrowers.toString() + value = centerInfo.activeGroupBorrowers.toString(), ) MifosCenterDetailsText( icon = MifosIcons.person, field = stringResource(id = R.string.feature_center_active_client_borrowers), - value = centerInfo.activeClientBorrowers.toString() + value = centerInfo.activeClientBorrowers.toString(), ) MifosCenterDetailsText( icon = MifosIcons.group, field = stringResource(id = R.string.feature_center_active_overdue_group_loans), - value = centerInfo.overdueGroupLoans.toString() + value = centerInfo.overdueGroupLoans.toString(), ) MifosCenterDetailsText( icon = MifosIcons.person, field = stringResource(id = R.string.feature_center_active_group_loan), - value = centerInfo.overdueClientLoans.toString() + value = centerInfo.overdueClientLoans.toString(), ) } } @Composable -fun MifosCenterDetailsText(icon: ImageVector, field: String, value: String) { +private fun MifosCenterDetailsText(icon: ImageVector, field: String, value: String) { Row( modifier = Modifier .padding(start = 16.dp, end = 16.dp, top = 8.dp, bottom = 8.dp) .fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically + verticalAlignment = Alignment.CenterVertically, ) { Icon( modifier = Modifier.size(18.dp), imageVector = icon, contentDescription = null, - tint = DarkGray + tint = DarkGray, ) Text( modifier = Modifier @@ -301,10 +312,10 @@ fun MifosCenterDetailsText(icon: ImageVector, field: String, value: String) { style = TextStyle( fontSize = 18.sp, fontWeight = FontWeight.Normal, - fontStyle = FontStyle.Normal + fontStyle = FontStyle.Normal, ), color = Black, - textAlign = TextAlign.Start + textAlign = TextAlign.Start, ) Text( @@ -312,40 +323,39 @@ fun MifosCenterDetailsText(icon: ImageVector, field: String, value: String) { style = TextStyle( fontSize = 18.sp, fontWeight = FontWeight.Normal, - fontStyle = FontStyle.Normal + fontStyle = FontStyle.Normal, ), color = DarkGray, - textAlign = TextAlign.Start + textAlign = TextAlign.Start, ) } } -class CenterDetailsUiStateProvider : PreviewParameterProvider { +private class CenterDetailsUiStateProvider : PreviewParameterProvider { override val values: Sequence get() = sequenceOf( CenterDetailsUiState.Loading, CenterDetailsUiState.Error(R.string.feature_center_error_loading_centers), - CenterDetailsUiState.CenterDetails(CenterWithAssociations(), CenterInfo()) + CenterDetailsUiState.CenterDetails(CenterWithAssociations(), CenterInfo()), ) } - @Preview(showBackground = true) @Composable private fun CenterDetailsScreenPreview( - @PreviewParameter(CenterDetailsUiStateProvider::class) state: CenterDetailsUiState + @PreviewParameter(CenterDetailsUiStateProvider::class) state: CenterDetailsUiState, ) { CenterDetailsScreen( state = state, onBackPressed = {}, onMenuClick = {}, onRetryClick = {}, - onActivateCenter = {} + onActivateCenter = {}, ) } enum class MenuItems { ADD_SAVINGS_ACCOUNT, - GROUP_LIST -} \ No newline at end of file + GROUP_LIST, +} diff --git a/feature/center/src/main/java/com/mifos/feature/center/center_details/CenterDetailsUiState.kt b/feature/center/src/main/java/com/mifos/feature/center/centerDetails/CenterDetailsUiState.kt similarity index 51% rename from feature/center/src/main/java/com/mifos/feature/center/center_details/CenterDetailsUiState.kt rename to feature/center/src/main/java/com/mifos/feature/center/centerDetails/CenterDetailsUiState.kt index eb1ce360154..e5c11d5f60e 100644 --- a/feature/center/src/main/java/com/mifos/feature/center/center_details/CenterDetailsUiState.kt +++ b/feature/center/src/main/java/com/mifos/feature/center/centerDetails/CenterDetailsUiState.kt @@ -1,4 +1,13 @@ -package com.mifos.feature.center.center_details +/* + * Copyright 2024 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.feature.center.centerDetails import com.mifos.core.objects.group.CenterInfo import com.mifos.core.objects.group.CenterWithAssociations @@ -14,6 +23,6 @@ sealed class CenterDetailsUiState { data class CenterDetails( val centerWithAssociations: CenterWithAssociations, - val centerInfo: CenterInfo + val centerInfo: CenterInfo, ) : CenterDetailsUiState() -} \ No newline at end of file +} diff --git a/feature/center/src/main/java/com/mifos/feature/center/center_details/CenterDetailsViewModel.kt b/feature/center/src/main/java/com/mifos/feature/center/centerDetails/CenterDetailsViewModel.kt similarity index 72% rename from feature/center/src/main/java/com/mifos/feature/center/center_details/CenterDetailsViewModel.kt rename to feature/center/src/main/java/com/mifos/feature/center/centerDetails/CenterDetailsViewModel.kt index e475304f600..d40b37ff71c 100644 --- a/feature/center/src/main/java/com/mifos/feature/center/center_details/CenterDetailsViewModel.kt +++ b/feature/center/src/main/java/com/mifos/feature/center/centerDetails/CenterDetailsViewModel.kt @@ -1,4 +1,13 @@ -package com.mifos.feature.center.center_details +/* + * Copyright 2024 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.feature.center.centerDetails import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel @@ -15,11 +24,10 @@ import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import javax.inject.Inject - @HiltViewModel class CenterDetailsViewModel @Inject constructor( private val getCenterDetailsUseCase: GetCenterDetailsUseCase, - private val savedStateHandle: SavedStateHandle + private val savedStateHandle: SavedStateHandle, ) : ViewModel() { val centerId = savedStateHandle.getStateFlow(key = Constants.CENTER_ID, initialValue = 0) @@ -31,8 +39,9 @@ class CenterDetailsViewModel @Inject constructor( fun loadClientDetails(centerId: Int) = viewModelScope.launch(Dispatchers.IO) { getCenterDetailsUseCase(centerId, false).collect { result -> when (result) { - is Resource.Error -> _centerDetailsUiState.value = - CenterDetailsUiState.Error(R.string.feature_center_error_loading_centers) + is Resource.Error -> + _centerDetailsUiState.value = + CenterDetailsUiState.Error(R.string.feature_center_error_loading_centers) is Resource.Loading -> _centerDetailsUiState.value = CenterDetailsUiState.Loading @@ -40,11 +49,11 @@ class CenterDetailsViewModel @Inject constructor( result.data?.let { _centerDetailsUiState.value = CenterDetailsUiState.CenterDetails( it.first, - if (it.second.isNotEmpty()) it.second[0] else CenterInfo() + if (it.second.isNotEmpty()) it.second[0] else CenterInfo(), ) } } } } } -} \ No newline at end of file +} diff --git a/feature/center/src/main/java/com/mifos/feature/center/center_group_list/GroupListScreen.kt b/feature/center/src/main/java/com/mifos/feature/center/centerGroupList/GroupListScreen.kt similarity index 85% rename from feature/center/src/main/java/com/mifos/feature/center/center_group_list/GroupListScreen.kt rename to feature/center/src/main/java/com/mifos/feature/center/centerGroupList/GroupListScreen.kt index fedbf0afa0a..79a4b07492f 100644 --- a/feature/center/src/main/java/com/mifos/feature/center/center_group_list/GroupListScreen.kt +++ b/feature/center/src/main/java/com/mifos/feature/center/centerGroupList/GroupListScreen.kt @@ -1,4 +1,13 @@ -package com.mifos.feature.center.center_group_list +/* + * Copyright 2024 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.feature.center.centerGroupList import androidx.compose.foundation.Canvas import androidx.compose.foundation.layout.Arrangement @@ -44,11 +53,10 @@ import com.mifos.core.ui.components.MifosEmptyUi import com.mifos.feature.center.R @Composable -fun GroupListScreen( +internal fun GroupListScreen( onBackPressed: () -> Unit, - loadClientsOfGroup: (List) -> Unit + loadClientsOfGroup: (List) -> Unit, ) { - val viewModel: GroupListViewModel = hiltViewModel() val centerId by viewModel.centerId.collectAsStateWithLifecycle() val state by viewModel.groupListUiState.collectAsStateWithLifecycle() @@ -76,16 +84,16 @@ fun GroupListScreen( }, onRetry = { viewModel.loadGroupByCenter(centerId) - } + }, ) } @Composable -fun GroupListScreen( +internal fun GroupListScreen( state: GroupListUiState, onBackPressed: () -> Unit, onRetry: () -> Unit, - onGroupClick: (Int) -> Unit + onGroupClick: (Int) -> Unit, ) { val snackbarHostState = remember { SnackbarHostState() } @@ -93,7 +101,7 @@ fun GroupListScreen( icon = MifosIcons.arrowBack, title = stringResource(id = R.string.feature_center_groups), onBackPressed = onBackPressed, - snackbarHostState = snackbarHostState + snackbarHostState = snackbarHostState, ) { paddingValues -> Column(modifier = Modifier.padding(paddingValues)) { when (state) { @@ -107,12 +115,12 @@ fun GroupListScreen( if (state.centerWithAssociations.groupMembers.isEmpty()) { MifosEmptyUi( text = stringResource(id = R.string.feature_center_no_group_list_to_show), - icon = MifosIcons.fileTask + icon = MifosIcons.fileTask, ) } else { GroupListContent( centerWithAssociations = state.centerWithAssociations, - onGroupClick = onGroupClick + onGroupClick = onGroupClick, ) } } @@ -121,11 +129,10 @@ fun GroupListScreen( } } - @Composable -fun GroupListContent( +private fun GroupListContent( centerWithAssociations: CenterWithAssociations, - onGroupClick: (Int) -> Unit + onGroupClick: (Int) -> Unit, ) { LazyColumn { items(centerWithAssociations.groupMembers) { group -> @@ -134,11 +141,10 @@ fun GroupListContent( } } - @Composable -fun GroupItem( +private fun GroupItem( group: Group, - onGroupClick: (Int) -> Unit + onGroupClick: (Int) -> Unit, ) { Card( modifier = Modifier @@ -146,22 +152,22 @@ fun GroupItem( shape = RoundedCornerShape(0.dp), elevation = CardDefaults.cardElevation(defaultElevation = 2.dp), colors = CardDefaults.cardColors( - containerColor = Color.White + containerColor = Color.White, ), - onClick = { group.id?.let { onGroupClick(it) } } + onClick = { group.id?.let { onGroupClick(it) } }, ) { Column(modifier = Modifier.padding(8.dp)) { Row( modifier = Modifier .fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically + verticalAlignment = Alignment.CenterVertically, ) { Text( modifier = Modifier .padding(8.dp), text = group.name.toString(), - style = MaterialTheme.typography.bodyMedium + style = MaterialTheme.typography.bodyMedium, ) Text( modifier = Modifier.padding(8.dp), @@ -177,7 +183,7 @@ fun GroupItem( stringResource(id = R.string.feature_center_active) } else { stringResource(id = R.string.feature_center_inactive) - } + }, ) Canvas(modifier = Modifier.size(16.dp)) { if (group.status?.value?.let { Status.isActive(it) } == true) { @@ -198,21 +204,21 @@ class GroupListUiStateProvider : PreviewParameterProvider { get() = sequenceOf( GroupListUiState.Loading, GroupListUiState.Error(R.string.feature_center_failed_to_load_group_list), - GroupListUiState.GroupList(sampleCenterWithAssociations) + GroupListUiState.GroupList(sampleCenterWithAssociations), ) } @Preview(showBackground = true) @Composable private fun GroupListScreenPreview( - @PreviewParameter(GroupListUiStateProvider::class) state: GroupListUiState + @PreviewParameter(GroupListUiStateProvider::class) state: GroupListUiState, ) { GroupListScreen( state = state, onBackPressed = {}, onGroupClick = {}, - onRetry = {} + onRetry = {}, ) } -val sampleCenterWithAssociations = CenterWithAssociations() \ No newline at end of file +val sampleCenterWithAssociations = CenterWithAssociations() diff --git a/feature/center/src/main/java/com/mifos/feature/center/centerGroupList/GroupListUiState.kt b/feature/center/src/main/java/com/mifos/feature/center/centerGroupList/GroupListUiState.kt new file mode 100644 index 00000000000..1ad5c786b66 --- /dev/null +++ b/feature/center/src/main/java/com/mifos/feature/center/centerGroupList/GroupListUiState.kt @@ -0,0 +1,24 @@ +/* + * Copyright 2024 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.feature.center.centerGroupList + +import com.mifos.core.objects.group.CenterWithAssociations + +/** + * Created by Aditya Gupta on 06/08/23. + */ +sealed class GroupListUiState { + + data object Loading : GroupListUiState() + + data class Error(val message: Int) : GroupListUiState() + + data class GroupList(val centerWithAssociations: CenterWithAssociations) : GroupListUiState() +} diff --git a/feature/center/src/main/java/com/mifos/feature/center/center_group_list/GroupListViewModel.kt b/feature/center/src/main/java/com/mifos/feature/center/centerGroupList/GroupListViewModel.kt similarity index 67% rename from feature/center/src/main/java/com/mifos/feature/center/center_group_list/GroupListViewModel.kt rename to feature/center/src/main/java/com/mifos/feature/center/centerGroupList/GroupListViewModel.kt index b910938d27e..f33b16bd103 100644 --- a/feature/center/src/main/java/com/mifos/feature/center/center_group_list/GroupListViewModel.kt +++ b/feature/center/src/main/java/com/mifos/feature/center/centerGroupList/GroupListViewModel.kt @@ -1,4 +1,13 @@ -package com.mifos.feature.center.center_group_list +/* + * Copyright 2024 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.feature.center.centerGroupList import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel @@ -21,7 +30,7 @@ import javax.inject.Inject class GroupListViewModel @Inject constructor( private val getGroupsUseCase: GetGroupsUseCase, private val getGroupsByCenterUseCase: GetGroupsByCenterUseCase, - private val savedStateHandle: SavedStateHandle + private val savedStateHandle: SavedStateHandle, ) : ViewModel() { val centerId = savedStateHandle.getStateFlow(key = Constants.CENTER_ID, initialValue = 0) @@ -32,27 +41,28 @@ class GroupListViewModel @Inject constructor( private val _groupAssociationState = MutableStateFlow(null) val groupAssociationState = _groupAssociationState.asStateFlow() - fun loadGroupByCenter(id: Int) = viewModelScope.launch(Dispatchers.IO) { getGroupsByCenterUseCase(id).collect { result -> when (result) { - is Resource.Error -> _groupListUiState.value = - GroupListUiState.Error(R.string.feature_center_failed_to_load_group_list) + is Resource.Error -> + _groupListUiState.value = + GroupListUiState.Error(R.string.feature_center_failed_to_load_group_list) is Resource.Loading -> _groupListUiState.value = GroupListUiState.Loading - is Resource.Success -> _groupListUiState.value = - GroupListUiState.GroupList(result.data ?: CenterWithAssociations()) + is Resource.Success -> + _groupListUiState.value = + GroupListUiState.GroupList(result.data ?: CenterWithAssociations()) } - } } fun loadGroups(groupId: Int) = viewModelScope.launch(Dispatchers.IO) { getGroupsUseCase(groupId).collect { result -> when (result) { - is Resource.Error -> _groupListUiState.value = - GroupListUiState.Error(R.string.feature_center_failed_to_load_group_list) + is Resource.Error -> + _groupListUiState.value = + GroupListUiState.Error(R.string.feature_center_failed_to_load_group_list) is Resource.Loading -> _groupListUiState.value = GroupListUiState.Loading @@ -60,4 +70,4 @@ class GroupListViewModel @Inject constructor( } } } -} \ No newline at end of file +} diff --git a/feature/center/src/main/java/com/mifos/feature/center/center_list/ui/CenterListScreen.kt b/feature/center/src/main/java/com/mifos/feature/center/centerList/ui/CenterListScreen.kt similarity index 84% rename from feature/center/src/main/java/com/mifos/feature/center/center_list/ui/CenterListScreen.kt rename to feature/center/src/main/java/com/mifos/feature/center/centerList/ui/CenterListScreen.kt index 0be04d07e41..fbf41c56f5e 100644 --- a/feature/center/src/main/java/com/mifos/feature/center/center_list/ui/CenterListScreen.kt +++ b/feature/center/src/main/java/com/mifos/feature/center/centerList/ui/CenterListScreen.kt @@ -1,6 +1,15 @@ +/* + * Copyright 2024 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 + */ @file:OptIn(ExperimentalFoundationApi::class, ExperimentalMaterialApi::class) -package com.mifos.feature.center.center_list.ui +package com.mifos.feature.center.centerList.ui import androidx.activity.compose.BackHandler import androidx.compose.foundation.Canvas @@ -72,16 +81,15 @@ import com.mifos.core.designsystem.theme.White import com.mifos.core.objects.group.Center import com.mifos.core.ui.components.SelectionModeTopAppBar import com.mifos.feature.center.R +import com.mifos.feature.center.syncCentersDialog.SyncCenterDialogScreen import kotlinx.coroutines.flow.flowOf @Composable -fun CenterListScreen( +internal fun CenterListScreen( paddingValues: PaddingValues, createNewCenter: () -> Unit, - syncClicked: (List
) -> Unit, - onCenterSelect: (Int) -> Unit + onCenterSelect: (Int) -> Unit, ) { - val viewModel: CenterListViewModel = hiltViewModel() val refreshState by viewModel.isRefreshing.collectAsStateWithLifecycle() val state by viewModel.centerListUiState.collectAsStateWithLifecycle() @@ -99,21 +107,19 @@ fun CenterListScreen( }, refreshState = refreshState, onCenterSelect = onCenterSelect, - syncClicked = syncClicked + // syncClicked = syncClicked ) } @Composable -fun CenterListScreen( - paddingValues : PaddingValues, +internal fun CenterListScreen( + paddingValues: PaddingValues, state: CenterListUiState, createNewCenter: () -> Unit, onRefresh: () -> Unit, refreshState: Boolean, - syncClicked: (List
) -> Unit, - onCenterSelect: (Int) -> Unit + onCenterSelect: (Int) -> Unit, ) { - val snackbarHostState = remember { SnackbarHostState() } var isInSelectionMode by rememberSaveable { mutableStateOf(false) } val selectedItems = remember { mutableStateListOf
() } @@ -121,13 +127,16 @@ fun CenterListScreen( isInSelectionMode = false selectedItems.clear() } + val sync = rememberSaveable { + mutableStateOf(false) + } BackHandler(enabled = isInSelectionMode) { resetSelectionMode() } val pullRefreshState = rememberPullRefreshState( refreshing = refreshState, - onRefresh = onRefresh + onRefresh = onRefresh, ) LaunchedEffect( @@ -149,8 +158,7 @@ fun CenterListScreen( actions = { FilledTonalButton( onClick = { - syncClicked(selectedItems.toList()) - resetSelectionMode() + sync.value = true }, ) { Icon( @@ -159,7 +167,7 @@ fun CenterListScreen( ) Text(text = stringResource(id = R.string.feature_center_sync)) } - } + }, ) } }, @@ -167,19 +175,19 @@ fun CenterListScreen( floatingActionButton = { FloatingActionButton( onClick = { createNewCenter() }, - containerColor = BlueSecondary + containerColor = BlueSecondary, ) { Icon( imageVector = MifosIcons.Add, - contentDescription = null + contentDescription = null, ) } - } + }, ) { paddingValue -> Column( modifier = Modifier .padding(paddingValue), - verticalArrangement = Arrangement.Center + verticalArrangement = Arrangement.Center, ) { Box(modifier = Modifier.pullRefresh(pullRefreshState)) { when (state) { @@ -200,20 +208,33 @@ fun CenterListScreen( selectedItems = selectedItems, onRefresh = { onRefresh() - }, onCenterSelect = { + }, + onCenterSelect = { onCenterSelect(it) - }, selectedMode = { + }, + selectedMode = { isInSelectionMode = true - } + }, ) } is CenterListUiState.CenterListDb -> CenterListDbContent(centerList = state.centers) } + if (sync.value) { + SyncCenterDialogScreen( + dismiss = { + sync.value = false + selectedItems.clear() + resetSelectionMode() + }, + hide = { sync.value = false }, + centers = selectedItems.toList(), + ) + } PullRefreshIndicator( refreshing = refreshState, state = pullRefreshState, - modifier = Modifier.align(Alignment.TopCenter) + modifier = Modifier.align(Alignment.TopCenter), ) } } @@ -221,16 +242,14 @@ fun CenterListScreen( } @Composable -fun CenterListContent( +private fun CenterListContent( centerPagingList: LazyPagingItems
, isInSelectionMode: Boolean, selectedItems: SnapshotStateList
, onRefresh: () -> Unit, onCenterSelect: (Int) -> Unit, - selectedMode: () -> Unit - + selectedMode: () -> Unit, ) { - when (centerPagingList.loadState.refresh) { is LoadState.Error -> { MifosSweetError(message = stringResource(id = R.string.feature_center_error_loading_centers)) { @@ -280,14 +299,16 @@ fun CenterListContent( centerPagingList[index]?.let { selectedItems.add(it) } cardColor = LightGray } - } + }, ), colors = CardDefaults.cardColors( containerColor = if (selectedItems.isEmpty()) { cardColor = White White - } else cardColor, - ) + } else { + cardColor + }, + ), ) { Row( modifier = Modifier @@ -296,22 +317,22 @@ fun CenterListContent( start = 16.dp, end = 16.dp, top = 24.dp, - bottom = 24.dp + bottom = 24.dp, ), - verticalAlignment = Alignment.CenterVertically + verticalAlignment = Alignment.CenterVertically, ) { Canvas( modifier = Modifier.size(16.dp), onDraw = { drawCircle( - color = if (centerPagingList[index]?.active == true) Color.Green else Color.Red + color = if (centerPagingList[index]?.active == true) Color.Green else Color.Red, ) - } + }, ) Column( modifier = Modifier .weight(1f) - .padding(start = 16.dp) + .padding(start = 16.dp), ) { centerPagingList[index]?.name?.let { Text( @@ -320,8 +341,8 @@ fun CenterListContent( fontSize = 16.sp, fontWeight = FontWeight.Normal, fontStyle = FontStyle.Normal, - color = Black - ) + color = Black, + ), ) } Text( @@ -330,8 +351,8 @@ fun CenterListContent( fontSize = 14.sp, fontWeight = FontWeight.Normal, fontStyle = FontStyle.Normal, - color = DarkGray - ) + color = DarkGray, + ), ) Row { Text( @@ -340,8 +361,8 @@ fun CenterListContent( fontSize = 14.sp, fontWeight = FontWeight.Normal, fontStyle = FontStyle.Normal, - color = DarkGray - ) + color = DarkGray, + ), ) Spacer(modifier = Modifier.width(26.dp)) Text( @@ -350,8 +371,8 @@ fun CenterListContent( fontSize = 14.sp, fontWeight = FontWeight.Normal, fontStyle = FontStyle.Normal, - color = DarkGray - ) + color = DarkGray, + ), ) } Row { @@ -361,8 +382,8 @@ fun CenterListContent( fontSize = 14.sp, fontWeight = FontWeight.Normal, fontStyle = FontStyle.Normal, - color = DarkGray - ) + color = DarkGray, + ), ) Spacer(modifier = Modifier.width(26.dp)) Text( @@ -371,8 +392,8 @@ fun CenterListContent( fontSize = 14.sp, fontWeight = FontWeight.Normal, fontStyle = FontStyle.Normal, - color = DarkGray - ) + color = DarkGray, + ), ) } } @@ -380,7 +401,7 @@ fun CenterListContent( AsyncImage( modifier = Modifier.size(20.dp), model = R.drawable.feature_center_ic_done_all_black_24dp, - contentDescription = null + contentDescription = null, ) } } @@ -407,10 +428,10 @@ fun CenterListContent( .padding(6.dp), text = stringResource(id = R.string.feature_center_no_more_centers), style = TextStyle( - fontSize = 14.sp + fontSize = 14.sp, ), color = DarkGray, - textAlign = TextAlign.Center + textAlign = TextAlign.Center, ) } } @@ -421,8 +442,8 @@ fun CenterListContent( } @Composable -fun CenterListDbContent( - centerList: List
+private fun CenterListDbContent( + centerList: List
, ) { LazyColumn { items(centerList) { center -> @@ -431,8 +452,8 @@ fun CenterListDbContent( modifier = Modifier .padding(6.dp), colors = CardDefaults.cardColors( - containerColor = White - ) + containerColor = White, + ), ) { Row( modifier = Modifier @@ -441,22 +462,22 @@ fun CenterListDbContent( start = 16.dp, end = 16.dp, top = 24.dp, - bottom = 24.dp + bottom = 24.dp, ), - verticalAlignment = Alignment.CenterVertically + verticalAlignment = Alignment.CenterVertically, ) { Canvas( modifier = Modifier.size(16.dp), onDraw = { drawCircle( - color = if (center.active == true) Color.Green else Color.Red + color = if (center.active == true) Color.Green else Color.Red, ) - } + }, ) Column( modifier = Modifier .weight(1f) - .padding(start = 16.dp) + .padding(start = 16.dp), ) { center.name?.let { Text( @@ -465,8 +486,8 @@ fun CenterListDbContent( fontSize = 16.sp, fontWeight = FontWeight.Normal, fontStyle = FontStyle.Normal, - color = Black - ) + color = Black, + ), ) } Text( @@ -475,8 +496,8 @@ fun CenterListDbContent( fontSize = 14.sp, fontWeight = FontWeight.Normal, fontStyle = FontStyle.Normal, - color = DarkGray - ) + color = DarkGray, + ), ) Row { Text( @@ -485,8 +506,8 @@ fun CenterListDbContent( fontSize = 14.sp, fontWeight = FontWeight.Normal, fontStyle = FontStyle.Normal, - color = DarkGray - ) + color = DarkGray, + ), ) Spacer(modifier = Modifier.width(26.dp)) Text( @@ -495,8 +516,8 @@ fun CenterListDbContent( fontSize = 14.sp, fontWeight = FontWeight.Normal, fontStyle = FontStyle.Normal, - color = DarkGray - ) + color = DarkGray, + ), ) } Row { @@ -506,8 +527,8 @@ fun CenterListDbContent( fontSize = 14.sp, fontWeight = FontWeight.Normal, fontStyle = FontStyle.Normal, - color = DarkGray - ) + color = DarkGray, + ), ) Spacer(modifier = Modifier.width(26.dp)) Text( @@ -516,15 +537,15 @@ fun CenterListDbContent( fontSize = 14.sp, fontWeight = FontWeight.Normal, fontStyle = FontStyle.Normal, - color = DarkGray - ) + color = DarkGray, + ), ) } } AsyncImage( modifier = Modifier.size(20.dp), model = R.drawable.feature_center_ic_done_all_black_24dp, - contentDescription = null + contentDescription = null, ) } } @@ -532,7 +553,6 @@ fun CenterListDbContent( } } - class CenterListUiStateProvider : PreviewParameterProvider { @@ -541,11 +561,10 @@ class CenterListUiStateProvider : CenterListUiState.Loading, CenterListUiState.Error(R.string.feature_center_error_loading_centers), CenterListUiState.CenterListDb(sampleCenterListDb), - CenterListUiState.CenterList(sampleCenterList) + CenterListUiState.CenterList(sampleCenterList), ) } - @Preview(showBackground = true) @Composable private fun CenterListContentPreview() { @@ -555,11 +574,10 @@ private fun CenterListContentPreview() { selectedItems = rememberSaveable { mutableStateListOf() }, onRefresh = {}, onCenterSelect = {}, - selectedMode = {} + selectedMode = {}, ) } - @Preview(showBackground = true) @Composable private fun CenterListDbContentPreview() { @@ -569,7 +587,7 @@ private fun CenterListDbContentPreview() { @Preview(showBackground = true) @Composable private fun CenterListScreenPreview( - @PreviewParameter(CenterListUiStateProvider::class) centerListUiState: CenterListUiState + @PreviewParameter(CenterListUiStateProvider::class) centerListUiState: CenterListUiState, ) { CenterListScreen( paddingValues = PaddingValues(), @@ -578,7 +596,6 @@ private fun CenterListScreenPreview( onRefresh = {}, refreshState = false, onCenterSelect = {}, - syncClicked = {} ) } @@ -589,7 +606,7 @@ val sampleCenterListDb = List(10) { officeName = "Office $it", staffId = it, staffName = "Staff $it", - active = it % 2 == 0 + active = it % 2 == 0, ) } diff --git a/feature/center/src/main/java/com/mifos/feature/center/center_list/ui/CenterUiState.kt b/feature/center/src/main/java/com/mifos/feature/center/centerList/ui/CenterListUiState.kt similarity index 55% rename from feature/center/src/main/java/com/mifos/feature/center/center_list/ui/CenterUiState.kt rename to feature/center/src/main/java/com/mifos/feature/center/centerList/ui/CenterListUiState.kt index f044e5cf9a0..20358bc53e5 100644 --- a/feature/center/src/main/java/com/mifos/feature/center/center_list/ui/CenterUiState.kt +++ b/feature/center/src/main/java/com/mifos/feature/center/centerList/ui/CenterListUiState.kt @@ -1,8 +1,16 @@ -package com.mifos.feature.center.center_list.ui +/* + * Copyright 2024 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.feature.center.centerList.ui import androidx.paging.PagingData import com.mifos.core.objects.group.Center -import com.mifos.core.objects.group.CenterWithAssociations import kotlinx.coroutines.flow.Flow /** @@ -17,4 +25,4 @@ sealed class CenterListUiState { data class CenterList(val centers: Flow>) : CenterListUiState() data class CenterListDb(val centers: List
) : CenterListUiState() -} \ No newline at end of file +} diff --git a/feature/center/src/main/java/com/mifos/feature/center/center_list/ui/CenterListViewModel.kt b/feature/center/src/main/java/com/mifos/feature/center/centerList/ui/CenterListViewModel.kt similarity index 64% rename from feature/center/src/main/java/com/mifos/feature/center/center_list/ui/CenterListViewModel.kt rename to feature/center/src/main/java/com/mifos/feature/center/centerList/ui/CenterListViewModel.kt index a5ebf3b7ff8..68373743d62 100644 --- a/feature/center/src/main/java/com/mifos/feature/center/center_list/ui/CenterListViewModel.kt +++ b/feature/center/src/main/java/com/mifos/feature/center/centerList/ui/CenterListViewModel.kt @@ -1,4 +1,13 @@ -package com.mifos.feature.center.center_list.ui +/* + * Copyright 2024 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.feature.center.centerList.ui import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope @@ -14,12 +23,11 @@ import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch import javax.inject.Inject - @HiltViewModel class CenterListViewModel @Inject constructor( private val prefManager: PrefManager, private val repository: CenterListRepository, - private val getCenterListDbUseCase: GetCenterListDbUseCase + private val getCenterListDbUseCase: GetCenterListDbUseCase, ) : ViewModel() { // for refresh feature @@ -36,8 +44,11 @@ class CenterListViewModel @Inject constructor( val centerListUiState = _centerListUiState.asStateFlow() fun getCenterList() { - if (prefManager.userStatus) loadCentersFromDb() - else loadCentersFromApi() + if (prefManager.userStatus) { + loadCentersFromDb() + } else { + loadCentersFromApi() + } } private fun loadCentersFromApi() = viewModelScope.launch(Dispatchers.IO) { @@ -48,13 +59,15 @@ class CenterListViewModel @Inject constructor( private fun loadCentersFromDb() = viewModelScope.launch(Dispatchers.IO) { getCenterListDbUseCase().collect { result -> when (result) { - is Resource.Error -> _centerListUiState.value = - CenterListUiState.Error(R.string.feature_center_failed_to_load_db_centers) + is Resource.Error -> + _centerListUiState.value = + CenterListUiState.Error(R.string.feature_center_failed_to_load_db_centers) is Resource.Loading -> _centerListUiState.value = CenterListUiState.Loading - is Resource.Success -> _centerListUiState.value = - CenterListUiState.CenterListDb(result.data ?: emptyList()) + is Resource.Success -> + _centerListUiState.value = + CenterListUiState.CenterListDb(result.data ?: emptyList()) } } } diff --git a/feature/center/src/main/java/com/mifos/feature/center/center_group_list/GroupListUiState.kt b/feature/center/src/main/java/com/mifos/feature/center/center_group_list/GroupListUiState.kt deleted file mode 100644 index a6c11bd23fc..00000000000 --- a/feature/center/src/main/java/com/mifos/feature/center/center_group_list/GroupListUiState.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.mifos.feature.center.center_group_list - -import com.mifos.core.objects.group.CenterWithAssociations - -/** - * Created by Aditya Gupta on 06/08/23. - */ -sealed class GroupListUiState { - - data object Loading : GroupListUiState() - - data class Error(val message: Int) : GroupListUiState() - - data class GroupList(val centerWithAssociations: CenterWithAssociations) : GroupListUiState() -} \ No newline at end of file diff --git a/feature/center/src/main/java/com/mifos/feature/center/create_center/CreateNewCenterScreen.kt b/feature/center/src/main/java/com/mifos/feature/center/createCenter/CreateNewCenterScreen.kt similarity index 86% rename from feature/center/src/main/java/com/mifos/feature/center/create_center/CreateNewCenterScreen.kt rename to feature/center/src/main/java/com/mifos/feature/center/createCenter/CreateNewCenterScreen.kt index bc62721d858..4d2cb7a7a36 100644 --- a/feature/center/src/main/java/com/mifos/feature/center/create_center/CreateNewCenterScreen.kt +++ b/feature/center/src/main/java/com/mifos/feature/center/createCenter/CreateNewCenterScreen.kt @@ -1,6 +1,15 @@ +/* + * Copyright 2024 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 + */ @file:OptIn(ExperimentalMaterial3Api::class) -package com.mifos.feature.center.create_center +package com.mifos.feature.center.createCenter import android.widget.Toast import androidx.compose.foundation.isSystemInDarkTheme @@ -59,10 +68,9 @@ import java.text.SimpleDateFormat import java.util.Locale @Composable -fun CreateNewCenterScreen( - onCreateSuccess: () -> Unit +internal fun CreateNewCenterScreen( + onCreateSuccess: () -> Unit, ) { - val viewModel: CreateNewCenterViewModel = hiltViewModel() val state by viewModel.createNewCenterUiState.collectAsStateWithLifecycle() @@ -78,23 +86,22 @@ fun CreateNewCenterScreen( createCenter = { viewModel.createNewCenter(it) }, - onCreateSuccess = onCreateSuccess + onCreateSuccess = onCreateSuccess, ) } @Composable -fun CreateNewCenterScreen( +internal fun CreateNewCenterScreen( state: CreateNewCenterUiState, onRetry: () -> Unit, createCenter: (CenterPayload) -> Unit, - onCreateSuccess: () -> Unit + onCreateSuccess: () -> Unit, ) { - val snackbarHostState = remember { SnackbarHostState() } MifosScaffold( title = stringResource(id = R.string.feature_center_create_new_center), - snackbarHostState = snackbarHostState + snackbarHostState = snackbarHostState, ) { paddingValues -> Column(modifier = Modifier.padding(paddingValues)) { when (state) { @@ -102,7 +109,7 @@ fun CreateNewCenterScreen( Toast.makeText( LocalContext.current, stringResource(id = R.string.feature_center_center_created_successfully), - Toast.LENGTH_SHORT + Toast.LENGTH_SHORT, ).show() onCreateSuccess() } @@ -121,10 +128,8 @@ fun CreateNewCenterScreen( } } - @Composable -fun CreateNewCenterContent(offices: List, createCenter: (CenterPayload) -> Unit) { - +private fun CreateNewCenterContent(offices: List, createCenter: (CenterPayload) -> Unit) { val context = LocalContext.current var centerName by rememberSaveable(stateSaver = TextFieldValue.Saver) { mutableStateOf(TextFieldValue("")) @@ -140,7 +145,7 @@ fun CreateNewCenterContent(offices: List, createCenter: (CenterPayload) override fun isSelectableDate(utcTimeMillis: Long): Boolean { return utcTimeMillis >= System.currentTimeMillis() } - } + }, ) var showDatePicker by rememberSaveable { mutableStateOf(false) } var officeId by rememberSaveable { mutableIntStateOf(0) } @@ -185,7 +190,6 @@ fun CreateNewCenterContent(offices: List, createCenter: (CenterPayload) } } - if (showDatePicker) { DatePickerDialog( onDismissRequest = { @@ -198,18 +202,17 @@ fun CreateNewCenterContent(offices: List, createCenter: (CenterPayload) datePickerState.selectedDateMillis?.let { activateDate = it } - } + }, ) { Text(stringResource(id = R.string.feature_center_select)) } }, dismissButton = { TextButton( onClick = { showDatePicker = false - } + }, ) { Text(stringResource(id = R.string.feature_center_cancel)) } - } - ) - { + }, + ) { DatePicker(state = datePickerState) } } @@ -218,7 +221,7 @@ fun CreateNewCenterContent(offices: List, createCenter: (CenterPayload) value = centerName, onValueChange = { centerName = it }, label = R.string.feature_center_center_name, - error = null + error = null, ) MifosTextFieldDropdown( @@ -231,22 +234,21 @@ fun CreateNewCenterContent(offices: List, createCenter: (CenterPayload) offices[index].id?.let { officeId = it } - }, label = R.string.feature_center_office, options = offices.map { it.name.toString() }, - readOnly = true + readOnly = true, ) Row( modifier = Modifier.padding(8.dp), - verticalAlignment = Alignment.CenterVertically + verticalAlignment = Alignment.CenterVertically, ) { Checkbox( checked = isActivate, onCheckedChange = { isActivate = it - } + }, ) Text(text = stringResource(id = R.string.feature_center_activate)) } @@ -254,12 +256,12 @@ fun CreateNewCenterContent(offices: List, createCenter: (CenterPayload) if (isActivate) { MifosDatePickerTextField( value = SimpleDateFormat("dd MMMM yyyy", Locale.getDefault()).format( - activateDate + activateDate, ), label = R.string.feature_center_activation_date, openDatePicker = { showDatePicker = true - } + }, ) Spacer(modifier = Modifier.height(16.dp)) } @@ -271,16 +273,20 @@ fun CreateNewCenterContent(offices: List, createCenter: (CenterPayload) CenterPayload( name = centerName.text, active = isActivate, - activationDate = if (isActivate) SimpleDateFormat( - "dd MMMM yyyy", - Locale.getDefault() - ).format( - activateDate - ) else null, + activationDate = if (isActivate) { + SimpleDateFormat( + "dd MMMM yyyy", + Locale.getDefault(), + ).format( + activateDate, + ) + } else { + null + }, officeId = officeId, dateFormat = "dd MMMM yyyy", - locale = "en" - ) + locale = "en", + ), ) } }, @@ -290,8 +296,8 @@ fun CreateNewCenterContent(offices: List, createCenter: (CenterPayload) .padding(start = 16.dp, end = 16.dp), contentPadding = PaddingValues(), colors = ButtonDefaults.buttonColors( - containerColor = if (isSystemInDarkTheme()) BluePrimaryDark else BluePrimary - ) + containerColor = if (isSystemInDarkTheme()) BluePrimaryDark else BluePrimary, + ), ) { Text(text = stringResource(id = R.string.feature_center_create), fontSize = 16.sp) } @@ -303,24 +309,23 @@ class CreateNewCenterUiStateProvider : PreviewParameterProvider(CreateNewCenterUiState.Loading) + val createNewCenterUiState = _createNewCenterUiState.asStateFlow() + + fun loadOffices() = viewModelScope.launch(Dispatchers.IO) { + getOfficeListUseCase().collect { result -> + when (result) { + is Resource.Error -> + _createNewCenterUiState.value = + CreateNewCenterUiState.Error(R.string.feature_center_failed_to_load_offices) + + is Resource.Loading -> + _createNewCenterUiState.value = + CreateNewCenterUiState.Loading + + is Resource.Success -> + _createNewCenterUiState.value = + CreateNewCenterUiState.Offices(result.data ?: emptyList()) + } + } + } + + fun createNewCenter(centerPayload: CenterPayload) = viewModelScope.launch(Dispatchers.IO) { + createNewCenterUseCase(centerPayload).collect { result -> + when (result) { + is Resource.Error -> + _createNewCenterUiState.value = + CreateNewCenterUiState.Error(R.string.feature_center_failed_to_create_center) + + is Resource.Loading -> + _createNewCenterUiState.value = + CreateNewCenterUiState.Loading + + is Resource.Success -> + _createNewCenterUiState.value = + CreateNewCenterUiState.CenterCreatedSuccessfully + } + } + } +} diff --git a/feature/center/src/main/java/com/mifos/feature/center/create_center/CreateNewCenterViewModel.kt b/feature/center/src/main/java/com/mifos/feature/center/create_center/CreateNewCenterViewModel.kt deleted file mode 100644 index b44df65533a..00000000000 --- a/feature/center/src/main/java/com/mifos/feature/center/create_center/CreateNewCenterViewModel.kt +++ /dev/null @@ -1,57 +0,0 @@ -package com.mifos.feature.center.create_center - -import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope -import com.mifos.core.common.utils.Resource -import com.mifos.core.data.CenterPayload -import com.mifos.core.domain.use_cases.CreateNewCenterUseCase -import com.mifos.core.domain.use_cases.GetOfficeListUseCase -import com.mifos.feature.center.R -import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.launch -import javax.inject.Inject - -@HiltViewModel -class CreateNewCenterViewModel @Inject constructor( - private val getOfficeListUseCase: GetOfficeListUseCase, - private val createNewCenterUseCase: CreateNewCenterUseCase -) : ViewModel() { - - private val _createNewCenterUiState = - MutableStateFlow(CreateNewCenterUiState.Loading) - val createNewCenterUiState = _createNewCenterUiState.asStateFlow() - - - fun loadOffices() = viewModelScope.launch(Dispatchers.IO) { - getOfficeListUseCase().collect { result -> - when (result) { - is Resource.Error -> _createNewCenterUiState.value = - CreateNewCenterUiState.Error(R.string.feature_center_failed_to_load_offices) - - is Resource.Loading -> _createNewCenterUiState.value = - CreateNewCenterUiState.Loading - - is Resource.Success -> _createNewCenterUiState.value = - CreateNewCenterUiState.Offices(result.data ?: emptyList()) - } - } - } - - fun createNewCenter(centerPayload: CenterPayload) = viewModelScope.launch(Dispatchers.IO) { - createNewCenterUseCase(centerPayload).collect { result -> - when (result) { - is Resource.Error -> _createNewCenterUiState.value = - CreateNewCenterUiState.Error(R.string.feature_center_failed_to_create_center) - - is Resource.Loading -> _createNewCenterUiState.value = - CreateNewCenterUiState.Loading - - is Resource.Success -> _createNewCenterUiState.value = - CreateNewCenterUiState.CenterCreatedSuccessfully - } - } - } -} \ No newline at end of file diff --git a/feature/center/src/main/java/com/mifos/feature/center/navigation/CenterNavigation.kt b/feature/center/src/main/java/com/mifos/feature/center/navigation/CenterNavigation.kt index 817459990a5..e5a2efc1947 100644 --- a/feature/center/src/main/java/com/mifos/feature/center/navigation/CenterNavigation.kt +++ b/feature/center/src/main/java/com/mifos/feature/center/navigation/CenterNavigation.kt @@ -1,3 +1,12 @@ +/* + * Copyright 2024 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.feature.center.navigation import androidx.compose.foundation.layout.PaddingValues @@ -9,40 +18,38 @@ import androidx.navigation.navArgument import androidx.navigation.navigation import com.mifos.core.common.utils.Constants import com.mifos.core.objects.client.Client -import com.mifos.core.objects.group.Center -import com.mifos.feature.center.center_details.CenterDetailsScreen -import com.mifos.feature.center.center_group_list.GroupListScreen -import com.mifos.feature.center.center_list.ui.CenterListScreen -import com.mifos.feature.center.create_center.CreateNewCenterScreen +import com.mifos.feature.center.centerDetails.CenterDetailsScreen +import com.mifos.feature.center.centerGroupList.GroupListScreen +import com.mifos.feature.center.centerList.ui.CenterListScreen +import com.mifos.feature.center.createCenter.CreateNewCenterScreen fun NavGraphBuilder.centerNavGraph( navController: NavController, paddingValues: PaddingValues, - onActivateCenter: (Int,String) -> Unit, - addSavingsAccount: (Int) -> Unit + onActivateCenter: (Int, String) -> Unit, + addSavingsAccount: (Int) -> Unit, ) { navigation( startDestination = CenterScreens.CenterListScreen.route, - route = "center_screen_route" + route = "center_screen_route", ) { centerListScreenRoute( paddingValues = paddingValues, createNewCenter = navController::navigateCreateCenterScreenRoute, - syncClicked = { }, // TODO open sync dialog inside center list screen - onCenterSelect = navController::navigateCenterDetailsScreenRoute + onCenterSelect = navController::navigateCenterDetailsScreenRoute, ) centerDetailScreenRoute( onBackPressed = navController::popBackStack, onActivateCenter = onActivateCenter, addSavingsAccount = addSavingsAccount, - groupList = navController::navigateCenterGroupListScreenRoute + groupList = navController::navigateCenterGroupListScreenRoute, ) centerGroupListScreenRoute( onBackPressed = navController::popBackStack, - loadClientsOfGroup = { } + loadClientsOfGroup = { }, ) createCenterScreenRoute( - onCreateSuccess = navController::popBackStack + onCreateSuccess = navController::popBackStack, ) } } @@ -50,71 +57,65 @@ fun NavGraphBuilder.centerNavGraph( fun NavGraphBuilder.centerListScreenRoute( paddingValues: PaddingValues, createNewCenter: () -> Unit, - syncClicked: (List
) -> Unit, - onCenterSelect: (Int) -> Unit + onCenterSelect: (Int) -> Unit, ) { composable( - route = CenterScreens.CenterListScreen.route + route = CenterScreens.CenterListScreen.route, ) { CenterListScreen( paddingValues = paddingValues, createNewCenter = createNewCenter, - syncClicked = syncClicked, - onCenterSelect = onCenterSelect + onCenterSelect = onCenterSelect, ) } } fun NavGraphBuilder.centerDetailScreenRoute( onBackPressed: () -> Unit, - onActivateCenter: (Int,String) -> Unit, + onActivateCenter: (Int, String) -> Unit, addSavingsAccount: (Int) -> Unit, - groupList: (Int) -> Unit + groupList: (Int) -> Unit, ) { composable( route = CenterScreens.CenterDetailScreen.route, - arguments = listOf(navArgument(Constants.CENTER_ID, builder = { type = NavType.IntType })) + arguments = listOf(navArgument(Constants.CENTER_ID, builder = { type = NavType.IntType })), ) { CenterDetailsScreen( onBackPressed = onBackPressed, - onActivateCenter = {onActivateCenter(it,Constants.ACTIVATE_CENTER)}, + onActivateCenter = { onActivateCenter(it, Constants.ACTIVATE_CENTER) }, addSavingsAccount = addSavingsAccount, - groupList = groupList + groupList = groupList, ) } } fun NavGraphBuilder.centerGroupListScreenRoute( onBackPressed: () -> Unit, - loadClientsOfGroup: (List) -> Unit + loadClientsOfGroup: (List) -> Unit, ) { composable( route = CenterScreens.CenterGroupListScreen.route, - arguments = listOf(navArgument(Constants.CENTER_ID, builder = { type = NavType.IntType })) + arguments = listOf(navArgument(Constants.CENTER_ID, builder = { type = NavType.IntType })), ) { GroupListScreen( onBackPressed = onBackPressed, - loadClientsOfGroup = loadClientsOfGroup + loadClientsOfGroup = loadClientsOfGroup, ) } } fun NavGraphBuilder.createCenterScreenRoute( - onCreateSuccess: () -> Unit + onCreateSuccess: () -> Unit, ) { composable( - route = CenterScreens.CreateCenterScreen.route + route = CenterScreens.CreateCenterScreen.route, ) { CreateNewCenterScreen( - onCreateSuccess = onCreateSuccess + onCreateSuccess = onCreateSuccess, ) } } -fun NavController.navigateCenterListScreenRoute() { - navigate(CenterScreens.CenterListScreen.route) -} - fun NavController.navigateCenterDetailsScreenRoute(centerId: Int) { navigate(CenterScreens.CenterDetailScreen.argument(centerId)) } diff --git a/feature/center/src/main/java/com/mifos/feature/center/navigation/CenterScreens.kt b/feature/center/src/main/java/com/mifos/feature/center/navigation/CenterScreens.kt index 0739d2b9ba9..648d8d5117d 100644 --- a/feature/center/src/main/java/com/mifos/feature/center/navigation/CenterScreens.kt +++ b/feature/center/src/main/java/com/mifos/feature/center/navigation/CenterScreens.kt @@ -1,20 +1,26 @@ +/* + * Copyright 2024 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.feature.center.navigation import com.mifos.core.common.utils.Constants - sealed class CenterScreens(val route: String) { data object CenterListScreen : CenterScreens("center_list_screen") data object CenterDetailScreen : CenterScreens("center_detail_screen/{${Constants.CENTER_ID}}") { - fun argument(centerId: Int) = "center_detail_screen/${centerId}" + fun argument(centerId: Int) = "center_detail_screen/$centerId" } data object CenterGroupListScreen : CenterScreens("center_group_list_screen/{${Constants.CENTER_ID}}") { - fun arguments(centerId: Int) = "center_group_list_screen/${centerId}" + fun arguments(centerId: Int) = "center_group_list_screen/$centerId" } data object CreateCenterScreen : CenterScreens("create_center_screen/{${Constants.CENTER_ID}}") - - data object SyncCenterPayloadsScreen : CenterScreens("sync_center_payloads_screen") -} \ No newline at end of file +} diff --git a/feature/center/src/main/java/com/mifos/feature/center/sync_centers_dialog/SyncCentersDialogScreen.kt b/feature/center/src/main/java/com/mifos/feature/center/syncCentersDialog/SyncCentersDialogScreen.kt similarity index 79% rename from feature/center/src/main/java/com/mifos/feature/center/sync_centers_dialog/SyncCentersDialogScreen.kt rename to feature/center/src/main/java/com/mifos/feature/center/syncCentersDialog/SyncCentersDialogScreen.kt index d05823ac58d..417a3e6434f 100644 --- a/feature/center/src/main/java/com/mifos/feature/center/sync_centers_dialog/SyncCentersDialogScreen.kt +++ b/feature/center/src/main/java/com/mifos/feature/center/syncCentersDialog/SyncCentersDialogScreen.kt @@ -1,5 +1,15 @@ -package com.mifos.feature.center.sync_centers_dialog - +/* + * Copyright 2024 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.feature.center.syncCentersDialog + +import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row @@ -19,6 +29,7 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign @@ -27,35 +38,40 @@ import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.mifos.core.designsystem.component.MifosCircularProgress +import com.mifos.core.objects.group.Center import com.mifos.feature.center.R @Composable -fun SyncCenterDialogScreen( +internal fun SyncCenterDialogScreen( viewModel: SyncCentersDialogViewModel = hiltViewModel(), dismiss: () -> Unit, hide: () -> Unit, + centers: List
? = listOf(), ) { val uiState by viewModel.syncCentersDialogUiState.collectAsStateWithLifecycle() val uiData by viewModel.syncCenterData.collectAsStateWithLifecycle() LaunchedEffect(key1 = Unit) { viewModel.syncCenter() + centers?.let { + viewModel.setCentersList(centersList = centers) + } } SyncCenterDialogScreen( uiState = uiState, uiData = uiData, dismiss = dismiss, - hide = hide + hide = hide, ) } @Composable -fun SyncCenterDialogScreen( +internal fun SyncCenterDialogScreen( uiState: SyncCentersDialogUiState, uiData: SyncCentersDialogData, dismiss: () -> Unit, - hide: () -> Unit + hide: () -> Unit, ) { val snackBarHostState = remember { SnackbarHostState() } @@ -64,7 +80,7 @@ fun SyncCenterDialogScreen( uiData = uiData, okClicked = dismiss, hideClicked = hide, - cancelClicked = dismiss + cancelClicked = dismiss, ) when (uiState) { @@ -81,27 +97,30 @@ fun SyncCenterDialogScreen( } dismiss() } + + else -> {} } } } @Composable -fun SyncGroupDialogContent( +private fun SyncGroupDialogContent( uiData: SyncCentersDialogData, okClicked: () -> Unit, hideClicked: () -> Unit, - cancelClicked: () -> Unit + cancelClicked: () -> Unit, ) { Column( modifier = Modifier .fillMaxWidth() - .padding(8.dp), - horizontalAlignment = Alignment.CenterHorizontally + .padding(8.dp) + .background(Color.White), + horizontalAlignment = Alignment.CenterHorizontally, ) { Text( modifier = Modifier.fillMaxWidth(), textAlign = TextAlign.Center, - text = stringResource(id = R.string.feature_center_sync_centers_full_information) + text = stringResource(id = R.string.feature_center_sync_centers_full_information), ) PayloadField( @@ -114,7 +133,7 @@ fun SyncGroupDialogContent( PayloadField( label = stringResource(id = R.string.feature_center_total), value = uiData.centersList.size.toString() + stringResource(R.string.feature_center_space) + stringResource( - com.mifos.feature.center.R.string.feature_center_center + com.mifos.feature.center.R.string.feature_center_center, ), ) @@ -137,7 +156,7 @@ fun SyncGroupDialogContent( ) LinearProgressIndicator( - modifier = Modifier.fillMaxWidth() + modifier = Modifier.fillMaxWidth(), ) Spacer(modifier = Modifier.height(12.dp)) @@ -148,7 +167,7 @@ fun SyncGroupDialogContent( ) LinearProgressIndicator( - modifier = Modifier.fillMaxWidth() + modifier = Modifier.fillMaxWidth(), ) Spacer(modifier = Modifier.height(12.dp)) @@ -159,7 +178,7 @@ fun SyncGroupDialogContent( ) LinearProgressIndicator( - modifier = Modifier.fillMaxWidth() + modifier = Modifier.fillMaxWidth(), ) Spacer(modifier = Modifier.height(12.dp)) @@ -172,19 +191,19 @@ fun SyncGroupDialogContent( Spacer(modifier = Modifier.height(12.dp)) Row( - modifier = Modifier.fillMaxWidth() + modifier = Modifier.fillMaxWidth(), ) { if (uiData.isSyncSuccess) { FilledTonalButton( onClick = { okClicked() }, - modifier = Modifier.weight(1f) + modifier = Modifier.weight(1f), ) { Text(text = stringResource(id = R.string.feature_center_dialog_action_ok)) } } else { FilledTonalButton( onClick = { cancelClicked() }, - modifier = Modifier.weight(1f) + modifier = Modifier.weight(1f), ) { Text(text = stringResource(id = R.string.feature_center_cancel)) } @@ -193,7 +212,7 @@ fun SyncGroupDialogContent( FilledTonalButton( onClick = { hideClicked() }, - modifier = Modifier.weight(1f) + modifier = Modifier.weight(1f), ) { Text(text = stringResource(id = R.string.feature_center_hide)) } @@ -203,33 +222,33 @@ fun SyncGroupDialogContent( } @Composable -fun PayloadField(label: String, value: String) { +private fun PayloadField(label: String, value: String) { Row( modifier = Modifier .fillMaxWidth() - .padding(vertical = 4.dp) + .padding(vertical = 4.dp), ) { Text( text = label, style = MaterialTheme.typography.bodyMedium, fontWeight = FontWeight.Bold, - modifier = Modifier.weight(1f) + modifier = Modifier.weight(1f), ) Text( text = value, style = MaterialTheme.typography.bodyMedium, - modifier = Modifier.weight(1f) + modifier = Modifier.weight(1f), ) } } @Preview(showBackground = true, backgroundColor = 0xFFFFFFFF) @Composable -fun SyncCenterDialogScreenPreview() { +private fun SyncCenterDialogScreenPreview() { SyncCenterDialogScreen( dismiss = { }, uiState = SyncCentersDialogUiState.Success, uiData = SyncCentersDialogData(), - hide = { } + hide = { }, ) -} \ No newline at end of file +} diff --git a/feature/center/src/main/java/com/mifos/feature/center/sync_centers_dialog/SyncCentersDialogUiState.kt b/feature/center/src/main/java/com/mifos/feature/center/syncCentersDialog/SyncCentersDialogUiState.kt similarity index 62% rename from feature/center/src/main/java/com/mifos/feature/center/sync_centers_dialog/SyncCentersDialogUiState.kt rename to feature/center/src/main/java/com/mifos/feature/center/syncCentersDialog/SyncCentersDialogUiState.kt index ce3e44d0ba4..f961722cedb 100644 --- a/feature/center/src/main/java/com/mifos/feature/center/sync_centers_dialog/SyncCentersDialogUiState.kt +++ b/feature/center/src/main/java/com/mifos/feature/center/syncCentersDialog/SyncCentersDialogUiState.kt @@ -1,4 +1,13 @@ -package com.mifos.feature.center.sync_centers_dialog +/* + * Copyright 2024 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.feature.center.syncCentersDialog import androidx.compose.ui.graphics.vector.ImageVector import com.mifos.core.objects.group.Center @@ -12,7 +21,7 @@ sealed class SyncCentersDialogUiState { data class Error( val messageResId: Int? = null, val imageVector: ImageVector? = null, - val message: String? = null + val message: String? = null, ) : SyncCentersDialogUiState() } @@ -25,5 +34,5 @@ data class SyncCentersDialogData( val totalGroupsSyncCount: Int = 0, val clientSyncCount: Int = 0, val failedSyncGroupCount: Int = 0, - val centersList: List
= listOf() + val centersList: List
= listOf(), ) diff --git a/feature/center/src/main/java/com/mifos/feature/center/sync_centers_dialog/SyncCentersDialogViewModel.kt b/feature/center/src/main/java/com/mifos/feature/center/syncCentersDialog/SyncCentersDialogViewModel.kt similarity index 93% rename from feature/center/src/main/java/com/mifos/feature/center/sync_centers_dialog/SyncCentersDialogViewModel.kt rename to feature/center/src/main/java/com/mifos/feature/center/syncCentersDialog/SyncCentersDialogViewModel.kt index 0c2daa7b089..249561f95f0 100644 --- a/feature/center/src/main/java/com/mifos/feature/center/sync_centers_dialog/SyncCentersDialogViewModel.kt +++ b/feature/center/src/main/java/com/mifos/feature/center/syncCentersDialog/SyncCentersDialogViewModel.kt @@ -1,4 +1,13 @@ -package com.mifos.feature.center.sync_centers_dialog +/* + * Copyright 2024 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.feature.center.syncCentersDialog import androidx.lifecycle.ViewModel import com.mifos.core.common.utils.Constants @@ -46,11 +55,10 @@ class SyncCentersDialogViewModel @Inject constructor( val syncCentersDialogUiState: StateFlow = _syncCentersDialogUiState private val _syncCenterData: MutableStateFlow = MutableStateFlow( - SyncCentersDialogData() + SyncCentersDialogData(), ) val syncCenterData: StateFlow = _syncCenterData - private var mLoanAccountList: List = ArrayList() private var mSavingsAccountList: List = ArrayList() private var mMemberLoanAccountsList: List = ArrayList() @@ -154,23 +162,24 @@ class SyncCentersDialogViewModel @Inject constructor( override fun onNext(centerAccounts: CenterAccounts) { mLoanAccountList = getActiveLoanAccounts( centerAccounts - .loanAccounts + .loanAccounts, ) mSavingsAccountList = getActiveSavingsAccounts( centerAccounts - .savingsAccounts + .savingsAccounts, ) mMemberLoanAccountsList = getActiveLoanAccounts( centerAccounts - .memberLoanAccounts + .memberLoanAccounts, ) - //Updating UI - maxSingleSyncCenterProgressBar = (mLoanAccountList.size + - mSavingsAccountList.size + mMemberLoanAccountsList.size) + // Updating UI + maxSingleSyncCenterProgressBar = ( + mLoanAccountList.size + + mSavingsAccountList.size + mMemberLoanAccountsList.size + ) checkAccountsSyncStatusAndSyncAccounts() } }) - } /** @@ -183,13 +192,13 @@ class SyncCentersDialogViewModel @Inject constructor( */ private fun checkAccountsSyncStatusAndSyncAccounts() { if (mLoanAccountList.isNotEmpty() && !mLoanAccountSyncStatus) { - //Sync the Active Loan and LoanRepayment + // Sync the Active Loan and LoanRepayment checkNetworkConnectionAndSyncLoanAndLoanRepayment() } else if (mSavingsAccountList.isNotEmpty() && !mSavingAccountSyncStatus) { - //Sync the Active Savings Account + // Sync the Active Savings Account checkNetworkConnectionAndSyncSavingsAccountAndTransactionTemplate() } else if (mMemberLoanAccountsList.isNotEmpty()) { - //Sync the Active member Loan Account + // Sync the Active member Loan Account checkNetworkConnectionAndSyncMemberLoanAndMemberLoanRepayment() } else { maxSingleSyncCenterProgressBar = 1 @@ -314,7 +323,6 @@ class SyncCentersDialogViewModel @Inject constructor( } } }) - } /** @@ -343,7 +351,6 @@ class SyncCentersDialogViewModel @Inject constructor( } } }) - } /** @@ -374,11 +381,11 @@ class SyncCentersDialogViewModel @Inject constructor( private fun getLoanAndLoanRepayment(loanId: Int): Observable { return Observable.combineLatest( repository.syncLoanById(loanId), - repository.syncLoanRepaymentTemplate(loanId) + repository.syncLoanRepaymentTemplate(loanId), ) { loanWithAssociations, loanRepaymentTemplate -> LoanAndLoanRepayment( loanWithAssociations, - loanRepaymentTemplate + loanRepaymentTemplate, ) } .observeOn(AndroidSchedulers.mainThread()) @@ -393,20 +400,24 @@ class SyncCentersDialogViewModel @Inject constructor( * @return SavingsAccountAndTransactionTemplate */ private fun getSavingsAccountAndTemplate( - savingsAccountType: String, savingsAccountId: Int + savingsAccountType: String, + savingsAccountId: Int, ): Observable { return Observable.combineLatest( repository.syncSavingsAccount( - savingsAccountType, savingsAccountId, - Constants.TRANSACTIONS + savingsAccountType, + savingsAccountId, + Constants.TRANSACTIONS, ), repository.syncSavingsAccountTransactionTemplate( savingsAccountType, - savingsAccountId, Constants.SAVINGS_ACCOUNT_TRANSACTION_DEPOSIT - ) + savingsAccountId, + Constants.SAVINGS_ACCOUNT_TRANSACTION_DEPOSIT, + ), ) { savingsAccountWithAssociations, savingsAccountTransactionTemplate -> SavingsAccountAndTransactionTemplate( - savingsAccountWithAssociations, savingsAccountTransactionTemplate + savingsAccountWithAssociations, + savingsAccountTransactionTemplate, ) } .observeOn(AndroidSchedulers.mainThread()) @@ -441,7 +452,6 @@ class SyncCentersDialogViewModel @Inject constructor( } } }) - } /** @@ -472,7 +482,6 @@ class SyncCentersDialogViewModel @Inject constructor( } } }) - } /** @@ -501,16 +510,15 @@ class SyncCentersDialogViewModel @Inject constructor( override fun onNext(groupAccounts: GroupAccounts) { mLoanAccountList = getActiveLoanAccounts( groupAccounts - .loanAccounts + .loanAccounts, ) mSavingsAccountList = getActiveSavingsAccounts( groupAccounts - .savingsAccounts + .savingsAccounts, ) checkAccountsSyncStatusAndSyncGroupAccounts() } }) - } /** @@ -539,16 +547,15 @@ class SyncCentersDialogViewModel @Inject constructor( override fun onNext(clientAccounts: ClientAccounts) { mLoanAccountList = getActiveLoanAccounts( clientAccounts - .loanAccounts + .loanAccounts, ) mSavingsAccountList = getSyncableSavingsAccounts( clientAccounts - .savingsAccounts + .savingsAccounts, ) checkAccountsSyncStatusAndSyncClientAccounts() } }) - } /** @@ -559,19 +566,19 @@ class SyncCentersDialogViewModel @Inject constructor( */ private fun checkAccountsSyncStatusAndSyncGroupAccounts() { if (mLoanAccountList.isNotEmpty() && !mLoanAccountSyncStatus) { - //Sync the Active Loan and LoanRepayment + // Sync the Active Loan and LoanRepayment mLoanAccountList[mLoanAndRepaymentSyncIndex].id?.let { syncGroupLoanAndLoanRepayment( - it + it, ) } } else if (mSavingsAccountList.isNotEmpty()) { - //Sync the Active Savings Account + // Sync the Active Savings Account mSavingsAccountList[mSavingsAndTransactionSyncIndex].id?.let { mSavingsAccountList[mSavingsAndTransactionSyncIndex].depositType?.endpoint?.let { it1 -> syncGroupSavingsAccountAndTemplate( it1, - it + it, ) } } @@ -588,19 +595,19 @@ class SyncCentersDialogViewModel @Inject constructor( */ private fun checkAccountsSyncStatusAndSyncClientAccounts() { if (mLoanAccountList.isNotEmpty() && !mLoanAccountSyncStatus) { - //Sync the Active Loan and LoanRepayment + // Sync the Active Loan and LoanRepayment mLoanAccountList[mLoanAndRepaymentSyncIndex].id?.let { syncClientLoanAndLoanRepayment( - it + it, ) } } else if (mSavingsAccountList.isNotEmpty()) { - //Sync the Active Savings Account + // Sync the Active Savings Account mSavingsAccountList[mSavingsAndTransactionSyncIndex].id?.let { mSavingsAccountList[mSavingsAndTransactionSyncIndex].depositType?.endpoint?.let { it1 -> syncClientSavingsAccountAndTemplate( it1, - it + it, ) } } @@ -638,7 +645,6 @@ class SyncCentersDialogViewModel @Inject constructor( } } }) - } /** @@ -670,7 +676,6 @@ class SyncCentersDialogViewModel @Inject constructor( } } }) - } /** @@ -695,7 +700,7 @@ class SyncCentersDialogViewModel @Inject constructor( if (mLoanAndRepaymentSyncIndex != mLoanAccountList.size) { mLoanAccountList[mLoanAndRepaymentSyncIndex].id?.let { syncGroupLoanAndLoanRepayment( - it + it, ) } } else { @@ -704,7 +709,6 @@ class SyncCentersDialogViewModel @Inject constructor( } } }) - } /** @@ -729,7 +733,7 @@ class SyncCentersDialogViewModel @Inject constructor( if (mLoanAndRepaymentSyncIndex != mLoanAccountList.size) { mLoanAccountList[mLoanAndRepaymentSyncIndex].id?.let { syncClientLoanAndLoanRepayment( - it + it, ) } } else { @@ -738,7 +742,6 @@ class SyncCentersDialogViewModel @Inject constructor( } } }) - } /** @@ -750,7 +753,7 @@ class SyncCentersDialogViewModel @Inject constructor( */ private fun syncGroupSavingsAccountAndTemplate( savingsAccountType: String, - savingsAccountId: Int + savingsAccountId: Int, ) { getSavingsAccountAndTemplate(savingsAccountType, savingsAccountId) .subscribe(object : Subscriber() { @@ -767,7 +770,7 @@ class SyncCentersDialogViewModel @Inject constructor( mSavingsAccountList[mSavingsAndTransactionSyncIndex].id?.let { it1 -> syncGroupSavingsAccountAndTemplate( it, - it1 + it1, ) } } @@ -776,7 +779,6 @@ class SyncCentersDialogViewModel @Inject constructor( } } }) - } /** @@ -788,7 +790,7 @@ class SyncCentersDialogViewModel @Inject constructor( */ private fun syncClientSavingsAccountAndTemplate( savingsAccountType: String, - savingsAccountId: Int + savingsAccountId: Int, ) { getSavingsAccountAndTemplate(savingsAccountType, savingsAccountId) .subscribe(object : Subscriber() { @@ -805,7 +807,7 @@ class SyncCentersDialogViewModel @Inject constructor( .depositType?.endpoint?.let { it1 -> syncClientSavingsAccountAndTemplate( it1, - it + it, ) } } @@ -814,7 +816,6 @@ class SyncCentersDialogViewModel @Inject constructor( } } }) - } private fun updateTotalSyncProgressBarAndCount() { @@ -829,14 +830,14 @@ class SyncCentersDialogViewModel @Inject constructor( } private fun checkNetworkConnection( - taskWhenOnline: () -> Unit + taskWhenOnline: () -> Unit, ) { if (networkUtilsWrapper.isNetworkConnected()) { taskWhenOnline.invoke() } else { _syncCentersDialogUiState.value = SyncCentersDialogUiState.Error( messageResId = R.string.feature_center_error_not_connected_internet, - imageVector = MifosIcons.WifiOff + imageVector = MifosIcons.WifiOff, ) } } @@ -854,7 +855,7 @@ class SyncCentersDialogViewModel @Inject constructor( Observable.from(savingsAccounts) .filter { savingsAccount -> savingsAccount.status?.active == true && - !savingsAccount.depositType!!.isRecurring + !savingsAccount.depositType!!.isRecurring } .subscribe { savingsAccount -> accounts.add(savingsAccount) } return accounts @@ -873,11 +874,10 @@ class SyncCentersDialogViewModel @Inject constructor( Observable.from(savingsAccounts) .filter { savingsAccount -> savingsAccount.depositType?.value == "Savings" && - savingsAccount.status?.active == true && - !savingsAccount.depositType!!.isRecurring + savingsAccount.status?.active == true && + !savingsAccount.depositType!!.isRecurring } .subscribe { savingsAccount -> accounts.add(savingsAccount) } return accounts } - -} \ No newline at end of file +} diff --git a/feature/center/src/main/res/drawable/feature_center_ic_done_all_black_24dp.xml b/feature/center/src/main/res/drawable/feature_center_ic_done_all_black_24dp.xml index 3ff8c7dd868..2a9ffbace01 100644 --- a/feature/center/src/main/res/drawable/feature_center_ic_done_all_black_24dp.xml +++ b/feature/center/src/main/res/drawable/feature_center_ic_done_all_black_24dp.xml @@ -1,3 +1,13 @@ + + + Failed to load Centers Failed to load Database Centers diff --git a/feature/center/src/test/java/com/mifos/feature/center/ExampleUnitTest.kt b/feature/center/src/test/java/com/mifos/feature/center/ExampleUnitTest.kt index 1346bd44160..2aaec998ccf 100644 --- a/feature/center/src/test/java/com/mifos/feature/center/ExampleUnitTest.kt +++ b/feature/center/src/test/java/com/mifos/feature/center/ExampleUnitTest.kt @@ -1,9 +1,17 @@ +/* + * Copyright 2024 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.feature.center +import org.junit.Assert.assertEquals import org.junit.Test -import org.junit.Assert.* - /** * Example local unit test, which will execute on the development machine (host). * @@ -14,4 +22,4 @@ class ExampleUnitTest { fun addition_isCorrect() { assertEquals(4, 2 + 2) } -} \ No newline at end of file +} diff --git a/mifosng-android/src/main/java/com/mifos/mifosxdroid/adapters/CenterAdapter.kt b/mifosng-android/src/main/java/com/mifos/mifosxdroid/adapters/CenterAdapter.kt deleted file mode 100644 index d78ecef9c22..00000000000 --- a/mifosng-android/src/main/java/com/mifos/mifosxdroid/adapters/CenterAdapter.kt +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This project is licensed under the open source MPL V2. - * See https://github.com/openMF/android-client/blob/master/LICENSE.md - */ -package com.mifos.mifosxdroid.adapters - -import android.content.Context -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.BaseAdapter -import com.mifos.core.objects.db.MeetingCenter -import com.mifos.mifosxdroid.R -import com.mifos.mifosxdroid.databinding.RowCenterItemBinding - -class CenterAdapter(context: Context?, centers: List) : BaseAdapter() { - private val layoutInflater: LayoutInflater - private val centers: List - - init { - layoutInflater = LayoutInflater.from(context) - this.centers = centers - } - - override fun getCount(): Int { - return centers.size - } - - override fun getItem(i: Int): MeetingCenter { - return centers[i] - } - - override fun getItemId(i: Int): Long { - return 0 - } - - override fun getView(i: Int, view: View, viewGroup: ViewGroup): View { - val binding: RowCenterItemBinding = view.tag as RowCenterItemBinding - val center = centers[i] - binding.tvCenterName.text = center.name - - if (center.isSynced == 1) { - binding.ivCenterSynced.setImageResource(R.drawable.ic_content_import_export) - } - - return view - } -} - - - - diff --git a/mifosng-android/src/main/java/com/mifos/mifosxdroid/adapters/CentersListAdapter.kt b/mifosng-android/src/main/java/com/mifos/mifosxdroid/adapters/CentersListAdapter.kt deleted file mode 100644 index 1a9490fb9c0..00000000000 --- a/mifosng-android/src/main/java/com/mifos/mifosxdroid/adapters/CentersListAdapter.kt +++ /dev/null @@ -1,108 +0,0 @@ -package com.mifos.mifosxdroid.adapters - -import android.graphics.Color -import android.os.Build -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.ImageView -import android.widget.TextView -import androidx.core.content.ContextCompat -import androidx.recyclerview.widget.RecyclerView -import com.mifos.core.objects.group.Center -import com.mifos.mifosxdroid.R -import com.mifos.mifosxdroid.core.SelectableAdapter -import com.mifos.mifosxdroid.views.CircularImageView -import com.mifos.utils.Utils - - -class CentersListAdapter( - val onCenterClick: (Int) -> Unit, - val onCenterLongClick: (Int) -> Unit -) : SelectableAdapter() { - - private var centers: List
= ArrayList() - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { - val viewHolder = ViewHolder( - LayoutInflater.from(parent.context) - .inflate(R.layout.row_center_list_item, parent, false) - ) - viewHolder.itemView.setOnClickListener { - if (viewHolder.adapterPosition != RecyclerView.NO_POSITION) - onCenterClick(viewHolder.adapterPosition) - } - viewHolder.itemView.setOnLongClickListener { - if (viewHolder.adapterPosition != RecyclerView.NO_POSITION) - onCenterLongClick(viewHolder.adapterPosition) - return@setOnLongClickListener true - } - return viewHolder - } - - override fun onBindViewHolder(holder: ViewHolder, position: Int) { - val center = centers[position] - holder.apply { - tvAccountNumber.text = String.format( - itemView.context.getString(R.string.centerList_account_prefix), center.accountNo - ) - tvCenterId.text = center.id.toString() - tvCenterName.text = center.name - if (center.staffId != null) { - tvStaffId.text = center.staffId.toString() - tvStaffName.text = center.staffName - } else { - tvStaffId.text = "" - tvStaffName.setText(R.string.no_staff) - } - tvOfficeId.text = center.officeId.toString() - tvOfficeName.text = center.officeName - ivStatusIndicator.setImageDrawable( - Utils.setCircularBackground( - if (center.active == true) R.color.light_green else R.color.light_red, - itemView.context - ) - ) - - //Changing the Color of Selected Centers - viewSelectedOverlay.setBackgroundColor( - if (isSelected(position)) { - if (Build.VERSION.SDK_INT >= 23) { - ContextCompat.getColor(itemView.context, R.color.primary) - } else { - itemView.context.resources.getColor(R.color.primary) - } - } else Color.WHITE - ) - ivSyncStatus.visibility = if (center.sync) View.VISIBLE else View.INVISIBLE - } - } - - - fun setCenters(centers: List
) { - this.centers = centers - notifyDataSetChanged() - } - - fun getItem(position: Int) = centers[position] - - - override fun getItemId(i: Int) = 0L - - override fun getItemCount() = centers.size - - - class ViewHolder(v: View) : RecyclerView.ViewHolder(v) { - val ivStatusIndicator: CircularImageView = v.findViewById(R.id.iv_status_indicator) - val tvAccountNumber: TextView = v.findViewById(R.id.tv_account_number) - val tvCenterName: TextView = v.findViewById(R.id.tv_center_name) - val tvCenterId: TextView = v.findViewById(R.id.tv_center_id) - val tvStaffName: TextView = v.findViewById(R.id.tv_staff_name) - val tvStaffId: TextView = v.findViewById(R.id.tv_staff_id) - val tvOfficeName: TextView = v.findViewById(R.id.tv_office_name) - val tvOfficeId: TextView = v.findViewById(R.id.tv_office_id) - val viewSelectedOverlay: View = v.findViewById(R.id.card_view) - val ivSyncStatus: ImageView = v.findViewById(R.id.iv_sync_status) - } - -} \ No newline at end of file diff --git a/mifosng-android/src/main/java/com/mifos/mifosxdroid/components/Navigation.kt b/mifosng-android/src/main/java/com/mifos/mifosxdroid/components/Navigation.kt index b0ad79316a2..6968fedcf5d 100644 --- a/mifosng-android/src/main/java/com/mifos/mifosxdroid/components/Navigation.kt +++ b/mifosng-android/src/main/java/com/mifos/mifosxdroid/components/Navigation.kt @@ -39,6 +39,7 @@ import com.mifos.feature.loan.navigation.navigateToLoanAccountScreen import com.mifos.feature.loan.navigation.navigateToLoanAccountSummaryScreen import com.mifos.feature.note.navigation.navigateToNoteScreen import com.mifos.feature.note.navigation.noteScreen +import com.mifos.feature.offline.navigation.navigateToSyncCenterPayloadsScreen import com.mifos.feature.offline.navigation.offlineNavGraph import com.mifos.feature.path_tracking.navigation.pathTrackingNavGraph import com.mifos.feature.report.navigation.reportNavGraph @@ -164,10 +165,10 @@ fun Navigation( paddingValues = padding, onActivateCenter = navController::navigateToActivateScreen, addSavingsAccount = { -// TODO() check this logic navController.navigateToAddSavingsAccount(it, 0, true) - } - ) + }, + + ) reportNavGraph( navController = navController @@ -201,12 +202,12 @@ fun Navigation( dataTableNavGraph( navController = navController, - clientCreated = { client , userStatus -> + clientCreated = { client, userStatus -> navController.popBackStack() navController.popBackStack() Toast.makeText(context, context.resources.getString(R.string.client) + MifosResponseHandler.response, Toast.LENGTH_LONG).show() - if(userStatus == Constants.USER_ONLINE){ + if (userStatus == Constants.USER_ONLINE){ client.clientId?.let { navController.navigateClientDetailsScreen(it) } } } diff --git a/mifosng-android/src/main/java/com/mifos/mifosxdroid/dialogfragments/synccenterdialog/SyncCentersDialogFragment.kt b/mifosng-android/src/main/java/com/mifos/mifosxdroid/dialogfragments/synccenterdialog/SyncCentersDialogFragment.kt deleted file mode 100644 index 4f620185c5f..00000000000 --- a/mifosng-android/src/main/java/com/mifos/mifosxdroid/dialogfragments/synccenterdialog/SyncCentersDialogFragment.kt +++ /dev/null @@ -1,62 +0,0 @@ -package com.mifos.mifosxdroid.dialogfragments.synccenterdialog - -import android.os.Bundle -import android.os.Parcelable -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import androidx.compose.ui.platform.ComposeView -import androidx.compose.ui.platform.ViewCompositionStrategy -import androidx.fragment.app.DialogFragment -import com.mifos.core.objects.group.Center -import com.mifos.feature.center.sync_centers_dialog.SyncCenterDialogScreen -import com.mifos.feature.center.sync_centers_dialog.SyncCentersDialogViewModel -import com.mifos.utils.Constants -import dagger.hilt.android.AndroidEntryPoint - -@AndroidEntryPoint -class SyncCentersDialogFragment : DialogFragment() { - - private lateinit var viewModel: SyncCentersDialogViewModel - - override fun onCreate(savedInstanceState: Bundle?) { - val centers: List
? = requireArguments().getParcelableArrayList(Constants.CENTER) - centers?.let { - viewModel.setCentersList(centersList = centers) - } - super.onCreate(savedInstanceState) - } - - override fun onCreateView( - inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - return ComposeView(requireActivity()).apply { - setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed) - setContent { - SyncCenterDialogScreen( - hide = { hideDialog() }, - dismiss = { dismissDialog() } - ) - } - } - } - - private fun dismissDialog() { - dialog?.dismiss() - } - - private fun hideDialog() { - dialog?.hide() - } - - companion object { - fun newInstance(center: List
?): SyncCentersDialogFragment { - val syncCentersDialogFragment = SyncCentersDialogFragment() - val args = Bundle() - args.putParcelableArrayList(Constants.CENTER, center as ArrayList?) - syncCentersDialogFragment.arguments = args - return syncCentersDialogFragment - } - } -} \ No newline at end of file diff --git a/mifosng-android/src/main/java/com/mifos/mifosxdroid/online/centerdetails/CenterDetailsFragment.kt b/mifosng-android/src/main/java/com/mifos/mifosxdroid/online/centerdetails/CenterDetailsFragment.kt index fae741108c9..e69de29bb2d 100644 --- a/mifosng-android/src/main/java/com/mifos/mifosxdroid/online/centerdetails/CenterDetailsFragment.kt +++ b/mifosng-android/src/main/java/com/mifos/mifosxdroid/online/centerdetails/CenterDetailsFragment.kt @@ -1,84 +0,0 @@ -package com.mifos.mifosxdroid.online.centerdetails - -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import androidx.appcompat.app.AppCompatActivity -import androidx.compose.ui.platform.ComposeView -import androidx.navigation.fragment.findNavController -import com.mifos.feature.center.center_details.CenterDetailsScreen -import com.mifos.mifosxdroid.core.MifosBaseFragment -import com.mifos.utils.Constants -import dagger.hilt.android.AndroidEntryPoint - -/** - * Created by Rajan Maurya on 05/02/17. - */ -@AndroidEntryPoint -class CenterDetailsFragment : MifosBaseFragment() { - - private var centerId = 0 - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - if (arguments != null) { - centerId = requireArguments().getInt(Constants.CENTER_ID) - } - } - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - return ComposeView(requireActivity()).apply { - setContent { - CenterDetailsScreen( - onBackPressed = { - requireActivity().onBackPressed() - }, - onActivateCenter = { - onClickActivateCenter() - }, - addSavingsAccount = { centerId -> - addCenterSavingAccount(centerId) - }, - groupList = { centerId -> - loadGroupsOfCenter(centerId) - }) - } - } - } - - override fun onResume() { - super.onResume() - (requireActivity() as AppCompatActivity).supportActionBar?.hide() - } - - override fun onStop() { - super.onStop() - (requireActivity() as AppCompatActivity).supportActionBar?.show() - } - - private fun onClickActivateCenter() { -// val action = CenterDetailsFragmentDirections.actionCenterDetailsFragmentToActivateFragment( -// centerId, -// Constants.ACTIVATE_CENTER -// ) -// findNavController().navigate(action) - } - - private fun addCenterSavingAccount(centerId: Int) { -// val action = -// CenterDetailsFragmentDirections.actionCenterDetailsFragmentToSavingsAccountFragment( -// centerId, -// true -// ) -// findNavController().navigate(action) - } - - private fun loadGroupsOfCenter(centerId: Int) { - } - -} \ No newline at end of file diff --git a/mifosng-android/src/main/java/com/mifos/mifosxdroid/online/centerlist/CenterListFragment.kt b/mifosng-android/src/main/java/com/mifos/mifosxdroid/online/centerlist/CenterListFragment.kt deleted file mode 100755 index fd600cb99e1..00000000000 --- a/mifosng-android/src/main/java/com/mifos/mifosxdroid/online/centerlist/CenterListFragment.kt +++ /dev/null @@ -1,82 +0,0 @@ -/* - * This project is licensed under the open source MPL V2. - * See https://github.com/openMF/android-client/blob/master/LICENSE.md - */ -package com.mifos.mifosxdroid.online.centerlist - -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.ui.platform.ComposeView -import androidx.compose.ui.platform.ViewCompositionStrategy -import androidx.navigation.fragment.findNavController -import com.mifos.core.objects.group.Center -import com.mifos.feature.center.center_list.ui.CenterListScreen -import com.mifos.mifosxdroid.R -import com.mifos.mifosxdroid.activity.home.HomeActivity -import com.mifos.mifosxdroid.core.MifosBaseFragment -import com.mifos.mifosxdroid.dialogfragments.synccenterdialog.SyncCentersDialogFragment -import com.mifos.utils.FragmentConstants -import dagger.hilt.android.AndroidEntryPoint - -/** - * Created by ishankhanna on 11/03/14. - **/ -@AndroidEntryPoint -class CenterListFragment : MifosBaseFragment() { - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - return ComposeView(requireActivity()).apply { - (activity as HomeActivity).supportActionBar?.title = getString(R.string.centers) - setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed) - setContent { -// CenterListScreen( -// paddingValues = PaddingValues(), -// createNewCenter = { -// onClickCreateNewCenter() -// }, -// onCenterSelect = { center -> -// selectedCenters(center) -// }, -// syncClicked = { selectedCenters -> -// syncCenters(selectedCenters) -// } -// ) - } - } - } - - private fun onClickCreateNewCenter() { - findNavController().navigate(R.id.action_navigation_center_list_to_createNewCenterFragment) - } - - private fun selectedCenters(center: Center) { - val action = center.id?.let { - CenterListFragmentDirections.actionNavigationCenterListToCentersActivity( - it - ) - } - action?.let { findNavController().navigate(it) } - } - - private fun syncCenters(selectedCenters: List
) { - val syncCentersDialogFragment = - SyncCentersDialogFragment.newInstance(ArrayList(selectedCenters)) - val fragmentTransaction = - activity?.supportFragmentManager?.beginTransaction() - fragmentTransaction?.addToBackStack(FragmentConstants.FRAG_CLIENT_SYNC) - syncCentersDialogFragment.isCancelable = false - fragmentTransaction?.let { - syncCentersDialogFragment.show( - fragmentTransaction, - resources.getString(R.string.sync_centers) - ) - } - } -} diff --git a/mifosng-android/src/main/java/com/mifos/mifosxdroid/online/createnewcenter/CreateNewCenterFragment.kt b/mifosng-android/src/main/java/com/mifos/mifosxdroid/online/createnewcenter/CreateNewCenterFragment.kt deleted file mode 100755 index 9012cb06440..00000000000 --- a/mifosng-android/src/main/java/com/mifos/mifosxdroid/online/createnewcenter/CreateNewCenterFragment.kt +++ /dev/null @@ -1,40 +0,0 @@ -/* - * This project is licensed under the open source MPL V2. - * See https://github.com/openMF/android-client/blob/master/LICENSE.md - */ -package com.mifos.mifosxdroid.online.createnewcenter - -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import androidx.compose.ui.platform.ComposeView -import androidx.compose.ui.platform.ViewCompositionStrategy -import androidx.fragment.app.Fragment -import androidx.navigation.fragment.findNavController -import com.mifos.feature.center.create_center.CreateNewCenterScreen -import dagger.hilt.android.AndroidEntryPoint - -/** - * Created by nellyk on 1/22/2016. - */ -@AndroidEntryPoint -class CreateNewCenterFragment : Fragment() { - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - return ComposeView(requireContext()).apply { - setViewCompositionStrategy( - ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed - ) - setContent { - CreateNewCenterScreen(onCreateSuccess = { - findNavController().popBackStack() - }) - } - } - } -} \ No newline at end of file diff --git a/mifosng-android/src/main/java/com/mifos/mifosxdroid/online/grouplist/GroupListFragment.kt b/mifosng-android/src/main/java/com/mifos/mifosxdroid/online/grouplist/GroupListFragment.kt deleted file mode 100755 index c7f46181d89..00000000000 --- a/mifosng-android/src/main/java/com/mifos/mifosxdroid/online/grouplist/GroupListFragment.kt +++ /dev/null @@ -1,69 +0,0 @@ -/* - * This project is licensed under the open source MPL V2. - * See https://github.com/openMF/android-client/blob/master/LICENSE.md - */ -package com.mifos.mifosxdroid.online.grouplist - -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import androidx.appcompat.app.AppCompatActivity -import androidx.compose.ui.platform.ComposeView -import androidx.compose.ui.platform.ViewCompositionStrategy -import androidx.fragment.app.Fragment -import androidx.navigation.fragment.findNavController -import androidx.navigation.fragment.navArgs -import com.mifos.core.objects.client.Client -import com.mifos.core.objects.navigation.ClientListArgs -import com.mifos.feature.center.center_group_list.GroupListScreen -import dagger.hilt.android.AndroidEntryPoint - -@AndroidEntryPoint -class GroupListFragment : Fragment() { - -// private val arg: GroupListFragmentArgs by navArgs() - private var centerId = 0 - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) -// centerId = arg.centerId - } - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - return ComposeView(requireContext()).apply { - setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed) - setContent { - GroupListScreen( - onBackPressed = { - findNavController().popBackStack() - }, - loadClientsOfGroup = { - loadClientsOfGroup(it) - } - ) - } - } - } - - override fun onResume() { - super.onResume() - (requireActivity() as AppCompatActivity).supportActionBar?.hide() - } - - override fun onStop() { - super.onStop() - (requireActivity() as AppCompatActivity).supportActionBar?.show() - } - - private fun loadClientsOfGroup(clientList: List) { -// val action = GroupListFragmentDirections.actionGroupListFragmentToClientListFragment( -// ClientListArgs(clientList, true) -// ) -// findNavController().navigate(action) - } -} \ No newline at end of file diff --git a/mifosng-android/src/main/java/com/mifos/utils/Constants.kt b/mifosng-android/src/main/java/com/mifos/utils/Constants.kt index 78136eded68..002f25705c1 100644 --- a/mifosng-android/src/main/java/com/mifos/utils/Constants.kt +++ b/mifosng-android/src/main/java/com/mifos/utils/Constants.kt @@ -8,24 +8,6 @@ package com.mifos.utils * Created by satya on 13/04/14. */ object Constants { - const val INSTANCE_URL_KEY = "instanceURL" - const val INSTANCE_DOMAIN_KEY = "instanceDomain" - const val INSTANCE_PORT_KEY = "instancePort" - const val TENANT_IDENTIFIER_KEY = "tenant identifier" - const val PROTOCOL_HTTP = "http://" - const val PROTOCOL_HTTPS = "https://" - const val API_PATH = "/mifosng-provider/api/v1" - - /** - * Entity Type, Like Clients, Groups, Staff, Loans, Savings and Client Identifiers - */ - const val ENTITY_TYPE_CLIENTS = "clients" - const val ENTITY_TYPE_GROUPS = "groups" - const val ENTITY_TYPE_LOANS = "loans" - const val ENTITY_TYPE_SAVINGS = "savings" - const val ENTITY_TYPE_STAFF = "staff" - const val ENTITY_TYPE_CLIENT_IDENTIFIERS = "client_identifiers" - //Search Entities const val SEARCH_ENTITY_CLIENT = "CLIENT" const val SEARCH_ENTITY_GROUP = "GROUP" @@ -36,100 +18,19 @@ object Constants { const val CLIENT_ID = "clientId" const val ID = "id" const val CLIENT = "Client" - const val CLIENTS = "clients" - const val LOAN_ACCOUNT_NUMBER = "loanAccountNumber" - const val LOAN_PAYMENT_TYPE_OPTIONS = "LoanPaymentTypeOptions" - const val LOAN_SUMMARY = "loanWithAssociation" - const val SAVINGS_ACCOUNT_NUMBER = "savingsAccountNumber" - const val SAVINGS_ACCOUNT_ID = "savingsAccountId" - const val SAVINGS_ACCOUNT_TYPE = "savingsAccountType" - const val SAVINGS_ACCOUNT_TRANSACTION_TYPE = "transactionType" - const val SAVINGS_ACCOUNT_TRANSACTION_DEPOSIT = "Deposit" - const val SAVINGS_ACCOUNT_TRANSACTION_WITHDRAWAL = "Withdrawal" - const val DATA_TABLE_REGISTERED_NAME = "dataTableRegisteredName" const val CENTER_ID = "centerId" const val GROUP_ID = "groupId" const val GROUP_NAME = "groupName" const val GROUPS = "groups" const val GROUP_ACCOUNT = "isGroupAccount" const val CENTER = "center" - const val ENTITY_TYPE = "entityType" - const val ENTITY_ID = "entityId" - const val DOCUMENT_ACTIONS = "document_actions" - const val DOCUMENT = "document_title" - const val DOCUMENT_DESCRIPTION = "document_description" - const val CHARGE_ID = "chargeId" - const val DATE_OF_COLLECTION = "dateOfCollection" - const val REPAYMENT_DATE = "repaymentDate" - const val DATE_FORMAT = "dateFormat" - const val CALENDAR_INSTANCE_ID = "calendarInstanceId" - const val LOCALE = "locale" - const val LOCALE_EN = "en" - const val DATE_FORMAT_LONG = "dd MMMM yyyy" - const val TRANSACTIONS = "transactions" - const val SURVEYS = "surveys" - const val ANSWERS = "answers" - const val QUESTION_DATA = "question data" - const val IS_A_PARENT_FRAGMENT = "isAParentFragment" const val STOP_TRACKING = "stop_tracking" const val SERVICE_STATUS = "service_status" - const val DATA_TABLE_NAME = "data_table_name" - const val DIALOG_FRAGMENT = 1 - const val ACTIVATE_CLIENT = "activate_client" - const val ACTIVATE_CENTER = "activate_center" - const val ACTIVATE_GROUP = "activate_group" - const val ACTIVATE_TYPE = "activation_type" - const val INTIAL_LOGIN = "initial_login" - const val INDIVIDUAL_SHEET = "collection_sheet" - const val DISBURSEMENT_DATE = "disbursement_date" - const val TRANSACTION_DATE = "transaction_date" - const val ADAPTER_POSITION = "adapter_position" - const val PAYLOAD = "payload" - const val PAYMENT_LIST = "payment_list" - const val LOAN_AND_CLIENT = "loan_and_client_item" - const val PAYMENT_OPTIONS = "payment_options" - const val MEMBERS = "members" - const val NEW = "NEW" - const val SAVED = "SAVED" - const val FILLNOW = "FillNow" //This needs to be 8 bits because validateRequestPermissionsRequestCode // in FragmentActivity requires requestCode to be of 8 bits, meaning the range is from 0 to 255. const val REQUEST_PERMISSION_SETTING = 254 - /** - * PERMISSIONS_........ is an app-defined int constant of RunTime Permission . The callback - * method gets the result of the request. - */ - const val PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 1 - const val PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE = 2 - const val PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 3 - - /** - * String Constant of Permissions in SharedPreference - */ - const val READ_EXTERNAL_STORAGE_STATUS = "read_external_storage_status" - const val WRITE_EXTERNAL_STORAGE_STATUS = "write_external_storage_status" - const val ACCESS_FINE_LOCATION_STATUS = "access_fine_location_status" - - /** - * Constants to identify which Data Tables have to be shown - */ - const val DATA_TABLE_CLIENTS = 2001 - const val DATA_TABLE_LOANS = 2002 - const val DATA_TABLES_SAVINGS_ACCOUNTS = 2003 - - /** - * Constants to for Data Table Menu Names - */ - const val DATA_TABLE_CLIENTS_NAME = "More Client Info" - const val DATA_TABLE_LOAN_NAME = "More Loan Info" - const val DATA_TABLE_SAVINGS_ACCOUNTS_NAME = "More Savings Account Info" - const val DATA_TABLE_NAME_CLIENT = "m_client" - const val DATA_TABLE_NAME_SAVINGS = "m_savings_account" - const val DATA_TABLE_NAME_LOANS = "m_loan" - const val DATA_TABLE_NAME_GROUP = "m_group" - /** * User Logged In Status * 0 for Online and 1 for Offline @@ -137,15 +38,6 @@ object Constants { const val USER_ONLINE = false const val USER_OFFLINE = true - /** - * Constants to determine in the generic DataTableListFragment, the type of query that - * has to be forwarded after showing the datatables and adding the values - * to the corresponding payload. - */ - const val CREATE_CLIENT = 3001 - const val CLIENT_LOAN = 3002 - const val GROUP_LOAN = 3003 - /** * Constant to identify whether Simple Collection Sheet fragment has to be opened * or the Individual Collection Sheet. @@ -157,51 +49,6 @@ object Constants { /** * Constants related to RunReports */ - const val REPORT_NAME = "report_name" - const val REPORT_ID = "report_id" - const val CLIENT_REPORT_ITEM = "client_report_item" - const val CLIENT_REPORT = "client_report" - const val REPORT_CATEGORY = "report_category" - const val LOAN = "Loan" - const val ACCOUNTING = "Accounting" - const val FUND = "Fund" - const val SAVINGS = "Savings" - const val LOAN_OFFICER_ID_SELECT = "loanOfficerIdSelectAll" - const val LOAN_PRODUCT_ID_SELECT = "loanProductIdSelectAll" - const val LOAN_PURPOSE_ID_SELECT = "loanPurposeIdSelectAll" - const val FUND_ID_SELECT = "fundIdSelectAll" - const val CURRENCY_ID_SELECT = "currencyIdSelectAll" - const val OFFICE_ID_SELECT = "OfficeIdSelectOne" - const val PAR_TYPE_SELECT = "parTypeSelect" - const val SAVINGS_ACCOUNT_SUB_STATUS = "SavingsAccountSubStatus" - const val SELECT_GL_ACCOUNT_NO = "SelectGLAccountNO" - const val OBLIG_DATE_TYPE_SELECT = "obligDateTypeSelect" - const val R_LOAN_OFFICER_ID = "R_loanOfficerId" - const val R_LOAN_PRODUCT_ID = "R_loanProductId" - const val R_LOAN_PURPOSE_ID = "R_loanPurposeId" - const val R_FUND_ID = "R_fundId" - const val R_CURRENCY_ID = "R_currencyId" - const val R_OFFICE_ID = "R_officeId" - const val R_PAR_TYPE = "R_parType" - const val R_SUB_STATUS = "R_subStatus" - const val R_ACCOUNT = "R_account" - const val R_OBLIG_DATE_TYPE = "R_obligDateType" - const val START_DATE_SELECT = "startDateSelect" - const val END_DATE_SELECT = "endDateSelect" - const val SELECT_ACCOUNT = "selectAccount" - const val FROM_X_SELECT = "fromXSelect" - const val TO_Y_SELECT = "toYSelect" - const val OVERDUE_X_SELECT = "overdueXSelect" - const val OVERDUE_Y_SELECT = "overdueYSelect" - const val R_START_DATE = "R_startDate" - const val R_END_DATE = "R_endDate" - const val R_ACCOUNT_NO = "R_accountNo" - const val R_FROM_X = "R_fromX" - const val R_TO_Y = "R_toY" - const val R_OVERDUE_X = "R_overdueX" - const val R_OVERDUE_Y = "R_overdueY" - const val ACTION_REPORT = "report" - const val CURR_PASSWORD = "currentPassword" - const val IS_TO_UPDATE_PASS_CODE = "updatePassCode" + const val HAS_SETTING_CHANGED = "hasSettingsChanged" } \ No newline at end of file diff --git a/mifosng-android/src/main/res/layout/activity_center_details.xml b/mifosng-android/src/main/res/layout/activity_center_details.xml deleted file mode 100644 index 26400d179e9..00000000000 --- a/mifosng-android/src/main/res/layout/activity_center_details.xml +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - -