Compare commits
5 Commits
1a21998c39
...
feature/en
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
29a42ee6be | ||
| 904954c735 | |||
| 99e764ab4d | |||
| 0eb745d5f3 | |||
| 097648c03e |
2
Jenkinsfile
vendored
2
Jenkinsfile
vendored
@@ -16,7 +16,7 @@ pipeline
|
|||||||
{
|
{
|
||||||
steps
|
steps
|
||||||
{
|
{
|
||||||
sh 'echo "Debut du pipeline"'
|
sh 'echo "Debut du pipeline test"'
|
||||||
cleanWs()
|
cleanWs()
|
||||||
checkout scm
|
checkout scm
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,9 @@
|
|||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" href="{{ SGL_LIEN }}">SGL</a>
|
<a class="nav-link" href="{{ SGL_LIEN }}">SGL</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link" href="#">Laboratoire</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ try:
|
|||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
EMAIL_EQUIPE_INFORMATIQUE = ["support@cerfig.org"]
|
||||||
|
|
||||||
def solde_conge(employe):
|
def solde_conge(employe):
|
||||||
"""Fonction de calcul du solde de congé restant l'employé"""
|
"""Fonction de calcul du solde de congé restant l'employé"""
|
||||||
contrat = Contrat.objects.filter(employe=employe, statut='actif').order_by('-date_debut').first()
|
contrat = Contrat.objects.filter(employe=employe, statut='actif').order_by('-date_debut').first()
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -12,7 +12,7 @@
|
|||||||
</div>
|
</div>
|
||||||
{% if messages %}
|
{% if messages %}
|
||||||
{% for message in messages %}
|
{% for message in messages %}
|
||||||
<div class="alert alert-{% if message.tags == 'error' %}danger{% else %}success{% endif %} alert-dismissible fade show" role="alert">
|
<div class="alert alert-{% if message.tags == 'error' %}danger{% else %}success{% endif %} alert-dismissible fade show mt-2" role="alert">
|
||||||
{{ message }}
|
{{ message }}
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<form method="POST" action="{% url 'gestion_employe:modifier-mot-passe' %}">
|
<form method="POST" action="{% url 'gestion_employe:modifier-mot-passe' %}" id="formulaire_mot_de_passe">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<div class="form-group mb-2">
|
<div class="form-group mb-2">
|
||||||
<label>Votre mot de passe actuel :</label>
|
<label>Votre mot de passe actuel :</label>
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
import json
|
import json
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
|
import requests
|
||||||
from dateutil.relativedelta import relativedelta
|
from dateutil.relativedelta import relativedelta
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.contrib.auth import authenticate
|
from django.contrib.auth import logout
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
|
from django.contrib.auth.password_validation import validate_password
|
||||||
|
from django.core.exceptions import ValidationError
|
||||||
from django.db.models import Sum
|
from django.db.models import Sum
|
||||||
from django.forms.models import model_to_dict
|
from django.forms.models import model_to_dict
|
||||||
from django.http import JsonResponse
|
from django.http import JsonResponse
|
||||||
@@ -176,25 +179,6 @@ def mon_profil(request):
|
|||||||
"contrat_nb_jours_restant": max(0, contrats.nombre_jours_restant if contrats else 0)
|
"contrat_nb_jours_restant": max(0, contrats.nombre_jours_restant if contrats else 0)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@login_required
|
|
||||||
def modifier_mot_passe(request):
|
|
||||||
"""Vue pour permettre à un utilisateur de modifier son mot de passe et ses informations de profil"""
|
|
||||||
user = User.objects.get(username=request.user)
|
|
||||||
if request.method == "POST":
|
|
||||||
ancien_mdp = request.POST["ancien-mdp"]
|
|
||||||
nouveau_mdp = request.POST["nouveau-mdp"]
|
|
||||||
confirmation_mdp = request.POST["confirmation-mdp"]
|
|
||||||
|
|
||||||
if authenticate(request, username=request.user, password=ancien_mdp) is None:
|
|
||||||
messages.error(request, "Ancien mot de passe incorrect.")
|
|
||||||
elif nouveau_mdp != confirmation_mdp:
|
|
||||||
messages.error(request, "Les deux nouveaux ne correspondent pas.")
|
|
||||||
else:
|
|
||||||
user.set_password(nouveau_mdp)
|
|
||||||
user.save()
|
|
||||||
messages.success(request, "Mot de passe modifié avec succès.")
|
|
||||||
|
|
||||||
return redirect("gestion_employe:mon-profil")
|
|
||||||
|
|
||||||
def modifier_employer(request):
|
def modifier_employer(request):
|
||||||
"""Vue pour permettre à un utilisateur de modifier les informations d'un employé"""
|
"""Vue pour permettre à un utilisateur de modifier les informations d'un employé"""
|
||||||
@@ -302,7 +286,6 @@ def creation_contrat(request):
|
|||||||
'contrat_form': form
|
'contrat_form': form
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def contrats_employe(request, employe_id):
|
def contrats_employe(request, employe_id):
|
||||||
|
|
||||||
@@ -341,6 +324,7 @@ def contrats_employe(request, employe_id):
|
|||||||
"employe": employe.user.get_full_name(),
|
"employe": employe.user.get_full_name(),
|
||||||
"contrats": data
|
"contrats": data
|
||||||
})
|
})
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def enregistrer_detail_employe(request):
|
def enregistrer_detail_employe(request):
|
||||||
"""Vue pour permettre à un utilisateur de modifier les détails d'un employé via une requête AJAX"""
|
"""Vue pour permettre à un utilisateur de modifier les détails d'un employé via une requête AJAX"""
|
||||||
@@ -379,7 +363,6 @@ def enregistrer_detail_employe(request):
|
|||||||
else:
|
else:
|
||||||
return JsonResponse({"message": "Méthode non autorisée."}, status=405)
|
return JsonResponse({"message": "Méthode non autorisée."}, status=405)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def liste_employe(request):
|
def liste_employe(request):
|
||||||
""" Vue pour retourner la liste de tous les employés """
|
""" Vue pour retourner la liste de tous les employés """
|
||||||
@@ -509,3 +492,47 @@ def supprimer_formation(request, id_formation):
|
|||||||
formation.delete()
|
formation.delete()
|
||||||
messages.success(request, "Formation supprimée ")
|
messages.success(request, "Formation supprimée ")
|
||||||
return redirect("mes_formations")
|
return redirect("mes_formations")
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def modifier_mot_passe(request):
|
||||||
|
"""Vue pour permettre à un employé de modifier son mot de passe"""
|
||||||
|
if request.method == "POST":
|
||||||
|
username = request.user.username
|
||||||
|
ancien_mdp = request.POST.get("ancien-mdp")
|
||||||
|
nouveau_mdp = request.POST.get("nouveau-mdp")
|
||||||
|
confirmation_mdp = request.POST.get("confirmation-mdp")
|
||||||
|
|
||||||
|
try:
|
||||||
|
validate_password(nouveau_mdp, user=request.user)
|
||||||
|
except ValidationError as e:
|
||||||
|
messages.error(request, f"Erreur : {' '.join(e.messages)}")
|
||||||
|
return redirect("gestion_employe:mon-profil")
|
||||||
|
|
||||||
|
donnees = {
|
||||||
|
"username": username,
|
||||||
|
"ancien_mdp": ancien_mdp,
|
||||||
|
"nouveau_mdp": nouveau_mdp,
|
||||||
|
"confirmation_mdp": confirmation_mdp
|
||||||
|
}
|
||||||
|
|
||||||
|
headers = {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"Accept": "application/json",
|
||||||
|
}
|
||||||
|
|
||||||
|
response = requests.post(
|
||||||
|
"http://localhost:8000/modifier-mot-de-passe/",
|
||||||
|
json=donnees,
|
||||||
|
headers=headers
|
||||||
|
)
|
||||||
|
|
||||||
|
data = response.json()
|
||||||
|
cle = next(iter(data.keys()))
|
||||||
|
valeur = next(iter(data.values()))
|
||||||
|
|
||||||
|
if cle == "success":
|
||||||
|
messages.success(request, valeur)
|
||||||
|
else:
|
||||||
|
messages.error(request, valeur)
|
||||||
|
|
||||||
|
return redirect("gestion_employe:mon-profil")
|
||||||
|
|||||||
Binary file not shown.
@@ -26,7 +26,7 @@ const calendrier = Schedule(document.getElementById('planning-reservation'), {
|
|||||||
$("employe").value=data.employe;
|
$("employe").value=data.employe;
|
||||||
$("salle").value=data.salle;
|
$("salle").value=data.salle;
|
||||||
$("statut-reservation").innerHTML=data.statut;
|
$("statut-reservation").innerHTML=data.statut;
|
||||||
$("date_debut").value=data.date_debut;
|
$("date_evenement").value=data.date_evenement;
|
||||||
$("heure_debut").value=data.heure_debut;
|
$("heure_debut").value=data.heure_debut;
|
||||||
$("heure_fin").value=data.heure_fin;
|
$("heure_fin").value=data.heure_fin;
|
||||||
$("motif_reservation").value=data.motif_reservation;
|
$("motif_reservation").value=data.motif_reservation;
|
||||||
@@ -171,7 +171,7 @@ const tableau_reservation_attente = new Tabulator("#tableau-reservation-attente"
|
|||||||
columns: [
|
columns: [
|
||||||
{title: "Employé", field: "employe"},
|
{title: "Employé", field: "employe"},
|
||||||
{title: "Salle", field: "salle"},
|
{title: "Salle", field: "salle"},
|
||||||
{title: "Date de l'evenement", field: "date_debut"},
|
{title: "Date de l'evenement", field: "date_evenement"},
|
||||||
{title: "Heure de début", field: "heure_debut"},
|
{title: "Heure de début", field: "heure_debut"},
|
||||||
{title: "Heure de fin", field: "heure_fin"},
|
{title: "Heure de fin", field: "heure_fin"},
|
||||||
{title: "Motif de reservation", field: "motif_reservation"},
|
{title: "Motif de reservation", field: "motif_reservation"},
|
||||||
@@ -183,6 +183,8 @@ const tableau_reservation_attente = new Tabulator("#tableau-reservation-attente"
|
|||||||
tableau_reservation_attente.on("rowClick", (row, rowData) => {
|
tableau_reservation_attente.on("rowClick", (row, rowData) => {
|
||||||
const data = rowData.getData();
|
const data = rowData.getData();
|
||||||
|
|
||||||
|
console.log(data);
|
||||||
|
|
||||||
if(data.besoin_zoom === false){
|
if(data.besoin_zoom === false){
|
||||||
$("lien_zoom_container").className = 'd-none';
|
$("lien_zoom_container").className = 'd-none';
|
||||||
}
|
}
|
||||||
@@ -196,8 +198,7 @@ tableau_reservation_attente.on("rowClick", (row, rowData) => {
|
|||||||
$("employe").value=data.employe;
|
$("employe").value=data.employe;
|
||||||
$("salle").value=data.salle;
|
$("salle").value=data.salle;
|
||||||
$("statut-reservation").innerHTML=data.statut;
|
$("statut-reservation").innerHTML=data.statut;
|
||||||
$("date_debut").value = data.date_debut;
|
$("date_evenement").value = data.date_evenement;
|
||||||
$("date_fin").value = data.date_fin;
|
|
||||||
$("heure_debut").value=data.heure_debut;
|
$("heure_debut").value=data.heure_debut;
|
||||||
$("heure_fin").value=data.heure_fin;
|
$("heure_fin").value=data.heure_fin;
|
||||||
$("motif_reservation").value=data.motif_reservation;
|
$("motif_reservation").value=data.motif_reservation;
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col py-2 px-4">
|
<div class="col py-2 px-4">
|
||||||
<h1 class="text-center">Reservation de salle</h1>
|
<h1 class="text-center">Réservation de salle</h1>
|
||||||
<hr>
|
<hr>
|
||||||
<div class="row d-flex justify-content-around">
|
<div class="row d-flex justify-content-around">
|
||||||
<div class="form-group col-5 me-2">
|
<div class="form-group col-5 me-2">
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="row mt-2">
|
<div class="row mt-2">
|
||||||
<div class="col d-flex justify-content-center">
|
<div class="col d-flex justify-content-center">
|
||||||
<button class="btn btn-lg btn-primary me-2" data-bs-toggle="modal" data-bs-target="#modalReservation">Nouvelle reservation</button>
|
<button class="btn btn-lg btn-primary me-2" data-bs-toggle="modal" data-bs-target="#modalReservation">Nouvelle réservation</button>
|
||||||
<button type="button" class="btn btn-warning" data-bs-toggle="modal" data-bs-target="#modalReservationAttente">
|
<button type="button" class="btn btn-warning" data-bs-toggle="modal" data-bs-target="#modalReservationAttente">
|
||||||
Validation en attente <span class="badge badge-light">{{ nb_reservation_attente }}</span>
|
Validation en attente <span class="badge badge-light">{{ nb_reservation_attente }}</span>
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h1 class="modal-title fs-5" id="modalReservationLabel">
|
<h1 class="modal-title fs-5" id="modalReservationLabel">
|
||||||
Nouvelle reservation
|
Nouvelle réservation
|
||||||
</h1>
|
</h1>
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h1 class="modal-title fs-5" id="modalDetailReservationLabel">
|
<h1 class="modal-title fs-5" id="modalDetailReservationLabel">
|
||||||
Détails de la reservation (<span id='statut-reservation'></span>)
|
Détails de la réservation (<span id='statut-reservation'></span>)
|
||||||
</h1>
|
</h1>
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
</div>
|
</div>
|
||||||
@@ -22,12 +22,8 @@
|
|||||||
<input class="form-control" id="salle" readonly>
|
<input class="form-control" id="salle" readonly>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group mb-2">
|
<div class="form-group mb-2">
|
||||||
<label>Date de debut :</label>
|
<label>Date de l'évènement :</label>
|
||||||
<input type='date' class="form-control" id="date_debut" readonly >
|
<input type='date' class="form-control" id="date_evenement" readonly >
|
||||||
</div>
|
|
||||||
<div class="form-group mb-2">
|
|
||||||
<label>Date de fin :</label>
|
|
||||||
<input type='date' class="form-control" id="date_fin" readonly >
|
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group mb-2">
|
<div class="form-group mb-2">
|
||||||
<label>Heure de début :</label>
|
<label>Heure de début :</label>
|
||||||
@@ -38,7 +34,7 @@
|
|||||||
<input type='time' class="form-control" id="heure_fin" readonly >
|
<input type='time' class="form-control" id="heure_fin" readonly >
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group mb-2">
|
<div class="form-group mb-2">
|
||||||
<label>Motif de la reservation :</label>
|
<label>Motif de la réservation :</label>
|
||||||
<textarea class="form-control" id="motif_reservation" readonly ></textarea>
|
<textarea class="form-control" id="motif_reservation" readonly ></textarea>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-check mb-2">
|
<div class="form-check mb-2">
|
||||||
@@ -53,6 +49,7 @@
|
|||||||
<label class="form-check-label">Besoin d'un ordinateur {{ reservation.statut }}</label>
|
<label class="form-check-label">Besoin d'un ordinateur {{ reservation.statut }}</label>
|
||||||
<input type="checkbox" class="form-check-input" id="besoin_ordinateur" readonly >
|
<input type="checkbox" class="form-check-input" id="besoin_ordinateur" readonly >
|
||||||
</div>
|
</div>
|
||||||
|
<hr />
|
||||||
<div class='d-flex justify-content-around mt-2'>
|
<div class='d-flex justify-content-around mt-2'>
|
||||||
{% if appartient_au_departement_informatique %}
|
{% if appartient_au_departement_informatique %}
|
||||||
<button class="btn btn-primary" id="ajoutZoom">Ajout du lien zoom</button>
|
<button class="btn btn-primary" id="ajoutZoom">Ajout du lien zoom</button>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h1 class="modal-title fs-5" id="modalReservationAttenteLabel">
|
<h1 class="modal-title fs-5" id="modalReservationAttenteLabel">
|
||||||
Liste des reservation en attente de validation
|
Liste des réservation en attente de validation
|
||||||
</h1>
|
</h1>
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -78,12 +78,26 @@ def index(request: HttpRequest):
|
|||||||
fonctions_utilitaire.envoyer_mail(
|
fonctions_utilitaire.envoyer_mail(
|
||||||
sujet = "Reservation de salle",
|
sujet = "Reservation de salle",
|
||||||
message = f"""
|
message = f"""
|
||||||
Une nouvelle demande de réservation de la {dict(Reservation.TYPE_CHOICES).get(salle)} a été effectuée par {employe.user.first_name} {employe.user.last_name} du {form.cleaned_data.get('date_debut').strftime('%d/%m/%Y')} au {form.cleaned_data.get('date_fin').strftime('%d/%m/%Y')} pour motif "{motif}".
|
Une nouvelle demande de réservation de la {dict(Reservation.TYPE_CHOICES).get(salle)} a été effectuée par {employe.user.first_name} {employe.user.last_name} du {form.cleaned_data.get('date_debut').strftime('%d/%m/%Y')} au {form.cleaned_data.get('date_fin').strftime('%d/%m/%Y')} pour motif "{motif}".
|
||||||
Veuillez vous connecter à la plateforme pour plus de détails.""",
|
Veuillez vous connecter à la plateforme pour plus de détails.""",
|
||||||
destinataires = fonctions_utilitaire.EMAIL_ASSISTANTE_DE_DIRECTION
|
destinataires = fonctions_utilitaire.EMAIL_ASSISTANTE_DE_DIRECTION
|
||||||
)
|
)
|
||||||
|
# return redirect('gestion_salle:reservation-salle')
|
||||||
|
if salle == "lien_zoom" or besoin_zoom or besoin_ordi :
|
||||||
|
|
||||||
|
if fonctions_utilitaire.EMAIL_EQUIPE_INFORMATIQUE:
|
||||||
|
fonctions_utilitaire.envoyer_mail(
|
||||||
|
sujet="Demande de lien Zoom",
|
||||||
|
message=f"""
|
||||||
|
Bonjour,
|
||||||
|
Une nouvelle demande de réservation de salle nécessitant un lien Zoom a été effectuée par {employe.user.first_name} {employe.user.last_name} du {date_debut.strftime('%d/%m/%Y')} au {date_fin.strftime('%d/%m/%Y')} de {heure_debut.strftime('%H:%M')} a {heure_fin.strftime('%H:%M')} pour le motif {motif}
|
||||||
|
|
||||||
|
Veuillez vous connecter à la plateforme pour plus de détails.""",
|
||||||
|
destinataires=fonctions_utilitaire.EMAIL_EQUIPE_INFORMATIQUE
|
||||||
|
)
|
||||||
return redirect('gestion_salle:reservation-salle')
|
return redirect('gestion_salle:reservation-salle')
|
||||||
|
|
||||||
|
|
||||||
formulaire_reservation = ReservationForm()
|
formulaire_reservation = ReservationForm()
|
||||||
departement = employe.departement
|
departement = employe.departement
|
||||||
|
|
||||||
@@ -139,6 +153,7 @@ def liste_reservation_attente(request):
|
|||||||
"employe_id": reservation.employe.user.id,
|
"employe_id": reservation.employe.user.id,
|
||||||
"salle": dict(Reservation.TYPE_CHOICES).get(reservation.salle),
|
"salle": dict(Reservation.TYPE_CHOICES).get(reservation.salle),
|
||||||
'statut': dict(Reservation.STATUT).get(reservation.statut),
|
'statut': dict(Reservation.STATUT).get(reservation.statut),
|
||||||
|
"date_evenement": reservation.date_debut.strftime('%Y-%m-%d'),
|
||||||
} for reservation in reservations
|
} for reservation in reservations
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -151,7 +166,7 @@ def detail_reservation(request:HttpRequest, reservation_id:int):
|
|||||||
reservation_json = {
|
reservation_json = {
|
||||||
'id_reservation': reservation_id,
|
'id_reservation': reservation_id,
|
||||||
'employe': f"{employe.first_name} {employe.last_name}",
|
'employe': f"{employe.first_name} {employe.last_name}",
|
||||||
'salle': reservation.salle,
|
'salle': dict(Reservation.TYPE_CHOICES).get(reservation.salle),
|
||||||
'statut': dict(Reservation.STATUT).get(reservation.statut),
|
'statut': dict(Reservation.STATUT).get(reservation.statut),
|
||||||
'date_evenement': reservation.date_debut.strftime('%Y-%m-%d'),
|
'date_evenement': reservation.date_debut.strftime('%Y-%m-%d'),
|
||||||
'heure_debut': reservation.heure_debut.strftime('%H:%M'),
|
'heure_debut': reservation.heure_debut.strftime('%H:%M'),
|
||||||
|
|||||||
Reference in New Issue
Block a user