1use crate::dropshipping::*;
2use crate::orders::*;
3
4#[derive(Clone, Copy, Debug, PartialEq, Eq)]
5#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
6pub enum OrderTransitionLabel {
7 CapturePayment,
8 CancelBeforePayment,
9 MarkBackordered,
10 PackPaidOrder,
11 RefundPaidOrder,
12 ShipPackedOrder,
13 ConfirmDelivery,
14 RefundDeliveredOrder,
15 ReceiveBackorderPayment,
16 CancelBackorder,
17}
18
19#[must_use]
20pub const fn order_transition_target(
21 source: OrderStatus,
22 label: OrderTransitionLabel,
23) -> Option<OrderStatus> {
24 match (source, label) {
25 (OrderStatus::New, OrderTransitionLabel::CapturePayment) => Some(OrderStatus::Paid),
26 (OrderStatus::New, OrderTransitionLabel::CancelBeforePayment)
27 | (OrderStatus::Backordered, OrderTransitionLabel::CancelBackorder) => {
28 Some(OrderStatus::Cancelled)
29 }
30 (OrderStatus::New, OrderTransitionLabel::MarkBackordered) => Some(OrderStatus::Backordered),
31 (OrderStatus::Paid, OrderTransitionLabel::PackPaidOrder) => Some(OrderStatus::Packed),
32 (OrderStatus::Paid, OrderTransitionLabel::RefundPaidOrder) => Some(OrderStatus::Refunded),
33 (OrderStatus::Packed, OrderTransitionLabel::ShipPackedOrder) => Some(OrderStatus::Shipped),
34 (OrderStatus::Shipped, OrderTransitionLabel::ConfirmDelivery) => {
35 Some(OrderStatus::Delivered)
36 }
37 (OrderStatus::Delivered, OrderTransitionLabel::RefundDeliveredOrder) => {
38 Some(OrderStatus::Refunded)
39 }
40 (OrderStatus::Backordered, OrderTransitionLabel::ReceiveBackorderPayment) => {
41 Some(OrderStatus::Paid)
42 }
43 _ => None,
44 }
45}
46
47#[must_use]
48pub fn execute_order_trace(
49 start: OrderStatus,
50 trace: &[OrderTransitionLabel],
51) -> Option<Vec<OrderStatus>> {
52 let mut states = vec![start];
53 let mut current = start;
54 for label in trace {
55 current = order_transition_target(current, *label)?;
56 states.push(current);
57 }
58 Some(states)
59}
60
61#[must_use]
62pub fn paid_fulfillment_trace() -> Vec<OrderTransitionLabel> {
63 vec![
64 OrderTransitionLabel::CapturePayment,
65 OrderTransitionLabel::PackPaidOrder,
66 OrderTransitionLabel::ShipPackedOrder,
67 OrderTransitionLabel::ConfirmDelivery,
68 ]
69}
70
71#[must_use]
72pub fn unpaid_cancellation_trace() -> Vec<OrderTransitionLabel> {
73 vec![OrderTransitionLabel::CancelBeforePayment]
74}
75
76#[must_use]
77pub const fn terminal_order_status(status: OrderStatus) -> bool {
78 matches!(
79 status,
80 OrderStatus::Delivered | OrderStatus::Cancelled | OrderStatus::Refunded
81 )
82}
83
84#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
85pub struct OrderStatusLts;
86
87impl OrderStatusLts {
88 #[must_use]
89 pub const fn transition(
90 self,
91 source: OrderStatus,
92 label: OrderTransitionLabel,
93 ) -> Option<OrderStatus> {
94 order_transition_target(source, label)
95 }
96
97 #[must_use]
98 pub fn execute(
99 self,
100 start: OrderStatus,
101 trace: &[OrderTransitionLabel],
102 ) -> Option<Vec<OrderStatus>> {
103 execute_order_trace(start, trace)
104 }
105}
106
107#[must_use]
108pub const fn order_status_lts() -> OrderStatusLts {
109 OrderStatusLts
110}
111
112#[derive(Clone, Copy, Debug, PartialEq, Eq)]
113#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
114pub enum DropshipPOTransitionLabel {
115 Submit,
116 CancelBeforeSubmit,
117 Accept,
118 Reject,
119 CancelSubmitted,
120 ShipAccepted,
121 CancelAccepted,
122 ConfirmDelivery,
123}
124
125#[must_use]
126pub const fn dropship_po_transition_target(
127 source: DropshipPOStatus,
128 label: DropshipPOTransitionLabel,
129) -> Option<DropshipPOStatus> {
130 match (source, label) {
131 (DropshipPOStatus::Created, DropshipPOTransitionLabel::Submit) => {
132 Some(DropshipPOStatus::Submitted)
133 }
134 (DropshipPOStatus::Created, DropshipPOTransitionLabel::CancelBeforeSubmit)
135 | (DropshipPOStatus::Submitted, DropshipPOTransitionLabel::CancelSubmitted)
136 | (DropshipPOStatus::Accepted, DropshipPOTransitionLabel::CancelAccepted) => {
137 Some(DropshipPOStatus::Cancelled)
138 }
139 (DropshipPOStatus::Submitted, DropshipPOTransitionLabel::Accept) => {
140 Some(DropshipPOStatus::Accepted)
141 }
142 (DropshipPOStatus::Submitted, DropshipPOTransitionLabel::Reject) => {
143 Some(DropshipPOStatus::Rejected)
144 }
145 (DropshipPOStatus::Accepted, DropshipPOTransitionLabel::ShipAccepted) => {
146 Some(DropshipPOStatus::Shipped)
147 }
148 (DropshipPOStatus::Shipped, DropshipPOTransitionLabel::ConfirmDelivery) => {
149 Some(DropshipPOStatus::Delivered)
150 }
151 _ => None,
152 }
153}
154
155#[must_use]
156pub fn execute_dropship_po_trace(
157 start: DropshipPOStatus,
158 trace: &[DropshipPOTransitionLabel],
159) -> Option<Vec<DropshipPOStatus>> {
160 let mut states = vec![start];
161 let mut current = start;
162 for label in trace {
163 current = dropship_po_transition_target(current, *label)?;
164 states.push(current);
165 }
166 Some(states)
167}
168
169#[must_use]
170pub fn dropship_po_delivery_trace() -> Vec<DropshipPOTransitionLabel> {
171 vec![
172 DropshipPOTransitionLabel::Submit,
173 DropshipPOTransitionLabel::Accept,
174 DropshipPOTransitionLabel::ShipAccepted,
175 DropshipPOTransitionLabel::ConfirmDelivery,
176 ]
177}
178
179#[must_use]
180pub const fn terminal_dropship_po_status(status: DropshipPOStatus) -> bool {
181 matches!(
182 status,
183 DropshipPOStatus::Delivered | DropshipPOStatus::Cancelled | DropshipPOStatus::Rejected
184 )
185}
186
187#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
188pub struct DropshipPoLts;
189
190impl DropshipPoLts {
191 #[must_use]
192 pub const fn transition(
193 self,
194 source: DropshipPOStatus,
195 label: DropshipPOTransitionLabel,
196 ) -> Option<DropshipPOStatus> {
197 dropship_po_transition_target(source, label)
198 }
199
200 #[must_use]
201 pub fn execute(
202 self,
203 start: DropshipPOStatus,
204 trace: &[DropshipPOTransitionLabel],
205 ) -> Option<Vec<DropshipPOStatus>> {
206 execute_dropship_po_trace(start, trace)
207 }
208}
209
210#[must_use]
211pub const fn dropship_po_lts() -> DropshipPoLts {
212 DropshipPoLts
213}
214
215#[must_use]
216pub const fn dropship_polts() -> DropshipPoLts {
217 DropshipPoLts
218}