From db1cf1f456123a7ec9e1ac7cb810b292495553d4 Mon Sep 17 00:00:00 2001 From: Flectra Community Bot Date: Sun, 25 Jul 2021 02:12:32 +0000 Subject: [PATCH] Automatic Update form OCA2FC Migrator --- .gitlab-ci.yml | 806 +++++++++--------- README.md | 31 +- base_tier_validation/__manifest__.py | 2 +- base_tier_validation/data/mail_data.xml | 10 + .../i18n/base_tier_validation.pot | 11 + base_tier_validation/i18n/es.po | 11 + base_tier_validation/i18n/fr.po | 11 + base_tier_validation/i18n/nl_NL.po | 11 + base_tier_validation/i18n/zh_CN.po | 11 + .../models/tier_validation.py | 21 +- .../__manifest__.py | 2 +- .../models/tier_review.py | 28 +- chained_swapper/COPYRIGHT | 17 + chained_swapper/LICENSE | 663 ++++++++++++++ chained_swapper/README.rst | 140 +++ chained_swapper/__init__.py | 5 + chained_swapper/__manifest__.py | 19 + chained_swapper/demo/chained_swapper_demo.xml | 43 + chained_swapper/hooks.py | 14 + chained_swapper/i18n/chained_swapper.pot | 280 ++++++ chained_swapper/i18n/es.po | 296 +++++++ chained_swapper/models/__init__.py | 3 + chained_swapper/models/chained_swapper.py | 196 +++++ chained_swapper/security/ir.model.access.csv | 8 + chained_swapper/static/description/icon.png | Bin 0 -> 9455 bytes chained_swapper/static/description/index.html | 490 +++++++++++ chained_swapper/tests/__init__.py | 3 + chained_swapper/tests/test_chained_swapper.py | 104 +++ .../views/chained_swapper_views.xml | 145 ++++ chained_swapper/wizard/__init__.py | 3 + .../wizard/chained_swapper_wizard.py | 164 ++++ .../wizard/chained_swapper_wizard_views.xml | 23 + mass_editing/COPYRIGHT | 4 +- 33 files changed, 3154 insertions(+), 421 deletions(-) create mode 100644 chained_swapper/COPYRIGHT create mode 100644 chained_swapper/LICENSE create mode 100644 chained_swapper/README.rst create mode 100644 chained_swapper/__init__.py create mode 100644 chained_swapper/__manifest__.py create mode 100644 chained_swapper/demo/chained_swapper_demo.xml create mode 100644 chained_swapper/hooks.py create mode 100644 chained_swapper/i18n/chained_swapper.pot create mode 100644 chained_swapper/i18n/es.po create mode 100644 chained_swapper/models/__init__.py create mode 100644 chained_swapper/models/chained_swapper.py create mode 100644 chained_swapper/security/ir.model.access.csv create mode 100644 chained_swapper/static/description/icon.png create mode 100644 chained_swapper/static/description/index.html create mode 100644 chained_swapper/tests/__init__.py create mode 100644 chained_swapper/tests/test_chained_swapper.py create mode 100644 chained_swapper/views/chained_swapper_views.xml create mode 100644 chained_swapper/wizard/__init__.py create mode 100644 chained_swapper/wizard/chained_swapper_wizard.py create mode 100644 chained_swapper/wizard/chained_swapper_wizard_views.xml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f951ba8..07ee644 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -44,30 +44,31 @@ test_all_modules: --db_password flectra --database test_all --test-enable - --init base_cancel_confirm,base_technical_features,base_menu_visibility_restriction,mass_editing,base_optional_quick_create,filter_multi_user,barcode_action,base_tier_validation_server_action,base_tier_validation,document_quick_access,base_export_manager,sequence_check_digit,base_tier_validation_formula,sequence_reset_period,base_search_custom_field_filter,date_range,base_tier_validation_forward,default_multi_user,base_revision,multi_step_wizard,base_import_security_group + --init base_cancel_confirm,filter_multi_user,default_multi_user,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,chained_swapper,base_optional_quick_create --stop-after-init --log-level error --log-handler flectra.addons.base_cancel_confirm:TEST - --log-handler flectra.addons.base_technical_features:TEST - --log-handler flectra.addons.base_menu_visibility_restriction:TEST - --log-handler flectra.addons.mass_editing:TEST - --log-handler flectra.addons.base_optional_quick_create:TEST --log-handler flectra.addons.filter_multi_user:TEST - --log-handler flectra.addons.barcode_action:TEST - --log-handler flectra.addons.base_tier_validation_server_action:TEST - --log-handler flectra.addons.base_tier_validation:TEST - --log-handler flectra.addons.document_quick_access:TEST - --log-handler flectra.addons.base_export_manager:TEST - --log-handler flectra.addons.sequence_check_digit:TEST - --log-handler flectra.addons.base_tier_validation_formula:TEST + --log-handler flectra.addons.default_multi_user:TEST --log-handler flectra.addons.sequence_reset_period:TEST - --log-handler flectra.addons.base_search_custom_field_filter:TEST + --log-handler flectra.addons.sequence_check_digit:TEST + --log-handler flectra.addons.base_import_security_group:TEST --log-handler flectra.addons.date_range:TEST --log-handler flectra.addons.base_tier_validation_forward:TEST - --log-handler flectra.addons.default_multi_user:TEST - --log-handler flectra.addons.base_revision:TEST + --log-handler flectra.addons.base_menu_visibility_restriction:TEST + --log-handler flectra.addons.barcode_action:TEST --log-handler flectra.addons.multi_step_wizard:TEST - --log-handler flectra.addons.base_import_security_group:TEST + --log-handler flectra.addons.base_technical_features:TEST + --log-handler flectra.addons.base_tier_validation_formula:TEST + --log-handler flectra.addons.base_tier_validation:TEST + --log-handler flectra.addons.base_search_custom_field_filter:TEST + --log-handler flectra.addons.base_revision:TEST + --log-handler flectra.addons.base_export_manager:TEST + --log-handler flectra.addons.document_quick_access:TEST + --log-handler flectra.addons.mass_editing:TEST + --log-handler flectra.addons.base_tier_validation_server_action:TEST + --log-handler flectra.addons.chained_swapper:TEST + --log-handler flectra.addons.base_optional_quick_create:TEST " @@ -104,138 +105,6 @@ test_module_base_cancel_confirm: --log-level error --log-handler flectra.addons.base_cancel_confirm:TEST" -test_module_base_technical_features: - 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 - - pip3 install -r ${CI_PROJECT_DIR}/requirements.txt - - su - flectra -c "mkdir ~/others" - - 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_technical_features - - psql -h psql -U flectra -d test_base_technical_features -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_technical_features - - chown -R flectra.flectra /opt/flectra/.local/share/filestore/test_base_technical_features - - su - flectra -c "/opt/flectra/flectra-bin - --addons-path ${CI_PROJECT_DIR} - --db_host psql - --db_port 5432 - --db_user flectra - --db_password flectra - --database test_base_technical_features - --test-enable -i base_technical_features - --stop-after-init - --log-level error - --log-handler flectra.addons.base_technical_features:TEST" - -test_module_base_menu_visibility_restriction: - 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 - - pip3 install -r ${CI_PROJECT_DIR}/requirements.txt - - su - flectra -c "mkdir ~/others" - - 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_menu_visibility_restriction - - psql -h psql -U flectra -d test_base_menu_visibility_restriction -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_menu_visibility_restriction - - chown -R flectra.flectra /opt/flectra/.local/share/filestore/test_base_menu_visibility_restriction - - su - flectra -c "/opt/flectra/flectra-bin - --addons-path ${CI_PROJECT_DIR} - --db_host psql - --db_port 5432 - --db_user flectra - --db_password flectra - --database test_base_menu_visibility_restriction - --test-enable -i base_menu_visibility_restriction - --stop-after-init - --log-level error - --log-handler flectra.addons.base_menu_visibility_restriction:TEST" - -test_module_mass_editing: - 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 - - pip3 install -r ${CI_PROJECT_DIR}/requirements.txt - - su - flectra -c "mkdir ~/others" - - 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_mass_editing - - psql -h psql -U flectra -d test_mass_editing -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_mass_editing - - chown -R flectra.flectra /opt/flectra/.local/share/filestore/test_mass_editing - - su - flectra -c "/opt/flectra/flectra-bin - --addons-path ${CI_PROJECT_DIR} - --db_host psql - --db_port 5432 - --db_user flectra - --db_password flectra - --database test_mass_editing - --test-enable -i mass_editing - --stop-after-init - --log-level error - --log-handler flectra.addons.mass_editing:TEST" - -test_module_base_optional_quick_create: - 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 - - pip3 install -r ${CI_PROJECT_DIR}/requirements.txt - - su - flectra -c "mkdir ~/others" - - 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_optional_quick_create - - psql -h psql -U flectra -d test_base_optional_quick_create -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_optional_quick_create - - chown -R flectra.flectra /opt/flectra/.local/share/filestore/test_base_optional_quick_create - - su - flectra -c "/opt/flectra/flectra-bin - --addons-path ${CI_PROJECT_DIR} - --db_host psql - --db_port 5432 - --db_user flectra - --db_password flectra - --database test_base_optional_quick_create - --test-enable -i base_optional_quick_create - --stop-after-init - --log-level error - --log-handler flectra.addons.base_optional_quick_create:TEST" - test_module_filter_multi_user: stage: testsingle when: on_failure @@ -269,7 +138,7 @@ test_module_filter_multi_user: --log-level error --log-handler flectra.addons.filter_multi_user:TEST" -test_module_barcode_action: +test_module_default_multi_user: stage: testsingle when: on_failure image: @@ -285,220 +154,22 @@ test_module_barcode_action: - 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_barcode_action - - psql -h psql -U flectra -d test_barcode_action -f ${CI_PROJECT_DIR}/ci_data/dump.sql + - createdb -h psql -U flectra -O flectra -T template1 test_default_multi_user + - psql -h psql -U flectra -d test_default_multi_user -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_barcode_action - - chown -R flectra.flectra /opt/flectra/.local/share/filestore/test_barcode_action + - mv ${CI_PROJECT_DIR}/ci_data/filestore /opt/flectra/.local/share/filestore/test_default_multi_user + - chown -R flectra.flectra /opt/flectra/.local/share/filestore/test_default_multi_user - su - flectra -c "/opt/flectra/flectra-bin --addons-path ${CI_PROJECT_DIR} --db_host psql --db_port 5432 --db_user flectra --db_password flectra - --database test_barcode_action - --test-enable -i barcode_action + --database test_default_multi_user + --test-enable -i default_multi_user --stop-after-init --log-level error - --log-handler flectra.addons.barcode_action:TEST" - -test_module_base_tier_validation_server_action: - 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 - - pip3 install -r ${CI_PROJECT_DIR}/requirements.txt - - su - flectra -c "mkdir ~/others" - - 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_tier_validation_server_action - - psql -h psql -U flectra -d test_base_tier_validation_server_action -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_tier_validation_server_action - - chown -R flectra.flectra /opt/flectra/.local/share/filestore/test_base_tier_validation_server_action - - su - flectra -c "/opt/flectra/flectra-bin - --addons-path ${CI_PROJECT_DIR} - --db_host psql - --db_port 5432 - --db_user flectra - --db_password flectra - --database test_base_tier_validation_server_action - --test-enable -i base_tier_validation_server_action - --stop-after-init - --log-level error - --log-handler flectra.addons.base_tier_validation_server_action:TEST" - -test_module_base_tier_validation: - 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 - - pip3 install -r ${CI_PROJECT_DIR}/requirements.txt - - su - flectra -c "mkdir ~/others" - - 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_tier_validation - - psql -h psql -U flectra -d test_base_tier_validation -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_tier_validation - - chown -R flectra.flectra /opt/flectra/.local/share/filestore/test_base_tier_validation - - su - flectra -c "/opt/flectra/flectra-bin - --addons-path ${CI_PROJECT_DIR} - --db_host psql - --db_port 5432 - --db_user flectra - --db_password flectra - --database test_base_tier_validation - --test-enable -i base_tier_validation - --stop-after-init - --log-level error - --log-handler flectra.addons.base_tier_validation:TEST" - -test_module_document_quick_access: - 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 - - pip3 install -r ${CI_PROJECT_DIR}/requirements.txt - - su - flectra -c "mkdir ~/others" - - 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_document_quick_access - - psql -h psql -U flectra -d test_document_quick_access -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_document_quick_access - - chown -R flectra.flectra /opt/flectra/.local/share/filestore/test_document_quick_access - - su - flectra -c "/opt/flectra/flectra-bin - --addons-path ${CI_PROJECT_DIR} - --db_host psql - --db_port 5432 - --db_user flectra - --db_password flectra - --database test_document_quick_access - --test-enable -i document_quick_access - --stop-after-init - --log-level error - --log-handler flectra.addons.document_quick_access:TEST" - -test_module_base_export_manager: - 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 - - pip3 install -r ${CI_PROJECT_DIR}/requirements.txt - - su - flectra -c "mkdir ~/others" - - 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_export_manager - - psql -h psql -U flectra -d test_base_export_manager -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_export_manager - - chown -R flectra.flectra /opt/flectra/.local/share/filestore/test_base_export_manager - - su - flectra -c "/opt/flectra/flectra-bin - --addons-path ${CI_PROJECT_DIR} - --db_host psql - --db_port 5432 - --db_user flectra - --db_password flectra - --database test_base_export_manager - --test-enable -i base_export_manager - --stop-after-init - --log-level error - --log-handler flectra.addons.base_export_manager:TEST" - -test_module_sequence_check_digit: - 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 - - pip3 install -r ${CI_PROJECT_DIR}/requirements.txt - - su - flectra -c "mkdir ~/others" - - 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_sequence_check_digit - - psql -h psql -U flectra -d test_sequence_check_digit -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_sequence_check_digit - - chown -R flectra.flectra /opt/flectra/.local/share/filestore/test_sequence_check_digit - - su - flectra -c "/opt/flectra/flectra-bin - --addons-path ${CI_PROJECT_DIR} - --db_host psql - --db_port 5432 - --db_user flectra - --db_password flectra - --database test_sequence_check_digit - --test-enable -i sequence_check_digit - --stop-after-init - --log-level error - --log-handler flectra.addons.sequence_check_digit:TEST" - -test_module_base_tier_validation_formula: - 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 - - pip3 install -r ${CI_PROJECT_DIR}/requirements.txt - - su - flectra -c "mkdir ~/others" - - 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_tier_validation_formula - - psql -h psql -U flectra -d test_base_tier_validation_formula -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_tier_validation_formula - - chown -R flectra.flectra /opt/flectra/.local/share/filestore/test_base_tier_validation_formula - - su - flectra -c "/opt/flectra/flectra-bin - --addons-path ${CI_PROJECT_DIR} - --db_host psql - --db_port 5432 - --db_user flectra - --db_password flectra - --database test_base_tier_validation_formula - --test-enable -i base_tier_validation_formula - --stop-after-init - --log-level error - --log-handler flectra.addons.base_tier_validation_formula:TEST" + --log-handler flectra.addons.default_multi_user:TEST" test_module_sequence_reset_period: stage: testsingle @@ -533,7 +204,7 @@ test_module_sequence_reset_period: --log-level error --log-handler flectra.addons.sequence_reset_period:TEST" -test_module_base_search_custom_field_filter: +test_module_sequence_check_digit: stage: testsingle when: on_failure image: @@ -549,22 +220,55 @@ test_module_base_search_custom_field_filter: - 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_search_custom_field_filter - - psql -h psql -U flectra -d test_base_search_custom_field_filter -f ${CI_PROJECT_DIR}/ci_data/dump.sql + - createdb -h psql -U flectra -O flectra -T template1 test_sequence_check_digit + - psql -h psql -U flectra -d test_sequence_check_digit -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_search_custom_field_filter - - chown -R flectra.flectra /opt/flectra/.local/share/filestore/test_base_search_custom_field_filter + - mv ${CI_PROJECT_DIR}/ci_data/filestore /opt/flectra/.local/share/filestore/test_sequence_check_digit + - chown -R flectra.flectra /opt/flectra/.local/share/filestore/test_sequence_check_digit - su - flectra -c "/opt/flectra/flectra-bin --addons-path ${CI_PROJECT_DIR} --db_host psql --db_port 5432 --db_user flectra --db_password flectra - --database test_base_search_custom_field_filter - --test-enable -i base_search_custom_field_filter + --database test_sequence_check_digit + --test-enable -i sequence_check_digit --stop-after-init --log-level error - --log-handler flectra.addons.base_search_custom_field_filter:TEST" + --log-handler flectra.addons.sequence_check_digit:TEST" + +test_module_base_import_security_group: + 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 + - pip3 install -r ${CI_PROJECT_DIR}/requirements.txt + - su - flectra -c "mkdir ~/others" + - 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_import_security_group + - psql -h psql -U flectra -d test_base_import_security_group -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_import_security_group + - chown -R flectra.flectra /opt/flectra/.local/share/filestore/test_base_import_security_group + - su - flectra -c "/opt/flectra/flectra-bin + --addons-path ${CI_PROJECT_DIR} + --db_host psql + --db_port 5432 + --db_user flectra + --db_password flectra + --database test_base_import_security_group + --test-enable -i base_import_security_group + --stop-after-init + --log-level error + --log-handler flectra.addons.base_import_security_group:TEST" test_module_date_range: stage: testsingle @@ -632,7 +336,7 @@ test_module_base_tier_validation_forward: --log-level error --log-handler flectra.addons.base_tier_validation_forward:TEST" -test_module_default_multi_user: +test_module_base_menu_visibility_restriction: stage: testsingle when: on_failure image: @@ -648,24 +352,24 @@ test_module_default_multi_user: - 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_default_multi_user - - psql -h psql -U flectra -d test_default_multi_user -f ${CI_PROJECT_DIR}/ci_data/dump.sql + - createdb -h psql -U flectra -O flectra -T template1 test_base_menu_visibility_restriction + - psql -h psql -U flectra -d test_base_menu_visibility_restriction -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_default_multi_user - - chown -R flectra.flectra /opt/flectra/.local/share/filestore/test_default_multi_user + - mv ${CI_PROJECT_DIR}/ci_data/filestore /opt/flectra/.local/share/filestore/test_base_menu_visibility_restriction + - chown -R flectra.flectra /opt/flectra/.local/share/filestore/test_base_menu_visibility_restriction - su - flectra -c "/opt/flectra/flectra-bin --addons-path ${CI_PROJECT_DIR} --db_host psql --db_port 5432 --db_user flectra --db_password flectra - --database test_default_multi_user - --test-enable -i default_multi_user + --database test_base_menu_visibility_restriction + --test-enable -i base_menu_visibility_restriction --stop-after-init --log-level error - --log-handler flectra.addons.default_multi_user:TEST" + --log-handler flectra.addons.base_menu_visibility_restriction:TEST" -test_module_base_revision: +test_module_barcode_action: stage: testsingle when: on_failure image: @@ -681,22 +385,22 @@ test_module_base_revision: - 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_revision - - psql -h psql -U flectra -d test_base_revision -f ${CI_PROJECT_DIR}/ci_data/dump.sql + - createdb -h psql -U flectra -O flectra -T template1 test_barcode_action + - psql -h psql -U flectra -d test_barcode_action -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_revision - - chown -R flectra.flectra /opt/flectra/.local/share/filestore/test_base_revision + - mv ${CI_PROJECT_DIR}/ci_data/filestore /opt/flectra/.local/share/filestore/test_barcode_action + - chown -R flectra.flectra /opt/flectra/.local/share/filestore/test_barcode_action - su - flectra -c "/opt/flectra/flectra-bin --addons-path ${CI_PROJECT_DIR} --db_host psql --db_port 5432 --db_user flectra --db_password flectra - --database test_base_revision - --test-enable -i base_revision + --database test_barcode_action + --test-enable -i barcode_action --stop-after-init --log-level error - --log-handler flectra.addons.base_revision:TEST" + --log-handler flectra.addons.barcode_action:TEST" test_module_multi_step_wizard: stage: testsingle @@ -731,7 +435,7 @@ test_module_multi_step_wizard: --log-level error --log-handler flectra.addons.multi_step_wizard:TEST" -test_module_base_import_security_group: +test_module_base_technical_features: stage: testsingle when: on_failure image: @@ -747,20 +451,350 @@ test_module_base_import_security_group: - 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_import_security_group - - psql -h psql -U flectra -d test_base_import_security_group -f ${CI_PROJECT_DIR}/ci_data/dump.sql + - createdb -h psql -U flectra -O flectra -T template1 test_base_technical_features + - psql -h psql -U flectra -d test_base_technical_features -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_import_security_group - - chown -R flectra.flectra /opt/flectra/.local/share/filestore/test_base_import_security_group + - mv ${CI_PROJECT_DIR}/ci_data/filestore /opt/flectra/.local/share/filestore/test_base_technical_features + - chown -R flectra.flectra /opt/flectra/.local/share/filestore/test_base_technical_features - su - flectra -c "/opt/flectra/flectra-bin --addons-path ${CI_PROJECT_DIR} --db_host psql --db_port 5432 --db_user flectra --db_password flectra - --database test_base_import_security_group - --test-enable -i base_import_security_group + --database test_base_technical_features + --test-enable -i base_technical_features --stop-after-init --log-level error - --log-handler flectra.addons.base_import_security_group:TEST" + --log-handler flectra.addons.base_technical_features:TEST" + +test_module_base_tier_validation_formula: + 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 + - pip3 install -r ${CI_PROJECT_DIR}/requirements.txt + - su - flectra -c "mkdir ~/others" + - 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_tier_validation_formula + - psql -h psql -U flectra -d test_base_tier_validation_formula -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_tier_validation_formula + - chown -R flectra.flectra /opt/flectra/.local/share/filestore/test_base_tier_validation_formula + - su - flectra -c "/opt/flectra/flectra-bin + --addons-path ${CI_PROJECT_DIR} + --db_host psql + --db_port 5432 + --db_user flectra + --db_password flectra + --database test_base_tier_validation_formula + --test-enable -i base_tier_validation_formula + --stop-after-init + --log-level error + --log-handler flectra.addons.base_tier_validation_formula:TEST" + +test_module_base_tier_validation: + 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 + - pip3 install -r ${CI_PROJECT_DIR}/requirements.txt + - su - flectra -c "mkdir ~/others" + - 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_tier_validation + - psql -h psql -U flectra -d test_base_tier_validation -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_tier_validation + - chown -R flectra.flectra /opt/flectra/.local/share/filestore/test_base_tier_validation + - su - flectra -c "/opt/flectra/flectra-bin + --addons-path ${CI_PROJECT_DIR} + --db_host psql + --db_port 5432 + --db_user flectra + --db_password flectra + --database test_base_tier_validation + --test-enable -i base_tier_validation + --stop-after-init + --log-level error + --log-handler flectra.addons.base_tier_validation:TEST" + +test_module_base_search_custom_field_filter: + 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 + - pip3 install -r ${CI_PROJECT_DIR}/requirements.txt + - su - flectra -c "mkdir ~/others" + - 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_search_custom_field_filter + - psql -h psql -U flectra -d test_base_search_custom_field_filter -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_search_custom_field_filter + - chown -R flectra.flectra /opt/flectra/.local/share/filestore/test_base_search_custom_field_filter + - su - flectra -c "/opt/flectra/flectra-bin + --addons-path ${CI_PROJECT_DIR} + --db_host psql + --db_port 5432 + --db_user flectra + --db_password flectra + --database test_base_search_custom_field_filter + --test-enable -i base_search_custom_field_filter + --stop-after-init + --log-level error + --log-handler flectra.addons.base_search_custom_field_filter:TEST" + +test_module_base_revision: + 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 + - pip3 install -r ${CI_PROJECT_DIR}/requirements.txt + - su - flectra -c "mkdir ~/others" + - 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_revision + - psql -h psql -U flectra -d test_base_revision -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_revision + - chown -R flectra.flectra /opt/flectra/.local/share/filestore/test_base_revision + - su - flectra -c "/opt/flectra/flectra-bin + --addons-path ${CI_PROJECT_DIR} + --db_host psql + --db_port 5432 + --db_user flectra + --db_password flectra + --database test_base_revision + --test-enable -i base_revision + --stop-after-init + --log-level error + --log-handler flectra.addons.base_revision:TEST" + +test_module_base_export_manager: + 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 + - pip3 install -r ${CI_PROJECT_DIR}/requirements.txt + - su - flectra -c "mkdir ~/others" + - 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_export_manager + - psql -h psql -U flectra -d test_base_export_manager -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_export_manager + - chown -R flectra.flectra /opt/flectra/.local/share/filestore/test_base_export_manager + - su - flectra -c "/opt/flectra/flectra-bin + --addons-path ${CI_PROJECT_DIR} + --db_host psql + --db_port 5432 + --db_user flectra + --db_password flectra + --database test_base_export_manager + --test-enable -i base_export_manager + --stop-after-init + --log-level error + --log-handler flectra.addons.base_export_manager:TEST" + +test_module_document_quick_access: + 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 + - pip3 install -r ${CI_PROJECT_DIR}/requirements.txt + - su - flectra -c "mkdir ~/others" + - 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_document_quick_access + - psql -h psql -U flectra -d test_document_quick_access -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_document_quick_access + - chown -R flectra.flectra /opt/flectra/.local/share/filestore/test_document_quick_access + - su - flectra -c "/opt/flectra/flectra-bin + --addons-path ${CI_PROJECT_DIR} + --db_host psql + --db_port 5432 + --db_user flectra + --db_password flectra + --database test_document_quick_access + --test-enable -i document_quick_access + --stop-after-init + --log-level error + --log-handler flectra.addons.document_quick_access:TEST" + +test_module_mass_editing: + 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 + - pip3 install -r ${CI_PROJECT_DIR}/requirements.txt + - su - flectra -c "mkdir ~/others" + - 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_mass_editing + - psql -h psql -U flectra -d test_mass_editing -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_mass_editing + - chown -R flectra.flectra /opt/flectra/.local/share/filestore/test_mass_editing + - su - flectra -c "/opt/flectra/flectra-bin + --addons-path ${CI_PROJECT_DIR} + --db_host psql + --db_port 5432 + --db_user flectra + --db_password flectra + --database test_mass_editing + --test-enable -i mass_editing + --stop-after-init + --log-level error + --log-handler flectra.addons.mass_editing:TEST" + +test_module_base_tier_validation_server_action: + 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 + - pip3 install -r ${CI_PROJECT_DIR}/requirements.txt + - su - flectra -c "mkdir ~/others" + - 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_tier_validation_server_action + - psql -h psql -U flectra -d test_base_tier_validation_server_action -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_tier_validation_server_action + - chown -R flectra.flectra /opt/flectra/.local/share/filestore/test_base_tier_validation_server_action + - su - flectra -c "/opt/flectra/flectra-bin + --addons-path ${CI_PROJECT_DIR} + --db_host psql + --db_port 5432 + --db_user flectra + --db_password flectra + --database test_base_tier_validation_server_action + --test-enable -i base_tier_validation_server_action + --stop-after-init + --log-level error + --log-handler flectra.addons.base_tier_validation_server_action:TEST" + +test_module_chained_swapper: + 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 + - pip3 install -r ${CI_PROJECT_DIR}/requirements.txt + - su - flectra -c "mkdir ~/others" + - 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_chained_swapper + - psql -h psql -U flectra -d test_chained_swapper -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_chained_swapper + - chown -R flectra.flectra /opt/flectra/.local/share/filestore/test_chained_swapper + - su - flectra -c "/opt/flectra/flectra-bin + --addons-path ${CI_PROJECT_DIR} + --db_host psql + --db_port 5432 + --db_user flectra + --db_password flectra + --database test_chained_swapper + --test-enable -i chained_swapper + --stop-after-init + --log-level error + --log-handler flectra.addons.chained_swapper:TEST" + +test_module_base_optional_quick_create: + 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 + - pip3 install -r ${CI_PROJECT_DIR}/requirements.txt + - su - flectra -c "mkdir ~/others" + - 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_optional_quick_create + - psql -h psql -U flectra -d test_base_optional_quick_create -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_optional_quick_create + - chown -R flectra.flectra /opt/flectra/.local/share/filestore/test_base_optional_quick_create + - su - flectra -c "/opt/flectra/flectra-bin + --addons-path ${CI_PROJECT_DIR} + --db_host psql + --db_port 5432 + --db_user flectra + --db_password flectra + --database test_base_optional_quick_create + --test-enable -i base_optional_quick_create + --stop-after-init + --log-level error + --log-handler flectra.addons.base_optional_quick_create:TEST" diff --git a/README.md b/README.md index 13a8533..69c5528 100644 --- a/README.md +++ b/README.md @@ -10,25 +10,26 @@ Available addons addon | version | summary --- | --- | --- [base_cancel_confirm](base_cancel_confirm/) | 2.0.1.0.2| Base Cancel Confirm -[base_technical_features](base_technical_features/) | 2.0.1.1.0| Access to technical features without activating debug mode -[base_menu_visibility_restriction](base_menu_visibility_restriction/) | 2.0.1.0.0| Restrict (with groups) menu visibilty -[mass_editing](mass_editing/) | 2.0.1.0.1| Mass Editing -[base_optional_quick_create](base_optional_quick_create/) | 2.0.1.0.0| Avoid "quick create" on m2o fields, on a "by model" basis [filter_multi_user](filter_multi_user/) | 2.0.1.0.0| Allows to share user-defined filters filters among several users. -[barcode_action](barcode_action/) | 2.0.1.0.0| Allows to use barcodes as a launcher -[base_tier_validation_server_action](base_tier_validation_server_action/) | 2.0.1.1.0| Add option to call server action when a tier is validated -[base_tier_validation](base_tier_validation/) | 2.0.2.3.0| Implement a validation process based on tiers. -[document_quick_access](document_quick_access/) | 2.0.1.0.0| Document quick access -[base_export_manager](base_export_manager/) | 2.0.1.0.1| Manage model export profiles -[sequence_check_digit](sequence_check_digit/) | 2.0.1.0.0| Adds a check digit on sequences -[base_tier_validation_formula](base_tier_validation_formula/) | 2.0.2.0.0| Formulas for Base tier validation +[default_multi_user](default_multi_user/) | 2.0.1.0.0| Allows to share user-defined defaults among several users. [sequence_reset_period](sequence_reset_period/) | 2.0.1.0.0| Auto-generate yearly/monthly/weekly/daily sequence period ranges -[base_search_custom_field_filter](base_search_custom_field_filter/) | 2.0.1.0.0| Add custom filters for fields via UI +[sequence_check_digit](sequence_check_digit/) | 2.0.1.0.0| Adds a check digit on sequences +[base_import_security_group](base_import_security_group/) | 2.0.1.0.0| Group-based permissions for importing CSV files [date_range](date_range/) | 2.0.2.0.2| Manage all kind of date range [base_tier_validation_forward](base_tier_validation_forward/) | 2.0.1.0.2| Forward option for base tiers -[default_multi_user](default_multi_user/) | 2.0.1.0.0| Allows to share user-defined defaults among several users. -[base_revision](base_revision/) | 2.0.1.0.1| Keep track of revised document +[base_menu_visibility_restriction](base_menu_visibility_restriction/) | 2.0.1.0.0| Restrict (with groups) menu visibilty +[barcode_action](barcode_action/) | 2.0.1.0.0| Allows to use barcodes as a launcher [multi_step_wizard](multi_step_wizard/) | 2.0.1.0.0| Multi-Steps Wizards -[base_import_security_group](base_import_security_group/) | 2.0.1.0.0| Group-based permissions for importing CSV files +[base_technical_features](base_technical_features/) | 2.0.1.1.0| Access to technical features without activating debug mode +[base_tier_validation_formula](base_tier_validation_formula/) | 2.0.2.0.0| Formulas for Base tier validation +[base_tier_validation](base_tier_validation/) | 2.0.2.4.0| Implement a validation process based on tiers. +[base_search_custom_field_filter](base_search_custom_field_filter/) | 2.0.1.0.0| Add custom filters for fields via UI +[base_revision](base_revision/) | 2.0.1.0.1| Keep track of revised document +[base_export_manager](base_export_manager/) | 2.0.1.0.1| Manage model export profiles +[document_quick_access](document_quick_access/) | 2.0.1.0.0| Document quick access +[mass_editing](mass_editing/) | 2.0.1.0.1| Mass Editing +[base_tier_validation_server_action](base_tier_validation_server_action/) | 2.0.1.1.1| Add option to call server action when a tier is validated +[chained_swapper](chained_swapper/) | 2.0.1.0.0| Chained Swapper +[base_optional_quick_create](base_optional_quick_create/) | 2.0.1.0.0| Avoid "quick create" on m2o fields, on a "by model" basis diff --git a/base_tier_validation/__manifest__.py b/base_tier_validation/__manifest__.py index e3d80e0..a0476c3 100644 --- a/base_tier_validation/__manifest__.py +++ b/base_tier_validation/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Base Tier Validation", "summary": "Implement a validation process based on tiers.", - "version": "2.0.2.3.0", + "version": "2.0.2.4.0", "development_status": "Mature", "maintainers": ["LoisRForgeFlow"], "category": "Tools", diff --git a/base_tier_validation/data/mail_data.xml b/base_tier_validation/data/mail_data.xml index cd1cdb2..42b0ff8 100644 --- a/base_tier_validation/data/mail_data.xml +++ b/base_tier_validation/data/mail_data.xml @@ -30,4 +30,14 @@ + + Tier Validation Restarted + + + + diff --git a/base_tier_validation/i18n/base_tier_validation.pot b/base_tier_validation/i18n/base_tier_validation.pot index 0240604..7fea642 100644 --- a/base_tier_validation/i18n/base_tier_validation.pot +++ b/base_tier_validation/i18n/base_tier_validation.pot @@ -455,6 +455,12 @@ msgstr "" msgid "The operation is under validation." msgstr "" +#. module: base_tier_validation +#: code:addons/base_tier_validation/models/tier_validation.py:0 +#, python-format +msgid "The review has been reset by %s." +msgstr "" + #. module: base_tier_validation #: code:addons/base_tier_validation/models/tier_validation.py:0 #, python-format @@ -498,6 +504,11 @@ msgstr "" msgid "Tier Validation Requested" msgstr "" +#. module: base_tier_validation +#: model:mail.message.subtype,name:base_tier_validation.mt_tier_validation_restarted +msgid "Tier Validation Restarted" +msgstr "" + #. module: base_tier_validation #: model:ir.ui.menu,name:base_tier_validation.menu_tier_confirmation msgid "Tier Validations" diff --git a/base_tier_validation/i18n/es.po b/base_tier_validation/i18n/es.po index 461da16..0e09019 100644 --- a/base_tier_validation/i18n/es.po +++ b/base_tier_validation/i18n/es.po @@ -478,6 +478,12 @@ msgstr "Estado" msgid "The operation is under validation." msgstr "Esta operación está en proceso de validación." +#. module: base_tier_validation +#: code:addons/base_tier_validation/models/tier_validation.py:0 +#, python-format +msgid "The review has been reset by %s." +msgstr "" + #. module: base_tier_validation #: code:addons/base_tier_validation/models/tier_validation.py:0 #, python-format @@ -525,6 +531,11 @@ msgstr "Validaciones de Nivel (abstracto)" msgid "Tier Validation Requested" msgstr "" +#. module: base_tier_validation +#: model:mail.message.subtype,name:base_tier_validation.mt_tier_validation_restarted +msgid "Tier Validation Restarted" +msgstr "" + #. module: base_tier_validation #: model:ir.ui.menu,name:base_tier_validation.menu_tier_confirmation msgid "Tier Validations" diff --git a/base_tier_validation/i18n/fr.po b/base_tier_validation/i18n/fr.po index b131a9a..b9f7010 100644 --- a/base_tier_validation/i18n/fr.po +++ b/base_tier_validation/i18n/fr.po @@ -471,6 +471,12 @@ msgstr "Statut" msgid "The operation is under validation." msgstr "" +#. module: base_tier_validation +#: code:addons/base_tier_validation/models/tier_validation.py:0 +#, python-format +msgid "The review has been reset by %s." +msgstr "" + #. module: base_tier_validation #: code:addons/base_tier_validation/models/tier_validation.py:0 #, python-format @@ -514,6 +520,11 @@ msgstr "" msgid "Tier Validation Requested" msgstr "Validation par un tiers demandée" +#. module: base_tier_validation +#: model:mail.message.subtype,name:base_tier_validation.mt_tier_validation_restarted +msgid "Tier Validation Restarted" +msgstr "" + #. module: base_tier_validation #: model:ir.ui.menu,name:base_tier_validation.menu_tier_confirmation msgid "Tier Validations" diff --git a/base_tier_validation/i18n/nl_NL.po b/base_tier_validation/i18n/nl_NL.po index d6abfd5..7f5c480 100644 --- a/base_tier_validation/i18n/nl_NL.po +++ b/base_tier_validation/i18n/nl_NL.po @@ -460,6 +460,12 @@ msgstr "Status" msgid "The operation is under validation." msgstr "De bewerking is onder validatie." +#. module: base_tier_validation +#: code:addons/base_tier_validation/models/tier_validation.py:0 +#, python-format +msgid "The review has been reset by %s." +msgstr "" + #. module: base_tier_validation #: code:addons/base_tier_validation/models/tier_validation.py:0 #, python-format @@ -507,6 +513,11 @@ msgstr "Tier-validatie (abstract)" msgid "Tier Validation Requested" msgstr "" +#. module: base_tier_validation +#: model:mail.message.subtype,name:base_tier_validation.mt_tier_validation_restarted +msgid "Tier Validation Restarted" +msgstr "" + #. module: base_tier_validation #: model:ir.ui.menu,name:base_tier_validation.menu_tier_confirmation msgid "Tier Validations" diff --git a/base_tier_validation/i18n/zh_CN.po b/base_tier_validation/i18n/zh_CN.po index fc3e09b..0fb81e1 100644 --- a/base_tier_validation/i18n/zh_CN.po +++ b/base_tier_validation/i18n/zh_CN.po @@ -458,6 +458,12 @@ msgstr "状态" msgid "The operation is under validation." msgstr "该操作正在审批中。" +#. module: base_tier_validation +#: code:addons/base_tier_validation/models/tier_validation.py:0 +#, python-format +msgid "The review has been reset by %s." +msgstr "" + #. module: base_tier_validation #: code:addons/base_tier_validation/models/tier_validation.py:0 #, python-format @@ -505,6 +511,11 @@ msgstr "多层级审批(抽象)" msgid "Tier Validation Requested" msgstr "" +#. module: base_tier_validation +#: model:mail.message.subtype,name:base_tier_validation.mt_tier_validation_restarted +msgid "Tier Validation Restarted" +msgstr "" + #. module: base_tier_validation #: model:ir.ui.menu,name:base_tier_validation.menu_tier_confirmation msgid "Tier Validations" diff --git a/base_tier_validation/models/tier_validation.py b/base_tier_validation/models/tier_validation.py index bc6dbfc..37f90c9 100644 --- a/base_tier_validation/models/tier_validation.py +++ b/base_tier_validation/models/tier_validation.py @@ -211,7 +211,7 @@ class TierValidation(models.AbstractModel): and getattr(rec, self._state_field) in self._state_from and not vals.get(self._state_field) in (self._state_to + [self._cancel_state]) - and not self._check_allow_write_under_validation(vals) + and not rec._check_allow_write_under_validation(vals) ): raise ValidationError(_("The operation is under validation.")) if vals.get(self._state_field) in self._state_from: @@ -251,11 +251,14 @@ class TierValidation(models.AbstractModel): def _get_rejected_notification_subtype(self): return "base_tier_validation.mt_tier_validation_rejected" + def _get_restarted_notification_subtype(self): + return "base_tier_validation.mt_tier_validation_restarted" + def _notify_accepted_reviews(self): post = "message_post" if hasattr(self, post): # Notify state change - getattr(self, post)( + getattr(self.sudo(), post)( subtype_xmlid=self._get_accepted_notification_subtype(), body=self._notify_accepted_reviews_body(), ) @@ -320,7 +323,7 @@ class TierValidation(models.AbstractModel): post = "message_post" if hasattr(self, post): # Notify state change - getattr(self, post)( + getattr(self.sudo(), post)( subtype_xmlid=self._get_rejected_notification_subtype(), body=self._notify_rejected_review_body(), ) @@ -388,11 +391,23 @@ class TierValidation(models.AbstractModel): self._notify_review_requested(created_trs) return created_trs + def _notify_restarted_review_body(self): + return _("The review has been reset by %s.") % (self.env.user.name) + + def _notify_restarted_review(self): + post = "message_post" + if hasattr(self, post): + getattr(self.sudo(), post)( + subtype_xmlid=self._get_restarted_notification_subtype(), + body=self._notify_restarted_review_body(), + ) + def restart_validation(self): for rec in self: if getattr(rec, self._state_field) in self._state_from: rec.mapped("review_ids").unlink() self._update_counter() + rec._notify_restarted_review() @api.model def _update_counter(self): diff --git a/base_tier_validation_server_action/__manifest__.py b/base_tier_validation_server_action/__manifest__.py index bb80c4f..fd5136e 100644 --- a/base_tier_validation_server_action/__manifest__.py +++ b/base_tier_validation_server_action/__manifest__.py @@ -3,7 +3,7 @@ { "name": "Base Tier Validation - Server Action", "summary": "Add option to call server action when a tier is validated", - "version": "2.0.1.1.0", + "version": "2.0.1.1.1", "development_status": "Alpha", "maintainers": ["kittiu"], "category": "Tools", diff --git a/base_tier_validation_server_action/models/tier_review.py b/base_tier_validation_server_action/models/tier_review.py index bde26b0..6bb42e1 100644 --- a/base_tier_validation_server_action/models/tier_review.py +++ b/base_tier_validation_server_action/models/tier_review.py @@ -1,20 +1,24 @@ # Copyright 2020 Ecosoft (http://ecosoft.co.th) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -from flectra import api, models +from flectra import models class TierReview(models.Model): _inherit = "tier.review" - @api.constrains("status") - def _trigger_server_action(self): - for rec in self.filtered(lambda l: l.status in ["approved", "rejected"]): - server_action = False - if rec.status == "approved": - server_action = rec.definition_id.server_action_id - if rec.status == "rejected": - server_action = rec.definition_id.rejected_server_action_id - if server_action: - ctx = {"active_model": rec.model, "active_id": rec.res_id} - server_action.with_context(ctx).run() + def write(self, vals): + res = super().write(vals) + if vals.get("status") in ["approved", "rejected"]: + for rec in self: + server_action = False + if rec.status == "approved": + server_action = rec.definition_id.server_action_id + if rec.status == "rejected": + server_action = rec.definition_id.rejected_server_action_id + if server_action: + server_action.with_context( + active_model=rec.model, + active_id=rec.res_id, + ).sudo().run() + return res diff --git a/chained_swapper/COPYRIGHT b/chained_swapper/COPYRIGHT new file mode 100644 index 0000000..924accc --- /dev/null +++ b/chained_swapper/COPYRIGHT @@ -0,0 +1,17 @@ +Most of the files are + + :Copyright: This stylesheet has been placed in the public domain. + + + + + Language + + + + + + child_ids.lang + + + + Only parent company + bool(records.mapped('parent_id')) + + + + Chained swap: Language + chained.swapper.wizard + form + new + + form + + + + + + + diff --git a/chained_swapper/hooks.py b/chained_swapper/hooks.py new file mode 100644 index 0000000..584c812 --- /dev/null +++ b/chained_swapper/hooks.py @@ -0,0 +1,14 @@ +# Copyright 2020 Tecnativa - Ernesto Tejeda +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from flectra.api import SUPERUSER_ID, Environment + + +def uninstall_hook(cr, registry): + """Delete the actions that were created with chained_swapper when + the module is uninstalled""" + env = Environment(cr, SUPERUSER_ID, {}) + env["ir.actions.act_window"].search( + [("res_model", "=", "chained.swapper.wizard")] + ).unlink() + return True diff --git a/chained_swapper/i18n/chained_swapper.pot b/chained_swapper/i18n/chained_swapper.pot new file mode 100644 index 0000000..7b0b71a --- /dev/null +++ b/chained_swapper/i18n/chained_swapper.pot @@ -0,0 +1,280 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * chained_swapper +# +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: chained_swapper +#: code:addons/chained_swapper/wizard/chained_swapper_wizard.py:0 +#, python-format +msgid "Chained swap done:" +msgstr "" + +#. module: chained_swapper +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper__ref_ir_act_window_id +msgid "Action" +msgstr "" + +#. module: chained_swapper +#: model:ir.model.fields,help:chained_swapper.field_chained_swapper__ref_ir_act_window_id +msgid "" +"Action to make this template available on records of the related document " +"model." +msgstr "" + +#. module: chained_swapper +#: model_terms:ir.ui.view,arch_db:chained_swapper.chained_swapper_view_form +msgid "Add Action" +msgstr "" + +#. module: chained_swapper +#: model_terms:ir.ui.view,arch_db:chained_swapper.chained_swapper_view_form +msgid "" +"Add a new contextual action of related documents to open a composition " +"wizard" +msgstr "" + +#. module: chained_swapper +#: model_terms:ir.ui.view,arch_db:chained_swapper.chained_swapper_view_form +msgid "Advanced" +msgstr "" + +#. module: chained_swapper +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper__allowed_field_ids +msgid "Allowed Field" +msgstr "" + +#. module: chained_swapper +#: model:ir.model.fields,help:chained_swapper.field_chained_swapper_constraint__expression +msgid "" +"Boolean python expression. You can use the keyword 'records' as the records " +"selected to execute the contextual action. Ex.: " +"bool(records.mapped('parent_id'))" +msgstr "" + +#. module: chained_swapper +#: model:ir.model,name:chained_swapper.model_chained_swapper +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_constraint__chained_swapper_id +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_sub_field__chained_swapper_id +msgid "Chained Swapper" +msgstr "" + +#. module: chained_swapper +#: model:ir.model,name:chained_swapper.model_chained_swapper_constraint +msgid "Chained Swapper Constraint" +msgstr "" + +#. module: chained_swapper +#: model:ir.model,name:chained_swapper.model_chained_swapper_sub_field +msgid "Chained Swapper Sub-field" +msgstr "" + +#. module: chained_swapper +#: code:addons/chained_swapper/models/chained_swapper.py:0 +#, python-format +msgid "Chained swap" +msgstr "" + +#. module: chained_swapper +#: model:ir.actions.act_window,name:chained_swapper.partner_chained_swap_lang_action_demo +msgid "Chained swap: Language" +msgstr "" + +#. module: chained_swapper +#: model_terms:ir.ui.view,arch_db:chained_swapper.chained_swapper_wizard_view_form +msgid "Change" +msgstr "" + +#. module: chained_swapper +#: model_terms:ir.ui.view,arch_db:chained_swapper.chained_swapper_wizard_view_form +msgid "Close" +msgstr "" + +#. module: chained_swapper +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_constraint__expression +#: model_terms:ir.ui.view,arch_db:chained_swapper.chained_swapper_constraint_view_form +msgid "Constraint expression" +msgstr "" + +#. module: chained_swapper +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper__constraint_ids +#: model_terms:ir.ui.view,arch_db:chained_swapper.chained_swapper_view_form +msgid "Constraints" +msgstr "" + +#. module: chained_swapper +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper__create_uid +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_constraint__create_uid +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_sub_field__create_uid +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_wizard__create_uid +msgid "Created by" +msgstr "" + +#. module: chained_swapper +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper__create_date +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_constraint__create_date +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_sub_field__create_date +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_wizard__create_date +msgid "Created on" +msgstr "" + +#. module: chained_swapper +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper__display_name +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_constraint__display_name +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_sub_field__display_name +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_wizard__display_name +msgid "Display Name" +msgstr "" + +#. module: chained_swapper +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper__field_id +msgid "Field" +msgstr "" + +#. module: chained_swapper +#: model:ir.actions.act_window,name:chained_swapper.chained_swapper_action +#: model:ir.ui.menu,name:chained_swapper.chained_swapper_menu +#: model:ir.ui.menu,name:chained_swapper.chained_swapper_submenu +msgid "Field Swaps" +msgstr "" + +#. module: chained_swapper +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper__group_ids +msgid "Groups" +msgstr "" + +#. module: chained_swapper +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper__id +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_constraint__id +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_sub_field__id +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_wizard__id +msgid "ID" +msgstr "" + +#. module: chained_swapper +#: code:addons/chained_swapper/models/chained_swapper.py:0 +#, python-format +msgid "Incorrect sub-field expression:" +msgstr "" + +#. module: chained_swapper +#: code:addons/chained_swapper/models/chained_swapper.py:0 +#, python-format +msgid "Invalid constraint expression: " +msgstr "" + +#. module: chained_swapper +#: model:chained.swapper,name:chained_swapper.chained_swapper_demo +msgid "Language" +msgstr "" + +#. module: chained_swapper +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper____last_update +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_constraint____last_update +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_sub_field____last_update +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_wizard____last_update +msgid "Last Modified on" +msgstr "" + +#. module: chained_swapper +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper__write_uid +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_constraint__write_uid +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_sub_field__write_uid +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_wizard__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: chained_swapper +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper__write_date +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_constraint__write_date +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_sub_field__write_date +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_wizard__write_date +msgid "Last Updated on" +msgstr "" + +#. module: chained_swapper +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper__model_id +msgid "Model" +msgstr "" + +#. module: chained_swapper +#: model:ir.model.constraint,message:chained_swapper.constraint_chained_swapper_model_id_field_id_unique +msgid "Model and Field must be unique!" +msgstr "" + +#. module: chained_swapper +#: model:ir.model.fields,help:chained_swapper.field_chained_swapper__model_id +msgid "" +"Model is used for Selecting Field. This is editable until Contextual Action " +"is not created." +msgstr "" + +#. module: chained_swapper +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper__name +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_constraint__name +msgid "Name" +msgstr "" + +#. module: chained_swapper +#: code:addons/chained_swapper/wizard/chained_swapper_wizard.py:0 +#, python-format +msgid "Not possible to swap the field due to the constraint" +msgstr "" + +#. module: chained_swapper +#: model:chained.swapper.constraint,name:chained_swapper.chained_swapper_constraint_demo +msgid "Only parent company" +msgstr "" + +#. module: chained_swapper +#: model_terms:ir.ui.view,arch_db:chained_swapper.chained_swapper_view_form +msgid "Remove Action" +msgstr "" + +#. module: chained_swapper +#: model_terms:ir.ui.view,arch_db:chained_swapper.chained_swapper_view_form +msgid "Remove the contextual action to use this template on related documents" +msgstr "" + +#. module: chained_swapper +#: model_terms:ir.ui.view,arch_db:chained_swapper.chained_swapper_view_form +msgid "Security" +msgstr "" + +#. module: chained_swapper +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_sub_field__sub_field_chain +msgid "Sub Field Chain" +msgstr "" + +#. module: chained_swapper +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper__sub_field_ids +#: model_terms:ir.ui.view,arch_db:chained_swapper.chained_swapper_view_form +msgid "Sub-fields" +msgstr "" + +#. module: chained_swapper +#: code:addons/chained_swapper/models/chained_swapper.py:0 +#, python-format +msgid "The sub-field '%s' is not compatible with the main field." +msgstr "" + +#. module: chained_swapper +#: model:ir.model,name:chained_swapper.model_chained_swapper_wizard +msgid "Wizard chained swapper" +msgstr "" + +#. module: chained_swapper +#: model:ir.model.fields,help:chained_swapper.field_chained_swapper_sub_field__sub_field_chain +msgid "" +"You can specify here a field of related fields as dotted names. Ex.: " +"'child_ids.lang'." +msgstr "" diff --git a/chained_swapper/i18n/es.po b/chained_swapper/i18n/es.po new file mode 100644 index 0000000..05a68e2 --- /dev/null +++ b/chained_swapper/i18n/es.po @@ -0,0 +1,296 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * chained_swapper +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2020-08-14 10:32+0000\n" +"PO-Revision-Date: 2020-08-14 12:33+0200\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: \n" +"X-Generator: Poedit 2.3\n" + +#. module: chained_swapper +#: code:addons/chained_swapper/wizard/chained_swapper_wizard.py:146 +#, python-format +msgid "Chained swap done:" +msgstr "Cambio encadenado realizado:" + +#. module: chained_swapper +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper__ref_ir_act_window_id +msgid "Action" +msgstr "Acción" + +#. module: chained_swapper +#: model:ir.model.fields,help:chained_swapper.field_chained_swapper__ref_ir_act_window_id +msgid "" +"Action to make this template available on records of the related document " +"model." +msgstr "" +"Acción contextual para hacer que esta plantilla esté disponible en los " +"registros del modelo de documento relacionado." + +#. module: chained_swapper +#: model_terms:ir.ui.view,arch_db:chained_swapper.chained_swapper_view_form +msgid "Add Action" +msgstr "Añadir acción" + +#. module: chained_swapper +#: model_terms:ir.ui.view,arch_db:chained_swapper.chained_swapper_view_form +msgid "" +"Add a new contextual action of related documents to open a composition wizard" +msgstr "" +"Añade una acción contextual para los documentos relacionados para abrir un " +"asistente de intercambio encadenado" + +#. module: chained_swapper +#: model_terms:ir.ui.view,arch_db:chained_swapper.chained_swapper_view_form +msgid "Advanced" +msgstr "Avanzado" + +#. module: chained_swapper +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper__allowed_field_ids +msgid "Allowed Field" +msgstr "Campos permitidos" + +#. module: chained_swapper +#: model:ir.model.fields,help:chained_swapper.field_chained_swapper_constraint__expression +msgid "" +"Boolean python expression. You can use the keyword 'records' as the records " +"selected to execute the contextual action. Ex.: bool(records." +"mapped('parent_id'))" +msgstr "" +"Expresión Python booleana. Puede usar la palabra clave 'records' para hacer " +"referencia a los registros seleccionados al ejecutar la acción contextual. " +"Ej.: bool(records.mapped('parent_id'))" + +#. module: chained_swapper +#: model:ir.model,name:chained_swapper.model_chained_swapper +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_constraint__chained_swapper_id +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_sub_field__chained_swapper_id +msgid "Chained Swapper" +msgstr "Intercambiador encadenado" + +#. module: chained_swapper +#: model:ir.model,name:chained_swapper.model_chained_swapper_constraint +msgid "Chained Swapper Constraint" +msgstr "Intercambiador encadenado - Restricciones" + +#. module: chained_swapper +#: model:ir.model,name:chained_swapper.model_chained_swapper_sub_field +msgid "Chained Swapper Sub-field" +msgstr "Intercambiador encadenado - Sub-campos" + +#. module: chained_swapper +#: code:addons/chained_swapper/models/chained_swapper.py:104 +#, python-format +msgid "Chained swap" +msgstr "Cambio encadenado" + +#. module: chained_swapper +#: model:ir.actions.act_window,name:chained_swapper.partner_chained_swap_lang_action_demo +msgid "Chained swap: Language" +msgstr "Cambio encadenado: Idioma" + +#. module: chained_swapper +#: model_terms:ir.ui.view,arch_db:chained_swapper.chained_swapper_wizard_view_form +msgid "Change" +msgstr "Cambiar" + +#. module: chained_swapper +#: model_terms:ir.ui.view,arch_db:chained_swapper.chained_swapper_wizard_view_form +msgid "Close" +msgstr "Cerrar" + +#. module: chained_swapper +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_constraint__expression +#: model_terms:ir.ui.view,arch_db:chained_swapper.chained_swapper_constraint_view_form +msgid "Constraint expression" +msgstr "Expresión de restricción" + +#. module: chained_swapper +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper__constraint_ids +#: model_terms:ir.ui.view,arch_db:chained_swapper.chained_swapper_view_form +msgid "Constraints" +msgstr "Restricciones" + +#. module: chained_swapper +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper__create_uid +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_constraint__create_uid +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_sub_field__create_uid +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_wizard__create_uid +msgid "Created by" +msgstr "Creado por" + +#. module: chained_swapper +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper__create_date +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_constraint__create_date +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_sub_field__create_date +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_wizard__create_date +msgid "Created on" +msgstr "Creado el" + +#. module: chained_swapper +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper__display_name +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_constraint__display_name +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_sub_field__display_name +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_wizard__display_name +msgid "Display Name" +msgstr "Nombre mostrado" + +#. module: chained_swapper +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper__field_id +msgid "Field" +msgstr "Campo" + +#. module: chained_swapper +#: model:ir.actions.act_window,name:chained_swapper.chained_swapper_action +#: model:ir.ui.menu,name:chained_swapper.chained_swapper_menu +#: model:ir.ui.menu,name:chained_swapper.chained_swapper_submenu +msgid "Field Swaps" +msgstr "Intercambios de campo" + +#. module: chained_swapper +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper__group_ids +msgid "Groups" +msgstr "Grupos" + +#. module: chained_swapper +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper__id +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_constraint__id +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_sub_field__id +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_wizard__id +msgid "ID" +msgstr "ID" + +#. module: chained_swapper +#: code:addons/chained_swapper/models/chained_swapper.py:151 +#, python-format +msgid "Incorrect sub-field expression:" +msgstr "Expresión de sub-campo incorrecta:" + +#. module: chained_swapper +#: code:addons/chained_swapper/models/chained_swapper.py:193 +#, python-format +msgid "Invalid constraint expression: " +msgstr "Expresión de restricción no válida:" + +#. module: chained_swapper +#: model:chained.swapper,name:chained_swapper.chained_swapper_demo +msgid "Language" +msgstr "Idioma" + +#. module: chained_swapper +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper____last_update +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_constraint____last_update +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_sub_field____last_update +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_wizard____last_update +msgid "Last Modified on" +msgstr "Última modificación en" + +#. module: chained_swapper +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper__write_uid +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_constraint__write_uid +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_sub_field__write_uid +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_wizard__write_uid +msgid "Last Updated by" +msgstr "Última actualización por" + +#. module: chained_swapper +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper__write_date +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_constraint__write_date +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_sub_field__write_date +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_wizard__write_date +msgid "Last Updated on" +msgstr "Última actualización el" + +#. module: chained_swapper +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper__model_id +msgid "Model" +msgstr "Modelo" + +#. module: chained_swapper +#: sql_constraint:chained.swapper:0 +msgid "Model and Field must be unique!" +msgstr "La combinación Modelo-Campo debe ser única!" + +#. module: chained_swapper +#: model:ir.model.fields,help:chained_swapper.field_chained_swapper__model_id +msgid "" +"Model is used for Selecting Field. This is editable until Contextual Action " +"is not created." +msgstr "" +"El modelo se utiliza para seleccionar el campo. Este es editable mientras la " +"acción contextual no esté creada." + +#. module: chained_swapper +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper__name +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_constraint__name +msgid "Name" +msgstr "Nombre" + +#. module: chained_swapper +#: code:addons/chained_swapper/wizard/chained_swapper_wizard.py:32 +#, python-format +msgid "Not possible to swap the field due to the constraint" +msgstr "No es posible cambiar el campo debido a la restricción" + +#. module: chained_swapper +#: model:chained.swapper.constraint,name:chained_swapper.chained_swapper_constraint_demo +msgid "Only parent company" +msgstr "Solo compañías padres" + +#. module: chained_swapper +#: model_terms:ir.ui.view,arch_db:chained_swapper.chained_swapper_view_form +msgid "Remove Action" +msgstr "Eliminar acción" + +#. module: chained_swapper +#: model_terms:ir.ui.view,arch_db:chained_swapper.chained_swapper_view_form +msgid "Remove the contextual action to use this template on related documents" +msgstr "" +"Borrar la acción conceptual para usar esta plantilla en documentos " +"relacionados" + +#. module: chained_swapper +#: model_terms:ir.ui.view,arch_db:chained_swapper.chained_swapper_view_form +msgid "Security" +msgstr "Seguridad" + +#. module: chained_swapper +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper_sub_field__sub_field_chain +msgid "Sub Field Chain" +msgstr "Cadena de sub-campo" + +#. module: chained_swapper +#: model:ir.model.fields,field_description:chained_swapper.field_chained_swapper__sub_field_ids +#: model_terms:ir.ui.view,arch_db:chained_swapper.chained_swapper_view_form +msgid "Sub-fields" +msgstr "Sub-campo" + +#. module: chained_swapper +#: code:addons/chained_swapper/models/chained_swapper.py:162 +#, python-format +msgid "The sub-field '%s' is not compatible with the main field." +msgstr "El sub-campo '%s' no es compatible con el campo principal." + +#. module: chained_swapper +#: model:ir.model,name:chained_swapper.model_chained_swapper_wizard +msgid "Wizard chained swapper" +msgstr "Asistente de intercambiador encadenado" + +#. module: chained_swapper +#: model:ir.model.fields,help:chained_swapper.field_chained_swapper_sub_field__sub_field_chain +msgid "" +"You can specify here a field of related fields as dotted names. Ex.: " +"'child_ids.lang'." +msgstr "" +"Puede especificar aquí un campo de campos relacionados como una cadena de " +"nombres separada por puntos. Ej.: 'child_ids.lang'." diff --git a/chained_swapper/models/__init__.py b/chained_swapper/models/__init__.py new file mode 100644 index 0000000..10e942d --- /dev/null +++ b/chained_swapper/models/__init__.py @@ -0,0 +1,3 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import chained_swapper diff --git a/chained_swapper/models/chained_swapper.py b/chained_swapper/models/chained_swapper.py new file mode 100644 index 0000000..88e7764 --- /dev/null +++ b/chained_swapper/models/chained_swapper.py @@ -0,0 +1,196 @@ +# Copyright 2020 Tecnativa - Ernesto Tejeda +# Copyright 2020 Tecnativa - Pedro M. Baeza +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from flectra import _, api, exceptions, fields, models +from flectra.tools.safe_eval import safe_eval + + +class ChainedSwapper(models.Model): + _name = "chained.swapper" + _description = "Chained Swapper" + + name = fields.Char(required=True, translate=True, index=1) + model_id = fields.Many2one( + comodel_name="ir.model", + required=True, + ondelete="cascade", + help="Model is used for Selecting Field. This is editable " + "until Contextual Action is not created.", + ) + allowed_field_ids = fields.Many2many( + comodel_name="ir.model.fields", compute="_compute_allowed_field_ids" + ) + field_id = fields.Many2one( + comodel_name="ir.model.fields", + required=True, + ondelete="cascade", + domain="[('id', 'in', allowed_field_ids)]", + ) + sub_field_ids = fields.One2many( + comodel_name="chained.swapper.sub.field", + inverse_name="chained_swapper_id", + string="Sub-fields", + ) + constraint_ids = fields.One2many( + comodel_name="chained.swapper.constraint", + inverse_name="chained_swapper_id", + string="Constraints", + ) + ref_ir_act_window_id = fields.Many2one( + comodel_name="ir.actions.act_window", + string="Action", + readonly=True, + help="Action to make this template available on records " + "of the related document model.", + ) + group_ids = fields.Many2many( + comodel_name="res.groups", + relation="mass_group_rel", + column1="mass_id", + column2="group_id", + string="Groups", + ) + + _sql_constraints = [ + ( + "model_id_field_id_unique", + "unique (model_id, field_id)", + "Model and Field must be unique!", + ), + ] + + @api.depends("model_id") + def _compute_allowed_field_ids(self): + model_obj = self.env["ir.model"] + field_obj = self.env["ir.model.fields"] + for record in self: + allowed_field_ids = False + if record.model_id: + all_models = record.model_id + active_model_obj = self.env[record.model_id.model] + if active_model_obj._inherits: + keys = list(active_model_obj._inherits.keys()) + all_models |= model_obj.search([("model", "in", keys)]) + allowed_field_ids = field_obj.search( + [ + ("ttype", "not in", ["reference", "function", "one2many"]), + ("model_id", "in", all_models.ids), + ] + ) + record.allowed_field_ids = allowed_field_ids + + @api.constrains("model_id", "field_id") + def _check_sub_field_ids(self): + self.mapped("sub_field_ids")._check_sub_field_chain() + + @api.onchange("model_id") + def _onchange_model_id(self): + self.field_id = False + + def write(self, vals): + res = super().write(vals) + if "name" in vals: + self.mapped("ref_ir_act_window_id").write({"name": vals["name"]}) + return res + + def unlink(self): + self.unlink_action() + return super().unlink() + + def add_action(self): + self.ensure_one() + action = self.env["ir.actions.act_window"].create( + { + "name": _("Chained swap") + ": " + self.name, + "type": "ir.actions.act_window", + "res_model": "chained.swapper.wizard", + "groups_id": [(4, x.id) for x in self.group_ids], + "context": "{'chained_swapper_id': %d}" % (self.id), + "view_mode": "form", + "target": "new", + "binding_model_id": self.model_id.id, + "binding_type": "action", + } + ) + self.write({"ref_ir_act_window_id": action.id}) + return True + + def unlink_action(self): + self.mapped("ref_ir_act_window_id").unlink() + return True + + +class ChainedSwapperSubField(models.Model): + _name = "chained.swapper.sub.field" + _description = "Chained Swapper Sub-field" + + chained_swapper_id = fields.Many2one( + comodel_name="chained.swapper", ondelete="cascade" + ) + sub_field_chain = fields.Char( + required=True, + help="You can specify here a field of related fields as " + "dotted names. Ex.: 'child_ids.lang'.", + ) + + @api.constrains("chained_swapper_id", "sub_field_chain") + def _check_sub_field_chain(self): + for rec in self: + # Check sub-field exist + try: + chain_list = rec.sub_field_chain.split(".") + chain_field_name = chain_list.pop() + chain_model = self.env[rec.chained_swapper_id.model_id.model] + for name in chain_list: + chain_model = chain_model[name] + chain_model[chain_field_name] # pylint: disable=W0104 + except KeyError: + raise exceptions.ValidationError( + _("Incorrect sub-field expression:") + " " + rec.sub_field_chain + ) + # Check sub-field and original field are the same type + swap_field = rec.chained_swapper_id.field_id + chain_field = self.env["ir.model.fields"].search( + [ + ("model_id", "=", rec.chained_swapper_id.model_id.id), + ("name", "=", chain_field_name), + ] + ) + if ( + chain_field.ttype != swap_field.ttype + or chain_field.relation != swap_field.relation + ): + raise exceptions.ValidationError( + _("The sub-field '%s' is not compatible with the main" " field.") + % rec.sub_field_chain + ) + + +class ChainedSwapperConstraint(models.Model): + _name = "chained.swapper.constraint" + _description = "Chained Swapper Constraint" + + chained_swapper_id = fields.Many2one( + comodel_name="chained.swapper", ondelete="cascade" + ) + name = fields.Char(required=True, translate=True) + expression = fields.Text( + string="Constraint expression", + required=True, + help="Boolean python expression. You can use the keyword " + "'records' as the records selected to execute the " + "contextual action. Ex.: bool(records.mapped('parent_id'))", + default="True", + ) + + @api.constrains("expression") + def _check_expression(self): + for record in self: + model = self.env[record.chained_swapper_id.model_id.model] + try: + safe_eval(record.expression, {"records": model}) + except Exception: + raise exceptions.ValidationError( + _("Invalid constraint expression:" + " " + record.expression) + ) diff --git a/chained_swapper/security/ir.model.access.csv b/chained_swapper/security/ir.model.access.csv new file mode 100644 index 0000000..4bd1828 --- /dev/null +++ b/chained_swapper/security/ir.model.access.csv @@ -0,0 +1,8 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_chained_swapper_user,chained.swapper.user,model_chained_swapper,base.group_user,1,0,0,0 +access_chained_swapper_erp_manager,chained.swapper.erp_manager,model_chained_swapper,base.group_erp_manager,1,1,1,1 +access_chained_swapper_sub_field_user,chained.swapper.sub.field.user,model_chained_swapper_sub_field,base.group_user,1,0,0,0 +access_chained_swapper_sub_field_erp_manager,chained.swapper.sub.field.erp_manager,model_chained_swapper_sub_field,base.group_erp_manager,1,1,1,1 +access_chained_swapper_constraint_user,chained.swapper.constraint.user,model_chained_swapper_constraint,base.group_user,1,0,0,0 +access_chained_swapper_constraint_erp_manager,chained.swapper.constraint.erp_manager,model_chained_swapper_constraint,base.group_erp_manager,1,1,1,1 +access_chained_swapper_wizard,chained.swapper.wizard.constraint.erp_manager,model_chained_swapper_wizard,base.group_user,1,1,1,1 diff --git a/chained_swapper/static/description/icon.png b/chained_swapper/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 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 B#b5vc literal 0 KcmV+b0RR6000031 diff --git a/chained_swapper/static/description/index.html b/chained_swapper/static/description/index.html new file mode 100644 index 0000000..20e2be8 --- /dev/null +++ b/chained_swapper/static/description/index.html @@ -0,0 +1,490 @@ + + + + + + +Chained Swapper + + + +
+

Chained Swapper

+ + +

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

+

This module allows to swap the value of a field and propagate it in a chained +way to linked records. Example: changing the delivery address in a confirmed +sales order, it should be changed in its delivery orders as well.

+

It also allows to apply constraints for not allowing to do that change +according rules, so the business logic is not broken. Example: Don’t allow +to change the delivery address if the delivery order is validated.

+

This module requires some technical knowledge for setting the chained swap and +the constraint, as it’s defined through technical names and Python code.

+

WARNING: Use this module with care, as it can screw up database consistency +if swaps are not properly designed .

+

Table of contents

+ +
+

Configuration

+

To configure this module, you need to:

+
    +
  1. Go to Setting > Field Swaps > Field Swaps.

    +
  2. +
  3. Create a new object and set the following data as an example:

    +
      +
    • Name for identifying it and use it for the action name.

      +
    • +
    • Select the source model where the swap will be started.

      +
    • +
    • Select the starting field for which the swap will be done.

      +
    • +
    • Add several chained fields. They are expressed as a string using +dot notation, taking the source model as beginning for looking there +the first field, and continuing from there drilling through. Example: +picking_ids.partner_id for sale.order model will go to the linked +deliveries orders, and change the customer there.

      +
    • +
    • Add possible constraints for restricting the chained swap. They are +Python expressions that must be one line that is evaluated as boolean. +If the evaluation is true, then a message will be thrown and no swap +will be allowed. You can use the variable records in your code, that +will be referring the selected records for doing the swap. Example: for +restricting sales orders that have a delivery order validated:

      +

      any(p.state == ‘done’ for p in records.mapped(‘picking_ids.state’))

      +

      Other variables you can use are env, date and datetime. +Each constraint has a name for identifying it, but also for showing that +name when displaying the error trying to do the swap.

      +
    • +
    +
  4. +
  5. Click on ‘Add action’ smart button to add a new action in the source model.

    +
  6. +
+

On demo databases, you can check the example “Language”, that changes the +language of a contact, and propagate it to children contacts.

+
+
+

Usage

+

To use this module, you need to:

+
    +
  1. Go to the source document in list mode.
  2. +
  3. Select one or several records.
  4. +
  5. Click on Action and locate the option “Chained swap: <name of the swap>”.
  6. +
  7. If one of the selected records doesn’t comply with one of the constraints, +a message will be shown, and the swap won’t continue.
  8. +
  9. If everything is OK, a popup will arise, and you will see a field for +filling the new value.
  10. +
  11. Click on “Change”, and the swap will be done.
  12. +
  13. On the chatter of the source document, an entry will be logged for +reflecting the done swap.
  14. +
+
+
+

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

+
    +
  • Tecnativa
  • +
+
+
+

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/chained_swapper/tests/__init__.py b/chained_swapper/tests/__init__.py new file mode 100644 index 0000000..ccd7e32 --- /dev/null +++ b/chained_swapper/tests/__init__.py @@ -0,0 +1,3 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from . import test_chained_swapper diff --git a/chained_swapper/tests/test_chained_swapper.py b/chained_swapper/tests/test_chained_swapper.py new file mode 100644 index 0000000..626c403 --- /dev/null +++ b/chained_swapper/tests/test_chained_swapper.py @@ -0,0 +1,104 @@ +# Copyright 2020 Tecnativa - Ernesto Tejeda +# Copyright 2020 Tecnativa - Pedro M. Baeza +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from flectra import exceptions +from flectra.modules import registry +from flectra.tests import common +from flectra.tests.common import Form + +from ..hooks import uninstall_hook + + +class TestChainedSwapper(common.SavepointCase): + @classmethod + def setUpClass(cls): + super(TestChainedSwapper, cls).setUpClass() + cls.env["res.lang"].load_lang("es_ES") + res_partner = cls.env["res.partner"] + cls.partner_parent = res_partner.create( + {"name": "parent partner cs", "lang": "en_US"} + ) + cls.partner_child_1 = res_partner.create( + {"name": "partner child1 cs", "parent_id": cls.partner_parent.id} + ) + cls.partner_child_2 = res_partner.create( + {"name": "partner child2 cs", "parent_id": cls.partner_parent.id} + ) + # Prevent duplicate error removing demo data if exists + record = cls.env.ref("chained_swapper.chained_swapper_demo", False) + if record: + record.unlink() + + chained_swapper_form = Form(cls.env["chained.swapper"]) + chained_swapper_form.name = "Language" + chained_swapper_form.model_id = cls.env.ref("base.model_res_partner") + chained_swapper_form.field_id = cls.env.ref("base.field_res_partner__lang") + with chained_swapper_form.sub_field_ids.new() as sub_field_form: + sub_field_form.sub_field_chain = "child_ids.lang" + with chained_swapper_form.constraint_ids.new() as constraint_form: + constraint_form.name = "Only parent company" + constraint_form.expression = "bool(records.mapped('parent_id'))" + + cls.chained_swapper = chained_swapper_form.save() + cls.chained_swapper.add_action() + + def test_create_unlink_action(self): + """Test if Sidebar Action is added / removed to / from given object.""" + action = ( + self.chained_swapper.ref_ir_act_window_id + and self.chained_swapper.ref_ir_act_window_id.binding_model_id + ) + self.assertTrue(action) + # Remove the action + self.chained_swapper.unlink_action() + action = self.chained_swapper.ref_ir_act_window_id + self.assertFalse(action) + # Add an action + self.chained_swapper.add_action() + action = ( + self.chained_swapper.ref_ir_act_window_id + and self.chained_swapper.ref_ir_act_window_id.binding_model_id + ) + self.assertTrue(action) + + def test_unlink_chained_swapper(self): + """Test if related actions are removed when a chained swapper + record is unlinked.""" + action_id = self.chained_swapper.ref_ir_act_window_id.id + self.chained_swapper.unlink() + action = self.env["ir.actions.act_window"].search([("id", "=", action_id)]) + self.assertFalse(action) + + def test_change_constrained_partner_language(self): + with self.assertRaises(exceptions.UserError): + self.env["chained.swapper.wizard"].with_context( + active_model="res.partner", + active_id=self.partner_parent.id, + active_ids=(self.partner_parent | self.partner_child_1).ids, + chained_swapper_id=self.chained_swapper.id, + ).create({"lang": "es_ES"}) + + def test_change_partner_language(self): + self.env["chained.swapper.wizard"].with_context( + active_model="res.partner", + active_id=self.partner_parent.id, + active_ids=[self.partner_parent.id], + chained_swapper_id=self.chained_swapper.id, + ).create({"lang": "es_ES"}) + self.assertEqual(self.partner_parent.lang, "es_ES") + self.assertEqual(self.partner_child_1.lang, "es_ES") + self.assertEqual(self.partner_child_2.lang, "es_ES") + + def test_uninstall_hook(self): + """Test if related actions are removed when mass editing + record is uninstalled.""" + action_id = self.chained_swapper.ref_ir_act_window_id.id + uninstall_hook(self.cr, registry) + self.assertFalse(self.env["ir.actions.act_window"].browse(action_id).exists()) + + def test_invalid_constraint(self): + with self.assertRaises(exceptions.ValidationError): + self.chained_swapper.constraint_ids.write( + {"expression": "Something incorrect"} + ) diff --git a/chained_swapper/views/chained_swapper_views.xml b/chained_swapper/views/chained_swapper_views.xml new file mode 100644 index 0000000..ed6013d --- /dev/null +++ b/chained_swapper/views/chained_swapper_views.xml @@ -0,0 +1,145 @@ + + + + + + chained.swapper.form + chained.swapper + +
+ +
+ + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ + chained.swapper.tree + chained.swapper + + + + + + + + + + Field Swaps + chained.swapper + tree,form + + + + chained.swapper.sub.field.tree + chained.swapper.sub.field + + + + + + + + + chained.swapper.constraint.tree + chained.swapper.constraint + + + + + + + + + chained.swapper.constraint.form + chained.swapper.constraint + +
+ + + + + + +
+
+
+ + + + +
diff --git a/chained_swapper/wizard/__init__.py b/chained_swapper/wizard/__init__.py new file mode 100644 index 0000000..f841eb5 --- /dev/null +++ b/chained_swapper/wizard/__init__.py @@ -0,0 +1,3 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import chained_swapper_wizard diff --git a/chained_swapper/wizard/chained_swapper_wizard.py b/chained_swapper/wizard/chained_swapper_wizard.py new file mode 100644 index 0000000..9165165 --- /dev/null +++ b/chained_swapper/wizard/chained_swapper_wizard.py @@ -0,0 +1,164 @@ +# Copyright 2020 Tecnativa - Ernesto Tejeda +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from datetime import date, datetime + +from lxml import etree + +from flectra import _, api, models +from flectra.exceptions import UserError +from flectra.tools.safe_eval import safe_eval + + +class ChainedSwapperWizard(models.TransientModel): + _name = "chained.swapper.wizard" + _description = "Wizard chained swapper" + + @api.model + def default_get(self, fields): + context = self.env.context + if context.get("chained_swapper_id"): + records = self.env[context.get("active_model")].browse( + context.get("active_ids") + ) + exp_dict = { + "records": records, + "env": self.env, + "date": date, + "datetime": datetime, + } + chained_swapper = self.env["chained.swapper"].browse( + context.get("chained_swapper_id") + ) + for constraint in chained_swapper.constraint_ids: + if safe_eval(constraint.expression, exp_dict): + raise UserError( + _("Not possible to swap the field due to the constraint") + + ": " + + constraint.name + ) + return super().default_get(fields) + + @api.model + def fields_view_get( + self, view_id=None, view_type="form", toolbar=False, submenu=False + ): + """As we don't have any field in this model, result['fields'] + and result['arch'] are modified to add dynamically the + corresponding field. + """ + res = super().fields_view_get( + view_id=view_id, + view_type=view_type, + toolbar=toolbar, + submenu=submenu, + ) + if not self.env.context.get("chained_swapper_id"): + return res + chained_swapper = self.env["chained.swapper"].browse( + self.env.context.get("chained_swapper_id") + ) + model_obj = self.env[self.env.context.get("active_model")] + field_info = model_obj.fields_get() + field = chained_swapper.field_id + # Fields dict + all_fields = { + field.name: { + "type": field.ttype, + "string": field.field_description, + "views": {}, + } + } + if field.ttype in ["many2many", "many2one"]: + all_fields[field.name]["relation"] = field.relation + elif field.ttype == "selection": + field_selection = field_info[field.name]["selection"] + all_fields[field.name]["selection"] = field_selection + # XML view definition + doc = etree.XML(res["arch"]) + group_node = doc.xpath("//group[@name='swap_field_group']")[0] + etree.SubElement(group_node, "field", {"name": field.name, "colspan": "4"}) + if field.ttype in ["one2many", "many2many", "text"]: + group_node.set("string", field.field_description) + group_node.set("nolabel", "1") + res.update(arch=etree.tostring(doc, encoding="unicode"), fields=all_fields) + return res + + @api.model + def create(self, vals): + """As we don't have any field in this model, the key-value pair + received in vals dict are only used to change the value in the active + models. + """ + model_obj = self.env[self.env.context.get("active_model")] + context = self.env.context + field_name, new_value = list(vals.items())[0] + # write the active model + model = model_obj.browse(self.env.context.get("active_ids")) + original_values = {m.id: m[field_name] for m in model} + model.write(vals) + if hasattr(model, "message_post"): + self.post_chained_swap(model, field_name, original_values, new_value) + # write chained models + chained_swapper_obj = self.env["chained.swapper"] + chained_swapper = chained_swapper_obj.browse(context.get("chained_swapper_id")) + for sub_field in chained_swapper.sub_field_ids: + chain_fields = sub_field.sub_field_chain.split(".") + field_name = chain_fields.pop() + chain_model = model + for chain_field in chain_fields: + chain_model = chain_model.mapped(chain_field) + original_values = {cm.id: cm[field_name] for cm in chain_model} + chain_model.write({field_name: new_value}) + # post swap + if hasattr(chain_model, "message_post"): + self.post_chained_swap( + chain_model, field_name, original_values, new_value + ) + return super().create({}) + + def change_action(self): + return {"type": "ir.actions.act_window_close"} + + @api.model + def post_chained_swap(self, model, field_name, original_values, new_value): + def human_readable_field(value): + result = value + field_def = model._fields[field_name] + if field_def.type == "selection": + if type(field_def.selection) == list: + selection = field_def.selection + else: + selection = field_def.selection(self) + for selection_item in selection: + if selection_item[0] == value: + result = selection_item[1] + break + elif field_def.type == "many2one": + if type(value) == int: + result = self.env[field_def.comodel_name].browse(value) + result = result.display_name + elif field_def.type == "many2many": + if type(value) == list: + ids = value[0][2] + value = self.env[field_def.comodel_name].browse(ids) + result = str(value.mapped("display_name")) + return result + + field_desc = model._fields[field_name].string + new_value = human_readable_field(new_value) + for m in model: + original_value = human_readable_field(original_values[m.id]) + m.message_post( + body=_("Chained swap done:") + + "
{}: {} ⇒ {}".format(field_desc, original_value, new_value) + ) + + def read(self, fields, load="_classic_read"): + """Without this call, dynamic fields build by fields_view_get() + generate a crash and warning, i.e.: read() with unknown field 'myfield' + """ + real_fields = set(fields) & set(self._fields) + result = super().read(list(real_fields), load=load) + result[0].update({x: False for x in set(fields) - real_fields}) + return result diff --git a/chained_swapper/wizard/chained_swapper_wizard_views.xml b/chained_swapper/wizard/chained_swapper_wizard_views.xml new file mode 100644 index 0000000..083041b --- /dev/null +++ b/chained_swapper/wizard/chained_swapper_wizard_views.xml @@ -0,0 +1,23 @@ + + + + + chained.swapper.wizard.form + chained.swapper.wizard + +
+ +
+
+ +
+
+
diff --git a/mass_editing/COPYRIGHT b/mass_editing/COPYRIGHT index abcdd46..2244a61 100644 --- a/mass_editing/COPYRIGHT +++ b/mass_editing/COPYRIGHT @@ -1,9 +1,7 @@ Most of the files are :Copyright: This stylesheet has been placed in the public domain. - Copyright (C) 2016 Serpent Consulting Services Pvt. Ltd. (support@serpentcs.com) - Copyright (C) 2019-Today GRAP (http://www.grap.coop) - Copyright (C) 2020 - Iván Todorovich (https://twitter.com/ivan.todorovich) + Copyright (C) 2019 - Today: GRAP (http://www.grap.coop) Copyright (C) 2020 - Iván Todorovich Copyright (C) 2020 Iván Todorovich (https://twitter.com/ivantodorovich) Copyright 2016 Serpent Consulting Services Pvt. Ltd. (support@serpentcs.com)