diff --git a/setup/stock_valuation_layer_accounting_date/odoo/addons/stock_valuation_layer_accounting_date b/setup/stock_valuation_layer_accounting_date/odoo/addons/stock_valuation_layer_accounting_date new file mode 120000 index 000000000..e570f63d5 --- /dev/null +++ b/setup/stock_valuation_layer_accounting_date/odoo/addons/stock_valuation_layer_accounting_date @@ -0,0 +1 @@ +../../../../stock_valuation_layer_accounting_date \ No newline at end of file diff --git a/setup/stock_valuation_layer_accounting_date/setup.py b/setup/stock_valuation_layer_accounting_date/setup.py new file mode 100644 index 000000000..28c57bb64 --- /dev/null +++ b/setup/stock_valuation_layer_accounting_date/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/stock_valuation_layer_accounting_date/README.rst b/stock_valuation_layer_accounting_date/README.rst new file mode 100644 index 000000000..56657cd7c --- /dev/null +++ b/stock_valuation_layer_accounting_date/README.rst @@ -0,0 +1,94 @@ +===================================== +Stock Valuation Layer Accounting Date +===================================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:c9ce5446a0d7c7193a21c42bbbaaae58224b3dd67ebe23d76ebf39da12b0cc7a + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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--warehouse-lightgray.png?logo=github + :target: https://github.com/OCA/stock-logistics-warehouse/tree/16.0/stock_valuation_layer_accounting_date + :alt: OCA/stock-logistics-warehouse +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/stock-logistics-warehouse-16-0/stock-logistics-warehouse-16-0-stock_valuation_layer_accounting_date + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/stock-logistics-warehouse&target_branch=16.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module adds Accounting Date field in stock.valuation.layer, enabling the report +output based on this field. + +Accounting Date is computed (and stored in the record) based on the following logic: + +* If a journal entry linked to the stock.valuation.layer record, take the date of the + journal entry. +* Otherwise, convert create_date (datetime) of the stock.valuation.layer record to date, + with consideration to user's timezone. + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +#. Go to *Inventory > Reporting > Inventory Valuation* and click 'Inventory at Date'. +#. In the wizard, select a date in 'Inventory at Date', and click 'Valuation as of + Accounting Date' (note that 'hh:mm:ss' part of the selection in 'Inventory at Date' + is ignored in this context). + +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 to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Quartile Limited + +Contributors +~~~~~~~~~~~~ + +* `Quartile Limited `_: + * Aung Ko Ko lin + * Yoshi Tashiro + +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-warehouse `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/stock_valuation_layer_accounting_date/__init__.py b/stock_valuation_layer_accounting_date/__init__.py new file mode 100644 index 000000000..0759f9486 --- /dev/null +++ b/stock_valuation_layer_accounting_date/__init__.py @@ -0,0 +1,3 @@ +from . import models +from . import wizard +from .hooks import pre_init_hook diff --git a/stock_valuation_layer_accounting_date/__manifest__.py b/stock_valuation_layer_accounting_date/__manifest__.py new file mode 100644 index 000000000..db1d61f67 --- /dev/null +++ b/stock_valuation_layer_accounting_date/__manifest__.py @@ -0,0 +1,17 @@ +# Copyright 2022-2023 Quartile Limited +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +{ + "name": "Stock Valuation Layer Accounting Date", + "category": "Stock", + "version": "16.0.1.0.0", + "author": "Quartile Limited, Odoo Community Association (OCA)", + "website": "https://github.com/OCA/stock-logistics-warehouse", + "license": "AGPL-3", + "depends": ["stock_account"], + "data": [ + "views/stock_valuation_layer_views.xml", + "wizard/stock_quantity_history.xml", + ], + "pre_init_hook": "pre_init_hook", + "installable": True, +} diff --git a/stock_valuation_layer_accounting_date/hooks.py b/stock_valuation_layer_accounting_date/hooks.py new file mode 100644 index 000000000..e3128f127 --- /dev/null +++ b/stock_valuation_layer_accounting_date/hooks.py @@ -0,0 +1,32 @@ +# Copyright 2022-2023 Quartile Limited +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +import logging + +from odoo.tools.sql import column_exists, create_column + +_logger = logging.getLogger(__name__) + + +def pre_init_hook(cr): + if not column_exists(cr, "stock_valuation_layer", "accounting_date"): + _logger.info("Creating column 'accounting_date' in stock_valuation_layer.") + create_column(cr, "stock_valuation_layer", "accounting_date", "date") + _logger.info("Updating accounting_date with account_move.date.") + cr.execute( + """ + UPDATE stock_valuation_layer svl + SET accounting_date = am.date + FROM account_move am + WHERE svl.account_move_id = am.id + AND am.state = 'posted' + """ + ) + _logger.info("Updating 'account_date' with stock_valuation_layer.create_date.") + cr.execute( + """ + UPDATE stock_valuation_layer svl + SET accounting_date = svl.create_date::date + WHERE svl.accounting_date IS NULL + """ + ) diff --git a/stock_valuation_layer_accounting_date/i18n/ja.po b/stock_valuation_layer_accounting_date/i18n/ja.po new file mode 100644 index 000000000..20a8ba5de --- /dev/null +++ b/stock_valuation_layer_accounting_date/i18n/ja.po @@ -0,0 +1,43 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * stock_valuation_layer_accounting_date +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 15.0+e\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-12-26 01:48+0000\n" +"PO-Revision-Date: 2022-12-26 01:48+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: stock_valuation_layer_accounting_date +#: model:ir.model.fields,field_description:stock_valuation_layer_accounting_date.field_stock_valuation_layer__accounting_date +msgid "Accounting Date" +msgstr "会計日" + +#. module: stock_valuation_layer_accounting_date +#: model:ir.model.fields,help:stock_valuation_layer_accounting_date.field_stock_valuation_layer__accounting_date +msgid "" +"Date of the linked journal entry if applicable, otherwise the create date of" +" the record (timezone aware)" +msgstr "紐づく仕訳がある場合はその日付、なければレコード作成日(タイムゾーンの考慮あり)" + +#. module: stock_valuation_layer_accounting_date +#: model:ir.model,name:stock_valuation_layer_accounting_date.model_stock_quantity_history +msgid "Stock Quantity History" +msgstr "在庫数量履歴" + +#. module: stock_valuation_layer_accounting_date +#: model:ir.model,name:stock_valuation_layer_accounting_date.model_stock_valuation_layer +msgid "Stock Valuation Layer" +msgstr "在庫評価レイヤー" + +#. module: stock_valuation_layer_accounting_date +#: model_terms:ir.ui.view,arch_db:stock_valuation_layer_accounting_date.view_stock_quantity_history +msgid "Valuation as of Accounting Date" +msgstr "会計日での評価" diff --git a/stock_valuation_layer_accounting_date/models/__init__.py b/stock_valuation_layer_accounting_date/models/__init__.py new file mode 100644 index 000000000..f75b2df31 --- /dev/null +++ b/stock_valuation_layer_accounting_date/models/__init__.py @@ -0,0 +1 @@ +from . import stock_valuation_layer diff --git a/stock_valuation_layer_accounting_date/models/stock_valuation_layer.py b/stock_valuation_layer_accounting_date/models/stock_valuation_layer.py new file mode 100644 index 000000000..afd59c4a7 --- /dev/null +++ b/stock_valuation_layer_accounting_date/models/stock_valuation_layer.py @@ -0,0 +1,26 @@ +# Copyright 2022-2023 Quartile Limited +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import api, fields, models + + +class StockValuationLayer(models.Model): + _inherit = "stock.valuation.layer" + + accounting_date = fields.Date( + compute="_compute_accounting_date", + store=True, + help="Date of the linked journal entry if applicable, otherwise the create " + "date of the record (timezone aware)", + ) + + @api.depends("create_date", "account_move_id.state", "account_move_id.date") + def _compute_accounting_date(self): + for rec in self: + account_move = rec.account_move_id + if account_move and account_move.state == "posted": + rec.accounting_date = account_move.date + continue + rec.accounting_date = fields.Datetime.context_timestamp( + self, rec.create_date + ) diff --git a/stock_valuation_layer_accounting_date/readme/CONTRIBUTORS.rst b/stock_valuation_layer_accounting_date/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000..475f7c31a --- /dev/null +++ b/stock_valuation_layer_accounting_date/readme/CONTRIBUTORS.rst @@ -0,0 +1,3 @@ +* `Quartile Limited `_: + * Aung Ko Ko lin + * Yoshi Tashiro diff --git a/stock_valuation_layer_accounting_date/readme/DESCRIPTION.rst b/stock_valuation_layer_accounting_date/readme/DESCRIPTION.rst new file mode 100644 index 000000000..6f4878d40 --- /dev/null +++ b/stock_valuation_layer_accounting_date/readme/DESCRIPTION.rst @@ -0,0 +1,9 @@ +This module adds Accounting Date field in stock.valuation.layer, enabling the report +output based on this field. + +Accounting Date is computed (and stored in the record) based on the following logic: + +* If a journal entry linked to the stock.valuation.layer record, take the date of the + journal entry. +* Otherwise, convert create_date (datetime) of the stock.valuation.layer record to date, + with consideration to user's timezone. diff --git a/stock_valuation_layer_accounting_date/readme/USAGE.rst b/stock_valuation_layer_accounting_date/readme/USAGE.rst new file mode 100644 index 000000000..391de6ab1 --- /dev/null +++ b/stock_valuation_layer_accounting_date/readme/USAGE.rst @@ -0,0 +1,4 @@ +#. Go to *Inventory > Reporting > Inventory Valuation* and click 'Inventory at Date'. +#. In the wizard, select a date in 'Inventory at Date', and click 'Valuation as of + Accounting Date' (note that 'hh:mm:ss' part of the selection in 'Inventory at Date' + is ignored in this context). diff --git a/stock_valuation_layer_accounting_date/static/description/index.html b/stock_valuation_layer_accounting_date/static/description/index.html new file mode 100644 index 000000000..0ad65cbe5 --- /dev/null +++ b/stock_valuation_layer_accounting_date/static/description/index.html @@ -0,0 +1,441 @@ + + + + + + +Stock Valuation Layer Accounting Date + + + +
+

Stock Valuation Layer Accounting Date

+ + +

Beta License: AGPL-3 OCA/stock-logistics-warehouse Translate me on Weblate Try me on Runboat

+

This module adds Accounting Date field in stock.valuation.layer, enabling the report +output based on this field.

+

Accounting Date is computed (and stored in the record) based on the following logic:

+
    +
  • If a journal entry linked to the stock.valuation.layer record, take the date of the +journal entry.
  • +
  • Otherwise, convert create_date (datetime) of the stock.valuation.layer record to date, +with consideration to user’s timezone.
  • +
+

Table of contents

+ +
+

Usage

+
    +
  1. Go to Inventory > Reporting > Inventory Valuation and click ‘Inventory at Date’.
  2. +
  3. In the wizard, select a date in ‘Inventory at Date’, and click ‘Valuation as of +Accounting Date’ (note that ‘hh:mm:ss’ part of the selection in ‘Inventory at Date’ +is ignored in this context).
  4. +
+
+
+

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 to smash it by providing a detailed and welcomed +feedback.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • Quartile Limited
  • +
+
+
+

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-warehouse project on GitHub.

+

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

+
+
+
+ + diff --git a/stock_valuation_layer_accounting_date/tests/__init__.py b/stock_valuation_layer_accounting_date/tests/__init__.py new file mode 100644 index 000000000..4ca2e9b9f --- /dev/null +++ b/stock_valuation_layer_accounting_date/tests/__init__.py @@ -0,0 +1 @@ +from . import test_stock_valuation_layer_accounting_date diff --git a/stock_valuation_layer_accounting_date/tests/test_stock_valuation_layer_accounting_date.py b/stock_valuation_layer_accounting_date/tests/test_stock_valuation_layer_accounting_date.py new file mode 100644 index 000000000..ad04a4a01 --- /dev/null +++ b/stock_valuation_layer_accounting_date/tests/test_stock_valuation_layer_accounting_date.py @@ -0,0 +1,41 @@ +# Copyright 2022-2023 Quartile Limited +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from datetime import date + +from freezegun import freeze_time + +from odoo.tests import tagged + +from odoo.addons.stock_account.tests.test_stockvaluationlayer import ( + TestStockValuationStandard, +) + + +@tagged("post_install", "-at_install") +class TestStockValuationStandard(TestStockValuationStandard): + def setUp(self): + super(TestStockValuationStandard, self).setUp() + + @freeze_time("2022-12-02 23:00:00", tz_offset=9) + def test_svl_accounting_date_real_time(self): + self.product1.product_tmpl_id.categ_id.property_valuation = "real_time" + self._make_in_move(self.product1, 10) + valuation_layer = self.product1.stock_valuation_layer_ids + self.assertEqual(valuation_layer.accounting_date, date(2022, 12, 3)) + account_move = valuation_layer.account_move_id + account_move.button_draft() + account_move.name = "/" + account_move.date = "2022-11-30" + account_move.action_post() + self.assertEqual(valuation_layer.accounting_date, date(2022, 11, 30)) + + def test_svl_accounting_date_manual_periodic(self): + # Not using freeze_time() in this test since it cannot be applied to create_date + # without a hack. + self.product1.product_tmpl_id.categ_id.property_valuation = "manual_periodic" + self._make_in_move(self.product1, 10) + valuation_layer = self.product1.stock_valuation_layer_ids + self.assertEqual( + valuation_layer.accounting_date, valuation_layer.create_date.date() + ) diff --git a/stock_valuation_layer_accounting_date/views/stock_valuation_layer_views.xml b/stock_valuation_layer_accounting_date/views/stock_valuation_layer_views.xml new file mode 100644 index 000000000..732ddf7c8 --- /dev/null +++ b/stock_valuation_layer_accounting_date/views/stock_valuation_layer_views.xml @@ -0,0 +1,22 @@ + + + stock.valuation.layer.form + stock.valuation.layer + + + + + + + + + stock.valuation.layer.tree + stock.valuation.layer + + + + + + + + diff --git a/stock_valuation_layer_accounting_date/wizard/__init__.py b/stock_valuation_layer_accounting_date/wizard/__init__.py new file mode 100644 index 000000000..51f2abb55 --- /dev/null +++ b/stock_valuation_layer_accounting_date/wizard/__init__.py @@ -0,0 +1 @@ +from . import stock_quantity_history diff --git a/stock_valuation_layer_accounting_date/wizard/stock_quantity_history.py b/stock_valuation_layer_accounting_date/wizard/stock_quantity_history.py new file mode 100644 index 000000000..c1d065666 --- /dev/null +++ b/stock_valuation_layer_accounting_date/wizard/stock_quantity_history.py @@ -0,0 +1,20 @@ +# Copyright 2022 Quartile Limited +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import models +from odoo.tools.misc import format_datetime + + +class StockQuantityHistory(models.TransientModel): + _inherit = "stock.quantity.history" + + def open_at_accounting_date(self): + action = self.env["ir.actions.actions"]._for_xml_id( + "stock_account.stock_valuation_layer_action" + ) + action["domain"] = [ + ("accounting_date", "<=", self.inventory_datetime), + ("product_id.type", "=", "product"), + ] + action["display_name"] = format_datetime(self.env, self.inventory_datetime) + return action diff --git a/stock_valuation_layer_accounting_date/wizard/stock_quantity_history.xml b/stock_valuation_layer_accounting_date/wizard/stock_quantity_history.xml new file mode 100644 index 000000000..49975bff2 --- /dev/null +++ b/stock_valuation_layer_accounting_date/wizard/stock_quantity_history.xml @@ -0,0 +1,19 @@ + + + + Inventory Report at Date + stock.quantity.history + + + +