forked from Mapan/odoo17e
108 lines
4.7 KiB
Python
108 lines
4.7 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
|
|
import json
|
|
import logging
|
|
from odoo.tools.zeep import Client, Settings, helpers
|
|
from odoo.tools.zeep.exceptions import Fault
|
|
|
|
from odoo.exceptions import UserError
|
|
from odoo.addons.delivery_fedex.models.fedex_request import remove_accents, FedexRequest, LogPlugin, STATECODE_REQUIRED_COUNTRIES
|
|
from odoo.models import _
|
|
from odoo.tools.misc import file_path
|
|
|
|
|
|
class AllStringEncoder(json.JSONEncoder):
|
|
def default(self, obj):
|
|
if not isinstance(obj, dict) and not isinstance(obj, list):
|
|
return str(obj)
|
|
return json.JSONEncoder.default(self, obj)
|
|
|
|
|
|
class FEDEXLocationsRequest(FedexRequest):
|
|
def __init__(self, debug_logger, request_type="locs", prod_environment=False):
|
|
super(FEDEXLocationsRequest, self).__init__(debug_logger, request_type, prod_environment)
|
|
wsdl_folder = 'prod' if prod_environment else 'test'
|
|
wsdl_path = file_path(f'website_sale_fedex/api/{wsdl_folder}/LocationsService_v12.wsdl')
|
|
self._start_locs_transaction(wsdl_path)
|
|
|
|
def _start_locs_transaction(self, wsdl_path):
|
|
settings = Settings(strict=False)
|
|
self.client = Client('file:///%s' % wsdl_path.lstrip('/'), plugins=[LogPlugin(self.debug_logger)], settings=settings)
|
|
self.factory = self.client.type_factory('ns0')
|
|
self.VersionId = self.factory.VersionId()
|
|
self.VersionId.ServiceId = 'locs'
|
|
self.VersionId.Major = '12'
|
|
self.VersionId.Intermediate = '0'
|
|
self.VersionId.Minor = '0'
|
|
|
|
def set_locs_details(self, carrier, ship_to):
|
|
self.LocationsSearchCriterion = 'ADDRESS'
|
|
|
|
self.Address = self.factory.Address()
|
|
self.Address.StreetLines = [remove_accents(street) for street in [ship_to.street, ship_to.street2] if street]
|
|
self.Address.City = remove_accents(ship_to.city)
|
|
if ship_to.country_id.code in STATECODE_REQUIRED_COUNTRIES:
|
|
self.Address.StateOrProvinceCode = ship_to.state_id.code
|
|
else:
|
|
self.Address.StateOrProvinceCode = ''
|
|
self.Address.PostalCode = ship_to.zip
|
|
self.Address.CountryCode = ship_to.country_id.code
|
|
|
|
self.MultipleMatchesAction = 'RETURN_ALL'
|
|
|
|
self.SortDetail = self.factory.LocationSortDetail()
|
|
self.SortDetail.Criterion = 'DISTANCE'
|
|
self.SortDetail.Order = 'LOWEST_TO_HIGHEST'
|
|
|
|
self.Constraints = self.factory.SearchLocationConstraints()
|
|
self.Constraints.RadiusDistance = self.factory.Distance()
|
|
self.Constraints.RadiusDistance.Value = carrier.fedex_locations_radius_value
|
|
self.Constraints.RadiusDistance.Units = carrier.fedex_locations_radius_unit.name.upper()
|
|
|
|
def process_locs(self):
|
|
_logger = logging.getLogger(__name__)
|
|
try:
|
|
self.response = self.client.service.searchLocations(
|
|
WebAuthenticationDetail=self.WebAuthenticationDetail,
|
|
ClientDetail=self.ClientDetail,
|
|
TransactionDetail=self.TransactionDetail,
|
|
Version=self.VersionId,
|
|
LocationsSearchCriterion=self.LocationsSearchCriterion,
|
|
Address=self.Address,
|
|
MultipleMatchesAction=self.MultipleMatchesAction,
|
|
SortDetail=self.SortDetail,
|
|
Constraints=self.Constraints,
|
|
)
|
|
|
|
if self.response.HighestSeverity != 'ERROR' and self.response.HighestSeverity != 'FAILURE':
|
|
response = self.response['AddressToLocationRelationships'][0]['DistanceAndLocationDetails']
|
|
response = helpers.serialize_object(response, dict)
|
|
else:
|
|
raise UserError(
|
|
'\n'.join(
|
|
("%s: %s" % (n.Code, n.Message))
|
|
for n in self.response.Notifications
|
|
if (n.Severity == 'ERROR' or n.Severity == 'FAILURE')
|
|
)
|
|
)
|
|
if any([n.Severity == 'WARNING' for n in self.response.Notifications]):
|
|
_logger.warning(
|
|
'\n'.join(
|
|
("%s: %s" % (n.Code, n.Message))
|
|
for n in self.response.Notifications
|
|
if n.Severity == 'WARNING'
|
|
)
|
|
)
|
|
|
|
except Fault as fault:
|
|
raise UserError(_('There was an error retrieving Fedex localisations:\n%s', fault))
|
|
except IOError:
|
|
raise UserError(_('Fedex Server Not Found'))
|
|
except ValueError:
|
|
raise UserError(_('No Fedex pick-up points available for that shipping address'))
|
|
return self._sanitize_response(response)
|
|
|
|
def _sanitize_response(self, response):
|
|
return json.loads(json.dumps(response, cls=AllStringEncoder))
|