Skip to content
Extraits de code Groupes Projets
Sélectionner une révision Git
  • 0b7d0c34bd2aeb69cb306ff0a70a0da3c4f59a9d
  • 12.0-evo-202003 par défaut
  • 14-RV-20250324
  • 14-RV-20240830
  • 14-RV-20231222
  • 12-RV-Bug_ecrasement_date_radiation
  • 12-RV-revision-staff
  • 12-RV-copadev
  • 12-RV-Correctif-open-instagram
  • 12-RV-Tree-Coop-Ajout-effectif
  • 12.0-RV-Instagram
  • 12.0-RV-segment_visibility
  • 12.0 protégée
  • 12.0-RV-Abonnements
14 résultats

res_partner_newsletter.py

Blame
  • Bifurcation depuis Le Filament / Confédération Générale des SCOP / cgscop_partner
    Le projet source a une visibilité limitée.
    scop_cotisation_idf.py 8,21 Kio
    # © 2021 Le Filament (<http://www.le-filament.com>)
    # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
    
    from odoo import api, fields, models
    
    
    class ScopCotisationsIDF(models.Model):
        _name = "scop.cotisation.idf"
        _description = "Cotisations IDF"
    
        # ------------------------------------------------------
        # Fields declaration
        # ------------------------------------------------------
        name = fields.Char("Libellé")
        company_id = fields.Many2one(
            comodel_name="res.company",
            string="Société",
        )
        partner_id = fields.Many2one(
            comodel_name="res.partner",
            string="Adhérent",
            required=True,
            domain=[("is_company", "=", True)],
        )
        journal = fields.Char("Journal")
        writing_date = fields.Date("Date écriture")
        piece = fields.Integer("Numéro de pièce comptable")
        year = fields.Char("Année")
        type = fields.Selection(
            [
                ("inv", "Cotisation"),
                ("refund", "Avoir"),
                ("reject", "Rejet"),
                ("pay", "Paiement"),
            ],
            string="Type",
            required=True,
        )
        lettrage = fields.Char("Référence de lettrage")
        currency_id = fields.Many2one(
            comodel_name="res.currency",
            string="Monnaie",
            related="company_id.currency_id",
        )
        debit = fields.Monetary(string="Débit", currency_field="currency_id")
        credit = fields.Monetary(string="Crédit", currency_field="currency_id")
        amount_residual = fields.Monetary(
            string="Reste à payer",
            compute="_compute_amount_residual",
            store=True,
            currency_field="currency_id",
        )
        state = fields.Selection(
            string="Etat",
            selection=[
                ("no_invoice", "Pas de cotisation associée"),
                ("awaiting_payments", "En attente de paiements"),
                (
                    "overpaid",
                    "La somme des paiements est supérieure au " "montant de la cotisation",
                ),
                ("paid", "La cotisation a bien été réglée !"),
            ],
            required=False,
            search="_search_state",
            compute="_compute_state",
        )
    
        invoice_id = fields.Many2one(
            comodel_name="scop.cotisation.idf", string="Cotisation"
        )
        payments_ids = fields.One2many(
            comodel_name="scop.cotisation.idf",
            inverse_name="invoice_id",
            string="Paiements / Avoirs",
            required=False,
            readonly=True,
        )
    
        exoneration = fields.Boolean(
            string="Exonération", compute="_compute_exoneration", store=True
        )
        cotiz_zero = fields.Boolean(string="Non appelée")
    
        # ------------------------------------------------------
        # Computed fields
        # ------------------------------------------------------
        @api.depends("payments_ids", "debit", "payments_ids.debit", "payments_ids.credit")
        def _compute_amount_residual(self):
            for r in self:
                if r.type == "inv":
                    if r.payments_ids:
                        amount_paid = sum(r.payments_ids.mapped("credit"))
                        r.amount_residual = r.debit - amount_paid
                    else:
                        r.amount_residual = r.debit
    
        def _compute_state(self):
            """
            A line can be in different states :
            - No invoice related to a payment / refund
            - Too many payments related to one invoice
            - Some payments are missing
            - The invoice has been paid
            """
    
            def which_state(amount_residual):
                if amount_residual > 0:
                    return "awaiting_payments"
                elif amount_residual < 0:
                    return "overpaid"
                else:
                    return "paid"
    
            for r in self:
                if r.type != "inv":
                    if not r.invoice_id:
                        r.state = "no_invoice"
                    else:
                        r.state = which_state(r.invoice_id.amount_residual)
                else:
                    r.state = which_state(r.amount_residual)
    
        def _search_state(self, operator, value):
            recs = None
            if operator == "=":
                recs = self.search([]).filtered(lambda x: x.state == value)
            elif operator == "in":
                recs = self.search([]).filtered(lambda x: x.state in value)
            elif operator == "!=":
                recs = self.search([]).filtered(lambda x: x.state != value)
            elif operator == "not in":
                recs = self.search([]).filtered(lambda x: x.state not in value)
            if recs:
                return [("id", "in", [x.id for x in recs])]
    
        @api.depends("type", "invoice_id", "payments_ids", "payments_ids.type")
        def _compute_exoneration(self):
            for r in self:
                if r.type == "refund":
                    r.exoneration = True
                if r.type == "inv":
                    exos = r.payments_ids.filtered(lambda l: l.exoneration is True)
                    if exos:
                        r.exoneration = True
    
        # ------------------------------------------------------
        # Actions
        # ------------------------------------------------------
        def reconcile(self):
            """
            Link payments and invoices if same letter for a given year
            :return:
            """
            years = set(self.mapped("year"))
            partners = self.mapped("partner_id")
            for year in years:
                for partner in partners:
                    invoice_lines = self.search(
                        [
                            ["year", "=", year],
                            ["partner_id", "=", partner.id],
                            ["type", "=", "inv"],
                        ]
                    )
                    letters = set(invoice_lines.mapped("lettrage"))
                    lines_to_lettre = self.search(
                        [
                            ["year", "=", year],
                            ["partner_id", "=", partner.id],
                            ["type", "!=", "inv"],
                        ]
                    )
                    for line in lines_to_lettre:
                        if line.lettrage in letters:
                            line.invoice_id = invoice_lines.filtered(
                                lambda l: l.lettrage == line.lettrage
                            )[0]
    
        def action_open_payment(self):
            return {
                "type": "ir.actions.act_window",
                "name": "Paiement / Avoir",
                "views": [
                    [
                        self.env.ref("cgscop_invoice_idf.view_scop_cotisation_idf_form").id,
                        "form",
                    ]
                ],
                "view_mode": "form",
                "res_model": "scop.cotisation.idf",
                "target": "current",
                "res_id": self.id,
            }
    
        def action_free_payment(self):
            self.invoice_id = None
    
        def action_show_payments(self):
            form_view = self.env.ref("cgscop_invoice_idf.view_scop_cotisation_idf_form").id
            tree_view = self.env.ref("cgscop_invoice_idf.view_scop_cotisation_idf_tree").id
            return {
                "type": "ir.actions.act_window",
                "name": "Paiement / Avoir",
                "views": [[tree_view, "tree"], [form_view, "form"]],
                "view_mode": "form",
                "res_model": "scop.cotisation.idf",
                "target": "current",
                "domain": [("id", "in", self.payments_ids.ids)],
            }
    
        def action_show_invoice(self):
            form_view = self.env.ref("cgscop_invoice_idf.view_scop_cotisation_idf_form").id
            return {
                "type": "ir.actions.act_window",
                "name": "Cotisation",
                "views": [[form_view, "form"]],
                "view_mode": "form",
                "res_model": "scop.cotisation.idf",
                "target": "current",
                "res_id": self.invoice_id.id,
            }
    
        def action_show_partner_contribution_idf(self):
            form_view = self.env.ref("cgscop_invoice_idf.view_scop_cotisation_idf_form").id
            tree_view = self.env.ref("cgscop_invoice_idf.view_scop_cotisation_idf_tree").id
            return {
                "type": "ir.actions.act_window",
                "name": "Cotisations IDF - " + self.partner_id.name,
                "views": [[tree_view, "tree"], [form_view, "form"]],
                "view_mode": "form",
                "res_model": "scop.cotisation.idf",
                "target": "current",
                "domain": [("partner_id", "=", self.partner_id.id)],
            }