karrio-freightcom 2025.5.6__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/freightcom/__init__.py +3 -0
- karrio/mappers/freightcom/mapper.py +55 -0
- karrio/mappers/freightcom/proxy.py +38 -0
- karrio/mappers/freightcom/settings.py +19 -0
- karrio/plugins/freightcom/__init__.py +19 -0
- karrio/providers/freightcom/__init__.py +6 -0
- karrio/providers/freightcom/error.py +40 -0
- karrio/providers/freightcom/quote.py +179 -0
- karrio/providers/freightcom/shipping.py +294 -0
- karrio/providers/freightcom/units.py +153 -0
- karrio/providers/freightcom/utils.py +39 -0
- karrio/providers/freightcom/void_shipment.py +50 -0
- karrio/schemas/freightcom/__init__.py +0 -0
- karrio/schemas/freightcom/error.py +1859 -0
- karrio/schemas/freightcom/quote_reply.py +2555 -0
- karrio/schemas/freightcom/quote_request.py +4522 -0
- karrio/schemas/freightcom/shipment_cancel_reply.py +2063 -0
- karrio/schemas/freightcom/shipment_cancel_request.py +1915 -0
- karrio/schemas/freightcom/shipping_reply.py +4236 -0
- karrio/schemas/freightcom/shipping_request.py +5953 -0
- karrio_freightcom-2025.5.6.dist-info/METADATA +44 -0
- karrio_freightcom-2025.5.6.dist-info/RECORD +25 -0
- karrio_freightcom-2025.5.6.dist-info/WHEEL +5 -0
- karrio_freightcom-2025.5.6.dist-info/entry_points.txt +2 -0
- karrio_freightcom-2025.5.6.dist-info/top_level.txt +3 -0
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import re
|
|
2
|
+
import karrio.lib as lib
|
|
3
|
+
import karrio.core.units as units
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class FreightPackagingType(lib.StrEnum):
|
|
7
|
+
freightcom_pallet = "Pallet"
|
|
8
|
+
freightcom_drum = "Drum"
|
|
9
|
+
freightcom_boxes = "Boxes"
|
|
10
|
+
freightcom_rolls = "Rolls"
|
|
11
|
+
freightcom_pipes_tubes = "Pipes/Tubes"
|
|
12
|
+
freightcom_bales = "Bales"
|
|
13
|
+
freightcom_bags = "Bags"
|
|
14
|
+
freightcom_cylinder = "Cylinder"
|
|
15
|
+
freightcom_pails = "Pails"
|
|
16
|
+
freightcom_reels = "Reels"
|
|
17
|
+
|
|
18
|
+
freightcom_envelope = "Envelope"
|
|
19
|
+
freightcom_courier = "Courier"
|
|
20
|
+
freightcom_pak = "Pak"
|
|
21
|
+
freightcom_package = "Package"
|
|
22
|
+
|
|
23
|
+
""" Unified Packaging type mapping """
|
|
24
|
+
envelope = freightcom_envelope
|
|
25
|
+
pak = freightcom_pak
|
|
26
|
+
tube = freightcom_pipes_tubes
|
|
27
|
+
pallet = freightcom_pallet
|
|
28
|
+
small_box = freightcom_boxes
|
|
29
|
+
medium_box = freightcom_boxes
|
|
30
|
+
large_box = freightcom_boxes
|
|
31
|
+
your_packaging = freightcom_package
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class PaymentType(lib.StrEnum): # TODO:: retrieve the complete list of payment types
|
|
35
|
+
check = "Check"
|
|
36
|
+
|
|
37
|
+
sender = "Sender"
|
|
38
|
+
recipient = "Recipient"
|
|
39
|
+
third_party = "Third Party"
|
|
40
|
+
credit_card = "Card"
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class ShippingService(lib.StrEnum):
|
|
44
|
+
freightcom_all = "0"
|
|
45
|
+
freightcom_usf_holland = "1911"
|
|
46
|
+
freightcom_central_transport = "2029"
|
|
47
|
+
freightcom_estes = "2107"
|
|
48
|
+
freightcom_canpar_ground = "3400"
|
|
49
|
+
freightcom_canpar_select = "3404"
|
|
50
|
+
freightcom_canpar_overnight = "3407"
|
|
51
|
+
freightcom_dicom_ground = "3700"
|
|
52
|
+
freightcom_purolator_ground = "4000"
|
|
53
|
+
freightcom_purolator_express = "4003"
|
|
54
|
+
freightcom_purolator_express_9_am = "4004"
|
|
55
|
+
freightcom_purolator_express_10_30_am = "4005"
|
|
56
|
+
freightcom_purolator_ground_us = "4016"
|
|
57
|
+
freightcom_purolator_express_us = "4015"
|
|
58
|
+
freightcom_purolator_express_us_9_am = "4013"
|
|
59
|
+
freightcom_purolator_express_us_10_30_am = "4014"
|
|
60
|
+
freightcom_fedex_express_saver = "4100"
|
|
61
|
+
freightcom_fedex_ground = "4101"
|
|
62
|
+
freightcom_fedex_2day = "4102"
|
|
63
|
+
freightcom_fedex_priority_overnight = "4104"
|
|
64
|
+
freightcom_fedex_standard_overnight = "4105"
|
|
65
|
+
freightcom_fedex_first_overnight = "4106"
|
|
66
|
+
freightcom_fedex_international_priority = "4108"
|
|
67
|
+
freightcom_fedex_international_economy = "4109"
|
|
68
|
+
freightcom_ups_standard = "4600"
|
|
69
|
+
freightcom_ups_expedited = "4601"
|
|
70
|
+
freightcom_ups_express_saver = "4602"
|
|
71
|
+
freightcom_ups_express = "4603"
|
|
72
|
+
freightcom_ups_express_early = "4604"
|
|
73
|
+
freightcom_ups_3day_select = "4605"
|
|
74
|
+
freightcom_ups_worldwide_expedited = "4606"
|
|
75
|
+
freightcom_ups_worldwide_express = "4607"
|
|
76
|
+
freightcom_ups_worldwide_express_plus = "4608"
|
|
77
|
+
freightcom_ups_worldwide_express_saver = "4609"
|
|
78
|
+
freightcom_dhl_express_easy = "5202"
|
|
79
|
+
freightcom_dhl_express_10_30 = "5208"
|
|
80
|
+
freightcom_dhl_express_worldwide = "5211"
|
|
81
|
+
freightcom_dhl_express_12_00 = "5215"
|
|
82
|
+
freightcom_dhl_economy_select = "5216"
|
|
83
|
+
freightcom_dhl_ecommerce_am_service = "5706"
|
|
84
|
+
freightcom_dhl_ecommerce_ground_service = "5707"
|
|
85
|
+
freightcom_canadapost_regular_parcel = "6301"
|
|
86
|
+
freightcom_canadapost_expedited_parcel = "6300"
|
|
87
|
+
freightcom_canadapost_xpresspost = "6303"
|
|
88
|
+
freightcom_canadapost_priority = "6302"
|
|
89
|
+
|
|
90
|
+
@classmethod
|
|
91
|
+
def info(cls, serviceId, carrierId, serviceName, carrierName):
|
|
92
|
+
carrier_name = CARRIER_IDS.get(str(carrierId)) or carrierName
|
|
93
|
+
service = cls.map(str(serviceId))
|
|
94
|
+
formatted_name = re.sub(
|
|
95
|
+
r"((?<=[a-z])[A-Z]|(?<!\A)[A-Z](?=[a-z]))", r" \1", serviceName
|
|
96
|
+
)
|
|
97
|
+
service_name = (service.name or formatted_name).replace("freightcom_", "")
|
|
98
|
+
|
|
99
|
+
return carrier_name, service.name_or_key, service_name
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
CARRIER_IDS = {
|
|
103
|
+
"34": "canpar",
|
|
104
|
+
"37": "dicom",
|
|
105
|
+
"40": "purolator",
|
|
106
|
+
"41": "fedex",
|
|
107
|
+
"52": "dhl",
|
|
108
|
+
"57": "dhl_ecommerce",
|
|
109
|
+
"63": "canadapost",
|
|
110
|
+
"46": "ups",
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
class ShippingOption(lib.Enum):
|
|
115
|
+
freightcom_saturday_pickup_required = lib.OptionEnum("saturdayPickupRequired", bool)
|
|
116
|
+
freightcom_homeland_security = lib.OptionEnum("homelandSecurity", bool)
|
|
117
|
+
freightcom_exhibition_convention_site = lib.OptionEnum(
|
|
118
|
+
"exhibitionConventionSite", bool
|
|
119
|
+
)
|
|
120
|
+
freightcom_military_base_delivery = lib.OptionEnum("militaryBaseDelivery", bool)
|
|
121
|
+
freightcom_customs_in_bond_freight = lib.OptionEnum("customsIn_bondFreight", bool)
|
|
122
|
+
freightcom_limited_access = lib.OptionEnum("limitedAccess", bool)
|
|
123
|
+
freightcom_excess_length = lib.OptionEnum("excessLength", bool)
|
|
124
|
+
freightcom_tailgate_pickup = lib.OptionEnum("tailgatePickup", bool)
|
|
125
|
+
freightcom_residential_pickup = lib.OptionEnum("residentialPickup", bool)
|
|
126
|
+
freightcom_cross_border_fee = lib.OptionEnum("crossBorderFee", bool)
|
|
127
|
+
freightcom_notify_recipient = lib.OptionEnum("notifyRecipient", bool)
|
|
128
|
+
freightcom_single_shipment = lib.OptionEnum("singleShipment", bool)
|
|
129
|
+
freightcom_tailgate_delivery = lib.OptionEnum("tailgateDelivery", bool)
|
|
130
|
+
freightcom_residential_delivery = lib.OptionEnum("residentialDelivery", bool)
|
|
131
|
+
freightcom_insurance_type = lib.OptionEnum("insuranceType", float)
|
|
132
|
+
freightcom_inside_delivery = lib.OptionEnum("insideDelivery", bool)
|
|
133
|
+
freightcom_is_saturday_service = lib.OptionEnum("isSaturdayService", bool)
|
|
134
|
+
freightcom_dangerous_goods_type = lib.OptionEnum("dangerousGoodsType", bool)
|
|
135
|
+
freightcom_stackable = lib.OptionEnum("stackable", bool)
|
|
136
|
+
|
|
137
|
+
""" Unified Option type mapping """
|
|
138
|
+
saturday_delivery = freightcom_saturday_pickup_required
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def shipping_options_initializer(
|
|
142
|
+
options: dict,
|
|
143
|
+
package_options: units.Options = None,
|
|
144
|
+
) -> units.Options:
|
|
145
|
+
"""
|
|
146
|
+
Apply default values to the given options.
|
|
147
|
+
"""
|
|
148
|
+
_options = options.copy()
|
|
149
|
+
|
|
150
|
+
if package_options is not None:
|
|
151
|
+
_options.update(package_options.content)
|
|
152
|
+
|
|
153
|
+
return units.ShippingOptions(_options, ShippingOption)
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import math
|
|
2
|
+
from typing import Optional
|
|
3
|
+
from karrio.core import Settings as BaseSettings
|
|
4
|
+
from karrio.core.utils import XP
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Settings(BaseSettings):
|
|
8
|
+
"""Freightcom connection settings."""
|
|
9
|
+
|
|
10
|
+
username: str
|
|
11
|
+
password: str
|
|
12
|
+
|
|
13
|
+
account_country_code: str = None
|
|
14
|
+
metadata: dict = {}
|
|
15
|
+
config: dict = {}
|
|
16
|
+
|
|
17
|
+
@property
|
|
18
|
+
def server_url(self):
|
|
19
|
+
return (
|
|
20
|
+
"https://test.freightcom.com/rpc2"
|
|
21
|
+
if self.test_mode
|
|
22
|
+
else "https://app.freightcom.com/rpc2"
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
@property
|
|
26
|
+
def carrier_name(self):
|
|
27
|
+
return "freightcom"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def standard_request_serializer(element) -> str:
|
|
31
|
+
return XP.export(
|
|
32
|
+
element, namespacedef_='xmlns="http://www.freightcom.net/XMLSchema"'
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def ceil(value: Optional[float]) -> Optional[int]:
|
|
37
|
+
if value is None:
|
|
38
|
+
return None
|
|
39
|
+
return math.ceil(value)
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
from typing import List, Tuple
|
|
2
|
+
from karrio.schemas.freightcom.shipment_cancel_request import (
|
|
3
|
+
ShipmentCancelRequestType,
|
|
4
|
+
Freightcom,
|
|
5
|
+
OrderType,
|
|
6
|
+
)
|
|
7
|
+
from karrio.core.models import ShipmentCancelRequest, ConfirmationDetails, Message
|
|
8
|
+
from karrio.core.utils import (
|
|
9
|
+
Element,
|
|
10
|
+
Serializable,
|
|
11
|
+
)
|
|
12
|
+
from karrio.providers.freightcom.error import parse_error_response
|
|
13
|
+
from karrio.providers.freightcom.utils import Settings, standard_request_serializer
|
|
14
|
+
import karrio.lib as lib
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def parse_shipment_cancel_reply(
|
|
18
|
+
_response: lib.Deserializable[Element],
|
|
19
|
+
settings: Settings,
|
|
20
|
+
) -> Tuple[ConfirmationDetails, List[Message]]:
|
|
21
|
+
response = _response.deserialize()
|
|
22
|
+
errors = parse_error_response(response, settings)
|
|
23
|
+
success = len(errors) == 0
|
|
24
|
+
confirmation: ConfirmationDetails = (
|
|
25
|
+
ConfirmationDetails(
|
|
26
|
+
carrier_id=settings.carrier_id,
|
|
27
|
+
carrier_name=settings.carrier_name,
|
|
28
|
+
success=success,
|
|
29
|
+
operation="Cancel Shipment",
|
|
30
|
+
)
|
|
31
|
+
if success
|
|
32
|
+
else None
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
return confirmation, errors
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def shipment_cancel_request(
|
|
39
|
+
payload: ShipmentCancelRequest, settings: Settings
|
|
40
|
+
) -> Serializable:
|
|
41
|
+
request = Freightcom(
|
|
42
|
+
username=settings.username,
|
|
43
|
+
password=settings.password,
|
|
44
|
+
version="3.1.0",
|
|
45
|
+
ShipmentCancelRequest=ShipmentCancelRequestType(
|
|
46
|
+
Order=OrderType(orderId=payload.shipment_identifier)
|
|
47
|
+
),
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
return Serializable(request, standard_request_serializer)
|
|
File without changes
|