[ADD] delivery_ups_oca_hibou: 3rd party billing, package declared value/signature requirement

This commit is contained in:
Jared Kipe
2022-09-06 22:10:48 +00:00
parent 3cc794c1fb
commit f52fcdd5ed
8 changed files with 258 additions and 1 deletions

View File

@@ -0,0 +1,3 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from . import models

View File

@@ -0,0 +1,19 @@
{
'name': 'Hibou UPS Shipping (OCA)',
'version': '15.0.1.0.0',
'category': 'Stock',
'author': "Hibou Corp.",
'license': 'OPL-1',
'website': 'https://hibou.io/',
'depends': [
'delivery_ups_oca',
'delivery_hibou',
],
'data': [
'views/stock_views.xml',
],
'demo': [
],
'installable': True,
'application': False,
}

View File

@@ -0,0 +1,5 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from . import delivery_carrier
from . import stock
from . import ups_request_patch

View File

@@ -0,0 +1,47 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from odoo import models
from odoo.exceptions import ValidationError
class DeliveryCarrier(models.Model):
_inherit = 'delivery.carrier'
def _get_ups_signature_required_type(self, order=None, picking=None, package=None):
# '3' for Adult Sig.
return '2'
def _get_ups_signature_required(self, order=None, picking=None, package=None):
if self.get_signature_required(order=order, picking=picking, package=package):
return self._get_ups_signature_required_type(order=order, picking=picking, package=package)
return False
def _get_main_ups_account_number(self, order=None, picking=None):
wh = None
if order:
wh = order.warehouse_id
if picking:
wh = picking.picking_type_id.warehouse_id
if wh and wh.ups_shipper_number:
return wh.ups_shipper_number
return self.ups_shipper_number
def _get_ups_account_number(self, order=None, picking=None):
"""
Common hook to customize what UPS Account number to use.
:return: UPS Account Number
"""
# Provided by Hibou Odoo Suite `delivery_hibou`
third_party_account = self.get_third_party_account(order=order, picking=picking)
if third_party_account:
if not third_party_account.delivery_type == 'ups':
raise ValidationError('Non-UPS Shipping Account indicated during UPS shipment.')
return third_party_account.name
if picking and picking.picking_type_id.warehouse_id.ups_shipper_number:
return picking.picking_type_id.warehouse_id.ups_shipper_number
return self.ups_shipper_number
def _get_ups_carrier_account(self, picking):
# 3rd party billing should return False if not used.
account = self._get_ups_account_number(picking=picking)
return account if account not in (self.ups_shipper_number, picking.picking_type_id.warehouse_id.ups_shipper_number) else False

View File

@@ -0,0 +1,9 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from odoo import fields, models
class StockWarehouse(models.Model):
_inherit = 'stock.warehouse'
ups_shipper_number = fields.Char(string='UPS Shipper Number')

View File

@@ -0,0 +1,159 @@
# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details.
from odoo.addons.delivery_ups_oca.models.ups_request import UpsRequest
import logging
_logger = logging.getLogger(__name__)
def _quant_package_data(self, package, picking):
# TODO do we want to call this without a package?
if not package and picking.package_ids:
package = picking.package_ids
currency = picking.sale_id.currency_id if picking.sale_id else picking.company_id.currency_id
insurance_currency_code = currency.name
res = []
NumOfPieces = picking.number_of_packages
PackageWeight = picking.shipping_weight
if package:
NumOfPieces = len(package)
# PackageWeight = sum(package.mapped('shipping_weight'))
for p in package:
package_data = {
"Description": p.name,
"NumOfPieces": str(NumOfPieces),
"Packaging": {
"Code": p.package_type_id.shipper_package_code,
"Description": p.name,
},
"Dimensions": {
"UnitOfMeasurement": {"Code": self.package_dimension_code},
"Length": str(p.package_type_id.packaging_length),
"Width": str(p.package_type_id.width),
"Height": str(p.package_type_id.height),
},
"PackageWeight": {
"UnitOfMeasurement": {"Code": self.package_weight_code},
"Weight": str(p.shipping_weight),
},
"PackageServiceOptions": "",
}
# Hibou Insurance & Signature Requirement
insurance_value = self.carrier.get_insurance_value(picking=picking, package=p)
if insurance_value:
if not package_data['PackageServiceOptions']:
package_data['PackageServiceOptions'] = {}
package_data['PackageServiceOptions']['DeclaredValue'] = {
'Type': {'Code': '01'},
'MonetaryValue': str(insurance_value),
'CurrencyCode': insurance_currency_code,
}
signature_required = self.carrier._get_ups_signature_required(picking=picking, package=p)
if signature_required:
if not package_data['PackageServiceOptions']:
package_data['PackageServiceOptions'] = {}
package_data['PackageServiceOptions']['DeliveryConfirmation'] = {
'DCISType': signature_required,
}
res.append(package_data)
return res
package_type = self.carrier.ups_default_package_type_id
return [{
"Description": picking.name,
"NumOfPieces": str(NumOfPieces),
"Packaging": {
"Code": package_type.shipper_package_code,
"Description": package_type.name,
},
"Dimensions": {
"UnitOfMeasurement": {"Code": self.package_dimension_code},
"Length": str(package_type.packaging_length),
"Width": str(package_type.width),
"Height": str(package_type.height),
},
"PackageWeight": {
"UnitOfMeasurement": {"Code": self.package_weight_code},
"Weight": str(PackageWeight),
},
# TODO add signature requirements...
"PackageServiceOptions": "",
}]
def _prepare_create_shipping(self, picking, package=None):
_logger.warning('_prepare_create_shipping(%s, %s)' % (picking, package))
"""Return a dict that can be passed to the shipping endpoint of the UPS API"""
# setup some request level account details
self.shipper_number = self.carrier._get_main_ups_account_number(picking=picking)
if not package:
package = picking.package_ids
packages = []
if package:
packages = self._quant_package_data(package, picking)
else:
_logger.warning(' NOT COMPLETE _prepare_create_shipping')
packages = []
package_info = self._quant_package_data_from_picking(
self.default_packaging_id, picking, False
)
package_weight = round(
(picking.shipping_weight / picking.number_of_packages), 2
)
for i in range(0, picking.number_of_packages):
package_item = package_info
package_name = "%s (%s)" % (picking.name, i + 1)
package_item["Description"] = package_name
package_item["NumOfPieces"] = "1"
package_item["Packaging"]["Description"] = package_name
package_item["PackageWeight"]["Weight"] = str(package_weight)
packages.append(package_item)
res = {
"ShipmentRequest": {
"Shipment": {
"Description": picking.name,
"Shipper": self._partner_to_shipping_data(
partner=picking.company_id.partner_id,
ShipperNumber=self.shipper_number,
),
"ShipTo": self._partner_to_shipping_data(picking.partner_id),
"ShipFrom": self._partner_to_shipping_data(
picking.picking_type_id.warehouse_id.partner_id
or picking.company_id.partner_id
),
"PaymentInformation": {
"ShipmentCharge": {
"Type": "01",
"BillShipper": {
"AccountNumber": self.shipper_number,
},
}
},
"Service": {"Code": self.service_code},
"Package": packages,
},
"LabelSpecification": self._label_data(),
}
}
ups_carrier_account = self.carrier._get_ups_carrier_account(picking)
if ups_carrier_account:
# del res['ShipmentRequest']['Shipment']['PaymentInformation']['ShipmentCharge']['BillShipper']
# res['ShipmentRequest']['Shipment']['PaymentInformation']['ShipmentCharge']['Type'] = '02'
res['ShipmentRequest']['Shipment']['PaymentInformation']['ShipmentCharge'] = {
'Type': '01',
'BillReceiver': {
'Address': self._partner_to_shipping_data(picking.partner_id),
'AccountNumber': ups_carrier_account,
}
}
# TODO do we need to change the BillReceiver.Address.PostalCode ?
_logger.warning(' ' + str(res))
return res
UpsRequest._prepare_create_shipping = _prepare_create_shipping
UpsRequest._quant_package_data = _quant_package_data

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record id="ups_view_warehouse" model="ir.ui.view">
<field name="name">stock.warehouse</field>
<field name="model">stock.warehouse</field>
<field name="inherit_id" ref="stock.view_warehouse" />
<field name="arch" type="xml">
<xpath expr="//field[@name='partner_id']" position="after">
<field name="ups_shipper_number"/>
</xpath>
</field>
</record>
</odoo>