<commit_before>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<commit_msg>[DOC] Improved documentation.<commit_after>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.
    
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 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)

A menu in Settings/Users has been added to allow 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
++++++++++++++++++++++++++++

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):
      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]
    return result
{'fraction_non_alphanumeric': 0.08208446866485014, 'fraction_numerical': 0.0013623978201634877, 'mean_word_length': 4.519736842105263, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6619452', 'n_tokens_mistral': 1499, 'n_tokens_neox': 1461, 'n_words': 814}