forked from cosmicpython/code
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_allocation.py
More file actions
179 lines (120 loc) · 5.94 KB
/
test_allocation.py
File metadata and controls
179 lines (120 loc) · 5.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
import domain_model
from datetime import date, timedelta
today = date.today()
tomorrow = today + timedelta(days=1)
later = tomorrow + timedelta(days=10)
Order = lambda d: domain_model.Order(lines=[domain_model.OrderLine(sku, qty) for sku, qty in d.items()])
Warehouse = lambda d: domain_model.Warehouse(lines=[domain_model.OrderLine(sku, qty) for sku, qty in d.items()])
Shipment = lambda d, eta: domain_model.Shipment(
lines=[domain_model.OrderLine(sku, qty) for sku, qty in d.items()],
eta=eta,
)
def test_can_allocate_to_warehouse():
order = Order({'a-sku': 10})
warehouse = Warehouse({'a-sku': 1000})
order.allocate(warehouse, shipments=[])
assert order.allocation.sources['a-sku'] == warehouse
assert warehouse.quantities['a-sku'] == 990
def test_can_allocate_to_shipment():
order = Order({'a-sku': 10})
shipment = Shipment({'a-sku': 1000}, eta=tomorrow)
order.allocate(warehouse=Warehouse({}), shipments=[shipment])
assert order.allocation.sources['a-sku'] == shipment
assert shipment.quantities['a-sku'] == 990
def test_ignores_irrelevant_warehouse():
order = Order({'sku1': 10})
warehouse = Warehouse({'sku2': 1000})
shipment = Shipment({'sku1': 1000}, eta=tomorrow)
order.allocate(warehouse=warehouse, shipments=[shipment])
assert order.allocation.sources['sku1'] == shipment
def test_can_allocate_to_correct_shipment():
order = Order({'sku2': 10})
shipment1 = Shipment({'sku1': 1000}, eta=tomorrow)
shipment2 = Shipment({'sku2': 1000}, eta=tomorrow)
order.allocate(warehouse=Warehouse({}), shipments=[shipment1, shipment2])
assert order.allocation.sources['sku2'] == shipment2
def test_allocates_to_warehouse_in_preference_to_shipment():
order = Order({'sku1': 10})
warehouse = Warehouse({'sku1': 1000})
shipment = Shipment({'sku1': 1000}, eta=tomorrow)
order.allocate(warehouse, shipments=[shipment])
assert order.allocation.sources['sku1'] == warehouse
assert warehouse.quantities['sku1'] == 990
assert shipment.quantities['sku1'] == 1000
def test_can_allocate_multiple_lines_to_wh():
order = Order({'sku1': 5, 'sku2': 10})
warehouse = Warehouse({'sku1': 1000, 'sku2': 1000})
order.allocate(warehouse, shipments=[])
assert order.allocation.sources['sku1'] == warehouse
assert order.allocation.sources['sku2'] == warehouse
assert warehouse.quantities['sku1'] == 995
assert warehouse.quantities['sku2'] == 990
def test_can_allocate_multiple_lines_to_shipment():
order = Order({'sku1': 5, 'sku2': 10})
shipment = Shipment({'sku1': 1000, 'sku2': 1000}, eta=tomorrow)
order.allocate(warehouse=Warehouse({}), shipments=[shipment])
assert order.allocation.sources['sku1'] == shipment
assert order.allocation.sources['sku2'] == shipment
assert shipment.quantities['sku1'] == 995
assert shipment.quantities['sku2'] == 990
def test_can_allocate_to_both():
order = Order({'sku1': 5, 'sku2': 10})
shipment = Shipment({'sku2': 1000}, eta=tomorrow)
warehouse = Warehouse({'sku1': 1000})
order.allocate(warehouse, shipments=[shipment])
assert order.allocation.sources['sku1'] == warehouse
assert order.allocation.sources['sku2'] == shipment
assert warehouse.quantities['sku1'] == 995
assert shipment.quantities['sku2'] == 990
def test_can_allocate_to_both_preferring_warehouse():
order = Order({'sku1': 1, 'sku2': 2, 'sku3': 3, 'sku4': 4})
shipment = Shipment({'sku1': 1000, 'sku2': 1000, 'sku3': 1000}, eta=tomorrow)
warehouse = Warehouse({'sku3': 1000, 'sku4': 1000})
order.allocate(warehouse, shipments=[shipment])
assert order.allocation.sources['sku1'] == shipment
assert order.allocation.sources['sku2'] == shipment
assert order.allocation.sources['sku3'] == warehouse
assert order.allocation.sources['sku4'] == warehouse
assert shipment.quantities['sku1'] == 999
assert shipment.quantities['sku2'] == 998
assert shipment.quantities['sku3'] == 1000
assert warehouse.quantities['sku3'] == 997
assert warehouse.quantities['sku4'] == 996
def test_allocated_to_earliest_suitable_shipment_in_list():
order = Order({'sku1': 10, 'sku2': 10})
shipment1 = Shipment({'sku1': 1000, 'sku2': 1000}, eta=today)
shipment2 = Shipment({'sku1': 1000, 'sku2': 1000}, eta=tomorrow)
warehouse = Warehouse({})
order.allocate(warehouse, shipments=[shipment2, shipment1])
assert order.allocation.sources['sku1'] == shipment1
assert order.allocation.sources['sku2'] == shipment1
def test_still_chooses_earliest_if_split_across_shipments():
order = Order({'sku1': 10, 'sku2': 10, 'sku3': 10})
shipment1 = Shipment({'sku1': 1000}, eta=today)
shipment2 = Shipment({'sku2': 1000, 'sku3': 1000}, eta=tomorrow)
shipment3 = Shipment({'sku2': 1000, 'sku3': 1000}, eta=later)
warehouse = Warehouse({})
order.allocate(warehouse, shipments=[shipment3, shipment2, shipment1])
assert order.allocation.sources['sku1'] == shipment1
assert order.allocation.sources['sku2'] == shipment2
assert order.allocation.sources['sku3'] == shipment2
def test_warehouse_not_quite_enough_means_we_use_shipment():
order = Order({'sku1': 10, 'sku2': 10})
warehouse = Warehouse({'sku1': 10, 'sku2': 5})
shipment = Shipment({
'sku1': 1000,
'sku2': 1000,
}, eta=tomorrow)
order.allocate(warehouse, shipments=[shipment])
assert order.allocation.sources['sku1'] == shipment
assert order.allocation.sources['sku2'] == shipment
def test_cannot_allocate_if_insufficent_quantity_in_warehouse():
order = Order({'a-sku': 10})
warehouse = Warehouse({'a-sku': 5})
order.allocate(warehouse, shipments=[])
assert 'a-sku' not in order.allocation.skus
def test_cannot_allocate_if_insufficent_quantity_in_shipment():
order = Order({'a-sku': 10})
shipment = Shipment({'a-sku': 5}, eta=tomorrow)
order.allocate(warehouse=Warehouse({}), shipments=[shipment])
assert 'a-sku' not in order.allocation.skus