chore: import enterprise addons 19.0 bulk snapshot

This commit is contained in:
1b-agent committed 2026-09-16 10:13:08 +00:00
commit ca4af030d3
39951 files changed
+15570005

No files matched your search

+5
View File
@@ -0,0 +1,5 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import delivery_fedex
from . import fedex_locations_request
@@ -0,0 +1,98 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import re
from odoo import fields, models
from .fedex_locations_request import FEDEXLocationsRequest
class DeliveryCarrier(models.Model):
_inherit = 'delivery.carrier'
fedex_use_locations = fields.Boolean(string='Use Fedex Locations', help='Allows the ecommerce user to choose a pick-up point as delivery address.')
fedex_locations_radius_value = fields.Integer(string='Fedex Locations Radius', help='Maximum locations distance radius.', default=15, required=True)
fedex_locations_radius_unit = fields.Many2one('uom.uom', compute='_compute_fedex_locations_radius_unit', search='_search_fedex_locations_radius_unit', store=True)
fedex_locations_radius_unit_name = fields.Char('Fedex Radius Unit Name', related='fedex_locations_radius_unit.display_name')
def _compute_fedex_locations_radius_unit(self):
for carrier in self:
carrier.fedex_locations_radius_unit = self._get_distance_uom_id_from_ir_config_parameter()
def _search_fedex_locations_radius_unit(self, operator, value):
return [('name', operator, value)]
def _get_distance_uom_id_from_ir_config_parameter(self):
distance_in_miles_param = self.env['ir.config_parameter'].sudo().get_param('product.volume_in_cubic_feet')
if distance_in_miles_param == '1':
return self.env.ref('uom.product_uom_mile')
return self.env.ref('uom.product_uom_km')
def _fedex_get_close_locations(self, partner_address):
superself = self.sudo()
srm = FEDEXLocationsRequest(self.log_xml, request_type="locs", prod_environment=self.prod_environment)
srm.web_authentication_detail(superself.fedex_developer_key, superself.fedex_developer_password)
srm.client_detail(superself.fedex_account_number, superself.fedex_meter_number)
srm.transaction_detail('Location Request zip_code=%s' % partner_address.zip)
srm.set_locs_details(self, partner_address)
locations = srm.process_locs()
close_locations = []
for location in locations:
address = location['LocationDetail']['LocationContactAndAddress']['Address']
contact = location['LocationDetail']['LocationContactAndAddress']['Contact']
name = contact['CompanyName'] if contact else location['LocationDetail']['LocationTypeForDisplay']
latitude, longitude = re.compile(r'([-+]\d+\.\d+)([-+]\d+\.\d+)').match(
address['GeographicCoordinates']
).groups()
close_locations.append(dict(
id=location['LocationDetail']['LocationId'],
name=name,
opening_hours=self._fedex_format_opening_hours(
location['LocationDetail']['HoursForEffectiveDate']
),
street=address['StreetLines'][0],
city=address['City'].title(),
zip_code=address['PostalCode'],
state=address['StateOrProvinceCode'],
country_code=address['CountryCode'],
additional_data=dict(
location_detail=location['LocationDetail'],
),
latitude=latitude,
longitude=longitude,
))
return close_locations
def _fedex_update_srm(self, srm, request_type, order=None, picking=None):
"""Add alternate delivery address to the shipment."""
res = super()._fedex_update_srm(srm, request_type, order, picking)
if picking:
order = picking.sale_id
if order and order.pickup_location_data:
pickup_location_data = order.pickup_location_data or {}
fedex_loc_details = pickup_location_data.get('additional_data', {}).get('location_detail', {})
hold_at_loc = srm.factory.HoldAtLocationDetail()
hold_at_loc.PhoneNumber = order.partner_shipping_id.phone
hold_at_loc.LocationContactAndAddress = fedex_loc_details.get('LocationContactAndAddress', {})
if 'AddressAncillaryDetail' in hold_at_loc.LocationContactAndAddress:
del hold_at_loc.LocationContactAndAddress['AddressAncillaryDetail']
hold_at_loc.LocationType = fedex_loc_details.get('LocationType')
hold_at_loc.LocationId = fedex_loc_details.get('LocationId')
srm.RequestedShipment.SpecialServicesRequested.HoldAtLocationDetail = hold_at_loc
return res
def _fedex_format_opening_hours(self, opening_hours):
formatted_opening_hours = dict()
for day, opening_hour in enumerate(opening_hours):
# An alternative could be the usage of:
# format_time(self.env,'2000-01-01 08:00:00', tz="UTC", time_format="short")
# but it adds AM or PM at the end of the time frame
formatted_opening_hours[day] = [
o['Begins'][:-3] + " - " + o['Ends'][:-3] for o in opening_hour['Hours']
]
return formatted_opening_hours
@@ -0,0 +1,106 @@
# -*- 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.tools 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.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 OSError:
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))