@@ -1,3 +1,4 @@
|
||||
* Use no breaking space to format number and date
|
||||
* Fallback to code to format currency without symbol
|
||||
* Add sort method to order like ModelStorage.search
|
||||
* Do not alter argument values of with_transaction decorator (#12108)
|
||||
|
||||
@@ -38,6 +38,9 @@ class DeleteDefaultError(UserError):
|
||||
pass
|
||||
|
||||
|
||||
NO_BREAKING_SPACE = '\u00A0'
|
||||
|
||||
|
||||
class Lang(DeactivableMixin, ModelSQL, ModelView):
|
||||
"Language"
|
||||
__name__ = "ir.lang"
|
||||
@@ -473,7 +476,7 @@ class Lang(DeactivableMixin, ModelSQL, ModelView):
|
||||
formatted, seps = self._group(formatted, monetary=monetary)
|
||||
if seps:
|
||||
formatted = _strip_padding(formatted, seps)
|
||||
return formatted
|
||||
return formatted.replace(' ', NO_BREAKING_SPACE)
|
||||
|
||||
def currency(
|
||||
self, val, currency, symbol=True, grouping=False, digits=None):
|
||||
@@ -528,7 +531,9 @@ class Lang(DeactivableMixin, ModelSQL, ModelView):
|
||||
# this should be the most fitting sign position
|
||||
s = sign + s
|
||||
|
||||
return s.replace('<', '').replace('>', '')
|
||||
return (
|
||||
s.replace('<', '').replace('>', '')
|
||||
.replace(' ', NO_BREAKING_SPACE))
|
||||
|
||||
def strftime(self, value, format=None):
|
||||
'''
|
||||
@@ -561,7 +566,7 @@ class Lang(DeactivableMixin, ModelSQL, ModelView):
|
||||
else:
|
||||
p = self.pm or 'PM'
|
||||
format = format.replace('%p', p)
|
||||
return value.strftime(format)
|
||||
return value.strftime(format).replace(' ', NO_BREAKING_SPACE)
|
||||
|
||||
def format_number(self, value, digits=None, grouping=True, monetary=None):
|
||||
if digits is None:
|
||||
@@ -574,14 +579,13 @@ class Lang(DeactivableMixin, ModelSQL, ModelView):
|
||||
|
||||
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)
|
||||
separated = True
|
||||
s = self.format_number(value, digits, grouping)
|
||||
if position:
|
||||
s = s + (separated and ' ' or '') + symbol
|
||||
else:
|
||||
s = symbol + (separated and ' ' or '') + s
|
||||
return s
|
||||
return s.replace(' ', NO_BREAKING_SPACE)
|
||||
|
||||
|
||||
class LangConfigStart(ModelView):
|
||||
|
||||
@@ -101,6 +101,8 @@ TIMEDELTA_DEFAULT_CONVERTER['w'] = TIMEDELTA_DEFAULT_CONVERTER['d'] * 7
|
||||
TIMEDELTA_DEFAULT_CONVERTER['M'] = TIMEDELTA_DEFAULT_CONVERTER['d'] * 30
|
||||
TIMEDELTA_DEFAULT_CONVERTER['Y'] = TIMEDELTA_DEFAULT_CONVERTER['d'] * 365
|
||||
|
||||
NO_BREAKING_SPACE = '\u00A0'
|
||||
|
||||
# For most OS maximum filename is 255 but Excel has a limitation which include
|
||||
# the path of 218.
|
||||
# As on Windows report is most likely to be open from
|
||||
@@ -483,7 +485,7 @@ class Report(URLMixin, PoolBase):
|
||||
# Add space if no time
|
||||
text += ' '
|
||||
text += ('%.6f' % value)[1:]
|
||||
return text
|
||||
return text.replace(' ', NO_BREAKING_SPACE)
|
||||
|
||||
@classmethod
|
||||
def format_currency(
|
||||
|
||||
@@ -153,8 +153,8 @@ class IrTestCase(ModuleTestCase):
|
||||
currency.symbol = None
|
||||
currency.code = 'USD'
|
||||
test_data = [
|
||||
(Decimal('10.50'), True, False, None, 'USD 10.50'),
|
||||
(Decimal('10.50'), True, False, 4, 'USD 10.5000'),
|
||||
(Decimal('10.50'), True, False, None, 'USD 10.50'),
|
||||
(Decimal('10.50'), True, False, 4, 'USD 10.5000'),
|
||||
]
|
||||
for value, symbol, grouping, digits, result in test_data:
|
||||
self.assertEqual(
|
||||
@@ -181,17 +181,17 @@ class IrTestCase(ModuleTestCase):
|
||||
Lang = pool.get('ir.lang')
|
||||
lang = Lang.get('en')
|
||||
test_data = [
|
||||
(datetime.date(2016, 8, 3), '%d %B %Y', "03 August 2016"),
|
||||
(datetime.time(8, 20), '%I:%M %p', "08:20 AM"),
|
||||
(datetime.date(2016, 8, 3), '%d %B %Y', "03 August 2016"),
|
||||
(datetime.time(8, 20), '%I:%M %p', "08:20 AM"),
|
||||
(datetime.datetime(2018, 11, 1, 14, 30), '%a %d %b %Y %I:%M %p',
|
||||
"Thu 01 Nov 2018 02:30 PM"),
|
||||
"Thu 01 Nov 2018 02:30 PM"),
|
||||
(datetime.date(2018, 11, 1), '%x', "11/01/2018"),
|
||||
(datetime.datetime(2018, 11, 1, 14, 30, 12),
|
||||
'%x %X', "11/01/2018 14:30:12"),
|
||||
'%x %X', "11/01/2018 14:30:12"),
|
||||
(datetime.datetime(2018, 11, 1, 14, 30, 12),
|
||||
'%H:%M:%S', "14:30:12"),
|
||||
(datetime.datetime(2018, 11, 1, 14, 30, 12), None,
|
||||
"11/01/2018 14:30:12"),
|
||||
"11/01/2018 14:30:12"),
|
||||
]
|
||||
for date, format_, result in test_data:
|
||||
self.assertEqual(lang.strftime(date, format_), result)
|
||||
@@ -222,8 +222,8 @@ class IrTestCase(ModuleTestCase):
|
||||
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'),
|
||||
(Decimal('10.50'), False, None, '10.50 Kg'),
|
||||
(Decimal('1000.50'), True, 4, '1,000.5000 Kg'),
|
||||
]
|
||||
for value, grouping, digits, result in test_data:
|
||||
self.assertEqual(
|
||||
|
||||
@@ -19,7 +19,7 @@ class ReportTestCase(unittest.TestCase):
|
||||
"Test format datetime"
|
||||
self.assertEqual(Report.format_datetime(
|
||||
datetime.datetime(2020, 7, 8, 13, 30, 00)),
|
||||
'07/08/2020 13:30:00')
|
||||
'07/08/2020 13:30:00')
|
||||
|
||||
@with_transaction()
|
||||
def test_format_datetime_custom_format(self):
|
||||
@@ -27,7 +27,7 @@ class ReportTestCase(unittest.TestCase):
|
||||
self.assertEqual(Report.format_datetime(
|
||||
datetime.datetime(2020, 7, 8, 13, 30, 00),
|
||||
format='%d %b %Y %I:%M %p'),
|
||||
"08 Jul 2020 01:30 PM"),
|
||||
"08 Jul 2020 01:30 PM"),
|
||||
|
||||
|
||||
def create_test_format_timedelta(i, in_, out):
|
||||
@@ -42,20 +42,20 @@ def create_test_format_timedelta(i, in_, out):
|
||||
for i, (in_, out) in enumerate([
|
||||
(None, ''),
|
||||
(datetime.timedelta(), '00:00'),
|
||||
(datetime.timedelta(days=3, hours=5, minutes=30), '3d 05:30'),
|
||||
(datetime.timedelta(weeks=48), '11M 6d'),
|
||||
(datetime.timedelta(weeks=50), '11M 2w 6d'),
|
||||
(datetime.timedelta(weeks=52), '12M 4d'),
|
||||
(datetime.timedelta(days=3, hours=5, minutes=30), '3d 05:30'),
|
||||
(datetime.timedelta(weeks=48), '11M 6d'),
|
||||
(datetime.timedelta(weeks=50), '11M 2w 6d'),
|
||||
(datetime.timedelta(weeks=52), '12M 4d'),
|
||||
(datetime.timedelta(days=360), '12M'),
|
||||
(datetime.timedelta(days=364), '12M 4d'),
|
||||
(datetime.timedelta(days=364), '12M 4d'),
|
||||
(datetime.timedelta(days=365), '1Y'),
|
||||
(datetime.timedelta(days=366), '1Y 1d'),
|
||||
(datetime.timedelta(days=366), '1Y 1d'),
|
||||
(datetime.timedelta(hours=2, minutes=5, seconds=10), '02:05:10'),
|
||||
(datetime.timedelta(minutes=15, microseconds=42),
|
||||
'00:15:00.000042'),
|
||||
(datetime.timedelta(days=1, microseconds=42), '1d .000042'),
|
||||
(datetime.timedelta(days=1, microseconds=42), '1d .000042'),
|
||||
(datetime.timedelta(seconds=-1), '-00:00:01'),
|
||||
(datetime.timedelta(days=-1, hours=-5, minutes=-30), '-1d 05:30'),
|
||||
(datetime.timedelta(days=-1, hours=-5, minutes=-30), '-1d 05:30'),
|
||||
]):
|
||||
test_method = create_test_format_timedelta(i, in_, out)
|
||||
setattr(ReportTestCase, test_method.__name__, test_method)
|
||||
|
||||
Reference in New Issue
Block a user