11import logging
22from dataclasses import dataclass
33from datetime import date
4- from typing import List
4+ from typing import List , Optional
55import requests
66import requests .exceptions
77
8+ from notifications import notify_delay , notify_new_large_shipment
9+
810API_URL = 'https://example.org'
911
1012@dataclass
@@ -17,27 +19,56 @@ class OrderLine:
1719class Shipment :
1820 reference : str
1921 lines : List [OrderLine ]
20- eta : date
22+ eta : Optional [date ]
23+ incoterm : str
24+
25+
26+ def set_eta (shipment , eta ):
27+ logging .info (
28+ 'setting new shipment eta for %s: %s (was %s)' ,
29+ shipment .reference , eta , shipment .eta
30+ )
31+ if shipment .eta is not None and eta > shipment .eta :
32+ notify_delay (shipment_ref = shipment .reference , delay = eta - shipment .eta )
33+ if shipment .eta is None and shipment .incoterm == 'FOB' and len (shipment .lines ) > 10 :
34+ notify_new_large_shipment (shipment_ref = shipment .reference , eta = eta )
2135
36+ shipment .eta = eta
37+ sync_to_api (shipment )
2238
23- def update_shipment (shipment ):
39+
40+
41+ def sync_to_api (shipment ):
2442 external_shipment_id = get_shipment_id (shipment .reference )
25- requests .put (f'{ API_URL } /shipment/{ external_shipment_id } ' , json = {
26- 'client_reference' : shipment .reference ,
27- 'arrival_date' : shipment .eta ,
28- 'contents' : [
29- {'sku' : ol .sku , 'quantity' : ol .quantity }
30- for ol in shipment .lines
31- ]
32- })
43+ if external_shipment_id is None :
44+ requests .post (f'{ API_URL } /shipments/' , json = {
45+ 'client_reference' : shipment .reference ,
46+ 'arrival_date' : shipment .eta .isoformat ()[:10 ],
47+ 'products' : [
48+ {'sku' : ol .sku , 'quantity' : ol .quantity }
49+ for ol in shipment .lines
50+ ]
51+ })
52+
53+ else :
54+ requests .put (f'{ API_URL } /shipments/{ external_shipment_id } ' , json = {
55+ 'client_reference' : shipment .reference ,
56+ 'arrival_date' : shipment .eta .isoformat ()[:10 ],
57+ 'products' : [
58+ {'sku' : ol .sku , 'quantity' : ol .quantity }
59+ for ol in shipment .lines
60+ ]
61+ })
3362
3463
35- def get_shipment_id (our_reference ):
64+ def get_shipment_id (our_reference ) -> Optional [ str ] :
3665 try :
37- their_shipments = requests .get (f"{ API_URL } /shipment/" ).json ()['items' ]
38- return next (s for s in their_shipments if s ['client_reference' ] == our_reference )
39- except StopIteration :
40- logging .error ('No shipment found with reference %s' , our_reference )
66+ their_shipments = requests .get (f"{ API_URL } /shipments/" ).json ()['items' ]
67+ return next (
68+ (s for s in their_shipments if s ['client_reference' ] == our_reference ),
69+ None
70+ )
4171
4272 except requests .exceptions .RequestException :
4373 logging .exception ('Error retrieving shipment' )
74+ raise
0 commit comments