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>
|
||||
Reference in New Issue
Block a user