Merge pull request #1043 from pramodn02/develop
MIFOSX-1421 : corrected interest calculation for different interest comp...
This commit is contained in:
+24
-41
@@ -964,7 +964,6 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
}
|
||||
|
||||
public void updateLoanSchedule(final LoanScheduleModel modifiedLoanSchedule) {
|
||||
clearInstallmentLoanCharge();
|
||||
this.repaymentScheduleInstallments.clear();
|
||||
|
||||
for (final LoanScheduleModelPeriod scheduledLoanInstallment : modifiedLoanSchedule.getPeriods()) {
|
||||
@@ -984,14 +983,6 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
|
||||
}
|
||||
|
||||
private void clearInstallmentLoanCharge() {
|
||||
for (final LoanCharge loanCharge : charges()) {
|
||||
if (loanCharge.isInstalmentFee()) {
|
||||
loanCharge.clearLoanInstallmentCharges();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateLoanScheduleDependentDerivedFields() {
|
||||
this.expectedMaturityDate = determineExpectedMaturityDate().toDate();
|
||||
this.actualMaturityDate = determineExpectedMaturityDate().toDate();
|
||||
@@ -1203,14 +1194,8 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
final String chargesParamName = "charges";
|
||||
|
||||
if (isChargesModified) {
|
||||
actualChanges.put(chargesParamName, getLoanCharges(possiblyModifedLoanCharges));
|
||||
|
||||
actualChanges.put(chargesParamName, getLoanCharges(possiblyModifedLoanCharges));
|
||||
actualChanges.put("recalculateLoanSchedule", true);
|
||||
|
||||
for (final LoanCharge loanCharge : possiblyModifedLoanCharges) {
|
||||
recalculateLoanCharge(loanCharge);
|
||||
}
|
||||
}
|
||||
|
||||
final String collateralParamName = "collateral";
|
||||
@@ -1269,6 +1254,13 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
return actualChanges;
|
||||
}
|
||||
|
||||
public void recalculateAllCharges() {
|
||||
Set<LoanCharge> charges = this.charges();
|
||||
for (final LoanCharge loanCharge : charges) {
|
||||
recalculateLoanCharge(loanCharge);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isInterestRecalculationEnabledForProduct() {
|
||||
return this.loanProduct.isInterestRecalculationEnabled();
|
||||
}
|
||||
@@ -1723,12 +1715,12 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
return ids;
|
||||
}
|
||||
|
||||
public void disburse(final LoanScheduleGeneratorFactory loanScheduleFactory, final AppUser currentUser, final JsonCommand command,
|
||||
final ApplicationCurrency currency, final List<Long> existingTransactionIds, final List<Long> existingReversedTransactionIds,
|
||||
final Map<String, Object> actualChanges, final LocalDate calculatedRepaymentsStartingFromDate, final boolean isHolidayEnabled,
|
||||
final List<Holiday> holidays, final WorkingDays workingDays, final boolean allowTransactionsOnHoliday,
|
||||
final boolean allowTransactionsOnNonWorkingDay, final boolean recalculateSchedule,
|
||||
final CalendarInstance calendarInstanceForInterestRecalculation) {
|
||||
public ChangedTransactionDetail disburse(final LoanScheduleGeneratorFactory loanScheduleFactory, final AppUser currentUser,
|
||||
final JsonCommand command, final ApplicationCurrency currency, final List<Long> existingTransactionIds,
|
||||
final List<Long> existingReversedTransactionIds, final Map<String, Object> actualChanges,
|
||||
final LocalDate calculatedRepaymentsStartingFromDate, final boolean isHolidayEnabled, final List<Holiday> holidays,
|
||||
final WorkingDays workingDays, final boolean allowTransactionsOnHoliday, final boolean allowTransactionsOnNonWorkingDay,
|
||||
final boolean recalculateSchedule, final CalendarInstance calendarInstanceForInterestRecalculation) {
|
||||
|
||||
final LoanStatus statusEnum = this.loanLifecycleStateMachine.transition(LoanEvent.LOAN_DISBURSED,
|
||||
LoanStatus.fromInt(this.loanStatus));
|
||||
@@ -1763,13 +1755,7 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
if (isRepaymentScheduleRegenerationRequiredForDisbursement(actualDisbursementDate) || recalculateSchedule || isEmiAmountChanged) {
|
||||
regenerateRepaymentSchedule(loanScheduleFactory, currency, calculatedRepaymentsStartingFromDate, isHolidayEnabled, holidays,
|
||||
workingDays);
|
||||
if (recalculateSchedule) {
|
||||
Set<LoanCharge> charges = this.charges();
|
||||
for (LoanCharge loanCharge : charges) {
|
||||
recalculateLoanCharge(loanCharge);
|
||||
}
|
||||
updateSummaryWithTotalFeeChargesDueAtDisbursement(deriveSumTotalOfChargesDueAtDisbursement());
|
||||
}
|
||||
updateSummaryWithTotalFeeChargesDueAtDisbursement(deriveSumTotalOfChargesDueAtDisbursement());
|
||||
}
|
||||
if (this.repaymentScheduleDetail().isInterestRecalculationEnabled()
|
||||
&& fetchRepaymentScheduleInstallment(1).getDueDate().isBefore(LocalDate.now())) {
|
||||
@@ -1794,8 +1780,7 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
this.loanTransactions.add(interestAppliedTransaction);
|
||||
}
|
||||
|
||||
// changedTransactionDetail =
|
||||
// reprocessTransactionForDisbursement(changedTransactionDetail);
|
||||
return reprocessTransactionForDisbursement();
|
||||
|
||||
}
|
||||
|
||||
@@ -1860,14 +1845,8 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
return disburseAmount;
|
||||
}
|
||||
|
||||
public ChangedTransactionDetail reprocessTransactionForDisbursement() {
|
||||
private ChangedTransactionDetail reprocessTransactionForDisbursement() {
|
||||
ChangedTransactionDetail changedTransactionDetail = null;
|
||||
for (LoanCharge loanCharge : this.charges) {
|
||||
if (loanCharge.isInstalmentFee() && loanCharge.hasNoLoanInstallmentCharges()) {
|
||||
final Set<LoanInstallmentCharge> chargePerInstallments = generateInstallmentLoanCharges(loanCharge);
|
||||
loanCharge.addLoanInstallmentCharges(chargePerInstallments);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.loanProduct.isMultiDisburseLoan()) {
|
||||
if (!this.actualDisbursementDate.equals(fetchLastDisburseDetail().getDisbursementDate())) {
|
||||
@@ -2015,6 +1994,10 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
isHolidayEnabled, holidays, workingDays);
|
||||
|
||||
updateLoanSchedule(loanSchedule);
|
||||
Set<LoanCharge> charges = this.charges();
|
||||
for (LoanCharge loanCharge : charges) {
|
||||
recalculateLoanCharge(loanCharge);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleDisbursementTransaction(final LocalDate disbursedOn) {
|
||||
@@ -2146,10 +2129,6 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
regenerateRepaymentSchedule(loanScheduleFactory, applicationCurrency, calculatedRepaymentsStartingFromDate,
|
||||
isHolidayEnabled, holidays, workingDays);
|
||||
if (isDisbueseAmtChanged) {
|
||||
Set<LoanCharge> charges = charges();
|
||||
for (LoanCharge loanCharge : charges) {
|
||||
recalculateLoanCharge(loanCharge);
|
||||
}
|
||||
updateSummaryWithTotalFeeChargesDueAtDisbursement(deriveSumTotalOfChargesDueAtDisbursement());
|
||||
}
|
||||
}
|
||||
@@ -4149,4 +4128,8 @@ public class Loan extends AbstractPersistable<Long> {
|
||||
}
|
||||
return cumulativeOurstanding;
|
||||
}
|
||||
|
||||
public List<LoanRepaymentScheduleInstallment> fetchRepaymentScheduleInstallments() {
|
||||
return this.repaymentScheduleInstallments;
|
||||
}
|
||||
}
|
||||
+50
-34
@@ -67,6 +67,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
||||
private final LoanScheduleGeneratorFactory loanScheduleFactory;
|
||||
private final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepository;
|
||||
private final CalendarInstanceRepository calendarInstanceRepository;
|
||||
private final LoanRepaymentScheduleInstallmentRepository repaymentScheduleInstallmentRepository;
|
||||
|
||||
@Autowired
|
||||
public LoanAccountDomainServiceJpa(final LoanAssembler loanAccountAssembler, final LoanRepository loanRepository,
|
||||
@@ -77,7 +78,8 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
||||
final JournalEntryWritePlatformService journalEntryWritePlatformService,
|
||||
final AccountTransferRepository accountTransferRepository, final LoanScheduleGeneratorFactory loanScheduleFactory,
|
||||
final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepository,
|
||||
final CalendarInstanceRepository calendarInstanceRepository) {
|
||||
final CalendarInstanceRepository calendarInstanceRepository,
|
||||
final LoanRepaymentScheduleInstallmentRepository repaymentScheduleInstallmentRepository) {
|
||||
this.loanAccountAssembler = loanAccountAssembler;
|
||||
this.loanRepository = loanRepository;
|
||||
this.loanTransactionRepository = loanTransactionRepository;
|
||||
@@ -91,6 +93,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
||||
this.loanScheduleFactory = loanScheduleFactory;
|
||||
this.applicationCurrencyRepository = applicationCurrencyRepository;
|
||||
this.calendarInstanceRepository = calendarInstanceRepository;
|
||||
this.repaymentScheduleInstallmentRepository = repaymentScheduleInstallmentRepository;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@@ -156,19 +159,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
||||
holidays, workingDays, allowTransactionsOnNonWorkingDay, isHolidayEnabled, isRecoveryRepayment, this.loanScheduleFactory,
|
||||
applicationCurrency, calculatedRepaymentsStartingFromDate, restCalendarInstance);
|
||||
|
||||
try {
|
||||
this.loanTransactionRepository.save(newRepaymentTransaction);
|
||||
} catch (DataIntegrityViolationException e) {
|
||||
final Throwable realCause = e.getCause();
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("loan.transaction");
|
||||
if (realCause.getMessage().toLowerCase().contains("external_id_unique")) {
|
||||
baseDataValidator.reset().parameter("externalId").value(newRepaymentTransaction.getExternalId())
|
||||
.failWithCode("value.must.be.unique");
|
||||
}
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors); }
|
||||
}
|
||||
saveLoanTransactionWithDataIntegrityViolationChecks(newRepaymentTransaction);
|
||||
|
||||
/***
|
||||
* TODO Vishwas Batch save is giving me a
|
||||
@@ -178,11 +169,11 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
||||
* recorded against the loan)
|
||||
***/
|
||||
|
||||
this.loanRepository.saveAndFlush(loan);
|
||||
saveAndFlushLoanWithDataIntegrityViolationChecks(loan);
|
||||
|
||||
if (changedTransactionDetail != null) {
|
||||
for (Map.Entry<Long, LoanTransaction> mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) {
|
||||
this.loanTransactionRepository.save(mapEntry.getValue());
|
||||
saveLoanTransactionWithDataIntegrityViolationChecks(mapEntry.getValue());
|
||||
// update loan with references to the newly created transactions
|
||||
loan.getLoanTransactions().add(mapEntry.getValue());
|
||||
updateLoanTransaction(mapEntry.getKey(), mapEntry.getValue());
|
||||
@@ -204,6 +195,43 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
||||
return newRepaymentTransaction;
|
||||
}
|
||||
|
||||
private void saveLoanTransactionWithDataIntegrityViolationChecks(LoanTransaction newRepaymentTransaction) {
|
||||
try {
|
||||
this.loanTransactionRepository.save(newRepaymentTransaction);
|
||||
} catch (DataIntegrityViolationException e) {
|
||||
final Throwable realCause = e.getCause();
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("loan.transaction");
|
||||
if (realCause.getMessage().toLowerCase().contains("external_id_unique")) {
|
||||
baseDataValidator.reset().parameter("externalId").value(newRepaymentTransaction.getExternalId())
|
||||
.failWithCode("value.must.be.unique");
|
||||
}
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors); }
|
||||
}
|
||||
}
|
||||
|
||||
private void saveAndFlushLoanWithDataIntegrityViolationChecks(final Loan loan) {
|
||||
try {
|
||||
List<LoanRepaymentScheduleInstallment> installments = loan.fetchRepaymentScheduleInstallments();
|
||||
for (LoanRepaymentScheduleInstallment installment : installments) {
|
||||
if (installment.getId() == null) {
|
||||
this.repaymentScheduleInstallmentRepository.save(installment);
|
||||
}
|
||||
}
|
||||
this.loanRepository.saveAndFlush(loan);
|
||||
} catch (final DataIntegrityViolationException e) {
|
||||
final Throwable realCause = e.getCause();
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("loan.transaction");
|
||||
if (realCause.getMessage().toLowerCase().contains("external_id_unique")) {
|
||||
baseDataValidator.reset().parameter("externalId").failWithCode("value.must.be.unique");
|
||||
}
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors); }
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public LoanTransaction makeChargePayment(final Loan loan, final Long chargeId, final LocalDate transactionDate,
|
||||
@@ -233,8 +261,8 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
||||
allowTransactionsOnHoliday, holidays, workingDays, allowTransactionsOnNonWorkingDay, newPaymentTransaction,
|
||||
installmentNumber);
|
||||
}
|
||||
this.loanTransactionRepository.save(newPaymentTransaction);
|
||||
this.loanRepository.saveAndFlush(loan);
|
||||
saveLoanTransactionWithDataIntegrityViolationChecks(newPaymentTransaction);
|
||||
saveAndFlushLoanWithDataIntegrityViolationChecks(loan);
|
||||
|
||||
if (StringUtils.isNotBlank(noteText)) {
|
||||
final Note note = Note.loanTransactionNote(loan, newPaymentTransaction, noteText);
|
||||
@@ -295,7 +323,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
||||
loan.makeRefund(newRefundTransaction, defaultLoanLifecycleStateMachine(), existingTransactionIds, existingReversedTransactionIds,
|
||||
allowTransactionsOnHoliday, holidays, workingDays, allowTransactionsOnNonWorkingDay);
|
||||
|
||||
this.loanTransactionRepository.save(newRefundTransaction);
|
||||
saveLoanTransactionWithDataIntegrityViolationChecks(newRefundTransaction);
|
||||
this.loanRepository.save(loan);
|
||||
|
||||
if (StringUtils.isNotBlank(noteText)) {
|
||||
@@ -327,20 +355,8 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
||||
txnExternalId);
|
||||
disbursementTransaction.updateLoan(loan);
|
||||
loan.getLoanTransactions().add(disbursementTransaction);
|
||||
try {
|
||||
this.loanTransactionRepository.save(disbursementTransaction);
|
||||
} catch (DataIntegrityViolationException e) {
|
||||
final Throwable realCause = e.getCause();
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("loan.transaction");
|
||||
if (realCause.getMessage().toLowerCase().contains("external_id_unique")) {
|
||||
baseDataValidator.reset().parameter("externalId").value(disbursementTransaction.getExternalId())
|
||||
.failWithCode("value.must.be.unique");
|
||||
}
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors); }
|
||||
}
|
||||
this.loanRepository.saveAndFlush(loan);
|
||||
saveLoanTransactionWithDataIntegrityViolationChecks(disbursementTransaction);
|
||||
saveAndFlushLoanWithDataIntegrityViolationChecks(loan);
|
||||
|
||||
if (StringUtils.isNotBlank(noteText)) {
|
||||
final Note note = Note.loanTransactionNote(loan, disbursementTransaction, noteText);
|
||||
@@ -355,7 +371,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
||||
@Override
|
||||
public void reverseTransfer(final LoanTransaction loanTransaction) {
|
||||
loanTransaction.reverse();
|
||||
this.loanTransactionRepository.save(loanTransaction);
|
||||
saveLoanTransactionWithDataIntegrityViolationChecks(loanTransaction);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+30
-38
@@ -280,17 +280,7 @@ public class LoanCharge extends AbstractPersistable<Long> {
|
||||
}
|
||||
this.amountOrPercentage = chargeAmount;
|
||||
if (this.loan != null && isInstalmentFee()) {
|
||||
final Set<LoanInstallmentCharge> chargePerInstallments = this.loan.generateInstallmentLoanCharges(this);
|
||||
if (this.loanInstallmentCharge.isEmpty()) {
|
||||
this.loanInstallmentCharge.addAll(chargePerInstallments);
|
||||
} else {
|
||||
int index = 0;
|
||||
final LoanInstallmentCharge[] loanChargePerInstallments = new LoanInstallmentCharge[chargePerInstallments.size()];
|
||||
final LoanInstallmentCharge[] loanChargePerInstallmentArray = chargePerInstallments.toArray(loanChargePerInstallments);
|
||||
for (final LoanInstallmentCharge chargePerInstallment : this.loanInstallmentCharge) {
|
||||
chargePerInstallment.copyFrom(loanChargePerInstallmentArray[index++]);
|
||||
}
|
||||
}
|
||||
updateInstallmentCharges();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -386,17 +376,7 @@ public class LoanCharge extends AbstractPersistable<Long> {
|
||||
this.amountOrPercentage = amount;
|
||||
this.amountOutstanding = calculateOutstanding();
|
||||
if (this.loan != null && isInstalmentFee()) {
|
||||
final Set<LoanInstallmentCharge> chargePerInstallments = this.loan.generateInstallmentLoanCharges(this);
|
||||
if (this.loanInstallmentCharge.isEmpty()) {
|
||||
this.loanInstallmentCharge.addAll(chargePerInstallments);
|
||||
} else {
|
||||
int index = 0;
|
||||
final LoanInstallmentCharge[] loanChargePerInstallments = new LoanInstallmentCharge[chargePerInstallments.size()];
|
||||
final LoanInstallmentCharge[] loanChargePerInstallmentArray = chargePerInstallments.toArray(loanChargePerInstallments);
|
||||
for (final LoanInstallmentCharge chargePerInstallment : this.loanInstallmentCharge) {
|
||||
chargePerInstallment.copyFrom(loanChargePerInstallmentArray[index++]);
|
||||
}
|
||||
}
|
||||
updateInstallmentCharges();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -474,22 +454,36 @@ public class LoanCharge extends AbstractPersistable<Long> {
|
||||
}
|
||||
this.amountOrPercentage = newValue;
|
||||
if (isInstalmentFee()) {
|
||||
final Set<LoanInstallmentCharge> chargePerInstallments = this.loan.generateInstallmentLoanCharges(this);
|
||||
if (this.loanInstallmentCharge.isEmpty()) {
|
||||
this.loanInstallmentCharge.addAll(chargePerInstallments);
|
||||
} else {
|
||||
int index = 0;
|
||||
final LoanInstallmentCharge[] loanChargePerInstallments = new LoanInstallmentCharge[chargePerInstallments.size()];
|
||||
final LoanInstallmentCharge[] loanChargePerInstallmentArray = chargePerInstallments.toArray(loanChargePerInstallments);
|
||||
for (final LoanInstallmentCharge chargePerInstallment : this.loanInstallmentCharge) {
|
||||
chargePerInstallment.copyFrom(loanChargePerInstallmentArray[index++]);
|
||||
}
|
||||
}
|
||||
updateInstallmentCharges();
|
||||
}
|
||||
}
|
||||
return actualChanges;
|
||||
}
|
||||
|
||||
private void updateInstallmentCharges() {
|
||||
final Collection<LoanInstallmentCharge> remove = new HashSet<>();
|
||||
final Set<LoanInstallmentCharge> chargePerInstallments = this.loan.generateInstallmentLoanCharges(this);
|
||||
if (this.loanInstallmentCharge.isEmpty()) {
|
||||
this.loanInstallmentCharge.addAll(chargePerInstallments);
|
||||
} else {
|
||||
int index = 0;
|
||||
final LoanInstallmentCharge[] loanChargePerInstallments = new LoanInstallmentCharge[chargePerInstallments.size()];
|
||||
final LoanInstallmentCharge[] loanChargePerInstallmentArray = chargePerInstallments.toArray(loanChargePerInstallments);
|
||||
for (final LoanInstallmentCharge chargePerInstallment : this.loanInstallmentCharge) {
|
||||
if (index == loanChargePerInstallmentArray.length) {
|
||||
remove.add(chargePerInstallment);
|
||||
chargePerInstallment.updateInstallment(null);
|
||||
} else {
|
||||
chargePerInstallment.copyFrom(loanChargePerInstallmentArray[index++]);
|
||||
}
|
||||
}
|
||||
this.loanInstallmentCharge.removeAll(remove);
|
||||
/*while (index < loanChargePerInstallmentArray.length - 1) {
|
||||
chargePerInstallments.add(loanChargePerInstallmentArray[index++]);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isDueAtDisbursement() {
|
||||
return ChargeTimeType.fromInt(this.chargeTime).equals(ChargeTimeType.DISBURSEMENT);
|
||||
}
|
||||
@@ -811,7 +805,7 @@ public class LoanCharge extends AbstractPersistable<Long> {
|
||||
public List<LoanChargePaidDetail> fetchRepaymentInstallment(final MonetaryCurrency currency) {
|
||||
List<LoanChargePaidDetail> chargePaidDetails = new ArrayList<>();
|
||||
for (final LoanInstallmentCharge loanChargePerInstallment : this.loanInstallmentCharge) {
|
||||
if (loanChargePerInstallment.isPending()
|
||||
if (!loanChargePerInstallment.isChargeAmountpaid(currency)
|
||||
&& loanChargePerInstallment.getAmountThroughChargePayment(currency).isGreaterThanZero()) {
|
||||
LoanChargePaidDetail chargePaidDetail = new LoanChargePaidDetail(
|
||||
loanChargePerInstallment.getAmountThroughChargePayment(currency),
|
||||
@@ -857,11 +851,9 @@ public class LoanCharge extends AbstractPersistable<Long> {
|
||||
|
||||
public void updateWaivedAmount(MonetaryCurrency currency) {
|
||||
if (isInstalmentFee()) {
|
||||
this.amountWaived = BigDecimal.ZERO;
|
||||
for (final LoanInstallmentCharge chargePerInstallment : this.loanInstallmentCharge) {
|
||||
final Money amountWaived = chargePerInstallment.updateWaivedAmount(currency);
|
||||
if (this.amountWaived == null) {
|
||||
this.amountWaived = BigDecimal.ZERO;
|
||||
}
|
||||
final Money amountWaived = chargePerInstallment.updateWaivedAndAmountPaidThroughChargePaymentAmount(currency);
|
||||
this.amountWaived = this.amountWaived.add(amountWaived.getAmount());
|
||||
this.amountOutstanding = this.amountOutstanding.subtract(amountWaived.getAmount());
|
||||
if (determineIfFullyPaid()) {
|
||||
|
||||
+31
-2
@@ -145,6 +145,12 @@ public class LoanInstallmentCharge extends AbstractPersistable<Long> {
|
||||
return !(isPaid() || isWaived());
|
||||
}
|
||||
|
||||
public boolean isChargeAmountpaid(MonetaryCurrency currency) {
|
||||
Money amounPaidThroughChargePayment = Money.of(currency, this.amountThroughChargePayment);
|
||||
Money paid = Money.of(currency, this.amountPaid);
|
||||
return amounPaidThroughChargePayment.isEqualTo(paid);
|
||||
}
|
||||
|
||||
public LoanRepaymentScheduleInstallment getRepaymentInstallment() {
|
||||
return this.installment;
|
||||
}
|
||||
@@ -199,16 +205,35 @@ public class LoanInstallmentCharge extends AbstractPersistable<Long> {
|
||||
this.amountPaid = BigDecimal.ZERO;
|
||||
this.amountWaived = BigDecimal.ZERO;
|
||||
this.amountWrittenOff = BigDecimal.ZERO;
|
||||
this.amountThroughChargePayment = BigDecimal.ZERO;
|
||||
this.amountOutstanding = calculateAmountOutstanding(currency);
|
||||
this.paid = false;
|
||||
this.waived = false;
|
||||
|
||||
}
|
||||
|
||||
public Money getAmountThroughChargePayment(final MonetaryCurrency currency) {
|
||||
return Money.of(currency, this.amountThroughChargePayment);
|
||||
}
|
||||
|
||||
public Money updateWaivedAmount(final MonetaryCurrency currency) {
|
||||
public Money getUnpaidAmountThroughChargePayment(final MonetaryCurrency currency) {
|
||||
return Money.of(currency, this.amountThroughChargePayment).minus(this.amountPaid);
|
||||
}
|
||||
|
||||
private void updateAmountThroughChargePayment(final MonetaryCurrency currency) {
|
||||
Money amountThroughChargePayment = getAmountThroughChargePayment(currency);
|
||||
if (amountThroughChargePayment.isGreaterThanZero() && amountThroughChargePayment.isGreaterThan(this.getAmount(currency))) {
|
||||
this.amountThroughChargePayment = this.getAmount();
|
||||
}
|
||||
}
|
||||
|
||||
public Money updateWaivedAndAmountPaidThroughChargePaymentAmount(final MonetaryCurrency currency) {
|
||||
updateWaivedAmount(currency);
|
||||
updateAmountThroughChargePayment(currency);
|
||||
return getAmountWaived(currency);
|
||||
}
|
||||
|
||||
private void updateWaivedAmount(final MonetaryCurrency currency) {
|
||||
Money waivedAmount = getAmountWaived(currency);
|
||||
if (waivedAmount.isGreaterThanZero()) {
|
||||
if (waivedAmount.isGreaterThan(this.getAmount(currency))) {
|
||||
@@ -221,7 +246,11 @@ public class LoanInstallmentCharge extends AbstractPersistable<Long> {
|
||||
this.waived = false;
|
||||
}
|
||||
}
|
||||
return getAmountWaived(currency);
|
||||
}
|
||||
|
||||
|
||||
public void updateInstallment(LoanRepaymentScheduleInstallment installment) {
|
||||
this.installment = installment;
|
||||
}
|
||||
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package org.mifosplatform.portfolio.loanaccount.domain;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
|
||||
public interface LoanRepaymentScheduleInstallmentRepository extends JpaRepository<LoanRepaymentScheduleInstallment, Long>,
|
||||
JpaSpecificationExecutor<LoanRepaymentScheduleInstallment> {
|
||||
|
||||
}
|
||||
+1
@@ -263,6 +263,7 @@ public final class LoanTransaction extends AbstractPersistable<Long> {
|
||||
this.interestPortion = null;
|
||||
this.feeChargesPortion = null;
|
||||
this.penaltyChargesPortion = null;
|
||||
this.overPaymentPortion = null;
|
||||
}
|
||||
|
||||
public void updateLoan(final Loan loan) {
|
||||
|
||||
+42
-25
@@ -86,8 +86,12 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
|
||||
for (final LoanRepaymentScheduleInstallment installment : installments) {
|
||||
for (final LoanCharge loanCharge : transferCharges) {
|
||||
if (loanCharge.isDueForCollectionFromAndUpToAndIncluding(startDate, installment.getDueDate())) {
|
||||
LoanChargePaidDetail chargePaidDetail = new LoanChargePaidDetail(
|
||||
installment.getFeeChargesOutstanding(currency), installment, loanCharge.isFeeCharge());
|
||||
Money amountForProcess = loanCharge.getAmount(currency);
|
||||
if (amountForProcess.isGreaterThan(loanTransaction.getAmount(currency))) {
|
||||
amountForProcess = loanTransaction.getAmount(currency);
|
||||
}
|
||||
LoanChargePaidDetail chargePaidDetail = new LoanChargePaidDetail(amountForProcess, installment,
|
||||
loanCharge.isFeeCharge());
|
||||
chargePaidDetails.add(chargePaidDetail);
|
||||
break;
|
||||
}
|
||||
@@ -98,11 +102,13 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
|
||||
Money unprocessed = loanTransaction.getAmount(currency);
|
||||
for (LoanChargePaidDetail chargePaidDetail : chargePaidDetails) {
|
||||
final List<LoanRepaymentScheduleInstallment> processInstallments = new ArrayList<>(1);
|
||||
unprocessed = unprocessed.minus(chargePaidDetail.getAmount());
|
||||
processInstallments.add(chargePaidDetail.getInstallment());
|
||||
Money unprocessedAfterProcess = handleTransactionAndCharges(loanTransaction, currency, processInstallments,
|
||||
transferCharges, chargePaidDetail.getAmount(), chargePaidDetail.isFeeCharge());
|
||||
unprocessed = unprocessed.plus(unprocessedAfterProcess);
|
||||
Money processAmt = chargePaidDetail.getAmount();
|
||||
if(processAmt.isGreaterThan(unprocessed)){
|
||||
processAmt = unprocessed;
|
||||
}
|
||||
unprocessed = handleTransactionAndCharges(loanTransaction, currency, processInstallments,
|
||||
transferCharges, processAmt, chargePaidDetail.isFeeCharge());
|
||||
if (!unprocessed.isGreaterThanZero()) {
|
||||
break;
|
||||
}
|
||||
@@ -206,7 +212,7 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
|
||||
if (loanTransaction.isNotWaiver()) {
|
||||
Money feeCharges = loanTransaction.getFeeChargesPortion(currency);
|
||||
Money penaltyCharges = loanTransaction.getPenaltyChargesPortion(currency);
|
||||
if (chargeAmountToProcess != null) {
|
||||
if (chargeAmountToProcess != null && feeCharges.isGreaterThan(chargeAmountToProcess)) {
|
||||
if (isFeeCharge) {
|
||||
feeCharges = chargeAmountToProcess;
|
||||
} else {
|
||||
@@ -235,23 +241,26 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
|
||||
}
|
||||
|
||||
for (final LoanRepaymentScheduleInstallment currentInstallment : installments) {
|
||||
if (transactionAmountUnprocessed.isGreaterThanZero()) {
|
||||
if (currentInstallment.isNotFullyPaidOff()) {
|
||||
|
||||
if (currentInstallment.isNotFullyPaidOff()) {
|
||||
|
||||
// is this transaction early/late/on-time with respect to the
|
||||
// current installment?
|
||||
if (isTransactionInAdvanceOfInstallment(installmentIndex, installments, transactionDate, transactionAmountUnprocessed)) {
|
||||
transactionAmountUnprocessed = handleTransactionThatIsPaymentInAdvanceOfInstallment(currentInstallment, installments,
|
||||
loanTransaction, transactionDate, transactionAmountUnprocessed);
|
||||
} else if (isTransactionALateRepaymentOnInstallment(installmentIndex, installments, loanTransaction.getTransactionDate())) {
|
||||
// does this result in a late payment of existing
|
||||
// installment?
|
||||
transactionAmountUnprocessed = handleTransactionThatIsALateRepaymentOfInstallment(currentInstallment, installments,
|
||||
loanTransaction, transactionAmountUnprocessed);
|
||||
} else {
|
||||
// standard transaction
|
||||
transactionAmountUnprocessed = handleTransactionThatIsOnTimePaymentOfInstallment(currentInstallment, loanTransaction,
|
||||
transactionAmountUnprocessed);
|
||||
// is this transaction early/late/on-time with respect to
|
||||
// the
|
||||
// current installment?
|
||||
if (isTransactionInAdvanceOfInstallment(installmentIndex, installments, transactionDate, transactionAmountUnprocessed)) {
|
||||
transactionAmountUnprocessed = handleTransactionThatIsPaymentInAdvanceOfInstallment(currentInstallment,
|
||||
installments, loanTransaction, transactionDate, transactionAmountUnprocessed);
|
||||
} else if (isTransactionALateRepaymentOnInstallment(installmentIndex, installments,
|
||||
loanTransaction.getTransactionDate())) {
|
||||
// does this result in a late payment of existing
|
||||
// installment?
|
||||
transactionAmountUnprocessed = handleTransactionThatIsALateRepaymentOfInstallment(currentInstallment, installments,
|
||||
loanTransaction, transactionAmountUnprocessed);
|
||||
} else {
|
||||
// standard transaction
|
||||
transactionAmountUnprocessed = handleTransactionThatIsOnTimePaymentOfInstallment(currentInstallment,
|
||||
loanTransaction, transactionAmountUnprocessed);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -292,10 +301,18 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen
|
||||
}
|
||||
final Money amountPaidTowardsCharge = unpaidCharge.updatePaidAmountBy(amountRemaining, installmentNumber, feeAmount);
|
||||
if (!amountPaidTowardsCharge.isZero()) {
|
||||
if (!loanTransaction.isChargePayment()) {
|
||||
Set<LoanChargePaidBy> chargesPaidBies = loanTransaction.getLoanChargesPaid();
|
||||
if (loanTransaction.isChargePayment()) {
|
||||
for (final LoanChargePaidBy chargePaidBy : chargesPaidBies) {
|
||||
LoanCharge loanCharge = chargePaidBy.getLoanCharge();
|
||||
if (loanCharge.getId().equals(unpaidCharge.getId())) {
|
||||
chargePaidBy.setAmount(amountPaidTowardsCharge.getAmount());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
final LoanChargePaidBy loanChargePaidBy = new LoanChargePaidBy(loanTransaction, unpaidCharge,
|
||||
amountPaidTowardsCharge.getAmount());
|
||||
loanTransaction.getLoanChargesPaid().add(loanChargePaidBy);
|
||||
chargesPaidBies.add(loanChargePaidBy);
|
||||
}
|
||||
amountRemaining = amountRemaining.minus(amountPaidTowardsCharge);
|
||||
}
|
||||
|
||||
+16
-17
@@ -231,15 +231,14 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
||||
principalForThisPeriod = principalForThisPeriod.plus(actualOutstanding);
|
||||
}
|
||||
}
|
||||
|
||||
interestReducedDueToEarlyPayment = interestReducedDueToEarlyPayment.plus(loanApplicationTerms.interestRateFor(
|
||||
this.paymentPeriodsInOneYearCalculator, mc, diffDays, detail.getAmount()));
|
||||
this.paymentPeriodsInOneYearCalculator, mc, detail.getAmount(), detail.getStartDate(), scheduledDueDate));
|
||||
|
||||
} else if (detail.isLatePayment() && detail.isOverlapping(periodStartDate, scheduledDueDate)
|
||||
&& periodStartDate.isBefore(LocalDate.now())) {
|
||||
LocalDate fromDate = periodStartDate;
|
||||
LocalDate toDate = scheduledDueDate;
|
||||
if (!detail.getStartDate().isAfter(periodStartDate)) {
|
||||
if (!detail.getStartDate().isBefore(periodStartDate)) {
|
||||
fromDate = detail.getStartDate();
|
||||
}
|
||||
if (!detail.getToDate().isAfter(scheduledDueDate)) {
|
||||
@@ -248,9 +247,8 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
||||
if (toDate.isAfter(LocalDate.now())) {
|
||||
toDate = LocalDate.now();
|
||||
}
|
||||
int diffDays = Days.daysBetween(fromDate, toDate).getDays();
|
||||
interestDueToLatePayment = interestDueToLatePayment.plus(loanApplicationTerms.interestRateFor(
|
||||
this.paymentPeriodsInOneYearCalculator, mc, diffDays, detail.getAmount()));
|
||||
this.paymentPeriodsInOneYearCalculator, mc, detail.getAmount(), fromDate, toDate));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -333,18 +331,19 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
||||
for (RecalculationDetail detail : processDetails.values()) {
|
||||
LocalDate fromDate = detail.getStartDate();
|
||||
LocalDate toDate = detail.getToDate();
|
||||
int diffDays = Days.daysBetween(fromDate, toDate).getDays();
|
||||
Money interestDueToLatePayment = loanApplicationTerms.interestRateFor(this.paymentPeriodsInOneYearCalculator, mc, diffDays,
|
||||
detail.getAmount());
|
||||
if (!toDate.isAfter(LocalDate.now())) {
|
||||
Money interestDueToLatePayment = loanApplicationTerms.interestRateFor(this.paymentPeriodsInOneYearCalculator, mc,
|
||||
detail.getAmount(), fromDate, toDate);
|
||||
|
||||
totalInterestCharged = totalInterestCharged.add(interestDueToLatePayment.getAmount());
|
||||
totalRepaymentExpected = totalRepaymentExpected.add(interestDueToLatePayment.getAmount());
|
||||
totalInterestCharged = totalInterestCharged.add(interestDueToLatePayment.getAmount());
|
||||
totalRepaymentExpected = totalRepaymentExpected.add(interestDueToLatePayment.getAmount());
|
||||
|
||||
final LoanScheduleModelPeriod installment = LoanScheduleModelRepaymentPeriod.repayment(periodNumber, fromDate, toDate,
|
||||
interestDueToLatePayment.zero(), interestDueToLatePayment.zero(), interestDueToLatePayment,
|
||||
interestDueToLatePayment.zero(), interestDueToLatePayment.zero(), interestDueToLatePayment);
|
||||
periods.add(installment);
|
||||
periodNumber++;
|
||||
final LoanScheduleModelPeriod installment = LoanScheduleModelRepaymentPeriod.repayment(periodNumber, fromDate, toDate,
|
||||
interestDueToLatePayment.zero(), interestDueToLatePayment.zero(), interestDueToLatePayment,
|
||||
interestDueToLatePayment.zero(), interestDueToLatePayment.zero(), interestDueToLatePayment);
|
||||
periods.add(installment);
|
||||
periodNumber++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -711,8 +710,8 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
||||
}
|
||||
}
|
||||
|
||||
int days = Days.daysBetween(calculateInterestFrom, LocalDate.now()).getDays();
|
||||
Money interest = applicationTerms.interestRateFor(this.paymentPeriodsInOneYearCalculator, mc, days, prepaymentAmount);
|
||||
Money interest = applicationTerms.interestRateFor(this.paymentPeriodsInOneYearCalculator, mc, prepaymentAmount,
|
||||
calculateInterestFrom, LocalDate.now());
|
||||
prepaymentAmount = prepaymentAmount.plus(interest).plus(amount);
|
||||
return prepaymentAmount;
|
||||
}
|
||||
|
||||
+67
-4
@@ -13,6 +13,8 @@ import java.util.List;
|
||||
|
||||
import org.joda.time.Days;
|
||||
import org.joda.time.LocalDate;
|
||||
import org.joda.time.Period;
|
||||
import org.joda.time.PeriodType;
|
||||
import org.mifosplatform.organisation.monetary.domain.ApplicationCurrency;
|
||||
import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
|
||||
import org.mifosplatform.organisation.monetary.domain.Money;
|
||||
@@ -661,15 +663,21 @@ public final class LoanApplicationTerms {
|
||||
return periodicInterestRate;
|
||||
}
|
||||
|
||||
public Money interestRateFor(final PaymentPeriodsInOneYearCalculator calculator, final MathContext mc, int days,
|
||||
final Money outstandingBalance) {
|
||||
final long loanTermPeriodsInOneYear = calculatePeriodsInOneYear(calculator);
|
||||
public Money interestRateFor(final PaymentPeriodsInOneYearCalculator calculator, final MathContext mc, final Money outstandingBalance,
|
||||
final LocalDate fromDate, final LocalDate toDate) {
|
||||
|
||||
long loanTermPeriodsInOneYear = calculator.calculate(PeriodFrequencyType.DAYS).longValue();
|
||||
int repaymentEvery = Days.daysBetween(fromDate, toDate).getDays();
|
||||
if (isFallingInRepaymentPeriod(fromDate, toDate)) {
|
||||
loanTermPeriodsInOneYear = calculatePeriodsInOneYear(calculator);
|
||||
repaymentEvery = getPeriodsBetween(fromDate, toDate);
|
||||
}
|
||||
|
||||
final BigDecimal divisor = BigDecimal.valueOf(Double.valueOf("100.0"));
|
||||
final BigDecimal loanTermPeriodsInYearBigDecimal = BigDecimal.valueOf(loanTermPeriodsInOneYear);
|
||||
final BigDecimal oneDayOfYearInterestRate = this.annualNominalInterestRate.divide(loanTermPeriodsInYearBigDecimal, mc).divide(
|
||||
divisor, mc);
|
||||
BigDecimal interestRate = oneDayOfYearInterestRate.multiply(BigDecimal.valueOf(days), mc);
|
||||
BigDecimal interestRate = oneDayOfYearInterestRate.multiply(BigDecimal.valueOf(repaymentEvery), mc);
|
||||
return outstandingBalance.multiplyRetainScale(interestRate, mc.getRoundingMode());
|
||||
}
|
||||
|
||||
@@ -967,4 +975,59 @@ public final class LoanApplicationTerms {
|
||||
public CalendarInstance getRestCalendarInstance() {
|
||||
return this.restCalendarInstance;
|
||||
}
|
||||
|
||||
private boolean isFallingInRepaymentPeriod(LocalDate fromDate, LocalDate toDate) {
|
||||
boolean isSameAsRepaymentPeriod = false;
|
||||
if (this.interestCalculationPeriodMethod.getValue().equals(InterestCalculationPeriodMethod.SAME_AS_REPAYMENT_PERIOD.getValue())) {
|
||||
switch (this.repaymentPeriodFrequencyType) {
|
||||
case WEEKS:
|
||||
int days = getPeriodsBetween(fromDate, toDate);
|
||||
isSameAsRepaymentPeriod = (days % 7) == 0;
|
||||
break;
|
||||
case MONTHS:
|
||||
boolean isFromDateOnEndDate = false;
|
||||
if (fromDate.getDayOfMonth() > fromDate.plusDays(1).getDayOfMonth()) {
|
||||
isFromDateOnEndDate = true;
|
||||
}
|
||||
boolean isToDateOnEndDate = false;
|
||||
if (toDate.getDayOfMonth() > toDate.plusDays(1).getDayOfMonth()) {
|
||||
isToDateOnEndDate = true;
|
||||
}
|
||||
|
||||
if (isFromDateOnEndDate && isToDateOnEndDate) {
|
||||
isSameAsRepaymentPeriod = true;
|
||||
} else {
|
||||
|
||||
int months = getPeriodsBetween(fromDate, toDate);
|
||||
fromDate = fromDate.plusMonths(months);
|
||||
isSameAsRepaymentPeriod = fromDate.isEqual(toDate);
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return isSameAsRepaymentPeriod;
|
||||
}
|
||||
|
||||
private Integer getPeriodsBetween(LocalDate fromDate, LocalDate toDate) {
|
||||
Integer numberOfPeriods = 0;
|
||||
PeriodType periodType = PeriodType.yearMonthDay();
|
||||
Period difference = new Period(fromDate, toDate, periodType);
|
||||
switch (this.repaymentPeriodFrequencyType) {
|
||||
case WEEKS:
|
||||
numberOfPeriods = difference.getDays();
|
||||
break;
|
||||
case MONTHS:
|
||||
numberOfPeriods = difference.getMonths();
|
||||
break;
|
||||
case YEARS:
|
||||
numberOfPeriods = difference.getYears();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return numberOfPeriods;
|
||||
}
|
||||
}
|
||||
+33
-23
@@ -54,9 +54,9 @@ import org.mifosplatform.portfolio.loanaccount.data.LoanChargeData;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.DefaultLoanLifecycleStateMachine;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.Loan;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanCharge;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanChargeRepository;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanInstallmentCharge;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanLifecycleStateMachine;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallmentRepository;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleTransactionProcessorFactory;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepository;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanStatus;
|
||||
@@ -119,8 +119,8 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
||||
private final CalendarInstanceRepository calendarInstanceRepository;
|
||||
private final SavingsAccountAssembler savingsAccountAssembler;
|
||||
private final AccountAssociationsRepository accountAssociationsRepository;
|
||||
private final LoanChargeRepository loanChargeRepository;
|
||||
private final LoanReadPlatformService loanReadPlatformService;
|
||||
private final LoanRepaymentScheduleInstallmentRepository repaymentScheduleInstallmentRepository;
|
||||
|
||||
@Autowired
|
||||
public LoanApplicationWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final FromJsonHelper fromJsonHelper,
|
||||
@@ -135,7 +135,8 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
||||
final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory,
|
||||
final CalendarRepository calendarRepository, final CalendarInstanceRepository calendarInstanceRepository,
|
||||
final SavingsAccountAssembler savingsAccountAssembler, final AccountAssociationsRepository accountAssociationsRepository,
|
||||
final LoanChargeRepository loanChargeRepository, final LoanReadPlatformService loanReadPlatformService) {
|
||||
final LoanRepaymentScheduleInstallmentRepository repaymentScheduleInstallmentRepository,
|
||||
final LoanReadPlatformService loanReadPlatformService) {
|
||||
this.context = context;
|
||||
this.fromJsonHelper = fromJsonHelper;
|
||||
this.loanApplicationTransitionApiJsonValidator = loanApplicationTransitionApiJsonValidator;
|
||||
@@ -158,7 +159,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
||||
this.calendarInstanceRepository = calendarInstanceRepository;
|
||||
this.savingsAccountAssembler = savingsAccountAssembler;
|
||||
this.accountAssociationsRepository = accountAssociationsRepository;
|
||||
this.loanChargeRepository = loanChargeRepository;
|
||||
this.repaymentScheduleInstallmentRepository = repaymentScheduleInstallmentRepository;
|
||||
this.loanReadPlatformService = loanReadPlatformService;
|
||||
}
|
||||
|
||||
@@ -517,36 +518,22 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
||||
|
||||
final LoanScheduleModel loanSchedule = this.calculationPlatformService.calculateLoanSchedule(query, false);
|
||||
existingLoanApplication.updateLoanSchedule(loanSchedule);
|
||||
existingLoanApplication.recalculateAllCharges();
|
||||
}
|
||||
|
||||
this.loanRepository.saveAndFlush(existingLoanApplication);
|
||||
|
||||
// FIXME: adding loan installment charges along with the other
|
||||
// charges,
|
||||
// is trying to add extra entries with null values. Because of that
|
||||
// persisting charges separately
|
||||
final String chargesParamName = "charges";
|
||||
if (changes.containsKey(chargesParamName)) {
|
||||
final Set<LoanCharge> loanCharges = this.loanChargeAssembler.fromParsedJson(command.parsedJson());
|
||||
existingLoanApplication.updateLoanCharges(loanCharges);
|
||||
this.loanRepository.saveAndFlush(existingLoanApplication);
|
||||
existingLoanApplication.updateLoanCharges(possiblyModifedLoanCharges);
|
||||
}
|
||||
|
||||
saveAndFlushLoanWithDataIntegrityViolationChecks(existingLoanApplication);
|
||||
|
||||
final String submittedOnNote = command.stringValueOfParameterNamed("submittedOnNote");
|
||||
if (StringUtils.isNotBlank(submittedOnNote)) {
|
||||
final Note note = Note.loanNote(existingLoanApplication, submittedOnNote);
|
||||
this.noteRepository.save(note);
|
||||
}
|
||||
|
||||
for (final LoanCharge loanCharge : existingLoanApplication.charges()) {
|
||||
if (loanCharge.isInstalmentFee() && loanCharge.hasNoLoanInstallmentCharges()) {
|
||||
final Set<LoanInstallmentCharge> chargePerInstallments = existingLoanApplication
|
||||
.generateInstallmentLoanCharges(loanCharge);
|
||||
loanCharge.addLoanInstallmentCharges(chargePerInstallments);
|
||||
this.loanChargeRepository.save(loanCharge);
|
||||
}
|
||||
}
|
||||
|
||||
final Long calendarId = command.longValueOfParameterNamed("calendarId");
|
||||
Calendar calendar = null;
|
||||
if (calendarId != null && calendarId != 0) {
|
||||
@@ -896,4 +883,27 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
||||
}
|
||||
}
|
||||
|
||||
private void saveAndFlushLoanWithDataIntegrityViolationChecks(final Loan loan) {
|
||||
try {
|
||||
List<LoanRepaymentScheduleInstallment> installments = loan.fetchRepaymentScheduleInstallments();
|
||||
for (LoanRepaymentScheduleInstallment installment : installments) {
|
||||
if (installment.getId() == null) {
|
||||
this.repaymentScheduleInstallmentRepository.save(installment);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.loanRepository.saveAndFlush(loan);
|
||||
} catch (final DataIntegrityViolationException e) {
|
||||
final Throwable realCause = e.getCause();
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("loan.application");
|
||||
if (realCause.getMessage().toLowerCase().contains("external_id_unique")) {
|
||||
baseDataValidator.reset().parameter("externalId").failWithCode("value.must.be.unique");
|
||||
}
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors); }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+69
-51
@@ -98,6 +98,7 @@ import org.mifosplatform.portfolio.loanaccount.domain.LoanInstallmentCharge;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanLifecycleStateMachine;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanOverdueInstallmentCharge;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallmentRepository;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanRepository;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanStatus;
|
||||
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransaction;
|
||||
@@ -166,6 +167,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
private final FromJsonHelper fromApiJsonHelper;
|
||||
private final AccountTransferRepository accountTransferRepository;
|
||||
private final CalendarRepository calendarRepository;
|
||||
private final LoanRepaymentScheduleInstallmentRepository repaymentScheduleInstallmentRepository;
|
||||
|
||||
@Autowired
|
||||
public LoanWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
|
||||
@@ -185,7 +187,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
final AccountAssociationsReadPlatformService accountAssociationsReadPlatformService,
|
||||
final LoanChargeReadPlatformService loanChargeReadPlatformService, final LoanReadPlatformService loanReadPlatformService,
|
||||
final FromJsonHelper fromApiJsonHelper, final AccountTransferRepository accountTransferRepository,
|
||||
final CalendarRepository calendarRepository) {
|
||||
final CalendarRepository calendarRepository,
|
||||
final LoanRepaymentScheduleInstallmentRepository repaymentScheduleInstallmentRepository) {
|
||||
this.context = context;
|
||||
this.loanEventApiJsonValidator = loanEventApiJsonValidator;
|
||||
this.loanAssembler = loanAssembler;
|
||||
@@ -213,6 +216,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
this.fromApiJsonHelper = fromApiJsonHelper;
|
||||
this.accountTransferRepository = accountTransferRepository;
|
||||
this.calendarRepository = calendarRepository;
|
||||
this.repaymentScheduleInstallmentRepository = repaymentScheduleInstallmentRepository;
|
||||
}
|
||||
|
||||
private LoanLifecycleStateMachine defaultLoanLifecycleStateMachine() {
|
||||
@@ -267,6 +271,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
Money amountBeforeAdjust = loan.getPrincpal();
|
||||
loan.validateAccountStatus(LoanEvent.LOAN_DISBURSED);
|
||||
boolean canDisburse = loan.canDisburse(actualDisbursementDate);
|
||||
ChangedTransactionDetail changedTransactionDetail = null;
|
||||
if (canDisburse) {
|
||||
Money disburseAmount = loan.adjustDisburseAmount(command, actualDisbursementDate);
|
||||
boolean recalcualteSchedule = amountBeforeAdjust.isNotEqualTo(loan.getPrincpal());
|
||||
@@ -286,9 +291,10 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
CalendarEntityType.LOAN_RECALCULATION_DETAIL.getValue());
|
||||
}
|
||||
|
||||
loan.disburse(this.loanScheduleFactory, currentUser, command, applicationCurrency, existingTransactionIds,
|
||||
existingReversedTransactionIds, changes, calculatedRepaymentsStartingFromDate, isHolidayEnabled, holidays, workingDays,
|
||||
allowTransactionsOnHoliday, allowTransactionsOnNonWorkingDay, recalcualteSchedule, restCalendarInstance);
|
||||
changedTransactionDetail = loan.disburse(this.loanScheduleFactory, currentUser, command, applicationCurrency,
|
||||
existingTransactionIds, existingReversedTransactionIds, changes, calculatedRepaymentsStartingFromDate,
|
||||
isHolidayEnabled, holidays, workingDays, allowTransactionsOnHoliday, allowTransactionsOnNonWorkingDay,
|
||||
recalcualteSchedule, restCalendarInstance);
|
||||
}
|
||||
if (!changes.isEmpty()) {
|
||||
saveAndFlushLoanWithDataIntegrityViolationChecks(loan);
|
||||
@@ -299,11 +305,6 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
this.noteRepository.save(note);
|
||||
}
|
||||
|
||||
// fix me
|
||||
// adding loan installment charges along with the actual
|
||||
// disbursement, is trying to add 2 extra entries with null values.
|
||||
// which is causing issues
|
||||
ChangedTransactionDetail changedTransactionDetail = loan.reprocessTransactionForDisbursement();
|
||||
saveAndFlushLoanWithDataIntegrityViolationChecks(loan);
|
||||
|
||||
if (changedTransactionDetail != null) {
|
||||
@@ -367,6 +368,14 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
|
||||
private void saveAndFlushLoanWithDataIntegrityViolationChecks(final Loan loan) {
|
||||
try {
|
||||
List<LoanRepaymentScheduleInstallment> installments = loan.fetchRepaymentScheduleInstallments();
|
||||
for (LoanRepaymentScheduleInstallment installment : installments) {
|
||||
if (installment.getId() == null) {
|
||||
this.repaymentScheduleInstallmentRepository.save(installment);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.loanRepository.saveAndFlush(loan);
|
||||
} catch (final DataIntegrityViolationException e) {
|
||||
final Throwable realCause = e.getCause();
|
||||
@@ -380,6 +389,29 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
}
|
||||
}
|
||||
|
||||
private void saveLoanWithDataIntegrityViolationChecks(final Loan loan) {
|
||||
try {
|
||||
List<LoanRepaymentScheduleInstallment> installments = loan.fetchRepaymentScheduleInstallments();
|
||||
for (LoanRepaymentScheduleInstallment installment : installments) {
|
||||
if (installment.getId() == null) {
|
||||
this.repaymentScheduleInstallmentRepository.save(installment);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.loanRepository.save(loan);
|
||||
} catch (final DataIntegrityViolationException e) {
|
||||
final Throwable realCause = e.getCause();
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("loan.transaction");
|
||||
if (realCause.getMessage().toLowerCase().contains("external_id_unique")) {
|
||||
baseDataValidator.reset().parameter("externalId").failWithCode("value.must.be.unique");
|
||||
}
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException("validation.msg.validation.errors.exist",
|
||||
"Validation errors exist.", dataValidationErrors); }
|
||||
}
|
||||
}
|
||||
|
||||
/****
|
||||
* TODO Vishwas: Pair with Ashok and re-factor collection sheet code-base
|
||||
*
|
||||
@@ -426,6 +458,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
loan.validateAccountStatus(LoanEvent.LOAN_DISBURSED);
|
||||
updateLoanCounters(loan, actualDisbursementDate);
|
||||
boolean canDisburse = loan.canDisburse(actualDisbursementDate);
|
||||
ChangedTransactionDetail changedTransactionDetail = null;
|
||||
if (canDisburse) {
|
||||
Money amountBeforeAdjust = loan.getPrincpal();
|
||||
Money disburseAmount = loan.adjustDisburseAmount(command, actualDisbursementDate);
|
||||
@@ -445,24 +478,14 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
loan.loanInterestRecalculationDetailId(), CalendarEntityType.LOAN_RECALCULATION_DETAIL.getValue());
|
||||
}
|
||||
|
||||
loan.disburse(this.loanScheduleFactory, currentUser, command, applicationCurrency, existingTransactionIds,
|
||||
existingReversedTransactionIds, changes, firstRepaymentOnDate, isHolidayEnabled, holidays, workingDays,
|
||||
allowTransactionsOnHoliday, allowTransactionsOnNonWorkingDay, recalcualteSchedule, restCalendarInstance);
|
||||
changedTransactionDetail = loan.disburse(this.loanScheduleFactory, currentUser, command, applicationCurrency,
|
||||
existingTransactionIds, existingReversedTransactionIds, changes, firstRepaymentOnDate, isHolidayEnabled, holidays,
|
||||
workingDays, allowTransactionsOnHoliday, allowTransactionsOnNonWorkingDay, recalcualteSchedule,
|
||||
restCalendarInstance);
|
||||
}
|
||||
if (!changes.isEmpty()) {
|
||||
try {
|
||||
this.loanRepository.save(loan);
|
||||
} catch (final DataIntegrityViolationException e) {
|
||||
final Throwable realCause = e.getCause();
|
||||
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
|
||||
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors)
|
||||
.resource("loan.transaction");
|
||||
if (realCause.getMessage().toLowerCase().contains("external_id_unique")) {
|
||||
baseDataValidator.reset().parameter("externalId").failWithCode("value.must.be.unique");
|
||||
}
|
||||
if (!dataValidationErrors.isEmpty()) { throw new PlatformApiDataValidationException(
|
||||
"validation.msg.validation.errors.exist", "Validation errors exist.", dataValidationErrors); }
|
||||
}
|
||||
|
||||
saveLoanWithDataIntegrityViolationChecks(loan);
|
||||
|
||||
final String noteText = command.stringValueOfParameterNamed("note");
|
||||
if (StringUtils.isNotBlank(noteText)) {
|
||||
@@ -470,11 +493,6 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
this.noteRepository.save(note);
|
||||
}
|
||||
|
||||
// fix me
|
||||
// adding loan installment charges along with the actual
|
||||
// disbursement, is trying to add 2 extra entries with null
|
||||
// values. which is causing issues
|
||||
ChangedTransactionDetail changedTransactionDetail = loan.reprocessTransactionForDisbursement();
|
||||
saveAndFlushLoanWithDataIntegrityViolationChecks(loan);
|
||||
if (changedTransactionDetail != null) {
|
||||
for (final Map.Entry<Long, LoanTransaction> mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) {
|
||||
@@ -542,7 +560,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
existingReversedTransactionIds, calculatedRepaymentsStartingFromDate, isHolidayEnabled, holidays, workingDays);
|
||||
|
||||
if (!changes.isEmpty()) {
|
||||
this.loanRepository.saveAndFlush(loan);
|
||||
saveAndFlushLoanWithDataIntegrityViolationChecks(loan);
|
||||
this.accountTransfersWritePlatformService.reverseAllTransactions(loanId, PortfolioAccountType.LOAN);
|
||||
String noteText = null;
|
||||
if (command.hasParameter("note")) {
|
||||
@@ -719,7 +737,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
* only in edge cases (when a adjustment is made before the latest
|
||||
* payment recorded against the loan)
|
||||
***/
|
||||
this.loanRepository.saveAndFlush(loan);
|
||||
saveAndFlushLoanWithDataIntegrityViolationChecks(loan);
|
||||
if (changedTransactionDetail != null) {
|
||||
for (final Map.Entry<Long, LoanTransaction> mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) {
|
||||
this.loanTransactionRepository.save(mapEntry.getValue());
|
||||
@@ -821,7 +839,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
* only in edge cases (when a waiver is made before the latest payment
|
||||
* recorded against the loan)
|
||||
***/
|
||||
this.loanRepository.saveAndFlush(loan);
|
||||
saveAndFlushLoanWithDataIntegrityViolationChecks(loan);
|
||||
if (changedTransactionDetail != null) {
|
||||
for (final Map.Entry<Long, LoanTransaction> mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) {
|
||||
this.loanTransactionRepository.save(mapEntry.getValue());
|
||||
@@ -898,7 +916,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
this.loanTransactionRepository.save(mapEntry.getValue());
|
||||
this.accountTransfersWritePlatformService.updateLoanTransaction(mapEntry.getKey(), mapEntry.getValue());
|
||||
}
|
||||
this.loanRepository.save(loan);
|
||||
saveLoanWithDataIntegrityViolationChecks(loan);
|
||||
final String noteText = command.stringValueOfParameterNamed("note");
|
||||
if (StringUtils.isNotBlank(noteText)) {
|
||||
changes.put("note", noteText);
|
||||
@@ -968,7 +986,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
this.loanTransactionRepository.save(mapEntry.getValue());
|
||||
this.accountTransfersWritePlatformService.updateLoanTransaction(mapEntry.getKey(), mapEntry.getValue());
|
||||
}
|
||||
this.loanRepository.save(loan);
|
||||
saveLoanWithDataIntegrityViolationChecks(loan);
|
||||
|
||||
final String noteText = command.stringValueOfParameterNamed("note");
|
||||
if (StringUtils.isNotBlank(noteText)) {
|
||||
@@ -1026,7 +1044,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
|
||||
loan.closeAsMarkedForReschedule(command, defaultLoanLifecycleStateMachine(), changes);
|
||||
|
||||
this.loanRepository.save(loan);
|
||||
saveLoanWithDataIntegrityViolationChecks(loan);
|
||||
|
||||
final String noteText = command.stringValueOfParameterNamed("note");
|
||||
if (StringUtils.isNotBlank(noteText)) {
|
||||
@@ -1120,7 +1138,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
* entered only in edge cases (when a payment is made before the
|
||||
* latest payment recorded against the loan)
|
||||
***/
|
||||
this.loanRepository.save(loan);
|
||||
saveLoanWithDataIntegrityViolationChecks(loan);
|
||||
if (changedTransactionDetail != null) {
|
||||
for (final Map.Entry<Long, LoanTransaction> mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) {
|
||||
this.loanTransactionRepository.save(mapEntry.getValue());
|
||||
@@ -1155,7 +1173,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
|
||||
final Map<String, Object> changes = loan.updateLoanCharge(loanCharge, command);
|
||||
|
||||
this.loanRepository.save(loan);
|
||||
saveLoanWithDataIntegrityViolationChecks(loan);
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withCommandId(command.commandId()) //
|
||||
@@ -1220,7 +1238,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
existingTransactionIds, existingReversedTransactionIds, loanInstallmentNumber);
|
||||
|
||||
this.loanTransactionRepository.save(waiveTransaction);
|
||||
this.loanRepository.save(loan);
|
||||
saveLoanWithDataIntegrityViolationChecks(loan);
|
||||
|
||||
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);
|
||||
|
||||
@@ -1251,7 +1269,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
LOAN_CHARGE_CANNOT_BE_DELETED_REASON.LOAN_NOT_IN_SUBMITTED_AND_PENDING_APPROVAL_STAGE, loanCharge.getId()); }
|
||||
|
||||
loan.removeLoanCharge(loanCharge);
|
||||
this.loanRepository.save(loan);
|
||||
saveLoanWithDataIntegrityViolationChecks(loan);
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withCommandId(command.commandId()) //
|
||||
@@ -1448,7 +1466,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
loan.setLoanStatus(LoanStatus.TRANSFER_IN_PROGRESS.getValue());
|
||||
|
||||
this.loanTransactionRepository.save(newTransferTransaction);
|
||||
this.loanRepository.save(loan);
|
||||
saveLoanWithDataIntegrityViolationChecks(loan);
|
||||
|
||||
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);
|
||||
|
||||
@@ -1477,7 +1495,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
}
|
||||
|
||||
this.loanTransactionRepository.save(newTransferAcceptanceTransaction);
|
||||
this.loanRepository.save(loan);
|
||||
saveLoanWithDataIntegrityViolationChecks(loan);
|
||||
|
||||
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);
|
||||
|
||||
@@ -1497,7 +1515,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
loan.setLoanStatus(LoanStatus.ACTIVE.getValue());
|
||||
|
||||
this.loanTransactionRepository.save(newTransferAcceptanceTransaction);
|
||||
this.loanRepository.save(loan);
|
||||
saveLoanWithDataIntegrityViolationChecks(loan);
|
||||
|
||||
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);
|
||||
|
||||
@@ -1509,7 +1527,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
public void rejectLoanTransfer(final Long accountId) {
|
||||
final Loan loan = this.loanAssembler.assembleFrom(accountId);
|
||||
loan.setLoanStatus(LoanStatus.TRANSFER_ON_HOLD.getValue());
|
||||
this.loanRepository.save(loan);
|
||||
saveLoanWithDataIntegrityViolationChecks(loan);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@@ -1534,7 +1552,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
|
||||
loan.reassignLoanOfficer(toLoanOfficer, dateOfLoanOfficerAssignment);
|
||||
|
||||
this.loanRepository.save(loan);
|
||||
saveLoanWithDataIntegrityViolationChecks(loan);
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withCommandId(command.commandId()) //
|
||||
@@ -1570,7 +1588,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
if (!loan.hasLoanOfficer(fromLoanOfficer)) { throw new LoanOfficerAssignmentException(loanId, fromLoanOfficerId); }
|
||||
|
||||
loan.reassignLoanOfficer(toLoanOfficer, dateOfLoanOfficerAssignment);
|
||||
this.loanRepository.save(loan);
|
||||
saveLoanWithDataIntegrityViolationChecks(loan);
|
||||
}
|
||||
this.loanRepository.flush();
|
||||
|
||||
@@ -1598,7 +1616,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
|
||||
loan.removeLoanOfficer(dateOfLoanOfficerunAssigned);
|
||||
|
||||
this.loanRepository.save(loan);
|
||||
saveLoanWithDataIntegrityViolationChecks(loan);
|
||||
|
||||
return new CommandProcessingResultBuilder() //
|
||||
.withCommandId(command.commandId()) //
|
||||
@@ -1644,7 +1662,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loan.getOfficeId(), loan.getDisbursementDate().toDate());
|
||||
loan.updateLoanRepaymentScheduleDates(calendar.getStartDateLocalDate(), calendar.getRecurrence(), isHolidayEnabled,
|
||||
holidays, workingDays);
|
||||
this.loanRepository.save(loan);
|
||||
saveLoanWithDataIntegrityViolationChecks(loan);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2022,7 +2040,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
this.accountTransfersWritePlatformService.updateLoanTransaction(mapEntry.getKey(), mapEntry.getValue());
|
||||
}
|
||||
}
|
||||
this.loanRepository.save(loan);
|
||||
saveLoanWithDataIntegrityViolationChecks(loan);
|
||||
|
||||
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);
|
||||
return new CommandProcessingResultBuilder() //
|
||||
@@ -2064,7 +2082,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
existingTransactionIds, existingReversedTransactionIds, changes, this.loanScheduleFactory, applicationCurrency,
|
||||
calculatedRepaymentsStartingFromDate, isHolidayEnabled, holidays, workingDays, restCalendarInstance);
|
||||
|
||||
this.loanRepository.saveAndFlush(loan);
|
||||
saveAndFlushLoanWithDataIntegrityViolationChecks(loan);
|
||||
|
||||
if (changedTransactionDetail != null) {
|
||||
for (Map.Entry<Long, LoanTransaction> mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) {
|
||||
@@ -2191,7 +2209,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
calculatedRepaymentsStartingFromDate, isHolidayEnabled, holidays, workingDays, restCalendarInstance,
|
||||
existingTransactionIds, existingReversedTransactionIds);
|
||||
|
||||
this.loanRepository.save(loan);
|
||||
saveLoanWithDataIntegrityViolationChecks(loan);
|
||||
|
||||
if (changedTransactionDetail != null) {
|
||||
for (final Map.Entry<Long, LoanTransaction> mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) {
|
||||
|
||||
Reference in New Issue
Block a user