diff --git a/delivery_ups_hibou/api/Error1.1.xsd b/delivery_ups_hibou/api/Error1.1.xsd new file mode 100644 index 00000000..c720608a --- /dev/null +++ b/delivery_ups_hibou/api/Error1.1.xsd @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/delivery_ups_hibou/api/IFWS.xsd b/delivery_ups_hibou/api/IFWS.xsd new file mode 100644 index 00000000..c36e5b33 --- /dev/null +++ b/delivery_ups_hibou/api/IFWS.xsd @@ -0,0 +1,318 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/delivery_ups_hibou/api/LBRecovery.xsd b/delivery_ups_hibou/api/LBRecovery.xsd new file mode 100644 index 00000000..05588c56 --- /dev/null +++ b/delivery_ups_hibou/api/LBRecovery.xsd @@ -0,0 +1,166 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/delivery_ups_hibou/api/LabelRecoveryWS.wsdl b/delivery_ups_hibou/api/LabelRecoveryWS.wsdl new file mode 100644 index 00000000..fe895eba --- /dev/null +++ b/delivery_ups_hibou/api/LabelRecoveryWS.wsdl @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/delivery_ups_hibou/api/RateWS.wsdl b/delivery_ups_hibou/api/RateWS.wsdl new file mode 100644 index 00000000..7aeb7555 --- /dev/null +++ b/delivery_ups_hibou/api/RateWS.wsdl @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/delivery_ups_hibou/api/RateWebServiceSchema.xsd b/delivery_ups_hibou/api/RateWebServiceSchema.xsd new file mode 100644 index 00000000..951ab3a1 --- /dev/null +++ b/delivery_ups_hibou/api/RateWebServiceSchema.xsd @@ -0,0 +1,644 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/delivery_ups_hibou/api/Ship.wsdl b/delivery_ups_hibou/api/Ship.wsdl new file mode 100644 index 00000000..2c0b081d --- /dev/null +++ b/delivery_ups_hibou/api/Ship.wsdl @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/delivery_ups_hibou/api/ShipWebServiceSchema.xsd b/delivery_ups_hibou/api/ShipWebServiceSchema.xsd new file mode 100644 index 00000000..cd1c1236 --- /dev/null +++ b/delivery_ups_hibou/api/ShipWebServiceSchema.xsd @@ -0,0 +1,933 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/delivery_ups_hibou/api/TNTWS.wsdl b/delivery_ups_hibou/api/TNTWS.wsdl new file mode 100644 index 00000000..5e69403f --- /dev/null +++ b/delivery_ups_hibou/api/TNTWS.wsdl @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/delivery_ups_hibou/api/TimeInTransitWebServiceSchema.xsd b/delivery_ups_hibou/api/TimeInTransitWebServiceSchema.xsd new file mode 100644 index 00000000..1c6928e0 --- /dev/null +++ b/delivery_ups_hibou/api/TimeInTransitWebServiceSchema.xsd @@ -0,0 +1,193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/delivery_ups_hibou/api/UPSSecurity.xsd b/delivery_ups_hibou/api/UPSSecurity.xsd new file mode 100644 index 00000000..63378ec4 --- /dev/null +++ b/delivery_ups_hibou/api/UPSSecurity.xsd @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/delivery_ups_hibou/api/Void.wsdl b/delivery_ups_hibou/api/Void.wsdl new file mode 100644 index 00000000..caee6a1e --- /dev/null +++ b/delivery_ups_hibou/api/Void.wsdl @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/delivery_ups_hibou/api/VoidWebServiceSchema.xsd b/delivery_ups_hibou/api/VoidWebServiceSchema.xsd new file mode 100644 index 00000000..7b69d7c0 --- /dev/null +++ b/delivery_ups_hibou/api/VoidWebServiceSchema.xsd @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/delivery_ups_hibou/api/common.xsd b/delivery_ups_hibou/api/common.xsd new file mode 100644 index 00000000..ddb84840 --- /dev/null +++ b/delivery_ups_hibou/api/common.xsd @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/delivery_ups_hibou/models/delivery_ups.py b/delivery_ups_hibou/models/delivery_ups.py index cd254e9c..c2e12a36 100644 --- a/delivery_ups_hibou/models/delivery_ups.py +++ b/delivery_ups_hibou/models/delivery_ups.py @@ -5,6 +5,9 @@ from odoo.exceptions import UserError, ValidationError from odoo.addons.delivery_ups.models.ups_request import UPSRequest, Package from odoo.tools import pdf +import logging +_logger = logging.getLogger(__name__) + class ProviderUPS(models.Model): _inherit = 'delivery.carrier' @@ -136,16 +139,27 @@ class ProviderUPS(models.Model): shipper_warehouse = superself.get_shipper_warehouse(picking=picking) recipient = superself.get_recipient(picking=picking) + picking_packages = picking.package_ids + package_carriers = picking_packages.mapped('carrier_id') + if package_carriers: + # only ship ours + picking_packages = picking_packages.filtered(lambda p: p.carrier_id == self and not p.carrier_tracking_ref) + + if not picking_packages: + continue + packages = [] package_names = [] - if picking.package_ids: + if picking_packages: # Create all packages - for package in picking.package_ids: + for package in picking_packages: packages.append(Package(self, package.shipping_weight, quant_pack=package.packaging_id, name=package.name)) package_names.append(package.name) + + # what is the point of weight_bulk? # Create one package with the rest (the content that is not in a package) - if picking.weight_bulk: - packages.append(Package(self, picking.weight_bulk)) + # if picking.weight_bulk: + # packages.append(Package(self, picking.weight_bulk)) invoice_line_total = 0 for move in picking.move_lines: @@ -179,7 +193,7 @@ class ProviderUPS(models.Model): if check_value: raise UserError(check_value) - package_type = picking.package_ids and picking.package_ids[0].packaging_id.shipper_package_code or self.ups_default_packaging_id.shipper_package_code + package_type = picking_packages and picking_packages[0].packaging_id.shipper_package_code or self.ups_default_packaging_id.shipper_package_code result = srm.send_shipping( shipment_info=shipment_info, packages=packages, shipper=shipper_company, ship_from=shipper_warehouse, ship_to=recipient, packaging_type=package_type, service_type=ups_service_type, label_file_type=self.ups_label_file_type, ups_carrier_account=ups_carrier_account, @@ -229,7 +243,6 @@ class ProviderUPS(models.Model): return rates def _ups_rate_shipment_multi_package(self, order=None, picking=None, package=None): - # TODO package here is ignored, it should not be (UPS is not multi-rating capable until we can get rates for a single package) superself = self.sudo() srm = UPSRequest(self.log_xml, superself.ups_username, superself.ups_passwd, superself.ups_shipper_number, superself.ups_access_number, self.prod_environment) ResCurrency = self.env['res.currency'] @@ -260,9 +273,13 @@ class ProviderUPS(models.Model): company = picking.company_id date_order = picking.sale_id.date_order or fields.Date.today() if picking.sale_id else fields.Date.today() # Is total quantity the number of packages or the number of items being shipped? - total_qty = len(picking.package_ids) - packages = [Package(self, package.shipping_weight) for package in picking.package_ids] - + if package: + total_qty = 1 + packages = [Package(self, package.shipping_weight)] + else: + # all packages.... + total_qty = len(picking.package_ids) + packages = [Package(self, package.shipping_weight) for package in picking.package_ids.filtered(lambda p: not p.carrier_id)] shipment_info = { 'total_qty': total_qty # required when service type = 'UPS Worldwide Express Freight' @@ -292,9 +309,8 @@ class ProviderUPS(models.Model): 'error_message': check_value, 'warning_message': False, }] - - #ups_service_type = order.ups_service_type or self.ups_default_service_type - ups_service_type = None # See if this gets us all service types + # We now use Shop if we send multi=True + ups_service_type = (order.ups_service_type or self.ups_default_service_type) if order else self.ups_default_service_type result = srm.get_shipping_price( shipment_info=shipment_info, packages=packages, shipper=shipper_company, ship_from=shipper_warehouse, ship_to=recipient, packaging_type=self.ups_default_packaging_id.shipper_package_code, service_type=ups_service_type, @@ -304,7 +320,14 @@ class ProviderUPS(models.Model): response = [] for rate in result: - if rate.get('error_message'): + if isinstance(rate, str): + # assume error + response.append({ + 'success': False, 'price': 0.0, + 'error_message': _('Error:\n%s') % rate, + 'warning_message': False, + }) + elif rate.get('error_message'): _logger.error('UPS error: %s' % rate['error_message']) response.append({ 'success': False, 'price': 0.0, @@ -328,6 +351,7 @@ class ProviderUPS(models.Model): if carrier: response.append({ 'carrier': carrier, + 'package': package or self.env['stock.quant.package'].browse(), 'success': True, 'price': price, 'error_message': False, diff --git a/delivery_ups_hibou/models/ups_request_patch.py b/delivery_ups_hibou/models/ups_request_patch.py index 475927cf..336f6a9f 100644 --- a/delivery_ups_hibou/models/ups_request_patch.py +++ b/delivery_ups_hibou/models/ups_request_patch.py @@ -1,17 +1,52 @@ # Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. +from os import path as os_path import suds from odoo.addons.delivery_ups.models.ups_request import UPSRequest SUDS_VERSION = suds.__version__ +import logging +_logger = logging.getLogger(__name__) + +# If you're getting SOAP/suds errors +# logging.getLogger('suds.client').setLevel(logging.DEBUG) + +TNT_CODE_MAP = { + 'GND': '03', + # TODO fill in the rest if needed.... +} + + +def patched__init__(self, debug_logger, username, password, shipper_number, access_number, prod_environment): + self.debug_logger = debug_logger + # Product and Testing url + self.endurl = "https://onlinetools.ups.com/webservices/" + if not prod_environment: + self.endurl = "https://wwwcie.ups.com/webservices/" + + # Basic detail require to authenticate + self.username = username + self.password = password + self.shipper_number = shipper_number + self.access_number = access_number + + self.rate_wsdl = '../api/RateWS.wsdl' + self.ship_wsdl = '../api/Ship.wsdl' + self.void_wsdl = '../api/Void.wsdl' + dirname = os_path.dirname(__file__) + self.tnt_wsdl = os_path.join(dirname, '../api/TNTWS.wsdl') + def patched_get_shipping_price(self, shipment_info, packages, shipper, ship_from, ship_to, packaging_type, service_type, - saturday_delivery, cod_info, date_planned=False): + saturday_delivery, cod_info, date_planned=False, multi=False): client = self._set_client(self.rate_wsdl, 'Rate', 'RateRequest') request = client.factory.create('ns0:RequestType') + request.RequestOption = 'Rate' + if multi: + request.RequestOption = 'Shop' classification = client.factory.create('ns2:CodeDescriptionType') classification.Code = '00' # Get rates for the shipper account @@ -83,18 +118,78 @@ def patched_get_shipping_price(self, shipment_info, packages, shipper, ship_from return self.get_error_message(response.Response.ResponseStatus.Code, response.Response.ResponseStatus.Description) - result = {} - result['currency_code'] = response.RatedShipment[0].TotalCharges.CurrencyCode + if multi: + result = [] + tnt_response = None + tnt_ready = False + for rated_shipment in response.RatedShipment: + res = {} + res['service_code'] = rated_shipment.Service.Code + res['currency_code'] = rated_shipment.TotalCharges.CurrencyCode + negotiated_rate = 'NegotiatedRateCharges' in rated_shipment and rated_shipment.NegotiatedRateCharges.TotalCharge.MonetaryValue or None - # Some users are qualified to receive negotiated rates - negotiated_rate = 'NegotiatedRateCharges' in response.RatedShipment[0] and response.RatedShipment[ - 0].NegotiatedRateCharges.TotalCharge.MonetaryValue or None + res['price'] = negotiated_rate or rated_shipment.TotalCharges.MonetaryValue + # Hibou Delivery + if hasattr(rated_shipment, 'GuaranteedDelivery') and hasattr(rated_shipment.GuaranteedDelivery, 'BusinessDaysInTransit'): + res['transit_days'] = int(rated_shipment.GuaranteedDelivery.BusinessDaysInTransit) - result['price'] = negotiated_rate or response.RatedShipment[0].TotalCharges.MonetaryValue + if not res.get('transit_days') and date_planned: + if not tnt_response: + try: + tnt_client = self._set_client(self.tnt_wsdl, 'TimeInTransit', 'TimeInTransitRequest') + tnt_request = tnt_client.factory.create('tnt:TimeInTransitRequest') + tnt_request.Request.RequestOption = 'TNT' + + tnt_request.ShipFrom.Address.City = ship_from.city or '' + tnt_request.ShipFrom.Address.CountryCode = ship_from.country_id.code or '' + tnt_request.ShipFrom.Address.PostalCode = ship_from.zip or '' + if ship_from.country_id.code in ('US', 'CA', 'IE'): + tnt_request.ShipFrom.Address.StateProvinceCode = ship_from.state_id.code or '' + + tnt_request.ShipTo.Address.City = ship_to.city or '' + tnt_request.ShipTo.Address.CountryCode = ship_to.country_id.code or '' + tnt_request.ShipTo.Address.PostalCode = ship_to.zip or '' + if ship_to.country_id.code in ('US', 'CA', 'IE'): + tnt_request.ShipTo.Address.StateProvinceCode = ship_to.state_id.code or '' + + tnt_request.Pickup.Date = date_planned.split(' ')[0].replace('-', '') + tnt_request.Pickup.Time = date_planned.split(' ')[1].replace(':', '') + + # tnt_request_transit_from = tnt_client.factory.create('ns1:TransitFrom') + tnt_response = tnt_client.service.ProcessTimeInTransit(Request=tnt_request.Request, + ShipFrom=tnt_request.ShipFrom, + ShipTo=tnt_request.ShipTo, + Pickup=tnt_request.Pickup) + tnt_ready = tnt_response.Response.ResponseStatus.Code == "1" + except Exception as e: + _logger.warning('exception during the UPS Time In Transit request. ' + str(e)) + tnt_ready = False + tnt_response = '-1' + if tnt_ready: + for service in tnt_response.TransitResponse.ServiceSummary: + if TNT_CODE_MAP.get(service.Service.Code) == service_type: + if hasattr(service, 'EstimatedArrival') and hasattr(service.EstimatedArrival, 'BusinessDaysInTransit'): + res['transit_days'] = int(service.EstimatedArrival.BusinessDaysInTransit) + break + # use TNT API to + result.append(res) + else: + result = {} + result['currency_code'] = response.RatedShipment[0].TotalCharges.CurrencyCode + + # Some users are qualified to receive negotiated rates + negotiated_rate = 'NegotiatedRateCharges' in response.RatedShipment[0] and response.RatedShipment[ + 0].NegotiatedRateCharges.TotalCharge.MonetaryValue or None + + result['price'] = negotiated_rate or response.RatedShipment[0].TotalCharges.MonetaryValue + # Hibou Delivery + if hasattr(response.RatedShipment[0], 'GuaranteedDelivery') and hasattr(response.RatedShipment[0].GuaranteedDelivery, 'BusinessDaysInTransit'): + result['transit_days'] = int(response.RatedShipment[0].GuaranteedDelivery.BusinessDaysInTransit) + + if not result.get('transit_days') and date_planned: + # use TNT API to + _logger.warning(' We would now use the TNT service. But who would show the transit days? 2') - # Hibou Delivery - if hasattr(response.RatedShipment[0], 'GuaranteedDelivery') and hasattr(response.RatedShipment[0].GuaranteedDelivery, 'BusinessDaysInTransit'): - result['transit_days'] = int(response.RatedShipment[0].GuaranteedDelivery.BusinessDaysInTransit) # End return result @@ -110,5 +205,5 @@ def patched_get_shipping_price(self, shipment_info, packages, shipper, ship_from except IOError as e: return self.get_error_message('0', 'UPS Server Not Found:\n%s' % e) - +UPSRequest.__init__ = patched__init__ UPSRequest.get_shipping_price = patched_get_shipping_price