package net.gepafin.tendermanagement.util; import java.text.MessageFormat; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import net.gepafin.tendermanagement.config.Translator; import net.gepafin.tendermanagement.constants.GepafinConstant; import net.gepafin.tendermanagement.dao.FormDao; import net.gepafin.tendermanagement.dao.VatCheckDao; import net.gepafin.tendermanagement.entities.ApplicationFormEntity; import net.gepafin.tendermanagement.entities.ApplicationFormFieldEntity; import net.gepafin.tendermanagement.model.request.ApplicationFormFieldRequestBean; 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.repositories.ApplicationFormFieldRepository; import net.gepafin.tendermanagement.web.rest.api.errors.CustomValidationException; import net.gepafin.tendermanagement.web.rest.api.errors.Status; import net.gepafin.tendermanagement.web.rest.api.errors.ValidationException; import org.apache.commons.lang3.StringUtils; import org.json.JSONObject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.CollectionUtils; public class FieldValidator { private final List errors = new ArrayList<>(); public static FieldValidator create() { return new FieldValidator(); } @Autowired private VatCheckDao vatCheckDao; public FieldValidator notNull(Object object, String fieldLabel) { if (Objects.isNull(object)) { errors.add(MessageFormat.format(Translator.toLocale(GepafinConstant.FIELD_NOT_NULL), fieldLabel)); } return this; } public FieldValidator notEmpty(List list, String fieldLabel) { if (list == null || list.isEmpty()) { errors.add(MessageFormat.format(Translator.toLocale(GepafinConstant.FIELD_NOT_EMPTY), fieldLabel)); } return this; } public void validate() { if (!errors.isEmpty()) { throw new ValidationException(Status.VALIDATION_ERROR, errors, Translator.toLocale(GepafinConstant.VALIDATION_MESSAGE)); } } public FieldValidator minLength(String value, Long minLength, String fieldLabel) { if (minLength != null && value != null && value.length() < minLength) { errors.add(MessageFormat.format(Translator.toLocale(GepafinConstant.VALIDATION_FIELD_MIN_LENGTH), fieldLabel, minLength)); } return this; } public FieldValidator maxLength(String value, Long maxLength, String fieldLabel) { if (maxLength != null && value != null && value.length() > maxLength) { errors.add(MessageFormat.format(Translator.toLocale(GepafinConstant.VALIDATION_FIELD_MAX_LENGTH), fieldLabel, maxLength)); } return this; } public FieldValidator matchesPattern(String value, String pattern, String fieldLabel) { if (value != null && pattern != null && !value.matches(pattern)) { errors.add(MessageFormat.format(Translator.toLocale(GepafinConstant.VALIDATION_FIELD_PATTERN), fieldLabel)); } return this; } public FieldValidator addError( String errorMessage) { errors.add(errorMessage); return this; } public static boolean isNullOrZero(Long value) { return value == null || value == 0L; } public FieldValidator validateCustom(String value, String customRule, String fieldId, ContentResponseBean contentResponseBean) { if (customRule == null || value == null) { return this; // No custom rule to validate } switch (customRule) { case GepafinConstant.IS_PIVA: // VAT number: max 11 digits, can start with 0 if (!value.matches("^\\d{1,11}$")) { errors.add(MessageFormat.format(Translator.toLocale(GepafinConstant.VALIDATION_PIVA), fieldId, customRule)); } break; case GepafinConstant.IS_CODICE_FISCALE: // 16 characters: 6 letters, 2 digits, 1 letter, 2 digits, 1 letter, 3 digits, 1 letter if (!value.matches("^[A-Z]{6}[0-9]{2}[A-Z]{1}[0-9]{2}[A-Z]{1}[0-9]{3}[A-Z]{1}$")) { errors.add(MessageFormat.format(Translator.toLocale(GepafinConstant.VALIDATION_CODICE_FISCALE), fieldId, customRule)); } break; case GepafinConstant.IS_CAP: // 5 digits (can start with 0) if (!value.matches("^[0-9]{5}$")) { errors.add(MessageFormat.format(Translator.toLocale(GepafinConstant.VALIDATION_CAP), fieldId, customRule)); } break; case GepafinConstant.IS_IBAN: // IBAN must be 27 characters if (value.length() != 27) { errors.add(MessageFormat.format(Translator.toLocale(GepafinConstant.VALIDATION_IBAN), fieldId, customRule)); } break; case GepafinConstant.IS_EMAIL: case GepafinConstant.IS_EMAIL_PEC: // Email validation (using a simple regex for email) if (!value.matches("^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+$")) { errors.add(MessageFormat.format(Translator.toLocale(GepafinConstant.VALIDATION_EMAIL), fieldId, customRule)); } break; case GepafinConstant.IS_URL: // URL validation (simple regex for URL) if (!value.matches("^(https?|ftp)://[^\s/$.?#].[^\s]*$")) { errors.add(MessageFormat.format(Translator.toLocale(GepafinConstant.VALIDATION_URL), fieldId, customRule)); } break; case GepafinConstant.IS_MARCA_DA_BOLLO: // Length must be 14 digits (can start with 0) if (!value.matches("^[0-9]{14}$")) { errors.add(MessageFormat.format(Translator.toLocale(GepafinConstant.VALIDATION_MARCA_DA_BOLLO), fieldId, customRule)); } break; case GepafinConstant.NON_EMPTY_TABLES: // checkTableValidation(value, fieldId, contentResponseBean, errors); break; default: // 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)); break; } return this; } public FieldValidator validateCustomTableValidation(String value, String customRule, String fieldId, ContentResponseBean contentResponseBean) { if (customRule == null ) { return this; // No custom rule to validate } switch (customRule) { case GepafinConstant.NON_EMPTY_TABLES: try { checkTableValidation(value, fieldId, contentResponseBean, errors); } catch (Exception e) { throw new RuntimeException(e); } break; } return this; } private static void checkTableValidation(String value, String fieldId, ContentResponseBean contentResponseBean, List errors) throws Exception { Map stateFieldMap= new HashMap<>(); String tableType = contentResponseBean.getSettings().stream() .filter(setting ->GepafinConstant.CRITERIA_TABLE_COLUMNS.equals(setting.getName())) // Check for "table_columns" .map(SettingResponseBean::getName) // Extract the name .findFirst() // Get the first matching result .orElse(null); // Default to null if no match if (tableType!=null){ try { Object object = PdfUtils.extractRows(value);; value= Utils.convertToString(object); } catch (Exception e) { throw new RuntimeException(e); } } contentResponseBean.getSettings().stream() .filter(setting -> "table_columns".equals(setting.getName()) || GepafinConstant.CRITERIA_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) settingValue) // Cast to Map .map(valueMap -> (List>) 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> 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 field = fieldValueList.get(rowIndex); // // boolean hasSingleNonNullPredefinedFalse = false; // // for (Map.Entry 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; // } // // } boolean hasAtLeastOneNonEmptyPredefinedFalse = fieldValueList.stream() .anyMatch(field -> stateFieldMap.entrySet().stream() .filter(entry -> Boolean.FALSE.equals(entry.getValue())) // Check only predefined: false fields .anyMatch(entry -> { Object fieldValue = field.get(entry.getKey()); return fieldValue != null && !StringUtils.isEmpty(fieldValue.toString()); }) ); if (!hasAtLeastOneNonEmptyPredefinedFalse) { errors.add(MessageFormat.format( Translator.toLocale(GepafinConstant.VALIDATION_IN_TABLE), fieldId)); } } catch (Exception e) { } } public FieldValidator isRequired(String value,Boolean isRequired, String fieldName) { if (Boolean.TRUE.equals(isRequired)) { // Only check if isRequired is true if (Objects.isNull(value) || value.isEmpty()) { // Check if value is null or empty errors.add(MessageFormat.format(Translator.toLocale(GepafinConstant.FIELD_NOT_NULL), fieldName)); } } return this; } public boolean hasErrors() { 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; } public FieldValidator formulaValidation(Object fieldValue, double finalValue, String label) { if (fieldValue != null) { try { double fieldValueAsDouble = Double.parseDouble(fieldValue.toString()); // Convert fieldValue to double if (Double.compare(finalValue, fieldValueAsDouble) != 0) { // Compare doubles safely errors.add(MessageFormat.format(Translator.toLocale(GepafinConstant.FORMULA_AMOUNT_NOT_MATCHED), label)); } } catch (NumberFormatException e) { throw new CustomValidationException(Status.BAD_REQUEST, "Invalid field value: " + fieldValue); } } return this; } }