diff --git a/setup/stock_account_move_show_draft_button/odoo/addons/stock_account_move_show_draft_button b/setup/stock_account_move_show_draft_button/odoo/addons/stock_account_move_show_draft_button new file mode 120000 index 00000000000..3a18facb3ac --- /dev/null +++ b/setup/stock_account_move_show_draft_button/odoo/addons/stock_account_move_show_draft_button @@ -0,0 +1 @@ +../../../../stock_account_move_show_draft_button \ No newline at end of file diff --git a/setup/stock_account_move_show_draft_button/setup.py b/setup/stock_account_move_show_draft_button/setup.py new file mode 100644 index 00000000000..28c57bb6403 --- /dev/null +++ b/setup/stock_account_move_show_draft_button/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/stock_account_move_show_draft_button/README.rst b/stock_account_move_show_draft_button/README.rst new file mode 100644 index 00000000000..76f84addf57 --- /dev/null +++ b/stock_account_move_show_draft_button/README.rst @@ -0,0 +1,105 @@ +==================================== +Stock Account Move Show Draft Button +==================================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:36828e6a8c9918a10daf2a99f8abc13630d74db46a50933cb51c31ed60e9d32f + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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%2Faccount--financial--tools-lightgray.png?logo=github + :target: https://github.com/OCA/account-financial-tools/tree/16.0/stock_account_move_show_draft_button + :alt: OCA/account-financial-tools +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/account-financial-tools-16-0/account-financial-tools-16-0-stock_account_move_show_draft_button + :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/account-financial-tools&target_branch=16.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module will allow to bypass the protection on draft mode button +visibility on account moves. + +This will not show the draft button in case of hash integrity +restriction. + +**Table of contents** + +.. contents:: + :local: + +Use Cases / Context +=================== + +In some situations, people needs to change non critical information that +are not editable if the account move is not draft. + +If stock_account module is installed and stock valuation layers have +been generated, Odoo does not allow to come back to draft. + +The solution provided here would allow to get back to draft mode, log +the information and warn the user about the implications. + +Configuration +============= + +- In Settings > Users & Companies > Users +- Choose a user +- In Access Rights > Technical +- Check the 'Account Moves - Show Draft Button' box in 'Access Rights' + +|Access Rights| + +.. |Access Rights| image:: https://raw.githubusercontent.com/OCA/account-financial-tools/16.0/stock_account_move_show_draft_button/static/description/access_right.png + +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 +------- + +* ACSONE SA/NV +* ADHOC SA + +Contributors +------------ + +- Denis Roussel denis.roussel@acsone.eu + +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/account-financial-tools `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/stock_account_move_show_draft_button/__init__.py b/stock_account_move_show_draft_button/__init__.py new file mode 100644 index 00000000000..0650744f6bc --- /dev/null +++ b/stock_account_move_show_draft_button/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/stock_account_move_show_draft_button/__manifest__.py b/stock_account_move_show_draft_button/__manifest__.py new file mode 100644 index 00000000000..acc9e230007 --- /dev/null +++ b/stock_account_move_show_draft_button/__manifest__.py @@ -0,0 +1,19 @@ +# Copyright 2024 ACSONE SA/NV +# Copyright 2024 ADHOC SA +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +{ + "name": "Stock Account Move Show Draft Button", + "summary": """ + This module allows to reset an account move to draft even if there are valuation + lines""", + "version": "16.0.1.0.0", + "license": "AGPL-3", + "author": "ACSONE SA/NV,ADHOC SA,Odoo Community Association (OCA)", + "website": "https://github.com/OCA/account-financial-tools", + "depends": ["stock_account"], + "data": [ + "security/security.xml", + "views/account_move.xml", + ], +} diff --git a/stock_account_move_show_draft_button/models/__init__.py b/stock_account_move_show_draft_button/models/__init__.py new file mode 100644 index 00000000000..9c0a4213854 --- /dev/null +++ b/stock_account_move_show_draft_button/models/__init__.py @@ -0,0 +1 @@ +from . import account_move diff --git a/stock_account_move_show_draft_button/models/account_move.py b/stock_account_move_show_draft_button/models/account_move.py new file mode 100644 index 00000000000..3f9632f293b --- /dev/null +++ b/stock_account_move_show_draft_button/models/account_move.py @@ -0,0 +1,61 @@ +# Copyright 2024 ACSONE SA/NV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import _, api, fields, models +from odoo.exceptions import UserError + + +class AccountMove(models.Model): + + _inherit = "account.move" + + reset_to_draft_bypassed = fields.Boolean( + readonly=True, + help="If this is checked, this record has been reset to draft by bypassing the " + "warning about stock valuations.", + ) + allow_draft_button_bypass = fields.Boolean( + compute="_compute_allow_draft_button_bypass", + help="This is a technical field in order to show the reset to draft button if user" + "has the right to.", + ) + + @api.depends("show_reset_to_draft_button", "restrict_mode_hash_table", "state") + def _compute_allow_draft_button_bypass(self): + user_has_access = self.env.user.has_group( + "stock_account_move_show_draft_button.can_bypass_draft_button" + ) + for move in self: + if ( + user_has_access + and not move.show_reset_to_draft_button + and not move.restrict_mode_hash_table + and move.state in ("posted", "cancel") + ): + move.allow_draft_button_bypass = True + else: + move.allow_draft_button_bypass = False + + def action_button_draft_bypass(self): + self.ensure_one() + if not self.allow_draft_button_bypass: + raise UserError( + _( + "You don't have the right to bypass the draft state restriction! " + "Please ask your administrator." + ) + ) + self.button_draft() + self.write({"reset_to_draft_bypassed": True}) + self._log_to_draft_bypass() + + def _log_to_draft_bypass(self): + """ + Post a message on account move that the user had bypassed the + warning about resetting to draft. + """ + self.ensure_one() + body = _( + "The move was reset to draft by bypassing the warning about stock valuations." + ) + self.message_post(body=body) diff --git a/stock_account_move_show_draft_button/readme/CONFIGURE.md b/stock_account_move_show_draft_button/readme/CONFIGURE.md new file mode 100644 index 00000000000..3bdce25380a --- /dev/null +++ b/stock_account_move_show_draft_button/readme/CONFIGURE.md @@ -0,0 +1,6 @@ +- In Settings > Users & Companies > Users +- Choose a user +- In Access Rights > Technical +- Check the 'Account Moves - Show Draft Button' box in 'Access Rights' + +![Access Rights](../static/description/access_right.png) diff --git a/stock_account_move_show_draft_button/readme/CONTEXT.md b/stock_account_move_show_draft_button/readme/CONTEXT.md new file mode 100644 index 00000000000..e0ce33eb420 --- /dev/null +++ b/stock_account_move_show_draft_button/readme/CONTEXT.md @@ -0,0 +1,8 @@ +In some situations, people needs to change non critical information that are +not editable if the account move is not draft. + +If stock_account module is installed and stock valuation layers have been generated, +Odoo does not allow to come back to draft. + +The solution provided here would allow to get back to draft mode, log the information +and warn the user about the implications. diff --git a/stock_account_move_show_draft_button/readme/CONTRIBUTORS.md b/stock_account_move_show_draft_button/readme/CONTRIBUTORS.md new file mode 100644 index 00000000000..4e7e6847269 --- /dev/null +++ b/stock_account_move_show_draft_button/readme/CONTRIBUTORS.md @@ -0,0 +1 @@ +- Denis Roussel diff --git a/stock_account_move_show_draft_button/readme/DESCRIPTION.md b/stock_account_move_show_draft_button/readme/DESCRIPTION.md new file mode 100644 index 00000000000..0cbe53dbc62 --- /dev/null +++ b/stock_account_move_show_draft_button/readme/DESCRIPTION.md @@ -0,0 +1,4 @@ +This module will allow to bypass the protection on draft mode button visibility on +account moves. + +This will not show the draft button in case of hash integrity restriction. diff --git a/stock_account_move_show_draft_button/security/security.xml b/stock_account_move_show_draft_button/security/security.xml new file mode 100644 index 00000000000..35285448d04 --- /dev/null +++ b/stock_account_move_show_draft_button/security/security.xml @@ -0,0 +1,13 @@ + + + + + Account Moves - Show Draft Button + + + This group should be given to users that have the right to bypass the draft button visibility. + + diff --git a/stock_account_move_show_draft_button/static/description/access_right.png b/stock_account_move_show_draft_button/static/description/access_right.png new file mode 100644 index 00000000000..30fa801467d Binary files /dev/null and b/stock_account_move_show_draft_button/static/description/access_right.png differ diff --git a/stock_account_move_show_draft_button/static/description/icon.png b/stock_account_move_show_draft_button/static/description/icon.png new file mode 100644 index 00000000000..3a0328b516c Binary files /dev/null and b/stock_account_move_show_draft_button/static/description/icon.png differ diff --git a/stock_account_move_show_draft_button/static/description/index.html b/stock_account_move_show_draft_button/static/description/index.html new file mode 100644 index 00000000000..995144dda55 --- /dev/null +++ b/stock_account_move_show_draft_button/static/description/index.html @@ -0,0 +1,445 @@ + + + + + +Stock Account Move Show Draft Button + + + +
+

Stock Account Move Show Draft Button

+ + +

Beta License: AGPL-3 OCA/account-financial-tools Translate me on Weblate Try me on Runboat

+

This module will allow to bypass the protection on draft mode button +visibility on account moves.

+

This will not show the draft button in case of hash integrity +restriction.

+

Table of contents

+ +
+

Use Cases / Context

+

In some situations, people needs to change non critical information that +are not editable if the account move is not draft.

+

If stock_account module is installed and stock valuation layers have +been generated, Odoo does not allow to come back to draft.

+

The solution provided here would allow to get back to draft mode, log +the information and warn the user about the implications.

+
+
+

Configuration

+
    +
  • In Settings > Users & Companies > Users
  • +
  • Choose a user
  • +
  • In Access Rights > Technical
  • +
  • Check the ‘Account Moves - Show Draft Button’ box in ‘Access Rights’
  • +
+

Access Rights

+
+
+

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

+
    +
  • ACSONE SA/NV
  • +
  • ADHOC SA
  • +
+
+
+

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/account-financial-tools project on GitHub.

+

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

+
+
+
+ + diff --git a/stock_account_move_show_draft_button/tests/__init__.py b/stock_account_move_show_draft_button/tests/__init__.py new file mode 100644 index 00000000000..37479457cda --- /dev/null +++ b/stock_account_move_show_draft_button/tests/__init__.py @@ -0,0 +1 @@ +from . import test_account_move_draft diff --git a/stock_account_move_show_draft_button/tests/test_account_move_draft.py b/stock_account_move_show_draft_button/tests/test_account_move_draft.py new file mode 100644 index 00000000000..2233ef9cf44 --- /dev/null +++ b/stock_account_move_show_draft_button/tests/test_account_move_draft.py @@ -0,0 +1,126 @@ +# Copyright 2024 ACSONE SA/NV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from odoo.exceptions import UserError +from odoo.fields import Command +from odoo.tests import Form, users + +from odoo.addons.base.tests.common import BaseCommon + + +class TestAccountMoveDraft(BaseCommon): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.picking_obj = cls.env["stock.picking"] + cls.picking_type_in = cls.env.ref("stock.picking_type_in") + cls.suppliers = cls.env.ref("stock.stock_location_suppliers") + cls.stock = cls.env.ref("stock.stock_location_stock") + cls.account_group = cls.env.ref("account.group_account_user") + cls.stock_manager = cls.env.ref("stock.group_stock_manager") + cls.group = cls.env.ref( + "stock_account_move_show_draft_button.can_bypass_draft_button" + ) + cls.account_model = cls.env["account.account"] + cls.user_account = cls.env["res.users"].create( + { + "name": "Account User", + "login": "test-account-user-draft", + "email": "test@test.com", + "groups_id": [Command.set((cls.account_group | cls.stock_manager).ids)], + } + ) + cls.inventory_account = cls.account_model.create( + { + "name": "Inventory variations", + "code": "INV", + "account_type": "expense", + "reconcile": True, + } + ) + cls.product = cls.env["product.product"].create( + { + "name": "Product Test", + "type": "product", + "standard_price": 5.0, + } + ) + cls.supplier = cls.env["res.partner"].create( + { + "name": "Test Supplier", + } + ) + + def _create_picking(self): + self.picking = self.picking_obj.create( + { + "partner_id": self.supplier.id, + "picking_type_id": self.picking_type_in.id, + "location_id": self.suppliers.id, + "location_dest_id": self.stock.id, + "move_ids": [ + Command.create( + { + "name": self.product.name, + "location_id": self.suppliers.id, + "location_dest_id": self.stock.id, + "product_id": self.product.id, + "product_uom": self.product.uom_id.id, + "product_uom_qty": 5.0, + } + ) + ], + } + ) + self.picking.action_confirm() + + def _create_in_invoice(self): + # Create manually the invoice to mimic what should happen in purchase + with Form( + self.env["account.move"].with_context(default_move_type="in_invoice") + ) as invoice_form: + invoice_form.partner_id = self.partner + invoice_form.invoice_date = "2024-01-01" + with invoice_form.invoice_line_ids.new() as line_form: + line_form.product_id = self.product + line_form.quantity = 5.0 + + self.invoice = invoice_form.save() + self.invoice._post() + + def _create_valuation_line(self): + move = self.picking.move_ids + self.layer = self.env["stock.valuation.layer"].create( + { + "stock_valuation_layer_id": move.stock_valuation_layer_ids.id, + "product_id": move.product_id.id, + "quantity": 0.0, + "value": self.invoice.invoice_line_ids.amount_currency, + "account_move_line_id": self.invoice.invoice_line_ids.id, + "company_id": self.invoice.company_id.id, + } + ) + + @users("test-account-user-draft") + def test_action_draft(self): + self._create_picking() + self.picking.move_line_ids.qty_done = 5.0 + self.picking._action_done() + self._create_in_invoice() + + # Create the valuation line + self._create_valuation_line() + + with self.assertRaises(UserError): + self.invoice.action_button_draft_bypass() + + self.env.user.groups_id |= self.group + self.invoice.invoice_line_ids.invalidate_recordset() + messages_before = self.invoice.message_ids + self.invoice.action_button_draft_bypass() + + self.assertTrue(self.invoice.reset_to_draft_bypassed) + messages = self.invoice.message_ids - messages_before + self.assertIn( + "The move was reset to draft by bypassing the warning about stock valuations.", + messages.mapped("preview"), + ) diff --git a/stock_account_move_show_draft_button/views/account_move.xml b/stock_account_move_show_draft_button/views/account_move.xml new file mode 100644 index 00000000000..8a8f7df28ee --- /dev/null +++ b/stock_account_move_show_draft_button/views/account_move.xml @@ -0,0 +1,29 @@ + + + + + + account.move.form (in account_move_allow_draft) + account.move + + + + + + +