# Copyright 2020 Le Filament (<http://www.le-filament.com>) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from datetime import datetime, timedelta from odoo import models, fields, api import csv import base64 class Project(models.Model): _inherit = "project.project" privacy_visibility = fields.Selection([ ('followers', 'On invitation only'), ('employees', 'Visible by all employees'), ('portal', 'Visible by following customers'), ], string='Confidentialité', required=True, default='employees') # Champs étape "Demande" => Vue générale name_subtitle = fields.Char("Sous-titre") first_contact_id = fields.Many2one( 'res.partner', string='1er contact', domain=[ ('active', '=', True), ('is_company', '=', False)], on_delete='restrict') type_contact = fields.Selection([ ('adherent', 'Adhérent'), ('no_adherent', 'Non adhérent'), ('pdp', 'Porteur de projet'), ], string="Type contact") date_first_contact = fields.Date( "Date de 1er contact", default=fields.Date.today) prescripteur_id = fields.Many2one( 'res.partner', string='Prescripteur', domain=[ ('active', '=', True), ('is_company', '=', False)], on_delete='restrict') porteurs_projets_ids = fields.Many2many( comodel_name='res.partner.porteur.project', relation='res_partner_porteur_project_rel', column1='porteur_id', column2='project_id', string="Porteurs de projet") description = fields.Text("Description") territoire_id = fields.Many2one( 'res.partner', string='Territoire', domain=[ ('active', '=', True), ('is_company', '=', True), ('type_structure_id', '=', 'ComCom')], on_delete='restrict') departement_ids = fields.Many2many( comodel_name='res.partner', relation='res_partner_departement_rel', column1='partner_id', column2='departement_id', domain=[ ('active', '=', True), ('is_company', '=', True), ('type_structure_id.name', '=', 'Département')], string="Départements", related='territoire_id.departement_ids') region_ids = fields.Many2many( comodel_name='res.partner', relation='res_partner_region_rel', column1='partner_id', column2='region_id', domain=[ ('active', '=', True), ('is_company', '=', True), ('type_structure_id.name', '=', 'Région')], string="Régions", related='territoire_id.region_ids') petr_ids = fields.Many2many( comodel_name='res.partner', relation='res_partner_petr_rel', column1='partner_id', column2='petr_id', domain=[ ('active', '=', True), ('is_company', '=', True), ('type_structure_id.name', '=', 'PETR/PNR')], string="PETR/PNR", related='territoire_id.petr_ids') departement = fields.Selection([ ('12', '12'), ('34', '34'), ('46', '46'), ('48', '48'), ('81', '81'), ('82', '82') ], string="Département du projet") user_id = fields.Many2one( 'res.users', string='CFD', default=lambda self: self.env.user, track_visibility="onchange") # Champs étape "Instruction" => Vue générale od_ids = fields.Many2many( comodel_name='res.partner', column1='project_id', column2='od_id', relation='res_partner_od_rel', string='OD', domain=[ ('active', '=', True), ('is_company', '=', True)], on_delete='restrict') elu_id = fields.Many2one( 'res.partner', string='Elu qui présente le dossier', domain=[ ('active', '=', True), ('is_company', '=', False)], on_delete='restrict') animateur_ids = fields.Many2many( comodel_name = 'res.partner', column1='project_id', column2='anim_id', relation='res_partner_anim_rel', string='Animateurs', domain=[ ('active', '=', True), ('is_company', '=', False)], on_delete='restrict') type_convention_id = fields.Many2one( 'adefpat.type.convention', domain=[ '|', ('date_end_validity', '>=', fields.Date.today()), ('date_end_validity', '=', False)], string="Type de convention de financement") date_ca = fields.Date("Date de CA") date_demarrage = fields.Date("Date de démarrage prévisionnel") # list_photos_ids = fields.One2many('images') # documents_ids = fields.One2many('ir.attachment', "Documents") # Champs étape "Instruction" => Onglet Dossier contexte = fields.Text("Contexte projet") caract_beneficiaire = fields.Text("Caractéristiques du bénéficiaire") historique = fields.Text("Historique & Aujourd’hui") besoins_beneficiaires = fields.Text("Besoins des bénéficiaires") objectifs_accompagnement = fields.Text("Objectifs d’accompagnement") competences_requises = fields.Text("Compétences du CF") secteurs_requis = fields.Text("Secteurs d’activités") modalites_intervention = fields.Text("Modalités d'intervention") modalites_facturation = fields.Text("Modalités de facturation") modalites_reponse = fields.Text("Modalités de réponse") # Infos dossier CA type_beneficiaire = fields.Char("Type de bénéficiares", compute='_compute_type_beneficiaire') objectif_projet = fields.Selection( [ ('creation', "Création d'entreprise"), ('creation_activite', 'Création nouvelle activité'), ('consolidation', 'Consolidation'), ('emergence', 'Émergence'), ('operation', "Opération territoriale pour les entreprises"), ('post_creation', 'Post-création'), ('post_reprise', 'Post-reprise'), ('projet_inter', 'Projet inter-entreprise'), ('projet_structurant', 'Projet structurant territoire'), ('reprise', 'Reprise'), ('transmission', 'Transmission'), ], string="Objectif projet") secteur_crit = fields.Selection( [ ('agriculture', 'Agriculture'), ('agro_alimentaire', 'Agro-alimentaire'), ('artisanat', 'Artisanat - Commerce - Industrie'), ('culture', 'Culture'), ('environnement', 'Environnement'), ('intersectoriel', 'Intersectoriel'), ('service', 'Service'), ('service', 'Services à la population'), ('tourisme', 'Tourisme - Hôtellerie - Restauration'), ], string="Secteur d'activité") taille = fields.Selection( [ ('inf_10', "De 10 à 250"), ('sup_10', "< 10 salariés") ], string="Taille entreprise") objectif_formation = fields.Selection( [ ('def_projet', "Définition de projet"), ('def_modele_eco', "Définition d'un modèle économique"), ('def_strat_com', "Définition d'une stratégie de développement"), ('diagnostic', 'Diagnostic stratégique'), ('gestion_prod', 'Gestion de production'), ('gestion_financ', 'Gestion financière'), ('marketing', "Marketing - Commercialisation - Promotion - Communication"), ('management', 'Management - Organisation - RH'), ('orga_collective', 'Organisation collective'), ], string="Objectif formation") type_formation = fields.Selection( [ ('individuelle', 'Générale individuelle'), ('collective', 'Générale collective'), ('indiv_collect', 'Générale collective individualisée'), ], string="Type formation") encadrement = fields.Selection( [ ('minimis', 'De minimis'), ('neant', 'Neant'), ('encadrement', 'Encadrement des aides à la formation') ], string="Encadrement Aides") lieu = fields.Text("Lieu") periode_realisation = fields.Text("Période de réalisation") # Info Budget nb_jours_adefpat = fields.Float("Nombre de jours CFD") cout_jour_adefpat = fields.Float("Coût jour CFD") total_cout_adefpat = fields.Float("Total coûts CFD", compute='_compute_total_cout_adefpat') financement_adefpat = fields.Float("Financement Adefpat", compute='_compute_financement_adefpat') financement_ids = fields.One2many( 'adefpat.project.financement', 'project_id', string="Financements") total_financement = fields.Float("Total autres", compute='_compute_total_financment') cout_ids = fields.One2many( 'adefpat.project.cout', 'project_id', string="Coûts") total_cout = fields.Float("Total coûts", compute='_compute_total_cout') honoraire_intervenant = fields.Float( "Honoraires d'intervenants") total_budget_cout = fields.Float("Total budget coûts", compute='_compute_total_budget_cout') total_budget_financement = fields.Float("Total budget financements", compute='_compute_total_budget_financement') # Champs étape "Instruction" => Onglet Consultation consulant_ids = fields.Many2many( comodel_name='res.partner.consultants.project', relation='res_partner_consultants_project_rel', column1='consultant_id', column2='project_id', string="Consultants") date_selection = fields.Date("Date de sélection") date_notification = fields.Date("Date de notification") date_cdc = fields.Date("Date d'envoi du CDC") # Champs étape "Instruction" => Onglet GAP elu_referent_id = fields.Many2one( 'res.partner', string='Élu référent', domain=[ ('active', '=', True), ('is_company', '=', False)], on_delete='restrict') membre_ids = fields.Many2many( comodel_name='res.partner.membres.project', relation='res_partner_membres_project_rel', column1='membre_id', column2='project_id', string="Membres") # documents_gap_ids = fields.One2many('ir.attachment', string="Documents GAP") modalite_gap = fields.Text("Modalités GAP") reunion_ids = fields.One2many( 'adefpat.reunion.gap', 'project_id', string="Réunions") # Champs étape "Prêt pour CA" => Onglet Général num_dossier = fields.Char("Numéro de dossier") @api.depends('financement_ids', 'financement_ids.montant') @api.multi def _compute_total_financment(self): for project in self: project.total_financement = 0.0 for financement in project.financement_ids: project.total_financement += financement.montant @api.depends('cout_ids', 'cout_ids.montant') @api.multi def _compute_total_cout(self): for project in self: project.total_cout = 0.0 for cout in project.cout_ids: project.total_cout += cout.montant @api.depends('nb_jours_adefpat', 'cout_jour_adefpat') @api.multi def _compute_total_cout_adefpat(self): for project in self: project.total_cout_adefpat = project.nb_jours_adefpat * project.cout_jour_adefpat @api.depends('total_cout_adefpat', 'total_cout') @api.multi def _compute_total_budget_cout(self): for project in self: project.total_budget_cout = project.total_cout_adefpat + project.total_cout @api.depends('total_budget_cout', 'total_financement') @api.multi def _compute_financement_adefpat(self): for project in self: project.financement_adefpat = project.total_budget_cout - project.total_financement @api.depends('financement_adefpat', 'total_financement') @api.multi def _compute_total_budget_financement(self): for project in self: project.total_budget_financement = project.financement_adefpat + project.total_financement @api.depends('porteurs_projets_ids', 'porteurs_projets_ids.statut') @api.multi def _compute_type_beneficiaire(self): for project in self: list_benef = [] for porteur in project.porteurs_projets_ids: if porteur.statut: list_benef.append(porteur.statut.name) project.type_beneficiaire = list(dict.fromkeys(list_benef)) @api.multi def validate_ca(self): for project in self: project.num_dossier = project.departement + '/' + datetime.strftime(datetime.today(), '%y') + '/' + self.env['ir.sequence'].next_by_code( 'increment_num_dossier') # @api.multi # def export_gap(self): # for project in self: # if project.membre_ids: # with open('export.csv', mode='w') as file: # writer = csv.writer(file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL) # # create a row contains heading of each column # writer.writerow( # ['Membre', 'Email']) # # fetch products and write respective data. # for membre in project.membre_ids: # writer.writerow([membre.lastname, membre.email]) # with open('export.csv', 'r', encoding="utf-8") as f2: # data = str.encode(f2.read(), 'utf-8') class AdefpatTypeConvention(models.Model): _name = 'adefpat.type.convention' _description = 'Liste type de convetion' name = fields.Char("Convention") date_end_validity = fields.Date("Date de fin de validité") class AdefpatReunionGAP(models.Model): _name = 'adefpat.reunion.gap' _description = 'Réunions GAP' # document_ids = fields.One2many('ir.attachment', string="Documents") date = fields.Date("Date du GAP") project_id = fields.Many2one( 'project.project', string='Projet', default=lambda self: self.env.context.get('default_project_id')) class AdefpatMembresProjets(models.Model): _name = 'res.partner.membres.project' _description = 'Membres' partner_id = fields.Many2one( 'res.partner', string='Membre', domain=[ ('active', '=', True), ('is_company', '=', False)], on_delete='restrict') lastname = fields.Char( related='partner_id.lastname', string="Nom", store=False) firstname = fields.Char( related='partner_id.firstname', string="Prénom", store=False) commune = fields.Char( related='partner_id.city', string="Commune", store=False) mobile = fields.Char( related='partner_id.mobile', string="Mobile", store=False) fixe = fields.Char( related='partner_id.phone', string="Fixe", store=False) email = fields.Char( related='partner_id.email', string="Email", store=False) class AdefpatConsultantsProjets(models.Model): _name = 'res.partner.consultants.project' _description = 'Consultants' partner_id = fields.Many2one( 'res.partner', string='Consultant', domain=[ ('active', '=', True), ('is_company', '=', False), ('is_consultant_form', '=', True), '|', ('reference', '=', 'reference'), ('reference', '=', 'prereference')], on_delete='restrict') lastname = fields.Char( related='partner_id.lastname', string="Nom", store=False) firstname = fields.Char( related='partner_id.firstname', string="Prénom", store=False) mobile = fields.Char( related='partner_id.mobile', string="Mobile", store=False) email = fields.Char( related='partner_id.email', string="Email", store=False) reference = fields.Selection([ ('reference', 'Référencé'), ('prereference', 'Pré-Référencé'), ('dereference', 'Dé-Référencé')], related='partner_id.reference', string="Référencement", store=False) cout_journée = fields.Float("Coût journée") # document_ids = fields.One2many('ir.attachment', string="Documents Consultants") is_selected = fields.Boolean("Est sélectionné") class AdefpatPorteursProjets(models.Model): _name = 'res.partner.porteur.project' _description = 'Porteurs de projets' porteur_id = fields.Many2one( 'res.partner', string='Porteur de projet', domain=[ ('active', '=', True), ('is_company', '=', False)], on_delete='restrict') partner_id = fields.Many2one( 'res.partner', string='Porteur de projet', domain=[ ('active', '=', True), ('is_company', '=', False)], on_delete='restrict') lastname = fields.Char( related='porteur_id.lastname', string="Nom", store=False) firstname = fields.Char( related='porteur_id.firstname', string="Prénom", store=False) commune = fields.Char( related='porteur_id.city', string="Commune", store=False) mobile = fields.Char( related='porteur_id.mobile', string="Mobile", store=False) fixe = fields.Char( related='porteur_id.phone', string="Fixe", store=False) email = fields.Char( related='porteur_id.email', string="Email", store=False) statut = fields.Many2one( 'adefpat.project.statut', string="Statut") eligible = fields.Boolean( string="Eligible") is_present = fields.Boolean("Est présent") task_id = fields.Many2one( 'project.task', string='Tâche', default=lambda self: self.env.context.get('default_task_id')) class AdefpatStatut(models.Model): _name = 'adefpat.project.statut' _description = 'Statut' name = fields.Char("Statut") class AdefpatFinancement(models.Model): _name = 'adefpat.project.financement' _description = 'Financements' partner_id = fields.Many2one( 'res.partner', string='Facturation', domain=[ ('active', '=', True)], on_delete='restrict') montant = fields.Float("Montant") project_id = fields.Many2one( 'project.project', string='Projet', default=lambda self: self.env.context.get('default_project_id')) class AdefpatCout(models.Model): _name = 'adefpat.project.cout' _description = 'Coûts' module = fields.Char("Nom du module") partner_id = fields.Many2one( 'res.partner', string='Consultant', domain=[ ('active', '=', True), ('is_company', '=', False), ('is_consultant_form', '=', True)], on_delete='restrict') nb_jour_theorique = fields.Float("Nombre de jours théoriques") nb_jour_pratiques = fields.Float("Nombre de jours pratiques") cout_jour = fields.Float("Coût jour") montant = fields.Float("Montant", compute='_compute_montant') project_id = fields.Many2one( 'project.project', string='Projet', default=lambda self: self.env.context.get('default_project_id')) @api.depends('cout_jour', 'nb_jour_theorique') def _compute_montant(self): for r in self: r.montant = r.cout_jour * r.nb_jour_theorique