Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ package cmp.navigation.navigation
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.navigation.NavController
import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.navigation
import cmp.navigation.AppState
Expand Down Expand Up @@ -208,6 +210,20 @@ internal fun FeatureNavHost(
},
hasDatatables = appState.navController::navigateDataTableList,
onDocumentClicked = appState.navController::navigateToDocumentListScreen,
navigateToHome = {
appState.navController.navigateAndClearBackStack(HomeDestinationsScreen.SearchScreen.route)
},
)
}
}

// id showing error in ide eventhough syntax correct and app is building fine so don't pay attention to id red colour
fun NavController.navigateAndClearBackStack(route: String) {
this.navigate(route) {
popUpTo(graph.findStartDestination().id) {
inclusive = true
}
launchSingleTop = true
restoreState = false
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
package com.mifos.core.data.repository

import com.mifos.core.common.utils.DataState
import com.mifos.core.network.model.StaffOption
import com.mifos.room.entities.accounts.ClientAccounts
import com.mifos.room.entities.client.ClientEntity
import io.ktor.client.request.forms.MultiPartFormDataContent
Expand All @@ -26,7 +27,13 @@ interface ClientDetailsRepository {

suspend fun getClientAccounts(clientId: Int): ClientAccounts

suspend fun getClientStaffOptions(clientId: Int): List<StaffOption>

suspend fun getClient(clientId: Int): ClientEntity

fun getImage(clientId: Int): Flow<DataState<String>>

suspend fun assignStaff(clientId: Int, staffId: Int): DataState<Unit>

suspend fun unassignStaff(clientId: Int, staffId: Int): DataState<Unit>
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ package com.mifos.core.data.repositoryImp
import com.mifos.core.common.utils.DataState
import com.mifos.core.data.repository.ClientDetailsRepository
import com.mifos.core.network.datamanager.DataManagerClient
import com.mifos.core.network.model.StaffOption
import com.mifos.room.entities.accounts.ClientAccounts
import com.mifos.room.entities.client.ClientEntity
import io.ktor.client.request.forms.MultiPartFormDataContent
Expand All @@ -36,11 +37,29 @@ class ClientDetailsRepositoryImp(
return dataManagerClient.getClientAccounts(clientId)
}

override suspend fun getClientStaffOptions(clientId: Int): List<StaffOption> {
return dataManagerClient.getClientStaff(clientId)
}

override suspend fun getClient(clientId: Int): ClientEntity {
return dataManagerClient.getClient(clientId)
}

override fun getImage(clientId: Int): Flow<DataState<String>> {
return dataManagerClient.getClientImage(clientId)
}

override suspend fun assignStaff(
clientId: Int,
staffId: Int,
): DataState<Unit> {
return dataManagerClient.assignClientStaff(clientId, staffId)
}

override suspend fun unassignStaff(
clientId: Int,
staffId: Int,
): DataState<Unit> {
return dataManagerClient.unAssignClientStaff(clientId, staffId)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,13 @@ fun MifosButton(
text: @Composable () -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
shape: Shape = ButtonDefaults.shape,
shape: Shape = DesignToken.shapes.medium,
contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
elevation: ButtonElevation? = ButtonDefaults.buttonElevation(),
colors: ButtonColors = ButtonDefaults.buttonColors(),
colors: ButtonColors = ButtonDefaults.buttonColors(
containerColor = MaterialTheme.colorScheme.primary,
contentColor = AppColors.customWhite,
),
) {
Button(
onClick = onClick,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import androidx.compose.material3.ExposedDropdownMenuBox
import androidx.compose.material3.ExposedDropdownMenuDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.OutlinedTextFieldDefaults
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
Expand All @@ -30,6 +31,7 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.unit.dp
import com.mifos.core.designsystem.theme.MifosTypography
import org.jetbrains.compose.ui.tooling.preview.Preview

@OptIn(ExperimentalMaterial3Api::class)
Expand Down Expand Up @@ -68,17 +70,28 @@ fun MifosTextFieldDropdown(
},
value = value,
onValueChange = onValueChanged,
label = { label?.let { Text(it) } },
label = {
label?.let {
Text(
text = it,
style = MifosTypography.bodySmall,
)
}
},
modifier = modifier
.menuAnchor()
.clickable(enabled = readOnly) { isExpanded = true },
maxLines = 1,
textStyle = MaterialTheme.typography.bodyLarge,
textStyle = MifosTypography.bodyLarge,
keyboardOptions = KeyboardOptions.Default.copy(imeAction = ImeAction.Next),
trailingIcon = {
ExposedDropdownMenuDefaults.TrailingIcon(expanded = isExpanded)
},
readOnly = readOnly,
colors = OutlinedTextFieldDefaults.colors(
focusedBorderColor = MaterialTheme.colorScheme.primary,
unfocusedBorderColor = MaterialTheme.colorScheme.primary,
),
)

ExposedDropdownMenu(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright 2025 Mifos Initiative
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* See https://github.com/openMF/android-client/blob/master/LICENSE.md
*/
package com.mifos.core.model.objects.clients

import kotlinx.serialization.Serializable

@Serializable
data class AssignStaffRequest(
val staffId: Int,
)
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import com.mifos.core.common.utils.Page
import com.mifos.core.common.utils.asDataStateFlow
import com.mifos.core.datastore.UserPreferencesRepository
import com.mifos.core.model.objects.clients.ActivatePayload
import com.mifos.core.model.objects.clients.AssignStaffRequest
import com.mifos.core.model.objects.clients.ClientAddressRequest
import com.mifos.core.model.objects.clients.ClientAddressResponse
import com.mifos.core.model.objects.noncoreobjects.Identifier
Expand All @@ -29,6 +30,7 @@ import com.mifos.core.network.model.DeleteClientsClientIdIdentifiersIdentifierId
import com.mifos.core.network.model.PinpointLocationActionResponse
import com.mifos.core.network.model.PostClientsClientIdRequest
import com.mifos.core.network.model.PostClientsClientIdResponse
import com.mifos.core.network.model.StaffOption
import com.mifos.room.entities.accounts.ClientAccounts
import com.mifos.room.entities.client.AddressConfiguration
import com.mifos.room.entities.client.AddressTemplate
Expand Down Expand Up @@ -163,6 +165,10 @@ class DataManagerClient(
// }
// }

suspend fun getClientStaff(clientId: Int): List<StaffOption> {
return mBaseApiManager.clientService.getStaffList(clientId).staffOptions
}

/**
* This Method Fetching the Client Accounts (Loan, saving, etc Accounts ) from REST API
* and get the ClientAccounts and then Saving all Accounts into the Database and give the
Expand Down Expand Up @@ -471,4 +477,44 @@ class DataManagerClient(
suspend fun getAddressTemplate(): AddressTemplate {
return mBaseApiManager.clientService.getAddressTemplate()
}

suspend fun assignClientStaff(
clientId: Int,
staffId: Int,
): DataState<Unit> {
return try {
val res = mBaseApiManager.clientService.assignStaff(
clientId = clientId,
payload = AssignStaffRequest(staffId),
)
if (res.status.value == 200) {
DataState.Success(Unit)
} else {
val errorBody = res.bodyAsText()
DataState.Error(Exception(errorBody))
}
} catch (e: Exception) {
DataState.Error(e)
}
}

suspend fun unAssignClientStaff(
clientId: Int,
staffId: Int,
): DataState<Unit> {
return try {
val res = mBaseApiManager.clientService.unassignStaff(
clientId = clientId,
payload = AssignStaffRequest(staffId),
)
if (res.status.value == 200) {
DataState.Success(Unit)
} else {
val errorBody = res.bodyAsText()
DataState.Error(Exception(errorBody))
}
} catch (e: Exception) {
DataState.Error(e)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,5 @@ data class GetClientsPageItemsResponse(

val dateOfBirth: List<Int?> = emptyList(),

val staffOptions: List<StaffOption> = emptyList(),
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* Copyright 2025 Mifos Initiative
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*
* See https://github.com/openMF/android-client/blob/master/LICENSE.md
*/
package com.mifos.core.network.model

import kotlinx.serialization.Serializable

@Serializable
data class StaffOption(
val id: Int,
val displayName: String,
)
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ package com.mifos.core.network.services

import com.mifos.core.common.utils.Page
import com.mifos.core.model.objects.clients.ActivatePayload
import com.mifos.core.model.objects.clients.AssignStaffRequest
import com.mifos.core.model.objects.clients.ClientAddressRequest
import com.mifos.core.model.objects.clients.ClientAddressResponse
import com.mifos.core.model.objects.noncoreobjects.Identifier
import com.mifos.core.model.objects.noncoreobjects.IdentifierCreationResponse
import com.mifos.core.model.objects.noncoreobjects.IdentifierPayload
import com.mifos.core.model.objects.noncoreobjects.IdentifierTemplate
import com.mifos.core.network.GenericResponse
import com.mifos.core.network.model.GetClientsPageItemsResponse
import com.mifos.core.network.model.PinpointLocationActionResponse
import com.mifos.core.network.model.PostAuthenticationRequest
import com.mifos.core.network.model.PostAuthenticationResponse
Expand Down Expand Up @@ -242,4 +244,19 @@ interface ClientService {
*/
@GET("client/addresses/template")
suspend fun getAddressTemplate(): AddressTemplate

@GET("clients/{clientId}?template=true&staffInSelectedOfficeOnly=true")
suspend fun getStaffList(@Path("clientId") clientId: Int): GetClientsPageItemsResponse

@POST("clients/{clientId}?command=assignStaff")
suspend fun assignStaff(
@Path("clientId") clientId: Int,
@Body payload: AssignStaffRequest,
): HttpResponse

@POST("clients/{clientId}?command=unassignStaff")
suspend fun unassignStaff(
@Path("clientId") clientId: Int,
@Body payload: AssignStaffRequest,
): HttpResponse
}
Loading