From e3943c7d3137c3499a0ecb47f9e99eb26dbf3b3f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20-=20Le=20Filament?= <remi@le-filament.com>
Date: Thu, 28 Apr 2022 16:27:51 +0200
Subject: [PATCH] [IMP] pre-commit

---
 .editorconfig                   |  20 +
 .eslintrc.yml                   | 187 +++++++++
 .flake8                         |  12 +
 .gitignore                      |  75 ++++
 .isort.cfg                      |  13 +
 .pre-commit-config.yaml         | 127 +++++++
 .prettierrc.yml                 |   8 +
 .pylintrc                       |  87 +++++
 .pylintrc-mandatory             |  64 ++++
 LICENSE                         |   0
 README.rst                      |   1 -
 __init__.py                     |   2 +-
 __manifest__.py                 |  26 +-
 models/__init__.py              |   2 +-
 models/account_invoice.py       |  74 ++--
 models/lefilament_alfresco.py   |  74 ++--
 models/project.py               | 651 +++++++++++++++++++-------------
 models/project_task.py          | 111 +++---
 security/ir.model.access.csv    |   2 +-
 static/description/icon.png     | Bin
 views/account_invoice_views.xml |   8 +-
 views/project_views.xml         | 219 +++++++----
 22 files changed, 1309 insertions(+), 454 deletions(-)
 create mode 100644 .editorconfig
 create mode 100644 .eslintrc.yml
 create mode 100644 .flake8
 create mode 100644 .gitignore
 create mode 100644 .isort.cfg
 create mode 100644 .pre-commit-config.yaml
 create mode 100644 .prettierrc.yml
 create mode 100644 .pylintrc
 create mode 100644 .pylintrc-mandatory
 mode change 100755 => 100644 LICENSE
 mode change 100755 => 100644 README.rst
 mode change 100755 => 100644 __init__.py
 mode change 100755 => 100644 __manifest__.py
 mode change 100755 => 100644 models/__init__.py
 mode change 100755 => 100644 models/project.py
 mode change 100755 => 100644 models/project_task.py
 mode change 100755 => 100644 security/ir.model.access.csv
 mode change 100755 => 100644 static/description/icon.png
 mode change 100755 => 100644 views/project_views.xml

diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..bfd7ac5
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,20 @@
+# Configuration for known file extensions
+[*.{css,js,json,less,md,py,rst,sass,scss,xml,yaml,yml}]
+charset = utf-8
+end_of_line = lf
+indent_size = 4
+indent_style = space
+insert_final_newline = true
+trim_trailing_whitespace = true
+
+[*.{json,yml,yaml,rst,md}]
+indent_size = 2
+
+# Do not configure editor for libs and autogenerated content
+[{*/static/{lib,src/lib}/**,*/static/description/index.html,*/readme/../README.rst}]
+charset = unset
+end_of_line = unset
+indent_size = unset
+indent_style = unset
+insert_final_newline = false
+trim_trailing_whitespace = false
diff --git a/.eslintrc.yml b/.eslintrc.yml
new file mode 100644
index 0000000..d4cc423
--- /dev/null
+++ b/.eslintrc.yml
@@ -0,0 +1,187 @@
+env:
+  browser: true
+  es6: true
+
+# See https://github.com/OCA/odoo-community.org/issues/37#issuecomment-470686449
+parserOptions:
+  ecmaVersion: 2017
+
+overrides:
+  - files:
+      - "**/*.esm.js"
+    parserOptions:
+      sourceType: module
+
+# Globals available in Odoo that shouldn't produce errorings
+globals:
+  _: readonly
+  $: readonly
+  fuzzy: readonly
+  jQuery: readonly
+  moment: readonly
+  odoo: readonly
+  openerp: readonly
+  owl: readonly
+
+# Styling is handled by Prettier, so we only need to enable AST rules;
+# see https://github.com/OCA/maintainer-quality-tools/pull/618#issuecomment-558576890
+rules:
+  accessor-pairs: warn
+  array-callback-return: warn
+  callback-return: warn
+  capitalized-comments:
+    - warn
+    - always
+    - ignoreConsecutiveComments: true
+      ignoreInlineComments: true
+  complexity:
+    - warn
+    - 15
+  constructor-super: warn
+  dot-notation: warn
+  eqeqeq: warn
+  global-require: warn
+  handle-callback-err: warn
+  id-blacklist: warn
+  id-match: warn
+  init-declarations: error
+  max-depth: warn
+  max-nested-callbacks: warn
+  max-statements-per-line: warn
+  no-alert: warn
+  no-array-constructor: warn
+  no-caller: warn
+  no-case-declarations: warn
+  no-class-assign: warn
+  no-cond-assign: error
+  no-const-assign: error
+  no-constant-condition: warn
+  no-control-regex: warn
+  no-debugger: error
+  no-delete-var: warn
+  no-div-regex: warn
+  no-dupe-args: error
+  no-dupe-class-members: error
+  no-dupe-keys: error
+  no-duplicate-case: error
+  no-duplicate-imports: error
+  no-else-return: warn
+  no-empty-character-class: warn
+  no-empty-function: error
+  no-empty-pattern: error
+  no-empty: warn
+  no-eq-null: error
+  no-eval: error
+  no-ex-assign: error
+  no-extend-native: warn
+  no-extra-bind: warn
+  no-extra-boolean-cast: warn
+  no-extra-label: warn
+  no-fallthrough: warn
+  no-func-assign: error
+  no-global-assign: error
+  no-implicit-coercion:
+    - warn
+    - allow: ["~"]
+  no-implicit-globals: warn
+  no-implied-eval: warn
+  no-inline-comments: warn
+  no-inner-declarations: warn
+  no-invalid-regexp: warn
+  no-irregular-whitespace: warn
+  no-iterator: warn
+  no-label-var: warn
+  no-labels: warn
+  no-lone-blocks: warn
+  no-lonely-if: error
+  no-mixed-requires: error
+  no-multi-str: warn
+  no-native-reassign: error
+  no-negated-condition: warn
+  no-negated-in-lhs: error
+  no-new-func: warn
+  no-new-object: warn
+  no-new-require: warn
+  no-new-symbol: warn
+  no-new-wrappers: warn
+  no-new: warn
+  no-obj-calls: warn
+  no-octal-escape: warn
+  no-octal: warn
+  no-param-reassign: warn
+  no-path-concat: warn
+  no-process-env: warn
+  no-process-exit: warn
+  no-proto: warn
+  no-prototype-builtins: warn
+  no-redeclare: warn
+  no-regex-spaces: warn
+  no-restricted-globals: warn
+  no-restricted-imports: warn
+  no-restricted-modules: warn
+  no-restricted-syntax: warn
+  no-return-assign: error
+  no-script-url: warn
+  no-self-assign: warn
+  no-self-compare: warn
+  no-sequences: warn
+  no-shadow-restricted-names: warn
+  no-shadow: warn
+  no-sparse-arrays: warn
+  no-sync: warn
+  no-this-before-super: warn
+  no-throw-literal: warn
+  no-undef-init: warn
+  no-undef: error
+  no-unmodified-loop-condition: warn
+  no-unneeded-ternary: error
+  no-unreachable: error
+  no-unsafe-finally: error
+  no-unused-expressions: error
+  no-unused-labels: error
+  no-unused-vars: error
+  no-use-before-define: error
+  no-useless-call: warn
+  no-useless-computed-key: warn
+  no-useless-concat: warn
+  no-useless-constructor: warn
+  no-useless-escape: warn
+  no-useless-rename: warn
+  no-void: warn
+  no-with: warn
+  operator-assignment: [error, always]
+  prefer-const: warn
+  radix: warn
+  require-yield: warn
+  sort-imports: warn
+  spaced-comment: [error, always]
+  strict: [error, function]
+  use-isnan: error
+  valid-jsdoc:
+    - warn
+    - prefer:
+        arg: param
+        argument: param
+        augments: extends
+        constructor: class
+        exception: throws
+        func: function
+        method: function
+        prop: property
+        return: returns
+        virtual: abstract
+        yield: yields
+      preferType:
+        array: Array
+        bool: Boolean
+        boolean: Boolean
+        number: Number
+        object: Object
+        str: String
+        string: String
+      requireParamDescription: false
+      requireReturn: false
+      requireReturnDescription: false
+      requireReturnType: false
+  valid-typeof: warn
+  yoda: warn
diff --git a/.flake8 b/.flake8
new file mode 100644
index 0000000..e397e8e
--- /dev/null
+++ b/.flake8
@@ -0,0 +1,12 @@
+[flake8]
+max-line-length = 88
+max-complexity = 16
+# B = bugbear
+# B9 = bugbear opinionated (incl line length)
+select = C,E,F,W,B,B9
+# E203: whitespace before ':' (black behaviour)
+# E501: flake8 line length (covered by bugbear B950)
+# W503: line break before binary operator (black behaviour)
+ignore = E203,E501,W503
+per-file-ignores=
+    __init__.py:F401
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..818770f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,75 @@
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+/.venv
+/.pytest_cache
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+env/
+bin/
+build/
+develop-eggs/
+dist/
+eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+*.egg-info/
+.installed.cfg
+*.egg
+*.eggs
+
+# 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/.isort.cfg b/.isort.cfg
new file mode 100644
index 0000000..0ec187e
--- /dev/null
+++ b/.isort.cfg
@@ -0,0 +1,13 @@
+[settings]
+; see https://github.com/psf/black
+multi_line_output=3
+include_trailing_comma=True
+force_grid_wrap=0
+combine_as_imports=True
+use_parentheses=True
+line_length=88
+known_odoo=odoo
+known_odoo_addons=odoo.addons
+sections=FUTURE,STDLIB,THIRDPARTY,ODOO,ODOO_ADDONS,FIRSTPARTY,LOCALFOLDER
+default_section=THIRDPARTY
+ensure_newline_before_comments = True
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000..1c6434b
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,127 @@
+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/|
+  # 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$|
+  # You don't usually want a bot to modify your legal texts
+  (LICENSE.*|COPYING.*)
+default_language_version:
+  python: python3
+  node: "14.13.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$"
+  - repo: https://github.com/oca/maintainer-tools
+    rev: ab1d7f6
+    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/myint/autoflake
+    rev: v1.4
+    hooks:
+      - id: autoflake
+        args:
+          - --expand-star-imports
+          - --ignore-init-module-imports
+          - --in-place
+          - --remove-all-unused-imports
+          - --remove-duplicate-keys
+          - --remove-unused-variables
+  - repo: https://github.com/psf/black
+    rev: 20.8b1
+    hooks:
+      - id: black
+  - repo: https://github.com/pre-commit/mirrors-prettier
+    rev: v2.1.2
+    hooks:
+      - id: prettier
+        name: prettier (with plugin-xml)
+        additional_dependencies:
+          - "prettier@2.1.2"
+          - "@prettier/plugin-xml@0.12.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: v7.8.1
+    hooks:
+      - id: eslint
+        verbose: true
+        args:
+          - --color
+          - --fix
+  - repo: https://github.com/pre-commit/pre-commit-hooks
+    rev: v3.2.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/asottile/pyupgrade
+    rev: v2.7.2
+    hooks:
+      - id: pyupgrade
+        args: ["--keep-percent-format"]
+  - repo: https://github.com/PyCQA/isort
+    rev: 5.5.1
+    hooks:
+      - id: isort
+        name: isort except __init__.py
+        args:
+          - --settings=.
+        exclude: /__init__\.py$
+  - repo: https://gitlab.com/PyCQA/flake8
+    rev: 3.8.3
+    hooks:
+      - id: flake8
+        name: flake8
+        additional_dependencies: ["flake8-bugbear==20.1.4"]
+  - repo: https://github.com/PyCQA/pylint
+    rev: pylint-2.5.3
+    hooks:
+      - id: pylint
+        name: pylint with optional checks
+        args:
+          - --rcfile=.pylintrc
+          - --exit-zero
+        verbose: true
+        additional_dependencies: &pylint_deps
+          - pylint-odoo==3.5.0
+      - id: pylint
+        name: pylint with mandatory checks
+        args:
+          - --rcfile=.pylintrc-mandatory
+        additional_dependencies: *pylint_deps
diff --git a/.prettierrc.yml b/.prettierrc.yml
new file mode 100644
index 0000000..5b6d4b3
--- /dev/null
+++ b/.prettierrc.yml
@@ -0,0 +1,8 @@
+# Defaults for all prettier-supported languages.
+# Prettier will complete this with settings from .editorconfig file.
+bracketSpacing: false
+printWidth: 88
+proseWrap: always
+semi: true
+trailingComma: "es5"
+xmlWhitespaceSensitivity: "strict"
diff --git a/.pylintrc b/.pylintrc
new file mode 100644
index 0000000..30c91fa
--- /dev/null
+++ b/.pylintrc
@@ -0,0 +1,87 @@
+[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=12.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,
+    # 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,
+    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..e37fa65
--- /dev/null
+++ b/.pylintrc-mandatory
@@ -0,0 +1,64 @@
+[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=12.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
+
+[REPORTS]
+msg-template={path}:{line}: [{msg_id}({symbol}), {obj}] {msg}
+output-format=colorized
+reports=no
diff --git a/LICENSE b/LICENSE
old mode 100755
new mode 100644
diff --git a/README.rst b/README.rst
old mode 100755
new mode 100644
index 81e27ee..550be66
--- a/README.rst
+++ b/README.rst
@@ -33,4 +33,3 @@ Maintainer
    :target: https://le-filament.com
 
 This module is maintained by Le Filament
-
diff --git a/__init__.py b/__init__.py
old mode 100755
new mode 100644
index 59fb482..06b0d57
--- a/__init__.py
+++ b/__init__.py
@@ -1,4 +1,4 @@
 # Copyright 2020 Le Filament (<http://www.le-filament.com>)
 # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
 
-from . import models
\ No newline at end of file
+from . import models
diff --git a/__manifest__.py b/__manifest__.py
old mode 100755
new mode 100644
index 66da64d..620d246
--- a/__manifest__.py
+++ b/__manifest__.py
@@ -1,16 +1,14 @@
 {
-    'name': "ADEFPAT - Gestion des avenants",
-    'summary': """Gestion des avenants""",
-    'author': "Le Filament",
-    'website': "https://www.le-filament.com",
-    'version': '12.0.1.0.1',
-    'license': "AGPL-3",
-    'depends': [
-        'adefpat_project', 'adefpat_alfresco_generation', 'adefpat_account'],
-    'data': [
-        'security/ir.model.access.csv',
-        'views/account_invoice_views.xml',
-        'views/project_views.xml',
+    "name": "ADEFPAT - Gestion des avenants",
+    "summary": """Gestion des avenants""",
+    "author": "Le Filament",
+    "website": "https://www.le-filament.com",
+    "version": "12.0.1.0.1",
+    "license": "AGPL-3",
+    "depends": ["adefpat_project", "adefpat_alfresco_generation", "adefpat_account"],
+    "data": [
+        "security/ir.model.access.csv",
+        "views/account_invoice_views.xml",
+        "views/project_views.xml",
     ],
-
-}
\ No newline at end of file
+}
diff --git a/models/__init__.py b/models/__init__.py
old mode 100755
new mode 100644
index 683bf62..d611a8c
--- a/models/__init__.py
+++ b/models/__init__.py
@@ -3,4 +3,4 @@
 
 from . import project
 from . import account_invoice
-from . import lefilament_alfresco
\ No newline at end of file
+from . import lefilament_alfresco
diff --git a/models/account_invoice.py b/models/account_invoice.py
index 1fb667a..47e9943 100644
--- a/models/account_invoice.py
+++ b/models/account_invoice.py
@@ -2,12 +2,13 @@
 # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
 
 import base64
-from odoo import fields, models, api
+
+from odoo import _, api, fields, models
 from odoo.exceptions import UserError
 
 
 class AccountInvoice(models.Model):
-    _inherit = 'account.invoice'
+    _inherit = "account.invoice"
 
     # ------------------------------------------------------
     # Fields declaration
@@ -43,46 +44,60 @@ class AccountInvoice(models.Model):
     # ------------------------------------------------------
     @api.multi
     def generate_alfresco_file(self):
+        """
+        Ajoute un fichier sur la GED Alfresco
+        @return: fonction get_partner_files() de res.partner
+        """
         if self.is_avenant:
-            """
-                Ajoute un fichier sur la GED Alfresco
-                @return: fonction get_partner_files() de res.partner
-            """
             # Get proof folder nodeRef
-            backend = self.env['cmis.backend'].search([], limit=1)
+            backend = self.env["cmis.backend"].search([], limit=1)
             # Si la facture a déjà été créée, ouvrir dans Alfresco
             if self.alfresco_file:
-                prop = backend.get_cmis_repository().getFolder(
-                    self.alfresco_file).getProperties()
+                prop = (
+                    backend.get_cmis_repository()
+                    .getFolder(self.alfresco_file)
+                    .getProperties()
+                )
                 url = backend.get_content_details_url_from_props(prop)
-            # Sinon, la créer, puis la stocker ainsi que les documents liées à la facture dans Alfresco
+            # Sinon, la créer, puis la stocker ainsi que les documents liées à la
+            # facture dans Alfresco
             else:
                 project_folder = self.project_id.cmis_folder
                 self.cmis_folder = project_folder
 
                 if not project_folder:
-                    raise UserError("Le dossier du projet n'est pas configuré")
+                    raise UserError(_("Le dossier du projet n'est pas configuré"))
 
                 # Get Mimetype
-                attachment = self.env.ref('account.account_invoices').retrieve_attachment(self)
+                attachment = self.env.ref(
+                    "account.account_invoices"
+                ).retrieve_attachment(self)
                 if not attachment:
                     raise UserError(
-                        "La facture n'a pas encore été générée. Imprimer la facture pour pouvoir la visualiser dans Alfresco")
+                        _(
+                            "La facture n'a pas encore été générée. "
+                            "Imprimer la facture pour pouvoir la visualiser dans Alfresco"
+                        )
+                    )
 
                 content_type = attachment.mimetype
 
-                path_proj = backend.get_cmis_repository().getFolder(
-                    project_folder).getPaths()
+                path_proj = (
+                    backend.get_cmis_repository().getFolder(project_folder).getPaths()
+                )
 
                 # Get template doc Facture
-                template_doc = self.env['adefpat.template.doc'].search([
-                    ('type_temp', '=', 'facture_av'),
-                    ('noderef_document', '=', False)])
+                template_doc = self.env["adefpat.template.doc"].search(
+                    [("type_temp", "=", "facture_av"), ("noderef_document", "=", False)]
+                )
 
                 # Get doc linked to Facture
-                template_doc_ids = self.env['adefpat.template.doc'].search([
-                    ('type_temp', '=', 'facture_av'),
-                    ('noderef_document', '!=', False)])
+                template_doc_ids = self.env["adefpat.template.doc"].search(
+                    [
+                        ("type_temp", "=", "facture_av"),
+                        ("noderef_document", "!=", False),
+                    ]
+                )
 
                 # Strore template in Alfresco
                 for template in template_doc_ids:
@@ -90,24 +105,23 @@ class AccountInvoice(models.Model):
                     self._publipostage_documents(template, keys, False)
 
                 path_n0 = path_proj + [template_doc.dossier.name]
-                path = '/'.join(path_n0)
+                path = "/".join(path_n0)
                 cmis_obj = backend.get_folder_by_path(path)
 
                 file = cmis_obj.createDocument(
                     name=attachment.name,
                     properties={},
                     contentFile=base64.b64decode(attachment.datas),
-                    contentType=content_type
+                    contentType=content_type,
                 )
-                file_id = file.getProperties().get('cmis:objectId')
+                file_id = file.getProperties().get("cmis:objectId")
                 self.alfresco_file = file.getObjectId()
-                prop = backend.get_cmis_repository().getFolder(
-                    file_id).getProperties()
+                prop = backend.get_cmis_repository().getFolder(file_id).getProperties()
                 url = backend.get_content_details_url_from_props(prop)
             return {
-                'type': 'ir.actions.act_url',
-                'url': url,
-                'target': 'new',
+                "type": "ir.actions.act_url",
+                "url": url,
+                "target": "new",
             }
         else:
-            return super(AccountInvoice, self).generate_alfresco_file()
\ No newline at end of file
+            return super(AccountInvoice, self).generate_alfresco_file()
diff --git a/models/lefilament_alfresco.py b/models/lefilament_alfresco.py
index f0d2a46..06e8a8a 100644
--- a/models/lefilament_alfresco.py
+++ b/models/lefilament_alfresco.py
@@ -1,19 +1,21 @@
 # Copyright 2021 Le Filament (<http://www.le-filament.com>)
 # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
 
-from odoo import fields, models, api
+from odoo import models
+
 
 class LeFilamentAlfresco(models.AbstractModel):
-    """ Appelle l'API alfresco et implémente les fonctions suivantes :
+    """Appelle l'API alfresco et implémente les fonctions suivantes :"""
 
-    """
-    _inherit = 'lefilament.alfresco'
+    _inherit = "lefilament.alfresco"
 
-    def _publipostage_documents_malette_avenant(self, template_doc, keys_obj=None, versionable=None):
-        url = '/alfresco/s/publipostage'
+    def _publipostage_documents_malette_avenant(
+        self, template_doc, keys_obj=None, versionable=None
+    ):
+        url = "/alfresco/s/publipostage"
 
         # Récupération du backend
-        backend_name = self._fields['cmis_folder']
+        backend_name = self._fields["cmis_folder"]
         backend = backend_name.get_backend(self.env)
         # Path du dossier projet
 
@@ -21,43 +23,61 @@ class LeFilamentAlfresco(models.AbstractModel):
         # If not parent_id, path = dossier.name
 
         path_all, dossier_id = template_doc.get_path_all()
-        if dossier_id.model_id.model == 'res.partner.porteur.project':
-            object_ids = self.env['res.partner.porteur.project'].search([
-                ('project_id', '=', self.id),
-                ('is_malette_ok', '=', False)
-            ])
+        if dossier_id.model_id.model == "res.partner.porteur.project":
+            object_ids = self.env["res.partner.porteur.project"].search(
+                [("project_id", "=", self.id), ("is_malette_ok", "=", False)]
+            )
 
             for obj in object_ids:
                 if obj.cmis_folder:
-                    parent_path = backend.get_cmis_repository().getFolder(
-                        obj.cmis_folder).getPaths()
+                    parent_path = (
+                        backend.get_cmis_repository()
+                        .getFolder(obj.cmis_folder)
+                        .getPaths()
+                    )
                     if path_all:
                         path_n0 = parent_path + [path_all]
                     else:
                         path_n0 = parent_path
-                    path = '/'.join(path_n0)
+                    path = "/".join(path_n0)
                     keys = obj.fill_data()
                     keys_obj.update(keys)
 
                     # Document PDF
-                    cmis_obj_nodeRef = backend.get_folder_by_path(path).getProperties()['alfcmis:nodeRef']
-                    mimetype = template_doc.name.split('.')[1]
-                    if mimetype == 'pdf':
+                    cmis_obj_nodeRef = backend.get_folder_by_path(path).getProperties()[
+                        "alfcmis:nodeRef"
+                    ]
+                    mimetype = template_doc.name.split(".")[1]
+                    if mimetype == "pdf":
                         # get ID document to copy
-                        id_doc = template_doc.noderef_document.replace('workspace://SpacesStore/', '')
+                        id_doc = template_doc.noderef_document.replace(
+                            "workspace://SpacesStore/", ""
+                        )
                         # Get ID to noderef Folder parent
-                        id_parent = cmis_obj_nodeRef.replace('workspace://SpacesStore/', '')
-                        uri = '/alfresco/s/slingshot/doclib/action/copy-to/node/workspace/SpacesStore/' + id_parent
-                        workspace = 'workspace://SpacesStore/' + id_doc
-                        workspace_parent = 'workspace://SpacesStore/' + id_parent
+                        id_parent = cmis_obj_nodeRef.replace(
+                            "workspace://SpacesStore/", ""
+                        )
+                        uri = (
+                            "/alfresco/s/slingshot/doclib/action/copy-to/"
+                            "node/workspace/SpacesStore/" + id_parent
+                        )
+                        workspace = "workspace://SpacesStore/" + id_doc
+                        workspace_parent = "workspace://SpacesStore/" + id_parent
                         # Copy the document and retur the objectId Created
                         nodeDoc = self.copy_document(
                             url=uri,
                             workspace=workspace,
                             workspace_parent=workspace_parent,
-                            backend=backend)
+                            backend=backend,
+                        )
                         self.update_doc_properties(template_doc, nodeDoc)
                     else:
-                        document = self.publipostage_documents(url, path, template_doc, backend, keys_obj, versionable)
-                        nodeDoc = document.json().get('nodeRef', '').replace('workspace://SpacesStore/', '')
-                        self.update_doc_properties(template_doc, nodeDoc)
\ No newline at end of file
+                        document = self.publipostage_documents(
+                            url, path, template_doc, backend, keys_obj, versionable
+                        )
+                        nodeDoc = (
+                            document.json()
+                            .get("nodeRef", "")
+                            .replace("workspace://SpacesStore/", "")
+                        )
+                        self.update_doc_properties(template_doc, nodeDoc)
diff --git a/models/project.py b/models/project.py
old mode 100755
new mode 100644
index f09d4fb..38809c6
--- a/models/project.py
+++ b/models/project.py
@@ -1,9 +1,11 @@
 # Copyright 2021 Le Filament (<http://www.le-filament.com>)
 # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
 
-from datetime import datetime, timedelta
+from datetime import timedelta
+
 import babel.dates
-from odoo import fields, api, models
+
+from odoo import _, api, fields, models
 from odoo.exceptions import UserError
 
 
@@ -12,11 +14,15 @@ class Project(models.Model):
 
     is_avenant = fields.Boolean("Avenant lancé", default=False)
     date_ca_av = fields.Date("Date de CA Avenant")
-    date_ca_av_next = fields.Date("Lendemain date de CA Avenant", compute='_compute_date_ca_av_next')
+    date_ca_av_next = fields.Date(
+        "Lendemain date de CA Avenant", compute="_compute_date_ca_av_next"
+    )
     # Champs étape "Instruction" => Onglet Dossier Avenants
     contexte_av = fields.Text("Rappel du contexte projet")
     caract_beneficiaire_av = fields.Text("Caractéristiques du bénéficiaire")
-    resultats_accompagnement = fields.Text("Résultats de l'accompagnement et besoins subsistants")
+    resultats_accompagnement = fields.Text(
+        "Résultats de l'accompagnement et besoins subsistants"
+    )
     objectifs_accompagnement_av = fields.Text("Objectifs d’accompagnement")
     besoins_beneficiaires_av = fields.Text("Besoins des bénéficiaires")
 
@@ -27,68 +33,75 @@ class Project(models.Model):
     lieu_av = fields.Text("Lieu")
     periode_realisation_av = fields.Text("Période de réalisation")
 
-    modalite_gap_av = fields.Text(
-        "Avenant - Modalités GAP")
+    modalite_gap_av = fields.Text("Avenant - Modalités GAP")
 
     # Info Budget
     nb_jours_adefpat_av = fields.Float("Nombre de jours CFD")
     cout_jour_adefpat_av = fields.Float("Coût jour CFD")
     nb_jour_theorique_tot_av = fields.Float(
-        "Nombre de jours théoriques total", 
-        compute='_compute_nb_jour_theorique_tot_av')
+        "Nombre de jours théoriques total", compute="_compute_nb_jour_theorique_tot_av"
+    )
     nb_jour_theorique_tot_global = fields.Float(
         "Nombre de jours théoriques au global",
-        compute='_compute_nb_jour_theorique_tot_global')
+        compute="_compute_nb_jour_theorique_tot_global",
+    )
     nb_jour_pratique_tot_av = fields.Float(
-        "Nombre de jours pratiques total", 
-        compute='_compute_nb_jour_pratique_tot_av')
+        "Nombre de jours pratiques total", compute="_compute_nb_jour_pratique_tot_av"
+    )
     nb_jour_tot_av = fields.Float(
-        "Nombre de jours total",
-        compute='_compute_nb_jour_tot_av',
-        store=True)
+        "Nombre de jours total", compute="_compute_nb_jour_tot_av", store=True
+    )
     nb_heure_tot_av = fields.Float(
-        "Nombre d'heures' total",
-        compute='_compute_nb_jour_tot_av',
-        store=True)
+        "Nombre d'heures' total", compute="_compute_nb_jour_tot_av", store=True
+    )
     total_cout_adefpat_av = fields.Float(
-        "Total coûts CFD", 
-        compute='_compute_total_cout_adefpat_av')
+        "Total coûts CFD", compute="_compute_total_cout_adefpat_av"
+    )
     financement_adefpat_av = fields.Float(
-        "Financement Adefpat", 
-        compute='_compute_financement_adefpat_av')
+        "Financement Adefpat", compute="_compute_financement_adefpat_av"
+    )
 
     financement_ids = fields.One2many(
-        'adefpat.project.financement',
-        'project_id',
-        domain=[('type_avenant', '=', False)],
-        string="Financements")
+        "adefpat.project.financement",
+        "project_id",
+        domain=[("type_avenant", "=", False)],
+        string="Financements",
+    )
     cout_ids = fields.One2many(
-        'adefpat.project.cout',
-        'project_id',
-        domain=[('type_avenant', '=', False)],
-        string="Coûts")
+        "adefpat.project.cout",
+        "project_id",
+        domain=[("type_avenant", "=", False)],
+        string="Coûts",
+    )
 
     financement_av_ids = fields.One2many(
-        'adefpat.project.financement',
-        'project_id',
-        domain=[('type_avenant', '=', True)],
-        string="Financements Avenants")
-    total_financement_av = fields.Float("Total autres Avenants", compute='_compute_total_financment_av')
+        "adefpat.project.financement",
+        "project_id",
+        domain=[("type_avenant", "=", True)],
+        string="Financements Avenants",
+    )
+    total_financement_av = fields.Float(
+        "Total autres Avenants", compute="_compute_total_financment_av"
+    )
     cout_av_ids = fields.One2many(
-        'adefpat.project.cout.av',
-        'project_id',
-        string="Coûts Avenants")
+        "adefpat.project.cout.av", "project_id", string="Coûts Avenants"
+    )
 
-    total_cout_av = fields.Float("Total coûts Avenants", compute='_compute_total_cout_av')
+    total_cout_av = fields.Float(
+        "Total coûts Avenants", compute="_compute_total_cout_av"
+    )
     # honoraire_intervenant = fields.Float(
     #     "Honoraires d'intervenants")
 
     total_budget_cout_av = fields.Float(
-        "Total budget coûts",
-        compute='_compute_total_budget_cout_av')
-    total_budget_financement_av = fields.Float("Total budget financements", compute='_compute_total_budget_financement_av')
+        "Total budget coûts", compute="_compute_total_budget_cout_av"
+    )
+    total_budget_financement_av = fields.Float(
+        "Total budget financements", compute="_compute_total_budget_financement_av"
+    )
     explication_financement_av = fields.Text(
-        "Explication financement porteur de projet",)
+        "Explication financement porteur de projet",
+    )
 
     # ------------------------------------------------------
     # Actions
@@ -96,112 +109,144 @@ class Project(models.Model):
     @api.multi
     def fill_avenant(self):
         for project in self:
-            project.write({
-                'is_avenant': True,
-                'contexte_av': project.contexte,
-                'caract_beneficiaire_av': project.caract_beneficiaire,
-                'objectifs_accompagnement_av': project.objectifs_accompagnement,
-                'besoins_beneficiaires_av': project.besoins_beneficiaires,
-                'contenu_formation_av': project.contenu_formation,
-                'methode_savoir_av': project.methode_savoir,
-                'travaux_intersessions_av': project.travaux_intersessions,
-                'lieu_av': project.lieu,
-                'periode_realisation_av': project.periode_realisation,
-                'modalite_gap_av': project.modalite_gap,
-                'explication_financement_av': project.explication_financement,
-                'nb_jours_adefpat_av': project.nb_jours_adefpat,
-                'cout_jour_adefpat_av': project.cout_jour_adefpat
-            })
+            project.write(
+                {
+                    "is_avenant": True,
+                    "contexte_av": project.contexte,
+                    "caract_beneficiaire_av": project.caract_beneficiaire,
+                    "objectifs_accompagnement_av": project.objectifs_accompagnement,
+                    "besoins_beneficiaires_av": project.besoins_beneficiaires,
+                    "contenu_formation_av": project.contenu_formation,
+                    "methode_savoir_av": project.methode_savoir,
+                    "travaux_intersessions_av": project.travaux_intersessions,
+                    "lieu_av": project.lieu,
+                    "periode_realisation_av": project.periode_realisation,
+                    "modalite_gap_av": project.modalite_gap,
+                    "explication_financement_av": project.explication_financement,
+                    "nb_jours_adefpat_av": project.nb_jours_adefpat,
+                    "cout_jour_adefpat_av": project.cout_jour_adefpat,
+                }
+            )
 
     def fill_data(self):
         res = super(Project, self).fill_data()
         if self.is_avenant and self.date_ca_av_next:
-            res['##date_ca_next##'] = babel.dates.format_date(date=self.date_ca_av_next, format='dd MMMM Y',
-                                                               locale=self._context.get('lang') or 'en_US')
+            res["##date_ca_next##"] = babel.dates.format_date(
+                date=self.date_ca_av_next,
+                format="dd MMMM Y",
+                locale=self._context.get("lang") or "en_US",
+            )
         return res
 
     def fill_data_av(self):
 
         parser = [
-            'name',
-            'name:NAME',
-            'date_ca_av',
-
+            "name",
+            "name:NAME",
+            "date_ca_av",
             # Entête Dossier CA
-            'name_subtitle',
-            'num_dossier',
+            "name_subtitle",
+            "num_dossier",
             # Critères dossier CA
-            'nb_activité',
-            'nb_emplois',
-            'type_beneficiaire',
-
+            "nb_activité",
+            "nb_emplois",
+            "type_beneficiaire",
             # Blocs CA
-            'contenu_formation_av',
-            'methode_savoir_av',
-            'travaux_intersessions_av',
-            'lieu_av',
-            'periode_realisation_av',
-            'explication_financement_av',
-            'modalite_gap_av',
-            'resultats_accompagnement',
-
+            "contenu_formation_av",
+            "methode_savoir_av",
+            "travaux_intersessions_av",
+            "lieu_av",
+            "periode_realisation_av",
+            "explication_financement_av",
+            "modalite_gap_av",
+            "resultats_accompagnement",
             # CDC
-            'contexte_av',
-            'caract_beneficiaire_av',
-            'historique',
-            'besoins_beneficiaires_av',
-            'objectifs_accompagnement_av',
-            'competences_requises',
-            'secteurs_requis',
-            'modalites_intervention',
-            'modalites_facturation',
-            'modalites_reponse',
-            'modalites_modif_marche',
-            'financement_adefpat_av',
-            'total_budget_financement_av',
-            'total_financement_av',
-            'nb_jours_adefpat_av',
-            'cout_jour_adefpat_av',
-            'total_cout_adefpat_av',
-            'total_budget_cout_av',
-            'total_cout_av',
-
+            "contexte_av",
+            "caract_beneficiaire_av",
+            "historique",
+            "besoins_beneficiaires_av",
+            "objectifs_accompagnement_av",
+            "competences_requises",
+            "secteurs_requis",
+            "modalites_intervention",
+            "modalites_facturation",
+            "modalites_reponse",
+            "modalites_modif_marche",
+            "financement_adefpat_av",
+            "total_budget_financement_av",
+            "total_financement_av",
+            "nb_jours_adefpat_av",
+            "cout_jour_adefpat_av",
+            "total_cout_adefpat_av",
+            "total_budget_cout_av",
+            "total_cout_av",
             # # Selection field
-            'departement',
-            'objectif_projet',
-            'secteur_crit',
-            'taille',
-            'objectif_formation',
-            'type_formation',
-            'encadrement',
-
+            "departement",
+            "objectif_projet",
+            "secteur_crit",
+            "taille",
+            "objectif_formation",
+            "type_formation",
+            "encadrement",
             # Many2one
-            ('territoire_id', ['display_name', 'street']),
-            ('elu_referent_id', ['name']),
-            ('user_id:cfd_name', ['name']),
-            ('user_id:cfd_email', ['email']),
-            ('type_convention_id', ['name']),
-
+            ("territoire_id", ["display_name", "street"]),
+            ("elu_referent_id", ["name"]),
+            ("user_id:cfd_name", ["name"]),
+            ("user_id:cfd_email", ["email"]),
+            ("type_convention_id", ["name"]),
             # One2many List
             (
-            'membre_ids:LIST_membres', {'type_data': 'LIST', 'fields': [('partner_id', ['display_name', 'function'])]}),
-            ('porteurs_projets_ids:LIST_porteurs_project',
-             {'type_data': 'LIST', 'fields': [('porteur_id', ['display_name'])]}),
-            ('financement_av_ids:LIST_financement', {'type_data': 'LIST', 'fields': [('partner_id', ['display_name'])]}),
-
-            ('porteurs_projets_ids:LIST_porteurs_adress',
-             {'type_data': 'LIST', 'fields': [('porteur_id', ['display_name', 'street', 'zip', 'city'])]}),
-            ('financement_av_ids:LIST_financement_adress',
-             {'type_data': 'LIST', 'fields': [('partner_id', ['display_name', 'street', 'zip', 'city'])]}),
-            ('od_ids:LIST_ods_adress', {'type_data': 'MULTI', 'fields': ['display_name', 'street', 'zip', 'city']}),
-
+                "membre_ids:LIST_membres",
+                {
+                    "type_data": "LIST",
+                    "fields": [("partner_id", ["display_name", "function"])],
+                },
+            ),
+            (
+                "porteurs_projets_ids:LIST_porteurs_project",
+                {"type_data": "LIST", "fields": [("porteur_id", ["display_name"])]},
+            ),
+            (
+                "financement_av_ids:LIST_financement",
+                {"type_data": "LIST", "fields": [("partner_id", ["display_name"])]},
+            ),
+            (
+                "porteurs_projets_ids:LIST_porteurs_adress",
+                {
+                    "type_data": "LIST",
+                    "fields": [
+                        ("porteur_id", ["display_name", "street", "zip", "city"])
+                    ],
+                },
+            ),
+            (
+                "financement_av_ids:LIST_financement_adress",
+                {
+                    "type_data": "LIST",
+                    "fields": [
+                        ("partner_id", ["display_name", "street", "zip", "city"])
+                    ],
+                },
+            ),
+            (
+                "od_ids:LIST_ods_adress",
+                {
+                    "type_data": "MULTI",
+                    "fields": ["display_name", "street", "zip", "city"],
+                },
+            ),
             # One2many Enum
-            ('petr_ids:petr_list', {'type_data': 'ENUM', 'fields': ['name']}),
-            ('porteurs_projets_ids:commune_list', {'type_data': 'ENUM', 'fields': ['commune']}),
-            ('cout_ids:consultants', {'type_data': 'ENUM', 'fields': [('partner_id', ['name'])]}),
-            ('od_ids:ods', {'type_data': 'ENUM', 'fields': ['name']}),
-            ('animateur_ids:animateurs', {'type_data': 'ENUM', 'fields': ['name']}),
-
+            ("petr_ids:petr_list", {"type_data": "ENUM", "fields": ["name"]}),
+            (
+                "porteurs_projets_ids:commune_list",
+                {"type_data": "ENUM", "fields": ["commune"]},
+            ),
+            (
+                "cout_ids:consultants",
+                {"type_data": "ENUM", "fields": [("partner_id", ["name"])]},
+            ),
+            ("od_ids:ods", {"type_data": "ENUM", "fields": ["name"]}),
+            ("animateur_ids:animateurs", {"type_data": "ENUM", "fields": ["name"]}),
         ]
 
         keys = self.json_build(parser)[0]
@@ -210,19 +255,27 @@ class Project(models.Model):
         # Nombre de PP eligibles
         nb_stagiaires = 0
         if self.porteurs_projets_ids:
-            nb_stagiaires = len(self.porteurs_projets_ids.filtered(lambda r: r.eligible == True))
-            keys['##nb_porteurs##'] = nb_stagiaires
+            nb_stagiaires = len(self.porteurs_projets_ids.filtered("eligible"))
+            keys["##nb_porteurs##"] = nb_stagiaires
 
         # Tableau des modules
         tab_mod = []
         for modul in self.cout_av_ids:
-            tab_par_mod = [modul.module, nb_stagiaires, modul.nb_jour_theorique, modul.nb_jour_pratiques,
-                           (7 * nb_stagiaires * modul.nb_jour_theorique), (7 * nb_stagiaires * modul.nb_jour_pratiques),
-                           ((7 * nb_stagiaires * modul.nb_jour_theorique) + (
-                                       7 * nb_stagiaires * modul.nb_jour_pratiques))]
+            tab_par_mod = [
+                modul.module,
+                nb_stagiaires,
+                modul.nb_jour_theorique,
+                modul.nb_jour_pratiques,
+                (7 * nb_stagiaires * modul.nb_jour_theorique),
+                (7 * nb_stagiaires * modul.nb_jour_pratiques),
+                (
+                    (7 * nb_stagiaires * modul.nb_jour_theorique)
+                    + (7 * nb_stagiaires * modul.nb_jour_pratiques)
+                ),
+            ]
             tab_mod.append(tab_par_mod)
 
-        keys['##TAB_MODULE_AV##'] = tab_mod
+        keys["##TAB_MODULE_AV##"] = tab_mod
 
         # Tableau des porteurs de projets
         tab_pp = []
@@ -236,20 +289,23 @@ class Project(models.Model):
             if cout.partner_id:
                 if res:
                     if cout.partner_id.name not in res:
-                        res += ', ' + cout.partner_id.name
+                        res += ", " + cout.partner_id.name
                         if cout.partner_id.email:
-                            res += ' (' + cout.partner_id.email + ')'
+                            res += " (" + cout.partner_id.email + ")"
                 else:
                     res += cout.partner_id.name
                     if cout.partner_id.email:
-                        res += ' (' + cout.partner_id.email + ')'
-        keys['##consultants_email##'] = res
+                        res += " (" + cout.partner_id.email + ")"
+        keys["##consultants_email##"] = res
 
-        keys['##TAB_PORTEURS##'] = tab_pp
+        keys["##TAB_PORTEURS##"] = tab_pp
 
         if self.date_ca_av_next:
-            keys['##date_ca_av_next##'] = babel.dates.format_date(date=self.date_ca_av_next, format='dd MMMM Y',
-                                                               locale=self._context.get('lang') or 'en_US')
+            keys["##date_ca_av_next##"] = babel.dates.format_date(
+                date=self.date_ca_av_next,
+                format="dd MMMM Y",
+                locale=self._context.get("lang") or "en_US",
+            )
         return keys
 
     @api.multi
@@ -257,20 +313,26 @@ class Project(models.Model):
         for project in self:
             if not project.cmis_folder:
                 raise UserError(
-                    "Le répertoire Projet d'Alfresco n'est pas configuré")
+                    _("Le répertoire Projet d'Alfresco n'est pas configuré")
+                )
 
             # Récupération du template de Dossier CA
-            template_docs = self.env['adefpat.template.doc'].search([
-                '&', '|', ('convention_ids', '=', False),
-                ('convention_ids', '=', project.type_convention_id.id),
-                ('type_temp', '=', 'dossier_ca_av')])
+            template_docs = self.env["adefpat.template.doc"].search(
+                [
+                    "&",
+                    "|",
+                    ("convention_ids", "=", False),
+                    ("convention_ids", "=", project.type_convention_id.id),
+                    ("type_temp", "=", "dossier_ca_av"),
+                ]
+            )
             keys = project.fill_data_av()
             for template_doc in template_docs:
                 url = project._publipostage_documents(template_doc, keys, True)
                 return {
-                    'type': 'ir.actions.act_url',
-                    'url': url,
-                    'target': 'new',
+                    "type": "ir.actions.act_url",
+                    "url": url,
+                    "target": "new",
                 }
 
     @api.multi
@@ -278,47 +340,81 @@ class Project(models.Model):
         for project in self:
             if not project.cmis_folder:
                 raise UserError(
-                    "Le répertoire Projet d'Alfresco n'est pas configuré")
+                    _("Le répertoire Projet d'Alfresco n'est pas configuré")
+                )
 
             # Fill data project
             keys = project.fill_data_av()
 
             # Récupération des conventions d'accompagnement
             # 1 par formateur
-            template_docs = self.env['adefpat.template.doc'].search([
-                '&', '|', ('convention_ids', '=', False),
-                ('convention_ids', '=', project.type_convention_id.id),
-                ('type_temp', '=', 'convention_accompagnement_av')])
+            template_docs = self.env["adefpat.template.doc"].search(
+                [
+                    "&",
+                    "|",
+                    ("convention_ids", "=", False),
+                    ("convention_ids", "=", project.type_convention_id.id),
+                    ("type_temp", "=", "convention_accompagnement_av"),
+                ]
+            )
 
             for template_doc in template_docs:
 
                 ####################################
                 # Group by consultants
                 ####################################
-                consulant_ok_ids = self.consulant_ids.filtered(lambda r: r.is_selected == True)
+                consulant_ok_ids = self.consulant_ids.filtered("is_selected")
                 for consult in consulant_ok_ids:
                     keys_obj = consult.fill_data()
                     keys.update(keys_obj)
 
-                    cout_ids = self.env['adefpat.project.cout.av'].sudo().read_group(
-                        [('project_id', '=', project.id),
-                         ('consultant_id', '=', consult.id)],
-                        ['partner_id', 'montant', 'nb_jour_theorique', 'nb_jour_pratiques'],
-                        ['partner_id'], lazy=False)
-
-                    keys['##montant##'] = cout_ids[0]['montant']
-                    keys['##nb_jour_theorique_tot_av##'] = cout_ids[0]['nb_jour_theorique']
-                    keys['##nb_jour_pratique_tot_av##'] = cout_ids[0]['nb_jour_pratiques']
-                    keys['##nb_jour_tot_av##'] = cout_ids[0]['nb_jour_pratiques'] + cout_ids[0]['nb_jour_theorique']
-                    keys['##nb_heure_tot_av##'] = (cout_ids[0]['nb_jour_pratiques'] + cout_ids[0]['nb_jour_theorique']) * 7
+                    cout_ids = (
+                        self.env["adefpat.project.cout.av"]
+                        .sudo()
+                        .read_group(
+                            [
+                                ("project_id", "=", project.id),
+                                ("consultant_id", "=", consult.id),
+                            ],
+                            [
+                                "partner_id",
+                                "montant",
+                                "nb_jour_theorique",
+                                "nb_jour_pratiques",
+                            ],
+                            ["partner_id"],
+                            lazy=False,
+                        )
+                    )
+
+                    keys["##montant##"] = cout_ids[0]["montant"]
+                    keys["##nb_jour_theorique_tot_av##"] = cout_ids[0][
+                        "nb_jour_theorique"
+                    ]
+                    keys["##nb_jour_pratique_tot_av##"] = cout_ids[0][
+                        "nb_jour_pratiques"
+                    ]
+                    keys["##nb_jour_tot_av##"] = (
+                        cout_ids[0]["nb_jour_pratiques"]
+                        + cout_ids[0]["nb_jour_theorique"]
+                    )
+                    keys["##nb_heure_tot_av##"] = (
+                        cout_ids[0]["nb_jour_pratiques"]
+                        + cout_ids[0]["nb_jour_theorique"]
+                    ) * 7
                     project._publipostage_documents(template_doc, keys, False)
 
             # Récupération des annexes de conventions d'accompagnement
             # 1 par bénéficiaire
-            template_docs = self.env['adefpat.template.doc'].search([
-                '&', '|', ('convention_ids', '=', False),
-                ('convention_ids', '=', project.type_convention_id.id),
-                ('type_temp', '=', 'annexe_convention_av')])
+            template_docs = self.env["adefpat.template.doc"].search(
+                [
+                    "&",
+                    "|",
+                    ("convention_ids", "=", False),
+                    ("convention_ids", "=", project.type_convention_id.id),
+                    ("type_temp", "=", "annexe_convention_av"),
+                ]
+            )
 
             for template_doc in template_docs:
                 for financ in project.financement_av_ids:
@@ -327,10 +423,15 @@ class Project(models.Model):
                     project._publipostage_documents(template_doc, keys, False)
 
             # Récupération des conventions d'objectif
-            template_docs = self.env['adefpat.template.doc'].search([
-                '&', '|', ('convention_ids', '=', False),
-                ('convention_ids', '=', project.type_convention_id.id),
-                ('type_temp', '=', 'convention_objectif_av')])
+            template_docs = self.env["adefpat.template.doc"].search(
+                [
+                    "&",
+                    "|",
+                    ("convention_ids", "=", False),
+                    ("convention_ids", "=", project.type_convention_id.id),
+                    ("type_temp", "=", "convention_objectif_av"),
+                ]
+            )
             for template_doc in template_docs:
                 # Get the display name of first Animateur
                 if project.animateur_ids:
@@ -347,20 +448,22 @@ class Project(models.Model):
                 project._publipostage_documents(template_doc, keys, True)
 
             # Open URL from path in alfresco
-            backend_name = self._fields['cmis_folder']
+            backend_name = self._fields["cmis_folder"]
             backend = backend_name.get_backend(project.env)
-            parent_path = backend.get_cmis_repository().getFolder(
-                project.cmis_folder).getPaths()
+            parent_path = (
+                backend.get_cmis_repository().getFolder(project.cmis_folder).getPaths()
+            )
             path_proj = parent_path + [template_doc.dossier.name]
-            path = '/'.join(path_proj)
+            path = "/".join(path_proj)
             cmis_folder = backend.get_folder_by_path(path)
-            properties = backend.get_cmis_repository().getFolder(
-                cmis_folder).getProperties()
+            properties = (
+                backend.get_cmis_repository().getFolder(cmis_folder).getProperties()
+            )
             url = backend.get_content_details_url_from_props(properties)
             return {
-                'type': 'ir.actions.act_url',
-                'url': url,
-                'target': 'new',
+                "type": "ir.actions.act_url",
+                "url": url,
+                "target": "new",
             }
 
     @api.multi
@@ -369,17 +472,26 @@ class Project(models.Model):
             if project.is_avenant:
                 if not project.cmis_folder:
                     raise UserError(
-                        "Le répertoire Projet d'Alfresco n'est pas configuré")
+                        _("Le répertoire Projet d'Alfresco n'est pas configuré")
+                    )
                 project.is_send_malette = True
                 # Récupération des template pour les malettes
-                template_docs = self.env['adefpat.template.doc'].search([
-                    '&', '&', '|', ('convention_ids', '=', False),
-                    ('convention_ids', '=', project.type_convention_id.id),
-                    ('type_temp', '=', False),
-                    ('noderef_document', '!=', False)])
+                template_docs = self.env["adefpat.template.doc"].search(
+                    [
+                        "&",
+                        "&",
+                        "|",
+                        ("convention_ids", "=", False),
+                        ("convention_ids", "=", project.type_convention_id.id),
+                        ("type_temp", "=", False),
+                        ("noderef_document", "!=", False),
+                    ]
+                )
                 keys = project.fill_data()
                 for template_doc in template_docs:
-                    project._publipostage_documents_malette_avenant(template_doc, keys, True)
+                    project._publipostage_documents_malette_avenant(
+                        template_doc, keys, True
+                    )
 
                 # Mise a jour de l'envoi malette sur les porteurs de projet
                 for porteur in project.porteurs_projets_ids:
@@ -387,15 +499,18 @@ class Project(models.Model):
                         porteur.is_malette_ok = True
 
                 # Open URL Project in Alfresco
-                backend_name = self._fields['cmis_folder']
+                backend_name = self._fields["cmis_folder"]
                 backend = backend_name.get_backend(project.env)
-                properties = backend.get_cmis_repository().getFolder(
-                    project.cmis_folder).getProperties()
+                properties = (
+                    backend.get_cmis_repository()
+                    .getFolder(project.cmis_folder)
+                    .getProperties()
+                )
                 url = backend.get_content_details_url_from_props(properties)
                 return {
-                    'type': 'ir.actions.act_url',
-                    'url': url,
-                    'target': 'new',
+                    "type": "ir.actions.act_url",
+                    "url": url,
+                    "target": "new",
                 }
             else:
                 return super(Project, self).generate_dossier_global()
@@ -411,30 +526,35 @@ class Project(models.Model):
 
                 if partner.type_structure_id:
                     # search the product corresponding to the company associated
-                    product_id = self.env['product.product'].search([('type_product', '=', 'collectivite')])
+                    product_id = self.env["product.product"].search(
+                        [("type_product", "=", "collectivite")]
+                    )
                 else:
                     # search the product corresponding to the company associated
-                    product_id = self.env['product.product'].search([('type_product', '=', 'particular')])
+                    product_id = self.env["product.product"].search(
+                        [("type_product", "=", "particular")]
+                    )
                 # If doesn't exist, create the invoice
                 if not benef.invoice_id:
                     account_invoice_id = self.create_invoice(
-                        product_id, partner, benef.montant)
-                    account_invoice_id.write({
-                        'is_avenant': True,
-                        'name': partner.name + " - avenant"})
-                    benef.write({'invoice_id': account_invoice_id.id})
+                        product_id, partner, benef.montant
+                    )
+                    account_invoice_id.write(
+                        {"is_avenant": True, "name": partner.name + " - avenant"}
+                    )
+                    benef.write({"invoice_id": account_invoice_id.id})
 
     # ------------------------------------------------------
     # Compute
     # ------------------------------------------------------
-    @api.depends('date_ca_av')
+    @api.depends("date_ca_av")
     @api.multi
     def _compute_date_ca_av_next(self):
         for project in self:
             if project.date_ca_av:
                 project.date_ca_av_next = project.date_ca_av + timedelta(days=1)
 
-    @api.depends('financement_av_ids', 'financement_av_ids.montant')
+    @api.depends("financement_av_ids", "financement_av_ids.montant")
     @api.multi
     def _compute_total_financment_av(self):
         for project in self:
@@ -443,7 +563,7 @@ class Project(models.Model):
                 total_financement += financement.montant
             project.total_financement_av = total_financement
 
-    @api.depends('cout_av_ids', 'cout_av_ids.montant')
+    @api.depends("cout_av_ids", "cout_av_ids.montant")
     @api.multi
     def _compute_total_cout_av(self):
         for project in self:
@@ -452,7 +572,7 @@ class Project(models.Model):
                 total_cout += cout.montant
             project.total_cout_av = total_cout
 
-    @api.depends('cout_av_ids', 'cout_av_ids.nb_jour_theorique')
+    @api.depends("cout_av_ids", "cout_av_ids.nb_jour_theorique")
     @api.multi
     def _compute_nb_jour_theorique_tot_av(self):
         for project in self:
@@ -461,19 +581,23 @@ class Project(models.Model):
                 total_jour += cout.nb_jour_theorique
             project.nb_jour_theorique_tot_av = total_jour
 
-    @api.depends('nb_jour_theorique_tot_av', 'nb_jour_theorique_tot')
+    @api.depends("nb_jour_theorique_tot_av", "nb_jour_theorique_tot")
     @api.multi
     def _compute_nb_jour_theorique_tot_global(self):
         for project in self:
-            project.nb_jour_theorique_tot_global = project.nb_jour_theorique_tot_av + project.nb_jour_theorique_tot
+            project.nb_jour_theorique_tot_global = (
+                project.nb_jour_theorique_tot_av + project.nb_jour_theorique_tot
+            )
 
-    @api.depends('nb_jour_plann', 'nb_jour_theorique_tot_global')
+    @api.depends("nb_jour_plann", "nb_jour_theorique_tot_global")
     @api.multi
     def _compute_nb_jour_rest(self):
         for project in self:
-            project.nb_jour_rest = project.nb_jour_theorique_tot_global - project.nb_jour_plann
+            project.nb_jour_rest = (
+                project.nb_jour_theorique_tot_global - project.nb_jour_plann
+            )
 
-    @api.depends('cout_av_ids', 'cout_av_ids.nb_jour_pratiques')
+    @api.depends("cout_av_ids", "cout_av_ids.nb_jour_pratiques")
     @api.multi
     def _compute_nb_jour_pratique_tot_av(self):
         for project in self:
@@ -482,7 +606,9 @@ class Project(models.Model):
                 total_jour += cout.nb_jour_pratiques
             project.nb_jour_pratique_tot_av = total_jour
 
-    @api.depends('cout_av_ids', 'cout_av_ids.nb_jour_theorique', 'cout_av_ids.nb_jour_pratiques')
+    @api.depends(
+        "cout_av_ids", "cout_av_ids.nb_jour_theorique", "cout_av_ids.nb_jour_pratiques"
+    )
     @api.multi
     def _compute_nb_jour_tot_av(self):
         for project in self:
@@ -492,89 +618,104 @@ class Project(models.Model):
             project.nb_jour_tot_av = total_jour
             project.nb_heure_tot_av = total_jour * 7
 
-    @api.depends('nb_jours_adefpat_av', 'cout_jour_adefpat_av')
+    @api.depends("nb_jours_adefpat_av", "cout_jour_adefpat_av")
     @api.multi
     def _compute_total_cout_adefpat_av(self):
         for project in self:
-            project.total_cout_adefpat_av = project.nb_jours_adefpat_av * project.cout_jour_adefpat_av
+            project.total_cout_adefpat_av = (
+                project.nb_jours_adefpat_av * project.cout_jour_adefpat_av
+            )
 
-    @api.depends('total_cout_adefpat_av', 'total_cout_av')
+    @api.depends("total_cout_adefpat_av", "total_cout_av")
     @api.multi
     def _compute_total_budget_cout_av(self):
         for project in self:
-            project.total_budget_cout_av = project.total_cout_adefpat_av + project.total_cout_av
+            project.total_budget_cout_av = (
+                project.total_cout_adefpat_av + project.total_cout_av
+            )
 
-    @api.depends('total_budget_cout_av', 'total_financement_av')
+    @api.depends("total_budget_cout_av", "total_financement_av")
     @api.multi
     def _compute_financement_adefpat_av(self):
         for project in self:
-            project.financement_adefpat_av = project.total_budget_cout_av - project.total_financement_av
+            project.financement_adefpat_av = (
+                project.total_budget_cout_av - project.total_financement_av
+            )
 
-    @api.depends('financement_adefpat_av', 'total_financement_av')
+    @api.depends("financement_adefpat_av", "total_financement_av")
     @api.multi
     def _compute_total_budget_financement_av(self):
         for project in self:
-            project.total_budget_financement_av = project.financement_adefpat_av + project.total_financement_av
+            project.total_budget_financement_av = (
+                project.financement_adefpat_av + project.total_financement_av
+            )
 
 
 class AdefpatFinancement(models.Model):
-    _inherit = 'adefpat.project.financement'
+    _inherit = "adefpat.project.financement"
 
     type_avenant = fields.Boolean("Type avenant", default=False)
 
 
 class AdefpatCout(models.Model):
-    _inherit = 'adefpat.project.cout'
+    _inherit = "adefpat.project.cout"
 
     type_avenant = fields.Boolean("Type avenant", default=False)
 
 
 class AdefpatCoutAV(models.Model):
-    _name = 'adefpat.project.cout.av'
-    _description = 'Coûts Avenants'
+    _name = "adefpat.project.cout.av"
+    _description = "Coûts Avenants"
 
     @api.model
     def _default_consultant_id(self):
-        return self.env['res.partner.consultants.project'].search([
-            ('project_id', '=', self.env.context.get('default_project_id')),
-            ('is_selected', '=', True)
-        ], limit=1)
+        return self.env["res.partner.consultants.project"].search(
+            [
+                ("project_id", "=", self.env.context.get("default_project_id")),
+                ("is_selected", "=", True),
+            ],
+            limit=1,
+        )
 
     module = fields.Char("Nom du module")
     project_id = fields.Many2one(
-        'project.project',
-        string='Projet',
-        default=lambda self: self.env.context.get('default_project_id'))
+        "project.project",
+        string="Projet",
+        default=lambda self: self.env.context.get("default_project_id"),
+    )
     consultant_id = fields.Many2one(
-        'res.partner.consultants.project',
+        "res.partner.consultants.project",
         string="Consultant",
         domain="[('is_selected', '=', True)]",
-        on_delete='restrict',
-        default=_default_consultant_id
+        on_delete="restrict",
+        default=_default_consultant_id,
     )
     partner_id = fields.Many2one(
-        'res.partner',
-        string='Consultant',
-        related='consultant_id.partner_id',
-        store=True)
+        "res.partner",
+        string="Consultant",
+        related="consultant_id.partner_id",
+        store=True,
+    )
     nb_jour_theorique = fields.Float("Nombre de jours théoriques")
     nb_jour_pratiques = fields.Float("Nombre de jours pratiques")
-    cout_jour = fields.Float("Coût jour", related='consultant_id.cout_journée')
-    montant = fields.Float("Montant", compute='_compute_montant', store=True)
+    cout_jour = fields.Float("Coût jour", related="consultant_id.cout_journée")
+    montant = fields.Float("Montant", compute="_compute_montant", store=True)
 
-    @api.depends('cout_jour', 'nb_jour_theorique')
+    @api.depends("cout_jour", "nb_jour_theorique")
     def _compute_montant(self):
         for r in self:
-            r.montant = r.cout_jour * r.nb_jour_theorique\
+            r.montant = r.cout_jour * r.nb_jour_theorique
 
 
 class AdefpatTemplateDoc(models.Model):
-    _inherit = 'adefpat.template.doc'
-
-    type_temp = fields.Selection(selection_add=[
-        ('convention_accompagnement_av', "Avenant Conventions d'accompagnement"),
-        ('convention_objectif_av', "Avenant Conventions d'objectif"),
-        ('annexe_convention_av', "Avenant Annexes Conventions"),
-        ('dossier_ca_av', "Avenant Dossier CA"),
-        ('facture_av', "Avenant Facture"),
-    ])
\ No newline at end of file
+    _inherit = "adefpat.template.doc"
+
+    type_temp = fields.Selection(
+        selection_add=[
+            ("convention_accompagnement_av", "Avenant Conventions d'accompagnement"),
+            ("convention_objectif_av", "Avenant Conventions d'objectif"),
+            ("annexe_convention_av", "Avenant Annexes Conventions"),
+            ("dossier_ca_av", "Avenant Dossier CA"),
+            ("facture_av", "Avenant Facture"),
+        ]
+    )
diff --git a/models/project_task.py b/models/project_task.py
old mode 100755
new mode 100644
index cd7379b..553bafd
--- a/models/project_task.py
+++ b/models/project_task.py
@@ -1,90 +1,99 @@
 # Copyright 2020 Le Filament (<http://www.le-filament.com>)
 # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
 
-from odoo import fields, models, api
+from odoo import api, fields, models
 
 
 class ProjectTask(models.Model):
-    _inherit = 'project.task'
+    _inherit = "project.task"
 
     @api.model
     def default_get(self, fields):
         res = super(ProjectTask, self).default_get(fields)
-        if 'default_project_id' in self.env.context:
-            default_project_id = self.env['project.project'].browse(self.env.context['default_project_id'])
+        if "default_project_id" in self.env.context:
+            default_project_id = self.env["project.project"].browse(
+                self.env.context["default_project_id"]
+            )
             if default_project_id.exists().porteurs_projets_ids:
                 participant_ids = []
                 for porteur_project in default_project_id.porteurs_projets_ids:
                     vals = {
-                        'porteur_id': porteur_project.porteur_id.id,
-                        'lastname': porteur_project.lastname,
-                        'firstname': porteur_project.firstname,
-                        'commune': porteur_project.commune,
-                        'mobile': porteur_project.mobile,
-                        'fixe': porteur_project.fixe,
-                        'email': porteur_project.email,
-                        'eligible': porteur_project.eligible,
+                        "porteur_id": porteur_project.porteur_id.id,
+                        "lastname": porteur_project.lastname,
+                        "firstname": porteur_project.firstname,
+                        "commune": porteur_project.commune,
+                        "mobile": porteur_project.mobile,
+                        "fixe": porteur_project.fixe,
+                        "email": porteur_project.email,
+                        "eligible": porteur_project.eligible,
                     }
                     participant_ids.append((0, 0, vals))
-                res.update({'participant_ids': participant_ids})
-                cout_id = self.env['adefpat.project.cout'].search([
-                    ('project_id', '=', default_project_id.id),
-                    ('partner_id', '!=', False)
-                ], limit=1)
+                res.update({"participant_ids": participant_ids})
+                cout_id = self.env["adefpat.project.cout"].search(
+                    [
+                        ("project_id", "=", default_project_id.id),
+                        ("partner_id", "!=", False),
+                    ],
+                    limit=1,
+                )
                 if cout_id:
-                    res.update({'formateur_id': cout_id.partner_id.id})
+                    res.update({"formateur_id": cout_id.partner_id.id})
         return res
 
     user_id = fields.Many2one(
-        'res.users',
-        string='CFD',
+        "res.users",
+        string="CFD",
         default=lambda self: self.env.uid,
         index=True,
-        track_visibility='always')
+        track_visibility="always",
+    )
     formateur_id = fields.Many2one(
-        'res.partner',
-        string='Formateur',
+        "res.partner",
+        string="Formateur",
         domain=[
-            ('active', '=', True),
-            ('is_company', '=', False),
-            ('is_consultant_form', '=', True),
-            '|', ('reference', '=', 'reference'),
-            ('reference', '=', 'prereference')],
-        on_delete='restrict')
-    duree_jr = fields.Selection([
-            ('demi_journee', "Demi journée"),
-            ('journee', "Journée"),
+            ("active", "=", True),
+            ("is_company", "=", False),
+            ("is_consultant_form", "=", True),
+            "|",
+            ("reference", "=", "reference"),
+            ("reference", "=", "prereference"),
+        ],
+        on_delete="restrict",
+    )
+    duree_jr = fields.Selection(
+        [
+            ("demi_journee", "Demi journée"),
+            ("journee", "Journée"),
         ],
-        "Durée (en jours)")
-    duree_hr = fields.Float(
-        "Durée en jours",
-        compute='_compute_duree_hr',
-        store=True
+        "Durée (en jours)",
     )
+    duree_hr = fields.Float("Durée en jours", compute="_compute_duree_hr", store=True)
     participant_ids = fields.One2many(
-        'res.partner.porteur.project',
-        'task_id',
-        string="Participants")
-    cout_seance = fields.Float("Coût de la séance", compute='_compute_cout_seance')
+        "res.partner.porteur.project", "task_id", string="Participants"
+    )
+    cout_seance = fields.Float("Coût de la séance", compute="_compute_cout_seance")
     date_account = fields.Date("Date de la facture")
 
-    @api.depends('duree_jr')
+    @api.depends("duree_jr")
     @api.multi
     def _compute_duree_hr(self):
         for task in self:
-            if task.duree_jr == 'journee':
+            if task.duree_jr == "journee":
                 task.duree_hr = 1
-            if task.duree_jr == 'demi_journee':
-                task.duree_hr = 0.5\
+            if task.duree_jr == "demi_journee":
+                task.duree_hr = 0.5
 
-    @api.depends('formateur_id', 'duree_hr')
+    @api.depends("formateur_id", "duree_hr")
     @api.multi
     def _compute_cout_seance(self):
         for task in self:
             if task.formateur_id:
-                formateur_proj = self.env['adefpat.project.cout'].search([
-                    ('project_id', '=', task.project_id.id),
-                    ('partner_id', '=', task.formateur_id.id)
-                ], limit=1)
+                formateur_proj = self.env["adefpat.project.cout"].search(
+                    [
+                        ("project_id", "=", task.project_id.id),
+                        ("partner_id", "=", task.formateur_id.id),
+                    ],
+                    limit=1,
+                )
                 if formateur_proj:
-                    task.cout_seance = formateur_proj.cout_jour * task.duree_hr
\ No newline at end of file
+                    task.cout_seance = formateur_proj.cout_jour * task.duree_hr
diff --git a/security/ir.model.access.csv b/security/ir.model.access.csv
old mode 100755
new mode 100644
index ee38fb4..a185d4f
--- 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_adefpat_project_cout_av_group_user,access_adefpat_project_cout_av_group_user,model_adefpat_project_cout_av,base.group_user,1,1,1,1
\ No newline at end of file
+access_adefpat_project_cout_av_group_user,access_adefpat_project_cout_av_group_user,model_adefpat_project_cout_av,base.group_user,1,1,1,1
diff --git a/static/description/icon.png b/static/description/icon.png
old mode 100755
new mode 100644
diff --git a/views/account_invoice_views.xml b/views/account_invoice_views.xml
index 418f27d..169d9e6 100644
--- a/views/account_invoice_views.xml
+++ b/views/account_invoice_views.xml
@@ -1,16 +1,16 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8" ?>
 <odoo>
     <data>
 
         <record id="invoice_form" model="ir.ui.view">
             <field name="name">adefpat.invoice_form.form</field>
             <field name="model">account.invoice</field>
-            <field name="inherit_id" ref="adefpat_account.invoice_form"/>
+            <field name="inherit_id" ref="adefpat_account.invoice_form" />
             <field name="arch" type="xml">
                 <xpath expr="//field[@name='project_id']" position="after">
-                    <field name="is_avenant"/>
+                    <field name="is_avenant" />
                 </xpath>
             </field>
         </record>
     </data>
-</odoo>
\ No newline at end of file
+</odoo>
diff --git a/views/project_views.xml b/views/project_views.xml
old mode 100755
new mode 100644
index 106c14a..9df244d
--- a/views/project_views.xml
+++ b/views/project_views.xml
@@ -1,95 +1,134 @@
-<?xml version="1.0"?>
+<?xml version="1.0" ?>
 <!-- Copyright 2020 Le Filament
      License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
-
 <odoo>
     <data>
 
         <record id="edit_project" model="ir.ui.view">
             <field name="name">av.project.project.form</field>
             <field name="model">project.project</field>
-            <field name="inherit_id" ref="adefpat_project.edit_project"/>
+            <field name="inherit_id" ref="adefpat_project.edit_project" />
             <field name="arch" type="xml">
                 <field name="territoire_id" position="before">
-                    <field name="is_avenant" invisible="1"/>
+                    <field name="is_avenant" invisible="1" />
                 </field>
                 <field name="nb_jour_plann" position="before">
-                    <field name="nb_jour_theorique_tot_global"/>
+                    <field name="nb_jour_theorique_tot_global" />
                 </field>
                 <header position="inside">
                     <!-- Ajout du bouton pour récupérer les infos avenants -->
-                    <button string="Avenant"
-                      type="object" class="btn btn-primary"
-                      name="fill_avenant" attrs="{'invisible': [('is_avenant', '=', True)]}"/>
+                    <button
+                        string="Avenant"
+                        type="object"
+                        class="btn btn-primary"
+                        name="fill_avenant"
+                        attrs="{'invisible': [('is_avenant', '=', True)]}"
+                    />
                 </header>
                 <page name="gap" position="after">
-                    <page name="dossier_av" string="Dossier Avenant" attrs="{'invisible': [('is_avenant', '=', False)]}">
+                    <page
+                        name="dossier_av"
+                        string="Dossier Avenant"
+                        attrs="{'invisible': [('is_avenant', '=', False)]}"
+                    >
                         <header>
-                            <button string="Générer Avenant Dossier CA"
-                              type="object" class="btn btn-primary"
-                              name="generate_dossier_ca_av"/>
-                            <button string="Générer Avenant Conventions"
-                              type="object" class="btn btn-primary"
-                              name="generate_dossier_conventions_av"/>
+                            <button
+                                string="Générer Avenant Dossier CA"
+                                type="object"
+                                class="btn btn-primary"
+                                name="generate_dossier_ca_av"
+                            />
+                            <button
+                                string="Générer Avenant Conventions"
+                                type="object"
+                                class="btn btn-primary"
+                                name="generate_dossier_conventions_av"
+                            />
                         </header>
                         <group>
-                            <field name="date_ca_av"/>
+                            <field name="date_ca_av" />
                         </group>
                         <group string="Dossier Consultation Avenant">
                             <group>
-                                <field name="contexte_av"/>
-                                <field name="caract_beneficiaire_av"/>
-                                <field name="besoins_beneficiaires_av"/>
-                                <field name="resultats_accompagnement"/>
-                                <field name="objectifs_accompagnement_av"/>
+                                <field name="contexte_av" />
+                                <field name="caract_beneficiaire_av" />
+                                <field name="besoins_beneficiaires_av" />
+                                <field name="resultats_accompagnement" />
+                                <field name="objectifs_accompagnement_av" />
                             </group>
                             <group string="Infos Dossier CA">
-                                <field name="lieu_av"/>
-                                <field name="periode_realisation_av"/>
-                                <field name="contenu_formation_av" placeholder="Contenu des séances / Evaluation - capitalisation / La dernière séance permettra de dégager les acquis pédagogiques en s’appuyant sur les objectifs initiaux d’accompagnement : retour d’expérience / pointage des actions restant à conduire"/>
-                                <field name="methode_savoir_av" placeholder="Méthodes et savoir transmis / Evaluation - capitalisation / La dernière séance permettra de dégager les acquis pédagogiques en s’appuyant sur les objectifs initiaux d’accompagnement : retour d’expérience / pointage des actions restant à conduire"/>
-                                <field name="travaux_intersessions_av" placeholder="Travaux intersessions / Evaluation - capitalisation / La dernière séance permettra de dégager les acquis pédagogiques en s’appuyant sur les objectifs initiaux d’accompagnement : retour d’expérience / pointage des actions restant à conduire"/>
+                                <field name="lieu_av" />
+                                <field name="periode_realisation_av" />
+                                <field
+                                    name="contenu_formation_av"
+                                    placeholder="Contenu des séances / Evaluation - capitalisation / La dernière séance permettra de dégager les acquis pédagogiques en s’appuyant sur les objectifs initiaux d’accompagnement : retour d’expérience / pointage des actions restant à conduire"
+                                />
+                                <field
+                                    name="methode_savoir_av"
+                                    placeholder="Méthodes et savoir transmis / Evaluation - capitalisation / La dernière séance permettra de dégager les acquis pédagogiques en s’appuyant sur les objectifs initiaux d’accompagnement : retour d’expérience / pointage des actions restant à conduire"
+                                />
+                                <field
+                                    name="travaux_intersessions_av"
+                                    placeholder="Travaux intersessions / Evaluation - capitalisation / La dernière séance permettra de dégager les acquis pédagogiques en s’appuyant sur les objectifs initiaux d’accompagnement : retour d’expérience / pointage des actions restant à conduire"
+                                />
                             </group>
                         </group>
                         <group>
-                            <field name="modalite_gap_av"/>
+                            <field name="modalite_gap_av" />
                         </group>
                     </page>
 
-                    <page string="Budget Avenant" attrs="{'invisible': [('is_avenant', '=', False)]}">
-                        <button string="Générer Factures Avenant"
-                          type="object" class="btn btn-primary"
-                          name="action_generate_invoices_av"/>
+                    <page
+                        string="Budget Avenant"
+                        attrs="{'invisible': [('is_avenant', '=', False)]}"
+                    >
+                        <button
+                            string="Générer Factures Avenant"
+                            type="object"
+                            class="btn btn-primary"
+                            name="action_generate_invoices_av"
+                        />
                         <group>
                             <group string="Adefpat">
-                                <field name="nb_jours_adefpat_av"/>
-                                <field name="cout_jour_adefpat_av"/>
+                                <field name="nb_jours_adefpat_av" />
+                                <field name="cout_jour_adefpat_av" />
                             </group>
-                            <group >
-                                <field name="nb_jour_tot_av" invisible="1"/>
-                                <field name="nb_heure_tot_av" invisible="1"/>
-                                <field name="nb_jour_theorique_tot_av"/>
+                            <group>
+                                <field name="nb_jour_tot_av" invisible="1" />
+                                <field name="nb_heure_tot_av" invisible="1" />
+                                <field name="nb_jour_theorique_tot_av" />
                             </group>
                         </group>
-                        <field name="cout_av_ids" widget="one2many" context="{'default_project_id': active_id}">
+                        <field
+                            name="cout_av_ids"
+                            widget="one2many"
+                            context="{'default_project_id': active_id}"
+                        >
                             <tree string="Coûts Avenants" editable="top">
-                                <field name="module"/>
-                                <field name="consultant_id"/>
-                                <field name="partner_id" invisible="1"/>
-                                <field name="nb_jour_theorique"/>
-                                <field name="nb_jour_pratiques"/>
-                                <field name="cout_jour"/>
-                                <field name="montant" sum="Montant"/>
-                                <field name="project_id" invisible="1"/>
+                                <field name="module" />
+                                <field name="consultant_id" />
+                                <field name="partner_id" invisible="1" />
+                                <field name="nb_jour_theorique" />
+                                <field name="nb_jour_pratiques" />
+                                <field name="cout_jour" />
+                                <field name="montant" sum="Montant" />
+                                <field name="project_id" invisible="1" />
                             </tree>
                         </field>
-                        <field name="financement_av_ids" widget="one2many" context="{'default_type_avenant': True}">
+                        <field
+                            name="financement_av_ids"
+                            widget="one2many"
+                            context="{'default_type_avenant': True}"
+                        >
                             <tree string="Financements Avenant" editable="top">
                                 <field name="partner_id" />
-                                <field name="montant" sum="Montant"/>
-                                <field name="project_id" invisible="1"/>
-                                <field name="invoice_id" domain="[('project_id', '=', project_id)]"/>
-                                <field name="type_avenant" invisible="1"/>
+                                <field name="montant" sum="Montant" />
+                                <field name="project_id" invisible="1" />
+                                <field
+                                    name="invoice_id"
+                                    domain="[('project_id', '=', project_id)]"
+                                />
+                                <field name="type_avenant" invisible="1" />
                             </tree>
                         </field>
                         <group>
@@ -102,30 +141,56 @@
                                 </thead>
                                 <tbody>
                                     <tr>
-                                        <td >
+                                        <td>
                                             <tr>
                                                 <td>
                                                     Honoraire d'intervenant :
-                                                    <field name="cout_av_ids" widget="one2many" context="{'default_project_id': active_id}">
-                                                        <tree string="Coûts" editable="top">
-                                                            <field name="module"/>
-                                                            <field name="consultant_id"/>
-                                                            <field name="partner_id" invisible="1"/>
-                                                            <field name="nb_jour_theorique"/>
-                                                            <field name="nb_jour_pratiques"/>
-                                                            <field name="cout_jour"/>
-                                                            <field name="montant" sum="Montant"/>
+                                                    <field
+                                                        name="cout_av_ids"
+                                                        widget="one2many"
+                                                        context="{'default_project_id': active_id}"
+                                                    >
+                                                        <tree
+                                                            string="Coûts"
+                                                            editable="top"
+                                                        >
+                                                            <field name="module" />
+                                                            <field
+                                                                name="consultant_id"
+                                                            />
+                                                            <field
+                                                                name="partner_id"
+                                                                invisible="1"
+                                                            />
+                                                            <field
+                                                                name="nb_jour_theorique"
+                                                            />
+                                                            <field
+                                                                name="nb_jour_pratiques"
+                                                            />
+                                                            <field name="cout_jour" />
+                                                            <field
+                                                                name="montant"
+                                                                sum="Montant"
+                                                            />
                                                         </tree>
                                                     </field>
                                                 </td>
-                                                <td><field name="total_cout_av" widget="monetary" readonly="True"/> €</td>
+                                                <td><field
+                                                        name="total_cout_av"
+                                                        widget="monetary"
+                                                        readonly="True"
+                                                    /> €</td>
                                             </tr>
                                             <tr>
                                                 <td>
-                                                    Temps Adefpat: <br/>
+                                                    Temps Adefpat: <br />
                                                 </td>
                                                 <td>
-                                                    <field name="total_cout_adefpat_av"  readonly="True"/> €
+                                                    <field
+                                                        name="total_cout_adefpat_av"
+                                                        readonly="True"
+                                                    /> €
                                                 </td>
                                             </tr>
                                         </td>
@@ -136,7 +201,11 @@
                                                     Adefpat:
                                                 </td>
                                                 <td>
-                                                    <field name="financement_adefpat_av" widget="monetary" readonly="True"/> €
+                                                    <field
+                                                        name="financement_adefpat_av"
+                                                        widget="monetary"
+                                                        readonly="True"
+                                                    /> €
                                                 </td>
                                             </tr>
                                             <tr>
@@ -144,7 +213,11 @@
                                                     Autres:
                                                 </td>
                                                 <td>
-                                                    <field name="total_financement_av" widget="monetary" readonly="True"/> €
+                                                    <field
+                                                        name="total_financement_av"
+                                                        widget="monetary"
+                                                        readonly="True"
+                                                    /> €
                                                 </td>
                                             </tr>
                                         </td>
@@ -153,7 +226,11 @@
                                         <td>
                                             <tr>
                                                 <td>Budget Total: </td>
-                                                <td><field name="total_budget_cout_av" widget="monetary" readonly="True"/> €
+                                                <td><field
+                                                        name="total_budget_cout_av"
+                                                        widget="monetary"
+                                                        readonly="True"
+                                                    /> €
                                                 </td>
                                             </tr>
                                         </td>
@@ -161,7 +238,11 @@
                                         <td>
                                             <tr>
                                                 <td>Budget Total:</td>
-                                                <td><field name="total_budget_financement_av" widget="monetary" readonly="True"/> €</td>
+                                                <td><field
+                                                        name="total_budget_financement_av"
+                                                        widget="monetary"
+                                                        readonly="True"
+                                                    /> €</td>
                                             </tr>
                                         </td>
                                     </tr>
@@ -169,7 +250,7 @@
                             </table>
                         </group>
                         <group>
-                            <field name="explication_financement_av"/>
+                            <field name="explication_financement_av" />
                         </group>
                     </page>
                 </page>
-- 
GitLab