karrio-hay-post 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/hay_post/__init__.py +4 -0
- karrio/mappers/hay_post/mapper.py +40 -0
- karrio/mappers/hay_post/proxy.py +61 -0
- karrio/mappers/hay_post/settings.py +23 -0
- karrio/plugins/hay_post/__init__.py +23 -0
- karrio/providers/hay_post/__init__.py +11 -0
- karrio/providers/hay_post/error.py +30 -0
- karrio/providers/hay_post/rate.py +115 -0
- karrio/providers/hay_post/shipment/__init__.py +5 -0
- karrio/providers/hay_post/shipment/create.py +106 -0
- karrio/providers/hay_post/tracking.py +82 -0
- karrio/providers/hay_post/units.py +303 -0
- karrio/providers/hay_post/utils.py +65 -0
- karrio/schemas/hay_post/__init__.py +0 -0
- karrio/schemas/hay_post/auth_request.py +12 -0
- karrio/schemas/hay_post/auth_response.py +11 -0
- karrio/schemas/hay_post/error.py +9 -0
- karrio/schemas/hay_post/order_create_request.py +36 -0
- karrio/schemas/hay_post/order_create_response.py +12 -0
- karrio/schemas/hay_post/order_tracking_request.py +8 -0
- karrio/schemas/hay_post/order_tracking_response.py +103 -0
- karrio/schemas/hay_post/tariff_request.py +80 -0
- karrio_hay_post-2025.5rc1.dist-info/METADATA +86 -0
- karrio_hay_post-2025.5rc1.dist-info/RECORD +27 -0
- karrio_hay_post-2025.5rc1.dist-info/WHEEL +5 -0
- karrio_hay_post-2025.5rc1.dist-info/entry_points.txt +2 -0
- karrio_hay_post-2025.5rc1.dist-info/top_level.txt +3 -0
@@ -0,0 +1,40 @@
|
|
1
|
+
"""Karrio HayPost client mapper."""
|
2
|
+
|
3
|
+
import typing
|
4
|
+
import karrio.lib as lib
|
5
|
+
import karrio.api.mapper as mapper
|
6
|
+
import karrio.core.models as models
|
7
|
+
import karrio.providers.hay_post as provider
|
8
|
+
import karrio.mappers.hay_post.settings as provider_settings
|
9
|
+
|
10
|
+
|
11
|
+
class Mapper(mapper.Mapper):
|
12
|
+
settings: provider_settings.Settings
|
13
|
+
|
14
|
+
def create_rate_request(self, payload: models.RateRequest) -> lib.Serializable:
|
15
|
+
return provider.rate_request(payload, self.settings)
|
16
|
+
|
17
|
+
def create_tracking_request(
|
18
|
+
self, payload: models.TrackingRequest
|
19
|
+
) -> lib.Serializable:
|
20
|
+
return provider.tracking_request(payload, self.settings)
|
21
|
+
|
22
|
+
def create_shipment_request(
|
23
|
+
self, payload: models.ShipmentRequest
|
24
|
+
) -> lib.Serializable:
|
25
|
+
return provider.shipment_request(payload, self.settings)
|
26
|
+
|
27
|
+
def parse_rate_response(
|
28
|
+
self, response: lib.Deserializable[str]
|
29
|
+
) -> typing.Tuple[typing.List[models.RateDetails], typing.List[models.Message]]:
|
30
|
+
return provider.parse_rate_response(response, self.settings)
|
31
|
+
|
32
|
+
def parse_shipment_response(
|
33
|
+
self, response: lib.Deserializable[str]
|
34
|
+
) -> typing.Tuple[models.ShipmentDetails, typing.List[models.Message]]:
|
35
|
+
return provider.parse_shipment_response(response, self.settings)
|
36
|
+
|
37
|
+
def parse_tracking_response(
|
38
|
+
self, response: lib.Deserializable[str]
|
39
|
+
) -> typing.Tuple[typing.List[models.TrackingDetails], typing.List[models.Message]]:
|
40
|
+
return provider.parse_tracking_response(response, self.settings)
|
@@ -0,0 +1,61 @@
|
|
1
|
+
"""Karrio HayPost client proxy."""
|
2
|
+
|
3
|
+
import karrio.lib as lib
|
4
|
+
import karrio.api.proxy as proxy
|
5
|
+
import karrio.mappers.hay_post.settings as provider_settings
|
6
|
+
|
7
|
+
|
8
|
+
class Proxy(proxy.Proxy):
|
9
|
+
settings: provider_settings.Settings
|
10
|
+
|
11
|
+
def get_rates(self, request: lib.Serializable) -> lib.Deserializable[str]:
|
12
|
+
response = lib.request(
|
13
|
+
url=f"{self.settings.server_url}/Api/Order/CalculateTariff",
|
14
|
+
data=lib.to_json(lib.to_list(request.serialize())),
|
15
|
+
trace=self.trace_as("json"),
|
16
|
+
method="POST",
|
17
|
+
headers={
|
18
|
+
"Accept": "application/json",
|
19
|
+
"Content-Type": "application/json",
|
20
|
+
"Authorization": self.settings.authorization,
|
21
|
+
},
|
22
|
+
proxy=self.settings.proxy,
|
23
|
+
)
|
24
|
+
|
25
|
+
response_dict = {"rates": response, "request": request.value}
|
26
|
+
|
27
|
+
return lib.Deserializable(response_dict, lib.to_dict)
|
28
|
+
|
29
|
+
def create_shipment(self, request: lib.Serializable) -> lib.Deserializable[str]:
|
30
|
+
response = lib.request(
|
31
|
+
url=f"{self.settings.server_url}/Api/Order/CreateOrderByCustomerShort",
|
32
|
+
data=lib.to_json(request.serialize()),
|
33
|
+
trace=self.trace_as("json"),
|
34
|
+
method="POST",
|
35
|
+
headers={
|
36
|
+
"Accept": "application/json",
|
37
|
+
"Content-Type": "application/json",
|
38
|
+
"Authorization": self.settings.authorization,
|
39
|
+
},
|
40
|
+
proxy=self.settings.proxy,
|
41
|
+
)
|
42
|
+
|
43
|
+
return lib.Deserializable(response, lib.to_dict)
|
44
|
+
|
45
|
+
def get_tracking(self, request: lib.Serializable) -> lib.Deserializable[str]:
|
46
|
+
query = request.serialize()
|
47
|
+
trackingnumber = query[0]
|
48
|
+
|
49
|
+
response = lib.request(
|
50
|
+
url=f"{self.settings.server_url}/Api/Order/Tracking/{trackingnumber}",
|
51
|
+
trace=self.trace_as("json"),
|
52
|
+
method="GET",
|
53
|
+
proxy=self.settings.proxy,
|
54
|
+
headers={
|
55
|
+
"Accept": "application/json",
|
56
|
+
"Content-Type": "application/json",
|
57
|
+
"Authorization": self.settings.authorization,
|
58
|
+
},
|
59
|
+
)
|
60
|
+
|
61
|
+
return lib.Deserializable(response, lib.to_dict)
|
@@ -0,0 +1,23 @@
|
|
1
|
+
"""Karrio HayPost client settings."""
|
2
|
+
|
3
|
+
import attr
|
4
|
+
import karrio.providers.hay_post.utils as provider_utils
|
5
|
+
|
6
|
+
|
7
|
+
@attr.s(auto_attribs=True)
|
8
|
+
class Settings(provider_utils.Settings):
|
9
|
+
"""HayPost connection settings."""
|
10
|
+
|
11
|
+
# required carrier specific properties
|
12
|
+
username: str
|
13
|
+
password: str
|
14
|
+
customer_id: str
|
15
|
+
customer_type: str
|
16
|
+
|
17
|
+
# generic properties
|
18
|
+
id: str = None
|
19
|
+
test_mode: bool = False
|
20
|
+
carrier_id: str = "hay_post"
|
21
|
+
account_country_code: str = None
|
22
|
+
metadata: dict = {}
|
23
|
+
config: dict = {}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
import karrio.core.metadata as metadata
|
2
|
+
import karrio.mappers.hay_post as mappers
|
3
|
+
import karrio.providers.hay_post.units as units
|
4
|
+
|
5
|
+
|
6
|
+
METADATA = metadata.PluginMetadata(
|
7
|
+
status="beta",
|
8
|
+
id="hay_post",
|
9
|
+
label="HayPost",
|
10
|
+
|
11
|
+
# Integrations
|
12
|
+
Mapper=mappers.Mapper,
|
13
|
+
Proxy=mappers.Proxy,
|
14
|
+
Settings=mappers.Settings,
|
15
|
+
|
16
|
+
# Data Units
|
17
|
+
services=units.ShippingService,
|
18
|
+
options=units.ShippingOption,
|
19
|
+
connection_configs=units.ConnectionConfig,
|
20
|
+
# package_presets=units.PackagePresets, # Enum of parcel presets/templates
|
21
|
+
|
22
|
+
is_hub=False
|
23
|
+
)
|
@@ -0,0 +1,11 @@
|
|
1
|
+
|
2
|
+
from karrio.providers.hay_post.utils import Settings
|
3
|
+
from karrio.providers.hay_post.rate import parse_rate_response, rate_request
|
4
|
+
from karrio.providers.hay_post.shipment import (
|
5
|
+
parse_shipment_response,
|
6
|
+
shipment_request,
|
7
|
+
)
|
8
|
+
from karrio.providers.hay_post.tracking import (
|
9
|
+
parse_tracking_response,
|
10
|
+
tracking_request,
|
11
|
+
)
|
@@ -0,0 +1,30 @@
|
|
1
|
+
import typing
|
2
|
+
import karrio.lib as lib
|
3
|
+
import karrio.core.models as models
|
4
|
+
import karrio.providers.hay_post.utils as provider_utils
|
5
|
+
|
6
|
+
import karrio.schemas.hay_post.error as hay_post
|
7
|
+
|
8
|
+
|
9
|
+
def parse_error_response(
|
10
|
+
response: dict,
|
11
|
+
settings: provider_utils.Settings,
|
12
|
+
**kwargs,
|
13
|
+
) -> typing.List[models.Message]:
|
14
|
+
responses = response if isinstance(response, list) else [response]
|
15
|
+
|
16
|
+
errors: typing.List[hay_post.ErrorType] = [
|
17
|
+
lib.to_object(hay_post.ErrorType, error) for error in responses
|
18
|
+
]
|
19
|
+
|
20
|
+
return [
|
21
|
+
models.Message(
|
22
|
+
carrier_id=settings.carrier_id,
|
23
|
+
carrier_name=settings.carrier_name,
|
24
|
+
code="error",
|
25
|
+
message=" ".join(error.key.split("_")).capitalize(),
|
26
|
+
details={**kwargs},
|
27
|
+
)
|
28
|
+
for error in errors
|
29
|
+
if error.key is not None
|
30
|
+
]
|
@@ -0,0 +1,115 @@
|
|
1
|
+
import typing
|
2
|
+
import karrio.lib as lib
|
3
|
+
import karrio.core.models as models
|
4
|
+
import karrio.providers.hay_post.error as error
|
5
|
+
|
6
|
+
import karrio.providers.hay_post.utils as provider_utils
|
7
|
+
import karrio.providers.hay_post.units as provider_units
|
8
|
+
import karrio.schemas.hay_post.tariff_request as hay_post
|
9
|
+
|
10
|
+
|
11
|
+
def parse_rate_response(
|
12
|
+
_response: lib.Deserializable[dict],
|
13
|
+
settings: provider_utils.Settings,
|
14
|
+
) -> typing.Tuple[typing.List[models.RateDetails], typing.List[models.Message]]:
|
15
|
+
response = _response.deserialize()
|
16
|
+
rate_response = lib.to_dict(response.get("rates"))
|
17
|
+
|
18
|
+
messages = error.parse_error_response(response, settings)
|
19
|
+
rates = [
|
20
|
+
(
|
21
|
+
_extract_details(response, settings)
|
22
|
+
if not isinstance(rate_response, dict)
|
23
|
+
else None
|
24
|
+
)
|
25
|
+
]
|
26
|
+
|
27
|
+
return rates, messages
|
28
|
+
|
29
|
+
|
30
|
+
def _extract_details(
|
31
|
+
data: dict,
|
32
|
+
settings: provider_utils.Settings,
|
33
|
+
) -> models.RateDetails:
|
34
|
+
service = provider_units.ShippingService.map(
|
35
|
+
str(data.get("request", {}).get("serviceCategoryDirectionId", 0))
|
36
|
+
)
|
37
|
+
currency = provider_units.ShippingCurrency.map(
|
38
|
+
str(data.get("request", {}).get("currencyId", 0))
|
39
|
+
).name
|
40
|
+
|
41
|
+
return models.RateDetails(
|
42
|
+
carrier_id=settings.carrier_id,
|
43
|
+
carrier_name=settings.carrier_name,
|
44
|
+
service=service.name_or_key,
|
45
|
+
total_charge=lib.to_money(data.get("rates", 0)),
|
46
|
+
currency=currency,
|
47
|
+
)
|
48
|
+
|
49
|
+
|
50
|
+
def rate_request(
|
51
|
+
payload: models.RateRequest,
|
52
|
+
settings: provider_utils.Settings,
|
53
|
+
) -> lib.Serializable:
|
54
|
+
shipper = lib.to_address(payload.shipper)
|
55
|
+
recipient = lib.to_address(payload.recipient)
|
56
|
+
packages = lib.to_packages(payload.parcels)
|
57
|
+
|
58
|
+
options = lib.to_shipping_options(
|
59
|
+
payload.options,
|
60
|
+
package_options=packages.options,
|
61
|
+
initializer=provider_units.shipping_options_initializer,
|
62
|
+
)
|
63
|
+
|
64
|
+
service = (
|
65
|
+
lib.to_services(payload.services, provider_units.ShippingService).first
|
66
|
+
or provider_units.ShippingService.yes_ordered_value
|
67
|
+
)
|
68
|
+
|
69
|
+
currency_id = lib.to_int(
|
70
|
+
provider_units.ShippingCurrency.map(options.currency.state).value
|
71
|
+
or provider_units.ShippingCurrency.AMD.value
|
72
|
+
)
|
73
|
+
additional_services = [
|
74
|
+
int(service.value.code)
|
75
|
+
for service in provider_units.ShippingOption
|
76
|
+
if service.name in options
|
77
|
+
]
|
78
|
+
|
79
|
+
if not additional_services:
|
80
|
+
additional_services.append(
|
81
|
+
int(provider_units.ShippingOption.notification.value.code)
|
82
|
+
)
|
83
|
+
|
84
|
+
request = hay_post.TariffRequestElementType(
|
85
|
+
customerId=int(settings.customer_id),
|
86
|
+
serviceCategoryDirectionId=int(service.value),
|
87
|
+
weight=packages.weight.value,
|
88
|
+
totalPrice=packages.total_value if packages.total_value else 0,
|
89
|
+
currencyId=currency_id,
|
90
|
+
destinationAddress=hay_post.NAddressType(
|
91
|
+
cityVillage=recipient.city,
|
92
|
+
address=recipient.address_line1,
|
93
|
+
postalCode=recipient.postal_code,
|
94
|
+
receiverInfo=hay_post.ReceiverInfoType(
|
95
|
+
companyName=recipient.company_name,
|
96
|
+
firstName=recipient.person_name,
|
97
|
+
phoneNumber=recipient.phone_number,
|
98
|
+
email=recipient.email,
|
99
|
+
),
|
100
|
+
),
|
101
|
+
returnAddress=hay_post.NAddressType(
|
102
|
+
cityVillage=shipper.city,
|
103
|
+
address=shipper.address_line1,
|
104
|
+
postalCode=shipper.postal_code,
|
105
|
+
receiverInfo=hay_post.ReceiverInfoType(
|
106
|
+
companyName=shipper.company_name,
|
107
|
+
firstName=shipper.person_name,
|
108
|
+
phoneNumber=shipper.phone_number,
|
109
|
+
email=shipper.email,
|
110
|
+
),
|
111
|
+
),
|
112
|
+
additionalServices=additional_services,
|
113
|
+
)
|
114
|
+
|
115
|
+
return lib.Serializable(request, lib.to_dict)
|
@@ -0,0 +1,106 @@
|
|
1
|
+
import typing
|
2
|
+
import karrio.lib as lib
|
3
|
+
import karrio.core.units as units
|
4
|
+
import karrio.core.models as models
|
5
|
+
import karrio.providers.hay_post.error as error
|
6
|
+
import karrio.providers.hay_post.utils as provider_utils
|
7
|
+
import karrio.providers.hay_post.units as provider_units
|
8
|
+
import karrio.schemas.hay_post.order_create_request as hay_post
|
9
|
+
import karrio.schemas.hay_post.order_create_response as hay_post_response
|
10
|
+
|
11
|
+
|
12
|
+
def parse_shipment_response(
|
13
|
+
_response: lib.Deserializable[dict],
|
14
|
+
settings: provider_utils.Settings,
|
15
|
+
) -> typing.Tuple[models.ShipmentDetails, typing.List[models.Message]]:
|
16
|
+
response = _response.deserialize()
|
17
|
+
|
18
|
+
messages = error.parse_error_response(response, settings)
|
19
|
+
shipment = (
|
20
|
+
_extract_details(response, settings) if response.get("key") is None else None
|
21
|
+
)
|
22
|
+
|
23
|
+
return shipment, messages
|
24
|
+
|
25
|
+
|
26
|
+
def _extract_details(
|
27
|
+
data: dict,
|
28
|
+
settings: provider_utils.Settings,
|
29
|
+
) -> models.ShipmentDetails:
|
30
|
+
shipment = lib.to_object(hay_post_response.OrderCreateResponseType, data)
|
31
|
+
return models.ShipmentDetails(
|
32
|
+
carrier_id=settings.carrier_id,
|
33
|
+
carrier_name=settings.carrier_name,
|
34
|
+
tracking_number=shipment.barcode,
|
35
|
+
shipment_identifier=str(shipment.id),
|
36
|
+
docs=models.Documents(
|
37
|
+
label="No label...",
|
38
|
+
),
|
39
|
+
meta=dict(
|
40
|
+
revertOrderId=shipment.revertOrderId,
|
41
|
+
revertBarcode=shipment.revertBarcode,
|
42
|
+
postalcode=shipment.postalcode,
|
43
|
+
),
|
44
|
+
)
|
45
|
+
|
46
|
+
|
47
|
+
def shipment_request(
|
48
|
+
payload: models.ShipmentRequest,
|
49
|
+
settings: provider_utils.Settings,
|
50
|
+
) -> lib.Serializable:
|
51
|
+
shipper = lib.to_address(payload.shipper)
|
52
|
+
recipient = lib.to_address(payload.recipient)
|
53
|
+
packages = lib.to_packages(payload.parcels)
|
54
|
+
service = provider_units.ShippingService.map(payload.service)
|
55
|
+
|
56
|
+
options = lib.to_shipping_options(
|
57
|
+
payload.options,
|
58
|
+
package_options=packages.options,
|
59
|
+
initializer=provider_units.shipping_options_initializer,
|
60
|
+
)
|
61
|
+
|
62
|
+
additional_services = [
|
63
|
+
int(service.value.code)
|
64
|
+
for service in provider_units.ShippingOption
|
65
|
+
if service.name in options
|
66
|
+
]
|
67
|
+
|
68
|
+
shipper_country_id = lib.to_int(
|
69
|
+
provider_units.ShippingCountries.map(shipper.country_code).value
|
70
|
+
)
|
71
|
+
recipient_country_id = lib.to_int(
|
72
|
+
provider_units.ShippingCountries.map(recipient.country_code).value
|
73
|
+
)
|
74
|
+
|
75
|
+
request = hay_post.OrderCreateRequestType(
|
76
|
+
customerId=int(settings.customer_id),
|
77
|
+
serviceCategoryDirectionId=service.value,
|
78
|
+
weight=packages.weight.value,
|
79
|
+
destinationAddress=hay_post.NAddressType(
|
80
|
+
countryId=recipient_country_id,
|
81
|
+
street=recipient.street,
|
82
|
+
cityVillage=recipient.city,
|
83
|
+
postalCode=recipient.postal_code,
|
84
|
+
receiverInfo=hay_post.ReceiverInfoType(
|
85
|
+
companyName=recipient.company_name,
|
86
|
+
firstName=recipient.person_name,
|
87
|
+
phoneNumber=recipient.phone_number,
|
88
|
+
email=recipient.email,
|
89
|
+
),
|
90
|
+
),
|
91
|
+
returnAddress=hay_post.NAddressType(
|
92
|
+
countryId=shipper_country_id,
|
93
|
+
street=shipper.street,
|
94
|
+
cityVillage=shipper.city,
|
95
|
+
postalCode=shipper.postal_code,
|
96
|
+
receiverInfo=hay_post.ReceiverInfoType(
|
97
|
+
companyName=shipper.company_name,
|
98
|
+
firstName=shipper.person_name,
|
99
|
+
phoneNumber=shipper.phone_number,
|
100
|
+
email=shipper.email,
|
101
|
+
),
|
102
|
+
),
|
103
|
+
additionalServices=additional_services,
|
104
|
+
)
|
105
|
+
|
106
|
+
return lib.Serializable(request, lib.to_dict)
|
@@ -0,0 +1,82 @@
|
|
1
|
+
import typing
|
2
|
+
import karrio.lib as lib
|
3
|
+
import karrio.core.models as models
|
4
|
+
import karrio.providers.hay_post.error as error
|
5
|
+
import karrio.providers.hay_post.units as provider_units
|
6
|
+
import karrio.providers.hay_post.utils as provider_utils
|
7
|
+
import karrio.schemas.hay_post.order_tracking_response as hay_post
|
8
|
+
|
9
|
+
from datetime import datetime
|
10
|
+
|
11
|
+
|
12
|
+
def parse_tracking_response(
|
13
|
+
_response: lib.Deserializable[dict],
|
14
|
+
settings: provider_utils.Settings,
|
15
|
+
) -> typing.Tuple[typing.List[models.TrackingDetails], typing.List[models.Message]]:
|
16
|
+
response = _response.deserialize()
|
17
|
+
|
18
|
+
messages = error.parse_error_response(response, settings)
|
19
|
+
tracking_details = [
|
20
|
+
_extract_details(response, settings) if response.get("key") is None else None
|
21
|
+
]
|
22
|
+
|
23
|
+
return tracking_details, messages
|
24
|
+
|
25
|
+
|
26
|
+
def _extract_details(
|
27
|
+
data: dict,
|
28
|
+
settings: provider_utils.Settings,
|
29
|
+
) -> models.TrackingDetails:
|
30
|
+
detail = lib.to_object(hay_post.OrderTrackingResponseType, data)
|
31
|
+
|
32
|
+
status = next(
|
33
|
+
(
|
34
|
+
status.name
|
35
|
+
for status in list(provider_units.TrackingStatus)
|
36
|
+
if detail.order.stateId in status.value
|
37
|
+
),
|
38
|
+
provider_units.TrackingStatus.delivered.name,
|
39
|
+
)
|
40
|
+
|
41
|
+
return models.TrackingDetails(
|
42
|
+
tracking_number=detail.order.trackingId,
|
43
|
+
carrier_name=settings.carrier_name,
|
44
|
+
carrier_id=settings.carrier_id,
|
45
|
+
info=models.TrackingInfo(
|
46
|
+
customer_name=f"{detail.customer.firstName} {detail.customer.lastName}",
|
47
|
+
note=detail.order.comment,
|
48
|
+
order_date=lib.fdate(detail.order.createDate, "%Y-%m-%dT%H:%M:%S"),
|
49
|
+
order_id=str(detail.order.id),
|
50
|
+
package_weight=str(detail.order.weight),
|
51
|
+
shipment_pickup_date=lib.fdate(
|
52
|
+
detail.order.createDate, "%Y-%m-%dT%H:%M:%S"
|
53
|
+
),
|
54
|
+
shipment_service=detail.order.service.name,
|
55
|
+
shipment_origin_country=detail.returnAddress.country.name,
|
56
|
+
shipment_origin_postal_code=detail.returnAddress.postalCode,
|
57
|
+
shipment_destination_country=detail.orderDestinationAddress.country.name,
|
58
|
+
shipment_destination_postal_code=detail.orderDestinationAddress.country.name,
|
59
|
+
),
|
60
|
+
events=[
|
61
|
+
models.TrackingEvent(
|
62
|
+
date=lib.fdate(detail.order.createDate, "%Y-%m-%dT%H:%M:%S"),
|
63
|
+
description=(
|
64
|
+
detail.order.comment if detail.order.comment else "No description"
|
65
|
+
),
|
66
|
+
code=detail.order.transactionId,
|
67
|
+
time=lib.fdate(detail.order.createDate, "%Y-%m-%dT%H:%M:%S"),
|
68
|
+
location=detail.orderDestinationAddress.address,
|
69
|
+
)
|
70
|
+
],
|
71
|
+
delivered=status == "delivered",
|
72
|
+
status=status,
|
73
|
+
)
|
74
|
+
|
75
|
+
|
76
|
+
def tracking_request(
|
77
|
+
payload: models.TrackingRequest,
|
78
|
+
settings: provider_utils.Settings,
|
79
|
+
) -> lib.Serializable:
|
80
|
+
request = payload.tracking_numbers
|
81
|
+
|
82
|
+
return lib.Serializable(request)
|
@@ -0,0 +1,303 @@
|
|
1
|
+
import karrio.lib as lib
|
2
|
+
import karrio.core.units as units
|
3
|
+
|
4
|
+
|
5
|
+
class PackagingType(lib.StrEnum):
|
6
|
+
"""Carrier specific packaging type"""
|
7
|
+
|
8
|
+
PACKAGE = "PACKAGE"
|
9
|
+
|
10
|
+
""" Unified Packaging type mapping """
|
11
|
+
envelope = PACKAGE
|
12
|
+
pak = PACKAGE
|
13
|
+
tube = PACKAGE
|
14
|
+
pallet = PACKAGE
|
15
|
+
small_box = PACKAGE
|
16
|
+
medium_box = PACKAGE
|
17
|
+
your_packaging = PACKAGE
|
18
|
+
|
19
|
+
|
20
|
+
class ShippingCurrency(lib.StrEnum):
|
21
|
+
RUB = "3"
|
22
|
+
USD = "2"
|
23
|
+
EUR = "4"
|
24
|
+
AMD = "1"
|
25
|
+
|
26
|
+
|
27
|
+
class ShippingService(lib.StrEnum):
|
28
|
+
"""Carrier specific services"""
|
29
|
+
|
30
|
+
letter_ordered = "88"
|
31
|
+
letter_simple = "79"
|
32
|
+
letter_valued = "89"
|
33
|
+
package_ordered = "93"
|
34
|
+
package_simple = "92"
|
35
|
+
package_valued = "100"
|
36
|
+
parcel_simple = "94"
|
37
|
+
parcel_valued = "95"
|
38
|
+
postcard_ordered = "91"
|
39
|
+
postcard_simple = "90"
|
40
|
+
sekogram_simple = "96"
|
41
|
+
sprint_simple = "97"
|
42
|
+
yes_ordered_value = "99"
|
43
|
+
|
44
|
+
|
45
|
+
class ShippingOption(lib.Enum):
|
46
|
+
"""Carrier specific options"""
|
47
|
+
|
48
|
+
notification = lib.OptionEnum("2", bool)
|
49
|
+
ordered_packaging = lib.OptionEnum("3", bool)
|
50
|
+
pick_up = lib.OptionEnum("4", bool)
|
51
|
+
postmen_delivery_value = lib.OptionEnum("5", bool)
|
52
|
+
delivery = lib.OptionEnum("6", bool)
|
53
|
+
international_notification = lib.OptionEnum("15", bool)
|
54
|
+
domestic_sms = lib.OptionEnum("16", bool)
|
55
|
+
international_sms = lib.OptionEnum("17", bool)
|
56
|
+
|
57
|
+
|
58
|
+
def shipping_options_initializer(
|
59
|
+
options: dict,
|
60
|
+
package_options: units.ShippingOptions = None,
|
61
|
+
) -> units.ShippingOptions:
|
62
|
+
"""
|
63
|
+
Apply default values to the given options.
|
64
|
+
"""
|
65
|
+
_options = options.copy()
|
66
|
+
|
67
|
+
if package_options is not None:
|
68
|
+
_options.update(package_options.content)
|
69
|
+
|
70
|
+
return units.ShippingOptions(_options, ShippingOption)
|
71
|
+
|
72
|
+
|
73
|
+
class ConnectionConfig(lib.Enum):
|
74
|
+
shipping_options = lib.OptionEnum("shipping_options", list)
|
75
|
+
shipping_services = lib.OptionEnum("shipping_services", list)
|
76
|
+
|
77
|
+
|
78
|
+
class TrackingStatus(lib.Enum):
|
79
|
+
on_hold = [11]
|
80
|
+
delivered = [6]
|
81
|
+
in_transit = [1, 2, 7, 5]
|
82
|
+
delivery_failed = [10, 3, 4]
|
83
|
+
delivery_delayed = [8, 9]
|
84
|
+
|
85
|
+
|
86
|
+
class ShippingCountries(lib.Enum):
|
87
|
+
"""Country codes"""
|
88
|
+
|
89
|
+
AF = 1
|
90
|
+
AL = 2
|
91
|
+
DZ = 3
|
92
|
+
AS = 4
|
93
|
+
AD = 5
|
94
|
+
AO = 6
|
95
|
+
AG = 9
|
96
|
+
AR = 10
|
97
|
+
AM = 11
|
98
|
+
AW = 12
|
99
|
+
AU = 13
|
100
|
+
AT = 14
|
101
|
+
BS = 16
|
102
|
+
BH = 17
|
103
|
+
BD = 18
|
104
|
+
BB = 19
|
105
|
+
BY = 20
|
106
|
+
BE = 21
|
107
|
+
BZ = 22
|
108
|
+
BJ = 23
|
109
|
+
BT = 25
|
110
|
+
BO = 26
|
111
|
+
BA = 28
|
112
|
+
BW = 29
|
113
|
+
BR = 31
|
114
|
+
VG = 33
|
115
|
+
BG = 35
|
116
|
+
BF = 36
|
117
|
+
BI = 37
|
118
|
+
CV = 38
|
119
|
+
KH = 39
|
120
|
+
CM = 40
|
121
|
+
CA = 41
|
122
|
+
KY = 42
|
123
|
+
CF = 43
|
124
|
+
TD = 44
|
125
|
+
CL = 45
|
126
|
+
CN = 46
|
127
|
+
HK = 47
|
128
|
+
MO = 47
|
129
|
+
CO = 51
|
130
|
+
KM = 52
|
131
|
+
CG = 53
|
132
|
+
CK = 54
|
133
|
+
CR = 55
|
134
|
+
HR = 56
|
135
|
+
CU = 57
|
136
|
+
CY = 59
|
137
|
+
CZ = 60
|
138
|
+
CD = 63
|
139
|
+
DK = 64
|
140
|
+
DJ = 65
|
141
|
+
DM = 66
|
142
|
+
DO = 67
|
143
|
+
EC = 68
|
144
|
+
EG = 69
|
145
|
+
SV = 70
|
146
|
+
GQ = 71
|
147
|
+
ER = 72
|
148
|
+
EE = 73
|
149
|
+
ET = 74
|
150
|
+
FJ = 77
|
151
|
+
FI = 78
|
152
|
+
FR = 79
|
153
|
+
GF = 80
|
154
|
+
PF = 81
|
155
|
+
GA = 83
|
156
|
+
GM = 84
|
157
|
+
GE = 85
|
158
|
+
DE = 86
|
159
|
+
GH = 87
|
160
|
+
GR = 89
|
161
|
+
GD = 91
|
162
|
+
GU = 93
|
163
|
+
GT = 94
|
164
|
+
GN = 96
|
165
|
+
GW = 97
|
166
|
+
GY = 98
|
167
|
+
HT = 99
|
168
|
+
HN = 102
|
169
|
+
HU = 103
|
170
|
+
IS = 104
|
171
|
+
IN = 105
|
172
|
+
ID = 106
|
173
|
+
IQ = 108
|
174
|
+
IE = 109
|
175
|
+
IL = 111
|
176
|
+
IT = 112
|
177
|
+
JM = 113
|
178
|
+
JP = 114
|
179
|
+
JO = 116
|
180
|
+
KZ = 117
|
181
|
+
KE = 118
|
182
|
+
KI = 119
|
183
|
+
KW = 120
|
184
|
+
KG = 121
|
185
|
+
LV = 123
|
186
|
+
LB = 124
|
187
|
+
LS = 125
|
188
|
+
LY = 127
|
189
|
+
LI = 128
|
190
|
+
LT = 129
|
191
|
+
LU = 130
|
192
|
+
MG = 131
|
193
|
+
MW = 132
|
194
|
+
MY = 133
|
195
|
+
MV = 134
|
196
|
+
ML = 135
|
197
|
+
MT = 136
|
198
|
+
MH = 137
|
199
|
+
MQ = 138
|
200
|
+
MR = 139
|
201
|
+
MU = 140
|
202
|
+
MX = 142
|
203
|
+
FM = 143
|
204
|
+
MC = 144
|
205
|
+
MN = 145
|
206
|
+
ME = 146
|
207
|
+
MZ = 149
|
208
|
+
MM = 150
|
209
|
+
NA = 151
|
210
|
+
NR = 152
|
211
|
+
NP = 153
|
212
|
+
NL = 154
|
213
|
+
NC = 155
|
214
|
+
NZ = 156
|
215
|
+
NI = 157
|
216
|
+
NE = 158
|
217
|
+
NG = 159
|
218
|
+
NU = 160
|
219
|
+
MP = 162
|
220
|
+
NO = 163
|
221
|
+
OM = 164
|
222
|
+
PK = 165
|
223
|
+
PW = 166
|
224
|
+
PA = 167
|
225
|
+
PG = 168
|
226
|
+
PY = 169
|
227
|
+
PE = 170
|
228
|
+
PH = 171
|
229
|
+
PL = 173
|
230
|
+
PT = 174
|
231
|
+
PR = 175
|
232
|
+
QA = 176
|
233
|
+
MD = 178
|
234
|
+
RO = 179
|
235
|
+
RU = 180
|
236
|
+
RW = 181
|
237
|
+
KN = 185
|
238
|
+
VC = 189
|
239
|
+
WS = 190
|
240
|
+
SM = 191
|
241
|
+
ST = 192
|
242
|
+
SA = 193
|
243
|
+
SN = 194
|
244
|
+
RS = 195
|
245
|
+
SC = 196
|
246
|
+
SL = 197
|
247
|
+
SG = 198
|
248
|
+
SK = 200
|
249
|
+
SI = 201
|
250
|
+
SB = 202
|
251
|
+
SO = 203
|
252
|
+
ZA = 204
|
253
|
+
ES = 207
|
254
|
+
LK = 208
|
255
|
+
PS = 209
|
256
|
+
SD = 210
|
257
|
+
SR = 211
|
258
|
+
SE = 214
|
259
|
+
CH = 215
|
260
|
+
SY = 216
|
261
|
+
TJ = 217
|
262
|
+
TH = 218
|
263
|
+
TL = 220
|
264
|
+
TG = 221
|
265
|
+
TO = 223
|
266
|
+
TT = 224
|
267
|
+
TN = 225
|
268
|
+
TM = 227
|
269
|
+
TV = 229
|
270
|
+
UG = 230
|
271
|
+
UA = 231
|
272
|
+
AE = 232
|
273
|
+
GB = 233
|
274
|
+
TZ = 234
|
275
|
+
US = 237
|
276
|
+
UY = 238
|
277
|
+
UZ = 239
|
278
|
+
VU = 240
|
279
|
+
VE = 241
|
280
|
+
VN = 242
|
281
|
+
YE = 245
|
282
|
+
ZM = 246
|
283
|
+
ZW = 247
|
284
|
+
BN = 252
|
285
|
+
GP = 253
|
286
|
+
SZ = 254
|
287
|
+
BL = 255
|
288
|
+
VA = 256
|
289
|
+
KR = 257
|
290
|
+
KP = 258
|
291
|
+
IR = 454
|
292
|
+
TW = 455
|
293
|
+
TR = 456
|
294
|
+
JE = 458
|
295
|
+
MK = 459
|
296
|
+
CW = 460
|
297
|
+
BM = 464
|
298
|
+
LA = 465
|
299
|
+
LR = 466
|
300
|
+
MA = 467
|
301
|
+
LC = 468
|
302
|
+
SS = 469
|
303
|
+
CI = 470
|
@@ -0,0 +1,65 @@
|
|
1
|
+
import json
|
2
|
+
import karrio.lib as lib
|
3
|
+
import karrio.core as core
|
4
|
+
|
5
|
+
|
6
|
+
class Settings(core.Settings):
|
7
|
+
"""HayPost connection settings."""
|
8
|
+
|
9
|
+
username: str
|
10
|
+
password: str
|
11
|
+
customer_id: str
|
12
|
+
customer_type: str
|
13
|
+
|
14
|
+
@property
|
15
|
+
def proxy(self):
|
16
|
+
# Add proxy for using hay_post API in test mode
|
17
|
+
if self.test_mode:
|
18
|
+
return "username:passowrd@host:port"
|
19
|
+
return None
|
20
|
+
|
21
|
+
@property
|
22
|
+
def carrier_name(self):
|
23
|
+
return "hay_post"
|
24
|
+
|
25
|
+
@property
|
26
|
+
def connection_config(self) -> lib.units.Options:
|
27
|
+
from karrio.providers.hay_post.units import ConnectionConfig
|
28
|
+
|
29
|
+
return lib.to_connection_config(
|
30
|
+
self.config or {},
|
31
|
+
option_type=ConnectionConfig,
|
32
|
+
)
|
33
|
+
|
34
|
+
@property
|
35
|
+
def server_url(self):
|
36
|
+
if self.test_mode:
|
37
|
+
return "https://dev-order.haypost.am"
|
38
|
+
return "https://order.haypost.am"
|
39
|
+
|
40
|
+
@property
|
41
|
+
def authorization(self):
|
42
|
+
url = "https://identity.haypost.am/api/Connect/Token"
|
43
|
+
if self.test_mode:
|
44
|
+
url = "https://dev-identity.haypost.am/api/Connect/Token"
|
45
|
+
|
46
|
+
try:
|
47
|
+
response = lib.request(
|
48
|
+
url=url,
|
49
|
+
method="POST",
|
50
|
+
data=json.dumps(
|
51
|
+
{
|
52
|
+
"username": self.username,
|
53
|
+
"password": self.password,
|
54
|
+
"customerType": self.customer_type,
|
55
|
+
}
|
56
|
+
),
|
57
|
+
proxy=self.proxy,
|
58
|
+
headers={"Content-Type": "application/json"},
|
59
|
+
)
|
60
|
+
|
61
|
+
return lib.to_dict(response).get("accessToken")
|
62
|
+
|
63
|
+
except Exception as e:
|
64
|
+
print(f"Request failed: {e}")
|
65
|
+
return None
|
File without changes
|
@@ -0,0 +1,12 @@
|
|
1
|
+
import attr
|
2
|
+
import jstruct
|
3
|
+
import typing
|
4
|
+
|
5
|
+
|
6
|
+
@attr.s(auto_attribs=True)
|
7
|
+
class AuthRequestType:
|
8
|
+
username: typing.Optional[str] = None
|
9
|
+
password: typing.Optional[str] = None
|
10
|
+
customerType: typing.Optional[int] = None
|
11
|
+
deviceId: typing.Optional[str] = None
|
12
|
+
fcmToken: typing.Optional[str] = None
|
@@ -0,0 +1,11 @@
|
|
1
|
+
import attr
|
2
|
+
import jstruct
|
3
|
+
import typing
|
4
|
+
|
5
|
+
|
6
|
+
@attr.s(auto_attribs=True)
|
7
|
+
class AuthResponseType:
|
8
|
+
accessToken: typing.Optional[str] = None
|
9
|
+
expDate: typing.Optional[int] = None
|
10
|
+
refreshToken: typing.Optional[str] = None
|
11
|
+
navigation: typing.Optional[int] = None
|
@@ -0,0 +1,36 @@
|
|
1
|
+
import attr
|
2
|
+
import jstruct
|
3
|
+
import typing
|
4
|
+
|
5
|
+
|
6
|
+
@attr.s(auto_attribs=True)
|
7
|
+
class ReceiverInfoType:
|
8
|
+
companyName: typing.Optional[str] = None
|
9
|
+
firstName: typing.Optional[str] = None
|
10
|
+
lastName: typing.Optional[str] = None
|
11
|
+
phoneNumber: typing.Optional[str] = None
|
12
|
+
email: typing.Optional[str] = None
|
13
|
+
|
14
|
+
|
15
|
+
@attr.s(auto_attribs=True)
|
16
|
+
class NAddressType:
|
17
|
+
countryId: typing.Optional[int] = None
|
18
|
+
provinceStateId: typing.Optional[int] = None
|
19
|
+
cityVillage: typing.Optional[str] = None
|
20
|
+
street: typing.Optional[str] = None
|
21
|
+
building: typing.Optional[int] = None
|
22
|
+
apartment: typing.Optional[int] = None
|
23
|
+
postalCode: typing.Optional[str] = None
|
24
|
+
receiverInfo: typing.Optional[ReceiverInfoType] = jstruct.JStruct[ReceiverInfoType]
|
25
|
+
|
26
|
+
|
27
|
+
@attr.s(auto_attribs=True)
|
28
|
+
class OrderCreateRequestType:
|
29
|
+
customerId: typing.Optional[int] = None
|
30
|
+
serviceCategoryDirectionId: typing.Optional[int] = None
|
31
|
+
weight: typing.Optional[int] = None
|
32
|
+
comment: typing.Optional[str] = None
|
33
|
+
returnRegisteredAddress: typing.Optional[bool] = None
|
34
|
+
destinationAddress: typing.Optional[NAddressType] = jstruct.JStruct[NAddressType]
|
35
|
+
returnAddress: typing.Optional[NAddressType] = jstruct.JStruct[NAddressType]
|
36
|
+
additionalServices: typing.Optional[typing.List[int]] = None
|
@@ -0,0 +1,12 @@
|
|
1
|
+
import attr
|
2
|
+
import jstruct
|
3
|
+
import typing
|
4
|
+
|
5
|
+
|
6
|
+
@attr.s(auto_attribs=True)
|
7
|
+
class OrderCreateResponseType:
|
8
|
+
id: typing.Optional[int] = None
|
9
|
+
barcode: typing.Optional[str] = None
|
10
|
+
revertOrderId: typing.Optional[int] = None
|
11
|
+
revertBarcode: typing.Optional[str] = None
|
12
|
+
postalcode: typing.Any = None
|
@@ -0,0 +1,103 @@
|
|
1
|
+
import attr
|
2
|
+
import jstruct
|
3
|
+
import typing
|
4
|
+
|
5
|
+
|
6
|
+
@attr.s(auto_attribs=True)
|
7
|
+
class AdditionalServiceType:
|
8
|
+
id: typing.Optional[int] = None
|
9
|
+
name: typing.Optional[str] = None
|
10
|
+
fee: typing.Optional[int] = None
|
11
|
+
key: typing.Optional[str] = None
|
12
|
+
relationIndexId: typing.Optional[int] = None
|
13
|
+
isActive: typing.Optional[bool] = None
|
14
|
+
|
15
|
+
|
16
|
+
@attr.s(auto_attribs=True)
|
17
|
+
class LegalTypeObjectType:
|
18
|
+
id: typing.Optional[int] = None
|
19
|
+
name: typing.Optional[str] = None
|
20
|
+
|
21
|
+
|
22
|
+
@attr.s(auto_attribs=True)
|
23
|
+
class CustomerType:
|
24
|
+
customerId: typing.Optional[int] = None
|
25
|
+
firstName: typing.Optional[str] = None
|
26
|
+
lastName: typing.Optional[str] = None
|
27
|
+
phone: typing.Any = None
|
28
|
+
legalType: typing.Optional[LegalTypeObjectType] = jstruct.JStruct[LegalTypeObjectType]
|
29
|
+
documents: typing.Optional[typing.List[typing.Any]] = None
|
30
|
+
companyName: typing.Any = None
|
31
|
+
|
32
|
+
|
33
|
+
@attr.s(auto_attribs=True)
|
34
|
+
class OrderType:
|
35
|
+
id: typing.Optional[int] = None
|
36
|
+
customerId: typing.Optional[int] = None
|
37
|
+
trackingId: typing.Optional[str] = None
|
38
|
+
amount: typing.Optional[int] = None
|
39
|
+
weight: typing.Optional[int] = None
|
40
|
+
stateId: typing.Optional[int] = None
|
41
|
+
comment: typing.Optional[str] = None
|
42
|
+
service: typing.Optional[LegalTypeObjectType] = jstruct.JStruct[LegalTypeObjectType]
|
43
|
+
category: typing.Optional[LegalTypeObjectType] = jstruct.JStruct[LegalTypeObjectType]
|
44
|
+
transactionId: typing.Any = None
|
45
|
+
bundle: typing.Any = None
|
46
|
+
shipment: typing.Any = None
|
47
|
+
createDate: typing.Optional[str] = None
|
48
|
+
isVerified: typing.Optional[bool] = None
|
49
|
+
recaddress: typing.Any = None
|
50
|
+
locationId: typing.Any = None
|
51
|
+
codAmount: typing.Any = None
|
52
|
+
paymentMethodId: typing.Optional[int] = None
|
53
|
+
isInternational: typing.Optional[bool] = None
|
54
|
+
partner: typing.Any = None
|
55
|
+
|
56
|
+
|
57
|
+
@attr.s(auto_attribs=True)
|
58
|
+
class ReceiverInfoType:
|
59
|
+
companyName: typing.Optional[str] = None
|
60
|
+
firstName: typing.Optional[str] = None
|
61
|
+
lastName: typing.Optional[str] = None
|
62
|
+
phoneNumber: typing.Optional[str] = None
|
63
|
+
email: typing.Optional[str] = None
|
64
|
+
nickname: typing.Any = None
|
65
|
+
|
66
|
+
|
67
|
+
@attr.s(auto_attribs=True)
|
68
|
+
class NAddressType:
|
69
|
+
country: typing.Optional[LegalTypeObjectType] = jstruct.JStruct[LegalTypeObjectType]
|
70
|
+
provinceState: typing.Optional[LegalTypeObjectType] = jstruct.JStruct[LegalTypeObjectType]
|
71
|
+
cityVillage: typing.Optional[LegalTypeObjectType] = jstruct.JStruct[LegalTypeObjectType]
|
72
|
+
street: typing.Optional[LegalTypeObjectType] = jstruct.JStruct[LegalTypeObjectType]
|
73
|
+
building: typing.Optional[LegalTypeObjectType] = jstruct.JStruct[LegalTypeObjectType]
|
74
|
+
apartment: typing.Optional[LegalTypeObjectType] = jstruct.JStruct[LegalTypeObjectType]
|
75
|
+
postalCode: typing.Optional[str] = None
|
76
|
+
address: typing.Any = None
|
77
|
+
isHomeDelivery: typing.Optional[bool] = None
|
78
|
+
isDeliveryPaid: typing.Optional[bool] = None
|
79
|
+
deliveryDate: typing.Optional[str] = None
|
80
|
+
receiverInfo: typing.Optional[ReceiverInfoType] = jstruct.JStruct[ReceiverInfoType]
|
81
|
+
factreceiverInfo: typing.Any = None
|
82
|
+
|
83
|
+
|
84
|
+
@attr.s(auto_attribs=True)
|
85
|
+
class OrderStateHistoryType:
|
86
|
+
id: typing.Optional[int] = None
|
87
|
+
orderId: typing.Optional[int] = None
|
88
|
+
stateId: typing.Optional[int] = None
|
89
|
+
createDate: typing.Optional[str] = None
|
90
|
+
userId: typing.Optional[int] = None
|
91
|
+
isActive: typing.Optional[bool] = None
|
92
|
+
|
93
|
+
|
94
|
+
@attr.s(auto_attribs=True)
|
95
|
+
class OrderTrackingResponseType:
|
96
|
+
order: typing.Optional[OrderType] = jstruct.JStruct[OrderType]
|
97
|
+
info: typing.Any = None
|
98
|
+
orderDestinationAddress: typing.Optional[NAddressType] = jstruct.JStruct[NAddressType]
|
99
|
+
returnAddress: typing.Optional[NAddressType] = jstruct.JStruct[NAddressType]
|
100
|
+
customer: typing.Optional[CustomerType] = jstruct.JStruct[CustomerType]
|
101
|
+
orderStateHistories: typing.Optional[typing.List[OrderStateHistoryType]] = jstruct.JList[OrderStateHistoryType]
|
102
|
+
additionalServices: typing.Optional[typing.List[AdditionalServiceType]] = jstruct.JList[AdditionalServiceType]
|
103
|
+
rejectedOrders: typing.Optional[typing.List[typing.Any]] = None
|
@@ -0,0 +1,80 @@
|
|
1
|
+
import attr
|
2
|
+
import jstruct
|
3
|
+
import typing
|
4
|
+
|
5
|
+
|
6
|
+
@attr.s(auto_attribs=True)
|
7
|
+
class ReceiverInfoType:
|
8
|
+
companyName: typing.Optional[str] = None
|
9
|
+
firstName: typing.Optional[str] = None
|
10
|
+
lastName: typing.Optional[str] = None
|
11
|
+
phoneNumber: typing.Optional[str] = None
|
12
|
+
email: typing.Optional[str] = None
|
13
|
+
nickname: typing.Optional[str] = None
|
14
|
+
|
15
|
+
|
16
|
+
@attr.s(auto_attribs=True)
|
17
|
+
class NAddressType:
|
18
|
+
countryId: typing.Optional[int] = None
|
19
|
+
provinceStateId: typing.Optional[int] = None
|
20
|
+
provinceState: typing.Optional[str] = None
|
21
|
+
cityVillageId: typing.Optional[int] = None
|
22
|
+
cityVillage: typing.Optional[str] = None
|
23
|
+
streetId: typing.Optional[int] = None
|
24
|
+
street: typing.Optional[str] = None
|
25
|
+
buildingId: typing.Optional[int] = None
|
26
|
+
building: typing.Optional[str] = None
|
27
|
+
apartment: typing.Optional[str] = None
|
28
|
+
apartmentId: typing.Optional[int] = None
|
29
|
+
address: typing.Optional[str] = None
|
30
|
+
postalCode: typing.Optional[str] = None
|
31
|
+
deliveryDate: typing.Optional[str] = None
|
32
|
+
receiverInfo: typing.Optional[ReceiverInfoType] = jstruct.JStruct[ReceiverInfoType]
|
33
|
+
|
34
|
+
|
35
|
+
@attr.s(auto_attribs=True)
|
36
|
+
class CodType:
|
37
|
+
amount: typing.Optional[int] = None
|
38
|
+
bank: typing.Optional[str] = None
|
39
|
+
accountNumber: typing.Optional[str] = None
|
40
|
+
|
41
|
+
|
42
|
+
@attr.s(auto_attribs=True)
|
43
|
+
class EnclosureEnclosureType:
|
44
|
+
description: typing.Optional[str] = None
|
45
|
+
hsCode: typing.Optional[str] = None
|
46
|
+
quantity: typing.Optional[int] = None
|
47
|
+
weight: typing.Optional[int] = None
|
48
|
+
amount: typing.Optional[int] = None
|
49
|
+
countryOfOrigin: typing.Optional[str] = None
|
50
|
+
|
51
|
+
|
52
|
+
@attr.s(auto_attribs=True)
|
53
|
+
class OrderInfoEnclosureType:
|
54
|
+
enclosures: typing.Optional[typing.List[EnclosureEnclosureType]] = jstruct.JList[EnclosureEnclosureType]
|
55
|
+
enclosureTypeId: typing.Optional[int] = None
|
56
|
+
|
57
|
+
|
58
|
+
@attr.s(auto_attribs=True)
|
59
|
+
class OrderInfoType:
|
60
|
+
valuedAmount: typing.Optional[int] = None
|
61
|
+
valuedAmountCurrency: typing.Optional[int] = None
|
62
|
+
enclosure: typing.Optional[typing.List[OrderInfoEnclosureType]] = jstruct.JList[OrderInfoEnclosureType]
|
63
|
+
cod: typing.Optional[CodType] = jstruct.JStruct[CodType]
|
64
|
+
|
65
|
+
|
66
|
+
@attr.s(auto_attribs=True)
|
67
|
+
class TariffRequestElementType:
|
68
|
+
customerId: typing.Optional[int] = None
|
69
|
+
serviceCategoryDirectionId: typing.Optional[int] = None
|
70
|
+
weight: typing.Optional[int] = None
|
71
|
+
totalPrice: typing.Optional[int] = None
|
72
|
+
currencyId: typing.Optional[int] = None
|
73
|
+
comment: typing.Optional[str] = None
|
74
|
+
returnRegisteredAddress: typing.Optional[bool] = None
|
75
|
+
partner: typing.Optional[int] = None
|
76
|
+
externalId: typing.Optional[str] = None
|
77
|
+
destinationAddress: typing.Optional[NAddressType] = jstruct.JStruct[NAddressType]
|
78
|
+
returnAddress: typing.Optional[NAddressType] = jstruct.JStruct[NAddressType]
|
79
|
+
orderInfo: typing.Optional[OrderInfoType] = jstruct.JStruct[OrderInfoType]
|
80
|
+
additionalServices: typing.Optional[typing.List[int]] = None
|
@@ -0,0 +1,86 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: karrio_hay_post
|
3
|
+
Version: 2025.5rc1
|
4
|
+
Summary: Karrio - HayPost Shipping Extension
|
5
|
+
Author-email: karrio <hello@karrio.io>
|
6
|
+
License-Expression: Apache-2.0
|
7
|
+
Project-URL: Homepage, https://github.com/karrioapi/karrio
|
8
|
+
Classifier: Intended Audience :: Developers
|
9
|
+
Classifier: Operating System :: OS Independent
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
11
|
+
Requires-Python: >=3.7
|
12
|
+
Description-Content-Type: text/markdown
|
13
|
+
Requires-Dist: karrio
|
14
|
+
|
15
|
+
# karrio.hay_post
|
16
|
+
|
17
|
+
This package is a HayPost extension of the [karrio](https://pypi.org/project/karrio) multi carrier shipping SDK.
|
18
|
+
|
19
|
+
## Requirements
|
20
|
+
|
21
|
+
`Python 3.7+`
|
22
|
+
|
23
|
+
## Installation
|
24
|
+
|
25
|
+
```bash
|
26
|
+
pip install karrio.hay_post
|
27
|
+
```
|
28
|
+
|
29
|
+
## Usage
|
30
|
+
|
31
|
+
```python
|
32
|
+
import karrio.sdk as karrio
|
33
|
+
from karrio.mappers.hay_post.settings import Settings
|
34
|
+
|
35
|
+
# Initialize a carrier gateway
|
36
|
+
hay_post = karrio.gateway["hay_post"].create(
|
37
|
+
Settings(
|
38
|
+
...
|
39
|
+
)
|
40
|
+
)
|
41
|
+
```
|
42
|
+
|
43
|
+
For test mode, you need to add your proxy or use a static IP address that HayPost has whitelisted.
|
44
|
+
Additionally, you need to connect with HayPost managers to obtain test and production
|
45
|
+
accounts. [Haypost ContactUs](https://www.haypost.am/en/contact-us)
|
46
|
+
|
47
|
+
Check the [Karrio Mutli-carrier SDK docs](https://docs.karrio.io) for Shipping API requests
|
48
|
+
|
49
|
+
## Additional information
|
50
|
+
|
51
|
+
### Services
|
52
|
+
|
53
|
+
* letter_ordered
|
54
|
+
* letter_simple
|
55
|
+
* letter_valued
|
56
|
+
* package_ordered
|
57
|
+
* package_simple
|
58
|
+
* package_valued
|
59
|
+
* parcel_simple
|
60
|
+
* parcel_valued
|
61
|
+
* postcard_ordered
|
62
|
+
* postcard_simple
|
63
|
+
* sekogram_simple
|
64
|
+
* sprint_simple
|
65
|
+
* yes_ordered_value
|
66
|
+
|
67
|
+
### Currencies
|
68
|
+
|
69
|
+
* RUB
|
70
|
+
* USD
|
71
|
+
* EUR
|
72
|
+
* AMD
|
73
|
+
|
74
|
+
### Additional Services as Option
|
75
|
+
|
76
|
+
* notification
|
77
|
+
* ordered_packaging
|
78
|
+
* pick_up
|
79
|
+
* postmen_delivery_value
|
80
|
+
* delivery
|
81
|
+
* international_notification
|
82
|
+
* domestic_sms
|
83
|
+
* international_sms
|
84
|
+
|
85
|
+
### Note
|
86
|
+
* To obtain rates, you first need to configure them in the Carrier Configurations section (Services and Options).
|
@@ -0,0 +1,27 @@
|
|
1
|
+
karrio/mappers/hay_post/__init__.py,sha256=1KDqsn4fjq_tSOtOpLMPRCY9ox0PmGKSPaET8HVebPs,153
|
2
|
+
karrio/mappers/hay_post/mapper.py,sha256=uj_CU-C4eq_zh17PnjhKeH3W0G5nUJagRovsKjn3sH4,1522
|
3
|
+
karrio/mappers/hay_post/proxy.py,sha256=1AT6Dgpz9Yc2Gns0ft4l_tA7z2OE3STLmRAmktDtSYw,2186
|
4
|
+
karrio/mappers/hay_post/settings.py,sha256=FOi3lE_7mZMmiid-xxhzM2RbLcQbSslEf8ZgIghoHz4,530
|
5
|
+
karrio/plugins/hay_post/__init__.py,sha256=QWyl2q-cdQkKMG-LRIZwvNR-_6hwlr_FH2Ku0nkzzFk,565
|
6
|
+
karrio/providers/hay_post/__init__.py,sha256=kgo_OSPJ2IZQ8-gv94VuUzCmOd-lg-2LInid3EaLxEY,335
|
7
|
+
karrio/providers/hay_post/error.py,sha256=WYD8M-o7jcsyXfpaNa0xO5k-UY0J8x7V7F_lVf3IeqM,845
|
8
|
+
karrio/providers/hay_post/rate.py,sha256=_H_WR2YMCRN9ENpSzxwv8VqYkdMYsD0L_YZ9_qFq8a0,3778
|
9
|
+
karrio/providers/hay_post/tracking.py,sha256=EwOTybLxitEfcdFq2Mus_fPMv3PyEQK_tITJNsS2Evs,2967
|
10
|
+
karrio/providers/hay_post/units.py,sha256=-EZFSjCQ-VeimynqzwSkc40v-XTbvHLrEIlccw_AY_4,4811
|
11
|
+
karrio/providers/hay_post/utils.py,sha256=7aukNJcwzvjx4027p7XMwBTdiGXeZOyuFkGpSqRBGIA,1733
|
12
|
+
karrio/providers/hay_post/shipment/__init__.py,sha256=Y7q1mUiD5sRy9tWuXpIGqPcDPMLodmOy4-QJ3xpAJCo,110
|
13
|
+
karrio/providers/hay_post/shipment/create.py,sha256=cfgG1t0yV1BH1QJN_xXHqlt5y_6vPgyBWPEjIbfcRTU,3625
|
14
|
+
karrio/schemas/hay_post/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
15
|
+
karrio/schemas/hay_post/auth_request.py,sha256=_GEoPHr590QEy3o4dOA3EhpRRumSLxuhyQn4WcHU2W8,307
|
16
|
+
karrio/schemas/hay_post/auth_response.py,sha256=vTpl-Lv4FGQTmL3e2G9JkoMoiUdmocMoF7H7bFm-9d0,270
|
17
|
+
karrio/schemas/hay_post/error.py,sha256=mSwJo38_ehtXr8Er7rGhbCP9k55wbCae4aEv4emApXA,162
|
18
|
+
karrio/schemas/hay_post/order_create_request.py,sha256=MfLYbWKxKTHalG5Tl_6jfGKOLRGenBXImuS3EFK6D7U,1285
|
19
|
+
karrio/schemas/hay_post/order_create_response.py,sha256=nhpjb5pbP8WBQ3z9w2y7fcfFeLlsC3y9uSLhU8v8KDg,306
|
20
|
+
karrio/schemas/hay_post/order_tracking_request.py,sha256=m8RBuPzaA7h7x_GQzFdY6kJOHq4awSXVT2GTyHMpyAA,150
|
21
|
+
karrio/schemas/hay_post/order_tracking_response.py,sha256=axk2Tny9yRfrSOF7_5FeuVzgLIDIcH69Fohjvxa8UoM,4043
|
22
|
+
karrio/schemas/hay_post/tariff_request.py,sha256=lct5WzV7wnFAcjw9Yuls9WDgvw0LQtJfb5OtjbyVa7g,2913
|
23
|
+
karrio_hay_post-2025.5rc1.dist-info/METADATA,sha256=8AsnrCRaOUJPSmAkzbn2F9B0vlcHfvYrChc8Goq06wk,1937
|
24
|
+
karrio_hay_post-2025.5rc1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
25
|
+
karrio_hay_post-2025.5rc1.dist-info/entry_points.txt,sha256=XF98wJWJnsSYHoobsm-_5qos_8oHR38gRV8PHtlXqog,61
|
26
|
+
karrio_hay_post-2025.5rc1.dist-info/top_level.txt,sha256=FZCY8Nwft8oEGHdl--xku8P3TrnOxu5dETEU_fWpRSM,20
|
27
|
+
karrio_hay_post-2025.5rc1.dist-info/RECORD,,
|