Implement basic shipping with XPS Ship API
This commit is contained in:
parent
520142fd62
commit
f65169ebbc
@ -5,8 +5,7 @@ from django.db.models import Q
|
||||
|
||||
from measurement.measures import Weight
|
||||
|
||||
from core.usps import USPSApi
|
||||
from core.exceptions import USPSPostageError, ShippingAddressError
|
||||
from core.xps import get_quote
|
||||
from core.models import (
|
||||
ShippingRate,
|
||||
SiteSettings,
|
||||
@ -43,42 +42,27 @@ def get_shipping_container_from_choices(choices):
|
||||
return SiteSettings.load().default_shipping_rate.container
|
||||
return choices[0].container
|
||||
|
||||
# - A 48 36
|
||||
# - B 80 48 60 72 64 80 96
|
||||
# - Small mailing box: 12 24 16 32
|
||||
# - Shoe box: 48 64
|
||||
# - Large flat rate box: 96 128
|
||||
|
||||
|
||||
|
||||
def get_shipping_cost(total_weight, postal_code):
|
||||
if not total_weight > Weight(lb=0):
|
||||
return Decimal('0.00')
|
||||
|
||||
container = get_shipping_container_from_choices(
|
||||
get_shipping_container_choices_from_weight(total_weight)
|
||||
)
|
||||
container = "box_a"
|
||||
if total_weight <= Weight(lb=3):
|
||||
container = "box_a"
|
||||
elif total_weight <= Weight(lb=6):
|
||||
container = "box_b"
|
||||
else:
|
||||
container = "large_flat_rate_box"
|
||||
|
||||
usps_rate_request = build_usps_rate_request(
|
||||
str(total_weight.lb), container, str(postal_code)
|
||||
)
|
||||
|
||||
usps = USPSApi(SiteSettings.load().usps_user_id)
|
||||
|
||||
try:
|
||||
validation = usps.get_rate(usps_rate_request)
|
||||
except ConnectionError as e:
|
||||
raise e(
|
||||
'Could not connect to USPS, try again.'
|
||||
)
|
||||
|
||||
logger.info(validation.result)
|
||||
try:
|
||||
postage = dict(
|
||||
validation.result['RateV4Response']['Package']['Postage']
|
||||
)
|
||||
except KeyError:
|
||||
raise USPSPostageError(
|
||||
'Could not retrieve postage.'
|
||||
)
|
||||
|
||||
if usps_rate_request['service'] == ShippingContainer.PRIORITY:
|
||||
shipping_cost = Decimal(postage['Rate'])
|
||||
elif usps_rate_request['service'] == ShippingContainer.PRIORITY_COMMERCIAL:
|
||||
shipping_cost = Decimal(postage['CommercialRate'])
|
||||
shipping_cost = get_quote(postal_code, total_weight, container)
|
||||
|
||||
return shipping_cost
|
||||
|
||||
|
||||
68
core/xps.py
68
core/xps.py
@ -10,12 +10,78 @@ customer_id = "12375190"
|
||||
headers = {'Authorization': 'RSIS ' + api_key, 'Content-Type': 'application/json'}
|
||||
base_url = "https://xpsshipper.com/restapi/v1/customers/" + customer_id
|
||||
|
||||
def get_container(weight, name):
|
||||
containers = {
|
||||
"box_a": {
|
||||
"type_code": "usps_custom_package",
|
||||
"dim_unit": "in",
|
||||
"pieces": {
|
||||
"weight": weight,
|
||||
"length": "10.125",
|
||||
"width": "7.125",
|
||||
"height": "5",
|
||||
"insuranceAmount": None,
|
||||
"declaredValue": None
|
||||
}
|
||||
},
|
||||
"box_b": {
|
||||
"type_code": "usps_custom_package",
|
||||
"dim_unit": "in",
|
||||
"pieces": {
|
||||
"weight": weight,
|
||||
"length": "13",
|
||||
"width": "11",
|
||||
"height": "6",
|
||||
"insuranceAmount": None,
|
||||
"declaredValue": None
|
||||
}
|
||||
},
|
||||
"large_flat_rate_box": {
|
||||
"type_code": "usps_large_flat_rate_box",
|
||||
"dim_unit": None,
|
||||
"pieces": {
|
||||
"weight": weight,
|
||||
"length": None,
|
||||
"width": None,
|
||||
"height": None,
|
||||
"insuranceAmount": None,
|
||||
"declaredValue": None
|
||||
}
|
||||
}
|
||||
}
|
||||
return containers[name]
|
||||
|
||||
def get_quote(weight):
|
||||
|
||||
def get_quote(destination_zip, weight, container):
|
||||
data = get_data(destination_zip, weight, container)
|
||||
resp = request("/quote", data)
|
||||
return resp["totalAmount"]
|
||||
|
||||
|
||||
def request(url, data):
|
||||
r = requests.post(base_url + url, headers=headers, data=json.dumps(data))
|
||||
return r.json()
|
||||
|
||||
def get_data(destination_zip, weight, container):
|
||||
container = get_container(weight, container)
|
||||
data = {
|
||||
"carrierCode": "usps",
|
||||
"serviceCode": "usps_priority",
|
||||
"packageTypeCode": container["type_code"],
|
||||
"signatureOptionCode": "NO_SIGNATURE_REQUIRED",
|
||||
"sender": {
|
||||
"country": "US",
|
||||
"zip": "98368"
|
||||
},
|
||||
"receiver": {
|
||||
"country": "US",
|
||||
"zip": destination_zip
|
||||
},
|
||||
"residential": True,
|
||||
"weightUnit": "lb",
|
||||
"dimUnit": container["dim_unit"],
|
||||
"currency": "USD",
|
||||
"customsCurrency": "USD",
|
||||
"pieces": [ container["pieces"] ]
|
||||
}
|
||||
return data
|
||||
|
||||
@ -14,8 +14,8 @@ from core.models import (
|
||||
ProductCategory, Product, ProductVariant, OrderLine, Coupon, ShippingRate,
|
||||
SiteSettings
|
||||
)
|
||||
from core.usps import USPSApi
|
||||
from core.exceptions import USPSPostageError, ShippingAddressError
|
||||
|
||||
from core.xps import get_data, get_quote
|
||||
from core import (
|
||||
DiscountValueType,
|
||||
VoucherType,
|
||||
@ -259,42 +259,20 @@ class Cart:
|
||||
return Decimal('0.00')
|
||||
|
||||
if len(self) > 0 and self.session.get('shipping_address'):
|
||||
usps_rate_request = build_usps_rate_request(
|
||||
str(self.total_weight.lb),
|
||||
container,
|
||||
str(self.session.get('shipping_address')['postal_code'])
|
||||
)
|
||||
postal_code = str(self.session.get('shipping_address')['postal_code'])
|
||||
|
||||
usps = USPSApi(self.site_settings.usps_user_id)
|
||||
container = "box_a"
|
||||
|
||||
try:
|
||||
validation = usps.get_rate(usps_rate_request)
|
||||
except ConnectionError as e:
|
||||
raise e(
|
||||
'Could not connect to USPS, try again.'
|
||||
)
|
||||
if self.total_weight <= Weight(lb=3):
|
||||
container = "box_a"
|
||||
elif self.total_weight <= Weight(lb=6):
|
||||
container = "box_b"
|
||||
else:
|
||||
container = "large_flat_rate_box"
|
||||
|
||||
logger.info(validation.result)
|
||||
try:
|
||||
postage = dict(
|
||||
validation.result['RateV4Response']['Package']['Postage']
|
||||
)
|
||||
except KeyError:
|
||||
logger.warning(validation.result)
|
||||
raise USPSPostageError(
|
||||
'Could not retrieve postage.'
|
||||
)
|
||||
shipping_price = get_quote(postal_code, str(self.total_weight.lb), container)
|
||||
|
||||
if usps_rate_request['service'] == ShippingContainer.PRIORITY:
|
||||
shipping_price = Decimal(postage['Rate'])
|
||||
elif usps_rate_request['service'] == ShippingContainer.PRIORITY_COMMERCIAL:
|
||||
shipping_price = Decimal(postage['CommercialRate'])
|
||||
|
||||
return shipping_price
|
||||
else:
|
||||
raise ShippingAddressError(
|
||||
'Could not retrieve shipping address.'
|
||||
)
|
||||
return Decimal(shipping_price)
|
||||
|
||||
def create_order(self):
|
||||
params = self.build_order_params()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user