FINERACT-2081: Payments after loan charge - payment allocation
This commit is contained in:
committed by
Adam Saghy
parent
2d0c8db993
commit
31c9079ad9
+26
-19
@@ -209,29 +209,34 @@ public class LoanChargeWritePlatformServiceImpl implements LoanChargeWritePlatfo
|
||||
boolean isAppliedOnBackDate = false;
|
||||
LoanCharge loanCharge = null;
|
||||
LocalDate recalculateFrom = loan.fetchInterestRecalculateFromDate();
|
||||
LocalDate transactionDate = null;
|
||||
if (chargeDefinition.isPercentageOfDisbursementAmount()) {
|
||||
LoanTrancheDisbursementCharge loanTrancheDisbursementCharge;
|
||||
ExternalId externalId = externalIdFactory.createFromCommand(command, "externalId");
|
||||
boolean needToGenerateNewExternalId = false;
|
||||
boolean isFirst = true;
|
||||
for (LoanDisbursementDetails disbursementDetail : loanDisburseDetails) {
|
||||
if (disbursementDetail.actualDisbursementDate() == null) {
|
||||
// If multiple charges to be applied, only the first one will get the provided externalId, for the
|
||||
// rest we generate new ones (if needed)
|
||||
if (needToGenerateNewExternalId) {
|
||||
if (!isFirst) {
|
||||
externalId = externalIdFactory.create();
|
||||
}
|
||||
LocalDate dueDate = disbursementDetail.expectedDisbursementDateAsLocalDate();
|
||||
loanCharge = loanChargeAssembler.createNewWithoutLoan(chargeDefinition, disbursementDetail.principal(), null, null,
|
||||
null, disbursementDetail.expectedDisbursementDateAsLocalDate(), null, null, externalId);
|
||||
null, dueDate, null, null, externalId);
|
||||
loanTrancheDisbursementCharge = new LoanTrancheDisbursementCharge(loanCharge, disbursementDetail);
|
||||
loanCharge.updateLoanTrancheDisbursementCharge(loanTrancheDisbursementCharge);
|
||||
businessEventNotifierService.notifyPreBusinessEvent(new LoanAddChargeBusinessEvent(loanCharge));
|
||||
validateAddLoanCharge(loan, chargeDefinition, loanCharge);
|
||||
addCharge(loan, chargeDefinition, loanCharge);
|
||||
isAppliedOnBackDate = true;
|
||||
if (DateUtils.isAfter(recalculateFrom, disbursementDetail.expectedDisbursementDateAsLocalDate())) {
|
||||
recalculateFrom = disbursementDetail.expectedDisbursementDateAsLocalDate();
|
||||
if (DateUtils.isAfter(recalculateFrom, dueDate)) {
|
||||
recalculateFrom = dueDate;
|
||||
}
|
||||
needToGenerateNewExternalId = true;
|
||||
if (isFirst) {
|
||||
transactionDate = loanCharge.getEffectiveDueDate();
|
||||
}
|
||||
isFirst = false;
|
||||
}
|
||||
}
|
||||
if (loanCharge == null) {
|
||||
@@ -246,35 +251,38 @@ public class LoanChargeWritePlatformServiceImpl implements LoanChargeWritePlatfo
|
||||
|
||||
validateAddLoanCharge(loan, chargeDefinition, loanCharge);
|
||||
isAppliedOnBackDate = addCharge(loan, chargeDefinition, loanCharge);
|
||||
if (loanCharge.getDueLocalDate() == null || DateUtils.isAfter(recalculateFrom, loanCharge.getDueLocalDate())) {
|
||||
if (DateUtils.isAfter(recalculateFrom, loanCharge.getDueLocalDate())) {
|
||||
isAppliedOnBackDate = true;
|
||||
recalculateFrom = loanCharge.getDueLocalDate();
|
||||
}
|
||||
transactionDate = loanCharge.getEffectiveDueDate();
|
||||
}
|
||||
|
||||
boolean reprocessRequired = true;
|
||||
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
||||
// overpaid transactions will be reprocessed and pay this charge
|
||||
boolean overpaidReprocess = !loanCharge.isDueAtDisbursement() && !loanCharge.isPaid() && loan.getStatus().isOverpaid();
|
||||
if (!overpaidReprocess && loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
||||
if (isAppliedOnBackDate && loan.isFeeCompoundingEnabledForInterestRecalculation()) {
|
||||
|
||||
loan = runScheduleRecalculation(loan, recalculateFrom);
|
||||
reprocessRequired = false;
|
||||
}
|
||||
this.loanWritePlatformService.updateOriginalSchedule(loan);
|
||||
}
|
||||
// [For Adv payment allocation strategy] check if charge due date is earlier than last transaction
|
||||
// date, if yes trigger reprocess else no reprocessing
|
||||
if (AdvancedPaymentScheduleTransactionProcessor.ADVANCED_PAYMENT_ALLOCATION_STRATEGY.equals(loan.transactionProcessingStrategy())) {
|
||||
if (!overpaidReprocess && AdvancedPaymentScheduleTransactionProcessor.ADVANCED_PAYMENT_ALLOCATION_STRATEGY
|
||||
.equals(loan.transactionProcessingStrategy())) {
|
||||
// [For Adv payment allocation strategy] check if charge due date is earlier than last transaction
|
||||
// date, if yes trigger reprocess else no reprocessing
|
||||
LoanTransaction lastPaymentTransaction = loan.getLastTransactionForReprocessing();
|
||||
if (lastPaymentTransaction != null) {
|
||||
if (loanCharge.getEffectiveDueDate() != null
|
||||
&& DateUtils.isAfter(loanCharge.getEffectiveDueDate(), lastPaymentTransaction.getTransactionDate())) {
|
||||
reprocessRequired = false;
|
||||
}
|
||||
if (lastPaymentTransaction != null
|
||||
&& DateUtils.isAfter(loanCharge.getEffectiveDueDate(), lastPaymentTransaction.getTransactionDate())) {
|
||||
reprocessRequired = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (reprocessRequired) {
|
||||
ChangedTransactionDetail changedTransactionDetail = loan.reprocessTransactions();
|
||||
ChangedTransactionDetail changedTransactionDetail = overpaidReprocess
|
||||
? loan.reprocessTransactionsWithPostTransactionChecks(transactionDate)
|
||||
: loan.reprocessTransactions();
|
||||
if (changedTransactionDetail != null) {
|
||||
for (final Map.Entry<Long, LoanTransaction> mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) {
|
||||
loanAccountDomainService.saveLoanTransactionWithDataIntegrityViolationChecks(mapEntry.getValue());
|
||||
@@ -284,7 +292,6 @@ public class LoanChargeWritePlatformServiceImpl implements LoanChargeWritePlatfo
|
||||
replayedTransactionBusinessEventService.raiseTransactionReplayedEvents(changedTransactionDetail);
|
||||
}
|
||||
loan = loanAccountDomainService.saveAndFlushLoanWithDataIntegrityViolationChecks(loan);
|
||||
|
||||
}
|
||||
|
||||
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);
|
||||
|
||||
Reference in New Issue
Block a user