Remove disbursement details in undo loan disbursal action (#2609)
Co-authored-by: Jose Alberto Hernandez <alberto@MacBook-Pro.local>
This commit is contained in:
co-authored by
Jose Alberto Hernandez
parent
ee0184c0a5
commit
d4517f4a4d
+1
-5
@@ -564,11 +564,7 @@ public class TellerManagementReadPlatformServiceImpl implements TellerManagement
|
||||
|
||||
final LocalDate startDate = JdbcSupport.getLocalDate(rs, "start_date");
|
||||
final LocalDate endDate = JdbcSupport.getLocalDate(rs, "end_date");
|
||||
final Integer fullDayFromDB = rs.getInt("full_day");
|
||||
Boolean fullDay = false;
|
||||
if (fullDayFromDB == 1) {
|
||||
fullDay = true;
|
||||
}
|
||||
final Boolean fullDay = rs.getBoolean("full_day");
|
||||
final String startTime = rs.getString("start_time");
|
||||
final String endTime = rs.getString("end_time");
|
||||
|
||||
|
||||
+1
@@ -25,6 +25,7 @@ public interface LoanApiConstants {
|
||||
String disbursementDataParameterName = "disbursementData";
|
||||
String disbursementDateParameterName = "expectedDisbursementDate";
|
||||
String disbursementPrincipalParameterName = "principal";
|
||||
String disbursementReversedParameterName = "reversed";
|
||||
String disbursementNetDisbursalAmountParameterName = "netDisbursalAmount";
|
||||
String updatedDisbursementDateParameterName = "updatedExpectedDisbursementDate";
|
||||
String updatedDisbursementPrincipalParameterName = "updatedPrincipal";
|
||||
|
||||
+1
-1
@@ -959,7 +959,7 @@ final class LoansApiResourceSwagger {
|
||||
public GetLoansLoanIdTimeline timeline;
|
||||
public GetLoansLoanIdSummary summary;
|
||||
public GetLoansLoanIdRepaymentSchedule repaymentSchedule;
|
||||
@Schema(description = "Set of GetLoansLoanIdDisbursementDetails")
|
||||
@Schema(description = "Set of GetLoansLoanIdTransactions")
|
||||
public Set<GetLoansLoanIdTransactions> transactions;
|
||||
@Schema(description = "Set of GetLoansLoanIdDisbursementDetails")
|
||||
public Set<GetLoansLoanIdDisbursementDetails> disbursementDetails;
|
||||
|
||||
+49
-34
@@ -59,7 +59,6 @@ import javax.persistence.Table;
|
||||
import javax.persistence.Transient;
|
||||
import javax.persistence.UniqueConstraint;
|
||||
import javax.persistence.Version;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.fineract.infrastructure.codes.domain.CodeValue;
|
||||
import org.apache.fineract.infrastructure.core.api.JsonCommand;
|
||||
@@ -143,7 +142,6 @@ import org.apache.fineract.portfolio.repaymentwithpostdatedchecks.domain.PostDat
|
||||
import org.apache.fineract.useradministration.domain.AppUser;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Slf4j
|
||||
@Entity
|
||||
@Component
|
||||
@Table(name = "m_loan", uniqueConstraints = { @UniqueConstraint(columnNames = { "account_no" }, name = "loan_account_no_UNIQUE"),
|
||||
@@ -916,7 +914,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
private Money getTotalAllTrancheDisbursementAmount() {
|
||||
Money amount = Money.zero(getCurrency());
|
||||
if (isMultiDisburmentLoan()) {
|
||||
for (final LoanDisbursementDetails loanDisbursementDetail : this.disbursementDetails) {
|
||||
for (final LoanDisbursementDetails loanDisbursementDetail : getDisbursementDetails()) {
|
||||
amount = amount.plus(loanDisbursementDetail.principal());
|
||||
}
|
||||
}
|
||||
@@ -1133,7 +1131,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
loanCharge.update(this);
|
||||
if (this.loanProduct.isMultiDisburseLoan() && loanCharge.isTrancheDisbursementCharge()) {
|
||||
loanCharge.getTrancheDisbursementCharge().getloanDisbursementDetails().updateLoan(this);
|
||||
for (final LoanDisbursementDetails loanDisbursementDetails : this.disbursementDetails) {
|
||||
for (final LoanDisbursementDetails loanDisbursementDetails : getDisbursementDetails()) {
|
||||
if (loanCharge.getTrancheDisbursementCharge().getloanDisbursementDetails().getId() == null) {
|
||||
if (loanCharge.getTrancheDisbursementCharge().getloanDisbursementDetails().equals(loanDisbursementDetails)) {
|
||||
loanTrancheDisbursementCharge = new LoanTrancheDisbursementCharge(loanCharge, loanDisbursementDetails);
|
||||
@@ -1600,7 +1598,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
final JsonArray disbursementDataArray = command.arrayOfParameterNamed(LoanApiConstants.disbursementDataParameterName);
|
||||
|
||||
if (loanProduct.isDisallowExpectedDisbursements()) {
|
||||
if (!disbursementDataArray.isEmpty()) {
|
||||
if (disbursementDataArray != null && !disbursementDataArray.isEmpty()) {
|
||||
final String errorMessage = "For this loan product, disbursement details are not allowed";
|
||||
throw new MultiDisbursementDataNotAllowedException(LoanApiConstants.disbursementDataParameterName, errorMessage);
|
||||
}
|
||||
@@ -1609,11 +1607,12 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
final String errorMessage = "For this loan product, disbursement details must be provided";
|
||||
throw new MultiDisbursementDataRequiredException(LoanApiConstants.disbursementDataParameterName, errorMessage);
|
||||
}
|
||||
}
|
||||
if (disbursementDataArray.size() > loanProduct.maxTrancheCount()) {
|
||||
final String errorMessage = "Number of tranche shouldn't be greter than " + loanProduct.maxTrancheCount();
|
||||
throw new ExceedingTrancheCountException(LoanApiConstants.disbursementDataParameterName, errorMessage,
|
||||
loanProduct.maxTrancheCount(), disbursementDetails.size());
|
||||
|
||||
if (disbursementDataArray.size() > loanProduct.maxTrancheCount()) {
|
||||
final String errorMessage = "Number of tranche shouldn't be greter than " + loanProduct.maxTrancheCount();
|
||||
throw new ExceedingTrancheCountException(LoanApiConstants.disbursementDataParameterName, errorMessage,
|
||||
loanProduct.maxTrancheCount(), disbursementDetails.size());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.disbursementDetails.clear();
|
||||
@@ -1905,7 +1904,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
if (loanDisbursementDetail.actualDisbursementDate() == null) {
|
||||
LocalDate actualDisbursementDate = null;
|
||||
LoanDisbursementDetails disbursementDetails = new LoanDisbursementDetails(expectedDisbursementDate, actualDisbursementDate,
|
||||
principal, this.netDisbursalAmount);
|
||||
principal, this.netDisbursalAmount, false);
|
||||
disbursementDetails.updateLoan(this);
|
||||
if (!loanDisbursementDetail.equals(disbursementDetails)) {
|
||||
loanDisbursementDetail.copy(disbursementDetails);
|
||||
@@ -1916,7 +1915,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
} else {
|
||||
LocalDate actualDisbursementDate = null;
|
||||
LoanDisbursementDetails disbursementDetails = new LoanDisbursementDetails(expectedDisbursementDate, actualDisbursementDate,
|
||||
principal, this.netDisbursalAmount);
|
||||
principal, this.netDisbursalAmount, false);
|
||||
disbursementDetails.updateLoan(this);
|
||||
this.disbursementDetails.add(disbursementDetails);
|
||||
for (LoanTrancheCharge trancheCharge : trancheCharges) {
|
||||
@@ -1959,7 +1958,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
|
||||
public LoanDisbursementDetails fetchLoanDisbursementsById(Long id) {
|
||||
LoanDisbursementDetails loanDisbursementDetail = null;
|
||||
for (LoanDisbursementDetails disbursementDetail : this.disbursementDetails) {
|
||||
for (LoanDisbursementDetails disbursementDetail : getDisbursementDetails()) {
|
||||
if (id.equals(disbursementDetail.getId())) {
|
||||
loanDisbursementDetail = disbursementDetail;
|
||||
break;
|
||||
@@ -1970,7 +1969,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
|
||||
private List<Long> fetchDisbursementIds() {
|
||||
List<Long> list = new ArrayList<>();
|
||||
for (LoanDisbursementDetails disbursementDetails : this.disbursementDetails) {
|
||||
for (LoanDisbursementDetails disbursementDetails : getDisbursementDetails()) {
|
||||
list.add(disbursementDetails.getId());
|
||||
}
|
||||
return list;
|
||||
@@ -2254,22 +2253,23 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
recalculateAllCharges();
|
||||
|
||||
if (loanProduct.isMultiDisburseLoan()) {
|
||||
List<LoanDisbursementDetails> currentDisbursementDetails = getDisbursementDetails();
|
||||
if (loanProduct.isDisallowExpectedDisbursements()) {
|
||||
if (!disbursementDetails.isEmpty()) {
|
||||
if (!currentDisbursementDetails.isEmpty()) {
|
||||
final String errorMessage = "For this loan product, disbursement details are not allowed";
|
||||
throw new MultiDisbursementDataNotAllowedException(LoanApiConstants.disbursementDataParameterName, errorMessage);
|
||||
}
|
||||
} else {
|
||||
if (disbursementDetails.isEmpty()) {
|
||||
if (currentDisbursementDetails.isEmpty()) {
|
||||
final String errorMessage = "For this loan product, disbursement details must be provided";
|
||||
throw new MultiDisbursementDataRequiredException(LoanApiConstants.disbursementDataParameterName, errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.disbursementDetails.size() > loanProduct.maxTrancheCount()) {
|
||||
if (currentDisbursementDetails.size() > loanProduct.maxTrancheCount()) {
|
||||
final String errorMessage = "Number of tranche shouldn't be greter than " + loanProduct.maxTrancheCount();
|
||||
throw new ExceedingTrancheCountException(LoanApiConstants.disbursementDataParameterName, errorMessage,
|
||||
loanProduct.maxTrancheCount(), disbursementDetails.size());
|
||||
loanProduct.maxTrancheCount(), currentDisbursementDetails.size());
|
||||
}
|
||||
}
|
||||
this.approvedOnDate = approvedOn;
|
||||
@@ -2463,7 +2463,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
private List<LoanDisbursementDetails> getDisbursedLoanDisbursementDetails() {
|
||||
List<LoanDisbursementDetails> ret = new ArrayList<>();
|
||||
if (this.disbursementDetails != null && this.disbursementDetails.size() > 0) {
|
||||
for (LoanDisbursementDetails disbursementDetail : this.disbursementDetails) {
|
||||
for (LoanDisbursementDetails disbursementDetail : getDisbursementDetails()) {
|
||||
if (disbursementDetail.actualDisbursementDate() != null) {
|
||||
ret.add(disbursementDetail);
|
||||
}
|
||||
@@ -2634,7 +2634,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
private Collection<LoanDisbursementDetails> fetchUndisbursedDetail() {
|
||||
Collection<LoanDisbursementDetails> disbursementDetails = new ArrayList<>();
|
||||
LocalDate date = null;
|
||||
for (LoanDisbursementDetails disbursementDetail : this.disbursementDetails) {
|
||||
for (LoanDisbursementDetails disbursementDetail : getDisbursementDetails()) {
|
||||
if (disbursementDetail.actualDisbursementDate() == null) {
|
||||
if (date == null || disbursementDetail.expectedDisbursementDate().compareTo(date) == 0 ? Boolean.TRUE : Boolean.FALSE) {
|
||||
disbursementDetails.add(disbursementDetail);
|
||||
@@ -2653,7 +2653,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
LoanDisbursementDetails details = null;
|
||||
LocalDate date = this.actualDisbursementDate;
|
||||
if (date != null) {
|
||||
for (LoanDisbursementDetails disbursementDetail : this.disbursementDetails) {
|
||||
for (LoanDisbursementDetails disbursementDetail : getDisbursementDetails()) {
|
||||
if (disbursementDetail.actualDisbursementDate() != null) {
|
||||
if (disbursementDetail.actualDisbursementDate().isAfter(date)
|
||||
|| disbursementDetail.actualDisbursementDate().compareTo(date) == 0 ? Boolean.TRUE : Boolean.FALSE) {
|
||||
@@ -2668,7 +2668,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
|
||||
private boolean isDisbursementMissed() {
|
||||
boolean isDisbursementMissed = false;
|
||||
for (LoanDisbursementDetails disbursementDetail : this.disbursementDetails) {
|
||||
for (LoanDisbursementDetails disbursementDetail : getDisbursementDetails()) {
|
||||
if (disbursementDetail.actualDisbursementDate() == null
|
||||
&& DateUtils.getBusinessLocalDate().isAfter(disbursementDetail.expectedDisbursementDateAsLocalDate())) {
|
||||
isDisbursementMissed = true;
|
||||
@@ -2680,7 +2680,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
|
||||
public BigDecimal getDisbursedAmount() {
|
||||
BigDecimal principal = BigDecimal.ZERO;
|
||||
for (LoanDisbursementDetails disbursementDetail : this.disbursementDetails) {
|
||||
for (LoanDisbursementDetails disbursementDetail : getDisbursementDetails()) {
|
||||
if (disbursementDetail.actualDisbursementDate() != null) {
|
||||
principal = principal.add(disbursementDetail.principal());
|
||||
}
|
||||
@@ -2689,7 +2689,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
}
|
||||
|
||||
private void removeDisbursementDetail() {
|
||||
Set<LoanDisbursementDetails> details = new HashSet<>(this.disbursementDetails);
|
||||
Set<LoanDisbursementDetails> details = new HashSet<>(getDisbursementDetails());
|
||||
for (LoanDisbursementDetails disbursementDetail : details) {
|
||||
if (disbursementDetail.actualDisbursementDate() == null) {
|
||||
this.disbursementDetails.remove(disbursementDetail);
|
||||
@@ -2699,10 +2699,15 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
|
||||
private boolean isDisbursementAllowed() {
|
||||
boolean isAllowed = false;
|
||||
for (LoanDisbursementDetails disbursementDetail : this.disbursementDetails) {
|
||||
if (disbursementDetail.actualDisbursementDate() == null) {
|
||||
isAllowed = true;
|
||||
break;
|
||||
List<LoanDisbursementDetails> disbursementDetails = getDisbursementDetails();
|
||||
if (disbursementDetails == null || disbursementDetails.size() == 0) {
|
||||
isAllowed = true;
|
||||
} else {
|
||||
for (LoanDisbursementDetails disbursementDetail : disbursementDetails) {
|
||||
if (disbursementDetail.actualDisbursementDate() == null) {
|
||||
isAllowed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return isAllowed;
|
||||
@@ -2710,7 +2715,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
|
||||
private boolean atleastOnceDisbursed() {
|
||||
boolean isDisbursed = false;
|
||||
for (LoanDisbursementDetails disbursementDetail : this.disbursementDetails) {
|
||||
for (LoanDisbursementDetails disbursementDetail : getDisbursementDetails()) {
|
||||
if (disbursementDetail.actualDisbursementDate() != null) {
|
||||
isDisbursed = true;
|
||||
break;
|
||||
@@ -2926,7 +2931,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
: Boolean.TRUE;
|
||||
this.loanRepaymentScheduleDetail.setPrincipal(this.approvedPrincipal);
|
||||
if (this.loanProduct.isMultiDisburseLoan()) {
|
||||
for (final LoanDisbursementDetails details : this.disbursementDetails) {
|
||||
for (final LoanDisbursementDetails details : getDisbursementDetails()) {
|
||||
details.updateActualDisbursementDate(null);
|
||||
}
|
||||
}
|
||||
@@ -5094,10 +5099,20 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
return list;
|
||||
}
|
||||
|
||||
public List<LoanDisbursementDetails> getDisbursementDetails() {
|
||||
public List<LoanDisbursementDetails> getAllDisbursementDetails() {
|
||||
return this.disbursementDetails;
|
||||
}
|
||||
|
||||
public List<LoanDisbursementDetails> getDisbursementDetails() {
|
||||
List<LoanDisbursementDetails> currentDisbursementDetails = new ArrayList<LoanDisbursementDetails>();
|
||||
for (LoanDisbursementDetails disbursementDetail : this.disbursementDetails) {
|
||||
if (!disbursementDetail.isReversed()) {
|
||||
currentDisbursementDetails.add(disbursementDetail);
|
||||
}
|
||||
}
|
||||
return currentDisbursementDetails;
|
||||
}
|
||||
|
||||
public ChangedTransactionDetail updateDisbursementDateAndAmountForTranche(final LoanDisbursementDetails disbursementDetails,
|
||||
final JsonCommand command, final Map<String, Object> actualChanges, final ScheduleGeneratorDTO scheduleGeneratorDTO) {
|
||||
final Locale locale = command.extractLocale();
|
||||
@@ -5552,7 +5567,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
NthDayType nthDayType = null;
|
||||
DayOfWeekType dayOfWeekType = null;
|
||||
final List<DisbursementData> disbursementData = new ArrayList<>();
|
||||
for (LoanDisbursementDetails disbursementDetails : this.disbursementDetails) {
|
||||
for (LoanDisbursementDetails disbursementDetails : getDisbursementDetails()) {
|
||||
disbursementData.add(disbursementDetails.toData());
|
||||
}
|
||||
|
||||
@@ -6215,7 +6230,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
charge.resetToOriginal(loanCurrency());
|
||||
}
|
||||
}
|
||||
for (final LoanDisbursementDetails details : this.disbursementDetails) {
|
||||
for (final LoanDisbursementDetails details : getDisbursementDetails()) {
|
||||
if (actualDisbursementDate.equals(details.actualDisbursementDate())) {
|
||||
this.loanRepaymentScheduleDetail.setPrincipal(getDisbursedAmount().subtract(details.principal()));
|
||||
details.updateActualDisbursementDate(null);
|
||||
@@ -6278,7 +6293,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
* get the next repayment LocalDate for rescheduling at the time of disbursement
|
||||
*/
|
||||
public LocalDate getNextPossibleRepaymentDateForRescheduling() {
|
||||
List<LoanDisbursementDetails> loanDisbursementDetails = this.disbursementDetails;
|
||||
List<LoanDisbursementDetails> loanDisbursementDetails = getDisbursementDetails();
|
||||
LocalDate nextRepaymentDate = DateUtils.getBusinessLocalDate();
|
||||
for (LoanDisbursementDetails loanDisbursementDetail : loanDisbursementDetails) {
|
||||
if (loanDisbursementDetail.actualDisbursementDate() == null) {
|
||||
|
||||
+13
-1
@@ -49,16 +49,20 @@ public class LoanDisbursementDetails extends AbstractPersistableCustom {
|
||||
@Column(name = "net_disbursal_amount", scale = 6, precision = 19)
|
||||
private BigDecimal netDisbursalAmount;
|
||||
|
||||
@Column(name = "is_reversed", nullable = false)
|
||||
private boolean reversed;
|
||||
|
||||
protected LoanDisbursementDetails() {
|
||||
|
||||
}
|
||||
|
||||
public LoanDisbursementDetails(final LocalDate expectedDisbursementDate, final LocalDate actualDisbursementDate,
|
||||
final BigDecimal principal, final BigDecimal netDisbursalAmount) {
|
||||
final BigDecimal principal, final BigDecimal netDisbursalAmount, final boolean reversed) {
|
||||
this.expectedDisbursementDate = expectedDisbursementDate;
|
||||
this.actualDisbursementDate = actualDisbursementDate;
|
||||
this.principal = principal;
|
||||
this.netDisbursalAmount = netDisbursalAmount;
|
||||
this.reversed = reversed;
|
||||
}
|
||||
|
||||
public void updateLoan(final Loan loan) {
|
||||
@@ -88,6 +92,7 @@ public class LoanDisbursementDetails extends AbstractPersistableCustom {
|
||||
this.principal = disbursementDetails.principal;
|
||||
this.expectedDisbursementDate = disbursementDetails.expectedDisbursementDate;
|
||||
this.actualDisbursementDate = disbursementDetails.actualDisbursementDate;
|
||||
this.reversed = disbursementDetails.reversed;
|
||||
}
|
||||
|
||||
public LocalDate expectedDisbursementDate() {
|
||||
@@ -142,4 +147,11 @@ public class LoanDisbursementDetails extends AbstractPersistableCustom {
|
||||
this.principal = principal;
|
||||
}
|
||||
|
||||
public void reverse() {
|
||||
this.reversed = true;
|
||||
}
|
||||
|
||||
public boolean isReversed() {
|
||||
return reversed;
|
||||
}
|
||||
}
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.fineract.portfolio.loanaccount.domain;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||
|
||||
public interface LoanDisbursementDetailsRepository
|
||||
extends JpaRepository<LoanDisbursementDetails, Long>, JpaSpecificationExecutor<LoanDisbursementDetails> {
|
||||
|
||||
}
|
||||
+3
-3
@@ -1628,7 +1628,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
public Collection<DisbursementData> retrieveLoanDisbursementDetails(final Long loanId) {
|
||||
final LoanDisbursementDetailMapper rm = new LoanDisbursementDetailMapper(sqlGenerator);
|
||||
final String sql = "select " + rm.schema()
|
||||
+ " where dd.loan_id=? group by dd.id, lc.amount_waived_derived order by dd.expected_disburse_date";
|
||||
+ " where dd.loan_id=? and dd.is_reversed=false group by dd.id, lc.amount_waived_derived order by dd.expected_disburse_date";
|
||||
return this.jdbcTemplate.query(sql, rm, loanId); // NOSONAR
|
||||
}
|
||||
|
||||
@@ -1960,7 +1960,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
sqlBuilder.append(" left join m_floating_rates bfr on bfr.is_base_lending_rate = true");
|
||||
sqlBuilder.append(" left join m_floating_rates_periods bfrp on bfr.id = bfrp.floating_rates_id and bfrp.created_date >= ?");
|
||||
sqlBuilder.append(" WHERE ml.loan_status_id = ? ");
|
||||
sqlBuilder.append(" and ml.is_npa = false ");
|
||||
sqlBuilder.append(" and ml.is_npa = false and dd.is_reversed = false ");
|
||||
sqlBuilder.append(" and ((");
|
||||
sqlBuilder.append("ml.interest_recalculation_enabled = true ");
|
||||
sqlBuilder.append(" and (ml.interest_recalcualated_on is null or ml.interest_recalcualated_on <> ?)");
|
||||
@@ -2008,7 +2008,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService {
|
||||
sqlBuilder.append(" left join m_floating_rates bfr on bfr.is_base_lending_rate = true");
|
||||
sqlBuilder.append(" left join m_floating_rates_periods bfrp on bfr.id = bfrp.floating_rates_id and bfrp.created_date >= ?");
|
||||
sqlBuilder.append(" WHERE ml.loan_status_id = ? ");
|
||||
sqlBuilder.append(" and ml.is_npa = false ");
|
||||
sqlBuilder.append(" and ml.is_npa = false and dd.is_reversed = false ");
|
||||
sqlBuilder.append(" and ((");
|
||||
sqlBuilder.append("ml.interest_recalculation_enabled = true ");
|
||||
sqlBuilder.append(" and (ml.interest_recalcualated_on is null or ml.interest_recalcualated_on <> ? )");
|
||||
|
||||
+7
-3
@@ -337,9 +337,13 @@ public class LoanUtilService {
|
||||
netDisbursalAmount = jsonObject.getAsJsonPrimitive(LoanApiConstants.disbursementNetDisbursalAmountParameterName)
|
||||
.getAsBigDecimal();
|
||||
}
|
||||
|
||||
disbursementDatas.add(
|
||||
new LoanDisbursementDetails(expectedDisbursementDate, actualDisbursementDate, principal, netDisbursalAmount));
|
||||
boolean isReversed = false;
|
||||
if (jsonObject.has(LoanApiConstants.disbursementReversedParameterName)) {
|
||||
isReversed = this.fromApiJsonHelper.extractBooleanNamed(LoanApiConstants.disbursementReversedParameterName,
|
||||
jsonObject);
|
||||
}
|
||||
disbursementDatas.add(new LoanDisbursementDetails(expectedDisbursementDate, actualDisbursementDate, principal,
|
||||
netDisbursalAmount, isReversed));
|
||||
i++;
|
||||
} while (i < disbursementDataArray.size());
|
||||
}
|
||||
|
||||
+17
-3
@@ -164,6 +164,7 @@ import org.apache.fineract.portfolio.loanaccount.domain.LoanChargePaidBy;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanChargeRepository;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanCollateralManagement;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanDisbursementDetails;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanDisbursementDetailsRepository;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanEvent;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanInstallmentCharge;
|
||||
import org.apache.fineract.portfolio.loanaccount.domain.LoanInterestRecalcualtionAdditionalDetails;
|
||||
@@ -269,7 +270,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
private final LoanRepository loanRepository;
|
||||
private final RepaymentWithPostDatedChecksAssembler repaymentWithPostDatedChecksAssembler;
|
||||
private final PostDatedChecksRepository postDatedChecksRepository;
|
||||
|
||||
private final LoanDisbursementDetailsRepository loanDisbursementDetailsRepository;
|
||||
private final LoanRepaymentScheduleInstallmentRepository loanRepaymentScheduleInstallmentRepository;
|
||||
|
||||
private LoanLifecycleStateMachine defaultLoanLifecycleStateMachine() {
|
||||
@@ -325,9 +326,9 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
// products
|
||||
final LocalDate artificialExpectedDate = loan.getExpectedDisbursedOnLocalDate();
|
||||
LoanDisbursementDetails disbursementDetail = new LoanDisbursementDetails(artificialExpectedDate, null,
|
||||
loan.getDisbursedAmount(), null);
|
||||
loan.getDisbursedAmount(), null, false);
|
||||
disbursementDetail.updateLoan(loan);
|
||||
loan.getDisbursementDetails().add(disbursementDetail);
|
||||
loan.getAllDisbursementDetails().add(disbursementDetail);
|
||||
}
|
||||
}
|
||||
loan.validateAccountStatus(LoanEvent.LOAN_DISBURSED);
|
||||
@@ -869,6 +870,19 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
||||
final Map<String, Object> accountingBridgeData = loan.deriveAccountingBridgeData(currency.getCode(), existingTransactionIds,
|
||||
existingReversedTransactionIds, isAccountTransfer);
|
||||
journalEntryWritePlatformService.createJournalEntriesForLoan(accountingBridgeData);
|
||||
|
||||
// Remove All the Disbursement Details If the Loan Product is disabled and exists one
|
||||
if (loan.loanProduct().isDisallowExpectedDisbursements()) {
|
||||
if (!loan.getDisbursementDetails().isEmpty()) {
|
||||
List<LoanDisbursementDetails> reversedDisbursementDetails = new ArrayList<LoanDisbursementDetails>();
|
||||
for (LoanDisbursementDetails disbursementDetail : loan.getAllDisbursementDetails()) {
|
||||
disbursementDetail.reverse();
|
||||
reversedDisbursementDetails.add(disbursementDetail);
|
||||
}
|
||||
this.loanDisbursementDetailsRepository.saveAllAndFlush(reversedDisbursementDetails);
|
||||
}
|
||||
}
|
||||
|
||||
businessEventNotifierService.notifyPostBusinessEvent(new LoanUndoDisbursalBusinessEvent(loan));
|
||||
}
|
||||
|
||||
|
||||
+2
@@ -1237,6 +1237,8 @@ final class LoanProductsApiResourceSwagger {
|
||||
@Schema(example = "50")
|
||||
public Integer principalThresholdForLastInstalment;
|
||||
public GetDelinquencyBucketsResponse delinquencyBucket;
|
||||
@Schema(example = "true")
|
||||
public Boolean disallowExpectedDisbursements;
|
||||
}
|
||||
|
||||
@Schema(description = "PutLoanProductsProductIdRequest")
|
||||
|
||||
@@ -69,4 +69,5 @@
|
||||
<include file="parts/0047_add_loan_delinquency_tags_business_step.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0048_rework_loan_account_locks.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0049_add_send_asynchronous_events_job.xml" relativeToChangelogFile="true"/>
|
||||
<include file="parts/0050_add_reverse_flag_disbursement_details.xml" relativeToChangelogFile="true"/>
|
||||
</databaseChangeLog>
|
||||
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
-->
|
||||
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
|
||||
|
||||
<changeSet id="1" author="fineract">
|
||||
<addColumn tableName="m_loan_disbursement_detail">
|
||||
<column name="is_reversed" type="boolean" defaultValueBoolean="false">
|
||||
<constraints nullable="false"/>
|
||||
</column>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
</databaseChangeLog>
|
||||
+8
-3
@@ -25,6 +25,7 @@ import io.restassured.specification.RequestSpecification;
|
||||
import io.restassured.specification.ResponseSpecification;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import org.apache.fineract.client.models.GetLoansLoanIdResponse;
|
||||
import org.apache.fineract.integrationtests.common.ClientHelper;
|
||||
import org.apache.fineract.integrationtests.common.Utils;
|
||||
import org.apache.fineract.integrationtests.common.loans.LoanApplicationTestBuilder;
|
||||
@@ -75,7 +76,7 @@ public class ClientLoanNonTrancheMultipleDisbursementsIntegrationTest {
|
||||
.withMultiDisburse() //
|
||||
.withInterestCalculationPeriodTypeAsRepaymentPeriod(true) //
|
||||
.withMaxTrancheCount("30") //
|
||||
.withDisallowExpectectedDisbursements(true);
|
||||
.withDisallowExpectedDisbursements(true);
|
||||
if (isInterestRecalculationEnabled) {
|
||||
final String interestRecalculationCompoundingMethod = LoanProductTestBuilder.RECALCULATION_COMPOUNDING_METHOD_NONE;
|
||||
final String rescheduleStrategyMethod = LoanProductTestBuilder.RECALCULATION_STRATEGY_REDUCE_NUMBER_OF_INSTALLMENTS;
|
||||
@@ -160,8 +161,12 @@ public class ClientLoanNonTrancheMultipleDisbursementsIntegrationTest {
|
||||
|
||||
LOG.info("-------------------------------DISBURSE non-tranch multi-disbursal loan ----------");
|
||||
final String netDisbursedAmt = null;
|
||||
loanStatusHashMap = this.loanTransactionHelper.disburseLoanWithNetDisbursalAmount(submitDate, loanID, approved.toString(),
|
||||
netDisbursedAmt);
|
||||
loanStatusHashMap = this.loanTransactionHelper.disburseLoanWithTransactionAmount(submitDate, loanID, approved.toString());
|
||||
|
||||
GetLoansLoanIdResponse getLoansLoanIdResponse = this.loanTransactionHelper.getLoan(requestSpec, responseSpec, loanID);
|
||||
Assertions.assertNotNull(getLoansLoanIdResponse);
|
||||
|
||||
this.loanTransactionHelper.printRepaymentSchedule(getLoansLoanIdResponse);
|
||||
|
||||
LoanStatusChecker.verifyLoanIsActive(loanStatusHashMap);
|
||||
loanSchedule = this.loanTransactionHelper.getLoanRepaymentSchedule(this.requestSpec, this.responseSpec, loanID);
|
||||
|
||||
+118
-15
@@ -35,9 +35,12 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.fineract.client.models.GetLoanProductsProductIdResponse;
|
||||
import org.apache.fineract.client.models.GetLoansLoanIdRepaymentPeriod;
|
||||
import org.apache.fineract.client.models.GetLoansLoanIdRepaymentSchedule;
|
||||
import org.apache.fineract.client.models.GetLoansLoanIdResponse;
|
||||
import org.apache.fineract.client.models.PostLoansLoanIdResponse;
|
||||
import org.apache.fineract.client.models.PutLoansLoanIdResponse;
|
||||
import org.apache.fineract.integrationtests.common.ClientHelper;
|
||||
import org.apache.fineract.integrationtests.common.CollateralManagementHelper;
|
||||
import org.apache.fineract.integrationtests.common.Utils;
|
||||
@@ -271,8 +274,6 @@ public class LoanDisbursementDetailsIntegrationTest {
|
||||
|
||||
@Test
|
||||
public void validateEqualInstallmentsForMultiTrancheLoan() {
|
||||
List<HashMap> emptyTranches = new ArrayList<>();
|
||||
|
||||
final String operationDate = "01 January 2014";
|
||||
final String principal = "1000";
|
||||
final String disbursedPrincipal = "900";
|
||||
@@ -284,7 +285,7 @@ public class LoanDisbursementDetailsIntegrationTest {
|
||||
.withInterestTypeAsDecliningBalance().withMoratorium("", "").withInterestCalculationPeriodTypeAsRepaymentPeriod(true)
|
||||
.withInterestTypeAsDecliningBalance() //
|
||||
.withMultiDisburse() //
|
||||
.withDisallowExpectectedDisbursements(true) //
|
||||
.withDisallowExpectedDisbursements(true) //
|
||||
.build(null);
|
||||
log.info("Product {}", loanProductJSON);
|
||||
final Integer loanProductId = this.loanTransactionHelper.getLoanProductId(loanProductJSON);
|
||||
@@ -294,7 +295,7 @@ public class LoanDisbursementDetailsIntegrationTest {
|
||||
|
||||
log.info("-------------------LOAN CREATED WITH loanId----------------- {}", loanId);
|
||||
|
||||
this.loanTransactionHelper.approveLoanWithApproveAmount(operationDate, expectedDisbursementDate, principal, loanId, emptyTranches);
|
||||
this.loanTransactionHelper.approveLoanWithApproveAmount(operationDate, expectedDisbursementDate, principal, loanId, null);
|
||||
log.info("-------------------MULTI DISBURSAL LOAN APPROVED SUCCESSFULLY-------");
|
||||
|
||||
GetLoansLoanIdResponse getLoansLoanIdResponse = this.loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
|
||||
@@ -347,6 +348,101 @@ public class LoanDisbursementDetailsIntegrationTest {
|
||||
this.editLoanDisbursementDetails();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void allowModifyLoanApplicationAfterUndoDisbursalWithTranches() throws ParseException {
|
||||
final String operationDate = this.approveDate;
|
||||
List<HashMap> tranches = new ArrayList<>();
|
||||
String principal = "1000";
|
||||
final List<HashMap> collaterals = new ArrayList<>();
|
||||
|
||||
final Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec, operationDate);
|
||||
log.info("---------------------------------CLIENT CREATED WITH ID--------------------------------------------------- {}", clientId);
|
||||
|
||||
final Integer loanProductId = this.loanTransactionHelper
|
||||
.getLoanProductId(new LoanProductTestBuilder().withInterestTypeAsDecliningBalance().withTranches(true)
|
||||
.withDisallowExpectedDisbursements(true).withInterestCalculationPeriodTypeAsRepaymentPeriod(true).build(null));
|
||||
log.info("----------------------------------LOAN PRODUCT CREATED WITH ID------------------------------------------- {}",
|
||||
loanProductId);
|
||||
GetLoanProductsProductIdResponse getLoanProductsProductIdResponse = this.loanTransactionHelper.getLoanProduct(loanProductId);
|
||||
assertNotNull(getLoanProductsProductIdResponse);
|
||||
log.info("Loan Product Id {} with DisallowExpectectedDisbursements in {}", loanProductId,
|
||||
getLoanProductsProductIdResponse.getDisallowExpectedDisbursements());
|
||||
assertEquals(true, getLoanProductsProductIdResponse.getDisallowExpectedDisbursements());
|
||||
|
||||
final Integer loanId = applyForLoanApplicationWithTranches(clientId, loanProductId, proposedAmount, tranches);
|
||||
log.info("-----------------------------------LOAN CREATED WITH LOANID------------------------------------------------- {}", loanId);
|
||||
|
||||
loanTransactionHelper.approveLoanWithApproveAmount(operationDate, operationDate, approvalAmount, loanId, tranches);
|
||||
GetLoansLoanIdResponse getLoansLoanIdResponse = this.loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
|
||||
assertNotNull(getLoansLoanIdResponse);
|
||||
log.info("Loan Id {} with Status {} with Disbursement details {}", getLoansLoanIdResponse.getId(),
|
||||
getLoansLoanIdResponse.getStatus().getCode(), getLoansLoanIdResponse.getDisbursementDetails().size());
|
||||
log.info("-------------------MULTI DISBURSAL LOAN APPROVED SUCCESSFULLY-------");
|
||||
assertEquals(0, getLoansLoanIdResponse.getDisbursementDetails().size(), "Disbursement details items");
|
||||
|
||||
loanTransactionHelper.disburseLoanWithTransactionAmount(operationDate, loanId, principal);
|
||||
|
||||
getLoansLoanIdResponse = this.loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
|
||||
assertNotNull(getLoansLoanIdResponse);
|
||||
log.info("Loan Id {} with Status {} with Disbursement details {}", getLoansLoanIdResponse.getId(),
|
||||
getLoansLoanIdResponse.getStatus().getCode(), getLoansLoanIdResponse.getDisbursementDetails().size());
|
||||
log.info("-------------------MULTI DISBURSAL LOAN DISBURSED SUCCESSFULLY-------");
|
||||
assertEquals(1, getLoansLoanIdResponse.getDisbursementDetails().size(), "Disbursement details items");
|
||||
|
||||
PostLoansLoanIdResponse postLoansLoanIdResponse = this.loanTransactionHelper.applyLoanCommand(loanId, "undoDisbursal");
|
||||
assertNotNull(postLoansLoanIdResponse);
|
||||
log.info("-------------------UNDO DISBURSAL LOAN SUCCESSFULLY-------");
|
||||
getLoansLoanIdResponse = this.loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
|
||||
assertNotNull(getLoansLoanIdResponse);
|
||||
log.info("Loan Id {} with Status {} with Disbursement details {}", getLoansLoanIdResponse.getId(),
|
||||
getLoansLoanIdResponse.getStatus().getCode(), getLoansLoanIdResponse.getDisbursementDetails().size());
|
||||
assertEquals(0, getLoansLoanIdResponse.getDisbursementDetails().size(), "Disbursement details items");
|
||||
|
||||
getLoansLoanIdResponse = this.loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
|
||||
assertNotNull(getLoansLoanIdResponse);
|
||||
log.info("Loan Id {} with Status {} with Disbursement details {}", getLoansLoanIdResponse.getId(),
|
||||
getLoansLoanIdResponse.getStatus().getCode(), getLoansLoanIdResponse.getDisbursementDetails().size());
|
||||
assertEquals(0, getLoansLoanIdResponse.getDisbursementDetails().size(), "Disbursement details items");
|
||||
|
||||
postLoansLoanIdResponse = this.loanTransactionHelper.applyLoanCommand(loanId, "undoApproval");
|
||||
assertNotNull(postLoansLoanIdResponse);
|
||||
log.info("-------------------UNDO APPROVAL LOAN SUCCESSFULLY-------");
|
||||
|
||||
getLoansLoanIdResponse = this.loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
|
||||
assertNotNull(getLoansLoanIdResponse);
|
||||
log.info("Loan Id {} with Status {} with Disbursement details {}", getLoansLoanIdResponse.getId(),
|
||||
getLoansLoanIdResponse.getStatus().getCode(), getLoansLoanIdResponse.getDisbursementDetails().size());
|
||||
|
||||
principal = "10000";
|
||||
final String loanApplicationJSON = buildLoanApplicationJSON(clientId, loanProductId, principal, tranches, operationDate,
|
||||
collaterals);
|
||||
log.info("Modify Loan Application: {}", loanApplicationJSON);
|
||||
PutLoansLoanIdResponse putLoansLoanIdResponse = this.loanTransactionHelper.modifyLoanApplication(loanId, loanApplicationJSON);
|
||||
assertNotNull(putLoansLoanIdResponse);
|
||||
|
||||
getLoansLoanIdResponse = this.loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
|
||||
assertNotNull(getLoansLoanIdResponse);
|
||||
log.info("Loan Id {} with Status {} with Disbursement details {} and Principal {}", getLoansLoanIdResponse.getId(),
|
||||
getLoansLoanIdResponse.getStatus().getCode(), getLoansLoanIdResponse.getDisbursementDetails().size(),
|
||||
getLoansLoanIdResponse.getPrincipal());
|
||||
|
||||
// ReDo the Approval and Disbursement
|
||||
loanTransactionHelper.approveLoanWithApproveAmount(operationDate, operationDate, approvalAmount, loanId, null);
|
||||
getLoansLoanIdResponse = this.loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
|
||||
assertNotNull(getLoansLoanIdResponse);
|
||||
log.info("Loan Id {} with Status {} with Disbursement details {}", getLoansLoanIdResponse.getId(),
|
||||
getLoansLoanIdResponse.getStatus().getCode(), getLoansLoanIdResponse.getDisbursementDetails().size());
|
||||
|
||||
loanTransactionHelper.disburseLoanWithTransactionAmount(operationDate, loanId, principal);
|
||||
|
||||
getLoansLoanIdResponse = this.loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
|
||||
assertNotNull(getLoansLoanIdResponse);
|
||||
log.info("Loan Id {} with Status {} with Disbursement details {}", getLoansLoanIdResponse.getId(),
|
||||
getLoansLoanIdResponse.getStatus().getCode(), getLoansLoanIdResponse.getDisbursementDetails().size());
|
||||
log.info("-------------------MULTI DISBURSAL LOAN DISBURSED SUCCESSFULLY-------");
|
||||
assertEquals(1, getLoansLoanIdResponse.getDisbursementDetails().size(), "Disbursement details items");
|
||||
}
|
||||
|
||||
private void editLoanDisbursementDetails() throws ParseException {
|
||||
this.editDateAndPrincipalOfExistingTranche();
|
||||
this.addNewDisbursementDetails();
|
||||
@@ -412,17 +508,10 @@ public class LoanDisbursementDetailsIntegrationTest {
|
||||
return date;
|
||||
}
|
||||
|
||||
private Integer applyForLoanApplicationWithTranches(final Integer clientId, final Integer loanProductId, String principal,
|
||||
List<HashMap> tranches) {
|
||||
log.info("----------------APPLYING FOR LOAN APPLICATION");
|
||||
List<HashMap> collaterals = new ArrayList<>();
|
||||
final Integer collateralId = CollateralManagementHelper.createCollateralProduct(this.requestSpec, this.responseSpec);
|
||||
Assertions.assertNotNull(collateralId);
|
||||
final Integer clientCollateralId = CollateralManagementHelper.createClientCollateral(this.requestSpec, this.responseSpec,
|
||||
clientId.toString(), collateralId);
|
||||
Assertions.assertNotNull(clientCollateralId);
|
||||
addCollaterals(collaterals, clientCollateralId, BigDecimal.valueOf(1));
|
||||
final String loanApplicationJSON = new LoanApplicationTestBuilder() //
|
||||
private String buildLoanApplicationJSON(final Integer clientId, final Integer loanProductId, String principal, List<HashMap> tranches,
|
||||
final String operationDate, List<HashMap> collaterals) {
|
||||
|
||||
return new LoanApplicationTestBuilder() //
|
||||
.withPrincipal(principal) //
|
||||
.withLoanTermFrequency("5") //
|
||||
.withLoanTermFrequencyAsMonths() //
|
||||
@@ -435,6 +524,20 @@ public class LoanDisbursementDetailsIntegrationTest {
|
||||
.withInterestTypeAsDecliningBalance() //
|
||||
.withSubmittedOnDate("01 March 2014") //
|
||||
.withCollaterals(collaterals).build(clientId.toString(), loanProductId.toString(), null);
|
||||
}
|
||||
|
||||
private Integer applyForLoanApplicationWithTranches(final Integer clientId, final Integer loanProductId, String principal,
|
||||
List<HashMap> tranches) {
|
||||
log.info("----------------APPLYING FOR LOAN APPLICATION");
|
||||
List<HashMap> collaterals = new ArrayList<>();
|
||||
final Integer collateralId = CollateralManagementHelper.createCollateralProduct(this.requestSpec, this.responseSpec);
|
||||
Assertions.assertNotNull(collateralId);
|
||||
final Integer clientCollateralId = CollateralManagementHelper.createClientCollateral(this.requestSpec, this.responseSpec,
|
||||
clientId.toString(), collateralId);
|
||||
Assertions.assertNotNull(clientCollateralId);
|
||||
addCollaterals(collaterals, clientCollateralId, BigDecimal.valueOf(1));
|
||||
final String loanApplicationJSON = buildLoanApplicationJSON(clientId, loanProductId, principal, tranches, "01 March 2014",
|
||||
collaterals);
|
||||
|
||||
return this.loanTransactionHelper.getLoanId(loanApplicationJSON);
|
||||
}
|
||||
|
||||
+1
-1
@@ -394,7 +394,7 @@ public class LoanProductTestBuilder {
|
||||
return this;
|
||||
}
|
||||
|
||||
public LoanProductTestBuilder withDisallowExpectectedDisbursements(boolean disallowExpectectedDisbursements) {
|
||||
public LoanProductTestBuilder withDisallowExpectedDisbursements(boolean disallowExpectectedDisbursements) {
|
||||
this.disallowExpectedDisbursements = disallowExpectectedDisbursements;
|
||||
if (this.disallowExpectedDisbursements) {
|
||||
this.allowApprovedDisbursedAmountsOverApplied = true;
|
||||
|
||||
+25
@@ -45,7 +45,9 @@ import org.apache.fineract.client.models.GetLoanProductsProductIdResponse;
|
||||
import org.apache.fineract.client.models.GetLoansLoanIdRepaymentPeriod;
|
||||
import org.apache.fineract.client.models.GetLoansLoanIdRepaymentSchedule;
|
||||
import org.apache.fineract.client.models.GetLoansLoanIdResponse;
|
||||
import org.apache.fineract.client.models.PostLoansLoanIdResponse;
|
||||
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsResponse;
|
||||
import org.apache.fineract.client.models.PutLoansLoanIdResponse;
|
||||
import org.apache.fineract.client.util.JSON;
|
||||
import org.apache.fineract.integrationtests.common.CommonConstants;
|
||||
import org.apache.fineract.integrationtests.common.Utils;
|
||||
@@ -136,6 +138,12 @@ public class LoanTransactionHelper {
|
||||
"/fineract-provider/api/v1/loans/" + id + "?" + Utils.TENANT_IDENTIFIER, loanApplicationJSON, "loanId");
|
||||
}
|
||||
|
||||
public PutLoansLoanIdResponse modifyLoanApplication(final Integer id, final String loanApplicationJSON) {
|
||||
final String response = Utils.performServerPut(this.requestSpec, this.responseSpec,
|
||||
"/fineract-provider/api/v1/loans/" + id + "?" + Utils.TENANT_IDENTIFIER, loanApplicationJSON, null);
|
||||
return GSON.fromJson(response, PutLoansLoanIdResponse.class);
|
||||
}
|
||||
|
||||
public ArrayList getLoanRepaymentSchedule(final RequestSpecification requestSpec, final ResponseSpecification responseSpec,
|
||||
final Integer loanID) {
|
||||
final String URL = "/fineract-provider/api/v1/loans/" + loanID + "?associations=repaymentSchedule&" + Utils.TENANT_IDENTIFIER;
|
||||
@@ -319,6 +327,21 @@ public class LoanTransactionHelper {
|
||||
getDisburseLoanAsJSON(date, null, netDisbursalAmount));
|
||||
}
|
||||
|
||||
public PostLoansLoanIdResponse applyLoanCommand(final Integer loanId, final String command) {
|
||||
String undoBodyJson = "{}";
|
||||
String url = "";
|
||||
if (command.equals(UNDO_APPROVAL_LOAN_COMMAND)) {
|
||||
undoBodyJson = "{'note':'UNDO APPROVAL'}";
|
||||
url = createLoanOperationURL(UNDO_APPROVAL_LOAN_COMMAND, loanId);
|
||||
} else if (command.equals(UNDO_DISBURSE_LOAN_COMMAND)) {
|
||||
undoBodyJson = "{'note' : 'UNDO DISBURSAL'}";
|
||||
url = createLoanOperationURL(UNDO_DISBURSE_LOAN_COMMAND, loanId);
|
||||
}
|
||||
final String response = Utils.performServerPost(this.requestSpec, this.responseSpec, url, undoBodyJson, null);
|
||||
log.info("Response {}", response);
|
||||
return GSON.fromJson(response, PostLoansLoanIdResponse.class);
|
||||
}
|
||||
|
||||
public HashMap undoDisbursal(final Integer loanID) {
|
||||
final String undoDisburseJson = "{'note' : 'UNDO DISBURSAL'}";
|
||||
log.info("IN DISBURSE LOAN");
|
||||
@@ -807,6 +830,8 @@ public class LoanTransactionHelper {
|
||||
}
|
||||
|
||||
private HashMap performLoanTransaction(final String postURLForLoanTransaction, final String jsonToBeSent) {
|
||||
log.info("URL: {}", postURLForLoanTransaction);
|
||||
log.info("Body: {}", jsonToBeSent);
|
||||
final HashMap response = Utils.performServerPost(this.requestSpec, this.responseSpec, postURLForLoanTransaction, jsonToBeSent,
|
||||
"changes");
|
||||
return (HashMap) response.get("status");
|
||||
|
||||
Reference in New Issue
Block a user