diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/DataIntegrityErrorHandler.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/DataIntegrityErrorHandler.java new file mode 100644 index 000000000..4201812d8 --- /dev/null +++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/DataIntegrityErrorHandler.java @@ -0,0 +1,48 @@ +/** + * 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.infrastructure; + +import lombok.extern.slf4j.Slf4j; +import org.apache.fineract.infrastructure.core.api.JsonCommand; +import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException; +import org.springframework.stereotype.Component; + +@Component +@Slf4j +public class DataIntegrityErrorHandler { + + public void handleDataIntegrityIssues(final JsonCommand command, final Throwable realCause, final Exception dve, final String msgType, + final String msgDescription) { + + if (realCause.getMessage().contains("external_id")) { + + final String externalId = command.stringValueOfParameterNamed("externalId"); + throw new PlatformDataIntegrityException("error.msg." + msgType + ".duplicate.externalId", + msgDescription + ": externalId `" + externalId + "` already exists", "externalId", externalId); + } + + logAsErrorUnexpectedDataIntegrityException(dve); + throw new PlatformDataIntegrityException("error.msg." + msgType + ".unknown.data.integrity.issue", + "Unknown data integrity issue with resource: " + msgDescription); + } + + private void logAsErrorUnexpectedDataIntegrityException(final Exception dve) { + log.error("Error occured.", dve); + } +} diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/AddLoanChargeCommandHandler.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/AddLoanChargeCommandHandler.java index 4c4987b4c..4f02b1724 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/AddLoanChargeCommandHandler.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/AddLoanChargeCommandHandler.java @@ -19,12 +19,11 @@ package org.apache.fineract.portfolio.loanaccount.handler; import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; import org.apache.fineract.commands.annotation.CommandType; import org.apache.fineract.commands.handler.NewCommandSourceHandler; +import org.apache.fineract.infrastructure.DataIntegrityErrorHandler; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; -import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException; import org.apache.fineract.portfolio.loanaccount.service.LoanWritePlatformService; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.orm.jpa.JpaSystemException; @@ -33,11 +32,11 @@ import org.springframework.transaction.annotation.Transactional; @Service @RequiredArgsConstructor -@Slf4j @CommandType(entity = "LOANCHARGE", action = "CREATE") public class AddLoanChargeCommandHandler implements NewCommandSourceHandler { private final LoanWritePlatformService writePlatformService; + private final DataIntegrityErrorHandler dataIntegrityErrorHandler; @Transactional @Override @@ -45,27 +44,9 @@ public class AddLoanChargeCommandHandler implements NewCommandSourceHandler { try { return this.writePlatformService.addLoanCharge(command.getLoanId(), command); } catch (final JpaSystemException | DataIntegrityViolationException dve) { - handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve); + dataIntegrityErrorHandler.handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve, "loan.charge", "Loan Charge"); return CommandProcessingResult.empty(); } } - private void handleDataIntegrityIssues(final JsonCommand command, final Throwable realCause, final Exception dve) { - - if (realCause.getMessage().contains("external_id")) { - - final String externalId = command.stringValueOfParameterNamed("externalId"); - throw new PlatformDataIntegrityException("error.msg.loan.charge.duplicate.externalId", - "Loan Charge with externalId `" + externalId + "` already exists", "externalId", externalId); - } - - logAsErrorUnexpectedDataIntegrityException(dve); - throw new PlatformDataIntegrityException("error.msg.loan.charge.unknown.data.integrity.issue", - "Unknown data integrity issue with resource."); - } - - private void logAsErrorUnexpectedDataIntegrityException(final Exception dve) { - log.error("Error occured.", dve); - } - } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/CreditBalanceRefundCommandHandler.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/CreditBalanceRefundCommandHandler.java index 4253ee231..43aad5211 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/CreditBalanceRefundCommandHandler.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/CreditBalanceRefundCommandHandler.java @@ -19,12 +19,11 @@ package org.apache.fineract.portfolio.loanaccount.handler; import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; import org.apache.fineract.commands.annotation.CommandType; import org.apache.fineract.commands.handler.NewCommandSourceHandler; +import org.apache.fineract.infrastructure.DataIntegrityErrorHandler; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; -import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException; import org.apache.fineract.portfolio.loanaccount.service.LoanWritePlatformService; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.orm.jpa.JpaSystemException; @@ -33,11 +32,11 @@ import org.springframework.transaction.annotation.Transactional; @Service @RequiredArgsConstructor -@Slf4j @CommandType(entity = "LOAN", action = "CREDITBALANCEREFUND") public class CreditBalanceRefundCommandHandler implements NewCommandSourceHandler { private final LoanWritePlatformService writePlatformService; + private final DataIntegrityErrorHandler dataIntegrityErrorHandler; @Transactional @Override @@ -46,27 +45,10 @@ public class CreditBalanceRefundCommandHandler implements NewCommandSourceHandle try { return this.writePlatformService.creditBalanceRefund(command.getLoanId(), command); } catch (final JpaSystemException | DataIntegrityViolationException dve) { - handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve, "loan.creditBalanceRefund", "Credit Balance Refund"); + dataIntegrityErrorHandler.handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve, "loan.creditBalanceRefund", + "Credit Balance Refund"); return CommandProcessingResult.empty(); } } - private void handleDataIntegrityIssues(final JsonCommand command, final Throwable realCause, final Exception dve, final String msgType, - final String msgDescription) { - - if (realCause.getMessage().contains("external_id")) { - - final String externalId = command.stringValueOfParameterNamed("externalId"); - throw new PlatformDataIntegrityException("error.msg." + msgType + ".duplicate.externalId", - msgDescription + " with externalId `" + externalId + "` already exists", "externalId", externalId); - } - - logAsErrorUnexpectedDataIntegrityException(dve); - throw new PlatformDataIntegrityException("error.msg.loan.charge.unknown.data.integrity.issue", - "Unknown data integrity issue with resource."); - } - - private void logAsErrorUnexpectedDataIntegrityException(final Exception dve) { - log.error("Error occured.", dve); - } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/DisburseLoanCommandHandler.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/DisburseLoanCommandHandler.java index a90183f79..83267c329 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/DisburseLoanCommandHandler.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/DisburseLoanCommandHandler.java @@ -21,9 +21,12 @@ package org.apache.fineract.portfolio.loanaccount.handler; import lombok.RequiredArgsConstructor; import org.apache.fineract.commands.annotation.CommandType; import org.apache.fineract.commands.handler.NewCommandSourceHandler; +import org.apache.fineract.infrastructure.DataIntegrityErrorHandler; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; import org.apache.fineract.portfolio.loanaccount.service.LoanWritePlatformService; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.orm.jpa.JpaSystemException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -33,11 +36,18 @@ import org.springframework.transaction.annotation.Transactional; public class DisburseLoanCommandHandler implements NewCommandSourceHandler { private final LoanWritePlatformService writePlatformService; + private final DataIntegrityErrorHandler dataIntegrityErrorHandler; @Transactional @Override public CommandProcessingResult processCommand(final JsonCommand command) { - return this.writePlatformService.disburseLoan(command.entityId(), command, false); + try { + return this.writePlatformService.disburseLoan(command.entityId(), command, false); + } catch (final JpaSystemException | DataIntegrityViolationException dve) { + dataIntegrityErrorHandler.handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve, "loan.disbursement", + "Disbursement"); + return CommandProcessingResult.empty(); + } } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/LoanGoodwilCreditCommandHandler.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/LoanGoodwillCreditCommandHandler.java similarity index 65% rename from fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/LoanGoodwilCreditCommandHandler.java rename to fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/LoanGoodwillCreditCommandHandler.java index 81a696edf..196dd35a3 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/LoanGoodwilCreditCommandHandler.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/LoanGoodwillCreditCommandHandler.java @@ -21,25 +21,35 @@ package org.apache.fineract.portfolio.loanaccount.handler; import lombok.RequiredArgsConstructor; import org.apache.fineract.commands.annotation.CommandType; import org.apache.fineract.commands.handler.NewCommandSourceHandler; +import org.apache.fineract.infrastructure.DataIntegrityErrorHandler; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionType; import org.apache.fineract.portfolio.loanaccount.service.LoanWritePlatformService; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.orm.jpa.JpaSystemException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service @RequiredArgsConstructor @CommandType(entity = "LOAN", action = "GOODWILLCREDIT") -public class LoanGoodwilCreditCommandHandler implements NewCommandSourceHandler { +public class LoanGoodwillCreditCommandHandler implements NewCommandSourceHandler { private final LoanWritePlatformService writePlatformService; + private final DataIntegrityErrorHandler dataIntegrityErrorHandler; @Transactional @Override public CommandProcessingResult processCommand(final JsonCommand command) { - boolean isRecoveryRepayment = false; - return this.writePlatformService.makeLoanRepayment(LoanTransactionType.GOODWILL_CREDIT, command.getLoanId(), command, - isRecoveryRepayment); + try { + boolean isRecoveryRepayment = false; + return this.writePlatformService.makeLoanRepayment(LoanTransactionType.GOODWILL_CREDIT, command.getLoanId(), command, + isRecoveryRepayment); + } catch (final JpaSystemException | DataIntegrityViolationException dve) { + dataIntegrityErrorHandler.handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve, "loan.goodwillCredit", + "Goodwill Credit"); + return CommandProcessingResult.empty(); + } } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/LoanMerchantIssuedRefundCommandHandler.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/LoanMerchantIssuedRefundCommandHandler.java index 433c479a7..ef71cc222 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/LoanMerchantIssuedRefundCommandHandler.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/LoanMerchantIssuedRefundCommandHandler.java @@ -21,10 +21,13 @@ package org.apache.fineract.portfolio.loanaccount.handler; import lombok.RequiredArgsConstructor; import org.apache.fineract.commands.annotation.CommandType; import org.apache.fineract.commands.handler.NewCommandSourceHandler; +import org.apache.fineract.infrastructure.DataIntegrityErrorHandler; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionType; import org.apache.fineract.portfolio.loanaccount.service.LoanWritePlatformService; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.orm.jpa.JpaSystemException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -34,12 +37,19 @@ import org.springframework.transaction.annotation.Transactional; public class LoanMerchantIssuedRefundCommandHandler implements NewCommandSourceHandler { private final LoanWritePlatformService writePlatformService; + private final DataIntegrityErrorHandler dataIntegrityErrorHandler; @Transactional @Override public CommandProcessingResult processCommand(final JsonCommand command) { - boolean isRecoveryRepayment = false; - return this.writePlatformService.makeLoanRepayment(LoanTransactionType.MERCHANT_ISSUED_REFUND, command.getLoanId(), command, - isRecoveryRepayment); + try { + boolean isRecoveryRepayment = false; + return this.writePlatformService.makeLoanRepayment(LoanTransactionType.MERCHANT_ISSUED_REFUND, command.getLoanId(), command, + isRecoveryRepayment); + } catch (final JpaSystemException | DataIntegrityViolationException dve) { + dataIntegrityErrorHandler.handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve, "loan.merchantIssuedRefund", + "Merchant Issued Refund"); + return CommandProcessingResult.empty(); + } } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/LoanPayoutRefundCommandHandler.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/LoanPayoutRefundCommandHandler.java index 0f48ad6d9..1de3ccfb8 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/LoanPayoutRefundCommandHandler.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/LoanPayoutRefundCommandHandler.java @@ -21,10 +21,13 @@ package org.apache.fineract.portfolio.loanaccount.handler; import lombok.RequiredArgsConstructor; import org.apache.fineract.commands.annotation.CommandType; import org.apache.fineract.commands.handler.NewCommandSourceHandler; +import org.apache.fineract.infrastructure.DataIntegrityErrorHandler; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionType; import org.apache.fineract.portfolio.loanaccount.service.LoanWritePlatformService; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.orm.jpa.JpaSystemException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -34,12 +37,19 @@ import org.springframework.transaction.annotation.Transactional; public class LoanPayoutRefundCommandHandler implements NewCommandSourceHandler { private final LoanWritePlatformService writePlatformService; + private final DataIntegrityErrorHandler dataIntegrityErrorHandler; @Transactional @Override public CommandProcessingResult processCommand(final JsonCommand command) { - boolean isRecoveryRepayment = false; - return this.writePlatformService.makeLoanRepayment(LoanTransactionType.PAYOUT_REFUND, command.getLoanId(), command, - isRecoveryRepayment); + try { + boolean isRecoveryRepayment = false; + return this.writePlatformService.makeLoanRepayment(LoanTransactionType.PAYOUT_REFUND, command.getLoanId(), command, + isRecoveryRepayment); + } catch (final JpaSystemException | DataIntegrityViolationException dve) { + dataIntegrityErrorHandler.handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve, "loan.payoutRefund", + "Payout Refund"); + return CommandProcessingResult.empty(); + } } } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/LoanRepaymentCommandHandler.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/LoanRepaymentCommandHandler.java index 3bbd62bf7..28d679b76 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/LoanRepaymentCommandHandler.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/handler/LoanRepaymentCommandHandler.java @@ -21,10 +21,13 @@ package org.apache.fineract.portfolio.loanaccount.handler; import lombok.RequiredArgsConstructor; import org.apache.fineract.commands.annotation.CommandType; import org.apache.fineract.commands.handler.NewCommandSourceHandler; +import org.apache.fineract.infrastructure.DataIntegrityErrorHandler; import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionType; import org.apache.fineract.portfolio.loanaccount.service.LoanWritePlatformService; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.orm.jpa.JpaSystemException; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -34,12 +37,18 @@ import org.springframework.transaction.annotation.Transactional; public class LoanRepaymentCommandHandler implements NewCommandSourceHandler { private final LoanWritePlatformService writePlatformService; + private final DataIntegrityErrorHandler dataIntegrityErrorHandler; @Transactional @Override public CommandProcessingResult processCommand(final JsonCommand command) { - boolean isRecoveryRepayment = false; - return this.writePlatformService.makeLoanRepayment(LoanTransactionType.REPAYMENT, command.getLoanId(), command, - isRecoveryRepayment); + try { + boolean isRecoveryRepayment = false; + return this.writePlatformService.makeLoanRepayment(LoanTransactionType.REPAYMENT, command.getLoanId(), command, + isRecoveryRepayment); + } catch (final JpaSystemException | DataIntegrityViolationException dve) { + dataIntegrityErrorHandler.handleDataIntegrityIssues(command, dve.getMostSpecificCause(), dve, "loan.repayment", "Repayment"); + return CommandProcessingResult.empty(); + } } }