简体   繁体   中英

Add computed field to custom filter as stored field in ODOO

customer_count = fields.Char(string='Customer Count', compute='cust_count')

class ResBuilding(models.Model):
    _name = "res.partner.building"
    _description = "Customer BUilding"
    _order = "id desc"

    region_id = fields.Many2one('res.state.city', string='Region', required=True, ondelete='cascade')
    city_id = fields.Many2one('city.covered.area', string='Area', required=True, ondelete='cascade')
    name = fields.Char(string='Name', required=True, translate=True, copy=False)
    image = fields.Binary(string="Building image")
    latitude = fields.Char(string='Latitude')
    customer_count = fields.Char(string='Customer Count', compute='cust_count', store=True)
    longitude = fields.Char(string='Longitude')
    active = fields.Boolean(string='Active', default=True, track_visibility='onchange')
    partner_ids = fields.One2many('res.partner', 'building_id', string='Customer List', readonly=True)

    @api.multi
    @api.depends('partner_ids')
    def cust_count(self):
        for record in self:
            count = self.env['res.partner'].search_count([('building_id', '=', record.id)])
            record.customer_count = count

    @api.multi
    def name_get(self):
        result = []
        for route in self:
            name = route.city_id.name + '-' + route.name
            result.append((route.id, name))
        return result

    @api.multi
    def write(self, vals):
        res = super(ResBuilding, self).write(vals)
        print(vals, self.id)
        if vals.get('city_id'):
            customers = self.env['res.partner'].search([('building_id', '=', self.id)])
            for c in customers:
                c.living_area = vals.get('city_id')
        return res

    @api.multi
    @api.depends('latitude', 'longitude')
    def on_change_location(self):
        for li in self:
            if li.latitude and li.longitude:
                self.env.cr.execute("""update res_partner set location_latitude=""" + str(li.latitude) + """,
                                        location_longitude=""" + str(li.longitude) + """where building_id=""" + str(
                    li.id))
        return True

    @api.multi
    def write(self, vals):
        res = super(ResBuilding, self).write(vals)
        self.on_change_region_id()
        return res

    @api.multi
    @api.depends('region_id')
    def on_change_region_id(self):
        for li in self:
            if li.region_id:
                self.env.cr.execute(
                    """update res_partner set city_id=""" + str(li.region_id.id) + """where building_id=""" + str(
                        li.id))
        return True



I want find the customer count in a specific building based on building id. and want The coustomer_count field to be added to the add custom filter

by this code,i am getting count correctly. But the field customer_count does not appear in custom filter

when i add store=True, the field is coming in custom filter but the count is coming as 0.

Your code is not correct, even with storing the field.

customer_count = fields.Char(
    string='Customer Count', compute='cust_count', store=True)

@api.multi
@api.depends()
def cust_count(self):
    for record in self:
        count = self.env['res.partner'].search_count([('building_id', '=', record.id)])
        record.customer_count = count

Always use for each loops in compute methods, because in case of multi relational fields using your building model or just by presenting this computed field in a list of your building model will lead to a multi recordset behind self .

But that's not all. There should be a possibility to trigger the recomputation of the field and if easy to do using depends . Right now i don't see any easy possibility, because i don't know all your relations and workflows. Without storing the field you probably don't need that, but it would work there too.

So what to do to trigger a recomputation? Just work up from the other site of the relation: res.partner . Override it's write, create and unlink method to trigger the recomputation "manually".

class ResPartner(models.Model):
    _inherit = "res.partner"

    @api.multi
    def write(self, values):
        old_buildings = self.mapped('building_id')
        res = super(ResPartner, self).write(values)
        if 'building_id' in values:
            new_buildings = self.mapped('building_id')
            trigger_buildings = old_buildins | new_buildings
            trigger_buildings.cust_count()
        return res

    @api.model
    def create(self, values):
        partner = super(ResPartner, self).create(values)
        partner.building_id.cust_count()
        return partner

    @api.multi
    def unlink(self):
        buildings = self.mapped('building_id')
        res = super(ResPartner, self).unlink()
        buildings.cust_count()
        return res

Another way is to use a one2many field on your building model in relation to res.partner and fill depends with it, like depends('partner_ids') . But in my experience one2many fields in such and lot of other situations tend to lead to bad performance.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM