From b63d2b043632fbd21656b7313a71eda0ec869b6f Mon Sep 17 00:00:00 2001 From: Cedric Collins Date: Wed, 31 Aug 2022 23:44:33 -0500 Subject: [PATCH] [IMP] delivery_purolator: add multi-rating for orders H10820 --- .../data/delivery_purolator_demo.xml | 31 +++++++-- .../models/delivery_purolator.py | 65 +++++++++++++++++++ .../models/purolator_services.py | 4 -- delivery_purolator/tests/test_purolator.py | 13 +++- 4 files changed, 102 insertions(+), 11 deletions(-) diff --git a/delivery_purolator/data/delivery_purolator_demo.xml b/delivery_purolator/data/delivery_purolator_demo.xml index 2b8cbcc2..a8746dc8 100644 --- a/delivery_purolator/data/delivery_purolator_demo.xml +++ b/delivery_purolator/data/delivery_purolator_demo.xml @@ -3,9 +3,10 @@ - - Purolator Delivery - Delivery_Puro + + + Purolator Express + Delivery_PurolatorExpress service @@ -13,10 +14,30 @@ 0.0 order - - Purolator Test Carrier + + Purolator Express Test purolator + PurolatorExpress + + + + + Purolator Ground + Delivery_PurolatorGround + service + + + + 0.0 + order + + + Purolator Ground Test + + purolator + PurolatorGround + diff --git a/delivery_purolator/models/delivery_purolator.py b/delivery_purolator/models/delivery_purolator.py index 00d18c03..a18c63f1 100644 --- a/delivery_purolator/models/delivery_purolator.py +++ b/delivery_purolator/models/delivery_purolator.py @@ -1,5 +1,7 @@ from odoo import fields, models, _ from .purolator_services import PurolatorClient +import logging +_logger = logging.getLogger(__name__) PUROLATOR_SERVICES = [ @@ -99,6 +101,7 @@ class ProviderPurolator(models.Model): self.prod_environment, ) res = client.get_quick_estimate(sender.zip, receiver_address, 'CustomerPackaging', weight) + _logger.warning('get_quick_estimate: %s', res) if res['error']: return { 'success': False, @@ -120,3 +123,65 @@ class ProviderPurolator(models.Model): 'error_message': False, 'warning_message': False, } + + def purolator_rate_shipment_multi(self, order=None, picking=None, packages=None): + sender = self.get_shipper_warehouse(order=order, picking=picking) + receiver = self.get_recipient(order=order, picking=picking) + receiver_address = { + 'City': receiver.city, + 'Province': receiver.state_id.code, + 'Country': receiver.country_id.code, + 'PostalCode': receiver.zip, + } + weight_uom_id = self.env['product.template']._get_weight_uom_id_from_ir_config_parameter() + + date_planned = fields.Datetime.now() + if self.env.context.get('date_planned'): + date_planned = self.env.context.get('date_planned') + + if order: + weight = weight_uom_id._compute_quantity(order._get_estimated_weight(), self.env.ref('uom.product_uom_lb'), round=False) + else: + raise NotImplementedError + client = PurolatorClient( + self.purolator_api_key, + self.purolator_password, + self.purolator_activation_key, + self.purolator_account_number, + self.prod_environment, + ) + res = client.get_quick_estimate(sender.zip, receiver_address, 'CustomerPackaging', weight) + if res['error']: + return [{'carrier': self, + 'success': False, + 'price': 0.0, + 'error_message': _('Error:\n%s') % res['error'], + 'warning_message': False, + }] + rates = [] + for shipment in res['shipments']: + carrier = self.purolator_find_delivery_carrier_for_service(shipment['ServiceID']) + if carrier: + price = shipment['TotalPrice'] + rates.append({ + 'carrier': carrier, + # 'package': package or self.env['stock.quant.package'].browse(), + 'success': True, + 'price': price, + 'error_message': False, + 'warning_message': _('TotalCharge not found.') if price == 0.0 else False, + 'date_planned': date_planned, + 'date_delivered': fields.Date.to_date(shipment['ExpectedDeliveryDate']), + 'transit_days': shipment['EstimatedTransitDays'], + 'service_code': shipment['ServiceID'], + }) + + return rates + + def purolator_find_delivery_carrier_for_service(self, service_code): + if self.purolator_service_type == service_code: + return self + carrier = self.search([('delivery_type', '=', 'purolator'), + ('purolator_service_type', '=', service_code) + ], limit=1) + return carrier diff --git a/delivery_purolator/models/purolator_services.py b/delivery_purolator/models/purolator_services.py index c82db5da..bc69c095 100644 --- a/delivery_purolator/models/purolator_services.py +++ b/delivery_purolator/models/purolator_services.py @@ -4,8 +4,6 @@ from zeep import Client from zeep.cache import SqliteCache from zeep.transports import Transport from odoo.exceptions import UserError -import logging -_logger = logging.getLogger(__name__) class PurolatorClient(object): @@ -33,7 +31,6 @@ class PurolatorClient(object): RequestReference='RatingExample', UserToken=self.activation_key, ) - # _logger.warning('*** header_value:\n%s' % header_value) client.set_default_soapheaders([header_value]) return client @@ -60,7 +57,6 @@ class PurolatorClient(object): 'WeightUnit': 'lb', }, ) - # _logger.warning('**** GetQuickEstimate response:\n%s', response) errors = response['body']['ResponseInformation']['Errors'] if errors: return { diff --git a/delivery_purolator/tests/test_purolator.py b/delivery_purolator/tests/test_purolator.py index 9e4e546e..2febb852 100644 --- a/delivery_purolator/tests/test_purolator.py +++ b/delivery_purolator/tests/test_purolator.py @@ -5,7 +5,7 @@ from odoo.tests.common import Form, TransactionCase class TestPurolator(TransactionCase): def setUp(self): super().setUp() - self.carrier = self.env.ref('delivery_purolator.purolator_carrier', raise_if_not_found=False) + self.carrier = self.env.ref('delivery_purolator.purolator_ground', raise_if_not_found=False) if not self.carrier or not self.carrier.purolator_api_key: self.skipTest('Purolator Shipping not configured, skipping tests.') if self.carrier.prod_environment: @@ -41,10 +41,19 @@ class TestPurolator(TransactionCase): }) def test_00_rate_order(self): + # Regular Update Shipping functionality delivery_wizard = Form(self.env['choose.delivery.carrier'].with_context({ 'default_order_id': self.sale_order.id, - 'default_carrier_id': self.ref('delivery_purolator.purolator_carrier'), + 'default_carrier_id': self.ref('delivery_purolator.purolator_ground'), })) choose_delivery_carrier = delivery_wizard.save() choose_delivery_carrier.update_price() self.assertGreater(choose_delivery_carrier.delivery_price, 0.0, "Purolator delivery cost for this SO has not been correctly estimated.") + + # Multi-rating with sale order + rates = self.carrier.rate_shipment_multi(order=self.sale_order) + carrier_express = self.env.ref('delivery_purolator.purolator_ground') + rate_express = list(filter(lambda r: r['carrier'] == carrier_express, rates)) + rate_express = rate_express and rate_express[0] + self.assertGreater(rate_express['price'], 0.0) + self.assertGreater(rate_express['transit_days'], 0)