package org.hso.ecommerce.action.warehouse; import org.hso.ecommerce.entities.booking.BookingReason; import org.hso.ecommerce.entities.shop.Article; import org.hso.ecommerce.entities.supplier.SupplierOrder; import org.hso.ecommerce.entities.warehouse.WarehouseBooking; import org.hso.ecommerce.entities.warehouse.WarehouseBookingPosition; import org.hso.ecommerce.entities.warehouse.WarehouseBookingPositionSlotEntry; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Date; import java.util.List; public class SupplierOrderArrivedAction { private final Article article; private final ArrayList warehouseCandidates; private final SupplierOrder order; public SupplierOrderArrivedAction(List warehouseCandidates, SupplierOrder order, Article article) { this.warehouseCandidates = new ArrayList<>(warehouseCandidates); this.order = order; this.article = article; } public Result finish() throws NoSpaceInWarehouseException { // Sort for most filled slot first; warehouseCandidates.sort((b, a) -> Integer.compare(a.newSumSlot, b.newSumSlot)); int needed = order.numberOfUnits; WarehouseBooking booking = new WarehouseBooking(); booking.created = new Timestamp(new Date().getTime()); booking.reason = new BookingReason(order); for (WarehouseBookingPositionSlotEntry entry : warehouseCandidates) { int canBeAdded = article.warehouseUnitsPerSlot - entry.newSumSlot; if (canBeAdded == 0) { // this slot is full, skip continue; } int willBeAdded = Math.min(canBeAdded, needed); needed -= willBeAdded; WarehouseBookingPosition bookingPosition = new WarehouseBookingPosition(); bookingPosition.article = article; bookingPosition.amount = willBeAdded; bookingPosition.slotEntry = entry.copyAddAmount(willBeAdded, article); bookingPosition.booking = booking; booking.positions.add(bookingPosition); if (needed == 0) { break; } } if (needed > 0) { throw new NoSpaceInWarehouseException(article); } order.delivered = new Timestamp(new Date().getTime()); return new Result(order, booking); } public static class Result extends Exception { private final SupplierOrder order; private final WarehouseBooking booking; public Result(SupplierOrder order, WarehouseBooking booking) { this.order = order; this.booking = booking; } public SupplierOrder getOrder() { return order; } public WarehouseBooking getBooking() { return booking; } } public static class NoSpaceInWarehouseException extends Exception { private Article article; public NoSpaceInWarehouseException(Article article) { super("The quantity of article '" + article.title + "' does not fit in warehouse."); this.article = article; } public Article getArticle() { return article; } } }