Skip to content

Commit

Permalink
Merge pull request #27 from openwms/20_Consider_UOMRelation_and_Label
Browse files Browse the repository at this point in the history
  • Loading branch information
openwms committed Apr 1, 2023
2 parents d4a4826 + b013d2c commit 4eb6c27
Show file tree
Hide file tree
Showing 27 changed files with 377 additions and 79 deletions.
11 changes: 11 additions & 0 deletions src/main/java/org/openwms/wms/receiving/ReceivingMapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.openwms.wms.receiving.impl.ReceivingOrderPosition;
import org.openwms.wms.receiving.impl.ReceivingTransportUnitOrderPosition;
import org.openwms.wms.receiving.inventory.Product;
import org.openwms.wms.receiving.spi.wms.inventory.ProductVO;
import org.openwms.wms.receiving.transport.TransportUnit;

import java.util.List;
Expand Down Expand Up @@ -84,9 +85,19 @@ default ReceivingOrderPositionMO fromEOtoMO(BaseReceivingOrderPosition eo, @Cont
}

@Mapping(target = "foreignPKey", source = "pKey")
@Mapping(target = "overbookingAllowed", source = "overbookingAllowed")
@Mapping(target = "ol", ignore = true)
Product convertFromMO(ProductMO mo);

@Mapping(target = "foreignPKey", source = "pKey")
@Mapping(target = "sku", source = "sku")
@Mapping(target = "label", source = "label")
@Mapping(target = "baseUnit", source = "baseUnit")
@Mapping(target = "description", source = "description")
@Mapping(target = "overbookingAllowed", source = "overbookingAllowed")
@Mapping(target = "ol", ignore = true)
Product convertFromVO(ProductVO vo);

@Mapping(target = "foreignPKey", source = "pKey")
@Mapping(target = "ol", ignore = true)
TransportUnit convertFromMO(TransportUnitMO mo);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class QuantityCaptureRequestVO extends CaptureRequestVO implements Serializable {

/** The business key of the captured {@code TransportUnit} where the goods are captured in. */
@JsonProperty("transportUnitBK")
@NotBlank(groups = ValidationGroups.CreateQuantityReceipt.class)
private String transportUnitId;
/** The captured {@code TransportUnit} where the goods are captured in. */
@JsonProperty("transportUnit")
@NotNull(groups = ValidationGroups.CreateQuantityReceipt.class)
private TransportUnitVO transportUnit;

/** The unique identifier if the {@code LoadUnit} where the goods are captured in. */
@JsonProperty("loadUnitLabel")
Expand Down Expand Up @@ -64,12 +64,12 @@ public class QuantityCaptureRequestVO extends CaptureRequestVO implements Serial
@JsonProperty("lotId")
private String lotId;

public String getTransportUnitId() {
return transportUnitId;
public TransportUnitVO getTransportUnit() {
return transportUnit;
}

public void setTransportUnitId(String transportUnitId) {
this.transportUnitId = transportUnitId;
public void setTransportUnit(TransportUnitVO transportUnit) {
this.transportUnit = transportUnit;
}

public String getLoadUnitLabel() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ public class TransportUnitVO extends AbstractBase<LocationVO> implements Seriali
@JsonProperty("transportUnitType")
private String transportUnitType;

public TransportUnitVO() {
}

public TransportUnitVO(String transportUnitId) {
this.transportUnitId = transportUnitId;
}

public String getTransportUnitId() {
return transportUnitId;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public class ProductMO implements Serializable {
private String sku;
private String label;
private Measurable baseUnit;
private Boolean overbookingAllowed;
private String description;

public String getpKey() {
Expand Down Expand Up @@ -65,6 +66,14 @@ public void setBaseUnit(Measurable baseUnit) {
this.baseUnit = baseUnit;
}

public Boolean getOverbookingAllowed() {
return overbookingAllowed;
}

public void setOverbookingAllowed(Boolean overbookingAllowed) {
this.overbookingAllowed = overbookingAllowed;
}

public String getDescription() {
return description;
}
Expand Down
37 changes: 37 additions & 0 deletions src/main/java/org/openwms/wms/receiving/events/CacheJanitor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright 2005-2022 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openwms.wms.receiving.events;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Component;

/**
* A CacheJanitor is used to evict caches.
*
* @author Heiko Scherrer
*/
@Component
public class CacheJanitor {

private static final Logger LOGGER = LoggerFactory.getLogger(CacheJanitor.class);

@CacheEvict(cacheNames = "products", allEntries = true)
public void evictProductCache() {
LOGGER.debug("Product cache evicted");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ private Optional<ReceivingOrder> handleExpectedReceipt(String pKey, Measurable q
ReceivingOrderPosition position;
// Got an unexpected receipt. If this is configured to be okay we proceed otherwise throw
if (openPosition.isEmpty()) {
if (openPositions.get(0).getProduct().isOverbookingAllowed()) {
if (openPositions.get(0).getProduct().getOverbookingAllowed()) {
position = openPositions.get(0);
} else {
LOGGER.error("Received a goods receipt but all ReceivingOrderPositions are already satisfied and unexpected receipts are not allowed");
Expand All @@ -120,7 +120,7 @@ private Optional<ReceivingOrder> handleExpectedReceipt(String pKey, Measurable q
private void createPackagingUnitsForDemand(QuantityCaptureRequestVO request) {
final var sku = request.getProduct().getSku();
final var quantityReceived = request.getQuantityReceived();
final var transportUnitId = request.getTransportUnitId();
final var transportUnitId = request.getTransportUnit().getTransportUnitId();
final var loadUnitPosition = request.getLoadUnitLabel();
final var existingProduct = getProduct(sku);
final var details = request.getDetails();
Expand All @@ -133,9 +133,6 @@ private void createPackagingUnitsForDemand(QuantityCaptureRequestVO request) {
pu.setDetails(details);
pu.setSerialNumber(request.getSerialNumber());
pu.setLotId(request.getLotId());
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Create new PackagingUnit [{}] on TransportUnit [{}] and LoadUnit [{}]", pu, transportUnitId, loadUnitPosition);
}
asyncPackagingUnitApi.create(new CreatePackagingUnitCommand(transportUnitId, loadUnitPosition, request.getLoadUnitType(), pu));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
import javax.validation.constraints.NotNull;
import java.io.Serializable;

import static javax.persistence.CascadeType.MERGE;
import static javax.persistence.CascadeType.PERSIST;
import static org.openwms.wms.order.OrderState.COMPLETED;

/**
Expand Down Expand Up @@ -64,7 +66,7 @@ public class ReceivingOrderPosition extends BaseReceivingOrderPosition implement
private Measurable quantityReceived;

/** The expected {@link Product} to be receipt. */
@ManyToOne
@ManyToOne(cascade = {PERSIST, MERGE})
@JoinColumn(name = "C_SKU", referencedColumnName = "C_SKU", foreignKey = @ForeignKey(name = "FK_REC_POS_PRODUCT"), nullable = false)
@NotNull(groups = ValidationGroups.CreateQuantityReceipt.class)
private Product product;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public class Product extends ApplicationEntity implements Comparable<Product>, S

@NotNull
@Column(name = "C_OVERBOOKING_ALLOWED", nullable = false)
private boolean overbookingAllowed;
private Boolean overbookingAllowed;

/** Dear JPA ... */
protected Product() {
Expand Down Expand Up @@ -134,11 +134,11 @@ public void setBaseUnit(Measurable baseUnit) {
this.baseUnit = baseUnit;
}

public boolean isOverbookingAllowed() {
public Boolean getOverbookingAllowed() {
return overbookingAllowed;
}

public void setOverbookingAllowed(boolean overbookingAllowed) {
public void setOverbookingAllowed(Boolean overbookingAllowed) {
this.overbookingAllowed = overbookingAllowed;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
package org.openwms.wms.receiving.inventory;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.Optional;

/**
Expand All @@ -33,10 +32,4 @@ public interface ProductService {
* @return The instance
*/
Optional<Product> findBySku(@NotBlank String sku);

void create(@NotNull Product product);

Product update(@NotNull Product product);

void delete(@NotBlank String pKey);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright 2005-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openwms.wms.receiving.inventory;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;

/**
* A ProductSynchronizer offers methods to synchronize the internal state of a {@link Product} with an external source.
*
* @author Heiko Scherrer
*/
public interface ProductSynchronizer {

/**
* Create a new {@link Product} instance.
*
* @param product The instance to create
*/
void create(@NotNull Product product);

/**
* Update an existing {@link Product} instance
*
* @param product The instance to update
* @return The updated instance
*/
Product update(@NotNull Product product);

/**
* Delete an existing {@link Product}.
*
* @param pKey The persistent key of the instance to delete
*/
void delete(@NotBlank String pKey);
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@
*/
package org.openwms.wms.receiving.inventory.impl;

import org.openwms.wms.receiving.events.CacheJanitor;
import org.openwms.wms.receiving.events.ProductEvent;
import org.openwms.wms.receiving.inventory.Product;
import org.openwms.wms.receiving.inventory.ProductService;
import org.openwms.wms.receiving.inventory.ProductSynchronizer;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

Expand All @@ -29,18 +30,21 @@
@Component
public class ProductEventListener {

private final ProductService productService;
private final CacheJanitor cacheJanitor;
private final ProductSynchronizer productSynchronizer;

public ProductEventListener(ProductService productService) {
this.productService = productService;
public ProductEventListener(CacheJanitor cacheJanitor, ProductSynchronizer productSynchronizer) {
this.cacheJanitor = cacheJanitor;
this.productSynchronizer = productSynchronizer;
}

@EventListener
public void onEvent(ProductEvent event) {
cacheJanitor.evictProductCache();
switch (event.getType()) {
case CREATED -> productService.create((Product) event.getSource());
case UPDATED -> productService.update((Product) event.getSource());
case DELETED -> productService.delete((String) event.getSource());
case CREATED -> productSynchronizer.create((Product) event.getSource());
case UPDATED -> productSynchronizer.update((Product) event.getSource());
case DELETED -> productSynchronizer.delete((String) event.getSource());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,7 @@ public interface ProductRepository extends JpaRepository<Product, Long> {

Optional<Product> findBypKey(String persistentKey);

Optional<Product> findByForeignPKey(String foreignPKey);

Optional<Product> findBySku(String sku);
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,14 @@

import org.ameba.annotation.Measured;
import org.ameba.annotation.TxService;
import org.openwms.wms.receiving.ReceivingMapper;
import org.openwms.wms.receiving.inventory.Product;
import org.openwms.wms.receiving.inventory.ProductService;
import org.openwms.wms.receiving.spi.wms.inventory.SyncProductApi;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.Optional;

/**
Expand All @@ -32,10 +35,15 @@
@TxService
class ProductServiceImpl implements ProductService {

private static final Logger LOGGER = LoggerFactory.getLogger(ProductServiceImpl.class);
private final ReceivingMapper receivingMapper;
private final ProductRepository repository;
private final SyncProductApi productApi;

ProductServiceImpl(ProductRepository repository) {
ProductServiceImpl(ReceivingMapper receivingMapper, ProductRepository repository, SyncProductApi productApi) {
this.receivingMapper = receivingMapper;
this.repository = repository;
this.productApi = productApi;
}

/**
Expand All @@ -44,33 +52,15 @@ class ProductServiceImpl implements ProductService {
@Override
@Measured
public Optional<Product> findBySku(@NotBlank String sku) {
return repository.findBySku(sku);
}

/**
* {@inheritDoc}
*/
@Override
@Measured
public void create(@NotNull Product product) {
repository.save(product);
}

/**
* {@inheritDoc}
*/
@Override
@Measured
public Product update(@NotNull Product product) {
return repository.save(product);
}

/**
* {@inheritDoc}
*/
@Override
@Measured
public void delete(@NotBlank String pKey) {
repository.findBypKey(pKey).ifPresent(repository::delete);
var vo = productApi.findBySKU(sku);
if (vo == null) {
LOGGER.debug("Getting the Product with [{}] from the database instead of the Inventory Service", sku);
return repository.findBySku(sku);
}
var savedOne = repository.findByForeignPKey(vo.getpKey());
if (savedOne.isPresent()) {
return savedOne;
}
return Optional.of(receivingMapper.convertFromVO(vo));
}
}

0 comments on commit 4eb6c27

Please sign in to comment.