2
votes

I have a problem in ODOO 10 with a many2many relationship. I have extended res.partner this way:

class ResPartner(models.Model):
    x_bagsdesign = fields.Many2many('product.product',string='Bags Design',relation='bags_design_manufactur')

then I have extended also product.template model:

class product_template_fields(models.Model):
    _inherit = 'product.template'
    x_traders_stock = fields.Many2many(
    'res.partner', string='Traders with access to stock',relation='xtradstock_res_partner_rel')

    @api.multi
    def write(self, vals):

        record = super(product_template_fields, self).write(vals)  
        for singletrader in self.x_traders_stock:
            singletrader.x_bagsdesign = [(4,self.id)]    

        return record

This way every time a new x_traders_stock is inserted in product.template, a new x_bags_design is also created in res.partner.

BUT.. when I save a new record in product.template I get an sql error:

bad query:  INSERT INTO bags_design_manufactur (res_partner_id, product_product_id)
                    (SELECT a, b FROM unnest(ARRAY[1]) AS a, unnest(ARRAY[7]) AS b)
                    EXCEPT (SELECT res_partner_id, product_product_id FROM bags_design_manufactur WHERE res_partner_id IN (1))

I don't understand where the EXCEPT part of the sql query is coming from and how to prevent it. If anyone can help I would be grateful.. thanks!

1

1 Answers

3
votes

The error message is a bit different from expected, but I can fix some problems in your code. First of all you have to take into account that a product.product object is a variant of a product.template object, so you can have in a database many product.product objects pointing to the same product.template (e.g. a product.template is a T-shirt and a product.product is a T-shirt colour red size M). This means that you can't try to set the ID of a product.template in a field which is expecting the ID of a product.product, as you're doing here:

singletrader.x_bagsdesign = [(4,self.id)]

Of course, that mistake will not give you the message error you are receiving, there must be something wrong in other part of your code (I guess related to bags_design_manufactur model).

However, to fix the problem I told you above, you should write this:

class product_template_fields(models.Model):
    _inherit = 'product.template'

    x_traders_stock = fields.Many2many(
        comodel_name='res.partner',
        string='Traders with access to stock',
        relation='xtradstock_res_partner_rel'
    )

    @api.multi
    def write(self, vals):
        result = super(product_template_fields, self).write(vals)
        for prod_templ in self:
            products = self.env['product.product'].search([
                ('product_tmpl_id', '=', prod_templ.id),
            ])
            for singletrader in prod_templ.x_traders_stock:
                singletrader.write({
                    'x_bagsdesign': [(4, product.id) for product in products],
                })
        return result

EDIT

product.product inherits from product.template by delegation, this means that every field you create in product.template model is going to be available in product.product objects, so when you are creating the Many2many field x_traders_stock in product.template, you're creating it in product.product too, so you don't need to add records each time a x_trader is generated. Instead you should change your models:

class ResPartner(models.Model):
    x_bagsdesign_prod_templ = fields.Many2many(
        comodel_name='product.template',
        column1='partner_id',
        column2='product_tmpl_id',
        string='Bags Design',
        relation='xtradstock_res_partner_rel'
    )


class ProductTemplate(models.Model):
    _inherit = 'product.template'

    x_traders_stock = fields.Many2many(
        comodel_name='res.partner',
        column1='product_tmpl_id',
        column2='partner_id',
        string='Traders with access to stock',
        relation='xtradstock_res_partner_rel'
    )

And then, if you want to access to the product.product objects a partner has, you can do it this way:

any_partner.x_bagsdesign_prod_templ.mapped('product_variant_ids')

If you preferred it, you could even create a new related field in res.partner which brought the product.product objects a partner has.