diff --git a/__init__.py b/__init__.py
index 0650744f6bc69b9f0b865e8c7174c813a5f5995e..aa3b1de85c711057427efc896571a5cc9a75dd1b 100644
--- a/__init__.py
+++ b/__init__.py
@@ -1 +1,5 @@
+# Copyright 2023 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 wizards
diff --git a/__manifest__.py b/__manifest__.py
index c2f9c7dc250f6ef28ca6046674e817ee75d3b62b..fa2324b8b61a3845f7f5b005aaf65fd0d77d8e22 100644
--- a/__manifest__.py
+++ b/__manifest__.py
@@ -5,14 +5,15 @@
     "website": "https://le-filament.com",
     "version": "16.0.1.0.0",
     "license": "AGPL-3",
-    "depends": ["api_enedis", "oacc"],
+    "depends": ["api_enedis", "oacc", "queue_job"],
     "data": [
-        # "security/ir.model.access.csv",
+        "security/ir.model.access.csv",
         # datas
         # views
         "views/acc_operation_views.xml",
         # views menu
         # wizard
+        "wizards/acc_operation_wizard_views.xml"
     ],
     "assets": {
         "web._assets_primary_variables": [],
diff --git a/models/acc_operation.py b/models/acc_operation.py
index 0fb76b770136f03b2a5e82175c3f963099e55c3a..67ea361ab329ec27f44b659b3cf927d10ee0ad34 100644
--- a/models/acc_operation.py
+++ b/models/acc_operation.py
@@ -1,7 +1,9 @@
 # Copyright 2023 Le Filament (<http://www.le-filament.com>)
 # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
 import logging
-from datetime import date
+import pytz
+
+from datetime import date, datetime
 
 from odoo import _, fields, models
 from odoo.exceptions import UserError
@@ -38,88 +40,38 @@ class AccOperation(models.Model):
     # ------------------------------------------------------
     # CRUD methods (ORM overrides)
     # ------------------------------------------------------
-    # @api.model
-    # def _auto_get_enedis_data(self):
-    #     """This method is called from a cron job.
-    #     It is used to get data from Enedis with API.
-    #     """
-    #     day_birthday = date.today() - relativedelta(months=1, days=10)
-    #     records = self.search(
-    #         [
-    #             ("birthday_date", "=", day_birthday.day),
-    #             ("client_id", "!=", False),
-    #             ("secret_id", "!=", False),
-    #         ]
-    #     )
-    #     for rec in records:
-    #         last_date = day_birthday + relativedelta(months=1, days=-1)
-    #         token = self.access_token()
-    #         rec.get_curves(day_birthday, last_date, token)
 
     # ------------------------------------------------------
     # Actions
     # ------------------------------------------------------
-    # def get_curves(self, date_start, date_end, token=None):
-    #     # Ask token to API
-    #     if not token:
-    #         token = self.access_token()
-    #
-    #     # Création du lot
-    #     batch_name = (
-    #         "Courbes du "
-    #         + str(date_start)
-    #         + " au "
-    #         + str(date_end)
-    #         + " - Opération :"
-    #         + str(self.name)
-    #     )
-    #     batch = self.env["queue.job.batch"].get_new_batch(batch_name)
-    #     # Load consommation data by PRM
-    #     for delivery_counter_id in self.acc_delivery_ids:
-    #         # Mise en file d'attente des appels API consommateur
-    #         self.with_context(job_batch=batch).with_delay().definitive_load_curves(
-    #             date_start, date_end, delivery_counter_id, token=token
-    #         )
-    #
-    #     # Load production data by PRM
-    #     for injection_counter_id in self.acc_injection_ids:
-    #         # Mise en file d'attente des appels API producteur
-    #         self.with_context(job_batch=batch).with_delay().definitive_load_curves(
-    #             date_start, date_end, injection_counter_id, token=token
-    #         )
-    #     # lancement de la file d'attente
-    #     batch.enqueue()
+    # def curves(self):
+    #     self.ensure_one()
+    #     message = self.get_curves()
     #
-    # def get_curves_all(self, date_start):
-    #     # Calcul du nombre de mois entre la date de début de contrat
-    #     # de l'opération et la date du jour pour lancer la récupération des données
-    #     num_months = (date.today().year - date_start.year) * 12 + (
-    #         date.today().month - date_start.month
+    #     # Logs information
+    #     log_id = self.env["acc.logs"].create(
+    #         {
+    #             "name": "Appel API Enedis Courbes du " + str(fields.Date.today()),
+    #             "date_launched": fields.Datetime.now(),
+    #             "type_log": "api",
+    #             "message": message,
+    #             "acc_operation_id": self.id,
+    #         }
     #     )
     #
-    #     date_start_it = date_start
-    #     date_end_it = date_start + relativedelta(months=1, days=-1)
-    #
-    #     token = self.access_token()
-    #     i = 1
-    #     while i < num_months:
-    #         self.get_curves(date_start_it, date_end_it, token)
-    #         date_start_it = date_start_it + relativedelta(months=1)
-    #         date_end_it = date_start_it + relativedelta(months=1, days=-1)
-    #         i += 1
-
-    # ------------------------------------------------------
-    # API functions
-    # ------------------------------------------------------
-    def _check_access_api(self):
-        if not self.client_id and not self.secret_id:
-            raise UserError(
-                _(
-                    "L'identifiant et la clé de l'opération pour l'utilisation de "
-                    "l'API Enedis ne sont pas renseignées. "
-                    "Veuillez les renseigner dans l'onglet API Enedis."
-                )
-            )
+    #     view_id = self.env.ref("oacc.acc_logs_form").id
+    #     return {
+    #         "name": "LOGS",
+    #         "view_type": "form",
+    #         "view_mode": "form",
+    #         "views": [(view_id, "form")],
+    #         "res_model": "acc.logs",
+    #         "view_id": view_id,
+    #         "type": "ir.actions.act_window",
+    #         "res_id": log_id.id,
+    #         "target": "new",
+    #         "flags": {"initial_mode": "view"},
+    #     }
 
     def get_perimeter(self):
         self.ensure_one()
@@ -150,6 +102,134 @@ class AccOperation(models.Model):
             "flags": {"initial_mode": "view"},
         }
 
+    # ------------------------------------------------------
+    # API functions
+    # ------------------------------------------------------
+    def curves(
+        self,
+        date_start,
+        date_end,
+        usage_point_cons_ids=None,
+        usage_point_prod_ids=None):
+        """
+        Récupère les données de l'opération concernant le périmètre:
+         - liste des PRM
+         - date de début opération
+        """
+        self._check_access_api()
+
+        # Si pas de PRM sélectionnés
+        if not usage_point_cons_ids and not usage_point_prod_ids:
+            usage_point_cons_ids = self.acc_delivery_ids
+            usage_point_prod_ids = self.acc_injection_ids
+
+        message = str()
+        message += (
+            "<h1>API Enedis OACC - Appel Courbes "
+            + str(fields.Datetime.now())
+            + "</h1>"
+            "Appel API pour la période "
+            "" + str(date_start) + " " + str(date_end) + "<br/>"
+        )
+
+        if usage_point_cons_ids:
+            # Traitement données de cons
+            message += "<br/><strong>Traitement des données de consommation</strong><br/>"
+            for usage_point_id in usage_point_cons_ids:
+                desc = "Opération: " + self.name + " - PRM: " + usage_point_id.name + " - Date: " + str(fields.Datetime.today())
+                # message += self.with_delay(description=desc).get_definitive_load_curves(
+                self.with_delay(description=desc).get_definitive_load_curves(
+                    date_end,
+                    date_start,
+                    ["cons,autocons,complement"],
+                    usage_point_id)
+
+        if usage_point_prod_ids:
+            # Traitement données de prod
+            message += "<br/><strong>Traitement des données de production</strong><br/>"
+            for usage_point_id in usage_point_prod_ids:
+                desc = "Opération: " + self.name + " - PRM: " + usage_point_id.name + " - Date: " + str(
+                    fields.Datetime.today())
+                self.with_delay(description=desc).get_definitive_load_curves(
+                # message += self.with_delay(description=desc).get_definitive_load_curves(
+                    date_end,
+                    date_start,
+                    ["surplus,prod"],
+                    usage_point_id)
+
+        message += (
+            "<br/><h1>Fin appel API Courbes: " + str(fields.Datetime.now()) + "</h1>"
+        )
+        # Logs information
+        log_id = self.env["acc.logs"].create(
+            {
+                "name": "Appel API Enedis Courbes du " + str(fields.Date.today()) + " - Période " + str(date_start) + " " + str(date_end),
+                "date_launched": fields.Datetime.now(),
+                "type_log": "api",
+                "message": message,
+                "acc_operation_id": self.id,
+            }
+        )
+
+    def get_definitive_load_curves(
+        self, date_end, date_start, type_curve, usage_point_id):
+
+        message = str()
+        message += "PRM " + usage_point_id.name + "\n"
+        message += "Appel API ...\n"
+        curves_data = self._get_definitive_load_curves(
+            self.name, date_end, date_start, type_curve,
+            usage_point_id.name, self.client_id, self.secret_id)
+        message += "Appel API terminé. Traitement des données ...\n"
+
+        curves = curves_data.get("curves")
+
+        if curves:
+            name = usage_point_id.name + "_" + str(date_start) + "_" + str(date_end)
+        for curve in curves:
+            type = curve["type"]
+
+            for point in curve["interval_reading"]:
+                dt = pytz.utc.localize(
+                    datetime.strptime(point["timestamp"], "%Y-%m-%dT%H:%M:%SZ")
+                )
+                date_slot = fields.Datetime.to_string(
+                    dt.astimezone(pytz.timezone("Europe/Paris"))
+                )
+                date_slot_utc = fields.Datetime.to_string(dt)
+
+                self.env["acc.enedis.cdc"].create(
+                    {
+                        "name": name,
+                        "acc_operation_id": self.id,
+                        "acc_counter_id": usage_point_id.id or False,
+                        "comp_data_type": type,
+                        "power": point["value"],
+                        "date_slot": date_slot,
+                        "date_slot_utc": date_slot_utc,
+                    }
+                )
+        message += "Fin du traitement des données\n"
+        return message
+
+    def get_curves_all(self, date_start):
+        # Calcul du nombre de mois entre la date de début de contrat
+        # de l'opération et la date du jour pour lancer la récupération des données
+        num_months = (date.today().year - date_start.year) * 12 + (
+            date.today().month - date_start.month
+        )
+
+        date_start_it = date_start
+        date_end_it = date_start + relativedelta(months=1, days=-1)
+
+        token = self.access_token()
+        i = 1
+        while i < num_months:
+            self.get_curves(date_start_it, date_end_it, token)
+            date_start_it = date_start_it + relativedelta(months=1)
+            date_end_it = date_start_it + relativedelta(months=1, days=-1)
+            i += 1
+
     def perimeter(self):
         """
         Récupère les données de l'opération concernant le périmètre:
@@ -230,3 +310,12 @@ class AccOperation(models.Model):
     # ------------------------------------------------------
     # Business methods
     # ------------------------------------------------------
+    def _check_access_api(self):
+        if not self.client_id and not self.secret_id:
+            raise UserError(
+                _(
+                    "L'identifiant et la clé de l'opération pour l'utilisation de "
+                    "l'API Enedis ne sont pas renseignées. "
+                    "Veuillez les renseigner dans l'onglet API Enedis."
+                )
+            )
diff --git a/security/ir.model.access.csv b/security/ir.model.access.csv
index 301b7dab167cbcb978ea78e7da9e7f032c40b90e..8dfe7ddba803a0ace1cd62fe854300e1012eb97a 100644
--- a/security/ir.model.access.csv
+++ b/security/ir.model.access.csv
@@ -1 +1,3 @@
 id,name,model_id/id,group_id/id,perm_read,perm_write,perm_create,perm_unlink
+"access_acc_operation_wizard_group_partner_manager","acc_operation_wizard group_partner_manager","model_acc_operation_wizard","base.group_partner_manager",1,1,1,1
+"access_acc_operation_wizard_group_user","acc_operation_wizard group_user","model_acc_operation_wizard","base.group_user",1,0,0,0
diff --git a/views/acc_operation_views.xml b/views/acc_operation_views.xml
index a26f66fa2eae5b12eb1ecd11e5b1721737e3f83c..583f3150f493d9e0e28d795d940ec530bfc8e016 100644
--- a/views/acc_operation_views.xml
+++ b/views/acc_operation_views.xml
@@ -16,6 +16,13 @@
                             name="get_perimeter"
                             attrs="{'invisible':[('client_id','=', False), ('secret_id','=', False)]}"
                         />
+                        <button
+                            string="Récupération des courbes"
+                            type="action"
+                            class="btn-primary"
+                            name="%(oacc_enedis_api.acc_operation_wizard_action)d"
+                            attrs="{'invisible':[('client_id','=', False), ('secret_id','=', False)]}"
+                        />
                     </header>
                     <group>
                         <field name="client_id" />
diff --git a/wizards/__init__.py b/wizards/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..ddbfb3b9f6d01d7faaea73339637505722e74e49
--- /dev/null
+++ b/wizards/__init__.py
@@ -0,0 +1,4 @@
+# Copyright 2023 Le Filament (<http://www.le-filament.com>)
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
+
+from . import acc_operation_wizard
diff --git a/wizards/acc_operation_wizard.py b/wizards/acc_operation_wizard.py
new file mode 100644
index 0000000000000000000000000000000000000000..f6b966f4f8d9e2a0b22970bfae703e653dcb722a
--- /dev/null
+++ b/wizards/acc_operation_wizard.py
@@ -0,0 +1,96 @@
+# Copyright 2023 Le Filament (<http://www.le-filament.com>)
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
+
+from odoo import _, fields, models
+from odoo.exceptions import UserError
+
+
+class AccOperationWizard(models.TransientModel):
+    _name = "acc.operation.wizard"
+    _description = "Récupération des courbes pour une date donnée"
+
+    # ------------------------------------------------------
+    # Fields declaration
+    # ------------------------------------------------------
+    def _default_operation_id(self):
+        op = self.env['acc.operation'].browse(self.env.context.get('active_ids')[0] if self.env.context.get('active_ids') else [])
+        return op
+
+    operation_id = fields.Many2one(
+        "acc.operation", default=lambda self: self._default_operation_id())
+    date_start = fields.Date("Date de début")
+    date_end = fields.Date("Date de fin")
+    prm_cons_ids = fields.Many2many(
+        "acc.counter",
+        relation="acc_counter_cons_rel",
+        column1="cons_id",
+        column2="op_id",
+        domain=[("is_delivery", "=", True)],
+        string="PRM de soutirage")
+    prm_prod_ids = fields.Many2many(
+        "acc.counter",
+        relation="acc_counter_prod_rel",
+        column1="prod_id",
+        column2="op_id",
+        domain=[("is_injection", "=", True)],
+        string="PRM d'injection")
+
+    # ------------------------------------------------------
+    # SQL Constraints
+    # ------------------------------------------------------
+
+    # ------------------------------------------------------
+    # Default methods
+    # ------------------------------------------------------
+
+    # ------------------------------------------------------
+    # Computed fields / Search Fields
+    # ------------------------------------------------------
+
+    # ------------------------------------------------------
+    # Onchange / Constraints
+    # ------------------------------------------------------
+
+    # ------------------------------------------------------
+    # CRUD methods (ORM overrides)
+    # ------------------------------------------------------
+
+    # ------------------------------------------------------
+    # Actions
+    # ------------------------------------------------------
+    def get_curves(self):
+        if not self.date_end and not self.date_start:
+            raise UserError(
+                _("Les champs Date de début et Date de fin sont obligatoires")
+            )
+        if (self.date_end - self.date_start).days > 31:
+            raise UserError(_("L'intervalle de temps ne doit pas dépasser 31 Jours"))
+
+        if (self.date_end <= self.date_start):
+            raise UserError(_("La date de fin doit être supérieure à la date de début"))
+
+        self.operation_id.curves(
+            self.date_start, self.date_end, self.prm_cons_ids, self.prm_prod_ids
+        )
+        return {"type": "ir.actions.act_window_close"}
+
+    def get_curves_all(self):
+        context = dict(self._context or {})
+        if context.get("active_ids", False):
+            op = self.env["acc.operation"].browse(context.get("active_ids"))
+            if not op.date_start_contract:
+                raise UserError(
+                    _(
+                        "Renseigner une date de début de contrat pour"
+                        " pouvoir récupérer les courbes à partie de cette date."
+                    )
+                )
+            date_start = op.date_start_contract
+            self.env["acc.operation"].browse(context.get("active_ids")).get_curves_all(
+                date_start
+            )
+        return {"type": "ir.actions.act_window_close"}
+
+    # ------------------------------------------------------
+    # Business methods
+    # ------------------------------------------------------
diff --git a/wizards/acc_operation_wizard_views.xml b/wizards/acc_operation_wizard_views.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f9e9c4bbf24657a9f40b7a01feecf89d13bf8059
--- /dev/null
+++ b/wizards/acc_operation_wizard_views.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<odoo>
+    <!-- WIZARD FORM -->
+    <record id="acc_operation_wizard_view_form" model="ir.ui.view">
+        <field name="name">acc.operation.wizard.form</field>
+        <field name="model">acc.operation.wizard</field>
+        <field name="arch" type="xml">
+            <form>
+                <group>
+                    <field name="operation_id" invisible="1"/>
+                    <field
+                        name="prm_cons_ids"
+                        widget="many2many_tags"
+                        domain="[('is_delivery', '=', True), ('acc_operation_id', '=', operation_id)]"
+                        options="{'no_create_edit': True, 'no_create': True}"
+                    />
+                    <field
+                        name="prm_prod_ids"
+                        widget="many2many_tags"
+                        options="{'no_create_edit': True, 'no_create': True}"
+                        domain="[('is_injection', '=', True), ('acc_operation_id', '=', operation_id)]"
+                    />
+                </group>
+                <group name="period" string="Période" col="2">
+                    <field name="date_start" />
+                    <field name="date_end" />
+                </group>
+                <footer>
+                    <button
+                        class="btn btn-sm btn-primary"
+                        name="get_curves"
+                        string="Récupérer"
+                        type="object"
+                    />
+                    <button
+                        class="btn btn-sm btn-primary"
+                        name="get_curves_all"
+                        string="Récupérer depuis le début"
+                        type="object"
+                    />
+                    <button
+                        class="btn btn-sm btn-default"
+                        special="cancel"
+                        string="Annuler"
+                    />
+                </footer>
+            </form>
+        </field>
+    </record>
+
+    <record id="acc_operation_wizard_action" model="ir.actions.act_window">
+        <field name="name">Récupération des courbes</field>
+        <field name="type">ir.actions.act_window</field>
+        <field name="res_model">acc.operation.wizard</field>
+        <field name="view_mode">form</field>
+        <field name="view_id" ref="acc_operation_wizard_view_form" />
+        <field name="target">new</field>
+    </record>
+
+</odoo>