Java tutorial
package de.metas.ui.web.picking.pickingslot; import java.math.BigDecimal; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.stream.Stream; import org.adempiere.warehouse.LocatorId; import org.adempiere.warehouse.WarehouseId; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Maps; import de.metas.handlingunits.HuId; import de.metas.i18n.ITranslatableString; import de.metas.picking.api.PickingSlotId; import de.metas.product.ProductId; import de.metas.ui.web.handlingunits.HUEditorRowType; import de.metas.ui.web.handlingunits.WEBUI_HU_Constants; import de.metas.ui.web.picking.PickingConstants; import de.metas.ui.web.view.IViewRow; import de.metas.ui.web.view.ViewId; import de.metas.ui.web.view.descriptor.annotation.ViewColumn; import de.metas.ui.web.view.descriptor.annotation.ViewColumn.ViewColumnLayout; import de.metas.ui.web.view.descriptor.annotation.ViewColumnHelper; import de.metas.ui.web.view.json.JSONViewDataType; import de.metas.ui.web.window.datatypes.DocumentId; import de.metas.ui.web.window.datatypes.DocumentPath; import de.metas.ui.web.window.datatypes.LookupValue; import de.metas.ui.web.window.datatypes.MediaType; import de.metas.ui.web.window.datatypes.json.JSONLookupValue; import de.metas.ui.web.window.descriptor.DocumentFieldWidgetType; import lombok.Builder; import lombok.NonNull; import lombok.ToString; /* * #%L * metasfresh-webui-api * %% * Copyright (C) 2017 metas GmbH * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 2 of the * License, or (at your option) any later version. * * 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 * 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 * <http://www.gnu.org/licenses/gpl-2.0.html>. * #L% */ /** * Rows shown in {@link PickingSlotView}. One row can represent a picking slot, a TU or a picked good (CU). * * @author metas-dev <dev@metasfresh.com> * */ @ToString public final class PickingSlotRow implements IViewRow { public static PickingSlotRow cast(final IViewRow row) { return (PickingSlotRow) row; } private final PickingSlotRowId pickingSlotRowId; private final PickingSlotRowType type; private final DocumentPath documentPath; private final boolean processed; private final ImmutableMap<PickingSlotRowId, PickingSlotRow> includedHURows; private transient ImmutableMap<String, Object> _fieldNameAndJsonValues; // lazy private final ViewId includedViewId; // // Picking slot private final LookupValue pickingSlotBPartner; private final LookupValue pickingSlotBPLocation; private final LookupValue pickingSlotWarehouse; private final LocatorId pickingSlotLocatorId; private final ITranslatableString pickingSlotCaption; // // HU private final boolean huTopLevel; @ViewColumn(captionKey = "HUCode", widgetType = DocumentFieldWidgetType.Text, layouts = { @ViewColumnLayout(when = JSONViewDataType.grid, seqNo = 10), @ViewColumnLayout(when = JSONViewDataType.includedView, seqNo = 10) }) private final String huCode; @ViewColumn(captionKey = "M_Product_ID", widgetType = DocumentFieldWidgetType.Lookup, layouts = { @ViewColumnLayout(when = JSONViewDataType.grid, seqNo = 30), @ViewColumnLayout(when = JSONViewDataType.includedView, seqNo = 30) }) private final JSONLookupValue huProduct; @ViewColumn(captionKey = "M_HU_PI_Item_Product_ID", widgetType = DocumentFieldWidgetType.Text, // restrictToMediaTypes = { MediaType.SCREEN }, // layouts = { @ViewColumnLayout(when = JSONViewDataType.grid, seqNo = 40), @ViewColumnLayout(when = JSONViewDataType.includedView, seqNo = 40) }) private final String huPackingInfo; @ViewColumn(captionKey = "QtyCU", widgetType = DocumentFieldWidgetType.Quantity, layouts = { @ViewColumnLayout(when = JSONViewDataType.grid, seqNo = 50), @ViewColumnLayout(when = JSONViewDataType.includedView, seqNo = 50) }) private final BigDecimal huQtyCU; @Builder(builderMethodName = "fromSourceHUBuilder", builderClassName = "FromSourceHUBuilder") private PickingSlotRow(final HuId huId, final HUEditorRowType huEditorRowType, final String huCode, final JSONLookupValue product, final String packingInfo, final BigDecimal qtyCU, final boolean topLevelHU) { pickingSlotRowId = PickingSlotRowId.ofSourceHU(huId); this.type = PickingSlotRowType.forPickingHuRow(huEditorRowType); processed = true; documentPath = DocumentPath.rootDocumentPath(WEBUI_HU_Constants.WEBUI_HU_Window_ID, huId); // // HU this.huCode = huCode; huProduct = product; huPackingInfo = packingInfo; huQtyCU = qtyCU; huTopLevel = topLevelHU; // // Picking slot info pickingSlotWarehouse = null; pickingSlotLocatorId = null; pickingSlotBPartner = null; pickingSlotBPLocation = null; pickingSlotCaption = null; // // Included rows - we don't show any this.includedHURows = ImmutableMap.of(); this.includedViewId = null; } /** * Picking slot row constructor. * * @param pickingSlotId * @param pickingSlotName * @param pickingSlotWarehouse * @param pickingSlotBPartner * @param pickingSlotBPLocation * @param includedHURows */ @Builder(builderMethodName = "fromPickingSlotBuilder", builderClassName = "FromPickingSlotBuilder") private PickingSlotRow(final PickingSlotId pickingSlotId, // final String pickingSlotName, final LookupValue pickingSlotWarehouse, final LocatorId pickingSlotLocatorId, final LookupValue pickingSlotBPartner, final LookupValue pickingSlotBPLocation, // final List<PickingSlotRow> includedHURows, final ViewId includedViewId) { pickingSlotRowId = PickingSlotRowId.ofPickingSlotId(pickingSlotId); type = PickingSlotRowType.forPickingSlotRow(); processed = false; documentPath = DocumentPath.rootDocumentPath(PickingConstants.WINDOWID_PickingSlotView, pickingSlotId); // HU huCode = null; huProduct = null; huPackingInfo = null; huQtyCU = null; huTopLevel = false; // Picking slot info this.pickingSlotWarehouse = pickingSlotWarehouse; this.pickingSlotLocatorId = pickingSlotLocatorId; this.pickingSlotBPartner = pickingSlotBPartner; this.pickingSlotBPLocation = pickingSlotBPLocation; pickingSlotCaption = buildPickingSlotCaption(pickingSlotName, pickingSlotBPartner, pickingSlotBPLocation); // Included rows this.includedHURows = includedHURows == null ? ImmutableMap.of() : Maps.uniqueIndex(includedHURows, PickingSlotRow::getPickingSlotRowId); this.includedViewId = includedViewId; } /** * Constructor for a row that represents an HU which is already assigned to a picking slot (aka a picked HU). * * @param pickingSlotId * @param huId * @param huStorageProductId * @param type * @param processed * @param code * @param product * @param packingInfo * @param qtyCU * @param includedHURows */ @Builder(builderMethodName = "fromPickedHUBuilder", builderClassName = "FromPickedHUBuilder") private PickingSlotRow(@NonNull final PickingSlotId pickingSlotId, @NonNull final HuId huId, final int huStorageProductId, // final HUEditorRowType huEditorRowType, final boolean processed, // final String huCode, final JSONLookupValue product, final String packingInfo, final BigDecimal qtyCU, final boolean topLevelHU, // final List<PickingSlotRow> includedHURows) { pickingSlotRowId = PickingSlotRowId.ofPickedHU(pickingSlotId, huId, huStorageProductId); this.type = PickingSlotRowType.forPickingHuRow(huEditorRowType); this.processed = processed; documentPath = DocumentPath.rootDocumentPath(WEBUI_HU_Constants.WEBUI_HU_Window_ID, huId); // HU this.huCode = huCode; huProduct = product; huPackingInfo = packingInfo; huQtyCU = qtyCU; huTopLevel = topLevelHU; // Picking slot info pickingSlotWarehouse = null; pickingSlotLocatorId = null; pickingSlotBPartner = null; pickingSlotBPLocation = null; pickingSlotCaption = null; // Included rows this.includedHURows = includedHURows == null ? ImmutableMap.of() : Maps.uniqueIndex(includedHURows, PickingSlotRow::getPickingSlotRowId); this.includedViewId = null; } private static final ITranslatableString buildPickingSlotCaption(final String pickingSlotName, final LookupValue pickingSlotBPartner, final LookupValue pickingSlotBPLocation) { return ITranslatableString.compose(" ", ITranslatableString.constant(pickingSlotName), pickingSlotBPartner != null ? pickingSlotBPartner.getDisplayNameTrl() : ITranslatableString.empty(), pickingSlotBPLocation != null ? pickingSlotBPLocation.getDisplayNameTrl() : ITranslatableString.empty()); } @Override public DocumentId getId() { return pickingSlotRowId.toDocumentId(); } public PickingSlotRowId getPickingSlotRowId() { return pickingSlotRowId; } @Override public PickingSlotRowType getType() { return type; } @Override public boolean isProcessed() { return processed; } @Override public DocumentPath getDocumentPath() { return documentPath; } @Override public Map<String, Object> getFieldNameAndJsonValues() { if (_fieldNameAndJsonValues == null) { _fieldNameAndJsonValues = ViewColumnHelper.extractJsonMap(this); } return _fieldNameAndJsonValues; } @Override public List<PickingSlotRow> getIncludedRows() { return ImmutableList.copyOf(includedHURows.values()); } public Stream<PickingSlotRow> streamIncludedRowsRecursivelly() { return includedHURows.values().stream().flatMap(PickingSlotRow::streamThisRowAndIncludedRowsRecursivelly); } public Stream<PickingSlotRow> streamThisRowAndIncludedRowsRecursivelly() { final Stream<PickingSlotRow> thisRowStream = Stream.of(this); final Stream<PickingSlotRow> includedRowsStream = streamIncludedRowsRecursivelly(); return Stream.concat(thisRowStream, includedRowsStream); } public Optional<PickingSlotRow> findIncludedRowById(final PickingSlotRowId includedRowId) { // This if (this.pickingSlotRowId.equals(includedRowId)) { return Optional.of(this); } // Direct children { final PickingSlotRow row = includedHURows.get(includedRowId); if (row != null) { return Optional.of(row); } } // Ask all included HU rows return includedHURows.values().stream() .map(includedHURow -> includedHURow.findIncludedRowById(includedRowId).orElse(null)) .filter(row -> row != null).findFirst(); } @Override public boolean isSingleColumn() { return isPickingSlotRow(); } @Override public ITranslatableString getSingleColumnCaption() { return pickingSlotCaption; } /** * @return {@code true} if this row represents an actual picking slot and not any sort of HU that is also shown in this view. */ public boolean isPickingSlotRow() { return pickingSlotRowId.isPickingSlotRow(); } public PickingSlotId getPickingSlotId() { return getPickingSlotRowId().getPickingSlotId(); } public HuId getHuId() { return pickingSlotRowId.getHuId(); } /** * @return {@code true} is this row represents an HU that is assigned to a picking slot */ public boolean isPickedHURow() { return pickingSlotRowId.isPickedHURow(); } public boolean isTopLevelHU() { return huTopLevel; } public boolean isLU() { return isPickedHURow() && getType().isLU(); } public boolean isTU() { return isPickedHURow() && getType().isTU(); } public boolean isCU() { return isPickedHURow() && getType().isCU(); } public boolean isCUOrStorage() { return isPickedHURow() && getType().isCUOrStorage(); } /** * * @return {@code true} if this row represents an HU that is a source-HU for fine-picking. */ public boolean isPickingSourceHURow() { return pickingSlotRowId.isPickingSourceHURow(); } public WarehouseId getPickingSlotWarehouseId() { return pickingSlotWarehouse != null ? WarehouseId.ofRepoId(pickingSlotWarehouse.getIdAsInt()) : null; } public BigDecimal getHuQtyCU() { return huQtyCU; } public ProductId getHuProductId() { return huProduct != null ? ProductId.ofRepoId(huProduct.getKeyAsInt()) : null; } @Override public ViewId getIncludedViewId() { return includedViewId; } public LocatorId getPickingSlotLocatorId() { return pickingSlotLocatorId; } public int getBPartnerId() { return pickingSlotBPartner != null ? pickingSlotBPartner.getIdAsInt() : -1; } public int getBPartnerLocationId() { return pickingSlotBPLocation != null ? pickingSlotBPLocation.getIdAsInt() : -1; } }