diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 732d0c4a644eb444d6b4385643ff32fab19fab52..ad02204ce27c2f7c43ac83df01370f8e97ac9d0e 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -6,6 +6,8 @@ exclude: |
   ^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
@@ -25,8 +27,13 @@ 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: 7d8a9f9ad73db0976fb03cbee43d953bc29b89e9
+    rev: ab1d7f6
     hooks:
       # update the NOT INSTALLABLE ADDONS section above
       - id: oca-update-pre-commit-excluded-addons
@@ -48,10 +55,11 @@ repos:
     hooks:
       - id: black
   - repo: https://github.com/pre-commit/mirrors-prettier
-    rev: v2.6.2
+    rev: v2.1.2
     hooks:
       - id: prettier
         name: prettier (with plugin-xml)
+        exclude: ^datas/
         additional_dependencies:
           - "prettier@2.1.2"
           - "@prettier/plugin-xml@0.12.0"
@@ -59,7 +67,7 @@ repos:
           - --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: v8.15.0
+    rev: v7.8.1
     hooks:
       - id: eslint
         verbose: true
@@ -67,7 +75,7 @@ repos:
           - --color
           - --fix
   - repo: https://github.com/pre-commit/pre-commit-hooks
-    rev: v4.2.0
+    rev: v3.2.0
     hooks:
       - id: trailing-whitespace
         # exclude autogenerated files
@@ -89,37 +97,33 @@ repos:
       - id: mixed-line-ending
         args: ["--fix=lf"]
   - repo: https://github.com/asottile/pyupgrade
-    rev: v2.32.1
+    rev: v2.7.2
     hooks:
       - id: pyupgrade
         args: ["--keep-percent-format"]
   - repo: https://github.com/PyCQA/isort
-    rev: 5.10.1
+    rev: 5.12.0
     hooks:
       - id: isort
         name: isort except __init__.py
         args:
           - --settings=.
         exclude: /__init__\.py$
-  - repo: https://gitlab.com/PyCQA/flake8
-    rev: 3.9.2
+  - 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: v2.11.1
+  - 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==5.0.5
-      - id: pylint
-        name: pylint with mandatory checks
+      - id: pylint_odoo
         args:
           - --rcfile=.pylintrc-mandatory
-        additional_dependencies: *pylint_deps
diff --git a/datas/mail_data.xml b/datas/mail_data.xml
index 08bd158bcb4b4cabb8f1c5eaf408cc008905978c..33542d366ed5c7403c8a703656ff5a77f2e8dce0 100644
--- a/datas/mail_data.xml
+++ b/datas/mail_data.xml
@@ -4,48 +4,56 @@
         <!-- Email d'avis de prélèvement -->
         <record id="email_template_payment_order" model="mail.template">
             <field name="name">CG SCOP : Prélèvements</field>
-            <field
-                name="model_id"
-                ref="account_payment_order.model_account_payment_order"
-            />
-            <field
-                name="email_from"
-            >"Confédération Générale des Scop et Scic" &lt;administratif.cg@scop.coop&gt;</field>
-            <field
-                name="reply_to"
-            >"Confédération Générale des Scop et Scic" &lt;administratif.cg@scop.coop&gt;</field>
+            <field name="model_id" ref="account_payment_order.model_account_payment_order"/>
+            <field name="email_from">"Confédération Générale des Scop et Scic" &lt;administratif.cg@scop.coop&gt;</field>
+            <field name="reply_to">"Confédération Générale des Scop et Scic" &lt;administratif.cg@scop.coop&gt;</field>
             <field name="partner_to">${object.get_recipients()}</field>
             <field name="subject">CG SCOP : Avis de prélèvement</field>
             <field name="body_html" type="html">
                 <div style="margin: 0px; padding: 0px;">
                     <p style="margin: 0px; padding: 0px; font-size: 13px;">
+                        <p>${object.get_email_values().get("partner_id").member_number} - ${object.get_email_values().get("partner_id").name}</p>
+                        <p>&#160;</p>
                         <p>Chère Coopératrice, Cher Coopérateur,</p>
                         <p>&#160;</p>
-                        <p
-                        >Vous avez choisi de régler vos cotisations à la Confédération générale des Scop et des Scic par prélèvement bancaire.</p>
-                        <p
-                        >Nous vous informons que nous allons procéder le ${object.get_email_values().get("date").strftime('%d/%m/%Y')} à un prélèvement sur votre compte ${object.get_email_values().get("bank")} de ${format_amount(object.get_email_values().get("total"), object.company_currency_id)}</p>
+                        <p>&#160;</p>
+                        <p>
+                            Vous avez choisi de régler vos cotisations à la Confédération générale des Scop et des Scic par prélèvement bancaire.
+                        </p>
+                        <p>
+                            Nous vous informons que nous avons procédé ce jour à un ordre de prélèvement qui sera présenté au débit de votre compte le ${object.get_email_values().get("date").strftime('%d/%m/%Y')}.
+                        </p>
+                        <p>&#160;</p>
+                        <p>
+                            Le mandat de prélèvement enregistré pour votre coopérative est le suivant : ${object.get_email_values().get("bank")}
+                        </p>
+                        <p>&#160;</p>
+                        <p>
+                            Ce courriel vous est envoyé à titre informatif, l’ordre de prélèvement ne peut plus être arrêté en banque, sauf par vos soins en prenant contact avec votre établissement bancaire.
+                        </p>
+                        <p>Dans ce cas, nous vous remercions de bien vouloir nous en informer.</p>
+                        <p>&#160;</p>
+                        <p>
+                            En cas de difficulté économique, nous vous invitons également à vous rapprocher de votre délégation régionale.
+                        </p>
                         <p>&#160;</p>
                         <p>
                             Ce prélèvement correspond au paiement des cotisations :
                             <ul>
                                 % for line in object.get_email_values().get("deadline"):
-                                % set quarter = "er" if line.get("cotiz_quarter") == "1" else "ème"
+                                % set quarter = "er" if line.get("quarter") == "1" else "ème"
                                 <li>
-                                    ${line.get("cotiz_quarter")}${quarter} Trimestre ${line.get("year")} : ${format_amount(line.get("amount_total_signed"), object.company_currency_id)}
+                                    ${line.get("quarter")}${quarter} Trimestre ${line.get("year")} : ${format_amount(line.get("amount"), object.company_currency_id)}
                                 </li>
                                 % endfor
                             </ul>
                         </p>
                         <p>&#160;</p>
-                        <p
-                        >Nous vous rappelons que les bordereaux de cotisations sont désormais mis à disposition dans <a
-                                href="https://extranet.scop.coop/"
-                            >votre espace extranet</a> et ne sont plus transmis par courrier.</p>
                         <p>
-                            Pour toute question relative à vos cotisations appelées par la CGSCOP, notre équipe est à votre disposition par téléphone au 01 44 85 47 00 ou par courriel à <a
-                                href="mailto:administratif.cg@scop.coop"
-                            >administratif.cg@scop.coop</a>.
+                            Nous vous rappelons que les bordereaux de cotisations sont mis à disposition dans <a href="https://extranet.scop.coop/">votre espace extranet</a> et ne sont plus transmis par courrier.
+                        </p>
+                        <p>
+                            Pour toute question relative à vos cotisations appelées par la CGSCOP, notre équipe est à votre disposition par téléphone au 01 44 85 47 00 ou par courriel à <a href="mailto:administratif.cg@scop.coop">administratif.cg@scop.coop</a>.
                         </p>
                         <p>&#160;</p>
                         <p
diff --git a/models/account_banking_mandate.py b/models/account_banking_mandate.py
index 46bad68f689611c2be1c1194393878dde9530f42..c8c423648d82ea4ea95217337fc9dfeb73d72472 100644
--- a/models/account_banking_mandate.py
+++ b/models/account_banking_mandate.py
@@ -49,10 +49,12 @@ class AccountBankingMandate(models.Model):
         Affecte le mandat courant pur la facture passée en paramètre
         :param invoice : objet account.move
         """
-        payment_mode = self.env["account.payment.mode"].search([
-            ("payment_method_id.code", "=", "sepa_direct_debit"),
-            ("company_id", "=", self.env.company.id)
-        ])
+        payment_mode = self.env["account.payment.mode"].search(
+            [
+                ("payment_method_id.code", "=", "sepa_direct_debit"),
+                ("company_id", "=", self.env.company.id),
+            ]
+        )
         if not payment_mode:
             raise UserError(_("Aucun mode de prélèvement SEPA configuré."))
 
@@ -70,9 +72,10 @@ class AccountBankingMandate(models.Model):
         Supprime le mandat courant pur la facture passée en paramètre
         :param invoice : objet account.move
         """
-        payment_mode = self.env["account.payment.mode"].search([
-            ("name", "ilike", "Virement"), ("company_id", "=", self.env.company.id)
-        ], limit=1)
+        payment_mode = self.env["account.payment.mode"].search(
+            [("name", "ilike", "Virement"), ("company_id", "=", self.env.company.id)],
+            limit=1,
+        )
         for invoice in invoice_ids:
             invoice.update(
                 {
diff --git a/models/account_payment_order.py b/models/account_payment_order.py
index 1c817dc143a8111dc671d16b01f669b6b8fda36d..b388710c1a6bf8a5e9d510c054862815c15d878f 100644
--- a/models/account_payment_order.py
+++ b/models/account_payment_order.py
@@ -1,6 +1,8 @@
 # Copyright 2020 Le Filament
 # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
 
+from itertools import groupby
+
 from odoo import _, fields, models
 from odoo.exceptions import UserError, ValidationError
 
@@ -33,8 +35,11 @@ class AccountPaymentOrder(models.Model):
 
     def _compute_bank_line_amount(self):
         for po in self:
-            po.bank_line_amount = sum(po.payment_ids.filtered(
-                lambda p: not p.reversed_entry_id).mapped("amount_total_signed"))
+            po.bank_line_amount = sum(
+                po.payment_ids.filtered(lambda p: not p.reversed_entry_id).mapped(
+                    "amount_total_signed"
+                )
+            )
 
     def _compute_attachment_ids(self):
         Attachment = self.env["ir.attachment"]
@@ -124,11 +129,7 @@ class AccountPaymentOrder(models.Model):
         try:
             template = self.env.ref("cgscop_cotisation.email_template_payment_order")
         except Exception:
-            raise UserError(
-                _(
-                    "Aucun modèle d'e-mail n'a été trouvé."
-                )
-            )
+            raise UserError(_("Aucun modèle d'e-mail n'a été trouvé."))
         # Get partners
         partner_ids = self.payment_line_ids.mapped("partner_id")
         for partner in partner_ids:
@@ -178,20 +179,32 @@ class AccountPaymentOrder(models.Model):
         partner_line_ids = self.payment_line_ids.filtered(
             lambda l: l.partner_id == partner_id
         )
-        invoice_ids = partner_line_ids.mapped("move_line_id.move_id").filtered(
-            "is_contribution"
-        )
+
+        quarter_detail = []
+        quarter_agg = []
+        for line in partner_line_ids:
+            invoice_id = line.move_line_id.move_id
+            quarter_detail.append(
+                ("%s-%s" % (invoice_id.year, invoice_id.cotiz_quarter), line.amount_currency)
+            )
+        quarter_detail.sort(key=lambda x: x[0])
+
+        for quarter, values in groupby(quarter_detail, key=lambda x: x[0]):
+            amount = 0
+            for val in values:
+                amount += val[1]
+            quarter_agg.append({
+                "year": quarter[0:4],
+                "quarter": quarter[-1],
+                "amount": amount,
+            })
+
         return {
+            "partner_id": partner_id,
             "total": sum(partner_line_ids.mapped("amount_currency")),
             "date": partner_line_ids.mapped("date")[0],
             "bank": partner_line_ids.mapped("partner_bank_id.acc_number")[0],
-            "deadline": invoice_ids.read_group(
-                domain=[("id", "in", invoice_ids.ids)],
-                fields=["year", "cotiz_quarter", "amount_total_signed"],
-                groupby=["year", "cotiz_quarter"],
-                orderby="year,cotiz_quarter",
-                lazy=False,
-            ),
+            "deadline": quarter_agg,
         }
 
     def get_recipients(self):
diff --git a/views/account_payment_order.xml b/views/account_payment_order.xml
index 8d4c7924076463fcd68b24928431afca19b6f34e..0a4df285278d2ae37ddf578ab43012f5008cdabf 100644
--- a/views/account_payment_order.xml
+++ b/views/account_payment_order.xml
@@ -134,18 +134,35 @@
 <!--                                />-->
                             </tree>
                             <form>
-                                <h1><field name="name"/></h1>
+                                <h1><field name="name" /></h1>
                                 <group>
                                     <group>
-                                        <field name="datas" filename="name" attrs="{'invisible':[('type','=','url')]}" string="Télécharger le fichier"/>
-                                        <field name="name" invisible="1" attrs="{'invisible':[('type','=','url')]}" class="oe_inline oe_right"/>
-                                        <field name="url" widget="url" attrs="{'invisible':[('type','=','binary')]}"/>
-                                        <field name="mimetype" groups="base.group_no_one"/>
-                                        <field name="type"/>
+                                        <field
+                                            name="datas"
+                                            filename="name"
+                                            attrs="{'invisible':[('type','=','url')]}"
+                                            string="Télécharger le fichier"
+                                        />
+                                        <field
+                                            name="name"
+                                            invisible="1"
+                                            attrs="{'invisible':[('type','=','url')]}"
+                                            class="oe_inline oe_right"
+                                        />
+                                        <field
+                                            name="url"
+                                            widget="url"
+                                            attrs="{'invisible':[('type','=','binary')]}"
+                                        />
+                                        <field
+                                            name="mimetype"
+                                            groups="base.group_no_one"
+                                        />
+                                        <field name="type" />
                                     </group>
                                     <group>
-                                        <field name="create_uid"/>
-                                        <field name="create_date"/>
+                                        <field name="create_uid" />
+                                        <field name="create_date" />
                                     </group>
                                 </group>
                             </form>
diff --git a/wizard/scop_deces_wizard.py b/wizard/scop_deces_wizard.py
index d2954c0b3ea0b3f2c7ab883dd9a93c4425ec296a..6f41eb0dd52fd367e8fb2ae801e0867d3873db7e 100644
--- a/wizard/scop_deces_wizard.py
+++ b/wizard/scop_deces_wizard.py
@@ -20,10 +20,12 @@ class ScopDecesWizard(models.TransientModel):
         if mandate_ids:
             for mandate in mandate_ids:
                 mandate.update({"state": "expired"})
-                invoice_ids = self.env["account.move"].search([
-                    ("mandate_id", "=", mandate.id),
-                    ("move_type", "in", ("out_invoice", "out_refund")),
-                    ("state", "in", ("draft", "posted")),
-                    ("payment_state", "in", ("draft", "not_paid", "partial")),
-                ])
+                invoice_ids = self.env["account.move"].search(
+                    [
+                        ("mandate_id", "=", mandate.id),
+                        ("move_type", "in", ("out_invoice", "out_refund")),
+                        ("state", "in", ("draft", "posted")),
+                        ("payment_state", "in", ("draft", "not_paid", "partial")),
+                    ]
+                )
                 mandate._remove_invoice_mandate(invoice_ids)