[FIX] mrp_subcontracting_account: read price unit at validation
In a subcontracting flow, the extra_cost on the subcontracted production is read on the purchase line (via _get_price_unit() ) at the production creation. In case the price unit on this purchase line change before the validation, the stock valuation layer linked to the production will not take this new value into account. This commit ensures the price unit is the right one at validation Note: the first version of the current fix broke a use case. The test `test_tracked_compo_and_backorder` has been added to protect that use case. closes odoo/odoo#87817 X-original-commit: 1ff1b4a9a2b9ab27b29fdcac93731fa053c77cc7 Signed-off-by: William Henrotin (whe) <whe@odoo.com> Signed-off-by: Adrien Widart <awt@odoo.com> Co-authored-by: William Henrotin (whe) <whe@odoo.com> Co-authored-by: Adrien Widart <awt@odoo.com>
This commit is contained in:
committed by
Adrien Widart
co-authored by
Adrien Widart
parent
1cfac2f2cd
commit
7ef48801bb
@@ -10,6 +10,7 @@ class MrpProduction(models.Model):
|
||||
def _cal_price(self, consumed_moves):
|
||||
finished_move = self.move_finished_ids.filtered(lambda x: x.product_id == self.product_id and x.state not in ('done', 'cancel') and x.quantity_done > 0)
|
||||
# Take the price unit of the reception move
|
||||
if finished_move.move_dest_ids.is_subcontract:
|
||||
self.extra_cost = finished_move.move_dest_ids._get_price_unit()
|
||||
last_done_receipt = finished_move.move_dest_ids.filtered(lambda m: m.state == 'done')[-1:]
|
||||
if last_done_receipt.is_subcontract:
|
||||
self.extra_cost = last_done_receipt._get_price_unit()
|
||||
return super()._cal_price(consumed_moves=consumed_moves)
|
||||
|
||||
@@ -51,9 +51,11 @@ class TestAccountSubcontractingFlows(TestMrpSubcontractingCommon):
|
||||
move.product_id = self.finished
|
||||
move.product_uom_qty = 1
|
||||
picking_receipt = picking_form.save()
|
||||
picking_receipt.move_ids.price_unit = 30.0
|
||||
picking_receipt.move_ids.price_unit = 15.0
|
||||
|
||||
picking_receipt.action_confirm()
|
||||
# Suppose the additional cost changes:
|
||||
picking_receipt.move_ids.price_unit = 30.0
|
||||
picking_receipt.move_ids.quantity_done = 1.0
|
||||
picking_receipt._action_done()
|
||||
|
||||
@@ -157,6 +159,59 @@ class TestAccountSubcontractingFlows(TestMrpSubcontractingCommon):
|
||||
for layer in f_layers:
|
||||
self.assertEqual(layer.value, 100 + 50)
|
||||
|
||||
def test_tracked_compo_and_backorder(self):
|
||||
"""
|
||||
Suppose a subcontracted product P with two tracked components, P is FIFO
|
||||
Create a receipt for 10 x P, receive 5, then 3 and then 2
|
||||
"""
|
||||
self.env.ref('product.product_category_all').property_cost_method = 'fifo'
|
||||
self.comp1.tracking = 'lot'
|
||||
self.comp1.standard_price = 10
|
||||
self.comp2.tracking = 'lot'
|
||||
self.comp2.standard_price = 20
|
||||
|
||||
lot01, lot02 = self.env['stock.lot'].create([{
|
||||
'name': "Lot of %s" % product.name,
|
||||
'product_id': product.id,
|
||||
'company_id': self.env.company.id,
|
||||
} for product in (self.comp1, self.comp2)])
|
||||
|
||||
receipt_form = Form(self.env['stock.picking'])
|
||||
receipt_form.picking_type_id = self.env.ref('stock.picking_type_in')
|
||||
receipt_form.partner_id = self.subcontractor_partner1
|
||||
with receipt_form.move_ids_without_package.new() as move:
|
||||
move.product_id = self.finished
|
||||
move.product_uom_qty = 10
|
||||
receipt = receipt_form.save()
|
||||
# add an extra cost
|
||||
receipt.move_ids.price_unit = 50
|
||||
receipt.action_confirm()
|
||||
|
||||
for qty_producing in (5, 3, 2):
|
||||
action = receipt.action_record_components()
|
||||
mo = self.env['mrp.production'].browse(action['res_id'])
|
||||
mo_form = Form(mo.with_context(**action['context']), view=action['view_id'])
|
||||
mo_form.qty_producing = qty_producing
|
||||
with mo_form.move_line_raw_ids.edit(0) as ml:
|
||||
ml.lot_id = lot01
|
||||
with mo_form.move_line_raw_ids.edit(1) as ml:
|
||||
ml.lot_id = lot02
|
||||
mo = mo_form.save()
|
||||
mo.subcontracting_record_component()
|
||||
|
||||
action = receipt.button_validate()
|
||||
if isinstance(action, dict):
|
||||
wizard = Form(self.env[action['res_model']].with_context(action['context'])).save()
|
||||
wizard.process()
|
||||
receipt = receipt.backorder_ids
|
||||
|
||||
self.assertRecordValues(self.finished.stock_valuation_layer_ids, [
|
||||
{'quantity': 5, 'value': 5 * (10 + 20 + 50)},
|
||||
{'quantity': 3, 'value': 3 * (10 + 20 + 50)},
|
||||
{'quantity': 2, 'value': 2 * (10 + 20 + 50)},
|
||||
])
|
||||
|
||||
|
||||
class TestBomPriceSubcontracting(TestBomPrice):
|
||||
|
||||
def test_01_compute_price_subcontracting_cost(self):
|
||||
|
||||
Reference in New Issue
Block a user