diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 168470e2ed745631aefb772a4a864cf1de76d3cb..c575299fc05d609e25260193f2b663be50d0fd31 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -16,7 +16,7 @@ exclude: |
   (LICENSE.*|COPYING.*)
 default_language_version:
   python: python3
-  node: "14.18.0"
+  node: "16.17.0"
 repos:
   - repo: local
     hooks:
@@ -27,15 +27,20 @@ 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: dfba427ba03900b69e0a7f2c65890dc48921d36a
+    rev: 4cd2b852214dead80822e93e6749b16f2785b2fe
     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
+    rev: v1.6.1
     hooks:
       - id: autoflake
         args:
@@ -46,22 +51,22 @@ repos:
           - --remove-duplicate-keys
           - --remove-unused-variables
   - repo: https://github.com/psf/black
-    rev: 22.3.0
+    rev: 22.8.0
     hooks:
       - id: black
   - repo: https://github.com/pre-commit/mirrors-prettier
-    rev: v2.4.1
+    rev: v2.7.1
     hooks:
       - id: prettier
         name: prettier (with plugin-xml)
         additional_dependencies:
-          - "prettier@2.4.1"
-          - "@prettier/plugin-xml@1.1.0"
+          - "prettier@2.7.1"
+          - "@prettier/plugin-xml@2.2.0"
         args:
           - --plugin=@prettier/plugin-xml
         files: \.(css|htm|html|js|json|jsx|less|md|scss|toml|ts|xml|yaml|yml)$
   - repo: https://github.com/pre-commit/mirrors-eslint
-    rev: v7.32.0
+    rev: v8.24.0
     hooks:
       - id: eslint
         verbose: true
@@ -69,7 +74,7 @@ repos:
           - --color
           - --fix
   - repo: https://github.com/pre-commit/pre-commit-hooks
-    rev: v4.0.1
+    rev: v4.3.0
     hooks:
       - id: trailing-whitespace
         # exclude autogenerated files
@@ -91,12 +96,12 @@ repos:
       - id: mixed-line-ending
         args: ["--fix=lf"]
   - repo: https://github.com/asottile/pyupgrade
-    rev: v2.29.0
+    rev: v2.38.2
     hooks:
       - id: pyupgrade
         args: ["--keep-percent-format"]
   - repo: https://github.com/PyCQA/isort
-    rev: 5.9.3
+    rev: 5.10.1
     hooks:
       - id: isort
         name: isort except __init__.py
diff --git a/.pylintrc b/.pylintrc
index d431ca78d44080ba32c20c6991c2655f2ab6423b..71c476d4f10ac08a7333729b93705c9573d240d5 100644
--- a/.pylintrc
+++ b/.pylintrc
@@ -1,3 +1,5 @@
+
+
 [MASTER]
 load-plugins=pylint_odoo
 score=n
@@ -8,7 +10,7 @@ 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=15.0
+valid_odoo_versions=16.0
 
 [MESSAGES CONTROL]
 disable=all
@@ -96,6 +98,7 @@ enable=anomalous-backslash-in-string,
     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,
diff --git a/.pylintrc-mandatory b/.pylintrc-mandatory
index 189c548631665bef116fc4d0df3b986f9727df31..ed2c2171ffe63ac191e30ed0759c4b6211ad5f15 100644
--- a/.pylintrc-mandatory
+++ b/.pylintrc-mandatory
@@ -1,3 +1,4 @@
+
 [MASTER]
 load-plugins=pylint_odoo
 score=n
@@ -8,7 +9,7 @@ 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=15.0
+valid_odoo_versions=16.0
 
 [MESSAGES CONTROL]
 disable=all
@@ -88,7 +89,8 @@ enable=anomalous-backslash-in-string,
     website-manifest-key-not-valid-uri,
     xml-attribute-translatable,
     xml-deprecated-qweb-directive,
-    xml-deprecated-tree-attribute
+    xml-deprecated-tree-attribute,
+    external-request-timeout
 
 [REPORTS]
 msg-template={path}:{line}: [{msg_id}({symbol}), {obj}] {msg}
diff --git a/__manifest__.py b/__manifest__.py
index cfe161219722a6eb2af6efa171bc39649fdb3b35..42f1ce755dd42450165fb0a4ce9584527affe842 100644
--- a/__manifest__.py
+++ b/__manifest__.py
@@ -1,6 +1,6 @@
 {
     "name": "Le Filament - Training",
-    "version": "15.0.1.0.0",
+    "version": "16.0.1.0.0",
     "summary": "Training sessions managment",
     "license": "AGPL-3",
     "author": "Le Filament",
diff --git a/models/training_training.py b/models/training_training.py
index ed742afdf310a5bf38803afb8154d1ae5dd41913..2dbccb2dc398290caa31081eccc0ec9420fb661b 100644
--- a/models/training_training.py
+++ b/models/training_training.py
@@ -104,10 +104,11 @@ class Training(models.Model):
     # ------------------------------------------------------
     # Override ORM
     # ------------------------------------------------------
-    @api.model
-    def create(self, vals):
-        record = super(Training, self).create(vals)
-        if vals.get("course_id", False):
+    @api.model_create_multi
+    @api.returns("self", lambda value: value.id)
+    def create(self, vals_list):
+        records = super(Training, self).create(vals_list)
+        for record in records.filtered("course_id"):
             for s in record.course_id.session_ids:
                 self.env["training.session"].create(
                     {
@@ -117,10 +118,11 @@ class Training(models.Model):
                         "sequence": s.sequence,
                     }
                 )
-        return record
+        return records
 
     def write(self, vals):
-        record = super(Training, self).write(vals)
+        res = super(Training, self).write(vals)
+        # If we modify the course, then we delete and recreate sessions
         if vals.get("course_id", False):
             self.session_ids.unlink()
             for s in self.course_id.session_ids:
@@ -132,7 +134,7 @@ class Training(models.Model):
                         "sequence": s.sequence,
                     }
                 )
-        return record
+        return res
 
     # ------------------------------------------------------
     # compute