feat: Update module to Odoo 19, adjust XPath selectors from tree to list in views and tests, and simplify readonly attribute logic.

This commit is contained in:
Suherdy Yacob 2026-01-20 15:32:26 +07:00
parent 64cac68586
commit 98ff30fff7
4 changed files with 15 additions and 17 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "Vendor Bill Editable Totals", "name": "Vendor Bill Editable Totals",
"version": "17.0.1.0.2", "version": "19.0.1.0.3",
"summary": "Enable direct editing of tax excluded and tax included amounts on vendor bill lines with automatic unit price recalculation", "summary": "Enable direct editing of tax excluded and tax included amounts on vendor bill lines with automatic unit price recalculation",
"description": """ "description": """
Vendor Bill Editable Totals Vendor Bill Editable Totals

View File

@ -80,7 +80,7 @@ def test_price_subtotal_field_editable():
# Find the xpath that modifies price_subtotal # Find the xpath that modifies price_subtotal
xpath_elements = root.xpath( xpath_elements = root.xpath(
"//xpath[@expr=\"//field[@name='invoice_line_ids']/tree//field[@name='price_subtotal']\"]" "//xpath[@expr=\"//field[@name='invoice_line_ids']/list//field[@name='price_subtotal']\"]"
) )
if not xpath_elements: if not xpath_elements:
@ -132,7 +132,7 @@ def test_price_total_field_editable():
# Find the xpath that modifies price_total # Find the xpath that modifies price_total
xpath_elements = root.xpath( xpath_elements = root.xpath(
"//xpath[@expr=\"//field[@name='invoice_line_ids']/tree//field[@name='price_total']\"]" "//xpath[@expr=\"//field[@name='invoice_line_ids']/list//field[@name='price_total']\"]"
) )
if not xpath_elements: if not xpath_elements:
@ -184,7 +184,7 @@ def test_fields_readonly_conditions():
# Check price_subtotal attrs # Check price_subtotal attrs
xpath_subtotal = root.xpath( xpath_subtotal = root.xpath(
"//xpath[@expr=\"//field[@name='invoice_line_ids']/tree//field[@name='price_subtotal']\"]" "//xpath[@expr=\"//field[@name='invoice_line_ids']/list//field[@name='price_subtotal']\"]"
) )
if not xpath_subtotal: if not xpath_subtotal:
@ -205,7 +205,7 @@ def test_fields_readonly_conditions():
# Check price_total attrs # Check price_total attrs
xpath_total = root.xpath( xpath_total = root.xpath(
"//xpath[@expr=\"//field[@name='invoice_line_ids']/tree//field[@name='price_total']\"]" "//xpath[@expr=\"//field[@name='invoice_line_ids']/list//field[@name='price_total']\"]"
) )
if not xpath_total: if not xpath_total:

View File

@ -50,7 +50,7 @@ class TestViewConfiguration(TransactionCase):
arch = etree.fromstring(self.view.arch) arch = etree.fromstring(self.view.arch)
# Find the xpath that modifies price_subtotal # Find the xpath that modifies price_subtotal
xpath_elements = arch.xpath("//xpath[@expr=\"//field[@name='invoice_line_ids']/tree//field[@name='price_subtotal']\"]") xpath_elements = arch.xpath("//xpath[@expr=\"//field[@name='invoice_line_ids']/list//field[@name='price_subtotal']\"]")
self.assertTrue( self.assertTrue(
len(xpath_elements) > 0, len(xpath_elements) > 0,
@ -80,7 +80,7 @@ class TestViewConfiguration(TransactionCase):
arch = etree.fromstring(self.view.arch) arch = etree.fromstring(self.view.arch)
# Find the xpath that modifies price_total # Find the xpath that modifies price_total
xpath_elements = arch.xpath("//xpath[@expr=\"//field[@name='invoice_line_ids']/tree//field[@name='price_total']\"]") xpath_elements = arch.xpath("//xpath[@expr=\"//field[@name='invoice_line_ids']/list//field[@name='price_total']\"]")
self.assertTrue( self.assertTrue(
len(xpath_elements) > 0, len(xpath_elements) > 0,
@ -110,7 +110,7 @@ class TestViewConfiguration(TransactionCase):
arch = etree.fromstring(self.view.arch) arch = etree.fromstring(self.view.arch)
# Check price_subtotal attrs # Check price_subtotal attrs
xpath_subtotal = arch.xpath("//xpath[@expr=\"//field[@name='invoice_line_ids']/tree//field[@name='price_subtotal']\"]") xpath_subtotal = arch.xpath("//xpath[@expr=\"//field[@name='invoice_line_ids']/list//field[@name='price_subtotal']\"]")
self.assertTrue(len(xpath_subtotal) > 0, "price_subtotal xpath should exist") self.assertTrue(len(xpath_subtotal) > 0, "price_subtotal xpath should exist")
attrs_subtotal = xpath_subtotal[0].xpath(".//attribute[@name='attrs']") attrs_subtotal = xpath_subtotal[0].xpath(".//attribute[@name='attrs']")
@ -133,7 +133,7 @@ class TestViewConfiguration(TransactionCase):
) )
# Check price_total attrs # Check price_total attrs
xpath_total = arch.xpath("//xpath[@expr=\"//field[@name='invoice_line_ids']/tree//field[@name='price_total']\"]") xpath_total = arch.xpath("//xpath[@expr=\"//field[@name='invoice_line_ids']/list//field[@name='price_total']\"]")
self.assertTrue(len(xpath_total) > 0, "price_total xpath should exist") self.assertTrue(len(xpath_total) > 0, "price_total xpath should exist")
attrs_total = xpath_total[0].xpath(".//attribute[@name='attrs']") attrs_total = xpath_total[0].xpath(".//attribute[@name='attrs']")
@ -251,7 +251,7 @@ class TestViewConfiguration(TransactionCase):
arch = etree.fromstring(self.view.arch) arch = etree.fromstring(self.view.arch)
# Verify both fields have attrs that reference parent.state # Verify both fields have attrs that reference parent.state
xpath_subtotal = arch.xpath("//xpath[@expr=\"//field[@name='invoice_line_ids']/tree//field[@name='price_subtotal']\"]") xpath_subtotal = arch.xpath("//xpath[@expr=\"//field[@name='invoice_line_ids']/list//field[@name='price_subtotal']\"]")
attrs_subtotal = xpath_subtotal[0].xpath(".//attribute[@name='attrs']") attrs_subtotal = xpath_subtotal[0].xpath(".//attribute[@name='attrs']")
attrs_text_subtotal = attrs_subtotal[0].text attrs_text_subtotal = attrs_subtotal[0].text
@ -262,7 +262,7 @@ class TestViewConfiguration(TransactionCase):
"Attrs should reference parent.state for price_subtotal" "Attrs should reference parent.state for price_subtotal"
) )
xpath_total = arch.xpath("//xpath[@expr=\"//field[@name='invoice_line_ids']/tree//field[@name='price_total']\"]") xpath_total = arch.xpath("//xpath[@expr=\"//field[@name='invoice_line_ids']/list//field[@name='price_total']\"]")
attrs_total = xpath_total[0].xpath(".//attribute[@name='attrs']") attrs_total = xpath_total[0].xpath(".//attribute[@name='attrs']")
attrs_text_total = attrs_total[0].text attrs_text_total = attrs_total[0].text

View File

@ -8,15 +8,13 @@
<field name="inherit_id" ref="account.view_move_form"/> <field name="inherit_id" ref="account.view_move_form"/>
<field name="arch" type="xml"> <field name="arch" type="xml">
<!-- Make price_subtotal editable in vendor bill invoice lines --> <!-- Make price_subtotal editable in vendor bill invoice lines -->
<xpath expr="//field[@name='invoice_line_ids']/tree//field[@name='price_subtotal']" position="attributes"> <xpath expr="//field[@name='invoice_line_ids']/list//field[@name='price_subtotal']" position="attributes">
<attribute name="readonly">0</attribute> <attribute name="readonly">parent.state != 'draft'</attribute>
<attribute name="attrs">{'readonly': [('parent.state', '!=', 'draft')]}</attribute>
</xpath> </xpath>
<!-- Make price_total editable in vendor bill invoice lines --> <!-- Make price_total editable in vendor bill invoice lines -->
<xpath expr="//field[@name='invoice_line_ids']/tree//field[@name='price_total']" position="attributes"> <xpath expr="//field[@name='invoice_line_ids']/list//field[@name='price_total']" position="attributes">
<attribute name="readonly">0</attribute> <attribute name="readonly">parent.state != 'draft'</attribute>
<attribute name="attrs">{'readonly': [('parent.state', '!=', 'draft')]}</attribute>
</xpath> </xpath>
</field> </field>
</record> </record>