Skip to content

Commit

Permalink
Merge pull request #87 from PurplShip/purplship-2020.12
Browse files Browse the repository at this point in the history
[release] Purplship SDK edition 2020.12
  • Loading branch information
danh91 authored Dec 16, 2020
2 parents 0858736 + 4f1d241 commit 8922c6d
Show file tree
Hide file tree
Showing 130 changed files with 968 additions and 799 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<p align="center">
<p align="center">
<a href="https://purplship.com" target="_blank">
<img src="https://github.com/PurplShip/purplship-server/raw/main/src/purpleserver/purpleserver/static/purpleserver/img/icon.png" alt="Purplship" height="200">
<img src="https://github.com/PurplShip/purplship-server/raw/main/src/purpleserver/purpleserver/static/purpleserver/img/icon.png" alt="Purplship" height="100">
</a>
</p>
<h2 align="center">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
PickupRequestRecipientAddress,
Recipient,
)
from purplship.core.utils import Serializable, concat_str, to_date
from purplship.core.utils import Serializable, SF, DF
from purplship.core.models import (
ShipmentDetails,
PickupRequest,
Expand All @@ -25,8 +25,8 @@ def parse_pickup_response(response: dict, settings: Settings) -> Tuple[PickupDet

def pickup_request(payload: PickupRequest, _) -> Serializable:
shipments: List[ShipmentDetails] = payload.options.get('shipments', [])
after = to_date(f"{payload.pickup_date} {payload.ready_time}", current_format="%Y-%m-%d %H:%M")
before = to_date(f"{payload.pickup_date} {payload.ready_time}", current_format="%Y-%m-%d %H:%M")
after = DF.date(f"{payload.pickup_date} {payload.ready_time}", current_format="%Y-%m-%d %H:%M")
before = DF.date(f"{payload.pickup_date} {payload.ready_time}", current_format="%Y-%m-%d %H:%M")

request = BoxKnightPickupRequest(
packageCount=len(payload.parcels),
Expand All @@ -37,7 +37,7 @@ def pickup_request(payload: PickupRequest, _) -> Serializable:
email=payload.address.email,
),
recipientAddress=PickupRequestRecipientAddress(
street=concat_str(payload.address.address_line1, payload.address.address_line2, join=True),
street=SF.concat_str(payload.address.address_line1, payload.address.address_line2, join=True),
city=payload.address.city,
province=payload.address.state_code,
country=payload.address.country_code,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
Address,
Recipient,
)
from purplship.core.utils import Serializable, concat_str
from purplship.core.utils import Serializable, SF
from purplship.core.models import (
ShipmentRequest,
ShipmentDetails,
Expand Down Expand Up @@ -35,15 +35,15 @@ def shipment_request(payload: ShipmentRequest, _) -> Serializable:
email=payload.recipient.email
),
recipientAddress=Address(
street=concat_str(payload.recipient.address_line1, payload.recipient.address_line2, join=True),
street=SF.concat_str(payload.recipient.address_line1, payload.recipient.address_line2, join=True),
city=payload.recipient.city,
province=payload.recipient.state_code,
country=payload.recipient.country_code,
postalCode=payload.recipient.postal_code,
unit=None
),
originAddress=Address(
street=concat_str(payload.shipper.address_line1, payload.shipper.address_line2, join=True),
street=SF.concat_str(payload.shipper.address_line1, payload.shipper.address_line2, join=True),
city=payload.shipper.city,
province=payload.shipper.state_code,
country=payload.shipper.country_code,
Expand Down
2 changes: 1 addition & 1 deletion extensions/boxknight/setup.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from setuptools import setup, find_namespace_packages

setup(name='purplship.boxknight',
version='2020.11-alpha',
version='2020.12-alpha',
description='Multi-carrier shipping API integration with python',
url='https://github.com/PurplShip/purplship',
author='Purplship Team',
Expand Down
65 changes: 43 additions & 22 deletions extensions/canadapost/purplship/mappers/canadapost/proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,10 @@
from purplship.core.utils.serializable import Serializable, Deserializable
from purplship.core.utils.pipeline import Pipeline, Job
from purplship.core.utils import (
to_xml,
request as http,
exec_parrallel,
bundle_xml,
XP,
)
from purplship.providers.canadapost import process_error
from purplship.mappers.canadapost.settings import Settings


Expand All @@ -30,7 +28,7 @@ def get_rates(self, request: Serializable[mailing_scenario]) -> Deserializable[s
},
method="POST",
)
return Deserializable(response, to_xml)
return Deserializable(response, XP.to_xml)

def get_tracking(self, request: Serializable[List[str]]) -> Deserializable[str]:
"""
Expand All @@ -50,7 +48,7 @@ def track(tracking_pin: str) -> str:

response: List[str] = exec_parrallel(track, request.serialize())

return Deserializable(bundle_xml(xml_strings=response), to_xml)
return Deserializable(XP.bundle_xml(xml_strings=response), XP.to_xml)

def create_shipment(self, request: Serializable[Pipeline]) -> Deserializable[str]:
def _contract_shipment(job: Job):
Expand Down Expand Up @@ -108,23 +106,46 @@ def process(job: Job):
pipeline: Pipeline = request.serialize()
response = pipeline.apply(process)

return Deserializable(bundle_xml(response), to_xml)
return Deserializable(XP.bundle_xml(response), XP.to_xml)

def cancel_shipment(self, request: Serializable) -> Deserializable:
shipment_id = request.serialize()
response = http(
url=f"{self.settings.server_url}/rs/{self.settings.customer_number}/{self.settings.customer_number}/shipment/{shipment_id}",
headers={
"Content-Type": "application/vnd.cpc.shipment-v8+xml",
"Accept": "application/vnd.cpc.shipment-v8+xml",
"Authorization": f"Basic {self.settings.authorization}",
"Accept-language": f"{self.settings.language}-CA",
},
method="DELETE",
on_error=process_error,
)

return Deserializable(response or "<wrapper></wrapper>", to_xml)
def _request(method: str, shipment_id: str, path: str = '', **kwargs):
return http(
url=f"{self.settings.server_url}/rs/{self.settings.customer_number}/{self.settings.customer_number}/shipment/{shipment_id}{path}",
headers={
"Content-Type": "application/vnd.cpc.shipment-v8+xml",
"Accept": "application/vnd.cpc.shipment-v8+xml",
"Authorization": f"Basic {self.settings.authorization}",
"Accept-language": f"{self.settings.language}-CA",
},
method=method,
**kwargs
)

def process(job: Job):
if job.data is None:
return job.fallback

subprocess = {
"info": lambda _: _request(
'GET', job.data.serialize()
),
"refund": lambda _: _request(
'POST', job.data['id'], '/refund', data=bytearray(job.data['payload'].serialize(), "utf-8")
),
"cancel": lambda _: _request(
'DELETE', job.data.serialize()
),
}
if job.id not in subprocess:
raise PurplShipError(f"Unknown shipment cancel request job id: {job.id}")

return subprocess[job.id](job)

pipeline: Pipeline = request.serialize()
response = pipeline.apply(process)
return Deserializable(XP.bundle_xml(response), XP.to_xml)

def schedule_pickup(self, request: Serializable[Pipeline]) -> Deserializable[str]:
def _availability(job: Job) -> str:
Expand Down Expand Up @@ -167,7 +188,7 @@ def process(job: Job):
pipeline: Pipeline = request.serialize()
response = pipeline.apply(process)

return Deserializable(bundle_xml(response), to_xml)
return Deserializable(XP.bundle_xml(response), XP.to_xml)

def modify_pickup(self, request: Serializable[dict]) -> Deserializable[str]:
def _get_pickup(job: Job) -> str:
Expand Down Expand Up @@ -210,7 +231,7 @@ def process(job: Job):
pipeline: Pipeline = request.serialize()
response = pipeline.apply(process)

return Deserializable(bundle_xml(response), to_xml)
return Deserializable(XP.bundle_xml(response), XP.to_xml)

def cancel_pickup(self, request: Serializable[str]) -> Deserializable[str]:
pickuprequest = request.serialize()
Expand All @@ -223,4 +244,4 @@ def cancel_pickup(self, request: Serializable[str]) -> Deserializable[str]:
},
method="DELETE",
)
return Deserializable(response or "<wrapper></wrapper>", to_xml)
return Deserializable(response or "<wrapper></wrapper>", XP.to_xml)
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,13 @@
)
from purplship.core.utils import (
Serializable,
export,
Element,
concat_str,
build,
format_date,
decimal,
Job,
Pipeline,
to_xml,
bundle_xml
SF,
DF,
NF,
XP,
)
from purplship.core.models import PickupRequest, PickupDetails, Message, ChargeDetails, PickupUpdateRequest
from purplship.core.units import Packages
Expand All @@ -51,18 +48,18 @@ def parse_pickup_response(

def _extract_pickup_details(response: Element, settings: Settings) -> PickupDetails:
header = next(
(build(PickupRequestHeaderType, elt) for elt in response.xpath(".//*[local-name() = $name]", name="pickup-request-header"))
(XP.build(PickupRequestHeaderType, elt) for elt in response.xpath(".//*[local-name() = $name]", name="pickup-request-header"))
)
price = next(
(build(PickupRequestPriceType, elt) for elt in response.xpath(".//*[local-name() = $name]", name="pickup-request-price")),
(XP.build(PickupRequestPriceType, elt) for elt in response.xpath(".//*[local-name() = $name]", name="pickup-request-price")),
None
)

price_amount = sum(
[
decimal(price.hst_amount or 0.0),
decimal(price.gst_amount or 0.0),
decimal(price.due_amount or 0.0),
NF.decimal(price.hst_amount or 0.0),
NF.decimal(price.gst_amount or 0.0),
NF.decimal(price.due_amount or 0.0),
],
0.0,
) if price is not None else None
Expand All @@ -71,9 +68,9 @@ def _extract_pickup_details(response: Element, settings: Settings) -> PickupDeta
carrier_id=settings.carrier_id,
carrier_name=settings.carrier_name,
confirmation_number=header.request_id,
pickup_date=format_date(header.next_pickup_date),
pickup_date=DF.fdate(header.next_pickup_date),
pickup_charge=ChargeDetails(
name="Pickup fees", amount=decimal(price_amount), currency="CAD"
name="Pickup fees", amount=NF.decimal(price_amount), currency="CAD"
) if price is not None else None,
)

Expand Down Expand Up @@ -109,7 +106,7 @@ def _create_pickup_request(payload: PickupRequest, settings: Settings, update: b
)
address = dict(
company=payload.address.company_name or "",
address_line_1=concat_str(
address_line_1=SF.concat_str(
payload.address.address_line1, payload.address.address_line2, join=True
),
city=payload.address.city,
Expand Down Expand Up @@ -170,21 +167,21 @@ def _get_pickup_availability(payload: PickupRequest):


def _create_pickup(availability_response: str, payload: PickupRequest, settings: Settings):
availability = build(pickup_availability, to_xml(availability_response))
availability = XP.build(pickup_availability, XP.to_xml(availability_response))
data = _create_pickup_request(payload, settings) if availability.on_demand_tour else None

return Job(id="create_pickup", data=data, fallback="" if data is None else "")


def _get_pickup(update_response: str, payload: PickupUpdateRequest, settings: Settings) -> Job:
errors = parse_error_response(to_xml(bundle_xml([update_response])), settings)
errors = parse_error_response(XP.to_xml(XP.bundle_xml([update_response])), settings)
data = None if any(errors) else f"/enab/{settings.customer_number}/pickuprequest/{payload.confirmation_number}/details"

return Job(id="get_pickup", data=Serializable(data), fallback="" if data is None else "")


def _request_serializer(request: PickupRequestDetails, update: bool = False) -> str:
return export(
return XP.export(
request,
name_=("pickup-request-update" if update else "pickup-request-details"),
namespacedef_='xmlns="http://www.canadapost.ca/ws/pickuprequest"',
Expand Down
24 changes: 12 additions & 12 deletions extensions/canadapost/purplship/providers/canadapost/rate.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from functools import reduce
from datetime import datetime
from typing import List, Tuple, cast
from purplship.core.utils import Serializable, export, Element, decimal, no_space
from purplship.core.utils import Serializable, Element, NF, XP
from purplship.providers.canadapost.utils import Settings
from purplship.core.units import Country, Currency, Packages, Services, Options
from purplship.core.errors import OriginNotServicedError
Expand All @@ -42,7 +42,7 @@ def _extract_quote(price_quote_node: Element, settings: Settings) -> RateDetails
ChargeDetails(
name=d.adjustment_name,
currency=currency,
amount=decimal(d.adjustment_cost or 0),
amount=NF.decimal(d.adjustment_cost or 0),
)
for d in price_quote.price_details.adjustments.adjustment
]
Expand All @@ -54,10 +54,10 @@ def _extract_quote(price_quote_node: Element, settings: Settings) -> RateDetails
service_standardType, price_quote.service_standard
).expected_transit_time,
service=ServiceType(price_quote.service_code).name,
base_charge=decimal(price_quote.price_details.base or 0),
total_charge=decimal(price_quote.price_details.due or 0),
discount=decimal(reduce(lambda total, d: total + d.amount, discounts, 0.0)),
duties_and_taxes=decimal(
base_charge=NF.decimal(price_quote.price_details.base or 0),
total_charge=NF.decimal(price_quote.price_details.due or 0),
discount=NF.decimal(reduce(lambda total, d: total + d.amount, discounts, 0.0)),
duties_and_taxes=NF.decimal(
float(price_quote.price_details.taxes.gst.valueOf_ or 0)
+ float(price_quote.price_details.taxes.pst.valueOf_ or 0)
+ float(price_quote.price_details.taxes.hst.valueOf_ or 0)
Expand All @@ -67,7 +67,7 @@ def _extract_quote(price_quote_node: Element, settings: Settings) -> RateDetails
lambda a: ChargeDetails(
name=a.adjustment_name,
currency=currency,
amount=decimal(a.adjustment_cost or 0),
amount=NF.decimal(a.adjustment_cost or 0),
),
price_quote.price_details.adjustments.adjustment,
)
Expand Down Expand Up @@ -124,20 +124,20 @@ def rate_request(
)
if any(requested_services) else None
),
origin_postal_code=no_space(payload.shipper.postal_code),
origin_postal_code=payload.shipper.postal_code,
destination=destinationType(
domestic=(
domesticType(postal_code=no_space(payload.recipient.postal_code))
domesticType(postal_code=payload.recipient.postal_code)
if (payload.recipient.country_code == Country.CA.name)
else None
),
united_states=(
united_statesType(zip_code=no_space(payload.recipient.postal_code))
united_statesType(zip_code=payload.recipient.postal_code)
if (payload.recipient.country_code == Country.US.name)
else None
),
international=(
internationalType(country_code=no_space(payload.recipient.postal_code))
internationalType(country_code=payload.recipient.postal_code)
if (
payload.recipient.country_code
not in [Country.US.name, Country.CA.name]
Expand All @@ -151,7 +151,7 @@ def rate_request(


def _request_serializer(request: mailing_scenario) -> str:
return export(
return XP.export(
request, namespacedef_='xmlns="http://www.canadapost.ca/ws/ship/rate-v4"'
)

Expand Down
Loading

0 comments on commit 8922c6d

Please sign in to comment.