Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[16.0][IMP] despatch_advice_import_ubl : collect package (logistic transport units) #945

Merged
merged 2 commits into from
Jul 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions despatch_advice_import/wizard/despatch_advice_import.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,10 @@ def process_document(self):
)
self.process_data(parsed_order_document)

def _collect_lines_by_id(self, lines_doc):
def _collect_lines_by_id(self, lines_doc, key="order_line_id"):
lines_by_id = {}
for line in lines_doc:
line_id = int(line["order_line_id"])
line_id = int(line[key])
if line_id in lines_by_id:
lines_by_id[line_id]["qty"] += line["qty"]
lines_by_id[line_id]["backorder_qty"] += line["backorder_qty"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
<cbc:ID>0810805774</cbc:ID>
<cbc:ID>{picking_name}</cbc:ID>
<cbc:IssueDate>2020-11-16</cbc:IssueDate>
<cbc:DespatchAdviceTypeCode>scheduled</cbc:DespatchAdviceTypeCode>
<cac:OrderReference>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
>
<cbc:ID>0810805774</cbc:ID>
<cbc:ID>{picking_name}</cbc:ID>
<cbc:IssueDate>2020-11-16</cbc:IssueDate>
<cbc:DespatchAdviceTypeCode>scheduled</cbc:DespatchAdviceTypeCode>
<cac:OrderReference>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ def test_xml_convert_to_internal_data_01(self):
All the fields are filled into the internal data structure.
"""
xml_content = self.despatch_advice_xml1.decode("utf-8").format(
picking_name="0810805774",
order_id=self.purchase_order.name,
line_1_id=self.line1.id,
line_1_qty=self.line1.product_qty,
Expand All @@ -110,6 +111,7 @@ def test_xml_convert_to_internal_data_01(self):
"date": "2020-11-16",
"despatch_advice_type_code": "delivery",
"estimated_delivery_date": "2020-11-17",
"id": "0810805774",
"lines": [
{
"backorder_qty": 12.0,
Expand Down Expand Up @@ -149,6 +151,7 @@ def test_xml_convert_to_internal_data_02(self):
All the fields are filled into the internal data structure.
"""
xml_content = self.despatch_advice_xml2.decode("utf-8").format(
picking_name="0810805774",
line_1_id=self.line1.id,
line_1_order_id=self.purchase_order.name,
line_1_qty=self.line1.product_qty,
Expand All @@ -172,6 +175,7 @@ def test_xml_convert_to_internal_data_02(self):
"date": "2020-11-16",
"despatch_advice_type_code": "scheduled",
"estimated_delivery_date": "2020-11-17",
"id": "0810805774",
"lines": [
{
"backorder_qty": 12.0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -705,6 +705,7 @@ def test_despatch_advice_import(self):
self.assertTrue(po_moves)

xml_content2 = self.despatch_advice_xml2.decode("utf-8").format(
picking_name="0810805774",
order_id=self.purchase_order.name,
line_3_id=self.line3.id,
line_6_id=self.line6.id,
Expand Down
119 changes: 72 additions & 47 deletions despatch_advice_import_ubl/wizard/despatch_advice_import.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,100 +31,123 @@ def parse_ubl_despatch_advice(self, xml_root):
else:
main_xmlns = ns.pop("DespatchAdvice")
ns["main"] = main_xmlns
date_xpath = xml_root.xpath("/main:DespatchAdvice/cbc:IssueDate", namespaces=ns)
estimated_delivery_date_xpath = xml_root.xpath(
date_el = xml_root.xpath("/main:DespatchAdvice/cbc:IssueDate", namespaces=ns)
estimated_delivery_date_el = xml_root.xpath(
"/main:DespatchAdvice/cac:Shipment/cac:Delivery/"
"cac:EstimatedDeliveryPeriod/cbc:EndDate",
namespaces=ns,
)
order_reference_xpath = xml_root.xpath(
order_id_el = xml_root.xpath("/main:DespatchAdvice/cbc:ID", namespaces=ns)
order_reference_el = xml_root.xpath(
"/main:DespatchAdvice/cac:OrderReference/cbc:ID", namespaces=ns
)

despatch_advice_type_code_xpath = xml_root.xpath(
despatch_advice_type_code_el = xml_root.xpath(
"/main:DespatchAdvice/cbc:DespatchAdviceTypeCode", namespaces=ns
)

supplier_xpath = xml_root.xpath(
supplier_el = xml_root.xpath(
"/main:DespatchAdvice/cac:DespatchSupplierParty/cac:Party", namespaces=ns
)
# We only take the "official references" for supplier_dict
supplier_dict = self.ubl_parse_party(supplier_xpath[0], ns)
supplier_dict = self.ubl_parse_party(supplier_el[0], ns)
supplier_dict = {
"vat": supplier_dict.get("vat"),
}
customer_xpath = xml_root.xpath(
customer_el = xml_root.xpath(
"/main:DespatchAdvice/cac:DeliveryCustomerParty/cac:Party", namespaces=ns
)
customer_dict = self.ubl_parse_party(customer_xpath[0], ns)
customer_dict = self.ubl_parse_party(customer_el[0], ns)

customer_dict = {"vat": customer_dict.get("vat")}
lines_xpath = xml_root.xpath(
lines_el = xml_root.xpath(
"/main:DespatchAdvice/cac:DespatchLine", namespaces=ns
)
res_lines = []
for line in lines_xpath:
for line in lines_el:
res_lines.append(self.parse_ubl_despatch_advice_line(line, ns))
res = {
"ref": order_reference_xpath[0].text if order_reference_xpath else "",
"id": order_id_el[0].text if order_id_el else "",
"ref": order_reference_el[0].text if order_reference_el else "",
"supplier": supplier_dict,
"company": customer_dict,
"despatch_advice_type_code": despatch_advice_type_code_xpath[0].text
if len(despatch_advice_type_code_xpath) > 0
else "",
"date": len(date_xpath) and date_xpath[0].text,
"estimated_delivery_date": len(estimated_delivery_date_xpath)
and estimated_delivery_date_xpath[0].text,
"despatch_advice_type_code": (
despatch_advice_type_code_el[0].text
if len(despatch_advice_type_code_el) > 0
else ""
),
"date": len(date_el) and date_el[0].text,
"estimated_delivery_date": len(estimated_delivery_date_el)
and estimated_delivery_date_el[0].text,
"lines": res_lines,
}
return res

@api.model
def parse_ubl_despatch_advice_line(self, line, ns):
line_id_xpath = line.xpath("cbc:ID", namespaces=ns)
qty_xpath = line.xpath("cbc:DeliveredQuantity", namespaces=ns)
qty = float(qty_xpath[0].text)
backorder_qty_xpath = line.xpath("cbc:OutstandingQuantity", namespaces=ns)
line_id_el = line.xpath("cbc:ID", namespaces=ns)
qty_el = line.xpath("cbc:DeliveredQuantity", namespaces=ns)
qty = float(qty_el[0].text)
backorder_qty_el = line.xpath("cbc:OutstandingQuantity", namespaces=ns)
backorder_qty = None
if backorder_qty_xpath and len(backorder_qty_xpath):
backorder_qty = float(backorder_qty_xpath[0].text)
if backorder_qty_el and len(backorder_qty_el):
backorder_qty = float(backorder_qty_el[0].text)
else:
backorder_qty = 0

product_ref_xpath = line.xpath(
product_ref_el = line.xpath(
"cac:Item/cac:SellersItemIdentification/cbc:ID", namespaces=ns
)

if len(product_ref_xpath) == 0:
product_ref_xpath = line.xpath(
if len(product_ref_el) == 0:
product_ref_el = line.xpath(
"cac:Item/cac:BuyersItemIdentification/cbc:ID", namespaces=ns
)

product_lot_xpath = line.xpath(
product_lot_el = line.xpath(
"cac:Item/cac:ItemInstance/cac:LotIdentification/cbc:LotNumberID",
namespaces=ns,
)
order_reference_xpath = line.xpath(
order_reference_el = line.xpath(
"cac:OrderLineReference/cac:OrderReference/cbc:ID", namespaces=ns
)

order_line_id_xpath = line.xpath(
order_line_id_el = line.xpath(
"cac:OrderLineReference/cbc:LineID", namespaces=ns
)

if not order_line_id_xpath:
if not order_line_id_el:
raise UserError(_("Missing line ID in the Despatch Advice."))

res_line = {
"line_id": line_id_xpath[0].text,
"order_line_id": order_line_id_xpath[0].text,
"ref": order_reference_xpath[0].text if order_reference_xpath else "",
"line_id": line_id_el[0].text,
"order_line_id": order_line_id_el[0].text,
"ref": order_reference_el[0].text if order_reference_el else "",
"qty": qty,
"product_ref": product_ref_xpath[0].text,
"product_lot": product_lot_xpath[0].text if product_lot_xpath else "",
"uom": {"unece_code": qty_xpath[0].attrib.get("unitCode")},
"product_ref": product_ref_el[0].text,
"product_lot": product_lot_el[0].text if product_lot_el else "",
"uom": {"unece_code": qty_el[0].attrib.get("unitCode")},
"backorder_qty": backorder_qty,
}

package_id_el = line.xpath(
"cac:Shipment/cac:TransportHandlingUnit/cac:ActualPackage/cbc:ID",
namespaces=ns,
)
package_type_el = line.xpath(
"cac:Shipment/cac:TransportHandlingUnit/cbc:TransportHandlingUnitTypeCode",
namespaces=ns,
)
package_weight_el = line.xpath(
"cac:Shipment/cac:GrossWeightMeasure/cbc:Measure", namespaces=ns
)
if package_id_el or package_type_el:
res_line["package"] = {
"name": package_id_el[0].text if package_id_el else "",
"type": package_type_el[0].text if package_type_el else "",
"weight": package_weight_el[0].text if package_weight_el else "",
}

defaults = self.env.context.get("despatch_advice_import__default_vals", {}).get(
"lines", {}
)
Expand All @@ -133,21 +156,23 @@ def parse_ubl_despatch_advice_line(self, line, ns):

@api.model
def ubl_parse_party(self, party_node, ns):
partner_name_xpath = party_node.xpath("cac:PartyName/cbc:Name", namespaces=ns)
if not partner_name_xpath:
partner_name_xpath = party_node.xpath(
partner_name_el = party_node.xpath("cac:PartyName/cbc:Name", namespaces=ns)
if not partner_name_el:
partner_name_el = party_node.xpath(
"cac:PartyLegalEntity/cbc:RegistrationName", namespaces=ns
)

vat_xpath = party_node.xpath("cac:PartyIdentification/cbc:ID", namespaces=ns)
vat_el = party_node.xpath("cac:PartyIdentification/cbc:ID", namespaces=ns)
partner_dict = {
"vat": vat_xpath[0].text
if vat_xpath and vat_xpath[0].attrib.get("schemeName").upper()
else False,
"name": partner_name_xpath[0].text,
"vat": (
vat_el[0].text
if vat_el and vat_el[0].attrib.get("schemeName").upper()
else False
),
"name": partner_name_el[0].text,
}
address_xpath = party_node.xpath("cac:PostalAddress", namespaces=ns)
if address_xpath:
address_dict = self.ubl_parse_address(address_xpath[0], ns)
address_el = party_node.xpath("cac:PostalAddress", namespaces=ns)
if address_el:
address_dict = self.ubl_parse_address(address_el[0], ns)
partner_dict.update(address_dict)
return partner_dict
Loading