diff --git a/src/main/java/com/kingsrook/qbits/wms/advanced/model/WmsReplenishmentRule.java b/src/main/java/com/kingsrook/qbits/wms/advanced/model/WmsReplenishmentRule.java index 247ff5e..84e3f3f 100644 --- a/src/main/java/com/kingsrook/qbits/wms/advanced/model/WmsReplenishmentRule.java +++ b/src/main/java/com/kingsrook/qbits/wms/advanced/model/WmsReplenishmentRule.java @@ -7,7 +7,14 @@ package com.kingsrook.qbits.wms.advanced.model; import java.time.Instant; +import com.kingsrook.qbits.wms.core.model.WmsItem; +import com.kingsrook.qbits.wms.core.model.WmsLocation; +import com.kingsrook.qbits.wms.core.model.WmsWarehouse; +import com.kingsrook.qbits.wms.core.model.WmsZone; import com.kingsrook.qqq.backend.core.exceptions.QException; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter; import com.kingsrook.qqq.backend.core.model.data.QField; import com.kingsrook.qqq.backend.core.model.data.QRecord; import com.kingsrook.qqq.backend.core.model.data.QRecordEntity; @@ -19,10 +26,6 @@ import com.kingsrook.qqq.backend.core.model.metadata.tables.QFieldSection; import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData; import com.kingsrook.qqq.backend.core.model.metadata.tables.SectionFactory; import com.kingsrook.qqq.backend.core.model.metadata.tables.Tier; -import com.kingsrook.qbits.wms.core.model.WmsItem; -import com.kingsrook.qbits.wms.core.model.WmsLocation; -import com.kingsrook.qbits.wms.core.model.WmsWarehouse; -import com.kingsrook.qbits.wms.core.model.WmsZone; @QMetaDataProducingEntity( @@ -59,6 +62,14 @@ public class WmsReplenishmentRule extends QRecordEntity java.util.List.of("sourceZoneId"))) .withSection(SectionFactory.defaultT3("createDate", "modifyDate")); + // Scope pickLocationId choices to the selected warehouseId. + table.getField("pickLocationId").withPossibleValueSourceFilter(new QQueryFilter( + new QFilterCriteria("warehouseId", QCriteriaOperator.EQUALS, "${input.warehouseId}"))); + + // Scope sourceZoneId choices to the selected warehouseId. + table.getField("sourceZoneId").withPossibleValueSourceFilter(new QQueryFilter( + new QFilterCriteria("warehouseId", QCriteriaOperator.EQUALS, "${input.warehouseId}"))); + return (table); } } diff --git a/src/main/java/com/kingsrook/qbits/wms/billing/model/WmsBillingActivity.java b/src/main/java/com/kingsrook/qbits/wms/billing/model/WmsBillingActivity.java index fe5cc54..3587fb9 100644 --- a/src/main/java/com/kingsrook/qbits/wms/billing/model/WmsBillingActivity.java +++ b/src/main/java/com/kingsrook/qbits/wms/billing/model/WmsBillingActivity.java @@ -7,21 +7,50 @@ package com.kingsrook.qbits.wms.billing.model; import java.math.BigDecimal; import java.time.Instant; -import com.kingsrook.qqq.backend.core.model.data.QField; -import com.kingsrook.qqq.backend.core.model.data.QRecord; -import com.kingsrook.qqq.backend.core.model.data.QRecordEntity; -import com.kingsrook.qqq.backend.core.model.metadata.producers.annotations.QMetaDataProducingEntity; import com.kingsrook.qbits.wms.core.enums.BillingActivityType; import com.kingsrook.qbits.wms.core.model.WmsClient; import com.kingsrook.qbits.wms.core.model.WmsTask; import com.kingsrook.qbits.wms.core.model.WmsWarehouse; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter; +import com.kingsrook.qqq.backend.core.model.data.QField; +import com.kingsrook.qqq.backend.core.model.data.QRecord; +import com.kingsrook.qqq.backend.core.model.data.QRecordEntity; +import com.kingsrook.qqq.backend.core.model.metadata.QInstance; +import com.kingsrook.qqq.backend.core.model.metadata.producers.MetaDataCustomizerInterface; +import com.kingsrook.qqq.backend.core.model.metadata.producers.annotations.QMetaDataProducingEntity; +import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData; -@QMetaDataProducingEntity(produceTableMetaData = true) +@QMetaDataProducingEntity(tableMetaDataCustomizer = WmsBillingActivity.TableMetaDataCustomizer.class, produceTableMetaData = true) public class WmsBillingActivity extends QRecordEntity { public static final String TABLE_NAME = "wmsBillingActivity"; + + + /******************************************************************************* + ** Customize dependent choices after entity fields have been produced. + *******************************************************************************/ + public static class TableMetaDataCustomizer implements MetaDataCustomizerInterface + { + /*************************************************************************** + ** Restrict possible values to the current form scope. + ***************************************************************************/ + @Override + public QTableMetaData customizeMetaData(QInstance qInstance, QTableMetaData table) + { + // Scope rateId choices to the selected activityTypeId. + table.getField("rateId").withPossibleValueSourceFilter(new QQueryFilter( + new QFilterCriteria("activityTypeId", QCriteriaOperator.EQUALS, "${input.activityTypeId}"))); + + return (table); + } + } + + + @QField(isEditable = false, isPrimaryKey = true) private Integer id; diff --git a/src/main/java/com/kingsrook/qbits/wms/core/model/WmsInventory.java b/src/main/java/com/kingsrook/qbits/wms/core/model/WmsInventory.java index f025fe7..de119ed 100644 --- a/src/main/java/com/kingsrook/qbits/wms/core/model/WmsInventory.java +++ b/src/main/java/com/kingsrook/qbits/wms/core/model/WmsInventory.java @@ -7,7 +7,11 @@ package com.kingsrook.qbits.wms.core.model; import java.math.BigDecimal; import java.time.Instant; import java.time.LocalDate; +import com.kingsrook.qbits.wms.core.enums.InventoryStatus; import com.kingsrook.qqq.backend.core.exceptions.QException; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter; import com.kingsrook.qqq.backend.core.model.data.QField; import com.kingsrook.qqq.backend.core.model.data.QRecord; import com.kingsrook.qqq.backend.core.model.data.QRecordEntity; @@ -16,10 +20,9 @@ import com.kingsrook.qqq.backend.core.model.metadata.layout.QIcon; import com.kingsrook.qqq.backend.core.model.metadata.producers.MetaDataCustomizerInterface; import com.kingsrook.qqq.backend.core.model.metadata.producers.annotations.QMetaDataProducingEntity; import com.kingsrook.qqq.backend.core.model.metadata.tables.QFieldSection; -import com.kingsrook.qqq.backend.core.model.metadata.tables.Tier; import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData; import com.kingsrook.qqq.backend.core.model.metadata.tables.SectionFactory; -import com.kingsrook.qbits.wms.core.enums.InventoryStatus; +import com.kingsrook.qqq.backend.core.model.metadata.tables.Tier; @QMetaDataProducingEntity( @@ -59,6 +62,18 @@ public class WmsInventory extends QRecordEntity java.util.List.of("holdReason", "lastCountDate"))) .withSection(SectionFactory.defaultT3("createDate", "modifyDate")); + // Scope locationId choices to the selected warehouseId. + table.getField("locationId").withPossibleValueSourceFilter(new QQueryFilter( + new QFilterCriteria("warehouseId", QCriteriaOperator.EQUALS, "${input.warehouseId}"))); + + // Scope lpnId choices to the selected warehouseId. + table.getField("lpnId").withPossibleValueSourceFilter(new QQueryFilter( + new QFilterCriteria("warehouseId", QCriteriaOperator.EQUALS, "${input.warehouseId}"))); + + // Scope itemId choices to the selected clientId. + table.getField("itemId").withPossibleValueSourceFilter(new QQueryFilter( + new QFilterCriteria("clientId", QCriteriaOperator.EQUALS, "${input.clientId}"))); + return (table); } } diff --git a/src/main/java/com/kingsrook/qbits/wms/core/model/WmsInventoryHold.java b/src/main/java/com/kingsrook/qbits/wms/core/model/WmsInventoryHold.java index 58ad71b..3563214 100644 --- a/src/main/java/com/kingsrook/qbits/wms/core/model/WmsInventoryHold.java +++ b/src/main/java/com/kingsrook/qbits/wms/core/model/WmsInventoryHold.java @@ -5,18 +5,51 @@ package com.kingsrook.qbits.wms.core.model; import java.time.Instant; +import com.kingsrook.qbits.wms.core.enums.HoldType; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter; import com.kingsrook.qqq.backend.core.model.data.QField; import com.kingsrook.qqq.backend.core.model.data.QRecord; import com.kingsrook.qqq.backend.core.model.data.QRecordEntity; +import com.kingsrook.qqq.backend.core.model.metadata.QInstance; +import com.kingsrook.qqq.backend.core.model.metadata.producers.MetaDataCustomizerInterface; import com.kingsrook.qqq.backend.core.model.metadata.producers.annotations.QMetaDataProducingEntity; -import com.kingsrook.qbits.wms.core.enums.HoldType; +import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData; -@QMetaDataProducingEntity(producePossibleValueSource = true, produceTableMetaData = true) +@QMetaDataProducingEntity(tableMetaDataCustomizer = WmsInventoryHold.TableMetaDataCustomizer.class, producePossibleValueSource = true, produceTableMetaData = true) public class WmsInventoryHold extends QRecordEntity { public static final String TABLE_NAME = "wmsInventoryHold"; + + + /******************************************************************************* + ** Customize dependent choices after entity fields have been produced. + *******************************************************************************/ + public static class TableMetaDataCustomizer implements MetaDataCustomizerInterface + { + /*************************************************************************** + ** Restrict possible values to the current form scope. + ***************************************************************************/ + @Override + public QTableMetaData customizeMetaData(QInstance qInstance, QTableMetaData table) + { + // Scope locationId choices to the selected warehouseId. + table.getField("locationId").withPossibleValueSourceFilter(new QQueryFilter( + new QFilterCriteria("warehouseId", QCriteriaOperator.EQUALS, "${input.warehouseId}"))); + + // Scope itemId choices to the selected clientId. + table.getField("itemId").withPossibleValueSourceFilter(new QQueryFilter( + new QFilterCriteria("clientId", QCriteriaOperator.EQUALS, "${input.clientId}"))); + + return (table); + } + } + + + @QField(isEditable = false, isPrimaryKey = true) private Integer id; diff --git a/src/main/java/com/kingsrook/qbits/wms/core/model/WmsLicensePlate.java b/src/main/java/com/kingsrook/qbits/wms/core/model/WmsLicensePlate.java index 22af630..b4177b5 100644 --- a/src/main/java/com/kingsrook/qbits/wms/core/model/WmsLicensePlate.java +++ b/src/main/java/com/kingsrook/qbits/wms/core/model/WmsLicensePlate.java @@ -5,18 +5,47 @@ package com.kingsrook.qbits.wms.core.model; import java.time.Instant; +import com.kingsrook.qbits.wms.core.enums.LpnStatus; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter; import com.kingsrook.qqq.backend.core.model.data.QField; import com.kingsrook.qqq.backend.core.model.data.QRecord; import com.kingsrook.qqq.backend.core.model.data.QRecordEntity; +import com.kingsrook.qqq.backend.core.model.metadata.QInstance; +import com.kingsrook.qqq.backend.core.model.metadata.producers.MetaDataCustomizerInterface; import com.kingsrook.qqq.backend.core.model.metadata.producers.annotations.QMetaDataProducingEntity; -import com.kingsrook.qbits.wms.core.enums.LpnStatus; +import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData; -@QMetaDataProducingEntity(producePossibleValueSource = true, produceTableMetaData = true) +@QMetaDataProducingEntity(tableMetaDataCustomizer = WmsLicensePlate.TableMetaDataCustomizer.class, producePossibleValueSource = true, produceTableMetaData = true) public class WmsLicensePlate extends QRecordEntity { public static final String TABLE_NAME = "wmsLicensePlate"; + + + /******************************************************************************* + ** Customize dependent choices after entity fields have been produced. + *******************************************************************************/ + public static class TableMetaDataCustomizer implements MetaDataCustomizerInterface + { + /*************************************************************************** + ** Restrict possible values to the current form scope. + ***************************************************************************/ + @Override + public QTableMetaData customizeMetaData(QInstance qInstance, QTableMetaData table) + { + // Scope locationId choices to the selected warehouseId. + table.getField("locationId").withPossibleValueSourceFilter(new QQueryFilter( + new QFilterCriteria("warehouseId", QCriteriaOperator.EQUALS, "${input.warehouseId}"))); + + return (table); + } + } + + + @QField(isEditable = false, isPrimaryKey = true) private Integer id; diff --git a/src/main/java/com/kingsrook/qbits/wms/core/model/WmsLocation.java b/src/main/java/com/kingsrook/qbits/wms/core/model/WmsLocation.java index 18352b1..13e7f72 100644 --- a/src/main/java/com/kingsrook/qbits/wms/core/model/WmsLocation.java +++ b/src/main/java/com/kingsrook/qbits/wms/core/model/WmsLocation.java @@ -6,7 +6,11 @@ package com.kingsrook.qbits.wms.core.model; import java.math.BigDecimal; import java.time.Instant; +import com.kingsrook.qbits.wms.core.enums.LocationType; import com.kingsrook.qqq.backend.core.exceptions.QException; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter; import com.kingsrook.qqq.backend.core.model.data.QField; import com.kingsrook.qqq.backend.core.model.data.QRecord; import com.kingsrook.qqq.backend.core.model.data.QRecordEntity; @@ -15,10 +19,9 @@ import com.kingsrook.qqq.backend.core.model.metadata.layout.QIcon; import com.kingsrook.qqq.backend.core.model.metadata.producers.MetaDataCustomizerInterface; import com.kingsrook.qqq.backend.core.model.metadata.producers.annotations.QMetaDataProducingEntity; import com.kingsrook.qqq.backend.core.model.metadata.tables.QFieldSection; -import com.kingsrook.qqq.backend.core.model.metadata.tables.Tier; import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData; import com.kingsrook.qqq.backend.core.model.metadata.tables.SectionFactory; -import com.kingsrook.qbits.wms.core.enums.LocationType; +import com.kingsrook.qqq.backend.core.model.metadata.tables.Tier; @QMetaDataProducingEntity( @@ -54,6 +57,10 @@ public class WmsLocation extends QRecordEntity java.util.List.of("maxWeightLbs", "maxVolumeCubicFt", "currentWeightLbs", "currentVolumeCubicFt", "isMixedSkuAllowed"))) .withSection(SectionFactory.defaultT3("createDate", "modifyDate")); + // Scope zoneId choices to the selected warehouseId. + table.getField("zoneId").withPossibleValueSourceFilter(new QQueryFilter( + new QFilterCriteria("warehouseId", QCriteriaOperator.EQUALS, "${input.warehouseId}"))); + return (table); } } diff --git a/src/main/java/com/kingsrook/qbits/wms/core/model/WmsTask.java b/src/main/java/com/kingsrook/qbits/wms/core/model/WmsTask.java index b5388a5..7651266 100644 --- a/src/main/java/com/kingsrook/qbits/wms/core/model/WmsTask.java +++ b/src/main/java/com/kingsrook/qbits/wms/core/model/WmsTask.java @@ -6,7 +6,13 @@ package com.kingsrook.qbits.wms.core.model; import java.math.BigDecimal; import java.time.Instant; +import com.kingsrook.qbits.wms.core.enums.EquipmentType; +import com.kingsrook.qbits.wms.core.enums.TaskStatus; +import com.kingsrook.qbits.wms.core.enums.TaskType; import com.kingsrook.qqq.backend.core.exceptions.QException; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter; import com.kingsrook.qqq.backend.core.model.data.QField; import com.kingsrook.qqq.backend.core.model.data.QRecord; import com.kingsrook.qqq.backend.core.model.data.QRecordEntity; @@ -15,12 +21,9 @@ import com.kingsrook.qqq.backend.core.model.metadata.layout.QIcon; import com.kingsrook.qqq.backend.core.model.metadata.producers.MetaDataCustomizerInterface; import com.kingsrook.qqq.backend.core.model.metadata.producers.annotations.QMetaDataProducingEntity; import com.kingsrook.qqq.backend.core.model.metadata.tables.QFieldSection; -import com.kingsrook.qqq.backend.core.model.metadata.tables.Tier; import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData; import com.kingsrook.qqq.backend.core.model.metadata.tables.SectionFactory; -import com.kingsrook.qbits.wms.core.enums.EquipmentType; -import com.kingsrook.qbits.wms.core.enums.TaskStatus; -import com.kingsrook.qbits.wms.core.enums.TaskType; +import com.kingsrook.qqq.backend.core.model.metadata.tables.Tier; @QMetaDataProducingEntity( @@ -67,6 +70,22 @@ public class WmsTask extends QRecordEntity java.util.List.of("notes", "shortReason"))) .withSection(SectionFactory.defaultT3("createDate", "modifyDate")); + // Scope lpnId choices to the selected warehouseId. + table.getField("lpnId").withPossibleValueSourceFilter(new QQueryFilter( + new QFilterCriteria("warehouseId", QCriteriaOperator.EQUALS, "${input.warehouseId}"))); + + // Scope sourceLocationId choices to the selected warehouseId. + table.getField("sourceLocationId").withPossibleValueSourceFilter(new QQueryFilter( + new QFilterCriteria("warehouseId", QCriteriaOperator.EQUALS, "${input.warehouseId}"))); + + // Scope destinationLocationId choices to the selected warehouseId. + table.getField("destinationLocationId").withPossibleValueSourceFilter(new QQueryFilter( + new QFilterCriteria("warehouseId", QCriteriaOperator.EQUALS, "${input.warehouseId}"))); + + // Scope zoneId choices to the selected warehouseId. + table.getField("zoneId").withPossibleValueSourceFilter(new QQueryFilter( + new QFilterCriteria("warehouseId", QCriteriaOperator.EQUALS, "${input.warehouseId}"))); + return (table); } } diff --git a/src/main/java/com/kingsrook/qbits/wms/fulfillment/model/WmsKitBom.java b/src/main/java/com/kingsrook/qbits/wms/fulfillment/model/WmsKitBom.java index 1904992..173e9fb 100644 --- a/src/main/java/com/kingsrook/qbits/wms/fulfillment/model/WmsKitBom.java +++ b/src/main/java/com/kingsrook/qbits/wms/fulfillment/model/WmsKitBom.java @@ -6,7 +6,13 @@ package com.kingsrook.qbits.wms.fulfillment.model; import java.time.Instant; +import com.kingsrook.qbits.wms.core.model.WmsClient; +import com.kingsrook.qbits.wms.core.model.WmsItem; +import com.kingsrook.qbits.wms.core.model.WmsUnitOfMeasure; import com.kingsrook.qqq.backend.core.exceptions.QException; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter; import com.kingsrook.qqq.backend.core.model.data.QField; import com.kingsrook.qqq.backend.core.model.data.QRecord; import com.kingsrook.qqq.backend.core.model.data.QRecordEntity; @@ -18,9 +24,6 @@ import com.kingsrook.qqq.backend.core.model.metadata.tables.QFieldSection; import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData; import com.kingsrook.qqq.backend.core.model.metadata.tables.SectionFactory; import com.kingsrook.qqq.backend.core.model.metadata.tables.Tier; -import com.kingsrook.qbits.wms.core.model.WmsClient; -import com.kingsrook.qbits.wms.core.model.WmsItem; -import com.kingsrook.qbits.wms.core.model.WmsUnitOfMeasure; @QMetaDataProducingEntity( @@ -54,6 +57,18 @@ public class WmsKitBom extends QRecordEntity java.util.List.of("componentUomId", "clientId"))) .withSection(SectionFactory.defaultT3("createDate", "modifyDate")); + // Scope componentUomId choices to the selected componentItemId. + table.getField("componentUomId").withPossibleValueSourceFilter(new QQueryFilter( + new QFilterCriteria("itemId", QCriteriaOperator.EQUALS, "${input.componentItemId}"))); + + // Scope kitItemId choices to the selected clientId. + table.getField("kitItemId").withPossibleValueSourceFilter(new QQueryFilter( + new QFilterCriteria("clientId", QCriteriaOperator.EQUALS, "${input.clientId}"))); + + // Scope componentItemId choices to the selected clientId. + table.getField("componentItemId").withPossibleValueSourceFilter(new QQueryFilter( + new QFilterCriteria("clientId", QCriteriaOperator.EQUALS, "${input.clientId}"))); + return (table); } } diff --git a/src/main/java/com/kingsrook/qbits/wms/fulfillment/model/WmsKitWorkOrder.java b/src/main/java/com/kingsrook/qbits/wms/fulfillment/model/WmsKitWorkOrder.java index 4ef983f..e9402c4 100644 --- a/src/main/java/com/kingsrook/qbits/wms/fulfillment/model/WmsKitWorkOrder.java +++ b/src/main/java/com/kingsrook/qbits/wms/fulfillment/model/WmsKitWorkOrder.java @@ -7,7 +7,15 @@ package com.kingsrook.qbits.wms.fulfillment.model; import java.time.Instant; +import com.kingsrook.qbits.wms.core.enums.KitWorkOrderStatus; +import com.kingsrook.qbits.wms.core.enums.KitWorkOrderType; +import com.kingsrook.qbits.wms.core.model.WmsClient; +import com.kingsrook.qbits.wms.core.model.WmsItem; +import com.kingsrook.qbits.wms.core.model.WmsWarehouse; import com.kingsrook.qqq.backend.core.exceptions.QException; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter; import com.kingsrook.qqq.backend.core.model.data.QField; import com.kingsrook.qqq.backend.core.model.data.QRecord; import com.kingsrook.qqq.backend.core.model.data.QRecordEntity; @@ -19,11 +27,6 @@ import com.kingsrook.qqq.backend.core.model.metadata.tables.QFieldSection; import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData; import com.kingsrook.qqq.backend.core.model.metadata.tables.SectionFactory; import com.kingsrook.qqq.backend.core.model.metadata.tables.Tier; -import com.kingsrook.qbits.wms.core.enums.KitWorkOrderStatus; -import com.kingsrook.qbits.wms.core.enums.KitWorkOrderType; -import com.kingsrook.qbits.wms.core.model.WmsClient; -import com.kingsrook.qbits.wms.core.model.WmsItem; -import com.kingsrook.qbits.wms.core.model.WmsWarehouse; @QMetaDataProducingEntity( @@ -57,6 +60,10 @@ public class WmsKitWorkOrder extends QRecordEntity java.util.List.of("warehouseId", "clientId", "assignedTo", "completedDate"))) .withSection(SectionFactory.defaultT3("createDate", "modifyDate")); + // Scope kitItemId choices to the selected clientId. + table.getField("kitItemId").withPossibleValueSourceFilter(new QQueryFilter( + new QFilterCriteria("clientId", QCriteriaOperator.EQUALS, "${input.clientId}"))); + return (table); } } diff --git a/src/main/java/com/kingsrook/qbits/wms/fulfillment/model/WmsOrder.java b/src/main/java/com/kingsrook/qbits/wms/fulfillment/model/WmsOrder.java index aae3cf0..b9e1140 100644 --- a/src/main/java/com/kingsrook/qbits/wms/fulfillment/model/WmsOrder.java +++ b/src/main/java/com/kingsrook/qbits/wms/fulfillment/model/WmsOrder.java @@ -7,7 +7,13 @@ package com.kingsrook.qbits.wms.fulfillment.model; import java.math.BigDecimal; import java.time.Instant; +import com.kingsrook.qbits.wms.core.enums.OrderStatus; +import com.kingsrook.qbits.wms.core.model.WmsClient; +import com.kingsrook.qbits.wms.core.model.WmsWarehouse; import com.kingsrook.qqq.backend.core.exceptions.QException; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter; import com.kingsrook.qqq.backend.core.model.data.QField; import com.kingsrook.qqq.backend.core.model.data.QRecord; import com.kingsrook.qqq.backend.core.model.data.QRecordEntity; @@ -22,9 +28,6 @@ import com.kingsrook.qqq.backend.core.model.metadata.tables.QFieldSection; import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData; import com.kingsrook.qqq.backend.core.model.metadata.tables.SectionFactory; import com.kingsrook.qqq.backend.core.model.metadata.tables.Tier; -import com.kingsrook.qbits.wms.core.enums.OrderStatus; -import com.kingsrook.qbits.wms.core.model.WmsClient; -import com.kingsrook.qbits.wms.core.model.WmsWarehouse; @QMetaDataProducingEntity( @@ -75,6 +78,10 @@ public class WmsOrder extends QRecordEntity "totalLineCount", "totalUnitCount", "orderValue", "specialInstructions"))) .withSection(SectionFactory.defaultT3("createDate", "modifyDate")); + // Scope waveId choices to the selected warehouseId. + table.getField("waveId").withPossibleValueSourceFilter(new QQueryFilter( + new QFilterCriteria("warehouseId", QCriteriaOperator.EQUALS, "${input.warehouseId}"))); + return (table); } } diff --git a/src/main/java/com/kingsrook/qbits/wms/fulfillment/model/WmsOrderLine.java b/src/main/java/com/kingsrook/qbits/wms/fulfillment/model/WmsOrderLine.java index de07747..d648d7f 100644 --- a/src/main/java/com/kingsrook/qbits/wms/fulfillment/model/WmsOrderLine.java +++ b/src/main/java/com/kingsrook/qbits/wms/fulfillment/model/WmsOrderLine.java @@ -6,7 +6,13 @@ package com.kingsrook.qbits.wms.fulfillment.model; import java.time.Instant; +import com.kingsrook.qbits.wms.core.enums.OrderLineStatus; +import com.kingsrook.qbits.wms.core.model.WmsItem; +import com.kingsrook.qbits.wms.core.model.WmsUnitOfMeasure; import com.kingsrook.qqq.backend.core.exceptions.QException; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter; import com.kingsrook.qqq.backend.core.model.data.QField; import com.kingsrook.qqq.backend.core.model.data.QRecord; import com.kingsrook.qqq.backend.core.model.data.QRecordEntity; @@ -18,9 +24,6 @@ import com.kingsrook.qqq.backend.core.model.metadata.tables.QFieldSection; import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData; import com.kingsrook.qqq.backend.core.model.metadata.tables.SectionFactory; import com.kingsrook.qqq.backend.core.model.metadata.tables.Tier; -import com.kingsrook.qbits.wms.core.enums.OrderLineStatus; -import com.kingsrook.qbits.wms.core.model.WmsItem; -import com.kingsrook.qbits.wms.core.model.WmsUnitOfMeasure; @QMetaDataProducingEntity( @@ -57,6 +60,10 @@ public class WmsOrderLine extends QRecordEntity java.util.List.of("uomId", "lotPreference"))) .withSection(SectionFactory.defaultT3("createDate", "modifyDate")); + // Scope uomId choices to the selected itemId. + table.getField("uomId").withPossibleValueSourceFilter(new QQueryFilter( + new QFilterCriteria("itemId", QCriteriaOperator.EQUALS, "${input.itemId}"))); + return (table); } } diff --git a/src/main/java/com/kingsrook/qbits/wms/inventory/processes/CycleCountProcessMetaDataProducer.java b/src/main/java/com/kingsrook/qbits/wms/inventory/processes/CycleCountProcessMetaDataProducer.java index 6414d8b..c1ce473 100644 --- a/src/main/java/com/kingsrook/qbits/wms/inventory/processes/CycleCountProcessMetaDataProducer.java +++ b/src/main/java/com/kingsrook/qbits/wms/inventory/processes/CycleCountProcessMetaDataProducer.java @@ -6,7 +6,14 @@ package com.kingsrook.qbits.wms.inventory.processes; +import com.kingsrook.qbits.wms.core.enums.CycleCountType; +import com.kingsrook.qbits.wms.core.model.WmsCycleCount; +import com.kingsrook.qbits.wms.core.model.WmsWarehouse; +import com.kingsrook.qbits.wms.core.model.WmsZone; import com.kingsrook.qqq.backend.core.exceptions.QException; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter; import com.kingsrook.qqq.backend.core.model.metadata.MetaDataProducerInterface; import com.kingsrook.qqq.backend.core.model.metadata.QInstance; import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference; @@ -18,10 +25,6 @@ import com.kingsrook.qqq.backend.core.model.metadata.processes.QComponentType; import com.kingsrook.qqq.backend.core.model.metadata.processes.QFrontendComponentMetaData; import com.kingsrook.qqq.backend.core.model.metadata.processes.QFrontendStepMetaData; import com.kingsrook.qqq.backend.core.model.metadata.processes.QProcessMetaData; -import com.kingsrook.qbits.wms.core.enums.CycleCountType; -import com.kingsrook.qbits.wms.core.model.WmsCycleCount; -import com.kingsrook.qbits.wms.core.model.WmsWarehouse; -import com.kingsrook.qbits.wms.core.model.WmsZone; public class CycleCountProcessMetaDataProducer implements MetaDataProducerInterface @@ -51,7 +54,9 @@ public class CycleCountProcessMetaDataProducer implements MetaDataProducerInterf .withComponent(new QFrontendComponentMetaData().withType(QComponentType.EDIT_FORM)) .withFormField(new QFieldMetaData("warehouseId", QFieldType.INTEGER).withLabel("Warehouse").withPossibleValueSourceName(WmsWarehouse.TABLE_NAME).withIsRequired(true)) .withFormField(new QFieldMetaData("countTypeId", QFieldType.INTEGER).withLabel("Count Type").withPossibleValueSourceName(CycleCountType.NAME).withIsRequired(true)) - .withFormField(new QFieldMetaData("zoneId", QFieldType.INTEGER).withLabel("Target Zone").withPossibleValueSourceName(WmsZone.TABLE_NAME)) + // Scope zone choices to the warehouse selected on this process form. + .withFormField(new QFieldMetaData("zoneId", QFieldType.INTEGER).withLabel("Target Zone").withPossibleValueSourceName(WmsZone.TABLE_NAME) + .withPossibleValueSourceFilter(new QQueryFilter(new QFilterCriteria("warehouseId", QCriteriaOperator.EQUALS, "${input.warehouseId}")))) .withFormField(new QFieldMetaData("assignedTo", QFieldType.STRING).withLabel("Assign To"))) ////////////////////////////////////////////////////////////////////////// diff --git a/src/main/java/com/kingsrook/qbits/wms/receiving/model/WmsAsnLine.java b/src/main/java/com/kingsrook/qbits/wms/receiving/model/WmsAsnLine.java index 01edabc..64aa483 100644 --- a/src/main/java/com/kingsrook/qbits/wms/receiving/model/WmsAsnLine.java +++ b/src/main/java/com/kingsrook/qbits/wms/receiving/model/WmsAsnLine.java @@ -7,19 +7,48 @@ package com.kingsrook.qbits.wms.receiving.model; import java.time.Instant; import java.time.LocalDate; +import com.kingsrook.qbits.wms.core.model.WmsItem; +import com.kingsrook.qbits.wms.core.model.WmsUnitOfMeasure; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter; import com.kingsrook.qqq.backend.core.model.data.QField; import com.kingsrook.qqq.backend.core.model.data.QRecord; import com.kingsrook.qqq.backend.core.model.data.QRecordEntity; +import com.kingsrook.qqq.backend.core.model.metadata.QInstance; +import com.kingsrook.qqq.backend.core.model.metadata.producers.MetaDataCustomizerInterface; import com.kingsrook.qqq.backend.core.model.metadata.producers.annotations.QMetaDataProducingEntity; -import com.kingsrook.qbits.wms.core.model.WmsItem; -import com.kingsrook.qbits.wms.core.model.WmsUnitOfMeasure; +import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData; -@QMetaDataProducingEntity(produceTableMetaData = true) +@QMetaDataProducingEntity(tableMetaDataCustomizer = WmsAsnLine.TableMetaDataCustomizer.class, produceTableMetaData = true) public class WmsAsnLine extends QRecordEntity { public static final String TABLE_NAME = "wmsAsnLine"; + + + /******************************************************************************* + ** Customize dependent choices after entity fields have been produced. + *******************************************************************************/ + public static class TableMetaDataCustomizer implements MetaDataCustomizerInterface + { + /*************************************************************************** + ** Restrict possible values to the current form scope. + ***************************************************************************/ + @Override + public QTableMetaData customizeMetaData(QInstance qInstance, QTableMetaData table) + { + // Scope uomId choices to the selected itemId. + table.getField("uomId").withPossibleValueSourceFilter(new QQueryFilter( + new QFilterCriteria("itemId", QCriteriaOperator.EQUALS, "${input.itemId}"))); + + return (table); + } + } + + + @QField(isEditable = false, isPrimaryKey = true) private Integer id; diff --git a/src/main/java/com/kingsrook/qbits/wms/receiving/model/WmsPurchaseOrder.java b/src/main/java/com/kingsrook/qbits/wms/receiving/model/WmsPurchaseOrder.java index a29fa7b..58de7f6 100644 --- a/src/main/java/com/kingsrook/qbits/wms/receiving/model/WmsPurchaseOrder.java +++ b/src/main/java/com/kingsrook/qbits/wms/receiving/model/WmsPurchaseOrder.java @@ -7,7 +7,15 @@ package com.kingsrook.qbits.wms.receiving.model; import java.time.Instant; import java.time.LocalDate; +import com.kingsrook.qbits.wms.core.enums.PurchaseOrderStatus; +import com.kingsrook.qbits.wms.core.model.WmsClient; +import com.kingsrook.qbits.wms.core.model.WmsLocation; +import com.kingsrook.qbits.wms.core.model.WmsVendor; +import com.kingsrook.qbits.wms.core.model.WmsWarehouse; import com.kingsrook.qqq.backend.core.exceptions.QException; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter; import com.kingsrook.qqq.backend.core.model.data.QField; import com.kingsrook.qqq.backend.core.model.data.QRecord; import com.kingsrook.qqq.backend.core.model.data.QRecordEntity; @@ -22,11 +30,6 @@ import com.kingsrook.qqq.backend.core.model.metadata.tables.QFieldSection; import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData; import com.kingsrook.qqq.backend.core.model.metadata.tables.SectionFactory; import com.kingsrook.qqq.backend.core.model.metadata.tables.Tier; -import com.kingsrook.qbits.wms.core.enums.PurchaseOrderStatus; -import com.kingsrook.qbits.wms.core.model.WmsClient; -import com.kingsrook.qbits.wms.core.model.WmsLocation; -import com.kingsrook.qbits.wms.core.model.WmsVendor; -import com.kingsrook.qbits.wms.core.model.WmsWarehouse; @QMetaDataProducingEntity( @@ -73,6 +76,10 @@ public class WmsPurchaseOrder extends QRecordEntity java.util.List.of("notes"))) .withSection(SectionFactory.defaultT3("createDate", "modifyDate")); + // Scope dockDoorId choices to the selected warehouseId. + table.getField("dockDoorId").withPossibleValueSourceFilter(new QQueryFilter( + new QFilterCriteria("warehouseId", QCriteriaOperator.EQUALS, "${input.warehouseId}"))); + return (table); } } diff --git a/src/main/java/com/kingsrook/qbits/wms/receiving/model/WmsPurchaseOrderLine.java b/src/main/java/com/kingsrook/qbits/wms/receiving/model/WmsPurchaseOrderLine.java index 30a24b9..b1cdb9c 100644 --- a/src/main/java/com/kingsrook/qbits/wms/receiving/model/WmsPurchaseOrderLine.java +++ b/src/main/java/com/kingsrook/qbits/wms/receiving/model/WmsPurchaseOrderLine.java @@ -7,20 +7,49 @@ package com.kingsrook.qbits.wms.receiving.model; import java.math.BigDecimal; import java.time.Instant; -import com.kingsrook.qqq.backend.core.model.data.QField; -import com.kingsrook.qqq.backend.core.model.data.QRecord; -import com.kingsrook.qqq.backend.core.model.data.QRecordEntity; -import com.kingsrook.qqq.backend.core.model.metadata.producers.annotations.QMetaDataProducingEntity; import com.kingsrook.qbits.wms.core.enums.PurchaseOrderStatus; import com.kingsrook.qbits.wms.core.model.WmsItem; import com.kingsrook.qbits.wms.core.model.WmsUnitOfMeasure; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter; +import com.kingsrook.qqq.backend.core.model.data.QField; +import com.kingsrook.qqq.backend.core.model.data.QRecord; +import com.kingsrook.qqq.backend.core.model.data.QRecordEntity; +import com.kingsrook.qqq.backend.core.model.metadata.QInstance; +import com.kingsrook.qqq.backend.core.model.metadata.producers.MetaDataCustomizerInterface; +import com.kingsrook.qqq.backend.core.model.metadata.producers.annotations.QMetaDataProducingEntity; +import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData; -@QMetaDataProducingEntity(producePossibleValueSource = true, produceTableMetaData = true) +@QMetaDataProducingEntity(tableMetaDataCustomizer = WmsPurchaseOrderLine.TableMetaDataCustomizer.class, producePossibleValueSource = true, produceTableMetaData = true) public class WmsPurchaseOrderLine extends QRecordEntity { public static final String TABLE_NAME = "wmsPurchaseOrderLine"; + + + /******************************************************************************* + ** Customize dependent choices after entity fields have been produced. + *******************************************************************************/ + public static class TableMetaDataCustomizer implements MetaDataCustomizerInterface + { + /*************************************************************************** + ** Restrict possible values to the current form scope. + ***************************************************************************/ + @Override + public QTableMetaData customizeMetaData(QInstance qInstance, QTableMetaData table) + { + // Scope uomId choices to the selected itemId. + table.getField("uomId").withPossibleValueSourceFilter(new QQueryFilter( + new QFilterCriteria("itemId", QCriteriaOperator.EQUALS, "${input.itemId}"))); + + return (table); + } + } + + + @QField(isEditable = false, isPrimaryKey = true) private Integer id; diff --git a/src/main/java/com/kingsrook/qbits/wms/receiving/model/WmsPutawayRule.java b/src/main/java/com/kingsrook/qbits/wms/receiving/model/WmsPutawayRule.java index 9786b04..4f46d4f 100644 --- a/src/main/java/com/kingsrook/qbits/wms/receiving/model/WmsPutawayRule.java +++ b/src/main/java/com/kingsrook/qbits/wms/receiving/model/WmsPutawayRule.java @@ -7,10 +7,6 @@ package com.kingsrook.qbits.wms.receiving.model; import java.time.Instant; -import com.kingsrook.qqq.backend.core.model.data.QField; -import com.kingsrook.qqq.backend.core.model.data.QRecord; -import com.kingsrook.qqq.backend.core.model.data.QRecordEntity; -import com.kingsrook.qqq.backend.core.model.metadata.producers.annotations.QMetaDataProducingEntity; import com.kingsrook.qbits.wms.core.enums.StorageRequirements; import com.kingsrook.qbits.wms.core.enums.VelocityClass; import com.kingsrook.qbits.wms.core.enums.ZoneType; @@ -18,13 +14,46 @@ import com.kingsrook.qbits.wms.core.model.WmsClient; import com.kingsrook.qbits.wms.core.model.WmsItemCategory; import com.kingsrook.qbits.wms.core.model.WmsWarehouse; import com.kingsrook.qbits.wms.core.model.WmsZone; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter; +import com.kingsrook.qqq.backend.core.model.data.QField; +import com.kingsrook.qqq.backend.core.model.data.QRecord; +import com.kingsrook.qqq.backend.core.model.data.QRecordEntity; +import com.kingsrook.qqq.backend.core.model.metadata.QInstance; +import com.kingsrook.qqq.backend.core.model.metadata.producers.MetaDataCustomizerInterface; +import com.kingsrook.qqq.backend.core.model.metadata.producers.annotations.QMetaDataProducingEntity; +import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData; -@QMetaDataProducingEntity(produceTableMetaData = true) +@QMetaDataProducingEntity(tableMetaDataCustomizer = WmsPutawayRule.TableMetaDataCustomizer.class, produceTableMetaData = true) public class WmsPutawayRule extends QRecordEntity { public static final String TABLE_NAME = "wmsPutawayRule"; + + + /******************************************************************************* + ** Customize dependent choices after entity fields have been produced. + *******************************************************************************/ + public static class TableMetaDataCustomizer implements MetaDataCustomizerInterface + { + /*************************************************************************** + ** Restrict possible values to the current form scope. + ***************************************************************************/ + @Override + public QTableMetaData customizeMetaData(QInstance qInstance, QTableMetaData table) + { + // Scope targetZoneId choices to the selected warehouseId. + table.getField("targetZoneId").withPossibleValueSourceFilter(new QQueryFilter( + new QFilterCriteria("warehouseId", QCriteriaOperator.EQUALS, "${input.warehouseId}"))); + + return (table); + } + } + + + @QField(isEditable = false, isPrimaryKey = true) private Integer id; diff --git a/src/main/java/com/kingsrook/qbits/wms/receiving/model/WmsReceipt.java b/src/main/java/com/kingsrook/qbits/wms/receiving/model/WmsReceipt.java index e3d844d..b1f44bd 100644 --- a/src/main/java/com/kingsrook/qbits/wms/receiving/model/WmsReceipt.java +++ b/src/main/java/com/kingsrook/qbits/wms/receiving/model/WmsReceipt.java @@ -6,7 +6,14 @@ package com.kingsrook.qbits.wms.receiving.model; import java.time.Instant; +import com.kingsrook.qbits.wms.core.enums.ReceiptStatus; +import com.kingsrook.qbits.wms.core.enums.ReceiptType; +import com.kingsrook.qbits.wms.core.model.WmsClient; +import com.kingsrook.qbits.wms.core.model.WmsWarehouse; import com.kingsrook.qqq.backend.core.exceptions.QException; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter; import com.kingsrook.qqq.backend.core.model.data.QField; import com.kingsrook.qqq.backend.core.model.data.QRecord; import com.kingsrook.qqq.backend.core.model.data.QRecordEntity; @@ -21,10 +28,6 @@ import com.kingsrook.qqq.backend.core.model.metadata.tables.QFieldSection; import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData; import com.kingsrook.qqq.backend.core.model.metadata.tables.SectionFactory; import com.kingsrook.qqq.backend.core.model.metadata.tables.Tier; -import com.kingsrook.qbits.wms.core.enums.ReceiptStatus; -import com.kingsrook.qbits.wms.core.enums.ReceiptType; -import com.kingsrook.qbits.wms.core.model.WmsClient; -import com.kingsrook.qbits.wms.core.model.WmsWarehouse; @QMetaDataProducingEntity( @@ -73,6 +76,11 @@ public class WmsReceipt extends QRecordEntity java.util.List.of("notes"))) .withSection(SectionFactory.defaultT3("createDate", "modifyDate")); + // Scope purchaseOrderId choices to the selected warehouseId and clientId. + table.getField("purchaseOrderId").withPossibleValueSourceFilter(new QQueryFilter( + new QFilterCriteria("warehouseId", QCriteriaOperator.EQUALS, "${input.warehouseId}"), + new QFilterCriteria("clientId", QCriteriaOperator.EQUALS, "${input.clientId}"))); + return (table); } } diff --git a/src/main/java/com/kingsrook/qbits/wms/receiving/model/WmsReceiptLine.java b/src/main/java/com/kingsrook/qbits/wms/receiving/model/WmsReceiptLine.java index 119bc2d..181b775 100644 --- a/src/main/java/com/kingsrook/qbits/wms/receiving/model/WmsReceiptLine.java +++ b/src/main/java/com/kingsrook/qbits/wms/receiving/model/WmsReceiptLine.java @@ -7,23 +7,52 @@ package com.kingsrook.qbits.wms.receiving.model; import java.time.Instant; import java.time.LocalDate; -import com.kingsrook.qqq.backend.core.model.data.QField; -import com.kingsrook.qqq.backend.core.model.data.QRecord; -import com.kingsrook.qqq.backend.core.model.data.QRecordEntity; -import com.kingsrook.qqq.backend.core.model.metadata.producers.annotations.QMetaDataProducingEntity; import com.kingsrook.qbits.wms.core.enums.ConditionCode; import com.kingsrook.qbits.wms.core.enums.QcStatus; import com.kingsrook.qbits.wms.core.enums.ReceiptStatus; import com.kingsrook.qbits.wms.core.model.WmsItem; import com.kingsrook.qbits.wms.core.model.WmsLicensePlate; import com.kingsrook.qbits.wms.core.model.WmsUnitOfMeasure; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter; +import com.kingsrook.qqq.backend.core.model.data.QField; +import com.kingsrook.qqq.backend.core.model.data.QRecord; +import com.kingsrook.qqq.backend.core.model.data.QRecordEntity; +import com.kingsrook.qqq.backend.core.model.metadata.QInstance; +import com.kingsrook.qqq.backend.core.model.metadata.producers.MetaDataCustomizerInterface; +import com.kingsrook.qqq.backend.core.model.metadata.producers.annotations.QMetaDataProducingEntity; +import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData; -@QMetaDataProducingEntity(produceTableMetaData = true) +@QMetaDataProducingEntity(tableMetaDataCustomizer = WmsReceiptLine.TableMetaDataCustomizer.class, produceTableMetaData = true) public class WmsReceiptLine extends QRecordEntity { public static final String TABLE_NAME = "wmsReceiptLine"; + + + /******************************************************************************* + ** Customize dependent choices after entity fields have been produced. + *******************************************************************************/ + public static class TableMetaDataCustomizer implements MetaDataCustomizerInterface + { + /*************************************************************************** + ** Restrict possible values to the current form scope. + ***************************************************************************/ + @Override + public QTableMetaData customizeMetaData(QInstance qInstance, QTableMetaData table) + { + // Scope uomId choices to the selected itemId. + table.getField("uomId").withPossibleValueSourceFilter(new QQueryFilter( + new QFilterCriteria("itemId", QCriteriaOperator.EQUALS, "${input.itemId}"))); + + return (table); + } + } + + + @QField(isEditable = false, isPrimaryKey = true) private Integer id; diff --git a/src/main/java/com/kingsrook/qbits/wms/returns/model/WmsReturnAuthorization.java b/src/main/java/com/kingsrook/qbits/wms/returns/model/WmsReturnAuthorization.java index 43a4c07..5864cc3 100644 --- a/src/main/java/com/kingsrook/qbits/wms/returns/model/WmsReturnAuthorization.java +++ b/src/main/java/com/kingsrook/qbits/wms/returns/model/WmsReturnAuthorization.java @@ -7,7 +7,15 @@ package com.kingsrook.qbits.wms.returns.model; import java.time.Instant; +import com.kingsrook.qbits.wms.core.enums.ReturnAuthorizationStatus; +import com.kingsrook.qbits.wms.core.enums.ReturnReasonCode; +import com.kingsrook.qbits.wms.core.model.WmsClient; +import com.kingsrook.qbits.wms.core.model.WmsWarehouse; +import com.kingsrook.qbits.wms.fulfillment.model.WmsOrder; import com.kingsrook.qqq.backend.core.exceptions.QException; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter; import com.kingsrook.qqq.backend.core.model.data.QField; import com.kingsrook.qqq.backend.core.model.data.QRecord; import com.kingsrook.qqq.backend.core.model.data.QRecordEntity; @@ -22,11 +30,6 @@ import com.kingsrook.qqq.backend.core.model.metadata.tables.QFieldSection; import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData; import com.kingsrook.qqq.backend.core.model.metadata.tables.SectionFactory; import com.kingsrook.qqq.backend.core.model.metadata.tables.Tier; -import com.kingsrook.qbits.wms.core.enums.ReturnAuthorizationStatus; -import com.kingsrook.qbits.wms.core.enums.ReturnReasonCode; -import com.kingsrook.qbits.wms.core.model.WmsClient; -import com.kingsrook.qbits.wms.core.model.WmsWarehouse; -import com.kingsrook.qbits.wms.fulfillment.model.WmsOrder; @QMetaDataProducingEntity( @@ -76,6 +79,11 @@ public class WmsReturnAuthorization extends QRecordEntity java.util.List.of("notes"))) .withSection(SectionFactory.defaultT3("createDate", "modifyDate")); + // Scope originalOrderId choices to the selected warehouseId and clientId. + table.getField("originalOrderId").withPossibleValueSourceFilter(new QQueryFilter( + new QFilterCriteria("warehouseId", QCriteriaOperator.EQUALS, "${input.warehouseId}"), + new QFilterCriteria("clientId", QCriteriaOperator.EQUALS, "${input.clientId}"))); + return (table); } } diff --git a/src/main/java/com/kingsrook/qbits/wms/shipping/model/WmsDockAppointment.java b/src/main/java/com/kingsrook/qbits/wms/shipping/model/WmsDockAppointment.java index 9e2bdba..037e6fa 100644 --- a/src/main/java/com/kingsrook/qbits/wms/shipping/model/WmsDockAppointment.java +++ b/src/main/java/com/kingsrook/qbits/wms/shipping/model/WmsDockAppointment.java @@ -7,7 +7,14 @@ package com.kingsrook.qbits.wms.shipping.model; import java.time.Instant; import java.time.LocalDate; +import com.kingsrook.qbits.wms.core.enums.DockAppointmentStatus; +import com.kingsrook.qbits.wms.core.enums.DockAppointmentType; +import com.kingsrook.qbits.wms.core.model.WmsLocation; +import com.kingsrook.qbits.wms.core.model.WmsWarehouse; import com.kingsrook.qqq.backend.core.exceptions.QException; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter; import com.kingsrook.qqq.backend.core.model.data.QField; import com.kingsrook.qqq.backend.core.model.data.QRecord; import com.kingsrook.qqq.backend.core.model.data.QRecordEntity; @@ -19,10 +26,6 @@ import com.kingsrook.qqq.backend.core.model.metadata.tables.QFieldSection; import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData; import com.kingsrook.qqq.backend.core.model.metadata.tables.SectionFactory; import com.kingsrook.qqq.backend.core.model.metadata.tables.Tier; -import com.kingsrook.qbits.wms.core.enums.DockAppointmentStatus; -import com.kingsrook.qbits.wms.core.enums.DockAppointmentType; -import com.kingsrook.qbits.wms.core.model.WmsLocation; -import com.kingsrook.qbits.wms.core.model.WmsWarehouse; @QMetaDataProducingEntity( @@ -60,6 +63,10 @@ public class WmsDockAppointment extends QRecordEntity java.util.List.of("referenceType", "referenceId", "notes"))) .withSection(SectionFactory.defaultT3("createDate", "modifyDate")); + // Scope dockDoorId choices to the selected warehouseId. + table.getField("dockDoorId").withPossibleValueSourceFilter(new QQueryFilter( + new QFilterCriteria("warehouseId", QCriteriaOperator.EQUALS, "${input.warehouseId}"))); + return (table); } } diff --git a/src/main/java/com/kingsrook/qbits/wms/shipping/model/WmsShipment.java b/src/main/java/com/kingsrook/qbits/wms/shipping/model/WmsShipment.java index c5346cd..94808c1 100644 --- a/src/main/java/com/kingsrook/qbits/wms/shipping/model/WmsShipment.java +++ b/src/main/java/com/kingsrook/qbits/wms/shipping/model/WmsShipment.java @@ -9,7 +9,15 @@ package com.kingsrook.qbits.wms.shipping.model; import java.math.BigDecimal; import java.time.Instant; import java.time.LocalDate; +import com.kingsrook.qbits.wms.core.enums.ShipmentStatus; +import com.kingsrook.qbits.wms.core.enums.ShippingMode; +import com.kingsrook.qbits.wms.core.model.WmsClient; +import com.kingsrook.qbits.wms.core.model.WmsLocation; +import com.kingsrook.qbits.wms.core.model.WmsWarehouse; import com.kingsrook.qqq.backend.core.exceptions.QException; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter; import com.kingsrook.qqq.backend.core.model.data.QField; import com.kingsrook.qqq.backend.core.model.data.QRecord; import com.kingsrook.qqq.backend.core.model.data.QRecordEntity; @@ -21,11 +29,6 @@ import com.kingsrook.qqq.backend.core.model.metadata.tables.QFieldSection; import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData; import com.kingsrook.qqq.backend.core.model.metadata.tables.SectionFactory; import com.kingsrook.qqq.backend.core.model.metadata.tables.Tier; -import com.kingsrook.qbits.wms.core.enums.ShipmentStatus; -import com.kingsrook.qbits.wms.core.enums.ShippingMode; -import com.kingsrook.qbits.wms.core.model.WmsClient; -import com.kingsrook.qbits.wms.core.model.WmsLocation; -import com.kingsrook.qbits.wms.core.model.WmsWarehouse; @QMetaDataProducingEntity( @@ -66,6 +69,14 @@ public class WmsShipment extends QRecordEntity java.util.List.of("labelUrl", "commercialInvoiceUrl"))) .withSection(SectionFactory.defaultT3("createDate", "modifyDate")); + // Scope dockDoorId choices to the selected warehouseId. + table.getField("dockDoorId").withPossibleValueSourceFilter(new QQueryFilter( + new QFilterCriteria("warehouseId", QCriteriaOperator.EQUALS, "${input.warehouseId}"))); + + // Scope manifestId choices to the selected warehouseId. + table.getField("manifestId").withPossibleValueSourceFilter(new QQueryFilter( + new QFilterCriteria("warehouseId", QCriteriaOperator.EQUALS, "${input.warehouseId}"))); + return (table); } } diff --git a/src/test/java/com/kingsrook/qbits/wms/ContingentPossibleValuesTest.java b/src/test/java/com/kingsrook/qbits/wms/ContingentPossibleValuesTest.java new file mode 100644 index 0000000..abe9d07 --- /dev/null +++ b/src/test/java/com/kingsrook/qbits/wms/ContingentPossibleValuesTest.java @@ -0,0 +1,184 @@ +/******************************************************************************* + ** Metadata and memory-backend regression tests for contingent possible values. + *******************************************************************************/ +package com.kingsrook.qbits.wms; + + +import java.io.Serializable; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import com.kingsrook.qbits.wms.inventory.processes.CycleCountProcessMetaDataProducer; +import com.kingsrook.qqq.backend.core.actions.values.SearchPossibleValueSourceAction; +import com.kingsrook.qqq.backend.core.context.QContext; +import com.kingsrook.qqq.backend.core.model.actions.tables.insert.InsertInput; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter; +import com.kingsrook.qqq.backend.core.model.actions.values.SearchPossibleValueSourceInput; +import com.kingsrook.qqq.backend.core.model.data.QRecord; +import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData; +import com.kingsrook.qqq.backend.core.model.metadata.possiblevalues.PossibleValueSearchFilterUseCase; +import com.kingsrook.qqq.backend.core.model.metadata.processes.QFrontendStepMetaData; +import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData; +import com.kingsrook.qqq.backend.core.modules.backend.implementations.memory.MemoryRecordStore; +import com.kingsrook.qqq.backend.core.utils.collections.MapBuilder; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + + +/******************************************************************************* + ** Verify declared dependencies and their behavior through real possible-value searches. + *******************************************************************************/ +public class ContingentPossibleValuesTest extends BaseTest +{ + /******************************************************************************* + ** Verify every dependent field and its referenced table, then search two scopes. + *******************************************************************************/ + @ParameterizedTest + @CsvSource({ + "wmsLocation,zoneId,warehouseId,warehouseId,,", + "wmsOrderLine,uomId,itemId,itemId,,", + "wmsAsnLine,uomId,itemId,itemId,,", + "wmsPurchaseOrderLine,uomId,itemId,itemId,,", + "wmsReceiptLine,uomId,itemId,itemId,,", + "wmsKitBom,componentUomId,itemId,componentItemId,,", + "wmsKitBom,kitItemId,clientId,clientId,,", + "wmsKitBom,componentItemId,clientId,clientId,,", + "wmsReceipt,purchaseOrderId,warehouseId,warehouseId,clientId,clientId", + "wmsOrder,waveId,warehouseId,warehouseId,,", + "wmsPurchaseOrder,dockDoorId,warehouseId,warehouseId,,", + "wmsDockAppointment,dockDoorId,warehouseId,warehouseId,,", + "wmsShipment,dockDoorId,warehouseId,warehouseId,,", + "wmsShipment,manifestId,warehouseId,warehouseId,,", + "wmsInventory,locationId,warehouseId,warehouseId,,", + "wmsInventory,lpnId,warehouseId,warehouseId,,", + "wmsInventory,itemId,clientId,clientId,,", + "wmsInventoryHold,locationId,warehouseId,warehouseId,,", + "wmsInventoryHold,itemId,clientId,clientId,,", + "wmsLicensePlate,locationId,warehouseId,warehouseId,,", + "wmsReplenishmentRule,pickLocationId,warehouseId,warehouseId,,", + "wmsReplenishmentRule,sourceZoneId,warehouseId,warehouseId,,", + "wmsPutawayRule,targetZoneId,warehouseId,warehouseId,,", + "wmsTask,lpnId,warehouseId,warehouseId,,", + "wmsTask,sourceLocationId,warehouseId,warehouseId,,", + "wmsTask,destinationLocationId,warehouseId,warehouseId,,", + "wmsTask,zoneId,warehouseId,warehouseId,,", + "wmsKitWorkOrder,kitItemId,clientId,clientId,,", + "wmsReturnAuthorization,originalOrderId,warehouseId,warehouseId,clientId,clientId", + "wmsBillingActivity,rateId,activityTypeId,activityTypeId,," + }) + void tableFilters(String tableName, String fieldName, String column, String input, String secondColumn, String secondInput) throws Exception + { + QTableMetaData table = QContext.getQInstance().getTable(tableName); + QFieldMetaData field = table.getField(fieldName); + assertTrue(field.getIsEditable()); + assertTrue(table.getField(input).getIsEditable()); + assertCriterion(field, 0, column, input); + assertEquals(secondColumn == null ? 1 : 2, field.getPossibleValueSourceFilter().getCriteria().size()); + if(secondColumn != null) + { + assertTrue(table.getField(secondInput).getIsEditable()); + assertCriterion(field, 1, secondColumn, secondInput); + } + assertSearchScopes(field, column, input, secondColumn, secondInput); + } + + + + /******************************************************************************* + ** The process field must carry its own filter, independent of table fields. + *******************************************************************************/ + @Test + void cycleCountForm() throws Exception + { + QFrontendStepMetaData step = (QFrontendStepMetaData) QContext.getQInstance() + .getProcess(CycleCountProcessMetaDataProducer.NAME).getStep("selectCountType"); + QFieldMetaData field = step.getFormField("zoneId"); + assertTrue(step.getFormField("warehouseId").getIsEditable()); + assertTrue(field.getIsEditable()); + assertCriterion(field, 0, "warehouseId", "warehouseId"); + assertEquals(1, field.getPossibleValueSourceFilter().getCriteria().size()); + assertSearchScopes(field, "warehouseId", "warehouseId", null, null); + } + + + + /******************************************************************************* + ** Validate the expression and the actual column on the possible-value table. + *******************************************************************************/ + private void assertCriterion(QFieldMetaData field, int index, String column, String input) + { + assertNotNull(field.getPossibleValueSourceFilter()); + QFilterCriteria criterion = field.getPossibleValueSourceFilter().getCriteria().get(index); + assertEquals(column, criterion.getFieldName()); + assertEquals(QCriteriaOperator.EQUALS, criterion.getOperator()); + assertEquals(List.of("${input." + input + "}"), criterion.getValues()); + String target = QContext.getQInstance().getPossibleValueSource(field.getPossibleValueSourceName()).getTableName(); + assertNotNull(QContext.getQInstance().getTable(target).getField(column)); + } + + + + /******************************************************************************* + ** Seed both scopes; paired filters also get rows matching only one criterion. + *******************************************************************************/ + private void assertSearchScopes(QFieldMetaData field, String column, String input, String secondColumn, String secondInput) throws Exception + { + String target = QContext.getQInstance().getPossibleValueSource(field.getPossibleValueSourceName()).getTableName(); + // Isolate contingent filtering from record-security authorization in this test. + QContext.getQInstance().getTable(target).setRecordSecurityLocks(List.of()); + seed(target, 101, column, 1, secondColumn, 1); + seed(target, 102, column, 2, secondColumn, 2); + Map values = Map.of(input, 1); + Set all = Set.of(101, 102); + if(secondColumn != null) + { + seed(target, 103, column, 1, secondColumn, 2); + seed(target, 104, column, 2, secondColumn, 1); + values = Map.of(input, 1, secondInput, 1); + all = Set.of(101, 102, 103, 104); + assertEquals(Set.of(), search(field, Map.of(input, 1), PossibleValueSearchFilterUseCase.FORM)); + assertEquals(Set.of(), search(field, Map.of(secondInput, 1), PossibleValueSearchFilterUseCase.FORM)); + } + assertEquals(Set.of(101), search(field, values, PossibleValueSearchFilterUseCase.FORM)); + assertEquals(Set.of(), search(field, Map.of(), PossibleValueSearchFilterUseCase.FORM)); + assertEquals(all, search(field, Map.of(), PossibleValueSearchFilterUseCase.FILTER)); + assertCriterion(field, 0, column, input); + } + + + + /******************************************************************************* + ** Seed the memory backend directly so unrelated required fields do not interfere. + *******************************************************************************/ + private void seed(String table, int id, String column, int scope, String secondColumn, int secondScope) throws Exception + { + QRecord record = new QRecord().withTableName(table).withValue("id", id).withValue(column, scope); + if(secondColumn != null) + { + record.setValue(secondColumn, secondScope); + } + MemoryRecordStore.getInstance().insert(new InsertInput(table).withRecord(record), true); + } + + + + /******************************************************************************* + ** Interpret a clone exactly as the UI does before invoking the real PVS action. + *******************************************************************************/ + private Set search(QFieldMetaData field, Map values, PossibleValueSearchFilterUseCase useCase) throws Exception + { + QQueryFilter filter = field.getPossibleValueSourceFilter().clone(); + filter.interpretValues(MapBuilder.of("input", values), useCase); + return new SearchPossibleValueSourceAction().execute(new SearchPossibleValueSourceInput() + .withPossibleValueSourceName(field.getPossibleValueSourceName()) + .withDefaultQueryFilter(filter)) + .getResults().stream().map(value -> (Serializable) value.getId()).collect(Collectors.toSet()); + } +}