diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exception/MultiException.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exception/MultiException.java
index 79ba28bef..9e8e28a3f 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exception/MultiException.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/exception/MultiException.java
@@ -18,6 +18,14 @@
*/
package org.apache.fineract.infrastructure.core.exception;
+import com.google.common.io.CharStreams;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
/**
* Exception with multiple root causes.
*
@@ -25,21 +33,69 @@ package org.apache.fineract.infrastructure.core.exception;
* each of which could fail, but where we don't want to fail immediately but continue, and
* then fail at end.
*
- *
The failures MUST each be logged within the loop, as they occur; this exception is
- * only thrown to propagate the failure, but will not contain and re-log the details.
+ *
The failures should typically also each be logged within the loop, as they occur; this exception is
+ * only thrown to propagate the failure, and the caller may or may not log this with the details.
+ *
+ *
Originally inspired by org.junit.runners.model.MultipleFailureException
.
*
* @author Michael Vorburger.ch
*/
public class MultiException extends Exception {
- private final int n;
+ private final List throwables;
- public MultiException(int n) {
- super(n + "x failures occured here (details have been previously logged");
- this.n = n;
+ public MultiException(List problems) {
+ super("MultiException with " + problems.size() + " contained causes (details available)");
+ if (problems.isEmpty()) { throw new IllegalArgumentException("List of Throwables must not be empty"); }
+ this.throwables = new ArrayList<>(problems);
}
- public int getCausesSize() {
- return n;
+ public List getCauses() {
+ return Collections.unmodifiableList(throwables);
+ }
+
+ @Override
+ public String getMessage() {
+ int i = 0;
+ StringBuilder sb = new StringBuilder(super.getMessage());
+ for (Throwable e : throwables) {
+ sb.append("\n ");
+ sb.append(++i);
+ sb.append(". ");
+ Writer w = CharStreams.asWriter(sb);
+ e.printStackTrace(new PrintWriter(w, true));
+ }
+ sb.append("\n which was itself thrown..");
+ return sb.toString();
+ }
+
+ @Override
+ public void printStackTrace() {
+ System.err.println(super.getMessage());
+ int i = 0;
+ for (Throwable e : throwables) {
+ System.err.print(++i + ".");
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public void printStackTrace(PrintStream s) {
+ s.println(super.getMessage());
+ int i = 0;
+ for (Throwable e : throwables) {
+ s.print(++i + ".");
+ e.printStackTrace(s);
+ }
+ }
+
+ @Override
+ public void printStackTrace(PrintWriter s) {
+ s.println(super.getMessage());
+ int i = 0;
+ for (Throwable e : throwables) {
+ s.print(++i + ".");
+ e.printStackTrace(s);
+ }
}
}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/exception/JobExecutionException.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/exception/JobExecutionException.java
index c66b9d612..02dc85776 100755
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/exception/JobExecutionException.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/exception/JobExecutionException.java
@@ -18,11 +18,16 @@
*/
package org.apache.fineract.infrastructure.jobs.exception;
+import java.util.List;
import org.apache.fineract.infrastructure.core.exception.MultiException;
public class JobExecutionException extends MultiException {
- public JobExecutionException(int n) {
- super(n);
+ public JobExecutionException(List problems) {
+ super(problems);
+ }
+
+ public JobExecutionException(MultiException multiException) {
+ super(multiException.getCauses());
}
}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/service/StandingInstructionWritePlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/service/StandingInstructionWritePlatformServiceImpl.java
index a65bfec1b..9594b43e6 100755
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/service/StandingInstructionWritePlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/account/service/StandingInstructionWritePlatformServiceImpl.java
@@ -24,8 +24,10 @@ import static org.apache.fineract.portfolio.account.AccountDetailConstants.toAcc
import static org.apache.fineract.portfolio.account.api.StandingInstructionApiConstants.statusParamName;
import java.math.BigDecimal;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
@@ -193,7 +195,7 @@ public class StandingInstructionWritePlatformServiceImpl implements StandingInst
public void executeStandingInstructions() throws JobExecutionException {
Collection instructionDatas = this.standingInstructionReadPlatformService
.retrieveAll(StandingInstructionStatus.ACTIVE.getValue());
- final StringBuilder sb = new StringBuilder();
+ List errors = new ArrayList<>();
for (StandingInstructionData data : instructionDatas) {
boolean isDueForTransfer = false;
AccountTransferRecurrenceType recurrenceType = data.recurrenceType();
@@ -240,7 +242,7 @@ public class StandingInstructionWritePlatformServiceImpl implements StandingInst
+ " Standing instruction trasfer ", null, null, null, null, data.toTransferType(), null, null, data
.transferType().getValue(), null, null, null, null, null, fromSavingsAccount,
isRegularTransaction, isExceptionForBalanceCheck);
- final boolean transferCompleted = transferAmount(sb, accountTransferDTO, data.getId());
+ final boolean transferCompleted = transferAmount(errors, accountTransferDTO, data.getId());
if(transferCompleted){
final String updateQuery = "UPDATE m_account_transfer_standing_instructions SET last_run_date = ? where id = ?";
@@ -249,14 +251,10 @@ public class StandingInstructionWritePlatformServiceImpl implements StandingInst
}
}
- if (sb.length() > 0) {
- logger.error("executeStandingInstructions (transferAmount) encountered failure/s: {}", sb.toString());
- // This is a bit of a hack (related to https://issues.apache.org/jira/browse/FINERACT-858) and could be improved..
- throw new JobExecutionException(123456789);
- }
+ if (!errors.isEmpty()) { throw new JobExecutionException(errors); }
}
- private boolean transferAmount(final StringBuilder sb, final AccountTransferDTO accountTransferDTO, final Long instructionId) {
+ private boolean transferAmount(final List errors, final AccountTransferDTO accountTransferDTO, final Long instructionId) {
boolean transferCompleted = true;
StringBuilder errorLog = new StringBuilder();
StringBuilder updateQuery = new StringBuilder(
@@ -264,24 +262,20 @@ public class StandingInstructionWritePlatformServiceImpl implements StandingInst
try {
this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO);
} catch (final PlatformApiDataValidationException e) {
- sb.append("Validation exception while trasfering funds for standing Instruction id").append(instructionId).append(" from ")
- .append(accountTransferDTO.getFromAccountId()).append(" to ").append(accountTransferDTO.getToAccountId())
- .append("--------");
+ errors.add(new Exception("Validation exception while transfering funds for standing Instruction id" + instructionId + " from "
+ + accountTransferDTO.getFromAccountId() + " to " + accountTransferDTO.getToAccountId(), e));
errorLog.append("Validation exception while trasfering funds " + e.getDefaultUserMessage());
} catch (final InsufficientAccountBalanceException e) {
- sb.append("InsufficientAccountBalance Exception while trasfering funds for standing Instruction id").append(instructionId)
- .append(" from ").append(accountTransferDTO.getFromAccountId()).append(" to ")
- .append(accountTransferDTO.getToAccountId()).append("--------");
+ errors.add(new Exception("InsufficientAccountBalance Exception while trasfering funds for standing Instruction id"
+ + instructionId + " from " + accountTransferDTO.getFromAccountId() + " to " + accountTransferDTO.getToAccountId(), e));
errorLog.append("InsufficientAccountBalance Exception ");
} catch (final AbstractPlatformServiceUnavailableException e) {
- sb.append("Platform exception while trasfering funds for standing Instruction id").append(instructionId).append(" from ")
- .append(accountTransferDTO.getFromAccountId()).append(" to ").append(accountTransferDTO.getToAccountId())
- .append("--------");
+ errors.add(new Exception("Platform exception while trasfering funds for standing Instruction id" + instructionId + " from "
+ + accountTransferDTO.getFromAccountId() + " to " + accountTransferDTO.getToAccountId(), e));
errorLog.append("Platform exception while trasfering funds " + e.getDefaultUserMessage());
} catch (Exception e) {
- sb.append("Exception while trasfering funds for standing Instruction id").append(instructionId).append(" from ")
- .append(accountTransferDTO.getFromAccountId()).append(" to ").append(accountTransferDTO.getToAccountId())
- .append("--------");
+ errors.add(new Exception("Unhandled System Exception while trasfering funds for standing Instruction id" + instructionId
+ + " from " + accountTransferDTO.getFromAccountId() + " to " + accountTransferDTO.getToAccountId(), e));
errorLog.append("Exception while trasfering funds " + e.getMessage());
}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualPlatformServiceImpl.java
index 284b692c0..5798c962b 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualPlatformServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanAccrualPlatformServiceImpl.java
@@ -21,6 +21,7 @@ package org.apache.fineract.portfolio.loanaccount.service;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import org.apache.fineract.infrastructure.core.exception.MultiException;
import org.apache.fineract.infrastructure.jobs.annotation.CronTarget;
@@ -63,16 +64,16 @@ public class LoanAccrualPlatformServiceImpl implements LoanAccrualPlatformServic
}
}
- int errors = 0;
+ List errors = new ArrayList<>();
for (Map.Entry> mapEntry : loanDataMap.entrySet()) {
try {
this.loanAccrualWritePlatformService.addAccrualAccounting(mapEntry.getKey(), mapEntry.getValue());
} catch (Exception e) {
LOG.error("Failed to add accural transaction for loan {}", mapEntry.getKey(), e);
- ++errors;
+ errors.add(e);
}
}
- if (errors > 0) { throw new JobExecutionException(errors); }
+ if (!errors.isEmpty()) { throw new JobExecutionException(errors); }
}
@Override
@@ -81,18 +82,18 @@ public class LoanAccrualPlatformServiceImpl implements LoanAccrualPlatformServic
try {
addPeriodicAccruals(LocalDate.now());
} catch (MultiException e) {
- throw new JobExecutionException(e.getCausesSize());
+ throw new JobExecutionException(e);
}
}
@Override
- public void addPeriodicAccruals(final LocalDate tilldate) throws MultiException {
+ public void addPeriodicAccruals(final LocalDate tilldate) throws JobExecutionException {
Collection loanScheduleAccrualDatas = this.loanReadPlatformService.retrivePeriodicAccrualData(tilldate);
addPeriodicAccruals(tilldate, loanScheduleAccrualDatas);
}
@Override
- public void addPeriodicAccruals(final LocalDate tilldate, Collection loanScheduleAccrualDatas) throws MultiException {
+ public void addPeriodicAccruals(final LocalDate tilldate, Collection loanScheduleAccrualDatas) throws JobExecutionException {
Map> loanDataMap = new HashMap<>();
for (final LoanScheduleAccrualData accrualData : loanScheduleAccrualDatas) {
if (loanDataMap.containsKey(accrualData.getLoanId())) {
@@ -104,16 +105,16 @@ public class LoanAccrualPlatformServiceImpl implements LoanAccrualPlatformServic
}
}
- int errors = 0;
+ List errors = new ArrayList<>();
for (Map.Entry> mapEntry : loanDataMap.entrySet()) {
try {
this.loanAccrualWritePlatformService.addPeriodicAccruals(tilldate, mapEntry.getKey(), mapEntry.getValue());
} catch (Exception e) {
LOG.error("Failed to add accural transaction for loan {}", mapEntry.getKey(), e);
- ++errors;
+ errors.add(e);
}
}
- if (errors > 0) { throw new MultiException(errors); }
+ if (!errors.isEmpty()) { throw new JobExecutionException(errors); }
}
@Override
@@ -121,16 +122,16 @@ public class LoanAccrualPlatformServiceImpl implements LoanAccrualPlatformServic
public void addPeriodicAccrualsForLoansWithIncomePostedAsTransactions() throws JobExecutionException {
Collection loanIds = this.loanReadPlatformService.retrieveLoanIdsWithPendingIncomePostingTransactions();
if(loanIds != null && loanIds.size() > 0){
- int errors = 0;
+ List errors = new ArrayList<>();
for (Long loanId : loanIds) {
try {
this.loanAccrualWritePlatformService.addIncomeAndAccrualTransactions(loanId);
} catch (Exception e) {
LOG.error("Failed to add income and accrual transaction for loan {}", loanId, e);
- ++errors;
+ errors.add(e);
}
}
- if (errors > 0) { throw new JobExecutionException(errors); }
+ if (!errors.isEmpty()) { throw new JobExecutionException(errors); }
}
}
}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanSchedularServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanSchedularServiceImpl.java
index b785700f5..03edf22d8 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanSchedularServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanSchedularServiceImpl.java
@@ -95,7 +95,7 @@ public class LoanSchedularServiceImpl implements LoanSchedularService {
}
}
- int numberOfErrors = 0;
+ List exceptions = new ArrayList<>();
for (final Long loanId : overdueScheduleData.keySet()) {
try {
this.loanWritePlatformService.applyOverdueChargesForLoan(loanId, overdueScheduleData.get(loanId));
@@ -104,17 +104,17 @@ public class LoanSchedularServiceImpl implements LoanSchedularService {
final List errors = e.getErrors();
for (final ApiParameterError error : errors) {
logger.error("Apply Charges due for overdue loans failed for account {} with message: {}", loanId, error.getDeveloperMessage(), e);
- ++numberOfErrors;
}
+ exceptions.add(e);
} catch (final AbstractPlatformDomainRuleException e) {
logger.error("Apply Charges due for overdue loans failed for account {} with message: {}", loanId, e.getDefaultUserMessage(), e);
- ++numberOfErrors;
+ exceptions.add(e);
} catch (Exception e) {
logger.error("Apply Charges due for overdue loans failed for account {}", loanId, e);
- ++numberOfErrors;
+ exceptions.add(e);
}
}
- if (numberOfErrors > 0) { throw new JobExecutionException(numberOfErrors); }
+ if (!exceptions.isEmpty()) { throw new JobExecutionException(exceptions); }
}
}
@@ -129,7 +129,7 @@ public class LoanSchedularServiceImpl implements LoanSchedularService {
.fetchLoansForInterestRecalculation();
int i = 0;
if (!loanIds.isEmpty()) {
- int errors = 0;
+ List errors = new ArrayList<>();
for (Long loanId : loanIds) {
logger.info("recalculateInterest: Loan ID = {}", loanId);
Integer numberOfRetries = 0;
@@ -143,7 +143,7 @@ public class LoanSchedularServiceImpl implements LoanSchedularService {
// Fail if the transaction has been retried for maxNumberOfRetries
if (numberOfRetries >= maxNumberOfRetries) {
logger.error("Recalulate interest job has been retried for the max allowed attempts of {} and will be rolled back", numberOfRetries);
- ++errors;
+ errors.add(exception);
break;
}
// Else sleep for a random time (between 1 to 10 seconds) and continue
@@ -154,19 +154,19 @@ public class LoanSchedularServiceImpl implements LoanSchedularService {
numberOfRetries = numberOfRetries + 1;
} catch (InterruptedException e) {
logger.error("Interest recalculation for loans retry failed due to InterruptedException", e) ;
- ++errors;
+ errors.add(e);
break;
}
} catch (Exception e) {
logger.error("Interest recalculation for loans failed for account {}", loanId, e);
numberOfRetries = maxNumberOfRetries + 1;
- ++errors;
+ errors.add(e);
}
i++;
}
logger.info("recalculateInterest: Loans count {}", i);
}
- if (errors > 0) { throw new JobExecutionException(errors); }
+ if (!errors.isEmpty()) { throw new JobExecutionException(errors); }
}
}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java
index 9f549563b..d92242165 100755
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java
@@ -181,7 +181,6 @@ import org.apache.fineract.portfolio.note.domain.NoteRepository;
import org.apache.fineract.portfolio.paymentdetail.domain.PaymentDetail;
import org.apache.fineract.portfolio.paymentdetail.service.PaymentDetailWritePlatformService;
import org.apache.fineract.portfolio.savings.domain.SavingsAccount;
-import org.apache.fineract.portfolio.savings.exception.InsufficientAccountBalanceException;
import org.apache.fineract.portfolio.transfer.api.TransferApiConstants;
import org.apache.fineract.useradministration.domain.AppUser;
import org.joda.time.LocalDate;
@@ -325,27 +324,27 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
@Transactional
@Override
public CommandProcessingResult disburseGLIMLoan(final Long loanId, final JsonCommand command)
- {
- final Long parentLoanId=loanId;
- GroupLoanIndividualMonitoringAccount parentLoan=glimRepository.findById(parentLoanId).get();
- List childLoans=this.loanRepository.findByGlimId(loanId);
- CommandProcessingResult result=null;
- int count=0;
- for(Loan loan:childLoans)
- {
- result=disburseLoan(loan.getId(),command,false);
- if(result.getLoanId()!=null)
- {
- count++;
- // if all the child loans are approved, mark the parent loan as approved
- if(count==parentLoan.getChildAccountsCount())
- {
- parentLoan.setLoanStatus(LoanStatus.ACTIVE.getValue());
- glimRepository.save(parentLoan);
- }
- }
- }
- return result;
+ {
+ final Long parentLoanId=loanId;
+ GroupLoanIndividualMonitoringAccount parentLoan=glimRepository.findById(parentLoanId).get();
+ List childLoans=this.loanRepository.findByGlimId(loanId);
+ CommandProcessingResult result=null;
+ int count=0;
+ for(Loan loan:childLoans)
+ {
+ result=disburseLoan(loan.getId(),command,false);
+ if(result.getLoanId()!=null)
+ {
+ count++;
+ // if all the child loans are approved, mark the parent loan as approved
+ if(count==parentLoan.getChildAccountsCount())
+ {
+ parentLoan.setLoanStatus(LoanStatus.ACTIVE.getValue());
+ glimRepository.save(parentLoan);
+ }
+ }
+ }
+ return result;
}
@Transactional
@@ -772,27 +771,27 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
@Override
public CommandProcessingResult undoGLIMLoanDisbursal(final Long loanId, final JsonCommand command)
{
- //GroupLoanIndividualMonitoringAccount glimAccount=glimRepository.findOne(loanId);
- final Long parentLoanId=loanId;
- GroupLoanIndividualMonitoringAccount parentLoan=glimRepository.findById(parentLoanId).get();
- List childLoans=this.loanRepository.findByGlimId(loanId);
- CommandProcessingResult result=null;
- int count=0;
- for(Loan loan:childLoans)
- {
- result=undoLoanDisbursal(loan.getId(),command);
- if(result.getLoanId()!=null)
- {
- count++;
- // if all the child loans are approved, mark the parent loan as approved
- if(count==parentLoan.getChildAccountsCount())
- {
- parentLoan.setLoanStatus(LoanStatus.APPROVED.getValue());
- glimRepository.save(parentLoan);
- }
- }
- }
- return result;
+ //GroupLoanIndividualMonitoringAccount glimAccount=glimRepository.findOne(loanId);
+ final Long parentLoanId=loanId;
+ GroupLoanIndividualMonitoringAccount parentLoan=glimRepository.findById(parentLoanId).get();
+ List childLoans=this.loanRepository.findByGlimId(loanId);
+ CommandProcessingResult result=null;
+ int count=0;
+ for(Loan loan:childLoans)
+ {
+ result=undoLoanDisbursal(loan.getId(),command);
+ if(result.getLoanId()!=null)
+ {
+ count++;
+ // if all the child loans are approved, mark the parent loan as approved
+ if(count==parentLoan.getChildAccountsCount())
+ {
+ parentLoan.setLoanStatus(LoanStatus.APPROVED.getValue());
+ glimRepository.save(parentLoan);
+ }
+ }
+ }
+ return result;
}
@Transactional
@@ -854,28 +853,28 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
public CommandProcessingResult makeGLIMLoanRepayment(final Long loanId, final JsonCommand command)
{
- final Long parentLoanId=loanId;
+ final Long parentLoanId=loanId;
- GroupLoanIndividualMonitoringAccount parentLoan=glimRepository.findById(parentLoanId).get();
+ glimRepository.findById(parentLoanId).get();
- JsonArray repayments= command.arrayOfParameterNamed("formDataArray");
- JsonCommand childCommand=null;
- CommandProcessingResult result=null;
- JsonObject jsonObject=null;
+ JsonArray repayments= command.arrayOfParameterNamed("formDataArray");
+ JsonCommand childCommand=null;
+ CommandProcessingResult result=null;
+ JsonObject jsonObject=null;
- Long[] childLoanId=new Long[repayments.size()];
- for (int i = 0; i < repayments.size(); i++) {
- jsonObject=repayments.get(i).getAsJsonObject();
- LOG.info("{}",jsonObject.toString());
- childLoanId[i]=jsonObject.get("loanId").getAsLong();
- }
- int j=0;
- for(JsonElement element:repayments )
- {
- childCommand=JsonCommand.fromExistingCommand(command,element);
- result=makeLoanRepayment(childLoanId[j++],childCommand,false);
- }
- return result;
+ Long[] childLoanId=new Long[repayments.size()];
+ for (int i = 0; i < repayments.size(); i++) {
+ jsonObject=repayments.get(i).getAsJsonObject();
+ LOG.info("{}",jsonObject.toString());
+ childLoanId[i]=jsonObject.get("loanId").getAsLong();
+ }
+ int j=0;
+ for(JsonElement element:repayments )
+ {
+ childCommand=JsonCommand.fromExistingCommand(command,element);
+ result=makeLoanRepayment(childLoanId[j++],childCommand,false);
+ }
+ return result;
}
@Transactional
@@ -1868,7 +1867,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
final Collection chargeDatas = this.loanChargeReadPlatformService.retrieveLoanChargesForFeePayment(
ChargePaymentMode.ACCOUNT_TRANSFER.getValue(), LoanStatus.ACTIVE.getValue());
final boolean isRegularTransaction = true;
- int errors = 0;
+ List errors = new ArrayList<>();
if (chargeDatas != null) {
for (final LoanChargeData chargeData : chargeDatas) {
if (chargeData.isInstallmentFee()) {
@@ -1889,9 +1888,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
null, LoanTransactionType.CHARGE_PAYMENT.getValue(), chargeData.getId(),
installmentChargeData.getInstallmentNumber(), AccountTransferType.CHARGE_PAYMENT.getValue(), null,
null, null, null, null, fromSavingsAccount, isRegularTransaction, isExceptionForBalanceCheck);
- if (!transferFeeCharge(accountTransferDTO)) {
- ++errors;
- }
+ transferFeeCharge(accountTransferDTO, errors);
}
}
} else if (chargeData.getDueDate() != null && !chargeData.getDueDate().isAfter(DateUtils.getLocalDateOfTenant())) {
@@ -1905,25 +1902,19 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
LoanTransactionType.CHARGE_PAYMENT.getValue(), chargeData.getId(), null,
AccountTransferType.CHARGE_PAYMENT.getValue(), null, null, null, null, null, fromSavingsAccount,
isRegularTransaction, isExceptionForBalanceCheck);
- if (!transferFeeCharge(accountTransferDTO)) {
- ++errors;
- }
+ transferFeeCharge(accountTransferDTO, errors);
}
}
}
- if (errors > 0) { throw new JobExecutionException(errors); }
+ if (!errors.isEmpty()) { throw new JobExecutionException(errors); }
}
- private boolean transferFeeCharge(final AccountTransferDTO accountTransferDTO) {
+ private void transferFeeCharge(final AccountTransferDTO accountTransferDTO, List errors) {
try {
this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO);
- return true;
- } catch (final PlatformApiDataValidationException e) {
- LOG.error("Validation exception while paying charge {} for loan id {}", accountTransferDTO.getChargeId(), accountTransferDTO.getToAccountId(), e);
- return false;
- } catch (final InsufficientAccountBalanceException e) {
- LOG.error("InsufficientAccountBalanceException while paying charge {} for loan id {}", accountTransferDTO.getChargeId(), accountTransferDTO.getToAccountId(), e);
- return false;
+ } catch (RuntimeException e) {
+ LOG.error("Exception while paying charge {} for loan id {}", accountTransferDTO.getChargeId(), accountTransferDTO.getToAccountId(), e);
+ errors.add(e);
}
}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/RecalculateInterestPoster.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/RecalculateInterestPoster.java
index 93f6d9819..58ef5bc1c 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/RecalculateInterestPoster.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/RecalculateInterestPoster.java
@@ -18,7 +18,9 @@
*/
package org.apache.fineract.portfolio.loanaccount.service;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;
import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil;
@@ -56,7 +58,7 @@ public class RecalculateInterestPoster implements Callable {
int i = 0;
if (!loanIds.isEmpty()) {
- int errors = 0;
+ List errors = new ArrayList<>();
for (Long loanId : loanIds) {
logger.info("Loan ID {}", loanId);
Integer numberOfRetries = 0;
@@ -70,7 +72,7 @@ public class RecalculateInterestPoster implements Callable {
// Fail if the transaction has been retired for maxNumberOfRetries
if (numberOfRetries >= maxNumberOfRetries) {
logger.error("Recalulate interest job has been retried for the max allowed attempts of {} and will be rolled back", numberOfRetries);
- ++errors;
+ errors.add(exception);
break;
}
// Else sleep for a random time (between 1 to 10 seconds) and continue
@@ -81,19 +83,19 @@ public class RecalculateInterestPoster implements Callable {
numberOfRetries = numberOfRetries + 1;
} catch (InterruptedException e) {
logger.error("Interest recalculation for loans retry failed due to InterruptedException", e) ;
- ++errors;
+ errors.add(e);
break;
}
} catch (Exception e) {
logger.error("Interest recalculation for loans failed for account {}", loanId, e);
numberOfRetries = maxNumberOfRetries + 1;
- ++errors;
+ errors.add(e);
}
i++;
}
logger.info("Loans count {}", i);
}
- if (errors > 0) { throw new JobExecutionException(errors); }
+ if (!errors.isEmpty()) { throw new JobExecutionException(errors); }
}
return null;
}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java
index 09601dc9f..c1c5fc565 100755
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/DepositAccountWritePlatformServiceJpaRepositoryImpl.java
@@ -575,20 +575,20 @@ public class DepositAccountWritePlatformServiceJpaRepositoryImpl implements Depo
@Override
@CronTarget(jobName = JobName.TRANSFER_INTEREST_TO_SAVINGS)
public void transferInterestToSavings() throws JobExecutionException {
- int errors = 0;
+ List errors = new ArrayList<>();
Collection accountTrasferData = this.depositAccountReadPlatformService.retrieveDataForInterestTransfer();
for (AccountTransferDTO accountTransferDTO : accountTrasferData) {
try {
this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO);
} catch (final PlatformApiDataValidationException e) {
LOG.error("Validation exception while trasfering Interest from {} to {}", accountTransferDTO.getFromAccountId(), accountTransferDTO.getToAccountId(), e);
- ++errors;
+ errors.add(e);
} catch (final InsufficientAccountBalanceException e) {
LOG.error("InsufficientAccountBalanceException while trasfering Interest from {} to {} ", accountTransferDTO.getFromAccountId(), accountTransferDTO.getToAccountId(), e);
- ++errors;
+ errors.add(e);
}
}
- if (errors > 0) { throw new JobExecutionException(errors); }
+ if (!errors.isEmpty()) { throw new JobExecutionException(errors); }
}
@Override
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsSchedularServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsSchedularServiceImpl.java
index 0e3cc7f44..67b7733ef 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsSchedularServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/savings/service/SavingsSchedularServiceImpl.java
@@ -20,6 +20,7 @@ package org.apache.fineract.portfolio.savings.service;
import static org.apache.fineract.portfolio.savings.domain.SavingsAccountStatusType.ACTIVE;
+import java.util.ArrayList;
import java.util.List;
import org.apache.fineract.infrastructure.core.service.DateUtils;
import org.apache.fineract.infrastructure.jobs.annotation.CronTarget;
@@ -62,7 +63,7 @@ public class SavingsSchedularServiceImpl implements SavingsSchedularService {
int page = 0;
Integer initialSize = 500;
Integer totalPageSize = 0;
- int errors = 0;
+ List errors = new ArrayList<>();
do {
PageRequest pageRequest = PageRequest.of(page, initialSize);
Page savingsAccounts = this.savingsAccountRepository.findByStatus(ACTIVE.getValue(), pageRequest);
@@ -74,14 +75,14 @@ public class SavingsSchedularServiceImpl implements SavingsSchedularService {
this.savingsAccountWritePlatformService.postInterest(savingsAccount, postInterestAsOn, transactionDate);
} catch (Exception e) {
LOG.error("Failed to post interest for Savings with id {}", savingsAccount.getId(), e);
- ++errors;
+ errors.add(e);
}
}
page++;
totalPageSize = savingsAccounts.getTotalPages();
} while (page < totalPageSize);
- if (errors > 0) { throw new JobExecutionException(errors); }
+ if (!errors.isEmpty()) { throw new JobExecutionException(errors); }
}
@Override
diff --git a/fineract-provider/src/main/java/org/apache/fineract/scheduledjobs/service/ScheduledJobRunnerServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/scheduledjobs/service/ScheduledJobRunnerServiceImpl.java
index 20e3fc66a..3d0a705c8 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/scheduledjobs/service/ScheduledJobRunnerServiceImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/scheduledjobs/service/ScheduledJobRunnerServiceImpl.java
@@ -21,6 +21,7 @@ package org.apache.fineract.scheduledjobs.service;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.SimpleDateFormat;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
@@ -239,20 +240,20 @@ public class ScheduledJobRunnerServiceImpl implements ScheduledJobRunnerService
@CronTarget(jobName = JobName.PAY_DUE_SAVINGS_CHARGES)
public void applyDueChargesForSavings() throws JobExecutionException {
final Collection chargesDueData = this.savingsAccountChargeReadPlatformService.retrieveChargesWithDue();
- int numberOfErrors = 0;
+ List exceptions = new ArrayList<>();
for (final SavingsAccountAnnualFeeData savingsAccountReference : chargesDueData) {
try {
this.savingsAccountWritePlatformService.applyChargeDue(savingsAccountReference.getId(), savingsAccountReference.getAccountId());
} catch (final PlatformApiDataValidationException e) {
+ exceptions.add(e);
final List errors = e.getErrors();
for (final ApiParameterError error : errors) {
logger.error("Apply Charges due for savings failed for account {} with message: {}", savingsAccountReference.getAccountNo(), error.getDeveloperMessage(), e);
- ++numberOfErrors;
}
}
}
logger.info("{}: Savings accounts affected by update: {}", ThreadLocalContextUtil.getTenant().getName(), chargesDueData.size());
- if (numberOfErrors > 0) { throw new JobExecutionException(numberOfErrors); }
+ if (!exceptions.isEmpty()) { throw new JobExecutionException(exceptions); }
}
@Transactional
@@ -372,7 +373,7 @@ public class ScheduledJobRunnerServiceImpl implements ScheduledJobRunnerService
@Override
@CronTarget(jobName = JobName.POST_DIVIDENTS_FOR_SHARES)
public void postDividends() throws JobExecutionException {
- int numberOfErrors = 0;
+ List exceptions = new ArrayList<>();
List