Skip to content

Commit edd3194

Browse files
authored
feature(clientAddress): Add client address create and read functionality (#2493)
1 parent 08c8681 commit edd3194

17 files changed

Lines changed: 1375 additions & 3 deletions

File tree

core/data/src/commonMain/kotlin/com/mifos/core/data/repository/CreateNewClientRepository.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
package com.mifos.core.data.repository
1111

1212
import com.mifos.core.common.utils.DataState
13+
import com.mifos.core.model.objects.clients.ClientAddressEntity
14+
import com.mifos.core.network.model.PostClientAddressRequest
15+
import com.mifos.core.network.model.PostClientAddressResponse
1316
import com.mifos.room.entities.client.AddressConfiguration
1417
import com.mifos.room.entities.client.AddressTemplate
1518
import com.mifos.room.entities.client.ClientPayloadEntity
@@ -37,4 +40,12 @@ interface CreateNewClientRepository {
3740
suspend fun getAddressConfiguration(): AddressConfiguration
3841

3942
suspend fun getAddressTemplate(): AddressTemplate
43+
44+
suspend fun getAddresses(clientId: Int): List<ClientAddressEntity>
45+
46+
suspend fun createClientAddress(
47+
clientId: Int,
48+
addressTypeId: Int,
49+
addressRequest: PostClientAddressRequest,
50+
): PostClientAddressResponse
4051
}

core/data/src/commonMain/kotlin/com/mifos/core/data/repositoryImp/CreateNewClientRepositoryImp.kt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,12 @@ package com.mifos.core.data.repositoryImp
1212
import com.mifos.core.common.utils.DataState
1313
import com.mifos.core.common.utils.asDataStateFlow
1414
import com.mifos.core.data.repository.CreateNewClientRepository
15+
import com.mifos.core.model.objects.clients.ClientAddressEntity
1516
import com.mifos.core.network.datamanager.DataManagerClient
1617
import com.mifos.core.network.datamanager.DataManagerOffices
1718
import com.mifos.core.network.datamanager.DataManagerStaff
19+
import com.mifos.core.network.model.PostClientAddressRequest
20+
import com.mifos.core.network.model.PostClientAddressResponse
1821
import com.mifos.room.entities.client.AddressConfiguration
1922
import com.mifos.room.entities.client.AddressTemplate
2023
import com.mifos.room.entities.client.ClientPayloadEntity
@@ -63,4 +66,20 @@ class CreateNewClientRepositoryImp(
6366
override suspend fun getAddressTemplate(): AddressTemplate {
6467
return dataManagerClient.getAddressTemplate()
6568
}
69+
70+
override suspend fun getAddresses(clientId: Int): List<ClientAddressEntity> {
71+
return dataManagerClient.getClientAddresses(clientId = clientId)
72+
}
73+
74+
override suspend fun createClientAddress(
75+
clientId: Int,
76+
addressTypeId: Int,
77+
addressRequest: PostClientAddressRequest,
78+
): PostClientAddressResponse {
79+
return dataManagerClient.createClientAddress(
80+
clientId = clientId,
81+
addressTypeId = addressTypeId,
82+
addressRequest = addressRequest,
83+
)
84+
}
6685
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright 2025 Mifos Initiative
3+
*
4+
* This Source Code Form is subject to the terms of the Mozilla Public
5+
* License, v. 2.0. If a copy of the MPL was not distributed with this
6+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
7+
*
8+
* See https://github.com/openMF/android-client/blob/master/LICENSE.md
9+
*/
10+
package com.mifos.core.model.objects.clients
11+
12+
import com.mifos.core.model.utils.Parcelable
13+
import com.mifos.core.model.utils.Parcelize
14+
import kotlinx.serialization.Serializable
15+
16+
@Parcelize
17+
@Serializable
18+
data class ClientAddressEntity(
19+
val clientID: Int = -1,
20+
val addressType: String = "",
21+
val addressId: Int = -1,
22+
val addressTypeId: Int = -1,
23+
val isActive: Boolean = false,
24+
val street: String = "",
25+
val addressLine1: String = "",
26+
val addressLine2: String = "",
27+
val addressLine3: String = "",
28+
val townVillage: String = "",
29+
val city: String = "",
30+
val countyDistrict: String = "",
31+
val stateProvinceId: Int = -1,
32+
val countryName: String = "",
33+
val stateName: String = "",
34+
val countryId: Int = -1,
35+
val postalCode: String = "",
36+
val latitude: Double = 0.0,
37+
val longitude: Double = 0.0,
38+
val createdBy: String = "",
39+
val createdOn: String = "",
40+
val updatedBy: String = "",
41+
val updatedOn: String = "",
42+
) : Parcelable

core/network/src/commonMain/kotlin/com/mifos/core/network/datamanager/DataManagerClient.kt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import com.mifos.core.common.utils.asDataStateFlow
1515
import com.mifos.core.datastore.UserPreferencesRepository
1616
import com.mifos.core.model.objects.clients.ActivatePayload
1717
import com.mifos.core.model.objects.clients.AssignStaffRequest
18+
import com.mifos.core.model.objects.clients.ClientAddressEntity
1819
import com.mifos.core.model.objects.clients.ClientAddressRequest
1920
import com.mifos.core.model.objects.clients.ClientAddressResponse
2021
import com.mifos.core.model.objects.clients.ClientCloseRequest
@@ -34,6 +35,8 @@ import com.mifos.core.network.model.ClientCloseTemplateResponse
3435
import com.mifos.core.network.model.CollateralItem
3536
import com.mifos.core.network.model.DeleteClientsClientIdIdentifiersIdentifierIdResponse
3637
import com.mifos.core.network.model.PinpointLocationActionResponse
38+
import com.mifos.core.network.model.PostClientAddressRequest
39+
import com.mifos.core.network.model.PostClientAddressResponse
3740
import com.mifos.core.network.model.PostClientsClientIdRequest
3841
import com.mifos.core.network.model.PostClientsClientIdResponse
3942
import com.mifos.core.network.model.SavingAccountOption
@@ -507,6 +510,22 @@ class DataManagerClient(
507510
return mBaseApiManager.clientService.getAddressTemplate()
508511
}
509512

513+
suspend fun getClientAddresses(clientId: Int): List<ClientAddressEntity> {
514+
return mBaseApiManager.clientService.getClientAddresses(clientId = clientId)
515+
}
516+
517+
suspend fun createClientAddress(
518+
clientId: Int,
519+
addressTypeId: Int,
520+
addressRequest: PostClientAddressRequest,
521+
): PostClientAddressResponse {
522+
return mBaseApiManager.clientService.createClientAddress(
523+
clientId = clientId,
524+
addressTypeId = addressTypeId,
525+
addressPayload = addressRequest,
526+
)
527+
}
528+
510529
suspend fun assignClientStaff(
511530
clientId: Int,
512531
staffId: Int,
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright 2025 Mifos Initiative
3+
*
4+
* This Source Code Form is subject to the terms of the Mozilla Public
5+
* License, v. 2.0. If a copy of the MPL was not distributed with this
6+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
7+
*
8+
* See https://github.com/openMF/android-client/blob/master/LICENSE.md
9+
*/
10+
package com.mifos.core.network.model
11+
12+
import com.mifos.core.model.utils.Parcelable
13+
import com.mifos.core.model.utils.Parcelize
14+
import kotlinx.serialization.Serializable
15+
16+
@Parcelize
17+
@Serializable
18+
data class PostClientAddressRequest(
19+
val addressLine1: String = "",
20+
21+
val addressLine2: String = "",
22+
23+
val addressLine3: String = "",
24+
25+
val city: String = "",
26+
27+
val stateProvinceId: Int = -1,
28+
29+
val countryId: Int = -1,
30+
31+
val postalCode: String = "",
32+
) : Parcelable
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/*
2+
* Copyright 2025 Mifos Initiative
3+
*
4+
* This Source Code Form is subject to the terms of the Mozilla Public
5+
* License, v. 2.0. If a copy of the MPL was not distributed with this
6+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
7+
*
8+
* See https://github.com/openMF/android-client/blob/master/LICENSE.md
9+
*/
10+
package com.mifos.core.network.model
11+
12+
import kotlinx.serialization.Serializable
13+
14+
@Serializable
15+
data class PostClientAddressResponse(
16+
val resourceId: Long? = null,
17+
)

core/network/src/commonMain/kotlin/com/mifos/core/network/services/ClientService.kt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ package com.mifos.core.network.services
1212
import com.mifos.core.common.utils.Page
1313
import com.mifos.core.model.objects.clients.ActivatePayload
1414
import com.mifos.core.model.objects.clients.AssignStaffRequest
15+
import com.mifos.core.model.objects.clients.ClientAddressEntity
1516
import com.mifos.core.model.objects.clients.ClientAddressRequest
1617
import com.mifos.core.model.objects.clients.ClientAddressResponse
1718
import com.mifos.core.model.objects.clients.ClientCloseRequest
@@ -29,6 +30,8 @@ import com.mifos.core.network.model.GetClientsPageItemsResponse
2930
import com.mifos.core.network.model.PinpointLocationActionResponse
3031
import com.mifos.core.network.model.PostAuthenticationRequest
3132
import com.mifos.core.network.model.PostAuthenticationResponse
33+
import com.mifos.core.network.model.PostClientAddressRequest
34+
import com.mifos.core.network.model.PostClientAddressResponse
3235
import com.mifos.room.basemodel.APIEndPoint
3336
import com.mifos.room.entities.accounts.ClientAccounts
3437
import com.mifos.room.entities.client.AddressConfiguration
@@ -257,6 +260,16 @@ interface ClientService {
257260
@GET("client/addresses/template")
258261
suspend fun getAddressTemplate(): AddressTemplate
259262

263+
@GET("client/{clientId}/addresses")
264+
suspend fun getClientAddresses(@Path("clientId") clientId: Int): List<ClientAddressEntity>
265+
266+
@POST("client/{clientId}/addresses?type={addressTypeId}")
267+
suspend fun createClientAddress(
268+
@Path("clientId") clientId: Int,
269+
@Path("addressTypeId") addressTypeId: Int,
270+
@Body addressPayload: PostClientAddressRequest,
271+
): PostClientAddressResponse
272+
260273
@GET("clients/{clientId}?template=true&staffInSelectedOfficeOnly=true")
261274
suspend fun getClientTemplate(@Path("clientId") clientId: Int): GetClientsPageItemsResponse
262275

feature/client/src/commonMain/composeResources/values/strings.xml

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,11 +193,30 @@
193193
<string name="feature_client_county_district">County/District</string>
194194
<string name="feature_client_country">Country</string>
195195
<string name="feature_client_state_province">State/Province</string>
196+
<string name="feature_client_province">Province</string>
196197
<string name="feature_client_postal_code">Postal Code</string>
197198
<string name="feature_client_address_active">Address Active</string>
198199
<string name="feature_client_error_address_type_is_required">Address Type is required</string>
199200
<string name="feature_client_failed_to_fetch_address_configuration">Failed to fetch address configuration</string>
200201
<string name="feature_client_failed_to_fetch_address_template">Failed to fetch address template</string>
202+
<string name="feature_client_unable_to_create_address_for_client">Unable to create address for client</string>
203+
<string name="feature_client_success_title">Address Created Successfully</string>
204+
<string name="feature_client_create_address_success_message">Client Address created successfully. Click Continue to view the Client Addresses.</string>
205+
<string name="feature_client_address_creation_failure_title">Address Creation Failed</string>
206+
207+
208+
<string name="feature_client_empty_address_card_title">No Item Found</string>
209+
<string name="feature_client_empty_address_card_message">Click on '+' Button to add an item. </string>
210+
<string name="feature_client_failed_to_load_address">Failed to load addresses</string>
211+
212+
<string name="feature_client_address_type_error">Address Type cannot be empty.</string>
213+
<string name="feature_client_address_line_error">Address Line 1 cannot be empty.</string>
214+
<string name="feature_client_address_city_error">City cannot be empty.</string>
215+
<string name="feature_client_address_state_province_error">State/Province cannot be empty.</string>
216+
<string name="feature_client_address_country_error">Country cannot be empty.</string>
217+
<string name="feature_client_address_postal_code_error">Postal Code cannot be empty.</string>
218+
219+
201220

202221
<string name="feature_client_pinpoint_location_marker_title">Pinpoint Location</string>
203222
<string name="feature_client_select_location_dialog_title">Select Location</string>
@@ -362,7 +381,7 @@
362381
<string name="btn_submit">Submit</string>
363382
<string name="msg_cannot_assign_staff">Can't Assign a Staff to this client</string>
364383

365-
<!-- Success & Failure Messages -->
384+
<!-- ShowAddressList & Failure Messages -->
366385
<string name="staff_unassign_success_title">Staff Unassigned Successfully!!</string>
367386
<string name="staff_unassign_success_message">Your request was completed successfully.</string>
368387
<string name="staff_unassign_failure_title">Staff Unassigning Failed!</string>
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright 2025 Mifos Initiative
3+
*
4+
* This Source Code Form is subject to the terms of the Mozilla Public
5+
* License, v. 2.0. If a copy of the MPL was not distributed with this
6+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
7+
*
8+
* See https://github.com/openMF/android-client/blob/master/LICENSE.md
9+
*/
10+
package com.mifos.feature.client.clientAddress
11+
12+
import androidx.navigation.NavController
13+
import androidx.navigation.NavGraphBuilder
14+
import androidx.navigation.compose.composable
15+
import com.mifos.feature.client.clientAddress.addAddress.AddAddressRoute
16+
import kotlinx.serialization.Serializable
17+
18+
@Serializable
19+
data class ClientAddressRoute(
20+
val id: Int = -1,
21+
)
22+
23+
fun NavGraphBuilder.clientAddressNavigation(
24+
onNavigateBack: () -> Unit,
25+
navController: NavController,
26+
navigateToAddAddressForm: (Int) -> Unit,
27+
) {
28+
composable<ClientAddressRoute> {
29+
ClientAddressScreen(
30+
onNavigateBack = onNavigateBack,
31+
navigateToAddAddressForm = navigateToAddAddressForm,
32+
navController = navController,
33+
)
34+
}
35+
}
36+
37+
fun NavController.navigateToClientAddressRoute(
38+
id: Int,
39+
) {
40+
this.navigate(
41+
ClientAddressRoute(id = id),
42+
)
43+
}
44+
45+
fun NavController.navigateToClientAddressRouteOnStatus(id: Int) {
46+
this.navigate(
47+
ClientAddressRoute(id = id),
48+
) {
49+
popUpTo<AddAddressRoute> { inclusive = true }
50+
launchSingleTop = true
51+
}
52+
}

0 commit comments

Comments
 (0)