From 325ab9a6113a86dd576942baf7cf9ef5008e544d Mon Sep 17 00:00:00 2001 From: Julien - Le Filament <julien@le-filament.com> Date: Wed, 16 Apr 2025 11:00:41 +0200 Subject: [PATCH] [UPD] pre commit --- .gitignore | 89 ++++++++ .pre-commit-config.yaml | 123 +++++++++++ .pylintrc | 123 +++++++++++ .pylintrc-mandatory | 98 +++++++++ .ruff.toml | 30 +++ README.rst | 52 ++--- __init__.py | 10 +- __manifest__.py | 38 ++-- eslint.config.cjs | 202 ++++++++++++++++++ models/__init__.py | 6 +- .../sharepoint_mixin.cpython-312.pyc | Bin 7100 -> 7097 bytes models/res_config_settings.py | 8 +- models/res_partner.py | 17 +- models/sharepoint_mixin.py | 44 ++-- prettier.config.cjs | 14 ++ security/ir.model.access.csv | 4 +- views/res_config_settings.xml | 64 +++--- views/res_partner_views.xml | 48 ++--- 18 files changed, 832 insertions(+), 138 deletions(-) create mode 100644 .gitignore create mode 100644 .pre-commit-config.yaml create mode 100644 .pylintrc create mode 100644 .pylintrc-mandatory create mode 100644 .ruff.toml create mode 100644 eslint.config.cjs create mode 100644 prettier.config.cjs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..109270f --- /dev/null +++ b/.gitignore @@ -0,0 +1,89 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +/.venv +/.pytest_cache +/.ruff_cache + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +bin/ +build/ +develop-eggs/ +dist/ +eggs/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg +*.eggs +.copier-answers.yml + +# Windows installers +*.msi + +# Debian packages +*.deb + +# Redhat packages +*.rpm + +# MacOS packages +*.dmg +*.pkg + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.cache +nosetests.xml +coverage.xml + +# Translations +*.mo + +# Pycharm +.idea + +# Eclipse +.settings + +# Visual Studio cache/options directory +.vs/ +.vscode + +# OSX Files +.DS_Store + +# Django stuff: +*.log + +# Mr Developer +.mr.developer.cfg +.project +.pydevproject + +# Rope +.ropeproject + +# Sphinx documentation +docs/_build/ + +# Backup files +*~ +*.swp + +# OCA rules +!static/lib/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..207e4c9 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,123 @@ +exclude: | + (?x) + # NOT INSTALLABLE ADDONS + # END NOT INSTALLABLE ADDONS + # 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/|^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) + /static/(src/)?lib/| + # Repos using Sphinx to generate docs don't need prettying + ^docs/_templates/.*\.html$| + # Don't bother non-technical authors with formatting issues in docs + readme/.*\.(rst|md)$| + # Ignore build and dist directories in addons + /build/|/dist/| + # Ignore test files in addons + /tests/samples/.*| + # You don't usually want a bot to modify your legal texts + (LICENSE.*|COPYING.*) +default_language_version: + python: python3 + node: "22.9.0" +repos: + - repo: local + hooks: + # These files are most likely copier diff rejection junks; if found, + # review them manually, fix the problem (if needed) and remove them + - id: forbidden-files + name: forbidden files + entry: found forbidden files; remove them + language: fail + files: "\\.rej$" + - id: en-po-files + name: en.po files cannot exist + entry: found a en.po file + language: fail + files: '[a-zA-Z0-9_]*/i18n/en\.po$' + - repo: https://github.com/oca/maintainer-tools + rev: bf9ecb9938b6a5deca0ff3d870fbd3f33341fded + hooks: + # update the NOT INSTALLABLE ADDONS section above + - id: oca-update-pre-commit-excluded-addons + - id: oca-fix-manifest-website + args: ["https://le-filament.com"] + - repo: https://github.com/OCA/odoo-pre-commit-hooks + rev: v0.0.33 + hooks: + - id: oca-checks-odoo-module + - id: oca-checks-po + 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@3.3.3" + - "@prettier/plugin-xml@3.4.1" + - repo: local + hooks: + - id: eslint + name: eslint + entry: eslint + args: + - --color + - --fix + verbose: true + types: [javascript] + language: node + additional_dependencies: + - "eslint@9.12.0" + - "eslint-plugin-jsdoc@50.3.1" + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.6.0 + hooks: + - id: trailing-whitespace + # exclude autogenerated files + exclude: /README\.rst$|\.pot?$ + - id: end-of-file-fixer + # exclude autogenerated files + exclude: /README\.rst$|\.pot?$ + - id: debug-statements + - id: fix-encoding-pragma + args: ["--remove"] + - id: check-case-conflict + - id: check-docstring-first + - id: check-executables-have-shebangs + - id: check-merge-conflict + # exclude files where underlines are not distinguishable from merge conflicts + exclude: /README\.rst$|^docs/.*\.rst$ + - id: check-symlinks + - id: check-xml + - id: mixed-line-ending + args: ["--fix=lf"] + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.6.8 + hooks: + - id: ruff + args: [--fix, --exit-non-zero-on-fix] + - id: ruff-format + - repo: https://github.com/OCA/pylint-odoo + rev: v9.1.3 + hooks: + - id: pylint_odoo + name: pylint with optional checks + args: + - --rcfile=.pylintrc + - --exit-zero + verbose: true + - id: pylint_odoo + args: + - --rcfile=.pylintrc-mandatory diff --git a/.pylintrc b/.pylintrc new file mode 100644 index 0000000..b855a92 --- /dev/null +++ b/.pylintrc @@ -0,0 +1,123 @@ + + +[MASTER] +load-plugins=pylint_odoo +score=n + +[ODOOLINT] +readme-template-url="https://github.com/OCA/maintainer-tools/blob/master/template/module/README.rst" +manifest-required-authors=Le Filament +manifest-required-keys=license +manifest-deprecated-keys=description,active +license-allowed=AGPL-3,GPL-2,GPL-2 or any later version,GPL-3,GPL-3 or any later version,LGPL-3 +valid-odoo-versions=18.0 + +[MESSAGES CONTROL] +disable=all + +# This .pylintrc contains optional AND mandatory checks and is meant to be +# loaded in an IDE to have it check everything, in the hope this will make +# optional checks more visible to contributors who otherwise never look at a +# green travis to see optional checks that failed. +# .pylintrc-mandatory containing only mandatory checks is used the pre-commit +# config as a blocking check. + +enable=anomalous-backslash-in-string, + api-one-deprecated, + api-one-multi-together, + 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, + license-allowed, + manifest-author-string, + manifest-deprecated-key, + manifest-required-author, + manifest-required-key, + manifest-version-format, + method-compute, + 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, + 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, + 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, + redefined-builtin, + too-complex, + unnecessary-utf8-coding-comment + + +[REPORTS] +msg-template={path}:{line}: [{msg_id}({symbol}), {obj}] {msg} +output-format=colorized +reports=no diff --git a/.pylintrc-mandatory b/.pylintrc-mandatory new file mode 100644 index 0000000..f945051 --- /dev/null +++ b/.pylintrc-mandatory @@ -0,0 +1,98 @@ + +[MASTER] +load-plugins=pylint_odoo +score=n + +[ODOOLINT] +readme-template-url="https://github.com/OCA/maintainer-tools/blob/master/template/module/README.rst" +manifest-required-authors=Le Filament +manifest-required-keys=license +manifest-deprecated-keys=description,active +license-allowed=AGPL-3,GPL-2,GPL-2 or any later version,GPL-3,GPL-3 or any later version,LGPL-3 +valid-odoo-versions=18.0 + +[MESSAGES CONTROL] +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, + license-allowed, + manifest-author-string, + manifest-deprecated-key, + manifest-required-author, + manifest-required-key, + manifest-version-format, + method-compute, + 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, + 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] +msg-template={path}:{line}: [{msg_id}({symbol}), {obj}] {msg} +output-format=colorized +reports=no diff --git a/.ruff.toml b/.ruff.toml new file mode 100644 index 0000000..0f1e35f --- /dev/null +++ b/.ruff.toml @@ -0,0 +1,30 @@ + +target-version = "py310" +fix = true + +[lint] +extend-select = [ + "B", + "C90", + "E501", # line too long (default 88) + "I", # isort + "UP", # pyupgrade +] +exclude = ["setup/*"] + +[format] +exclude = ["setup/*"] + +[lint.per-file-ignores] +"__init__.py" = ["F401", "I001"] # ignore unused and unsorted imports in __init__.py +"__manifest__.py" = ["B018"] # useless expression + +[lint.isort] +section-order = ["future", "standard-library", "third-party", "odoo", "odoo-addons", "first-party", "local-folder"] + +[lint.isort.sections] +"odoo" = ["odoo"] +"odoo-addons" = ["odoo.addons"] + +[lint.mccabe] +max-complexity = 16 diff --git a/README.rst b/README.rst index b304a63..ea18b8f 100644 --- a/README.rst +++ b/README.rst @@ -1,26 +1,26 @@ -.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg - :target: http://www.gnu.org/licenses/agpl - :alt: License: AGPL-3 - - -========================= -CG SCOP - SIOF sharepoint -========================= - -Ce module permet de creer un repo sharepoint pour toute scop - - -Credits -======= - -Funders -------- - -The development of this module has been financially supported by: - - Confédération Générale des SCOP (https://www.les-scop.coop) - - -Contributors ------------- -* Benjamin <benjamin@le-filament.com> +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :target: http://www.gnu.org/licenses/agpl + :alt: License: AGPL-3 + + +========================= +CG SCOP - SIOF sharepoint +========================= + +Ce module permet de creer un repo sharepoint pour toute scop + + +Credits +======= + +Funders +------- + +The development of this module has been financially supported by: + + Confédération Générale des SCOP (https://www.les-scop.coop) + + +Contributors +------------ +* Benjamin <benjamin@le-filament.com> diff --git a/__init__.py b/__init__.py index 7fc870d..48e1758 100644 --- a/__init__.py +++ b/__init__.py @@ -1,5 +1,5 @@ -# © 2020 Le Filament (<https://www.le-filament.com>) -# © 2020 Confédération Générale des Scop (<https://www.les-scop.coop>) -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - -from . import models +# © 2020 Le Filament (<https://www.le-filament.com>) +# © 2020 Confédération Générale des Scop (<https://www.les-scop.coop>) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from . import models diff --git a/__manifest__.py b/__manifest__.py index 9aa08a8..b86431d 100644 --- a/__manifest__.py +++ b/__manifest__.py @@ -1,19 +1,19 @@ -# © 2024 Le Filament (<https://www.le-filament.com>) -# © 2024 Confédération Générale des Scop (<https://www.les-scop.coop>) -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -{ - "name": "CG SCOP - Utilisation de SharepointAPI MsGraph", - "summary": "SIOF Sharepoint", - "author": "Le Filament, Confédération Générale des Scop", - "version": "18.0.1.0.0", - "license": "AGPL-3", - "depends": [], - "data": [ - # security - # "security/ir.model.access.csv", - # views - "views/res_partner_views.xml", - "views/res_config_settings.xml" - ], - "external_dependencies": {"python": ["msal"]}, -} +# © 2024 Le Filament (<https://www.le-filament.com>) +# © 2024 Confédération Générale des Scop (<https://www.les-scop.coop>) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +{ + "name": "CG SCOP - Utilisation de SharepointAPI MsGraph", + "summary": "SIOF Sharepoint", + "author": "Le Filament, Confédération Générale des Scop", + "version": "18.0.1.0.0", + "license": "AGPL-3", + "depends": [], + "data": [ + # security + # "security/ir.model.access.csv", + # views + "views/res_partner_views.xml", + "views/res_config_settings.xml", + ], + "external_dependencies": {"python": ["msal"]}, +} diff --git a/eslint.config.cjs b/eslint.config.cjs new file mode 100644 index 0000000..0d5731f --- /dev/null +++ b/eslint.config.cjs @@ -0,0 +1,202 @@ +jsdoc = require("eslint-plugin-jsdoc"); + +const config = [{ + plugins: { + jsdoc, + }, + + languageOptions: { + globals: { + _: "readonly", + $: "readonly", + fuzzy: "readonly", + jQuery: "readonly", + moment: "readonly", + odoo: "readonly", + openerp: "readonly", + owl: "readonly", + luxon: "readonly", + }, + + ecmaVersion: 2024, + sourceType: "script", + }, + + rules: { + "accessor-pairs": "warn", + "array-callback-return": "warn", + "callback-return": "warn", + "capitalized-comments": ["warn", "always", { + ignoreConsecutiveComments: true, + ignoreInlineComments: true, + }], + complexity: ["warn", 15], + "constructor-super": "warn", + "dot-notation": "warn", + eqeqeq: "warn", + "global-require": "warn", + "handle-callback-err": "warn", + "id-blacklist": "warn", + "id-match": "warn", + "init-declarations": "error", + "max-depth": "warn", + "max-nested-callbacks": "warn", + "max-statements-per-line": "warn", + "no-alert": "warn", + "no-array-constructor": "warn", + "no-caller": "warn", + "no-case-declarations": "warn", + "no-class-assign": "warn", + "no-cond-assign": "error", + "no-const-assign": "error", + "no-constant-condition": "warn", + "no-control-regex": "warn", + "no-debugger": "error", + "no-delete-var": "warn", + "no-div-regex": "warn", + "no-dupe-args": "error", + "no-dupe-class-members": "error", + "no-dupe-keys": "error", + "no-duplicate-case": "error", + "no-duplicate-imports": "error", + "no-else-return": "warn", + "no-empty-character-class": "warn", + "no-empty-function": "error", + "no-empty-pattern": "error", + "no-empty": "warn", + "no-eq-null": "error", + "no-eval": "error", + "no-ex-assign": "error", + "no-extend-native": "warn", + "no-extra-bind": "warn", + "no-extra-boolean-cast": "warn", + "no-extra-label": "warn", + "no-fallthrough": "warn", + "no-func-assign": "error", + "no-global-assign": "error", + "no-implicit-coercion": ["warn", { + allow: ["~"], + }], + "no-implicit-globals": "warn", + "no-implied-eval": "warn", + "no-inline-comments": "warn", + "no-inner-declarations": "warn", + "no-invalid-regexp": "warn", + "no-irregular-whitespace": "warn", + "no-iterator": "warn", + "no-label-var": "warn", + "no-labels": "warn", + "no-lone-blocks": "warn", + "no-lonely-if": "error", + "no-mixed-requires": "error", + "no-multi-str": "warn", + "no-native-reassign": "error", + "no-negated-condition": "warn", + "no-negated-in-lhs": "error", + "no-new-func": "warn", + "no-new-object": "warn", + "no-new-require": "warn", + "no-new-symbol": "warn", + "no-new-wrappers": "warn", + "no-new": "warn", + "no-obj-calls": "warn", + "no-octal-escape": "warn", + "no-octal": "warn", + "no-param-reassign": "warn", + "no-path-concat": "warn", + "no-process-env": "warn", + "no-process-exit": "warn", + "no-proto": "warn", + "no-prototype-builtins": "warn", + "no-redeclare": "warn", + "no-regex-spaces": "warn", + "no-restricted-globals": "warn", + "no-restricted-imports": "warn", + "no-restricted-modules": "warn", + "no-restricted-syntax": "warn", + "no-return-assign": "error", + "no-script-url": "warn", + "no-self-assign": "warn", + "no-self-compare": "warn", + "no-sequences": "warn", + "no-shadow-restricted-names": "warn", + "no-shadow": "warn", + "no-sparse-arrays": "warn", + "no-sync": "warn", + "no-this-before-super": "warn", + "no-throw-literal": "warn", + "no-undef-init": "warn", + "no-undef": "error", + "no-unmodified-loop-condition": "warn", + "no-unneeded-ternary": "error", + "no-unreachable": "error", + "no-unsafe-finally": "error", + "no-unused-expressions": "error", + "no-unused-labels": "error", + "no-unused-vars": "error", + "no-use-before-define": "error", + "no-useless-call": "warn", + "no-useless-computed-key": "warn", + "no-useless-concat": "warn", + "no-useless-constructor": "warn", + "no-useless-escape": "warn", + "no-useless-rename": "warn", + "no-void": "warn", + "no-with": "warn", + "operator-assignment": ["error", "always"], + "prefer-const": "warn", + radix: "warn", + "require-yield": "warn", + "sort-imports": "warn", + "spaced-comment": ["error", "always"], + strict: ["error", "function"], + "use-isnan": "error", + + "jsdoc/check-tag-names": "warn", + "jsdoc/check-types": "warn", + "jsdoc/require-param-description": "off", + "jsdoc/require-return": "off", + "jsdoc/require-return-description": "off", + "jsdoc/require-return-type": "off", + + "valid-typeof": "warn", + yoda: "warn", + }, + + settings: { + jsdoc: { + tagNamePreference: { + arg: "param", + argument: "param", + augments: "extends", + constructor: "class", + exception: "throws", + func: "function", + method: "function", + prop: "property", + return: "returns", + virtual: "abstract", + yield: "yields", + }, + preferredTypes: { + array: "Array", + bool: "Boolean", + boolean: "Boolean", + number: "Number", + object: "Object", + str: "String", + string: "String", + }, + }, + }, + +}, { + files: ["**/*.esm.js"], + + languageOptions: { + ecmaVersion: 2024, + sourceType: "module", + }, +}]; + +module.exports = config diff --git a/models/__init__.py b/models/__init__.py index 92f600f..5d2d0b3 100644 --- a/models/__init__.py +++ b/models/__init__.py @@ -1,3 +1,3 @@ -from . import sharepoint_mixin -from . import res_partner -from . import res_config_settings +from . import sharepoint_mixin +from . import res_partner +from . import res_config_settings diff --git a/models/__pycache__/sharepoint_mixin.cpython-312.pyc b/models/__pycache__/sharepoint_mixin.cpython-312.pyc index a627ff0730f249ce3a35237fefc3a17ad1a7feae..76d4b69e91487e5daf71b94db78b0edde625abc3 100644 GIT binary patch delta 132 zcmdmEzSErdG%qg~0|NttQR35dhmE|Zyo@T7xfo?Q^iopO5=(PRHfQjzVUks2WMF7u z_`t&;YPrYqqKHce=M6#g3j!7$tPiB*HX93kW@1d*tS-EViLqew6H!rS#=6bFBsMUz ks<QHb3YffJ>YI2yBcsrSwCiG87sa%`GJtqR+6)W~00R^!O8@`> delta 135 zcmdmKzQ>&RG%qg~0|NuY!-S{lwHtX&c^OqFb1}+rh8Cw5=>?@Grfg2<UBe`=!N|bS z!0>^GLDX`O<wX&f4$cRH78e98J6J!kF-XgAHW2vC#F(;KMR*SrW6|b^qN2=<4V%A9 nY+z(nXXXDCGI@>EH*rTMMxhC5*Tu9hifMgi0P%{n85kG<yagy0 diff --git a/models/res_config_settings.py b/models/res_config_settings.py index 9e99b02..564800e 100644 --- a/models/res_config_settings.py +++ b/models/res_config_settings.py @@ -1,6 +1,5 @@ # Copyright 2021- Le Filament (https://le-filament.com) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) -from datetime import datetime from odoo import fields, models @@ -28,7 +27,8 @@ class ResConfig(models.TransientModel): "siof_sharepoint.admin_sharepoint_secret_id", default="" ) res.update( - admin_sharepoint_user_id=admin_sharepoint_user_id, admin_sharepoint_secret_id=admin_sharepoint_secret_id + admin_sharepoint_user_id=admin_sharepoint_user_id, + admin_sharepoint_secret_id=admin_sharepoint_secret_id, ) return res @@ -38,10 +38,12 @@ class ResConfig(models.TransientModel): ) self.env["ir.config_parameter"].set_param( - "siof_sharepoint.admin_sharepoint_secret_id", self.admin_sharepoint_secret_id + "siof_sharepoint.admin_sharepoint_secret_id", + self.admin_sharepoint_secret_id, ) return super().set_values() + # ------------------------------------------------------ # Computed fields / Search Fields # ------------------------------------------------------ diff --git a/models/res_partner.py b/models/res_partner.py index a84fd76..c825719 100644 --- a/models/res_partner.py +++ b/models/res_partner.py @@ -11,30 +11,27 @@ class ResPartner(models.Model): @api.model_create_multi def create(self, vals_list): - partners = super().create(vals_list) for partner in partners: partner.init_sharepoint_directory() return partners def action_redirect_to_sharepoint(self): - # Action de redirection return { - 'type': 'ir.actions.act_url', - 'url': self.sharepoint_folder_url, - 'target': 'new', + "type": "ir.actions.act_url", + "url": self.sharepoint_folder_url, + "target": "new", } def action_init_sharepoint(self): - - if not self.sharepoint_folder_id: # and if self is a cooperative + if not self.sharepoint_folder_id: # and if self is a cooperative # le dossier associé n est pas créé lets go self.init_sharepoint_directory() # Action de redirection return { - 'type': 'ir.actions.act_url', - 'url': self.sharepoint_folder_url, - 'target': 'new', + "type": "ir.actions.act_url", + "url": self.sharepoint_folder_url, + "target": "new", } diff --git a/models/sharepoint_mixin.py b/models/sharepoint_mixin.py index 6001f48..91d6eb9 100644 --- a/models/sharepoint_mixin.py +++ b/models/sharepoint_mixin.py @@ -1,23 +1,26 @@ -from odoo import fields, models -from odoo.exceptions import UserError +import logging import requests from msal import ConfidentialClientApplication -import logging +from odoo import _, fields, models +from odoo.exceptions import UserError _logger = logging.getLogger(__name__) ms_graph_site_url = "https://graph.microsoft.com/v1.0/sites" root_site = "doc-erp" tenant_id = "76d9117c-fdf5-4dff-9dd2-11a06fa7cd7e" +default_timeout = 1 class SharepointMixin(models.AbstractModel): _name = "sharepoint.mixin" _description = "Mixing to create scop drive in sharepoint" - sharepoint_folder_id = fields.Char("Identifiant di dossier dans sharepoint", default=None) + sharepoint_folder_id = fields.Char( + "Identifiant di dossier dans sharepoint", default=None + ) sharepoint_folder_url = fields.Char( "Url sharepoint", default="https://cgscop.sharepoint.com/sites/doc-erp/SIOF" ) @@ -25,7 +28,10 @@ class SharepointMixin(models.AbstractModel): def create_folder(self, site_id, drive_id, folder_name, parent_path=None): # Vérifie si on crée un dossier à la racine ou dans un sous-dossier if parent_path: - url = f"{ms_graph_site_url}/{site_id}/drives/{drive_id}/root:/{parent_path}/{folder_name}" + url = ( + f"{ms_graph_site_url}/{site_id}/drives/{drive_id}" + f"/root:/{parent_path}/{folder_name}" + ) else: url = f"{ms_graph_site_url}/{site_id}/drives/{drive_id}/root/children" @@ -36,14 +42,17 @@ class SharepointMixin(models.AbstractModel): } response = requests.post( - url, headers=self.make_request_headers(self.env.user), json=data + url, + headers=self.make_request_headers(self.env.user), + json=data, + timeout=default_timeout, ) if response.status_code == 201: self.sharepoint_folder_id = response.json().get("id") self.sharepoint_folder_url = response.json().get("webUrl") else: - print(f"❌ Erreur ({response.status_code}):", response.text) + _logger.error(f"Erreur ({response.status_code}):", response.text) return None def init_sharepoint_directory(self): @@ -73,7 +82,7 @@ class SharepointMixin(models.AbstractModel): ) if not root_admin_user or not root_admin_pass: - raise UserError("Sharepoint admin credentials not configured") + raise UserError(_("Sharepoint admin credentials not configured")) app = ConfidentialClientApplication( root_admin_user, authority=authority, client_credential=root_admin_pass @@ -89,12 +98,13 @@ class SharepointMixin(models.AbstractModel): "Error acquiring authorization token. " "Check your tenantID, clientID and clientSecret." ) - raise UserError(f"{accesstoken.get("error")}\n{accesstoken.get("error_description")}") + raise UserError( + f"{accesstoken.get("error")}\n{accesstoken.get("error_description")}" + ) else: _logger.info("Token retreived from MSAL Cache....") return - def make_request_headers(self, connected_user): provider_id = connected_user.sudo().oauth_provider_id @@ -105,7 +115,7 @@ class SharepointMixin(models.AbstractModel): token = self.get_ms_graph_admin_token() return { - "Authorization": f"Bearer " + token, + "Authorization": "Bearer " + token, "Content-type": "application/json", } @@ -115,7 +125,11 @@ class SharepointMixin(models.AbstractModel): """ try: url = f"{ms_graph_site_url}/root:/sites/doc-erp" - results = requests.get(url, headers=self.make_request_headers(self.env.user)).json() + results = requests.get( + url, + headers=self.make_request_headers(self.env.user), + timeout=default_timeout, + ).json() error = results.get("error") if error: raise UserError(f"{error.get('code')}\n{error.get('message')}") @@ -130,7 +144,11 @@ class SharepointMixin(models.AbstractModel): try: url = f"{ms_graph_site_url}/{site_id}/drives" - results = requests.get(url, headers=self.make_request_headers(self.env.user)).json() + results = requests.get( + url, + headers=self.make_request_headers(self.env.user), + timeout=default_timeout, + ).json() error = results.get("error") if error: raise Exception(error.get("code", "Error")) diff --git a/prettier.config.cjs b/prettier.config.cjs new file mode 100644 index 0000000..e66cd82 --- /dev/null +++ b/prettier.config.cjs @@ -0,0 +1,14 @@ +/** @type {import('prettier').Config} */ + +const config = { + // https://github.com/prettier/prettier/issues/15388#issuecomment-1717746872 + plugins: [require.resolve("@prettier/plugin-xml")], + bracketSpacing: false, + printWidth: 88, + proseWrap: "always", + semi: true, + trailingComma: "es5", + xmlWhitespaceSensitivity: "preserve", +}; + +module.exports = config; diff --git a/security/ir.model.access.csv b/security/ir.model.access.csv index c244372..a93d20c 100644 --- a/security/ir.model.access.csv +++ b/security/ir.model.access.csv @@ -1,2 +1,2 @@ -id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink -"access_auth_oauth_provider","auth_oauth_provider all","model_auth_oauth_provider","base.group_user",1,0,0,0 \ No newline at end of file +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +"access_auth_oauth_provider","auth_oauth_provider all","model_auth_oauth_provider","base.group_user",1,0,0,0 diff --git a/views/res_config_settings.xml b/views/res_config_settings.xml index 41dab06..6474cea 100644 --- a/views/res_config_settings.xml +++ b/views/res_config_settings.xml @@ -1,36 +1,36 @@ <?xml version="1.0" encoding="utf-8" ?> <odoo> - <record id="res_config_settings_financial_contract_view_form" model="ir.ui.view"> - <field name="name">res.config.settings.view.financial.contract_form.inherit</field> - <field name="model">res.config.settings</field> - <field name="priority" eval="40" /> - <field name="inherit_id" ref="base.res_config_settings_view_form" /> - <field name="arch" type="xml"> - <xpath expr="//form" position="inside"> - <app - data-string="Administrateur sharepoint" - string="Administrateur sharepoint" - name="admin_sharepoint" - > - <block title="Administrateur sharepoint" name="admin_sharepoint"> - <setting> - <field name="admin_sharepoint_user_id" /> - </setting> - <setting> - <field name="admin_sharepoint_secret_id" /> - </setting> - </block> - </app> - </xpath> - </field> - </record> + <record id="res_config_settings_financial_contract_view_form" model="ir.ui.view"> + <field name="name">res.config.settings.view.financial.contract_form.inherit</field> + <field name="model">res.config.settings</field> + <field name="priority" eval="40" /> + <field name="inherit_id" ref="base.res_config_settings_view_form" /> + <field name="arch" type="xml"> + <xpath expr="//form" position="inside"> + <app + data-string="Administrateur sharepoint" + string="Administrateur sharepoint" + name="admin_sharepoint" + > + <block title="Administrateur sharepoint" name="admin_sharepoint"> + <setting> + <field name="admin_sharepoint_user_id" /> + </setting> + <setting> + <field name="admin_sharepoint_secret_id" /> + </setting> + </block> + </app> + </xpath> + </field> + </record> - <record id="action_admin_sharepoint_config" model="ir.actions.act_window"> - <field name="name">Settings</field> - <field name="type">ir.actions.act_window</field> - <field name="res_model">res.config.settings</field> - <field name="view_mode">form</field> - <field name="target">inline</field> - <field name="context">{'module' : 'siof_sharepoint', 'bin_size': False}</field> - </record> + <record id="action_admin_sharepoint_config" model="ir.actions.act_window"> + <field name="name">Settings</field> + <field name="type">ir.actions.act_window</field> + <field name="res_model">res.config.settings</field> + <field name="view_mode">form</field> + <field name="target">inline</field> + <field name="context">{'module' : 'siof_sharepoint', 'bin_size': False}</field> + </record> </odoo> diff --git a/views/res_partner_views.xml b/views/res_partner_views.xml index 0bb7d1e..963cefe 100644 --- a/views/res_partner_views.xml +++ b/views/res_partner_views.xml @@ -1,29 +1,27 @@ <?xml version="1.0" ?> <odoo> - <record model="ir.ui.view" id="view_partner_form_sharepoint"> - <field name="name">res.partner.form.sharepoint</field> - <field name="model">res.partner</field> - <field name="inherit_id" ref="base.view_partner_form" /> - <field name="arch" type="xml"> - <xpath expr="//notebook" position="inside"> - <page name="Sharepoint"> - <button - name="action_redirect_to_sharepoint" - string="Go to Sharepoint" - type="object" - class="btn-primary" - /> + <record model="ir.ui.view" id="view_partner_form_sharepoint"> + <field name="name">res.partner.form.sharepoint</field> + <field name="model">res.partner</field> + <field name="inherit_id" ref="base.view_partner_form" /> + <field name="arch" type="xml"> + <xpath expr="//notebook" position="inside"> + <page name="Sharepoint"> + <button + name="action_redirect_to_sharepoint" + string="Go to Sharepoint" + type="object" + class="btn-primary" + /> - - <button - name="action_init_sharepoint" - string="Init sharepoint" - type="object" - class="btn-primary" - /> - - </page> - </xpath> - </field> - </record> + <button + name="action_init_sharepoint" + string="Init sharepoint" + type="object" + class="btn-primary" + /> + </page> + </xpath> + </field> + </record> </odoo> -- GitLab