From 4ecc0c4c71bed76949ba5d90603a39bdd64fdf0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Mon, 11 Apr 2022 23:41:21 +0200 Subject: [PATCH] Add notification message issue11065 review367951004 --- CHANGELOG | 1 + doc/ref/models.rst | 9 +++++++++ trytond/ir/model.py | 10 ++++++++++ trytond/model/modelview.py | 22 ++++++++++++++++++++++ trytond/tests/test_tryton.py | 2 +- 5 files changed, 43 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index b0dd61a3f1..d925691b0b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +* Add notification message * Add validate_fields to ModelStorage * Drop support for PyPy and psycopg2cffi * Use a set for field's depends diff --git a/doc/ref/models.rst b/doc/ref/models.rst index 3dceadfcb3..8052efd333 100644 --- a/doc/ref/models.rst +++ b/doc/ref/models.rst @@ -113,6 +113,15 @@ Instance methods: Return the new values of all fields by calling ``on_change_with`` method of each field. +.. method:: Model.on_change_notify(fieldnames) + + Returns a list of type and message couple to display on the client side. + Available types are ``info``, ``warning`` and ``error``. + + .. note:: + To be called by the client, this method must be decorated + by :meth:`~trytond.model.fields.depends` with the fields needed. + .. method:: Model.pre_validate() Validate the instance before being stored. diff --git a/trytond/ir/model.py b/trytond/ir/model.py index 7f1ae04e47..6304018f24 100644 --- a/trytond/ir/model.py +++ b/trytond/ir/model.py @@ -73,6 +73,7 @@ class Model(ModelSQL, ModelView): cls.__rpc__.update({ 'list_models': RPC(), 'list_history': RPC(), + 'get_notification': RPC(), 'get_names': RPC(), 'global_search': RPC(), }) @@ -145,6 +146,15 @@ class Model(ModelSQL, ModelView): return [name for name, model in Pool().iterobject() if getattr(model, '_history', False)] + @classmethod + def get_notification(cls): + "Return a dictionary of model to notify with the depending fields" + return { + name: list(model._on_change_notify_depends) + for name, model in Pool().iterobject() + if issubclass(model, ModelView) + and model._on_change_notify_depends} + @classmethod def get_name_items(cls): "Return a list of couple mapping models to names" diff --git a/trytond/model/modelview.py b/trytond/model/modelview.py index 6dcd0bd61f..383c287d87 100644 --- a/trytond/model/modelview.py +++ b/trytond/model/modelview.py @@ -50,6 +50,7 @@ class ModelView(Model): cls.__rpc__['view_toolbar_get'] = RPC(cache=dict(days=1)) cls.__rpc__['on_change'] = RPC(instantiate=0) cls.__rpc__['on_change_with'] = RPC(instantiate=0) + cls.__rpc__['on_change_notify'] = RPC(instantiate=0) cls._buttons = {} fields_ = {} @@ -165,6 +166,21 @@ class ModelView(Model): methods['depend_methods'][meth_name] - meth_done) meth_done.add(meth_name) + set_methods('on_change_notify') + cls._on_change_notify_depends = methods['depends']['on_change_notify'] + meth_names = list(methods['depend_methods']['on_change_notify']) + meth_done = set() + while meth_names: + meth_name = meth_names.pop() + method = getattr(cls, meth_name) + assert callable(method) or isinstance(method, property), \ + "%s.%s not callable or property" % (cls, meth_name) + set_methods(meth_name) + cls._on_change_notify_depends |= methods['depends'][meth_name] + meth_names += list( + methods['depend_methods'][meth_name] - meth_done) + meth_done.add(meth_name) + @classmethod def fields_view_get(cls, view_id=None, view_type='form', level=None): ''' @@ -744,6 +760,12 @@ class ModelView(Model): changes[fieldname] = getattr(self, method_name)() return changes + def on_change_notify(self): + """Return a list of type and message couples. + Available types are info, warning and error. + """ + return [] + @property def _changed_values(self): """Return the values changed since the instantiation. diff --git a/trytond/tests/test_tryton.py b/trytond/tests/test_tryton.py index 879d02d26e..eb97f18242 100644 --- a/trytond/tests/test_tryton.py +++ b/trytond/tests/test_tryton.py @@ -427,7 +427,7 @@ class ModuleTestCase(unittest.TestCase): for prefixes in [['default_'], ['on_change_', 'on_change_with_'], ['order_'], ['domain_'], ['autocomplete_']]: - if attr == 'on_change_with': + if attr in {'on_change_with', 'on_change_notify'}: continue # TODO those method should be renamed if attr == 'default_get':