Merge branch 'dev' of http://git.progiweb.ca/stephan/ms1inscription-v5 into dev
This commit is contained in:
25
.vscode/settings.json
vendored
Normal file
25
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"sqltools.connections": [
|
||||
{
|
||||
"mysqlOptions": {
|
||||
"authProtocol": "default",
|
||||
"enableSsl": "Disabled"
|
||||
},
|
||||
"ssh": "Enabled",
|
||||
"previewLimit": 50,
|
||||
"server": "localhost",
|
||||
"port": 3306,
|
||||
"sshOptions": {
|
||||
"port": 7822,
|
||||
"host": "104.254.182.111",
|
||||
"username": "devinscription",
|
||||
"password": "M-G7+[NdA34H"
|
||||
},
|
||||
"driver": "MariaDB",
|
||||
"name": "astral(dev) ms1inscription",
|
||||
"username": "devinscription_bd",
|
||||
"password": "x$@_v0-l_I((",
|
||||
"database": "devinscription_preprod"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -394,7 +394,7 @@ if ($action == 'batch_go') {
|
||||
|
||||
$nextBib = fxGetNextAvailableBib($epr_id, $tabRanges);
|
||||
$simu = fxProcessBatchAssignments($epr_id, $participants, $tabRanges, 'simulation');
|
||||
$summary = fxBuildBatchSummaryFromRanges($tabRangesInfos, $participants);
|
||||
$summary = fxBuildBatchSummaryFromRanges($tabRangesInfos, $participants, $epr_id);
|
||||
|
||||
$info = "{$summary['nb_dispo']} disponibles / {$summary['nb_participants']} à assigner → manque {$summary['nb_manque']}";
|
||||
// =====================
|
||||
@ -451,7 +451,7 @@ if ($action == 'batch_apply') {
|
||||
return in_array((int)$r['epr_bib_id'], $ids);
|
||||
});
|
||||
|
||||
$summary = fxBuildBatchSummaryFromRanges($tabRangesInfos, $participants);
|
||||
$summary = fxBuildBatchSummaryFromRanges($tabRangesInfos, $participants, $epr_id);
|
||||
|
||||
$assigned = count($exec);
|
||||
$total = count($participants);
|
||||
|
||||
@ -2039,7 +2039,12 @@ if ($strLangue == 'fr') {
|
||||
if (totalEl) totalEl.textContent = data.info.total;
|
||||
if (avecEl) avecEl.textContent = data.info.avec_bib;
|
||||
syncBibUiState(row);
|
||||
let sansBib = parseInt(data.info.sans_bib || 0, 10);
|
||||
let sansBib = parseInt(
|
||||
(data.info.a_assigner !== undefined && data.info.a_assigner !== null)
|
||||
? data.info.a_assigner
|
||||
: (data.info.sans_bib || 0),
|
||||
10
|
||||
);
|
||||
if (isNaN(sansBib)) sansBib = 0;
|
||||
let isResetMode = row.dataset.mode === 'reset';
|
||||
let message = '';
|
||||
@ -2332,6 +2337,23 @@ if ($strLangue == 'fr') {
|
||||
|
||||
let container = btnView.closest('.epr-block');
|
||||
|
||||
// Vérifier si une vue est déjà ouverte
|
||||
let existing = document.querySelector('.epr-row-view');
|
||||
|
||||
// Toggle : si c'est le même œil qui a ouvert la vue, on la ferme et on s'arrête
|
||||
if (existing
|
||||
&& existing.dataset.eprId === epr_id
|
||||
&& existing.dataset.rangeId === range_id
|
||||
) {
|
||||
existing.remove();
|
||||
return;
|
||||
}
|
||||
|
||||
// Un autre œil a été cliqué : fermer la vue précédente avant d'ouvrir la nouvelle
|
||||
if (existing) {
|
||||
existing.remove();
|
||||
}
|
||||
|
||||
fetch('/ajax_bib_range.php', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
@ -2360,14 +2382,17 @@ if ($strLangue == 'fr') {
|
||||
|
||||
let row = btnView.closest('.epr-row');
|
||||
|
||||
// 1. Supprimer toute vue existante
|
||||
let existing = document.querySelector('.epr-row-view');
|
||||
if (existing) {
|
||||
existing.remove();
|
||||
}
|
||||
|
||||
// 2. Injecter sous la bonne ligne
|
||||
// Injecter la nouvelle vue sous la ligne du bouton cliqué,
|
||||
// en mémorisant epr_id et range_id pour le toggle suivant
|
||||
row.insertAdjacentHTML('afterend', data.html);
|
||||
|
||||
// Stocker les identifiants sur la vue injectée pour pouvoir détecter
|
||||
// le 2e clic sur le même œil
|
||||
let newView = row.nextElementSibling;
|
||||
if (newView && newView.classList.contains('epr-row-view')) {
|
||||
newView.dataset.eprId = epr_id;
|
||||
newView.dataset.rangeId = range_id;
|
||||
}
|
||||
});
|
||||
|
||||
return;
|
||||
|
||||
@ -2550,8 +2550,8 @@ function fxUpdateQuantites($intEpreuve, $intQuantite, $strLangue) {
|
||||
}
|
||||
|
||||
|
||||
// v2
|
||||
function renderBatchConfig($tabBibAssignments, $strLangue = 'fr') {
|
||||
// v2 — options d'ordre batch (table bib_assignements)
|
||||
function renderBatchConfig($tabBibAssignments, $strLangue = 'fr', $isTeamEpreuve = false) {
|
||||
|
||||
ob_start();
|
||||
?>
|
||||
@ -2562,7 +2562,13 @@ function renderBatchConfig($tabBibAssignments, $strLangue = 'fr') {
|
||||
<div class="mb-2">
|
||||
<label>Ordre d’assignation</label>
|
||||
<select class="form-control form-control-sm batch-order">
|
||||
<?php for ($j = 1; $j < count($tabBibAssignments)+1; $j++) { ?>
|
||||
<?php for ($j = 1; $j < count($tabBibAssignments)+1; $j++) {
|
||||
// bib_assignements.ba_equipe = 1 : option équipe seulement (ex. ba_id 5 « Nom d'équipe »)
|
||||
// → masquée sur épreuve solo ; visible sur épreuve équipe (individuel ou 1 équipe = 1 dossard)
|
||||
if ((int)($tabBibAssignments[$j]['ba_equipe'] ?? 0) === 1 && !$isTeamEpreuve) {
|
||||
continue;
|
||||
}
|
||||
?>
|
||||
<option value="<?php echo $tabBibAssignments[$j]['ba_id']; ?>">
|
||||
<?php echo $tabBibAssignments[$j]['ba_nom_' . $strLangue]; ?>
|
||||
</option>
|
||||
@ -2784,7 +2790,10 @@ if ($teamMode <= 0) {
|
||||
|
||||
|
||||
<div class="batch-config-container" style="display:none;">
|
||||
<?php echo renderBatchConfig($tabBibAssignments, $strLangue); ?>
|
||||
<?php
|
||||
// 3e arg. : epr_equipe = 1 → afficher aussi les tris « équipe » (ba_equipe = 1 dans bib_assignements)
|
||||
echo renderBatchConfig($tabBibAssignments, $strLangue, (int)$tabEpreuves[$i]['epr_equipe'] === 1);
|
||||
?>
|
||||
|
||||
<button type="button" class="btn btn-sm btn-secondary btn-simuler-batch" style="display:none;">
|
||||
Simuler
|
||||
@ -2958,11 +2967,14 @@ function fxInfosBibEpreuve($epr_id){
|
||||
|
||||
$row = $objDatabase->fxGetRow($sql);
|
||||
|
||||
return [
|
||||
$info = [
|
||||
'total' => (int)($row['total'] ?? 0),
|
||||
'avec_bib' => (int)($row['avec_bib'] ?? 0),
|
||||
'sans_bib' => (int)($row['sans_bib'] ?? 0)
|
||||
'sans_bib' => (int)($row['sans_bib'] ?? 0),
|
||||
'a_assigner' => fxCountBatchAssignUnits($epr_id)
|
||||
];
|
||||
|
||||
return $info;
|
||||
}
|
||||
function renderBibRanges($tabBibRanges, $epr_id = 0, $mode = 'assign') {
|
||||
//print_rsl($tabBibRanges);
|
||||
@ -3338,7 +3350,8 @@ function fxGetParticipantsForBatchAssign($epr_id, $ba_id) {
|
||||
|
||||
// =====================
|
||||
// RÉCUPÉRER L'ORDER BY DYNAMIQUE
|
||||
// Source : table bib_assignements
|
||||
// Source : bib_assignements.ba_sql_order (choix du promoteur dans le batch)
|
||||
// Ex. ba_id 5 : TRIM(c.pec_nom_equipe), p.par_nom, p.par_prenom
|
||||
// =====================
|
||||
$sqlOrder = "
|
||||
SELECT ba_sql_order
|
||||
@ -3359,11 +3372,10 @@ function fxGetParticipantsForBatchAssign($epr_id, $ba_id) {
|
||||
}
|
||||
|
||||
// =====================
|
||||
// PARTICIPANTS SOLO À ASSIGNER
|
||||
// Important :
|
||||
// PARTICIPANTS À ASSIGNER (solo et équipe)
|
||||
// - jointure c.* requise pour les tris par nom d'équipe (pec_nom_equipe)
|
||||
// - on ne prend que ceux sans no_bib
|
||||
// - on exclut rol_id 3 et 4 comme dans l'ancien code
|
||||
// - aucune écriture DB ici
|
||||
// =====================
|
||||
$sql = "
|
||||
SELECT
|
||||
@ -3497,201 +3509,333 @@ function fxGetNextAvailableBib($epr_id, $tabRanges) {
|
||||
// 👉 aucun BIB disponible
|
||||
return null;
|
||||
}
|
||||
function fxProcessBatchAssignments($epr_id, $participants, $tabRanges, $mode = 'simulation') {
|
||||
function fxLoadUsedBibsForBatch($epr_id) {
|
||||
global $objDatabase;
|
||||
|
||||
$assignments = [];
|
||||
$teamMap = [];
|
||||
$usedBib = [];
|
||||
$sql = "
|
||||
SELECT no_bib
|
||||
FROM resultats_participants
|
||||
WHERE epr_id = " . intval($epr_id) . "
|
||||
AND no_bib IS NOT NULL
|
||||
AND no_bib != ''
|
||||
AND no_bib > 0
|
||||
";
|
||||
$rows = $objDatabase->fxGetResults($sql);
|
||||
|
||||
$updatedTeams = [];
|
||||
$teamBibMap = [];
|
||||
$nextTeamNumber = 1;
|
||||
if (empty($participants) || empty($tabRanges)) {
|
||||
return $assignments;
|
||||
foreach ($rows as $r) {
|
||||
$usedBib[(int)$r['no_bib']] = true;
|
||||
}
|
||||
|
||||
return $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;
|
||||
|
||||
// =====================
|
||||
// MODE SIMULATION → cache en mémoire
|
||||
// MODE EXECUTE → on ne fait PAS confiance au cache
|
||||
// =====================
|
||||
$usedBib = [];
|
||||
foreach ($tabRanges as $range) {
|
||||
$start = (int)$range['start'];
|
||||
$end = (int)$range['end'];
|
||||
|
||||
if ($mode === 'simulation') {
|
||||
|
||||
// Charger les BIB déjà utilisés (1 seule fois)
|
||||
$sql = "
|
||||
SELECT no_bib
|
||||
FROM resultats_participants
|
||||
WHERE epr_id = $epr_id
|
||||
AND no_bib IS NOT NULL
|
||||
AND no_bib != ''
|
||||
";
|
||||
|
||||
$rows = $objDatabase->fxGetResults($sql);
|
||||
|
||||
foreach ($rows as $r) {
|
||||
$usedBib[(int)$r['no_bib']] = true;
|
||||
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 = $epr_id
|
||||
AND no_bib = $i
|
||||
AND is_cancelled = 0
|
||||
";
|
||||
if ((int)$objDatabase->fxGetVar($sqlCheck) === 0) {
|
||||
return $i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// =====================
|
||||
// BOUCLE PRINCIPALE
|
||||
// =====================
|
||||
foreach ($participants as $p) {
|
||||
|
||||
$par_id = (int)$p['par_id'];
|
||||
$teamKey = (int)($p['pec_id_original'] ?? 0);
|
||||
$teamMode = (int)($p['epr_bib_team_mode'] ?? 1);
|
||||
$teamNumber = 0;
|
||||
|
||||
$teamMode = (int)($p['epr_bib_team_mode'] ?? 1);
|
||||
if ($teamMode !== 3 && $teamKey > 0) {
|
||||
|
||||
if (!isset($teamMap[$teamKey])) {
|
||||
|
||||
$teamMap[$teamKey] = $nextTeamNumber;
|
||||
$nextTeamNumber++;
|
||||
}
|
||||
|
||||
$teamNumber = $teamMap[$teamKey];
|
||||
}
|
||||
$foundBib = null;
|
||||
if ($teamMode === 3 && $teamKey > 0) {
|
||||
|
||||
if (isset($teamBibMap[$teamKey])) {
|
||||
|
||||
$foundBib = $teamBibMap[$teamKey];
|
||||
$teamNumber = $teamBibMap[$teamKey];
|
||||
}
|
||||
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;
|
||||
|
||||
// =====================
|
||||
// CHERCHER BIB LIBRE
|
||||
// =====================
|
||||
if ($foundBib === null) {
|
||||
$sqlUpdate = "
|
||||
UPDATE resultats_participants
|
||||
SET no_bib = " . intval($foundBib) . ",
|
||||
par_date_bib = IFNULL(par_date_bib, NOW())
|
||||
WHERE par_id = " . intval($par_id) . "
|
||||
AND is_cancelled = 0
|
||||
AND (no_bib IS NULL OR no_bib = '' OR no_bib = 0)
|
||||
";
|
||||
|
||||
foreach ($tabRanges as $range) {
|
||||
$objDatabase->fxQuery($sqlUpdate);
|
||||
}
|
||||
|
||||
$start = (int)$range['start'];
|
||||
$end = (int)$range['end'];
|
||||
function fxApplyBatchTeamNumber($epr_id, $teamKey, $teamNumber, &$updatedTeams) {
|
||||
global $objDatabase;
|
||||
|
||||
for ($i = $start; $i <= $end; $i++) {
|
||||
|
||||
// =====================
|
||||
// SIMULATION
|
||||
// =====================
|
||||
if ($mode === 'simulation') {
|
||||
|
||||
if (!isset($usedBib[$i])) {
|
||||
$foundBib = $i;
|
||||
$usedBib[$i] = true; // réserver
|
||||
break 2;
|
||||
}
|
||||
|
||||
} else {
|
||||
// =====================
|
||||
// EXECUTE (sécurisé DB)
|
||||
// =====================
|
||||
$sqlCheck = "
|
||||
SELECT COUNT(*)
|
||||
FROM resultats_participants
|
||||
WHERE epr_id = $epr_id
|
||||
AND no_bib = $i
|
||||
";
|
||||
|
||||
$exists = (int)$objDatabase->fxGetVar($sqlCheck);
|
||||
|
||||
if ($exists === 0) {
|
||||
$foundBib = $i;
|
||||
|
||||
// ÉCRITURE RÉELLE
|
||||
$sqlUpdate = "
|
||||
UPDATE resultats_participants
|
||||
SET no_bib = $i,
|
||||
par_date_bib = IFNULL(par_date_bib, NOW())
|
||||
WHERE par_id = $par_id
|
||||
AND is_cancelled = 0
|
||||
AND (no_bib IS NULL OR no_bib = '' OR no_bib = 0)
|
||||
";
|
||||
|
||||
$objDatabase->fxQuery($sqlUpdate);
|
||||
if ($teamNumber > 0 && !isset($updatedTeams[$teamKey])) {
|
||||
if ($teamKey <= 0 || $teamNumber <= 0 || isset($updatedTeams[$teamKey])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$sqlTeam = "
|
||||
UPDATE resultats_epreuves_commandees
|
||||
SET no_equipe = $teamNumber
|
||||
WHERE pec_id_original = $teamKey
|
||||
AND epr_id = $epr_id
|
||||
SET no_equipe = " . intval($teamNumber) . "
|
||||
WHERE pec_id_original = " . intval($teamKey) . "
|
||||
AND epr_id = " . intval($epr_id) . "
|
||||
";
|
||||
|
||||
$objDatabase->fxQuery($sqlTeam);
|
||||
|
||||
$updatedTeams[$teamKey] = true;
|
||||
}
|
||||
break 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
} }
|
||||
if (
|
||||
$teamMode === 3
|
||||
&& $teamKey > 0
|
||||
&& $foundBib > 0
|
||||
) {
|
||||
|
||||
if (!isset($teamBibMap[$teamKey])) {
|
||||
function fxBuildBatchAssignmentRow($p, $foundBib, $teamNumber) {
|
||||
return [
|
||||
'rol_id' => $p['rol_id'],
|
||||
'par_id' => (int)$p['par_id'],
|
||||
'par_prenom' => $p['par_prenom'],
|
||||
'par_nom' => $p['par_nom'],
|
||||
'no_bib' => $foundBib,
|
||||
'no_equipe' => $teamNumber,
|
||||
'pec_nom_equipe' => $p['pec_nom_equipe'] ?? '',
|
||||
];
|
||||
}
|
||||
|
||||
$teamBibMap[$teamKey] = $foundBib;
|
||||
function fxGetBatchTeamKey($p) {
|
||||
return (int)($p['pec_id_original'] ?? $p['pec_id'] ?? 0);
|
||||
}
|
||||
|
||||
$teamNumber = $foundBib;
|
||||
function fxCountBatchAssignUnits($epr_id, $participants = null) {
|
||||
global $objDatabase;
|
||||
|
||||
$epr_id = intval($epr_id);
|
||||
|
||||
if ($epr_id <= 0) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (
|
||||
$teamMode === 3
|
||||
&& $teamKey > 0
|
||||
&& isset($teamBibMap[$teamKey])
|
||||
) {
|
||||
|
||||
$foundBib = $teamBibMap[$teamKey];
|
||||
$teamNumber = $teamBibMap[$teamKey];
|
||||
$sqlEpreuve = "
|
||||
SELECT epr_equipe, epr_bib_team_mode
|
||||
FROM inscriptions_epreuves
|
||||
WHERE epr_id = $epr_id
|
||||
LIMIT 1
|
||||
";
|
||||
$tabEpreuve = $objDatabase->fxGetRow($sqlEpreuve);
|
||||
|
||||
$countParticipants = function ($rows) {
|
||||
return is_array($rows) ? count($rows) : 0;
|
||||
};
|
||||
|
||||
if (!$tabEpreuve || (int)$tabEpreuve['epr_equipe'] !== 1) {
|
||||
if (is_array($participants)) {
|
||||
return $countParticipants($participants);
|
||||
}
|
||||
|
||||
return (int)$objDatabase->fxGetVar("
|
||||
SELECT COUNT(*)
|
||||
FROM resultats_participants
|
||||
WHERE epr_id = $epr_id
|
||||
AND is_cancelled = 0
|
||||
AND (no_bib IS NULL OR no_bib = '' OR no_bib = 0)
|
||||
AND rol_id NOT IN (3, 4)
|
||||
");
|
||||
}
|
||||
|
||||
$teamMode = (int)($tabEpreuve['epr_bib_team_mode'] ?? 1);
|
||||
if ($teamMode <= 0) {
|
||||
$teamMode = 1;
|
||||
}
|
||||
|
||||
if ($teamMode !== 3) {
|
||||
if (is_array($participants)) {
|
||||
return $countParticipants($participants);
|
||||
}
|
||||
|
||||
return (int)$objDatabase->fxGetVar("
|
||||
SELECT COUNT(*)
|
||||
FROM resultats_participants
|
||||
WHERE epr_id = $epr_id
|
||||
AND is_cancelled = 0
|
||||
AND (no_bib IS NULL OR no_bib = '' OR no_bib = 0)
|
||||
AND rol_id NOT IN (3, 4)
|
||||
");
|
||||
}
|
||||
|
||||
if (is_array($participants)) {
|
||||
$teams = [];
|
||||
|
||||
foreach ($participants as $p) {
|
||||
$teamKey = fxGetBatchTeamKey($p);
|
||||
|
||||
if ($teamKey > 0) {
|
||||
$teams[$teamKey] = true;
|
||||
}
|
||||
}
|
||||
|
||||
return count($teams);
|
||||
}
|
||||
|
||||
return (int)$objDatabase->fxGetVar("
|
||||
SELECT COUNT(DISTINCT p.pec_id)
|
||||
FROM resultats_participants p
|
||||
WHERE p.epr_id = $epr_id
|
||||
AND p.is_cancelled = 0
|
||||
AND (p.no_bib IS NULL OR p.no_bib = '' OR p.no_bib = 0)
|
||||
AND p.rol_id NOT IN (3, 4)
|
||||
AND p.pec_id > 0
|
||||
");
|
||||
}
|
||||
// =====================
|
||||
// PLUS DE PLACE → STOP
|
||||
// =====================
|
||||
|
||||
function fxProcessBatchAssignmentsSolo($epr_id, $participants, $tabRanges, $mode = 'simulation') {
|
||||
$assignments = [];
|
||||
$usedBib = ($mode === 'simulation') ? fxLoadUsedBibsForBatch($epr_id) : [];
|
||||
|
||||
foreach ($participants as $p) {
|
||||
$foundBib = fxFindNextBatchBib($epr_id, $tabRanges, $mode, $usedBib);
|
||||
|
||||
if ($foundBib === null) {
|
||||
break;
|
||||
}
|
||||
if (
|
||||
$teamMode === 3
|
||||
&& $teamKey > 0
|
||||
) {
|
||||
|
||||
$teamNumber = $foundBib;
|
||||
}
|
||||
// =====================
|
||||
// STOCKER LE RÉSULTAT
|
||||
// =====================
|
||||
$assignments[] = [
|
||||
'rol_id' => $p['rol_id'],
|
||||
'par_id' => $par_id,
|
||||
'par_prenom' => $p['par_prenom'],
|
||||
'par_nom' => $p['par_nom'],
|
||||
'no_bib' => $foundBib,
|
||||
'no_equipe' => $teamNumber,
|
||||
'pec_nom_equipe' => $p['pec_nom_equipe'] ?? '',
|
||||
if ($mode === 'execute') {
|
||||
fxApplyBatchParticipantBib($epr_id, (int)$p['par_id'], $foundBib);
|
||||
}
|
||||
|
||||
];
|
||||
$assignments[] = fxBuildBatchAssignmentRow($p, $foundBib, 0);
|
||||
}
|
||||
|
||||
return $assignments;
|
||||
}
|
||||
function fxBuildBatchSummaryFromRanges($tabRangesInfos, $participants) {
|
||||
|
||||
$nbParticipants = count($participants);
|
||||
function fxProcessBatchAssignmentsEquipe($epr_id, $participants, $tabRanges, $mode, $teamMode) {
|
||||
global $objDatabase;
|
||||
|
||||
$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) : [];
|
||||
|
||||
foreach ($participants as $p) {
|
||||
$par_id = (int)$p['par_id'];
|
||||
$teamKey = fxGetBatchTeamKey($p);
|
||||
$teamNumber = 0;
|
||||
$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++;
|
||||
}
|
||||
|
||||
$teamNumber = $teamMap[$teamKey];
|
||||
}
|
||||
|
||||
if ($foundBib === null) {
|
||||
// Premier membre d'une équipe (mode 3) ou chaque participant (mode 1)
|
||||
$foundBib = fxFindNextBatchBib($epr_id, $tabRanges, $mode, $usedBib, $teamMode);
|
||||
}
|
||||
|
||||
if ($foundBib === null) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ($teamMode === 3 && $teamKey > 0) {
|
||||
$teamBibMap[$teamKey] = $foundBib;
|
||||
$teamNumber = $foundBib;
|
||||
}
|
||||
|
||||
if ($mode === 'execute') {
|
||||
fxApplyBatchParticipantBib($epr_id, $par_id, $foundBib);
|
||||
fxApplyBatchTeamNumber($epr_id, $teamKey, $teamNumber, $updatedTeams);
|
||||
}
|
||||
|
||||
$assignments[] = fxBuildBatchAssignmentRow($p, $foundBib, $teamNumber);
|
||||
}
|
||||
|
||||
return $assignments;
|
||||
}
|
||||
|
||||
function fxProcessBatchAssignments($epr_id, $participants, $tabRanges, $mode = 'simulation') {
|
||||
global $objDatabase;
|
||||
|
||||
if (empty($participants) || empty($tabRanges)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$epr_id = intval($epr_id);
|
||||
$sqlEpreuve = "
|
||||
SELECT epr_equipe, epr_bib_team_mode
|
||||
FROM inscriptions_epreuves
|
||||
WHERE epr_id = $epr_id
|
||||
LIMIT 1
|
||||
";
|
||||
$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;
|
||||
}
|
||||
|
||||
return fxProcessBatchAssignmentsEquipe($epr_id, $participants, $tabRanges, $mode, $teamMode);
|
||||
}
|
||||
|
||||
function fxBuildBatchSummaryFromRanges($tabRangesInfos, $participants, $epr_id = 0) {
|
||||
|
||||
$nbParticipants = fxCountBatchAssignUnits($epr_id, $participants);
|
||||
$nbDispo = 0;
|
||||
|
||||
if (!empty($tabRangesInfos)) {
|
||||
|
||||
Reference in New Issue
Block a user