modular monolith, context maps left in app-monolith
This commit is contained in:
54
adapter-commons/pom.xml
Normal file
54
adapter-commons/pom.xml
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>pl.com.bottega</groupId>
|
||||||
|
<artifactId>adapter-commons</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>1.5.8.RELEASE</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-rest</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||||
|
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||||
|
<version>2.8.5</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<version>3.0.2</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>test-jar</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
||||||
@@ -2,11 +2,9 @@ package pl.com.bottega.tools;
|
|||||||
|
|
||||||
import org.springframework.data.repository.CrudRepository;
|
import org.springframework.data.repository.CrudRepository;
|
||||||
import org.springframework.data.rest.core.annotation.RestResource;
|
import org.springframework.data.rest.core.annotation.RestResource;
|
||||||
import org.springframework.stereotype.Repository;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
@Repository
|
|
||||||
public interface CommandRepository<T, ID extends Serializable> extends CrudRepository<T, ID> {
|
public interface CommandRepository<T, ID extends Serializable> extends CrudRepository<T, ID> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -2,11 +2,9 @@ package pl.com.bottega.tools;
|
|||||||
|
|
||||||
import org.springframework.data.repository.CrudRepository;
|
import org.springframework.data.repository.CrudRepository;
|
||||||
import org.springframework.data.rest.core.annotation.RestResource;
|
import org.springframework.data.rest.core.annotation.RestResource;
|
||||||
import org.springframework.stereotype.Repository;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
@Repository
|
|
||||||
public interface ProjectionRepository<T, ID extends Serializable> extends CrudRepository<T, ID> {
|
public interface ProjectionRepository<T, ID extends Serializable> extends CrudRepository<T, ID> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -17,19 +17,37 @@
|
|||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>pl.com.bottega</groupId>
|
<groupId>pl.com.bottega</groupId>
|
||||||
<artifactId>shared-kernel-model</artifactId>
|
<artifactId>demand-forecasting-adapters</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>pl.com.bottega</groupId>
|
<groupId>pl.com.bottega</groupId>
|
||||||
<artifactId>demand-forecasting-model</artifactId>
|
<artifactId>shortages-prediction-adapters</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>pl.com.bottega</groupId>
|
<groupId>pl.com.bottega</groupId>
|
||||||
<artifactId>shortages-prediction-model</artifactId>
|
<artifactId>product-management-adapters</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>pl.com.bottega</groupId>
|
||||||
|
<artifactId>production-planning-adapters</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>pl.com.bottega</groupId>
|
||||||
|
<artifactId>adapter-commons</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>pl.com.bottega</groupId>
|
||||||
|
<artifactId>adapter-commons</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<type>test-jar</type>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.projectlombok</groupId>
|
<groupId>org.projectlombok</groupId>
|
||||||
@@ -53,11 +71,6 @@
|
|||||||
<groupId>org.springframework.data</groupId>
|
<groupId>org.springframework.data</groupId>
|
||||||
<artifactId>spring-data-rest-hal-browser</artifactId>
|
<artifactId>spring-data-rest-hal-browser</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>com.fasterxml.jackson.datatype</groupId>
|
|
||||||
<artifactId>jackson-datatype-jsr310</artifactId>
|
|
||||||
<version>2.8.5</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-test</artifactId>
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
package pl.com.bottega.factory.delivery.planning.definition;
|
package pl.com.bottega.factory.delivery.planning.definition;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import org.springframework.data.rest.core.annotation.*;
|
import org.springframework.data.rest.core.annotation.HandleAfterCreate;
|
||||||
|
import org.springframework.data.rest.core.annotation.HandleAfterSave;
|
||||||
|
import org.springframework.data.rest.core.annotation.RepositoryEventHandler;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import pl.com.bottega.factory.delivery.planning.projection.DeliveryForecastProjection;
|
import pl.com.bottega.factory.delivery.planning.projection.DeliveryForecastProjection;
|
||||||
|
|
||||||
|
|||||||
@@ -1,76 +0,0 @@
|
|||||||
package pl.com.bottega.factory.demand.forecasting;
|
|
||||||
|
|
||||||
import lombok.*;
|
|
||||||
import pl.com.bottega.tools.JsonConverter;
|
|
||||||
import pl.com.bottega.tools.TechnicalId;
|
|
||||||
|
|
||||||
import javax.persistence.*;
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.time.LocalDate;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@Entity(name = "Demand")
|
|
||||||
@Data
|
|
||||||
@NoArgsConstructor
|
|
||||||
@EqualsAndHashCode(of = "id")
|
|
||||||
@ToString(exclude = "product")
|
|
||||||
public class DemandEntity implements Serializable {
|
|
||||||
|
|
||||||
@Id
|
|
||||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
|
||||||
private Long id;
|
|
||||||
@ManyToOne
|
|
||||||
private ProductDemandEntity product;
|
|
||||||
@Column
|
|
||||||
private LocalDate date;
|
|
||||||
@Column
|
|
||||||
@Convert(converter = DemandAsJson.class)
|
|
||||||
private DemandValue value;
|
|
||||||
|
|
||||||
DemandEntity(ProductDemandEntity product, LocalDate date) {
|
|
||||||
this.product = product;
|
|
||||||
this.date = date;
|
|
||||||
}
|
|
||||||
|
|
||||||
DemandEntityId createId() {
|
|
||||||
return new DemandEntityId(product.getRefNo(), date, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
void set(Demand demand, Adjustment adjustment) {
|
|
||||||
value = new DemandValue(demand, adjustment);
|
|
||||||
}
|
|
||||||
|
|
||||||
DemandValue get() {
|
|
||||||
return Optional.ofNullable(value)
|
|
||||||
.orElse(DemandValue.NO_VAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Value
|
|
||||||
static class DemandValue {
|
|
||||||
public static final DemandValue NO_VAL = new DemandValue(null, null);
|
|
||||||
|
|
||||||
Demand documented;
|
|
||||||
Adjustment adjustment;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class DemandAsJson extends JsonConverter<DemandValue> {
|
|
||||||
public DemandAsJson() {
|
|
||||||
super(DemandValue.class);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
static class DemandEntityId extends DailyId implements TechnicalId {
|
|
||||||
|
|
||||||
Long id;
|
|
||||||
|
|
||||||
DemandEntityId(String refNo, LocalDate date) {
|
|
||||||
super(refNo, date);
|
|
||||||
}
|
|
||||||
|
|
||||||
DemandEntityId(String refNo, LocalDate date, Long id) {
|
|
||||||
super(refNo, date);
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -7,7 +7,7 @@ import pl.com.bottega.factory.delivery.planning.projection.DeliveryForecastProje
|
|||||||
import pl.com.bottega.factory.demand.forecasting.command.DemandReviewDao;
|
import pl.com.bottega.factory.demand.forecasting.command.DemandReviewDao;
|
||||||
import pl.com.bottega.factory.demand.forecasting.command.DemandReviewEntity;
|
import pl.com.bottega.factory.demand.forecasting.command.DemandReviewEntity;
|
||||||
import pl.com.bottega.factory.demand.forecasting.projection.CurrentDemandProjection;
|
import pl.com.bottega.factory.demand.forecasting.projection.CurrentDemandProjection;
|
||||||
import pl.com.bottega.factory.shortages.prediction.ShortagePredictionEventsMapping;
|
import pl.com.bottega.factory.shortages.prediction.monitoring.ShortagePredictionService;
|
||||||
|
|
||||||
import java.time.Clock;
|
import java.time.Clock;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
@@ -18,23 +18,24 @@ import java.util.stream.Collectors;
|
|||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
class DemandEventsMapping implements DemandEvents {
|
class DemandEventsMapping implements DemandEvents {
|
||||||
|
|
||||||
private final CurrentDemandProjection demands;
|
private final CurrentDemandProjection demandProjection;
|
||||||
private final DeliveryForecastProjection deliveries;
|
private final DeliveryForecastProjection deliveryProjection;
|
||||||
private final ShortagePredictionEventsMapping predictions;
|
private final ShortagePredictionService shortagePrediction;
|
||||||
private final DemandReviewDao reviews;
|
private final DemandReviewDao demandReviews;
|
||||||
private final Clock clock;
|
private final Clock clock;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void emit(DemandedLevelsChanged event) {
|
public void emit(DemandedLevelsChanged event) {
|
||||||
demands.persistCurrentDemands(event);
|
demandProjection.persistCurrentDemands(event);
|
||||||
deliveries.persistDeliveryForecasts(event);
|
deliveryProjection.persistDeliveryForecasts(event);
|
||||||
predictions.predictShortages(event);
|
shortagePrediction.predictShortages(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void emit(ReviewRequested event) {
|
public void emit(ReviewRequested event) {
|
||||||
reviews.save(event.getReviews().stream()
|
Instant timestamp = Instant.now(clock);
|
||||||
.map(review -> new DemandReviewEntity(Instant.now(clock), review))
|
demandReviews.save(event.getReviews().stream()
|
||||||
|
.map(r -> new DemandReviewEntity(timestamp, r))
|
||||||
.collect(Collectors.toList())
|
.collect(Collectors.toList())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,17 +2,23 @@ package pl.com.bottega.factory.product.management;
|
|||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import org.springframework.data.rest.core.annotation.HandleAfterCreate;
|
import org.springframework.data.rest.core.annotation.HandleAfterCreate;
|
||||||
import org.springframework.data.rest.core.annotation.HandleAfterSave;
|
|
||||||
import org.springframework.data.rest.core.annotation.RepositoryEventHandler;
|
import org.springframework.data.rest.core.annotation.RepositoryEventHandler;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
import pl.com.bottega.factory.demand.forecasting.DemandService;
|
||||||
|
import pl.com.bottega.factory.stock.forecast.ressource.StockForecastDao;
|
||||||
|
import pl.com.bottega.factory.stock.forecast.ressource.StockForecastEntity;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@RepositoryEventHandler
|
@RepositoryEventHandler
|
||||||
public class ProductDescriptionEventsMapping {
|
public class ProductDescriptionEventsMapping {
|
||||||
|
|
||||||
@HandleAfterSave
|
private final DemandService demandService;
|
||||||
|
private final StockForecastDao stockForecasts;
|
||||||
|
|
||||||
@HandleAfterCreate
|
@HandleAfterCreate
|
||||||
public void handle(ProductDescriptionEntity entity) {
|
public void handle(ProductDescriptionEntity entity) {
|
||||||
|
demandService.init(entity.getRefNo());
|
||||||
|
stockForecasts.save(new StockForecastEntity(entity.getRefNo()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ import pl.com.bottega.factory.shortages.prediction.calculation.ProductionForecas
|
|||||||
import pl.com.bottega.factory.warehouse.WarehouseService;
|
import pl.com.bottega.factory.warehouse.WarehouseService;
|
||||||
|
|
||||||
import java.time.Clock;
|
import java.time.Clock;
|
||||||
import java.time.Instant;
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.temporal.ChronoUnit;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.SortedSet;
|
import java.util.SortedSet;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
@@ -21,7 +21,7 @@ import static java.util.stream.Collectors.toMap;
|
|||||||
|
|
||||||
@Component
|
@Component
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
class ForecastORMProvider implements Forecasts {
|
class ForecastORMRepository implements Forecasts {
|
||||||
|
|
||||||
private final WarehouseService stocks;
|
private final WarehouseService stocks;
|
||||||
private final DeliveryForecastDao deliveries;
|
private final DeliveryForecastDao deliveries;
|
||||||
@@ -31,21 +31,21 @@ class ForecastORMProvider implements Forecasts {
|
|||||||
@Override
|
@Override
|
||||||
public Forecast get(RefNoId refNo, int daysAhead) {
|
public Forecast get(RefNoId refNo, int daysAhead) {
|
||||||
Stock stock = stocks.forRefNo(refNo);
|
Stock stock = stocks.forRefNo(refNo);
|
||||||
Instant now = Instant.now(clock);
|
LocalDateTime time = LocalDateTime.now(clock);
|
||||||
LocalDateTime time = now.atZone(clock.getZone()).toLocalDateTime();
|
LocalDateTime max = time.plusDays(daysAhead).truncatedTo(ChronoUnit.DAYS);
|
||||||
|
|
||||||
Map<LocalDateTime, Long> deliveries = this.deliveries
|
Map<LocalDateTime, Long> deliveries = this.deliveries
|
||||||
.findByRefNoAndTimeGreaterThanEqual(refNo.getRefNo(), time).stream()
|
.findByRefNoAndTimeBetween(refNo.getRefNo(), time, max).stream()
|
||||||
.collect(toMap(
|
.collect(toMap(
|
||||||
DeliveryForecastEntity::getTime,
|
DeliveryForecastEntity::getTime,
|
||||||
DeliveryForecastEntity::getLevel
|
DeliveryForecastEntity::getLevel
|
||||||
));
|
));
|
||||||
SortedSet<LocalDateTime> deliveryTimes = new TreeSet<>(deliveries.keySet());
|
SortedSet<LocalDateTime> deliveryTimes = new TreeSet<>(deliveries.keySet());
|
||||||
|
|
||||||
Deliveries demand = new Deliveries(deliveries);
|
DeliveriesForecast demand = new DeliveriesForecast(deliveries);
|
||||||
|
|
||||||
ProductionOutputs outputs = new ProductionForecast(
|
ProductionOutputs outputs = new ProductionForecast(
|
||||||
this.outputs.findByRefNoAndStartGreaterThanEqual(refNo.getRefNo(), time).stream()
|
this.outputs.findByRefNoAndEndGreaterThanAndStartLessThan(refNo.getRefNo(), time, max).stream()
|
||||||
.map(e -> new Item(
|
.map(e -> new Item(
|
||||||
e.getStart(),
|
e.getStart(),
|
||||||
e.getDuration(),
|
e.getDuration(),
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package pl.com.bottega.factory.shortages.prediction.monitoring;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import pl.com.bottega.factory.shortages.prediction.notification.NotificationOfShortage;
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
@Component
|
||||||
|
@AllArgsConstructor
|
||||||
|
class ShortageEventsMapping implements ShortageEvents {
|
||||||
|
|
||||||
|
private final NotificationOfShortage notification;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void emit(NewShortage event) {
|
||||||
|
notification.notifyAbout(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void emit(ShortageSolved event) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,7 +11,6 @@ import java.util.List;
|
|||||||
@Builder
|
@Builder
|
||||||
public class StockForecast {
|
public class StockForecast {
|
||||||
|
|
||||||
String refNo;
|
|
||||||
@Singular
|
@Singular
|
||||||
List<DailyForecast> forecasts;
|
List<DailyForecast> forecasts;
|
||||||
|
|
||||||
|
|||||||
@@ -53,8 +53,7 @@ public class StockForecastQuery {
|
|||||||
Map<LocalDate, Long> outputs) {
|
Map<LocalDate, Long> outputs) {
|
||||||
LocalDate stopAtDay = today.plusDays(15);
|
LocalDate stopAtDay = today.plusDays(15);
|
||||||
long level = stock.getLevel();
|
long level = stock.getLevel();
|
||||||
StockForecastBuilder builder = StockForecast.builder()
|
StockForecastBuilder builder = StockForecast.builder();
|
||||||
.refNo(refNo.getRefNo());
|
|
||||||
for (LocalDate date = today; date.isBefore(stopAtDay); date = date.plusDays(1)) {
|
for (LocalDate date = today; date.isBefore(stopAtDay); date = date.plusDays(1)) {
|
||||||
long withLocked = level + stock.getLocked();
|
long withLocked = level + stock.getLocked();
|
||||||
long demand = demands.getOrDefault(date, 0L);
|
long demand = demands.getOrDefault(date, 0L);
|
||||||
|
|||||||
@@ -1,36 +1,39 @@
|
|||||||
package pl.com.bottega.factory.stock.forecast.ressource;
|
package pl.com.bottega.factory.stock.forecast.ressource;
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
import org.springframework.data.rest.core.config.Projection;
|
import org.springframework.data.rest.core.config.Projection;
|
||||||
import pl.com.bottega.factory.product.management.ProductDescriptionEntity;
|
|
||||||
import pl.com.bottega.factory.stock.forecast.StockForecast;
|
import pl.com.bottega.factory.stock.forecast.StockForecast;
|
||||||
|
|
||||||
import javax.persistence.*;
|
import javax.persistence.*;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
@Entity(name = "StockForecast")
|
@Entity(name = "StockForecast")
|
||||||
@Data
|
@Getter
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@EqualsAndHashCode(of = "id")
|
@EqualsAndHashCode(of = "id")
|
||||||
@ToString(exclude = "product")
|
@ToString
|
||||||
public class StockForecastEntity implements Serializable {
|
public class StockForecastEntity implements Serializable {
|
||||||
|
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
@ManyToOne
|
@Column
|
||||||
private ProductDescriptionEntity product;
|
private String refNo;
|
||||||
|
|
||||||
|
public StockForecastEntity(String refNo) {
|
||||||
|
this.refNo = refNo;
|
||||||
|
}
|
||||||
|
|
||||||
public StockForecast getStockForecast() {
|
public StockForecast getStockForecast() {
|
||||||
return StaticAccess.calculateQuery(product.getRefNo());
|
return StaticAccess.calculateQuery(refNo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Projection(types = {StockForecastEntity.class})
|
@Projection(types = {StockForecastEntity.class})
|
||||||
interface CollectionItem {
|
interface CollectionItem {
|
||||||
ProductDescriptionEntity getProduct();
|
String getRefNo();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,15 +2,15 @@
|
|||||||
curl http://localhost:8080
|
curl http://localhost:8080
|
||||||
|
|
||||||
curl -X POST -H "Content-Type: application/json" \
|
curl -X POST -H "Content-Type: application/json" \
|
||||||
-d @app-monolith/src/test/resources/pl.com.bottega.factory.product.management/product-descriptions.json \
|
-d @app-monolith/src/test/resources/examples/product-descriptions.json \
|
||||||
http://localhost:8080/product-descriptions
|
http://localhost:8080/product-descriptions
|
||||||
|
|
||||||
curl -X POST -H "Content-Type: application/json" \
|
curl -X POST -H "Content-Type: application/json" \
|
||||||
-d @app-monolith/src/test/resources/pl.com.bottega.factory.delivery.planning/delivery-definitions.json \
|
-d @app-monolith/src/test/resources/examples/delivery-definitions.json \
|
||||||
http://localhost:8080/delivery-definitions
|
http://localhost:8080/delivery-definitions
|
||||||
|
|
||||||
curl -X POST -H "Content-Type: application/json" \
|
curl -X POST -H "Content-Type: application/json" \
|
||||||
-d @app-monolith/src/test/resources/pl.com.bottega.factory.demand.forecasting.command/demand-adjustments.json \
|
-d @app-monolith/src/test/resources/examples/demand-adjustments.json \
|
||||||
http://localhost:8080/demand-adjustments
|
http://localhost:8080/demand-adjustments
|
||||||
|
|
||||||
curl http://localhost:8080/demand-forecasts
|
curl http://localhost:8080/demand-forecasts
|
||||||
|
|||||||
@@ -4,19 +4,26 @@
|
|||||||
"adjustment": {
|
"adjustment": {
|
||||||
"refNo": "3009000",
|
"refNo": "3009000",
|
||||||
"adjustments": {
|
"adjustments": {
|
||||||
"2017-12-15": {
|
"2017-12-17": {
|
||||||
"demand": {
|
"demand": {
|
||||||
"level": 1000,
|
"level": 2000,
|
||||||
"schema": "AtDayStart"
|
"schema": "AtDayStart"
|
||||||
},
|
},
|
||||||
"strong": true
|
"strong": true
|
||||||
},
|
},
|
||||||
"2017-12-16": {
|
"2017-12-22": {
|
||||||
"demand": {
|
"demand": {
|
||||||
"level": 1000,
|
"level": 1000,
|
||||||
"schema": "AtDayStart"
|
"schema": "AtDayStart"
|
||||||
},
|
},
|
||||||
"strong": false
|
"strong": false
|
||||||
|
},
|
||||||
|
"2017-12-23": {
|
||||||
|
"demand": {
|
||||||
|
"level": 300,
|
||||||
|
"schema": "AtDayStart"
|
||||||
|
},
|
||||||
|
"strong": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
84
demand-forecasting-adapters/pom.xml
Normal file
84
demand-forecasting-adapters/pom.xml
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>pl.com.bottega</groupId>
|
||||||
|
<artifactId>demand-forecasting-adapters</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>1.5.8.RELEASE</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>pl.com.bottega</groupId>
|
||||||
|
<artifactId>demand-forecasting-model</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>pl.com.bottega</groupId>
|
||||||
|
<artifactId>adapter-commons</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>1.16.18</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.postgresql</groupId>
|
||||||
|
<artifactId>postgresql</artifactId>
|
||||||
|
<version>42.1.4</version>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.spockframework</groupId>
|
||||||
|
<artifactId>spock-core</artifactId>
|
||||||
|
<version>1.1-groovy-2.4</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.spockframework</groupId>
|
||||||
|
<artifactId>spock-spring</artifactId>
|
||||||
|
<version>1.1-groovy-2.4</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.bytebuddy</groupId>
|
||||||
|
<artifactId>byte-buddy</artifactId>
|
||||||
|
<version>1.7.9</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<compilerArgs>
|
||||||
|
<arg>-parameters</arg>
|
||||||
|
</compilerArgs>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package pl.com.bottega.factory.delivery.planning.definition;
|
package pl.com.bottega.factory.delivery.planning.definition;
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import pl.com.bottega.tools.JsonConverter;
|
import pl.com.bottega.tools.JsonConverter;
|
||||||
|
|
||||||
@@ -9,7 +9,7 @@ import javax.persistence.*;
|
|||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
@Entity(name = "DeliveryPlannerDefinition")
|
@Entity(name = "DeliveryPlannerDefinition")
|
||||||
@Data
|
@Getter
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@EqualsAndHashCode(of = "refNo")
|
@EqualsAndHashCode(of = "refNo")
|
||||||
public class DeliveryPlannerDefinitionEntity implements Serializable {
|
public class DeliveryPlannerDefinitionEntity implements Serializable {
|
||||||
@@ -16,7 +16,7 @@ import java.util.List;
|
|||||||
public interface DeliveryForecastDao extends ProjectionRepository<DeliveryForecastEntity, Long> {
|
public interface DeliveryForecastDao extends ProjectionRepository<DeliveryForecastEntity, Long> {
|
||||||
|
|
||||||
@RestResource(path = "refNos", rel = "refNos")
|
@RestResource(path = "refNos", rel = "refNos")
|
||||||
List<DeliveryForecastEntity> findByRefNoAndTimeGreaterThanEqual(String refNo, LocalDateTime from);
|
List<DeliveryForecastEntity> findByRefNoAndTimeBetween(String refNo, LocalDateTime from, LocalDateTime to);
|
||||||
|
|
||||||
@RestResource(exported = false)
|
@RestResource(exported = false)
|
||||||
void deleteByRefNoAndDate(String refNo, LocalDate date);
|
void deleteByRefNoAndDate(String refNo, LocalDate date);
|
||||||
@@ -3,9 +3,11 @@ package pl.com.bottega.factory.demand.forecasting;
|
|||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import pl.com.bottega.factory.demand.forecasting.DailyDemand.DemandUpdated;
|
import pl.com.bottega.factory.demand.forecasting.DailyDemand.DemandUpdated;
|
||||||
import pl.com.bottega.factory.demand.forecasting.DemandEntity.DemandEntityId;
|
|
||||||
import pl.com.bottega.factory.demand.forecasting.persistence.DemandDao;
|
import pl.com.bottega.factory.demand.forecasting.persistence.DemandDao;
|
||||||
|
import pl.com.bottega.factory.demand.forecasting.persistence.DemandEntity;
|
||||||
|
import pl.com.bottega.factory.demand.forecasting.persistence.DemandEntity.DemandEntityId;
|
||||||
import pl.com.bottega.factory.demand.forecasting.persistence.ProductDemandDao;
|
import pl.com.bottega.factory.demand.forecasting.persistence.ProductDemandDao;
|
||||||
|
import pl.com.bottega.factory.demand.forecasting.persistence.ProductDemandEntity;
|
||||||
import pl.com.bottega.factory.product.management.RefNoId;
|
import pl.com.bottega.factory.product.management.RefNoId;
|
||||||
import pl.com.bottega.tools.TechnicalId;
|
import pl.com.bottega.tools.TechnicalId;
|
||||||
|
|
||||||
@@ -24,7 +26,7 @@ import static java.util.stream.Collectors.toMap;
|
|||||||
class DemandORMRepository {
|
class DemandORMRepository {
|
||||||
|
|
||||||
private final Clock clock;
|
private final Clock clock;
|
||||||
private final DemandEventsMapping events;
|
private final DemandEvents events;
|
||||||
private final ReviewPolicy reviewPolicy = ReviewPolicy.BASIC;
|
private final ReviewPolicy reviewPolicy = ReviewPolicy.BASIC;
|
||||||
private final EntityManager em;
|
private final EntityManager em;
|
||||||
private final ProductDemandDao rootDao;
|
private final ProductDemandDao rootDao;
|
||||||
@@ -55,8 +57,8 @@ class DemandORMRepository {
|
|||||||
entity.createId(),
|
entity.createId(),
|
||||||
unitOfWork,
|
unitOfWork,
|
||||||
reviewPolicy,
|
reviewPolicy,
|
||||||
entity.get().getDocumented(),
|
entity.getValue().getDocumented(),
|
||||||
entity.get().getAdjustment()))
|
entity.getValue().getAdjustment()))
|
||||||
.orElseGet(() -> new DailyDemand(
|
.orElseGet(() -> new DailyDemand(
|
||||||
new DemandEntityId(refNo, date),
|
new DemandEntityId(refNo, date),
|
||||||
unitOfWork,
|
unitOfWork,
|
||||||
@@ -76,13 +78,22 @@ class DemandORMRepository {
|
|||||||
if (TechnicalId.isPersisted(updated.getId())) {
|
if (TechnicalId.isPersisted(updated.getId())) {
|
||||||
entity = demandDao.getOne(TechnicalId.get(updated.getId()));
|
entity = demandDao.getOne(TechnicalId.get(updated.getId()));
|
||||||
} else {
|
} else {
|
||||||
entity = new DemandEntity(root, updated.getId().getDate());
|
entity = new DemandEntity(
|
||||||
|
updated.getId().getRefNo(),
|
||||||
|
updated.getId().getDate()
|
||||||
|
);
|
||||||
demandDao.save(entity);
|
demandDao.save(entity);
|
||||||
}
|
}
|
||||||
entity.set(
|
entity.setValue(new DemandValue(
|
||||||
updated.getDocumented().nullIfNone(),
|
updated.getDocumented().nullIfNone(),
|
||||||
updated.getAdjustment()
|
updated.getAdjustment()
|
||||||
);
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void initDemandsFor(String refNo) {
|
||||||
|
if (rootDao.findByRefNo(refNo) == null) {
|
||||||
|
rootDao.save(new ProductDemandEntity(refNo));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -13,6 +13,10 @@ public class DemandService {
|
|||||||
|
|
||||||
private final DemandORMRepository repository;
|
private final DemandORMRepository repository;
|
||||||
|
|
||||||
|
public void init(String refNo) {
|
||||||
|
repository.initDemandsFor(refNo);
|
||||||
|
}
|
||||||
|
|
||||||
public void process(Document document) {
|
public void process(Document document) {
|
||||||
ProductDemand model = repository.get(document.getRefNo());
|
ProductDemand model = repository.get(document.getRefNo());
|
||||||
model.process(document);
|
model.process(document);
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package pl.com.bottega.factory.demand.forecasting;
|
||||||
|
|
||||||
|
import lombok.Value;
|
||||||
|
|
||||||
|
@Value
|
||||||
|
public class DemandValue {
|
||||||
|
Demand documented;
|
||||||
|
Adjustment adjustment;
|
||||||
|
}
|
||||||
@@ -4,8 +4,8 @@ import lombok.EqualsAndHashCode;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import pl.com.bottega.factory.demand.forecasting.ReviewRequested.ReviewNeeded;
|
|
||||||
import pl.com.bottega.factory.demand.forecasting.ReviewDecision;
|
import pl.com.bottega.factory.demand.forecasting.ReviewDecision;
|
||||||
|
import pl.com.bottega.factory.demand.forecasting.ReviewRequested.ReviewNeeded;
|
||||||
import pl.com.bottega.tools.JsonConverter;
|
import pl.com.bottega.tools.JsonConverter;
|
||||||
|
|
||||||
import javax.persistence.*;
|
import javax.persistence.*;
|
||||||
@@ -3,7 +3,6 @@ package pl.com.bottega.factory.demand.forecasting.persistence;
|
|||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
import org.springframework.data.rest.core.annotation.RestResource;
|
import org.springframework.data.rest.core.annotation.RestResource;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
import pl.com.bottega.factory.demand.forecasting.DemandEntity;
|
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
package pl.com.bottega.factory.demand.forecasting.persistence;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
import pl.com.bottega.factory.demand.forecasting.DailyId;
|
||||||
|
import pl.com.bottega.factory.demand.forecasting.DemandValue;
|
||||||
|
import pl.com.bottega.tools.JsonConverter;
|
||||||
|
import pl.com.bottega.tools.TechnicalId;
|
||||||
|
|
||||||
|
import javax.persistence.*;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
|
||||||
|
@Entity(name = "Demand")
|
||||||
|
@Getter
|
||||||
|
@NoArgsConstructor
|
||||||
|
@EqualsAndHashCode(of = "id")
|
||||||
|
@ToString
|
||||||
|
public class DemandEntity implements Serializable {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
|
private Long id;
|
||||||
|
@Column
|
||||||
|
String refNo;
|
||||||
|
@Column
|
||||||
|
private LocalDate date;
|
||||||
|
@Column
|
||||||
|
@Convert(converter = DemandAsJson.class)
|
||||||
|
@Setter
|
||||||
|
private DemandValue value;
|
||||||
|
|
||||||
|
public DemandEntity(String refNo, LocalDate date) {
|
||||||
|
this.refNo = refNo;
|
||||||
|
this.date = date;
|
||||||
|
this.value = new DemandValue(null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DemandEntityId createId() {
|
||||||
|
return new DemandEntityId(refNo, date, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class DemandAsJson extends JsonConverter<DemandValue> {
|
||||||
|
public DemandAsJson() {
|
||||||
|
super(DemandValue.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
public static class DemandEntityId extends DailyId implements TechnicalId {
|
||||||
|
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
public DemandEntityId(String refNo, LocalDate date) {
|
||||||
|
super(refNo, date);
|
||||||
|
}
|
||||||
|
|
||||||
|
DemandEntityId(String refNo, LocalDate date, Long id) {
|
||||||
|
super(refNo, date);
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,7 +3,6 @@ package pl.com.bottega.factory.demand.forecasting.persistence;
|
|||||||
import org.springframework.data.jpa.repository.JpaRepository;
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
import org.springframework.data.rest.core.annotation.RestResource;
|
import org.springframework.data.rest.core.annotation.RestResource;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
import pl.com.bottega.factory.demand.forecasting.ProductDemandEntity;
|
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
@RestResource(exported = false)
|
@RestResource(exported = false)
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
package pl.com.bottega.factory.demand.forecasting;
|
package pl.com.bottega.factory.demand.forecasting.persistence;
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
@@ -11,7 +10,6 @@ import javax.persistence.*;
|
|||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
@Entity(name = "ProductDemand")
|
@Entity(name = "ProductDemand")
|
||||||
@Data
|
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@EqualsAndHashCode(of = "id")
|
@EqualsAndHashCode(of = "id")
|
||||||
public class ProductDemandEntity implements Serializable {
|
public class ProductDemandEntity implements Serializable {
|
||||||
@@ -22,13 +20,13 @@ public class ProductDemandEntity implements Serializable {
|
|||||||
@Version
|
@Version
|
||||||
private Long version;
|
private Long version;
|
||||||
@Column
|
@Column
|
||||||
private String refNo;
|
String refNo;
|
||||||
|
|
||||||
public ProductDemandEntity(String refNo) {
|
public ProductDemandEntity(String refNo) {
|
||||||
this.refNo = refNo;
|
this.refNo = refNo;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProductDemandEntityId createId() {
|
public ProductDemandEntityId createId() {
|
||||||
return new ProductDemandEntityId(refNo, id);
|
return new ProductDemandEntityId(refNo, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,6 +25,7 @@ public class CurrentDemandEntity implements Serializable {
|
|||||||
@Column
|
@Column
|
||||||
private long level;
|
private long level;
|
||||||
@Column
|
@Column
|
||||||
|
@Enumerated(EnumType.STRING)
|
||||||
private Demand.Schema schema;
|
private Demand.Schema schema;
|
||||||
|
|
||||||
CurrentDemandEntity(String refNo, LocalDate date, long level, Demand.Schema schema) {
|
CurrentDemandEntity(String refNo, LocalDate date, long level, Demand.Schema schema) {
|
||||||
@@ -4,7 +4,9 @@ import org.springframework.beans.factory.annotation.Autowired
|
|||||||
import org.springframework.boot.test.context.SpringBootTest
|
import org.springframework.boot.test.context.SpringBootTest
|
||||||
import org.springframework.test.annotation.Commit
|
import org.springframework.test.annotation.Commit
|
||||||
import pl.com.bottega.factory.demand.forecasting.persistence.DemandDao
|
import pl.com.bottega.factory.demand.forecasting.persistence.DemandDao
|
||||||
|
import pl.com.bottega.factory.demand.forecasting.persistence.DemandEntity
|
||||||
import pl.com.bottega.factory.demand.forecasting.persistence.ProductDemandDao
|
import pl.com.bottega.factory.demand.forecasting.persistence.ProductDemandDao
|
||||||
|
import pl.com.bottega.factory.demand.forecasting.persistence.ProductDemandEntity
|
||||||
import spock.lang.Specification
|
import spock.lang.Specification
|
||||||
|
|
||||||
import javax.persistence.EntityManager
|
import javax.persistence.EntityManager
|
||||||
@@ -20,7 +22,7 @@ import java.time.ZoneId
|
|||||||
class DemandORMRepositoryTest extends Specification {
|
class DemandORMRepositoryTest extends Specification {
|
||||||
|
|
||||||
def clock = Clock.fixed(Instant.now(), ZoneId.systemDefault())
|
def clock = Clock.fixed(Instant.now(), ZoneId.systemDefault())
|
||||||
def events = Mock(DemandEventsMapping)
|
def events = Mock(DemandEvents)
|
||||||
@Autowired
|
@Autowired
|
||||||
EntityManager em
|
EntityManager em
|
||||||
@Autowired
|
@Autowired
|
||||||
@@ -89,7 +91,7 @@ class DemandORMRepositoryTest extends Specification {
|
|||||||
def root = rootDao.save(new ProductDemandEntity(refNo))
|
def root = rootDao.save(new ProductDemandEntity(refNo))
|
||||||
demands.each { date, level ->
|
demands.each { date, level ->
|
||||||
def demand = new DemandEntity(root, date)
|
def demand = new DemandEntity(root, date)
|
||||||
demand.set(Demand.of(level), null)
|
demand.setValue(new DemandValue(Demand.of(level), null))
|
||||||
demandDao.save(demand)
|
demandDao.save(demand)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -9,6 +9,26 @@
|
|||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>pl.com.bottega</groupId>
|
||||||
|
<artifactId>shared-kernel-model</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>1.16.18</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.spockframework</groupId>
|
||||||
|
<artifactId>spock-core</artifactId>
|
||||||
|
<version>1.1-groovy-2.4</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
@@ -46,48 +66,4 @@
|
|||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>pl.com.bottega</groupId>
|
|
||||||
<artifactId>shared-kernel-model</artifactId>
|
|
||||||
<version>1.0-SNAPSHOT</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.projectlombok</groupId>
|
|
||||||
<artifactId>lombok</artifactId>
|
|
||||||
<version>1.16.18</version>
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>junit</groupId>
|
|
||||||
<artifactId>junit</artifactId>
|
|
||||||
<version>4.12</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.assertj</groupId>
|
|
||||||
<artifactId>assertj-core</artifactId>
|
|
||||||
<version>3.8.0</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>info.cukes</groupId>
|
|
||||||
<artifactId>cucumber-java</artifactId>
|
|
||||||
<version>1.2.5</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>info.cukes</groupId>
|
|
||||||
<artifactId>cucumber-core</artifactId>
|
|
||||||
<version>1.2.5</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.spockframework</groupId>
|
|
||||||
<artifactId>spock-core</artifactId>
|
|
||||||
<version>1.1-groovy-2.4</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
</project>
|
</project>
|
||||||
@@ -15,6 +15,7 @@ class DailyDemand {
|
|||||||
|
|
||||||
private final Events events;
|
private final Events events;
|
||||||
private final ReviewPolicy policy;
|
private final ReviewPolicy policy;
|
||||||
|
|
||||||
interface Events {
|
interface Events {
|
||||||
void emit(LevelChanged event);
|
void emit(LevelChanged event);
|
||||||
|
|
||||||
|
|||||||
@@ -4,5 +4,4 @@ public interface DemandEvents {
|
|||||||
void emit(DemandedLevelsChanged event);
|
void emit(DemandedLevelsChanged event);
|
||||||
|
|
||||||
void emit(ReviewRequested event);
|
void emit(ReviewRequested event);
|
||||||
|
|
||||||
}
|
}
|
||||||
6
pom.xml
6
pom.xml
@@ -11,10 +11,14 @@
|
|||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
<module>app-monolith</module>
|
<module>app-monolith</module>
|
||||||
|
<module>adapter-commons</module>
|
||||||
<module>shared-kernel-model</module>
|
<module>shared-kernel-model</module>
|
||||||
<module>demand-forecasting-model</module>
|
<module>demand-forecasting-model</module>
|
||||||
|
<module>demand-forecasting-adapters</module>
|
||||||
<module>shortages-prediction-model</module>
|
<module>shortages-prediction-model</module>
|
||||||
<!--<module>playground-model</module>-->
|
<module>shortages-prediction-adapters</module>
|
||||||
|
<module>product-management-adapters</module>
|
||||||
|
<module>production-planning-adapters</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
78
product-management-adapters/pom.xml
Normal file
78
product-management-adapters/pom.xml
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>pl.com.bottega</groupId>
|
||||||
|
<artifactId>product-management-adapters</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>1.5.8.RELEASE</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>pl.com.bottega</groupId>
|
||||||
|
<artifactId>adapter-commons</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>1.16.18</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.postgresql</groupId>
|
||||||
|
<artifactId>postgresql</artifactId>
|
||||||
|
<version>42.1.4</version>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.spockframework</groupId>
|
||||||
|
<artifactId>spock-core</artifactId>
|
||||||
|
<version>1.1-groovy-2.4</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.spockframework</groupId>
|
||||||
|
<artifactId>spock-spring</artifactId>
|
||||||
|
<version>1.1-groovy-2.4</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.bytebuddy</groupId>
|
||||||
|
<artifactId>byte-buddy</artifactId>
|
||||||
|
<version>1.7.9</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<compilerArgs>
|
||||||
|
<arg>-parameters</arg>
|
||||||
|
</compilerArgs>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package pl.com.bottega.factory.product.management;
|
package pl.com.bottega.factory.product.management;
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import pl.com.bottega.tools.JsonConverter;
|
import pl.com.bottega.tools.JsonConverter;
|
||||||
|
|
||||||
@@ -9,7 +9,7 @@ import javax.persistence.*;
|
|||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
@Entity(name = "ProductDescription")
|
@Entity(name = "ProductDescription")
|
||||||
@Data
|
@Getter
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@EqualsAndHashCode(of = "refNo")
|
@EqualsAndHashCode(of = "refNo")
|
||||||
public class ProductDescriptionEntity implements Serializable {
|
public class ProductDescriptionEntity implements Serializable {
|
||||||
78
production-planning-adapters/pom.xml
Normal file
78
production-planning-adapters/pom.xml
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>pl.com.bottega</groupId>
|
||||||
|
<artifactId>production-planning-adapters</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>1.5.8.RELEASE</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>pl.com.bottega</groupId>
|
||||||
|
<artifactId>adapter-commons</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>1.16.18</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.postgresql</groupId>
|
||||||
|
<artifactId>postgresql</artifactId>
|
||||||
|
<version>42.1.4</version>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.spockframework</groupId>
|
||||||
|
<artifactId>spock-core</artifactId>
|
||||||
|
<version>1.1-groovy-2.4</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.spockframework</groupId>
|
||||||
|
<artifactId>spock-spring</artifactId>
|
||||||
|
<version>1.1-groovy-2.4</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.bytebuddy</groupId>
|
||||||
|
<artifactId>byte-buddy</artifactId>
|
||||||
|
<version>1.7.9</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<compilerArgs>
|
||||||
|
<arg>-parameters</arg>
|
||||||
|
</compilerArgs>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
||||||
@@ -14,5 +14,5 @@ import java.util.List;
|
|||||||
itemResourceRel = "production-output")
|
itemResourceRel = "production-output")
|
||||||
public interface ProductionOutputDao extends ProjectionRepository<ProductionOutputEntity, Long> {
|
public interface ProductionOutputDao extends ProjectionRepository<ProductionOutputEntity, Long> {
|
||||||
@RestResource(path = "refNos", rel = "refNos")
|
@RestResource(path = "refNos", rel = "refNos")
|
||||||
List<ProductionOutputEntity> findByRefNoAndStartGreaterThanEqual(String refNo, LocalDateTime from);
|
List<ProductionOutputEntity> findByRefNoAndEndGreaterThanAndStartLessThan(String refNo, LocalDateTime from, LocalDateTime to);
|
||||||
}
|
}
|
||||||
@@ -25,6 +25,8 @@ public class ProductionOutputEntity implements Serializable {
|
|||||||
@Column
|
@Column
|
||||||
private Duration duration;
|
private Duration duration;
|
||||||
@Column
|
@Column
|
||||||
|
private LocalDateTime end;
|
||||||
|
@Column
|
||||||
private int partsPerMinute;
|
private int partsPerMinute;
|
||||||
@Column
|
@Column
|
||||||
private long total;
|
private long total;
|
||||||
@@ -36,6 +38,7 @@ public class ProductionOutputEntity implements Serializable {
|
|||||||
this.refNo = refNo;
|
this.refNo = refNo;
|
||||||
this.start = start;
|
this.start = start;
|
||||||
this.duration = duration;
|
this.duration = duration;
|
||||||
|
this.end = start.plus(duration);
|
||||||
this.partsPerMinute = partsPerMinute;
|
this.partsPerMinute = partsPerMinute;
|
||||||
this.total = total;
|
this.total = total;
|
||||||
}
|
}
|
||||||
@@ -9,6 +9,21 @@
|
|||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>1.16.18</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.spockframework</groupId>
|
||||||
|
<artifactId>spock-core</artifactId>
|
||||||
|
<version>1.1-groovy-2.4</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
@@ -47,36 +62,4 @@
|
|||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.projectlombok</groupId>
|
|
||||||
<artifactId>lombok</artifactId>
|
|
||||||
<version>1.16.18</version>
|
|
||||||
<scope>compile</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.assertj</groupId>
|
|
||||||
<artifactId>assertj-core</artifactId>
|
|
||||||
<version>3.8.0</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>info.cukes</groupId>
|
|
||||||
<artifactId>cucumber-java</artifactId>
|
|
||||||
<version>1.2.5</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>info.cukes</groupId>
|
|
||||||
<artifactId>cucumber-core</artifactId>
|
|
||||||
<version>1.2.5</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.spockframework</groupId>
|
|
||||||
<artifactId>spock-core</artifactId>
|
|
||||||
<version>1.1-groovy-2.4</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
</project>
|
</project>
|
||||||
@@ -21,7 +21,7 @@ public class Demand {
|
|||||||
return new Demand(level, schema);
|
return new Demand(level, schema);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Demand nothingDemanded() {
|
static Demand nothingDemanded() {
|
||||||
return NONE;
|
return NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
84
shortages-prediction-adapters/pom.xml
Normal file
84
shortages-prediction-adapters/pom.xml
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>pl.com.bottega</groupId>
|
||||||
|
<artifactId>shortages-prediction-adapters</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>1.5.8.RELEASE</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>pl.com.bottega</groupId>
|
||||||
|
<artifactId>shortages-prediction-model</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>pl.com.bottega</groupId>
|
||||||
|
<artifactId>adapter-commons</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>1.16.18</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.postgresql</groupId>
|
||||||
|
<artifactId>postgresql</artifactId>
|
||||||
|
<version>42.1.4</version>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.spockframework</groupId>
|
||||||
|
<artifactId>spock-core</artifactId>
|
||||||
|
<version>1.1-groovy-2.4</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.spockframework</groupId>
|
||||||
|
<artifactId>spock-spring</artifactId>
|
||||||
|
<version>1.1-groovy-2.4</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.bytebuddy</groupId>
|
||||||
|
<artifactId>byte-buddy</artifactId>
|
||||||
|
<version>1.7.9</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<compilerArgs>
|
||||||
|
<arg>-parameters</arg>
|
||||||
|
</compilerArgs>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
||||||
@@ -5,23 +5,23 @@ import org.springframework.stereotype.Component;
|
|||||||
import pl.com.bottega.factory.product.management.RefNoId;
|
import pl.com.bottega.factory.product.management.RefNoId;
|
||||||
import pl.com.bottega.factory.shortages.prediction.Configuration;
|
import pl.com.bottega.factory.shortages.prediction.Configuration;
|
||||||
import pl.com.bottega.factory.shortages.prediction.calculation.Forecasts;
|
import pl.com.bottega.factory.shortages.prediction.calculation.Forecasts;
|
||||||
import pl.com.bottega.factory.shortages.prediction.notification.NotificationOfShortage;
|
import pl.com.bottega.factory.shortages.prediction.monitoring.persistence.ShortagesDao;
|
||||||
|
import pl.com.bottega.factory.shortages.prediction.monitoring.persistence.ShortagesEntity;
|
||||||
import pl.com.bottega.tools.TechnicalId;
|
import pl.com.bottega.tools.TechnicalId;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
class ShortagePredictionProcessORMRepository implements ShortagePredictionProcessRepository {
|
class ShortagePredictionProcessORMRepository {
|
||||||
|
|
||||||
private final ShortagesDao dao;
|
private final ShortagesDao dao;
|
||||||
private final ShortageDiffPolicy policy = ShortageDiffPolicy.ValuesAreNotSame;
|
private final ShortageDiffPolicy policy = ShortageDiffPolicy.ValuesAreNotSame;
|
||||||
private final Forecasts forecasts;
|
private final Forecasts forecasts;
|
||||||
private final Configuration configuration = () -> 14;
|
private final Configuration configuration = () -> 14;
|
||||||
private final NotificationOfShortage notifications;
|
private final ShortageEvents events;
|
||||||
|
|
||||||
@Override
|
ShortagePredictionProcess get(RefNoId refNo) {
|
||||||
public ShortagePredictionProcess get(RefNoId refNo) {
|
|
||||||
Optional<ShortagesEntity> entity = dao.findByRefNo(refNo.getRefNo());
|
Optional<ShortagesEntity> entity = dao.findByRefNo(refNo.getRefNo());
|
||||||
return new ShortagePredictionProcess(
|
return new ShortagePredictionProcess(
|
||||||
entity.map(ShortagesEntity::createId)
|
entity.map(ShortagesEntity::createId)
|
||||||
@@ -31,8 +31,7 @@ class ShortagePredictionProcessORMRepository implements ShortagePredictionProces
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
void save(ShortagePredictionProcess model) {
|
||||||
public void save(ShortagePredictionProcess model) {
|
|
||||||
// persisted after event
|
// persisted after event
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,12 +41,12 @@ class ShortagePredictionProcessORMRepository implements ShortagePredictionProces
|
|||||||
refNo, dao::findOne,
|
refNo, dao::findOne,
|
||||||
() -> dao.save(new ShortagesEntity(refNo.getRefNo())));
|
() -> dao.save(new ShortagesEntity(refNo.getRefNo())));
|
||||||
entity.setShortages(event.getShortages());
|
entity.setShortages(event.getShortages());
|
||||||
notifications.emit(event);
|
events.emit(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void delete(ShortageSolved event) {
|
private void delete(ShortageSolved event) {
|
||||||
dao.delete(TechnicalId.get(event.getRefNo()));
|
dao.delete(TechnicalId.get(event.getRefNo()));
|
||||||
notifications.emit(event);
|
events.emit(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class EventsHandler implements ShortageEvents {
|
private class EventsHandler implements ShortageEvents {
|
||||||
@@ -1,18 +1,17 @@
|
|||||||
package pl.com.bottega.factory.shortages.prediction;
|
package pl.com.bottega.factory.shortages.prediction.monitoring;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import pl.com.bottega.factory.demand.forecasting.DemandedLevelsChanged;
|
import pl.com.bottega.factory.demand.forecasting.DemandedLevelsChanged;
|
||||||
import pl.com.bottega.factory.shortages.prediction.monitoring.ShortagePredictionProcess;
|
|
||||||
import pl.com.bottega.factory.shortages.prediction.monitoring.ShortagePredictionProcessRepository;
|
|
||||||
|
|
||||||
@Lazy
|
import javax.transaction.Transactional;
|
||||||
@Component
|
|
||||||
|
@Service
|
||||||
|
@Transactional
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class ShortagePredictionEventsMapping {
|
public class ShortagePredictionService {
|
||||||
|
|
||||||
private final ShortagePredictionProcessRepository repository;
|
private final ShortagePredictionProcessORMRepository repository;
|
||||||
|
|
||||||
public void predictShortages(DemandedLevelsChanged event) {
|
public void predictShortages(DemandedLevelsChanged event) {
|
||||||
ShortagePredictionProcess model = repository.get(event.getRefNo());
|
ShortagePredictionProcess model = repository.get(event.getRefNo());
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package pl.com.bottega.factory.shortages.prediction.monitoring;
|
package pl.com.bottega.factory.shortages.prediction.monitoring.persistence;
|
||||||
|
|
||||||
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
|
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
|
||||||
import org.springframework.data.rest.core.annotation.RestResource;
|
import org.springframework.data.rest.core.annotation.RestResource;
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
package pl.com.bottega.factory.shortages.prediction.monitoring;
|
package pl.com.bottega.factory.shortages.prediction.monitoring.persistence;
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
import pl.com.bottega.factory.product.management.RefNoId;
|
import pl.com.bottega.factory.product.management.RefNoId;
|
||||||
import pl.com.bottega.factory.shortages.prediction.Shortages;
|
import pl.com.bottega.factory.shortages.prediction.Shortages;
|
||||||
import pl.com.bottega.tools.JsonConverter;
|
import pl.com.bottega.tools.JsonConverter;
|
||||||
@@ -13,7 +13,7 @@ import javax.persistence.*;
|
|||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
@Entity(name = "Shortage")
|
@Entity(name = "Shortage")
|
||||||
@Data
|
@Getter
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@EqualsAndHashCode(of = "refNo")
|
@EqualsAndHashCode(of = "refNo")
|
||||||
public class ShortagesEntity implements Serializable {
|
public class ShortagesEntity implements Serializable {
|
||||||
@@ -27,17 +27,18 @@ public class ShortagesEntity implements Serializable {
|
|||||||
private String refNo;
|
private String refNo;
|
||||||
@Column(length = 1024)
|
@Column(length = 1024)
|
||||||
@Convert(converter = ShortagesAsJson.class)
|
@Convert(converter = ShortagesAsJson.class)
|
||||||
|
@Setter
|
||||||
private Shortages shortages;
|
private Shortages shortages;
|
||||||
|
|
||||||
ShortagesEntity(String refNo) {
|
public ShortagesEntity(String refNo) {
|
||||||
this.refNo = refNo;
|
this.refNo = refNo;
|
||||||
}
|
}
|
||||||
|
|
||||||
RefNoId createId() {
|
public RefNoId createId() {
|
||||||
return new ShortagesEntityId(refNo, id);
|
return new ShortagesEntityId(refNo, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static RefNoId createId(RefNoId id) {
|
public static RefNoId createId(RefNoId id) {
|
||||||
return id instanceof ShortagesEntityId ? id : new ShortagesEntityId(id.getRefNo());
|
return id instanceof ShortagesEntityId ? id : new ShortagesEntityId(id.getRefNo());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6,6 +6,8 @@ import org.springframework.test.annotation.Commit
|
|||||||
import pl.com.bottega.factory.product.management.RefNoId
|
import pl.com.bottega.factory.product.management.RefNoId
|
||||||
import pl.com.bottega.factory.shortages.prediction.Shortages
|
import pl.com.bottega.factory.shortages.prediction.Shortages
|
||||||
import pl.com.bottega.factory.shortages.prediction.calculation.Forecasts
|
import pl.com.bottega.factory.shortages.prediction.calculation.Forecasts
|
||||||
|
import pl.com.bottega.factory.shortages.prediction.monitoring.persistence.ShortagesDao
|
||||||
|
import pl.com.bottega.factory.shortages.prediction.monitoring.persistence.ShortagesEntity
|
||||||
import pl.com.bottega.factory.shortages.prediction.notification.NotificationOfShortage
|
import pl.com.bottega.factory.shortages.prediction.notification.NotificationOfShortage
|
||||||
import spock.lang.Specification
|
import spock.lang.Specification
|
||||||
|
|
||||||
@@ -9,6 +9,26 @@
|
|||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>pl.com.bottega</groupId>
|
||||||
|
<artifactId>shared-kernel-model</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>1.16.18</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.spockframework</groupId>
|
||||||
|
<artifactId>spock-core</artifactId>
|
||||||
|
<version>1.1-groovy-2.4</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
@@ -47,41 +67,4 @@
|
|||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>pl.com.bottega</groupId>
|
|
||||||
<artifactId>shared-kernel-model</artifactId>
|
|
||||||
<version>1.0-SNAPSHOT</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.projectlombok</groupId>
|
|
||||||
<artifactId>lombok</artifactId>
|
|
||||||
<version>1.16.18</version>
|
|
||||||
<scope>compile</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.assertj</groupId>
|
|
||||||
<artifactId>assertj-core</artifactId>
|
|
||||||
<version>3.8.0</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>info.cukes</groupId>
|
|
||||||
<artifactId>cucumber-java</artifactId>
|
|
||||||
<version>1.2.5</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>info.cukes</groupId>
|
|
||||||
<artifactId>cucumber-core</artifactId>
|
|
||||||
<version>1.2.5</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.spockframework</groupId>
|
|
||||||
<artifactId>spock-core</artifactId>
|
|
||||||
<version>1.1-groovy-2.4</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
</project>
|
</project>
|
||||||
@@ -6,7 +6,7 @@ import java.time.LocalDateTime;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
class Deliveries {
|
class DeliveriesForecast {
|
||||||
|
|
||||||
private final Map<LocalDateTime, Long> forecast;
|
private final Map<LocalDateTime, Long> forecast;
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@ public class Forecast {
|
|||||||
private final SortedSet<LocalDateTime> deliveryTimes;
|
private final SortedSet<LocalDateTime> deliveryTimes;
|
||||||
private final Stock stock;
|
private final Stock stock;
|
||||||
private final ProductionOutputs outputs;
|
private final ProductionOutputs outputs;
|
||||||
private final Deliveries deliveries;
|
private final DeliveriesForecast deliveries;
|
||||||
|
|
||||||
public Optional<Shortages> findShortages() {
|
public Optional<Shortages> findShortages() {
|
||||||
long level = stock.getLevel();
|
long level = stock.getLevel();
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import java.util.Optional;
|
|||||||
* Created by michal on 02.02.2017.
|
* Created by michal on 02.02.2017.
|
||||||
*/
|
*/
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class ShortagePredictionProcess {
|
class ShortagePredictionProcess {
|
||||||
|
|
||||||
private final RefNoId refNo;
|
private final RefNoId refNo;
|
||||||
private Shortages known;
|
private Shortages known;
|
||||||
@@ -24,19 +24,19 @@ public class ShortagePredictionProcess {
|
|||||||
private final Configuration configuration;
|
private final Configuration configuration;
|
||||||
private final ShortageEvents events;
|
private final ShortageEvents events;
|
||||||
|
|
||||||
public void onDemandChanged() {
|
void onDemandChanged() {
|
||||||
predict(After.DemandChanged);
|
predict(After.DemandChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onPlanChanged() {
|
void onPlanChanged() {
|
||||||
predict(After.PlanChanged);
|
predict(After.PlanChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onStockChanged() {
|
void onStockChanged() {
|
||||||
predict(After.StockChanged);
|
predict(After.StockChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onLockedParts() {
|
void onLockedParts() {
|
||||||
predict(After.LockedParts);
|
predict(After.LockedParts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
package pl.com.bottega.factory.shortages.prediction.monitoring;
|
|
||||||
|
|
||||||
import pl.com.bottega.factory.product.management.RefNoId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by michal on 03.02.2017.
|
|
||||||
*/
|
|
||||||
public interface ShortagePredictionProcessRepository {
|
|
||||||
ShortagePredictionProcess get(RefNoId refNo);
|
|
||||||
|
|
||||||
void save(ShortagePredictionProcess model);
|
|
||||||
}
|
|
||||||
@@ -7,15 +7,13 @@ import lombok.Value;
|
|||||||
import pl.com.bottega.factory.shortages.prediction.Shortages;
|
import pl.com.bottega.factory.shortages.prediction.Shortages;
|
||||||
import pl.com.bottega.factory.shortages.prediction.monitoring.NewShortage;
|
import pl.com.bottega.factory.shortages.prediction.monitoring.NewShortage;
|
||||||
import pl.com.bottega.factory.shortages.prediction.monitoring.NewShortage.After;
|
import pl.com.bottega.factory.shortages.prediction.monitoring.NewShortage.After;
|
||||||
import pl.com.bottega.factory.shortages.prediction.monitoring.ShortageEvents;
|
|
||||||
import pl.com.bottega.factory.shortages.prediction.monitoring.ShortageSolved;
|
|
||||||
|
|
||||||
import java.time.Clock;
|
import java.time.Clock;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class NotificationOfShortage implements ShortageEvents {
|
public class NotificationOfShortage {
|
||||||
|
|
||||||
private final QualityTasks qualityTasks;
|
private final QualityTasks qualityTasks;
|
||||||
private final Clock clock;
|
private final Clock clock;
|
||||||
@@ -33,8 +31,7 @@ public class NotificationOfShortage implements ShortageEvents {
|
|||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void notifyAbout(NewShortage event) {
|
||||||
public void emit(NewShortage event) {
|
|
||||||
Shortages shortage = event.getShortages();
|
Shortages shortage = event.getShortages();
|
||||||
rules.wayOfNotificationAfter(event.getTrigger())
|
rules.wayOfNotificationAfter(event.getTrigger())
|
||||||
.notifyAbout(event.getShortages());
|
.notifyAbout(event.getShortages());
|
||||||
@@ -44,11 +41,6 @@ public class NotificationOfShortage implements ShortageEvents {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void emit(ShortageSolved event) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Value
|
@Value
|
||||||
@Builder
|
@Builder
|
||||||
static class NotificationRules {
|
static class NotificationRules {
|
||||||
|
|||||||
@@ -12,12 +12,12 @@ trait ShortagesCalculationAssemblerTrait {
|
|||||||
String refNo = "3009000"
|
String refNo = "3009000"
|
||||||
SortedSet<LocalDateTime> times
|
SortedSet<LocalDateTime> times
|
||||||
|
|
||||||
Forecasts forecastProvider(Stock stock, Deliveries demands, ProductionOutputs outputs) {
|
Forecasts forecastProvider(Stock stock, DeliveriesForecast demands, ProductionOutputs outputs) {
|
||||||
def forecast = forecast(stock, demands, outputs)
|
def forecast = forecast(stock, demands, outputs)
|
||||||
return { RefNoId refNo, int daysAhead -> forecast } as Forecasts
|
return { RefNoId refNo, int daysAhead -> forecast } as Forecasts
|
||||||
}
|
}
|
||||||
|
|
||||||
Forecast forecast(Stock stock, Deliveries demands, ProductionOutputs outputs) {
|
Forecast forecast(Stock stock, DeliveriesForecast demands, ProductionOutputs outputs) {
|
||||||
new Forecast(refNo, now, times, stock, outputs, demands)
|
new Forecast(refNo, now, times, stock, outputs, demands)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,14 +35,14 @@ trait ShortagesCalculationAssemblerTrait {
|
|||||||
new ProductionForecast.Item(start, duration, partsPerMinute)
|
new ProductionForecast.Item(start, duration, partsPerMinute)
|
||||||
}
|
}
|
||||||
|
|
||||||
Deliveries noDeliveries() {
|
DeliveriesForecast noDeliveries() {
|
||||||
times = Collections.emptySortedSet()
|
times = Collections.emptySortedSet()
|
||||||
new Deliveries([:])
|
new DeliveriesForecast([:])
|
||||||
}
|
}
|
||||||
|
|
||||||
Deliveries deliveries(Map<LocalDateTime, Long> demands) {
|
DeliveriesForecast deliveries(Map<LocalDateTime, Long> demands) {
|
||||||
times = new TreeSet<>(demands.keySet())
|
times = new TreeSet<>(demands.keySet())
|
||||||
new Deliveries(demands)
|
new DeliveriesForecast(demands)
|
||||||
}
|
}
|
||||||
|
|
||||||
Stock stock(long levels) {
|
Stock stock(long levels) {
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package pl.com.bottega.factory.shortages.prediction.notification
|
|||||||
import pl.com.bottega.factory.product.management.RefNoId
|
import pl.com.bottega.factory.product.management.RefNoId
|
||||||
import pl.com.bottega.factory.shortages.prediction.Shortages
|
import pl.com.bottega.factory.shortages.prediction.Shortages
|
||||||
import pl.com.bottega.factory.shortages.prediction.monitoring.NewShortage
|
import pl.com.bottega.factory.shortages.prediction.monitoring.NewShortage
|
||||||
import pl.com.bottega.factory.shortages.prediction.monitoring.ShortageSolved
|
|
||||||
import spock.lang.Specification
|
import spock.lang.Specification
|
||||||
|
|
||||||
import java.time.*
|
import java.time.*
|
||||||
@@ -25,7 +24,7 @@ class NotificationOfShortageSpec extends Specification {
|
|||||||
def notificator = notificator()
|
def notificator = notificator()
|
||||||
|
|
||||||
when:
|
when:
|
||||||
notificator.emit(newShortage(After.DemandChanged, withShortage()))
|
notificator.notifyAbout(newShortage(After.DemandChanged, withShortage()))
|
||||||
|
|
||||||
then:
|
then:
|
||||||
1 * notifications.alertPlanner(withShortage())
|
1 * notifications.alertPlanner(withShortage())
|
||||||
@@ -36,7 +35,7 @@ class NotificationOfShortageSpec extends Specification {
|
|||||||
def notificator = notificator()
|
def notificator = notificator()
|
||||||
|
|
||||||
when:
|
when:
|
||||||
notificator.emit(newShortage(After.LockedParts, withShortage()))
|
notificator.notifyAbout(newShortage(After.LockedParts, withShortage()))
|
||||||
|
|
||||||
then:
|
then:
|
||||||
1 * notifications.softNotifyPlanner(withShortage())
|
1 * notifications.softNotifyPlanner(withShortage())
|
||||||
@@ -47,7 +46,7 @@ class NotificationOfShortageSpec extends Specification {
|
|||||||
def notificator = notificator()
|
def notificator = notificator()
|
||||||
|
|
||||||
when:
|
when:
|
||||||
notificator.emit(newShortage(After.PlanChanged, withShortage()))
|
notificator.notifyAbout(newShortage(After.PlanChanged, withShortage()))
|
||||||
|
|
||||||
then:
|
then:
|
||||||
1 * notifications.markOnPlan(withShortage())
|
1 * notifications.markOnPlan(withShortage())
|
||||||
@@ -58,7 +57,7 @@ class NotificationOfShortageSpec extends Specification {
|
|||||||
def notificator = notificator()
|
def notificator = notificator()
|
||||||
|
|
||||||
when:
|
when:
|
||||||
notificator.emit(newShortage(After.StockChanged, withShortage()))
|
notificator.notifyAbout(newShortage(After.StockChanged, withShortage()))
|
||||||
|
|
||||||
then:
|
then:
|
||||||
1 * notifications.alertPlanner(withShortage())
|
1 * notifications.alertPlanner(withShortage())
|
||||||
@@ -69,7 +68,7 @@ class NotificationOfShortageSpec extends Specification {
|
|||||||
def notificator = notificator()
|
def notificator = notificator()
|
||||||
|
|
||||||
when:
|
when:
|
||||||
notificator.emit(newShortage(After.StockChanged,
|
notificator.notifyAbout(newShortage(After.StockChanged,
|
||||||
withShortage(Duration.ofDays(1), 500))
|
withShortage(Duration.ofDays(1), 500))
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -82,7 +81,7 @@ class NotificationOfShortageSpec extends Specification {
|
|||||||
def notificator = notificator()
|
def notificator = notificator()
|
||||||
|
|
||||||
when:
|
when:
|
||||||
notificator.emit(newShortage(After.StockChanged,
|
notificator.notifyAbout(newShortage(After.StockChanged,
|
||||||
withShortage(Duration.ofDays(1), 0))
|
withShortage(Duration.ofDays(1), 0))
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -95,7 +94,7 @@ class NotificationOfShortageSpec extends Specification {
|
|||||||
def notificator = notificator()
|
def notificator = notificator()
|
||||||
|
|
||||||
when:
|
when:
|
||||||
notificator.emit(newShortage(After.StockChanged,
|
notificator.notifyAbout(newShortage(After.StockChanged,
|
||||||
withShortage(Duration.ofDays(10), 500))
|
withShortage(Duration.ofDays(10), 500))
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -103,18 +102,6 @@ class NotificationOfShortageSpec extends Specification {
|
|||||||
0 * tasks.increasePriorityFor(_)
|
0 * tasks.increasePriorityFor(_)
|
||||||
}
|
}
|
||||||
|
|
||||||
def "No notification after shortage solved specified for now"() {
|
|
||||||
given:
|
|
||||||
def notificator = notificator()
|
|
||||||
|
|
||||||
when:
|
|
||||||
notificator.emit(new ShortageSolved(new RefNoId(refNo)))
|
|
||||||
|
|
||||||
then:
|
|
||||||
0 * tasks.increasePriorityFor(_)
|
|
||||||
0 * notifications._(_)
|
|
||||||
}
|
|
||||||
|
|
||||||
def notificator() {
|
def notificator() {
|
||||||
new NotificationOfShortage(
|
new NotificationOfShortage(
|
||||||
tasks, clock, policy,
|
tasks, clock, policy,
|
||||||
|
|||||||
Reference in New Issue
Block a user