From 9c5ff301b8567dc37371c519895c4133071975b7 Mon Sep 17 00:00:00 2001 From: jbeficent Date: Wed, 23 Mar 2016 16:18:47 +0100 Subject: [PATCH] [FIX] various fixes as per peer review --- stock_inventory_revaluation/models/product.py | 15 +- .../models/stock_inventory_revaluation.py | 187 +++++++++--------- .../tests/test_stock_inventory_revaluation.py | 71 +++++-- .../stock_inventory_revaluation_view.xml | 4 +- 4 files changed, 167 insertions(+), 110 deletions(-) diff --git a/stock_inventory_revaluation/models/product.py b/stock_inventory_revaluation/models/product.py index c523ca54f..ece98eb99 100644 --- a/stock_inventory_revaluation/models/product.py +++ b/stock_inventory_revaluation/models/product.py @@ -12,14 +12,15 @@ class ProductCategory(models.Model): property_inventory_revaluation_increase_account_categ = fields.Many2one( 'account.account', string='Valuation Increase Account', company_dependent=True, - help="Define the G/L accounts to be used as the balancing account in " - "the transaction created by the revaluation. The G/L Increase " - "Account is used when the inventory value is increased due to " - "the revaluation.") + help="Define the Financial Accounts to be used as the balancing " + "account in the transaction created by the revaluation. " + "The Valuation Increase Account is used when the inventory value " + "is increased due to the revaluation.") property_inventory_revaluation_decrease_account_categ = fields.Many2one( 'account.account', string='Valuation Decrease Account', company_dependent=True, - help="Define the G/L accounts to be used as the balancing account in " - "the transaction created by the revaluation. The G/L Decrease " - "Account is used when the inventory value is decreased.") + help="Define the Financial Accounts to be used as the balancing " + "account in the transaction created by the revaluation. " + "The Valuation Decrease Account is used when the inventory value " + "is decreased.") diff --git a/stock_inventory_revaluation/models/stock_inventory_revaluation.py b/stock_inventory_revaluation/models/stock_inventory_revaluation.py index 31409d55d..c26ccee6d 100644 --- a/stock_inventory_revaluation/models/stock_inventory_revaluation.py +++ b/stock_inventory_revaluation/models/stock_inventory_revaluation.py @@ -23,30 +23,35 @@ class StockInventoryRevaluation(models.Model): res = self.env['account.journal'].search([('type', '=', 'general')]) return res and res[0] or False - @api.one + @api.multi def _get_product_template_qty(self): - self.qty_available = 0 - for prod_variant in self.product_template_id.product_variant_ids: - self.qty_available += prod_variant.qty_available + for revaluation in self: + revaluation.qty_available = 0 + for prod_variant in \ + revaluation.product_template_id.product_variant_ids: + revaluation.qty_available += prod_variant.qty_available - @api.one + @api.multi def _calc_product_template_value(self): - qty_available = 0 - current_value = 0.0 quant_obj = self.env['stock.quant'] - for prod_variant in self.product_template_id.product_variant_ids: - qty_available += prod_variant.qty_available - if self.product_template_id.cost_method == 'real': - quants = quant_obj.search([('product_id', '=', - prod_variant.id), - ('location_id.usage', '=', - 'internal')]) - for quant in quants: - current_value += quant.cost - else: - current_value = \ - self.product_template_id.standard_price * qty_available - self.current_value = current_value + for revaluation in self: + qty_available = 0 + current_value = 0.0 + for prod_variant in \ + revaluation.product_template_id.product_variant_ids: + qty_available += prod_variant.qty_available + if revaluation.product_template_id.cost_method == 'real': + quants = quant_obj.search([('product_id', '=', + prod_variant.id), + ('location_id.usage', '=', + 'internal')]) + for quant in quants: + current_value += quant.cost + else: + current_value = \ + revaluation.product_template_id.standard_price * \ + qty_available + revaluation.current_value = current_value name = fields.Char('Reference', help="Reference for the journal entry", @@ -167,26 +172,27 @@ class StockInventoryRevaluation(models.Model): "the transaction created by the revaluation. The Decrease " "Account is used when the inventory value is decreased.") - move_id = fields.Many2one('account.move', 'Account move', readonly=True, - copy=False) + account_move_id = fields.Many2one('account.move', 'Account move', + readonly=True, copy=False) reval_quant_ids = fields.One2many('stock.inventory.revaluation.quant', 'revaluation_id', string='Revaluation line quants') - @api.one + @api.multi @api.depends("product_template_id", "product_template_id.standard_price") def _calc_current_cost(self): - self.current_cost = self.product_template_id.standard_price + for revaluation in self: + revaluation.current_cost = revaluation.product_template_id.standard_price - @api.one + @api.multi @api.constrains('product_template_id', 'company_id') def _check_is_stockable(self): - if self.product_template_id.type != 'product': - raise UserError(_('Configuration error!\nThe product must be ' - 'stockable.')) + for revaluation in self: + if revaluation.product_template_id.type != 'product': + raise UserError(_('Configuration error!\nThe product must be ' + 'stockable.')) - @api.one @api.onchange("product_template_id") def _onchange_product_template_id(self): if self.product_template_id: @@ -214,10 +220,10 @@ class StockInventoryRevaluation(models.Model): def _prepare_debit_move_line_data(self, amount, account_id, prod_id): return { 'name': self.name, - 'date': self.move_id.date, + 'date': self.account_move_id.date, 'product_id': prod_id, 'account_id': account_id, - 'move_id': self.move_id.id, + 'move_id': self.account_move_id.id, 'debit': amount } @@ -225,10 +231,10 @@ class StockInventoryRevaluation(models.Model): def _prepare_credit_move_line_data(self, amount, account_id, prod_id): return { 'name': self.name, - 'date': self.move_id.date, + 'date': self.account_move_id.date, 'product_id': prod_id, 'account_id': account_id, - 'move_id': self.move_id.id, + 'move_id': self.account_move_id.id, 'credit': amount } @@ -238,11 +244,11 @@ class StockInventoryRevaluation(models.Model): move_data = self._prepare_move_data(timenow) datas = self.env['product.template'].get_product_accounts( self.product_template_id.id) - self.move_id = self.env['account.move'].create(move_data).id + self.account_move_id = self.env['account.move'].create(move_data).id move_line_obj = self.env['account.move.line'] if not self.decrease_account_id or not self.increase_account_id: - raise UserError(_("Please add a Increase Account and " + raise UserError(_("Please add an Increase Account and " "a Decrease Account.")) for prod_variant in self.product_template_id.product_variant_ids: @@ -262,52 +268,56 @@ class StockInventoryRevaluation(models.Model): move_line_data = self._prepare_credit_move_line_data( abs(amount_diff), credit_account_id, prod_variant.id) move_line_obj.create(move_line_data) - if self.move_id.journal_id.entry_posted: - self.move_id.post() + if self.account_move_id.journal_id.entry_posted: + self.account_move_id.post() - @api.one + @api.multi def post(self): + for revaluation in self: + amount_diff = 0.0 + if revaluation.product_template_id.cost_method == 'real': + for reval_quant in revaluation.reval_quant_ids: + amount_diff += reval_quant.get_total_value() + reval_quant.write_new_cost() + if amount_diff == 0.0: + return True + else: + if revaluation.product_template_id.cost_method \ + in ['standard', 'average']: - amount_diff = 0.0 - if self.product_template_id.cost_method == 'real': - for reval_quant in self.reval_quant_ids: - amount_diff += reval_quant.get_total_value() - reval_quant.write_new_cost() - if amount_diff == 0.0: - return True - else: - if self.product_template_id.cost_method in ['standard', 'average']: + if revaluation.revaluation_type == 'price_change': + diff = revaluation.current_cost - revaluation.new_cost + amount_diff = revaluation.qty_available * diff + else: + amount_diff = \ + revaluation.current_value - revaluation.new_value + if revaluation.new_value < 0: + raise UserError( + _("The new value for product %s cannot " + "be negative" % + revaluation.product_template_id.name)) + if revaluation.qty_available <= 0.0: + raise UserError( + _("Cannot do an inventory value change if the " + "quantity available for product %s " + "is 0 or negative" % + revaluation.product_template_id.name)) - if self.revaluation_type == 'price_change': - diff = self.current_cost - self.new_cost - amount_diff = self.qty_available * diff - else: - amount_diff = self.current_value - self.new_value - if self.new_value < 0: - raise UserError(_("The new value for product %s " - "cannot be negative" - % self.product_template_id.name)) - if self.qty_available <= 0.0: - raise UserError( - _("Cannot do an inventory value change if the " - "quantity available for product %s " - "is 0 or negative" % - self.product_template_id.name)) + if revaluation.revaluation_type == 'price_change': + revaluation.old_cost = revaluation.current_cost + revaluation.product_template_id.write( + {'standard_price': revaluation.new_cost}) + else: + revaluation.old_cost = revaluation.current_cost + revaluation.old_value = revaluation.current_value + value_diff = revaluation.current_value - \ + revaluation.new_value + new_cost = value_diff / revaluation.qty_available + revaluation.product_template_id.write( + {'standard_price': new_cost}) - if self.revaluation_type == 'price_change': - self.old_cost = self.current_cost - self.product_template_id.write({'standard_price': - self.new_cost}) - else: - self.old_cost = self.current_cost - self.old_value = self.current_value - value_diff = self.current_value - self.new_value - new_cost = value_diff / self.qty_available - self.product_template_id.write({'standard_price': - new_cost}) - - if self.product_template_id.valuation == 'real_time': - self._create_accounting_entry(amount_diff) + if revaluation.product_template_id.valuation == 'real_time': + revaluation._create_accounting_entry(amount_diff) @api.model def create(self, values): @@ -330,18 +340,19 @@ class StockInventoryRevaluation(models.Model): @api.multi def button_cancel(self): moves = self.env['account.move'] - if self.move_id: - moves += self.move_id - for reval_quant in self.reval_quant_ids: - reval_quant.quant_id.write({'cost': reval_quant.old_cost}) - if moves: - # second, invalidate the move(s) - moves.button_cancel() - # delete the move this revaluation was pointing to - # Note that the corresponding move_lines and move_reconciles - # will be automatically deleted too - moves.unlink() - self.write({'state': 'cancel'}) + for revaluation in self: + if revaluation.account_move_id: + moves += revaluation.account_move_id + for reval_quant in revaluation.reval_quant_ids: + reval_quant.quant_id.write({'cost': reval_quant.old_cost}) + if moves: + # second, invalidate the move(s) + moves.button_cancel() + # delete the move this revaluation was pointing to + # Note that the corresponding move_lines and move_reconciles + # will be automatically deleted too + moves.unlink() + revaluation.state = 'cancel' return True diff --git a/stock_inventory_revaluation/tests/test_stock_inventory_revaluation.py b/stock_inventory_revaluation/tests/test_stock_inventory_revaluation.py index eb3dd08ae..6ecf286d6 100644 --- a/stock_inventory_revaluation/tests/test_stock_inventory_revaluation.py +++ b/stock_inventory_revaluation/tests/test_stock_inventory_revaluation.py @@ -24,6 +24,8 @@ class TestStockInventoryRevaluation(TransactionCase): env['stock.inventory.revaluation.quant'] self.get_quant_model = self.\ env['stock.inventory.revaluation.get.quant'] + self.mass_post_model = self.\ + env['stock.inventory.revaluation.mass.post'] self.stock_change_model = self.env['stock.change.product.qty'] self.stock_lot_model = self.env['stock.production.lot'] self.stock_location_model = self.env['stock.location'] @@ -174,6 +176,21 @@ class TestStockInventoryRevaluation(TransactionCase): for reval_quant in revaluation.reval_quant_ids: reval_quant.new_cost = 8.0 + def _mass_post(self, revaluations): + """Get Quants for Inventory Revaluation between the date supplied.""" + context = { + 'active_id': revaluations[0], + 'active_ids': [rev.id for rev in revaluations], + 'active_model': 'stock.inventory.revaluation', + } + mass_post_wiz = self.mass_post_model.with_context(context).create({}) + mass_post_wiz.process() + return True + + def test_defaults(self): + """Test default methods""" + self.assertNotEqual(self.reval_model._default_journal(), False) + def test_inventory_revaluation_price_change_real(self): """Test that the inventory is revaluated when the inventory price for a product managed under real costing method is @@ -194,16 +211,13 @@ class TestStockInventoryRevaluation(TransactionCase): expected_result = (10.00 - 8.00) * 20.00 - for move_line in invent_price_change_real.move_id.line_id: + for move_line in invent_price_change_real.account_move_id.line_id: if move_line.debit: self.assertEqual(move_line.debit, expected_result, 'Incorrect inventory revaluation for ' 'type Price Change.') - def test_inventory_revaluation_price_change_average(self): - """Test that the inventory is revaluated when the - inventory price for a product managed under average costing method is - changed.""" + def create_inventory_revaluation_price_change_average(self): revaluation_type = 'price_change' # Create an Inventory Revaluation for average cost product invent_price_change_average = self._create_inventory_revaluation( @@ -211,30 +225,61 @@ class TestStockInventoryRevaluation(TransactionCase): self.product_average.product_tmpl_id) # Post the inventory revaluation invent_price_change_average.new_cost = 8.00 + return invent_price_change_average + + def test_inventory_revaluation_price_change_average(self): + """Test that the inventory is revaluated when the + inventory price for a product managed under average costing method is + changed.""" + invent_price_change_average = \ + self.create_inventory_revaluation_price_change_average() invent_price_change_average.button_post() expected_result = (10.00 - 8.00) * 20.00 - for move_line in invent_price_change_average.move_id.line_id: + for move_line in invent_price_change_average.account_move_id.line_id: if move_line.debit: self.assertEqual(move_line.debit, expected_result, 'Incorrect inventory revaluation for ' 'type Price Change.') - def test_inventory_revaluation_value_change(self): - """Test that the inventory is revaluated when the - inventory price for any product is changed.""" + def create_inventory_revaluation_value_change(self): # Create an Inventory Revaluation for value change for average # cost product revaluation_type = 'inventory_value' - invent_average = self._create_inventory_revaluation( + invent_value_change = self._create_inventory_revaluation( self.journal, revaluation_type, self.product_average.product_tmpl_id) - invent_average.new_value = 100.00 + invent_value_change.new_value = 100.00 + return invent_value_change + def test_inventory_revaluation_value_change(self): + """Test that the inventory is revaluated when the + inventory price for any product is changed.""" + invent_value_change = self.create_inventory_revaluation_value_change() # Post the inventory revaluation - invent_average.button_post() + invent_value_change.button_post() - for move_line in invent_average.move_id.line_id: + for move_line in invent_value_change.account_move_id.line_id: if move_line.debit: self.assertEqual(move_line.debit, 100.0, 'Incorrect inventory revaluation for ' 'type Inventory Debit/Credit.') + + def test_mass_post(self): + """Test mass post""" + revaluations = [] + + # Create an Inventory Revaluation for average cost product + invent_price_change_average = \ + self.create_inventory_revaluation_price_change_average() + revaluations.append(invent_price_change_average) + + # Create an Inventory Revaluation for real cost product + invent_value_change = self.create_inventory_revaluation_value_change() + revaluations.append(invent_value_change) + + # Post the inventory revaluation using wizard + self._mass_post(revaluations) + + # Check that both inventory valuations are now posted + self.assertEqual(invent_price_change_average.state, 'posted') + self.assertEqual(invent_value_change.state, 'posted') diff --git a/stock_inventory_revaluation/views/stock_inventory_revaluation_view.xml b/stock_inventory_revaluation/views/stock_inventory_revaluation_view.xml index 8cbc47506..e3f16924f 100644 --- a/stock_inventory_revaluation/views/stock_inventory_revaluation_view.xml +++ b/stock_inventory_revaluation/views/stock_inventory_revaluation_view.xml @@ -67,7 +67,7 @@ - + @@ -119,7 +119,7 @@ - +