Merge pull request #170 from Kitzanos/custom-table-validation
GEPAFINBE-86 & GEPAFINBE-103 custom table validation
This commit is contained in:
@@ -386,6 +386,8 @@ public class GepafinConstant {
|
|||||||
public static final String COUNT="count";
|
public static final String COUNT="count";
|
||||||
public static final String APPLICATION_PER_CALL="applicationPerCall";
|
public static final String APPLICATION_PER_CALL="applicationPerCall";
|
||||||
public static final String APPLICATION_PER_STATUS="applicationPerStatus";
|
public static final String APPLICATION_PER_STATUS="applicationPerStatus";
|
||||||
|
public static final String NON_EMPTY_TABLES="nonEmptyTables";
|
||||||
|
public static final String VALIDATION_IN_TABLE = "validation.table.message";
|
||||||
public static final String CALL_EXPIRED="call.expired";
|
public static final String CALL_EXPIRED="call.expired";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,13 +55,13 @@ public class FormDao {
|
|||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private CallRepository callRepository;
|
private CallRepository callRepository;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private Validator validator;
|
private Validator validator;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private CriteriaFormFieldRepository criteriaFormFieldRepository;
|
private CriteriaFormFieldRepository criteriaFormFieldRepository;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private EvaluationCriteriaService evaluationCriteriaService;
|
private EvaluationCriteriaService evaluationCriteriaService;
|
||||||
|
|
||||||
@@ -144,7 +144,7 @@ public class FormDao {
|
|||||||
validateAndSaveCriteriaFormField(callEntity, formEntity, formRequest.getContent());
|
validateAndSaveCriteriaFormField(callEntity, formEntity, formRequest.getContent());
|
||||||
return convertFormEntityToFormResponseBean(formEntity);
|
return convertFormEntityToFormResponseBean(formEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateAndSaveCriteriaFormField(CallEntity callEntity, FormEntity formEntity,
|
private void validateAndSaveCriteriaFormField(CallEntity callEntity, FormEntity formEntity,
|
||||||
List<ContentRequestBean> contentResponseBeans) {
|
List<ContentRequestBean> contentResponseBeans) {
|
||||||
|
|
||||||
@@ -211,7 +211,7 @@ public class FormDao {
|
|||||||
|
|
||||||
/** This code is responsible for adding a version history log for the "creating criteria form field" operation. **/
|
/** This code is responsible for adding a version history log for the "creating criteria form field" operation. **/
|
||||||
loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(null).newData(criteriaFormField).build());
|
loggingUtil.addVersionHistory(VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.INSERT).oldData(null).newData(criteriaFormField).build());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void validateForm(FormRequest formRequest){
|
public void validateForm(FormRequest formRequest){
|
||||||
@@ -397,9 +397,9 @@ public class FormDao {
|
|||||||
FieldValidator validator = FieldValidator.create();
|
FieldValidator validator = FieldValidator.create();
|
||||||
formResponseBean.getContent().forEach(contentResponseBean -> {
|
formResponseBean.getContent().forEach(contentResponseBean -> {
|
||||||
String fieldId = contentResponseBean.getId();
|
String fieldId = contentResponseBean.getId();
|
||||||
String value = (String) formFieldMap.get(fieldId);
|
|
||||||
String fieldLabel=contentResponseBean.getLabel();
|
String fieldLabel=contentResponseBean.getLabel();
|
||||||
|
Object object=formFieldMap.get(fieldId);
|
||||||
|
String value =Utils.convertToString(object);
|
||||||
if(value == null && isApplicationFormExist) {
|
if(value == null && isApplicationFormExist) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -408,7 +408,7 @@ public class FormDao {
|
|||||||
.minLength(value, fieldValidatorBean.getMinLength(), fieldLabel) // Only applies if minLength is not null
|
.minLength(value, fieldValidatorBean.getMinLength(), fieldLabel) // Only applies if minLength is not null
|
||||||
.maxLength(value, fieldValidatorBean.getMaxLength(), fieldLabel) // Only applies if maxLength is not null
|
.maxLength(value, fieldValidatorBean.getMaxLength(), fieldLabel) // Only applies if maxLength is not null
|
||||||
.matchesPattern(value, fieldValidatorBean.getPattern(), fieldLabel) // Only applies if pattern is present
|
.matchesPattern(value, fieldValidatorBean.getPattern(), fieldLabel) // Only applies if pattern is present
|
||||||
.validateCustom(value, fieldValidatorBean.getCustom(), fieldLabel); // Add the custom validation here
|
.validateCustom(value, fieldValidatorBean.getCustom(), fieldLabel,contentResponseBean); // Add the custom validation here
|
||||||
if (fieldValidatorBean.getCustom() != null && fieldValidatorBean.getCustom().equals(GepafinConstant.IS_PIVA)) {
|
if (fieldValidatorBean.getCustom() != null && fieldValidatorBean.getCustom().equals(GepafinConstant.IS_PIVA)) {
|
||||||
String error = validateVatNumber(value, fieldValidatorBean.getCustom(), fieldLabel);
|
String error = validateVatNumber(value, fieldValidatorBean.getCustom(), fieldLabel);
|
||||||
if(error != null) {
|
if(error != null) {
|
||||||
@@ -428,11 +428,14 @@ public class FormDao {
|
|||||||
for (Object value : list) {
|
for (Object value : list) {
|
||||||
setFormFieldMap(fieldId, formFieldMap, value);
|
setFormFieldMap(fieldId, formFieldMap, value);
|
||||||
}
|
}
|
||||||
}
|
}else if (list.stream().allMatch(item -> item instanceof Map<?, ?> map &&
|
||||||
|
map.keySet().stream().allMatch(String.class::isInstance))) {
|
||||||
|
if (fieldValue != null) {
|
||||||
|
formFieldMap.put(fieldId, fieldValue);
|
||||||
|
}
|
||||||
|
} else setFormFieldMap(fieldId, formFieldMap, fieldValue);
|
||||||
}
|
}
|
||||||
else setFormFieldMap(fieldId, formFieldMap, fieldValue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setFormFieldMap(String fieldId, Map<String, Object> formFieldMap, Object value) {
|
private void setFormFieldMap(String fieldId, Map<String, Object> formFieldMap, Object value) {
|
||||||
if (value instanceof String) {
|
if (value instanceof String) {
|
||||||
if(value !=null && Boolean.FALSE.equals(StringUtils.isEmpty((String)value))) {
|
if(value !=null && Boolean.FALSE.equals(StringUtils.isEmpty((String)value))) {
|
||||||
@@ -453,7 +456,7 @@ public class FormDao {
|
|||||||
for(ApplicationFormFieldEntity applicationFormFieldEntity:applicationFormFieldEntityList) {
|
for(ApplicationFormFieldEntity applicationFormFieldEntity:applicationFormFieldEntityList) {
|
||||||
formFieldMap.put(applicationFormFieldEntity.getFieldId(),applicationFormFieldEntity.getFieldValue());
|
formFieldMap.put(applicationFormFieldEntity.getFieldId(),applicationFormFieldEntity.getFieldValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
FormResponseBean formResponseBean = convertFormEntityToFormResponseBean(formEntity);
|
FormResponseBean formResponseBean = convertFormEntityToFormResponseBean(formEntity);
|
||||||
FieldValidator validator = FieldValidator.create();
|
FieldValidator validator = FieldValidator.create();
|
||||||
formResponseBean.getContent().forEach(contentResponseBean -> {
|
formResponseBean.getContent().forEach(contentResponseBean -> {
|
||||||
@@ -462,10 +465,11 @@ public class FormDao {
|
|||||||
|
|
||||||
FieldValidatorBean fieldValidatorBean = Utils.convertSourceObjectToDestinationObject(contentResponseBean.getValidators(), FieldValidatorBean.class);
|
FieldValidatorBean fieldValidatorBean = Utils.convertSourceObjectToDestinationObject(contentResponseBean.getValidators(), FieldValidatorBean.class);
|
||||||
validator
|
validator
|
||||||
.isRequired(value,fieldValidatorBean.getIsRequired(),fieldId);
|
.isRequired(value,fieldValidatorBean.getIsRequired(),contentResponseBean.getLabel());
|
||||||
});
|
});
|
||||||
|
validator.validate();
|
||||||
if (validator.hasErrors()) {
|
if (validator.hasErrors()) {
|
||||||
return false; // Validation failed, return false
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,20 @@
|
|||||||
package net.gepafin.tendermanagement.util;
|
package net.gepafin.tendermanagement.util;
|
||||||
|
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import net.gepafin.tendermanagement.config.Translator;
|
import net.gepafin.tendermanagement.config.Translator;
|
||||||
import net.gepafin.tendermanagement.constants.GepafinConstant;
|
import net.gepafin.tendermanagement.constants.GepafinConstant;
|
||||||
import net.gepafin.tendermanagement.dao.FormDao;
|
import net.gepafin.tendermanagement.dao.FormDao;
|
||||||
import net.gepafin.tendermanagement.dao.VatCheckDao;
|
import net.gepafin.tendermanagement.dao.VatCheckDao;
|
||||||
|
import net.gepafin.tendermanagement.model.request.ContentRequestBean;
|
||||||
|
import net.gepafin.tendermanagement.model.response.ContentResponseBean;
|
||||||
|
import net.gepafin.tendermanagement.model.response.SettingResponseBean;
|
||||||
import net.gepafin.tendermanagement.web.rest.api.errors.Status;
|
import net.gepafin.tendermanagement.web.rest.api.errors.Status;
|
||||||
import net.gepafin.tendermanagement.web.rest.api.errors.ValidationException;
|
import net.gepafin.tendermanagement.web.rest.api.errors.ValidationException;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
@@ -75,7 +78,7 @@ public class FieldValidator {
|
|||||||
return value == null || value == 0L;
|
return value == null || value == 0L;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FieldValidator validateCustom(String value, String customRule, String fieldId) {
|
public FieldValidator validateCustom(String value, String customRule, String fieldId, ContentResponseBean contentResponseBean) {
|
||||||
if (customRule == null || value == null) {
|
if (customRule == null || value == null) {
|
||||||
return this; // No custom rule to validate
|
return this; // No custom rule to validate
|
||||||
}
|
}
|
||||||
@@ -131,6 +134,10 @@ public class FieldValidator {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GepafinConstant.NON_EMPTY_TABLES:
|
||||||
|
checkTableValidation(value, fieldId, contentResponseBean, errors);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// If the custom rule is unknown, just log or add an error (optional)
|
// If the custom rule is unknown, just log or add an error (optional)
|
||||||
errors.add(MessageFormat.format(Translator.toLocale(GepafinConstant.VALIDATION_FIELD_CUSTOM), fieldId, customRule));
|
errors.add(MessageFormat.format(Translator.toLocale(GepafinConstant.VALIDATION_FIELD_CUSTOM), fieldId, customRule));
|
||||||
@@ -139,6 +146,70 @@ public class FieldValidator {
|
|||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void checkTableValidation(String value, String fieldId, ContentResponseBean contentResponseBean, List<String> errors) {
|
||||||
|
Map<String, Boolean> stateFieldMap= new HashMap<>();
|
||||||
|
|
||||||
|
contentResponseBean.getSettings().stream()
|
||||||
|
.filter(setting -> "table_columns".equals(setting.getName())) // Check for "table_columns"
|
||||||
|
.map(SettingResponseBean::getValue)
|
||||||
|
.filter(Objects::nonNull) // Ensure value is not null
|
||||||
|
.filter(settingValue -> settingValue instanceof Map) // Ensure value is a Map
|
||||||
|
.map(settingValue -> (Map<String, Object>) settingValue) // Cast to Map
|
||||||
|
.map(valueMap -> (List<Map<String, Object>>) valueMap.get("stateFieldData")) // Extract stateFieldData list
|
||||||
|
.filter(Objects::nonNull) // Ensure stateFieldData is not null
|
||||||
|
.flatMap(List::stream) // Flatten the list of field data maps
|
||||||
|
.forEach(fieldData -> {
|
||||||
|
String fieldName = (String) fieldData.get("name"); // Get the name field
|
||||||
|
Boolean isPredefined = (Boolean) fieldData.get("predefined"); // Get the predefined field
|
||||||
|
|
||||||
|
if (fieldName != null && isPredefined != null) {
|
||||||
|
stateFieldMap.put(fieldName, isPredefined);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
List<Map<String, Object>> fieldValueList = Utils.convertJsonStringIntoJsonList(value);
|
||||||
|
|
||||||
|
if (fieldValueList == null || fieldValueList.isEmpty()) {
|
||||||
|
errors.add(MessageFormat.format(
|
||||||
|
Translator.toLocale(GepafinConstant.VALIDATION_IN_TABLE),
|
||||||
|
fieldId));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int rowIndex = 0; rowIndex < fieldValueList.size(); rowIndex++) {
|
||||||
|
Map<String, Object> field = fieldValueList.get(rowIndex);
|
||||||
|
|
||||||
|
boolean hasSingleNonNullPredefinedFalse = false;
|
||||||
|
|
||||||
|
for (Map.Entry<String, Boolean> entry : stateFieldMap.entrySet()) {
|
||||||
|
String stateKey = entry.getKey();
|
||||||
|
Boolean isPredefinedFalse = Boolean.FALSE.equals(entry.getValue());
|
||||||
|
|
||||||
|
if (isPredefinedFalse) {
|
||||||
|
Object fieldValue = field.get(stateKey);
|
||||||
|
if (fieldValue != null && !StringUtils.isEmpty(fieldValue.toString())) {
|
||||||
|
hasSingleNonNullPredefinedFalse = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasSingleNonNullPredefinedFalse) {
|
||||||
|
errors.add(MessageFormat.format(
|
||||||
|
Translator.toLocale(GepafinConstant.VALIDATION_IN_TABLE),
|
||||||
|
fieldId));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public FieldValidator isRequired(String value,Boolean isRequired, String fieldName) {
|
public FieldValidator isRequired(String value,Boolean isRequired, String fieldName) {
|
||||||
if (Boolean.TRUE.equals(isRequired)) { // Only check if isRequired is true
|
if (Boolean.TRUE.equals(isRequired)) { // Only check if isRequired is true
|
||||||
if (Objects.isNull(value) || value.isEmpty()) { // Check if value is null or empty
|
if (Objects.isNull(value) || value.isEmpty()) { // Check if value is null or empty
|
||||||
@@ -150,4 +221,16 @@ public class FieldValidator {
|
|||||||
public boolean hasErrors() {
|
public boolean hasErrors() {
|
||||||
return !errors.isEmpty();
|
return !errors.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public ContentRequestBean getContentRequestBeanFromJson(String jsonString) throws JsonProcessingException {
|
||||||
|
ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
|
||||||
|
// Parse the JSON into a ContentRequestBean
|
||||||
|
ContentRequestBean contentRequestBean = objectMapper.readValue(jsonString, ContentRequestBean.class);
|
||||||
|
|
||||||
|
// Now contentRequestBean is populated with the data from the JSON
|
||||||
|
return contentRequestBean;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ invalid.status.change.from.draft=Status cannot be changed to READY_TO_PUBLISH or
|
|||||||
status.cannot.be.changed=Status cannot be changed.
|
status.cannot.be.changed=Status cannot be changed.
|
||||||
published.call.not.update=Published call cannot be updated.
|
published.call.not.update=Published call cannot be updated.
|
||||||
invalid.status.change.from.publish=Status cannot be changed to READY_TO_PUBLISH or DRAFT from PUBLISH.
|
invalid.status.change.from.publish=Status cannot be changed to READY_TO_PUBLISH or DRAFT from PUBLISH.
|
||||||
|
validation.table.message=Data for field {0} is not present.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -341,4 +341,5 @@ user.with.company.not.found = Utente con azienda non trovato per utente o aziend
|
|||||||
user.action.fetched.successfully = Dettagli sull'azione dell'utente recuperati correttamente.
|
user.action.fetched.successfully = Dettagli sull'azione dell'utente recuperati correttamente.
|
||||||
action.context.labels.fetched.successfully = Etichette del contesto dell'azione recuperate correttamente.
|
action.context.labels.fetched.successfully = Etichette del contesto dell'azione recuperate correttamente.
|
||||||
amount.accepted.required=L'importo accettato <20> obbligatorio durante l'approvazione della domanda.
|
amount.accepted.required=L'importo accettato <20> obbligatorio durante l'approvazione della domanda.
|
||||||
call.expired=La chiamata è scaduta.
|
validation.table.message=I dati per il campo {0} non sono presenti.
|
||||||
|
call.expired=La chiamata <20> scaduta.
|
||||||
|
|||||||
Reference in New Issue
Block a user