From 517ff7dff6c9db3684d1424d192b52fe31bc89eb Mon Sep 17 00:00:00 2001 From: stephan Date: Tue, 26 May 2026 10:11:11 -0400 Subject: [PATCH] Enhance bib assignment logic in batch processing functions to support team modes and prevent duplicates. Add detailed documentation for clarity. --- php/inc_fx_promoteur.php | 48 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/php/inc_fx_promoteur.php b/php/inc_fx_promoteur.php index 426c341..b744df9 100644 --- a/php/inc_fx_promoteur.php +++ b/php/inc_fx_promoteur.php @@ -3521,25 +3521,55 @@ function fxLoadUsedBibsForBatch($epr_id) { return $usedBib; } -function fxFindNextBatchBib($epr_id, $tabRanges, $mode, &$usedBib) { +/** + * Cherche le prochain dossard libre dans les séquences sélectionnées. + * + * Règle anti-doublon (mode execute / GO) : + * - solo ou équipe « dossards individuels » : un numéro = une personne (COUNT participants) + * - équipe « 1 équipe = 1 dossard » : un numéro = une équipe (COUNT DISTINCT pec_id) + * → plusieurs coéquipiers peuvent partager le même no_bib + * + * @param int $teamMode epr_bib_team_mode (1 = individuel, 3 = 1 équipe = 1 dossard) + */ +function fxFindNextBatchBib($epr_id, $tabRanges, $mode, &$usedBib, $teamMode = 1) { global $objDatabase; + $epr_id = intval($epr_id); + $teamMode = (int)$teamMode; + foreach ($tabRanges as $range) { $start = (int)$range['start']; $end = (int)$range['end']; for ($i = $start; $i <= $end; $i++) { if ($mode === 'simulation') { + // Simulation : cache mémoire (même logique solo/équipe via $teamBibMap en amont) if (!isset($usedBib[$i])) { $usedBib[$i] = true; return $i; } + } elseif ($teamMode === 3) { + // GO — mode « 1 équipe = 1 dossard » + // Le numéro est libre s'il n'est pas déjà pris par une autre équipe. + $sqlCheck = " + SELECT COUNT(DISTINCT pec_id) + FROM resultats_participants + WHERE epr_id = $epr_id + AND no_bib = $i + AND is_cancelled = 0 + AND pec_id > 0 + "; + if ((int)$objDatabase->fxGetVar($sqlCheck) === 0) { + return $i; + } } else { + // GO — solo ou dossards individuels : un numéro ne peut servir qu'à une personne $sqlCheck = " SELECT COUNT(*) FROM resultats_participants - WHERE epr_id = " . intval($epr_id) . " + WHERE epr_id = $epr_id AND no_bib = $i + AND is_cancelled = 0 "; if ((int)$objDatabase->fxGetVar($sqlCheck) === 0) { return $i; @@ -3551,6 +3581,11 @@ function fxFindNextBatchBib($epr_id, $tabRanges, $mode, &$usedBib) { return null; } +/** + * Écrit le no_bib d'un participant (batch GO). + * Note : en mode « 1 équipe = 1 dossard », plusieurs lignes peuvent légitimement + * recevoir le même no_bib — ce n'est pas un doublon erroné. + */ function fxApplyBatchParticipantBib($epr_id, $par_id, $foundBib) { global $objDatabase; @@ -3708,6 +3743,8 @@ function fxProcessBatchAssignmentsEquipe($epr_id, $participants, $tabRanges, $mo $assignments = []; $teamMap = []; $updatedTeams = []; + // Mode 3 : mémorise le dossard déjà choisi pour chaque équipe (pec_id) + // → les coéquipiers réutilisent ce numéro sans repasser par fxFindNextBatchBib $teamBibMap = []; $nextTeamNumber = 1; $usedBib = ($mode === 'simulation') ? fxLoadUsedBibsForBatch($epr_id) : []; @@ -3719,9 +3756,11 @@ function fxProcessBatchAssignmentsEquipe($epr_id, $participants, $tabRanges, $mo $foundBib = null; if ($teamMode === 3 && $teamKey > 0 && isset($teamBibMap[$teamKey])) { + // Coéquipier suivant : même dossard que le premier membre déjà traité $foundBib = $teamBibMap[$teamKey]; $teamNumber = $foundBib; } elseif ($teamMode !== 3 && $teamKey > 0) { + // Mode dossards individuels : no_equipe séquentiel (1, 2, 3…) partagé par l'équipe if (!isset($teamMap[$teamKey])) { $teamMap[$teamKey] = $nextTeamNumber; $nextTeamNumber++; @@ -3731,7 +3770,8 @@ function fxProcessBatchAssignmentsEquipe($epr_id, $participants, $tabRanges, $mo } if ($foundBib === null) { - $foundBib = fxFindNextBatchBib($epr_id, $tabRanges, $mode, $usedBib); + // Premier membre d'une équipe (mode 3) ou chaque participant (mode 1) + $foundBib = fxFindNextBatchBib($epr_id, $tabRanges, $mode, $usedBib, $teamMode); } if ($foundBib === null) { @@ -3770,10 +3810,12 @@ function fxProcessBatchAssignments($epr_id, $participants, $tabRanges, $mode = ' "; $tabEpreuve = $objDatabase->fxGetRow($sqlEpreuve); + // Épreuves solo : logique simple, inchangée (1 personne = 1 dossard) if (!$tabEpreuve || (int)$tabEpreuve['epr_equipe'] !== 1) { return fxProcessBatchAssignmentsSolo($epr_id, $participants, $tabRanges, $mode); } + // Épreuves équipe uniquement — voir fxProcessBatchAssignmentsEquipe() $teamMode = (int)($tabEpreuve['epr_bib_team_mode'] ?? 1); if ($teamMode <= 0) { $teamMode = 1;