I'm trying to modify the BoM lines to add two custom fields: measure and unit of measure, like this:
It was the easy part, but, as you can see, PO order does not take the measure and unit of measure values from the BoM lines.
We need to take this values from BoM and split each item by measures too, not just by variants but also by measures because our vendors work with this.
How can we create this behavior? Which functions handle this?
We must take that values from the stock move from the given values
.
First, we will add both values in the respective models:
class MrpBomLine(models.Model):
_inherit = 'mrp.bom.line'
item_num = fields.Integer(_('CAD Item Position'), help=_(
"This is the item reference position into the CAD document that declares this BoM."))
measure = fields.Char(_('Measure'))
measure_uom_id = fields.Many2one(
'product.uom',
'Unit of Measure',
help="Unit of Measure (Unit of Measure) is the unit of measurement for the products measure")
class PurchaseOrderLine(models.Model):
_inherit = 'purchase.order.line'
measure = fields.Char(_('Measure'))
measure_uom_id = fields.Many2one(
'product.uom',
'Unit of Measure',
help="Unit of Measure (Unit of Measure) is the unit of measurement for the products measure"
)
We don't need to add any other thing in the mrp
model.
Second, we need to override the methods that prepare the purchase order lines, it is in the procurement rule. So, we inherit the procurement rule's model:
class ProcurementRule(models.Model):
_inherit = 'procurement.rule'
We continue with the prepare function:
@api.multi
def _prepare_purchase_order_line(
self, product_id, product_qty, product_uom, values, po, supplier
):
result = super(ProcurementRule, self)._prepare_purchase_order_line(
product_id, product_qty, product_uom, values, po, supplier
)
if values.get('move_dest_ids', False):
result['measure'] = values['move_dest_ids'].bom_line_id.measure
result['measure_uom_id'] = values['move_dest_ids'].bom_line_id.measure_uom_id.id
return result
We don't need to add the custom fields to the stock move or other function, this is because of Odoo
handle creation using a data dictionary, in this case, it is values
, inside of this value we can find all related variables and fields, bom.line
variables also, where we included the custom fields.
Until here, we solved the problem of taking the information from bom.line
to purchase.order
.
Now, we need to avoid duplicates in the purchase order, for that we will modify the _run_buy
function:
# Create Line
po_line = False
for line in po.order_line:
if line.product_id == product_id and \
line.product_uom == product_id.uom_po_id and \
values.get('move_dest_ids', False) and \
line.measure == values['move_dest_ids'].bom_line_id.measure and \
line.measure_uom_id.id == values['move_dest_ids'].bom_line_id.measure_uom_id.id:
if line._merge_in_existing_line(
product_id, product_qty, product_uom,
location_id, name, origin, values
):
vals = self._update_purchase_order_line(
product_id, product_qty, product_uom,
values, line, partner
)
po_line = line.write(vals)
break
We check first if the move_dest_ids
key exists; after, we check that the product in the order line has the same measure that the product in the BoM line, and finally we check if the measure's unit of measure is the same. Just that.
In this way we have added two custom fields in the Bom Line model and that the values of these fields are transferred from one model to another with the minimum code necessary and intervening as little as possible in the system flow.