[IMP] base_action_rule: allow using the CharDomain widget
authorAmit Vora <avo@openerp.com>
Mon, 23 Jun 2014 05:27:42 +0000 (10:57 +0530)
committerThibault Delavallée <tde@openerp.com>
Wed, 1 Oct 2014 07:07:29 +0000 (09:07 +0200)
to set the filter and pre-update filter. Using ir.filters is still
possible, but is not the only way anymore of setting the domains
used in the base action rules.

addons/base_action_rule/base_action_rule.py
addons/base_action_rule/base_action_rule_view.xml
addons/crm/crm_action_rule_demo.xml

index 864d283..1afecfa 100644 (file)
@@ -88,14 +88,16 @@ class base_action_rule(osv.osv):
         'server_action_ids': fields.many2many('ir.actions.server', string='Server Actions',
             domain="[('model_id', '=', model_id)]",
             help="Examples: email reminders, call object service, etc."),
-        'filter_pre_id': fields.many2one('ir.filters', string='Before Update Filter',
-            ondelete='restrict',
-            domain="[('model_id', '=', model_id.model)]",
+        'filter_pre_id': fields.many2one(
+            'ir.filters', string='Before Update Filter',
+            ondelete='restrict', domain="[('model_id', '=', model_id.model)]",
             help="If present, this condition must be satisfied before the update of the record."),
-        'filter_id': fields.many2one('ir.filters', string='Filter',
-            ondelete='restrict',
-            domain="[('model_id', '=', model_id.model)]",
+        'filter_pre_domain': fields.char(string='Before Update Domain', help="If present, this condition must be satisfied before the update of the record."),
+        'filter_id': fields.many2one(
+            'ir.filters', string='Filter',
+            ondelete='restrict', domain="[('model_id', '=', model_id.model)]",
             help="If present, this condition must be satisfied before executing the action rule."),
+        'filter_domain': fields.char(string='Domain', help="If present, this condition must be satisfied before executing the action rule."),
         'last_run': fields.datetime('Last Run', readonly=1, copy=False),
     }
 
@@ -114,21 +116,31 @@ class base_action_rule(osv.osv):
             clear_fields = ['filter_pre_id']
         return {'value': dict.fromkeys(clear_fields, False)}
 
-    def _filter(self, cr, uid, action, action_filter, record_ids, context=None):
-        """ filter the list record_ids that satisfy the action filter """
-        if record_ids and action_filter:
-            assert action.model == action_filter.model_id, "Filter model different from action rule model"
-            model = self.pool[action_filter.model_id]
-            domain = [('id', 'in', record_ids)] + eval(action_filter.domain)
-            ctx = dict(context or {})
-            ctx.update(eval(action_filter.context))
-            record_ids = model.search(cr, uid, domain, context=ctx)
+    def onchange_filter_pre_id(self, cr, uid, ids, filter_pre_id, context=None):
+        ir_filter = self.pool['ir.filters'].browse(cr, uid, filter_pre_id, context=context)
+        return {'value': {'filter_pre_domain': ir_filter.domain}}
+
+    def onchange_filter_id(self, cr, uid, ids, filter_id, context=None):
+        ir_filter = self.pool['ir.filters'].browse(cr, uid, filter_id, context=context)
+        return {'value': {'filter_domain': ir_filter.domain}}
+
+    def _filter(self, cr, uid, action, action_filter, record_ids, domain=False, context=None):
+        """ Filter the list record_ids that satisfy the domain or the action filter. """
+        if record_ids and (domain is not False or action_filter):
+            if domain is not False:
+                new_domain = [('id', 'in', record_ids)] + eval(domain)
+                ctx = context
+            elif action_filter:
+                assert action.model == action_filter.model_id, "Filter model different from action rule model"
+                new_domain = [('id', 'in', record_ids)] + eval(action_filter.domain)
+                ctx = dict(context or {})
+                ctx.update(eval(action_filter.context))
+            record_ids = self.pool[action.model].search(cr, uid, new_domain, context=ctx)
         return record_ids
 
     def _process(self, cr, uid, action, record_ids, context=None):
         """ process the given action on the records """
         model = self.pool[action.model_id.model]
-
         # modify records
         values = {}
         if 'date_action_last' in model._all_columns:
@@ -184,7 +196,7 @@ class base_action_rule(osv.osv):
 
                 # check postconditions, and execute actions on the records that satisfy them
                 for action in action_model.browse(cr, uid, action_ids, context=context):
-                    if action_model._filter(cr, uid, action, action.filter_id, [new_id], context=context):
+                    if action_model._filter(cr, uid, action, action.filter_id, [new_id], domain=action.filter_domain, context=context):
                         action_model._process(cr, uid, action, [new_id], context=context)
                 return new_id
 
@@ -211,14 +223,14 @@ class base_action_rule(osv.osv):
                 # check preconditions
                 pre_ids = {}
                 for action in actions:
-                    pre_ids[action] = action_model._filter(cr, uid, action, action.filter_pre_id, ids, context=context)
+                    pre_ids[action] = action_model._filter(cr, uid, action, action.filter_pre_id, ids, domain=action.filter_pre_domain, context=context)
 
                 # call original method
                 write.origin(self, cr, uid, ids, vals, context=context, **kwargs)
 
                 # check postconditions, and execute actions on the records that satisfy them
                 for action in actions:
-                    post_ids = action_model._filter(cr, uid, action, action.filter_id, pre_ids[action], context=context)
+                    post_ids = action_model._filter(cr, uid, action, action.filter_id, pre_ids[action], domain=action.filter_domain, context=context)
                     if post_ids:
                         action_model._process(cr, uid, action, post_ids, context=context)
                 return True
@@ -301,12 +313,13 @@ class base_action_rule(osv.osv):
                 last_run = get_datetime(action.last_run)
             else:
                 last_run = datetime.utcfromtimestamp(0)
-
             # retrieve all the records that satisfy the action's condition
             model = self.pool[action.model_id.model]
             domain = []
             ctx = dict(context)
-            if action.filter_id:
+            if action.filter_domain:
+                domain = eval(action.context)
+            elif action.filter_id:
                 domain = eval(action.filter_id.domain)
                 ctx.update(eval(action.filter_id.context))
                 if 'lang' not in ctx:
index 2087d51..8e5ac4a 100644 (file)
                         </group>
                         <notebook>
                             <page string="Conditions">
-                                <group>
+                                <group attrs="{'invisible': [('model', '!=', False)]}">
+                                    <p><b>Please choose the document type before setting the conditions.</b></p>
+                                </group>
+                                <group attrs="{'invisible': [('model', '=', False)]}">
                                     <field name="kind" required="1"
                                         on_change="onchange_kind(kind)"/>
-                                    <field name="filter_pre_id"
-                                        domain="[('model_id','=',model), ('user_id', '=', False)]"
-                                        context="{'default_model_id': model}"
-                                        attrs="{'invisible': [('kind', '!=', 'on_write')]}"/>
-                                    <field name="filter_id"
-                                        domain="[('model_id','=',model), ('user_id', '=', False)]"
-                                        context="{'default_model_id': model}"/>
+                                    <label for="filter_pre_id" attrs="{'invisible': [('kind', '!=', 'on_write')]}"/>
+                                    <div attrs="{'invisible': [('kind', '!=', 'on_write')]}">
+                                        <field name="filter_pre_domain" widget="char_domain" options="{'model_field': 'model'}"
+                                            class="oe_inline"/>
+                                        <div class="oe_edit_only oe_inline">Set selection based on a search filter:
+                                            <field name="filter_pre_id" domain="[('model_id', '=', model), '|', ('user_id', '=', uid), ('user_id', '=', False)]"
+                                                class="oe_inline" context="{'default_model_id': model}"
+                                                on_change="onchange_filter_pre_id(filter_pre_id, context)"/></div>
+                                    </div>
+                                    <label for="filter_id"/>
+                                    <div>
+                                        <field name="filter_domain" widget="char_domain" options="{'model_field': 'model'}"
+                                            class="oe_inline"/>
+                                        <div class="oe_edit_only oe_inline">Set selection based on a search filter:
+                                            <field name="filter_id" domain="[('model_id', '=', model), '|', ('user_id', '=', uid), ('user_id', '=', False)]"
+                                                class="oe_inline" context="{'default_model_id': model}"
+                                                on_change="onchange_filter_id(filter_id, context)"/></div>
+                                    </div>
                                     <field name="trg_date_id"
                                         attrs="{'invisible': [('kind', '!=', 'on_time')], 'required': [('kind', '=', 'on_time')]}"/>
                                     <label for="trg_date_range" string="Delay After Trigger Date"
                                     <field name="trg_date_calendar_id" class="oe_inline"
                                         attrs="{'invisible': ['|', ('trg_date_id','=',False), ('trg_date_range_type', '!=', 'day')]}"/>
                                 </group>
-                                <p>
-                                    Select when the action must be run, and add filters and/or timing conditions.
-                                    <br/>
-                                    In order to create a new filter:
-                                    <ul>
+                                <div attrs="{'invisible': [('model', '=', False)]}">
+                                    <p>Select when the action must be run, and choose records and/or timing conditions.</p>
+                                    <p groups="base.group_no_one">You may also use filters instead of choosing records. In order to create a new filter:</p>
+                                    <ul groups="base.group_no_one">
                                         <li>Go to your "Related Document Model" page and set the filter parameters in the "Search" view (Example of filter based on Leads/Opportunities: Creation Date "is equal to" 01/01/2012)</li>
                                         <li>In this same "Search" view, select the menu "Save Current Filter", enter the name (Ex: Create the 01/01/2012) and add the option "Share with all users"</li>
                                     </ul>
-                                    The filter must therefore be available in this page.
-                                </p>
+                                </div>
                             </page>
                             <page string="Actions">
                                 <group name="action_field" col="4" string="Fields to Change">
index d77211a..797ac77 100644 (file)
@@ -21,7 +21,7 @@
             <field name="model_id" ref="model_crm_lead"/>
             <field name="sequence">1</field>
             <field name="kind">on_time</field>
-            <field name="filter_id" ref="filter_draft_lead"/>
+            <field name="filter_domain">[('stage_id.sequence', '=', 1)]</field>
             <field name="trg_date_id" ref="field_crm_lead_create_date"/>
             <field name="trg_date_range">5</field>
             <field name="trg_date_range_type">day</field>