Merge pull request #1471 from pramodn02/performanceissues
MIFOSX-2166: changed transaction scope to loan level instead of repay…
This commit is contained in:
+18
-2
@@ -48,7 +48,15 @@ public class LoanAccrualPlatformServiceImpl implements LoanAccrualPlatformServic
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (Map.Entry<Long, Collection<LoanScheduleAccrualData>> mapEntry : loanDataMap.entrySet()) {
|
for (Map.Entry<Long, Collection<LoanScheduleAccrualData>> mapEntry : loanDataMap.entrySet()) {
|
||||||
this.loanAccrualWritePlatformService.addAccrualAccounting(mapEntry.getKey(), mapEntry.getValue(), sb);
|
try {
|
||||||
|
this.loanAccrualWritePlatformService.addAccrualAccounting(mapEntry.getKey(), mapEntry.getValue());
|
||||||
|
} catch (Exception e) {
|
||||||
|
Throwable realCause = e;
|
||||||
|
if (e.getCause() != null) {
|
||||||
|
realCause = e.getCause();
|
||||||
|
}
|
||||||
|
sb.append("failed to add accural transaction for loan " + mapEntry.getKey() + " with message " + realCause.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sb.length() > 0) { throw new JobExecutionException(sb.toString()); }
|
if (sb.length() > 0) { throw new JobExecutionException(sb.toString()); }
|
||||||
@@ -82,7 +90,15 @@ public class LoanAccrualPlatformServiceImpl implements LoanAccrualPlatformServic
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (Map.Entry<Long, Collection<LoanScheduleAccrualData>> mapEntry : loanDataMap.entrySet()) {
|
for (Map.Entry<Long, Collection<LoanScheduleAccrualData>> mapEntry : loanDataMap.entrySet()) {
|
||||||
this.loanAccrualWritePlatformService.addPeriodicAccruals(tilldate, mapEntry.getKey(), mapEntry.getValue(), sb);
|
try {
|
||||||
|
this.loanAccrualWritePlatformService.addPeriodicAccruals(tilldate, mapEntry.getKey(), mapEntry.getValue());
|
||||||
|
} catch (Exception e) {
|
||||||
|
Throwable realCause = e;
|
||||||
|
if (e.getCause() != null) {
|
||||||
|
realCause = e.getCause();
|
||||||
|
}
|
||||||
|
sb.append("failed to add accural transaction for loan " + mapEntry.getKey() + " with message " + realCause.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
|
|||||||
+2
-2
@@ -12,8 +12,8 @@ import org.mifosplatform.portfolio.loanaccount.data.LoanScheduleAccrualData;
|
|||||||
|
|
||||||
public interface LoanAccrualWritePlatformService {
|
public interface LoanAccrualWritePlatformService {
|
||||||
|
|
||||||
void addAccrualAccounting(Long loanId, Collection<LoanScheduleAccrualData> loanScheduleAccrualDatas, StringBuilder sb);
|
void addAccrualAccounting(Long loanId, Collection<LoanScheduleAccrualData> loanScheduleAccrualDatas) throws Exception;
|
||||||
|
|
||||||
void addPeriodicAccruals(LocalDate tilldate, Long loanId, Collection<LoanScheduleAccrualData> loanScheduleAccrualDatas, StringBuilder sb);
|
void addPeriodicAccruals(LocalDate tilldate, Long loanId, Collection<LoanScheduleAccrualData> loanScheduleAccrualDatas) throws Exception;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+54
-86
@@ -32,11 +32,8 @@ import org.mifosplatform.portfolio.loanaccount.loanschedule.data.LoanSchedulePer
|
|||||||
import org.mifosplatform.portfolio.loanproduct.service.LoanEnumerations;
|
import org.mifosplatform.portfolio.loanproduct.service.LoanEnumerations;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.jdbc.core.JdbcTemplate;
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
import org.springframework.orm.jpa.JpaTransactionManager;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.TransactionStatus;
|
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.transaction.support.DefaultTransactionDefinition;
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class LoanAccrualWritePlatformServiceImpl implements LoanAccrualWritePlatformService {
|
public class LoanAccrualWritePlatformServiceImpl implements LoanAccrualWritePlatformService {
|
||||||
@@ -46,89 +43,67 @@ public class LoanAccrualWritePlatformServiceImpl implements LoanAccrualWritePlat
|
|||||||
private final JdbcTemplate jdbcTemplate;
|
private final JdbcTemplate jdbcTemplate;
|
||||||
private final DataSource dataSource;
|
private final DataSource dataSource;
|
||||||
private final JournalEntryWritePlatformService journalEntryWritePlatformService;
|
private final JournalEntryWritePlatformService journalEntryWritePlatformService;
|
||||||
private final JpaTransactionManager transactionManager;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public LoanAccrualWritePlatformServiceImpl(final RoutingDataSource dataSource, final LoanReadPlatformService loanReadPlatformService,
|
public LoanAccrualWritePlatformServiceImpl(final RoutingDataSource dataSource, final LoanReadPlatformService loanReadPlatformService,
|
||||||
final JournalEntryWritePlatformService journalEntryWritePlatformService, final JpaTransactionManager transactionManager,
|
final JournalEntryWritePlatformService journalEntryWritePlatformService,
|
||||||
final LoanChargeReadPlatformService loanChargeReadPlatformService) {
|
final LoanChargeReadPlatformService loanChargeReadPlatformService) {
|
||||||
this.loanReadPlatformService = loanReadPlatformService;
|
this.loanReadPlatformService = loanReadPlatformService;
|
||||||
this.dataSource = dataSource;
|
this.dataSource = dataSource;
|
||||||
this.jdbcTemplate = new JdbcTemplate(this.dataSource);
|
this.jdbcTemplate = new JdbcTemplate(this.dataSource);
|
||||||
this.journalEntryWritePlatformService = journalEntryWritePlatformService;
|
this.journalEntryWritePlatformService = journalEntryWritePlatformService;
|
||||||
this.transactionManager = transactionManager;
|
|
||||||
this.loanChargeReadPlatformService = loanChargeReadPlatformService;
|
this.loanChargeReadPlatformService = loanChargeReadPlatformService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public void addAccrualAccounting(final Long loanId, final Collection<LoanScheduleAccrualData> loanScheduleAccrualDatas,
|
public void addAccrualAccounting(final Long loanId, final Collection<LoanScheduleAccrualData> loanScheduleAccrualDatas)
|
||||||
final StringBuilder sb) {
|
throws Exception {
|
||||||
Collection<LoanChargeData> chargeData = this.loanChargeReadPlatformService.retrieveLoanChargesForAccural(loanId);
|
Collection<LoanChargeData> chargeData = this.loanChargeReadPlatformService.retrieveLoanChargesForAccural(loanId);
|
||||||
Collection<LoanSchedulePeriodData> loanWaiverScheduleData = new ArrayList<>(1);
|
Collection<LoanSchedulePeriodData> loanWaiverScheduleData = new ArrayList<>(1);
|
||||||
Collection<LoanTransactionData> loanWaiverTansactionData = new ArrayList<>(1);
|
Collection<LoanTransactionData> loanWaiverTansactionData = new ArrayList<>(1);
|
||||||
|
|
||||||
for (final LoanScheduleAccrualData accrualData : loanScheduleAccrualDatas) {
|
for (final LoanScheduleAccrualData accrualData : loanScheduleAccrualDatas) {
|
||||||
try {
|
if (accrualData.getWaivedInterestIncome() != null && loanWaiverScheduleData.isEmpty()) {
|
||||||
if (accrualData.getWaivedInterestIncome() != null && loanWaiverScheduleData.isEmpty()) {
|
loanWaiverScheduleData = this.loanReadPlatformService.fetchWaiverInterestRepaymentData(accrualData.getLoanId());
|
||||||
loanWaiverScheduleData = this.loanReadPlatformService.fetchWaiverInterestRepaymentData(accrualData.getLoanId());
|
loanWaiverTansactionData = this.loanReadPlatformService.retrieveWaiverLoanTransactions(accrualData.getLoanId());
|
||||||
loanWaiverTansactionData = this.loanReadPlatformService.retrieveWaiverLoanTransactions(accrualData.getLoanId());
|
|
||||||
}
|
|
||||||
updateCharges(chargeData, accrualData, accrualData.getFromDateAsLocaldate(), accrualData.getDueDateAsLocaldate());
|
|
||||||
updateInterestIncome(accrualData, loanWaiverTansactionData, loanWaiverScheduleData, accrualData.getDueDateAsLocaldate());
|
|
||||||
addAccrualAccounting(accrualData);
|
|
||||||
} catch (Exception e) {
|
|
||||||
Throwable realCause = e;
|
|
||||||
if (e.getCause() != null) {
|
|
||||||
realCause = e.getCause();
|
|
||||||
}
|
|
||||||
sb.append("failed to add accural transaction for repayment with id " + accrualData.getRepaymentScheduleId()
|
|
||||||
+ " with message " + realCause.getMessage());
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
updateCharges(chargeData, accrualData, accrualData.getFromDateAsLocaldate(), accrualData.getDueDateAsLocaldate());
|
||||||
|
updateInterestIncome(accrualData, loanWaiverTansactionData, loanWaiverScheduleData, accrualData.getDueDateAsLocaldate());
|
||||||
|
addAccrualAccounting(accrualData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public void addPeriodicAccruals(final LocalDate tilldate, Long loanId, Collection<LoanScheduleAccrualData> loanScheduleAccrualDatas,
|
public void addPeriodicAccruals(final LocalDate tilldate, Long loanId, Collection<LoanScheduleAccrualData> loanScheduleAccrualDatas)
|
||||||
StringBuilder sb) {
|
throws Exception {
|
||||||
boolean firstTime = true;
|
boolean firstTime = true;
|
||||||
LocalDate accruredTill = null;
|
LocalDate accruredTill = null;
|
||||||
Collection<LoanChargeData> chargeData = this.loanChargeReadPlatformService.retrieveLoanChargesForAccural(loanId);
|
Collection<LoanChargeData> chargeData = this.loanChargeReadPlatformService.retrieveLoanChargesForAccural(loanId);
|
||||||
Collection<LoanSchedulePeriodData> loanWaiverScheduleData = new ArrayList<>(1);
|
Collection<LoanSchedulePeriodData> loanWaiverScheduleData = new ArrayList<>(1);
|
||||||
Collection<LoanTransactionData> loanWaiverTansactionData = new ArrayList<>(1);
|
Collection<LoanTransactionData> loanWaiverTansactionData = new ArrayList<>(1);
|
||||||
for (final LoanScheduleAccrualData accrualData : loanScheduleAccrualDatas) {
|
for (final LoanScheduleAccrualData accrualData : loanScheduleAccrualDatas) {
|
||||||
try {
|
if (accrualData.getWaivedInterestIncome() != null && loanWaiverScheduleData.isEmpty()) {
|
||||||
if (accrualData.getWaivedInterestIncome() != null && loanWaiverScheduleData.isEmpty()) {
|
loanWaiverScheduleData = this.loanReadPlatformService.fetchWaiverInterestRepaymentData(accrualData.getLoanId());
|
||||||
loanWaiverScheduleData = this.loanReadPlatformService.fetchWaiverInterestRepaymentData(accrualData.getLoanId());
|
loanWaiverTansactionData = this.loanReadPlatformService.retrieveWaiverLoanTransactions(accrualData.getLoanId());
|
||||||
loanWaiverTansactionData = this.loanReadPlatformService.retrieveWaiverLoanTransactions(accrualData.getLoanId());
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (accrualData.getDueDateAsLocaldate().isAfter(tilldate)) {
|
if (accrualData.getDueDateAsLocaldate().isAfter(tilldate)) {
|
||||||
if (accruredTill == null || firstTime) {
|
if (accruredTill == null || firstTime) {
|
||||||
accruredTill = accrualData.getAccruedTill();
|
accruredTill = accrualData.getAccruedTill();
|
||||||
firstTime = false;
|
firstTime = false;
|
||||||
}
|
}
|
||||||
if (accruredTill == null || accruredTill.isBefore(tilldate)) {
|
if (accruredTill == null || accruredTill.isBefore(tilldate)) {
|
||||||
updateCharges(chargeData, accrualData, accrualData.getFromDateAsLocaldate(), tilldate);
|
updateCharges(chargeData, accrualData, accrualData.getFromDateAsLocaldate(), tilldate);
|
||||||
updateInterestIncome(accrualData, loanWaiverTansactionData, loanWaiverScheduleData, tilldate);
|
|
||||||
addAccrualTillSpecificDate(tilldate, accrualData);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
updateCharges(chargeData, accrualData, accrualData.getFromDateAsLocaldate(), accrualData.getDueDateAsLocaldate());
|
|
||||||
updateInterestIncome(accrualData, loanWaiverTansactionData, loanWaiverScheduleData, tilldate);
|
updateInterestIncome(accrualData, loanWaiverTansactionData, loanWaiverScheduleData, tilldate);
|
||||||
addAccrualAccounting(accrualData);
|
addAccrualTillSpecificDate(tilldate, accrualData);
|
||||||
accruredTill = accrualData.getDueDateAsLocaldate();
|
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} else {
|
||||||
Throwable realCause = e;
|
updateCharges(chargeData, accrualData, accrualData.getFromDateAsLocaldate(), accrualData.getDueDateAsLocaldate());
|
||||||
if (e.getCause() != null) {
|
updateInterestIncome(accrualData, loanWaiverTansactionData, loanWaiverScheduleData, tilldate);
|
||||||
realCause = e.getCause();
|
addAccrualAccounting(accrualData);
|
||||||
}
|
accruredTill = accrualData.getDueDateAsLocaldate();
|
||||||
sb.append("failed to add accural transaction for repayment with id " + accrualData.getRepaymentScheduleId()
|
|
||||||
+ " with message " + realCause.getMessage());
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -265,41 +240,34 @@ public class LoanAccrualWritePlatformServiceImpl implements LoanAccrualWritePlat
|
|||||||
private void addAccrualAccounting(LoanScheduleAccrualData scheduleAccrualData, BigDecimal amount, BigDecimal interestportion,
|
private void addAccrualAccounting(LoanScheduleAccrualData scheduleAccrualData, BigDecimal amount, BigDecimal interestportion,
|
||||||
BigDecimal totalAccInterest, BigDecimal feeportion, BigDecimal totalAccFee, BigDecimal penaltyportion,
|
BigDecimal totalAccInterest, BigDecimal feeportion, BigDecimal totalAccFee, BigDecimal penaltyportion,
|
||||||
BigDecimal totalAccPenalty, final LocalDate accruedTill) throws Exception {
|
BigDecimal totalAccPenalty, final LocalDate accruedTill) throws Exception {
|
||||||
TransactionStatus transactionStatus = this.transactionManager.getTransaction(new DefaultTransactionDefinition());
|
String transactionSql = "INSERT INTO m_loan_transaction (loan_id,office_id,is_reversed,transaction_type_enum,transaction_date,amount,interest_portion_derived,"
|
||||||
try {
|
+ "fee_charges_portion_derived,penalty_charges_portion_derived, submitted_on_date) VALUES (?, ?, 0, ?, ?, ?, ?, ?, ?, ?)";
|
||||||
String transactionSql = "INSERT INTO m_loan_transaction (loan_id,office_id,is_reversed,transaction_type_enum,transaction_date,amount,interest_portion_derived,"
|
this.jdbcTemplate.update(transactionSql, scheduleAccrualData.getLoanId(), scheduleAccrualData.getOfficeId(),
|
||||||
+ "fee_charges_portion_derived,penalty_charges_portion_derived, submitted_on_date) VALUES (?, ?, 0, ?, ?, ?, ?, ?, ?, ?)";
|
LoanTransactionType.ACCRUAL.getValue(), accruedTill.toDate(), amount, interestportion, feeportion, penaltyportion,
|
||||||
this.jdbcTemplate.update(transactionSql, scheduleAccrualData.getLoanId(), scheduleAccrualData.getOfficeId(),
|
DateUtils.getDateOfTenant());
|
||||||
LoanTransactionType.ACCRUAL.getValue(), accruedTill.toDate(), amount, interestportion, feeportion, penaltyportion,
|
@SuppressWarnings("deprecation")
|
||||||
DateUtils.getDateOfTenant());
|
final Long transactonId = this.jdbcTemplate.queryForLong("SELECT LAST_INSERT_ID()");
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
final Long transactonId = this.jdbcTemplate.queryForLong("SELECT LAST_INSERT_ID()");
|
|
||||||
|
|
||||||
Map<LoanChargeData, BigDecimal> applicableCharges = scheduleAccrualData.getApplicableCharges();
|
Map<LoanChargeData, BigDecimal> applicableCharges = scheduleAccrualData.getApplicableCharges();
|
||||||
String chargespaidSql = "INSERT INTO m_loan_charge_paid_by (loan_transaction_id, loan_charge_id, amount,installment_number) VALUES (?,?,?,?)";
|
String chargespaidSql = "INSERT INTO m_loan_charge_paid_by (loan_transaction_id, loan_charge_id, amount,installment_number) VALUES (?,?,?,?)";
|
||||||
for (Map.Entry<LoanChargeData, BigDecimal> entry : applicableCharges.entrySet()) {
|
for (Map.Entry<LoanChargeData, BigDecimal> entry : applicableCharges.entrySet()) {
|
||||||
LoanChargeData chargeData = entry.getKey();
|
LoanChargeData chargeData = entry.getKey();
|
||||||
this.jdbcTemplate.update(chargespaidSql, transactonId, chargeData.getId(), entry.getValue(),
|
this.jdbcTemplate.update(chargespaidSql, transactonId, chargeData.getId(), entry.getValue(),
|
||||||
scheduleAccrualData.getInstallmentNumber());
|
scheduleAccrualData.getInstallmentNumber());
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, Object> transactionMap = toMapData(transactonId, amount, interestportion, feeportion, penaltyportion,
|
|
||||||
scheduleAccrualData, accruedTill);
|
|
||||||
|
|
||||||
String repaymetUpdatesql = "UPDATE m_loan_repayment_schedule SET accrual_interest_derived=?, accrual_fee_charges_derived=?, "
|
|
||||||
+ "accrual_penalty_charges_derived=? WHERE id=?";
|
|
||||||
this.jdbcTemplate.update(repaymetUpdatesql, totalAccInterest, totalAccFee, totalAccPenalty,
|
|
||||||
scheduleAccrualData.getRepaymentScheduleId());
|
|
||||||
|
|
||||||
String updateLoan = "UPDATE m_loan SET accrued_till=? WHERE id=?";
|
|
||||||
this.jdbcTemplate.update(updateLoan, accruedTill.toDate(), scheduleAccrualData.getLoanId());
|
|
||||||
final Map<String, Object> accountingBridgeData = deriveAccountingBridgeData(scheduleAccrualData, transactionMap);
|
|
||||||
this.journalEntryWritePlatformService.createJournalEntriesForLoan(accountingBridgeData);
|
|
||||||
} catch (Exception e) {
|
|
||||||
this.transactionManager.rollback(transactionStatus);
|
|
||||||
throw e;
|
|
||||||
}
|
}
|
||||||
this.transactionManager.commit(transactionStatus);
|
|
||||||
|
Map<String, Object> transactionMap = toMapData(transactonId, amount, interestportion, feeportion, penaltyportion,
|
||||||
|
scheduleAccrualData, accruedTill);
|
||||||
|
|
||||||
|
String repaymetUpdatesql = "UPDATE m_loan_repayment_schedule SET accrual_interest_derived=?, accrual_fee_charges_derived=?, "
|
||||||
|
+ "accrual_penalty_charges_derived=? WHERE id=?";
|
||||||
|
this.jdbcTemplate.update(repaymetUpdatesql, totalAccInterest, totalAccFee, totalAccPenalty,
|
||||||
|
scheduleAccrualData.getRepaymentScheduleId());
|
||||||
|
|
||||||
|
String updateLoan = "UPDATE m_loan SET accrued_till=? WHERE id=?";
|
||||||
|
this.jdbcTemplate.update(updateLoan, accruedTill.toDate(), scheduleAccrualData.getLoanId());
|
||||||
|
final Map<String, Object> accountingBridgeData = deriveAccountingBridgeData(scheduleAccrualData, transactionMap);
|
||||||
|
this.journalEntryWritePlatformService.createJournalEntriesForLoan(accountingBridgeData);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Object> deriveAccountingBridgeData(final LoanScheduleAccrualData loanScheduleAccrualData,
|
public Map<String, Object> deriveAccountingBridgeData(final LoanScheduleAccrualData loanScheduleAccrualData,
|
||||||
|
|||||||
Reference in New Issue
Block a user