diff --git a/__manifest__.py b/__manifest__.py
index 3c94d6b7fcf96213a024f4a877635154552a8f02..09e96df5398bb489d9cb21320540f9bbce31175a 100755
--- a/__manifest__.py
+++ b/__manifest__.py
@@ -25,6 +25,8 @@
         "views/res_config_settings.xml",
         "views/scop_bordereau_cg.xml",
         "views/scop_cotisation_cg.xml",
+        "views/scop_cotisation_simulation.xml",
+        "views/scop_liasse_fiscale.xml",
         "wizard/export_journal_wizard_view.xml",
         "wizard/scop_cotisation_cg_wizard.xml",
         "wizard/scop_bordereau_update_confirm_view.xml",
diff --git a/models/__init__.py b/models/__init__.py
index c7c3521d1bd6b94ce2b5b45f226de0f61ae76f0e..14a36e45970b8b7d70501ae26d038f07fc6e1863 100755
--- a/models/__init__.py
+++ b/models/__init__.py
@@ -5,4 +5,6 @@ from . import account_invoice
 from . import res_company
 from . import res_config_settings
 from . import scop_bordereau_cg
+from . import scop_cotisation_simulation
 from . import scop_cotisation_cg
+from . import scop_liasse_fiscale
diff --git a/models/scop_cotisation_cg.py b/models/scop_cotisation_cg.py
index 0c8811a8d755eb063f3230ce2f8ba288b02cb172..3e3410e97a63e607e5047b6614a45c005c3651ac 100644
--- a/models/scop_cotisation_cg.py
+++ b/models/scop_cotisation_cg.py
@@ -1,9 +1,12 @@
 # © 2021 Le Filament (<http://www.le-filament.com>)
 # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
 
+import base64
 import json
 import logging
 import threading
+import xlsxwriter
+from io import BytesIO
 
 from odoo import models, fields, api, exceptions, registry
 
@@ -20,6 +23,11 @@ class ScopCotisation(models.Model):
         compute='_compute_name',
         store=True)
 
+    simul_ids = fields.One2many(
+        comodel_name='scop.cotisation.cg.simulation',
+        inverse_name='cotisation_id',
+        string='Simulations')
+
     invoice_ids = fields.One2many(
         comodel_name='account.invoice',
         inverse_name='cotisation_cg_id',
@@ -36,31 +44,12 @@ class ScopCotisation(models.Model):
 
     state = fields.Selection([
         ('new', 'Brouillon'),
-        ('ongoing', 'Instruction'),
+        ('ongoing', 'En cours'),
         ('end', 'Clôturé')],
         string="Statut", default='new',
         compute='_compute_state',
         store=True, track_visibility='onchange',)
 
-    amount_cg = fields.Monetary(
-        string="Montant CG Scop", currency_field='company_currency_id',
-        compute='_compute_amount_cotiz_cg')
-    amount_fede_com = fields.Monetary(
-        string="Montant Fédé de la Com", currency_field='company_currency_id',
-        compute='_compute_amount_cotiz_cg')
-    amount_fede_cae = fields.Monetary(
-        string="Montant Fédé CAE", currency_field='company_currency_id',
-        compute='_compute_amount_cotiz_cg')
-    amount_ur_hdf = fields.Monetary(
-        string="Montant UR HDF", currency_field='company_currency_id',
-        compute='_compute_amount_cotiz_cg')
-    amount_ur_med = fields.Monetary(
-        string="Montant UR Pyrénées", currency_field='company_currency_id',
-        compute='_compute_amount_cotiz_cg')
-    amount_total = fields.Monetary(
-        string="Montant total", compute="_compute_amount_total",
-        currency_field='company_currency_id')
-
     invoice_count = fields.Integer(
         string='Appels de cotisations émis',
         compute='_compute_real')
@@ -108,48 +97,6 @@ class ScopCotisation(models.Model):
                 cotiz.year,
                 dict(self._fields['state'].selection).get(cotiz.state))
 
-    @api.multi
-    def _compute_amount_cotiz_cg(self):
-        for cotiz in self:
-            type_contribution_cg = cotiz.env.ref('cgscop_partner.riga_14397')
-            cotiz_cg = cotiz.invoice_ids.filtered(
-                lambda i: i.type_contribution_id == type_contribution_cg)
-
-            type_contribution_fede_com = cotiz.env.ref(
-                'cgscop_partner.riga_14398')
-            cotiz_fede_com = cotiz.invoice_ids.filtered(
-                lambda i: i.type_contribution_id == type_contribution_fede_com)
-
-            type_contribution_fede_cae = cotiz.env.ref(
-                'cgscop_partner.cotiz_fede_cae')
-            cotiz_fede_cae = cotiz.invoice_ids.filtered(
-                lambda i: i.type_contribution_id == type_contribution_fede_cae)
-
-            type_contribution_ur = cotiz.env.ref('cgscop_partner.riga_14399')
-            cotiz_ur = cotiz.invoice_ids.filtered(
-                lambda i: i.type_contribution_id == type_contribution_ur)
-
-            ur_hdf = cotiz.env.ref('cgscop_partner.riga_14232')
-            cotiz_hdf = cotiz_ur.filtered(lambda i: i.partner_ur_id == ur_hdf)
-
-            ur_med = cotiz.env.ref('cgscop_partner.riga_14243')
-            cotiz_med = cotiz_ur.filtered(lambda i: i.partner_ur_id == ur_med)
-
-            cotiz.amount_cg = sum(cotiz_cg.mapped("amount_total"))
-            cotiz.amount_fede_com = sum(cotiz_fede_com.mapped("amount_total"))
-            cotiz.amount_fede_cae = sum(cotiz_fede_cae.mapped("amount_total"))
-            cotiz.amount_ur_hdf = sum(cotiz_hdf.mapped("amount_total"))
-            cotiz.amount_ur_med = sum(cotiz_med.mapped("amount_total"))
-
-    @api.multi
-    def _compute_amount_total(self):
-        for cotiz in self:
-            cotiz.amount_total = (cotiz.amount_cg +
-                                  cotiz.amount_fede_com +
-                                  cotiz.amount_fede_cae +
-                                  cotiz.amount_ur_hdf +
-                                  cotiz.amount_ur_med)
-
     @api.multi
     def _compute_amount_called(self):
         for cotiz in self:
@@ -237,6 +184,10 @@ class ScopCotisation(models.Model):
             raise exceptions.UserError(
                 "La cotisation CG Scop n'est pas configurée.")
 
+        if not self.trimester_1 or not self.trimester_2 or not self.trimester_3 or not self.trimester_4:
+            raise exceptions.UserError(
+                "Les trimestres doivent être configurés pour lancer les cotisations.")
+
         # List of members already invoiced
         member_invoiced = self.invoice_ids.mapped('partner_id')
 
@@ -252,8 +203,6 @@ class ScopCotisation(models.Model):
                     "</h3> <hr/>" +
                     "Nombre d'adhérents renouvelés : " +
                     str(self.member_count) +
-                    # "<br/>Nombre de nouveaux adhérents : " +
-                    # str(self.new_member_count) +
                     "<br/>Bordereaux déjà générées non vides : " +
                     str(self.invoiced_member_count) +
                     "<br/>Bordereaux à générer : " +
@@ -293,6 +242,10 @@ class ScopCotisation(models.Model):
         }
 
     def cotiz_generate_wizard(self):
+        if not self.trimester_1 or not self.trimester_2 or not self.trimester_3 or not self.trimester_4:
+            raise exceptions.UserError(
+                "Les trimestres doivent être configurés pour lancer les cotisations.")
+
         wizard = self.env['scop.cotisation.cg.wizard'].create({
             'year': self.year,
             'cotisation_cg_id': self.id,
@@ -439,6 +392,226 @@ class ScopCotisation(models.Model):
             'target': 'new'
         }
 
+    def add_simul(self):
+        """
+        Ajoute une simulation à la base de cotisation pour l'année donnée.
+        Cette simulation est sous la forme d'un fichier Excel avec le détail
+        des cotisations par coopératives.
+
+        @return: object scop.cotisation.cg.simulation
+        """
+        # Get context
+        type_simul = self.env.context.get('type_simul')
+
+        # Get contribution type
+        type_cotisation_cg = self.env.ref('cgscop_partner.riga_14397')
+
+        # Get product type
+        InvoiceLine = self.env['account.invoice.line']
+        product_cg_id = self.company_id.contribution_cg_id
+        product_com_id = self.company_id.contribution_fede_com_id
+        product_cae_id = self.company_id.contribution_fede_cae_id
+        product_hdf_id = self.company_id.contribution_hdf_id
+        product_med_id = self.company_id.contribution_med_id
+
+        # List of members
+        members = self.get_members()
+
+        header = [
+            'N° Adhérent',
+            'Union Régionale',
+            'Forme Coopérative',
+            'Organisme',
+            'Type de cotisation',
+            'Cotisation ' + str(self.year),
+            'Cotisation ' + str(self.year - 1),
+            'Assiette',
+            'Montant Assiette',
+            'Année Liasse',
+            'CA sens CG Scop',
+            'VABDF sens CG Scop',
+            'Salaires sens CG Scop',
+            'Résultat',
+            'Dernier effectif connu',
+            'Moyen de paiement'
+        ]
+
+        # Init variables
+        datas = []
+        total_cg = total_hdf = total_com = total_med = total_cae = 0
+        count_member = 0
+
+        for m in self.web_progress_iter(members, msg="cotisations calculées"):
+            liasse = self.get_liasse(m)
+            line_ids = InvoiceLine.search([
+                ('partner_id', '=', m.id),
+                ('invoice_id.state', 'not in', ('draft', 'cancel')),
+                ('invoice_id.year', '=', self.year - 1)
+            ])
+
+            # Calcul Cotisation CG Scop
+            net_results = liasse.L2053_HN \
+                if liasse.L2053_HN > 0 else liasse.L2051_DI
+            contrib_cg = self.round_to_closest_multiple(
+                liasse.contribution_cg, 4) if liasse else 300
+            contribution_amount = contrib_cg
+            contribution_name = type_cotisation_cg.name
+
+            # Calcul cotisation N-1
+            contribution_last_year = sum(line_ids.filtered(
+                lambda l: l.product_id == product_cg_id).mapped('price_subtotal_signed'))
+
+            # Construction Tableau
+            datas_contrib = [
+                m.member_number,
+                m.ur_id.name,
+                m.cooperative_form_id.name,
+                m.name,
+                contribution_name,
+                contribution_amount,
+                contribution_last_year,
+                liasse.contribution_base_type.upper() if liasse else 'CA',
+                liasse.contribution_base_amount,
+                liasse.year,
+                liasse.revenue_cg,
+                liasse.av_cg,
+                liasse.wage_cg,
+                net_results,
+                m.staff_last,
+                m.customer_payment_mode_id.name if m.customer_payment_mode_id else 'Virement/Chèque',
+            ]
+
+            # Ajout ligne CG Scop
+            datas.append(datas_contrib)
+
+            if type_simul == 'all':
+                # Ajout ligne UR HDF
+                ur_hdf = self.env.ref('cgscop_partner.riga_14232')
+                if m.ur_id == ur_hdf:
+                    # Calcul cotisation
+                    contrib_hdf = self.round_to_closest_multiple(
+                        liasse.contribution_hdf, 4) if liasse else 40
+                    # Calcul cotisation N-1
+                    contribution_last_year = sum(line_ids.filtered(
+                        lambda l: l.product_id == product_hdf_id).mapped('price_subtotal_signed'))
+                    datas_contrib[4] = 'Cotisation UR HDF'
+                    datas_contrib[5] = contrib_hdf
+                    datas_contrib[6] = contribution_last_year
+                    datas.append(datas_contrib)
+                    total_hdf += contrib_hdf
+
+                # Ajout ligne UR Med
+                ur_med = self.env.ref('cgscop_partner.riga_14243')
+                if m.ur_id == ur_med:
+                    # Calcul cotisation
+                    contrib_med = self.round_to_closest_multiple(
+                        liasse.contribution_med, 4) if liasse else 0
+                    # Calcul cotisation N-1
+                    contribution_last_year = sum(line_ids.filtered(
+                        lambda l: l.product_id == product_med_id).mapped('price_subtotal_signed'))
+                    datas_contrib[4] = 'Cotisation UR Méditerranée'
+                    datas_contrib[5] = contrib_med
+                    datas_contrib[6] = contribution_last_year
+                    datas.append(datas_contrib)
+                    total_med += contrib_med
+
+                # Ajout ligne Fédération Com
+                if m.is_federation_com:
+                    # Calcul cotisation
+                    if liasse:
+                        contrib_fede_com = self.round_to_closest_multiple(
+                            liasse.contribution_com, 4)
+                    else:
+                        staff_id = self.get_last_staff_id(liasse.partner_id)
+                        if staff_id.staff_average > 0:
+                            contrib_fede_com = staff_id.staff_average * 108
+                        else:
+                            contrib_fede_com = staff_id.staff_count * 108
+                        if contrib_fede_com < 108:
+                            contrib_fede_com = 108
+                    # Calcul cotisation N-1
+                    contribution_last_year = sum(line_ids.filtered(
+                        lambda l: l.product_id == product_com_id).mapped('price_subtotal_signed'))
+                    datas_contrib[4] = 'Cotisation Fédération de la Com'
+                    datas_contrib[5] = contrib_fede_com
+                    datas_contrib[6] = contribution_last_year
+                    datas.append(datas_contrib)
+                    total_com += contrib_fede_com
+
+                # Ajout ligne Fédération CAE
+                if m.is_federation_cae:
+                    contrib_fede_cae = 100
+                    # Calcul cotisation N-1
+                    contribution_last_year = sum(line_ids.filtered(
+                        lambda l: l.product_id == product_cae_id).mapped('price_subtotal_signed'))
+                    datas_contrib[4] = 'Cotisation Fédération des CAE'
+                    datas_contrib[5] = contrib_fede_cae
+                    datas_contrib[6] = contribution_last_year
+                    datas.append(datas_contrib)
+                    total_cae += contrib_fede_cae
+
+            count_member += 1
+            total_cg += contrib_cg
+
+        # Génération du ficher Excel
+        file_name = 'Simulation cotisations ' + str(self.year) + '.xlsx'
+        output = BytesIO()
+        workbook = xlsxwriter.Workbook(output, {'in_memory': True})
+        worksheet1 = workbook.add_worksheet('Données brutes')
+
+        # Intégration Header
+        format_header = workbook.add_format(
+            {'bg_color': '#eeeeee', 'font_color': '#333333', 'bold': True})
+        for col, h in enumerate(header):
+            worksheet1.write(0, col, h, format_header)
+
+        # Intégration datas
+        format_monetary = workbook.add_format(
+            {'num_format': '#,##0 [$€-407]'})
+        for row, contrib in enumerate(datas):
+            for col, value in enumerate(contrib):
+                worksheet1.write(row + 1, col, value)
+
+        # Format columns
+        worksheet1.set_column(0, 0, 10, None)
+        worksheet1.set_column(1, 1, 30, None)
+        worksheet1.set_column(2, 2, 15, None)
+        worksheet1.set_column(3, 3, 50, None)
+        worksheet1.set_column(4, 4, 25, None)
+        worksheet1.set_column(5, 6, 20, format_monetary)
+        worksheet1.set_column(8, 13, 20, format_monetary)
+        worksheet1.set_column(14, 14, 15, None)
+        worksheet1.set_column(15, 15, 20, None)
+
+        # Enregistrement du fichier dans la base
+        workbook.close()
+        output.seek(0)
+        mem_bytes = output.read()
+        file_base64 = base64.b64encode(mem_bytes)
+
+        simul_id = self.simul_ids.create({
+            'cotisation_id': self.id,
+            'file': file_base64,
+            'filename': file_name,
+            'type_simul': type_simul,
+            'total_member': count_member,
+            'total_cg': total_cg,
+            'total_hdf': total_hdf,
+            'total_com': total_com,
+            'total_cae': total_cae,
+            'total_med': total_med,
+        })
+
+        return {
+            'name': 'Simulation cotisation',
+            'type': 'ir.actions.act_window',
+            'view_mode': 'form',
+            'res_model': 'scop.cotisation.cg.simulation',
+            'res_id': simul_id.id,
+            'target': 'new',
+            'flags': {'mode': 'readonly', 'default_buttons': False}
+        }
+
     # ------------------------------------------------------
     # Global functions
     # ------------------------------------------------------
@@ -593,6 +766,19 @@ class ScopCotisation(models.Model):
     # Calcul des cotisations
     # ------------------------------------------------------
     def get_cotiz_cg(self, partner, bordereau):
+        """
+            Appelle la fonction de calcul de la cotisation CG Scop
+            à partir des variables du bordereau
+        """
+
+        type_assiette = bordereau.type_assiette_retenu
+        ca = self.check_dureeExercice(
+            bordereau.ca_retenu, bordereau.dureeExercice)
+        va = self.check_dureeExercice(
+            bordereau.va_cg_retenu, bordereau.dureeExercice)
+        return self.calc_cotiz_cg(partner, ca, va, type_assiette)
+
+    def calc_cotiz_cg(self, partner, ca, va, type_assiette):
         """
             Calcule la cotisation de la CG Scop :
             - VA = VA saisie ou VA au sens CGSCOP si pas de VA renseignée
@@ -607,11 +793,6 @@ class ScopCotisation(models.Model):
             @return float : cotisation
         """
         values = self.get_values_for_cotiz_cg(partner)
-        type_assiette = bordereau.type_assiette_retenu
-        ca = self.check_dureeExercice(
-            bordereau.ca_retenu, bordereau.dureeExercice)
-        va = self.check_dureeExercice(
-            bordereau.va_cg_retenu, bordereau.dureeExercice)
         if type_assiette == 'ca':
             rate = self.get_rate_ca(partner)
             cotiz = ca * rate
diff --git a/models/scop_cotisation_simulation.py b/models/scop_cotisation_simulation.py
new file mode 100644
index 0000000000000000000000000000000000000000..03d1e9d535bd59b1a766065420e71b4644e8602a
--- /dev/null
+++ b/models/scop_cotisation_simulation.py
@@ -0,0 +1,32 @@
+# © 2021 Le Filament (<http://www.le-filament.com>)
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
+
+import json
+import logging
+import threading
+
+from odoo import models, fields, api, exceptions, registry
+
+_logger = logging.getLogger(__name__)
+
+
+class ScopCotisation(models.Model):
+    _name = "scop.cotisation.cg.simulation"
+    _description = "Simulation cotisations CG"
+
+    cotisation_id = fields.Many2one(
+        comodel_name='scop.cotisation.cg',
+    )
+
+    file = fields.Binary('Fichier')
+    filename = fields.Char()
+    type_simul = fields.Selection(
+        selection=[('all', 'Toutes les cotisation'), ('cgscop', 'Cotisations CG Scop')],
+        string='Type de simulation'
+    )
+    total_member = fields.Integer('Nombre Adhérents')
+    total_cg = fields.Float('Total CG Scop')
+    total_hdf = fields.Float('Total UR HDF')
+    total_med = fields.Float('Total UR Med')
+    total_com = fields.Float('Total Fédération Com')
+    total_cae = fields.Float('Total Fédération CAE')
diff --git a/models/scop_liasse_fiscale.py b/models/scop_liasse_fiscale.py
new file mode 100644
index 0000000000000000000000000000000000000000..24e6d72f302f82ab58cd1ed1fd0da291368e1e92
--- /dev/null
+++ b/models/scop_liasse_fiscale.py
@@ -0,0 +1,301 @@
+# © 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, fields, api
+
+
+class ScopLiasseFiscale(models.Model):
+    _inherit = "scop.liasse.fiscale"
+
+    contribution_cg = fields.Float(
+        string='Cotisation CG Scop',
+        compute='_compute_contribution_cg',
+        store=True)
+    contribution_base_type = fields.Selection(
+        string='Type Assiette de cotisation',
+        selection=[('ca', 'CA'),
+                   ('va', 'VA'), ],
+        compute='_compute_contribution_cg',
+        store=True)
+    contribution_base_amount = fields.Integer(
+        string='Montant Assiette de cotisation',
+        compute='_compute_contribution_cg',
+        store=True)
+    contribution_hdf = fields.Float(
+        string='Cotisation UR HDF',
+        compute='_compute_contribution_hdf',
+        store=True)
+    contribution_med = fields.Float(
+        string='Cotisation UR Méditerranée',
+        compute='_compute_contribution_med',
+        store=True)
+    contribution_com = fields.Float(
+        string='Cotisation Fédération Com',
+        compute='_compute_contribution_com',
+        store=True)
+
+    # ------------------------------------------------------
+    # Compute fields
+    # ------------------------------------------------------
+    @api.depends('av_lf', 'av_cg', 'revenue_cg')
+    @api.multi
+    def _compute_contribution_cg(self):
+        """
+            Calcule la cotisation de la CG Scop :
+            - VA = VA saisie ou VA au sens CGSCOP si pas de VA renseignée
+            - 0,3% du CA ou 0,7% de la VA
+            - 300 € pour CA compris entre 0 et 100 K€
+            - 600 € pour CA compris entre 100 et 200 K€
+            - Max = 375 K€
+
+            @return float : cotisation
+        """
+        for liasse in self:
+            # Calcul VA
+            va = liasse.av_lf if liasse.av_lf > 0 else liasse.av_cg
+            ca = liasse.revenue_cg
+            if liasse.dureeExercice and liasse.dureeExercice not in (0, 12):
+                va = va * (12 / liasse.dureeExercice)
+                ca = ca * (12 / liasse.dureeExercice)
+
+            # Calcul Type Assiette
+            if ca > 0 and va > 0:
+                if ca <= va * 7 / 3:
+                    contribution_base_type = 'ca'
+                    contribution_base_amount = ca
+                else:
+                    contribution_base_type = 'va'
+                    contribution_base_amount = va
+            else:
+                if va > 0:
+                    contribution_base_type = 'va'
+                    contribution_base_amount = va
+                else:
+                    contribution_base_type = 'ca'
+                    contribution_base_amount = ca
+
+            liasse.contribution_base_type = contribution_base_type
+            liasse.contribution_base_amount = contribution_base_amount
+
+            # Calcul valeurs plancher
+            values = self.get_values_for_cotiz_cg(liasse.partner_id)
+
+            # Calcul Cotisation CG Scop
+            if contribution_base_type == 'ca':
+                rate = self.get_rate_ca(liasse.partner_id)
+                contribution = ca * rate
+            else:
+                rate = self.get_rate_va(liasse.partner_id)
+                contribution = va * rate
+
+            if contribution < values['plancher1']:
+                liasse.contribution_cg = values['plancher1']
+            elif contribution < values['plancher2']:
+                liasse.contribution_cg = values['plancher2']
+            elif contribution >= values['plancher3']:
+                if contribution_base_type == 'ca':
+                    contribution = (25000000 * rate) + (ca - 25000000) * (rate / 2)
+                else:
+                    cotiz = (10714286 * rate) + (va - 10714286) * (rate / 2)
+                if contribution <= values['plafond']:
+                    liasse.contribution_cg = cotiz
+                else:
+                    liasse.contribution_cg = values['plafond']
+            else:
+                liasse.contribution_cg = contribution
+
+    @api.depends('wage_cg')
+    @api.multi
+    def _compute_contribution_hdf(self):
+        """
+            Calcule la cotisation de l'UR HDF pour 1 partenaire :
+            - 0,1 % de la masse salariale annuelle brute prévisionnelle
+            ou figurant sur la liasse fiscale.
+
+            @return float : cotisation
+        """
+        ur_hdf = self.env.ref('cgscop_partner.riga_14232')
+        for liasse in self:
+            if liasse.partner_id.ur_id == ur_hdf:
+                rate = 0.001
+                plancher = 40
+                if liasse.dureeExercice and liasse.dureeExercice not in (0, 12):
+                    wage_cg = liasse.wage_cg * (12/liasse.dureeExercice)
+                else:
+                    wage_cg = liasse.wage_cg
+                if wage_cg > 0:
+                    contribution_hdf = wage_cg * rate
+                else:
+                    contribution_hdf = 0
+
+                if contribution_hdf > plancher:
+                    liasse.contribution_hdf = contribution_hdf
+                else:
+                    liasse.contribution_hdf = plancher
+
+    @api.depends('av_lf', 'av_cg')
+    @api.multi
+    def _compute_contribution_com(self):
+        """
+            Calcule la cotisation de la fédération de la com pour 1 partenaire
+            - Assiette annuelle : VA saisie ou VA au sens CGSCOP
+            - Taux : 0.0032
+            - Calcul : Valeur Ajoutée * 0.0032
+            - Pour les nouvelles coopératives (pas de comptes annuels) :
+                108 € par salarié (effectif moyen s’il est saisi, à défaut
+                effectif), soit 27 € par salarié et par trimestre.
+            - Plancher annuel : 108 €
+            - Plafond annuel : 18 428 €
+
+            @return float : cotisation
+        """
+        plancher = 108
+        plafond = 18428
+        rate = 0.0032
+        for liasse in self:
+            if liasse.partner_id.is_federation_com:
+                # Calcul VA
+                va = liasse.av_lf if liasse.av_lf > 0 else liasse.av_cg
+
+                # Calcul VA proratisée
+                if liasse.dureeExercice and liasse.dureeExercice not in (0, 12):
+                    va = va * (12 / liasse.dureeExercice)
+                else:
+                    va = va
+
+                # Calcul effectifs
+                staff_id = self.get_last_staff_id(liasse.partner_id)
+                if staff_id:
+                    staff_average = staff_id.staff_average
+                    staff_count = staff_id.staff_count
+                else:
+                    staff_average = 0
+                    staff_count = 0
+
+                # Calcul cotisation
+                if va != 0:
+                    contribution_com = va * rate
+                else:
+                    if staff_average > 0:
+                        contribution_com = staff_average * plancher
+                    else:
+                        contribution_com = staff_count * plancher
+                if plancher <= contribution_com <= plafond:
+                    liasse.contribution_com = contribution_com
+                elif contribution_com < plancher:
+                    liasse.contribution_com = plancher
+                else:
+                    liasse.contribution_com = plafond
+
+    @api.depends('contribution_cg', 'L2053_HN')
+    @api.multi
+    def _compute_contribution_med(self):
+        """
+            Calcule la cotisation de l'UR Med pour 1 liasse :
+            - Assiette : Assiette de la cotisation CGSCOP
+            - Taux d’appel : 1/3 du taux
+            - Calcul intermédiaire : Assiette * taux
+                (soit 1/3 de la cotisation CGSCOP sans plancher)
+            - Complément de cotisation : 1% du résultat net si positif
+            - Abattement pour sociétariat :
+                Taux de sociétariat =   nombre de salariés sociétaires /
+                                        nombre de salariés
+                Abattement 20 % si >= 50 %
+                Abattement 30 % si >= 80 %
+            - Calcul cotisations :
+                [(Assiette*taux) + (résultat net *0.01)]* (1 ou 0.8 ou 0.7)
+
+            @return float : cotisation
+        """
+        ur_med = self.env.ref('cgscop_partner.riga_14243')
+        for liasse in self:
+            if liasse.partner_id.ur_id == ur_med:
+                # Assiette CG
+                assiette_rate = 1/3
+                assiette = liasse.contribution_cg
+
+                # Résultat net
+                net_results_rate = 0.01
+                net_results = liasse.L2053_HN if liasse.L2053_HN > 0 else liasse.L2051_DI
+                if liasse.dureeExercice and liasse.dureeExercice not in (0, 12):
+                    net_results = net_results * (12/liasse.dureeExercice)
+
+                # Effectifs
+                staff_id = self.get_last_staff_id(liasse.partner_id)
+                if staff_id:
+                    staff_shareholder_count = staff_id.staff_shareholder_count
+                    staff_count = staff_id.staff_count
+                else:
+                    staff_shareholder_count = staff_count = 0
+
+                # Taux d'abattement pour sociétariat
+                if staff_count > 0:
+                    societariat_rate = staff_shareholder_count / staff_count
+                else:
+                    societariat_rate = 0
+
+                if 0.5 <= societariat_rate < 0.8:
+                    abatt_rate = 1 - 0.2
+                elif societariat_rate >= 0.8:
+                    abatt_rate = 1 - 0.3
+                else:
+                    abatt_rate = 1 - 0
+
+                # Calcul Cotisation
+                contribution_med = ((assiette * assiette_rate) +
+                         (net_results * net_results_rate)) * abatt_rate
+                final_contribution_med = contribution_med if contribution_med >= 0 else 0
+                liasse.contribution_med = final_contribution_med
+
+    # ------------------------------------------------------
+    # Business Function
+    # ------------------------------------------------------
+    def get_values_for_cotiz_cg(self, partner):
+        # Calcul des Taux SCOP en fonction du type
+        plancher1 = 300
+        plancher2 = 600
+        plancher3 = 75000
+        plafond = 375000
+        if partner.cooperative_form_id in (
+                self.env.ref('cgscop_partner.form_coop47'),
+                self.env.ref('cgscop_partner.form_lamaneur')):
+            plancher1 = 1 / 3 * plancher1
+            plancher2 = 1 / 3 * plancher2
+            plancher3 = 1 / 3 * plancher3
+            plafond = 1 / 3 * plafond
+
+        return {
+            'plancher1': plancher1,
+            'plancher2': plancher2,
+            'plancher3': plancher3,
+            'plafond': plafond,
+        }
+
+    def get_rate_ca(self, partner):
+        # Calcul des Taux SCOP en fonction du type
+        if partner.cooperative_form_id in (
+                self.env.ref('cgscop_partner.form_coop47'),
+                self.env.ref('cgscop_partner.form_lamaneur')):
+            rate_ca = 0.002
+        else:
+            rate_ca = 0.003
+        return rate_ca
+
+    def get_rate_va(self, partner):
+        # Calcul des Taux SCOP en fonction du type
+        if partner.cooperative_form_id in (
+                self.env.ref('cgscop_partner.form_coop47'),
+                self.env.ref('cgscop_partner.form_lamaneur')):
+            rate_va = 0.0047
+        else:
+            rate_va = 0.007
+        return rate_va
+
+    def get_last_staff_id(self, partner):
+        """
+        Return last known staff_id line
+        :param partner:
+        :return:
+        """
+        staff_id = partner.staff_ids.sorted(key=lambda l: l.effective_date)
+        return staff_id[-1] if len(staff_id) > 1 else staff_id
\ No newline at end of file
diff --git a/security/ir.model.access.csv b/security/ir.model.access.csv
index eb297e129b283e04a98adc2c4776d4c16daa6df1..68bfdfbe3ce217b57d6aa7c62b09d3b8bf20a629 100755
--- a/security/ir.model.access.csv
+++ b/security/ir.model.access.csv
@@ -1,4 +1,6 @@
 id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
+access_scop_cotisation_simulation,access_scop_cotisation_simulation,model_scop_cotisation_cg_simulation,account.group_account_manager,1,1,1,1
+admin_access_scop_cotisation_simulation,admin_access_scop_cotisation_simulation,model_scop_cotisation_cg_simulation,cgscop_partner.group_cg_administrator,1,1,1,1
 access_scop_cotisation_cg,access_scop_cotisation_cg,model_scop_cotisation_cg,account.group_account_manager,1,1,1,0
 admin_access_scop_cotisation_cg,admin_access_scop_cotisation_cg,model_scop_cotisation_cg,cgscop_partner.group_cg_administrator,1,1,1,1
 access_scop_bordereau,access_scop_bordereau,model_scop_bordereau,account.group_account_manager,1,1,1,1
diff --git a/views/scop_cotisation_cg.xml b/views/scop_cotisation_cg.xml
index 239e050abdf06d5a01513c22927fdaaee6fada2f..354cd086444c317c963ca3455e8818dd7a32a27a 100644
--- a/views/scop_cotisation_cg.xml
+++ b/views/scop_cotisation_cg.xml
@@ -14,7 +14,6 @@
                     <field name="year"/>
                     <field name="name"/>
                     <field name="create_date"/>
-                    <field name="amount_cg"/>
                     <field name="state"/>
                     <field name="member_count"/>
                     <field name="write_date"/>
@@ -42,7 +41,7 @@
                         <group>
                             <group name="contribution" string="Cotisations">
                                 <field name="year"/>
-                                <field name="date_cotisation" attrs="{'readonly': [('state', '!=', 'new')]}"/>
+                                <field name="date_cotisation" attrs="{'readonly': [('state', '!=', 'new')], 'required': [('state', '!=', 'new')]}"/>
                                 <field name="create_date"/>
                                 <field name="write_date"/>
                                 <field name="payment_term_id"/>
@@ -50,28 +49,32 @@
                             <group name="count_contribution" string="Adhérents">
                                 <field name="member_count" readonly="1"/>
                                 <field name="new_member_count" readonly="1"/>
-                                <field name="invoiced_member_count" readonly="1" string="Bordereaux générés non vides"/>
                                 <field name="invoice_count" readonly="1"/>
                                 <field name="invoice_valid_count" readonly="1"/>
                             </group>
                         </group>
                         <group>
-                            <group name="simulation" string="Simulation">
-                                <field name="amount_cg" readonly="1" widget="monetary"/>
-                                <field name="amount_fede_com" readonly="1" widget="monetary"/>
-                                <field name="amount_fede_cae" readonly="1" widget="monetary"/>
-                                <field name="amount_ur_hdf" readonly="1" widget="monetary"/>
-                                <field name="amount_ur_med" readonly="1" widget="monetary"/>
-                                <hr/>
-                                <field name="amount_total" readonly="1" widget="monetary"/>
-                            </group>
                             <group name="schedule" string="Échéancier">
-                                <field name="trimester_1" required="1"/>
-                                <field name="trimester_2" required="1"/>
-                                <field name="trimester_3" required="1"/>
-                                <field name="trimester_4" required="1"/>
+                                <field name="trimester_1" attrs="{'required': [('state', '!=', 'new')]}"/>
+                                <field name="trimester_2" attrs="{'required': [('state', '!=', 'new')]}"/>
+                                <field name="trimester_3" attrs="{'required': [('state', '!=', 'new')]}"/>
+                                <field name="trimester_4" attrs="{'required': [('state', '!=', 'new')]}"/>
                             </group>
                         </group>
+                        <notebook>
+                            <page name="simulation" string="Simulations">
+                                <h5>Ajouter une simulation :</h5>
+                                <hr/>
+                                <button name="add_simul" class="btn btn-outline-info" style="margin-right: 20px; width: 250px;"
+                                        type="object" string="Globale : CG, UR et Fédération"
+                                        attrs="{'invisible': [('state', '!=', 'new')]}" context="{'type_simul': 'all'}"/>
+
+                                <button name="add_simul" class="btn btn-outline-info" style="width: 250px;"
+                                        type="object" string="CG Scop uniquement"
+                                        attrs="{'invisible': [('state', '!=', 'new')]}" context="{'type_simul': 'cgscop'}"/>
+                                <field name="simul_ids"/>
+                            </page>
+                        </notebook>
                     </sheet>
                 </form>
             </field>
@@ -88,10 +91,8 @@
                     <field name="state"/>
                     <field name="member_count"/>
                     <field name="new_member_count"/>
-                    <field name="invoiced_member_count"/>
                     <field name="percent_cotiz_paid"/>
                     <field name="graph_values"/>
-                    <field name="amount_total"/>
                     <field name="amount_called"/>
                     <field name="amount_paid"/>
                     <field name="amount_residual"/>
@@ -106,7 +107,6 @@
                                             <p class="text-muted">
                                                 Nombre d'adhérents renouvelés : <field name="member_count"/> <br />
                                                 Nombre de nouveaux adhérents : <field name="new_member_count"/> <br />
-                                                Nombre d'adhérents facturés : <field name="invoiced_member_count"/>
                                             </p>
                                         </t>
                                     </div>
@@ -122,10 +122,6 @@
                                     <div class="col-6">
                                         <table class="table table-bordered">
                                             <tbody>
-                                                <tr>
-                                                    <td>Montant théorique</td>
-                                                    <td><field name="amount_total"/> €</td>
-                                                </tr>
                                                 <tr>
                                                     <td>Montant appelé</td>
                                                     <td><field name="amount_called"/> €</td>
diff --git a/views/scop_cotisation_simulation.xml b/views/scop_cotisation_simulation.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7e5f1753174d46b2f947feedd8ec4f4d9f89505b
--- /dev/null
+++ b/views/scop_cotisation_simulation.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0"?>
+<!-- Copyright 2019 Le Filament
+     License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
+
+<odoo>
+    <data>
+
+        <!-- Tree view -->
+        <record id="view_scop_cotisation_cg_simulation_tree" model="ir.ui.view">
+            <field name="name">scop.cotisation.cg.simulation.tree</field>
+            <field name="model">scop.cotisation.cg.simulation</field>
+            <field name="arch" type="xml">
+                <tree string="Simulations" create="0" edit="0">
+                    <field name="create_date" string="Date de création"/>
+                    <field name="type_simul"/>
+                    <field name="file"  string="Fichier"/>
+                    <field name="total_member"/>
+                    <field name="total_cg"/>
+                    <field name="total_hdf"/>
+                    <field name="total_med"/>
+                    <field name="total_com"/>
+                    <field name="total_cae"/>
+                </tree>
+            </field>
+        </record>
+
+        <!-- Form view -->
+        <record id="view_scop_cotisation_cg_simulation_form" model="ir.ui.view">
+            <field name="name">scop.cotisation.cg.simulation.form</field>
+            <field name="model">scop.cotisation.cg.simulation</field>
+            <field name="arch" type="xml">
+                <form>
+                    <sheet>
+                        <group>
+                            <group string="Fichier simulation">
+                                <field name="create_date" string="Date de création"/>
+                                <field name="type_simul" readonly="1"/>
+                                <field name="file"  filename="filename" readonly="1"/>
+                                <field name="filename"  invisible="1"/>
+                            </group>
+                            <group string="Données globales">
+                                <field name="total_member" readonly="1"/>
+                                <field name="total_cg" readonly="1"/>
+                                <field name="total_hdf" readonly="1"/>
+                                <field name="total_med" readonly="1"/>
+                                <field name="total_com" readonly="1"/>
+                                <field name="total_cae" readonly="1"/>
+                            </group>
+                        </group>
+                    </sheet>
+                </form>
+            </field>
+        </record>
+
+
+        <record id="view_scop_cotisation_cg_simulation_action" model="ir.actions.act_window">
+            <field name="name">Simulation Cotisation</field>
+            <field name="type">ir.actions.act_window</field>
+            <field name="res_model">scop.cotisation.cg.simulation</field>
+            <field name="view_mode">form</field>
+        </record>
+
+
+    </data>
+</odoo>
diff --git a/views/scop_liasse_fiscale.xml b/views/scop_liasse_fiscale.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2f5260ea5c31affedcb7e9f3ff0faad1a6a7b363
--- /dev/null
+++ b/views/scop_liasse_fiscale.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+<!-- Copyright 2021 Le Filament
+     License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
+
+<odoo>
+    <data>
+
+        <!-- Form view -->
+        <record id="view_scop_liasse_fiscale_simulation_form" model="ir.ui.view">
+            <field name="name">scop.liasse.fiscale.contribution.form</field>
+            <field name="model">scop.liasse.fiscale</field>
+            <field name="inherit_id" ref="cgscop_liste_ministere.scop_liasse_fiscale_form_view_prio"/>
+            <field name="arch" type="xml">
+                <xpath expr="//form" position="inside">
+                    <hr/>
+                    <div class="alert alert-info" role="alert">
+                        <strong><u>Cotisations théoriques</u></strong><br/>
+                        Cette section donne les montants théoriques des diverses cotisations en fonction des valeurs de la liasse fiscale.
+                    </div>
+                    <group name="simulation">
+                        <group>
+                            <field name="contribution_base_type" string="Type Assiette"/>
+                            <field name="contribution_base_amount" string="Montant Assiette"/>
+                            <field name="contribution_cg" string="Cotisation CG Scop"/>
+                        </group>
+                        <group>
+                            <field name="contribution_hdf" string="Cotisation HDF"/>
+                            <field name="contribution_med" string="Cotisation Méditerranée"/>
+                            <field name="contribution_com" string="Cotisation Fédération Com"/>
+                        </group>
+                    </group>
+                </xpath>
+            </field>
+        </record>
+    </data>
+</odoo>