diff --git a/stock_account_valuation_report/README.rst b/stock_account_valuation_report/README.rst new file mode 100644 index 0000000..96f7ef5 --- /dev/null +++ b/stock_account_valuation_report/README.rst @@ -0,0 +1,80 @@ +============================== +Stock Account Valuation Report +============================== + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fstock--logistics--reporting-lightgray.png?logo=github + :target: https://github.com/OCA/stock-logistics-reporting/tree/11.0/stock_account_valuation_report + :alt: OCA/stock-logistics-reporting +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/stock-logistics-reporting-11-0/stock-logistics-reporting-11-0-stock_account_valuation_report + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/151/11.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + +When you trigger a report of inventory valuation, and you use +perpetual inventory, you should be able to reconcile the valuation +from an inventory perspective with the valuation +from an accounting perspective. + +This module changes the report in *Inventory / Reporting / Inventory Valuation* +to display separately the Quantity and Value of each product for the +Inventory and the Accounting systems . + +**Table of contents** + +.. contents:: + :local: + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Eficent + +Contributors +~~~~~~~~~~~~ + +* Jordi Ballester Alomar + +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +This module is part of the `OCA/stock-logistics-reporting `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/stock_account_valuation_report/__init__.py b/stock_account_valuation_report/__init__.py new file mode 100644 index 0000000..aee8895 --- /dev/null +++ b/stock_account_valuation_report/__init__.py @@ -0,0 +1,2 @@ +from . import models +from . import wizards diff --git a/stock_account_valuation_report/__manifest__.py b/stock_account_valuation_report/__manifest__.py new file mode 100644 index 0000000..8935752 --- /dev/null +++ b/stock_account_valuation_report/__manifest__.py @@ -0,0 +1,19 @@ +# Copyright 2018 Eficent Business and IT Consulting Services, S.L. +# () +# Copyright 2018 Aleph Objects, Inc. +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +{ + "name": "Stock Account Valuation Report", + "version": "11.0.1.0.0", + "summary": "Improves logic of the Inventory Valuation Report", + "author": "Eficent, Odoo Community Association (OCA)", + "website": "https://github.com/OCA/stock-logistics-reporting", + "category": "Warehouse Management", + "depends": ["stock_account"], + "license": "AGPL-3", + "data": [ + "views/product_product_views.xml", + ], + 'installable': True, +} diff --git a/stock_account_valuation_report/models/__init__.py b/stock_account_valuation_report/models/__init__.py new file mode 100644 index 0000000..4f71609 --- /dev/null +++ b/stock_account_valuation_report/models/__init__.py @@ -0,0 +1,2 @@ +from . import product_product +from . import account_move_line diff --git a/stock_account_valuation_report/models/account_move_line.py b/stock_account_valuation_report/models/account_move_line.py new file mode 100644 index 0000000..7afc6c6 --- /dev/null +++ b/stock_account_valuation_report/models/account_move_line.py @@ -0,0 +1,10 @@ +# Copyright 2018 Eficent Business and IT Consulting Services, S.L. +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from odoo import fields, models + + +class AccountMoveLine(models.Model): + _inherit = "account.move.line" + + product_id = fields.Many2one(index=True) diff --git a/stock_account_valuation_report/models/product_product.py b/stock_account_valuation_report/models/product_product.py new file mode 100644 index 0000000..e71008d --- /dev/null +++ b/stock_account_valuation_report/models/product_product.py @@ -0,0 +1,139 @@ +# Copyright 2018 Eficent Business and IT Consulting Services, S.L. +# () +# Copyright 2018 Aleph Objects, Inc. +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from odoo import fields, models, _ + + +class ProductProduct(models.Model): + _inherit = 'product.product' + + stock_value = fields.Float( + 'Inventory Value', compute='_compute_inventory_value') + account_value = fields.Float( + 'Accounting Value', compute='_compute_inventory_value') + qty_at_date = fields.Float( + 'Inventory Quantity', compute='_compute_inventory_value') + account_qty_at_date = fields.Float( + 'Accounting Quantity', compute='_compute_inventory_value') + stock_fifo_real_time_aml_ids = fields.Many2many( + 'account.move.line', compute='_compute_inventory_value') + stock_fifo_manual_move_ids = fields.Many2many( + 'stock.move', compute='_compute_inventory_value') + + def _compute_inventory_value(self): + stock_move = self.env['stock.move'] + self.env['account.move.line'].check_access_rights('read') + to_date = self.env.context.get('to_date', False) + location = self.env.context.get('location', False) + accounting_values = {} + if not location: + query = """ + SELECT aml.product_id, aml.account_id, + sum(aml.debit) - sum(aml.credit), sum(quantity), + array_agg(aml.id) + FROM account_move_line AS aml + WHERE aml.product_id IN %%s + AND aml.company_id=%%s %s + GROUP BY aml.product_id, aml.account_id""" + params = (tuple(self._ids, ), self.env.user.company_id.id) + if to_date: + # pylint: disable=sql-injection + query = query % ('AND aml.date <= %s',) + params = params + (to_date,) + else: + query = query % ('',) + self.env.cr.execute(query, params=params) + res = self.env.cr.fetchall() + for row in res: + accounting_values[(row[0], row[1])] = (row[2], row[3], + list(row[4])) + stock_move_domain = [ + ('product_id', 'in', self._ids), + ('date', '<=', to_date)] + stock_move._get_all_base_domain() + moves = stock_move.search(stock_move_domain) + history = {} + if to_date: + query = """ + SELECT DISTINCT ON ("product_id") product_id, cost + FROM "product_price_history" + WHERE datetime <= %s::date + AND product_id IN %s + ORDER BY "product_id", "datetime" DESC NULLS LAST + """ + args = (to_date, tuple(self._ids)) + self.env.cr.execute(query, args) + for row in self.env.cr.dictfetchall(): + history.update({ + row['product_id']: row['cost'] + }) + quantities_dict = self._compute_quantities_dict( + self._context.get('lot_id'), self._context.get('owner_id'), + self._context.get('package_id'), self._context.get('from_date'), + self._context.get('to_date')) + for product in self: + qty_available = quantities_dict[product.id]['qty_available'] + # Retrieve the values from accounting + # We cannot provide location-specific accounting valuation, + # so better, leave the data empty in that case: + if product.valuation == 'real_time' and not location: + valuation_account_id = \ + product.categ_id.property_stock_valuation_account_id.id + value, quantity, aml_ids = accounting_values.get( + (product.id, valuation_account_id)) or (0, 0, []) + product.account_value = value + product.account_qty_at_date = quantity + product.stock_fifo_real_time_aml_ids = \ + self.env['account.move.line'].browse(aml_ids) + # Retrieve the values from inventory + if product.cost_method in ['standard', 'average']: + + price_used = product.standard_price + if to_date: + price_used = history.get(product.id, 0) + product.stock_value = price_used * qty_available + product.qty_at_date = qty_available + elif product.cost_method == 'fifo': + if to_date: + if product.product_tmpl_id.valuation == 'manual_periodic': + product.stock_value = sum(moves.mapped('value')) + product.qty_at_date = qty_available + product.stock_fifo_manual_move_ids = stock_move.browse( + moves.ids) + else: + product.stock_value, moves = \ + product._sum_remaining_values() + product.qty_at_date = qty_available + product.stock_fifo_manual_move_ids = moves + + def action_view_amls(self): + self.ensure_one() + to_date = self.env.context.get('to_date') + tree_view_ref = self.env.ref('stock_account.view_stock_account_aml') + form_view_ref = self.env.ref('account.view_move_line_form') + action = {'name': _('Accounting Valuation at date'), + 'type': 'ir.actions.act_window', 'view_type': 'form', + 'view_mode': 'tree,form', 'context': self.env.context, + 'res_model': 'account.move.line', + 'domain': [('id', 'in', self.with_context( + to_date=to_date).stock_fifo_real_time_aml_ids.ids)], + 'views': [(tree_view_ref.id, 'tree'), + (form_view_ref.id, 'form')]} + return action + + def action_view_stock_moves(self): + self.ensure_one() + to_date = self.env.context.get('to_date') + tree_view_ref = self.env.ref( + 'stock_account.view_move_tree_valuation_at_date') + form_view_ref = self.env.ref('stock.view_move_form') + action = {'name': _('Inventory Valuation'), + 'type': 'ir.actions.act_window', 'view_type': 'form', + 'view_mode': 'tree,form', 'context': self.env.context, + 'res_model': 'stock.move', + 'domain': [('id', 'in', self.with_context( + to_date=to_date).stock_fifo_manual_move_ids.ids)], + 'views': [(tree_view_ref.id, 'tree'), + (form_view_ref.id, 'form')]} + return action diff --git a/stock_account_valuation_report/readme/CONTRIBUTORS.rst b/stock_account_valuation_report/readme/CONTRIBUTORS.rst new file mode 100644 index 0000000..6860aff --- /dev/null +++ b/stock_account_valuation_report/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Jordi Ballester Alomar diff --git a/stock_account_valuation_report/readme/DESCRIPTION.rst b/stock_account_valuation_report/readme/DESCRIPTION.rst new file mode 100644 index 0000000..70ea676 --- /dev/null +++ b/stock_account_valuation_report/readme/DESCRIPTION.rst @@ -0,0 +1,8 @@ +When you trigger a report of inventory valuation, and you use +perpetual inventory, you should be able to reconcile the valuation +from an inventory perspective with the valuation +from an accounting perspective. + +This module changes the report in *Inventory / Reporting / Inventory Valuation* +to display separately the Quantity and Value of each product for the +Inventory and the Accounting systems . diff --git a/stock_account_valuation_report/static/description/icon.png b/stock_account_valuation_report/static/description/icon.png new file mode 100644 index 0000000..3a0328b Binary files /dev/null and b/stock_account_valuation_report/static/description/icon.png differ diff --git a/stock_account_valuation_report/static/description/index.html b/stock_account_valuation_report/static/description/index.html new file mode 100644 index 0000000..a6ce4b2 --- /dev/null +++ b/stock_account_valuation_report/static/description/index.html @@ -0,0 +1,425 @@ + + + + + + +Stock Account Valuation Report + + + +
+

Stock Account Valuation Report

+ + +

Beta License: AGPL-3 OCA/stock-logistics-reporting Translate me on Weblate Try me on Runbot

+

When you trigger a report of inventory valuation, and you use +perpetual inventory, you should be able to reconcile the valuation +from an inventory perspective with the valuation +from an accounting perspective.

+

This module changes the report in Inventory / Reporting / Inventory Valuation +to display separately the Quantity and Value of each product for the +Inventory and the Accounting systems .

+

Table of contents

+ +
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Eficent
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

This module is part of the OCA/stock-logistics-reporting project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/stock_account_valuation_report/views/product_product_views.xml b/stock_account_valuation_report/views/product_product_views.xml new file mode 100644 index 0000000..247172c --- /dev/null +++ b/stock_account_valuation_report/views/product_product_views.xml @@ -0,0 +1,35 @@ + + + + product.stock.tree.2.inherit + product.product + + + + + + + + + + + +