Search in sources :

Example 1 with IDocumentFieldView

use of de.metas.ui.web.window.model.IDocumentFieldView in project metasfresh-webui-api by metasfresh.

the class WindowRestController method getDocumentFieldZoomInto.

private JSONZoomInto getDocumentFieldZoomInto(final DocumentPath documentPath, final String fieldName) {
    userSession.assertLoggedIn();
    final DocumentZoomIntoInfo zoomIntoInfo = documentCollection.forDocumentReadonly(documentPath, document -> {
        final IDocumentFieldView field = document.getFieldView(fieldName);
        // Generic ZoomInto button
        if (field.getDescriptor().getWidgetType() == DocumentFieldWidgetType.ZoomIntoButton) {
            final ButtonFieldActionDescriptor buttonActionDescriptor = field.getDescriptor().getButtonActionDescriptor();
            final String zoomIntoTableIdFieldName = buttonActionDescriptor.getZoomIntoTableIdFieldName();
            final Integer adTableId = document.getFieldView(zoomIntoTableIdFieldName).getValueAs(Integer.class);
            if (adTableId == null || adTableId <= 0) {
                throw new EntityNotFoundException("Cannot fetch ZoomInto infos from a null value. No AD_Table_ID.").setParameter("documentPath", documentPath).setParameter("fieldName", fieldName).setParameter("zoomIntoTableIdFieldName", zoomIntoTableIdFieldName);
            }
            final Integer recordId = field.getValueAs(Integer.class);
            if (recordId == null) {
                throw new EntityNotFoundException("Cannot fetch ZoomInto infos from a null value. No Record_ID.").setParameter("documentPath", documentPath).setParameter("fieldName", fieldName).setParameter("zoomIntoTableIdFieldName", zoomIntoTableIdFieldName);
            }
            final String tableName = Services.get(IADTableDAO.class).retrieveTableName(adTableId);
            return DocumentZoomIntoInfo.of(tableName, recordId);
        } else // Key Field
        if (field.isKey()) {
            // Allow zooming into key column. It shall open precisely this record in a new window.
            // (see https://github.com/metasfresh/metasfresh/issues/1687 to understand the use-case)
            final String tableName = document.getEntityDescriptor().getTableName();
            final int recordId = document.getDocumentIdAsInt();
            return DocumentZoomIntoInfo.of(tableName, recordId);
        } else // Regular lookup value
        {
            return field.getZoomIntoInfo();
        }
    });
    final JSONDocumentPath jsonZoomIntoDocumentPath;
    if (zoomIntoInfo == null) {
        throw new EntityNotFoundException("ZoomInto not supported").setParameter("documentPath", documentPath).setParameter("fieldName", fieldName);
    } else if (!zoomIntoInfo.isRecordIdPresent()) {
        final WindowId windowId = documentCollection.getWindowId(zoomIntoInfo);
        jsonZoomIntoDocumentPath = JSONDocumentPath.newWindowRecord(windowId);
    } else {
        final DocumentPath zoomIntoDocumentPath = documentCollection.getDocumentPath(zoomIntoInfo);
        jsonZoomIntoDocumentPath = JSONDocumentPath.ofWindowDocumentPath(zoomIntoDocumentPath);
    }
    return JSONZoomInto.builder().documentPath(jsonZoomIntoDocumentPath).source(JSONDocumentPath.ofWindowDocumentPath(documentPath, fieldName)).build();
}
Also used : ButtonFieldActionDescriptor(de.metas.ui.web.window.descriptor.ButtonFieldActionDescriptor) DocumentZoomIntoInfo(de.metas.ui.web.window.model.lookup.DocumentZoomIntoInfo) WindowId(de.metas.ui.web.window.datatypes.WindowId) IADTableDAO(org.adempiere.ad.table.api.IADTableDAO) DocumentPath(de.metas.ui.web.window.datatypes.DocumentPath) JSONDocumentPath(de.metas.ui.web.window.datatypes.json.JSONDocumentPath) EntityNotFoundException(de.metas.ui.web.exceptions.EntityNotFoundException) IDocumentFieldView(de.metas.ui.web.window.model.IDocumentFieldView) JSONDocumentPath(de.metas.ui.web.window.datatypes.json.JSONDocumentPath)

Example 2 with IDocumentFieldView

use of de.metas.ui.web.window.model.IDocumentFieldView in project metasfresh-webui-api by metasfresh.

the class ASIRepository method loadASIDocumentField.

private static void loadASIDocumentField(final Document asiDoc, final I_M_AttributeInstance fromAI) {
    final String fieldName = fromAI.getM_Attribute().getValue();
    final IDocumentFieldView field = asiDoc.getFieldViewOrNull(fieldName);
    // This can happen if we are trying to load an old ASI but in meantime the AttributeSet was changed and the attribute was removed or deactivated.
    if (field == null) {
        logger.warn("Attribute {} no longer exist in {}", fieldName, asiDoc.getEntityDescriptor());
        return;
    }
    final Object value = field.getDescriptor().getDataBindingNotNull(ASIAttributeFieldBinding.class).readValue(fromAI);
    asiDoc.processValueChange(fieldName, value, () -> "update from " + fromAI);
}
Also used : ASIAttributeFieldBinding(de.metas.ui.web.pattribute.ASIDescriptorFactory.ASIAttributeFieldBinding) IDocumentFieldView(de.metas.ui.web.window.model.IDocumentFieldView)

Example 3 with IDocumentFieldView

use of de.metas.ui.web.window.model.IDocumentFieldView in project metasfresh-webui-api by metasfresh.

the class SqlDocumentQueryBuilder method buildSqlWhereClause.

private IPair<IStringExpression, List<Object>> buildSqlWhereClause() {
    final SqlParamsCollector sqlParams = SqlParamsCollector.newInstance();
    final CompositeStringExpression.Builder sqlWhereClauseBuilder = IStringExpression.composer();
    // 
    // Entity's WHERE clause
    {
        final IStringExpression entityWhereClauseExpression = entityBinding.getSqlWhereClause();
        if (!entityWhereClauseExpression.isNullExpression()) {
            sqlWhereClauseBuilder.appendIfNotEmpty("\n AND ");
            sqlWhereClauseBuilder.append(" /* entity where clause */ (").append(entityWhereClauseExpression).append(")");
        }
    }
    // 
    // Key column
    // FIXME: handle AD_Reference/AD_Ref_List(s). In that case the recordId will be AD_Ref_List.Value,
    // so the SQL where clause which is currently build is AD_Ref_List_ID=<the AD_Ref_List.Value>.
    // The build SQL where clause shall be something like AD_Reference_ID=<the reference, i think we shall fetch it somehow from Lookup> AND Value=<the value, which currently is the recordId>
    final DocumentId recordId = getRecordId();
    if (recordId != null) {
        final List<SqlDocumentFieldDataBindingDescriptor> keyFields = entityBinding.getKeyFields();
        if (keyFields.isEmpty()) {
            throw new AdempiereException("Failed building where clause because there is no Key Column defined in " + entityBinding);
        } else // Single primary key
        if (keyFields.size() == 1) {
            final String keyColumnName = keyFields.get(0).getColumnName();
            sqlWhereClauseBuilder.appendIfNotEmpty("\n AND ");
            sqlWhereClauseBuilder.append(" /* key */ ").append(keyColumnName).append("=").append(sqlParams.placeholder(recordId.toInt()));
        } else // Composed primary key
        {
            final Map<String, Object> keyColumnName2value = extractComposedKey(recordId, keyFields);
            keyColumnName2value.forEach((keyColumnName, value) -> {
                sqlWhereClauseBuilder.appendIfNotEmpty("\n AND ");
                sqlWhereClauseBuilder.append(" /* key */ ").append(keyColumnName).append("=").append(sqlParams.placeholder(value));
            });
        }
    }
    // 
    // Parent link where clause (if any)
    final Document parentDocument = getParentDocument();
    if (parentDocument != null) {
        final String parentLinkColumnName = entityBinding.getParentLinkColumnName();
        final String linkColumnName = entityBinding.getLinkColumnName();
        if (parentLinkColumnName != null && linkColumnName != null) {
            final IDocumentFieldView parentLinkField = parentDocument.getFieldView(parentLinkColumnName);
            final Object parentLinkValue = parentLinkField.getValue();
            final DocumentFieldWidgetType parentLinkWidgetType = parentLinkField.getWidgetType();
            final Class<?> targetClass = entityBinding.getFieldByFieldName(linkColumnName).getSqlValueClass();
            final Object sqlParentLinkValue = SqlDocumentsRepository.convertValueToPO(parentLinkValue, parentLinkColumnName, parentLinkWidgetType, targetClass);
            sqlWhereClauseBuilder.appendIfNotEmpty("\n AND ");
            sqlWhereClauseBuilder.append(" /* parent link */ ").append(linkColumnName).append("=").append(sqlParams.placeholder(sqlParentLinkValue));
        }
    }
    // 
    // Document filters
    {
        final String sqlFilters = SqlDocumentFilterConverters.createEntityBindingEffectiveConverter(entityBinding).getSql(sqlParams, getDocumentFilters(), SqlOptions.usingTableAlias(entityBinding.getTableAlias()));
        if (!Check.isEmpty(sqlFilters, true)) {
            sqlWhereClauseBuilder.appendIfNotEmpty("\n AND ");
            sqlWhereClauseBuilder.append(" /* filters */ (\n").append(sqlFilters).append(")\n");
        }
    }
    // Build the final SQL where clause
    return ImmutablePair.of(sqlWhereClauseBuilder.build(), Collections.unmodifiableList(sqlParams.toList()));
}
Also used : IPair(org.adempiere.util.lang.IPair) SqlDocumentFieldDataBindingDescriptor(de.metas.ui.web.window.descriptor.sql.SqlDocumentFieldDataBindingDescriptor) DocumentId(de.metas.ui.web.window.datatypes.DocumentId) Env(org.compiere.util.Env) ArrayList(java.util.ArrayList) IStringExpression(org.adempiere.ad.expression.api.IStringExpression) Evaluatee(org.compiere.util.Evaluatee) SqlDocumentFilterConverters(de.metas.ui.web.document.filter.sql.SqlDocumentFilterConverters) ImmutableList(com.google.common.collect.ImmutableList) SqlEntityFieldBinding(de.metas.ui.web.window.descriptor.sql.SqlEntityFieldBinding) SqlDocumentEntityDataBindingDescriptor(de.metas.ui.web.window.descriptor.sql.SqlDocumentEntityDataBindingDescriptor) IDocumentFieldView(de.metas.ui.web.window.model.IDocumentFieldView) Map(java.util.Map) DocumentEntityDescriptor(de.metas.ui.web.window.descriptor.DocumentEntityDescriptor) DocumentFilter(de.metas.ui.web.document.filter.DocumentFilter) DocumentQueryOrderBy(de.metas.ui.web.window.model.DocumentQueryOrderBy) OnVariableNotFound(org.adempiere.ad.expression.api.IExpressionEvaluator.OnVariableNotFound) Properties(java.util.Properties) WindowConstants(de.metas.ui.web.window.WindowConstants) UserRolePermissionsKey(org.adempiere.ad.security.UserRolePermissionsKey) Evaluatees(org.compiere.util.Evaluatees) ImmutableMap(com.google.common.collect.ImmutableMap) AccessSqlStringExpression(org.adempiere.ad.security.impl.AccessSqlStringExpression) MoreObjects(com.google.common.base.MoreObjects) Objects(java.util.Objects) DocumentFieldDescriptor(de.metas.ui.web.window.descriptor.DocumentFieldDescriptor) List(java.util.List) ImmutablePair(org.adempiere.util.lang.ImmutablePair) AdempiereException(org.adempiere.exceptions.AdempiereException) Check(org.adempiere.util.Check) DocumentFieldWidgetType(de.metas.ui.web.window.descriptor.DocumentFieldWidgetType) DocumentQuery(de.metas.ui.web.window.model.DocumentQuery) LookupValueByIdSupplier(de.metas.ui.web.window.model.lookup.LookupValueByIdSupplier) SqlParamsCollector(de.metas.ui.web.document.filter.sql.SqlParamsCollector) Collections(java.util.Collections) Document(de.metas.ui.web.window.model.Document) CompositeStringExpression(org.adempiere.ad.expression.api.impl.CompositeStringExpression) CompositeStringExpression(org.adempiere.ad.expression.api.impl.CompositeStringExpression) DocumentId(de.metas.ui.web.window.datatypes.DocumentId) Document(de.metas.ui.web.window.model.Document) IDocumentFieldView(de.metas.ui.web.window.model.IDocumentFieldView) SqlDocumentFieldDataBindingDescriptor(de.metas.ui.web.window.descriptor.sql.SqlDocumentFieldDataBindingDescriptor) DocumentFieldWidgetType(de.metas.ui.web.window.descriptor.DocumentFieldWidgetType) AdempiereException(org.adempiere.exceptions.AdempiereException) IStringExpression(org.adempiere.ad.expression.api.IStringExpression) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) SqlParamsCollector(de.metas.ui.web.document.filter.sql.SqlParamsCollector)

Example 4 with IDocumentFieldView

use of de.metas.ui.web.window.model.IDocumentFieldView in project metasfresh-webui-api by metasfresh.

the class SqlDocumentsRepository method saveLabels.

private static final void saveLabels(final Document document, final IDocumentFieldView documentField) {
    final LabelsLookup lookup = LabelsLookup.cast(documentField.getDescriptor().getLookupDescriptor(LookupScope.DocumentField));
    final int linkId = document.getFieldView(lookup.getLinkColumnName()).getValueAsInt(-1);
    final Set<Object> listValuesInDatabase = lookup.retrieveExistingValues(linkId).getKeys();
    final LookupValuesList lookupValuesList = documentField.getValueAs(LookupValuesList.class);
    final Set<Object> listValuesToSave = lookupValuesList != null ? new HashSet<>(lookupValuesList.getKeys()) : new HashSet<>();
    // 
    // Delete removed labels
    {
        final Set<Object> listValuesToDelete = new HashSet<>(listValuesInDatabase);
        listValuesToDelete.removeAll(listValuesToSave);
        if (!listValuesToDelete.isEmpty()) {
            final int countDeleted = lookup.retrieveExistingValuesRecordQuery(linkId).addInArrayFilter(lookup.getLabelsValueColumnName(), listValuesToDelete).create().delete();
            if (countDeleted != listValuesToDelete.size()) {
                logger.warn("Possible issue while deleting labels for linkId={}: listValuesToDelete={}, countDeleted={}", linkId, listValuesToDelete, countDeleted);
            }
        }
    }
    // 
    // Create new labels
    {
        final Set<Object> listValuesToSaveEffective = new HashSet<>(listValuesToSave);
        listValuesToSaveEffective.removeAll(listValuesInDatabase);
        listValuesToSaveEffective.forEach(listValueToSave -> createLabelPORecord(listValueToSave, linkId, lookup));
    }
}
Also used : Password(de.metas.ui.web.window.datatypes.Password) DocumentPermissionsHelper(de.metas.ui.web.window.controller.DocumentPermissionsHelper) IntegerLookupValue(de.metas.ui.web.window.datatypes.LookupValue.IntegerLookupValue) ITrx(org.adempiere.ad.trx.api.ITrx) TableModelLoader(org.adempiere.ad.persistence.TableModelLoader) InterfaceWrapperHelper(org.adempiere.model.InterfaceWrapperHelper) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ResultSet(java.sql.ResultSet) IDocumentFieldView(de.metas.ui.web.window.model.IDocumentFieldView) Map(java.util.Map) POInfo(org.compiere.model.POInfo) JSONNullValue(de.metas.ui.web.window.datatypes.json.JSONNullValue) WindowConstants(de.metas.ui.web.window.WindowConstants) DocumentValuesSupplier(de.metas.ui.web.window.model.Document.DocumentValuesSupplier) NonNull(lombok.NonNull) Timestamp(java.sql.Timestamp) Set(java.util.Set) IQueryBuilder(org.adempiere.ad.dao.IQueryBuilder) PreparedStatement(java.sql.PreparedStatement) Collectors(java.util.stream.Collectors) ITrxManager(org.adempiere.ad.trx.api.ITrxManager) UserSession(de.metas.ui.web.session.UserSession) DocumentFieldDescriptor(de.metas.ui.web.window.descriptor.DocumentFieldDescriptor) DBException(org.adempiere.exceptions.DBException) Services(org.adempiere.util.Services) EntityNotFoundException(de.metas.ui.web.exceptions.EntityNotFoundException) List(java.util.List) StringLookupValue(de.metas.ui.web.window.datatypes.LookupValue.StringLookupValue) LookupScope(de.metas.ui.web.window.descriptor.LookupDescriptorProvider.LookupScope) IDocumentChangesCollector(de.metas.ui.web.window.model.IDocumentChangesCollector) DocumentFieldWidgetType(de.metas.ui.web.window.descriptor.DocumentFieldWidgetType) DocumentQuery(de.metas.ui.web.window.model.DocumentQuery) Joiner(com.google.common.base.Joiner) LogManager(de.metas.logging.LogManager) DocumentPath(de.metas.ui.web.window.datatypes.DocumentPath) SqlDocumentFieldDataBindingDescriptor(de.metas.ui.web.window.descriptor.sql.SqlDocumentFieldDataBindingDescriptor) DocumentId(de.metas.ui.web.window.datatypes.DocumentId) TimeUtil(org.compiere.util.TimeUtil) OrderedDocumentsList(de.metas.ui.web.window.model.OrderedDocumentsList) Function(java.util.function.Function) PlainContextAware(org.adempiere.model.PlainContextAware) DocumentNotFoundException(de.metas.ui.web.window.exceptions.DocumentNotFoundException) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) SQLException(java.sql.SQLException) DB(org.compiere.util.DB) LookupDescriptor(de.metas.ui.web.window.descriptor.LookupDescriptor) ImmutableList(com.google.common.collect.ImmutableList) SqlDocumentEntityDataBindingDescriptor(de.metas.ui.web.window.descriptor.sql.SqlDocumentEntityDataBindingDescriptor) DisplayType(org.compiere.util.DisplayType) DocumentEntityDescriptor(de.metas.ui.web.window.descriptor.DocumentEntityDescriptor) LookupValuesList(de.metas.ui.web.window.datatypes.LookupValuesList) DBMoreThenOneRecordsFoundException(org.adempiere.exceptions.DBMoreThenOneRecordsFoundException) DocumentFieldValueLoader(de.metas.ui.web.window.descriptor.sql.DocumentFieldValueLoader) JSONLookupValue(de.metas.ui.web.window.datatypes.json.JSONLookupValue) LookupValue(de.metas.ui.web.window.datatypes.LookupValue) Logger(org.slf4j.Logger) DocumentsRepository(de.metas.ui.web.window.model.DocumentsRepository) DocumentFieldDataBindingDescriptor(de.metas.ui.web.window.descriptor.DocumentFieldDataBindingDescriptor) IQueryBL(org.adempiere.ad.dao.IQueryBL) LabelsLookup(de.metas.ui.web.window.model.lookup.LabelsLookup) AdempiereException(org.adempiere.exceptions.AdempiereException) DataTypes(de.metas.ui.web.window.datatypes.DataTypes) Check(org.adempiere.util.Check) PO(org.compiere.model.PO) JSONDate(de.metas.ui.web.window.datatypes.json.JSONDate) Document(de.metas.ui.web.window.model.Document) ResultSet(java.sql.ResultSet) Set(java.util.Set) HashSet(java.util.HashSet) LabelsLookup(de.metas.ui.web.window.model.lookup.LabelsLookup) LookupValuesList(de.metas.ui.web.window.datatypes.LookupValuesList)

Example 5 with IDocumentFieldView

use of de.metas.ui.web.window.model.IDocumentFieldView in project metasfresh-webui-api by metasfresh.

the class SqlDocumentsRepository method save.

@Override
public void save(final Document document) {
    Services.get(ITrxManager.class).assertThreadInheritedTrxExists();
    assertThisRepository(document.getEntityDescriptor());
    DocumentPermissionsHelper.assertCanEdit(document);
    // Runnables to be executed after the PO is saved
    final List<Runnable> afterSaveRunnables = new ArrayList<>();
    // 
    // Load the PO / Create new PO instance
    final PO po = retrieveOrCreatePO(document);
    // 
    // Set values to PO
    final boolean isNew = document.isNew();
    boolean changes = false;
    for (final IDocumentFieldView documentField : document.getFieldViews()) {
        if (!isNew && !documentField.hasChangesToSave()) {
            logger.trace("Skip setting PO value because document field has no changes: {}", documentField);
            continue;
        }
        if (DocumentFieldWidgetType.Labels == documentField.getWidgetType()) {
            // save labels after PO is saved because we want to make sure it's not new (so we can link to it)
            afterSaveRunnables.add(() -> saveLabels(document, documentField));
        }
        if (setPOValue(po, documentField)) {
            changes = true;
        }
    }
    // 
    // Save the PO
    boolean needsRefresh = false;
    if (changes) {
        // 
        // Actual save
        // TODO: advice the PO to not reload after save.
        InterfaceWrapperHelper.save(po);
        document.markAsNotNew();
        needsRefresh = true;
    } else {
        logger.trace("Skip saving {} because there was no actual change", po);
    }
    // Execute after save runnables
    if (!afterSaveRunnables.isEmpty()) {
        afterSaveRunnables.forEach(r -> r.run());
        needsRefresh = true;
    }
    // Reload the document
    if (needsRefresh) {
        final SqlDocumentEntityDataBindingDescriptor dataBinding = document.getEntityDescriptor().getDataBinding(SqlDocumentEntityDataBindingDescriptor.class);
        final DocumentId idNew = extractDocumentId(po, dataBinding);
        refresh(document, idNew);
    }
    // Notify the parent document that one of it's children were saved
    if (!document.isRootDocument()) {
        document.getParentDocument().onChildSaved(document);
    }
}
Also used : ITrxManager(org.adempiere.ad.trx.api.ITrxManager) SqlDocumentEntityDataBindingDescriptor(de.metas.ui.web.window.descriptor.sql.SqlDocumentEntityDataBindingDescriptor) ArrayList(java.util.ArrayList) DocumentId(de.metas.ui.web.window.datatypes.DocumentId) IDocumentFieldView(de.metas.ui.web.window.model.IDocumentFieldView) PO(org.compiere.model.PO)

Aggregations

IDocumentFieldView (de.metas.ui.web.window.model.IDocumentFieldView)6 DocumentId (de.metas.ui.web.window.datatypes.DocumentId)4 DocumentEntityDescriptor (de.metas.ui.web.window.descriptor.DocumentEntityDescriptor)3 DocumentFieldDescriptor (de.metas.ui.web.window.descriptor.DocumentFieldDescriptor)3 DocumentFieldWidgetType (de.metas.ui.web.window.descriptor.DocumentFieldWidgetType)3 SqlDocumentEntityDataBindingDescriptor (de.metas.ui.web.window.descriptor.sql.SqlDocumentEntityDataBindingDescriptor)3 ArrayList (java.util.ArrayList)3 List (java.util.List)3 AdempiereException (org.adempiere.exceptions.AdempiereException)3 ImmutableList (com.google.common.collect.ImmutableList)2 EntityNotFoundException (de.metas.ui.web.exceptions.EntityNotFoundException)2 WindowConstants (de.metas.ui.web.window.WindowConstants)2 DocumentPath (de.metas.ui.web.window.datatypes.DocumentPath)2 StringLookupValue (de.metas.ui.web.window.datatypes.LookupValue.StringLookupValue)2 DocumentFieldDataBindingDescriptor (de.metas.ui.web.window.descriptor.DocumentFieldDataBindingDescriptor)2 LookupDescriptor (de.metas.ui.web.window.descriptor.LookupDescriptor)2 DocumentsRepository (de.metas.ui.web.window.model.DocumentsRepository)2 Function (java.util.function.Function)2 ITrxManager (org.adempiere.ad.trx.api.ITrxManager)2 InterfaceWrapperHelper (org.adempiere.model.InterfaceWrapperHelper)2