From c8d5fac87c3492e9546b328b8d50896e569ce487 Mon Sep 17 00:00:00 2001 From: Jared Kipe Date: Mon, 4 Oct 2021 10:55:58 -0700 Subject: [PATCH] [IMP] delivery_stamps: multi-rating backports from 14.0 (note missing international) --- delivery_stamps/__manifest__.py | 4 +- delivery_stamps/models/delivery_stamps.py | 112 +++++++++++++++++- .../views/delivery_stamps_view.xml | 2 +- 3 files changed, 110 insertions(+), 8 deletions(-) diff --git a/delivery_stamps/__manifest__.py b/delivery_stamps/__manifest__.py index e980c556..75416e82 100644 --- a/delivery_stamps/__manifest__.py +++ b/delivery_stamps/__manifest__.py @@ -1,10 +1,10 @@ { 'name': 'Stamps.com (USPS) Shipping', 'summary': 'Send your shippings through Stamps.com and track them online.', - 'version': '11.0.1.0.0', + 'version': '11.0.2.0.0', 'author': "Hibou Corp.", 'category': 'Warehouse', - 'license': 'AGPL-3', + 'license': 'OPL-1', 'images': [], 'website': "https://hibou.io", 'description': """ diff --git a/delivery_stamps/models/delivery_stamps.py b/delivery_stamps/models/delivery_stamps.py index 3a420d16..177fa17c 100644 --- a/delivery_stamps/models/delivery_stamps.py +++ b/delivery_stamps/models/delivery_stamps.py @@ -114,7 +114,31 @@ class ProviderStamps(models.Model): ret_val.PackageType = self._stamps_package_type() ret_val.ServiceType = self.stamps_service_type ret_val.WeightLb = weight - ret_val.ContentType = 'Merchandise' + ret_val.ContentType = self._stamps_content_type() + return ret_val + + def _get_stamps_shipping_multi(self, service, date_planned, order=False, picking=False, package=False): + if order: + weight = sum([(line.product_id.weight * line.product_qty) for line in order.order_line]) or 0.0 + elif not package: + weight = picking.shipping_weight + else: + weight = package.shipping_weight or package.weight + weight = self._stamps_convert_weight(weight) + + shipper = self.get_shipper_warehouse(order=order, picking=picking) + recipient = self.get_recipient(order=order, picking=picking) + + if not all((shipper.zip, recipient.zip)): + raise ValidationError('Stamps needs ZIP. From: ' + str(shipper.zip) + ' To: ' + str(recipient.zip)) + + ret_val = service.create_shipping() + ret_val.ShipDate = date_planned.strftime('%Y-%m-%d') if date_planned else date.today().isoformat() + ret_val.From = self._stamps_address(service, shipper) + ret_val.To = self._stamps_address(service, recipient) + ret_val.PackageType = self._stamps_package_type(package=package) + ret_val.WeightLb = weight + ret_val.ContentType = self._stamps_content_type() return ret_val def _stamps_get_addresses_for_picking(self, picking): @@ -129,7 +153,13 @@ class ProviderStamps(models.Model): if not all((from_partner.zip, to_partner.zip)): raise ValidationError('Stamps needs ZIP. From: ' + str(from_partner.zip) + ' To: ' + str(to_partner.zip)) - for package in picking.package_ids: + 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) + + for package in picking_packages: weight = self._stamps_convert_weight(package.shipping_weight) l, w, h = self._stamps_package_dimensions(package=package) @@ -144,9 +174,9 @@ class ProviderStamps(models.Model): ret_val.Height = h ret_val.ServiceType = self.stamps_service_type ret_val.WeightLb = weight - ret_val.ContentType = 'Merchandise' - ret.append((package.name + ret_val.ShipDate + str(ret_val.WeightLb), ret_val)) - if not ret: + ret_val.ContentType = self._stamps_content_type(package=package) + ret.append((package.name + ret_val.ShipDate + str(ret_val.WeightLb) + self._stamps_hash_partner(to_partner), ret_val)) + if not ret and not package_carriers: weight = self._stamps_convert_weight(picking.shipping_weight) l, w, h = self._stamps_package_dimensions() @@ -232,6 +262,8 @@ class ProviderStamps(models.Model): package_labels = [] shippings = self._stamps_get_shippings_for_picking(service, picking) + if not shippings: + continue company, from_partner, to_partner = self._stamps_get_addresses_for_picking(picking) from_address = service.create_address() @@ -330,3 +362,73 @@ class ProviderStamps(models.Model): 'carrier_price': 0.0}) except WebFault as e: raise ValidationError(e) + + def stamps_rate_shipment_multi(self, order=None, picking=None, packages=None): + if not packages: + return self._stamps_rate_shipment_multi_package(order=order, picking=picking) + else: + rates = [] + for package in packages: + rates += self._stamps_rate_shipment_multi_package(order=order, picking=picking, package=package) + return rates + + def _stamps_rate_shipment_multi_package(self, order=None, picking=None, package=None): + self.ensure_one() + date_planned = fields.Datetime.now() + if self.env.context.get('date_planned'): + date_planned = self.env.context.get('date_planned') + res = [] + service = self._get_stamps_service() + shipping = self._get_stamps_shipping_multi(service, date_planned, order=order, picking=picking, package=package) + rates = service.get_rates(shipping) + for rate in rates: + price = float(rate.Amount) + if order: + currency = order.currency_id + else: + currency = picking.sale_id.currency_id if picking.sale_id else picking.company_id.currency_id + if currency.name != 'USD': + quote_currency = self.env['res.currency'].search([('name', '=', 'USD')], limit=1) + price = quote_currency.compute(rate.Amount, currency) + + delivery_days = rate.DeliverDays + if delivery_days.find('-') >= 0: + delivery_days = delivery_days.split('-') + transit_days = int(delivery_days[-1]) + else: + transit_days = int(delivery_days) + date_delivered = None + if transit_days > 0: + date_delivered = self.calculate_date_delivered(date_planned, transit_days) + service_code = rate.ServiceType + carrier = self.stamps_find_delivery_carrier_for_service(service_code) + if carrier: + res.append({ + 'carrier': carrier, + 'package': package or self.env['stock.quant.package'].browse(), + 'success': True, + 'price': price, + 'error_message': False, + 'warning_message': False, + 'transit_days': transit_days, + 'date_delivered': date_delivered, + 'date_planned': date_planned, + 'service_code': service_code, + }) + if not res: + res.append({ + 'success': False, + 'price': 0.0, + 'error_message': 'No valid rates returned from Stamps.com', + 'warning_message': False + }) + return res + + def stamps_find_delivery_carrier_for_service(self, service_code): + if self.stamps_service_type == service_code: + return self + # arbitrary decision, lets find the same user name + carrier = self.search([('stamps_username', '=', self.stamps_username), + ('stamps_service_type', '=', service_code) + ], limit=1) + return carrier diff --git a/delivery_stamps/views/delivery_stamps_view.xml b/delivery_stamps/views/delivery_stamps_view.xml index c4bb6fb0..a8a26dc1 100644 --- a/delivery_stamps/views/delivery_stamps_view.xml +++ b/delivery_stamps/views/delivery_stamps_view.xml @@ -30,7 +30,7 @@ product.packaging - +