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:
|
To accommodate to those differences, separate architectural patterns are applied:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
**Simple Create Read Update Delete functionality** are exposed with leverage of CRUD framework.
|
**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 -
|
Only the most valuable part of that enterprise software is embedded in hexagonal architecture -
|
||||||
complex business processing modeled in form of the Domain Model.
|
complex business processing modeled in form of the Domain Model.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
**Application Services** - providing entry point to Domain Model functionality,
|
**Application Services** - providing entry point to Domain Model functionality,
|
||||||
Application Services are ports for Primary / Driving Adapters like RESTfull endpoints.
|
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.
|
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**:
|
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:
|
after cleaning and trimming initial model to most valuable and needed areas:
|
||||||

|

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

|

|
||||||
|
|
||||||
is excellent canvas to cooperative exploration of:
|
is excellent canvas to cooperative exploration of:
|
||||||
- impacted and required actors,
|
- 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 |