Fixed issue with entity datatable check

This commit is contained in:
Satish
2016-12-19 09:45:57 +05:30
parent 94baf15b97
commit 8b20f0818c
10 changed files with 301 additions and 260 deletions
@@ -33,7 +33,7 @@ public enum EntityTables {
LOAN("m_loan",
new Integer[]{StatusEnum.CREATE.getCode(),
StatusEnum.APPROVE.getCode(),
StatusEnum.ACTIVATE.getCode(),
StatusEnum.DISBURSE.getCode(),
StatusEnum.WITHDRAWN.getCode(),
StatusEnum.REJECTED.getCode(),
StatusEnum.WRITE_OFF.getCode()},
@@ -26,7 +26,7 @@ import org.apache.fineract.infrastructure.core.data.EnumOptionData;
public enum StatusEnum {
CREATE("create", 100), APPROVE("approve", 200), ACTIVATE("activate", 300), WITHDRAWN("withdraw", 400), REJECTED("reject", 500), CLOSE(
"close", 600), WRITE_OFF("write off", 601), RESCHEDULE("reschedule", 602), OVERPAY("overpay", 700);
"close", 600), WRITE_OFF("write off", 601), RESCHEDULE("reschedule", 602), OVERPAY("overpay", 700), DISBURSE("disburse", 800);
private String name;
@@ -85,6 +85,9 @@ public enum StatusEnum {
case 700:
ret = StatusEnum.OVERPAY;
break;
case 800:
ret = StatusEnum.DISBURSE;
break;
default:
break;
}
@@ -23,10 +23,16 @@ import org.apache.fineract.infrastructure.core.exception.AbstractPlatformDomainR
/**
* A {@link AbstractPlatformDomainRuleException} thrown when datatable resources are not found.
*/
public class DatatabaleEntryRequiredException extends AbstractPlatformDomainRuleException{
public class DatatableEntryRequiredException extends AbstractPlatformDomainRuleException {
public DatatabaleEntryRequiredException(String datatableName) {
super("error.msg.entry.required.in.datatable." + datatableName, "The datatable " + datatableName
+ " needs to be filled in before the current action can be proceeded", datatableName);
public DatatableEntryRequiredException(String datatableName) {
super("error.msg.entry.required.in.datatable." + datatableName, "The datatable " + datatableName
+ " needs to be filled in before the current action can be proceeded", datatableName);
}
public DatatableEntryRequiredException(String datatableName, Long appTableId) {
super("error.msg.entry.cannot.be.deleted.datatable." + datatableName + ".attached.to.entity.datatable.check",
"The entry cannot be deleted, due to datatable " + datatableName + " is attached to an Entity-Datatable check",
datatableName, appTableId);
}
}
@@ -55,261 +55,242 @@ import com.google.gson.JsonObject;
@Service
public class EntityDatatableChecksWritePlatformServiceImpl implements EntityDatatableChecksWritePlatformService {
private final static Logger logger = LoggerFactory.getLogger(EntityDatatableChecksWritePlatformServiceImpl.class);
private final static Logger logger = LoggerFactory.getLogger(EntityDatatableChecksWritePlatformServiceImpl.class);
private final PlatformSecurityContext context;
private final EntityDatatableChecksDataValidator fromApiJsonDeserializer;
private final EntityDatatableChecksRepository entityDatatableChecksRepository;
private final ReadWriteNonCoreDataService readWriteNonCoreDataService;
private final LoanProductReadPlatformService loanProductReadPlatformService;
private final SavingsProductReadPlatformService savingsProductReadPlatformService;
private final FromJsonHelper fromApiJsonHelper;
private final ConfigurationDomainService configurationDomainService;
private final PlatformSecurityContext context;
private final EntityDatatableChecksDataValidator fromApiJsonDeserializer;
private final EntityDatatableChecksRepository entityDatatableChecksRepository;
private final ReadWriteNonCoreDataService readWriteNonCoreDataService;
private final LoanProductReadPlatformService loanProductReadPlatformService;
private final SavingsProductReadPlatformService savingsProductReadPlatformService;
private final FromJsonHelper fromApiJsonHelper;
private final ConfigurationDomainService configurationDomainService;
@Autowired
public EntityDatatableChecksWritePlatformServiceImpl(final PlatformSecurityContext context,
final EntityDatatableChecksDataValidator fromApiJsonDeserializer,
final EntityDatatableChecksRepository entityDatatableChecksRepository,
final ReadWriteNonCoreDataService readWriteNonCoreDataService,
final LoanProductReadPlatformService loanProductReadPlatformService,
final SavingsProductReadPlatformService savingsProductReadPlatformService,
final FromJsonHelper fromApiJsonHelper,
final ConfigurationDomainService configurationDomainService) {
this.context = context;
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.entityDatatableChecksRepository = entityDatatableChecksRepository;
this.readWriteNonCoreDataService = readWriteNonCoreDataService;
this.loanProductReadPlatformService = loanProductReadPlatformService;
this.savingsProductReadPlatformService = savingsProductReadPlatformService;
this.fromApiJsonHelper = fromApiJsonHelper;
this.configurationDomainService = configurationDomainService;
}
@Autowired
public EntityDatatableChecksWritePlatformServiceImpl(final PlatformSecurityContext context,
final EntityDatatableChecksDataValidator fromApiJsonDeserializer,
final EntityDatatableChecksRepository entityDatatableChecksRepository,
final ReadWriteNonCoreDataService readWriteNonCoreDataService,
final LoanProductReadPlatformService loanProductReadPlatformService,
final SavingsProductReadPlatformService savingsProductReadPlatformService, final FromJsonHelper fromApiJsonHelper,
final ConfigurationDomainService configurationDomainService) {
this.context = context;
this.fromApiJsonDeserializer = fromApiJsonDeserializer;
this.entityDatatableChecksRepository = entityDatatableChecksRepository;
this.readWriteNonCoreDataService = readWriteNonCoreDataService;
this.loanProductReadPlatformService = loanProductReadPlatformService;
this.savingsProductReadPlatformService = savingsProductReadPlatformService;
this.fromApiJsonHelper = fromApiJsonHelper;
this.configurationDomainService = configurationDomainService;
}
@Transactional
@Override
public CommandProcessingResult createCheck(final JsonCommand command) {
@Transactional
@Override
public CommandProcessingResult createCheck(final JsonCommand command) {
try {
this.context.authenticatedUser();
try {
this.context.authenticatedUser();
this.fromApiJsonDeserializer.validateForCreate(command.json());
this.fromApiJsonDeserializer.validateForCreate(command.json());
// check if the datatable is linked to the entity
// check if the datatable is linked to the entity
String datatableName = command.stringValueOfParameterNamed("datatableName");
DatatableData datatableData = this.readWriteNonCoreDataService.retrieveDatatable(datatableName);
String datatableName = command.stringValueOfParameterNamed("datatableName");
DatatableData datatableData = this.readWriteNonCoreDataService.retrieveDatatable(datatableName);
if (datatableData == null) {
throw new DatatableNotFoundException(datatableName);
}
if (datatableData == null) { throw new DatatableNotFoundException(datatableName); }
final String entity = command.stringValueOfParameterNamed("entity");
final String foreignKeyColumnName = EntityTables.getForeignKeyColumnNameOnDatatable(entity);
final boolean columnExist = datatableData.hasColumn(foreignKeyColumnName);
final String entity = command.stringValueOfParameterNamed("entity");
final String foreignKeyColumnName = EntityTables.getForeignKeyColumnNameOnDatatable(entity);
final boolean columnExist = datatableData.hasColumn(foreignKeyColumnName);
logger.info(datatableData.getRegisteredTableName() + "has column " + foreignKeyColumnName + " ? "
+ columnExist);
logger.info(datatableData.getRegisteredTableName() + "has column " + foreignKeyColumnName + " ? " + columnExist);
if (!columnExist) {
throw new EntityDatatableCheckNotSupportedException(datatableData.getRegisteredTableName(), entity);
}
if (!columnExist) { throw new EntityDatatableCheckNotSupportedException(datatableData.getRegisteredTableName(), entity); }
final Long productId = command.longValueOfParameterNamed("productId");
final Long status = command.longValueOfParameterNamed("status");
final Long productId = command.longValueOfParameterNamed("productId");
final Long status = command.longValueOfParameterNamed("status");
List<EntityDatatableChecks> entityDatatableCheck = null;
if (productId == null) {
entityDatatableCheck = this.entityDatatableChecksRepository.findByEntityStatusAndDatatableIdAndNoProduct(entity, status,
datatableName);
if (!entityDatatableCheck.isEmpty()) { throw new EntityDatatableCheckAlreadyExistsException(entity, status, datatableName); }
} else {
if (entity.equals("m_loan")) {
// if invalid loan product id, throws exception
this.loanProductReadPlatformService.retrieveLoanProduct(productId);
} else if (entity.equals("m_savings_account")) {
// if invalid savings product id, throws exception
this.savingsProductReadPlatformService.retrieveOne(productId);
} else {
throw new EntityDatatableCheckNotSupportedException(entity, productId);
}
entityDatatableCheck = this.entityDatatableChecksRepository.findByEntityStatusAndDatatableIdAndProductId(entity, status,
datatableName, productId);
if (!entityDatatableCheck.isEmpty()) { throw new EntityDatatableCheckAlreadyExistsException(entity, status, datatableName,
productId); }
}
List<EntityDatatableChecks> entityDatatableCheck = null;
if (productId == null) {
entityDatatableCheck = this.entityDatatableChecksRepository
.findByEntityStatusAndDatatableIdAndNoProduct(entity, status, datatableName);
if (!entityDatatableCheck.isEmpty()) {
throw new EntityDatatableCheckAlreadyExistsException(entity, status, datatableName);
}
} else {
if (entity.equals("m_loan")) {
// if invalid loan product id, throws exception
this.loanProductReadPlatformService.retrieveLoanProduct(productId);
} else if (entity.equals("m_savings_account")) {
// if invalid savings product id, throws exception
this.savingsProductReadPlatformService.retrieveOne(productId);
} else {
throw new EntityDatatableCheckNotSupportedException(entity, productId);
}
entityDatatableCheck = this.entityDatatableChecksRepository
.findByEntityStatusAndDatatableIdAndProductId(entity, status, datatableName, productId);
if (!entityDatatableCheck.isEmpty()) {
throw new EntityDatatableCheckAlreadyExistsException(entity, status, datatableName, productId);
}
}
final EntityDatatableChecks check = EntityDatatableChecks.fromJson(command);
final EntityDatatableChecks check = EntityDatatableChecks.fromJson(command);
this.entityDatatableChecksRepository.saveAndFlush(check);
this.entityDatatableChecksRepository.saveAndFlush(check);
return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) //
.withEntityId(check.getId()) //
.build();
} catch (final DataAccessException e) {
handleReportDataIntegrityIssues(command, e.getMostSpecificCause(), e);
return CommandProcessingResult.empty();
} catch (final PersistenceException dve) {
Throwable throwable = ExceptionUtils.getRootCause(dve.getCause());
handleReportDataIntegrityIssues(command, throwable, dve);
return CommandProcessingResult.empty();
}
}
return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) //
.withEntityId(check.getId()) //
.build();
} catch (final DataAccessException e) {
handleReportDataIntegrityIssues(command, e.getMostSpecificCause(), e);
return CommandProcessingResult.empty();
}catch (final PersistenceException dve) {
Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ;
handleReportDataIntegrityIssues(command, throwable, dve);
return CommandProcessingResult.empty();
}
}
@Override
public void runTheCheck(final Long entityId, final String entityName, final Long statusCode, String foreignKeyColumn) {
final List<EntityDatatableChecks> tableRequiredBeforeClientActivation = entityDatatableChecksRepository.findByEntityAndStatus(
entityName, statusCode);
public void runTheCheck(final Long entityId, final String entityName, final Long statusCode,
String foreignKeyColumn) {
final List<EntityDatatableChecks> tableRequiredBeforeClientActivation = entityDatatableChecksRepository
.findByEntityAndStatus(entityName, statusCode);
if (tableRequiredBeforeClientActivation != null) {
List<String> reqDatatables = new ArrayList<>();
for (EntityDatatableChecks t : tableRequiredBeforeClientActivation) {
if (tableRequiredBeforeClientActivation != null) {
List<String> reqDatatables = new ArrayList<>();
for (EntityDatatableChecks t : tableRequiredBeforeClientActivation) {
final String datatableName = t.getDatatableName();
final Long countEntries = readWriteNonCoreDataService.countDatatableEntries(datatableName, entityId, foreignKeyColumn);
final String datatableName = t.getDatatableName();
final Long countEntries = readWriteNonCoreDataService.countDatatableEntries(datatableName, entityId,
foreignKeyColumn);
logger.info("The are " + countEntries + " entries in the table " + datatableName);
if (countEntries.intValue() == 0) {
reqDatatables.add(datatableName);
}
}
if (reqDatatables.size() > 0) { throw new DatatableEntryRequiredException(reqDatatables.toString()); }
}
logger.info("The are " + countEntries + " entries in the table " + datatableName);
if (countEntries.intValue() == 0) {
reqDatatables.add(datatableName);
}
}
if(reqDatatables.size() > 0){
throw new DatatabaleEntryRequiredException(reqDatatables.toString());
}
}
}
}
@Override
public void runTheCheckForProduct(final Long entityId, final String entityName, final Long statusCode, String foreignKeyColumn,
long productId) {
List<EntityDatatableChecks> tableRequiredBeforAction = entityDatatableChecksRepository.findByEntityStatusAndProduct(entityName,
statusCode, productId);
public void runTheCheckForProduct(final Long entityId, final String entityName, final Long statusCode,
String foreignKeyColumn, long productId) {
List<EntityDatatableChecks> tableRequiredBeforAction = entityDatatableChecksRepository
.findByEntityStatusAndProduct(entityName, statusCode, productId);
if (tableRequiredBeforAction == null || tableRequiredBeforAction.size() < 1) {
tableRequiredBeforAction = entityDatatableChecksRepository.findByEntityStatusAndNoProduct(entityName, statusCode);
}
if (tableRequiredBeforAction != null) {
List<String> reqDatatables = new ArrayList<>();
for (EntityDatatableChecks t : tableRequiredBeforAction) {
if (tableRequiredBeforAction == null || tableRequiredBeforAction.size() < 1) {
tableRequiredBeforAction = entityDatatableChecksRepository.findByEntityStatusAndNoProduct(entityName,
statusCode);
}
if (tableRequiredBeforAction != null) {
List<String> reqDatatables = new ArrayList<>();
for (EntityDatatableChecks t : tableRequiredBeforAction) {
final String datatableName = t.getDatatableName();
final Long countEntries = readWriteNonCoreDataService.countDatatableEntries(datatableName, entityId, foreignKeyColumn);
final String datatableName = t.getDatatableName();
final Long countEntries = readWriteNonCoreDataService.countDatatableEntries(datatableName, entityId,
foreignKeyColumn);
logger.info("The are " + countEntries + " entries in the table " + datatableName);
if (countEntries.intValue() == 0) {
reqDatatables.add(datatableName);
}
}
if (reqDatatables.size() > 0) { throw new DatatableEntryRequiredException(reqDatatables.toString()); }
}
logger.info("The are " + countEntries + " entries in the table " + datatableName);
if (countEntries.intValue() == 0) {
reqDatatables.add(datatableName);
}
}
if(reqDatatables.size() > 0){
throw new DatatabaleEntryRequiredException(reqDatatables.toString());
}
}
}
}
@Transactional
@Override
public boolean saveDatatables(final Long status, final String entity, final Long entityId, final Long productId,
final JsonArray datatableDatas) {
final AppUser user = this.context.authenticatedUser();
boolean isMakerCheckerEnabled = false;
if (datatableDatas != null && datatableDatas.size() > 0) {
for (JsonElement element : datatableDatas) {
final String datatableName = this.fromApiJsonHelper.extractStringNamed("registeredTableName", element);
final JsonObject datatableData = this.fromApiJsonHelper.extractJsonObjectNamed("data", element);
@Transactional
@Override
public boolean saveDatatables(final Long status, final String entity, final Long entityId,
final Long productId, final JsonArray datatableDatas) {
final AppUser user = this.context.authenticatedUser();
boolean isMakerCheckerEnabled = false;
if(datatableDatas != null && datatableDatas.size() > 0){
for(JsonElement element : datatableDatas){
final String datatableName = this.fromApiJsonHelper.extractStringNamed("registeredTableName",element);
final JsonObject datatableData = this.fromApiJsonHelper.extractJsonObjectNamed("data", element);
if (datatableName == null || datatableData == null) {
final ApiParameterError error = ApiParameterError.generalError(
"registeredTableName.and.data.parameters.must.be.present.in.each.list.items.in.datatables",
"registeredTableName and data parameters must be present in each list items in datatables");
List<ApiParameterError> errors = new ArrayList<>();
errors.add(error);
throw new PlatformApiDataValidationException(errors);
}
final String taskPermissionName = "CREATE_" + datatableName;
user.validateHasPermissionTo(taskPermissionName);
if (this.configurationDomainService.isMakerCheckerEnabledForTask(taskPermissionName)) {
isMakerCheckerEnabled = true;
}
try {
this.readWriteNonCoreDataService.createNewDatatableEntry(datatableName, entityId, datatableData.toString());
} catch (PlatformApiDataValidationException e) {
List<ApiParameterError> errors = e.getErrors();
for (ApiParameterError error : e.getErrors()) {
error.setParameterName("datatables." + datatableName + "." + error.getParameterName());
}
throw e;
}
}
}
return isMakerCheckerEnabled;
}
if(datatableName == null || datatableData == null){
final ApiParameterError error = ApiParameterError.generalError("registeredTableName.and.data.parameters.must.be.present.in.each.list.items.in.datatables",
"registeredTableName and data parameters must be present in each list items in datatables");
List<ApiParameterError> errors = new ArrayList<>();
errors.add(error);
throw new PlatformApiDataValidationException(errors);
}
final String taskPermissionName = "CREATE_" + datatableName;
user.validateHasPermissionTo(taskPermissionName);
if(this.configurationDomainService.isMakerCheckerEnabledForTask(taskPermissionName)){
isMakerCheckerEnabled = true;
}
try{
this.readWriteNonCoreDataService.createNewDatatableEntry(datatableName, entityId, datatableData.toString());
} catch(PlatformApiDataValidationException e){
List<ApiParameterError> errors = e.getErrors();
for(ApiParameterError error : e.getErrors()){
error.setParameterName("datatables."+datatableName+"."+error.getParameterName());
}
throw e;
}
}
}
return isMakerCheckerEnabled;
}
private List<String> getDatatableNames(Long status, String entity, Long productId) {
List<String> ret = new ArrayList<>();
List<EntityDatatableChecks> tableRequiredBeforeAction = null;
if (productId != null) {
tableRequiredBeforeAction = this.entityDatatableChecksRepository.findByEntityStatusAndProduct(entity, status, productId);
}
private List<String> getDatatableNames(Long status, String entity, Long productId) {
List<String> ret = new ArrayList<>();
List<EntityDatatableChecks> tableRequiredBeforeAction = null;
if(productId != null){
tableRequiredBeforeAction = this.entityDatatableChecksRepository
.findByEntityStatusAndProduct(entity, status, productId);
}
if (tableRequiredBeforeAction == null || tableRequiredBeforeAction.size() < 1) {
tableRequiredBeforeAction = this.entityDatatableChecksRepository.findByEntityStatusAndNoProduct(entity, status);
}
if (tableRequiredBeforeAction != null && tableRequiredBeforeAction.size() > 0) {
for (EntityDatatableChecks t : tableRequiredBeforeAction) {
ret.add(t.getDatatableName());
}
}
return ret;
}
if (tableRequiredBeforeAction == null || tableRequiredBeforeAction.size() < 1) {
tableRequiredBeforeAction = this.entityDatatableChecksRepository.findByEntityStatusAndNoProduct(entity,
status);
}
if (tableRequiredBeforeAction != null && tableRequiredBeforeAction.size() > 0) {
for (EntityDatatableChecks t : tableRequiredBeforeAction) {
ret.add(t.getDatatableName());
}
}
return ret;
}
@Transactional
@Override
public CommandProcessingResult deleteCheck(final Long entityDatatableCheckId) {
@Transactional
@Override
public CommandProcessingResult deleteCheck(final Long entityDatatableCheckId) {
final EntityDatatableChecks check = this.entityDatatableChecksRepository.findOne(entityDatatableCheckId);
if (check == null) { throw new EntityDatatableChecksNotFoundException(entityDatatableCheckId); }
final EntityDatatableChecks check = this.entityDatatableChecksRepository.findOne(entityDatatableCheckId);
if (check == null) {
throw new EntityDatatableChecksNotFoundException(entityDatatableCheckId);
}
this.entityDatatableChecksRepository.delete(check);
this.entityDatatableChecksRepository.delete(check);
return new CommandProcessingResultBuilder() //
.withEntityId(entityDatatableCheckId) //
.build();
}
return new CommandProcessingResultBuilder() //
.withEntityId(entityDatatableCheckId) //
.build();
}
/*
* Guaranteed to throw an exception no matter what the data integrity issue
* is.
*/
private void handleReportDataIntegrityIssues(final JsonCommand command, final Throwable realCause, final Exception dae) {
/*
* Guaranteed to throw an exception no matter what the data integrity issue
* is.
*/
private void handleReportDataIntegrityIssues(final JsonCommand command, final Throwable realCause, final Exception dae) {
if (realCause.getMessage().contains("FOREIGN KEY (`x_registered_table_name`)")) {
final String datatableName = command.stringValueOfParameterNamed("datatableName");
throw new PlatformDataIntegrityException("error.msg.entityDatatableCheck.foreign.key.constraint", "datatable with name '"
+ datatableName + "' do not exist", "datatableName", datatableName);
}
if (realCause.getMessage().contains("FOREIGN KEY (`x_registered_table_name`)")) {
final String datatableName = command.stringValueOfParameterNamed("datatableName");
throw new PlatformDataIntegrityException("error.msg.entityDatatableCheck.foreign.key.constraint",
"datatable with name '" + datatableName + "' do not exist", "datatableName", datatableName);
}
if (realCause.getMessage().contains("unique_entity_check")) {
final String datatableName = command.stringValueOfParameterNamed("datatableName");
final long status = command.longValueOfParameterNamed("status");
final String entity = command.stringValueOfParameterNamed("entity");
final long productId = command.longValueOfParameterNamed("productId");
throw new EntityDatatableCheckAlreadyExistsException(entity, status, datatableName, productId);
}
if (realCause.getMessage().contains("unique_entity_check")) {
final String datatableName = command.stringValueOfParameterNamed("datatableName");
final long status = command.longValueOfParameterNamed("status");
final String entity = command.stringValueOfParameterNamed("entity");
final long productId = command.longValueOfParameterNamed("productId");
throw new EntityDatatableCheckAlreadyExistsException(entity, status, datatableName, productId);
}
logger.error(dae.getMessage(), dae);
throw new PlatformDataIntegrityException("error.msg.report.unknown.data.integrity.issue",
"Unknown data integrity issue with resource: " + realCause.getMessage());
}
logger.error(dae.getMessage(), dae);
throw new PlatformDataIntegrityException("error.msg.report.unknown.data.integrity.issue",
"Unknown data integrity issue with resource: " + realCause.getMessage());
}
}
@@ -45,6 +45,7 @@ import org.apache.fineract.infrastructure.core.serialization.JsonParserHelper;
import org.apache.fineract.infrastructure.core.service.RoutingDataSource;
import org.apache.fineract.infrastructure.dataqueries.api.DataTableApiConstant;
import org.apache.fineract.infrastructure.dataqueries.data.*;
import org.apache.fineract.infrastructure.dataqueries.exception.DatatableEntryRequiredException;
import org.apache.fineract.infrastructure.dataqueries.exception.DatatableNotFoundException;
import org.apache.fineract.infrastructure.dataqueries.exception.DatatableSystemErrorException;
import org.apache.fineract.infrastructure.security.service.PlatformSecurityContext;
@@ -1121,9 +1122,9 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
@Override
public CommandProcessingResult deleteDatatableEntries(final String dataTableName, final Long appTableId) {
if (isDatatableAttachedToEntityDatatableCheck(dataTableName)) { throw new DatatableEntryRequiredException(dataTableName, appTableId); }
final String appTable = queryForApplicationTableName(dataTableName);
final CommandProcessingResult commandProcessingResult = checkMainResourceExistsWithinScope(appTable, appTableId);
final String deleteOneToOneEntrySql = getDeleteEntriesSql(dataTableName, getFKField(appTable), appTableId);
final int rowsDeleted = this.jdbcTemplate.update(deleteOneToOneEntrySql);
@@ -1135,7 +1136,7 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
@Transactional
@Override
public CommandProcessingResult deleteDatatableEntry(final String dataTableName, final Long appTableId, final Long datatableId) {
if (isDatatableAttachedToEntityDatatableCheck(dataTableName)) { throw new DatatableEntryRequiredException(dataTableName, appTableId); }
final String appTable = queryForApplicationTableName(dataTableName);
final CommandProcessingResult commandProcessingResult = checkMainResourceExistsWithinScope(appTable, appTableId);
@@ -1730,4 +1731,13 @@ public class ReadWriteNonCoreDataServiceImpl implements ReadWriteNonCoreDataServ
return count;
}
public boolean isDatatableAttachedToEntityDatatableCheck(final String datatableName) {
StringBuilder builder = new StringBuilder();
builder.append(" SELECT COUNT(edc.`x_registered_table_name`) FROM `x_registered_table` xrt ");
builder.append(" JOIN m_entity_datatable_check edc ON edc.`x_registered_table_name` = xrt.`registered_table_name`");
builder.append(" WHERE edc.`x_registered_table_name` = '" + datatableName + "'");
final Long count = this.jdbcTemplate.queryForObject(builder.toString(), Long.class);
return (count > 0) ? true : false;
}
}
@@ -74,6 +74,10 @@ public class ClientRepositoryWrapper {
public void delete(final Client client) {
this.repository.delete(client);
}
public void flush() {
this.repository.flush();
}
public Client getActiveClientInUserScope(Long clientId) {
final Client client = this.findOneWithNotFoundDetection(clientId);
@@ -18,7 +18,11 @@
*/
package org.apache.fineract.portfolio.client.service;
import java.util.*;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import javax.persistence.PersistenceException;
@@ -50,8 +54,18 @@ import org.apache.fineract.organisation.staff.domain.StaffRepositoryWrapper;
import org.apache.fineract.portfolio.address.service.AddressWritePlatformService;
import org.apache.fineract.portfolio.client.api.ClientApiConstants;
import org.apache.fineract.portfolio.client.data.ClientDataValidator;
import org.apache.fineract.portfolio.client.domain.*;
import org.apache.fineract.portfolio.client.exception.*;
import org.apache.fineract.portfolio.client.domain.AccountNumberGenerator;
import org.apache.fineract.portfolio.client.domain.Client;
import org.apache.fineract.portfolio.client.domain.ClientNonPerson;
import org.apache.fineract.portfolio.client.domain.ClientNonPersonRepositoryWrapper;
import org.apache.fineract.portfolio.client.domain.ClientRepositoryWrapper;
import org.apache.fineract.portfolio.client.domain.ClientStatus;
import org.apache.fineract.portfolio.client.domain.LegalForm;
import org.apache.fineract.portfolio.client.exception.ClientActiveForUpdateException;
import org.apache.fineract.portfolio.client.exception.ClientHasNoStaffException;
import org.apache.fineract.portfolio.client.exception.ClientMustBePendingToBeDeletedException;
import org.apache.fineract.portfolio.client.exception.InvalidClientSavingProductException;
import org.apache.fineract.portfolio.client.exception.InvalidClientStateTransitionException;
import org.apache.fineract.portfolio.common.BusinessEventNotificationConstants.BUSINESS_ENTITY;
import org.apache.fineract.portfolio.common.BusinessEventNotificationConstants.BUSINESS_EVENTS;
import org.apache.fineract.portfolio.common.service.BusinessEventNotifierService;
@@ -151,23 +165,29 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
@Transactional
@Override
public CommandProcessingResult deleteClient(final Long clientId) {
try {
final Client client = this.clientRepository.findOneWithNotFoundDetection(clientId);
final Client client = this.clientRepository.findOneWithNotFoundDetection(clientId);
if (client.isNotPending()) { throw new ClientMustBePendingToBeDeletedException(clientId); }
final List<Note> relatedNotes = this.noteRepository.findByClientId(clientId);
this.noteRepository.deleteInBatch(relatedNotes);
if (client.isNotPending()) { throw new ClientMustBePendingToBeDeletedException(clientId); }
final List<Note> relatedNotes = this.noteRepository.findByClientId(clientId);
this.noteRepository.deleteInBatch(relatedNotes);
final ClientNonPerson clientNonPerson = this.clientNonPersonRepository.findOneByClientId(clientId);
if (clientNonPerson != null) this.clientNonPersonRepository.delete(clientNonPerson);
final ClientNonPerson clientNonPerson = this.clientNonPersonRepository.findOneByClientId(clientId);
if(clientNonPerson != null)
this.clientNonPersonRepository.delete(clientNonPerson);
this.clientRepository.delete(client);
return new CommandProcessingResultBuilder() //
.withOfficeId(client.officeId()) //
.withClientId(clientId) //
.withEntityId(clientId) //
.build();
this.clientRepository.delete(client);
this.clientRepository.flush();
return new CommandProcessingResultBuilder() //
.withOfficeId(client.officeId()) //
.withClientId(clientId) //
.withEntityId(clientId) //
.build();
} catch (DataIntegrityViolationException dve) {
Throwable throwable = ExceptionUtils.getRootCause(dve.getCause()) ;
logger.error(throwable.getMessage());
throw new PlatformDataIntegrityException("error.msg.client.unknown.data.integrity.issue",
"Unknown data integrity issue with resource.");
}
}
/*
@@ -270,9 +290,11 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
final Client newClient = Client.createNew(currentUser, clientOffice, clientParentGroup, staff, savingsProductId, gender,
clientType, clientClassification, legalFormValue, command);
this.clientRepository.save(newClient);
boolean rollbackTransaction = false;
if (newClient.isActive()) {
validateParentGroupRulesBeforeClientActivation(newClient);
runEntityDatatableCheck(newClient.getId());
final CommandWrapper commandWrapper = new CommandWrapperBuilder().activateClient(null).build();
rollbackTransaction = this.commandProcessingService.validateCommand(commandWrapper, currentUser);
}
@@ -533,8 +555,7 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
final DateTimeFormatter fmt = DateTimeFormat.forPattern(command.dateFormat()).withLocale(locale);
final LocalDate activationDate = command.localDateValueOfParameterNamed("activationDate");
entityDatatableChecksWritePlatformService.runTheCheck(clientId, EntityTables.CLIENT.getName(),
StatusEnum.ACTIVATE.getCode().longValue(), EntityTables.CLIENT.getForeignKeyColumnNameOnDatatable());
runEntityDatatableCheck(clientId);
final AppUser currentUser = this.context.authenticatedUser();
client.activate(currentUser, fmt, activationDate);
@@ -766,6 +787,11 @@ public class ClientWritePlatformServiceJpaRepositoryImpl implements ClientWriteP
}
}
private void runEntityDatatableCheck(final Long clientId) {
entityDatatableChecksWritePlatformService.runTheCheck(clientId, EntityTables.CLIENT.getName(), StatusEnum.ACTIVATE.getCode()
.longValue(), EntityTables.CLIENT.getForeignKeyColumnNameOnDatatable());
}
@Override
public CommandProcessingResult rejectClient(final Long entityId, final JsonCommand command) {
final AppUser currentUser = this.context.authenticatedUser();
@@ -62,4 +62,8 @@ public class GroupRepositoryWrapper {
public void delete(final Group entity) {
this.repository.delete(entity);
}
public void flush() {
this.repository.flush();
}
}
@@ -174,6 +174,7 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
boolean rollbackTransaction = false;
if (newGroup.isActive()) {
this.groupRepository.save(newGroup);
// validate Group creation rules for Group
if (newGroup.isGroup()) {
validateGroupRulesBeforeActivation(newGroup);
@@ -295,9 +296,6 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
validateOfficeOpeningDateisAfterGroupOrCenterOpeningDate(group.getOffice(), group.getGroupLevel(), activationDate);
entityDatatableChecksWritePlatformService.runTheCheck(groupId, EntityTables.GROUP.getName(),
StatusEnum.ACTIVATE.getCode().longValue(), EntityTables.GROUP.getForeignKeyColumnNameOnDatatable());
group.activate(currentUser, activationDate);
this.groupRepository.saveAndFlush(group);
@@ -323,6 +321,8 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
Integer maxClients = configurationDomainService.retrieveMaxAllowedClientsInGroup();
boolean isGroupClientCountValid = group.isGroupsClientCountWithinMinMaxRange(minClients, maxClients);
if (!isGroupClientCountValid) { throw new GroupMemberCountNotInPermissibleRangeException(group.getId(), minClients, maxClients); }
entityDatatableChecksWritePlatformService.runTheCheck(group.getId(), EntityTables.GROUP.getName(),
StatusEnum.ACTIVATE.getCode().longValue(), EntityTables.GROUP.getForeignKeyColumnNameOnDatatable());
}
public void validateGroupRulesBeforeClientAssociation(final Group group) {
@@ -549,21 +549,28 @@ public class GroupingTypesWritePlatformServiceJpaRepositoryImpl implements Group
@Transactional
@Override
public CommandProcessingResult deleteGroup(final Long groupId) {
try {
final Group groupForDelete = this.groupRepository.findOneWithNotFoundDetection(groupId);
final Group groupForDelete = this.groupRepository.findOneWithNotFoundDetection(groupId);
if (groupForDelete.isNotPending()) { throw new GroupMustBePendingToBeDeletedException(groupId); }
if (groupForDelete.isNotPending()) { throw new GroupMustBePendingToBeDeletedException(groupId); }
final List<Note> relatedNotes = this.noteRepository.findByGroupId(groupId);
this.noteRepository.deleteInBatch(relatedNotes);
final List<Note> relatedNotes = this.noteRepository.findByGroupId(groupId);
this.noteRepository.deleteInBatch(relatedNotes);
this.groupRepository.delete(groupForDelete);
return new CommandProcessingResultBuilder() //
.withOfficeId(groupForDelete.getId()) //
.withGroupId(groupForDelete.officeId()) //
.withEntityId(groupForDelete.getId()) //
.build();
this.groupRepository.delete(groupForDelete);
this.groupRepository.flush();
return new CommandProcessingResultBuilder() //
.withOfficeId(groupForDelete.getId()) //
.withGroupId(groupForDelete.officeId()) //
.withEntityId(groupForDelete.getId()) //
.build();
} catch (DataIntegrityViolationException dve) {
Throwable throwable = ExceptionUtils.getRootCause(dve.getCause());
logger.error(throwable.getMessage());
throw new PlatformDataIntegrityException("error.msg.group.unknown.data.integrity.issue",
"Unknown data integrity issue with resource.");
}
}
@Override
@@ -268,7 +268,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
final Date rescheduledRepaymentDate = command.DateValueOfParameterNamed("adjustRepaymentDate");
entityDatatableChecksWritePlatformService.runTheCheckForProduct(loanId, EntityTables.LOAN.getName(),
StatusEnum.ACTIVATE.getCode().longValue(), EntityTables.LOAN.getForeignKeyColumnNameOnDatatable(), loan.productId());
StatusEnum.DISBURSE.getCode().longValue(), EntityTables.LOAN.getForeignKeyColumnNameOnDatatable(), loan.productId());
// check for product mix validations
checkForProductMixRestrictions(loan);