diff --git a/account_sequence_option/__init__.py b/account_sequence_option/__init__.py
new file mode 100644
index 000000000..b7f345e3e
--- /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 000000000..964c60afd
--- /dev/null
+++ b/account_sequence_option/__manifest__.py
@@ -0,0 +1,19 @@
+# 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": "14.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"],
+ "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 000000000..6b6fcc4c6
--- /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 000000000..e601b658d
--- /dev/null
+++ b/account_sequence_option/demo/account_demo_options.xml
@@ -0,0 +1,95 @@
+
+
+
+
+
+ Customer Invoice
+
+ CINV/
+
+
+
+ Customer Refund
+
+ CREF/
+
+
+
+ Vendor Bill
+
+ VBIL/
+
+
+
+ Vendor Refund
+
+ VREF/
+
+
+
+ Customer Payment
+
+ CPAY/
+
+
+
+ Vendor Payment
+
+ VPAY/
+
+
+
+
+
+
+ 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/models/__init__.py b/account_sequence_option/models/__init__.py
new file mode 100644
index 000000000..a46d682dc
--- /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 000000000..6d6d039ac
--- /dev/null
+++ b/account_sequence_option/models/account_move.py
@@ -0,0 +1,64 @@
+# 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_name",
+ default=False,
+ copy=False,
+ store=True,
+ index=True,
+ )
+
+ @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 l: l.name in (False, "/") and l.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()
+ 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 = "/"
+
+ # Bypass constrains if sequence is defined
+ def _constrains_date_sequence(self):
+ records = self.filtered(
+ lambda l: self.env["ir.sequence.option.line"].get_sequence(l)
+ )
+ 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 000000000..441b1a5e8
--- /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/readme/CONTRIBUTORS.rst b/account_sequence_option/readme/CONTRIBUTORS.rst
new file mode 100644
index 000000000..6ce956d96
--- /dev/null
+++ b/account_sequence_option/readme/CONTRIBUTORS.rst
@@ -0,0 +1 @@
+* Kitti U.
diff --git a/account_sequence_option/readme/DESCRIPTION.rst b/account_sequence_option/readme/DESCRIPTION.rst
new file mode 100644
index 000000000..a23cf505f
--- /dev/null
+++ b/account_sequence_option/readme/DESCRIPTION.rst
@@ -0,0 +1,2 @@
+This module extends module ir_sequence_option and allow you to
+provide optional sequences for account.move documents, i.e., invoice, bill, journal entry.
diff --git a/account_sequence_option/static/description/icon.png b/account_sequence_option/static/description/icon.png
new file mode 100644
index 000000000..3a0328b51
Binary files /dev/null and b/account_sequence_option/static/description/icon.png differ
diff --git a/account_sequence_option/tests/__init__.py b/account_sequence_option/tests/__init__.py
new file mode 100644
index 000000000..7fa68a111
--- /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 000000000..1e061b200
--- /dev/null
+++ b/account_sequence_option/tests/test_account_sequence_option.py
@@ -0,0 +1,74 @@
+# 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
+from odoo.tests.common import Form, TransactionCase, tagged
+
+
+@tagged("post_install", "-at_install")
+class TestAccountSequenceOption(TransactionCase):
+ def setUp(self):
+ super(TestAccountSequenceOption, self).setUp()
+ self.AccountMove = self.env["account.move"]
+ self.AccountMoveLine = self.env["account.move.line"]
+ self.partner_id = self.env.ref("base.res_partner_1")
+ self.product_id_1 = self.env.ref("product.product_product_6")
+ self.account_seq_opt1 = self.env.ref("account_sequence_option.account_sequence")
+ self.pay_in = self.env.ref("account.account_payment_method_manual_in")
+ self.pay_out = self.env.ref("account.account_payment_method_manual_out")
+
+ 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
+
+ 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.payment_type = payment_type
+ move_form.partner_type = partner_type
+ 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.assertIn("CINV", self.invoice.name)
+ # 2. Vendor Bill
+ self.invoice = self._create_invoice("in_invoice")
+ self.invoice.action_post()
+ self.assertIn("VBIL", self.invoice.name)
+ # 3. Customer Refund
+ self.invoice = self._create_invoice("out_refund")
+ self.invoice.action_post()
+ self.assertIn("CREF", self.invoice.name)
+ # 4. Vendor Refund
+ self.invoice = self._create_invoice("in_refund")
+ self.invoice.action_post()
+ self.assertIn("VREF", self.invoice.name)
+ # 5. Customer Payment
+ self.payment = self._create_payment("inbound", "customer")
+ self.payment.action_post()
+ self.assertIn("CPAY", self.payment.name)
+ # 6. Vendor Payment
+ self.payment = self._create_payment("outbound", "supplier")
+ self.payment.action_post()
+ self.assertIn("VPAY", self.payment.name)
diff --git a/setup/account_sequence_option/odoo/addons/account_sequence_option b/setup/account_sequence_option/odoo/addons/account_sequence_option
new file mode 120000
index 000000000..a29bce64b
--- /dev/null
+++ b/setup/account_sequence_option/odoo/addons/account_sequence_option
@@ -0,0 +1 @@
+../../../../account_sequence_option
\ No newline at end of file
diff --git a/setup/account_sequence_option/setup.py b/setup/account_sequence_option/setup.py
new file mode 100644
index 000000000..28c57bb64
--- /dev/null
+++ b/setup/account_sequence_option/setup.py
@@ -0,0 +1,6 @@
+import setuptools
+
+setuptools.setup(
+ setup_requires=['setuptools-odoo'],
+ odoo_addon=True,
+)