diff --git a/trytond/trytond/ir/sequence.py b/trytond/trytond/ir/sequence.py
index 03e364255a..ef5417cb9b 100644
--- a/trytond/trytond/ir/sequence.py
+++ b/trytond/trytond/ir/sequence.py
@@ -106,6 +106,7 @@ class Sequence(DeactivableMixin, ModelSQL, ModelView):
'required': Eval('type').in_(
['decimal timestamp', 'hexadecimal timestamp']),
}, depends=['type'])
+ preview = fields.Function(fields.Char("Preview"), 'on_change_with_preview')
@classmethod
def __setup__(cls):
@@ -337,8 +338,9 @@ class Sequence(DeactivableMixin, ModelSQL, ModelView):
'''
pool = Pool()
Date = pool.get('ir.date')
+ context = Transaction().context
if not date:
- date = Date.today()
+ date = context.get('date') or Date.today()
class CustomFormatter(dict):
@@ -373,10 +375,10 @@ class Sequence(DeactivableMixin, ModelSQL, ModelView):
f"Unknown substitution format {format_}")
return value
- @staticmethod
- def _timestamp(sequence):
- return int((time.time() - sequence.timestamp_offset)
- / sequence.timestamp_rounding)
+ @fields.depends('timestamp_offset', 'timestamp_rounding')
+ def _timestamp(self):
+ return int(
+ (time.time() - self.timestamp_offset) / self.timestamp_rounding)
@classmethod
def _get_sequence(cls, sequence):
@@ -386,6 +388,9 @@ class Sequence(DeactivableMixin, ModelSQL, ModelView):
cursor.execute('SELECT nextval(\'"%s"\')'
% sequence._sql_sequence_name)
number_next, = cursor.fetchone()
+ # clean cache
+ Transaction().counter += 1
+ sequence._local_cache.pop(sequence.id, None)
else:
# Pre-fetch number_next
number_next = sequence.number_next_internal
@@ -394,16 +399,30 @@ class Sequence(DeactivableMixin, ModelSQL, ModelView):
'number_next_internal': (number_next
+ sequence.number_increment),
})
- return '%%0%sd' % sequence.padding % number_next
+ return f'{number_next:0>{sequence.padding}d}'
elif sequence.type in ('decimal timestamp', 'hexadecimal timestamp'):
timestamp = sequence.last_timestamp
while timestamp == sequence.last_timestamp:
- timestamp = cls._timestamp(sequence)
+ timestamp = sequence._timestamp()
cls.write([sequence], {
'last_timestamp': timestamp,
})
if sequence.type == 'decimal timestamp':
- return '%d' % timestamp
+ return f'{timestamp:d}'
+ else:
+ return hex(timestamp)[2:].upper()
+ return ''
+
+ @fields.depends('type', 'padding', 'number_next', methods=['_timestamp'])
+ def _get_preview_sequence(self):
+ if self.type == 'incremental':
+ number_next = self.number_next or 0
+ padding = self.padding or 0
+ return f'{number_next:0>{padding}d}'
+ elif self.type in {'decimal timestamp', 'hexadecimal timestamp'}:
+ timestamp = self._timestamp()
+ if self.type == 'decimal timestamp':
+ return f'{timestamp:d}'
else:
return hex(timestamp)[2:].upper()
return ''
@@ -420,11 +439,18 @@ class Sequence(DeactivableMixin, ModelSQL, ModelView):
raise MissingError(gettext('ir.msg_sequence_missing'))
if _lock:
self.lock()
- date = Transaction().context.get('date')
return '%s%s%s' % (
- cls._process(sequence.prefix, date=date),
+ cls._process(sequence.prefix),
cls._get_sequence(sequence),
- cls._process(sequence.suffix, date=date),
+ cls._process(sequence.suffix),
+ )
+
+ @fields.depends('prefix', 'suffix', methods=['_get_preview_sequence'])
+ def on_change_with_preview(self, name=None):
+ return '%s%s%s' % (
+ self._process(self.prefix),
+ self._get_preview_sequence(),
+ self._process(self.suffix),
)
diff --git a/trytond/trytond/ir/view/sequence_form.xml b/trytond/trytond/ir/view/sequence_form.xml
index 4bb404e69f..2710f9bed4 100644
--- a/trytond/trytond/ir/view/sequence_form.xml
+++ b/trytond/trytond/ir/view/sequence_form.xml
@@ -14,20 +14,22 @@ this repository contains the full copyright notices and license terms. -->
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/trytond/trytond/tests/test_sequence.py b/trytond/trytond/tests/test_sequence.py
index 87f405643f..591f11d51a 100644
--- a/trytond/trytond/tests/test_sequence.py
+++ b/trytond/trytond/tests/test_sequence.py
@@ -40,19 +40,23 @@ class SequenceTestCase(unittest.TestCase):
'type': 'incremental',
}])
self.assertEqual(sequence.number_next, 1)
+ self.assertEqual(sequence.preview, '1')
self.assertEqual(sequence.get(), '1')
Sequence.write([sequence], {
'number_increment': 10,
})
self.assertEqual(sequence.number_next, 2)
+ self.assertEqual(sequence.preview, '2')
self.assertEqual(sequence.get(), '2')
+ self.assertEqual(sequence.preview, '12')
self.assertEqual(sequence.get(), '12')
Sequence.write([sequence], {
'padding': 3,
})
self.assertEqual(sequence.number_next, 22)
+ self.assertEqual(sequence.preview, '022')
self.assertEqual(sequence.get(), '022')
@with_transaction()
@@ -72,6 +76,7 @@ class SequenceTestCase(unittest.TestCase):
'suffix': '',
'type': 'decimal timestamp',
}])
+ self.assertTrue(sequence.preview)
timestamp = sequence.get()
self.assertEqual(timestamp, str(sequence.last_timestamp))
@@ -101,6 +106,7 @@ class SequenceTestCase(unittest.TestCase):
'suffix': '',
'type': 'hexadecimal timestamp',
}])
+ self.assertTrue(sequence.preview)
timestamp = sequence.get()
self.assertEqual(timestamp,
hex(int(sequence.last_timestamp))[2:].upper())
@@ -131,6 +137,7 @@ class SequenceTestCase(unittest.TestCase):
'suffix': '/suffix',
'type': 'incremental',
}])
+ self.assertEqual(sequence.preview, 'prefix/1/suffix')
self.assertEqual(sequence.get(),
'prefix/1/suffix')
@@ -139,6 +146,8 @@ class SequenceTestCase(unittest.TestCase):
'suffix': '/${day}.${month}.${year}',
})
with Transaction().set_context(date=datetime.date(2010, 8, 15)):
+ self.assertEqual(
+ Sequence(sequence).preview, '2010-08-15/2/15.08.2010')
self.assertEqual(sequence.get(), '2010-08-15/2/15.08.2010')