FINERACT-1958-Autopayment-downpayment

This commit is contained in:
Ruchi Dhamankar
2023-08-15 08:33:12 +02:00
committed by Arnold Gálovics
parent 7c0c525cd5
commit ef2c446761
24 changed files with 503 additions and 52 deletions
@@ -424,4 +424,14 @@ public final class MathUtil {
public static Money min(Money first, Money second, Money third, boolean notNull) {
return min(min(first, second, notNull), third, notNull);
}
public static BigDecimal percentageOf(final BigDecimal value, final BigDecimal percentage, final int precision) {
BigDecimal percentageOf = BigDecimal.ZERO;
if (isGreaterThanZero(value)) {
final MathContext mc = new MathContext(precision, MoneyHelper.getRoundingMode());
final BigDecimal multiplicand = percentage.divide(BigDecimal.valueOf(100L), mc);
percentageOf = value.multiply(multiplicand, mc);
}
return percentageOf;
}
}
@@ -54,6 +54,7 @@ public class LoanTransactionEnumData {
private final boolean chargeAdjustment;
private final boolean chargeback;
private final boolean chargeoff;
private final boolean downPayment;
public LoanTransactionEnumData(final Long id, final String code, final String value) {
this.id = id;
@@ -83,11 +84,12 @@ public class LoanTransactionEnumData {
this.chargeback = Long.valueOf(25).equals(this.id);
this.chargeAdjustment = Long.valueOf(26).equals(this.id);
this.chargeoff = Long.valueOf(27).equals(this.id);
this.downPayment = Long.valueOf(28).equals(this.id);
}
public boolean isRepaymentType() {
if (isRepayment() || isMerchantIssuedRefund() || isPayoutRefund() || isGoodwillCredit() || isChargeRefund()
|| isChargeAdjustment()) {
if (isRepayment() || isMerchantIssuedRefund() || isPayoutRefund() || isGoodwillCredit() || isChargeRefund() || isChargeAdjustment()
|| isDownPayment()) {
return true;
}
return false;
@@ -2954,6 +2954,42 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
}
public void handleDownPayment(final BigDecimal disbursedAmount, final JsonCommand command,
final ScheduleGeneratorDTO scheduleGeneratorDTO) {
if (isAutoRepaymentForDownPaymentEnabled()) {
LocalDate disbursedOn = command.localDateValueOfParameterNamed(ACTUAL_DISBURSEMENT_DATE);
BigDecimal disbursedAmountPercentageForDownPayment = this.loanRepaymentScheduleDetail
.getDisbursedAmountPercentageForDownPayment();
ExternalId externalId = ExternalId.empty();
if (TemporaryConfigurationServiceContainer.isExternalIdAutoGenerationEnabled()) {
externalId = ExternalId.generate();
}
Money downPaymentMoney = Money.of(getCurrency(),
MathUtil.percentageOf(disbursedAmount, disbursedAmountPercentageForDownPayment, 9));
LoanTransaction downPaymentTransaction = LoanTransaction.downPayment(getOffice(), downPaymentMoney, null, disbursedOn,
externalId);
/*
* Currently mapping down payment transaction as repayment transaction to loan repayment schedule for
* consistency. Need to replace below logic for creating new installment for down payment and mapping.
*/
LoanEvent event = LoanEvent.LOAN_REPAYMENT_OR_WAIVER;
validateRepaymentTypeAccountStatus(downPaymentTransaction, event);
HolidayDetailDTO holidayDetailDTO = scheduleGeneratorDTO.getHolidayDetailDTO();
validateRepaymentDateIsOnHoliday(downPaymentTransaction.getTransactionDate(), holidayDetailDTO.isAllowTransactionsOnHoliday(),
holidayDetailDTO.getHolidays());
validateRepaymentDateIsOnNonWorkingDay(downPaymentTransaction.getTransactionDate(), holidayDetailDTO.getWorkingDays(),
holidayDetailDTO.isAllowTransactionsOnNonWorkingDay());
handleRepaymentOrRecoveryOrWaiverTransaction(downPaymentTransaction, loanLifecycleStateMachine, null, scheduleGeneratorDTO);
}
}
private boolean isAutoRepaymentForDownPaymentEnabled() {
return this.loanRepaymentScheduleDetail.isEnableDownPayment()
&& this.loanRepaymentScheduleDetail.isEnableAutoRepaymentForDownPayment();
}
public LoanTransaction handlePayDisbursementTransaction(final Long chargeId, final LoanTransaction chargesPayment,
final List<Long> existingTransactionIds, final List<Long> existingReversedTransactionIds) {
existingTransactionIds.addAll(findExistingTransactionIds());
@@ -3132,7 +3168,8 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
private void validateRepaymentTypeAccountStatus(LoanTransaction repaymentTransaction, LoanEvent event) {
if (repaymentTransaction.isGoodwillCredit() || repaymentTransaction.isMerchantIssuedRefund()
|| repaymentTransaction.isPayoutRefund() || repaymentTransaction.isChargeRefund() || repaymentTransaction.isRepayment()) {
|| repaymentTransaction.isPayoutRefund() || repaymentTransaction.isChargeRefund() || repaymentTransaction.isRepayment()
|| repaymentTransaction.isDownPayment()) {
if (!(isOpen() || isClosedObligationsMet() || isOverPaid())) {
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
@@ -180,6 +180,12 @@ public class LoanTransaction extends AbstractAuditableWithUTCDateTimeCustom {
externalId);
}
public static LoanTransaction downPayment(final Office office, final Money amount, final PaymentDetail paymentDetail,
final LocalDate paymentDate, final ExternalId externalId) {
return new LoanTransaction(null, office, LoanTransactionType.DOWN_PAYMENT, paymentDetail, amount.getAmount(), paymentDate,
externalId);
}
public void setLoanTransactionToRepaymentScheduleMappings(final Integer installmentId, final BigDecimal chargePerInstallment) {
for (LoanTransactionToRepaymentScheduleMapping loanTransactionToRepaymentScheduleMapping : this.loanTransactionToRepaymentScheduleMappings) {
final LoanRepaymentScheduleInstallment loanRepaymentScheduleInstallment = loanTransactionToRepaymentScheduleMapping
@@ -558,7 +564,7 @@ public class LoanTransaction extends AbstractAuditableWithUTCDateTimeCustom {
public boolean isRepaymentLikeType() {
return isRepayment() || isMerchantIssuedRefund() || isPayoutRefund() || isGoodwillCredit() || isChargeRefund()
|| isChargeAdjustment();
|| isChargeAdjustment() || isDownPayment();
}
public boolean isTypeAllowedForChargeback() {
@@ -573,6 +579,10 @@ public class LoanTransaction extends AbstractAuditableWithUTCDateTimeCustom {
return LoanTransactionType.MERCHANT_ISSUED_REFUND.equals(getTypeOf()) && isNotReversed();
}
public boolean isDownPayment() {
return LoanTransactionType.DOWN_PAYMENT.equals(getTypeOf()) && isNotReversed();
}
public boolean isPayoutRefund() {
return LoanTransactionType.PAYOUT_REFUND.equals(getTypeOf()) && isNotReversed();
}
@@ -59,7 +59,8 @@ public enum LoanTransactionType {
CHARGE_REFUND(24, "loanTransactionType.chargeRefund"), //
CHARGEBACK(25, "loanTransactionType.chargeback"), //
CHARGE_ADJUSTMENT(26, "loanTransactionType.chargeAdjustment"), //
CHARGE_OFF(27, "loanTransactionType.chargeOff");
CHARGE_OFF(27, "loanTransactionType.chargeOff"), //
DOWN_PAYMENT(28, "loanTransactionType.downPayment");
private final Integer value;
private final String code;
@@ -102,6 +103,7 @@ public enum LoanTransactionType {
case 25 -> LoanTransactionType.CHARGEBACK;
case 26 -> LoanTransactionType.CHARGE_ADJUSTMENT;
case 27 -> LoanTransactionType.CHARGE_OFF;
case 28 -> LoanTransactionType.DOWN_PAYMENT;
default -> LoanTransactionType.INVALID;
};
}
@@ -143,7 +145,7 @@ public enum LoanTransactionType {
}
public boolean isRepaymentType() {
return (isRepayment() || isMerchantIssuedRefund() || isPayoutRefund() || isGoodwillCredit() || isChargeRefund());
return (isRepayment() || isMerchantIssuedRefund() || isPayoutRefund() || isGoodwillCredit() || isChargeRefund() || isDownPayment());
}
public boolean isRecoveryRepayment() {
@@ -189,4 +191,8 @@ public enum LoanTransactionType {
public boolean isChargeOff() {
return this.equals(LoanTransactionType.CHARGE_OFF);
}
public boolean isDownPayment() {
return this.equals(LoanTransactionType.DOWN_PAYMENT);
}
}
@@ -209,6 +209,7 @@ public final class LoanApplicationTerms {
private LocalDate newScheduledDueDateStart;
private boolean isDownPaymentEnabled;
private BigDecimal disbursedAmountPercentageForDownPayment;
private boolean isAutoRepaymentForDownPaymentEnabled;
public static LoanApplicationTerms assembleFrom(final ApplicationCurrency currency, final Integer loanTermFrequency,
final PeriodFrequencyType loanTermPeriodFrequencyType, final Integer numberOfRepayments, final Integer repaymentEvery,
@@ -233,7 +234,8 @@ public final class LoanApplicationTerms {
boolean isSkipRepaymentOnFirstDayOfMonth, final HolidayDetailDTO holidayDetailDTO, final boolean allowCompoundingOnEod,
final boolean isEqualAmortization, final boolean isInterestToBeRecoveredFirstWhenGreaterThanEMI,
final BigDecimal fixedPrincipalPercentagePerInstallment, final boolean isPrincipalCompoundingDisabledForOverdueLoans,
final Boolean enableDownPayment, final BigDecimal disbursedAmountPercentageForDownPayment) {
final Boolean enableDownPayment, final BigDecimal disbursedAmountPercentageForDownPayment,
final Boolean isAutoRepaymentForDownPaymentEnabled) {
final LoanRescheduleStrategyMethod rescheduleStrategyMethod = null;
final CalendarHistoryDataWrapper calendarHistoryDataWrapper = null;
@@ -250,7 +252,8 @@ public final class LoanApplicationTerms {
calendarHistoryDataWrapper, isInterestChargedFromDateSameAsDisbursalDateEnabled, numberOfDays,
isSkipRepaymentOnFirstDayOfMonth, holidayDetailDTO, allowCompoundingOnEod, isEqualAmortization, false,
isInterestToBeRecoveredFirstWhenGreaterThanEMI, fixedPrincipalPercentagePerInstallment,
isPrincipalCompoundingDisabledForOverdueLoans, enableDownPayment, disbursedAmountPercentageForDownPayment);
isPrincipalCompoundingDisabledForOverdueLoans, enableDownPayment, disbursedAmountPercentageForDownPayment,
isAutoRepaymentForDownPaymentEnabled);
}
@@ -298,8 +301,10 @@ public final class LoanApplicationTerms {
final boolean isEqualAmortization = loanProductRelatedDetail.isEqualAmortization();
final boolean isDownPaymentEnabled = loanProductRelatedDetail.isEnableDownPayment();
BigDecimal disbursedAmountPercentageForDownPayment = null;
boolean isAutoRepaymentForDownPaymentEnabled = false;
if (isDownPaymentEnabled) {
disbursedAmountPercentageForDownPayment = loanProductRelatedDetail.getDisbursedAmountPercentageForDownPayment();
isAutoRepaymentForDownPaymentEnabled = loanProductRelatedDetail.isEnableAutoRepaymentForDownPayment();
}
return new LoanApplicationTerms(applicationCurrency, loanTermFrequency, loanTermPeriodFrequencyType, numberOfRepayments,
repaymentEvery, repaymentPeriodFrequencyType, ((nthDay != null) ? nthDay.getValue() : null), dayOfWeek, amortizationMethod,
@@ -315,7 +320,8 @@ public final class LoanApplicationTerms {
isInterestChargedFromDateSameAsDisbursalDateEnabled, numberOfDays, isSkipRepaymentOnFirstDayOfMonth, holidayDetailDTO,
allowCompoundingOnEod, isEqualAmortization, isFirstRepaymentDateAllowedOnHoliday,
isInterestToBeRecoveredFirstWhenGreaterThanEMI, fixedPrincipalPercentagePerInstallment,
isPrincipalCompoundingDisabledForOverdueLoans, isDownPaymentEnabled, disbursedAmountPercentageForDownPayment);
isPrincipalCompoundingDisabledForOverdueLoans, isDownPaymentEnabled, disbursedAmountPercentageForDownPayment,
isAutoRepaymentForDownPaymentEnabled);
}
private LoanApplicationTerms(final ApplicationCurrency currency, final Integer loanTermFrequency,
@@ -342,7 +348,7 @@ public final class LoanApplicationTerms {
final boolean allowCompoundingOnEod, final boolean isEqualAmortization, final boolean isFirstRepaymentDateAllowedOnHoliday,
final boolean isInterestToBeRecoveredFirstWhenGreaterThanEMI, final BigDecimal fixedPrincipalPercentagePerInstallment,
final boolean isPrincipalCompoundingDisabledForOverdueLoans, final boolean isDownPaymentEnabled,
final BigDecimal disbursedAmountPercentageForDownPayment) {
final BigDecimal disbursedAmountPercentageForDownPayment, final boolean isAutoRepaymentForDownPaymentEnabled) {
this.currency = currency;
this.loanTermFrequency = loanTermFrequency;
@@ -421,6 +427,7 @@ public final class LoanApplicationTerms {
this.isPrincipalCompoundingDisabledForOverdueLoans = isPrincipalCompoundingDisabledForOverdueLoans;
this.isDownPaymentEnabled = isDownPaymentEnabled;
this.disbursedAmountPercentageForDownPayment = disbursedAmountPercentageForDownPayment;
this.isAutoRepaymentForDownPaymentEnabled = isAutoRepaymentForDownPaymentEnabled;
}
public Money adjustPrincipalIfLastRepaymentPeriod(final Money principalForPeriod, final Money totalCumulativePrincipalToDate,
@@ -1265,7 +1272,7 @@ public final class LoanApplicationTerms {
this.interestPaymentGrace, this.interestChargingGrace, this.amortizationMethod, this.inArrearsTolerance.getAmount(),
this.graceOnArrearsAgeing, this.daysInMonthType.getValue(), this.daysInYearType.getValue(),
this.interestRecalculationEnabled, this.isEqualAmortization, this.isDownPaymentEnabled,
this.disbursedAmountPercentageForDownPayment);
this.disbursedAmountPercentageForDownPayment, this.isAutoRepaymentForDownPaymentEnabled);
}
public Integer getLoanTermFrequency() {
@@ -150,5 +150,6 @@ public interface LoanProductConstants {
// down-payment related
String ENABLE_DOWN_PAYMENT = "enableDownPayment";
String DISBURSED_AMOUNT_PERCENTAGE_DOWN_PAYMENT = "disbursedAmountPercentageForDownPayment";
String ENABLE_AUTO_REPAYMENT_DOWN_PAYMENT = "enableAutoRepaymentForDownPayment";
}
@@ -388,6 +388,8 @@ public class LoanProduct extends AbstractPersistableCustom {
final boolean enableDownPayment = command.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.ENABLE_DOWN_PAYMENT);
final BigDecimal disbursedAmountPercentageDownPayment = command
.bigDecimalValueOfParameterNamed(LoanProductConstants.DISBURSED_AMOUNT_PERCENTAGE_DOWN_PAYMENT);
final boolean enableAutoRepaymentForDownPayment = command
.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.ENABLE_AUTO_REPAYMENT_DOWN_PAYMENT);
return new LoanProduct(fund, loanTransactionProcessingStrategy, name, shortName, description, currency, principal, minPrincipal,
maxPrincipal, interestRatePerPeriod, minInterestRatePerPeriod, maxInterestRatePerPeriod, interestFrequencyType,
@@ -405,7 +407,7 @@ public class LoanProduct extends AbstractPersistableCustom {
minimumGapBetweenInstallments, maximumGapBetweenInstallments, syncExpectedWithDisbursementDate, canUseForTopup,
isEqualAmortization, productRates, fixedPrincipalPercentagePerInstallment, disallowExpectedDisbursements,
allowApprovedDisbursedAmountsOverApplied, overAppliedCalculationType, overAppliedNumber, dueDaysForRepaymentEvent,
overDueDaysForRepaymentEvent, enableDownPayment, disbursedAmountPercentageDownPayment);
overDueDaysForRepaymentEvent, enableDownPayment, disbursedAmountPercentageDownPayment, enableAutoRepaymentForDownPayment);
}
@@ -617,7 +619,8 @@ public class LoanProduct extends AbstractPersistableCustom {
final List<Rate> rates, final BigDecimal fixedPrincipalPercentagePerInstallment, final boolean disallowExpectedDisbursements,
final boolean allowApprovedDisbursedAmountsOverApplied, final String overAppliedCalculationType,
final Integer overAppliedNumber, final Integer dueDaysForRepaymentEvent, final Integer overDueDaysForRepaymentEvent,
final boolean enableDownPayment, final BigDecimal disbursedAmountPercentageForDownPayment) {
final boolean enableDownPayment, final BigDecimal disbursedAmountPercentageForDownPayment,
final boolean enableAutoRepaymentForDownPayment) {
this.fund = fund;
this.transactionProcessingStrategyCode = transactionProcessingStrategyCode;
this.name = name.trim();
@@ -650,7 +653,8 @@ public class LoanProduct extends AbstractPersistableCustom {
considerPartialPeriodInterest, repayEvery, repaymentFrequencyType, defaultNumberOfInstallments, graceOnPrincipalPayment,
recurringMoratoriumOnPrincipalPeriods, graceOnInterestPayment, graceOnInterestCharged, amortizationMethod,
inArrearsTolerance, graceOnArrearsAgeing, daysInMonthType.getValue(), daysInYearType.getValue(),
isInterestRecalculationEnabled, isEqualAmortization, enableDownPayment, disbursedAmountPercentageForDownPayment);
isInterestRecalculationEnabled, isEqualAmortization, enableDownPayment, disbursedAmountPercentageForDownPayment,
enableAutoRepaymentForDownPayment);
this.loanProductRelatedDetail.validateRepaymentPeriodWithGraceSettings();
@@ -1235,6 +1239,13 @@ public class LoanProduct extends AbstractPersistableCustom {
this.loanProductRelatedDetail.updateDisbursedAmountPercentageForDownPayment(newValue);
}
if (command.isChangeInBooleanParameterNamed(LoanProductConstants.ENABLE_AUTO_REPAYMENT_DOWN_PAYMENT,
this.loanProductRelatedDetail.isEnableAutoRepaymentForDownPayment())) {
final boolean newValue = command.booleanPrimitiveValueOfParameterNamed(LoanProductConstants.ENABLE_AUTO_REPAYMENT_DOWN_PAYMENT);
actualChanges.put(LoanProductConstants.ENABLE_AUTO_REPAYMENT_DOWN_PAYMENT, newValue);
this.loanProductRelatedDetail.updateEnableAutoRepaymentForDownPayment(newValue);
}
return actualChanges;
}
@@ -135,6 +135,9 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
@Column(name = "disbursed_amount_percentage_for_down_payment", scale = 6, precision = 9)
private BigDecimal disbursedAmountPercentageForDownPayment;
@Column(name = "enable_auto_repayment_for_down_payment", nullable = false)
private boolean enableAutoRepaymentForDownPayment;
public static LoanProductRelatedDetail createFrom(final MonetaryCurrency currency, final BigDecimal principal,
final BigDecimal nominalInterestRatePerPeriod, final PeriodFrequencyType interestRatePeriodFrequencyType,
final BigDecimal nominalAnnualInterestRate, final InterestMethod interestMethod,
@@ -144,14 +147,15 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
final Integer graceOnInterestPayment, final Integer graceOnInterestCharged, final AmortizationMethod amortizationMethod,
final BigDecimal inArrearsTolerance, final Integer graceOnArrearsAgeing, final Integer daysInMonthType,
final Integer daysInYearType, final boolean isInterestRecalculationEnabled, final boolean isEqualAmortization,
final boolean enableDownPayment, final BigDecimal disbursedAmountPercentageForDownPayment) {
final boolean enableDownPayment, final BigDecimal disbursedAmountPercentageForDownPayment,
final boolean enableAutoRepaymentForDownPayment) {
return new LoanProductRelatedDetail(currency, principal, nominalInterestRatePerPeriod, interestRatePeriodFrequencyType,
nominalAnnualInterestRate, interestMethod, interestCalculationPeriodMethod, allowPartialPeriodInterestCalcualtion,
repaymentEvery, repaymentPeriodFrequencyType, numberOfRepayments, graceOnPrincipalPayment,
recurringMoratoriumOnPrincipalPeriods, graceOnInterestPayment, graceOnInterestCharged, amortizationMethod,
inArrearsTolerance, graceOnArrearsAgeing, daysInMonthType, daysInYearType, isInterestRecalculationEnabled,
isEqualAmortization, enableDownPayment, disbursedAmountPercentageForDownPayment);
isEqualAmortization, enableDownPayment, disbursedAmountPercentageForDownPayment, enableAutoRepaymentForDownPayment);
}
protected LoanProductRelatedDetail() {
@@ -167,7 +171,8 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
final Integer graceOnInterestPayment, final Integer graceOnInterestCharged, final AmortizationMethod amortizationMethod,
final BigDecimal inArrearsTolerance, final Integer graceOnArrearsAgeing, final Integer daysInMonthType,
final Integer daysInYearType, final boolean isInterestRecalculationEnabled, final boolean isEqualAmortization,
final boolean enableDownPayment, final BigDecimal disbursedAmountPercentageForDownPayment) {
final boolean enableDownPayment, final BigDecimal disbursedAmountPercentageForDownPayment,
final boolean enableAutoRepaymentForDownPayment) {
this.currency = currency;
this.principal = defaultPrincipal;
this.nominalInterestRatePerPeriod = defaultNominalInterestRatePerPeriod;
@@ -196,6 +201,7 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
this.isEqualAmortization = isEqualAmortization;
this.enableDownPayment = enableDownPayment;
this.disbursedAmountPercentageForDownPayment = disbursedAmountPercentageForDownPayment;
this.enableAutoRepaymentForDownPayment = enableAutoRepaymentForDownPayment;
}
private Integer defaultToNullIfZero(final Integer value) {
@@ -701,4 +707,12 @@ public class LoanProductRelatedDetail implements LoanProductMinimumRepaymentSche
public void updateDisbursedAmountPercentageForDownPayment(BigDecimal disbursedAmountPercentageForDownPayment) {
this.disbursedAmountPercentageForDownPayment = disbursedAmountPercentageForDownPayment;
}
public Boolean isEnableAutoRepaymentForDownPayment() {
return enableAutoRepaymentForDownPayment;
}
public void updateEnableAutoRepaymentForDownPayment(boolean enableAutoRepaymentForDownPayment) {
this.enableAutoRepaymentForDownPayment = enableAutoRepaymentForDownPayment;
}
}
@@ -293,6 +293,8 @@ public final class LoanEnumerations {
LoanTransactionType.CHARGE_ADJUSTMENT.getCode(), "Charge Adjustment");
case CHARGE_OFF -> new LoanTransactionEnumData(LoanTransactionType.CHARGE_OFF.getValue().longValue(),
LoanTransactionType.CHARGE_OFF.getCode(), "Charge-off");
case DOWN_PAYMENT -> new LoanTransactionEnumData(LoanTransactionType.DOWN_PAYMENT.getValue().longValue(),
LoanTransactionType.DOWN_PAYMENT.getCode(), "Down Payment");
};
}
@@ -25,4 +25,5 @@
<!-- Sequence is starting from 1000 to make it easier to move existing liquibase changesets here -->
<include relativeToChangelogFile="true" file="parts/1001_add_audit_fields_to_loan_charge.xml"/>
<include relativeToChangelogFile="true" file="parts/1002_add_payment_allocation_rule.xml"/>
<include relativeToChangelogFile="true" file="parts/1003_add_loan_product_auto_repayment_down_payment_configuration.xml"/>
</databaseChangeLog>
@@ -0,0 +1,39 @@
<?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.1.xsd">
<changeSet author="fineract" id="1">
<addColumn tableName="m_product_loan">
<column defaultValueBoolean="false" type="boolean" name="enable_auto_repayment_for_down_payment">
<constraints nullable="false"/>
</column>
</addColumn>
</changeSet>
<changeSet author="fineract" id="2">
<addColumn tableName="m_loan">
<column defaultValueBoolean="false" type="boolean" name="enable_auto_repayment_for_down_payment">
<constraints nullable="false"/>
</column>
</addColumn>
</changeSet>
</databaseChangeLog>