domain/retail/reorder.rs
1//! Reorder contracts for stock-threshold decisions and manager/vendor workflow creation.
2
3use serde::{Deserialize, Serialize};
4
5use crate::entities::LocationId;
6use crate::policy;
7
8use super::inventory::Position;
9use super::product::Sku;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
12/// Reorder policy deciding whether low stock creates a manager review, staff task, or vendor notice.
13pub enum Policy {
14 /// Manual review retail operational signal for inventory, POS, reorder, recommendation, or review handling.
15 ManualReview,
16 /// Auto create manager task retail operational signal for inventory, POS, reorder, recommendation, or review handling.
17 AutoCreateManagerTask,
18 /// Vendor managed retail operational signal for inventory, POS, reorder, recommendation, or review handling.
19 VendorManaged,
20}
21
22impl Policy {
23 /// Evaluates an inventory position against the policy and emits only threshold-backed reorder actions.
24 pub fn evaluate(&self, position: &Position) -> Decision {
25 if !position.is_at_or_below_reorder_threshold() {
26 return Decision::NoAction;
27 }
28 match self {
29 Self::ManualReview => Decision::ManagerReviewRequired {
30 reason: Reason::AtOrBelowThreshold,
31 gate: policy::ReviewGate::ManagerApproval,
32 },
33 Self::AutoCreateManagerTask => Decision::CreateStaffTask {
34 location_id: position.location_id,
35 sku: position.sku().clone(),
36 reason: Reason::AtOrBelowThreshold,
37 gate: policy::ReviewGate::ManagerApproval,
38 },
39 Self::VendorManaged => Decision::VendorManagedNotice {
40 sku: position.sku().clone(),
41 reason: Reason::AtOrBelowThreshold,
42 },
43 }
44 }
45}
46
47#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
48/// Reorder decision produced when available units are at or below threshold.
49pub enum Decision {
50 /// No action retail operational signal for inventory, POS, reorder, recommendation, or review handling.
51 NoAction,
52 /// Create staff task retail operational signal for inventory, POS, reorder, recommendation, or review handling.
53 CreateStaffTask {
54 /// Source-derived location id carried by this retail contract.
55 location_id: LocationId,
56 /// Source-derived sku carried by this retail contract.
57 sku: Sku,
58 /// Business reason staff should review before proceeding.
59 reason: Reason,
60 /// Source-derived gate carried by this retail contract.
61 gate: policy::ReviewGate,
62 },
63 /// Manager review required retail operational signal for inventory, POS, reorder, recommendation, or review handling.
64 ManagerReviewRequired {
65 /// Business reason staff should review before proceeding.
66 reason: Reason,
67 /// Source-derived gate carried by this retail contract.
68 gate: policy::ReviewGate,
69 },
70 /// Vendor managed notice retail operational signal for inventory, POS, reorder, recommendation, or review handling.
71 VendorManagedNotice {
72 /// Source-derived sku carried by this retail contract.
73 sku: Sku,
74 /// Business reason staff should review before proceeding.
75 reason: Reason,
76 },
77}
78
79#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
80/// Business reason explaining why reorder action or vendor notice is needed.
81pub enum Reason {
82 /// At or below threshold retail operational signal for inventory, POS, reorder, recommendation, or review handling.
83 AtOrBelowThreshold,
84 /// Vendor backorder retail operational signal for inventory, POS, reorder, recommendation, or review handling.
85 VendorBackorder,
86 /// Forecasted boarding diet depletion retail operational signal for inventory, POS, reorder, recommendation, or review handling.
87 ForecastedBoardingDietDepletion,
88}