Fonctionnalite: Ajout des contrats
This commit is contained in:
@@ -1,6 +0,0 @@
|
||||
from django.contrib import admin
|
||||
from .models import DomaineDeRecherche
|
||||
|
||||
@admin.register(DomaineDeRecherche)
|
||||
class DomaineDeRecherche(admin.ModelAdmin):
|
||||
list_display = ('nom',)
|
||||
@@ -1,176 +0,0 @@
|
||||
from django import forms
|
||||
from gestion_projet.models import Projet
|
||||
from .models import (
|
||||
ActiviteProjet,
|
||||
Bailleur,
|
||||
DocumentProjet,
|
||||
FinancementProjet,
|
||||
LivrablesLivres,
|
||||
DomaineDeRecherche
|
||||
)
|
||||
|
||||
class ProjetForm(forms.ModelForm):
|
||||
"""Formulaire de création et de modification d'un projet, avec validation des dates et personnalisation des champs."""
|
||||
class Meta:
|
||||
model = Projet
|
||||
fields = (
|
||||
'id_projet',
|
||||
'nom_projet',
|
||||
'date_debut',
|
||||
'date_fin',
|
||||
'numero_convention',
|
||||
'domaine_recherche',
|
||||
'type_projet',
|
||||
'budget',
|
||||
'budget_RH',
|
||||
'description'
|
||||
)
|
||||
# domaine_recherche = forms.ModelMultipleChoiceField(
|
||||
# queryset=DomaineDeRecherche.objects.all(),
|
||||
# to_field_name="nom",
|
||||
# required=False
|
||||
# )
|
||||
widgets = {
|
||||
'id_projet': forms.TextInput(attrs={'class': "form-control"}),
|
||||
'nom_projet': forms.TextInput(attrs={'class': "form-control"}),
|
||||
'numero_convention': forms.TextInput(attrs={'class': "form-control"}),
|
||||
'domaine_recherche': forms.SelectMultiple(attrs={'class': "form-control"}),
|
||||
'type_projet': forms.Select(attrs={'class': "form-select"}),
|
||||
'budget': forms.NumberInput(attrs={'class': "form-control"}),
|
||||
'budget_RH': forms.NumberInput(attrs={'class': "form-control"}),
|
||||
'description': forms.Textarea(attrs={'class': "form-control"}),
|
||||
'date_debut': forms.DateInput(attrs={'type': 'date', 'class': "form-control"}),
|
||||
'date_fin': forms.DateInput(attrs={'type': 'date', 'class': "form-control"}),
|
||||
}
|
||||
|
||||
class BailleurForm(forms.ModelForm):
|
||||
"""
|
||||
Formulaire de création et de modification d'un bailleur,
|
||||
avec validation des champs et personnalisation des labels.
|
||||
"""
|
||||
class Meta:
|
||||
model = Bailleur
|
||||
fields = ('nom_organisme', 'contact', 'email', 'pays')
|
||||
widgets = {
|
||||
'nom_organisme':forms.TextInput(attrs={
|
||||
'class':'form-control',
|
||||
}),
|
||||
'contact':forms.TextInput(attrs={
|
||||
'class':'form-control',
|
||||
}),
|
||||
'email':forms.TextInput(attrs={
|
||||
'class':'form-control',
|
||||
}),
|
||||
'pays':forms.TextInput(attrs={
|
||||
'class':'form-control',
|
||||
}),
|
||||
}
|
||||
|
||||
class DocumentProjetForm(forms.ModelForm):
|
||||
"""
|
||||
Formulaire pour ajouter ou modifier un document associé à un projet,
|
||||
avec validation des champs et personnalisation des labels.
|
||||
"""
|
||||
class Meta:
|
||||
model = DocumentProjet
|
||||
fields = [
|
||||
'nom_document',
|
||||
'numero',
|
||||
'date_validite',
|
||||
'fichier',
|
||||
'description'
|
||||
]
|
||||
widgets = {
|
||||
'nom_document': forms.Select(attrs={'class': 'form-select'}),
|
||||
'description': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}),
|
||||
'numero': forms.TextInput(attrs={'class': 'form-control'}),
|
||||
'date_validite': forms.DateInput(attrs={'class': 'form-control', 'type': 'date'}),
|
||||
'fichier': forms.ClearableFileInput(attrs={'class': 'form-control'}),
|
||||
}
|
||||
|
||||
class ActiviteProjetForm(forms.ModelForm):
|
||||
"""Formulaire pour créer ou modifier une activité de projet, avec validation des champs et personnalisation des widgets."""
|
||||
class Meta:
|
||||
model = ActiviteProjet
|
||||
fields = (
|
||||
'titre',
|
||||
'date_debut',
|
||||
'date_fin',
|
||||
'besoin_ressource_materielle',
|
||||
'budget_prevu',
|
||||
'description',
|
||||
)
|
||||
|
||||
widgets = {
|
||||
'titre':forms.TextInput(attrs={
|
||||
'class':'form-control',
|
||||
'placeholder':'Titre de l’activité'
|
||||
}),
|
||||
'description':forms.Textarea(attrs={
|
||||
'class':'form-control',
|
||||
'rows':3,
|
||||
'placeholder':'Description de l’activité'
|
||||
}),
|
||||
'date_debut':forms.DateInput(attrs={
|
||||
'class':'form-control',
|
||||
'type':'date'
|
||||
}),
|
||||
'date_fin':forms.DateInput(attrs={
|
||||
'class':'form-control',
|
||||
'type':'date'
|
||||
}),
|
||||
'besoin_ressource_materielle': forms.Textarea(attrs={
|
||||
'class':'form-control',
|
||||
'rows':3,
|
||||
'placeholder':'Besoin de ressources matérielles'
|
||||
}),
|
||||
'budget_prevu': forms.NumberInput(attrs={
|
||||
'class':'form-control',
|
||||
'placeholder':'Budget prévu'
|
||||
}),
|
||||
}
|
||||
|
||||
class FinancementProjetFrom(forms.ModelForm):
|
||||
"""Formulaire pour créer ou modifier le financement relatif à un projet."""
|
||||
class Meta:
|
||||
model = FinancementProjet
|
||||
fields = (
|
||||
'projet',
|
||||
'bailleur',
|
||||
'pourcentage',
|
||||
)
|
||||
|
||||
widgets = {
|
||||
'projet':forms.Select(attrs={
|
||||
'class':'form-select',
|
||||
}),
|
||||
'bailleur':forms.Select(attrs={
|
||||
'class':'form-select',
|
||||
}),
|
||||
'pourcentage':forms.NumberInput(attrs={
|
||||
'class':'form-control',
|
||||
}),
|
||||
}
|
||||
|
||||
class LivrablesLivresForm(forms.ModelForm):
|
||||
"""Formulaire pour créer ou modifier un livrable livré dans le cadre d'une activité de projet."""
|
||||
class Meta:
|
||||
model = LivrablesLivres
|
||||
fields = (
|
||||
'activite',
|
||||
'nom',
|
||||
'fichier',
|
||||
)
|
||||
|
||||
widgets = {
|
||||
'activite': forms.Select(attrs={
|
||||
'class':'form-select',
|
||||
}),
|
||||
'nom': forms.TextInput(attrs={
|
||||
'class':'form-control',
|
||||
'placeholder':'Nom du livrable'
|
||||
}),
|
||||
'fichier': forms.ClearableFileInput(attrs={
|
||||
'class':'form-control',
|
||||
}),
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
# Generated by Django 5.2.13 on 2026-04-17 12:03
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='ActiviteProjet',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('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(decimal_places=2, default=0, max_digits=15, verbose_name='Budget prévu')),
|
||||
('budget_depense', models.DecimalField(decimal_places=2, default=0, max_digits=15, verbose_name='Budget dépensé')),
|
||||
('besoin_ressource_materielle', models.TextField(verbose_name='Besoin de ressources matérielles')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Bailleur',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('nom_organisme', models.CharField(max_length=200, unique=True)),
|
||||
('contact', models.CharField(blank=True, max_length=100, null=True)),
|
||||
('email', models.EmailField(blank=True, max_length=254, null=True)),
|
||||
('pays', models.CharField(blank=True, max_length=100, null=True)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='DomaineDeRecherche',
|
||||
fields=[
|
||||
('nom', models.CharField(choices=[('sciences_sociales', 'Sciences sociales'), ('naturelles', 'Naturelles'), ('humaines', 'Humaines'), ('veterinaires', 'Vétérinaires')], max_length=100, primary_key=True, serialize=False, verbose_name='Domaine de recherche')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Domaine de recherche',
|
||||
'verbose_name_plural': 'Domaines de recherche',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='LivrablesLivres',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('nom', models.CharField(max_length=255, verbose_name='Nom du livrable')),
|
||||
('fichier', models.FileField(blank=True, null=True, upload_to='fichier_livrables/')),
|
||||
('activite', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='gestion_projet.activiteprojet')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Projet',
|
||||
fields=[
|
||||
('id_projet', models.CharField(blank=True, max_length=100, primary_key=True, serialize=False, unique=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(choices=[('laboratoire', 'Laboratoire'), ('épidémiologie', 'Épidémiologie'), ('sciences sociales', 'Sciences sociales'), ('cliniques', 'Cliniques'), ('autre', 'Autre')], default='épidémiologie', max_length=100, verbose_name='Type de projet')),
|
||||
('budget', models.DecimalField(decimal_places=2, max_digits=12, verbose_name='Budget')),
|
||||
('budget_RH', models.DecimalField(decimal_places=2, max_digits=12, verbose_name='Budget RH')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('bailleur', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='gestion_projet.bailleur', verbose_name='Bailleur de fonds')),
|
||||
('domaine_recherche', models.ManyToManyField(to='gestion_projet.domainederecherche')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='DocumentProjet',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('date_ajout', models.DateTimeField(auto_now_add=True, verbose_name="Date d'ajout")),
|
||||
('nom_document', models.CharField(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')], max_length=100, verbose_name='Type de document')),
|
||||
('description', models.TextField(blank=True, verbose_name='Description')),
|
||||
('numero', models.CharField(blank=True, max_length=100, 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')),
|
||||
('projet', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='documents', to='gestion_projet.projet', verbose_name='Projet')),
|
||||
],
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='activiteprojet',
|
||||
name='projet',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='gestion_projet.projet', verbose_name='Projet'),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='FinancementProjet',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('pourcentage', models.DecimalField(decimal_places=2, max_digits=5)),
|
||||
('bailleur', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='gestion_projet.bailleur')),
|
||||
('projet', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='gestion_projet.projet')),
|
||||
],
|
||||
options={
|
||||
'unique_together': {('projet', 'bailleur')},
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -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
|
||||
@@ -1,19 +0,0 @@
|
||||
const boutonEnregistrerProjet = $("btnEnregistrerProjet");
|
||||
|
||||
boutonEnregistrerProjet.addEventListener("click", function() {
|
||||
const formulaire = $("formCreationProjet");
|
||||
const formData = new FormData(formulaire);
|
||||
fetch(formulaire.action, {
|
||||
method: "POST",
|
||||
body: formData,
|
||||
headers: {
|
||||
"X-CSRFToken": formData.get("csrfmiddlewaretoken")
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
if (response.ok) {
|
||||
window.location.reload();
|
||||
alert("Projet enregistré avec succès !");
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -1,22 +0,0 @@
|
||||
const btn_enregistrer_financement = document.getElementById('btn_enregistrer_financement');
|
||||
|
||||
btn_enregistrer_financement.addEventListener('click', function() {
|
||||
const form = document.getElementById('form_financement');
|
||||
const formData = new FormData(form);
|
||||
fetch(form.action, {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
headers: {
|
||||
'X-CSRFToken': formData.get('csrfmiddlewaretoken')
|
||||
}
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
alert(data.message);
|
||||
window.location.reload();
|
||||
}else {
|
||||
alert(data.message);
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -1,64 +0,0 @@
|
||||
const $ = (element) => document.getElementById(element)
|
||||
const url_liste_projet = $("tableau-liste-projet").dataset.url;
|
||||
const tableau_liste_projet = new Tabulator("#tableau-liste-projet", {
|
||||
fitColumns: true,
|
||||
responsiveLayout : true,
|
||||
columns: [
|
||||
{title: "Projet", field: "nom_projet"},
|
||||
{title: "Source de financement", field: "source_financement"},
|
||||
{title: "Budget Total", field: "budget"},
|
||||
{title: "Budget RH", field: "budget_RH"},
|
||||
{title: "Avancement", field: "avancement", formatter: "progress"},
|
||||
{title: "Statut", field: "statut"},
|
||||
],
|
||||
ajaxURL: url_liste_projet
|
||||
})
|
||||
|
||||
const employes_affectes_projet = new Tabulator("#employes_affectes_projet", {
|
||||
columns: [
|
||||
{title: "Employé", field: "employe"},
|
||||
{title: "Pourcentage d'affectation", field: "pourcentage_affectation"},
|
||||
],
|
||||
placeholder: "Aucun employé affecté pour ce projet",
|
||||
})
|
||||
|
||||
const bailleurs_projet = new Tabulator("#bailleurs_projet", {
|
||||
columns: [
|
||||
{title: "Bailleur", field: "bailleur"},
|
||||
{title: "Pourcentage de financement", field: "pourcentage_financement"},
|
||||
],
|
||||
placeholder: "Aucun bailleur attribué pour ce projet",
|
||||
})
|
||||
|
||||
tableau_liste_projet.on("rowClick", function (row, rowData) {
|
||||
const data = rowData.getData();
|
||||
const modal = new bootstrap.Modal($("modalDetailProjet"));
|
||||
|
||||
$("detail_id_projet").value = data.id_projet;
|
||||
$("detail_nom_projet").value = data.nom_projet;
|
||||
$("detail_date_debut").value = data.date_debut;
|
||||
$("detail_date_fin").value = data.date_fin;
|
||||
$("detail_numero_convention").value = data.numero_convention;
|
||||
$("detail_type_projet").value = data.type_projet;
|
||||
Array.from($("detail_domaine_recherche").options).forEach(option => {
|
||||
if (data.domaine_recherche.includes(option.value)) {
|
||||
option.selected = true;
|
||||
} else {
|
||||
option.selected = false;
|
||||
}
|
||||
});
|
||||
$("detail_budget").value = data.budget;
|
||||
$("detail_budget_rh").value = data.budget_RH;
|
||||
$("detail_description").value = data.description;
|
||||
$("detail_statut").value = data.statut;
|
||||
|
||||
employes_affectes_projet.setData(`projet/liste-employes-par-projet/${$("detail_id_projet").value}`);
|
||||
bailleurs_projet.setData(`projet/bailleurs/${data.id_projet}/`);
|
||||
|
||||
modal.show();
|
||||
})
|
||||
|
||||
// $('detail-projet-form').addEventListener('submit', (e) => {
|
||||
// e.preventDefault();
|
||||
// new FormData($("detail-projet-form"));
|
||||
// })
|
||||
@@ -1,20 +0,0 @@
|
||||
const urlListeDocument = document.getElementById('listeDocuments').dataset.urllistedocument;
|
||||
|
||||
const table_liste_documents = new Tabulator(document.getElementById('listeDocuments'), {
|
||||
layout: "fitColumns",
|
||||
placeholder: "Aucun document trouvé",
|
||||
columns: [
|
||||
{ title: "Nom du Document", field: "nom_document" },
|
||||
{ title: "Numéro", field: "numero" },
|
||||
{ title: "Date de Validité", field: "date_validite", formatter: "datetime", formatterParams: {
|
||||
inputFormat: "yyyy-MM-dd",
|
||||
outputFormat: "dd/MM/yyyy"
|
||||
}
|
||||
},
|
||||
{ title: "Lien vers le Document", field: "lien_document", formatter:"link", formatterParams:{
|
||||
target:"_blank",
|
||||
}
|
||||
},
|
||||
],
|
||||
ajaxURL: urlListeDocument,
|
||||
});
|
||||
@@ -1,59 +0,0 @@
|
||||
const $ = (element) => document.getElementById(element)
|
||||
|
||||
const url_liste_activite = $("tableau-liste-activite").dataset.urllisteactivite
|
||||
const tableau_liste_activite = new Tabulator("#tableau-liste-activite", {
|
||||
columns: [
|
||||
{title: "Activité", field: "titre"},
|
||||
{title: "Date début", field: "date_debut"},
|
||||
{title: "Date fin", field: "date_fin"},
|
||||
{title: "Budget prévu", field: "budget_prevu"},
|
||||
{title: "Budget dépensé", field: "budget_depense"},
|
||||
{title: "Motif de changement de budget", field: "motif_changement_budget"},
|
||||
{title: "Statut", field: "statut"},
|
||||
],
|
||||
ajaxURL: url_liste_activite,
|
||||
})
|
||||
tableau_liste_activite.on("rowClick", function (row, rowData) {
|
||||
const data = rowData.getData();
|
||||
$("idDetailActivite").value = data.id;
|
||||
$("titreDetailActivite").value = data.titre;
|
||||
$("descriptionDetailActivite").value = data.description;
|
||||
$("date_debutDetailActivite").value = data.date_debut;
|
||||
$("date_finDetailActivite").value = data.date_fin;
|
||||
$("statutDetailActivite").value = data.statut;
|
||||
$("budget_prevuDetailActivite").value = data.budget_prevu;
|
||||
$("besoin_ressources_materiellesDetailActivite").value = data.besoin_ressource_materielle;
|
||||
const modal = new bootstrap.Modal($("modalDetailActivite"));
|
||||
modal.show();
|
||||
|
||||
fetch(`liste-des-livrables/${data.id}/`)
|
||||
.then(response => response.json())
|
||||
.then(livrables => {
|
||||
tableau_liste_livrable.setData(livrables);
|
||||
})
|
||||
})
|
||||
|
||||
const tableau_liste_livrable = new Tabulator("#listeLivrables", {
|
||||
columns: [
|
||||
{title: "Livrable", field: "titre"},
|
||||
{title: "Lien du livrable", field: "lien", formatter: "link", formatterParams: {blank: true}},
|
||||
],
|
||||
placeholder: "Aucun livrable trouvé",
|
||||
})
|
||||
|
||||
$("btnMiseAJourDepense").addEventListener("click", function() {
|
||||
const modal = new bootstrap.Modal($("modalDepenseActivite"));
|
||||
bootstrap.Modal.getOrCreateInstance($("modalDetailActivite")).hide();
|
||||
const idActivite = $("idDetailActivite").value;
|
||||
const budgetPrevu = $("budget_prevuDetailActivite").value;
|
||||
|
||||
$("id_activite_depense").value = idActivite;
|
||||
$("budget_prevu").value = budgetPrevu;
|
||||
modal.show();
|
||||
})
|
||||
|
||||
$("btnAnnulerActivite").addEventListener("click", function(event) {
|
||||
new bootstrap.Modal($("modalAnnulerActivite")).show();
|
||||
$("id_activite_annulation").value = $("idDetailActivite").value;
|
||||
bootstrap.Modal.getOrCreateInstance($("modalDetailActivite")).hide();
|
||||
})
|
||||
@@ -1,37 +0,0 @@
|
||||
{% extends "BASE.html" %}
|
||||
{% load static %}
|
||||
{% block 'titre_page' %} Gestion des projets {% endblock %}
|
||||
{% block 'contenu' %}
|
||||
<button class="btn btn-primary mb-3">
|
||||
<i class="bi bi-caret-left-fill"></i> Retour
|
||||
</button>
|
||||
|
||||
{% if messages %}
|
||||
{% for message in messages %}
|
||||
<div class="alert alert-{% if message.tags == "error" %}danger{% else %}success{% endif %} alert-dismissible fade show" role="alert">
|
||||
{{ message }}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
<div class="row d-flex justify-content-center">
|
||||
<div class="col-8 card bordered rounded py-4 px-2 ">
|
||||
<h5>Ajout du financement au projet (Nom du projet ici)</h5>
|
||||
<hr>
|
||||
<form method="POST" action="{% url 'gestion_projet:creation-projet' %}">
|
||||
{% csrf_token %}
|
||||
{{ formulaire_creation_projet.as_p }}
|
||||
<div class="d-flex justify-content-end">
|
||||
<button type="submit" class="btn btn-danger">Annuler</button>
|
||||
<a href="{% url 'gestion_projet:ajouter_financement' %}" class="btn btn-primary ms-2">Enregistrer et ajouter un financement</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block 'modal' %}
|
||||
{% include "gestion_projet/parts/modalAjoutProjet.html" %}
|
||||
{% endblock %}
|
||||
{% block 'js' %}
|
||||
<script type="text/javascript" src="{% static 'gestion_projet/js/index.js' %}"></script>
|
||||
{% endblock %}
|
||||
@@ -1,32 +0,0 @@
|
||||
{% extends "BASE.html" %}
|
||||
{% load static %}
|
||||
{% block 'titre_page' %} Gestion des projets {% endblock %}
|
||||
{% block 'contenu' %}
|
||||
{% if messages %}
|
||||
{% for message in messages %}
|
||||
<div class="alert alert-{{ message.tags }} alert-dismissible fade show" role="alert">
|
||||
{{ message }}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% comment %} <h3>Enregistrement d'un nouveau projet</h3> {% endcomment %}
|
||||
<div class="row d-flex justify-content-center">
|
||||
<div class="col-8 card bordered rounded py-4 px-2 ">
|
||||
<h5>Enregistrement d'un nouveau projet</h5>
|
||||
<hr>
|
||||
<form method="POST" action="{% url 'gestion_projet:creation-projet' %}">
|
||||
{% csrf_token %}
|
||||
{{ formulaire_creation_projet.as_p }}
|
||||
<div class="d-flex justify-content-end">
|
||||
<button type="submit" class="btn btn-danger">Annuler</button>
|
||||
<button class="btn btn-primary ms-2">Enregistrer</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block 'modal' %}
|
||||
{% endblock %}
|
||||
{% block 'js' %}
|
||||
{% endblock %}
|
||||
@@ -1,61 +0,0 @@
|
||||
{% extends "BASE.html" %}
|
||||
{% load static %}
|
||||
{% load tags_personnaliser %}
|
||||
{% block 'titre_page' %} Gestion des projets {% endblock %}
|
||||
{% block 'contenu' %}
|
||||
<h3>Gestion des projets</h3>
|
||||
{% if messages %}
|
||||
{% for message in messages %}
|
||||
<div class="alert alert-{% if message.tags == "error" %}danger{% else %}success{% endif %} alert-dismissible fade show" role="alert">
|
||||
{{ message }}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
<div class="row">
|
||||
<div class="col text-white bg-success d-flex flex-column justify-content-center align-items-center border rounded p-4">
|
||||
<span class="fs-5">Projets en cours</span>
|
||||
<h3>{{projet_en_cours}}</h3>
|
||||
</div>
|
||||
<div class="col text-white bg-success d-flex flex-column justify-content-center align-items-center border rounded p-4 mx-2">
|
||||
<span class="fs-5">Budget Total (GNF)</span>
|
||||
<h3>{{budget_total}}</h3>
|
||||
</div>
|
||||
<div class="col text-white bg-success d-flex flex-column justify-content-center align-items-center border rounded p-4">
|
||||
<span class="fs-5">Personnel sous projet</span>
|
||||
<h3>{{nombre_personnel}}</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-4">
|
||||
<div class="col d-flex justify-content-between align-items-center mb-3">
|
||||
<h5 class="mb-4" >La liste des projets </h5>
|
||||
{% if user|has_group:"ressource_humaine" %}
|
||||
<div>
|
||||
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#modalProjet">
|
||||
<i class="bi bi-plus-circle"></i> Ajouter un projet
|
||||
</button>
|
||||
<button class="btn btn-info" data-bs-toggle="modal" data-bs-target="#modalBailleur">
|
||||
<i class="bi bi-person"></i> Ajouter un bailleur
|
||||
</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div id="tableau-liste-projet" data-url="{% url 'gestion_projet:liste-projet' %}"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block 'modal' %}
|
||||
{% include "gestion_projet/parts/modalAjoutProjet.html" %}
|
||||
{% include "gestion_projet/parts/modalFinancement.html" %}
|
||||
{% include "gestion_projet/parts/creation_bailleur.html" %}
|
||||
{% include "gestion_projet/parts/modalDetailProjet.html" %}
|
||||
{% endblock %}
|
||||
{% block 'js' %}
|
||||
<script type="text/javascript" src="{% static 'gestion_projet/js/index.js' %}"></script>
|
||||
<script type="text/javascript" src="{% static 'gestion_projet/js/creation_projet.js' %}"></script>
|
||||
<script type="text/javascript" src="{% static 'gestion_projet/js/enregistrement_bailleur.js' %}"></script>
|
||||
<script type="text/javascript" src="{% static 'gestion_projet/js/enregistrement_financement.js' %}"></script>
|
||||
{% endblock %}
|
||||
@@ -1,16 +0,0 @@
|
||||
<div class="modal fade" id="modalListeDocument" tabindex="-1" aria-labelledby="modalListeDocumentLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title fw-bold" id="modalListeDocumentLabel">Liste des Documents</h5>
|
||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div class="modal-body p-4">
|
||||
<div id="listeDocuments" data-urllistedocument="{% url 'gestion_projet:liste-documents-projet' %}"></div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Fermer</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,20 +0,0 @@
|
||||
<div class="modal fade" id="modalAjoutActivite" tabindex="-1" aria-labelledby="modalAjoutActiviteLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="modalAjoutActiviteLabel">Ajouter une Activité</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<form method="POST" action="{% url 'gestion_projet:ajouter-activite' %}">
|
||||
{% csrf_token %}
|
||||
<div class="modal-body">
|
||||
{{ form_ajout_activite.as_p }}
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Annuler</button>
|
||||
<button type="submit" class="btn btn-primary">Ajouter</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,20 +0,0 @@
|
||||
<div class="modal fade" id="modalAjoutDocument" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Ajouter un Document</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<form method="POST" action="{% url 'gestion_projet:ajouter-document' %}" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
<div class="modal-body">
|
||||
{{ form_ajout_document.as_p }}
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Annuler</button>
|
||||
<button type="submit" class="btn btn-primary">Ajouter</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,20 +0,0 @@
|
||||
<div class="modal fade" id="modalAjouterLivrable" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Ajouter un livrable - (Nom du livrable)</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form method="post" action="{% url 'gestion_projet:ajouter-livrable' %}" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
{{ form_ajout_livrable.as_p }}
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Annuler</button>
|
||||
<button type="submit" class="btn btn-success">Enregistrer</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,21 +0,0 @@
|
||||
<!-- Modale Projet -->
|
||||
<div class="modal fade" id="modalProjet" tabindex="-1" aria-labelledby="modalProjetLabel" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-orange-dark">
|
||||
<h5 class="modal-title" id="modalProjetLabel">Ajouter un projet</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fermer"></button>
|
||||
</div>
|
||||
<div class="modal-body p-3">
|
||||
<form method="POST" id="formCreationProjet" action="{% url 'gestion_projet:creation-projet' %}">
|
||||
{% csrf_token %}
|
||||
{{ formulaire_creation_projet.as_p }}
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" id="btnEnregistrerProjet" class="btn btn-success">Enregistrer</button>
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Fermer</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,26 +0,0 @@
|
||||
<div class="modal fade" id="modalAnnulerActivite" tabindex="-1" aria-labelledby="modalAnnulerActiviteLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title fw-bold" id="modalAnnulerActiviteLabel">Annuler l'activité</h5>
|
||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div class="modal-body p-4">
|
||||
<form method="POST" action="{% url 'gestion_projet:annuler-activite' %}">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="id_activite" id="id_activite_annulation">
|
||||
<div class="mb-3">
|
||||
<label for="motif_annulation" class="form-label">Motif d'annulation</label>
|
||||
<textarea class="form-control" name="motif_annulation" id="motif_annulation" rows="4" required></textarea>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Annuler</button>
|
||||
<button type="submit" class="btn btn-danger">
|
||||
<i class="bi bi-x-circle"></i> Confirmer l'annulation
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,58 +0,0 @@
|
||||
<div class="modal fade" id="modalDetailActivite" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header bg-orange-dark">
|
||||
<h5 class="modal-title">Détails de l'activité</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row g-3">
|
||||
<div class="">
|
||||
<input type="hidden" id="idDetailActivite">
|
||||
<div class="form-group mb-2">
|
||||
<label>Titre :</label>
|
||||
<input type="text" class="form-control" id="titreDetailActivite">
|
||||
</div>
|
||||
<div class="form-group mb-2">
|
||||
<label>Description :</label>
|
||||
<textarea class="form-control" id="descriptionDetailActivite"></textarea>
|
||||
</div>
|
||||
<div class="form-group mb-2">
|
||||
<label>Date de début :</label>
|
||||
<input type="date" class="form-control" id="date_debutDetailActivite">
|
||||
</div>
|
||||
<div class="form-group mb-2">
|
||||
<label>Date de fin :</label>
|
||||
<input type="date" class="form-control" id="date_finDetailActivite">
|
||||
</div>
|
||||
<div class="form-group mb-2">
|
||||
<label>Statut:</label>
|
||||
<input type="text" class="form-control" id="statutDetailActivite">
|
||||
</div>
|
||||
<div class="form-group mb-2">
|
||||
<label>Budget prévu :</label>
|
||||
<input type="number" class="form-control" id="budget_prevuDetailActivite">
|
||||
</div>
|
||||
<div class="form-group mb-2">
|
||||
<label>Besoin de ressources matérielles:</label>
|
||||
<textarea class="form-control" id="besoin_ressources_materiellesDetailActivite"></textarea>
|
||||
</div>
|
||||
<p><strong>Liste des livrables :</strong></p>
|
||||
<div id="listeLivrables"></div>
|
||||
<button class="btn btn-danger d-block mx-auto" id="btnAnnulerActivite">
|
||||
Annuler cette activité
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-success" id="btnMiseAJourDepense">
|
||||
<i class="bi bi-plus-circle"></i> Mise à jour du budget
|
||||
</button>
|
||||
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#modalAjouterLivrable">
|
||||
<i class="bi bi-plus-circle"></i> Ajouter un livrable
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,115 +0,0 @@
|
||||
{% load tags_personnaliser %}
|
||||
<div class="modal fade" id="modalDetailProjet{{ activite.id }}" tabindex="-1">
|
||||
<div class="modal-dialog ">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header ">
|
||||
<h5 class="modal-title">Détails du projet </h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row g-3">
|
||||
<div class="col" id="detail-projet-container">
|
||||
<form method='post' action="{% url 'gestion_projet:mises-a-jour-projet' %}" id="detail-projet-form">
|
||||
{% csrf_token %}
|
||||
<div class="form-group mb-2">
|
||||
<label>Id projet:</label>
|
||||
<input type="text" class="form-control" id="detail_id_projet" name='id_projet' readonly>
|
||||
</div>
|
||||
<div class="form-group mb-2">
|
||||
<label> Nom projet :</label>
|
||||
<input type="text" class="form-control" id="detail_nom_projet" name='nom_projet'>
|
||||
</div>
|
||||
<div class="form-group mb-2">
|
||||
<label>Numero de convention:</label>
|
||||
<input type="text" class="form-control" id="detail_numero_convention" name="numero_convention">
|
||||
</div>
|
||||
<div class="form-group mb-2">
|
||||
<label>Date de début :</label>
|
||||
<input type="date" class="form-control" id="detail_date_debut" name='date_debut'>
|
||||
</div>
|
||||
<div class="form-group mb-2">
|
||||
<label>Date de fin :</label>
|
||||
<input type="date" class="form-control" id="detail_date_fin" name='date_fin'>
|
||||
</div>
|
||||
<div class="form-group mb-2">
|
||||
<label> Type de projet </label>
|
||||
<select class="form-select" id="detail_type_projet" name='type_projet'>
|
||||
<option value="laboratoire">Laboratoire</option>
|
||||
<option value="épidémiologie">Épidémiologie</option>
|
||||
<option value="sciences sociales">Sciences sociales</option>
|
||||
<option value="cliniques">Cliniques</option>
|
||||
<option value="autre">Autre</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group mb-2">
|
||||
<label> Domaine de recherche </label>
|
||||
<select class="form-select" multiple id="detail_domaine_recherche" name="domaine_recherche">
|
||||
<option value="sciences_sociales">Sciences sociales</option>
|
||||
<option value="naturelles">Naturelles</option>
|
||||
<option value="humaines">Humaines</option>
|
||||
<option value="veterinaires">Vétérinaires</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group mb-2">
|
||||
<label>Budget :</label>
|
||||
<input type="number" class="form-control" id="detail_budget" name='budget'>
|
||||
</div>
|
||||
<div class="form-group mb-2">
|
||||
<label>Budget RH:</label>
|
||||
<input type="number" class="form-control" id="detail_budget_rh" name='budget_RH'>
|
||||
</div>
|
||||
<div class="form-group mb-2">
|
||||
<label>Description :</label>
|
||||
<textarea class="form-control" id="detail_description" name='description'></textarea>
|
||||
</div>
|
||||
<div class="form-check-group mb-2">
|
||||
<label class="form-check-label">Statut :</label>
|
||||
<input type="text" class="form-control" id="detail_statut" readonly>
|
||||
</div>
|
||||
<button type='submit' class="btn btn-warning">
|
||||
<i class="bi bi-pencil"></i> Modifier Projet
|
||||
</button>
|
||||
</form>
|
||||
<hr class="my-4">
|
||||
<div class="accordion" id="accordionDetailProjet">
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header" id="employesAffectes">
|
||||
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
|
||||
Employés Affectés
|
||||
</button>
|
||||
</h2>
|
||||
<div id="collapseOne" class="accordion-collapse collapse show" aria-labelledby="employesAffectes" data-bs-parent="#accordionDetailProjet">
|
||||
<div class="accordion-body">
|
||||
<div id="employes_affectes_projet"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header" id="bailleursProjet">
|
||||
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
|
||||
Liste des bailleurs
|
||||
</button>
|
||||
</h2>
|
||||
<div id="collapseTwo" class="accordion-collapse collapse" aria-labelledby="bailleursProjet" data-bs-parent="#accordionDetailProjet">
|
||||
<div class="accordion-body">
|
||||
<div id="bailleurs_projet"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
{% if user|has_group:"ressource_humaine" %}
|
||||
<button class="btn btn-success" data-bs-toggle="modal" data-bs-target="#modal_ajout_financement">
|
||||
<i class="bi bi-plus-circle"></i> Ajouter un financement
|
||||
</button>
|
||||
{% endif %}
|
||||
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">
|
||||
<i class="bi bi-x-circle"></i> Fermer
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,20 +0,0 @@
|
||||
<div class="modal fade" id="modal_ajout_financement" tabindex="-1" aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">Ajout de financement</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fermer"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form method="POST" id="form_financement" action="{% url 'gestion_projet:ajouter_financement' %}">
|
||||
{% csrf_token %}
|
||||
{{ form_ajout_financement.as_p }}
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" id="btn_enregistrer_financement" class="btn btn-success">Enregistrer</button>
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Annuler</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,36 +0,0 @@
|
||||
<div class="modal fade" id="modalDepenseActivite" tabindex="-1" aria-labelledby="modalDepenseActiviteLabel" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="modalDepenseActiviteLabel">
|
||||
<i class="bi bi-cash-stack me-2"></i> Mise à jour des dépenses
|
||||
</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form method="POST" action="{% url 'gestion_projet:mettre-a-jour-depense' %}">
|
||||
{% csrf_token %}
|
||||
<input type="hidden" name="id_activite" id="id_activite_depense">
|
||||
<div class="mb-2">
|
||||
<label class="form-label">Budget prévu (GNF)</label>
|
||||
<input type="number" class="form-control" name="budget_prevu" id="budget_prevu" value="" disabled>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<label for="budget_depense" class="form-label">Montant dépensé (GNF)</label>
|
||||
<input type="number" name="budget_depense" id="budget_depense" class="form-control" required>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<label class="form-label">Motif de différence</label>
|
||||
<textarea class="form-control" name="motif" rows="3"></textarea>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Annuler</button>
|
||||
<button type="submit" class="btn btn-success">
|
||||
<i class="bi bi-save"></i> Enregistrer
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,64 +0,0 @@
|
||||
{% extends "BASE.html" %}
|
||||
{% load static %}
|
||||
{% block 'titre_page' %} Gestion des projets {% endblock %}
|
||||
{% block 'contenu' %}
|
||||
{% if messages %}
|
||||
{% for message in messages %}
|
||||
<div class="alert alert-{% if message.tags == "error" %}danger{% else %}success{% endif %} alert-dismissible fade show" role="alert">
|
||||
{{ message }}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
<h5 class="mb-4 fw-bold text-uppercase text-orange-dark">
|
||||
<i class="bi bi-kanban-fill me-2"></i> Suivi des Activités ({{ nom_projet }} )
|
||||
</h5>
|
||||
<div class="row d-flex justify-content-center mb-4">
|
||||
<div class="col text-white bg-success d-flex flex-column justify-content-center align-items-center border rounded p-4">
|
||||
<span class="fs-5">Budget Total (GNF)</span>
|
||||
<h3>{{ budget_total }}</h3>
|
||||
</div>
|
||||
<div class="col text-white bg-info d-flex flex-column justify-content-center align-items-center border rounded mx-3 p-4">
|
||||
<span class="fs-5">Budget RH (GNF)</span>
|
||||
<h3>{{ budget_RH }}</h3>
|
||||
</div>
|
||||
<div class="col text-white bg-warning d-flex flex-column justify-content-center align-items-center border rounded p-4">
|
||||
<span class="fs-5">Budget Dépensé (GNF)</span>
|
||||
<h3>{{budget_depense}}</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="mt-4 d-flex justify-content-between mb-3">
|
||||
<h5><i class="bi bi-people"></i> La liste des Activités</h5>
|
||||
<div>
|
||||
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#modalAjoutActivite">
|
||||
<i class="bi bi-plus-circle me-2"></i> Ajouter une Activité
|
||||
</button>
|
||||
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#modalAjoutDocument">
|
||||
<i class="bi bi-plus-circle me-2"></i> Ajouter un document
|
||||
</button>
|
||||
<button class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#modalListeDocument">
|
||||
Documents du projet
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="table-responsive">
|
||||
<div id="tableau-liste-activite" data-urllisteactivite="{% url 'gestion_projet:liste-activites-projet' %}"></div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block 'modal' %}
|
||||
{% include "gestion_projet/parts/modalAjoutActivite.html" %}
|
||||
{% include "gestion_projet/parts/modalDetailActivite.html" %}
|
||||
{% include "gestion_projet/parts/modalAjoutDocument.html" %}
|
||||
{% include "gestion_projet/parts/modalMiseAJourDepense.html" %}
|
||||
{% include "gestion_projet/parts/modalAjoutLivrable.html" %}
|
||||
{% include "gestion_projet/parts/liste_document_projet.html" %}
|
||||
{% include "gestion_projet/parts/modalAnnulerActivite.html" %}
|
||||
{% endblock %}
|
||||
{% block 'js' %}
|
||||
<script type="text/javascript" src="{% static 'gestion_projet/js/suivi-activites.js' %}"></script>
|
||||
<script type="text/javascript" src="{% static 'gestion_projet/js/liste_documents_projet.js' %}"></script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
Reference in New Issue
Block a user