refactor: Reimplement packaging_qty as a computed and inversed field, allowing product_qty to always be visible.

This commit is contained in:
Suherdy Yacob 2026-02-10 08:23:41 +07:00
parent 076fb7ee0b
commit 5762c3896b
2 changed files with 22 additions and 17 deletions

View File

@ -1,23 +1,27 @@
from odoo import api, fields, models from odoo import api, fields, models
from odoo.tools import float_compare
class MrpProduction(models.Model): class MrpProduction(models.Model):
_inherit = 'mrp.production' _inherit = 'mrp.production'
packaging_id = fields.Many2one('mrp.packaging', string='Packaging', domain="[('product_tmpl_id', '=', product_tmpl_id)]", check_company=True) packaging_id = fields.Many2one('mrp.packaging', string='Packaging', domain="[('product_tmpl_id', '=', product_tmpl_id)]", check_company=True)
packaging_qty = fields.Float('Quantity Packaging', default=0.0) packaging_qty = fields.Float('Quantity Packaging', compute='_compute_packaging_qty', inverse='_inverse_packaging_qty', store=True, readonly=False)
@api.onchange('packaging_qty') @api.depends('product_qty', 'packaging_id', 'packaging_id.qty')
def _onchange_packaging_qty(self): def _compute_packaging_qty(self):
if self.packaging_id and self.packaging_qty: for record in self:
self.product_qty = self.packaging_id.qty * self.packaging_qty if record.packaging_id and record.packaging_id.qty:
new_qty = record.product_qty / record.packaging_id.qty
@api.onchange('packaging_id') if float_compare(new_qty, record.packaging_qty, precision_digits=2) != 0:
def _onchange_packaging_id(self): record.packaging_qty = new_qty
if self.packaging_id and self.packaging_id.qty:
self.packaging_qty = self.product_qty / self.packaging_id.qty
else: else:
self.packaging_qty = 0.0 record.packaging_qty = 0.0
def _inverse_packaging_qty(self):
for record in self:
if record.packaging_id and record.packaging_id.qty:
record.product_qty = record.packaging_qty * record.packaging_id.qty
qty_producing_packaging = fields.Float('Quantity Producing Packaging', compute='_compute_qty_producing_packaging', inverse='_inverse_qty_producing_packaging', digits=(16, 2)) qty_producing_packaging = fields.Float('Quantity Producing Packaging', compute='_compute_qty_producing_packaging', inverse='_inverse_qty_producing_packaging', digits=(16, 2))
@ -116,8 +120,8 @@ class MrpProduction(models.Model):
@api.onchange('product_qty') @api.onchange('product_qty')
def _onchange_product_qty(self): def _onchange_product_qty(self):
if self.packaging_id and self.packaging_id.qty: # Merge finished move lines if quantity changes
self.packaging_qty = self.product_qty / self.packaging_id.qty self._merge_finished_move_lines()
@api.onchange('bom_id') @api.onchange('bom_id')
def _onchange_bom_id(self): def _onchange_bom_id(self):
@ -125,5 +129,5 @@ class MrpProduction(models.Model):
if self.bom_id and self.bom_id.packaging_id: if self.bom_id and self.bom_id.packaging_id:
self.packaging_id = self.bom_id.packaging_id self.packaging_id = self.bom_id.packaging_id
self.packaging_qty = self.bom_id.packaging_qty self.packaging_qty = self.bom_id.packaging_qty
# Trigger qty calculation # Trigger qty calculation (handled by compute)
self._onchange_packaging_qty() # self._onchange_packaging_qty()

View File

@ -5,12 +5,13 @@
<field name="model">mrp.production</field> <field name="model">mrp.production</field>
<field name="inherit_id" ref="mrp.mrp_production_form_view"/> <field name="inherit_id" ref="mrp.mrp_production_form_view"/>
<field name="arch" type="xml"> <field name="arch" type="xml">
<xpath expr="//label[@for='product_qty']" position="attributes"> <!-- Removed invisible attributes to allow editing product_qty with packaging -->
<!-- <xpath expr="//label[@for='product_qty']" position="attributes">
<attribute name="invisible">packaging_id</attribute> <attribute name="invisible">packaging_id</attribute>
</xpath> </xpath>
<xpath expr="//div[@name='qty']" position="attributes"> <xpath expr="//div[@name='qty']" position="attributes">
<attribute name="invisible">packaging_id</attribute> <attribute name="invisible">packaging_id</attribute>
</xpath> </xpath> -->
<xpath expr="//div[@name='qty']" position="after"> <xpath expr="//div[@name='qty']" position="after">
<field name="packaging_id" placeholder="Packaging" invisible="packaging_id" readonly="state in ('done', 'cancel')"/> <field name="packaging_id" placeholder="Packaging" invisible="packaging_id" readonly="state in ('done', 'cancel')"/>
<label for="packaging_qty" string="Quantity" invisible="not packaging_id"/> <label for="packaging_qty" string="Quantity" invisible="not packaging_id"/>