[FIX] mrp: always show post inventory button

The inventory button was shown or hide depending of the product valuation.
As the valuation was previously stored on the stock moves and posting
split the stock moves. Fifo and Avco valuation was not well computed.
The migration to stock valuation layer fixed this behavior. This
commit shows the post inventory button as soon as there are some
finished move to be posted.

task : 54665

closes odoo/odoo#41781

X-original-commit: 5dfa3f817d3a9f47a863a587569a862a40c7d159
Signed-off-by: William Henrotin <Whenrow@users.noreply.github.com>
This commit is contained in:
William Henrotin
2019-12-10 12:41:06 +00:00
parent 9debcaf377
commit 9503f463e3
5 changed files with 278 additions and 11 deletions
+2 -5
View File
@@ -368,13 +368,10 @@ class MrpProduction(models.Model):
any_quantity_done = any([m.quantity_done > 0 for m in order.move_raw_ids])
order.unreserve_visible = not any_quantity_done and already_reserved
@api.depends('move_raw_ids.quantity_done', 'move_finished_ids.quantity_done', 'is_locked')
@api.depends('move_finished_ids.quantity_done', 'move_finished_ids.state', 'is_locked')
def _compute_post_visible(self):
for order in self:
if order.product_tmpl_id._is_cost_method_standard():
order.post_visible = order.is_locked and any((x.quantity_done > 0 and x.state not in ['done', 'cancel']) for x in order.move_raw_ids | order.move_finished_ids)
else:
order.post_visible = order.is_locked and any((x.quantity_done > 0 and x.state not in ['done', 'cancel']) for x in order.move_finished_ids)
order.post_visible = order.is_locked and any((x.quantity_done > 0 and x.state not in ['done', 'cancel']) for x in order.move_finished_ids)
@api.depends('workorder_ids.state', 'move_finished_ids', 'move_finished_ids.quantity_done', 'is_locked')
def _get_produced_qty(self):
+1
View File
@@ -2,3 +2,4 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import test_mrp_account
from . import test_bom_price
from . import test_valuation_layers
@@ -0,0 +1,275 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
""" Implementation of "INVENTORY VALUATION TESTS (With valuation layers)" spreadsheet. """
from odoo.addons.stock_account.tests.test_stockvaluationlayer import TestStockValuationCommon
from odoo.tests import Form
class TestMrpValuationCommon(TestStockValuationCommon):
@classmethod
def setUpClass(cls):
super(TestMrpValuationCommon, cls).setUpClass()
cls.component_category = cls.env['product.category'].create(
{'name': 'category2'}
)
cls.component = cls.env['product.product'].create({
'name': 'component1',
'type': 'product',
'categ_id': cls.component_category.id,
})
cls.bom = cls.env['mrp.bom'].create({
'product_id': cls.product1.id,
'product_tmpl_id': cls.product1.product_tmpl_id.id,
'product_uom_id': cls.uom_unit.id,
'product_qty': 1.0,
'type': 'normal',
'bom_line_ids': [
(0, 0, {'product_id': cls.component.id, 'product_qty': 1})
]})
def _make_mo(self, bom, quantity=1):
mo_form = Form(self.env['mrp.production'])
mo_form.product_id = bom.product_id
mo_form.bom_id = bom
mo_form.product_qty = quantity
mo = mo_form.save()
mo.action_confirm()
return mo
def _produce(self, mo, quantity=0):
produce_form = Form(self.env['mrp.product.produce'].with_context({
'active_id': mo.id,
'active_ids': [mo.id],
}))
if quantity:
produce_form.qty_producing = quantity
product_produce = produce_form.save()
product_produce.do_produce()
class TestMrpValuationStandard(TestMrpValuationCommon):
def test_fifo_fifo_1(self):
self.component.product_tmpl_id.categ_id.property_cost_method = 'fifo'
self.product1.product_tmpl_id.categ_id.property_cost_method = 'fifo'
self._make_in_move(self.component, 1, 10)
self._make_in_move(self.component, 1, 20)
mo = self._make_mo(self.bom, 2)
self._produce(mo, 1)
mo.post_inventory()
self.assertEqual(self.component.value_svl, 20)
self.assertEqual(self.product1.value_svl, 10)
self.assertEqual(self.component.quantity_svl, 1)
self.assertEqual(self.product1.quantity_svl, 1)
self._produce(mo)
mo.button_mark_done()
self.assertEqual(self.component.value_svl, 0)
self.assertEqual(self.product1.value_svl, 30)
self.assertEqual(self.component.quantity_svl, 0)
self.assertEqual(self.product1.quantity_svl, 2)
def test_fifo_fifo_2(self):
self.component.product_tmpl_id.categ_id.property_cost_method = 'fifo'
self.product1.product_tmpl_id.categ_id.property_cost_method = 'fifo'
self._make_in_move(self.component, 1, 10)
self._make_in_move(self.component, 1, 20)
mo = self._make_mo(self.bom, 2)
self._produce(mo)
mo.button_mark_done()
self.assertEqual(self.component.value_svl, 0)
self.assertEqual(self.product1.value_svl, 30)
self.assertEqual(self.component.quantity_svl, 0)
self.assertEqual(self.product1.quantity_svl, 2)
self._make_out_move(self.product1, 1)
self.assertEqual(self.product1.value_svl, 15)
def test_fifo_avco_1(self):
self.component.product_tmpl_id.categ_id.property_cost_method = 'fifo'
self.product1.product_tmpl_id.categ_id.property_cost_method = 'average'
self._make_in_move(self.component, 1, 10)
self._make_in_move(self.component, 1, 20)
mo = self._make_mo(self.bom, 2)
self._produce(mo, 1)
mo.post_inventory()
self.assertEqual(self.component.value_svl, 20)
self.assertEqual(self.product1.value_svl, 10)
self.assertEqual(self.component.quantity_svl, 1)
self.assertEqual(self.product1.quantity_svl, 1)
self._produce(mo)
mo.button_mark_done()
self.assertEqual(self.component.value_svl, 0)
self.assertEqual(self.product1.value_svl, 30)
self.assertEqual(self.component.quantity_svl, 0)
self.assertEqual(self.product1.quantity_svl, 2)
def test_fifo_avco_2(self):
self.component.product_tmpl_id.categ_id.property_cost_method = 'fifo'
self.product1.product_tmpl_id.categ_id.property_cost_method = 'average'
self._make_in_move(self.component, 1, 10)
self._make_in_move(self.component, 1, 20)
mo = self._make_mo(self.bom, 2)
self._produce(mo)
mo.button_mark_done()
self.assertEqual(self.component.value_svl, 0)
self.assertEqual(self.product1.value_svl, 30)
self.assertEqual(self.component.quantity_svl, 0)
self.assertEqual(self.product1.quantity_svl, 2)
self._make_out_move(self.product1, 1)
self.assertEqual(self.product1.value_svl, 15)
def test_fifo_std_1(self):
self.component.product_tmpl_id.categ_id.property_cost_method = 'fifo'
self.product1.product_tmpl_id.categ_id.property_cost_method = 'standard'
self.product1.standard_price = 8.8
self._make_in_move(self.component, 1, 10)
self._make_in_move(self.component, 1, 20)
mo = self._make_mo(self.bom, 2)
self._produce(mo, 1)
mo.post_inventory()
self.assertEqual(self.component.value_svl, 20)
self.assertEqual(self.product1.value_svl, 8.8)
self.assertEqual(self.component.quantity_svl, 1)
self.assertEqual(self.product1.quantity_svl, 1)
self._produce(mo)
mo.button_mark_done()
self.assertEqual(self.component.value_svl, 0)
self.assertEqual(self.product1.value_svl, 8.8 * 2)
self.assertEqual(self.component.quantity_svl, 0)
self.assertEqual(self.product1.quantity_svl, 2)
def test_fifo_std_2(self):
self.component.product_tmpl_id.categ_id.property_cost_method = 'fifo'
self.product1.product_tmpl_id.categ_id.property_cost_method = 'standard'
self.product1.standard_price = 8.8
self._make_in_move(self.component, 1, 10)
self._make_in_move(self.component, 1, 20)
mo = self._make_mo(self.bom, 2)
self._produce(mo)
mo.button_mark_done()
self.assertEqual(self.component.value_svl, 0)
self.assertEqual(self.product1.value_svl, 8.8 * 2)
self.assertEqual(self.component.quantity_svl, 0)
self.assertEqual(self.product1.quantity_svl, 2)
self._make_out_move(self.product1, 1)
self.assertEqual(self.product1.value_svl, 8.8)
def test_std_avco_1(self):
self.component.product_tmpl_id.categ_id.property_cost_method = 'standard'
self.product1.product_tmpl_id.categ_id.property_cost_method = 'average'
self.component.standard_price = 8.8
self._make_in_move(self.component, 1)
self._make_in_move(self.component, 1)
mo = self._make_mo(self.bom, 2)
self._produce(mo, 1)
mo.post_inventory()
self.assertEqual(self.component.value_svl, 8.8)
self.assertEqual(self.product1.value_svl, 8.8)
self.assertEqual(self.component.quantity_svl, 1)
self.assertEqual(self.product1.quantity_svl, 1)
self._produce(mo)
mo.button_mark_done()
self.assertEqual(self.component.value_svl, 0)
self.assertEqual(self.product1.value_svl, 8.8 * 2)
self.assertEqual(self.component.quantity_svl, 0)
self.assertEqual(self.product1.quantity_svl, 2)
def test_std_avco_2(self):
self.component.product_tmpl_id.categ_id.property_cost_method = 'standard'
self.product1.product_tmpl_id.categ_id.property_cost_method = 'average'
self.component.standard_price = 8.8
self._make_in_move(self.component, 1)
self._make_in_move(self.component, 1)
mo = self._make_mo(self.bom, 2)
self._produce(mo)
mo.button_mark_done()
self.assertEqual(self.component.value_svl, 0)
self.assertEqual(self.product1.value_svl, 8.8 * 2)
self.assertEqual(self.component.quantity_svl, 0)
self.assertEqual(self.product1.quantity_svl, 2)
self._make_out_move(self.product1, 1)
self.assertEqual(self.product1.value_svl, 8.8)
def test_std_std_1(self):
self.component.product_tmpl_id.categ_id.property_cost_method = 'standard'
self.product1.product_tmpl_id.categ_id.property_cost_method = 'standard'
self.component.standard_price = 8.8
self.product1.standard_price = 7.2
self._make_in_move(self.component, 1)
self._make_in_move(self.component, 1)
mo = self._make_mo(self.bom, 2)
self._produce(mo, 1)
mo.post_inventory()
self.assertEqual(self.component.value_svl, 8.8)
self.assertEqual(self.product1.value_svl, 7.2)
self.assertEqual(self.component.quantity_svl, 1)
self.assertEqual(self.product1.quantity_svl, 1)
self._produce(mo)
mo.button_mark_done()
self.assertEqual(self.component.value_svl, 0)
self.assertEqual(self.product1.value_svl, 7.2 * 2)
self.assertEqual(self.component.quantity_svl, 0)
self.assertEqual(self.product1.quantity_svl, 2)
def test_std_std_2(self):
self.component.product_tmpl_id.categ_id.property_cost_method = 'standard'
self.product1.product_tmpl_id.categ_id.property_cost_method = 'standard'
self.component.standard_price = 8.8
self.product1.standard_price = 7.2
self._make_in_move(self.component, 1)
self._make_in_move(self.component, 1)
mo = self._make_mo(self.bom, 2)
self._produce(mo)
mo.button_mark_done()
self.assertEqual(self.component.value_svl, 0)
self.assertEqual(self.product1.value_svl, 7.2 * 2)
self.assertEqual(self.component.quantity_svl, 0)
self.assertEqual(self.product1.quantity_svl, 2)
self._make_out_move(self.product1, 1)
self.assertEqual(self.product1.value_svl, 7.2)
def test_avco_avco_1(self):
self.component.product_tmpl_id.categ_id.property_cost_method = 'average'
self.product1.product_tmpl_id.categ_id.property_cost_method = 'average'
self._make_in_move(self.component, 1, 10)
self._make_in_move(self.component, 1, 20)
mo = self._make_mo(self.bom, 2)
self._produce(mo, 1)
mo.post_inventory()
self.assertEqual(self.component.value_svl, 15)
self.assertEqual(self.product1.value_svl, 15)
self.assertEqual(self.component.quantity_svl, 1)
self.assertEqual(self.product1.quantity_svl, 1)
self._produce(mo)
mo.button_mark_done()
self.assertEqual(self.component.value_svl, 0)
self.assertEqual(self.product1.value_svl, 30)
self.assertEqual(self.component.quantity_svl, 0)
self.assertEqual(self.product1.quantity_svl, 2)
def test_avco_avco_2(self):
self.component.product_tmpl_id.categ_id.property_cost_method = 'average'
self.product1.product_tmpl_id.categ_id.property_cost_method = 'average'
self._make_in_move(self.component, 1, 10)
self._make_in_move(self.component, 1, 20)
mo = self._make_mo(self.bom, 2)
self._produce(mo)
mo.button_mark_done()
self.assertEqual(self.component.value_svl, 0)
self.assertEqual(self.product1.value_svl, 30)
self.assertEqual(self.component.quantity_svl, 0)
self.assertEqual(self.product1.quantity_svl, 2)
self._make_out_move(self.product1, 1)
self.assertEqual(self.product1.value_svl, 15)
-3
View File
@@ -580,9 +580,6 @@ class ProductTemplate(models.Model):
relation="stock.location.route", string="Category Routes",
related='categ_id.total_route_ids', readonly=False)
def _is_cost_method_standard(self):
return True
@api.depends(
'product_variant_ids',
'product_variant_ids.stock_move_ids.product_qty',
-3
View File
@@ -64,9 +64,6 @@ class ProductTemplate(models.Model):
# -------------------------------------------------------------------------
# Misc.
# -------------------------------------------------------------------------
def _is_cost_method_standard(self):
return self.categ_id.property_cost_method == 'standard'
def _get_product_accounts(self):
""" Add the stock accounts related to product to the result of super()
@return: dictionary which contains information regarding stock accounts and super (income+expense accounts)