Compare commits
2 Commits
master
...
doc/domain
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e7240e0c4b | ||
|
|
3cd55afa37 |
10
README.md
@@ -12,7 +12,7 @@ On the other hand scalability or non functional requirements are different for d
|
||||
|
||||
To accommodate to those differences, separate architectural patterns are applied:
|
||||
|
||||

|
||||

|
||||
|
||||
**Simple Create Read Update Delete functionality** are exposed with leverage of CRUD framework.
|
||||
|
||||
@@ -76,7 +76,7 @@ Examples in code:
|
||||
Only the most valuable part of that enterprise software is embedded in hexagonal architecture -
|
||||
complex business processing modeled in form of the Domain Model.
|
||||
|
||||

|
||||

|
||||
|
||||
**Application Services** - providing entry point to Domain Model functionality,
|
||||
Application Services are ports for Primary / Driving Adapters like RESTfull endpoints.
|
||||
@@ -103,13 +103,13 @@ with **Model Exploration Whirlpool** and build **Ubiquitous Language** with your
|
||||
Adding infrastructure and technology later is easy thanks to Hexagonal Architecture.
|
||||
|
||||
Simply starting from ZERO business knowledge through initial domain and opportunity exploration with **Big Picture Event Storming**:
|
||||

|
||||

|
||||
|
||||
after cleaning and trimming initial model to most valuable and needed areas:
|
||||

|
||||

|
||||
|
||||
Deep dive in **Demand Forecasting** sub-domain with **Design Level Event Storming**:
|
||||

|
||||

|
||||
|
||||
is excellent canvas to cooperative exploration of:
|
||||
- impacted and required actors,
|
||||
|
||||
|
Before Width: | Height: | Size: 177 KiB After Width: | Height: | Size: 177 KiB |
104
doc/demand-forecasting/README.md
Normal file
@@ -0,0 +1,104 @@
|
||||
# Demand forecasting
|
||||
Demand forecasting refers to predicting future the sales of the product.
|
||||
|
||||
Demand forecasting, enables organization to take various business decision on operational level, such as:
|
||||
- production planning,
|
||||
- purchasing of materials,
|
||||
- shortage prediction,
|
||||
- product pricing,
|
||||
- inventory optimization,
|
||||
- business risk management.
|
||||
|
||||
But to benefit from being demand-driven, demanded values need to be predicted, collected and kept accurate according to dynamic conditions.
|
||||
|
||||
There is plenty of demand predicting approaches:
|
||||
- Qualitative approaches:
|
||||
- Judgemental (surveys, specialist opinion, consensus methods)
|
||||
- Experimental (test marketing, customer buying database, customer panels)
|
||||
- Quantitative:
|
||||
- Relationship (econometric models, life cycle models, input-output models)
|
||||
- Time Series (moving averages, exponential smoothing, threshold methods, GARCH, TBATS, adaptive models)
|
||||
- Scenario Modeling: refining quantitative forecast with specific adjustments reflecting upcoming situation.
|
||||
|
||||
## Continuous demand forecasting
|
||||
Continuous demand forecasting refers to automated,
|
||||
continuous prediction no high granularity like demand for product-day-location.
|
||||
Continuous calculation involve predictive modeling,
|
||||
algorithmic modeling, pattern identification, scenario modeling and simulations
|
||||
by combining selected predicting approaches depending on demands mathematical properties.
|
||||

|
||||
|
||||
Review example [**demand forecasting
expertise**](demand-forecasting-expertise.R) leveraging FactoryAnalytics and R-language.
|
||||
Expertise is generating pdf document while fetching and posting data to REST endpoints of **demand-forecasting** bounded context.
|
||||
|
||||
Interactions with **demand-forecasting** bounded context can be found in source code:
|
||||
- External event **demand forecasting
expertise** is handled by port
|
||||
[DemandService.process(Document)](../../demand-forecasting-model/src/main/java/io/dddbyexamples/factory/demand/forecasting/DemandService.java)
|
||||
- External event **forecast recalculated** is handled by port
|
||||
[DemandService.process(Document)](../../demand-forecasting-model/src/main/java/io/dddbyexamples/factory/demand/forecasting/DemandService.java)
|
||||
- Command **adjust demand** is handled by port
|
||||
[DemandService.adjust(AdjustDemand)](../../demand-forecasting-model/src/main/java/io/dddbyexamples/factory/demand/forecasting/DemandService.java)
|
||||
- Read model **stock forecast** is calculated on query time by
|
||||
[StockForecastQuery.get(RefNoId)](../../app-monolith/src/main/java/io/dddbyexamples/factory/stock/forecast/StockForecastQuery.java)
|
||||
|
||||
## Framework agreement and call‐off orders
|
||||
Demands information can be collected based on framework agreement and call‐off orders.
|
||||
In case of high volume production of low value consumables or materials,
|
||||
an framework agreement with customer specifies contracted demand (on annual, quarterly or monthly granularity).
|
||||
In addition call‐off order’s contains commitment values in short period of time
|
||||
with higher granularity like product-day-location or product-week-location.
|
||||
Call-off orders and be actualized continuous even on daily basis
|
||||
replacing need for in house continuous demand forecasting.
|
||||

|
||||
|
||||
Review example **call-of order** document:
|
||||
|
||||

|
||||
|
||||
Example document contains demand forecast for two products
|
||||
- 5 weeks ahead daily demand for first
|
||||
- 2 weeks ahead daily demand for second
|
||||
and some weekly demands aggregates.
|
||||
|
||||
Interactions with **demand-forecasting** bounded context can be found in source code:
|
||||
- External event **framework agreement signed** is handled by port
|
||||
[DemandService.process(Document)](../../demand-forecasting-model/src/main/java/io/dddbyexamples/factory/demand/forecasting/DemandService.java)
|
||||
- External event **call-of order** is handled by port
|
||||
[DemandService.process(Document)](../../demand-forecasting-model/src/main/java/io/dddbyexamples/factory/demand/forecasting/DemandService.java)
|
||||
- Command **adjust demand** is handled by port
|
||||
[DemandService.adjust(AdjustDemand)](../../demand-forecasting-model/src/main/java/io/dddbyexamples/factory/demand/forecasting/DemandService.java)
|
||||
- Read model **stock forecast** is calculated on query time by
|
||||
[StockForecastQuery.get(RefNoId)](../../app-monolith/src/main/java/io/dddbyexamples/factory/stock/forecast/StockForecastQuery.java)
|
||||
- Domain event **review required**
|
||||
[ReviewRequired](../../shared-kernel-model/src/main/java/io/dddbyexamples/factory/demand/forecasting/ReviewRequired.java)
|
||||
can be published via push notification to Logistician, and is stored as read model and exposed by REST endpoint
|
||||
[RequiredReviewDao.findByRefNoAndDecisionIsNull(String)](../../demand-forecasting-adapters/src/main/java/io/dddbyexamples/factory/demand/forecasting/command/RequiredReviewDao.java)
|
||||
- Command **apply review decision** is handled by port
|
||||
[DemandService.review(ApplyReviewDecision)](../../demand-forecasting-model/src/main/java/io/dddbyexamples/factory/demand/forecasting/DemandService.java)
|
||||
|
||||
## Custom orders
|
||||
For custom goods ordered in advance, order based demand can replace demand forecasting.
|
||||
In case of lack of neither continuous demand forecasting nor call‐off orders,
|
||||
customer orders can be treated as product-day-location demand
|
||||
so any further processing requiring demand information may work normally.
|
||||

|
||||
|
||||
Interactions with **demand-forecasting** bounded context can be found in source code:
|
||||
- External event **demand forecasting
expertise** is handled by port
|
||||
[DemandService.process(Document)](../../demand-forecasting-model/src/main/java/io/dddbyexamples/factory/demand/forecasting/DemandService.java)
|
||||
- External event **order** is handled by port
|
||||
[DemandService.process(Document)](../../demand-forecasting-model/src/main/java/io/dddbyexamples/factory/demand/forecasting/DemandService.java)
|
||||
|
||||
## Manual management
|
||||
Ad-hoc adjustments of demands on top of any existing forecasts.
|
||||
|
||||
Note that **adjust demand** can change demand for multiple days atomically.
|
||||
|
||||
Interactions with **demand-forecasting** bounded context can be found in source code:
|
||||
- Command **adjust demand** is handled by port
|
||||
[DemandService.adjust(AdjustDemand)](../../demand-forecasting-model/src/main/java/io/dddbyexamples/factory/demand/forecasting/DemandService.java)
|
||||
- Read model **stock forecast** is calculated on query time by
|
||||
[StockForecastQuery.get(RefNoId)](../../app-monolith/src/main/java/io/dddbyexamples/factory/stock/forecast/StockForecastQuery.java)
|
||||
|
||||
## Propagation of demand
|
||||

|
||||
BIN
doc/demand-forecasting/call-of-order.png
Normal file
|
After Width: | Height: | Size: 360 KiB |
BIN
doc/demand-forecasting/call-of-orders.gif
Normal file
|
After Width: | Height: | Size: 2.8 MiB |
BIN
doc/demand-forecasting/continuous-forecasting.gif
Normal file
|
After Width: | Height: | Size: 2.4 MiB |
BIN
doc/demand-forecasting/custom-orders.gif
Normal file
|
After Width: | Height: | Size: 877 KiB |
69
doc/demand-forecasting/demand-forecasting-expertise.R
Normal file
@@ -0,0 +1,69 @@
|
||||
#' /* setup
|
||||
library(FactoryAnalytics)
|
||||
productRefNo <- "3009013"
|
||||
#' */
|
||||
|
||||
#' ---
|
||||
#' title: "Initial demand forecasting expertise
|
||||
#' author: "Michał Michaluk"
|
||||
#' output: pdf_document
|
||||
#' ---
|
||||
|
||||
#' # Initial demand forecasting expertise of new product release
|
||||
{{productRefNo}}
|
||||
|
||||
#' ## Method exmplanation
|
||||
#' Demand forecasting for new product will be calculated based on relationship to existing products of the same family namly *3009002* and *3009004*.
|
||||
#' *3009002*, *3009004* are the most popular colors of our product _black_ and _blue_ respectivly.
|
||||
#' Retailers feedback sugests that new _dark gray_ color is havly demand, but unavaliable from our manufacture.
|
||||
|
||||
#' Experts consensus suggests that introduction of new *3009013* _dark gray_ product will
|
||||
#' increase market share of related colors (_black_, _blue_ and new _dark gray_) in that product family about 15%.
|
||||
#' In addition it will take over about
|
||||
#' - 25% of *3009002* _black_ demands,
|
||||
#' - 40% of *3009004* _blue_ demands
|
||||
#' of existing products, becoming the most popular color in family.
|
||||
|
||||
#' ## Calculation
|
||||
#' New color will be shipped at 2018/09/01
|
||||
#' forecast 60 days from release will be more than suficient.
|
||||
|
||||
#' fetch current demand forecast for 3009002 (black)
|
||||
blackDemand <- demand.forecast.current(
|
||||
refNo = "3009002",
|
||||
from = as.Date("2018/09/01"),
|
||||
to = as.Date("2018/10/30")
|
||||
)
|
||||
#' fetch current demand forecast for 3009004 (blue)
|
||||
blueDemand <- demand.forecast.current(
|
||||
refNo = "3009004",
|
||||
from = as.Date("2018/09/01"),
|
||||
to = as.Date("2018/10/30")
|
||||
)
|
||||
|
||||
#' Experts provided calculation
|
||||
expectedDemand <- (blackDemand$level + blueDemand$level) * 0.15 + blackDemand$level * 0.25 + blueDemand$level * 0.40
|
||||
|
||||
darkgrayDemand <- data.frame(
|
||||
refNo = rep(productRefNo, 60),
|
||||
date = blackDemand$date,
|
||||
level = expectedDemand
|
||||
)
|
||||
|
||||
#' Adaptation of existing products demand only for presentation purpose
|
||||
blackDemand$level <- blackDemand$level * 0.25
|
||||
blueDemand$level <- blueDemand$level * 0.40
|
||||
|
||||
#' ## Results
|
||||
plot(darkgrayDemand[, c("date", "level")], type = "l", col = "darkgray", lty = 1)
|
||||
lines(blueDemand[, c("date", "level")], type = "l", col = "blue", lty = 2)
|
||||
lines(blackDemand[, c("date", "level")], type = "l", col = "black", lty = 2)
|
||||
legend(0, 0,
|
||||
legend = c(productRefNo, "3009002 (black)", "3009004 (blue)"),
|
||||
col = c("darkgray", "black", "blue"),
|
||||
lty = c(1,2,2), ncol=1
|
||||
)
|
||||
|
||||
#' Demand forecast saved alongside report generation:
|
||||
darkgrayDemand
|
||||
demand.forecast.new(darkgrayDemand)
|
||||
BIN
doc/demand-forecasting/demand-propagation.gif
Normal file
|
After Width: | Height: | Size: 2.8 MiB |
|
Before Width: | Height: | Size: 258 KiB After Width: | Height: | Size: 258 KiB |
|
Before Width: | Height: | Size: 119 KiB After Width: | Height: | Size: 119 KiB |
|
Before Width: | Height: | Size: 340 KiB After Width: | Height: | Size: 340 KiB |
|
Before Width: | Height: | Size: 296 KiB After Width: | Height: | Size: 296 KiB |