diff --git a/CHANGELOG b/CHANGELOG index 27ef81acfe..72db12e43f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +* Add format_datetime to Report * Allow sharing view searches * Allow overriding digits in Lang.currency and Report.format_currency * Add record name in report filename diff --git a/trytond/ir/lang.py b/trytond/ir/lang.py index 3c97e16491..ec74d70b39 100644 --- a/trytond/ir/lang.py +++ b/trytond/ir/lang.py @@ -520,7 +520,10 @@ class Lang(DeactivableMixin, ModelSQL, ModelView): Day = pool.get('ir.calendar.day') if format is None: format = self.date + if isinstance(value, datetime.datetime): + format += ' %H:%M:%S' format = format.replace('%x', self.date) + format = format.replace('%X', '%H:%M:%S') if isinstance(value, datetime.date): for f, i, klass in (('%A', 6, Day), ('%B', 1, Month)): for field, f in [('name', f), ('abbreviation', f.lower())]: diff --git a/trytond/report/report.py b/trytond/report/report.py index bbd71094df..2b56b64cab 100644 --- a/trytond/report/report.py +++ b/trytond/report/report.py @@ -1,6 +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. import datetime +import dateutil.tz import os import inspect import logging @@ -244,6 +245,7 @@ class Report(URLMixin, PoolBase): report_context['records'] = records report_context['record'] = records[0] if records else None report_context['format_date'] = cls.format_date + report_context['format_datetime'] = cls.format_datetime report_context['format_timedelta'] = cls.format_timedelta report_context['format_currency'] = cls.format_currency report_context['format_number'] = cls.format_number @@ -339,6 +341,20 @@ class Report(URLMixin, PoolBase): lang = Lang.get() return lang.strftime(value, format=format) + @classmethod + def format_datetime(cls, value, lang=None, format=None, timezone=None): + pool = Pool() + Lang = pool.get('ir.lang') + if lang is None: + lang = Lang.get() + if value.tzinfo is None: + value = value.replace(tzinfo=dateutil.tz.tzutc()) + if timezone: + if isinstance(timezone, str): + timezone = dateutil.tz.gettz(timezone) + value = value.astimezone(timezone) + return lang.strftime(value, format) + @classmethod def format_timedelta(cls, value, converter=None, lang=None): pool = Pool() diff --git a/trytond/tests/test_ir.py b/trytond/tests/test_ir.py index 0617de8255..be1bbebf03 100644 --- a/trytond/tests/test_ir.py +++ b/trytond/tests/test_ir.py @@ -95,6 +95,12 @@ class IrTestCase(ModuleTestCase): (datetime.datetime(2018, 11, 1, 14, 30), '%a %d %b %Y %I:%M %p', "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"), + (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"), ] for date, format_, result in test_data: self.assertEqual(lang.strftime(date, format_), result) diff --git a/trytond/tests/test_report.py b/trytond/tests/test_report.py index 848ad89591..3a7948801b 100644 --- a/trytond/tests/test_report.py +++ b/trytond/tests/test_report.py @@ -2,6 +2,7 @@ # this repository contains the full copyright notices and license terms. import unittest import datetime + from trytond.tests.test_tryton import activate_module, with_transaction from trytond.report.report import Report @@ -13,6 +14,21 @@ class ReportTestCase(unittest.TestCase): def setUpClass(cls): activate_module('tests') + @with_transaction() + def test_format_datetime(self): + "Test format datetime" + self.assertEqual(Report.format_datetime( + datetime.datetime(2020, 7, 8, 13, 30, 00)), + '07/08/2020 13:30:00') + + @with_transaction() + def test_format_datetime_custom_format(self): + "Test format datetime custom format" + 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"), + def create_test_format_timedelta(i, in_, out): @with_transaction()