From 2583fe5477094d214f47437e1d5205f842319054 Mon Sep 17 00:00:00 2001
From: benjamin <benjamin@le-filament.com>
Date: Tue, 18 Apr 2023 11:43:56 +0200
Subject: [PATCH] [add] change deadline wizard

---
 __manifest__.py                              |   1 +
 report/scop_contribution_report.py           |   4 +-
 security/ir.model.access.csv                 |   2 +
 views/scop_bordereau_cg.xml                  |   6 ++
 wizard/__init__.py                           |   1 +
 wizard/scop_bordereau_deadline_wizard.py     | 106 +++++++++++++++++++
 wizard/scop_bordereau_deadline_wizard.xml    |  53 ++++++++++
 wizard/scop_bordereau_payment_mode_wizard.py |  26 +++--
 wizard/scop_bordereau_refund_wizard.py       |   2 +-
 9 files changed, 189 insertions(+), 12 deletions(-)
 create mode 100644 wizard/scop_bordereau_deadline_wizard.py
 create mode 100644 wizard/scop_bordereau_deadline_wizard.xml

diff --git a/__manifest__.py b/__manifest__.py
index cc6fe91..660bce8 100644
--- a/__manifest__.py
+++ b/__manifest__.py
@@ -42,6 +42,7 @@
         "wizard/export_journal_wizard_view.xml",
         "wizard/mandate_change_bordereau_wizard.xml",
         "wizard/scop_cotisation_cg_regul_wizard.xml",
+        "wizard/scop_bordereau_deadline_wizard.xml",
         "wizard/scop_bordereau_update_liasse_wizard.xml",
         "wizard/scop_bordereau_payment_mode_wizard.xml",
         "wizard/scop_bordereau_refund_wizard.xml",
diff --git a/report/scop_contribution_report.py b/report/scop_contribution_report.py
index 00ac369..89a69e4 100644
--- a/report/scop_contribution_report.py
+++ b/report/scop_contribution_report.py
@@ -89,7 +89,9 @@ class ScopContributionReport(models.Model):
                 return base64.b64encode(bordereau_pdf)
             else:
                 raise UserError(
-                    _("Impossible de télécharger le bordereau associé à cette cotisation.")
+                    _(
+                        "Impossible de télécharger le bordereau associé à cette cotisation."
+                    )
                 )
         else:
             raise UserError(_("Pas de bordereau rattaché à cette cotisation."))
diff --git a/security/ir.model.access.csv b/security/ir.model.access.csv
index 3bb8d51..4fc53d6 100644
--- a/security/ir.model.access.csv
+++ b/security/ir.model.access.csv
@@ -5,6 +5,8 @@ access_scop_cotisation_cg,access_scop_cotisation_cg,model_scop_cotisation_cg,cgs
 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,cgscop_cotisation_cg.group_cotisation_cg_administrative,1,1,1,1
 admin_access_scop_bordereau,admin_access_scop_bordereau,model_scop_bordereau,cgscop_partner.group_cg_administrator,1,1,1,1
+access_scop_bordereau_deadline_wizard,access_scop_bordereau_deadline_wizard,model_scop_bordereau_deadline_wizard,cgscop_cotisation_cg.group_cotisation_cg_administrative,1,1,1,1
+access_scop_bordereau_deadline_invoice_wizard,access_scop_bordereau_deadline_invoice_wizard,model_scop_bordereau_deadline_invoice_wizard,cgscop_cotisation_cg.group_cotisation_cg_administrative,1,1,1,1
 access_scop_bordereau_version,access_scop_bordereau_version,model_scop_bordereau_version,cgscop_cotisation_cg.group_cotisation_cg_administrative,1,1,1,1
 admin_access_scop_bordereau_version,admin_access_scop_bordereau_version,model_scop_bordereau_version,cgscop_partner.group_cg_administrator,1,1,1,1
 access_scop_bordereau_refund_wizard_quarter,access_scop_bordereau_refund_wizard_quarter,model_scop_bordereau_refund_wizard_quarter,cgscop_cotisation_cg.group_cotisation_cg_administrative,1,1,1,1
diff --git a/views/scop_bordereau_cg.xml b/views/scop_bordereau_cg.xml
index 8538c4f..d8de854 100644
--- a/views/scop_bordereau_cg.xml
+++ b/views/scop_bordereau_cg.xml
@@ -71,6 +71,12 @@
                             type="action"
                             states="ongoing,validated,paid"
                         />
+                        <button
+                            name="%(cgscop_cotisation_cg.scop_bordereau_deadline_wizard_act_window)d"
+                            string="Modifier les échéances"
+                            type="action"
+                            states="new,validated"
+                        />
                     </header>
                     <sheet>
                         <div class="oe_button_box" name="button_box">
diff --git a/wizard/__init__.py b/wizard/__init__.py
index 3a73f47..5abd851 100644
--- a/wizard/__init__.py
+++ b/wizard/__init__.py
@@ -4,6 +4,7 @@
 from . import account_move_reversal
 from . import export_journal_wizard
 from . import mandate_change_bordereau_wizard
+from . import scop_bordereau_deadline_wizard
 from . import scop_bordereau_update_liasse_wizard
 from . import scop_bordereau_payment_mode_wizard
 from . import scop_bordereau_refund_wizard
diff --git a/wizard/scop_bordereau_deadline_wizard.py b/wizard/scop_bordereau_deadline_wizard.py
new file mode 100644
index 0000000..e93747d
--- /dev/null
+++ b/wizard/scop_bordereau_deadline_wizard.py
@@ -0,0 +1,106 @@
+# Copyright 2021 Le Filament
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
+
+from odoo import fields, models
+
+
+class ScopBordereauDeadlineWizard(models.TransientModel):
+    _name = "scop.bordereau.deadline.wizard"
+    _description = "Modification des dates d'échéance"
+
+    # ------------------------------------------------------
+    # Default functions
+    # ------------------------------------------------------
+    def _default_bordereau_id(self):
+        bordereau_id = self.env["scop.bordereau"].browse(
+            self.env.context.get("active_id")
+        )
+        return bordereau_id.id
+
+    def _default_invoice_ids(self):
+        bordereau_id = self.env["scop.bordereau"].browse(
+            self.env.context.get("active_id")
+        )
+        invoice_ids = bordereau_id.invoice_ids.filtered(
+            lambda i: i.payment_state in ["not_paid", "partial"]
+        )
+        default_invoices = invoice_ids.mapped(lambda i: (0, 0, {"invoice_id": i.id}))
+        return default_invoices
+
+    # ------------------------------------------------------
+    # Fields declaration
+    # ------------------------------------------------------
+    bordereau_id = fields.Many2one(
+        comodel_name="scop.bordereau",
+        string="Bordereau",
+        readonly=True,
+        default=_default_bordereau_id,
+    )
+    partner_id = fields.Many2one(
+        comodel_name="res.partner",
+        string="Adhérent",
+        related="bordereau_id.partner_id",
+    )
+    invoice_ids = fields.One2many(
+        comodel_name="scop.bordereau.deadline.invoice.wizard",
+        inverse_name="wizard_id",
+        string="Appels de cotisation",
+        default=_default_invoice_ids,
+    )
+
+    # ------------------------------------------------------
+    # Constrains
+    # ------------------------------------------------------
+
+    # ------------------------------------------------------
+    # Override ORM
+    # ------------------------------------------------------
+
+    # ------------------------------------------------------
+    # Action
+    # ------------------------------------------------------
+    def change_deadline(self):
+        self.ensure_one()
+        self.invoice_ids.change_deadline()
+        return {"type": "ir.actions.act_window_close"}
+
+
+class ScopBordereauDeadlineInvoiceWizard(models.TransientModel):
+    _name = "scop.bordereau.deadline.invoice.wizard"
+    _description = "Appels de cotisation"
+
+    wizard_id = fields.Many2one(
+        comodel_name="scop.bordereau.deadline.wizard",
+        string="Wizard",
+        required=True,
+        ondelete="cascade",
+    )
+    invoice_id = fields.Many2one(
+        comodel_name="account.move",
+        string="Appel de cotisation",
+        required=True,
+        readonly=True,
+        ondelete="cascade",
+    )
+    old_deadline = fields.Date("Date d'échéance", related="invoice_id.invoice_date_due")
+    quarter = fields.Selection(related="invoice_id.cotiz_quarter")
+    type_contribution_id = fields.Many2one(
+        comodel_name="scop.contribution.type",
+        string="Type de cotisation",
+        related="invoice_id.type_contribution_id",
+    )
+    new_deadline = fields.Date(
+        "Nouvelle date d'échéance",
+    )
+
+    # ------------------------------------------------------
+    # Action
+    # ------------------------------------------------------
+    def change_deadline(self):
+        for line in self:
+            if line.new_deadline:
+                line.invoice_id.invoice_date_due = line.new_deadline
+                aml_ids = line.invoice_id.line_ids.filtered(
+                    lambda l: l.date_maturity == line.old_deadline
+                )
+                aml_ids.update({"date_maturity": line.new_deadline})
diff --git a/wizard/scop_bordereau_deadline_wizard.xml b/wizard/scop_bordereau_deadline_wizard.xml
new file mode 100644
index 0000000..eecc1a2
--- /dev/null
+++ b/wizard/scop_bordereau_deadline_wizard.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<odoo>
+    <!--  Copyright 2021 Le Filament
+          License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).  -->
+    <data>
+
+        <record id="scop_bordereau_deadline_wizard_form_view" model="ir.ui.view">
+            <field name="name">scop.bordereau.deadline.wizard.form</field>
+            <field name="model">scop.bordereau.deadline.wizard</field>
+            <field name="arch" type="xml">
+                <form string="Modification des echeances">
+                    <sheet>
+                        <group>
+                            <field name="bordereau_id" />
+                            <field name="partner_id" />
+                        </group>
+                        <separator string="Appels de cotisation" />
+                        <field name="invoice_ids">
+                            <tree create="0" delete="0" editable="top">
+                                <field name="invoice_id" readonly="1" force_save="1" />
+                                <field name="type_contribution_id" />
+                                <field name="quarter" />
+                                <field name="old_deadline" />
+                                <field name="new_deadline" />
+                            </tree>
+                        </field>
+                    </sheet>
+                    <footer>
+                        <button
+                            name="change_deadline"
+                            type="object"
+                            string="Modifier les dates d'échéance"
+                            class="oe_highlight"
+                        />
+                        <button string="Annuler" special="cancel" class="oe_link" />
+                    </footer>
+                </form>
+            </field>
+        </record>
+
+        <record
+            id="scop_bordereau_deadline_wizard_act_window"
+            model="ir.actions.act_window"
+        >
+            <field name="name">Modifier les dates d'échéance</field>
+            <field name="type">ir.actions.act_window</field>
+            <field name="res_model">scop.bordereau.deadline.wizard</field>
+            <field name="view_mode">form</field>
+            <field name="target">new</field>
+        </record>
+
+    </data>
+</odoo>
diff --git a/wizard/scop_bordereau_payment_mode_wizard.py b/wizard/scop_bordereau_payment_mode_wizard.py
index 17d7490..24553be 100644
--- a/wizard/scop_bordereau_payment_mode_wizard.py
+++ b/wizard/scop_bordereau_payment_mode_wizard.py
@@ -44,22 +44,28 @@ class ScopBordereauChangePaymentMode(models.TransientModel):
                 }
             )
             # Recherche les bordereaux non payés
-            bordereau_ids = self.env["scop.bordereau"].search([
-                ("partner_id", "=", bordereau_id.partner_id.id),
-                ("state", "not in", ["paid", "cancel"]),
-            ])
+            bordereau_ids = self.env["scop.bordereau"].search(
+                [
+                    ("partner_id", "=", bordereau_id.partner_id.id),
+                    ("state", "not in", ["paid", "cancel"]),
+                ]
+            )
             # Recherche les factures liées aux bordereaux non payées
             invoice_ids = bordereau_ids.mapped("invoice_ids").filtered(
-                lambda i: i.payment_state not in ["paid", "reversed"])
+                lambda i: i.payment_state not in ["paid", "reversed"]
+            )
         else:
             bordereau_ids = bordereau_id
             invoice_ids = bordereau_id.invoice_ids.filtered(
-                lambda i: i.payment_state not in ["paid", "reversed"])
+                lambda i: i.payment_state not in ["paid", "reversed"]
+            )
             if not invoice_ids:
-                raise UserError(_(
-                    "Tous les appels liés à ce bordereau sont payés, il n'est pas possible "
-                    "de modifier le mode de paiement"
-                ))
+                raise UserError(
+                    _(
+                        "Tous les appels liés à ce bordereau sont payés, il n'est pas possible "
+                        "de modifier le mode de paiement"
+                    )
+                )
 
         # Met à jour le mode de paiement sur les bordereaux
         bordereau_ids.update({"payment_mode_id": self.payment_mode_id.id})
diff --git a/wizard/scop_bordereau_refund_wizard.py b/wizard/scop_bordereau_refund_wizard.py
index 47b935f..5945af5 100644
--- a/wizard/scop_bordereau_refund_wizard.py
+++ b/wizard/scop_bordereau_refund_wizard.py
@@ -77,7 +77,7 @@ class ScopBordereauRefundWizard(models.TransientModel):
             ["type_contribution_id", "amount_total_signed"],
             ["type_contribution_id"],
         )
-        
+
         ur_hdf = self.env.ref("cgscop_partner.riga_14232").id
         if bordereau_id.partner_id.ur_id.id == ur_hdf:
             product_ur = self.env.company.contribution_hdf_id
-- 
GitLab