Consider these four models:
class bsi_production_order(models.Model):
_name = 'bsi.production.order'
name = fields.Char('Reference', required=True, index=True, copy=False, readonly='True', default='New')
date = fields.Date(string="Production Date")
production_type = fields.Selection([
('budgeted','Budgeted'),
('nonbudgeted','Non Budgeted'),
('direct','Direct Order'),
], string='Type of Order', index=True,
track_visibility='onchange', copy=False,
help=" ")
notes = fields.Text(string="Notes")
order_lines = fields.One2many('bsi.production.order.lines', 'production_order', states={'finished': [('readonly', True)], 'cancel': [('readonly', True)]}, string="Order lines", copy=True)
print_orders = fields.One2many('bsi.print.order', 'production_orders', string="Print Orders")
class bsi_production_order_lines(models.Model):
_name = 'bsi.production.order.lines'
production_order = fields.Many2one('bsi.production.order', string="Production Orders")
isbn = fields.Many2one('product.product', string="ISBN", domain="[('is_isbn', '=', True)]")
qty = fields.Float(string="Quantity")
consumed_qty = fields.Float(string="Consumed quantity")
remaining_qty = fields.Float(string="Remaining quantity", compute="_remaining_func")
@api.onchange('qty', 'consumed_qty')
def _remaining_func(self):
if self.qty or self.consumed_qty:
self.remaining_qty = self.qty +(-self.consumed_qty)
class bsi_print_order(models.Model):
_name = 'bsi.print.order'
name = fields.Char('Reference', required=True, index=True, copy=False, readonly='True', default='New')
date = fields.Date(string="Print Date")
origin = fields.Char(string="Origin")
production_orders = fields.Many2one('bsi.production.order', ondelete='cascade', string="Production Order")
order_lines = fields.One2many('bsi.print.order.lines', 'print_order', string="Order lines")
class bsi_print_order_lines(models.Model):
_name = 'bsi.print.order.lines'
print_order = fields.Many2one('bsi.print.order', string="Print Order")
production_orders = fields.Many2one('bsi.production.order', ondelete='cascade', string="Production 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")
@api.onchange('qty', 'consumed_qty')
def _remaining_func(self):
if self.consumed_qty or self.qty:
self.remaining_qty = self.qty +(-self.consumed_qty)
So, production order has production order lines, and print order has it's order lines too (One2many order_lines
fields)
There is a method on both of them, which are both called _remaining_func_
.
These are OK for remaining_qty
fields, but consumed_qty
should be inter-related between production.order and print.order.
So, for example, if qty
on bsi.production.order.lines
is 10, (There are other methods which create a bsi.print.order
from production order), and on bsi.print.order
I put on qty
the value 5, the original 10 should be 5 on bsi.production.order.line
, I think with a similar method like _remaining_func_
I can achieve this, but I'm kind of confused on how to do this between the two models.
Any ideas?
If further explanation is needed, please let me know.
What you want is impossible to manage unless the relationship between bsi.production.order
and bsi.print.order
is 1:1, but in your case it seems that a production order can have many print orders. I give you the example:
You could create a Many2one
field in bsi.print.order.line
pointing to bsi.production.order.line
:
class bsi_print_order_lines(models.Model):
_name = 'bsi.print.order.lines'
po_line_related = fields.Many2one('bsi.production.order.lines', ondelete='cascade', string="Production Order Line Related")
And each time a print line is created, you can easily create the related production line (you have all data you need):
@api.model
def create(self, vals):
print_line = super(bsi_print_order_lines, self).create(vals)
po_line_vals = {
'production_order': print_line.print_order.production_orders.id,
'isbn': print_line.isbn,
'qty': print_line.qty,
'consumed_qty': print_line.consumed_qty,
'remaining_qty': print_line.remaining_qty,
}
po_line = self.env['bsi.production.order.lines'].create(po_line_vals)
return print_line
But you have to do the same the other way round (this time overwriting bsi.production.order.lines
ORM create method), and here you find the problem:
@api.model
def create(self, vals):
po_line = super(bsi_production_order_lines, self).create(vals)
print_line_vals = {
'production_orders': po_line.production_order.id,
'po_line_related': po_line.id,
'isbn': po_line.isbn,
'qty': po_line.qty,
'consumed_qty': po_line.consumed_qty,
'remaining_qty': po_line.remaining_qty,
'print_order': '???????' # You cannot know which print order you have to write here since a production order can have several ones...
}
print_line = self.env['bsi.print.order.lines'].create(print_line_vals)
return po_line
If the relationship between bsi.production.order
and bsi.print.order
was 1:1, you could get the print order with search
(because you would be sure that is going to return only one record):
@api.model
def create(self, vals):
po_line = super(bsi_production_order_lines, self).create(vals)
print_order = self.env['bsi.print.order'].search([
('production_orders', '=', po_line.production_order.id)
]).ensure_one()
print_line_vals = {
'production_orders': po_line.production_order.id,
'po_line_related': po_line.id,
'isbn': po_line.isbn,
'qty': po_line.qty,
'consumed_qty': po_line.consumed_qty,
'remaining_qty': po_line.remaining_qty,
'print_order': print_order.id,
}
print_line = self.env['bsi.print.order.lines'].create(print_line_vals)
return po_line
And this way you would have your production lines and print lines related, and you would have to overwrite write
and unlink
methods too to control when a line is modified or removed, do the same for its "twin" (it would be easy to find it thanks to the new Many2one
field named po_line_related
).
Of course it would not be a beautiful solution but I think it is the only one (using Odoo API) for your Entity-Relationship Diagram.