diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 1c6434bfc2274c73d98dbf62b6de9baccdc353ce..4acca684ec8c5cda7b3ecd21b9e568ab03d57e8c 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -27,6 +27,11 @@ repos:
         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: ab1d7f6
     hooks:
@@ -46,7 +51,7 @@ repos:
           - --remove-duplicate-keys
           - --remove-unused-variables
   - repo: https://github.com/psf/black
-    rev: 20.8b1
+    rev: 22.3.0
     hooks:
       - id: black
   - repo: https://github.com/pre-commit/mirrors-prettier
@@ -96,32 +101,28 @@ repos:
       - id: pyupgrade
         args: ["--keep-percent-format"]
   - repo: https://github.com/PyCQA/isort
-    rev: 5.5.1
+    rev: 5.12.0
     hooks:
       - id: isort
         name: isort except __init__.py
         args:
           - --settings=.
         exclude: /__init__\.py$
-  - repo: https://gitlab.com/PyCQA/flake8
+  - repo: https://github.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
+  - repo: https://github.com/OCA/pylint-odoo
+    rev: 7.0.2
     hooks:
-      - id: pylint
+      - id: pylint_odoo
         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
+      - id: pylint_odoo
         args:
           - --rcfile=.pylintrc-mandatory
-        additional_dependencies: *pylint_deps
diff --git a/__init__.py b/__init__.py
index 957992f377d7ce8942a87238397684babc5eb305..11671ffaead3d4042e93185d6ee1d4b81a032dd5 100644
--- a/__init__.py
+++ b/__init__.py
@@ -1,4 +1,4 @@
 # Copyright 2021 Le Filament (<http://www.le-filament.com>)
 # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
 
-from . import models
+from . import models, wizard
diff --git a/models/res_partner.py b/models/res_partner.py
index 121d888c6b72618768ae74a3464af0e977f6c84c..78047823e055cae8519b6920125fd928ea4ee875 100644
--- a/models/res_partner.py
+++ b/models/res_partner.py
@@ -3,7 +3,8 @@
 
 from pytz import timezone
 
-from odoo import fields, models
+from odoo import _, fields, models
+from odoo.exceptions import UserError
 
 
 class ScopAlfrescoAdhesionPartner(models.Model):
@@ -67,36 +68,79 @@ class ScopAlfrescoAdhesionPartner(models.Model):
         }
 
     def check_docs_adhesion(self):
-        compulsory_docs = self.get_compulsory_docs()
-        missing_docs = self.check_compulsory_docs()
-        html = str()
-        for doc in compulsory_docs:
-            html += "<input type='checkbox'"
-            if doc.name not in missing_docs:
-                html += "checked"
-            html += "/> " + doc.name + "<br/>"
-        local_tz = timezone("Europe/Paris")
-        utc_tz = timezone("UTC")
-        html += (
-            "<hr/>Vérifié le "
-            + "<strong>"
-            + utc_tz.localize(fields.Datetime.now())
-            .astimezone(local_tz)
-            .strftime("%d/%m/%Y à %-H:%M")
-            + "</strong>"
-        )
-        self.log_missing_docs = html
+        self.scop_check_docs("adhesion")
 
     # ------------------------------------------------------
     # Business method
     # ------------------------------------------------------
-    def get_compulsory_docs(self):
-        return self.env["scop.adhesion.file"].search(
-            [
-                ("coop_type_id", "=", self.cooperative_form_id.id),
-                ("is_compulsory", "=", True),
-            ]
+    def get_compulsory_docs(self, type_process):
+        domain = [
+            ("coop_type_id", "=", self.cooperative_form_id.id),
+            ("is_compulsory", "=", True),
+            ("type_process", "=", type_process),
+        ]
+
+        return self.env["scop.adhesion.file"].search(domain)
+
+    def scop_check_docs(self, type_process, error_type=""):
+        """
+        Return error message for mandatory documents
+        :param str type_process: scop.adhesion.file type_process
+        :param str error_type: scop.adhesion.file type_process
+        """
+        errors = str()
+        compulsory_docs = self.get_compulsory_docs(type_process)
+        # Remove KBIS for registration in progress
+        if type_process == "project" and self.is_registration_in_progress:
+            compulsory_docs = compulsory_docs.filtered(lambda d: d.type_doc != "KBI")
+        # Get loaded docs
+        loaded_docs = self.compulsory_doc_cmis_query()
+
+        errors_complete_docs = self.check_compulsory_docs(compulsory_docs, loaded_docs)
+        if errors_complete_docs:
+            errors_str = str()
+            for error in errors_complete_docs:
+                errors_str += "<li>" + error + "</li>"
+            errors += (
+                "<hr/><strong>Documents manquants :</strong><ul>" + errors_str + "</ul>"
+            )
+        # Si des erreurs remplir les logs avec la liste des documents manquants
+        if errors:
+            local_tz = timezone("Europe/Paris")
+            utc_tz = timezone("UTC")
+            log_date = (
+                utc_tz.localize(fields.Datetime.now())
+                .astimezone(local_tz)
+                .strftime("%d/%m/%Y %-H:%M")
+            )
+            self.list_logs = "<strong>%s</strong> %s %s" % (
+                log_date,
+                error_type,
+                errors,
+            )
+        else:
+            self.list_logs = False
+
+    def check_compulsory_docs(self, compulsory_docs, loaded_docs):
+        """
+        Override function to check docs with cmis query
+        :param obj compulsory_docs: scop.adhesion.file object
+        :param list loaded_docs: cmis query response
+        @returns list: list of missing mandatory documents
+        """
+        errors = list()
+
+        compulsory_docs_list = compulsory_docs.mapped(
+            lambda d: {"name": d.name, "metadata": d.type_doc}
+        )
+        loaded_docs_list = list(
+            map(lambda d: d.properties.get("crm:type"), loaded_docs)
         )
+        for mandatory_doc in compulsory_docs_list:
+            if mandatory_doc.get("metadata") not in loaded_docs_list:
+                errors.append(mandatory_doc.get("name"))
+
+        return errors
 
     # ------------------------------------------------------
     # Override parent
@@ -166,23 +210,46 @@ class ScopAlfrescoAdhesionPartner(models.Model):
 
         return res
 
-    def check_compulsory_docs(self):
+    def scop_suivi_adhesion(self):
         """
-        Override function to check docs with cmis query
-        :return:
+        Inherit parent to check documents
         """
-        errors = list()
-        compulsory_docs = self.get_compulsory_docs()
-        loaded_docs = self.env["scop.adhesion.file"].compulsory_doc_cmis_query(self)
+        # vérification des documents obligatoires
+        self.scop_check_docs("project", "Impossible de créer la coopérative")
 
-        compulsory_docs_list = compulsory_docs.mapped(
-            lambda d: {"name": d.name, "metadata": d.type_doc}
-        )
-        loaded_docs_list = list(
-            map(lambda d: d.properties.get("crm:type"), loaded_docs)
-        )
-        for mandatory_doc in compulsory_docs_list:
-            if mandatory_doc.get("metadata") not in loaded_docs_list:
-                errors.append(mandatory_doc.get("name"))
+        return super(ScopAlfrescoAdhesionPartner, self).scop_suivi_adhesion()
 
-        return errors
+    def scop_sumbit_cg(self):
+        """
+        Inherit parent to check documents
+        """
+        res = super(ScopAlfrescoAdhesionPartner, self).scop_sumbit_cg()
+        return res
+
+    # ------------------------------------------------------
+    # Alfresco method
+    # ------------------------------------------------------
+    def compulsory_doc_cmis_query(self):
+        self.ensure_one()
+        backend = self.env["cmis.backend"].search([])
+        backend.ensure_one()
+        cmis_client = backend.get_cmis_client()
+        query = (
+            """
+                    SELECT * FROM crm:document as d
+                    JOIN crm:organisme as o ON d.cmis:objectId = o.cmis:objectId
+                    WHERE o.crm:id = '%s'"""
+            % self.id
+        )
+        try:
+            doc = cmis_client.getDefaultRepository().query(query)
+            result = doc.getResults()
+            return result
+        except Exception as e:
+            raise UserError(
+                _(
+                    "Impossible de vérifier les documents d'adhésion"
+                    " dans Alfresco : %s"
+                )
+                % e
+            )
diff --git a/models/scop_adhesion_file.py b/models/scop_adhesion_file.py
index 3005cbe3dfc625fe9f06dc52ed4a1600b7b796ea..62fd4e2637d670a7f00b79197d09f6bb3b944590 100644
--- a/models/scop_adhesion_file.py
+++ b/models/scop_adhesion_file.py
@@ -1,7 +1,7 @@
 # © 2021 Le Filament (<http://www.le-filament.com>)
 # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
 
-from odoo import _, exceptions, fields, models
+from odoo import fields, models
 
 
 class ScopAdhesionFiles(models.Model):
@@ -9,30 +9,3 @@ class ScopAdhesionFiles(models.Model):
     _description = "Documents pour adhésion des coops"
 
     type_doc = fields.Char("Méta : Type")
-
-    # ------------------------------------------------------
-    # Business method
-    # ------------------------------------------------------
-    def compulsory_doc_cmis_query(self, partner):
-        backend = self.env["cmis.backend"].search([])
-        backend.ensure_one()
-        cmis_client = backend.get_cmis_client()
-        query = (
-            """
-                    SELECT * FROM crm:document as d
-                    JOIN crm:organisme as o ON d.cmis:objectId = o.cmis:objectId
-                    WHERE o.crm:id = '%s'"""
-            % partner.id
-        )
-        try:
-            doc = cmis_client.getDefaultRepository().query(query)
-            result = doc.getResults()
-            return result
-        except Exception as e:
-            raise exceptions.UserError(
-                _(
-                    "Impossible de vérifier les documents d'adhésion"
-                    " dans Alfresco : %s"
-                )
-                % e
-            )
diff --git a/views/res_partner.xml b/views/res_partner.xml
index 2fc93ccfc63790f28a5221ac0851b2441d0ee412..22c00e03102cffa03639fe20ac18739592b879a1 100644
--- a/views/res_partner.xml
+++ b/views/res_partner.xml
@@ -22,12 +22,12 @@
                         type="object"
                         name="check_docs_adhesion"
                         class="btn-info mb-10"
-                        attrs="{'invisible': [('project_status', '!=', '4_adhesion')]}"
+                        attrs="{'invisible': [('membership_status', '!=', 'adhesion')]}"
                     />
                     <div
                         class="alert alert-info mt16"
                         role="alert"
-                        attrs="{'invisible':['|', '|', ('write_date', '=', False), ('log_missing_docs', '=', False), ('project_status', '!=', '4_adhesion')]}"
+                        attrs="{'invisible':['|', '|', ('write_date', '=', False), ('log_missing_docs', '=', False), ('membership_status', '!=', 'adhesion')]}"
                     >
                         <field
                             class="o_field_header"
diff --git a/wizard/__init__.py b/wizard/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..fa7df483ff99190683a7c026cbfa48aa75d25cde
--- /dev/null
+++ b/wizard/__init__.py
@@ -0,0 +1,4 @@
+# Copyright 2021 Le Filament (<http://www.le-filament.com>)
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
+
+from . import scop_membership_submit_wizard
diff --git a/wizard/scop_membership_submit_wizard.py b/wizard/scop_membership_submit_wizard.py
new file mode 100644
index 0000000000000000000000000000000000000000..ef06b11720aeedbd387fa2dbb8b6dd6c611db05a
--- /dev/null
+++ b/wizard/scop_membership_submit_wizard.py
@@ -0,0 +1,23 @@
+# © 2021 Le Filament (<http://www.le-filament.com>)
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
+
+from odoo import models
+
+
+class ScopMembershipSubmitWizard(models.TransientModel):
+    _inherit = "scop.membership.submit.wizard"
+
+    # ------------------------------------------------------
+    # Compute
+    # ------------------------------------------------------
+    def _compute_list_logs(self):
+        super(ScopMembershipSubmitWizard, self)._compute_list_logs()
+        # vérification des documents obligatoires
+        self.partner_id.scop_check_docs(
+            "adhesion", "Impossible de transmettre le dossier d'adhésion"
+        )
+        if not self.list_logs:
+            self.list_logs = self.partner_id.list_logs
+        else:
+            if self.partner_id.list_logs:
+                self.list_logs = self.partner_id.list_logs + self.list_logs