FINERACT-2210: Fix incorrect accounting of "buyback" for charged-off loan with fraud
This commit is contained in:
committed by
Adam Saghy
parent
30543fd72e
commit
13c99f98ab
+2
-2
@@ -1274,7 +1274,7 @@ public class LoanProductsRequestFactory {
|
||||
final List<PostChargeOffReasonToExpenseAccountMappings> chargeOffReasonToExpenseAccountMappings = new ArrayList<>();
|
||||
final PostChargeOffReasonToExpenseAccountMappings chargeOffDelinquentReason = new PostChargeOffReasonToExpenseAccountMappings();
|
||||
chargeOffDelinquentReason.chargeOffReasonCodeValueId(codeValueResolver.resolve(chargeOffReasonId, DefaultCodeValue.DELINQUENT));
|
||||
chargeOffDelinquentReason.expenseAccountId(accountTypeResolver.resolve(DefaultAccountType.CREDIT_LOSS_BAD_DEBT_FRAUD));
|
||||
chargeOffDelinquentReason.expenseAccountId(accountTypeResolver.resolve(DefaultAccountType.CREDIT_LOSS_BAD_DEBT));
|
||||
chargeOffReasonToExpenseAccountMappings.add(chargeOffDelinquentReason);
|
||||
|
||||
return new PostLoanProductsRequest()//
|
||||
@@ -1369,7 +1369,7 @@ public class LoanProductsRequestFactory {
|
||||
.incomeFromChargeOffInterestAccountId(accountTypeResolver.resolve(DefaultAccountType.INTEREST_INCOME_CHARGE_OFF))//
|
||||
.incomeFromChargeOffFeesAccountId(accountTypeResolver.resolve(DefaultAccountType.FEE_CHARGE_OFF))//
|
||||
.chargeOffExpenseAccountId(accountTypeResolver.resolve(DefaultAccountType.CREDIT_LOSS_BAD_DEBT))//
|
||||
.chargeOffFraudExpenseAccountId(accountTypeResolver.resolve(DefaultAccountType.CREDIT_LOSS_BAD_DEBT))//
|
||||
.chargeOffFraudExpenseAccountId(accountTypeResolver.resolve(DefaultAccountType.CREDIT_LOSS_BAD_DEBT_FRAUD))//
|
||||
.chargeOffReasonToExpenseAccountMappings(chargeOffReasonToExpenseAccountMappings)//
|
||||
.incomeFromChargeOffPenaltyAccountId(accountTypeResolver.resolve(DefaultAccountType.FEE_CHARGE_OFF));//
|
||||
}
|
||||
|
||||
@@ -7647,7 +7647,7 @@ Feature: Charge-off
|
||||
| Type | Account code | Account name | Debit | Credit |
|
||||
| ASSET | 112601 | Loans Receivable | | 100.0 |
|
||||
| ASSET | 112603 | Interest/Fee Receivable | | 0.62 |
|
||||
| EXPENSE | 744037 | Credit Loss/Bad Debt-Fraud | 100.0 | |
|
||||
| EXPENSE | 744007 | Credit Loss/Bad Debt | 100.0 | |
|
||||
| INCOME | 404001 | Interest Income Charge Off | 0.62 | |
|
||||
Then Admin does a charge-off undo the loan
|
||||
Then Loan Transactions tab has a "CHARGE_OFF" transaction with date "03 February 2024" which has the following Journal entries:
|
||||
@@ -7656,8 +7656,8 @@ Feature: Charge-off
|
||||
| ASSET | 112601 | Loans Receivable | 100.0 | |
|
||||
| ASSET | 112603 | Interest/Fee Receivable | | 0.62 |
|
||||
| ASSET | 112603 | Interest/Fee Receivable | 0.62 | |
|
||||
| EXPENSE | 744037 | Credit Loss/Bad Debt-Fraud | 100.0 | |
|
||||
| EXPENSE | 744037 | Credit Loss/Bad Debt-Fraud | | 100.0 |
|
||||
| EXPENSE | 744007 | Credit Loss/Bad Debt | 100.0 | |
|
||||
| EXPENSE | 744007 | Credit Loss/Bad Debt | | 100.0 |
|
||||
| INCOME | 404001 | Interest Income Charge Off | 0.62 | |
|
||||
| INCOME | 404001 | Interest Income Charge Off | | 0.62 |
|
||||
|
||||
@@ -8345,3 +8345,98 @@ Feature: Charge-off
|
||||
| 14 April 2025 | Accrual | 3.26 | 0.0 | 3.26 | 0.0 | 0.0 | 0.0 | false | false |
|
||||
| 14 April 2025 | Accrual Adjustment | 0.1 | 0.0 | 0.1 | 0.0 | 0.0 | 0.0 | false | false |
|
||||
| 14 April 2025 | Charge-off | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | false | true |
|
||||
|
||||
@TestRailId:C3618
|
||||
Scenario: Charge-off on a fraud loan respects GL mapping based on charge-off reason for buyback
|
||||
When Admin sets the business date to "1 January 2024"
|
||||
And Admin creates a client with random data
|
||||
And Admin creates a fully customized loan with the following data:
|
||||
| LoanProduct | submitted on date | with Principal | ANNUAL interest rate % | interest type | interest calculation period | amortization type | loanTermFrequency | loanTermFrequencyType | repaymentEvery | repaymentFrequencyType | numberOfRepayments | graceOnPrincipalPayment | graceOnInterestPayment | interest free period | Payment strategy |
|
||||
| LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF_DELINQUENT_REASON | 01 January 2024 | 100 | 7 | DECLINING_BALANCE | SAME_AS_REPAYMENT_PERIOD | EQUAL_INSTALLMENTS | 6 | MONTHS | 1 | MONTHS | 6 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION |
|
||||
Then Loan Repayment schedule has 6 periods, with the following data for periods:
|
||||
| Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
||||
| | | 01 January 2024 | | 100.0 | | | 0.0 | | 0.0 | | | | 0.0 |
|
||||
| 1 | 31 | 01 February 2024 | | 83.59 | 16.41 | 0.59 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 |
|
||||
| 2 | 29 | 01 March 2024 | | 67.05 | 16.54 | 0.46 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 |
|
||||
| 3 | 31 | 01 April 2024 | | 50.45 | 16.6 | 0.4 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 |
|
||||
| 4 | 30 | 01 May 2024 | | 33.74 | 16.71 | 0.29 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 |
|
||||
| 5 | 31 | 01 June 2024 | | 16.94 | 16.8 | 0.2 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 |
|
||||
| 6 | 30 | 01 July 2024 | | 0.0 | 16.94 | 0.1 | 0.0 | 0.0 | 17.04 | 0.0 | 0.0 | 0.0 | 17.04 |
|
||||
Then Loan Repayment schedule has the following data in Total row:
|
||||
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
||||
| 100 | 2.04 | 0 | 0 | 102.04 | 0 | 0 | 0 | 102.04 |
|
||||
And Admin successfully approves the loan on "1 January 2024" with "100" amount and expected disbursement date on "1 January 2024"
|
||||
And Admin successfully disburse the loan on "1 January 2024" with "100" EUR transaction amount
|
||||
When Admin makes asset externalization request by Loan ID with unique ownerExternalId, system-generated transferExternalId and the following data:
|
||||
| Transaction type | settlementDate | purchasePriceRatio |
|
||||
| sale | 2024-01-21 | 1 |
|
||||
Then Asset externalization response has the correct Loan ID, transferExternalId
|
||||
Then Fetching Asset externalization details by loan id gives numberOfElements: 1 with correct ownerExternalId and the following data:
|
||||
| settlementDate | purchasePriceRatio | status | effectiveFrom | effectiveTo | Transaction type |
|
||||
| 2024-01-21 | 1 | PENDING | 2024-01-01 | 9999-12-31 | SALE |
|
||||
When Admin sets the business date to "22 January 2024"
|
||||
When Admin runs inline COB job for Loan
|
||||
Then LoanOwnershipTransferBusinessEvent is created
|
||||
Then LoanAccountSnapshotBusinessEvent is created
|
||||
Then Fetching Asset externalization details by loan id gives numberOfElements: 2 with correct ownerExternalId and the following data:
|
||||
| settlementDate | purchasePriceRatio | status | effectiveFrom | effectiveTo | Transaction type |
|
||||
| 2024-01-21 | 1 | PENDING | 2024-01-01 | 2024-01-21 | SALE |
|
||||
| 2024-01-21 | 1 | ACTIVE | 2024-01-22 | 9999-12-31 | SALE |
|
||||
Then The latest asset externalization transaction with "ACTIVE" status has the following TRANSFER Journal entries:
|
||||
| glAccountType | glAccountCode | glAccountName | entryType | amount |
|
||||
| ASSET | 112601 | Loans Receivable | CREDIT | 100.00 |
|
||||
| ASSET | 112603 | Interest/Fee Receivable | CREDIT | 2.04 |
|
||||
| ASSET | 146000 | Asset transfer | DEBIT | 102.04 |
|
||||
| ASSET | 112601 | Loans Receivable | DEBIT | 100.00 |
|
||||
| ASSET | 112603 | Interest/Fee Receivable | DEBIT | 2.04 |
|
||||
| ASSET | 146000 | Asset transfer | CREDIT | 102.04 |
|
||||
Then The asset external owner has the following OWNER Journal entries:
|
||||
| glAccountType | glAccountCode | glAccountName | entryType | amount |
|
||||
| ASSET | 112601 | Loans Receivable | DEBIT | 100.00 |
|
||||
| ASSET | 112603 | Interest/Fee Receivable | DEBIT | 2.04 |
|
||||
Then Admin can successfully set Fraud flag to the loan
|
||||
When Admin sets the business date to "03 February 2024"
|
||||
And Admin does charge-off the loan with reason "DELINQUENT" on "03 February 2024"
|
||||
Then Loan Transactions tab has a "CHARGE_OFF" transaction with date "03 February 2024" which has the following Journal entries:
|
||||
| Type | Account code | Account name | Debit | Credit |
|
||||
| ASSET | 112601 | Loans Receivable | | 100.0 |
|
||||
| ASSET | 112603 | Interest/Fee Receivable | | 0.62 |
|
||||
| EXPENSE | 744007 | Credit Loss/Bad Debt | 100.0 | |
|
||||
| INCOME | 404001 | Interest Income Charge Off | 0.62 | |
|
||||
When Admin makes asset externalization request by Loan ID with unique ownerExternalId, system-generated transferExternalId and the following data:
|
||||
| Transaction type | settlementDate | purchasePriceRatio |
|
||||
| buyback | 2024-02-03 | |
|
||||
Then Fetching Asset externalization details by loan id gives numberOfElements: 3 with correct ownerExternalId and the following data:
|
||||
| settlementDate | purchasePriceRatio | status | effectiveFrom | effectiveTo | Transaction type |
|
||||
| 2024-01-21 | 1 | PENDING | 2024-01-01 | 2024-01-21 | SALE |
|
||||
| 2024-01-21 | 1 | ACTIVE | 2024-01-22 | 9999-12-31 | SALE |
|
||||
| 2024-02-03 | 1 | BUYBACK | 2024-02-03 | 9999-12-31 | BUYBACK |
|
||||
When Admin sets the business date to "04 May 2024"
|
||||
When Admin runs inline COB job for Loan
|
||||
Then LoanOwnershipTransferBusinessEvent is created
|
||||
Then LoanAccountSnapshotBusinessEvent is created
|
||||
Then Fetching Asset externalization details by loan id gives numberOfElements: 3 with correct ownerExternalId and the following data:
|
||||
| settlementDate | purchasePriceRatio | status | effectiveFrom | effectiveTo | Transaction type |
|
||||
| 2024-01-21 | 1 | PENDING | 2024-01-01 | 2024-01-21 | SALE |
|
||||
| 2024-01-21 | 1 | ACTIVE | 2024-01-22 | 2024-02-03 | SALE |
|
||||
| 2024-02-03 | 1 | BUYBACK | 2024-02-03 | 2024-02-03 | BUYBACK |
|
||||
Then The latest asset externalization transaction with "BUYBACK" status has the following TRANSFER Journal entries:
|
||||
| glAccountType | glAccountCode | glAccountName | entryType | amount |
|
||||
| EXPENSE | 744007 | Credit Loss/Bad Debt | DEBIT | 100.00 |
|
||||
| INCOME | 404001 | Interest Income Charge Off | DEBIT | 0.62 |
|
||||
| ASSET | 146000 | Asset transfer | CREDIT | 100.62 |
|
||||
| EXPENSE | 744007 | Credit Loss/Bad Debt | CREDIT | 100.00 |
|
||||
| INCOME | 404001 | Interest Income Charge Off | CREDIT | 0.62 |
|
||||
| ASSET | 146000 | Asset transfer | DEBIT | 100.62 |
|
||||
Then The asset external owner has the following OWNER Journal entries:
|
||||
| glAccountType | glAccountCode | glAccountName | entryType | amount |
|
||||
| ASSET | 112601 | Loans Receivable | DEBIT | 100.00 |
|
||||
| ASSET | 112603 | Interest/Fee Receivable | DEBIT | 2.04 |
|
||||
| ASSET | 112603 | Interest/Fee Receivable | DEBIT | 0.24 |
|
||||
| INCOME | 404000 | Interest Income | CREDIT | 0.24 |
|
||||
| ASSET | 112601 | Loans Receivable | CREDIT | 100.00 |
|
||||
| ASSET | 112603 | Interest/Fee Receivable | CREDIT | 0.62 |
|
||||
| EXPENSE | 744007 | Credit Loss/Bad Debt | DEBIT | 100.00 |
|
||||
| INCOME | 404001 | Interest Income Charge Off | DEBIT | 0.62 |
|
||||
| EXPENSE | 744007 | Credit Loss/Bad Debt | CREDIT | 100.00 |
|
||||
| INCOME | 404001 | Interest Income Charge Off | CREDIT | 0.62 |
|
||||
+5
@@ -90,6 +90,11 @@ public class InvestorAccountingHelper {
|
||||
}
|
||||
}
|
||||
|
||||
public ProductToGLAccountMapping getChargeOffMappingByCodeValue(final Long loanProductId, final PortfolioProductType productType,
|
||||
final Long chargeOffReasonId) {
|
||||
return accountMappingRepository.findChargeOffReasonMapping(loanProductId, productType.getValue(), chargeOffReasonId);
|
||||
}
|
||||
|
||||
private JournalEntry createCreditJournalEntryForInvestor(final Office office, final String currencyCode, final GLAccount account,
|
||||
final Long loanId, final Long transactionId, final LocalDate transactionDate, final BigDecimal amount) {
|
||||
final boolean manualEntry = false;
|
||||
|
||||
+48
-35
@@ -31,6 +31,8 @@ import org.apache.fineract.accounting.financialactivityaccount.domain.FinancialA
|
||||
import org.apache.fineract.accounting.financialactivityaccount.domain.FinancialActivityAccountRepositoryWrapper;
|
||||
import org.apache.fineract.accounting.glaccount.domain.GLAccount;
|
||||
import org.apache.fineract.accounting.journalentry.domain.JournalEntry;
|
||||
import org.apache.fineract.accounting.producttoaccountmapping.domain.ProductToGLAccountMapping;
|
||||
import org.apache.fineract.infrastructure.core.service.MathUtil;
|
||||
import org.apache.fineract.investor.accounting.journalentry.service.InvestorAccountingHelper;
|
||||
import org.apache.fineract.investor.domain.ExternalAssetOwner;
|
||||
import org.apache.fineract.investor.domain.ExternalAssetOwnerJournalEntryMapping;
|
||||
@@ -39,6 +41,7 @@ import org.apache.fineract.investor.domain.ExternalAssetOwnerTransfer;
|
||||
import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferJournalEntryMapping;
|
||||
import org.apache.fineract.investor.domain.ExternalAssetOwnerTransferJournalEntryMappingRepository;
|
||||
import org.apache.fineract.organisation.office.domain.Office;
|
||||
import org.apache.fineract.portfolio.PortfolioProductType;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -94,7 +97,8 @@ public class AccountingServiceImpl implements AccountingService {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<JournalEntry> createJournalEntries(Loan loan, ExternalAssetOwnerTransfer transfer, boolean isReversalOrder) {
|
||||
private List<JournalEntry> createJournalEntries(final Loan loan, final ExternalAssetOwnerTransfer transfer,
|
||||
final boolean isReversalOrder) {
|
||||
this.helper.checkForBranchClosures(loan.getOffice().getId(), transfer.getSettlementDate());
|
||||
// transaction properties
|
||||
final Long transactionId = transfer.getId();
|
||||
@@ -106,8 +110,8 @@ public class AccountingServiceImpl implements AccountingService {
|
||||
final BigDecimal overPaymentAmount = loan.getTotalOverpaid();
|
||||
|
||||
// Moving money to asset transfer account
|
||||
List<JournalEntry> journalEntryList = createJournalEntries(loan, transactionId, transactionDate, principalAmount, interestAmount,
|
||||
feesAmount, penaltiesAmount, overPaymentAmount, !isReversalOrder);
|
||||
final List<JournalEntry> journalEntryList = createJournalEntries(loan, transactionId, transactionDate, principalAmount,
|
||||
interestAmount, feesAmount, penaltiesAmount, overPaymentAmount, !isReversalOrder);
|
||||
// Moving money from asset transfer account
|
||||
journalEntryList.addAll(createJournalEntries(loan, transactionId, transactionDate, principalAmount, interestAmount, feesAmount,
|
||||
penaltiesAmount, overPaymentAmount, isReversalOrder));
|
||||
@@ -171,82 +175,91 @@ public class AccountingServiceImpl implements AccountingService {
|
||||
});
|
||||
}
|
||||
|
||||
private List<JournalEntry> createJournalEntries(Loan loan, Long transactionId, LocalDate transactionDate, BigDecimal principalAmount,
|
||||
BigDecimal interestAmount, BigDecimal feesAmount, BigDecimal penaltiesAmount, BigDecimal overPaymentAmount,
|
||||
boolean isReversalOrder) {
|
||||
Long loanProductId = loan.productId();
|
||||
Long loanId = loan.getId();
|
||||
Office office = loan.getOffice();
|
||||
String currencyCode = loan.getCurrencyCode();
|
||||
List<JournalEntry> journalEntryList = new ArrayList<>();
|
||||
private List<JournalEntry> createJournalEntries(final Loan loan, final Long transactionId, final LocalDate transactionDate,
|
||||
final BigDecimal principalAmount, final BigDecimal interestAmount, final BigDecimal feesAmount,
|
||||
final BigDecimal penaltiesAmount, final BigDecimal overPaymentAmount, final boolean isReversalOrder) {
|
||||
final Long loanProductId = loan.productId();
|
||||
final Long loanId = loan.getId();
|
||||
final Office office = loan.getOffice();
|
||||
final String currencyCode = loan.getCurrencyCode();
|
||||
final List<JournalEntry> journalEntryList = new ArrayList<>();
|
||||
BigDecimal totalDebitAmount = BigDecimal.ZERO;
|
||||
Map<GLAccount, BigDecimal> accountMap = new LinkedHashMap<>();
|
||||
final Map<GLAccount, BigDecimal> accountMap = new LinkedHashMap<>();
|
||||
// principal entry
|
||||
if (principalAmount != null && principalAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
AccountingConstants.AccrualAccountsForLoan accrualAccount = AccountingConstants.AccrualAccountsForLoan.LOAN_PORTFOLIO;
|
||||
if (loan.isChargedOff()) {
|
||||
if (loan.isFraud()) {
|
||||
accrualAccount = AccountingConstants.AccrualAccountsForLoan.CHARGE_OFF_FRAUD_EXPENSE;
|
||||
} else {
|
||||
accrualAccount = AccountingConstants.AccrualAccountsForLoan.CHARGE_OFF_EXPENSE;
|
||||
}
|
||||
}
|
||||
if (MathUtil.isGreaterThanZero(principalAmount)) {
|
||||
totalDebitAmount = totalDebitAmount.add(principalAmount);
|
||||
GLAccount account = this.helper.getLinkedGLAccountForLoanProduct(loanProductId, accrualAccount.getValue());
|
||||
GLAccount account;
|
||||
if (loan.isChargedOff()) {
|
||||
final Long chargeOffReasonId = loan.fetchChargeOffReasonId();
|
||||
final ProductToGLAccountMapping mapping = chargeOffReasonId != null
|
||||
? helper.getChargeOffMappingByCodeValue(loanProductId, PortfolioProductType.LOAN, chargeOffReasonId)
|
||||
: null;
|
||||
if (mapping != null) {
|
||||
account = mapping.getGlAccount();
|
||||
} else {
|
||||
final AccountingConstants.AccrualAccountsForLoan accrualAccount = loan.isFraud()
|
||||
? AccountingConstants.AccrualAccountsForLoan.CHARGE_OFF_FRAUD_EXPENSE
|
||||
: AccountingConstants.AccrualAccountsForLoan.CHARGE_OFF_EXPENSE;
|
||||
account = helper.getLinkedGLAccountForLoanProduct(loanProductId, accrualAccount.getValue());
|
||||
}
|
||||
} else {
|
||||
account = helper.getLinkedGLAccountForLoanProduct(loanProductId,
|
||||
AccountingConstants.AccrualAccountsForLoan.LOAN_PORTFOLIO.getValue());
|
||||
}
|
||||
accountMap.put(account, principalAmount);
|
||||
}
|
||||
// interest entry
|
||||
if (interestAmount != null && interestAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(interestAmount)) {
|
||||
AccountingConstants.AccrualAccountsForLoan accrualAccount = AccountingConstants.AccrualAccountsForLoan.INTEREST_RECEIVABLE;
|
||||
if (loan.isChargedOff()) {
|
||||
accrualAccount = AccountingConstants.AccrualAccountsForLoan.INCOME_FROM_CHARGE_OFF_INTEREST;
|
||||
}
|
||||
totalDebitAmount = totalDebitAmount.add(interestAmount);
|
||||
GLAccount account = this.helper.getLinkedGLAccountForLoanProduct(loanProductId, accrualAccount.getValue());
|
||||
final GLAccount account = this.helper.getLinkedGLAccountForLoanProduct(loanProductId, accrualAccount.getValue());
|
||||
if (accountMap.containsKey(account)) {
|
||||
BigDecimal amount = accountMap.get(account).add(interestAmount);
|
||||
final BigDecimal amount = accountMap.get(account).add(interestAmount);
|
||||
accountMap.put(account, amount);
|
||||
} else {
|
||||
accountMap.put(account, interestAmount);
|
||||
}
|
||||
}
|
||||
// fee entry
|
||||
if (feesAmount != null && feesAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(feesAmount)) {
|
||||
AccountingConstants.AccrualAccountsForLoan accrualAccount = AccountingConstants.AccrualAccountsForLoan.FEES_RECEIVABLE;
|
||||
if (loan.isChargedOff()) {
|
||||
accrualAccount = AccountingConstants.AccrualAccountsForLoan.INCOME_FROM_CHARGE_OFF_FEES;
|
||||
}
|
||||
totalDebitAmount = totalDebitAmount.add(feesAmount);
|
||||
GLAccount account = this.helper.getLinkedGLAccountForLoanProduct(loanProductId, accrualAccount.getValue());
|
||||
final GLAccount account = this.helper.getLinkedGLAccountForLoanProduct(loanProductId, accrualAccount.getValue());
|
||||
if (accountMap.containsKey(account)) {
|
||||
BigDecimal amount = accountMap.get(account).add(feesAmount);
|
||||
final BigDecimal amount = accountMap.get(account).add(feesAmount);
|
||||
accountMap.put(account, amount);
|
||||
} else {
|
||||
accountMap.put(account, feesAmount);
|
||||
}
|
||||
}
|
||||
// penalty entry
|
||||
if (penaltiesAmount != null && penaltiesAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(penaltiesAmount)) {
|
||||
AccountingConstants.AccrualAccountsForLoan accrualAccount = AccountingConstants.AccrualAccountsForLoan.PENALTIES_RECEIVABLE;
|
||||
if (loan.isChargedOff()) {
|
||||
accrualAccount = AccountingConstants.AccrualAccountsForLoan.INCOME_FROM_CHARGE_OFF_PENALTY;
|
||||
}
|
||||
totalDebitAmount = totalDebitAmount.add(penaltiesAmount);
|
||||
GLAccount account = this.helper.getLinkedGLAccountForLoanProduct(loanProductId, accrualAccount.getValue());
|
||||
final GLAccount account = this.helper.getLinkedGLAccountForLoanProduct(loanProductId, accrualAccount.getValue());
|
||||
if (accountMap.containsKey(account)) {
|
||||
BigDecimal amount = accountMap.get(account).add(penaltiesAmount);
|
||||
final BigDecimal amount = accountMap.get(account).add(penaltiesAmount);
|
||||
accountMap.put(account, amount);
|
||||
} else {
|
||||
accountMap.put(account, penaltiesAmount);
|
||||
}
|
||||
}
|
||||
// overpaid entry
|
||||
if (overPaymentAmount != null && overPaymentAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(overPaymentAmount)) {
|
||||
totalDebitAmount = totalDebitAmount.add(overPaymentAmount);
|
||||
GLAccount account = this.helper.getLinkedGLAccountForLoanProduct(loanProductId,
|
||||
final GLAccount account = this.helper.getLinkedGLAccountForLoanProduct(loanProductId,
|
||||
AccountingConstants.AccrualAccountsForLoan.OVERPAYMENT.getValue());
|
||||
if (accountMap.containsKey(account)) {
|
||||
BigDecimal amount = accountMap.get(account).add(overPaymentAmount);
|
||||
final BigDecimal amount = accountMap.get(account).add(overPaymentAmount);
|
||||
accountMap.put(account, amount);
|
||||
} else {
|
||||
accountMap.put(account, overPaymentAmount);
|
||||
@@ -257,7 +270,7 @@ public class AccountingServiceImpl implements AccountingService {
|
||||
journalEntryList.add(this.helper.createCreditJournalEntryOrReversalForInvestor(office, currencyCode, loanId, transactionId,
|
||||
transactionDate, entry.getValue(), isReversalOrder, entry.getKey()));
|
||||
}
|
||||
if (totalDebitAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(totalDebitAmount)) {
|
||||
journalEntryList.add(this.helper.createDebitJournalEntryOrReversalForInvestor(office, currencyCode,
|
||||
AccountingConstants.FinancialActivity.ASSET_TRANSFER.getValue(), loanProductId, loanId, transactionId, transactionDate,
|
||||
totalDebitAmount, isReversalOrder));
|
||||
|
||||
Reference in New Issue
Block a user