Search code examples
pythonodooodoo-8

Check boolean field from parent model into lines - Odoo v8


I want to check a boolean field, from a parent class, into a child (lines) class.

class bsi_print_order(models.Model):
    _name = 'bsi.print.order'

    @api.model
    def create(self, vals):
        if vals.get('name', 'New') == 'New':
            vals['name'] = self.env['ir.sequence'].next_by_code('bsi.print.order') or '/'
        return super(bsi_print_order, self).create(vals)

    name = fields.Char('Reference', required=True, index=True, copy=False, readonly='True', default='New')
    date = fields.Date(string="Print Date",default=fields.Datetime.now)
    production_orders = fields.Many2one('bsi.production.order', ondelete='cascade', string="Production Order")
    due_date = fields.Date(string="Due Date")
    journal_entry = fields.Many2one('account.move', string="Journal Entry")
    stock_picking_id = fields.Many2one('stock.picking', string="Stock Picking")
    order_picking = fields.One2many('bsi.print.order.lines', 'print_order', string="Order lines")
    book_block = fields.Boolean(string="Book Block", default=True)
    binding = fields.Boolean(string="Binding")
    edging = fields.Boolean(string="Edging")

class bsi_print_order_lines(models.Model):
    _name = 'bsi.print.order.lines'

    print_order = fields.Many2one('bsi.print.order', string="Print Order")
    isbn = fields.Many2one('product.product', string="ISBN", domain="[('is_isbn', '=', True)]")
    qty = fields.Integer(string="Quantity")
    consumed_qty = fields.Integer(string="Quantity consumed")
    remaining_qty = fields.Float(string="Remaining quantity") #, compute="_remaining_func"
    is_book_block = fields.Boolean(string="Is Book Block Done")
    is_binding = fields.Boolean(string="Is Binding Done")
    is_edging = fields.Boolean(string="Is Edging Done")
    isbns = fields.Many2one('worksheets.isbns', string="Worksheet ISBNS")

So, when book_block button is checked, is_book_block should be automatically checked too, same with binding and edging, they should check is_binding and is_edging respectively.

These are the methods I have:

@api.depends('book_block', 'order_picking', 'order_picking.is_book_block')
def _bool_book_block(self):
    if self.book_block == True:
        order_picking.is_book_block = True
    else:
        order_picking.is_book_block = False

@api.depends('binding', 'order_picking', 'order_picking.is_binding')
def _bool_binding(self):
    if self.binding == True:
        order_picking.is_binding = True
    else:
        order_picking.is_binding = False

@api.onchange('edging', 'order_picking', 'order_picking.is_edging')
def _bool_edging(self):
    if self.edging == True:
        order_picking.is_edging == True
    else:
        order_picking.is_edging == False

But it doesn't work, I do check edging for example, and even save the document, but no changes on the boolean fields in lines.

Any ideas?


Solution

  • When you use depends the field must have a compute attribute :

       some_feild = fiels.SomeType(......., compute='method_name')
    
    
       @api.depends('some_field_2', ...)
       def method_name(self):
            # and here the function will be computed.
    

    If your field are 100% computed field, best thing in odoo that you can listen for changing in the parent class to compute the child field:

    class bsi_print_order(models.Model):
        _name = 'bsi.print.order'
        ....
    
    
    
    class bsi_print_order_lines(models.Model):
        _name = 'bsi.print.order.lines'
    
        is_book_block = fields.Boolean(string="Is Book Block Done", compute="compute_book_block")
    
        @api.depends('print_order.book_block')
        def compute_book_block(self):
    
            # in depends it's always a good this to loop
            # or use api.one with depends 
            for rec in self:
                if rec.print_order:
                    self.is_book_block = self.print_order.book_block
    

    But this is Ok only if this field is always a compute field, i mean the user will never change it's value from the UI.

    If your field is not computed and the user can change the value if he want than you need to use onchange in the parent class.

    class bsi_print_order(models.Model):
        _name = 'bsi.print.order'
        ....
    
        @api.onchange('book_block '):
        def onchange_book_block(self):
            # in onchange no need for loop 
            # because self should always have only one recod
            for line in self.order_picking:
                line.is_book_block = self.book_block