Thibault Delavallée (OpenERP) has proposed merging 
lp:~openerp-dev/openobject-server/trunk-need_action-tde into 
lp:openobject-server.

Requested reviews:
  OpenERP Core Team (openerp)

For more details, see:
https://code.launchpad.net/~openerp-dev/openobject-server/trunk-need_action-tde/+merge/97207

Need action 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.
    
This class wraps a table (base.needaction_users_rel) that behaves like a 
many2many field. However, no field is added to the model inheriting from 
base.needaction. The mixin class manages the low-level considerations of 
updating relationships. Every change made on the record calls a method that 
updates the relationships.

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).

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 allows having a quick look to 
need_action_user_ids.
-- 
https://code.launchpad.net/~openerp-dev/openobject-server/trunk-need_action-tde/+merge/97207
Your team OpenERP R&D Team is subscribed to branch 
lp:~openerp-dev/openobject-server/trunk-need_action-tde.
=== added file 'doc/api/need_action_specs.rst'
--- doc/api/need_action_specs.rst	1970-01-01 00:00:00 +0000
+++ doc/api/need_action_specs.rst	2012-03-15 10:12:19 +0000
@@ -0,0 +1,34 @@
+Need action 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.
+    
+This class wraps a table (base.needaction_users_rel) that behaves like a many2many field. However, no field is added to the model inheriting from base.needaction. The mixin class manages the low-level considerations of updating relationships. Every change made on the record calls a method that updates the relationships.
+
+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).
+
+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 allows having a quick look to need_action_user_ids.
+
+Addon implementation example
+++++++++++++++++++++++++++++
+
+In your ``foo`` module, you want to specify that when it is in state ``confirmed``, it has to be validated by a manager, given by the field ``manager_id``. After making ``foo`` inheriting from ``base.needaction``, you override the ``get_needaction_user_ids`` method:
+
+::
+
+  [...]
+  _inherit = [base.needaction]
+  [...]
+  def get_needaction_user_ids(self, cr, uid, ids, context=None):
+    # set the list void by default
+    result = dict.fromkeys(ids, [])
+    for foo_obj in self.browse(cr, uid, ids, context=context):
+      # 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]
+    return result

=== modified file 'doc/index.rst.inc'
--- doc/index.rst.inc	2012-03-05 14:07:38 +0000
+++ doc/index.rst.inc	2012-03-15 10:12:19 +0000
@@ -6,3 +6,11 @@
    :maxdepth: 1
 
    test-framework
+
+New feature merges
+++++++++++++++++++
+
+.. toctree::
+   :maxdepth: 1
+
+   api/need_action_specs

=== modified file 'openerp/addons/base/__init__.py'
--- openerp/addons/base/__init__.py	2011-09-28 21:13:26 +0000
+++ openerp/addons/base/__init__.py	2012-03-15 10:12:19 +0000
@@ -25,6 +25,7 @@
 import publisher_warranty
 import report
 import test
+import base_needaction
 
 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
 

=== modified file 'openerp/addons/base/__openerp__.py'
--- openerp/addons/base/__openerp__.py	2012-03-01 13:46:08 +0000
+++ openerp/addons/base/__openerp__.py	2012-03-15 10:12:19 +0000
@@ -40,6 +40,7 @@
     ],
     'update_xml': [
         'base_update.xml',
+        'base_needaction_view.xml',
         'ir/wizard/wizard_menu_view.xml',
         'ir/ir.xml',
         'ir/ir_config_parameter_view.xml',

=== added file 'openerp/addons/base/base_needaction.py'
--- openerp/addons/base/base_needaction.py	1970-01-01 00:00:00 +0000
+++ openerp/addons/base/base_needaction.py	2012-03-15 10:12:19 +0000
@@ -0,0 +1,174 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+#    OpenERP, Open Source Management Solution
+#    Copyright (C) 2009-Today OpenERP SA (<http://www.openerp.com>)
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU Affero General Public License as
+#    published by the Free Software Foundation, either version 3 of the
+#    License, or (at your option) any later version
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU Affero General Public License for more details
+#
+#    You should have received a copy of the GNU Affero General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>
+#
+##############################################################################
+
+from osv import osv, fields
+from tools.translate import _
+
+class base_needaction_users_rel(osv.osv):
+    '''
+    base_needaction_users_rel holds data related to the needaction
+    mechanism inside OpenERP. A needaction is characterized by:
+    - res_model: model of the record requiring an action
+    - res_id: ID of the record requiring an action
+    - user_id: foreign key to the res.users table, to the user that
+      has to perform the action
+    '''
+    
+    _name = 'base.needaction_users_rel'
+    _rec_name = 'id'
+    _order = 'res_model asc'
+    _columns = {
+        'res_model': fields.char('Related Document Model', size=128,
+                        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',
+                        ondelete='cascade', select=1, required=True),
+    }
+
+
+class base_needaction(osv.osv):
+    '''Mixin class for objects using the need action feature.
+    
+    Need action feature can be used by objects willing 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 list of
+    users asked ot perform an action.
+    
+    This class wraps a table (base.needaction_users_rel) that behaves
+    like a many2many field. However, no field is added to the model
+    inheriting from base.needaction. The mixin class manages the low-level
+    considerations of updating relationships. Every change made on the
+    record calls a method that updates the relationships.
+    
+    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).
+    This mechanism is used for instance to display the number of pending
+    actions in menus, such as Leads (12).
+    '''
+    _name = 'base.needaction'
+    _description = 'Need action mechanism'
+    
+    _columns = {
+    }
+    
+    #------------------------------------------------------
+    # need action relationship management
+    #------------------------------------------------------
+    
+    def _link_users(self, cr, uid, ids, user_ids, context=None):
+        if context is None:
+            context = {}
+        needact_rel_obj = self.pool.get('base.needaction_users_rel')
+        for id in ids:
+            for user_id in user_ids:
+                needact_rel_obj.create(cr, uid, {'res_model': self._name, 'res_id': id, 'user_id': user_id}, context=context)
+        return True
+    
+    def _unlink_users(self, cr, uid, ids, context=None):
+        if context is None:
+            context = {}
+        needact_rel_obj = self.pool.get('base.needaction_users_rel')
+        to_del_ids = needact_rel_obj.search(cr, uid, [('res_model', '=', self._name), ('res_id', 'in', ids)], context=context)
+        return needact_rel_obj.unlink(cr, uid, to_del_ids, context=context)
+    
+    def _update_users(self, cr, uid, ids, user_ids, context=None):
+        if context is None:
+            context = {}
+        # unlink old records
+        self._unlink_users(cr, uid, ids, context=context)
+        # link new records
+        for res_id in ids:
+            self._link_users(cr, uid, ids, user_ids, context=context)
+        return True
+    
+    #------------------------------------------------------
+    # Addon API
+    #------------------------------------------------------
+    
+    def get_needaction_user_ids(self, cr, uid, ids, context=None):
+        result = dict.fromkeys(ids, [])
+        return result
+    
+    def create(self, cr, uid, values, context=None):
+        if context is None:
+            context = {}
+        # perform create
+        obj_id = super(base_needaction, self).create(cr, uid, values, context=context)
+        # link user_ids
+        needaction_user_ids = self.get_needaction_user_ids(cr, uid, [obj_id], context=context)
+        self._update_users(cr, uid, [obj_id], needaction_user_ids[obj_id], context=context)
+        return obj_id
+    
+    def write(self, cr, uid, ids, values, context=None):
+        if context is None:
+            context = {}
+        # perform write
+        write_res = super(base_needaction, self).write(cr, uid, ids, values, context=context)
+        # get and update user_ids
+        needaction_user_ids = self.get_needaction_user_ids(cr, uid, ids, context=context)
+        for id in ids:
+            self._update_users(cr, uid, [id], needaction_user_ids[id], context=context)
+        return write_res
+    
+    def unlink(self, cr, uid, ids, context=None):
+        if context is None:
+            context = {}
+        # unlink user_ids
+        self._unlink_users(cr, uid, ids, context=context)
+        # perform unlink
+        return super(base_needaction, self).unlink(cr, uid, ids, context=context)
+    
+    #------------------------------------------------------
+    # General API
+    #------------------------------------------------------
+    
+    def needaction_get_user_needaction_ids(self, cr, uid, user_id, offset=0, limit=None, order=None, count=False, context=None):
+        if context is None:
+            context = {}
+        needact_rel_obj = self.pool.get('base.needaction_users_rel')
+        search_res = needact_rel_obj.search(cr, uid, [('user_id', '=', user_id)], offset=offset, limit=limit, order=order, count=count, context=context)
+        return search_res
+    
+    def needaction_get_user_record_references(self, cr, uid, user_id, offset=0, limit=None, order=None, context=None):
+        '''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).'''
+        if context is None:
+            context = {}
+        needact_rel_obj = self.pool.get('base.needaction_users_rel')
+        needact_obj_ids = self.get_user_needaction_ids(cr, uid, user_id, offset=offset, limit=limit, order=order, context=context)
+        needact_objs = needact_rel_obj.browse(cr, uid, needact_obj_ids, context=context)
+        record_references = [(needact_obj.res_model, needact_obj.res_id) for needact_obj in needact_objs]
+        return record_references
+
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

=== added file 'openerp/addons/base/base_needaction_view.xml'
--- openerp/addons/base/base_needaction_view.xml	1970-01-01 00:00:00 +0000
+++ openerp/addons/base/base_needaction_view.xml	2012-03-15 10:12:19 +0000
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+    <data>
+        
+        <record model="ir.ui.view" id="view_notification_tree">
+            <field name="name">base.needaction_users_rel.tree</field>
+            <field name="model">base.needaction_users_rel</field>
+            <field name="type">tree</field>
+            <field name="sequence">10</field>
+            <field name="arch" type="xml">
+                <tree string="Subscription">
+                    <field name="user_id"/>
+                    <field name="res_model"/>
+                    <field name="res_id"/>
+                </tree>
+            </field>
+        </record>
+
+        <record id="action_view_needaction_users_rel" model="ir.actions.act_window">
+            <field name="name">Need action relationships</field>
+            <field name="res_model">base.needaction_users_rel</field>
+            <field name="view_type">form</field>
+            <field name="view_mode">tree,form</field>
+        </record>
+
+        <menuitem id="menu_needaction_users_rel" name="Need actions" parent="base.menu_users" sequence="20" action="action_view_needaction_users_rel" groups="base.group_extended"/>
+
+    </data>
+</openerp>

_______________________________________________
Mailing list: https://launchpad.net/~openerp-dev-gtk
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~openerp-dev-gtk
More help   : https://help.launchpad.net/ListHelp

Reply via email to