1
votes

I would like to make a filter on a Many2one field in Odoo 8. This is for the stock module.

I have created extra fields where the user can enter additional information. Now we want to filter the available fields that appear in the dropdown, or when clicking the "more" butten to show only the additional fields for that product.

This is the code for the stock.production.lot model When product_id is updated, then the domain filter should be changed.

class StockProductionLot(models.Model):
    _inherit = "stock.production.lot"
    lot_lot_additional_fields = fields.One2many("lot.lot.additional.fields", "stock_production_lot")

    @api.onchange("product_id")
    def onchange_product_id(self):
        res = {}
        cat_fields = self.product_id.categ_id.lot_fields_category.lot_additional_fields
        ids = []
        for item in cat_fields:
            ids.append(item.id)
        if self.product_id:
            res["domain"] = {"lot_additional_fields": [("id", "in", "ids")]}
        return res

This is the model to connect the additional fields model to the lot number model. lot_additional_fields should be updated here.

class LotLotAdditionalFields(models.Model):
    _name = "lot.lot.additional.fields"
    value = fields.Char("Value")
    stock_production_lot = fields.Many2one("stock.production.lot", string="Lot/Serial Number")
    lot_additional_fields = fields.Many2one("lot.additional.fields", string="Additional field")

If someone could help me to solve this I would be very greatful.

======================= EDIT =============================

I have added the code to stock.production.lot

class StockProductionLot(models.Model):
    _inherit = "stock.production.lot"
    lot_lot_additional_fields = fields.One2many("lot.lot.additional.fields", "stock_production_lot")
    lot_additional_fields = fields.Many2one("lot.additional.fields", string="Lot additional fields")
    remarks = fields.Html("General remarks")

    @api.onchange('product_id')
    def onchange_product_id(self):
        res = {}
        if self.product_id:
            ids = self.product_id.categ_id.lot_fields_category.lot_additional_fields.mapped('id')
            res['domain'] = {'lot_lot_additional_fields': [('lot_additional_fields', 'in', ids)]}
        return res

to lot.additional.fields I have added product_id:

class LotAdditionalFields(models.Model):
    _name = "lot.additional.fields"
    name = fields.Char("Name", required=True)
    type = fields.Selection(
        [("int", "Numerical"), ("string", "Alfanumerical"), ("boolean", "Checkbox"), ("date", "Date")], required=True)
    mandatory = fields.Boolean("Mandatory field")
    display_order = fields.Integer("Display Order")
    lot_field_category = fields.Many2many("lot.field.category", string="Field Category", required=True)
    lot_lot_additional_fields = fields.One2many("lot.lot.additional.fields", "lot_additional_fields")
    product_id = fields.Many2one("product.product", string="Product ID")

lot_lot_additional_fields I have left the same:

class LotLotAdditionalFields(models.Model):
    _name = "lot.lot.additional.fields"
    value = fields.Char("Value")
    stock_production_lot = fields.Many2one("stock.production.lot", string="Lot/Serial Number")
    lot_additional_fields = fields.Many2one("lot.additional.fields", string="Additional field")

I will also add the xml code:

 <record id="view_production_lot_form" model="ir.ui.view">
            <field name="name">Stock Production Lot Form</field>
            <field name="model">stock.production.lot</field>
            <field name="inherit_id" ref="stock.view_production_lot_form"/>
            <field name="arch" type="xml">
                <page string="Products" position="after">
                    <page string="Additional Fields">
                        <field name="lot_lot_additional_fields" >
                            <tree editable="bottom">
                                <field name="lot_additional_fields"  />
                                <field name="value"/>
                            </tree>
                        </field>
                        <h3>General remarks</h3>
                        <field name="remarks"/>
                    </page>
                </page>
            </field>
    </record>
1

1 Answers

3
votes

You have to take into account that in the line res["domain"] = {"lot_additional_fields": [("id", "in", "ids")]} you are altering the domain of the model stock.production.lot, which by the way, seems that doesn't have any field named lot_additional_fields (it has a field named lot_lot_additional_fields instead).

@api.onchange('product_id')
def onchange_product_id(self):
    res = {}
    if self.product_id:
        ids = self.product_id.categ_id.lot_fields_category.lot_additional_fields.mapped('id')
        res['domain'] = {'lot_lot_additional_fields': [('lot_additional_fields', 'in', ids)]}
    return res

I was reading your code and now I'm sure that the code I wrote here is the right code you wanted to get in your attempt. However, I don't have any information about the views and the class lot.additional.fields, only about stock.production.lot and lot.lot.additional.fields, and I guess (if I understood well what you want) that this is not going to work (modification of domain in a view is not going to modify the domain of other different view) unless you have a Many2one field pointing to product_id in the lot.additional.fields class (which I can't see here).

EDIT

Ok, first correct me if I'm wrong: in your stock_production_lot form view, you see the tree of the field lot_lot_additional_fields. Here, if you open the dropdown of the field lot_additional_fields, you only want to be able to select those lot_additional_fields which belong to the same lot_fields_category of the categ_id of the product_id of the current stock_production_lot, don't you?

In this case, try this code:

Python (put this onchange inside of your lot.lot.additional.fields class)

@api.onchange('stock_production_lot')
def onchange_stock_production_lot(self):
    res = {}
    if stock_production_lot:
        ids = self.stock_production_lot.product_id.categ_id.lot_fields_category.lot_additional_fields.mapped('id')
        res['domain'] = {
            'lot_additional_fields': [('id', 'in', ids)]}
        }
    return res

XML (modify your view_production_lot_form code and write this one)

<record id="view_production_lot_form" model="ir.ui.view">
    <field name="name">Stock Production Lot Form</field>
    <field name="model">stock.production.lot</field>
    <field name="inherit_id" ref="stock.view_production_lot_form"/>
    <field name="arch" type="xml">
        <page string="Products" position="after">
            <page string="Additional Fields">
                <field name="lot_lot_additional_fields" widget="one2many_list" context="{'default_stock_production_lot': active_id}">
                    <tree editable="bottom">
                        <field name="stock_production_lot" invisible="1"/>
                        <field name="lot_additional_fields"/>
                        <field name="value"/>
                    </tree>
                </field>
                <h3>General remarks</h3>
                <field name="remarks"/>
            </page>
        </page>
    </field>
</record>