Skip to content
Extraits de code Groupes Projets

Comparer les révisions

Les modifications sont affichées comme si la révision source était fusionnée avec la révision cible. En savoir plus sur la comparaison des révisions.

Source

Sélectionner le projet cible
No results found
Sélectionner une révision Git
  • 12.0
  • 12.0-lm-00
  • 13.0
  • 14.0
  • 14.0-2507-inpi
5 résultats

Cible

Sélectionner le projet cible
  • lefilament/cgscop/cgscop_partner
  • hsilvant/cgscop_partner
2 résultats
Sélectionner une révision Git
  • 12-RV-Bug_ecrasement_date_radiation
  • 12-RV-Correctif-open-instagram
  • 12-RV-Tree-Coop-Ajout-effectif
  • 12-RV-copadev
  • 12-RV-revision-staff
  • 12.0
  • 12.0-RV-Abonnements
  • 12.0-RV-Instagram
  • 12.0-RV-segment_visibility
  • 12.0-evo-202003
  • 14-RV-20231222
  • 14-RV-20240830
  • 14-RV-20250324
13 résultats
Afficher les modifications
Affichage de
avec 2458 ajouts et 900 suppressions
---Fields in module 'cgscop_partner'---
cgscop_partner / res.partner / project_status (selection) : selection_keys is now '['1_information','2_pre-diagnostic','3_accompagnement', '4_suivi', '5_abandonne', '6_decede'] ('['1_information','2_pre-diagnostic','3_accompagnement', '4_adhesion', '5_cg', '6_suivi', '7_abandonne']')
cgscop_partner / res.partner / membership_status (selection) : selection_keys is now '['not_member', 'adhesion', 'soumis_cg', 'member', 'out'] ('['not_member', 'adhesion', 'soumis_cg', 'member', 'out']')
# © 2019 Le Filament (<http://www.le-filament.com>) # © 2019 Le Filament (<http://www.le-filament.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import ir_http
from . import res_company from . import res_company
from . import mail_activity
from . import mail_activity_type from . import mail_activity_type
from . import res_partner from . import scop_revision
from . import scop_membership
from . import scop_period
from . import scop_partner_staff
from . import scop_federation_activity
from . import res_department
from . import res_partner_lists
from . import res_partner_newsletter from . import res_partner_newsletter
from . import res_partner
from . import res_users from . import res_users
from . import scop_contribution from . import scop_contribution
from . import scop_liasse_fiscale from . import scop_action_rse
from . import scop_membership from . import scop_action_te
from . import scop_period
from . import scop_questionnaire
from . import scop_revision
from . import union_regionale from . import union_regionale
# © 2019 Le Filament (<http://www.le-filament.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models
class IrHttp(models.AbstractModel):
_inherit = "ir.http"
def session_info(self):
"""
Ajoute l'ur_id dans le contexte
"""
result = super(IrHttp, self).session_info()
user = self.env.user
result["ur_id"] = user.company_id.ur_id.id
result["ur_company"] = dict(
user.company_ids.mapped(lambda c: (c.id, c.ur_id.id))
)
return result
# © 2019 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 MailActivity(models.Model):
_inherit = "mail.activity"
activity_type_id = fields.Many2one(
domain="""[
'|', ('res_model_id', '=', False), ('res_model_id', '=', res_model_id),
'|', ('ur_id','=',False), ('ur_id','=',context.get('current_ur_id', False))
]
""",
)
@api.model
def get_activity_data(self, res_model, domain):
"""
Surcharge la fonction parente pour n'afficher que les activités liées à l'UR
dans la vue Activité
"""
result = super(MailActivity, self).get_activity_data(res_model, domain)
activity_type_infos = []
activity_type_ids = self.env["mail.activity.type"].search(
[
"|",
("res_model_id.model", "=", res_model),
("res_model_id", "=", False),
"|",
("ur_id", "=", False),
("ur_id", "=", self.env.context.get("current_ur_id", False)),
]
)
for elem in sorted(activity_type_ids, key=lambda item: item.sequence):
mail_template_info = []
for mail_template_id in elem.mail_template_ids:
mail_template_info.append(
{"id": mail_template_id.id, "name": mail_template_id.name}
)
activity_type_infos.append([elem.id, elem.name, mail_template_info])
result["activity_types"] = activity_type_infos
return result
...@@ -8,11 +8,12 @@ class MailActivityType(models.Model): ...@@ -8,11 +8,12 @@ class MailActivityType(models.Model):
_inherit = "mail.activity.type" _inherit = "mail.activity.type"
def _default_ur(self): def _default_ur(self):
return self.env['res.company']._ur_default_get() return self.env["res.company"]._ur_default_get()
ur_id = fields.Many2one( ur_id = fields.Many2one(
'union.regionale', "union.regionale",
string='Union Régionale', string="Union Régionale",
index=True, index=True,
on_delete='restrict', ondelete="restrict",
default=_default_ur) default=_default_ur,
)
# © 2019 Le Filament (<http://www.le-filament.com>) # © 2019 Le Filament (<http://www.le-filament.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import fields, models, api from odoo import api, fields, models
class ResCompany(models.Model): class ResCompany(models.Model):
...@@ -10,6 +10,6 @@ class ResCompany(models.Model): ...@@ -10,6 +10,6 @@ class ResCompany(models.Model):
@api.model @api.model
def _ur_default_get(self): def _ur_default_get(self):
# Renvoie l'UR de l'utlisateur courant # Renvoie l'UR de l'utlisateur courant
return self.env['res.users']._get_ur() return self.env["res.users"]._get_ur()
ur_id = fields.Many2one('union.regionale', string='UR') ur_id = fields.Many2one("union.regionale", string="UR")
# © 2019 Le Filament (<http://www.le-filament.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import fields, models
class ResDepartment(models.Model):
_description = "Départements"
_name = "res.department"
_order = "code"
name = fields.Char(string="Nom", size=128, required=True)
code = fields.Char(
string="Numéro",
size=3,
required=True,
)
_sql_constraints = [
(
"code_uniq",
"unique (code)",
"You cannot have two departments with the same code!",
)
]
# © 2019 Le Filament (<http://www.le-filament.com>) # © 2019 Le Filament (<http://www.le-filament.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import logging
import time
from datetime import datetime, timedelta from datetime import datetime, timedelta
from odoo import models, fields, api
from odoo.exceptions import ValidationError from odoo import _, api, fields, models
from odoo.exceptions import UserError, ValidationError
from lxml import etree
_logger = logging.getLogger(__name__)
class ScopPartner(models.Model): class ScopPartner(models.Model):
_inherit = "res.partner" _inherit = "res.partner"
def _default_ur(self): def _default_ur(self):
return self.env['res.company']._ur_default_get() return self.env["res.company"]._ur_default_get()
def _default_country(self): def _default_country(self):
return self.env.ref('base.fr', False) 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)]
# Inherit parent
active = fields.Boolean(
tracking=True,
)
# Infos générales - champs non affichés # Infos générales - champs non affichés
is_cooperative = fields.Boolean("Est une coopérative") is_cooperative = fields.Boolean("Est une coopérative")
parent_is_cooperative = fields.Boolean(
string="Parent est une coopérative",
related="parent_id.is_cooperative",
)
current_user_ur_id = fields.Many2one( current_user_ur_id = fields.Many2one(
'union.regionale', "union.regionale",
string="Union Régionale de l'utilisateur", string="Union Régionale de l'utilisateur",
compute='_compute_current_user_ur_id', compute="_compute_current_user_ur_id",
search='_search_current_user_ur_id') search="_search_current_user_ur_id",
)
# Informations organisme - champs non affichés # Informations organisme - champs non affichés
id_ur = fields.Char("Identifiant UR") id_ur = fields.Char("Identifiant UR")
id_riga = fields.Char("Identifiant RIGA")
# Informations Bandeau # Informations Bandeau
project_status = fields.Selection( project_status = fields.Selection(
[('1_information', "Phase d'information"), [
('2_pre-diagnostic', 'Phase de pré-diagnostic'), ("1_information", "Phase d'information"),
('3_accompagnement', "Phase d'accompagnement projet"), ("2_pre-diagnostic", "Phase de pré-diagnostic"),
('4_adhesion', "Phase d'adhésion"), ("3_accompagnement", "Phase d'accompagnement projet"),
('5_cg', 'Soumis CGScop'), ("4_suivi", "Phase de suivi"),
('6_suivi', 'Phase de suivi'), ("5_abandonne", "Projet abandonné"),
('7_abandonne', 'Projet abandonné')], ("6_decede", "Coop Décédée"),
track_visibility='onchange', ],
string='Statut projet', tracking=True,
index=True) string="Statut projet",
name = fields.Char(index=True, track_visibility='onchange') index=True,
)
name = fields.Char(index=True, tracking=True, string="Dénomination Sociale")
nickname = fields.Char(string="Dénomination interne")
cooperative_form_id = fields.Many2one( cooperative_form_id = fields.Many2one(
'res.partner.cooperative.form', "res.partner.cooperative.form",
string="Cooperative form", string="Cooperative form",
on_delete='restrict', ondelete="restrict",
track_visibility='onchange') tracking=True,
)
partner_company_type_id = fields.Many2one( partner_company_type_id = fields.Many2one(
comodel_name='res.partner.company.type', comodel_name="res.partner.company.type",
string='Legal Form', string="Statut Juridique",
on_delete='restrict', ondelete="restrict",
track_visibility='onchange') tracking=True,
)
membership_status = fields.Selection( membership_status = fields.Selection(
[('member', 'Adhérent'), [
('not_member', 'Non Adhérent'), ("not_member", "Non Adhérent"),
('out', 'Radié')], ("adhesion", "Phase d'Adhésion"),
("soumis_cg", "Soumis CG"),
("member", "Adhérent"),
("out", "Radié"),
],
string="Statut d'adhésion", string="Statut d'adhésion",
compute='_compute_membership', store=True) default="not_member",
tracking=True,
)
member_number = fields.Char( member_number = fields.Char(
"No adhérent (texte)", "No adhérent (texte)", compute="_compute_membership_number", store=True
compute='_compute_membership', store=True) )
member_number_int = fields.Integer( member_number_int = fields.Integer(
"No adhérent", "No adhérent",
compute='_compute_membership_int', store=True, group_operator="") group_operator="",
cae = fields.Boolean("CAE", track_visibility='onchange') )
member_start = fields.Date(
dissolution_date = fields.Date('Date de Décès', "Date d'adhésion", compute="_compute_membership", store=True
track_visibility='onchange') )
cae = fields.Boolean("CAE", tracking=True)
dissolution_date = fields.Date("Date de Décès", tracking=True)
dissolution_reason_id = fields.Many2one( dissolution_reason_id = fields.Many2one(
'res.partner.dissolution.reason', "res.partner.dissolution.reason",
string="Motif Décès", string="Motif Décès",
on_delete='restrict', ondelete="restrict",
track_visibility='onchange') tracking=True,
)
# Infos générales / Contact # Infos générales / Contact
sigle = fields.Char("Sigle") sigle = fields.Char("Sigle")
street = fields.Char("Rue", track_visibility='onchange') street = fields.Char("Rue", tracking=1)
street2 = fields.Char("Rue 2", track_visibility='onchange') street2 = fields.Char("Rue 2", tracking=1)
street3 = fields.Char("Rue 3", track_visibility='onchange') street3 = fields.Char("Rue 3", tracking=1)
zip = fields.Char("CP", change_default=True, track_visibility='onchange') zip = fields.Char("CP", change_default=True, tracking=1)
zip_departement = fields.Char( zip_departement = fields.Char(
"Num Département", "Num Département", compute="_compute_num_departement", store=True
compute='_compute_num_departement', )
store=True)
region = fields.Many2one( region = fields.Many2one(
comodel_name='res.country.state', comodel_name="res.country.state",
string='Région', string="Région",
compute='_compute_region', compute="_compute_region",
store=True) store=True,
city = fields.Char("Ville", track_visibility='onchange') )
cedex = fields.Char("Cedex", track_visibility='onchange') city = fields.Char("Ville", tracking=1)
country_id = fields.Many2one('res.country', string='Country', cedex = fields.Char("Cedex", tracking=1)
ondelete='restrict', country_id = fields.Many2one(
"res.country",
string="Pays",
ondelete="restrict",
default=_default_country, default=_default_country,
track_visibility='onchange') tracking=True,
phone = fields.Char("Téléphone 1", track_visibility='onchange') )
mobile = fields.Char("Téléphone 2", track_visibility='onchange') # Adresse postale
email = fields.Char("eMail administratif", track_visibility='onchange') postal_street = fields.Char("Adresse postale - Rue", tracking=1)
postal_street2 = fields.Char("Adresse postale - Rue 2", tracking=1)
postal_street3 = fields.Char("Adresse postale - Rue 3", tracking=1)
postal_zip = fields.Char("Adresse postale - CP", tracking=1)
postal_city = fields.Char("Adresse postale - Ville", tracking=1)
postal_cedex = fields.Char("Adresse postale - Cedex", tracking=1)
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") facebook = fields.Char("Facebook")
linkedin = fields.Char("LinkedIn") linkedin = fields.Char("LinkedIn")
twitter = fields.Char("Twitter") twitter = fields.Char("Twitter")
instagram = fields.Char("Instagram")
# Infos générales / Suivi UR # Infos générales / Suivi UR
ur_id = fields.Many2one( ur_id = fields.Many2one(
'union.regionale', "union.regionale",
string='Union Régionale', string="Union Régionale",
index=True, index=True,
on_delete='restrict', ondelete="restrict",
default=_default_ur, default=_default_ur,
track_visibility='onchange') tracking=True,
)
creation_delegate_id = fields.Many2one( creation_delegate_id = fields.Many2one(
'res.users', "res.users",
string='Délégué de création', string="Délégué de création",
on_delete='restrict', track_visibility='onchange') ondelete="restrict",
tracking=True,
)
followup_delegate_id = fields.Many2one( followup_delegate_id = fields.Many2one(
'res.users', "res.users",
string='Délégué de suivi', string="Délégué de suivi",
domain=[('active', '=', True)], domain=[("active", "=", True)],
on_delete='restrict', ondelete="restrict",
track_visibility='onchange') tracking=True,
segment_1_id = fields.Many2many('res.partner.segment1', )
column1='partner_id', support_delegate_id = fields.Many2one(
column2='segment_id', "res.users",
string='Segmentation 1') string="Délégué en support",
segment_2_id = fields.Many2many('res.partner.segment2', domain=[("active", "=", True)],
column1='partner_id', ondelete="restrict",
column2='segment_id', tracking=True,
string='Segmentation 2') )
segment_3_id = fields.Many2many('res.partner.segment3', segment_1_id = fields.Many2many(
column1='partner_id', "res.partner.segment1",
column2='segment_id', column1="partner_id",
string='Segmentation 3') column2="segment_id",
segment_4_id = fields.Many2many('res.partner.segment4', string="Segmentation 1",
column1='partner_id', )
column2='segment_id', segment_2_id = fields.Many2many(
string='Segmentation 4') "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é # Infos générales / Infos activité
creation_origin_id = fields.Many2one( creation_origin_id = fields.Many2one(
'res.partner.creation.origin', "res.partner.creation.origin",
string="Origine création en coop", string="Origine création en coop",
domain=[('parent_id', '=', False)], domain=[("parent_id", "=", False)],
on_delete='restrict', track_visibility='onchange') ondelete="restrict",
tracking=True,
)
creation_suborigin_id = fields.Many2one( creation_suborigin_id = fields.Many2one(
'res.partner.creation.origin', "res.partner.creation.origin",
string="Sous-Origine création en coop", string="Sous-Origine création en coop",
domain=[('child_ids', '=', False)], domain=[("child_ids", "=", False)],
on_delete='restrict', track_visibility='onchange') ondelete="restrict",
date_1st_sign = fields.Date( tracking=True,
'Date 1er signature coop', )
track_visibility='onchange') date_1st_sign = fields.Date("Date 1ère signature coop", tracking=True)
registration_date = fields.Date( registration_date = fields.Date(string="Date d'immatriculation RCS", tracking=True)
string="Date d'immatriculation RCS", social_object = fields.Text("Objet Social", tracking=True)
track_visibility='onchange')
social_object = fields.Text('Objet Social', track_visibility='onchange')
naf_id = fields.Many2one( naf_id = fields.Many2one(
'res.partner.naf', "res.partner.naf",
string='Code NAF', string="Code NAF",
on_delete='restrict', ondelete="restrict",
track_visibility='onchange') 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)
activity_customers = fields.Selection(
[
("ND", "Non définie"),
("PR", "Clients professionnels"),
("PA", "Clients particuliers"),
("PP", "Clients professionnels et particuliers"),
],
string="Relation commerciale",
default="ND",
tracking=True,
)
certification_ids = fields.Many2many( certification_ids = fields.Many2many(
comodel_name='res.partner.certification', comodel_name="res.partner.certification",
string='Agrément', on_delete='restrict') string="Agréments",
siret = fields.Char(string='SIRET', size=14, index=True, ondelete="restrict",
track_visibility='onchange') )
formatted_siret = fields.Char(string='SIRET formaté', other_certification = fields.Char(string="Autre agrément", required=False)
compute='_compute_from_siret') siret = fields.Char(string="SIRET du siège", size=14, index=True, tracking=True, copy=False)
siren = fields.Char(string='SIREN', size=11, compute='_compute_from_siret') 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 €)") capital = fields.Integer("Capital (en €)")
first_closeout = fields.Date( first_closeout = fields.Date("1er bilan en coop")
'1er bilan en coop')
closeout_month = fields.Selection( closeout_month = fields.Selection(
[(12842, 'Janvier'), [
(12843, 'Février'), ("1", "Janvier"),
(12844, 'Mars'), ("2", "Février"),
(12845, 'Avril'), ("3", "Mars"),
(12846, 'Mai'), ("4", "Avril"),
(12847, 'Juin'), ("5", "Mai"),
(12848, 'Juillet'), ("6", "Juin"),
(12849, 'Août'), ("7", "Juillet"),
(12850, 'Septembre'), ("8", "Août"),
(12851, 'Octobre'), ("9", "Septembre"),
(12852, 'Novembre'), ("10", "Octobre"),
(12853, 'Décembre')], ("11", "Novembre"),
string='Mois clôture exercices', default=12853) ("12", "Décembre"),
],
string="Mois clôture exercices",
)
is_seed_scop = fields.Boolean("Est une SCOP d'amorçage") is_seed_scop = fields.Boolean("Est une SCOP d'amorçage")
seed_end = fields.Date("Date de fin du dispositif d'amorçage") seed_end = fields.Date("Date de fin du dispositif d'amorçage")
is_incubated = fields.Boolean("Est incubé") is_incubated = fields.Boolean("Est incubé")
incubator_id = fields.Many2one( incubator_id = fields.Many2one(
'res.partner', "res.partner",
string='Incubateur', string="Incubateur",
domain=[('active', '=', True), ('is_company', '=', True), domain=_get_domain_incubator_id,
('organization_subtype_id.name', '=', 'Incubateur')], ondelete="restrict",
on_delete='restrict') )
is_ag_constitution = fields.Boolean('AG constitutive réalisée') is_ag_constitution = fields.Boolean("AG constitutive réalisée")
is_registration_in_progress = fields.Boolean(
string="En cours d'immatriculation", default=False
)
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 # Contacts
director_ids = fields.One2many( director_ids = fields.One2many(
'res.partner', 'parent_id', "res.partner",
string='Contacts Dirigeants', "parent_id",
domain=[('active', '=', True), ('mandate_id', '!=', False)]) string="Contacts Dirigeants",
domain=[("mandate_id", "!=", False)],
)
other_child_ids = fields.One2many( other_child_ids = fields.One2many(
'res.partner', 'parent_id', string='Autres Contacts', "res.partner",
domain=[('active', '=', True), ('mandate_id', '=', False)]) "parent_id",
string="Autres Contacts",
domain=[("mandate_id", "=", False)],
)
# Révisions # Révisions
revision_contract = fields.Date("Date du contrat de révision", revision_contract = fields.Date(
track_visibility='onchange') string="Début du contrat de révision",
tracking=True,
)
revision_contract_end = fields.Date(
string="Fin du contrat de révision",
tracking=True,
)
revision_contract_tacite = fields.Boolean(
string="Tacite reconduction",
tracking=True,
default=False
)
revision_mandat_cac = fields.Boolean(
string="Mandat CAC actif",
tracking=True,
default=False
)
revision_company_id = fields.Many2one( revision_company_id = fields.Many2one(
'res.partner', "res.partner",
string='Organisme de révision', string="Organisme de révision",
domain=[('active', '=', True), ('is_company', '=', True), domain=_get_domain_revision_company_id,
'|', ('organization_subtype_id.name', '=', ondelete="restrict",
'Organisme réviseur'), tracking=True,
('organization_subtype_id.name', '=', 'Organisme réviseur, ' + )
'Expert-comptable / Commissaire au compte')],
on_delete='restrict',
track_visibility='onchange')
revision_backup_company_id = fields.Many2one( revision_backup_company_id = fields.Many2one(
'res.partner', "res.partner",
string='Organisme de révision suppléant', string="Organisme de révision suppléant",
domain=[('active', '=', True), ('is_company', '=', True), domain=_get_domain_revision_company_id,
'|', ('organization_subtype_id.name', '=', ondelete="restrict",
'Organisme réviseur'), tracking=True,
('organization_subtype_id.name', '=', 'Organisme réviseur, ' + )
'Expert-comptable / Commissaire au compte')],
on_delete='restrict')
revision_person_id = fields.Many2one( revision_person_id = fields.Many2one(
'res.users', comodel_name="res.users",
string='Réviseur', string="Réviseur",
on_delete='restrict', ondelete="restrict",
track_visibility='onchange') tracking=True,
)
revision_certified_person_id = fields.Many2one( revision_certified_person_id = fields.Many2one(
'res.users', comodel_name="res.users",
string='Réviseur agréé', string="Réviseur agréé",
on_delete='restrict') ondelete="restrict",
revision_person_assign_date = fields.Date("Date de nomination du réviseur", tracking=True,
track_visibility='onchange') )
revision_person_assign_date = fields.Date(
string="Date de nomination du réviseur", tracking=True
)
revision_person_assign_end = fields.Date(
string="Date de fin nomination réviseur", tracking=True
)
revision_type = fields.Selection( revision_type = fields.Selection(
[('1y', "Annuelle"), [
('5y', 'Quinquennale'), ("1y", "Annuelle"),
('5ys', "Quinquennale séquencée")], ("5y", "Quinquennale"),
string='Périodicité de la révision') ("5ys", "Quinquennale séquencée (annuel)"),
revision_next_date = fields.Date("Prochain exercice révisable") ("5ys23", "Quinquennale séquencée (2 ans et 3 ans)"),
],
string="Périodicité de la révision",
tracking=True,
)
revision_type_ok = fields.Boolean(
string="Périodicité de révision ok",
tracking=True,
compute="_compute_revision_type_ok",
)
revision_quinq_exercice = fields.Integer(
"Quinquénnale exercice à réviser",
compute="_compute_revision_quinq_exercice",
)
revision_next_date = fields.Date("Prochain exercice révisable (old)")
revision_format_id = fields.Many2one( revision_format_id = fields.Many2one(
'scop.revision.format', "scop.revision.format",
string='Format de révision', string="Format de révision",
on_delete='restrict') ondelete="restrict",
tracking=True,
)
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,
readonly=False,
)
revision_same_exercice = fields.Boolean(
string="Révision sur l'année de cloture",
tracking=True,
)
revision_next_year = fields.Integer(
"Année prochaine révision",
compute="_compute_revision_next_year",
store=True,
readonly=False,
)
revision_ids = fields.One2many( revision_ids = fields.One2many(
comodel_name='scop.revision', comodel_name="scop.revision",
inverse_name='partner_id', inverse_name="partner_id",
string='Liste des Révisions') string="Liste des Révisions",
)
revision_quinq_A1 = fields.Integer(
"Quinquénnale année 1",
compute="_compute_revision_quinq_annee",
)
revision_quinq_A2 = fields.Integer(
"Quinquénnale année 2",
compute="_compute_revision_quinq_annee",
)
revision_quinq_A3 = fields.Integer(
"Quinquénnale année 3",
compute="_compute_revision_quinq_annee",
)
revision_quinq_A4 = fields.Integer(
"Quinquénnale année 4",
compute="_compute_revision_quinq_annee",
)
revision_quinq_A5 = fields.Integer(
"Quinquénnale année 5",
compute="_compute_revision_quinq_annee",
)
revision_activite_A1 = fields.Integer(
"Activité révision année 1",
tracking=True,
)
revision_activite_A2 = fields.Integer(
"Activité révision année 2",
tracking=True,
)
revision_activite_A3 = fields.Integer(
"Activité révision année 3",
tracking=True,
)
revision_activite_A4 = fields.Integer(
"Activité révision année 4",
tracking=True,
)
revision_activite_A5 = fields.Integer(
"Activité révision année 5",
tracking=True,
)
# Action RSE et TE
action_rse_ids = fields.One2many(
comodel_name="scop.action.rse",
inverse_name="partner_id",
string="Liste des Actions RSE",
)
action_te_ids = fields.Many2many(
"scop.action.te",
column1="partner_id",
column2="action_id",
string="Expertises transition éco.",
)
is_rse = fields.Boolean(
string="Engagement TE", compute="_compute_is_rse", store=True, default=False
)
# Historique # Historique
scop_period_ids = fields.One2many( scop_period_ids = fields.One2many(
comodel_name='scop.period', comodel_name="scop.period",
inverse_name='partner_id', inverse_name="partner_id",
string="Historique") string="Historique",
)
# Période d'adhésion # Période d'adhésion
membership_period_ids = fields.One2many( membership_period_ids = fields.One2many(
comodel_name='scop.membership.period', comodel_name="scop.membership.period",
inverse_name='partner_id', inverse_name="partner_id",
string="Périodes d'adhésion") string="Périodes d'adhésion",
)
# Cotisation
contribution_ids = fields.One2many( # Effectifs
comodel_name='scop.contribution', staff_ids = fields.One2many(
inverse_name='partner_id', comodel_name="scop.partner.staff",
string='Cotisations') inverse_name="partner_id",
is_up_to_date_cg = fields.Boolean("A jour cotisation CG") string="Effectifs",
is_up_to_date_fede = fields.Boolean("A jour cotisation Fédérations") )
is_up_to_date_ur = fields.Boolean("A jour cotisation UR")
# Questionnaire
# Liste Ministère # Liste Ministère
direccte_id = fields.Many2one(
'res.partner',
string='DIRECCTE rattachée',
domain=[('active', '=', True), ('is_company', '=', True),
('organization_subtype_id', '=', 'DIRECCTE')],
on_delete='restrict')
questionnaire_ids = fields.One2many(
comodel_name='scop.questionnaire',
inverse_name='partner_id',
string='Listes Ministère')
staff_last = fields.Integer( staff_last = fields.Integer(
string="Dernier effectif connu", string="Dernier effectif connu",
compute="_compute_last_effective", compute="_compute_last_effective",
store=True) store=True,
)
staff_shareholder_last = fields.Integer(
string="Dernier effectif associés connu",
compute="_compute_last_effective",
store=True,
)
staff_last_date = fields.Date( staff_last_date = fields.Date(
string="Date dernier effectif connu", string="Date dernier effectif connu",
compute="_compute_last_effective", compute="_compute_last_effective",
store=True) store=True,
)
# Liasse fiscale
liasse_fiscale_ids = fields.One2many(
comodel_name='scop.liasse.fiscale',
inverse_name='partner_id',
string='Liasses Fiscales')
# Champs pour personnes # Champs pour personnes
birthyear = fields.Integer("Année de naissance") birthyear = fields.Integer("Année de naissance")
subscription_ids = fields.One2many( subscription_ids = fields.One2many(
comodel_name='res.partner.newsletter.subscription', comodel_name="res.partner.newsletter.subscription",
inverse_name='partner_id', inverse_name="partner_id",
string='Abonnements') string="Abonnements",
)
contact_origin_id = fields.Many2one( contact_origin_id = fields.Many2one(
'res.partner.rgpd.origin', "res.partner.rgpd.origin",
string="Origine du contact", string="Origine du contact",
on_delete='restrict') ondelete="restrict",
)
mandate_id = fields.Many2one( mandate_id = fields.Many2one(
'res.partner.mandate', "res.partner.mandate", string="Mandat", ondelete="restrict"
string="Mandat", )
on_delete='restrict') function_lst_id = fields.Many2one(
"res.partner.function_lst", string="Fonction", ondelete="restrict"
)
contact_legality = fields.Selection( contact_legality = fields.Selection(
[("employee", "Salarié"), [
("employee", "Salarié"),
("customer", "Client en contrat"), ("customer", "Client en contrat"),
("supplier", "Fournisseur en contrat"), ("supplier", "Fournisseur en contrat"),
("consent", "Consentement"), ("consent", "Consentement"),
("legitimate", "Intérêt légitime"), ("legitimate", "Intérêt légitime"),
("none", "Aucune")], ("none", "Aucune"),
],
string="Licéité du contact", string="Licéité du contact",
compute="_compute_contact_legality", compute="_compute_contact_legality",
store=True) 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)
has_mvt_mandate = fields.Boolean(string="Elu du mouvement", default=False)
mvt_mandate_ids = fields.Many2many(
comodel_name="res.partner.mvt.mandate",
relation="res_partner_mvt_mandate_rel",
column1="partner_id",
column2="mvt_mandate_id",
string="Mandats mouvement",
)
mvt_vip_ids = fields.Many2many(
comodel_name="res.partner.mvt.vip",
relation="res_partner_mvt_vip_rel",
column1="partner_id",
column2="mvt_vip_id",
string="Etiquettes VIP",
)
# Champs pour partenaires # Champs pour partenaires
organization_type_id = fields.Many2one( organization_type_id = fields.Many2one(
'res.partner.organization.type', "res.partner.organization.type",
string="Catégorie Type", string="Famille",
domain=[('parent_id', '=', False)], ondelete="restrict",
on_delete='restrict', compute="_compute_org_type_id",
track_visibility='onchange') tracking=True,
)
organization_subtype_id = fields.Many2one( organization_subtype_id = fields.Many2one(
'res.partner.organization.type', "res.partner.organization.type",
string="Type", string="Type",
domain=[('child_ids', '=', False)], domain=[("child_ids", "=", False)],
on_delete='restrict', ondelete="restrict",
track_visibility='onchange') 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 # Constrains
# ------------------------------------------------------ # ------------------------------------------------------
@api.constrains('zip_id', 'country_id', 'city_id', 'state_id') @api.constrains("zip_id", "country_id", "city_id", "state_id")
def _check_zip(self): def _check_zip(self):
return return
@api.constrains('siret') @api.constrains("revision_contract", "revision_contract_end")
def _check_siret(self): def _check_revision_contract(self):
if self.siret and not self.env.context.get('import_file'): for rec in self:
siren = (self.siret[:3] + " " + if rec.revision_contract and \
self.siret[3:6] + " " + rec.revision_contract_end and \
self.siret[6:9]) rec.revision_contract > rec.revision_contract_end:
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( raise ValidationError(
"Ce SIREN existe déjà parmi les coopératives") _(
elif self.search_count([('siret', '=', self.siret)]) > 1: "La date de fin du contrat de révision doit être supérieure"
raise ValidationError("Ce SIRET existe déjà") " à la date de début du contrat de révision"
)
# ------------------------------------------------------ )
# Actions return
# ------------------------------------------------------
@api.multi
def open_facebook(self):
self.ensure_one()
return {
"type": "ir.actions.act_url",
"url": self.facebook,
}
@api.multi @api.constrains("revision_person_assign_date", "revision_person_assign_end")
def open_linkedin(self): def _check_revision_person_assign(self):
self.ensure_one() for rec in self:
return { if rec.revision_person_assign_date and \
"type": "ir.actions.act_url", rec.revision_person_assign_end and \
"url": self.linkedin, rec.revision_person_assign_date > rec.revision_person_assign_end:
} raise ValidationError(
_(
"La date de fin de nomination du réviseur doit être supérieure"
" à la date de début de nomination du réviseur"
)
)
return
@api.multi @api.constrains("siret")
def open_twitter(self): def _check_siret(self):
self.ensure_one() if self.siret and not self.env.context.get("import_file"):
return { siren = self.siret[:3] + " " + self.siret[3:6] + " " + self.siret[6:9]
"type": "ir.actions.act_url", if (
"url": self.twitter, not self.siret.isdigit()
} and self.siret != "En attente d'immatriculation"
):
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à"))
@api.constrains("is_company", "type", "email", "phone", "mobile", "user_ids")
def _check_contact_info(self):
# Contrainte de tel ou mail lors de la modification d'un contact
if not self.is_company and self.type == "contact" and not self.user_ids:
if not self.email and not self.phone and not self.mobile:
raise UserError(
_("Vous devez saisir au moins un e-mail ou un téléphone pour %s")
% self.name
)
# ------------------------------------------------------ # ------------------------------------------------------
# Onchange # Onchange
# ------------------------------------------------------ # ------------------------------------------------------
@api.onchange('creation_origin_id') # 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
@api.onchange("nickname")
def onchange_nickname(self):
if (
self.is_cooperative
and self.project_status in ["1_information", "2_pre-diagnostic", "3_accompagnement"]
):
self.lastname = self.nickname
# 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): def onchange_creation_origin_id(self):
for coop in self: for coop in self:
coop.creation_suborigin_id = False coop.creation_suborigin_id = False
@api.onchange('is_seed_scop') # TODO: à vérifier
@api.onchange("is_seed_scop")
def onchange_is_seed_scop(self): def onchange_is_seed_scop(self):
for coop in self: for coop in self:
if coop.is_seed_scop == True: if coop.is_seed_scop:
if coop.date_1st_sign: if coop.date_1st_sign:
coop.seed_end = coop.date_1st_sign + timedelta(2556) coop.seed_end = coop.date_1st_sign + timedelta(2556)
else: else:
...@@ -411,479 +783,1017 @@ class ScopPartner(models.Model): ...@@ -411,479 +783,1017 @@ class ScopPartner(models.Model):
else: else:
coop.seed_end = False coop.seed_end = False
@api.onchange('organization_subtype_id') @api.onchange("name")
def onchange_organization_subtype_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
@api.onchange('name')
def onchange_name(self): def onchange_name(self):
if self.search_count([('name', '=ilike', self.name)]) > 0: if self.search_count([("name", "=ilike", self.name)]) > 0:
return { return {
'warning': { "warning": {
'title': "Attention", "title": "Attention",
'message': "Ce nom / cette raison sociale existe déjà, " "message": "Ce nom / cette raison sociale existe déjà, "
+ "merci de vérifier que vous n'êtes pas en " + "merci de vérifier que vous n'êtes pas en "
+ "train de créer un doublon"}} + "train de créer un doublon",
}
}
@api.onchange('mobile') @api.onchange("mobile")
def onchange_mobile(self): def onchange_mobile(self):
if self.mobile and len(self.mobile) > 0 and len(self.mobile) < 10: if self.mobile and len(self.mobile) > 0 and len(self.mobile) < 10:
raise ValidationError( raise ValidationError(
"Le numéro de téléphone doit contenir au moins 10 caractères") _("Le numéro de téléphone doit contenir au moins 10 caractères")
)
@api.onchange('phone') @api.onchange("phone")
def onchange_phone(self): def onchange_phone(self):
if self.phone and len(self.phone) > 0 and len(self.phone) < 10: if self.phone and len(self.phone) > 0 and len(self.phone) < 10:
raise ValidationError( raise ValidationError(
"Le numéro de téléphone doit contenir au moins 10 caractères") _("Le numéro de téléphone doit contenir au moins 10 caractères")
)
@api.onchange('siret') @api.onchange("siret")
def onchange_siret(self): def onchange_siret(self):
if self.siret: if self.siret:
siren = (self.siret[:3] + " " + siren = self.siret[:3] + " " + self.siret[3:6] + " " + self.siret[6:9]
self.siret[3:6] + " " + if self.search_count([("siret", "=like", self.siret)]) > 0:
self.siret[6:9])
if self.search_count([('siret', '=like', self.siret)]) > 0:
return { return {
'warning': { "warning": {
'title': "Attention", "title": "Attention",
'message': "Ce SIRET existe déjà, merci de vérifier " "message": "Ce SIRET existe déjà, merci de vérifier "
+ "que vous n'êtes pas en train de créer un" + "que vous n'êtes pas en train de créer un"
+ " doublon"}} + " doublon",
elif self.search_count([('siret', '=like', siren+"%")]) > 0: }
}
elif self.search_count([("siret", "=like", siren + "%")]) > 0:
return { return {
'warning': { "warning": {
'title': "Attention", "title": "Attention",
'message': "Ce SIREN existe déjà, merci de vérifier " "message": "Ce SIREN existe déjà, merci de vérifier "
+ "que vous n'êtes pas en train de créer un" + "que vous n'êtes pas en train de créer un"
+ " doublon"}} + " 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 # Common functions
# ------------------------------------------------------ # ------------------------------------------------------
def _create_period(self, partner): def _create_period(self, partner):
new_period = self.env['scop.period'].create({ new_period = self._add_period(partner)
'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,
'cae': partner.cae
})
partner.scop_period_ids = new_period partner.scop_period_ids = new_period
def _add_period(self, partner):
new_period = self.env["scop.period"].with_context().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
if partner.siret or not partner.is_registration_in_progress
else "En attente d'immatriculation"
),
"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,
}
)
return new_period
# ------------------------------------------------------ # ------------------------------------------------------
# Override ORM # 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),
("nickname", operator, name),
("sigle", operator, 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 # Creation d'une periode lorsque le statut passe en Phase de Suivi
@api.multi
def write(self, vals): def write(self, vals):
if vals.get('name'): # Gestion casse des informations
vals['name'] = vals.get('name').title() if vals.get("name"):
if vals.get('lastname'): vals["name"] = vals.get("name").title()
vals['lastname'] = vals.get('lastname').title() if vals.get("lastname"):
if vals.get('firstname'): vals["lastname"] = vals.get("lastname").title()
vals['firstname'] = vals.get('firstname').title() if vals.get("firstname"):
if vals.get('city'): vals["firstname"] = vals.get("firstname").title()
vals['city'] = vals.get('city').upper() 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) 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: for partner in self:
if (not partner.is_company # Création d'une période lors du changement de statut en Suivi
and partner.type == 'contact' if vals.get("project_status") == "4_suivi" and not self.env.context.get(
and not partner.user_ids): "import_file"
if (not partner.email and not partner.phone ):
and not partner.mobile): if not partner.scop_period_ids:
raise ValidationError( partner.sudo()._create_period(partner)
"Vous devez saisir au moins un e-mail ou un téléphone\
pour " + partner.name) # Ajout des followers de la fiche
partners_to_subscribe = []
if (vals.get('project_status') == '6_suivi' if partner.followup_delegate_id != partner.create_uid:
and not self.env.context.get('import_file')): partners_to_subscribe.append(partner.followup_delegate_id.partner_id.id)
partner._create_period(partner) if partner.creation_delegate_id != partner.create_uid:
partners_to_subscribe = [ partners_to_subscribe.append(partner.creation_delegate_id.partner_id.id)
partner.followup_delegate_id.partner_id.id,
partner.creation_delegate_id.partner_id.id if partners_to_subscribe:
]
partner.message_subscribe(partner_ids=partners_to_subscribe) partner.message_subscribe(partner_ids=partners_to_subscribe)
return result return result
# Création d'une période lors de la création d'une coopérative
@api.model_create_multi @api.model_create_multi
def create(self, vals_list): def create(self, vals_list):
"""
Création d'une période lors de la création d'une coopérative
"""
# Gestion casse des informations
for vals in vals_list: for vals in vals_list:
if vals.get('name'): if vals.get("name"):
vals['name'] = vals.get('name').title() vals["name"] = vals.get("name").title()
if vals.get('lastname'): if vals.get("lastname"):
vals['lastname'] = vals.get('lastname').title() vals["lastname"] = vals.get("lastname").title()
if vals.get('firstname'): if vals.get("firstname"):
vals['firstname'] = vals.get('firstname').title() vals["firstname"] = vals.get("firstname").title()
if vals.get('city'): if vals.get("city"):
vals['city'] = vals.get('city').upper() vals["city"] = vals.get("city").upper()
partners = super(ScopPartner, self).create(vals_list) partners = super(ScopPartner, self).create(vals_list)
for vals in vals_list: for vals in vals_list:
if vals.get('is_cooperative') and vals.get( # Création d'une période si la coop est en statut en Suivi
'project_status') == '6_suivi': if vals.get("is_cooperative") and vals.get("project_status") == "4_suivi":
for partner in partners: for partner in partners:
partner._create_period(partner) if not partner.scop_period_ids:
partner.sudo()._create_period(partner)
for partner in partners:
partners_to_subscribe = [
partner.followup_delegate_id.partner_id.id,
partner.creation_delegate_id.partner_id.id
]
partner.message_subscribe(partner_ids=partners_to_subscribe)
return partners 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,
)
def action_archive(self):
"""
Lève une erreur si une coopérative qui n'est pas à l'état abandonné fait partie des
items à archiver
"""
coop_ids = self.filtered(
lambda p: p.is_cooperative and p.project_status != "5_abandonne"
)
if coop_ids:
raise UserError(
_(
"Il n'est pas possible d'archiver une coopérative qui n'est pas en "
"statut abandonné."
)
)
else:
return super().action_archive()
# ------------------------------------------------------ # ------------------------------------------------------
# Computed Fields # Computed Fields
# ------------------------------------------------------ # ------------------------------------------------------
@api.depends('siret') @api.depends("siret")
def _compute_from_siret(self): def _compute_siren(self):
for company in self: for partner in self:
if company.siret: if partner.siret:
company.siren = (company.siret[:3] + " " + partner.siren = (
company.siret[3:6] + " " + partner.siret[:3]
company.siret[6:9]) + " "
company.formatted_siret = (company.siret[:3] + " " + + partner.siret[3:6]
company.siret[3:6] + " " + + " "
company.siret[6:9] + " " + + partner.siret[6:9]
company.siret[9:]) )
partner.pappers_url = (
@api.depends('zip') "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")
def _compute_num_departement(self): def _compute_num_departement(self):
for company in self: for company in self:
if company.zip: if company.zip:
company.zip_departement = company.zip[:2] 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
else:
company.zip_departement = False
@api.depends('zip') @api.depends("zip")
def _compute_region(self): def _compute_region(self):
for partner in self: for partner in self:
if partner.zip: if partner.zip:
zip_id = self.env['res.city.zip'].search([ zip_id = self.env["res.city.zip"].search([("name", "=", partner.zip)])
('name', '=', partner.zip)])
if zip_id: if zip_id:
partner.region = zip_id[0].city_id[0].state_id partner.region = zip_id[0].city_id[0].state_id
@api.model @api.model
def _compute_current_user_ur_id(self): def _compute_current_user_ur_id(self):
for partner in self: for partner in self:
partner.current_user_ur_id = self.env.user.company_id.ur_id.id partner.current_user_ur_id = self.env.company.ur_id
def _search_current_user_ur_id(self, operator, value): def _search_current_user_ur_id(self, operator, value):
return [('ur_id', '=', self.env.user.company_id.ur_id.id)] return [("ur_id", "=", self.env.company.ur_id.id)]
@api.depends('contact_origin_id', @api.depends(
'parent_id.cooperative_form_id', "contact_origin_id",
'parent_id.membership_status') "parent_id.cooperative_form_id",
"parent_id.membership_status",
)
def _compute_contact_legality(self): def _compute_contact_legality(self):
for partner in self: for partner in self:
partner.contact_legality = 'none' partner.contact_legality = "none"
if (partner.contact_origin_id.name == if partner.contact_origin_id.name == "Fiche contact, site internet":
"Fiche contact, site internet"): partner.contact_legality = "consent"
partner.contact_legality = 'consent'
if partner.contact_origin_id.name in ( if partner.contact_origin_id.name in (
"Prospect journée d'info coll", "Prospect journée d'info coll",
"Prospect (salon, rdv, internet…)", "Prospect (salon, rdv, internet…)",
"Elus"): "Elus",
partner.contact_legality = 'legitimate' ):
if (partner.contact_origin_id.name in ( partner.contact_legality = "legitimate"
"Salariés CG", "Salariés UR", "Salariés Fédération")): if partner.contact_origin_id.name in (
partner.contact_legality = 'employee' "Salariés CG",
if (partner.contact_origin_id.name in ( "Salariés UR",
"Elus", "VIP, Officiels", "Fournisseurs")): "Salariés Fédération",
partner.contact_legality = 'legitimate' ):
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: if not partner.is_company and partner.parent_id:
parent = partner.parent_id parent = partner.parent_id
if (partner.contact_origin_id.name in ( if (
partner.contact_origin_id.name
in (
"Dossiers d'adhésion", "Dossiers d'adhésion",
"Dossiers annuels non LM (scic, scop47)") "Dossiers annuels non LM (scic, scop47)",
)
and parent.cooperative_form_id and parent.cooperative_form_id
and parent.membership_status == "member"): and parent.membership_status == "member"
partner.contact_legality = 'customer' ):
if (partner.contact_origin_id.name == ( partner.contact_legality = "customer"
"Dossiers annuels non LM (scic, scop47)") if (
and parent.membership_status != "member"): partner.contact_origin_id.name
partner.contact_legality = 'legitimate' == ("Dossiers annuels non LM (scic, scop47)")
if (partner.contact_origin_id.name == ( and parent.membership_status != "member"
"Dossiers Liste ministère") ):
and parent.cooperative_form_id.name == "SCIC"): partner.contact_legality = "legitimate"
partner.contact_legality = 'customer' if (
partner.contact_origin_id.name == ("Dossiers Liste ministère")
@api.depends('membership_period_ids', 'membership_period_ids.state', and parent.cooperative_form_id.name == "SCIC"
'membership_period_ids.end_reason_id') ):
@api.multi partner.contact_legality = "customer"
@api.depends("action_rse_ids","action_te_ids")
def _compute_is_rse(self):
"""
Est on une coop RSE/TE
"""
for partner in self:
partner.is_rse = False
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",
)
# Todo: A revoir comment on assigne le statut member
def _compute_membership(self): def _compute_membership(self):
for partner in self: for partner in self:
type_cg = self.env['scop.membership.type'].search([ if partner.membership_period_ids:
('name', '=', 'Confédération générale des SCOP')], limit=1).id type_cg = self.env.ref("cgscop_partner.membership_type_1").id
last_membership_period = self.env['scop.membership.period'].search( last_membership_period = self.env["scop.membership.period"].search(
[('partner_id', '=', partner.id), [("partner_id", "=", partner.id), ("type_id", "=", type_cg)],
('type_id', '=', type_cg)],
limit=1, limit=1,
order='start desc') order="start desc,id desc",
if (last_membership_period )
and not last_membership_period.end_reason_id if last_membership_period and not last_membership_period.end:
and last_membership_period.state == 'done'):
partner.membership_status = "member" partner.membership_status = "member"
partner.member_number = last_membership_period.number partner.member_start = last_membership_period.start
elif (last_membership_period elif last_membership_period and last_membership_period.end_reason_id:
and last_membership_period.end_reason_id):
partner.membership_status = "out" partner.membership_status = "out"
partner.member_number = last_membership_period.number
else: else:
partner.membership_status = "not_member" partner.membership_status = "not_member"
@api.depends('member_number') @api.depends("member_number_int")
@api.multi def _compute_membership_number(self):
def _compute_membership_int(self):
for partner in self: for partner in self:
if partner.member_number: if partner.member_number_int:
partner.member_number_int = int(partner.member_number) partner.member_number = str(partner.member_number_int)
else:
partner.member_number = False
@api.depends('questionnaire_ids', 'questionnaire_ids.staff_count', @api.depends("membership_period_ids", "membership_period_ids.end")
'questionnaire_ids.effective_date') def _compute_federation(self):
@api.multi
def _compute_last_effective(self):
for partner in self: for partner in self:
lm = partner.questionnaire_ids.search( if partner.is_cooperative:
[['partner_id', '=', partner.id], ['staff_count', '>', 0]], partner.is_federation_com = partner._get_federation(
limit=1, "cgscop_partner.membership_type_2"
order='effective_date desc') )
if lm: partner.is_federation_btp = partner._get_federation(
partner.staff_last = lm[0].staff_count "cgscop_partner.membership_type_4"
partner.staff_last_date = lm[0].effective_date )
partner.is_federation_indus = partner._get_federation(
# ------------------------------------------------------ "cgscop_partner.membership_type_3"
# Button Action )
# ------------------------------------------------------ partner.is_federation_cae = partner._get_federation(
@api.multi "cgscop_partner.membership_type_5"
def scop_send_to_cg(self): )
self.write({
'project_status': '5_cg', def _get_federation(self, external_id):
}) member_type_id = self.env.ref(external_id).id
partner_id = self.id
return True membership_period = self.env["scop.membership.period"].search(
[
@api.multi ("partner_id", "=", partner_id),
def partner_archive(self): ("type_id", "=", member_type_id),
self.active = False ("end", "=", False),
]
# TODO - remove temporary function once RIGA API in place )
@api.multi if membership_period:
def scop_valid_cg(self):
self.write({
'project_status': '6_suivi',
})
return True 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:
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
@api.multi def _compute_segment_nb(self):
def scop_abandonne(self): for partner in self:
self.write({ # Calcul nombre de segment 1
'project_status': '7_abandonne', seg1 = partner.env["res.partner.segment1"].search(
}) [("ur_id", "=", self.env.user.ur_id.id)]
return True )
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
class ResPartneCertification(models.Model): @api.depends(
_name = "res.partner.certification" "revision_next_exercice", "revision_same_exercice",
_description = "Certification" )
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
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":
self._compute_revision_quinq_exercice()
partner.revision_next_exercice = partner.revision_quinq_exercice
# 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
name = fields.Char('Certification') # On calcule l'année de révision de la quinquénale
id_riga = fields.Integer("ID RIGA") partner.revision_quinq_exercice = base_rev + 5
color = fields.Integer('Couleur Index')
@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
class ScopPartnerCompanyType(models.Model): # ------------------------------------------------------
_inherit = "res.partner.company.type" # Button & Action
# ------------------------------------------------------
def open_facebook(self):
self.ensure_one()
return {
"type": "ir.actions.act_url",
"url": self.facebook,
}
id_riga = fields.Integer("ID RIGA") def open_linkedin(self):
is_coop = fields.Boolean("Est un statut coopératif") 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,
}
class ResPartnerCooperativeForm(models.Model): def open_instagram(self):
_name = "res.partner.cooperative.form" self.ensure_one()
_description = "Cooperative form" return {
"type": "ir.actions.act_url",
"url": self.instagram,
}
name = fields.Char('Cooperative form') def open_pappers(self):
id_riga = fields.Integer("ID RIGA") 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"}
class ResPartnerCreationOrigin(models.Model): def partner_archive(self):
_name = "res.partner.creation.origin" self.active = False
_description = "Creation Origin"
_parent_name = "parent_id"
_parent_store = True
_rec_name = 'name'
_order = 'id'
name = fields.Char('Origine / Sous-Origine', index=True, required=True) def scop_prj_adhesion(self):
parent_id = fields.Many2one( self.write({"membership_status": "adhesion"})
comodel_name='res.partner.creation.origin',
string='Origine (parent)',
index=True,
ondelete='restrict')
parent_path = fields.Char(index=True)
child_ids = fields.One2many(
comodel_name='res.partner.creation.origin',
inverse_name='parent_id',
string='Sous origines')
id_riga = fields.Integer("ID RIGA")
@api.constrains('parent_id')
def _check_origin_recursion(self):
if not self._check_recursion():
raise ValidationError(
'Vous ne pouvez pas créer des origines récursives.')
return True return True
def scop_abandonne(self):
class ResPartnerDissolutionReason(models.Model): self.write(
_name = "res.partner.dissolution.reason" {
_description = "Dissolution Reason" "project_status": "5_abandonne",
}
name = fields.Char('Dissolution Reason') )
class ResPartnerMandate(models.Model):
_name = "res.partner.mandate"
_description = "Mandat"
name = fields.Char('Mandat')
class ScopPartnerNaf(models.Model):
_inherit = "res.partner.naf"
id_riga = fields.Integer("ID RIGA")
class ResPartnerOrganizationType(models.Model):
_name = "res.partner.organization.type"
_description = "Type of Organization"
_parent_name = "parent_id"
_parent_store = True
_rec_name = 'name'
_order = 'id'
name = fields.Char('Type / Sous-Type', index=True, required=True)
parent_id = fields.Many2one(
comodel_name='res.partner.organization.type',
string='Type (parent)',
index=True,
ondelete='cascade')
parent_path = fields.Char(index=True)
child_ids = fields.One2many(
comodel_name='res.partner.organization.type',
inverse_name='parent_id',
string='Sous types')
id_riga = fields.Integer("ID RIGA")
@api.constrains('parent_id')
def _check_origin_recursion(self):
if not self._check_recursion():
raise ValidationError(
'Vous ne pouvez pas créer des types récursifs.')
return True 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",
},
}
class ResPartnerRgpdOrigin(models.Model): def edit_director(self):
_name = "res.partner.rgpd.origin" return {
_description = "Origin" "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",
}
name = fields.Char('Origin') 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",
}
class ResPartnerSegment1(models.Model): def write_contact(self):
_name = "res.partner.segment1" return self
_description = "Segments 1"
_rec_name = 'name' def show_coop(self):
_order = 'ur_id, name' """
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",
}
def _default_ur(self): # Détermine le filtre par défaut pour l'affichage
return self.env['res.company']._ur_default_get() 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})
name = fields.Char('Nom', index=True, required=True) return {
color = fields.Integer(string='ID Couleur') "name": "Coopératives",
id_riga = fields.Integer("ID RIGA") "type": "ir.actions.act_window",
ur_id = fields.Many2one( "res_model": "res.partner",
'union.regionale', "search_view_id": (
string='Union Régionale', self.env.ref("cgscop_partner.scop_partner_view_search").id,
index=True, ),
on_delete='restrict', "view_mode": "tree,form,activity",
default=_default_ur) "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",
}
class ResPartnerSegment2(models.Model): # Détermine le filtre par défaut pour l'affichage
_name = "res.partner.segment2" filtre = self.env.company.ur_id.partner_filter
_description = "Segments 2" if filtre == "2":
_rec_name = 'name' ctx.update({"search_default_my_ur": True})
_order = 'ur_id, name'
def _default_ur(self): return {
return self.env['res.company']._ur_default_get() "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,
}
name = fields.Char('Nom', index=True, required=True) def show_organisme(self):
color = fields.Integer(string='ID Couleur') """
id_riga = fields.Integer("ID RIGA") Affichage des organismes avec filtre par défaut
ur_id = fields.Many2one( """
'union.regionale', ctx = {
string='Union Régionale', "default_is_company": True,
index=True, "default_is_cooperative": True,
on_delete='restrict', "default_company_type": "company",
default=_default_ur) "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})
class ResPartnerSegment3(models.Model): return {
_name = "res.partner.segment3" "name": "Tous les organismes",
_description = "Segments 3" "type": "ir.actions.act_window",
_rec_name = 'name' "res_model": "res.partner",
_order = 'ur_id, name' "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),
],
"context": ctx,
}
def _default_ur(self): def show_processus_adhesion(self):
return self.env['res.company']._ur_default_get() """
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",
}
name = fields.Char('Nom', index=True, required=True) # Détermine le filtre par défaut pour l'affichage
color = fields.Integer(string='ID Couleur') filtre = self.env.company.ur_id.partner_filter
id_riga = fields.Integer("ID RIGA") if filtre == "2":
ur_id = fields.Many2one( ctx.update({"search_default_my_ur": True})
'union.regionale',
string='Union Régionale',
index=True,
on_delete='restrict',
default=_default_ur)
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,
}
# ------------------------------------------------------
# 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 ""
class ResPartnerSegment4(models.Model): def get_postal_address(self):
_name = "res.partner.segment4" self.ensure_one()
_description = "Segments 4" street_address_fields = [self.postal_street, self.postal_street2, self.postal_street3]
_rec_name = 'name' street_address_list = list(filter(bool, street_address_fields))
_order = 'ur_id, name' 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)
def _default_ur(self): # ------------------------------------------------------
return self.env['res.company']._ur_default_get() # 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"),
("is_incubated", "=", True),
]
)
name = fields.Char('Nom', index=True, required=True) i = 0
color = fields.Integer(string='ID Couleur') for partner in partners:
id_riga = fields.Integer("ID RIGA") partner.geo_localize()
ur_id = fields.Many2one( i += 1
'union.regionale', time.sleep(1)
string='Union Régionale', _logger.info("Mise à jour de %d coordonnées", i)
index=True,
on_delete='restrict',
default=_default_ur)
# © 2019 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
from odoo.exceptions import ValidationError
class ResPartneCertification(models.Model):
_name = "res.partner.certification"
_description = "Agrément Scop"
_order = "sequence, name"
name = fields.Char("Agréments")
sequence = fields.Integer("Séquence", default=10)
color = fields.Integer("Couleur Index")
class ScopPartnerCompanyType(models.Model):
_inherit = "res.partner.company.type"
is_coop = fields.Boolean("Est un statut coopératif")
class ResPartnerCooperativeForm(models.Model):
_name = "res.partner.cooperative.form"
_description = "Forme Coopérative"
name = fields.Char("Forme Coopérative")
def _get_lm_form(self):
type_lm = self.env.ref("cgscop_partner.form_scop")
type_lamaneur = self.env.ref("cgscop_partner.form_lamaneur")
type_unionscop = self.env.ref("cgscop_partner.form_unionscop")
return type_lm + type_lamaneur + type_unionscop
class ResPartnerCreationOrigin(models.Model):
_name = "res.partner.creation.origin"
_description = "Creation Origin Scop"
_parent_name = "parent_id"
_parent_store = True
_rec_name = "name"
_order = "id"
name = fields.Char("Origine / Sous-Origine", index=True, required=True)
parent_id = fields.Many2one(
comodel_name="res.partner.creation.origin",
string="Origine (parent)",
index=True,
ondelete="restrict",
)
parent_path = fields.Char(index=True)
child_ids = fields.One2many(
comodel_name="res.partner.creation.origin",
inverse_name="parent_id",
string="Sous origines",
)
@api.constrains("parent_id")
def _check_origin_recursion(self):
if not self._check_recursion():
raise ValidationError(
_("Vous ne pouvez pas créer des origines récursives.")
)
return True
class ResPartnerDissolutionReason(models.Model):
_name = "res.partner.dissolution.reason"
_description = "Dissolution Reason"
name = fields.Char("Motif de Décès")
class ResPartnerMandate(models.Model):
_name = "res.partner.mandate"
_description = "Mandat"
name = fields.Char("Mandat")
class ResPartnerFunctionLst(models.Model):
_name = "res.partner.function_lst"
_description = "Fonctions"
name = fields.Char("Fonction")
class ResPartnerFederation(models.Model):
_name = "res.partner.federation"
_description = "Fédérations"
name = fields.Char("Fédération")
class ScopPartnerNaf(models.Model):
_inherit = "res.partner.naf"
secteur_id = fields.Many2one(
"res.partner.secteur.activite",
string="Secteur",
ondelete="restrict",
)
federation_id = fields.Many2one(
"res.partner.federation", string="Fédération", ondelete="restrict"
)
class ResPartnerOrganizationType(models.Model):
_name = "res.partner.organization.type"
_description = "Type of Organization"
_parent_name = "parent_id"
_parent_store = True
_rec_name = "name"
_order = "id"
name = fields.Char("Type / Sous-Type", index=True, required=True)
parent_id = fields.Many2one(
comodel_name="res.partner.organization.type",
string="Type (parent)",
index=True,
ondelete="cascade",
)
parent_path = fields.Char(index=True)
child_ids = fields.One2many(
comodel_name="res.partner.organization.type",
inverse_name="parent_id",
string="Sous types",
)
@api.constrains("parent_id")
def _check_origin_recursion(self):
if not self._check_recursion():
raise ValidationError(_("Vous ne pouvez pas créer des types récursifs."))
return True
class ResPartnerRgpdOrigin(models.Model):
_name = "res.partner.rgpd.origin"
_description = "RGPD Origin"
name = fields.Char("Origine")
class ResPartnerSegment1(models.Model):
_name = "res.partner.segment1"
_description = "Segments 1"
_rec_name = "name"
_order = "ur_id, name"
def _default_ur(self):
return self.env["res.company"]._ur_default_get()
name = fields.Char("Nom", index=True, required=True)
color = fields.Integer(string="ID Couleur")
ur_id = fields.Many2one(
"union.regionale",
string="Union Régionale",
index=True,
ondelete="restrict",
default=_default_ur,
)
class ResPartnerSegment2(models.Model):
_name = "res.partner.segment2"
_description = "Segments 2"
_rec_name = "name"
_order = "ur_id, name"
def _default_ur(self):
return self.env["res.company"]._ur_default_get()
name = fields.Char("Nom", index=True, required=True)
color = fields.Integer(string="ID Couleur")
ur_id = fields.Many2one(
"union.regionale",
string="Union Régionale",
index=True,
ondelete="restrict",
default=_default_ur,
)
class ResPartnerSegment3(models.Model):
_name = "res.partner.segment3"
_description = "Segments 3"
_rec_name = "name"
_order = "ur_id, name"
def _default_ur(self):
return self.env["res.company"]._ur_default_get()
name = fields.Char("Nom", index=True, required=True)
color = fields.Integer(string="ID Couleur")
ur_id = fields.Many2one(
"union.regionale",
string="Union Régionale",
index=True,
ondelete="restrict",
default=_default_ur,
)
class ResPartnerSegment4(models.Model):
_name = "res.partner.segment4"
_description = "Segments 4"
_rec_name = "name"
_order = "ur_id, name"
def _default_ur(self):
return self.env["res.company"]._ur_default_get()
name = fields.Char("Nom", index=True, required=True)
color = fields.Integer(string="ID Couleur")
ur_id = fields.Many2one(
"union.regionale",
string="Union Régionale",
index=True,
ondelete="restrict",
default=_default_ur,
)
class ResPartnerSecteurActivite(models.Model):
_name = "res.partner.secteur.activite"
_description = "Secteurs d'activité"
name = fields.Char("Secteur")
class ResPartnerFiliere(models.Model):
_name = "res.partner.filiere"
_description = "Filières"
_rec_name = "name"
_order = "name"
name = fields.Char("Filière")
class ResPartnerMvtMandate(models.Model):
_name = "res.partner.mvt.mandate"
_description = "Mandats du mouvement"
_rec_name = "name"
_order = "name"
name = fields.Char("Mandat")
class ResPartnerMvtVip(models.Model):
_name = "res.partner.mvt.vip"
_description = "Etiquettes VIP"
_rec_name = "name"
_order = "name"
name = fields.Char("Etiquette")
# © 2019 Le Filament (<http://www.le-filament.com>) # © 2019 Le Filament (<http://www.le-filament.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models, fields from odoo import fields, models
class ResPartnerNewsletterSubscription(models.Model): class ResPartnerNewsletterSubscription(models.Model):
...@@ -9,21 +9,24 @@ class ResPartnerNewsletterSubscription(models.Model): ...@@ -9,21 +9,24 @@ class ResPartnerNewsletterSubscription(models.Model):
_description = "Subscription" _description = "Subscription"
partner_id = fields.Many2one( partner_id = fields.Many2one(
comodel_name='res.partner', comodel_name="res.partner",
string='Contact', string="Contact",
domain=[('is_company', '=', False)], domain=[("is_company", "=", False)],
ondelete='cascade', index=True) ondelete="cascade",
index=True,
)
newsletter_id = fields.Many2one( newsletter_id = fields.Many2one(
comodel_name='res.partner.newsletter', comodel_name="res.partner.newsletter",
string='Newsletter', string="Newsletter",
domain=[('is_company', '=', False)], domain=[("is_company", "=", False)],
ondelete='cascade', index=True) ondelete="cascade",
consent = fields.Boolean("Consentement") index=True,
)
consent = fields.Boolean(string="Consentement", default=True)
class ResPartnerNewsletter(models.Model): class ResPartnerNewsletter(models.Model):
_name = "res.partner.newsletter" _name = "res.partner.newsletter"
_description = "Newsletter" _description = "Newsletter"
name = fields.Char('Newsletter') name = fields.Char("Newsletter")
id_riga = fields.Integer("Identifiant RIGA")
# © 2019 Le Filament (<http://www.le-filament.com>) # © 2019 Le Filament (<http://www.le-filament.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import fields, models, api, modules from odoo import api, fields, models, modules, tools
class ResUsers(models.Model): class ResUsers(models.Model):
...@@ -9,27 +9,60 @@ class ResUsers(models.Model): ...@@ -9,27 +9,60 @@ class ResUsers(models.Model):
@api.model @api.model
def _get_ur(self): def _get_ur(self):
return self.env.user.company_id.ur_id return self.env.company.ur_id
ur_id = fields.Many2one('union.regionale', compute='_compute_ur_id', ur_id = fields.Many2one(
string='UR', store=True) comodel_name="union.regionale",
compute="_compute_ur_id",
string="UR",
store=True,
)
current_ur_id = fields.Many2one(
comodel_name="union.regionale",
compute="_compute_current_ur_id",
string="UR courant",
)
@api.depends('company_id.ur_id') # ------------------------------------------------------
# Compute functions
# ------------------------------------------------------
@api.depends("company_id.ur_id")
def _compute_ur_id(self): def _compute_ur_id(self):
for user in self: for user in self:
user.ur_id = user.company_id.ur_id user.ur_id = user.company_id.ur_id
def _compute_current_ur_id(self):
for user in self:
user.current_ur_id = self.env.company.ur_id
# ------------------------------------------------------
# Override parent
# ------------------------------------------------------
@api.model @api.model
def systray_get_activities(self): def systray_get_activities(self):
activities = super(ResUsers, self).systray_get_activities() activities = super(ResUsers, self).systray_get_activities()
for activity in activities: for activity in activities:
if activity['model'] != 'res.partner': if activity["model"] != "res.partner":
continue continue
activity['icon'] = modules.module.get_module_icon('contacts') activity["icon"] = modules.module.get_module_icon("contacts")
activity['actions'] = [{ activity["actions"] = [
'icon': 'fa-th', {
'name': 'Summary', "icon": "fa-th",
'action_xmlid': 'cgscop_partner.cgscop_action_contacts_summary' "name": "Summary",
}] "action_xmlid": "cgscop_partner.cgscop_action_contacts_summary",
}
]
return activities return activities
@api.model
@tools.ormcache("self._uid")
def context_get(self):
"""
Ajoute l'ur_id dans le contexte
"""
user = self.env.user
context = super(ResUsers, self).context_get()
new_context = context.copy()
new_context["ur_id"] = user.company_id.ur_id.id
new_context["current_ur_id"] = self.env.company.ur_id.id
return new_context
# © 2019 Le Filament (<http://www.le-filament.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import fields, models
class ScopActionRse(models.Model):
_name = "scop.action.rse"
_inherit = ["mail.thread"]
_description = "Actions RSE engagées"
_order = "partner_id, action_category, action_date"
partner_id = fields.Many2one(
comodel_name="res.partner",
string="Organisme",
domain=[("is_company", "=", True)],
ondelete="cascade",
index=True,
)
action_date = fields.Date(string="Début de l'action", index=True, tracking=True)
action_category = fields.Selection(
[
("1", "1 - La gouvernance de l’organisation"),
("2", "2 - Les droits de l’homme"),
("3", "3 - Les relations et les conditions de travail"),
("4", "4 - L’environnement"),
("5", "5 - La loyauté des pratiques dans les affaires"),
("6", "6 - Les questions relatives aux consommateurs"),
("7", "7 - Les communautés et le territoire"),
],
string="Catégorie RSE",
tracking=True,
)
action_manager = fields.Text(string="Référent de l'action", tracking=True)
action_description = fields.Text(string="Description de l'action", tracking=True)
action_measure = fields.Text(string="Indicateurs de suivi", tracking=True)
# ------------------------------------------------------
# Contraintes SQL
# ------------------------------------------------------
# Unicité de l'action par organisme et par date
_sql_constraints = [
(
"action_rse",
"unique(partner_id, action_category, action_date)",
"Une action RSE a déjà été enregistrée à cette date",
),
]
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import fields, models
class ScopActionTe(models.Model):
_name = "scop.action.te"
_description = "Expertises transition écologique"
_order = "name"
name = fields.Char(
string="Nom"
)
color = fields.Integer(
string="Couleur"
)
active = fields.Boolean(
default=True
)
# © 2019 Le Filament (<http://www.le-filament.com>) # © 2019 Le Filament (<http://www.le-filament.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models, fields from odoo import fields, models
class ScopContributions(models.Model):
_name = "scop.contribution"
_description = "Contributions"
_order = 'partner_id, year, type_id'
partner_id = fields.Many2one(
comodel_name='res.partner',
string='Organisme',
domain=[('is_company', '=', True)],
ondelete='cascade', index=True)
id_riga = fields.Integer("ID RIGA")
type_id = fields.Many2one(
'scop.contribution.type',
string="Type de cotisation",
ondelete='restrict', index=True)
year = fields.Integer("Année", index=True)
calculation_date = fields.Datetime("Date calcul cotisation")
loss = fields.Boolean("Perte")
amount_calculated = fields.Integer("Montant calculé")
amount_called = fields.Integer("Montant appelé")
amount_paid = fields.Float("Montant réglé")
amount_remaining_previous = fields.Float("Mnt Restant cum. à fin N-1")
amount_paid_late = fields.Float("Mnt réglé après clôture")
spreading = fields.Integer("Echelonnement")
amount_remaining = fields.Float("Montant Restant")
quarter_1 = fields.Date("1er Trim.")
quarter_2 = fields.Date("2ème Trim.")
quarter_3 = fields.Date("3ème Trim.")
quarter_4 = fields.Date("4ème Trim.")
# TODO: déplacer dans scop_cotisation
class ScopContributionType(models.Model): class ScopContributionType(models.Model):
_name = "scop.contribution.type" _name = "scop.contribution.type"
_description = "Contribution type" _description = "Contribution type"
name = fields.Char('Contribution type') name = fields.Char("Contribution type")
id_riga = fields.Integer("ID RIGA")
# © 2020 Le Filament (<http://www.le-filament.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import fields, models
class ScopFederationComActivity(models.Model):
_name = "scop.federation.com.activity"
_description = "Activité Fédération de la Com"
_order = "name"
name = fields.Char("Domaine d'activité", required=True)
partner_ids = fields.Many2many(
comodel_name="res.partner",
relation="res_partner_federation_com_activity_rel",
column1="com_activity_id",
column2="partner_id",
string="Cooperatives",
domain=[("is_cooperative", "=", True)],
)
class ScopFederationIndusActivity(models.Model):
_name = "scop.federation.indus.activity"
_description = "Activité Fédération de l'Industrie"
_order = "name"
name = fields.Char(
"Domaine d'activité",
required=True,
)
partner_ids = fields.Many2many(
comodel_name="res.partner",
relation="res_partner_federation_indus_activity_rel",
column1="indus_activity_id",
column2="partner_id",
string="Cooperatives",
domain=[("is_cooperative", "=", True)],
)
# © 2019 Le Filament (<http://www.le-filament.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models, fields
class ScopLiasseFiscale(models.Model):
_name = "scop.liasse.fiscale"
_description = "Liasse Fiscale"
id_riga = fields.Integer("ID RIGA", index=True)
partner_id = fields.Many2one(
comodel_name='res.partner',
string='Organisme',
domain=[('is_company', '=', True)],
ondelete='cascade', index=True)
year = fields.Char("Année", index=True)
type_id = fields.Many2one(
'scop.liasse.fiscale.type',
string="Type de Liasse Fiscale",
ondelete='restrict', index=True)
effective_date = fields.Date("Date d'effet de la liasse")
duration = fields.Integer("Durée de l’exercice")
closing_date = fields.Date("Exercice clos le")
source_id = fields.Many2one(
'scop.liasse.fiscale.source',
string="Source de Liasse Fiscale",
ondelete='restrict')
revenue_cg = fields.Float("'CA' sens CGSCOP")
margin_cg = fields.Float("'Marge' sens CGSCOP")
av_cg = fields.Float("'VABDF' sens CGSCOP")
wage_cg = fields.Float("'Salaires' sens CGSCOP")
margin2ca = fields.Float("Marge*2 > CA")
margin_cgsubv = fields.Float("'Marge' sens CGSCOP-Subv")
av_cgsubv = fields.Float("'VA BDF' sens CGSCOP-Subv")
revenue_cgsubv = fields.Float("'CA' sens CGSCOP-Subv")
is_av_lf = fields.Boolean("VA sur LF")
av_lf = fields.Float("VA indiquée sur LF")
revenue_sub = fields.Float("CA_SUB")
sal = fields.Float("SAL")
margin = fields.Float("MARGE")
distribution = fields.Float(
"Répartition statutaire des excédents nets de gestion")
capital_cae = fields.Float("Capital détenu (CAE)")
flexible_keys = fields.Boolean("Clés flexible")
reserve = fields.Float("Réserve légale")
share_ass_perm = fields.Float("Part des permanents associés")
dvpt_fund = fields.Float("Fond de développement")
share_ass_work = fields.Float("Part des entrepreneurs salariés associés")
share_capital = fields.Float("Part capital")
share_work = fields.Float("Part travail")
pension_fund = fields.Float("Caisse retraite/solidarité")
others = fields.Float("Autres")
key_name = fields.Float("Nom de la clé")
status_update = fields.Date("Modification des statuts")
class ScopLiasseFiscaleType(models.Model):
_name = "scop.liasse.fiscale.type"
_description = "Type de Liasse Fiscale"
name = fields.Char('Type de Liasse Fiscale')
class ScopLiasseFiscaleSource(models.Model):
_name = "scop.liasse.fiscale.source"
_description = "Source de Liasse Fiscale"
name = fields.Char('Source de Liasse Fiscale')
id_riga = fields.Integer("ID RIGA")
# © 2019 Le Filament (<http://www.le-filament.com>) # © 2019 Le Filament (<http://www.le-filament.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models, fields from odoo import fields, models
class ScopMembershipPeriod(models.Model): class ScopMembershipPeriod(models.Model):
...@@ -10,40 +10,38 @@ class ScopMembershipPeriod(models.Model): ...@@ -10,40 +10,38 @@ class ScopMembershipPeriod(models.Model):
_order = "start desc" _order = "start desc"
partner_id = fields.Many2one( partner_id = fields.Many2one(
comodel_name='res.partner', comodel_name="res.partner",
string='Organisme', string="Organisme",
domain=[('is_company', '=', True)], domain=[("is_company", "=", True)],
ondelete='cascade', index=True) ondelete="restrict",
id_riga = fields.Integer("ID RIGA") index=True,
)
type_id = fields.Many2one( type_id = fields.Many2one(
'scop.membership.type', "scop.membership.type",
string="Type d'adhésion", string="Type d'adhésion",
ondelete='restrict', index=True) ondelete="restrict",
start = fields.Date('Début d’adhésion', index=True) index=True,
end = fields.Date('Fin d’adhésion') )
start = fields.Date("Début d’adhésion", index=True)
end = fields.Date("Fin d’adhésion")
end_reason_id = fields.Many2one( end_reason_id = fields.Many2one(
'scop.membership.reason.end', "scop.membership.reason.end",
string='Motif de fin d’adhésion', string="Motif de fin d’adhésion",
ondelete='restrict') ondelete="restrict",
)
number = fields.Char("No adhérent", index=True) number = fields.Char("No adhérent", index=True)
state = fields.Selection( note = fields.Text("Commentaires")
[("none", "Non Adhérent"),
("ongoing", "Traitement de l'adhésion"),
("approval", "Attente d'approbation"),
("done", "Adhérent")],
string="Statut adhésion", default="none")
note = fields.Text('Commentaires')
class ScopMembershipType(models.Model): class ScopMembershipType(models.Model):
_name = "scop.membership.type" _name = "scop.membership.type"
_description = "Membership type" _description = "Membership type"
name = fields.Char('Membership type') name = fields.Char("Membership type")
class ScopMembershipReasonEnd(models.Model): class ScopMembershipReasonEnd(models.Model):
_name = "scop.membership.reason.end" _name = "scop.membership.reason.end"
_description = "Reason for end of membership" _description = "Reason for end of membership"
name = fields.Char('Reason for end of membership') name = fields.Char("Reason for end of membership")
# © 2020 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
from odoo.exceptions import ValidationError
class ScopPartnerStaff(models.Model):
_name = "scop.partner.staff"
_description = "Effectifs"
_rec_name = "partner_id"
_order = "effective_date, partner_id"
# ------------------------------------------------------
# Default
# ------------------------------------------------------
@api.model
def default_get(self, fields):
res = super(ScopPartnerStaff, self).default_get(fields)
partner_id = self.env.context.get("default_partner_id", False)
if partner_id:
staff_line = self.search(
[
("partner_id", "=", partner_id),
],
order="effective_date desc, id desc",
limit=1,
)
if staff_line:
staff_list = [
"staff_count",
"staff_shareholder_count",
"staff_shareholder_total",
"staff_average",
]
for staff in staff_list:
res[staff] = staff_line[staff]
return res
# ------------------------------------------------------
# Fields declaration
# ------------------------------------------------------
partner_id = fields.Many2one(
comodel_name="res.partner",
string="Organisme",
domain=[("is_cooperative", "=", True)],
ondelete="restrict",
required=True,
index=True,
)
partner_city = fields.Char("Ville", related="partner_id.city")
partner_siret = fields.Char("SIRET", related="partner_id.siret")
cooperative_form_id = fields.Many2one(related="partner_id.cooperative_form_id")
naf_id = fields.Many2one(related="partner_id.naf_id")
is_partner_in_tracked_naf = fields.Boolean(
"Coop dans les NAF marqués",
compute="_compute_is_partner_in_tracked_naf",
)
user_id = fields.Many2one(
comodel_name="res.users",
string="Utilisateur",
ondelete="restrict",
required=True,
default=lambda self: self.env.uid,
)
type_entry = fields.Selection(
[
("questionnaire", "Questionnaire"),
("questionnaire_inscription", "Questionnaire Inscription"),
("membership", "Adhésion"),
("regul_ur", "Régularisation UR"),
("regul_cg", "Régularisation CG"),
("regul_diane", "Régularisation Diane"),
],
string="Type",
default="regul_ur",
required=True,
)
effective_date = fields.Date(
string="Date",
default=lambda self: fields.Date.today(),
required=True,
)
staff_count = fields.Integer(
"Effectif (EF)",
)
staff_shareholder_count = fields.Integer("Nb Sociétaires Salarié")
staff_shareholder_total = fields.Integer("Total associés")
staff_average = fields.Float("Equivalent temps plein (ETP)")
staff_men = fields.Integer("Eff. salariés hommes")
staff_women = fields.Integer("Eff. salariés femmes")
staff_shareholder_men = fields.Integer("Sociétaires salariés hommes")
staff_shareholder_women = fields.Integer("Sociétaires salariés femmes")
comment = fields.Char("Commentaire")
is_admin_user = fields.Boolean(
compute="_compute_is_admin_user",
)
# ------------------------------------------------------
# Compute
# ------------------------------------------------------
def _compute_is_partner_in_tracked_naf(self):
naf_90_01Z = self.env.ref("lefilament_naf.naf_90_01Z").id
naf_90_02Z = self.env.ref("lefilament_naf.naf_90_02Z").id
naf_78_20Z = self.env.ref("lefilament_naf.naf_78_20Z").id
naf_82_11Z = self.env.ref("lefilament_naf.naf_82_11Z").id
naf_78_10Z = self.env.ref("lefilament_naf.naf_78_10Z").id
for r in self:
if r.naf_id.id in (
naf_90_01Z,
naf_90_02Z,
naf_78_20Z,
naf_82_11Z,
naf_78_10Z,
):
r.is_partner_in_tracked_naf = True
else:
r.is_partner_in_tracked_naf = False
def _compute_is_admin_user(self):
self.is_admin_user = (
self.env.user.has_group("cgscop_partner.group_cg_administrative") or False
)
# ------------------------------------------------------
# OnChange
# ------------------------------------------------------
@api.onchange("type_entry")
def _onchange_type_entry(self):
"""
Interdit la sélection questionnaire ou questionnaire inscription
sur l'interface
"""
if self.type_entry in (
"questionnaire",
"questionnaire_inscription",
) and not self.env.user.has_group("cgscop_partner.group_cg_administrative"):
raise ValidationError(
_('Vous ne pouvez choisir que des types "Régularisation".')
)
# ------------------------------------------------------
# Contrains
# ------------------------------------------------------
@api.constrains(
"cooperative_form_id",
"type_entry",
"staff_count",
"staff_shareholder_count",
"staff_average",
)
def _check_staff(self):
"""
Règles spécifiques pour les effectifs
"""
scic = self.env.ref("cgscop_partner.form_scic").id
scop = self.env.ref("cgscop_partner.form_scop").id
def check_staff_shareholder():
# Effectif total >= effectif sociétaires
if self.staff_shareholder_count > 0:
if not self.staff_count >= self.staff_shareholder_count:
raise ValidationError(
_(
"L'effectif total doit être supérieur ou égal au "
"nombre de sociétaires salariés"
)
)
# Les règles ne s'appliquent pas pour les entrées LM / Questionnaire
if self.type_entry not in ("questionnaire", "questionnaire_inscription"):
# Règles pour les SCIC
if self.cooperative_form_id.id == scic:
check_staff_shareholder()
# Règles pour les SCOP
elif self.cooperative_form_id.id == scop:
# Effectif total non nul
if self.staff_count == 0:
raise ValidationError(
_(
"L'effectif total doit être supérieur ou égal à 0 "
"pour cette copérative de type SCOP"
)
)
check_staff_shareholder()
# Règles sprécifiques pour les NAF suivis
if self.is_partner_in_tracked_naf:
if self.staff_average == 0:
raise ValidationError(
_(
"Le nombre d'équivalent temps plein doit être "
"renseigné pour cette coopérative"
)
)
@api.constrains("effective_date")
def _check_effective_date(self):
"""
Interdit la création de deux lignes à une même date
pour un même partenaire sauf pour LM
"""
for record in self:
doublon = self.search(
[
("partner_id", "=", record.partner_id.id),
("effective_date", "=", record.effective_date),
]
)
if len(doublon) > 1 and record.type_entry not in (
"questionnaire",
"questionnaire_inscription",
):
raise ValidationError(
_("Vous ne pouvez pas créer 2 ajustements à la même date.")
)
# ------------------------------------------------------
# Buttons
# ------------------------------------------------------
def edit_staff(self):
form_id = self.env.ref("cgscop_partner.scop_partner_staff_form_view")
return {
"type": "ir.actions.act_window",
"res_model": "scop.partner.staff",
"view_mode": "form",
"views": [[form_id.id, "form"]],
"res_id": self.id,
"target": "new",
}
# © 2019 Le Filament (<http://www.le-filament.com>) # © 2019 Le Filament (<http://www.le-filament.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models, fields, api from odoo import api, fields, models
class ScopPeriod(models.Model): class ScopPeriod(models.Model):
...@@ -11,71 +11,122 @@ class ScopPeriod(models.Model): ...@@ -11,71 +11,122 @@ class ScopPeriod(models.Model):
# Infos générales # Infos générales
partner_id = fields.Many2one( partner_id = fields.Many2one(
comodel_name='res.partner', comodel_name="res.partner",
string='Organisme', string="Organisme",
domain=[('is_cooperative', '=', True)], domain=[("is_cooperative", "=", True)],
ondelete='cascade', required=True, index=True) ondelete="cascade",
id_riga = fields.Integer("ID RIGA") required=True,
start = fields.Date('Début de validité', required=True, index=True,
default=fields.Date.today(), index=True) )
end = fields.Date('Fin de validité') start = fields.Date(
"Début de validité",
required=True,
default=lambda self: fields.Date.today(),
index=True,
)
end = fields.Date("Fin de validité")
end_reason = fields.Selection( end_reason = fields.Selection(
[('juri', "Modification de la forme juridique"), [
('form', "Changement de forme coopérative"), ("juri", "Modification de la forme juridique"),
('acti', "Changement d'activité (NAF)"), ("form", "Changement de forme coopérative"),
('adr', "Changement d'adresse"), ("acti", "Changement d'activité (NAF)"),
('nom', "Changement de dénomination sociale"), ("adr", "Changement d'adresse"),
('deces', 'Décès'), ("nom", "Changement de dénomination sociale"),
('autr', "Autres")], ("registration", "Immatriculation"),
string='Motif de fin de validité') ("dreets", "Radiation DREETS"),
comments = fields.Text('Commentaires') ("deces", "Décès"),
name = fields.Char('Raison Sociale', required=True, index=True) ("autr", "Autres"),
],
string="Motif de fin de validité",
)
comments = fields.Text("Commentaires")
name = fields.Char("Raison Sociale", required=True, index=True)
cooperative_form_id = fields.Many2one( cooperative_form_id = fields.Many2one(
'res.partner.cooperative.form', "res.partner.cooperative.form",
string="Cooperative form", string="Cooperative form",
on_delete='restrict') ondelete="restrict",
)
partner_company_type_id = fields.Many2one( partner_company_type_id = fields.Many2one(
comodel_name='res.partner.company.type', comodel_name="res.partner.company.type",
string='Legal Form', string="Legal Form",
track_visibility='onchange', ondelete="restrict",
on_delete='restrict') )
siret = fields.Char(string='SIRET', size=14) siret = fields.Char(string="SIRET", size=14)
street = fields.Char() street = fields.Char()
street2 = fields.Char() street2 = fields.Char()
street3 = fields.Char() street3 = fields.Char()
zip = fields.Char() zip = fields.Char()
zip_id = fields.Many2one('res.city.zip', 'ZIP Location') zip_id = fields.Many2one("res.city.zip", "ZIP Location")
city = fields.Char() city = fields.Char()
cedex = fields.Char() cedex = fields.Char()
state_id = fields.Many2one( state_id = fields.Many2one(
"res.country.state", "res.country.state",
string='State', string="State",
ondelete='restrict', ondelete="restrict",
domain="[('country_id', '=?', country_id)]") domain="[('country_id', '=?', country_id)]",
country_id = fields.Many2one( )
'res.country', string='Country', ondelete='restrict') country_id = fields.Many2one("res.country", string="Country", ondelete="restrict")
naf_id = fields.Many2one( naf_id = fields.Many2one("res.partner.naf", string="Code NAF", ondelete="restrict")
'res.partner.naf', ur_id = fields.Many2one(comodel_name="union.regionale", string="Union Régionale")
string='Code NAF',
on_delete='restrict')
cae = fields.Boolean("CAE") cae = fields.Boolean("CAE")
dissolution_reason_id = fields.Many2one( dissolution_reason_id = fields.Many2one(
'res.partner.dissolution.reason', "res.partner.dissolution.reason",
string="Motif Décés", string="Motif Décès",
on_delete='restrict', ondelete="restrict",
track_visibility='onchange') )
number = fields.Char(
string="No adhérent", related="partner_id.member_number", store=False
)
# ------------------------------------------------------
# Override ORM
# ------------------------------------------------------
@api.model_create_multi
def create(self, vals_list):
period_ids = super().create(vals_list)
vals_list_index = 0
for period in period_ids:
if period == period.partner_id.scop_period_ids[0]:
partner_vals = period._get_partner_vals(vals_list[vals_list_index])
# Update partner
period.partner_id.sudo().write(partner_vals)
vals_list_index += 1
return period_ids
@api.multi
def write(self, vals): def write(self, vals):
for period in self: for period in self:
partner_vals = dict(vals) if period == period.partner_id.scop_period_ids[0]:
partner_vals.pop('partner_id', False) partner_vals = self._get_partner_vals(vals)
partner_vals.pop('id_riga', False)
partner_vals.pop('start', False)
partner_vals.pop('end', False)
partner_vals.pop('end_reason', False)
partner_vals.pop('comments', False)
partner_vals.pop('dissolution_reason_id', False)
# Update partner # Update partner
period.partner_id.write(partner_vals) period.partner_id.sudo().write(partner_vals)
return super(ScopPeriod, self).write(vals) return super(ScopPeriod, self).write(vals)
# ------------------------------------------------------
# Business funcitons
# ------------------------------------------------------
def _get_partner_vals(self, vals):
"""
:param dict vals: dictionnaire des valeurs à créer ou à mettre à jour
"""
partner_vals = dict(vals)
# Suppression des valeurs à ne pas remonter à l'organisme
partner_vals.pop("partner_id", False)
partner_vals.pop("start", False)
partner_vals.pop("comments", False)
# Si la date de fin est modifiée et que l'organisme est décédé
# on remonte la date de décès
if "end" in partner_vals:
if (
partner_vals.get("end_reason", False) == "deces"
or self.end_reason == "deces"
):
partner_vals.update(
{"dissolution_date": partner_vals.get("end")}
)
if not partner_vals.get("end"):
partner_vals.update({"dissolution_date": None})
partner_vals.pop("end", False)
partner_vals.pop("end_reason", False)
return partner_vals
# © 2019 Le Filament (<http://www.le-filament.com>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from datetime import date
from odoo import models, fields, api
class ScopQuestionnaire(models.Model):
_name = "scop.questionnaire"
_description = "Questionnaire"
partner_id = fields.Many2one(
comodel_name='res.partner',
string='Organisme',
domain=[('is_company', '=', True)],
ondelete='cascade', index=True)
id_riga = fields.Integer("ID RIGA")
year = fields.Char("Année", index=True)
type_id = fields.Many2one(
'scop.questionnaire.type',
string="Type de questionnaire",
ondelete='restrict', index=True)
effective_date = fields.Date("Date d'effet du questionnaire")
staff_count = fields.Integer("Effectif (EF)")
staff_shareholder_count = fields.Integer("Eff. Sociétaires (ES)")
staff_average = fields.Integer("Eff. Moyen (EM)")
class ScopQuestionnaireType(models.Model):
_name = "scop.questionnaire.type"
_description = "Type de Questionnaire"
name = fields.Char('Type de Questionnaire')