FINERACT-2042 Chargeback with credit allocation, accounting

This commit is contained in:
Peter Bagrij
2024-03-07 11:34:48 +01:00
committed by Peter Bagrij
parent 5f9845f86a
commit 697449e7e7
15 changed files with 960 additions and 308 deletions
@@ -35,6 +35,7 @@ import java.util.HashSet;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.Set; import java.util.Set;
import org.apache.fineract.infrastructure.core.domain.AbstractAuditableWithUTCDateTimeCustom; import org.apache.fineract.infrastructure.core.domain.AbstractAuditableWithUTCDateTimeCustom;
import org.apache.fineract.infrastructure.core.domain.ExternalId; import org.apache.fineract.infrastructure.core.domain.ExternalId;
@@ -763,7 +764,14 @@ public class LoanTransaction extends AbstractAuditableWithUTCDateTimeCustom {
thisTransactionData.put("currencyCode", currencyCode); thisTransactionData.put("currencyCode", currencyCode);
thisTransactionData.put("amount", this.amount); thisTransactionData.put("amount", this.amount);
thisTransactionData.put("netDisbursalAmount", this.loan.getNetDisbursalAmount()); 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("interestPortion", this.interestPortion);
thisTransactionData.put("feeChargesPortion", this.feeChargesPortion); thisTransactionData.put("feeChargesPortion", this.feeChargesPortion);
thisTransactionData.put("penaltyChargesPortion", this.penaltyChargesPortion); thisTransactionData.put("penaltyChargesPortion", this.penaltyChargesPortion);
@@ -790,6 +798,26 @@ public class LoanTransaction extends AbstractAuditableWithUTCDateTimeCustom {
thisTransactionData.put("loanChargesPaid", loanChargesPaidData); 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() LoanTransactionRelation loanTransactionRelation = loanTransactionRelations.stream()
.filter(e -> LoanTransactionRelationTypeEnum.CHARGE_ADJUSTMENT.equals(e.getRelationType())).findAny().orElse(null); .filter(e -> LoanTransactionRelationTypeEnum.CHARGE_ADJUSTMENT.equals(e.getRelationType())).findAny().orElse(null);
if (loanTransactionRelation != null) { if (loanTransactionRelation != null) {
@@ -60,4 +60,9 @@ public class LoanTransactionDTO {
private final String chargeRefundChargeType; private final String chargeRefundChargeType;
private final LoanChargeData loanChargeData; 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;
} }
@@ -156,9 +156,15 @@ public class AccountingProcessorHelper {
isAccountTransfer = this.accountTransfersReadPlatformService.isAccountTransfer(Long.parseLong(transactionId), isAccountTransfer = this.accountTransfersReadPlatformService.isAccountTransfer(Long.parseLong(transactionId),
PortfolioAccountType.LOAN); 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, final LoanTransactionDTO transaction = new LoanTransactionDTO(transactionOfficeId, paymentTypeId, transactionId,
transactionDate, transactionType, amount, principal, interest, fees, penalties, overPayments, reversed, 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"); Boolean isLoanToLoanTransfer = (Boolean) accountingBridgeData.get("isLoanToLoanTransfer");
transaction.setLoanToLoanTransfer(isLoanToLoanTransfer != null && isLoanToLoanTransfer); transaction.setLoanToLoanTransfer(isLoanToLoanTransfer != null && isLoanToLoanTransfer);
newLoanTransactions.add(transaction); newLoanTransactions.add(transaction);
@@ -430,25 +430,54 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
final BigDecimal overpaidAmount = Objects.isNull(loanTransactionDTO.getOverPayment()) ? BigDecimal.ZERO final BigDecimal overpaidAmount = Objects.isNull(loanTransactionDTO.getOverPayment()) ? BigDecimal.ZERO
: loanTransactionDTO.getOverPayment(); : loanTransactionDTO.getOverPayment();
if (BigDecimal.ZERO.compareTo(overpaidAmount) == 0) { // when no overpay final BigDecimal principalCredited = Objects.isNull(loanTransactionDTO.getPrincipal()) ? BigDecimal.ZERO
helper.createJournalEntriesAndReversalsForLoan(office, currencyCode, AccrualAccountsForLoan.LOAN_PORTFOLIO.getValue(), : loanTransactionDTO.getPrincipal();
AccrualAccountsForLoan.FUND_SOURCE.getValue(), loanProductId, paymentTypeId, loanId, transactionId, transactionDate, final BigDecimal feeCredited = Objects.isNull(loanTransactionDTO.getFees()) ? BigDecimal.ZERO : loanTransactionDTO.getFees();
amount, isReversal); final BigDecimal penaltyCredited = Objects.isNull(loanTransactionDTO.getPenalties()) ? BigDecimal.ZERO
} else if (overpaidAmount.compareTo(amount) >= 0) { // when the overpay amount is matching with the normal : loanTransactionDTO.getPenalties();
// amount
helper.createJournalEntriesAndReversalsForLoan(office, currencyCode, AccrualAccountsForLoan.OVERPAYMENT.getValue(), final BigDecimal principalPaid = Objects.isNull(loanTransactionDTO.getPrincipalPaid()) ? BigDecimal.ZERO
AccrualAccountsForLoan.FUND_SOURCE.getValue(), loanProductId, paymentTypeId, loanId, transactionId, transactionDate, : loanTransactionDTO.getPrincipalPaid();
amount, isReversal); final BigDecimal feePaid = Objects.isNull(loanTransactionDTO.getFeePaid()) ? BigDecimal.ZERO : loanTransactionDTO.getFeePaid();
} else { final BigDecimal penaltyPaid = Objects.isNull(loanTransactionDTO.getPenaltyPaid()) ? BigDecimal.ZERO
BigDecimal diff = amount.subtract(overpaidAmount); : loanTransactionDTO.getPenaltyPaid();
helper.createDebitJournalEntryOrReversalForLoan(office, currencyCode, AccrualAccountsForLoan.LOAN_PORTFOLIO.getValue(),
loanProductId, paymentTypeId, loanId, transactionId, transactionDate, diff, isReversal); helper.createCreditJournalEntryOrReversalForLoan(office, currencyCode, AccrualAccountsForLoan.FUND_SOURCE, loanProductId,
helper.createCreditJournalEntryOrReversalForLoan(office, currencyCode, AccrualAccountsForLoan.FUND_SOURCE, loanProductId, paymentTypeId, loanId, transactionId, transactionDate, amount, isReversal);
paymentTypeId, loanId, transactionId, transactionDate, amount, isReversal);
if (overpaidAmount.compareTo(BigDecimal.ZERO) > 0) {
helper.createDebitJournalEntryOrReversalForLoan(office, currencyCode, AccrualAccountsForLoan.OVERPAYMENT.getValue(), helper.createDebitJournalEntryOrReversalForLoan(office, currencyCode, AccrualAccountsForLoan.OVERPAYMENT.getValue(),
loanProductId, paymentTypeId, loanId, transactionId, transactionDate, overpaidAmount, isReversal); 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);
}
} }
/** /**
@@ -3194,13 +3194,13 @@ public class AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
); );
// verify journal entries // verify journal entries
verifyJournalEntries(loanResponse.getLoanId(), journalEntry(100.0, loansReceivableAccount, "DEBIT"), // verifyJournalEntries(loanResponse.getLoanId(), journalEntry(100.0, loansReceivableAccount, "DEBIT"), //
journalEntry(100.0, suspenseClearingAccount, "CREDIT"), // journalEntry(100.0, fundSource, "CREDIT"), //
journalEntry(100.0, loansReceivableAccount, "CREDIT"), // journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
journalEntry(50.0, overpaymentAccount, "CREDIT"), // journalEntry(50.0, overpaymentAccount, "CREDIT"), //
journalEntry(150.0, suspenseClearingAccount, "DEBIT"), // journalEntry(150.0, fundSource, "DEBIT"), //
journalEntry(50.0, loansReceivableAccount, "DEBIT"), // journalEntry(50.0, loansReceivableAccount, "DEBIT"), //
journalEntry(50.0, overpaymentAccount, "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 // verify journal entries
verifyJournalEntries(loanResponse.getLoanId(), journalEntry(100.0, loansReceivableAccount, "DEBIT"), // verifyJournalEntries(loanResponse.getLoanId(), journalEntry(100.0, loansReceivableAccount, "DEBIT"), //
journalEntry(100.0, suspenseClearingAccount, "CREDIT"), // journalEntry(100.0, fundSource, "CREDIT"), //
journalEntry(100.0, loansReceivableAccount, "CREDIT"), // journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
journalEntry(50.0, overpaymentAccount, "CREDIT"), // journalEntry(50.0, overpaymentAccount, "CREDIT"), //
journalEntry(150.0, suspenseClearingAccount, "DEBIT"), // journalEntry(150.0, fundSource, "DEBIT"), //
journalEntry(28.0, overpaymentAccount, "DEBIT"), // journalEntry(28.0, overpaymentAccount, "DEBIT"), //
journalEntry(28.0, suspenseClearingAccount, "CREDIT") // journalEntry(28.0, fundSource, "CREDIT") //
); );
}); });
} }
@@ -72,6 +72,7 @@ import org.apache.fineract.integrationtests.common.BatchHelper;
import org.apache.fineract.integrationtests.common.BusinessDateHelper; import org.apache.fineract.integrationtests.common.BusinessDateHelper;
import org.apache.fineract.integrationtests.common.ClientHelper; import org.apache.fineract.integrationtests.common.ClientHelper;
import org.apache.fineract.integrationtests.common.GlobalConfigurationHelper; 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.Utils;
import org.apache.fineract.integrationtests.common.accounting.Account; import org.apache.fineract.integrationtests.common.accounting.Account;
import org.apache.fineract.integrationtests.common.accounting.AccountHelper; import org.apache.fineract.integrationtests.common.accounting.AccountHelper;
@@ -114,6 +115,7 @@ public abstract class BaseLoanIntegrationTest {
protected final LoanProductHelper loanProductHelper = new LoanProductHelper(); protected final LoanProductHelper loanProductHelper = new LoanProductHelper();
protected JournalEntryHelper journalEntryHelper = new JournalEntryHelper(requestSpec, responseSpec); protected JournalEntryHelper journalEntryHelper = new JournalEntryHelper(requestSpec, responseSpec);
protected ClientHelper clientHelper = new ClientHelper(requestSpec, responseSpec); protected ClientHelper clientHelper = new ClientHelper(requestSpec, responseSpec);
protected SchedulerJobHelper schedulerJobHelper = new SchedulerJobHelper(requestSpec);
protected final InlineLoanCOBHelper inlineLoanCOBHelper = new InlineLoanCOBHelper(requestSpec, responseSpec); protected final InlineLoanCOBHelper inlineLoanCOBHelper = new InlineLoanCOBHelper(requestSpec, responseSpec);
protected BusinessDateHelper businessDateHelper = new BusinessDateHelper(); protected BusinessDateHelper businessDateHelper = new BusinessDateHelper();
@@ -123,18 +125,22 @@ public abstract class BaseLoanIntegrationTest {
protected DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(DATETIME_PATTERN); protected DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(DATETIME_PATTERN);
// asset // asset
protected final Account loansReceivableAccount = accountHelper.createAssetAccount(); protected final Account loansReceivableAccount = accountHelper.createAssetAccount("loanPortfolio");
protected final Account interestFeeReceivableAccount = accountHelper.createAssetAccount();
protected final Account suspenseAccount = accountHelper.createAssetAccount(); 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 // liability
protected final Account suspenseClearingAccount = accountHelper.createLiabilityAccount(); protected final Account fundSource = accountHelper.createLiabilityAccount("fundSource");
protected final Account overpaymentAccount = accountHelper.createLiabilityAccount(); protected final Account overpaymentAccount = accountHelper.createLiabilityAccount("overpayment");
// income // income
protected final Account interestIncomeAccount = accountHelper.createIncomeAccount(); protected final Account interestIncomeAccount = accountHelper.createIncomeAccount("interestIncome");
protected final Account feeIncomeAccount = accountHelper.createIncomeAccount(); protected final Account feeIncomeAccount = accountHelper.createIncomeAccount("feeIncome");
protected final Account feeChargeOffAccount = accountHelper.createIncomeAccount(); protected final Account penaltyIncomeAccount = accountHelper.createIncomeAccount("penaltyIncome");
protected final Account recoveriesAccount = accountHelper.createIncomeAccount(); protected final Account feeChargeOffAccount = accountHelper.createIncomeAccount("feeChargeOff");
protected final Account interestIncomeChargeOffAccount = accountHelper.createIncomeAccount(); protected final Account recoveriesAccount = accountHelper.createIncomeAccount("recoveries");
protected final Account interestIncomeChargeOffAccount = accountHelper.createIncomeAccount("interestIncomeChargeOff");
// expense // expense
protected final Account creditLossBadDebtAccount = accountHelper.createExpenseAccount(); protected final Account creditLossBadDebtAccount = accountHelper.createExpenseAccount();
protected final Account creditLossBadDebtFraudAccount = accountHelper.createExpenseAccount(); protected final Account creditLossBadDebtFraudAccount = accountHelper.createExpenseAccount();
@@ -159,6 +165,7 @@ public abstract class BaseLoanIntegrationTest {
.includeInBorrowerCycle(false)// .includeInBorrowerCycle(false)//
.currencyCode("USD")// .currencyCode("USD")//
.digitsAfterDecimal(2)// .digitsAfterDecimal(2)//
.inMultiplesOf(0)//
.installmentAmountInMultiplesOf(1)// .installmentAmountInMultiplesOf(1)//
.useBorrowerCycle(false)// .useBorrowerCycle(false)//
.minPrincipal(100.0)// .minPrincipal(100.0)//
@@ -207,24 +214,18 @@ public abstract class BaseLoanIntegrationTest {
.outstandingLoanBalance(10000.0)// .outstandingLoanBalance(10000.0)//
.charges(Collections.emptyList())// .charges(Collections.emptyList())//
.accountingRule(3)// .accountingRule(3)//
.fundSourceAccountId(suspenseClearingAccount.getAccountID().longValue())// .fundSourceAccountId(fundSource.getAccountID().longValue())//
.loanPortfolioAccountId(loansReceivableAccount.getAccountID().longValue())// .loanPortfolioAccountId(loansReceivableAccount.getAccountID().longValue())//
.transfersInSuspenseAccountId(suspenseAccount.getAccountID().longValue())// .transfersInSuspenseAccountId(suspenseAccount.getAccountID().longValue())//
.interestOnLoanAccountId(interestIncomeAccount.getAccountID().longValue())// .interestOnLoanAccountId(interestIncomeAccount.getAccountID().longValue())//
.incomeFromFeeAccountId(feeIncomeAccount.getAccountID().longValue())// .incomeFromFeeAccountId(feeIncomeAccount.getAccountID().longValue())//
.incomeFromPenaltyAccountId(feeIncomeAccount.getAccountID().longValue())// .incomeFromPenaltyAccountId(penaltyIncomeAccount.getAccountID().longValue())//
.incomeFromRecoveryAccountId(recoveriesAccount.getAccountID().longValue())// .incomeFromRecoveryAccountId(recoveriesAccount.getAccountID().longValue())//
.writeOffAccountId(writtenOffAccount.getAccountID().longValue())// .writeOffAccountId(writtenOffAccount.getAccountID().longValue())//
.overpaymentLiabilityAccountId(overpaymentAccount.getAccountID().longValue())// .overpaymentLiabilityAccountId(overpaymentAccount.getAccountID().longValue())//
.receivableInterestAccountId(interestFeeReceivableAccount.getAccountID().longValue())// .receivableInterestAccountId(interestReceivableAccount.getAccountID().longValue())//
.receivableFeeAccountId(interestFeeReceivableAccount.getAccountID().longValue())// .receivableFeeAccountId(feeReceivableAccount.getAccountID().longValue())//
.receivablePenaltyAccountId(interestFeeReceivableAccount.getAccountID().longValue())// .receivablePenaltyAccountId(penaltyReceivableAccount.getAccountID().longValue())//
.dateFormat(DATETIME_PATTERN)//
.locale("en_GB")//
.disallowExpectedDisbursements(true)//
.allowApprovedDisbursedAmountsOverApplied(true)//
.overAppliedCalculationType("percentage")//
.overAppliedNumber(50)//
.goodwillCreditAccountId(goodwillExpenseAccount.getAccountID().longValue())// .goodwillCreditAccountId(goodwillExpenseAccount.getAccountID().longValue())//
.incomeFromGoodwillCreditInterestAccountId(interestIncomeChargeOffAccount.getAccountID().longValue())// .incomeFromGoodwillCreditInterestAccountId(interestIncomeChargeOffAccount.getAccountID().longValue())//
.incomeFromGoodwillCreditFeesAccountId(feeChargeOffAccount.getAccountID().longValue())// .incomeFromGoodwillCreditFeesAccountId(feeChargeOffAccount.getAccountID().longValue())//
@@ -233,7 +234,12 @@ public abstract class BaseLoanIntegrationTest {
.incomeFromChargeOffFeesAccountId(feeChargeOffAccount.getAccountID().longValue())// .incomeFromChargeOffFeesAccountId(feeChargeOffAccount.getAccountID().longValue())//
.chargeOffExpenseAccountId(creditLossBadDebtAccount.getAccountID().longValue())// .chargeOffExpenseAccountId(creditLossBadDebtAccount.getAccountID().longValue())//
.chargeOffFraudExpenseAccountId(creditLossBadDebtFraudAccount.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() { protected PostLoanProductsRequest createOnePeriod30DaysLongNoInterestPeriodicAccrualProductWithAdvancedPaymentAllocation() {
@@ -344,7 +350,7 @@ public abstract class BaseLoanIntegrationTest {
boolean found = loanDetails.getTransactions().stream().anyMatch(item -> Objects.equals(item.getAmount(), tr.amount) // boolean found = loanDetails.getTransactions().stream().anyMatch(item -> Objects.equals(item.getAmount(), tr.amount) //
&& Objects.equals(item.getType().getValue(), tr.type) // && Objects.equals(item.getType().getValue(), tr.type) //
&& Objects.equals(item.getDate(), LocalDate.parse(tr.date, dateTimeFormatter)) // && 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.getPrincipalPortion(), tr.principalPortion) //
&& Objects.equals(item.getInterestPortion(), tr.interestPortion) // && Objects.equals(item.getInterestPortion(), tr.interestPortion) //
&& Objects.equals(item.getFeeChargesPortion(), tr.feePortion) // && 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) { protected Long addCharge(Long loanId, boolean isPenalty, double amount, String dueDate) {
Integer chargeId = ChargesHelper.createCharges(requestSpec, responseSpec, Integer chargeId = ChargesHelper.createCharges(requestSpec, responseSpec,
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, String.valueOf(amount), isPenalty)); ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, String.valueOf(amount), isPenalty));
@@ -602,9 +620,10 @@ public abstract class BaseLoanIntegrationTest {
return response.getResourceId(); return response.getResourceId();
} }
protected void addChargebackForLoan(Long loanId, Long transactionId, Double amount) { protected Long addChargebackForLoan(Long loanId, Long transactionId, Double amount) {
loanTransactionHelper.chargebackLoanTransaction(loanId, transactionId, PostLoansLoanIdTransactionsResponse response = loanTransactionHelper.chargebackLoanTransaction(loanId, transactionId,
new PostLoansLoanIdTransactionsTransactionIdRequest().locale("en").transactionAmount(amount).paymentTypeId(1L)); new PostLoansLoanIdTransactionsTransactionIdRequest().locale("en").transactionAmount(amount).paymentTypeId(1L));
return response.getResourceId();
} }
protected PostChargesResponse createCharge(Double amount) { 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")); new BusinessDateRequest().type(BUSINESS_DATE.getName()).date(date).dateFormat(DATETIME_PATTERN).locale("en"));
} }
protected Journal journalEntry(double principalAmount, Account account, String type) { protected Long getTransactionId(Long loanId, String type, String date) {
return new Journal(principalAmount, account, type); 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) { protected Transaction transaction(double principalAmount, String type, String date) {
@@ -639,16 +672,16 @@ public abstract class BaseLoanIntegrationTest {
return new Transaction(principalAmount, type, date, true); 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) { 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); 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, double interestPortion, double feePortion, double penaltyPortion, double unrecognizedIncomePortion, double overpaymentPortion,
boolean reversed) { 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); unrecognizedIncomePortion, overpaymentPortion, reversed);
} }
@@ -765,7 +798,7 @@ public abstract class BaseLoanIntegrationTest {
Double amount; Double amount;
String type; String type;
String date; String date;
Double outstandingAmount; Double outstandingPrincipal;
Double principalPortion; Double principalPortion;
Double interestPortion; Double interestPortion;
Double feePortion; Double feePortion;
@@ -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, private void verifyLoanSummaryAmounts(Long loanId, double creditedPrincipal, double creditedFee, double creditedPenalty,
double totalOutstanding) { double totalOutstanding) {
GetLoansLoanIdResponse loanResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId.intValue()); GetLoansLoanIdResponse loanResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId.intValue());
@@ -1023,10 +1472,10 @@ public class LoanChargebackWithCreditAllocationsIntegrationTests extends BaseLoa
} }
@Nullable @Nullable
private Long applyAndApproveLoan(Long clientId, Long loanProductId) { private Long applyAndApproveLoan(Long clientId, Long loanProductId, int numberOfRepayments) {
PostLoansRequest applicationRequest = applyLoanRequest(clientId, loanProductId, "01 January 2023", 1250.0, 4)// PostLoansRequest applicationRequest = applyLoanRequest(clientId, loanProductId, "01 January 2023", 1250.0, numberOfRepayments)//
.repaymentEvery(1)// .repaymentEvery(1)//
.loanTermFrequency(4)// .loanTermFrequency(numberOfRepayments)//
.repaymentFrequencyType(RepaymentFrequencyType.MONTHS)// .repaymentFrequencyType(RepaymentFrequencyType.MONTHS)//
.loanTermFrequencyType(RepaymentFrequencyType.MONTHS)// .loanTermFrequencyType(RepaymentFrequencyType.MONTHS)//
.transactionProcessingStrategyCode("advanced-payment-allocation-strategy"); .transactionProcessingStrategyCode("advanced-payment-allocation-strategy");
@@ -1036,8 +1485,12 @@ public class LoanChargebackWithCreditAllocationsIntegrationTests extends BaseLoa
PostLoansLoanIdResponse approvedLoanResult = loanTransactionHelper.approveLoan(postLoansResponse.getResourceId(), PostLoansLoanIdResponse approvedLoanResult = loanTransactionHelper.approveLoan(postLoansResponse.getResourceId(),
approveLoanRequest(1250.0, "01 January 2023")); approveLoanRequest(1250.0, "01 January 2023"));
Long loanId = approvedLoanResult.getLoanId(); return approvedLoanResult.getLoanId();
return loanId; }
@Nullable
private Long applyAndApproveLoan(Long clientId, Long loanProductId) {
return applyAndApproveLoan(clientId, loanProductId, 4);
} }
public Long createLoanProduct(AdvancedPaymentData defaultAllocation, CreditAllocationData creditAllocationData) { public Long createLoanProduct(AdvancedPaymentData defaultAllocation, CreditAllocationData creditAllocationData) {
@@ -23,7 +23,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNotNull;
import java.math.BigDecimal; import java.math.BigDecimal;
import org.apache.fineract.client.models.GetJournalEntriesTransactionIdResponse;
import org.apache.fineract.client.models.GetLoanProductsProductIdResponse; import org.apache.fineract.client.models.GetLoanProductsProductIdResponse;
import org.apache.fineract.client.models.GetLoansLoanIdTransactionsTransactionIdResponse; import org.apache.fineract.client.models.GetLoansLoanIdTransactionsTransactionIdResponse;
import org.apache.fineract.client.models.PostLoanProductsRequest; import org.apache.fineract.client.models.PostLoanProductsRequest;
@@ -88,15 +87,10 @@ public class LoanDownPaymentTransactionChargebackTest extends BaseLoanIntegratio
); );
// verify journal entries for chargeback transaction // verify journal entries for chargeback transaction
GetJournalEntriesTransactionIdResponse journalEntries = journalEntryHelper verifyTRJournalEntries(chargebackTransactionId, //
.getJournalEntries("L" + chargebackTransactionId.toString()); credit(fundSource, 50.0), //
assertEquals(2L, journalEntries.getTotalFilteredRecords()); debit(loansReceivableAccount, 50.0) //
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());
}); });
} }
@@ -152,15 +146,10 @@ public class LoanDownPaymentTransactionChargebackTest extends BaseLoanIntegratio
); );
// verify journal entries for chargeback transaction // verify journal entries for chargeback transaction
GetJournalEntriesTransactionIdResponse journalEntries = journalEntryHelper verifyTRJournalEntries(chargebackTransactionId, //
.getJournalEntries("L" + chargebackTransactionId.toString()); credit(fundSource, 50.0), //
assertEquals(2L, journalEntries.getTotalFilteredRecords()); debit(loansReceivableAccount, 50.0) //
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());
}); });
} }
@@ -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(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) // 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"), // verifyJournalEntries(loanResponse.getResourceId(), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), // journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, fundSource, "CREDIT"), //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), // journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
journalEntry(250.0, suspenseClearingAccount, "DEBIT") // journalEntry(250.0, fundSource, "DEBIT") //
); );
loanTransactionHelper.makeLoanRepayment(loanResponse.getResourceId(), new PostLoansLoanIdTransactionsRequest() 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(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) // 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"), // verifyJournalEntries(loanResponse.getResourceId(), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), // journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, fundSource, "CREDIT"), //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), // journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
journalEntry(250.0, suspenseClearingAccount, "DEBIT") // journalEntry(250.0, fundSource, "DEBIT") //
); );
String externalId = UUID.randomUUID().toString(); String externalId = UUID.randomUUID().toString();
@@ -74,9 +74,9 @@ public class LoanRescheduleTestWithDownpayment extends BaseLoanIntegrationTest {
// verify journal entries // verify journal entries
verifyJournalEntries(loanId, journalEntry(250.0, loansReceivableAccount, "CREDIT"), // 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, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT") // journalEntry(1000.0, fundSource, "CREDIT") //
); );
// Verify Repayment Schedule // Verify Repayment Schedule
@@ -18,6 +18,7 @@
*/ */
package org.apache.fineract.integrationtests; 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.integrationtests.common.loans.LoanProductTestBuilder.DEFAULT_STRATEGY;
import static org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.impl.AdvancedPaymentScheduleTransactionProcessor.ADVANCED_PAYMENT_ALLOCATION_STRATEGY; import static org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.impl.AdvancedPaymentScheduleTransactionProcessor.ADVANCED_PAYMENT_ALLOCATION_STRATEGY;
import static org.junit.jupiter.api.Assertions.assertEquals; 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.AdvancedPaymentData;
import org.apache.fineract.client.models.GetDelinquencyBucketsResponse; import org.apache.fineract.client.models.GetDelinquencyBucketsResponse;
import org.apache.fineract.client.models.GetDelinquencyRangesResponse; 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.GetLoanProductsProductIdResponse;
import org.apache.fineract.client.models.GetLoansLoanIdRepaymentPeriod; import org.apache.fineract.client.models.GetLoansLoanIdRepaymentPeriod;
import org.apache.fineract.client.models.GetLoansLoanIdRepaymentSchedule; 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.ClientHelper;
import org.apache.fineract.integrationtests.common.GlobalConfigurationHelper; import org.apache.fineract.integrationtests.common.GlobalConfigurationHelper;
import org.apache.fineract.integrationtests.common.Utils; 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.AccountHelper;
import org.apache.fineract.integrationtests.common.accounting.JournalEntryHelper; import org.apache.fineract.integrationtests.common.accounting.JournalEntryHelper;
import org.apache.fineract.integrationtests.common.loans.LoanApplicationTestBuilder; import org.apache.fineract.integrationtests.common.loans.LoanApplicationTestBuilder;
@@ -72,7 +71,7 @@ import org.junit.jupiter.params.provider.MethodSource;
@Slf4j @Slf4j
@ExtendWith(LoanTestLifecycleExtension.class) @ExtendWith(LoanTestLifecycleExtension.class)
public class LoanTransactionChargebackTest { public class LoanTransactionChargebackTest extends BaseLoanIntegrationTest {
private ResponseSpecification responseSpec; private ResponseSpecification responseSpec;
private ResponseSpecification responseSpecErr400; private ResponseSpecification responseSpecErr400;
@@ -139,14 +138,10 @@ public class LoanTransactionChargebackTest {
loanTransactionHelper.validateLoanPrincipalOustandingBalance(getLoansLoanIdResponse, amount.doubleValue()); loanTransactionHelper.validateLoanPrincipalOustandingBalance(getLoansLoanIdResponse, amount.doubleValue());
GetJournalEntriesTransactionIdResponse journalEntries = journalEntryHelper verifyTRJournalEntries(chargebackTransactionId, //
.getJournalEntries("L" + chargebackTransactionId.toString()); credit(fundSource, 1000.0), //
assertEquals(2L, journalEntries.getTotalFilteredRecords()); debit(loansReceivableAccount, 1000.0) //
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());
// Try to reverse a Loan Transaction charge back // Try to reverse a Loan Transaction charge back
PostLoansLoanIdTransactionsResponse reverseTransactionResponse = loanTransactionHelper.reverseLoanTransaction(loanId, PostLoansLoanIdTransactionsResponse reverseTransactionResponse = loanTransactionHelper.reverseLoanTransaction(loanId,
@@ -431,17 +426,11 @@ public class LoanTransactionChargebackTest {
assertEquals(getLoansLoanIdResponse.getTimeline().getExpectedMaturityDate(), assertEquals(getLoansLoanIdResponse.getTimeline().getExpectedMaturityDate(),
getLoansLoanIdResponse.getTimeline().getActualMaturityDate()); getLoansLoanIdResponse.getTimeline().getActualMaturityDate());
GetJournalEntriesTransactionIdResponse journalEntries = journalEntryHelper verifyTRJournalEntries(chargebackTransactionId, //
.getJournalEntries("L" + chargebackTransactionId.toString()); credit(fundSource, 200.0), //
assertEquals(3L, journalEntries.getTotalFilteredRecords()); debit(loansReceivableAccount, 100.0), //
assertEquals(100.0, journalEntries.getPageItems().get(0).getAmount()); debit(overpaymentAccount, 100.0) //
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());
final GetDelinquencyRangesResponse delinquencyRange = getLoansLoanIdResponse.getDelinquencyRange(); final GetDelinquencyRangesResponse delinquencyRange = getLoansLoanIdResponse.getDelinquencyRange();
assertNull(delinquencyRange); assertNull(delinquencyRange);
@@ -525,14 +514,10 @@ public class LoanTransactionChargebackTest {
loanTransactionHelper.validateLoanPrincipalOustandingBalance(getLoansLoanIdResponse, Double.valueOf("0.00")); loanTransactionHelper.validateLoanPrincipalOustandingBalance(getLoansLoanIdResponse, Double.valueOf("0.00"));
GetJournalEntriesTransactionIdResponse journalEntries = journalEntryHelper verifyTRJournalEntries(chargebackTransactionId, //
.getJournalEntries("L" + chargebackTransactionId.toString()); credit(fundSource, 50.0), //
assertEquals(2L, journalEntries.getTotalFilteredRecords()); debit(overpaymentAccount, 50.0) //
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());
} }
@ParameterizedTest @ParameterizedTest
@@ -632,12 +617,20 @@ public class LoanTransactionChargebackTest {
final Integer delinquencyBucketId, final boolean withJournalEntries, LoanProductTestBuilder loanProductTestBuilder) { final Integer delinquencyBucketId, final boolean withJournalEntries, LoanProductTestBuilder loanProductTestBuilder) {
final HashMap<String, Object> loanProductMap; final HashMap<String, Object> loanProductMap;
if (withJournalEntries) { if (withJournalEntries) {
final Account assetAccount = accountHelper.createAssetAccount();
final Account expenseAccount = accountHelper.createExpenseAccount();
final Account incomeAccount = accountHelper.createIncomeAccount();
final Account overpaymentAccount = accountHelper.createLiabilityAccount();
loanProductMap = loanProductTestBuilder 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); .build(null, delinquencyBucketId);
} else { } else {
loanProductMap = loanProductTestBuilder.build(null, delinquencyBucketId); loanProductMap = loanProductTestBuilder.build(null, delinquencyBucketId);
@@ -69,9 +69,9 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries // verify journal entries
verifyJournalEntries(loanId, // verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), // journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
journalEntry(250.0, suspenseClearingAccount, "DEBIT"), // journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), // journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT") // journalEntry(1000.0, fundSource, "CREDIT") //
); );
// Verify Repayment Schedule // Verify Repayment Schedule
@@ -91,14 +91,14 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
verifyJournalEntries(loanId, verifyJournalEntries(loanId,
// original entries // original entries
journalEntry(250.0, loansReceivableAccount, "CREDIT"), // journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
journalEntry(250.0, suspenseClearingAccount, "DEBIT"), // journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), // journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), // journalEntry(1000.0, fundSource, "CREDIT"), //
// original entries reverted // original entries reverted
journalEntry(250.0, loansReceivableAccount, "DEBIT"), // journalEntry(250.0, loansReceivableAccount, "DEBIT"), //
journalEntry(250.0, suspenseClearingAccount, "CREDIT"), // journalEntry(250.0, fundSource, "CREDIT"), //
journalEntry(1000.0, loansReceivableAccount, "CREDIT"), // journalEntry(1000.0, loansReceivableAccount, "CREDIT"), //
journalEntry(1000.0, suspenseClearingAccount, "DEBIT")); // journalEntry(1000.0, fundSource, "DEBIT")); //
verifyRepaymentSchedule(loanId, // verifyRepaymentSchedule(loanId, //
installment(1000.0, null, "01 January 2023"), // installment(1000.0, null, "01 January 2023"), //
@@ -139,9 +139,9 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries // verify journal entries
verifyJournalEntries(loanId, // verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), // journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
journalEntry(250.0, suspenseClearingAccount, "DEBIT"), // journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), // journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT") // journalEntry(1000.0, fundSource, "CREDIT") //
); );
// make a repayment // make a repayment
@@ -164,23 +164,23 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
verifyJournalEntries(loanId, // verifyJournalEntries(loanId, //
// original entries down-payment // original entries down-payment
journalEntry(250.0, loansReceivableAccount, "CREDIT"), // journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
journalEntry(250.0, suspenseClearingAccount, "DEBIT"), // journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), // journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), // journalEntry(1000.0, fundSource, "CREDIT"), //
// repayment entries // repayment entries
journalEntry(100.0, loansReceivableAccount, "CREDIT"), // journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
journalEntry(100.0, suspenseClearingAccount, "DEBIT"), // journalEntry(100.0, fundSource, "DEBIT"), //
// original entries compensated // original entries compensated
journalEntry(250.0, loansReceivableAccount, "DEBIT"), // journalEntry(250.0, loansReceivableAccount, "DEBIT"), //
journalEntry(250.0, suspenseClearingAccount, "CREDIT"), // journalEntry(250.0, fundSource, "CREDIT"), //
journalEntry(1000.0, loansReceivableAccount, "CREDIT"), // journalEntry(1000.0, loansReceivableAccount, "CREDIT"), //
journalEntry(1000.0, suspenseClearingAccount, "DEBIT"), // journalEntry(1000.0, fundSource, "DEBIT"), //
// repayment entries compensated // repayment entries compensated
journalEntry(250.0, loansReceivableAccount, "DEBIT"), // journalEntry(250.0, loansReceivableAccount, "DEBIT"), //
journalEntry(250.0, suspenseClearingAccount, "CREDIT") // journalEntry(250.0, fundSource, "CREDIT") //
); );
verifyRepaymentSchedule(loanId, // verifyRepaymentSchedule(loanId, //
@@ -225,9 +225,9 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries // verify journal entries
verifyJournalEntries(loanId, // verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), // journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
journalEntry(250.0, suspenseClearingAccount, "DEBIT"), // journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), // journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT") // journalEntry(1000.0, fundSource, "CREDIT") //
); );
// undoDisbursal // undoDisbursal
@@ -240,15 +240,15 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
verifyJournalEntries(loanId, // verifyJournalEntries(loanId, //
// original entries // original entries
journalEntry(250.0, loansReceivableAccount, "CREDIT"), // journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
journalEntry(250.0, suspenseClearingAccount, "DEBIT"), // journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), // journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), // journalEntry(1000.0, fundSource, "CREDIT"), //
// original entries are compensated // original entries are compensated
journalEntry(250.0, loansReceivableAccount, "DEBIT"), // journalEntry(250.0, loansReceivableAccount, "DEBIT"), //
journalEntry(250.0, suspenseClearingAccount, "CREDIT"), // journalEntry(250.0, fundSource, "CREDIT"), //
journalEntry(1000.0, loansReceivableAccount, "CREDIT"), // journalEntry(1000.0, loansReceivableAccount, "CREDIT"), //
journalEntry(1000.0, suspenseClearingAccount, "DEBIT") // journalEntry(1000.0, fundSource, "DEBIT") //
); );
// verify repayment entries are reverted // verify repayment entries are reverted
@@ -298,11 +298,11 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries // verify journal entries
verifyJournalEntries(loanId, // verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), // journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
journalEntry(250.0, suspenseClearingAccount, "DEBIT"), // journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(100.0, loansReceivableAccount, "CREDIT"), // journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
journalEntry(100.0, suspenseClearingAccount, "DEBIT"), // journalEntry(100.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), // journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT") // journalEntry(1000.0, fundSource, "CREDIT") //
); );
// Verify Repayment Schedule // Verify Repayment Schedule
@@ -322,23 +322,23 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
verifyJournalEntries(loanId, // verifyJournalEntries(loanId, //
// original entries // original entries
journalEntry(250.0, loansReceivableAccount, "CREDIT"), // journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
journalEntry(250.0, suspenseClearingAccount, "DEBIT"), // journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), // journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), // journalEntry(1000.0, fundSource, "CREDIT"), //
// original entries compensated // original entries compensated
journalEntry(250.0, loansReceivableAccount, "DEBIT"), // journalEntry(250.0, loansReceivableAccount, "DEBIT"), //
journalEntry(250.0, suspenseClearingAccount, "CREDIT"), // journalEntry(250.0, fundSource, "CREDIT"), //
journalEntry(1000.0, loansReceivableAccount, "CREDIT"), // journalEntry(1000.0, loansReceivableAccount, "CREDIT"), //
journalEntry(1000.0, suspenseClearingAccount, "DEBIT"), // journalEntry(1000.0, fundSource, "DEBIT"), //
// manual partial repayment of the first installment // manual partial repayment of the first installment
journalEntry(100.0, loansReceivableAccount, "CREDIT"), // 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 // manual partial repayment of the first installment compensation after undoDisburse
journalEntry(100.0, loansReceivableAccount, "DEBIT"), // journalEntry(100.0, loansReceivableAccount, "DEBIT"), //
journalEntry(100.0, suspenseClearingAccount, "CREDIT") // journalEntry(100.0, fundSource, "CREDIT") //
); );
// Verify Repayment Schedule // Verify Repayment Schedule
@@ -381,9 +381,9 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries // verify journal entries
verifyJournalEntries(loanId, // verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), // journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
journalEntry(250.0, suspenseClearingAccount, "DEBIT"), // journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), // journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT") // journalEntry(1000.0, fundSource, "CREDIT") //
); );
// Verify Repayment Schedule // Verify Repayment Schedule
@@ -429,9 +429,9 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries // verify journal entries
verifyJournalEntries(loanId, // verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), // journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
journalEntry(250.0, suspenseClearingAccount, "DEBIT"), // journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), // journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT") // journalEntry(1000.0, fundSource, "CREDIT") //
); );
// Verify Repayment Schedule // Verify Repayment Schedule
@@ -476,9 +476,9 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries // verify journal entries
verifyJournalEntries(loanId, // verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), // journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
journalEntry(250.0, suspenseClearingAccount, "DEBIT"), // journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), // journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT") // journalEntry(1000.0, fundSource, "CREDIT") //
); );
// Verify Repayment Schedule // Verify Repayment Schedule
@@ -498,14 +498,14 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
verifyJournalEntries(loanId, // verifyJournalEntries(loanId, //
// original entries // original entries
journalEntry(250.0, loansReceivableAccount, "CREDIT"), // journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
journalEntry(250.0, suspenseClearingAccount, "DEBIT"), // journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), // journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), // journalEntry(1000.0, fundSource, "CREDIT"), //
// original entries reverted // original entries reverted
journalEntry(250.0, loansReceivableAccount, "DEBIT"), // journalEntry(250.0, loansReceivableAccount, "DEBIT"), //
journalEntry(250.0, suspenseClearingAccount, "CREDIT"), // journalEntry(250.0, fundSource, "CREDIT"), //
journalEntry(1000.0, loansReceivableAccount, "CREDIT"), // journalEntry(1000.0, loansReceivableAccount, "CREDIT"), //
journalEntry(1000.0, suspenseClearingAccount, "DEBIT") // journalEntry(1000.0, fundSource, "DEBIT") //
); );
// Verify Repayment Schedule // Verify Repayment Schedule
@@ -548,9 +548,9 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries // verify journal entries
verifyJournalEntries(loanId, // verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), // journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
journalEntry(250.0, suspenseClearingAccount, "DEBIT"), // journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), // journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT") // journalEntry(1000.0, fundSource, "CREDIT") //
); );
// make a repayment // make a repayment
@@ -573,23 +573,23 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
verifyJournalEntries(loanId, verifyJournalEntries(loanId,
// original entries down-payment // original entries down-payment
journalEntry(250.0, loansReceivableAccount, "CREDIT"), // journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
journalEntry(250.0, suspenseClearingAccount, "DEBIT"), // journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), // journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), // journalEntry(1000.0, fundSource, "CREDIT"), //
// repayment entries // repayment entries
journalEntry(100.0, loansReceivableAccount, "CREDIT"), // journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
journalEntry(100.0, suspenseClearingAccount, "DEBIT"), // journalEntry(100.0, fundSource, "DEBIT"), //
// original entries compensated // original entries compensated
journalEntry(250.0, loansReceivableAccount, "DEBIT"), // journalEntry(250.0, loansReceivableAccount, "DEBIT"), //
journalEntry(250.0, suspenseClearingAccount, "CREDIT"), // journalEntry(250.0, fundSource, "CREDIT"), //
journalEntry(1000.0, loansReceivableAccount, "CREDIT"), // journalEntry(1000.0, loansReceivableAccount, "CREDIT"), //
journalEntry(1000.0, suspenseClearingAccount, "DEBIT"), // journalEntry(1000.0, fundSource, "DEBIT"), //
// repayment entries compensated // repayment entries compensated
journalEntry(250.0, loansReceivableAccount, "DEBIT"), // journalEntry(250.0, loansReceivableAccount, "DEBIT"), //
journalEntry(250.0, suspenseClearingAccount, "CREDIT") // journalEntry(250.0, fundSource, "CREDIT") //
); );
// Verify Repayment Schedule // Verify Repayment Schedule
@@ -635,9 +635,9 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries // verify journal entries
verifyJournalEntries(loanId, // verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), // journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
journalEntry(250.0, suspenseClearingAccount, "DEBIT"), // journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), // journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT") // journalEntry(1000.0, fundSource, "CREDIT") //
); );
// undoDisbursal // undoDisbursal
@@ -650,15 +650,15 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
verifyJournalEntries(loanId, verifyJournalEntries(loanId,
// original entries // original entries
journalEntry(250.0, loansReceivableAccount, "CREDIT"), // journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
journalEntry(250.0, suspenseClearingAccount, "DEBIT"), // journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), // journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), // journalEntry(1000.0, fundSource, "CREDIT"), //
// original entries are compensated // original entries are compensated
journalEntry(250.0, loansReceivableAccount, "DEBIT"), // journalEntry(250.0, loansReceivableAccount, "DEBIT"), //
journalEntry(250.0, suspenseClearingAccount, "CREDIT"), // journalEntry(250.0, fundSource, "CREDIT"), //
journalEntry(1000.0, loansReceivableAccount, "CREDIT"), // journalEntry(1000.0, loansReceivableAccount, "CREDIT"), //
journalEntry(1000.0, suspenseClearingAccount, "DEBIT") // journalEntry(1000.0, fundSource, "DEBIT") //
); );
// Verify Repayment Schedule // Verify Repayment Schedule
@@ -707,11 +707,11 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries // verify journal entries
verifyJournalEntries(loanId, // verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), // journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
journalEntry(250.0, suspenseClearingAccount, "DEBIT"), // journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(100.0, loansReceivableAccount, "CREDIT"), // journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
journalEntry(100.0, suspenseClearingAccount, "DEBIT"), // journalEntry(100.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), // journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT") // journalEntry(1000.0, fundSource, "CREDIT") //
); );
// Verify Repayment Schedule // Verify Repayment Schedule
@@ -731,23 +731,23 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
verifyJournalEntries(loanId, verifyJournalEntries(loanId,
// original entries // original entries
journalEntry(250.0, loansReceivableAccount, "CREDIT"), // journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
journalEntry(250.0, suspenseClearingAccount, "DEBIT"), // journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), // journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), // journalEntry(1000.0, fundSource, "CREDIT"), //
// original entries compensated // original entries compensated
journalEntry(250.0, loansReceivableAccount, "DEBIT"), // journalEntry(250.0, loansReceivableAccount, "DEBIT"), //
journalEntry(250.0, suspenseClearingAccount, "CREDIT"), // journalEntry(250.0, fundSource, "CREDIT"), //
journalEntry(1000.0, loansReceivableAccount, "CREDIT"), // journalEntry(1000.0, loansReceivableAccount, "CREDIT"), //
journalEntry(1000.0, suspenseClearingAccount, "DEBIT"), // journalEntry(1000.0, fundSource, "DEBIT"), //
// manual partial repayment of the first installment // manual partial repayment of the first installment
journalEntry(100.0, loansReceivableAccount, "CREDIT"), // 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 // manual partial repayment of the first installment compensation after undoDisburse
journalEntry(100.0, loansReceivableAccount, "DEBIT"), // journalEntry(100.0, loansReceivableAccount, "DEBIT"), //
journalEntry(100.0, suspenseClearingAccount, "CREDIT") // journalEntry(100.0, fundSource, "CREDIT") //
); );
// Verify Repayment Schedule // Verify Repayment Schedule
@@ -787,9 +787,9 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries // verify journal entries
verifyJournalEntries(loanId, journalEntry(250.0, loansReceivableAccount, "CREDIT"), // 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, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT") // journalEntry(1000.0, fundSource, "CREDIT") //
); );
// Verify Repayment Schedule // Verify Repayment Schedule
@@ -815,13 +815,13 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries // verify journal entries
verifyJournalEntries(loanId, // verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), // journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
journalEntry(250.0, suspenseClearingAccount, "DEBIT"), // journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), // journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), // journalEntry(1000.0, fundSource, "CREDIT"), //
journalEntry(100.0, loansReceivableAccount, "CREDIT"), // journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
journalEntry(100.0, suspenseClearingAccount, "DEBIT"), // journalEntry(100.0, fundSource, "DEBIT"), //
journalEntry(400.0, loansReceivableAccount, "DEBIT"), // journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
journalEntry(400.0, suspenseClearingAccount, "CREDIT") // journalEntry(400.0, fundSource, "CREDIT") //
); );
// Verify Repayment Schedule // Verify Repayment Schedule
@@ -846,21 +846,21 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
verifyJournalEntries(loanId, verifyJournalEntries(loanId,
// first disbursement + down-payment // first disbursement + down-payment
journalEntry(250.0, loansReceivableAccount, "CREDIT"), // journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
journalEntry(250.0, suspenseClearingAccount, "DEBIT"), // journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), // journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), // journalEntry(1000.0, fundSource, "CREDIT"), //
// second disbursement + down-payment // second disbursement + down-payment
journalEntry(100.0, loansReceivableAccount, "CREDIT"), // journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
journalEntry(100.0, suspenseClearingAccount, "DEBIT"), // journalEntry(100.0, fundSource, "DEBIT"), //
journalEntry(400.0, loansReceivableAccount, "DEBIT"), // journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
journalEntry(400.0, suspenseClearingAccount, "CREDIT"), // journalEntry(400.0, fundSource, "CREDIT"), //
// compensation of second disbursement + down-payment // compensation of second disbursement + down-payment
journalEntry(100.0, loansReceivableAccount, "DEBIT"), // journalEntry(100.0, loansReceivableAccount, "DEBIT"), //
journalEntry(100.0, suspenseClearingAccount, "CREDIT"), // journalEntry(100.0, fundSource, "CREDIT"), //
journalEntry(400.0, loansReceivableAccount, "CREDIT"), // journalEntry(400.0, loansReceivableAccount, "CREDIT"), //
journalEntry(400.0, suspenseClearingAccount, "DEBIT") // journalEntry(400.0, fundSource, "DEBIT") //
); );
verifyRepaymentSchedule(loanId, // verifyRepaymentSchedule(loanId, //
@@ -901,9 +901,9 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries // verify journal entries
verifyJournalEntries(loanId, journalEntry(250.0, loansReceivableAccount, "CREDIT"), // 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, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT") // journalEntry(1000.0, fundSource, "CREDIT") //
); );
// Verify Repayment Schedule // Verify Repayment Schedule
@@ -941,15 +941,15 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries // verify journal entries
verifyJournalEntries(loanId, // verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), // journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
journalEntry(250.0, suspenseClearingAccount, "DEBIT"), // journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), // journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), // journalEntry(1000.0, fundSource, "CREDIT"), //
journalEntry(300.0, loansReceivableAccount, "CREDIT"), // journalEntry(300.0, loansReceivableAccount, "CREDIT"), //
journalEntry(300.0, suspenseClearingAccount, "DEBIT"), // journalEntry(300.0, fundSource, "DEBIT"), //
journalEntry(100.0, loansReceivableAccount, "CREDIT"), // journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
journalEntry(100.0, suspenseClearingAccount, "DEBIT"), // journalEntry(100.0, fundSource, "DEBIT"), //
journalEntry(400.0, loansReceivableAccount, "DEBIT"), // journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
journalEntry(400.0, suspenseClearingAccount, "CREDIT") // journalEntry(400.0, fundSource, "CREDIT") //
); );
// Verify Repayment Schedule // Verify Repayment Schedule
@@ -975,25 +975,25 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
verifyJournalEntries(loanId, verifyJournalEntries(loanId,
// first disbursement + down-payment // first disbursement + down-payment
journalEntry(250.0, loansReceivableAccount, "CREDIT"), // journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
journalEntry(250.0, suspenseClearingAccount, "DEBIT"), // journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), // journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), // journalEntry(1000.0, fundSource, "CREDIT"), //
// repayment // repayment
journalEntry(300.0, loansReceivableAccount, "CREDIT"), // journalEntry(300.0, loansReceivableAccount, "CREDIT"), //
journalEntry(300.0, suspenseClearingAccount, "DEBIT"), // journalEntry(300.0, fundSource, "DEBIT"), //
// second disbursement + down-payment // second disbursement + down-payment
journalEntry(100.0, loansReceivableAccount, "CREDIT"), // journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
journalEntry(100.0, suspenseClearingAccount, "DEBIT"), // journalEntry(100.0, fundSource, "DEBIT"), //
journalEntry(400.0, loansReceivableAccount, "DEBIT"), // journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
journalEntry(400.0, suspenseClearingAccount, "CREDIT"), // journalEntry(400.0, fundSource, "CREDIT"), //
// compensation of second disbursement + down-payment // compensation of second disbursement + down-payment
journalEntry(100.0, loansReceivableAccount, "DEBIT"), // journalEntry(100.0, loansReceivableAccount, "DEBIT"), //
journalEntry(100.0, suspenseClearingAccount, "CREDIT"), // journalEntry(100.0, fundSource, "CREDIT"), //
journalEntry(400.0, loansReceivableAccount, "CREDIT"), // journalEntry(400.0, loansReceivableAccount, "CREDIT"), //
journalEntry(400.0, suspenseClearingAccount, "DEBIT") // journalEntry(400.0, fundSource, "DEBIT") //
); );
verifyRepaymentSchedule(loanId, // verifyRepaymentSchedule(loanId, //
@@ -1038,9 +1038,9 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries // verify journal entries
verifyJournalEntries(loanId, // verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), // journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
journalEntry(250.0, suspenseClearingAccount, "DEBIT"), // journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), // journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT") // journalEntry(1000.0, fundSource, "CREDIT") //
); );
// Verify Repayment Schedule // Verify Repayment Schedule
@@ -1070,13 +1070,13 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries // verify journal entries
verifyJournalEntries(loanId, // verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), // journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
journalEntry(250.0, suspenseClearingAccount, "DEBIT"), // journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), // journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), // journalEntry(1000.0, fundSource, "CREDIT"), //
journalEntry(100.0, loansReceivableAccount, "CREDIT"), // journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
journalEntry(100.0, suspenseClearingAccount, "DEBIT"), // journalEntry(100.0, fundSource, "DEBIT"), //
journalEntry(400.0, loansReceivableAccount, "DEBIT"), // journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
journalEntry(400.0, suspenseClearingAccount, "CREDIT") // journalEntry(400.0, fundSource, "CREDIT") //
); );
// Verify Repayment Schedule // Verify Repayment Schedule
@@ -1101,21 +1101,21 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
verifyJournalEntries(loanId, verifyJournalEntries(loanId,
// first disbursement + down-payment // first disbursement + down-payment
journalEntry(250.0, loansReceivableAccount, "CREDIT"), // journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
journalEntry(250.0, suspenseClearingAccount, "DEBIT"), // journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), // journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), // journalEntry(1000.0, fundSource, "CREDIT"), //
// second disbursement + down-payment // second disbursement + down-payment
journalEntry(100.0, loansReceivableAccount, "CREDIT"), // journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
journalEntry(100.0, suspenseClearingAccount, "DEBIT"), // journalEntry(100.0, fundSource, "DEBIT"), //
journalEntry(400.0, loansReceivableAccount, "DEBIT"), // journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
journalEntry(400.0, suspenseClearingAccount, "CREDIT"), // journalEntry(400.0, fundSource, "CREDIT"), //
// compensation of second disbursement + down-payment // compensation of second disbursement + down-payment
journalEntry(100.0, loansReceivableAccount, "DEBIT"), // journalEntry(100.0, loansReceivableAccount, "DEBIT"), //
journalEntry(100.0, suspenseClearingAccount, "CREDIT"), // journalEntry(100.0, fundSource, "CREDIT"), //
journalEntry(400.0, loansReceivableAccount, "CREDIT"), // journalEntry(400.0, loansReceivableAccount, "CREDIT"), //
journalEntry(400.0, suspenseClearingAccount, "DEBIT") // journalEntry(400.0, fundSource, "DEBIT") //
); );
verifyRepaymentSchedule(loanId, // verifyRepaymentSchedule(loanId, //
@@ -1157,9 +1157,9 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries // verify journal entries
verifyJournalEntries(loanId, // verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), // journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
journalEntry(250.0, suspenseClearingAccount, "DEBIT"), // journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), // journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT") // journalEntry(1000.0, fundSource, "CREDIT") //
); );
// Verify Repayment Schedule // Verify Repayment Schedule
@@ -1186,13 +1186,13 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries // verify journal entries
verifyJournalEntries(loanId, // verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), // journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
journalEntry(250.0, suspenseClearingAccount, "DEBIT"), // journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), // journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), // journalEntry(1000.0, fundSource, "CREDIT"), //
journalEntry(100.0, loansReceivableAccount, "CREDIT"), // journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
journalEntry(100.0, suspenseClearingAccount, "DEBIT"), // journalEntry(100.0, fundSource, "DEBIT"), //
journalEntry(400.0, loansReceivableAccount, "DEBIT"), // journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
journalEntry(400.0, suspenseClearingAccount, "CREDIT") // journalEntry(400.0, fundSource, "CREDIT") //
); );
// Verify Repayment Schedule // Verify Repayment Schedule
@@ -1249,9 +1249,9 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries // verify journal entries
verifyJournalEntries(loanId, // verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), // journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
journalEntry(250.0, suspenseClearingAccount, "DEBIT"), // journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), // journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT") // journalEntry(1000.0, fundSource, "CREDIT") //
); );
// Verify Repayment Schedule // Verify Repayment Schedule
@@ -1281,13 +1281,13 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries // verify journal entries
verifyJournalEntries(loanId, // verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), // journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
journalEntry(250.0, suspenseClearingAccount, "DEBIT"), // journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), // journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), // journalEntry(1000.0, fundSource, "CREDIT"), //
journalEntry(100.0, loansReceivableAccount, "CREDIT"), // journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
journalEntry(100.0, suspenseClearingAccount, "DEBIT"), // journalEntry(100.0, fundSource, "DEBIT"), //
journalEntry(400.0, loansReceivableAccount, "DEBIT"), // journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
journalEntry(400.0, suspenseClearingAccount, "CREDIT") // journalEntry(400.0, fundSource, "CREDIT") //
); );
// Verify Repayment Schedule // Verify Repayment Schedule
@@ -1341,9 +1341,9 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries // verify journal entries
verifyJournalEntries(loanId, // verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), // journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
journalEntry(250.0, suspenseClearingAccount, "DEBIT"), // journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), // journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT") // journalEntry(1000.0, fundSource, "CREDIT") //
); );
// Verify Repayment Schedule // Verify Repayment Schedule
@@ -1370,13 +1370,13 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries // verify journal entries
verifyJournalEntries(loanId, // verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), // journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
journalEntry(250.0, suspenseClearingAccount, "DEBIT"), // journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), // journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), // journalEntry(1000.0, fundSource, "CREDIT"), //
journalEntry(100.0, loansReceivableAccount, "CREDIT"), // journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
journalEntry(100.0, suspenseClearingAccount, "DEBIT"), // journalEntry(100.0, fundSource, "DEBIT"), //
journalEntry(400.0, loansReceivableAccount, "DEBIT"), // journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
journalEntry(400.0, suspenseClearingAccount, "CREDIT") // journalEntry(400.0, fundSource, "CREDIT") //
); );
// Verify Repayment Schedule // Verify Repayment Schedule
@@ -1404,27 +1404,27 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
verifyJournalEntries(loanId, verifyJournalEntries(loanId,
// 1st disbursal + down-payment // 1st disbursal + down-payment
journalEntry(250.0, loansReceivableAccount, "CREDIT"), // journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
journalEntry(250.0, suspenseClearingAccount, "DEBIT"), // journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), // journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), // journalEntry(1000.0, fundSource, "CREDIT"), //
// 2nd disbursal + down-payment // 2nd disbursal + down-payment
journalEntry(100.0, loansReceivableAccount, "CREDIT"), // journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
journalEntry(100.0, suspenseClearingAccount, "DEBIT"), // journalEntry(100.0, fundSource, "DEBIT"), //
journalEntry(400.0, loansReceivableAccount, "DEBIT"), // journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
journalEntry(400.0, suspenseClearingAccount, "CREDIT"), // journalEntry(400.0, fundSource, "CREDIT"), //
// compensation of the 1st disbursal + down-payment // compensation of the 1st disbursal + down-payment
journalEntry(250.0, loansReceivableAccount, "DEBIT"), // journalEntry(250.0, loansReceivableAccount, "DEBIT"), //
journalEntry(250.0, suspenseClearingAccount, "CREDIT"), // journalEntry(250.0, fundSource, "CREDIT"), //
journalEntry(1000.0, loansReceivableAccount, "CREDIT"), // journalEntry(1000.0, loansReceivableAccount, "CREDIT"), //
journalEntry(1000.0, suspenseClearingAccount, "DEBIT"), // journalEntry(1000.0, fundSource, "DEBIT"), //
// compensation of the 2nd disbursal + down-payment // compensation of the 2nd disbursal + down-payment
journalEntry(100.0, loansReceivableAccount, "DEBIT"), // journalEntry(100.0, loansReceivableAccount, "DEBIT"), //
journalEntry(100.0, suspenseClearingAccount, "CREDIT"), // journalEntry(100.0, fundSource, "CREDIT"), //
journalEntry(400.0, loansReceivableAccount, "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 // verify journal entries
verifyJournalEntries(loanId, // verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), // journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
journalEntry(250.0, suspenseClearingAccount, "DEBIT"), // journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), // journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT") // journalEntry(1000.0, fundSource, "CREDIT") //
); );
// Verify Repayment Schedule // Verify Repayment Schedule
@@ -1495,13 +1495,13 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries // verify journal entries
verifyJournalEntries(loanId, // verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), // journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
journalEntry(250.0, suspenseClearingAccount, "DEBIT"), // journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), // journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), // journalEntry(1000.0, fundSource, "CREDIT"), //
journalEntry(100.0, loansReceivableAccount, "CREDIT"), // journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
journalEntry(100.0, suspenseClearingAccount, "DEBIT"), // journalEntry(100.0, fundSource, "DEBIT"), //
journalEntry(400.0, loansReceivableAccount, "DEBIT"), // journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
journalEntry(400.0, suspenseClearingAccount, "CREDIT") // journalEntry(400.0, fundSource, "CREDIT") //
); );
// Verify Repayment Schedule // Verify Repayment Schedule
@@ -1529,27 +1529,27 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
verifyJournalEntries(loanId, verifyJournalEntries(loanId,
// 1st disbursal + down-payment // 1st disbursal + down-payment
journalEntry(250.0, loansReceivableAccount, "CREDIT"), // journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
journalEntry(250.0, suspenseClearingAccount, "DEBIT"), // journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), // journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), // journalEntry(1000.0, fundSource, "CREDIT"), //
// 2nd disbursal + down-payment // 2nd disbursal + down-payment
journalEntry(100.0, loansReceivableAccount, "CREDIT"), // journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
journalEntry(100.0, suspenseClearingAccount, "DEBIT"), // journalEntry(100.0, fundSource, "DEBIT"), //
journalEntry(400.0, loansReceivableAccount, "DEBIT"), // journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
journalEntry(400.0, suspenseClearingAccount, "CREDIT"), // journalEntry(400.0, fundSource, "CREDIT"), //
// compensation of the 1st disbursal + down-payment // compensation of the 1st disbursal + down-payment
journalEntry(250.0, loansReceivableAccount, "DEBIT"), // journalEntry(250.0, loansReceivableAccount, "DEBIT"), //
journalEntry(250.0, suspenseClearingAccount, "CREDIT"), // journalEntry(250.0, fundSource, "CREDIT"), //
journalEntry(1000.0, loansReceivableAccount, "CREDIT"), // journalEntry(1000.0, loansReceivableAccount, "CREDIT"), //
journalEntry(1000.0, suspenseClearingAccount, "DEBIT"), // journalEntry(1000.0, fundSource, "DEBIT"), //
// compensation of the 2nd disbursal + down-payment // compensation of the 2nd disbursal + down-payment
journalEntry(100.0, loansReceivableAccount, "DEBIT"), // journalEntry(100.0, loansReceivableAccount, "DEBIT"), //
journalEntry(100.0, suspenseClearingAccount, "CREDIT"), // journalEntry(100.0, fundSource, "CREDIT"), //
journalEntry(400.0, loansReceivableAccount, "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 // verify journal entries
verifyJournalEntries(loanId, // verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), // journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
journalEntry(250.0, suspenseClearingAccount, "DEBIT"), // journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), // journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT") // journalEntry(1000.0, fundSource, "CREDIT") //
); );
// Verify Repayment Schedule // Verify Repayment Schedule
@@ -1614,13 +1614,13 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries // verify journal entries
verifyJournalEntries(loanId, // verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), // journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
journalEntry(250.0, suspenseClearingAccount, "DEBIT"), // journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), // journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), // journalEntry(1000.0, fundSource, "CREDIT"), //
journalEntry(100.0, loansReceivableAccount, "CREDIT"), // journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
journalEntry(100.0, suspenseClearingAccount, "DEBIT"), // journalEntry(100.0, fundSource, "DEBIT"), //
journalEntry(400.0, loansReceivableAccount, "DEBIT"), // journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
journalEntry(400.0, suspenseClearingAccount, "CREDIT") // journalEntry(400.0, fundSource, "CREDIT") //
); );
// Verify Repayment Schedule // Verify Repayment Schedule
@@ -1654,35 +1654,35 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
verifyJournalEntries(loanId, verifyJournalEntries(loanId,
// 1st disbursal + down-payment // 1st disbursal + down-payment
journalEntry(250.0, loansReceivableAccount, "CREDIT"), // journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
journalEntry(250.0, suspenseClearingAccount, "DEBIT"), // journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), // journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), // journalEntry(1000.0, fundSource, "CREDIT"), //
// 2nd disbursal + down-payment // 2nd disbursal + down-payment
journalEntry(100.0, loansReceivableAccount, "CREDIT"), // journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
journalEntry(100.0, suspenseClearingAccount, "DEBIT"), // journalEntry(100.0, fundSource, "DEBIT"), //
journalEntry(400.0, loansReceivableAccount, "DEBIT"), // journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
journalEntry(400.0, suspenseClearingAccount, "CREDIT"), // journalEntry(400.0, fundSource, "CREDIT"), //
// manual repayment // manual repayment
journalEntry(50.0, loansReceivableAccount, "CREDIT"), // journalEntry(50.0, loansReceivableAccount, "CREDIT"), //
journalEntry(50.0, suspenseClearingAccount, "DEBIT"), // journalEntry(50.0, fundSource, "DEBIT"), //
// compensation of the 1st disbursal + down-payment // compensation of the 1st disbursal + down-payment
journalEntry(250.0, loansReceivableAccount, "DEBIT"), // journalEntry(250.0, loansReceivableAccount, "DEBIT"), //
journalEntry(250.0, suspenseClearingAccount, "CREDIT"), // journalEntry(250.0, fundSource, "CREDIT"), //
journalEntry(1000.0, loansReceivableAccount, "CREDIT"), // journalEntry(1000.0, loansReceivableAccount, "CREDIT"), //
journalEntry(1000.0, suspenseClearingAccount, "DEBIT"), // journalEntry(1000.0, fundSource, "DEBIT"), //
// compensation of the 2nd disbursal + down-payment // compensation of the 2nd disbursal + down-payment
journalEntry(100.0, loansReceivableAccount, "DEBIT"), // journalEntry(100.0, loansReceivableAccount, "DEBIT"), //
journalEntry(100.0, suspenseClearingAccount, "CREDIT"), // journalEntry(100.0, fundSource, "CREDIT"), //
journalEntry(400.0, loansReceivableAccount, "CREDIT"), // journalEntry(400.0, loansReceivableAccount, "CREDIT"), //
journalEntry(400.0, suspenseClearingAccount, "DEBIT"), // journalEntry(400.0, fundSource, "DEBIT"), //
// compensation of repayment // compensation of repayment
journalEntry(50.0, loansReceivableAccount, "DEBIT"), // 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 // verify journal entries
verifyJournalEntries(loanId, // verifyJournalEntries(loanId, //
journalEntry(250.0, loansReceivableAccount, "CREDIT"), // journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
journalEntry(250.0, suspenseClearingAccount, "DEBIT"), // journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), // journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT") // journalEntry(1000.0, fundSource, "CREDIT") //
); );
// Verify Repayment Schedule // Verify Repayment Schedule
@@ -1752,13 +1752,13 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
// verify journal entries // verify journal entries
verifyJournalEntries(loanId, journalEntry(250.0, loansReceivableAccount, "CREDIT"), // 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, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), // journalEntry(1000.0, fundSource, "CREDIT"), //
journalEntry(100.0, loansReceivableAccount, "CREDIT"), // journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
journalEntry(100.0, suspenseClearingAccount, "DEBIT"), // journalEntry(100.0, fundSource, "DEBIT"), //
journalEntry(400.0, loansReceivableAccount, "DEBIT"), // journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
journalEntry(400.0, suspenseClearingAccount, "CREDIT") // journalEntry(400.0, fundSource, "CREDIT") //
); );
// Verify Repayment Schedule // Verify Repayment Schedule
@@ -1792,35 +1792,35 @@ public class UndoLoanDisbursalWithDownPaymentIntegrationTest extends BaseLoanInt
verifyJournalEntries(loanId, verifyJournalEntries(loanId,
// 1st disbursal + down-payment // 1st disbursal + down-payment
journalEntry(250.0, loansReceivableAccount, "CREDIT"), // journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
journalEntry(250.0, suspenseClearingAccount, "DEBIT"), // journalEntry(250.0, fundSource, "DEBIT"), //
journalEntry(1000.0, loansReceivableAccount, "DEBIT"), // journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), // journalEntry(1000.0, fundSource, "CREDIT"), //
// 2nd disbursal + down-payment // 2nd disbursal + down-payment
journalEntry(100.0, loansReceivableAccount, "CREDIT"), // journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
journalEntry(100.0, suspenseClearingAccount, "DEBIT"), // journalEntry(100.0, fundSource, "DEBIT"), //
journalEntry(400.0, loansReceivableAccount, "DEBIT"), // journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
journalEntry(400.0, suspenseClearingAccount, "CREDIT"), // journalEntry(400.0, fundSource, "CREDIT"), //
// manual repayment // manual repayment
journalEntry(50.0, loansReceivableAccount, "CREDIT"), // journalEntry(50.0, loansReceivableAccount, "CREDIT"), //
journalEntry(50.0, suspenseClearingAccount, "DEBIT"), // journalEntry(50.0, fundSource, "DEBIT"), //
// compensation of the 1st disbursal + down-payment // compensation of the 1st disbursal + down-payment
journalEntry(250.0, loansReceivableAccount, "DEBIT"), // journalEntry(250.0, loansReceivableAccount, "DEBIT"), //
journalEntry(250.0, suspenseClearingAccount, "CREDIT"), // journalEntry(250.0, fundSource, "CREDIT"), //
journalEntry(1000.0, loansReceivableAccount, "CREDIT"), // journalEntry(1000.0, loansReceivableAccount, "CREDIT"), //
journalEntry(1000.0, suspenseClearingAccount, "DEBIT"), // journalEntry(1000.0, fundSource, "DEBIT"), //
// compensation of the 2nd disbursal + down-payment // compensation of the 2nd disbursal + down-payment
journalEntry(100.0, loansReceivableAccount, "DEBIT"), // journalEntry(100.0, loansReceivableAccount, "DEBIT"), //
journalEntry(100.0, suspenseClearingAccount, "CREDIT"), // journalEntry(100.0, fundSource, "CREDIT"), //
journalEntry(400.0, loansReceivableAccount, "CREDIT"), // journalEntry(400.0, loansReceivableAccount, "CREDIT"), //
journalEntry(400.0, suspenseClearingAccount, "DEBIT"), // journalEntry(400.0, fundSource, "DEBIT"), //
// compensation of repayment // compensation of repayment
journalEntry(50.0, loansReceivableAccount, "DEBIT"), // journalEntry(50.0, loansReceivableAccount, "DEBIT"), //
journalEntry(50.0, suspenseClearingAccount, "CREDIT") // journalEntry(50.0, fundSource, "CREDIT") //
); );
}); });
} }
@@ -42,35 +42,55 @@ public class AccountHelper extends IntegrationTest {
} }
public Account createAssetAccount() { 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, final Integer accountID = Utils.performServerPost(this.requestSpec, this.responseSpec, CREATE_GL_ACCOUNT_URL, assetAccountJSON,
GL_ACCOUNT_ID_RESPONSE); GL_ACCOUNT_ID_RESPONSE);
return new Account(accountID, Account.AccountType.ASSET); return new Account(accountID, Account.AccountType.ASSET);
} }
public Account createIncomeAccount() { public Account createIncomeAccount(String accountName) {
final String assetAccountJSON = new GLAccountBuilder().withAccountTypeAsIncome().build(); final String assetAccountJSON = new GLAccountBuilder().withName(accountName).withAccountTypeAsIncome().build();
final Integer accountID = Utils.performServerPost(this.requestSpec, this.responseSpec, CREATE_GL_ACCOUNT_URL, assetAccountJSON, final Integer accountID = Utils.performServerPost(this.requestSpec, this.responseSpec, CREATE_GL_ACCOUNT_URL, assetAccountJSON,
GL_ACCOUNT_ID_RESPONSE); GL_ACCOUNT_ID_RESPONSE);
return new Account(accountID, Account.AccountType.INCOME); return new Account(accountID, Account.AccountType.INCOME);
} }
public Account createExpenseAccount() { public Account createExpenseAccount(String accountName) {
final String assetAccountJSON = new GLAccountBuilder().withAccountTypeAsExpense().build(); final String assetAccountJSON = new GLAccountBuilder().withName(accountName).withAccountTypeAsExpense().build();
final Integer accountID = Utils.performServerPost(this.requestSpec, this.responseSpec, CREATE_GL_ACCOUNT_URL, assetAccountJSON, final Integer accountID = Utils.performServerPost(this.requestSpec, this.responseSpec, CREATE_GL_ACCOUNT_URL, assetAccountJSON,
GL_ACCOUNT_ID_RESPONSE); GL_ACCOUNT_ID_RESPONSE);
return new Account(accountID, Account.AccountType.EXPENSE); return new Account(accountID, Account.AccountType.EXPENSE);
} }
public Account createLiabilityAccount() { public Account createLiabilityAccount(String accountName) {
final String liabilityAccountJSON = new GLAccountBuilder().withAccountTypeAsLiability().build(); final String liabilityAccountJSON = new GLAccountBuilder().withName(accountName).withAccountTypeAsLiability().build();
final Integer accountID = Utils.performServerPost(this.requestSpec, this.responseSpec, CREATE_GL_ACCOUNT_URL, liabilityAccountJSON, final Integer accountID = Utils.performServerPost(this.requestSpec, this.responseSpec, CREATE_GL_ACCOUNT_URL, liabilityAccountJSON,
GL_ACCOUNT_ID_RESPONSE); GL_ACCOUNT_ID_RESPONSE);
return new Account(accountID, Account.AccountType.LIABILITY); return new Account(accountID, Account.AccountType.LIABILITY);
} }
public Account createEquityAccount() { public Account createEquityAccount(String accountName) {
final String equityAccountJSON = new GLAccountBuilder().withAccountTypeAsAsEquity().build(); final String equityAccountJSON = new GLAccountBuilder().withName(accountName).withAccountTypeAsAsEquity().build();
final Integer accountID = Utils.performServerPost(this.requestSpec, this.responseSpec, CREATE_GL_ACCOUNT_URL, equityAccountJSON, final Integer accountID = Utils.performServerPost(this.requestSpec, this.responseSpec, CREATE_GL_ACCOUNT_URL, equityAccountJSON,
GL_ACCOUNT_ID_RESPONSE); GL_ACCOUNT_ID_RESPONSE);
return new Account(accountID, Account.AccountType.EQUITY); return new Account(accountID, Account.AccountType.EQUITY);
@@ -21,6 +21,7 @@ package org.apache.fineract.integrationtests.common.accounting;
import com.google.gson.Gson; import com.google.gson.Gson;
import java.util.Calendar; import java.util.Calendar;
import java.util.HashMap; import java.util.HashMap;
import org.apache.commons.lang3.StringUtils;
import org.apache.fineract.integrationtests.common.Utils; import org.apache.fineract.integrationtests.common.Utils;
public class GLAccountBuilder { public class GLAccountBuilder {
@@ -86,6 +87,13 @@ public class GLAccountBuilder {
return this; return this;
} }
public GLAccountBuilder withName(String name) {
if (StringUtils.isNotBlank(name)) {
this.name = Utils.uniqueRandomStringGenerator(name + "_", 5);
}
return this;
}
public GLAccountBuilder withAccountUsageAsHeader() { public GLAccountBuilder withAccountUsageAsHeader() {
accountUsage = ACCOUNT_USAGE_HEADER; accountUsage = ACCOUNT_USAGE_HEADER;
return this; return this;
@@ -25,6 +25,8 @@ import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import lombok.Builder;
import org.apache.fineract.client.models.AdvancedPaymentData; import org.apache.fineract.client.models.AdvancedPaymentData;
import org.apache.fineract.client.models.CreditAllocationData; import org.apache.fineract.client.models.CreditAllocationData;
import org.apache.fineract.integrationtests.common.Utils; 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_FEE = "2";
public static final String RECALCULATION_COMPOUNDING_METHOD_INTEREST_AND_FEE = "3"; public static final String RECALCULATION_COMPOUNDING_METHOD_INTEREST_AND_FEE = "3";
private static final String NONE = "1"; public static final String NONE = "1";
private static final String CASH_BASED = "2"; public static final String CASH_BASED = "2";
private static final String ACCRUAL_PERIODIC = "3"; public static final String ACCRUAL_PERIODIC = "3";
private static final String ACCRUAL_UPFRONT = "4"; public static final String ACCRUAL_UPFRONT = "4";
public static final String INTEREST_APPLICABLE_STRATEGY_REST_DATE = "2"; public static final String INTEREST_APPLICABLE_STRATEGY_REST_DATE = "2";
public static final String INTEREST_APPLICABLE_STRATEGY_ON_PRE_CLOSE_DATE = "1"; public static final String INTEREST_APPLICABLE_STRATEGY_ON_PRE_CLOSE_DATE = "1";
@@ -157,6 +159,7 @@ public class LoanProductTestBuilder {
private Integer repaymentStartDateType = null; private Integer repaymentStartDateType = null;
private String loanScheduleType = LoanScheduleType.CUMULATIVE.name(); private String loanScheduleType = LoanScheduleType.CUMULATIVE.name();
private String loanScheduleProcessingType = LoanScheduleProcessingType.HORIZONTAL.name(); private String loanScheduleProcessingType = LoanScheduleProcessingType.HORIZONTAL.name();
private FullAccountingConfig fullAccountingConfig;
public String build() { public String build() {
final HashMap<String, Object> map = build(null, null); final HashMap<String, Object> map = build(null, null);
@@ -231,7 +234,9 @@ public class LoanProductTestBuilder {
map.put("outstandingLoanBalance", this.outstandingLoanBalance); 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)); map.putAll(getAccountMappingForAccrualBased(this.feeAndPenaltyAssetAccount));
} else if (this.accountingRule.equals(CASH_BASED)) { } else if (this.accountingRule.equals(CASH_BASED)) {
map.putAll(getAccountMappingForCashBased()); map.putAll(getAccountMappingForCashBased());
@@ -487,6 +492,13 @@ public class LoanProductTestBuilder {
return this; 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() { private Map<String, String> getAccountMappingForCashBased() {
final Map<String, String> map = new HashMap<>(); final Map<String, String> map = new HashMap<>();
for (int i = 0; i < this.accountList.length; i++) { for (int i = 0; i < this.accountList.length; i++) {
@@ -768,4 +780,78 @@ public class LoanProductTestBuilder {
return transactionProcessingStrategyCode; 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;
}
}
} }