PackagingUnitVO.java

  1. /*
  2.  * Copyright 2005-2025 the original author or authors.
  3.  *
  4.  * Licensed under the Apache License, Version 2.0 (the "License");
  5.  * you may not use this file except in compliance with the License.
  6.  * You may obtain a copy of the License at
  7.  *
  8.  * http://www.apache.org/licenses/LICENSE-2.0
  9.  *
  10.  * Unless required by applicable law or agreed to in writing, software
  11.  * distributed under the License is distributed on an "AS IS" BASIS,
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13.  * See the License for the specific language governing permissions and
  14.  * limitations under the License.
  15.  */
  16. package org.openwms.wms.inventory.api;

  17. import com.fasterxml.jackson.annotation.JsonFormat;
  18. import com.fasterxml.jackson.annotation.JsonIgnore;
  19. import com.fasterxml.jackson.annotation.JsonInclude;
  20. import com.fasterxml.jackson.annotation.JsonProperty;
  21. import jakarta.validation.Valid;
  22. import jakarta.validation.constraints.NotNull;
  23. import jakarta.validation.constraints.Null;
  24. import org.ameba.http.AbstractBase;
  25. import org.openwms.core.units.api.Measurable;
  26. import org.openwms.core.units.api.Weight;
  27. import org.openwms.wms.location.api.LocationVO;

  28. import java.beans.ConstructorProperties;
  29. import java.time.ZonedDateTime;
  30. import java.util.HashMap;
  31. import java.util.List;
  32. import java.util.Map;
  33. import java.util.Objects;
  34. import java.util.StringJoiner;

  35. import static org.openwms.wms.api.TimeProvider.DATE_TIME_WITH_TIMEZONE;

  36. /**
  37.  * A PackagingUnitVO represents a quantity of a {@code Product} packaged into a single physical unit.
  38.  *
  39.  * @author Heiko Scherrer
  40.  */
  41. @JsonInclude(JsonInclude.Include.NON_EMPTY)
  42. public class PackagingUnitVO extends AbstractBase<PackagingUnitVO> {

  43.     /** The persistent key of the {@code PackagingUnit}. */
  44.     @JsonProperty("pKey")
  45.     @Null(groups = ValidationGroups.CreatePackagingUnit.class)
  46.     public String pKey;
  47.     /** Some hint where to find the {@code PackagingUnit} within its container. */
  48.     @JsonProperty("physicalPosition")
  49.     public String physicalPosition;
  50.     /** The serial number of the {@code PackagingUnit}. */
  51.     @JsonProperty("serialNumber")
  52.     public String serialNumber;
  53.     /** The business key referring to a defined {@code Lot}. */
  54.     @JsonProperty("lotId")
  55.     private String lotId;
  56.     /** The expiration date of this particular {@code PackagingUnit}. */
  57.     @JsonProperty("expiresAt")
  58.     @JsonFormat(pattern = DATE_TIME_WITH_TIMEZONE)
  59.     private ZonedDateTime expiresAt;
  60.     /** The production date of this particular {@code PackagingUnit}. */
  61.     @JsonProperty("producedAt")
  62.     @JsonFormat(pattern = DATE_TIME_WITH_TIMEZONE)
  63.     private ZonedDateTime producedAt;
  64.     /** A {@code PackagingUnit} can have arbitrary labels assigned. */
  65.     @JsonProperty("labels")
  66.     private List<String> labels;
  67.     /** Packed {@code Product}, must not be {@literal null}. */
  68.     @JsonProperty("product")
  69.     public ProductVO product;
  70.     /** Described in what kind of UOM the PackagingUnit is stored in. */
  71.     @JsonProperty("productUnit")
  72.     public UomRelationVO uomRelation;
  73.     /** Packed quantity, must not be {@literal null}. */
  74.     @JsonProperty("quantity")
  75.     @NotNull
  76.     public Measurable quantity;
  77.     /** Calculated available quantity. */
  78.     @JsonProperty("qtyAvailable")
  79.     public Measurable qtyAvailable;
  80.     /** Availability state of this {@code PackagingUnit}. */
  81.     @JsonProperty("state")
  82.     private String state;
  83.     /** The comprising {@code LoadUnit} the {@code PackagingUnit} is stored in. */
  84.     @JsonProperty("loadUnit")
  85.     public LoadUnitVO loadUnit;
  86.     /** The actual {@code Location} the {@code PackagingUnit} is placed on. */
  87.     @JsonProperty("actualLocation")
  88.     public LocationVO actualLocation;
  89.     /** The current dimension of the {@code PackagingUnit}. */
  90.     @JsonProperty("dimension")
  91.     public DimensionVO dimension;
  92.     /** The current weight of the {@code PackagingUnit}. */
  93.     @JsonProperty("weight")
  94.     public Weight weight;
  95.     /** Any kind of message placed on the {@code PackagingUnit}. */
  96.     @JsonProperty("message")
  97.     public String message;
  98.     /** How are the {@code PackagingUnit}s distributed in a {@code LoadUnit}. */
  99.     @JsonProperty("distribution")
  100.     public PhysicalDistributionVO loadUnitDistribution;
  101.     /** Arbitrary detail information on this {@code PackagingUnit}. */
  102.     @JsonProperty("details")
  103.     private Map<String, String> details = new HashMap<>();

  104.     @Valid
  105.     public boolean validate() {
  106.         return !(this.product == null && this.uomRelation == null);
  107.     }

  108.     /*~ -------------- Constructors -------------- */
  109.     public PackagingUnitVO() { }

  110.     @ConstructorProperties({"product", "quantity"})
  111.     public PackagingUnitVO(ProductVO product, Measurable quantity) {
  112.         this.product = product;
  113.         this.quantity = quantity;
  114.     }

  115.     /*~ --------------- Methods ---------------- */
  116.     @JsonIgnore
  117.     @Valid
  118.     public boolean isValid() {
  119.         return (this.loadUnit == null && this.actualLocation != null) ||
  120.                 (this.loadUnit != null && this.actualLocation == null);
  121.     }

  122.     @JsonIgnore
  123.     public boolean hasLoadUnit() {
  124.         return this.loadUnit != null;
  125.     }

  126.     @JsonIgnore
  127.     public boolean hasActualLocation() {
  128.         return this.actualLocation != null;
  129.     }

  130.     /**
  131.      * {@inheritDoc}
  132.      *
  133.      * Not:
  134.      * - details
  135.      */
  136.     @Override
  137.     public String toString() {
  138.         return new StringJoiner(", ", PackagingUnitVO.class.getSimpleName() + "[", "]")
  139.                 .add("pKey='" + pKey + "'")
  140.                 .add("physicalPosition='" + physicalPosition + "'")
  141.                 .add("serialNumber='" + serialNumber + "'")
  142.                 .add("lotId='" + lotId + "'")
  143.                 .add("expiresAt=" + expiresAt)
  144.                 .add("producedAt=" + producedAt)
  145.                 .add("labels=" + labels)
  146.                 .add("product=" + product)
  147.                 .add("quantity=" + quantity)
  148.                 .add("state='" + state + "'")
  149.                 .add("loadUnit=" + loadUnit)
  150.                 .add("actualLocation=" + actualLocation)
  151.                 .add("dimension=" + dimension)
  152.                 .add("weight=" + weight)
  153.                 .add("message='" + message + "'")
  154.                 .add("loadUnitDistribution=" + loadUnitDistribution)
  155.                 .toString();
  156.     }

  157.     /**
  158.      * {@inheritDoc}
  159.      *
  160.      * Not:
  161.      * - details
  162.      */
  163.     @Override
  164.     public boolean equals(Object o) {
  165.         if (this == o) return true;
  166.         if (!(o instanceof PackagingUnitVO)) return false;
  167.         if (!super.equals(o)) return false;
  168.         PackagingUnitVO that = (PackagingUnitVO) o;
  169.         return Objects.equals(pKey, that.pKey) && Objects.equals(physicalPosition, that.physicalPosition) && Objects.equals(serialNumber, that.serialNumber)&& Objects.equals(lotId, that.lotId) && Objects.equals(expiresAt, that.expiresAt) && Objects.equals(producedAt, that.producedAt) && Objects.equals(labels, that.labels) && Objects.equals(product, that.product) && Objects.equals(quantity, that.quantity) && Objects.equals(state, that.state) && Objects.equals(loadUnit, that.loadUnit) && Objects.equals(actualLocation, that.actualLocation) && Objects.equals(dimension, that.dimension) && Objects.equals(weight, that.weight) && Objects.equals(message, that.message) && Objects.equals(loadUnitDistribution, that.loadUnitDistribution);
  170.     }

  171.     /**
  172.      * {@inheritDoc}
  173.      *
  174.      * Not:
  175.      * - details
  176.      */
  177.     @Override
  178.     public int hashCode() {
  179.         return Objects.hash(super.hashCode(), pKey, physicalPosition, serialNumber, lotId, expiresAt, producedAt, labels, product, quantity, state, loadUnit, actualLocation, dimension, weight, message, loadUnitDistribution);
  180.     }

  181.     /*~ --------------- Accessors ---------------- */

  182.     public String getpKey() {
  183.         return pKey;
  184.     }

  185.     public void setpKey(String pKey) {
  186.         this.pKey = pKey;
  187.     }

  188.     public String getPhysicalPosition() {
  189.         return physicalPosition;
  190.     }

  191.     public void setPhysicalPosition(String physicalPosition) {
  192.         this.physicalPosition = physicalPosition;
  193.     }

  194.     public String getSerialNumber() {
  195.         return serialNumber;
  196.     }

  197.     public void setSerialNumber(String serialNumber) {
  198.         this.serialNumber = serialNumber;
  199.     }

  200.     public String getLotId() {
  201.         return lotId;
  202.     }

  203.     public void setLotId(String lotId) {
  204.         this.lotId = lotId;
  205.     }

  206.     public ZonedDateTime getExpiresAt() {
  207.         return expiresAt;
  208.     }

  209.     public void setExpiresAt(ZonedDateTime expiresAt) {
  210.         this.expiresAt = expiresAt;
  211.     }

  212.     public ZonedDateTime getProducedAt() {
  213.         return producedAt;
  214.     }

  215.     public void setProducedAt(ZonedDateTime producedAt) {
  216.         this.producedAt = producedAt;
  217.     }

  218.     public List<String> getLabels() {
  219.         return labels;
  220.     }

  221.     public void setLabels(List<String> labels) {
  222.         this.labels = labels;
  223.     }

  224.     public ProductVO getProduct() {
  225.         return product;
  226.     }

  227.     public void setProduct(ProductVO product) {
  228.         this.product = product;
  229.     }

  230.     public UomRelationVO getUomRelation() {
  231.         return uomRelation;
  232.     }

  233.     public void setUomRelation(UomRelationVO uomRelation) {
  234.         this.uomRelation = uomRelation;
  235.     }

  236.     public Measurable getQuantity() {
  237.         return quantity;
  238.     }

  239.     public void setQuantity(Measurable quantity) {
  240.         this.quantity = quantity;
  241.     }

  242.     public Measurable getQtyAvailable() {
  243.         return qtyAvailable;
  244.     }

  245.     public void setQtyAvailable(Measurable qtyAvailable) {
  246.         this.qtyAvailable = qtyAvailable;
  247.     }

  248.     public String getState() {
  249.         return state;
  250.     }

  251.     public void setState(String state) {
  252.         this.state = state;
  253.     }

  254.     public LoadUnitVO getLoadUnit() {
  255.         return loadUnit;
  256.     }

  257.     public void setLoadUnit(LoadUnitVO loadUnit) {
  258.         this.loadUnit = loadUnit;
  259.     }

  260.     public LocationVO getActualLocation() {
  261.         return actualLocation;
  262.     }

  263.     public void setActualLocation(LocationVO actualLocation) {
  264.         this.actualLocation = actualLocation;
  265.     }

  266.     public DimensionVO getDimension() {
  267.         return dimension;
  268.     }

  269.     public void setDimension(DimensionVO dimension) {
  270.         this.dimension = dimension;
  271.     }

  272.     public Weight getWeight() {
  273.         return weight;
  274.     }

  275.     public void setWeight(Weight weight) {
  276.         this.weight = weight;
  277.     }

  278.     public String getMessage() {
  279.         return message;
  280.     }

  281.     public void setMessage(String message) {
  282.         this.message = message;
  283.     }

  284.     public PhysicalDistributionVO getLoadUnitDistribution() {
  285.         return loadUnitDistribution;
  286.     }

  287.     public void setLoadUnitDistribution(PhysicalDistributionVO loadUnitDistribution) {
  288.         this.loadUnitDistribution = loadUnitDistribution;
  289.     }

  290.     public Map<String, String> getDetails() {
  291.         return details;
  292.     }

  293.     public void setDetails(Map<String, String> details) {
  294.         this.details = details;
  295.     }
  296. }