102 lines
2.7 KiB
Python
102 lines
2.7 KiB
Python
import logging
|
|
from decimal import Decimal
|
|
from django.conf import settings
|
|
from django.db.models import Q
|
|
|
|
from measurement.measures import Weight
|
|
|
|
from core.usps import USPSApi
|
|
from core.exceptions import USPSPostageError, ShippingAddressError
|
|
from core.models import (
|
|
ShippingRate,
|
|
SiteSettings,
|
|
)
|
|
from core import (
|
|
ShippingService,
|
|
ShippingProvider,
|
|
ShippingContainer
|
|
)
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def get_shipping_container_choices_from_weight(weight):
|
|
is_selectable = Q(
|
|
is_selectable=True
|
|
)
|
|
min_weight_matched = Q(
|
|
min_order_weight__lte=weight) | Q(
|
|
min_order_weight__isnull=True
|
|
)
|
|
max_weight_matched = Q(
|
|
max_order_weight__gte=weight) | Q(
|
|
max_order_weight__isnull=True
|
|
)
|
|
containers = ShippingRate.objects.filter(
|
|
is_selectable & min_weight_matched & max_weight_matched
|
|
)
|
|
return containers
|
|
|
|
|
|
def get_shipping_container_from_choices(choices):
|
|
if len(choices) == 0:
|
|
return SiteSettings.load().default_shipping_rate.container
|
|
return choices[0].container
|
|
|
|
|
|
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)
|
|
)
|
|
|
|
usps_rate_request = build_usps_rate_request(
|
|
str(total_weight.lb), container, str(postal_code)
|
|
)
|
|
|
|
usps = USPSApi(SiteSettings.load().usps_user_id, test=settings.DEBUG)
|
|
|
|
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'])
|
|
|
|
return shipping_cost
|
|
|
|
|
|
def build_usps_rate_request(weight, container, zip_destination):
|
|
service = ShippingContainer.get_shipping_service_from_container(container)
|
|
return \
|
|
{
|
|
'service': service,
|
|
'zip_origination': SiteSettings.load().default_zip_origination,
|
|
'zip_destination': zip_destination,
|
|
'pounds': weight,
|
|
'ounces': '0',
|
|
'container': container,
|
|
'width': '',
|
|
'length': '',
|
|
'height': '',
|
|
'girth': '',
|
|
'machinable': 'TRUE'
|
|
}
|