Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FINERACT-2148: return loan charge off behaviour with loan details #4197

Merged
merged 1 commit into from
Nov 29, 2024
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 @@ -24,6 +24,7 @@
import java.util.List;
import java.util.Set;
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
import org.apache.fineract.infrastructure.core.data.StringEnumOptionData;
import org.apache.fineract.portfolio.delinquency.api.DelinquencyApiResourceSwagger.GetDelinquencyRangesResponse;

/**
Expand Down Expand Up @@ -1202,6 +1203,7 @@ private GetLoansLoanIdLoanTermEnumData() {}
public List<GetLoansLoanIdLoanTermVariations> emiAmountVariations;
@Schema(description = "List of GetLoansLoanIdLoanTermVariations")
public List<GetLoansLoanIdLoanTermVariations> loanTermVariations;
public StringEnumOptionData chargeOffBehaviour;
}

@Schema(description = "GetLoansResponse")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import lombok.experimental.Accessors;
import org.apache.fineract.infrastructure.codes.data.CodeValueData;
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
import org.apache.fineract.infrastructure.core.data.StringEnumOptionData;
import org.apache.fineract.infrastructure.core.domain.ExternalId;
import org.apache.fineract.infrastructure.dataqueries.data.DatatableData;
import org.apache.fineract.organisation.monetary.data.CurrencyData;
Expand Down Expand Up @@ -269,6 +270,8 @@ public class LoanAccountData {
private EnumOptionData loanScheduleType;
private EnumOptionData loanScheduleProcessingType;

private StringEnumOptionData chargeOffBehaviour;

public static LoanAccountData importInstanceIndividual(EnumOptionData loanTypeEnumOption, Long clientId, Long productId,
Long loanOfficerId, LocalDate submittedOnDate, Long fundId, BigDecimal principal, Integer numberOfRepayments,
Integer repaymentEvery, EnumOptionData repaidEveryFrequencyEnums, Integer loanTermFrequency,
Expand Down Expand Up @@ -453,7 +456,7 @@ public static LoanAccountData basicLoanDetails(final Long id, final String accou
LocalDate lastClosedBusinessDate, LocalDate overpaidOnDate, final boolean chargedOff, final boolean enableDownPayment,
final BigDecimal disbursedAmountPercentageForDownPayment, final boolean enableAutoRepaymentForDownPayment,
final boolean enableInstallmentLevelDelinquency, final EnumOptionData loanScheduleType,
final EnumOptionData loanScheduleProcessingType, final Integer fixedLength) {
final EnumOptionData loanScheduleProcessingType, final Integer fixedLength, final StringEnumOptionData chargeOffBehaviour) {

final CollectionData delinquent = CollectionData.template();

Expand Down Expand Up @@ -497,7 +500,8 @@ public static LoanAccountData basicLoanDetails(final Long id, final String accou
.setEnableDownPayment(enableDownPayment).setDisbursedAmountPercentageForDownPayment(disbursedAmountPercentageForDownPayment)
.setEnableAutoRepaymentForDownPayment(enableAutoRepaymentForDownPayment)
.setEnableInstallmentLevelDelinquency(enableInstallmentLevelDelinquency).setLoanScheduleType(loanScheduleType)
.setLoanScheduleProcessingType(loanScheduleProcessingType).setFixedLength(fixedLength);
.setLoanScheduleProcessingType(loanScheduleProcessingType).setFixedLength(fixedLength)
.setChargeOffBehaviour(chargeOffBehaviour);
}

/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@
import org.apache.fineract.portfolio.loanaccount.data.RepaymentScheduleRelatedLoanData;
import org.apache.fineract.portfolio.loanaccount.data.ScheduleGeneratorDTO;
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
import org.apache.fineract.portfolio.loanaccount.domain.LoanChargeOffBehaviour;
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleTransactionProcessorFactory;
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepositoryWrapper;
Expand Down Expand Up @@ -702,7 +703,8 @@ public String loanSchema() {
+ " l.total_recovered_derived as totalRecovered, topuploan.account_no as closureLoanAccountNo, "
+ " topup.topup_amount as topupAmount, l.last_closed_business_date as lastClosedBusinessDate,l.overpaidon_date as overpaidOnDate, "
+ " l.is_charged_off as isChargedOff, l.charge_off_reason_cv_id as chargeOffReasonId, codec.code_value as chargeOffReason, l.charged_off_on_date as chargedOffOnDate, l.enable_down_payment as enableDownPayment, l.disbursed_amount_percentage_for_down_payment as disbursedAmountPercentageForDownPayment, l.enable_auto_repayment_for_down_payment as enableAutoRepaymentForDownPayment,"
+ " cobu.username as chargedOffByUsername, cobu.firstname as chargedOffByFirstname, cobu.lastname as chargedOffByLastname, l.loan_schedule_type as loanScheduleType, l.loan_schedule_processing_type as loanScheduleProcessingType "
+ " cobu.username as chargedOffByUsername, cobu.firstname as chargedOffByFirstname, cobu.lastname as chargedOffByLastname, l.loan_schedule_type as loanScheduleType, l.loan_schedule_processing_type as loanScheduleProcessingType, "
+ " l.charge_off_behaviour as chargeOffBehaviour " //
+ " from m_loan l" //
+ " join m_product_loan lp on lp.id = l.product_id" //
+ " left join m_loan_recalculation_details lir on lir.loan_id = l.id join m_currency rc on rc."
Expand Down Expand Up @@ -1066,6 +1068,7 @@ public LoanAccountData mapRow(final ResultSet rs, @SuppressWarnings("unused") fi
final String loanScheduleProcessingTypeStr = rs.getString("loanScheduleProcessingType");
final LoanScheduleProcessingType loanScheduleProcessingType = LoanScheduleProcessingType.valueOf(loanScheduleProcessingTypeStr);
final Integer fixedLength = JdbcSupport.getInteger(rs, "fixedLength");
final LoanChargeOffBehaviour chargeOffBehaviour = LoanChargeOffBehaviour.valueOf(rs.getString("chargeOffBehaviour"));

return LoanAccountData.basicLoanDetails(id, accountNo, status, externalId, clientId, clientAccountNo, clientName,
clientOfficeId, clientExternalId, groupData, loanType, loanProductId, loanProductName, loanProductDescription,
Expand All @@ -1084,7 +1087,7 @@ public LoanAccountData mapRow(final ResultSet rs, @SuppressWarnings("unused") fi
fixedPrincipalPercentagePerInstallment, delinquencyRange, disallowExpectedDisbursements, isFraud,
lastClosedBusinessDate, overpaidOnDate, isChargedOff, enableDownPayment, disbursedAmountPercentageForDownPayment,
enableAutoRepaymentForDownPayment, enableInstallmentLevelDelinquency, loanScheduleType.asEnumOptionData(),
loanScheduleProcessingType.asEnumOptionData(), fixedLength);
loanScheduleProcessingType.asEnumOptionData(), fixedLength, chargeOffBehaviour.getValueAsStringEnumOptionData());
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.fineract.integrationtests;

import java.math.BigDecimal;
import org.apache.fineract.client.models.GetLoanProductsProductIdResponse;
import org.apache.fineract.client.models.GetLoansLoanIdResponse;
import org.apache.fineract.client.models.PostLoanProductsResponse;
import org.apache.fineract.client.models.PostLoansResponse;
import org.apache.fineract.client.models.PutLoanProductsProductIdRequest;
import org.apache.fineract.integrationtests.common.ClientHelper;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

public class LoanProductWithChargeOffBehaviourTest extends BaseLoanIntegrationTest {

private Long clientId;
private Long loanProductId;
private Long loanId;

// create client, progressive loan product with charge-off behaviour REGULAR (default), loan with disburse limit
// 1000 for the client,
// and disburse 250 on 01 June 2024
@BeforeEach
public void beforeEach() {
runAt("01 June 2024", () -> {
clientId = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId();
final PostLoanProductsResponse loanProductsResponse = loanProductHelper.createLoanProduct(create4IProgressive());
loanProductId = loanProductsResponse.getResourceId();
PostLoansResponse postLoansResponse = loanTransactionHelper.applyLoan(
applyLP2ProgressiveLoanRequest(clientId, loanProductsResponse.getResourceId(), "01 June 2024", 1000.0, 10.0, 4, null));
loanId = postLoansResponse.getLoanId();
loanTransactionHelper.approveLoan(loanId, approveLoanRequest(1000.0, "01 June 2024"));
disburseLoan(loanId, BigDecimal.valueOf(250.0), "01 June 2024");
});
}

@Test
public void testSavedToLoanNotChangingWithProduct() {
runAt("01 June 2024", () -> {
GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanId);
Assertions.assertEquals("REGULAR", loanDetails.getChargeOffBehaviour().getId());

loanProductHelper.updateLoanProductById(loanProductId,
new PutLoanProductsProductIdRequest().chargeOffBehaviour("ZERO_INTEREST"));
final GetLoanProductsProductIdResponse loanProduct = loanTransactionHelper.getLoanProduct(loanProductId.intValue());
Assertions.assertEquals("ZERO_INTEREST", loanProduct.getChargeOffBehaviour().getId());

loanDetails = loanTransactionHelper.getLoanDetails(loanId);
Assertions.assertEquals("REGULAR", loanDetails.getChargeOffBehaviour().getId());
});
}
}
Loading