Search code examples
pythonodooodoo-8

Change boolean field from parent class to child class - Odoo v8


Consider this:

@api.multi
@api.onchange('order_lines', 'order_lines.is_book_block', '')
@api.constrains('order_lines', 'order_lines.isbn')
def check_quantity(self):
    location = self.printer_book_block.property_stock_supplier.id
    for rec in self:
        if rec.order_lines:
            for line in rec.order_lines:
                if line.qty > line.isbn.with_context({ 'location': location, }).qty_available >= 0:#line.isbn.qty_available in location:
                    rec.write({'state': 'awaitingraw'})
                else:
                    rec.write({'state': 'work_in_progress', 'is_book_block': True})

When there is enough product quantity (isbn) on the specified location, change state of the document to work_in_progess and also change Boolean field is_book_block to True.

The state field is on the parent model:

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')
order_lines = 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")
state = fields.Selection([
        ('draft','Draft'),
        ('awaitingraw','Awaiting raw materials'),
        ('work_in_progress','Print in Progress'),
        ('delivered','Delivered'),
        ('cancel','Cancel'),
    ], string="State")

The is_book_block field is on the child class One2many order_lines field:

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")
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")

There are also other two fields is_binding and is_edging.

Anyways, knowing one is sufficient to figure out the other two (I guess, lol) so, since state is on the parent class, it works nicely, the state of the record actually changes, however, while there is no syntax error with is_book_block it should change to True, but it doesn't, so, I think this is because the method is looping on order_lines but it changes things on parent class only (bsi.production.order).

Any ideas?


Solution

  • From what i understand the is_book_blockis in the line when you loop through lines every line is a record it self you call write if you want to set more than field or just change that field:

      # when you change just one field no need for write just 
      rec.state = 'work_in_progress' # is enough
      # because rec.state will trigger write method
      # but for more than one field use write to trigger it only one time
      # line is a record too you can call write also if you want
      line.is_book_block = True
    

    One thing remove order_lines.is_book_blockfrom onchange decorator because you will trigger an infinitive call for the the method :

      @api.onchange('order_lines')