Search code examples
odooopenerp-7openerp-8

How to filter with the current_user fields?


I added this to the res.users model:

class res_users(osv.osv):
    _inherit = 'res.users'  

    _columns = {            
        'por_sucursal': fields.boolean('Por Sucursal', help="Es por Sucursal"), 
        'sucursal_u' : fields.many2one('sucursales', 'Sucursal', help="Selecciona la sucursal"),           
    }

    _defaults = {
        'por_sucursal': False,            
    }    

res_users()

I also have the model ordenes.orden:

class ordenes_orden(osv.Model):
    _name = 'ordenes.orden'
    _description = 'Ordenes de servicio'
    _columns = {            
        'sucursal' : fields.many2one('sucursales', 'Sucursal', help="Selecciona la sucursal", required= True),
    }        

ordenes_orden()

Where the model sucursales come from:

class sucursales(osv.Model):
    _name = 'sucursales'
    _description = 'Sucursales de la empresa'   
    _columns = {            
        'name': fields.char('Sucursal', size=50, help="Sucursal"),
    }
sucursales()

Finally I added this class as well:

class ordenes(osv.Model):
    _name = 'ordenes.orden'
    _inherit = 'ordenes.orden'

    def dame_sucursal(self, cr, uid, ids, field, arg, context=None):
        res = {}
        for obj in self.browse(cr, uid, ids, context=context):
            res[obj.id] = False
            user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
            if user and user.sucursal_u and user.por_sucursal:
                res[obj.id] = user.sucursal_u.id

        return res

    _columns = {            
        'name_suc': fields.function(dame_sucursal, type='many2one', store= True,
                                                readonly = True, relation='sucursales')
    }    

ordenes()

So I want to filter all the orders from the sucursal where are equal to the current_user's sucursal in the tree view. It works fine, but only the first time. The function field doesn't update if I change the sucursal from the current user. This is my tree view:

<record id="open_view_ordenes_sucursales" model="ir.actions.act_window">
    <field name="name">Ordenes</field>
    <field name="res_model">ordenes.orden</field>
    <field name="view_type">form</field>
    <field name="view_mode">tree,form</field>
    <field name="domain">[('sucursal','=','name_suc'),('state', 'not in', ('done','cancel'))]</field>
    <field name="view_id" ref="x_sucursal_view_tree"/>   
</record>

Solution

  • Your code cannot work because you are trying to store the succursal of the current user on the ordenes.orden records - this is impossible because multiple users may be searching the orders at the same time.

    The domain expression you used on the tree view cannot work either: ('sucursal','=','name_suc') will display only orders where the succursal is exactly named "name_suc" - it has nothing to do with the name_suc field. The right hand side of each domain term is a static literal value. You can read more about domains in the Odoo documentation.

    But there is a much simpler way to do what you want, assuming your succursales are supposed to be similar to the buit-in company concept of Odoo; you should use a similar technique to filter records: per-record security record rules (ir.rule). Try the following:

    • remove the useless name_suc column on your order, and the related domain
    • create a record rule (ir.rule) for the ordenes.orden model with the following domain value: [('sucursal', '=', user.sucursal.id)]. You can do it in the user interface to test it, or create it in your module's XML data:

      <record id="ordenes_sucursales_rule" model="ir.rule">
          <field name="name">Per sucursal rule</field>
          <field name="model_id" ref="model_ordenes_orden"/>
          <field name="domain_force">[('sucursal', '=', user.sucursal_u.id)]
          </field>
      </record>
      

      This will automatically filter the orders according to the sucursal of the users everywhere, except for the Administrator account (ID 1) that is never restricted by record rules.

      If you also want users to see orders that have no sucursal, you can modify the rule as follows:

      <record id="ordenes_sucursales_rule" model="ir.rule">
          <field name="name">Per sucursal rule</field>
          <field name="model_id" ref="model_ordenes_orden"/>
          <field name="domain_force">['|', ('sucursal', '=', False),
                                           ('sucursal', '=', user.sucursal_u.id)]
          </field>
      </record>
      

      This assumes you have a sucursal field on ordenes.orden that is a many2one to sucursales.