Merge pull request #469 from mifoscontributer/MIFOSX-478

Applying Productmix check for loans
This commit is contained in:
Vishwas Babu A J
2013-07-23 04:57:40 -07:00
4 changed files with 68 additions and 2 deletions
@@ -46,6 +46,12 @@ public interface LoanRepository extends JpaRepository<Loan, Long>, JpaSpecificat
public static final String FIND_CLIENT_LOANS_TO_UPDATE_LOANPRODUCT_COUNTER = "from Loan l where l.loanProductCounter > :loanProductCounter" public static final String FIND_CLIENT_LOANS_TO_UPDATE_LOANPRODUCT_COUNTER = "from Loan l where l.loanProductCounter > :loanProductCounter"
+ " and l.client.id = :clientId and l.loanCounter is NULL order by l.loanProductCounter"; + " and l.client.id = :clientId and l.loanCounter is NULL order by l.loanProductCounter";
public static final String FIND_ACTIVE_LOANS_PRODUCT_IDS_BY_CLIENT = "Select loan.loanProduct.id from Loan loan where "
+ "loan.client.id = :clientId and loan.loanStatus = :loanStatus group by loan.loanProduct.id";
public static final String FIND_ACTIVE_LOANS_PRODUCT_IDS_BY_GROUP = "Select loan.loanProduct.id from Loan loan where "
+ "loan.group.id = :groupId and loan.loanStatus = :loanStatus and loan.client.id is NULL group by loan.loanProduct.id";
@Query(FIND_GROUP_LOANS_DISBURSED_AFTER) @Query(FIND_GROUP_LOANS_DISBURSED_AFTER)
List<Loan> getGroupLoansDisbursedAfter(@Param("disbursementDate") Date disbursementDate, @Param("groupId") Long groupId, List<Loan> getGroupLoansDisbursedAfter(@Param("disbursementDate") Date disbursementDate, @Param("groupId") Long groupId,
@Param("loanType") Integer loanType); @Param("loanType") Integer loanType);
@@ -100,4 +106,10 @@ public interface LoanRepository extends JpaRepository<Loan, Long>, JpaSpecificat
@Query("from Loan loan where loan.group.office.id IN :officeIds and loan.loanStatus IN :loanStatuses") @Query("from Loan loan where loan.group.office.id IN :officeIds and loan.loanStatus IN :loanStatuses")
List<Loan> findByGroupOfficeIdsAndLoanStatus(@Param("officeIds") Collection<Long> officeIds, @Param("loanStatuses") Collection<Integer> loanStatuses); List<Loan> findByGroupOfficeIdsAndLoanStatus(@Param("officeIds") Collection<Long> officeIds, @Param("loanStatuses") Collection<Integer> loanStatuses);
@Query(FIND_ACTIVE_LOANS_PRODUCT_IDS_BY_CLIENT)
List<Long> findActiveLoansLoanProductIdsByClient(@Param("clientId") Long clientId, @Param("loanStatus") Integer loanStatus);
@Query(FIND_ACTIVE_LOANS_PRODUCT_IDS_BY_GROUP)
List<Long> findActiveLoansLoanProductIdsByGroup(@Param("groupId") Long groupId, @Param("loanStatus") Integer loanStatus);
} }
@@ -0,0 +1,12 @@
package org.mifosplatform.portfolio.loanaccount.exception;
import org.mifosplatform.infrastructure.core.exception.AbstractPlatformDomainRuleException;
public class LoanDisbursalException extends AbstractPlatformDomainRuleException {
public LoanDisbursalException(final String cureentProduct, final String restrictedProduct) {
super("error.msg.loan.disbursal.failed", "This loan could not be disbursed as `" + cureentProduct + "` and `" + restrictedProduct
+ "` are not allowed to co-exist", new Object[] { cureentProduct, restrictedProduct });
}
}
@@ -32,8 +32,8 @@ import org.mifosplatform.organisation.monetary.domain.MonetaryCurrency;
import org.mifosplatform.organisation.monetary.domain.Money; import org.mifosplatform.organisation.monetary.domain.Money;
import org.mifosplatform.organisation.office.domain.Office; import org.mifosplatform.organisation.office.domain.Office;
import org.mifosplatform.organisation.staff.domain.Staff; import org.mifosplatform.organisation.staff.domain.Staff;
import org.mifosplatform.organisation.workingdays.domain.WorkingDaysRepositoryWrapper;
import org.mifosplatform.organisation.workingdays.domain.WorkingDays; import org.mifosplatform.organisation.workingdays.domain.WorkingDays;
import org.mifosplatform.organisation.workingdays.domain.WorkingDaysRepositoryWrapper;
import org.mifosplatform.portfolio.calendar.domain.Calendar; import org.mifosplatform.portfolio.calendar.domain.Calendar;
import org.mifosplatform.portfolio.calendar.domain.CalendarEntityType; import org.mifosplatform.portfolio.calendar.domain.CalendarEntityType;
import org.mifosplatform.portfolio.calendar.domain.CalendarInstance; import org.mifosplatform.portfolio.calendar.domain.CalendarInstance;
@@ -66,6 +66,7 @@ import org.mifosplatform.portfolio.loanaccount.domain.LoanSummaryWrapper;
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransaction; import org.mifosplatform.portfolio.loanaccount.domain.LoanTransaction;
import org.mifosplatform.portfolio.loanaccount.domain.LoanTransactionRepository; import org.mifosplatform.portfolio.loanaccount.domain.LoanTransactionRepository;
import org.mifosplatform.portfolio.loanaccount.domain.LoanType; import org.mifosplatform.portfolio.loanaccount.domain.LoanType;
import org.mifosplatform.portfolio.loanaccount.exception.LoanDisbursalException;
import org.mifosplatform.portfolio.loanaccount.exception.LoanNotFoundException; import org.mifosplatform.portfolio.loanaccount.exception.LoanNotFoundException;
import org.mifosplatform.portfolio.loanaccount.exception.LoanOfficerAssignmentException; import org.mifosplatform.portfolio.loanaccount.exception.LoanOfficerAssignmentException;
import org.mifosplatform.portfolio.loanaccount.exception.LoanOfficerUnassignmentException; import org.mifosplatform.portfolio.loanaccount.exception.LoanOfficerUnassignmentException;
@@ -73,8 +74,10 @@ import org.mifosplatform.portfolio.loanaccount.exception.LoanTransactionNotFound
import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanScheduleGeneratorFactory; import org.mifosplatform.portfolio.loanaccount.loanschedule.domain.LoanScheduleGeneratorFactory;
import org.mifosplatform.portfolio.loanaccount.serialization.LoanEventApiJsonValidator; import org.mifosplatform.portfolio.loanaccount.serialization.LoanEventApiJsonValidator;
import org.mifosplatform.portfolio.loanaccount.serialization.LoanUpdateCommandFromApiJsonDeserializer; import org.mifosplatform.portfolio.loanaccount.serialization.LoanUpdateCommandFromApiJsonDeserializer;
import org.mifosplatform.portfolio.loanproduct.data.LoanProductData;
import org.mifosplatform.portfolio.loanproduct.domain.LoanProductRelatedDetail; import org.mifosplatform.portfolio.loanproduct.domain.LoanProductRelatedDetail;
import org.mifosplatform.portfolio.loanproduct.exception.InvalidCurrencyException; import org.mifosplatform.portfolio.loanproduct.exception.InvalidCurrencyException;
import org.mifosplatform.portfolio.loanproduct.service.LoanProductReadPlatformService;
import org.mifosplatform.portfolio.note.domain.Note; import org.mifosplatform.portfolio.note.domain.Note;
import org.mifosplatform.portfolio.note.domain.NoteRepository; import org.mifosplatform.portfolio.note.domain.NoteRepository;
import org.mifosplatform.portfolio.paymentdetail.domain.PaymentDetail; import org.mifosplatform.portfolio.paymentdetail.domain.PaymentDetail;
@@ -83,6 +86,7 @@ import org.mifosplatform.useradministration.domain.AppUser;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
@Service @Service
public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatformService { public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatformService {
@@ -106,6 +110,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
private final HolidayRepository holidayRepository; private final HolidayRepository holidayRepository;
private final ConfigurationDomainService configurationDomainService; private final ConfigurationDomainService configurationDomainService;
private final WorkingDaysRepositoryWrapper workingDaysRepository; private final WorkingDaysRepositoryWrapper workingDaysRepository;
private final LoanProductReadPlatformService loanProductReadPlatformService;
@Autowired @Autowired
public LoanWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, public LoanWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context,
@@ -118,7 +123,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory, final LoanRepaymentScheduleTransactionProcessorFactory loanRepaymentScheduleTransactionProcessorFactory,
final LoanScheduleGeneratorFactory loanScheduleFactory, final CalendarInstanceRepository calendarInstanceRepository, final LoanScheduleGeneratorFactory loanScheduleFactory, final CalendarInstanceRepository calendarInstanceRepository,
final PaymentDetailWritePlatformService paymentDetailWritePlatformService, final HolidayRepository holidayRepository, final PaymentDetailWritePlatformService paymentDetailWritePlatformService, final HolidayRepository holidayRepository,
final ConfigurationDomainService configurationDomainService, final WorkingDaysRepositoryWrapper workingDaysRepository) { final ConfigurationDomainService configurationDomainService, final WorkingDaysRepositoryWrapper workingDaysRepository,
final LoanProductReadPlatformService loanProductReadPlatformService) {
this.context = context; this.context = context;
this.loanEventApiJsonValidator = loanEventApiJsonValidator; this.loanEventApiJsonValidator = loanEventApiJsonValidator;
@@ -139,6 +145,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
this.holidayRepository = holidayRepository; this.holidayRepository = holidayRepository;
this.configurationDomainService = configurationDomainService; this.configurationDomainService = configurationDomainService;
this.workingDaysRepository = workingDaysRepository; this.workingDaysRepository = workingDaysRepository;
this.loanProductReadPlatformService = loanProductReadPlatformService;
} }
private LoanLifecycleStateMachine defaultLoanLifecycleStateMachine() { private LoanLifecycleStateMachine defaultLoanLifecycleStateMachine() {
@@ -155,6 +162,10 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
this.loanEventApiJsonValidator.validateDisbursement(command.json()); this.loanEventApiJsonValidator.validateDisbursement(command.json());
final Loan loan = retrieveLoanBy(loanId); final Loan loan = retrieveLoanBy(loanId);
//check for product mix validations
checkForProductMixRestrictions(loan);
// validate actual disbursement date against meeting date // validate actual disbursement date against meeting date
final CalendarInstance calendarInstance = this.calendarInstanceRepository.findCalendarInstaneByLoanId(loan.getId(), final CalendarInstance calendarInstance = this.calendarInstanceRepository.findCalendarInstaneByLoanId(loan.getId(),
CalendarEntityType.LOANS.getValue()); CalendarEntityType.LOANS.getValue());
@@ -1233,4 +1244,31 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
} }
this.holidayRepository.save(holidays); this.holidayRepository.save(holidays);
} }
private void checkForProductMixRestrictions(final Loan loan) {
final List<Long> activeLoansLoanProductIds;
final Long productId = loan.loanProduct().getId();
if (loan.isGroupLoan()) {
activeLoansLoanProductIds = this.loanRepository.findActiveLoansLoanProductIdsByGroup(loan.getGroupId(),
LoanStatus.ACTIVE.getValue());
} else {
activeLoansLoanProductIds = this.loanRepository.findActiveLoansLoanProductIdsByClient(loan.getClientId(),
LoanStatus.ACTIVE.getValue());
}
checkForProductMixRestrictions(activeLoansLoanProductIds, productId, loan.loanProduct().productName());
}
private void checkForProductMixRestrictions(final List<Long> activeLoansLoanProductIds, final Long productId, final String productName) {
if (!CollectionUtils.isEmpty(activeLoansLoanProductIds)) {
final Collection<LoanProductData> restrictedPrdouctsList = this.loanProductReadPlatformService
.retrieveRestrictedProductsForMix(productId);
for (LoanProductData restrictedProduct : restrictedPrdouctsList) {
if (activeLoansLoanProductIds.contains(restrictedProduct.getId())) { throw new LoanDisbursalException(productName,
restrictedProduct.getName()); }
}
}
}
} }
@@ -408,5 +408,9 @@ public class LoanProduct extends AbstractPersistable<Long> {
} }
return closeLocalDate; return closeLocalDate;
} }
public String productName() {
return this.name;
}
} }