diff --git a/ test-requirements.txt b/ test-requirements.txt deleted file mode 100644 index a3c717d..0000000 --- a/ test-requirements.txt +++ /dev/null @@ -1 +0,0 @@ -requests-mock==1.10.0 diff --git a/.copier-answers.yml b/.copier-answers.yml index ed2a30b..293e802 100644 --- a/.copier-answers.yml +++ b/.copier-answers.yml @@ -1,9 +1,10 @@ # Do NOT update manually; changes here will be overwritten by Copier -_commit: v1.24 +_commit: v1.36 _src_path: https://github.com/OCA/oca-addons-repo-template.git additional_ruff_rules: [] ci: GitHub convert_readme_fragments_to_markdown: false +enable_checklog_odoo: false generate_requirements_txt: true github_check_license: false github_ci_extra_env: {} diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..e0d5668 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +test-requirements.txt merge=union diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index 38b0ba1..5e6c3fb 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -13,13 +13,14 @@ jobs: pre-commit: runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v3 - - uses: actions/setup-python@v2 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: python-version: "3.11" + cache: 'pip' - name: Get python version run: echo "PY=$(python -VV | sha256sum | cut -d' ' -f1)" >> $GITHUB_ENV - - uses: actions/cache@v1 + - uses: actions/cache@v4 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 1c657c5..6501f5e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest name: Detect unreleased dependencies steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - run: | for reqfile in requirements.txt test-requirements.txt ; do if [ -f ${reqfile} ] ; then @@ -40,7 +40,7 @@ jobs: makepot: "false" services: postgres: - image: postgres:12.0 + image: postgres:12 env: POSTGRES_USER: odoo POSTGRES_PASSWORD: odoo @@ -48,7 +48,7 @@ jobs: ports: - 5432:5432 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: persist-credentials: false - name: Install addons and dependencies @@ -63,6 +63,13 @@ jobs: run: oca_init_test_database - name: Run tests run: oca_run_tests + - name: Upload screenshots from JS tests + uses: actions/upload-artifact@v4 + if: ${{ failure() }} + with: + name: Screenshots of failed JS tests - ${{ matrix.name }}${{ join(matrix.include) }} + path: /tmp/odoo_tests/${{ env.PGDATABASE }} + if-no-files-found: ignore - name: Update .pot files run: oca_export_and_push_pot https://x-access-token:${{ secrets.GIT_PUSH_TOKEN }}@github.com/${{ github.repository }} if: ${{ matrix.makepot == 'true' && github.event_name == 'push' && github.repository_owner == 'akretion' }} diff --git a/.gitignore b/.gitignore index 2b045db..6ec07a0 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,9 @@ var/ *.egg *.eggs +# Windows installers +*.msi + # Debian packages *.deb @@ -33,6 +36,7 @@ var/ # MacOS packages *.dmg +*.pkg # Installer logs pip-log.txt diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 92ffa42..8b79a7e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,7 +5,7 @@ exclude: | # Files and folders generated by bots, to avoid loops ^setup/|/static/description/index\.html$| # We don't want to mess with tool-generated files - .svg$|/tests/([^/]+/)?cassettes/|^.copier-answers.yml$|^.github/| + .svg$|/tests/([^/]+/)?cassettes/|^.copier-answers.yml$|^.github/|^eslint.config.cjs|^prettier.config.cjs| # Maybe reactivate this when all README files include prettier ignore tags? ^README\.md$| # Library files can have extraneous formatting (even minimized) @@ -39,11 +39,11 @@ repos: language: fail files: '[a-zA-Z0-9_]*/i18n/en\.po$' - repo: https://github.com/sbidoul/whool - rev: v0.5 + rev: v1.3 hooks: - id: whool-init - repo: https://github.com/oca/maintainer-tools - rev: d5fab7ee87fceee858a3d01048c78a548974d935 + rev: f9b919b9868143135a9c9cb03021089cabba8223 hooks: # update the NOT INSTALLABLE ADDONS section above - id: oca-update-pre-commit-excluded-addons @@ -63,25 +63,38 @@ repos: hooks: - id: oca-checks-odoo-module - id: oca-checks-po - - repo: https://github.com/pre-commit/mirrors-prettier - rev: v2.7.1 + args: + - --disable=po-pretty-format + - repo: local hooks: - id: prettier name: prettier (with plugin-xml) + entry: prettier + args: + - --write + - --list-different + - --ignore-unknown + types: [text] + files: \.(css|htm|html|js|json|jsx|less|md|scss|toml|ts|xml|yaml|yml)$ + language: node additional_dependencies: - "prettier@2.7.1" - "@prettier/plugin-xml@2.2.0" - args: - - --plugin=@prettier/plugin-xml - files: \.(css|htm|html|js|json|jsx|less|md|scss|toml|ts|xml|yaml|yml)$ - - repo: https://github.com/pre-commit/mirrors-eslint - rev: v8.24.0 + - repo: local hooks: - id: eslint - verbose: true + name: eslint + entry: eslint args: - --color - --fix + verbose: true + types: [javascript] + language: node + additional_dependencies: + - "eslint@8.24.0" + - "eslint-plugin-jsdoc@" + - "globals@" - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.3.0 hooks: diff --git a/.pylintrc b/.pylintrc index b8bdae0..23e2b49 100644 --- a/.pylintrc +++ b/.pylintrc @@ -25,19 +25,25 @@ disable=all enable=anomalous-backslash-in-string, api-one-deprecated, api-one-multi-together, - assignment-from-none, - attribute-deprecated, class-camelcase, - dangerous-default-value, dangerous-view-replace-wo-priority, - development-status-allowed, duplicate-id-csv, - duplicate-key, duplicate-xml-fields, duplicate-xml-record-id, eval-referenced, - eval-used, incoherent-interpreter-exec-perm, + openerp-exception-warning, + redundant-modulename-xml, + relative-import, + rst-syntax-error, + wrong-tabs-instead-of-spaces, + xml-syntax-error, + assignment-from-none, + attribute-deprecated, + dangerous-default-value, + development-status-allowed, + duplicate-key, + eval-used, license-allowed, manifest-author-string, manifest-deprecated-key, @@ -48,73 +54,68 @@ 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, - 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, + missing-newline-extrafiles, + old-api7-method-defined, + po-msgstr-variables, + po-syntax-error, + str-format-used, + unnecessary-utf8-coding-comment, + xml-attribute-translatable, + xml-deprecated-qweb-directive, + xml-deprecated-tree-attribute, + attribute-string-redundant, + consider-merging-classes-inherited, + context-overridden, + except-pass, invalid-commit, manifest-maintainers-list, - missing-newline-extrafiles, missing-readme, missing-return, odoo-addons-relative-import, - old-api7-method-defined, - po-msgstr-variables, - po-syntax-error, 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, - # messages that do not cause the lint step to fail - consider-merging-classes-inherited, + missing-manifest-dependency, + too-complex,, 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, - odoo-addons-relative-import, old-api7-method-defined, + unnecessary-utf8-coding-comment, + # messages that do not cause the lint step to fail + consider-merging-classes-inherited, + deprecated-module, + invalid-commit, + missing-readme, + odoo-addons-relative-import, redefined-builtin, - too-complex, - unnecessary-utf8-coding-comment + manifest-external-assets [REPORTS] diff --git a/.pylintrc-mandatory b/.pylintrc-mandatory index 4a7d901..0e7473d 100644 --- a/.pylintrc-mandatory +++ b/.pylintrc-mandatory @@ -17,19 +17,25 @@ disable=all enable=anomalous-backslash-in-string, api-one-deprecated, api-one-multi-together, - assignment-from-none, - attribute-deprecated, class-camelcase, - dangerous-default-value, dangerous-view-replace-wo-priority, - development-status-allowed, duplicate-id-csv, - duplicate-key, duplicate-xml-fields, duplicate-xml-record-id, eval-referenced, - eval-used, incoherent-interpreter-exec-perm, + openerp-exception-warning, + redundant-modulename-xml, + relative-import, + rst-syntax-error, + wrong-tabs-instead-of-spaces, + xml-syntax-error, + assignment-from-none, + attribute-deprecated, + dangerous-default-value, + development-status-allowed, + duplicate-key, + eval-used, license-allowed, manifest-author-string, manifest-deprecated-key, @@ -40,56 +46,50 @@ 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, - 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, + missing-newline-extrafiles, + old-api7-method-defined, + po-msgstr-variables, + po-syntax-error, + str-format-used, + unnecessary-utf8-coding-comment, + xml-attribute-translatable, + xml-deprecated-qweb-directive, + xml-deprecated-tree-attribute, + attribute-string-redundant, + consider-merging-classes-inherited, + context-overridden, + except-pass, invalid-commit, manifest-maintainers-list, - missing-newline-extrafiles, missing-readme, missing-return, odoo-addons-relative-import, - old-api7-method-defined, - po-msgstr-variables, - po-syntax-error, 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 [REPORTS] diff --git a/.ruff.toml b/.ruff.toml index 0240c75..8e8eccb 100644 --- a/.ruff.toml +++ b/.ruff.toml @@ -10,6 +10,7 @@ extend-select = [ "I", # isort "UP", # pyupgrade ] +extend-safe-fixes = ["UP008"] exclude = ["setup/*"] [format] diff --git a/README.md b/README.md index 637b100..5332d09 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ +[![Support the OCA](https://odoo-community.org/readme-banner-image)](https://odoo-community.org/get-involved?utm_source=repo-readme) +# Partner Module Information [![Pre-commit Status](https://github.com/akretion/partner-module-information/actions/workflows/pre-commit.yml/badge.svg?branch=16.0)](https://github.com/akretion/partner-module-information/actions/workflows/pre-commit.yml?query=branch%3A16.0) [![Build Status](https://github.com/akretion/partner-module-information/actions/workflows/test.yml/badge.svg?branch=16.0)](https://github.com/akretion/partner-module-information/actions/workflows/test.yml?query=branch%3A16.0) @@ -7,8 +9,6 @@ -# Partner Module Information - Repo for managing odoo modules and follow migration by project This repo allow you to : diff --git a/module_info_import/README.rst b/module_info_import/README.rst index b04f2ac..9d830d0 100644 --- a/module_info_import/README.rst +++ b/module_info_import/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + ================== Module Info Import ================== @@ -13,7 +17,7 @@ Module Info Import .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status :alt: Beta -.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png +.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-akretion%2Fpartner--module--information-lightgray.png?logo=github diff --git a/module_info_import/models/module_information.py b/module_info_import/models/module_information.py index f281690..330bf60 100644 --- a/module_info_import/models/module_information.py +++ b/module_info_import/models/module_information.py @@ -35,23 +35,25 @@ def synchronize_module(self): data = self.get_module_info(version.name) for orga, repos in data.items(): for repo, modules in repos.items(): - for module_name, vals in modules.items(): + for module_name, values in modules.items(): + vals = self._prepare_vals(values) self._update_or_create_modules( version, orga, repo, module_name, vals ) + def _prepare_vals(self, values): + return { + "description": values["description"], + "shortdesc": values["name"], + "authors": values["author"], + } + @api.model def _update_or_create_modules( self, version, orga_name, repo_name, module_name, vals ): repo = self._get_or_create_repo(orga_name, repo_name) - vals = { - "repo_id": repo.id, - "name": module_name, - "description": vals["description"], - "shortdesc": vals["name"], - "authors": vals["author"], - } + vals.update({"repo_id": repo.id, "name": module_name}) module = self.search([("name", "=", module_name), ("partner_id", "=", False)]) if module: if module._should_update_module(version.name, orga_name): @@ -60,6 +62,7 @@ def _update_or_create_modules( else: vals.update({"available_version_ids": [(4, version.id, 0)]}) module = self.create(vals) + return module @api.model def _get_or_create_repo(self, orga_name, repo_name): @@ -70,7 +73,11 @@ def _get_or_create_repo(self, orga_name, repo_name): return repo else: return self.env["module.repo"].create( - {"organization": orga_name, "name": repo_name} + { + "organization": orga_name, + "name": repo_name, + "url": f"https://github.com/{orga_name}/{repo_name}", + } ) @api.model diff --git a/module_info_import/static/description/index.html b/module_info_import/static/description/index.html index 411f461..07103b3 100644 --- a/module_info_import/static/description/index.html +++ b/module_info_import/static/description/index.html @@ -3,15 +3,16 @@ -Module Info Import +README.rst -
-

Module Info Import

+
+ + +Odoo Community Association + +
+

Module Info Import

-

Beta License: AGPL-3 akretion/partner-module-information

+

Beta License: AGPL-3 akretion/partner-module-information

Get a List of Odoo module information from another repo https://github.com/akretion/odoo-module-tracker/tree/gh-pages

Table of contents

@@ -382,7 +388,7 @@

Module Info Import

-

Bug Tracker

+

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 to smash it by providing a detailed and welcomed @@ -390,19 +396,20 @@

Bug Tracker

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

-

Credits

+

Credits

-

Authors

+

Authors

  • Akretion
-

Maintainers

+

Maintainers

This module is part of the akretion/partner-module-information project on GitHub.

You are welcome to contribute.

+
diff --git a/module_info_import_odoo_repository/README.rst b/module_info_import_odoo_repository/README.rst new file mode 100644 index 0000000..5eb2d3f --- /dev/null +++ b/module_info_import_odoo_repository/README.rst @@ -0,0 +1,59 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + +======================================= +Module Info Import From odoo Repository +======================================= + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:68355ee3fd120c37cb03b078934cf9b35b2676f51e8b13d4d054469eca37f154 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-akretion%2Fpartner--module--information-lightgray.png?logo=github + :target: https://github.com/akretion/partner-module-information/tree/16.0/module_info_import_odoo_repository + :alt: akretion/partner-module-information + +|badge1| |badge2| |badge3| + +Get a List of Odoo module information from another repo https://github.com/akretion/odoo-module-tracker/tree/gh-pages + +**Table of contents** + +.. contents:: + :local: + +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 to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Akretion + +Maintainers +~~~~~~~~~~~ + +This module is part of the `akretion/partner-module-information `_ project on GitHub. + +You are welcome to contribute. diff --git a/module_info_import_odoo_repository/__init__.py b/module_info_import_odoo_repository/__init__.py new file mode 100644 index 0000000..0650744 --- /dev/null +++ b/module_info_import_odoo_repository/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/module_info_import_odoo_repository/__manifest__.py b/module_info_import_odoo_repository/__manifest__.py new file mode 100644 index 0000000..7aabbcc --- /dev/null +++ b/module_info_import_odoo_repository/__manifest__.py @@ -0,0 +1,12 @@ +{ + "name": "Module Info Import From odoo Repository", + "summary": "Get information about modules from akretion/odoo-module-tracker", + "version": "16.0.1.0.0", + "website": "https://github.com/akretion/partner-module-information", + "license": "AGPL-3", + "author": "Akretion, Odoo Community Association (OCA)", + "category": "Tools", + "depends": ["module_info_import"], + "data": ["data/ir_cron.xml"], + "installable": True, +} diff --git a/module_info_import_odoo_repository/data/ir_cron.xml b/module_info_import_odoo_repository/data/ir_cron.xml new file mode 100644 index 0000000..e153461 --- /dev/null +++ b/module_info_import_odoo_repository/data/ir_cron.xml @@ -0,0 +1,17 @@ + + + + Module Information: Synchronize community module informations From Odoo Repository + + + 1 + weeks + -1 + + + code + model.synchronize_module_from_odoo_repository() + + diff --git a/module_info_import_odoo_repository/models/__init__.py b/module_info_import_odoo_repository/models/__init__.py new file mode 100644 index 0000000..fd20137 --- /dev/null +++ b/module_info_import_odoo_repository/models/__init__.py @@ -0,0 +1,2 @@ +from . import module_information +from . import module_version diff --git a/module_info_import_odoo_repository/models/module_information.py b/module_info_import_odoo_repository/models/module_information.py new file mode 100644 index 0000000..7a02b92 --- /dev/null +++ b/module_info_import_odoo_repository/models/module_information.py @@ -0,0 +1,51 @@ +import logging +import re + +import requests + +from odoo import api, models + +_logger = logging.getLogger(__name__) + + +class ModuleInformation(models.Model): + _inherit = "module.information" + + # called by cron + @api.model + def synchronize_module_from_odoo_repository(self): + url = self.env["ir.config_parameter"].sudo().get_param("odoo_repository_url") + response = requests.get(url, timeout=60) + for module in response.json(): + self.with_delay()._update_module_from_odoo_repository(module) + + def _update_module_from_odoo_repository(self, module): + version_id = self.env["odoo.version"]._get_id(module["branch"]) + version = self.env["odoo.version"].browse(version_id) + url = module["repository"]["repo_url"].lower() + match = re.search(r"github\.com\/([^\/]+)\/([^\/]+)", url) + if match: + # Only support github module for now, use org and repo + # from the url to be homogenious with existing data from + # module_info_import + org, repo = match.groups() + mod = self._update_or_create_modules( + version, + org, + repo, + module["module"], + self._prepare_vals_from_odoo_repository(module), + ) + mod_version = mod.module_version_ids.filtered( + lambda s: s.version_id == version + ) + if mod_version.migrations != module["migrations"]: + mod_version.migrations = module["migrations"] + mod_version._update_migration_hook() + + def _prepare_vals_from_odoo_repository(self, module): + return { + "description": module["summary"], + "shortdesc": module["title"], + "authors": ",".join(module["authors"]), + } diff --git a/module_info_import_odoo_repository/models/module_version.py b/module_info_import_odoo_repository/models/module_version.py new file mode 100644 index 0000000..65acf2e --- /dev/null +++ b/module_info_import_odoo_repository/models/module_version.py @@ -0,0 +1,15 @@ +# Copyright 2025 Akretion (https://www.akretion.com). +# @author Sébastien BEAU +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class ModuleVersion(models.Model): + _inherit = "module.version" + + migrations = fields.Json(helper="Migration information from odoo repository") + + def _update_migration_hook(self): + """Hook that can do extra processing after updating the migrations fields""" + self.ensure_one() diff --git a/module_info_import_odoo_repository/pyproject.toml b/module_info_import_odoo_repository/pyproject.toml new file mode 100644 index 0000000..4231d0c --- /dev/null +++ b/module_info_import_odoo_repository/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/module_info_import_odoo_repository/readme/DESCRIPTION.rst b/module_info_import_odoo_repository/readme/DESCRIPTION.rst new file mode 100644 index 0000000..98996f9 --- /dev/null +++ b/module_info_import_odoo_repository/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +Get a List of Odoo module information from another repo https://github.com/akretion/odoo-module-tracker/tree/gh-pages diff --git a/module_info_import_odoo_repository/static/description/index.html b/module_info_import_odoo_repository/static/description/index.html new file mode 100644 index 0000000..e0db40a --- /dev/null +++ b/module_info_import_odoo_repository/static/description/index.html @@ -0,0 +1,415 @@ + + + + + +README.rst + + + +
+ + + +Odoo Community Association + +
+

Module Info Import From odoo Repository

+ +

Beta License: AGPL-3 akretion/partner-module-information

+

Get a List of Odoo module information from another repo https://github.com/akretion/odoo-module-tracker/tree/gh-pages

+

Table of contents

+ +
+

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 to smash it by providing a detailed and welcomed +feedback.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • Akretion
  • +
+
+
+

Maintainers

+

This module is part of the akretion/partner-module-information project on GitHub.

+

You are welcome to contribute.

+
+
+
+
+ + diff --git a/module_info_import_odoo_repository/tests/__init__.py b/module_info_import_odoo_repository/tests/__init__.py new file mode 100644 index 0000000..ee3dc46 --- /dev/null +++ b/module_info_import_odoo_repository/tests/__init__.py @@ -0,0 +1 @@ +from . import test_module_info_partner diff --git a/module_info_import_odoo_repository/tests/data/module_list_14.yaml b/module_info_import_odoo_repository/tests/data/module_list_14.yaml new file mode 100644 index 0000000..91072e7 --- /dev/null +++ b/module_info_import_odoo_repository/tests/data/module_list_14.yaml @@ -0,0 +1,2566 @@ +akretion: + ak-odoo-incubator: + account_move_line_mass_edit_account: {} + attachment_asset_in_db: {} + base_custom_export: {} + dash_shared: + maintainers: + - Kev-Roche + database_age_cron: {} + forbid_record_creation: {} + intercompany_shared_contact: {} + label_wizard: {} + mail_unique_layout: {} + module_analysis_price: {} + product_pricelist_per_attribute_value: {} + product_uom_force_change: {} + project_estimate_step: {} + project_time_in_day: {} + proxy_action: {} + purchase_edi_file: {} + purchase_lot: {} + security_rule_not_editable: {} + odoo-usability: + account_bank_reconciliation_summary_xlsx: {} + account_invoice_update_wizard: {} + account_invoice_update_wizard_payment_mode: {} + account_menu_usability: {} + account_move_label_copy: {} + account_usability: {} + base_company_extension: {} + base_dynamic_list: {} + base_mail_sender_bcc: {} + base_partner_one2many_phone: {} + base_partner_ref: {} + base_usability: {} + crm_usability: {} + delivery_usability: {} + eradicate_quick_create: {} + hr_contract_usability: {} + link_tracker_usability: {} + mail_no_portal: + maintainers: + - alexis-via + mail_usability: {} + mrp_usability: {} + partner_tree_default_account: {} + partner_tree_default_base: {} + partner_tree_default_contacts: {} + pos_config_single_user: {} + pos_product_tree_default: {} + pos_usability: {} + product_category_tax: {} + product_manager_group: {} + product_manager_group_stock: {} + product_no_translation: {} + product_print_zpl_barcode: {} + product_usability: {} + purchase_product_tree_default: {} + purchase_stock_usability: {} + purchase_usability: {} + sale_confirm_wizard: {} + sale_no_optional_product: {} + sale_no_preview_button: {} + sale_order_add_bom: {} + sale_order_route: {} + sale_product_tree_default: {} + sale_purchase_no_product_template_menu: {} + sale_quotation_title: {} + sale_show_transaction: {} + sale_stock_usability: {} + sale_usability: {} + sales_team_usability: {} + shopinvader_usability: {} + stock_account_usability: {} + stock_inventory_usability: {} + stock_no_product_template_menu: {} + stock_picking_type_default_partner: {} + stock_product_tree_default: {} + stock_reception_usability: {} + stock_usability: {} + stock_valuation_xlsx: {} + web_tab_title: + maintainers: + - rvalyi +oca: + account-financial-reporting: + account_financial_report: {} + account_move_line_report_xls: {} + account_tax_balance: + maintainers: + - pedrobaeza + mis_builder_cash_flow: + maintainers: + - jjscarafia + mis_template_financial_report: + maintainers: + - hbrunn + partner_statement: + maintainers: + - MiquelRForgeFlow + account-financial-tools: + account_account_constraint_code: {} + account_asset_batch_compute: {} + account_asset_low_value: + maintainers: + - kittiu + account_asset_management: {} + account_asset_management_menu: {} + account_asset_number: {} + account_asset_transfer: + maintainers: + - kittiu + account_balance_line: {} + account_cash_deposit: {} + account_chart_update: {} + account_check_deposit: {} + account_fiscal_month: {} + account_fiscal_position_vat_check: {} + account_fiscal_year: + maintainers: + - eLBati + account_invoice_constraint_chronology: {} + account_journal_general_sequence: + maintainers: + - yajo + account_journal_lock_date: {} + account_loan: {} + account_lock_date_update: {} + account_lock_to_date: {} + account_menu: + maintainers: + - legalsylvain + account_move_budget: {} + account_move_fiscal_month: {} + account_move_fiscal_year: {} + account_move_force_removal: {} + account_move_line_check_number: + maintainers: + - ps-tubtim + account_move_line_menu: {} + account_move_line_purchase_info: {} + account_move_line_sale_info: {} + account_move_line_tax_editable: {} + account_move_line_used_currency: {} + account_move_name_sequence: + maintainers: + - alexis-via + - moylop260 + - frahikLV + account_move_print: + maintainers: + - JordiBForgeFlow + account_move_reversal_choose_method: {} + account_move_template: {} + account_netting: {} + account_no_default: + maintainers: + - dreispt + account_reconcile_show_boolean: + maintainers: + - remi-filament + account_sequence_option: + maintainers: + - kittiu + account_template_active: + maintainers: + - legalsylvain + base_vat_optional_vies: {} + product_category_tax: {} + stock_account_prepare_anglo_saxon_out_lines_hook: {} + account-fiscal-rule: + account_avatax_exemption: {} + account_avatax_exemption_base: {} + account_avatax_oca: + maintainers: + - dreispt + account_avatax_sale_oca: + maintainers: + - dreispt + account_avatax_website_sale: + maintainers: + - cybernexus + account_fiscal_position_partner_type: {} + account_multi_vat: + maintainers: + - ThomasBinsfeld + account_product_fiscal_classification: + maintainers: + - legalsylvain + account_product_fiscal_classification_test: + maintainers: + - legalsylvain + l10n_eu_oss: {} + account-invoice-reporting: + account_comment_template: {} + account_invoice_line_report: {} + account_invoice_line_sale_line_position: {} + account_invoice_production_lot: {} + account_invoice_report_due_list: {} + account_invoice_report_grouped_by_picking: {} + account_invoice_report_grouped_by_picking_sale_mrp: {} + account_invoice_report_hide_line: + maintainers: + - bodedra + - max3903 + partner_time_to_pay: + maintainers: + - max3903 + account-invoicing: + account_billing: + maintainers: + - Saran440 + account_global_discount: {} + account_invoice_alternate_payer: {} + account_invoice_base_invoicing_mode: {} + account_invoice_blocking: {} + account_invoice_change_currency: + maintainers: + - luisg123v + account_invoice_check_picking_date: + maintainers: + - carlosdauden + account_invoice_check_total: {} + account_invoice_date_due: + maintainers: + - luisg123v + - joao-p-marques + account_invoice_discount_display_amount: {} + account_invoice_fiscal_position_update: + maintainers: + - alexis-via + account_invoice_fixed_discount: {} + account_invoice_force_number: {} + account_invoice_line_description: {} + account_invoice_line_sequence: {} + account_invoice_merge: {} + account_invoice_mode_at_shipping: {} + account_invoice_mode_monthly: {} + account_invoice_mode_weekly: {} + account_invoice_partner: {} + account_invoice_payment_retention: {} + account_invoice_pricelist: {} + account_invoice_pricelist_sale: {} + account_invoice_refund_line_selection: {} + account_invoice_refund_link: {} + account_invoice_refund_reason: + maintainers: + - max3903 + account_invoice_refund_reinvoice: {} + account_invoice_restrict_linked_so: {} + account_invoice_search_by_reference: {} + account_invoice_section_sale_order: {} + account_invoice_supplier_ref_unique: {} + account_invoice_supplier_self_invoice: {} + account_invoice_supplierinfo_update: {} + account_invoice_supplierinfo_update_discount: + maintainers: + - legalsylvain + account_invoice_tax_note: {} + account_invoice_tax_required: {} + account_invoice_transmit_method: + maintainers: + - alexis-via + account_invoice_tree_currency: {} + account_invoice_triple_discount: {} + account_invoice_validation_queued: + maintainers: + - pedrobaeza + account_invoice_view_payment: {} + account_mail_autosubscribe: + maintainers: + - ivantodorovich + account_move_exception: {} + account_move_line_accounting_description: {} + account_move_line_accounting_description_purchase: {} + account_move_line_accounting_description_sale: {} + account_move_original_partner: {} + account_move_post_block: {} + account_move_propagate_ref: {} + account_move_tier_validation: {} + account_move_tier_validation_forward: {} + account_receipt_print: {} + account_refund_payment_term: + maintainers: + - petrus-v + product_supplierinfo_for_customer_invoice: {} + purchase_stock_picking_return_invoicing: + maintainers: + - pedrobaeza + - MiquelRForgeFlow + sale_line_refund_to_invoice_qty: {} + sale_order_invoicing_grouping_criteria: + maintainers: + - pedrobaeza + sale_order_invoicing_queued: {} + sale_timesheet_invoice_description: {} + stock_picking_invoicing: {} + account-payment: + account_cash_discount_base: {} + account_cash_discount_payment: {} + account_cash_discount_write_off: {} + account_cash_invoice: {} + account_check_date: + maintainers: + - ps-tubtim + account_check_payee: + maintainers: + - ps-tubtim + account_due_list: {} + account_due_list_aging_comment: {} + account_due_list_days_overdue: {} + account_due_list_payment_mode: {} + account_financial_discount: + maintainers: + - grindtildeath + account_payment_batch_process: {} + account_payment_batch_process_discount: + maintainers: + - mgosai + account_payment_credit_card: + maintainers: + - max3903 + account_payment_multi_deduction: + maintainers: + - kittiu + account_payment_paired_internal_transfer: {} + account_payment_return: {} + account_payment_return_import: {} + account_payment_return_import_iso20022: {} + account_payment_term_discount: + maintainers: + - bodedra + account_payment_term_extension: {} + account_payment_terminal: + maintainers: + - sbejaoui + account_payment_view_check_number: {} + account_payment_widget_amount: + maintainers: + - ChrisOForgeFlow + partner_aging: + maintainers: + - smangukiya + account-reconcile: + account_bank_statement_reopen_skip_undo_reconciliation: {} + account_mass_reconcile: {} + account_mass_reconcile_as_job: {} + account_mass_reconcile_by_mrp_production: {} + account_mass_reconcile_by_purchase_line: {} + account_mass_reconcile_by_sale_line: {} + account_mass_reconcile_ref_deep_search: {} + account_move_base_import: {} + account_move_reconcile_helper: {} + account_partner_reconcile: {} + account_reconcile_model_strict_match_amount: {} + account_reconcile_payment_order: + maintainers: + - pedrobaeza + account_reconcile_reconciliation_date: {} + account_reconcile_restrict_partner_mismatch: {} + account_reconciliation_widget: {} + bank-payment: + account_banking_mandate: {} + account_banking_mandate_contact: {} + account_banking_mandate_sale: {} + account_banking_pain_base: {} + account_banking_sepa_credit_transfer: {} + account_banking_sepa_direct_debit: {} + account_invoice_select_for_payment: {} + account_payment_mode: {} + account_payment_mode_default_account: {} + account_payment_order: {} + account_payment_order_notification: + maintainers: + - victoralmau + account_payment_order_return: {} + account_payment_order_sequence_payment_mode: {} + account_payment_order_tier_validation: + maintainers: + - marcelsavegnago + account_payment_order_vendor_email: {} + account_payment_partner: {} + account_payment_purchase: {} + account_payment_purchase_stock: {} + account_payment_sale: {} + bank-statement-import: + account_statement_import: + maintainers: + - alexis-via + account_statement_import_base: + maintainers: + - alexis-via + account_statement_import_camt: {} + account_statement_import_camt54: {} + account_statement_import_file_reconciliation_widget: + maintainers: + - alexis-via + account_statement_import_move_line: + maintainers: + - pedrobaeza + account_statement_import_ofx: {} + account_statement_import_online: + maintainers: + - alexey-pelykh + account_statement_import_online_paypal: + maintainers: + - alexey-pelykh + account_statement_import_online_ponto: {} + account_statement_import_online_ponto_ing: {} + account_statement_import_paypal: {} + account_statement_import_txt_xlsx: + maintainers: + - alexey-pelykh + community-data-files: + account_payment_unece: {} + account_tax_unece: + maintainers: + - alexis-via + base_bank_from_iban: {} + base_currency_iso_4217: {} + base_iso3166: {} + base_unece: + maintainers: + - astirpe + - alexis-via + l10n_eu_nace: {} + l10n_eu_product_adr: {} + uom_unece: + maintainers: + - astirpe + - alexis-via + connector: + component: + maintainers: + - guewen + component_event: {} + connector: {} + connector_base_product: {} + test_component: + maintainers: + - guewen + test_connector: {} + connector-ecommerce: + connector_ecommerce: {} + connector-telephony: + asterisk_click2dial: + maintainers: + - alexis-via + base_phone: + maintainers: + - alexis-via + connector_voicent: + maintainers: + - max3903 + crm_phone: + maintainers: + - alexis-via + event_phone: + maintainers: + - alexis-via + hr_phone: + maintainers: + - alexis-via + hr_recruitment_phone: + maintainers: + - alexis-via + sms_no_alter_body: {} + sms_no_automatic_delete: {} + sms_ovh_http: + maintainers: + - sebastienbeau + contract: + agreement: + maintainers: + - ygol + - alexis-via + agreement_account: + maintainers: + - alexis-via + - bealdav + agreement_legal: + maintainers: + - max3903 + - ygol + agreement_legal_sale: + maintainers: + - osi-scampbell + - max3903 + agreement_maintenance: + maintainers: + - max3903 + agreement_mrp: + maintainers: + - smangukiya + - max3903 + agreement_project: + maintainers: + - smangukiya + - ygol + - max3903 + agreement_repair: + maintainers: + - smangukiya + - max3903 + agreement_sale: + maintainers: + - alexis-via + - bealdav + agreement_serviceprofile: + maintainers: + - max3903 + agreement_stock: + maintainers: + - smangukiya + - max3903 + agreement_tier_validation: {} + contract: {} + contract_delivery_zone: {} + contract_invoice_start_end_dates: + maintainers: + - florian-dacosta + contract_mandate: {} + contract_payment_mode: {} + contract_sale: {} + contract_sale_generation: {} + contract_sale_tag: + maintainers: + - rousseldenis + contract_update_last_date_invoiced: {} + contract_variable_qty_prorated: + maintainers: + - sbejaoui + contract_variable_quantity: {} + crm: + crm_claim: {} + crm_claim_code: {} + crm_industry: {} + crm_l10n_eu_nace: {} + crm_lead_code: {} + crm_lead_firstname: {} + crm_lead_search_archive: + maintainers: + - bealdav + crm_lead_vat: {} + crm_location: {} + crm_location_nuts: {} + crm_phone_extension: + maintainers: + - bizzappdev + crm_phonecall: {} + crm_phonecall_summary_predefined: {} + crm_project: {} + crm_security_group: + maintainers: + - victoralmau + crm_stage_probability: {} + marketing_crm_partner: {} + currency: + account_cryptocurrency: {} + currency_rate_inverted: {} + currency_rate_update: {} + currency_rate_update_cmc: {} + delivery-carrier: + base_delivery_carrier_files: {} + base_delivery_carrier_label: {} + carrier_account_environment: + maintainers: + - florian-dacosta + delivery_auto_refresh: {} + delivery_carrier_agency: {} + delivery_carrier_category: + maintainers: + - rousseldenis + delivery_carrier_city: + maintainers: + - ivantodorovich + delivery_carrier_customer_info: {} + delivery_carrier_default_tracking_url: + maintainers: + - rousseldenis + delivery_carrier_info: {} + delivery_carrier_label_batch: {} + delivery_carrier_location: + maintainers: + - ivantodorovich + delivery_carrier_multi_zip: {} + delivery_carrier_package_measure_required: {} + delivery_carrier_partner: {} + delivery_carrier_pricelist: {} + delivery_correos_express: {} + delivery_cttexpress: {} + delivery_free_fee_removal: {} + delivery_multi_destination: {} + delivery_package_fee: {} + delivery_package_number: {} + delivery_postlogistics: {} + delivery_postlogistics_server_env: {} + delivery_price_method: {} + delivery_price_rule_untaxed: + maintainers: + - AshishHirapara + delivery_roulier: + maintainers: + - florian-dacosta + delivery_roulier_laposte_fr: + maintainers: + - florian-dacosta + delivery_roulier_option: + maintainers: + - florian-dacosta + delivery_schenker: {} + delivery_send_to_shipper_at_operation: {} + delivery_state: {} + delivery_tnt_oca: + maintainers: + - victoralmau + partner_default_delivery_carrier: + maintainers: + - SilvioC2C + partner_delivery_zone: {} + server_environment_delivery: {} + stock_picking_carrier_from_rule: {} + stock_picking_delivery_link: {} + e-commerce: + product_template_multi_link: {} + product_template_multi_link_date_span: {} + product_variant_multi_link: {} + website_sale_attribute_filter_form_submit: {} + website_sale_attribute_filter_multiselect: {} + website_sale_attribute_filter_price: + maintainers: + - Tardo + website_sale_b2x_alt_price: + maintainers: + - Yajo + website_sale_barcode_search: {} + website_sale_cart_expire: + maintainers: + - ivantodorovich + website_sale_category_breadcrumb: + maintainers: + - Rad0van + website_sale_checkout_country_vat: {} + website_sale_checkout_skip_payment: {} + website_sale_delivery_group: + maintainers: + - ivantodorovich + website_sale_hide_price: {} + website_sale_order_type: + maintainers: + - joao-p-marques + website_sale_product_assortment: + maintainers: + - CarlosRoca13 + website_sale_product_attribute_filter_category: + maintainers: + - ivantodorovich + website_sale_product_attribute_filter_visibility: {} + website_sale_product_attribute_value_filter_existing: {} + website_sale_product_brand: {} + website_sale_product_description: {} + website_sale_product_detail_attribute_image: {} + website_sale_product_detail_attribute_value_image: {} + website_sale_product_minimal_price: + maintainers: + - sergio-teruel + website_sale_require_legal: {} + website_sale_show_company_data: {} + website_sale_stock_available: {} + website_sale_stock_provisioning_date: {} + website_sale_suggest_create_account: {} + website_sale_tax_toggle: {} + website_sale_wishlist_keep: {} + edi: + account_einvoice_generate: + maintainers: + - alexis-via + account_invoice_download: + maintainers: + - alexis-via + account_invoice_download_ovh: + maintainers: + - alexis-via + account_invoice_export: {} + account_invoice_export_server_env: {} + account_invoice_facturx: + maintainers: + - alexis-via + account_invoice_facturx_py3o: + maintainers: + - alexis-via + account_invoice_import: + maintainers: + - alexis-via + account_invoice_import_facturx: + maintainers: + - alexis-via + account_invoice_import_invoice2data: + maintainers: + - alexis-via + account_invoice_import_simple_pdf: + maintainers: + - alexis-via + account_invoice_import_ubl: {} + account_invoice_ubl: {} + base_business_document_import: + maintainers: + - alexis-via + base_business_document_import_phone: + maintainers: + - alexis-via + base_ebill_payment_contract: + maintainers: + - TDu + base_edi: + maintainers: + - simahawk + base_facturx: + maintainers: + - alexis-via + base_ubl: {} + base_ubl_payment: {} + edi_account_invoice_import: + maintainers: + - LoisRForgeFlow + edi_account_oca: {} + edi_backend_partner_oca: + maintainers: + - LoisRForgeFlow + edi_endpoint_oca: {} + edi_exchange_template_oca: + maintainers: + - simahawk + edi_exchange_template_party_data: + maintainers: + - simahawk + edi_oca: + maintainers: + - simahawk + - etobella + edi_party_data_oca: + maintainers: + - simahawk + edi_purchase_oca: {} + edi_sale_order_import: + maintainers: + - simahawk + edi_sale_order_import_ubl: + maintainers: + - simahawk + edi_sale_order_import_ubl_endpoint: + maintainers: + - simahawk + edi_stock_oca: {} + edi_storage_oca: {} + edi_ubl_oca: + maintainers: + - simahawk + edi_voxel_oca: {} + edi_webservice_oca: + maintainers: + - etobella + - simahawk + edi_xml_oca: + maintainers: + - simahawk + partner_identification_import: {} + pdf_helper: + maintainers: + - simahawk + - alexis-via + product_import: {} + product_import_ubl: {} + purchase_order_ubl: {} + purchase_stock_ubl: {} + sale_order_customer_free_ref: {} + sale_order_import: {} + sale_order_import_ubl: {} + sale_order_import_ubl_customer_free_ref: {} + sale_order_packaging_import: {} + sale_order_ubl: {} + hr: + gamification_badge_report: + maintainers: + - AmmarOfficewalaSerpentcs + hr_branch: + maintainers: + - luistorresm + hr_contract_currency: {} + hr_contract_document: {} + hr_contract_employee_calendar_planning: {} + hr_contract_multi_job: {} + hr_contract_reference: {} + hr_contract_type: + maintainers: + - etobella + hr_course: {} + hr_course_survey: {} + hr_department_code: {} + hr_employee_age: {} + hr_employee_birth_name: {} + hr_employee_calendar_planning: + maintainers: + - victoralmau + - pedrobaeza + hr_employee_digitized_signature: + maintainers: + - newtratip + hr_employee_document: {} + hr_employee_firstname: {} + hr_employee_id: {} + hr_employee_lastnames: {} + hr_employee_medical_examination: {} + hr_employee_partner_external: {} + hr_employee_phone_extension: {} + hr_employee_ppe: + maintainers: + - marcelsavegnago + - eduaparicio + hr_employee_relative: {} + hr_employee_service: {} + hr_employee_service_contract: {} + hr_employee_ssn: {} + hr_holidays_settings: {} + hr_job_category: {} + hr_org_chart_overview: {} + hr_period: {} + hr_personal_equipment_request: {} + hr_personal_equipment_request_tier_validation: {} + hr_personal_equipment_stock: {} + hr_personal_equipment_variant_configurator: {} + hr_recruitment_notification: + maintainers: + - joao-p-marques + hr_worked_days_from_timesheet: {} + hr-timesheet: + crm_timesheet: {} + hr_employee_product: {} + hr_timesheet_activity_begin_end: {} + hr_timesheet_analysis: + maintainers: + - alexey-pelykh + hr_timesheet_employee_analytic_tag: + maintainers: + - victoralmau + hr_timesheet_purchase_order: {} + hr_timesheet_report: + maintainers: + - alexey-pelykh + hr_timesheet_report_milestone: {} + hr_timesheet_sheet: {} + hr_timesheet_sheet_activity: {} + hr_timesheet_sheet_attendance: {} + hr_timesheet_sheet_autodraft: {} + hr_timesheet_sheet_period: {} + hr_timesheet_sheet_policy_department_manager: {} + hr_timesheet_sheet_policy_project_manager: {} + hr_timesheet_task_domain: {} + hr_timesheet_task_required: {} + hr_timesheet_task_stage: {} + hr_timesheet_time_restriction: {} + hr_timesheet_time_type: {} + hr_utilization_analysis: + maintainers: + - alexey-pelykh + hr_utilization_report: {} + sale_timesheet_budget: + maintainers: + - victoralmau + sale_timesheet_line_exclude: {} + sale_timesheet_order_line_sync: {} + sale_timesheet_rounded: {} + intrastat: + intrastat_base: {} + intrastat_product: {} + intrastat_product_generic: {} + product_harmonized_system: + maintainers: + - alexis-via + - luc-demeyer + product_harmonized_system_delivery: + maintainers: + - alexis-via + - luc-demeyer + product_harmonized_system_stock: + maintainers: + - alexis-via + - luc-demeyer + l10n-brazil: + l10n_br_account: + maintainers: + - renatonlima + - rvalyi + l10n_br_account_due_list: + maintainers: + - renatonlima + - rvalyi + l10n_br_account_nfe: + maintainers: + - antoniospneto + - felipemotter + - mbcosta + l10n_br_account_payment_brcobranca: {} + l10n_br_account_payment_order: {} + l10n_br_base: + maintainers: + - renatonlima + - rvalyi + l10n_br_coa: + maintainers: + - renatonlima + - mileo + l10n_br_coa_generic: + maintainers: + - mileo + l10n_br_coa_simple: + maintainers: + - renatonlima + l10n_br_contract: + maintainers: + - mileo + - marcelsavegnago + l10n_br_crm: {} + l10n_br_currency_rate_update: + maintainers: + - renatonlima + l10n_br_delivery: + maintainers: + - renatonlima + - mbcosta + l10n_br_delivery_nfe: + maintainers: + - mbcosta + l10n_br_fiscal: + maintainers: + - renatonlima + l10n_br_fiscal_closing: {} + l10n_br_hr: {} + l10n_br_mis_report: + maintainers: + - mileo + l10n_br_nfe: + maintainers: + - rvalyi + - renatonlima + l10n_br_nfe_spec: + maintainers: + - rvalyi + l10n_br_nfse: + maintainers: + - gabrielcardoso21 + - mileo + - luismalta + - marcelsavegnago + l10n_br_portal: {} + l10n_br_purchase: + maintainers: + - renatonlima + - rvalyi + l10n_br_purchase_request: + maintainers: + - marcelsavegnago + l10n_br_purchase_stock: {} + l10n_br_repair: + maintainers: + - marcelsavegnago + l10n_br_resource: + maintainers: + - mileo + - hendixcosta + - lfdivino + l10n_br_sale: + maintainers: + - renatonlima + l10n_br_sale_invoice_plan: + maintainers: + - marcelsavegnago + l10n_br_sale_stock: + maintainers: + - renatonlima + - mbcosta + l10n_br_stock: {} + l10n_br_stock_account: {} + l10n_br_website_sale: {} + l10n_br_website_sale_delivery: + maintainers: + - marcelsavegnago + - DiegoParadeda + l10n_br_zip: + maintainers: + - renatonlima + payment_pagseguro: {} + spec_driven_model: + maintainers: + - rvalyi + l10n-france: + account_balance_ebp_csv_export: + maintainers: + - alexis-via + account_banking_fr_lcr: + maintainers: + - alexis-via + account_statement_import_fr_cfonb: + maintainers: + - alexis-via + l10n_fr_account_invoice_facturx: {} + l10n_fr_account_invoice_import_facturx: + maintainers: + - alexis-via + l10n_fr_account_invoice_import_simple_pdf: + maintainers: + - alexis-via + l10n_fr_account_tax_unece: + maintainers: + - alexis-via + l10n_fr_account_vat_return: + maintainers: + - alexis-via + l10n_fr_account_vat_return_teledec: + maintainers: + - alexis-via + l10n_fr_business_document_import: + maintainers: + - alexis-via + l10n_fr_chorus_account: + maintainers: + - alexis-via + l10n_fr_chorus_facturx: + maintainers: + - alexis-via + l10n_fr_chorus_sale: + maintainers: + - alexis-via + l10n_fr_cog: + maintainers: + - alexis-via + l10n_fr_das2: + maintainers: + - alexis-via + l10n_fr_department: + maintainers: + - legalsylvain + l10n_fr_department_oversea: + maintainers: + - alexis-via + l10n_fr_fec_oca: + maintainers: + - alexis-via + l10n_fr_hr_check_ssnid: + maintainers: + - alexis-via + l10n_fr_hr_rup: {} + l10n_fr_intrastat_product: + maintainers: + - alexis-via + l10n_fr_intrastat_service: + maintainers: + - alexis-via + l10n_fr_mis_reports: + maintainers: + - alexis-via + l10n_fr_pos_cert_allow_change_qty: {} + l10n_fr_siret: + maintainers: + - alexis-via + l10n_fr_siret_lookup: + maintainers: + - remi-filament + l10n_fr_state: + maintainers: + - legalsylvain + manufacture: + account_move_line_mrp_info: {} + base_repair: + maintainers: + - marcelsavegnago + mrp_account_analytic: + maintainers: + - dreispt + mrp_analytic_cost: {} + mrp_attachment_mgmt: + maintainers: + - victoralmau + mrp_bom_attribute_match: {} + mrp_bom_component_menu: {} + mrp_bom_hierarchy: {} + mrp_bom_line_sequence: {} + mrp_bom_location: {} + mrp_bom_tracking: {} + mrp_component_operation: {} + mrp_lot_on_hand_first: + maintainers: + - grindtildeath + mrp_multi_level: + maintainers: + - JordiBForgeFlow + - LoisRForgeFlow + mrp_multi_level_estimate: + maintainers: + - LoisRForgeFlow + mrp_planned_order_matrix: {} + mrp_production_grouped_by_product: {} + mrp_production_putaway_strategy: {} + mrp_production_quant_manual_assign: {} + mrp_production_serial_matrix: {} + mrp_progress_button: {} + mrp_restrict_lot: + maintainers: + - florian-dacosta + mrp_sale_info: {} + mrp_subcontracting_bom_dual_use: + maintainers: + - victoralmau + mrp_subcontracting_inhibit: + maintainers: + - victoralmau + mrp_subcontracting_partner_management: {} + mrp_subcontracting_purchase_link: {} + mrp_subcontracting_resupply_link: + maintainers: + - victoralmau + mrp_tag: {} + mrp_unbuild_move_link: {} + mrp_unbuild_subcontracting: {} + mrp_unbuild_valuation_layer_link: {} + mrp_warehouse_calendar: + maintainers: + - JordiBForgeFlow + mrp_workcenter_hierarchical: {} + mrp_workorder_sequence: + maintainers: + - LoisRForgeFlow + product_mrp_info: + maintainers: + - LoisRForgeFlow + quality_control_mrp_oca: {} + quality_control_oca: {} + quality_control_stock_oca: {} + repair_discount: {} + repair_refurbish: {} + repair_stock_move: {} + repair_type: {} + stock_picking_product_kit_helper: + maintainers: + - kittiu + stock_whole_kit_constraint: {} + mis-builder: + mis_builder: + maintainers: + - sbidoul + mis_builder_budget: + maintainers: + - sbidoul + mis_builder_demo: + maintainers: + - sbidoul + partner-contact: + animal: + maintainers: + - max3903 + animal_owner: + maintainers: + - max3903 + base_country_state_translatable: {} + base_location: {} + base_location_geonames_import: {} + base_location_nuts: {} + base_partner_sequence: {} + partner_address_street3: {} + partner_address_version: {} + partner_affiliate: {} + partner_bank_code: {} + partner_capital: {} + partner_category_security: + maintainers: + - victoralmau + partner_category_security_crm: + maintainers: + - victoralmau + partner_coc: + maintainers: + - bosd + partner_company_group: {} + partner_company_type: {} + partner_contact_access_link: + maintainers: + - Yajo + partner_contact_address_default: {} + partner_contact_age_range: {} + partner_contact_birthdate: {} + partner_contact_birthplace: {} + partner_contact_department: {} + partner_contact_gender: {} + partner_contact_in_several_companies: {} + partner_contact_job_position: {} + partner_contact_lang: {} + partner_contact_nationality: {} + partner_contact_personal_information_page: {} + partner_create_format_phone: {} + partner_data_vies_populator: {} + partner_deduplicate_acl: {} + partner_deduplicate_by_ref: {} + partner_deduplicate_by_website: {} + partner_deduplicate_filter: {} + partner_disable_gravatar: + maintainers: + - alexis-via + partner_duns: + maintainers: + - ivantodorovich + partner_email_check: {} + partner_email_duplicate_warn: + maintainers: + - alexis-via + partner_employee_quantity: + maintainers: + - pedrobaeza + partner_external_map: {} + partner_fax: {} + partner_firstname: {} + partner_helper: {} + partner_identification: {} + partner_identification_gln: {} + partner_identification_notification: {} + partner_identification_unique_by_category: {} + partner_industry_secondary: {} + partner_iterative_archive: {} + partner_label: {} + partner_manual_rank: {} + partner_mobile_duplicate_warn: + maintainers: + - alexis-via + partner_mobile_unique: + maintainers: + - AshishHirapara + partner_multi_relation: {} + partner_phone_extension: {} + partner_phone_secondary: + maintainers: + - ivantodorovich + partner_phonecall_schedule: {} + partner_pricelist_search: {} + partner_priority: + maintainers: + - patrickrwilson + partner_ref_unique: {} + partner_second_lastname: {} + partner_stage: + maintainers: + - dreispt + partner_tier_validation: + maintainers: + - dreispt + partner_title_order: {} + partner_tz: {} + partner_vat_unique: {} + portal_partner_select_all: {} + pos: + pos_access_right: {} + pos_backend_communication: + maintainers: + - hparfr + pos_cash_move_reason: {} + pos_customer_required: {} + pos_customer_tree_view_vat: + maintainers: + - mileo + pos_default_partner: {} + pos_disable_pricelist_selection: {} + pos_edit_order_line: {} + pos_empty_home: {} + pos_escpos_status: {} + pos_fixed_discount: + maintainers: + - eLBati + pos_global_discount_in_line: {} + pos_hide_banknote_button: {} + pos_margin: + maintainers: + - legalsylvain + pos_no_cash_bank_statement: + maintainers: + - alexis-via + pos_order_product_search: {} + pos_order_remove_line: + maintainers: + - robyf70 + pos_order_return: {} + pos_partner_firstname: + maintainers: + - robyf70 + pos_payment_change: + maintainers: + - legalsylvain + pos_payment_method_cashdro: {} + pos_payment_terminal: {} + pos_product_display_default_code: {} + pos_product_multi_barcode: {} + pos_product_sort: {} + pos_product_template: {} + pos_product_template_configurator: + maintainers: + - GabbasovDinar + - isserver1 + pos_receipt_hide_price: {} + pos_report_session_summary: {} + pos_require_product_quantity: {} + pos_reset_search: + maintainers: + - fkawala + pos_reuse_pricelist: {} + pos_session_pay_invoice: {} + pos_show_config_name: {} + pos_supplierinfo_barcode: + maintainers: + - eLBati + pos_supplierinfo_search: + maintainers: + - eLBati + pos_ticket_without_price: {} + pos_timeout: {} + pos_user_restriction: + maintainers: + - eLBati + pos_warning_exiting: {} + product-attribute: + base_product_mass_addition: {} + packaging_uom: + maintainers: + - rousseldenis + pos_product_cost_security: {} + product_assortment: {} + product_assortment_description: {} + product_attribute_archive: {} + product_attribute_value_menu: {} + product_barcode_required: + maintainers: + - simahawk + product_bom_revision: {} + product_categ_image: {} + product_category_active: {} + product_category_code: + maintainers: + - rousseldenis + product_category_code_unique: + maintainers: + - rousseldenis + product_category_product_link: {} + product_category_type: + maintainers: + - legalsylvain + product_code_mandatory: {} + product_code_unique: {} + product_cost_security: + maintainers: + - sergio-teruel + product_custom_info: {} + product_dimension: {} + product_form_pricelist: {} + product_logistics_uom: + maintainers: + - hparfr + product_lot_sequence: {} + product_main_supplierinfo: + maintainers: + - sebalix + product_manufacturer: {} + product_medical: {} + product_model_viewer: + maintainers: + - eLBati + product_multi_category: {} + product_multi_image: {} + product_net_weight: + maintainers: + - legalsylvain + product_order_noname: + maintainers: + - WR-96 + - moylop260 + - luisg123v + product_packaging_dimension: {} + product_packaging_type: {} + product_packaging_type_pallet: {} + product_packaging_type_required: + maintainers: + - simahawk + - dcrier + product_packaging_unit_price_calculator: {} + product_pricelist_assortment: {} + product_pricelist_button_box: + maintainers: + - rousseldenis + product_pricelist_direct_print: {} + product_pricelist_direct_print_company_group: {} + product_pricelist_revision: {} + product_pricelist_supplierinfo: {} + product_profile: + maintainers: + - bealdav + - sebastienbeau + - kevinkhao + product_restricted_type: {} + product_sale_manufactured_for: {} + product_seasonality: {} + product_secondary_unit: + maintainers: + - sergio-teruel + product_sequence: {} + product_state: + maintainers: + - emagdalenaC2i + product_state_active: + maintainers: + - rousseldenis + product_state_history: + maintainers: + - rousseldenis + product_status: {} + product_stock_state: + maintainers: + - sebastienbeau + - legalsylvain + - kevinkhao + product_supplierinfo_archive: + maintainers: + - GuillemCForgeFlow + - AlvaroTForgeFlow + - OriolVForgeFlow + product_supplierinfo_for_customer: {} + product_supplierinfo_for_customer_group: {} + product_supplierinfo_group: {} + product_supplierinfo_revision: {} + product_supplierinfo_stock_picking_type: + maintainers: + - victoralmau + product_template_tags: + maintainers: + - patrickrwilson + - ivantodorovich + product_template_tags_code: {} + product_tier_validation: + maintainers: + - dreispt + product_total_weight_from_packaging: {} + product_uom_updatable: {} + product_variant_attribute_name_manager: + maintainers: + - oriolvforgeflow + product_video_link: {} + product_weight: {} + product_weight_logistics_uom: + maintainers: + - hparfr + purchase_product_template_tags: + maintainers: + - ivantodorovich + sale_product_template_tags: + maintainers: + - ivantodorovich + stock_product_template_tags: + maintainers: + - ivantodorovich + uom_extra_data: {} + product-variant: + product_matrix_show_color: {} + product_matrix_sticky_header: {} + product_variant_configurator: {} + product_variant_default_code: + maintainers: + - Kev-Roche + product_variant_inactive: {} + product_variant_sale_price: {} + sale_order_line_variant_description: {} + project: + project_category: {} + project_deadline: {} + project_duplicate_subtask: {} + project_gtd: {} + project_hr: + maintainers: + - pedrobaeza + project_key: {} + project_list: {} + project_mail_chatter: {} + project_milestone: + maintainers: + - patrickrwilson + project_parent_task_filter: {} + project_recalculate: {} + project_role: + maintainers: + - alexey-pelykh + project_stage_closed: {} + project_stage_mgmt: + maintainers: + - DavidJForgeFlow + project_stage_state: {} + project_status: + maintainers: + - patrickrwilson + project_stock: + maintainers: + - victoralmau + project_stock_product_set: + maintainers: + - victoralmau + project_stock_request: {} + project_tag: + maintainers: + - patrickrwilson + project_task_add_very_high: + maintainers: + - astirpe + project_task_code: {} + project_task_default_stage: {} + project_task_dependency: + maintainers: + - astirpe + project_task_digitized_signature: {} + project_task_material: {} + project_task_pull_request: {} + project_template: + maintainers: + - patrickrwilson + project_template_milestone: + maintainers: + - patrickrwilson + project_timeline: {} + project_timeline_hr_timesheet: {} + project_timeline_task_dependency: {} + project_timesheet_time_control: + maintainers: + - ernestotejeda + project_timesheet_time_control_sale: + maintainers: + - eLBati + - bosd + project-reporting: + project_task_report: {} + purchase-reporting: + purchase_backorder: + maintainers: + - smangukiya + purchase_comment_template: {} + purchase-workflow: + partner_supplierinfo_smartbutton: + maintainers: + - victoralmau + procurement_batch_generator: + maintainers: + - alexis-via + procurement_purchase_no_grouping: {} + product_form_purchase_link: + maintainers: + - rousseldenis + product_supplier_code_purchase: {} + purchase_advance_payment: {} + purchase_allowed_product: {} + purchase_analytic_global: {} + purchase_blanket_order: {} + purchase_cancel_confirm: + maintainers: + - kittiu + purchase_cancel_reason: {} + purchase_commercial_partner: {} + purchase_delivery_split_date: {} + purchase_deposit: {} + purchase_discount: {} + purchase_exception: {} + purchase_fop_shipping: {} + purchase_force_invoiced: {} + purchase_invoice_plan: + maintainers: + - kittiu + purchase_isolated_rfq: + maintainers: + - kittiu + purchase_last_price_info: + maintainers: + - LoisRForgeFlow + purchase_location_by_line: {} + purchase_lot: + maintainers: + - florian-dacosta + purchase_manual_currency: {} + purchase_manual_delivery: {} + purchase_minimum_amount: {} + purchase_open_qty: {} + purchase_order_approval_block: {} + purchase_order_approved: {} + purchase_order_archive: {} + purchase_order_general_discount: {} + purchase_order_line_deep_sort: {} + purchase_order_line_description_picking: {} + purchase_order_line_invoicing: {} + purchase_order_line_menu: {} + purchase_order_line_packaging_qty: {} + purchase_order_line_price_history: {} + purchase_order_line_stock_available: {} + purchase_order_payment_term_report: {} + purchase_order_price_recalculation: + maintainers: + - victoralmau + purchase_order_product_attachment_mgmt: + maintainers: + - victoralmau + purchase_order_qty_change_no_recompute: + maintainers: + - victoralmau + purchase_order_secondary_unit: {} + purchase_order_shipping_date: {} + purchase_order_type: {} + purchase_order_uninvoiced_amount: {} + purchase_order_vendor_product: {} + purchase_order_weight_volume: {} + purchase_partner_approval: + maintainers: + - dreispt + purchase_partner_incoterm: + maintainers: + - TDu + - bealdav + purchase_picking_state: {} + purchase_product_usage: {} + purchase_propagate_qty: {} + purchase_quick: {} + purchase_reception_notify: {} + purchase_reception_status: + maintainers: + - alexis-via + purchase_report_menu_move: + maintainers: + - newtratip + purchase_representative: {} + purchase_request: {} + purchase_request_cancel_confirm: + maintainers: + - kittiu + purchase_request_department: {} + purchase_request_exception: {} + purchase_request_substate: {} + purchase_request_tier_validation: {} + purchase_request_to_requisition: {} + purchase_request_type: {} + purchase_requisition_tier_validation: {} + purchase_rfq_number: {} + purchase_security: + maintainers: + - joao-p-marques + purchase_stock_price_unit_sync: {} + purchase_stock_secondary_unit: {} + purchase_supplierinfo_product_breakdown: {} + purchase_tag: {} + purchase_tier_validation: {} + purchase_triple_discount: {} + purchase_vendor_bill_breakdown: + maintainers: + - geomer198 + - CetmixGitDrone + purchase_work_acceptance: + maintainers: + - ps-tubtim + purchase_work_acceptance_evaluation: + maintainers: + - kittiu + purchase_work_acceptance_invoice_plan: + maintainers: + - kittiu + purchase_work_acceptance_late_fines: + maintainers: + - Saran440 + purchase_work_acceptance_tier_validation: + maintainers: + - kittiu + sale_purchase_force_vendor: + maintainers: + - victoralmau + vendor_transport_lead_time: {} + reporting-engine: + base_comment_template: {} + bi_sql_editor: + maintainers: + - legalsylvain + bi_view_editor: {} + kpi_dashboard: + maintainers: + - etobella + kpi_dashboard_bokeh: {} + report_async: + maintainers: + - kittiu + report_context: {} + report_csv: {} + report_label: + maintainers: + - ivantodorovich + report_layout_config: {} + report_py3o: {} + report_py3o_fusion_server: {} + report_qr: {} + report_qweb_element_page_visibility: {} + report_qweb_encrypt: + maintainers: + - kittiu + report_qweb_parameter: {} + report_qweb_pdf_watermark: {} + report_qweb_signer: {} + report_wkhtmltopdf_param: {} + report_xlsx: {} + report_xlsx_helper: {} + report_xlsx_helper_demo: {} + report_xml: {} + sale-financial: {} + sale-reporting: + sale_backorder: + maintainers: + - smangukiya + sale_comment_template: {} + sale_layout_category_hide_detail: {} + sale_order_invoice_date: + maintainers: + - ivantodorovich + sale_order_line_position: {} + sale_order_report_product_image: {} + sale_order_weight: {} + sale_outgoing_product: {} + sale_report_commitment_date: + maintainers: + - ivantodorovich + sale_report_crossed_out_original_price: {} + sale_report_delivered: + maintainers: + - sergio-teruel + sale_report_delivered_brand: + maintainers: + - CarlosRoca13 + sale_report_delivered_subtotal: + maintainers: + - sergio-teruel + sale_report_delivery_date: + maintainers: + - ivantodorovich + sale-workflow: + portal_sale_personal_data_only: {} + pricelist_cache: {} + pricelist_cache_rest: {} + product_form_sale_link: {} + product_supplierinfo_for_customer_elaboration: {} + product_supplierinfo_for_customer_sale: {} + sale_advance_payment: {} + sale_amount_payment_link: {} + sale_automatic_workflow: {} + sale_automatic_workflow_delivery_state: {} + sale_automatic_workflow_ignore_exception: {} + sale_automatic_workflow_invoice_default_value: {} + sale_automatic_workflow_job: {} + sale_automatic_workflow_payment_mode: {} + sale_blanket_order: {} + sale_by_packaging: {} + sale_cancel_confirm: + maintainers: + - kittiu + sale_cancel_reason: {} + sale_commercial_partner: {} + sale_commitment_date_mandatory: {} + sale_company_currency: {} + sale_contact_type: {} + sale_default_uom: + maintainers: + - ashishhirapara + sale_delivery_date: + maintainers: + - mmequignon + sale_delivery_split_date: {} + sale_delivery_state: {} + sale_discount_display_amount: {} + sale_elaboration: {} + sale_exception: {} + sale_force_invoiced: {} + sale_global_discount: {} + sale_invoice_blocking: {} + sale_invoice_no_mail: {} + sale_invoice_plan: + maintainers: + - kittiu + sale_invoice_policy: {} + sale_isolated_quotation: + maintainers: + - bealdav + - kittiu + sale_last_price_info: {} + sale_mail_autosubscribe: + maintainers: + - ivantodorovich + sale_mrp_bom: {} + sale_order_archive: {} + sale_order_carrier_auto_assign: {} + sale_order_digitized_signature: + maintainers: + - mgosai + sale_order_disable_user_autosubscribe: {} + sale_order_general_discount: {} + sale_order_general_discount_triple: + maintainers: + - ashishhirapara + sale_order_invoice_amount: {} + sale_order_invoicing_finished_task: {} + sale_order_line_chained_move: + maintainers: + - rousseldenis + sale_order_line_date: {} + sale_order_line_delivery_state: {} + sale_order_line_description: {} + sale_order_line_description_single_attribute: {} + sale_order_line_discount_validation: + maintainers: + - max3903 + sale_order_line_initial_quantity: {} + sale_order_line_input: {} + sale_order_line_menu: {} + sale_order_line_note: {} + sale_order_line_packaging_qty: {} + sale_order_line_price_history: {} + sale_order_line_sequence: {} + sale_order_lot_generator: + maintainers: + - florian-dacosta + - mourad-ehm + - bealdav + sale_order_lot_selection: + maintainers: + - bodedra + sale_order_mass_action: {} + sale_order_note_template: {} + sale_order_partner_restrict: + maintainers: + - OriolVForgeFlow + sale_order_price_recalculation: {} + sale_order_priority: {} + sale_order_product_assortment: + maintainers: + - CarlosRoca13 + sale_order_qty_change_no_recompute: + maintainers: + - victoralmau + sale_order_report_without_price: {} + sale_order_revision: {} + sale_order_secondary_unit: {} + sale_order_tag: + maintainers: + - patrickrwilson + sale_order_type: {} + sale_order_warn_message: {} + sale_partner_approval: + maintainers: + - dreispt + sale_partner_incoterm: {} + sale_partner_version: {} + sale_pricelist_from_commitment_date: {} + sale_procurement_amendment: + maintainers: + - rousseldenis + sale_procurement_group_by_line: {} + sale_product_brand_exception: {} + sale_product_category_menu: {} + sale_product_multi_add: {} + sale_product_rating_verified: {} + sale_product_seasonality: {} + sale_product_set: {} + sale_product_set_packaging_qty: {} + sale_product_set_sale_by_packaging: {} + sale_quick: {} + sale_quick_seasonality: {} + sale_quotation_number: {} + sale_quotation_template_product_multi_add: {} + sale_rental: + maintainers: + - alexis-via + sale_restricted_qty: + maintainers: + - ashishhirapara + sale_shipping_info_helper: {} + sale_start_end_dates: + maintainers: + - alexis-via + sale_stock_delivery_address: {} + sale_stock_picking_blocking: {} + sale_stock_picking_note: {} + sale_stock_reconcile_valuation_kit: {} + sale_tier_validation: {} + sale_transaction_form_link: + maintainers: + - rousseldenis + sale_triple_discount: {} + sale_validity: {} + sale_wishlist: {} + sales_team_security: + maintainers: + - pedrobaeza + - ivantodorovich + sales_team_security_crm: + maintainers: + - ivantodorovich + sales_team_security_sale: + maintainers: + - ivantodorovich + search-engine: + connector_algolia: {} + connector_elasticsearch: {} + connector_search_engine: {} + server-auth: + auth_admin_passkey: {} + auth_api_key: {} + auth_api_key_group: + maintainers: + - simahawk + auth_api_key_server_env: {} + auth_dynamic_groups: {} + auth_jwt: + maintainers: + - sbidoul + auth_jwt_demo: + maintainers: + - sbidoul + auth_ldaps: {} + auth_oidc: + maintainers: + - sbidoul + auth_saml: {} + auth_session_timeout: {} + auth_signup_verify_email: {} + auth_user_case_insensitive: {} + password_security: {} + user_log_view: + maintainers: + - trojikman + users_ldap_groups: {} + users_ldap_mail: + maintainers: + - joao-p-marques + users_ldap_populate: + maintainers: + - joao-p-marques + vault: {} + vault_share: {} + server-backend: + base_external_dbsource: {} + base_global_discount: {} + base_import_match: {} + base_user_role: + maintainers: + - sebalix + - jcdrubay + - novawish + base_user_role_company: {} + base_user_role_profile: {} + server_action_navigate: + maintainers: + - legalsylvain + - ashishhirpara + server-brand: + disable_odoo_online: {} + portal_odoo_debranding: + maintainers: + - eLBati + - ivantodorovich + remove_odoo_enterprise: {} + server-env: + auth_saml_environment: {} + data_encryption: {} + mail_environment: {} + payment_environment: + maintainers: + - ivantodorovich + server_environment: {} + server_environment_data_encryption: {} + server_environment_iap: {} + server_environment_ir_config_parameter: {} + server-tools: + attachment_delete_restrict: + maintainers: + - yostashiro + - Kev-Roche + attachment_queue: + maintainers: + - florian-dacosta + - sebastienbeau + attachment_synchronize: + maintainers: + - florian-dacosta + - sebastienbeau + - GSLabIt + - bealdav + attachment_unindex_content: + maintainers: + - moylop260 + - ebirbe + - luisg123v + auditlog: {} + auto_backup: {} + autovacuum_message_attachment: {} + base_changeset: + maintainers: + - astirpe + base_conditional_image: {} + base_cron_exclusion: + maintainers: + - LoisRForgeFlow + base_custom_info: {} + base_deterministic_session_gc: {} + base_exception: + maintainers: + - hparfr + - sebastienbeau + base_fontawesome: {} + base_generate_code: + maintainers: + - Kev-Roche + base_jsonify: {} + base_kanban_stage: {} + base_kanban_stage_state: {} + base_m2m_custom_field: {} + base_model_restrict_update: {} + base_multi_image: {} + base_name_search_improved: {} + base_name_search_multi_lang: + maintainers: + - kittiu + base_remote: {} + base_report_auto_create_qweb: {} + base_search_fuzzy: {} + base_sequence_option: + maintainers: + - kittiu + base_sparse_field_list_support: {} + base_technical_user: {} + base_time_parameter: + maintainers: + - appstogrow + - nimarosa + base_time_window: {} + base_video_link: {} + base_view_inheritance_extension: {} + bus_alt_connection: {} + configuration_helper: {} + database_cleanup: {} + datetime_formatter: {} + dbfilter_from_header: {} + excel_import_export: + maintainers: + - kittiu + excel_import_export_demo: + maintainers: + - kittiu + fetchmail_incoming_log: {} + fetchmail_notify_error_to_sender: {} + fetchmail_notify_error_to_sender_test: {} + html_image_url_extractor: {} + html_text: {} + iap_alternative_provider: + maintainers: + - sebastienbeau + jsonifier: {} + letsencrypt: {} + mail_cleanup: {} + module_auto_update: {} + module_change_auto_install: + maintainers: + - legalsylvain + module_prototyper: {} + nsca_client: {} + onchange_helper: {} + rpc_helper: + maintainers: + - simahawk + scheduler_error_mailer: {} + sentry: + maintainers: + - barsi + - naglis + - versada + - moylop260 + - fernandahf + sequence_python: {} + slow_statement_logger: {} + sql_export: {} + sql_export_excel: {} + sql_export_mail: {} + sql_request_abstract: + maintainers: + - legalsylvain + test_base_time_window: {} + upgrade_analysis: {} + server-ux: + barcode_action: {} + base_cancel_confirm: + maintainers: + - kittiu + base_custom_filter: + maintainers: + - AshishHirapara + - ForgeFlow + base_export_manager: {} + base_import_security_group: {} + base_menu_visibility_restriction: + maintainers: + - victoralmau + base_optional_quick_create: {} + base_revision: {} + base_search_custom_field_filter: + maintainers: + - pedrobaeza + base_substate: {} + base_technical_features: {} + base_tier_validation: + maintainers: + - LoisRForgeFlow + base_tier_validation_correction: + maintainers: + - kittiu + base_tier_validation_formula: {} + base_tier_validation_forward: + maintainers: + - kittiu + base_tier_validation_report: + maintainers: + - kittiu + base_tier_validation_server_action: + maintainers: + - kittiu + base_user_locale: {} + chained_swapper: {} + date_range: + maintainers: + - lmignon + date_range_account: + maintainers: + - alexis-via + default_multi_user: + maintainers: + - LoisRForgeFlow + document_quick_access: + maintainers: + - etobella + document_quick_access_folder_auto_classification: + maintainers: + - etobella + filter_multi_user: + maintainers: + - LoisRForgeFlow + mass_editing: {} + mass_operation_abstract: {} + multi_step_wizard: {} + sequence_check_digit: {} + sequence_range_end: {} + sequence_reset_period: {} + server_action_domain: {} + social: + base_search_mail_content: {} + email_template_qweb: {} + mail_activity_board: {} + mail_activity_creator: {} + mail_activity_done: {} + mail_activity_partner: {} + mail_activity_team: {} + mail_allow_portal_internal_note: {} + mail_attach_existing_attachment: {} + mail_attach_existing_attachment_account: {} + mail_autosubscribe: {} + mail_chatter_thread_colour: {} + mail_debrand: + maintainers: + - pedrobaeza + - joao-p-marques + mail_drop_target: {} + mail_filter_adressee_by_contact: + maintainers: + - Kev-Roche + mail_full_expand: {} + mail_improved_tracking_value: {} + mail_inline_css: {} + mail_layout_force: + maintainers: + - ivantodorovich + mail_layout_preview: {} + mail_notification_custom_subject: + maintainers: + - joao-p-marques + mail_notification_with_history: + maintainers: + - TDu + mail_optional_autofollow: {} + mail_optional_follower_notification: {} + mail_outbound_static: {} + mail_partner_opt_out: {} + mail_preview_audio: {} + mail_preview_base: {} + mail_quoted_reply: {} + mail_restrict_follower_selection: {} + mail_restrict_send_button: {} + mail_send_copy: {} + mail_server_by_user: + maintainers: + - ChrisOForgeFlow + mail_show_follower: {} + mail_tracking: {} + mail_tracking_mailgun: {} + mail_tracking_mass_mailing: {} + mass_mailing_company_newsletter: + maintainers: + - ivantodorovich + mass_mailing_contact_partner: + maintainers: + - ivantodorovich + mass_mailing_custom_unsubscribe: {} + mass_mailing_event_registration_exclude: {} + mass_mailing_list_dynamic: {} + mass_mailing_partner: {} + mass_mailing_resend: + maintainers: + - pedrobaeza + mass_mailing_subscription_date: + maintainers: + - ivantodorovich + mass_mailing_subscription_email: + maintainers: + - ivantodorovich + mass_mailing_unique: {} + microsoft_outlook_single_tenant: {} + website_mass_mailing_name: {} + stock-logistics-barcode: + barcodes_generator_abstract: {} + barcodes_generator_location: {} + barcodes_generator_product: + maintainers: + - legalsylvain + base_gs1_barcode: {} + product_gs1_barcode: {} + product_multi_barcode: {} + product_multi_barcode_stock_menu: {} + product_supplierinfo_barcode: + maintainers: + - eLBati + sale_input_barcode: + maintainers: + - bealdav + stock_barcodes: {} + stock_barcodes_automatic_entry: + maintainers: + - AdriaGForgeFlow + stock_barcodes_gs1: {} + stock_barcodes_gs1_expiry: {} + stock_inventory_barcode: + maintainers: + - alexis-via + stock-logistics-reporting: + delivery_line_sale_line_position: {} + stock_account_quantity_history_location: {} + stock_account_valuation_report: {} + stock_card_report: {} + stock_inventory_valuation_pivot: {} + stock_picking_comment_template: {} + stock_picking_group_by_partner_by_carrier_sale_line_position: {} + stock_picking_report_custom_description: + maintainers: + - carlosdauden + stock_picking_report_valued: {} + stock_quantity_history_location: {} + stock_report_quantity_by_location: {} + stock-logistics-warehouse: + account_move_line_product: {} + account_move_line_stock_info: {} + procurement_auto_create_group: {} + product_quantity_update_force_inventory: {} + product_route_profile: + maintainers: + - Kev-Roche + scrap_location_filter: + maintainers: + - opensourceintegrators + scrap_reason_code: + maintainers: + - bodedra + stock_archive_constraint: + maintainers: + - victoralmau + stock_available: {} + stock_available_base_exclude_location: + maintainers: + - rousseldenis + stock_available_immediately: {} + stock_available_mrp: {} + stock_available_unreserved: + maintainers: + - LoisRForgeFlow + stock_change_qty_reason: {} + stock_cycle_count: + maintainers: + - LoisRForgeFlow + stock_demand_estimate: {} + stock_demand_estimate_matrix: {} + stock_exception: {} + stock_free_quantity: {} + stock_generate_putaway_from_inventory: + maintainers: + - pierrickbrun + - bealdav + - sebastienbeau + - kevinkhao + stock_helper: {} + stock_inventory_cost_info: {} + stock_inventory_discrepancy: {} + stock_inventory_exclude_sublocation: {} + stock_inventory_line_open: {} + stock_inventory_line_product_cost: {} + stock_inventory_lockdown: {} + stock_inventory_preparation_filter: {} + stock_inventory_preparation_filter_pos: + maintainers: + - alexis-via + stock_location_bin_name: {} + stock_location_children: {} + stock_location_empty: {} + stock_location_last_inventory_date: {} + stock_location_lockdown: {} + stock_location_position: {} + stock_location_route_description: {} + stock_location_tray: {} + stock_location_warehouse: {} + stock_location_zone: {} + stock_measuring_device: + maintainers: + - gurneyalex + stock_measuring_device_zippcube: + maintainers: + - gurneyalex + stock_move_auto_assign: {} + stock_move_common_dest: {} + stock_move_location: {} + stock_mts_mto_mrp_rule: + maintainers: + - geomer198 + - CetmixGitDrone + stock_mts_mto_rule: {} + stock_orderpoint_manual_procurement: {} + stock_orderpoint_manual_procurement_uom: {} + stock_orderpoint_move_link: {} + stock_orderpoint_origin: {} + stock_orderpoint_origin_mrp_link: {} + stock_orderpoint_purchase_link: {} + stock_orderpoint_route: {} + stock_orderpoint_uom: {} + stock_packaging_calculator: {} + stock_packaging_calculator_packaging_type: {} + stock_picking_cancel_confirm: + maintainers: + - kittiu + stock_picking_procure_method: {} + stock_picking_show_linked: {} + stock_product_qty_by_packaging: {} + stock_pull_list: + maintainers: + - LoisRForgeFlow + stock_putaway_method: + maintainers: + - asaunier + stock_putaway_product_template: + maintainers: + - kevinkhao + - sebastienbeau + stock_quant_manual_assign: {} + stock_quant_reservation_info: {} + stock_quant_reservation_info_mrp: {} + stock_request: {} + stock_request_analytic: {} + stock_request_cancel_confirm: + maintainers: + - kittiu + stock_request_direction: + maintainers: + - max3903 + stock_request_kanban: {} + stock_request_mrp: {} + stock_request_partner: {} + stock_request_picking_type: + maintainers: + - max3903 + stock_request_purchase: {} + stock_request_submit: {} + stock_request_tier_validation: {} + stock_reserve: {} + stock_reserve_rule: {} + stock_search_supplierinfo_code: {} + stock_secondary_unit: {} + stock_vertical_lift: {} + stock_vertical_lift_empty_tray_check: {} + stock_vertical_lift_kardex: {} + stock_vertical_lift_packaging_type: {} + stock_vertical_lift_qty_by_packaging: {} + stock_vertical_lift_server_env: {} + stock_vertical_lift_storage_type: {} + stock_warehouse_calendar: + maintainers: + - JordiBForgeFlow + stock-logistics-workflow: + delivery_package_default_shipping_weight: {} + delivery_procurement_group_carrier: {} + delivery_total_weight_from_packaging: {} + procurement_auto_create_group_carrier: {} + product_supplierinfo_for_customer_picking: {} + product_supplierinfo_picking: {} + purchase_stock_picking_invoice_link: {} + sale_line_returned_qty: {} + sale_line_returned_qty_mrp: {} + sale_order_global_stock_route: {} + sale_stock_mto_as_mts_orderpoint: {} + stock_auto_move: {} + stock_delivery_note: {} + stock_landed_costs_mrp_subcontracting: {} + stock_lock_lot: {} + stock_lot_on_hand_first: + maintainers: + - grindtildeath + stock_lot_product_qty_search: + maintainers: + - grindtildeath + stock_lot_production_date: {} + stock_lot_scrap: {} + stock_move_assign_picking_hook: {} + stock_move_change_source_location: {} + stock_move_forced_lot: {} + stock_move_line_auto_fill: {} + stock_move_quick_lot: {} + stock_no_negative: {} + stock_owner_restriction: {} + stock_partner_delivery_window: {} + stock_picking_auto_create_lot: + maintainers: + - sergio-teruel + stock_picking_back2draft: {} + stock_picking_backorder_strategy: + maintainers: + - rousseldenis + - mgosai + stock_picking_batch_extended: + maintainers: + - gurneyalex + - carlosdauden + - i-vyshnevska + stock_picking_cancel_reason: {} + stock_picking_filter_lot: {} + stock_picking_group_by_partner_by_carrier: {} + stock_picking_group_by_partner_by_carrier_by_date: {} + stock_picking_import_serial_number: + maintainers: + - sergio-teruel + stock_picking_invoice_link: {} + stock_picking_line_sequence: {} + stock_picking_mass_action: {} + stock_picking_product_link: + maintainers: + - robinkeunen + stock_picking_progress: + maintainers: + - mmequignon + - JuMiSanAr + stock_picking_purchase_order_link: {} + stock_picking_restrict_cancel_with_orig_move: {} + stock_picking_return_show_lot: {} + stock_picking_sale_order_link: {} + stock_picking_send_by_mail: {} + stock_picking_show_backorder: {} + stock_picking_show_return: {} + stock_picking_tier_validation: {} + stock_picking_warn_message: {} + stock_production_lot_active: + maintainers: + - ThomasBinsfeld + stock_push_delay: {} + stock_putaway_by_route: {} + stock_putaway_hook: {} + stock_quant_package_dimension: {} + stock_quant_package_dimension_total_weight_from_packaging: {} + stock_quant_package_product_packaging: {} + stock_restrict_lot: + maintainers: + - florian-dacosta + stock_return_request: {} + stock_scheduler_assignation_horizon: {} + stock_split_picking: {} + stock_valuation_layer_by_category: {} + stock_valuation_no_developer_mode: {} + web: + support_branding: {} + web_access_rule_buttons: {} + web_action_conditionable: {} + web_advanced_search: {} + web_calendar_color_field: {} + web_calendar_slot_duration: + maintainers: + - Yajo + web_company_color: {} + web_copy_confirm: {} + web_decimal_numpad_dot: {} + web_dialog_size: {} + web_disable_export_group: {} + web_domain_field: {} + web_drop_target: {} + web_environment_ribbon: {} + web_group_expand: {} + web_ir_actions_act_multi: {} + web_ir_actions_act_view_reload: {} + web_ir_actions_act_window_message: {} + web_listview_range_select: {} + web_m2x_options: {} + web_m2x_options_manager: {} + web_no_bubble: {} + web_notify: {} + web_pwa_oca: + maintainers: + - eLBati + web_refresher: {} + web_responsive: + maintainers: + - Yajo + - Tardo + web_search_with_and: {} + web_send_message_popup: {} + web_sheet_full_width: {} + web_switch_context_warning: {} + web_timeline: + maintainers: + - tarteo + web_tree_dynamic_colored_field: {} + web_tree_image_tooltip: {} + web_tree_many2one_clickable: {} + web_view_calendar_list: {} + web_widget_bokeh_chart: + maintainers: + - LoisRForgeFlow + web_widget_char_size: {} + web_widget_child_selector: {} + web_widget_ckeditor: + maintainers: + - ivantodorovich + web_widget_domain_editor_dialog: {} + web_widget_dropdown_dynamic: {} + web_widget_image_download: {} + web_widget_image_webcam: {} + web_widget_many2one_simple: + maintainers: + - Tardo + web_widget_mermaid: {} + web_widget_model_viewer: + maintainers: + - eLBati + web_widget_mpld3_chart: {} + web_widget_numeric_step: {} + web_widget_open_tab: {} + web_widget_plotly_chart: + maintainers: + - robyf70 + web_widget_text_markdown: {} + web_widget_url_advanced: {} + web_widget_x2many_2d_matrix: {} diff --git a/module_info_import_odoo_repository/tests/data/module_list_14_duplicate.yaml b/module_info_import_odoo_repository/tests/data/module_list_14_duplicate.yaml new file mode 100644 index 0000000..4614729 --- /dev/null +++ b/module_info_import_odoo_repository/tests/data/module_list_14_duplicate.yaml @@ -0,0 +1,12 @@ +akretion: + odoo-usability: + duplicate_module_test1: {} +oca: + account-financial-tools: + duplicate_module_test1: {} + duplicate_module_test2: {} +tiers: + module: + single_module_test: {} + duplicate_module_test1: {} + duplicate_module_test2: {} diff --git a/module_info_import_odoo_repository/tests/test_module_info_partner.py b/module_info_import_odoo_repository/tests/test_module_info_partner.py new file mode 100644 index 0000000..af6f25a --- /dev/null +++ b/module_info_import_odoo_repository/tests/test_module_info_partner.py @@ -0,0 +1,76 @@ +import os + +import requests_mock +import yaml + +from odoo.tests import TransactionCase + + +class TestinfoImport(TransactionCase): + def setUp(self): + super().setUp() + data_dir = os.path.join( + os.path.dirname(__file__), "data", "module_list_14.yaml" + ) + with open(data_dir) as f: + self.modules_yaml = f.read() + self.env["odoo.version"].search([]).unlink() + self.env["odoo.version"].create({"name": "14.0"}) + + def test_modules_import(self): + with requests_mock.mock() as m: + m.get( + "https://raw.githubusercontent.com/akretion/" + "odoo-module-tracker/gh-pages/14.0.yml", + text=self.modules_yaml, + ) + + self.env["module.information"].synchronize_module() + + modules_dict = yaml.safe_load(self.modules_yaml) + + module_list = [] + for _orga, repos in modules_dict.items(): + for _repo, modules in repos.items(): + for module in modules: + if module not in module_list: + module_list.append(module) + + self.assertEqual( + len(module_list), + self.env["module.information"].search_count( + [("available_version_ids", "=", "14.0")] + ), + ) + + def test_modules_import_duplicate(self): + data_dir = os.path.join( + os.path.dirname(__file__), "data", "module_list_14_duplicate.yaml" + ) + + with open(data_dir) as f: + self.modules_yaml = f.read() + with requests_mock.mock() as m: + m.get( + "https://raw.githubusercontent.com/akretion/" + "odoo-module-tracker/gh-pages/14.0.yml", + text=self.modules_yaml, + ) + self.env["module.information"].synchronize_module() + module = self.env["module.information"].search( + [("name", "=", "single_module_test")] + ) + # test module single is imported + self.assertEqual(module.repo_id.organization, "tiers") + # test module duplicate + module = self.env["module.information"].search( + [("name", "=", "duplicate_module_test1")] + ) + # check priority to OCA + self.assertEqual(module.repo_id.organization, "oca") + # test duplicate module diffrent order + module = self.env["module.information"].search( + [("name", "=", "duplicate_module_test2")] + ) + # check priority to OCA + self.assertEqual(module.repo_id.organization, "oca") diff --git a/module_info_import_odoo_repository/views/module_version_view.xml b/module_info_import_odoo_repository/views/module_version_view.xml new file mode 100644 index 0000000..6d8e4b8 --- /dev/null +++ b/module_info_import_odoo_repository/views/module_version_view.xml @@ -0,0 +1,50 @@ + + + + + module.version.tree.view + module.version + + + + + + + + + + + module.version.search.view + module.version + + + + + + + + + + + + + Module Versions + ir.actions.act_window + module.version + tree,form + + + + + + diff --git a/module_info_migration/README.rst b/module_info_migration/README.rst index 34cb0d6..6fb1d84 100644 --- a/module_info_migration/README.rst +++ b/module_info_migration/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + ===================== Module Info Migration ===================== @@ -13,7 +17,7 @@ Module Info Migration .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status :alt: Beta -.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png +.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-akretion%2Fpartner--module--information-lightgray.png?logo=github diff --git a/module_info_migration/__manifest__.py b/module_info_migration/__manifest__.py index 90fd6db..44878d0 100644 --- a/module_info_migration/__manifest__.py +++ b/module_info_migration/__manifest__.py @@ -5,12 +5,19 @@ "author": "Akretion, Odoo Community Association (OCA)", "website": "https://github.com/akretion/partner-module-information", "category": "Tools", - "depends": ["module_info_partner", "project", "project_task_stage_state"], + "depends": [ + "module_info_partner", + "module_info_import_odoo_repository", + "project", + "project_task_stage_state", + ], "data": [ "security/ir.model.access.csv", "views/res_partner.xml", "views/module_partner.xml", "views/module_information.xml", + "views/missing_pull_request_view.xml", + "views/project_task_view.xml", "wizard/module_task_creator.xml", ], "installable": True, diff --git a/module_info_migration/models/__init__.py b/module_info_migration/models/__init__.py index 68a542c..e5473b6 100644 --- a/module_info_migration/models/__init__.py +++ b/module_info_migration/models/__init__.py @@ -1,5 +1,9 @@ from . import res_partner from . import module_information from . import module_partner - +from . import module_version +from . import pull_request +from . import missing_pull_request from . import project_task +from . import project_project +from . import module_repo diff --git a/module_info_migration/models/missing_pull_request.py b/module_info_migration/models/missing_pull_request.py new file mode 100644 index 0000000..8f30cb2 --- /dev/null +++ b/module_info_migration/models/missing_pull_request.py @@ -0,0 +1,75 @@ +# Copyright 2025 Akretion (https://www.akretion.com). +# @author Sébastien BEAU +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class MissingPullRequest(models.Model): + _name = "missing.pull.request" + _description = "Missing Pull Request" + _order = "repo_id, src_version_id, target_version_id, pr_id" + + pr_id = fields.Many2one( + "pull.request", + "Pr", + readonly=True, + index=True, + ) + title = fields.Char(related="pr_id.title") + url = fields.Char(related="pr_id.url") + organization = fields.Char( + related="repo_id.organization", + store=True, + index=True, + ) + repo_id = fields.Many2one( + "module.repo", + "Repo", + related="pr_id.repo_id", + store=True, + readonly=True, + index=True, + ) + state = fields.Selection( + [ + ("to_analyse", "To Analyse"), + ("todo", "Todo"), + ("ignore", "Drop this code"), + ("useless", "Useless linting"), + ], + default="to_analyse", + index=True, + ) + module_ids = fields.Many2many( + comodel_name="module.module", + string="Module", + related="pr_id.module_ids", + index=True, + ) + src_version_id = fields.Many2one( + "odoo.version", + "Src Version", + related="pr_id.version_id", + store=True, + index=True, + ) + target_version_id = fields.Many2one( + "odoo.version", + "Target Version", + readonly=True, + index=True, + ) + missing_commits = fields.Text() + + def set_todo(self): + self.state = "todo" + + def set_ignore(self): + self.state = "ignore" + + def set_useless(self): + self.state = "useless" + + def set_to_analyse(self): + self.state = "to_analyse" diff --git a/module_info_migration/models/module_information.py b/module_info_migration/models/module_information.py index 4b2fe50..764a19f 100644 --- a/module_info_migration/models/module_information.py +++ b/module_info_migration/models/module_information.py @@ -4,6 +4,10 @@ class ModuleInformation(models.Model): _inherit = "module.information" + missing_pr_ids = fields.Many2many( + comodel_name="missing.pull.request", string="Missing Pr" + ) + obsolete_version_id = fields.Many2one( "odoo.version", string="Obsolete Version", diff --git a/module_info_migration/models/module_partner.py b/module_info_migration/models/module_partner.py index c84f94c..72096fd 100644 --- a/module_info_migration/models/module_partner.py +++ b/module_info_migration/models/module_partner.py @@ -1,4 +1,37 @@ -from odoo import _, api, exceptions, fields, models +import logging + +from odoo import _, api, fields, models +from odoo.exceptions import UserError + +_logger = logging.getLogger(__name__) + + +HTML_TEMPLATE = """ + + + + + + + + + + + + {rows} + +
idurlauthortitlemissing_commit
+""" + +ROW_TEMPLATE = """ + + {id} + {url} + {author} + {title} + {missing_commits} + +""" class ModulePartner(models.Model): @@ -7,13 +40,82 @@ class ModulePartner(models.Model): migration_status = fields.Selection( selection=[ ("obsolete", "Obsolete"), + ("todo", "Todo"), + ("planned", "Planned"), ("ongoing_pr", "Ongoing"), + ("port_commits", "Ported (missing commit)"), ("done", "Done"), ], compute="_compute_migrated", store=True, ) - task_ids = fields.Many2many("project.task", string="tasks") + task_ids = fields.Many2many( + "project.task", + string="Tasks", + readonly=True, + ) + + missing_commit = fields.Json( + compute="_compute_missing_commit", + store=True, + ) + missing_commit_html = fields.Html( + compute="_compute_missing_commit_html", + ) + missing_pr_ids = fields.Many2many( + comodel_name="missing.pull.request", + string="Missing Pr", + compute="_compute_missing_pr_ids", + ) + + @api.depends("module_version_id.missing_pr_ids") + def _compute_missing_pr_ids(self): + for record in self: + record.missing_pr_ids = record.module_version_id.missing_pr_ids.filtered( + lambda s, record=record: s.target_version_id + == record.partner_id.target_odoo_version_id + ) + + @api.depends("module_version_id.migrations") + def _compute_missing_commit(self): + for record in self: + migration = record._get_migration_data() + if migration: + record.missing_commit = migration["results"] + else: + record.missing_commit = [] + + @api.depends("module_version_id.migrations") + def _compute_missing_commit_html(self): + for record in self: + rows = [] + if record.missing_commit: + for pr_id, pr_info in record.missing_commit.items(): + if not pr_id: + rows.append( + ROW_TEMPLATE.format( + id=pr_id, + url=pr_info["url"], + author=pr_info["author"], + title=pr_info["title"], + missing_commits="
".join(pr_info["missing_commits"]), + ) + ) + if rows: + record.missing_commit_html = HTML_TEMPLATE.format(rows="\n".join(rows)) + else: + record.missing_commit_html = "" + + def _get_migration_data(self): + migrations = self.module_version_id.migrations or [] + target_version = self.partner_id.target_odoo_version_id + for migration in migrations: + if ( + migration["target_branch"] == target_version.name + and migration["process"] == "port_commits" + ): + return migration + return None @api.depends( "module_id.available_version_ids", @@ -21,6 +123,7 @@ class ModulePartner(models.Model): "module_id.wip_version_ids", "module_id.obsolete_version_id", "task_ids.stage_id", + "missing_commit", ) def _compute_migrated(self): versions = self.env["odoo.version"].search([]) @@ -36,41 +139,43 @@ def _compute_migrated(self): ).ids else: obsolete_version_ids = [] - if record.task_ids: - if any( - [task.state not in ("done", "cancel") for task in record.task_ids] - ): - record.migration_status = "ongoing_pr" - else: - record.migration_status = "done" - elif target_version in record.module_id.wip_version_ids: + + if target_version in record.module_id.wip_version_ids: record.migration_status = "ongoing_pr" elif target_version.id in obsolete_version_ids: record.migration_status = "obsolete" elif target_version in record.module_id.available_version_ids: - record.migration_status = "done" + if record.missing_commit: + record.migration_status = "port_commits" + else: + record.migration_status = "done" + elif record.task_ids: + record.migration_status = "planned" else: - record.migration_status = False + record.migration_status = "todo" def open_pull_request(self): self.ensure_one() - dest_module_version = self.env["module.version"].search( + pulls = self.env["pull.request"].search( [ + ("module_ids", "=", self.module_id.id), ("version_id", "=", self.partner_id.target_odoo_version_id.id), - ("url_pull_request", "!=", False), - ("module_id", "=", self.module_id.id), - ("state", "=", "pending"), ] ) - if not dest_module_version: - raise exceptions.UserError(_("No known migration PR for this module.")) - client_action = { - "type": "ir.actions.act_url", - "name": "Migration PR", - "target": "new", - "url": dest_module_version.url_pull_request, - } - return client_action + if len(pulls) == 0: + raise UserError(_("No known migration PR for this module.")) + elif len(pulls) > 1: + raise UserError( + _("Several Pull are open \n: %s") + % "\n- ".join([pull.url for pull in pulls]) + ) + else: + return { + "type": "ir.actions.act_url", + "name": "Migration PR", + "target": "new", + "url": pulls.url, + } def open_task(self): tasks = self.task_ids diff --git a/module_info_migration/models/module_repo.py b/module_info_migration/models/module_repo.py new file mode 100644 index 0000000..69acb1e --- /dev/null +++ b/module_info_migration/models/module_repo.py @@ -0,0 +1,12 @@ +# Copyright 2025 Akretion (https://www.akretion.com). +# @author Sébastien BEAU +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + + +from odoo import fields, models + + +class ModuleRepo(models.Model): + _inherit = "module.repo" + + missing_pr_ids = fields.One2many("missing.pull.request", "repo_id", "Missing Pr") diff --git a/module_info_migration/models/module_version.py b/module_info_migration/models/module_version.py new file mode 100644 index 0000000..2026365 --- /dev/null +++ b/module_info_migration/models/module_version.py @@ -0,0 +1,71 @@ +# Copyright 2025 Akretion (https://www.akretion.com). +# @author Sébastien BEAU +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +import logging + +from odoo import api, fields, models + +_logger = logging.getLogger(__name__) + + +class ModuleVersion(models.Model): + _inherit = "module.version" + + missing_pr_ids = fields.Many2many( + comodel_name="missing.pull.request", + string="Missing Pr", + compute="_compute_missing_pr_ids", + ) + + @api.depends( + "module_id.pr_ids.missing_pr_ids", + ) + def _compute_missing_pr_ids(self): + for record in self: + record.missing_pr_ids = record.module_id.pr_ids.missing_pr_ids.filtered( + lambda s, record=record: s.src_version_id == record.version_id + ) + + def _update_migration_hook(self): + res = super()._update_migration_hook() + if self.migrations: + for migration in self.migrations: + if migration["process"] == "port_commits": + target_version_id = self.env["odoo.version"]._get_id( + migration["target_branch"] + ) + for pr_number, pr_info in migration["results"].items(): + try: + pr_number = int(pr_number) + except Exception: + _logger.warning("Pr is missing, ignore %s" % pr_info) + continue + repo = self.module_id.repo_id + pr = self.env["pull.request"].search( + [ + ("repo_id", "=", repo.id), + ("number", "=", pr_number), + ] + ) + if not pr: + pr = repo.import_pr_number(pr_number) + miss = self.env["missing.pull.request"].search( + [ + ("repo_id", "=", repo.id), + ("pr_id", "=", pr.id), + ("target_version_id", "=", target_version_id), + ] + ) + if not miss: + miss = self.env["missing.pull.request"].create( + { + "repo_id": repo.id, + "pr_id": pr.id, + "target_version_id": target_version_id, + "missing_commits": "\n".join( + pr_info["missing_commits"] + ), + } + ) + return res diff --git a/module_info_migration/models/project_project.py b/module_info_migration/models/project_project.py new file mode 100644 index 0000000..4e4d68b --- /dev/null +++ b/module_info_migration/models/project_project.py @@ -0,0 +1,21 @@ +# Copyright 2025 Akretion (https://www.akretion.com). +# @author Sébastien BEAU +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import api, fields, models + + +class ProjectProject(models.Model): + _inherit = "project.project" + + is_migration_project = fields.Boolean( + compute="_compute_is_migration_project", + store=True, + ) + + @api.depends("partner_id.migration_project_id") + def _compute_is_migration_project(self): + for record in self: + record.is_migration_project = ( + record == record.partner_id.migration_project_id + ) diff --git a/module_info_migration/models/project_task.py b/module_info_migration/models/project_task.py index 4997f36..a3f635b 100644 --- a/module_info_migration/models/project_task.py +++ b/module_info_migration/models/project_task.py @@ -4,4 +4,9 @@ class ProjectTask(models.Model): _inherit = "project.task" - module_partner_ids = fields.Many2many("module.partner", string="Modules") + module_partner_ids = fields.Many2many( + "module.partner", string="Modules", domain="[('partner_id', '=', partner_id)]" + ) + is_migration_project = fields.Boolean( + related="project_id.is_migration_project", + ) diff --git a/module_info_migration/models/pull_request.py b/module_info_migration/models/pull_request.py new file mode 100644 index 0000000..becb6a8 --- /dev/null +++ b/module_info_migration/models/pull_request.py @@ -0,0 +1,12 @@ +# Copyright 2025 Akretion (https://www.akretion.com). +# @author Sébastien BEAU +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + + +from odoo import fields, models + + +class PullRequest(models.Model): + _inherit = "pull.request" + + missing_pr_ids = fields.One2many("missing.pull.request", "pr_id", "Missing Pr") diff --git a/module_info_migration/models/res_partner.py b/module_info_migration/models/res_partner.py index 60e49c1..d5ce260 100644 --- a/module_info_migration/models/res_partner.py +++ b/module_info_migration/models/res_partner.py @@ -4,4 +4,38 @@ class ResPartner(models.Model): _inherit = "res.partner" - target_odoo_version_id = fields.Many2one("odoo.version", string="Target version") + target_odoo_version_id = fields.Many2one( + "odoo.version", + string="Target version", + ) + migration_project_id = fields.Many2one( + "project.project", + string="Migration Project", + domain="[('partner_id', '=', id)]", + ) + migrated_module_nbr = fields.Integer( + compute="_compute_migrated_module_nbr", + ) + + def _compute_migrated_module_nbr(self): + for record in self: + if record.target_odoo_version_id: + record.migrated_module_nbr = self.env["module.partner"].search_count( + [ + ("migration_status", "=", "done"), + ("partner_id", "=", record.id), + ] + ) + else: + record.migrated_module_nbr = 0 + + def get_action_migration_tree(self): + self.ensure_one() + return { + "type": "ir.actions.act_window", + "res_model": "module.partner", + "name": f"Migration {self.name}", + "views": [], + "view_mode": "tree,form", + "domain": [["partner_id", "=", self.id]], + } diff --git a/module_info_migration/security/ir.model.access.csv b/module_info_migration/security/ir.model.access.csv index 63ea004..def53d2 100644 --- a/module_info_migration/security/ir.model.access.csv +++ b/module_info_migration/security/ir.model.access.csv @@ -1,2 +1,3 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink access_module_module_task_creator,full access module.task.creator,model_module_task_creator,base.group_user,1,1,1,1 +access_missing_pull_request,full access missing.pull.request,model_missing_pull_request,base.group_user,1,1,1,1 diff --git a/module_info_migration/static/description/index.html b/module_info_migration/static/description/index.html index 1fe6c4e..3afb4ee 100644 --- a/module_info_migration/static/description/index.html +++ b/module_info_migration/static/description/index.html @@ -3,15 +3,16 @@ -Module Info Migration +README.rst -
-

Module Info Migration

+
+ + +Odoo Community Association + +
+

Module Info Migration

-

Beta License: AGPL-3 akretion/partner-module-information

+

Beta License: AGPL-3 akretion/partner-module-information

Allow to indicate on which version you desired to migrate a partner’s project and show information about the work still to do for migrating the modules

Table of contents

@@ -385,15 +391,15 @@

Module Info Migration

-

Configuration

+

Configuration

Indicate in which version you want to migrate the project on partner’s formmodule_info_partnermodule_info_partnermodule_info_partner

-

Known issues / Roadmap

+

Known issues / Roadmap

This module is very experimental and will probably evolve. It is just a prototype, everything is still to do!

-

Bug Tracker

+

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 to smash it by providing a detailed and welcomed @@ -401,19 +407,20 @@

Bug Tracker

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

-

Credits

+

Credits

-

Authors

+

Authors

  • Akretion
-

Maintainers

+

Maintainers

This module is part of the akretion/partner-module-information project on GitHub.

You are welcome to contribute.

+
diff --git a/module_info_migration/views/missing_pull_request_view.xml b/module_info_migration/views/missing_pull_request_view.xml new file mode 100644 index 0000000..7b0ceff --- /dev/null +++ b/module_info_migration/views/missing_pull_request_view.xml @@ -0,0 +1,67 @@ + + + + + missing.pull.request + + + + + + + + + + + + + + + + missing.pull.request + +
+ + + + + + + + + + +
+ + + missing.pull.request + + + + + + + + + + + + + + Missing Commit Pull Request + ir.actions.act_window + missing.pull.request + tree,form + + [] + {} + + + + +
diff --git a/module_info_migration/views/module_partner.xml b/module_info_migration/views/module_partner.xml index 1cd6489..b44517e 100644 --- a/module_info_migration/views/module_partner.xml +++ b/module_info_migration/views/module_partner.xml @@ -1,12 +1,59 @@ + + module.partner + + +
+ +
+ + + + + + + + + + + +