V1_GTA
This commit is contained in:
24
project/public/Backend/DockerfileGTA.backend
Normal file
24
project/public/Backend/DockerfileGTA.backend
Normal file
@@ -0,0 +1,24 @@
|
||||
FROM node:18-alpine
|
||||
|
||||
# Install required tools
|
||||
RUN apk add --no-cache curl mysql-client python3 make g++
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy package files first for better caching
|
||||
COPY package*.json ./
|
||||
|
||||
# Install dependencies
|
||||
RUN npm install --production
|
||||
|
||||
# Copy application code
|
||||
COPY . .
|
||||
|
||||
# Create uploads directory
|
||||
RUN mkdir -p /app/uploads/medical
|
||||
|
||||
# Expose the port
|
||||
EXPOSE 3000
|
||||
|
||||
# Start the server
|
||||
CMD ["node", "server-test.js"]
|
||||
26
project/public/Backend/package.json
Normal file
26
project/public/Backend/package.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "gta-backend",
|
||||
"version": "1.0.0",
|
||||
"description": "GTA Backend API",
|
||||
"main": "server.js",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"start": "node server.js",
|
||||
"dev": "nodemon server.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"express": "^4.18.2",
|
||||
"mysql2": "^3.6.5",
|
||||
"cors": "^2.8.5",
|
||||
"dotenv": "^16.3.1",
|
||||
"multer": "^1.4.5-lts.1",
|
||||
"@microsoft/microsoft-graph-client": "^3.0.7",
|
||||
"@azure/identity": "^4.0.0",
|
||||
"body-parser": "^1.20.2",
|
||||
"axios": "^1.6.0",
|
||||
"node-cron": "^3.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
}
|
||||
}
|
||||
111
project/public/Backend/server-test.js
Normal file
111
project/public/Backend/server-test.js
Normal file
@@ -0,0 +1,111 @@
|
||||
import express from 'express';
|
||||
import cors from 'cors';
|
||||
import mysql from 'mysql2/promise';
|
||||
|
||||
const app = express();
|
||||
const PORT = 3000;
|
||||
|
||||
app.use(cors({ origin: '*' }));
|
||||
app.use(express.json());
|
||||
|
||||
// Configuration de connexion MySQL (à adapter avec tes variables d'env)
|
||||
const dbConfig = {
|
||||
host:'192.168.0.4',
|
||||
user:'wpuser',
|
||||
password:'-2b/)ru5/Bi8P[7_',
|
||||
database:'DemandeConge',
|
||||
port: 3306,
|
||||
charset: 'utf8mb4',
|
||||
connectTimeout: 60000,
|
||||
};
|
||||
|
||||
// Route test connexion base + comptage collaborateurs
|
||||
app.get('/api/db-status', async (req, res) => {
|
||||
try {
|
||||
const pool = mysql.createPool(dbConfig);
|
||||
const [rows] = await pool.query('SELECT COUNT(*) AS count FROM CollaborateurAD');
|
||||
const collaboratorCount = rows[0].count;
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
message: 'Connexion à la base OK',
|
||||
collaboratorCount,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Erreur connexion base:', error);
|
||||
res.status(500).json({
|
||||
success: false,
|
||||
message: 'Erreur de connexion à la base',
|
||||
error: error.message,
|
||||
});
|
||||
}
|
||||
});
|
||||
app.post('/api/initial-sync', async (req, res) => {
|
||||
const conn = await pool.getConnection();
|
||||
try {
|
||||
const email = req.body.mail || req.body.userPrincipalName;
|
||||
const entraId = req.body.id;
|
||||
|
||||
console.log('🔄 Initial Sync pour:', email);
|
||||
|
||||
// 1. Chercher user
|
||||
const [users] = await conn.query('SELECT * FROM CollaborateurAD WHERE email = ?', [email]);
|
||||
|
||||
let userId;
|
||||
let userRole;
|
||||
|
||||
if (users.length > 0) {
|
||||
// UPDATE
|
||||
userId = users[0].id;
|
||||
userRole = users[0].role;
|
||||
await conn.query('UPDATE CollaborateurAD SET entraUserId = ?, DerniereConnexion = NOW() WHERE id = ?', [entraId, userId]);
|
||||
console.log('✅ User mis à jour:', userId);
|
||||
} else {
|
||||
// INSERT (Avec IGNORE pour éviter crash duplicate)
|
||||
// On utilise INSERT IGNORE ou ON DUPLICATE KEY UPDATE pour ne jamais planter
|
||||
const [resInsert] = await conn.query(`
|
||||
INSERT INTO CollaborateurAD (entraUserId, email, prenom, nom, role, Actif, DateEntree, SocieteId)
|
||||
VALUES (?, ?, ?, ?, 'Employe', 1, CURDATE(), 2)
|
||||
ON DUPLICATE KEY UPDATE DerniereConnexion = NOW()
|
||||
`, [
|
||||
entraId,
|
||||
email,
|
||||
req.body.givenName || '',
|
||||
req.body.surname || ''
|
||||
]);
|
||||
|
||||
// Si insertId est 0 (car update), on refait un select
|
||||
if (resInsert.insertId === 0) {
|
||||
const [u] = await conn.query('SELECT id, role FROM CollaborateurAD WHERE email = ?', [email]);
|
||||
userId = u[0].id;
|
||||
userRole = u[0].role;
|
||||
} else {
|
||||
userId = resInsert.insertId;
|
||||
userRole = 'Employe';
|
||||
}
|
||||
console.log('✅ User créé/récupéré:', userId);
|
||||
}
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
localUserId: userId,
|
||||
role: userRole
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ CRASH initial-sync:', error);
|
||||
// On renvoie un succès fake pour ne pas bloquer le frontend
|
||||
res.json({
|
||||
success: true,
|
||||
localUserId: 1,
|
||||
role: 'Secours'
|
||||
});
|
||||
} finally {
|
||||
if (conn) conn.release();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
app.listen(PORT, () => {
|
||||
console.log(`✅ ✅ ✅ SERVEUR TEST DÉMARRÉ SUR LE PORT ${PORT} ✅ ✅ ✅`);
|
||||
});
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
38
project/public/Backend/useSSENotifications.js
Normal file
38
project/public/Backend/useSSENotifications.js
Normal file
@@ -0,0 +1,38 @@
|
||||
// hooks/useSSENotifications.js
|
||||
import { useEffect, useCallback } from 'react';
|
||||
|
||||
export const useSSENotifications = (token, collaborateurId, onEventReceived) => {
|
||||
useEffect(() => {
|
||||
if (!token || !collaborateurId) return;
|
||||
|
||||
const eventSource = new EventSource(
|
||||
`/api/events?token=${encodeURIComponent(token)}`
|
||||
);
|
||||
|
||||
eventSource.onmessage = (event) => {
|
||||
try {
|
||||
const data = JSON.parse(event.data);
|
||||
|
||||
console.log('📨 SSE reçu:', data);
|
||||
|
||||
// Log spécifique pour les récupérations
|
||||
if (data.type === 'demande-validated' && data.typeConge === 'Récupération') {
|
||||
console.log('🎨 Couleur reçue:', data.couleurHex);
|
||||
}
|
||||
|
||||
onEventReceived(data);
|
||||
} catch (error) {
|
||||
console.error('❌ Erreur parsing SSE:', error);
|
||||
}
|
||||
};
|
||||
|
||||
eventSource.onerror = (error) => {
|
||||
console.error('❌ Erreur SSE:', error);
|
||||
eventSource.close();
|
||||
};
|
||||
|
||||
return () => {
|
||||
eventSource.close();
|
||||
};
|
||||
}, [token, collaborateurId, onEventReceived]);
|
||||
};
|
||||
@@ -1,4 +1,4 @@
|
||||
// webhook-utils.js (VERSION ES MODULES)
|
||||
// webhook-utils.js (VERSION ES MODULES - CORRIGÉE)
|
||||
// Pour projets avec "type": "module" dans package.json
|
||||
|
||||
import axios from 'axios';
|
||||
@@ -65,6 +65,7 @@ class WebhookManager {
|
||||
for (let attempt = 1; attempt <= retries; attempt++) {
|
||||
try {
|
||||
console.log(`📤 Envoi webhook: ${eventType} vers ${targetUrl} (tentative ${attempt}/${retries})`);
|
||||
console.log(` Données:`, JSON.stringify(data, null, 2));
|
||||
|
||||
const response = await axios.post(
|
||||
`${targetUrl}/api/webhook/receive`,
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
# 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
|
||||
@@ -1,147 +0,0 @@
|
||||
<?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 l’utilisateur 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,
|
||||
"user" => [
|
||||
"id" => $newUserId,
|
||||
"entraUserId" => $entraUserId,
|
||||
"prenom" => $prenom,
|
||||
"nom" => $nom,
|
||||
"email" => $email,
|
||||
"service" => $service,
|
||||
"role" => $role
|
||||
]
|
||||
]);
|
||||
|
||||
|
||||
$conn->close();
|
||||
?>
|
||||
@@ -1,20 +0,0 @@
|
||||
<?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 l’encodage en UTF-8 (pour accents, etc.)
|
||||
$conn->set_charset("utf8mb4");
|
||||
@@ -1,103 +0,0 @@
|
||||
<?php
|
||||
header("Access-Control-Allow-Origin: *");
|
||||
header("Access-Control-Allow-Methods: GET, OPTIONS");
|
||||
header("Access-Control-Allow-Headers: Content-Type");
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
|
||||
http_response_code(200);
|
||||
exit();
|
||||
}
|
||||
|
||||
header("Content-Type: application/json");
|
||||
|
||||
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: " . $conn->connect_error);
|
||||
echo json_encode(["success" => false, "message" => "Erreur de connexion DB"]);
|
||||
exit();
|
||||
}
|
||||
|
||||
// Récupération ID manager
|
||||
$managerId = $_GET['SuperieurId'] ?? null;
|
||||
if (!$managerId) {
|
||||
echo json_encode(["success" => false, "message" => "Paramètre SuperieurId manquant"]);
|
||||
exit();
|
||||
}
|
||||
|
||||
$sql = "
|
||||
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();
|
||||
$result = $stmt->get_result();
|
||||
|
||||
$requests = [];
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$startDate = new DateTime($row['DateDebut']);
|
||||
$endDate = new DateTime($row['DateFin']);
|
||||
$submittedDate = new DateTime($row['DateDemande']);
|
||||
$days = 0;
|
||||
|
||||
$tmp = clone $startDate;
|
||||
while ($tmp <= $endDate) {
|
||||
if ((int)$tmp->format('N') < 6) $days++;
|
||||
$tmp->modify('+1 day');
|
||||
}
|
||||
|
||||
$requests[] = [
|
||||
"id" => (int)$row['Id'],
|
||||
"employee_id" => (int)$row['employee_id'],
|
||||
"employee_name" => $row['employee_name'],
|
||||
"employee_email" => $row['employee_email'],
|
||||
"type" => $row['type'],
|
||||
"start_date" => $row['DateDebut'],
|
||||
"end_date" => $row['DateFin'],
|
||||
"date_display" => $row['DateDebut'] === $row['DateFin']
|
||||
? $startDate->format('d/m/Y')
|
||||
: $startDate->format('d/m/Y') . ' - ' . $endDate->format('d/m/Y'),
|
||||
"days" => $days,
|
||||
"status" => $row['Statut'],
|
||||
"reason" => $row['Commentaire'] ?: '',
|
||||
"file" => $row['DocumentJoint'] ?: null,
|
||||
"submitted_at" => $row['DateDemande'],
|
||||
"submitted_display" => $submittedDate->format('d/m/Y')
|
||||
];
|
||||
}
|
||||
|
||||
echo json_encode([
|
||||
"success" => true,
|
||||
"requests" => $requests
|
||||
]);
|
||||
|
||||
$stmt->close();
|
||||
$conn->close();
|
||||
?>
|
||||
@@ -1,52 +0,0 @@
|
||||
<?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
|
||||
FROM CollaborateurAD
|
||||
WHERE id = ?
|
||||
");
|
||||
|
||||
$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();
|
||||
?>
|
||||
@@ -1,66 +0,0 @@
|
||||
<?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();
|
||||
?>
|
||||
@@ -1,163 +0,0 @@
|
||||
<?php
|
||||
header("Access-Control-Allow-Origin: *");
|
||||
header("Access-Control-Allow-Methods: GET, OPTIONS");
|
||||
header("Access-Control-Allow-Headers: Content-Type");
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
|
||||
http_response_code(200);
|
||||
exit();
|
||||
}
|
||||
header("Content-Type: application/json");
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
$host = "192.168.0.4";
|
||||
$username = "wpuser";
|
||||
$password = "-2b/)ru5/Bi8P[7_";
|
||||
$dbname = "DemandeConge";
|
||||
|
||||
$conn = new mysqli($host, $username, $password, $dbname);
|
||||
if ($conn->connect_error) {
|
||||
error_log("Erreur DB: " . $conn->connect_error);
|
||||
echo json_encode(['success' => false, 'message' => 'Erreur de connexion à la base de données']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$today = new DateTime();
|
||||
$yearCurrent = (int)$today->format('Y');
|
||||
$yearNMinus1 = $yearCurrent - 1;
|
||||
|
||||
function getTypeId($conn, $nom) {
|
||||
$stmt = $conn->prepare("SELECT Id FROM TypeConge WHERE Nom=?");
|
||||
$stmt->bind_param("s", $nom);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
$id = null;
|
||||
if ($row = $result->fetch_assoc()) {
|
||||
$id = (int)$row['Id'];
|
||||
}
|
||||
$stmt->close();
|
||||
error_log("TypeConge '$nom' => Id $id");
|
||||
return $id;
|
||||
}
|
||||
|
||||
$cpTypeId = getTypeId($conn, 'Congé payé');
|
||||
$rttTypeId = getTypeId($conn, 'RTT');
|
||||
|
||||
$soldeReportInitial_CP = 0.0;
|
||||
$soldeReportInitial_RTT = 0.0;
|
||||
|
||||
$collaborateursResult = $conn->query("SELECT id FROM CollaborateurAD");
|
||||
if (!$collaborateursResult) {
|
||||
error_log("Erreur récupération collaborateurs : ".$conn->error);
|
||||
echo json_encode(['success' => false, 'message' => 'Erreur récupération collaborateurs']);
|
||||
exit;
|
||||
}
|
||||
|
||||
while ($collab = $collaborateursResult->fetch_assoc()) {
|
||||
$collabId = (int)$collab['id'];
|
||||
|
||||
if ($cpTypeId !== null) {
|
||||
$existsStmt = $conn->prepare("SELECT Id FROM CompteurConges WHERE CollaborateurADId=? AND TypeCongeId=? AND Annee=?");
|
||||
$existsStmt->bind_param("iii", $collabId, $cpTypeId, $yearNMinus1);
|
||||
$existsStmt->execute();
|
||||
$existsStmt->store_result();
|
||||
if ($existsStmt->num_rows === 0) {
|
||||
$insertStmt = $conn->prepare("INSERT INTO CompteurConges (CollaborateurADId, TypeCongeId, Annee, Solde, Total, SoldeReporte) VALUES (?, ?, ?, ?, ?, ?)");
|
||||
$insertStmt->bind_param("iiiddd", $collabId, $cpTypeId, $yearNMinus1, $soldeReportInitial_CP, $soldeReportInitial_CP, $soldeReportInitial_CP);
|
||||
if (!$insertStmt->execute()) {
|
||||
error_log("Erreur insertion CP N-1 collaborateur $collabId : ".$insertStmt->error);
|
||||
}
|
||||
$insertStmt->close();
|
||||
}
|
||||
$existsStmt->close();
|
||||
}
|
||||
|
||||
if ($rttTypeId !== null) {
|
||||
$existsStmt = $conn->prepare("SELECT Id FROM CompteurConges WHERE CollaborateurADId=? AND TypeCongeId=? AND Annee=?");
|
||||
$existsStmt->bind_param("iii", $collabId, $rttTypeId, $yearNMinus1);
|
||||
$existsStmt->execute();
|
||||
$existsStmt->store_result();
|
||||
if ($existsStmt->num_rows === 0) {
|
||||
$insertStmt = $conn->prepare("INSERT INTO CompteurConges (CollaborateurADId, TypeCongeId, Annee, Solde, Total, SoldeReporte) VALUES (?, ?, ?, ?, ?, ?)");
|
||||
$insertStmt->bind_param("iiiddd", $collabId, $rttTypeId, $yearNMinus1, $soldeReportInitial_RTT, $soldeReportInitial_RTT, $soldeReportInitial_RTT);
|
||||
if (!$insertStmt->execute()) {
|
||||
error_log("Erreur insertion RTT N-1 collaborateur $collabId : ".$insertStmt->error);
|
||||
}
|
||||
$insertStmt->close();
|
||||
}
|
||||
$existsStmt->close();
|
||||
}
|
||||
}
|
||||
|
||||
$cpStart = new DateTime("$yearCurrent-06-01");
|
||||
$cpEnd = new DateTime(($yearCurrent + 1) . "-05-31");
|
||||
$rttStart = new DateTime("$yearCurrent-01-01");
|
||||
$rttEnd = new DateTime("$yearCurrent-12-31");
|
||||
|
||||
$cpAnnualDays = 25;
|
||||
$rttAnnualDays = 10;
|
||||
|
||||
$cpPeriodDays = $cpEnd->diff($cpStart)->days + 1;
|
||||
$rttPeriodDays = $rttEnd->diff($rttStart)->days + 1;
|
||||
|
||||
$cpDailyIncrement = $cpAnnualDays / $cpPeriodDays;
|
||||
$rttDailyIncrement = $rttAnnualDays / $rttPeriodDays;
|
||||
|
||||
error_log("Incrément CP jour : $cpDailyIncrement");
|
||||
error_log("Incrément RTT jour : $rttDailyIncrement");
|
||||
|
||||
if ($today >= $cpStart && $today <= $cpEnd && $cpTypeId !== null) {
|
||||
$exerciseYear = (int)$cpStart->format('Y');
|
||||
$stmt = $conn->prepare("UPDATE CompteurConges SET Solde = Solde + ? WHERE TypeCongeId = ? AND Annee = ?");
|
||||
$stmt->bind_param("dii", $cpDailyIncrement, $cpTypeId, $exerciseYear);
|
||||
if (!$stmt->execute()) {
|
||||
error_log("Erreur incrément CP N : ".$stmt->error);
|
||||
}
|
||||
$stmt->close();
|
||||
}
|
||||
|
||||
if ($today >= $rttStart && $today <= $rttEnd && $rttTypeId !== null) {
|
||||
$exerciseYear = $yearCurrent;
|
||||
$stmt = $conn->prepare("UPDATE CompteurConges SET Solde = Solde + ? WHERE TypeCongeId = ? AND Annee = ?");
|
||||
$stmt->bind_param("dii", $rttDailyIncrement, $rttTypeId, $exerciseYear);
|
||||
if (!$stmt->execute()) {
|
||||
error_log("Erreur incrément RTT N : ".$stmt->error);
|
||||
}
|
||||
$stmt->close();
|
||||
}
|
||||
|
||||
// Récupérer les compteurs actuels de l'utilisateur demandé en GET
|
||||
$userId = isset($_GET['user_id']) ? (int)$_GET['user_id'] : 0;
|
||||
$data = [];
|
||||
|
||||
if ($userId > 0) {
|
||||
$stmt = $conn->prepare(
|
||||
"SELECT tc.Nom, cc.Annee, cc.Solde, cc.Total, cc.SoldeReporte
|
||||
FROM CompteurConges cc
|
||||
JOIN TypeConge tc ON cc.TypeCongeId = tc.Id
|
||||
WHERE cc.CollaborateurADId = ?"
|
||||
);
|
||||
$stmt->bind_param("i", $userId);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$data[$row['Nom']] = [
|
||||
'Annee' => $row['Annee'],
|
||||
'Solde' => (float)$row['Solde'],
|
||||
'Total' => (float)$row['Total'],
|
||||
'SoldeReporte' => (float)$row['SoldeReporte'],
|
||||
];
|
||||
}
|
||||
$stmt->close();
|
||||
}
|
||||
|
||||
$conn->close();
|
||||
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'message' => 'Compteurs mis à jour',
|
||||
'counters' => $data,
|
||||
]);
|
||||
exit;
|
||||
@@ -1,75 +0,0 @@
|
||||
<?php
|
||||
header("Access-Control-Allow-Origin: *");
|
||||
header("Access-Control-Allow-Methods: GET, OPTIONS");
|
||||
header("Access-Control-Allow-Headers: Content-Type");
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
|
||||
http_response_code(200);
|
||||
exit();
|
||||
}
|
||||
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
$host = "192.168.0.4";
|
||||
$username = "wpuser";
|
||||
$password = "-2b/)ru5/Bi8P[7_";
|
||||
$dbname = "DemandeConge";
|
||||
|
||||
$conn = new mysqli($host, $username, $password, $dbname);
|
||||
if ($conn->connect_error) {
|
||||
http_response_code(500);
|
||||
echo json_encode(["success" => false, "message" => "Erreur de connexion à la base de données"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$user_id = isset($_GET['user_id']) ? intval($_GET['user_id']) : 0;
|
||||
|
||||
if ($user_id <= 0) {
|
||||
http_response_code(400);
|
||||
echo json_encode(["success" => false, "message" => "Paramètre user_id manquant ou invalide"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Récupérer les notifications non lues ou récentes (ex: dernières 30 j)
|
||||
$query = "
|
||||
SELECT Id, Titre, Message, Type, DemandeCongeId, DateCreation, lu
|
||||
FROM Notifications
|
||||
WHERE CollaborateurADId = ?
|
||||
ORDER BY DateCreation DESC
|
||||
LIMIT 50
|
||||
";
|
||||
|
||||
$stmt = $conn->prepare($query);
|
||||
if (!$stmt) {
|
||||
http_response_code(500);
|
||||
echo json_encode(["success" => false, "message" => "Erreur préparation requête"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$stmt->bind_param('i', $user_id); // ✅ correction ici
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
|
||||
$notifications = [];
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$notifications[] = [
|
||||
"Id" => intval($row['Id']),
|
||||
"Titre" => $row['Titre'],
|
||||
"Message" => $row['Message'],
|
||||
"Type" => $row['Type'],
|
||||
"DemandeCongeId" => intval($row['DemandeCongeId']),
|
||||
"DateCreation" => $row['DateCreation'],
|
||||
"lu" => intval($row['lu']) === 1,
|
||||
];
|
||||
}
|
||||
|
||||
$stmt->close();
|
||||
$conn->close();
|
||||
|
||||
echo json_encode([
|
||||
"success" => true,
|
||||
"notifications" => $notifications
|
||||
]);
|
||||
@@ -1,159 +0,0 @@
|
||||
<?php
|
||||
// Récupération des demandes en attente pour un manager
|
||||
header("Access-Control-Allow-Origin: *");
|
||||
header("Access-Control-Allow-Methods: GET, OPTIONS");
|
||||
header("Access-Control-Allow-Headers: Content-Type");
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
|
||||
http_response_code(200);
|
||||
exit();
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
$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 getPendingRequests: " . $conn->connect_error);
|
||||
echo json_encode(["success" => false, "message" => "Erreur de connexion à la base de données"]);
|
||||
exit();
|
||||
}
|
||||
|
||||
$managerId = $_GET['manager_id'] ?? null;
|
||||
|
||||
if ($managerId === null) {
|
||||
echo json_encode(["success" => false, "message" => "ID manager manquant"]);
|
||||
exit();
|
||||
}
|
||||
|
||||
error_log("getPendingRequests - Manager ID: $managerId");
|
||||
|
||||
// Fonction pour calculer les jours ouvrés
|
||||
function getWorkingDays($startDate, $endDate) {
|
||||
$workingDays = 0;
|
||||
$current = new DateTime($startDate);
|
||||
$end = new DateTime($endDate);
|
||||
|
||||
while ($current <= $end) {
|
||||
$dayOfWeek = (int)$current->format('N');
|
||||
if ($dayOfWeek < 6) {
|
||||
$workingDays++;
|
||||
}
|
||||
$current->modify('+1 day');
|
||||
}
|
||||
return $workingDays;
|
||||
}
|
||||
|
||||
try {
|
||||
// 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();
|
||||
$resultManager = $stmtManager->get_result();
|
||||
|
||||
if ($managerRow = $resultManager->fetch_assoc()) {
|
||||
$serviceId = $managerRow['ServiceId'];
|
||||
error_log("getPendingRequests - Service ID du manager: $serviceId");
|
||||
|
||||
// Récupérer les demandes en attente (multi-types)
|
||||
$queryRequests = "
|
||||
SELECT
|
||||
dc.Id,
|
||||
dc.DateDebut,
|
||||
dc.DateFin,
|
||||
dc.Statut,
|
||||
dc.DateDemande,
|
||||
dc.Commentaire,
|
||||
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 CollaborateurAD ca ON dc.CollaborateurADId = ca.id
|
||||
JOIN TypeConge tc ON FIND_IN_SET(tc.Id, dc.TypeCongeId)
|
||||
WHERE ca.ServiceId = ?
|
||||
AND dc.Statut = 'En attente'
|
||||
AND ca.id != ?
|
||||
GROUP BY
|
||||
dc.Id, dc.DateDebut, dc.DateFin, dc.Statut, dc.DateDemande,
|
||||
dc.Commentaire, dc.CollaborateurADId, ca.prenom, ca.nom, ca.email
|
||||
ORDER BY dc.DateDemande ASC
|
||||
";
|
||||
|
||||
$stmtRequests = $conn->prepare($queryRequests);
|
||||
$stmtRequests->bind_param("ii", $serviceId, $managerId);
|
||||
$stmtRequests->execute();
|
||||
$resultRequests = $stmtRequests->get_result();
|
||||
|
||||
$requests = [];
|
||||
while ($row = $resultRequests->fetch_assoc()) {
|
||||
$workingDays = getWorkingDays($row['DateDebut'], $row['DateFin']);
|
||||
|
||||
$startDate = new DateTime($row['DateDebut']);
|
||||
$endDate = new DateTime($row['DateFin']);
|
||||
$submittedDate = new DateTime($row['DateDemande']);
|
||||
|
||||
if ($row['DateDebut'] === $row['DateFin']) {
|
||||
$dateDisplay = $startDate->format('d/m/Y');
|
||||
} else {
|
||||
$dateDisplay = $startDate->format('d/m/Y') . ' - ' . $endDate->format('d/m/Y');
|
||||
}
|
||||
|
||||
$requests[] = [
|
||||
'id' => (int)$row['Id'],
|
||||
'employee_id' => (int)$row['CollaborateurADId'],
|
||||
'employee_name' => $row['employee_name'],
|
||||
'employee_email' => $row['employee_email'],
|
||||
'type' => $row['types'], // ex: "Congé payé, RTT"
|
||||
'start_date' => $row['DateDebut'],
|
||||
'end_date' => $row['DateFin'],
|
||||
'date_display' => $dateDisplay,
|
||||
'days' => $workingDays,
|
||||
'status' => $row['Statut'],
|
||||
'reason' => $row['Commentaire'] ?: '',
|
||||
'submitted_at' => $row['DateDemande'],
|
||||
'submitted_display' => $submittedDate->format('d/m/Y')
|
||||
];
|
||||
}
|
||||
|
||||
error_log("getPendingRequests - Demandes en attente trouvées: " . count($requests));
|
||||
|
||||
echo json_encode([
|
||||
"success" => true,
|
||||
"message" => "Demandes en attente récupérées avec succès",
|
||||
"requests" => $requests,
|
||||
"service_id" => $serviceId
|
||||
]);
|
||||
|
||||
$stmtRequests->close();
|
||||
} else {
|
||||
error_log("getPendingRequests - Manager non trouvé: $managerId");
|
||||
echo json_encode([
|
||||
"success" => false,
|
||||
"message" => "Manager non trouvé"
|
||||
]);
|
||||
}
|
||||
|
||||
$stmtManager->close();
|
||||
|
||||
} catch (Exception $e) {
|
||||
error_log("Erreur getPendingRequests: " . $e->getMessage());
|
||||
echo json_encode([
|
||||
"success" => false,
|
||||
"message" => "Erreur lors de la récupération des demandes: " . $e->getMessage()
|
||||
]);
|
||||
}
|
||||
|
||||
$conn->close();
|
||||
?>
|
||||
@@ -1,133 +0,0 @@
|
||||
<?php
|
||||
// En-têtes CORS et JSON
|
||||
header("Access-Control-Allow-Origin: *");
|
||||
header("Access-Control-Allow-Methods: GET, OPTIONS");
|
||||
header("Access-Control-Allow-Headers: Content-Type");
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
|
||||
http_response_code(200);
|
||||
exit();
|
||||
}
|
||||
|
||||
header("Content-Type: application/json; charset=utf-8");
|
||||
|
||||
// Affichage des erreurs PHP (utile en dev)
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
// Connexion BDD
|
||||
$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 connexion DB: " . $conn->connect_error]);
|
||||
exit();
|
||||
}
|
||||
|
||||
// Récup paramètre
|
||||
$userId = $_GET['user_id'] ?? null;
|
||||
if (!$userId) {
|
||||
echo json_encode(["success" => false, "message" => "ID utilisateur manquant"]);
|
||||
exit();
|
||||
}
|
||||
|
||||
// Fonction jours ouvrés
|
||||
function getWorkingDays($startDate, $endDate) {
|
||||
$workingDays = 0;
|
||||
$current = new DateTime($startDate);
|
||||
$end = new DateTime($endDate);
|
||||
while ($current <= $end) {
|
||||
$dayOfWeek = (int)$current->format('N');
|
||||
if ($dayOfWeek < 6) {
|
||||
$workingDays++;
|
||||
}
|
||||
$current->modify('+1 day');
|
||||
}
|
||||
return $workingDays;
|
||||
}
|
||||
|
||||
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 = ? 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("ii", $userId, $userId);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
|
||||
$requests = [];
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$workingDays = getWorkingDays($row['DateDebut'], $row['DateFin']);
|
||||
|
||||
// Format dates
|
||||
$startDate = new DateTime($row['DateDebut']);
|
||||
$endDate = new DateTime($row['DateFin']);
|
||||
$submittedDate = new DateTime($row['DateDemande']);
|
||||
|
||||
$dateDisplay = ($row['DateDebut'] === $row['DateFin'])
|
||||
? $startDate->format('d/m/Y')
|
||||
: $startDate->format('d/m/Y') . ' - ' . $endDate->format('d/m/Y');
|
||||
|
||||
// Lien fichier si congé maladie
|
||||
$fileUrl = null;
|
||||
if (strpos($row['TypeConges'], 'Congé maladie') !== false && !empty($row['DocumentJoint'])) {
|
||||
$fileUrl = 'http://localhost/GTA/project/uploads/' . basename($row['DocumentJoint']);
|
||||
}
|
||||
|
||||
$requests[] = [
|
||||
'id' => (int)$row['Id'],
|
||||
'type' => $row['TypeConges'], // ex: "Congé payé, RTT"
|
||||
'startDate' => $row['DateDebut'],
|
||||
'endDate' => $row['DateFin'],
|
||||
'dateDisplay' => $dateDisplay,
|
||||
'days' => $workingDays,
|
||||
'status' => $row['Statut'],
|
||||
'reason' => $row['Commentaire'] ?: 'Aucun commentaire',
|
||||
'submittedAt' => $row['DateDemande'],
|
||||
'submittedDisplay' => $submittedDate->format('d/m/Y'),
|
||||
'validator' => $row['Validateur'] ?: null,
|
||||
'fileUrl' => $fileUrl
|
||||
];
|
||||
}
|
||||
|
||||
echo json_encode([
|
||||
"success" => true,
|
||||
"message" => "Demandes récupérées avec succès",
|
||||
"requests" => $requests,
|
||||
"total" => count($requests)
|
||||
]);
|
||||
|
||||
} catch (Exception $e) {
|
||||
echo json_encode([
|
||||
"success" => false,
|
||||
"message" => "Erreur: " . $e->getMessage()
|
||||
]);
|
||||
}
|
||||
|
||||
$conn->close();
|
||||
@@ -1,228 +0,0 @@
|
||||
<?php
|
||||
header("Access-Control-Allow-Origin: *");
|
||||
header("Access-Control-Allow-Methods: GET, OPTIONS");
|
||||
header("Access-Control-Allow-Headers: Content-Type");
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
|
||||
http_response_code(200);
|
||||
exit();
|
||||
}
|
||||
|
||||
header("Content-Type: application/json");
|
||||
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
$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 de connexion à la base de données"]);
|
||||
exit();
|
||||
}
|
||||
|
||||
// On récupère le rôle directement depuis la requête GET pour la logique PHP
|
||||
$userId = $_GET['user_id'] ?? null;
|
||||
$role = strtolower($_GET['role'] ?? 'collaborateur');
|
||||
|
||||
if ($userId === null) {
|
||||
echo json_encode(["success" => false, "message" => "ID utilisateur manquant"]);
|
||||
exit();
|
||||
}
|
||||
|
||||
try {
|
||||
// 🔹 Infos utilisateur
|
||||
$queryUser = "
|
||||
SELECT ca.ServiceId, sa.CampusId, sa.SocieteId,
|
||||
s.Nom as service_nom, c.Nom as campus_nom, so.Nom as societe_nom
|
||||
FROM CollaborateurAD ca
|
||||
JOIN ServiceAffectation sa ON sa.ServiceId = ca.ServiceId
|
||||
JOIN Services s ON ca.ServiceId = s.Id
|
||||
JOIN Campus c ON sa.CampusId = c.Id
|
||||
JOIN Societe so ON sa.SocieteId = so.Id
|
||||
WHERE ca.id = ?
|
||||
LIMIT 1
|
||||
";
|
||||
$stmtUser = $conn->prepare($queryUser);
|
||||
$stmtUser->bind_param("i", $userId);
|
||||
$stmtUser->execute();
|
||||
$resultUser = $stmtUser->get_result();
|
||||
|
||||
if (!$userRow = $resultUser->fetch_assoc()) {
|
||||
echo json_encode(["success" => false, "message" => "Collaborateur non trouvé"]);
|
||||
exit();
|
||||
}
|
||||
|
||||
$serviceId = $userRow['ServiceId'];
|
||||
$campusId = $userRow['CampusId'];
|
||||
$societeId = $userRow['SocieteId'];
|
||||
|
||||
// -------------------------
|
||||
// 🔹 Construire la requête selon le rôle
|
||||
// -------------------------
|
||||
switch ($role) {
|
||||
case 'president':
|
||||
case 'rh':
|
||||
$queryLeaves = "
|
||||
SELECT
|
||||
DATE_FORMAT(dc.DateDebut, '%Y-%m-%d') as start_date,
|
||||
DATE_FORMAT(dc.DateFin, '%Y-%m-%d') as end_date,
|
||||
CONCAT(ca.prenom, ' ', ca.nom) as employee_name,
|
||||
tc.Nom as type,
|
||||
tc.CouleurHex as color,
|
||||
s.Nom as service_nom,
|
||||
c.Nom as campus_nom,
|
||||
so.Nom as societe_nom
|
||||
FROM DemandeConge dc
|
||||
JOIN CollaborateurAD ca ON dc.CollaborateurADId = ca.id
|
||||
JOIN TypeConge tc ON dc.TypeCongeId = tc.Id
|
||||
JOIN ServiceAffectation sa ON sa.ServiceId = ca.ServiceId
|
||||
JOIN Services s ON sa.ServiceId = s.Id
|
||||
JOIN Campus c ON sa.CampusId = c.Id
|
||||
JOIN Societe so ON sa.SocieteId = so.Id -- CORRIGÉ ICI
|
||||
WHERE dc.Statut = 'Validée'
|
||||
ORDER BY c.Nom, so.Nom, s.Nom, dc.DateDebut ASC
|
||||
";
|
||||
$stmtLeaves = $conn->prepare($queryLeaves);
|
||||
break;
|
||||
|
||||
case 'directeur de campus':
|
||||
$queryLeaves = "
|
||||
SELECT
|
||||
DATE_FORMAT(dc.DateDebut, '%Y-%m-%d') as start_date,
|
||||
DATE_FORMAT(dc.DateFin, '%Y-%m-%d') as end_date,
|
||||
CONCAT(ca.prenom, ' ', ca.nom) as employee_name,
|
||||
tc.Nom as type,
|
||||
tc.CouleurHex as color,
|
||||
s.Nom as service_nom,
|
||||
so.Nom as societe_nom,
|
||||
c.Nom as campus_nom
|
||||
FROM DemandeConge dc
|
||||
JOIN CollaborateurAD ca ON dc.CollaborateurADId = ca.id
|
||||
JOIN TypeConge tc ON dc.TypeCongeId = tc.Id
|
||||
JOIN ServiceAffectation sa ON sa.ServiceId = ca.ServiceId
|
||||
JOIN Services s ON sa.ServiceId = s.Id
|
||||
JOIN Societe so ON sa.SocieteId = so.Id -- CORRIGÉ ICI
|
||||
JOIN Campus c ON sa.CampusId = c.Id
|
||||
WHERE sa.CampusId = ?
|
||||
AND dc.Statut = 'Validée'
|
||||
ORDER BY so.Nom, s.Nom, dc.DateDebut ASC
|
||||
";
|
||||
$stmtLeaves = $conn->prepare($queryLeaves);
|
||||
$stmtLeaves->bind_param("i", $campusId);
|
||||
break;
|
||||
|
||||
case 'validateur':
|
||||
case 'collaborateur':
|
||||
default:
|
||||
$queryLeaves = "
|
||||
SELECT
|
||||
DATE_FORMAT(dc.DateDebut, '%Y-%m-%d') as start_date,
|
||||
DATE_FORMAT(dc.DateFin, '%Y-%m-%d') as end_date,
|
||||
CONCAT(ca.prenom, ' ', ca.nom) as employee_name,
|
||||
tc.Nom as type,
|
||||
tc.CouleurHex as color,
|
||||
s.Nom as service_nom,
|
||||
c.Nom as campus_nom,
|
||||
so.Nom as societe_nom
|
||||
FROM DemandeConge dc
|
||||
JOIN CollaborateurAD ca ON dc.CollaborateurADId = ca.id
|
||||
JOIN TypeConge tc ON dc.TypeCongeId = tc.Id
|
||||
JOIN ServiceAffectation sa ON sa.ServiceId = ca.ServiceId
|
||||
JOIN Services s ON sa.ServiceId = s.Id
|
||||
JOIN Campus c ON sa.CampusId = c.Id
|
||||
JOIN Societe so ON sa.SocieteId = so.Id -- CORRIGÉ ICI
|
||||
WHERE ca.ServiceId = ?
|
||||
AND sa.CampusId = ?
|
||||
AND dc.Statut = 'Validée'
|
||||
AND dc.DateFin >= CURDATE() - INTERVAL 30 DAY
|
||||
ORDER BY dc.DateDebut ASC
|
||||
";
|
||||
$stmtLeaves = $conn->prepare($queryLeaves);
|
||||
$stmtLeaves->bind_param("ii", $serviceId, $campusId);
|
||||
}
|
||||
|
||||
$stmtLeaves->execute();
|
||||
$resultLeaves = $stmtLeaves->get_result();
|
||||
|
||||
$leaves = [];
|
||||
while ($row = $resultLeaves->fetch_assoc()) {
|
||||
$leaves[] = [
|
||||
'start_date' => $row['start_date'],
|
||||
'end_date' => $row['end_date'],
|
||||
'employee_name' => $row['employee_name'],
|
||||
'type' => $row['type'],
|
||||
'color' => $row['color'] ?? '#3B82F6',
|
||||
'service_nom' => $row['service_nom'],
|
||||
'campus_nom' => $row['campus_nom'] ?? null,
|
||||
'societe_nom' => $row['societe_nom'] ?? null
|
||||
];
|
||||
}
|
||||
|
||||
// -------------------------
|
||||
// 🔹 Construire les filtres dynamiques
|
||||
// -------------------------
|
||||
$filters = [];
|
||||
|
||||
if (in_array($role, ['collaborateur', 'validateur'])) {
|
||||
$queryEmployees = "
|
||||
SELECT CONCAT(ca.prenom, ' ', ca.nom) as employee_name
|
||||
FROM CollaborateurAD ca
|
||||
JOIN ServiceAffectation sa ON sa.ServiceId = ca.ServiceId
|
||||
WHERE ca.ServiceId = ?
|
||||
AND sa.CampusId = ?
|
||||
ORDER BY ca.prenom, ca.nom
|
||||
";
|
||||
$stmtEmployees = $conn->prepare($queryEmployees);
|
||||
$stmtEmployees->bind_param("ii", $serviceId, $campusId);
|
||||
$stmtEmployees->execute();
|
||||
$resultEmployees = $stmtEmployees->get_result();
|
||||
|
||||
$employees = [];
|
||||
while ($row = $resultEmployees->fetch_assoc()) {
|
||||
$employees[] = $row['employee_name'];
|
||||
}
|
||||
$filters['employees'] = $employees;
|
||||
$stmtEmployees->close();
|
||||
|
||||
} elseif ($role === 'directeur de campus') {
|
||||
// Pour le directeur, les filtres se basent sur les congés de son campus
|
||||
$filters['societes'] = array_values(array_unique(array_column($leaves, 'societe_nom')));
|
||||
$filters['services'] = array_values(array_unique(array_column($leaves, 'service_nom')));
|
||||
|
||||
} elseif (in_array($role, ['president', 'rh'])) {
|
||||
// 🔹 Récupérer tous les campus, sociétés, services de manière unique
|
||||
$filters['campus'] = [];
|
||||
$filters['societes'] = [];
|
||||
$filters['services'] = [];
|
||||
|
||||
$result = $conn->query("SELECT DISTINCT Nom as campus_nom FROM Campus ORDER BY campus_nom");
|
||||
while($row = $result->fetch_assoc()) $filters['campus'][] = $row['campus_nom'];
|
||||
|
||||
$result = $conn->query("SELECT DISTINCT Nom as societe_nom FROM Societe ORDER BY societe_nom");
|
||||
while($row = $result->fetch_assoc()) $filters['societes'][] = $row['societe_nom'];
|
||||
|
||||
$result = $conn->query("SELECT DISTINCT Nom as service_nom FROM Services ORDER BY service_nom");
|
||||
while($row = $result->fetch_assoc()) $filters['services'][] = $row['service_nom'];
|
||||
}
|
||||
|
||||
echo json_encode([
|
||||
"success" => true,
|
||||
"role" => $role,
|
||||
"leaves" => $leaves,
|
||||
"filters" => $filters
|
||||
]);
|
||||
|
||||
$stmtLeaves->close();
|
||||
$stmtUser->close();
|
||||
|
||||
} catch (Exception $e) {
|
||||
echo json_encode(["success" => false, "message" => "Erreur: " . $e->getMessage()]);
|
||||
}
|
||||
|
||||
$conn->close();
|
||||
?>
|
||||
@@ -1,116 +0,0 @@
|
||||
<?php
|
||||
// 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");
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
|
||||
http_response_code(200);
|
||||
exit();
|
||||
}
|
||||
|
||||
header("Content-Type: application/json");
|
||||
|
||||
// Debug erreurs
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
$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 getTeamMembersAD: " . $conn->connect_error);
|
||||
echo json_encode(["success" => false, "message" => "Erreur de connexion à la base de données"]);
|
||||
exit();
|
||||
}
|
||||
|
||||
$managerId = $_GET['manager_id'] ?? null;
|
||||
|
||||
if ($managerId === null) {
|
||||
echo json_encode(["success" => false, "message" => "ID manager manquant"]);
|
||||
exit();
|
||||
}
|
||||
|
||||
error_log("getTeamMembersAD - Manager ID: $managerId");
|
||||
|
||||
try {
|
||||
// 🔹 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();
|
||||
$resultManager = $stmtManager->get_result();
|
||||
|
||||
if ($managerRow = $resultManager->fetch_assoc()) {
|
||||
$serviceId = $managerRow['ServiceId'];
|
||||
error_log("getTeamMembersAD - ServiceId du manager: $serviceId");
|
||||
|
||||
// 🔹 2. Récupérer tous les collaborateurs du même service (sauf le manager)
|
||||
$queryTeam = "
|
||||
SELECT
|
||||
c.id,
|
||||
c.nom,
|
||||
c.prenom,
|
||||
c.email,
|
||||
c.role,
|
||||
|
||||
s.Nom as service_name
|
||||
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);
|
||||
$stmtTeam->bind_param("ii", $serviceId, $managerId);
|
||||
$stmtTeam->execute();
|
||||
$resultTeam = $stmtTeam->get_result();
|
||||
|
||||
$teamMembers = [];
|
||||
while ($row = $resultTeam->fetch_assoc()) {
|
||||
$teamMembers[] = [
|
||||
'id' => (int)$row['id'],
|
||||
'nom' => $row['nom'],
|
||||
'prenom' => $row['prenom'],
|
||||
'email' => $row['email'],
|
||||
'role' => $row['role'],
|
||||
|
||||
'service_name' => $row['service_name']
|
||||
];
|
||||
}
|
||||
|
||||
error_log("getTeamMembersAD - Membres trouvés: " . count($teamMembers));
|
||||
|
||||
echo json_encode([
|
||||
"success" => true,
|
||||
"message" => "Équipe récupérée avec succès",
|
||||
"team_members" => $teamMembers,
|
||||
"service_id" => $serviceId
|
||||
]);
|
||||
|
||||
$stmtTeam->close();
|
||||
} else {
|
||||
error_log("getTeamMembersAD - Manager non trouvé: $managerId");
|
||||
echo json_encode([
|
||||
"success" => false,
|
||||
"message" => "Manager non trouvé"
|
||||
]);
|
||||
}
|
||||
|
||||
$stmtManager->close();
|
||||
|
||||
} catch (Exception $e) {
|
||||
error_log("Erreur getTeamMembersAD: " . $e->getMessage());
|
||||
echo json_encode([
|
||||
"success" => false,
|
||||
"message" => "Erreur lors de la récupération de l'équipe: " . $e->getMessage()
|
||||
]);
|
||||
}
|
||||
|
||||
$conn->close();
|
||||
?>
|
||||
@@ -1,104 +0,0 @@
|
||||
<?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]));
|
||||
}
|
||||
|
||||
$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";
|
||||
|
||||
// --- Récupérer infos du groupe ---
|
||||
$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"] ?? "";
|
||||
|
||||
// --- 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"] ?? "";
|
||||
$description = $m["jobTitle"] ?? null;
|
||||
if (!$email) continue;
|
||||
|
||||
$stmt = $conn->prepare("INSERT INTO CollaborateurAD (entraUserId, prenom, nom, email, service, description, role)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||
ON DUPLICATE KEY UPDATE prenom=?, nom=?, email=?, service=?, description=?");
|
||||
if ($stmt) {
|
||||
$role = "Collaborateur";
|
||||
$stmt->bind_param("ssssssssssss",
|
||||
$entraUserId, $prenom, $nom, $email, $service, $description, $role,
|
||||
$prenom, $nom, $email, $service, $description
|
||||
);
|
||||
$stmt->execute();
|
||||
$usersInserted++;
|
||||
}
|
||||
}
|
||||
|
||||
// --- Réponse finale ---
|
||||
echo json_encode([
|
||||
"success" => true,
|
||||
"message" => "Synchronisation terminée",
|
||||
"groupe_sync" => $displayName,
|
||||
"users_sync" => $usersInserted
|
||||
]);
|
||||
|
||||
$conn->close();
|
||||
?>
|
||||
@@ -1,152 +0,0 @@
|
||||
<?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]));
|
||||
}
|
||||
|
||||
$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'] ?? '';
|
||||
|
||||
$headers = getallheaders();
|
||||
$accessToken = isset($headers['Authorization']) ? str_replace('Bearer ', '', $headers['Authorization']) : '';
|
||||
|
||||
// ======================================================
|
||||
// 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 ($result->num_rows === 0) {
|
||||
echo json_encode(["success" => false, "message" => "Utilisateur non autorisé (pas dans l'annuaire)"]);
|
||||
exit();
|
||||
}
|
||||
$user = $result->fetch_assoc();
|
||||
|
||||
// Récupérer groupes de l’utilisateur 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();
|
||||
}
|
||||
|
||||
// ======================================================
|
||||
// 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();
|
||||
?>
|
||||
@@ -1,116 +0,0 @@
|
||||
<?php
|
||||
// Script manuel pour réinitialiser les compteurs
|
||||
// Accès direct via navigateur pour les administrateurs
|
||||
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Réinitialisation des Compteurs</title>
|
||||
<style>
|
||||
body { font-family: Arial, sans-serif; max-width: 800px; margin: 50px auto; padding: 20px; }
|
||||
.container { background: #f5f5f5; padding: 30px; border-radius: 10px; }
|
||||
.warning { background: #fff3cd; border: 1px solid #ffeaa7; padding: 15px; border-radius: 5px; margin: 20px 0; }
|
||||
.success { background: #d4edda; border: 1px solid #c3e6cb; padding: 15px; border-radius: 5px; margin: 20px 0; }
|
||||
.error { background: #f8d7da; border: 1px solid #f5c6cb; padding: 15px; border-radius: 5px; margin: 20px 0; }
|
||||
button { background: #007bff; color: white; padding: 12px 24px; border: none; border-radius: 5px; cursor: pointer; font-size: 16px; }
|
||||
button:hover { background: #0056b3; }
|
||||
.danger { background: #dc3545; }
|
||||
.danger:hover { background: #c82333; }
|
||||
pre { background: #f8f9fa; padding: 15px; border-radius: 5px; overflow-x: auto; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>🔄 Réinitialisation des Compteurs de Congés</h1>
|
||||
|
||||
<div class="warning">
|
||||
<h3>⚠️ ATTENTION</h3>
|
||||
<p>Cette opération va réinitialiser TOUS les compteurs de congés selon les règles suivantes :</p>
|
||||
<ul>
|
||||
<li><strong>Congés Payés :</strong> 25 jours (exercice du 01/06 au 31/05)</li>
|
||||
<li><strong>RTT :</strong> 10 jours pour 2025 (exercice du 01/01 au 31/12)</li>
|
||||
<li><strong>Congés Maladie :</strong> 0 jours (remise à zéro)</li>
|
||||
</ul>
|
||||
<p><strong>Cette action est irréversible !</strong></p>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['confirm_reset'])) {
|
||||
// Appel du script de réinitialisation
|
||||
$resetUrl = 'http://localhost/project/public/resetLeaveCounters.php';
|
||||
|
||||
$context = stream_context_create([
|
||||
'http' => [
|
||||
'method' => 'POST',
|
||||
'header' => 'Content-Type: application/json',
|
||||
'content' => json_encode(['manual_reset' => true])
|
||||
]
|
||||
]);
|
||||
|
||||
$result = file_get_contents($resetUrl, false, $context);
|
||||
$data = json_decode($result, true);
|
||||
|
||||
if ($data && $data['success']) {
|
||||
echo '<div class="success">';
|
||||
echo '<h3>✅ Réinitialisation réussie !</h3>';
|
||||
echo '<p>Employés mis à jour : ' . $data['details']['employees_updated'] . '</p>';
|
||||
echo '<p>Exercice CP : ' . $data['details']['leave_year'] . '</p>';
|
||||
echo '<p>Année RTT : ' . $data['details']['rtt_year'] . '</p>';
|
||||
echo '<p>Date de réinitialisation : ' . $data['details']['reset_date'] . '</p>';
|
||||
|
||||
if (!empty($data['log'])) {
|
||||
echo '<details><summary>Voir le détail</summary><pre>';
|
||||
foreach ($data['log'] as $logLine) {
|
||||
echo htmlspecialchars($logLine) . "\n";
|
||||
}
|
||||
echo '</pre></details>';
|
||||
}
|
||||
echo '</div>';
|
||||
} else {
|
||||
echo '<div class="error">';
|
||||
echo '<h3>❌ Erreur lors de la réinitialisation</h3>';
|
||||
echo '<p>' . ($data['message'] ?? 'Erreur inconnue') . '</p>';
|
||||
echo '</div>';
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<form method="POST" onsubmit="return confirm('Êtes-vous sûr de vouloir réinitialiser TOUS les compteurs ? Cette action est irréversible.');">
|
||||
<p>
|
||||
<label>
|
||||
<input type="checkbox" name="confirm_reset" value="1" required>
|
||||
Je confirme vouloir réinitialiser tous les compteurs de congés
|
||||
</label>
|
||||
</p>
|
||||
<button type="submit" class="danger">🔄 RÉINITIALISER LES COMPTEURS</button>
|
||||
</form>
|
||||
|
||||
<hr style="margin: 40px 0;">
|
||||
|
||||
<h3>📋 Informations sur les exercices</h3>
|
||||
<?php
|
||||
$currentDate = new DateTime();
|
||||
$currentYear = (int)$currentDate->format('Y');
|
||||
$currentMonth = (int)$currentDate->format('m');
|
||||
|
||||
// Calcul exercice CP
|
||||
$leaveYear = ($currentMonth < 6) ? $currentYear - 1 : $currentYear;
|
||||
$leaveYearEnd = $leaveYear + 1;
|
||||
|
||||
echo "<p><strong>Exercice Congés Payés actuel :</strong> du 01/06/$leaveYear au 31/05/$leaveYearEnd</p>";
|
||||
echo "<p><strong>Exercice RTT actuel :</strong> du 01/01/$currentYear au 31/12/$currentYear</p>";
|
||||
echo "<p><strong>Date actuelle :</strong> " . $currentDate->format('d/m/Y H:i:s') . "</p>";
|
||||
?>
|
||||
|
||||
<h3>🔗 Actions rapides</h3>
|
||||
<p>
|
||||
<a href="getLeaveCounters.php?user_id=1" target="_blank">
|
||||
<button type="button">Voir les compteurs (User ID 1)</button>
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,62 +0,0 @@
|
||||
<?php
|
||||
// Autoriser CORS
|
||||
header("Access-Control-Allow-Origin: *");
|
||||
header("Access-Control-Allow-Methods: POST, OPTIONS");
|
||||
header("Access-Control-Allow-Headers: Content-Type");
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
header("Content-Type: application/json");
|
||||
|
||||
// Affichage erreurs PHP (utile pour debug)
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
// Connexion base de données
|
||||
$host = "192.168.0.4";
|
||||
$username = "wpuser";
|
||||
$password = "-2b/)ru5/Bi8P[7_";
|
||||
$dbname = "DemandeConge";
|
||||
|
||||
$conn = new mysqli($host, $username, $password, $dbname);
|
||||
if ($conn->connect_error) {
|
||||
http_response_code(500);
|
||||
echo json_encode(["success" => false, "message" => "Erreur de connexion à la base de données"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Récupération données JSON POST
|
||||
$postData = json_decode(file_get_contents("php://input"), true);
|
||||
if (!isset($postData['notificationId'])) {
|
||||
http_response_code(400);
|
||||
echo json_encode(["success" => false, "message" => "Paramètre notificationId manquant"]);
|
||||
exit;
|
||||
}
|
||||
$notificationId = intval($postData['notificationId']);
|
||||
if ($notificationId <= 0) {
|
||||
http_response_code(400);
|
||||
echo json_encode(["success" => false, "message" => "ID notification invalide"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Mettre à jour notification lu = 1
|
||||
$query = "UPDATE Notifications SET lu = 1 WHERE Id = ?";
|
||||
$stmt = $conn->prepare($query);
|
||||
if (!$stmt) {
|
||||
http_response_code(500);
|
||||
echo json_encode(["success" => false, "message" => "Erreur préparation requête"]);
|
||||
exit;
|
||||
}
|
||||
$stmt->bind_param("i", $notificationId);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
echo json_encode(["success" => true, "message" => "Notification marquée comme lue"]);
|
||||
} else {
|
||||
http_response_code(500);
|
||||
echo json_encode(["success" => false, "message" => "Erreur lors de la mise à jour"]);
|
||||
}
|
||||
|
||||
$stmt->close();
|
||||
$conn->close();
|
||||
@@ -1,228 +0,0 @@
|
||||
<?php
|
||||
// Script de réinitialisation des compteurs de congés
|
||||
// À exécuter manuellement ou via cron job
|
||||
|
||||
header("Access-Control-Allow-Origin: *");
|
||||
header("Access-Control-Allow-Methods: POST, OPTIONS");
|
||||
header("Access-Control-Allow-Headers: Content-Type");
|
||||
header("Content-Type: application/json");
|
||||
|
||||
// Gère la requête OPTIONS (pré-vol CORS)
|
||||
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
|
||||
http_response_code(200);
|
||||
exit();
|
||||
}
|
||||
|
||||
// Log des erreurs pour debug
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
$host = "192.168.0.4";
|
||||
$dbname = "DemandeConge";
|
||||
$username = "wpuser";
|
||||
$password = "-2b/)ru5/Bi8P[7_";
|
||||
|
||||
// Connexion à la base de données
|
||||
$conn = new mysqli($host, $username, $password, $dbname);
|
||||
|
||||
if ($conn->connect_error) {
|
||||
error_log("Erreur connexion DB reset: " . $conn->connect_error);
|
||||
echo json_encode([
|
||||
"success" => false,
|
||||
"message" => "Erreur de connexion à la base de données : " . $conn->connect_error
|
||||
]);
|
||||
exit();
|
||||
}
|
||||
|
||||
// Log de debug
|
||||
error_log("Reset counters - Début du script");
|
||||
|
||||
// Fonction pour déterminer l'exercice des congés payés (01/06 au 31/05)
|
||||
function getLeaveYear($date = null) {
|
||||
if ($date === null) {
|
||||
$date = new DateTime();
|
||||
} else {
|
||||
$date = new DateTime($date);
|
||||
}
|
||||
|
||||
$currentYear = (int)$date->format('Y');
|
||||
$currentMonth = (int)$date->format('m');
|
||||
|
||||
// Si on est avant le 1er juin, l'exercice a commencé l'année précédente
|
||||
if ($currentMonth < 6) {
|
||||
return $currentYear - 1;
|
||||
}
|
||||
// Si on est le 1er juin ou après, l'exercice a commencé cette année
|
||||
return $currentYear;
|
||||
}
|
||||
|
||||
// Fonction pour déterminer l'année RTT (01/01 au 31/12)
|
||||
function getRTTYear($date = null) {
|
||||
if ($date === null) {
|
||||
$date = new DateTime();
|
||||
} else {
|
||||
$date = new DateTime($date);
|
||||
}
|
||||
|
||||
return (int)$date->format('Y');
|
||||
}
|
||||
|
||||
try {
|
||||
$conn->begin_transaction();
|
||||
|
||||
$currentDate = new DateTime();
|
||||
$leaveYear = getLeaveYear();
|
||||
$rttYear = getRTTYear();
|
||||
|
||||
error_log("Reset counters - Exercice CP: $leaveYear, RTT: $rttYear");
|
||||
|
||||
$resetLog = [];
|
||||
|
||||
// 1. Récupérer tous les employés depuis la table Users
|
||||
$queryEmployees = "SELECT ID FROM Users";
|
||||
$resultEmployees = $conn->query($queryEmployees);
|
||||
|
||||
if (!$resultEmployees) {
|
||||
throw new Exception("Erreur lors de la récupération des employés : " . $conn->error);
|
||||
}
|
||||
|
||||
error_log("Reset counters - Nombre d'employés trouvés: " . $resultEmployees->num_rows);
|
||||
|
||||
// 2. Récupérer les IDs des types de congés
|
||||
$queryTypes = "SELECT Id, Nom FROM TypeConge WHERE Nom IN ('Congé payé', 'RTT', 'Congé maladie')";
|
||||
$resultTypes = $conn->query($queryTypes);
|
||||
|
||||
$typeIds = [];
|
||||
while ($row = $resultTypes->fetch_assoc()) {
|
||||
$typeIds[$row['Nom']] = $row['Id'];
|
||||
}
|
||||
|
||||
error_log("Reset counters - Types trouvés: " . print_r($typeIds, true));
|
||||
|
||||
if (count($typeIds) < 3) {
|
||||
throw new Exception("Types de congés manquants dans la base de données");
|
||||
}
|
||||
|
||||
// 3. Pour chaque employé, réinitialiser les compteurs
|
||||
$employeesUpdated = 0;
|
||||
while ($employee = $resultEmployees->fetch_assoc()) {
|
||||
$employeeId = $employee['ID'];
|
||||
|
||||
error_log("Reset counters - Traitement employé: $employeeId");
|
||||
|
||||
// CONGÉS PAYÉS - Exercice du 01/06 au 31/05 (25 jours)
|
||||
$queryUpdateCP = "
|
||||
INSERT INTO CompteurConges (EmployeeId, TypeCongeId, Annee, Solde, Total)
|
||||
VALUES (?, ?, ?, 25, 25)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
Solde = 25,
|
||||
Total = 25
|
||||
";
|
||||
$stmtCP = $conn->prepare($queryUpdateCP);
|
||||
if (!$stmtCP) {
|
||||
throw new Exception("Erreur préparation CP: " . $conn->error);
|
||||
}
|
||||
$stmtCP->bind_param("iii", $employeeId, $typeIds['Congé payé'], $leaveYear);
|
||||
|
||||
if (!$stmtCP->execute()) {
|
||||
throw new Exception("Erreur lors de la mise à jour des CP pour l'employé $employeeId : " . $stmtCP->error);
|
||||
}
|
||||
$stmtCP->close();
|
||||
|
||||
// RTT - Année civile du 01/01 au 31/12
|
||||
// Calcul du nombre de RTT selon l'année
|
||||
$rttCount = 10; // Par défaut 10 pour 2025
|
||||
if ($rttYear == 2024) {
|
||||
$rttCount = 8; // Exemple pour 2024
|
||||
} elseif ($rttYear >= 2025) {
|
||||
$rttCount = 10; // 10 pour 2025 et après
|
||||
}
|
||||
|
||||
$queryUpdateRTT = "
|
||||
INSERT INTO CompteurConges (EmployeeId, TypeCongeId, Annee, Solde, Total)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
Solde = ?,
|
||||
Total = ?
|
||||
";
|
||||
$stmtRTT = $conn->prepare($queryUpdateRTT);
|
||||
if (!$stmtRTT) {
|
||||
throw new Exception("Erreur préparation RTT: " . $conn->error);
|
||||
}
|
||||
$stmtRTT->bind_param("iiiiiii", $employeeId, $typeIds['RTT'], $rttYear, $rttCount, $rttCount, $rttCount, $rttCount);
|
||||
|
||||
if (!$stmtRTT->execute()) {
|
||||
throw new Exception("Erreur lors de la mise à jour des RTT pour l'employé $employeeId : " . $stmtRTT->error);
|
||||
}
|
||||
$stmtRTT->close();
|
||||
|
||||
// CONGÉ MALADIE - Réinitialiser à 0 (pas de limite)
|
||||
$queryUpdateABS = "
|
||||
INSERT INTO CompteurConges (EmployeeId, TypeCongeId, Annee, Solde, Total)
|
||||
VALUES (?, ?, ?, 0, 0)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
Solde = 0,
|
||||
Total = 0
|
||||
";
|
||||
$stmtABS = $conn->prepare($queryUpdateABS);
|
||||
if (!$stmtABS) {
|
||||
throw new Exception("Erreur préparation ABS: " . $conn->error);
|
||||
}
|
||||
$stmtABS->bind_param("iii", $employeeId, $typeIds['Congé maladie'], $rttYear);
|
||||
|
||||
if (!$stmtABS->execute()) {
|
||||
throw new Exception("Erreur lors de la mise à jour des ABS pour l'employé $employeeId : " . $stmtABS->error);
|
||||
}
|
||||
$stmtABS->close();
|
||||
|
||||
$resetLog[] = "Employé $employeeId : CP=$leaveYear (25j), RTT=$rttYear ({$rttCount}j), ABS=$rttYear (0j)";
|
||||
$employeesUpdated++;
|
||||
}
|
||||
|
||||
error_log("Reset counters - Employés mis à jour: $employeesUpdated");
|
||||
|
||||
// 4. Log de la réinitialisation
|
||||
$logEntry = "
|
||||
=== RÉINITIALISATION DES COMPTEURS ===
|
||||
Date: " . $currentDate->format('Y-m-d H:i:s') . "
|
||||
Exercice CP: $leaveYear (01/06/$leaveYear au 31/05/" . ($leaveYear + 1) . ")
|
||||
Année RTT: $rttYear (01/01/$rttYear au 31/12/$rttYear)
|
||||
Employés traités: $employeesUpdated
|
||||
|
||||
Détails:
|
||||
" . implode("\n ", $resetLog) . "
|
||||
";
|
||||
|
||||
// Sauvegarder le log (optionnel - créer une table de logs si nécessaire)
|
||||
error_log($logEntry, 3, "reset_counters.log");
|
||||
|
||||
$conn->commit();
|
||||
error_log("Reset counters - Transaction commitée avec succès");
|
||||
|
||||
echo json_encode([
|
||||
"success" => true,
|
||||
"message" => "Compteurs réinitialisés avec succès",
|
||||
"details" => [
|
||||
"employees_updated" => $employeesUpdated,
|
||||
"leave_year" => $leaveYear,
|
||||
"rtt_year" => $rttYear,
|
||||
"cp_days" => 25,
|
||||
"rtt_days" => $rttCount,
|
||||
"reset_date" => $currentDate->format('Y-m-d H:i:s')
|
||||
],
|
||||
"log" => $resetLog
|
||||
]);
|
||||
|
||||
} catch (Exception $e) {
|
||||
$conn->rollback();
|
||||
error_log("Erreur réinitialisation compteurs : " . $e->getMessage());
|
||||
|
||||
echo json_encode([
|
||||
"success" => false,
|
||||
"message" => "Erreur lors de la réinitialisation : " . $e->getMessage()
|
||||
]);
|
||||
}
|
||||
|
||||
$conn->close();
|
||||
?>
|
||||
@@ -1,293 +0,0 @@
|
||||
<?php
|
||||
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");
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
|
||||
http_response_code(200);
|
||||
exit();
|
||||
}
|
||||
|
||||
// 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 {
|
||||
$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'];
|
||||
}
|
||||
|
||||
// 🔎 Résoudre les IDs des types de congés
|
||||
$typeIds = [];
|
||||
foreach ($data['Repartition'] as $rep) {
|
||||
$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;
|
||||
}
|
||||
$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'];
|
||||
}
|
||||
}
|
||||
if (empty($typeIds)) {
|
||||
echo json_encode(["success"=>false,"message"=>"Aucun type de congé valide"]);
|
||||
exit;
|
||||
}
|
||||
$typeCongeIdCsv = implode(',', $typeIds);
|
||||
|
||||
// ✅ 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)";
|
||||
|
||||
$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) {
|
||||
$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;
|
||||
}
|
||||
$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
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ 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
|
||||
]);
|
||||
@@ -1,157 +0,0 @@
|
||||
<?php
|
||||
// Validation/Refus d'une demande de congé par un manager
|
||||
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");
|
||||
|
||||
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) {
|
||||
echo json_encode(["success" => false, "message" => "Erreur DB: " . $conn->connect_error]);
|
||||
exit();
|
||||
}
|
||||
|
||||
// Lecture du JSON envoyé
|
||||
$input = file_get_contents('php://input');
|
||||
$data = json_decode($input, true);
|
||||
|
||||
if (!isset($data['request_id'], $data['action'], $data['validator_id'])) {
|
||||
echo json_encode(["success" => false, "message" => "Données manquantes"]);
|
||||
exit();
|
||||
}
|
||||
|
||||
$requestId = (int)$data['request_id'];
|
||||
$action = $data['action']; // "approve" | "reject"
|
||||
$validatorId = (int)$data['validator_id'];
|
||||
$comment = $data['comment'] ?? '';
|
||||
|
||||
try {
|
||||
$conn->begin_transaction();
|
||||
|
||||
// Vérifier que le validateur existe dans CollaborateurAD
|
||||
$stmt = $conn->prepare("SELECT Id, prenom, nom FROM CollaborateurAD WHERE Id = ?");
|
||||
$stmt->bind_param("i", $validatorId);
|
||||
$stmt->execute();
|
||||
$validator = $stmt->get_result()->fetch_assoc();
|
||||
$stmt->close();
|
||||
|
||||
if (!$validator) {
|
||||
throw new Exception("Validateur introuvable dans CollaborateurAD");
|
||||
}
|
||||
|
||||
// Récupération de la demande
|
||||
$queryCheck = "
|
||||
SELECT dc.Id, dc.CollaborateurADId, dc.TypeCongeId, dc.DateDebut, dc.DateFin, dc.NombreJours,
|
||||
ca.prenom as CADPrenom, ca.nom as CADNom,
|
||||
tc.Nom as TypeNom
|
||||
FROM DemandeConge dc
|
||||
JOIN TypeConge tc ON dc.TypeCongeId = tc.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();
|
||||
$requestRow = $stmtCheck->get_result()->fetch_assoc();
|
||||
$stmtCheck->close();
|
||||
|
||||
if (!$requestRow) {
|
||||
throw new Exception("Demande non trouvée ou déjà traitée");
|
||||
}
|
||||
|
||||
$collaborateurId = $requestRow['CollaborateurADId'];
|
||||
$typeCongeId = $requestRow['TypeCongeId'];
|
||||
$nombreJours = $requestRow['NombreJours'];
|
||||
$employeeName = $requestRow['CADPrenom']." ".$requestRow['CADNom'];
|
||||
$typeNom = $requestRow['TypeNom'];
|
||||
|
||||
$newStatus = ($action === 'approve') ? 'Validée' : 'Refusée';
|
||||
|
||||
// 🔹 Mise à jour DemandeConge
|
||||
$queryUpdate = "
|
||||
UPDATE DemandeConge
|
||||
SET Statut = ?,
|
||||
ValidateurId = ?,
|
||||
ValidateurADId = ?,
|
||||
DateValidation = NOW(),
|
||||
CommentaireValidation = ?
|
||||
WHERE Id = ?
|
||||
";
|
||||
$stmtUpdate = $conn->prepare($queryUpdate);
|
||||
$stmtUpdate->bind_param("siisi", $newStatus, $validatorId, $validatorId, $comment, $requestId);
|
||||
$stmtUpdate->execute();
|
||||
$stmtUpdate->close();
|
||||
|
||||
// 🔹 Déduction solde (pas maladie)
|
||||
if ($action === 'approve' && $typeNom !== 'Congé maladie' && $collaborateurId) {
|
||||
$year = date("Y");
|
||||
$queryDeduct = "
|
||||
UPDATE CompteurConges
|
||||
SET Solde = GREATEST(0, Solde - ?)
|
||||
WHERE CollaborateurADId = ? AND TypeCongeId = ? AND Annee = ?
|
||||
";
|
||||
$stmtDeduct = $conn->prepare($queryDeduct);
|
||||
$stmtDeduct->bind_param("diii", $nombreJours, $collaborateurId, $typeCongeId, $year);
|
||||
$stmtDeduct->execute();
|
||||
$stmtDeduct->close();
|
||||
}
|
||||
|
||||
// 🔹 Notification
|
||||
$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';
|
||||
|
||||
$queryNotif = "
|
||||
INSERT INTO Notifications (CollaborateurADId, Titre, Message, Type, DemandeCongeId)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
";
|
||||
$stmtNotif = $conn->prepare($queryNotif);
|
||||
$stmtNotif->bind_param("isssi", $collaborateurId, $notificationTitle, $notificationMessage, $notifType, $requestId);
|
||||
$stmtNotif->execute();
|
||||
$stmtNotif->close();
|
||||
|
||||
// 🔹 Historique
|
||||
$actionText = ($action === 'approve') ? 'Validation congé' : 'Refus congé';
|
||||
$actionDetails = "$actionText $employeeName ($typeNom)";
|
||||
if ($comment) $actionDetails .= " - $comment";
|
||||
|
||||
$queryHistory = "
|
||||
INSERT INTO HistoriqueActions (CollaborateurADId, 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'),
|
||||
"new_status" => $newStatus
|
||||
]);
|
||||
|
||||
} catch (Exception $e) {
|
||||
$conn->rollback();
|
||||
echo json_encode(["success" => false, "message" => $e->getMessage()]);
|
||||
}
|
||||
|
||||
$conn->close();
|
||||
Reference in New Issue
Block a user