This is an automated email from the ASF dual-hosted git repository.
bagrijp 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 697449e7e FINERACT-2042 Chargeback with credit allocation, accounting
697449e7e is described below
commit 697449e7e742a9fac350890ff201741bb8bcd93c
Author: Peter Bagrij <[email protected]>
AuthorDate: Fri Mar 1 19:12:27 2024 +0100
FINERACT-2042 Chargeback with credit allocation, accounting
---
.../loanaccount/domain/LoanTransaction.java | 30 +-
.../journalentry/data/LoanTransactionDTO.java | 5 +
.../service/AccountingProcessorHelper.java | 8 +-
.../AccrualBasedAccountingProcessorForLoan.java | 59 ++-
...PaymentAllocationLoanRepaymentScheduleTest.java | 12 +-
.../integrationtests/BaseLoanIntegrationTest.java | 97 +++--
...ebackWithCreditAllocationsIntegrationTests.java | 463 ++++++++++++++++++++-
.../LoanDownPaymentTransactionChargebackTest.java | 27 +-
.../LoanRepaymentScheduleWithDownPaymentTest.java | 14 +-
.../LoanRescheduleTestWithDownpayment.java | 4 +-
.../LoanTransactionChargebackTest.java | 63 ++-
...oanDisbursalWithDownPaymentIntegrationTest.java | 344 +++++++--------
.../common/accounting/AccountHelper.java | 38 +-
.../common/accounting/GLAccountBuilder.java | 8 +
.../common/loans/LoanProductTestBuilder.java | 96 ++++-
15 files changed, 960 insertions(+), 308 deletions(-)
diff --git
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransaction.java
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransaction.java
index 960ef6138..1b737fe28 100644
---
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransaction.java
+++
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransaction.java
@@ -35,6 +35,7 @@ import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.Set;
import
org.apache.fineract.infrastructure.core.domain.AbstractAuditableWithUTCDateTimeCustom;
import org.apache.fineract.infrastructure.core.domain.ExternalId;
@@ -763,7 +764,14 @@ public class LoanTransaction extends
AbstractAuditableWithUTCDateTimeCustom {
thisTransactionData.put("currencyCode", currencyCode);
thisTransactionData.put("amount", this.amount);
thisTransactionData.put("netDisbursalAmount",
this.loan.getNetDisbursalAmount());
- thisTransactionData.put("principalPortion", this.principalPortion);
+
+ if (transactionType.isChargeback()
+ && (getLoan().getCreditAllocationRules() == null ||
getLoan().getCreditAllocationRules().size() == 0)) {
+ thisTransactionData.put("principalPortion", this.amount);
+ } else {
+ thisTransactionData.put("principalPortion", this.principalPortion);
+ }
+
thisTransactionData.put("interestPortion", this.interestPortion);
thisTransactionData.put("feeChargesPortion", this.feeChargesPortion);
thisTransactionData.put("penaltyChargesPortion",
this.penaltyChargesPortion);
@@ -790,6 +798,26 @@ public class LoanTransaction extends
AbstractAuditableWithUTCDateTimeCustom {
thisTransactionData.put("loanChargesPaid", loanChargesPaidData);
}
+ if (transactionType.isChargeback() && this.overPaymentPortion != null
&& this.overPaymentPortion.compareTo(BigDecimal.ZERO) > 0) {
+ BigDecimal principalPaid = overPaymentPortion;
+ BigDecimal feePaid = BigDecimal.ZERO;
+ BigDecimal penaltyPaid = BigDecimal.ZERO;
+ if (getLoanTransactionToRepaymentScheduleMappings().size() > 0) {
+ principalPaid =
getLoanTransactionToRepaymentScheduleMappings().stream()
+ .map(mapping ->
Optional.ofNullable(mapping.getPrincipalPortion()).orElse(BigDecimal.ZERO))
+ .reduce(BigDecimal.ZERO, BigDecimal::add);
+ feePaid =
getLoanTransactionToRepaymentScheduleMappings().stream()
+ .map(mapping ->
Optional.ofNullable(mapping.getFeeChargesPortion()).orElse(BigDecimal.ZERO))
+ .reduce(BigDecimal.ZERO, BigDecimal::add);
+ penaltyPaid =
getLoanTransactionToRepaymentScheduleMappings().stream()
+ .map(mapping ->
Optional.ofNullable(mapping.getPenaltyChargesPortion()).orElse(BigDecimal.ZERO))
+ .reduce(BigDecimal.ZERO, BigDecimal::add);
+ }
+ thisTransactionData.put("principalPaid", principalPaid);
+ thisTransactionData.put("feePaid", feePaid);
+ thisTransactionData.put("penaltyPaid", penaltyPaid);
+ }
+
LoanTransactionRelation loanTransactionRelation =
loanTransactionRelations.stream()
.filter(e ->
LoanTransactionRelationTypeEnum.CHARGE_ADJUSTMENT.equals(e.getRelationType())).findAny().orElse(null);
if (loanTransactionRelation != null) {
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/data/LoanTransactionDTO.java
b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/data/LoanTransactionDTO.java
index bd9ebf290..07defb666 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/data/LoanTransactionDTO.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/data/LoanTransactionDTO.java
@@ -60,4 +60,9 @@ public class LoanTransactionDTO {
private final String chargeRefundChargeType;
private final LoanChargeData loanChargeData;
+
+ /** In case chargeback and overpayment the below field contains the
distribution payment **/
+ private final BigDecimal principalPaid;
+ private final BigDecimal feePaid;
+ private final BigDecimal penaltyPaid;
}
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccountingProcessorHelper.java
b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccountingProcessorHelper.java
index 804184c3e..d3ca6da09 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccountingProcessorHelper.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccountingProcessorHelper.java
@@ -156,9 +156,15 @@ public class AccountingProcessorHelper {
isAccountTransfer =
this.accountTransfersReadPlatformService.isAccountTransfer(Long.parseLong(transactionId),
PortfolioAccountType.LOAN);
}
+
+ BigDecimal principalPaid = (BigDecimal) map.get("principalPaid");
+ BigDecimal feePaid = (BigDecimal) map.get("feePaid");
+ BigDecimal penaltyPaid = (BigDecimal) map.get("penaltyPaid");
+
final LoanTransactionDTO transaction = new
LoanTransactionDTO(transactionOfficeId, paymentTypeId, transactionId,
transactionDate, transactionType, amount, principal,
interest, fees, penalties, overPayments, reversed,
- penaltyPaymentDetails, feePaymentDetails,
isAccountTransfer, chargeRefundChargeType, loanChargeData);
+ penaltyPaymentDetails, feePaymentDetails,
isAccountTransfer, chargeRefundChargeType, loanChargeData, principalPaid,
+ feePaid, penaltyPaid);
Boolean isLoanToLoanTransfer = (Boolean)
accountingBridgeData.get("isLoanToLoanTransfer");
transaction.setLoanToLoanTransfer(isLoanToLoanTransfer != null &&
isLoanToLoanTransfer);
newLoanTransactions.add(transaction);
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccrualBasedAccountingProcessorForLoan.java
b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccrualBasedAccountingProcessorForLoan.java
index f0ed03edb..d92657b7b 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccrualBasedAccountingProcessorForLoan.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccrualBasedAccountingProcessorForLoan.java
@@ -430,25 +430,54 @@ public class AccrualBasedAccountingProcessorForLoan
implements AccountingProcess
final BigDecimal overpaidAmount =
Objects.isNull(loanTransactionDTO.getOverPayment()) ? BigDecimal.ZERO
: loanTransactionDTO.getOverPayment();
- if (BigDecimal.ZERO.compareTo(overpaidAmount) == 0) { // when no
overpay
- helper.createJournalEntriesAndReversalsForLoan(office,
currencyCode, AccrualAccountsForLoan.LOAN_PORTFOLIO.getValue(),
- AccrualAccountsForLoan.FUND_SOURCE.getValue(),
loanProductId, paymentTypeId, loanId, transactionId, transactionDate,
- amount, isReversal);
- } else if (overpaidAmount.compareTo(amount) >= 0) { // when the
overpay amount is matching with the normal
- // amount
- helper.createJournalEntriesAndReversalsForLoan(office,
currencyCode, AccrualAccountsForLoan.OVERPAYMENT.getValue(),
- AccrualAccountsForLoan.FUND_SOURCE.getValue(),
loanProductId, paymentTypeId, loanId, transactionId, transactionDate,
- amount, isReversal);
- } else {
- BigDecimal diff = amount.subtract(overpaidAmount);
- helper.createDebitJournalEntryOrReversalForLoan(office,
currencyCode, AccrualAccountsForLoan.LOAN_PORTFOLIO.getValue(),
- loanProductId, paymentTypeId, loanId, transactionId,
transactionDate, diff, isReversal);
- helper.createCreditJournalEntryOrReversalForLoan(office,
currencyCode, AccrualAccountsForLoan.FUND_SOURCE, loanProductId,
- paymentTypeId, loanId, transactionId, transactionDate,
amount, isReversal);
+ final BigDecimal principalCredited =
Objects.isNull(loanTransactionDTO.getPrincipal()) ? BigDecimal.ZERO
+ : loanTransactionDTO.getPrincipal();
+ final BigDecimal feeCredited =
Objects.isNull(loanTransactionDTO.getFees()) ? BigDecimal.ZERO :
loanTransactionDTO.getFees();
+ final BigDecimal penaltyCredited =
Objects.isNull(loanTransactionDTO.getPenalties()) ? BigDecimal.ZERO
+ : loanTransactionDTO.getPenalties();
+
+ final BigDecimal principalPaid =
Objects.isNull(loanTransactionDTO.getPrincipalPaid()) ? BigDecimal.ZERO
+ : loanTransactionDTO.getPrincipalPaid();
+ final BigDecimal feePaid =
Objects.isNull(loanTransactionDTO.getFeePaid()) ? BigDecimal.ZERO :
loanTransactionDTO.getFeePaid();
+ final BigDecimal penaltyPaid =
Objects.isNull(loanTransactionDTO.getPenaltyPaid()) ? BigDecimal.ZERO
+ : loanTransactionDTO.getPenaltyPaid();
+
+ helper.createCreditJournalEntryOrReversalForLoan(office, currencyCode,
AccrualAccountsForLoan.FUND_SOURCE, loanProductId,
+ paymentTypeId, loanId, transactionId, transactionDate, amount,
isReversal);
+
+ if (overpaidAmount.compareTo(BigDecimal.ZERO) > 0) {
helper.createDebitJournalEntryOrReversalForLoan(office,
currencyCode, AccrualAccountsForLoan.OVERPAYMENT.getValue(),
loanProductId, paymentTypeId, loanId, transactionId,
transactionDate, overpaidAmount, isReversal);
}
+ if (principalCredited.compareTo(principalPaid) > 0) {
+ helper.createDebitJournalEntryOrReversalForLoan(office,
currencyCode, AccrualAccountsForLoan.LOAN_PORTFOLIO.getValue(),
+ loanProductId, paymentTypeId, loanId, transactionId,
transactionDate, principalCredited.subtract(principalPaid),
+ isReversal);
+ } else if (principalCredited.compareTo(principalPaid) < 0) {
+ helper.createCreditJournalEntryOrReversalForLoan(office,
currencyCode, AccrualAccountsForLoan.LOAN_PORTFOLIO.getValue(),
+ loanProductId, paymentTypeId, loanId, transactionId,
transactionDate, principalPaid.subtract(principalCredited),
+ isReversal);
+ }
+
+ if (feeCredited.compareTo(feePaid) > 0) {
+ helper.createDebitJournalEntryOrReversalForLoan(office,
currencyCode, AccrualAccountsForLoan.FEES_RECEIVABLE.getValue(),
+ loanProductId, paymentTypeId, loanId, transactionId,
transactionDate, feeCredited.subtract(feePaid), isReversal);
+ } else if (feeCredited.compareTo(feePaid) < 0) {
+ helper.createCreditJournalEntryOrReversalForLoan(office,
currencyCode, AccrualAccountsForLoan.FEES_RECEIVABLE.getValue(),
+ loanProductId, paymentTypeId, loanId, transactionId,
transactionDate, feePaid.subtract(feeCredited), isReversal);
+ }
+
+ if (penaltyCredited.compareTo(penaltyPaid) > 0) {
+ helper.createDebitJournalEntryOrReversalForLoan(office,
currencyCode, AccrualAccountsForLoan.PENALTIES_RECEIVABLE.getValue(),
+ loanProductId, paymentTypeId, loanId, transactionId,
transactionDate, penaltyCredited.subtract(penaltyPaid),
+ isReversal);
+ } else if (penaltyCredited.compareTo(penaltyPaid) < 0) {
+ helper.createCreditJournalEntryOrReversalForLoan(office,
currencyCode, AccrualAccountsForLoan.PENALTIES_RECEIVABLE.getValue(),
+ loanProductId, paymentTypeId, loanId, transactionId,
transactionDate, penaltyPaid.subtract(penaltyCredited),
+ isReversal);
+ }
+
}
/**
diff --git
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/AdvancedPaymentAllocationLoanRepaymentScheduleTest.java
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/AdvancedPaymentAllocationLoanRepaymentScheduleTest.java
index d6cb8f4f5..aa1bd5e42 100644
---
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/AdvancedPaymentAllocationLoanRepaymentScheduleTest.java
+++
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/AdvancedPaymentAllocationLoanRepaymentScheduleTest.java
@@ -3194,13 +3194,13 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
);
// verify journal entries
verifyJournalEntries(loanResponse.getLoanId(), journalEntry(100.0,
loansReceivableAccount, "DEBIT"), //
- journalEntry(100.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(100.0, fundSource, "CREDIT"), //
journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
journalEntry(50.0, overpaymentAccount, "CREDIT"), //
- journalEntry(150.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(150.0, fundSource, "DEBIT"), //
journalEntry(50.0, loansReceivableAccount, "DEBIT"), //
journalEntry(50.0, overpaymentAccount, "DEBIT"), //
- journalEntry(100.0, suspenseClearingAccount, "CREDIT") //
+ journalEntry(100.0, fundSource, "CREDIT") //
);
});
}
@@ -3273,12 +3273,12 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
);
// verify journal entries
verifyJournalEntries(loanResponse.getLoanId(), journalEntry(100.0,
loansReceivableAccount, "DEBIT"), //
- journalEntry(100.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(100.0, fundSource, "CREDIT"), //
journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
journalEntry(50.0, overpaymentAccount, "CREDIT"), //
- journalEntry(150.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(150.0, fundSource, "DEBIT"), //
journalEntry(28.0, overpaymentAccount, "DEBIT"), //
- journalEntry(28.0, suspenseClearingAccount, "CREDIT") //
+ journalEntry(28.0, fundSource, "CREDIT") //
);
});
}
diff --git
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/BaseLoanIntegrationTest.java
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/BaseLoanIntegrationTest.java
index fc4aaf202..bcd50f555 100644
---
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/BaseLoanIntegrationTest.java
+++
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/BaseLoanIntegrationTest.java
@@ -72,6 +72,7 @@ import
org.apache.fineract.integrationtests.common.BatchHelper;
import org.apache.fineract.integrationtests.common.BusinessDateHelper;
import org.apache.fineract.integrationtests.common.ClientHelper;
import org.apache.fineract.integrationtests.common.GlobalConfigurationHelper;
+import org.apache.fineract.integrationtests.common.SchedulerJobHelper;
import org.apache.fineract.integrationtests.common.Utils;
import org.apache.fineract.integrationtests.common.accounting.Account;
import org.apache.fineract.integrationtests.common.accounting.AccountHelper;
@@ -114,6 +115,7 @@ public abstract class BaseLoanIntegrationTest {
protected final LoanProductHelper loanProductHelper = new
LoanProductHelper();
protected JournalEntryHelper journalEntryHelper = new
JournalEntryHelper(requestSpec, responseSpec);
protected ClientHelper clientHelper = new ClientHelper(requestSpec,
responseSpec);
+ protected SchedulerJobHelper schedulerJobHelper = new
SchedulerJobHelper(requestSpec);
protected final InlineLoanCOBHelper inlineLoanCOBHelper = new
InlineLoanCOBHelper(requestSpec, responseSpec);
protected BusinessDateHelper businessDateHelper = new BusinessDateHelper();
@@ -123,18 +125,22 @@ public abstract class BaseLoanIntegrationTest {
protected DateTimeFormatter dateTimeFormatter =
DateTimeFormatter.ofPattern(DATETIME_PATTERN);
// asset
- protected final Account loansReceivableAccount =
accountHelper.createAssetAccount();
- protected final Account interestFeeReceivableAccount =
accountHelper.createAssetAccount();
- protected final Account suspenseAccount =
accountHelper.createAssetAccount();
+ protected final Account loansReceivableAccount =
accountHelper.createAssetAccount("loanPortfolio");
+
+ protected final Account interestReceivableAccount =
accountHelper.createAssetAccount("interestReceivable");
+ protected final Account feeReceivableAccount =
accountHelper.createAssetAccount("feeReceivable");
+ protected final Account penaltyReceivableAccount =
accountHelper.createAssetAccount("penaltyReceivable");
+ protected final Account suspenseAccount =
accountHelper.createAssetAccount("suspense");
// liability
- protected final Account suspenseClearingAccount =
accountHelper.createLiabilityAccount();
- protected final Account overpaymentAccount =
accountHelper.createLiabilityAccount();
+ protected final Account fundSource =
accountHelper.createLiabilityAccount("fundSource");
+ protected final Account overpaymentAccount =
accountHelper.createLiabilityAccount("overpayment");
// income
- protected final Account interestIncomeAccount =
accountHelper.createIncomeAccount();
- protected final Account feeIncomeAccount =
accountHelper.createIncomeAccount();
- protected final Account feeChargeOffAccount =
accountHelper.createIncomeAccount();
- protected final Account recoveriesAccount =
accountHelper.createIncomeAccount();
- protected final Account interestIncomeChargeOffAccount =
accountHelper.createIncomeAccount();
+ protected final Account interestIncomeAccount =
accountHelper.createIncomeAccount("interestIncome");
+ protected final Account feeIncomeAccount =
accountHelper.createIncomeAccount("feeIncome");
+ protected final Account penaltyIncomeAccount =
accountHelper.createIncomeAccount("penaltyIncome");
+ protected final Account feeChargeOffAccount =
accountHelper.createIncomeAccount("feeChargeOff");
+ protected final Account recoveriesAccount =
accountHelper.createIncomeAccount("recoveries");
+ protected final Account interestIncomeChargeOffAccount =
accountHelper.createIncomeAccount("interestIncomeChargeOff");
// expense
protected final Account creditLossBadDebtAccount =
accountHelper.createExpenseAccount();
protected final Account creditLossBadDebtFraudAccount =
accountHelper.createExpenseAccount();
@@ -159,6 +165,7 @@ public abstract class BaseLoanIntegrationTest {
.includeInBorrowerCycle(false)//
.currencyCode("USD")//
.digitsAfterDecimal(2)//
+ .inMultiplesOf(0)//
.installmentAmountInMultiplesOf(1)//
.useBorrowerCycle(false)//
.minPrincipal(100.0)//
@@ -207,24 +214,18 @@ public abstract class BaseLoanIntegrationTest {
.outstandingLoanBalance(10000.0)//
.charges(Collections.emptyList())//
.accountingRule(3)//
-
.fundSourceAccountId(suspenseClearingAccount.getAccountID().longValue())//
+ .fundSourceAccountId(fundSource.getAccountID().longValue())//
.loanPortfolioAccountId(loansReceivableAccount.getAccountID().longValue())//
.transfersInSuspenseAccountId(suspenseAccount.getAccountID().longValue())//
.interestOnLoanAccountId(interestIncomeAccount.getAccountID().longValue())//
.incomeFromFeeAccountId(feeIncomeAccount.getAccountID().longValue())//
-
.incomeFromPenaltyAccountId(feeIncomeAccount.getAccountID().longValue())//
+
.incomeFromPenaltyAccountId(penaltyIncomeAccount.getAccountID().longValue())//
.incomeFromRecoveryAccountId(recoveriesAccount.getAccountID().longValue())//
.writeOffAccountId(writtenOffAccount.getAccountID().longValue())//
.overpaymentLiabilityAccountId(overpaymentAccount.getAccountID().longValue())//
-
.receivableInterestAccountId(interestFeeReceivableAccount.getAccountID().longValue())//
-
.receivableFeeAccountId(interestFeeReceivableAccount.getAccountID().longValue())//
-
.receivablePenaltyAccountId(interestFeeReceivableAccount.getAccountID().longValue())//
- .dateFormat(DATETIME_PATTERN)//
- .locale("en_GB")//
- .disallowExpectedDisbursements(true)//
- .allowApprovedDisbursedAmountsOverApplied(true)//
- .overAppliedCalculationType("percentage")//
- .overAppliedNumber(50)//
+
.receivableInterestAccountId(interestReceivableAccount.getAccountID().longValue())//
+
.receivableFeeAccountId(feeReceivableAccount.getAccountID().longValue())//
+
.receivablePenaltyAccountId(penaltyReceivableAccount.getAccountID().longValue())//
.goodwillCreditAccountId(goodwillExpenseAccount.getAccountID().longValue())//
.incomeFromGoodwillCreditInterestAccountId(interestIncomeChargeOffAccount.getAccountID().longValue())//
.incomeFromGoodwillCreditFeesAccountId(feeChargeOffAccount.getAccountID().longValue())//
@@ -233,7 +234,12 @@ public abstract class BaseLoanIntegrationTest {
.incomeFromChargeOffFeesAccountId(feeChargeOffAccount.getAccountID().longValue())//
.chargeOffExpenseAccountId(creditLossBadDebtAccount.getAccountID().longValue())//
.chargeOffFraudExpenseAccountId(creditLossBadDebtFraudAccount.getAccountID().longValue())//
-
.incomeFromChargeOffPenaltyAccountId(feeChargeOffAccount.getAccountID().longValue());
+
.incomeFromChargeOffPenaltyAccountId(feeChargeOffAccount.getAccountID().longValue()).dateFormat(DATETIME_PATTERN)//
+ .locale("en_GB")//
+ .disallowExpectedDisbursements(true)//
+ .allowApprovedDisbursedAmountsOverApplied(true)//
+ .overAppliedCalculationType("percentage")//
+ .overAppliedNumber(50);
}
protected PostLoanProductsRequest
createOnePeriod30DaysLongNoInterestPeriodicAccrualProductWithAdvancedPaymentAllocation()
{
@@ -344,7 +350,7 @@ public abstract class BaseLoanIntegrationTest {
boolean found =
loanDetails.getTransactions().stream().anyMatch(item ->
Objects.equals(item.getAmount(), tr.amount) //
&& Objects.equals(item.getType().getValue(), tr.type)
//
&& Objects.equals(item.getDate(),
LocalDate.parse(tr.date, dateTimeFormatter)) //
- && Objects.equals(item.getOutstandingLoanBalance(),
tr.outstandingAmount) //
+ && Objects.equals(item.getOutstandingLoanBalance(),
tr.outstandingPrincipal) //
&& Objects.equals(item.getPrincipalPortion(),
tr.principalPortion) //
&& Objects.equals(item.getInterestPortion(),
tr.interestPortion) //
&& Objects.equals(item.getFeeChargesPortion(),
tr.feePortion) //
@@ -416,6 +422,18 @@ public abstract class BaseLoanIntegrationTest {
});
}
+ protected void verifyTRJournalEntries(Long transactionId, Journal...
entries) {
+ GetJournalEntriesTransactionIdResponse journalEntriesForLoan =
journalEntryHelper.getJournalEntries("L" + transactionId.toString());
+ Assertions.assertEquals(entries.length,
journalEntriesForLoan.getPageItems().size());
+ Arrays.stream(entries).forEach(journalEntry -> {
+ boolean found = journalEntriesForLoan.getPageItems().stream()
+ .anyMatch(item -> Objects.equals(item.getAmount(),
journalEntry.amount)
+ && Objects.equals(item.getGlAccountId(),
journalEntry.account.getAccountID().longValue())
+ &&
Objects.requireNonNull(item.getEntryType()).getValue().equals(journalEntry.type));
+ Assertions.assertTrue(found, "Required journal entry not found: "
+ journalEntry);
+ });
+ }
+
protected Long addCharge(Long loanId, boolean isPenalty, double amount,
String dueDate) {
Integer chargeId = ChargesHelper.createCharges(requestSpec,
responseSpec,
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT,
String.valueOf(amount), isPenalty));
@@ -602,9 +620,10 @@ public abstract class BaseLoanIntegrationTest {
return response.getResourceId();
}
- protected void addChargebackForLoan(Long loanId, Long transactionId,
Double amount) {
- loanTransactionHelper.chargebackLoanTransaction(loanId, transactionId,
+ protected Long addChargebackForLoan(Long loanId, Long transactionId,
Double amount) {
+ PostLoansLoanIdTransactionsResponse response =
loanTransactionHelper.chargebackLoanTransaction(loanId, transactionId,
new
PostLoansLoanIdTransactionsTransactionIdRequest().locale("en").transactionAmount(amount).paymentTypeId(1L));
+ return response.getResourceId();
}
protected PostChargesResponse createCharge(Double amount) {
@@ -627,8 +646,22 @@ public abstract class BaseLoanIntegrationTest {
new
BusinessDateRequest().type(BUSINESS_DATE.getName()).date(date).dateFormat(DATETIME_PATTERN).locale("en"));
}
- protected Journal journalEntry(double principalAmount, Account account,
String type) {
- return new Journal(principalAmount, account, type);
+ protected Long getTransactionId(Long loanId, String type, String date) {
+ GetLoansLoanIdResponse loan =
loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId.intValue());
+ return loan.getTransactions().stream().filter(tr ->
Objects.equals(tr.getType().getValue(), type)
+ && Objects.equals(tr.getDate(), LocalDate.parse(date,
dateTimeFormatter))).findAny().orElseThrow().getId();
+ }
+
+ protected Journal journalEntry(double amount, Account account, String
type) {
+ return new Journal(amount, account, type);
+ }
+
+ protected Journal debit(Account account, double amount) {
+ return new Journal(amount, account, "DEBIT");
+ }
+
+ protected Journal credit(Account account, double amount) {
+ return new Journal(amount, account, "CREDIT");
}
protected Transaction transaction(double principalAmount, String type,
String date) {
@@ -639,16 +672,16 @@ public abstract class BaseLoanIntegrationTest {
return new Transaction(principalAmount, type, date, true);
}
- protected TransactionExt transaction(double amount, String type, String
date, double outstandingAmount, double principalPortion,
+ protected TransactionExt transaction(double amount, String type, String
date, double outstandingPrincipal, double principalPortion,
double interestPortion, double feePortion, double penaltyPortion,
double unrecognizedIncomePortion, double overpaymentPortion) {
- return new TransactionExt(amount, type, date, outstandingAmount,
principalPortion, interestPortion, feePortion, penaltyPortion,
+ return new TransactionExt(amount, type, date, outstandingPrincipal,
principalPortion, interestPortion, feePortion, penaltyPortion,
unrecognizedIncomePortion, overpaymentPortion, false);
}
- protected TransactionExt transaction(double amount, String type, String
date, double outstandingAmount, double principalPortion,
+ protected TransactionExt transaction(double amount, String type, String
date, double outstandingPrincipal, double principalPortion,
double interestPortion, double feePortion, double penaltyPortion,
double unrecognizedIncomePortion, double overpaymentPortion,
boolean reversed) {
- return new TransactionExt(amount, type, date, outstandingAmount,
principalPortion, interestPortion, feePortion, penaltyPortion,
+ return new TransactionExt(amount, type, date, outstandingPrincipal,
principalPortion, interestPortion, feePortion, penaltyPortion,
unrecognizedIncomePortion, overpaymentPortion, reversed);
}
@@ -765,7 +798,7 @@ public abstract class BaseLoanIntegrationTest {
Double amount;
String type;
String date;
- Double outstandingAmount;
+ Double outstandingPrincipal;
Double principalPortion;
Double interestPortion;
Double feePortion;
diff --git
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanChargebackWithCreditAllocationsIntegrationTests.java
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanChargebackWithCreditAllocationsIntegrationTests.java
index 63ae1b179..ccb3e1a2a 100644
---
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanChargebackWithCreditAllocationsIntegrationTests.java
+++
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanChargebackWithCreditAllocationsIntegrationTests.java
@@ -1011,6 +1011,455 @@ public class
LoanChargebackWithCreditAllocationsIntegrationTests extends BaseLoa
});
}
+ @Test
+ public void testAccountingChargebackOnPrincipal() {
+ runAt("01 January 2023", () -> {
+ // Create Client
+ Long clientId =
clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId();
+ // Create Loan Product
+ Long loanProductId = createLoanProduct(//
+ createDefaultPaymentAllocation(), //
+ chargebackAllocation("PENALTY", "FEE", "INTEREST",
"PRINCIPAL")//
+ );
+ // Apply and Approve Loan
+ Long loanId = applyAndApproveLoan(clientId, loanProductId, 3);
+
+ // Disburse Loan
+ disburseLoan(loanId, BigDecimal.valueOf(750), "01 January 2023");
+
+ verifyRepaymentSchedule(loanId, //
+ installment(0, null, "01 January 2023"), //
+ installment(250.0, 0, 0, 0, 250.0, false, "01 February
2023"), //
+ installment(250.0, 0, 0, 0, 250.0, false, "01 March
2023"), //
+ installment(250.0, 0, 0, 0, 250.0, false, "01 April 2023")
//
+ );
+
+ // Repayment #1
+ updateBusinessDate("01 February 2023");
+ Long repaymentTransaction1 = addRepaymentForLoan(loanId, 250.0,
"01 February 2023");
+
+ // Repayment #2
+ updateBusinessDate("01 March 2023");
+ Long repaymentTransaction2 = addRepaymentForLoan(loanId, 250.0,
"01 March 2023");
+
+ // Repayment #3
+ updateBusinessDate("30 March 2023");
+ Long repaymentTransaction3 = addRepaymentForLoan(loanId, 250.0,
"30 March 2023");
+
+ // Chargeback 250
+ Long chargeback = addChargebackForLoan(loanId,
repaymentTransaction2, 250.0);
+
+ verifyTransactions(loanId, //
+ transaction(750.0, "Disbursement", "01 January 2023",
750.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
+ transaction(250.0, "Repayment", "01 February 2023", 500.0,
250.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
+ transaction(250.0, "Repayment", "01 March 2023", 250.0,
250.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
+ transaction(250.0, "Repayment", "30 March 2023", 0.0,
250.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
+ transaction(250.0, "Chargeback", "30 March 2023", 250,
250.0, 0.0, 0.0, 0.0, 0.0, 0.0) //
+ );
+
+ // Verify GL entries
+ verifyTRJournalEntries(repaymentTransaction1, //
+ debit(fundSource, 250), //
+ credit(loansReceivableAccount, 250)//
+ );
+
+ verifyTRJournalEntries(repaymentTransaction2, //
+ debit(fundSource, 250), //
+ credit(loansReceivableAccount, 250) //
+ );
+
+ verifyTRJournalEntries(repaymentTransaction3, //
+ debit(fundSource, 250), //
+ credit(loansReceivableAccount, 250)//
+ );
+
+ verifyTRJournalEntries(chargeback, //
+ debit(loansReceivableAccount, 250), //
+ credit(fundSource, 250) //
+ );
+
+ });
+ }
+
+ @Test
+ public void testAccountingChargebackOnPrincipalAndFees() {
+ runAt("01 January 2023", () -> {
+ // Create Client
+ Long clientId =
clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId();
+ // Create Loan Product
+ Long loanProductId = createLoanProduct(//
+ createDefaultPaymentAllocation(), //
+ chargebackAllocation("PENALTY", "FEE", "INTEREST",
"PRINCIPAL")//
+ );
+ // Apply and Approve Loan
+ Long loanId = applyAndApproveLoan(clientId, loanProductId, 3);
+
+ // Disburse Loan
+ disburseLoan(loanId, BigDecimal.valueOf(750), "01 January 2023");
+
+ Long feeId = addCharge(loanId, false, 30, "15 February 2023");
+
+ verifyRepaymentSchedule(loanId, //
+ installment(0, null, "01 January 2023"), //
+ installment(250.0, 0, 0, 0, 250.0, false, "01 February
2023"), //
+ installment(250.0, 0, 30, 0, 280.0, false, "01 March
2023"), //
+ installment(250.0, 0, 0, 0, 250.0, false, "01 April 2023")
//
+ );
+
+ // Repayment #1
+ updateBusinessDate("01 February 2023");
+ Long repaymentTransaction1 = addRepaymentForLoan(loanId, 250.0,
"01 February 2023");
+
+ // Repayment #2
+ updateBusinessDate("01 March 2023");
+ Long repaymentTransaction2 = addRepaymentForLoan(loanId, 280.0,
"01 March 2023");
+
+ // Run periodic accrual
+ schedulerJobHelper.executeAndAwaitJob("Add Accrual Transactions");
+
+ // Repayment #3
+ updateBusinessDate("30 March 2023");
+ Long repaymentTransaction3 = addRepaymentForLoan(loanId, 250.0,
"30 March 2023");
+
+ // Chargeback 250
+ Long chargeback = addChargebackForLoan(loanId,
repaymentTransaction2, 280.0);
+
+ verifyTransactions(loanId, //
+ transaction(750.0, "Disbursement", "01 January 2023",
750.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
+ transaction(250.0, "Repayment", "01 February 2023", 500.0,
250.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
+ transaction(280.0, "Repayment", "01 March 2023", 250.0,
250.0, 0.0, 30.0, 0.0, 0.0, 0.0), //
+ transaction(30.0, "Accrual", "01 March 2023", 0.0, 0.0,
0.0, 30.0, 0.0, 0.0, 0.0), //
+ transaction(250.0, "Repayment", "30 March 2023", 0.0,
250.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
+ transaction(280.0, "Chargeback", "30 March 2023", 250,
250.0, 0.0, 30.0, 0.0, 0.0, 0.0) //
+ );
+
+ // Verify GL entries
+ verifyTRJournalEntries(repaymentTransaction1, //
+ debit(fundSource, 250), //
+ credit(loansReceivableAccount, 250) //
+ );
+
+ verifyTRJournalEntries(repaymentTransaction2, //
+ debit(fundSource, 280), //
+ credit(loansReceivableAccount, 250), //
+ credit(feeReceivableAccount, 30)//
+ );
+
+ verifyTRJournalEntries(repaymentTransaction3, //
+ debit(fundSource, 250), //
+ credit(loansReceivableAccount, 250)//
+ );
+
+ verifyTRJournalEntries(chargeback, //
+ debit(loansReceivableAccount, 250), //
+ debit(feeReceivableAccount, 30), //
+ credit(fundSource, 280) //
+ );
+
+ });
+ }
+
+ @Test
+ public void testAccountingChargebackOnPrincipalAndPenalties() {
+ runAt("01 January 2023", () -> {
+ // Create Client
+ Long clientId =
clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId();
+ // Create Loan Product
+ Long loanProductId = createLoanProduct(//
+ createDefaultPaymentAllocation(), //
+ chargebackAllocation("PENALTY", "FEE", "INTEREST",
"PRINCIPAL")//
+ );
+ // Apply and Approve Loan
+ Long loanId = applyAndApproveLoan(clientId, loanProductId, 3);
+
+ // Disburse Loan
+ disburseLoan(loanId, BigDecimal.valueOf(750), "01 January 2023");
+
+ Long feeId = addCharge(loanId, true, 30, "15 February 2023");
+
+ verifyRepaymentSchedule(loanId, //
+ installment(0, null, "01 January 2023"), //
+ installment(250.0, 0, 0, 0, 250.0, false, "01 February
2023"), //
+ installment(250.0, 0, 0, 30.0, 280.0, false, "01 March
2023"), //
+ installment(250.0, 0, 0, 0, 250.0, false, "01 April 2023")
//
+ );
+
+ // Repayment #1
+ updateBusinessDate("01 February 2023");
+ Long repaymentTransaction1 = addRepaymentForLoan(loanId, 250.0,
"01 February 2023");
+
+ // Repayment #2
+ updateBusinessDate("01 March 2023");
+ Long repaymentTransaction2 = addRepaymentForLoan(loanId, 280.0,
"01 March 2023");
+
+ // Run periodic accrual
+ schedulerJobHelper.executeAndAwaitJob("Add Accrual Transactions");
+
+ // Repayment #3
+ updateBusinessDate("30 March 2023");
+ Long repaymentTransaction3 = addRepaymentForLoan(loanId, 250.0,
"30 March 2023");
+
+ // Chargeback 250
+ Long chargeback = addChargebackForLoan(loanId,
repaymentTransaction2, 280.0);
+
+ verifyTransactions(loanId, //
+ transaction(750.0, "Disbursement", "01 January 2023",
750.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
+ transaction(250.0, "Repayment", "01 February 2023", 500.0,
250.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
+ transaction(280.0, "Repayment", "01 March 2023", 250.0,
250.0, 0.0, 0.0, 30.0, 0.0, 0.0), //
+ transaction(30.0, "Accrual", "01 March 2023", 0.0, 0.0,
0.0, 0.0, 30.0, 0.0, 0.0), //
+ transaction(250.0, "Repayment", "30 March 2023", 0.0,
250.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
+ transaction(280.0, "Chargeback", "30 March 2023", 250,
250.0, 0.0, 0.0, 30.0, 0.0, 0.0) //
+ );
+
+ // Verify GL entries
+ verifyTRJournalEntries(repaymentTransaction1, //
+ debit(fundSource, 250), //
+ credit(loansReceivableAccount, 250) //
+ );
+
+ verifyTRJournalEntries(repaymentTransaction2, //
+ debit(fundSource, 280), //
+ credit(loansReceivableAccount, 250), //
+ credit(penaltyReceivableAccount, 30)//
+ );
+
+ verifyTRJournalEntries(repaymentTransaction3, //
+ debit(fundSource, 250), //
+ credit(loansReceivableAccount, 250)//
+ );
+
+ verifyTRJournalEntries(chargeback, //
+ debit(loansReceivableAccount, 250), //
+ debit(penaltyReceivableAccount, 30), //
+ credit(fundSource, 280) //
+ );
+
+ });
+ }
+
+ @Test
+ public void testAccountingOverpaymentAmountIsSmallerThanChargeback() {
+ runAt("01 January 2023", () -> {
+ // Create Client
+ Long clientId =
clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId();
+ // Create Loan Product
+ Long loanProductId = createLoanProduct(//
+ createDefaultPaymentAllocation(), //
+ chargebackAllocation("PENALTY", "FEE", "INTEREST",
"PRINCIPAL")//
+ );
+ // Apply and Approve Loan
+ Long loanId = applyAndApproveLoan(clientId, loanProductId, 3);
+
+ // Disburse Loan
+ disburseLoan(loanId, BigDecimal.valueOf(750), "01 January 2023");
+
+ verifyRepaymentSchedule(loanId, //
+ installment(0, null, "01 January 2023"), //
+ installment(250.0, 0, 0, 0, 250.0, false, "01 February
2023"), //
+ installment(250.0, 0, 0, 0, 250.0, false, "01 March
2023"), //
+ installment(250.0, 0, 0, 0, 250.0, false, "01 April 2023")
//
+ );
+
+ // Repayment #1
+ updateBusinessDate("01 February 2023");
+ Long repaymentTransaction1 = addRepaymentForLoan(loanId, 250.0,
"01 February 2023");
+
+ // Repayment #2
+ updateBusinessDate("01 March 2023");
+ Long repaymentTransaction2 = addRepaymentForLoan(loanId, 250.0,
"01 March 2023");
+
+ // Repayment #3
+ updateBusinessDate("30 March 2023");
+ Long repaymentTransaction3 = addRepaymentForLoan(loanId, 400.0,
"30 March 2023");
+
+ // Chargeback 250
+ updateBusinessDate("31 March 2023");
+ Long chargeback = addChargebackForLoan(loanId,
repaymentTransaction2, 250.0);
+
+ verifyTransactions(loanId, //
+ transaction(750.0, "Disbursement", "01 January 2023",
750.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
+ transaction(250.0, "Repayment", "01 February 2023", 500.0,
250.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
+ transaction(250.0, "Repayment", "01 March 2023", 250.0,
250.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
+ transaction(400.0, "Repayment", "30 March 2023", 0.0,
250.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
+ transaction(250.0, "Chargeback", "31 March 2023", 100,
250.0, 0.0, 0.0, 0.0, 0.0, 150.0) //
+ );
+
+ // Verify GL entries
+ verifyTRJournalEntries(repaymentTransaction1, //
+ debit(fundSource, 250), //
+ credit(loansReceivableAccount, 250) //
+ );
+
+ verifyTRJournalEntries(repaymentTransaction2, //
+ debit(fundSource, 250), //
+ credit(loansReceivableAccount, 250) //
+ );
+
+ verifyTRJournalEntries(repaymentTransaction3, //
+ debit(fundSource, 400), //
+ credit(loansReceivableAccount, 250), //
+ credit(overpaymentAccount, 150) //
+ );
+
+ verifyTRJournalEntries(chargeback, //
+ debit(loansReceivableAccount, 100), //
+ debit(overpaymentAccount, 150), //
+ credit(fundSource, 250) //
+ );
+ });
+ }
+
+ @Test
+ public void testAccountingOverpaymentAmountIsBiggerThanChargeback() {
+ runAt("01 January 2023", () -> {
+ // Create Client
+ Long clientId =
clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId();
+ // Create Loan Product
+ Long loanProductId = createLoanProduct(//
+ createDefaultPaymentAllocation(), //
+ chargebackAllocation("PENALTY", "FEE", "INTEREST",
"PRINCIPAL")//
+ );
+ // Apply and Approve Loan
+ Long loanId = applyAndApproveLoan(clientId, loanProductId, 3);
+
+ // Disburse Loan
+ disburseLoan(loanId, BigDecimal.valueOf(750), "01 January 2023");
+
+ verifyRepaymentSchedule(loanId, //
+ installment(0, null, "01 January 2023"), //
+ installment(250.0, 0, 0, 0, 250.0, false, "01 February
2023"), //
+ installment(250.0, 0, 0, 0, 250.0, false, "01 March
2023"), //
+ installment(250.0, 0, 0, 0, 250.0, false, "01 April 2023")
//
+ );
+
+ // Repayment #1
+ updateBusinessDate("01 February 2023");
+ Long repaymentTransaction1 = addRepaymentForLoan(loanId, 250.0,
"01 February 2023");
+
+ // Repayment #2
+ updateBusinessDate("01 March 2023");
+ Long repaymentTransaction2 = addRepaymentForLoan(loanId, 250.0,
"01 March 2023");
+
+ // Repayment #3
+ updateBusinessDate("30 March 2023");
+ Long repaymentTransaction3 = addRepaymentForLoan(loanId, 400.0,
"30 March 2023");
+
+ // Chargeback 250
+ updateBusinessDate("31 March 2023");
+ Long chargeback = addChargebackForLoan(loanId,
repaymentTransaction2, 100.0);
+
+ verifyTransactions(loanId, //
+ transaction(750.0, "Disbursement", "01 January 2023",
750.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
+ transaction(250.0, "Repayment", "01 February 2023", 500.0,
250.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
+ transaction(250.0, "Repayment", "01 March 2023", 250.0,
250.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
+ transaction(400.0, "Repayment", "30 March 2023", 0.0,
250.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
+ transaction(100.0, "Chargeback", "31 March 2023", 0.0,
100.0, 0.0, 0.0, 0.0, 0.0, -50.0) //
+ );
+
+ // Verify GL entries
+ verifyTRJournalEntries(repaymentTransaction1, //
+ debit(fundSource, 250), //
+ credit(loansReceivableAccount, 250) //
+ );
+
+ verifyTRJournalEntries(repaymentTransaction2, //
+ debit(fundSource, 250), //
+ credit(loansReceivableAccount, 250) //
+ );
+
+ verifyTRJournalEntries(repaymentTransaction3, //
+ debit(fundSource, 400), //
+ credit(loansReceivableAccount, 250), //
+ credit(overpaymentAccount, 150) //
+ );
+
+ verifyTRJournalEntries(chargeback, //
+ debit(overpaymentAccount, 100), //
+ credit(fundSource, 100) //
+ );
+ });
+ }
+
+ @Test
+ public void
testAccountingOverpaidLoansWithFeesWhenOverpaymentAmountIsBiggerThanChargeback()
{
+ runAt("01 January 2023", () -> {
+ // Create Client
+ Long clientId =
clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId();
+ // Create Loan Product
+ Long loanProductId = createLoanProduct(//
+ createDefaultPaymentAllocation(), //
+ chargebackAllocation("PENALTY", "FEE", "INTEREST",
"PRINCIPAL")//
+ );
+ // Apply and Approve Loan
+ Long loanId = applyAndApproveLoan(clientId, loanProductId, 3);
+
+ // Disburse Loan
+ disburseLoan(loanId, BigDecimal.valueOf(750), "01 January 2023");
+
+ verifyRepaymentSchedule(loanId, //
+ installment(0, null, "01 January 2023"), //
+ installment(250.0, 0, 0, 0, 250.0, false, "01 February
2023"), //
+ installment(250.0, 0, 0, 0, 250.0, false, "01 March
2023"), //
+ installment(250.0, 0, 0, 0, 250.0, false, "01 April 2023")
//
+ );
+
+ // Repayment #1
+ updateBusinessDate("01 February 2023");
+ Long repaymentTransaction1 = addRepaymentForLoan(loanId, 250.0,
"01 February 2023");
+
+ // Add fee & Repayment #2
+ updateBusinessDate("01 March 2023");
+ Long feeId = addCharge(loanId, false, 30, "01 March 2023");
+ Long repaymentTransaction2 = addRepaymentForLoan(loanId, 280.0,
"01 March 2023");
+ schedulerJobHelper.executeAndAwaitJob("Add Accrual Transactions");
+
+ // Repayment #3
+ updateBusinessDate("30 March 2023");
+ Long repaymentTransaction3 = addRepaymentForLoan(loanId, 400.0,
"30 March 2023");
+
+ // Chargeback 250
+ updateBusinessDate("31 March 2023");
+ Long chargeback = addChargebackForLoan(loanId,
repaymentTransaction2, 100.0);
+
+ verifyTransactions(loanId, //
+ transaction(750.0, "Disbursement", "01 January 2023",
750.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
+ transaction(250.0, "Repayment", "01 February 2023", 500.0,
250.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
+ transaction(280.0, "Repayment", "01 March 2023", 250.0,
250.0, 0.0, 30.0, 0.0, 0.0, 0.0), //
+ transaction(30.0, "Accrual", "01 March 2023", 0.0, 0.0,
0.0, 30.0, 0.0, 0.0, 0.0), //
+ transaction(400.0, "Repayment", "30 March 2023", 0.0,
250.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
+ transaction(100.0, "Chargeback", "31 March 2023", 0.0,
70.0, 0.0, 30.0, 0.0, 0.0, -50.0) //
+ );
+
+ // Verify GL entries
+ verifyTRJournalEntries(repaymentTransaction1, //
+ debit(fundSource, 250), //
+ credit(loansReceivableAccount, 250) //
+ );
+
+ verifyTRJournalEntries(repaymentTransaction2, //
+ debit(fundSource, 280), //
+ credit(loansReceivableAccount, 250), //
+ credit(feeReceivableAccount, 30) //
+ );
+
+ verifyTRJournalEntries(getTransactionId(loanId, "Accrual", "01
March 2023"), //
+ debit(feeReceivableAccount, 30), //
+ credit(feeIncomeAccount, 30) //
+ );
+
+ verifyTRJournalEntries(repaymentTransaction3, //
+ debit(fundSource, 400), //
+ credit(loansReceivableAccount, 250), //
+ credit(overpaymentAccount, 150) //
+ );
+
+ verifyTRJournalEntries(chargeback, //
+ debit(overpaymentAccount, 100), //
+ credit(fundSource, 100) //
+ );
+ });
+ }
+
private void verifyLoanSummaryAmounts(Long loanId, double
creditedPrincipal, double creditedFee, double creditedPenalty,
double totalOutstanding) {
GetLoansLoanIdResponse loanResponse =
loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId.intValue());
@@ -1023,10 +1472,10 @@ public class
LoanChargebackWithCreditAllocationsIntegrationTests extends BaseLoa
}
@Nullable
- private Long applyAndApproveLoan(Long clientId, Long loanProductId) {
- PostLoansRequest applicationRequest = applyLoanRequest(clientId,
loanProductId, "01 January 2023", 1250.0, 4)//
+ private Long applyAndApproveLoan(Long clientId, Long loanProductId, int
numberOfRepayments) {
+ PostLoansRequest applicationRequest = applyLoanRequest(clientId,
loanProductId, "01 January 2023", 1250.0, numberOfRepayments)//
.repaymentEvery(1)//
- .loanTermFrequency(4)//
+ .loanTermFrequency(numberOfRepayments)//
.repaymentFrequencyType(RepaymentFrequencyType.MONTHS)//
.loanTermFrequencyType(RepaymentFrequencyType.MONTHS)//
.transactionProcessingStrategyCode("advanced-payment-allocation-strategy");
@@ -1036,8 +1485,12 @@ public class
LoanChargebackWithCreditAllocationsIntegrationTests extends BaseLoa
PostLoansLoanIdResponse approvedLoanResult =
loanTransactionHelper.approveLoan(postLoansResponse.getResourceId(),
approveLoanRequest(1250.0, "01 January 2023"));
- Long loanId = approvedLoanResult.getLoanId();
- return loanId;
+ return approvedLoanResult.getLoanId();
+ }
+
+ @Nullable
+ private Long applyAndApproveLoan(Long clientId, Long loanProductId) {
+ return applyAndApproveLoan(clientId, loanProductId, 4);
}
public Long createLoanProduct(AdvancedPaymentData defaultAllocation,
CreditAllocationData creditAllocationData) {
diff --git
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanDownPaymentTransactionChargebackTest.java
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanDownPaymentTransactionChargebackTest.java
index 17e05c2de..2b8f7b015 100644
---
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanDownPaymentTransactionChargebackTest.java
+++
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanDownPaymentTransactionChargebackTest.java
@@ -23,7 +23,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import java.math.BigDecimal;
-import
org.apache.fineract.client.models.GetJournalEntriesTransactionIdResponse;
import org.apache.fineract.client.models.GetLoanProductsProductIdResponse;
import
org.apache.fineract.client.models.GetLoansLoanIdTransactionsTransactionIdResponse;
import org.apache.fineract.client.models.PostLoanProductsRequest;
@@ -88,15 +87,10 @@ public class LoanDownPaymentTransactionChargebackTest
extends BaseLoanIntegratio
);
// verify journal entries for chargeback transaction
- GetJournalEntriesTransactionIdResponse journalEntries =
journalEntryHelper
- .getJournalEntries("L" +
chargebackTransactionId.toString());
- assertEquals(2L, journalEntries.getTotalFilteredRecords());
- assertEquals(50.0,
journalEntries.getPageItems().get(0).getAmount());
- assertEquals("CREDIT",
journalEntries.getPageItems().get(0).getEntryType().getValue());
-
- assertEquals(50.0,
journalEntries.getPageItems().get(1).getAmount());
- assertEquals("DEBIT",
journalEntries.getPageItems().get(1).getEntryType().getValue());
-
+ verifyTRJournalEntries(chargebackTransactionId, //
+ credit(fundSource, 50.0), //
+ debit(loansReceivableAccount, 50.0) //
+ );
});
}
@@ -152,15 +146,10 @@ public class LoanDownPaymentTransactionChargebackTest
extends BaseLoanIntegratio
);
// verify journal entries for chargeback transaction
- GetJournalEntriesTransactionIdResponse journalEntries =
journalEntryHelper
- .getJournalEntries("L" +
chargebackTransactionId.toString());
- assertEquals(2L, journalEntries.getTotalFilteredRecords());
- assertEquals(50.0,
journalEntries.getPageItems().get(0).getAmount());
- assertEquals("CREDIT",
journalEntries.getPageItems().get(0).getEntryType().getValue());
-
- assertEquals(50.0,
journalEntries.getPageItems().get(1).getAmount());
- assertEquals("DEBIT",
journalEntries.getPageItems().get(1).getEntryType().getValue());
-
+ verifyTRJournalEntries(chargebackTransactionId, //
+ credit(fundSource, 50.0), //
+ debit(loansReceivableAccount, 50.0) //
+ );
});
}
diff --git
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRepaymentScheduleWithDownPaymentTest.java
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRepaymentScheduleWithDownPaymentTest.java
index d9cf82d3c..9ef2a6acb 100644
---
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRepaymentScheduleWithDownPaymentTest.java
+++
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRepaymentScheduleWithDownPaymentTest.java
@@ -1252,10 +1252,11 @@ public class LoanRepaymentScheduleWithDownPaymentTest
extends BaseLoanIntegratio
transaction(1000.0, "Disbursement", "03 March 2023",
1000.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
transaction(250.0, "Down Payment", "03 March 2023", 750.0,
250.0, 0.0, 0.0, 0.0, 0.0, 0.0) //
);
- verifyJournalEntries(loanResponse.getResourceId(),
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+ verifyJournalEntries(loanResponse.getResourceId(), //
+ journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
+ journalEntry(1000.0, fundSource, "CREDIT"), //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT") //
+ journalEntry(250.0, fundSource, "DEBIT") //
);
loanTransactionHelper.makeLoanRepayment(loanResponse.getResourceId(), new
PostLoansLoanIdTransactionsRequest()
@@ -1464,10 +1465,11 @@ public class LoanRepaymentScheduleWithDownPaymentTest
extends BaseLoanIntegratio
transaction(1000.0, "Disbursement", "03 March 2023",
1000.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
transaction(250.0, "Down Payment", "03 March 2023", 750.0,
250.0, 0.0, 0.0, 0.0, 0.0, 0.0) //
);
- verifyJournalEntries(loanResponse.getResourceId(),
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+ verifyJournalEntries(loanResponse.getResourceId(), //
+ journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
+ journalEntry(1000.0, fundSource, "CREDIT"), //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT") //
+ journalEntry(250.0, fundSource, "DEBIT") //
);
String externalId = UUID.randomUUID().toString();
diff --git
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleTestWithDownpayment.java
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleTestWithDownpayment.java
index d54a60d20..450553ff8 100644
---
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleTestWithDownpayment.java
+++
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleTestWithDownpayment.java
@@ -74,9 +74,9 @@ public class LoanRescheduleTestWithDownpayment extends
BaseLoanIntegrationTest {
// verify journal entries
verifyJournalEntries(loanId, journalEntry(250.0,
loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT") //
+ journalEntry(1000.0, fundSource, "CREDIT") //
);
// Verify Repayment Schedule
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 635a6c2c3..0fb211c96 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
@@ -18,6 +18,7 @@
*/
package org.apache.fineract.integrationtests;
+import static
org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder.ACCRUAL_PERIODIC;
import static
org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder.DEFAULT_STRATEGY;
import static
org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.impl.AdvancedPaymentScheduleTransactionProcessor.ADVANCED_PAYMENT_ALLOCATION_STRATEGY;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -39,7 +40,6 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.client.models.AdvancedPaymentData;
import org.apache.fineract.client.models.GetDelinquencyBucketsResponse;
import org.apache.fineract.client.models.GetDelinquencyRangesResponse;
-import
org.apache.fineract.client.models.GetJournalEntriesTransactionIdResponse;
import org.apache.fineract.client.models.GetLoanProductsProductIdResponse;
import org.apache.fineract.client.models.GetLoansLoanIdRepaymentPeriod;
import org.apache.fineract.client.models.GetLoansLoanIdRepaymentSchedule;
@@ -53,7 +53,6 @@ import
org.apache.fineract.integrationtests.common.BusinessDateHelper;
import org.apache.fineract.integrationtests.common.ClientHelper;
import org.apache.fineract.integrationtests.common.GlobalConfigurationHelper;
import org.apache.fineract.integrationtests.common.Utils;
-import org.apache.fineract.integrationtests.common.accounting.Account;
import org.apache.fineract.integrationtests.common.accounting.AccountHelper;
import
org.apache.fineract.integrationtests.common.accounting.JournalEntryHelper;
import
org.apache.fineract.integrationtests.common.loans.LoanApplicationTestBuilder;
@@ -72,7 +71,7 @@ import org.junit.jupiter.params.provider.MethodSource;
@Slf4j
@ExtendWith(LoanTestLifecycleExtension.class)
-public class LoanTransactionChargebackTest {
+public class LoanTransactionChargebackTest extends BaseLoanIntegrationTest {
private ResponseSpecification responseSpec;
private ResponseSpecification responseSpecErr400;
@@ -139,14 +138,10 @@ public class LoanTransactionChargebackTest {
loanTransactionHelper.validateLoanPrincipalOustandingBalance(getLoansLoanIdResponse,
amount.doubleValue());
- GetJournalEntriesTransactionIdResponse journalEntries =
journalEntryHelper
- .getJournalEntries("L" + chargebackTransactionId.toString());
- assertEquals(2L, journalEntries.getTotalFilteredRecords());
- assertEquals(1000.0, journalEntries.getPageItems().get(0).getAmount());
- assertEquals("CREDIT",
journalEntries.getPageItems().get(0).getEntryType().getValue());
-
- assertEquals(1000.0, journalEntries.getPageItems().get(1).getAmount());
- assertEquals("DEBIT",
journalEntries.getPageItems().get(1).getEntryType().getValue());
+ verifyTRJournalEntries(chargebackTransactionId, //
+ credit(fundSource, 1000.0), //
+ debit(loansReceivableAccount, 1000.0) //
+ );
// Try to reverse a Loan Transaction charge back
PostLoansLoanIdTransactionsResponse reverseTransactionResponse =
loanTransactionHelper.reverseLoanTransaction(loanId,
@@ -431,17 +426,11 @@ public class LoanTransactionChargebackTest {
assertEquals(getLoansLoanIdResponse.getTimeline().getExpectedMaturityDate(),
getLoansLoanIdResponse.getTimeline().getActualMaturityDate());
- GetJournalEntriesTransactionIdResponse journalEntries =
journalEntryHelper
- .getJournalEntries("L" + chargebackTransactionId.toString());
- assertEquals(3L, journalEntries.getTotalFilteredRecords());
- assertEquals(100.0, journalEntries.getPageItems().get(0).getAmount());
- assertEquals("DEBIT",
journalEntries.getPageItems().get(0).getEntryType().getValue());
-
- assertEquals(200.0, journalEntries.getPageItems().get(1).getAmount());
- assertEquals("CREDIT",
journalEntries.getPageItems().get(1).getEntryType().getValue());
-
- assertEquals(100.0, journalEntries.getPageItems().get(2).getAmount());
- assertEquals("DEBIT",
journalEntries.getPageItems().get(2).getEntryType().getValue());
+ verifyTRJournalEntries(chargebackTransactionId, //
+ credit(fundSource, 200.0), //
+ debit(loansReceivableAccount, 100.0), //
+ debit(overpaymentAccount, 100.0) //
+ );
final GetDelinquencyRangesResponse delinquencyRange =
getLoansLoanIdResponse.getDelinquencyRange();
assertNull(delinquencyRange);
@@ -525,14 +514,10 @@ public class LoanTransactionChargebackTest {
loanTransactionHelper.validateLoanPrincipalOustandingBalance(getLoansLoanIdResponse,
Double.valueOf("0.00"));
- GetJournalEntriesTransactionIdResponse journalEntries =
journalEntryHelper
- .getJournalEntries("L" + chargebackTransactionId.toString());
- assertEquals(2L, journalEntries.getTotalFilteredRecords());
- assertEquals(50.0, journalEntries.getPageItems().get(0).getAmount());
- assertEquals("CREDIT",
journalEntries.getPageItems().get(0).getEntryType().getValue());
-
- assertEquals(50.0, journalEntries.getPageItems().get(1).getAmount());
- assertEquals("DEBIT",
journalEntries.getPageItems().get(1).getEntryType().getValue());
+ verifyTRJournalEntries(chargebackTransactionId, //
+ credit(fundSource, 50.0), //
+ debit(overpaymentAccount, 50.0) //
+ );
}
@ParameterizedTest
@@ -632,12 +617,20 @@ public class LoanTransactionChargebackTest {
final Integer delinquencyBucketId, final boolean
withJournalEntries, LoanProductTestBuilder loanProductTestBuilder) {
final HashMap<String, Object> loanProductMap;
if (withJournalEntries) {
- final Account assetAccount = accountHelper.createAssetAccount();
- final Account expenseAccount =
accountHelper.createExpenseAccount();
- final Account incomeAccount = accountHelper.createIncomeAccount();
- final Account overpaymentAccount =
accountHelper.createLiabilityAccount();
loanProductMap = loanProductTestBuilder
- .withAccountingRulePeriodicAccrual(new Account[] {
assetAccount, expenseAccount, incomeAccount, overpaymentAccount })
+ .withFullAccountingConfig(ACCRUAL_PERIODIC,
+
LoanProductTestBuilder.FullAccountingConfig.builder().fundSourceAccountId(fundSource.getAccountID().longValue())//
+
.loanPortfolioAccountId(loansReceivableAccount.getAccountID().longValue())//
+
.transfersInSuspenseAccountId(suspenseAccount.getAccountID().longValue())//
+
.interestOnLoanAccountId(interestIncomeAccount.getAccountID().longValue())//
+
.incomeFromFeeAccountId(feeIncomeAccount.getAccountID().longValue())//
+
.incomeFromPenaltyAccountId(penaltyIncomeAccount.getAccountID().longValue())//
+
.incomeFromRecoveryAccountId(recoveriesAccount.getAccountID().longValue())//
+
.writeOffAccountId(writtenOffAccount.getAccountID().longValue())//
+
.overpaymentLiabilityAccountId(overpaymentAccount.getAccountID().longValue())//
+
.receivableInterestAccountId(interestReceivableAccount.getAccountID().longValue())//
+
.receivableFeeAccountId(interestReceivableAccount.getAccountID().longValue())//
+
.receivablePenaltyAccountId(interestReceivableAccount.getAccountID().longValue()).build())
.build(null, delinquencyBucketId);
} else {
loanProductMap = loanProductTestBuilder.build(null,
delinquencyBucketId);
diff --git
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/UndoLoanDisbursalWithDownPaymentIntegrationTest.java
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/UndoLoanDisbursalWithDownPaymentIntegrationTest.java
index 6ecb979ac..20f4837ac 100644
---
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/UndoLoanDisbursalWithDownPaymentIntegrationTest.java
+++
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/UndoLoanDisbursalWithDownPaymentIntegrationTest.java
@@ -69,9 +69,9 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest
extends BaseLoanInt
// verify journal entries
verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT") //
+ journalEntry(1000.0, fundSource, "CREDIT") //
);
// Verify Repayment Schedule
@@ -91,14 +91,14 @@ public class
UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
verifyJournalEntries(loanId,
// original entries
journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(1000.0, fundSource, "CREDIT"), //
// original entries reverted
journalEntry(250.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(250.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(250.0, fundSource, "CREDIT"), //
journalEntry(1000.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "DEBIT")); //
+ journalEntry(1000.0, fundSource, "DEBIT")); //
verifyRepaymentSchedule(loanId, //
installment(1000.0, null, "01 January 2023"), //
@@ -139,9 +139,9 @@ public class
UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries
verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT") //
+ journalEntry(1000.0, fundSource, "CREDIT") //
);
// make a repayment
@@ -164,23 +164,23 @@ public class
UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
verifyJournalEntries(loanId, //
// original entries down-payment
journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(1000.0, fundSource, "CREDIT"), //
// repayment entries
journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(100.0, fundSource, "DEBIT"), //
// original entries compensated
journalEntry(250.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(250.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(250.0, fundSource, "CREDIT"), //
journalEntry(1000.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(1000.0, fundSource, "DEBIT"), //
// repayment entries compensated
journalEntry(250.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(250.0, suspenseClearingAccount, "CREDIT") //
+ journalEntry(250.0, fundSource, "CREDIT") //
);
verifyRepaymentSchedule(loanId, //
@@ -225,9 +225,9 @@ public class
UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries
verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT") //
+ journalEntry(1000.0, fundSource, "CREDIT") //
);
// undoDisbursal
@@ -240,15 +240,15 @@ public class
UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
verifyJournalEntries(loanId, //
// original entries
journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(1000.0, fundSource, "CREDIT"), //
// original entries are compensated
journalEntry(250.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(250.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(250.0, fundSource, "CREDIT"), //
journalEntry(1000.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "DEBIT") //
+ journalEntry(1000.0, fundSource, "DEBIT") //
);
// verify repayment entries are reverted
@@ -298,11 +298,11 @@ public class
UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries
verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(100.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT") //
+ journalEntry(1000.0, fundSource, "CREDIT") //
);
// Verify Repayment Schedule
@@ -322,23 +322,23 @@ public class
UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
verifyJournalEntries(loanId, //
// original entries
journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(1000.0, fundSource, "CREDIT"), //
// original entries compensated
journalEntry(250.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(250.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(250.0, fundSource, "CREDIT"), //
journalEntry(1000.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(1000.0, fundSource, "DEBIT"), //
// manual partial repayment of the first installment
journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(100.0, fundSource, "DEBIT"), //
// manual partial repayment of the first installment
compensation after undoDisburse
journalEntry(100.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(100.0, suspenseClearingAccount, "CREDIT") //
+ journalEntry(100.0, fundSource, "CREDIT") //
);
// Verify Repayment Schedule
@@ -381,9 +381,9 @@ public class
UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries
verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT") //
+ journalEntry(1000.0, fundSource, "CREDIT") //
);
// Verify Repayment Schedule
@@ -429,9 +429,9 @@ public class
UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries
verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT") //
+ journalEntry(1000.0, fundSource, "CREDIT") //
);
// Verify Repayment Schedule
@@ -476,9 +476,9 @@ public class
UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries
verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT") //
+ journalEntry(1000.0, fundSource, "CREDIT") //
);
// Verify Repayment Schedule
@@ -498,14 +498,14 @@ public class
UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
verifyJournalEntries(loanId, //
// original entries
journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(1000.0, fundSource, "CREDIT"), //
// original entries reverted
journalEntry(250.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(250.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(250.0, fundSource, "CREDIT"), //
journalEntry(1000.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "DEBIT") //
+ journalEntry(1000.0, fundSource, "DEBIT") //
);
// Verify Repayment Schedule
@@ -548,9 +548,9 @@ public class
UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries
verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT") //
+ journalEntry(1000.0, fundSource, "CREDIT") //
);
// make a repayment
@@ -573,23 +573,23 @@ public class
UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
verifyJournalEntries(loanId,
// original entries down-payment
journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(1000.0, fundSource, "CREDIT"), //
// repayment entries
journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(100.0, fundSource, "DEBIT"), //
// original entries compensated
journalEntry(250.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(250.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(250.0, fundSource, "CREDIT"), //
journalEntry(1000.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(1000.0, fundSource, "DEBIT"), //
// repayment entries compensated
journalEntry(250.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(250.0, suspenseClearingAccount, "CREDIT") //
+ journalEntry(250.0, fundSource, "CREDIT") //
);
// Verify Repayment Schedule
@@ -635,9 +635,9 @@ public class
UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries
verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT") //
+ journalEntry(1000.0, fundSource, "CREDIT") //
);
// undoDisbursal
@@ -650,15 +650,15 @@ public class
UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
verifyJournalEntries(loanId,
// original entries
journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(1000.0, fundSource, "CREDIT"), //
// original entries are compensated
journalEntry(250.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(250.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(250.0, fundSource, "CREDIT"), //
journalEntry(1000.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "DEBIT") //
+ journalEntry(1000.0, fundSource, "DEBIT") //
);
// Verify Repayment Schedule
@@ -707,11 +707,11 @@ public class
UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries
verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(100.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT") //
+ journalEntry(1000.0, fundSource, "CREDIT") //
);
// Verify Repayment Schedule
@@ -731,23 +731,23 @@ public class
UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
verifyJournalEntries(loanId,
// original entries
journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(1000.0, fundSource, "CREDIT"), //
// original entries compensated
journalEntry(250.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(250.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(250.0, fundSource, "CREDIT"), //
journalEntry(1000.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(1000.0, fundSource, "DEBIT"), //
// manual partial repayment of the first installment
journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(100.0, fundSource, "DEBIT"), //
// manual partial repayment of the first installment
compensation after undoDisburse
journalEntry(100.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(100.0, suspenseClearingAccount, "CREDIT") //
+ journalEntry(100.0, fundSource, "CREDIT") //
);
// Verify Repayment Schedule
@@ -787,9 +787,9 @@ public class
UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries
verifyJournalEntries(loanId, journalEntry(250.0,
loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT") //
+ journalEntry(1000.0, fundSource, "CREDIT") //
);
// Verify Repayment Schedule
@@ -815,13 +815,13 @@ public class
UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries
verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(1000.0, fundSource, "CREDIT"), //
journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(100.0, fundSource, "DEBIT"), //
journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(400.0, suspenseClearingAccount, "CREDIT") //
+ journalEntry(400.0, fundSource, "CREDIT") //
);
// Verify Repayment Schedule
@@ -846,21 +846,21 @@ public class
UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
verifyJournalEntries(loanId,
// first disbursement + down-payment
journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(1000.0, fundSource, "CREDIT"), //
// second disbursement + down-payment
journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(100.0, fundSource, "DEBIT"), //
journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(400.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(400.0, fundSource, "CREDIT"), //
// compensation of second disbursement + down-payment
journalEntry(100.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(100.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(100.0, fundSource, "CREDIT"), //
journalEntry(400.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(400.0, suspenseClearingAccount, "DEBIT") //
+ journalEntry(400.0, fundSource, "DEBIT") //
);
verifyRepaymentSchedule(loanId, //
@@ -901,9 +901,9 @@ public class
UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries
verifyJournalEntries(loanId, journalEntry(250.0,
loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT") //
+ journalEntry(1000.0, fundSource, "CREDIT") //
);
// Verify Repayment Schedule
@@ -941,15 +941,15 @@ public class
UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries
verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(1000.0, fundSource, "CREDIT"), //
journalEntry(300.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(300.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(300.0, fundSource, "DEBIT"), //
journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(100.0, fundSource, "DEBIT"), //
journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(400.0, suspenseClearingAccount, "CREDIT") //
+ journalEntry(400.0, fundSource, "CREDIT") //
);
// Verify Repayment Schedule
@@ -975,25 +975,25 @@ public class
UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
verifyJournalEntries(loanId,
// first disbursement + down-payment
journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(1000.0, fundSource, "CREDIT"), //
// repayment
journalEntry(300.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(300.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(300.0, fundSource, "DEBIT"), //
// second disbursement + down-payment
journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(100.0, fundSource, "DEBIT"), //
journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(400.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(400.0, fundSource, "CREDIT"), //
// compensation of second disbursement + down-payment
journalEntry(100.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(100.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(100.0, fundSource, "CREDIT"), //
journalEntry(400.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(400.0, suspenseClearingAccount, "DEBIT") //
+ journalEntry(400.0, fundSource, "DEBIT") //
);
verifyRepaymentSchedule(loanId, //
@@ -1038,9 +1038,9 @@ public class
UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries
verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT") //
+ journalEntry(1000.0, fundSource, "CREDIT") //
);
// Verify Repayment Schedule
@@ -1070,13 +1070,13 @@ public class
UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries
verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(1000.0, fundSource, "CREDIT"), //
journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(100.0, fundSource, "DEBIT"), //
journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(400.0, suspenseClearingAccount, "CREDIT") //
+ journalEntry(400.0, fundSource, "CREDIT") //
);
// Verify Repayment Schedule
@@ -1101,21 +1101,21 @@ public class
UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
verifyJournalEntries(loanId,
// first disbursement + down-payment
journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(1000.0, fundSource, "CREDIT"), //
// second disbursement + down-payment
journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(100.0, fundSource, "DEBIT"), //
journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(400.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(400.0, fundSource, "CREDIT"), //
// compensation of second disbursement + down-payment
journalEntry(100.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(100.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(100.0, fundSource, "CREDIT"), //
journalEntry(400.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(400.0, suspenseClearingAccount, "DEBIT") //
+ journalEntry(400.0, fundSource, "DEBIT") //
);
verifyRepaymentSchedule(loanId, //
@@ -1157,9 +1157,9 @@ public class
UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries
verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT") //
+ journalEntry(1000.0, fundSource, "CREDIT") //
);
// Verify Repayment Schedule
@@ -1186,13 +1186,13 @@ public class
UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries
verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(1000.0, fundSource, "CREDIT"), //
journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(100.0, fundSource, "DEBIT"), //
journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(400.0, suspenseClearingAccount, "CREDIT") //
+ journalEntry(400.0, fundSource, "CREDIT") //
);
// Verify Repayment Schedule
@@ -1249,9 +1249,9 @@ public class
UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries
verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT") //
+ journalEntry(1000.0, fundSource, "CREDIT") //
);
// Verify Repayment Schedule
@@ -1281,13 +1281,13 @@ public class
UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries
verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(1000.0, fundSource, "CREDIT"), //
journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(100.0, fundSource, "DEBIT"), //
journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(400.0, suspenseClearingAccount, "CREDIT") //
+ journalEntry(400.0, fundSource, "CREDIT") //
);
// Verify Repayment Schedule
@@ -1341,9 +1341,9 @@ public class
UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries
verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT") //
+ journalEntry(1000.0, fundSource, "CREDIT") //
);
// Verify Repayment Schedule
@@ -1370,13 +1370,13 @@ public class
UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries
verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(1000.0, fundSource, "CREDIT"), //
journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(100.0, fundSource, "DEBIT"), //
journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(400.0, suspenseClearingAccount, "CREDIT") //
+ journalEntry(400.0, fundSource, "CREDIT") //
);
// Verify Repayment Schedule
@@ -1404,27 +1404,27 @@ public class
UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
verifyJournalEntries(loanId,
// 1st disbursal + down-payment
journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(1000.0, fundSource, "CREDIT"), //
// 2nd disbursal + down-payment
journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(100.0, fundSource, "DEBIT"), //
journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(400.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(400.0, fundSource, "CREDIT"), //
// compensation of the 1st disbursal + down-payment
journalEntry(250.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(250.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(250.0, fundSource, "CREDIT"), //
journalEntry(1000.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(1000.0, fundSource, "DEBIT"), //
// compensation of the 2nd disbursal + down-payment
journalEntry(100.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(100.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(100.0, fundSource, "CREDIT"), //
journalEntry(400.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(400.0, suspenseClearingAccount, "DEBIT") //
+ journalEntry(400.0, fundSource, "DEBIT") //
);
});
}
@@ -1463,9 +1463,9 @@ public class
UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries
verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT") //
+ journalEntry(1000.0, fundSource, "CREDIT") //
);
// Verify Repayment Schedule
@@ -1495,13 +1495,13 @@ public class
UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries
verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(1000.0, fundSource, "CREDIT"), //
journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(100.0, fundSource, "DEBIT"), //
journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(400.0, suspenseClearingAccount, "CREDIT") //
+ journalEntry(400.0, fundSource, "CREDIT") //
);
// Verify Repayment Schedule
@@ -1529,27 +1529,27 @@ public class
UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
verifyJournalEntries(loanId,
// 1st disbursal + down-payment
journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(1000.0, fundSource, "CREDIT"), //
// 2nd disbursal + down-payment
journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(100.0, fundSource, "DEBIT"), //
journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(400.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(400.0, fundSource, "CREDIT"), //
// compensation of the 1st disbursal + down-payment
journalEntry(250.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(250.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(250.0, fundSource, "CREDIT"), //
journalEntry(1000.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(1000.0, fundSource, "DEBIT"), //
// compensation of the 2nd disbursal + down-payment
journalEntry(100.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(100.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(100.0, fundSource, "CREDIT"), //
journalEntry(400.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(400.0, suspenseClearingAccount, "DEBIT") //
+ journalEntry(400.0, fundSource, "DEBIT") //
);
});
}
@@ -1585,9 +1585,9 @@ public class
UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries
verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT") //
+ journalEntry(1000.0, fundSource, "CREDIT") //
);
// Verify Repayment Schedule
@@ -1614,13 +1614,13 @@ public class
UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries
verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(1000.0, fundSource, "CREDIT"), //
journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(100.0, fundSource, "DEBIT"), //
journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(400.0, suspenseClearingAccount, "CREDIT") //
+ journalEntry(400.0, fundSource, "CREDIT") //
);
// Verify Repayment Schedule
@@ -1654,35 +1654,35 @@ public class
UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
verifyJournalEntries(loanId,
// 1st disbursal + down-payment
journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(1000.0, fundSource, "CREDIT"), //
// 2nd disbursal + down-payment
journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(100.0, fundSource, "DEBIT"), //
journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(400.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(400.0, fundSource, "CREDIT"), //
// manual repayment
journalEntry(50.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(50.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(50.0, fundSource, "DEBIT"), //
// compensation of the 1st disbursal + down-payment
journalEntry(250.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(250.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(250.0, fundSource, "CREDIT"), //
journalEntry(1000.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(1000.0, fundSource, "DEBIT"), //
// compensation of the 2nd disbursal + down-payment
journalEntry(100.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(100.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(100.0, fundSource, "CREDIT"), //
journalEntry(400.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(400.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(400.0, fundSource, "DEBIT"), //
// compensation of repayment
journalEntry(50.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(50.0, suspenseClearingAccount, "CREDIT") //
+ journalEntry(50.0, fundSource, "CREDIT") //
);
});
}
@@ -1721,9 +1721,9 @@ public class
UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries
verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT") //
+ journalEntry(1000.0, fundSource, "CREDIT") //
);
// Verify Repayment Schedule
@@ -1752,13 +1752,13 @@ public class
UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries
verifyJournalEntries(loanId, journalEntry(250.0,
loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(1000.0, fundSource, "CREDIT"), //
journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(100.0, fundSource, "DEBIT"), //
journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(400.0, suspenseClearingAccount, "CREDIT") //
+ journalEntry(400.0, fundSource, "CREDIT") //
);
// Verify Repayment Schedule
@@ -1792,35 +1792,35 @@ public class
UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
verifyJournalEntries(loanId,
// 1st disbursal + down-payment
journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(1000.0, fundSource, "CREDIT"), //
// 2nd disbursal + down-payment
journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(100.0, fundSource, "DEBIT"), //
journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(400.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(400.0, fundSource, "CREDIT"), //
// manual repayment
journalEntry(50.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(50.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(50.0, fundSource, "DEBIT"), //
// compensation of the 1st disbursal + down-payment
journalEntry(250.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(250.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(250.0, fundSource, "CREDIT"), //
journalEntry(1000.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(1000.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(1000.0, fundSource, "DEBIT"), //
// compensation of the 2nd disbursal + down-payment
journalEntry(100.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(100.0, suspenseClearingAccount, "CREDIT"), //
+ journalEntry(100.0, fundSource, "CREDIT"), //
journalEntry(400.0, loansReceivableAccount, "CREDIT"), //
- journalEntry(400.0, suspenseClearingAccount, "DEBIT"), //
+ journalEntry(400.0, fundSource, "DEBIT"), //
// compensation of repayment
journalEntry(50.0, loansReceivableAccount, "DEBIT"), //
- journalEntry(50.0, suspenseClearingAccount, "CREDIT") //
+ journalEntry(50.0, fundSource, "CREDIT") //
);
});
}
diff --git
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/accounting/AccountHelper.java
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/accounting/AccountHelper.java
index 0d2a50392..100447372 100644
---
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/accounting/AccountHelper.java
+++
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/accounting/AccountHelper.java
@@ -42,35 +42,55 @@ public class AccountHelper extends IntegrationTest {
}
public Account createAssetAccount() {
- final String assetAccountJSON = new
GLAccountBuilder().withAccountTypeAsAsset().build();
+ return this.createAssetAccount(null);
+ }
+
+ public Account createIncomeAccount() {
+ return this.createIncomeAccount(null);
+ }
+
+ public Account createExpenseAccount() {
+ return this.createExpenseAccount(null);
+ }
+
+ public Account createLiabilityAccount() {
+ return this.createLiabilityAccount(null);
+ }
+
+ public Account createEquityAccount() {
+ return this.createEquityAccount(null);
+ }
+
+ public Account createAssetAccount(String accountName) {
+ final String assetAccountJSON = new
GLAccountBuilder().withName(accountName).withAccountTypeAsAsset().build();
final Integer accountID = Utils.performServerPost(this.requestSpec,
this.responseSpec, CREATE_GL_ACCOUNT_URL, assetAccountJSON,
GL_ACCOUNT_ID_RESPONSE);
return new Account(accountID, Account.AccountType.ASSET);
}
- public Account createIncomeAccount() {
- final String assetAccountJSON = new
GLAccountBuilder().withAccountTypeAsIncome().build();
+ public Account createIncomeAccount(String accountName) {
+ final String assetAccountJSON = new
GLAccountBuilder().withName(accountName).withAccountTypeAsIncome().build();
final Integer accountID = Utils.performServerPost(this.requestSpec,
this.responseSpec, CREATE_GL_ACCOUNT_URL, assetAccountJSON,
GL_ACCOUNT_ID_RESPONSE);
return new Account(accountID, Account.AccountType.INCOME);
}
- public Account createExpenseAccount() {
- final String assetAccountJSON = new
GLAccountBuilder().withAccountTypeAsExpense().build();
+ public Account createExpenseAccount(String accountName) {
+ final String assetAccountJSON = new
GLAccountBuilder().withName(accountName).withAccountTypeAsExpense().build();
final Integer accountID = Utils.performServerPost(this.requestSpec,
this.responseSpec, CREATE_GL_ACCOUNT_URL, assetAccountJSON,
GL_ACCOUNT_ID_RESPONSE);
return new Account(accountID, Account.AccountType.EXPENSE);
}
- public Account createLiabilityAccount() {
- final String liabilityAccountJSON = new
GLAccountBuilder().withAccountTypeAsLiability().build();
+ public Account createLiabilityAccount(String accountName) {
+ final String liabilityAccountJSON = new
GLAccountBuilder().withName(accountName).withAccountTypeAsLiability().build();
final Integer accountID = Utils.performServerPost(this.requestSpec,
this.responseSpec, CREATE_GL_ACCOUNT_URL, liabilityAccountJSON,
GL_ACCOUNT_ID_RESPONSE);
return new Account(accountID, Account.AccountType.LIABILITY);
}
- public Account createEquityAccount() {
- final String equityAccountJSON = new
GLAccountBuilder().withAccountTypeAsAsEquity().build();
+ public Account createEquityAccount(String accountName) {
+ final String equityAccountJSON = new
GLAccountBuilder().withName(accountName).withAccountTypeAsAsEquity().build();
final Integer accountID = Utils.performServerPost(this.requestSpec,
this.responseSpec, CREATE_GL_ACCOUNT_URL, equityAccountJSON,
GL_ACCOUNT_ID_RESPONSE);
return new Account(accountID, Account.AccountType.EQUITY);
diff --git
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/accounting/GLAccountBuilder.java
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/accounting/GLAccountBuilder.java
index 9edec639f..9a675d159 100644
---
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/accounting/GLAccountBuilder.java
+++
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/accounting/GLAccountBuilder.java
@@ -21,6 +21,7 @@ package
org.apache.fineract.integrationtests.common.accounting;
import com.google.gson.Gson;
import java.util.Calendar;
import java.util.HashMap;
+import org.apache.commons.lang3.StringUtils;
import org.apache.fineract.integrationtests.common.Utils;
public class GLAccountBuilder {
@@ -86,6 +87,13 @@ public class GLAccountBuilder {
return this;
}
+ public GLAccountBuilder withName(String name) {
+ if (StringUtils.isNotBlank(name)) {
+ this.name = Utils.uniqueRandomStringGenerator(name + "_", 5);
+ }
+ return this;
+ }
+
public GLAccountBuilder withAccountUsageAsHeader() {
accountUsage = ACCOUNT_USAGE_HEADER;
return this;
diff --git
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanProductTestBuilder.java
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanProductTestBuilder.java
index a5973d554..7fd2529f4 100644
---
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanProductTestBuilder.java
+++
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanProductTestBuilder.java
@@ -25,6 +25,8 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
+import lombok.Builder;
import org.apache.fineract.client.models.AdvancedPaymentData;
import org.apache.fineract.client.models.CreditAllocationData;
import org.apache.fineract.integrationtests.common.Utils;
@@ -69,10 +71,10 @@ public class LoanProductTestBuilder {
public static final String RECALCULATION_COMPOUNDING_METHOD_FEE = "2";
public static final String
RECALCULATION_COMPOUNDING_METHOD_INTEREST_AND_FEE = "3";
- private static final String NONE = "1";
- private static final String CASH_BASED = "2";
- private static final String ACCRUAL_PERIODIC = "3";
- private static final String ACCRUAL_UPFRONT = "4";
+ public static final String NONE = "1";
+ public static final String CASH_BASED = "2";
+ public static final String ACCRUAL_PERIODIC = "3";
+ public static final String ACCRUAL_UPFRONT = "4";
public static final String INTEREST_APPLICABLE_STRATEGY_REST_DATE = "2";
public static final String INTEREST_APPLICABLE_STRATEGY_ON_PRE_CLOSE_DATE
= "1";
@@ -157,6 +159,7 @@ public class LoanProductTestBuilder {
private Integer repaymentStartDateType = null;
private String loanScheduleType = LoanScheduleType.CUMULATIVE.name();
private String loanScheduleProcessingType =
LoanScheduleProcessingType.HORIZONTAL.name();
+ private FullAccountingConfig fullAccountingConfig;
public String build() {
final HashMap<String, Object> map = build(null, null);
@@ -231,7 +234,9 @@ public class LoanProductTestBuilder {
map.put("outstandingLoanBalance", this.outstandingLoanBalance);
}
- if (this.accountingRule.equals(ACCRUAL_UPFRONT) ||
this.accountingRule.equals(ACCRUAL_PERIODIC)) {
+ if (this.fullAccountingConfig != null) {
+ map.putAll(this.fullAccountingConfig.toMap());
+ } else if (this.accountingRule.equals(ACCRUAL_UPFRONT) ||
this.accountingRule.equals(ACCRUAL_PERIODIC)) {
map.putAll(getAccountMappingForAccrualBased(this.feeAndPenaltyAssetAccount));
} else if (this.accountingRule.equals(CASH_BASED)) {
map.putAll(getAccountMappingForCashBased());
@@ -487,6 +492,13 @@ public class LoanProductTestBuilder {
return this;
}
+ public LoanProductTestBuilder withFullAccountingConfig(String
accountingRule, FullAccountingConfig fullAccountingConfig) {
+ this.accountingRule = accountingRule;
+ this.fullAccountingConfig = fullAccountingConfig;
+ this.accountList = null;
+ return this;
+ }
+
private Map<String, String> getAccountMappingForCashBased() {
final Map<String, String> map = new HashMap<>();
for (int i = 0; i < this.accountList.length; i++) {
@@ -768,4 +780,78 @@ public class LoanProductTestBuilder {
return transactionProcessingStrategyCode;
}
+ @Builder
+ public static class FullAccountingConfig {
+
+ private final Long fundSourceAccountId;
+ private final Long loanPortfolioAccountId;
+ private final Long transfersInSuspenseAccountId;
+ private final Long interestOnLoanAccountId;
+ private final Long incomeFromFeeAccountId;
+ private final Long incomeFromPenaltyAccountId;
+ private final Long incomeFromRecoveryAccountId;
+ private final Long writeOffAccountId;
+ private final Long overpaymentLiabilityAccountId;
+ private final Long receivableInterestAccountId;
+ private final Long receivableFeeAccountId;
+ private final Long receivablePenaltyAccountId;
+ private final Long goodwillCreditAccountId;
+ private final Long incomeFromGoodwillCreditInterestAccountId;
+ private final Long incomeFromGoodwillCreditFeesAccountId;
+ private final Long incomeFromGoodwillCreditPenaltyAccountId;
+ private final Long incomeFromChargeOffInterestAccountId;
+ private final Long incomeFromChargeOffFeesAccountId;
+ private final Long chargeOffExpenseAccountId;
+ private final Long chargeOffFraudExpenseAccountId;
+ private final Long incomeFromChargeOffPenaltyAccountId;
+ private final Long accountingRule;
+
+ public Map<String, String> toMap() {
+ Map<String, String> map = new HashMap<>();
+ Optional.ofNullable(fundSourceAccountId)
+ .ifPresent(fundSourceAccountId ->
map.put("fundSourceAccountId", Long.toString(fundSourceAccountId)));
+ Optional.ofNullable(loanPortfolioAccountId)
+ .ifPresent(loanPortfolioAccountId ->
map.put("loanPortfolioAccountId", Long.toString(loanPortfolioAccountId)));
+ Optional.ofNullable(transfersInSuspenseAccountId).ifPresent(
+ transfersInSuspenseAccountId ->
map.put("transfersInSuspenseAccountId",
Long.toString(transfersInSuspenseAccountId)));
+ Optional.ofNullable(interestOnLoanAccountId)
+ .ifPresent(interestOnLoanAccountId ->
map.put("interestOnLoanAccountId", Long.toString(interestOnLoanAccountId)));
+ Optional.ofNullable(incomeFromFeeAccountId)
+ .ifPresent(incomeFromFeeAccountId ->
map.put("incomeFromFeeAccountId", Long.toString(incomeFromFeeAccountId)));
+ Optional.ofNullable(incomeFromPenaltyAccountId).ifPresent(
+ incomeFromPenaltyAccountId ->
map.put("incomeFromPenaltyAccountId",
Long.toString(incomeFromPenaltyAccountId)));
+ Optional.ofNullable(incomeFromRecoveryAccountId).ifPresent(
+ incomeFromRecoveryAccountId ->
map.put("incomeFromRecoveryAccountId",
Long.toString(incomeFromRecoveryAccountId)));
+ Optional.ofNullable(writeOffAccountId)
+ .ifPresent(writeOffAccountId ->
map.put("writeOffAccountId", Long.toString(writeOffAccountId)));
+
Optional.ofNullable(overpaymentLiabilityAccountId).ifPresent(overpaymentLiabilityAccountId
-> map
+ .put("overpaymentLiabilityAccountId",
Long.toString(overpaymentLiabilityAccountId)));
+ Optional.ofNullable(receivableInterestAccountId).ifPresent(
+ receivableInterestAccountId ->
map.put("receivableInterestAccountId",
Long.toString(receivableInterestAccountId)));
+ Optional.ofNullable(receivableFeeAccountId)
+ .ifPresent(receivableFeeAccountId ->
map.put("receivableFeeAccountId", Long.toString(receivableFeeAccountId)));
+ Optional.ofNullable(receivablePenaltyAccountId).ifPresent(
+ receivablePenaltyAccountId ->
map.put("receivablePenaltyAccountId",
Long.toString(receivablePenaltyAccountId)));
+ Optional.ofNullable(goodwillCreditAccountId)
+ .ifPresent(goodwillCreditAccountId ->
map.put("goodwillCreditAccountId", Long.toString(goodwillCreditAccountId)));
+
Optional.ofNullable(incomeFromGoodwillCreditInterestAccountId).ifPresent(incomeFromGoodwillCreditInterestAccountId
-> map
+ .put("incomeFromGoodwillCreditInterestAccountId",
Long.toString(incomeFromGoodwillCreditInterestAccountId)));
+
Optional.ofNullable(incomeFromGoodwillCreditFeesAccountId).ifPresent(incomeFromGoodwillCreditFeesAccountId
-> map
+ .put("incomeFromGoodwillCreditFeesAccountId",
Long.toString(incomeFromGoodwillCreditFeesAccountId)));
+
Optional.ofNullable(incomeFromGoodwillCreditPenaltyAccountId).ifPresent(incomeFromGoodwillCreditPenaltyAccountId
-> map
+ .put("incomeFromGoodwillCreditPenaltyAccountId",
Long.toString(incomeFromGoodwillCreditPenaltyAccountId)));
+
Optional.ofNullable(incomeFromChargeOffInterestAccountId).ifPresent(incomeFromChargeOffInterestAccountId
-> map
+ .put("incomeFromChargeOffInterestAccountId",
Long.toString(incomeFromChargeOffInterestAccountId)));
+
Optional.ofNullable(incomeFromChargeOffFeesAccountId).ifPresent(incomeFromChargeOffFeesAccountId
-> map
+ .put("incomeFromChargeOffFeesAccountId",
Long.toString(incomeFromChargeOffFeesAccountId)));
+ Optional.ofNullable(chargeOffExpenseAccountId)
+ .ifPresent(chargeOffExpenseAccountId ->
map.put("chargeOffExpenseAccountId", Long.toString(chargeOffExpenseAccountId)));
+
Optional.ofNullable(chargeOffFraudExpenseAccountId).ifPresent(chargeOffFraudExpenseAccountId
-> map
+ .put("chargeOffFraudExpenseAccountId",
Long.toString(chargeOffFraudExpenseAccountId)));
+
Optional.ofNullable(incomeFromChargeOffPenaltyAccountId).ifPresent(incomeFromChargeOffPenaltyAccountId
-> map
+ .put("incomeFromChargeOffPenaltyAccountId",
Long.toString(incomeFromChargeOffPenaltyAccountId)));
+ return map;
+ }
+ }
+
}