Files
ms1inscription-v5/ajax_bib_range.php
2026-05-13 09:43:32 -04:00

615 lines
15 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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;