CreateWarehouseUseCase.java
package com.fulfilment.application.monolith.warehouses.domain.usecases;
import com.fulfilment.application.monolith.warehouses.domain.models.Location;
import com.fulfilment.application.monolith.warehouses.domain.models.Warehouse;
import com.fulfilment.application.monolith.warehouses.domain.ports.CreateWarehouseOperation;
import com.fulfilment.application.monolith.warehouses.domain.ports.LocationResolver;
import com.fulfilment.application.monolith.warehouses.domain.ports.WarehouseStore;
import jakarta.enterprise.context.ApplicationScoped;
import com.fulfilment.application.monolith.exception.HttpStatus;
import jakarta.ws.rs.BadRequestException;
import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.Response;
import java.time.LocalDateTime;
import java.util.List;
import org.jboss.logging.Logger;
@ApplicationScoped
public class CreateWarehouseUseCase implements CreateWarehouseOperation {
private static final Logger LOGGER = Logger.getLogger(CreateWarehouseUseCase.class.getName());
private final WarehouseStore warehouseStore;
private final LocationResolver locationResolver;
public CreateWarehouseUseCase(WarehouseStore warehouseStore, LocationResolver locationResolver) {
this.warehouseStore = warehouseStore;
this.locationResolver = locationResolver;
}
@Override
public void create(Warehouse warehouse) {
LOGGER.debugf("Attempting to create warehouse with businessUnitCode: %s at location: %s",
warehouse.businessUnitCode, warehouse.location);
// 1. Validate location exists
Location location = locationResolver.resolveByIdentifier(warehouse.location);
if (location == null) {
LOGGER.warnf("Location '%s' not found", warehouse.location);
throw new BadRequestException(
"Location '" + warehouse.location + "' does not exist.");
}
// 2. Validate business unit code is unique among active warehouses
Warehouse existing = warehouseStore.findByBusinessUnitCode(warehouse.businessUnitCode);
if (existing != null) {
LOGGER.warnf("Warehouse with businessUnitCode '%s' already exists", warehouse.businessUnitCode);
throw new WebApplicationException(
"Warehouse with business unit code '" + warehouse.businessUnitCode + "' already exists.", Response.Status.CONFLICT);
}
// 3. Check location has not reached its max number of warehouses
List<Warehouse> warehousesAtLocation = warehouseStore.getAll().stream()
.filter(w -> warehouse.location.equals(w.location))
.toList();
if (warehousesAtLocation.size() >= location.maxNumberOfWarehouses) {
LOGGER.warnf("Location '%s' has reached max warehouse count of %d",
warehouse.location, location.maxNumberOfWarehouses);
throw new WebApplicationException(
"Location '" + warehouse.location + "' has reached the maximum number of warehouses ("
+ location.maxNumberOfWarehouses + ").", HttpStatus.UNPROCESSABLE_ENTITY);
}
// 4. Check location total capacity is not exceeded
int usedCapacity = warehousesAtLocation.stream()
.mapToInt(w -> w.capacity)
.sum();
if (usedCapacity + warehouse.capacity > location.maxCapacity) {
LOGGER.warnf("Location '%s' max capacity %d would be exceeded (used: %d, new: %d)",
warehouse.location, location.maxCapacity, usedCapacity, warehouse.capacity);
throw new WebApplicationException(
"Adding this warehouse would exceed the maximum capacity of location '"
+ warehouse.location + "' (max: " + location.maxCapacity
+ ", used: " + usedCapacity + ", requested: " + warehouse.capacity + ").", HttpStatus.UNPROCESSABLE_ENTITY);
}
// 5. Validate warehouse capacity can accommodate its stock
if (warehouse.capacity < warehouse.stock) {
LOGGER.warnf("Warehouse capacity %d is less than stock %d", warehouse.capacity, warehouse.stock);
throw new WebApplicationException(
"Warehouse capacity (" + warehouse.capacity + ") cannot be less than its stock ("
+ warehouse.stock + ").", HttpStatus.UNPROCESSABLE_ENTITY);
}
// All validations passed — set creation timestamp and persist
warehouse.createdAt = LocalDateTime.now();
warehouseStore.create(warehouse);
LOGGER.infof("Warehouse '%s' created successfully at location '%s'",
warehouse.businessUnitCode, warehouse.location);
}
}