diff --git a/.copier-answers.yml b/.copier-answers.yml index c0d82c1..0dad1bf 100644 --- a/.copier-answers.yml +++ b/.copier-answers.yml @@ -1,5 +1,5 @@ # Do NOT update manually; changes here will be overwritten by Copier -_commit: v5.0 +_commit: v8.0.2 _src_path: git@github.com:Noviat-CI/addons-repo-template.git ci_disable_autoinstall_modules: account_asset odoo_test_flavor: Both @@ -9,4 +9,5 @@ rebel_module_groups: [] repo_name: Modules dedicated to manage the EBICS protocol repo_slug: account_ebics repo_type: customer +weblate_project_name: '' diff --git a/.github/workflows/check-version-bump.yml b/.github/workflows/check-version-bump.yml new file mode 100644 index 0000000..d31d3f5 --- /dev/null +++ b/.github/workflows/check-version-bump.yml @@ -0,0 +1,29 @@ +name: Check module version bump + +on: + pull_request: + branches: + - "18.0*" + +jobs: + check-version-bump: + runs-on: ubuntu-latest + name: Check module version bump + steps: + - uses: actions/checkout@v7 + with: + # HEAD is the PR merge commit, HEAD^1 the tip of the base branch + fetch-depth: 2 + persist-credentials: false + - name: Configure git authentication + # Header instead of URL credentials, see test.yml + env: + TOKEN: ${{ secrets.PRIVATE_TOKEN }} + run: | + git config --global http.https://github.com/.extraheader "AUTHORIZATION: basic $(printf 'x-access-token:%s' "$TOKEN" | base64 -w0)" + - name: Add Noviat CI Tools to PATH + run: | + git clone https://github.com/Noviat-CI/noviat-ci-tools.git /opt/noviat-ci-tools + echo "/opt/noviat-ci-tools" >> $GITHUB_PATH + - name: Check module version bump + run: check_module_version_bump diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index aca0b83..a58efe7 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -8,17 +8,23 @@ on: branches: - "18.0" +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: pre-commit: - runs-on: ubuntu-22.04 + runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - uses: actions/checkout@v7 + - uses: actions/setup-python@v7 with: python-version: "3.11" + cache: 'pip' + cache-dependency-path: '.pre-commit-config.yaml' - name: Get python version run: echo "PY=$(python -VV | sha256sum | cut -d' ' -f1)" >> $GITHUB_ENV - - uses: actions/cache@v4 + - uses: actions/cache@v6 with: path: ~/.cache/pre-commit key: pre-commit|${{ env.PY }}|${{ hashFiles('.pre-commit-config.yaml') }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ddf69aa..b13a7eb 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,18 +8,23 @@ on: branches: - "18.0" +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: unreleased-deps: runs-on: ubuntu-latest name: Detect unreleased dependencies steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 - run: | for reqfile in requirements.txt test-requirements.txt ; do if [ -f ${reqfile} ] ; then result=0 # reject non-comment lines that contain a / (i.e. URLs, relative paths) - grep "^[^#].*/" ${reqfile} || result=$? + # unless they have a "# SKIP TEST" comment + grep "^[^#].*/" ${reqfile} | grep -v "# SKIP TEST" || result=$? if [ $result -eq 0 ] ; then echo "Unreleased dependencies found in ${reqfile}." exit 1 @@ -27,7 +32,7 @@ jobs: fi done test: - runs-on: ubuntu-22.04 + runs-on: ubuntu-latest container: ${{ matrix.container }} name: ${{ matrix.name }} permissions: @@ -49,7 +54,7 @@ jobs: makepot: "true" services: postgres: - image: postgres:12.0 + image: postgres:12 env: POSTGRES_USER: odoo POSTGRES_PASSWORD: odoo @@ -60,20 +65,34 @@ jobs: INSTALL_ADDONS_DIR: "/tmp/addons-merged" ADDITIONAL_ADDONS_DIR: "/tmp/additional-addons" steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v7 with: persist-credentials: false + - name: Configure git authentication + env: + TOKEN: ${{ secrets.PRIVATE_TOKEN }} + run: | + git config --global http.https://github.com/.extraheader "AUTHORIZATION: basic $(printf 'x-access-token:%s' "$TOKEN" | base64 -w0)" + - name: Set pip constraints (pyOpenSSL / cryptography) + run: | + cat > /tmp/constraints.txt <<'EOF' + pyOpenSSL == 22.1.0 + cryptography == 38.0.4 + EOF + echo "PIP_CONSTRAINT=/tmp/constraints.txt" >> $GITHUB_ENV + - name: Upgrade pip in container + run: python -m pip install --upgrade pip + - name: Install Odoo upgrade util + run: python -m pip install git+https://github.com/odoo/upgrade-util@master - name: Add Noviat CI Tools to PATH run: | - git clone https://${{ secrets.PRIVATE_TOKEN }}@github.com/Noviat-CI/noviat-ci-tools.git /opt/noviat-ci-tools + git clone https://github.com/Noviat-CI/noviat-ci-tools.git /opt/noviat-ci-tools echo "/opt/noviat-ci-tools" >> $GITHUB_PATH - name: Clone Odoo Enterprise if: ${{ matrix.odoo_enterprise == 1 }} run : | - git clone https://${{ secrets.PRIVATE_TOKEN }}@github.com/odoo/enterprise.git --depth 1 -b 18.0 /opt/enterprise + git clone https://github.com/odoo/enterprise.git --depth 1 -b 18.0 /opt/enterprise - name: Clone Noviat Dependencies - env: - PRIVATE_TOKEN: ${{ secrets.PRIVATE_TOKEN }} run: clone_oca_dependencies_by_noviat - name: Create addons path run: | @@ -97,21 +116,30 @@ jobs: run: | echo "server_wide_modules = web,module_change_auto_install" >> ${ODOO_RC} echo "ODOO_MODULES_AUTO_INSTALL_DISABLED=${{ matrix.EXCLUDE_MODULES }}" >> $GITHUB_ENV - - name: Inject GitHub token for Noviat orgs in test-requirements.txt - run: | - sed -i -E "s#https://github.com/(Noviat-(Projects|Generic|ARP|Internal))#https://${{ secrets.PRIVATE_TOKEN }}@github.com/\1#g" test-requirements.txt - name: Install addons and dependencies run: | (ADDONS_PATH=${ADDONS_PATH} ADDONS_DIR=${INSTALL_ADDONS_DIR} oca_install_addons) + - name: Install external dependencies of core addons (not in Odoo requirements.txt) + run: | + (ADDONS_DIR=${INSTALL_ADDONS_DIR} noviat_install_odoo_external_dependencies) - name: Initialize test db run: oca_init_test_database - name: Run tests run: oca_run_tests - name: Generate coverage files + id: coverage run: | + # oca_run_tests exits early without coverage data when there is no + # addon to test (e.g. a freshly scaffolded version branch). + if [ -z "$(oca_list_addons_to_test)" ]; then + echo "No addon to test, skipping coverage report." + exit 0 + fi coverage report -m coverage xml -o coverage.xml + echo "report=true" >> "$GITHUB_OUTPUT" - name: Code Coverage Summary Report + if: steps.coverage.outputs.report == 'true' uses: irongut/CodeCoverageSummary@v1.3.0 with: filename: 'coverage.xml' @@ -120,7 +148,8 @@ jobs: output: 'both' hide_complexity: true - name: Write to Job Summary + if: steps.coverage.outputs.report == 'true' run: cat code-coverage-results.md >> $GITHUB_STEP_SUMMARY - name: Update .pot files - run: noviat_export_and_push_pot https://x-access-token:${{ secrets.PRIVATE_TOKEN }}@github.com/${{ github.repository }} + run: noviat_export_and_push_pot https://github.com/${{ github.repository }} if: ${{ matrix.makepot == 'true' && github.event_name == 'push' }} diff --git a/.github/workflows/update-addons-table.yml b/.github/workflows/update-addons-table.yml new file mode 100644 index 0000000..55fd435 --- /dev/null +++ b/.github/workflows/update-addons-table.yml @@ -0,0 +1,42 @@ +name: Update addons table after merge + +on: + push: + branches: + - "18.0" + paths-ignore: + - "README.md" + +permissions: + contents: write + +jobs: + gen-addons-table: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + with: + persist-credentials: false + fetch-depth: 0 + - uses: actions/setup-python@v7 + with: + python-version: "3.11" + - name: Install pre-commit + run: pip install pre-commit + - name: Run the manual hook to (re)generate the addons table + run: pre-commit run -a --hook-stage manual oca-gen-addons-table + continue-on-error: true + - name: Commit & push if changed + env: + TOKEN: ${{ secrets.PRIVATE_TOKEN }} + run: | + if ! git diff --quiet; then + git config user.name "noviat-ci-bot" + git config user.email "bot+ci@noviat.com" + git add -A + git commit -m "update addons table" + # Header instead of URL credentials, see test.yml + git config http.https://github.com/.extraheader "AUTHORIZATION: basic $(printf 'x-access-token:%s' "$TOKEN" | base64 -w0)" + git config --global --add safe.directory "$GITHUB_WORKSPACE" + git push origin HEAD:18.0 + fi diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bff66f6..9cc3fae 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -22,7 +22,7 @@ exclude: | (LICENSE.*|COPYING.*) default_language_version: python: python3 - node: "22.9.0" + node: "22.23.3" repos: - repo: local hooks: @@ -39,25 +39,38 @@ repos: language: fail files: '[a-zA-Z0-9_]*/i18n/en\.po$' - repo: https://github.com/sbidoul/whool - rev: v1.2 + rev: v1.3 hooks: - id: whool-init + additional_dependencies: + # force a fresh pre-commit env: up-to-date core addons lists and + # Odoo 20 support (since v1.16.0) + - manifestoo-core>=1.16.1 - repo: https://github.com/oca/maintainer-tools - rev: b89f767503be6ab2b11e4f50a7557cb20066e667 + rev: b8311a95009805a6e5593f0390f52c0fa350117f hooks: # update the NOT INSTALLABLE ADDONS section above - id: oca-update-pre-commit-excluded-addons - id: oca-fix-manifest-website args: ["https://www.noviat.com/"] - id: oca-gen-external-dependencies + additional_dependencies: + # an outdated manifestoo-core ignores recent core addons, and wipes + # requirements.txt on an Odoo series it does not know + - manifestoo-core>=1.16.1 - id: oca-gen-addons-table + stages: [manual] - repo: https://github.com/OCA/odoo-pre-commit-hooks - rev: v0.0.33 + rev: v0.2.27 hooks: - id: oca-checks-odoo-module + - id: oca-checks-odoo-module-fixit + args: + - --disable=use-header-comments - id: oca-checks-po args: - --disable=po-pretty-format + - --fix - repo: local hooks: - id: prettier @@ -71,8 +84,8 @@ repos: files: \.(css|htm|html|js|json|jsx|less|md|scss|toml|ts|xml|yaml|yml)$ language: node additional_dependencies: - - "prettier@3.3.3" - - "@prettier/plugin-xml@3.4.1" + - "prettier@3.9.9" + - "@prettier/plugin-xml@3.4.2" - repo: local hooks: - id: eslint @@ -85,10 +98,11 @@ repos: types: [javascript] language: node additional_dependencies: - - "eslint@9.12.0" - - "eslint-plugin-jsdoc@50.3.1" + - "eslint@10.11.0" + - "eslint-plugin-jsdoc@65.0.0" + - "globals@17.12.0" - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.6.0 + rev: v6.0.0 hooks: - id: trailing-whitespace # exclude autogenerated files @@ -97,8 +111,6 @@ repos: # exclude autogenerated files exclude: /README\.rst$|\.pot?$ - id: debug-statements - - id: fix-encoding-pragma - args: ["--remove"] - id: check-case-conflict - id: check-docstring-first - id: check-executables-have-shebangs @@ -109,21 +121,30 @@ repos: - id: check-xml - id: mixed-line-ending args: ["--fix=lf"] + - repo: https://github.com/asottile/pyupgrade + rev: v3.21.2 + hooks: + - id: pyupgrade - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.6.8 + rev: v0.16.9 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] - id: ruff-format + # markdown is prettier's job (ruff >= 0.16 also formats its code blocks) + types_or: [python, pyi, jupyter] - repo: https://github.com/OCA/pylint-odoo - rev: v9.1.3 + rev: v10.0.11 hooks: - id: pylint_odoo - name: pylint with optional checks + name: pylint (optional, core only) args: - --rcfile=.pylintrc - --exit-zero verbose: true - id: pylint_odoo + name: pylint-odoo (mandatory, blocking) args: + - --disable=missing-readme - --rcfile=.pylintrc-mandatory + verbose: true diff --git a/.pylintrc b/.pylintrc index 6f3a412..b3e77fc 100644 --- a/.pylintrc +++ b/.pylintrc @@ -1,9 +1,11 @@ - [MASTER] ignore-patterns=["^.*/TODO/.*$"] load-plugins=pylint_odoo score=n +[IMPORTS] +deprecated-modules=pdb,pudb,ipdb,bs4 + [ODOOLINT] #readme-template-url="https://github.com/OCA/maintainer-tools/blob/master/template/module/README.rst" manifest-required-authors=Noviat @@ -22,22 +24,15 @@ disable=all # .pylintrc-mandatory containing only mandatory checks is used the pre-commit # config as a blocking check. -enable=anomalous-backslash-in-string, - api-one-deprecated, - api-one-multi-together, +enable = + anomalous-backslash-in-string, assignment-from-none, attribute-deprecated, - class-camelcase, dangerous-default-value, - dangerous-view-replace-wo-priority, + deprecated-module, development-status-allowed, - duplicate-id-csv, duplicate-key, - duplicate-xml-fields, - duplicate-xml-record-id, - eval-referenced, eval-used, - incoherent-interpreter-exec-perm, license-allowed, manifest-author-string, manifest-deprecated-key, @@ -48,73 +43,73 @@ enable=anomalous-backslash-in-string, method-inverse, method-required-super, method-search, - openerp-exception-warning, pointless-statement, pointless-string-statement, print-used, redundant-keyword-arg, - redundant-modulename-xml, reimported, - relative-import, return-in-init, - rst-syntax-error, sql-injection, too-few-format-args, translation-field, translation-required, unreachable, use-vim-comment, - wrong-tabs-instead-of-spaces, - xml-syntax-error, + # >= 15 attribute-string-redundant, - character-not-valid-in-resource-link, consider-merging-classes-inherited, context-overridden, - create-user-wo-reset-password, - dangerous-filter-wo-user, - dangerous-qweb-replace-wo-priority, - deprecated-data-xml-node, - deprecated-openerp-xml-node, - duplicate-po-message-definition, except-pass, - file-not-used, invalid-commit, + manifest-external-assets, manifest-maintainers-list, - missing-newline-extrafiles, - # missing-readme, + missing-readme, missing-return, odoo-addons-relative-import, - old-api7-method-defined, - po-msgstr-variables, - po-syntax-error, + odoo-exception-warning, renamed-field-parameter, resource-not-exist, - str-format-used, test-folder-imported, translation-contains-variable, translation-positional-used, - unnecessary-utf8-coding-comment, website-manifest-key-not-valid-uri, - xml-attribute-translatable, - xml-deprecated-qweb-directive, - xml-deprecated-tree-attribute, + # >= 16 external-request-timeout, + # >= 19 + bad-builtin-groupby, + category-allowed, + deprecated-name-get, + deprecated-odoo-model-method, + deprecated-self-cr, + inheritable-method-lambda, + inheritable-method-string, + invalid-email, + manifest-behind-migrations, + manifest-data-duplicated, + missing-odoo-file, + no-raise-unlink, + no-search-all, + no-wizard-in-models, + prohibited-method-override, + prefer-env-translation, + translation-format-interpolation, + translation-format-truncated, + translation-injection, + translation-fstring-interpolation, + translation-not-lazy, + translation-too-few-args, + translation-too-many-args, + translation-unsupported-format, + no-write-in-compute, + odoolint, + # >= 20 + manifest-summary-multiline, # messages that do not cause the lint step to fail consider-merging-classes-inherited, - create-user-wo-reset-password, - dangerous-filter-wo-user, - deprecated-module, - file-not-used, invalid-commit, - missing-manifest-dependency, - missing-newline-extrafiles, - # missing-readme, - no-utf8-coding-comment, + missing-readme, odoo-addons-relative-import, - old-api7-method-defined, - redefined-builtin, - too-complex, - unnecessary-utf8-coding-comment + redefined-builtin [REPORTS] diff --git a/.pylintrc-mandatory b/.pylintrc-mandatory index ef3d59a..cd769dc 100644 --- a/.pylintrc-mandatory +++ b/.pylintrc-mandatory @@ -3,6 +3,9 @@ ignore-patterns=["^.*/TODO/.*$"] load-plugins=pylint_odoo score=n +[IMPORTS] +deprecated-modules=pdb,pudb,ipdb,bs4 + [ODOOLINT] #readme-template-url="https://github.com/OCA/maintainer-tools/blob/master/template/module/README.rst" manifest-required-authors=Noviat @@ -14,22 +17,15 @@ valid-odoo-versions=18.0 [MESSAGES CONTROL] disable=all -enable=anomalous-backslash-in-string, - api-one-deprecated, - api-one-multi-together, +enable = + anomalous-backslash-in-string, assignment-from-none, attribute-deprecated, - class-camelcase, dangerous-default-value, - dangerous-view-replace-wo-priority, + deprecated-module, development-status-allowed, - duplicate-id-csv, duplicate-key, - duplicate-xml-fields, - duplicate-xml-record-id, - eval-referenced, eval-used, - incoherent-interpreter-exec-perm, license-allowed, manifest-author-string, manifest-deprecated-key, @@ -40,57 +36,67 @@ enable=anomalous-backslash-in-string, method-inverse, method-required-super, method-search, - openerp-exception-warning, pointless-statement, pointless-string-statement, print-used, redundant-keyword-arg, - redundant-modulename-xml, reimported, - relative-import, return-in-init, - rst-syntax-error, sql-injection, too-few-format-args, translation-field, translation-required, unreachable, use-vim-comment, - wrong-tabs-instead-of-spaces, - xml-syntax-error, + # >= 15 attribute-string-redundant, - character-not-valid-in-resource-link, consider-merging-classes-inherited, context-overridden, - create-user-wo-reset-password, - dangerous-filter-wo-user, - dangerous-qweb-replace-wo-priority, - deprecated-data-xml-node, - deprecated-openerp-xml-node, - duplicate-po-message-definition, except-pass, - file-not-used, invalid-commit, + manifest-external-assets, manifest-maintainers-list, - missing-newline-extrafiles, - # missing-readme, + missing-readme, missing-return, odoo-addons-relative-import, - old-api7-method-defined, - po-msgstr-variables, - po-syntax-error, + odoo-exception-warning, renamed-field-parameter, resource-not-exist, - str-format-used, test-folder-imported, translation-contains-variable, translation-positional-used, - unnecessary-utf8-coding-comment, website-manifest-key-not-valid-uri, - xml-attribute-translatable, - xml-deprecated-qweb-directive, - xml-deprecated-tree-attribute, - external-request-timeout + # >= 16 + external-request-timeout, + # >= 19 + bad-builtin-groupby, + category-allowed, + deprecated-name-get, + deprecated-odoo-model-method, + deprecated-self-cr, + inheritable-method-lambda, + inheritable-method-string, + invalid-email, + manifest-behind-migrations, + manifest-data-duplicated, + missing-odoo-file, + no-raise-unlink, + no-search-all, + no-wizard-in-models, + prohibited-method-override, + prefer-env-translation, + translation-format-interpolation, + translation-format-truncated, + translation-injection, + translation-fstring-interpolation, + translation-not-lazy, + translation-too-few-args, + translation-too-many-args, + translation-unsupported-format, + no-write-in-compute, + odoolint, + # >= 20 + manifest-summary-multiline [REPORTS] msg-template={path}:{line}: [{msg_id}({symbol}), {obj}] {msg} diff --git a/.ruff.toml b/.ruff.toml index 5e63128..b153261 100644 --- a/.ruff.toml +++ b/.ruff.toml @@ -3,7 +3,14 @@ target-version = "py310" fix = true [lint] -extend-select = [ +# Explicit rule set: ruff >= 0.16 enables 413 rules by default, many of which go +# against Odoo idioms (naive UTC datetimes, `self = self.with_context()`, list +# `_inherit`). "E4", "E7", "E9" and "F" are the defaults of ruff < 0.16. +select = [ + "E4", + "E7", + "E9", + "F", "B", "C90", "E501", # line too long (default 88) diff --git a/README.md b/README.md index 7172d94..f5cbc01 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ [![Pre-commit Status](https://github.com/Noviat/account_ebics/actions/workflows/pre-commit.yml/badge.svg?branch=18.0)](https://github.com/Noviat/account_ebics/actions/workflows/pre-commit.yml?query=branch%3A18.0) [![Build Status](https://github.com/Noviat/account_ebics/actions/workflows/test.yml/badge.svg?branch=18.0)](https://github.com/Noviat/account_ebics/actions/workflows/test.yml?query=branch%3A18.0) - # Modules dedicated to manage the EBICS protocol diff --git a/account_ebics/__manifest__.py b/account_ebics/__manifest__.py index 3031ab8..6b670b0 100644 --- a/account_ebics/__manifest__.py +++ b/account_ebics/__manifest__.py @@ -26,7 +26,6 @@ "wizards/ebics_admin_order.xml", "views/menu.xml", ], - "installable": True, "application": True, "external_dependencies": { "python": [ diff --git a/account_ebics/data/ebics_file_format.xml b/account_ebics/data/ebics_file_format.xml index 8c40ab0..cf8cafd 100644 --- a/account_ebics/data/ebics_file_format.xml +++ b/account_ebics/data/ebics_file_format.xml @@ -1,4 +1,4 @@ - + diff --git a/account_ebics/migrations/13.0.1.1/post-migration.py b/account_ebics/migrations/13.0.1.1/post-migration.py index 954d6c5..94783f9 100644 --- a/account_ebics/migrations/13.0.1.1/post-migration.py +++ b/account_ebics/migrations/13.0.1.1/post-migration.py @@ -3,7 +3,7 @@ import os -from openupgradelib import openupgrade # pylint: disable=W7936 +from openupgradelib import openupgrade # pylint: disable=E0401 @openupgrade.migrate() diff --git a/account_ebics/models/account_journal.py b/account_ebics/models/account_journal.py index 333a8e6..7db3ca1 100644 --- a/account_ebics/models/account_journal.py +++ b/account_ebics/models/account_journal.py @@ -11,13 +11,13 @@ class AccountJournal(models.Model): comodel_name="ebics.config", relation="account_journal_ebics_config_rel", readonly=True, - string="Ebics Configs", + string="EBICS Configs", ) ebics_config_id = fields.Many2one( comodel_name="ebics.config", compute="_compute_ebics_config_id", compute_sudo=True, - string="Ebics Config", + string="EBICS Config", ) @api.depends("ebics_config_ids") diff --git a/account_ebics/models/ebics_config.py b/account_ebics/models/ebics_config.py index 7da7e4d..b75d1a7 100644 --- a/account_ebics/models/ebics_config.py +++ b/account_ebics/models/ebics_config.py @@ -8,7 +8,7 @@ import re from odoo import api, fields, models from odoo.exceptions import UserError -_logger = logging.getLogger(__name__) +_logger = logging.getLogger(__name__) # lint-ignore=unused-logger class EbicsConfig(models.Model): @@ -160,13 +160,12 @@ class EbicsConfig(models.Model): for rec in self: rec.company_ids = rec.journal_ids.mapped("company_id") - def unlink(self): - for ebics_config in self: - if ebics_config.state == "active": - raise UserError( - self.env._("You cannot remove active EBICS configurations.") - ) - return super().unlink() + @api.ondelete(at_uninstall=False) + def _unlink_except_active(self): + if any(rec.state == "active" for rec in self): + raise UserError( + self.env._("You cannot remove active EBICS configurations.") + ) def set_to_draft(self): return self.write({"state": "draft"}) @@ -199,8 +198,8 @@ class EbicsConfig(models.Model): if not os.path.exists(dirname): raise UserError( self.env._( - "EBICS Keys Root Directory %s is not available." - "\nPlease contact your system administrator." + "EBICS Keys Root Directory %(dir)s is not available." + "\nPlease contact your system administrator.", + dir=dirname, ) - % dirname ) diff --git a/account_ebics/models/ebics_file.py b/account_ebics/models/ebics_file.py index 9106e70..33f80ec 100644 --- a/account_ebics/models/ebics_file.py +++ b/account_ebics/models/ebics_file.py @@ -9,12 +9,12 @@ from traceback import format_exception from lxml import etree -from odoo import fields, models +from odoo import api, fields, models from odoo.exceptions import UserError from odoo.addons.base.models.res_bank import sanitize_account_number -_logger = logging.getLogger(__name__) +_logger = logging.getLogger(__name__) # lint-ignore=unused-logger DUP_CHECK_FORMATS = ["cfonb120", "camt053"] @@ -63,7 +63,6 @@ class EbicsFile(models.Model): ) user_id = fields.Many2one( comodel_name="res.users", - string="User", default=lambda self: self.env.user, readonly=True, ) @@ -91,13 +90,16 @@ class EbicsFile(models.Model): help="Companies sharing this EBICS file.", ) + @api.ondelete(at_uninstall=False) + def _unlink_except_done(self): + if any(rec.state == "done" for rec in self): + raise UserError( + self.env._("You can only remove EBICS files in state 'Draft'.") + ) + def unlink(self): ff_methods = self._file_format_methods() for ebics_file in self: - if ebics_file.state == "done": - raise UserError( - self.env._("You can only remove EBICS files in state 'Draft'.") - ) # execute format specific actions ff = ebics_file.format_id.download_process_method if ff in ff_methods: @@ -385,8 +387,7 @@ class EbicsFile(models.Model): file_data = base64.b64decode(self.data).replace(b"\n", b"").replace(b"\r", b"") if len(file_data) % 120: message = self.env._( - "Incorrect CFONB120 file:\n" - "the file is not divisible in 120 char lines" + "Incorrect CFONB120 file:\nthe file is not divisible in 120 char lines" ) res["notifications"].append({"type": "error", "message": message}) return datas @@ -650,7 +651,7 @@ class EbicsFile(models.Model): self.env._( "The current version of the 'account_ebics' module " "has no support to automatically process EBICS files " - "with format %s." + "with format %s.", + self.format_id.name, ) - % self.format_id.name ) diff --git a/account_ebics/models/ebics_userid.py b/account_ebics/models/ebics_userid.py index d9de5d3..4aef532 100644 --- a/account_ebics/models/ebics_userid.py +++ b/account_ebics/models/ebics_userid.py @@ -69,8 +69,7 @@ class EbicsUserID(models.Model): string="Users", required=True, domain=[("share", "=", False)], - help="Users who are allowed to use this EBICS UserID for " - " bank transactions.", + help="Users who are allowed to use this EBICS UserID for bank transactions.", ) signature_class = fields.Selection( selection=[("E", "Single signature"), ("T", "Transport signature")], @@ -149,7 +148,7 @@ class EbicsUserID(models.Model): # create self-signed X.509 certificates ebics_key_x509 = fields.Boolean( string="X509 support", - help="Set this flag in order to work with " "self-signed X.509 certificates", + help="Set this flag in order to work with self-signed X.509 certificates", ) ebics_key_x509_dn_cn = fields.Char( string="Common Name [CN]", @@ -417,7 +416,7 @@ class EbicsUserID(models.Model): if not ebics_config_bank: raise UserError( self.env._( - "No bank defined for the financial journal " "of the EBICS Config" + "No bank defined for the financial journal of the EBICS Config" ) ) try: @@ -476,8 +475,7 @@ class EbicsUserID(models.Model): if cc in ["FR", "DE"]: lang = cc else: - lang = self.env.user.lang or self.env["res.lang"].search([])[0].code - lang = lang[:2] + lang = self.env.user.lang[:2] lang = lang.lower() lang = lang if lang in INI_LETTER_LANGS else "en" fn_date = fields.Date.today().isoformat() diff --git a/account_ebics/security/ebics_security.xml b/account_ebics/security/ebics_security.xml index f55664d..fef2c38 100644 --- a/account_ebics/security/ebics_security.xml +++ b/account_ebics/security/ebics_security.xml @@ -1,6 +1,6 @@ - + - + EBICS Manager diff --git a/account_ebics/views/ebics_config_views.xml b/account_ebics/views/ebics_config_views.xml index 0982a20..af5345a 100644 --- a/account_ebics/views/ebics_config_views.xml +++ b/account_ebics/views/ebics_config_views.xml @@ -1,4 +1,4 @@ - + ebics.config.list diff --git a/account_ebics/views/ebics_file_format_views.xml b/account_ebics/views/ebics_file_format_views.xml index 99fc173..46a23a6 100644 --- a/account_ebics/views/ebics_file_format_views.xml +++ b/account_ebics/views/ebics_file_format_views.xml @@ -1,4 +1,4 @@ - + ebics.file.format.search diff --git a/account_ebics/views/ebics_file_views.xml b/account_ebics/views/ebics_file_views.xml index bc8aa72..ca0d782 100644 --- a/account_ebics/views/ebics_file_views.xml +++ b/account_ebics/views/ebics_file_views.xml @@ -1,4 +1,4 @@ - + ebics.file.search @@ -81,7 +81,7 @@ ebics.file.form ebics.file - 1 +
@@ -177,7 +177,7 @@ ebics.file.process.result ebics.file - 100 + diff --git a/account_ebics/views/ebics_userid_views.xml b/account_ebics/views/ebics_userid_views.xml index 152caca..272e296 100644 --- a/account_ebics/views/ebics_userid_views.xml +++ b/account_ebics/views/ebics_userid_views.xml @@ -1,4 +1,4 @@ - + ebics.userid.list diff --git a/account_ebics/views/menu.xml b/account_ebics/views/menu.xml index 5a92812..b77f1f8 100644 --- a/account_ebics/views/menu.xml +++ b/account_ebics/views/menu.xml @@ -1,4 +1,4 @@ - + + EBICS Administrative Order ebics.admin.order - 1 + 1 @@ -31,7 +31,7 @@ EBICS Administrative Order result ebics.admin.order - 2 + diff --git a/account_ebics/wizards/ebics_change_passphrase.xml b/account_ebics/wizards/ebics_change_passphrase.xml index 549ca4e..67e2af4 100644 --- a/account_ebics/wizards/ebics_change_passphrase.xml +++ b/account_ebics/wizards/ebics_change_passphrase.xml @@ -1,9 +1,9 @@ - + EBICS Keys Change Passphrase ebics.change.passphrase - 1 + @@ -40,7 +40,7 @@ EBICS Keys Change Passphrase ebics.change.passphrase - 2 + diff --git a/account_ebics/wizards/ebics_xfer.py b/account_ebics/wizards/ebics_xfer.py index 56a1ced..215c476 100644 --- a/account_ebics/wizards/ebics_xfer.py +++ b/account_ebics/wizards/ebics_xfer.py @@ -224,9 +224,9 @@ class EbicsXfer(models.TransientModel): client = self._setup_client() if not client: err_cnt += 1 - self.note += ( - self.env._("EBICS client setup failed for connection '%s'") - % self.ebics_config_id.name + self.note += self.env._( + "EBICS client setup failed for connection '%s'", + self.ebics_config_id.name, ) else: download_formats = ( @@ -336,11 +336,8 @@ class EbicsXfer(models.TransientModel): if ebics_files: self.note += "\n" for f in ebics_files: - self.note += ( - self.env._( - "EBICS File '%s' is available for further processing." - ) - % f.name + self.note += self.env._( + "EBICS File '%s' is available for further processing.", f.name ) self.note += "\n" @@ -406,9 +403,8 @@ class EbicsXfer(models.TransientModel): OrderID = client.upload(order_type, upload_data) if OrderID: self.note += "\n" - self.note += ( - self.env._("EBICS File has been uploaded (OrderID %s).") - % OrderID + self.note += self.env._( + "EBICS File has been uploaded (OrderID %s).", OrderID ) ef_note = "" if self.env.context.get("origin"): @@ -619,9 +615,9 @@ class EbicsXfer(models.TransientModel): self.env._( "EBICS File with name '%s' has already been downloaded." "\nPlease check this file and rename in case there is " - "no risk on duplicate transactions." + "no risk on duplicate transactions.", + fn, ) - % fn ) data = base64.encodebytes(data) ef_vals = { diff --git a/account_ebics/wizards/ebics_xfer.xml b/account_ebics/wizards/ebics_xfer.xml index c7d838c..a08e150 100644 --- a/account_ebics/wizards/ebics_xfer.xml +++ b/account_ebics/wizards/ebics_xfer.xml @@ -1,9 +1,9 @@ - + EBICS File Download ebics.xfer - 1 + @@ -55,7 +55,7 @@ EBICS File Upload ebics.xfer - 1 + @@ -120,7 +120,7 @@ EBICS File Transfer ebics.xfer - 2 + @@ -148,7 +148,7 @@ Mark EBICS files as Downloaded ebics.xfer - 1 +