Skip to content
Snippets Groups Projects
project.py 21.1 KiB
Newer Older
  • Learn to ignore specific revisions
  • Juliana's avatar
    Juliana committed
    # 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
    
    from odoo.tools.misc import xlwt
    
    Juliana's avatar
    Juliana committed
    
    
    import csv
    import base64
    
    
    HEADER_MEMBER = [
        'Nom',
        'Prénom',
        'Commune',
        'Mobile',
        'Fixe',
        'Email'
        ]
    
    
    Juliana's avatar
    Juliana committed
    
    class Project(models.Model):
        _inherit = "project.project"
    
    
        @api.model
        def _default_explication_financement(self):
            if self.env.user.company_id.explication_financement:
                return self.env.user.company_id.explication_financement
    
    
        privacy_visibility = fields.Selection([
                ('followers', 'On invitation only'),
                ('employees', 'Visible by all employees'),
                ('portal', 'Visible by following customers'),
            ],
            string='Confidentialité', required=True,
            default='employees')
    
    Juliana's avatar
    Juliana committed
        # 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'),
            ],
    
    Juliana's avatar
    Juliana committed
            string="Type contact")
        date_first_contact = fields.Date(
    
            "Date de 1er contact",
            default=fields.Date.today)
    
    Juliana's avatar
    Juliana committed
        prescripteur_id = fields.Many2one(
            'res.partner',
            string='Prescripteur',
            domain=[
                ('active', '=', True), 
                ('is_company', '=', False)],
            on_delete='restrict')
    
    Juliana's avatar
    Juliana committed
        porteurs_projets_ids = fields.One2many(
    
            'res.partner.porteur.project',
            'project_id',
    
    Juliana's avatar
    Juliana committed
            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.name', '=', 'ComCom'),
                ('type_structure_id.name', '=', 'PETR/PNR')],
    
            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')
    
    Juliana's avatar
    Juliana committed
        departement = fields.Selection([
            ('12', '12'),
            ('34', '34'),
            ('46', '46'),
            ('48', '48'),
            ('81', '81'),
            ('82', '82')
        ], string="Département du projet")
    
        user_id = fields.Many2one(
    
            string='CFD', 
            default=lambda self: self.env.user, 
            track_visibility="onchange")
    
    Juliana's avatar
    Juliana committed
    
        # 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',
    
    Juliana's avatar
    Juliana committed
            string='OD',
            domain=[
                ('active', '=', True), 
                ('is_company', '=', True)],
            on_delete='restrict')
    
        elu_id = fields.Many2one(
    
    Juliana's avatar
    Juliana committed
            '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',
    
    Juliana's avatar
    Juliana committed
            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)],
    
    Juliana's avatar
    Juliana committed
            string="Type de convention de financement")
    
        date_ca = fields.Date("Date de CA")
    
        date_demarrage = fields.Date("Date de démarrage prévisionnel")
    
    Juliana's avatar
    Juliana committed
    
        # 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")
    
    Juliana's avatar
    Juliana committed
        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')
    
    Juliana's avatar
    Juliana committed
        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'),
    
    Juliana's avatar
    Juliana committed
            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'),
    
    Juliana's avatar
    Juliana committed
            string="Secteur d'activité")
        taille = fields.Selection(
    
            [
                ('inf_10', "De 10 à 250"),
                ('sup_10', "< 10 salariés")
            ],
    
    Juliana's avatar
    Juliana committed
            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'),
    
    Juliana's avatar
    Juliana committed
            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'),
            ],
    
    Juliana's avatar
    Juliana committed
            string="Type formation")
        encadrement = fields.Selection(
    
            [
                ('minimis', 'De minimis'),
                ('neant', 'Neant'),
                ('encadrement', 'Encadrement des aides à la formation')
            ],
    
    Juliana's avatar
    Juliana committed
            string="Encadrement Aides")
    
        nb_activité = fields.Integer("Nombre d’activités ou entreprises concernées")
    
        nb_emplois = fields.Integer("Nombre d’emplois concernés")
    
    Juliana's avatar
    Juliana committed
        lieu = fields.Text("Lieu")
        periode_realisation = fields.Text("Période de réalisation")
    
        contenu_formation = fields.Text("Contenu de formation")
    
    
        # Info Budget
    
        nb_jours_adefpat = fields.Float("Nombre de jours CFD")
        cout_jour_adefpat = fields.Float("Coût jour CFD")
    
    Juliana's avatar
    Juliana committed
        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")
    
    Juliana's avatar
    Juliana committed
    
    
    Juliana's avatar
    Juliana committed
        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')
    
        explication_financement = fields.Text(
            "Explication financement porteur de projet",
            default=_default_explication_financement)
    
    Juliana's avatar
    Juliana committed
        # Champs étape "Instruction" => Onglet Consultation
    
    Juliana's avatar
    Juliana committed
        consulant_ids = fields.One2many(
            'res.partner.consultants.project',
            'project_id',
    
    Juliana's avatar
    Juliana committed
            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")
    
    Juliana's avatar
    Juliana committed
        # 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.One2many(
            'res.partner.membres.project',
            'project_id',
    
    Juliana's avatar
    Juliana committed
            string="Membres")
        modalite_gap = fields.Text("Modalités GAP")
    
        reunion_ids = fields.One2many(
            'adefpat.reunion.gap', 
            'project_id', 
            string="Réunions")
    
    Juliana's avatar
    Juliana committed
    
        # 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:
    
    Juliana's avatar
    Juliana committed
                total_financement = 0.0
    
                for financement in project.financement_ids:
    
    Juliana's avatar
    Juliana committed
                    total_financement += financement.montant
                project.total_financement = total_financement
    
    
        @api.depends('cout_ids', 'cout_ids.montant')
        @api.multi
        def _compute_total_cout(self):
            for project in self:
    
    Juliana's avatar
    Juliana committed
                total_cout = 0.0
    
                for cout in project.cout_ids:
    
    Juliana's avatar
    Juliana committed
                    total_cout += cout.montant
                project.total_cout = total_cout
    
    
        @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:
    
                project.type_beneficiaire = ', '.join(project.porteurs_projets_ids.mapped('statut.name'))
    
        @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(
    
        def get_workbook(self, filename_, project_id):
            project = self.env['project.project'].search([('id', '=', project_id)])
            workbook = xlwt.Workbook()
            worksheet = workbook.add_sheet(filename_)
    
            gap_ids = project.membre_ids
            
            header_file = HEADER_MEMBER
            for i, fieldname in enumerate(header_file):
                worksheet.write(0, i, fieldname)
                worksheet.col(i).width = 8000  # around 220 pixels
    
            base_style = xlwt.easyxf('align: wrap yes')
            cell_style = base_style
    
            row_index = 1
    
            for gap_id in gap_ids:
                worksheet.write(row_index, 0,
                                str(gap_id.lastname), cell_style)
                worksheet.write(row_index, 1,
                                str(gap_id.firstname), cell_style)
                worksheet.write(row_index, 2,
                                str(gap_id.commune), cell_style)
                worksheet.write(row_index, 3,
                                str(gap_id.mobile), cell_style)
                worksheet.write(row_index, 4,
                                str(gap_id.fixe), cell_style)
                worksheet.write(row_index, 5,
                                str(gap_id.email), cell_style)
                row_index = row_index + 1
            return workbook
    
        @api.multi
        def export_gap(self):
            for project in self:
                filename_ = project.name
                project_id = project.id
                return {
                    'type': 'ir.actions.act_url',
                    'url':
                        '/web/export_gap?filename_=%s&project_id=%s'
                        % (filename_, project_id),
                    'target': 'new',
                }
    
    Juliana's avatar
    Juliana committed
    
    class AdefpatTypeConvention(models.Model):
        _name = 'adefpat.type.convention'
    
        _description = 'Liste type de convention'
    
    Juliana's avatar
    Juliana committed
    
    
        name = fields.Char(
            string="Convention",
            required=True,
        )
    
        date_end_validity = fields.Date("Date de fin de validité")
    
    Juliana's avatar
    Juliana committed
    
    
    class AdefpatReunionGAP(models.Model):
        _name = 'adefpat.reunion.gap'
        _description = 'Réunions GAP'
    
        _rec_name = 'date'
    
    Juliana's avatar
    Juliana committed
    
        # document_ids = fields.One2many('ir.attachment', string="Documents")
    
        date = fields.Date(
            string="Date du GAP",
            required=True,
        )
    
    Juliana's avatar
    Juliana committed
        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)],
    
            required=True,
    
    Juliana's avatar
    Juliana committed
            on_delete='restrict')
        lastname = fields.Char(
            related='partner_id.lastname', 
    
    Juliana's avatar
    Juliana committed
        firstname = fields.Char(
            related='partner_id.firstname', 
            string="Prénom",
    
    Juliana's avatar
    Juliana committed
        commune = fields.Char(
            related='partner_id.city', 
            string="Commune",
    
    Juliana's avatar
    Juliana committed
        mobile = fields.Char(
            related='partner_id.mobile', 
            string="Mobile",
    
    Juliana's avatar
    Juliana committed
        fixe = fields.Char(
            related='partner_id.phone', 
            string="Fixe",
    
    Juliana's avatar
    Juliana committed
        email = fields.Char(
            related='partner_id.email', 
            string="Email",
    
        project_id = fields.Many2one(
            'project.project',
            string='Projet',
            default=lambda self: self.env.context.get('default_project_id'))
    
    Juliana's avatar
    Juliana committed
    
    
    class AdefpatConsultantsProjets(models.Model):
        _name = 'res.partner.consultants.project'
        _description = 'Consultants'
    
        _rec_name = 'name'
    
    Juliana's avatar
    Juliana committed
    
        partner_id = fields.Many2one(
            'res.partner',
            string='Consultant',
            domain=[
                ('active', '=', True), 
    
                ('is_company', '=', False),
                ('is_consultant_form', '=', True),
                '|', ('reference', '=', 'reference'),
                ('reference', '=', 'prereference')],
    
            required=True,
    
    Juliana's avatar
    Juliana committed
            on_delete='restrict')
    
        name = fields.Char(related='partner_id.name')
    
    Juliana's avatar
    Juliana committed
        lastname = fields.Char(
            related='partner_id.lastname', 
    
    Juliana's avatar
    Juliana committed
        firstname = fields.Char(
            related='partner_id.firstname', 
    
    Juliana's avatar
    Juliana committed
        mobile = fields.Char(
            related='partner_id.mobile', 
    
    Juliana's avatar
    Juliana committed
        email = fields.Char(
            related='partner_id.email', 
    
    Juliana's avatar
    Juliana committed
        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")
    
        is_selected = fields.Boolean("Est sélectionné")
    
    Juliana's avatar
    Juliana committed
        project_id = fields.Many2one(
            'project.project',
            string='Projet',
            default=lambda self: self.env.context.get('default_project_id'))
    
    Juliana's avatar
    Juliana committed
    
    
    class AdefpatPorteursProjets(models.Model):
        _name = 'res.partner.porteur.project'
        _description = 'Porteurs de projets'
    
        _rec_name = 'name'
    
    Juliana's avatar
    Juliana committed
    
    
        porteur_id = fields.Many2one(
    
    Juliana's avatar
    Juliana committed
            'res.partner',
            string='Porteur de projet',
    
            domain=[('is_company', '=', False)],
            required=True,
            on_delete='restrict'
        )
        name = fields.Char(related='porteur_id.name')
    
    Juliana's avatar
    Juliana committed
        lastname = fields.Char(
    
    Juliana's avatar
    Juliana committed
            related='porteur_id.lastname',
    
    Juliana's avatar
    Juliana committed
        firstname = fields.Char(
    
    Juliana's avatar
    Juliana committed
            related='porteur_id.firstname',
    
    Juliana's avatar
    Juliana committed
        commune = fields.Char(
    
    Juliana's avatar
    Juliana committed
            related='porteur_id.city',
    
    Juliana's avatar
    Juliana committed
        mobile = fields.Char(
    
    Juliana's avatar
    Juliana committed
            related='porteur_id.mobile',
    
    Juliana's avatar
    Juliana committed
        fixe = fields.Char(
    
    Juliana's avatar
    Juliana committed
            related='porteur_id.phone',
    
    Juliana's avatar
    Juliana committed
        email = fields.Char(
    
    Juliana's avatar
    Juliana committed
            related='porteur_id.email',
    
        statut = fields.Many2one(
            'adefpat.project.statut',
    
    Juliana's avatar
    Juliana committed
            string="Statut")
        eligible = fields.Boolean(
    
            string="Eligible")
    
    Juliana's avatar
    Juliana committed
        is_present = fields.Boolean("Est présent")
        task_id = fields.Many2one(
            'project.task',
    
            string='Séance',
    
    Juliana's avatar
    Juliana committed
            default=lambda self: self.env.context.get('default_task_id'))
    
        project_id = fields.Many2one(
            'project.project',
            string='Projet',
            default=lambda self: self.env.context.get('default_project_id'))
    
    
    
    class AdefpatStatut(models.Model):
        _name = 'adefpat.project.statut'
        _description = 'Statut'
    
    
        name = fields.Char("Statut", required=True,)
    
    
    
    class AdefpatFinancement(models.Model):
        _name = 'adefpat.project.financement'
        _description = 'Financements'
    
        partner_id = fields.Many2one(
            'res.partner',
    
            string='Facturation',
    
            domain=[
                ('active', '=', True)],
    
            required=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", required=True,)
    
        partner_id = fields.Many2one(
            'res.partner',
    
            string='Consultant',
    
                ('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