commit for FINERACT-55 (Standing instruction not disabled at loan/savings account closure)
This commit is contained in:
+25
-1
@@ -18,8 +18,32 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.portfolio.account.domain;
|
package org.apache.fineract.portfolio.account.domain;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
|
||||||
|
import org.apache.fineract.portfolio.savings.domain.SavingsAccount;
|
||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||||
|
import org.springframework.data.jpa.repository.Query;
|
||||||
|
import org.springframework.data.repository.query.Param;
|
||||||
|
|
||||||
public interface StandingInstructionRepository extends JpaRepository<AccountTransferStandingInstruction, Long>,
|
public interface StandingInstructionRepository extends JpaRepository<AccountTransferStandingInstruction, Long>,
|
||||||
JpaSpecificationExecutor<AccountTransferStandingInstruction> {}
|
JpaSpecificationExecutor<AccountTransferStandingInstruction> {
|
||||||
|
public final static String FIND_BY_LOAN_AND_STATUS_QUERY = "select accountTransferStandingInstruction "
|
||||||
|
+ "from AccountTransferStandingInstruction accountTransferStandingInstruction "
|
||||||
|
+ "where accountTransferStandingInstruction.status = :status "
|
||||||
|
+ "and (accountTransferStandingInstruction.accountTransferDetails.toLoanAccount = :loan "
|
||||||
|
+ "or accountTransferStandingInstruction.accountTransferDetails.fromLoanAccount = :loan)";
|
||||||
|
|
||||||
|
public final static String FIND_BY_SAVINGS_AND_STATUS_QUERY = "select accountTransferStandingInstruction "
|
||||||
|
+ "from AccountTransferStandingInstruction accountTransferStandingInstruction "
|
||||||
|
+ "where accountTransferStandingInstruction.status = :status "
|
||||||
|
+ "and (accountTransferStandingInstruction.accountTransferDetails.toSavingsAccount = :savingsAccount "
|
||||||
|
+ "or accountTransferStandingInstruction.accountTransferDetails.fromSavingsAccount = :savingsAccount)";
|
||||||
|
|
||||||
|
@Query(FIND_BY_LOAN_AND_STATUS_QUERY)
|
||||||
|
public Collection<AccountTransferStandingInstruction> findByLoanAccountAndStatus(@Param("loan") Loan loan, @Param("status") Integer status);
|
||||||
|
|
||||||
|
@Query(FIND_BY_SAVINGS_AND_STATUS_QUERY)
|
||||||
|
public Collection<AccountTransferStandingInstruction> findBySavingsAccountAndStatus(@Param("savingsAccount") SavingsAccount savingsAccount, @Param("status") Integer status);
|
||||||
|
}
|
||||||
|
|||||||
+7
@@ -58,4 +58,11 @@ public interface LoanAccountDomainService {
|
|||||||
void saveLoanWithDataIntegrityViolationChecks(Loan loan);
|
void saveLoanWithDataIntegrityViolationChecks(Loan loan);
|
||||||
|
|
||||||
Map<String, Object> foreCloseLoan(final Loan loan, final LocalDate foreClourseDate, String noteText);
|
Map<String, Object> foreCloseLoan(final Loan loan, final LocalDate foreClourseDate, String noteText);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disables all standing instructions linked to a closed loan
|
||||||
|
*
|
||||||
|
* @param loan {@link Loan} object
|
||||||
|
*/
|
||||||
|
void disableStandingInstructionsLinkedToClosedLoan(Loan loan);
|
||||||
}
|
}
|
||||||
|
|||||||
+26
-1
@@ -50,7 +50,10 @@ import org.apache.fineract.organisation.monetary.domain.Money;
|
|||||||
import org.apache.fineract.organisation.workingdays.domain.WorkingDays;
|
import org.apache.fineract.organisation.workingdays.domain.WorkingDays;
|
||||||
import org.apache.fineract.organisation.workingdays.domain.WorkingDaysRepositoryWrapper;
|
import org.apache.fineract.organisation.workingdays.domain.WorkingDaysRepositoryWrapper;
|
||||||
import org.apache.fineract.portfolio.account.domain.AccountTransferRepository;
|
import org.apache.fineract.portfolio.account.domain.AccountTransferRepository;
|
||||||
|
import org.apache.fineract.portfolio.account.domain.AccountTransferStandingInstruction;
|
||||||
import org.apache.fineract.portfolio.account.domain.AccountTransferTransaction;
|
import org.apache.fineract.portfolio.account.domain.AccountTransferTransaction;
|
||||||
|
import org.apache.fineract.portfolio.account.domain.StandingInstructionRepository;
|
||||||
|
import org.apache.fineract.portfolio.account.domain.StandingInstructionStatus;
|
||||||
import org.apache.fineract.portfolio.client.domain.Client;
|
import org.apache.fineract.portfolio.client.domain.Client;
|
||||||
import org.apache.fineract.portfolio.client.exception.ClientNotActiveException;
|
import org.apache.fineract.portfolio.client.exception.ClientNotActiveException;
|
||||||
import org.apache.fineract.portfolio.common.BusinessEventNotificationConstants.BUSINESS_ENTITY;
|
import org.apache.fineract.portfolio.common.BusinessEventNotificationConstants.BUSINESS_ENTITY;
|
||||||
@@ -96,6 +99,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
|||||||
private final PlatformSecurityContext context;
|
private final PlatformSecurityContext context;
|
||||||
private final BusinessEventNotifierService businessEventNotifierService;
|
private final BusinessEventNotifierService businessEventNotifierService;
|
||||||
private final LoanUtilService loanUtilService;
|
private final LoanUtilService loanUtilService;
|
||||||
|
private final StandingInstructionRepository standingInstructionRepository;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public LoanAccountDomainServiceJpa(final LoanAssembler loanAccountAssembler, final LoanRepository loanRepository,
|
public LoanAccountDomainServiceJpa(final LoanAssembler loanAccountAssembler, final LoanRepository loanRepository,
|
||||||
@@ -108,7 +112,8 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
|||||||
final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepository,
|
final ApplicationCurrencyRepositoryWrapper applicationCurrencyRepository,
|
||||||
final LoanRepaymentScheduleInstallmentRepository repaymentScheduleInstallmentRepository,
|
final LoanRepaymentScheduleInstallmentRepository repaymentScheduleInstallmentRepository,
|
||||||
final LoanAccrualPlatformService loanAccrualPlatformService, final PlatformSecurityContext context,
|
final LoanAccrualPlatformService loanAccrualPlatformService, final PlatformSecurityContext context,
|
||||||
final BusinessEventNotifierService businessEventNotifierService, final LoanUtilService loanUtilService) {
|
final BusinessEventNotifierService businessEventNotifierService, final LoanUtilService loanUtilService,
|
||||||
|
final StandingInstructionRepository standingInstructionRepository) {
|
||||||
this.loanAccountAssembler = loanAccountAssembler;
|
this.loanAccountAssembler = loanAccountAssembler;
|
||||||
this.loanRepository = loanRepository;
|
this.loanRepository = loanRepository;
|
||||||
this.loanTransactionRepository = loanTransactionRepository;
|
this.loanTransactionRepository = loanTransactionRepository;
|
||||||
@@ -125,6 +130,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
|||||||
this.context = context;
|
this.context = context;
|
||||||
this.businessEventNotifierService = businessEventNotifierService;
|
this.businessEventNotifierService = businessEventNotifierService;
|
||||||
this.loanUtilService = loanUtilService;
|
this.loanUtilService = loanUtilService;
|
||||||
|
this.standingInstructionRepository = standingInstructionRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@@ -209,6 +215,9 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
|||||||
this.businessEventNotifierService.notifyBusinessEventWasExecuted(BUSINESS_EVENTS.LOAN_MAKE_REPAYMENT,
|
this.businessEventNotifierService.notifyBusinessEventWasExecuted(BUSINESS_EVENTS.LOAN_MAKE_REPAYMENT,
|
||||||
constructEntityMap(BUSINESS_ENTITY.LOAN_TRANSACTION, newRepaymentTransaction));
|
constructEntityMap(BUSINESS_ENTITY.LOAN_TRANSACTION, newRepaymentTransaction));
|
||||||
|
|
||||||
|
// disable all active standing orders linked to this loan if status changes to closed
|
||||||
|
disableStandingInstructionsLinkedToClosedLoan(loan);
|
||||||
|
|
||||||
builderResult.withEntityId(newRepaymentTransaction.getId()) //
|
builderResult.withEntityId(newRepaymentTransaction.getId()) //
|
||||||
.withOfficeId(loan.getOfficeId()) //
|
.withOfficeId(loan.getOfficeId()) //
|
||||||
.withClientId(loan.getClientId()) //
|
.withClientId(loan.getClientId()) //
|
||||||
@@ -705,4 +714,20 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
|
|||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
|
public void disableStandingInstructionsLinkedToClosedLoan(Loan loan) {
|
||||||
|
if ((loan != null) && (loan.status() != null) && loan.status().isClosed()) {
|
||||||
|
final Integer standingInstructionStatus = StandingInstructionStatus.ACTIVE.getValue();
|
||||||
|
final Collection<AccountTransferStandingInstruction> accountTransferStandingInstructions = this.standingInstructionRepository
|
||||||
|
.findByLoanAccountAndStatus(loan, standingInstructionStatus);
|
||||||
|
|
||||||
|
if (!accountTransferStandingInstructions.isEmpty()) {
|
||||||
|
for (AccountTransferStandingInstruction accountTransferStandingInstruction : accountTransferStandingInstructions) {
|
||||||
|
accountTransferStandingInstruction.updateStatus(StandingInstructionStatus.DISABLED.getValue());
|
||||||
|
this.standingInstructionRepository.save(accountTransferStandingInstruction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+8
@@ -1165,6 +1165,10 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
this.loanAccountDomainService.recalculateAccruals(loan);
|
this.loanAccountDomainService.recalculateAccruals(loan);
|
||||||
this.businessEventNotifierService.notifyBusinessEventWasExecuted(BUSINESS_EVENTS.LOAN_CLOSE,
|
this.businessEventNotifierService.notifyBusinessEventWasExecuted(BUSINESS_EVENTS.LOAN_CLOSE,
|
||||||
constructEntityMap(BUSINESS_ENTITY.LOAN, loan));
|
constructEntityMap(BUSINESS_ENTITY.LOAN, loan));
|
||||||
|
|
||||||
|
// disable all active standing instructions linked to the loan
|
||||||
|
this.loanAccountDomainService.disableStandingInstructionsLinkedToClosedLoan(loan);
|
||||||
|
|
||||||
CommandProcessingResult result = null;
|
CommandProcessingResult result = null;
|
||||||
if (possibleClosingTransaction != null) {
|
if (possibleClosingTransaction != null) {
|
||||||
|
|
||||||
@@ -1221,6 +1225,10 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|
|||||||
}
|
}
|
||||||
this.businessEventNotifierService.notifyBusinessEventWasExecuted(BUSINESS_EVENTS.LOAN_CLOSE_AS_RESCHEDULE,
|
this.businessEventNotifierService.notifyBusinessEventWasExecuted(BUSINESS_EVENTS.LOAN_CLOSE_AS_RESCHEDULE,
|
||||||
constructEntityMap(BUSINESS_ENTITY.LOAN, loan));
|
constructEntityMap(BUSINESS_ENTITY.LOAN, loan));
|
||||||
|
|
||||||
|
// disable all active standing instructions linked to the loan
|
||||||
|
this.loanAccountDomainService.disableStandingInstructionsLinkedToClosedLoan(loan);
|
||||||
|
|
||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
.withCommandId(command.commandId()) //
|
.withCommandId(command.commandId()) //
|
||||||
.withEntityId(loanId) //
|
.withEntityId(loanId) //
|
||||||
|
|||||||
+33
-1
@@ -29,6 +29,7 @@ import static org.apache.fineract.portfolio.savings.SavingsApiConstants.withdraw
|
|||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.MathContext;
|
import java.math.MathContext;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
@@ -60,6 +61,9 @@ import org.apache.fineract.organisation.staff.domain.Staff;
|
|||||||
import org.apache.fineract.organisation.staff.domain.StaffRepositoryWrapper;
|
import org.apache.fineract.organisation.staff.domain.StaffRepositoryWrapper;
|
||||||
import org.apache.fineract.organisation.workingdays.domain.WorkingDaysRepositoryWrapper;
|
import org.apache.fineract.organisation.workingdays.domain.WorkingDaysRepositoryWrapper;
|
||||||
import org.apache.fineract.portfolio.account.PortfolioAccountType;
|
import org.apache.fineract.portfolio.account.PortfolioAccountType;
|
||||||
|
import org.apache.fineract.portfolio.account.domain.AccountTransferStandingInstruction;
|
||||||
|
import org.apache.fineract.portfolio.account.domain.StandingInstructionRepository;
|
||||||
|
import org.apache.fineract.portfolio.account.domain.StandingInstructionStatus;
|
||||||
import org.apache.fineract.portfolio.account.service.AccountAssociationsReadPlatformService;
|
import org.apache.fineract.portfolio.account.service.AccountAssociationsReadPlatformService;
|
||||||
import org.apache.fineract.portfolio.account.service.AccountTransfersReadPlatformService;
|
import org.apache.fineract.portfolio.account.service.AccountTransfersReadPlatformService;
|
||||||
import org.apache.fineract.portfolio.charge.domain.Charge;
|
import org.apache.fineract.portfolio.charge.domain.Charge;
|
||||||
@@ -133,6 +137,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
private final ConfigurationDomainService configurationDomainService;
|
private final ConfigurationDomainService configurationDomainService;
|
||||||
private final DepositAccountOnHoldTransactionRepository depositAccountOnHoldTransactionRepository;
|
private final DepositAccountOnHoldTransactionRepository depositAccountOnHoldTransactionRepository;
|
||||||
private final AppUserRepositoryWrapper appuserRepository;
|
private final AppUserRepositoryWrapper appuserRepository;
|
||||||
|
private final StandingInstructionRepository standingInstructionRepository;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public SavingsAccountWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
|
public SavingsAccountWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
|
||||||
@@ -152,7 +157,8 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
final SavingsAccountDataValidator fromApiJsonDeserializer, final SavingsAccountRepositoryWrapper savingsRepository,
|
final SavingsAccountDataValidator fromApiJsonDeserializer, final SavingsAccountRepositoryWrapper savingsRepository,
|
||||||
final StaffRepositoryWrapper staffRepository, final ConfigurationDomainService configurationDomainService,
|
final StaffRepositoryWrapper staffRepository, final ConfigurationDomainService configurationDomainService,
|
||||||
final DepositAccountOnHoldTransactionRepository depositAccountOnHoldTransactionRepository,
|
final DepositAccountOnHoldTransactionRepository depositAccountOnHoldTransactionRepository,
|
||||||
final AppUserRepositoryWrapper appuserRepository) {
|
final AppUserRepositoryWrapper appuserRepository,
|
||||||
|
final StandingInstructionRepository standingInstructionRepository) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.savingAccountRepository = savingAccountRepository;
|
this.savingAccountRepository = savingAccountRepository;
|
||||||
this.savingsAccountTransactionRepository = savingsAccountTransactionRepository;
|
this.savingsAccountTransactionRepository = savingsAccountTransactionRepository;
|
||||||
@@ -176,6 +182,7 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
this.configurationDomainService = configurationDomainService;
|
this.configurationDomainService = configurationDomainService;
|
||||||
this.depositAccountOnHoldTransactionRepository = depositAccountOnHoldTransactionRepository;
|
this.depositAccountOnHoldTransactionRepository = depositAccountOnHoldTransactionRepository;
|
||||||
this.appuserRepository = appuserRepository;
|
this.appuserRepository = appuserRepository;
|
||||||
|
this.standingInstructionRepository = standingInstructionRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
@@ -646,6 +653,10 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// disable all standing orders linked to the savings account
|
||||||
|
this.disableStandingInstructionsLinkedToClosedSavings(account);
|
||||||
|
|
||||||
return new CommandProcessingResultBuilder() //
|
return new CommandProcessingResultBuilder() //
|
||||||
.withEntityId(savingsId) //
|
.withEntityId(savingsId) //
|
||||||
.withOfficeId(account.officeId()) //
|
.withOfficeId(account.officeId()) //
|
||||||
@@ -1275,4 +1286,25 @@ public class SavingsAccountWritePlatformServiceJpaRepositoryImpl implements Savi
|
|||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disable all standing instructions linked to the savings account if the status is "closed"
|
||||||
|
*
|
||||||
|
* @param savingsAccount -- the savings account object
|
||||||
|
* @return None
|
||||||
|
**/
|
||||||
|
@Transactional
|
||||||
|
private void disableStandingInstructionsLinkedToClosedSavings(final SavingsAccount savingsAccount) {
|
||||||
|
if (savingsAccount != null && savingsAccount.isClosed()) {
|
||||||
|
final Integer standingInstructionStatus = StandingInstructionStatus.ACTIVE.getValue();
|
||||||
|
final Collection<AccountTransferStandingInstruction> accountTransferStandingInstructions = this.standingInstructionRepository
|
||||||
|
.findBySavingsAccountAndStatus(savingsAccount, standingInstructionStatus);
|
||||||
|
|
||||||
|
if (!accountTransferStandingInstructions.isEmpty()) {
|
||||||
|
for (AccountTransferStandingInstruction accountTransferStandingInstruction : accountTransferStandingInstructions) {
|
||||||
|
accountTransferStandingInstruction.updateStatus(StandingInstructionStatus.DISABLED.getValue());
|
||||||
|
this.standingInstructionRepository.save(accountTransferStandingInstruction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user