Skip to content
Open
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 @@ -46,6 +46,7 @@ import com.mifos.core.data.repository.LoanAccountRepository
import com.mifos.core.data.repository.LoanAccountSummaryRepository
import com.mifos.core.data.repository.LoanChargeFormRepository
import com.mifos.core.data.repository.LoanChargeRepository
import com.mifos.core.data.repository.LoanForeclosureRepository
import com.mifos.core.data.repository.LoanRepaymentRepository
import com.mifos.core.data.repository.LoanRepaymentScheduleRepository
import com.mifos.core.data.repository.LoanReschedulesRepository
Expand Down Expand Up @@ -115,6 +116,7 @@ import com.mifos.core.data.repositoryImp.LoanAccountRepositoryImp
import com.mifos.core.data.repositoryImp.LoanAccountSummaryRepositoryImp
import com.mifos.core.data.repositoryImp.LoanChargeFormRepositoryImp
import com.mifos.core.data.repositoryImp.LoanChargeRepositoryImp
import com.mifos.core.data.repositoryImp.LoanForeclosureRepositoryImp
import com.mifos.core.data.repositoryImp.LoanRepaymentRepositoryImp
import com.mifos.core.data.repositoryImp.LoanRepaymentScheduleRepositoryImp
import com.mifos.core.data.repositoryImp.LoanReschedulesRepositoryImpl
Expand Down Expand Up @@ -197,6 +199,7 @@ val RepositoryModule = module {
singleOf(::LoanRepaymentScheduleRepositoryImp) bind LoanRepaymentScheduleRepository::class
singleOf(::LoanTransactionsRepositoryImp) bind LoanTransactionsRepository::class
singleOf(::LoanReschedulesRepositoryImpl) bind LoanReschedulesRepository::class
singleOf(::LoanForeclosureRepositoryImp) bind LoanForeclosureRepository::class

// Account Transfer
singleOf(::AmountTransferRepositoryImp) bind AmountTransferRepository::class
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright 2026 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/mifos-x-field-officer-app/blob/master/LICENSE.md
*/
package com.mifos.core.data.repository

import com.mifos.core.common.utils.DataState
import com.mifos.core.model.objects.account.loan.foreclosure.LoanForeclosureInput
import com.mifos.core.model.objects.account.loan.foreclosure.LoanForeclosureTemplate

interface LoanForeclosureRepository {

suspend fun getLoanForeclosureTemplate(
loanId: Int,
transactionDate: String,
dateFormat: String,
locale: String,
): DataState<LoanForeclosureTemplate>

suspend fun submitLoanForeclosure(
loanId: Int,
input: LoanForeclosureInput,
): DataState<Unit>
}

@biplab1 biplab1 May 15, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright 2026 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/mifos-x-field-officer-app/blob/master/LICENSE.md
*/
package com.mifos.core.data.repositoryImp

import com.mifos.core.common.utils.DataState
import com.mifos.core.data.repository.LoanForeclosureRepository
import com.mifos.core.model.objects.account.loan.foreclosure.LoanForeclosureInput
import com.mifos.core.model.objects.account.loan.foreclosure.LoanForeclosureTemplate
import com.mifos.core.network.datamanager.DataManagerLoan
import com.mifos.core.network.mappers.loan.toDomain
import com.mifos.core.network.mappers.loan.toDto
import kotlinx.coroutines.withContext
import template.core.base.common.manager.DispatcherManager

class LoanForeclosureRepositoryImp(
private val dataManager: DataManagerLoan,
private val dispatcher: DispatcherManager,
) : LoanForeclosureRepository {
Comment thread
coderabbitai[bot] marked this conversation as resolved.

override suspend fun getLoanForeclosureTemplate(
loanId: Int,
transactionDate: String,
dateFormat: String,
locale: String,
): DataState<LoanForeclosureTemplate> {
return withContext(dispatcher.io) {
try {
val dto = dataManager.getLoanForeclosureTemplate(
loanId = loanId,
transactionDate = transactionDate,
dateFormat = dateFormat,
locale = locale,
)
DataState.Success(dto.toDomain())
} catch (e: Exception) {
DataState.Error(e)
}
}
}

override suspend fun submitLoanForeclosure(
loanId: Int,
input: LoanForeclosureInput,
): DataState<Unit> {
return withContext(dispatcher.io) {
try {
dataManager.submitLoanForeclosure(loanId, input.toDto())
DataState.Success(Unit)
} catch (e: Exception) {
DataState.Error(e)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright 2026 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/mifos-x-field-officer-app/blob/master/LICENSE.md
*/
package com.mifos.core.model.objects.account.loan.foreclosure

data class LoanForeclosureInput(
val transactionDate: String,
val note: String,
val dateFormat: String,
val locale: String,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Copyright 2026 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/mifos-x-field-officer-app/blob/master/LICENSE.md
*/
package com.mifos.core.model.objects.account.loan.foreclosure

data class LoanForeclosureTemplate(
val loanId: Int? = null,
val amount: Double? = null,
val principalPortion: Double? = null,
val interestPortion: Double? = null,
val feeChargesPortion: Double? = null,
val penaltyChargesPortion: Double? = null,
)
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import com.mifos.core.model.objects.account.loan.transfer.AccountTransferTemplat
import com.mifos.core.network.BaseApiManager
import com.mifos.core.network.GenericResponse
import com.mifos.core.network.model.LoansPayload
import com.mifos.core.network.model.loan.LoanForeclosureRequestDto
import com.mifos.core.network.model.loan.LoanForeclosureTemplateDto
import com.mifos.room.entities.PaymentTypeOptionEntity
import com.mifos.room.entities.accounts.loans.LoanRepaymentRequestEntity
import com.mifos.room.entities.accounts.loans.LoanRepaymentResponseEntity
Expand Down Expand Up @@ -412,4 +414,37 @@ class DataManagerLoan(
throw IllegalStateException(extractErrorMessage(response))
}
}

suspend fun getLoanForeclosureTemplate(
loanId: Int,
transactionDate: String,
dateFormat: String,
locale: String,
): LoanForeclosureTemplateDto {
val response = mBaseApiManager.loanService.getLoanForeclosureTemplate(
loanId = loanId,
transactionDate = transactionDate,
dateFormat = dateFormat,
locale = locale,
)
if (!response.status.isSuccess()) {
val errorMessage = extractErrorMessage(response)
throw IllegalStateException(errorMessage)
}

return Json { ignoreUnknownKeys = true }.decodeFromString<LoanForeclosureTemplateDto>(response.bodyAsText())
}

suspend fun submitLoanForeclosure(
loanId: Int,
request: LoanForeclosureRequestDto,
) {
val response = mBaseApiManager.loanService.submitLoanForeclosure(
loanId = loanId,
body = request,
)
if (!response.status.isSuccess()) {
throw IllegalStateException(extractErrorMessage(response))
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright 2026 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/mifos-x-field-officer-app/blob/master/LICENSE.md
*/
package com.mifos.core.network.mappers.loan

import com.mifos.core.model.objects.account.loan.foreclosure.LoanForeclosureInput
import com.mifos.core.model.objects.account.loan.foreclosure.LoanForeclosureTemplate
import com.mifos.core.network.model.loan.LoanForeclosureRequestDto
import com.mifos.core.network.model.loan.LoanForeclosureTemplateDto

fun LoanForeclosureTemplateDto.toDomain(): LoanForeclosureTemplate =
LoanForeclosureTemplate(
loanId = loanId,
amount = amount,
principalPortion = principalPortion,
interestPortion = interestPortion,
feeChargesPortion = feeChargesPortion,
penaltyChargesPortion = penaltyChargesPortion,
)

fun LoanForeclosureInput.toDto(): LoanForeclosureRequestDto =
LoanForeclosureRequestDto(
transactionDate = transactionDate,
note = note,
dateFormat = dateFormat,
locale = locale,
)
Comment thread
Kartikey15dem marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* Copyright 2026 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/mifos-x-field-officer-app/blob/master/LICENSE.md
*/
package com.mifos.core.network.model.loan

import kotlinx.serialization.Serializable

@Serializable
data class LoanForeclosureRequestDto(
val transactionDate: String,
val note: String,
val dateFormat: String,
val locale: String,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright 2026 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/mifos-x-field-officer-app/blob/master/LICENSE.md
*/
package com.mifos.core.network.model.loan

import kotlinx.serialization.Serializable

@Serializable
data class LoanForeclosureTemplateDto(
val loanId: Int? = null,
val amount: Double? = null,
val principalPortion: Double? = null,
val interestPortion: Double? = null,
val feeChargesPortion: Double? = null,
val penaltyChargesPortion: Double? = null,
)
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import com.mifos.core.model.objects.payloads.GroupLoanPayload
import com.mifos.core.model.objects.template.loan.GroupLoanTemplate
import com.mifos.core.network.GenericResponse
import com.mifos.core.network.model.LoansPayload
import com.mifos.core.network.model.loan.LoanForeclosureRequestDto
import com.mifos.room.basemodel.APIEndPoint
import com.mifos.room.entities.accounts.loans.Loan
import com.mifos.room.entities.accounts.loans.LoanRepaymentRequestEntity
Expand Down Expand Up @@ -196,4 +197,18 @@ interface LoanService {
@Path("scheduleId") scheduleId: Int,
@Body request: LoanRescheduleRejectionRequest,
): HttpResponse

@GET(APIEndPoint.LOANS + "/{loanId}/transactions/template?command=foreclosure")
suspend fun getLoanForeclosureTemplate(
@Path("loanId") loanId: Int,
@Query("transactionDate") transactionDate: String,
@Query("dateFormat") dateFormat: String,
@Query("locale") locale: String,
): HttpResponse

@POST(APIEndPoint.LOANS + "/{loanId}/transactions?command=foreclosure")
suspend fun submitLoanForeclosure(
@Path("loanId") loanId: Int,
@Body body: LoanForeclosureRequestDto,
): HttpResponse
Comment thread
Kartikey15dem marked this conversation as resolved.
}
Original file line number Diff line number Diff line change
Expand Up @@ -475,4 +475,13 @@
<string name="feature_loan_reschedule_fetch_failed">Failed to load reschedule history.</string>
<string name="feature_loan_reschedule_approve_failed">Failed to approve reschedule.</string>
<string name="feature_loan_reschedule_delete_failed">Failed to delete reschedule.</string>

<!-- Loan Foreclosure -->
<string name="feature_loan_transaction_date">Transaction Date*</string>
<string name="feature_loan_interest">Interest</string>
<string name="feature_loan_fee_amount">Fee Amount</string>
<string name="feature_loan_penalty_amount">Penalty Amount*</string>
<string name="feature_loan_note">Note*</string>
<string name="feature_loan_foreclosure">Foreclosure</string>
<string name="feature_loan_transaction_amount_mandatory">Transaction Amount*</string>
Comment thread
Kartikey15dem marked this conversation as resolved.
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import com.mifos.feature.loan.loanAccountSummary.LoanAccountSummaryViewModel
import com.mifos.feature.loan.loanApproval.LoanAccountApprovalViewModel
import com.mifos.feature.loan.loanCharge.LoanChargeViewModel
import com.mifos.feature.loan.loanDisbursement.LoanAccountDisbursementViewModel
import com.mifos.feature.loan.loanForeclosure.LoanForeclosureViewModel
import com.mifos.feature.loan.loanRepayment.LoanRepaymentViewModel
import com.mifos.feature.loan.loanRepaymentSchedule.LoanRepaymentScheduleViewModel
import com.mifos.feature.loan.loanReschedules.LoanReschedulesViewModel
Expand All @@ -41,4 +42,5 @@ val LoanModule = module {
viewModelOf(::AmountTransferViewModel)
viewModelOf(::LoanReschedulesViewModel)
viewModelOf(::LoanRescheduleFormViewModel)
viewModelOf(::LoanForeclosureViewModel)
}
Loading
Loading