diff --git a/CHANGELOG b/CHANGELOG index 9fd79e4e33..e11d75e800 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,5 @@ +* Add methods to format number and symbol on Lang +* Add format number with symbol on Report * Allow locking tables by calling ModelSQL.lock without records * Add test on domain of relation fields * Add stored path as alternative to MPTT diff --git a/trytond/ir/lang.py b/trytond/ir/lang.py index a7fca17e00..e81c45fffa 100644 --- a/trytond/ir/lang.py +++ b/trytond/ir/lang.py @@ -5,6 +5,7 @@ import datetime from locale import CHAR_MAX from ast import literal_eval +from decimal import Decimal from sql import Table from trytond.cache import Cache @@ -552,6 +553,26 @@ class Lang(DeactivableMixin, ModelSQL, ModelView): format = format.replace('%p', p) return value.strftime(format) + def format_number(self, value, digits=None, grouping=True, monetary=None): + if digits is None: + d = value + if not isinstance(d, Decimal): + d = Decimal(repr(value)) + digits = -int(d.as_tuple().exponent) + return self.format( + '%.*f', (digits, value), grouping=grouping, monetary=monetary) + + def format_number_symbol(self, value, symbol, digits=None, grouping=True): + symbol, position = symbol.get_symbol(value) + separated = ( + value < 0 and self.n_sep_by_space or self.p_sep_by_space) + s = self.format_number(value, digits, grouping) + if position: + s = s + (separated and ' ' or '') + symbol + else: + s = symbol + (separated and ' ' or '') + s + return s + class LangConfigStart(ModelView): "Configure languages" diff --git a/trytond/report/report.py b/trytond/report/report.py index a20dc89964..8fe33386bd 100644 --- a/trytond/report/report.py +++ b/trytond/report/report.py @@ -13,7 +13,6 @@ import warnings import zipfile import operator -from decimal import Decimal from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from io import BytesIO @@ -288,6 +287,7 @@ class Report(URLMixin, PoolBase): report_context['format_timedelta'] = cls.format_timedelta report_context['format_currency'] = cls.format_currency report_context['format_number'] = cls.format_number + report_context['format_number_symbol'] = cls.format_number_symbol report_context['datetime'] = datetime def set_lang(language=None): @@ -445,7 +445,8 @@ class Report(URLMixin, PoolBase): Lang = pool.get('ir.lang') if lang is None: lang = Lang.get() - return lang.currency(value, currency, symbol, grouping, digits=digits) + return lang.currency( + value, currency, symbol=symbol, grouping=grouping, digits=digits) @classmethod def format_number( @@ -454,13 +455,18 @@ class Report(URLMixin, PoolBase): Lang = pool.get('ir.lang') if lang is None: lang = Lang.get() - if digits is None: - d = value - if not isinstance(d, Decimal): - d = Decimal(repr(value)) - digits = -int(d.as_tuple().exponent) - return lang.format('%.' + str(digits) + 'f', value, - grouping=grouping, monetary=monetary) + return lang.format_number( + value, digits=digits, grouping=grouping, monetary=monetary) + + @classmethod + def format_number_symbol( + cls, value, lang, symbol, digits=None, grouping=True): + pool = Pool() + Lang = pool.get('ir.lang') + if lang is None: + lang = Lang.get() + return lang.format_number_symbol( + value, symbol, digits=digits, grouping=grouping) def get_email(report, record, languages): diff --git a/trytond/tests/test_ir.py b/trytond/tests/test_ir.py index c0bd8ce452..fe8c3f8773 100644 --- a/trytond/tests/test_ir.py +++ b/trytond/tests/test_ir.py @@ -169,6 +169,40 @@ class IrTestCase(ModuleTestCase): for date, format_, result in test_data: self.assertEqual(lang.strftime(date, format_), result) + @with_transaction() + def test_lang_format_number(self): + "Test Lang.format_number" + pool = Pool() + Lang = pool.get('ir.lang') + lang = Lang.get('en') + test_data = [ + (Decimal('10.50'), False, None, '10.50'), + (Decimal('10.50'), False, 4, '10.5000'), + (Decimal('1000.50'), True, 4, '1,000.5000'), + ] + for value, grouping, digits, result in test_data: + self.assertEqual( + lang.format_number(value, digits, grouping), result) + + @with_transaction() + def test_lang_format_number_symbol(self): + "Test Lang.format_number_symbol" + pool = Pool() + Lang = pool.get('ir.lang') + lang = Lang.get('en') + unit = Mock() + unit.symbol = 'Kg' + unit.get_symbol = Mock() + unit.get_symbol.return_value = 'Kg', 1 + test_data = [ + (Decimal('10.50'), False, None, '10.50Kg'), + (Decimal('1000.50'), True, 4, '1,000.5000Kg'), + ] + for value, grouping, digits, result in test_data: + self.assertEqual( + lang.format_number_symbol(value, unit, digits, grouping), + result) + @with_transaction() def test_model_data_get_id(self): "Test ModelData.get_id"