blob: f204786f25c911bebc0acfd405bb485f154365f7 [file] [log] [blame]
/**
* 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.portfolio.loanaccount.domain;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.apache.fineract.infrastructure.core.domain.ExternalId;
import org.apache.fineract.portfolio.loanaccount.exception.LoanNotFoundException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* <p>
* Wrapper for {@link LoanRepository} that adds NULL checking and Error handling capabilities
* </p>
*/
@Service
public class LoanRepositoryWrapper {
private final LoanRepository repository;
@Autowired
public LoanRepositoryWrapper(final LoanRepository repository) {
this.repository = repository;
}
@Transactional(readOnly = true)
public Loan findOneWithNotFoundDetection(final Long id) {
return this.findOneWithNotFoundDetection(id, false);
}
@Transactional(readOnly = true)
public Loan findOneWithNotFoundDetection(final Long id, boolean loadLazyCollections) {
final Loan loan = this.repository.findById(id).orElseThrow(() -> new LoanNotFoundException(id));
if (loadLazyCollections) {
loan.initializeLazyCollections();
}
return loan;
}
// Root Entities are enough
public Collection<Loan> findActiveLoansByLoanIdAndGroupId(Long clientId, Long groupId) {
final Collection<Integer> loanStatuses = new ArrayList<>(Arrays.asList(LoanStatus.SUBMITTED_AND_PENDING_APPROVAL.getValue(),
LoanStatus.APPROVED.getValue(), LoanStatus.ACTIVE.getValue(), LoanStatus.OVERPAID.getValue()));
return this.repository.findByClientIdAndGroupIdAndLoanStatus(clientId, groupId, loanStatuses);
}
public Loan saveAndFlush(final Loan loan) {
return this.repository.saveAndFlush(loan);
}
@Transactional
public Loan save(final Loan loan) {
return this.repository.save(loan);
}
public List<Loan> save(List<Loan> loans) {
return this.repository.saveAll(loans);
}
public void flush() {
this.repository.flush();
}
public void delete(final Long loanId) {
this.repository.deleteById(loanId);
}
// Only root entities is enough
public List<Loan> getGroupLoansDisbursedAfter(@Param("disbursementDate") LocalDate disbursementDate, @Param("groupId") Long groupId,
@Param("loanType") Integer loanType) {
return this.repository.getGroupLoansDisbursedAfter(disbursementDate, groupId, loanType);
}
// Only root entities enough
public List<Loan> getClientOrJLGLoansDisbursedAfter(@Param("disbursementDate") LocalDate disbursementDate,
@Param("clientId") Long clientId) {
return this.repository.getClientOrJLGLoansDisbursedAfter(disbursementDate, clientId);
}
public Integer getMaxGroupLoanCounter(@Param("groupId") Long groupId, @Param("loanType") Integer loanType) {
return this.repository.getMaxGroupLoanCounter(groupId, loanType);
}
public Integer getMaxGroupLoanProductCounter(@Param("productId") Long productId, @Param("groupId") Long groupId,
@Param("loanType") Integer loanType) {
return this.repository.getMaxGroupLoanProductCounter(productId, groupId, loanType);
}
public Integer getMaxClientOrJLGLoanCounter(@Param("clientId") Long clientId) {
return this.repository.getMaxClientOrJLGLoanCounter(clientId);
}
public List<LoanRepaymentScheduleInstallment> getLoanRepaymentScheduleInstallments(final Long loanId) {
final Loan loan = this.repository.findById(loanId).orElseThrow(() -> new LoanNotFoundException(loanId));
return loan.getRepaymentScheduleInstallments();
}
public Integer getNumberOfRepayments(final Long loanId) {
return this.repository.findById(loanId).orElseThrow(() -> new LoanNotFoundException(loanId)).getNumberOfRepayments();
}
public Integer getMaxClientOrJLGLoanProductCounter(@Param("productId") Long productId, @Param("clientId") Long clientId) {
return this.repository.getMaxClientOrJLGLoanProductCounter(productId, clientId);
}
// Only root entities are enough
public List<Loan> getGroupLoansToUpdateLoanCounter(@Param("loanCounter") Integer loanCounter, @Param("groupId") Long groupId,
@Param("groupLoanType") Integer groupLoanType) {
return this.repository.getGroupLoansToUpdateLoanCounter(loanCounter, groupId, groupLoanType);
}
// Only root entities are enough
public List<Loan> getClientOrJLGLoansToUpdateLoanCounter(@Param("loanCounter") Integer loanCounter, @Param("clientId") Long clientId) {
return this.repository.getClientOrJLGLoansToUpdateLoanCounter(loanCounter, clientId);
}
// Only root entities are enough
public List<Loan> getGroupLoansToUpdateLoanProductCounter(@Param("loanProductCounter") Integer loanProductCounter,
@Param("groupId") Long groupId, @Param("groupLoanType") Integer groupLoanType) {
return this.repository.getGroupLoansToUpdateLoanProductCounter(loanProductCounter, groupId, groupLoanType);
}
// Only root entities are enough
public List<Loan> getClientLoansToUpdateLoanProductCounter(@Param("loanProductCounter") Integer loanProductCounter,
@Param("clientId") Long clientId) {
return this.repository.getClientLoansToUpdateLoanProductCounter(loanProductCounter, clientId);
}
// Need loanOfficerHistory. Check whether FETCH JOIN is good enough here
@Transactional(readOnly = true)
public List<Loan> findByClientIdAndGroupId(@Param("clientId") Long clientId, @Param("groupId") Long groupId) {
List<Loan> loans = this.repository.findByClientIdAndGroupId(clientId, groupId);
if (loans != null && loans.size() > 0) {
for (Loan loan : loans) {
loan.initializeLoanOfficerHistory();
}
}
return loans;
}
// need loanTransactions, loanOfficerHistory
@Transactional(readOnly = true)
public List<Loan> findLoanByClientId(@Param("clientId") Long clientId) {
List<Loan> loans = this.repository.findLoanByClientId(clientId);
if (loans != null && loans.size() > 0) {
for (Loan loan : loans) {
loan.initializeTransactions();
loan.initializeLoanOfficerHistory();
}
}
return loans;
}
// Root entities are enough
public List<Loan> findByGroupId(@Param("groupId") Long groupId) {
return this.repository.findByGroupId(groupId);
}
// Looks like we need complete Data
public List<Loan> findByIdsAndLoanStatusAndLoanType(@Param("ids") Collection<Long> ids,
@Param("loanStatuses") Collection<Integer> loanStatuses, @Param("loanTypes") Collection<Integer> loanTypes) {
List<Loan> loans = this.repository.findByIdsAndLoanStatusAndLoanType(ids, loanStatuses, loanTypes);
if (loans != null && loans.size() > 0) {
for (Loan loan : loans) {
loan.initializeLazyCollections();
}
}
return loans;
}
// This method is not used
public List<Long> getLoansDisbursedAfter(@Param("disbursalDate") LocalDate disbursalDate) {
return this.repository.getLoansDisbursedAfter(disbursalDate);
}
// Repayments Schedule
public List<Loan> findByClientOfficeIdsAndLoanStatus(@Param("officeIds") Collection<Long> officeIds,
@Param("loanStatuses") Collection<Integer> loanStatuses) {
List<Loan> loans = this.repository.findByClientOfficeIdsAndLoanStatus(officeIds, loanStatuses);
if (loans != null && loans.size() > 0) {
for (Loan loan : loans) {
loan.initializeRepaymentSchedule();
}
}
return loans;
}
// Repayments Schedule
public List<Loan> findByGroupOfficeIdsAndLoanStatus(@Param("officeIds") Collection<Long> officeIds,
@Param("loanStatuses") Collection<Integer> loanStatuses) {
List<Loan> loans = this.repository.findByGroupOfficeIdsAndLoanStatus(officeIds, loanStatuses);
if (loans != null && loans.size() > 0) {
for (Loan loan : loans) {
loan.initializeRepaymentSchedule();
}
}
return loans;
}
public List<Long> findActiveLoansLoanProductIdsByClient(@Param("clientId") Long clientId, @Param("loanStatus") Integer loanStatus) {
return this.repository.findActiveLoansLoanProductIdsByClient(clientId, loanStatus);
}
public List<Long> findActiveLoansLoanProductIdsByGroup(@Param("groupId") Long groupId, @Param("loanStatus") Integer loanStatus) {
return this.repository.findActiveLoansLoanProductIdsByGroup(groupId, loanStatus);
}
public boolean doNonClosedLoanAccountsExistForClient(@Param("clientId") Long clientId) {
return this.repository.doNonClosedLoanAccountsExistForClient(clientId);
}
public boolean doNonClosedLoanAccountsExistForProduct(@Param("productId") Long productId) {
return this.repository.doNonClosedLoanAccountsExistForProduct(productId);
}
public Loan findNonClosedLoanByAccountNumber(@Param("accountNumber") String accountNumber) {
return this.repository.findNonClosedLoanByAccountNumber(accountNumber);
}
public boolean existLoanByExternalId(final ExternalId externalId) {
return this.repository.existsByExternalId(externalId);
}
// Looks like we need complete entity
@Transactional(readOnly = true)
public Loan findNonClosedLoanThatBelongsToClient(@Param("loanId") Long loanId, @Param("clientId") Long clientId) {
Loan loan = this.repository.findNonClosedLoanThatBelongsToClient(loanId, clientId);
if (loan != null) {
loan.initializeTransactions();
}
return loan;
}
public Long findIdByExternalId(ExternalId externalId) {
return this.repository.findIdByExternalId(externalId);
}
}