Search in sources :

Example 1 with EntityReferenceWrapper

use of org.meveo.model.crm.EntityReferenceWrapper in project meveo by meveo-org.

the class CustomEntityInstanceService method list.

public List<CustomEntityInstance> list(String cetCode, Map<String, Object> values) {
    QueryBuilder qb = new QueryBuilder(getEntityClass(), "cei", null);
    qb.addCriterion("cei.cetCode", "=", cetCode, true);
    final List<CustomEntityInstance> resultList = qb.getTypedQuery(getEntityManager(), CustomEntityInstance.class).getResultList();
    var ownValues = new HashMap<>(values);
    for (var entry : values.entrySet()) {
        if (entry.getValue() instanceof EntityReferenceWrapper) {
            ownValues.remove(entry.getKey());
        }
    }
    if (ownValues != null && !ownValues.isEmpty()) {
        return resultList.stream().filter(customEntityInstance -> filterOnValues(ownValues, customEntityInstance)).collect(Collectors.toList());
    }
    return resultList;
}
Also used : StringUtils(org.apache.commons.lang.StringUtils) Date(java.util.Date) ELException(org.meveo.elresolver.ELException) NoResultException(javax.persistence.NoResultException) EntityDoesNotExistsException(org.meveo.api.exception.EntityDoesNotExistsException) Matcher(java.util.regex.Matcher) Map(java.util.Map) Observes(javax.enterprise.event.Observes) BigDecimal(com.ibm.icu.math.BigDecimal) Stateless(javax.ejb.Stateless) ModuleItem(org.meveo.model.ModuleItem) SqlConfiguration(org.meveo.model.sql.SqlConfiguration) WFTransitionService(org.meveo.service.wf.WFTransitionService) CustomEntityInstance(org.meveo.model.customEntities.CustomEntityInstance) MeveoModule(org.meveo.model.module.MeveoModule) Collection(java.util.Collection) Set(java.util.Set) Instant(java.time.Instant) Collectors(java.util.stream.Collectors) StandardCharsets(java.nio.charset.StandardCharsets) BusinessException(org.meveo.admin.exception.BusinessException) CustomEntityTemplate(org.meveo.model.customEntities.CustomEntityTemplate) Workflow(org.meveo.model.wf.Workflow) WFAction(org.meveo.model.wf.WFAction) MeveoModuleHelper(org.meveo.service.admin.impl.MeveoModuleHelper) List(java.util.List) ModuleUninstall(org.meveo.service.admin.impl.ModuleUninstall) CustomFieldsCacheContainerProvider(org.meveo.cache.CustomFieldsCacheContainerProvider) Pattern(java.util.regex.Pattern) PaginationConfiguration(org.meveo.admin.util.pagination.PaginationConfiguration) EntityReferenceWrapper(org.meveo.model.crm.EntityReferenceWrapper) HashMap(java.util.HashMap) ModulePostUninstall(org.meveo.model.ModulePostUninstall) CustomFieldTemplate(org.meveo.model.crm.CustomFieldTemplate) CustomFieldValues(org.meveo.model.crm.custom.CustomFieldValues) MeveoFileUtils(org.meveo.commons.utils.MeveoFileUtils) BusinessService(org.meveo.service.base.BusinessService) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) Inject(javax.inject.Inject) JacksonUtil(org.meveo.model.persistence.JacksonUtil) CustomFieldTemplateService(org.meveo.service.crm.impl.CustomFieldTemplateService) CollectionUtils(org.apache.commons.collections.CollectionUtils) MeveoValueExpressionWrapper(org.meveo.service.base.MeveoValueExpressionWrapper) WFTransition(org.meveo.model.wf.WFTransition) CEIUtils(org.meveo.model.persistence.CEIUtils) WFActionService(org.meveo.service.wf.WFActionService) WorkflowService(org.meveo.service.wf.WorkflowService) QueryBuilder(org.meveo.commons.utils.QueryBuilder) Files(java.nio.file.Files) DBStorageType(org.meveo.model.persistence.DBStorageType) IOException(java.io.IOException) CustomFieldInstanceService(org.meveo.service.crm.impl.CustomFieldInstanceService) GitHelper(org.meveo.service.git.GitHelper) File(java.io.File) Collections(java.util.Collections) HashMap(java.util.HashMap) EntityReferenceWrapper(org.meveo.model.crm.EntityReferenceWrapper) QueryBuilder(org.meveo.commons.utils.QueryBuilder) CustomEntityInstance(org.meveo.model.customEntities.CustomEntityInstance)

Example 2 with EntityReferenceWrapper

use of org.meveo.model.crm.EntityReferenceWrapper in project meveo by meveo-org.

the class FilteringJobBean method execute.

/**
 * Execute the jobInstance.
 *
 * @param result The result execution
 * @param jobInstance the jobInstance to execute
 */
@SuppressWarnings("unchecked")
@Interceptors({ JobLoggingInterceptor.class, PerformanceInterceptor.class })
@TransactionAttribute(TransactionAttributeType.NEVER)
public void execute(JobExecutionResultImpl result, JobInstance jobInstance) {
    ScriptInterface scriptInterface = null;
    Map<String, Object> context = null;
    try {
        Long nbRuns = new Long(1);
        Long waitingMillis = new Long(0);
        try {
            nbRuns = (Long) customFieldInstanceService.getCFValue(jobInstance, "nbRuns");
            waitingMillis = (Long) customFieldInstanceService.getCFValue(jobInstance, "waitingMillis");
            if (nbRuns == -1) {
                nbRuns = (long) Runtime.getRuntime().availableProcessors();
            }
        } catch (Exception e) {
            nbRuns = new Long(1);
            waitingMillis = new Long(0);
            log.warn("Cant get customFields for " + jobInstance.getJobTemplate(), e.getMessage());
        }
        String filterCode = ((EntityReferenceWrapper) customFieldInstanceService.getCFValue(jobInstance, "FilteringJob_filter")).getCode();
        String scriptCode = ((EntityReferenceWrapper) customFieldInstanceService.getCFValue(jobInstance, "FilteringJob_script")).getCode();
        String recordVariableName = (String) customFieldInstanceService.getCFValue(jobInstance, "FilteringJob_recordVariableName");
        try {
            scriptInterface = scriptInstanceService.getScriptInstance(scriptCode);
        } catch (EntityNotFoundException | InvalidScriptException e) {
            result.registerError(e.getMessage());
            return;
        }
        context = (Map<String, Object>) customFieldInstanceService.getCFValue(jobInstance, "FilteringJob_variables");
        if (context == null) {
            context = new HashMap<String, Object>();
        }
        Filter filter = filterService.findByCode(filterCode);
        if (filter == null) {
            result.registerError("Cant find filter : " + filterCode);
            return;
        }
        scriptInterface.init(context);
        List<? extends IEntity> filtredEntities = filterService.filteredListAsObjects(filter);
        int nbItemsToProcess = filtredEntities == null ? 0 : filtredEntities.size();
        result.setNbItemsToProcess(nbItemsToProcess);
        List<Future<String>> futures = new ArrayList<Future<String>>();
        SubListCreator subListCreator = new SubListCreator(filtredEntities, nbRuns.intValue());
        log.debug("NbItemsToProcess:{}, block to run{}, nbThreads:{}.", nbItemsToProcess, subListCreator.getBlocToRun(), nbRuns);
        MeveoUser lastCurrentUser = currentUser.unProxy();
        while (subListCreator.isHasNext()) {
            futures.add(filtringJobAsync.launchAndForget((List<? extends IEntity>) subListCreator.getNextWorkSet(), result, scriptInterface, recordVariableName, lastCurrentUser));
            if (subListCreator.isHasNext()) {
                try {
                    Thread.sleep(waitingMillis.longValue());
                } catch (InterruptedException e) {
                    log.error("", e);
                }
            }
        }
        // Wait for all async methods to finish
        for (Future<String> future : futures) {
            try {
                future.get();
            } catch (InterruptedException e) {
            // It was cancelled from outside - no interest
            } catch (ExecutionException e) {
                Throwable cause = e.getCause();
                result.registerError(cause.getMessage());
                result.addReport(cause.getMessage());
                log.error("Failed to execute async method", cause);
            }
        }
    } catch (Exception e) {
        log.error("Error on execute", e);
        result.setReport("error:" + e.getMessage());
    } finally {
        try {
            scriptInterface.finalize(context);
        } catch (Exception e) {
            log.error("Error on finally execute", e);
            result.setReport("finalize error:" + e.getMessage());
        }
    }
}
Also used : InvalidScriptException(org.meveo.admin.exception.InvalidScriptException) ArrayList(java.util.ArrayList) ScriptInterface(org.meveo.service.script.ScriptInterface) EntityReferenceWrapper(org.meveo.model.crm.EntityReferenceWrapper) ArrayList(java.util.ArrayList) List(java.util.List) ExecutionException(java.util.concurrent.ExecutionException) IEntity(org.meveo.model.IEntity) EntityNotFoundException(javax.persistence.EntityNotFoundException) EntityNotFoundException(javax.persistence.EntityNotFoundException) InvalidScriptException(org.meveo.admin.exception.InvalidScriptException) ExecutionException(java.util.concurrent.ExecutionException) SubListCreator(org.meveo.admin.async.SubListCreator) Filter(org.meveo.model.filter.Filter) Future(java.util.concurrent.Future) MeveoUser(org.meveo.security.MeveoUser) Interceptors(javax.interceptor.Interceptors) TransactionAttribute(javax.ejb.TransactionAttribute)

Example 3 with EntityReferenceWrapper

use of org.meveo.model.crm.EntityReferenceWrapper in project meveo by meveo-org.

the class NativePersistenceService method castValue.

/**
 * Convert value of unknown data type to a target data type. A value of type
 * list is considered as already converted value, as would come only from WS.
 *
 * @param value        Value to convert
 * @param targetClass  Target data type class to convert to
 * @param expectedList Is return value expected to be a list. If value is not a
 *                     list and is a string a value will be parsed as comma
 *                     separated string and each value will be converted
 *                     accordingly. If a single value is passed, it will be
 *                     added to a list.
 * @param datePatterns Optional. Date patterns to apply to a date type field.
 *                     Conversion is attempted in that order until a valid date
 *                     is matched.If no values are provided, a standard date and
 *                     time and then date only patterns will be applied.
 * @return A converted data type
 * @throws ValidationException Value can not be cast to a target class
 */
@SuppressWarnings({ "rawtypes", "unchecked" })
protected Object castValue(Object value, Class targetClass, boolean expectedList, String[] datePatterns) throws ValidationException {
    if (StringUtils.isBlank(value)) {
        return null;
    }
    if (value.equals(true)) {
        return 1;
    } else if (value.equals(false)) {
        return 0;
    }
    // Nothing to cast - same data type
    if (targetClass.isAssignableFrom(value.getClass()) && !expectedList) {
        return value;
    }
    // separated string and convert each value separately
    if (expectedList) {
        if (value instanceof Collection) {
            Collection<?> collectionValue = (Collection<?>) value;
            // Convert entity references wrapper list to list of string
            {
                List<String> entityReferences = collectionValue.stream().filter(EntityReferenceWrapper.class::isInstance).map(EntityReferenceWrapper.class::cast).map(EntityReferenceWrapper::getUuid).filter(Objects::nonNull).collect(Collectors.toList());
                if (!entityReferences.isEmpty()) {
                    return entityReferences;
                }
            }
            // Convert entity references wrapper list to list of long
            {
                List<Long> entityReferences = collectionValue.stream().filter(EntityReferenceWrapper.class::isInstance).map(EntityReferenceWrapper.class::cast).map(EntityReferenceWrapper::getId).filter(Objects::nonNull).collect(Collectors.toList());
                if (!entityReferences.isEmpty()) {
                    return entityReferences;
                }
            }
            return value;
        } else if (value instanceof String) {
            try {
                // First try to parse json
                return JacksonUtil.fromString((String) value, List.class);
            } catch (Exception e) {
                // If it fails, parse comma separated string
                List valuesConverted = new ArrayList<>();
                String[] valueItems = ((String) value).split(",");
                for (String valueItem : valueItems) {
                    Object valueConverted = castValue(valueItem, targetClass, false, datePatterns);
                    if (valueConverted != null) {
                        valuesConverted.add(valueConverted);
                    } else {
                        throw new ValidationException("Filter value " + value + " does not match " + targetClass.getSimpleName());
                    }
                }
                return valuesConverted;
            }
        } else {
            // A single value list
            Object valueConverted = castValue(value, targetClass, false, datePatterns);
            if (valueConverted != null) {
                return Collections.singletonList(valueConverted);
            } else {
                throw new ValidationException("Filter value " + value + " does not match " + targetClass.getSimpleName());
            }
        }
    } else {
        if (value instanceof Collection) {
            return JacksonUtil.toString(value);
        }
    }
    Number numberVal = null;
    BigDecimal bdVal = null;
    String stringVal = null;
    Boolean booleanVal = null;
    Date dateVal = null;
    List listVal = null;
    if (value instanceof BigDecimal) {
        bdVal = (BigDecimal) value;
    } else if (value instanceof Number) {
        numberVal = (Number) value;
    } else if (value instanceof Boolean) {
        booleanVal = (Boolean) value;
    } else if (value instanceof Date) {
        dateVal = (Date) value;
    } else if (value instanceof String) {
        stringVal = (String) value;
    } else if (value instanceof List) {
        listVal = (List) value;
    } else if (value instanceof Map) {
        stringVal = JacksonUtil.toString(value);
    } else if (value instanceof File) {
        stringVal = ((File) value).getAbsolutePath();
    } else {
        throw new ValidationException("Unrecognized data type for value " + value + " type " + value.getClass());
    }
    try {
        if (targetClass == String.class) {
            if (value instanceof Map) {
                return stringVal;
            }
            if (stringVal != null || listVal != null) {
                return value;
            } else {
                return value.toString();
            }
        } else if (targetClass == Boolean.class || (targetClass.isPrimitive() && targetClass.getName().equals("boolean"))) {
            if (booleanVal != null) {
                return value;
            } else {
                return Boolean.parseBoolean(value.toString());
            }
        } else if (targetClass == Date.class || targetClass == Instant.class) {
            if (dateVal != null || listVal != null) {
                return value;
            } else if (numberVal != null) {
                return Instant.ofEpochMilli(numberVal.longValue());
            } else if (stringVal != null) {
                // Use provided date patterns or try default patterns if they were not provided
                if (datePatterns != null) {
                    for (String datePattern : datePatterns) {
                        Instant date = DateUtils.parseDateWithPattern(stringVal, datePattern);
                        if (date != null) {
                            return date;
                        }
                    }
                } else {
                    // first try with date and time and then only with date format
                    Instant date = DateUtils.parseDateWithPattern(stringVal, DateUtils.DATE_TIME_PATTERN);
                    if (date == null) {
                        date = DateUtils.parseDateWithPattern(stringVal, paramBean.getDateTimeFormat());
                    }
                    if (date == null) {
                        date = DateUtils.parseDateWithPattern(stringVal, DateUtils.DATE_PATTERN);
                    }
                    if (date == null) {
                        date = DateUtils.parseDateWithPattern(stringVal, paramBean.getDateFormat());
                    }
                    return date;
                }
            }
        } else if (targetClass.isEnum()) {
            if (listVal != null || targetClass.isAssignableFrom(value.getClass())) {
                return value;
            } else if (stringVal != null) {
                Enum enumVal = ReflectionUtils.getEnumFromString((Class<? extends Enum>) targetClass, stringVal);
                if (enumVal != null) {
                    return enumVal;
                }
            }
        } else if (targetClass == Integer.class || (targetClass.isPrimitive() && targetClass.getName().equals("int"))) {
            if (numberVal != null || bdVal != null || listVal != null) {
                return value;
            } else if (stringVal != null) {
                return Integer.parseInt(stringVal);
            }
        } else if (targetClass == Long.class || (targetClass.isPrimitive() && targetClass.getName().equals("long"))) {
            if (numberVal != null || bdVal != null || listVal != null) {
                return value;
            } else if (stringVal != null) {
                return Long.parseLong(stringVal);
            }
        } else if (targetClass == Byte.class || (targetClass.isPrimitive() && targetClass.getName().equals("byte"))) {
            if (numberVal != null || bdVal != null || listVal != null) {
                return value;
            } else if (stringVal != null) {
                return Byte.parseByte(stringVal);
            }
        } else if (targetClass == Short.class || (targetClass.isPrimitive() && targetClass.getName().equals("short"))) {
            if (numberVal != null || bdVal != null || listVal != null) {
                return value;
            } else if (stringVal != null) {
                return Short.parseShort(stringVal);
            }
        } else if (targetClass == Double.class || (targetClass.isPrimitive() && targetClass.getName().equals("double"))) {
            if (numberVal != null || bdVal != null || listVal != null) {
                return value;
            } else if (stringVal != null) {
                return Double.parseDouble(stringVal);
            }
        } else if (targetClass == Float.class || (targetClass.isPrimitive() && targetClass.getName().equals("float"))) {
            if (numberVal != null || bdVal != null || listVal != null) {
                return value;
            } else if (stringVal != null) {
                return Float.parseFloat(stringVal);
            }
        } else if (targetClass == BigDecimal.class) {
            if (numberVal != null || bdVal != null || listVal != null) {
                return value;
            } else if (stringVal != null) {
                return new BigDecimal(stringVal);
            }
        }
    } catch (NumberFormatException e) {
    // Swallow - validation will take care of it later
    }
    return value;
}
Also used : IdentifiableEnum(org.meveo.model.IdentifiableEnum) CustomFieldStorageTypeEnum(org.meveo.model.crm.custom.CustomFieldStorageTypeEnum) CustomFieldTypeEnum(org.meveo.model.crm.custom.CustomFieldTypeEnum) ValidationException(org.meveo.admin.exception.ValidationException) Instant(java.time.Instant) ArrayList(java.util.ArrayList) NoResultException(javax.persistence.NoResultException) NonUniqueResultException(javax.persistence.NonUniqueResultException) NotImplementedException(org.apache.commons.lang.NotImplementedException) ValidationException(org.meveo.admin.exception.ValidationException) BusinessException(org.meveo.admin.exception.BusinessException) PersistenceException(javax.persistence.PersistenceException) SQLException(java.sql.SQLException) BigDecimal(java.math.BigDecimal) Date(java.util.Date) LocalDate(java.time.LocalDate) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) BigInteger(java.math.BigInteger) EntityReferenceWrapper(org.meveo.model.crm.EntityReferenceWrapper) Objects(java.util.Objects) Collection(java.util.Collection) List(java.util.List) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) CustomModelObject(org.meveo.model.customEntities.CustomModelObject) Map(java.util.Map) HashMap(java.util.HashMap) File(java.io.File)

Example 4 with EntityReferenceWrapper

use of org.meveo.model.crm.EntityReferenceWrapper in project meveo by meveo-org.

the class NativePersistenceService method findIdByUniqueValues.

/**
 * Find a record uuid in table using its exact values
 *
 * @param sqlConnectionCode Code of the sql configuration
 * @param customTemplate Template related to the table
 * @param queryValues Values used to filter the result
 * @param fields
 * @return The uuid of the record if it was found or null if it was not
 */
public String findIdByUniqueValues(String sqlConnectionCode, CustomModelObject customTemplate, Map<String, Object> queryValues, Collection<CustomFieldTemplate> fields) {
    String result = null;
    String tableName = PostgresReserverdKeywords.escapeAndFormat(customTemplate.getDbTableName());
    if (queryValues.isEmpty()) {
        throw new IllegalArgumentException("Query values should not be empty");
    }
    StringBuilder q = new StringBuilder();
    q.append("SELECT uuid FROM {h-schema}" + tableName + " as a\n");
    Map<Integer, Object> queryParamers = new HashMap<>();
    Map<String, Object> uniqueValues = new HashMap<>();
    for (CustomFieldTemplate cft : fields) {
        if (cft.isUnique()) {
            Object uniqueValue = Optional.ofNullable(queryValues.get(cft.getCode())).orElse(queryValues.get(cft.getDbFieldname()));
            // Don't use inherited values
            if (uniqueValue != null && cft.getAppliesTo().equals(customTemplate.getAppliesTo())) {
                uniqueValues.put(cft.getDbFieldname(), uniqueValue);
            }
        }
    }
    if (uniqueValues.isEmpty()) {
        result = null;
    } else {
        AtomicInteger i = new AtomicInteger(1);
        uniqueValues.forEach((key, value) -> {
            key = PostgresReserverdKeywords.escapeAndFormat(key);
            if (!(value instanceof Collection) && !(value instanceof File) && !(value instanceof Map)) {
                if (value instanceof EntityReferenceWrapper) {
                    value = ((EntityReferenceWrapper) value).getUuid();
                }
                if (i.get() == 1) {
                    q.append("WHERE a." + key + " = ?\n");
                } else {
                    q.append("AND a." + key + " = ?\n");
                }
                queryParamers.put(i.getAndIncrement(), value);
            }
        });
        QueryBuilder builder = new QueryBuilder();
        builder.setSqlString(q.toString());
        Session session = crossStorageTransaction.getHibernateSession(sqlConnectionCode);
        NativeQuery<Map<String, Object>> query = builder.getNativeQuery(session, true);
        queryParamers.forEach((k, v) -> query.setParameter(k, v));
        try {
            Map<String, Object> singleResult = query.getSingleResult();
            result = (String) singleResult.get("uuid");
        } catch (NoResultException | NonUniqueResultException e) {
            result = null;
        } catch (Exception e) {
            log.error("Error executing query {}", query.getQueryString());
            throw e;
        }
    }
    if (result == null && customTemplate instanceof CustomEntityTemplate) {
        CustomEntityTemplate cet = (CustomEntityTemplate) customTemplate;
        CustomEntityTemplate superTemplate = cet.getSuperTemplate();
        if (superTemplate != null) {
            if (HibernateUtils.isLazyLoaded(superTemplate)) {
                superTemplate = customEntityTemplateService.findById(superTemplate.getId(), List.of("superTemplate"));
            }
            result = findIdByUniqueValues(sqlConnectionCode, superTemplate, queryValues, fields);
        }
    }
    return result;
}
Also used : NonUniqueResultException(javax.persistence.NonUniqueResultException) HashMap(java.util.HashMap) QueryBuilder(org.meveo.commons.utils.QueryBuilder) NoResultException(javax.persistence.NoResultException) NoResultException(javax.persistence.NoResultException) NonUniqueResultException(javax.persistence.NonUniqueResultException) NotImplementedException(org.apache.commons.lang.NotImplementedException) ValidationException(org.meveo.admin.exception.ValidationException) BusinessException(org.meveo.admin.exception.BusinessException) PersistenceException(javax.persistence.PersistenceException) SQLException(java.sql.SQLException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) BigInteger(java.math.BigInteger) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) EntityReferenceWrapper(org.meveo.model.crm.EntityReferenceWrapper) CustomEntityTemplate(org.meveo.model.customEntities.CustomEntityTemplate) CustomFieldTemplate(org.meveo.model.crm.CustomFieldTemplate) Collection(java.util.Collection) CustomModelObject(org.meveo.model.customEntities.CustomModelObject) File(java.io.File) Map(java.util.Map) HashMap(java.util.HashMap) Session(org.hibernate.Session)

Example 5 with EntityReferenceWrapper

use of org.meveo.model.crm.EntityReferenceWrapper in project meveo by meveo-org.

the class CustomFieldInstanceService method setCFValue.

/**
 * Set a Custom field value on an entity.
 *
 * @param entity Entity
 * @param cfCode Custom field value code
 * @param value  Value to set
 * @return custom field value
 * @throws BusinessException business exception.
 */
@SuppressWarnings("unchecked")
public CustomFieldValue setCFValue(ICustomFieldEntity entity, String cfCode, Object value) throws BusinessException {
    log.trace("Setting CF value. Code: {}, entity {} value {}", cfCode, entity, value);
    String repository = "default";
    CustomEntityTemplate cet = null;
    if (entity instanceof CustomEntityInstance) {
        cet = ((CustomEntityInstance) entity).getCet();
        repository = ((CustomEntityInstance) entity).getRepository() != null ? ((CustomEntityInstance) entity).getRepository().getCode() : "default";
    }
    // Can not set the value if field is versionable without a date
    CustomFieldTemplate cft = cfTemplateService.findByCodeAndAppliesTo(cfCode, entity);
    if (cft == null) {
        throw new BusinessException("Custom field template with code " + cfCode + " not found found for entity " + entity);
    }
    // Handle serialized map values
    if ((cft.getStorageType() == CustomFieldStorageTypeEnum.MAP || cft.getStorageType() == CustomFieldStorageTypeEnum.MATRIX) && value instanceof String) {
        value = JacksonUtil.fromString((String) value, Map.class);
    }
    if (cft.isVersionable()) {
        throw new RuntimeException("Can not determine a period for Custom Field " + entity.getClass().getSimpleName() + "/" + cfCode + " value if no date or date range is provided");
    }
    // Handle cases when appProvider was passed instead of a real Provider entity. The class in this case is org.meveo.model.crm.Provider$Proxy$_$$_WeldClientProxy
    if (entity instanceof Provider && entity.getClass().getSimpleName().contains("Proxy")) {
        entity = providerService.findById(appProvider.getId());
    }
    CustomFieldValue cfValue = null;
    if (entity.getCfValues() != null) {
        cfValue = entity.getCfValues().getCfValue(cfCode);
    }
    log.trace("Setting CF value1. Code: {}, cfValue {}", cfCode, cfValue);
    // No existing CF value. Create CF value with new value. Assign(persist) NULL value only if cft.defaultValue is present
    if (cfValue == null) {
        if (cft.getFieldType() == CustomFieldTypeEnum.ENTITY) {
            /* Don't wrap primitive entity references */
            if (cft.getStoragesNullSafe().contains(DBStorageType.NEO4J)) {
                String cetCode = cft.getEntityClazzCetCode();
                CustomEntityTemplate refCet = customEntityTemplateService.findByCode(cetCode);
                if (refCet == null) {
                    throw new org.meveo.exceptions.EntityDoesNotExistsException(CustomEntityTemplate.class, cetCode);
                }
                if (refCet.getNeo4JStorageConfiguration() != null && refCet.getNeo4JStorageConfiguration().isPrimitiveEntity()) {
                    return entity.getCfValuesNullSafe().setValue(cfCode, value);
                }
            }
            if (customFieldTemplateService.isReferenceJpaEntity(cft.getEntityClazzCetCode())) {
                if (cft.getStorageType() == CustomFieldStorageTypeEnum.LIST) {
                    try {
                        var collectionValue = JacksonUtil.convert(value, new TypeReference<List<EntityReferenceWrapper>>() {
                        });
                        cfValue = entity.getCfValuesNullSafe().setValue(cfCode, collectionValue, EntityReferenceWrapper.class);
                    } catch (Exception e) {
                        // FIXME: Handle these cases
                        log.warn("Unhandled data : {}", value.toString());
                    }
                } else {
                    EntityReferenceWrapper entityReferenceWrapper = new EntityReferenceWrapper();
                    entityReferenceWrapper.setClassnameCode(cft.getEntityClazzCetCode());
                    if (value instanceof EntityReferenceWrapper) {
                        entityReferenceWrapper = (EntityReferenceWrapper) value;
                    } else if (value instanceof String) {
                        entityReferenceWrapper.setUuid((String) value);
                        entityReferenceWrapper.setCode((String) value);
                    } else if (value instanceof BusinessEntity) {
                        entityReferenceWrapper.setCode(((BusinessEntity) value).getCode());
                        entityReferenceWrapper.setId(((BusinessEntity) value).getId());
                    } else if (StringUtils.isNumeric(String.valueOf(value))) {
                        entityReferenceWrapper.setId(Long.parseLong(String.valueOf(value)));
                    } else if (value instanceof BaseEntity) {
                        JpaUtils.extractNaturalId(value).ifPresent(entityReferenceWrapper::setCode);
                        entityReferenceWrapper.setId(((BaseEntity) value).getId());
                    }
                    cfValue = entity.getCfValuesNullSafe().setValue(cfCode, entityReferenceWrapper);
                }
            } else {
                EntityReferenceWrapper entityReferenceWrapper = new EntityReferenceWrapper();
                entityReferenceWrapper.setClassnameCode(cft.getEntityClazzCetCode());
                entityReferenceWrapper.setRepository(repository);
                if (value instanceof Map) {
                    Map<String, Object> valueAsMap = (Map<String, Object>) value;
                    entityReferenceWrapper.setCode((String) valueAsMap.get("code"));
                    entityReferenceWrapper.setUuid((String) valueAsMap.get("uuid"));
                    if (entityReferenceWrapper.getUuid() == null) {
                        entityReferenceWrapper.setUuid((String) valueAsMap.get("meveo_uuid"));
                    }
                } else if (value instanceof String) {
                    entityReferenceWrapper.setUuid((String) value);
                    fetchCode(cft, (String) value, entityReferenceWrapper);
                } else if (value instanceof EntityReferenceWrapper) {
                    entityReferenceWrapper = (EntityReferenceWrapper) value;
                }
                if (entityReferenceWrapper.getUuid() != null) {
                    cfValue = entity.getCfValuesNullSafe().setValue(cfCode, entityReferenceWrapper);
                } else if (value instanceof Collection) {
                    List<EntityReferenceWrapper> entityReferences = new ArrayList<>();
                    List<Map<String, Object>> entityValues = new ArrayList<>();
                    for (Object item : (Collection<?>) value) {
                        EntityReferenceWrapper itemWrapper = new EntityReferenceWrapper();
                        itemWrapper.setClassnameCode(cft.getEntityClazzCetCode());
                        if (item instanceof Map) {
                            Map<String, Object> valueAsMap = (Map<String, Object>) item;
                            itemWrapper.setCode((String) valueAsMap.get("code"));
                            itemWrapper.setUuid((String) valueAsMap.get("uuid"));
                            if (itemWrapper.getUuid() == null) {
                                itemWrapper.setUuid((String) valueAsMap.get("meveo_uuid"));
                            }
                            if (itemWrapper.getUuid() == null) {
                                entityValues.add(valueAsMap);
                            }
                        } else if (item instanceof String) {
                            itemWrapper.setUuid((String) item);
                            itemWrapper.setCode((String) item);
                            // Try to fetch code
                            fetchCode(cft, (String) item, itemWrapper);
                        } else if (item instanceof EntityReferenceWrapper) {
                            itemWrapper = (EntityReferenceWrapper) item;
                        }
                        if (itemWrapper.getUuid() != null || itemWrapper.getCode() != null) {
                            entityReferences.add(itemWrapper);
                        }
                    }
                    // If entity references list is empty, the entities referenced are probably being created
                    if (!entityReferences.isEmpty()) {
                        cfValue = entity.getCfValuesNullSafe().setValue(cfCode, entityReferences);
                    } else if (!entityValues.isEmpty()) {
                        cfValue = entity.getCfValuesNullSafe().setValue(cfCode, entityValues);
                    }
                } else {
                    entity.getCfValuesNullSafe().setValue(cfCode, value);
                }
            }
            if (value instanceof CustomEntityInstance) {
                cfValue = entity.getCfValuesNullSafe().setValue(cfCode, value);
            }
        } else {
            cfValue = entity.getCfValuesNullSafe().setValue(cfCode, value);
        }
        log.trace("Setting CF value 2. Code: {}, cfValue {}", cfCode, cfValue);
    // Existing CFI found. Update with new value or NULL value only if cft.defaultValue is present
    } else if (value != null || cft.getDefaultValue() != null) {
        try {
            cfValue.setValue(value);
        } catch (IllegalArgumentException e) {
            log.error("Error setting value for field template with code " + cfCode + " for entity " + entity + " : " + e.getMessage());
            throw e;
        }
    // Existing CF value found, but new value is null, so remove CF value all together
    } else {
        entity.getCfValues().removeValue(cfCode);
        return null;
    }
    return cfValue;
}
Also used : CustomFieldValue(org.meveo.model.crm.custom.CustomFieldValue) EntityDoesNotExistsException(org.meveo.api.exception.EntityDoesNotExistsException) BusinessException(org.meveo.admin.exception.BusinessException) CurrentUserProvider(org.meveo.security.keycloak.CurrentUserProvider) Provider(org.meveo.model.crm.Provider) BusinessException(org.meveo.admin.exception.BusinessException) EntityDoesNotExistsException(org.meveo.api.exception.EntityDoesNotExistsException) CustomEntityTemplate(org.meveo.model.customEntities.CustomEntityTemplate) EntityReferenceWrapper(org.meveo.model.crm.EntityReferenceWrapper) CustomFieldTemplate(org.meveo.model.crm.CustomFieldTemplate) CustomEntityInstance(org.meveo.model.customEntities.CustomEntityInstance)

Aggregations

EntityReferenceWrapper (org.meveo.model.crm.EntityReferenceWrapper)25 HashMap (java.util.HashMap)17 Map (java.util.Map)16 ArrayList (java.util.ArrayList)15 List (java.util.List)12 Collection (java.util.Collection)10 Date (java.util.Date)9 LinkedHashMap (java.util.LinkedHashMap)8 File (java.io.File)7 Instant (java.time.Instant)7 BusinessException (org.meveo.admin.exception.BusinessException)7 CustomEntityInstance (org.meveo.model.customEntities.CustomEntityInstance)7 CustomFieldTemplate (org.meveo.model.crm.CustomFieldTemplate)6 CustomModelObject (org.meveo.model.customEntities.CustomModelObject)5 BigDecimal (java.math.BigDecimal)4 BigInteger (java.math.BigInteger)4 NoResultException (javax.persistence.NoResultException)4 NonUniqueResultException (javax.persistence.NonUniqueResultException)4 PersistenceException (javax.persistence.PersistenceException)4 EntityReferenceDto (org.meveo.api.dto.EntityReferenceDto)4