[FIX] stock/mrp_landed_cost: fix domain no scalable.

Making a dynamic domain with a `allowed_xxx_ids` field is a bad idea
when the domain doesn't filter out the most of records. It can create a
performance issue, if the `allowed_xxx_ids` contains too much ids
(for 70K by example), then a lot of data will be exchange to/from server
for each onchange (500Ko, > 1 sec) which slows down all the form views.

Change it into a static domain, which slows down a little the
search of the picking but the onchange becomes very fast. Also the JS
won't parse anymore a huge `allowed_xxx_ids` fields (the form becomes
smoother).

task-2558097
This commit is contained in:
Rémy Voet (ryv)
2021-07-13 06:57:17 +00:00
parent 2461543aad
commit f329de26eb
5 changed files with 9 additions and 34 deletions
@@ -13,18 +13,6 @@ class StockLandedCost(models.Model):
mrp_production_ids = fields.Many2many(
'mrp.production', string='Manufacturing order',
copy=False, states={'done': [('readonly', True)]}, groups='mrp.group_mrp_user')
allowed_mrp_production_ids = fields.Many2many(
'mrp.production', compute='_compute_allowed_mrp_production_ids', groups='mrp.group_mrp_user')
@api.depends('company_id')
def _compute_allowed_mrp_production_ids(self):
for cost in self:
moves = self.env['stock.move'].search([
('stock_valuation_layer_ids', '!=', False),
('production_id', '!=', False),
('company_id', '=', cost.company_id.id)
])
self.allowed_mrp_production_ids = moves.production_id
@api.onchange('target_model')
def _onchange_target_model(self):
@@ -121,10 +121,12 @@ class TestStockLandedCostsMrp(ValuationReconciliationTestCommon):
landed_cost = Form(self.env['stock.landed.cost'].with_user(self.allow_user)).save()
landed_cost.target_model = 'manufacturing'
self.assertTrue(man_order.id in landed_cost.allowed_mrp_production_ids.ids)
# Check domain of the views
self.assertTrue(man_order in self.env['mrp.production'].search([
('move_finished_ids.stock_valuation_layer_ids', '!=', False), ('company_id', '=', landed_cost.company_id.id)]))
landed_cost.mrp_production_ids = [(6, 0, [man_order.id])]
landed_cost.cost_lines = [(0, 0, {'product_id': self.landed_cost.id, 'price_unit': 5.0, 'split_method': 'equal'})]
landed_cost.button_validate()
self.assertEqual(landed_cost.state, 'done')
@@ -10,11 +10,10 @@
<attribute name="groups">mrp.group_mrp_user</attribute>
</field>
<field name="picking_ids" position="after">
<field name="allowed_mrp_production_ids" invisible="1"/>
<field name="mrp_production_ids"
widget="many2many_tags" options="{'no_create_edit': True}"
attrs="{'invisible': [('target_model', '!=', 'manufacturing')]}"
domain="[('id', 'in', allowed_mrp_production_ids)]"/>
attrs="{'invisible': [('target_model', '!=', 'manufacturing')]}"
domain="[('company_id', '=', company_id), ('move_finished_ids.stock_valuation_layer_ids', '!=', False)]"/>
</field>
</field>
</record>
@@ -44,7 +44,6 @@ class StockLandedCost(models.Model):
picking_ids = fields.Many2many(
'stock.picking', string='Transfers',
copy=False, states={'done': [('readonly', True)]})
allowed_picking_ids = fields.Many2many('stock.picking', compute='_compute_allowed_picking_ids')
cost_lines = fields.One2many(
'stock.landed.cost.lines', 'cost_id', 'Cost Lines',
copy=True, states={'done': [('readonly', True)]})
@@ -79,20 +78,6 @@ class StockLandedCost(models.Model):
for cost in self:
cost.amount_total = sum(line.price_unit for line in cost.cost_lines)
@api.depends('company_id')
def _compute_allowed_picking_ids(self):
valued_picking_ids_per_company = defaultdict(list)
if self.company_id:
self.env.cr.execute("""SELECT sm.picking_id, sm.company_id
FROM stock_move AS sm
INNER JOIN stock_valuation_layer AS svl ON svl.stock_move_id = sm.id
WHERE sm.picking_id IS NOT NULL AND sm.company_id IN %s
GROUP BY sm.picking_id, sm.company_id""", [tuple(self.company_id.ids)])
for res in self.env.cr.fetchall():
valued_picking_ids_per_company[res[1]].append(res[0])
for cost in self:
cost.allowed_picking_ids = valued_picking_ids_per_company[cost.company_id.id]
@api.onchange('target_model')
def _onchange_target_model(self):
if self.target_model != 'picking':
@@ -29,9 +29,10 @@
<group>
<group>
<field name="date"/>
<field name="allowed_picking_ids" invisible="1"/>
<field name="target_model" widget="radio" invisible="1"/>
<field name="picking_ids" widget="many2many_tags" options="{'no_create_edit': True}" domain="[('id', 'in', allowed_picking_ids)]" attrs="{'invisible': [('target_model', '!=', 'picking')]}"/>
<field name="picking_ids" widget="many2many_tags"
options="{'no_create_edit': True}" attrs="{'invisible': [('target_model', '!=', 'picking')]}"
domain="[('company_id', '=', company_id), ('move_lines.stock_valuation_layer_ids', '!=', False)]"/>
</group>
<group>
<label for="account_journal_id" string="Journal"/>