details: https://code.tryton.org/tryton/commit/3dcd79aff559
branch: default
user: Cédric Krier <[email protected]>
date: Sat Mar 28 17:54:47 2026 +0100
description:
Add ethanol volume to price list formula
diffstat:
modules/stock_ethanol/doc/design.rst | 13 +++
modules/stock_ethanol/product.py | 55 ++++++++++++-
modules/stock_ethanol/product.xml | 7 +
modules/stock_ethanol/tests/test_module.py | 40 +++++++++-
modules/stock_ethanol/tryton.cfg | 6 +
modules/stock_ethanol/view/product_price_list_line_form.xml | 10 ++
6 files changed, 129 insertions(+), 2 deletions(-)
diffs (205 lines):
diff -r 78badbeff5b4 -r 3dcd79aff559 modules/stock_ethanol/doc/design.rst
--- a/modules/stock_ethanol/doc/design.rst Sat Mar 28 17:50:12 2026 +0100
+++ b/modules/stock_ethanol/doc/design.rst Sat Mar 28 17:54:47 2026 +0100
@@ -30,3 +30,16 @@
The `Product <product:concept-product>` concept is introduced by the
:doc:`Product Module <product:index>`.
+
+.. _model-product.price_list:
+
+Price List
+==========
+
+When the *Stock Ethanol Module* is activated, a new parameter based on the
+volume of ethanol is added to the *Price List* formula.
+
+.. seealso::
+
+ The Price List concept is introduced by the :doc:`Product Price List Module
+ <product_price_list:index>`.
diff -r 78badbeff5b4 -r 3dcd79aff559 modules/stock_ethanol/product.py
--- a/modules/stock_ethanol/product.py Sat Mar 28 17:50:12 2026 +0100
+++ b/modules/stock_ethanol/product.py Sat Mar 28 17:54:47 2026 +0100
@@ -1,11 +1,13 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
+from decimal import Decimal
+
from sql.conditionals import Coalesce
from trytond.model import fields
from trytond.pool import Pool, PoolMeta
-from trytond.pyson import Eval, If
+from trytond.pyson import Eval, Id, If
class Template(metaclass=PoolMeta):
@@ -173,3 +175,54 @@
volume = quantity * self.volume * ethanol_by_volume
unit = self.volume_uom
return UoM.compute_qty(unit, volume, unit_volume, round=round)
+
+
+class PriceList(metaclass=PoolMeta):
+ __name__ = 'product.price_list'
+
+ def get_context_formula(self, product, quantity, uom, pattern=None):
+ pool = Pool()
+ UoM = pool.get('product.uom')
+ ModelData = pool.get('ir.model.data')
+
+ liter = UoM(ModelData.get_id('product', 'uom_liter'))
+
+ context = super().get_context_formula(
+ product, quantity, uom, pattern=pattern)
+ ethanol_volume = None
+ if product:
+ ethanol_volume = product.compute_ethanol_volume(
+ 1, product.default_uom, liter, round=False)
+ if ethanol_volume is None:
+ ethanol_volume = 0
+ context['names']['ethanol_volume'] = Decimal(str(ethanol_volume))
+ return context
+
+
+class PriceListLine(metaclass=PoolMeta):
+ __name__ = 'product.price_list.line'
+
+ ethanol_volume_uom = fields.Many2One(
+ 'product.uom', "AlcoholVolume UoM",
+ domain=[('category', '=', Id('product', 'uom_cat_volume'))],
+ help="Leave empty for liter.")
+
+ @classmethod
+ def __setup__(cls):
+ super().__setup__()
+ cls.formula.help += ("\n"
+ "-ethanol_volume: the volume of alcohol in 1 unit of product")
+
+ def get_unit_price(self, **context):
+ pool = Pool()
+ UoM = pool.get('product.uom')
+ ModelData = pool.get('ir.model.data')
+
+ if self.ethanol_volume_uom:
+ context['names'] = context['names'].copy()
+ liter = UoM(ModelData.get_id('product', 'uom_liter'))
+ ethanol_volume = UoM.compute_qty(
+ liter, float(context['names']['ethanol_volume']),
+ self.ethanol_volume_uom, round=False)
+ context['names']['ethanol_volume'] = Decimal(str(ethanol_volume))
+ return super().get_unit_price(**context)
diff -r 78badbeff5b4 -r 3dcd79aff559 modules/stock_ethanol/product.xml
--- a/modules/stock_ethanol/product.xml Sat Mar 28 17:50:12 2026 +0100
+++ b/modules/stock_ethanol/product.xml Sat Mar 28 17:54:47 2026 +0100
@@ -21,4 +21,11 @@
<field name="name">product_product_list</field>
</record>
</data>
+ <data depends="product_price_list">
+ <record model="ir.ui.view" id="product_price_list_line_view_form">
+ <field name="model">product.price_list.line</field>
+ <field name="inherit"
ref="product_price_list.price_list_line_view_form"/>
+ <field name="name">product_price_list_line_form</field>
+ </record>
+ </data>
</tryton>
diff -r 78badbeff5b4 -r 3dcd79aff559 modules/stock_ethanol/tests/test_module.py
--- a/modules/stock_ethanol/tests/test_module.py Sat Mar 28 17:50:12
2026 +0100
+++ b/modules/stock_ethanol/tests/test_module.py Sat Mar 28 17:54:47
2026 +0100
@@ -1,6 +1,9 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
+from decimal import Decimal
+
+from trytond.modules.company.tests import create_company, set_company
from trytond.pool import Pool
from trytond.tests.test_tryton import ModuleTestCase, with_transaction
@@ -8,7 +11,10 @@
class StockEthanolTestCase(ModuleTestCase):
"Test Stock Ethanol module"
module = 'stock_ethanol'
- extras = ['account_stock_eu_excise', 'product_measurements']
+ extras = [
+ 'account_stock_eu_excise',
+ 'product_measurements',
+ 'product_price_list']
@with_transaction()
def test_convert_quantity(self):
@@ -53,5 +59,37 @@
self.assertEqual(excise_tax.convert_quantity(product, 10), 1)
+ @with_transaction()
+ def test_price_list_context_formula(self):
+ "Test price list context formula"
+ pool = Pool()
+ Template = pool.get('product.template')
+ Product = pool.get('product.product')
+ UoM = pool.get('product.uom')
+ PriceList = pool.get('product.price_list')
+
+ unit, = UoM.search([('name', '=', "Liter")])
+ cm3, = UoM.search([('name', '=', "Cubic centimeter")])
+
+ company = create_company()
+ with set_company(company):
+ template = Template(
+ name="Product", default_uom=unit, products=None,
+ list_price=Decimal('100'),
+ contain_ethanol=True, ethanol_by_volume=.2)
+ template.save()
+ product = Product(template=template)
+ product.save()
+
+ price_list = PriceList(
+ name="List", price='list_price',
+ lines=[{
+ 'formula': 'unit_price - .05 * ethanol_volume',
+ 'ethanol_volume_uom': cm3,
+ }])
+ price_list.save()
+
+ self.assertEqual(price_list.compute(product, 5, unit), Decimal(90))
+
del ModuleTestCase
diff -r 78badbeff5b4 -r 3dcd79aff559 modules/stock_ethanol/tryton.cfg
--- a/modules/stock_ethanol/tryton.cfg Sat Mar 28 17:50:12 2026 +0100
+++ b/modules/stock_ethanol/tryton.cfg Sat Mar 28 17:54:47 2026 +0100
@@ -8,6 +8,7 @@
extras_depend:
account_stock_eu_excise
product_measurements
+ product_price_list
xml:
product.xml
stock.xml
@@ -26,3 +27,8 @@
model:
account_stock_eu.ExciseTax
account_stock_eu.ExciseTaxRate
+
+[register product_price_list]
+model:
+ product.PriceList
+ product.PriceListLine
diff -r 78badbeff5b4 -r 3dcd79aff559
modules/stock_ethanol/view/product_price_list_line_form.xml
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/stock_ethanol/view/product_price_list_line_form.xml Sat Mar
28 17:54:47 2026 +0100
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
+this repository contains the full copyright notices and license terms. -->
+<data>
+ <xpath expr="//field[@name='formula']" position="after">
+ <label name="ethanol_volume_uom"/>
+ <field name="ethanol_volume_uom" widget="selection"/>
+ <newline/>
+ </xpath>
+</data>