diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000000000000000000000000000000000000..bfd7ac53df9f103f6dc8853738c63fd364445fde
--- /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/.gitignore b/.gitignore
index b0e1bbefecdd6e195f0bc3469b0fcd465ee61046..109270f27c2a80740fab3c0fbc084b9d938f964e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,89 @@
-.*
-*.pyc
-!.gitignore
\ No newline at end of file
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+/.venv
+/.pytest_cache
+/.ruff_cache
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+env/
+bin/
+build/
+develop-eggs/
+dist/
+eggs/
+lib64/
+parts/
+sdist/
+var/
+*.egg-info/
+.installed.cfg
+*.egg
+*.eggs
+.copier-answers.yml
+
+# Windows installers
+*.msi
+
+# Debian packages
+*.deb
+
+# Redhat packages
+*.rpm
+
+# MacOS packages
+*.dmg
+*.pkg
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.coverage
+.cache
+nosetests.xml
+coverage.xml
+
+# Translations
+*.mo
+
+# Pycharm
+.idea
+
+# Eclipse
+.settings
+
+# Visual Studio cache/options directory
+.vs/
+.vscode
+
+# OSX Files
+.DS_Store
+
+# Django stuff:
+*.log
+
+# Mr Developer
+.mr.developer.cfg
+.project
+.pydevproject
+
+# Rope
+.ropeproject
+
+# Sphinx documentation
+docs/_build/
+
+# Backup files
+*~
+*.swp
+
+# OCA rules
+!static/lib/
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..207e4c9037d15863a1efcc9bd98b6199792df472
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,123 @@
+exclude: |
+  (?x)
+  # NOT INSTALLABLE ADDONS
+  # END NOT INSTALLABLE ADDONS
+  # Files and folders generated by bots, to avoid loops
+  ^setup/|/static/description/index\.html$|
+  # We don't want to mess with tool-generated files
+  .svg$|/tests/([^/]+/)?cassettes/|^.copier-answers.yml$|^.github/|^eslint.config.cjs|^prettier.config.cjs|
+  # Maybe reactivate this when all README files include prettier ignore tags?
+  ^README\.md$|
+  # Library files can have extraneous formatting (even minimized)
+  /static/(src/)?lib/|
+  # Repos using Sphinx to generate docs don't need prettying
+  ^docs/_templates/.*\.html$|
+  # Don't bother non-technical authors with formatting issues in docs
+  readme/.*\.(rst|md)$|
+  # Ignore build and dist directories in addons
+  /build/|/dist/|
+  # Ignore test files in addons
+  /tests/samples/.*|
+  # You don't usually want a bot to modify your legal texts
+  (LICENSE.*|COPYING.*)
+default_language_version:
+  python: python3
+  node: "22.9.0"
+repos:
+  - repo: local
+    hooks:
+      # These files are most likely copier diff rejection junks; if found,
+      # review them manually, fix the problem (if needed) and remove them
+      - id: forbidden-files
+        name: forbidden files
+        entry: found forbidden files; remove them
+        language: fail
+        files: "\\.rej$"
+      - id: en-po-files
+        name: en.po files cannot exist
+        entry: found a en.po file
+        language: fail
+        files: '[a-zA-Z0-9_]*/i18n/en\.po$'
+  - repo: https://github.com/oca/maintainer-tools
+    rev: bf9ecb9938b6a5deca0ff3d870fbd3f33341fded
+    hooks:
+      # update the NOT INSTALLABLE ADDONS section above
+      - id: oca-update-pre-commit-excluded-addons
+      - id: oca-fix-manifest-website
+        args: ["https://le-filament.com"]
+  - repo: https://github.com/OCA/odoo-pre-commit-hooks
+    rev: v0.0.33
+    hooks:
+      - id: oca-checks-odoo-module
+      - id: oca-checks-po
+        args:
+          - --disable=po-pretty-format
+  - repo: local
+    hooks:
+      - id: prettier
+        name: prettier (with plugin-xml)
+        entry: prettier
+        args:
+          - --write
+          - --list-different
+          - --ignore-unknown
+        types: [text]
+        files: \.(css|htm|html|js|json|jsx|less|md|scss|toml|ts|xml|yaml|yml)$
+        language: node
+        additional_dependencies:
+          - "prettier@3.3.3"
+          - "@prettier/plugin-xml@3.4.1"
+  - repo: local
+    hooks:
+      - id: eslint
+        name: eslint
+        entry: eslint
+        args:
+          - --color
+          - --fix
+        verbose: true
+        types: [javascript]
+        language: node
+        additional_dependencies:
+          - "eslint@9.12.0"
+          - "eslint-plugin-jsdoc@50.3.1"
+  - repo: https://github.com/pre-commit/pre-commit-hooks
+    rev: v4.6.0
+    hooks:
+      - id: trailing-whitespace
+        # exclude autogenerated files
+        exclude: /README\.rst$|\.pot?$
+      - id: end-of-file-fixer
+        # exclude autogenerated files
+        exclude: /README\.rst$|\.pot?$
+      - id: debug-statements
+      - id: fix-encoding-pragma
+        args: ["--remove"]
+      - id: check-case-conflict
+      - id: check-docstring-first
+      - id: check-executables-have-shebangs
+      - id: check-merge-conflict
+        # exclude files where underlines are not distinguishable from merge conflicts
+        exclude: /README\.rst$|^docs/.*\.rst$
+      - id: check-symlinks
+      - id: check-xml
+      - id: mixed-line-ending
+        args: ["--fix=lf"]
+  - repo: https://github.com/astral-sh/ruff-pre-commit
+    rev: v0.6.8
+    hooks:
+      - id: ruff
+        args: [--fix, --exit-non-zero-on-fix]
+      - id: ruff-format
+  - repo: https://github.com/OCA/pylint-odoo
+    rev: v9.1.3
+    hooks:
+      - id: pylint_odoo
+        name: pylint with optional checks
+        args:
+          - --rcfile=.pylintrc
+          - --exit-zero
+        verbose: true
+      - id: pylint_odoo
+        args:
+          - --rcfile=.pylintrc-mandatory
diff --git a/.pylintrc b/.pylintrc
new file mode 100644
index 0000000000000000000000000000000000000000..b855a9270efdb66248c84038041d1a589961ee44
--- /dev/null
+++ b/.pylintrc
@@ -0,0 +1,123 @@
+
+
+[MASTER]
+load-plugins=pylint_odoo
+score=n
+
+[ODOOLINT]
+readme-template-url="https://github.com/OCA/maintainer-tools/blob/master/template/module/README.rst"
+manifest-required-authors=Le Filament
+manifest-required-keys=license
+manifest-deprecated-keys=description,active
+license-allowed=AGPL-3,GPL-2,GPL-2 or any later version,GPL-3,GPL-3 or any later version,LGPL-3
+valid-odoo-versions=18.0
+
+[MESSAGES CONTROL]
+disable=all
+
+# This .pylintrc contains optional AND mandatory checks and is meant to be
+# loaded in an IDE to have it check everything, in the hope this will make
+# optional checks more visible to contributors who otherwise never look at a
+# green travis to see optional checks that failed.
+# .pylintrc-mandatory containing only mandatory checks is used the pre-commit
+# config as a blocking check.
+
+enable=anomalous-backslash-in-string,
+    api-one-deprecated,
+    api-one-multi-together,
+    assignment-from-none,
+    attribute-deprecated,
+    class-camelcase,
+    dangerous-default-value,
+    dangerous-view-replace-wo-priority,
+    development-status-allowed,
+    duplicate-id-csv,
+    duplicate-key,
+    duplicate-xml-fields,
+    duplicate-xml-record-id,
+    eval-referenced,
+    eval-used,
+    incoherent-interpreter-exec-perm,
+    license-allowed,
+    manifest-author-string,
+    manifest-deprecated-key,
+    manifest-required-author,
+    manifest-required-key,
+    manifest-version-format,
+    method-compute,
+    method-inverse,
+    method-required-super,
+    method-search,
+    openerp-exception-warning,
+    pointless-statement,
+    pointless-string-statement,
+    print-used,
+    redundant-keyword-arg,
+    redundant-modulename-xml,
+    reimported,
+    relative-import,
+    return-in-init,
+    rst-syntax-error,
+    sql-injection,
+    too-few-format-args,
+    translation-field,
+    translation-required,
+    unreachable,
+    use-vim-comment,
+    wrong-tabs-instead-of-spaces,
+    xml-syntax-error,
+    attribute-string-redundant,
+    character-not-valid-in-resource-link,
+    consider-merging-classes-inherited,
+    context-overridden,
+    create-user-wo-reset-password,
+    dangerous-filter-wo-user,
+    dangerous-qweb-replace-wo-priority,
+    deprecated-data-xml-node,
+    deprecated-openerp-xml-node,
+    duplicate-po-message-definition,
+    except-pass,
+    file-not-used,
+    invalid-commit,
+    manifest-maintainers-list,
+    missing-newline-extrafiles,
+    missing-readme,
+    missing-return,
+    odoo-addons-relative-import,
+    old-api7-method-defined,
+    po-msgstr-variables,
+    po-syntax-error,
+    renamed-field-parameter,
+    resource-not-exist,
+    str-format-used,
+    test-folder-imported,
+    translation-contains-variable,
+    translation-positional-used,
+    unnecessary-utf8-coding-comment,
+    website-manifest-key-not-valid-uri,
+    xml-attribute-translatable,
+    xml-deprecated-qweb-directive,
+    xml-deprecated-tree-attribute,
+    external-request-timeout,
+    # messages that do not cause the lint step to fail
+    consider-merging-classes-inherited,
+    create-user-wo-reset-password,
+    dangerous-filter-wo-user,
+    deprecated-module,
+    file-not-used,
+    invalid-commit,
+    missing-manifest-dependency,
+    missing-newline-extrafiles,
+    missing-readme,
+    no-utf8-coding-comment,
+    odoo-addons-relative-import,
+    old-api7-method-defined,
+    redefined-builtin,
+    too-complex,
+    unnecessary-utf8-coding-comment
+
+
+[REPORTS]
+msg-template={path}:{line}: [{msg_id}({symbol}), {obj}] {msg}
+output-format=colorized
+reports=no
diff --git a/.pylintrc-mandatory b/.pylintrc-mandatory
new file mode 100644
index 0000000000000000000000000000000000000000..f9450512a1b688db0b671c400b492ac9e4e2e425
--- /dev/null
+++ b/.pylintrc-mandatory
@@ -0,0 +1,98 @@
+
+[MASTER]
+load-plugins=pylint_odoo
+score=n
+
+[ODOOLINT]
+readme-template-url="https://github.com/OCA/maintainer-tools/blob/master/template/module/README.rst"
+manifest-required-authors=Le Filament
+manifest-required-keys=license
+manifest-deprecated-keys=description,active
+license-allowed=AGPL-3,GPL-2,GPL-2 or any later version,GPL-3,GPL-3 or any later version,LGPL-3
+valid-odoo-versions=18.0
+
+[MESSAGES CONTROL]
+disable=all
+
+enable=anomalous-backslash-in-string,
+    api-one-deprecated,
+    api-one-multi-together,
+    assignment-from-none,
+    attribute-deprecated,
+    class-camelcase,
+    dangerous-default-value,
+    dangerous-view-replace-wo-priority,
+    development-status-allowed,
+    duplicate-id-csv,
+    duplicate-key,
+    duplicate-xml-fields,
+    duplicate-xml-record-id,
+    eval-referenced,
+    eval-used,
+    incoherent-interpreter-exec-perm,
+    license-allowed,
+    manifest-author-string,
+    manifest-deprecated-key,
+    manifest-required-author,
+    manifest-required-key,
+    manifest-version-format,
+    method-compute,
+    method-inverse,
+    method-required-super,
+    method-search,
+    openerp-exception-warning,
+    pointless-statement,
+    pointless-string-statement,
+    print-used,
+    redundant-keyword-arg,
+    redundant-modulename-xml,
+    reimported,
+    relative-import,
+    return-in-init,
+    rst-syntax-error,
+    sql-injection,
+    too-few-format-args,
+    translation-field,
+    translation-required,
+    unreachable,
+    use-vim-comment,
+    wrong-tabs-instead-of-spaces,
+    xml-syntax-error,
+    attribute-string-redundant,
+    character-not-valid-in-resource-link,
+    consider-merging-classes-inherited,
+    context-overridden,
+    create-user-wo-reset-password,
+    dangerous-filter-wo-user,
+    dangerous-qweb-replace-wo-priority,
+    deprecated-data-xml-node,
+    deprecated-openerp-xml-node,
+    duplicate-po-message-definition,
+    except-pass,
+    file-not-used,
+    invalid-commit,
+    manifest-maintainers-list,
+    missing-newline-extrafiles,
+    missing-readme,
+    missing-return,
+    odoo-addons-relative-import,
+    old-api7-method-defined,
+    po-msgstr-variables,
+    po-syntax-error,
+    renamed-field-parameter,
+    resource-not-exist,
+    str-format-used,
+    test-folder-imported,
+    translation-contains-variable,
+    translation-positional-used,
+    unnecessary-utf8-coding-comment,
+    website-manifest-key-not-valid-uri,
+    xml-attribute-translatable,
+    xml-deprecated-qweb-directive,
+    xml-deprecated-tree-attribute,
+    external-request-timeout
+
+[REPORTS]
+msg-template={path}:{line}: [{msg_id}({symbol}), {obj}] {msg}
+output-format=colorized
+reports=no
diff --git a/.ruff.toml b/.ruff.toml
new file mode 100644
index 0000000000000000000000000000000000000000..0f1e35f24803bf777951495f745cb2f1630cb4cb
--- /dev/null
+++ b/.ruff.toml
@@ -0,0 +1,30 @@
+
+target-version = "py310"
+fix = true
+
+[lint]
+extend-select = [
+    "B",
+    "C90",
+    "E501",  # line too long (default 88)
+    "I",  # isort
+    "UP",  # pyupgrade
+]
+exclude = ["setup/*"]
+
+[format]
+exclude = ["setup/*"]
+
+[lint.per-file-ignores]
+"__init__.py" = ["F401", "I001"]  # ignore unused and unsorted imports in __init__.py
+"__manifest__.py" = ["B018"]  # useless expression
+
+[lint.isort]
+section-order = ["future", "standard-library", "third-party", "odoo", "odoo-addons", "first-party", "local-folder"]
+
+[lint.isort.sections]
+"odoo" = ["odoo"]
+"odoo-addons" = ["odoo.addons"]
+
+[lint.mccabe]
+max-complexity = 16
diff --git a/README.rst b/README.rst
index fdad646713e5ae5b6df66cf05263bcfc78c1ae01..23bc879c2ec4fc1b3c01b58be8153e3c91d07c4a 100644
--- a/README.rst
+++ b/README.rst
@@ -57,4 +57,4 @@ Maintainer
    :alt: Le Filament
    :target: https://le-filament.com
 
-This module is maintained by `Le Filament <https://le-filament.com>`_
\ No newline at end of file
+This module is maintained by `Le Filament <https://le-filament.com>`_
diff --git a/__manifest__.py b/__manifest__.py
index 52bffebab68a3428478636efb84388dd4a74e597..8db078e59edecd6ede212c2054eaa3dfd59392d6 100644
--- a/__manifest__.py
+++ b/__manifest__.py
@@ -1,22 +1,23 @@
-# © 2018 Le Filament (<https://www.le-filament.com>)
-# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
-
 {
-    'name': 'Le Filament - SIREN',
-    'summary': "Recherche dans la base SIREN",
-    'version': '12.0.2.0.0',
-    'license': 'AGPL-3',
-    'author': 'LE FILAMENT',
-    'category': 'Partner',
-    'depends': ['base'],
-    'contributors': [
-        'Benjamin Rivier <benjamin@le-filament.com>',
-        'Rémi Cazenave <remi@le-filament.com>',
+    "name": "Le Filament - SIREN",
+    "summary": "Recherche dans la base SIREN",
+    "version": "18.0.2.0.0",
+    "license": "AGPL-3",
+    "author": "Le Filament",
+    "category": "Partner",
+    "depends": ["base"],
+    "contributors": [
+        "Benjamin <benjamin@le-filament.com>",
+        "Rémi Cazenave <remi@le-filament.com>",
     ],
-    'website': 'https://www.le-filament.com',
-    'data': [
-        'wizard/wizard_siren.xml',
-        'views/res_partner.xml',
+    "website": "https://www.le-filament.com",
+    "data": [
+        # security
+        "security/ir.model.access.csv",
+        # wizard
+        "wizard/wizard_siren.xml",
+        # views
+        "views/res_partner.xml",
     ],
-    'qweb': [],
+    "qweb": [],
 }
diff --git a/eslint.config.cjs b/eslint.config.cjs
new file mode 100644
index 0000000000000000000000000000000000000000..0d5731f89a8bc2073894c17dfe41e410db0e4cfe
--- /dev/null
+++ b/eslint.config.cjs
@@ -0,0 +1,202 @@
+jsdoc = require("eslint-plugin-jsdoc");
+
+const config = [{
+    plugins: {
+      jsdoc,
+    },
+
+    languageOptions: {
+        globals: {
+            _: "readonly",
+            $: "readonly",
+            fuzzy: "readonly",
+            jQuery: "readonly",
+            moment: "readonly",
+            odoo: "readonly",
+            openerp: "readonly",
+            owl: "readonly",
+            luxon: "readonly",
+        },
+
+        ecmaVersion: 2024,
+        sourceType: "script",
+    },
+
+    rules: {
+        "accessor-pairs": "warn",
+        "array-callback-return": "warn",
+        "callback-return": "warn",
+        "capitalized-comments": ["warn", "always", {
+            ignoreConsecutiveComments: true,
+            ignoreInlineComments: true,
+        }],
+        complexity: ["warn", 15],
+        "constructor-super": "warn",
+        "dot-notation": "warn",
+        eqeqeq: "warn",
+        "global-require": "warn",
+        "handle-callback-err": "warn",
+        "id-blacklist": "warn",
+        "id-match": "warn",
+        "init-declarations": "error",
+        "max-depth": "warn",
+        "max-nested-callbacks": "warn",
+        "max-statements-per-line": "warn",
+        "no-alert": "warn",
+        "no-array-constructor": "warn",
+        "no-caller": "warn",
+        "no-case-declarations": "warn",
+        "no-class-assign": "warn",
+        "no-cond-assign": "error",
+        "no-const-assign": "error",
+        "no-constant-condition": "warn",
+        "no-control-regex": "warn",
+        "no-debugger": "error",
+        "no-delete-var": "warn",
+        "no-div-regex": "warn",
+        "no-dupe-args": "error",
+        "no-dupe-class-members": "error",
+        "no-dupe-keys": "error",
+        "no-duplicate-case": "error",
+        "no-duplicate-imports": "error",
+        "no-else-return": "warn",
+        "no-empty-character-class": "warn",
+        "no-empty-function": "error",
+        "no-empty-pattern": "error",
+        "no-empty": "warn",
+        "no-eq-null": "error",
+        "no-eval": "error",
+        "no-ex-assign": "error",
+        "no-extend-native": "warn",
+        "no-extra-bind": "warn",
+        "no-extra-boolean-cast": "warn",
+        "no-extra-label": "warn",
+        "no-fallthrough": "warn",
+        "no-func-assign": "error",
+        "no-global-assign": "error",
+        "no-implicit-coercion": ["warn", {
+            allow: ["~"],
+        }],
+        "no-implicit-globals": "warn",
+        "no-implied-eval": "warn",
+        "no-inline-comments": "warn",
+        "no-inner-declarations": "warn",
+        "no-invalid-regexp": "warn",
+        "no-irregular-whitespace": "warn",
+        "no-iterator": "warn",
+        "no-label-var": "warn",
+        "no-labels": "warn",
+        "no-lone-blocks": "warn",
+        "no-lonely-if": "error",
+        "no-mixed-requires": "error",
+        "no-multi-str": "warn",
+        "no-native-reassign": "error",
+        "no-negated-condition": "warn",
+        "no-negated-in-lhs": "error",
+        "no-new-func": "warn",
+        "no-new-object": "warn",
+        "no-new-require": "warn",
+        "no-new-symbol": "warn",
+        "no-new-wrappers": "warn",
+        "no-new": "warn",
+        "no-obj-calls": "warn",
+        "no-octal-escape": "warn",
+        "no-octal": "warn",
+        "no-param-reassign": "warn",
+        "no-path-concat": "warn",
+        "no-process-env": "warn",
+        "no-process-exit": "warn",
+        "no-proto": "warn",
+        "no-prototype-builtins": "warn",
+        "no-redeclare": "warn",
+        "no-regex-spaces": "warn",
+        "no-restricted-globals": "warn",
+        "no-restricted-imports": "warn",
+        "no-restricted-modules": "warn",
+        "no-restricted-syntax": "warn",
+        "no-return-assign": "error",
+        "no-script-url": "warn",
+        "no-self-assign": "warn",
+        "no-self-compare": "warn",
+        "no-sequences": "warn",
+        "no-shadow-restricted-names": "warn",
+        "no-shadow": "warn",
+        "no-sparse-arrays": "warn",
+        "no-sync": "warn",
+        "no-this-before-super": "warn",
+        "no-throw-literal": "warn",
+        "no-undef-init": "warn",
+        "no-undef": "error",
+        "no-unmodified-loop-condition": "warn",
+        "no-unneeded-ternary": "error",
+        "no-unreachable": "error",
+        "no-unsafe-finally": "error",
+        "no-unused-expressions": "error",
+        "no-unused-labels": "error",
+        "no-unused-vars": "error",
+        "no-use-before-define": "error",
+        "no-useless-call": "warn",
+        "no-useless-computed-key": "warn",
+        "no-useless-concat": "warn",
+        "no-useless-constructor": "warn",
+        "no-useless-escape": "warn",
+        "no-useless-rename": "warn",
+        "no-void": "warn",
+        "no-with": "warn",
+        "operator-assignment": ["error", "always"],
+        "prefer-const": "warn",
+        radix: "warn",
+        "require-yield": "warn",
+        "sort-imports": "warn",
+        "spaced-comment": ["error", "always"],
+        strict: ["error", "function"],
+        "use-isnan": "error",
+
+        "jsdoc/check-tag-names": "warn",
+        "jsdoc/check-types": "warn",
+        "jsdoc/require-param-description": "off",
+        "jsdoc/require-return": "off",
+        "jsdoc/require-return-description": "off",
+        "jsdoc/require-return-type": "off",
+
+        "valid-typeof": "warn",
+        yoda: "warn",
+    },
+
+    settings: {
+        jsdoc: {
+            tagNamePreference: {
+                arg: "param",
+                argument: "param",
+                augments: "extends",
+                constructor: "class",
+                exception: "throws",
+                func: "function",
+                method: "function",
+                prop: "property",
+                return: "returns",
+                virtual: "abstract",
+                yield: "yields",
+            },
+            preferredTypes: {
+                array: "Array",
+                bool: "Boolean",
+                boolean: "Boolean",
+                number: "Number",
+                object: "Object",
+                str: "String",
+                string: "String",
+            },
+        },
+    },
+
+}, {
+    files: ["**/*.esm.js"],
+
+    languageOptions: {
+        ecmaVersion: 2024,
+        sourceType: "module",
+    },
+}];
+
+module.exports = config
diff --git a/models/res_partner.py b/models/res_partner.py
index 94a8c859597595d70099e769254916c2ea68240f..2886d22f81aef6de65cc384eab201255d5f64a92 100644
--- a/models/res_partner.py
+++ b/models/res_partner.py
@@ -5,15 +5,15 @@ from odoo import fields, models
 
 
 class PartnerSiren(models.Model):
-    _inherit = 'res.partner'
+    _inherit = "res.partner"
 
     # Fields
-    forme_juridique = fields.Char("Forme Juridique")
-    siren = fields.Char("SIREN")
-    siret = fields.Char("SIRET")
+    forme_juridique = fields.Char()
+    siren = fields.Char()
+    siret = fields.Char()
     ape = fields.Char("Code APE")
     lib_ape = fields.Char("Libellé APE")
     date_creation = fields.Date("Date de création")
-    effectif = fields.Char("Effectif")
+    effectif = fields.Char()
     ess = fields.Boolean("ESS")
     categorie = fields.Char("Catégorie")
diff --git a/prettier.config.cjs b/prettier.config.cjs
new file mode 100644
index 0000000000000000000000000000000000000000..e66cd82cc1e4dfeded9749598144f820c8491fab
--- /dev/null
+++ b/prettier.config.cjs
@@ -0,0 +1,14 @@
+/** @type {import('prettier').Config} */
+
+const config = {
+  // https://github.com/prettier/prettier/issues/15388#issuecomment-1717746872
+  plugins: [require.resolve("@prettier/plugin-xml")],
+  bracketSpacing: false,
+  printWidth: 88,
+  proseWrap: "always",
+  semi: true,
+  trailingComma: "es5",
+  xmlWhitespaceSensitivity: "preserve",
+};
+
+module.exports = config;
diff --git a/security/ir.model.access.csv b/security/ir.model.access.csv
new file mode 100644
index 0000000000000000000000000000000000000000..9fefdc7a3162f81618ecdb43771c37e2814b1f9b
--- /dev/null
+++ b/security/ir.model.access.csv
@@ -0,0 +1,3 @@
+id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink
+access_siren_wizard,access_siren_wizard,model_siren_wizard,base.group_user,1,1,1,1
+access_siren_wizard_company,access_siren_wizard_company,model_siren_wizard_company,base.group_user,1,1,1,1
\ No newline at end of file
diff --git a/views/res_partner.xml b/views/res_partner.xml
index 86fc2904aefead89655b3585c206bcca4e6e98b0..2bc34c5648e0bc13c5bf86fa22618d54a1eb567e 100644
--- a/views/res_partner.xml
+++ b/views/res_partner.xml
@@ -1,41 +1,22 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8" ?>
 <odoo>
-    <data>
-        <!-- Client Form View -->
-        <record id="partner_form_siren_view" model="ir.ui.view">
-            <field name="name">res.partner.siren.form.view</field>
-            <field name="model">res.partner</field>
-            <field name="inherit_id" ref="base.view_partner_form"/>
-            <field name="arch" type="xml" >
-                <!-- ADD HEADER BUTTON -->
-                <xpath expr="//sheet" position="before">
-                    <header attrs="{'invisible': [('is_company','!=',True)]}">
-                        <button string="Pré-remplir / Mettre à jour" type="action" name="%(lefilament_siren.siren_wizard_action)d" class="oe_highlight"/>
-                    </header>
-                </xpath>
-                <!-- ADD PARTNER INFO TAB -->
-                <xpath expr="//page[@name='internal_notes']" position="after" attrs="{'invisible': [('is_company','!=',True)]}">
-                    <page name="legal_infos" string="Infos Légales">
-                        <group>
-                            <group string="Infos légales">
-                                <field name="forme_juridique" />
-                                <field name="siren" />
-                                <field name="siret" />
-                                <field name="ape" />
-                                <field name="lib_ape" />
-                            </group>
-                            <group string="Infos Entreprise">
-                                <field name="categorie" />
-                                <field name="date_creation" />
-                                <field name="effectif" />
-                            </group>
-                            <group string="ESS">
-                                <field name="ess" />
-                            </group>
-                        </group>
-                    </page>
-                </xpath>
-            </field>
-        </record>
-    </data>
+    <!-- Client Form View -->
+    <record id="partner_form_siren_view" model="ir.ui.view">
+        <field name="name">res.partner.siren.form.view</field>
+        <field name="model">res.partner</field>
+        <field name="inherit_id" ref="base.view_partner_form" />
+        <field name="arch" type="xml">
+            <!-- ADD HEADER BUTTON -->
+            <xpath expr="//sheet" position="before">
+                <header invisible="not is_company">
+                    <button
+                        string="Pré-remplir / Mettre à jour"
+                        type="action"
+                        name="%(lefilament_siren.siren_wizard_action)d"
+                        class="oe_highlight"
+                    />
+                </header>
+            </xpath>
+        </field>
+    </record>
 </odoo>
diff --git a/wizard/wizard_siren.py b/wizard/wizard_siren.py
index 769e648845ec4ea92d5eabe1458ad0e016edc560..035736b247d20367d6926afeac4b40f048c4fd74 100644
--- a/wizard/wizard_siren.py
+++ b/wizard/wizard_siren.py
@@ -5,117 +5,123 @@ import requests
 
 from odoo import api, fields, models
 
-URL = "https://data.opendatasoft.com/api/records/1.0/"\
+URL = (
+    "https://data.opendatasoft.com/api/records/1.0/"
     "search/?dataset=economicref-france-sirene-v3%40public&q={request}&rows=100"
+)
 
 
 class SirenWizard(models.TransientModel):
-    _name = 'siren.wizard'
-    _description = 'Get values from companies'
+    _name = "siren.wizard"
+    _description = "Get values from companies"
 
     # Default functions
     @api.model
     def _default_name(self):
-        return self.env['res.partner'].browse(
-            self.env.context.get('active_id')).name
+        return self.env["res.partner"].browse(self.env.context.get("active_id")).name
 
     @api.model
     def _default_partner(self):
-        return self.env.context.get('active_id')
+        return self.env.context.get("active_id")
 
     # Fields
-    name = fields.Char(string='Entreprise', default=_default_name)
-    city = fields.Char(string='Ville')
-    company_lines = fields.One2many('siren.wizard.company',
-                                    'wizard_id', string="Résultats",)
-    partner_id = fields.Integer('Partner', default=_default_partner)
+    name = fields.Char("Recherche", default=_default_name)
+    city = fields.Char(string="Ville")
+    company_lines = fields.One2many(
+        comodel_name="siren.wizard.company",
+        inverse_name="wizard_id",
+        string="Résultats",
+    )
+    partner_id = fields.Many2one(
+        comodel_name="res.partner", string="Entreprise", default=_default_partner
+    )
 
     # Action
     @api.model
     def _prepare_partner_from_data(self, data):
         return {
-            'name': data.get('denominationunitelegale'),
-            'street': data.get('adresseetablissement', False),
-            'zip': data.get('codepostaletablissement', False),
-            'city': data.get('libellecommuneetablissement', False),
-            'siren': data.get('siren', False),
-            'siret': data.get('siret', False),
-            'categorie': data.get('categorieentreprise', False),
-            'date_creation': data.get('datecreationunitelegale',
-                                      False),
-            'ape': data.get('activiteprincipaleunitelegale', False),
-            'lib_ape': data.get('divisionunitelegale', False),
-            'forme_juridique': data.get('naturejuridiqueunitelegale', False),
-            'effectif': data.get('trancheeffectifsunitelegale', 0),
-            'ess': (True if data.get('economiesocialesolidaireunitelegale')
-                    else False),
-            'etat_etablissement': data.get(
-                'etatadministratifetablissement',
-                False),
+            "name": data.get("denominationunitelegale"),
+            "street": data.get("adresseetablissement", False),
+            "zip": data.get("codepostaletablissement", False),
+            "city": data.get("libellecommuneetablissement", False),
+            "siren": data.get("siren", False),
+            "siret": data.get("siret", False),
+            "categorie": data.get("categorieentreprise", False),
+            "date_creation": data.get("datecreationunitelegale", False),
+            "ape": data.get("activiteprincipaleunitelegale", False),
+            "lib_ape": data.get("divisionunitelegale", False),
+            "forme_juridique": data.get("naturejuridiqueunitelegale", False),
+            "effectif": data.get("trancheeffectifsunitelegale", 0),
+            "ess": (True if data.get("economiesocialesolidaireunitelegale") else False),
+            "etat_etablissement": data.get("etatadministratifetablissement", False),
         }
 
     def get_company_lines(self):
         # Get request
-        r = requests.get(URL.format(request=self.name))
+        r = requests.get(URL.format(request=self.name), timeout=15)
         # Serialization request to JSON
         companies = r.json()
         # Fill new company lines
         companies_vals = []
-        for company in companies['records']:
-            res = self._prepare_partner_from_data(company['fields'])
+        for company in companies["records"]:
+            res = self._prepare_partner_from_data(company["fields"])
             companies_vals.append((0, 0, res))
         self.company_lines.unlink()
         self.company_lines = companies_vals
         return {
-            'context': self.env.context,
-            'view_type': 'form',
-            'view_mode': 'form',
-            'res_model': 'siren.wizard',
-            'res_id': self.id,
-            'view_id': False,
-            'type': 'ir.actions.act_window',
-            'target': 'new',
+            "context": self.env.context,
+            "views": [(False, "form")],
+            "view_mode": "form",
+            "res_model": "siren.wizard",
+            "res_id": self.id,
+            "type": "ir.actions.act_window",
+            "target": "new",
         }
 
 
 class SirenWizardCompanies(models.TransientModel):
-    _name = 'siren.wizard.company'
-    _description = 'Companies Selection'
+    _name = "siren.wizard.company"
+    _description = "Companies Selection"
 
     # Fields
-    wizard_id = fields.Many2one('siren.wizard', string='Wizard',)
-    name = fields.Char(string='Nom')
-    street = fields.Char(string='Rue')
-    zip = fields.Char(string='CP')
-    city = fields.Char(string='Ville')
+    wizard_id = fields.Many2one(
+        "siren.wizard",
+        string="Wizard",
+    )
+    name = fields.Char(string="Nom")
+    street = fields.Char(string="Rue")
+    zip = fields.Char(string="CP")
+    city = fields.Char(string="Ville")
 
-    forme_juridique = fields.Char("Forme Juridique")
+    forme_juridique = fields.Char()
     siren = fields.Char("SIREN")
     siret = fields.Char("SIRET")
     ape = fields.Char("Code APE")
     lib_ape = fields.Char("Libellé APE")
     date_creation = fields.Date("Date de création")
-    effectif = fields.Char("Effectif")
+    effectif = fields.Char()
     ess = fields.Boolean("ESS", default=False)
     categorie = fields.Char("Catégorie")
     etat_etablissement = fields.Char("Etat établissement")
 
     # Action
-    @api.multi
     def update_partner(self):
-        partner = self.env['res.partner'].browse(self.wizard_id.partner_id)
-        partner.write({
-            'name': self.name,
-            'street': self.street,
-            'zip': self.zip,
-            'city': self.city,
-            'forme_juridique': self.forme_juridique,
-            'siren': self.siren,
-            'siret': self.siret,
-            'ape': self.ape,
-            'lib_ape': self.lib_ape,
-            'date_creation': self.date_creation,
-            'effectif': self.effectif,
-            'ess': self.ess,
-            'categorie': self.categorie,
-        })
+        self.ensure_one()
+        partner = self.wizard_id.partner_id
+        partner.update(
+            {
+                "name": self.name,
+                "street": self.street,
+                "zip": self.zip,
+                "city": self.city,
+                "forme_juridique": self.forme_juridique,
+                "siren": self.siren,
+                "siret": self.siret,
+                "ape": self.ape,
+                "lib_ape": self.lib_ape,
+                "date_creation": self.date_creation,
+                "effectif": self.effectif,
+                "ess": self.ess,
+                "categorie": self.categorie,
+            }
+        )
diff --git a/wizard/wizard_siren.xml b/wizard/wizard_siren.xml
index aa2e0d8032416ea6fc6e83c622dab3a425ad09c8..82fe94a9bb383b3df2dcda42e9b37bf1c6d966b6 100644
--- a/wizard/wizard_siren.xml
+++ b/wizard/wizard_siren.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="UTF-8"?>
+<?xml version="1.0" encoding="UTF-8" ?>
 <!-- Copyright 2018 Le Filament (<https://www.le-filament.com>)
      License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
 <odoo>
@@ -9,22 +9,41 @@
         <field name="arch" type="xml">
             <form string="Recherche Entreprise">
                 <p>Recherche</p>
-                    <h4>
-                        <field name="name" />
-                        <button class="btn btn-sm btn-primary" name="get_company_lines" string="Rechercher" type="object"/>
-                    </h4>
+                <h4>
+                    <field name="name" />
+                    <button
+                        class="btn btn-sm btn-primary"
+                        name="get_company_lines"
+                        string="Rechercher"
+                        type="object"
+                    />
+                </h4>
                 <field name="company_lines" readonly="True">
-                    <tree decoration-it="etat_etablissement == 'Fermé'" decoration-danger="etat_etablissement == 'Fermé'" >
+                    <list
+                        decoration-it="etat_etablissement == 'Fermé'"
+                        decoration-danger="etat_etablissement == 'Fermé'"
+                        default_order="etat_etablissement,name"
+                    >
                         <field name="name" />
                         <field name="street" />
                         <field name="zip" />
                         <field name="city" />
                         <field name="etat_etablissement" />
-                        <button class="btn btn-primary" name="update_partner" string="Sélectionner" type="object" confirm="Valider l'entreprise sélectionnée ?"/>
-                    </tree>
+                        <button
+                            class="btn btn-primary"
+                            name="update_partner"
+                            string="Sélectionner"
+                            type="object"
+                            confirm="Valider l'entreprise sélectionnée ?"
+                        />
+                    </list>
                 </field>
                 <footer>
-                    <button class="btn btn-sm btn-default" special="cancel" string="Fermer"/>
+                    <button
+                        class="btn btn-sm btn-default"
+                        special="cancel"
+                        string="Fermer"
+                    />
                 </footer>
             </form>
         </field>
@@ -36,7 +55,9 @@
         <field name="model">siren.wizard.company</field>
         <field name="arch" type="xml">
             <form string="Entreprise">
-                <h3><field name="name" /></h3>
+                <h3>
+                    <field name="name" />
+                </h3>
                 <group>
                     <group string="Coordonnées">
                         <field name="street" />
@@ -61,7 +82,13 @@
                     </group>
                 </group>
                 <footer>
-                    <button class="btn btn-sm btn-primary" name="update_partner" string="Sélectionner" type="object" confirm="Valider l'entreprise sélectionnée ?"/>
+                    <button
+                        class="btn btn-sm btn-primary"
+                        name="update_partner"
+                        string="Sélectionner"
+                        type="object"
+                        confirm="Valider l'entreprise sélectionnée ?"
+                    />
                 </footer>
             </form>
         </field>
@@ -72,8 +99,7 @@
         <field name="type">ir.actions.act_window</field>
         <field name="res_model">siren.wizard</field>
         <field name="view_mode">form</field>
-        <field name="view_id" ref="siren_wizard_view_form"/>
+        <field name="view_id" ref="siren_wizard_view_form" />
         <field name="target">new</field>
     </record>
-
-</odoo>
\ No newline at end of file
+</odoo>