karrio-usps 2025.5rc1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- karrio/mappers/usps/__init__.py +3 -0
- karrio/mappers/usps/mapper.py +94 -0
- karrio/mappers/usps/proxy.py +155 -0
- karrio/mappers/usps/settings.py +26 -0
- karrio/plugins/usps/__init__.py +24 -0
- karrio/providers/usps/__init__.py +26 -0
- karrio/providers/usps/error.py +56 -0
- karrio/providers/usps/manifest.py +100 -0
- karrio/providers/usps/pickup/__init__.py +4 -0
- karrio/providers/usps/pickup/cancel.py +40 -0
- karrio/providers/usps/pickup/create.py +102 -0
- karrio/providers/usps/pickup/update.py +109 -0
- karrio/providers/usps/rate.py +204 -0
- karrio/providers/usps/shipment/__init__.py +9 -0
- karrio/providers/usps/shipment/cancel.py +53 -0
- karrio/providers/usps/shipment/create.py +279 -0
- karrio/providers/usps/tracking.py +112 -0
- karrio/providers/usps/units.py +303 -0
- karrio/providers/usps/utils.py +320 -0
- karrio/schemas/usps/__init__.py +0 -0
- karrio/schemas/usps/error_response.py +31 -0
- karrio/schemas/usps/label_request.py +142 -0
- karrio/schemas/usps/label_response.py +84 -0
- karrio/schemas/usps/pickup_request.py +49 -0
- karrio/schemas/usps/pickup_response.py +58 -0
- karrio/schemas/usps/pickup_update_request.py +55 -0
- karrio/schemas/usps/pickup_update_response.py +58 -0
- karrio/schemas/usps/rate_request.py +38 -0
- karrio/schemas/usps/rate_response.py +89 -0
- karrio/schemas/usps/scan_form_request.py +36 -0
- karrio/schemas/usps/scan_form_response.py +46 -0
- karrio/schemas/usps/tracking_response.py +113 -0
- karrio_usps-2025.5rc1.dist-info/METADATA +45 -0
- karrio_usps-2025.5rc1.dist-info/RECORD +37 -0
- karrio_usps-2025.5rc1.dist-info/WHEEL +5 -0
- karrio_usps-2025.5rc1.dist-info/entry_points.txt +2 -0
- karrio_usps-2025.5rc1.dist-info/top_level.txt +3 -0
@@ -0,0 +1,112 @@
|
|
1
|
+
"""Karrio USPS rating API implementation."""
|
2
|
+
|
3
|
+
# import karrio.schemas.usps.tracking_request as usps
|
4
|
+
import karrio.schemas.usps.tracking_response as tracking
|
5
|
+
|
6
|
+
import typing
|
7
|
+
import karrio.lib as lib
|
8
|
+
import karrio.core.units as units
|
9
|
+
import karrio.core.models as models
|
10
|
+
import karrio.providers.usps.error as error
|
11
|
+
import karrio.providers.usps.utils as provider_utils
|
12
|
+
import karrio.providers.usps.units as provider_units
|
13
|
+
|
14
|
+
|
15
|
+
def parse_tracking_response(
|
16
|
+
_response: lib.Deserializable[typing.List[typing.Tuple[str, dict]]],
|
17
|
+
settings: provider_utils.Settings,
|
18
|
+
) -> typing.Tuple[typing.List[models.TrackingDetails], typing.List[models.Message]]:
|
19
|
+
responses = _response.deserialize()
|
20
|
+
|
21
|
+
messages: typing.List[models.Message] = sum(
|
22
|
+
[
|
23
|
+
error.parse_error_response(response, settings, tracking_number=_)
|
24
|
+
for _, response in responses
|
25
|
+
],
|
26
|
+
start=[],
|
27
|
+
)
|
28
|
+
tracking_details = [
|
29
|
+
_extract_details(details, settings)
|
30
|
+
for _, details in responses
|
31
|
+
if "error" not in details
|
32
|
+
]
|
33
|
+
|
34
|
+
return tracking_details, messages
|
35
|
+
|
36
|
+
|
37
|
+
def _extract_details(
|
38
|
+
data: dict,
|
39
|
+
settings: provider_utils.Settings,
|
40
|
+
) -> models.TrackingDetails:
|
41
|
+
details = lib.to_object(tracking.TrackingResponseType, data)
|
42
|
+
status = next(
|
43
|
+
(
|
44
|
+
status.name
|
45
|
+
for status in list(provider_units.TrackingStatus)
|
46
|
+
if any(
|
47
|
+
_.lower() in getattr(details, "status", "").lower()
|
48
|
+
for _ in status.value
|
49
|
+
)
|
50
|
+
or any(
|
51
|
+
_.lower() in getattr(details, "statusCategory", "").lower()
|
52
|
+
for _ in status.value
|
53
|
+
)
|
54
|
+
),
|
55
|
+
provider_units.TrackingStatus.in_transit.name,
|
56
|
+
)
|
57
|
+
|
58
|
+
return models.TrackingDetails(
|
59
|
+
carrier_id=settings.carrier_id,
|
60
|
+
carrier_name=settings.carrier_name,
|
61
|
+
tracking_number=details.trackingNumber,
|
62
|
+
events=[
|
63
|
+
models.TrackingEvent(
|
64
|
+
date=lib.fdate(
|
65
|
+
event.eventTimestamp,
|
66
|
+
try_formats=["%Y-%m-%dT%H:%M:%SZ", "%Y-%m-%dT%H:%M:%S"],
|
67
|
+
),
|
68
|
+
description=event.eventType,
|
69
|
+
code=event.eventCode,
|
70
|
+
time=lib.flocaltime(
|
71
|
+
event.eventTimestamp,
|
72
|
+
try_formats=["%Y-%m-%dT%H:%M:%SZ", "%Y-%m-%dT%H:%M:%S"],
|
73
|
+
),
|
74
|
+
location=lib.text(
|
75
|
+
event.eventCity,
|
76
|
+
event.eventZIP,
|
77
|
+
event.eventState,
|
78
|
+
event.eventCountry,
|
79
|
+
separator=", ",
|
80
|
+
),
|
81
|
+
)
|
82
|
+
for event in details.trackingEvents
|
83
|
+
],
|
84
|
+
estimated_delivery=lib.fdate(
|
85
|
+
details.expectedDeliveryTimeStamp,
|
86
|
+
try_formats=["%Y-%m-%dT%H:%M:%SZ", "%Y-%m-%dT%H:%M:%S"],
|
87
|
+
),
|
88
|
+
delivered=status == "delivered",
|
89
|
+
status=status,
|
90
|
+
info=models.TrackingInfo(
|
91
|
+
# fmt: off
|
92
|
+
carrier_tracking_link=settings.tracking_url.format(details.trackingNumber),
|
93
|
+
expected_delivery=lib.fdate(details.expectedDeliveryTimeStamp, "%Y-%m-%dT%H:%M:%SZ"),
|
94
|
+
shipment_service=provider_units.ShippingService.map(details.mailClass).name_or_key,
|
95
|
+
shipment_origin_country=details.originCountry,
|
96
|
+
shipment_origin_postal_code=details.originZIP,
|
97
|
+
shipment_destination_country=details.destinationCountryCode,
|
98
|
+
shipment_destination_postal_code=details.destinationZIP,
|
99
|
+
# fmt: on
|
100
|
+
),
|
101
|
+
)
|
102
|
+
|
103
|
+
|
104
|
+
def tracking_request(
|
105
|
+
payload: models.TrackingRequest,
|
106
|
+
settings: provider_utils.Settings,
|
107
|
+
) -> lib.Serializable:
|
108
|
+
|
109
|
+
# map data to convert karrio model to usps specific type
|
110
|
+
request = payload.tracking_numbers
|
111
|
+
|
112
|
+
return lib.Serializable(request, lib.to_dict)
|
@@ -0,0 +1,303 @@
|
|
1
|
+
import typing
|
2
|
+
import karrio.lib as lib
|
3
|
+
import karrio.core.units as units
|
4
|
+
|
5
|
+
|
6
|
+
class PackagingType(lib.StrEnum):
|
7
|
+
"""Carrier specific packaging type"""
|
8
|
+
|
9
|
+
usps_3_digit = "3D"
|
10
|
+
usps_3_digit_dimensional_rectangular = "3N"
|
11
|
+
usps_3_digit_dimensional_nonrectangular = "3R"
|
12
|
+
usps_5_digit = "5D"
|
13
|
+
usps_basic = "BA"
|
14
|
+
usps_mixed_ndc = "BB"
|
15
|
+
usps_ndc = "BM"
|
16
|
+
usps_cubic_pricing_tier_1 = "C1"
|
17
|
+
usps_cubic_pricing_tier_2 = "C2"
|
18
|
+
usps_cubic_pricing_tier_3 = "C3"
|
19
|
+
usps_cubic_pricing_tier_4 = "C4"
|
20
|
+
usps_cubic_pricing_tier_5 = "C5"
|
21
|
+
usps_cubic_parcel = "CP"
|
22
|
+
usps_connect_local = "CM"
|
23
|
+
usps_non_presorted = "NP"
|
24
|
+
usps_full_tray_box = "O1"
|
25
|
+
usps_half_tray_box = "O2"
|
26
|
+
usps_emm_tray_box = "O3"
|
27
|
+
usps_flat_tub_tray_box = "O4"
|
28
|
+
usps_surface_transported_pallet = "O5"
|
29
|
+
usps_half_pallet_box = "O7"
|
30
|
+
usps_oversized = "OS"
|
31
|
+
usps_cubic_soft_pack_tier_1 = "P5"
|
32
|
+
usps_cubic_soft_pack_tier_2 = "P6"
|
33
|
+
usps_cubic_soft_pack_tier_3 = "P7"
|
34
|
+
usps_cubic_soft_pack_tier_4 = "P8"
|
35
|
+
usps_cubic_soft_pack_tier_5 = "P9"
|
36
|
+
usps_cubic_soft_pack_tier_6 = "Q6"
|
37
|
+
usps_cubic_soft_pack_tier_7 = "Q7"
|
38
|
+
usps_cubic_soft_pack_tier_8 = "Q8"
|
39
|
+
usps_cubic_soft_pack_tier_9 = "Q9"
|
40
|
+
usps_cubic_soft_pack_tier_10 = "Q0"
|
41
|
+
usps_priority_mail_express_single_piece = "PA"
|
42
|
+
usps_large_flat_rate_box = "PL"
|
43
|
+
usps_large_flat_rate_box_apofpo = "PM"
|
44
|
+
usps_presorted = "PR"
|
45
|
+
usps_small_flat_rate_bag = "SB"
|
46
|
+
usps_scf_dimensional_nonrectangular = "SN"
|
47
|
+
usps_scf_dimensional_rectangular = "SR"
|
48
|
+
usps_single_piece = "SP"
|
49
|
+
|
50
|
+
""" Unified Packaging type mapping """
|
51
|
+
envelope = usps_single_piece
|
52
|
+
pak = usps_single_piece
|
53
|
+
tube = usps_scf_dimensional_nonrectangular
|
54
|
+
pallet = usps_large_flat_rate_box
|
55
|
+
small_box = usps_single_piece
|
56
|
+
medium_box = usps_scf_dimensional_rectangular
|
57
|
+
your_packaging = usps_single_piece
|
58
|
+
|
59
|
+
|
60
|
+
class ContentType(lib.StrEnum):
|
61
|
+
HAZMAT = "HAZMAT"
|
62
|
+
CREMATED_REMAINS = "CREMATED_REMAINS"
|
63
|
+
BEES = "BEES"
|
64
|
+
DAY_OLD_POULTRY = "DAY_OLD_POULTRY"
|
65
|
+
ADULT_BIRDS = "ADULT_BIRDS"
|
66
|
+
OTHER_LIVES = "OTHER_LIVES"
|
67
|
+
PERISHABLE = "PERISHABLE"
|
68
|
+
PHARMACEUTICALS = "PHARMACEUTICALS"
|
69
|
+
MEDICAL_SUPPLIES = "MEDICAL_SUPPLIES"
|
70
|
+
FRUITS = "FRUITS"
|
71
|
+
VEGETABLES = "VEGETABLES"
|
72
|
+
LIVE_PLANTS = "LIVE_PLANTS"
|
73
|
+
|
74
|
+
|
75
|
+
class LabelType(lib.StrEnum):
|
76
|
+
"""Carrier specific label type"""
|
77
|
+
|
78
|
+
PDF = "PDF"
|
79
|
+
TIFF = "TIFF"
|
80
|
+
JPG = "JPG"
|
81
|
+
SVG = "SVG"
|
82
|
+
ZPL203DPI = "ZPL203DPI"
|
83
|
+
ZPL300DPI = "ZPL300DPI"
|
84
|
+
LABEL_BROKER = "LABEL_BROKER"
|
85
|
+
NONE = "NONE"
|
86
|
+
|
87
|
+
""" Unified Label type mapping """
|
88
|
+
ZPL = ZPL203DPI
|
89
|
+
PNG = JPG
|
90
|
+
|
91
|
+
|
92
|
+
class ShippingService(lib.StrEnum):
|
93
|
+
"""Carrier specific services"""
|
94
|
+
|
95
|
+
usps_parcel_select_lightweight = "PARCEL_SELECT_LIGHTWEIGHT"
|
96
|
+
usps_parcel_select = "PARCEL_SELECT"
|
97
|
+
usps_priority_mail_express = "PRIORITY_MAIL_EXPRESS"
|
98
|
+
usps_priority_mail = "PRIORITY_MAIL"
|
99
|
+
usps_library_mail = "LIBRARY_MAIL"
|
100
|
+
usps_media_mail = "MEDIA_MAIL"
|
101
|
+
usps_bound_printed_matter = "BOUND_PRINTED_MATTER"
|
102
|
+
usps_connect_local = "USPS_CONNECT_LOCAL"
|
103
|
+
usps_connect_mail = "USPS_CONNECT_MAIL"
|
104
|
+
usps_connect_next_day = "USPS_CONNECT_NEXT_DAY"
|
105
|
+
usps_connect_regional = "USPS_CONNECT_REGIONAL"
|
106
|
+
usps_connect_same_day = "USPS_CONNECT_SAME_DAY"
|
107
|
+
usps_ground_advantage = "USPS_GROUND_ADVANTAGE"
|
108
|
+
usps_domestic_matter_for_the_blind = "DOMESTIC_MATTER_FOR_THE_BLIND"
|
109
|
+
usps_all = "ALL"
|
110
|
+
|
111
|
+
@classmethod
|
112
|
+
def to_product_code(cls, product_name: str) -> str:
|
113
|
+
"""Convert product description to product code
|
114
|
+
|
115
|
+
to_product_code("Priority Mail Padded Flat Rate Envelope") -> "usps_priority_mail_padded_flat_rate_envelope"
|
116
|
+
|
117
|
+
Args:
|
118
|
+
product_name (str): Product name
|
119
|
+
|
120
|
+
Returns:
|
121
|
+
str: Service code
|
122
|
+
"""
|
123
|
+
return lib.to_slug("usps", product_name).replace("usps_usps_", "usps_")
|
124
|
+
|
125
|
+
@classmethod
|
126
|
+
def to_product_name(cls, product_code: str) -> str:
|
127
|
+
"""Convert product code to product name
|
128
|
+
|
129
|
+
to_product_name("usps_priority_mail_padded_flat_rate_envelope") -> "USPS PRIORITY MAIL PADDED FLAT RATE ENVELOPE"
|
130
|
+
|
131
|
+
Args:
|
132
|
+
product_code (str): Service code
|
133
|
+
|
134
|
+
Returns:
|
135
|
+
str: Product name
|
136
|
+
"""
|
137
|
+
if not product_code:
|
138
|
+
return ""
|
139
|
+
|
140
|
+
# Remove the "usps_" prefix if present
|
141
|
+
if product_code.startswith("usps_"):
|
142
|
+
product_code = product_code[5:] # Remove "usps_" (5 characters)
|
143
|
+
|
144
|
+
# Replace underscores with spaces and convert to uppercase
|
145
|
+
product_name = product_code.replace("_", " ").upper()
|
146
|
+
|
147
|
+
# Add "USPS" prefix
|
148
|
+
return f"USPS {product_name}"
|
149
|
+
|
150
|
+
@classmethod
|
151
|
+
def to_mail_class(cls, product_code: str) -> typing.Optional['ShippingService']:
|
152
|
+
"""Convert product code to mail class
|
153
|
+
|
154
|
+
to_mail_class("usps_priority_mail_padded_flat_rate_envelope") -> "PRIORITY_MAIL"
|
155
|
+
|
156
|
+
Args:
|
157
|
+
product_code (str): Service code
|
158
|
+
|
159
|
+
Returns:
|
160
|
+
str: ShippingService
|
161
|
+
"""
|
162
|
+
return ShippingService.map(
|
163
|
+
next((
|
164
|
+
service for service in list(cls) if service.name in product_code
|
165
|
+
), None)
|
166
|
+
)
|
167
|
+
|
168
|
+
|
169
|
+
INCOMPATIBLE_SERVICES = [
|
170
|
+
ShippingService.usps_ground_advantage.name, # type: ignore
|
171
|
+
]
|
172
|
+
|
173
|
+
|
174
|
+
class ShippingOption(lib.Enum):
|
175
|
+
"""Carrier specific options"""
|
176
|
+
|
177
|
+
# fmt: off
|
178
|
+
usps_label_delivery_service = lib.OptionEnum("415", bool)
|
179
|
+
usps_tracking_plus_6_months = lib.OptionEnum("480", bool)
|
180
|
+
usps_tracking_plus_1_year = lib.OptionEnum("481", bool)
|
181
|
+
usps_tracking_plus_3_years = lib.OptionEnum("482", bool)
|
182
|
+
usps_tracking_plus_5_years = lib.OptionEnum("483", bool)
|
183
|
+
usps_tracking_plus_7_years = lib.OptionEnum("484", bool)
|
184
|
+
usps_tracking_plus_10_years = lib.OptionEnum("485", bool)
|
185
|
+
usps_tracking_plus_signature_3_years = lib.OptionEnum("486", bool)
|
186
|
+
usps_tracking_plus_signature_5_years = lib.OptionEnum("487", bool)
|
187
|
+
usps_tracking_plus_signature_7_years = lib.OptionEnum("488", bool)
|
188
|
+
usps_tracking_plus_signature_10_years = lib.OptionEnum("489", bool)
|
189
|
+
usps_hazardous_materials_air_eligible_ethanol = lib.OptionEnum("810", bool)
|
190
|
+
usps_hazardous_materials_class_1_toy_propellant_safety_fuse_package = lib.OptionEnum("811", bool)
|
191
|
+
usps_hazardous_materials_class_3_flammable_and_combustible_liquids = lib.OptionEnum("812", bool)
|
192
|
+
usps_hazardous_materials_class_7_radioactive_materials = lib.OptionEnum("813", bool)
|
193
|
+
usps_hazardous_materials_class_8_air_eligible_corrosive_materials = lib.OptionEnum("814", bool)
|
194
|
+
usps_hazardous_materials_class_8_nonspillable_wet_batteries = lib.OptionEnum("815", bool)
|
195
|
+
usps_hazardous_materials_class_9_lithium_battery_marked_ground_only = lib.OptionEnum("816", bool)
|
196
|
+
usps_hazardous_materials_class_9_lithium_battery_returns = lib.OptionEnum("817", bool)
|
197
|
+
usps_hazardous_materials_class_9_marked_lithium_batteries = lib.OptionEnum("818", bool)
|
198
|
+
usps_hazardous_materials_class_9_dry_ice = lib.OptionEnum("819", bool)
|
199
|
+
usps_hazardous_materials_class_9_unmarked_lithium_batteries = lib.OptionEnum("820", bool)
|
200
|
+
usps_hazardous_materials_class_9_magnetized_materials = lib.OptionEnum("821", bool)
|
201
|
+
usps_hazardous_materials_division_4_1_mailable_flammable_solids_and_safety_matches = lib.OptionEnum("822", bool)
|
202
|
+
usps_hazardous_materials_division_5_1_oxidizers = lib.OptionEnum("823", bool)
|
203
|
+
usps_hazardous_materials_division_5_2_organic_peroxides = lib.OptionEnum("824", bool)
|
204
|
+
usps_hazardous_materials_division_6_1_toxic_materials = lib.OptionEnum("825", bool)
|
205
|
+
usps_hazardous_materials_division_6_2_biological_materials = lib.OptionEnum("826", bool)
|
206
|
+
usps_hazardous_materials_excepted_quantity_provision = lib.OptionEnum("827", bool)
|
207
|
+
usps_hazardous_materials_ground_only_hazardous_materials = lib.OptionEnum("828", bool)
|
208
|
+
usps_hazardous_materials_air_eligible_id8000_consumer_commodity = lib.OptionEnum("829", bool)
|
209
|
+
usps_hazardous_materials_lighters = lib.OptionEnum("830", bool)
|
210
|
+
usps_hazardous_materials_limited_quantity_ground = lib.OptionEnum("831", bool)
|
211
|
+
usps_hazardous_materials_small_quantity_provision_markings_required = lib.OptionEnum("832", bool)
|
212
|
+
usps_hazardous_materials = lib.OptionEnum("857", bool)
|
213
|
+
usps_certified_mail = lib.OptionEnum("910", bool)
|
214
|
+
usps_certified_mail_restricted_delivery = lib.OptionEnum("911", bool)
|
215
|
+
usps_certified_mail_adult_signature_required = lib.OptionEnum("912", bool)
|
216
|
+
usps_certified_mail_adult_signature_restricted_delivery = lib.OptionEnum("913", bool)
|
217
|
+
usps_collect_on_delivery = lib.OptionEnum("915", float)
|
218
|
+
usps_collect_on_delivery_restricted_delivery = lib.OptionEnum("917", bool)
|
219
|
+
usps_tracking_electronic = lib.OptionEnum("920", bool)
|
220
|
+
usps_signature_confirmation = lib.OptionEnum("921", bool)
|
221
|
+
usps_adult_signature_required = lib.OptionEnum("922", bool)
|
222
|
+
usps_adult_signature_restricted_delivery = lib.OptionEnum("923", bool)
|
223
|
+
usps_signature_confirmation_restricted_delivery = lib.OptionEnum("924", bool)
|
224
|
+
usps_priority_mail_express_merchandise_insurance = lib.OptionEnum("925", bool)
|
225
|
+
usps_insurance_below_500 = lib.OptionEnum("930", float)
|
226
|
+
usps_insurance_above_500 = lib.OptionEnum("931", float)
|
227
|
+
usps_insurance_restricted_delivery = lib.OptionEnum("934", bool)
|
228
|
+
usps_registered_mail = lib.OptionEnum("940", bool)
|
229
|
+
usps_registered_mail_restricted_delivery = lib.OptionEnum("941", bool)
|
230
|
+
usps_return_receipt = lib.OptionEnum("955", bool)
|
231
|
+
usps_return_receipt_electronic = lib.OptionEnum("957", bool)
|
232
|
+
usps_signature_requested_priority_mail_express_only = lib.OptionEnum("981", bool)
|
233
|
+
usps_parcel_locker_delivery = lib.OptionEnum("984", bool)
|
234
|
+
usps_po_to_addressee_priority_mail_express_only = lib.OptionEnum("986", bool)
|
235
|
+
usps_sunday_delivery = lib.OptionEnum("981", bool)
|
236
|
+
|
237
|
+
""" Custom Options """
|
238
|
+
usps_mail_class = lib.OptionEnum("mailClass", ShippingService)
|
239
|
+
usps_facility_id = lib.OptionEnum("facilityId")
|
240
|
+
usps_machinable_piece = lib.OptionEnum("machinable", bool)
|
241
|
+
usps_hold_for_pickup = lib.OptionEnum("holdForPickup", bool)
|
242
|
+
usps_processing_category = lib.OptionEnum("processingCategory")
|
243
|
+
usps_carrier_release = lib.OptionEnum("carrierRelease", bool)
|
244
|
+
usps_physical_signature_required = lib.OptionEnum("physicalSignatureRequired", bool)
|
245
|
+
usps_price_type = lib.OptionEnum("priceType", lib.units.create_enum("priceType", ["RETAIL", "COMMERCIAL", "CONTRACT"]))
|
246
|
+
usps_destination_entry_facility_type = lib.OptionEnum("destinationEntryFacilityType", lib.units.create_enum("destinationEntryFacilityType", ["NONE", "DESTINATION_NETWORK_DISTRIBUTION_CENTER", "DESTINATION_SECTIONAL_CENTER_FACILITY", "DESTINATION_DELIVERY_UNIT", "DESTINATION_SERVICE_HUB"]))
|
247
|
+
usps_extra_services = lib.OptionEnum("extraServices", list)
|
248
|
+
usps_shipping_filter = lib.OptionEnum("shippingFilter", lib.units.create_enum("shippingFilter", ["PRICE", "SERVICE_STANDARDS"]))
|
249
|
+
|
250
|
+
""" Unified Option type mapping """
|
251
|
+
cash_on_delivery = usps_collect_on_delivery
|
252
|
+
signature_confirmation = usps_signature_confirmation
|
253
|
+
sunday_delivery = usps_sunday_delivery
|
254
|
+
hold_at_location = usps_hold_for_pickup
|
255
|
+
# fmt: on
|
256
|
+
|
257
|
+
|
258
|
+
CUSTOM_OPTIONS = [
|
259
|
+
ShippingOption.usps_mail_class.name,
|
260
|
+
ShippingOption.usps_extra_services.name,
|
261
|
+
ShippingOption.usps_facility_id.name,
|
262
|
+
ShippingOption.usps_machinable_piece.name,
|
263
|
+
ShippingOption.usps_hold_for_pickup.name,
|
264
|
+
ShippingOption.usps_processing_category.name,
|
265
|
+
ShippingOption.usps_carrier_release.name,
|
266
|
+
ShippingOption.usps_physical_signature_required.name,
|
267
|
+
ShippingOption.usps_price_type.name,
|
268
|
+
ShippingOption.usps_destination_entry_facility_type.name,
|
269
|
+
ShippingOption.usps_shipping_filter.name,
|
270
|
+
]
|
271
|
+
|
272
|
+
|
273
|
+
def shipping_options_initializer(
|
274
|
+
options: dict,
|
275
|
+
package_options: units.ShippingOptions = None,
|
276
|
+
) -> units.ShippingOptions:
|
277
|
+
"""
|
278
|
+
Apply default values to the given options.
|
279
|
+
"""
|
280
|
+
|
281
|
+
if package_options is not None:
|
282
|
+
options.update(package_options.content)
|
283
|
+
|
284
|
+
if "insurance" in options:
|
285
|
+
if lib.to_money(options["insurance"]) > 500:
|
286
|
+
options[ShippingOption.usps_insurance_above_500.name] = options["insurance"]
|
287
|
+
else:
|
288
|
+
options[ShippingOption.usps_insurance_below_500.name] = options["insurance"]
|
289
|
+
|
290
|
+
def items_filter(key: str) -> bool:
|
291
|
+
return key in ShippingOption # type: ignore
|
292
|
+
|
293
|
+
return units.ShippingOptions(options, ShippingOption, items_filter=items_filter)
|
294
|
+
|
295
|
+
|
296
|
+
class TrackingStatus(lib.Enum):
|
297
|
+
on_hold = ["on hold"]
|
298
|
+
delivered = ["delivered"]
|
299
|
+
in_transit = ["in transit"]
|
300
|
+
delivery_failed = ["delivery failed"]
|
301
|
+
delivery_delayed = ["delivery delayed"]
|
302
|
+
out_for_delivery = ["out for delivery"]
|
303
|
+
ready_for_pickup = ["ready for pickup"]
|