fix for MIFOSX-884
This commit is contained in:
+159
-162
@@ -295,7 +295,6 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
@Column(name = "max_outstanding_loan_balance", scale = 6, precision = 19, nullable = false)
|
@Column(name = "max_outstanding_loan_balance", scale = 6, precision = 19, nullable = false)
|
||||||
private BigDecimal maxOutstandingLoanBalance;
|
private BigDecimal maxOutstandingLoanBalance;
|
||||||
|
|
||||||
|
|
||||||
@LazyCollection(LazyCollectionOption.FALSE)
|
@LazyCollection(LazyCollectionOption.FALSE)
|
||||||
@OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true)
|
@OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true)
|
||||||
private Set<LoanDisbursementDetails> disbursementDetails = new HashSet<LoanDisbursementDetails>();
|
private Set<LoanDisbursementDetails> disbursementDetails = new HashSet<LoanDisbursementDetails>();
|
||||||
@@ -305,7 +304,6 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
@OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true)
|
@OneToMany(cascade = CascadeType.ALL, mappedBy = "loan", orphanRemoval = true)
|
||||||
private final Set<LoanTermVariations> loanTermVariations = new HashSet<LoanTermVariations>();
|
private final Set<LoanTermVariations> loanTermVariations = new HashSet<LoanTermVariations>();
|
||||||
|
|
||||||
|
|
||||||
public static Loan newIndividualLoanApplication(final String accountNo, final Client client, final Integer loanType,
|
public static Loan newIndividualLoanApplication(final String accountNo, final Client client, final Integer loanType,
|
||||||
final LoanProduct loanProduct, final Fund fund, final Staff officer, final CodeValue loanPurpose,
|
final LoanProduct loanProduct, final Fund fund, final Staff officer, final CodeValue loanPurpose,
|
||||||
final LoanTransactionProcessingStrategy transactionProcessingStrategy,
|
final LoanTransactionProcessingStrategy transactionProcessingStrategy,
|
||||||
@@ -317,7 +315,7 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
final Boolean syncDisbursementWithMeeting = null;
|
final Boolean syncDisbursementWithMeeting = null;
|
||||||
return new Loan(accountNo, client, group, loanType, fund, officer, loanPurpose, transactionProcessingStrategy, loanProduct,
|
return new Loan(accountNo, client, group, loanType, fund, officer, loanPurpose, transactionProcessingStrategy, loanProduct,
|
||||||
loanRepaymentScheduleDetail, status, loanCharges, collateral, syncDisbursementWithMeeting, fixedEmiAmount,
|
loanRepaymentScheduleDetail, status, loanCharges, collateral, syncDisbursementWithMeeting, fixedEmiAmount,
|
||||||
disbursementDetails,maxOutstandingLoanBalance);
|
disbursementDetails, maxOutstandingLoanBalance);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Loan newGroupLoanApplication(final String accountNo, final Group group, final Integer loanType,
|
public static Loan newGroupLoanApplication(final String accountNo, final Group group, final Integer loanType,
|
||||||
@@ -325,14 +323,14 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
final LoanTransactionProcessingStrategy transactionProcessingStrategy,
|
final LoanTransactionProcessingStrategy transactionProcessingStrategy,
|
||||||
final LoanProductRelatedDetail loanRepaymentScheduleDetail, final Set<LoanCharge> loanCharges,
|
final LoanProductRelatedDetail loanRepaymentScheduleDetail, final Set<LoanCharge> loanCharges,
|
||||||
final Boolean syncDisbursementWithMeeting, final BigDecimal fixedEmiAmount,
|
final Boolean syncDisbursementWithMeeting, final BigDecimal fixedEmiAmount,
|
||||||
final Set<LoanDisbursementDetails> disbursementDetails,final BigDecimal maxOutstandingLoanBalance) {
|
final Set<LoanDisbursementDetails> disbursementDetails, final BigDecimal maxOutstandingLoanBalance) {
|
||||||
final LoanStatus status = null;
|
final LoanStatus status = null;
|
||||||
final CodeValue loanPurpose = null;
|
final CodeValue loanPurpose = null;
|
||||||
final Set<LoanCollateral> collateral = null;
|
final Set<LoanCollateral> collateral = null;
|
||||||
final Client client = null;
|
final Client client = null;
|
||||||
return new Loan(accountNo, client, group, loanType, fund, officer, loanPurpose, transactionProcessingStrategy, loanProduct,
|
return new Loan(accountNo, client, group, loanType, fund, officer, loanPurpose, transactionProcessingStrategy, loanProduct,
|
||||||
loanRepaymentScheduleDetail, status, loanCharges, collateral, syncDisbursementWithMeeting, fixedEmiAmount,
|
loanRepaymentScheduleDetail, status, loanCharges, collateral, syncDisbursementWithMeeting, fixedEmiAmount,
|
||||||
disbursementDetails,maxOutstandingLoanBalance);
|
disbursementDetails, maxOutstandingLoanBalance);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Loan newIndividualLoanApplicationFromGroup(final String accountNo, final Client client, final Group group,
|
public static Loan newIndividualLoanApplicationFromGroup(final String accountNo, final Client client, final Group group,
|
||||||
@@ -340,13 +338,13 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
final LoanTransactionProcessingStrategy transactionProcessingStrategy,
|
final LoanTransactionProcessingStrategy transactionProcessingStrategy,
|
||||||
final LoanProductRelatedDetail loanRepaymentScheduleDetail, final Set<LoanCharge> loanCharges,
|
final LoanProductRelatedDetail loanRepaymentScheduleDetail, final Set<LoanCharge> loanCharges,
|
||||||
final Boolean syncDisbursementWithMeeting, final BigDecimal fixedEmiAmount,
|
final Boolean syncDisbursementWithMeeting, final BigDecimal fixedEmiAmount,
|
||||||
final Set<LoanDisbursementDetails> disbursementDetails,final BigDecimal maxOutstandingLoanBalance) {
|
final Set<LoanDisbursementDetails> disbursementDetails, final BigDecimal maxOutstandingLoanBalance) {
|
||||||
final LoanStatus status = null;
|
final LoanStatus status = null;
|
||||||
final CodeValue loanPurpose = null;
|
final CodeValue loanPurpose = null;
|
||||||
final Set<LoanCollateral> collateral = null;
|
final Set<LoanCollateral> collateral = null;
|
||||||
return new Loan(accountNo, client, group, loanType, fund, officer, loanPurpose, transactionProcessingStrategy, loanProduct,
|
return new Loan(accountNo, client, group, loanType, fund, officer, loanPurpose, transactionProcessingStrategy, loanProduct,
|
||||||
loanRepaymentScheduleDetail, status, loanCharges, collateral, syncDisbursementWithMeeting, fixedEmiAmount,
|
loanRepaymentScheduleDetail, status, loanCharges, collateral, syncDisbursementWithMeeting, fixedEmiAmount,
|
||||||
disbursementDetails,maxOutstandingLoanBalance);
|
disbursementDetails, maxOutstandingLoanBalance);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Loan() {
|
protected Loan() {
|
||||||
@@ -473,8 +471,6 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
|
|
||||||
validateChargeHasValidSpecifiedDateIfApplicable(loanCharge, getDisbursementDate(), getLastRepaymentPeriodDueDate());
|
validateChargeHasValidSpecifiedDateIfApplicable(loanCharge, getDisbursementDate(), getLastRepaymentPeriodDueDate());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
loanCharge.update(this);
|
loanCharge.update(this);
|
||||||
|
|
||||||
final BigDecimal amount = calculateAmountPercentageAppliedTo(loanCharge);
|
final BigDecimal amount = calculateAmountPercentageAppliedTo(loanCharge);
|
||||||
@@ -907,12 +903,15 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
|
|
||||||
public void updateLoanCharges(final Set<LoanCharge> loanCharges) {
|
public void updateLoanCharges(final Set<LoanCharge> loanCharges) {
|
||||||
List<Long> existingCharges = fetchAllLoanChargeIds();
|
List<Long> existingCharges = fetchAllLoanChargeIds();
|
||||||
|
|
||||||
|
/** Process new and updated charges **/
|
||||||
for (final LoanCharge loanCharge : loanCharges) {
|
for (final LoanCharge loanCharge : loanCharges) {
|
||||||
LoanCharge charge = loanCharge;
|
LoanCharge charge = loanCharge;
|
||||||
if(loanCharge.getId() == null){
|
// add new charges
|
||||||
|
if (loanCharge.getId() == null) {
|
||||||
loanCharge.update(this);
|
loanCharge.update(this);
|
||||||
this.charges.add(loanCharge);
|
this.charges.add(loanCharge);
|
||||||
}else{
|
} else {
|
||||||
charge = fetchLoanChargesById(charge.getId());
|
charge = fetchLoanChargesById(charge.getId());
|
||||||
existingCharges.remove(charge.getId());
|
existingCharges.remove(charge.getId());
|
||||||
}
|
}
|
||||||
@@ -933,7 +932,9 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
charge.update(chargeAmt, loanCharge.getDueLocalDate(), amount, repaymentScheduleDetail().getNumberOfRepayments(),
|
charge.update(chargeAmt, loanCharge.getDueLocalDate(), amount, repaymentScheduleDetail().getNumberOfRepayments(),
|
||||||
totalChargeAmt);
|
totalChargeAmt);
|
||||||
}
|
}
|
||||||
for(Long id:existingCharges){
|
|
||||||
|
/** Updated deleted charges **/
|
||||||
|
for (Long id : existingCharges) {
|
||||||
fetchLoanChargesById(id).setActive(false);
|
fetchLoanChargesById(id).setActive(false);
|
||||||
}
|
}
|
||||||
updateSummaryWithTotalFeeChargesDueAtDisbursement(deriveSumTotalOfChargesDueAtDisbursement());
|
updateSummaryWithTotalFeeChargesDueAtDisbursement(deriveSumTotalOfChargesDueAtDisbursement());
|
||||||
@@ -1245,17 +1246,19 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
if (command.isChangeInBigDecimalParameterNamed(LoanApiConstants.emiAmountParameterName, this.fixedEmiAmount)) {
|
if (command.isChangeInBigDecimalParameterNamed(LoanApiConstants.emiAmountParameterName, this.fixedEmiAmount)) {
|
||||||
this.fixedEmiAmount = command.bigDecimalValueOfParameterNamed(LoanApiConstants.emiAmountParameterName);
|
this.fixedEmiAmount = command.bigDecimalValueOfParameterNamed(LoanApiConstants.emiAmountParameterName);
|
||||||
}
|
}
|
||||||
if (command.isChangeInBigDecimalParameterNamed(LoanApiConstants.maxOutstandingBalanceParameterName, this.maxOutstandingLoanBalance)) {
|
if (command.isChangeInBigDecimalParameterNamed(LoanApiConstants.maxOutstandingBalanceParameterName,
|
||||||
this.maxOutstandingLoanBalance = command.bigDecimalValueOfParameterNamed(LoanApiConstants.maxOutstandingBalanceParameterName);
|
this.maxOutstandingLoanBalance)) {
|
||||||
|
this.maxOutstandingLoanBalance = command
|
||||||
|
.bigDecimalValueOfParameterNamed(LoanApiConstants.maxOutstandingBalanceParameterName);
|
||||||
}
|
}
|
||||||
if (this.disbursementDetails.isEmpty()) {
|
if (this.disbursementDetails.isEmpty()) {
|
||||||
final String errorMessage = "For this loan product, disbursement details must be provided";
|
final String errorMessage = "For this loan product, disbursement details must be provided";
|
||||||
throw new MultiDisbursementDataRequiredException(LoanApiConstants.disbursementDataParameterName, errorMessage);
|
throw new MultiDisbursementDataRequiredException(LoanApiConstants.disbursementDataParameterName, errorMessage);
|
||||||
}
|
}
|
||||||
if(disbursementDetails.size() > loanProduct.maxTrancheCount()){
|
if (disbursementDetails.size() > loanProduct.maxTrancheCount()) {
|
||||||
final String errorMessage = "Number of tranche shouldn't be greter than "+loanProduct.maxTrancheCount();
|
final String errorMessage = "Number of tranche shouldn't be greter than " + loanProduct.maxTrancheCount();
|
||||||
throw new ExceedingTrancheCountException(LoanApiConstants.disbursementDataParameterName, errorMessage,
|
throw new ExceedingTrancheCountException(LoanApiConstants.disbursementDataParameterName, errorMessage,
|
||||||
loanProduct.maxTrancheCount(),disbursementDetails.size());
|
loanProduct.maxTrancheCount(), disbursementDetails.size());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.disbursementDetails.clear();
|
this.disbursementDetails.clear();
|
||||||
@@ -1265,7 +1268,6 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
return actualChanges;
|
return actualChanges;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void updateDisbursementDetails(final JsonCommand command, final Map<String, Object> actualChanges) {
|
private void updateDisbursementDetails(final JsonCommand command, final Map<String, Object> actualChanges) {
|
||||||
|
|
||||||
List<Long> list = fetchDisbursementIds();
|
List<Long> list = fetchDisbursementIds();
|
||||||
@@ -1415,7 +1417,6 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
|
|
||||||
updateLoanSchedule(loanSchedule);
|
updateLoanSchedule(loanSchedule);
|
||||||
|
|
||||||
|
|
||||||
LoanStatus from = null;
|
LoanStatus from = null;
|
||||||
if (this.loanStatus != null) {
|
if (this.loanStatus != null) {
|
||||||
from = LoanStatus.fromInt(this.loanStatus);
|
from = LoanStatus.fromInt(this.loanStatus);
|
||||||
@@ -1685,9 +1686,9 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
return ids;
|
return ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void disburse(final LoanScheduleGeneratorFactory loanScheduleFactory, final AppUser currentUser,
|
public void disburse(final LoanScheduleGeneratorFactory loanScheduleFactory, final AppUser currentUser, final JsonCommand command,
|
||||||
final JsonCommand command, final ApplicationCurrency currency, final List<Long> existingTransactionIds,
|
final ApplicationCurrency currency, final List<Long> existingTransactionIds, final List<Long> existingReversedTransactionIds,
|
||||||
final List<Long> existingReversedTransactionIds, final Map<String, Object> actualChanges, final PaymentDetail paymentDetail,
|
final Map<String, Object> actualChanges, final PaymentDetail paymentDetail,
|
||||||
final LocalDate calculatedRepaymentsStartingFromDate, final boolean isHolidayEnabled, final List<Holiday> holidays,
|
final LocalDate calculatedRepaymentsStartingFromDate, final boolean isHolidayEnabled, final List<Holiday> holidays,
|
||||||
final WorkingDays workingDays, final boolean allowTransactionsOnHoliday, final boolean allowTransactionsOnNonWorkingDay) {
|
final WorkingDays workingDays, final boolean allowTransactionsOnHoliday, final boolean allowTransactionsOnNonWorkingDay) {
|
||||||
|
|
||||||
@@ -1698,15 +1699,16 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
LoanStatus.fromInt(this.loanStatus));
|
LoanStatus.fromInt(this.loanStatus));
|
||||||
boolean isMultiTrancheDisburse = false;
|
boolean isMultiTrancheDisburse = false;
|
||||||
final LocalDate actualDisbursementDate = command.localDateValueOfParameterNamed("actualDisbursementDate");
|
final LocalDate actualDisbursementDate = command.localDateValueOfParameterNamed("actualDisbursementDate");
|
||||||
if(LoanStatus.fromInt(this.loanStatus).isActive() && isAllTranchesNotDisbursed()){
|
if (LoanStatus.fromInt(this.loanStatus).isActive() && isAllTranchesNotDisbursed()) {
|
||||||
LoanDisbursementDetails details = fetchLastDisburseDetail();
|
LoanDisbursementDetails details = fetchLastDisburseDetail();
|
||||||
|
|
||||||
if(details != null){
|
if (details != null) {
|
||||||
lastDusburseDate = details.actualDisbursementDate();
|
lastDusburseDate = details.actualDisbursementDate();
|
||||||
}
|
}
|
||||||
if(actualDisbursementDate.toDate().before(lastDusburseDate)){
|
if (actualDisbursementDate.toDate().before(lastDusburseDate)) {
|
||||||
final String errorMsg = "Loan can't be disbursed before "+lastDusburseDate;
|
final String errorMsg = "Loan can't be disbursed before " + lastDusburseDate;
|
||||||
throw new LoanDisbursalException(errorMsg, "actualdisbursementdate.before.lastdusbursedate", lastDusburseDate,actualDisbursementDate.toDate());
|
throw new LoanDisbursalException(errorMsg, "actualdisbursementdate.before.lastdusbursedate", lastDusburseDate,
|
||||||
|
actualDisbursementDate.toDate());
|
||||||
}
|
}
|
||||||
isMultiTrancheDisburse = true;
|
isMultiTrancheDisburse = true;
|
||||||
}
|
}
|
||||||
@@ -1718,38 +1720,37 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
this.loanStatus = statusEnum.getValue();
|
this.loanStatus = statusEnum.getValue();
|
||||||
actualChanges.put("status", LoanEnumerations.status(this.loanStatus));
|
actualChanges.put("status", LoanEnumerations.status(this.loanStatus));
|
||||||
|
|
||||||
|
|
||||||
final String txnExternalId = command.stringValueOfParameterNamedAllowingNull("externalId");
|
final String txnExternalId = command.stringValueOfParameterNamedAllowingNull("externalId");
|
||||||
Money disburseAmount = this.loanRepaymentScheduleDetail.getPrincipal().zero();
|
Money disburseAmount = this.loanRepaymentScheduleDetail.getPrincipal().zero();
|
||||||
BigDecimal principalDisbursed = command.bigDecimalValueOfParameterNamed(LoanApiConstants.principalDisbursedParameterName);
|
BigDecimal principalDisbursed = command.bigDecimalValueOfParameterNamed(LoanApiConstants.principalDisbursedParameterName);
|
||||||
if(this.actualDisbursementDate == null){
|
if (this.actualDisbursementDate == null) {
|
||||||
this.actualDisbursementDate = actualDisbursementDate.toDate();
|
this.actualDisbursementDate = actualDisbursementDate.toDate();
|
||||||
}
|
}
|
||||||
BigDecimal diff = BigDecimal.ZERO;
|
BigDecimal diff = BigDecimal.ZERO;
|
||||||
Collection<LoanDisbursementDetails> details = fetchUndisbursedDetail();
|
Collection<LoanDisbursementDetails> details = fetchUndisbursedDetail();
|
||||||
if(principalDisbursed == null){
|
if (principalDisbursed == null) {
|
||||||
disburseAmount = this.loanRepaymentScheduleDetail.getPrincipal();
|
disburseAmount = this.loanRepaymentScheduleDetail.getPrincipal();
|
||||||
if(!details.isEmpty()){
|
if (!details.isEmpty()) {
|
||||||
disburseAmount = disburseAmount.zero();
|
disburseAmount = disburseAmount.zero();
|
||||||
for(LoanDisbursementDetails disbursementDetails:details){
|
for (LoanDisbursementDetails disbursementDetails : details) {
|
||||||
disbursementDetails.updateActualDisbursementDate(actualDisbursementDate.toDate());
|
disbursementDetails.updateActualDisbursementDate(actualDisbursementDate.toDate());
|
||||||
disburseAmount = disburseAmount.plus(disbursementDetails.principal());
|
disburseAmount = disburseAmount.plus(disbursementDetails.principal());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else{
|
} else {
|
||||||
disburseAmount = disburseAmount.plus(principalDisbursed);
|
disburseAmount = disburseAmount.plus(principalDisbursed);
|
||||||
|
|
||||||
if(details.isEmpty()){
|
if (details.isEmpty()) {
|
||||||
diff = this.loanRepaymentScheduleDetail.getPrincipal().minus(principalDisbursed).getAmount();
|
diff = this.loanRepaymentScheduleDetail.getPrincipal().minus(principalDisbursed).getAmount();
|
||||||
}else{
|
} else {
|
||||||
for(LoanDisbursementDetails disbursementDetails:details){
|
for (LoanDisbursementDetails disbursementDetails : details) {
|
||||||
disbursementDetails.updateActualDisbursementDate(actualDisbursementDate.toDate());
|
disbursementDetails.updateActualDisbursementDate(actualDisbursementDate.toDate());
|
||||||
diff = diff.add(disbursementDetails.principal().subtract(principalDisbursed));
|
diff = diff.add(disbursementDetails.principal().subtract(principalDisbursed));
|
||||||
disbursementDetails.updatePrincipal(principalDisbursed);
|
disbursementDetails.updatePrincipal(principalDisbursed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.loanRepaymentScheduleDetail.setPrincipal(this.loanRepaymentScheduleDetail.getPrincipal().minus(diff).getAmount());
|
this.loanRepaymentScheduleDetail.setPrincipal(this.loanRepaymentScheduleDetail.getPrincipal().minus(diff).getAmount());
|
||||||
if(diff.compareTo(BigDecimal.ZERO) == -1){
|
if (diff.compareTo(BigDecimal.ZERO) == -1) {
|
||||||
final String errorMsg = "Loan can't be disbursed,disburse amount is exceeding approved amount ";
|
final String errorMsg = "Loan can't be disbursed,disburse amount is exceeding approved amount ";
|
||||||
throw new LoanDisbursalException(errorMsg, "disburse.amount.must.be.less.than.approved.amount", principalDisbursed,
|
throw new LoanDisbursalException(errorMsg, "disburse.amount.must.be.less.than.approved.amount", principalDisbursed,
|
||||||
this.loanRepaymentScheduleDetail.getPrincipal().getAmount());
|
this.loanRepaymentScheduleDetail.getPrincipal().getAmount());
|
||||||
@@ -1766,15 +1767,17 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
validateDisbursementDateIsOnNonWorkingDay(workingDays, allowTransactionsOnNonWorkingDay);
|
validateDisbursementDateIsOnNonWorkingDay(workingDays, allowTransactionsOnNonWorkingDay);
|
||||||
validateDisbursementDateIsOnHoliday(allowTransactionsOnHoliday, holidays);
|
validateDisbursementDateIsOnHoliday(allowTransactionsOnHoliday, holidays);
|
||||||
|
|
||||||
handleDisbursementTransaction(paymentDetail, actualDisbursementDate, txnExternalId,disburseAmount);
|
handleDisbursementTransaction(paymentDetail, actualDisbursementDate, txnExternalId, disburseAmount);
|
||||||
BigDecimal emiAmount = command.bigDecimalValueOfParameterNamed(LoanApiConstants.emiAmountParameterName);
|
BigDecimal emiAmount = command.bigDecimalValueOfParameterNamed(LoanApiConstants.emiAmountParameterName);
|
||||||
boolean isEmiAmountChanged = false;
|
boolean isEmiAmountChanged = false;
|
||||||
if(this.loanProduct.isMultiDisburseLoan() && emiAmount != null && emiAmount.compareTo(retriveLastEmiAmount()) != 0){
|
if (this.loanProduct.isMultiDisburseLoan() && emiAmount != null && emiAmount.compareTo(retriveLastEmiAmount()) != 0) {
|
||||||
LoanTermVariations loanVariationTerms = new LoanTermVariations(LoanTermVariationType.EMI_AMOUNT.getValue(),actualDisbursementDate.toDate(),emiAmount,this);
|
LoanTermVariations loanVariationTerms = new LoanTermVariations(LoanTermVariationType.EMI_AMOUNT.getValue(),
|
||||||
|
actualDisbursementDate.toDate(), emiAmount, this);
|
||||||
this.loanTermVariations.add(loanVariationTerms);
|
this.loanTermVariations.add(loanVariationTerms);
|
||||||
isEmiAmountChanged = true;
|
isEmiAmountChanged = true;
|
||||||
}
|
}
|
||||||
if (isRepaymentScheduleRegenerationRequiredForDisbursement(actualDisbursementDate) || diff.compareTo(BigDecimal.ZERO) !=0 || isEmiAmountChanged) {
|
if (isRepaymentScheduleRegenerationRequiredForDisbursement(actualDisbursementDate) || diff.compareTo(BigDecimal.ZERO) != 0
|
||||||
|
|| isEmiAmountChanged) {
|
||||||
regenerateRepaymentSchedule(loanScheduleFactory, currency, calculatedRepaymentsStartingFromDate, isHolidayEnabled,
|
regenerateRepaymentSchedule(loanScheduleFactory, currency, calculatedRepaymentsStartingFromDate, isHolidayEnabled,
|
||||||
holidays, workingDays);
|
holidays, workingDays);
|
||||||
updateLoanRepaymentPeriodsDerivedFields(actualDisbursementDate);
|
updateLoanRepaymentPeriodsDerivedFields(actualDisbursementDate);
|
||||||
@@ -1788,22 +1791,23 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
actualDisbursementDate);
|
actualDisbursementDate);
|
||||||
this.loanTransactions.add(interestAppliedTransaction);
|
this.loanTransactions.add(interestAppliedTransaction);
|
||||||
|
|
||||||
// changedTransactionDetail = reprocessTransactionForDisbursement(changedTransactionDetail);
|
// changedTransactionDetail =
|
||||||
|
// reprocessTransactionForDisbursement(changedTransactionDetail);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChangedTransactionDetail reprocessTransactionForDisbursement() {
|
public ChangedTransactionDetail reprocessTransactionForDisbursement() {
|
||||||
ChangedTransactionDetail changedTransactionDetail = null;
|
ChangedTransactionDetail changedTransactionDetail = null;
|
||||||
for(LoanCharge loanCharge:this.charges){
|
for (LoanCharge loanCharge : this.charges) {
|
||||||
if (loanCharge.isInstalmentFee() && loanCharge.hasNoLoanInstallmentCharges()) {
|
if (loanCharge.isInstalmentFee() && loanCharge.hasNoLoanInstallmentCharges()) {
|
||||||
final Set<LoanInstallmentCharge> chargePerInstallments = generateInstallmentLoanCharges(loanCharge);
|
final Set<LoanInstallmentCharge> chargePerInstallments = generateInstallmentLoanCharges(loanCharge);
|
||||||
loanCharge.addLoanInstallmentCharges(chargePerInstallments);
|
loanCharge.addLoanInstallmentCharges(chargePerInstallments);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(this.loanProduct.isMultiDisburseLoan()){
|
if (this.loanProduct.isMultiDisburseLoan()) {
|
||||||
if(!this.actualDisbursementDate.equals(fetchLastDisburseDetail().getDisbursementDate())){
|
if (!this.actualDisbursementDate.equals(fetchLastDisburseDetail().getDisbursementDate())) {
|
||||||
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.transactionProcessorFactory
|
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.transactionProcessorFactory
|
||||||
.determineProcessor(this.transactionProcessingStrategy);
|
.determineProcessor(this.transactionProcessingStrategy);
|
||||||
final List<LoanTransaction> allNonContraTransactionsPostDisbursement = retreiveListOfTransactionsPostDisbursement();
|
final List<LoanTransaction> allNonContraTransactionsPostDisbursement = retreiveListOfTransactionsPostDisbursement();
|
||||||
@@ -1817,37 +1821,35 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
updateLoanSummaryDerivedFields();
|
updateLoanSummaryDerivedFields();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return changedTransactionDetail;
|
return changedTransactionDetail;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Collection<LoanDisbursementDetails> fetchUndisbursedDetail(){
|
private Collection<LoanDisbursementDetails> fetchUndisbursedDetail() {
|
||||||
Collection<LoanDisbursementDetails> disbursementDetails = new ArrayList<LoanDisbursementDetails>();
|
Collection<LoanDisbursementDetails> disbursementDetails = new ArrayList<LoanDisbursementDetails>();
|
||||||
Date date = null;
|
Date date = null;
|
||||||
for(LoanDisbursementDetails disbursementDetail:this.disbursementDetails){
|
for (LoanDisbursementDetails disbursementDetail : this.disbursementDetails) {
|
||||||
if(disbursementDetail.actualDisbursementDate() == null){
|
if (disbursementDetail.actualDisbursementDate() == null) {
|
||||||
if(date == null || disbursementDetail.expectedDisbursementDate().equals(date)){
|
if (date == null || disbursementDetail.expectedDisbursementDate().equals(date)) {
|
||||||
disbursementDetails.add(disbursementDetail);
|
disbursementDetails.add(disbursementDetail);
|
||||||
date =disbursementDetail.expectedDisbursementDate();
|
date = disbursementDetail.expectedDisbursementDate();
|
||||||
}else if(disbursementDetail.expectedDisbursementDate().before(date)){
|
} else if (disbursementDetail.expectedDisbursementDate().before(date)) {
|
||||||
disbursementDetails.clear();
|
disbursementDetails.clear();
|
||||||
disbursementDetails.add(disbursementDetail);
|
disbursementDetails.add(disbursementDetail);
|
||||||
date =disbursementDetail.expectedDisbursementDate();
|
date = disbursementDetail.expectedDisbursementDate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return disbursementDetails;
|
return disbursementDetails;
|
||||||
}
|
}
|
||||||
|
|
||||||
private LoanDisbursementDetails fetchLastDisburseDetail(){
|
private LoanDisbursementDetails fetchLastDisburseDetail() {
|
||||||
LoanDisbursementDetails details = null;
|
LoanDisbursementDetails details = null;
|
||||||
Date date = this.actualDisbursementDate;
|
Date date = this.actualDisbursementDate;
|
||||||
if(date != null){
|
if (date != null) {
|
||||||
for(LoanDisbursementDetails disbursementDetail:this.disbursementDetails){
|
for (LoanDisbursementDetails disbursementDetail : this.disbursementDetails) {
|
||||||
if(disbursementDetail.actualDisbursementDate() != null){
|
if (disbursementDetail.actualDisbursementDate() != null) {
|
||||||
if(disbursementDetail.actualDisbursementDate().after(date) ||
|
if (disbursementDetail.actualDisbursementDate().after(date) || disbursementDetail.actualDisbursementDate().equals(date)) {
|
||||||
disbursementDetail.actualDisbursementDate().equals(date)){
|
date = disbursementDetail.actualDisbursementDate();
|
||||||
date =disbursementDetail.actualDisbursementDate();
|
|
||||||
details = disbursementDetail;
|
details = disbursementDetail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1856,29 +1858,29 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
return details;
|
return details;
|
||||||
}
|
}
|
||||||
|
|
||||||
private BigDecimal getDisbursedAmount(){
|
private BigDecimal getDisbursedAmount() {
|
||||||
BigDecimal principal = BigDecimal.ZERO;
|
BigDecimal principal = BigDecimal.ZERO;
|
||||||
for(LoanDisbursementDetails disbursementDetail:this.disbursementDetails){
|
for (LoanDisbursementDetails disbursementDetail : this.disbursementDetails) {
|
||||||
if(disbursementDetail.actualDisbursementDate() != null){
|
if (disbursementDetail.actualDisbursementDate() != null) {
|
||||||
principal = principal.add(disbursementDetail.principal());
|
principal = principal.add(disbursementDetail.principal());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return principal;
|
return principal;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeDisbursementDetail(){
|
private void removeDisbursementDetail() {
|
||||||
Set<LoanDisbursementDetails> details = new HashSet<LoanDisbursementDetails>(this.disbursementDetails);
|
Set<LoanDisbursementDetails> details = new HashSet<LoanDisbursementDetails>(this.disbursementDetails);
|
||||||
for(LoanDisbursementDetails disbursementDetail:details){
|
for (LoanDisbursementDetails disbursementDetail : details) {
|
||||||
if(disbursementDetail.actualDisbursementDate() == null){
|
if (disbursementDetail.actualDisbursementDate() == null) {
|
||||||
this.disbursementDetails.remove(disbursementDetail);
|
this.disbursementDetails.remove(disbursementDetail);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isDisbursementAllowed(){
|
private boolean isDisbursementAllowed() {
|
||||||
boolean isAllowed = false;
|
boolean isAllowed = false;
|
||||||
for(LoanDisbursementDetails disbursementDetail:this.disbursementDetails){
|
for (LoanDisbursementDetails disbursementDetail : this.disbursementDetails) {
|
||||||
if(disbursementDetail.actualDisbursementDate() == null){
|
if (disbursementDetail.actualDisbursementDate() == null) {
|
||||||
isAllowed = true;
|
isAllowed = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1886,10 +1888,10 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
return isAllowed;
|
return isAllowed;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean atleastOnceDisbursed(){
|
private boolean atleastOnceDisbursed() {
|
||||||
boolean isDisbursed = false;
|
boolean isDisbursed = false;
|
||||||
for(LoanDisbursementDetails disbursementDetail:this.disbursementDetails){
|
for (LoanDisbursementDetails disbursementDetail : this.disbursementDetails) {
|
||||||
if(disbursementDetail.actualDisbursementDate() != null){
|
if (disbursementDetail.actualDisbursementDate() != null) {
|
||||||
isDisbursed = true;
|
isDisbursed = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1926,26 +1928,27 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
}
|
}
|
||||||
final List<LoanTermVariationsData> loanVariationTermsData = new ArrayList<LoanTermVariationsData>();
|
final List<LoanTermVariationsData> loanVariationTermsData = new ArrayList<LoanTermVariationsData>();
|
||||||
boolean isDefaultEmiAmountReq = true;
|
boolean isDefaultEmiAmountReq = true;
|
||||||
for(LoanTermVariations variationTerms:this.loanTermVariations){
|
for (LoanTermVariations variationTerms : this.loanTermVariations) {
|
||||||
if(variationTerms.getTermType().isEMIAmountVariation()){
|
if (variationTerms.getTermType().isEMIAmountVariation()) {
|
||||||
if(variationTerms.getTermApplicableFrom().equals(this.getDisbursementDate().toDate())){
|
if (variationTerms.getTermApplicableFrom().equals(this.getDisbursementDate().toDate())) {
|
||||||
isDefaultEmiAmountReq =false;
|
isDefaultEmiAmountReq = false;
|
||||||
}
|
}
|
||||||
loanVariationTermsData.add(variationTerms.toData());
|
loanVariationTermsData.add(variationTerms.toData());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(isDefaultEmiAmountReq){
|
if (isDefaultEmiAmountReq) {
|
||||||
LoanTermVariationsData data = new LoanTermVariationsData(null, LoanEnumerations.loanvariationType(LoanTermVariationType.EMI_AMOUNT), this.getDisbursementDate(), this.fixedEmiAmount);
|
LoanTermVariationsData data = new LoanTermVariationsData(null,
|
||||||
|
LoanEnumerations.loanvariationType(LoanTermVariationType.EMI_AMOUNT), this.getDisbursementDate(), this.fixedEmiAmount);
|
||||||
loanVariationTermsData.add(data);
|
loanVariationTermsData.add(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
final LoanApplicationTerms loanApplicationTerms = LoanApplicationTerms
|
final LoanApplicationTerms loanApplicationTerms = LoanApplicationTerms.assembleFrom(applicationCurrency, loanTermFrequency,
|
||||||
.assembleFrom(applicationCurrency, loanTermFrequency, loanTermPeriodFrequencyType, getDisbursementDate(),
|
loanTermPeriodFrequencyType, getDisbursementDate(), getExpectedFirstRepaymentOnDate(),
|
||||||
getExpectedFirstRepaymentOnDate(), calculatedRepaymentsStartingFromDate, getInArrearsTolerance(),
|
calculatedRepaymentsStartingFromDate, getInArrearsTolerance(), this.loanRepaymentScheduleDetail,
|
||||||
this.loanRepaymentScheduleDetail, this.loanProduct.isMultiDisburseLoan(), this.fixedEmiAmount, disbursementData,
|
this.loanProduct.isMultiDisburseLoan(), this.fixedEmiAmount, disbursementData, this.maxOutstandingLoanBalance,
|
||||||
this.maxOutstandingLoanBalance,loanVariationTermsData);
|
loanVariationTermsData);
|
||||||
|
|
||||||
final LoanScheduleModel loanSchedule = loanScheduleGenerator.generate(mc, applicationCurrency, loanApplicationTerms,charges(),
|
final LoanScheduleModel loanSchedule = loanScheduleGenerator.generate(mc, applicationCurrency, loanApplicationTerms, charges(),
|
||||||
isHolidayEnabled, holidays, workingDays);
|
isHolidayEnabled, holidays, workingDays);
|
||||||
|
|
||||||
updateLoanSchedule(loanSchedule);
|
updateLoanSchedule(loanSchedule);
|
||||||
@@ -1954,8 +1957,8 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
private LoanTransaction handleDisbursementTransaction(final PaymentDetail paymentDetail, final LocalDate disbursedOn,
|
private LoanTransaction handleDisbursementTransaction(final PaymentDetail paymentDetail, final LocalDate disbursedOn,
|
||||||
final String txnExternalId, Money disburseAmt) {
|
final String txnExternalId, Money disburseAmt) {
|
||||||
// track disbursement transaction
|
// track disbursement transaction
|
||||||
final LoanTransaction disbursementTransaction = LoanTransaction.disbursement(getOffice(),
|
final LoanTransaction disbursementTransaction = LoanTransaction.disbursement(getOffice(), disburseAmt, paymentDetail, disbursedOn,
|
||||||
disburseAmt, paymentDetail, disbursedOn, txnExternalId);
|
txnExternalId);
|
||||||
disbursementTransaction.updateLoan(this);
|
disbursementTransaction.updateLoan(this);
|
||||||
this.loanTransactions.add(disbursementTransaction);
|
this.loanTransactions.add(disbursementTransaction);
|
||||||
|
|
||||||
@@ -1972,13 +1975,14 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
* "APPLY Charge" transactions are created for all other fees ( which
|
* "APPLY Charge" transactions are created for all other fees ( which
|
||||||
* are created during disbursal but not repaid)
|
* are created during disbursal but not repaid)
|
||||||
**/
|
**/
|
||||||
if(disbursedOn.toDate().equals(this.actualDisbursementDate)){
|
if (disbursedOn.toDate().equals(this.actualDisbursementDate)) {
|
||||||
Money disbursentMoney = Money.zero(getCurrency());
|
Money disbursentMoney = Money.zero(getCurrency());
|
||||||
final LoanTransaction chargesPayment = LoanTransaction.repaymentAtDisbursement(getOffice(), disbursentMoney, null, disbursedOn,
|
final LoanTransaction chargesPayment = LoanTransaction.repaymentAtDisbursement(getOffice(), disbursentMoney, null, disbursedOn,
|
||||||
null);
|
null);
|
||||||
for (final LoanCharge charge : charges()) {
|
for (final LoanCharge charge : charges()) {
|
||||||
if (charge.isDueAtDisbursement()) {
|
if (charge.isDueAtDisbursement()) {
|
||||||
if (totalFeeChargesDueAtDisbursement.isGreaterThanZero() && !charge.getChargePaymentMode().isPaymentModeAccountTransfer()) {
|
if (totalFeeChargesDueAtDisbursement.isGreaterThanZero()
|
||||||
|
&& !charge.getChargePaymentMode().isPaymentModeAccountTransfer()) {
|
||||||
charge.markAsFullyPaid();
|
charge.markAsFullyPaid();
|
||||||
// Add "Loan Charge Paid By" details to this transaction
|
// Add "Loan Charge Paid By" details to this transaction
|
||||||
final LoanChargePaidBy loanChargePaidBy = new LoanChargePaidBy(chargesPayment, charge, charge.amount());
|
final LoanChargePaidBy loanChargePaidBy = new LoanChargePaidBy(chargesPayment, charge, charge.amount());
|
||||||
@@ -2004,14 +2008,13 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
getApprovedOnDate());
|
getApprovedOnDate());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(getExpectedFirstRepaymentOnDate() != null && disbursedOn.isAfter(getExpectedFirstRepaymentOnDate()))
|
if (getExpectedFirstRepaymentOnDate() != null && disbursedOn.isAfter(getExpectedFirstRepaymentOnDate())) {
|
||||||
{
|
final String errorMessage = "submittedOnDate cannot be after the loans expectedFirstRepaymentOnDate: "
|
||||||
final String errorMessage = "submittedOnDate cannot be after the loans expectedFirstRepaymentOnDate: " + getExpectedFirstRepaymentOnDate().toString();
|
+ getExpectedFirstRepaymentOnDate().toString();
|
||||||
throw new InvalidLoanStateTransitionException("disbursal", "cannot.be.after.expected.first.repayment.date", errorMessage, disbursedOn,
|
throw new InvalidLoanStateTransitionException("disbursal", "cannot.be.after.expected.first.repayment.date", errorMessage,
|
||||||
getExpectedFirstRepaymentOnDate());
|
disbursedOn, getExpectedFirstRepaymentOnDate());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
validateActivityNotBeforeClientOrGroupTransferDate(LoanEvent.LOAN_DISBURSED, disbursedOn);
|
validateActivityNotBeforeClientOrGroupTransferDate(LoanEvent.LOAN_DISBURSED, disbursedOn);
|
||||||
|
|
||||||
if (disbursedOn.isAfter(new LocalDate())) {
|
if (disbursedOn.isAfter(new LocalDate())) {
|
||||||
@@ -2065,13 +2068,13 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
this.disbursedBy = null;
|
this.disbursedBy = null;
|
||||||
boolean isDisbueseAmtChanged = !this.approvedPrincipal.equals(this.loanRepaymentScheduleDetail.getPrincipal());
|
boolean isDisbueseAmtChanged = !this.approvedPrincipal.equals(this.loanRepaymentScheduleDetail.getPrincipal());
|
||||||
this.loanRepaymentScheduleDetail.setPrincipal(this.approvedPrincipal);
|
this.loanRepaymentScheduleDetail.setPrincipal(this.approvedPrincipal);
|
||||||
if(this.loanProduct.isMultiDisburseLoan()){
|
if (this.loanProduct.isMultiDisburseLoan()) {
|
||||||
for(final LoanDisbursementDetails details:this.disbursementDetails){
|
for (final LoanDisbursementDetails details : this.disbursementDetails) {
|
||||||
details.updateActualDisbursementDate(null);
|
details.updateActualDisbursementDate(null);
|
||||||
details.resetPrincipal();
|
details.resetPrincipal();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
boolean isEmiAmountChanged = this.loanTermVariations.size()>0;
|
boolean isEmiAmountChanged = this.loanTermVariations.size() > 0;
|
||||||
updateLoanToPreDisbursalState();
|
updateLoanToPreDisbursalState();
|
||||||
if (isScheduleRegenerateRequired || isDisbueseAmtChanged || isEmiAmountChanged) {
|
if (isScheduleRegenerateRequired || isDisbueseAmtChanged || isEmiAmountChanged) {
|
||||||
// clear off actual disbusrement date so schedule regeneration
|
// clear off actual disbusrement date so schedule regeneration
|
||||||
@@ -2262,9 +2265,9 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(this.loanProduct.isMultiDisburseLoan() && adjustedTransaction == null){
|
if (this.loanProduct.isMultiDisburseLoan() && adjustedTransaction == null) {
|
||||||
BigDecimal totalDisbursed = getDisbursedAmount();
|
BigDecimal totalDisbursed = getDisbursedAmount();
|
||||||
if(totalDisbursed.compareTo(this.summary.getTotalPrincipalRepaid())<0){
|
if (totalDisbursed.compareTo(this.summary.getTotalPrincipalRepaid()) < 0) {
|
||||||
final String errorMessage = "The transaction cannot be done before the loan disbursement: "
|
final String errorMessage = "The transaction cannot be done before the loan disbursement: "
|
||||||
+ getApprovedOnDate().toString();
|
+ getApprovedOnDate().toString();
|
||||||
throw new InvalidLoanStateTransitionException("transaction", "cannot.be.done.before.disbursement", errorMessage);
|
throw new InvalidLoanStateTransitionException("transaction", "cannot.be.done.before.disbursement", errorMessage);
|
||||||
@@ -2324,8 +2327,7 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
|
|
||||||
boolean isAllChargesPaid = true;
|
boolean isAllChargesPaid = true;
|
||||||
for (final LoanCharge loanCharge : this.charges) {
|
for (final LoanCharge loanCharge : this.charges) {
|
||||||
if (loanCharge.isActive()
|
if (loanCharge.isActive() && !(loanCharge.isPaid() || loanCharge.isWaived())) {
|
||||||
&& !(loanCharge.isPaid() || loanCharge.isWaived())) {
|
|
||||||
isAllChargesPaid = false;
|
isAllChargesPaid = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2511,7 +2513,7 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
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) {
|
||||||
|
|
||||||
validateAccountStatus(LoanEvent.WRITE_OFF_OUTSTANDING_UNDO);
|
validateAccountStatus(LoanEvent.WRITE_OFF_OUTSTANDING_UNDO);
|
||||||
existingTransactionIds.addAll(findExistingTransactionIds());
|
existingTransactionIds.addAll(findExistingTransactionIds());
|
||||||
@@ -2579,15 +2581,14 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
|
|
||||||
public ChangedTransactionDetail closeAsWrittenOff(final JsonCommand command, final LoanLifecycleStateMachine loanLifecycleStateMachine,
|
public ChangedTransactionDetail closeAsWrittenOff(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 AppUser currentUser,final LoanScheduleGeneratorFactory loanScheduleFactory, final ApplicationCurrency currency,
|
final AppUser currentUser, final LoanScheduleGeneratorFactory loanScheduleFactory, final ApplicationCurrency currency,
|
||||||
final LocalDate calculatedRepaymentsStartingFromDate, final boolean isHolidayEnabled, final List<Holiday> holidays,
|
final LocalDate calculatedRepaymentsStartingFromDate, final boolean isHolidayEnabled, final List<Holiday> holidays,
|
||||||
final WorkingDays workingDays) {
|
final WorkingDays workingDays) {
|
||||||
|
|
||||||
|
|
||||||
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.transactionProcessorFactory
|
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.transactionProcessorFactory
|
||||||
.determineProcessor(this.transactionProcessingStrategy);
|
.determineProcessor(this.transactionProcessingStrategy);
|
||||||
ChangedTransactionDetail changedTransactionDetail = closeDisbursements(loanScheduleFactory, currency, calculatedRepaymentsStartingFromDate, isHolidayEnabled, holidays,
|
ChangedTransactionDetail changedTransactionDetail = closeDisbursements(loanScheduleFactory, currency,
|
||||||
workingDays, loanRepaymentScheduleTransactionProcessor);
|
calculatedRepaymentsStartingFromDate, isHolidayEnabled, holidays, workingDays, loanRepaymentScheduleTransactionProcessor);
|
||||||
|
|
||||||
validateAccountStatus(LoanEvent.WRITE_OFF_OUTSTANDING);
|
validateAccountStatus(LoanEvent.WRITE_OFF_OUTSTANDING);
|
||||||
|
|
||||||
@@ -2639,22 +2640,23 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
|
|
||||||
updateLoanSummaryDerivedFields();
|
updateLoanSummaryDerivedFields();
|
||||||
}
|
}
|
||||||
if(changedTransactionDetail == null){
|
if (changedTransactionDetail == null) {
|
||||||
changedTransactionDetail = new ChangedTransactionDetail();
|
changedTransactionDetail = new ChangedTransactionDetail();
|
||||||
}
|
}
|
||||||
changedTransactionDetail.getNewTransactionMappings().put(0L, loanTransaction);
|
changedTransactionDetail.getNewTransactionMappings().put(0L, loanTransaction);
|
||||||
return changedTransactionDetail;
|
return changedTransactionDetail;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ChangedTransactionDetail closeDisbursements(final LoanScheduleGeneratorFactory loanScheduleFactory, final ApplicationCurrency currency,
|
private ChangedTransactionDetail closeDisbursements(final LoanScheduleGeneratorFactory loanScheduleFactory,
|
||||||
final LocalDate calculatedRepaymentsStartingFromDate, final boolean isHolidayEnabled, final List<Holiday> holidays,
|
final ApplicationCurrency currency, final LocalDate calculatedRepaymentsStartingFromDate, final boolean isHolidayEnabled,
|
||||||
final WorkingDays workingDays, final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor) {
|
final List<Holiday> holidays, final WorkingDays workingDays,
|
||||||
|
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(loanScheduleFactory, currency, calculatedRepaymentsStartingFromDate, isHolidayEnabled,
|
regenerateRepaymentSchedule(loanScheduleFactory, currency, calculatedRepaymentsStartingFromDate, isHolidayEnabled, holidays,
|
||||||
holidays, workingDays);
|
workingDays);
|
||||||
|
|
||||||
final List<LoanTransaction> allNonContraTransactionsPostDisbursement = retreiveListOfTransactionsPostDisbursement();
|
final List<LoanTransaction> allNonContraTransactionsPostDisbursement = retreiveListOfTransactionsPostDisbursement();
|
||||||
changedTransactionDetail = loanRepaymentScheduleTransactionProcessor.handleTransaction(getDisbursementDate(),
|
changedTransactionDetail = loanRepaymentScheduleTransactionProcessor.handleTransaction(getDisbursementDate(),
|
||||||
@@ -2670,11 +2672,11 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
return changedTransactionDetail;
|
return changedTransactionDetail;
|
||||||
}
|
}
|
||||||
|
|
||||||
private LoanTransaction findlatestTransaction(){
|
private LoanTransaction findlatestTransaction() {
|
||||||
LoanTransaction transaction = null;
|
LoanTransaction transaction = null;
|
||||||
for(LoanTransaction loanTransaction:this.loanTransactions){
|
for (LoanTransaction loanTransaction : this.loanTransactions) {
|
||||||
if(!loanTransaction.isReversed() &&
|
if (!loanTransaction.isReversed()
|
||||||
(transaction == null || transaction.getTransactionDate().isBefore(loanTransaction.getTransactionDate()))){
|
&& (transaction == null || transaction.getTransactionDate().isBefore(loanTransaction.getTransactionDate()))) {
|
||||||
transaction = loanTransaction;
|
transaction = loanTransaction;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2687,7 +2689,6 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
final LocalDate calculatedRepaymentsStartingFromDate, final boolean isHolidayEnabled, final List<Holiday> holidays,
|
final LocalDate calculatedRepaymentsStartingFromDate, final boolean isHolidayEnabled, final List<Holiday> holidays,
|
||||||
final WorkingDays workingDays) {
|
final WorkingDays workingDays) {
|
||||||
|
|
||||||
|
|
||||||
validateAccountStatus(LoanEvent.LOAN_CLOSED);
|
validateAccountStatus(LoanEvent.LOAN_CLOSED);
|
||||||
|
|
||||||
existingTransactionIds.addAll(findExistingTransactionIds());
|
existingTransactionIds.addAll(findExistingTransactionIds());
|
||||||
@@ -2713,8 +2714,8 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
}
|
}
|
||||||
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.transactionProcessorFactory
|
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.transactionProcessorFactory
|
||||||
.determineProcessor(this.transactionProcessingStrategy);
|
.determineProcessor(this.transactionProcessingStrategy);
|
||||||
ChangedTransactionDetail changedTransactionDetail = closeDisbursements(loanScheduleFactory, currency, calculatedRepaymentsStartingFromDate, isHolidayEnabled, holidays,
|
ChangedTransactionDetail changedTransactionDetail = closeDisbursements(loanScheduleFactory, currency,
|
||||||
workingDays, loanRepaymentScheduleTransactionProcessor);
|
calculatedRepaymentsStartingFromDate, isHolidayEnabled, holidays, workingDays, loanRepaymentScheduleTransactionProcessor);
|
||||||
|
|
||||||
LoanTransaction loanTransaction = null;
|
LoanTransaction loanTransaction = null;
|
||||||
if (isOpen()) {
|
if (isOpen()) {
|
||||||
@@ -2768,7 +2769,7 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(changedTransactionDetail == null){
|
if (changedTransactionDetail == null) {
|
||||||
changedTransactionDetail = new ChangedTransactionDetail();
|
changedTransactionDetail = new ChangedTransactionDetail();
|
||||||
}
|
}
|
||||||
changedTransactionDetail.getNewTransactionMappings().put(0L, loanTransaction);
|
changedTransactionDetail.getNewTransactionMappings().put(0L, loanTransaction);
|
||||||
@@ -2866,10 +2867,9 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
return status().isActive();
|
return status().isActive();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isAllTranchesNotDisbursed(){
|
private boolean isAllTranchesNotDisbursed() {
|
||||||
return this.loanProduct.isMultiDisburseLoan()
|
return this.loanProduct.isMultiDisburseLoan()
|
||||||
&& (LoanStatus.fromInt(this.loanStatus).isActive()
|
&& (LoanStatus.fromInt(this.loanStatus).isActive() || LoanStatus.fromInt(this.loanStatus).isApproved())
|
||||||
||LoanStatus.fromInt(this.loanStatus).isApproved())
|
|
||||||
&& isDisbursementAllowed();
|
&& isDisbursementAllowed();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2916,7 +2916,7 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
return disbursementDate;
|
return disbursementDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LocalDate getExpectedDisbursedOnLocalDateForTemplate(){
|
public LocalDate getExpectedDisbursedOnLocalDateForTemplate() {
|
||||||
|
|
||||||
LocalDate expectedDisbursementDate = null;
|
LocalDate expectedDisbursementDate = null;
|
||||||
if (this.expectedDisbursementDate != null) {
|
if (this.expectedDisbursementDate != null) {
|
||||||
@@ -2924,20 +2924,20 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Collection<LoanDisbursementDetails> details = fetchUndisbursedDetail();
|
Collection<LoanDisbursementDetails> details = fetchUndisbursedDetail();
|
||||||
if(!details.isEmpty()){
|
if (!details.isEmpty()) {
|
||||||
for(LoanDisbursementDetails disbursementDetails:details){
|
for (LoanDisbursementDetails disbursementDetails : details) {
|
||||||
expectedDisbursementDate = new LocalDate(disbursementDetails.expectedDisbursementDate());
|
expectedDisbursementDate = new LocalDate(disbursementDetails.expectedDisbursementDate());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return expectedDisbursementDate;
|
return expectedDisbursementDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BigDecimal getDisburseAmountForTemplate(){
|
public BigDecimal getDisburseAmountForTemplate() {
|
||||||
BigDecimal principal = this.loanRepaymentScheduleDetail.getPrincipal().getAmount();
|
BigDecimal principal = this.loanRepaymentScheduleDetail.getPrincipal().getAmount();
|
||||||
Collection<LoanDisbursementDetails> details = fetchUndisbursedDetail();
|
Collection<LoanDisbursementDetails> details = fetchUndisbursedDetail();
|
||||||
if(!details.isEmpty()){
|
if (!details.isEmpty()) {
|
||||||
principal =BigDecimal.ZERO;
|
principal = BigDecimal.ZERO;
|
||||||
for(LoanDisbursementDetails disbursementDetails:details){
|
for (LoanDisbursementDetails disbursementDetails : details) {
|
||||||
principal = principal.add(disbursementDetails.principal());
|
principal = principal.add(disbursementDetails.principal());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2959,9 +2959,9 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
|
|
||||||
private boolean isActualDisbursedOnDateEarlierOrLaterThanExpected(final LocalDate actualDisbursedOnDate) {
|
private boolean isActualDisbursedOnDateEarlierOrLaterThanExpected(final LocalDate actualDisbursedOnDate) {
|
||||||
boolean isRegenerationRequired = false;
|
boolean isRegenerationRequired = false;
|
||||||
if(this.loanProduct.isMultiDisburseLoan()){
|
if (this.loanProduct.isMultiDisburseLoan()) {
|
||||||
LoanDisbursementDetails details = fetchLastDisburseDetail();
|
LoanDisbursementDetails details = fetchLastDisburseDetail();
|
||||||
if(!details.expectedDisbursementDate().equals(details.actualDisbursementDate())){
|
if (!details.expectedDisbursementDate().equals(details.actualDisbursementDate())) {
|
||||||
isRegenerationRequired = true;
|
isRegenerationRequired = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3399,8 +3399,6 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public Group group() {
|
public Group group() {
|
||||||
return this.group;
|
return this.group;
|
||||||
}
|
}
|
||||||
@@ -3414,9 +3412,7 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Integer getLoanProductLoanCounter() {
|
public Integer getLoanProductLoanCounter() {
|
||||||
if(this.loanProductCounter == null){
|
if (this.loanProductCounter == null) { return 0; }
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return this.loanProductCounter;
|
return this.loanProductCounter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3533,9 +3529,9 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
|
|
||||||
public Set<LoanCharge> charges() {
|
public Set<LoanCharge> charges() {
|
||||||
Set<LoanCharge> loanCharges = new HashSet<LoanCharge>();
|
Set<LoanCharge> loanCharges = new HashSet<LoanCharge>();
|
||||||
if(this.charges != null){
|
if (this.charges != null) {
|
||||||
for(LoanCharge charge:this.charges){
|
for (LoanCharge charge : this.charges) {
|
||||||
if(charge.isActive()){
|
if (charge.isActive()) {
|
||||||
loanCharges.add(charge);
|
loanCharges.add(charge);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3585,8 +3581,8 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case LOAN_DISBURSED:
|
case LOAN_DISBURSED:
|
||||||
if ((!(isApproved() && isNotDisbursed()) && !this.loanProduct.isMultiDisburseLoan()) ||
|
if ((!(isApproved() && isNotDisbursed()) && !this.loanProduct.isMultiDisburseLoan())
|
||||||
(this.loanProduct.isMultiDisburseLoan() && !isAllTranchesNotDisbursed())) {
|
|| (this.loanProduct.isMultiDisburseLoan() && !isAllTranchesNotDisbursed())) {
|
||||||
final String defaultUserMessage = "Loan Disbursal is not allowed. Loan Account is not in approved and not disbursed state.";
|
final String defaultUserMessage = "Loan Disbursal is not allowed. Loan Account is not in approved and not disbursed state.";
|
||||||
final ApiParameterError error = ApiParameterError.generalError(
|
final ApiParameterError error = ApiParameterError.generalError(
|
||||||
"error.msg.loan.disbursal.account.is.not.approve.not.disbursed.state", defaultUserMessage);
|
"error.msg.loan.disbursal.account.is.not.approve.not.disbursed.state", defaultUserMessage);
|
||||||
@@ -3698,41 +3694,42 @@ public class Loan extends AbstractPersistable<Long> {
|
|||||||
return this.disbursementDetails;
|
return this.disbursementDetails;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChangedTransactionDetail updateDisbursementDateForTranche(final LoanDisbursementDetails disbursementDetails,final JsonCommand command,final List<Long> existingTransactionIds,
|
public ChangedTransactionDetail updateDisbursementDateForTranche(final LoanDisbursementDetails disbursementDetails,
|
||||||
final List<Long> existingReversedTransactionIds, final Map<String, Object> actualChanges,
|
final JsonCommand command, final List<Long> existingTransactionIds, final List<Long> existingReversedTransactionIds,
|
||||||
final LoanScheduleGeneratorFactory loanScheduleFactory, final ApplicationCurrency currency,
|
final Map<String, Object> actualChanges, final LoanScheduleGeneratorFactory loanScheduleFactory,
|
||||||
final LocalDate calculatedRepaymentsStartingFromDate, final boolean isHolidayEnabled, final List<Holiday> holidays,
|
final ApplicationCurrency currency, final LocalDate calculatedRepaymentsStartingFromDate, final boolean isHolidayEnabled,
|
||||||
final WorkingDays workingDays){
|
final List<Holiday> holidays, final WorkingDays workingDays) {
|
||||||
validateAccountStatus(LoanEvent.LOAN_EDIT_MULTI_DISBURSE_DATE);
|
validateAccountStatus(LoanEvent.LOAN_EDIT_MULTI_DISBURSE_DATE);
|
||||||
final LocalDate expectedDisbursementDate = command.localDateValueOfParameterNamed(LoanApiConstants.disbursementDateParameterName);
|
final LocalDate expectedDisbursementDate = command.localDateValueOfParameterNamed(LoanApiConstants.disbursementDateParameterName);
|
||||||
disbursementDetails.updateExpectedDisbursementDate(expectedDisbursementDate.toDate());
|
disbursementDetails.updateExpectedDisbursementDate(expectedDisbursementDate.toDate());
|
||||||
actualChanges.put(LoanApiConstants.disbursementDateParameterName, command.stringValueOfParameterNamed(LoanApiConstants.disbursementDateParameterName));
|
actualChanges.put(LoanApiConstants.disbursementDateParameterName,
|
||||||
actualChanges.put(LoanApiConstants.disbursementIdParameterName, command.stringValueOfParameterNamed(LoanApiConstants.disbursementIdParameterName));
|
command.stringValueOfParameterNamed(LoanApiConstants.disbursementDateParameterName));
|
||||||
|
actualChanges.put(LoanApiConstants.disbursementIdParameterName,
|
||||||
|
command.stringValueOfParameterNamed(LoanApiConstants.disbursementIdParameterName));
|
||||||
existingTransactionIds.addAll(findExistingTransactionIds());
|
existingTransactionIds.addAll(findExistingTransactionIds());
|
||||||
existingReversedTransactionIds.addAll(findExistingReversedTransactionIds());
|
existingReversedTransactionIds.addAll(findExistingReversedTransactionIds());
|
||||||
regenerateRepaymentSchedule(loanScheduleFactory, currency, calculatedRepaymentsStartingFromDate, isHolidayEnabled,
|
regenerateRepaymentSchedule(loanScheduleFactory, currency, calculatedRepaymentsStartingFromDate, isHolidayEnabled, holidays,
|
||||||
holidays, workingDays);
|
workingDays);
|
||||||
|
|
||||||
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.transactionProcessorFactory
|
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.transactionProcessorFactory
|
||||||
.determineProcessor(this.transactionProcessingStrategy);
|
.determineProcessor(this.transactionProcessingStrategy);
|
||||||
final List<LoanTransaction> allNonContraTransactionsPostDisbursement = retreiveListOfTransactionsPostDisbursement();
|
final List<LoanTransaction> allNonContraTransactionsPostDisbursement = retreiveListOfTransactionsPostDisbursement();
|
||||||
ChangedTransactionDetail changedTransactionDetail = loanRepaymentScheduleTransactionProcessor.handleTransaction(getDisbursementDate(),
|
ChangedTransactionDetail changedTransactionDetail = loanRepaymentScheduleTransactionProcessor.handleTransaction(
|
||||||
allNonContraTransactionsPostDisbursement, getCurrency(), this.repaymentScheduleInstallments, charges());
|
getDisbursementDate(), allNonContraTransactionsPostDisbursement, getCurrency(), this.repaymentScheduleInstallments,
|
||||||
|
charges());
|
||||||
for (final Map.Entry<Long, LoanTransaction> mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) {
|
for (final Map.Entry<Long, LoanTransaction> mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) {
|
||||||
mapEntry.getValue().updateLoan(this);
|
mapEntry.getValue().updateLoan(this);
|
||||||
this.loanTransactions.add(mapEntry.getValue());
|
this.loanTransactions.add(mapEntry.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
return changedTransactionDetail;
|
return changedTransactionDetail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BigDecimal retriveLastEmiAmount() {
|
||||||
public BigDecimal retriveLastEmiAmount(){
|
|
||||||
BigDecimal emiAmount = this.fixedEmiAmount;
|
BigDecimal emiAmount = this.fixedEmiAmount;
|
||||||
Date startDate = this.getDisbursementDate().toDate();
|
Date startDate = this.getDisbursementDate().toDate();
|
||||||
for(LoanTermVariations loanTermVariations:this.loanTermVariations){
|
for (LoanTermVariations loanTermVariations : this.loanTermVariations) {
|
||||||
if(loanTermVariations.getTermType().isEMIAmountVariation() &&
|
if (loanTermVariations.getTermType().isEMIAmountVariation() && !startDate.after(loanTermVariations.getTermApplicableFrom())) {
|
||||||
!startDate.after(loanTermVariations.getTermApplicableFrom())){
|
|
||||||
startDate = loanTermVariations.getTermApplicableFrom();
|
startDate = loanTermVariations.getTermApplicableFrom();
|
||||||
emiAmount = loanTermVariations.getTermValue();
|
emiAmount = loanTermVariations.getTermValue();
|
||||||
}
|
}
|
||||||
|
|||||||
+33
-17
@@ -184,7 +184,8 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
|||||||
if (clientId != null) {
|
if (clientId != null) {
|
||||||
cycleNumber = this.loanReadPlatformService.retriveLoanCounter(clientId, loanProduct.getId());
|
cycleNumber = this.loanReadPlatformService.retriveLoanCounter(clientId, loanProduct.getId());
|
||||||
} else if (groupId != null) {
|
} else if (groupId != null) {
|
||||||
cycleNumber = this.loanReadPlatformService.retriveLoanCounter(groupId, AccountType.GROUP.getValue(), loanProduct.getId());
|
cycleNumber = this.loanReadPlatformService.retriveLoanCounter(groupId, AccountType.GROUP.getValue(),
|
||||||
|
loanProduct.getId());
|
||||||
}
|
}
|
||||||
this.loanProductCommandFromApiJsonDeserializer.validateMinMaxConstraints(command.parsedJson(), baseDataValidator,
|
this.loanProductCommandFromApiJsonDeserializer.validateMinMaxConstraints(command.parsedJson(), baseDataValidator,
|
||||||
loanProduct, cycleNumber);
|
loanProduct, cycleNumber);
|
||||||
@@ -271,21 +272,39 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
|||||||
loanId); }
|
loanId); }
|
||||||
|
|
||||||
final Set<LoanCharge> existingCharges = existingLoanApplication.charges();
|
final Set<LoanCharge> existingCharges = existingLoanApplication.charges();
|
||||||
Map<Long,LoanChargeData> chargesMap = new HashMap<Long, LoanChargeData>();
|
Map<Long, LoanChargeData> chargesMap = new HashMap<Long, LoanChargeData>();
|
||||||
for(LoanCharge charge:existingCharges){
|
for (LoanCharge charge : existingCharges) {
|
||||||
LoanChargeData chargeData = new LoanChargeData(charge.getId(),charge.getDueLocalDate() ,charge.amountOrPercentage());
|
LoanChargeData chargeData = new LoanChargeData(charge.getId(), charge.getDueLocalDate(), charge.amountOrPercentage());
|
||||||
chargesMap.put(charge.getId(), chargeData);
|
chargesMap.put(charge.getId(), chargeData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores all charges which are passed in during modify loan
|
||||||
|
* application
|
||||||
|
**/
|
||||||
final Set<LoanCharge> possiblyModifedLoanCharges = this.loanChargeAssembler.fromParsedJson(command.parsedJson());
|
final Set<LoanCharge> possiblyModifedLoanCharges = this.loanChargeAssembler.fromParsedJson(command.parsedJson());
|
||||||
|
/** Boolean determines if any charge has been modified **/
|
||||||
boolean isChargeModified = false;
|
boolean isChargeModified = false;
|
||||||
for(LoanCharge loanCharge : possiblyModifedLoanCharges){
|
|
||||||
if(loanCharge.getId() == null){
|
/**
|
||||||
|
* If there are any charges already present, which are now not
|
||||||
|
* passed in as a part of the request, deem the charges as modified
|
||||||
|
**/
|
||||||
|
if (!possiblyModifedLoanCharges.containsAll(existingCharges)) {
|
||||||
|
isChargeModified = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If any new charges are added or values of existing charges are
|
||||||
|
* modified
|
||||||
|
**/
|
||||||
|
for (LoanCharge loanCharge : possiblyModifedLoanCharges) {
|
||||||
|
if (loanCharge.getId() == null) {
|
||||||
isChargeModified = true;
|
isChargeModified = true;
|
||||||
}else{
|
} else {
|
||||||
LoanChargeData chargeData = chargesMap.get(loanCharge.getId());
|
LoanChargeData chargeData = chargesMap.get(loanCharge.getId());
|
||||||
if(loanCharge.amountOrPercentage().compareTo(chargeData.amountOrPercentage()) != 0 ||
|
if (loanCharge.amountOrPercentage().compareTo(chargeData.amountOrPercentage()) != 0
|
||||||
(loanCharge.isSpecifiedDueDate() && !loanCharge.getDueLocalDate().equals(chargeData.getDueDate()))){
|
|| (loanCharge.isSpecifiedDueDate() && !loanCharge.getDueLocalDate().equals(chargeData.getDueDate()))) {
|
||||||
isChargeModified = true;
|
isChargeModified = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -338,7 +357,8 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
|||||||
if (clientId != null) {
|
if (clientId != null) {
|
||||||
cycleNumber = this.loanReadPlatformService.retriveLoanCounter(clientId, loanProduct.getId());
|
cycleNumber = this.loanReadPlatformService.retriveLoanCounter(clientId, loanProduct.getId());
|
||||||
} else if (groupId != null) {
|
} else if (groupId != null) {
|
||||||
cycleNumber = this.loanReadPlatformService.retriveLoanCounter(groupId, AccountType.GROUP.getValue(), loanProduct.getId());
|
cycleNumber = this.loanReadPlatformService.retriveLoanCounter(groupId, AccountType.GROUP.getValue(),
|
||||||
|
loanProduct.getId());
|
||||||
}
|
}
|
||||||
this.loanProductCommandFromApiJsonDeserializer.validateMinMaxConstraints(command.parsedJson(), baseDataValidator,
|
this.loanProductCommandFromApiJsonDeserializer.validateMinMaxConstraints(command.parsedJson(), baseDataValidator,
|
||||||
loanProduct, cycleNumber);
|
loanProduct, cycleNumber);
|
||||||
@@ -728,17 +748,13 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
|
|||||||
submittedOnDate.toString(), closeDate.toString());
|
submittedOnDate.toString(), closeDate.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(expectedFirstRepaymentOnDate != null && submittedOnDate.isAfter(expectedFirstRepaymentOnDate))
|
if (expectedFirstRepaymentOnDate != null && submittedOnDate.isAfter(expectedFirstRepaymentOnDate)) {
|
||||||
{
|
|
||||||
defaultUserMessage = "submittedOnDate cannot be after the loans expectedFirstRepaymentOnDate.";
|
defaultUserMessage = "submittedOnDate cannot be after the loans expectedFirstRepaymentOnDate.";
|
||||||
throw new LoanApplicationDateException("submitted.on.date.cannot.be.after.the.loan.expected.first.repayment.date", defaultUserMessage,
|
throw new LoanApplicationDateException("submitted.on.date.cannot.be.after.the.loan.expected.first.repayment.date",
|
||||||
submittedOnDate.toString(), expectedFirstRepaymentOnDate.toString());
|
defaultUserMessage, submittedOnDate.toString(), expectedFirstRepaymentOnDate.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private void checkClientOrGroupActive(final Loan loan) {
|
private void checkClientOrGroupActive(final Loan loan) {
|
||||||
final Client client = loan.client();
|
final Client client = loan.client();
|
||||||
if (client != null) {
|
if (client != null) {
|
||||||
|
|||||||
Reference in New Issue
Block a user