diff --git a/addons/stock_account/__manifest__.py b/addons/stock_account/__manifest__.py index ac9a54f1af0..e1fdfa3b079 100644 --- a/addons/stock_account/__manifest__.py +++ b/addons/stock_account/__manifest__.py @@ -31,6 +31,7 @@ Dashboard / Reports for Warehouse Management includes: 'views/res_config_settings_views.xml', 'data/product_data.xml', 'views/product_views.xml', + 'views/stock_valuation_layer_views.xml', ], 'test': [ ], diff --git a/addons/stock_account/models/__init__.py b/addons/stock_account/models/__init__.py index 134f11a2a47..9a0a869ef08 100644 --- a/addons/stock_account/models/__init__.py +++ b/addons/stock_account/models/__init__.py @@ -11,4 +11,6 @@ from . import stock_move from . import stock_inventory from . import stock_location from . import stock_move_line +from . import stock_picking +from . import stock_valuation_layer from . import res_config_settings diff --git a/addons/stock_account/models/account_move.py b/addons/stock_account/models/account_move.py index 97aebcdec29..be94260a407 100644 --- a/addons/stock_account/models/account_move.py +++ b/addons/stock_account/models/account_move.py @@ -10,3 +10,5 @@ class AccountMove(models.Model): _inherit = 'account.move' stock_move_id = fields.Many2one('stock.move', string='Stock Move') + stock_valuation_layer_ids = fields.One2many('stock.valuation.layer', 'account_move_id', string='Stock Valuation Layer') + diff --git a/addons/stock_account/models/product.py b/addons/stock_account/models/product.py index 8fb6a9ff916..b3c57626f97 100644 --- a/addons/stock_account/models/product.py +++ b/addons/stock_account/models/product.py @@ -60,6 +60,26 @@ class ProductProduct(models.Model): stock_fifo_manual_move_ids = fields.Many2many( 'stock.move', compute='_compute_stock_value') + value_svl = fields.Float(compute='_compute_value_svl') + quantity_svl = fields.Float(compute='_compute_value_svl') + stock_valuation_layer_ids = fields.One2many('stock.valuation.layer', 'product_id') + + @api.depends('stock_valuation_layer_ids') + def _compute_value_svl(self): + """Compute `value_svl` and `quantity_svl`.""" + domain = [ + ('product_id', 'in', self.ids), + ('company_id', '=', self.env.user.company_id.id) + ] + if self.env.context.get('to_date'): + to_date = fields.Datetime.to_datetime(self.env.context['to_date']) + domain.append(('create_date', '<=', to_date)) + groups = self.env['stock.valuation.layer'].read_group(domain, ['value:sum', 'quantity:sum'], ['product_id']) + for group in groups: + product = self.browse(group['product_id'][0]) + product.value_svl = group['value'] + product.quantity_svl = group['quantity'] + @api.multi def do_change_standard_price(self, new_price, account_id): """ Changes the Standard Price of Product and creates an account move accordingly.""" diff --git a/addons/stock_account/models/stock_move.py b/addons/stock_account/models/stock_move.py index 68ef562a79b..2d0ef85cb09 100644 --- a/addons/stock_account/models/stock_move.py +++ b/addons/stock_account/models/stock_move.py @@ -20,6 +20,7 @@ class StockMove(models.Model): remaining_qty = fields.Float(copy=False) remaining_value = fields.Float(copy=False) account_move_ids = fields.One2many('account.move', 'stock_move_id') + stock_valuation_layer_ids = fields.One2many('stock.valuation.layer', 'stock_move_id') @api.multi def action_get_account_moves(self): diff --git a/addons/stock_account/models/stock_picking.py b/addons/stock_account/models/stock_picking.py new file mode 100644 index 00000000000..cf3dba44314 --- /dev/null +++ b/addons/stock_account/models/stock_picking.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import models + + +class StockPicking(models.Model): + _inherit = 'stock.picking' + + def action_view_stock_valuation_layers(self): + self.ensure_one() + domain = [('id', 'in', self.move_lines.stock_valuation_layer_ids.ids)] + action = self.env.ref('stock_account.stock_valuation_layer_action').read()[0] + return dict(action, domain=domain) + diff --git a/addons/stock_account/models/stock_valuation_layer.py b/addons/stock_account/models/stock_valuation_layer.py new file mode 100644 index 00000000000..4eb6f5c86a8 --- /dev/null +++ b/addons/stock_account/models/stock_valuation_layer.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models + + +class StockValuationLayer(models.Model): + """Stock Valuation Layer""" + + _name = 'stock.valuation.layer' + _description = 'Stock Valuation Layer' + _order = 'create_date, id' + + _rec_name = 'product_id' + + company_id = fields.Many2one('res.company', 'Company', readonly=True, required=True) + product_id = fields.Many2one('product.product', 'Product', readonly=True, required=True) + quantity = fields.Float('Quantity', digits=0, help='Quantity', readonly=True) + uom_id = fields.Many2one(related='product_id.uom_id', readonly=True, required=True) + currency_id = fields.Many2one('res.currency', 'Currency', related='company_id.currency_id', readonly=True, required=True) + unit_cost = fields.Monetary('Unit Value', readonly=True) + value = fields.Monetary('Total Value', readonly=True) + remaining_qty = fields.Float(digits=0, readonly=True) + description = fields.Char('Description', readonly=True) + stock_move_id = fields.Many2one('stock.move', 'Stock Move', readonly=True) + account_move_id = fields.Many2one('account.move', 'Journal Entry', readonly=True) + diff --git a/addons/stock_account/security/ir.model.access.csv b/addons/stock_account/security/ir.model.access.csv index 3f44363eb0c..0a9ba71377d 100644 --- a/addons/stock_account/security/ir.model.access.csv +++ b/addons/stock_account/security/ir.model.access.csv @@ -2,3 +2,4 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink access_account_account_stock_manager,account.account stock manager,account.model_account_account,stock.group_stock_manager,1,0,0,0 access_stock_picking_invoicing_payments,stock.picking,stock.model_stock_picking,account.group_account_invoice,1,1,1,0 access_stock_move_invoicing_payments,stock.move,model_stock_move,account.group_account_invoice,1,1,1,0 +access_stock_valuation_layer,access_stock_valuation_layer,model_stock_valuation_layer,stock.group_stock_manager,1,1,1,0 diff --git a/addons/stock_account/security/stock_account_security.xml b/addons/stock_account/security/stock_account_security.xml index ea222a0fcc5..4a6f38ee61a 100644 --- a/addons/stock_account/security/stock_account_security.xml +++ b/addons/stock_account/security/stock_account_security.xml @@ -12,6 +12,13 @@ ['|',('company_id','=',False),('company_id', 'in', company_ids)] --> + + + Stock Valuation Layer Multicompany + + + [('company_id','=',user.company_id.id)] + diff --git a/addons/stock_account/views/stock_valuation_layer_views.xml b/addons/stock_account/views/stock_valuation_layer_views.xml new file mode 100644 index 00000000000..bbcbc1af797 --- /dev/null +++ b/addons/stock_account/views/stock_valuation_layer_views.xml @@ -0,0 +1,95 @@ + + + stock.valuation.layer.form + stock.valuation.layer + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + stock.valuation.layer.tree + stock.valuation.layer + + + + + + + + + + + + + + + stock.valuation.layer.tree + stock.valuation.layer + + + + + + + + + Stock Valuation + ir.actions.act_window + stock.valuation.layer + tree,form + form + + + {'search_default_group_by_product_id': 1} + + + There is no valuation layers. Valuation layers are created when some product moves should impact the valuation of the stock. + + + + + + stock.valuation.layer.picking + stock.picking + + + + + + + + +
+ There is no valuation layers. Valuation layers are created when some product moves should impact the valuation of the stock. +