Fonctionnalite: Ajout des contrats
This commit is contained in:
@@ -1,309 +0,0 @@
|
||||
from django.db import models
|
||||
from datetime import date
|
||||
from django.utils import timezone
|
||||
|
||||
class Bailleur(models.Model):
|
||||
"""Modèle représentant un bailleur de fonds pour les projets de recherche."""
|
||||
nom_organisme = models.CharField(
|
||||
max_length=200,
|
||||
unique=True
|
||||
)
|
||||
contact = models.CharField(
|
||||
max_length=100,
|
||||
blank=True,
|
||||
null=True
|
||||
)
|
||||
email = models.EmailField(
|
||||
blank=True,
|
||||
null=True
|
||||
)
|
||||
pays = models.CharField(
|
||||
max_length=100,
|
||||
blank=True,
|
||||
null=True
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return self.nom_organisme
|
||||
|
||||
class DomaineDeRecherche(models.Model):
|
||||
"""Modèle représentant les domaines de recherche"""
|
||||
|
||||
DOMAINE_RECHERCHE = [
|
||||
('sciences_sociales', 'Sciences sociales'),
|
||||
('naturelles', 'Naturelles'),
|
||||
('humaines', 'Humaines'),
|
||||
('veterinaires', 'Vétérinaires')
|
||||
]
|
||||
|
||||
nom = models.CharField(
|
||||
max_length=100,
|
||||
verbose_name="Domaine de recherche",
|
||||
choices=DOMAINE_RECHERCHE,
|
||||
primary_key=True
|
||||
)
|
||||
|
||||
class Meta:
|
||||
verbose_name = 'Domaine de recherche'
|
||||
verbose_name_plural = 'Domaines de recherche'
|
||||
|
||||
def __str__(self):
|
||||
return self.nom
|
||||
|
||||
class Projet(models.Model):
|
||||
"""Modèle représentant un projet de recherche avec ses caractéristiques et son bailleur associé."""
|
||||
TYPE_PROJET = [
|
||||
('laboratoire', 'Laboratoire'),
|
||||
('épidémiologie', 'Épidémiologie'),
|
||||
('sciences sociales', 'Sciences sociales'),
|
||||
('cliniques', 'Cliniques'),
|
||||
('autre', 'Autre'),
|
||||
]
|
||||
id_projet = models.CharField(
|
||||
max_length=100,
|
||||
blank=True,
|
||||
unique=True,
|
||||
primary_key=True,
|
||||
verbose_name="ID du projet"
|
||||
)
|
||||
nom_projet = models.CharField(
|
||||
max_length=200,
|
||||
verbose_name="Nom du projet"
|
||||
)
|
||||
date_debut = models.DateField(
|
||||
verbose_name="Date de début"
|
||||
)
|
||||
date_fin = models.DateField(
|
||||
verbose_name="Date de fin"
|
||||
)
|
||||
numero_convention = models.CharField(
|
||||
max_length=100,
|
||||
verbose_name="Numéro de convention"
|
||||
)
|
||||
description = models.TextField(
|
||||
verbose_name="Description"
|
||||
)
|
||||
type_projet = models.CharField(
|
||||
max_length=100,
|
||||
choices=TYPE_PROJET,
|
||||
default='épidémiologie',
|
||||
verbose_name="Type de projet"
|
||||
)
|
||||
domaine_recherche = models.ManyToManyField(DomaineDeRecherche)
|
||||
budget=models.DecimalField(
|
||||
max_digits=12,
|
||||
decimal_places=2,
|
||||
verbose_name="Budget"
|
||||
)
|
||||
budget_RH = models.DecimalField(
|
||||
max_digits=12,
|
||||
decimal_places=2,
|
||||
verbose_name="Budget RH"
|
||||
)
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
bailleur = models.ForeignKey(
|
||||
Bailleur,
|
||||
on_delete=models.SET_NULL,
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name="Bailleur de fonds"
|
||||
)
|
||||
|
||||
@property
|
||||
def statut(self):
|
||||
if self.date_fin < date.today():
|
||||
return "Terminé"
|
||||
return "En cours"
|
||||
|
||||
@property
|
||||
def avancement(self):
|
||||
aujourd_hui = date.today()
|
||||
if (self.date_debut and self.date_fin) and (self.date_debut < self.date_fin):
|
||||
duree_projet = (self.date_fin - self.date_debut).days
|
||||
temps_ecoule = (aujourd_hui - self.date_debut).days
|
||||
if duree_projet > 0:
|
||||
return round((temps_ecoule / duree_projet) * 100, 2)
|
||||
|
||||
return 0
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.nom_projet}"
|
||||
|
||||
class FinancementProjet(models.Model):
|
||||
"""
|
||||
Modèle représentant le financement d'un projet par un bailleur,
|
||||
avec le pourcentage de contribution.
|
||||
"""
|
||||
projet = models.ForeignKey(
|
||||
Projet,
|
||||
on_delete=models.CASCADE
|
||||
)
|
||||
bailleur = models.ForeignKey(
|
||||
Bailleur,
|
||||
on_delete=models.CASCADE
|
||||
)
|
||||
pourcentage = models.DecimalField(
|
||||
max_digits = 5,
|
||||
decimal_places=2
|
||||
)
|
||||
|
||||
class Meta:
|
||||
unique_together = ('projet', 'bailleur')
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.bailleur.nom} - {self.projet.nom_projet} ({self.pourcentage}%)"
|
||||
|
||||
class DocumentProjet(models.Model):
|
||||
"""Modèle représentant un document associé à un projet, avec des métadonnées et un fichier attaché."""
|
||||
NOM_DOCUMENT_CHOICES = [
|
||||
('protocole', 'Protocole d’étude'),
|
||||
('ethique', "Approbation du comité d'éthique"),
|
||||
('autorisation', 'Autorisation (DNLP)'),
|
||||
('rapport_technique', 'Rapport technique'),
|
||||
('rapport_financier', 'Rapport financier'),
|
||||
('rapport_avancement', "Rapport d'avancement"),
|
||||
('convention', 'Convention'),
|
||||
('rapport_final', 'Rapport final'),
|
||||
('autre', 'Autre'),
|
||||
]
|
||||
|
||||
projet = models.ForeignKey(
|
||||
Projet,
|
||||
on_delete=models.CASCADE,
|
||||
related_name='documents',
|
||||
verbose_name="Projet"
|
||||
)
|
||||
date_ajout = models.DateTimeField(
|
||||
auto_now_add=True,
|
||||
verbose_name="Date d'ajout"
|
||||
)
|
||||
nom_document = models.CharField(
|
||||
max_length = 100,
|
||||
choices = NOM_DOCUMENT_CHOICES,
|
||||
verbose_name="Type de document"
|
||||
)
|
||||
description = models.TextField(
|
||||
blank = True,
|
||||
verbose_name = "Description"
|
||||
)
|
||||
numero = models.CharField(
|
||||
max_length = 100,
|
||||
blank = True,
|
||||
null = True,
|
||||
verbose_name = "Numéro du document"
|
||||
)
|
||||
date_validite = models.DateField(
|
||||
blank = True,
|
||||
null = True,
|
||||
verbose_name = "Date de validité"
|
||||
)
|
||||
fichier = models.FileField(
|
||||
upload_to = 'documents_projets/',
|
||||
verbose_name = "Fichier à télécharger"
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.nom_document} ({self.projet})"
|
||||
|
||||
class ActiviteProjet(models.Model):
|
||||
"""Modèle représentant le planning d'un projet, avec des activités associées et un statut."""
|
||||
projet = models.ForeignKey(
|
||||
Projet,
|
||||
on_delete = models.CASCADE,
|
||||
verbose_name = "Projet"
|
||||
)
|
||||
titre = models.CharField(
|
||||
max_length = 200,
|
||||
verbose_name = "Titre de l'activité"
|
||||
)
|
||||
description = models.TextField(
|
||||
blank = True,
|
||||
null = True,
|
||||
verbose_name = "Description de l'activité"
|
||||
)
|
||||
date_debut = models.DateField(verbose_name="Date de début")
|
||||
date_fin = models.DateField(verbose_name="Date de fin")
|
||||
annuler = models.BooleanField(
|
||||
default = False,
|
||||
verbose_name = "Annuler l'activité"
|
||||
)
|
||||
motif_annulation = models.TextField(
|
||||
blank = True,
|
||||
null = True,
|
||||
verbose_name = "Motif d'annulation"
|
||||
)
|
||||
|
||||
motif_changement_budget = models.TextField(
|
||||
blank = True,
|
||||
null = True,
|
||||
verbose_name = "Motif de changement de budget"
|
||||
)
|
||||
budget_prevu = models.DecimalField(
|
||||
max_digits = 15,
|
||||
decimal_places = 2,
|
||||
default = 0,
|
||||
verbose_name = "Budget prévu"
|
||||
)
|
||||
budget_depense = models.DecimalField(
|
||||
max_digits = 15,
|
||||
decimal_places = 2,
|
||||
default = 0,
|
||||
verbose_name = "Budget dépensé"
|
||||
)
|
||||
besoin_ressource_materielle = models.TextField(
|
||||
verbose_name="Besoin de ressources matérielles"
|
||||
)
|
||||
|
||||
@property
|
||||
def statut(self):
|
||||
today = timezone.now().date()
|
||||
if not self.annuler:
|
||||
if self.date_fin < today:
|
||||
return 'Terminé'
|
||||
elif self.date_debut > today:
|
||||
return 'À venir'
|
||||
else:
|
||||
return 'En cours'
|
||||
else:
|
||||
return 'Annulé'
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.titre} ({self.projet.nom_projet})"
|
||||
|
||||
# class LivrableAttendu(models.Model):
|
||||
# """
|
||||
# Modèle représentant un livrable attendu pour une activité de projet,
|
||||
# avec des critères de validation.
|
||||
# """
|
||||
# activite = models.ForeignKey(
|
||||
# ActiviteProjet,
|
||||
# on_delete = models.CASCADE,
|
||||
# related_name = "livrables_attendus"
|
||||
# )
|
||||
# nom = models.CharField(max_length=255)
|
||||
|
||||
# def __str__(self):
|
||||
# return f"{self.nom} (Activité: {self.activite.titre})"
|
||||
|
||||
class LivrablesLivres(models.Model):
|
||||
"""Modèle représentant un livrable livré pour une activité de projet."""
|
||||
activite = models.ForeignKey(
|
||||
ActiviteProjet,
|
||||
on_delete = models.CASCADE
|
||||
)
|
||||
# nom = models.ForeignKey(
|
||||
# LivrableAttendu,
|
||||
# on_delete = models.CASCADE
|
||||
# )
|
||||
nom = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name="Nom du livrable"
|
||||
)
|
||||
|
||||
fichier = models.FileField(
|
||||
upload_to = 'fichier_livrables/',
|
||||
blank = True,
|
||||
null = True
|
||||
)
|
||||
def __str__(self):
|
||||
return self.nom
|
||||
Reference in New Issue
Block a user