1
0
forked from Mapan/odoo17e
odoo17e-kedaikipas58/addons/website_sale_fedex/models/fedex_locations_request.py
2024-12-10 09:04:09 +07:00

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))