From 3680e6f8dfa08c79bc1f6a3fc86ab30a2d7b7ca2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Sch=C3=B6neberg?= Date: Thu, 10 Aug 2017 15:45:29 +0200 Subject: [PATCH] solve error "Assumption failure: tableName not empty" * solution: extend the API to support multi-table rows (take a look at PPOrderLinesView.getTableNameOrNull()) * also renamed IView.getTableName() to getTableNameOrNull() Exception when opening PP Order issue / receipt https://github.com/metasfresh/metasfresh-webui-api/issues/528 --- .../ui/web/handlingunits/HUEditorView.java | 21 +++++++- .../handlingunits/HUEditorViewRepository.java | 6 ++- .../metas/ui/web/picking/PackageableView.java | 7 ++- .../metas/ui/web/picking/PickingSlotView.java | 7 ++- .../metas/ui/web/pporder/PPOrderLineType.java | 53 +++++++++++++------ .../ui/web/pporder/PPOrderLinesLoader.java | 13 +++-- .../ui/web/pporder/PPOrderLinesView.java | 24 +++++++-- .../process/ViewAsPreconditionsContext.java | 10 +++- .../ADProcessInstancesRepository.java | 4 +- .../de/metas/ui/web/view/DefaultView.java | 7 ++- src/main/java/de/metas/ui/web/view/IView.java | 16 ++++-- 11 files changed, 128 insertions(+), 40 deletions(-) diff --git a/src/main/java/de/metas/ui/web/handlingunits/HUEditorView.java b/src/main/java/de/metas/ui/web/handlingunits/HUEditorView.java index 65f6c66a2..69993aef6 100644 --- a/src/main/java/de/metas/ui/web/handlingunits/HUEditorView.java +++ b/src/main/java/de/metas/ui/web/handlingunits/HUEditorView.java @@ -8,6 +8,8 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import javax.annotation.Nullable; + import org.adempiere.ad.dao.IQueryBL; import org.adempiere.ad.trx.api.ITrx; import org.adempiere.model.InterfaceWrapperHelper; @@ -189,9 +191,24 @@ public ITranslatableString getDescription() return ImmutableTranslatableString.empty(); } + /** + * Always returns {@link I_M_HU#Table_Name}, even if the underlying {@link HUEditorRow}'s type is {@link HUEditorRowType#HUStorage}.
+ * (because i don't understand it well enough) + */ @Override - public String getTableName() - { + public String getTableNameOrNull(@Nullable final DocumentId documentId) + { + // commented out for now, see javadoc + // if (documentId == null) + // { + // return null; + // } + // final HUEditorRow huEditorRow = getById(documentId); + // final HUEditorRowType type = huEditorRow.getType(); + // if (type == HUEditorRowType.HUStorage) + // { + // return I_M_HU_Storage.Table_Name; + // } return I_M_HU.Table_Name; } diff --git a/src/main/java/de/metas/ui/web/handlingunits/HUEditorViewRepository.java b/src/main/java/de/metas/ui/web/handlingunits/HUEditorViewRepository.java index 926fcadd7..c6fd25f1d 100644 --- a/src/main/java/de/metas/ui/web/handlingunits/HUEditorViewRepository.java +++ b/src/main/java/de/metas/ui/web/handlingunits/HUEditorViewRepository.java @@ -306,7 +306,11 @@ private IHUProductStorage getSingleProductStorage(final I_M_HU hu) return productStorage; } - private HUEditorRow createHUEditorRow(final int parent_HU_ID, final int topLevelHUId, final IHUProductStorage huStorage, final boolean processed) + private HUEditorRow createHUEditorRow( + final int parent_HU_ID, + final int topLevelHUId, + @NonNull final IHUProductStorage huStorage, + final boolean processed) { final I_M_HU hu = huStorage.getM_HU(); final int huId = hu.getM_HU_ID(); diff --git a/src/main/java/de/metas/ui/web/picking/PackageableView.java b/src/main/java/de/metas/ui/web/picking/PackageableView.java index ae4b4b057..aee4aa5e8 100644 --- a/src/main/java/de/metas/ui/web/picking/PackageableView.java +++ b/src/main/java/de/metas/ui/web/picking/PackageableView.java @@ -9,6 +9,8 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import javax.annotation.Nullable; + import org.adempiere.ad.dao.IQueryBL; import org.adempiere.model.InterfaceWrapperHelper; import org.adempiere.service.ISysConfigBL; @@ -121,8 +123,11 @@ public Set getReferencingDocumentPaths() return ImmutableSet.of(); } + /** + * Always returns {@link I_M_Packageable_V#Table_Name}. + */ @Override - public String getTableName() + public String getTableNameOrNull(@Nullable final DocumentId ignored) { return I_M_Packageable_V.Table_Name; } diff --git a/src/main/java/de/metas/ui/web/picking/PickingSlotView.java b/src/main/java/de/metas/ui/web/picking/PickingSlotView.java index 7e21c4ba1..102c9e49f 100644 --- a/src/main/java/de/metas/ui/web/picking/PickingSlotView.java +++ b/src/main/java/de/metas/ui/web/picking/PickingSlotView.java @@ -8,6 +8,8 @@ import java.util.function.Supplier; import java.util.stream.Stream; +import javax.annotation.Nullable; + import org.adempiere.ad.trx.api.ITrx; import org.adempiere.util.lang.ExtendedMemorizingSupplier; import org.adempiere.util.lang.impl.TableRecordReference; @@ -128,8 +130,11 @@ public Set getReferencingDocumentPaths() return ImmutableSet.of(); } + /** + * Always returns {@link I_M_PickingSlot#Table_Name} + */ @Override - public String getTableName() + public String getTableNameOrNull(@Nullable final DocumentId ignored) { return I_M_PickingSlot.Table_Name; } diff --git a/src/main/java/de/metas/ui/web/pporder/PPOrderLineType.java b/src/main/java/de/metas/ui/web/pporder/PPOrderLineType.java index e7c0bb035..298d78e5a 100644 --- a/src/main/java/de/metas/ui/web/pporder/PPOrderLineType.java +++ b/src/main/java/de/metas/ui/web/pporder/PPOrderLineType.java @@ -3,12 +3,17 @@ import java.util.stream.Stream; import org.adempiere.util.GuavaCollectors; +import org.eevolution.model.I_PP_Order; +import org.eevolution.model.I_PP_Order_BOMLine; import com.fasterxml.jackson.annotation.JsonValue; import com.google.common.collect.ImmutableMap; +import de.metas.handlingunits.model.I_M_HU; +import de.metas.handlingunits.model.I_M_HU_Storage; import de.metas.ui.web.handlingunits.HUEditorRowType; import de.metas.ui.web.view.IViewRowType; +import lombok.NonNull; /* * #%L @@ -34,39 +39,48 @@ public enum PPOrderLineType implements IViewRowType { - MainProduct("MP", true) // - , BOMLine_Component("CO", false) // - , BOMLine_ByCoProduct("BY", true) // - // - , HU_LU(HUEditorRowType.LU) // - , HU_TU(HUEditorRowType.TU) // - , HU_VHU(HUEditorRowType.VHU) // - , HU_Storage(HUEditorRowType.HUStorage) // + MainProduct("MP", true, I_PP_Order.Table_Name), + BOMLine_Component("CO", false, I_PP_Order_BOMLine.Table_Name), + BOMLine_ByCoProduct("BY", true, I_PP_Order_BOMLine.Table_Name), + + HU_LU(HUEditorRowType.LU, I_M_HU.Table_Name), + HU_TU(HUEditorRowType.TU, I_M_HU.Table_Name), + HU_VHU(HUEditorRowType.VHU, I_M_HU.Table_Name), + HU_Storage(HUEditorRowType.HUStorage, I_M_HU_Storage.Table_Name) ; private final String name; private final String iconName; private final HUEditorRowType huType; - + + private final String tableName; + private final boolean canReceive; private final boolean canIssue; - private PPOrderLineType(final String name, final boolean canReceive) + private PPOrderLineType( + @NonNull final String name, + final boolean canReceive, + @NonNull final String tableName) { this.name = name; this.iconName = canReceive ? "PP_Order_Receive" : "PP_Order_Issue"; // see https://github.com/metasfresh/metasfresh-webui-frontend/issues/675#issuecomment-297016790 this.huType = null; - + this.tableName = tableName; + this.canReceive = canReceive; this.canIssue = !canReceive; } - private PPOrderLineType(HUEditorRowType huType) + private PPOrderLineType( + @NonNull final HUEditorRowType huType, + @NonNull final String tableName) { this.name = huType.getName(); this.iconName = huType.getIconName(); this.huType = huType; - + this.tableName = tableName; + canReceive = false; canIssue = false; } @@ -78,6 +92,11 @@ public String getName() return name; } + public String getTableName() + { + return tableName; + } + @Override public String getIconName() { @@ -98,12 +117,12 @@ public boolean canIssue() { return canIssue; } - + public boolean isBOMLine() { return this == BOMLine_Component || this == BOMLine_ByCoProduct; } - + public boolean isHUOrHUStorage() { return this == HU_LU @@ -115,13 +134,13 @@ public boolean isHUOrHUStorage() public static final PPOrderLineType ofHUEditorRowType(final HUEditorRowType huType) { PPOrderLineType type = huType2type.get(huType); - if(type == null) + if (type == null) { throw new IllegalArgumentException("No type found for " + huType); } return type; } - + private static final ImmutableMap huType2type = Stream.of(values()) .filter(type -> type.huType != null) .collect(GuavaCollectors.toImmutableMapByKey(type -> type.huType)); diff --git a/src/main/java/de/metas/ui/web/pporder/PPOrderLinesLoader.java b/src/main/java/de/metas/ui/web/pporder/PPOrderLinesLoader.java index 5d825b88e..9427ebe0c 100644 --- a/src/main/java/de/metas/ui/web/pporder/PPOrderLinesLoader.java +++ b/src/main/java/de/metas/ui/web/pporder/PPOrderLinesLoader.java @@ -4,6 +4,8 @@ import java.util.Comparator; import java.util.List; +import javax.annotation.Nullable; + import org.adempiere.ad.trx.api.ITrx; import org.adempiere.model.InterfaceWrapperHelper; import org.adempiere.util.GuavaCollectors; @@ -43,6 +45,7 @@ import de.metas.ui.web.window.datatypes.WindowId; import de.metas.ui.web.window.datatypes.json.JSONLookupValue; import lombok.Builder; +import lombok.NonNull; /* * #%L @@ -251,10 +254,14 @@ private PPOrderLineRow createForQty(final I_PP_Order_Qty ppOrderQty, final boole { final HUEditorRow huEditorRow = huEditorRepo.retrieveForHUId(ppOrderQty.getM_HU_ID()); final HUEditorRow parentHUViewRecord = null; - return createForHUViewRecordRecursivelly(ppOrderQty, huEditorRow, parentHUViewRecord, readonly); + return createForHUViewRecordRecursively(ppOrderQty, huEditorRow, parentHUViewRecord, readonly); } - private PPOrderLineRow createForHUViewRecordRecursivelly(final I_PP_Order_Qty ppOrderQty, final HUEditorRow huEditorRow, final HUEditorRow parentHUEditorRow, final boolean readonly) + private PPOrderLineRow createForHUViewRecordRecursively( + @NonNull final I_PP_Order_Qty ppOrderQty, + @NonNull final HUEditorRow huEditorRow, + @Nullable final HUEditorRow parentHUEditorRow, + final boolean readonly) { final PPOrderLineType type = PPOrderLineType.ofHUEditorRowType(huEditorRow.getType()); @@ -300,7 +307,7 @@ private PPOrderLineRow createForHUViewRecordRecursivelly(final I_PP_Order_Qty pp .setQtyPlan(null) // always null .setQty(qty) // - .addIncludedDocumentFrom(huEditorRow.getIncludedRows(), includedHUEditorRow -> createForHUViewRecordRecursivelly(ppOrderQty, includedHUEditorRow, huEditorRow, readonly)) + .addIncludedDocumentFrom(huEditorRow.getIncludedRows(), includedHUEditorRow -> createForHUViewRecordRecursively(ppOrderQty, includedHUEditorRow, huEditorRow, readonly)) // .build(); } diff --git a/src/main/java/de/metas/ui/web/pporder/PPOrderLinesView.java b/src/main/java/de/metas/ui/web/pporder/PPOrderLinesView.java index 35ddd39e0..9e67a14ea 100644 --- a/src/main/java/de/metas/ui/web/pporder/PPOrderLinesView.java +++ b/src/main/java/de/metas/ui/web/pporder/PPOrderLinesView.java @@ -4,6 +4,8 @@ import java.util.Set; import java.util.stream.Stream; +import javax.annotation.Nullable; + import org.adempiere.util.GuavaCollectors; import org.adempiere.util.Services; import org.adempiere.util.lang.ExtendedMemorizingSupplier; @@ -93,8 +95,7 @@ private PPOrderLinesView( @NonNull final JSONViewDataType viewType, final Set referencingDocumentPaths, final int ppOrderId, - final ASIViewRowAttributesProvider asiAttributesProvider - ) + final ASIViewRowAttributesProvider asiAttributesProvider) { this.parentViewId = parentViewId; // might be null this.parentRowId = parentRowId; // might be null @@ -140,7 +141,7 @@ public ViewId getParentViewId() { return parentViewId; } - + @Override public DocumentId getParentRowId() { @@ -165,10 +166,23 @@ public ImmutableSet getReferencingDocumentPaths() return referencingDocumentPaths; } + /** + * @param may be {@code null}; in that case, the method also returns {@code null} + * @return the table name for the given row + */ @Override - public String getTableName() + public String getTableNameOrNull(@Nullable final DocumentId documentId) { - return null; // no particular table (i.e. we have more) + if (documentId == null) + { + return null; + } + final PPOrderLineRow ppOrderLine = getById(documentId); + if (ppOrderLine == null) + { + return null; // just be sure to avoid an NPE in here + } + return ppOrderLine.getType().getTableName(); } public int getPP_Order_ID() diff --git a/src/main/java/de/metas/ui/web/process/ViewAsPreconditionsContext.java b/src/main/java/de/metas/ui/web/process/ViewAsPreconditionsContext.java index 774860e7b..ccbf71918 100644 --- a/src/main/java/de/metas/ui/web/process/ViewAsPreconditionsContext.java +++ b/src/main/java/de/metas/ui/web/process/ViewAsPreconditionsContext.java @@ -83,7 +83,15 @@ private ViewAsPreconditionsContext(@NonNull final IView view, @NonNull final Doc Check.assumeNotNull(view, "Parameter view is not null"); this.view = view; this.windowId = view.getViewId().getWindowId(); - this.tableName = view.getTableName(); + if (selectedDocumentIds.isSingleDocumentId()) + { + this.tableName = view.getTableNameOrNull(selectedDocumentIds.getSingleDocumentId()); + } + else + { + this.tableName = view.getTableNameOrNull(null); + } + this.selectedDocumentIds = selectedDocumentIds; } diff --git a/src/main/java/de/metas/ui/web/process/adprocess/ADProcessInstancesRepository.java b/src/main/java/de/metas/ui/web/process/adprocess/ADProcessInstancesRepository.java index 287e18bd7..d99a5e391 100644 --- a/src/main/java/de/metas/ui/web/process/adprocess/ADProcessInstancesRepository.java +++ b/src/main/java/de/metas/ui/web/process/adprocess/ADProcessInstancesRepository.java @@ -218,13 +218,13 @@ private ProcessInfo createProcessInfo(@NonNull final CreateProcessInstanceReques } else { - tableName = view.getTableName(); + tableName = view.getTableNameOrNull(viewSingleDocumentId); recordId = -1; } } else { - tableName = view.getTableName(); + tableName = view.getTableNameOrNull(null); recordId = -1; } diff --git a/src/main/java/de/metas/ui/web/view/DefaultView.java b/src/main/java/de/metas/ui/web/view/DefaultView.java index ee402a98b..6356bd7a4 100644 --- a/src/main/java/de/metas/ui/web/view/DefaultView.java +++ b/src/main/java/de/metas/ui/web/view/DefaultView.java @@ -194,8 +194,11 @@ public ImmutableSet getReferencingDocumentPaths() return referencingDocumentPaths; } + /** + * Returns the table name as provided by our internal {@link IViewDataRepository}. + */ @Override - public String getTableName() + public String getTableNameOrNull(@Nullable final DocumentId ignored) { return viewDataRepository.getTableName(); } @@ -410,7 +413,7 @@ public List retrieveModelsByIds(final DocumentIdsSelection rowIds, final @Override public void notifyRecordsChanged(final Set recordRefs) { - final String viewTableName = getTableName(); + final String viewTableName = getTableNameOrNull(null); final DocumentIdsSelection rowIds = recordRefs.stream() .filter(recordRef -> Objects.equals(viewTableName, recordRef.getTableName())) diff --git a/src/main/java/de/metas/ui/web/view/IView.java b/src/main/java/de/metas/ui/web/view/IView.java index 7a416042f..ce098e249 100644 --- a/src/main/java/de/metas/ui/web/view/IView.java +++ b/src/main/java/de/metas/ui/web/view/IView.java @@ -4,6 +4,8 @@ import java.util.Set; import java.util.stream.Stream; +import javax.annotation.Nullable; + import org.adempiere.util.lang.impl.TableRecordReference; import org.compiere.util.Evaluatee; @@ -54,8 +56,12 @@ public interface IView Set getReferencingDocumentPaths(); - /** @return table name or null */ - String getTableName(); + /** + * @param documentId can be used by multi-table implementations to return the correct table name for a given row. + * + * @return table name for the given row; might also return {@code null}. + */ + String getTableNameOrNull(@Nullable DocumentId documentId); /** * @return In case this is an included view, this method will return the parent's viewId. Else null will be returned. @@ -115,15 +121,15 @@ default List getByIds(final DocumentIdsSelection rowIds) List getFilters(); List getDefaultOrderBys(); - + default TableRecordReference getTableRecordReferenceOrNull(@NonNull final DocumentId rowId) { final int recordId = rowId.toIntOr(-1); - if(recordId < 0) + if (recordId < 0) { return null; } - return TableRecordReference.of(getTableName(), recordId); + return TableRecordReference.of(getTableNameOrNull(rowId), recordId); } String getSqlWhereClause(DocumentIdsSelection rowIds);