1
+ from dataclasses import dataclass
2
+
1
3
def allocate (order , warehouse , shipments ):
2
4
ordered_sources = [warehouse ] + sorted (shipments )
3
- allocation = {}
4
- for source in reversed ( ordered_sources ) :
5
- allocation .update (source .allocation_for (order ))
6
- decrement_source_quantities (order , allocation )
5
+ allocation = Allocation ( order , {})
6
+ for source in ordered_sources :
7
+ allocation .supplement_with (source .allocation_for (order ))
8
+ allocation . decrement_source_quantities ()
7
9
return allocation
8
10
9
- def decrement_source_quantities (order , allocation ):
10
- for sku , source in allocation .items ():
11
- source [sku ] -= order [sku ]
12
11
13
12
14
- class Order (dict ):
15
- pass
13
+
14
+ class Allocation :
15
+
16
+ def __init__ (self , order , sources ):
17
+ self .order = order
18
+ self .sources = sources
19
+
20
+ def __getitem__ (self , sku ):
21
+ return self .sources [sku ]
22
+
23
+ def __contains__ (self , sku ):
24
+ return sku in self .sources
25
+
26
+ def supplement_with (self , other ):
27
+ for sku , qty in other .sources .items ():
28
+ if sku not in self :
29
+ self .sources [sku ] = qty
30
+
31
+ def decrement_source_quantities (self ):
32
+ for sku , source in self .sources .items ():
33
+ source [sku ] -= self .order [sku ]
34
+
35
+
36
+ @dataclass
37
+ class OrderLine :
38
+ sku : str
39
+ qty : int
40
+
41
+
42
+ class Order :
43
+ def __init__ (self , quantities ):
44
+ self .quantities = quantities
45
+
46
+ def __getitem__ (self , sku ):
47
+ return self .quantities [sku ]
48
+
49
+ @property
50
+ def lines (self ):
51
+ return [
52
+ OrderLine (sku , qty )
53
+ for sku , qty in self .quantities .items ()
54
+ ]
16
55
17
56
18
57
class _Stock (dict ):
19
58
20
59
def allocation_for (self , order ):
21
- return {
22
- sku : self
23
- for sku , quantity in order .items ()
24
- if sku in self
25
- and self [sku ] > quantity
26
- }
60
+ return Allocation ( order , {
61
+ line . sku : self
62
+ for line in order .lines
63
+ if line . sku in self
64
+ and self [line . sku ] > line . qty
65
+ })
27
66
28
67
29
68
class Warehouse (_Stock ):
30
- pass
69
+
70
+ def __repr__ (self ):
71
+ return f'<Warehouse { super ().__repr__ ()} >'
31
72
32
73
33
74
34
75
class Shipment (_Stock ):
76
+ def __repr__ (self ):
77
+ return f'<Shipment { super ().__repr__ ()} >'
35
78
36
79
def __init__ (self , d , eta ):
37
80
self .eta = eta
@@ -40,4 +83,3 @@ def __init__(self, d, eta):
40
83
def __lt__ (self , other ):
41
84
return self .eta < other .eta
42
85
43
-
0 commit comments