FINERACT-2210: Fix journal entries creation issue when amount is null
This commit is contained in:
committed by
Adam Saghy
parent
a1d51e1e34
commit
a11c567413
+1
@@ -106,6 +106,7 @@ public enum DefaultLoanProduct implements LoanProduct {
|
||||
LP2_ACCELERATE_MATURITY_CHARGE_OFF_BEHAVIOUR_LAST_INSTALLMENT_STRATEGY, //
|
||||
LP2_ADV_PYMNT_INTEREST_DAILY_INT_RECALCULATION_ZERO_INT_CHARGE_OFF_INT_RECOGNITION_FROM_DISB_DATE, //
|
||||
LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF_DELINQUENT_REASON, //
|
||||
LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF_DELINQUENT_REASON_INTEREST_RECALC, //
|
||||
LP2_ADV_DP_CUSTOM_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_HORIZONTAL, //
|
||||
LP2_ADV_DP_IR_CUSTOM_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_HORIZONTAL, //
|
||||
LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALC_DAILY_DISBURSEMENT_CHARGES, //
|
||||
|
||||
+34
@@ -2227,6 +2227,40 @@ public class LoanProductGlobalInitializerStep implements FineractGlobalInitializ
|
||||
TestContext.INSTANCE.set(
|
||||
TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALC_DAILY_CASH_ACCOUNTING_DISBURSEMENT_CHARGES,
|
||||
responseLoanProductsRequestLP2AdvancedpaymentInterestEmi36030InterestRecalcDailyCashAccountingDisbursementCharge);
|
||||
|
||||
// LP2 + zero-interest chargeOff behaviour + progressive loan schedule + horizontal + delinquent charge-off
|
||||
// reason to GL account mapping + interest recalculation
|
||||
// (LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF_DELINQUENT_REASON_INTEREST_RECALC)
|
||||
final String name90 = DefaultLoanProduct.LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF_DELINQUENT_REASON_INTEREST_RECALC.getName();
|
||||
|
||||
final PostLoanProductsRequest loanProductsRequestAdvZeroInterestChargeOffProgressiveDelinquentReasonIntRecalc = loanProductsRequestFactory
|
||||
.defaultLoanProductsRequestLP2ChargeOffReasonToExpenseAccountMappings()//
|
||||
.name(name90)//
|
||||
.enableDownPayment(false)//
|
||||
.isInterestRecalculationEnabled(true)//
|
||||
.preClosureInterestCalculationStrategy(1)//
|
||||
.rescheduleStrategyMethod(4)//
|
||||
.interestRecalculationCompoundingMethod(0)//
|
||||
.recalculationRestFrequencyType(2)//
|
||||
.recalculationRestFrequencyInterval(1)//
|
||||
.enableAutoRepaymentForDownPayment(null)//
|
||||
.disbursedAmountPercentageForDownPayment(null)//
|
||||
.transactionProcessingStrategyCode(ADVANCED_PAYMENT_ALLOCATION.getValue())//
|
||||
.loanScheduleType("PROGRESSIVE") //
|
||||
.loanScheduleProcessingType("HORIZONTAL")//
|
||||
.interestRateFrequencyType(3)//
|
||||
.maxInterestRatePerPeriod(10.0)//
|
||||
.paymentAllocation(List.of(//
|
||||
createPaymentAllocation("DEFAULT", "NEXT_INSTALLMENT"), //
|
||||
createPaymentAllocation("GOODWILL_CREDIT", "LAST_INSTALLMENT"), //
|
||||
createPaymentAllocation("MERCHANT_ISSUED_REFUND", "REAMORTIZATION"), //
|
||||
createPaymentAllocation("PAYOUT_REFUND", "NEXT_INSTALLMENT")))//
|
||||
.chargeOffBehaviour("ZERO_INTEREST");//
|
||||
final Response<PostLoanProductsResponse> responseLoanProductsRequestAdvZeroInterestChargeOffProgressiveDelinquentReasonIntRecalc = loanProductsApi
|
||||
.createLoanProduct(loanProductsRequestAdvZeroInterestChargeOffProgressiveDelinquentReasonIntRecalc).execute();
|
||||
TestContext.INSTANCE.set(
|
||||
TestContextKey.DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF_DELINQUENT_REASON_INTEREST_RECALC,
|
||||
responseLoanProductsRequestAdvZeroInterestChargeOffProgressiveDelinquentReasonIntRecalc);
|
||||
}
|
||||
|
||||
public static AdvancedPaymentData createPaymentAllocation(String transactionType, String futureInstallmentAllocationRule,
|
||||
|
||||
+1
@@ -117,6 +117,7 @@ public abstract class TestContextKey {
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR = "loanProductCreateResponseLP2AdvancedPaymentZeroInterestChargeOffBehaviour";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF = "loanProductCreateResponseLP2AdvancedPaymentZeroInterestChargeOff";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF_DELINQUENT_REASON = "loanProductCreateResponseLP2AdvancedPaymentZeroInterestChargeOffDelinquentReason";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF_DELINQUENT_REASON_INTEREST_RECALC = "loanProductCreateResponseLP2AdvancedPaymentZeroInterestChargeOffDelinquentReasonInterestRecalculation";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADVANCED_DP_CUSTOM_PAYMENT_ALLOCATION_PROGRESSIVE_LOAN_SCHEDULE = "loanProductCreateResponseLP2ProgressiveLoanScheduleDPCustomPaymentAllocation";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADVANCED_DP_IR_CUSTOM_PAYMENT_ALLOCATION_PROGRESSIVE_LOAN_SCHEDULE = "loanProductCreateResponseLP2ProgressiveLoanScheduleDPIRCustomPaymentAllocation";
|
||||
public static final String DEFAULT_LOAN_PRODUCT_CREATE_RESPONSE_LP2_ADV_PYMNT_INTEREST_DAILY_EMI_360_30_INTEREST_RECALCULATION_DAILY_ALLOW_PARTIAL_PERIOD = "loanProductCreateResponseLP2AdvancedPaymentInterestDailyEmi36030InterestRecalculationDailyAllowPartialPeriod";
|
||||
|
||||
@@ -8123,3 +8123,225 @@ Feature: Charge-off
|
||||
And Loan Charges tab has the following data:
|
||||
| Name | isPenalty | Payment due at | Due as of | Calculation type | Due | Paid | Waived | Outstanding |
|
||||
| Snooze fee | false | Specified due date | 23 January 2024 | Flat | 5.0 | 0.0 | 5.0 | 0.0 |
|
||||
|
||||
@TestRailId:C3611
|
||||
Scenario: As a user I want to verify that backdated transactions are allowed after charge-off and backdated full repayment, interestRecalculation = false
|
||||
When Admin sets the business date to "11 March 2025"
|
||||
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 | 11 March 2025 | 500 | 7 | DECLINING_BALANCE | SAME_AS_REPAYMENT_PERIOD | EQUAL_INSTALLMENTS | 6 | MONTHS | 1 | MONTHS | 6 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION |
|
||||
And Admin successfully approves the loan on "11 March 2025" with "500" amount and expected disbursement date on "11 March 2025"
|
||||
And Admin successfully disburse the loan on "11 March 2025" with "500" EUR transaction amount
|
||||
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 | Waived | Outstanding |
|
||||
| | | 11 March 2025 | | 500.0 | | | 0.0 | | 0.0 | 0.0 | | | | |
|
||||
| 1 | 31 | 11 April 2025 | | 417.97 | 82.03 | 2.97 | 0.0 | 0.0 | 85.0 | 0.0 | 0.0 | 0.0 | 0.0 | 85.0 |
|
||||
| 2 | 30 | 11 May 2025 | | 335.37 | 82.6 | 2.4 | 0.0 | 0.0 | 85.0 | 0.0 | 0.0 | 0.0 | 0.0 | 85.0 |
|
||||
| 3 | 31 | 11 June 2025 | | 252.36 | 83.01 | 1.99 | 0.0 | 0.0 | 85.0 | 0.0 | 0.0 | 0.0 | 0.0 | 85.0 |
|
||||
| 4 | 30 | 11 July 2025 | | 168.81 | 83.55 | 1.45 | 0.0 | 0.0 | 85.0 | 0.0 | 0.0 | 0.0 | 0.0 | 85.0 |
|
||||
| 5 | 31 | 11 August 2025 | | 84.81 | 84.0 | 1.0 | 0.0 | 0.0 | 85.0 | 0.0 | 0.0 | 0.0 | 0.0 | 85.0 |
|
||||
| 6 | 31 | 11 September 2025| | 0.0 | 84.81 | 0.5 | 0.0 | 0.0 | 85.31 | 0.0 | 0.0 | 0.0 | 0.0 | 85.31 |
|
||||
Then Loan Repayment schedule has the following data in Total row:
|
||||
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Waived | Outstanding |
|
||||
| 500.0 | 10.31 | 0.0 | 0 | 510.31 | 0.0 | 0 | 0 | 0.0 | 510.31 |
|
||||
Then Loan Transactions tab has the following data:
|
||||
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
|
||||
| 11 March 2025 | Disbursement | 500.0 | 0.0 | 0.0 | 0.0 | 0.0 | 500.0 | false | false |
|
||||
Then Admin can successfully set Fraud flag to the loan
|
||||
When Admin runs inline COB job for Loan
|
||||
When Admin sets the business date to "14 April 2025"
|
||||
And Admin does charge-off the loan with reason "DELINQUENT" on "14 April 2025"
|
||||
Then Loan marked as charged-off on "14 April 2025"
|
||||
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 | Waived | Outstanding |
|
||||
| | | 11 March 2025 | | 500.0 | | | 0.0 | | 0.0 | 0.0 | | | | |
|
||||
| 1 | 31 | 11 April 2025 | | 417.97 | 82.03 | 2.97 | 0.0 | 0.0 | 85.0 | 0.0 | 0.0 | 0.0 | 0.0 | 85.0 |
|
||||
| 2 | 30 | 11 May 2025 | | 333.21 | 84.76 | 0.24 | 0.0 | 0.0 | 85.0 | 0.0 | 0.0 | 0.0 | 0.0 | 85.0 |
|
||||
| 3 | 31 | 11 June 2025 | | 248.21 | 85.0 | 0.0 | 0.0 | 0.0 | 85.0 | 0.0 | 0.0 | 0.0 | 0.0 | 85.0 |
|
||||
| 4 | 30 | 11 July 2025 | | 163.21 | 85.0 | 0.0 | 0.0 | 0.0 | 85.0 | 0.0 | 0.0 | 0.0 | 0.0 | 85.0 |
|
||||
| 5 | 31 | 11 August 2025 | | 78.21 | 85.0 | 0.0 | 0.0 | 0.0 | 85.0 | 0.0 | 0.0 | 0.0 | 0.0 | 85.0 |
|
||||
| 6 | 31 | 11 September 2025 | | 0.0 | 78.21 | 0.0 | 0.0 | 0.0 | 78.21 | 0.0 | 0.0 | 0.0 | 0.0 | 78.21 |
|
||||
Then Loan Repayment schedule has the following data in Total row:
|
||||
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Waived | Outstanding |
|
||||
| 500.0 | 3.21 | 0.0 | 0 | 503.21 | 0 | 0 | 0 | 0.0 | 503.21 |
|
||||
Then Loan Transactions tab has the following data:
|
||||
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
|
||||
| 11 March 2025 | Disbursement | 500.0 | 0.0 | 0.0 | 0.0 | 0.0 | 500.0 | false | false |
|
||||
| 14 April 2025 | Accrual | 3.21 | 0.0 | 3.21 | 0.0 | 0.0 | 0.0 | false | false |
|
||||
| 14 April 2025 | Charge-off | 503.21 | 500.0 | 3.21 | 0.0 | 0.0 | 0.0 | false | false |
|
||||
When Admin runs inline COB job for Loan
|
||||
When Customer makes "REPAYMENT" transaction with "AUTOPAY" payment type on "13 April 2025" with 500 EUR transaction amount and system-generated Idempotency key
|
||||
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 | Waived | Outstanding |
|
||||
| | | 11 March 2025 | | 500.0 | | | 0.0 | | 0.0 | 0.0 | | | | |
|
||||
| 1 | 31 | 11 April 2025 | 13 April 2025 | 417.97 | 82.03 | 2.97 | 0.0 | 0.0 | 85.0 | 85.0 | 0.0 | 85.0 | 0.0 | 0.0 |
|
||||
| 2 | 30 | 11 May 2025 | 13 April 2025 | 335.37 | 82.6 | 2.4 | 0.0 | 0.0 | 85.0 | 85.0 | 85.0 | 0.0 | 0.0 | 0.0 |
|
||||
| 3 | 31 | 11 June 2025 | 13 April 2025 | 252.36 | 83.01 | 1.99 | 0.0 | 0.0 | 85.0 | 85.0 | 85.0 | 0.0 | 0.0 | 0.0 |
|
||||
| 4 | 30 | 11 July 2025 | 13 April 2025 | 168.81 | 83.55 | 1.45 | 0.0 | 0.0 | 85.0 | 85.0 | 85.0 | 0.0 | 0.0 | 0.0 |
|
||||
| 5 | 31 | 11 August 2025 | 13 April 2025 | 84.81 | 84.0 | 1.0 | 0.0 | 0.0 | 85.0 | 85.0 | 85.0 | 0.0 | 0.0 | 0.0 |
|
||||
| 6 | 31 | 11 September 2025 | | 0.0 | 84.81 | 0.0 | 0.0 | 0.0 | 84.81 | 75.0 | 75.0 | 0.0 | 0.0 | 9.81 |
|
||||
Then Loan Repayment schedule has the following data in Total row:
|
||||
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Waived | Outstanding |
|
||||
| 500.0 | 9.81 | 0.0 | 0 | 509.81 | 500.0 | 415.0 | 85.0 | 0.0 | 9.81 |
|
||||
Then Loan Transactions tab has the following data:
|
||||
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
|
||||
| 11 March 2025 | Disbursement | 500.0 | 0.0 | 0.0 | 0.0 | 0.0 | 500.0 | false | false |
|
||||
| 13 April 2025 | Repayment | 500.0 | 490.19 | 9.81 | 0.0 | 0.0 | 9.81 | false | false |
|
||||
| 14 April 2025 | Accrual | 3.21 | 0.0 | 3.21 | 0.0 | 0.0 | 0.0 | false | false |
|
||||
| 14 April 2025 | Accrual Adjustment | 0.24 | 0.0 | 0.24 | 0.0 | 0.0 | 0.0 | false | false |
|
||||
| 14 April 2025 | Charge-off | 9.81 | 9.81 | 0.0 | 0.0 | 0.0 | 0.0 | false | true |
|
||||
When Customer makes "MERCHANT_ISSUED_REFUND" transaction with "AUTOPAY" payment type on "13 April 2025" with 500 EUR transaction amount and system-generated Idempotency key
|
||||
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 | Waived | Outstanding |
|
||||
| | | 11 March 2025 | | 500.0 | | | 0.0 | | 0.0 | 0.0 | | | | |
|
||||
| 1 | 31 | 11 April 2025 | 13 April 2025 | 417.97 | 82.03 | 2.97 | 0.0 | 0.0 | 85.0 | 85.0 | 0.0 | 85.0 | 0.0 | 0.0 |
|
||||
| 2 | 30 | 11 May 2025 | 13 April 2025 | 335.37 | 82.6 | 2.4 | 0.0 | 0.0 | 85.0 | 85.0 | 85.0 | 0.0 | 0.0 | 0.0 |
|
||||
| 3 | 31 | 11 June 2025 | 13 April 2025 | 252.36 | 83.01 | 1.99 | 0.0 | 0.0 | 85.0 | 85.0 | 85.0 | 0.0 | 0.0 | 0.0 |
|
||||
| 4 | 30 | 11 July 2025 | 13 April 2025 | 168.81 | 83.55 | 1.45 | 0.0 | 0.0 | 85.0 | 85.0 | 85.0 | 0.0 | 0.0 | 0.0 |
|
||||
| 5 | 31 | 11 August 2025 | 13 April 2025 | 84.81 | 84.0 | 1.0 | 0.0 | 0.0 | 85.0 | 85.0 | 85.0 | 0.0 | 0.0 | 0.0 |
|
||||
| 6 | 31 | 11 September 2025 | 13 April 2025 | 0.0 | 84.81 | 0.5 | 0.0 | 0.0 | 85.31 | 85.31 | 85.31 | 0.0 | 0.0 | 0.0 |
|
||||
Then Loan Repayment schedule has the following data in Total row:
|
||||
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Waived | Outstanding |
|
||||
| 500.0 | 10.31 | 0.0 | 0 | 510.31 | 510.31 | 425.31 | 85.0 | 0.0 | 0.0 |
|
||||
Then Loan Transactions tab has the following data:
|
||||
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
|
||||
| 11 March 2025 | Disbursement | 500.0 | 0.0 | 0.0 | 0.0 | 0.0 | 500.0 | false | false |
|
||||
| 13 April 2025 | Repayment | 500.0 | 490.19 | 9.81 | 0.0 | 0.0 | 9.81 | false | false |
|
||||
| 13 April 2025 | Merchant Issued Refund | 500.0 | 9.81 | 0.5 | 0.0 | 0.0 | 0.0 | false | false |
|
||||
| 14 April 2025 | Accrual | 3.21 | 0.0 | 3.21 | 0.0 | 0.0 | 0.0 | false | false |
|
||||
| 14 April 2025 | Accrual Adjustment | 0.24 | 0.0 | 0.24 | 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 |
|
||||
When Customer makes "GOODWILL_CREDIT" transaction with "AUTOPAY" payment type on "13 April 2025" with 500 EUR transaction amount and system-generated Idempotency key
|
||||
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 | Waived | Outstanding |
|
||||
| | | 11 March 2025 | | 500.0 | | | 0.0 | | 0.0 | 0.0 | | | | |
|
||||
| 1 | 31 | 11 April 2025 | 13 April 2025 | 417.97 | 82.03 | 2.97 | 0.0 | 0.0 | 85.0 | 85.0 | 0.0 | 85.0 | 0.0 | 0.0 |
|
||||
| 2 | 30 | 11 May 2025 | 13 April 2025 | 335.37 | 82.6 | 2.4 | 0.0 | 0.0 | 85.0 | 85.0 | 85.0 | 0.0 | 0.0 | 0.0 |
|
||||
| 3 | 31 | 11 June 2025 | 13 April 2025 | 252.36 | 83.01 | 1.99 | 0.0 | 0.0 | 85.0 | 85.0 | 85.0 | 0.0 | 0.0 | 0.0 |
|
||||
| 4 | 30 | 11 July 2025 | 13 April 2025 | 168.81 | 83.55 | 1.45 | 0.0 | 0.0 | 85.0 | 85.0 | 85.0 | 0.0 | 0.0 | 0.0 |
|
||||
| 5 | 31 | 11 August 2025 | 13 April 2025 | 84.81 | 84.0 | 1.0 | 0.0 | 0.0 | 85.0 | 85.0 | 85.0 | 0.0 | 0.0 | 0.0 |
|
||||
| 6 | 31 | 11 September 2025 | 13 April 2025 | 0.0 | 84.81 | 0.5 | 0.0 | 0.0 | 85.31 | 85.31 | 85.31 | 0.0 | 0.0 | 0.0 |
|
||||
Then Loan Repayment schedule has the following data in Total row:
|
||||
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Waived | Outstanding |
|
||||
| 500.0 | 10.31 | 0.0 | 0 | 510.31 | 510.31 | 425.31 | 85.0 | 0.0 | 0.0 |
|
||||
Then Loan Transactions tab has the following data:
|
||||
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
|
||||
| 11 March 2025 | Disbursement | 500.0 | 0.0 | 0.0 | 0.0 | 0.0 | 500.0 | false | false |
|
||||
| 13 April 2025 | Repayment | 500.0 | 490.19 | 9.81 | 0.0 | 0.0 | 9.81 | false | false |
|
||||
| 13 April 2025 | Merchant Issued Refund | 500.0 | 9.81 | 0.5 | 0.0 | 0.0 | 0.0 | false | false |
|
||||
| 13 April 2025 | Goodwill Credit | 500.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | false | false |
|
||||
| 14 April 2025 | Accrual | 3.21 | 0.0 | 3.21 | 0.0 | 0.0 | 0.0 | false | false |
|
||||
| 14 April 2025 | Accrual Adjustment | 0.24 | 0.0 | 0.24 | 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:C3612
|
||||
Scenario: As a user I want to verify that backdated transactions are allowed after charge-off and backdated full repayment, interestRecalculation = true
|
||||
When Admin sets the business date to "11 March 2025"
|
||||
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_INTEREST_RECALC | 11 March 2025 | 500 | 7 | DECLINING_BALANCE | SAME_AS_REPAYMENT_PERIOD | EQUAL_INSTALLMENTS | 6 | MONTHS | 1 | MONTHS | 6 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION |
|
||||
And Admin successfully approves the loan on "11 March 2025" with "500" amount and expected disbursement date on "11 March 2025"
|
||||
And Admin successfully disburse the loan on "11 March 2025" with "500" EUR transaction amount
|
||||
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 | Waived | Outstanding |
|
||||
| | | 11 March 2025 | | 500.0 | | | 0.0 | | 0.0 | 0.0 | | | | |
|
||||
| 1 | 31 | 11 April 2025 | | 417.97 | 82.03 | 2.97 | 0.0 | 0.0 | 85.0 | 0.0 | 0.0 | 0.0 | 0.0 | 85.0 |
|
||||
| 2 | 30 | 11 May 2025 | | 335.37 | 82.6 | 2.4 | 0.0 | 0.0 | 85.0 | 0.0 | 0.0 | 0.0 | 0.0 | 85.0 |
|
||||
| 3 | 31 | 11 June 2025 | | 252.36 | 83.01 | 1.99 | 0.0 | 0.0 | 85.0 | 0.0 | 0.0 | 0.0 | 0.0 | 85.0 |
|
||||
| 4 | 30 | 11 July 2025 | | 168.81 | 83.55 | 1.45 | 0.0 | 0.0 | 85.0 | 0.0 | 0.0 | 0.0 | 0.0 | 85.0 |
|
||||
| 5 | 31 | 11 August 2025 | | 84.81 | 84.0 | 1.0 | 0.0 | 0.0 | 85.0 | 0.0 | 0.0 | 0.0 | 0.0 | 85.0 |
|
||||
| 6 | 31 | 11 September 2025| | 0.0 | 84.81 | 0.5 | 0.0 | 0.0 | 85.31 | 0.0 | 0.0 | 0.0 | 0.0 | 85.31 |
|
||||
Then Loan Repayment schedule has the following data in Total row:
|
||||
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Waived | Outstanding |
|
||||
| 500.0 | 10.31 | 0.0 | 0 | 510.31 | 0.0 | 0 | 0 | 0.0 | 510.31 |
|
||||
Then Loan Transactions tab has the following data:
|
||||
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
|
||||
| 11 March 2025 | Disbursement | 500.0 | 0.0 | 0.0 | 0.0 | 0.0 | 500.0 | false | false |
|
||||
Then Admin can successfully set Fraud flag to the loan
|
||||
When Admin runs inline COB job for Loan
|
||||
When Admin sets the business date to "14 April 2025"
|
||||
And Admin does charge-off the loan with reason "DELINQUENT" on "14 April 2025"
|
||||
Then Loan marked as charged-off on "14 April 2025"
|
||||
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 | Waived | Outstanding |
|
||||
| | | 11 March 2025 | | 500.0 | | | 0.0 | | 0.0 | 0.0 | | | | |
|
||||
| 1 | 31 | 11 April 2025 | | 417.97 | 82.03 | 2.97 | 0.0 | 0.0 | 85.0 | 0.0 | 0.0 | 0.0 | 0.0 | 85.0 |
|
||||
| 2 | 30 | 11 May 2025 | | 333.26 | 84.71 | 0.29 | 0.0 | 0.0 | 85.0 | 0.0 | 0.0 | 0.0 | 0.0 | 85.0 |
|
||||
| 3 | 31 | 11 June 2025 | | 248.26 | 85.0 | 0.0 | 0.0 | 0.0 | 85.0 | 0.0 | 0.0 | 0.0 | 0.0 | 85.0 |
|
||||
| 4 | 30 | 11 July 2025 | | 163.26 | 85.0 | 0.0 | 0.0 | 0.0 | 85.0 | 0.0 | 0.0 | 0.0 | 0.0 | 85.0 |
|
||||
| 5 | 31 | 11 August 2025 | | 78.26 | 85.0 | 0.0 | 0.0 | 0.0 | 85.0 | 0.0 | 0.0 | 0.0 | 0.0 | 85.0 |
|
||||
| 6 | 31 | 11 September 2025 | | 0.0 | 78.26 | 0.0 | 0.0 | 0.0 | 78.26 | 0.0 | 0.0 | 0.0 | 0.0 | 78.26 |
|
||||
Then Loan Repayment schedule has the following data in Total row:
|
||||
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Waived | Outstanding |
|
||||
| 500.0 | 3.26 | 0.0 | 0 | 503.26 | 0.0 | 0 | 0 | 0.0 | 503.26 |
|
||||
Then Loan Transactions tab has the following data:
|
||||
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
|
||||
| 11 March 2025 | Disbursement | 500.0 | 0.0 | 0.0 | 0.0 | 0.0 | 500.0 | false | false |
|
||||
| 14 April 2025 | Accrual | 3.26 | 0.0 | 3.26 | 0.0 | 0.0 | 0.0 | false | false |
|
||||
| 14 April 2025 | Charge-off | 503.26 | 500.0 | 3.26 | 0.0 | 0.0 | 0.0 | false | false |
|
||||
When Admin runs inline COB job for Loan
|
||||
When Customer makes "REPAYMENT" transaction with "AUTOPAY" payment type on "13 April 2025" with 500 EUR transaction amount and system-generated Idempotency key
|
||||
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 | Waived | Outstanding |
|
||||
| | | 11 March 2025 | | 500.0 | | | 0.0 | | 0.0 | 0.0 | | | | |
|
||||
| 1 | 31 | 11 April 2025 | 13 April 2025 | 417.97 | 82.03 | 2.97 | 0.0 | 0.0 | 85.0 | 85.0 | 0.0 | 85.0 | 0.0 | 0.0 |
|
||||
| 2 | 30 | 11 May 2025 | 13 April 2025 | 333.16 | 84.81 | 0.19 | 0.0 | 0.0 | 85.0 | 85.0 | 85.0 | 0.0 | 0.0 | 0.0 |
|
||||
| 3 | 31 | 11 June 2025 | 13 April 2025 | 248.16 | 85.0 | 0.0 | 0.0 | 0.0 | 85.0 | 85.0 | 85.0 | 0.0 | 0.0 | 0.0 |
|
||||
| 4 | 30 | 11 July 2025 | 13 April 2025 | 163.16 | 85.0 | 0.0 | 0.0 | 0.0 | 85.0 | 85.0 | 85.0 | 0.0 | 0.0 | 0.0 |
|
||||
| 5 | 31 | 11 August 2025 | 13 April 2025 | 78.16 | 85.0 | 0.0 | 0.0 | 0.0 | 85.0 | 85.0 | 85.0 | 0.0 | 0.0 | 0.0 |
|
||||
| 6 | 31 | 11 September 2025 | | 0.0 | 78.16 | 0.0 | 0.0 | 0.0 | 78.16 | 75.0 | 75.0 | 0.0 | 0.0 | 3.16 |
|
||||
Then Loan Repayment schedule has the following data in Total row:
|
||||
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Waived | Outstanding |
|
||||
| 500.0 | 3.16 | 0.0 | 0 | 503.16 | 500.0 | 415.0 | 85.0 | 0.0 | 3.16 |
|
||||
Then Loan Transactions tab has the following data:
|
||||
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
|
||||
| 11 March 2025 | Disbursement | 500.0 | 0.0 | 0.0 | 0.0 | 0.0 | 500.0 | false | false |
|
||||
| 13 April 2025 | Repayment | 500.0 | 496.84 | 3.16 | 0.0 | 0.0 | 3.16 | false | false |
|
||||
| 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 | 3.16 | 3.16 | 0.0 | 0.0 | 0.0 | 0.0 | false | true |
|
||||
When Customer makes "MERCHANT_ISSUED_REFUND" transaction with "AUTOPAY" payment type on "13 April 2025" with 500 EUR transaction amount and system-generated Idempotency key
|
||||
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 | Waived | Outstanding |
|
||||
| | | 11 March 2025 | | 500.0 | | | 0.0 | | 0.0 | 0.0 | | | | |
|
||||
| 1 | 31 | 11 April 2025 | 13 April 2025 | 417.97 | 82.03 | 2.97 | 0.0 | 0.0 | 85.0 | 85.0 | 0.0 | 85.0 | 0.0 | 0.0 |
|
||||
| 2 | 30 | 11 May 2025 | 13 April 2025 | 333.16 | 84.81 | 0.19 | 0.0 | 0.0 | 85.0 | 85.0 | 85.0 | 0.0 | 0.0 | 0.0 |
|
||||
| 3 | 31 | 11 June 2025 | 13 April 2025 | 248.16 | 85.0 | 0.0 | 0.0 | 0.0 | 85.0 | 85.0 | 85.0 | 0.0 | 0.0 | 0.0 |
|
||||
| 4 | 30 | 11 July 2025 | 13 April 2025 | 163.16 | 85.0 | 0.0 | 0.0 | 0.0 | 85.0 | 85.0 | 85.0 | 0.0 | 0.0 | 0.0 |
|
||||
| 5 | 31 | 11 August 2025 | 13 April 2025 | 78.16 | 85.0 | 0.0 | 0.0 | 0.0 | 85.0 | 85.0 | 85.0 | 0.0 | 0.0 | 0.0 |
|
||||
| 6 | 31 | 11 September 2025 | 13 April 2025 | 0.0 | 78.16 | 0.0 | 0.0 | 0.0 | 78.16 | 78.16 | 78.16 | 0.0 | 0.0 | 0.0 |
|
||||
Then Loan Repayment schedule has the following data in Total row:
|
||||
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Waived | Outstanding |
|
||||
| 500.0 | 3.16 | 0.0 | 0 | 503.16 | 503.16 | 418.16 | 85.0 | 0.0 | 0.0 |
|
||||
Then Loan Transactions tab has the following data:
|
||||
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
|
||||
| 11 March 2025 | Disbursement | 500.0 | 0.0 | 0.0 | 0.0 | 0.0 | 500.0 | false | false |
|
||||
| 13 April 2025 | Repayment | 500.0 | 496.84 | 3.16 | 0.0 | 0.0 | 3.16 | false | false |
|
||||
| 13 April 2025 | Merchant Issued Refund | 500.0 | 3.16 | 0.0 | 0.0 | 0.0 | 0.0 | false | false |
|
||||
| 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 |
|
||||
When Customer makes "GOODWILL_CREDIT" transaction with "AUTOPAY" payment type on "13 April 2025" with 500 EUR transaction amount and system-generated Idempotency key
|
||||
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 | Waived | Outstanding |
|
||||
| | | 11 March 2025 | | 500.0 | | | 0.0 | | 0.0 | 0.0 | | | | |
|
||||
| 1 | 31 | 11 April 2025 | 13 April 2025 | 417.97 | 82.03 | 2.97 | 0.0 | 0.0 | 85.0 | 85.0 | 0.0 | 85.0 | 0.0 | 0.0 |
|
||||
| 2 | 30 | 11 May 2025 | 13 April 2025 | 333.16 | 84.81 | 0.19 | 0.0 | 0.0 | 85.0 | 85.0 | 85.0 | 0.0 | 0.0 | 0.0 |
|
||||
| 3 | 31 | 11 June 2025 | 13 April 2025 | 248.16 | 85.0 | 0.0 | 0.0 | 0.0 | 85.0 | 85.0 | 85.0 | 0.0 | 0.0 | 0.0 |
|
||||
| 4 | 30 | 11 July 2025 | 13 April 2025 | 163.16 | 85.0 | 0.0 | 0.0 | 0.0 | 85.0 | 85.0 | 85.0 | 0.0 | 0.0 | 0.0 |
|
||||
| 5 | 31 | 11 August 2025 | 13 April 2025 | 78.16 | 85.0 | 0.0 | 0.0 | 0.0 | 85.0 | 85.0 | 85.0 | 0.0 | 0.0 | 0.0 |
|
||||
| 6 | 31 | 11 September 2025 | 13 April 2025 | 0.0 | 78.16 | 0.0 | 0.0 | 0.0 | 78.16 | 78.16 | 78.16 | 0.0 | 0.0 | 0.0 |
|
||||
Then Loan Repayment schedule has the following data in Total row:
|
||||
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Waived | Outstanding |
|
||||
| 500.0 | 3.16 | 0.0 | 0 | 503.16 | 503.16 | 418.16 | 85.0 | 0.0 | 0.0 |
|
||||
Then Loan Transactions tab has the following data:
|
||||
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
|
||||
| 11 March 2025 | Disbursement | 500.0 | 0.0 | 0.0 | 0.0 | 0.0 | 500.0 | false | false |
|
||||
| 13 April 2025 | Repayment | 500.0 | 496.84 | 3.16 | 0.0 | 0.0 | 3.16 | false | false |
|
||||
| 13 April 2025 | Merchant Issued Refund | 500.0 | 3.16 | 0.0 | 0.0 | 0.0 | 0.0 | false | false |
|
||||
| 13 April 2025 | Goodwill Credit | 500.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | false | false |
|
||||
| 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 |
|
||||
|
||||
+30
-21
@@ -1400,20 +1400,25 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
|
||||
if (!installments.isEmpty() && transactionDate.isBefore(loan.getMaturityDate())) {
|
||||
if (transactionCtx instanceof ProgressiveTransactionCtx progressiveTransactionCtx
|
||||
&& loanTransaction.getLoan().isInterestBearingAndInterestRecalculationEnabled()) {
|
||||
final BigDecimal interestOutstanding = currentInstallment.getInterestOutstanding(loan.getCurrency()).getAmount();
|
||||
final BigDecimal newInterest = emiCalculator.getPeriodInterestTillDate(progressiveTransactionCtx.getModel(),
|
||||
currentInstallment.getDueDate(), transactionDate, true).getAmount();
|
||||
currentInstallment.updateInterestCharged(newInterest);
|
||||
if (interestOutstanding.compareTo(BigDecimal.ZERO) > 0 || newInterest.compareTo(BigDecimal.ZERO) > 0) {
|
||||
currentInstallment.updateInterestCharged(newInterest);
|
||||
}
|
||||
} else {
|
||||
final BigDecimal totalInterest = currentInstallment.getInterestOutstanding(transactionCtx.getCurrency()).getAmount();
|
||||
final long totalDaysInPeriod = ChronoUnit.DAYS.between(currentInstallment.getFromDate(), currentInstallment.getDueDate());
|
||||
final long daysTillChargeOff = ChronoUnit.DAYS.between(currentInstallment.getFromDate(), transactionDate);
|
||||
if (totalInterest.compareTo(BigDecimal.ZERO) > 0) {
|
||||
final long totalDaysInPeriod = ChronoUnit.DAYS.between(currentInstallment.getFromDate(),
|
||||
currentInstallment.getDueDate());
|
||||
final long daysTillChargeOff = ChronoUnit.DAYS.between(currentInstallment.getFromDate(), transactionDate);
|
||||
|
||||
final MathContext mc = MoneyHelper.getMathContext();
|
||||
final Money interestTillChargeOff = Money.of(transactionCtx.getCurrency(),
|
||||
totalInterest.divide(BigDecimal.valueOf(totalDaysInPeriod), mc).multiply(BigDecimal.valueOf(daysTillChargeOff), mc),
|
||||
mc);
|
||||
final MathContext mc = MoneyHelper.getMathContext();
|
||||
final Money interestTillChargeOff = Money.of(transactionCtx.getCurrency(), totalInterest
|
||||
.divide(BigDecimal.valueOf(totalDaysInPeriod), mc).multiply(BigDecimal.valueOf(daysTillChargeOff), mc), mc);
|
||||
|
||||
currentInstallment.updateInterestCharged(interestTillChargeOff.getAmount());
|
||||
currentInstallment.updateInterestCharged(interestTillChargeOff.getAmount());
|
||||
}
|
||||
}
|
||||
|
||||
currentInstallment.updateDueDate(transactionDate);
|
||||
@@ -1478,25 +1483,27 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
|
||||
private void handleZeroInterestChargeOff(final LoanTransaction loanTransaction, final TransactionCtx transactionCtx) {
|
||||
final LocalDate transactionDate = loanTransaction.getTransactionDate();
|
||||
final List<LoanRepaymentScheduleInstallment> installments = transactionCtx.getInstallments();
|
||||
final MonetaryCurrency currency = loanTransaction.getLoan().getCurrency();
|
||||
|
||||
if (!installments.isEmpty()) {
|
||||
if (transactionCtx instanceof ProgressiveTransactionCtx progressiveTransactionCtx
|
||||
&& loanTransaction.getLoan().isInterestBearingAndInterestRecalculationEnabled()) {
|
||||
installments.stream().filter(installment -> !installment.getFromDate().isAfter(transactionDate)
|
||||
&& installment.getDueDate().isAfter(transactionDate)).forEach(installment -> {
|
||||
final BigDecimal interestOutstanding = installment.getInterestOutstanding(currency).getAmount();
|
||||
final BigDecimal newInterest = emiCalculator.getPeriodInterestTillDate(progressiveTransactionCtx.getModel(),
|
||||
installment.getDueDate(), transactionDate, true).getAmount();
|
||||
final BigDecimal interestRemoved = installment.getInterestCharged().subtract(newInterest);
|
||||
installment.updatePrincipal(MathUtil.nullToZero(installment.getPrincipal()).add(interestRemoved));
|
||||
installment.updateInterestCharged(newInterest);
|
||||
if (interestOutstanding.compareTo(BigDecimal.ZERO) > 0 || newInterest.compareTo(BigDecimal.ZERO) > 0) {
|
||||
final BigDecimal interestRemoved = installment.getInterestCharged().subtract(newInterest);
|
||||
installment.updatePrincipal(MathUtil.nullToZero(installment.getPrincipal()).add(interestRemoved));
|
||||
installment.updateInterestCharged(newInterest);
|
||||
}
|
||||
});
|
||||
progressiveTransactionCtx.setChargedOff(true);
|
||||
} else {
|
||||
calculatePartialPeriodInterest(transactionCtx, transactionDate);
|
||||
}
|
||||
|
||||
final MonetaryCurrency currency = loanTransaction.getLoan().getCurrency();
|
||||
|
||||
installments.stream()
|
||||
.filter(installment -> installment.getFromDate().isAfter(transactionDate) && !installment.isObligationsMet())
|
||||
.forEach(installment -> {
|
||||
@@ -1538,16 +1545,18 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
|
||||
.filter(installment -> !installment.getFromDate().isAfter(chargeOffDate) && installment.getDueDate().isAfter(chargeOffDate))
|
||||
.forEach(installment -> {
|
||||
final BigDecimal totalInterest = installment.getInterestOutstanding(transactionCtx.getCurrency()).getAmount();
|
||||
final long totalDaysInPeriod = ChronoUnit.DAYS.between(installment.getFromDate(), installment.getDueDate());
|
||||
final long daysTillChargeOff = ChronoUnit.DAYS.between(installment.getFromDate(), chargeOffDate);
|
||||
if (totalInterest.compareTo(BigDecimal.ZERO) > 0) {
|
||||
final long totalDaysInPeriod = ChronoUnit.DAYS.between(installment.getFromDate(), installment.getDueDate());
|
||||
final long daysTillChargeOff = ChronoUnit.DAYS.between(installment.getFromDate(), chargeOffDate);
|
||||
|
||||
final MathContext mc = MoneyHelper.getMathContext();
|
||||
final Money interestTillChargeOff = Money.of(transactionCtx.getCurrency(), totalInterest
|
||||
.divide(BigDecimal.valueOf(totalDaysInPeriod), mc).multiply(BigDecimal.valueOf(daysTillChargeOff), mc), mc);
|
||||
final MathContext mc = MoneyHelper.getMathContext();
|
||||
final Money interestTillChargeOff = Money.of(transactionCtx.getCurrency(), totalInterest
|
||||
.divide(BigDecimal.valueOf(totalDaysInPeriod), mc).multiply(BigDecimal.valueOf(daysTillChargeOff), mc), mc);
|
||||
|
||||
final BigDecimal interestRemoved = totalInterest.subtract(interestTillChargeOff.getAmount());
|
||||
installment.updatePrincipal(MathUtil.nullToZero(installment.getPrincipal()).add(interestRemoved));
|
||||
installment.updateInterestCharged(interestTillChargeOff.getAmount());
|
||||
final BigDecimal interestRemoved = totalInterest.subtract(interestTillChargeOff.getAmount());
|
||||
installment.updatePrincipal(MathUtil.nullToZero(installment.getPrincipal()).add(interestRemoved));
|
||||
installment.updateInterestCharged(interestTillChargeOff.getAmount());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+13
-6
@@ -60,6 +60,7 @@ import org.apache.fineract.accounting.producttoaccountmapping.exception.ProductT
|
||||
import org.apache.fineract.infrastructure.core.data.EnumOptionData;
|
||||
import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
|
||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||
import org.apache.fineract.infrastructure.core.service.MathUtil;
|
||||
import org.apache.fineract.infrastructure.event.business.domain.journalentry.LoanJournalEntryCreatedBusinessEvent;
|
||||
import org.apache.fineract.infrastructure.event.business.service.BusinessEventNotifierService;
|
||||
import org.apache.fineract.organisation.office.domain.Office;
|
||||
@@ -453,13 +454,19 @@ public class AccountingProcessorHelper {
|
||||
JournalAmountHolder totalAccountHolder, Long loanProductId, Long paymentTypeId, Long loanId, String transactionId,
|
||||
LocalDate transactionDate) {
|
||||
splitAccountsHolder.forEach(journalItemHolder -> {
|
||||
final GLAccount account = getLinkedGLAccountForLoanProduct(loanProductId, journalItemHolder.getAccountType(), paymentTypeId);
|
||||
createDebitJournalEntryForLoan(office, currencyCode, account, loanId, transactionId, transactionDate,
|
||||
journalItemHolder.getAmount());
|
||||
if (MathUtil.isGreaterThanZero(journalItemHolder.getAmount())) {
|
||||
final GLAccount account = getLinkedGLAccountForLoanProduct(loanProductId, journalItemHolder.getAccountType(),
|
||||
paymentTypeId);
|
||||
createDebitJournalEntryForLoan(office, currencyCode, account, loanId, transactionId, transactionDate,
|
||||
journalItemHolder.getAmount());
|
||||
}
|
||||
});
|
||||
final GLAccount totalAccount = getLinkedGLAccountForLoanProduct(loanProductId, totalAccountHolder.getAccountType(), paymentTypeId);
|
||||
createCreditJournalEntryForLoan(office, currencyCode, totalAccount, loanId, transactionId, transactionDate,
|
||||
totalAccountHolder.getAmount());
|
||||
if (MathUtil.isGreaterThanZero(totalAccountHolder.getAmount())) {
|
||||
final GLAccount totalAccount = getLinkedGLAccountForLoanProduct(loanProductId, totalAccountHolder.getAccountType(),
|
||||
paymentTypeId);
|
||||
createCreditJournalEntryForLoan(office, currencyCode, totalAccount, loanId, transactionId, transactionDate,
|
||||
totalAccountHolder.getAmount());
|
||||
}
|
||||
}
|
||||
|
||||
public void createCreditJournalEntryForLoan(final Office office, final String currencyCode,
|
||||
|
||||
+141
-115
@@ -147,75 +147,79 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
if (isMarkedAsChargeOff) {
|
||||
// ChargeOFF
|
||||
// principal payment
|
||||
if (principalAmount != null && principalAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(principalAmount)) {
|
||||
populateCreditDebitMaps(loanProductId, principalAmount, paymentTypeId,
|
||||
AccrualAccountsForLoan.INCOME_FROM_CHARGE_OFF_INTEREST.getValue(),
|
||||
AccrualAccountsForLoan.INTEREST_ON_LOANS.getValue(), glAccountBalanceHolder);
|
||||
}
|
||||
// interest payment
|
||||
if (interestAmount != null && interestAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(interestAmount)) {
|
||||
populateCreditDebitMaps(loanProductId, interestAmount, paymentTypeId,
|
||||
AccrualAccountsForLoan.INCOME_FROM_CHARGE_OFF_INTEREST.getValue(),
|
||||
AccrualAccountsForLoan.INTEREST_ON_LOANS.getValue(), glAccountBalanceHolder);
|
||||
}
|
||||
// handle fees payment
|
||||
if (feesAmount != null && feesAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(feesAmount)) {
|
||||
populateCreditDebitMaps(loanProductId, feesAmount, paymentTypeId,
|
||||
AccrualAccountsForLoan.INCOME_FROM_CHARGE_OFF_INTEREST.getValue(),
|
||||
AccrualAccountsForLoan.INTEREST_ON_LOANS.getValue(), glAccountBalanceHolder);
|
||||
}
|
||||
|
||||
// handle penalty payment
|
||||
if (penaltiesAmount != null && penaltiesAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(penaltiesAmount)) {
|
||||
populateCreditDebitMaps(loanProductId, penaltiesAmount, paymentTypeId,
|
||||
AccrualAccountsForLoan.INCOME_FROM_CHARGE_OFF_INTEREST.getValue(),
|
||||
AccrualAccountsForLoan.INTEREST_ON_LOANS.getValue(), glAccountBalanceHolder);
|
||||
}
|
||||
// handle overpayment
|
||||
if (overPayment != null && overPayment.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(overPayment)) {
|
||||
populateCreditDebitMaps(loanProductId, overPayment, paymentTypeId, AccrualAccountsForLoan.OVERPAYMENT.getValue(),
|
||||
AccrualAccountsForLoan.INTEREST_ON_LOANS.getValue(), glAccountBalanceHolder);
|
||||
}
|
||||
} else {
|
||||
// principal payment
|
||||
if (principalAmount != null && principalAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(principalAmount)) {
|
||||
populateCreditDebitMaps(loanProductId, principalAmount, paymentTypeId, AccrualAccountsForLoan.LOAN_PORTFOLIO.getValue(),
|
||||
AccrualAccountsForLoan.INTEREST_ON_LOANS.getValue(), glAccountBalanceHolder);
|
||||
}
|
||||
// interest payment
|
||||
if (interestAmount != null && interestAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(interestAmount)) {
|
||||
populateCreditDebitMaps(loanProductId, interestAmount, paymentTypeId, AccrualAccountsForLoan.INTEREST_RECEIVABLE.getValue(),
|
||||
AccrualAccountsForLoan.INTEREST_ON_LOANS.getValue(), glAccountBalanceHolder);
|
||||
}
|
||||
// handle fees payment
|
||||
if (feesAmount != null && feesAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(feesAmount)) {
|
||||
populateCreditDebitMaps(loanProductId, feesAmount, paymentTypeId, AccrualAccountsForLoan.FEES_RECEIVABLE.getValue(),
|
||||
AccrualAccountsForLoan.INTEREST_ON_LOANS.getValue(), glAccountBalanceHolder);
|
||||
}
|
||||
|
||||
// handle penalty payment
|
||||
if (penaltiesAmount != null && penaltiesAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(penaltiesAmount)) {
|
||||
populateCreditDebitMaps(loanProductId, penaltiesAmount, paymentTypeId,
|
||||
AccrualAccountsForLoan.PENALTIES_RECEIVABLE.getValue(), AccrualAccountsForLoan.INTEREST_ON_LOANS.getValue(),
|
||||
glAccountBalanceHolder);
|
||||
}
|
||||
// handle overpayment
|
||||
if (overPayment != null && overPayment.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(overPayment)) {
|
||||
populateCreditDebitMaps(loanProductId, overPayment, paymentTypeId, AccrualAccountsForLoan.OVERPAYMENT.getValue(),
|
||||
AccrualAccountsForLoan.INTEREST_ON_LOANS.getValue(), glAccountBalanceHolder);
|
||||
}
|
||||
}
|
||||
// create credit entries
|
||||
for (Map.Entry<Long, BigDecimal> creditEntry : glAccountBalanceHolder.getCreditBalances().entrySet()) {
|
||||
GLAccount glAccount = glAccountBalanceHolder.getGlAccountMap().get(creditEntry.getKey());
|
||||
this.helper.createCreditJournalEntryForLoan(office, currencyCode, loanId, transactionId, transactionDate,
|
||||
creditEntry.getValue(), glAccount);
|
||||
if (MathUtil.isGreaterThanZero(creditEntry.getValue())) {
|
||||
GLAccount glAccount = glAccountBalanceHolder.getGlAccountMap().get(creditEntry.getKey());
|
||||
this.helper.createCreditJournalEntryForLoan(office, currencyCode, loanId, transactionId, transactionDate,
|
||||
creditEntry.getValue(), glAccount);
|
||||
}
|
||||
}
|
||||
// create debit entries
|
||||
for (Map.Entry<Long, BigDecimal> debitEntry : glAccountBalanceHolder.getDebitBalances().entrySet()) {
|
||||
GLAccount glAccount = glAccountBalanceHolder.getGlAccountMap().get(debitEntry.getKey());
|
||||
this.helper.createDebitJournalEntryForLoan(office, currencyCode, loanId, transactionId, transactionDate, debitEntry.getValue(),
|
||||
glAccount);
|
||||
if (MathUtil.isGreaterThanZero(debitEntry.getValue())) {
|
||||
GLAccount glAccount = glAccountBalanceHolder.getGlAccountMap().get(debitEntry.getKey());
|
||||
this.helper.createDebitJournalEntryForLoan(office, currencyCode, loanId, transactionId, transactionDate,
|
||||
debitEntry.getValue(), glAccount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -241,14 +245,15 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
ProductToGLAccountMapping mapping = chargeOffReasonCodeValue != null
|
||||
? helper.getChargeOffMappingByCodeValue(loanProductId, PortfolioProductType.LOAN, chargeOffReasonCodeValue)
|
||||
: null;
|
||||
if (mapping != null) {
|
||||
GLAccount accountCredit = this.helper.getLinkedGLAccountForLoanProduct(loanProductId,
|
||||
AccrualAccountsForLoan.LOAN_PORTFOLIO.getValue(), paymentTypeId);
|
||||
glAccountBalanceHolder.addToCredit(accountCredit, principalAmount);
|
||||
glAccountBalanceHolder.addToDebit(mapping.getGlAccount(), principalAmount);
|
||||
} else {
|
||||
// principal payment
|
||||
if (principalAmount != null && principalAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
|
||||
if (MathUtil.isGreaterThanZero(principalAmount)) {
|
||||
if (mapping != null) {
|
||||
GLAccount accountCredit = this.helper.getLinkedGLAccountForLoanProduct(loanProductId,
|
||||
AccrualAccountsForLoan.LOAN_PORTFOLIO.getValue(), paymentTypeId);
|
||||
glAccountBalanceHolder.addToCredit(accountCredit, principalAmount);
|
||||
glAccountBalanceHolder.addToDebit(mapping.getGlAccount(), principalAmount);
|
||||
} else {
|
||||
// principal payment
|
||||
if (isMarkedFraud) {
|
||||
populateCreditDebitMaps(loanProductId, principalAmount, paymentTypeId, AccrualAccountsForLoan.LOAN_PORTFOLIO.getValue(),
|
||||
AccrualAccountsForLoan.CHARGE_OFF_FRAUD_EXPENSE.getValue(), glAccountBalanceHolder);
|
||||
@@ -259,43 +264,48 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
}
|
||||
}
|
||||
// interest payment
|
||||
if (interestAmount != null && interestAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
|
||||
if (MathUtil.isGreaterThanZero(interestAmount)) {
|
||||
populateCreditDebitMaps(loanProductId, interestAmount, paymentTypeId, AccrualAccountsForLoan.INTEREST_RECEIVABLE.getValue(),
|
||||
AccrualAccountsForLoan.INCOME_FROM_CHARGE_OFF_INTEREST.getValue(), glAccountBalanceHolder);
|
||||
}
|
||||
// handle fees payment
|
||||
if (feesAmount != null && feesAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(feesAmount)) {
|
||||
populateCreditDebitMaps(loanProductId, feesAmount, paymentTypeId, AccrualAccountsForLoan.FEES_RECEIVABLE.getValue(),
|
||||
AccrualAccountsForLoan.INCOME_FROM_CHARGE_OFF_FEES.getValue(), glAccountBalanceHolder);
|
||||
}
|
||||
// handle penalty payment
|
||||
if (penaltiesAmount != null && penaltiesAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(penaltiesAmount)) {
|
||||
populateCreditDebitMaps(loanProductId, penaltiesAmount, paymentTypeId, AccrualAccountsForLoan.PENALTIES_RECEIVABLE.getValue(),
|
||||
AccrualAccountsForLoan.INCOME_FROM_CHARGE_OFF_PENALTY.getValue(), glAccountBalanceHolder);
|
||||
}
|
||||
// create credit entries
|
||||
for (Map.Entry<Long, BigDecimal> creditEntry : glAccountBalanceHolder.getCreditBalances().entrySet()) {
|
||||
GLAccount glAccount = glAccountBalanceHolder.getGlAccountMap().get(creditEntry.getKey());
|
||||
this.helper.createCreditJournalEntryForLoan(office, currencyCode, loanId, transactionId, transactionDate,
|
||||
creditEntry.getValue(), glAccount);
|
||||
if (MathUtil.isGreaterThanZero(creditEntry.getValue())) {
|
||||
GLAccount glAccount = glAccountBalanceHolder.getGlAccountMap().get(creditEntry.getKey());
|
||||
this.helper.createCreditJournalEntryForLoan(office, currencyCode, loanId, transactionId, transactionDate,
|
||||
creditEntry.getValue(), glAccount);
|
||||
}
|
||||
}
|
||||
// create debit entries
|
||||
for (Map.Entry<Long, BigDecimal> debitEntry : glAccountBalanceHolder.getDebitBalances().entrySet()) {
|
||||
GLAccount glAccount = glAccountBalanceHolder.getGlAccountMap().get(debitEntry.getKey());
|
||||
this.helper.createDebitJournalEntryForLoan(office, currencyCode, loanId, transactionId, transactionDate, debitEntry.getValue(),
|
||||
glAccount);
|
||||
if (MathUtil.isGreaterThanZero(debitEntry.getValue())) {
|
||||
GLAccount glAccount = glAccountBalanceHolder.getGlAccountMap().get(debitEntry.getKey());
|
||||
this.helper.createDebitJournalEntryForLoan(office, currencyCode, loanId, transactionId, transactionDate,
|
||||
debitEntry.getValue(), glAccount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void populateCreditDebitMaps(Long loanProductId, BigDecimal transactionPartAmount, Long paymentTypeId,
|
||||
Integer creditAccountType, Integer debitAccountType, GLAccountBalanceHolder glAccountBalanceHolder) {
|
||||
// Resolve Credit
|
||||
GLAccount accountCredit = this.helper.getLinkedGLAccountForLoanProduct(loanProductId, creditAccountType, paymentTypeId);
|
||||
glAccountBalanceHolder.addToCredit(accountCredit, transactionPartAmount);
|
||||
// Resolve Debit
|
||||
GLAccount accountDebit = this.helper.getLinkedGLAccountForLoanProduct(loanProductId, debitAccountType, paymentTypeId);
|
||||
glAccountBalanceHolder.addToDebit(accountDebit, transactionPartAmount);
|
||||
if (MathUtil.isGreaterThanZero(transactionPartAmount)) {
|
||||
// Resolve Credit
|
||||
GLAccount accountCredit = this.helper.getLinkedGLAccountForLoanProduct(loanProductId, creditAccountType, paymentTypeId);
|
||||
glAccountBalanceHolder.addToCredit(accountCredit, transactionPartAmount);
|
||||
// Resolve Debit
|
||||
GLAccount accountDebit = this.helper.getLinkedGLAccountForLoanProduct(loanProductId, debitAccountType, paymentTypeId);
|
||||
glAccountBalanceHolder.addToDebit(accountDebit, transactionPartAmount);
|
||||
}
|
||||
}
|
||||
|
||||
private void createJournalEntriesForChargeAdjustment(LoanDTO loanDTO, LoanTransactionDTO loanTransactionDTO, Office office) {
|
||||
@@ -329,7 +339,7 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
Map<GLAccount, BigDecimal> accountMap = new LinkedHashMap<>();
|
||||
|
||||
// handle principal payment
|
||||
if (principalAmount != null && principalAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(principalAmount)) {
|
||||
totalDebitAmount = totalDebitAmount.add(principalAmount);
|
||||
GLAccount account = this.helper.getLinkedGLAccountForLoanProduct(loanProductId,
|
||||
AccrualAccountsForLoan.INCOME_FROM_CHARGE_OFF_FEES.getValue(), paymentTypeId);
|
||||
@@ -337,7 +347,7 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
}
|
||||
|
||||
// handle interest payment
|
||||
if (interestAmount != null && interestAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(interestAmount)) {
|
||||
totalDebitAmount = totalDebitAmount.add(interestAmount);
|
||||
GLAccount account = this.helper.getLinkedGLAccountForLoanProduct(loanProductId,
|
||||
AccrualAccountsForLoan.INCOME_FROM_CHARGE_OFF_FEES.getValue(), paymentTypeId);
|
||||
@@ -351,7 +361,7 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
}
|
||||
|
||||
// handle fees payment
|
||||
if (feesAmount != null && feesAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(feesAmount)) {
|
||||
totalDebitAmount = totalDebitAmount.add(feesAmount);
|
||||
GLAccount account = this.helper.getLinkedGLAccountForLoanProduct(loanProductId,
|
||||
AccrualAccountsForLoan.INCOME_FROM_CHARGE_OFF_FEES.getValue(), paymentTypeId);
|
||||
@@ -364,7 +374,7 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
}
|
||||
|
||||
// handle penalty payment
|
||||
if (penaltiesAmount != null && penaltiesAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(penaltiesAmount)) {
|
||||
totalDebitAmount = totalDebitAmount.add(penaltiesAmount);
|
||||
GLAccount account = this.helper.getLinkedGLAccountForLoanProduct(loanProductId,
|
||||
AccrualAccountsForLoan.INCOME_FROM_CHARGE_OFF_PENALTY.getValue(), paymentTypeId);
|
||||
@@ -377,7 +387,7 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
}
|
||||
|
||||
// handle overpayment
|
||||
if (overPaymentAmount != null && overPaymentAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(overPaymentAmount)) {
|
||||
totalDebitAmount = totalDebitAmount.add(overPaymentAmount);
|
||||
GLAccount account = this.helper.getLinkedGLAccountForLoanProduct(loanProductId, AccrualAccountsForLoan.OVERPAYMENT.getValue(),
|
||||
paymentTypeId);
|
||||
@@ -390,11 +400,13 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
}
|
||||
|
||||
for (Map.Entry<GLAccount, BigDecimal> entry : accountMap.entrySet()) {
|
||||
this.helper.createCreditJournalEntryForLoan(office, currencyCode, loanId, transactionId, transactionDate, entry.getValue(),
|
||||
entry.getKey());
|
||||
if (MathUtil.isGreaterThanZero(entry.getValue())) {
|
||||
this.helper.createCreditJournalEntryForLoan(office, currencyCode, loanId, transactionId, transactionDate, entry.getValue(),
|
||||
entry.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
if (totalDebitAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(totalDebitAmount)) {
|
||||
Long chargeId = loanTransactionDTO.getLoanChargeData().getChargeId();
|
||||
Integer accountMappingTypeId;
|
||||
if (loanTransactionDTO.getLoanChargeData().isPenalty()) {
|
||||
@@ -428,7 +440,7 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
Map<GLAccount, BigDecimal> accountMap = new LinkedHashMap<>();
|
||||
|
||||
// handle principal payment
|
||||
if (principalAmount != null && principalAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(principalAmount)) {
|
||||
totalDebitAmount = totalDebitAmount.add(principalAmount);
|
||||
GLAccount account = this.helper.getLinkedGLAccountForLoanProduct(loanProductId,
|
||||
AccrualAccountsForLoan.LOAN_PORTFOLIO.getValue(), paymentTypeId);
|
||||
@@ -436,7 +448,7 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
}
|
||||
|
||||
// handle interest payment
|
||||
if (interestAmount != null && interestAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(interestAmount)) {
|
||||
totalDebitAmount = totalDebitAmount.add(interestAmount);
|
||||
GLAccount account = this.helper.getLinkedGLAccountForLoanProduct(loanProductId,
|
||||
AccrualAccountsForLoan.INTEREST_RECEIVABLE.getValue(), paymentTypeId);
|
||||
@@ -449,7 +461,7 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
}
|
||||
|
||||
// handle fees payment
|
||||
if (feesAmount != null && feesAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(feesAmount)) {
|
||||
totalDebitAmount = totalDebitAmount.add(feesAmount);
|
||||
GLAccount account = this.helper.getLinkedGLAccountForLoanProduct(loanProductId,
|
||||
AccrualAccountsForLoan.FEES_RECEIVABLE.getValue(), paymentTypeId);
|
||||
@@ -462,7 +474,7 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
}
|
||||
|
||||
// handle penalties payment
|
||||
if (penaltiesAmount != null && penaltiesAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(penaltiesAmount)) {
|
||||
totalDebitAmount = totalDebitAmount.add(penaltiesAmount);
|
||||
GLAccount account = this.helper.getLinkedGLAccountForLoanProduct(loanProductId,
|
||||
AccrualAccountsForLoan.PENALTIES_RECEIVABLE.getValue(), paymentTypeId);
|
||||
@@ -475,7 +487,7 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
}
|
||||
|
||||
// handle overpayment
|
||||
if (overPaymentAmount != null && overPaymentAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(overPaymentAmount)) {
|
||||
totalDebitAmount = totalDebitAmount.add(overPaymentAmount);
|
||||
GLAccount account = this.helper.getLinkedGLAccountForLoanProduct(loanProductId, AccrualAccountsForLoan.OVERPAYMENT.getValue(),
|
||||
paymentTypeId);
|
||||
@@ -488,11 +500,13 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
}
|
||||
|
||||
for (Map.Entry<GLAccount, BigDecimal> entry : accountMap.entrySet()) {
|
||||
this.helper.createCreditJournalEntryForLoan(office, currencyCode, loanId, transactionId, transactionDate, entry.getValue(),
|
||||
entry.getKey());
|
||||
if (MathUtil.isGreaterThanZero(entry.getValue())) {
|
||||
this.helper.createCreditJournalEntryForLoan(office, currencyCode, loanId, transactionId, transactionDate, entry.getValue(),
|
||||
entry.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
if (totalDebitAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(totalDebitAmount)) {
|
||||
Long chargeId = loanTransactionDTO.getLoanChargeData().getChargeId();
|
||||
Integer accountMappingTypeId;
|
||||
if (loanTransactionDTO.getLoanChargeData().isPenalty()) {
|
||||
@@ -538,10 +552,12 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
final BigDecimal penaltyPaid = Objects.isNull(loanTransactionDTO.getPenaltyPaid()) ? BigDecimal.ZERO
|
||||
: loanTransactionDTO.getPenaltyPaid();
|
||||
|
||||
helper.createCreditJournalEntryForLoan(office, currencyCode, AccrualAccountsForLoan.FUND_SOURCE, loanProductId, paymentTypeId,
|
||||
loanId, transactionId, transactionDate, amount);
|
||||
if (MathUtil.isGreaterThanZero(amount)) {
|
||||
helper.createCreditJournalEntryForLoan(office, currencyCode, AccrualAccountsForLoan.FUND_SOURCE, loanProductId, paymentTypeId,
|
||||
loanId, transactionId, transactionDate, amount);
|
||||
}
|
||||
|
||||
if (overpaidAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(overpaidAmount)) {
|
||||
helper.createDebitJournalEntryForLoan(office, currencyCode, AccrualAccountsForLoan.OVERPAYMENT.getValue(), loanProductId,
|
||||
paymentTypeId, loanId, transactionId, transactionDate, overpaidAmount);
|
||||
}
|
||||
@@ -617,7 +633,8 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
final LocalDate transactionDate = loanTransactionDTO.getTransactionDate();
|
||||
final BigDecimal overpaymentPortion = loanTransactionDTO.getOverPayment() != null ? loanTransactionDTO.getOverPayment()
|
||||
: BigDecimal.ZERO;
|
||||
final BigDecimal principalPortion = loanTransactionDTO.getAmount().subtract(overpaymentPortion);
|
||||
final BigDecimal loanTransactionDTOAmount = loanTransactionDTO.getAmount();
|
||||
final BigDecimal principalPortion = loanTransactionDTOAmount.subtract(overpaymentPortion);
|
||||
final Long paymentTypeId = loanTransactionDTO.getPaymentTypeId();
|
||||
|
||||
// create journal entries for the disbursement
|
||||
@@ -630,15 +647,17 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
this.helper.createDebitJournalEntryForLoan(office, currencyCode, AccrualAccountsForLoan.OVERPAYMENT.getValue(), loanProductId,
|
||||
paymentTypeId, loanId, transactionId, transactionDate, overpaymentPortion);
|
||||
}
|
||||
if (loanTransactionDTO.isLoanToLoanTransfer()) {
|
||||
this.helper.createCreditJournalEntryForLoan(office, currencyCode, FinancialActivity.ASSET_TRANSFER.getValue(), loanProductId,
|
||||
paymentTypeId, loanId, transactionId, transactionDate, loanTransactionDTO.getAmount());
|
||||
} else if (loanTransactionDTO.isAccountTransfer()) {
|
||||
this.helper.createCreditJournalEntryForLoan(office, currencyCode, FinancialActivity.LIABILITY_TRANSFER.getValue(),
|
||||
loanProductId, paymentTypeId, loanId, transactionId, transactionDate, loanTransactionDTO.getAmount());
|
||||
} else {
|
||||
this.helper.createCreditJournalEntryForLoan(office, currencyCode, AccrualAccountsForLoan.FUND_SOURCE.getValue(), loanProductId,
|
||||
paymentTypeId, loanId, transactionId, transactionDate, loanTransactionDTO.getAmount());
|
||||
if (MathUtil.isGreaterThanZero(loanTransactionDTOAmount)) {
|
||||
if (loanTransactionDTO.isLoanToLoanTransfer()) {
|
||||
this.helper.createCreditJournalEntryForLoan(office, currencyCode, FinancialActivity.ASSET_TRANSFER.getValue(),
|
||||
loanProductId, paymentTypeId, loanId, transactionId, transactionDate, loanTransactionDTOAmount);
|
||||
} else if (loanTransactionDTO.isAccountTransfer()) {
|
||||
this.helper.createCreditJournalEntryForLoan(office, currencyCode, FinancialActivity.LIABILITY_TRANSFER.getValue(),
|
||||
loanProductId, paymentTypeId, loanId, transactionId, transactionDate, loanTransactionDTOAmount);
|
||||
} else {
|
||||
this.helper.createCreditJournalEntryForLoan(office, currencyCode, AccrualAccountsForLoan.FUND_SOURCE.getValue(),
|
||||
loanProductId, paymentTypeId, loanId, transactionId, transactionDate, loanTransactionDTOAmount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -705,7 +724,7 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
BigDecimal totalDebitAmount = new BigDecimal(0);
|
||||
|
||||
// principal payment
|
||||
if (principalAmount != null && principalAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(principalAmount)) {
|
||||
totalDebitAmount = totalDebitAmount.add(principalAmount);
|
||||
if (loanTransactionDTO.getTransactionType().isMerchantIssuedRefund()) {
|
||||
if (isMarkedFraud) {
|
||||
@@ -747,7 +766,7 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
}
|
||||
|
||||
// interest payment
|
||||
if (interestAmount != null && interestAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(interestAmount)) {
|
||||
totalDebitAmount = totalDebitAmount.add(interestAmount);
|
||||
if (loanTransactionDTO.getTransactionType().isMerchantIssuedRefund()) {
|
||||
populateCreditDebitMaps(loanProductId, interestAmount, paymentTypeId,
|
||||
@@ -777,7 +796,7 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
}
|
||||
|
||||
// handle fees payment
|
||||
if (feesAmount != null && feesAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(feesAmount)) {
|
||||
totalDebitAmount = totalDebitAmount.add(feesAmount);
|
||||
if (loanTransactionDTO.getTransactionType().isMerchantIssuedRefund()) {
|
||||
populateCreditDebitMaps(loanProductId, feesAmount, paymentTypeId,
|
||||
@@ -816,7 +835,7 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
}
|
||||
|
||||
// handle penalties
|
||||
if (penaltiesAmount != null && penaltiesAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(penaltiesAmount)) {
|
||||
totalDebitAmount = totalDebitAmount.add(penaltiesAmount);
|
||||
if (loanTransactionDTO.getTransactionType().isMerchantIssuedRefund()) {
|
||||
populateCreditDebitMaps(loanProductId, penaltiesAmount, paymentTypeId,
|
||||
@@ -853,7 +872,7 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
}
|
||||
|
||||
// overpayment
|
||||
if (overPaymentAmount != null && overPaymentAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(overPaymentAmount)) {
|
||||
totalDebitAmount = totalDebitAmount.add(overPaymentAmount);
|
||||
if (loanTransactionDTO.getTransactionType().isMerchantIssuedRefund()) {
|
||||
populateCreditDebitMaps(loanProductId, overPaymentAmount, paymentTypeId, AccrualAccountsForLoan.OVERPAYMENT.getValue(),
|
||||
@@ -876,12 +895,14 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
|
||||
// create credit entries
|
||||
for (Map.Entry<Long, BigDecimal> creditEntry : glAccountBalanceHolder.getCreditBalances().entrySet()) {
|
||||
GLAccount glAccount = glAccountBalanceHolder.getGlAccountMap().get(creditEntry.getKey());
|
||||
this.helper.createCreditJournalEntryForLoan(office, currencyCode, loanId, transactionId, transactionDate,
|
||||
creditEntry.getValue(), glAccount);
|
||||
if (MathUtil.isGreaterThanZero(creditEntry.getValue())) {
|
||||
GLAccount glAccount = glAccountBalanceHolder.getGlAccountMap().get(creditEntry.getKey());
|
||||
this.helper.createCreditJournalEntryForLoan(office, currencyCode, loanId, transactionId, transactionDate,
|
||||
creditEntry.getValue(), glAccount);
|
||||
}
|
||||
}
|
||||
|
||||
if (totalDebitAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(totalDebitAmount)) {
|
||||
if (writeOff) {
|
||||
this.helper.createDebitJournalEntryForLoan(office, currencyCode, AccrualAccountsForLoan.LOSSES_WRITTEN_OFF.getValue(),
|
||||
loanProductId, paymentTypeId, loanId, transactionId, transactionDate, totalDebitAmount);
|
||||
@@ -907,7 +928,7 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
* Charge Refunds have an extra refund related pair of journal entries in addition to those related to the
|
||||
* repayment above
|
||||
***/
|
||||
if (totalDebitAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(totalDebitAmount)) {
|
||||
if (loanTransactionDTO.getTransactionType().isChargeRefund()) {
|
||||
Integer incomeAccount = this.helper.getValueForFeeOrPenaltyIncomeAccount(loanTransactionDTO.getChargeRefundChargeType());
|
||||
this.helper.createJournalEntriesForLoan(office, currencyCode, incomeAccount, AccrualAccountsForLoan.FUND_SOURCE.getValue(),
|
||||
@@ -940,7 +961,7 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
Map<Integer, BigDecimal> debitAccountMapForGoodwillCredit = new LinkedHashMap<>();
|
||||
|
||||
// handle principal payment or writeOff
|
||||
if (principalAmount != null && principalAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(principalAmount)) {
|
||||
totalDebitAmount = totalDebitAmount.add(principalAmount);
|
||||
GLAccount account = this.helper.getLinkedGLAccountForLoanProduct(loanProductId,
|
||||
AccrualAccountsForLoan.LOAN_PORTFOLIO.getValue(), paymentTypeId);
|
||||
@@ -952,7 +973,7 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
}
|
||||
|
||||
// handle interest payment of writeOff
|
||||
if (interestAmount != null && interestAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(interestAmount)) {
|
||||
totalDebitAmount = totalDebitAmount.add(interestAmount);
|
||||
GLAccount account = this.helper.getLinkedGLAccountForLoanProduct(loanProductId,
|
||||
AccrualAccountsForLoan.INTEREST_RECEIVABLE.getValue(), paymentTypeId);
|
||||
@@ -970,10 +991,8 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
}
|
||||
|
||||
// handle fees payment of writeOff
|
||||
if (feesAmount != null && feesAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
|
||||
if (MathUtil.isGreaterThanZero(feesAmount)) {
|
||||
totalDebitAmount = totalDebitAmount.add(feesAmount);
|
||||
|
||||
if (isIncomeFromFee) {
|
||||
this.helper.createCreditJournalEntryForLoanCharges(office, currencyCode, AccrualAccountsForLoan.INCOME_FROM_FEES.getValue(),
|
||||
loanProductId, loanId, transactionId, transactionDate, feesAmount, loanTransactionDTO.getFeePayments());
|
||||
@@ -994,7 +1013,7 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
}
|
||||
|
||||
// handle penalties payment of writeOff
|
||||
if (penaltiesAmount != null && penaltiesAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(penaltiesAmount)) {
|
||||
totalDebitAmount = totalDebitAmount.add(penaltiesAmount);
|
||||
if (isIncomeFromFee) {
|
||||
GLAccount account = this.helper.getLinkedGLAccountForLoanProduct(loanProductId,
|
||||
@@ -1023,7 +1042,7 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
}
|
||||
}
|
||||
|
||||
if (overPaymentAmount != null && overPaymentAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(overPaymentAmount)) {
|
||||
totalDebitAmount = totalDebitAmount.add(overPaymentAmount);
|
||||
GLAccount account = this.helper.getLinkedGLAccountForLoanProduct(loanProductId, AccrualAccountsForLoan.OVERPAYMENT.getValue(),
|
||||
paymentTypeId);
|
||||
@@ -1040,14 +1059,16 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
}
|
||||
|
||||
for (Map.Entry<GLAccount, BigDecimal> entry : accountMap.entrySet()) {
|
||||
this.helper.createCreditJournalEntryForLoan(office, currencyCode, loanId, transactionId, transactionDate, entry.getValue(),
|
||||
entry.getKey());
|
||||
if (MathUtil.isGreaterThanZero(entry.getValue())) {
|
||||
this.helper.createCreditJournalEntryForLoan(office, currencyCode, loanId, transactionId, transactionDate, entry.getValue(),
|
||||
entry.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Single DEBIT transaction for write-offs or Repayments
|
||||
***/
|
||||
if (totalDebitAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(totalDebitAmount)) {
|
||||
if (writeOff) {
|
||||
this.helper.createDebitJournalEntryForLoan(office, currencyCode, AccrualAccountsForLoan.LOSSES_WRITTEN_OFF.getValue(),
|
||||
loanProductId, paymentTypeId, loanId, transactionId, transactionDate, totalDebitAmount);
|
||||
@@ -1078,7 +1099,7 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
* Charge Refunds have an extra refund related pair of journal entries in addition to those related to the
|
||||
* repayment above
|
||||
***/
|
||||
if (totalDebitAmount.compareTo(BigDecimal.ZERO) > 0 && loanTransactionDTO.getTransactionType().isChargeRefund()) {
|
||||
if (MathUtil.isGreaterThanZero(totalDebitAmount) && loanTransactionDTO.getTransactionType().isChargeRefund()) {
|
||||
Integer incomeAccount = this.helper.getValueForFeeOrPenaltyIncomeAccount(loanTransactionDTO.getChargeRefundChargeType());
|
||||
this.helper.createJournalEntriesForLoan(office, currencyCode, incomeAccount, AccrualAccountsForLoan.FUND_SOURCE.getValue(),
|
||||
loanProductId, paymentTypeId, loanId, transactionId, transactionDate, totalDebitAmount);
|
||||
@@ -1122,10 +1143,11 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
final BigDecimal amount = loanTransactionDTO.getAmount();
|
||||
final Long paymentTypeId = loanTransactionDTO.getPaymentTypeId();
|
||||
|
||||
this.helper.createJournalEntriesForLoan(office, currencyCode, AccrualAccountsForLoan.FUND_SOURCE.getValue(),
|
||||
AccrualAccountsForLoan.INCOME_FROM_RECOVERY.getValue(), loanProductId, paymentTypeId, loanId, transactionId,
|
||||
transactionDate, amount);
|
||||
|
||||
if (MathUtil.isGreaterThanZero(amount)) {
|
||||
this.helper.createJournalEntriesForLoan(office, currencyCode, AccrualAccountsForLoan.FUND_SOURCE.getValue(),
|
||||
AccrualAccountsForLoan.INCOME_FROM_RECOVERY.getValue(), loanProductId, paymentTypeId, loanId, transactionId,
|
||||
transactionDate, amount);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1156,7 +1178,7 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
final Long paymentTypeId = loanTransactionDTO.getPaymentTypeId();
|
||||
|
||||
// create journal entries for recognizing interest
|
||||
if (interestAmount != null && interestAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(interestAmount)) {
|
||||
if (transactionType.isAccrualAdjustment()) {
|
||||
this.helper.createJournalEntriesForLoan(office, currencyCode, AccrualAccountsForLoan.INTEREST_ON_LOANS.getValue(),
|
||||
AccrualAccountsForLoan.INTEREST_RECEIVABLE.getValue(), loanProductId, paymentTypeId, loanId, transactionId,
|
||||
@@ -1168,7 +1190,7 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
}
|
||||
}
|
||||
// create journal entries for the fees application
|
||||
if (feesAmount != null && feesAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(feesAmount)) {
|
||||
if (transactionType.isAccrualAdjustment()) {
|
||||
this.helper.createJournalEntriesForLoanCharges(office, currencyCode, AccrualAccountsForLoan.INCOME_FROM_FEES.getValue(),
|
||||
AccrualAccountsForLoan.FEES_RECEIVABLE.getValue(), loanProductId, loanId, transactionId, transactionDate,
|
||||
@@ -1180,7 +1202,7 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
}
|
||||
}
|
||||
// create journal entries for the penalties application
|
||||
if (penaltiesAmount != null && penaltiesAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(penaltiesAmount)) {
|
||||
if (transactionType.isAccrualAdjustment()) {
|
||||
this.helper.createJournalEntriesForLoanCharges(office, currencyCode,
|
||||
AccrualAccountsForLoan.INCOME_FROM_PENALTIES.getValue(), AccrualAccountsForLoan.PENALTIES_RECEIVABLE.getValue(),
|
||||
@@ -1205,14 +1227,16 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
final BigDecimal refundAmount = loanTransactionDTO.getAmount();
|
||||
final Long paymentTypeId = loanTransactionDTO.getPaymentTypeId();
|
||||
|
||||
if (loanTransactionDTO.isAccountTransfer()) {
|
||||
this.helper.createJournalEntriesForLoan(office, currencyCode, AccrualAccountsForLoan.OVERPAYMENT.getValue(),
|
||||
FinancialActivity.LIABILITY_TRANSFER.getValue(), loanProductId, paymentTypeId, loanId, transactionId, transactionDate,
|
||||
refundAmount);
|
||||
} else {
|
||||
this.helper.createJournalEntriesForLoan(office, currencyCode, AccrualAccountsForLoan.OVERPAYMENT.getValue(),
|
||||
AccrualAccountsForLoan.FUND_SOURCE.getValue(), loanProductId, paymentTypeId, loanId, transactionId, transactionDate,
|
||||
refundAmount);
|
||||
if (MathUtil.isGreaterThanZero(refundAmount)) {
|
||||
if (loanTransactionDTO.isAccountTransfer()) {
|
||||
this.helper.createJournalEntriesForLoan(office, currencyCode, AccrualAccountsForLoan.OVERPAYMENT.getValue(),
|
||||
FinancialActivity.LIABILITY_TRANSFER.getValue(), loanProductId, paymentTypeId, loanId, transactionId,
|
||||
transactionDate, refundAmount);
|
||||
} else {
|
||||
this.helper.createJournalEntriesForLoan(office, currencyCode, AccrualAccountsForLoan.OVERPAYMENT.getValue(),
|
||||
AccrualAccountsForLoan.FUND_SOURCE.getValue(), loanProductId, paymentTypeId, loanId, transactionId, transactionDate,
|
||||
refundAmount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1241,12 +1265,12 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
BigDecimal totalAmount = BigDecimal.ZERO;
|
||||
List<JournalAmountHolder> journalAmountHolders = new ArrayList<>();
|
||||
|
||||
if (principalAmount != null && principalAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(principalAmount)) {
|
||||
totalAmount = totalAmount.add(principalAmount);
|
||||
journalAmountHolders
|
||||
.add(new JournalAmountHolder(determineAccrualAccountForCBR(isMarkedChargeOff, isMarkedFraud, false), principalAmount));
|
||||
}
|
||||
if (overpaymentAmount != null && overpaymentAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(overpaymentAmount)) {
|
||||
totalAmount = totalAmount.add(overpaymentAmount);
|
||||
journalAmountHolders
|
||||
.add(new JournalAmountHolder(determineAccrualAccountForCBR(isMarkedChargeOff, isMarkedFraud, true), overpaymentAmount));
|
||||
@@ -1293,19 +1317,19 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
|
||||
BigDecimal totalDebitAmount = new BigDecimal(0);
|
||||
|
||||
if (principalAmount != null && principalAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(principalAmount)) {
|
||||
totalDebitAmount = totalDebitAmount.add(principalAmount);
|
||||
this.helper.createDebitJournalEntryForLoan(office, currencyCode, AccrualAccountsForLoan.LOAN_PORTFOLIO.getValue(),
|
||||
loanProductId, paymentTypeId, loanId, transactionId, transactionDate, principalAmount);
|
||||
}
|
||||
|
||||
if (interestAmount != null && interestAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(interestAmount)) {
|
||||
totalDebitAmount = totalDebitAmount.add(interestAmount);
|
||||
this.helper.createDebitJournalEntryForLoan(office, currencyCode, AccrualAccountsForLoan.INTEREST_ON_LOANS.getValue(),
|
||||
loanProductId, paymentTypeId, loanId, transactionId, transactionDate, interestAmount);
|
||||
}
|
||||
|
||||
if (feesAmount != null && feesAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(feesAmount)) {
|
||||
totalDebitAmount = totalDebitAmount.add(feesAmount);
|
||||
|
||||
List<ChargePaymentDTO> chargePaymentDTOs = new ArrayList<>();
|
||||
@@ -1320,7 +1344,7 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
loanProductId, loanId, transactionId, transactionDate, feesAmount, chargePaymentDTOs);
|
||||
}
|
||||
|
||||
if (penaltiesAmount != null && penaltiesAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(penaltiesAmount)) {
|
||||
totalDebitAmount = totalDebitAmount.add(penaltiesAmount);
|
||||
List<ChargePaymentDTO> chargePaymentDTOs = new ArrayList<>();
|
||||
|
||||
@@ -1334,14 +1358,16 @@ public class AccrualBasedAccountingProcessorForLoan implements AccountingProcess
|
||||
loanProductId, loanId, transactionId, transactionDate, penaltiesAmount, chargePaymentDTOs);
|
||||
}
|
||||
|
||||
if (overPaymentAmount != null && overPaymentAmount.compareTo(BigDecimal.ZERO) > 0) {
|
||||
if (MathUtil.isGreaterThanZero(overPaymentAmount)) {
|
||||
totalDebitAmount = totalDebitAmount.add(overPaymentAmount);
|
||||
this.helper.createDebitJournalEntryForLoan(office, currencyCode, AccrualAccountsForLoan.OVERPAYMENT.getValue(), loanProductId,
|
||||
paymentTypeId, loanId, transactionId, transactionDate, overPaymentAmount);
|
||||
}
|
||||
|
||||
/*** create a single debit entry (or reversal) for the entire amount **/
|
||||
this.helper.createCreditJournalEntryForLoan(office, currencyCode, AccrualAccountsForLoan.FUND_SOURCE.getValue(), loanProductId,
|
||||
paymentTypeId, loanId, transactionId, transactionDate, totalDebitAmount);
|
||||
if (MathUtil.isGreaterThanZero(totalDebitAmount)) {
|
||||
/*** create a single debit entry (or reversal) for the entire amount **/
|
||||
this.helper.createCreditJournalEntryForLoan(office, currencyCode, AccrualAccountsForLoan.FUND_SOURCE.getValue(), loanProductId,
|
||||
paymentTypeId, loanId, transactionId, transactionDate, totalDebitAmount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user