From 03cd5c47b288b36075da27cba597f4b8bb93e271 Mon Sep 17 00:00:00 2001 From: "Turkesh Patel (Open ERP)" Date: Fri, 30 Mar 2012 10:40:38 +0530 Subject: [PATCH 1/7] [IMP] store functional fields in database bzr revid: tpa@tinyerp.com-20120330051038-y7b1vdamhdp4pj3n --- openerp/addons/base/ir/ir_ui_menu.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openerp/addons/base/ir/ir_ui_menu.py b/openerp/addons/base/ir/ir_ui_menu.py index 344457db863..01e11ffc8bb 100644 --- a/openerp/addons/base/ir/ir_ui_menu.py +++ b/openerp/addons/base/ir/ir_ui_menu.py @@ -284,8 +284,8 @@ class ir_ui_menu(osv.osv): 'web_icon_hover':fields.char('Web Icon File (hover)', size=128), 'web_icon_data': fields.function(_get_image_icon, string='Web Icon Image', type='binary', readonly=True, store=True, multi='icon'), 'web_icon_hover_data':fields.function(_get_image_icon, string='Web Icon Image (hover)', type='binary', readonly=True, store=True, multi='icon'), - 'has_needaction': fields.function(_get_needaction, string='User has actions to perform', type='boolean', help='', multi='has_action'), - 'needaction_ctr': fields.function(_get_needaction, string='Action counter', type='integer', help='', multi='has_action'), + 'has_needaction': fields.function(_get_needaction,store=True,string='User has actions to perform', type='boolean', help='', multi='has_action'), + 'needaction_ctr': fields.function(_get_needaction,store=True, string='Action counter', type='integer', help='', multi='has_action'), 'action': fields.function(_action, fnct_inv=_action_inv, type='reference', string='Action', selection=[ From 2f97bcdf7d95d52e52dc70e0652b4da6c2094488 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Fri, 30 Mar 2012 12:03:37 +0200 Subject: [PATCH 2/7] [FIX] Removed the store=True (too much access to DB), as this is not necessary. Fixed dict of dict: inner dict instantiation is done for each iteration, because argument management in python made all dicts pointers to the same dict bzr revid: tde@openerp.com-20120330100337-miqra4q5sjokt7en --- openerp/addons/base/ir/ir_ui_menu.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/openerp/addons/base/ir/ir_ui_menu.py b/openerp/addons/base/ir/ir_ui_menu.py index 01e11ffc8bb..18d390e8ae9 100644 --- a/openerp/addons/base/ir/ir_ui_menu.py +++ b/openerp/addons/base/ir/ir_ui_menu.py @@ -258,8 +258,9 @@ class ir_ui_menu(osv.osv): def _get_needaction(self, cr, uid, ids, field_names, args, context=None): if context is None: context = {} - res = dict.fromkeys(ids, {}) + res = dict.fromkeys(ids) for menu in self.browse(cr, uid, ids, context=context): + res[menu.id] = {} if menu.action and menu.action.type == 'ir.actions.act_window' and menu.action.res_model: menu_needaction_res = osv.osv.get_needaction_info(cr, uid, menu.action.res_model, uid, domain=menu.action.domain, context=context) else: @@ -284,8 +285,8 @@ class ir_ui_menu(osv.osv): 'web_icon_hover':fields.char('Web Icon File (hover)', size=128), 'web_icon_data': fields.function(_get_image_icon, string='Web Icon Image', type='binary', readonly=True, store=True, multi='icon'), 'web_icon_hover_data':fields.function(_get_image_icon, string='Web Icon Image (hover)', type='binary', readonly=True, store=True, multi='icon'), - 'has_needaction': fields.function(_get_needaction,store=True,string='User has actions to perform', type='boolean', help='', multi='has_action'), - 'needaction_ctr': fields.function(_get_needaction,store=True, string='Action counter', type='integer', help='', multi='has_action'), + 'has_needaction': fields.function(_get_needaction, string='User has actions to perform', type='boolean', help='', multi='has_action'), + 'needaction_ctr': fields.function(_get_needaction, string='Action counter', type='integer', help='', multi='has_action'), 'action': fields.function(_action, fnct_inv=_action_inv, type='reference', string='Action', selection=[ From 3ee9f70343ca0eb571f5ec9eb01eccb89c09dc78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Fri, 30 Mar 2012 12:19:29 +0200 Subject: [PATCH 3/7] [IMP] Renamed added fields. Added comments and improved help. bzr revid: tde@openerp.com-20120330101929-18opxctcz1eeyl4u --- openerp/addons/base/ir/ir_ui_menu.py | 8 ++++---- openerp/osv/orm.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/openerp/addons/base/ir/ir_ui_menu.py b/openerp/addons/base/ir/ir_ui_menu.py index 18d390e8ae9..205d44b0363 100644 --- a/openerp/addons/base/ir/ir_ui_menu.py +++ b/openerp/addons/base/ir/ir_ui_menu.py @@ -265,8 +265,8 @@ class ir_ui_menu(osv.osv): menu_needaction_res = osv.osv.get_needaction_info(cr, uid, menu.action.res_model, uid, domain=menu.action.domain, context=context) else: menu_needaction_res = [False, 0] - res[menu.id]['has_needaction'] = menu_needaction_res[0] - res[menu.id]['needaction_ctr'] = menu_needaction_res[1] + res[menu.id]['uses_needaction'] = menu_needaction_res[0] + res[menu.id]['needaction_uid_ctr'] = menu_needaction_res[1] return res _columns = { @@ -285,8 +285,8 @@ class ir_ui_menu(osv.osv): 'web_icon_hover':fields.char('Web Icon File (hover)', size=128), 'web_icon_data': fields.function(_get_image_icon, string='Web Icon Image', type='binary', readonly=True, store=True, multi='icon'), 'web_icon_hover_data':fields.function(_get_image_icon, string='Web Icon Image (hover)', type='binary', readonly=True, store=True, multi='icon'), - 'has_needaction': fields.function(_get_needaction, string='User has actions to perform', type='boolean', help='', multi='has_action'), - 'needaction_ctr': fields.function(_get_needaction, string='Action counter', type='integer', help='', multi='has_action'), + 'uses_needaction': fields.function(_get_needaction, string='Related model uses the need action mechanism', type='boolean', help='If the menu entry is related to a act_window action, and this action is related to a model that uses the need_action mechanism, this field is set to true. Otherwise, it is false.', multi='_get_needaction'), + 'needaction_uid_ctr': fields.function(_get_needaction, string='Number of actions the user has to perform', type='integer', help='If the related model uses the need action mechanism, this field gives the number of actions the current user has to perform.', multi='_get_needaction'), 'action': fields.function(_action, fnct_inv=_action_inv, type='reference', string='Action', selection=[ diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index 86eed18ff6b..6d6d6dd0d38 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -722,7 +722,7 @@ class BaseModel(object): """Base method for needaction mechanism - see base.needaction for actual implementation - this method returns default values - :return: [has_needaction=False, needaction_ctr=0] + :return: [uses_needaction=False, needaction_uid_ctr=0] """ model_obj = pooler.get_pool(cr.dbname).get(model_name) if hasattr(model_obj, 'needaction_get_record_ids'): From 94075df78e347c051e5f7ef85b3d23d9848e0259 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Fri, 30 Mar 2012 12:24:19 +0200 Subject: [PATCH 4/7] [DOC] Added comments. bzr revid: tde@openerp.com-20120330102419-n2co6dwf00q0muue --- openerp/osv/orm.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index 6d6d6dd0d38..da424611dd9 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -721,8 +721,18 @@ class BaseModel(object): def get_needaction_info(cr, uid, model_name, user_id, limit=None, order=None, domain=False, context=None): """Base method for needaction mechanism - see base.needaction for actual implementation + - if the model uses the need action mechanism + (hasattr(model_obj, 'needaction_get_record_ids'): + - get the record ids on which the user has actions to perform + - evaluate the menu domain + - compose a new domain: menu domain, limited to ids of + records requesting an action + - count the number of records maching that domain, that + is the number of actions the user has to perform - this method returns default values - :return: [uses_needaction=False, needaction_uid_ctr=0] + :param: model_name: the name of the model (ex: hr.holidays) + :param: user_id: the id of user + :return: [uses_needaction=True/False, needaction_uid_ctr=%d] """ model_obj = pooler.get_pool(cr.dbname).get(model_name) if hasattr(model_obj, 'needaction_get_record_ids'): @@ -730,8 +740,7 @@ class BaseModel(object): if not ids: return [True, 0] if domain: - domain = eval(domain) - new_domain = domain + [('id', 'in', ids)] + new_domain = eval(domain) + [('id', 'in', ids)] else: new_domain = [('ids', 'in', ids)] return [True, model_obj.search(cr, uid, new_domain, limit=limit, order=order, count=True)] From 3d726e1d4d6ad20d6db211fe511e74e091cad406 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Fri, 30 Mar 2012 12:38:22 +0200 Subject: [PATCH 5/7] [DOC] Improved comments bzr revid: tde@openerp.com-20120330103822-3esas0shsvoidb90 --- openerp/addons/base/base_needaction.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/openerp/addons/base/base_needaction.py b/openerp/addons/base/base_needaction.py index 657cf8f5d55..08a0452ebab 100644 --- a/openerp/addons/base/base_needaction.py +++ b/openerp/addons/base/base_needaction.py @@ -34,6 +34,7 @@ class base_needaction_users_rel(osv.osv): ''' _name = 'base.needaction_users_rel' + _description = 'Relationships between records and users, for need action mechanism' _rec_name = 'id' _order = 'res_model asc' _columns = { @@ -41,7 +42,7 @@ class base_needaction_users_rel(osv.osv): select=1, required=True), 'res_id': fields.integer('Related Document ID', select=1, required=True), - 'user_id': fields.many2one('res.users', string='Related User ID', + 'user_id': fields.many2one('res.users', string='Related User', ondelete='cascade', select=1, required=True), } @@ -70,13 +71,18 @@ class base_needaction(osv.osv): This class also offers several global services,: - ``needaction_get_user_record_references``: for a given uid, get all - the records that asks this user to perform an action. Records - are given as references, a list of tuples (model_name, record_id). - This mechanism is used for instance to display the number of pending - actions in menus, such as Leads (12). + the records that ask this user to perform an action. Records + are given as references, a list of tuples (model_name, record_id). + - ``needaction_get_record_ids``: for a given model_name and uid, get + all record ids that ask this user to perform an action. This + mechanism is used for instance to display the number of pending + actions in menus, such as Leads (12). + - ``needaction_get_action_count``: as ``needaction_get_record_ids`` + but returns only the number of action, not the ids (performs a + search with count=True) ''' _name = 'base.needaction' - _description = 'Need action mechanism' + _description = 'Need action of users on records API' _columns = { } From c2e1b6a3840ca1bcad5b77279a7d4dc2d6ef42c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Fri, 30 Mar 2012 12:42:42 +0200 Subject: [PATCH 6/7] [DOC] Improved documentation. bzr revid: tde@openerp.com-20120330104242-h68fy7zsnueaod9m --- doc/api/need_action_specs.rst | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/doc/api/need_action_specs.rst b/doc/api/need_action_specs.rst index 5cffe05be2c..8efd548845a 100644 --- a/doc/api/need_action_specs.rst +++ b/doc/api/need_action_specs.rst @@ -1,5 +1,8 @@ -Need action mixin class -======================= +Need action mechanism +===================== + +base.needaction mixin class ++++++++++++++++++++++++++++ This revision adds a mixin class for objects using the need action feature. Need action mechanism can be used by objects that have to be able to signal that an action is required on a particular record. If in the business logic an action must be performed by somebody, for instance validation by a manager, this mechanism allows to set a field with the user_id of the user requested to perform the action. @@ -8,11 +11,20 @@ This class wraps a table (base.needaction_users_rel) that behaves like a many2ma Objects using the need_action feature should override the ``get_needaction_user_ids`` method. This methods returns a dictionary whose keys are record ids, and values a list of user ids, like in a many2many relationship. Therefore by defining only one method, you can specify if an action is required by defining the users that have to do it, in every possible situation. This class also offers several global services,: - - ``needaction_get_user_record_references``: for a given uid, get all the records that asks this user to perform an action. Records are given as references, a list of tuples (model_name, record_id). + - ``needaction_get_user_record_references``: for a given uid, get all the records that ask this user to perform an action. Records are given as references, a list of tuples (model_name, record_id). + - ``needaction_get_record_ids``: for a given model_name and uid, get all record ids that ask this user to perform an action. This mechanism is used for instance to display the number of pending actions in menus, such as Leads (12). + - ``needaction_get_action_count``: as ``needaction_get_record_ids`` but returns only the number of action, not the ids (performs a search with count=True) -This mechanism is used for instance to display the number of pending actions in menus, such as Leads (12). +A menu in Settings/Users has been added to allow having a quick look to need_action_user_ids. -A menu in Settings/Users has been added to allows having a quick look to need_action_user_ids. +Menu modification ++++++++++++++++++ + +This revision adds two functional fields to ``ir.ui.menu`` model : + - ``uses_needaction``: boolean field. If the menu entry is related to a act_window action, and this action is related to a model that uses the need_action mechanism, this field is set to true. Otherwise, it is false. + - ``needaction_uid_ctr``: integer field. If the related model uses the need action mechanism, this field gives the number of actions the current user has to perform. + +Those fields are functional, because they must be recalculated for each user, and each time menus are displayed. ``needaction_uid_ctr`` takes into account the domain of the action, in order to display accurate numbers. Addon implementation example ++++++++++++++++++++++++++++ @@ -26,8 +38,9 @@ In your ``foo`` module, you want to specify that when it is in state ``confirmed [...] def get_needaction_user_ids(self, cr, uid, ids, context=None): # set the list void by default - result = dict.fromkeys(ids, []) + result = dict.fromkeys(ids) for foo_obj in self.browse(cr, uid, ids, context=context): + result[foo_obj.id] = [] # if foo_obj is confirmed: manager is required to perform an action if foo_obj.state == 'confirmed': result[foo_obj.id] = [foo_obj.manager_id] From f57efbb152db29db2a0652f8ea55691a3202915e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thibault=20Delavall=C3=A9e?= Date: Fri, 30 Mar 2012 12:49:36 +0200 Subject: [PATCH 7/7] [FIX] Too long model description bzr revid: tde@openerp.com-20120330104936-p2cnbtua1znie6et --- openerp/addons/base/base_needaction.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openerp/addons/base/base_needaction.py b/openerp/addons/base/base_needaction.py index 08a0452ebab..69f620d7379 100644 --- a/openerp/addons/base/base_needaction.py +++ b/openerp/addons/base/base_needaction.py @@ -34,7 +34,7 @@ class base_needaction_users_rel(osv.osv): ''' _name = 'base.needaction_users_rel' - _description = 'Relationships between records and users, for need action mechanism' + _description = 'Needaction relationship table' _rec_name = 'id' _order = 'res_model asc' _columns = {