diff --git a/src/main/java/de/metas/ui/web/handlingunits/process/WEBUI_M_HU_Transform.java b/src/main/java/de/metas/ui/web/handlingunits/process/WEBUI_M_HU_Transform.java index 7224d17e4..55b0c15b2 100644 --- a/src/main/java/de/metas/ui/web/handlingunits/process/WEBUI_M_HU_Transform.java +++ b/src/main/java/de/metas/ui/web/handlingunits/process/WEBUI_M_HU_Transform.java @@ -155,7 +155,7 @@ private LookupValuesList getLULookupValues(final LookupDataSourceContext context * * @return a list of HU PI items that link the currently selected TU with a TUperLU-qty and a LU packing instruction. */ - @ProcessParamLookupValuesProvider(parameterName = PARAM_M_HU_PI_Item_ID, dependsOn = { PARAM_Action }, numericKey = true, lookupTableName = I_M_HU_PI_Item.Table_Name) + @ProcessParamLookupValuesProvider(parameterName = PARAM_M_HU_PI_Item_ID, dependsOn = PARAM_Action , numericKey = true, lookupTableName = I_M_HU_PI_Item.Table_Name) private LookupValuesList getM_HU_PI_Item_ID() { return newParametersFiller().getM_HU_PI_Item_IDs(); diff --git a/src/main/java/de/metas/ui/web/handlingunits/process/WebuiHUTransformCommand.java b/src/main/java/de/metas/ui/web/handlingunits/process/WebuiHUTransformCommand.java index 805b34c15..7d12cbd51 100644 --- a/src/main/java/de/metas/ui/web/handlingunits/process/WebuiHUTransformCommand.java +++ b/src/main/java/de/metas/ui/web/handlingunits/process/WebuiHUTransformCommand.java @@ -71,12 +71,12 @@ public class WebuiHUTransformCommand public static enum ActionType { /** - * Invokes {@link HUTransferService#cuToNewCU(I_M_HU, BigDecimal)}. + * Invokes {@link HUTransformService#cuToNewCU(I_M_HU, BigDecimal)}. */ CU_To_NewCU, /** - * Invokes {@link HUTransferService#cuToNewTUs(I_M_HU, BigDecimal, I_M_HU_PI_Item_Product, boolean)}. + * Invokes {@link HUTransformService#cuToNewTUs(I_M_HU, BigDecimal, I_M_HU_PI_Item_Product, boolean)}. */ CU_To_NewTUs, @@ -92,22 +92,22 @@ public static enum ActionType TU_Set_Ownership, /** - * Invokes {@link HUTransferService#cuToExistingTU(I_M_HU, BigDecimal, I_M_HU)}. + * Invokes {@link HUTransformService#cuToExistingTU(I_M_HU, BigDecimal, I_M_HU)}. */ CU_To_ExistingTU, /** - * Invokes {@link HUTransferService#tuToNewTUs(I_M_HU, BigDecimal, boolean)}. + * Invokes {@link HUTransformService#tuToNewTUs(I_M_HU, BigDecimal, boolean)}. */ TU_To_NewTUs, /** - * Invokes {@link HUTransferService#tuToNewLUs(I_M_HU, BigDecimal, I_M_HU_PI_Item, boolean)}. + * Invokes {@link HUTransformService#tuToNewLUs(I_M_HU, BigDecimal, I_M_HU_PI_Item, boolean)}. */ TU_To_NewLUs, /** - * Invokes {@link HUTransferService#tuToExistingLU(I_M_HU, BigDecimal, I_M_HU). + * Invokes {@link HUTransformService#tuToExistingLU(I_M_HU, BigDecimal, I_M_HU). */ TU_To_ExistingLU, diff --git a/src/main/java/de/metas/ui/web/handlingunits/process/WebuiHUTransformParametersFiller.java b/src/main/java/de/metas/ui/web/handlingunits/process/WebuiHUTransformParametersFiller.java index b087c017d..2666c39cb 100644 --- a/src/main/java/de/metas/ui/web/handlingunits/process/WebuiHUTransformParametersFiller.java +++ b/src/main/java/de/metas/ui/web/handlingunits/process/WebuiHUTransformParametersFiller.java @@ -1,6 +1,5 @@ package de.metas.ui.web.handlingunits.process; -import java.math.RoundingMode; import java.util.Collection; import java.util.Comparator; import java.util.HashSet; @@ -12,7 +11,6 @@ import org.adempiere.ad.service.IADReferenceDAO; import org.adempiere.ad.service.IADReferenceDAO.ADRefListItem; import org.adempiere.util.Services; -import org.adempiere.util.StringUtils; import org.compiere.model.I_AD_Process_Para; import org.compiere.model.I_C_BPartner; import org.compiere.util.DisplayType; @@ -237,7 +235,6 @@ public LookupValuesList getM_HU_PI_Item_Products() private static LookupValuesList retrieveHUPItemProductsForNewTU(final HUEditorRow cuRow) { - // final HUEditorRow cuRow = getSingleSelectedRow(); final I_M_Product product = cuRow.getM_Product(); final I_C_BPartner bPartner = cuRow.getM_HU().getC_BPartner(); @@ -380,16 +377,8 @@ public LookupValuesList getM_HU_PI_Item_IDs() return luPIItems.stream() .filter(luPIItem -> luPIItem.getM_HU_PI_Version().isCurrent() && luPIItem.getM_HU_PI_Version().isActive() && luPIItem.getM_HU_PI_Version().getM_HU_PI().isActive()) - .map(luPIItem -> IntegerLookupValue.of(luPIItem.getM_HU_PI_Item_ID(), buildHUPIItemString(luPIItem))) + .map(luPIItem -> IntegerLookupValue.of(luPIItem.getM_HU_PI_Item_ID(), WEBUI_ProcessHelper.buildHUPIItemString(luPIItem))) .sorted(Comparator.comparing(IntegerLookupValue::getDisplayName)) .collect(LookupValuesList.collect()); } - - private static String buildHUPIItemString(final I_M_HU_PI_Item huPIItem) - { - return StringUtils.formatMessage("{} ({} x {})", - huPIItem.getM_HU_PI_Version().getName(), - huPIItem.getQty().setScale(0, RoundingMode.HALF_UP), // it's always integer quantities - huPIItem.getIncluded_HU_PI().getName()); - } } diff --git a/src/main/java/de/metas/ui/web/handlingunits/util/WEBUI_ProcessHelper.java b/src/main/java/de/metas/ui/web/handlingunits/util/WEBUI_ProcessHelper.java index de31c298a..779b0a4a9 100644 --- a/src/main/java/de/metas/ui/web/handlingunits/util/WEBUI_ProcessHelper.java +++ b/src/main/java/de/metas/ui/web/handlingunits/util/WEBUI_ProcessHelper.java @@ -1,16 +1,21 @@ package de.metas.ui.web.handlingunits.util; +import java.math.RoundingMode; import java.util.Comparator; +import java.util.List; import java.util.Properties; -import java.util.stream.Stream; + +import javax.annotation.Nullable; import org.adempiere.service.ISysConfigBL; import org.adempiere.util.Services; +import org.adempiere.util.StringUtils; import org.compiere.model.I_C_BPartner; import org.compiere.model.I_M_Product; import org.compiere.util.Env; import de.metas.handlingunits.IHUPIItemProductDAO; +import de.metas.handlingunits.model.I_M_HU_PI_Item; import de.metas.handlingunits.model.I_M_HU_PI_Item_Product; import de.metas.ui.web.window.datatypes.LookupValue.IntegerLookupValue; import de.metas.ui.web.window.datatypes.LookupValuesList; @@ -53,9 +58,23 @@ public class WEBUI_ProcessHelper * @param bPartner optional, may be null * @return */ - public LookupValuesList retrieveHUPIItemProducts(final Properties ctx, - @NonNull final I_M_Product product, - final I_C_BPartner bPartner) + public LookupValuesList retrieveHUPIItemProducts( + @NonNull final Properties ctx, + @NonNull final I_M_Product product, + @Nullable final I_C_BPartner bPartner) + { + final List list = retrieveHUPIItemProductRecords(ctx, product, bPartner); + + return list.stream() + .sorted(Comparator.comparing(I_M_HU_PI_Item_Product::getName)) + .map(huPIItemProduct -> IntegerLookupValue.of(huPIItemProduct.getM_HU_PI_Item_Product_ID(), huPIItemProduct.getName())) + .collect(LookupValuesList.collect()); + } + + public List retrieveHUPIItemProductRecords( + @NonNull final Properties ctx, + @NonNull final I_M_Product product, + @Nullable final I_C_BPartner bPartner) { final IHUPIItemProductDAO hupiItemProductDAO = Services.get(IHUPIItemProductDAO.class); final ISysConfigBL sysConfigBL = Services.get(ISysConfigBL.class); @@ -63,13 +82,16 @@ public LookupValuesList retrieveHUPIItemProducts(final Properties ctx, final boolean allowInfiniteCapacity = sysConfigBL.getBooleanValue(SYSCONFIG_ALLOW_INFINIT_CAPACITY_TUS, true, Env.getAD_Client_ID(ctx), Env.getAD_Org_ID(ctx)); - final Stream stream = hupiItemProductDAO - .retrieveTUs(ctx, product, bPartner, allowInfiniteCapacity) - .stream(); - - return stream - .sorted(Comparator.comparing(I_M_HU_PI_Item_Product::getName)) - .map(huPIItemProduct -> IntegerLookupValue.of(huPIItemProduct.getM_HU_PI_Item_Product_ID(), huPIItemProduct.getName())) - .collect(LookupValuesList.collect()); + final List list = hupiItemProductDAO + .retrieveTUs(ctx, product, bPartner, allowInfiniteCapacity); + return list; + } + + public String buildHUPIItemString(final I_M_HU_PI_Item huPIItem) + { + return StringUtils.formatMessage("{} ({} x {})", + huPIItem.getM_HU_PI_Version().getName(), + huPIItem.getQty().setScale(0, RoundingMode.HALF_UP), // it's always integer quantities + huPIItem.getIncluded_HU_PI().getName()); } } diff --git a/src/main/java/de/metas/ui/web/pporder/PPOrderLineRow.java b/src/main/java/de/metas/ui/web/pporder/PPOrderLineRow.java index dc11699fc..0cee09697 100644 --- a/src/main/java/de/metas/ui/web/pporder/PPOrderLineRow.java +++ b/src/main/java/de/metas/ui/web/pporder/PPOrderLineRow.java @@ -252,13 +252,13 @@ public IViewRowAttributes getAttributes() throws EntityNotFoundException { if (attributesSupplier == null) { - throw new EntityNotFoundException("Document does not support attributes"); + throw new EntityNotFoundException("This PPOrderLineRow does not support attributes; this=" + this); } final IViewRowAttributes attributes = attributesSupplier.get(); if (attributes == null) { - throw new EntityNotFoundException("Document does not support attributes"); + throw new EntityNotFoundException("This PPOrderLineRow does not support attributes; this=" + this); } return attributes; } diff --git a/src/main/java/de/metas/ui/web/pporder/process/PackingInfoProcessParams.java b/src/main/java/de/metas/ui/web/pporder/process/PackingInfoProcessParams.java index 044deeca3..2ae954175 100644 --- a/src/main/java/de/metas/ui/web/pporder/process/PackingInfoProcessParams.java +++ b/src/main/java/de/metas/ui/web/pporder/process/PackingInfoProcessParams.java @@ -1,8 +1,9 @@ package de.metas.ui.web.pporder.process; +import static org.adempiere.model.InterfaceWrapperHelper.loadOutOfTrx; + import java.math.BigDecimal; import java.util.List; -import java.util.stream.Collectors; import javax.annotation.Nullable; @@ -11,8 +12,11 @@ import org.adempiere.exceptions.FillMandatoryException; import org.adempiere.model.InterfaceWrapperHelper; import org.adempiere.util.Services; +import org.compiere.model.I_C_BPartner; +import org.compiere.model.I_M_Product; import org.compiere.util.Env; +import de.metas.handlingunits.IHUPIItemProductDAO; import de.metas.handlingunits.IHandlingUnitsDAO; import de.metas.handlingunits.allocation.ILUTUConfigurationFactory; import de.metas.handlingunits.impl.IDocumentLUTUConfigurationManager; @@ -20,11 +24,13 @@ import de.metas.handlingunits.model.I_M_HU_PI; import de.metas.handlingunits.model.I_M_HU_PI_Item; import de.metas.handlingunits.model.I_M_HU_PI_Item_Product; -import de.metas.handlingunits.model.I_M_HU_PI_Version; -import de.metas.handlingunits.model.X_M_HU_PI_Version; +import de.metas.printing.esb.base.util.Check; import de.metas.process.IProcessDefaultParametersProvider; import de.metas.process.Param; import de.metas.quantity.Quantity; +import de.metas.ui.web.handlingunits.util.WEBUI_ProcessHelper; +import de.metas.ui.web.window.datatypes.LookupValue.IntegerLookupValue; +import de.metas.ui.web.window.datatypes.LookupValuesList; import lombok.Builder; import lombok.NonNull; @@ -58,9 +64,9 @@ public class PackingInfoProcessParams @Param(parameterName = PARAM_M_HU_PI_Item_Product_ID) private int tu_HU_PI_Item_Product_ID; // - public static final String PARAM_M_LU_HU_PI_ID = "M_LU_HU_PI_ID"; - @Param(parameterName = PARAM_M_LU_HU_PI_ID) - private int lu_HU_PI_ID; + public static final String PARAM_PARAM_M_HU_PI_Item_ID = "M_HU_PI_Item_ID"; + @Param(parameterName = PARAM_PARAM_M_HU_PI_Item_ID) + private int lu_PI_Item_ID; // public static final String PARAM_QtyCU = "QtyCU"; @Param(parameterName = PARAM_QtyCU) @@ -79,13 +85,16 @@ public class PackingInfoProcessParams private final BigDecimal enforceAvailableQtyTU; private final boolean enforceOneLUorTU; + private final boolean enforcePhysicalTU; + @Builder - public PackingInfoProcessParams( // - @NonNull final IDocumentLUTUConfigurationManager defaultLUTUConfigManager // - , final BigDecimal enforceAvailableQtyTU // - , final boolean enforceOneLUorTU // - ) + public PackingInfoProcessParams( + @NonNull final IDocumentLUTUConfigurationManager defaultLUTUConfigManager, + @Nullable final BigDecimal enforceAvailableQtyTU, + final boolean enforceOneLUorTU, + final boolean enforcePhysicalTU) { + this.enforcePhysicalTU = enforcePhysicalTU; this.defaultLUTUConfigManager = defaultLUTUConfigManager; this.enforceAvailableQtyTU = enforceAvailableQtyTU; this.enforceOneLUorTU = enforceOneLUorTU; @@ -94,12 +103,13 @@ public PackingInfoProcessParams( // public Object getParameterDefaultValue(final String parameterName) { final I_M_HU_LUTU_Configuration defaultLUTUConfig = getDefaultLUTUConfig(); + switch (parameterName) { case PARAM_M_HU_PI_Item_Product_ID: return defaultLUTUConfig.getM_HU_PI_Item_Product_ID(); - case PARAM_M_LU_HU_PI_ID: - return defaultLUTUConfig.getM_LU_HU_PI_ID(); + case PARAM_PARAM_M_HU_PI_Item_ID: + return defaultLUTUConfig.getM_LU_HU_PI_Item_ID(); case PARAM_QtyCU: return defaultLUTUConfig.getQtyCU(); case PARAM_QtyTU: @@ -111,6 +121,43 @@ public Object getParameterDefaultValue(final String parameterName) } } + /** + * + * @return a list of PI item products that match the selected CU's product and partner, sorted by name. + */ + public LookupValuesList getM_HU_PI_Item_Products() + { + final I_M_HU_LUTU_Configuration defaultLUTUConfig = getDefaultLUTUConfig(); + + final I_M_Product product = defaultLUTUConfig.getM_Product(); + final I_C_BPartner bPartner = defaultLUTUConfig.getC_BPartner(); + + return WEBUI_ProcessHelper.retrieveHUPIItemProducts(Env.getCtx(), product, bPartner); + } + + public LookupValuesList getM_HU_PI_Item_IDs(I_M_HU_PI_Item_Product pip) + { + if (pip == null) + { + return LookupValuesList.EMPTY; + } + + final List luPIItems = getAvailableLuPIItems(pip, getDefaultLUTUConfig().getC_BPartner()); + return luPIItems.stream() + .map(luPIItem -> IntegerLookupValue.of(luPIItem.getM_HU_PI_Item_ID(), WEBUI_ProcessHelper.buildHUPIItemString(luPIItem))) + .collect(LookupValuesList.collect()); + } + + private List getAvailableLuPIItems(I_M_HU_PI_Item_Product pip, final I_C_BPartner bPartner) + { + final IHandlingUnitsDAO handlingUnitsDAO = Services.get(IHandlingUnitsDAO.class); + + final I_M_HU_PI piOfCurrentPip = pip.getM_HU_PI_Item().getM_HU_PI_Version().getM_HU_PI(); + + final List luPIItems = handlingUnitsDAO.retrieveParentPIItemsForParentPI(piOfCurrentPip, null, bPartner); + return luPIItems; + } + public I_M_HU_LUTU_Configuration getDefaultLUTUConfig() { if (_defaultLUTUConfig == null) @@ -129,19 +176,68 @@ else if (enforceAvailableQtyTU != null) adjustDefaultLUTUConfig_EnforceAvailableTUs(defaultLUTUConfig, enforceAvailableQtyTU); } + if (enforcePhysicalTU) + { + boolean needToFallback; + if (defaultLUTUConfig.getM_HU_PI_Item_Product_ID() <= 0) + { + needToFallback = true; + } + else + { + final IHUPIItemProductDAO hupiItemProductDAO = Services.get(IHUPIItemProductDAO.class); + needToFallback = defaultLUTUConfig.getM_HU_PI_Item_Product_ID() == hupiItemProductDAO.retrieveVirtualPIMaterialItemProduct(Env.getCtx()).getM_HU_PI_Item_Product_ID(); + } + if (needToFallback) + { + final List availableHUPIItemProductRecords = WEBUI_ProcessHelper.retrieveHUPIItemProductRecords(Env.getCtx(), defaultLUTUConfig.getM_Product(), defaultLUTUConfig.getC_BPartner()); + Check.errorIf(availableHUPIItemProductRecords.isEmpty(), + "There is no non-virtual M_HU_PI_Item_Product value for the given product and bPartner; product={}; bPartner={}", + defaultLUTUConfig.getM_Product(), defaultLUTUConfig.getC_BPartner()); + + final I_M_HU_PI_Item_Product pip = availableHUPIItemProductRecords.get(0); + defaultLUTUConfig.setM_HU_PI_Item_Product(pip); + defaultLUTUConfig.setM_TU_HU_PI_ID(pip.getM_HU_PI_Item().getM_HU_PI_Version().getM_HU_PI_ID()); + defaultLUTUConfig.setQtyCU(pip.getQty()); + + final List luPIItems = getAvailableLuPIItems(pip, defaultLUTUConfig.getC_BPartner()); + if (luPIItems.isEmpty()) + { + defaultLUTUConfig.setM_LU_HU_PI_Item(null); + defaultLUTUConfig.setM_LU_HU_PI(null); + } + else + { + final I_M_HU_PI_Item luPiItem = luPIItems.get(0); + defaultLUTUConfig.setM_LU_HU_PI_Item(luPiItem); + defaultLUTUConfig.setQtyTU(luPiItem.getQty()); + defaultLUTUConfig.setM_LU_HU_PI_ID(luPiItem.getM_HU_PI_Version().getM_HU_PI_ID()); + } + + } + } + // // Make sure nobody is overriding the existing configuration if (defaultLUTUConfig.getM_HU_LUTU_Configuration_ID() > 0) { InterfaceWrapperHelper.setSaveDeleteDisabled(defaultLUTUConfig, true); } - _defaultLUTUConfig = defaultLUTUConfig; } return _defaultLUTUConfig; + } - private void adjustDefaultLUTUConfig_EnforceOneLUorTU(@NonNull final I_M_HU_LUTU_Configuration defaultLUTUConfig, @Nullable final BigDecimal availableQtyTU) + /** + * Modifies the given {@code defaultLUTUConfig} such that one top level HU (either LU or TU) is created. + * + * @param defaultLUTUConfig + * @param availableQtyTU optional, may be {@code null}. If given, and the given {@code defaultLUTUConfig}'s top level HU is an LU, then this is the number of TUs within the LU. + */ + private void adjustDefaultLUTUConfig_EnforceOneLUorTU( + @NonNull final I_M_HU_LUTU_Configuration defaultLUTUConfig, + @Nullable final BigDecimal availableQtyTU) { if (lutuConfigurationFactory.isNoLU(defaultLUTUConfig)) { @@ -169,10 +265,17 @@ private void adjustDefaultLUTUConfig_EnforceOneLUorTU(@NonNull final I_M_HU_LUTU } } } - } - private void adjustDefaultLUTUConfig_EnforceAvailableTUs(@NonNull final I_M_HU_LUTU_Configuration defaultLUTUConfig, @NonNull final BigDecimal availableQtyTU) + /** + * Modifies the given {@code defaultLUTUConfig} such that the TU quantity and (if applicable) also the LU quantity are consistent with the given {@code availableQtyTU}. + * + * @param defaultLUTUConfig + * @param availableQtyTU + */ + private void adjustDefaultLUTUConfig_EnforceAvailableTUs( + @NonNull final I_M_HU_LUTU_Configuration defaultLUTUConfig, + @NonNull final BigDecimal availableQtyTU) { // // TU @@ -230,11 +333,11 @@ public I_M_HU_LUTU_Configuration createNewLUTUConfig() final I_M_HU_LUTU_Configuration defaultLUTUConfig = getDefaultLUTUConfig(); // Validate parameters - final int M_LU_HU_PI_ID = getLU_HU_PI_ID(); // not mandatory + final int lu_PI_Item_ID = getLuPiItemId(); // not mandatory final int M_HU_PI_Item_Product_ID = getTU_HU_PI_Item_Product_ID(); final BigDecimal qtyCU = getQtyCU(); final BigDecimal qtyTU = getQtyTU(); - + if (M_HU_PI_Item_Product_ID <= 0) { throw new FillMandatoryException(PARAM_M_HU_PI_Item_Product_ID); @@ -267,34 +370,18 @@ public I_M_HU_LUTU_Configuration createNewLUTUConfig() // // LU - if (M_LU_HU_PI_ID > 0) + if (lu_PI_Item_ID > 0) { final BigDecimal qtyLU = getQtyLU(); if (qtyLU == null || qtyLU.signum() <= 0) { throw new FillMandatoryException(PARAM_QtyLU); } - - final I_M_HU_PI luPI = InterfaceWrapperHelper.create(Env.getCtx(), M_LU_HU_PI_ID, I_M_HU_PI.class, ITrx.TRXNAME_None); - - final IHandlingUnitsDAO handlingUnitsDAO = Services.get(IHandlingUnitsDAO.class); - final I_M_HU_PI_Version luPIV = handlingUnitsDAO.retrievePICurrentVersion(luPI); - final List luPI_ItemsAvailable = handlingUnitsDAO.retrieveParentPIItemsForParentPI(tuPI, X_M_HU_PI_Version.HU_UNITTYPE_LoadLogistiqueUnit, lutuConfigNew.getC_BPartner()); - final I_M_HU_PI_Item luPI_Item = luPI_ItemsAvailable - .stream() - .filter(piItem -> piItem.getM_HU_PI_Version_ID() == luPIV.getM_HU_PI_Version_ID()) - .findFirst() - .orElseThrow(() -> { - final String luPI_ItemsAvailableStr = luPI_ItemsAvailable.stream() - .map(item -> item.getM_HU_PI_Version().getM_HU_PI().getName()) - .distinct() - .collect(Collectors.joining(", ")); - return new AdempiereException(tuPI.getName() + " cannot be loaded to " + luPI.getName() - + "\n Available LU PI items: " + luPI_ItemsAvailableStr); - });; - - lutuConfigNew.setM_LU_HU_PI(luPI); + + final I_M_HU_PI_Item luPI_Item = loadOutOfTrx(lu_PI_Item_ID, I_M_HU_PI_Item.class); + lutuConfigNew.setM_LU_HU_PI_Item(luPI_Item); + lutuConfigNew.setM_LU_HU_PI(luPI_Item.getM_HU_PI_Version().getM_HU_PI()); lutuConfigNew.setQtyLU(qtyLU); lutuConfigNew.setIsInfiniteQtyLU(false); } @@ -309,14 +396,14 @@ public I_M_HU_LUTU_Configuration createNewLUTUConfig() return lutuConfigNew; } - public int getLU_HU_PI_ID() + public int getLuPiItemId() { - return lu_HU_PI_ID; + return lu_PI_Item_ID; } - public void setLU_HU_PI_ID(final int lu_HU_PI_ID) + public void setLuPiItemId(final int lu_PI_Item_ID) { - this.lu_HU_PI_ID = lu_HU_PI_ID; + this.lu_PI_Item_ID = lu_PI_Item_ID; } public int getTU_HU_PI_Item_Product_ID() diff --git a/src/main/java/de/metas/ui/web/pporder/process/WEBUI_PP_Order_Receipt.java b/src/main/java/de/metas/ui/web/pporder/process/WEBUI_PP_Order_Receipt.java index 049da7a34..d3aee6d6e 100644 --- a/src/main/java/de/metas/ui/web/pporder/process/WEBUI_PP_Order_Receipt.java +++ b/src/main/java/de/metas/ui/web/pporder/process/WEBUI_PP_Order_Receipt.java @@ -11,6 +11,8 @@ import de.metas.handlingunits.impl.IDocumentLUTUConfigurationManager; import de.metas.handlingunits.model.I_M_HU_LUTU_Configuration; +import de.metas.handlingunits.model.I_M_HU_PI_Item; +import de.metas.handlingunits.model.I_M_HU_PI_Item_Product; import de.metas.handlingunits.model.I_PP_Order; import de.metas.handlingunits.pporder.api.IHUPPOrderBL; import de.metas.handlingunits.pporder.api.IPPOrderReceiptHUProducer; @@ -24,7 +26,10 @@ import de.metas.ui.web.pporder.PPOrderLineRow; import de.metas.ui.web.pporder.PPOrderLineType; import de.metas.ui.web.pporder.PPOrderLinesView; +import de.metas.ui.web.process.descriptor.ProcessParamLookupValuesProvider; import de.metas.ui.web.view.IViewsRepository; +import de.metas.ui.web.window.datatypes.LookupValuesList; +import lombok.NonNull; /* * #%L @@ -56,21 +61,20 @@ public class WEBUI_PP_Order_Receipt private final transient IHUPPOrderBL huPPOrderBL = Services.get(IHUPPOrderBL.class); private final transient IViewsRepository viewsRepo = Adempiere.getBean(IViewsRepository.class); - // - // Parameters - @Param(parameterName = PackingInfoProcessParams.PARAM_M_HU_PI_Item_Product_ID) - private int p_M_HU_PI_Item_Product_ID; - // - @Param(parameterName = PackingInfoProcessParams.PARAM_M_LU_HU_PI_ID) - private int p_M_LU_HU_PI_ID; - // - @Param(parameterName = PackingInfoProcessParams.PARAM_QtyCU) + // parameters + @Param(parameterName = PackingInfoProcessParams.PARAM_M_HU_PI_Item_Product_ID, mandatory = true) + private I_M_HU_PI_Item_Product p_M_HU_PI_Item_Product; + + @Param(parameterName = PackingInfoProcessParams.PARAM_PARAM_M_HU_PI_Item_ID, mandatory = false) + private I_M_HU_PI_Item p_M_HU_PI_Item; + + @Param(parameterName = PackingInfoProcessParams.PARAM_QtyCU, mandatory = true) private BigDecimal p_QtyCU; - // - @Param(parameterName = PackingInfoProcessParams.PARAM_QtyTU) + + @Param(parameterName = PackingInfoProcessParams.PARAM_QtyTU, mandatory = true) private BigDecimal p_QtyTU; - // - @Param(parameterName = PackingInfoProcessParams.PARAM_QtyLU) + + @Param(parameterName = PackingInfoProcessParams.PARAM_QtyLU, mandatory = false) private BigDecimal p_QtyLU; private transient PackingInfoProcessParams _packingInfoParams; @@ -81,12 +85,19 @@ private PackingInfoProcessParams getPackingInfoParams() { _packingInfoParams = PackingInfoProcessParams.builder() .defaultLUTUConfigManager(createDefaultLUTUConfigManager(getSingleSelectedRow())) + .enforcePhysicalTU(true) // https://github.com/metasfresh/metasfresh-webui-api/issues/528 .build(); } // Update it - _packingInfoParams.setTU_HU_PI_Item_Product_ID(p_M_HU_PI_Item_Product_ID); - _packingInfoParams.setLU_HU_PI_ID(p_M_LU_HU_PI_ID); + if (p_M_HU_PI_Item_Product != null) + { + _packingInfoParams.setTU_HU_PI_Item_Product_ID(p_M_HU_PI_Item_Product.getM_HU_PI_Item_Product_ID()); + } + if (p_M_HU_PI_Item != null) + { + _packingInfoParams.setLuPiItemId(p_M_HU_PI_Item.getM_HU_PI_Item_ID()); + } _packingInfoParams.setQtyLU(p_QtyLU); _packingInfoParams.setQtyTU(p_QtyTU); _packingInfoParams.setQtyCU(p_QtyCU); @@ -94,7 +105,7 @@ private PackingInfoProcessParams getPackingInfoParams() return _packingInfoParams; } - private IDocumentLUTUConfigurationManager createDefaultLUTUConfigManager(final PPOrderLineRow row) + private IDocumentLUTUConfigurationManager createDefaultLUTUConfigManager(@NonNull final PPOrderLineRow row) { final PPOrderLineType type = row.getType(); if (type == PPOrderLineType.MainProduct) @@ -150,14 +161,14 @@ protected ProcessPreconditionsResolution checkPreconditionsApplicable() return ProcessPreconditionsResolution.rejectWithInternalReason("not planning or in review"); } - final PPOrderLineRow ppOrderLine = getSingleSelectedRow(); - if (!ppOrderLine.isReceipt()) + final PPOrderLineRow ppOrderLineRow = getSingleSelectedRow(); + if (!ppOrderLineRow.isReceipt()) { - return ProcessPreconditionsResolution.reject("not a receipt line"); + return ProcessPreconditionsResolution.rejectWithInternalReason("ppOrderLineRow is not a receipt line; ppOrderLineRow=" + ppOrderLineRow); } - if (ppOrderLine.isProcessed()) + if (ppOrderLineRow.isProcessed()) { - return ProcessPreconditionsResolution.rejectWithInternalReason("row processed"); + return ProcessPreconditionsResolution.rejectWithInternalReason("ppOrderLineRow is already processed; ppOrderLineRow=" + ppOrderLineRow); } // @@ -175,12 +186,36 @@ protected ProcessPreconditionsResolution checkPreconditionsApplicable() return ProcessPreconditionsResolution.accept(); } + /** + * metasfresh/metasfresh-webui-api#528: never return the "No Packing Item" a.k.a. virtual {@code M_HU_PI_Item_Product_ID}. + */ @Override public Object getParameterDefaultValue(final IProcessDefaultParameter parameter) { return getPackingInfoParams().getParameterDefaultValue(parameter.getColumnName()); } + /** + * + * @return a list of PI item products that match the selected CU's product and partner, sorted by name. + */ + @ProcessParamLookupValuesProvider(parameterName = PackingInfoProcessParams.PARAM_M_HU_PI_Item_Product_ID, dependsOn = {}, numericKey = true, lookupTableName = I_M_HU_PI_Item_Product.Table_Name) + private LookupValuesList getM_HU_PI_Item_Products() + { + return getPackingInfoParams().getM_HU_PI_Item_Products(); + } + + /** + * For the currently selected pip this method loads att + * + * @return + */ + @ProcessParamLookupValuesProvider(parameterName = PackingInfoProcessParams.PARAM_PARAM_M_HU_PI_Item_ID, dependsOn = PackingInfoProcessParams.PARAM_M_HU_PI_Item_Product_ID, numericKey = true, lookupTableName = I_M_HU_PI_Item.Table_Name) + private LookupValuesList getM_HU_PI_Item_IDs() + { + return getPackingInfoParams().getM_HU_PI_Item_IDs(p_M_HU_PI_Item_Product); + } + @Override @RunOutOfTrx protected String doIt() throws Exception diff --git a/src/main/java/de/metas/ui/web/pporder/process/WEBUI_PP_Order_Template.java b/src/main/java/de/metas/ui/web/pporder/process/WEBUI_PP_Order_Template.java index 67e0b8b52..fded65e10 100644 --- a/src/main/java/de/metas/ui/web/pporder/process/WEBUI_PP_Order_Template.java +++ b/src/main/java/de/metas/ui/web/pporder/process/WEBUI_PP_Order_Template.java @@ -34,7 +34,7 @@ */ public abstract class WEBUI_PP_Order_Template extends ViewBasedProcessTemplate -// implements IProcessPrecondition // let the extending class to activate this interface +// implements IProcessPrecondition // let the extending class activate this interface { @Override protected final PPOrderLinesView getView() diff --git a/src/main/java/de/metas/ui/web/process/descriptor/ProcessParamLookupValuesProvider.java b/src/main/java/de/metas/ui/web/process/descriptor/ProcessParamLookupValuesProvider.java index 58e3ba229..20ff3ebbd 100644 --- a/src/main/java/de/metas/ui/web/process/descriptor/ProcessParamLookupValuesProvider.java +++ b/src/main/java/de/metas/ui/web/process/descriptor/ProcessParamLookupValuesProvider.java @@ -46,7 +46,7 @@ *
  • parameters (if any) can be: {@link LookupDataSourceContext} * * - * + * Note: please take care that the respective parameter's default value is among the list returned by your method implementation. * * @author metas-dev * @@ -65,7 +65,7 @@ /** true if we will provide {@link IntegerLookupValue}s, else {@link StringLookupValue}s are assumed */ boolean numericKey(); - + LookupSource lookupSource() default LookupSource.list; /** optional lookup table name; needed for zoom into */ diff --git a/src/main/java/de/metas/ui/web/view/json/JSONViewRow.java b/src/main/java/de/metas/ui/web/view/json/JSONViewRow.java index ba84c972d..8313dd577 100644 --- a/src/main/java/de/metas/ui/web/view/json/JSONViewRow.java +++ b/src/main/java/de/metas/ui/web/view/json/JSONViewRow.java @@ -109,10 +109,7 @@ private static JSONViewRow ofRow(final IViewRow row, final String adLanguage) // // Attributes - if (row.hasAttributes()) - { - jsonRow.supportAttributes = true; - } + jsonRow.supportAttributes = row.hasAttributes(); // // Included views diff --git a/src/main/java/de/metas/ui/web/window/datatypes/LookupValue.java b/src/main/java/de/metas/ui/web/window/datatypes/LookupValue.java index 08a06bbbc..35fd00bd7 100644 --- a/src/main/java/de/metas/ui/web/window/datatypes/LookupValue.java +++ b/src/main/java/de/metas/ui/web/window/datatypes/LookupValue.java @@ -11,6 +11,9 @@ import de.metas.i18n.ITranslatableString; import de.metas.i18n.ImmutableTranslatableString; +import de.metas.process.IProcessDefaultParametersProvider; +import de.metas.process.JavaProcess; +import de.metas.ui.web.process.descriptor.ProcessParamLookupValuesProvider; /* * #%L @@ -25,11 +28,11 @@ * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public - * License along with this program. If not, see + * License along with this program. If not, see * . * #L% */ @@ -102,16 +105,16 @@ public static final LookupValue fromNamePair(final NamePair namePair, final Stri final LookupValue defaultValue = null; return fromNamePair(namePair, adLanguage, defaultValue); } - + public static final LookupValue fromNamePair(final NamePair namePair, final String adLanguage, final LookupValue defaultValue) { if (namePair == null) { return defaultValue; } - + final ITranslatableString displayNameTrl; - if(adLanguage == null) + if (adLanguage == null) { displayNameTrl = ImmutableTranslatableString.anyLanguage(namePair.getName()); } @@ -119,7 +122,7 @@ public static final LookupValue fromNamePair(final NamePair namePair, final Stri { displayNameTrl = ImmutableTranslatableString.singleLanguage(adLanguage, namePair.getName()); } - + if (namePair instanceof ValueNamePair) { final ValueNamePair vnp = (ValueNamePair)namePair; @@ -190,13 +193,12 @@ public String getDisplayName() { return displayName.getDefaultValue(); } - + public String getDisplayName(final String adLanguage) { return displayName.translate(adLanguage); } - public ITranslatableString getDisplayNameTrl() { return displayName; @@ -225,13 +227,12 @@ public static final StringLookupValue of(final String value, final String displa { return new StringLookupValue(value, ImmutableTranslatableString.constant(displayName)); } - + public static final StringLookupValue of(final String value, final ITranslatableString displayName) { return new StringLookupValue(value, displayName); } - public static final StringLookupValue unknown(final String value) { return new StringLookupValue(value, ImmutableTranslatableString.constant("<" + value + ">")); @@ -257,17 +258,24 @@ public int getIdAsInt() public static final class IntegerLookupValue extends LookupValue { + /** + * Create a new value using the given {@code displayName} as a constant string that is valid in any language and thus never needs translation. + * Note: without "anyLanguage", you can run into trouble when combining {@link ProcessParamLookupValuesProvider} and {@link IProcessDefaultParametersProvider} in one {@link JavaProcess} implementation. + * + * @param id + * @param displayName + * @return + */ public static final IntegerLookupValue of(final int id, final String displayName) { - return new IntegerLookupValue(id, ImmutableTranslatableString.constant(displayName)); + return new IntegerLookupValue(id, ImmutableTranslatableString.anyLanguage(displayName)); } - + public static final IntegerLookupValue of(final int id, final ITranslatableString displayName) { return new IntegerLookupValue(id, displayName); } - public static final IntegerLookupValue of(final StringLookupValue stringLookupValue) { if (stringLookupValue == null)