diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7375a99..0d9c29b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -71,10 +71,11 @@ test_all_modules: --db_password flectra --database test_all --test-enable - --init base_cancel_confirm,filter_multi_user,default_multi_user,sequence_range_end,sequence_reset_period,sequence_check_digit,base_import_security_group,date_range,base_tier_validation_forward,base_menu_visibility_restriction,barcode_action,multi_step_wizard,base_technical_features,base_tier_validation_formula,base_tier_validation,base_search_custom_field_filter,base_revision,base_export_manager,document_quick_access,mass_editing,base_tier_validation_server_action,mass_operation_abstract,chained_swapper,base_optional_quick_create,document_quick_access_folder_auto_classification + --init base_cancel_confirm,base_substate,filter_multi_user,default_multi_user,sequence_range_end,sequence_reset_period,sequence_check_digit,base_import_security_group,date_range,base_tier_validation_forward,base_menu_visibility_restriction,barcode_action,multi_step_wizard,base_technical_features,base_tier_validation_formula,base_tier_validation,base_search_custom_field_filter,base_revision,base_export_manager,document_quick_access,mass_editing,base_tier_validation_server_action,mass_operation_abstract,chained_swapper,base_optional_quick_create,document_quick_access_folder_auto_classification --stop-after-init --log-level error --log-handler flectra.addons.base_cancel_confirm:TEST + --log-handler flectra.addons.base_substate:TEST --log-handler flectra.addons.filter_multi_user:TEST --log-handler flectra.addons.default_multi_user:TEST --log-handler flectra.addons.sequence_range_end:TEST @@ -162,6 +163,66 @@ test_module_base_cancel_confirm: --log-level error --log-handler flectra.addons.base_cancel_confirm:TEST" +test_module_base_substate: + stage: testsingle + when: on_failure + image: + name: registry.gitlab.com/jamotion/flectra/ubuntudev:2-latest + entrypoint: ["/bin/sh", "-c"] + script: + - apt-get install -y p7zip-full + - apt install -y expect-dev libzbar0 poppler-utils + - pip3 install -r ${CI_PROJECT_DIR}/requirements.txt + - su - flectra -c "mkdir ~/others" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/account-analytic.git ~/others/account-analytic" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/account-closing.git ~/others/account-closing" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/account-financial-tools.git ~/others/account-financial-tools" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/account-invoicing.git ~/others/account-invoicing" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/account-payment.git ~/others/account-payment" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/bank-payment.git ~/others/bank-payment" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/brand.git ~/others/brand" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/community-data-files.git ~/others/community-data-files" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/connector.git ~/others/connector" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/edi.git ~/others/edi" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/partner-contact.git ~/others/partner-contact" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/product-attribute.git ~/others/product-attribute" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/queue.git ~/others/queue" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/report-print-send.git ~/others/report-print-send" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/reporting-engine.git ~/others/reporting-engine" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/rest-framework.git ~/others/rest-framework" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/sale-workflow.git ~/others/sale-workflow" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/server-auth.git ~/others/server-auth" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/server-env.git ~/others/server-env" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/server-tools.git ~/others/server-tools" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/social.git ~/others/social" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/stock-logistics-transport.git ~/others/stock-logistics-transport" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/stock-logistics-warehouse.git ~/others/stock-logistics-warehouse" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/stock-logistics-workflow.git ~/others/stock-logistics-workflow" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/storage.git ~/others/storage" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/web.git ~/others/web" + - su - flectra -c "git clone --branch 20-fixed --depth 1 https://gitlab-ci-token:${CI_JOB_TOKEN}@gitlab.com/flectra-community/wms.git ~/others/wms" + - sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && dpkg-reconfigure --frontend=noninteractive locales && update-locale LANG=en_US.UTF-8 + - mkdir ${CI_PROJECT_DIR}/ci_data + - wget -O ${CI_PROJECT_DIR}/ci_data/test_base.zip https://gitlab.com/flectra-community/devops/oca2fc/raw/master/ci_data/test_base.zip + - 7z x -o ${CI_PROJECT_DIR}/ci_data/ ${CI_PROJECT_DIR}/ci_data/test_base.zip + - export PGPASSWORD="flectra" + - createdb -h psql -U flectra -O flectra -T template1 test_base_substate + - psql -h psql -U flectra -d test_base_substate -f ${CI_PROJECT_DIR}/ci_data/dump.sql + - su - flectra -c "mkdir -p ~/.local/share/filestore" + - mv ${CI_PROJECT_DIR}/ci_data/filestore /opt/flectra/.local/share/filestore/test_base_substate + - chown -R flectra.flectra /opt/flectra/.local/share/filestore/test_base_substate + - su - flectra -c "/opt/flectra/flectra-bin + --addons-path ${CI_PROJECT_DIR},~/others/account-analytic,~/others/account-closing,~/others/account-financial-tools,~/others/account-invoicing,~/others/account-payment,~/others/bank-payment,~/others/brand,~/others/community-data-files,~/others/connector,~/others/edi,~/others/partner-contact,~/others/product-attribute,~/others/queue,~/others/report-print-send,~/others/reporting-engine,~/others/rest-framework,~/others/sale-workflow,~/others/server-auth,~/others/server-env,~/others/server-tools,~/others/social,~/others/stock-logistics-transport,~/others/stock-logistics-warehouse,~/others/stock-logistics-workflow,~/others/storage,~/others/web,~/others/wms + --db_host psql + --db_port 5432 + --db_user flectra + --db_password flectra + --database test_base_substate + --test-enable -i base_substate + --stop-after-init + --log-level error + --log-handler flectra.addons.base_substate:TEST" + test_module_filter_multi_user: stage: testsingle when: on_failure diff --git a/README.md b/README.md index 4ef2400..ab7178f 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ Available addons addon | version | summary --- | --- | --- [base_cancel_confirm](base_cancel_confirm/) | 2.0.1.0.2| Base Cancel Confirm +[base_substate](base_substate/) | 2.0.1.0.0| Base Sub State [filter_multi_user](filter_multi_user/) | 2.0.1.0.0| Allows to share user-defined filters filters among several users. [default_multi_user](default_multi_user/) | 2.0.1.0.0| Allows to share user-defined defaults among several users. [sequence_range_end](sequence_range_end/) | 2.0.1.0.0| Sequence prefix/suffix option, 'range_end_', to use the beginning of the range diff --git a/base_substate/COPYRIGHT b/base_substate/COPYRIGHT new file mode 100644 index 0000000..8c28c19 --- /dev/null +++ b/base_substate/COPYRIGHT @@ -0,0 +1,18 @@ +Most of the files are + + :Copyright: This stylesheet has been placed in the public domain. + +

Beta License: AGPL-3 OCA/server-ux Translate me on Weblate Try me on Runbot

+

This module provide abstract models to manage customizable +substates to be applied on different models (sale order, purchase, …).

+
+

example:

+ +

It is not useful for itself. You can see an example of implementation +in the ‘purchase_substate’ module. (purchase-workflow repository).

+

Table of contents

+
+ +
+
+

Usage

+
    +
  1. You must install an application module depending this one (for example purchase_substate)
  2. +
+
+
+

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

+
    +
  • Akretion
  • +
+
+
+

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/server-ux project on GitHub.

+

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

+
+
+
+ + + diff --git a/base_substate/tests/__init__.py b/base_substate/tests/__init__.py new file mode 100644 index 0000000..7b880d2 --- /dev/null +++ b/base_substate/tests/__init__.py @@ -0,0 +1 @@ +from . import test_base_substate diff --git a/base_substate/tests/models.py b/base_substate/tests/models.py new file mode 100644 index 0000000..e1df037 --- /dev/null +++ b/base_substate/tests/models.py @@ -0,0 +1,53 @@ +# Copyright 2020 Akretion Mourad EL HADJ MIMOUNE +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +from flectra import api, fields, models + + +class SaleTest(models.Model): + _inherit = "base.substate.mixin" + _name = "base.substate.test.sale" + _description = "Base substate Test Model" + + name = fields.Char(required=True) + user_id = fields.Many2one("res.users", string="Responsible") + state = fields.Selection( + [("draft", "New"), ("cancel", "Cancelled"), ("sale", "Sale"), ("done", "Done")], + string="Status", + readonly=True, + default="draft", + ) + active = fields.Boolean(default=True) + partner_id = fields.Many2one("res.partner", string="Partner") + line_ids = fields.One2many( + comodel_name="base.substate.test.sale.line", + inverse_name="sale_id", + context={"active_test": False}, + ) + amount_total = fields.Float(compute="_compute_amount_total", store=True) + + @api.depends("line_ids") + def _compute_amount_total(self): + for record in self: + for line in record.line_ids: + record.amount_total += line.amount * line.qty + + def button_confirm(self): + self.write({"state": "sale"}) + return True + + def button_cancel(self): + self.write({"state": "cancel"}) + + +class LineTest(models.Model): + _name = "base.substate.test.sale.line" + _description = "Base substate Test Model Line" + + name = fields.Char() + sale_id = fields.Many2one( + comodel_name="base.substate.test.sale", + ondelete="cascade", + context={"active_test": False}, + ) + qty = fields.Float() + amount = fields.Float() diff --git a/base_substate/tests/test_base_substate.py b/base_substate/tests/test_base_substate.py new file mode 100644 index 0000000..000cf0f --- /dev/null +++ b/base_substate/tests/test_base_substate.py @@ -0,0 +1,121 @@ +# Copyright 2020 Akretion Mourad EL HADJ MIMOUNE +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from flectra_test_helper import FakeModelLoader + +from flectra.tests import common, tagged + + +@tagged("-at_install", "post_install") +class TestBaseSubstate(common.SavepointCase, FakeModelLoader): + @classmethod + def setUpClass(cls): + super(TestBaseSubstate, cls).setUpClass() + cls.loader = FakeModelLoader(cls.env, cls.__module__) + cls.loader.backup_registry() + from .models import LineTest, SaleTest + + cls.loader.update_registry((SaleTest, LineTest)) + + cls.substate_test_sale = cls.env["base.substate.test.sale"] + cls.substate_test_sale_line = cls.env["base.substate.test.sale.line"] + + cls.base_substate = cls.env["base.substate.mixin"] + cls.substate_type = cls.env["base.substate.type"] + + cls.substate_type._fields["model"].selection.append( + ("base.substate.test.sale", "Sale Order") + ) + + cls.substate_type = cls.env["base.substate.type"].create( + { + "name": "Sale", + "model": "base.substate.test.sale", + "target_state_field": "state", + } + ) + + cls.substate_val_quotation = cls.env["target.state.value"].create( + { + "name": "Quotation", + "base_substate_type_id": cls.substate_type.id, + "target_state_value": "draft", + } + ) + + cls.substate_val_sale = cls.env["target.state.value"].create( + { + "name": "Sale order", + "base_substate_type_id": cls.substate_type.id, + "target_state_value": "sale", + } + ) + cls.substate_under_negotiation = cls.env["base.substate"].create( + { + "name": "Under negotiation", + "sequence": 1, + "target_state_value_id": cls.substate_val_quotation.id, + } + ) + + cls.substate_won = cls.env["base.substate"].create( + { + "name": "Won", + "sequence": 3, + "target_state_value_id": cls.substate_val_quotation.id, + } + ) + + cls.substate_wait_docs = cls.env["base.substate"].create( + { + "name": "Waiting for legal documents", + "sequence": 4, + "target_state_value_id": cls.substate_val_sale.id, + } + ) + + cls.substate_valid_docs = cls.env["base.substate"].create( + { + "name": "To validate legal documents", + "sequence": 5, + "target_state_value_id": cls.substate_val_sale.id, + } + ) + + cls.substate_in_delivering = cls.env["base.substate"].create( + { + "name": "In delivering", + "sequence": 6, + "target_state_value_id": cls.substate_val_sale.id, + } + ) + + @classmethod + def tearDownClass(cls): + cls.loader.restore_registry() + super().tearDownClass() + + def test_sale_order_substate(self): + partner = self.env.ref("base.res_partner_1") + so_test1 = self.substate_test_sale.create( + { + "name": "Test base substate to basic sale", + "partner_id": partner.id, + "line_ids": [ + (0, 0, {"name": "line test", "amount": 120.0, "qty": 1.5}) + ], + } + ) + self.assertTrue(so_test1.state == "draft") + self.assertTrue(so_test1.substate_id == self.substate_under_negotiation) + + # Test that validation of sale order change substate_id + so_test1.button_confirm() + self.assertTrue(so_test1.state == "sale") + self.assertTrue(so_test1.substate_id == self.substate_wait_docs) + + # Test that substate_id is set to false if + # there is not substate corresponding to state + so_test1.button_cancel() + self.assertTrue(so_test1.state == "cancel") + self.assertTrue(not so_test1.substate_id) diff --git a/base_substate/views/base_substate_type_views.xml b/base_substate/views/base_substate_type_views.xml new file mode 100644 index 0000000..b5a2fa0 --- /dev/null +++ b/base_substate/views/base_substate_type_views.xml @@ -0,0 +1,85 @@ + + + + + base.substate.type + + + + + + + + + + base.substate.type + +
+ +
+
+ + + + + + +
+
+
+
+ + base.substate.type + + + + + + + + + + Sub State Type + ir.actions.act_window + base.substate.type + tree,form + + [] + {} + + + + + form + + + + + + tree + + + + +
diff --git a/base_substate/views/base_substate_value_views.xml b/base_substate/views/base_substate_value_views.xml new file mode 100644 index 0000000..8fae74c --- /dev/null +++ b/base_substate/views/base_substate_value_views.xml @@ -0,0 +1,83 @@ + + + + + target.state.value + + + + + + + + + + target.state.value + +
+ +
+
+ + + + + + +
+
+
+
+ + target.state.value + + + + + + + + + + Target State Value + ir.actions.act_window + target.state.value + tree,form + + [] + {} + + + + + form + + + + + + tree + + + +
diff --git a/base_substate/views/base_substate_views.xml b/base_substate/views/base_substate_views.xml new file mode 100644 index 0000000..7296e22 --- /dev/null +++ b/base_substate/views/base_substate_views.xml @@ -0,0 +1,89 @@ + + + + + base.substate + + + + + + + + + + + + base.substate + +
+ +
+ +
+
+
+ + + + + + + + + +
+
+
+
+ + base.substate + + + + + + + + Base Substate + ir.actions.act_window + base.substate + tree,form + + [] + {} + + + + + form + + + + + + tree + + + +