changement au niveau de requetes adaptés aux collaborateurs AD

This commit is contained in:
2025-08-27 09:40:17 +02:00
parent 9fb0c0a27f
commit ed4a7c02ca
29 changed files with 1741 additions and 548 deletions

View File

@@ -0,0 +1,14 @@
# Utilise une image PHP avec Apache et la version 8.1
FROM php:8.1-apache
# Installe l'extension mysqli pour te connecter à la base de données MySQL
RUN docker-php-ext-install mysqli && docker-php-ext-enable mysqli
# Active le module de réécriture d'URL d'Apache (souvent utile)
RUN a2enmod rewrite
# Copie tous les fichiers du back-end dans le dossier de travail d'Apache
COPY . /var/www/html/
# Expose le port 80 (par défaut pour un serveur web)
EXPOSE 80

View File

@@ -0,0 +1,147 @@
<?php
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json");
header("Access-Control-Allow-Headers: Content-Type, Authorization");
// Connexion DB
$host = "192.168.0.4";
$dbname = "DemandeConge";
$username = "wpuser";
$password = "-2b/)ru5/Bi8P[7_";
$conn = new mysqli($host, $username, $password, $dbname);
if ($conn->connect_error) {
die(json_encode(["authorized" => false, "message" => "Erreur DB: " . $conn->connect_error]));
}
// --- ID du groupe cible (Ensup-Groupe) ---
$groupId = "c1ea877c-6bca-4f47-bfad-f223640813a0";
// Récupération des données POST
$data = json_decode(file_get_contents("php://input"), true);
$userPrincipalName = $data["userPrincipalName"] ?? "";
// Récupération du token dans les headers
$headers = getallheaders();
$accessToken = isset($headers['Authorization'])
? str_replace("Bearer ", "", $headers['Authorization'])
: "";
if (!$userPrincipalName || !$accessToken) {
echo json_encode(["authorized" => false, "message" => "Email ou token manquant"]);
exit;
}
/**
* Fonction générique pour appeler Graph API
*/
function callGraph($url, $accessToken, $method = "GET", $body = null) {
$ch = curl_init($url);
$headers = ["Authorization: Bearer $accessToken"];
if ($method === "POST") {
$headers[] = "Content-Type: application/json";
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
}
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode !== 200) {
return null;
}
return json_decode($response, true);
}
/**
* Vérifier si utilisateur appartient à un groupe
*/
function isUserInGroup($userId, $groupId, $accessToken) {
$url = "https://graph.microsoft.com/v1.0/users/$userId/checkMemberGroups";
$data = json_encode(["groupIds" => [$groupId]]);
$result = callGraph($url, $accessToken, "POST", $data);
return $result && isset($result["value"]) && in_array($groupId, $result["value"]);
}
// 🔹 1. Vérifier si utilisateur existe déjà en DB
$stmt = $conn->prepare("SELECT id, entraUserId, prenom, nom, email, service, role FROM CollaborateurAD WHERE email = ? LIMIT 1");
$stmt->bind_param("s", $userPrincipalName);
$stmt->execute();
$result = $stmt->get_result();
$user = $result->fetch_assoc();
$stmt->close();
if ($user) {
echo json_encode([
"authorized" => true,
"role" => $user["role"],
"groups" => [$user["role"]],
"localUserId" => (int)$user["id"], // 🔹 ajout important
"user" => $user
]);
$conn->close();
exit;
}
// 🔹 2. Sinon → chercher lutilisateur dans Microsoft Graph
$userGraph = callGraph("https://graph.microsoft.com/v1.0/users/$userPrincipalName?\$select=id,displayName,givenName,surname,mail,department,jobTitle", $accessToken);
if (!$userGraph) {
echo json_encode([
"authorized" => false,
"message" => "Utilisateur introuvable dans Entra ou token invalide"
]);
$conn->close();
exit;
}
// 🔹 3. Vérifier appartenance au groupe Ensup-Groupe
$isInTargetGroup = isUserInGroup($userGraph["id"], $groupId, $accessToken);
if (!$isInTargetGroup) {
echo json_encode([
"authorized" => false,
"message" => "Utilisateur non autorisé : il n'appartient pas au groupe requis"
]);
$conn->close();
exit;
}
// 🔹 4. Insérer dans la base si nouveau
$entraUserId = $userGraph["id"];
$prenom = $userGraph["givenName"] ?? "";
$nom = $userGraph["surname"] ?? "";
$email = $userGraph["mail"] ?? $userPrincipalName;
$service = $userGraph["department"] ?? "";
$role = "Collaborateur"; // rôle par défaut
$stmt = $conn->prepare("INSERT INTO CollaborateurAD (entraUserId, prenom, nom, email, service, role)
VALUES (?, ?, ?, ?, ?, ?)");
$stmt->bind_param("ssssss", $entraUserId, $prenom, $nom, $email, $service, $role);
$stmt->execute();
$newUserId = $stmt->insert_id;
$stmt->close();
// 🔹 5. Réponse finale
echo json_encode([
"authorized" => true,
"role" => $role,
"groups" => [$role],
"localUserId" => (int)$newUserId, // 🔹 ajout important
"user" => [
"id" => $newUserId,
"entraUserId" => $entraUserId,
"prenom" => $prenom,
"nom" => $nom,
"email" => $email,
"service" => $service,
"role" => $role
]
]);
$conn->close();
?>

20
project/public/php/db.php Normal file
View File

@@ -0,0 +1,20 @@
<?php
// Informations de connexion
$host = "192.168.0.4";
$dbname = "DemandeConge";
$username = "wpuser";
$password = "-2b/)ru5/Bi8P[7_";
// Connexion MySQLi
$conn = new mysqli($host, $username, $password, $dbname);
// Vérification de la connexion
if ($conn->connect_error) {
die(json_encode([
"success" => false,
"message" => "Erreur DB: " . $conn->connect_error
]));
}
// Important : définir lencodage en UTF-8 (pour accents, etc.)
$conn->set_charset("utf8mb4");

View File

@@ -27,7 +27,6 @@ if ($conn->connect_error) {
exit();
}
// Récupération ID manager
$managerId = $_GET['SuperieurId'] ?? null;
if (!$managerId) {
@@ -36,31 +35,29 @@ if (!$managerId) {
}
$sql = "
SELECT
dc.Id,
dc.DateDebut,
dc.DateFin,
dc.Statut,
dc.DateDemande,
dc.Commentaire,
dc.DocumentJoint,
dc.EmployeeId,
CONCAT(u.Prenom, ' ', u.Nom) as employee_name,
u.Email as employee_email,
tc.Nom as type
FROM DemandeConge dc
JOIN Users u ON dc.EmployeeId = u.ID
JOIN TypeConge tc ON dc.TypeCongeId = tc.Id
JOIN HierarchieValidation hv ON hv.EmployeId = u.ID
WHERE hv.SuperieurId = ?
ORDER BY dc.DateDemande DESC
SELECT
dc.Id,
dc.DateDebut,
dc.DateFin,
dc.Statut,
dc.DateDemande,
dc.Commentaire,
dc.DocumentJoint,
dc.CollaborateurADId AS employee_id,
CONCAT(ca.Prenom, ' ', ca.Nom) as employee_name,
ca.Email as employee_email,
tc.Nom as type
FROM DemandeConge dc
JOIN CollaborateurAD ca ON dc.CollaborateurADId = ca.id
JOIN TypeConge tc ON dc.TypeCongeId = tc.Id
JOIN HierarchieValidationAD hv ON hv.CollaborateurId = ca.id
WHERE hv.SuperieurId = ?
ORDER BY dc.DateDemande DESC
";
$stmt = $conn->prepare($sql);
$stmt->bind_param("i", $managerId);
$stmt->execute();
// Manquant dans ton code
$result = $stmt->get_result();
$requests = [];
@@ -78,7 +75,7 @@ while ($row = $result->fetch_assoc()) {
$requests[] = [
"id" => (int)$row['Id'],
"employee_id" => (int)$row['EmployeeId'],
"employee_id" => (int)$row['employee_id'],
"employee_name" => $row['employee_name'],
"employee_email" => $row['employee_email'],
"type" => $row['type'],

View File

@@ -0,0 +1,51 @@
<?php
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: POST, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type, Authorization");
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
http_response_code(200);
exit();
}
header("Content-Type: application/json");
$host = "192.168.0.4";
$dbname = "DemandeConge";
$username = "wpuser";
$password = "-2b/)ru5/Bi8P[7_";
$conn = new mysqli($host, $username, $password, $dbname);
if ($conn->connect_error) {
die(json_encode(["success" => false, "message" => "Erreur DB : " . $conn->connect_error]));
}
// Récupérer l'ID
$id = isset($_GET['id']) ? (int)$_GET['id'] : 0;
if ($id <= 0) {
echo json_encode(["success" => false, "message" => "ID collaborateur invalide"]);
exit;
}
try {
$stmt = $conn->prepare("
SELECT id, Nom, Prenom, Email, Matricule, Telephone, Adresse
FROM CollaborateurAD
WHERE id = ? AND Actif = 1
");
$stmt->bind_param("i", $id);
$stmt->execute();
$result = $stmt->get_result();
$employee = $result->fetch_assoc();
if ($employee) {
echo json_encode(["success" => true, "employee" => $employee]);
} else {
echo json_encode(["success" => false, "message" => "Collaborateur non trouvé"]);
}
} catch (Exception $e) {
echo json_encode(["success" => false, "message" => "Erreur DB: " . $e->getMessage()]);
}
$conn->close();
?>

View File

@@ -0,0 +1,66 @@
<?php
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: POST, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type, Authorization");
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
http_response_code(200);
exit();
}
header("Content-Type: application/json");
$host = "192.168.0.4";
$dbname = "DemandeConge";
$username = "wpuser";
$password = "-2b/)ru5/Bi8P[7_";
$conn = new mysqli($host, $username, $password, $dbname);
if ($conn->connect_error) {
die(json_encode(["success" => false, "message" => "Erreur DB : " . $conn->connect_error]));
}
// Récupérer l'ID
$id = isset($_GET['id']) ? (int)$_GET['id'] : 0;
if ($id <= 0) {
echo json_encode(["success" => false, "message" => "ID employé invalide"]);
exit;
}
try {
$sql = "SELECT Id, TypeCongeId, NombreJours, DateDebut, DateFin, Statut
FROM DemandeConge
WHERE EmployeeId = ?
ORDER BY DateDemande DESC";
$stmt = $conn->prepare($sql);
$stmt->bind_param("i", $id);
$stmt->execute();
$result = $stmt->get_result();
// Mapping des types de congés
$typeNames = [
1 => "Congé payé",
2 => "RTT",
3 => "Maladie"
];
$requests = [];
while ($row = $result->fetch_assoc()) {
$row['type'] = $typeNames[$row['TypeCongeId']] ?? "Autre";
$row['days'] = (float)$row['NombreJours'];
// Formater jours : 2j ou 1.5j
$row['days_display'] = ((int)$row['days'] == $row['days'] ? (int)$row['days'] : $row['days']) . "j";
$row['date_display'] = date("d/m/Y", strtotime($row['DateDebut']))
. " - "
. date("d/m/Y", strtotime($row['DateFin']));
$requests[] = $row;
}
echo json_encode(["success" => true, "requests" => $requests]);
} catch (Exception $e) {
echo json_encode(["success" => false, "message" => "Erreur DB: " . $e->getMessage()]);
}
$conn->close();
?>

View File

@@ -27,22 +27,22 @@ $leaveYear = getLeaveYear();
$rttYear = getRTTYear();
$currentDate = date('Y-m-d');
// --- Soldes initiaux (CompteurConges) restent inchangés ---
// --- Soldes initiaux (CompteurConges pour CollaborateurAD) ---
$cpSolde = 0; $rttSolde = 0; $absSolde = 0;
if ($cpTypeId !== null) {
$q="SELECT Solde FROM CompteurConges WHERE EmployeeId=? AND TypeCongeId=? AND Annee=?";
$q="SELECT Solde FROM CompteurConges WHERE CollaborateurADId=? AND TypeCongeId=? AND Annee=?";
$s=$conn->prepare($q); $s->bind_param("iii",$userId,$cpTypeId,$leaveYear); $s->execute(); $res=$s->get_result(); if($r=$res->fetch_assoc()) $cpSolde=$r['Solde']; $s->close();
}
if ($rttTypeId !== null) {
$q="SELECT Solde FROM CompteurConges WHERE EmployeeId=? AND TypeCongeId=? AND Annee=?";
$q="SELECT Solde FROM CompteurConges WHERE CollaborateurADId=? AND TypeCongeId=? AND Annee=?";
$s=$conn->prepare($q); $s->bind_param("iii",$userId,$rttTypeId,$rttYear); $s->execute(); $res=$s->get_result(); if($r=$res->fetch_assoc()) $rttSolde=$r['Solde']; $s->close();
}
if ($absTypeId !== null) {
$q="SELECT Solde FROM CompteurConges WHERE EmployeeId=? AND TypeCongeId=? AND Annee=?";
$q="SELECT Solde FROM CompteurConges WHERE CollaborateurADId=? AND TypeCongeId=? AND Annee=?";
$s=$conn->prepare($q); $s->bind_param("iii",$userId,$absTypeId,$rttYear); $s->execute(); $res=$s->get_result(); if($r=$res->fetch_assoc()) $absSolde=$r['Solde']; $s->close();
}
// --- Calcul CP in process : priorité DemandeCongeType, fallback = working days on DemandeConge ---
// --- Calcul CP en cours ---
$cpInProcess = 0;
if ($cpTypeId !== null) {
$sql = "
@@ -50,13 +50,13 @@ if ($cpTypeId !== null) {
FROM DemandeConge dc
LEFT JOIN DemandeCongeType dct
ON dct.DemandeCongeId = dc.Id AND dct.TypeCongeId = ?
WHERE dc.EmployeeId = ?
WHERE dc.CollaborateurADId = ?
AND dc.Statut IN ('En attente','Validée')
AND dc.DateFin >= ?
AND (dct.NombreJours IS NOT NULL OR FIND_IN_SET(?, dc.TypeCongeId))
";
$s = $conn->prepare($sql);
$s->bind_param("iiss", $cpTypeId, $userId, $currentDate, $cpTypeId);
$s->bind_param("iisi", $cpTypeId, $userId, $currentDate, $cpTypeId);
$s->execute();
$res = $s->get_result();
while ($r = $res->fetch_assoc()) {
@@ -69,7 +69,7 @@ if ($cpTypeId !== null) {
$s->close();
}
// --- Calcul RTT in process (même logique) ---
// --- Calcul RTT en cours ---
$rttInProcess = 0;
if ($rttTypeId !== null) {
$sql = "
@@ -77,13 +77,13 @@ if ($rttTypeId !== null) {
FROM DemandeConge dc
LEFT JOIN DemandeCongeType dct
ON dct.DemandeCongeId = dc.Id AND dct.TypeCongeId = ?
WHERE dc.EmployeeId = ?
WHERE dc.CollaborateurADId = ?
AND dc.Statut IN ('En attente','Validée')
AND dc.DateFin >= ?
AND (dct.NombreJours IS NOT NULL OR FIND_IN_SET(?, dc.TypeCongeId))
";
$s = $conn->prepare($sql);
$s->bind_param("iiss", $rttTypeId, $userId, $currentDate, $rttTypeId);
$s->bind_param("iisi", $rttTypeId, $userId, $currentDate, $rttTypeId);
$s->execute();
$res = $s->get_result();
while ($r = $res->fetch_assoc()) {
@@ -96,7 +96,7 @@ if ($rttTypeId !== null) {
$s->close();
}
// --- Calcul absenteisme (validation) : priorité DemandeCongeType, fallback = DATEDIFF+1 ---
// --- Calcul absenteisme validé ---
$absenteism = 0;
if ($absTypeId !== null) {
$sql = "
@@ -104,7 +104,7 @@ if ($absTypeId !== null) {
FROM DemandeConge dc
LEFT JOIN DemandeCongeType dct
ON dct.DemandeCongeId = dc.Id AND dct.TypeCongeId = ?
WHERE dc.EmployeeId = ?
WHERE dc.CollaborateurADId = ?
AND dc.Statut = 'Validée'
AND (dct.NombreJours IS NOT NULL OR FIND_IN_SET(?, dc.TypeCongeId))
";
@@ -116,7 +116,6 @@ if ($absTypeId !== null) {
if ($r['NombreJours'] !== null) {
$absenteism += (float)$r['NombreJours'];
} else {
// fallback : DATEDIFF + 1
$d1 = new DateTime($r['DateDebut']); $d2 = new DateTime($r['DateFin']);
$absenteism += ($d2->diff($d1)->days + 1);
}

View File

@@ -55,8 +55,8 @@ function getWorkingDays($startDate, $endDate) {
}
try {
// Récupérer le service du manager
$queryManagerService = "SELECT ServiceId FROM Users WHERE ID = ?";
// Récupérer le service du manager (table CollaborateurAD)
$queryManagerService = "SELECT ServiceId FROM CollaborateurAD WHERE id = ?";
$stmtManager = $conn->prepare($queryManagerService);
$stmtManager->bind_param("i", $managerId);
$stmtManager->execute();
@@ -75,19 +75,19 @@ try {
dc.Statut,
dc.DateDemande,
dc.Commentaire,
dc.EmployeeId,
CONCAT(u.Prenom, ' ', u.Nom) as employee_name,
u.Email as employee_email,
dc.CollaborateurADId,
CONCAT(ca.prenom, ' ', ca.nom) as employee_name,
ca.email as employee_email,
GROUP_CONCAT(tc.Nom ORDER BY tc.Nom SEPARATOR ', ') as types
FROM DemandeConge dc
JOIN Users u ON dc.EmployeeId = u.ID
JOIN CollaborateurAD ca ON dc.CollaborateurADId = ca.id
JOIN TypeConge tc ON FIND_IN_SET(tc.Id, dc.TypeCongeId)
WHERE u.ServiceId = ?
WHERE ca.ServiceId = ?
AND dc.Statut = 'En attente'
AND u.ID != ?
AND ca.id != ?
GROUP BY
dc.Id, dc.DateDebut, dc.DateFin, dc.Statut, dc.DateDemande,
dc.Commentaire, dc.EmployeeId, u.Prenom, u.Nom, u.Email
dc.Commentaire, dc.CollaborateurADId, ca.prenom, ca.nom, ca.email
ORDER BY dc.DateDemande ASC
";
@@ -112,7 +112,7 @@ try {
$requests[] = [
'id' => (int)$row['Id'],
'employee_id' => (int)$row['EmployeeId'],
'employee_id' => (int)$row['CollaborateurADId'],
'employee_name' => $row['employee_name'],
'employee_email' => $row['employee_email'],
'type' => $row['types'], // ex: "Congé payé, RTT"

View File

@@ -53,31 +53,31 @@ function getWorkingDays($startDate, $endDate) {
try {
// Requête multi-types
$query = "
SELECT
dc.Id,
dc.DateDebut,
dc.DateFin,
dc.Statut,
dc.DateDemande,
dc.Commentaire,
dc.Validateur,
dc.DocumentJoint,
GROUP_CONCAT(tc.Nom ORDER BY tc.Nom SEPARATOR ', ') AS TypeConges
FROM DemandeConge dc
JOIN TypeConge tc ON FIND_IN_SET(tc.Id, dc.TypeCongeId)
WHERE dc.EmployeeId = ?
GROUP BY
dc.Id, dc.DateDebut, dc.DateFin, dc.Statut, dc.DateDemande,
dc.Commentaire, dc.Validateur, dc.DocumentJoint
ORDER BY dc.DateDemande DESC
";
SELECT
dc.Id,
dc.DateDebut,
dc.DateFin,
dc.Statut,
dc.DateDemande,
dc.Commentaire,
dc.Validateur,
dc.DocumentJoint,
GROUP_CONCAT(tc.Nom ORDER BY tc.Nom SEPARATOR ', ') AS TypeConges
FROM DemandeConge dc
JOIN TypeConge tc ON FIND_IN_SET(tc.Id, dc.TypeCongeId)
WHERE (dc.EmployeeId = ? OR dc.CollaborateurADId = ?)
GROUP BY
dc.Id, dc.DateDebut, dc.DateFin, dc.Statut, dc.DateDemande,
dc.Commentaire, dc.Validateur, dc.DocumentJoint
ORDER BY dc.DateDemande DESC
";
$stmt = $conn->prepare($query);
if (!$stmt) {
throw new Exception("Erreur préparation SQL : " . $conn->error);
}
$stmt->bind_param("i", $userId);
$stmt->bind_param("ii", $userId, $userId);
$stmt->execute();
$result = $stmt->get_result();

View File

@@ -1,5 +1,5 @@
<?php
// Récupération des membres de l'équipe pour un manager
// Récupération des membres de l'équipe pour un manager AD
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: GET, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type");
@@ -11,7 +11,7 @@ if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
header("Content-Type: application/json");
// Log des erreurs pour debug
// Debug erreurs
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
@@ -24,7 +24,7 @@ $password = "-2b/)ru5/Bi8P[7_";
$conn = new mysqli($host, $username, $password, $dbname);
if ($conn->connect_error) {
error_log("Erreur connexion DB getTeamMembers: " . $conn->connect_error);
error_log("Erreur connexion DB getTeamMembersAD: " . $conn->connect_error);
echo json_encode(["success" => false, "message" => "Erreur de connexion à la base de données"]);
exit();
}
@@ -36,11 +36,11 @@ if ($managerId === null) {
exit();
}
error_log("getTeamMembers - Manager ID: $managerId");
error_log("getTeamMembersAD - Manager ID: $managerId");
try {
// D'abord, récupérer le service du manager
$queryManagerService = "SELECT ServiceId FROM Users WHERE ID = ?";
// 🔹 1. Récupérer le ServiceId du manager
$queryManagerService = "SELECT ServiceId FROM CollaborateurAD WHERE id = ?";
$stmtManager = $conn->prepare($queryManagerService);
$stmtManager->bind_param("i", $managerId);
$stmtManager->execute();
@@ -48,22 +48,22 @@ try {
if ($managerRow = $resultManager->fetch_assoc()) {
$serviceId = $managerRow['ServiceId'];
error_log("getTeamMembers - Service ID du manager: $serviceId");
error_log("getTeamMembersAD - ServiceId du manager: $serviceId");
// Récupérer tous les membres du même service (sauf le manager lui-même)
// 🔹 2. Récupérer tous les collaborateurs du même service (sauf le manager)
$queryTeam = "
SELECT
u.ID as id,
u.Nom as nom,
u.Prenom as prenom,
u.Email as email,
u.Role as role,
u.DateEmbauche as date_embauche,
c.id,
c.nom,
c.prenom,
c.email,
c.role,
s.Nom as service_name
FROM Users u
JOIN Services s ON u.ServiceId = s.Id
WHERE u.ServiceId = ? AND u.ID != ? AND u.Actif = 1
ORDER BY u.Prenom, u.Nom
FROM CollaborateurAD c
JOIN Services s ON c.ServiceId = s.Id
WHERE c.ServiceId = ? AND c.id != ?
ORDER BY c.prenom, c.nom
";
$stmtTeam = $conn->prepare($queryTeam);
@@ -79,12 +79,12 @@ try {
'prenom' => $row['prenom'],
'email' => $row['email'],
'role' => $row['role'],
'date_embauche' => $row['date_embauche'],
'service_name' => $row['service_name']
];
}
error_log("getTeamMembers - Membres trouvés: " . count($teamMembers));
error_log("getTeamMembersAD - Membres trouvés: " . count($teamMembers));
echo json_encode([
"success" => true,
@@ -95,7 +95,7 @@ try {
$stmtTeam->close();
} else {
error_log("getTeamMembers - Manager non trouvé: $managerId");
error_log("getTeamMembersAD - Manager non trouvé: $managerId");
echo json_encode([
"success" => false,
"message" => "Manager non trouvé"
@@ -105,7 +105,7 @@ try {
$stmtManager->close();
} catch (Exception $e) {
error_log("Erreur getTeamMembers: " . $e->getMessage());
error_log("Erreur getTeamMembersAD: " . $e->getMessage());
echo json_encode([
"success" => false,
"message" => "Erreur lors de la récupération de l'équipe: " . $e->getMessage()
@@ -113,4 +113,4 @@ try {
}
$conn->close();
?>
?>

View File

@@ -0,0 +1,128 @@
<?php
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json");
header("Access-Control-Allow-Headers: Content-Type, Authorization");
// --- Connexion DB ---
$host = "192.168.0.4";
$dbname = "DemandeConge";
$username = "wpuser";
$password = "-2b/)ru5/Bi8P[7_";
$conn = new mysqli($host, $username, $password, $dbname);
if ($conn->connect_error) {
die(json_encode(["success" => false, "message" => "Erreur DB: " . $conn->connect_error]));
}
// --- Authentification (client credentials) ---
$tenantId = "9840a2a0-6ae1-4688-b03d-d2ec291be0f9";
$clientId = "4bb4cc24-bac3-427c-b02c-5d14fc67b561";
$clientSecret = "ViC8Q~n4F5YweE18wjS0kfhp3kHh6LB2gZ76_b4R";
$scope = "https://graph.microsoft.com/.default";
$url = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token";
$data = [
"grant_type" => "client_credentials",
"client_id" => $clientId,
"client_secret" => $clientSecret,
"scope" => $scope
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
$tokenData = json_decode($result, true);
$accessToken = $tokenData["access_token"] ?? "";
if (!$accessToken) {
die(json_encode(["success" => false, "message" => "Impossible d'obtenir un token Microsoft", "details" => $tokenData]));
}
// --- ID du groupe cible (Ensup-Groupe) ---
$groupId = "c1ea877c-6bca-4f47-bfad-f223640813a0"; // 🔹 Mets l'Object ID de ton groupe ici
$urlGroup = "https://graph.microsoft.com/v1.0/groups/$groupId?\$select=id,displayName,description,mail,createdDateTime";
$ch = curl_init($urlGroup);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer $accessToken"]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$respGroup = curl_exec($ch);
curl_close($ch);
$group = json_decode($respGroup, true);
if (!isset($group["id"])) {
die(json_encode(["success" => false, "message" => "Impossible de récupérer le groupe Ensup-Groupe"]));
}
$displayName = $group["displayName"] ?? "";
$description = $group["description"] ?? "";
$mail = $group["mail"] ?? "";
$createdAt = null;
if (!empty($group["createdDateTime"])) {
$dt = new DateTime($group["createdDateTime"]);
$createdAt = $dt->format("Y-m-d H:i:s"); // format MySQL
}
// --- Insérer / mettre à jour le groupe dans EntraGroups ---
$stmt = $conn->prepare("INSERT INTO EntraGroups (Id, DisplayName, Description, Mail, CreatedAt, UpdatedAt, SyncDate, IsActive)
VALUES (?, ?, ?, ?, ?, NOW(), NOW(), 1)
ON DUPLICATE KEY UPDATE
DisplayName=?, Description=?, Mail=?, UpdatedAt=NOW(), SyncDate=NOW(), IsActive=1");
if ($stmt) {
$stmt->bind_param("ssssssss",
$groupId, $displayName, $description, $mail, $createdAt,
$displayName, $description, $mail
);
$stmt->execute();
}
// --- Récupérer les membres du groupe ---
$urlMembers = "https://graph.microsoft.com/v1.0/groups/$groupId/members?\$select=id,givenName,surname,mail,department,jobTitle";
$ch = curl_init($urlMembers);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer $accessToken"]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$respMembers = curl_exec($ch);
curl_close($ch);
$members = json_decode($respMembers, true)["value"] ?? [];
$usersInserted = 0;
foreach ($members as $m) {
$entraUserId = $m["id"];
$prenom = $m["givenName"] ?? "";
$nom = $m["surname"] ?? "";
$email = $m["mail"] ?? "";
$service = $m["department"] ?? "";
$role = "Collaborateur"; // par défaut
if (!$email) continue;
$stmt = $conn->prepare("INSERT INTO CollaborateurAD (entraUserId, prenom, nom, email, service, role)
VALUES (?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE prenom=?, nom=?, email=?, service=?, role=?");
if ($stmt) {
$stmt->bind_param("sssssssssss",
$entraUserId, $prenom, $nom, $email, $service, $role,
$prenom, $nom, $email, $service, $role
);
$stmt->execute();
$usersInserted++;
}
}
echo json_encode([
"success" => true,
"message" => "Synchronisation terminée",
"groupe_sync" => $displayName,
"users_sync" => $usersInserted
]);
$conn->close();
?>

View File

@@ -1,7 +1,7 @@
<?php
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: POST, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type");
header("Access-Control-Allow-Headers: Content-Type, Authorization");
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
http_response_code(200);
@@ -16,59 +16,137 @@ $username = "wpuser";
$password = "-2b/)ru5/Bi8P[7_";
$conn = new mysqli($host, $username, $password, $dbname);
if ($conn->connect_error) {
die(json_encode(["success" => false, "message" => "Erreur de connexion à la base de données : " . $conn->connect_error]));
die(json_encode(["success" => false, "message" => "Erreur DB : " . $conn->connect_error]));
}
$data = json_decode(file_get_contents('php://input'), true);
$email = $data['email'] ?? '';
$mot_de_passe = $data['mot_de_passe'] ?? '';
$entraUserId = $data['entraUserId'] ?? '';
$userPrincipalName = $data['userPrincipalName'] ?? '';
$query = "
SELECT
u.ID,
u.Prenom,
u.Nom,
u.Email,
u.Role,
u.ServiceId,
s.Nom AS ServiceNom
FROM Users u
LEFT JOIN Services s ON u.ServiceId = s.Id
WHERE u.Email = ? AND u.MDP = ?
";
$headers = getallheaders();
$accessToken = isset($headers['Authorization']) ? str_replace('Bearer ', '', $headers['Authorization']) : '';
$stmt = $conn->prepare($query);
// ======================================================
// 1⃣ Mode Azure AD (avec token + Entra)
// ======================================================
if ($accessToken && $entraUserId) {
// Vérifier si utilisateur existe déjà dans CollaborateurAD
$stmt = $conn->prepare("SELECT * FROM CollaborateurAD WHERE entraUserId=? OR email=? LIMIT 1");
$stmt->bind_param("ss", $entraUserId, $email);
$stmt->execute();
$result = $stmt->get_result();
if ($stmt === false) {
die(json_encode(["success" => false, "message" => "Erreur de préparation de la requête : " . $conn->error]));
}
$stmt->bind_param("ss", $email, $mot_de_passe);
$stmt->execute();
$result = $stmt->get_result();
if ($result->num_rows === 1) {
if ($result->num_rows === 0) {
echo json_encode(["success" => false, "message" => "Utilisateur non autorisé (pas dans l'annuaire)"]);
exit();
}
$user = $result->fetch_assoc();
echo json_encode([
"success" => true,
"message" => "Connexion réussie.",
"user" => [
"id" => $user['ID'],
"prenom" => $user['Prenom'],
"nom" => $user['Nom'],
"email" => $user['Email'],
"role" => $user['Role'],
"service" => $user['ServiceNom'] ?? 'Non défini'
]
]);
} else {
echo json_encode(["success" => false, "message" => "Identifiants incorrects."]);
// Récupérer groupes de lutilisateur via Graph
$ch = curl_init("https://graph.microsoft.com/v1.0/users/$userPrincipalName/memberOf?\$select=id");
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer $accessToken"]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
$dataGraph = json_decode($response, true);
$userGroups = [];
if (isset($dataGraph['value'])) {
foreach ($dataGraph['value'] as $g) {
if (isset($g['id'])) {
$userGroups[] = $g['id'];
}
}
}
// Vérifier si au moins un groupe est autorisé
$res = $conn->query("SELECT Id FROM EntraGroups WHERE IsActive=1");
$allowedGroups = [];
while ($row = $res->fetch_assoc()) {
$allowedGroups[] = $row['Id'];
}
$authorized = count(array_intersect($userGroups, $allowedGroups)) > 0;
if ($authorized) {
echo json_encode([
"success" => true,
"message" => "Connexion réussie via Azure AD",
"user" => [
"id" => $user['id'],
"prenom" => $user['prenom'],
"nom" => $user['nom'],
"email" => $user['email'],
"role" => $user['role'],
"service" => $user['service']
]
]);
} else {
echo json_encode(["success" => false, "message" => "Utilisateur non autorisé - pas dans un groupe actif"]);
}
$conn->close();
exit();
}
$stmt->close();
// ======================================================
// 2⃣ Mode local (login/password → Users)
// ======================================================
if ($email && $mot_de_passe) {
$query = "
SELECT
u.ID,
u.Prenom,
u.Nom,
u.Email,
u.Role,
u.ServiceId,
s.Nom AS ServiceNom
FROM Users u
LEFT JOIN Services s ON u.ServiceId = s.Id
WHERE u.Email = ? AND u.MDP = ?
";
$stmt = $conn->prepare($query);
if ($stmt === false) {
die(json_encode(["success" => false, "message" => "Erreur de préparation : " . $conn->error]));
}
$stmt->bind_param("ss", $email, $mot_de_passe);
$stmt->execute();
$result = $stmt->get_result();
if ($result->num_rows === 1) {
$user = $result->fetch_assoc();
echo json_encode([
"success" => true,
"message" => "Connexion réussie (mode local)",
"user" => [
"id" => $user['ID'],
"prenom" => $user['Prenom'],
"nom" => $user['Nom'],
"email" => $user['Email'],
"role" => $user['Role'],
"service" => $user['ServiceNom'] ?? 'Non défini'
]
]);
} else {
echo json_encode(["success" => false, "message" => "Identifiants incorrects (mode local)"]);
}
$stmt->close();
$conn->close();
exit();
}
// ======================================================
// 3⃣ Aucun mode ne correspond
// ======================================================
echo json_encode(["success" => false, "message" => "Aucune méthode de connexion fournie"]);
$conn->close();
?>

View File

@@ -1,100 +1,293 @@
<?php
// (headers, connexion, lecture FormData ou JSON — pareil que précédemment)
ini_set('display_errors', 1); ini_set('display_startup_errors', 1); error_reporting(E_ALL);
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: POST, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type");
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { http_response_code(200); exit(); }
header("Content-Type: application/json");
ob_clean();
header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Origin: http://localhost:5173");
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type, Authorization");
$host="192.168.0.4"; $dbname="DemandeConge"; $username="wpuser"; $password="-2b/)ru5/Bi8P[7_";
$conn = new mysqli($host,$username,$password,$dbname);
if ($conn->connect_error) { echo json_encode(["success"=>false,"message"=>"Erreur DB: ".$conn->connect_error]); exit(); }
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
http_response_code(200);
exit();
}
// Lecture JSON (support FormData via $_POST['data'])
if (isset($_POST['data'])) {
$data = json_decode($_POST['data'], true);
// Debug
ini_set('display_errors', 1);
error_reporting(E_ALL);
// Connexion DB
$host = "192.168.0.4";
$dbname = "DemandeConge";
$username = "wpuser";
$password = "-2b/)ru5/Bi8P[7_";
try {
$pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8", $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
echo json_encode(["success"=>false,"message"=>"Erreur DB: ".$e->getMessage()]);
exit;
}
// Lecture JSON brut
$input = file_get_contents('php://input');
$data = json_decode($input, true);
// 🔎 Debug pour vérifier ce qui arrive
error_log("📥 Payload reçu : " . print_r($data, true));
if (!$data) {
echo json_encode(["success"=>false,"message"=>"JSON invalide","raw"=>$input]);
exit;
}
// Vérification des champs obligatoires
$required = ['DateDebut','DateFin','Repartition','NombreJours','Email','Nom'];
foreach ($required as $f) {
if (!array_key_exists($f, $data)) {
echo json_encode([
"success"=>false,
"message"=>"Donnée manquante : $f",
"debug"=>$data
]);
exit;
}
}
$dateDebut = $data['DateDebut'];
$dateFin = $data['DateFin'];
$commentaire = $data['Commentaire'] ?? '';
$numDays = (float)$data['NombreJours'];
$userEmail = $data['Email'];
$userName = $data['Nom'];
$statut = 'En attente';
$currentDate = date('Y-m-d H:i:s');
// 🔎 Identifier si c'est un CollaborateurAD ou un User
$stmt = $pdo->prepare("SELECT id FROM CollaborateurAD WHERE email = :email LIMIT 1");
$stmt->execute([':email'=>$userEmail]);
$collabAD = $stmt->fetch(PDO::FETCH_ASSOC);
$isAD = false;
$employeeId = null;
$collaborateurId = null;
if ($collabAD) {
$isAD = true;
$collaborateurId = (int)$collabAD['id'];
} else {
$input = file_get_contents('php://input');
$data = json_decode($input, true);
}
if ($data === null) {
echo json_encode(["success"=>false,"message"=>"JSON invalide"]); $conn->close(); exit();
$stmt = $pdo->prepare("SELECT ID FROM Users WHERE Email = :email LIMIT 1");
$stmt->execute([':email'=>$userEmail]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$user) {
echo json_encode(["success"=>false,"message"=>"Aucun collaborateur trouvé pour $userEmail"]);
exit;
}
$employeeId = (int)$user['ID'];
}
// Vérifs minimales
if (!isset($data['EmployeeId'],$data['DateDebut'],$data['DateFin'],$data['Repartition'],$data['NombreJours'])) {
echo json_encode(["success"=>false,"message"=>"Données manquantes"]); $conn->close(); exit();
}
$employeeId = (int)$data['EmployeeId'];
$dateDebut = $data['DateDebut'];
$dateFin = $data['DateFin'];
$commentaire= $data['Commentaire'] ?? '';
$numDays = (float)$data['NombreJours'];
$statut = 'En attente';
$currentDate= date('Y-m-d H:i:s');
// 1) Construire la liste d'IDs pour TypeCongeId (CSV) (compatibilité)
// 🔎 Résoudre les IDs des types de congés
$typeIds = [];
foreach ($data['Repartition'] as $rep) {
$code = $rep['TypeConge']; // CP, RTT, ABS ou texte libre
$code = $rep['TypeConge'];
switch ($code) {
case 'CP': $name = 'Congé payé'; break;
case 'RTT': $name = 'RTT'; break;
case 'ABS': $name = 'Congé maladie'; break;
default: $name = $code; break;
default: $name = $code; break;
}
$s = $pdo->prepare("SELECT Id FROM TypeConge WHERE Nom = :nom LIMIT 1");
$s->execute([':nom'=>$name]);
if ($r = $s->fetch(PDO::FETCH_ASSOC)) {
$typeIds[] = $r['Id'];
}
$s = $conn->prepare("SELECT Id FROM TypeConge WHERE Nom = ?");
$s->bind_param("s", $name);
$s->execute();
$res = $s->get_result();
if ($r = $res->fetch_assoc()) $typeIds[] = $r['Id'];
$s->close();
}
if (empty($typeIds)) { echo json_encode(["success"=>false,"message"=>"Aucun type valide"]); $conn->close(); exit(); }
if (empty($typeIds)) {
echo json_encode(["success"=>false,"message"=>"Aucun type de congé valide"]);
exit;
}
$typeCongeIdCsv = implode(',', $typeIds);
// 2) Insertion unique dans DemandeConge
$insert = $conn->prepare("INSERT INTO DemandeConge (EmployeeId, DateDebut, DateFin, TypeCongeId, Statut, DateDemande, Commentaire, Validateur, NombreJours) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)");
$validParam = '';
$insert->bind_param("isssssssd", $employeeId, $dateDebut, $dateFin, $typeCongeIdCsv, $statut, $currentDate, $commentaire, $validParam, $numDays);
if (!$insert->execute()) {
echo json_encode(["success"=>false,"message"=>"Erreur insert DemandeConge: ".$insert->error]);
$insert->close(); $conn->close(); exit();
}
$demandeId = $conn->insert_id;
$insert->close();
// Insertion DemandeConge
$sql = "INSERT INTO DemandeConge
(EmployeeId, CollaborateurADId, DateDebut, DateFin, TypeCongeId, Statut, DateDemande, Commentaire, Validateur, NombreJours)
VALUES (:eid, :cid, :dd, :df, :tc, :st, :cd, :com, :val, :nj)";
// 3) INSÉRER la répartition réelle dans DemandeCongeType (une ligne par type)
$insertType = $conn->prepare("INSERT INTO DemandeCongeType (DemandeCongeId, TypeCongeId, NombreJours) VALUES (?, ?, ?)");
if (!$insertType) {
echo json_encode(["success"=>false,"message"=>"Erreur préparation DemandeCongeType: ".$conn->error]); $conn->close(); exit();
}
$stmt = $pdo->prepare($sql);
$stmt->execute([
':eid'=> $isAD ? 0 : $employeeId,
':cid'=> $isAD ? $collaborateurId : null,
':dd'=>$dateDebut,
':df'=>$dateFin,
':tc'=>$typeCongeIdCsv,
':st'=>$statut,
':cd'=>$currentDate,
':com'=>$commentaire,
':val'=>'',
':nj'=>$numDays
]);
$demandeId = $pdo->lastInsertId();
// ✅ Insertion DemandeCongeType
$sql = "INSERT INTO DemandeCongeType (DemandeCongeId, TypeCongeId, NombreJours) VALUES (:did, :tid, :nj)";
$stmt = $pdo->prepare($sql);
foreach ($data['Repartition'] as $rep) {
$code = $rep['TypeConge'];
$jours = (float)$rep['NombreJours'];
$code = $rep['TypeConge'];
switch ($code) {
case 'CP': $name = 'Congé payé'; break;
case 'RTT': $name = 'RTT'; break;
case 'ABS': $name = 'Congé maladie'; break;
default: $name = $code; break;
default: $name = $code; break;
}
$s = $conn->prepare("SELECT Id FROM TypeConge WHERE Nom = ?");
$s->bind_param("s", $name);
$s->execute();
$res = $s->get_result();
if ($r = $res->fetch_assoc()) {
$typeId = (int)$r['Id'];
$insertType->bind_param("iid", $demandeId, $typeId, $jours); // i,i,d
$insertType->execute();
$s = $pdo->prepare("SELECT Id FROM TypeConge WHERE Nom = :nom LIMIT 1");
$s->execute([':nom'=>$name]);
if ($r = $s->fetch(PDO::FETCH_ASSOC)) {
$stmt->execute([
':did'=>$demandeId,
':tid'=>$r['Id'],
':nj'=>$jours
]);
}
$s->close();
}
$insertType->close();
echo json_encode(["success"=>true,"message"=>"Demande soumise", "request_id"=>$demandeId]);
$conn->close();
?>
// ✅ Récupérer les validateurs selon hiérarchie
if ($isAD) {
$stmt = $pdo->prepare("
SELECT c.email
FROM HierarchieValidationAD hv
JOIN CollaborateurAD c ON hv.SuperieurId = c.id
WHERE hv.CollaborateurId = :id
");
$stmt->execute([':id'=>$collaborateurId]);
} else {
$stmt = $pdo->prepare("
SELECT u.Email
FROM HierarchieValidation hv
JOIN Users u ON hv.SuperieurId = u.ID
WHERE hv.EmployeId = :id
");
$stmt->execute([':id'=>$employeeId]);
}
$managers = $stmt->fetchAll(PDO::FETCH_COLUMN);
# =============================================================
# 📧 AUTH Microsoft Graph (client_credentials)
# =============================================================
$tenantId = "9840a2a0-6ae1-4688-b03d-d2ec291be0f9";
$clientId = "4bb4cc24-bac3-427c-b02c-5d14fc67b561";
$clientSecret = "gvf8Q~545Bafn8yYsgjW~QG_P1lpzaRe6gJNgb2t";
$url = "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token";
$data = [
"client_id" => $clientId,
"scope" => "https://graph.microsoft.com/.default",
"client_secret" => $clientSecret,
"grant_type" => "client_credentials"
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Content-Type: application/x-www-form-urlencoded"
]);
$response = curl_exec($ch);
curl_close($ch);
$tokenData = json_decode($response, true);
if (!isset($tokenData['access_token'])) {
echo json_encode(["success" => false, "message" => "Impossible de générer un token Graph", "debug"=>$tokenData]);
exit;
}
$accessToken = $tokenData['access_token'];
# =============================================================
# 📧 Fonction envoi mail
# =============================================================
function sendMailGraph($accessToken, $fromEmail, $toEmail, $subject, $bodyHtml) {
$url = "https://graph.microsoft.com/v1.0/users/$fromEmail/sendMail";
$mailData = [
"message" => [
"subject" => $subject,
"body" => [
"contentType" => "HTML",
"content" => $bodyHtml
],
"toRecipients" => [
["emailAddress" => ["address" => $toEmail]]
]
],
"saveToSentItems" => "false"
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer $accessToken",
"Content-Type: application/json"
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($mailData));
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode >= 200 && $httpCode < 300) {
return true;
} else {
error_log("❌ Erreur envoi mail: $response");
return false;
}
}
# =============================================================
# 📧 Envoi automatique des emails
# =============================================================
$fromEmail = "noreply@ensup.eu";
# Mail au collaborateur
sendMailGraph(
$accessToken,
$fromEmail,
$userEmail,
"Confirmation de votre demande de congés",
"
Bonjour {$userName},<br/><br/>
Votre demande du <b>{$dateDebut}</b> au <b>{$dateFin}</b>
({$numDays} jour(s)) a bien été enregistrée.<br/>
Elle est en attente de validation par votre manager.<br/><br/>
Merci.
"
);
# Mail aux managers
foreach ($managers as $managerEmail) {
sendMailGraph(
$accessToken,
$fromEmail,
$managerEmail,
"Nouvelle demande de congé - {$userName}",
"
Bonjour,<br/><br/>
{$userName} a soumis une demande de congé :<br/>
- Du <b>{$dateDebut}</b> au <b>{$dateFin}</b> ({$numDays} jour(s))<br/>
- Commentaire : " . (!empty($commentaire) ? $commentaire : "Aucun") . "<br/><br/>
Merci de valider cette demande.
"
);
}
# ✅ Réponse finale
echo json_encode([
"success"=>true,
"message"=>"Demande soumise",
"request_id"=>$demandeId,
"managers"=>$managers
]);

View File

View File

@@ -1,14 +0,0 @@
<?php
$host = "192.168.0.4";
$dbname = "DemandeConge";
$username = "wpuser";
$password = "-2b/)ru5/Bi8P[7_";
$conn = new mysqli($host, $username, $password, $dbname);
if ($conn->connect_error) {
die("❌ Connexion échouée : " . $conn->connect_error);
}
echo "✅ Connexion réussie à la base de données !";
?>

View File

@@ -11,187 +11,197 @@ if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
header("Content-Type: application/json");
// Log des erreurs pour debug
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
// Connexion DB
$host = "192.168.0.4";
$dbname = "DemandeConge";
$username = "wpuser";
$password = "-2b/)ru5/Bi8P[7_";
$conn = new mysqli($host, $username, $password, $dbname);
if ($conn->connect_error) {
error_log("Erreur connexion DB validateRequest: " . $conn->connect_error);
echo json_encode(["success" => false, "message" => "Erreur de connexion à la base de données"]);
echo json_encode(["success" => false, "message" => "Erreur DB: " . $conn->connect_error]);
exit();
}
// Lecture du JSON envoyé
$input = file_get_contents('php://input');
error_log("validateRequest - Input reçu: " . $input);
$data = json_decode($input, true);
if (!isset($data['request_id'], $data['action'], $data['validator_id'])) {
error_log("validateRequest - Données manquantes: " . print_r($data, true));
echo json_encode([
"success" => false,
"message" => "Données manquantes pour la validation"
]);
echo json_encode(["success" => false, "message" => "Données manquantes"]);
exit();
}
$requestId = (int)$data['request_id'];
$action = $data['action']; // 'approve' ou 'reject'
$requestId = (int)$data['request_id'];
$action = $data['action']; // "approve" | "reject"
$validatorId = (int)$data['validator_id'];
$comment = $data['comment'] ?? '';
error_log("validateRequest - Request ID: $requestId, Action: $action, Validator: $validatorId");
$comment = $data['comment'] ?? '';
try {
$conn->begin_transaction();
// Vérifier que la demande existe et est en attente
// Vérifier si validateur est Users ou CollaborateurAD
$isUserValidator = false;
$stmt = $conn->prepare("SELECT ID FROM Users WHERE ID = ?");
$stmt->bind_param("i", $validatorId);
$stmt->execute();
$res = $stmt->get_result();
if ($res->fetch_assoc()) {
$isUserValidator = true;
} else {
$stmt = $conn->prepare("SELECT Id FROM CollaborateurAD WHERE Id = ?");
$stmt->bind_param("i", $validatorId);
$stmt->execute();
$res = $stmt->get_result();
if (!$res->fetch_assoc()) {
throw new Exception("Validateur introuvable dans Users ou CollaborateurAD");
}
}
$stmt->close();
// Récupération demande
$queryCheck = "
SELECT dc.Id, dc.EmployeeId, dc.TypeCongeId, dc.DateDebut, dc.DateFin, dc.NombreJours,
u.Nom, u.Prenom, tc.Nom as TypeNom
SELECT dc.Id, dc.EmployeeId, dc.CollaborateurADId, dc.TypeCongeId, dc.DateDebut, dc.DateFin, dc.NombreJours,
u.Nom as UserNom, u.Prenom as UserPrenom,
ca.nom as CADNom, ca.prenom as CADPrenom,
tc.Nom as TypeNom
FROM DemandeConge dc
JOIN Users u ON dc.EmployeeId = u.ID
JOIN TypeConge tc ON dc.TypeCongeId = tc.Id
LEFT JOIN Users u ON dc.EmployeeId = u.ID
LEFT JOIN CollaborateurAD ca ON dc.CollaborateurADId = ca.Id
WHERE dc.Id = ? AND dc.Statut = 'En attente'
";
$stmtCheck = $conn->prepare($queryCheck);
$stmtCheck->bind_param("i", $requestId);
$stmtCheck->execute();
$resultCheck = $stmtCheck->get_result();
if ($requestRow = $resultCheck->fetch_assoc()) {
$employeeId = $requestRow['EmployeeId'];
$typeCongeId = $requestRow['TypeCongeId'];
$nombreJours = $requestRow['NombreJours'];
$employeeName = $requestRow['Prenom'] . ' ' . $requestRow['Nom'];
$typeNom = $requestRow['TypeNom'];
error_log("validateRequest - Demande trouvée: $employeeName, Type: $typeNom, Jours: $nombreJours");
// Déterminer le nouveau statut
$newStatus = ($action === 'approve') ? 'Validée' : 'Refusée';
// Mettre à jour la demande
if (!($requestRow = $resultCheck->fetch_assoc())) {
throw new Exception("Demande non trouvée ou déjà traitée");
}
$stmtCheck->close();
$employeeId = $requestRow['EmployeeId'];
$collaborateurId = $requestRow['CollaborateurADId'];
$typeCongeId = $requestRow['TypeCongeId'];
$nombreJours = $requestRow['NombreJours'];
$employeeName = $employeeId
? $requestRow['UserPrenom']." ".$requestRow['UserNom']
: $requestRow['CADPrenom']." ".$requestRow['CADNom'];
$typeNom = $requestRow['TypeNom'];
$newStatus = ($action === 'approve') ? 'Validée' : 'Refusée';
// 🔹 Mise à jour DemandeConge
if ($isUserValidator) {
$queryUpdate = "
UPDATE DemandeConge
UPDATE DemandeConge
SET Statut = ?,
ValidateurId = ?,
ValidateurADId = NULL,
DateValidation = NOW(),
CommentaireValidation = ?
WHERE Id = ?
";
$stmtUpdate = $conn->prepare($queryUpdate);
$stmtUpdate->bind_param("sisi", $newStatus, $validatorId, $comment, $requestId);
if ($stmtUpdate->execute()) {
error_log("validateRequest - Demande mise à jour avec succès");
// Si approuvée, déduire du solde (sauf pour congé maladie)
if ($action === 'approve' && $typeNom !== 'Congé maladie') {
// Déterminer l'année selon le type de congé
$currentDate = new DateTime();
if ($typeNom === 'Congé payé') {
// Exercice CP: 01/06 au 31/05
$year = ($currentDate->format('m') < 6) ? $currentDate->format('Y') - 1 : $currentDate->format('Y');
} else {
// RTT: année civile
$year = $currentDate->format('Y');
}
error_log("validateRequest - Déduction solde: Type=$typeNom, Année=$year, Jours=$nombreJours");
// Déduire du solde
$queryDeduct = "
UPDATE CompteurConges
SET Solde = GREATEST(0, Solde - ?)
WHERE EmployeeId = ? AND TypeCongeId = ? AND Annee = ?
";
$stmtDeduct = $conn->prepare($queryDeduct);
$stmtDeduct->bind_param("diii", $nombreJours, $employeeId, $typeCongeId, $year);
if ($stmtDeduct->execute()) {
error_log("validateRequest - Solde déduit avec succès");
} else {
error_log("validateRequest - Erreur déduction solde: " . $stmtDeduct->error);
}
$stmtDeduct->close();
}
// Créer une notification pour l'employé
$notificationTitle = ($action === 'approve') ? 'Demande approuvée' : 'Demande refusée';
$notificationMessage = "Votre demande de $typeNom a été " . (($action === 'approve') ? 'approuvée' : 'refusée');
if ($comment) {
$notificationMessage .= ". Commentaire: $comment";
}
$queryNotif = "
INSERT INTO Notifications (UserId, Titre, Message, Type, DemandeCongeId)
VALUES (?, ?, ?, ?, ?)
";
$notifType = ($action === 'approve') ? 'Success' : 'Error';
$stmtNotif = $conn->prepare($queryNotif);
$stmtNotif->bind_param("isssi", $employeeId, $notificationTitle, $notificationMessage, $notifType, $requestId);
$stmtNotif->execute();
$stmtNotif->close();
// Log dans l'historique
$actionText = ($action === 'approve') ? 'Validation congé' : 'Refus congé';
$actionDetails = "$actionText $employeeName ($typeNom)";
if ($comment) {
$actionDetails .= " - $comment";
}
$queryHistory = "
INSERT INTO HistoriqueActions (UserId, Action, Details, DemandeCongeId)
VALUES (?, ?, ?, ?)
";
$stmtHistory = $conn->prepare($queryHistory);
$stmtHistory->bind_param("issi", $validatorId, $actionText, $actionDetails, $requestId);
$stmtHistory->execute();
$stmtHistory->close();
$conn->commit();
echo json_encode([
"success" => true,
"message" => "Demande " . (($action === 'approve') ? 'approuvée' : 'refusée') . " avec succès",
"new_status" => $newStatus
]);
} else {
throw new Exception("Erreur lors de la mise à jour: " . $stmtUpdate->error);
}
$stmtUpdate->close();
} else {
throw new Exception("Demande non trouvée ou déjà traitée");
$queryUpdate = "
UPDATE DemandeConge
SET Statut = ?,
ValidateurId = NULL,
ValidateurADId = ?,
DateValidation = NOW(),
CommentaireValidation = ?
WHERE Id = ?
";
}
$stmtCheck->close();
$stmtUpdate = $conn->prepare($queryUpdate);
$stmtUpdate->bind_param("sisi", $newStatus, $validatorId, $comment, $requestId);
$stmtUpdate->execute();
$stmtUpdate->close();
// 🔹 Déduction solde (seulement Users, pas AD, hors maladie)
if ($action === 'approve' && $typeNom !== 'Congé maladie' && $employeeId) {
$currentDate = new DateTime();
$year = ($typeNom === 'Congé payé' && (int)$currentDate->format('m') < 6)
? $currentDate->format('Y') - 1
: $currentDate->format('Y');
$queryDeduct = "
UPDATE CompteurConges
SET Solde = GREATEST(0, Solde - ?)
WHERE EmployeeId = ? AND TypeCongeId = ? AND Annee = ?
";
$stmtDeduct = $conn->prepare($queryDeduct);
$stmtDeduct->bind_param("diii", $nombreJours, $employeeId, $typeCongeId, $year);
$stmtDeduct->execute();
$stmtDeduct->close();
}
// 🔹 Notification (User ou CollaborateurAD)
$notificationTitle = ($action === 'approve') ? 'Demande approuvée' : 'Demande refusée';
$notificationMessage = "Votre demande de $typeNom a été " . (($action === 'approve') ? "approuvée" : "refusée");
if ($comment) $notificationMessage .= " (Commentaire: $comment)";
$notifType = ($action === 'approve') ? 'Success' : 'Error';
if ($employeeId) {
$queryNotif = "
INSERT INTO Notifications (UserId, CollaborateurADId, Titre, Message, Type, DemandeCongeId)
VALUES (?, NULL, ?, ?, ?, ?)
";
$stmtNotif = $conn->prepare($queryNotif);
$stmtNotif->bind_param("isssi", $employeeId, $notificationTitle, $notificationMessage, $notifType, $requestId);
$stmtNotif->execute();
$stmtNotif->close();
} elseif ($collaborateurId) {
$queryNotif = "
INSERT INTO Notifications (UserId, CollaborateurADId, Titre, Message, Type, DemandeCongeId)
VALUES (NULL, ?, ?, ?, ?, ?)
";
$stmtNotif = $conn->prepare($queryNotif);
$stmtNotif->bind_param("isssi", $collaborateurId, $notificationTitle, $notificationMessage, $notifType, $requestId);
$stmtNotif->execute();
$stmtNotif->close();
}
// 🔹 Historique (User ou CollaborateurAD)
$actionText = ($action === 'approve') ? 'Validation congé' : 'Refus congé';
$actionDetails = "$actionText $employeeName ($typeNom)";
if ($comment) $actionDetails .= " - $comment";
if ($isUserValidator) {
$queryHistory = "
INSERT INTO HistoriqueActions (UserId, CollaborateurADId, Action, Details, DemandeCongeId)
VALUES (?, NULL, ?, ?, ?)
";
$stmtHistory = $conn->prepare($queryHistory);
$stmtHistory->bind_param("issi", $validatorId, $actionText, $actionDetails, $requestId);
} else {
$queryHistory = "
INSERT INTO HistoriqueActions (UserId, CollaborateurADId, Action, Details, DemandeCongeId)
VALUES (NULL, ?, ?, ?, ?)
";
$stmtHistory = $conn->prepare($queryHistory);
$stmtHistory->bind_param("issi", $validatorId, $actionText, $actionDetails, $requestId);
}
$stmtHistory->execute();
$stmtHistory->close();
$conn->commit();
echo json_encode([
"success" => true,
"message" => "Demande " . (($action === 'approve') ? 'approuvée' : 'refusée'),
"new_status" => $newStatus
]);
} catch (Exception $e) {
$conn->rollback();
error_log("Erreur validateRequest: " . $e->getMessage());
echo json_encode([
"success" => false,
"message" => "Erreur lors de la validation: " . $e->getMessage()
]);
echo json_encode(["success" => false, "message" => $e->getMessage()]);
}
$conn->close();
?>
?>