From 7cae06b629837d409a92227ed5d18423a0f11099 Mon Sep 17 00:00:00 2001 From: Kitti U Date: Sat, 8 May 2021 22:01:59 +0700 Subject: [PATCH 1/7] [14.0][ADD] base_sequence_option --- base_sequence_option/__init__.py | 4 + base_sequence_option/__manifest__.py | 20 + base_sequence_option/models/__init__.py | 5 + base_sequence_option/models/ir_sequence.py | 22 + .../models/sequence_option.py | 101 ++++ base_sequence_option/readme/CONTRIBUTORS.rst | 1 + base_sequence_option/readme/DESCRIPTION.rst | 16 + base_sequence_option/readme/USAGE.rst | 14 + .../security/ir.model.access.csv | 5 + .../static/description/icon.png | Bin 0 -> 9455 bytes .../static/description/index.html | 436 ++++++++++++++++++ base_sequence_option/tests/__init__.py | 5 + .../tests/base_sequence_tester.py | 30 ++ base_sequence_option/tests/common.py | 93 ++++ .../tests/test_base_sequence_option.py | 30 ++ .../views/sequence_option_view.xml | 95 ++++ 16 files changed, 877 insertions(+) create mode 100644 base_sequence_option/__init__.py create mode 100644 base_sequence_option/__manifest__.py create mode 100644 base_sequence_option/models/__init__.py create mode 100644 base_sequence_option/models/ir_sequence.py create mode 100644 base_sequence_option/models/sequence_option.py create mode 100644 base_sequence_option/readme/CONTRIBUTORS.rst create mode 100644 base_sequence_option/readme/DESCRIPTION.rst create mode 100644 base_sequence_option/readme/USAGE.rst create mode 100644 base_sequence_option/security/ir.model.access.csv create mode 100644 base_sequence_option/static/description/icon.png create mode 100644 base_sequence_option/static/description/index.html create mode 100644 base_sequence_option/tests/__init__.py create mode 100644 base_sequence_option/tests/base_sequence_tester.py create mode 100644 base_sequence_option/tests/common.py create mode 100644 base_sequence_option/tests/test_base_sequence_option.py create mode 100644 base_sequence_option/views/sequence_option_view.xml diff --git a/base_sequence_option/__init__.py b/base_sequence_option/__init__.py new file mode 100644 index 000000000..b7f345e3e --- /dev/null +++ b/base_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/base_sequence_option/__manifest__.py b/base_sequence_option/__manifest__.py new file mode 100644 index 000000000..ad23285b6 --- /dev/null +++ b/base_sequence_option/__manifest__.py @@ -0,0 +1,20 @@ +# Copyright 2021 Ecosoft Co., Ltd. (http://ecosoft.co.th) +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). + +{ + "name": "Base Sequence Option", + "summary": "Alternative sequence options for specific models", + "version": "14.0.1.0.0", + "author": "Ecosoft, Odoo Community Association (OCA)", + "maintainers": ["kittiu"], + "development_status": "Alpha", + "website": "https://github.com/OCA/server-tools", + "category": "Tools", + "depends": ["base"], + "data": [ + "security/ir.model.access.csv", + "views/sequence_option_view.xml", + ], + "license": "LGPL-3", + "installable": True, +} diff --git a/base_sequence_option/models/__init__.py b/base_sequence_option/models/__init__.py new file mode 100644 index 000000000..94cb0ad40 --- /dev/null +++ b/base_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 sequence_option +from . import ir_sequence diff --git a/base_sequence_option/models/ir_sequence.py b/base_sequence_option/models/ir_sequence.py new file mode 100644 index 000000000..c3b54f292 --- /dev/null +++ b/base_sequence_option/models/ir_sequence.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). + +from odoo import api, models + + +class IrSequence(models.Model): + _inherit = "ir.sequence" + + def next_by_id(self, sequence_date=None): + sequence_id = self.env.context.get("sequence_option_id", False) + if sequence_id: + self = self.browse(sequence_id) + return super().next_by_id(sequence_date=sequence_date) + + @api.model + def next_by_code(self, sequence_code, sequence_date=None): + sequence_id = self.env.context.get("sequence_option_id", False) + if sequence_id: + self = self.browse(sequence_id) + return super().next_by_id(sequence_date=sequence_date) + return super().next_by_code(sequence_code, sequence_date=sequence_date) diff --git a/base_sequence_option/models/sequence_option.py b/base_sequence_option/models/sequence_option.py new file mode 100644 index 000000000..e2197148c --- /dev/null +++ b/base_sequence_option/models/sequence_option.py @@ -0,0 +1,101 @@ +# 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 +from odoo.exceptions import ValidationError +from odoo.tools import safe_eval + + +class BaseSequenceOption(models.Model): + _name = "base.sequence.option" + _description = "Sequence Option Base Model" + + name = fields.Char(readonly=True) + use_sequence_option = fields.Boolean( + string="Use sequence options", + help="If checked, Odoo will try to find the new matching sequence first, " + "if not found, fall back to use the original Odoo sequence.", + ) + model = fields.Selection( + selection=[], + string="Apply On Model", + required=True, + readonly=True, + ) + option_ids = fields.One2many( + string="Sequence Options", + comodel_name="sequence.option", + inverse_name="base_id", + ) + + +class SequenceOption(models.Model): + _name = "sequence.option" + _description = "Sequence Options" + + base_id = fields.Many2one( + comodel_name="base.sequence.option", + index=True, + required=True, + ondelete="cascade", + ) + name = fields.Char( + string="Description", + required=True, + ) + model = fields.Selection( + related="base_id.model", + store=True, + readonly=True, + ) + use_sequence_option = fields.Boolean( + related="base_id.use_sequence_option", + store=True, + ) + filter_domain = fields.Char( + string="Apply On", + default="[]", + help="Find matching option by document values", + ) + sequence_id = fields.Many2one( + comodel_name="ir.sequence", + string="Sequence", + required=True, + ) + prefix = fields.Char( + related="sequence_id.prefix", + string="Prefix", + readonly=True, + ) + suffix = fields.Char( + related="sequence_id.suffix", + string="Suffix", + readonly=True, + ) + implementation = fields.Selection( + related="sequence_id.implementation", + string="Implementation", + readonly=True, + ) + + def get_model_options(self, model): + return self.sudo().search( + [("use_sequence_option", "=", True), ("model", "=", model)] + ) + + def get_sequence(self, record, options=False): + """ + Find sequence option that match the record values + """ + if not options: + options = self.get_model_options(record._name) + sequence = self.env["ir.sequence"] + for option in options: + domain = safe_eval.safe_eval(option.filter_domain) + if record.sudo().filtered_domain(domain): + if sequence: # Do not allow > 1 match + raise ValidationError( + _("Multiple optional sequences found for this model!") + ) + sequence = option.sequence_id + return sequence diff --git a/base_sequence_option/readme/CONTRIBUTORS.rst b/base_sequence_option/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000..6ce956d96 --- /dev/null +++ b/base_sequence_option/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Kitti U. diff --git a/base_sequence_option/readme/DESCRIPTION.rst b/base_sequence_option/readme/DESCRIPTION.rst new file mode 100644 index 000000000..6b2f0c6b9 --- /dev/null +++ b/base_sequence_option/readme/DESCRIPTION.rst @@ -0,0 +1,16 @@ +This module allow user to add optional sequences to some document model. +On which sequence is used, is based on domain matching with document values +(and original sequence will be bypassed). + +For example, it is now possible to, + +* Avoid using Odoo automatic sequence on invoice and vendor bill with old style sequence. +* Customer payment and vendor payment to run on different sequence. +* Assign different sales order sequence based on customer region. + +This is a base module and does nothing by itself. Following are modules +that will allow managing sequence options for each type of documents, I.e., + +* Purchase Order: purchase_sequence_option +* Invoice / Bill / Refund / Payment: account_sequence_option +* Others: create a new module with few lines of code diff --git a/base_sequence_option/readme/USAGE.rst b/base_sequence_option/readme/USAGE.rst new file mode 100644 index 000000000..3d902ff87 --- /dev/null +++ b/base_sequence_option/readme/USAGE.rst @@ -0,0 +1,14 @@ +To use this module, you need to: + +1. Go to *Settings > Technical > Sequences & Identifier > Manage Sequence Options*. +2. Based on extended module installed, different document types will be listed, i.e., Purchase Order. +3. Activite "Use sequence options" to use, if not, fall back to normal sequence. +4. For each option, provide, + * Name: i.e., Customer Invoice for Cust A., Customer Payment, etc. + * Apply On: a filter domain to test whether a document match this option. + * Sequence: select underlining sequence to perform + +**Note:** + +* If no options matches the document, fall back to normal sequence. +* If there are multiple sequence options that match same document, error will be raised. diff --git a/base_sequence_option/security/ir.model.access.csv b/base_sequence_option/security/ir.model.access.csv new file mode 100644 index 000000000..8ab27d585 --- /dev/null +++ b/base_sequence_option/security/ir.model.access.csv @@ -0,0 +1,5 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_sequence_option,access_sequence_option,model_sequence_option,base.group_user,1,0,0,0 +access_sequence_option_system,access_sequence_option_system,model_sequence_option,base.group_system,1,1,1,1 +access_base_sequence_option,access_base_sequence_option,model_base_sequence_option,base.group_user,1,0,0,0 +access_base_sequence_option_system,access_base_sequence_option_system,model_base_sequence_option,base.group_system,1,1,1,1 diff --git a/base_sequence_option/static/description/icon.png b/base_sequence_option/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 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 z 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 Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 diff --git a/base_sequence_option/static/description/index.html b/base_sequence_option/static/description/index.html new file mode 100644 index 000000000..3922ee59f --- /dev/null +++ b/base_sequence_option/static/description/index.html @@ -0,0 +1,436 @@ + + + + + + +Base Cron Exclusion + + + +
+

Base Cron Exclusion

+ + +

Production/Stable License: LGPL-3 OCA/server-tools Translate me on Weblate Try me on Runbot

+

This module extends the functionality of scheduled actions to allow you to +select the ones that should not run simultaneously.

+

Table of contents

+ +
+

Usage

+

To use this module, you need to:

+
    +
  1. Go to Settings > Technical > Automation > Scheduled Actions.
  2. +
  3. In the form view go to the tab Mutually Exclusive Scheduled Actions.
  4. +
  5. Fill it with the actions that should be blocked while running the action +you are editing. Note that this is mutual and the selected actions will +block the initial action when running.
  6. +
+
+
+

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

+
    +
  • ForgeFlow
  • +
+
+ +
+

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:

+

LoisRForgeFlow

+

This module is part of the OCA/server-tools project on GitHub.

+

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

+
+
+
+ + diff --git a/base_sequence_option/tests/__init__.py b/base_sequence_option/tests/__init__.py new file mode 100644 index 000000000..627300169 --- /dev/null +++ b/base_sequence_option/tests/__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 common +from . import test_base_sequence_option diff --git a/base_sequence_option/tests/base_sequence_tester.py b/base_sequence_option/tests/base_sequence_tester.py new file mode 100644 index 000000000..d9f2a165c --- /dev/null +++ b/base_sequence_option/tests/base_sequence_tester.py @@ -0,0 +1,30 @@ +# 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 BaseSequenceTester(models.Model): + _name = "base.sequence.tester" + _description = "Base Sequence Tester" + + name = fields.Char(default="/") + test_type = fields.Selection(selection=[("a", "A"), ("b", "B")]) + + @api.model + def create(self, vals): + seq = self.env["sequence.option"].get_sequence(self.new(vals)) + if seq: # use sequence from sequence.option, instead of base.sequence.tester + self = self.with_context(sequence_option_id=seq.id) + new_seq = self.env["ir.sequence"].next_by_code("base.sequence.tester") + vals["name"] = new_seq + return super().create(vals) + + +class BaseSequenceOption(models.Model): + _inherit = "base.sequence.option" + + model = fields.Selection( + selection_add=[("base.sequence.tester", "base.sequence.tester")], + ondelete={"base.sequence.tester": "cascade"}, + ) diff --git a/base_sequence_option/tests/common.py b/base_sequence_option/tests/common.py new file mode 100644 index 000000000..a19f002c1 --- /dev/null +++ b/base_sequence_option/tests/common.py @@ -0,0 +1,93 @@ +# Copyright 2021 Ecosoft Co., Ltd. (http://ecosoft.co.th) +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). + +from odoo_test_helper import FakeModelLoader + +from odoo.tests import common + + +class CommonBaseSequenceOption(common.SavepointCase): + @classmethod + def setUpClass(cls): + super(CommonBaseSequenceOption, cls).setUpClass() + + cls.loader = FakeModelLoader(cls.env, cls.__module__) + cls.loader.backup_registry() + from .base_sequence_tester import BaseSequenceOption, BaseSequenceTester + + cls.loader.update_registry((BaseSequenceTester, BaseSequenceOption)) + + cls.test_model = cls.env[BaseSequenceTester._name] + + cls.tester_model = cls.env["ir.model"].search( + [("model", "=", "base.sequence.tester")] + ) + + # Access record: + cls.env["ir.model.access"].create( + { + "name": "access.tester", + "model_id": cls.tester_model.id, + "perm_read": 1, + "perm_write": 1, + "perm_create": 1, + "perm_unlink": 1, + } + ) + + # Create sequence for type A and type B + cls.ir_sequence_obj = cls.env["ir.sequence"] + cls.ir_sequence_obj.create( + { + "name": "Default Sequence", + "code": "base.sequence.tester", + "padding": 5, + "prefix": "DEF/", + } + ) + seq_a = cls.ir_sequence_obj.create( + { + "name": "Type A", + "padding": 5, + "prefix": "TYPE-A/", + } + ) + seq_b = cls.ir_sequence_obj.create( + { + "name": "Type B", + "padding": 5, + "prefix": "TYPE-B/", + } + ) + + # Create sequence options for model bsae.sequence.tester: + cls.base_sequence_obj = cls.env["base.sequence.option"] + cls.base_seq = cls.base_sequence_obj.create( + { + "name": "Test Model", + "model": "base.sequence.tester", + "use_sequence_option": True, + } + ) + cls.sequence_obj = cls.env["sequence.option"] + cls.sequence_obj.create( + { + "base_id": cls.base_seq.id, + "name": "Option 1", + "filter_domain": [("test_type", "=", "a")], + "sequence_id": seq_a.id, + } + ) + cls.sequence_obj.create( + { + "base_id": cls.base_seq.id, + "name": "Option 1", + "filter_domain": [("test_type", "=", "b")], + "sequence_id": seq_b.id, + } + ) + + @classmethod + def tearDownClass(cls): + cls.loader.restore_registry() + super(CommonBaseSequenceOption, cls).tearDownClass() diff --git a/base_sequence_option/tests/test_base_sequence_option.py b/base_sequence_option/tests/test_base_sequence_option.py new file mode 100644 index 000000000..ecbc23e61 --- /dev/null +++ b/base_sequence_option/tests/test_base_sequence_option.py @@ -0,0 +1,30 @@ +# Copyright 2021 Ecosoft Co., Ltd. (http://ecosoft.co.th) +# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). + +from odoo.tests.common import tagged + +from .common import CommonBaseSequenceOption + + +@tagged("post_install", "-at_install") +class TestBaseSequenceTester(CommonBaseSequenceOption): + def test_sequence_options(self): + """ + Test 3 cases, + 1. Default + 2. Sequence Type A + 3. Sequence Type B + """ + # 1. Default + rec = self.test_model.create({}) + self.assertIn("DEF/", rec.name) + # 2. Type A + rec = self.test_model.create({"test_type": "a"}) + self.assertIn("TYPE-A/", rec.name) + # 3. Type B + rec = self.test_model.create({"test_type": "b"}) + self.assertIn("TYPE-B/", rec.name) + # Not useing the sequence + self.base_seq.use_sequence_option = False + rec = self.test_model.create({"test_type": "b"}) + self.assertIn("DEF/", rec.name) diff --git a/base_sequence_option/views/sequence_option_view.xml b/base_sequence_option/views/sequence_option_view.xml new file mode 100644 index 000000000..7b1724dd5 --- /dev/null +++ b/base_sequence_option/views/sequence_option_view.xml @@ -0,0 +1,95 @@ + + + + + + + view.base.sequence.option.tree + base.sequence.option + + + + + + + + + + + view.sequence.option.tree + sequence.option + + + + + + + + + + + + + view.base.sequence.option.form + base.sequence.option + +
+

+ +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ + + Manage Sequence Options + base.sequence.option + tree,form + + + + + +
From 5b0b1a39aa06c52a1b7f7d686e5c99b9c593d7c4 Mon Sep 17 00:00:00 2001 From: Kitti U Date: Sat, 28 Aug 2021 21:08:47 +0700 Subject: [PATCH 2/7] Refactor for multi-company --- base_sequence_option/__manifest__.py | 1 + base_sequence_option/models/__init__.py | 2 +- ...quence_option.py => ir_sequence_option.py} | 39 +++++++++++++++---- .../security/ir.model.access.csv | 8 ++-- .../security/sequence_option_security.xml | 18 +++++++++ base_sequence_option/tests/__init__.py | 2 +- .../tests/base_sequence_tester.py | 6 +-- base_sequence_option/tests/common.py | 10 ++--- ...e_option.py => test_ir_sequence_option.py} | 0 .../views/sequence_option_view.xml | 36 +++++++++-------- 10 files changed, 84 insertions(+), 38 deletions(-) rename base_sequence_option/models/{sequence_option.py => ir_sequence_option.py} (72%) create mode 100644 base_sequence_option/security/sequence_option_security.xml rename base_sequence_option/tests/{test_base_sequence_option.py => test_ir_sequence_option.py} (100%) diff --git a/base_sequence_option/__manifest__.py b/base_sequence_option/__manifest__.py index ad23285b6..3bbd82f7f 100644 --- a/base_sequence_option/__manifest__.py +++ b/base_sequence_option/__manifest__.py @@ -13,6 +13,7 @@ "depends": ["base"], "data": [ "security/ir.model.access.csv", + "security/sequence_option_security.xml", "views/sequence_option_view.xml", ], "license": "LGPL-3", diff --git a/base_sequence_option/models/__init__.py b/base_sequence_option/models/__init__.py index 94cb0ad40..e3f324a79 100644 --- a/base_sequence_option/models/__init__.py +++ b/base_sequence_option/models/__init__.py @@ -1,5 +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 sequence_option +from . import ir_sequence_option from . import ir_sequence diff --git a/base_sequence_option/models/sequence_option.py b/base_sequence_option/models/ir_sequence_option.py similarity index 72% rename from base_sequence_option/models/sequence_option.py rename to base_sequence_option/models/ir_sequence_option.py index e2197148c..c37d05d03 100644 --- a/base_sequence_option/models/sequence_option.py +++ b/base_sequence_option/models/ir_sequence_option.py @@ -6,9 +6,10 @@ from odoo.exceptions import ValidationError from odoo.tools import safe_eval -class BaseSequenceOption(models.Model): - _name = "base.sequence.option" +class IrSequenceOption(models.Model): + _name = "ir.sequence.option" _description = "Sequence Option Base Model" + _check_company_auto = True name = fields.Char(readonly=True) use_sequence_option = fields.Boolean( @@ -20,21 +21,32 @@ class BaseSequenceOption(models.Model): selection=[], string="Apply On Model", required=True, - readonly=True, + readonly=False, + index=True, ) option_ids = fields.One2many( string="Sequence Options", - comodel_name="sequence.option", + comodel_name="ir.sequence.option.line", inverse_name="base_id", ) + company_id = fields.Many2one( + comodel_name="res.company", + string="Company", + required=True, + readonly=False, + index=True, + default=lambda self: self.env.company, + help="Company related to this sequence option", + ) -class SequenceOption(models.Model): - _name = "sequence.option" - _description = "Sequence Options" +class IrSequenceOptionLine(models.Model): + _name = "ir.sequence.option.line" + _description = "Sequence Option Line" + _check_company_auto = True base_id = fields.Many2one( - comodel_name="base.sequence.option", + comodel_name="ir.sequence.option", index=True, required=True, ondelete="cascade", @@ -61,6 +73,7 @@ class SequenceOption(models.Model): comodel_name="ir.sequence", string="Sequence", required=True, + check_company=True, ) prefix = fields.Char( related="sequence_id.prefix", @@ -77,6 +90,11 @@ class SequenceOption(models.Model): string="Implementation", readonly=True, ) + company_id = fields.Many2one( + comodel_name="res.company", + related="base_id.company_id", + store=True, + ) def get_model_options(self, model): return self.sudo().search( @@ -89,6 +107,11 @@ class SequenceOption(models.Model): """ if not options: options = self.get_model_options(record._name) + # multi-company + company = ( + hasattr(record, "company_id") and record.company_id or self.env.company + ) + options = options.filtered(lambda l: l.company_id == company) sequence = self.env["ir.sequence"] for option in options: domain = safe_eval.safe_eval(option.filter_domain) diff --git a/base_sequence_option/security/ir.model.access.csv b/base_sequence_option/security/ir.model.access.csv index 8ab27d585..90a101a56 100644 --- a/base_sequence_option/security/ir.model.access.csv +++ b/base_sequence_option/security/ir.model.access.csv @@ -1,5 +1,5 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -access_sequence_option,access_sequence_option,model_sequence_option,base.group_user,1,0,0,0 -access_sequence_option_system,access_sequence_option_system,model_sequence_option,base.group_system,1,1,1,1 -access_base_sequence_option,access_base_sequence_option,model_base_sequence_option,base.group_user,1,0,0,0 -access_base_sequence_option_system,access_base_sequence_option_system,model_base_sequence_option,base.group_system,1,1,1,1 +access_ir_sequence_option_line,access_ir_sequence_option_line,model_ir_sequence_option_line,base.group_user,1,0,0,0 +access_ir_sequence_option_line_system,access_ir_sequence_option_line_system,model_ir_sequence_option_line,base.group_system,1,1,1,1 +access_ir_sequence_option,access_ir_sequence_option,model_ir_sequence_option,base.group_user,1,0,0,0 +access_ir_sequence_option_system,access_ir_sequence_option_system,model_ir_sequence_option,base.group_system,1,1,1,1 diff --git a/base_sequence_option/security/sequence_option_security.xml b/base_sequence_option/security/sequence_option_security.xml new file mode 100644 index 000000000..14ab82d31 --- /dev/null +++ b/base_sequence_option/security/sequence_option_security.xml @@ -0,0 +1,18 @@ + + + Sequence Option: multi-company + + + + [('company_id', 'in', company_ids)] + + + + Sequence Option Line: multi-company + + + + [('company_id', 'in', company_ids)] + + + diff --git a/base_sequence_option/tests/__init__.py b/base_sequence_option/tests/__init__.py index 627300169..118f59c2e 100644 --- a/base_sequence_option/tests/__init__.py +++ b/base_sequence_option/tests/__init__.py @@ -2,4 +2,4 @@ # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html). from . import common -from . import test_base_sequence_option +from . import test_ir_sequence_option diff --git a/base_sequence_option/tests/base_sequence_tester.py b/base_sequence_option/tests/base_sequence_tester.py index d9f2a165c..652bcc9a3 100644 --- a/base_sequence_option/tests/base_sequence_tester.py +++ b/base_sequence_option/tests/base_sequence_tester.py @@ -13,7 +13,7 @@ class BaseSequenceTester(models.Model): @api.model def create(self, vals): - seq = self.env["sequence.option"].get_sequence(self.new(vals)) + seq = self.env["ir.sequence.option.line"].get_sequence(self.new(vals)) if seq: # use sequence from sequence.option, instead of base.sequence.tester self = self.with_context(sequence_option_id=seq.id) new_seq = self.env["ir.sequence"].next_by_code("base.sequence.tester") @@ -21,8 +21,8 @@ class BaseSequenceTester(models.Model): return super().create(vals) -class BaseSequenceOption(models.Model): - _inherit = "base.sequence.option" +class IrSequenceOption(models.Model): + _inherit = "ir.sequence.option" model = fields.Selection( selection_add=[("base.sequence.tester", "base.sequence.tester")], diff --git a/base_sequence_option/tests/common.py b/base_sequence_option/tests/common.py index a19f002c1..92efc699e 100644 --- a/base_sequence_option/tests/common.py +++ b/base_sequence_option/tests/common.py @@ -13,9 +13,9 @@ class CommonBaseSequenceOption(common.SavepointCase): cls.loader = FakeModelLoader(cls.env, cls.__module__) cls.loader.backup_registry() - from .base_sequence_tester import BaseSequenceOption, BaseSequenceTester + from .base_sequence_tester import BaseSequenceTester, IrSequenceOption - cls.loader.update_registry((BaseSequenceTester, BaseSequenceOption)) + cls.loader.update_registry((BaseSequenceTester, IrSequenceOption)) cls.test_model = cls.env[BaseSequenceTester._name] @@ -60,8 +60,8 @@ class CommonBaseSequenceOption(common.SavepointCase): } ) - # Create sequence options for model bsae.sequence.tester: - cls.base_sequence_obj = cls.env["base.sequence.option"] + # Create sequence options for model base.sequence.tester: + cls.base_sequence_obj = cls.env["ir.sequence.option"] cls.base_seq = cls.base_sequence_obj.create( { "name": "Test Model", @@ -69,7 +69,7 @@ class CommonBaseSequenceOption(common.SavepointCase): "use_sequence_option": True, } ) - cls.sequence_obj = cls.env["sequence.option"] + cls.sequence_obj = cls.env["ir.sequence.option.line"] cls.sequence_obj.create( { "base_id": cls.base_seq.id, diff --git a/base_sequence_option/tests/test_base_sequence_option.py b/base_sequence_option/tests/test_ir_sequence_option.py similarity index 100% rename from base_sequence_option/tests/test_base_sequence_option.py rename to base_sequence_option/tests/test_ir_sequence_option.py diff --git a/base_sequence_option/views/sequence_option_view.xml b/base_sequence_option/views/sequence_option_view.xml index 7b1724dd5..19b667ae0 100644 --- a/base_sequence_option/views/sequence_option_view.xml +++ b/base_sequence_option/views/sequence_option_view.xml @@ -4,21 +4,22 @@ - - view.base.sequence.option.tree - base.sequence.option + + view.ir.sequence.option.tree + ir.sequence.option - + + - - view.sequence.option.tree - sequence.option + + view.ir.sequence.option.line.tree + ir.sequence.option.line @@ -30,17 +31,18 @@ - - view.base.sequence.option.form - base.sequence.option + + view.ir.sequence.option.form + ir.sequence.option -
+

+ @@ -55,6 +57,7 @@ + @@ -69,6 +72,7 @@ + @@ -77,17 +81,17 @@
- + Manage Sequence Options - base.sequence.option + ir.sequence.option tree,form - + From 844884471c74a8a1a14c163f314ad9f41b5d765b Mon Sep 17 00:00:00 2001 From: oca-travis Date: Tue, 23 Nov 2021 12:20:06 +0000 Subject: [PATCH 3/7] [UPD] Update base_sequence_option.pot --- .../i18n/base_sequence_option.pot | 209 ++++++++++++++++++ 1 file changed, 209 insertions(+) create mode 100644 base_sequence_option/i18n/base_sequence_option.pot diff --git a/base_sequence_option/i18n/base_sequence_option.pot b/base_sequence_option/i18n/base_sequence_option.pot new file mode 100644 index 000000000..9de07ab2a --- /dev/null +++ b/base_sequence_option/i18n/base_sequence_option.pot @@ -0,0 +1,209 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * base_sequence_option +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.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: base_sequence_option +#: model:ir.model.fields,field_description:base_sequence_option.field_ir_sequence_option_line__filter_domain +msgid "Apply On" +msgstr "" + +#. module: base_sequence_option +#: model:ir.model.fields,field_description:base_sequence_option.field_ir_sequence_option__model +#: model:ir.model.fields,field_description:base_sequence_option.field_ir_sequence_option_line__model +msgid "Apply On Model" +msgstr "" + +#. module: base_sequence_option +#: model:ir.model.fields,field_description:base_sequence_option.field_ir_sequence_option_line__base_id +msgid "Base" +msgstr "" + +#. module: base_sequence_option +#: model:ir.model.fields,field_description:base_sequence_option.field_ir_sequence_option__company_id +#: model:ir.model.fields,field_description:base_sequence_option.field_ir_sequence_option_line__company_id +msgid "Company" +msgstr "" + +#. module: base_sequence_option +#: model:ir.model.fields,help:base_sequence_option.field_ir_sequence_option__company_id +#: model:ir.model.fields,help:base_sequence_option.field_ir_sequence_option_line__company_id +msgid "Company related to this sequence option" +msgstr "" + +#. module: base_sequence_option +#: model:ir.model.fields,field_description:base_sequence_option.field_ir_sequence_option__create_uid +#: model:ir.model.fields,field_description:base_sequence_option.field_ir_sequence_option_line__create_uid +msgid "Created by" +msgstr "" + +#. module: base_sequence_option +#: model:ir.model.fields,field_description:base_sequence_option.field_ir_sequence_option__create_date +#: model:ir.model.fields,field_description:base_sequence_option.field_ir_sequence_option_line__create_date +msgid "Created on" +msgstr "" + +#. module: base_sequence_option +#: model:ir.model.fields,field_description:base_sequence_option.field_ir_sequence_option_line__name +msgid "Description" +msgstr "" + +#. module: base_sequence_option +#: model:ir.model.fields,field_description:base_sequence_option.field_ir_sequence__display_name +#: model:ir.model.fields,field_description:base_sequence_option.field_ir_sequence_option__display_name +#: model:ir.model.fields,field_description:base_sequence_option.field_ir_sequence_option_line__display_name +msgid "Display Name" +msgstr "" + +#. module: base_sequence_option +#: model_terms:ir.ui.view,arch_db:base_sequence_option.view_ir_sequence_option_form +#: model_terms:ir.ui.view,arch_db:base_sequence_option.view_ir_sequence_option_line_tree +msgid "Doctype Sequence" +msgstr "" + +#. module: base_sequence_option +#: model:ir.model.fields,help:base_sequence_option.field_ir_sequence_option_line__filter_domain +msgid "Find matching option by document values" +msgstr "" + +#. module: base_sequence_option +#: model:ir.model.fields,field_description:base_sequence_option.field_ir_sequence__id +#: model:ir.model.fields,field_description:base_sequence_option.field_ir_sequence_option__id +#: model:ir.model.fields,field_description:base_sequence_option.field_ir_sequence_option_line__id +msgid "ID" +msgstr "" + +#. module: base_sequence_option +#: model:ir.model.fields,help:base_sequence_option.field_ir_sequence_option__use_sequence_option +#: model:ir.model.fields,help:base_sequence_option.field_ir_sequence_option_line__use_sequence_option +msgid "" +"If checked, Odoo will try to find the new matching sequence first, if not " +"found, fall back to use the original Odoo sequence." +msgstr "" + +#. module: base_sequence_option +#: model:ir.model.fields,field_description:base_sequence_option.field_ir_sequence_option_line__implementation +msgid "Implementation" +msgstr "" + +#. module: base_sequence_option +#: model:ir.model.fields,field_description:base_sequence_option.field_ir_sequence____last_update +#: model:ir.model.fields,field_description:base_sequence_option.field_ir_sequence_option____last_update +#: model:ir.model.fields,field_description:base_sequence_option.field_ir_sequence_option_line____last_update +msgid "Last Modified on" +msgstr "" + +#. module: base_sequence_option +#: model:ir.model.fields,field_description:base_sequence_option.field_ir_sequence_option__write_uid +#: model:ir.model.fields,field_description:base_sequence_option.field_ir_sequence_option_line__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: base_sequence_option +#: model:ir.model.fields,field_description:base_sequence_option.field_ir_sequence_option__write_date +#: model:ir.model.fields,field_description:base_sequence_option.field_ir_sequence_option_line__write_date +msgid "Last Updated on" +msgstr "" + +#. module: base_sequence_option +#: model:ir.actions.act_window,name:base_sequence_option.action_ir_sequence_option +#: model:ir.ui.menu,name:base_sequence_option.menu_ir_sequence_option +#: model_terms:ir.ui.view,arch_db:base_sequence_option.view_ir_sequence_option_tree +msgid "Manage Sequence Options" +msgstr "" + +#. module: base_sequence_option +#: model_terms:ir.ui.view,arch_db:base_sequence_option.view_ir_sequence_option_form +msgid "Matching Domain" +msgstr "" + +#. module: base_sequence_option +#: code:addons/base_sequence_option/models/ir_sequence_option.py:0 +#, python-format +msgid "Multiple optional sequences found for this model!" +msgstr "" + +#. module: base_sequence_option +#: model:ir.model.fields,field_description:base_sequence_option.field_ir_sequence_option__name +#: model_terms:ir.ui.view,arch_db:base_sequence_option.view_ir_sequence_option_form +msgid "Name" +msgstr "" + +#. module: base_sequence_option +#: model:ir.model.fields,field_description:base_sequence_option.field_ir_sequence_option_line__prefix +msgid "Prefix" +msgstr "" + +#. module: base_sequence_option +#: model:ir.model.fields,help:base_sequence_option.field_ir_sequence_option_line__prefix +msgid "Prefix value of the record for the sequence" +msgstr "" + +#. module: base_sequence_option +#: model:ir.model,name:base_sequence_option.model_ir_sequence +#: model:ir.model.fields,field_description:base_sequence_option.field_ir_sequence_option_line__sequence_id +msgid "Sequence" +msgstr "" + +#. module: base_sequence_option +#: model:ir.model,name:base_sequence_option.model_ir_sequence_option +msgid "Sequence Option Base Model" +msgstr "" + +#. module: base_sequence_option +#: model:ir.model,name:base_sequence_option.model_ir_sequence_option_line +msgid "Sequence Option Line" +msgstr "" + +#. module: base_sequence_option +#: model:ir.model.fields,field_description:base_sequence_option.field_ir_sequence_option__option_ids +msgid "Sequence Options" +msgstr "" + +#. module: base_sequence_option +#: model:ir.model.fields,field_description:base_sequence_option.field_ir_sequence__smart_search +#: model:ir.model.fields,field_description:base_sequence_option.field_ir_sequence_option__smart_search +#: model:ir.model.fields,field_description:base_sequence_option.field_ir_sequence_option_line__smart_search +msgid "Smart Search" +msgstr "" + +#. module: base_sequence_option +#: model:ir.model.fields,field_description:base_sequence_option.field_ir_sequence_option_line__suffix +msgid "Suffix" +msgstr "" + +#. module: base_sequence_option +#: model:ir.model.fields,help:base_sequence_option.field_ir_sequence_option_line__suffix +msgid "Suffix value of the record for the sequence" +msgstr "" + +#. module: base_sequence_option +#: model_terms:ir.ui.view,arch_db:base_sequence_option.view_ir_sequence_option_form +msgid "Use Sequence" +msgstr "" + +#. module: base_sequence_option +#: model:ir.model.fields,field_description:base_sequence_option.field_ir_sequence_option__use_sequence_option +#: model:ir.model.fields,field_description:base_sequence_option.field_ir_sequence_option_line__use_sequence_option +msgid "Use sequence options" +msgstr "" + +#. module: base_sequence_option +#: model:ir.model.fields,help:base_sequence_option.field_ir_sequence_option_line__implementation +msgid "" +"While assigning a sequence number to a record, the 'no gap' sequence " +"implementation ensures that each previous sequence number has been assigned " +"already. While this sequence implementation will not skip any sequence " +"number upon assignment, there can still be gaps in the sequence if records " +"are deleted. The 'no gap' implementation is slower than the standard one." +msgstr "" From b562768696ea22b9169342a09749008ed83e41b8 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Tue, 23 Nov 2021 12:47:32 +0000 Subject: [PATCH 4/7] [UPD] README.rst --- base_sequence_option/README.rst | 119 ++++++++++++++++++ .../static/description/index.html | 67 +++++++--- 2 files changed, 168 insertions(+), 18 deletions(-) create mode 100644 base_sequence_option/README.rst diff --git a/base_sequence_option/README.rst b/base_sequence_option/README.rst new file mode 100644 index 000000000..0745017f8 --- /dev/null +++ b/base_sequence_option/README.rst @@ -0,0 +1,119 @@ +==================== +Base Sequence Option +==================== + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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%2Fserver--tools-lightgray.png?logo=github + :target: https://github.com/OCA/server-tools/tree/14.0/base_sequence_option + :alt: OCA/server-tools +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/server-tools-14-0/server-tools-14-0-base_sequence_option + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/149/14.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module allow user to add optional sequences to some document model. +On which sequence is used, is based on domain matching with document values +(and original sequence will be bypassed). + +For example, it is now possible to, + +* Avoid using Odoo automatic sequence on invoice and vendor bill with old style sequence. +* Customer payment and vendor payment to run on different sequence. +* Assign different sales order sequence based on customer region. + +This is a base module and does nothing by itself. Following are modules +that will allow managing sequence options for each type of documents, I.e., + +* Purchase Order: purchase_sequence_option +* Invoice / Bill / Refund / Payment: account_sequence_option +* Others: create a new module with few lines of code + +.. 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: + +Usage +===== + +To use this module, you need to: + +1. Go to *Settings > Technical > Sequences & Identifier > Manage Sequence Options*. +2. Based on extended module installed, different document types will be listed, i.e., Purchase Order. +3. Activite "Use sequence options" to use, if not, fall back to normal sequence. +4. For each option, provide, + * Name: i.e., Customer Invoice for Cust A., Customer Payment, etc. + * Apply On: a filter domain to test whether a document match this option. + * Sequence: select underlining sequence to perform + +**Note:** + +* If no options matches the document, fall back to normal sequence. +* If there are multiple sequence options that match same document, error will be raised. + +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 +~~~~~~~ + +* Ecosoft + +Contributors +~~~~~~~~~~~~ + +* Kitti U. + +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/server-tools `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/base_sequence_option/static/description/index.html b/base_sequence_option/static/description/index.html index 3922ee59f..bf8088a0f 100644 --- a/base_sequence_option/static/description/index.html +++ b/base_sequence_option/static/description/index.html @@ -4,7 +4,7 @@ -Base Cron Exclusion +Base Sequence Option -
-

Base Cron Exclusion

+
+

Base Sequence Option

-

Production/Stable License: LGPL-3 OCA/server-tools Translate me on Weblate Try me on Runbot

-

This module extends the functionality of scheduled actions to allow you to -select the ones that should not run simultaneously.

+

Alpha License: LGPL-3 OCA/server-tools Translate me on Weblate Try me on Runbot

+

This module allow user to add optional sequences to some document model. +On which sequence is used, is based on domain matching with document values +(and original sequence will be bypassed).

+

For example, it is now possible to,

+
    +
  • Avoid using Odoo automatic sequence on invoice and vendor bill with old style sequence.
  • +
  • Customer payment and vendor payment to run on different sequence.
  • +
  • Assign different sales order sequence based on customer region.
  • +
+

This is a base module and does nothing by itself. Following are modules +that will allow managing sequence options for each type of documents, I.e.,

+
    +
  • Purchase Order: purchase_sequence_option
  • +
  • Invoice / Bill / Refund / Payment: account_sequence_option
  • +
  • Others: create a new module with few lines of code
  • +
+
+

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

    @@ -387,19 +407,32 @@ select the ones that should not run simultaneously.

    Usage

    To use this module, you need to:

      -
    1. Go to Settings > Technical > Automation > Scheduled Actions.
    2. -
    3. In the form view go to the tab Mutually Exclusive Scheduled Actions.
    4. -
    5. Fill it with the actions that should be blocked while running the action -you are editing. Note that this is mutual and the selected actions will -block the initial action when running.
    6. +
    7. Go to Settings > Technical > Sequences & Identifier > Manage Sequence Options.
    8. +
    9. Based on extended module installed, different document types will be listed, i.e., Purchase Order.
    10. +
    11. Activite “Use sequence options” to use, if not, fall back to normal sequence.
    12. +
    13. +
      For each option, provide,
      +
        +
      • Name: i.e., Customer Invoice for Cust A., Customer Payment, etc.
      • +
      • Apply On: a filter domain to test whether a document match this option.
      • +
      • Sequence: select underlining sequence to perform
      • +
      +
      +
      +
    +

    Note:

    +
      +
    • If no options matches the document, fall back to normal sequence.
    • +
    • If there are multiple sequence options that match same document, error will be raised.
    • +

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.

+feedback.

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

@@ -407,15 +440,13 @@ If you spotted it first, help us smashing it by providing a detailed and welcome

Authors

    -
  • ForgeFlow
  • +
  • Ecosoft
@@ -426,8 +457,8 @@ If you spotted it first, help us smashing it by providing a detailed and welcome mission is to support the collaborative development of Odoo features and promote its widespread use.

Current maintainer:

-

LoisRForgeFlow

-

This module is part of the OCA/server-tools project on GitHub.

+

kittiu

+

This module is part of the OCA/server-tools project on GitHub.

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

From a60154c6f8ef39235ce7c743cd1d444fca7c1fbb Mon Sep 17 00:00:00 2001 From: Rad0van Date: Mon, 7 Feb 2022 20:18:14 +0100 Subject: [PATCH 5/7] [MIG] base_sequence_option: Migration to 15.0 --- base_sequence_option/README.rst | 23 +++++----- base_sequence_option/__manifest__.py | 3 +- .../static/description/index.html | 44 ++++++++++--------- base_sequence_option/tests/common.py | 4 +- .../views/sequence_option_view.xml | 4 +- 5 files changed, 42 insertions(+), 36 deletions(-) diff --git a/base_sequence_option/README.rst b/base_sequence_option/README.rst index 0745017f8..fc034fa00 100644 --- a/base_sequence_option/README.rst +++ b/base_sequence_option/README.rst @@ -2,10 +2,13 @@ Base Sequence Option ==================== -.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:75d8946f5cd25aef8d9c21b2bff8cba31e807609628e4899a2daca87ecd92196 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png :target: https://odoo-community.org/page/development-status @@ -14,16 +17,16 @@ Base Sequence Option :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html :alt: License: LGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fserver--tools-lightgray.png?logo=github - :target: https://github.com/OCA/server-tools/tree/14.0/base_sequence_option + :target: https://github.com/OCA/server-tools/tree/15.0/base_sequence_option :alt: OCA/server-tools .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/server-tools-14-0/server-tools-14-0-base_sequence_option + :target: https://translation.odoo-community.org/projects/server-tools-15-0/server-tools-15-0-base_sequence_option :alt: Translate me on Weblate -.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/149/14.0 - :alt: Try me on Runbot +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/server-tools&target_branch=15.0 + :alt: Try me on Runboat -|badge1| |badge2| |badge3| |badge4| |badge5| +|badge1| |badge2| |badge3| |badge4| |badge5| This module allow user to add optional sequences to some document model. On which sequence is used, is based on domain matching with document values @@ -75,8 +78,8 @@ 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 `_. +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. @@ -114,6 +117,6 @@ Current `maintainer `__: |maintainer-kittiu| -This module is part of the `OCA/server-tools `_ project on GitHub. +This module is part of the `OCA/server-tools `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/base_sequence_option/__manifest__.py b/base_sequence_option/__manifest__.py index 3bbd82f7f..661a2ae38 100644 --- a/base_sequence_option/__manifest__.py +++ b/base_sequence_option/__manifest__.py @@ -4,13 +4,14 @@ { "name": "Base Sequence Option", "summary": "Alternative sequence options for specific models", - "version": "14.0.1.0.0", + "version": "15.0.1.0.0", "author": "Ecosoft, Odoo Community Association (OCA)", "maintainers": ["kittiu"], "development_status": "Alpha", "website": "https://github.com/OCA/server-tools", "category": "Tools", "depends": ["base"], + "external_dependencies": {"python": ["odoo_test_helper"]}, "data": [ "security/ir.model.access.csv", "security/sequence_option_security.xml", diff --git a/base_sequence_option/static/description/index.html b/base_sequence_option/static/description/index.html index bf8088a0f..905a23193 100644 --- a/base_sequence_option/static/description/index.html +++ b/base_sequence_option/static/description/index.html @@ -1,20 +1,20 @@ - + - + Base Sequence Option