This is an automated email from the ASF dual-hosted git repository.
arnold pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git
The following commit(s) were added to refs/heads/develop by this push:
new 22bcccb17 Loan summary with principal adjustments
22bcccb17 is described below
commit 22bcccb17b582b146963e1d9da51bc1e17c70b2a
Author: Jose Alberto Hernandez <[email protected]>
AuthorDate: Fri Oct 14 14:55:16 2022 -0500
Loan summary with principal adjustments
---
.../src/main/avro/loan/v1/LoanSummaryDataV1.avsc | 8 +++
.../loanaccount/api/LoansApiResourceSwagger.java | 2 +
.../loanaccount/data/LoanSummaryData.java | 27 +++++----
.../portfolio/loanaccount/domain/LoanSummary.java | 11 +++-
.../loanaccount/domain/LoanSummaryWrapper.java | 11 +++-
.../service/LoanReadPlatformServiceImpl.java | 68 +++++++++++-----------
.../api/SelfLoansApiResourceSwagger.java | 2 +
.../db/changelog/tenant/changelog-tenant.xml | 1 +
.../0057_add_principal_adjustments_to_loan.xml | 30 ++++++++++
.../LoanTransactionChargebackTest.java | 21 ++++++-
10 files changed, 132 insertions(+), 49 deletions(-)
diff --git a/fineract-avro-schemas/src/main/avro/loan/v1/LoanSummaryDataV1.avsc
b/fineract-avro-schemas/src/main/avro/loan/v1/LoanSummaryDataV1.avsc
index 88dd74402..f19879e95 100644
--- a/fineract-avro-schemas/src/main/avro/loan/v1/LoanSummaryDataV1.avsc
+++ b/fineract-avro-schemas/src/main/avro/loan/v1/LoanSummaryDataV1.avsc
@@ -19,6 +19,14 @@
"bigdecimal"
]
},
+ {
+ "default": null,
+ "name": "principalAdjustments",
+ "type": [
+ "null",
+ "bigdecimal"
+ ]
+ },
{
"default": null,
"name": "principalPaid",
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResourceSwagger.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResourceSwagger.java
index 98bc435ff..34a066364 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResourceSwagger.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/api/LoansApiResourceSwagger.java
@@ -478,6 +478,8 @@ final class LoansApiResourceSwagger {
public Double principalDisbursed;
@Schema(example = "0.000000")
public Double principalPaid;
+ @Schema(example = "0.00")
+ public Double principalAdjustments;
@Schema(example = "0.000000")
public Double principalWrittenOff;
@Schema(example = "1000000.000000")
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanSummaryData.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanSummaryData.java
index efd710378..d9f33e2d7 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanSummaryData.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanSummaryData.java
@@ -31,6 +31,7 @@ public class LoanSummaryData {
private final CurrencyData currency;
private final BigDecimal principalDisbursed;
+ private final BigDecimal principalAdjustments;
private final BigDecimal principalPaid;
private final BigDecimal principalWrittenOff;
private final BigDecimal principalOutstanding;
@@ -67,20 +68,22 @@ public class LoanSummaryData {
private final Long writeoffReasonId;
private final String writeoffReason;
- public LoanSummaryData(final CurrencyData currency, final BigDecimal
principalDisbursed, final BigDecimal principalPaid,
- final BigDecimal principalWrittenOff, final BigDecimal
principalOutstanding, final BigDecimal principalOverdue,
- final BigDecimal interestCharged, final BigDecimal interestPaid,
final BigDecimal interestWaived,
- final BigDecimal interestWrittenOff, final BigDecimal
interestOutstanding, final BigDecimal interestOverdue,
- final BigDecimal feeChargesCharged, final BigDecimal
feeChargesDueAtDisbursementCharged, final BigDecimal feeChargesPaid,
- final BigDecimal feeChargesWaived, final BigDecimal
feeChargesWrittenOff, final BigDecimal feeChargesOutstanding,
- final BigDecimal feeChargesOverdue, final BigDecimal
penaltyChargesCharged, final BigDecimal penaltyChargesPaid,
- final BigDecimal penaltyChargesWaived, final BigDecimal
penaltyChargesWrittenOff, final BigDecimal penaltyChargesOutstanding,
- final BigDecimal penaltyChargesOverdue, final BigDecimal
totalExpectedRepayment, final BigDecimal totalRepayment,
- final BigDecimal totalExpectedCostOfLoan, final BigDecimal
totalCostOfLoan, final BigDecimal totalWaived,
- final BigDecimal totalWrittenOff, final BigDecimal
totalOutstanding, final BigDecimal totalOverdue,
- final LocalDate overdueSinceDate, final Long writeoffReasonId,
final String writeoffReason, final BigDecimal totalRecovered) {
+ public LoanSummaryData(final CurrencyData currency, final BigDecimal
principalDisbursed, final BigDecimal principalAdjustments,
+ final BigDecimal principalPaid, final BigDecimal
principalWrittenOff, final BigDecimal principalOutstanding,
+ final BigDecimal principalOverdue, final BigDecimal
interestCharged, final BigDecimal interestPaid,
+ final BigDecimal interestWaived, final BigDecimal
interestWrittenOff, final BigDecimal interestOutstanding,
+ final BigDecimal interestOverdue, final BigDecimal
feeChargesCharged, final BigDecimal feeChargesDueAtDisbursementCharged,
+ final BigDecimal feeChargesPaid, final BigDecimal
feeChargesWaived, final BigDecimal feeChargesWrittenOff,
+ final BigDecimal feeChargesOutstanding, final BigDecimal
feeChargesOverdue, final BigDecimal penaltyChargesCharged,
+ final BigDecimal penaltyChargesPaid, final BigDecimal
penaltyChargesWaived, final BigDecimal penaltyChargesWrittenOff,
+ final BigDecimal penaltyChargesOutstanding, final BigDecimal
penaltyChargesOverdue, final BigDecimal totalExpectedRepayment,
+ final BigDecimal totalRepayment, final BigDecimal
totalExpectedCostOfLoan, final BigDecimal totalCostOfLoan,
+ final BigDecimal totalWaived, final BigDecimal totalWrittenOff,
final BigDecimal totalOutstanding,
+ final BigDecimal totalOverdue, final LocalDate overdueSinceDate,
final Long writeoffReasonId, final String writeoffReason,
+ final BigDecimal totalRecovered) {
this.currency = currency;
this.principalDisbursed = principalDisbursed;
+ this.principalAdjustments = principalAdjustments;
this.principalPaid = principalPaid;
this.principalWrittenOff = principalWrittenOff;
this.principalOutstanding = principalOutstanding;
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanSummary.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanSummary.java
index 9eea2641d..902094070 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanSummary.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanSummary.java
@@ -23,6 +23,7 @@ import java.util.List;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Embeddable;
+import lombok.Getter;
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
import org.apache.fineract.organisation.monetary.domain.Money;
@@ -33,12 +34,16 @@ import
org.apache.fineract.organisation.monetary.domain.Money;
*
*/
@Embeddable
+@Getter
public final class LoanSummary {
// derived totals fields
@Column(name = "principal_disbursed_derived", scale = 6, precision = 19)
private BigDecimal totalPrincipalDisbursed;
+ @Column(name = "principal_adjustments_derived", scale = 6, precision = 19)
+ private BigDecimal totalPrincipalAdjustments;
+
@Column(name = "principal_repaid_derived", scale = 6, precision = 19)
private BigDecimal totalPrincipalRepaid;
@@ -182,6 +187,7 @@ public final class LoanSummary {
*/
public void zeroFields() {
this.totalPrincipalDisbursed = BigDecimal.ZERO;
+ this.totalPrincipalAdjustments = BigDecimal.ZERO;
this.totalPrincipalRepaid = BigDecimal.ZERO;
this.totalPrincipalWrittenOff = BigDecimal.ZERO;
this.totalPrincipalOutstanding = BigDecimal.ZERO;
@@ -214,11 +220,14 @@ public final class LoanSummary {
final Boolean disbursed, Set<LoanCharge> charges) {
this.totalPrincipalDisbursed = principal.getAmount();
+ this.totalPrincipalAdjustments =
summaryWrapper.calculateTotalPrincipalAdjusted(repaymentScheduleInstallments,
currency)
+ .getAmount();
this.totalPrincipalRepaid =
summaryWrapper.calculateTotalPrincipalRepaid(repaymentScheduleInstallments,
currency).getAmount();
this.totalPrincipalWrittenOff =
summaryWrapper.calculateTotalPrincipalWrittenOff(repaymentScheduleInstallments,
currency)
.getAmount();
- this.totalPrincipalOutstanding =
principal.minus(this.totalPrincipalRepaid).minus(this.totalPrincipalWrittenOff).getAmount();
+ this.totalPrincipalOutstanding =
principal.plus(this.totalPrincipalAdjustments).minus(this.totalPrincipalRepaid)
+ .minus(this.totalPrincipalWrittenOff).getAmount();
final Money totalInterestCharged =
summaryWrapper.calculateTotalInterestCharged(repaymentScheduleInstallments,
currency);
this.totalInterestCharged = totalInterestCharged.getAmount();
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanSummaryWrapper.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanSummaryWrapper.java
index 437eead01..5bd79a814 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanSummaryWrapper.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanSummaryWrapper.java
@@ -35,7 +35,16 @@ public final class LoanSummaryWrapper {
final MonetaryCurrency currency) {
Money total = Money.zero(currency);
for (final LoanRepaymentScheduleInstallment installment :
repaymentScheduleInstallments) {
- total =
total.plus(installment.getPrincipalCompleted(currency)).minus(installment.getCredits(currency));
+ total = total.plus(installment.getPrincipalCompleted(currency));
+ }
+ return total;
+ }
+
+ public Money calculateTotalPrincipalAdjusted(final
List<LoanRepaymentScheduleInstallment> repaymentScheduleInstallments,
+ final MonetaryCurrency currency) {
+ Money total = Money.zero(currency);
+ for (final LoanRepaymentScheduleInstallment installment :
repaymentScheduleInstallments) {
+ total = total.plus(installment.getCredits(currency));
}
return total;
}
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 54d901578..a80bbde22 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
@@ -264,7 +264,7 @@ public class LoanReadPlatformServiceImpl implements
LoanReadPlatformService {
* TODO Vishwas: Remove references to "Contra" from the codebase
***/
final String sql = "select " + rm.loanPaymentsSchema() + " where
tr.loan_id = ? and tr.transaction_type_enum not in (0, 3) "
- + " and (tr.is_reversed=false or
tr.manually_adjusted_or_reversed = true) " + " order by tr.transaction_date
ASC,id ";
+ + " and (tr.is_reversed=false or
tr.manually_adjusted_or_reversed = true) order by tr.transaction_date ASC,id ";
Collection<LoanTransactionData> loanTransactionData =
this.jdbcTemplate.query(sql, rm, loanId); // NOSONAR
for (LoanTransactionData loanTransaction : loanTransactionData) {
if (loanTransaction.getType().isRepaymentType()) {
@@ -615,14 +615,14 @@ public class LoanReadPlatformServiceImpl implements
LoanReadPlatformService {
+ sqlGenerator.escape("name")
+ " as currencyName, rc.display_symbol as
currencyDisplaySymbol, rc.internationalized_name_code as currencyNameCode, "
+ " l.loan_officer_id as loanOfficerId, s.display_name as
loanOfficerName, "
- + " l.principal_disbursed_derived as principalDisbursed,"
+ " l.principal_repaid_derived as principalPaid,"
- + " l.principal_writtenoff_derived as principalWrittenOff,"
- + " l.principal_outstanding_derived as
principalOutstanding," + " l.interest_charged_derived as interestCharged,"
- + " l.interest_repaid_derived as interestPaid," + "
l.interest_waived_derived as interestWaived,"
- + " l.interest_writtenoff_derived as interestWrittenOff,"
+ " l.interest_outstanding_derived as interestOutstanding,"
+ + " l.principal_disbursed_derived as principalDisbursed,
l.principal_repaid_derived as principalPaid,"
+ + " l.principal_adjustments_derived as
principalAdjustments, l.principal_writtenoff_derived as principalWrittenOff,"
+ + " l.principal_outstanding_derived as
principalOutstanding, l.interest_charged_derived as interestCharged,"
+ + " l.interest_repaid_derived as interestPaid,
l.interest_waived_derived as interestWaived,"
+ + " l.interest_writtenoff_derived as interestWrittenOff,
l.interest_outstanding_derived as interestOutstanding,"
+ " l.fee_charges_charged_derived as feeChargesCharged,"
+ " l.total_charges_due_at_disbursement_derived as
feeChargesDueAtDisbursementCharged,"
- + " l.fee_charges_repaid_derived as feeChargesPaid," + "
l.fee_charges_waived_derived as feeChargesWaived,"
+ + " l.fee_charges_repaid_derived as feeChargesPaid,
l.fee_charges_waived_derived as feeChargesWaived,"
+ " l.fee_charges_writtenoff_derived as
feeChargesWrittenOff,"
+ " l.fee_charges_outstanding_derived as
feeChargesOutstanding,"
+ " l.penalty_charges_charged_derived as
penaltyChargesCharged,"
@@ -630,15 +630,15 @@ public class LoanReadPlatformServiceImpl implements
LoanReadPlatformService {
+ " l.penalty_charges_waived_derived as
penaltyChargesWaived,"
+ " l.penalty_charges_writtenoff_derived as
penaltyChargesWrittenOff,"
+ " l.penalty_charges_outstanding_derived as
penaltyChargesOutstanding,"
- + " l.total_expected_repayment_derived as
totalExpectedRepayment," + " l.total_repayment_derived as totalRepayment,"
- + " l.total_expected_costofloan_derived as
totalExpectedCostOfLoan," + " l.total_costofloan_derived as totalCostOfLoan,"
- + " l.total_waived_derived as totalWaived," + "
l.total_writtenoff_derived as totalWrittenOff,"
- + " l.writeoff_reason_cv_id as writeoffReasonId," + "
codev.code_value as writeoffReason,"
- + " l.total_outstanding_derived as totalOutstanding," + "
l.total_overpaid_derived as totalOverpaid,"
- + " l.fixed_emi_amount as fixedEmiAmount," + "
l.max_outstanding_loan_balance as outstandingLoanBalance,"
- + " l.loan_sub_status_id as loanSubStatusId," + "
la.principal_overdue_derived as principalOverdue,"
- + " la.interest_overdue_derived as interestOverdue," + "
la.fee_charges_overdue_derived as feeChargesOverdue,"
- + " la.penalty_charges_overdue_derived as
penaltyChargesOverdue," + " la.total_overdue_derived as totalOverdue,"
+ + " l.total_expected_repayment_derived as
totalExpectedRepayment, l.total_repayment_derived as totalRepayment,"
+ + " l.total_expected_costofloan_derived as
totalExpectedCostOfLoan, l.total_costofloan_derived as totalCostOfLoan,"
+ + " l.total_waived_derived as totalWaived,
l.total_writtenoff_derived as totalWrittenOff,"
+ + " l.writeoff_reason_cv_id as writeoffReasonId,
codev.code_value as writeoffReason,"
+ + " l.total_outstanding_derived as totalOutstanding,
l.total_overpaid_derived as totalOverpaid,"
+ + " l.fixed_emi_amount as fixedEmiAmount,
l.max_outstanding_loan_balance as outstandingLoanBalance,"
+ + " l.loan_sub_status_id as loanSubStatusId,
la.principal_overdue_derived as principalOverdue,"
+ + " la.interest_overdue_derived as interestOverdue,
la.fee_charges_overdue_derived as feeChargesOverdue,"
+ + " la.penalty_charges_overdue_derived as
penaltyChargesOverdue, la.total_overdue_derived as totalOverdue,"
+ " la.overdue_since_date_derived as overdueSinceDate,"
+ " l.sync_disbursement_with_meeting as
syncDisbursementWithMeeting,"
+ " l.loan_counter as loanCounter, l.loan_product_counter
as loanProductCounter,"
@@ -659,21 +659,21 @@ public class LoanReadPlatformServiceImpl implements
LoanReadPlatformService {
+ " l.interest_rate_differential as
interestRateDifferential, "
+ " l.create_standing_instruction_at_disbursement as
createStandingInstructionAtDisbursement, "
+ " lpvi.minimum_gap as minimuminstallmentgap,
lpvi.maximum_gap as maximuminstallmentgap, "
- + " lp.can_use_for_topup as canUseForTopup, " + "
l.is_topup as isTopup, " + " topup.closure_loan_id as closureLoanId, "
- + " l.total_recovered_derived as totalRecovered" + ",
topuploan.account_no as closureLoanAccountNo, "
- + " topup.topup_amount as topupAmount " + " from m_loan l"
//
+ + " lp.can_use_for_topup as canUseForTopup, l.is_topup as
isTopup, topup.closure_loan_id as closureLoanId, "
+ + " l.total_recovered_derived as totalRecovered,
topuploan.account_no as closureLoanAccountNo, "
+ + " topup.topup_amount as topupAmount from m_loan l" //
+ " join m_product_loan lp on lp.id = l.product_id" //
- + " left join m_loan_recalculation_details lir on
lir.loan_id = l.id " + " join m_currency rc on rc."
+ + " left join m_loan_recalculation_details lir on
lir.loan_id = l.id join m_currency rc on rc."
+ sqlGenerator.escape("code") + " = l.currency_code" //
+ " left join m_client c on c.id = l.client_id" //
+ " left join m_group g on g.id = l.group_id" //
+ " left join m_loan_arrears_aging la on la.loan_id =
l.id" //
+ " left join m_fund f on f.id = l.fund_id" //
+ " left join m_staff s on s.id = l.loan_officer_id" //
- + " left join m_appuser sbu on sbu.id = l.created_by" + "
left join m_appuser rbu on rbu.id = l.rejectedon_userid"
+ + " left join m_appuser sbu on sbu.id = l.created_by left
join m_appuser rbu on rbu.id = l.rejectedon_userid"
+ " left join m_appuser wbu on wbu.id =
l.withdrawnon_userid"
+ " left join m_appuser abu on abu.id =
l.approvedon_userid"
- + " left join m_appuser dbu on dbu.id =
l.disbursedon_userid" + " left join m_appuser cbu on cbu.id = l.closedon_userid"
+ + " left join m_appuser dbu on dbu.id =
l.disbursedon_userid left join m_appuser cbu on cbu.id = l.closedon_userid"
+ " left join m_code_value cv on cv.id =
l.loanpurpose_cv_id"
+ " left join m_code_value codev on codev.id =
l.writeoff_reason_cv_id"
+ " left join ref_loan_transaction_processing_strategy lps
on lps.id = l.loan_transaction_strategy_id"
@@ -851,6 +851,7 @@ public class LoanReadPlatformServiceImpl implements
LoanReadPlatformService {
// loan summary
final BigDecimal principalDisbursed =
JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "principalDisbursed");
+ final BigDecimal principalAdjustments =
JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "principalAdjustments");
final BigDecimal principalPaid =
JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "principalPaid");
final BigDecimal principalWrittenOff =
JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "principalWrittenOff");
final BigDecimal principalOutstanding =
JdbcSupport.getBigDecimalDefaultToZeroIfNull(rs, "principalOutstanding");
@@ -892,14 +893,14 @@ public class LoanReadPlatformServiceImpl implements
LoanReadPlatformService {
inArrears = true;
}
- loanSummary = new LoanSummaryData(currencyData,
principalDisbursed, principalPaid, principalWrittenOff,
- principalOutstanding, principalOverdue,
interestCharged, interestPaid, interestWaived, interestWrittenOff,
- interestOutstanding, interestOverdue,
feeChargesCharged, feeChargesDueAtDisbursementCharged, feeChargesPaid,
- feeChargesWaived, feeChargesWrittenOff,
feeChargesOutstanding, feeChargesOverdue, penaltyChargesCharged,
- penaltyChargesPaid, penaltyChargesWaived,
penaltyChargesWrittenOff, penaltyChargesOutstanding,
- penaltyChargesOverdue, totalExpectedRepayment,
totalRepayment, totalExpectedCostOfLoan, totalCostOfLoan,
- totalWaived, totalWrittenOff, totalOutstanding,
totalOverdue, overdueSinceDate, writeoffReasonId, writeoffReason,
- totalRecovered);
+ loanSummary = new LoanSummaryData(currencyData,
principalDisbursed, principalAdjustments, principalPaid,
+ principalWrittenOff, principalOutstanding,
principalOverdue, interestCharged, interestPaid, interestWaived,
+ interestWrittenOff, interestOutstanding,
interestOverdue, feeChargesCharged, feeChargesDueAtDisbursementCharged,
+ feeChargesPaid, feeChargesWaived,
feeChargesWrittenOff, feeChargesOutstanding, feeChargesOverdue,
+ penaltyChargesCharged, penaltyChargesPaid,
penaltyChargesWaived, penaltyChargesWrittenOff,
+ penaltyChargesOutstanding, penaltyChargesOverdue,
totalExpectedRepayment, totalRepayment, totalExpectedCostOfLoan,
+ totalCostOfLoan, totalWaived, totalWrittenOff,
totalOutstanding, totalOverdue, overdueSinceDate, writeoffReasonId,
+ writeoffReason, totalRecovered);
}
GroupGeneralData groupData = null;
@@ -1015,8 +1016,7 @@ public class LoanReadPlatformServiceImpl implements
LoanReadPlatformService {
+ " ls.fee_charges_amount as feeChargesDue,
ls.fee_charges_completed_derived as feeChargesPaid,
ls.fee_charges_waived_derived as feeChargesWaived,
ls.fee_charges_writtenoff_derived as feeChargesWrittenOff, "
+ " ls.penalty_charges_amount as penaltyChargesDue,
ls.penalty_charges_completed_derived as penaltyChargesPaid,
ls.penalty_charges_waived_derived as penaltyChargesWaived,
ls.penalty_charges_writtenoff_derived as penaltyChargesWrittenOff, "
+ " ls.total_paid_in_advance_derived as
totalPaidInAdvanceForPeriod, ls.total_paid_late_derived as
totalPaidLateForPeriod, "
- + " mc.amount,mc.id as chargeId " + " from
m_loan_repayment_schedule ls "
- + " inner join m_loan ml on ml.id = ls.loan_id "
+ + " mc.amount,mc.id as chargeId from
m_loan_repayment_schedule ls " + " inner join m_loan ml on ml.id = ls.loan_id "
+ " join m_product_loan_charge plc on plc.product_loan_id
= ml.product_id "
+ " join m_charge mc on mc.id = plc.charge_id ";
@@ -1326,7 +1326,7 @@ public class LoanReadPlatformServiceImpl implements
LoanReadPlatformService {
+ " totran.description as toTransferDescription from
m_loan l join m_loan_transaction tr on tr.loan_id = l.id "
+ " join m_currency rc on rc." +
sqlGenerator.escape("code") + " = l.currency_code "
+ " left JOIN m_payment_detail pd ON tr.payment_detail_id
= pd.id"
- + " left join m_payment_type pt on pd.payment_type_id =
pt.id" + " left join m_office office on office.id=tr.office_id"
+ + " left join m_payment_type pt on pd.payment_type_id =
pt.id left join m_office office on office.id=tr.office_id"
+ " left join m_account_transfer_transaction fromtran on
fromtran.from_loan_transaction_id = tr.id "
+ " left join m_account_transfer_transaction totran on
totran.to_loan_transaction_id = tr.id ";
}
@@ -2067,7 +2067,7 @@ public class LoanReadPlatformServiceImpl implements
LoanReadPlatformService {
+ ", tr.amount as total, tr.principal_portion_derived as
principal, tr.interest_portion_derived as interest, "
+ " tr.fee_charges_portion_derived as fees,
tr.penalty_charges_portion_derived as penalties, "
+ " tr.overpayment_portion_derived as overpayment,
tr.outstanding_loan_balance_derived as outstandingLoanBalance, "
- + " tr.unrecognized_income_portion as unrecognizedIncome "
+ " from m_loan_transaction tr ";
+ + " tr.unrecognized_income_portion as unrecognizedIncome
from m_loan_transaction tr ";
}
@Override
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/loanaccount/api/SelfLoansApiResourceSwagger.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/loanaccount/api/SelfLoansApiResourceSwagger.java
index 36c943c19..40fe21e89 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/loanaccount/api/SelfLoansApiResourceSwagger.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/self/loanaccount/api/SelfLoansApiResourceSwagger.java
@@ -357,6 +357,8 @@ final class SelfLoansApiResourceSwagger {
public Double principalDisbursed;
@Schema(example = "0.000000")
public Double principalPaid;
+ @Schema(example = "0.00")
+ public Double principalAdjustments;
@Schema(example = "0.000000")
public Double principalWrittenOff;
@Schema(example = "1000000.000000")
diff --git
a/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml
b/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml
index 118402238..d4d072406 100644
---
a/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml
+++
b/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml
@@ -76,4 +76,5 @@
<include file="parts/0054_additional_fields_loan_repayment_schedule.xml"
relativeToChangelogFile="true"/>
<include file="parts/0055_add_submitted_on_date_to_loan_charge.xml"
relativeToChangelogFile="true"/>
<include file="parts/0056_add_external_event_default_configuration.xml"
relativeToChangelogFile="true"/>
+ <include file="parts/0057_add_principal_adjustments_to_loan.xml"
relativeToChangelogFile="true"/>
</databaseChangeLog>
diff --git
a/fineract-provider/src/main/resources/db/changelog/tenant/parts/0057_add_principal_adjustments_to_loan.xml
b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0057_add_principal_adjustments_to_loan.xml
new file mode 100644
index 000000000..63ae38916
--- /dev/null
+++
b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0057_add_principal_adjustments_to_loan.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+
+-->
+<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
+ <changeSet author="fineract" id="1">
+ <addColumn tableName="m_loan">
+ <column name="principal_adjustments_derived" type="DECIMAL(19, 6)"
defaultValueNumeric="0.000000">
+ <constraints nullable="false"/>
+ </column>
+ </addColumn>
+ </changeSet>
+</databaseChangeLog>
diff --git
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionChargebackTest.java
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionChargebackTest.java
index aa031f3a1..ba4dc1cb3 100644
---
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionChargebackTest.java
+++
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionChargebackTest.java
@@ -37,6 +37,7 @@ import
org.apache.fineract.client.models.GetLoanProductsProductIdResponse;
import org.apache.fineract.client.models.GetLoansLoanIdRepaymentPeriod;
import org.apache.fineract.client.models.GetLoansLoanIdRepaymentSchedule;
import org.apache.fineract.client.models.GetLoansLoanIdResponse;
+import org.apache.fineract.client.models.GetLoansLoanIdSummary;
import org.apache.fineract.client.models.GetLoansLoanIdTransactions;
import
org.apache.fineract.client.models.GetLoansLoanIdTransactionsTransactionIdResponse;
import org.apache.fineract.client.models.GetPaymentTypesResponse;
@@ -128,7 +129,8 @@ public class LoanTransactionChargebackTest {
loanTransactionHelper.printRepaymentSchedule(getLoansLoanIdResponse);
- Float amount = Float.valueOf("333.33");
+ final String baseAmount = "333.33";
+ Float amount = Float.valueOf(baseAmount);
final LocalDate transactionDate =
this.todaysDate.minusMonths(numberOfRepayments - 1).plusDays(3);
String operationDate = Utils.dateFormatter.format(transactionDate);
@@ -155,6 +157,8 @@ public class LoanTransactionChargebackTest {
assertEquals(Double.valueOf("666.67"),
period.getTotalDueForPeriod());
}
}
+
+ evaluateLoanSummaryAdjustments(getLoansLoanIdResponse,
Double.valueOf(baseAmount));
}
@Test
@@ -377,6 +381,8 @@ public class LoanTransactionChargebackTest {
getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec,
responseSpec, loanId);
loanTransactionHelper.validateLoanPrincipalOustandingBalance(getLoansLoanIdResponse,
Double.valueOf("200.00"));
+ evaluateLoanSummaryAdjustments(getLoansLoanIdResponse,
Double.valueOf("200.00"));
+
// Second round, array size equal to 1
reviewLoanTransactionRelations(loanId, transactionId, 1);
@@ -385,6 +391,8 @@ public class LoanTransactionChargebackTest {
getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec,
responseSpec, loanId);
loanTransactionHelper.validateLoanPrincipalOustandingBalance(getLoansLoanIdResponse,
Double.valueOf("500.00"));
+ evaluateLoanSummaryAdjustments(getLoansLoanIdResponse,
Double.valueOf("500.00"));
+
// Third round, array size equal to 2
reviewLoanTransactionRelations(loanId, transactionId, 2);
@@ -392,6 +400,8 @@ public class LoanTransactionChargebackTest {
getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec,
responseSpec, loanId);
loanTransactionHelper.validateLoanPrincipalOustandingBalance(getLoansLoanIdResponse,
Double.valueOf("1000.00"));
+
+ evaluateLoanSummaryAdjustments(getLoansLoanIdResponse,
Double.valueOf("1000.00"));
}
private Integer createAccounts(final Integer daysToSubtract, final Integer
numberOfRepayments) {
@@ -464,4 +474,13 @@ public class LoanTransactionChargebackTest {
log.info("Loan with {} Chargeback Transactions",
getLoansTransactionResponse.getTransactionRelations().size());
}
+ private void evaluateLoanSummaryAdjustments(GetLoansLoanIdResponse
getLoansLoanIdResponse, Double amountExpected) {
+ // Evaluate The Loan Summary Principal Adjustments
+ GetLoansLoanIdSummary getLoansLoanIdSummary =
getLoansLoanIdResponse.getSummary();
+ if (getLoansLoanIdSummary != null) {
+ log.info("Loan with Principal Adjustments {} expected {}",
getLoansLoanIdSummary.getPrincipalAdjustments(), amountExpected);
+ assertEquals(amountExpected,
getLoansLoanIdSummary.getPrincipalAdjustments());
+ }
+ }
+
}