Loan transaction date handling enhancement + Make Loan transaction auditable
This commit is contained in:
committed by
Arnold Gálovics
parent
ad4fa563de
commit
b30d5c5a16
+2
-2
@@ -664,7 +664,7 @@ public class TellerManagementReadPlatformServiceImpl implements TellerManagement
|
|||||||
sqlBuilder.append(" left join m_loan loan on loan_txn.loan_id = loan.id ");
|
sqlBuilder.append(" left join m_loan loan on loan_txn.loan_id = loan.id ");
|
||||||
sqlBuilder.append(" left join m_client cl on loan.client_id = cl.id ");
|
sqlBuilder.append(" left join m_client cl on loan.client_id = cl.id ");
|
||||||
sqlBuilder.append(" left join m_office o on cl.office_id = o.id ");
|
sqlBuilder.append(" left join m_office o on cl.office_id = o.id ");
|
||||||
sqlBuilder.append(" left join m_appuser user on loan_txn.appuser_id = user.id ");
|
sqlBuilder.append(" left join m_appuser user on loan_txn.createdby_id = user.id ");
|
||||||
sqlBuilder.append(" left join m_staff staff on user.staff_id = staff.id ");
|
sqlBuilder.append(" left join m_staff staff on user.staff_id = staff.id ");
|
||||||
sqlBuilder.append(" left join m_cashiers c on c.staff_id = staff.id ");
|
sqlBuilder.append(" left join m_cashiers c on c.staff_id = staff.id ");
|
||||||
sqlBuilder.append(" left join m_payment_detail payDetails on payDetails.id = loan_txn.payment_detail_id ");
|
sqlBuilder.append(" left join m_payment_detail payDetails on payDetails.id = loan_txn.payment_detail_id ");
|
||||||
@@ -829,7 +829,7 @@ public class TellerManagementReadPlatformServiceImpl implements TellerManagement
|
|||||||
sqlBuilder.append(" left join m_loan loan on loan_txn.loan_id = loan.id ");
|
sqlBuilder.append(" left join m_loan loan on loan_txn.loan_id = loan.id ");
|
||||||
sqlBuilder.append(" left join m_client cl on loan.client_id = cl.id ");
|
sqlBuilder.append(" left join m_client cl on loan.client_id = cl.id ");
|
||||||
sqlBuilder.append(" left join m_office o on cl.office_id = o.id ");
|
sqlBuilder.append(" left join m_office o on cl.office_id = o.id ");
|
||||||
sqlBuilder.append(" left join m_appuser user on loan_txn.appuser_id = user.id ");
|
sqlBuilder.append(" left join m_appuser user on loan_txn.createdby_id = user.id ");
|
||||||
sqlBuilder.append(" left join m_staff staff on user.staff_id = staff.id ");
|
sqlBuilder.append(" left join m_staff staff on user.staff_id = staff.id ");
|
||||||
sqlBuilder.append(" left join m_cashiers c on c.staff_id = staff.id ");
|
sqlBuilder.append(" left join m_cashiers c on c.staff_id = staff.id ");
|
||||||
sqlBuilder.append(" left join m_payment_detail payDetails on payDetails.id = loan_txn.payment_detail_id ");
|
sqlBuilder.append(" left join m_payment_detail payDetails on payDetails.id = loan_txn.payment_detail_id ");
|
||||||
|
|||||||
+78
-92
@@ -688,8 +688,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
* @param suppliedTransactionDate
|
* @param suppliedTransactionDate
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public LoanTransaction handleChargeAppliedTransaction(final LoanCharge loanCharge, final LocalDate suppliedTransactionDate,
|
public LoanTransaction handleChargeAppliedTransaction(final LoanCharge loanCharge, final LocalDate suppliedTransactionDate) {
|
||||||
final AppUser currentUser) {
|
|
||||||
final Money chargeAmount = loanCharge.getAmount(getCurrency());
|
final Money chargeAmount = loanCharge.getAmount(getCurrency());
|
||||||
Money feeCharges = chargeAmount;
|
Money feeCharges = chargeAmount;
|
||||||
Money penaltyCharges = Money.zero(loanCurrency());
|
Money penaltyCharges = Money.zero(loanCurrency());
|
||||||
@@ -714,7 +713,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final LoanTransaction applyLoanChargeTransaction = LoanTransaction.accrueLoanCharge(this, getOffice(), chargeAmount,
|
final LoanTransaction applyLoanChargeTransaction = LoanTransaction.accrueLoanCharge(this, getOffice(), chargeAmount,
|
||||||
transactionDate, feeCharges, penaltyCharges, DateUtils.getLocalDateTimeOfTenant(), currentUser);
|
transactionDate, feeCharges, penaltyCharges);
|
||||||
|
|
||||||
Integer installmentNumber = null;
|
Integer installmentNumber = null;
|
||||||
final LoanChargePaidBy loanChargePaidBy = new LoanChargePaidBy(applyLoanChargeTransaction, loanCharge,
|
final LoanChargePaidBy loanChargePaidBy = new LoanChargePaidBy(applyLoanChargeTransaction, loanCharge,
|
||||||
@@ -1009,8 +1008,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
|
|
||||||
public LoanTransaction waiveLoanCharge(final LoanCharge loanCharge, final LoanLifecycleStateMachine loanLifecycleStateMachine,
|
public LoanTransaction waiveLoanCharge(final LoanCharge loanCharge, final LoanLifecycleStateMachine loanLifecycleStateMachine,
|
||||||
final Map<String, Object> changes, final List<Long> existingTransactionIds, final List<Long> existingReversedTransactionIds,
|
final Map<String, Object> changes, final List<Long> existingTransactionIds, final List<Long> existingReversedTransactionIds,
|
||||||
final Integer loanInstallmentNumber, final ScheduleGeneratorDTO scheduleGeneratorDTO, final Money accruedCharge,
|
final Integer loanInstallmentNumber, final ScheduleGeneratorDTO scheduleGeneratorDTO, final Money accruedCharge) {
|
||||||
final AppUser currentUser) {
|
|
||||||
|
|
||||||
validateLoanIsNotClosed(loanCharge);
|
validateLoanIsNotClosed(loanCharge);
|
||||||
|
|
||||||
@@ -1062,14 +1060,14 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
existingReversedTransactionIds.addAll(findExistingReversedTransactionIds());
|
existingReversedTransactionIds.addAll(findExistingReversedTransactionIds());
|
||||||
|
|
||||||
final LoanTransaction waiveLoanChargeTransaction = LoanTransaction.waiveLoanCharge(this, getOffice(), amountWaived, transactionDate,
|
final LoanTransaction waiveLoanChargeTransaction = LoanTransaction.waiveLoanCharge(this, getOffice(), amountWaived, transactionDate,
|
||||||
feeChargesWaived, penaltyChargesWaived, unrecognizedIncome, DateUtils.getLocalDateTimeOfTenant(), currentUser);
|
feeChargesWaived, penaltyChargesWaived, unrecognizedIncome);
|
||||||
final LoanChargePaidBy loanChargePaidBy = new LoanChargePaidBy(waiveLoanChargeTransaction, loanCharge,
|
final LoanChargePaidBy loanChargePaidBy = new LoanChargePaidBy(waiveLoanChargeTransaction, loanCharge,
|
||||||
waiveLoanChargeTransaction.getAmount(getCurrency()).getAmount(), loanInstallmentNumber);
|
waiveLoanChargeTransaction.getAmount(getCurrency()).getAmount(), loanInstallmentNumber);
|
||||||
waiveLoanChargeTransaction.getLoanChargesPaid().add(loanChargePaidBy);
|
waiveLoanChargeTransaction.getLoanChargesPaid().add(loanChargePaidBy);
|
||||||
addLoanTransaction(waiveLoanChargeTransaction);
|
addLoanTransaction(waiveLoanChargeTransaction);
|
||||||
if (this.repaymentScheduleDetail().isInterestRecalculationEnabled()
|
if (this.repaymentScheduleDetail().isInterestRecalculationEnabled()
|
||||||
&& (loanCharge.getDueLocalDate() == null || DateUtils.getBusinessLocalDate().isAfter(loanCharge.getDueLocalDate()))) {
|
&& (loanCharge.getDueLocalDate() == null || DateUtils.getBusinessLocalDate().isAfter(loanCharge.getDueLocalDate()))) {
|
||||||
regenerateRepaymentScheduleWithInterestRecalculation(scheduleGeneratorDTO, currentUser);
|
regenerateRepaymentScheduleWithInterestRecalculation(scheduleGeneratorDTO);
|
||||||
}
|
}
|
||||||
// Waive of charges whose due date falls after latest 'repayment'
|
// Waive of charges whose due date falls after latest 'repayment'
|
||||||
// transaction dont require entire loan schedule to be reprocessed.
|
// transaction dont require entire loan schedule to be reprocessed.
|
||||||
@@ -1225,7 +1223,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
this.rates.addAll(loanRates);
|
this.rates.addAll(loanRates);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateLoanSchedule(final LoanScheduleModel modifiedLoanSchedule, AppUser currentUser) {
|
public void updateLoanSchedule(final LoanScheduleModel modifiedLoanSchedule) {
|
||||||
this.repaymentScheduleInstallments.clear();
|
this.repaymentScheduleInstallments.clear();
|
||||||
for (final LoanScheduleModelPeriod scheduledLoanInstallment : modifiedLoanSchedule.getPeriods()) {
|
for (final LoanScheduleModelPeriod scheduledLoanInstallment : modifiedLoanSchedule.getPeriods()) {
|
||||||
|
|
||||||
@@ -1242,11 +1240,11 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
|
|
||||||
updateLoanScheduleDependentDerivedFields();
|
updateLoanScheduleDependentDerivedFields();
|
||||||
updateLoanSummaryDerivedFields();
|
updateLoanSummaryDerivedFields();
|
||||||
applyAccurals(currentUser);
|
applyAccurals();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateLoanSchedule(final Collection<LoanRepaymentScheduleInstallment> installments, AppUser currentUser) {
|
public void updateLoanSchedule(final Collection<LoanRepaymentScheduleInstallment> installments) {
|
||||||
List<LoanRepaymentScheduleInstallment> existingInstallments = new ArrayList<>(this.repaymentScheduleInstallments);
|
List<LoanRepaymentScheduleInstallment> existingInstallments = new ArrayList<>(this.repaymentScheduleInstallments);
|
||||||
repaymentScheduleInstallments.clear();
|
repaymentScheduleInstallments.clear();
|
||||||
for (final LoanRepaymentScheduleInstallment installment : installments) {
|
for (final LoanRepaymentScheduleInstallment installment : installments) {
|
||||||
@@ -1262,7 +1260,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
}
|
}
|
||||||
updateLoanScheduleDependentDerivedFields();
|
updateLoanScheduleDependentDerivedFields();
|
||||||
updateLoanSummaryDerivedFields();
|
updateLoanSummaryDerivedFields();
|
||||||
applyAccurals(currentUser);
|
applyAccurals();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1279,13 +1277,13 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
/**
|
/**
|
||||||
* method updates accrual derived fields on installments and reverse the unprocessed transactions
|
* method updates accrual derived fields on installments and reverse the unprocessed transactions
|
||||||
*/
|
*/
|
||||||
private void applyAccurals(AppUser currentUser) {
|
private void applyAccurals() {
|
||||||
Collection<LoanTransaction> accruals = retreiveListOfAccrualTransactions();
|
Collection<LoanTransaction> accruals = retreiveListOfAccrualTransactions();
|
||||||
if (accruals.size() > 0) {
|
if (accruals.size() > 0) {
|
||||||
if (isPeriodicAccrualAccountingEnabledOnLoanProduct()) {
|
if (isPeriodicAccrualAccountingEnabledOnLoanProduct()) {
|
||||||
applyPeriodicAccruals(accruals);
|
applyPeriodicAccruals(accruals);
|
||||||
} else if (isNoneOrCashOrUpfrontAccrualAccountingEnabledOnLoanProduct()) {
|
} else if (isNoneOrCashOrUpfrontAccrualAccountingEnabledOnLoanProduct()) {
|
||||||
updateAccrualsForNonPeriodicAccruals(accruals, currentUser);
|
updateAccrualsForNonPeriodicAccruals(accruals);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1325,7 +1323,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateAccrualsForNonPeriodicAccruals(final Collection<LoanTransaction> accruals, final AppUser currentUser) {
|
private void updateAccrualsForNonPeriodicAccruals(final Collection<LoanTransaction> accruals) {
|
||||||
|
|
||||||
final Money interestApplied = Money.of(getCurrency(), this.summary.getTotalInterestCharged());
|
final Money interestApplied = Money.of(getCurrency(), this.summary.getTotalInterestCharged());
|
||||||
for (LoanTransaction loanTransaction : accruals) {
|
for (LoanTransaction loanTransaction : accruals) {
|
||||||
@@ -1334,7 +1332,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
loanTransaction.reverse();
|
loanTransaction.reverse();
|
||||||
final LocalDateTime currentDateTime = DateUtils.getLocalDateTimeOfTenant();
|
final LocalDateTime currentDateTime = DateUtils.getLocalDateTimeOfTenant();
|
||||||
final LoanTransaction interestAppliedTransaction = LoanTransaction.accrueInterest(getOffice(), this, interestApplied,
|
final LoanTransaction interestAppliedTransaction = LoanTransaction.accrueInterest(getOffice(), this, interestApplied,
|
||||||
getDisbursementDate(), currentDateTime, currentUser);
|
getDisbursementDate());
|
||||||
addLoanTransaction(interestAppliedTransaction);
|
addLoanTransaction(interestAppliedTransaction);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -1344,7 +1342,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
Money chargeAmount = loanCharge.getAmount(getCurrency());
|
Money chargeAmount = loanCharge.getAmount(getCurrency());
|
||||||
if (chargeAmount.isNotEqualTo(loanTransaction.getAmount(getCurrency()))) {
|
if (chargeAmount.isNotEqualTo(loanTransaction.getAmount(getCurrency()))) {
|
||||||
loanTransaction.reverse();
|
loanTransaction.reverse();
|
||||||
handleChargeAppliedTransaction(loanCharge, loanTransaction.getTransactionDate(), currentUser);
|
handleChargeAppliedTransaction(loanCharge, loanTransaction.getTransactionDate());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -2068,7 +2066,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
final LocalDate submittedOn, final String externalId, final boolean allowTransactionsOnHoliday, final List<Holiday> holidays,
|
final LocalDate submittedOn, final String externalId, final boolean allowTransactionsOnHoliday, final List<Holiday> holidays,
|
||||||
final WorkingDays workingDays, final boolean allowTransactionsOnNonWorkingDay) {
|
final WorkingDays workingDays, final boolean allowTransactionsOnNonWorkingDay) {
|
||||||
|
|
||||||
updateLoanSchedule(loanSchedule, currentUser);
|
updateLoanSchedule(loanSchedule);
|
||||||
|
|
||||||
LoanStatus from = null;
|
LoanStatus from = null;
|
||||||
if (this.loanStatus != null) {
|
if (this.loanStatus != null) {
|
||||||
@@ -2483,12 +2481,11 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
validateDisbursementDateIsOnHoliday(holidayDetailDTO.isAllowTransactionsOnHoliday(), holidayDetailDTO.getHolidays());
|
validateDisbursementDateIsOnHoliday(holidayDetailDTO.isAllowTransactionsOnHoliday(), holidayDetailDTO.getHolidays());
|
||||||
|
|
||||||
regenerateRepaymentScheduleWithInterestRecalculationIfNeeded(this.repaymentScheduleDetail().isInterestRecalculationEnabled(),
|
regenerateRepaymentScheduleWithInterestRecalculationIfNeeded(this.repaymentScheduleDetail().isInterestRecalculationEnabled(),
|
||||||
isDisbursementMissed(), scheduleGeneratorDTO, currentUser);
|
isDisbursementMissed(), scheduleGeneratorDTO);
|
||||||
|
|
||||||
updateSummaryWithTotalFeeChargesDueAtDisbursement(deriveSumTotalOfChargesDueAtDisbursement());
|
updateSummaryWithTotalFeeChargesDueAtDisbursement(deriveSumTotalOfChargesDueAtDisbursement());
|
||||||
updateLoanRepaymentPeriodsDerivedFields(actualDisbursementDate);
|
updateLoanRepaymentPeriodsDerivedFields(actualDisbursementDate);
|
||||||
LocalDateTime createdDate = DateUtils.getLocalDateTimeOfTenant();
|
handleDisbursementTransaction(actualDisbursementDate, paymentDetail);
|
||||||
handleDisbursementTransaction(actualDisbursementDate, createdDate, currentUser, paymentDetail);
|
|
||||||
updateLoanSummaryDerivedFields();
|
updateLoanSummaryDerivedFields();
|
||||||
final Money interestApplied = Money.of(getCurrency(), this.summary.getTotalInterestCharged());
|
final Money interestApplied = Money.of(getCurrency(), this.summary.getTotalInterestCharged());
|
||||||
|
|
||||||
@@ -2500,7 +2497,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
if (((isMultiDisburmentLoan() && getDisbursedLoanDisbursementDetails().size() == 1) || !isMultiDisburmentLoan())
|
if (((isMultiDisburmentLoan() && getDisbursedLoanDisbursementDetails().size() == 1) || !isMultiDisburmentLoan())
|
||||||
&& isNoneOrCashOrUpfrontAccrualAccountingEnabledOnLoanProduct()) {
|
&& isNoneOrCashOrUpfrontAccrualAccountingEnabledOnLoanProduct()) {
|
||||||
final LoanTransaction interestAppliedTransaction = LoanTransaction.accrueInterest(getOffice(), this, interestApplied,
|
final LoanTransaction interestAppliedTransaction = LoanTransaction.accrueInterest(getOffice(), this, interestApplied,
|
||||||
actualDisbursementDate, createdDate, currentUser);
|
actualDisbursementDate);
|
||||||
addLoanTransaction(interestAppliedTransaction);
|
addLoanTransaction(interestAppliedTransaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2509,12 +2506,12 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void regenerateRepaymentScheduleWithInterestRecalculationIfNeeded(boolean interestRecalculationEnabledParam,
|
private void regenerateRepaymentScheduleWithInterestRecalculationIfNeeded(boolean interestRecalculationEnabledParam,
|
||||||
boolean disbursementMissedParam, ScheduleGeneratorDTO scheduleGeneratorDTO, AppUser currentUser) {
|
boolean disbursementMissedParam, ScheduleGeneratorDTO scheduleGeneratorDTO) {
|
||||||
|
|
||||||
LocalDate firstInstallmentDueDate = fetchRepaymentScheduleInstallment(1).getDueDate();
|
LocalDate firstInstallmentDueDate = fetchRepaymentScheduleInstallment(1).getDueDate();
|
||||||
if (interestRecalculationEnabledParam
|
if (interestRecalculationEnabledParam
|
||||||
&& (firstInstallmentDueDate.isBefore(DateUtils.getBusinessLocalDate()) || disbursementMissedParam)) {
|
&& (firstInstallmentDueDate.isBefore(DateUtils.getBusinessLocalDate()) || disbursementMissedParam)) {
|
||||||
regenerateRepaymentScheduleWithInterestRecalculation(scheduleGeneratorDTO, currentUser);
|
regenerateRepaymentScheduleWithInterestRecalculation(scheduleGeneratorDTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -2532,7 +2529,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void regenerateScheduleOnDisbursement(final ScheduleGeneratorDTO scheduleGeneratorDTO, final boolean recalculateSchedule,
|
public void regenerateScheduleOnDisbursement(final ScheduleGeneratorDTO scheduleGeneratorDTO, final boolean recalculateSchedule,
|
||||||
final LocalDate actualDisbursementDate, BigDecimal emiAmount, final AppUser currentUser, LocalDate nextPossibleRepaymentDate,
|
final LocalDate actualDisbursementDate, BigDecimal emiAmount, LocalDate nextPossibleRepaymentDate,
|
||||||
Date rescheduledRepaymentDate) {
|
Date rescheduledRepaymentDate) {
|
||||||
boolean isEmiAmountChanged = false;
|
boolean isEmiAmountChanged = false;
|
||||||
if ((this.loanProduct.isMultiDisburseLoan() || this.loanProduct.canDefineInstallmentAmount()) && emiAmount != null
|
if ((this.loanProduct.isMultiDisburseLoan() || this.loanProduct.canDefineInstallmentAmount()) && emiAmount != null
|
||||||
@@ -2565,9 +2562,9 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
if (isRepaymentScheduleRegenerationRequiredForDisbursement(actualDisbursementDate) || recalculateSchedule || isEmiAmountChanged
|
if (isRepaymentScheduleRegenerationRequiredForDisbursement(actualDisbursementDate) || recalculateSchedule || isEmiAmountChanged
|
||||||
|| rescheduledRepaymentDate != null) {
|
|| rescheduledRepaymentDate != null) {
|
||||||
if (this.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
if (this.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
||||||
regenerateRepaymentScheduleWithInterestRecalculation(scheduleGeneratorDTO, currentUser);
|
regenerateRepaymentScheduleWithInterestRecalculation(scheduleGeneratorDTO);
|
||||||
} else {
|
} else {
|
||||||
regenerateRepaymentSchedule(scheduleGeneratorDTO, currentUser);
|
regenerateRepaymentSchedule(scheduleGeneratorDTO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2789,12 +2786,12 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
/*
|
/*
|
||||||
* Ability to regenerate the repayment schedule based on the loans current details/state.
|
* Ability to regenerate the repayment schedule based on the loans current details/state.
|
||||||
*/
|
*/
|
||||||
public void regenerateRepaymentSchedule(final ScheduleGeneratorDTO scheduleGeneratorDTO, final AppUser currentUser) {
|
public void regenerateRepaymentSchedule(final ScheduleGeneratorDTO scheduleGeneratorDTO) {
|
||||||
final LoanScheduleModel loanSchedule = regenerateScheduleModel(scheduleGeneratorDTO);
|
final LoanScheduleModel loanSchedule = regenerateScheduleModel(scheduleGeneratorDTO);
|
||||||
if (loanSchedule == null) {
|
if (loanSchedule == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
updateLoanSchedule(loanSchedule, currentUser);
|
updateLoanSchedule(loanSchedule);
|
||||||
final Set<LoanCharge> charges = this.charges();
|
final Set<LoanCharge> charges = this.charges();
|
||||||
for (final LoanCharge loanCharge : charges) {
|
for (final LoanCharge loanCharge : charges) {
|
||||||
if (!loanCharge.isWaived()) {
|
if (!loanCharge.isWaived()) {
|
||||||
@@ -2855,8 +2852,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
return interestRate;
|
return interestRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleDisbursementTransaction(final LocalDate disbursedOn, final LocalDateTime createdDate, final AppUser currentUser,
|
private void handleDisbursementTransaction(final LocalDate disbursedOn, final PaymentDetail paymentDetail) {
|
||||||
final PaymentDetail paymentDetail) {
|
|
||||||
|
|
||||||
// add repayment transaction to track incoming money from client to mfi
|
// add repayment transaction to track incoming money from client to mfi
|
||||||
// for (charges due at time of disbursement)
|
// for (charges due at time of disbursement)
|
||||||
@@ -2873,7 +2869,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
|
|
||||||
Money disbursentMoney = Money.zero(getCurrency());
|
Money disbursentMoney = Money.zero(getCurrency());
|
||||||
final LoanTransaction chargesPayment = LoanTransaction.repaymentAtDisbursement(getOffice(), disbursentMoney, paymentDetail,
|
final LoanTransaction chargesPayment = LoanTransaction.repaymentAtDisbursement(getOffice(), disbursentMoney, paymentDetail,
|
||||||
disbursedOn, null, createdDate, currentUser);
|
disbursedOn, null);
|
||||||
final Integer installmentNumber = null;
|
final Integer installmentNumber = null;
|
||||||
for (final LoanCharge charge : charges()) {
|
for (final LoanCharge charge : charges()) {
|
||||||
Date actualDisbursementDate = getActualDisbursementDate(charge);
|
Date actualDisbursementDate = getActualDisbursementDate(charge);
|
||||||
@@ -2898,7 +2894,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
* create a Charge applied transaction if Up front Accrual, None or Cash based accounting is enabled
|
* create a Charge applied transaction if Up front Accrual, None or Cash based accounting is enabled
|
||||||
**/
|
**/
|
||||||
if (isNoneOrCashOrUpfrontAccrualAccountingEnabledOnLoanProduct()) {
|
if (isNoneOrCashOrUpfrontAccrualAccountingEnabledOnLoanProduct()) {
|
||||||
handleChargeAppliedTransaction(charge, disbursedOn, currentUser);
|
handleChargeAppliedTransaction(charge, disbursedOn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2968,7 +2964,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Object> undoDisbursal(final ScheduleGeneratorDTO scheduleGeneratorDTO, final List<Long> existingTransactionIds,
|
public Map<String, Object> undoDisbursal(final ScheduleGeneratorDTO scheduleGeneratorDTO, final List<Long> existingTransactionIds,
|
||||||
final List<Long> existingReversedTransactionIds, AppUser currentUser) {
|
final List<Long> existingReversedTransactionIds) {
|
||||||
|
|
||||||
validateAccountStatus(LoanEvent.LOAN_DISBURSAL_UNDO);
|
validateAccountStatus(LoanEvent.LOAN_DISBURSAL_UNDO);
|
||||||
|
|
||||||
@@ -3003,7 +2999,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
// clear off actual disbusrement date so schedule regeneration
|
// clear off actual disbusrement date so schedule regeneration
|
||||||
// uses expected date.
|
// uses expected date.
|
||||||
|
|
||||||
regenerateRepaymentSchedule(scheduleGeneratorDTO, currentUser);
|
regenerateRepaymentSchedule(scheduleGeneratorDTO);
|
||||||
if (isDisbursedAmountChanged) {
|
if (isDisbursedAmountChanged) {
|
||||||
updateSummaryWithTotalFeeChargesDueAtDisbursement(deriveSumTotalOfChargesDueAtDisbursement());
|
updateSummaryWithTotalFeeChargesDueAtDisbursement(deriveSumTotalOfChargesDueAtDisbursement());
|
||||||
}
|
}
|
||||||
@@ -3070,7 +3066,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
|
|
||||||
public ChangedTransactionDetail waiveInterest(final LoanTransaction waiveInterestTransaction,
|
public ChangedTransactionDetail waiveInterest(final LoanTransaction waiveInterestTransaction,
|
||||||
final LoanLifecycleStateMachine loanLifecycleStateMachine, final List<Long> existingTransactionIds,
|
final LoanLifecycleStateMachine loanLifecycleStateMachine, final List<Long> existingTransactionIds,
|
||||||
final List<Long> existingReversedTransactionIds, final ScheduleGeneratorDTO scheduleGeneratorDTO, final AppUser currentUser) {
|
final List<Long> existingReversedTransactionIds, final ScheduleGeneratorDTO scheduleGeneratorDTO) {
|
||||||
|
|
||||||
validateAccountStatus(LoanEvent.LOAN_REPAYMENT_OR_WAIVER);
|
validateAccountStatus(LoanEvent.LOAN_REPAYMENT_OR_WAIVER);
|
||||||
|
|
||||||
@@ -3082,7 +3078,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
existingReversedTransactionIds.addAll(findExistingReversedTransactionIds());
|
existingReversedTransactionIds.addAll(findExistingReversedTransactionIds());
|
||||||
|
|
||||||
final ChangedTransactionDetail changedTransactionDetail = handleRepaymentOrRecoveryOrWaiverTransaction(waiveInterestTransaction,
|
final ChangedTransactionDetail changedTransactionDetail = handleRepaymentOrRecoveryOrWaiverTransaction(waiveInterestTransaction,
|
||||||
loanLifecycleStateMachine, null, scheduleGeneratorDTO, currentUser);
|
loanLifecycleStateMachine, null, scheduleGeneratorDTO);
|
||||||
|
|
||||||
return changedTransactionDetail;
|
return changedTransactionDetail;
|
||||||
}
|
}
|
||||||
@@ -3091,7 +3087,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
public ChangedTransactionDetail makeRepayment(final LoanTransaction repaymentTransaction,
|
public ChangedTransactionDetail makeRepayment(final LoanTransaction repaymentTransaction,
|
||||||
final LoanLifecycleStateMachine loanLifecycleStateMachine, final List<Long> existingTransactionIds,
|
final LoanLifecycleStateMachine loanLifecycleStateMachine, final List<Long> existingTransactionIds,
|
||||||
final List<Long> existingReversedTransactionIds, boolean isRecoveryRepayment, final ScheduleGeneratorDTO scheduleGeneratorDTO,
|
final List<Long> existingReversedTransactionIds, boolean isRecoveryRepayment, final ScheduleGeneratorDTO scheduleGeneratorDTO,
|
||||||
final AppUser currentUser, Boolean isHolidayValidationDone) {
|
Boolean isHolidayValidationDone) {
|
||||||
HolidayDetailDTO holidayDetailDTO = null;
|
HolidayDetailDTO holidayDetailDTO = null;
|
||||||
LoanEvent event = null;
|
LoanEvent event = null;
|
||||||
if (isRecoveryRepayment) {
|
if (isRecoveryRepayment) {
|
||||||
@@ -3115,7 +3111,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
existingReversedTransactionIds.addAll(findExistingReversedTransactionIds());
|
existingReversedTransactionIds.addAll(findExistingReversedTransactionIds());
|
||||||
|
|
||||||
final ChangedTransactionDetail changedTransactionDetail = handleRepaymentOrRecoveryOrWaiverTransaction(repaymentTransaction,
|
final ChangedTransactionDetail changedTransactionDetail = handleRepaymentOrRecoveryOrWaiverTransaction(repaymentTransaction,
|
||||||
loanLifecycleStateMachine, null, scheduleGeneratorDTO, currentUser);
|
loanLifecycleStateMachine, null, scheduleGeneratorDTO);
|
||||||
|
|
||||||
return changedTransactionDetail;
|
return changedTransactionDetail;
|
||||||
}
|
}
|
||||||
@@ -3184,7 +3180,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
|
|
||||||
private ChangedTransactionDetail handleRepaymentOrRecoveryOrWaiverTransaction(final LoanTransaction loanTransaction,
|
private ChangedTransactionDetail handleRepaymentOrRecoveryOrWaiverTransaction(final LoanTransaction loanTransaction,
|
||||||
final LoanLifecycleStateMachine loanLifecycleStateMachine, final LoanTransaction adjustedTransaction,
|
final LoanLifecycleStateMachine loanLifecycleStateMachine, final LoanTransaction adjustedTransaction,
|
||||||
final ScheduleGeneratorDTO scheduleGeneratorDTO, final AppUser currentUser) {
|
final ScheduleGeneratorDTO scheduleGeneratorDTO) {
|
||||||
|
|
||||||
ChangedTransactionDetail changedTransactionDetail = null;
|
ChangedTransactionDetail changedTransactionDetail = null;
|
||||||
|
|
||||||
@@ -3289,7 +3285,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
}
|
}
|
||||||
if (reprocess) {
|
if (reprocess) {
|
||||||
if (this.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
if (this.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
||||||
regenerateRepaymentScheduleWithInterestRecalculation(scheduleGeneratorDTO, currentUser);
|
regenerateRepaymentScheduleWithInterestRecalculation(scheduleGeneratorDTO);
|
||||||
}
|
}
|
||||||
final List<LoanTransaction> allNonContraTransactionsPostDisbursement = retreiveListOfTransactionsPostDisbursement();
|
final List<LoanTransaction> allNonContraTransactionsPostDisbursement = retreiveListOfTransactionsPostDisbursement();
|
||||||
changedTransactionDetail = loanRepaymentScheduleTransactionProcessor.handleTransaction(getDisbursementDate(),
|
changedTransactionDetail = loanRepaymentScheduleTransactionProcessor.handleTransaction(getDisbursementDate(),
|
||||||
@@ -3457,8 +3453,8 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
BigDecimal penaltyToPost = cumulativeIncomeFromInstallments.get("penalty")
|
BigDecimal penaltyToPost = cumulativeIncomeFromInstallments.get("penalty")
|
||||||
.subtract(cumulativeIncomeFromIncomePosting.get("penalty"));
|
.subtract(cumulativeIncomeFromIncomePosting.get("penalty"));
|
||||||
BigDecimal amountToPost = interestToPost.add(feeToPost).add(penaltyToPost);
|
BigDecimal amountToPost = interestToPost.add(feeToPost).add(penaltyToPost);
|
||||||
LoanTransaction finalIncomeTransaction = LoanTransaction.incomePosting(this, this.getOffice(), closedDate, amountToPost,
|
LoanTransaction finalIncomeTransaction = LoanTransaction.incomePosting(this, this.getOffice(), closedLocalDate, amountToPost,
|
||||||
interestToPost, feeToPost, penaltyToPost, null);
|
interestToPost, feeToPost, penaltyToPost);
|
||||||
addLoanTransaction(finalIncomeTransaction);
|
addLoanTransaction(finalIncomeTransaction);
|
||||||
if (isPeriodicAccrualAccountingEnabledOnLoanProduct()) {
|
if (isPeriodicAccrualAccountingEnabledOnLoanProduct()) {
|
||||||
List<LoanTransaction> updatedAccrualTransactions = retreiveListOfAccrualTransactions();
|
List<LoanTransaction> updatedAccrualTransactions = retreiveListOfAccrualTransactions();
|
||||||
@@ -3469,7 +3465,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
HashMap<String, Object> feeDetails = new HashMap<>();
|
HashMap<String, Object> feeDetails = new HashMap<>();
|
||||||
determineFeeDetails(lastAccruedDate, closedLocalDate, feeDetails);
|
determineFeeDetails(lastAccruedDate, closedLocalDate, feeDetails);
|
||||||
LoanTransaction finalAccrual = LoanTransaction.accrueTransaction(this, this.getOffice(), closedLocalDate, amountToPost,
|
LoanTransaction finalAccrual = LoanTransaction.accrueTransaction(this, this.getOffice(), closedLocalDate, amountToPost,
|
||||||
interestToPost, feeToPost, penaltyToPost, null);
|
interestToPost, feeToPost, penaltyToPost);
|
||||||
updateLoanChargesPaidBy(finalAccrual, feeDetails, null);
|
updateLoanChargesPaidBy(finalAccrual, feeDetails, null);
|
||||||
addLoanTransaction(finalAccrual);
|
addLoanTransaction(finalAccrual);
|
||||||
}
|
}
|
||||||
@@ -3607,7 +3603,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
return loanRepaymentScheduleInstallment;
|
return loanRepaymentScheduleInstallment;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LoanTransaction deriveDefaultInterestWaiverTransaction(final LocalDateTime createdDate, final AppUser currentUser) {
|
public LoanTransaction deriveDefaultInterestWaiverTransaction() {
|
||||||
|
|
||||||
final Money totalInterestOutstanding = getTotalInterestOutstandingOnLoan();
|
final Money totalInterestOutstanding = getTotalInterestOutstandingOnLoan();
|
||||||
Money possibleInterestToWaive = totalInterestOutstanding.copy();
|
Money possibleInterestToWaive = totalInterestOutstanding.copy();
|
||||||
@@ -3630,13 +3626,13 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return LoanTransaction.waiver(getOffice(), this, possibleInterestToWaive, transactionDate, possibleInterestToWaive,
|
return LoanTransaction.waiver(getOffice(), this, possibleInterestToWaive, transactionDate, possibleInterestToWaive,
|
||||||
possibleInterestToWaive.zero(), createdDate, currentUser);
|
possibleInterestToWaive.zero());
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChangedTransactionDetail adjustExistingTransaction(final LoanTransaction newTransactionDetail,
|
public ChangedTransactionDetail adjustExistingTransaction(final LoanTransaction newTransactionDetail,
|
||||||
final LoanLifecycleStateMachine loanLifecycleStateMachine, final LoanTransaction transactionForAdjustment,
|
final LoanLifecycleStateMachine loanLifecycleStateMachine, final LoanTransaction transactionForAdjustment,
|
||||||
final List<Long> existingTransactionIds, final List<Long> existingReversedTransactionIds,
|
final List<Long> existingTransactionIds, final List<Long> existingReversedTransactionIds,
|
||||||
final ScheduleGeneratorDTO scheduleGeneratorDTO, final AppUser currentUser) {
|
final ScheduleGeneratorDTO scheduleGeneratorDTO) {
|
||||||
|
|
||||||
HolidayDetailDTO holidayDetailDTO = scheduleGeneratorDTO.getHolidayDetailDTO();
|
HolidayDetailDTO holidayDetailDTO = scheduleGeneratorDTO.getHolidayDetailDTO();
|
||||||
validateActivityNotBeforeLastTransactionDate(LoanEvent.LOAN_REPAYMENT_OR_WAIVER, transactionForAdjustment.getTransactionDate());
|
validateActivityNotBeforeLastTransactionDate(LoanEvent.LOAN_REPAYMENT_OR_WAIVER, transactionForAdjustment.getTransactionDate());
|
||||||
@@ -3675,14 +3671,14 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
|
|
||||||
if (newTransactionDetail.isRepaymentType() || newTransactionDetail.isInterestWaiver()) {
|
if (newTransactionDetail.isRepaymentType() || newTransactionDetail.isInterestWaiver()) {
|
||||||
changedTransactionDetail = handleRepaymentOrRecoveryOrWaiverTransaction(newTransactionDetail, loanLifecycleStateMachine,
|
changedTransactionDetail = handleRepaymentOrRecoveryOrWaiverTransaction(newTransactionDetail, loanLifecycleStateMachine,
|
||||||
transactionForAdjustment, scheduleGeneratorDTO, currentUser);
|
transactionForAdjustment, scheduleGeneratorDTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
return changedTransactionDetail;
|
return changedTransactionDetail;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChangedTransactionDetail undoWrittenOff(final List<Long> existingTransactionIds, final List<Long> existingReversedTransactionIds,
|
public ChangedTransactionDetail undoWrittenOff(final List<Long> existingTransactionIds, final List<Long> existingReversedTransactionIds,
|
||||||
final ScheduleGeneratorDTO scheduleGeneratorDTO, final AppUser currentUser) {
|
final ScheduleGeneratorDTO scheduleGeneratorDTO) {
|
||||||
|
|
||||||
validateAccountStatus(LoanEvent.WRITE_OFF_OUTSTANDING_UNDO);
|
validateAccountStatus(LoanEvent.WRITE_OFF_OUTSTANDING_UNDO);
|
||||||
existingTransactionIds.addAll(findExistingTransactionIds());
|
existingTransactionIds.addAll(findExistingTransactionIds());
|
||||||
@@ -3694,7 +3690,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
.determineProcessor(this.transactionProcessingStrategy);
|
.determineProcessor(this.transactionProcessingStrategy);
|
||||||
final List<LoanTransaction> allNonContraTransactionsPostDisbursement = retreiveListOfTransactionsPostDisbursement();
|
final List<LoanTransaction> allNonContraTransactionsPostDisbursement = retreiveListOfTransactionsPostDisbursement();
|
||||||
if (this.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
if (this.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
||||||
regenerateRepaymentScheduleWithInterestRecalculation(scheduleGeneratorDTO, currentUser);
|
regenerateRepaymentScheduleWithInterestRecalculation(scheduleGeneratorDTO);
|
||||||
}
|
}
|
||||||
ChangedTransactionDetail changedTransactionDetail = loanRepaymentScheduleTransactionProcessor.handleTransaction(
|
ChangedTransactionDetail changedTransactionDetail = loanRepaymentScheduleTransactionProcessor.handleTransaction(
|
||||||
getDisbursementDate(), allNonContraTransactionsPostDisbursement, getCurrency(), getRepaymentScheduleInstallments(),
|
getDisbursementDate(), allNonContraTransactionsPostDisbursement, getCurrency(), getRepaymentScheduleInstallments(),
|
||||||
@@ -3766,7 +3762,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.transactionProcessorFactory
|
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.transactionProcessorFactory
|
||||||
.determineProcessor(this.transactionProcessingStrategy);
|
.determineProcessor(this.transactionProcessingStrategy);
|
||||||
ChangedTransactionDetail changedTransactionDetail = closeDisbursements(scheduleGeneratorDTO,
|
ChangedTransactionDetail changedTransactionDetail = closeDisbursements(scheduleGeneratorDTO,
|
||||||
loanRepaymentScheduleTransactionProcessor, currentUser);
|
loanRepaymentScheduleTransactionProcessor);
|
||||||
|
|
||||||
validateAccountStatus(LoanEvent.WRITE_OFF_OUTSTANDING);
|
validateAccountStatus(LoanEvent.WRITE_OFF_OUTSTANDING);
|
||||||
|
|
||||||
@@ -3805,7 +3801,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
LocalDateTime createdDate = DateUtils.getLocalDateTimeOfTenant();
|
LocalDateTime createdDate = DateUtils.getLocalDateTimeOfTenant();
|
||||||
loanTransaction = LoanTransaction.writeoff(this, getOffice(), writtenOffOnLocalDate, txnExternalId, createdDate, currentUser);
|
loanTransaction = LoanTransaction.writeoff(this, getOffice(), writtenOffOnLocalDate, txnExternalId);
|
||||||
LocalDate lastTransactionDate = getLastUserTransactionDate();
|
LocalDate lastTransactionDate = getLastUserTransactionDate();
|
||||||
if (lastTransactionDate.isAfter(writtenOffOnLocalDate)) {
|
if (lastTransactionDate.isAfter(writtenOffOnLocalDate)) {
|
||||||
final String errorMessage = "The date of the writeoff transaction must occur on or before previous transactions.";
|
final String errorMessage = "The date of the writeoff transaction must occur on or before previous transactions.";
|
||||||
@@ -3826,14 +3822,14 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private ChangedTransactionDetail closeDisbursements(final ScheduleGeneratorDTO scheduleGeneratorDTO,
|
private ChangedTransactionDetail closeDisbursements(final ScheduleGeneratorDTO scheduleGeneratorDTO,
|
||||||
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor, final AppUser currentUser) {
|
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor) {
|
||||||
ChangedTransactionDetail changedTransactionDetail = null;
|
ChangedTransactionDetail changedTransactionDetail = null;
|
||||||
if (isDisbursementAllowed() && atleastOnceDisbursed()) {
|
if (isDisbursementAllowed() && atleastOnceDisbursed()) {
|
||||||
this.loanRepaymentScheduleDetail.setPrincipal(getDisbursedAmount());
|
this.loanRepaymentScheduleDetail.setPrincipal(getDisbursedAmount());
|
||||||
removeDisbursementDetail();
|
removeDisbursementDetail();
|
||||||
regenerateRepaymentSchedule(scheduleGeneratorDTO, currentUser);
|
regenerateRepaymentSchedule(scheduleGeneratorDTO);
|
||||||
if (this.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
if (this.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
||||||
regenerateRepaymentScheduleWithInterestRecalculation(scheduleGeneratorDTO, currentUser);
|
regenerateRepaymentScheduleWithInterestRecalculation(scheduleGeneratorDTO);
|
||||||
}
|
}
|
||||||
final List<LoanTransaction> allNonContraTransactionsPostDisbursement = retreiveListOfTransactionsPostDisbursement();
|
final List<LoanTransaction> allNonContraTransactionsPostDisbursement = retreiveListOfTransactionsPostDisbursement();
|
||||||
changedTransactionDetail = loanRepaymentScheduleTransactionProcessor.handleTransaction(getDisbursementDate(),
|
changedTransactionDetail = loanRepaymentScheduleTransactionProcessor.handleTransaction(getDisbursementDate(),
|
||||||
@@ -3862,7 +3858,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
|
|
||||||
public ChangedTransactionDetail close(final JsonCommand command, final LoanLifecycleStateMachine loanLifecycleStateMachine,
|
public ChangedTransactionDetail close(final JsonCommand command, final LoanLifecycleStateMachine loanLifecycleStateMachine,
|
||||||
final Map<String, Object> changes, final List<Long> existingTransactionIds, final List<Long> existingReversedTransactionIds,
|
final Map<String, Object> changes, final List<Long> existingTransactionIds, final List<Long> existingReversedTransactionIds,
|
||||||
final ScheduleGeneratorDTO scheduleGeneratorDTO, final AppUser currentUser) {
|
final ScheduleGeneratorDTO scheduleGeneratorDTO) {
|
||||||
|
|
||||||
validateAccountStatus(LoanEvent.LOAN_CLOSED);
|
validateAccountStatus(LoanEvent.LOAN_CLOSED);
|
||||||
|
|
||||||
@@ -3890,7 +3886,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.transactionProcessorFactory
|
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.transactionProcessorFactory
|
||||||
.determineProcessor(this.transactionProcessingStrategy);
|
.determineProcessor(this.transactionProcessingStrategy);
|
||||||
ChangedTransactionDetail changedTransactionDetail = closeDisbursements(scheduleGeneratorDTO,
|
ChangedTransactionDetail changedTransactionDetail = closeDisbursements(scheduleGeneratorDTO,
|
||||||
loanRepaymentScheduleTransactionProcessor, currentUser);
|
loanRepaymentScheduleTransactionProcessor);
|
||||||
|
|
||||||
LoanTransaction loanTransaction = null;
|
LoanTransaction loanTransaction = null;
|
||||||
if (isOpen()) {
|
if (isOpen()) {
|
||||||
@@ -3904,8 +3900,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
changes.put("status", LoanEnumerations.status(this.loanStatus));
|
changes.put("status", LoanEnumerations.status(this.loanStatus));
|
||||||
}
|
}
|
||||||
this.closedOnDate = Date.from(closureDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
|
this.closedOnDate = Date.from(closureDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
|
||||||
loanTransaction = LoanTransaction.writeoff(this, getOffice(), closureDate, txnExternalId,
|
loanTransaction = LoanTransaction.writeoff(this, getOffice(), closureDate, txnExternalId);
|
||||||
DateUtils.getLocalDateTimeOfTenant(), currentUser);
|
|
||||||
final boolean isLastTransaction = isChronologicallyLatestTransaction(loanTransaction, getLoanTransactions());
|
final boolean isLastTransaction = isChronologicallyLatestTransaction(loanTransaction, getLoanTransactions());
|
||||||
if (!isLastTransaction) {
|
if (!isLastTransaction) {
|
||||||
final String errorMessage = "The closing date of the loan must be on or after latest transaction date.";
|
final String errorMessage = "The closing date of the loan must be on or after latest transaction date.";
|
||||||
@@ -5239,8 +5234,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ChangedTransactionDetail updateDisbursementDateAndAmountForTranche(final LoanDisbursementDetails disbursementDetails,
|
public ChangedTransactionDetail updateDisbursementDateAndAmountForTranche(final LoanDisbursementDetails disbursementDetails,
|
||||||
final JsonCommand command, final Map<String, Object> actualChanges, final ScheduleGeneratorDTO scheduleGeneratorDTO,
|
final JsonCommand command, final Map<String, Object> actualChanges, final ScheduleGeneratorDTO scheduleGeneratorDTO) {
|
||||||
final AppUser currentUser) {
|
|
||||||
final Locale locale = command.extractLocale();
|
final Locale locale = command.extractLocale();
|
||||||
validateAccountStatus(LoanEvent.LOAN_EDIT_MULTI_DISBURSE_DATE);
|
validateAccountStatus(LoanEvent.LOAN_EDIT_MULTI_DISBURSE_DATE);
|
||||||
final BigDecimal principal = command.bigDecimalValueOfParameterNamed(LoanApiConstants.updatedDisbursementPrincipalParameterName,
|
final BigDecimal principal = command.bigDecimalValueOfParameterNamed(LoanApiConstants.updatedDisbursementPrincipalParameterName,
|
||||||
@@ -5266,9 +5260,9 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
|
|
||||||
this.loanRepaymentScheduleDetail.setPrincipal(setPrincipalAmount);
|
this.loanRepaymentScheduleDetail.setPrincipal(setPrincipalAmount);
|
||||||
if (this.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
if (this.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
||||||
regenerateRepaymentScheduleWithInterestRecalculation(scheduleGeneratorDTO, currentUser);
|
regenerateRepaymentScheduleWithInterestRecalculation(scheduleGeneratorDTO);
|
||||||
} else {
|
} else {
|
||||||
regenerateRepaymentSchedule(scheduleGeneratorDTO, currentUser);
|
regenerateRepaymentSchedule(scheduleGeneratorDTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.transactionProcessorFactory
|
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.transactionProcessorFactory
|
||||||
@@ -5365,7 +5359,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ChangedTransactionDetail recalculateScheduleFromLastTransaction(final ScheduleGeneratorDTO generatorDTO,
|
public ChangedTransactionDetail recalculateScheduleFromLastTransaction(final ScheduleGeneratorDTO generatorDTO,
|
||||||
final List<Long> existingTransactionIds, final List<Long> existingReversedTransactionIds, final AppUser currentUser) {
|
final List<Long> existingTransactionIds, final List<Long> existingReversedTransactionIds) {
|
||||||
existingTransactionIds.addAll(findExistingTransactionIds());
|
existingTransactionIds.addAll(findExistingTransactionIds());
|
||||||
existingReversedTransactionIds.addAll(findExistingReversedTransactionIds());
|
existingReversedTransactionIds.addAll(findExistingReversedTransactionIds());
|
||||||
/*
|
/*
|
||||||
@@ -5376,17 +5370,16 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
* loanTransaction.getTransactionDate(); } } generatorDTO.setRecalculateFrom(recalculateFrom);
|
* loanTransaction.getTransactionDate(); } } generatorDTO.setRecalculateFrom(recalculateFrom);
|
||||||
*/
|
*/
|
||||||
if (this.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
if (this.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
||||||
regenerateRepaymentScheduleWithInterestRecalculation(generatorDTO, currentUser);
|
regenerateRepaymentScheduleWithInterestRecalculation(generatorDTO);
|
||||||
} else {
|
} else {
|
||||||
regenerateRepaymentSchedule(generatorDTO, currentUser);
|
regenerateRepaymentSchedule(generatorDTO);
|
||||||
}
|
}
|
||||||
return processTransactions();
|
return processTransactions();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChangedTransactionDetail handleRegenerateRepaymentScheduleWithInterestRecalculation(final ScheduleGeneratorDTO generatorDTO,
|
public ChangedTransactionDetail handleRegenerateRepaymentScheduleWithInterestRecalculation(final ScheduleGeneratorDTO generatorDTO) {
|
||||||
final AppUser currentUser) {
|
regenerateRepaymentScheduleWithInterestRecalculation(generatorDTO);
|
||||||
regenerateRepaymentScheduleWithInterestRecalculation(generatorDTO, currentUser);
|
|
||||||
return processTransactions();
|
return processTransactions();
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -5413,14 +5406,14 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
return changedTransactionDetail;
|
return changedTransactionDetail;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void regenerateRepaymentScheduleWithInterestRecalculation(final ScheduleGeneratorDTO generatorDTO, final AppUser currentUser) {
|
public void regenerateRepaymentScheduleWithInterestRecalculation(final ScheduleGeneratorDTO generatorDTO) {
|
||||||
|
|
||||||
LocalDate lastTransactionDate = getLastUserTransactionDate();
|
LocalDate lastTransactionDate = getLastUserTransactionDate();
|
||||||
final LoanScheduleDTO loanSchedule = getRecalculatedSchedule(generatorDTO);
|
final LoanScheduleDTO loanSchedule = getRecalculatedSchedule(generatorDTO);
|
||||||
if (loanSchedule == null) {
|
if (loanSchedule == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
updateLoanSchedule(loanSchedule.getInstallments(), currentUser);
|
updateLoanSchedule(loanSchedule.getInstallments());
|
||||||
this.interestRecalculatedOn = DateUtils.getBusinessDate();
|
this.interestRecalculatedOn = DateUtils.getBusinessDate();
|
||||||
LocalDate lastRepaymentDate = this.getLastRepaymentPeriodDueDate(true);
|
LocalDate lastRepaymentDate = this.getLastRepaymentPeriodDueDate(true);
|
||||||
Set<LoanCharge> charges = this.charges();
|
Set<LoanCharge> charges = this.charges();
|
||||||
@@ -5440,7 +5433,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
processPostDisbursementTransactions();
|
processPostDisbursementTransactions();
|
||||||
processIncomeTransactions(currentUser);
|
processIncomeTransactions();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateLoanChargesPaidBy(LoanTransaction accrual, HashMap<String, Object> feeDetails,
|
private void updateLoanChargesPaidBy(LoanTransaction accrual, HashMap<String, Object> feeDetails,
|
||||||
@@ -5468,7 +5461,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void processIncomeTransactions(AppUser currentUser) {
|
public void processIncomeTransactions() {
|
||||||
if (this.loanInterestRecalculationDetails != null && this.loanInterestRecalculationDetails.isCompoundingToBePostedAsTransaction()) {
|
if (this.loanInterestRecalculationDetails != null && this.loanInterestRecalculationDetails.isCompoundingToBePostedAsTransaction()) {
|
||||||
LocalDate lastCompoundingDate = this.getDisbursementDate();
|
LocalDate lastCompoundingDate = this.getDisbursementDate();
|
||||||
List<LoanInterestRecalcualtionAdditionalDetails> compoundingDetails = extractInterestRecalculationAdditionalDetails();
|
List<LoanInterestRecalcualtionAdditionalDetails> compoundingDetails = extractInterestRecalculationAdditionalDetails();
|
||||||
@@ -5480,8 +5473,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
}
|
}
|
||||||
LoanTransaction incomeTransaction = getTransactionForDate(incomeTransactions, compoundingDetail.getEffectiveDate());
|
LoanTransaction incomeTransaction = getTransactionForDate(incomeTransactions, compoundingDetail.getEffectiveDate());
|
||||||
LoanTransaction accrualTransaction = getTransactionForDate(accrualTransactions, compoundingDetail.getEffectiveDate());
|
LoanTransaction accrualTransaction = getTransactionForDate(accrualTransactions, compoundingDetail.getEffectiveDate());
|
||||||
addUpdateIncomeAndAccrualTransaction(compoundingDetail, lastCompoundingDate, currentUser, incomeTransaction,
|
addUpdateIncomeAndAccrualTransaction(compoundingDetail, lastCompoundingDate, incomeTransaction, accrualTransaction);
|
||||||
accrualTransaction);
|
|
||||||
lastCompoundingDate = compoundingDetail.getEffectiveDate();
|
lastCompoundingDate = compoundingDetail.getEffectiveDate();
|
||||||
}
|
}
|
||||||
List<LoanRepaymentScheduleInstallment> installments = getRepaymentScheduleInstallments();
|
List<LoanRepaymentScheduleInstallment> installments = getRepaymentScheduleInstallments();
|
||||||
@@ -5501,8 +5493,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void addUpdateIncomeAndAccrualTransaction(LoanInterestRecalcualtionAdditionalDetails compoundingDetail,
|
private void addUpdateIncomeAndAccrualTransaction(LoanInterestRecalcualtionAdditionalDetails compoundingDetail,
|
||||||
LocalDate lastCompoundingDate, AppUser currentUser, LoanTransaction existingIncomeTransaction,
|
LocalDate lastCompoundingDate, LoanTransaction existingIncomeTransaction, LoanTransaction existingAccrualTransaction) {
|
||||||
LoanTransaction existingAccrualTransaction) {
|
|
||||||
BigDecimal interest = BigDecimal.ZERO;
|
BigDecimal interest = BigDecimal.ZERO;
|
||||||
BigDecimal fee = BigDecimal.ZERO;
|
BigDecimal fee = BigDecimal.ZERO;
|
||||||
BigDecimal penalties = BigDecimal.ZERO;
|
BigDecimal penalties = BigDecimal.ZERO;
|
||||||
@@ -5525,28 +5516,26 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (existingIncomeTransaction == null) {
|
if (existingIncomeTransaction == null) {
|
||||||
LoanTransaction transaction = LoanTransaction.incomePosting(this, this.getOffice(),
|
LoanTransaction transaction = LoanTransaction.incomePosting(this, this.getOffice(), compoundingDetail.getEffectiveDate(),
|
||||||
Date.from(compoundingDetail.getEffectiveDate().atStartOfDay(ZoneId.systemDefault()).toInstant()),
|
compoundingDetail.getAmount(), interest, fee, penalties);
|
||||||
compoundingDetail.getAmount(), interest, fee, penalties, currentUser);
|
|
||||||
addLoanTransaction(transaction);
|
addLoanTransaction(transaction);
|
||||||
} else if (existingIncomeTransaction.getAmount(getCurrency()).getAmount().compareTo(compoundingDetail.getAmount()) != 0) {
|
} else if (existingIncomeTransaction.getAmount(getCurrency()).getAmount().compareTo(compoundingDetail.getAmount()) != 0) {
|
||||||
existingIncomeTransaction.reverse();
|
existingIncomeTransaction.reverse();
|
||||||
LoanTransaction transaction = LoanTransaction.incomePosting(this, this.getOffice(),
|
LoanTransaction transaction = LoanTransaction.incomePosting(this, this.getOffice(), compoundingDetail.getEffectiveDate(),
|
||||||
Date.from(compoundingDetail.getEffectiveDate().atStartOfDay(ZoneId.systemDefault()).toInstant()),
|
compoundingDetail.getAmount(), interest, fee, penalties);
|
||||||
compoundingDetail.getAmount(), interest, fee, penalties, currentUser);
|
|
||||||
addLoanTransaction(transaction);
|
addLoanTransaction(transaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isPeriodicAccrualAccountingEnabledOnLoanProduct()) {
|
if (isPeriodicAccrualAccountingEnabledOnLoanProduct()) {
|
||||||
if (existingAccrualTransaction == null) {
|
if (existingAccrualTransaction == null) {
|
||||||
LoanTransaction accrual = LoanTransaction.accrueTransaction(this, this.getOffice(), compoundingDetail.getEffectiveDate(),
|
LoanTransaction accrual = LoanTransaction.accrueTransaction(this, this.getOffice(), compoundingDetail.getEffectiveDate(),
|
||||||
compoundingDetail.getAmount(), interest, fee, penalties, currentUser);
|
compoundingDetail.getAmount(), interest, fee, penalties);
|
||||||
updateLoanChargesPaidBy(accrual, feeDetails, null);
|
updateLoanChargesPaidBy(accrual, feeDetails, null);
|
||||||
addLoanTransaction(accrual);
|
addLoanTransaction(accrual);
|
||||||
} else if (existingAccrualTransaction.getAmount(getCurrency()).getAmount().compareTo(compoundingDetail.getAmount()) != 0) {
|
} else if (existingAccrualTransaction.getAmount(getCurrency()).getAmount().compareTo(compoundingDetail.getAmount()) != 0) {
|
||||||
existingAccrualTransaction.reverse();
|
existingAccrualTransaction.reverse();
|
||||||
LoanTransaction accrual = LoanTransaction.accrueTransaction(this, this.getOffice(), compoundingDetail.getEffectiveDate(),
|
LoanTransaction accrual = LoanTransaction.accrueTransaction(this, this.getOffice(), compoundingDetail.getEffectiveDate(),
|
||||||
compoundingDetail.getAmount(), interest, fee, penalties, currentUser);
|
compoundingDetail.getAmount(), interest, fee, penalties);
|
||||||
updateLoanChargesPaidBy(accrual, feeDetails, null);
|
updateLoanChargesPaidBy(accrual, feeDetails, null);
|
||||||
addLoanTransaction(accrual);
|
addLoanTransaction(accrual);
|
||||||
}
|
}
|
||||||
@@ -6293,7 +6282,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Object> undoLastDisbursal(ScheduleGeneratorDTO scheduleGeneratorDTO, List<Long> existingTransactionIds,
|
public Map<String, Object> undoLastDisbursal(ScheduleGeneratorDTO scheduleGeneratorDTO, List<Long> existingTransactionIds,
|
||||||
List<Long> existingReversedTransactionIds, AppUser currentUser, Loan loan) {
|
List<Long> existingReversedTransactionIds, Loan loan) {
|
||||||
|
|
||||||
validateAccountStatus(LoanEvent.LOAN_DISBURSAL_UNDO_LAST);
|
validateAccountStatus(LoanEvent.LOAN_DISBURSAL_UNDO_LAST);
|
||||||
existingTransactionIds.addAll(findExistingTransactionIds());
|
existingTransactionIds.addAll(findExistingTransactionIds());
|
||||||
@@ -6331,8 +6320,7 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
reverseExistingTransactionsTillLastDisbursal(actualDisbursementDate);
|
reverseExistingTransactionsTillLastDisbursal(actualDisbursementDate);
|
||||||
loan.recalculateScheduleFromLastTransaction(scheduleGeneratorDTO, existingTransactionIds, existingReversedTransactionIds,
|
loan.recalculateScheduleFromLastTransaction(scheduleGeneratorDTO, existingTransactionIds, existingReversedTransactionIds);
|
||||||
currentUser);
|
|
||||||
actualChanges.put("undolastdisbursal", "true");
|
actualChanges.put("undolastdisbursal", "true");
|
||||||
actualChanges.put("disbursedAmount", this.getDisbursedAmount());
|
actualChanges.put("disbursedAmount", this.getDisbursedAmount());
|
||||||
updateLoanSummaryDerivedFields();
|
updateLoanSummaryDerivedFields();
|
||||||
@@ -6671,16 +6659,14 @@ public class Loan extends AbstractPersistableCustom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ChangedTransactionDetail handleForeClosureTransactions(final LoanTransaction repaymentTransaction,
|
public ChangedTransactionDetail handleForeClosureTransactions(final LoanTransaction repaymentTransaction,
|
||||||
final LoanLifecycleStateMachine loanLifecycleStateMachine, final ScheduleGeneratorDTO scheduleGeneratorDTO,
|
final LoanLifecycleStateMachine loanLifecycleStateMachine, final ScheduleGeneratorDTO scheduleGeneratorDTO) {
|
||||||
final AppUser appUser) {
|
|
||||||
|
|
||||||
LoanEvent event = LoanEvent.LOAN_FORECLOSURE;
|
LoanEvent event = LoanEvent.LOAN_FORECLOSURE;
|
||||||
validateAccountStatus(event);
|
validateAccountStatus(event);
|
||||||
validateForForeclosure(repaymentTransaction.getTransactionDate());
|
validateForForeclosure(repaymentTransaction.getTransactionDate());
|
||||||
this.loanSubStatus = LoanSubStatus.FORECLOSED.getValue();
|
this.loanSubStatus = LoanSubStatus.FORECLOSED.getValue();
|
||||||
applyAccurals(appUser);
|
applyAccurals();
|
||||||
return handleRepaymentOrRecoveryOrWaiverTransaction(repaymentTransaction, loanLifecycleStateMachine, null, scheduleGeneratorDTO,
|
return handleRepaymentOrRecoveryOrWaiverTransaction(repaymentTransaction, loanLifecycleStateMachine, null, scheduleGeneratorDTO);
|
||||||
appUser);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Money retrieveAccruedAmountAfterDate(final LocalDate tillDate) {
|
public Money retrieveAccruedAmountAfterDate(final LocalDate tillDate) {
|
||||||
|
|||||||
+11
-21
@@ -178,13 +178,12 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
|||||||
|
|
||||||
final Money repaymentAmount = Money.of(loan.getCurrency(), transactionAmount);
|
final Money repaymentAmount = Money.of(loan.getCurrency(), transactionAmount);
|
||||||
LoanTransaction newRepaymentTransaction = null;
|
LoanTransaction newRepaymentTransaction = null;
|
||||||
final LocalDateTime currentDateTime = DateUtils.getLocalDateTimeOfTenant();
|
|
||||||
if (isRecoveryRepayment) {
|
if (isRecoveryRepayment) {
|
||||||
newRepaymentTransaction = LoanTransaction.recoveryRepayment(loan.getOffice(), repaymentAmount, paymentDetail, transactionDate,
|
newRepaymentTransaction = LoanTransaction.recoveryRepayment(loan.getOffice(), repaymentAmount, paymentDetail, transactionDate,
|
||||||
txnExternalId, currentDateTime, currentUser);
|
txnExternalId);
|
||||||
} else {
|
} else {
|
||||||
newRepaymentTransaction = LoanTransaction.repaymentType(repaymentTransactionType, loan.getOffice(), repaymentAmount,
|
newRepaymentTransaction = LoanTransaction.repaymentType(repaymentTransactionType, loan.getOffice(), repaymentAmount,
|
||||||
paymentDetail, transactionDate, txnExternalId, currentDateTime, currentUser);
|
paymentDetail, transactionDate, txnExternalId);
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalDate recalculateFrom = null;
|
LocalDate recalculateFrom = null;
|
||||||
@@ -196,7 +195,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
|||||||
|
|
||||||
final ChangedTransactionDetail changedTransactionDetail = loan.makeRepayment(newRepaymentTransaction,
|
final ChangedTransactionDetail changedTransactionDetail = loan.makeRepayment(newRepaymentTransaction,
|
||||||
defaultLoanLifecycleStateMachine(), existingTransactionIds, existingReversedTransactionIds, isRecoveryRepayment,
|
defaultLoanLifecycleStateMachine(), existingTransactionIds, existingReversedTransactionIds, isRecoveryRepayment,
|
||||||
scheduleGeneratorDTO, currentUser, isHolidayValidationDone);
|
scheduleGeneratorDTO, isHolidayValidationDone);
|
||||||
|
|
||||||
saveLoanTransactionWithDataIntegrityViolationChecks(newRepaymentTransaction);
|
saveLoanTransactionWithDataIntegrityViolationChecks(newRepaymentTransaction);
|
||||||
|
|
||||||
@@ -361,7 +360,6 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
|||||||
public LoanTransaction makeChargePayment(final Loan loan, final Long chargeId, final LocalDate transactionDate,
|
public LoanTransaction makeChargePayment(final Loan loan, final Long chargeId, final LocalDate transactionDate,
|
||||||
final BigDecimal transactionAmount, final PaymentDetail paymentDetail, final String noteText, final String txnExternalId,
|
final BigDecimal transactionAmount, final PaymentDetail paymentDetail, final String noteText, final String txnExternalId,
|
||||||
final Integer transactionType, Integer installmentNumber) {
|
final Integer transactionType, Integer installmentNumber) {
|
||||||
AppUser currentUser = getAppUserIfPresent();
|
|
||||||
boolean isAccountTransfer = true;
|
boolean isAccountTransfer = true;
|
||||||
checkClientOrGroupActive(loan);
|
checkClientOrGroupActive(loan);
|
||||||
businessEventNotifierService.notifyPreBusinessEvent(new LoanChargePaymentPreBusinessEvent(loan));
|
businessEventNotifierService.notifyPreBusinessEvent(new LoanChargePaymentPreBusinessEvent(loan));
|
||||||
@@ -373,7 +371,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
|||||||
final LoanTransactionType loanTransactionType = LoanTransactionType.fromInt(transactionType);
|
final LoanTransactionType loanTransactionType = LoanTransactionType.fromInt(transactionType);
|
||||||
|
|
||||||
final LoanTransaction newPaymentTransaction = LoanTransaction.loanPayment(null, loan.getOffice(), paymentAmout, paymentDetail,
|
final LoanTransaction newPaymentTransaction = LoanTransaction.loanPayment(null, loan.getOffice(), paymentAmout, paymentDetail,
|
||||||
transactionDate, txnExternalId, loanTransactionType, DateUtils.getLocalDateTimeOfTenant(), currentUser);
|
transactionDate, txnExternalId, loanTransactionType);
|
||||||
|
|
||||||
if (loanTransactionType.isRepaymentAtDisbursement()) {
|
if (loanTransactionType.isRepaymentAtDisbursement()) {
|
||||||
loan.handlePayDisbursementTransaction(chargeId, newPaymentTransaction, existingTransactionIds, existingReversedTransactionIds);
|
loan.handlePayDisbursementTransaction(chargeId, newPaymentTransaction, existingTransactionIds, existingReversedTransactionIds);
|
||||||
@@ -445,7 +443,6 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
|||||||
public LoanTransaction makeRefund(final Long accountId, final CommandProcessingResultBuilder builderResult,
|
public LoanTransaction makeRefund(final Long accountId, final CommandProcessingResultBuilder builderResult,
|
||||||
final LocalDate transactionDate, final BigDecimal transactionAmount, final PaymentDetail paymentDetail, final String noteText,
|
final LocalDate transactionDate, final BigDecimal transactionAmount, final PaymentDetail paymentDetail, final String noteText,
|
||||||
final String txnExternalId) {
|
final String txnExternalId) {
|
||||||
AppUser currentUser = getAppUserIfPresent();
|
|
||||||
boolean isAccountTransfer = true;
|
boolean isAccountTransfer = true;
|
||||||
final Loan loan = this.loanAccountAssembler.assembleFrom(accountId);
|
final Loan loan = this.loanAccountAssembler.assembleFrom(accountId);
|
||||||
checkClientOrGroupActive(loan);
|
checkClientOrGroupActive(loan);
|
||||||
@@ -455,7 +452,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
|||||||
|
|
||||||
final Money refundAmount = Money.of(loan.getCurrency(), transactionAmount);
|
final Money refundAmount = Money.of(loan.getCurrency(), transactionAmount);
|
||||||
final LoanTransaction newRefundTransaction = LoanTransaction.refund(loan.getOffice(), refundAmount, paymentDetail, transactionDate,
|
final LoanTransaction newRefundTransaction = LoanTransaction.refund(loan.getOffice(), refundAmount, paymentDetail, transactionDate,
|
||||||
txnExternalId, DateUtils.getLocalDateTimeOfTenant(), currentUser);
|
txnExternalId);
|
||||||
final boolean allowTransactionsOnHoliday = this.configurationDomainService.allowTransactionsOnHolidayEnabled();
|
final boolean allowTransactionsOnHoliday = this.configurationDomainService.allowTransactionsOnHolidayEnabled();
|
||||||
final List<Holiday> holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loan.getOfficeId(),
|
final List<Holiday> holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loan.getOfficeId(),
|
||||||
Date.from(transactionDate.atStartOfDay(ZoneId.systemDefault()).toInstant()), HolidayStatusType.ACTIVE.getValue());
|
Date.from(transactionDate.atStartOfDay(ZoneId.systemDefault()).toInstant()), HolidayStatusType.ACTIVE.getValue());
|
||||||
@@ -492,7 +489,6 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
|||||||
@Override
|
@Override
|
||||||
public LoanTransaction makeDisburseTransaction(final Long loanId, final LocalDate transactionDate, final BigDecimal transactionAmount,
|
public LoanTransaction makeDisburseTransaction(final Long loanId, final LocalDate transactionDate, final BigDecimal transactionAmount,
|
||||||
final PaymentDetail paymentDetail, final String noteText, final String txnExternalId, final boolean isLoanToLoanTransfer) {
|
final PaymentDetail paymentDetail, final String noteText, final String txnExternalId, final boolean isLoanToLoanTransfer) {
|
||||||
AppUser currentUser = getAppUserIfPresent();
|
|
||||||
final Loan loan = this.loanAccountAssembler.assembleFrom(loanId);
|
final Loan loan = this.loanAccountAssembler.assembleFrom(loanId);
|
||||||
checkClientOrGroupActive(loan);
|
checkClientOrGroupActive(loan);
|
||||||
boolean isAccountTransfer = true;
|
boolean isAccountTransfer = true;
|
||||||
@@ -500,7 +496,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
|||||||
final List<Long> existingReversedTransactionIds = new ArrayList<>();
|
final List<Long> existingReversedTransactionIds = new ArrayList<>();
|
||||||
final Money amount = Money.of(loan.getCurrency(), transactionAmount);
|
final Money amount = Money.of(loan.getCurrency(), transactionAmount);
|
||||||
LoanTransaction disbursementTransaction = LoanTransaction.disbursement(loan.getOffice(), amount, paymentDetail, transactionDate,
|
LoanTransaction disbursementTransaction = LoanTransaction.disbursement(loan.getOffice(), amount, paymentDetail, transactionDate,
|
||||||
txnExternalId, DateUtils.getLocalDateTimeOfTenant(), currentUser);
|
txnExternalId);
|
||||||
|
|
||||||
// Subtract Previous loan outstanding balance from netDisbursalAmount
|
// Subtract Previous loan outstanding balance from netDisbursalAmount
|
||||||
loan.deductFromNetDisbursalAmount(transactionAmount);
|
loan.deductFromNetDisbursalAmount(transactionAmount);
|
||||||
@@ -646,11 +642,10 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
|||||||
businessEventNotifierService.notifyPreBusinessEvent(new LoanCreditBalanceRefundPreBusinessEvent(loan));
|
businessEventNotifierService.notifyPreBusinessEvent(new LoanCreditBalanceRefundPreBusinessEvent(loan));
|
||||||
final List<Long> existingTransactionIds = new ArrayList<>();
|
final List<Long> existingTransactionIds = new ArrayList<>();
|
||||||
final List<Long> existingReversedTransactionIds = new ArrayList<>();
|
final List<Long> existingReversedTransactionIds = new ArrayList<>();
|
||||||
AppUser currentUser = getAppUserIfPresent();
|
|
||||||
|
|
||||||
final Money refundAmount = Money.of(loan.getCurrency(), transactionAmount);
|
final Money refundAmount = Money.of(loan.getCurrency(), transactionAmount);
|
||||||
final LoanTransaction newCreditBalanceRefundTransaction = LoanTransaction.creditBalanceRefund(loan, loan.getOffice(), refundAmount,
|
final LoanTransaction newCreditBalanceRefundTransaction = LoanTransaction.creditBalanceRefund(loan, loan.getOffice(), refundAmount,
|
||||||
transactionDate, externalId, DateUtils.getLocalDateTimeOfTenant(), currentUser);
|
transactionDate, externalId);
|
||||||
|
|
||||||
loan.creditBalanceRefund(newCreditBalanceRefundTransaction, defaultLoanLifecycleStateMachine(), existingTransactionIds,
|
loan.creditBalanceRefund(newCreditBalanceRefundTransaction, defaultLoanLifecycleStateMachine(), existingTransactionIds,
|
||||||
existingReversedTransactionIds);
|
existingReversedTransactionIds);
|
||||||
@@ -681,11 +676,10 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
|||||||
businessEventNotifierService.notifyPreBusinessEvent(new LoanRefundPreBusinessEvent(loan));
|
businessEventNotifierService.notifyPreBusinessEvent(new LoanRefundPreBusinessEvent(loan));
|
||||||
final List<Long> existingTransactionIds = new ArrayList<>();
|
final List<Long> existingTransactionIds = new ArrayList<>();
|
||||||
final List<Long> existingReversedTransactionIds = new ArrayList<>();
|
final List<Long> existingReversedTransactionIds = new ArrayList<>();
|
||||||
AppUser currentUser = getAppUserIfPresent();
|
|
||||||
|
|
||||||
final Money refundAmount = Money.of(loan.getCurrency(), transactionAmount);
|
final Money refundAmount = Money.of(loan.getCurrency(), transactionAmount);
|
||||||
final LoanTransaction newRefundTransaction = LoanTransaction.refundForActiveLoan(loan.getOffice(), refundAmount, paymentDetail,
|
final LoanTransaction newRefundTransaction = LoanTransaction.refundForActiveLoan(loan.getOffice(), refundAmount, paymentDetail,
|
||||||
transactionDate, txnExternalId, DateUtils.getLocalDateTimeOfTenant(), currentUser);
|
transactionDate, txnExternalId);
|
||||||
final boolean allowTransactionsOnHoliday = this.configurationDomainService.allowTransactionsOnHolidayEnabled();
|
final boolean allowTransactionsOnHoliday = this.configurationDomainService.allowTransactionsOnHolidayEnabled();
|
||||||
final List<Holiday> holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loan.getOfficeId(),
|
final List<Holiday> holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loan.getOfficeId(),
|
||||||
Date.from(transactionDate.atStartOfDay(ZoneId.systemDefault()).toInstant()), HolidayStatusType.ACTIVE.getValue());
|
Date.from(transactionDate.atStartOfDay(ZoneId.systemDefault()).toInstant()), HolidayStatusType.ACTIVE.getValue());
|
||||||
@@ -716,7 +710,6 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
|||||||
public Map<String, Object> foreCloseLoan(final Loan loan, final LocalDate foreClosureDate, final String noteText) {
|
public Map<String, Object> foreCloseLoan(final Loan loan, final LocalDate foreClosureDate, final String noteText) {
|
||||||
businessEventNotifierService.notifyPreBusinessEvent(new LoanForeClosurePreBusinessEvent(loan));
|
businessEventNotifierService.notifyPreBusinessEvent(new LoanForeClosurePreBusinessEvent(loan));
|
||||||
MonetaryCurrency currency = loan.getCurrency();
|
MonetaryCurrency currency = loan.getCurrency();
|
||||||
LocalDateTime createdDate = DateUtils.getLocalDateTimeOfTenant();
|
|
||||||
final Map<String, Object> changes = new LinkedHashMap<>();
|
final Map<String, Object> changes = new LinkedHashMap<>();
|
||||||
List<LoanTransaction> newTransactions = new ArrayList<>();
|
List<LoanTransaction> newTransactions = new ArrayList<>();
|
||||||
|
|
||||||
@@ -737,12 +730,11 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
|||||||
Money total = interestPortion.plus(feePortion).plus(penaltyPortion);
|
Money total = interestPortion.plus(feePortion).plus(penaltyPortion);
|
||||||
if (total.isGreaterThanZero()) {
|
if (total.isGreaterThanZero()) {
|
||||||
LoanTransaction accrualTransaction = LoanTransaction.accrueTransaction(loan, loan.getOffice(), foreClosureDate,
|
LoanTransaction accrualTransaction = LoanTransaction.accrueTransaction(loan, loan.getOffice(), foreClosureDate,
|
||||||
total.getAmount(), interestPortion.getAmount(), feePortion.getAmount(), penaltyPortion.getAmount(), appUser);
|
total.getAmount(), interestPortion.getAmount(), feePortion.getAmount(), penaltyPortion.getAmount());
|
||||||
LocalDate fromDate = loan.getDisbursementDate();
|
LocalDate fromDate = loan.getDisbursementDate();
|
||||||
if (loan.getAccruedTill() != null) {
|
if (loan.getAccruedTill() != null) {
|
||||||
fromDate = loan.getAccruedTill();
|
fromDate = loan.getAccruedTill();
|
||||||
}
|
}
|
||||||
createdDate = createdDate.plusSeconds(1);
|
|
||||||
newTransactions.add(accrualTransaction);
|
newTransactions.add(accrualTransaction);
|
||||||
loan.addLoanTransaction(accrualTransaction);
|
loan.addLoanTransaction(accrualTransaction);
|
||||||
Set<LoanChargePaidBy> accrualCharges = accrualTransaction.getLoanChargesPaid();
|
Set<LoanChargePaidBy> accrualCharges = accrualTransaction.getLoanChargesPaid();
|
||||||
@@ -771,16 +763,14 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
|||||||
String externalId = null;
|
String externalId = null;
|
||||||
final LocalDateTime currentDateTime = DateUtils.getLocalDateTimeOfTenant();
|
final LocalDateTime currentDateTime = DateUtils.getLocalDateTimeOfTenant();
|
||||||
payment = LoanTransaction.repayment(loan.getOffice(), payPrincipal.plus(interestPayable).plus(feePayable).plus(penaltyPayable),
|
payment = LoanTransaction.repayment(loan.getOffice(), payPrincipal.plus(interestPayable).plus(feePayable).plus(penaltyPayable),
|
||||||
paymentDetail, foreClosureDate, externalId, currentDateTime, appUser);
|
paymentDetail, foreClosureDate, externalId);
|
||||||
createdDate = createdDate.plusSeconds(1);
|
|
||||||
payment.updateCreatedDate(Date.from(createdDate.atZone(DateUtils.getDateTimeZoneOfTenant()).toInstant()));
|
|
||||||
payment.updateLoan(loan);
|
payment.updateLoan(loan);
|
||||||
newTransactions.add(payment);
|
newTransactions.add(payment);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Long> transactionIds = new ArrayList<>();
|
List<Long> transactionIds = new ArrayList<>();
|
||||||
final ChangedTransactionDetail changedTransactionDetail = loan.handleForeClosureTransactions(payment,
|
final ChangedTransactionDetail changedTransactionDetail = loan.handleForeClosureTransactions(payment,
|
||||||
defaultLoanLifecycleStateMachine(), scheduleGeneratorDTO, appUser);
|
defaultLoanLifecycleStateMachine(), scheduleGeneratorDTO);
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* TODO Vishwas Batch save is giving me a HibernateOptimisticLockingFailureException, looping and saving for the
|
* TODO Vishwas Batch save is giving me a HibernateOptimisticLockingFailureException, looping and saving for the
|
||||||
|
|||||||
+73
-133
@@ -21,10 +21,8 @@ package org.apache.fineract.portfolio.loanaccount.domain;
|
|||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.ZoneId;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -38,10 +36,8 @@ import javax.persistence.JoinColumn;
|
|||||||
import javax.persistence.ManyToOne;
|
import javax.persistence.ManyToOne;
|
||||||
import javax.persistence.OneToMany;
|
import javax.persistence.OneToMany;
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
import javax.persistence.Temporal;
|
|
||||||
import javax.persistence.TemporalType;
|
|
||||||
import javax.persistence.UniqueConstraint;
|
import javax.persistence.UniqueConstraint;
|
||||||
import org.apache.fineract.infrastructure.core.domain.AbstractPersistableCustom;
|
import org.apache.fineract.infrastructure.core.domain.AbstractAuditableCustom;
|
||||||
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
import org.apache.fineract.infrastructure.core.service.DateUtils;
|
||||||
import org.apache.fineract.organisation.monetary.data.CurrencyData;
|
import org.apache.fineract.organisation.monetary.data.CurrencyData;
|
||||||
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
|
||||||
@@ -53,7 +49,6 @@ import org.apache.fineract.portfolio.loanaccount.data.LoanTransactionEnumData;
|
|||||||
import org.apache.fineract.portfolio.loanproduct.service.LoanEnumerations;
|
import org.apache.fineract.portfolio.loanproduct.service.LoanEnumerations;
|
||||||
import org.apache.fineract.portfolio.paymentdetail.data.PaymentDetailData;
|
import org.apache.fineract.portfolio.paymentdetail.data.PaymentDetailData;
|
||||||
import org.apache.fineract.portfolio.paymentdetail.domain.PaymentDetail;
|
import org.apache.fineract.portfolio.paymentdetail.domain.PaymentDetail;
|
||||||
import org.apache.fineract.useradministration.domain.AppUser;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All monetary transactions against a loan are modelled through this entity. Disbursements, Repayments, Waivers,
|
* All monetary transactions against a loan are modelled through this entity. Disbursements, Repayments, Waivers,
|
||||||
@@ -61,7 +56,7 @@ import org.apache.fineract.useradministration.domain.AppUser;
|
|||||||
*/
|
*/
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "m_loan_transaction", uniqueConstraints = { @UniqueConstraint(columnNames = { "external_id" }, name = "external_id_UNIQUE") })
|
@Table(name = "m_loan_transaction", uniqueConstraints = { @UniqueConstraint(columnNames = { "external_id" }, name = "external_id_UNIQUE") })
|
||||||
public class LoanTransaction extends AbstractPersistableCustom {
|
public class LoanTransaction extends AbstractAuditableCustom {
|
||||||
|
|
||||||
@ManyToOne(optional = false)
|
@ManyToOne(optional = false)
|
||||||
@JoinColumn(name = "loan_id", nullable = false)
|
@JoinColumn(name = "loan_id", nullable = false)
|
||||||
@@ -78,13 +73,11 @@ public class LoanTransaction extends AbstractPersistableCustom {
|
|||||||
@Column(name = "transaction_type_enum", nullable = false)
|
@Column(name = "transaction_type_enum", nullable = false)
|
||||||
private Integer typeOf;
|
private Integer typeOf;
|
||||||
|
|
||||||
@Temporal(TemporalType.DATE)
|
|
||||||
@Column(name = "transaction_date", nullable = false)
|
@Column(name = "transaction_date", nullable = false)
|
||||||
private Date dateOf;
|
private LocalDate dateOf;
|
||||||
|
|
||||||
@Temporal(TemporalType.DATE)
|
|
||||||
@Column(name = "submitted_on_date", nullable = false)
|
@Column(name = "submitted_on_date", nullable = false)
|
||||||
private Date submittedOnDate;
|
private LocalDate submittedOnDate;
|
||||||
|
|
||||||
@Column(name = "amount", scale = 6, precision = 19, nullable = false)
|
@Column(name = "amount", scale = 6, precision = 19, nullable = false)
|
||||||
private BigDecimal amount;
|
private BigDecimal amount;
|
||||||
@@ -113,14 +106,6 @@ public class LoanTransaction extends AbstractPersistableCustom {
|
|||||||
@Column(name = "external_id", length = 100, nullable = true, unique = true)
|
@Column(name = "external_id", length = 100, nullable = true, unique = true)
|
||||||
private String externalId;
|
private String externalId;
|
||||||
|
|
||||||
@Temporal(TemporalType.TIMESTAMP)
|
|
||||||
@Column(name = "created_date", nullable = false)
|
|
||||||
private Date createdDate;
|
|
||||||
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "appuser_id", nullable = true)
|
|
||||||
private AppUser appUser;
|
|
||||||
|
|
||||||
@OneToMany(cascade = CascadeType.ALL, mappedBy = "loanTransaction", orphanRemoval = true, fetch = FetchType.EAGER)
|
@OneToMany(cascade = CascadeType.ALL, mappedBy = "loanTransaction", orphanRemoval = true, fetch = FetchType.EAGER)
|
||||||
private Set<LoanChargePaidBy> loanChargesPaid = new HashSet<>();
|
private Set<LoanChargePaidBy> loanChargesPaid = new HashSet<>();
|
||||||
|
|
||||||
@@ -136,44 +121,34 @@ public class LoanTransaction extends AbstractPersistableCustom {
|
|||||||
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "loanTransaction")
|
@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER, mappedBy = "loanTransaction")
|
||||||
private Set<LoanTransactionToRepaymentScheduleMapping> loanTransactionToRepaymentScheduleMappings = new HashSet<>();
|
private Set<LoanTransactionToRepaymentScheduleMapping> loanTransactionToRepaymentScheduleMappings = new HashSet<>();
|
||||||
|
|
||||||
protected LoanTransaction() {
|
protected LoanTransaction() {}
|
||||||
/*
|
|
||||||
* this.loan = null; this.dateOf = null; this.typeOf = null; this.submittedOnDate = DateUtils.getDateOfTenant();
|
|
||||||
* this.createdDate = new Date(); this.appUser = null;
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
public static LoanTransaction incomePosting(final Loan loan, final Office office, final Date dateOf, final BigDecimal amount,
|
public static LoanTransaction incomePosting(final Loan loan, final Office office, final LocalDate dateOf, final BigDecimal amount,
|
||||||
final BigDecimal interestPortion, final BigDecimal feeChargesPortion, final BigDecimal penaltyChargesPortion,
|
final BigDecimal interestPortion, final BigDecimal feeChargesPortion, final BigDecimal penaltyChargesPortion) {
|
||||||
final AppUser appUser) {
|
|
||||||
final Integer typeOf = LoanTransactionType.INCOME_POSTING.getValue();
|
final Integer typeOf = LoanTransactionType.INCOME_POSTING.getValue();
|
||||||
final BigDecimal principalPortion = BigDecimal.ZERO;
|
final BigDecimal principalPortion = BigDecimal.ZERO;
|
||||||
final BigDecimal overPaymentPortion = BigDecimal.ZERO;
|
final BigDecimal overPaymentPortion = BigDecimal.ZERO;
|
||||||
final boolean reversed = false;
|
final boolean reversed = false;
|
||||||
final PaymentDetail paymentDetail = null;
|
final PaymentDetail paymentDetail = null;
|
||||||
final String externalId = null;
|
final String externalId = null;
|
||||||
final LocalDateTime createdDate = DateUtils.getLocalDateTimeOfTenant();
|
|
||||||
return new LoanTransaction(loan, office, typeOf, dateOf, amount, principalPortion, interestPortion, feeChargesPortion,
|
return new LoanTransaction(loan, office, typeOf, dateOf, amount, principalPortion, interestPortion, feeChargesPortion,
|
||||||
penaltyChargesPortion, overPaymentPortion, reversed, paymentDetail, externalId, createdDate, appUser);
|
penaltyChargesPortion, overPaymentPortion, reversed, paymentDetail, externalId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanTransaction disbursement(final Office office, final Money amount, final PaymentDetail paymentDetail,
|
public static LoanTransaction disbursement(final Office office, final Money amount, final PaymentDetail paymentDetail,
|
||||||
final LocalDate disbursementDate, final String externalId, final LocalDateTime createdDate, final AppUser appUser) {
|
final LocalDate disbursementDate, final String externalId) {
|
||||||
return new LoanTransaction(null, office, LoanTransactionType.DISBURSEMENT, paymentDetail, amount.getAmount(), disbursementDate,
|
return new LoanTransaction(null, office, LoanTransactionType.DISBURSEMENT, paymentDetail, amount.getAmount(), disbursementDate,
|
||||||
externalId, createdDate, appUser);
|
externalId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanTransaction repayment(final Office office, final Money amount, final PaymentDetail paymentDetail,
|
public static LoanTransaction repayment(final Office office, final Money amount, final PaymentDetail paymentDetail,
|
||||||
final LocalDate paymentDate, final String externalId, final LocalDateTime createdDate, final AppUser appUser) {
|
final LocalDate paymentDate, final String externalId) {
|
||||||
return new LoanTransaction(null, office, LoanTransactionType.REPAYMENT, paymentDetail, amount.getAmount(), paymentDate, externalId,
|
return new LoanTransaction(null, office, LoanTransactionType.REPAYMENT, paymentDetail, amount.getAmount(), paymentDate, externalId);
|
||||||
createdDate, appUser);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanTransaction repaymentType(final LoanTransactionType repaymentType, final Office office, final Money amount,
|
public static LoanTransaction repaymentType(final LoanTransactionType repaymentType, final Office office, final Money amount,
|
||||||
final PaymentDetail paymentDetail, final LocalDate paymentDate, final String externalId, final LocalDateTime createdDate,
|
final PaymentDetail paymentDetail, final LocalDate paymentDate, final String externalId) {
|
||||||
final AppUser appUser) {
|
return new LoanTransaction(null, office, repaymentType, paymentDetail, amount.getAmount(), paymentDate, externalId);
|
||||||
return new LoanTransaction(null, office, repaymentType, paymentDetail, amount.getAmount(), paymentDate, externalId, createdDate,
|
|
||||||
appUser);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLoanTransactionToRepaymentScheduleMappings(final Integer installmentId, final BigDecimal chargePerInstallment) {
|
public void setLoanTransactionToRepaymentScheduleMappings(final Integer installmentId, final BigDecimal chargePerInstallment) {
|
||||||
@@ -189,34 +164,32 @@ public class LoanTransaction extends AbstractPersistableCustom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static LoanTransaction recoveryRepayment(final Office office, final Money amount, final PaymentDetail paymentDetail,
|
public static LoanTransaction recoveryRepayment(final Office office, final Money amount, final PaymentDetail paymentDetail,
|
||||||
final LocalDate paymentDate, final String externalId, final LocalDateTime createdDate, final AppUser appUser) {
|
final LocalDate paymentDate, final String externalId) {
|
||||||
return new LoanTransaction(null, office, LoanTransactionType.RECOVERY_REPAYMENT, paymentDetail, amount.getAmount(), paymentDate,
|
return new LoanTransaction(null, office, LoanTransactionType.RECOVERY_REPAYMENT, paymentDetail, amount.getAmount(), paymentDate,
|
||||||
externalId, createdDate, appUser);
|
externalId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanTransaction loanPayment(final Loan loan, final Office office, final Money amount, final PaymentDetail paymentDetail,
|
public static LoanTransaction loanPayment(final Loan loan, final Office office, final Money amount, final PaymentDetail paymentDetail,
|
||||||
final LocalDate paymentDate, final String externalId, final LoanTransactionType transactionType,
|
final LocalDate paymentDate, final String externalId, final LoanTransactionType transactionType) {
|
||||||
final LocalDateTime createdDate, final AppUser appUser) {
|
return new LoanTransaction(loan, office, transactionType, paymentDetail, amount.getAmount(), paymentDate, externalId);
|
||||||
return new LoanTransaction(loan, office, transactionType, paymentDetail, amount.getAmount(), paymentDate, externalId, createdDate,
|
|
||||||
appUser);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanTransaction repaymentAtDisbursement(final Office office, final Money amount, final PaymentDetail paymentDetail,
|
public static LoanTransaction repaymentAtDisbursement(final Office office, final Money amount, final PaymentDetail paymentDetail,
|
||||||
final LocalDate paymentDate, final String externalId, final LocalDateTime createdDate, final AppUser appUser) {
|
final LocalDate paymentDate, final String externalId) {
|
||||||
return new LoanTransaction(null, office, LoanTransactionType.REPAYMENT_AT_DISBURSEMENT, paymentDetail, amount.getAmount(),
|
return new LoanTransaction(null, office, LoanTransactionType.REPAYMENT_AT_DISBURSEMENT, paymentDetail, amount.getAmount(),
|
||||||
paymentDate, externalId, createdDate, appUser);
|
paymentDate, externalId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanTransaction waiver(final Office office, final Loan loan, final Money amount, final LocalDate waiveDate,
|
public static LoanTransaction waiver(final Office office, final Loan loan, final Money amount, final LocalDate waiveDate,
|
||||||
final Money waived, final Money unrecognizedPortion, final LocalDateTime createdDate, final AppUser appUser) {
|
final Money waived, final Money unrecognizedPortion) {
|
||||||
LoanTransaction loanTransaction = new LoanTransaction(loan, office, LoanTransactionType.WAIVE_INTEREST, amount.getAmount(),
|
LoanTransaction loanTransaction = new LoanTransaction(loan, office, LoanTransactionType.WAIVE_INTEREST, amount.getAmount(),
|
||||||
waiveDate, null, createdDate, appUser);
|
waiveDate, null);
|
||||||
loanTransaction.updateInterestComponent(waived, unrecognizedPortion);
|
loanTransaction.updateInterestComponent(waived, unrecognizedPortion);
|
||||||
return loanTransaction;
|
return loanTransaction;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanTransaction accrueInterest(final Office office, final Loan loan, final Money amount,
|
public static LoanTransaction accrueInterest(final Office office, final Loan loan, final Money amount,
|
||||||
final LocalDate interestAppliedDate, final LocalDateTime createdDate, final AppUser appUser) {
|
final LocalDate interestAppliedDate) {
|
||||||
BigDecimal principalPortion = null;
|
BigDecimal principalPortion = null;
|
||||||
BigDecimal feesPortion = null;
|
BigDecimal feesPortion = null;
|
||||||
BigDecimal penaltiesPortion = null;
|
BigDecimal penaltiesPortion = null;
|
||||||
@@ -225,96 +198,80 @@ public class LoanTransaction extends AbstractPersistableCustom {
|
|||||||
boolean reversed = false;
|
boolean reversed = false;
|
||||||
PaymentDetail paymentDetail = null;
|
PaymentDetail paymentDetail = null;
|
||||||
String externalId = null;
|
String externalId = null;
|
||||||
return new LoanTransaction(loan, office, LoanTransactionType.ACCRUAL.getValue(),
|
return new LoanTransaction(loan, office, LoanTransactionType.ACCRUAL.getValue(), interestAppliedDate, interestPortion,
|
||||||
Date.from(interestAppliedDate.atStartOfDay(ZoneId.systemDefault()).toInstant()), interestPortion, principalPortion,
|
principalPortion, interestPortion, feesPortion, penaltiesPortion, overPaymentPortion, reversed, paymentDetail, externalId);
|
||||||
interestPortion, feesPortion, penaltiesPortion, overPaymentPortion, reversed, paymentDetail, externalId, createdDate,
|
|
||||||
appUser);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanTransaction accrual(final Loan loan, final Office office, final Money amount, final Money interest,
|
public static LoanTransaction accrual(final Loan loan, final Office office, final Money amount, final Money interest,
|
||||||
final Money feeCharges, final Money penaltyCharges, final LocalDate transactionDate) {
|
final Money feeCharges, final Money penaltyCharges, final LocalDate transactionDate) {
|
||||||
final AppUser appUser = null;
|
|
||||||
return accrueTransaction(loan, office, transactionDate, amount.getAmount(), interest.getAmount(), feeCharges.getAmount(),
|
return accrueTransaction(loan, office, transactionDate, amount.getAmount(), interest.getAmount(), feeCharges.getAmount(),
|
||||||
penaltyCharges.getAmount(), appUser);
|
penaltyCharges.getAmount());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanTransaction accrueTransaction(final Loan loan, final Office office, final LocalDate dateOf, final BigDecimal amount,
|
public static LoanTransaction accrueTransaction(final Loan loan, final Office office, final LocalDate dateOf, final BigDecimal amount,
|
||||||
final BigDecimal interestPortion, final BigDecimal feeChargesPortion, final BigDecimal penaltyChargesPortion,
|
final BigDecimal interestPortion, final BigDecimal feeChargesPortion, final BigDecimal penaltyChargesPortion) {
|
||||||
final AppUser appUser) {
|
|
||||||
BigDecimal principalPortion = null;
|
BigDecimal principalPortion = null;
|
||||||
BigDecimal overPaymentPortion = null;
|
BigDecimal overPaymentPortion = null;
|
||||||
boolean reversed = false;
|
boolean reversed = false;
|
||||||
PaymentDetail paymentDetail = null;
|
PaymentDetail paymentDetail = null;
|
||||||
String externalId = null;
|
String externalId = null;
|
||||||
LocalDateTime createdDate = DateUtils.getLocalDateTimeOfTenant();
|
return new LoanTransaction(loan, office, LoanTransactionType.ACCRUAL.getValue(), dateOf, amount, principalPortion, interestPortion,
|
||||||
return new LoanTransaction(loan, office, LoanTransactionType.ACCRUAL.getValue(),
|
feeChargesPortion, penaltyChargesPortion, overPaymentPortion, reversed, paymentDetail, externalId);
|
||||||
Date.from(dateOf.atStartOfDay(ZoneId.systemDefault()).toInstant()), amount, principalPortion, interestPortion,
|
|
||||||
feeChargesPortion, penaltyChargesPortion, overPaymentPortion, reversed, paymentDetail, externalId, createdDate, appUser);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanTransaction initiateTransfer(final Office office, final Loan loan, final LocalDate transferDate,
|
public static LoanTransaction initiateTransfer(final Office office, final Loan loan, final LocalDate transferDate) {
|
||||||
final LocalDateTime createdDate, final AppUser appUser) {
|
return new LoanTransaction(loan, office, LoanTransactionType.INITIATE_TRANSFER.getValue(), transferDate,
|
||||||
return new LoanTransaction(loan, office, LoanTransactionType.INITIATE_TRANSFER.getValue(),
|
loan.getSummary().getTotalOutstanding(), loan.getSummary().getTotalPrincipalOutstanding(),
|
||||||
Date.from(transferDate.atStartOfDay(ZoneId.systemDefault()).toInstant()), loan.getSummary().getTotalOutstanding(),
|
loan.getSummary().getTotalInterestOutstanding(), loan.getSummary().getTotalFeeChargesOutstanding(),
|
||||||
loan.getSummary().getTotalPrincipalOutstanding(), loan.getSummary().getTotalInterestOutstanding(),
|
loan.getSummary().getTotalPenaltyChargesOutstanding(), null, false, null, null);
|
||||||
loan.getSummary().getTotalFeeChargesOutstanding(), loan.getSummary().getTotalPenaltyChargesOutstanding(), null, false, null,
|
|
||||||
null, createdDate, appUser);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanTransaction approveTransfer(final Office office, final Loan loan, final LocalDate transferDate,
|
public static LoanTransaction approveTransfer(final Office office, final Loan loan, final LocalDate transferDate) {
|
||||||
final LocalDateTime createdDate, final AppUser appUser) {
|
return new LoanTransaction(loan, office, LoanTransactionType.APPROVE_TRANSFER.getValue(), transferDate,
|
||||||
return new LoanTransaction(loan, office, LoanTransactionType.APPROVE_TRANSFER.getValue(),
|
loan.getSummary().getTotalOutstanding(), loan.getSummary().getTotalPrincipalOutstanding(),
|
||||||
Date.from(transferDate.atStartOfDay(ZoneId.systemDefault()).toInstant()), loan.getSummary().getTotalOutstanding(),
|
loan.getSummary().getTotalInterestOutstanding(), loan.getSummary().getTotalFeeChargesOutstanding(),
|
||||||
loan.getSummary().getTotalPrincipalOutstanding(), loan.getSummary().getTotalInterestOutstanding(),
|
loan.getSummary().getTotalPenaltyChargesOutstanding(), null, false, null, null);
|
||||||
loan.getSummary().getTotalFeeChargesOutstanding(), loan.getSummary().getTotalPenaltyChargesOutstanding(), null, false, null,
|
|
||||||
null, createdDate, appUser);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanTransaction withdrawTransfer(final Office office, final Loan loan, final LocalDate transferDate,
|
public static LoanTransaction withdrawTransfer(final Office office, final Loan loan, final LocalDate transferDate) {
|
||||||
final LocalDateTime createdDate, final AppUser appUser) {
|
return new LoanTransaction(loan, office, LoanTransactionType.WITHDRAW_TRANSFER.getValue(), transferDate,
|
||||||
return new LoanTransaction(loan, office, LoanTransactionType.WITHDRAW_TRANSFER.getValue(),
|
loan.getSummary().getTotalOutstanding(), loan.getSummary().getTotalPrincipalOutstanding(),
|
||||||
Date.from(transferDate.atStartOfDay(ZoneId.systemDefault()).toInstant()), loan.getSummary().getTotalOutstanding(),
|
loan.getSummary().getTotalInterestOutstanding(), loan.getSummary().getTotalFeeChargesOutstanding(),
|
||||||
loan.getSummary().getTotalPrincipalOutstanding(), loan.getSummary().getTotalInterestOutstanding(),
|
loan.getSummary().getTotalPenaltyChargesOutstanding(), null, false, null, null);
|
||||||
loan.getSummary().getTotalFeeChargesOutstanding(), loan.getSummary().getTotalPenaltyChargesOutstanding(), null, false, null,
|
|
||||||
null, createdDate, appUser);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanTransaction refund(final Office office, final Money amount, final PaymentDetail paymentDetail,
|
public static LoanTransaction refund(final Office office, final Money amount, final PaymentDetail paymentDetail,
|
||||||
final LocalDate paymentDate, final String externalId, final LocalDateTime createdDate, final AppUser appUser) {
|
final LocalDate paymentDate, final String externalId) {
|
||||||
return new LoanTransaction(null, office, LoanTransactionType.REFUND, paymentDetail, amount.getAmount(), paymentDate, externalId,
|
return new LoanTransaction(null, office, LoanTransactionType.REFUND, paymentDetail, amount.getAmount(), paymentDate, externalId);
|
||||||
createdDate, appUser);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanTransaction copyTransactionProperties(final LoanTransaction loanTransaction) {
|
public static LoanTransaction copyTransactionProperties(final LoanTransaction loanTransaction) {
|
||||||
return new LoanTransaction(loanTransaction.loan, loanTransaction.office, loanTransaction.typeOf, loanTransaction.dateOf,
|
return new LoanTransaction(loanTransaction.loan, loanTransaction.office, loanTransaction.typeOf, loanTransaction.dateOf,
|
||||||
loanTransaction.amount, loanTransaction.principalPortion, loanTransaction.interestPortion,
|
loanTransaction.amount, loanTransaction.principalPortion, loanTransaction.interestPortion,
|
||||||
loanTransaction.feeChargesPortion, loanTransaction.penaltyChargesPortion, loanTransaction.overPaymentPortion,
|
loanTransaction.feeChargesPortion, loanTransaction.penaltyChargesPortion, loanTransaction.overPaymentPortion,
|
||||||
loanTransaction.reversed, loanTransaction.paymentDetail, loanTransaction.externalId,
|
loanTransaction.reversed, loanTransaction.paymentDetail, loanTransaction.externalId);
|
||||||
(loanTransaction.createdDate == null) ? LocalDateTime.now(DateUtils.getDateTimeZoneOfTenant())
|
|
||||||
: LocalDateTime.ofInstant(loanTransaction.createdDate.toInstant(), DateUtils.getDateTimeZoneOfTenant()),
|
|
||||||
loanTransaction.appUser);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanTransaction accrueLoanCharge(final Loan loan, final Office office, final Money amount, final LocalDate applyDate,
|
public static LoanTransaction accrueLoanCharge(final Loan loan, final Office office, final Money amount, final LocalDate applyDate,
|
||||||
final Money feeCharges, final Money penaltyCharges, final LocalDateTime createdDate, final AppUser appUser) {
|
final Money feeCharges, final Money penaltyCharges) {
|
||||||
String externalId = null;
|
String externalId = null;
|
||||||
final LoanTransaction applyCharge = new LoanTransaction(loan, office, LoanTransactionType.ACCRUAL, amount.getAmount(), applyDate,
|
final LoanTransaction applyCharge = new LoanTransaction(loan, office, LoanTransactionType.ACCRUAL, amount.getAmount(), applyDate,
|
||||||
externalId, createdDate, appUser);
|
externalId);
|
||||||
applyCharge.updateChargesComponents(feeCharges, penaltyCharges);
|
applyCharge.updateChargesComponents(feeCharges, penaltyCharges);
|
||||||
return applyCharge;
|
return applyCharge;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanTransaction creditBalanceRefund(final Loan loan, final Office office, final Money amount, final LocalDate paymentDate,
|
public static LoanTransaction creditBalanceRefund(final Loan loan, final Office office, final Money amount, final LocalDate paymentDate,
|
||||||
final String externalId, final LocalDateTime createdDate, final AppUser appUser) {
|
final String externalId) {
|
||||||
final PaymentDetail paymentDetail = null;
|
final PaymentDetail paymentDetail = null;
|
||||||
return new LoanTransaction(loan, office, LoanTransactionType.CREDIT_BALANCE_REFUND, paymentDetail, amount.getAmount(), paymentDate,
|
return new LoanTransaction(loan, office, LoanTransactionType.CREDIT_BALANCE_REFUND, paymentDetail, amount.getAmount(), paymentDate,
|
||||||
externalId, createdDate, appUser);
|
externalId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanTransaction refundForActiveLoan(final Office office, final Money amount, final PaymentDetail paymentDetail,
|
public static LoanTransaction refundForActiveLoan(final Office office, final Money amount, final PaymentDetail paymentDetail,
|
||||||
final LocalDate paymentDate, final String externalId, final LocalDateTime createdDate, final AppUser appUser) {
|
final LocalDate paymentDate, final String externalId) {
|
||||||
return new LoanTransaction(null, office, LoanTransactionType.REFUND_FOR_ACTIVE_LOAN, paymentDetail, amount.getAmount(), paymentDate,
|
return new LoanTransaction(null, office, LoanTransactionType.REFUND_FOR_ACTIVE_LOAN, paymentDetail, amount.getAmount(), paymentDate,
|
||||||
externalId, createdDate, appUser);
|
externalId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean transactionAmountsMatch(final MonetaryCurrency currency, final LoanTransaction loanTransaction,
|
public static boolean transactionAmountsMatch(final MonetaryCurrency currency, final LoanTransaction loanTransaction,
|
||||||
@@ -330,10 +287,10 @@ public class LoanTransaction extends AbstractPersistableCustom {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private LoanTransaction(final Loan loan, final Office office, final Integer typeOf, final Date dateOf, final BigDecimal amount,
|
private LoanTransaction(final Loan loan, final Office office, final Integer typeOf, final LocalDate dateOf, final BigDecimal amount,
|
||||||
final BigDecimal principalPortion, final BigDecimal interestPortion, final BigDecimal feeChargesPortion,
|
final BigDecimal principalPortion, final BigDecimal interestPortion, final BigDecimal feeChargesPortion,
|
||||||
final BigDecimal penaltyChargesPortion, final BigDecimal overPaymentPortion, final boolean reversed,
|
final BigDecimal penaltyChargesPortion, final BigDecimal overPaymentPortion, final boolean reversed,
|
||||||
final PaymentDetail paymentDetail, final String externalId, final LocalDateTime createdDate, final AppUser appUser) {
|
final PaymentDetail paymentDetail, final String externalId) {
|
||||||
|
|
||||||
this.loan = loan;
|
this.loan = loan;
|
||||||
this.typeOf = typeOf;
|
this.typeOf = typeOf;
|
||||||
@@ -348,52 +305,43 @@ public class LoanTransaction extends AbstractPersistableCustom {
|
|||||||
this.paymentDetail = paymentDetail;
|
this.paymentDetail = paymentDetail;
|
||||||
this.office = office;
|
this.office = office;
|
||||||
this.externalId = externalId;
|
this.externalId = externalId;
|
||||||
this.submittedOnDate = DateUtils.getBusinessDate();
|
this.submittedOnDate = DateUtils.getBusinessLocalDate();
|
||||||
this.createdDate = Date.from(createdDate.atZone(DateUtils.getDateTimeZoneOfTenant()).toInstant());
|
|
||||||
this.appUser = appUser;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanTransaction waiveLoanCharge(final Loan loan, final Office office, final Money waived, final LocalDate waiveDate,
|
public static LoanTransaction waiveLoanCharge(final Loan loan, final Office office, final Money waived, final LocalDate waiveDate,
|
||||||
final Money feeChargesWaived, final Money penaltyChargesWaived, final Money unrecognizedCharge, final LocalDateTime createdDate,
|
final Money feeChargesWaived, final Money penaltyChargesWaived, final Money unrecognizedCharge) {
|
||||||
final AppUser appUser) {
|
|
||||||
final LoanTransaction waiver = new LoanTransaction(loan, office, LoanTransactionType.WAIVE_CHARGES, waived.getAmount(), waiveDate,
|
final LoanTransaction waiver = new LoanTransaction(loan, office, LoanTransactionType.WAIVE_CHARGES, waived.getAmount(), waiveDate,
|
||||||
null, createdDate, appUser);
|
null);
|
||||||
waiver.updateChargesComponents(feeChargesWaived, penaltyChargesWaived, unrecognizedCharge);
|
waiver.updateChargesComponents(feeChargesWaived, penaltyChargesWaived, unrecognizedCharge);
|
||||||
|
|
||||||
return waiver;
|
return waiver;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoanTransaction writeoff(final Loan loan, final Office office, final LocalDate writeOffDate, final String externalId,
|
public static LoanTransaction writeoff(final Loan loan, final Office office, final LocalDate writeOffDate, final String externalId) {
|
||||||
final LocalDateTime createdDate, final AppUser appUser) {
|
return new LoanTransaction(loan, office, LoanTransactionType.WRITEOFF, null, writeOffDate, externalId);
|
||||||
return new LoanTransaction(loan, office, LoanTransactionType.WRITEOFF, null, writeOffDate, externalId, createdDate, appUser);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private LoanTransaction(final Loan loan, final Office office, final LoanTransactionType type, final BigDecimal amount,
|
private LoanTransaction(final Loan loan, final Office office, final LoanTransactionType type, final BigDecimal amount,
|
||||||
final LocalDate date, final String externalId, final LocalDateTime createdDate, final AppUser appUser) {
|
final LocalDate date, final String externalId) {
|
||||||
this.loan = loan;
|
this.loan = loan;
|
||||||
this.typeOf = type.getValue();
|
this.typeOf = type.getValue();
|
||||||
this.amount = amount;
|
this.amount = amount;
|
||||||
this.dateOf = Date.from(date.atStartOfDay(ZoneId.systemDefault()).toInstant());
|
this.dateOf = date;
|
||||||
this.externalId = externalId;
|
this.externalId = externalId;
|
||||||
this.office = office;
|
this.office = office;
|
||||||
this.submittedOnDate = DateUtils.getBusinessDate();
|
this.submittedOnDate = DateUtils.getBusinessLocalDate();
|
||||||
this.createdDate = Date.from(createdDate.atZone(DateUtils.getDateTimeZoneOfTenant()).toInstant());
|
|
||||||
this.appUser = appUser;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private LoanTransaction(final Loan loan, final Office office, final LoanTransactionType type, final PaymentDetail paymentDetail,
|
private LoanTransaction(final Loan loan, final Office office, final LoanTransactionType type, final PaymentDetail paymentDetail,
|
||||||
final BigDecimal amount, final LocalDate date, final String externalId, final LocalDateTime createdDate,
|
final BigDecimal amount, final LocalDate date, final String externalId) {
|
||||||
final AppUser appUser) {
|
|
||||||
this.loan = loan;
|
this.loan = loan;
|
||||||
this.typeOf = type.getValue();
|
this.typeOf = type.getValue();
|
||||||
this.paymentDetail = paymentDetail;
|
this.paymentDetail = paymentDetail;
|
||||||
this.amount = amount;
|
this.amount = amount;
|
||||||
this.dateOf = Date.from(date.atStartOfDay(ZoneId.systemDefault()).toInstant());
|
this.dateOf = date;
|
||||||
this.externalId = externalId;
|
this.externalId = externalId;
|
||||||
this.office = office;
|
this.office = office;
|
||||||
this.submittedOnDate = DateUtils.getBusinessDate();
|
this.submittedOnDate = DateUtils.getBusinessLocalDate();
|
||||||
this.createdDate = Date.from(createdDate.atZone(DateUtils.getDateTimeZoneOfTenant()).toInstant());
|
|
||||||
this.appUser = appUser;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reverse() {
|
public void reverse() {
|
||||||
@@ -504,10 +452,10 @@ public class LoanTransaction extends AbstractPersistableCustom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public LocalDate getTransactionDate() {
|
public LocalDate getTransactionDate() {
|
||||||
return LocalDate.ofInstant(this.dateOf.toInstant(), DateUtils.getDateTimeZoneOfTenant());
|
return this.dateOf;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Date getDateOf() {
|
public LocalDate getDateOf() {
|
||||||
return this.dateOf;
|
return this.dateOf;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -778,14 +726,10 @@ public class LoanTransaction extends AbstractPersistableCustom {
|
|||||||
this.manuallyAdjustedOrReversed = true;
|
this.manuallyAdjustedOrReversed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private LocalDate getCreatedDate() {
|
|
||||||
return (this.createdDate == null) ? LocalDate.now(DateUtils.getDateTimeZoneOfTenant())
|
|
||||||
: LocalDate.ofInstant(this.createdDate.toInstant(), DateUtils.getDateTimeZoneOfTenant());
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalDateTime getCreatedDateTime() {
|
public LocalDateTime getCreatedDateTime() {
|
||||||
return (this.createdDate == null) ? LocalDateTime.now(DateUtils.getDateTimeZoneOfTenant())
|
return (this.getCreatedDate().isPresent()
|
||||||
: LocalDateTime.ofInstant(this.createdDate.toInstant(), DateUtils.getDateTimeZoneOfTenant());
|
? LocalDateTime.ofInstant(this.getCreatedDate().get(), DateUtils.getDateTimeZoneOfTenant())
|
||||||
|
: DateUtils.getLocalDateTimeOfTenant());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isLastTransaction(final LoanTransaction loanTransaction) {
|
public boolean isLastTransaction(final LoanTransaction loanTransaction) {
|
||||||
@@ -793,7 +737,7 @@ public class LoanTransaction extends AbstractPersistableCustom {
|
|||||||
if (loanTransaction != null) {
|
if (loanTransaction != null) {
|
||||||
isLatest = this.getTransactionDate().isBefore(loanTransaction.getTransactionDate())
|
isLatest = this.getTransactionDate().isBefore(loanTransaction.getTransactionDate())
|
||||||
|| (this.getTransactionDate().isEqual(loanTransaction.getTransactionDate())
|
|| (this.getTransactionDate().isEqual(loanTransaction.getTransactionDate())
|
||||||
&& this.getCreatedDate().isBefore(loanTransaction.getCreatedDate()));
|
&& this.getCreatedDateTime().isBefore(loanTransaction.getCreatedDateTime()));
|
||||||
}
|
}
|
||||||
return isLatest;
|
return isLatest;
|
||||||
}
|
}
|
||||||
@@ -801,7 +745,7 @@ public class LoanTransaction extends AbstractPersistableCustom {
|
|||||||
public boolean isLatestTransaction(final LoanTransaction loanTransaction) {
|
public boolean isLatestTransaction(final LoanTransaction loanTransaction) {
|
||||||
boolean isLatest = false;
|
boolean isLatest = false;
|
||||||
if (loanTransaction != null) {
|
if (loanTransaction != null) {
|
||||||
isLatest = this.getCreatedDate().isBefore(loanTransaction.getCreatedDate());
|
isLatest = this.getCreatedDateTime().isBefore(loanTransaction.getCreatedDateTime());
|
||||||
}
|
}
|
||||||
return isLatest;
|
return isLatest;
|
||||||
}
|
}
|
||||||
@@ -845,10 +789,6 @@ public class LoanTransaction extends AbstractPersistableCustom {
|
|||||||
return isDisbursement() || isAccrual() || isRepaymentAtDisbursement();
|
return isDisbursement() || isAccrual() || isRepaymentAtDisbursement();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateCreatedDate(Date createdDate) {
|
|
||||||
this.createdDate = createdDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isAccrualTransaction() {
|
public boolean isAccrualTransaction() {
|
||||||
return isAccrual();
|
return isAccrual();
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -881,14 +881,14 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
|||||||
currentPeriodParams.minusEarlyPaidAmount(unprocessed);
|
currentPeriodParams.minusEarlyPaidAmount(unprocessed);
|
||||||
updateMapWithAmount(scheduleParams.getPrincipalPortionMap(), unprocessed.negated(), applicableDate);
|
updateMapWithAmount(scheduleParams.getPrincipalPortionMap(), unprocessed.negated(), applicableDate);
|
||||||
LoanTransaction loanTransaction = LoanTransaction.repayment(null, unprocessed, null,
|
LoanTransaction loanTransaction = LoanTransaction.repayment(null, unprocessed, null,
|
||||||
transactionDate, null, DateUtils.getLocalDateTimeOfTenant(), null);
|
transactionDate, null);
|
||||||
RecalculationDetail recalculationDetail = new RecalculationDetail(transactionDate, loanTransaction);
|
RecalculationDetail recalculationDetail = new RecalculationDetail(transactionDate, loanTransaction);
|
||||||
unprocessedTransactions.add(recalculationDetail);
|
unprocessedTransactions.add(recalculationDetail);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LoanTransaction loanTransaction = LoanTransaction.repayment(null, unprocessed, null, scheduledDueDate, null,
|
LoanTransaction loanTransaction = LoanTransaction.repayment(null, unprocessed, null, scheduledDueDate,
|
||||||
DateUtils.getLocalDateTimeOfTenant(), null);
|
null);
|
||||||
RecalculationDetail recalculationDetail = new RecalculationDetail(scheduledDueDate, loanTransaction);
|
RecalculationDetail recalculationDetail = new RecalculationDetail(scheduledDueDate, loanTransaction);
|
||||||
unprocessedTransactions.add(recalculationDetail);
|
unprocessedTransactions.add(recalculationDetail);
|
||||||
checkForOutstanding = false;
|
checkForOutstanding = false;
|
||||||
|
|||||||
+1
-3
@@ -116,7 +116,6 @@ import org.apache.fineract.portfolio.loanproduct.domain.LoanProductVariableInsta
|
|||||||
import org.apache.fineract.portfolio.loanproduct.domain.RecalculationFrequencyType;
|
import org.apache.fineract.portfolio.loanproduct.domain.RecalculationFrequencyType;
|
||||||
import org.apache.fineract.portfolio.loanproduct.exception.LoanProductNotFoundException;
|
import org.apache.fineract.portfolio.loanproduct.exception.LoanProductNotFoundException;
|
||||||
import org.apache.fineract.portfolio.loanproduct.service.LoanEnumerations;
|
import org.apache.fineract.portfolio.loanproduct.service.LoanEnumerations;
|
||||||
import org.apache.fineract.useradministration.domain.AppUser;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@@ -878,8 +877,7 @@ public class LoanScheduleAssembler {
|
|||||||
}
|
}
|
||||||
final LocalDate recalculateFrom = null;
|
final LocalDate recalculateFrom = null;
|
||||||
ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
||||||
AppUser currentUser = this.context.getAuthenticatedUserIfPresent();
|
loan.regenerateRepaymentSchedule(scheduleGeneratorDTO);
|
||||||
loan.regenerateRepaymentSchedule(scheduleGeneratorDTO, currentUser);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<LoanTermVariations> adjustExistingVariations(List<LoanTermVariations> variations, List<LoanTermVariations> newVariations,
|
private List<LoanTermVariations> adjustExistingVariations(List<LoanTermVariations> variations, List<LoanTermVariations> newVariations,
|
||||||
|
|||||||
+1
-3
@@ -34,7 +34,6 @@ import org.apache.fineract.portfolio.loanaccount.domain.LoanAccountDomainService
|
|||||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanTermVariations;
|
import org.apache.fineract.portfolio.loanaccount.domain.LoanTermVariations;
|
||||||
import org.apache.fineract.portfolio.loanaccount.service.LoanAssembler;
|
import org.apache.fineract.portfolio.loanaccount.service.LoanAssembler;
|
||||||
import org.apache.fineract.portfolio.loanaccount.service.LoanUtilService;
|
import org.apache.fineract.portfolio.loanaccount.service.LoanUtilService;
|
||||||
import org.apache.fineract.useradministration.domain.AppUser;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
@@ -104,8 +103,7 @@ public class LoanScheduleWritePlatformServiceImpl implements LoanScheduleWritePl
|
|||||||
loan.getLoanTermVariations().clear();
|
loan.getLoanTermVariations().clear();
|
||||||
final LocalDate recalculateFrom = null;
|
final LocalDate recalculateFrom = null;
|
||||||
ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
||||||
AppUser currentUser = this.context.getAuthenticatedUserIfPresent();
|
loan.regenerateRepaymentSchedule(scheduleGeneratorDTO);
|
||||||
loan.regenerateRepaymentSchedule(scheduleGeneratorDTO, currentUser);
|
|
||||||
this.loanAccountDomainService.saveLoanWithDataIntegrityViolationChecks(loan);
|
this.loanAccountDomainService.saveLoanWithDataIntegrityViolationChecks(loan);
|
||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
.withLoanId(loanId) //
|
.withLoanId(loanId) //
|
||||||
|
|||||||
+1
-1
@@ -487,7 +487,7 @@ public class LoanRescheduleRequestWritePlatformServiceImpl implements LoanResche
|
|||||||
final LoanScheduleDTO loanSchedule = loanScheduleGenerator.rescheduleNextInstallments(mathContext, loanApplicationTerms, loan,
|
final LoanScheduleDTO loanSchedule = loanScheduleGenerator.rescheduleNextInstallments(mathContext, loanApplicationTerms, loan,
|
||||||
loanApplicationTerms.getHolidayDetailDTO(), loanRepaymentScheduleTransactionProcessor, rescheduleFromDate);
|
loanApplicationTerms.getHolidayDetailDTO(), loanRepaymentScheduleTransactionProcessor, rescheduleFromDate);
|
||||||
|
|
||||||
loan.updateLoanSchedule(loanSchedule.getInstallments(), appUser);
|
loan.updateLoanSchedule(loanSchedule.getInstallments());
|
||||||
loan.recalculateAllCharges();
|
loan.recalculateAllCharges();
|
||||||
ChangedTransactionDetail changedTransactionDetail = loan.processTransactions();
|
ChangedTransactionDetail changedTransactionDetail = loan.processTransactions();
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -499,7 +499,7 @@ public class LoanAccrualWritePlatformServiceImpl implements LoanAccrualWritePlat
|
|||||||
final List<Long> existingReversedTransactionIds = new ArrayList<>();
|
final List<Long> existingReversedTransactionIds = new ArrayList<>();
|
||||||
existingTransactionIds.addAll(loan.findExistingTransactionIds());
|
existingTransactionIds.addAll(loan.findExistingTransactionIds());
|
||||||
existingReversedTransactionIds.addAll(loan.findExistingReversedTransactionIds());
|
existingReversedTransactionIds.addAll(loan.findExistingReversedTransactionIds());
|
||||||
loan.processIncomeTransactions(this.userRepository.fetchSystemUser());
|
loan.processIncomeTransactions();
|
||||||
this.loanRepositoryWrapper.saveAndFlush(loan);
|
this.loanRepositoryWrapper.saveAndFlush(loan);
|
||||||
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);
|
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -1050,7 +1050,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
|||||||
final JsonQuery query = JsonQuery.from(command.json(), parsedQuery, this.fromJsonHelper);
|
final JsonQuery query = JsonQuery.from(command.json(), parsedQuery, this.fromJsonHelper);
|
||||||
|
|
||||||
final LoanScheduleModel loanSchedule = this.calculationPlatformService.calculateLoanSchedule(query, false);
|
final LoanScheduleModel loanSchedule = this.calculationPlatformService.calculateLoanSchedule(query, false);
|
||||||
existingLoanApplication.updateLoanSchedule(loanSchedule, currentUser);
|
existingLoanApplication.updateLoanSchedule(loanSchedule);
|
||||||
existingLoanApplication.recalculateAllCharges();
|
existingLoanApplication.recalculateAllCharges();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1449,7 +1449,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
|||||||
|| changes.containsKey("expectedDisbursementDate")) {
|
|| changes.containsKey("expectedDisbursementDate")) {
|
||||||
LocalDate recalculateFrom = null;
|
LocalDate recalculateFrom = null;
|
||||||
ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
||||||
loan.regenerateRepaymentSchedule(scheduleGeneratorDTO, currentUser);
|
loan.regenerateRepaymentSchedule(scheduleGeneratorDTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loan.isTopup() && loan.getClientId() != null) {
|
if (loan.isTopup() && loan.getClientId() != null) {
|
||||||
@@ -1553,7 +1553,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
|||||||
|| changes.containsKey(LoanApiConstants.disbursementPrincipalParameterName)) {
|
|| changes.containsKey(LoanApiConstants.disbursementPrincipalParameterName)) {
|
||||||
LocalDate recalculateFrom = null;
|
LocalDate recalculateFrom = null;
|
||||||
ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
||||||
loan.regenerateRepaymentSchedule(scheduleGeneratorDTO, currentUser);
|
loan.regenerateRepaymentSchedule(scheduleGeneratorDTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
loan.adjustNetDisbursalAmount(loan.getProposedPrincipal());
|
loan.adjustNetDisbursalAmount(loan.getProposedPrincipal());
|
||||||
|
|||||||
+1
-2
@@ -503,8 +503,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
|||||||
final ApplicationCurrency applicationCurrency = this.applicationCurrencyRepository.findOneWithNotFoundDetection(currency);
|
final ApplicationCurrency applicationCurrency = this.applicationCurrencyRepository.findOneWithNotFoundDetection(currency);
|
||||||
final CurrencyData currencyData = applicationCurrency.toData();
|
final CurrencyData currencyData = applicationCurrency.toData();
|
||||||
|
|
||||||
final LoanTransaction waiveOfInterest = loan.deriveDefaultInterestWaiverTransaction(DateUtils.getLocalDateTimeOfTenant(),
|
final LoanTransaction waiveOfInterest = loan.deriveDefaultInterestWaiverTransaction();
|
||||||
currentUser);
|
|
||||||
|
|
||||||
final LoanTransactionEnumData transactionType = LoanEnumerations.transactionType(LoanTransactionType.WAIVE_INTEREST);
|
final LoanTransactionEnumData transactionType = LoanEnumerations.transactionType(LoanTransactionType.WAIVE_INTEREST);
|
||||||
|
|
||||||
|
|||||||
+24
-35
@@ -448,7 +448,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
existingTransactionIds.addAll(loan.findExistingTransactionIds());
|
existingTransactionIds.addAll(loan.findExistingTransactionIds());
|
||||||
existingReversedTransactionIds.addAll(loan.findExistingReversedTransactionIds());
|
existingReversedTransactionIds.addAll(loan.findExistingReversedTransactionIds());
|
||||||
LoanTransaction disbursementTransaction = LoanTransaction.disbursement(loan.getOffice(), amountToDisburse, paymentDetail,
|
LoanTransaction disbursementTransaction = LoanTransaction.disbursement(loan.getOffice(), amountToDisburse, paymentDetail,
|
||||||
actualDisbursementDate, txnExternalId, DateUtils.getLocalDateTimeOfTenant(), currentUser);
|
actualDisbursementDate, txnExternalId);
|
||||||
disbursementTransaction.updateLoan(loan);
|
disbursementTransaction.updateLoan(loan);
|
||||||
loan.addLoanTransaction(disbursementTransaction);
|
loan.addLoanTransaction(disbursementTransaction);
|
||||||
}
|
}
|
||||||
@@ -713,7 +713,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
existingTransactionIds.addAll(loan.findExistingTransactionIds());
|
existingTransactionIds.addAll(loan.findExistingTransactionIds());
|
||||||
existingReversedTransactionIds.addAll(loan.findExistingReversedTransactionIds());
|
existingReversedTransactionIds.addAll(loan.findExistingReversedTransactionIds());
|
||||||
LoanTransaction disbursementTransaction = LoanTransaction.disbursement(loan.getOffice(), disburseAmount, paymentDetail,
|
LoanTransaction disbursementTransaction = LoanTransaction.disbursement(loan.getOffice(), disburseAmount, paymentDetail,
|
||||||
actualDisbursementDate, txnExternalId, DateUtils.getLocalDateTimeOfTenant(), currentUser);
|
actualDisbursementDate, txnExternalId);
|
||||||
disbursementTransaction.updateLoan(loan);
|
disbursementTransaction.updateLoan(loan);
|
||||||
loan.addLoanTransaction(disbursementTransaction);
|
loan.addLoanTransaction(disbursementTransaction);
|
||||||
}
|
}
|
||||||
@@ -826,8 +826,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
// Remove post dated checks if added.
|
// Remove post dated checks if added.
|
||||||
loan.removePostDatedChecks();
|
loan.removePostDatedChecks();
|
||||||
|
|
||||||
final Map<String, Object> changes = loan.undoDisbursal(scheduleGeneratorDTO, existingTransactionIds, existingReversedTransactionIds,
|
final Map<String, Object> changes = loan.undoDisbursal(scheduleGeneratorDTO, existingTransactionIds,
|
||||||
currentUser);
|
existingReversedTransactionIds);
|
||||||
|
|
||||||
if (!changes.isEmpty()) {
|
if (!changes.isEmpty()) {
|
||||||
if (loan.isTopup() && loan.getClientId() != null) {
|
if (loan.isTopup() && loan.getClientId() != null) {
|
||||||
@@ -1050,7 +1050,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
final Money transactionAmountAsMoney = Money.of(loan.getCurrency(), transactionAmount);
|
final Money transactionAmountAsMoney = Money.of(loan.getCurrency(), transactionAmount);
|
||||||
final PaymentDetail paymentDetail = this.paymentDetailWritePlatformService.createPaymentDetail(command, changes);
|
final PaymentDetail paymentDetail = this.paymentDetailWritePlatformService.createPaymentDetail(command, changes);
|
||||||
LoanTransaction newTransactionDetail = LoanTransaction.repayment(loan.getOffice(), transactionAmountAsMoney, paymentDetail,
|
LoanTransaction newTransactionDetail = LoanTransaction.repayment(loan.getOffice(), transactionAmountAsMoney, paymentDetail,
|
||||||
transactionDate, txnExternalId, DateUtils.getLocalDateTimeOfTenant(), currentUser);
|
transactionDate, txnExternalId);
|
||||||
if (transactionToAdjust.isInterestWaiver()) {
|
if (transactionToAdjust.isInterestWaiver()) {
|
||||||
Money unrecognizedIncome = transactionAmountAsMoney.zero();
|
Money unrecognizedIncome = transactionAmountAsMoney.zero();
|
||||||
Money interestComponent = transactionAmountAsMoney;
|
Money interestComponent = transactionAmountAsMoney;
|
||||||
@@ -1062,7 +1062,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
newTransactionDetail = LoanTransaction.waiver(loan.getOffice(), loan, transactionAmountAsMoney, transactionDate,
|
newTransactionDetail = LoanTransaction.waiver(loan.getOffice(), loan, transactionAmountAsMoney, transactionDate,
|
||||||
interestComponent, unrecognizedIncome, DateUtils.getLocalDateTimeOfTenant(), currentUser);
|
interestComponent, unrecognizedIncome);
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalDate recalculateFrom = null;
|
LocalDate recalculateFrom = null;
|
||||||
@@ -1076,7 +1076,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
|
|
||||||
final ChangedTransactionDetail changedTransactionDetail = loan.adjustExistingTransaction(newTransactionDetail,
|
final ChangedTransactionDetail changedTransactionDetail = loan.adjustExistingTransaction(newTransactionDetail,
|
||||||
defaultLoanLifecycleStateMachine(), transactionToAdjust, existingTransactionIds, existingReversedTransactionIds,
|
defaultLoanLifecycleStateMachine(), transactionToAdjust, existingTransactionIds, existingReversedTransactionIds,
|
||||||
scheduleGeneratorDTO, currentUser);
|
scheduleGeneratorDTO);
|
||||||
|
|
||||||
if (newTransactionDetail.isGreaterThanZero(loan.getPrincpal().getCurrency())) {
|
if (newTransactionDetail.isGreaterThanZero(loan.getPrincpal().getCurrency())) {
|
||||||
if (paymentDetail != null) {
|
if (paymentDetail != null) {
|
||||||
@@ -1176,7 +1176,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
final LoanTransaction waiveInterestTransaction = LoanTransaction.waiver(loan.getOffice(), loan, transactionAmountAsMoney,
|
final LoanTransaction waiveInterestTransaction = LoanTransaction.waiver(loan.getOffice(), loan, transactionAmountAsMoney,
|
||||||
transactionDate, interestComponent, unrecognizedIncome, DateUtils.getLocalDateTimeOfTenant(), currentUser);
|
transactionDate, interestComponent, unrecognizedIncome);
|
||||||
businessEventNotifierService.notifyPreBusinessEvent(new LoanWaiveInterestBusinessEvent(waiveInterestTransaction));
|
businessEventNotifierService.notifyPreBusinessEvent(new LoanWaiveInterestBusinessEvent(waiveInterestTransaction));
|
||||||
LocalDate recalculateFrom = null;
|
LocalDate recalculateFrom = null;
|
||||||
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
||||||
@@ -1185,8 +1185,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
|
|
||||||
ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
||||||
final ChangedTransactionDetail changedTransactionDetail = loan.waiveInterest(waiveInterestTransaction,
|
final ChangedTransactionDetail changedTransactionDetail = loan.waiveInterest(waiveInterestTransaction,
|
||||||
defaultLoanLifecycleStateMachine(), existingTransactionIds, existingReversedTransactionIds, scheduleGeneratorDTO,
|
defaultLoanLifecycleStateMachine(), existingTransactionIds, existingReversedTransactionIds, scheduleGeneratorDTO);
|
||||||
currentUser);
|
|
||||||
|
|
||||||
this.loanTransactionRepository.saveAndFlush(waiveInterestTransaction);
|
this.loanTransactionRepository.saveAndFlush(waiveInterestTransaction);
|
||||||
|
|
||||||
@@ -1312,7 +1311,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
|
|
||||||
ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
||||||
ChangedTransactionDetail changedTransactionDetail = loan.close(command, defaultLoanLifecycleStateMachine(), changes,
|
ChangedTransactionDetail changedTransactionDetail = loan.close(command, defaultLoanLifecycleStateMachine(), changes,
|
||||||
existingTransactionIds, existingReversedTransactionIds, scheduleGeneratorDTO, currentUser);
|
existingTransactionIds, existingReversedTransactionIds, scheduleGeneratorDTO);
|
||||||
final LoanTransaction possibleClosingTransaction = changedTransactionDetail.getNewTransactionMappings().remove(0L);
|
final LoanTransaction possibleClosingTransaction = changedTransactionDetail.getNewTransactionMappings().remove(0L);
|
||||||
if (possibleClosingTransaction != null) {
|
if (possibleClosingTransaction != null) {
|
||||||
this.loanTransactionRepository.saveAndFlush(possibleClosingTransaction);
|
this.loanTransactionRepository.saveAndFlush(possibleClosingTransaction);
|
||||||
@@ -1561,11 +1560,10 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void runScheduleRecalculation(final Loan loan, final LocalDate recalculateFrom) {
|
public void runScheduleRecalculation(final Loan loan, final LocalDate recalculateFrom) {
|
||||||
AppUser currentUser = getAppUserIfPresent();
|
|
||||||
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
||||||
ScheduleGeneratorDTO generatorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
ScheduleGeneratorDTO generatorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
||||||
ChangedTransactionDetail changedTransactionDetail = loan
|
ChangedTransactionDetail changedTransactionDetail = loan
|
||||||
.handleRegenerateRepaymentScheduleWithInterestRecalculation(generatorDTO, currentUser);
|
.handleRegenerateRepaymentScheduleWithInterestRecalculation(generatorDTO);
|
||||||
saveLoanWithDataIntegrityViolationChecks(loan);
|
saveLoanWithDataIntegrityViolationChecks(loan);
|
||||||
if (changedTransactionDetail != null) {
|
if (changedTransactionDetail != null) {
|
||||||
for (final Map.Entry<Long, LoanTransaction> mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) {
|
for (final Map.Entry<Long, LoanTransaction> mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) {
|
||||||
@@ -1615,7 +1613,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
* the loan product uses Upfront Accruals
|
* the loan product uses Upfront Accruals
|
||||||
**/
|
**/
|
||||||
if (loan.status().isActive() && loan.isNoneOrCashOrUpfrontAccrualAccountingEnabledOnLoanProduct()) {
|
if (loan.status().isActive() && loan.isNoneOrCashOrUpfrontAccrualAccountingEnabledOnLoanProduct()) {
|
||||||
final LoanTransaction applyLoanChargeTransaction = loan.handleChargeAppliedTransaction(loanCharge, null, currentUser);
|
final LoanTransaction applyLoanChargeTransaction = loan.handleChargeAppliedTransaction(loanCharge, null);
|
||||||
this.loanTransactionRepository.saveAndFlush(applyLoanChargeTransaction);
|
this.loanTransactionRepository.saveAndFlush(applyLoanChargeTransaction);
|
||||||
}
|
}
|
||||||
boolean isAppliedOnBackDate = false;
|
boolean isAppliedOnBackDate = false;
|
||||||
@@ -1868,8 +1866,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
}
|
}
|
||||||
|
|
||||||
final LoanTransaction waiveTransaction = loan.waiveLoanCharge(loanCharge, defaultLoanLifecycleStateMachine(), changes,
|
final LoanTransaction waiveTransaction = loan.waiveLoanCharge(loanCharge, defaultLoanLifecycleStateMachine(), changes,
|
||||||
existingTransactionIds, existingReversedTransactionIds, loanInstallmentNumber, scheduleGeneratorDTO, accruedCharge,
|
existingTransactionIds, existingReversedTransactionIds, loanInstallmentNumber, scheduleGeneratorDTO, accruedCharge);
|
||||||
currentUser);
|
|
||||||
|
|
||||||
this.loanTransactionRepository.saveAndFlush(waiveTransaction);
|
this.loanTransactionRepository.saveAndFlush(waiveTransaction);
|
||||||
saveLoanWithDataIntegrityViolationChecks(loan);
|
saveLoanWithDataIntegrityViolationChecks(loan);
|
||||||
@@ -2113,7 +2110,6 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
@Override
|
@Override
|
||||||
public LoanTransaction initiateLoanTransfer(final Loan loan, final LocalDate transferDate) {
|
public LoanTransaction initiateLoanTransfer(final Loan loan, final LocalDate transferDate) {
|
||||||
|
|
||||||
AppUser currentUser = getAppUserIfPresent();
|
|
||||||
this.loanAssembler.setHelpers(loan);
|
this.loanAssembler.setHelpers(loan);
|
||||||
checkClientOrGroupActive(loan);
|
checkClientOrGroupActive(loan);
|
||||||
validateTransactionsForTransfer(loan, transferDate);
|
validateTransactionsForTransfer(loan, transferDate);
|
||||||
@@ -2123,8 +2119,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
final List<Long> existingTransactionIds = new ArrayList<>(loan.findExistingTransactionIds());
|
final List<Long> existingTransactionIds = new ArrayList<>(loan.findExistingTransactionIds());
|
||||||
final List<Long> existingReversedTransactionIds = new ArrayList<>(loan.findExistingReversedTransactionIds());
|
final List<Long> existingReversedTransactionIds = new ArrayList<>(loan.findExistingReversedTransactionIds());
|
||||||
|
|
||||||
final LoanTransaction newTransferTransaction = LoanTransaction.initiateTransfer(loan.getOffice(), loan, transferDate,
|
final LoanTransaction newTransferTransaction = LoanTransaction.initiateTransfer(loan.getOffice(), loan, transferDate);
|
||||||
DateUtils.getLocalDateTimeOfTenant(), currentUser);
|
|
||||||
loan.addLoanTransaction(newTransferTransaction);
|
loan.addLoanTransaction(newTransferTransaction);
|
||||||
loan.setLoanStatus(LoanStatus.TRANSFER_IN_PROGRESS.getValue());
|
loan.setLoanStatus(LoanStatus.TRANSFER_IN_PROGRESS.getValue());
|
||||||
|
|
||||||
@@ -2140,14 +2135,12 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
@Override
|
@Override
|
||||||
public LoanTransaction acceptLoanTransfer(final Loan loan, final LocalDate transferDate, final Office acceptedInOffice,
|
public LoanTransaction acceptLoanTransfer(final Loan loan, final LocalDate transferDate, final Office acceptedInOffice,
|
||||||
final Staff loanOfficer) {
|
final Staff loanOfficer) {
|
||||||
AppUser currentUser = getAppUserIfPresent();
|
|
||||||
this.loanAssembler.setHelpers(loan);
|
this.loanAssembler.setHelpers(loan);
|
||||||
businessEventNotifierService.notifyPreBusinessEvent(new LoanAcceptTransferBusinessEvent(loan));
|
businessEventNotifierService.notifyPreBusinessEvent(new LoanAcceptTransferBusinessEvent(loan));
|
||||||
final List<Long> existingTransactionIds = new ArrayList<>(loan.findExistingTransactionIds());
|
final List<Long> existingTransactionIds = new ArrayList<>(loan.findExistingTransactionIds());
|
||||||
final List<Long> existingReversedTransactionIds = new ArrayList<>(loan.findExistingReversedTransactionIds());
|
final List<Long> existingReversedTransactionIds = new ArrayList<>(loan.findExistingReversedTransactionIds());
|
||||||
|
|
||||||
final LoanTransaction newTransferAcceptanceTransaction = LoanTransaction.approveTransfer(acceptedInOffice, loan, transferDate,
|
final LoanTransaction newTransferAcceptanceTransaction = LoanTransaction.approveTransfer(acceptedInOffice, loan, transferDate);
|
||||||
DateUtils.getLocalDateTimeOfTenant(), currentUser);
|
|
||||||
loan.addLoanTransaction(newTransferAcceptanceTransaction);
|
loan.addLoanTransaction(newTransferAcceptanceTransaction);
|
||||||
if (loan.getTotalOverpaid() != null) {
|
if (loan.getTotalOverpaid() != null) {
|
||||||
loan.setLoanStatus(LoanStatus.OVERPAID.getValue());
|
loan.setLoanStatus(LoanStatus.OVERPAID.getValue());
|
||||||
@@ -2170,15 +2163,13 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
@Transactional
|
@Transactional
|
||||||
@Override
|
@Override
|
||||||
public LoanTransaction withdrawLoanTransfer(final Loan loan, final LocalDate transferDate) {
|
public LoanTransaction withdrawLoanTransfer(final Loan loan, final LocalDate transferDate) {
|
||||||
AppUser currentUser = getAppUserIfPresent();
|
|
||||||
this.loanAssembler.setHelpers(loan);
|
this.loanAssembler.setHelpers(loan);
|
||||||
businessEventNotifierService.notifyPreBusinessEvent(new LoanWithdrawTransferBusinessEvent(loan));
|
businessEventNotifierService.notifyPreBusinessEvent(new LoanWithdrawTransferBusinessEvent(loan));
|
||||||
|
|
||||||
final List<Long> existingTransactionIds = new ArrayList<>(loan.findExistingTransactionIds());
|
final List<Long> existingTransactionIds = new ArrayList<>(loan.findExistingTransactionIds());
|
||||||
final List<Long> existingReversedTransactionIds = new ArrayList<>(loan.findExistingReversedTransactionIds());
|
final List<Long> existingReversedTransactionIds = new ArrayList<>(loan.findExistingReversedTransactionIds());
|
||||||
|
|
||||||
final LoanTransaction newTransferAcceptanceTransaction = LoanTransaction.withdrawTransfer(loan.getOffice(), loan, transferDate,
|
final LoanTransaction newTransferAcceptanceTransaction = LoanTransaction.withdrawTransfer(loan.getOffice(), loan, transferDate);
|
||||||
DateUtils.getLocalDateTimeOfTenant(), currentUser);
|
|
||||||
loan.addLoanTransaction(newTransferAcceptanceTransaction);
|
loan.addLoanTransaction(newTransferAcceptanceTransaction);
|
||||||
loan.setLoanStatus(LoanStatus.ACTIVE.getValue());
|
loan.setLoanStatus(LoanStatus.ACTIVE.getValue());
|
||||||
|
|
||||||
@@ -2375,7 +2366,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
ScheduleGeneratorDTO scheduleGeneratorDTO = loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
ScheduleGeneratorDTO scheduleGeneratorDTO = loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
||||||
loan.setHelpers(null, this.loanSummaryWrapper, this.transactionProcessingStrategy);
|
loan.setHelpers(null, this.loanSummaryWrapper, this.transactionProcessingStrategy);
|
||||||
loan.recalculateScheduleFromLastTransaction(scheduleGeneratorDTO, existingTransactionIds,
|
loan.recalculateScheduleFromLastTransaction(scheduleGeneratorDTO, existingTransactionIds,
|
||||||
existingReversedTransactionIds, currentUser);
|
existingReversedTransactionIds);
|
||||||
createAndSaveLoanScheduleArchive(loan, scheduleGeneratorDTO);
|
createAndSaveLoanScheduleArchive(loan, scheduleGeneratorDTO);
|
||||||
} else if (reschedulebasedOnMeetingDates != null && reschedulebasedOnMeetingDates) {
|
} else if (reschedulebasedOnMeetingDates != null && reschedulebasedOnMeetingDates) {
|
||||||
loan.updateLoanRepaymentScheduleDates(calendar.getStartDateLocalDate(), calendar.getRecurrence(), isHolidayEnabled,
|
loan.updateLoanRepaymentScheduleDates(calendar.getStartDateLocalDate(), calendar.getRecurrence(), isHolidayEnabled,
|
||||||
@@ -2786,7 +2777,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
||||||
|
|
||||||
ChangedTransactionDetail changedTransactionDetail = loan.undoWrittenOff(existingTransactionIds, existingReversedTransactionIds,
|
ChangedTransactionDetail changedTransactionDetail = loan.undoWrittenOff(existingTransactionIds, existingReversedTransactionIds,
|
||||||
scheduleGeneratorDTO, currentUser);
|
scheduleGeneratorDTO);
|
||||||
if (changedTransactionDetail != null) {
|
if (changedTransactionDetail != null) {
|
||||||
for (final Map.Entry<Long, LoanTransaction> mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) {
|
for (final Map.Entry<Long, LoanTransaction> mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) {
|
||||||
this.loanTransactionRepository.save(mapEntry.getValue());
|
this.loanTransactionRepository.save(mapEntry.getValue());
|
||||||
@@ -2914,7 +2905,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
if (command.entityId() != null) {
|
if (command.entityId() != null) {
|
||||||
|
|
||||||
changedTransactionDetail = loan.updateDisbursementDateAndAmountForTranche(loanDisbursementDetails, command, changes,
|
changedTransactionDetail = loan.updateDisbursementDateAndAmountForTranche(loanDisbursementDetails, command, changes,
|
||||||
scheduleGeneratorDTO, currentUser);
|
scheduleGeneratorDTO);
|
||||||
} else {
|
} else {
|
||||||
// BigDecimal setAmount = loan.getApprovedPrincipal();
|
// BigDecimal setAmount = loan.getApprovedPrincipal();
|
||||||
Collection<LoanDisbursementDetails> loanDisburseDetails = loan.getDisbursementDetails();
|
Collection<LoanDisbursementDetails> loanDisburseDetails = loan.getDisbursementDetails();
|
||||||
@@ -2928,9 +2919,9 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
loan.repaymentScheduleDetail().setPrincipal(setAmount);
|
loan.repaymentScheduleDetail().setPrincipal(setAmount);
|
||||||
|
|
||||||
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) {
|
||||||
loan.regenerateRepaymentScheduleWithInterestRecalculation(scheduleGeneratorDTO, currentUser);
|
loan.regenerateRepaymentScheduleWithInterestRecalculation(scheduleGeneratorDTO);
|
||||||
} else {
|
} else {
|
||||||
loan.regenerateRepaymentSchedule(scheduleGeneratorDTO, currentUser);
|
loan.regenerateRepaymentSchedule(scheduleGeneratorDTO);
|
||||||
loan.processPostDisbursementTransactions();
|
loan.processPostDisbursementTransactions();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3049,7 +3040,6 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
public void recalculateInterest(final long loanId) {
|
public void recalculateInterest(final long loanId) {
|
||||||
Loan loan = this.loanAssembler.assembleFrom(loanId);
|
Loan loan = this.loanAssembler.assembleFrom(loanId);
|
||||||
LocalDate recalculateFrom = loan.fetchInterestRecalculateFromDate();
|
LocalDate recalculateFrom = loan.fetchInterestRecalculateFromDate();
|
||||||
AppUser currentUser = getAppUserIfPresent();
|
|
||||||
businessEventNotifierService.notifyPreBusinessEvent(new LoanInterestRecalculationBusinessEvent(loan));
|
businessEventNotifierService.notifyPreBusinessEvent(new LoanInterestRecalculationBusinessEvent(loan));
|
||||||
final List<Long> existingTransactionIds = new ArrayList<>();
|
final List<Long> existingTransactionIds = new ArrayList<>();
|
||||||
final List<Long> existingReversedTransactionIds = new ArrayList<>();
|
final List<Long> existingReversedTransactionIds = new ArrayList<>();
|
||||||
@@ -3057,7 +3047,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
ScheduleGeneratorDTO generatorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
ScheduleGeneratorDTO generatorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom);
|
||||||
|
|
||||||
ChangedTransactionDetail changedTransactionDetail = loan.recalculateScheduleFromLastTransaction(generatorDTO,
|
ChangedTransactionDetail changedTransactionDetail = loan.recalculateScheduleFromLastTransaction(generatorDTO,
|
||||||
existingTransactionIds, existingReversedTransactionIds, currentUser);
|
existingTransactionIds, existingReversedTransactionIds);
|
||||||
|
|
||||||
saveLoanWithDataIntegrityViolationChecks(loan);
|
saveLoanWithDataIntegrityViolationChecks(loan);
|
||||||
|
|
||||||
@@ -3101,7 +3091,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
AppUser currentUser = getAppUserIfPresent();
|
AppUser currentUser = getAppUserIfPresent();
|
||||||
final LocalDate actualDisbursementDate = command.localDateValueOfParameterNamed("actualDisbursementDate");
|
final LocalDate actualDisbursementDate = command.localDateValueOfParameterNamed("actualDisbursementDate");
|
||||||
BigDecimal emiAmount = command.bigDecimalValueOfParameterNamed(LoanApiConstants.emiAmountParameterName);
|
BigDecimal emiAmount = command.bigDecimalValueOfParameterNamed(LoanApiConstants.emiAmountParameterName);
|
||||||
loan.regenerateScheduleOnDisbursement(scheduleGeneratorDTO, recalculateSchedule, actualDisbursementDate, emiAmount, currentUser,
|
loan.regenerateScheduleOnDisbursement(scheduleGeneratorDTO, recalculateSchedule, actualDisbursementDate, emiAmount,
|
||||||
nextPossibleRepaymentDate, rescheduledRepaymentDate);
|
nextPossibleRepaymentDate, rescheduledRepaymentDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3213,7 +3203,6 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public CommandProcessingResult undoLastLoanDisbursal(Long loanId, JsonCommand command) {
|
public CommandProcessingResult undoLastLoanDisbursal(Long loanId, JsonCommand command) {
|
||||||
final AppUser currentUser = getAppUserIfPresent();
|
|
||||||
|
|
||||||
final Loan loan = this.loanAssembler.assembleFrom(loanId);
|
final Loan loan = this.loanAssembler.assembleFrom(loanId);
|
||||||
final LocalDate recalculateFromDate = loan.getLastRepaymentDate();
|
final LocalDate recalculateFromDate = loan.getLastRepaymentDate();
|
||||||
@@ -3229,7 +3218,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFromDate);
|
ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFromDate);
|
||||||
|
|
||||||
final Map<String, Object> changes = loan.undoLastDisbursal(scheduleGeneratorDTO, existingTransactionIds,
|
final Map<String, Object> changes = loan.undoLastDisbursal(scheduleGeneratorDTO, existingTransactionIds,
|
||||||
existingReversedTransactionIds, currentUser, loan);
|
existingReversedTransactionIds, loan);
|
||||||
if (!changes.isEmpty()) {
|
if (!changes.isEmpty()) {
|
||||||
saveAndFlushLoanWithDataIntegrityViolationChecks(loan);
|
saveAndFlushLoanWithDataIntegrityViolationChecks(loan);
|
||||||
String noteText = null;
|
String noteText = null;
|
||||||
|
|||||||
@@ -38,4 +38,5 @@
|
|||||||
<include file="parts/0016_changed_unique_constraint_of_ref_no.xml" relativeToChangelogFile="true"/>
|
<include file="parts/0016_changed_unique_constraint_of_ref_no.xml" relativeToChangelogFile="true"/>
|
||||||
<include file="parts/0017_fix_stretchy_reports.xml" relativeToChangelogFile="true"/>
|
<include file="parts/0017_fix_stretchy_reports.xml" relativeToChangelogFile="true"/>
|
||||||
<include file="parts/0018_pentaho_reports_to_table.xml" relativeToChangelogFile="true"/>
|
<include file="parts/0018_pentaho_reports_to_table.xml" relativeToChangelogFile="true"/>
|
||||||
|
<include file="parts/0019_refactor_loan_transaction.xml" relativeToChangelogFile="true"/>
|
||||||
</databaseChangeLog>
|
</databaseChangeLog>
|
||||||
|
|||||||
+59
@@ -0,0 +1,59 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
or more contributor license agreements. See the NOTICE file
|
||||||
|
distributed with this work for additional information
|
||||||
|
regarding copyright ownership. The ASF licenses this file
|
||||||
|
to you under the Apache License, Version 2.0 (the
|
||||||
|
"License"); you may not use this file except in compliance
|
||||||
|
with the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing,
|
||||||
|
software distributed under the License is distributed on an
|
||||||
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
KIND, either express or implied. See the License for the
|
||||||
|
specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
|
||||||
|
-->
|
||||||
|
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||||
|
<changeSet author="fineract" id="1">
|
||||||
|
<addColumn tableName="m_loan_transaction">
|
||||||
|
<column name="createdby_id" type="BIGINT" valueComputed="appuser_id"/>
|
||||||
|
<column name="lastmodifiedby_id" type="BIGINT" valueComputed="appuser_id"/>
|
||||||
|
<column name="lastmodified_date" type="DATETIME" valueComputed="created_date"/>
|
||||||
|
</addColumn>
|
||||||
|
</changeSet>
|
||||||
|
<changeSet id="2" author="fineract">
|
||||||
|
<dropColumn tableName="m_loan_transaction">
|
||||||
|
<column name="appuser_id"/>
|
||||||
|
</dropColumn>
|
||||||
|
</changeSet>
|
||||||
|
<changeSet author="fineract" id="3" context="postgresql">
|
||||||
|
<update tableName="stretchy_report">
|
||||||
|
<column name="report_sql" value="SELECT mc.id AS id, mc.firstname AS firstName, mc.middlename AS middleName, mc.lastname AS lastName, mc.display_name AS fullName, mc.mobile_no AS mobileNo, ml.principal_amount AS loanAmount, (COALESCE(ml.principal_outstanding_derived, 0) + COALESCE(ml.interest_outstanding_derived, 0) + COALESCE(ml.fee_charges_outstanding_derived, 0) + COALESCE(ml.penalty_charges_outstanding_derived, 0)) AS loanOutstanding, ounder.id AS officeNumber, ml.account_no AS loanAccountNumber, SUM(lt.amount) AS repaymentAmount FROM m_office mo JOIN m_office ounder ON ounder.hierarchy LIKE CONCAT(mo.hierarchy, '%') INNER JOIN m_client mc ON mc.office_id = ounder.id INNER JOIN m_loan ml ON ml.client_id = mc.id INNER JOIN r_enum_value rev ON rev.enum_id = ml.loan_status_id AND rev.enum_name = 'loan_status_id' INNER JOIN m_loan_transaction lt ON lt.loan_id = ml.id INNER JOIN m_appuser au ON au.id = lt.createdby_id LEFT JOIN m_loan_arrears_aging laa ON laa.loan_id = ml.id LEFT JOIN m_payment_detail mpd ON mpd.id = lt.payment_detail_id LEFT JOIN m_currency cur ON cur.code = ml.currency_code LEFT JOIN m_group_client gc ON gc.client_id = mc.id LEFT JOIN m_group g ON g.id = gc.group_id LEFT JOIN m_staff lo ON lo.id = ml.loan_officer_id LEFT JOIN m_guarantor gua ON gua.loan_id = ml.id WHERE ml.loan_status_id = 300 AND mo.id = '${officeId}' AND (COALESCE(ml.loan_officer_id, -10) = ${loanOfficerId} OR '-1' = ${loanOfficerId}) AND (EXTRACT(DAY FROM (CURRENT_DATE - lt.transaction_date::TIMESTAMP)) BETWEEN 9${fromX} AND ${toY}) AND lt.is_reversed = false AND lt.transaction_type_enum = 2 AND laa.loan_id IS NULL GROUP BY ml.id, mc.id, ounder.id ORDER BY ounder.hierarchy, ml.currency_code, mc.account_no, ml.account_no"/>
|
||||||
|
<where>id='174' AND report_name='Loan payments received (Active Loans)'</where>
|
||||||
|
</update>
|
||||||
|
<update tableName="stretchy_report">
|
||||||
|
<column name="report_sql" value="SELECT ml.id AS loanId, mc.id AS id, mc.firstname AS firstName, mc.middlename AS middleName, mc.lastname AS lastName, mc.display_name AS fullName, mc.mobile_no AS mobileNo, ml.principal_amount AS loanAmount, (COALESCE(ml.principal_outstanding_derived, 0) + COALESCE(ml.interest_outstanding_derived, 0) + COALESCE(ml.fee_charges_outstanding_derived, 0) + COALESCE(ml.penalty_charges_outstanding_derived, 0)) AS loanOutstanding, ounder.id AS officeNumber, ml.account_no AS loanAccountNumber, SUM(lt.amount) AS repaymentAmount FROM m_office mo JOIN m_office ounder ON ounder.hierarchy LIKE CONCAT(mo.hierarchy, '%') INNER JOIN m_client mc ON mc.office_id = ounder.id INNER JOIN m_loan ml ON ml.client_id = mc.id INNER JOIN r_enum_value rev ON rev.enum_id = ml.loan_status_id AND rev.enum_name = 'loan_status_id' INNER JOIN m_loan_arrears_aging laa ON laa.loan_id = ml.id INNER JOIN m_loan_transaction lt ON lt.loan_id = ml.id INNER JOIN m_appuser au ON au.id = lt.createdby_id LEFT JOIN m_payment_detail mpd ON mpd.id = lt.payment_detail_id LEFT JOIN m_currency cur ON cur.code = ml.currency_code LEFT JOIN m_group_client gc ON gc.client_id = mc.id LEFT JOIN m_group g ON g.id = gc.group_id LEFT JOIN m_staff lo ON lo.id = ml.loan_officer_id LEFT JOIN m_guarantor gua ON gua.loan_id = ml.id WHERE ml.loan_status_id = 300 AND mo.id = '${officeId}' AND (COALESCE(ml.loan_officer_id, -10) = ${loanOfficerId} OR '-1' = ${loanOfficerId}) AND (EXTRACT(DAY FROM(CURRENT_DATE - lt.transaction_date::TIMESTAMP)) BETWEEN ${fromX} AND ${toY}) AND (EXTRACT(DAY FROM(CURRENT_DATE - laa.overdue_since_date_derived::TIMESTAMP)) BETWEEN ${overdueX} AND ${overdueY}) AND lt.is_reversed = false AND lt.transaction_type_enum = 2 GROUP BY ml.id, mc.id, ounder.id ORDER BY ounder.hierarchy, ml.currency_code, mc.account_no, ml.account_no"/>
|
||||||
|
<where>id='175' AND report_name='Loan payments received (Overdue Loans)'</where>
|
||||||
|
</update>
|
||||||
|
</changeSet>
|
||||||
|
<changeSet author="fineract" id="4" context="mysql">
|
||||||
|
<update tableName="stretchy_report">
|
||||||
|
<column name="report_sql"
|
||||||
|
value="SELECT mc.id AS "id", mc.firstname AS "firstName", mc.middlename AS "middleName", mc.lastname AS "lastName", mc.display_name AS "fullName", mc.mobile_no AS "mobileNo", ml.principal_amount AS "loanAmount", (IFNULL(ml.principal_outstanding_derived, 0) + IFNULL(ml.interest_outstanding_derived, 0) + IFNULL(ml.fee_charges_outstanding_derived, 0) + IFNULL(ml.penalty_charges_outstanding_derived, 0)) AS "loanOutstanding", ounder.id AS "officeNumber", ml.account_no AS "loanAccountNumber", SUM(lt.amount) AS "repaymentAmount" FROM m_office mo JOIN m_office ounder ON ounder.hierarchy LIKE CONCAT(mo.hierarchy, '%') INNER JOIN m_client mc ON mc.office_id=ounder.id INNER JOIN m_loan ml ON ml.client_id = mc.id INNER JOIN r_enum_value rev ON rev.enum_id=ml.loan_status_id AND rev.enum_name = 'loan_status_id' INNER JOIN m_loan_transaction lt ON lt.loan_id = ml.id INNER JOIN m_appuser au ON au.id = lt.createdby_id LEFT JOIN m_loan_arrears_aging laa ON laa.loan_id=ml.id LEFT JOIN m_payment_detail mpd ON mpd.id=lt.payment_detail_id LEFT JOIN m_currency cur ON cur.code = ml.currency_code LEFT JOIN m_group_client gc ON gc.client_id = mc.id LEFT JOIN m_group g ON g.id = gc.group_id LEFT JOIN m_staff lo ON lo.id = ml.loan_officer_id LEFT JOIN m_guarantor gua ON gua.loan_id = ml.id WHERE ml.loan_status_id=300 AND mo.id=${officeId} AND (IFNULL(ml.loan_officer_id, -10) = ${loanOfficerId} OR "-1" = ${loanOfficerId}) AND (DATEDIFF(CURDATE(), lt.transaction_date) BETWEEN ${fromX} AND ${toY}) AND lt.is_reversed=0 AND lt.transaction_type_enum=2 AND laa.loan_id IS NULL GROUP BY ml.id ORDER BY ounder.hierarchy, ml.currency_code, mc.account_no, ml.account_no"/>
|
||||||
|
<where>id='174' AND report_name='Loan payments received (Active Loans)'</where>
|
||||||
|
</update>
|
||||||
|
<update tableName="stretchy_report">
|
||||||
|
<column name="report_sql"
|
||||||
|
value="SELECT ml.id AS "loanId", mc.id AS "id", mc.firstname AS "firstName", mc.middlename AS "middleName", mc.lastname AS "lastName", mc.display_name AS "fullName", mc.mobile_no AS "mobileNo", ml.principal_amount AS "loanAmount", (IFNULL(ml.principal_outstanding_derived, 0) + IFNULL(ml.interest_outstanding_derived, 0) + IFNULL(ml.fee_charges_outstanding_derived, 0) + IFNULL(ml.penalty_charges_outstanding_derived, 0)) AS "loanOutstanding", ounder.id AS "officeNumber", ml.account_no AS "loanAccountNumber", SUM(lt.amount) AS "repaymentAmount" FROM m_office mo JOIN m_office ounder ON ounder.hierarchy LIKE CONCAT(mo.hierarchy, '%') INNER JOIN m_client mc ON mc.office_id=ounder.id INNER JOIN m_loan ml ON ml.client_id = mc.id INNER JOIN r_enum_value rev ON rev.enum_id=ml.loan_status_id AND rev.enum_name = 'loan_status_id' INNER JOIN m_loan_arrears_aging laa ON laa.loan_id=ml.id INNER JOIN m_loan_transaction lt ON lt.loan_id = ml.id INNER JOIN m_appuser au ON au.id = lt.createdby_id LEFT JOIN m_payment_detail mpd ON mpd.id=lt.payment_detail_id LEFT JOIN m_currency cur ON cur.code = ml.currency_code LEFT JOIN m_group_client gc ON gc.client_id = mc.id LEFT JOIN m_group g ON g.id = gc.group_id LEFT JOIN m_staff lo ON lo.id = ml.loan_officer_id LEFT JOIN m_guarantor gua ON gua.loan_id = ml.id WHERE ml.loan_status_id=300 AND mo.id=${officeId} AND (IFNULL(ml.loan_officer_id, -10) = ${loanOfficerId} OR "-1" = ${loanOfficerId}) AND (DATEDIFF(CURDATE(), lt.transaction_date) BETWEEN ${fromX} AND ${toY}) AND (DATEDIFF(CURDATE(), laa.overdue_since_date_derived) BETWEEN ${overdueX} AND ${overdueY}) AND lt.is_reversed=0 AND lt.transaction_type_enum=2 GROUP BY ml.id ORDER BY ounder.hierarchy, ml.currency_code, mc.account_no, ml.account_no"/>
|
||||||
|
<where>id='175' AND report_name='Loan payments received (Overdue Loans)'</where>
|
||||||
|
</update>
|
||||||
|
</changeSet>
|
||||||
|
</databaseChangeLog>
|
||||||
Reference in New Issue
Block a user