FINERACT-1829-Store-Overpaid-Date-for-Loan

This commit is contained in:
Ruchi Dhamankar
2022-12-15 14:10:44 +01:00
committed by Arnold Gálovics
parent 41440e4ca4
commit 8457b31c0f
7 changed files with 255 additions and 14 deletions
@@ -1005,6 +1005,8 @@ final class LoansApiResourceSwagger {
@Schema(example = "250.000000")
public Double totalOverpaid;
public LocalDate lastClosedBusinessDate;
@Schema(example = "[2013, 11, 1]")
public LocalDate overpaidOnDate;
}
@Schema(description = "GetLoansResponse")
@@ -247,6 +247,7 @@ public class LoanAccountData {
private String linkAccountId;
private Long groupId;
private LocalDate expectedDisbursementDate;
private LocalDate overpaidOnDate;
private CollectionData delinquent;
private DelinquencyRangeData delinquencyRange;
@@ -379,7 +380,7 @@ public class LoanAccountData {
.setIsEqualAmortization(acc.isEqualAmortization).setRates(acc.rates).setIsRatesEnabled(acc.isRatesEnabled)
.setFixedPrincipalPercentagePerInstallment(acc.fixedPrincipalPercentagePerInstallment).setDelinquent(acc.delinquent)
.setDelinquencyRange(acc.delinquencyRange).setDisallowExpectedDisbursements(acc.disallowExpectedDisbursements)
.setFraud(acc.fraud);
.setFraud(acc.fraud).setOverpaidOnDate(acc.overpaidOnDate);
}
/**
@@ -450,7 +451,7 @@ public class LoanAccountData {
.setIsEqualAmortization(acc.isEqualAmortization).setRates(acc.rates).setIsRatesEnabled(acc.isRatesEnabled)
.setFixedPrincipalPercentagePerInstallment(acc.fixedPrincipalPercentagePerInstallment).setDelinquent(acc.delinquent)
.setDelinquencyRange(acc.delinquencyRange).setDisallowExpectedDisbursements(acc.disallowExpectedDisbursements)
.setFraud(acc.fraud);
.setFraud(acc.fraud).setOverpaidOnDate(acc.overpaidOnDate);
}
public static LoanAccountData loanProductWithTemplateDefaults(final LoanProductData product,
@@ -617,7 +618,8 @@ public class LoanAccountData {
.setClosureLoanId(acc.closureLoanId).setClosureLoanAccountNo(acc.closureLoanAccountNo).setTopupAmount(acc.topupAmount)
.setIsEqualAmortization(product.isEqualAmortization()).setRates(acc.rates).setIsRatesEnabled(acc.isRatesEnabled)
.setFixedPrincipalPercentagePerInstallment(product.getFixedPrincipalPercentagePerInstallment()).setDelinquent(delinquent)
.setDisallowExpectedDisbursements(product.getDisallowExpectedDisbursements()).setFraud(acc.fraud);
.setDisallowExpectedDisbursements(product.getDisallowExpectedDisbursements()).setFraud(acc.fraud)
.setOverpaidOnDate(acc.overpaidOnDate);
}
/*
@@ -650,7 +652,7 @@ public class LoanAccountData {
final boolean canUseForTopup, final boolean isTopup, final Long closureLoanId, final String closureLoanAccountNo,
final BigDecimal topupAmount, final boolean isEqualAmortization, final BigDecimal fixedPrincipalPercentagePerInstallment,
final DelinquencyRangeData delinquencyRange, final boolean disallowExpectedDisbursements, final boolean fraud,
LocalDate lastClosedBusinessDate) {
LocalDate lastClosedBusinessDate, LocalDate overpaidOnDate) {
final CollectionData delinquent = CollectionData.template();
@@ -690,7 +692,7 @@ public class LoanAccountData {
.setClosureLoanAccountNo(closureLoanAccountNo).setTopupAmount(topupAmount).setIsEqualAmortization(isEqualAmortization)
.setFixedPrincipalPercentagePerInstallment(fixedPrincipalPercentagePerInstallment).setDelinquent(delinquent)
.setDelinquencyRange(delinquencyRange).setDisallowExpectedDisbursements(disallowExpectedDisbursements).setFraud(fraud)
.setLastClosedBusinessDate(lastClosedBusinessDate);
.setLastClosedBusinessDate(lastClosedBusinessDate).setOverpaidOnDate(overpaidOnDate);
}
/*
@@ -774,7 +776,7 @@ public class LoanAccountData {
.setIsEqualAmortization(acc.isEqualAmortization)
.setFixedPrincipalPercentagePerInstallment(acc.fixedPrincipalPercentagePerInstallment)
.setDelinquencyRange(acc.delinquencyRange).setDisallowExpectedDisbursements(acc.disallowExpectedDisbursements)
.setFraud(acc.fraud).setLastClosedBusinessDate(acc.getLastClosedBusinessDate());
.setFraud(acc.fraud).setLastClosedBusinessDate(acc.getLastClosedBusinessDate()).setOverpaidOnDate(acc.overpaidOnDate);
}
public static LoanAccountData associationsAndTemplate(final LoanAccountData acc, final Collection<LoanProductData> productOptions,
@@ -849,7 +851,7 @@ public class LoanAccountData {
.setIsEqualAmortization(acc.isEqualAmortization).setRates(acc.rates).setIsRatesEnabled(acc.isRatesEnabled)
.setFixedPrincipalPercentagePerInstallment(acc.fixedPrincipalPercentagePerInstallment).setDelinquent(acc.delinquent)
.setDelinquencyRange(acc.delinquencyRange).setDisallowExpectedDisbursements(acc.disallowExpectedDisbursements)
.setFraud(acc.fraud);
.setFraud(acc.fraud).setOverpaidOnDate(acc.overpaidOnDate);
}
public static LoanAccountData associateMemberVariations(final LoanAccountData acc, final Map<Long, Integer> memberLoanCycle) {
@@ -946,7 +948,7 @@ public class LoanAccountData {
.setIsEqualAmortization(acc.isEqualAmortization).setRates(acc.rates).setIsRatesEnabled(acc.isRatesEnabled)
.setFixedPrincipalPercentagePerInstallment(acc.fixedPrincipalPercentagePerInstallment).setDelinquent(acc.delinquent)
.setDelinquencyRange(acc.delinquencyRange).setDisallowExpectedDisbursements(acc.disallowExpectedDisbursements)
.setFraud(acc.fraud);
.setFraud(acc.fraud).setOverpaidOnDate(acc.overpaidOnDate);
}
public static LoanAccountData withInterestRecalculationCalendarData(final LoanAccountData acc, final CalendarData calendarData,
@@ -1011,7 +1013,7 @@ public class LoanAccountData {
.setIsEqualAmortization(acc.isEqualAmortization).setRates(acc.rates).setIsRatesEnabled(acc.isRatesEnabled)
.setFixedPrincipalPercentagePerInstallment(acc.fixedPrincipalPercentagePerInstallment).setDelinquent(acc.delinquent)
.setDelinquencyRange(acc.delinquencyRange).setDisallowExpectedDisbursements(acc.disallowExpectedDisbursements)
.setFraud(acc.fraud);
.setFraud(acc.fraud).setOverpaidOnDate(acc.overpaidOnDate);
}
public static LoanAccountData withLoanCalendarData(final LoanAccountData acc, final CalendarData calendarData) {
@@ -1069,7 +1071,7 @@ public class LoanAccountData {
.setIsEqualAmortization(acc.isEqualAmortization).setRates(acc.rates).setIsRatesEnabled(acc.isRatesEnabled)
.setFixedPrincipalPercentagePerInstallment(acc.fixedPrincipalPercentagePerInstallment).setDelinquent(acc.delinquent)
.setDelinquencyRange(acc.delinquencyRange).setDisallowExpectedDisbursements(acc.disallowExpectedDisbursements)
.setFraud(acc.fraud);
.setFraud(acc.fraud).setOverpaidOnDate(acc.overpaidOnDate);
}
public static LoanAccountData withOriginalSchedule(final LoanAccountData acc, final LoanScheduleData originalSchedule) {
@@ -1130,7 +1132,7 @@ public class LoanAccountData {
.setIsEqualAmortization(acc.isEqualAmortization).setRates(acc.rates).setIsRatesEnabled(acc.isRatesEnabled)
.setFixedPrincipalPercentagePerInstallment(acc.fixedPrincipalPercentagePerInstallment).setDelinquent(acc.delinquent)
.setDelinquencyRange(acc.delinquencyRange).setDisallowExpectedDisbursements(acc.disallowExpectedDisbursements)
.setFraud(acc.fraud);
.setFraud(acc.fraud).setOverpaidOnDate(acc.overpaidOnDate);
}
public static final Comparator<LoanAccountData> ClientNameComparator = (loan1, loan2) -> {
@@ -314,6 +314,9 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
@Column(name = "total_overpaid_derived", scale = 6, precision = 19)
private BigDecimal totalOverpaid;
@Column(name = "overpaidon_date")
private LocalDate overpaidOnDate;
@Column(name = "loan_counter")
private Integer loanCounter;
@@ -3410,6 +3413,9 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
handleLoanRepaymentInFull(transactionDate, loanLifecycleStateMachine);
statusChanged = true;
}
if (this.totalOverpaid == null || BigDecimal.ZERO.compareTo(this.totalOverpaid) == 0) {
this.overpaidOnDate = null;
}
return statusChanged;
}
@@ -3429,6 +3435,9 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
this.closedOnDate = transactionDate;
this.actualMaturityDate = transactionDate;
} else if (LoanStatus.fromInt(this.loanStatus).isOverpaid()) {
if (this.totalOverpaid == null || BigDecimal.ZERO.compareTo(this.totalOverpaid) == 0) {
this.overpaidOnDate = null;
}
loanLifecycleStateMachine.transition(LoanEvent.LOAN_REPAYMENT_OR_WAIVER, this);
}
processIncomeAccrualTransactionOnLoanClosure();
@@ -3512,7 +3521,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
private void handleLoanOverpayment(final LoanLifecycleStateMachine loanLifecycleStateMachine) {
loanLifecycleStateMachine.transition(LoanEvent.LOAN_OVERPAYMENT, this);
this.overpaidOnDate = DateUtils.getBusinessLocalDate();
this.closedOnDate = null;
this.actualMaturityDate = null;
}
@@ -5280,6 +5289,10 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
return this.totalOverpaid;
}
public LocalDate getOverpaidOnDate() {
return this.overpaidOnDate;
}
public void updateIsInterestRecalculationEnabled() {
this.loanRepaymentScheduleDetail.updateIsInterestRecalculationEnabled(isInterestRecalculationEnabledForProduct());
}
@@ -6086,6 +6099,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
updateLoanSummaryDerivedFields();
if (this.totalOverpaid == null || BigDecimal.ZERO.compareTo(this.totalOverpaid) == 0) {
this.overpaidOnDate = null;
defaultLoanLifecycleStateMachine.transition(LoanEvent.LOAN_CREDIT_BALANCE_REFUND, this);
}
@@ -661,7 +661,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
+ " lpvi.minimum_gap as minimuminstallmentgap, lpvi.maximum_gap as maximuminstallmentgap, "
+ " lp.can_use_for_topup as canUseForTopup, l.is_topup as isTopup, topup.closure_loan_id as closureLoanId, "
+ " l.total_recovered_derived as totalRecovered, topuploan.account_no as closureLoanAccountNo, "
+ " topup.topup_amount as topupAmount, l.last_closed_business_date as lastClosedBusinessDate from m_loan l" //
+ " topup.topup_amount as topupAmount, l.last_closed_business_date as lastClosedBusinessDate,l.overpaidon_date as overpaidOnDate 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."
+ sqlGenerator.escape("code") + " = l.currency_code" //
@@ -988,6 +988,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
final boolean isFraud = rs.getBoolean("isFraud");
final LocalDate lastClosedBusinessDate = JdbcSupport.getLocalDate(rs, "lastClosedBusinessDate");
final LocalDate overpaidOnDate = JdbcSupport.getLocalDate(rs, "overpaidOnDate");
return LoanAccountData.basicLoanDetails(id, accountNo, status, externalId, clientId, clientAccountNo, clientName,
clientOfficeId, clientExternalId, groupData, loanType, loanProductId, loanProductName, loanProductDescription,
@@ -1004,7 +1005,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
createStandingInstructionAtDisbursement, isvariableInstallmentsAllowed, minimumGap, maximumGap, loanSubStatus,
canUseForTopup, isTopup, closureLoanId, closureLoanAccountNo, topupAmount, isEqualAmortization,
fixedPrincipalPercentagePerInstallment, delinquencyRange, disallowExpectedDisbursements, isFraud,
lastClosedBusinessDate);
lastClosedBusinessDate, overpaidOnDate);
}
}
@@ -96,4 +96,5 @@
<include file="parts/0074_add_last_cob_business_date_column_to_loan.xml" relativeToChangelogFile="true"/>
<include file="parts/0075_add_processed_commands_purge_job.xml" relativeToChangelogFile="true" />
<include file="parts/0076_add_loan_transaction_enum_values.xml" relativeToChangelogFile="true" />
<include file="parts/0077_add_overpaid_date_for_loan.xml" relativeToChangelogFile="true" />
</databaseChangeLog>
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.3.xsd">
<changeSet author="fineract" id="1">
<addColumn tableName="m_loan">
<column name="overpaidon_date" type="date">
<constraints nullable="true"/>
</column>
</addColumn>
</changeSet>
</databaseChangeLog>