Sélectionner une révision Git
scop_questionnaire.py
Bifurcation depuis
Le Filament / Confédération Générale des SCOP / cgscop_partner
Le projet source a une visibilité limitée.
res_partner.py 52,88 Kio
# © 2019 Le Filament (<http://www.le-filament.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import logging
import time
from datetime import datetime, timedelta
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
_logger = logging.getLogger(__name__)
class ScopPartner(models.Model):
_inherit = "res.partner"
def _default_ur(self):
return self.env["res.company"]._ur_default_get()
def _default_country(self):
return self.env.ref("base.fr", False)
@api.model
def _get_domain_incubator_id(self):
try:
incubator_id = self.env.ref("cgscop_partner.incubator").id
return [
("is_company", "=", True),
("organization_subtype_id", "=", incubator_id),
]
except Exception:
return [("is_company", "=", True)]
@api.model
def _get_domain_revision_company_id(self):
try:
rev_id = self.env.ref("cgscop_partner.riga_14953").id
com_id = self.env.ref("cgscop_partner.riga_16433").id
return [
("is_company", "=", True),
("organization_subtype_id", "in", [com_id, rev_id]),
]
except Exception:
return [("is_company", "=", True)]
# Infos générales - champs non affichés
is_cooperative = fields.Boolean("Est une coopérative")
current_user_ur_id = fields.Many2one(
"union.regionale",
string="Union Régionale de l'utilisateur",
compute="_compute_current_user_ur_id",
search="_search_current_user_ur_id",
)
# Informations organisme - champs non affichés
id_ur = fields.Char("Identifiant UR")
id_riga = fields.Char("Identifiant RIGA")
# Informations Bandeau
project_status = fields.Selection(
[
("1_information", "Phase d'information"),
("2_pre-diagnostic", "Phase de pré-diagnostic"),
("3_accompagnement", "Phase d'accompagnement projet"),
("4_suivi", "Phase de suivi"),
("5_abandonne", "Projet abandonné"),
("6_decede", "Coop Décédée"),
],
tracking=True,
string="Statut projet",
index=True,
)
name = fields.Char(index=True, tracking=True)
cooperative_form_id = fields.Many2one(
"res.partner.cooperative.form",
string="Cooperative form",
ondelete="restrict",
tracking=True,
)
partner_company_type_id = fields.Many2one(
comodel_name="res.partner.company.type",
string="Statut Juridique",
ondelete="restrict",
tracking=True,
)
membership_status = fields.Selection(
[
("not_member", "Non Adhérent"),
("adhesion", "Phase d'Adhésion"),
("soumis_cg", "Soumis CG"),
("member", "Adhérent"),
("out", "Radié"),
],
string="Statut d'adhésion",
default="not_member",
)
member_number = fields.Char(
"No adhérent (texte)", compute="_compute_membership_number", store=True
)
member_number_int = fields.Integer(
"No adhérent",
group_operator="",
)
member_start_stat = fields.Date(
"Date d'adhésion statistique",
compute="_compute_membership",
store=True,
)
member_start = fields.Date(
"Date d'adhésion", compute="_compute_membership", store=True
)
cae = fields.Boolean("CAE", tracking=True)
dissolution_date = fields.Date("Date de Décès", tracking=True)
dissolution_reason_id = fields.Many2one(
"res.partner.dissolution.reason",
string="Motif Décès",
ondelete="restrict",
tracking=True,
)
# Infos générales / Contact
sigle = fields.Char("Sigle")
street = fields.Char("Rue", tracking=1)
street2 = fields.Char("Rue 2", tracking=1)
street3 = fields.Char("Rue 3", tracking=1)
zip = fields.Char("CP", change_default=True, tracking=1)
zip_departement = fields.Char(
"Num Département", compute="_compute_num_departement", store=True
)
region = fields.Many2one(
comodel_name="res.country.state",
string="Région",
compute="_compute_region",
store=True,
)
city = fields.Char("Ville", tracking=1)
cedex = fields.Char("Cedex", tracking=1)
country_id = fields.Many2one(
"res.country",
string="Pays",
ondelete="restrict",
default=_default_country,
tracking=True,
)
phone = fields.Char("Téléphone 1", tracking=True)
mobile = fields.Char("Téléphone 2", tracking=True)
email = fields.Char("eMail administratif", tracking=True)
facebook = fields.Char("Facebook")
linkedin = fields.Char("LinkedIn")
twitter = fields.Char("Twitter")
instagram = fields.Char("Instagram")
# Infos générales / Suivi UR
ur_id = fields.Many2one(
"union.regionale",
string="Union Régionale",
index=True,
ondelete="restrict",
default=_default_ur,
tracking=True,
)
creation_delegate_id = fields.Many2one(
"res.users",
string="Délégué de création",
ondelete="restrict",
tracking=True,
)
followup_delegate_id = fields.Many2one(
"res.users",
string="Délégué de suivi",
domain=[("active", "=", True)],
ondelete="restrict",
tracking=True,
)
support_delegate_id = fields.Many2one(
"res.users",
string="Délégué en support",
domain=[("active", "=", True)],
ondelete="restrict",
tracking=True,
)
segment_1_id = fields.Many2many(
"res.partner.segment1",
column1="partner_id",
column2="segment_id",
string="Segmentation 1",
)
segment_2_id = fields.Many2many(
"res.partner.segment2",
column1="partner_id",
column2="segment_id",
string="Segmentation 2",
)
segment_3_id = fields.Many2many(
"res.partner.segment3",
column1="partner_id",
column2="segment_id",
string="Segmentation 3",
)
segment_4_id = fields.Many2many(
"res.partner.segment4",
column1="partner_id",
column2="segment_id",
string="Segmentation 4",
)
segment_1_nb = fields.Integer(
string="Nb de segments 1", compute="_compute_segment_nb"
)
segment_2_nb = fields.Integer(
string="Nb de segments 2", compute="_compute_segment_nb"
)
segment_3_nb = fields.Integer(
string="Nb de segments 3", compute="_compute_segment_nb"
)
segment_4_nb = fields.Integer(
string="Nb de segments 4", compute="_compute_segment_nb"
)
filiere_ids = fields.Many2many(
"res.partner.filiere",
column1="partner_id",
column2="filiere_id",
string="Filière",
)
is_mucs = fields.Boolean(string="Est adhérent Mucs", tracking=True)
is_mucs_update_date = fields.Date(string="Date MAJ Mucs", tracking=True)
is_union_sociale = fields.Boolean(
string="Est adhérent Union Sociale", tracking=True
)
is_union_sociale_update_date = fields.Date(
string="Date MAJ Union Sociale", tracking=True
)
# Infos générales / Infos activité
creation_origin_id = fields.Many2one(
"res.partner.creation.origin",
string="Origine création en coop",
domain=[("parent_id", "=", False)],
ondelete="restrict",
tracking=True,
)
creation_suborigin_id = fields.Many2one(
"res.partner.creation.origin",
string="Sous-Origine création en coop",
domain=[("child_ids", "=", False)],
ondelete="restrict",
tracking=True,
)
date_1st_sign = fields.Date("Date 1ère signature coop", tracking=True)
registration_date = fields.Date(string="Date d'immatriculation RCS", tracking=True)
social_object = fields.Text("Objet Social", tracking=True)
naf_id = fields.Many2one(
"res.partner.naf",
string="Code NAF",
ondelete="restrict",
tracking=True,
)
secteur_id = fields.Many2one(
"res.partner.secteur.activite",
string="Secteur d'activité",
related="naf_id.secteur_id",
store=True,
)
activity_desc = fields.Text("Description de l'activité", tracking=True)
certification_ids = fields.Many2many(
comodel_name="res.partner.certification",
string="Agréments",
ondelete="restrict",
)
other_certification = fields.Char(string="Autre agrément", required=False)
siret = fields.Char(string="SIRET", size=14, index=True, tracking=True, copy=False)
formatted_siret = fields.Char(
string="SIRET formaté", compute="_compute_formatted_siret"
)
siren = fields.Char(string="SIREN", size=11, compute="_compute_siren")
pappers_url = fields.Char(string="URL Pappers", compute="_compute_siren")
capital = fields.Integer("Capital (en €)")
first_closeout = fields.Date("1er bilan en coop")
closeout_month = fields.Selection(
[
("1", "Janvier"),
("2", "Février"),
("3", "Mars"),
("4", "Avril"),
("5", "Mai"),
("6", "Juin"),
("7", "Juillet"),
("8", "Août"),
("9", "Septembre"),
("10", "Octobre"),
("11", "Novembre"),
("12", "Décembre"),
],
string="Mois clôture exercices",
)
is_seed_scop = fields.Boolean("Est une SCOP d'amorçage")
seed_end = fields.Date("Date de fin du dispositif d'amorçage")
is_incubated = fields.Boolean("Est incubé")
incubator_id = fields.Many2one(
"res.partner",
string="Incubateur",
domain=_get_domain_incubator_id,
ondelete="restrict",
)
is_ag_constitution = fields.Boolean("AG constitutive réalisée")
is_federation_com = fields.Boolean(
string="Fédération de la Communication",
compute="_compute_federation",
store=True,
default=False,
)
is_federation_btp = fields.Boolean(
string="Fédération du BTP",
compute="_compute_federation",
store=True,
default=False,
)
is_federation_indus = fields.Boolean(
string="Fédération de l'Industrie",
compute="_compute_federation",
store=True,
default=False,
)
is_federation_cae = fields.Boolean(
string="Fédération des CAE",
compute="_compute_federation",
store=True,
default=False,
)
activity_federation_com_ids = fields.Many2many(
comodel_name="scop.federation.com.activity",
relation="res_partner_federation_com_activity_rel",
column1="partner_id",
column2="com_activity_id",
string="Domaine d'activité Com",
help="Fédération de la Com - Domaine d'activité",
)
activity_federation_indus_ids = fields.Many2many(
comodel_name="scop.federation.indus.activity",
relation="res_partner_federation_indus_activity_rel",
column1="partner_id",
column2="indus_activity_id",
string="Domaine d'activité Industrie",
help="Fédération de l'Industrie - Domaine d'activité",
)
copadev_member = fields.Boolean(string="Adhérent copadev", tracking=True)
# Contacts
director_ids = fields.One2many(
"res.partner",
"parent_id",
string="Contacts Dirigeants",
domain=[("mandate_id", "!=", False)],
)
other_child_ids = fields.One2many(
"res.partner",
"parent_id",
string="Autres Contacts",
domain=[("mandate_id", "=", False)],
)
# Révisions
revision_contract = fields.Date("Date du contrat de révision", tracking=True)
revision_company_id = fields.Many2one(
"res.partner",
string="Organisme de révision",
domain=_get_domain_revision_company_id,
ondelete="restrict",
tracking=True,
)
revision_backup_company_id = fields.Many2one(
"res.partner",
string="Organisme de révision suppléant",
domain=_get_domain_revision_company_id,
ondelete="restrict",
)
revision_person_id = fields.Many2one(
comodel_name="res.users",
string="Réviseur",
ondelete="restrict",
tracking=True,
)
revision_certified_person_id = fields.Many2one(
comodel_name="res.users", string="Réviseur agréé", ondelete="restrict"
)
revision_person_assign_date = fields.Date(
string="Date de nomination du réviseur", tracking=True
)
revision_type = fields.Selection(
[
("1y", "Annuelle"),
("5y", "Quinquennale"),
("5ys", "Quinquennale séquencée (annuel)"),
("5ys23", "Quinquennale séquencée (2 ans et 3 ans)"),
],
string="Périodicité de la révision",
)
revision_next_date = fields.Date("Prochain exercice révisable (old)")
revision_format_id = fields.Many2one(
"scop.revision.format",
string="Format de révision",
ondelete="restrict",
)
revision_tarif = fields.Integer(
"Tarif de vente", related="revision_format_id.tarif", store=False
)
revision_next_exercice = fields.Integer(
"Prochain exercice révisable",
compute="_compute_revision_next_exercice",
store=True,
)
revision_next_year = fields.Integer(
"Année prochaine révision",
compute="_compute_revision_next_year",
store=True,
)
revision_ids = fields.One2many(
comodel_name="scop.revision",
inverse_name="partner_id",
string="Liste des Révisions",
)
# Action RSE
action_rse_ids = fields.One2many(
comodel_name="scop.action.rse",
inverse_name="partner_id",
string="Liste des Actions RSE",
)
is_rse = fields.Boolean(
string="Engagement RSE", compute="_compute_is_rse", store=True, default=False
)
# Historique
scop_period_ids = fields.One2many(
comodel_name="scop.period",
inverse_name="partner_id",
string="Historique",
)
# Période d'adhésion
membership_period_ids = fields.One2many(
comodel_name="scop.membership.period",
inverse_name="partner_id",
string="Périodes d'adhésion",
)
# Effectifs
staff_ids = fields.One2many(
comodel_name="scop.partner.staff",
inverse_name="partner_id",
string="Effectifs",
)
# Liste Ministère
staff_last = fields.Integer(
string="Dernier effectif connu",
compute="_compute_last_effective",
store=True,
)
staff_shareholder_last = fields.Integer(
string="Dernier effectif associés connu",
compute="_compute_last_effective",
store=True,
)
staff_last_date = fields.Date(
string="Date dernier effectif connu",
compute="_compute_last_effective",
store=True,
)
# Champs pour personnes
birthyear = fields.Integer("Année de naissance")
subscription_ids = fields.One2many(
comodel_name="res.partner.newsletter.subscription",
inverse_name="partner_id",
string="Abonnements",
)
contact_origin_id = fields.Many2one(
"res.partner.rgpd.origin",
string="Origine du contact",
ondelete="restrict",
)
mandate_id = fields.Many2one(
"res.partner.mandate", string="Mandat", ondelete="restrict"
)
function_lst_id = fields.Many2one(
"res.partner.function_lst", string="Fonction", ondelete="restrict"
)
contact_legality = fields.Selection(
[
("employee", "Salarié"),
("customer", "Client en contrat"),
("supplier", "Fournisseur en contrat"),
("consent", "Consentement"),
("legitimate", "Intérêt légitime"),
("none", "Aucune"),
],
string="Licéité du contact",
compute="_compute_contact_legality",
store=True,
)
associate = fields.Selection(
selection=[
("asso", "Associé extérieur"),
("coop", "Associé coopérateur"),
("none", "Non associé"),
],
string="Associé",
)
employee = fields.Boolean(string="Salarié", default=True)
# Champs pour partenaires
organization_type_id = fields.Many2one(
"res.partner.organization.type",
string="Famille",
ondelete="restrict",
compute="_compute_org_type_id",
tracking=True,
)
organization_subtype_id = fields.Many2one(
"res.partner.organization.type",
string="Type",
domain=[("child_ids", "=", False)],
ondelete="restrict",
tracking=True,
)
# Droits utilisateurs
is_administrative = fields.Boolean(compute="_compute_is_administrative")
# Hack pour la création de contacts depuis la fiche organisme
parent_id_onchange = fields.Many2one("res.partner")
# ------------------------------------------------------
# Constrains
# ------------------------------------------------------
@api.constrains("zip_id", "country_id", "city_id", "state_id")
def _check_zip(self):
return
@api.constrains("siret")
def _check_siret(self):
if self.siret and not self.env.context.get("import_file"):
siren = self.siret[:3] + " " + self.siret[3:6] + " " + self.siret[6:9]
if not self.siret.isdigit():
raise ValidationError(_("Ce SIRET n'est pas valide"))
if len(self.siret) != 14:
raise ValidationError(_("La longueur du SIRET doit être égale à 14"))
if (
self.search_count(
[
("siret", "=like", siren + "%"),
("is_cooperative", "=", True),
]
)
> 1
):
raise ValidationError(_("Ce SIREN existe déjà parmi les coopératives"))
elif self.search_count([("siret", "=", self.siret)]) > 1:
raise ValidationError(_("Ce SIRET existe déjà"))
# ------------------------------------------------------
# Actions
# ------------------------------------------------------
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"}
# ------------------------------------------------------
# Onchange
# ------------------------------------------------------
# TODO: à vérifier
# Hack pour la création de contacts depuis la fiche organisme
@api.onchange("parent_id_onchange")
def _onchange_parent_id_onchange(self):
self.parent_id = self.parent_id_onchange
# TODO: à vérifier
@api.onchange("parent_id")
def _onchange_parent_id(self):
if self.parent_id.ur_id:
self.ur_id = self.parent_id.ur_id
@api.onchange("ur_id")
def _onchange_ur_id(self):
if self.child_ids:
for child in self.child_ids:
child.ur_id = self.ur_id
@api.onchange("creation_origin_id")
def onchange_creation_origin_id(self):
for coop in self:
coop.creation_suborigin_id = False
# TODO: à vérifier
@api.onchange("is_seed_scop")
def onchange_is_seed_scop(self):
for coop in self:
if coop.is_seed_scop:
if coop.date_1st_sign:
coop.seed_end = coop.date_1st_sign + timedelta(2556)
else:
coop.seed_end = datetime.today().date() + timedelta(2556)
else:
coop.seed_end = False
@api.onchange("name")
def onchange_name(self):
if self.search_count([("name", "=ilike", self.name)]) > 0:
return {
"warning": {
"title": "Attention",
"message": "Ce nom / cette raison sociale existe déjà, "
+ "merci de vérifier que vous n'êtes pas en "
+ "train de créer un doublon",
}
}
@api.onchange("mobile")
def onchange_mobile(self):
if self.mobile and len(self.mobile) > 0 and len(self.mobile) < 10:
raise ValidationError(
_("Le numéro de téléphone doit contenir au moins 10 caractères")
)
@api.onchange("phone")
def onchange_phone(self):
if self.phone and len(self.phone) > 0 and len(self.phone) < 10:
raise ValidationError(
_("Le numéro de téléphone doit contenir au moins 10 caractères")
)
@api.onchange("siret")
def onchange_siret(self):
if self.siret:
siren = self.siret[:3] + " " + self.siret[3:6] + " " + self.siret[6:9]
if self.search_count([("siret", "=like", self.siret)]) > 0:
return {
"warning": {
"title": "Attention",
"message": "Ce SIRET existe déjà, merci de vérifier "
+ "que vous n'êtes pas en train de créer un"
+ " doublon",
}
}
elif self.search_count([("siret", "=like", siren + "%")]) > 0:
return {
"warning": {
"title": "Attention",
"message": "Ce SIREN existe déjà, merci de vérifier "
+ "que vous n'êtes pas en train de créer un"
+ " doublon",
}
}
@api.onchange("cooperative_form_id")
def onchange_cooperative_form_id(self):
if self.cooperative_form_id == self.env.ref(
"cgscop_partner.form_noncooperative"
):
self.creation_origin_id = None
self.creation_suborigin_id = None
self.is_ag_constitution = None
self.date_1st_sign = None
self.first_closeout = None
# ------------------------------------------------------
# Common functions
# ------------------------------------------------------
def _create_period(self, partner):
new_period = self.env["scop.period"].create(
{
"partner_id": partner.id,
"start": partner.registration_date or fields.Date.today(),
"name": partner.name,
"cooperative_form_id": partner.cooperative_form_id.id,
"partner_company_type_id": partner.partner_company_type_id.id,
"siret": partner.siret,
"street": partner.street,
"street2": partner.street2,
"street3": partner.street3,
"zip": partner.zip,
"zip_id": partner.zip_id.id,
"city": partner.city,
"cedex": partner.cedex,
"state_id": partner.state_id.id,
"country_id": partner.country_id.id,
"naf_id": partner.naf_id.id,
"ur_id": partner.ur_id.id,
"cae": partner.cae,
}
)
partner.scop_period_ids = new_period
# ------------------------------------------------------
# Override ORM
# ------------------------------------------------------
@api.model
def _name_search(
self, name, args=None, operator="ilike", limit=100, name_get_uid=None
):
args = args or []
domain = [
"|",
("name", operator, name),
("member_number", "ilike", name),
]
return self._search(domain + args, limit=limit, access_rights_uid=name_get_uid)
# Creation d'une periode lorsque le statut passe en Phase de Suivi
# TODO: à revoir et demander si mise en majuscule du nom de la structure
def write(self, vals):
# Gestion casse des informations
if vals.get("name"):
vals["name"] = vals.get("name").title()
if vals.get("lastname"):
vals["lastname"] = vals.get("lastname").title()
if vals.get("firstname"):
vals["firstname"] = vals.get("firstname").title()
if vals.get("city"):
vals["city"] = vals.get("city").upper()
if len(self) == 1 and self.parent_id:
if self.type in ("contact", "invoice", "private"):
parent_ur_id = self.parent_id.ur_id.id
vals["ur_id"] = parent_ur_id
result = super(ScopPartner, self).write(vals)
# Hack pour notification lors de la modification du logo
if "image_128" in vals:
self.message_post(
body=_("Modification Logo"),
subtype="cgscop_base.cg_values_change",
)
for partner in self:
# Contrainte de tel ou mail lors de la modification d'un contact
if (
not partner.is_company
and partner.type == "contact"
and not partner.user_ids
):
if not partner.email and not partner.phone and not partner.mobile:
raise ValidationError(
_(
"Vous devez saisir au moins un e-mail ou un téléphone\
pour "
+ partner.name
)
)
# Création d'une période lors du changement de statut en Suivi
# Todo: A voir si le statut reste à celui là
if vals.get("project_status") == "4_suivi" and not self.env.context.get(
"import_file"
):
if not partner.scop_period_ids:
partner._create_period(partner)
# Ajout des followers de la fiche
partners_to_subscribe = []
if partner.followup_delegate_id != partner.create_uid:
partners_to_subscribe.append(partner.followup_delegate_id.partner_id.id)
if partner.creation_delegate_id != partner.create_uid:
partners_to_subscribe.append(partner.creation_delegate_id.partner_id.id)
if partners_to_subscribe:
partner.message_subscribe(partner_ids=partners_to_subscribe)
return result
# TODO: à revoir
# Création d'une période lors de la création d'une coopérative
@api.model_create_multi
def create(self, vals_list):
# Gestion casse des informations
for vals in vals_list:
if vals.get("name"):
vals["name"] = vals.get("name").title()
if vals.get("lastname"):
vals["lastname"] = vals.get("lastname").title()
if vals.get("firstname"):
vals["firstname"] = vals.get("firstname").title()
if vals.get("city"):
vals["city"] = vals.get("city").upper()
partners = super(ScopPartner, self).create(vals_list)
for vals in vals_list:
# Création d'une période si la coop est en statut en Suivi
# Todo: A voir si le statut est bien celui là
if vals.get("is_cooperative") and vals.get("project_status") == "4_suivi":
for partner in partners:
if not partner.scop_period_ids:
partner._create_period(partner)
return partners
@api.model
def _address_fields(self):
address_fields = super(ScopPartner, self)._address_fields()
address_fields.append("cedex")
return address_fields
# ------------------------------------------------------
# Override parent
# ------------------------------------------------------
def _get_contact_name(self, partner, name):
super(ScopPartner, self)._get_contact_name(partner, name)
return "%s, %s" % (
name,
partner.commercial_company_name or partner.sudo().parent_id.name,
)
# ------------------------------------------------------
# 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]
)
else:
partner.siren = None
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:]
)
else:
partner.formatted_siret = None
@api.depends("zip", "state_id")
def _compute_num_departement(self):
for company in self:
if company.zip:
if company.state_id:
try:
domtom = self.env.ref("cgscop_partner.domtom")
if company.state_id == domtom:
company.zip_departement = company.zip[:3]
else:
company.zip_departement = company.zip[:2]
except Exception:
company.zip_departement = company.zip[:2]
else:
company.zip_departement = company.zip[:2]
@api.depends("zip")
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
@api.model
def _compute_current_user_ur_id(self):
for partner in self:
partner.current_user_ur_id = self.env.company.ur_id
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",
)
def _compute_contact_legality(self):
for partner in self:
partner.contact_legality = "none"
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"
if partner.contact_origin_id.name in (
"Elus",
"VIP, Officiels",
"Fournisseurs",
):
partner.contact_legality = "legitimate"
if not partner.is_company and partner.parent_id:
parent = partner.parent_id
if (
partner.contact_origin_id.name
in (
"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"
@api.depends("action_rse_ids")
def _compute_is_rse(self):
"""
Est on une coop RSE
"""
for partner in self:
if len(partner.action_rse_ids) != 0:
partner.is_rse = True
@api.depends(
"membership_period_ids",
"membership_period_ids.end_reason_id",
"membership_period_ids.end",
)
# 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_stat = last_membership_period.start_stat
partner.member_start = last_membership_period.start
elif last_membership_period and last_membership_period.end_reason_id:
partner.membership_status = "out"
else:
partner.membership_status = "not_member"
@api.depends("member_number_int")
def _compute_membership_number(self):
for partner in 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(
"cgscop_partner.membership_type_2"
)
partner.is_federation_btp = partner._get_federation(
"cgscop_partner.membership_type_4"
)
partner.is_federation_indus = partner._get_federation(
"cgscop_partner.membership_type_3"
)
partner.is_federation_cae = partner._get_federation(
"cgscop_partner.membership_type_5"
)
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),
]
)
if membership_period:
return True
else:
return 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:
lm = partner.staff_ids.search(
[["partner_id", "=", partner.id], ["staff_count", ">", 0]],
limit=1,
order="effective_date desc",
)
if lm:
partner.staff_last = lm[0].staff_count
partner.staff_shareholder_last = lm[0].staff_shareholder_count
partner.staff_last_date = lm[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
else:
partner.organization_type_id = False
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")
def _compute_revision_next_year(self):
for partner in self:
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
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
)
# 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 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":
partner.revision_next_exercice = base_rev + 5
# 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
# ------------------------------------------------------
# Button & Action
# ------------------------------------------------------
def scop_send_to_cg(self):
# Todo: A vérifier pour le statut suivi car déjà en statut suivi normalement
self.write(
{
"project_status": "4_suivi",
"membership_status": "soumis_cg",
}
)
return True
def partner_archive(self):
self.active = False
def scop_valid_cg_button(self):
self.ensure_one()
self.scop_valid_cg()
def scop_valid_cg(self):
# Todo: A confirmer qu'on passe bien au statut member?
self.write(
{
"membership_status": "member",
}
)
return True
def scop_prj_adhesion(self):
self.write({"membership_status": "adhesion"})
return True
def scop_abandonne(self):
# Todo: A vérifier pour le statut member?
self.write(
{
"project_status": "5_abandonne",
}
)
return True
def add_director(self):
return {
"type": "ir.actions.act_window",
"views": [
[
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",
},
}
def edit_director(self):
return {
"type": "ir.actions.act_window",
"views": [
[
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",
}
def add_contact(self):
return {
"type": "ir.actions.act_window",
"views": [
[
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,
},
}
def edit_contact(self):
return {
"type": "ir.actions.act_window",
"views": [
[
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
def show_coop(self):
"""
Affichage des coop avec filtre 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 == "1":
ctx.update({"search_default_is_adherent": True})
elif filtre == "2":
ctx.update({"search_default_my_ur_adherent": True})
elif filtre == "3":
ctx.update({"search_default_is_federation_com": True})
elif filtre == "4":
ctx.update({"search_default_is_federation_indus": True})
elif filtre == "5":
ctx.update({"search_default_my_is_federation_btp": True})
elif filtre == "6":
ctx.update({"search_default_my_is_federation_cae": True})
return {
"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),
("project_status", "=", "4_suivi"),
],
"context": ctx,
}
def show_creation_project(self):
"""
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
if filtre == "2":
ctx.update({"search_default_my_ur": True})
return {
"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,
"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),
(
"project_status",
"in",
(
"1_information",
"2_pre-diagnostic",
"3_accompagnement",
"5_abandonne",
),
),
],
"context": ctx,
}
def show_organisme(self):
"""
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
if filtre == "2":
ctx.update({"search_default_my_ur_adherent": True})
return {
"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",
"domain": [
("is_cooperative", "=", True),
(
"project_status",
"in",
("4_suivi",),
),
],
"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_adherent": True})
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",
"in",
("adhesion", "soumis_cg"),
),
],
"context": ctx,
}
# ------------------------------------------------------
# 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)