Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
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
4 changes: 4 additions & 0 deletions core/common/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ kotlin {

sourceSets {
commonMain.dependencies {
api(projects.core.model)

implementation(libs.kotlinx.coroutines.core)
implementation(libs.kotlinx.serialization.json)
api(libs.coil.kt)
Expand All @@ -52,6 +54,8 @@ kotlin {
api(libs.squareup.okio)
api(libs.jb.kotlin.stdlib)
api(libs.kotlinx.datetime)

implementation(libs.ktor.client.core)
}

androidMain.dependencies {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* 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.common.utils

import com.mifos.core.model.objects.error.MifosError
import io.ktor.client.plugins.ClientRequestException
import io.ktor.client.plugins.ServerResponseException
import io.ktor.client.statement.bodyAsText
import kotlinx.serialization.json.Json

object MFErrorParser {
const val LOG_TAG: String = "MFErrorParser"

private val json: Json = Json { ignoreUnknownKeys = true }

private fun parseError(serverResponse: String?): MifosError {
return json.decodeFromString(serverResponse ?: "{}")
}

suspend fun errorMessage(throwableError: Throwable): String {
return try {
when (throwableError) {
is ClientRequestException, is ServerResponseException -> {
val response = (throwableError as? ClientRequestException)?.response
?: (throwableError as? ServerResponseException)?.response
val errorBody = response?.bodyAsText() ?: ""
parseError(errorBody).errors.firstOrNull()?.defaultUserMessage
?: "Something went wrong!"
}

else -> throwableError.message ?: "Unknown error"
}
} catch (exception: Exception) {
"Error processing response"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ interface CheckerInboxTasksRepository {

fun getRescheduleLoansTaskList(): Flow<DataState<List<RescheduleLoansTask>>>

suspend fun getCheckerTaskList(
fun getCheckerTaskList(
actionName: String? = null,
entityName: String? = null,
resourceId: Int? = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,13 @@ package com.mifos.core.data.repository

import com.mifos.room.entities.accounts.ClientAccounts
import com.mifos.room.entities.client.ClientEntity
import io.ktor.http.content.PartData

/**
* Created by Aditya Gupta on 06/08/23.
*/
interface ClientDetailsRepository {

suspend fun uploadClientImage(id: Int, file: PartData)
suspend fun uploadClientImage(clientId: Int, image: String)

suspend fun deleteClientImage(clientId: Int)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class CheckerInboxTasksRepositoryImp(
.asDataStateFlow()
}

override suspend fun getCheckerTaskList(
override fun getCheckerTaskList(
actionName: String?,
entityName: String?,
resourceId: Int?,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import com.mifos.core.data.repository.ClientDetailsRepository
import com.mifos.core.network.datamanager.DataManagerClient
import com.mifos.room.entities.accounts.ClientAccounts
import com.mifos.room.entities.client.ClientEntity
import io.ktor.http.content.PartData

/**
* Created by Aditya Gupta on 06/08/23.
Expand All @@ -22,8 +21,11 @@ class ClientDetailsRepositoryImp(
private val dataManagerClient: DataManagerClient,
) : ClientDetailsRepository {

override suspend fun uploadClientImage(id: Int, file: PartData) {
dataManagerClient.uploadClientImage(id, file)
override suspend fun uploadClientImage(clientId: Int, image: String) {
dataManagerClient.uploadClientImage(
clientId = clientId,
typedFile = "data:image/png;base64,$image",
)
}

override suspend fun deleteClientImage(clientId: Int) {
Expand Down
68 changes: 42 additions & 26 deletions core/domain/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,37 +8,53 @@
* See https://github.com/openMF/android-client/blob/master/LICENSE.md
*/
plugins {
alias(libs.plugins.mifos.android.library)
alias(libs.plugins.mifos.android.library.jacoco)
alias(libs.plugins.mifos.android.koin)
// alias(libs.plugins.mifos.android.hilt)
alias(libs.plugins.mifos.kmp.library)
alias(libs.plugins.mifos.kmp.koin)
alias(libs.plugins.jetbrainsCompose)
alias(libs.plugins.compose.compiler)
alias(libs.plugins.kotlin.serialization)
}

android {
namespace = "com.mifos.core.domain"
}

dependencies {
api(projects.core.data)
api(projects.core.model)

implementation(libs.javax.inject)

implementation(libs.dbflow)

// sdk client
// implementation(libs.fineract.client)

implementation(libs.rxandroid)
implementation(libs.rxjava)

implementation(libs.squareup.okhttp)

implementation(libs.androidx.paging.runtime.ktx)

testImplementation(projects.core.testing)
testImplementation (libs.androidx.paging.common.ktx)
testImplementation (libs.androidx.paging.testing)
kotlin {
sourceSets {
commonMain.dependencies {
api(projects.core.data)
api(projects.core.model)
api(projects.core.common)
api(projects.core.network)

implementation(libs.kotlinx.coroutines.core)
implementation(compose.components.resources)
implementation(libs.kotlinx.serialization.json)
// implementation(libs.fineract.client.kmp)
}

androidMain.dependencies {
implementation(libs.squareup.okhttp)
implementation(libs.ktor.client.okhttp)
implementation(libs.androidx.paging.runtime.ktx)
}
nativeMain.dependencies {
implementation(libs.ktor.client.darwin)
}
desktopMain.dependencies {
implementation(libs.ktor.client.okhttp)
}
jsMain.dependencies {
implementation(libs.ktor.client.js)
}
wasmJsMain.dependencies {
implementation(libs.ktor.client.js)
}
}
}

implementation(libs.kotlinx.serialization.json)
compose.resources {
publicResClass = true
generateResClass = always
packageOfResClass = "core.domain.generated.resources"
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
*/
package com.mifos.core.domain.useCases

import com.mifos.core.common.utils.Resource
import com.mifos.core.common.utils.DataState
import com.mifos.core.common.utils.asDataStateFlow
import com.mifos.core.data.repository.ActivateRepository
import com.mifos.core.model.objects.clients.ActivatePayload
import com.mifos.core.network.model.PostCentersCenterIdResponse
Expand All @@ -20,16 +21,10 @@ class ActivateCenterUseCase(
private val activateRepository: ActivateRepository,
) {

suspend operator fun invoke(
operator fun invoke(
centerId: Int,
centerPayload: ActivatePayload,
): Flow<Resource<PostCentersCenterIdResponse>> = flow {
try {
emit(Resource.Loading())
val response = activateRepository.activateCenter(centerId, centerPayload)
emit(Resource.Success(response))
} catch (exception: Exception) {
emit(Resource.Error(exception.message.toString()))
}
}
): Flow<DataState<PostCentersCenterIdResponse>> = flow {
emit(activateRepository.activateCenter(centerId, centerPayload))
}.asDataStateFlow()
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
*/
package com.mifos.core.domain.useCases

import com.mifos.core.common.utils.Resource
import com.mifos.core.common.utils.DataState
import com.mifos.core.common.utils.asDataStateFlow
import com.mifos.core.data.repository.ActivateRepository
import com.mifos.core.model.objects.clients.ActivatePayload
import com.mifos.core.network.model.PostClientsClientIdResponse
Expand All @@ -20,16 +21,10 @@ class ActivateClientUseCase(
private val activateRepository: ActivateRepository,
) {

suspend operator fun invoke(
operator fun invoke(
clientId: Int,
clientPayload: ActivatePayload,
): Flow<Resource<PostClientsClientIdResponse>> = flow {
try {
emit(Resource.Loading())
val response = activateRepository.activateClient(clientId, clientPayload)
emit(Resource.Success(response))
} catch (exception: Exception) {
emit(Resource.Error(exception.message.toString()))
}
}
): Flow<DataState<PostClientsClientIdResponse>> = flow {
emit(activateRepository.activateClient(clientId, clientPayload))
}.asDataStateFlow()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* 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.core.domain.useCases

import com.mifos.core.common.utils.DataState
import com.mifos.core.data.repository.ActivateRepository
import com.mifos.core.model.objects.clients.ActivatePayload
import com.mifos.core.network.GenericResponse
import kotlinx.coroutines.flow.Flow

class ActivateGroupUseCase(
private val activateRepository: ActivateRepository,
) {

operator fun invoke(
groupId: Int,
groupPayload: ActivatePayload,
): Flow<DataState<GenericResponse>> =
activateRepository.activateGroup(groupId, groupPayload)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* 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.core.domain.useCases

import com.mifos.core.common.utils.DataState
import com.mifos.core.data.repository.SavingsAccountActivateRepository
import com.mifos.core.network.GenericResponse
import kotlinx.coroutines.flow.Flow

/**
* Created by Pronay Sarker on 04/08/2024 (12:33 PM)
*/
class ActivateSavingsUseCase(
private val repository: SavingsAccountActivateRepository,
) {

operator fun invoke(
savingsAccountId: Int,
request: HashMap<String, String>,
): Flow<DataState<GenericResponse>> =
repository.activateSavings(savingsAccountId, request)
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
*/
package com.mifos.core.domain.useCases

import com.mifos.core.common.utils.Resource
import com.mifos.core.common.utils.DataState
import com.mifos.core.common.utils.asDataStateFlow
import com.mifos.core.data.repository.PinPointClientRepository
import com.mifos.core.model.objects.clients.ClientAddressRequest
import com.mifos.core.network.GenericResponse
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
Expand All @@ -19,16 +21,10 @@ class AddClientPinpointLocationUseCase(
private val pinPointClientRepository: PinPointClientRepository,
) {

suspend operator fun invoke(
operator fun invoke(
clientId: Int,
address: com.mifos.core.model.objects.clients.ClientAddressRequest,
): Flow<Resource<GenericResponse>> = flow {
try {
emit(Resource.Loading())
val response = pinPointClientRepository.addClientPinpointLocation(clientId, address)
emit(Resource.Success(response))
} catch (exception: Exception) {
emit(Resource.Error(exception.message.toString()))
}
}
address: ClientAddressRequest,
): Flow<DataState<GenericResponse>> = flow {
emit(pinPointClientRepository.addClientPinpointLocation(clientId, address))
}.asDataStateFlow()
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
*/
package com.mifos.core.domain.useCases

import com.mifos.core.common.utils.Resource
import com.mifos.core.common.utils.DataState
import com.mifos.core.common.utils.asDataStateFlow
import com.mifos.core.data.repository.DataTableRowDialogRepository
import com.mifos.core.network.GenericResponse
import kotlinx.coroutines.flow.Flow
Expand All @@ -19,17 +20,11 @@ class AddDataTableEntryUseCase(
private val repository: DataTableRowDialogRepository,
) {

suspend operator fun invoke(
operator fun invoke(
table: String,
entityId: Int,
payload: Map<String, String>,
): Flow<Resource<GenericResponse>> = flow {
try {
emit(Resource.Loading())
val response = repository.addDataTableEntry(table, entityId, payload)
emit(Resource.Success(response))
} catch (exception: Exception) {
emit(Resource.Error(exception.message.toString()))
}
}
): Flow<DataState<GenericResponse>> = flow {
emit(repository.addDataTableEntry(table, entityId, payload))
}.asDataStateFlow()
}
Loading