Context
The stock_location_orderpoint module allows defining replenishment rules at the stock location level.
A replenishment rule currently defines:
- a location scope
- a trigger mode (real-time, periodic, manual)
- a replenishment computation method
The current implementation is heavily based on stock moves (stock.move) as the entry point to determine which products should be evaluated.
Problem
The current design introduces several functional and technical limitations.
1. Incorrect behavior when no stock moves occur
For periodic rules, only products involved in stock moves since the last execution are evaluated.
This leads to incorrect situations:
- If planned replenishment pickings are deleted
- And no new stock moves occur
- Then the periodic rule does not generate any replenishment
- Even if stock is below the required level
2. Incompatibility with advanced replenishment strategies
The current approach prevents implementing strategies where demand evolves independently of stock moves.
Example:
- Seasonality-based replenishment
- Forecast-driven replenishment
In such cases:
- The replenishment need may change without any stock movement
- But the rule is never triggered → missing replenishment
3. Tight coupling and maintainability issues
The current implementation couples:
- trigger logic
- product selection
- replenishment computation
This results in:
- complex and heterogeneous code paths
- difficult extensibility
- duplication of logic across trigger modes
Proposed solution
Key idea
Refactor the module to rely on a common abstraction based on the following triplet:
- product
- forecasted quantity at location
- replenishment need
Separation of responsibilities
1. Trigger (when to compute)
The trigger becomes responsible for:
- selecting the products to evaluate
- computing their forecasted quantities at the given location
2. Replenishment strategy (how to compute)
The replenishment method becomes responsible for:
=> This fully decouples when the rule is executed from how the replenishment is computed.
Product selection per trigger mode
Real-time trigger
- Products come from stock moves
- 👍 unchanged behavior
Periodic / Manual trigger
- Products are selected based on recommended quantity.
- 👎 no longer dependent on stock moves
This ensures:
- all relevant products are evaluated
- even when no stock movement occurred
Performance considerations
To avoid performance issues when evaluating all products at a location:
- Forecasted quantities are computed using SQL queries
- Avoid relying on ORM-based computations for large datasets
Benefits
Functional
- Fixes missing replenishment scenarios
- Enables advanced strategies (e.g. seasonality, forecasting)
- Ensures consistent behavior across trigger modes
Technical
- Clear separation of concerns
- Improved modularity and extensibility
- Simplified and more homogeneous codebase
Performance
- Maintains performance through SQL-based computations
- Avoids heavy ORM recomputations
Migration / Compatibility
Future improvements enabled
This refactoring enables:
- pluggable replenishment strategies
- forecast-based or seasonality-based computations
- easier integration with demand planning tools
Notes
- Real-time behavior remains unchanged
- Focus has been put on preserving performance while improving correctness and extensibility
Context
The
stock_location_orderpointmodule allows defining replenishment rules at the stock location level.A replenishment rule currently defines:
The current implementation is heavily based on stock moves (
stock.move) as the entry point to determine which products should be evaluated.Problem
The current design introduces several functional and technical limitations.
1. Incorrect behavior when no stock moves occur
For periodic rules, only products involved in stock moves since the last execution are evaluated.
This leads to incorrect situations:
2. Incompatibility with advanced replenishment strategies
The current approach prevents implementing strategies where demand evolves independently of stock moves.
Example:
In such cases:
3. Tight coupling and maintainability issues
The current implementation couples:
This results in:
Proposed solution
Key idea
Refactor the module to rely on a common abstraction based on the following triplet:
Separation of responsibilities
1. Trigger (when to compute)
The trigger becomes responsible for:
2. Replenishment strategy (how to compute)
The replenishment method becomes responsible for:
computing the replenishment need
based on:
=> This fully decouples when the rule is executed from how the replenishment is computed.
Product selection per trigger mode
Real-time trigger
Periodic / Manual trigger
This ensures:
Performance considerations
To avoid performance issues when evaluating all products at a location:
Benefits
Functional
Technical
Performance
Migration / Compatibility
This is a refactoring with behavioral changes for periodic/manual triggers:
No data model changes expected (to be confirmed if implementation introduces new fields)
Future improvements enabled
This refactoring enables:
Notes