diff --git a/.badges/coverage.svg b/.badges/coverage.svg new file mode 100644 index 0000000000000000000000000000000000000000..4305ce9c031cf46f958d5a0f8c1e0f2cf99ad92d_LmJhZGdlcy9jb3ZlcmFnZS5zdmc= --- /dev/null +++ b/.badges/coverage.svg @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<svg xmlns="http://www.w3.org/2000/svg" width="124" height="20"> + <linearGradient id="b" x2="0" y2="100%"> + <stop offset="0" stop-color="#bbb" stop-opacity=".1" /> + <stop offset="1" stop-opacity=".1" /> + </linearGradient> + <mask id="anybadge_1"> + <rect width="124" height="20" rx="3" fill="#fff" /> + </mask> + <g mask="url(#anybadge_1)"> + <path fill="#555" d="M0 0h65v20H0z" /> + <path fill="#808080" d="M65 0h59v20H65z" /> + <path fill="url(#b)" d="M0 0h124v20H0z" /> + </g> + <g + fill="#fff" + text-anchor="middle" + font-family="DejaVu Sans,Verdana,Geneva,sans-serif" + font-size="11" + > + <text x="33.5" y="15" fill="#010101" fill-opacity=".3">coverage</text> + <text x="32.5" y="14">coverage</text> + </g> + <g + fill="#fff" + text-anchor="middle" + font-family="DejaVu Sans,Verdana,Geneva,sans-serif" + font-size="11" + > + <text x="95.5" y="15" fill="#010101" fill-opacity=".3">unknown</text> + <text x="94.5" y="14">unknown</text> + </g> +</svg> diff --git a/.badges/maturity.svg b/.badges/maturity.svg index 9dc3378641b434b446ecdc0cd1f26bb222ffaf09_LmJhZGdlcy9tYXR1cml0eS5zdmc=..4305ce9c031cf46f958d5a0f8c1e0f2cf99ad92d_LmJhZGdlcy9tYXR1cml0eS5zdmc= 100644 --- a/.badges/maturity.svg +++ b/.badges/maturity.svg @@ -1,2 +1,2 @@ -<?xml version="1.0" encoding="UTF-8"?> +<?xml version="1.0" encoding="UTF-8" ?> <svg xmlns="http://www.w3.org/2000/svg" width="97" height="20"> @@ -2,22 +2,32 @@ <svg xmlns="http://www.w3.org/2000/svg" width="97" height="20"> - <linearGradient id="b" x2="0" y2="100%"> - <stop offset="0" stop-color="#bbb" stop-opacity=".1"/> - <stop offset="1" stop-opacity=".1"/> - </linearGradient> - <mask id="anybadge_1"> - <rect width="97" height="20" rx="3" fill="#fff"/> - </mask> - <g mask="url(#anybadge_1)"> - <path fill="#555" d="M0 0h61v20H0z"/> - <path fill="#dfb317" d="M61 0h36v20H61z"/> - <path fill="url(#b)" d="M0 0h97v20H0z"/> - </g> - <g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11"> - <text x="31.5" y="15" fill="#010101" fill-opacity=".3">maturity</text> - <text x="30.5" y="14">maturity</text> - </g> - <g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11"> - <text x="80.0" y="15" fill="#010101" fill-opacity=".3">Beta</text> - <text x="79.0" y="14">Beta</text> - </g> -</svg> \ No newline at end of file + <linearGradient id="b" x2="0" y2="100%"> + <stop offset="0" stop-color="#bbb" stop-opacity=".1" /> + <stop offset="1" stop-opacity=".1" /> + </linearGradient> + <mask id="anybadge_1"> + <rect width="97" height="20" rx="3" fill="#fff" /> + </mask> + <g mask="url(#anybadge_1)"> + <path fill="#555" d="M0 0h61v20H0z" /> + <path fill="#dfb317" d="M61 0h36v20H61z" /> + <path fill="url(#b)" d="M0 0h97v20H0z" /> + </g> + <g + fill="#fff" + text-anchor="middle" + font-family="DejaVu Sans,Verdana,Geneva,sans-serif" + font-size="11" + > + <text x="31.5" y="15" fill="#010101" fill-opacity=".3">maturity</text> + <text x="30.5" y="14">maturity</text> + </g> + <g + fill="#fff" + text-anchor="middle" + font-family="DejaVu Sans,Verdana,Geneva,sans-serif" + font-size="11" + > + <text x="80.0" y="15" fill="#010101" fill-opacity=".3">Beta</text> + <text x="79.0" y="14">Beta</text> + </g> +</svg> diff --git a/.editorconfig b/.editorconfig index 9dc3378641b434b446ecdc0cd1f26bb222ffaf09_LmVkaXRvcmNvbmZpZw==..4305ce9c031cf46f958d5a0f8c1e0f2cf99ad92d_LmVkaXRvcmNvbmZpZw== 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,5 +1,5 @@ # Configuration for known file extensions -[*.{css,js,json,less,md,py,rst,sass,scss,xml,yaml,yml}] +[*.{css,htm,html,js,json,jsx,less,markdown,md,py,rst,sass,scss,toml,xml,yaml,yml}] charset = utf-8 end_of_line = lf indent_size = 4 @@ -7,6 +7,6 @@ insert_final_newline = true trim_trailing_whitespace = true -[*.{json,yml,yaml,rst,md}] +[*.{json,yml,yaml,rst,markdown,md,toml}] indent_size = 2 @@ -11,7 +11,7 @@ indent_size = 2 -# Do not configure editor for libs and autogenerated content -[{*/static/{lib,src/lib}/**,*/static/description/index.html,*/readme/../README.rst}] +# Do not configure editor for libs +[*/static/{lib,src/lib}/**] charset = unset end_of_line = unset indent_size = unset diff --git a/.eslintrc.yml b/.eslintrc.yml new file mode 100644 index 0000000000000000000000000000000000000000..4305ce9c031cf46f958d5a0f8c1e0f2cf99ad92d_LmVzbGludHJjLnltbA== --- /dev/null +++ b/.eslintrc.yml @@ -0,0 +1,187 @@ +env: + browser: true + es6: true + +# See https://github.com/OCA/odoo-community.org/issues/37#issuecomment-470686449 +parserOptions: + ecmaVersion: 2019 + +overrides: + - files: + - "**/*.esm.js" + parserOptions: + sourceType: module + +# Globals available in Odoo that shouldn't produce errorings +globals: + _: readonly + $: readonly + fuzzy: readonly + jQuery: readonly + moment: readonly + odoo: readonly + openerp: readonly + owl: readonly + +# Styling is handled by Prettier, so we only need to enable AST rules; +# see https://github.com/OCA/maintainer-quality-tools/pull/618#issuecomment-558576890 +rules: + accessor-pairs: warn + array-callback-return: warn + callback-return: warn + capitalized-comments: + - warn + - always + - ignoreConsecutiveComments: true + ignoreInlineComments: true + complexity: + - warn + - 15 + constructor-super: warn + dot-notation: warn + eqeqeq: warn + global-require: warn + handle-callback-err: warn + id-blacklist: warn + id-match: warn + init-declarations: error + max-depth: warn + max-nested-callbacks: warn + max-statements-per-line: warn + no-alert: warn + no-array-constructor: warn + no-caller: warn + no-case-declarations: warn + no-class-assign: warn + no-cond-assign: error + no-const-assign: error + no-constant-condition: warn + no-control-regex: warn + no-debugger: error + no-delete-var: warn + no-div-regex: warn + no-dupe-args: error + no-dupe-class-members: error + no-dupe-keys: error + no-duplicate-case: error + no-duplicate-imports: error + no-else-return: warn + no-empty-character-class: warn + no-empty-function: error + no-empty-pattern: error + no-empty: warn + no-eq-null: error + no-eval: error + no-ex-assign: error + no-extend-native: warn + no-extra-bind: warn + no-extra-boolean-cast: warn + no-extra-label: warn + no-fallthrough: warn + no-func-assign: error + no-global-assign: error + no-implicit-coercion: + - warn + - allow: ["~"] + no-implicit-globals: warn + no-implied-eval: warn + no-inline-comments: warn + no-inner-declarations: warn + no-invalid-regexp: warn + no-irregular-whitespace: warn + no-iterator: warn + no-label-var: warn + no-labels: warn + no-lone-blocks: warn + no-lonely-if: error + no-mixed-requires: error + no-multi-str: warn + no-native-reassign: error + no-negated-condition: warn + no-negated-in-lhs: error + no-new-func: warn + no-new-object: warn + no-new-require: warn + no-new-symbol: warn + no-new-wrappers: warn + no-new: warn + no-obj-calls: warn + no-octal-escape: warn + no-octal: warn + no-param-reassign: warn + no-path-concat: warn + no-process-env: warn + no-process-exit: warn + no-proto: warn + no-prototype-builtins: warn + no-redeclare: warn + no-regex-spaces: warn + no-restricted-globals: warn + no-restricted-imports: warn + no-restricted-modules: warn + no-restricted-syntax: warn + no-return-assign: error + no-script-url: warn + no-self-assign: warn + no-self-compare: warn + no-sequences: warn + no-shadow-restricted-names: warn + no-shadow: warn + no-sparse-arrays: warn + no-sync: warn + no-this-before-super: warn + no-throw-literal: warn + no-undef-init: warn + no-undef: error + no-unmodified-loop-condition: warn + no-unneeded-ternary: error + no-unreachable: error + no-unsafe-finally: error + no-unused-expressions: error + no-unused-labels: error + no-unused-vars: error + no-use-before-define: error + no-useless-call: warn + no-useless-computed-key: warn + no-useless-concat: warn + no-useless-constructor: warn + no-useless-escape: warn + no-useless-rename: warn + no-void: warn + no-with: warn + operator-assignment: [error, always] + prefer-const: warn + radix: warn + require-yield: warn + sort-imports: warn + spaced-comment: [error, always] + strict: [error, function] + use-isnan: error + valid-jsdoc: + - warn + - prefer: + arg: param + argument: param + augments: extends + constructor: class + exception: throws + func: function + method: function + prop: property + return: returns + virtual: abstract + yield: yields + preferType: + array: Array + bool: Boolean + boolean: Boolean + number: Number + object: Object + str: String + string: String + requireParamDescription: false + requireReturn: false + requireReturnDescription: false + requireReturnType: false + valid-typeof: warn + yoda: warn diff --git a/.flake8 b/.flake8 index 9dc3378641b434b446ecdc0cd1f26bb222ffaf09_LmZsYWtlOA==..4305ce9c031cf46f958d5a0f8c1e0f2cf99ad92d_LmZsYWtlOA== 100644 --- a/.flake8 +++ b/.flake8 @@ -1,2 +1,5 @@ [flake8] max-line-length = 88 +per-file-ignores= + __init__.py:F401 + __manifest__.py:B018 diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 9dc3378641b434b446ecdc0cd1f26bb222ffaf09_LmdpdGxhYi1jaS55bWw=..4305ce9c031cf46f958d5a0f8c1e0f2cf99ad92d_LmdpdGxhYi1jaS55bWw= 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,3 +1,3 @@ include: - project: xcg/ci-templates - file: /odoo/15.0/gitlab-ci.yaml + file: /odoo/16.0/gitlab-ci.yaml diff --git a/NEWS.rst b/NEWS.rst index 9dc3378641b434b446ecdc0cd1f26bb222ffaf09_TkVXUy5yc3Q=..4305ce9c031cf46f958d5a0f8c1e0f2cf99ad92d_TkVXUy5yc3Q= 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -2,6 +2,6 @@ Changelog ========= -15.0.1.0.0 +16.0.1.0.0 ---------- @@ -6,3 +6,3 @@ ---------- -Migration to Odoo 15 +Migration to Odoo 16. diff --git a/README.rst b/README.rst index 9dc3378641b434b446ecdc0cd1f26bb222ffaf09_UkVBRE1FLnJzdA==..4305ce9c031cf46f958d5a0f8c1e0f2cf99ad92d_UkVBRE1FLnJzdA== 100644 --- a/README.rst +++ b/README.rst @@ -2,8 +2,8 @@ Context Methods =============== -.. |coverage| image:: https://orus.io/xcg/odoo-modules/base_context/badges/branch/15.0/coverage.svg - :target: https://orus.io/xcg/odoo-modules/base_context/-/pipelines?ref=branch/15.0 +.. |coverage| image:: .badges/coverage.svg + :target: https://orus.io/xcg/odoo-modules/base_context/-/pipelines?ref=branch/16.0 :alt: Coverage report .. the image is updated by the CI when building the documentation .. |pylint| image:: .badges/pylint.svg @@ -7,7 +7,7 @@ :alt: Coverage report .. the image is updated by the CI when building the documentation .. |pylint| image:: .badges/pylint.svg - :target: https://orus.io/xcg/odoo-modules/base_context/-/pipelines?ref=branch/15.0 + :target: https://orus.io/xcg/odoo-modules/base_context/-/pipelines?ref=branch/16.0 :alt: pylint score .. |maturity| image:: .badges/maturity.svg :target: https://odoo-community.org/page/development-status diff --git a/__init__.py b/__init__.py index 9dc3378641b434b446ecdc0cd1f26bb222ffaf09_X19pbml0X18ucHk=..4305ce9c031cf46f958d5a0f8c1e0f2cf99ad92d_X19pbml0X18ucHk= 100644 --- a/__init__.py +++ b/__init__.py @@ -1,1 +1,1 @@ -from .hooks import post_load # noqa: F401 +from . import models diff --git a/__manifest__.py b/__manifest__.py index 9dc3378641b434b446ecdc0cd1f26bb222ffaf09_X19tYW5pZmVzdF9fLnB5..4305ce9c031cf46f958d5a0f8c1e0f2cf99ad92d_X19tYW5pZmVzdF9fLnB5 100644 --- a/__manifest__.py +++ b/__manifest__.py @@ -1,7 +1,7 @@ ############################################################################## # -# Base Clean Context, for Odoo -# Copyright (C) 2021, 2022 XCG Consulting <https://xcg-consulting.fr> +# Context Methods, for Odoo +# Copyright (C) 2021, 2022, 2023 XCG Consulting <https://xcg-consulting.fr> # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as @@ -21,6 +21,6 @@ "name": "Context Methods", "license": "AGPL-3", "summary": "Provide context method on models", - "version": "15.0.1.0.0", + "version": "16.0.1.0.0", "category": "Hidden", "author": "XCG Consulting", @@ -25,5 +25,5 @@ "category": "Hidden", "author": "XCG Consulting", - "website": "https://odoo.consulting/", + "website": "https://orbeet.io/", "depends": ["base"], "installable": True, @@ -28,4 +28,3 @@ "depends": ["base"], "installable": True, - "post_load": "post_load", } diff --git a/hooks.py b/hooks.py deleted file mode 100644 index 9dc3378641b434b446ecdc0cd1f26bb222ffaf09_aG9va3MucHk=..0000000000000000000000000000000000000000 --- a/hooks.py +++ /dev/null @@ -1,63 +0,0 @@ -############################################################################## -# -# Base Context, for Odoo -# Copyright (C) 2021, 2022 XCG Consulting <https://xcg-consulting.fr> -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. -# -############################################################################## -from typing import Dict - -from odoo.models import Model - - -def patch_base_model(): - """Add methods to the base model, so they are available with a simple - self.get_clean_context()""" - - def get_clean_context(self) -> Dict[str, str]: - """Remove cruft from the Odoo context. - - Useful when returning view display actions. - """ - - return { - key: value - for key, value in self.env.context.items() - if ( - not key.startswith("default_") - and not key.startswith("search_default_") - and key not in ("form_view_ref", "group_by", "tree_view_ref") - ) - } - - def with_lang(self: Model) -> Model: - """Add lang info from the current user regardless of what the context may - already contain. It so happens the context often has wrong lang info by - default. - - Useful when running automated tasks. - - :return: That same Odoo record set with added lang info. - """ - - return self.with_context(lang=self.env.user.lang) - - Model.get_clean_context = get_clean_context - Model.with_lang = with_lang - - -def post_load(): - """Execute all post loading hooks""" - patch_base_model() diff --git a/models/__init__.py b/models/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..4305ce9c031cf46f958d5a0f8c1e0f2cf99ad92d_bW9kZWxzL19faW5pdF9fLnB5 --- /dev/null +++ b/models/__init__.py @@ -0,0 +1,1 @@ +from . import base diff --git a/models/base.py b/models/base.py new file mode 100644 index 0000000000000000000000000000000000000000..4305ce9c031cf46f958d5a0f8c1e0f2cf99ad92d_bW9kZWxzL2Jhc2UucHk= --- /dev/null +++ b/models/base.py @@ -0,0 +1,55 @@ +############################################################################## +# +# Context Methods, for Odoo +# Copyright (C) 2021, 2022, 2023 XCG Consulting <https://xcg-consulting.fr> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +############################################################################## +from odoo.models import BaseModel + + +class Base(BaseModel): + """Add :py:meth:~odoo.models.Model.get_clean_context and + :py:meth:~odoo.models.Model.with_lang method on models.""" + + _inherit = "base" + + def get_clean_context(self) -> dict[str, str]: + """Remove cruft from the Odoo context. + + Useful when returning view display actions. + """ + + return { + key: value + for key, value in self.env.context.items() + if ( + not key.startswith("default_") + and not key.startswith("search_default_") + and key not in ("form_view_ref", "group_by", "tree_view_ref") + ) + } + + def with_lang(self) -> BaseModel: + """Add lang info from the current user regardless of what the context may + already contain. It so happens the context often has wrong lang info by + default. + + Useful when running automated tasks. + + :return: That same Odoo record set with added lang info. + """ + + return self.with_context(lang=self.env.user.lang) diff --git a/pyproject.toml b/pyproject.toml index 9dc3378641b434b446ecdc0cd1f26bb222ffaf09_cHlwcm9qZWN0LnRvbWw=..4305ce9c031cf46f958d5a0f8c1e0f2cf99ad92d_cHlwcm9qZWN0LnRvbWw= 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,1 +1,41 @@ +[project] +name = "odoo-addon-base_context" +dynamic = ["version"] +readme = "README.rst" +requires-python = "~=3.10.0" +license = { file = "LICENSE", name = "GNU Affero General Public License v3" } +keywords = ["odoo"] +authors = [{ name = "XCG Consulting" }] +classifiers = [ + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Framework :: Odoo", + "Framework :: Odoo :: 16.0", + "License :: OSI Approved :: GNU Affero General Public License v3" +] +dependencies = ["odoo==16.0.*"] + +[project.optional-dependencies] +doc = [] +test = [] + +[project.urls] +repository = "https://orus.io/xcg/odoo-modules/base_context" +changelog = "https://orus.io/xcg/odoo-modules/base_context/-/blob/branch/16.0/NEWS.rst" + +[build-system] +requires = ["setuptools >=64.0.0", "wheel", "setuptools_scm[toml] >=6.2"] +build-backend = "setuptools.build_meta" + +[tool.setuptools] +package-dir = { "odoo.addons.base_context" = "." } + +[tool.setuptools.package-data] +"*" = ["*"] + +[tool.setuptools_scm] + +[tool.black] +target = 3.10 + [tool.isort] @@ -1,5 +41,5 @@ [tool.isort] -py_version = 39 +py_version = 310 profile = "black" known_odoo = ['odoo'] known_odoo_addons = ['odoo.addons'] @@ -12,6 +52,3 @@ 'FIRSTPARTY', 'LOCALFOLDER' ] - -[tool.black] -target = 3.9 diff --git a/tests/__init__.py b/tests/__init__.py index 9dc3378641b434b446ecdc0cd1f26bb222ffaf09_dGVzdHMvX19pbml0X18ucHk=..4305ce9c031cf46f958d5a0f8c1e0f2cf99ad92d_dGVzdHMvX19pbml0X18ucHk= 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1,1 +1,1 @@ -from . import test_with_lang # noqa: F401 +from . import test_with_lang diff --git a/tests/test_with_lang.py b/tests/test_with_lang.py index 9dc3378641b434b446ecdc0cd1f26bb222ffaf09_dGVzdHMvdGVzdF93aXRoX2xhbmcucHk=..4305ce9c031cf46f958d5a0f8c1e0f2cf99ad92d_dGVzdHMvdGVzdF93aXRoX2xhbmcucHk= 100644 --- a/tests/test_with_lang.py +++ b/tests/test_with_lang.py @@ -1,6 +1,6 @@ ############################################################################## # -# Base Context, for Odoo +# Context Methods, for Odoo # Copyright (C) 2022 XCG Consulting <https://xcg-consulting.fr> # # This program is free software: you can redistribute it and/or modify