diff options
| -rw-r--r-- | addons/mrp/models/product.py | 14 | ||||
| -rw-r--r-- | addons/stock/models/product.py | 28 | ||||
| -rw-r--r-- | addons/stock/models/stock_inventory.py | 3 | ||||
| -rw-r--r-- | addons/stock/tests/test_product.py | 23 | ||||
| -rw-r--r-- | addons/stock_account/models/stock_move.py | 5 | ||||
| -rw-r--r-- | addons/stock_account/models/stock_valuation_layer.py | 1 | ||||
| -rw-r--r-- | addons/stock_account/views/stock_valuation_layer_views.xml | 1 |
7 files changed, 54 insertions, 21 deletions
diff --git a/addons/mrp/models/product.py b/addons/mrp/models/product.py index e61073ce8f1..6028ba24f00 100644 --- a/addons/mrp/models/product.py +++ b/addons/mrp/models/product.py @@ -30,6 +30,13 @@ class ProductTemplate(models.Model): template.used_in_bom_count = self.env['mrp.bom'].search_count( [('bom_line_ids.product_id', 'in', template.product_variant_ids.ids)]) + def write(self, values): + if 'active' in values: + self.filtered(lambda p: p.active != values['active']).with_context(active_test=False).bom_ids.write({ + 'active': values['active'] + }) + return super().write(values) + def action_used_in_bom(self): self.ensure_one() action = self.env.ref('mrp.mrp_bom_form_action').read()[0] @@ -70,6 +77,13 @@ class ProductProduct(models.Model): for product in self: product.used_in_bom_count = self.env['mrp.bom'].search_count([('bom_line_ids.product_id', '=', product.id)]) + def write(self, values): + if 'active' in values: + self.filtered(lambda p: p.active != values['active']).with_context(active_test=False).variant_bom_ids.write({ + 'active': values['active'] + }) + return super().write(values) + def get_components(self): """ Return the components list ids in case of kit product. Return the product itself otherwise""" diff --git a/addons/stock/models/product.py b/addons/stock/models/product.py index e270399ddb2..0052e4883b5 100644 --- a/addons/stock/models/product.py +++ b/addons/stock/models/product.py @@ -164,8 +164,8 @@ class Product(models.Model): domain_move_in += date_date_expected_domain_to domain_move_out += date_date_expected_domain_to - Move = self.env['stock.move'] - Quant = self.env['stock.quant'] + Move = self.env['stock.move'].with_context(active_test=False) + Quant = self.env['stock.quant'].with_context(active_test=False) domain_move_in_todo = [('state', 'in', ('waiting', 'confirmed', 'assigned', 'partially_available'))] + domain_move_in domain_move_out_todo = [('state', 'in', ('waiting', 'confirmed', 'assigned', 'partially_available'))] + domain_move_out moves_in_res = dict((item['product_id'][0], item['product_qty']) for item in Move.read_group(domain_move_in_todo, ['product_id', 'product_qty'], ['product_id'], orderby='id')) @@ -512,16 +512,11 @@ class Product(models.Model): return theoretical_quantity def write(self, values): - res = super(Product, self).write(values) - if 'active' in values and not values['active']: - products = self.mapped('orderpoint_ids').filtered(lambda r: r.active).mapped('product_id') - if products: - msg = _('You still have some active reordering rules on this product. Please archive or delete them first.') - msg += '\n\n' - for product in products: - msg += '- %s \n' % product.display_name - raise UserError(msg) - return res + if 'active' in values: + self.filtered(lambda p: p.active != values['active']).with_context(active_test=False).orderpoint_ids.write({ + 'active': values['active'] + }) + return super().write(values) def _get_rules_from_location(self, location, seen_rules=False): if not seen_rules: @@ -611,14 +606,14 @@ class ProductTemplate(models.Model): def _compute_quantities_dict(self): # TDE FIXME: why not using directly the function fields ? - variants_available = self.mapped('product_variant_ids')._product_available() + variants_available = self.with_context(active_test=False).mapped('product_variant_ids')._product_available() prod_available = {} for template in self: qty_available = 0 virtual_available = 0 incoming_qty = 0 outgoing_qty = 0 - for p in template.product_variant_ids: + for p in template.with_context(active_test=False).product_variant_ids: qty_available += variants_available[p.id]["qty_available"] virtual_available += variants_available[p.id]["virtual_available"] incoming_qty += variants_available[p.id]["incoming_qty"] @@ -711,7 +706,7 @@ class ProductTemplate(models.Model): # Be aware that the exact same function exists in product.product def action_open_quants(self): - return self.product_variant_ids.action_open_quants() + return self.with_context(active_test=False).product_variant_ids.filtered(lambda p: p.qty_available != 0).action_open_quants() def action_update_quantity_on_hand(self): advanced_option_groups = [ @@ -773,8 +768,9 @@ class ProductTemplate(models.Model): def action_product_tmpl_forecast_report(self): action = self.env.ref('stock.report_stock_quantity_action_product').read()[0] + product_ids = self.with_context(active_test=False).product_variant_ids.filtered(lambda p: p.virtual_available != 0) action['domain'] = [ - ('product_id', 'in', self.product_variant_ids.ids), + ('product_id', 'in', product_ids.ids) ] return action diff --git a/addons/stock/models/stock_inventory.py b/addons/stock/models/stock_inventory.py index a4c8766c493..c4784ccc02d 100644 --- a/addons/stock/models/stock_inventory.py +++ b/addons/stock/models/stock_inventory.py @@ -224,8 +224,9 @@ class Inventory(models.Model): domain = [('company_id', '=', self.company_id.id), ('quantity', '!=', '0'), - ('product_id.active', '=', True), ('location_id', 'in', locations_ids)] + if self.prefill_counted_quantity == 'zero': + domain.append(('product_id.active', '=', True)) if self.product_ids: domain = expression.AND([domain, [('product_id', 'in', self.product_ids.ids)]]) diff --git a/addons/stock/tests/test_product.py b/addons/stock/tests/test_product.py index d9a82f2e478..35c5bc1136e 100644 --- a/addons/stock/tests/test_product.py +++ b/addons/stock/tests/test_product.py @@ -5,6 +5,7 @@ # Copyright 2015 Camptocamp SA from odoo.addons.stock.tests.common2 import TestStockCommon +from odoo.tests.common import Form class TestVirtualAvailable(TestStockCommon): @@ -81,3 +82,25 @@ class TestVirtualAvailable(TestStockCommon): self.picking_out_2.do_unreserve() # 8 units are available again self.assertAlmostEqual(40.0, self.product_3.free_qty) + + def test_archive_product_1(self): + """`qty_available` and `virtual_available` are computed on archived products""" + self.assertTrue(self.product_3.active) + self.assertAlmostEqual(40.0, self.product_3.qty_available) + self.assertAlmostEqual(40.0, self.product_3.virtual_available) + self.product_3.active = False + self.assertAlmostEqual(40.0, self.product_3.qty_available) + self.assertAlmostEqual(40.0, self.product_3.virtual_available) + + def test_archive_product_2(self): + """Archiving a product should archive its reordering rules""" + self.assertTrue(self.product_3.active) + orderpoint_form = Form(self.env['stock.warehouse.orderpoint']) + orderpoint_form.product_id = self.product_3 + orderpoint_form.location_id = self.env.ref('stock.stock_location_stock') + orderpoint_form.product_min_qty = 0.0 + orderpoint_form.product_max_qty = 5.0 + orderpoint = orderpoint_form.save() + self.assertTrue(orderpoint.active) + self.product_3.active = False + self.assertFalse(orderpoint.active) diff --git a/addons/stock_account/models/stock_move.py b/addons/stock_account/models/stock_move.py index e82c7954624..36728170829 100644 --- a/addons/stock_account/models/stock_move.py +++ b/addons/stock_account/models/stock_move.py @@ -260,7 +260,8 @@ class StockMove(models.Model): todo_valued_moves._sanity_check_for_valuation() stock_valuation_layers |= getattr(todo_valued_moves, '_create_%s_svl' % valued_type)() - for svl in stock_valuation_layers.with_context(active_test=False): + + for svl in stock_valuation_layers: if not svl.product_id.valuation == 'real_time': continue if svl.currency_id.is_zero(svl.value): @@ -272,7 +273,7 @@ class StockMove(models.Model): # For every in move, run the vacuum for the linked product. products_to_vacuum = valued_moves['in'].mapped('product_id') company = valued_moves['in'].mapped('company_id') and valued_moves['in'].mapped('company_id')[0] or self.env.company - for product_to_vacuum in products_to_vacuum.with_context(active_test=False): + for product_to_vacuum in products_to_vacuum: product_to_vacuum._run_fifo_vacuum(company) return res diff --git a/addons/stock_account/models/stock_valuation_layer.py b/addons/stock_account/models/stock_valuation_layer.py index 1360f0f82b4..ffb96e4b773 100644 --- a/addons/stock_account/models/stock_valuation_layer.py +++ b/addons/stock_account/models/stock_valuation_layer.py @@ -13,7 +13,6 @@ class StockValuationLayer(models.Model): _rec_name = 'product_id' - active = fields.Boolean(related='product_id.active') company_id = fields.Many2one('res.company', 'Company', readonly=True, required=True) product_id = fields.Many2one('product.product', 'Product', readonly=True, required=True, check_company=True) categ_id = fields.Many2one('product.category', related='product_id.categ_id') diff --git a/addons/stock_account/views/stock_valuation_layer_views.xml b/addons/stock_account/views/stock_valuation_layer_views.xml index fc76a676907..309e6c01393 100644 --- a/addons/stock_account/views/stock_valuation_layer_views.xml +++ b/addons/stock_account/views/stock_valuation_layer_views.xml @@ -83,7 +83,6 @@ <field name="categ_id" /> <field name="product_tmpl_id" /> <separator/> - <filter string="Archived" name="inactive" domain="[('active','=',False)]"/> <group expand='0' string='Group by...'> <filter string='Product' name="group_by_product_id" context="{'group_by': 'product_id'}"/> </group> |
