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();
}
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);
}
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()));
}
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));
}
}
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);
}
}
Aggregations