mirror of
https://gitlab.com/hibou-io/hibou-odoo/suite.git
synced 2025-01-20 12:37:31 +02:00
[IMP] delivery_purolator: rework packaging, support packaging codes, tests
This commit is contained in:
@@ -2,9 +2,21 @@
|
|||||||
<odoo>
|
<odoo>
|
||||||
<data noupdate="1">
|
<data noupdate="1">
|
||||||
|
|
||||||
<record id="purolator_packaging_CustomerPackaging" model="stock.package.type">
|
<record id="purolator_packaging_default" model="stock.package.type">
|
||||||
<field name="name">Purolator Customer Packaging</field>
|
<field name="name">Purolator Default</field>
|
||||||
<field name="shipper_package_code">CustomerPackaging</field>
|
<field name="shipper_package_code" eval=""/>
|
||||||
|
<field name="package_carrier_type">purolator</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="purolator_packaging_large_package" model="stock.package.type">
|
||||||
|
<field name="name">Purolator LargePackage</field>
|
||||||
|
<field name="shipper_package_code">LargePackage</field>
|
||||||
|
<field name="package_carrier_type">purolator</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="purolator_packaging_flat_package" model="stock.package.type">
|
||||||
|
<field name="name">Purolator FlatPackage</field>
|
||||||
|
<field name="shipper_package_code">FlatPackage</field>
|
||||||
<field name="package_carrier_type">purolator</field>
|
<field name="package_carrier_type">purolator</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
<field name="delivery_type">purolator</field>
|
<field name="delivery_type">purolator</field>
|
||||||
<field name="purolator_service_type">PurolatorExpress</field>
|
<field name="purolator_service_type">PurolatorExpress</field>
|
||||||
<field name="prod_environment" eval="False"/>
|
<field name="prod_environment" eval="False"/>
|
||||||
<field name="purolator_default_package_type_id" ref="delivery_purolator.purolator_packaging_CustomerPackaging"/>
|
<field name="purolator_default_package_type_id" ref="delivery_purolator.purolator_packaging_default"/>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<record id="product_product_purolator_ground" model="product.product">
|
<record id="product_product_purolator_ground" model="product.product">
|
||||||
@@ -39,7 +39,7 @@
|
|||||||
<field name="delivery_type">purolator</field>
|
<field name="delivery_type">purolator</field>
|
||||||
<field name="purolator_service_type">PurolatorGround</field>
|
<field name="purolator_service_type">PurolatorGround</field>
|
||||||
<field name="prod_environment" eval="False"/>
|
<field name="prod_environment" eval="False"/>
|
||||||
<field name="purolator_default_package_type_id" ref="delivery_purolator.purolator_packaging_CustomerPackaging"/>
|
<field name="purolator_default_package_type_id" ref="delivery_purolator.purolator_packaging_default"/>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
</data>
|
</data>
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
from base64 import b64decode
|
||||||
from odoo import fields, models, _
|
from odoo import fields, models, _
|
||||||
from odoo.exceptions import UserError
|
from odoo.exceptions import UserError
|
||||||
from .purolator_services import PurolatorClient
|
from .purolator_services import PurolatorClient
|
||||||
@@ -253,7 +254,8 @@ class ProviderPurolator(models.Model):
|
|||||||
|
|
||||||
|
|
||||||
def _purolator_fill_address(self, addr, partner):
|
def _purolator_fill_address(self, addr, partner):
|
||||||
addr.Name = partner.name if not partner.is_company else ''
|
# known to not work without a name
|
||||||
|
addr.Name = partner.name
|
||||||
addr.Company = partner.name if partner.is_company else (partner.company_name or '')
|
addr.Company = partner.name if partner.is_company else (partner.company_name or '')
|
||||||
addr.Department = ''
|
addr.Department = ''
|
||||||
addr.StreetNumber, addr.StreetName, addr.StreetType = self._purolator_address_street(partner)
|
addr.StreetNumber, addr.StreetName, addr.StreetType = self._purolator_address_street(partner)
|
||||||
@@ -318,13 +320,13 @@ class ProviderPurolator(models.Model):
|
|||||||
p.carrier_tracking_ref = pin
|
p.carrier_tracking_ref = pin
|
||||||
doc_res = service.document_by_pin(pin, output_type=self.purolator_label_file_type)
|
doc_res = service.document_by_pin(pin, output_type=self.purolator_label_file_type)
|
||||||
for n, blob in enumerate(self._purolator_extract_doc_blobs(doc_res), 1):
|
for n, blob in enumerate(self._purolator_extract_doc_blobs(doc_res), 1):
|
||||||
document_blobs.append(('PuroPackage-%s-%s.%s' % (pin, n, self.purolator_label_file_type), blob))
|
document_blobs.append(('PuroPackage-%s-%s.%s' % (pin, n, self.purolator_label_file_type), b64decode(blob)))
|
||||||
else:
|
else:
|
||||||
# retrieve shipment_pin document(s)
|
# retrieve shipment_pin document(s)
|
||||||
doc_res = service.document_by_pin(shipment_pin, output_type=self.purolator_label_file_type)
|
doc_res = service.document_by_pin(shipment_pin, output_type=self.purolator_label_file_type)
|
||||||
# _logger.info('purolator service.document_by_pin for pin %s resulted in %s' % (shipment_pin, doc_res))
|
# _logger.info('purolator service.document_by_pin for pin %s resulted in %s' % (shipment_pin, doc_res))
|
||||||
for n, blob in enumerate(self._purolator_extract_doc_blobs(doc_res), 1):
|
for n, blob in enumerate(self._purolator_extract_doc_blobs(doc_res), 1):
|
||||||
document_blobs.append(('PuroShipment-%s-%s.%s' % (shipment_pin, n, self.purolator_label_file_type), blob))
|
document_blobs.append(('PuroShipment-%s-%s.%s' % (shipment_pin, n, self.purolator_label_file_type), b64decode(blob)))
|
||||||
|
|
||||||
if document_blobs:
|
if document_blobs:
|
||||||
logmessage = _("Shipment created in Purolator <br/> <b>Tracking Number/PIN : </b>%s") % (shipment_pin)
|
logmessage = _("Shipment created in Purolator <br/> <b>Tracking Number/PIN : </b>%s") % (shipment_pin)
|
||||||
|
|||||||
@@ -7,6 +7,15 @@ from zeep.transports import Transport
|
|||||||
from odoo.exceptions import UserError
|
from odoo.exceptions import UserError
|
||||||
|
|
||||||
|
|
||||||
|
PUROLATOR_PIECE_SPECIAL_HANDLING_TYPE = [
|
||||||
|
# 'AdditionalHandling', # unknown if this is "SpecialHandling"
|
||||||
|
'FlatPackage',
|
||||||
|
'LargePackage',
|
||||||
|
# 'Oversized', # unknown if this is "SpecialHandling"
|
||||||
|
# 'ResidentialAreaHeavyweight', # unknown if this is "SpecialHandling"
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class PurolatorClient(object):
|
class PurolatorClient(object):
|
||||||
|
|
||||||
# clients and factories
|
# clients and factories
|
||||||
@@ -151,9 +160,23 @@ class PurolatorClient(object):
|
|||||||
shipment.PaymentInformation = factory.PaymentInformation()
|
shipment.PaymentInformation = factory.PaymentInformation()
|
||||||
return shipment
|
return shipment
|
||||||
|
|
||||||
|
def _add_piece_code(self, factory, piece, code):
|
||||||
|
# note that we ONLY support special handling type
|
||||||
|
if not piece.Options:
|
||||||
|
piece.Options = factory.ArrayOfOptionIDValuePair()
|
||||||
|
piece.Options.OptionIDValuePair.append(factory.OptionIDValuePair(
|
||||||
|
ID='SpecialHandling',
|
||||||
|
Value='true',
|
||||||
|
))
|
||||||
|
piece.Options.OptionIDValuePair.append(factory.OptionIDValuePair(
|
||||||
|
ID='SpecialHandlingType',
|
||||||
|
Value=code,
|
||||||
|
))
|
||||||
|
|
||||||
def estimate_shipment_add_sale_order_packages(self, shipment, carrier, order):
|
def estimate_shipment_add_sale_order_packages(self, shipment, carrier, order):
|
||||||
# this could be a non-purolator package type as returned by the search functions
|
# this could be a non-purolator package type as returned by the search functions
|
||||||
package_type = carrier.get_package_type_for_order(order)
|
package_type = carrier.get_package_type_for_order(order)
|
||||||
|
package_type_codes = [t.strip() for t in (package_type.shipper_package_code or '').split(',') if t.strip() in PUROLATOR_PIECE_SPECIAL_HANDLING_TYPE]
|
||||||
shipment.PackageInformation.ServiceID = carrier.purolator_service_type
|
shipment.PackageInformation.ServiceID = carrier.purolator_service_type
|
||||||
weight = carrier.purolator_convert_weight(order._get_estimated_weight())
|
weight = carrier.purolator_convert_weight(order._get_estimated_weight())
|
||||||
package_type_max_weight = 0.0
|
package_type_max_weight = 0.0
|
||||||
@@ -190,6 +213,9 @@ class PurolatorClient(object):
|
|||||||
'DimensionUnit': 'in',
|
'DimensionUnit': 'in',
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
for package_code in package_type_codes:
|
||||||
|
self._add_piece_code(self.estimating_factory, p, package_code)
|
||||||
|
|
||||||
shipment.PackageInformation.PiecesInformation.Piece.append(p)
|
shipment.PackageInformation.PiecesInformation.Piece.append(p)
|
||||||
shipment.PackageInformation.TotalWeight.Value = str(weight)
|
shipment.PackageInformation.TotalWeight.Value = str(weight)
|
||||||
shipment.PackageInformation.TotalWeight.WeightUnit = 'lb'
|
shipment.PackageInformation.TotalWeight.WeightUnit = 'lb'
|
||||||
@@ -215,6 +241,7 @@ class PurolatorClient(object):
|
|||||||
package_weight = 1.0
|
package_weight = 1.0
|
||||||
total_weight_value += package_weight
|
total_weight_value += package_weight
|
||||||
package_type = carrier.purolator_default_package_type_id
|
package_type = carrier.purolator_default_package_type_id
|
||||||
|
package_type_codes = [t.strip() for t in (package_type.shipper_package_code or '').split(',') if t.strip() in PUROLATOR_PIECE_SPECIAL_HANDLING_TYPE]
|
||||||
p = factory.Piece(
|
p = factory.Piece(
|
||||||
Weight={
|
Weight={
|
||||||
'Value': str(package_weight),
|
'Value': str(package_weight),
|
||||||
@@ -233,6 +260,9 @@ class PurolatorClient(object):
|
|||||||
'DimensionUnit': 'in',
|
'DimensionUnit': 'in',
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
for package_code in package_type_codes:
|
||||||
|
self._add_piece_code(factory, p, package_code)
|
||||||
|
|
||||||
shipment.PackageInformation.PiecesInformation.Piece.append(p)
|
shipment.PackageInformation.PiecesInformation.Piece.append(p)
|
||||||
else:
|
else:
|
||||||
for package in packages:
|
for package in packages:
|
||||||
@@ -240,6 +270,11 @@ class PurolatorClient(object):
|
|||||||
if package_weight < 1.0:
|
if package_weight < 1.0:
|
||||||
package_weight = 1.0
|
package_weight = 1.0
|
||||||
package_type = package.package_type_id
|
package_type = package.package_type_id
|
||||||
|
package_type_code = package_type.shipper_package_code or ''
|
||||||
|
if package_type.package_carrier_type != 'purolator':
|
||||||
|
package_type_code = carrier.purolator_default_package_type_id.shipper_package_code or ''
|
||||||
|
package_type_codes = [t.strip() for t in package_type_code.split(',') if t.strip() in PUROLATOR_PIECE_SPECIAL_HANDLING_TYPE]
|
||||||
|
|
||||||
total_weight_value += package_weight
|
total_weight_value += package_weight
|
||||||
p = factory.Piece(
|
p = factory.Piece(
|
||||||
Weight={
|
Weight={
|
||||||
@@ -259,9 +294,9 @@ class PurolatorClient(object):
|
|||||||
'DimensionUnit': 'in',
|
'DimensionUnit': 'in',
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
# TODO p.Options.OptionIDValuePair (ID='SpecialHandling', Value='true')
|
for package_code in package_type_codes:
|
||||||
# can we do per-package signature requirements?
|
self._add_piece_code(factory, p, package_code)
|
||||||
# Packaging specific codes?
|
|
||||||
shipment.PackageInformation.PiecesInformation.Piece.append(p)
|
shipment.PackageInformation.PiecesInformation.Piece.append(p)
|
||||||
|
|
||||||
shipment.PackageInformation.TotalWeight.Value = str(total_weight_value)
|
shipment.PackageInformation.TotalWeight.Value = str(total_weight_value)
|
||||||
|
|||||||
@@ -54,6 +54,10 @@ class TestPurolator(TransactionCase):
|
|||||||
})],
|
})],
|
||||||
})
|
})
|
||||||
|
|
||||||
|
# reconfigure this method so that we can set its default package to one that needs a service code
|
||||||
|
self.delivery_carrier_ground = self.env.ref('delivery_purolator.purolator_ground')
|
||||||
|
self.delivery_carrier_ground.purolator_default_package_type_id = self.env.ref('delivery_purolator.purolator_packaging_large_package')
|
||||||
|
|
||||||
def _so_pick_shipping(self):
|
def _so_pick_shipping(self):
|
||||||
# Regular Update Shipping functionality
|
# Regular Update Shipping functionality
|
||||||
delivery_wizard = Form(self.env['choose.delivery.carrier'].with_context({
|
delivery_wizard = Form(self.env['choose.delivery.carrier'].with_context({
|
||||||
|
|||||||
Reference in New Issue
Block a user