diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoanApiConstants.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoanApiConstants.java index d36273d91..045c3fc9f 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoanApiConstants.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoanApiConstants.java @@ -25,6 +25,7 @@ public interface LoanApiConstants { String disbursementDataParameterName = "disbursementData"; String disbursementDateParameterName = "expectedDisbursementDate"; String disbursementPrincipalParameterName = "principal"; + String disbursementNetDisbursalAmountParameterName = "netDisbursalAmount"; String updatedDisbursementDateParameterName = "updatedExpectedDisbursementDate"; String updatedDisbursementPrincipalParameterName = "updatedPrincipal"; String disbursementIdParameterName = "id"; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/DisbursementData.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/DisbursementData.java index 322d02fd1..6cea5e44f 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/DisbursementData.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/DisbursementData.java @@ -31,6 +31,7 @@ public class DisbursementData implements Comparable { private final LocalDate expectedDisbursementDate; private final LocalDate actualDisbursementDate; private final BigDecimal principal; + private final BigDecimal netDisbursalAmount; @SuppressWarnings("unused") private final String loanChargeId; private final BigDecimal chargeAmount; @@ -61,6 +62,7 @@ public class DisbursementData implements Comparable { this.loanChargeId = null; this.chargeAmount = null; this.waivedChargeAmount = null; + this.netDisbursalAmount = null; } @@ -69,7 +71,8 @@ public class DisbursementData implements Comparable { } public DisbursementData(Long id, final LocalDate expectedDisbursementDate, final LocalDate actualDisbursementDate, - final BigDecimal principalDisbursed, final String loanChargeId, BigDecimal chargeAmount, BigDecimal waivedChargeAmount) { + final BigDecimal principalDisbursed, final BigDecimal netDisbursalAmount, final String loanChargeId, BigDecimal chargeAmount, + BigDecimal waivedChargeAmount) { this.id = id; this.expectedDisbursementDate = expectedDisbursementDate; this.actualDisbursementDate = actualDisbursementDate; @@ -77,6 +80,7 @@ public class DisbursementData implements Comparable { this.loanChargeId = loanChargeId; this.chargeAmount = chargeAmount; this.waivedChargeAmount = waivedChargeAmount; + this.netDisbursalAmount = netDisbursalAmount; } public LocalDate disbursementDate() { diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanAccountData.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanAccountData.java index 9279a5262..d1576499f 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanAccountData.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanAccountData.java @@ -93,6 +93,7 @@ public final class LoanAccountData { private final BigDecimal principal; private final BigDecimal approvedPrincipal; private final BigDecimal proposedPrincipal; + private final BigDecimal netDisbursalAmount; private final Integer termFrequency; private final EnumOptionData termPeriodFrequencyType; @@ -337,6 +338,7 @@ public final class LoanAccountData { this.approvedPrincipal = null; this.proposedPrincipal = null; + this.netDisbursalAmount = null; this.termFrequency = null; this.termPeriodFrequencyType = null; @@ -491,6 +493,7 @@ public final class LoanAccountData { final CurrencyData currencyData = null; final BigDecimal proposedPrincipal = null; final BigDecimal principal = null; + final BigDecimal netDisbursalAmount = null; final BigDecimal totalOverpaid = null; final BigDecimal inArrearsTolerance = null; final Integer termFrequency = null; @@ -586,11 +589,11 @@ public final class LoanAccountData { return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId, group, loanType, loanProductId, loanProductName, loanProductDescription, isLoanProductLinkedToFloatingRate, fundId, fundName, loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName, currencyData, proposedPrincipal, principal, principal, - totalOverpaid, inArrearsTolerance, termFrequency, termPeriodFrequencyType, numberOfRepayments, repaymentEvery, - repaymentFrequencyType, repaymentFrequencyNthDayType, repaymentFrequencyDayOfWeekType, transactionProcessingStrategyId, - transactionProcessingStrategyName, amortizationType, interestRatePerPeriod, interestRateFrequencyType, annualInterestRate, - interestType, isFloatingInterestRate, interestRateDifferential, interestCalculationPeriodType, - allowPartialPeriodInterestCalcualtion, expectedFirstRepaymentOnDate, graceOnPrincipalPayment, + netDisbursalAmount, totalOverpaid, inArrearsTolerance, termFrequency, termPeriodFrequencyType, numberOfRepayments, + repaymentEvery, repaymentFrequencyType, repaymentFrequencyNthDayType, repaymentFrequencyDayOfWeekType, + transactionProcessingStrategyId, transactionProcessingStrategyName, amortizationType, interestRatePerPeriod, + interestRateFrequencyType, annualInterestRate, interestType, isFloatingInterestRate, interestRateDifferential, + interestCalculationPeriodType, allowPartialPeriodInterestCalcualtion, expectedFirstRepaymentOnDate, graceOnPrincipalPayment, recurringMoratoriumOnPrincipalPeriods, graceOnInterestPayment, graceOnInterestCharged, interestChargedFromDate, timeline, summary, feeChargesDueAtDisbursementCharged, repaymentSchedule, transactions, charges, collateral, guarantors, calendarData, productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, repaymentFrequencyNthDayTypeOptions, @@ -632,6 +635,7 @@ public final class LoanAccountData { final CurrencyData currencyData = null; final BigDecimal proposedPrincipal = null; final BigDecimal principal = null; + final BigDecimal netDisbursalAmount = null; final BigDecimal totalOverpaid = null; final BigDecimal inArrearsTolerance = null; final Integer termFrequency = null; @@ -729,11 +733,11 @@ public final class LoanAccountData { return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId, group, loanType, loanProductId, loanProductName, loanProductDescription, isLoanProductLinkedToFloatingRate, fundId, fundName, loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName, currencyData, proposedPrincipal, principal, principal, - totalOverpaid, inArrearsTolerance, termFrequency, termPeriodFrequencyType, numberOfRepayments, repaymentEvery, - repaymentFrequencyType, repaymentFrequencyNthDayType, repaymentFrequencyDayOfWeekType, transactionProcessingStrategyId, - transactionProcessingStrategyName, amortizationType, interestRatePerPeriod, interestRateFrequencyType, annualInterestRate, - interestType, isFloatingInterestRate, interestRateDifferential, interestCalculationPeriodType, - allowPartialPeriodInterestCalcualtion, expectedFirstRepaymentOnDate, graceOnPrincipalPayment, + netDisbursalAmount, totalOverpaid, inArrearsTolerance, termFrequency, termPeriodFrequencyType, numberOfRepayments, + repaymentEvery, repaymentFrequencyType, repaymentFrequencyNthDayType, repaymentFrequencyDayOfWeekType, + transactionProcessingStrategyId, transactionProcessingStrategyName, amortizationType, interestRatePerPeriod, + interestRateFrequencyType, annualInterestRate, interestType, isFloatingInterestRate, interestRateDifferential, + interestCalculationPeriodType, allowPartialPeriodInterestCalcualtion, expectedFirstRepaymentOnDate, graceOnPrincipalPayment, recurringMoratoriumOnPrincipalPeriods, graceOnInterestPayment, graceOnInterestCharged, interestChargedFromDate, timeline, summary, feeChargesDueAtDisbursementCharged, repaymentSchedule, transactions, charges, collateral, guarantors, calendarData, productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, repaymentFrequencyNthDayTypeOptions, @@ -755,19 +759,20 @@ public final class LoanAccountData { clientAcc.clientName, clientAcc.clientOfficeId, acc.group, acc.loanType, acc.loanProductId, acc.loanProductName, acc.loanProductDescription, acc.isLoanProductLinkedToFloatingRate, acc.fundId, acc.fundName, acc.loanPurposeId, acc.loanPurposeName, acc.loanOfficerId, acc.loanOfficerName, acc.currency, acc.proposedPrincipal, acc.principal, - acc.approvedPrincipal, acc.totalOverpaid, acc.inArrearsTolerance, acc.termFrequency, acc.termPeriodFrequencyType, - acc.numberOfRepayments, acc.repaymentEvery, acc.repaymentFrequencyType, acc.repaymentFrequencyNthDayType, - acc.repaymentFrequencyDayOfWeekType, acc.transactionProcessingStrategyId, acc.transactionProcessingStrategyName, - acc.amortizationType, acc.interestRatePerPeriod, acc.interestRateFrequencyType, acc.annualInterestRate, acc.interestType, - acc.isFloatingInterestRate, acc.interestRateDifferential, acc.interestCalculationPeriodType, - acc.allowPartialPeriodInterestCalcualtion, acc.expectedFirstRepaymentOnDate, acc.graceOnPrincipalPayment, - acc.recurringMoratoriumOnPrincipalPeriods, acc.graceOnInterestPayment, acc.graceOnInterestCharged, - acc.interestChargedFromDate, clientAcc.timeline, acc.summary, acc.feeChargesAtDisbursementCharged, acc.repaymentSchedule, - acc.transactions, acc.charges, acc.collateral, acc.guarantors, acc.meeting, acc.productOptions, - acc.termFrequencyTypeOptions, acc.repaymentFrequencyTypeOptions, acc.repaymentFrequencyNthDayTypeOptions, - acc.repaymentFrequencyDaysOfWeekTypeOptions, acc.transactionProcessingStrategyOptions, acc.interestRateFrequencyTypeOptions, - acc.amortizationTypeOptions, acc.interestTypeOptions, acc.interestCalculationPeriodTypeOptions, acc.fundOptions, - acc.chargeOptions, null, acc.loanOfficerOptions, acc.loanPurposeOptions, acc.loanCollateralOptions, acc.calendarOptions, + acc.approvedPrincipal, acc.netDisbursalAmount, acc.totalOverpaid, acc.inArrearsTolerance, acc.termFrequency, + acc.termPeriodFrequencyType, acc.numberOfRepayments, acc.repaymentEvery, acc.repaymentFrequencyType, + acc.repaymentFrequencyNthDayType, acc.repaymentFrequencyDayOfWeekType, acc.transactionProcessingStrategyId, + acc.transactionProcessingStrategyName, acc.amortizationType, acc.interestRatePerPeriod, acc.interestRateFrequencyType, + acc.annualInterestRate, acc.interestType, acc.isFloatingInterestRate, acc.interestRateDifferential, + acc.interestCalculationPeriodType, acc.allowPartialPeriodInterestCalcualtion, acc.expectedFirstRepaymentOnDate, + acc.graceOnPrincipalPayment, acc.recurringMoratoriumOnPrincipalPeriods, acc.graceOnInterestPayment, + acc.graceOnInterestCharged, acc.interestChargedFromDate, clientAcc.timeline, acc.summary, + acc.feeChargesAtDisbursementCharged, acc.repaymentSchedule, acc.transactions, acc.charges, acc.collateral, acc.guarantors, + acc.meeting, acc.productOptions, acc.termFrequencyTypeOptions, acc.repaymentFrequencyTypeOptions, + acc.repaymentFrequencyNthDayTypeOptions, acc.repaymentFrequencyDaysOfWeekTypeOptions, + acc.transactionProcessingStrategyOptions, acc.interestRateFrequencyTypeOptions, acc.amortizationTypeOptions, + acc.interestTypeOptions, acc.interestCalculationPeriodTypeOptions, acc.fundOptions, acc.chargeOptions, null, + acc.loanOfficerOptions, acc.loanPurposeOptions, acc.loanCollateralOptions, acc.calendarOptions, acc.syncDisbursementWithMeeting, acc.loanCounter, acc.loanProductCounter, acc.notes, acc.accountLinkingOptions, acc.linkedAccount, acc.disbursementDetails, acc.multiDisburseLoan, acc.canDefineInstallmentAmount, acc.fixedEmiAmount, acc.maxOutstandingLoanBalance, acc.emiAmountVariations, acc.memberVariations, acc.product, acc.inArrears, @@ -806,6 +811,7 @@ public final class LoanAccountData { final CurrencyData currencyData = null; final BigDecimal proposedPrincipal = null; final BigDecimal principal = null; + final BigDecimal netDisbursalAmount = null; final BigDecimal totalOverpaid = null; final BigDecimal inArrearsTolerance = null; final Integer termFrequency = null; @@ -903,11 +909,11 @@ public final class LoanAccountData { return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId, group, loanType, loanProductId, loanProductName, loanProductDescription, isLoanProductLinkedToFloatingRate, fundId, fundName, loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName, currencyData, proposedPrincipal, principal, principal, - totalOverpaid, inArrearsTolerance, termFrequency, termPeriodFrequencyType, numberOfRepayments, repaymentEvery, - repaymentFrequencyType, repaymentFrequencyNthDayType, repaymentFrequencyDayOfWeekType, transactionProcessingStrategyId, - transactionProcessingStrategyName, amortizationType, interestRatePerPeriod, interestRateFrequencyType, annualInterestRate, - interestType, isFloatingInterestRate, interestRateDifferential, interestCalculationPeriodType, - allowPartialPeriodInterestCalcualtion, expectedFirstRepaymentOnDate, graceOnPrincipalPayment, + netDisbursalAmount, totalOverpaid, inArrearsTolerance, termFrequency, termPeriodFrequencyType, numberOfRepayments, + repaymentEvery, repaymentFrequencyType, repaymentFrequencyNthDayType, repaymentFrequencyDayOfWeekType, + transactionProcessingStrategyId, transactionProcessingStrategyName, amortizationType, interestRatePerPeriod, + interestRateFrequencyType, annualInterestRate, interestType, isFloatingInterestRate, interestRateDifferential, + interestCalculationPeriodType, allowPartialPeriodInterestCalcualtion, expectedFirstRepaymentOnDate, graceOnPrincipalPayment, recurringMoratoriumOnPrincipalPeriods, graceOnInterestPayment, graceOnInterestCharged, interestChargedFromDate, timeline, summary, feeChargesDueAtDisbursementCharged, repaymentSchedule, transactions, charges, collateral, guarantors, calendarData, productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, repaymentFrequencyNthDayTypeOptions, @@ -928,9 +934,9 @@ public final class LoanAccountData { return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, acc.clientId, acc.clientAccountNo, acc.clientName, acc.clientOfficeId, groupAcc.group, acc.loanType, acc.loanProductId, acc.loanProductName, acc.loanProductDescription, acc.isLoanProductLinkedToFloatingRate, acc.fundId, acc.fundName, acc.loanPurposeId, acc.loanPurposeName, acc.loanOfficerId, - acc.loanOfficerName, acc.currency, acc.proposedPrincipal, acc.principal, acc.approvedPrincipal, acc.totalOverpaid, - acc.inArrearsTolerance, acc.termFrequency, acc.termPeriodFrequencyType, acc.numberOfRepayments, acc.repaymentEvery, - acc.repaymentFrequencyType, acc.repaymentFrequencyNthDayType, acc.repaymentFrequencyDayOfWeekType, + acc.loanOfficerName, acc.currency, acc.proposedPrincipal, acc.principal, acc.approvedPrincipal, acc.netDisbursalAmount, + acc.totalOverpaid, acc.inArrearsTolerance, acc.termFrequency, acc.termPeriodFrequencyType, acc.numberOfRepayments, + acc.repaymentEvery, acc.repaymentFrequencyType, acc.repaymentFrequencyNthDayType, acc.repaymentFrequencyDayOfWeekType, acc.transactionProcessingStrategyId, acc.transactionProcessingStrategyName, acc.amortizationType, acc.interestRatePerPeriod, acc.interestRateFrequencyType, acc.annualInterestRate, acc.interestType, acc.isFloatingInterestRate, acc.interestRateDifferential, acc.interestCalculationPeriodType, acc.allowPartialPeriodInterestCalcualtion, @@ -1032,6 +1038,7 @@ public final class LoanAccountData { final Collection emiAmountVariations = null; BigDecimal principal = null; BigDecimal proposedPrincipal = null; + BigDecimal netDisbursalAmount = null; BigDecimal interestRatePerPeriod = null; Integer numberOfRepayments = null; @@ -1054,6 +1061,15 @@ public final class LoanAccountData { principal = product.getPrincipal(); proposedPrincipal = principal; } + + // Add net get net disbursal amount from charges and principal + netDisbursalAmount = principal; + if (charges != null && !charges.isEmpty()) { + for (LoanChargeData charge : charges) { + netDisbursalAmount = netDisbursalAmount.subtract(charge.getAmount()); + } + } + if (interestRatePerPeriod == null) { interestRatePerPeriod = product.getInterestRatePerPeriod(); } @@ -1085,8 +1101,8 @@ public final class LoanAccountData { return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId, group, loanType, product.getId(), product.getName(), product.getDescription(), product.isLinkedToFloatingInterestRates(), product.getFundId(), product.getFundName(), loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName, - product.getCurrency(), proposedPrincipal, principal, principal, totalOverpaid, product.getInArrearsTolerance(), - termFrequency, termPeriodFrequencyType, numberOfRepayments, product.getRepaymentEvery(), + product.getCurrency(), proposedPrincipal, principal, principal, netDisbursalAmount, totalOverpaid, + product.getInArrearsTolerance(), termFrequency, termPeriodFrequencyType, numberOfRepayments, product.getRepaymentEvery(), product.getRepaymentFrequencyType(), null, null, product.getTransactionProcessingStrategyId(), transactionProcessingStrategyName, product.getAmortizationType(), interestRatePerPeriod, product.getInterestRateFrequencyType(), product.getAnnualInterestRate(), product.getInterestType(), @@ -1142,21 +1158,28 @@ public final class LoanAccountData { charges.add(charge.toLoanChargeData()); } + BigDecimal netDisbursalAmount = product.getPrincipal(); + if (charges != null && !charges.isEmpty()) { + for (LoanChargeData charge : charges) { + netDisbursalAmount = netDisbursalAmount.subtract(charge.getAmount()); + } + } + return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, acc.clientId, acc.clientAccountNo, acc.clientName, acc.clientOfficeId, acc.group, acc.loanType, product.getId(), product.getName(), product.getDescription(), product.isLinkedToFloatingInterestRates(), product.getFundId(), product.getFundName(), acc.loanPurposeId, acc.loanPurposeName, acc.loanOfficerId, acc.loanOfficerName, product.getCurrency(), product.getPrincipal(), - product.getPrincipal(), product.getPrincipal(), acc.totalOverpaid, product.getInArrearsTolerance(), termFrequency, - termPeriodFrequencyType, product.getNumberOfRepayments(), product.getRepaymentEvery(), product.getRepaymentFrequencyType(), - null, null, product.getTransactionProcessingStrategyId(), product.getTransactionProcessingStrategyName(), - product.getAmortizationType(), product.getInterestRatePerPeriod(), product.getInterestRateFrequencyType(), - product.getAnnualInterestRate(), product.getInterestType(), product.isFloatingInterestRateCalculationAllowed(), - product.getDefaultDifferentialLendingRate(), product.getInterestCalculationPeriodType(), - product.getAllowPartialPeriodInterestCalcualtion(), acc.expectedFirstRepaymentOnDate, product.getGraceOnPrincipalPayment(), - product.getRecurringMoratoriumOnPrincipalPeriods(), product.getGraceOnInterestPayment(), - product.getGraceOnInterestCharged(), acc.interestChargedFromDate, acc.timeline, acc.summary, - acc.feeChargesAtDisbursementCharged, repaymentSchedule, transactions, charges, collateral, guarantors, calendarData, - productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, null, null, repaymentStrategyOptions, + product.getPrincipal(), product.getPrincipal(), netDisbursalAmount, acc.totalOverpaid, product.getInArrearsTolerance(), + termFrequency, termPeriodFrequencyType, product.getNumberOfRepayments(), product.getRepaymentEvery(), + product.getRepaymentFrequencyType(), null, null, product.getTransactionProcessingStrategyId(), + product.getTransactionProcessingStrategyName(), product.getAmortizationType(), product.getInterestRatePerPeriod(), + product.getInterestRateFrequencyType(), product.getAnnualInterestRate(), product.getInterestType(), + product.isFloatingInterestRateCalculationAllowed(), product.getDefaultDifferentialLendingRate(), + product.getInterestCalculationPeriodType(), product.getAllowPartialPeriodInterestCalcualtion(), + acc.expectedFirstRepaymentOnDate, product.getGraceOnPrincipalPayment(), product.getRecurringMoratoriumOnPrincipalPeriods(), + product.getGraceOnInterestPayment(), product.getGraceOnInterestCharged(), acc.interestChargedFromDate, acc.timeline, + acc.summary, acc.feeChargesAtDisbursementCharged, repaymentSchedule, transactions, charges, collateral, guarantors, + calendarData, productOptions, termFrequencyTypeOptions, repaymentFrequencyTypeOptions, null, null, repaymentStrategyOptions, interestRateFrequencyTypeOptions, amortizationTypeOptions, interestTypeOptions, interestCalculationPeriodTypeOptions, fundOptions, chargeOptions, chargeTemplate, loanOfficerOptions, loanPurposeOptions, loanCollateralOptions, calendarOptions, acc.syncDisbursementWithMeeting, acc.loanCounter, acc.loanProductCounter, notes, acc.accountLinkingOptions, @@ -1180,17 +1203,17 @@ public final class LoanAccountData { final String loanProductDescription, final boolean isLoanProductLinkedToFloatingRate, final Long fundId, final String fundName, final Long loanPurposeId, final String loanPurposeName, final Long loanOfficerId, final String loanOfficerName, final CurrencyData currencyData, final BigDecimal proposedPrincipal, final BigDecimal principal, - final BigDecimal approvedPrincipal, final BigDecimal totalOverpaid, final BigDecimal inArrearsTolerance, - final Integer termFrequency, final EnumOptionData termPeriodFrequencyType, final Integer numberOfRepayments, - final Integer repaymentEvery, final EnumOptionData repaymentFrequencyType, EnumOptionData repaymentFrequencyNthDayType, - EnumOptionData repaymentFrequencyDayOfWeekType, final Long transactionStrategyId, final String transactionStrategyName, - final EnumOptionData amortizationType, final BigDecimal interestRatePerPeriod, final EnumOptionData interestRateFrequencyType, - final BigDecimal annualInterestRate, final EnumOptionData interestType, final boolean isFloatingInterestRate, - final BigDecimal interestRateDifferential, final EnumOptionData interestCalculationPeriodType, - Boolean allowPartialPeriodInterestCalcualtion, final LocalDate expectedFirstRepaymentOnDate, - final Integer graceOnPrincipalPayment, final Integer recurringMoratoriumOnPrincipalPeriods, - final Integer graceOnInterestPayment, final Integer graceOnInterestCharged, final LocalDate interestChargedFromDate, - final LoanApplicationTimelineData timeline, final LoanSummaryData loanSummary, + final BigDecimal approvedPrincipal, final BigDecimal netDisbursalAmount, final BigDecimal totalOverpaid, + final BigDecimal inArrearsTolerance, final Integer termFrequency, final EnumOptionData termPeriodFrequencyType, + final Integer numberOfRepayments, final Integer repaymentEvery, final EnumOptionData repaymentFrequencyType, + EnumOptionData repaymentFrequencyNthDayType, EnumOptionData repaymentFrequencyDayOfWeekType, final Long transactionStrategyId, + final String transactionStrategyName, final EnumOptionData amortizationType, final BigDecimal interestRatePerPeriod, + final EnumOptionData interestRateFrequencyType, final BigDecimal annualInterestRate, final EnumOptionData interestType, + final boolean isFloatingInterestRate, final BigDecimal interestRateDifferential, + final EnumOptionData interestCalculationPeriodType, Boolean allowPartialPeriodInterestCalcualtion, + final LocalDate expectedFirstRepaymentOnDate, final Integer graceOnPrincipalPayment, + final Integer recurringMoratoriumOnPrincipalPeriods, final Integer graceOnInterestPayment, final Integer graceOnInterestCharged, + final LocalDate interestChargedFromDate, final LoanApplicationTimelineData timeline, final LoanSummaryData loanSummary, final BigDecimal feeChargesDueAtDisbursementCharged, final Boolean syncDisbursementWithMeeting, final Integer loanCounter, final Integer loanProductCounter, final Boolean multiDisburseLoan, Boolean canDefineInstallmentAmount, final BigDecimal fixedEmiAmont, final BigDecimal outstandingLoanBalance, final Boolean inArrears, @@ -1242,8 +1265,8 @@ public final class LoanAccountData { return new LoanAccountData(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId, group, loanType, loanProductId, loanProductName, loanProductDescription, isLoanProductLinkedToFloatingRate, fundId, fundName, loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName, currencyData, proposedPrincipal, principal, - approvedPrincipal, totalOverpaid, inArrearsTolerance, termFrequency, termPeriodFrequencyType, numberOfRepayments, - repaymentEvery, repaymentFrequencyType, repaymentFrequencyNthDayType, repaymentFrequencyDayOfWeekType, + approvedPrincipal, netDisbursalAmount, totalOverpaid, inArrearsTolerance, termFrequency, termPeriodFrequencyType, + numberOfRepayments, repaymentEvery, repaymentFrequencyType, repaymentFrequencyNthDayType, repaymentFrequencyDayOfWeekType, transactionStrategyId, transactionStrategyName, amortizationType, interestRatePerPeriod, interestRateFrequencyType, annualInterestRate, interestType, isFloatingInterestRate, interestRateDifferential, interestCalculationPeriodType, allowPartialPeriodInterestCalcualtion, expectedFirstRepaymentOnDate, graceOnPrincipalPayment, @@ -1290,9 +1313,9 @@ public final class LoanAccountData { return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, acc.clientId, acc.clientAccountNo, acc.clientName, acc.clientOfficeId, acc.group, acc.loanType, acc.loanProductId, acc.loanProductName, acc.loanProductDescription, acc.isLoanProductLinkedToFloatingRate, acc.fundId, acc.fundName, acc.loanPurposeId, acc.loanPurposeName, acc.loanOfficerId, - acc.loanOfficerName, acc.currency, acc.proposedPrincipal, acc.principal, acc.approvedPrincipal, acc.totalOverpaid, - acc.inArrearsTolerance, acc.termFrequency, acc.termPeriodFrequencyType, acc.numberOfRepayments, acc.repaymentEvery, - acc.repaymentFrequencyType, acc.repaymentFrequencyNthDayType, acc.repaymentFrequencyDayOfWeekType, + acc.loanOfficerName, acc.currency, acc.proposedPrincipal, acc.principal, acc.approvedPrincipal, acc.netDisbursalAmount, + acc.totalOverpaid, acc.inArrearsTolerance, acc.termFrequency, acc.termPeriodFrequencyType, acc.numberOfRepayments, + acc.repaymentEvery, acc.repaymentFrequencyType, acc.repaymentFrequencyNthDayType, acc.repaymentFrequencyDayOfWeekType, acc.transactionProcessingStrategyId, acc.transactionProcessingStrategyName, acc.amortizationType, acc.interestRatePerPeriod, acc.interestRateFrequencyType, acc.annualInterestRate, acc.interestType, acc.isFloatingInterestRate, acc.interestRateDifferential, acc.interestCalculationPeriodType, acc.allowPartialPeriodInterestCalcualtion, @@ -1331,9 +1354,9 @@ public final class LoanAccountData { return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, acc.clientId, acc.clientAccountNo, acc.clientName, acc.clientOfficeId, group, acc.loanType, acc.loanProductId, acc.loanProductName, acc.loanProductDescription, acc.isLoanProductLinkedToFloatingRate, acc.fundId, acc.fundName, acc.loanPurposeId, acc.loanPurposeName, acc.loanOfficerId, - acc.loanOfficerName, acc.currency, acc.proposedPrincipal, acc.principal, acc.approvedPrincipal, acc.totalOverpaid, - acc.inArrearsTolerance, acc.termFrequency, acc.termPeriodFrequencyType, acc.numberOfRepayments, acc.repaymentEvery, - acc.repaymentFrequencyType, acc.repaymentFrequencyNthDayType, acc.repaymentFrequencyDayOfWeekType, + acc.loanOfficerName, acc.currency, acc.proposedPrincipal, acc.principal, acc.approvedPrincipal, acc.netDisbursalAmount, + acc.totalOverpaid, acc.inArrearsTolerance, acc.termFrequency, acc.termPeriodFrequencyType, acc.numberOfRepayments, + acc.repaymentEvery, acc.repaymentFrequencyType, acc.repaymentFrequencyNthDayType, acc.repaymentFrequencyDayOfWeekType, acc.transactionProcessingStrategyId, acc.transactionProcessingStrategyName, acc.amortizationType, acc.interestRatePerPeriod, acc.interestRateFrequencyType, acc.annualInterestRate, acc.interestType, acc.isFloatingInterestRate, acc.interestRateDifferential, acc.interestCalculationPeriodType, acc.allowPartialPeriodInterestCalcualtion, @@ -1396,9 +1419,9 @@ public final class LoanAccountData { return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, acc.clientId, acc.clientAccountNo, acc.clientName, acc.clientOfficeId, acc.group, acc.loanType, acc.loanProductId, acc.loanProductName, acc.loanProductDescription, acc.isLoanProductLinkedToFloatingRate, acc.fundId, acc.fundName, acc.loanPurposeId, acc.loanPurposeName, acc.loanOfficerId, - acc.loanOfficerName, acc.currency, acc.proposedPrincipal, acc.principal, acc.approvedPrincipal, acc.totalOverpaid, - acc.inArrearsTolerance, acc.termFrequency, acc.termPeriodFrequencyType, acc.numberOfRepayments, acc.repaymentEvery, - acc.repaymentFrequencyType, acc.repaymentFrequencyNthDayType, acc.repaymentFrequencyDayOfWeekType, + acc.loanOfficerName, acc.currency, acc.proposedPrincipal, acc.principal, acc.approvedPrincipal, acc.netDisbursalAmount, + acc.totalOverpaid, acc.inArrearsTolerance, acc.termFrequency, acc.termPeriodFrequencyType, acc.numberOfRepayments, + acc.repaymentEvery, acc.repaymentFrequencyType, acc.repaymentFrequencyNthDayType, acc.repaymentFrequencyDayOfWeekType, acc.transactionProcessingStrategyId, acc.transactionProcessingStrategyName, acc.amortizationType, acc.interestRatePerPeriod, acc.interestRateFrequencyType, acc.annualInterestRate, acc.interestType, acc.isFloatingInterestRate, acc.interestRateDifferential, acc.interestCalculationPeriodType, acc.allowPartialPeriodInterestCalcualtion, @@ -1430,9 +1453,9 @@ public final class LoanAccountData { return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, acc.clientId, acc.clientAccountNo, acc.clientName, acc.clientOfficeId, acc.group, acc.loanType, acc.loanProductId, acc.loanProductName, acc.loanProductDescription, acc.isLoanProductLinkedToFloatingRate, acc.fundId, acc.fundName, acc.loanPurposeId, acc.loanPurposeName, acc.loanOfficerId, - acc.loanOfficerName, acc.currency, acc.proposedPrincipal, acc.principal, acc.approvedPrincipal, acc.totalOverpaid, - acc.inArrearsTolerance, acc.termFrequency, acc.termPeriodFrequencyType, acc.numberOfRepayments, acc.repaymentEvery, - acc.repaymentFrequencyType, acc.repaymentFrequencyNthDayType, acc.repaymentFrequencyDayOfWeekType, + acc.loanOfficerName, acc.currency, acc.proposedPrincipal, acc.principal, acc.approvedPrincipal, acc.netDisbursalAmount, + acc.totalOverpaid, acc.inArrearsTolerance, acc.termFrequency, acc.termPeriodFrequencyType, acc.numberOfRepayments, + acc.repaymentEvery, acc.repaymentFrequencyType, acc.repaymentFrequencyNthDayType, acc.repaymentFrequencyDayOfWeekType, acc.transactionProcessingStrategyId, acc.transactionProcessingStrategyName, acc.amortizationType, acc.interestRatePerPeriod, acc.interestRateFrequencyType, acc.annualInterestRate, acc.interestType, acc.isFloatingInterestRate, acc.interestRateDifferential, acc.interestCalculationPeriodType, acc.allowPartialPeriodInterestCalcualtion, @@ -1458,9 +1481,9 @@ public final class LoanAccountData { return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, acc.clientId, acc.clientAccountNo, acc.clientName, acc.clientOfficeId, acc.group, acc.loanType, acc.loanProductId, acc.loanProductName, acc.loanProductDescription, acc.isLoanProductLinkedToFloatingRate, acc.fundId, acc.fundName, acc.loanPurposeId, acc.loanPurposeName, acc.loanOfficerId, - acc.loanOfficerName, acc.currency, acc.proposedPrincipal, acc.principal, acc.approvedPrincipal, acc.totalOverpaid, - acc.inArrearsTolerance, acc.termFrequency, acc.termPeriodFrequencyType, acc.numberOfRepayments, acc.repaymentEvery, - acc.repaymentFrequencyType, calendarData.getRepeatsOnNthDayOfMonth(), calendarData.getRepeatsOnDay(), + acc.loanOfficerName, acc.currency, acc.proposedPrincipal, acc.principal, acc.approvedPrincipal, acc.netDisbursalAmount, + acc.totalOverpaid, acc.inArrearsTolerance, acc.termFrequency, acc.termPeriodFrequencyType, acc.numberOfRepayments, + acc.repaymentEvery, acc.repaymentFrequencyType, calendarData.getRepeatsOnNthDayOfMonth(), calendarData.getRepeatsOnDay(), acc.transactionProcessingStrategyId, acc.transactionProcessingStrategyName, acc.amortizationType, acc.interestRatePerPeriod, acc.interestRateFrequencyType, acc.annualInterestRate, acc.interestType, acc.isFloatingInterestRate, acc.interestRateDifferential, acc.interestCalculationPeriodType, acc.allowPartialPeriodInterestCalcualtion, @@ -1487,9 +1510,9 @@ public final class LoanAccountData { return new LoanAccountData(acc.id, acc.accountNo, acc.status, acc.externalId, acc.clientId, acc.clientAccountNo, acc.clientName, acc.clientOfficeId, acc.group, acc.loanType, acc.loanProductId, acc.loanProductName, acc.loanProductDescription, acc.isLoanProductLinkedToFloatingRate, acc.fundId, acc.fundName, acc.loanPurposeId, acc.loanPurposeName, acc.loanOfficerId, - acc.loanOfficerName, acc.currency, acc.proposedPrincipal, acc.principal, acc.approvedPrincipal, acc.totalOverpaid, - acc.inArrearsTolerance, acc.termFrequency, acc.termPeriodFrequencyType, acc.numberOfRepayments, acc.repaymentEvery, - acc.repaymentFrequencyType, acc.repaymentFrequencyNthDayType, acc.repaymentFrequencyDayOfWeekType, + acc.loanOfficerName, acc.currency, acc.proposedPrincipal, acc.principal, acc.approvedPrincipal, acc.netDisbursalAmount, + acc.totalOverpaid, acc.inArrearsTolerance, acc.termFrequency, acc.termPeriodFrequencyType, acc.numberOfRepayments, + acc.repaymentEvery, acc.repaymentFrequencyType, acc.repaymentFrequencyNthDayType, acc.repaymentFrequencyDayOfWeekType, acc.transactionProcessingStrategyId, acc.transactionProcessingStrategyName, acc.amortizationType, acc.interestRatePerPeriod, acc.interestRateFrequencyType, acc.annualInterestRate, acc.interestType, acc.isFloatingInterestRate, acc.interestRateDifferential, acc.interestCalculationPeriodType, acc.allowPartialPeriodInterestCalcualtion, @@ -1522,7 +1545,7 @@ public final class LoanAccountData { final String loanPurposeName, // final Long loanOfficerId, final String loanOfficerName, // final CurrencyData currency, BigDecimal proposedPrincipal, final BigDecimal principal, final BigDecimal approvedPrincipal, - final BigDecimal totalOverpaid, // + final BigDecimal netDisbursalAmount, final BigDecimal totalOverpaid, // final BigDecimal inArrearsTolerance, final Integer termFrequency, // final EnumOptionData termPeriodFrequencyType, final Integer numberOfRepayments, final Integer repaymentEvery, final EnumOptionData repaymentFrequencyType, // @@ -1588,6 +1611,7 @@ public final class LoanAccountData { this.proposedPrincipal = proposedPrincipal; this.principal = principal; this.approvedPrincipal = approvedPrincipal; + this.netDisbursalAmount = netDisbursalAmount; this.totalOverpaid = totalOverpaid; this.inArrearsTolerance = inArrearsTolerance; this.termFrequency = termFrequency; @@ -1894,6 +1918,10 @@ public final class LoanAccountData { return this.interestRateDifferential; } + public BigDecimal getNetDisbursalAmount() { + return netDisbursalAmount; + } + public void setDatatables(final List datatables) { this.datatables = datatables; } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanApprovalData.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanApprovalData.java index a20af3b63..81882260c 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanApprovalData.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanApprovalData.java @@ -28,6 +28,7 @@ public class LoanApprovalData { private final LocalDate approvalDate; private final BigDecimal approvalAmount; + private final BigDecimal netDisbursalAmount; // import fields private LocalDate approvedOnDate; @@ -48,11 +49,13 @@ public class LoanApprovalData { this.note = ""; this.approvalAmount = null; this.approvalDate = null; + this.netDisbursalAmount = null; } - public LoanApprovalData(final BigDecimal approvalAmount, final LocalDate approvalDate) { + public LoanApprovalData(final BigDecimal approvalAmount, final LocalDate approvalDate, final BigDecimal netDisbursalAmount) { this.approvalDate = approvalDate; this.approvalAmount = approvalAmount; + this.netDisbursalAmount = netDisbursalAmount; } public LocalDate getApprovalDate() { @@ -63,4 +66,8 @@ public class LoanApprovalData { return this.approvalAmount; } + public BigDecimal getNetDisbursalAmount() { + return this.netDisbursalAmount; + } + } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanTransactionData.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanTransactionData.java index 381e5c8c0..ce805898d 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanTransactionData.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanTransactionData.java @@ -46,6 +46,7 @@ public class LoanTransactionData { private final PaymentDetailData paymentDetailData; private final BigDecimal amount; + private final BigDecimal netDisbursalAmount; private final BigDecimal principalPortion; private final BigDecimal interestPortion; private final BigDecimal feeChargesPortion; @@ -99,6 +100,7 @@ public class LoanTransactionData { this.dateFormat = dateFormat; this.locale = locale; this.amount = null; + this.netDisbursalAmount = null; this.date = null; this.type = null; this.id = null; @@ -154,6 +156,7 @@ public class LoanTransactionData { this.currency = null; this.paymentDetailData = null; this.amount = null; + this.netDisbursalAmount = null; this.principalPortion = null; this.interestPortion = null; this.feeChargesPortion = null; @@ -191,54 +194,55 @@ public class LoanTransactionData { final Collection paymentTypeOptions) { return new LoanTransactionData(loanTransactionData.id, loanTransactionData.officeId, loanTransactionData.officeName, loanTransactionData.type, loanTransactionData.paymentDetailData, loanTransactionData.currency, loanTransactionData.date, - loanTransactionData.amount, loanTransactionData.principalPortion, loanTransactionData.interestPortion, - loanTransactionData.feeChargesPortion, loanTransactionData.penaltyChargesPortion, loanTransactionData.overpaymentPortion, - loanTransactionData.unrecognizedIncomePortion, paymentTypeOptions, loanTransactionData.externalId, - loanTransactionData.transfer, loanTransactionData.fixedEmiAmount, loanTransactionData.outstandingLoanBalance, - loanTransactionData.manuallyReversed); + loanTransactionData.amount, loanTransactionData.netDisbursalAmount, loanTransactionData.principalPortion, + loanTransactionData.interestPortion, loanTransactionData.feeChargesPortion, loanTransactionData.penaltyChargesPortion, + loanTransactionData.overpaymentPortion, loanTransactionData.unrecognizedIncomePortion, paymentTypeOptions, + loanTransactionData.externalId, loanTransactionData.transfer, loanTransactionData.fixedEmiAmount, + loanTransactionData.outstandingLoanBalance, loanTransactionData.manuallyReversed); } public LoanTransactionData(final Long id, final Long officeId, final String officeName, final LoanTransactionEnumData transactionType, final PaymentDetailData paymentDetailData, final CurrencyData currency, final LocalDate date, final BigDecimal amount, - final BigDecimal principalPortion, final BigDecimal interestPortion, final BigDecimal feeChargesPortion, - final BigDecimal penaltyChargesPortion, final BigDecimal overpaymentPortion, final String externalId, - final AccountTransferData transfer, BigDecimal fixedEmiAmount, BigDecimal outstandingLoanBalance, - final BigDecimal unrecognizedIncomePortion, final boolean manuallyReversed) { - this(id, officeId, officeName, transactionType, paymentDetailData, currency, date, amount, principalPortion, interestPortion, - feeChargesPortion, penaltyChargesPortion, overpaymentPortion, unrecognizedIncomePortion, null, externalId, transfer, - fixedEmiAmount, outstandingLoanBalance, manuallyReversed); - } - - public LoanTransactionData(final Long id, final Long officeId, final String officeName, final LoanTransactionEnumData transactionType, - final PaymentDetailData paymentDetailData, final CurrencyData currency, final LocalDate date, final BigDecimal amount, - final BigDecimal principalPortion, final BigDecimal interestPortion, final BigDecimal feeChargesPortion, - final BigDecimal penaltyChargesPortion, final BigDecimal overpaymentPortion, BigDecimal unrecognizedIncomePortion, - final Collection paymentTypeOptions, final String externalId, final AccountTransferData transfer, - final BigDecimal fixedEmiAmount, BigDecimal outstandingLoanBalance, boolean manuallyReversed) { - this(id, officeId, officeName, transactionType, paymentDetailData, currency, date, amount, principalPortion, interestPortion, - feeChargesPortion, penaltyChargesPortion, overpaymentPortion, unrecognizedIncomePortion, paymentTypeOptions, externalId, - transfer, fixedEmiAmount, outstandingLoanBalance, null, manuallyReversed); - } - - public LoanTransactionData(final Long id, final Long officeId, final String officeName, final LoanTransactionEnumData transactionType, - final PaymentDetailData paymentDetailData, final CurrencyData currency, final LocalDate date, final BigDecimal amount, - final BigDecimal principalPortion, final BigDecimal interestPortion, final BigDecimal feeChargesPortion, - final BigDecimal penaltyChargesPortion, final BigDecimal overpaymentPortion, final BigDecimal unrecognizedIncomePortion, + final BigDecimal netDisbursalAmount, final BigDecimal principalPortion, final BigDecimal interestPortion, + final BigDecimal feeChargesPortion, final BigDecimal penaltyChargesPortion, final BigDecimal overpaymentPortion, final String externalId, final AccountTransferData transfer, BigDecimal fixedEmiAmount, BigDecimal outstandingLoanBalance, - LocalDate submittedOnDate, final boolean manuallyReversed) { - this(id, officeId, officeName, transactionType, paymentDetailData, currency, date, amount, principalPortion, interestPortion, - feeChargesPortion, penaltyChargesPortion, overpaymentPortion, unrecognizedIncomePortion, null, externalId, transfer, - fixedEmiAmount, outstandingLoanBalance, submittedOnDate, manuallyReversed); + final BigDecimal unrecognizedIncomePortion, final boolean manuallyReversed) { + this(id, officeId, officeName, transactionType, paymentDetailData, currency, date, amount, netDisbursalAmount, principalPortion, + interestPortion, feeChargesPortion, penaltyChargesPortion, overpaymentPortion, unrecognizedIncomePortion, null, externalId, + transfer, fixedEmiAmount, outstandingLoanBalance, manuallyReversed); } public LoanTransactionData(final Long id, final Long officeId, final String officeName, final LoanTransactionEnumData transactionType, final PaymentDetailData paymentDetailData, final CurrencyData currency, final LocalDate date, final BigDecimal amount, - final BigDecimal principalPortion, final BigDecimal interestPortion, final BigDecimal feeChargesPortion, - final BigDecimal penaltyChargesPortion, final BigDecimal overpaymentPortion, final BigDecimal unrecognizedIncomePortion, - final Collection paymentTypeOptions, final String externalId, final AccountTransferData transfer, - final BigDecimal fixedEmiAmount, BigDecimal outstandingLoanBalance, final LocalDate submittedOnDate, - final boolean manuallyReversed) { + final BigDecimal netDisbursalAmount, final BigDecimal principalPortion, final BigDecimal interestPortion, + final BigDecimal feeChargesPortion, final BigDecimal penaltyChargesPortion, final BigDecimal overpaymentPortion, + BigDecimal unrecognizedIncomePortion, final Collection paymentTypeOptions, final String externalId, + final AccountTransferData transfer, final BigDecimal fixedEmiAmount, BigDecimal outstandingLoanBalance, + boolean manuallyReversed) { + this(id, officeId, officeName, transactionType, paymentDetailData, currency, date, amount, netDisbursalAmount, principalPortion, + interestPortion, feeChargesPortion, penaltyChargesPortion, overpaymentPortion, unrecognizedIncomePortion, + paymentTypeOptions, externalId, transfer, fixedEmiAmount, outstandingLoanBalance, null, manuallyReversed); + } + + public LoanTransactionData(final Long id, final Long officeId, final String officeName, final LoanTransactionEnumData transactionType, + final PaymentDetailData paymentDetailData, final CurrencyData currency, final LocalDate date, final BigDecimal amount, + final BigDecimal netDisbursalAmount, final BigDecimal principalPortion, final BigDecimal interestPortion, + final BigDecimal feeChargesPortion, final BigDecimal penaltyChargesPortion, final BigDecimal overpaymentPortion, + final BigDecimal unrecognizedIncomePortion, final String externalId, final AccountTransferData transfer, + BigDecimal fixedEmiAmount, BigDecimal outstandingLoanBalance, LocalDate submittedOnDate, final boolean manuallyReversed) { + this(id, officeId, officeName, transactionType, paymentDetailData, currency, date, amount, netDisbursalAmount, principalPortion, + interestPortion, feeChargesPortion, penaltyChargesPortion, overpaymentPortion, unrecognizedIncomePortion, null, externalId, + transfer, fixedEmiAmount, outstandingLoanBalance, submittedOnDate, manuallyReversed); + } + + public LoanTransactionData(final Long id, final Long officeId, final String officeName, final LoanTransactionEnumData transactionType, + final PaymentDetailData paymentDetailData, final CurrencyData currency, final LocalDate date, final BigDecimal amount, + final BigDecimal netDisbursalAmount, final BigDecimal principalPortion, final BigDecimal interestPortion, + final BigDecimal feeChargesPortion, final BigDecimal penaltyChargesPortion, final BigDecimal overpaymentPortion, + final BigDecimal unrecognizedIncomePortion, final Collection paymentTypeOptions, final String externalId, + final AccountTransferData transfer, final BigDecimal fixedEmiAmount, BigDecimal outstandingLoanBalance, + final LocalDate submittedOnDate, final boolean manuallyReversed) { this.id = id; this.officeId = officeId; this.officeName = officeName; @@ -247,6 +251,7 @@ public class LoanTransactionData { this.currency = currency; this.date = date; this.amount = amount; + this.netDisbursalAmount = netDisbursalAmount; this.principalPortion = principalPortion; this.interestPortion = interestPortion; this.feeChargesPortion = feeChargesPortion; @@ -264,17 +269,17 @@ public class LoanTransactionData { } public LoanTransactionData(Long id, LoanTransactionEnumData transactionType, LocalDate date, BigDecimal totalAmount, - BigDecimal principalPortion, BigDecimal interestPortion, BigDecimal feeChargesPortion, BigDecimal penaltyChargesPortion, - BigDecimal overpaymentPortion, BigDecimal unrecognizedIncomePortion, BigDecimal outstandingLoanBalance, - final boolean manuallyReversed) { - this(id, null, null, transactionType, null, null, date, totalAmount, principalPortion, interestPortion, feeChargesPortion, - penaltyChargesPortion, overpaymentPortion, unrecognizedIncomePortion, null, null, null, null, outstandingLoanBalance, null, - manuallyReversed); + BigDecimal netDisbursalAmount, BigDecimal principalPortion, BigDecimal interestPortion, BigDecimal feeChargesPortion, + BigDecimal penaltyChargesPortion, BigDecimal overpaymentPortion, BigDecimal unrecognizedIncomePortion, + BigDecimal outstandingLoanBalance, final boolean manuallyReversed) { + this(id, null, null, transactionType, null, null, date, totalAmount, netDisbursalAmount, principalPortion, interestPortion, + feeChargesPortion, penaltyChargesPortion, overpaymentPortion, unrecognizedIncomePortion, null, null, null, null, + outstandingLoanBalance, null, manuallyReversed); } public static LoanTransactionData loanTransactionDataForDisbursalTemplate(final LoanTransactionEnumData transactionType, final LocalDate expectedDisbursedOnLocalDateForTemplate, final BigDecimal disburseAmountForTemplate, - final Collection paymentOptions, final BigDecimal retriveLastEmiAmount, + final BigDecimal netDisbursalAmount, final Collection paymentOptions, final BigDecimal retriveLastEmiAmount, final LocalDate possibleNextRepaymentDate) { final Long id = null; final Long officeId = null; @@ -293,18 +298,18 @@ public class LoanTransactionData { final LocalDate submittedOnDate = null; final boolean manuallyReversed = false; return new LoanTransactionData(id, officeId, officeName, transactionType, paymentDetailData, currency, - expectedDisbursedOnLocalDateForTemplate, disburseAmountForTemplate, principalPortion, interestPortion, feeChargesPortion, - penaltyChargesPortion, overpaymentPortion, unrecognizedIncomePortion, paymentOptions, transfer, externalId, - retriveLastEmiAmount, outstandingLoanBalance, submittedOnDate, manuallyReversed, possibleNextRepaymentDate); + expectedDisbursedOnLocalDateForTemplate, disburseAmountForTemplate, netDisbursalAmount, principalPortion, interestPortion, + feeChargesPortion, penaltyChargesPortion, overpaymentPortion, unrecognizedIncomePortion, paymentOptions, transfer, + externalId, retriveLastEmiAmount, outstandingLoanBalance, submittedOnDate, manuallyReversed, possibleNextRepaymentDate); } private LoanTransactionData(Long id, final Long officeId, final String officeName, LoanTransactionEnumData transactionType, final PaymentDetailData paymentDetailData, final CurrencyData currency, final LocalDate date, BigDecimal amount, - final BigDecimal principalPortion, final BigDecimal interestPortion, final BigDecimal feeChargesPortion, - final BigDecimal penaltyChargesPortion, final BigDecimal overpaymentPortion, BigDecimal unrecognizedIncomePortion, - Collection paymentOptions, final AccountTransferData transfer, final String externalId, - final BigDecimal fixedEmiAmount, BigDecimal outstandingLoanBalance, final LocalDate submittedOnDate, + BigDecimal netDisbursalAmount, final BigDecimal principalPortion, final BigDecimal interestPortion, + final BigDecimal feeChargesPortion, final BigDecimal penaltyChargesPortion, final BigDecimal overpaymentPortion, + BigDecimal unrecognizedIncomePortion, Collection paymentOptions, final AccountTransferData transfer, + final String externalId, final BigDecimal fixedEmiAmount, BigDecimal outstandingLoanBalance, final LocalDate submittedOnDate, final boolean manuallyReversed, final LocalDate possibleNextRepaymentDate) { this.id = id; this.officeId = officeId; @@ -314,6 +319,7 @@ public class LoanTransactionData { this.currency = currency; this.date = date; this.amount = amount; + this.netDisbursalAmount = netDisbursalAmount; this.principalPortion = principalPortion; this.interestPortion = interestPortion; this.feeChargesPortion = feeChargesPortion; @@ -342,6 +348,10 @@ public class LoanTransactionData { return this.amount; } + public BigDecimal getNetDisbursalAmount() { + return netDisbursalAmount; + } + public BigDecimal getUnrecognizedIncomePortion() { return this.unrecognizedIncomePortion; } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/RepaymentScheduleRelatedLoanData.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/RepaymentScheduleRelatedLoanData.java index 53ccc536b..f25d96b75 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/RepaymentScheduleRelatedLoanData.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/RepaymentScheduleRelatedLoanData.java @@ -31,6 +31,7 @@ public class RepaymentScheduleRelatedLoanData { private final LocalDate actualDisbursementDate; private final CurrencyData currency; private final BigDecimal principal; + private final BigDecimal netDisbursalAmount; private final BigDecimal inArrearsTolerance; private final BigDecimal totalFeeChargesAtDisbursement; @@ -43,6 +44,7 @@ public class RepaymentScheduleRelatedLoanData { this.principal = principal; this.inArrearsTolerance = inArrearsTolerance; this.totalFeeChargesAtDisbursement = totalFeeChargesAtDisbursement; + this.netDisbursalAmount = this.principal.subtract(this.totalFeeChargesAtDisbursement); } public LocalDate disbursementDate() { @@ -75,7 +77,7 @@ public class RepaymentScheduleRelatedLoanData { public DisbursementData disbursementData() { BigDecimal waivedChargeAmount = null; - return new DisbursementData(null, this.expectedDisbursementDate, this.actualDisbursementDate, this.principal, null, null, - waivedChargeAmount); + return new DisbursementData(null, this.expectedDisbursementDate, this.actualDisbursementDate, this.principal, + this.netDisbursalAmount, null, null, waivedChargeAmount); } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java index debfd2866..3d3643c49 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java @@ -349,6 +349,9 @@ public class Loan extends AbstractPersistableCustom { @Column(name = "approved_principal", scale = 6, precision = 19, nullable = false) private BigDecimal approvedPrincipal; + @Column(name = "net_disbursal_amount", scale = 6, precision = 19, nullable = false) + private BigDecimal netDisbursalAmount; + @Column(name = "fixed_emi_amount", scale = 6, precision = 19, nullable = true) private BigDecimal fixedEmiAmount; @@ -530,6 +533,9 @@ public class Loan extends AbstractPersistableCustom { // rates added here this.rates = rates; + // Add net get net disbursal amount from charges and principal + this.netDisbursalAmount = this.approvedPrincipal.subtract(deriveSumTotalOfChargesDueAtDisbursement()); + } public Integer getNumberOfRepayments() { @@ -1871,7 +1877,7 @@ public class Loan extends AbstractPersistableCustom { if (loanDisbursementDetail.actualDisbursementDate() == null) { Date actualDisbursementDate = null; LoanDisbursementDetails disbursementDetails = new LoanDisbursementDetails(expectedDisbursementDate, actualDisbursementDate, - principal); + principal, this.netDisbursalAmount); disbursementDetails.updateLoan(this); if (!loanDisbursementDetail.equals(disbursementDetails)) { loanDisbursementDetail.copy(disbursementDetails); @@ -1882,7 +1888,7 @@ public class Loan extends AbstractPersistableCustom { } else { Date actualDisbursementDate = null; LoanDisbursementDetails disbursementDetails = new LoanDisbursementDetails(expectedDisbursementDate, actualDisbursementDate, - principal); + principal, this.netDisbursalAmount); disbursementDetails.updateLoan(this); this.disbursementDetails.add(disbursementDetails); for (LoanTrancheCharge trancheCharge : trancheCharges) { @@ -2224,6 +2230,7 @@ public class Loan extends AbstractPersistableCustom { actualChanges.put(LoanApiConstants.approvedLoanAmountParameterName, approvedLoanAmount); actualChanges.put(LoanApiConstants.disbursementPrincipalParameterName, approvedLoanAmount); + actualChanges.put(LoanApiConstants.disbursementNetDisbursalAmountParameterName, netDisbursalAmount); } else if (approvedLoanAmount.compareTo(this.proposedPrincipal) > 0) { final String errorMessage = "Loan approved amount can't be greater than loan amount demanded."; throw new InvalidLoanStateTransitionException("approval", "amount.can't.be.greater.than.loan.amount.demanded", @@ -2289,6 +2296,7 @@ public class Loan extends AbstractPersistableCustom { this.loanOfficer, approvedOn); this.loanOfficerHistory.add(loanOfficerAssignmentHistory); } + this.adjustNetDisbursalAmount(this.approvedPrincipal); } return actualChanges; @@ -2885,6 +2893,8 @@ public class Loan extends AbstractPersistableCustom { this.loanTopupDetails.setTopupAmount(null); } + this.adjustNetDisbursalAmount(this.approvedPrincipal); + actualChanges.put("actualDisbursementDate", ""); updateLoanSummaryDerivedFields(); @@ -5170,6 +5180,19 @@ public class Loan extends AbstractPersistableCustom { return this.approvedPrincipal; } + public BigDecimal getNetDisbursalAmount() { + return netDisbursalAmount; + } + + public BigDecimal deductFromNetDisbursalAmount(final BigDecimal subtrahend) { + this.netDisbursalAmount = this.netDisbursalAmount.subtract(subtrahend); + return netDisbursalAmount; + } + + public void setNetDisbursalAmount(BigDecimal netDisbursalAmount) { + this.netDisbursalAmount = netDisbursalAmount; + } + public BigDecimal getTotalOverpaid() { return this.totalOverpaid; } @@ -5750,7 +5773,7 @@ public class Loan extends AbstractPersistableCustom { } BigDecimal waivedChargeAmount = null; disbursementData.add(new DisbursementData(loanDisbursementDetails.getId(), expectedDisbursementDate, actualDisbursementDate, - loanDisbursementDetails.principal(), null, null, waivedChargeAmount)); + loanDisbursementDetails.principal(), this.netDisbursalAmount, null, null, waivedChargeAmount)); } return disbursementData; @@ -6726,4 +6749,7 @@ public class Loan extends AbstractPersistableCustom { return this.loanCollateralManagements; } + public void adjustNetDisbursalAmount(BigDecimal adjustedAmount) { + this.netDisbursalAmount = adjustedAmount.subtract(this.deriveSumTotalOfChargesDueAtDisbursement()); + } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java index a9590d2ee..d20cd26d6 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java @@ -498,6 +498,10 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService { final Money amount = Money.of(loan.getCurrency(), transactionAmount); LoanTransaction disbursementTransaction = LoanTransaction.disbursement(loan.getOffice(), amount, paymentDetail, transactionDate, txnExternalId, DateUtils.getLocalDateTimeOfTenant(), currentUser); + + // Subtract Previous loan outstanding balance from netDisbursalAmount + loan.deductFromNetDisbursalAmount(transactionAmount); + disbursementTransaction.updateLoan(loan); loan.addLoanTransaction(disbursementTransaction); saveLoanTransactionWithDataIntegrityViolationChecks(disbursementTransaction); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanDisbursementDetails.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanDisbursementDetails.java index d3fccdd3b..6399c36b4 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanDisbursementDetails.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanDisbursementDetails.java @@ -52,14 +52,19 @@ public class LoanDisbursementDetails extends AbstractPersistableCustom { @Column(name = "principal", scale = 6, precision = 19, nullable = false) private BigDecimal principal; + @Column(name = "net_disbursal_amount", scale = 6, precision = 19) + private BigDecimal netDisbursalAmount; + protected LoanDisbursementDetails() { } - public LoanDisbursementDetails(final Date expectedDisbursementDate, final Date actualDisbursementDate, final BigDecimal principal) { + public LoanDisbursementDetails(final Date expectedDisbursementDate, final Date actualDisbursementDate, final BigDecimal principal, + final BigDecimal netDisbursalAmount) { this.expectedDisbursementDate = expectedDisbursementDate; this.actualDisbursementDate = actualDisbursementDate; this.principal = principal; + this.netDisbursalAmount = netDisbursalAmount; } public void updateLoan(final Loan loan) { @@ -130,13 +135,22 @@ public class LoanDisbursementDetails extends AbstractPersistableCustom { actualDisburseDate = LocalDate.ofInstant(this.actualDisbursementDate.toInstant(), DateUtils.getDateTimeZoneOfTenant()); } BigDecimal waivedChargeAmount = null; - return new DisbursementData(getId(), expectedDisburseDate, actualDisburseDate, this.principal, null, null, waivedChargeAmount); + return new DisbursementData(getId(), expectedDisburseDate, actualDisburseDate, this.principal, this.netDisbursalAmount, null, null, + waivedChargeAmount); } public void updateActualDisbursementDate(Date actualDisbursementDate) { this.actualDisbursementDate = actualDisbursementDate; } + public BigDecimal getNetDisbursalAmount() { + return this.netDisbursalAmount; + } + + public void setNetDisbursalAmount(BigDecimal netDisbursalAmount) { + this.netDisbursalAmount = netDisbursalAmount; + } + public void updateExpectedDisbursementDateAndAmount(Date expectedDisbursementDate, BigDecimal principal) { this.expectedDisbursementDate = expectedDisbursementDate; this.principal = principal; diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransaction.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransaction.java index d7022cdfa..953ed31f7 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransaction.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransaction.java @@ -636,9 +636,9 @@ public class LoanTransaction extends AbstractPersistableCustom { paymentDetailData = this.paymentDetail.toData(); } return new LoanTransactionData(getId(), this.office.getId(), this.office.getName(), transactionType, paymentDetailData, - currencyData, getTransactionDate(), this.amount, this.principalPortion, this.interestPortion, this.feeChargesPortion, - this.penaltyChargesPortion, this.overPaymentPortion, this.externalId, transfer, null, outstandingLoanBalance, - this.unrecognizedIncomePortion, this.manuallyAdjustedOrReversed); + currencyData, getTransactionDate(), this.amount, this.loan.getNetDisbursalAmount(), this.principalPortion, + this.interestPortion, this.feeChargesPortion, this.penaltyChargesPortion, this.overPaymentPortion, this.externalId, + transfer, null, outstandingLoanBalance, this.unrecognizedIncomePortion, this.manuallyAdjustedOrReversed); } public Map toMapData(final CurrencyData currencyData) { @@ -653,6 +653,7 @@ public class LoanTransaction extends AbstractPersistableCustom { thisTransactionData.put("date", getTransactionDate()); thisTransactionData.put("currency", currencyData); thisTransactionData.put("amount", this.amount); + thisTransactionData.put("netDisbursalAmount", this.loan.getNetDisbursalAmount()); thisTransactionData.put("principalPortion", this.principalPortion); thisTransactionData.put("interestPortion", this.interestPortion); thisTransactionData.put("feeChargesPortion", this.feeChargesPortion); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleAssembler.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleAssembler.java index ff012d517..e217fc898 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleAssembler.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleAssembler.java @@ -520,6 +520,7 @@ public class LoanScheduleAssembler { final JsonObject jsonObject = disbursementDataArray.get(i).getAsJsonObject(); LocalDate expectedDisbursementDate = null; BigDecimal principal = null; + BigDecimal netDisbursalAmount = null; if (jsonObject.has(LoanApiConstants.disbursementDateParameterName)) { expectedDisbursementDate = this.fromApiJsonHelper @@ -530,9 +531,16 @@ public class LoanScheduleAssembler { && StringUtils.isNotBlank(jsonObject.get(LoanApiConstants.disbursementPrincipalParameterName).getAsString())) { principal = jsonObject.getAsJsonPrimitive(LoanApiConstants.disbursementPrincipalParameterName).getAsBigDecimal(); } + if (jsonObject.has(LoanApiConstants.disbursementNetDisbursalAmountParameterName) + && jsonObject.get(LoanApiConstants.disbursementNetDisbursalAmountParameterName).isJsonPrimitive() + && StringUtils.isNotBlank( + jsonObject.get(LoanApiConstants.disbursementNetDisbursalAmountParameterName).getAsString())) { + netDisbursalAmount = jsonObject.getAsJsonPrimitive(LoanApiConstants.disbursementNetDisbursalAmountParameterName) + .getAsBigDecimal(); + } BigDecimal waivedChargeAmount = null; - disbursementDatas - .add(new DisbursementData(null, expectedDisbursementDate, null, principal, null, null, waivedChargeAmount)); + disbursementDatas.add(new DisbursementData(null, expectedDisbursementDate, null, principal, netDisbursalAmount, null, + null, waivedChargeAmount)); i++; } while (i < disbursementDataArray.size()); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanApplicationTransitionApiJsonValidator.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanApplicationTransitionApiJsonValidator.java index cf3ad6cf3..5c0850e6b 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanApplicationTransitionApiJsonValidator.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanApplicationTransitionApiJsonValidator.java @@ -62,10 +62,11 @@ public final class LoanApplicationTransitionApiJsonValidator { throw new InvalidJsonException(); } - final Set disbursementParameters = new HashSet<>(Arrays.asList(LoanApiConstants.loanIdTobeApproved, - LoanApiConstants.approvedLoanAmountParameterName, LoanApiConstants.approvedOnDateParameterName, - LoanApiConstants.noteParameterName, LoanApiConstants.localeParameterName, LoanApiConstants.dateFormatParameterName, - LoanApiConstants.disbursementDataParameterName, LoanApiConstants.disbursementDateParameterName)); + final Set disbursementParameters = new HashSet<>( + Arrays.asList(LoanApiConstants.loanIdTobeApproved, LoanApiConstants.approvedLoanAmountParameterName, + LoanApiConstants.approvedOnDateParameterName, LoanApiConstants.disbursementNetDisbursalAmountParameterName, + LoanApiConstants.noteParameterName, LoanApiConstants.localeParameterName, LoanApiConstants.dateFormatParameterName, + LoanApiConstants.disbursementDataParameterName, LoanApiConstants.disbursementDateParameterName)); final Type typeOfMap = new TypeToken>() {}.getType(); this.fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, disbursementParameters); @@ -80,6 +81,11 @@ public final class LoanApplicationTransitionApiJsonValidator { baseDataValidator.reset().parameter(LoanApiConstants.approvedLoanAmountParameterName).value(principal).ignoreIfNull() .positiveAmount(); + final BigDecimal netDisbursalAmount = this.fromApiJsonHelper + .extractBigDecimalWithLocaleNamed(LoanApiConstants.disbursementNetDisbursalAmountParameterName, element); + baseDataValidator.reset().parameter(LoanApiConstants.disbursementNetDisbursalAmountParameterName).value(netDisbursalAmount) + .ignoreIfNull().positiveAmount(); + final LocalDate approvedOnDate = this.fromApiJsonHelper.extractLocalDateNamed(LoanApiConstants.approvedOnDateParameterName, element); baseDataValidator.reset().parameter(LoanApiConstants.approvedOnDateParameterName).value(approvedOnDate).notNull(); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanEventApiJsonValidator.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanEventApiJsonValidator.java index 2cac0dd93..8de348f99 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanEventApiJsonValidator.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanEventApiJsonValidator.java @@ -86,12 +86,13 @@ public final class LoanEventApiJsonValidator { if (isAccountTransfer) { disbursementParameters = new HashSet<>(Arrays.asList("actualDisbursementDate", "externalId", "note", "locale", "dateFormat", - LoanApiConstants.principalDisbursedParameterName, LoanApiConstants.emiAmountParameterName)); + LoanApiConstants.principalDisbursedParameterName, LoanApiConstants.emiAmountParameterName, + LoanApiConstants.disbursementNetDisbursalAmountParameterName)); } else { disbursementParameters = new HashSet<>(Arrays.asList("actualDisbursementDate", "externalId", "note", "locale", "dateFormat", "paymentTypeId", "accountNumber", "checkNumber", "routingCode", "receiptNumber", "bankNumber", "adjustRepaymentDate", LoanApiConstants.principalDisbursedParameterName, LoanApiConstants.emiAmountParameterName, - LoanApiConstants.postDatedChecks)); + LoanApiConstants.postDatedChecks, LoanApiConstants.disbursementNetDisbursalAmountParameterName)); } final Type typeOfMap = new TypeToken>() {}.getType(); @@ -112,6 +113,11 @@ public final class LoanEventApiJsonValidator { baseDataValidator.reset().parameter(LoanApiConstants.principalDisbursedParameterName).value(principal).ignoreIfNull() .positiveAmount(); + final BigDecimal netDisbursalAmount = this.fromApiJsonHelper + .extractBigDecimalWithLocaleNamed(LoanApiConstants.disbursementNetDisbursalAmountParameterName, element); + baseDataValidator.reset().parameter(LoanApiConstants.disbursementNetDisbursalAmountParameterName).value(netDisbursalAmount) + .ignoreIfNull().positiveAmount(); + final BigDecimal emiAmount = this.fromApiJsonHelper.extractBigDecimalWithLocaleNamed(LoanApiConstants.emiAmountParameterName, element); baseDataValidator.reset().parameter(LoanApiConstants.emiAmountParameterName).value(emiAmount).ignoreIfNull().positiveAmount() diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java index 35d608cbf..7d78d7543 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java @@ -1457,6 +1457,8 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa throw new GeneralPlatformDomainRuleException("error.msg.loan.amount.less.than.outstanding.of.loan.to.be.closed", "Topup loan amount should be greater than outstanding amount of loan to be closed."); } + BigDecimal netDisbursalAmount = loan.getApprovedPrincipal().subtract(loanOutstanding); + loan.adjustNetDisbursalAmount(netDisbursalAmount); } saveAndFlushLoanWithDataIntegrityViolationChecks(loan); @@ -1538,6 +1540,8 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa loan.regenerateRepaymentSchedule(scheduleGeneratorDTO, currentUser); } + loan.adjustNetDisbursalAmount(loan.getProposedPrincipal()); + saveAndFlushLoanWithDataIntegrityViolationChecks(loan); final String noteText = command.stringValueOfParameterNamed("note"); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java index a40178886..2de00d3b6 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanReadPlatformServiceImpl.java @@ -434,8 +434,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { RepaymentTransactionTemplateMapper mapper = new RepaymentTransactionTemplateMapper(); String sql = "select " + mapper.schema(); - LoanTransactionData loanTransactionData = this.jdbcTemplate.queryForObject(sql, mapper, LoanTransactionType.REPAYMENT.getValue(), - loanId, loanId); + LoanTransactionData loanTransactionData = this.jdbcTemplate.queryForObject(sql, mapper, + new Object[] { LoanTransactionType.REPAYMENT.getValue(), loanId, loanId }); final Collection paymentOptions = this.paymentTypeReadPlatformService.retrieveAllPaymentTypes(); return LoanTransactionData.templateOnTop(loanTransactionData, paymentOptions); } @@ -464,7 +464,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { BigDecimal adjustedChargeAmount = adjustPrepayInstallmentCharge(loan, onDate); return new LoanTransactionData(null, null, null, transactionType, null, currencyData, earliestUnpaidInstallmentDate, loanRepaymentScheduleInstallment.getTotalOutstanding(currency).getAmount().subtract(adjustedChargeAmount), - loanRepaymentScheduleInstallment.getPrincipalOutstanding(currency).getAmount(), + loan.getNetDisbursalAmount(), loanRepaymentScheduleInstallment.getPrincipalOutstanding(currency).getAmount(), loanRepaymentScheduleInstallment.getInterestOutstanding(currency).getAmount(), loanRepaymentScheduleInstallment.getFeeChargesOutstanding(currency).getAmount().subtract(adjustedChargeAmount), loanRepaymentScheduleInstallment.getPenaltyChargesOutstanding(currency).getAmount(), null, unrecognizedIncomePortion, @@ -508,7 +508,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { final BigDecimal outstandingLoanBalance = null; final BigDecimal unrecognizedIncomePortion = null; return new LoanTransactionData(null, null, null, transactionType, null, currencyData, waiveOfInterest.getTransactionDate(), amount, - null, null, null, null, null, null, null, null, outstandingLoanBalance, unrecognizedIncomePortion, false); + loan.getNetDisbursalAmount(), null, null, null, null, null, null, null, null, outstandingLoanBalance, + unrecognizedIncomePortion, false); } @Override @@ -519,14 +520,14 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { final LoanTransactionEnumData transactionType = LoanEnumerations.transactionType(LoanTransactionType.WRITEOFF); final BigDecimal unrecognizedIncomePortion = null; return new LoanTransactionData(null, null, null, transactionType, null, null, DateUtils.getLocalDateOfTenant(), null, null, null, - null, null, null, null, null, null, outstandingLoanBalance, unrecognizedIncomePortion, false); + null, null, null, null, null, null, null, outstandingLoanBalance, unrecognizedIncomePortion, false); } @Override public LoanApprovalData retrieveApprovalTemplate(final Long loanId) { final Loan loan = this.loanRepositoryWrapper.findOneWithNotFoundDetection(loanId, true); - return new LoanApprovalData(loan.getProposedPrincipal(), DateUtils.getLocalDateOfTenant()); + return new LoanApprovalData(loan.getProposedPrincipal(), DateUtils.getLocalDateOfTenant(), loan.getNetDisbursalAmount()); } @Override @@ -539,8 +540,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { } return LoanTransactionData.loanTransactionDataForDisbursalTemplate(transactionType, - loan.getExpectedDisbursedOnLocalDateForTemplate(), loan.getDisburseAmountForTemplate(), paymentOptions, - loan.retriveLastEmiAmount(), loan.getNextPossibleRepaymentDateForRescheduling()); + loan.getExpectedDisbursedOnLocalDateForTemplate(), loan.getDisburseAmountForTemplate(), loan.getNetDisbursalAmount(), + paymentOptions, loan.retriveLastEmiAmount(), loan.getNextPossibleRepaymentDateForRescheduling()); } @@ -603,7 +604,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { + " l.expected_disbursedon_date as expectedDisbursementDate, l.disbursedon_date as actualDisbursementDate, dbu.username as disbursedByUsername, dbu.firstname as disbursedByFirstname, dbu.lastname as disbursedByLastname," + " l.closedon_date as closedOnDate, cbu.username as closedByUsername, cbu.firstname as closedByFirstname, cbu.lastname as closedByLastname, l.writtenoffon_date as writtenOffOnDate, " + " l.expected_firstrepaymenton_date as expectedFirstRepaymentOnDate, l.interest_calculated_from_date as interestChargedFromDate, l.expected_maturedon_date as expectedMaturityDate, " - + " l.principal_amount_proposed as proposedPrincipal, l.principal_amount as principal, l.approved_principal as approvedPrincipal, l.arrearstolerance_amount as inArrearsTolerance, l.number_of_repayments as numberOfRepayments, l.repay_every as repaymentEvery," + + " l.principal_amount_proposed as proposedPrincipal, l.principal_amount as principal, l.approved_principal as approvedPrincipal, l.net_disbursal_amount as netDisbursalAmount, l.arrearstolerance_amount as inArrearsTolerance, l.number_of_repayments as numberOfRepayments, l.repay_every as repaymentEvery," + " l.grace_on_principal_periods as graceOnPrincipalPayment, l.recurring_moratorium_principal_periods as recurringMoratoriumOnPrincipalPeriods, l.grace_on_interest_periods as graceOnInterestPayment, l.grace_interest_free_periods as graceOnInterestCharged,l.grace_on_arrears_ageing as graceOnArrearsAgeing," + " l.nominal_interest_rate_per_period as interestRatePerPeriod, l.annual_nominal_interest_rate as annualInterestRate, " + " l.repayment_period_frequency_enum as repaymentFrequencyType, l.interest_period_frequency_enum as interestRateFrequencyType, " @@ -785,6 +786,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { final BigDecimal principal = rs.getBigDecimal("principal"); final BigDecimal approvedPrincipal = rs.getBigDecimal("approvedPrincipal"); final BigDecimal proposedPrincipal = rs.getBigDecimal("proposedPrincipal"); + final BigDecimal netDisbursalAmount = rs.getBigDecimal("netDisbursalAmount"); final BigDecimal totalOverpaid = rs.getBigDecimal("totalOverpaid"); final BigDecimal inArrearsTolerance = rs.getBigDecimal("inArrearsTolerance"); @@ -985,10 +987,10 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { return LoanAccountData.basicLoanDetails(id, accountNo, status, externalId, clientId, clientAccountNo, clientName, clientOfficeId, groupData, loanType, loanProductId, loanProductName, loanProductDescription, isLoanProductLinkedToFloatingRate, fundId, fundName, loanPurposeId, loanPurposeName, loanOfficerId, loanOfficerName, - currencyData, proposedPrincipal, principal, approvedPrincipal, totalOverpaid, inArrearsTolerance, termFrequency, - termPeriodFrequencyType, numberOfRepayments, repaymentEvery, repaymentFrequencyType, null, null, transactionStrategyId, - transactionStrategyName, amortizationType, interestRatePerPeriod, interestRateFrequencyType, annualInterestRate, - interestType, isFloatingInterestRate, interestRateDifferential, interestCalculationPeriodType, + currencyData, proposedPrincipal, principal, approvedPrincipal, netDisbursalAmount, totalOverpaid, inArrearsTolerance, + termFrequency, termPeriodFrequencyType, numberOfRepayments, repaymentEvery, repaymentFrequencyType, null, null, + transactionStrategyId, transactionStrategyName, amortizationType, interestRatePerPeriod, interestRateFrequencyType, + annualInterestRate, interestType, isFloatingInterestRate, interestRateDifferential, interestCalculationPeriodType, allowPartialPeriodInterestCalcualtion, expectedFirstRepaymentOnDate, graceOnPrincipalPayment, recurringMoratoriumOnPrincipalPeriods, graceOnInterestPayment, graceOnInterestCharged, interestChargedFromDate, timeline, loanSummary, feeChargesDueAtDisbursementCharged, syncDisbursementWithMeeting, loanCounter, loanProductCounter, @@ -1055,7 +1057,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { private LocalDate lastDueDate; private BigDecimal outstandingLoanPrincipalBalance; private boolean excludePastUndisbursed; - private BigDecimal totalPaidFeeCharges; + private final BigDecimal totalPaidFeeCharges; LoanScheduleResultSetExtractor(final RepaymentScheduleRelatedLoanData repaymentScheduleRelatedLoanData, Collection disbursementData, boolean isInterestRecalculationEnabled, BigDecimal totalPaidFeeCharges) { @@ -1290,7 +1292,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { + " tr.unrecognized_income_portion as unrecognizedIncome," + " tr.submitted_on_date as submittedOnDate, " + " tr.manually_adjusted_or_reversed as manuallyReversed, " + " pd.payment_type_id as paymentType,pd.account_number as accountNumber,pd.check_number as checkNumber, " - + " pd.receipt_number as receiptNumber, pd.bank_number as bankNumber,pd.routing_code as routingCode, " + + " pd.receipt_number as receiptNumber, pd.bank_number as bankNumber,pd.routing_code as routingCode, l.net_disbursal_amount as netDisbursalAmount," + " l.currency_code as currencyCode, l.currency_digits as currencyDigits, l.currency_multiplesof as inMultiplesOf, rc.`name` as currencyName, " + " rc.display_symbol as currencyDisplaySymbol, rc.internationalized_name_code as currencyNameCode, " + " pt.value as paymentTypeName, tr.external_id as externalId, tr.office_id as officeId, office.name as officeName, " @@ -1354,6 +1356,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { final BigDecimal outstandingLoanBalance = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "outstandingLoanBalance"); final String externalId = rs.getString("externalId"); + final BigDecimal netDisbursalAmount = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "netDisbursalAmount"); + AccountTransferData transfer = null; final Long fromTransferId = JdbcSupport.getLong(rs, "fromTransferId"); final Long toTransferId = JdbcSupport.getLong(rs, "toTransferId"); @@ -1375,7 +1379,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { toTransferDescription, toTransferReversed); } return new LoanTransactionData(id, officeId, officeName, transactionType, paymentDetailData, currencyData, date, totalAmount, - principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion, overPaymentPortion, + netDisbursalAmount, principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion, overPaymentPortion, unrecognizedIncomePortion, externalId, transfer, null, outstandingLoanBalance, submittedOnDate, manuallyReversed); } } @@ -1562,7 +1566,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { private static final class LoanDisbursementDetailMapper implements RowMapper { public String schema() { - return "dd.id as id,dd.expected_disburse_date as expectedDisbursementdate, dd.disbursedon_date as actualDisbursementdate,dd.principal as principal,sum(lc.amount) chargeAmount, lc.amount_waived_derived waivedAmount,group_concat(lc.id) loanChargeId " + return "dd.id as id,dd.expected_disburse_date as expectedDisbursementdate, dd.disbursedon_date as actualDisbursementdate,dd.principal as principal,dd.net_disbursal_amount as netDisbursalAmount,sum(lc.amount) chargeAmount, lc.amount_waived_derived waivedAmount,group_concat(lc.id) loanChargeId " + "from m_loan l inner join m_loan_disbursement_detail dd on dd.loan_id = l.id left join m_loan_tranche_disbursement_charge tdc on tdc.disbursement_detail_id=dd.id " + "left join m_loan_charge lc on lc.id=tdc.loan_charge_id and lc.is_active=1"; } @@ -1574,13 +1578,14 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { final LocalDate actualDisbursementdate = JdbcSupport.getLocalDate(rs, "actualDisbursementdate"); final BigDecimal principal = rs.getBigDecimal("principal"); final String loanChargeId = rs.getString("loanChargeId"); + final BigDecimal netDisbursalAmount = rs.getBigDecimal("netDisbursalAmount"); BigDecimal chargeAmount = rs.getBigDecimal("chargeAmount"); final BigDecimal waivedAmount = rs.getBigDecimal("waivedAmount"); if (chargeAmount != null && waivedAmount != null) { chargeAmount = chargeAmount.subtract(waivedAmount); } final DisbursementData disbursementData = new DisbursementData(id, expectedDisbursementdate, actualDisbursementdate, principal, - loanChargeId, chargeAmount, waivedAmount); + netDisbursalAmount, loanChargeId, chargeAmount, waivedAmount); return disbursementData; } @@ -1802,8 +1807,9 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { final Collection paymentOptions = this.paymentTypeReadPlatformService.retrieveAllPaymentTypes(); BigDecimal outstandingLoanBalance = null; final BigDecimal unrecognizedIncomePortion = null; - return new LoanTransactionData(null, null, null, transactionType, null, null, null, loan.getTotalWrittenOff(), null, null, null, - null, null, unrecognizedIncomePortion, paymentOptions, null, null, null, outstandingLoanBalance, false); + return new LoanTransactionData(null, null, null, transactionType, null, null, null, loan.getTotalWrittenOff(), + loan.getNetDisbursalAmount(), null, null, null, null, null, unrecognizedIncomePortion, paymentOptions, null, null, null, + outstandingLoanBalance, false); } @@ -1817,8 +1823,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { final List writeOffReasonOptions = new ArrayList<>( this.codeValueReadPlatformService.retrieveCodeValuesByCode(LoanApiConstants.WRITEOFFREASONS)); LoanTransactionData loanTransactionData = new LoanTransactionData(null, null, null, transactionType, null, loan.currency(), - DateUtils.getLocalDateOfTenant(), loan.getTotalOutstandingAmount(), null, null, null, null, null, null, null, null, - outstandingLoanBalance, unrecognizedIncomePortion, false); + DateUtils.getLocalDateOfTenant(), loan.getTotalOutstandingAmount(), loan.getNetDisbursalAmount(), null, null, null, null, + null, null, null, null, outstandingLoanBalance, unrecognizedIncomePortion, false); loanTransactionData.setWriteOffReasonOptions(writeOffReasonOptions); return loanTransactionData; } @@ -1960,8 +1966,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { final BigDecimal unrecognizedIncomePortion = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "unrecognizedIncome"); final BigDecimal outstandingLoanBalance = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "outstandingLoanBalance"); - return new LoanTransactionData(id, transactionType, date, totalAmount, principalPortion, interestPortion, feeChargesPortion, - penaltyChargesPortion, overPaymentPortion, unrecognizedIncomePortion, outstandingLoanBalance, false); + return new LoanTransactionData(id, transactionType, date, totalAmount, null, principalPortion, interestPortion, + feeChargesPortion, penaltyChargesPortion, overPaymentPortion, unrecognizedIncomePortion, outstandingLoanBalance, false); } } @@ -2094,8 +2100,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { final LoanTransactionEnumData transactionType = LoanEnumerations.transactionType(LoanTransactionType.REFUND_FOR_ACTIVE_LOAN); final Collection paymentOptions = this.paymentTypeReadPlatformService.retrieveAllPaymentTypes(); return new LoanTransactionData(null, null, null, transactionType, null, currencyData, earliestUnpaidInstallmentDate, - retrieveTotalPaidInAdvance(loan.getId()).getPaidInAdvance(), null, null, null, null, null, null, paymentOptions, null, null, - null, null, false); + retrieveTotalPaidInAdvance(loan.getId()).getPaidInAdvance(), null, loan.getNetDisbursalAmount(), null, null, null, null, + null, paymentOptions, null, null, null, null, false); } @Override @@ -2185,7 +2191,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { final Money outStandingAmount = loanRepaymentScheduleInstallment.getTotalOutstanding(currency); return new LoanTransactionData(null, null, null, transactionType, null, currencyData, earliestUnpaidInstallmentDate, - outStandingAmount.getAmount(), loanRepaymentScheduleInstallment.getPrincipalOutstanding(currency).getAmount(), + outStandingAmount.getAmount(), loan.getNetDisbursalAmount(), + loanRepaymentScheduleInstallment.getPrincipalOutstanding(currency).getAmount(), loanRepaymentScheduleInstallment.getInterestOutstanding(currency).getAmount(), loanRepaymentScheduleInstallment.getFeeChargesOutstanding(currency).getAmount(), loanRepaymentScheduleInstallment.getPenaltyChargesOutstanding(currency).getAmount(), null, unrecognizedIncomePortion, @@ -2224,7 +2231,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { sqlBuilder.append( "ls.penalty_charges_amount - IFNULL(ls.penalty_charges_completed_derived,0) - IFNULL(ls.penalty_charges_writtenoff_derived,0) - IFNULL(ls.penalty_charges_waived_derived,0) as penaltyDue, "); sqlBuilder.append( - "l.currency_code as currencyCode, l.currency_digits as currencyDigits, l.currency_multiplesof as inMultiplesOf, rc.`name` as currencyName, "); + "l.currency_code as currencyCode, l.currency_digits as currencyDigits, l.currency_multiplesof as inMultiplesOf, l.net_disbursal_amount as netDisbursalAmount, rc.`name` as currencyName, "); sqlBuilder.append("rc.display_symbol as currencyDisplaySymbol, rc.internationalized_name_code as currencyNameCode "); sqlBuilder.append("FROM m_loan l "); sqlBuilder.append( @@ -2261,6 +2268,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { final BigDecimal outstandingLoanBalance = null; final BigDecimal unrecognizedIncomePortion = null; final BigDecimal overPaymentPortion = null; + final BigDecimal netDisbursalAmount = JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "netDisbursalAmount"); final Long id = null; final Long officeId = null; final String officeName = null; @@ -2270,8 +2278,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService { final AccountTransferData transfer = null; final BigDecimal fixedEmiAmount = null; return new LoanTransactionData(id, officeId, officeName, transactionType, paymentDetailData, currencyData, date, totalDue, - principalPortion, interestDue, feeDue, penaltyDue, overPaymentPortion, externalId, transfer, fixedEmiAmount, - outstandingLoanBalance, unrecognizedIncomePortion, manuallyReversed); + netDisbursalAmount, principalPortion, interestDue, feeDue, penaltyDue, overPaymentPortion, externalId, transfer, + fixedEmiAmount, outstandingLoanBalance, unrecognizedIncomePortion, manuallyReversed); } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanUtilService.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanUtilService.java index 82a640014..ee201c8ea 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanUtilService.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanUtilService.java @@ -318,6 +318,7 @@ public class LoanUtilService { Date expectedDisbursementDate = null; Date actualDisbursementDate = null; BigDecimal principal = null; + BigDecimal netDisbursalAmount = null; if (jsonObject.has(LoanApiConstants.disbursementDateParameterName)) { LocalDate date = this.fromApiJsonHelper.extractLocalDateNamed(LoanApiConstants.disbursementDateParameterName, @@ -331,8 +332,16 @@ public class LoanUtilService { && StringUtils.isNotBlank(jsonObject.get(LoanApiConstants.disbursementPrincipalParameterName).getAsString())) { principal = jsonObject.getAsJsonPrimitive(LoanApiConstants.disbursementPrincipalParameterName).getAsBigDecimal(); } + if (jsonObject.has(LoanApiConstants.disbursementNetDisbursalAmountParameterName) + && jsonObject.get(LoanApiConstants.disbursementNetDisbursalAmountParameterName).isJsonPrimitive() + && StringUtils.isNotBlank( + jsonObject.get(LoanApiConstants.disbursementNetDisbursalAmountParameterName).getAsString())) { + netDisbursalAmount = jsonObject.getAsJsonPrimitive(LoanApiConstants.disbursementNetDisbursalAmountParameterName) + .getAsBigDecimal(); + } - disbursementDatas.add(new LoanDisbursementDetails(expectedDisbursementDate, actualDisbursementDate, principal)); + disbursementDatas.add( + new LoanDisbursementDetails(expectedDisbursementDate, actualDisbursementDate, principal, netDisbursalAmount)); i++; } while (i < disbursementDataArray.size()); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java index c37bc17f6..cbe94031e 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java @@ -448,6 +448,13 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf boolean canDisburse = loan.canDisburse(actualDisbursementDate); ChangedTransactionDetail changedTransactionDetail = null; if (canDisburse) { + + // Get netDisbursalAmount from disbursal screen field. + final BigDecimal netDisbursalAmount = command + .bigDecimalValueOfParameterNamed(LoanApiConstants.disbursementNetDisbursalAmountParameterName); + if (netDisbursalAmount != null) { + loan.setNetDisbursalAmount(netDisbursalAmount); + } Money disburseAmount = loan.adjustDisburseAmount(command, actualDisbursementDate); Money amountToDisburse = disburseAmount.copy(); boolean recalculateSchedule = amountBeforeAdjust.isNotEqualTo(loan.getPrincpal()); @@ -504,6 +511,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf } else { changedTransactionDetail = loan.disburse(currentUser, command, changes, scheduleGeneratorDTO, null); } + + loan.adjustNetDisbursalAmount(amountToDisburse.getAmount()); } if (!changes.isEmpty()) { saveAndFlushLoanWithDataIntegrityViolationChecks(loan); @@ -873,6 +882,15 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf currentUser); if (!changes.isEmpty()) { + if (loan.isTopup() && loan.getClientId() != null) { + final Long loanIdToClose = loan.getTopupLoanDetails().getLoanIdToClose(); + final LocalDate expectedDisbursementDate = command + .localDateValueOfParameterNamed(LoanApiConstants.disbursementDateParameterName); + BigDecimal loanOutstanding = this.loanReadPlatformService + .retrieveLoanPrePaymentTemplate(loanIdToClose, expectedDisbursementDate).getAmount(); + BigDecimal netDisbursalAmount = loan.getApprovedPrincipal().subtract(loanOutstanding); + loan.adjustNetDisbursalAmount(netDisbursalAmount); + } saveAndFlushLoanWithDataIntegrityViolationChecks(loan); this.accountTransfersWritePlatformService.reverseAllTransactions(loanId, PortfolioAccountType.LOAN); String noteText = null; diff --git a/fineract-provider/src/main/resources/sql/migrations/core_db/V371__loan_net_disbursal_amount.sql b/fineract-provider/src/main/resources/sql/migrations/core_db/V371__loan_net_disbursal_amount.sql new file mode 100644 index 000000000..456fa7afc --- /dev/null +++ b/fineract-provider/src/main/resources/sql/migrations/core_db/V371__loan_net_disbursal_amount.sql @@ -0,0 +1,21 @@ +-- +-- 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. +-- + +ALTER TABLE `m_loan` ADD COLUMN `net_disbursal_amount` DECIMAL(19,6) NOT NULL AFTER `approved_principal`; +ALTER TABLE `m_loan_disbursement_detail` ADD COLUMN `net_disbursal_amount` DECIMAL(19,6); diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/AccountTransferTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/AccountTransferTest.java index 31c77aea5..eec29b43f 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/AccountTransferTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/AccountTransferTest.java @@ -23,6 +23,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import io.restassured.builder.RequestSpecBuilder; import io.restassured.builder.ResponseSpecBuilder; import io.restassured.http.ContentType; +import io.restassured.path.json.JsonPath; import io.restassured.specification.RequestSpecification; import io.restassured.specification.ResponseSpecification; import java.math.BigDecimal; @@ -269,7 +270,9 @@ public class AccountTransferTest { toLoanStatusHashMap = this.loanTransactionHelper.approveLoan(LOAN_APPROVAL_DATE, toLoanID); LoanStatusChecker.verifyLoanIsApproved(toLoanStatusHashMap); - toLoanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSAL_DATE, toLoanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, toLoanID); + toLoanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSAL_DATE, toLoanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(toLoanStatusHashMap); Integer fromOfficeId = officeHelper.createOffice("01 January 2011"); @@ -387,7 +390,9 @@ public class AccountTransferTest { loanStatusHashMap = this.loanTransactionHelper.approveLoan(LOAN_APPROVAL_DATE, loanID); LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSAL_DATE, loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSAL_DATE, loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); final Integer fromSavingsProductID = createSavingsProduct(this.requestSpec, this.responseSpec, MINIMUM_OPENING_BALANCE, diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/AccountingScenarioIntegrationTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/AccountingScenarioIntegrationTest.java index 7d92d47d9..76d1e2bdf 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/AccountingScenarioIntegrationTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/AccountingScenarioIntegrationTest.java @@ -23,6 +23,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import io.restassured.builder.RequestSpecBuilder; import io.restassured.builder.ResponseSpecBuilder; import io.restassured.http.ContentType; +import io.restassured.path.json.JsonPath; import io.restassured.specification.RequestSpecification; import io.restassured.specification.ResponseSpecification; import java.math.BigDecimal; @@ -158,7 +159,9 @@ public class AccountingScenarioIntegrationTest { LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap); LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan(EXPECTED_DISBURSAL_DATE, loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(requestSpec, responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan(EXPECTED_DISBURSAL_DATE, loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); // CHECK ACCOUNT ENTRIES @@ -594,7 +597,9 @@ public class AccountingScenarioIntegrationTest { LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap); LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan(EXPECTED_DISBURSAL_DATE, loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(requestSpec, responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan(EXPECTED_DISBURSAL_DATE, loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); // CHECK ACCOUNT ENTRIES @@ -716,7 +721,9 @@ public class AccountingScenarioIntegrationTest { LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap); LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan(EXPECTED_DISBURSAL_DATE, loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(requestSpec, responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan(EXPECTED_DISBURSAL_DATE, loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); // CHECK ACCOUNT ENTRIES @@ -813,7 +820,9 @@ public class AccountingScenarioIntegrationTest { todayDate = Calendar.getInstance(); todayDate.add(Calendar.DATE, -2); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(requestSpec, responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); this.loanTransactionHelper.addChargesForLoan(loanID, LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON( @@ -919,7 +928,9 @@ public class AccountingScenarioIntegrationTest { todayDate = Calendar.getInstance(); todayDate.add(Calendar.DATE, -2); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(requestSpec, responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); this.loanTransactionHelper.addChargesForLoan(loanID, LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON( @@ -1019,7 +1030,9 @@ public class AccountingScenarioIntegrationTest { LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap); LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan(EXPECTED_DISBURSAL_DATE, loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(requestSpec, responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan(EXPECTED_DISBURSAL_DATE, loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); // CHECK ACCOUNT ENTRIES diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanIntegrationTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanIntegrationTest.java index 45a39834f..f26ce0b69 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanIntegrationTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanIntegrationTest.java @@ -289,7 +289,9 @@ public class ClientLoanIntegrationTest { LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); // DISBURSE - loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 September 2011", loanID, "10000"); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 September 2011", loanID, "10000", + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LOG.info("DISBURSE {}", loanStatusHashMap.toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); @@ -438,7 +440,9 @@ public class ClientLoanIntegrationTest { validateNumberForEqual("100.0", String.valueOf(firstInstallment.get("feeChargesDue"))); // DISBURSE - loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 September 2011", loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 September 2011", loanID, "10000", + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LOG.info("DISBURSE {}", loanStatusHashMap.toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); @@ -686,7 +690,9 @@ public class ClientLoanIntegrationTest { validateChargeExcludePrecission(flatAccTransfer, loanCharges, "100.0", "400", "0.0", "0.0"); // DISBURSE - loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 September 2011", loanID); + String loanDetail = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 September 2011", loanID, "10000", + JsonPath.from(loanDetail).get("netDisbursalAmount").toString()); LOG.info("DISBURSE {}", loanStatusHashMap.toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); @@ -838,7 +844,9 @@ public class ClientLoanIntegrationTest { assertEquals(balance, summary.get("accountBalance"), "Verifying opening Balance"); // DISBURSE - loanStatusHashMap = this.loanTransactionHelper.disburseLoanToSavings(SavingsAccountHelper.TRANSACTION_DATE, loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoanToSavings(SavingsAccountHelper.TRANSACTION_DATE, loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LOG.info("DISBURSE {}", loanStatusHashMap.toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); @@ -888,12 +896,15 @@ public class ClientLoanIntegrationTest { LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); // DISBURSE first Tranche - loanStatusHashMap = this.loanTransactionHelper.disburseLoan("01 March 2014", loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 March 2014", loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LOG.info("DISBURSE {}", loanStatusHashMap); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); // DISBURSE Second Tranche - loanStatusHashMap = this.loanTransactionHelper.disburseLoan("23 April 2014", loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan("23 April 2014", loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LOG.info("DISBURSE {}", loanStatusHashMap.toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); @@ -945,7 +956,9 @@ public class ClientLoanIntegrationTest { assertEquals(balance, summary.get("accountBalance"), "Verifying opening Balance"); // DISBURSE first Tranche - loanStatusHashMap = this.loanTransactionHelper.disburseLoanToSavings("01 March 2014", loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoanToSavings("01 March 2014", loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LOG.info("DISBURSE {}", loanStatusHashMap.toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); @@ -954,7 +967,8 @@ public class ClientLoanIntegrationTest { assertEquals(balance, summary.get("accountBalance"), "Verifying opening Balance"); // DISBURSE Second Tranche - loanStatusHashMap = this.loanTransactionHelper.disburseLoanToSavings("23 April 2014", loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoanToSavings("23 April 2014", loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LOG.info("DISBURSE {}", loanStatusHashMap.toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); @@ -1461,7 +1475,9 @@ public class ClientLoanIntegrationTest { LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); LOG.info("-------------------------------DISBURSE LOAN-------------------------------------------"); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 September 2011", loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 September 2011", loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); final JournalEntry[] assetAccountInitialEntry = { new JournalEntry(Float.parseFloat("100.00"), JournalEntry.TransactionType.DEBIT), @@ -1650,7 +1666,9 @@ public class ClientLoanIntegrationTest { LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); LOG.info("-------------------------------DISBURSE LOAN-------------------------------------------"); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 September 2011", loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 September 2011", loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); final JournalEntry[] assetAccountInitialEntry = { new JournalEntry(Float.parseFloat("120.00"), JournalEntry.TransactionType.DEBIT), @@ -1840,7 +1858,9 @@ public class ClientLoanIntegrationTest { LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); LOG.info("-------------------------------DISBURSE LOAN-------------------------------------------"); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 September 2011", loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 September 2011", loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); final JournalEntry[] assetAccountInitialEntry = { new JournalEntry(Float.parseFloat("126.06"), JournalEntry.TransactionType.DEBIT), @@ -2026,7 +2046,9 @@ public class ClientLoanIntegrationTest { LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); LOG.info("-------------------------------DISBURSE LOAN-------------------------------------------"); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 September 2011", loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 September 2011", loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); final JournalEntry[] assetAccountInitialEntry = { new JournalEntry(Float.parseFloat("605.94"), JournalEntry.TransactionType.DEBIT), @@ -2233,7 +2255,9 @@ public class ClientLoanIntegrationTest { LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); LOG.info("-------------------------------DISBURSE LOAN-------------------------------------------"); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 September 2011", loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 September 2011", loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); final JournalEntry[] assetAccountInitialEntry = { new JournalEntry(Float.parseFloat("605.94"), JournalEntry.TransactionType.DEBIT), @@ -2429,7 +2453,9 @@ public class ClientLoanIntegrationTest { LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); LOG.info("-------------------------------DISBURSE LOAN-------------------------------------------"); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 September 2011", loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 September 2011", loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); final JournalEntry[] assetAccountInitialEntry = { new JournalEntry(Float.parseFloat("605.94"), JournalEntry.TransactionType.DEBIT), @@ -2632,7 +2658,9 @@ public class ClientLoanIntegrationTest { LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); LOG.info("-------------------------------DISBURSE LOAN-------------------------------------------"); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 September 2011", loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 September 2011", loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); final JournalEntry[] assetAccountInitialEntry = { new JournalEntry(Float.parseFloat("100.00"), JournalEntry.TransactionType.DEBIT), @@ -2832,7 +2860,9 @@ public class ClientLoanIntegrationTest { LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); LOG.info("-------------------------------DISBURSE LOAN-------------------------------------------"); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 September 2011", loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 September 2011", loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); final JournalEntry[] assetAccountInitialEntry = { new JournalEntry(Float.parseFloat("120.00"), JournalEntry.TransactionType.DEBIT), @@ -3034,7 +3064,9 @@ public class ClientLoanIntegrationTest { LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); LOG.info("-------------------------------DISBURSE LOAN-------------------------------------------"); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 September 2011", loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 September 2011", loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); final JournalEntry[] assetAccountInitialEntry = { new JournalEntry(Float.parseFloat("126.06"), JournalEntry.TransactionType.DEBIT), @@ -3253,7 +3285,9 @@ public class ClientLoanIntegrationTest { LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); LOG.info("-------------------------------DISBURSE LOAN-------------------------------------------"); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 September 2011", loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 September 2011", loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); ArrayList loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); @@ -3402,7 +3436,9 @@ public class ClientLoanIntegrationTest { LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); LOG.info("-------------------------------DISBURSE LOAN-------------------------------------------"); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); @@ -3510,7 +3546,9 @@ public class ClientLoanIntegrationTest { LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); LOG.info("-------------------------------DISBURSE LOAN-------------------------------------------"); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); @@ -3593,7 +3631,9 @@ public class ClientLoanIntegrationTest { LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); LOG.info("-------------------------------DISBURSE LOAN-------------------------------------------"); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); @@ -3688,7 +3728,9 @@ public class ClientLoanIntegrationTest { LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); LOG.info("-------------------------------DISBURSE LOAN-------------------------------------------"); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); @@ -3820,7 +3862,9 @@ public class ClientLoanIntegrationTest { LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); LOG.info("-------------------------------DISBURSE LOAN-------------------------------------------"); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); @@ -3952,7 +3996,9 @@ public class ClientLoanIntegrationTest { LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); LOG.info("-------------------------------DISBURSE LOAN-------------------------------------------"); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); @@ -4044,7 +4090,9 @@ public class ClientLoanIntegrationTest { LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); LOG.info("-------------------------------DISBURSE LOAN-------------------------------------------"); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); @@ -4154,7 +4202,9 @@ public class ClientLoanIntegrationTest { LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); LOG.info("-------------------------------DISBURSE LOAN-------------------------------------------"); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); @@ -4253,7 +4303,9 @@ public class ClientLoanIntegrationTest { LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); LOG.info("-------------------------------DISBURSE LOAN-------------------------------------------"); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); @@ -4336,7 +4388,9 @@ public class ClientLoanIntegrationTest { LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); LOG.info("-------------------------------DISBURSE LOAN-------------------------------------------"); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); @@ -4424,7 +4478,9 @@ public class ClientLoanIntegrationTest { LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); LOG.info("-------------------------------DISBURSE LOAN-------------------------------------------"); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); @@ -4688,7 +4744,9 @@ public class ClientLoanIntegrationTest { LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); LOG.info("-------------------------------DISBURSE LOAN-------------------------------------------"); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan(fourMonthsfromNow, loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan(fourMonthsfromNow, loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); final JournalEntry[] assetAccountInitialEntry = { @@ -4872,7 +4930,9 @@ public class ClientLoanIntegrationTest { LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); LOG.info("-------------------------------DISBURSE LOAN-------------------------------------------"); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan(fourMonthsfromNow, loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan(fourMonthsfromNow, loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); final JournalEntry[] assetAccountInitialEntry = { new JournalEntry(Float.parseFloat("1440"), JournalEntry.TransactionType.DEBIT), @@ -5067,7 +5127,9 @@ public class ClientLoanIntegrationTest { LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); LOG.info("-------------------------------DISBURSE LOAN-------------------------------------------"); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan(fourMonthsfromNow, loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan(fourMonthsfromNow, loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); final JournalEntry[] assetAccountInitialEntry = { @@ -5298,7 +5360,9 @@ public class ClientLoanIntegrationTest { LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); LOG.info("----------------------------------- DISBURSE LOAN ----------------------------------------"); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 September 2011", loanID, "10,000.00"); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 September 2011", loanID, "10,000.00", + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LOG.info("DISBURSE {}", loanStatusHashMap); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); @@ -5364,7 +5428,9 @@ public class ClientLoanIntegrationTest { LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); LOG.info("-------------------------------DISBURSE LOAN-------------------------------------------"); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); @@ -5477,7 +5543,9 @@ public class ClientLoanIntegrationTest { LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); LOG.info("-------------------------------DISBURSE LOAN-------------------------------------------"); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID); diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ConcurrencyIntegrationTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ConcurrencyIntegrationTest.java index 966ec9f13..566c02453 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ConcurrencyIntegrationTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ConcurrencyIntegrationTest.java @@ -21,6 +21,7 @@ package org.apache.fineract.integrationtests; import io.restassured.builder.RequestSpecBuilder; import io.restassured.builder.ResponseSpecBuilder; import io.restassured.http.ContentType; +import io.restassured.path.json.JsonPath; import io.restassured.specification.RequestSpecification; import io.restassured.specification.ResponseSpecification; import java.math.BigDecimal; @@ -75,8 +76,9 @@ public class ConcurrencyIntegrationTest { final Integer loanProductID = createLoanProduct(false, NO_ACCOUNTING); final Integer loanID = applyForLoanApplication(clientID, loanProductID, "12,000.00"); this.loanTransactionHelper.approveLoan("20 September 2011", loanID); - this.loanTransactionHelper.disburseLoan("20 September 2011", loanID, "12,000.00"); - + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + this.loanTransactionHelper.disburseLoan("20 September 2011", loanID, "12,000.00", + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); ExecutorService executor = Executors.newFixedThreadPool(MYTHREADS); Calendar date = Calendar.getInstance(); date.set(2011, 9, 20); diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/DisbursalAndRepaymentScheduleTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/DisbursalAndRepaymentScheduleTest.java index fd4462421..43ee8e61c 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/DisbursalAndRepaymentScheduleTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/DisbursalAndRepaymentScheduleTest.java @@ -24,6 +24,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import io.restassured.builder.RequestSpecBuilder; import io.restassured.builder.ResponseSpecBuilder; import io.restassured.http.ContentType; +import io.restassured.path.json.JsonPath; import io.restassured.specification.RequestSpecification; import io.restassured.specification.ResponseSpecification; import java.text.SimpleDateFormat; @@ -156,7 +157,9 @@ public class DisbursalAndRepaymentScheduleTest { LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap); // Test for loan account approved can be disbursed - this.loanTransactionHelper.disburseLoan(disbursalDate, this.loanId); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, this.loanId); + this.loanTransactionHelper.disburseLoan(disbursalDate, this.loanId, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, this.loanId); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); @@ -312,7 +315,9 @@ public class DisbursalAndRepaymentScheduleTest { LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap); // Test for loan account approved can be disbursed - this.loanTransactionHelper.disburseLoan(disbursalDate, this.loanId); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, this.loanId); + this.loanTransactionHelper.disburseLoan(disbursalDate, this.loanId, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, this.loanId); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/GroupTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/GroupTest.java index 594ceaf68..618dd4230 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/GroupTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/GroupTest.java @@ -24,6 +24,7 @@ import static org.junit.jupiter.api.Assertions.assertNotEquals; import io.restassured.builder.RequestSpecBuilder; import io.restassured.builder.ResponseSpecBuilder; import io.restassured.http.ContentType; +import io.restassured.path.json.JsonPath; import io.restassured.specification.RequestSpecification; import io.restassured.specification.ResponseSpecification; import java.math.BigDecimal; @@ -136,7 +137,9 @@ public class GroupTest { final Integer loanId = this.applyForLoanApplication(clientID, loanProductId, this.principal); this.loanTransactionHelper.approveLoan("20 September 2014", loanId); - this.loanTransactionHelper.disburseLoan("20 September 2014", loanId); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanId); + this.loanTransactionHelper.disburseLoan("20 September 2014", loanId, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); final HashMap assignStaffAndInheritStaffForClientAccounts = (HashMap) GroupHelper.assignStaffInheritStaffForClientAccounts( this.requestSpec, this.responseSpec, groupID.toString(), createStaffId1.toString()); diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanApplicationUndoLastTrancheTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanApplicationUndoLastTrancheTest.java index 2172b6170..e1cbb0329 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanApplicationUndoLastTrancheTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanApplicationUndoLastTrancheTest.java @@ -21,6 +21,7 @@ package org.apache.fineract.integrationtests; import io.restassured.builder.RequestSpecBuilder; import io.restassured.builder.ResponseSpecBuilder; import io.restassured.http.ContentType; +import io.restassured.path.json.JsonPath; import io.restassured.specification.RequestSpecification; import io.restassured.specification.ResponseSpecification; import java.math.BigDecimal; @@ -106,7 +107,8 @@ public class LoanApplicationUndoLastTrancheTest { LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); // DISBURSE A LOAN - this.loanTransactionHelper.disburseLoan(disbursalDate, loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + this.loanTransactionHelper.disburseLoan(disbursalDate, loanID, JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID); // VALIDATE THE LOAN IS ACTIVE STATUS @@ -119,7 +121,7 @@ public class LoanApplicationUndoLastTrancheTest { LOG.info("-------------Make repayment 3-----------"); this.loanTransactionHelper.makeRepayment("01 June 2014", Float.valueOf("204"), loanID); // DISBURSE A SECOND TRANCHE - this.loanTransactionHelper.disburseLoan("23 June 2014", loanID); + this.loanTransactionHelper.disburseLoan("23 June 2014", loanID, JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); // UNDO LAST TRANCHE Float disbursedAmount = this.loanTransactionHelper.undoLastDisbursal(loanID); validateDisbursedAmount(disbursedAmount); diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanDisbursalDateValidationTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanDisbursalDateValidationTest.java index 2c14185a7..9d8337d15 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanDisbursalDateValidationTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanDisbursalDateValidationTest.java @@ -21,6 +21,7 @@ package org.apache.fineract.integrationtests; import io.restassured.builder.RequestSpecBuilder; import io.restassured.builder.ResponseSpecBuilder; import io.restassured.http.ContentType; +import io.restassured.path.json.JsonPath; import io.restassured.specification.RequestSpecification; import io.restassured.specification.ResponseSpecification; import java.math.BigDecimal; @@ -93,9 +94,10 @@ public class LoanDisbursalDateValidationTest { LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); // DISBURSE A LOAN + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); @SuppressWarnings("unchecked") List disbursalError = (List) this.loanTransactionHelper.disburseLoan(disbursalDate, loanID, - this.responseForbiddenError); + this.responseForbiddenError, JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); Assertions.assertEquals(disbursalError.get(0).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE), "error.msg.actual.disbursement.date.does.not.match.with.expected.disbursal.date"); diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleOnDecliningBalanceLoanTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleOnDecliningBalanceLoanTest.java index 7ed3e0028..4734355af 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleOnDecliningBalanceLoanTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleOnDecliningBalanceLoanTest.java @@ -24,6 +24,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import io.restassured.builder.RequestSpecBuilder; import io.restassured.builder.ResponseSpecBuilder; import io.restassured.http.ContentType; +import io.restassured.path.json.JsonPath; import io.restassured.specification.RequestSpecification; import io.restassured.specification.ResponseSpecification; import java.math.BigDecimal; @@ -216,7 +217,9 @@ public class LoanRescheduleOnDecliningBalanceLoanTest { private void disburseLoan() { if (this.loanId != null) { - this.loanTransactionHelper.disburseLoan(this.dateString, this.loanId); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, this.loanId); + this.loanTransactionHelper.disburseLoan(this.dateString, this.loanId, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LOG.info("Successfully disbursed loan (ID: {} )", this.loanId); } } diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleRequestTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleRequestTest.java index 13f265cbd..0e7a86bf7 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleRequestTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleRequestTest.java @@ -24,6 +24,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import io.restassured.builder.RequestSpecBuilder; import io.restassured.builder.ResponseSpecBuilder; import io.restassured.http.ContentType; +import io.restassured.path.json.JsonPath; import io.restassured.specification.RequestSpecification; import io.restassured.specification.ResponseSpecification; import java.math.BigDecimal; @@ -167,7 +168,9 @@ public class LoanRescheduleRequestTest { private void disburseLoan() { if (this.loanId != null) { - this.loanTransactionHelper.disburseLoan(this.dateString, this.loanId); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, this.loanId); + this.loanTransactionHelper.disburseLoan(this.dateString, this.loanId, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LOG.info("Successfully disbursed loan (ID: {} )", this.loanId); } } diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanReschedulingWithinCenterTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanReschedulingWithinCenterTest.java index 9f78e91e3..b51c47ce4 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanReschedulingWithinCenterTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanReschedulingWithinCenterTest.java @@ -24,6 +24,7 @@ import com.google.gson.Gson; import io.restassured.builder.RequestSpecBuilder; import io.restassured.builder.ResponseSpecBuilder; import io.restassured.http.ContentType; +import io.restassured.path.json.JsonPath; import io.restassured.specification.RequestSpecification; import io.restassured.specification.ResponseSpecification; import java.math.BigDecimal; @@ -142,7 +143,8 @@ public class LoanReschedulingWithinCenterTest { LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap); // Test for loan account approved can be disbursed - this.loanTransactionHelper.disburseLoan(disbursalDate, loanId); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanId); + this.loanTransactionHelper.disburseLoan(disbursalDate, loanId, JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanId); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); @@ -294,7 +296,8 @@ public class LoanReschedulingWithinCenterTest { LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); // DISBURSE A FIRST TRANCHE - this.loanTransactionHelper.disburseLoan(disbursementDate, loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + this.loanTransactionHelper.disburseLoan(disbursementDate, loanID, JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID); LOG.info("---------------------------------CHANGING GROUP MEETING DATE ------------------------------------------"); diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanWithWaiveInterestAndWriteOffIntegrationTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanWithWaiveInterestAndWriteOffIntegrationTest.java index 6ee827592..5001e5a7e 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanWithWaiveInterestAndWriteOffIntegrationTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanWithWaiveInterestAndWriteOffIntegrationTest.java @@ -21,6 +21,7 @@ package org.apache.fineract.integrationtests; import io.restassured.builder.RequestSpecBuilder; import io.restassured.builder.ResponseSpecBuilder; import io.restassured.http.ContentType; +import io.restassured.path.json.JsonPath; import io.restassured.specification.RequestSpecification; import io.restassured.specification.ResponseSpecification; import java.math.BigDecimal; @@ -104,7 +105,9 @@ public class LoanWithWaiveInterestAndWriteOffIntegrationTest { LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); // DISBURSE - loanStatusHashMap = this.loanTransactionHelper.disburseLoan(DISBURSEMENT_DATE, loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan(DISBURSEMENT_DATE, loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LOG.info("DISBURSE {}", loanStatusHashMap.toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); @@ -117,7 +120,8 @@ public class LoanWithWaiveInterestAndWriteOffIntegrationTest { LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); // DIBURSE AGAIN - loanStatusHashMap = this.loanTransactionHelper.disburseLoan(DISBURSEMENT_DATE, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan(DISBURSEMENT_DATE, loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LOG.info("DISBURSE {}", loanStatusHashMap); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); @@ -163,7 +167,9 @@ public class LoanWithWaiveInterestAndWriteOffIntegrationTest { LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); // DISBURSE - loanStatusHashMap = this.loanTransactionHelper.disburseLoan(DISBURSEMENT_DATE, loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan(DISBURSEMENT_DATE, loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LOG.info("DISBURSE {}", loanStatusHashMap); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/MinimumDaysBetweenDisbursalAndFirstRepaymentTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/MinimumDaysBetweenDisbursalAndFirstRepaymentTest.java index 7325d907d..0a013c8b9 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/MinimumDaysBetweenDisbursalAndFirstRepaymentTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/MinimumDaysBetweenDisbursalAndFirstRepaymentTest.java @@ -23,6 +23,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import io.restassured.builder.RequestSpecBuilder; import io.restassured.builder.ResponseSpecBuilder; import io.restassured.http.ContentType; +import io.restassured.path.json.JsonPath; import io.restassured.specification.RequestSpecification; import io.restassured.specification.ResponseSpecification; import java.math.BigDecimal; @@ -115,7 +116,9 @@ public class MinimumDaysBetweenDisbursalAndFirstRepaymentTest { LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap); // Test for loan account approved can be disbursed - this.loanTransactionHelper.disburseLoan(disbursalDate, this.loanId); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, this.loanId); + this.loanTransactionHelper.disburseLoan(disbursalDate, this.loanId, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, this.loanId); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/NotesTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/NotesTest.java index 38f9318c3..1e9a0a89d 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/NotesTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/NotesTest.java @@ -21,6 +21,7 @@ package org.apache.fineract.integrationtests; import io.restassured.builder.RequestSpecBuilder; import io.restassured.builder.ResponseSpecBuilder; import io.restassured.http.ContentType; +import io.restassured.path.json.JsonPath; import io.restassured.specification.RequestSpecification; import io.restassured.specification.ResponseSpecification; import java.math.BigDecimal; @@ -273,7 +274,8 @@ public class NotesTest { Assertions.assertNotNull(loanId); this.loanTransactionHelper.approveLoan("02 April 2012", loanId); - this.loanTransactionHelper.disburseLoan("02 April 2012", loanId); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanId); + this.loanTransactionHelper.disburseLoan("02 April 2012", loanId, JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); HashMap repayment = this.loanTransactionHelper.makeRepayment("02 April 2012", 100.0f, loanId); Integer loanTransactionId = (Integer) repayment.get("resourceId"); Assertions.assertNotNull(loanTransactionId); @@ -296,7 +298,8 @@ public class NotesTest { Assertions.assertNotNull(loanId); this.loanTransactionHelper.approveLoan("02 April 2012", loanId); - this.loanTransactionHelper.disburseLoan("02 April 2012", loanId); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanId); + this.loanTransactionHelper.disburseLoan("02 April 2012", loanId, JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); HashMap repayment = this.loanTransactionHelper.makeRepayment("02 April 2012", 100.0f, loanId); Integer loanTransactionId = (Integer) repayment.get("resourceId"); Assertions.assertNotNull(loanTransactionId); @@ -328,7 +331,8 @@ public class NotesTest { Assertions.assertNotNull(loanId); this.loanTransactionHelper.approveLoan("02 April 2012", loanId); - this.loanTransactionHelper.disburseLoan("02 April 2012", loanId); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanId); + this.loanTransactionHelper.disburseLoan("02 April 2012", loanId, JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); HashMap repayment = this.loanTransactionHelper.makeRepayment("02 April 2012", 100.0f, loanId); Integer loanTransactionId = (Integer) repayment.get("resourceId"); Assertions.assertNotNull(loanTransactionId); diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/SchedulerJobsTestResults.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/SchedulerJobsTestResults.java index 83a7bcc52..c78c87c6d 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/SchedulerJobsTestResults.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/SchedulerJobsTestResults.java @@ -24,6 +24,7 @@ import com.google.common.truth.Truth; import io.restassured.builder.RequestSpecBuilder; import io.restassured.builder.ResponseSpecBuilder; import io.restassured.http.ContentType; +import io.restassured.path.json.JsonPath; import io.restassured.specification.RequestSpecification; import io.restassured.specification.ResponseSpecification; import java.math.BigDecimal; @@ -239,7 +240,9 @@ public class SchedulerJobsTestResults { ArrayList chargesPendingState = this.loanTransactionHelper.getLoanCharges(loanID); Assertions.assertEquals(1, chargesPendingState.size()); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan(AccountTransferTest.LOAN_DISBURSAL_DATE, loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(requestSpec, responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan(AccountTransferTest.LOAN_DISBURSAL_DATE, loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); final HashMap summaryBefore = this.savingsAccountHelper.getSavingsSummary(savingsId); @@ -280,7 +283,9 @@ public class SchedulerJobsTestResults { loanStatusHashMap = this.loanTransactionHelper.approveLoan(AccountTransferTest.LOAN_APPROVAL_DATE, loanID); LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan(AccountTransferTest.LOAN_DISBURSAL_DATE, loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(requestSpec, responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan(AccountTransferTest.LOAN_DISBURSAL_DATE, loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); // Retrieving All Global Configuration details @@ -431,7 +436,9 @@ public class SchedulerJobsTestResults { loanStatusHashMap = this.loanTransactionHelper.approveLoan(AccountTransferTest.LOAN_APPROVAL_DATE, loanID); LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan(AccountTransferTest.LOAN_DISBURSAL_DATE, loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(requestSpec, responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan(AccountTransferTest.LOAN_DISBURSAL_DATE, loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); String JobName = "Update Loan Arrears Ageing"; @@ -476,7 +483,9 @@ public class SchedulerJobsTestResults { loanStatusHashMap = this.loanTransactionHelper.approveLoan(AccountTransferTest.LOAN_APPROVAL_DATE, loanID); LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(requestSpec, responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); ArrayList loanScheduleBefore = this.loanTransactionHelper.getLoanRepaymentSchedule(requestSpec, responseSpec, loanID); @@ -538,7 +547,9 @@ public class SchedulerJobsTestResults { loanStatusHashMap = this.loanTransactionHelper.approveLoan(AccountTransferTest.LOAN_APPROVAL_DATE, loanID); LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(requestSpec, responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan(LOAN_DISBURSEMENT_DATE, loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); HashMap loanSummaryBefore = this.loanTransactionHelper.getLoanSummary(requestSpec, responseSpec, loanID); @@ -667,7 +678,9 @@ public class SchedulerJobsTestResults { loanStatusHashMap = this.loanTransactionHelper.approveLoan(AccountTransferTest.LOAN_APPROVAL_DATE, loanID); LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan(AccountTransferTest.LOAN_APPROVAL_DATE_PLUS_ONE, loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(requestSpec, responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan(AccountTransferTest.LOAN_APPROVAL_DATE_PLUS_ONE, loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); String JobName = "Apply penalty to overdue loans"; @@ -713,7 +726,9 @@ public class SchedulerJobsTestResults { loanStatusHashMap = this.loanTransactionHelper.approveLoan(AccountTransferTest.LOAN_APPROVAL_DATE, loanID); LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan(AccountTransferTest.LOAN_APPROVAL_DATE_PLUS_ONE, loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(requestSpec, responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan(AccountTransferTest.LOAN_APPROVAL_DATE_PLUS_ONE, loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); String JobName = "Apply penalty to overdue loans"; @@ -764,7 +779,9 @@ public class SchedulerJobsTestResults { loanStatusHashMap = this.loanTransactionHelper.approveLoan(AccountTransferTest.LOAN_APPROVAL_DATE, loanID); LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan(AccountTransferTest.LOAN_DISBURSAL_DATE, loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(requestSpec, responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan(AccountTransferTest.LOAN_APPROVAL_DATE_PLUS_ONE, loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); final Boolean isNPABefore = (Boolean) this.loanTransactionHelper.getLoanDetail(requestSpec, responseSpec, loanID, "isNPA"); diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/ProvisioningIntegrationTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/ProvisioningIntegrationTest.java index 69468d6f8..d2ee8af26 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/ProvisioningIntegrationTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/ProvisioningIntegrationTest.java @@ -22,6 +22,7 @@ import com.google.gson.Gson; import io.restassured.builder.RequestSpecBuilder; import io.restassured.builder.ResponseSpecBuilder; import io.restassured.http.ContentType; +import io.restassured.path.json.JsonPath; import io.restassured.specification.RequestSpecification; import io.restassured.specification.ResponseSpecification; import java.math.BigDecimal; @@ -97,7 +98,9 @@ public class ProvisioningIntegrationTest { LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap); LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); LOG.info("-------------------------------DISBURSE LOAN-------------------------------------------"); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 September 2011", loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan("20 September 2011", loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); Assertions.assertNotNull(loanID); } diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanTransactionHelper.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanTransactionHelper.java index 7f88182d4..afd4339b5 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanTransactionHelper.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanTransactionHelper.java @@ -206,8 +206,9 @@ public class LoanTransactionHelper { return performLoanTransaction(createLoanOperationURL(UNDO_APPROVAL_LOAN_COMMAND, loanID), undoBodyJson); } - public HashMap disburseLoan(final String date, final Integer loanID) { - return performLoanTransaction(createLoanOperationURL(DISBURSE_LOAN_COMMAND, loanID), getDisburseLoanAsJSON(date, null)); + public HashMap disburseLoan(final String date, final Integer loanID, final String netDisbursalAmount) { + return performLoanTransaction(createLoanOperationURL(DISBURSE_LOAN_COMMAND, loanID), + getDisburseLoanAsJSON(date, null, netDisbursalAmount)); } public HashMap disburseLoanWithPostDatedChecks(final String date, final Integer loanId, final BigDecimal transactionAmount, @@ -237,17 +238,20 @@ public class LoanTransactionHelper { getDisburseLoanWithRepaymentRescheduleAsJSON(date, null, adjustRepaymentDate)); } - public HashMap disburseLoan(final String date, final Integer loanID, final String disburseAmt) { - return performLoanTransaction(createLoanOperationURL(DISBURSE_LOAN_COMMAND, loanID), getDisburseLoanAsJSON(date, disburseAmt)); + public HashMap disburseLoan(final String date, final Integer loanID, final String disburseAmt, final String netDisbursalAmount) { + return performLoanTransaction(createLoanOperationURL(DISBURSE_LOAN_COMMAND, loanID), + getDisburseLoanAsJSON(date, disburseAmt, netDisbursalAmount)); } - public Object disburseLoan(final String date, final Integer loanID, ResponseSpecification responseValidationError) { - return performLoanTransaction(createLoanOperationURL(DISBURSE_LOAN_COMMAND, loanID), getDisburseLoanAsJSON(date, null), - responseValidationError); + public Object disburseLoan(final String date, final Integer loanID, ResponseSpecification responseValidationError, + final String netDisbursalAmount) { + return performLoanTransaction(createLoanOperationURL(DISBURSE_LOAN_COMMAND, loanID), + getDisburseLoanAsJSON(date, null, netDisbursalAmount), responseValidationError); } - public HashMap disburseLoanToSavings(final String date, final Integer loanID) { - return performLoanTransaction(createLoanOperationURL(DISBURSE_LOAN_TO_SAVINGS_COMMAND, loanID), getDisburseLoanAsJSON(date, null)); + public HashMap disburseLoanToSavings(final String date, final Integer loanID, final String netDisbursalAmount) { + return performLoanTransaction(createLoanOperationURL(DISBURSE_LOAN_TO_SAVINGS_COMMAND, loanID), + getDisburseLoanAsJSON(date, null, netDisbursalAmount)); } public HashMap undoDisbursal(final Integer loanID) { @@ -407,11 +411,13 @@ public class LoanTransactionHelper { return Utils.performServerGet(requestSpec, responseSpec, GET_POST_DATED_TRANS_URL, ""); } - private String getDisburseLoanAsJSON(final String actualDisbursementDate, final String transactionAmount) { + private String getDisburseLoanAsJSON(final String actualDisbursementDate, final String transactionAmount, + final String netDisbursalAmount) { final HashMap map = new HashMap<>(); map.put("locale", "en"); map.put("dateFormat", "dd MMMM yyyy"); map.put("actualDisbursementDate", actualDisbursementDate); + map.put("netDisbursalAmount", netDisbursalAmount); map.put("note", "DISBURSE NOTE"); if (transactionAmount != null) { map.put("transactionAmount", transactionAmount); diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/guarantor/GuarantorTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/guarantor/GuarantorTest.java index ad88a4a26..3e7c70f53 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/guarantor/GuarantorTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/guarantor/GuarantorTest.java @@ -25,6 +25,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import io.restassured.builder.RequestSpecBuilder; import io.restassured.builder.ResponseSpecBuilder; import io.restassured.http.ContentType; +import io.restassured.path.json.JsonPath; import io.restassured.specification.RequestSpecification; import io.restassured.specification.ResponseSpecification; import java.math.BigDecimal; @@ -179,7 +180,9 @@ public class GuarantorTest { verifySavingsOnHoldBalance(externalSavigsId_2, external2_hold_funds); LOG.info("-------------------------------DISBURSE LOAN-------------------------------------------"); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan(loanDisbursementDate, loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan(loanDisbursementDate, loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); // First repayment @@ -371,7 +374,9 @@ public class GuarantorTest { } LOG.info("-------------------------------DISBURSE LOAN-------------------------------------------"); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan(loanDisbursementDate, loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan(loanDisbursementDate, loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); // First repayment @@ -475,7 +480,9 @@ public class GuarantorTest { verifySavingsOnHoldBalance(externalSavigsId_1, external1_hold_funds); LOG.info("-------------------------------DISBURSE LOAN-------------------------------------------"); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan(loanDisbursementDate, loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan(loanDisbursementDate, loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); // First repayment @@ -549,7 +556,9 @@ public class GuarantorTest { verifySavingsOnHoldBalance(externalSavigsId_1, external1_hold_funds); LOG.info("-------------------------------DISBURSE LOAN-------------------------------------------"); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan(loanDisbursementDate, loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan(loanDisbursementDate, loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); // First repayment @@ -619,7 +628,9 @@ public class GuarantorTest { verifySavingsOnHoldBalance(externalSavigsId_1, external1_hold_funds); LOG.info("-------------------------------DISBURSE LOAN-------------------------------------------"); - loanStatusHashMap = this.loanTransactionHelper.disburseLoan(loanDisbursementDate, loanID); + String loanDetails = this.loanTransactionHelper.getLoanDetails(this.requestSpec, this.responseSpec, loanID); + loanStatusHashMap = this.loanTransactionHelper.disburseLoan(loanDisbursementDate, loanID, + JsonPath.from(loanDetails).get("netDisbursalAmount").toString()); LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap); // First repayment