Skip to content
Extraits de code Groupes Projets
res_partner.py 62,4 ko
Newer Older
  • Learn to ignore specific revisions
  •                     "statut abandonné."
                    )
                )
            else:
                return super().action_archive()
    
    
        # ------------------------------------------------------
        # Computed Fields
        # ------------------------------------------------------
    
        @api.depends("siret")
        def _compute_siren(self):
            for partner in self:
                if partner.siret:
                    partner.siren = (
                        partner.siret[:3]
                        + " "
                        + partner.siret[3:6]
                        + " "
                        + partner.siret[6:9]
                    )
    
                    partner.pappers_url = (
                        "https://www.pappers.fr/entreprise/" + partner.siret[:9]
                    )
    
                    partner.pappers_url = None
    
    
        def _compute_formatted_siret(self):
            for partner in self:
                if partner.siret:
                    partner.formatted_siret = (
    
                        partner.siret[:3]
                        + " "
                        + partner.siret[3:6]
                        + " "
                        + partner.siret[6:9]
                        + " "
                        + partner.siret[9:]
    
        @api.depends("zip")
    
        def _compute_num_departement(self):
            for company in self:
                if company.zip:
    
                    zip_starts = company.zip[:3]
                    if zip_starts in ["200", "201"]:
                        zip_departement = "2A"
                    elif zip_starts == "202":
                        zip_departement = "2B"
                    elif zip_starts[:2] == "97":
                        zip_departement = zip_starts
                    else:
                        zip_departement = zip_starts[:2]
    
    
                    if zip_departement in ["2A", "2B"] or zip_departement.isdigit():
    
                        company.zip_departement = zip_departement
    
                        company.zip_departement = False
    
        def _compute_region(self):
            for partner in self:
                if partner.zip:
    
                    zip_id = self.env["res.city.zip"].search([("name", "=", partner.zip)])
    
                    if zip_id:
                        partner.region = zip_id[0].city_id[0].state_id
    
    
    Rémi - Le Filament's avatar
    Rémi - Le Filament a validé
        @api.model
        def _compute_current_user_ur_id(self):
            for partner in self:
    
                partner.current_user_ur_id = self.env.company.ur_id
    
    Rémi - Le Filament's avatar
    Rémi - Le Filament a validé
        def _search_current_user_ur_id(self, operator, value):
    
            return [("ur_id", "=", self.env.company.ur_id.id)]
    
        @api.depends(
            "contact_origin_id",
            "parent_id.cooperative_form_id",
            "parent_id.membership_status",
        )
    
    Rémi - Le Filament's avatar
    Rémi - Le Filament a validé
        def _compute_contact_legality(self):
            for partner in self:
    
                if partner.contact_origin_id.name == "Fiche contact, site internet":
    
                    partner.contact_legality = "consent"
                if partner.contact_origin_id.name in (
                    "Prospect journée d'info coll",
                    "Prospect (salon, rdv, internet…)",
                    "Elus",
                ):
                    partner.contact_legality = "legitimate"
                if partner.contact_origin_id.name in (
                    "Salariés CG",
                    "Salariés UR",
                    "Salariés Fédération",
                ):
                    partner.contact_legality = "employee"
    
    Rémi - Le Filament's avatar
    Rémi - Le Filament a validé
                if partner.contact_origin_id.name in (
    
                    "Elus",
                    "VIP, Officiels",
                    "Fournisseurs",
                ):
                    partner.contact_legality = "legitimate"
    
    Rémi - Le Filament's avatar
    Rémi - Le Filament a validé
                if not partner.is_company and partner.parent_id:
                    parent = partner.parent_id
    
    Rémi - Le Filament's avatar
    Rémi - Le Filament a validé
                            "Dossiers d'adhésion",
    
                            "Dossiers annuels non LM (scic, scop47)",
                        )
                        and parent.cooperative_form_id
                        and parent.membership_status == "member"
                    ):
                        partner.contact_legality = "customer"
                    if (
                        partner.contact_origin_id.name
                        == ("Dossiers annuels non LM (scic, scop47)")
                        and parent.membership_status != "member"
                    ):
                        partner.contact_legality = "legitimate"
                    if (
    
                        partner.contact_origin_id.name == ("Dossiers Liste ministère")
    
                        and parent.cooperative_form_id.name == "SCIC"
                    ):
                        partner.contact_legality = "customer"
    
    
        def _compute_is_rse(self):
            """
    
            """
            for partner in self:
    
                if len(partner.action_rse_ids) != 0:
                    partner.is_rse = True
    
                if len(partner.action_te_ids) != 0:
                    partner.is_rse = True
    
        @api.depends(
            "membership_period_ids",
            "membership_period_ids.end_reason_id",
            "membership_period_ids.end",
    
            "membership_period_ids.start",
    
    Juliana's avatar
    Juliana a validé
        # Todo: A revoir comment on assigne le statut member
    
        def _compute_membership(self):
            for partner in self:
    
                if partner.membership_period_ids:
                    type_cg = self.env.ref("cgscop_partner.membership_type_1").id
                    last_membership_period = self.env["scop.membership.period"].search(
                        [("partner_id", "=", partner.id), ("type_id", "=", type_cg)],
                        limit=1,
    
                        order="start desc,id desc",
    
                    )
                    if last_membership_period and not last_membership_period.end:
                        partner.membership_status = "member"
                        partner.member_start = last_membership_period.start
    
                    elif last_membership_period and last_membership_period.end_reason_id:
    
                else:
                    partner.membership_status = "not_member"
    
    
        @api.depends("member_number_int")
        def _compute_membership_number(self):
    
                if partner.member_number_int:
                    partner.member_number = str(partner.member_number_int)
                else:
                    partner.member_number = False
    
        @api.depends("membership_period_ids", "membership_period_ids.end")
    
        def _compute_federation(self):
            for partner in self:
                if partner.is_cooperative:
                    partner.is_federation_com = partner._get_federation(
    
                    partner.is_federation_btp = partner._get_federation(
    
                    partner.is_federation_indus = partner._get_federation(
    
                    partner.is_federation_cae = partner._get_federation(
    
    
        def _get_federation(self, external_id):
            member_type_id = self.env.ref(external_id).id
            partner_id = self.id
    
            membership_period = self.env["scop.membership.period"].search(
                [
                    ("partner_id", "=", partner_id),
                    ("type_id", "=", member_type_id),
                    ("end", "=", False),
                ]
            )
    
        @api.depends(
            "staff_ids",
            "staff_ids.staff_count",
            "staff_ids.staff_shareholder_count",
            "staff_ids.effective_date",
        )
    
        def _compute_last_effective(self):
            for partner in self:
    
                lines = partner._get_staff_lines()
                if lines:
                    partner.staff_last = lines[0].staff_count
                    partner.staff_shareholder_last = lines[0].staff_shareholder_count
                    partner.staff_last_date = lines[0].effective_date
    
        def _compute_segment_nb(self):
            for partner in self:
                # Calcul nombre de segment 1
    
                seg1 = partner.env["res.partner.segment1"].search(
                    [("ur_id", "=", self.env.user.ur_id.id)]
                )
    
                partner.segment_1_nb = len(seg1)
                # Calcul nombre de segment 2
    
                seg2 = partner.env["res.partner.segment2"].search(
                    [("ur_id", "=", self.env.user.ur_id.id)]
                )
    
                partner.segment_2_nb = len(seg2)
                # Calcul nombre de segment 3
    
                seg3 = partner.env["res.partner.segment3"].search(
                    [("ur_id", "=", self.env.user.ur_id.id)]
                )
    
                partner.segment_3_nb = len(seg3)
                # Calcul nombre de segment 4
    
                seg4 = partner.env["res.partner.segment4"].search(
                    [("ur_id", "=", self.env.user.ur_id.id)]
                )
    
                partner.segment_4_nb = len(seg4)
    
    
        @api.depends("organization_subtype_id")
    
        def _compute_org_type_id(self):
            for partner in self:
                if partner.organization_subtype_id:
    
                    partner.organization_type_id = partner.organization_subtype_id.parent_id
    
        def _compute_is_administrative(self):
            for partner in self:
    
                if self.env.user.has_group("cgscop_partner.group_cg_administrative"):
    
                    partner.is_administrative = True
                else:
                    partner.is_administrative = False
    
    
        @api.depends(
            "revision_next_exercice", "revision_same_exercice",
        )
    
        def _compute_revision_next_year(self):
            for partner in self:
    
                if partner.revision_same_exercice:
                    partner.revision_next_year = partner.revision_next_exercice
                else:
                    partner.revision_next_year = partner.revision_next_exercice + 1
    
        @api.depends(
            "revision_type",
            "revision_ids",
            "revision_ids.revision_result_year",
            "first_closeout",
        )
    
        def _compute_revision_next_exercice(self):
            for partner in self:
                # Si aucune périodicité de défini, on n'insiste pas
    
    jordan's avatar
    jordan a validé
                if not partner.revision_type or not partner.first_closeout:
                    partner.revision_next_exercice = False
                else:
                    # On commence par regarder si l'on a des révisions
                    last_rev = partner.revision_ids.sorted(
                        key=lambda r: r.revision_result_year, reverse=True
                    )
    
    jordan's avatar
    jordan a validé
                    # On calcule l'année de référence du calcul
                    if len(last_rev) > 0:
                        # si On a déjà révisé un exercice il devient la base du calcul
                        base_rev = last_rev[0].revision_result_year
    
    jordan's avatar
    jordan a validé
                        base_rev = partner.first_closeout.year - 1
    
                    # On calcule le prochain exercice révisable
                    # Cas d'une révision annuelle
                    if partner.revision_type == "1y":
                        partner.revision_next_exercice = base_rev + 1
                    # Cas d'une révision quinquénnale
                    elif partner.revision_type == "5y":
    
                        self._compute_revision_quinq_exercice()
                        partner.revision_next_exercice = partner.revision_quinq_exercice
    
    jordan's avatar
    jordan a validé
                    # Cas d'une révision quinquénnale séquencée (annuelle)
                    elif partner.revision_type == "5ys":
                        partner.revision_next_exercice = base_rev + 1
                    # Cas d'une révision quinquénnale séquencée (2 et 3)
                    elif partner.revision_type == "5ys23":
                        # On doit regarder l'écart avec la révision précédente
                        if len(last_rev) > 1:
                            # On a une réunion précédente ...
                            # ... il faut regarder l'écart entre les deux
                            ex1 = last_rev[0].revision_result_year
                            ex2 = last_rev[1].revision_result_year
                            # ... prochain exercice = 5 - durée de la précédente révision
                            partner.revision_next_exercice = base_rev + (5 - (ex1 - ex2))
                        else:
                            # Pas de révision précédente
                            partner.revision_next_exercice = base_rev + 2
    
        @api.depends(
            "revision_type",
            "revision_ids",
            "revision_ids.revision_result_year",
            "revision_ids.revision_type",
            "first_closeout",
        )
        def _compute_revision_quinq_exercice(self):
            for partner in self:
                # Si aucune périodicité de défini, on n'insiste pas
                if not partner.revision_type or not partner.first_closeout:
                    partner.revision_quinq_exercice = False
                else:
                    # On commence par regarder si l'on a des révisions classique ou speciale
                    last_rev = partner.revision_ids.filtered(
                        lambda p: p.revision_type != "int"
                        ).sorted(
                        key=lambda r: r.revision_result_year, reverse=True
                        )
    
                    # On calcule l'année de référence du calcul
                    if len(last_rev) > 0:
                        # si On a déjà révisé un exercice il devient la base du calcul
                        base_rev = last_rev[0].revision_result_year
                    else:
                        base_rev = partner.first_closeout.year - 1
    
                    # On calcule l'année de révision de la quinquénale
                    partner.revision_quinq_exercice = base_rev + 5
    
        @api.depends(
            "revision_quinq_exercice",
            "revision_same_exercice",
        )
        def _compute_revision_quinq_annee(self):
            for partner in self:
                if partner.revision_same_exercice:
                    partner.revision_quinq_A5 = partner.revision_quinq_exercice
    
                    partner.revision_quinq_A4 = partner.revision_quinq_exercice - 1
                    partner.revision_quinq_A3 = partner.revision_quinq_exercice - 2
                    partner.revision_quinq_A2 = partner.revision_quinq_exercice - 3
                    partner.revision_quinq_A1 = partner.revision_quinq_exercice - 4
    
                else:
                    partner.revision_quinq_A5 = partner.revision_quinq_exercice + 1
                    partner.revision_quinq_A4 = partner.revision_quinq_exercice
                    partner.revision_quinq_A3 = partner.revision_quinq_exercice - 1
                    partner.revision_quinq_A2 = partner.revision_quinq_exercice - 2
                    partner.revision_quinq_A1 = partner.revision_quinq_exercice - 3
    
        @api.depends(
            "revision_type",
            "revision_mandat_cac",
        )
        def _compute_revision_type_ok(self):
            for partner in self:
                partner.revision_type_ok = True
                if (partner.revision_type == "1y") and (partner.revision_mandat_cac) :
                    partner.revision_type_ok = False
                if (partner.revision_type == "1y") and (partner.cooperative_form_id.name == "SCIC") :
                    partner.revision_type_ok = False
    
    
        # ------------------------------------------------------
    
        # Button & Action
    
        # ------------------------------------------------------
    
        def open_facebook(self):
            self.ensure_one()
            return {
                "type": "ir.actions.act_url",
                "url": self.facebook,
            }
    
        def open_linkedin(self):
            self.ensure_one()
            return {
                "type": "ir.actions.act_url",
                "url": self.linkedin,
            }
    
        def open_twitter(self):
            self.ensure_one()
            return {
                "type": "ir.actions.act_url",
                "url": self.twitter,
            }
    
        def open_instagram(self):
            self.ensure_one()
            return {
                "type": "ir.actions.act_url",
                "url": self.instagram,
            }
    
        def open_pappers(self):
            self.ensure_one()
            return {
                "type": "ir.actions.act_url",
                "url": self.pappers_url,
            }
    
        def remove_director(self):
            self.write({"mandate_id": False})
            return {"type": "ir.actions.act_window_close"}
    
    
        def scop_prj_adhesion(self):
    
    Juliana's avatar
    Juliana a validé
            self.write({"membership_status": "adhesion"})
    
    Juliana's avatar
    Juliana a validé
                    "project_status": "5_abandonne",
    
                        self.env.ref("cgscop_partner.scop_partner_director_form_view").id,
    
                        "form",
                    ]
                ],
                "view_mode": "form",
                "res_model": "res.partner",
                "target": "new",
                "context": {
                    "default_parent_id_onchange": self.id,
                    "default_street": self.street,
                    "default_street2": self.street2,
                    "default_street3": self.street3,
                    "default_city": self.city,
                    "default_city_id": self.city_id.id,
                    "default_cedex": self.cedex,
                    "default_state_id": self.state_id.id,
                    "default_zip": self.zip,
                    "default_country_id": self.country_id.id,
                    "default_lang": self.lang,
                    "default_user_id": self.user_id.id,
                    "ur_id": self.ur_id.id,
                    "default_type": "contact",
    
                        self.env.ref("cgscop_partner.scop_partner_director_form_view").id,
    
                        "form",
                    ]
                ],
                "view_mode": "form",
                "res_model": "res.partner",
                "res_id": self.id,
                "target": "new",
    
                        self.env.ref("cgscop_partner.scop_partner_contact_form_view").id,
    
                        "form",
                    ]
                ],
                "view_mode": "form",
                "res_model": "res.partner",
                "target": "new",
                "context": {
                    "default_parent_id_onchange": self.id,
                    "default_street": self.street,
                    "default_street2": self.street2,
                    "default_street3": self.street3,
                    "default_city": self.city,
                    "default_city_id": self.city_id.id,
                    "default_cedex": self.cedex,
                    "default_state_id": self.state_id.id,
                    "default_zip": self.zip,
                    "default_country_id": self.country_id.id,
                    "default_lang": self.lang,
                    "default_user_id": self.user_id.id,
    
                        self.env.ref("cgscop_partner.scop_partner_contact_form_view").id,
    
                        "form",
                    ]
                ],
                "view_mode": "form",
                "res_model": "res.partner",
                "res_id": self.id,
                "target": "new",
    
        def write_contact(self):
            return self
    
    
            """
            Affichage des coop avec filtre par défaut
            """
    
            ctx = {
                "default_is_company": True,
                "default_is_cooperative": True,
                "default_company_type": "company",
    
    Juliana's avatar
    Juliana a validé
                "default_project_status": "4_suivi",
    
    
            # Détermine le filtre par défaut pour l'affichage
    
            filtre = self.env.company.ur_id.partner_filter
    
                ctx.update({"search_default_is_adherent": True})
    
                ctx.update({"search_default_my_ur_adherent": True})
    
                ctx.update({"search_default_is_federation_com": True})
    
                ctx.update({"search_default_is_federation_indus": True})
    
                ctx.update({"search_default_my_is_federation_btp": True})
    
                ctx.update({"search_default_my_is_federation_cae": True})
    
                "name": "Coopératives",
                "type": "ir.actions.act_window",
                "res_model": "res.partner",
                "search_view_id": (
                    self.env.ref("cgscop_partner.scop_partner_view_search").id,
                ),
                "view_mode": "tree,form,activity",
                "views": [
                    (
    
                        self.env.ref("cgscop_partner.view_partner_cooperative_tree").id,
    
                        "tree",
                    ),
                    (
                        self.env.ref("cgscop_partner.scop_contact_view_form").id,
                        "form",
                    ),
                ],
                "target": "current",
                "domain": [
                    ("is_cooperative", "=", True),
    
    Juliana's avatar
    Juliana a validé
                    ("project_status", "=", "4_suivi"),
    
                "context": ctx,
    
    Juliana's avatar
    Juliana a validé
        def show_creation_project(self):
    
    Juliana's avatar
    Juliana a validé
            Affichage des projets en création avec filtre par défaut
    
            ctx = {
                "default_is_company": True,
                "default_is_cooperative": True,
                "default_company_type": "company",
                "default_project_status": "1_information",
            }
    
    
            # Détermine le filtre par défaut pour l'affichage
    
            filtre = self.env.company.ur_id.partner_filter
    
                ctx.update({"search_default_my_ur": True})
    
    Juliana's avatar
    Juliana a validé
                "name": "Projets de création",
    
                "type": "ir.actions.act_window",
                "res_model": "res.partner",
                "search_view_id": (
                    self.env.ref("cgscop_partner.scop_partner_view_search").id,
                ),
                "view_mode": "kanban,tree,form,activity",
                "views": [
                    (
    
                        self.env.ref("cgscop_partner.view_partner_cooperative_kanban").id,
    
                        self.env.ref("cgscop_partner.view_partner_prospect_tree").id,
    
                        "tree",
                    ),
                    (
                        self.env.ref("cgscop_partner.scop_contact_view_form").id,
                        "form",
                    ),
                ],
                "target": "current",
                "domain": [
                    ("is_cooperative", "=", True),
                    (
                        "project_status",
                        "in",
                        (
                            "1_information",
                            "2_pre-diagnostic",
                            "3_accompagnement",
    
    Juliana's avatar
    Juliana a validé
                            "5_abandonne",
    
                "context": ctx,
    
            """
            Affichage des organismes avec filtre par défaut
            """
    
            ctx = {
                "default_is_company": True,
                "default_is_cooperative": True,
                "default_company_type": "company",
                "default_project_status": "1_information",
            }
    
    
            # Détermine le filtre par défaut pour l'affichage
    
            filtre = self.env.company.ur_id.partner_filter
    
                ctx.update({"search_default_my_ur_adherent": True})
    
                "name": "Tous les organismes",
                "type": "ir.actions.act_window",
                "res_model": "res.partner",
                "search_view_id": (
                    self.env.ref("cgscop_partner.scop_partner_view_search").id,
                ),
                "view_mode": "tree,form,activity",
                "views": [
                    (
    
                        self.env.ref("cgscop_partner.view_partner_cooperative_tree").id,
    
                        "tree",
                    ),
                    (
                        self.env.ref("cgscop_partner.scop_contact_view_form").id,
                        "form",
                    ),
                ],
                "target": "current",
    
    Juliana's avatar
    Juliana a validé
                "domain": [
                    ("is_cooperative", "=", True),
                ],
                "context": ctx,
            }
    
        def show_processus_adhesion(self):
            """
            Affichage des coopératives dans leur processus d'adhésion par défaut
            """
            ctx = {
                "default_is_company": True,
                "default_is_cooperative": True,
                "default_company_type": "company",
                "default_project_status": "4_suivi",
            }
    
            # Détermine le filtre par défaut pour l'affichage
            filtre = self.env.company.ur_id.partner_filter
            if filtre == "2":
    
                ctx.update({"search_default_my_ur": True})
    
    Juliana's avatar
    Juliana a validé
    
            return {
                "name": "Processus d'adhésion",
                "type": "ir.actions.act_window",
                "res_model": "res.partner",
                "search_view_id": (
                    self.env.ref("cgscop_partner.scop_partner_view_search").id,
                ),
                "view_mode": "kanban,tree,form,activity",
                "views": [
                    (
                        self.env.ref("cgscop_partner.view_partner_adhesion_kanban").id,
                        "kanban",
                    ),
                    (
                        self.env.ref("cgscop_partner.view_partner_prospect_tree").id,
                        "tree",
                    ),
                    (
                        self.env.ref("cgscop_partner.scop_contact_view_form").id,
                        "form",
                    ),
                ],
                "target": "current",
                "domain": [
                    ("is_cooperative", "=", True),
                    (
    
                        "membership_status",
    
    Juliana's avatar
    Juliana a validé
                        "in",
    
                        ("adhesion", "soumis_cg"),
    
                "context": ctx,
    
        # ------------------------------------------------------
        # Business Methods
        # ------------------------------------------------------
        def get_formatted_address(self):
            self.ensure_one()
            address_fields = [self.street, self.street2, self.street3]
            address = [f for f in address_fields if f]
            return "\n".join(address) if address else ""
    
    
        def get_postal_address(self):
            self.ensure_one()
            street_address_fields = [self.postal_street, self.postal_street2, self.postal_street3]
            street_address_list = list(filter(bool, street_address_fields))
            city_address_list = list(filter(bool, self.postal_zip, self.postal_city))
            street_address = "\n".join(street_address_list) if street_address_list else ""
            city_address = " ".join(city_address_list) if city_address_list else ""
            cedex = f" CEDEX {self.postal_cedex}" if self.postal_cedex else ""
            return f"{street_address}\n{city_address}{cedex}"
    
    
        def _get_staff_lines(self):
            self.ensure_one()
            return self.staff_ids.sorted(key="effective_date", reverse=True)
    
    
        # ------------------------------------------------------
        # CRON function
        # ------------------------------------------------------
        def _cron_geoloc_data_gouv(self, days=1):
            # Récupération des valeurs de suivi sur zip/city/street de la veille
            yesterday = fields.Date.today() - timedelta(days=days)
    
            partner_model = self.env["ir.model"].search([("model", "=", "res.partner")])
            address_values = self.env["ir.model.fields"].search(
                [
                    ("model_id", "=", partner_model.id),
                    ("name", "in", ["street", "street2", "zip", "city"]),
                ]
            )
    
            mail_tracking_value_ids = self.env["mail.tracking.value"].search(
                [
    
                    ("field", "in", address_values.ids),
    
                    ("create_date", ">=", yesterday),
                ]
            )
    
    
            # Récupération des messages de notif sur
            # res.partner en lien avec les valeurs de suivi
    
            mail_mess_ids = self.env["mail.message"].search(
                [
                    ("model", "=", "res.partner"),
                    ("message_type", "=", "notification"),
                    ("tracking_value_ids", "in", mail_tracking_value_ids.ids),
                ]
            )
    
            partner_list = mail_mess_ids.mapped("res_id")
    
    
            # Récupération des partners pour calcul des données GPS
    
            partners = self.env["res.partner"].search(
    
                [
                    "|",
                    "|",
                    ("id", "in", partner_list),
                    ("partner_latitude", "=", 0.0),
                    ("partner_latitude", "=", False),
    
                    ("membership_status", "=", "member"),
    
    
            i = 0
            for partner in partners:
                partner.geo_localize()
                i += 1
                time.sleep(1)
    
            _logger.info("Mise à jour de %d coordonnées", i)