Merge branch 'pull134' into develop

This commit is contained in:
Nazeer Hussain Shaik
2016-06-09 16:55:59 +05:30
17 changed files with 251 additions and 117 deletions
@@ -77,4 +77,17 @@ public class FineractEntityToEntityMappingData implements Serializable {
} }
public Long getRelationId() {
return relationId;
}
public Long getToId() {
return toId;
}
public String getFromEntity() {
return fromEntity;
}
} }
@@ -22,9 +22,9 @@ public class FineractEntityAccessType {
private String str; private String str;
public static final FineractEntityAccessType OFFICE_ACCESS_TO_LOAN_PRODUCTS = new FineractEntityAccessType("Office Access to Loan Products"); public static final FineractEntityAccessType OFFICE_ACCESS_TO_LOAN_PRODUCTS = new FineractEntityAccessType("office_access_to_loan_products");
public static final FineractEntityAccessType OFFICE_ACCESS_TO_SAVINGS_PRODUCTS = new FineractEntityAccessType("Office Access to Savings Products"); public static final FineractEntityAccessType OFFICE_ACCESS_TO_SAVINGS_PRODUCTS = new FineractEntityAccessType("office_access_to_savings_products");
public static final FineractEntityAccessType OFFICE_ACCESS_TO_CHARGES = new FineractEntityAccessType("Office Access to Fees/Charges"); public static final FineractEntityAccessType OFFICE_ACCESS_TO_CHARGES = new FineractEntityAccessType("office_access_to_fees/charges");
private FineractEntityAccessType (String str) { private FineractEntityAccessType (String str) {
this.str = str; this.str = str;
@@ -19,8 +19,11 @@
package org.apache.fineract.infrastructure.entityaccess.domain; package org.apache.fineract.infrastructure.entityaccess.domain;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
public interface FineractEntityRelationRepository extends JpaRepository<FineractEntityRelation, Long>{ public interface FineractEntityRelationRepository extends JpaRepository<FineractEntityRelation, Long>{
@Query("from FineractEntityRelation fea where fea.codeName= :codeName")
FineractEntityRelation findOneByCodeName(@Param("codeName") String codeName);
} }
@@ -38,5 +38,11 @@ public class FineractEntityRelationRepositoryWrapper {
if (fineractEntityRelation == null) { throw new FineractEntityAccessNotFoundException(id); } if (fineractEntityRelation == null) { throw new FineractEntityAccessNotFoundException(id); }
return fineractEntityRelation; return fineractEntityRelation;
} }
public FineractEntityRelation findOneByCodeName(final String codeName) {
final FineractEntityRelation fineractEntityRelation = this.fineractEntityRelationRepository.findOneByCodeName(codeName) ;
if (fineractEntityRelation == null) { throw new FineractEntityAccessNotFoundException(codeName); }
return fineractEntityRelation;
}
} }
@@ -19,10 +19,14 @@
package org.apache.fineract.infrastructure.entityaccess.domain; package org.apache.fineract.infrastructure.entityaccess.domain;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
public interface FineractEntityToEntityMappingRepository extends JpaRepository<FineractEntityToEntityMapping, Long>{ public interface FineractEntityToEntityMappingRepository extends JpaRepository<FineractEntityToEntityMapping, Long>{
@Query("from FineractEntityToEntityMapping feem where feem.fromId= :fromId and feem.toId= :toId and feem.relationId= :relId")
FineractEntityToEntityMapping findListByProductId(@Param("relId")FineractEntityRelation relId, @Param("toId")Long toId, @Param("fromId")Long fromId );
} }
@@ -28,5 +28,8 @@ public class FineractEntityAccessNotFoundException extends AbstractPlatformResou
public FineractEntityAccessNotFoundException(final Long id) { public FineractEntityAccessNotFoundException(final Long id) {
super("error.msg.entityaccess.id.invalid", "FineractEntityAccess with identifier " + id + " does not exist", id); super("error.msg.entityaccess.id.invalid", "FineractEntityAccess with identifier " + id + " does not exist", id);
} }
public FineractEntityAccessNotFoundException(final String codeName) {
super("error.msg.entityaccess.id.invalid", "FineractEntityAccess with identifier " + codeName + " does not exist");
}
} }
@@ -0,0 +1,29 @@
/**
* 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.entityaccess.exception;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException;
public class FineractEntityMappingConfigurationException extends AbstractPlatformDomainRuleException {
public FineractEntityMappingConfigurationException() {
super("error.msg.entityaccess.config",
"Error while getting entity maping configuration ");
}
}
@@ -0,0 +1,33 @@
/**
* 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.entityaccess.exception;
import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainRuleException;
/**
* A {@link RuntimeException} thrown when valid api request end up violating
* some domain rule.
*/
public class NotOfficeSpecificProductException extends AbstractPlatformDomainRuleException {
public NotOfficeSpecificProductException(final Long productId, final Long officeId) {
super("error.msg.office.product.not.found", "Product with productId " + productId +
" not office Specific Product in offfice with officeId", officeId);
}
}
@@ -20,19 +20,17 @@ package org.apache.fineract.infrastructure.entityaccess.service;
import java.util.Collection; import java.util.Collection;
import org.apache.fineract.infrastructure.entityaccess.data.FineractEntityAccessData;
import org.apache.fineract.infrastructure.entityaccess.data.FineractEntityRelationData; import org.apache.fineract.infrastructure.entityaccess.data.FineractEntityRelationData;
import org.apache.fineract.infrastructure.entityaccess.data.FineractEntityToEntityMappingData; import org.apache.fineract.infrastructure.entityaccess.data.FineractEntityToEntityMappingData;
import org.apache.fineract.infrastructure.entityaccess.domain.FineractEntityAccessType;
import org.apache.fineract.infrastructure.entityaccess.domain.FineractEntityType; import org.apache.fineract.infrastructure.entityaccess.domain.FineractEntityType;
public interface FineractEntityAccessReadService { public interface FineractEntityAccessReadService {
Collection<FineractEntityAccessData> retrieveEntityAccessFor(Long entityId, FineractEntityType type, FineractEntityAccessType accessType, Collection<FineractEntityToEntityMappingData> retrieveEntityAccessFor(FineractEntityType firstEntityType,
FineractEntityType secondType, boolean includeAllOffices); final Long relId, final Long fromEntityId,boolean includeAllSubOffices);
String getSQLQueryInClause_WithListOfIDsForEntityAccess(Long entityId, FineractEntityType firstEntityType, String getSQLQueryInClause_WithListOfIDsForEntityAccess( FineractEntityType firstEntityType,
FineractEntityAccessType accessType, FineractEntityType secondEntityType, boolean includeAllOffices); final Long relId,final Long fromEntityId ,boolean includeAllOffices);
String getSQLQueryInClauseIDList_ForLoanProductsForOffice(Long loanProductId, boolean includeAllOffices); String getSQLQueryInClauseIDList_ForLoanProductsForOffice(Long loanProductId, boolean includeAllOffices);
@@ -31,8 +31,11 @@ import org.apache.fineract.infrastructure.entityaccess.data.FineractEntityRelati
import org.apache.fineract.infrastructure.entityaccess.data.FineractEntityToEntityMappingData; import org.apache.fineract.infrastructure.entityaccess.data.FineractEntityToEntityMappingData;
import org.apache.fineract.infrastructure.entityaccess.domain.FineractEntity; import org.apache.fineract.infrastructure.entityaccess.domain.FineractEntity;
import org.apache.fineract.infrastructure.entityaccess.domain.FineractEntityAccessType; import org.apache.fineract.infrastructure.entityaccess.domain.FineractEntityAccessType;
import org.apache.fineract.infrastructure.entityaccess.domain.FineractEntityRelation;
import org.apache.fineract.infrastructure.entityaccess.domain.FineractEntityRelationRepositoryWrapper;
import org.apache.fineract.infrastructure.entityaccess.domain.FineractEntityType; import org.apache.fineract.infrastructure.entityaccess.domain.FineractEntityType;
import org.apache.fineract.infrastructure.entityaccess.exception.FineractEntityAccessConfigurationException; import org.apache.fineract.infrastructure.entityaccess.exception.FineractEntityAccessConfigurationException;
import org.apache.fineract.infrastructure.entityaccess.exception.FineractEntityMappingConfigurationException;
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext; import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
import org.apache.fineract.useradministration.domain.AppUser; import org.apache.fineract.useradministration.domain.AppUser;
import org.slf4j.Logger; import org.slf4j.Logger;
@@ -48,11 +51,14 @@ public class FineractEntityAccessReadServiceImpl implements FineractEntityAccess
private final PlatformSecurityContext context; private final PlatformSecurityContext context;
private final JdbcTemplate jdbcTemplate; private final JdbcTemplate jdbcTemplate;
private final static Logger logger = LoggerFactory.getLogger(GenericDataServiceImpl.class); private final static Logger logger = LoggerFactory.getLogger(GenericDataServiceImpl.class);
private final FineractEntityRelationRepositoryWrapper fineractEntityRelationRepository;
@Autowired @Autowired
public FineractEntityAccessReadServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource) { public FineractEntityAccessReadServiceImpl(final PlatformSecurityContext context, final RoutingDataSource dataSource,
final FineractEntityRelationRepositoryWrapper fineractEntityRelationRepository) {
this.context = context; this.context = context;
this.jdbcTemplate = new JdbcTemplate(dataSource); this.jdbcTemplate = new JdbcTemplate(dataSource);
this.fineractEntityRelationRepository = fineractEntityRelationRepository;
} }
/* /*
@@ -71,38 +77,32 @@ public class FineractEntityAccessReadServiceImpl implements FineractEntityAccess
* null if there is no entity restrictions or if there * null if there is no entity restrictions or if there
*/ */
@Override @Override
public String getSQLQueryInClause_WithListOfIDsForEntityAccess(Long firstEntityId, FineractEntityType firstEntityType, public String getSQLQueryInClause_WithListOfIDsForEntityAccess( FineractEntityType firstEntityType,
FineractEntityAccessType accessType, FineractEntityType secondEntityType, boolean includeAllOffices) { final Long relId, final Long fromEntityId, boolean includeAllOffices) {
Collection<FineractEntityAccessData> accesslist = retrieveEntityAccessFor(firstEntityId, firstEntityType, accessType, secondEntityType, Collection<FineractEntityToEntityMappingData> accesslist = retrieveEntityAccessFor(firstEntityType, relId, fromEntityId,
includeAllOffices); includeAllOffices);
String returnIdListStr = null; String returnIdListStr = null;
StringBuffer accessListCSVStrBuf = null; StringBuffer accessListCSVStrBuf = null;
if ((accesslist != null) && (accesslist.size() > 0)) { if ((accesslist != null) && (accesslist.size() > 0)) {
logger.debug("Found " + accesslist.size() + " access type restrictions while getting entity access configuration for " for(FineractEntityToEntityMappingData accessData: accesslist){
+ firstEntityType.getType() + ":" + firstEntityId + " with type " + accessType.toStr() + " against " if (accessData == null) {
+ secondEntityType.getType()); throw new FineractEntityMappingConfigurationException();
accessListCSVStrBuf = new StringBuffer(" "); }
for (int i = 0; i < accesslist.size(); i++) {
FineractEntityAccessData accessData = (FineractEntityAccessData) accesslist.toArray()[i]; if(accessListCSVStrBuf == null){
if (accessData == null) { throw new FineractEntityAccessConfigurationException(firstEntityId, firstEntityType, accessType, accessListCSVStrBuf = new StringBuffer() ;
secondEntityType); } }else{
if (accessData.getSecondEntity().getId() == 0) { // If there is accessListCSVStrBuf.append(",");
// any ID that }
// zero, then accessListCSVStrBuf.append(accessData.getToId());
// allow access if(accessData.getToId() == 0){
// to all accessListCSVStrBuf =null;
accessListCSVStrBuf = null; break;
break; }
} }
if (i > 0) {
accessListCSVStrBuf.append(',');
}
accessListCSVStrBuf.append(accessData.getSecondEntity().getId());
}
} else { } else {
logger.debug("Found zero access type restrictions while getting entity access configuration for " + firstEntityType.getType()
+ ":" + firstEntityId + " with type " + accessType.toStr() + " against " + secondEntityType.getType());
accessListCSVStrBuf = new StringBuffer(); accessListCSVStrBuf = new StringBuffer();
accessListCSVStrBuf.append("false"); // Append false so that no rows accessListCSVStrBuf.append("false"); // Append false so that no rows
// will be returned // will be returned
@@ -115,8 +115,8 @@ public class FineractEntityAccessReadServiceImpl implements FineractEntityAccess
} }
@Override @Override
public Collection<FineractEntityAccessData> retrieveEntityAccessFor(Long firstEntityId, FineractEntityType firstEntityType, public Collection<FineractEntityToEntityMappingData> retrieveEntityAccessFor(FineractEntityType firstEntityType,
FineractEntityAccessType accessType, FineractEntityType secondEntityType, boolean includeAllSubOffices) { final Long relId, final Long fromEntityId,boolean includeAllSubOffices) {
final AppUser currentUser = this.context.authenticatedUser(); final AppUser currentUser = this.context.authenticatedUser();
final String hierarchy = currentUser.getOffice().getHierarchy(); final String hierarchy = currentUser.getOffice().getHierarchy();
@@ -126,52 +126,27 @@ public class FineractEntityAccessReadServiceImpl implements FineractEntityAccess
} else { } else {
hierarchySearchString = hierarchy + "%"; hierarchySearchString = hierarchy + "%";
} }
String sql = getSQLForRetriveEntityAccessFor(firstEntityType, accessType, secondEntityType); String sql = getSQLForRetriveEntityAccessFor();
Collection<FineractEntityAccessData> entityAccessData = null; Collection<FineractEntityToEntityMappingData> entityAccessData = null;
FineractEntityAccessDataMapper mapper = new FineractEntityAccessDataMapper(); GetOneEntityMapper mapper = new GetOneEntityMapper();
if (includeAllSubOffices && (firstEntityType.getTable().equals("m_office"))) { if (includeAllSubOffices && (firstEntityType.getTable().equals("m_office"))) {
sql += " where firstentity.hierarchy like ? order by firstEntity.hierarchy"; sql += " where firstentity.hierarchy like ? order by firstEntity.hierarchy";
entityAccessData = this.jdbcTemplate.query(sql, mapper, new Object[] { firstEntityId, hierarchySearchString }); entityAccessData = this.jdbcTemplate.query(sql, mapper, new Object[] { fromEntityId, fromEntityId, hierarchySearchString });
} else { } else {
entityAccessData = this.jdbcTemplate.query(sql, mapper, new Object[] { firstEntityId }); entityAccessData = this.jdbcTemplate.query(sql, mapper, new Object[] { relId, fromEntityId});
} }
return entityAccessData; return entityAccessData;
} }
private String getSQLForRetriveEntityAccessFor(FineractEntityType firstEntityType, FineractEntityAccessType accessType, private String getSQLForRetriveEntityAccessFor() {
FineractEntityType secondEntityType) { StringBuffer str = new StringBuffer("select eem.rel_id as relId,eem.from_id as fromId, ");
StringBuffer str = new StringBuffer("select eea.entity_id as entity_id, entity_type as entity_type, "); str.append("eem.to_id as toId, eem.start_date as startDate, eem.end_date as endDate ");
str.append("access_type_code_value_id as access_id, cv.code_value as access_type_desc, c.code_name as code, "); str.append("from m_entity_to_entity_mapping eem ");
str.append("firstentity.id as first_entity_id, firstentity.name as entity_name, "); str.append("where eem.rel_id = ? ");
str.append("otherentity.id as second_entity_id, otherentity.name as second_entity_name, "); str.append("and eem.from_id = ? ");
str.append("eea.second_entity_type as second_entity_type ");
str.append("from m_entity_to_entity_access eea ");
str.append("left join m_code_value cv on (cv.code_value = ");
str.append("'");
str.append(accessType.toStr());
str.append("' ");
str.append("and eea.access_type_code_value_id = cv.id) ");
str.append("left join m_code c on (c.code_name = '");
str.append(FineractEntityAccessConstants.ENTITY_ACCESS_CODENAME);
str.append("' and cv.code_id = c.id) ");
str.append("left join ");
str.append(firstEntityType.getTable());
str.append(" firstentity on (eea.entity_type = ");
str.append("'");
str.append(firstEntityType.getType());
str.append("'");
str.append(" and eea.entity_id = firstentity.id) left join ");
str.append(secondEntityType.getTable());
str.append(" otherentity on (eea.second_entity_type = ");
str.append("'");
str.append(secondEntityType.getType());
str.append("' ");
str.append("and eea.second_entity_id = otherentity.id) ");
str.append("where eea.access_type_code_value_id = cv.id ");
str.append("and eea.entity_id = ? ");
logger.debug(str.toString()); logger.debug(str.toString());
return str.toString(); return str.toString();
} }
@@ -220,30 +195,32 @@ public class FineractEntityAccessReadServiceImpl implements FineractEntityAccess
public String getSQLQueryInClauseIDList_ForLoanProductsForOffice(Long officeId, boolean includeAllOffices) { public String getSQLQueryInClauseIDList_ForLoanProductsForOffice(Long officeId, boolean includeAllOffices) {
FineractEntityType firstEntityType = FineractEntityType.OFFICE; FineractEntityType firstEntityType = FineractEntityType.OFFICE;
FineractEntityAccessType accessType = FineractEntityAccessType.OFFICE_ACCESS_TO_LOAN_PRODUCTS; FineractEntityRelation fineractEntityRelation = fineractEntityRelationRepository
FineractEntityType secondEntityType = FineractEntityType.LOAN_PRODUCT; .findOneByCodeName(FineractEntityAccessType.OFFICE_ACCESS_TO_LOAN_PRODUCTS.toStr());
Long relId = fineractEntityRelation.getId();
return getSQLQueryInClause_WithListOfIDsForEntityAccess(officeId, firstEntityType, accessType, secondEntityType, includeAllOffices); return getSQLQueryInClause_WithListOfIDsForEntityAccess(firstEntityType, relId, officeId, includeAllOffices);
} }
@Override @Override
public String getSQLQueryInClauseIDList_ForSavingsProductsForOffice(Long officeId, boolean includeAllOffices) { public String getSQLQueryInClauseIDList_ForSavingsProductsForOffice(Long officeId, boolean includeAllOffices) {
FineractEntityType firstEntityType = FineractEntityType.OFFICE; FineractEntityType firstEntityType = FineractEntityType.OFFICE;
FineractEntityAccessType accessType = FineractEntityAccessType.OFFICE_ACCESS_TO_SAVINGS_PRODUCTS; FineractEntityRelation fineractEntityRelation = fineractEntityRelationRepository
FineractEntityType secondEntityType = FineractEntityType.SAVINGS_PRODUCT; .findOneByCodeName(FineractEntityAccessType.OFFICE_ACCESS_TO_SAVINGS_PRODUCTS.toStr());
Long relId = fineractEntityRelation.getId();
return getSQLQueryInClause_WithListOfIDsForEntityAccess(officeId, firstEntityType, accessType, secondEntityType, includeAllOffices); return getSQLQueryInClause_WithListOfIDsForEntityAccess(firstEntityType, relId, officeId, includeAllOffices);
} }
@Override @Override
public String getSQLQueryInClauseIDList_ForChargesForOffice(Long officeId, boolean includeAllOffices) { public String getSQLQueryInClauseIDList_ForChargesForOffice(Long officeId, boolean includeAllOffices) {
FineractEntityType firstEntityType = FineractEntityType.OFFICE; FineractEntityType firstEntityType = FineractEntityType.OFFICE;
FineractEntityAccessType accessType = FineractEntityAccessType.OFFICE_ACCESS_TO_CHARGES; FineractEntityRelation fineractEntityRelation = fineractEntityRelationRepository
FineractEntityType secondEntityType = FineractEntityType.CHARGE; .findOneByCodeName(FineractEntityAccessType.OFFICE_ACCESS_TO_CHARGES.toStr());
Long relId = fineractEntityRelation.getId();
return getSQLQueryInClause_WithListOfIDsForEntityAccess(officeId, firstEntityType, accessType, secondEntityType, includeAllOffices); return getSQLQueryInClause_WithListOfIDsForEntityAccess(firstEntityType, relId, officeId, includeAllOffices);
} }
@Override @Override
@@ -19,6 +19,7 @@
package org.apache.fineract.infrastructure.entityaccess.service; package org.apache.fineract.infrastructure.entityaccess.service;
import java.util.Collection; import java.util.Collection;
import java.util.Date;
import java.util.Iterator; import java.util.Iterator;
import org.apache.fineract.infrastructure.codes.data.CodeValueData; import org.apache.fineract.infrastructure.codes.data.CodeValueData;
@@ -29,6 +30,10 @@ import org.apache.fineract.infrastructure.configuration.domain.GlobalConfigurati
import org.apache.fineract.infrastructure.configuration.domain.GlobalConfigurationRepositoryWrapper; import org.apache.fineract.infrastructure.configuration.domain.GlobalConfigurationRepositoryWrapper;
import org.apache.fineract.infrastructure.entityaccess.FineractEntityAccessConstants; import org.apache.fineract.infrastructure.entityaccess.FineractEntityAccessConstants;
import org.apache.fineract.infrastructure.entityaccess.domain.FineractEntityAccessType; import org.apache.fineract.infrastructure.entityaccess.domain.FineractEntityAccessType;
import org.apache.fineract.infrastructure.entityaccess.domain.FineractEntityRelation;
import org.apache.fineract.infrastructure.entityaccess.domain.FineractEntityRelationRepositoryWrapper;
import org.apache.fineract.infrastructure.entityaccess.domain.FineractEntityToEntityMapping;
import org.apache.fineract.infrastructure.entityaccess.domain.FineractEntityToEntityMappingRepository;
import org.apache.fineract.infrastructure.entityaccess.domain.FineractEntityType; import org.apache.fineract.infrastructure.entityaccess.domain.FineractEntityType;
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext; import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
import org.apache.fineract.useradministration.domain.AppUser; import org.apache.fineract.useradministration.domain.AppUser;
@@ -47,6 +52,8 @@ public class FineractEntityAccessUtil {
private final CodeValueRepositoryWrapper codeValueRepository; private final CodeValueRepositoryWrapper codeValueRepository;
private final FineractEntityAccessWriteService fineractEntityAccessWriteService; private final FineractEntityAccessWriteService fineractEntityAccessWriteService;
private final FineractEntityAccessReadService fineractEntityAccessReadService; private final FineractEntityAccessReadService fineractEntityAccessReadService;
private final FineractEntityRelationRepositoryWrapper fineractEntityRelationRepositoryWrapper;
private final FineractEntityToEntityMappingRepository fineractEntityToEntityMappingRepository;
@Autowired @Autowired
public FineractEntityAccessUtil ( public FineractEntityAccessUtil (
@@ -55,20 +62,23 @@ public class FineractEntityAccessUtil {
final FineractEntityAccessWriteService fineractEntityAccessWriteService, final FineractEntityAccessWriteService fineractEntityAccessWriteService,
final CodeValueReadPlatformService codeValueReadPlatformService, final CodeValueReadPlatformService codeValueReadPlatformService,
final CodeValueRepositoryWrapper codeValueRepository, final CodeValueRepositoryWrapper codeValueRepository,
final FineractEntityAccessReadService fineractEntityAccessReadService) { final FineractEntityAccessReadService fineractEntityAccessReadService,
final FineractEntityRelationRepositoryWrapper fineractEntityRelationRepositoryWrapper,
final FineractEntityToEntityMappingRepository fineractEntityToEntityMappingRepository) {
this.context = context; this.context = context;
this.globalConfigurationRepository = globalConfigurationRepository; this.globalConfigurationRepository = globalConfigurationRepository;
this.fineractEntityAccessWriteService = fineractEntityAccessWriteService; this.fineractEntityAccessWriteService = fineractEntityAccessWriteService;
this.codeValueReadPlatformService = codeValueReadPlatformService; this.codeValueReadPlatformService = codeValueReadPlatformService;
this.codeValueRepository = codeValueRepository; this.codeValueRepository = codeValueRepository;
this.fineractEntityAccessReadService = fineractEntityAccessReadService; this.fineractEntityAccessReadService = fineractEntityAccessReadService;
this.fineractEntityRelationRepositoryWrapper = fineractEntityRelationRepositoryWrapper;
this.fineractEntityToEntityMappingRepository = fineractEntityToEntityMappingRepository;
} }
@Transactional @Transactional
public void checkConfigurationAndAddProductResrictionsForUserOffice ( public void checkConfigurationAndAddProductResrictionsForUserOffice (
final FineractEntityAccessType fineractEntityAccessType, final FineractEntityAccessType fineractEntityAccessType,
final FineractEntityType fineractEntityType,
final Long productOrChargeId) { final Long productOrChargeId) {
AppUser thisUser = this.context.authenticatedUser(); AppUser thisUser = this.context.authenticatedUser();
@@ -87,28 +97,17 @@ public class FineractEntityAccessUtil {
if (restrictToUserOfficeProperty.isEnabled() ) { if (restrictToUserOfficeProperty.isEnabled() ) {
final Long officeId = thisUser.getOffice().getId(); final Long officeId = thisUser.getOffice().getId();
Collection<CodeValueData> codevalues = codeValueReadPlatformService.retrieveCodeValuesByCode( Date startDateFormapping = null;
FineractEntityAccessConstants.ENTITY_ACCESS_CODENAME); Date endDateFormapping = null;
if (codevalues != null) { FineractEntityRelation fineractEntityRelation = fineractEntityRelationRepositoryWrapper
Iterator<CodeValueData> iterator = codevalues.iterator(); .findOneByCodeName(fineractEntityAccessType.toStr());
while(iterator.hasNext()) { Long relId = fineractEntityRelation.getId();
CodeValueData oneCodeValue = iterator.next(); final FineractEntityRelation mapId = this.fineractEntityRelationRepositoryWrapper
if ( (oneCodeValue != null) && .findOneWithNotFoundDetection(relId);
(oneCodeValue.getName().equals(fineractEntityAccessType.toStr())) ) { final FineractEntityToEntityMapping newMap = FineractEntityToEntityMapping.newMap(mapId, officeId,
CodeValue cv = codeValueRepository.findOneByCodeNameAndLabelWithNotFoundDetection( productOrChargeId, startDateFormapping, endDateFormapping);
FineractEntityAccessConstants.ENTITY_ACCESS_CODENAME, this.fineractEntityToEntityMappingRepository.save(newMap);
fineractEntityAccessType.toStr()
);
if (cv != null) {
fineractEntityAccessWriteService.addNewEntityAccess(
FineractEntityType.OFFICE.getType(), officeId,
cv,
fineractEntityType.getType(), productOrChargeId);
} }
}
}
}
}
} }
} }
@@ -114,7 +114,7 @@ public class ChargeWritePlatformServiceJpaRepositoryImpl implements ChargeWriteP
// save this savings product against a specific office // save this savings product against a specific office
// i.e. this savings product is specific for this office. // i.e. this savings product is specific for this office.
fineractEntityAccessUtil.checkConfigurationAndAddProductResrictionsForUserOffice( fineractEntityAccessUtil.checkConfigurationAndAddProductResrictionsForUserOffice(
FineractEntityAccessType.OFFICE_ACCESS_TO_CHARGES, FineractEntityType.CHARGE, charge.getId()); FineractEntityAccessType.OFFICE_ACCESS_TO_CHARGES, charge.getId());
return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(charge.getId()).build(); return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(charge.getId()).build();
} catch (final DataIntegrityViolationException dve) { } catch (final DataIntegrityViolationException dve) {
@@ -5982,4 +5982,12 @@ public class Loan extends AbstractPersistable<Long> {
this.writeOffReason = writeOffReason; this.writeOffReason = writeOffReason;
} }
public Group getGroup() {
return group;
}
public LoanProduct getLoanProduct() {
return loanProduct;
}
} }
@@ -32,15 +32,24 @@ import org.apache.fineract.infrastructure.accountnumberformat.domain.AccountNumb
import org.apache.fineract.infrastructure.accountnumberformat.domain.EntityAccountType; import org.apache.fineract.infrastructure.accountnumberformat.domain.EntityAccountType;
import org.apache.fineract.infrastructure.codes.domain.CodeValue; import org.apache.fineract.infrastructure.codes.domain.CodeValue;
import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService; import org.apache.fineract.infrastructure.configuration.domain.ConfigurationDomainService;
import org.apache.fineract.infrastructure.configuration.domain.GlobalConfigurationProperty;
import org.apache.fineract.infrastructure.configuration.domain.GlobalConfigurationRepositoryWrapper;
import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.api.JsonQuery; import org.apache.fineract.infrastructure.core.api.JsonQuery;
import org.apache.fineract.infrastructure.core.data.ApiParameterError; import org.apache.fineract.infrastructure.core.data.ApiParameterError;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder; import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder; import org.apache.fineract.infrastructure.core.data.DataValidatorBuilder;
import org.apache.fineract.infrastructure.entityaccess.exception.NotOfficeSpecificProductException;
import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException; import org.apache.fineract.infrastructure.core.exception.PlatformApiDataValidationException;
import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException; import org.apache.fineract.infrastructure.core.exception.PlatformDataIntegrityException;
import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper; import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
import org.apache.fineract.infrastructure.entityaccess.FineractEntityAccessConstants;
import org.apache.fineract.infrastructure.entityaccess.domain.FineractEntityAccessType;
import org.apache.fineract.infrastructure.entityaccess.domain.FineractEntityRelation;
import org.apache.fineract.infrastructure.entityaccess.domain.FineractEntityRelationRepository;
import org.apache.fineract.infrastructure.entityaccess.domain.FineractEntityToEntityMapping;
import org.apache.fineract.infrastructure.entityaccess.domain.FineractEntityToEntityMappingRepository;
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext; import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
import org.apache.fineract.organisation.staff.domain.Staff; import org.apache.fineract.organisation.staff.domain.Staff;
import org.apache.fineract.portfolio.account.domain.AccountAssociationType; import org.apache.fineract.portfolio.account.domain.AccountAssociationType;
@@ -156,6 +165,9 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
private final LoanScheduleAssembler loanScheduleAssembler; private final LoanScheduleAssembler loanScheduleAssembler;
private final LoanUtilService loanUtilService; private final LoanUtilService loanUtilService;
private final CalendarReadPlatformService calendarReadPlatformService; private final CalendarReadPlatformService calendarReadPlatformService;
private final GlobalConfigurationRepositoryWrapper globalConfigurationRepository;
private final FineractEntityToEntityMappingRepository repository;
private final FineractEntityRelationRepository fineractEntityRelationRepository;
@Autowired @Autowired
public LoanApplicationWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final FromJsonHelper fromJsonHelper, public LoanApplicationWritePlatformServiceJpaRepositoryImpl(final PlatformSecurityContext context, final FromJsonHelper fromJsonHelper,
@@ -175,7 +187,8 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
final AccountNumberFormatRepositoryWrapper accountNumberFormatRepository, final AccountNumberFormatRepositoryWrapper accountNumberFormatRepository,
final BusinessEventNotifierService businessEventNotifierService, final ConfigurationDomainService configurationDomainService, final BusinessEventNotifierService businessEventNotifierService, final ConfigurationDomainService configurationDomainService,
final LoanScheduleAssembler loanScheduleAssembler, final LoanUtilService loanUtilService, final LoanScheduleAssembler loanScheduleAssembler, final LoanUtilService loanUtilService,
final CalendarReadPlatformService calendarReadPlatformService) { final CalendarReadPlatformService calendarReadPlatformService, final GlobalConfigurationRepositoryWrapper globalConfigurationRepository,
final FineractEntityToEntityMappingRepository repository, final FineractEntityRelationRepository fineractEntityRelationRepository) {
this.context = context; this.context = context;
this.fromJsonHelper = fromJsonHelper; this.fromJsonHelper = fromJsonHelper;
this.loanApplicationTransitionApiJsonValidator = loanApplicationTransitionApiJsonValidator; this.loanApplicationTransitionApiJsonValidator = loanApplicationTransitionApiJsonValidator;
@@ -206,6 +219,9 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
this.loanScheduleAssembler = loanScheduleAssembler; this.loanScheduleAssembler = loanScheduleAssembler;
this.loanUtilService = loanUtilService; this.loanUtilService = loanUtilService;
this.calendarReadPlatformService = calendarReadPlatformService; this.calendarReadPlatformService = calendarReadPlatformService;
this.globalConfigurationRepository = globalConfigurationRepository;
this.repository = repository;
this.fineractEntityRelationRepository = fineractEntityRelationRepository;
} }
private LoanLifecycleStateMachine defaultLoanLifecycleStateMachine() { private LoanLifecycleStateMachine defaultLoanLifecycleStateMachine() {
@@ -224,14 +240,23 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
final LoanProduct loanProduct = this.loanProductRepository.findOne(productId); final LoanProduct loanProduct = this.loanProductRepository.findOne(productId);
if (loanProduct == null) { throw new LoanProductNotFoundException(productId); } if (loanProduct == null) { throw new LoanProductNotFoundException(productId); }
final Long clientId = this.fromJsonHelper.extractLongNamed("clientId", command.parsedJson());
if(clientId !=null){
Client client= this.clientRepository.findOneWithNotFoundDetection(clientId);
officeSpecificLoanProductValidation( productId,client.getOffice().getId());
}
final Long groupId = this.fromJsonHelper.extractLongNamed("groupId", command.parsedJson());
if(groupId != null){
Group group= this.groupRepository.findOneWithNotFoundDetection(groupId);
officeSpecificLoanProductValidation( productId,group.getOffice().getId());
}
this.fromApiJsonDeserializer.validateForCreate(command.json(), isMeetingMandatoryForJLGLoans, loanProduct); this.fromApiJsonDeserializer.validateForCreate(command.json(), isMeetingMandatoryForJLGLoans, loanProduct);
final List<ApiParameterError> dataValidationErrors = new ArrayList<>(); final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("loan"); final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors).resource("loan");
if (loanProduct.useBorrowerCycle()) { if (loanProduct.useBorrowerCycle()) {
final Long clientId = this.fromJsonHelper.extractLongNamed("clientId", command.parsedJson());
final Long groupId = this.fromJsonHelper.extractLongNamed("groupId", command.parsedJson());
Integer cycleNumber = 0; Integer cycleNumber = 0;
if (clientId != null) { if (clientId != null) {
cycleNumber = this.loanReadPlatformService.retriveLoanCounter(clientId, loanProduct.getId()); cycleNumber = this.loanReadPlatformService.retriveLoanCounter(clientId, loanProduct.getId());
@@ -802,6 +827,18 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
} }
} }
} }
if ((command.longValueOfParameterNamed(productIdParamName) != null)
|| (command.longValueOfParameterNamed(clientIdParamName) != null) || (command.longValueOfParameterNamed(groupIdParamName) != null)) {
Long OfficeId = null;
if(existingLoanApplication.getClient() != null){
OfficeId = existingLoanApplication.getClient().getOffice().getId();
}
else if(existingLoanApplication.getGroup() != null){
OfficeId = existingLoanApplication.getGroup().getOffice().getId();
}
officeSpecificLoanProductValidation( existingLoanApplication.getLoanProduct().getId(),OfficeId);
}
// updating loan interest recalculation details throwing null // updating loan interest recalculation details throwing null
// pointer exception after saveAndFlush // pointer exception after saveAndFlush
@@ -1160,4 +1197,20 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa
return map; return map;
} }
private void officeSpecificLoanProductValidation(final Long productId, final Long officeId) {
final GlobalConfigurationProperty restrictToUserOfficeProperty = this.globalConfigurationRepository
.findOneByNameWithNotFoundDetection(
FineractEntityAccessConstants.GLOBAL_CONFIG_FOR_OFFICE_SPECIFIC_PRODUCTS);
if (restrictToUserOfficeProperty.isEnabled()) {
FineractEntityRelation fineractEntityRelation = fineractEntityRelationRepository
.findOneByCodeName(FineractEntityAccessType.OFFICE_ACCESS_TO_LOAN_PRODUCTS.toStr());
FineractEntityToEntityMapping officeToLoanProductMappingList = this.repository.findListByProductId(fineractEntityRelation, productId,
officeId);
if (officeToLoanProductMappingList == null) {
throw new NotOfficeSpecificProductException(productId, officeId);
}
}
}
} }
@@ -136,7 +136,6 @@ public class LoanProductWritePlatformServiceJpaRepositoryImpl implements LoanPro
// i.e. this savings product is specific for this office. // i.e. this savings product is specific for this office.
fineractEntityAccessUtil.checkConfigurationAndAddProductResrictionsForUserOffice( fineractEntityAccessUtil.checkConfigurationAndAddProductResrictionsForUserOffice(
FineractEntityAccessType.OFFICE_ACCESS_TO_LOAN_PRODUCTS, FineractEntityAccessType.OFFICE_ACCESS_TO_LOAN_PRODUCTS,
FineractEntityType.LOAN_PRODUCT,
loanproduct.getId()); loanproduct.getId());
return new CommandProcessingResultBuilder() // return new CommandProcessingResultBuilder() //
@@ -128,7 +128,7 @@ public class SavingsProductWritePlatformServiceJpaRepositoryImpl implements Savi
// save this savings product against a specific office // save this savings product against a specific office
// i.e. this savings product is specific for this office. // i.e. this savings product is specific for this office.
fineractEntityAccessUtil.checkConfigurationAndAddProductResrictionsForUserOffice( fineractEntityAccessUtil.checkConfigurationAndAddProductResrictionsForUserOffice(
FineractEntityAccessType.OFFICE_ACCESS_TO_SAVINGS_PRODUCTS, FineractEntityType.SAVINGS_PRODUCT, product.getId()); FineractEntityAccessType.OFFICE_ACCESS_TO_SAVINGS_PRODUCTS, product.getId());
return new CommandProcessingResultBuilder() // return new CommandProcessingResultBuilder() //
.withEntityId(product.getId()) // .withEntityId(product.getId()) //
@@ -0,0 +1,9 @@
insert ignore into m_entity_to_entity_mapping (from_id,to_id,rel_id)
select mea.entity_id as fromId,
mea.second_entity_id as toid,
case mea.access_type_code_value_id
when 10 then 1
when 11 then 2
when 12 then 3
end as reId
from m_entity_to_entity_access mea