Skip to content

Commit

Permalink
Su 485 (#1357)
Browse files Browse the repository at this point in the history
* SU-485
  • Loading branch information
faheem205 authored Dec 9, 2024
1 parent e6a377d commit c0199a3
Show file tree
Hide file tree
Showing 8 changed files with 220 additions and 88 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1080,7 +1080,7 @@ public CommandProcessingResult blockClient(final Long clientId, final JsonComman
|| (incident.isVoluntary() && loanCharge.isVoluntaryInsurance())) {
if (loanCharge.getAmountOutstanding(loan.getCurrency()).isGreaterThanZero()) {
InsuranceIncidentNoveltyNews insuranceIncidentNoveltyNews = InsuranceIncidentNoveltyNews.instance(loan,
loanCharge, 0, incident, loan.getClosedOnDate(), BigDecimal.ZERO);
loanCharge, 0, incident, blockedOnDate, BigDecimal.ZERO);
this.insuranceIncidentNoveltyNewsRepository.saveAndFlush(insuranceIncidentNoveltyNews);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.apache.fineract.portfolio.loanaccount.data;

import java.time.LocalDate;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
Expand All @@ -12,6 +13,7 @@ public class DefaultOrCancelInsuranceInstallmentData {
private Long loanId;
private Long loanChargeId;
private Integer installment;
private LocalDate suspensionDate;

public Long loanId() {
return loanId;
Expand All @@ -36,4 +38,12 @@ public Integer installment() {
public void setInstallment(Integer installment) {
this.installment = installment;
}

public LocalDate suspensionDate() {
return suspensionDate;
}

public void setSuspensionDate(LocalDate suspensionDate) {
this.suspensionDate = suspensionDate;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ public class LoanArrearsAgingServiceImpl implements LoanArrearsAgingService {
private final PlatformSecurityContext context;
private final InsuranceIncidentRepository insuranceIncidentRepository;
private final InsuranceIncidentNoveltyNewsRepository insuranceIncidentNoveltyNewsRepository;
private final LoanReadPlatformService loanReadPlatformService;

@PostConstruct
public void registerForNotification() {
Expand Down Expand Up @@ -653,6 +654,18 @@ private void createSuspensionRemovedNews(Loan loan) {
daysInArrears = 0;
}
if (daysInArrears >= 90) {
// In case of transaction rollback, a loan can move again to suspension
LocalDate date = null;
try {
date = this.jdbcTemplate.queryForObject(
"select overdue_since_date_derived aging_days from m_loan_arrears_aging mlaa where mlaa.loan_id =?",
LocalDate.class, loan.getId());
} catch (final EmptyResultDataAccessException e) {
// not in arrears
}
if (date != null) {
temporarySuspendDefaultInsuranceCharges(loan, date.plusDays(90));
}
return;
}
final LocalDate currentDate = DateUtils.getBusinessLocalDate();
Expand All @@ -670,17 +683,25 @@ private void createSuspensionRemovedNews(Loan loan) {
// Do not add suspension news if loan is already in suspension
return;
}
} else {
// Loan was never in arrears
return;
}
Collection<LoanCharge> loanCharges = loan.getInsuranceChargesForNoveltyIncidentReporting(incident.isMandatory(),
incident.isVoluntary());
LocalDate transactionDate = currentDate;
List<LoanTransaction> transactions = loan.retrieveListOfTransactionsPostDisbursementExcludeAccruals();
if (!transactions.isEmpty()) {
transactionDate = transactions.get(transactions.size() - 1).getTransactionDate();
}
if (loanCharges != null && !loanCharges.isEmpty()) {
for (LoanCharge loanCharge : loanCharges) {
if (loanCharge.getAmountOutstanding(loan.getCurrency()).isGreaterThanZero()) {
if ((incident.isMandatory() && loanCharge.isMandatoryInsurance())
|| (incident.isVoluntary() && loanCharge.isVoluntaryInsurance())) {
BigDecimal cumulative = BigDecimal.ZERO;
InsuranceIncidentNoveltyNews insuranceIncidentNoveltyNews = InsuranceIncidentNoveltyNews.instance(loan, loanCharge,
null, incident, currentDate, cumulative);
null, incident, transactionDate, cumulative);

this.insuranceIncidentNoveltyNewsRepository.saveAndFlush(insuranceIncidentNoveltyNews);
}
Expand All @@ -689,4 +710,37 @@ private void createSuspensionRemovedNews(Loan loan) {
}
}

private void temporarySuspendDefaultInsuranceCharges(Loan loan, LocalDate suspensionDate) {
final LocalDate currentDate = DateUtils.getBusinessLocalDate();
InsuranceIncident incident = this.insuranceIncidentRepository
.findByIncidentType(InsuranceIncidentType.TEMPORARY_SUSPENSION_DUE_TO_DEFAULT);
InsuranceIncident suspensionRemovedIncident = this.insuranceIncidentRepository
.findByIncidentType(InsuranceIncidentType.SUSPENSION_REMOVED);
if (incident == null || (!incident.isMandatory() && !incident.isVoluntary())) {
throw new InsuranceIncidentNotFoundException(InsuranceIncidentType.TEMPORARY_SUSPENSION_DUE_TO_DEFAULT.name());
}

Optional<InsuranceIncidentNoveltyNews> lastSuspensionNewsOptional = this.insuranceIncidentNoveltyNewsRepository
.findLastSuspensionIfPresent(loan.getId(), incident.getId(), suspensionRemovedIncident.getId());
if (lastSuspensionNewsOptional.isPresent()) {
InsuranceIncidentNoveltyNews news = lastSuspensionNewsOptional.get();
if (news.getInsuranceIncident().getIncidentType().equals(InsuranceIncidentType.TEMPORARY_SUSPENSION_DUE_TO_DEFAULT)) {
// Do not add suspension news if loan is already in suspension
return;
}
}
for (LoanCharge loanCharge : loan.getCharges()) {
if (loanCharge.getAmountOutstanding(loan.getCurrency()).isGreaterThanZero()) {
if ((incident.isMandatory() && loanCharge.isMandatoryInsurance())
|| (incident.isVoluntary() && loanCharge.isVoluntaryInsurance())) {
BigDecimal cumulative = BigDecimal.ZERO;
InsuranceIncidentNoveltyNews insuranceIncidentNoveltyNews = InsuranceIncidentNoveltyNews.instance(loan, loanCharge,
null, incident, suspensionDate, cumulative);

this.insuranceIncidentNoveltyNewsRepository.saveAndFlush(insuranceIncidentNoveltyNews);
}
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3341,7 +3341,8 @@ ml.id loanId, min(mlrs.installment) installment, mlc.id loanChargeId

public String suspensionSchema() {
return """
distinct ml.id loanId, min(mlrs.installment) installment, mlc.id loanChargeId
distinct ml.id loanId, min(mlrs.installment) installment, mlc.id loanChargeId, mlaa.overdue_since_date_derived overdue_date,
? suspension_period
from
m_loan ml
join m_loan_arrears_aging mlaa on mlaa.loan_id = ml.id
Expand All @@ -3360,8 +3361,10 @@ public DefaultOrCancelInsuranceInstallmentData mapRow(@NotNull ResultSet rs, int
final Long loanId = JdbcSupport.getLong(rs, "loanId");
final Integer installment = JdbcSupport.getInteger(rs, "installment");
final Long loanChargeId = JdbcSupport.getLong(rs, "loanChargeId");
final LocalDate overDueDate = JdbcSupport.getLocalDate(rs, "overdue_date");
final Long suspensionPeriod = JdbcSupport.getLong(rs, "suspension_period");

return new DefaultOrCancelInsuranceInstallmentData(loanId, loanChargeId, installment);
return new DefaultOrCancelInsuranceInstallmentData(loanId, loanChargeId, installment, overDueDate.plusDays(suspensionPeriod));
}
}

Expand All @@ -3372,7 +3375,7 @@ public List<DefaultOrCancelInsuranceInstallmentData> getLoanDataWithDefaultOrCan
final DefaultInsuranceMapper rowMapper = new DefaultInsuranceMapper();
String sql = "SELECT " + rowMapper.schema();
Object[] params = null;
sql = sql + " and mc.charge_calculation_enum = " + ChargeCalculationType.FLAT_SEGOVOLUNTARIO.getValue();
// sql = sql + " and mc.charge_calculation_enum = " + ChargeCalculationType.FLAT_SEGOVOLUNTARIO.getValue();
if (loanId == null && insuranceCode == null) {
sql = sql + " and mlrs.duedate < CURRENT_DATE " + " and CURRENT_DATE - mlrs.duedate = 60 ";
params = new Object[] {};
Expand All @@ -3399,8 +3402,9 @@ public List<DefaultOrCancelInsuranceInstallmentData> getLoanDataWithDefaultManda

final DefaultInsuranceMapper rowMapper = new DefaultInsuranceMapper();
String sql = "SELECT " + rowMapper.suspensionSchema();
Object[] params = new Object[] { numberOfDays };
sql = sql + " and (CURRENT_DATE - mlaa.overdue_since_date_derived) >= ? " + " group by ml.id, mlc.id order by ml.id";
Object[] params = new Object[] { numberOfDays, numberOfDays };
sql = sql + " and (CURRENT_DATE - mlaa.overdue_since_date_derived) >= ? "
+ " group by ml.id, mlc.id, mlaa.overdue_since_date_derived order by ml.id";

return this.jdbcTemplate.query(sql, rowMapper, params); // NOSONAR
}
Expand Down
Loading

0 comments on commit c0199a3

Please sign in to comment.