changeset 53e45aa257f5 in modules/product:default
details: https://hg.tryton.org/modules/product?cmd=changeset&node=53e45aa257f5
description:
        Forbid to decrease digits of unit of measure

        issue11187
        review364711002
diffstat:

 CHANGELOG             |   1 +
 exceptions.py         |   6 ++++-
 message.xml           |   3 ++
 tests/test_product.py |  52 +++++++++++++++++++++++++++++++++++++++++++++++++++
 uom.py                |  24 ++++++++++------------
 5 files changed, 72 insertions(+), 14 deletions(-)

diffs (165 lines):

diff -r f4fda3a3f256 -r 53e45aa257f5 CHANGELOG
--- a/CHANGELOG Thu Feb 03 23:13:26 2022 +0100
+++ b/CHANGELOG Thu Feb 17 00:45:45 2022 +0100
@@ -1,3 +1,4 @@
+* Forbid to decrease digits of unit of measure
 * Add support for Python 3.10
 * Remove support for Python 3.6
 
diff -r f4fda3a3f256 -r 53e45aa257f5 exceptions.py
--- a/exceptions.py     Thu Feb 03 23:13:26 2022 +0100
+++ b/exceptions.py     Thu Feb 17 00:45:45 2022 +0100
@@ -1,7 +1,7 @@
 # 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 trytond.model.exceptions import ValidationError
+from trytond.model.exceptions import AccessError, ValidationError
 
 
 class TemplateValidationError(ValidationError):
@@ -16,5 +16,9 @@
     pass
 
 
+class UOMAccessError(AccessError):
+    pass
+
+
 class InvalidIdentifierCode(ValidationError):
     pass
diff -r f4fda3a3f256 -r 53e45aa257f5 message.xml
--- a/message.xml       Thu Feb 03 23:13:26 2022 +0100
+++ b/message.xml       Thu Feb 17 00:45:45 2022 +0100
@@ -12,6 +12,9 @@
         <record model="ir.message" id="msg_uom_modify_category">
             <field name="text">You cannot modify the category of UOM 
"%(uom)s".</field>
         </record>
+        <record model="ir.message" id="msg_uom_decrease_digits">
+            <field name="text">You cannot decrease the digits of UOM 
"%(uom)s".</field>
+        </record>
         <record model="ir.message" id="msg_uom_modify_options">
             <field name="text">If the UOM is still not used, you can delete it 
otherwise you can deactivate it and create a new one.</field>
         </record>
diff -r f4fda3a3f256 -r 53e45aa257f5 tests/test_product.py
--- a/tests/test_product.py     Thu Feb 03 23:13:26 2022 +0100
+++ b/tests/test_product.py     Thu Feb 17 00:45:45 2022 +0100
@@ -11,6 +11,7 @@
     ModuleTestCase, doctest_checker, doctest_teardown, with_transaction)
 from trytond.transaction import Transaction
 
+from ..exceptions import UOMAccessError
 from ..product import round_price
 
 
@@ -262,6 +263,57 @@
                 msg=msg)
 
     @with_transaction()
+    def test_uom_modify_factor_rate(self):
+        "Test can not modify factor or rate of uom"
+        pool = Pool()
+        Uom = pool.get('product.uom')
+        g, = Uom.search([('name', '=', "Gram")])
+
+        g.factor = 1
+        g.rate = 1
+
+        with self.assertRaises(UOMAccessError):
+            g.save()
+
+    @with_transaction()
+    def test_uom_modify_category(self):
+        "Test can not modify category of uom"
+        pool = Pool()
+        Uom = pool.get('product.uom')
+        Category = pool.get('product.uom.category')
+        g, = Uom.search([('name', '=', "Gram")])
+        units, = Category.search([('name', '=', "Units")])
+
+        g.category = units
+
+        with self.assertRaises(UOMAccessError):
+            g.save()
+
+    @with_transaction()
+    def test_uom_increase_digits(self):
+        "Test can increase digits of uom"
+        pool = Pool()
+        Uom = pool.get('product.uom')
+        g, = Uom.search([('name', '=', "Gram")])
+
+        g.digits += 1
+
+        g.save()
+
+    @with_transaction()
+    def test_uom_decrease_digits(self):
+        "Test can not decrease digits of uom"
+        pool = Pool()
+        Uom = pool.get('product.uom')
+        g, = Uom.search([('name', '=', "Gram")])
+
+        g.digits -= 1
+        g.rounding = 1
+
+        with self.assertRaises(UOMAccessError):
+            g.save()
+
+    @with_transaction()
     def test_product_search_domain(self):
         'Test product.product search_domain function'
         pool = Pool()
diff -r f4fda3a3f256 -r 53e45aa257f5 uom.py
--- a/uom.py    Thu Feb 03 23:13:26 2022 +0100
+++ b/uom.py    Thu Feb 17 00:45:45 2022 +0100
@@ -9,11 +9,10 @@
 from trytond.model import (
     Check, DeactivableMixin, DigitsMixin, ModelSQL, ModelView, SymbolMixin,
     fields)
-from trytond.model.exceptions import AccessError
 from trytond.pyson import Eval
 from trytond.transaction import Transaction
 
-from .exceptions import UOMValidationError
+from .exceptions import UOMAccessError, UOMValidationError
 
 __all__ = ['uom_conversion_digits']
 
@@ -153,26 +152,25 @@
             super(Uom, cls).write(*args)
             return
 
-        actions = iter(args)
-        all_uoms = []
-        for uoms, values in zip(actions, actions):
-            if 'rate' not in values and 'factor' not in values \
-                    and 'category' not in values:
-                continue
-            all_uoms += uoms
-
-        old_uom = dict((uom.id, (uom.factor, uom.rate, uom.category))
-            for uom in all_uoms)
+        all_uoms = sum(args[0:None:2], [])
+        old_uom = {
+            uom.id: (uom.factor, uom.rate, uom.category) for uom in all_uoms}
+        old_digits = {uom.id: uom.digits for uom in all_uoms}
 
         super(Uom, cls).write(*args)
 
         for uom in all_uoms:
             for i, field in enumerate(['factor', 'rate', 'category']):
                 if getattr(uom, field) != old_uom[uom.id][i]:
-                    raise AccessError(
+                    raise UOMAccessError(
                         gettext('product.msg_uom_modify_%s' % field,
                             uom=uom.rec_name),
                         gettext('product.msg_uom_modify_options'))
+            if uom.digits < old_digits[uom.id]:
+                raise UOMAccessError(
+                    gettext('product.msg_uom_decrease_digits',
+                        uom=uom.rec_name),
+                    gettext('product.msg_uom_modify_options'))
 
     @property
     def accurate_field(self):

Reply via email to