Initial clean V5 repository

This commit is contained in:
2026-05-13 09:43:32 -04:00
commit 5842222283
7264 changed files with 1322128 additions and 0 deletions

615
ajax_bib_range.php Normal file
View File

@ -0,0 +1,615 @@
<?php
require_once('php/inc_fonctions.php');
require_once('php/inc_fx_promoteur.php');
global $objDatabase;
header('Content-Type: application/json; charset=utf-8');
$action = $_REQUEST['action'] ?? '';
// =====================
// CREATE
// =====================
if ($action == 'create') {
$epr_id = intval($_REQUEST['epr_id'] ?? 0);
if ($epr_id > 0) {
// ⚠️ On ne crée PLUS en DB
// On récupère les ranges existants AVEC stats
$tabBibRanges = fxInfosBibRange($epr_id);
// 👉 On ajoute UNE ligne vide (UI seulement)
$tabBibRanges[] = [
'epr_bib_id' => 0, // ID temporaire
'epr_id' => $epr_id,
'epr_bib_start' => '',
'epr_bib_finish' => '',
'dernier_bib' => '',
'nb_utilises' => '',
'liste_trous' => '',
'liste_doublons' => ''
];
echo json_encode([
'success' => true,
'html' => renderBibRanges($tabBibRanges, $epr_id),
'error' => ''
]);
exit;
}
echo json_encode([
'success' => false,
'message' => 'epr_id invalide'
]);
exit;
}
// =====================
// DELETE
// =====================
if ($action == 'delete') {
$id = intval($_REQUEST['id'] ?? 0);
if ($id > 0) {
$range = fxInfosBibRange(0,$id);
$epr_id = $range[1]["epr_id"];
if (!$range) {
echo json_encode([
'success' => false,
'message' => 'Range introuvable'
]);
exit;
}
if ((int)$range[1]['nb_utilises'] > 0) {
echo json_encode([
'success' => false,
'message' => 'Impossible de supprimer : des dossards sont déjà utilisés dans ce range'
]);
exit;
}
$sql = "
DELETE FROM inscriptions_epreuves_bib
WHERE epr_bib_id = $id
";
$objDatabase->fxQuery($sql);
$tabBibRanges = fxInfosBibRange($epr_id);
echo json_encode([
'success' => true,
'html' => renderBibRanges($tabBibRanges,$epr_id),
'error' => ''
]);
exit;
}
echo json_encode([
'success' => false,
'message' => 'id invalide'
]);
exit;
}
// =====================
// SAVE
// =====================
if ($action == 'save') {
$id = intval($_REQUEST['id'] ?? 0);
$epr_id = intval($_REQUEST['epr_id'] ?? 0);
$start = intval($_REQUEST['start'] ?? 0);
$end = intval($_REQUEST['end'] ?? 0);
$is_new = ($id == 0);
// =====================
// VALIDATION 1 — epr_id
// =====================
if ($is_new && $epr_id <= 0) {
echo json_encode(['success' => false, 'message' => 'epr_id invalide']);
exit;
}
// =====================
// recherche eve_id
// =====================
$sqlGet = "SELECT eve_id FROM inscriptions_epreuves WHERE epr_id = $epr_id";
$eve_id = (int)$objDatabase->fxGetVar($sqlGet);
// =====================
// VALIDATION 2 — VALEURS NUMÉRIQUES
// =====================
if ($start <= 0 || $end <= 0) {
echo json_encode(['success' => false, 'message' => 'Valeurs invalides']);
exit;
}
// =====================
// VALIDATION 3 — LOGIQUE INTERVALLE
// =====================
if ($start > $end) {
echo json_encode(['success' => false, 'message' => 'Début doit être < fin']);
exit;
}
// =====================
// RÉCUPÉRER epr_id + PROTÉGER LES DOSSARDS SI UPDATE
// =====================
if (!$is_new) {
$sqlGet = "SELECT epr_id FROM inscriptions_epreuves_bib WHERE epr_bib_id = $id";
$epr_id = (int)$objDatabase->fxGetVar($sqlGet);
if ($epr_id <= 0) {
echo json_encode(['success' => false, 'message' => 'Range introuvable']);
exit;
}
$sqlCheckOrphans = "
SELECT COUNT(*)
FROM resultats_participants rp
INNER JOIN inscriptions_epreuves_bib b
ON b.epr_bib_id = $id
WHERE rp.epr_id = b.epr_id
AND rp.no_bib BETWEEN b.epr_bib_start AND b.epr_bib_finish
AND (
rp.no_bib < $start
OR rp.no_bib > $end
)
";
$nbOrphans = (int)$objDatabase->fxGetVar($sqlCheckOrphans);
if ($nbOrphans > 0) {
echo json_encode([
'success' => false,
'message' => 'Modification impossible : des dossards sortiraient du range'
]);
exit;
}
}
// =====================
// VALIDATION 4 — OVERLAP pas de double epreuves
// =====================
$sqlOverlap = "
SELECT COUNT(*)
FROM inscriptions_epreuves_bib
WHERE eve_id = $eve_id
AND epr_bib_start IS NOT NULL
AND epr_bib_finish IS NOT NULL
" . (!$is_new ? "AND epr_bib_id <> $id" : "") . "
AND (
$start <= epr_bib_finish
AND $end >= epr_bib_start
)
";
$hasOverlap = (int)$objDatabase->fxGetVar($sqlOverlap);
if ($hasOverlap > 0) {
echo json_encode([
'success' => false,
'message' => 'Conflit avec un autre intervalle de dossards'
]);
exit;
}
// =====================
// INSERT OU UPDATE
// =====================
if ($is_new) {
$sql = "
INSERT INTO inscriptions_epreuves_bib
(epr_id, epr_bib_start, epr_bib_finish, update_date, update_qui, eve_id)
VALUES
($epr_id, $start, $end, NOW(), 'admin', $eve_id)
";
} else {
$sql = "
UPDATE inscriptions_epreuves_bib
SET epr_bib_start = $start,
epr_bib_finish = $end,
update_date = NOW(),
eve_id = $eve_id
WHERE epr_bib_id = $id
";
}
$objDatabase->fxQuery($sql);
// =====================
// RELOAD HTML
// =====================
$tabBibRanges = fxInfosBibRange($epr_id);
echo json_encode([
'success' => true,
'html' => renderBibRanges($tabBibRanges, $epr_id)
]);
exit;
}
// =====================
// VIEW
// =====================
if ($action == 'view') {
$epr_id = intval($_REQUEST['epr_id'] ?? 0);
$range_id = intval($_REQUEST['range_id'] ?? 0);
if ($epr_id <= 0 || $range_id < 0) {
echo json_encode([
'success' => false,
'message' => 'Paramètres invalides'
]);
exit;
}
// TEMPORAIRE : affichage simple pour test
ob_start();
$html = renderBibView($epr_id, $range_id);
echo json_encode([
'success' => true,
'html' => $html
]);
exit;
}
// =====================
// ANALYSE BATCH
// =====================
if ($action == 'batch_analysis') {
$epr_id = intval($_POST['epr_id'] ?? 0);
if ($epr_id <= 0) {
echo json_encode([
'success' => false,
'message' => 'epr_id invalide'
]);
exit;
}
$infoBib = fxInfosBibEpreuve($epr_id);
echo json_encode([
'success' => true,
'info' => $infoBib
]);
exit;
}
if ($action == 'refresh_ranges') {
$epr_id = intval($_POST['epr_id'] ?? $_GET['epr_id'] ?? 0);
$mode = $_POST['mode'] ?? $_GET['mode'] ?? 'assign';
if ($epr_id <= 0) {
echo json_encode([
'success' => false,
'message' => 'epr_id invalide'
]);
exit;
}
$tabBibStats = fxInfosBibRange($epr_id);
echo json_encode([
'success' => true,
'html' => renderBibRanges($tabBibStats, $epr_id, $mode)
]);
exit;
}
if ($action == 'refresh_ranges_data') {
$epr_id = intval($_POST['epr_id'] ?? 0);
if ($epr_id <= 0) {
echo json_encode(['success' => false]);
exit;
}
$tab = fxInfosBibRange($epr_id);
$out = [];
foreach ($tab as $r) {
$nb_total = $r['nb_total_range'] ?? 0;
$nb_used = (int)($r['nb_utilises'] ?? 0);
$out[] = [
'id' => (int)$r['epr_bib_id'],
'last' => (int)$r['dernier_bib'],
'used' => $nb_used,
'dispo' => $nb_total - $nb_used,
'trous' => $r['liste_trous'] ?? '',
'doublons' => $r['liste_doublons'] ?? ''
];
}
echo json_encode([
'success' => true,
'ranges' => $out
]);
exit;
}
// =====================
// BATCH GO (DEBUG SEULEMENT)
// =====================
// Objectif :
// - recevoir les données du bouton GO
// - NE RIEN ÉCRIRE en DB
// - retourner les infos pour validation
if ($action == 'batch_go') {
// ID de lépreuve
$epr_id = intval($_POST['epr_id'] ?? 0);
// Liste des ranges sélectionnés (JSON → array PHP)
$ranges = json_decode($_POST['ranges'] ?? '[]', true);
// Ordre choisi (table bib_assignements)
$ba_id = intval($_POST['ba_id'] ?? 0);
// DEBUG : on retourne tout pour validation
// =====================
// TEST fxGetParticipantsForBatchAssign
// =====================
$participants = fxGetParticipantsForBatchAssign($epr_id, $ba_id);
// =====================
// UTILISER LA FONCTION PROPRE
// =====================
$tabRanges = fxGetRangesForBatchAssign($epr_id, $ranges);
$tabRangesInfos = fxInfosBibRange($epr_id); // ← ICI
$ids = array_map('intval', $ranges);
$tabRangesInfos = array_filter($tabRangesInfos, function($r) use ($ids) {
return in_array((int)$r['epr_bib_id'], $ids);
});
$nextBib = fxGetNextAvailableBib($epr_id, $tabRanges);
$simu = fxProcessBatchAssignments($epr_id, $participants, $tabRanges, 'simulation');
$summary = fxBuildBatchSummaryFromRanges($tabRangesInfos, $participants);
$info = "{$summary['nb_dispo']} disponibles / {$summary['nb_participants']} à assigner → manque {$summary['nb_manque']}";
// =====================
// SIMULATION (temporaire simple)
// =====================
// =====================
// RENDER VIEW EN MODE SIMULATION
// =====================
$html = renderBibView(
$epr_id,
0,
'fr',
'simulation',
$simu,
'Résultats de la simulation',
$info
);
echo json_encode([
'success' => true,
'html' => $html
]);
exit;
}
if ($action == 'batch_apply') {
// =====================
// GO BATCH (EXÉCUTION RÉELLE)
// - Assigne les BIB en DB
// - Utilise fxProcessBatchAssignments en mode 'execute'
// - Affiche le résultat réel ($exec), pas de simulation
// =====================
$epr_id = intval($_POST['epr_id'] ?? 0);
$ranges = json_decode($_POST['ranges'] ?? '[]', true);
$ba_id = intval($_POST['ba_id'] ?? 0);
$participants = fxGetParticipantsForBatchAssign($epr_id, $ba_id);
$tabRanges = fxGetRangesForBatchAssign($epr_id, $ranges);
$exec = fxProcessBatchAssignments($epr_id, $participants, $tabRanges, 'execute');
$tabRangesInfos = fxInfosBibRange($epr_id);
$ids = array_map('intval', $ranges);
$tabRangesInfos = array_filter($tabRangesInfos, function($r) use ($ids) {
return in_array((int)$r['epr_bib_id'], $ids);
});
$summary = fxBuildBatchSummaryFromRanges($tabRangesInfos, $participants);
$assigned = count($exec);
$total = count($participants);
$remaining = max(0, $total - $assigned);
$status = 'success';
if ($assigned === 0) {
$status = 'error';
} elseif ($assigned < $total) {
$status = 'partial';
}
if ($assigned === 0) {
$info = "Aucun dossard na pu être assigné.";
} elseif ($assigned === $total) {
$info = "Assignation complétée : $assigned dossards assignés avec succès.";
} else {
$info = "Assignation partielle complétée : $assigned dossards assignés avec succès. $remaining participants restent à assigner.";
}
$html = renderBibView(
$epr_id,
0,
'fr',
'execute',
$exec,
'Résultats de lassignation',
$info,$status
);
echo json_encode([
'success' => true,
'html' => $html
]);
exit;
}
// =====================
// RESET PREVIEW
// =====================
if ($action == 'reset_preview') {
$epr_id = intval($_POST['epr_id'] ?? 0);
$ranges = json_decode($_POST['ranges'] ?? '[]', true);
$participants = fxGetParticipantsForBatchReset($epr_id, $ranges);
$html = renderBibView(
$epr_id,
0,
'fr',
'reset',
$participants,
'Prévisualisation de la réinitialisation',
count($participants) . ' dossards seront retirés',
'warning'
);
echo json_encode([
'success' => true,
'html' => $html
]);
exit;
}
// =====================
// RESET APPLY
// =====================
if ($action == 'reset_apply') {
$epr_id = intval($_POST['epr_id'] ?? 0);
$ranges = json_decode($_POST['ranges'] ?? '[]', true);
$participants = fxGetParticipantsForBatchReset($epr_id, $ranges);
$count = 0;
foreach ($participants as $p) {
$par_id = intval($p['par_id']);
if ($par_id <= 0) {
continue;
}
$sql = "
UPDATE resultats_participants
SET no_bib = NULL
WHERE par_id = $par_id
AND is_cancelled = 0
";
$objDatabase->fxQuery($sql);
$count++;
}
$html = renderBibView(
$epr_id,
0,
'fr',
'reset',
$participants,
'Réinitialisation terminée',
$count . ' dossards retirés',
'success'
);
echo json_encode([
'success' => true,
'html' => $html
]);
exit;
}
// =====================
// SAVE TEAM MODE
// =====================
if ($action == 'save_team_mode') {
$epr_id = intval($_REQUEST['epr_id'] ?? 0);
$team_mode = intval($_REQUEST['team_mode'] ?? 0);
if ($epr_id <= 0 || !in_array($team_mode, [1, 2, 3])) {
echo json_encode([
'success' => false,
'message' => 'Paramètres invalides'
]);
exit;
}
$sql = "
UPDATE inscriptions_epreuves
SET epr_bib_team_mode = $team_mode
WHERE epr_id = $epr_id
LIMIT 1
";
$objDatabase->fxQuery($sql);
echo json_encode([
'success' => true
]);
exit;
}
// =====================
// ACTION INVALIDE
// =====================
echo json_encode([
'success' => false,
'message' => 'Action invalide'
]);
exit;