diff --git a/account_sequence_option/README.rst b/account_sequence_option/README.rst new file mode 100644 index 00000000000..10f5c91bc12 --- /dev/null +++ b/account_sequence_option/README.rst @@ -0,0 +1,123 @@ +======================= +Account Sequence Option +======================= + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:28733b1121285c3f10186d8b333d79bd9e5806cc6e3215364cc042cbc095a8f8 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png + :target: https://odoo-community.org/page/development-status + :alt: Alpha +.. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png + :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html + :alt: License: LGPL-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/17.0/account_sequence_option + :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-17-0/account-financial-tools-17-0-account_sequence_option + :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=17.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module extends module base_sequence_option and allow you to provide +optional sequences for account.move documents, i.e., invoice, bill, +journal entry. + +To use this module, enable developer mode, and check "Use sequence +options" under Settings -> Technical -> Manage Sequence Options. + +If you want to define your sequences in XML, feel free to use +demo/account_demo_options.xml as a base for your own sequence +definitions. + +The demo sequences use a continuous numbering scheme, without the +current year in the generated name. To use a scheme that does include +the year, set ``use_date_range`` to ``true``, and use ``%(range_year)s`` +the represent the year. For example, to generate an invoice scheme that +will generate "2022F00001" in 2022, try: + +:: + + + Customer Invoice + + %(range_year)sF + true + + +Odoo will generate the date ranges automagically when the first invoice +(or vendor bill, etc) of a year is posted. + +.. IMPORTANT:: + This is an alpha version, the data model and design can change at any time without warning. + Only for development or testing purpose, do not use in production. + `More details on development status `_ + +**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 to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* Ecosoft + +Contributors +------------ + +- Kitti U. +- `Sygel `__: + + - Ángel García de la Chica Herrera + +- `APSL-Nagarro `__: + + - Antoni Marroig + +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. + +.. |maintainer-kittiu| image:: https://github.com/kittiu.png?size=40px + :target: https://github.com/kittiu + :alt: kittiu + +Current `maintainer `__: + +|maintainer-kittiu| + +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/account_sequence_option/__init__.py b/account_sequence_option/__init__.py new file mode 100644 index 00000000000..b7f345e3e80 --- /dev/null +++ b/account_sequence_option/__init__.py @@ -0,0 +1,4 @@ +# Copyright 2021 Ecosoft Co., Ltd. (http://ecosoft.co.th) +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). + +from . import models diff --git a/account_sequence_option/__manifest__.py b/account_sequence_option/__manifest__.py new file mode 100644 index 00000000000..a94bbec0c58 --- /dev/null +++ b/account_sequence_option/__manifest__.py @@ -0,0 +1,22 @@ +# Copyright 2021 Ecosoft Co., Ltd. (http://ecosoft.co.th) +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). + +{ + "name": "Account Sequence Option", + "summary": "Manage sequence options for account.move, i.e., invoice, bill, entry", + "version": "17.0.1.0.0", + "author": "Ecosoft, Odoo Community Association (OCA)", + "development_status": "Alpha", + "website": "https://github.com/OCA/account-financial-tools", + "category": "Accounting", + "depends": ["account", "base_sequence_option"], + "data": [ + "data/account_sequence_option.xml", + "views/account_move_views.xml", + ], + "demo": ["demo/account_demo_options.xml"], + "maintainers": ["kittiu"], + "license": "LGPL-3", + "installable": True, + "auto_install": False, +} diff --git a/account_sequence_option/data/account_sequence_option.xml b/account_sequence_option/data/account_sequence_option.xml new file mode 100644 index 00000000000..6b6fcc4c6fd --- /dev/null +++ b/account_sequence_option/data/account_sequence_option.xml @@ -0,0 +1,9 @@ + + + + Invoice / Bill / Refund / Payment + account.move + + + + diff --git a/account_sequence_option/demo/account_demo_options.xml b/account_sequence_option/demo/account_demo_options.xml new file mode 100644 index 00000000000..2e3106c4a40 --- /dev/null +++ b/account_sequence_option/demo/account_demo_options.xml @@ -0,0 +1,95 @@ + + + + + + Customer Invoice + + CINV/ + false + + + + Customer Refund + + CREF/ + false + + + + Vendor Bill + + VBIL/ + false + + + + Vendor Refund + + VREF/ + false + + + + Customer Payment + + CPAY/ + false + + + + Vendor Payment + + VPAY/ + false + + + + + + + Customer Invoice + [("move_type", "=", "out_invoice")] + + + + + + Customer Refund + [("move_type", "=", "out_refund")] + + + + + + Vendor Bill + [("move_type", "=", "in_invoice")] + + + + + + Vendor Refund + [("move_type", "=", "in_refund")] + + + + + + Customer Payment + [("move_type", "=", "entry"), ("payment_id.payment_type", "=", "inbound")] + + + + + + Vendor Payment + [("move_type", "=", "entry"), ("payment_id.payment_type", "=", "outbound")] + + + + diff --git a/account_sequence_option/i18n/account_sequence_option.pot b/account_sequence_option/i18n/account_sequence_option.pot new file mode 100644 index 00000000000..c1dcace7431 --- /dev/null +++ b/account_sequence_option/i18n/account_sequence_option.pot @@ -0,0 +1,41 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_sequence_option +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \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: account_sequence_option +#: model:ir.model.fields,field_description:account_sequence_option.field_ir_sequence_option__model +msgid "Apply On Model" +msgstr "" + +#. module: account_sequence_option +#: model:ir.model,name:account_sequence_option.model_account_move +msgid "Journal Entry" +msgstr "" + +#. module: account_sequence_option +#: model:ir.model.fields,field_description:account_sequence_option.field_account_bank_statement_line__sequence_option +#: model:ir.model.fields,field_description:account_sequence_option.field_account_move__sequence_option +#: model:ir.model.fields,field_description:account_sequence_option.field_account_payment__sequence_option +msgid "Sequence Option" +msgstr "" + +#. module: account_sequence_option +#: model:ir.model,name:account_sequence_option.model_ir_sequence_option +msgid "Sequence Option Base Model" +msgstr "" + +#. module: account_sequence_option +#: model:ir.model.fields.selection,name:account_sequence_option.selection__ir_sequence_option__model__account_move +msgid "account.move" +msgstr "" diff --git a/account_sequence_option/i18n/it.po b/account_sequence_option/i18n/it.po new file mode 100644 index 00000000000..40616268f0a --- /dev/null +++ b/account_sequence_option/i18n/it.po @@ -0,0 +1,53 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * account_sequence_option +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2023-10-09 03:11+0000\n" +"Last-Translator: mymage \n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: account_sequence_option +#: model:ir.model.fields,field_description:account_sequence_option.field_ir_sequence_option__model +msgid "Apply On Model" +msgstr "Applica sul modello" + +#. module: account_sequence_option +#: model:ir.model,name:account_sequence_option.model_account_move +msgid "Journal Entry" +msgstr "Registrazione contabile" + +#. module: account_sequence_option +#: model:ir.model.fields,field_description:account_sequence_option.field_account_bank_statement_line__sequence_option +#: model:ir.model.fields,field_description:account_sequence_option.field_account_move__sequence_option +#: model:ir.model.fields,field_description:account_sequence_option.field_account_payment__sequence_option +msgid "Sequence Option" +msgstr "Opzione sequenza" + +#. module: account_sequence_option +#: model:ir.model,name:account_sequence_option.model_ir_sequence_option +msgid "Sequence Option Base Model" +msgstr "Sequenza modello base opzione" + +#. module: account_sequence_option +#: model:ir.model.fields.selection,name:account_sequence_option.selection__ir_sequence_option__model__account_move +msgid "account.move" +msgstr "Registrazione contabile (account.move)" + +#~ msgid "Display Name" +#~ msgstr "Nome visualizzato" + +#~ msgid "ID" +#~ msgstr "ID" + +#~ msgid "Last Modified on" +#~ msgstr "Ultima modifica il" diff --git a/account_sequence_option/models/__init__.py b/account_sequence_option/models/__init__.py new file mode 100644 index 00000000000..a46d682dc5b --- /dev/null +++ b/account_sequence_option/models/__init__.py @@ -0,0 +1,5 @@ +# Copyright 2021 Ecosoft Co., Ltd. (http://ecosoft.co.th) +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). + +from . import account_move +from . import sequence_option diff --git a/account_sequence_option/models/account_move.py b/account_sequence_option/models/account_move.py new file mode 100644 index 00000000000..1f759d16e86 --- /dev/null +++ b/account_sequence_option/models/account_move.py @@ -0,0 +1,70 @@ +# Copyright 2021 Ecosoft Co., Ltd. (http://ecosoft.co.th) +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). + +from odoo import api, fields, models + + +class AccountMove(models.Model): + _inherit = "account.move" + + sequence_option = fields.Boolean( + compute="_compute_sequence_option", + default=False, + copy=False, + store=True, + index=True, + ) + + @api.depends("posted_before", "state", "journal_id", "date") + def _compute_sequence_option(self): + if hasattr(self.env["account.journal"], "sequence_id"): + return + return self._compute_name() + + @api.depends("posted_before", "state", "journal_id", "date") + def _compute_name(self): + options = self.env["ir.sequence.option.line"].get_model_options(self._name) + # On post, get the sequence option + if options: + for rec in self.filtered( + lambda x: x.name in (False, "/") and x.state == "posted" + ): + sequence = self.env["ir.sequence.option.line"].get_sequence( + rec, options=options + ) + if sequence: + rec.name = sequence.next_by_id(sequence_date=rec.date) + rec.sequence_option = True + + # Call super() + res = super()._compute_name() + if options: + for rec in self: + # On create new, odoo may suggest the 1st new number, remove it. + if ( + not rec.create_date + and rec.state == "draft" + and rec.name not in (False, "/") + ): + rec.name = "/" + # On cancel/draft w/o number assigned yet, ensure no odoo number assigned. + if ( + rec.create_date + and rec.state in ("draft", "cancel") + and rec.name not in (False, "/") + and not rec.sequence_option + ): + rec.name = "/" + return res + + # Bypass constrains if sequence is defined + def _constrains_date_sequence(self): + records = self.filtered( + lambda x: self.env["ir.sequence.option.line"].get_sequence(x) + ) + return super(AccountMove, self - records)._constrains_date_sequence() + + def _get_last_sequence_domain(self, relaxed=False): + (where_string, param) = super()._get_last_sequence_domain(relaxed=relaxed) + where_string += " AND coalesce(sequence_option, false) = false " + return where_string, param diff --git a/account_sequence_option/models/sequence_option.py b/account_sequence_option/models/sequence_option.py new file mode 100644 index 00000000000..441b1a5e8b2 --- /dev/null +++ b/account_sequence_option/models/sequence_option.py @@ -0,0 +1,13 @@ +# Copyright 2021 Ecosoft Co., Ltd. (http://ecosoft.co.th) +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). + +from odoo import fields, models + + +class IrSequenceOption(models.Model): + _inherit = "ir.sequence.option" + + model = fields.Selection( + selection_add=[("account.move", "account.move")], + ondelete={"account.move": "cascade"}, + ) diff --git a/account_sequence_option/pyproject.toml b/account_sequence_option/pyproject.toml new file mode 100644 index 00000000000..4231d0cccb3 --- /dev/null +++ b/account_sequence_option/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/account_sequence_option/readme/CONTRIBUTORS.md b/account_sequence_option/readme/CONTRIBUTORS.md new file mode 100644 index 00000000000..d36595cac9b --- /dev/null +++ b/account_sequence_option/readme/CONTRIBUTORS.md @@ -0,0 +1,5 @@ +- Kitti U. \<\> +- [Sygel](https://www.sygel.es): + - Ángel García de la Chica Herrera +- [APSL-Nagarro](): + - Antoni Marroig \<\> \ No newline at end of file diff --git a/account_sequence_option/readme/DESCRIPTION.md b/account_sequence_option/readme/DESCRIPTION.md new file mode 100644 index 00000000000..5685ab96953 --- /dev/null +++ b/account_sequence_option/readme/DESCRIPTION.md @@ -0,0 +1,26 @@ +This module extends module base_sequence_option and allow you to provide +optional sequences for account.move documents, i.e., invoice, bill, +journal entry. + +To use this module, enable developer mode, and check "Use sequence +options" under Settings -\> Technical -\> Manage Sequence Options. + +If you want to define your sequences in XML, feel free to use +demo/account_demo_options.xml as a base for your own sequence +definitions. + +The demo sequences use a continuous numbering scheme, without the +current year in the generated name. To use a scheme that does include +the year, set `use_date_range` to `true`, and use `%(range_year)s` the +represent the year. For example, to generate an invoice scheme that will +generate "2022F00001" in 2022, try: + + + Customer Invoice + + %(range_year)sF + true + + +Odoo will generate the date ranges automagically when the first invoice +(or vendor bill, etc) of a year is posted. diff --git a/account_sequence_option/static/description/icon.png b/account_sequence_option/static/description/icon.png new file mode 100644 index 00000000000..3a0328b516c Binary files /dev/null and b/account_sequence_option/static/description/icon.png differ diff --git a/account_sequence_option/static/description/index.html b/account_sequence_option/static/description/index.html new file mode 100644 index 00000000000..3d9a4c145f9 --- /dev/null +++ b/account_sequence_option/static/description/index.html @@ -0,0 +1,461 @@ + + + + + +Account Sequence Option + + + +
+

Account Sequence Option

+ + +

Alpha License: LGPL-3 OCA/account-financial-tools Translate me on Weblate Try me on Runboat

+

This module extends module base_sequence_option and allow you to provide +optional sequences for account.move documents, i.e., invoice, bill, +journal entry.

+

To use this module, enable developer mode, and check “Use sequence +options” under Settings -> Technical -> Manage Sequence Options.

+

If you want to define your sequences in XML, feel free to use +demo/account_demo_options.xml as a base for your own sequence +definitions.

+

The demo sequences use a continuous numbering scheme, without the +current year in the generated name. To use a scheme that does include +the year, set use_date_range to true, and use %(range_year)s +the represent the year. For example, to generate an invoice scheme that +will generate “2022F00001” in 2022, try:

+
+<record id="seq_customer_invoice_1" model="ir.sequence">
+    <field name="name">Customer Invoice</field>
+    <field name="padding" eval="5" />
+    <field name="prefix">%(range_year)sF</field>
+    <field name="use_date_range">true</field>
+</record>
+
+

Odoo will generate the date ranges automagically when the first invoice +(or vendor bill, etc) of a year is posted.

+
+

Important

+

This is an alpha version, the data model and design can change at any time without warning. +Only for development or testing purpose, do not use in production. +More details on development status

+
+

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

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • Ecosoft
  • +
+
+
+

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.

+

Current maintainer:

+

kittiu

+

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/account_sequence_option/tests/__init__.py b/account_sequence_option/tests/__init__.py new file mode 100644 index 00000000000..7fa68a11132 --- /dev/null +++ b/account_sequence_option/tests/__init__.py @@ -0,0 +1,4 @@ +# Copyright 2021 Ecosoft Co., Ltd. (http://ecosoft.co.th) +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). + +from . import test_account_sequence_option diff --git a/account_sequence_option/tests/test_account_sequence_option.py b/account_sequence_option/tests/test_account_sequence_option.py new file mode 100644 index 00000000000..ceb8bbd7684 --- /dev/null +++ b/account_sequence_option/tests/test_account_sequence_option.py @@ -0,0 +1,97 @@ +# Copyright 2021 Ecosoft Co., Ltd. (http://ecosoft.co.th) +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). + +from datetime import timedelta + +from odoo import fields +from odoo.tests.common import Form, TransactionCase, tagged + + +@tagged("post_install", "-at_install") +class TestAccountSequenceOption(TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.AccountMove = cls.env["account.move"] + cls.AccountMoveLine = cls.env["account.move.line"] + cls.partner_id = cls.env.ref("base.res_partner_1") + cls.product_id_1 = cls.env.ref("product.product_product_6") + cls.account_seq_opt1 = cls.env.ref("account_sequence_option.account_sequence") + cls.pay_in = cls.env.ref("account.account_payment_method_manual_in") + cls.pay_out = cls.env.ref("account.account_payment_method_manual_out") + + @classmethod + def _create_invoice(self, move_type): + move_form = Form( + self.env["account.move"].with_context(default_move_type=move_type) + ) + move_form.partner_id = self.partner_id + move_form.invoice_date = fields.Date.today() + with move_form.invoice_line_ids.new() as line_form: + line_form.product_id = self.product_id_1 + invoice = move_form.save() + return invoice + + @classmethod + def _create_payment(self, payment_type, partner_type): + ctx = { + "default_payment_type": payment_type, + "default_partner_type": partner_type, + "default_move_journal_types": ("bank", "cash"), + } + move_form = Form(self.env["account.payment"].with_context(**ctx)) + move_form.partner_id = self.partner_id + payment = move_form.save() + return payment + + def test_account_sequence_options(self): + """Test different kind of sequences + 1. Customer Invoice 2. Vendor Bill + 3. Customer Refund 4. Vendor Refund + 5. Customer Payment 6. Vendor Payment + """ + self.account_seq_opt1.use_sequence_option = True + # 1. Customer Invoice + self.invoice = self._create_invoice("out_invoice") + self.invoice.action_post() + self.invoice._compute_name() + name = hasattr(self.env["account.journal"], "sequence_id") and "INV" or "CINV" + self.assertIn(name, self.invoice.name) + # 2. Vendor Bill + self.invoice = self._create_invoice("in_invoice") + self.invoice.action_post() + name = hasattr(self.env["account.journal"], "sequence_id") and "BILL" or "VBIL" + self.assertIn(name, self.invoice.name) + # 3. Customer Refund + self.invoice = self._create_invoice("out_refund") + self.invoice.action_post() + name = hasattr(self.env["account.journal"], "sequence_id") and "RINV" or "CREF" + self.assertIn(name, self.invoice.name) + # 4. Vendor Refund + self.invoice = self._create_invoice("in_refund") + self.invoice.action_post() + name = hasattr(self.env["account.journal"], "sequence_id") and "RBILL" or "VREF" + self.assertIn(name, self.invoice.name) + # 5. Customer Payment + self.payment = self._create_payment("inbound", "customer") + self.payment.action_post() + name = hasattr(self.env["account.journal"], "sequence_id") and "BNK1" or "CPAY" + self.assertIn(name, self.payment.name) + # 6. Vendor Payment + self.payment = self._create_payment("outbound", "supplier") + self.payment.action_post() + name = hasattr(self.env["account.journal"], "sequence_id") and "BNK1" or "VPAY" + self.assertIn(name, self.payment.name) + # 7. Create out invoice, post invoice, reset invoice to Draft + # Change Date, post invoice. + self.invoice = self._create_invoice("out_invoice") + self.invoice.action_post() + old_name = self.invoice.name + self.invoice.button_draft() + self.invoice.write( + {"invoice_date": self.invoice.invoice_date - timedelta(days=1)} + ) + self.invoice.action_post() + self.assertEqual(old_name, self.invoice.name) + + self.invoice._constrains_date_sequence() diff --git a/account_sequence_option/views/account_move_views.xml b/account_sequence_option/views/account_move_views.xml new file mode 100644 index 00000000000..c37ab1df9ff --- /dev/null +++ b/account_sequence_option/views/account_move_views.xml @@ -0,0 +1,15 @@ + + + + + account_sequence_option_view_move_form + account.move + + + + + + + + diff --git a/test-requirements.txt b/test-requirements.txt new file mode 100644 index 00000000000..568e7efd089 --- /dev/null +++ b/test-requirements.txt @@ -0,0 +1 @@ +odoo-addon-base_sequence_option @ git+https://github.com/OCA/server-tools.git@refs/pull/3009/head#subdirectory=base_sequence_option