MSIN-4379 — Refactor team mode handling to ensure unique bib assignment based on team name, enhancing batch processing logic. Update version code to 4.72.912.
This commit is contained in:
@ -6337,15 +6337,20 @@ function fxBibSqlNoBibUnsigned($strColumn = 'no_bib') {
|
||||
/**
|
||||
* SQL — nombre d'unités partageant un no_bib pour une épreuve.
|
||||
* Solo / équipe « dossards individuels » : une personne = une unité (COUNT participants).
|
||||
* Équipe « 1 équipe = 1 dossard » (epr_bib_team_mode = 3) : une équipe = une unité (DISTINCT pec_id).
|
||||
* Équipe « 1 équipe = 1 dossard » (epr_bib_team_mode = 3) : une équipe = une unité (nom d'équipe).
|
||||
*/
|
||||
function fxBibSqlDuplicateUnitCount($strEprIdExpr, $strBibNumExpr) {
|
||||
$strBibP2 = fxBibSqlNoBibUnsigned('p2.no_bib');
|
||||
$strTeamMode = "(SELECT CASE WHEN e.epr_equipe = 1 THEN IFNULL(NULLIF(e.epr_bib_team_mode, 0), 1) ELSE 1 END FROM inscriptions_epreuves e WHERE e.epr_id = ($strEprIdExpr) LIMIT 1)";
|
||||
$strTeamName = "TRIM(IFNULL(NULLIF(c2.pec_nom_equipe, ''), IFNULL(p2.par_nom_equipe, '')))";
|
||||
$strTeamUnit = "IF($strTeamName <> '', LOWER($strTeamName), CONCAT('pec:', IF(p2.pec_id > 0, p2.pec_id, p2.par_id)))";
|
||||
|
||||
return "(CASE WHEN $strTeamMode = 3 THEN (
|
||||
SELECT COUNT(DISTINCT IF(p2.pec_id > 0, p2.pec_id, p2.par_id))
|
||||
SELECT COUNT(DISTINCT $strTeamUnit)
|
||||
FROM resultats_participants p2
|
||||
LEFT JOIN resultats_epreuves_commandees c2
|
||||
ON c2.pec_id_original = p2.pec_id
|
||||
AND c2.epr_id = p2.epr_id
|
||||
WHERE p2.epr_id = ($strEprIdExpr)
|
||||
AND $strBibP2 = ($strBibNumExpr)
|
||||
AND p2.is_cancelled = 0
|
||||
@ -7939,20 +7944,23 @@ function fxAssignAutoBibForParticipant($epr_id, $par_id) {
|
||||
$teamMode = 1;
|
||||
}
|
||||
|
||||
$teamKey = fxGetBatchTeamKey($p);
|
||||
$foundBib = null;
|
||||
$teamNumber = 0;
|
||||
|
||||
// Mode équipe 3 : reprendre le dossard déjà posé sur un coéquipier.
|
||||
if ($isTeamEvent && $teamMode === 3 && $teamKey > 0) {
|
||||
$existingBib = fxGetExistingTeamBibInDb($epr_id, $teamKey);
|
||||
// Mode équipe 3 : reprendre le dossard déjà posé sur un coéquipier (même nom d'équipe).
|
||||
$strShareKey = '';
|
||||
if ($isTeamEvent && $teamMode === 3) {
|
||||
$strShareKey = fxGetBatchTeamShareKey($p);
|
||||
if ($strShareKey !== '') {
|
||||
$existingBib = fxGetExistingTeamBibByShareKeyInDb($epr_id, $p);
|
||||
|
||||
if ($existingBib !== null && (int)$existingBib > 0) {
|
||||
$foundBib = (int)$existingBib;
|
||||
$teamNumber = $foundBib;
|
||||
if ($existingBib !== null && (int)$existingBib > 0) {
|
||||
$foundBib = (int)$existingBib;
|
||||
$teamNumber = $foundBib;
|
||||
|
||||
if (fxApplyBatchParticipantBib($epr_id, $par_id, $foundBib) <= 0) {
|
||||
return ['success' => false, 'message' => 'assignation équipe impossible'];
|
||||
if (fxApplyBatchParticipantBib($epr_id, $par_id, $foundBib) <= 0) {
|
||||
return ['success' => false, 'message' => 'assignation équipe impossible'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7991,6 +7999,7 @@ function fxAssignAutoBibForParticipant($epr_id, $par_id) {
|
||||
return ['success' => false, 'message' => 'aucun dossard disponible'];
|
||||
}
|
||||
|
||||
$teamKey = fxGetBatchTeamKey($p);
|
||||
if ($isTeamEvent && $teamKey > 0) {
|
||||
$updatedTeams = [];
|
||||
|
||||
@ -8056,18 +8065,23 @@ function fxInfosBibEpreuve($epr_id){
|
||||
&& (int)($tabEpreuve['epr_bib_team_mode'] ?? 1) === 3;
|
||||
|
||||
if ($blnTeamOneBib) {
|
||||
// MSIN-4432 — aligné sur fxGetQuantites / fxCountBatchAssignUnits : une équipe = une unité.
|
||||
// MSIN-4379 — 1 équipe = 1 dossard : unité = nom d'équipe (repli pec_id si nom vide).
|
||||
$strTeamName = "TRIM(IFNULL(NULLIF(c.pec_nom_equipe, ''), IFNULL(p.par_nom_equipe, '')))";
|
||||
$strTeamUnit = "IF($strTeamName <> '', LOWER($strTeamName), CONCAT('pec:', p.pec_id))";
|
||||
$sql = "
|
||||
SELECT
|
||||
COUNT(DISTINCT p.pec_id) AS total,
|
||||
COUNT(DISTINCT $strTeamUnit) AS total,
|
||||
COUNT(DISTINCT CASE
|
||||
WHEN p.no_bib IS NOT NULL AND p.no_bib > 0 THEN p.pec_id
|
||||
WHEN p.no_bib IS NOT NULL AND p.no_bib > 0 THEN $strTeamUnit
|
||||
ELSE NULL
|
||||
END) AS avec_bib
|
||||
FROM resultats_participants p
|
||||
LEFT JOIN resultats_epreuves_commandees c
|
||||
ON c.pec_id_original = p.pec_id
|
||||
AND c.epr_id = p.epr_id
|
||||
WHERE p.epr_id = $epr_id
|
||||
AND p.is_cancelled = 0
|
||||
AND p.pec_id > 0
|
||||
AND p.rol_id NOT IN (3, 4)
|
||||
";
|
||||
$row = $objDatabase->fxGetRow($sql);
|
||||
$intTotal = (int)($row['total'] ?? 0);
|
||||
@ -8899,9 +8913,7 @@ function fxBuildBatchAssignmentRow($p, $foundBib, $teamNumber) {
|
||||
}
|
||||
|
||||
/**
|
||||
* MSIN-4379 — Clé d'équipe pour le batch.
|
||||
* Source de vérité = p.pec_id (tous les coéquipiers partagent le même).
|
||||
* pec_id_original (jointure) n'est qu'un repli si pec_id absent.
|
||||
* MSIN-4379 — Clé pec pour dossards individuels / écriture no_equipe sur la commande.
|
||||
*/
|
||||
function fxGetBatchTeamKey($p) {
|
||||
$intPec = (int)($p['pec_id'] ?? 0);
|
||||
@ -8912,9 +8924,39 @@ function fxGetBatchTeamKey($p) {
|
||||
return (int)($p['pec_id_original'] ?? 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* MSIN-4379 — Nom d'équipe affiché (colonne Équipe), source pour « 1 équipe = 1 dossard ».
|
||||
*/
|
||||
function fxGetBatchTeamDisplayName($p) {
|
||||
$str = trim((string)($p['pec_nom_equipe'] ?? ''));
|
||||
if ($str === '') {
|
||||
$str = trim((string)($p['par_nom_equipe'] ?? ''));
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* MSIN-4379 — Clé de partage mode 3 : nom d'équipe (insensible à la casse).
|
||||
* Sans nom → pec_id seul (ne fusionne pas tous les « sans nom » ensemble).
|
||||
*/
|
||||
function fxGetBatchTeamShareKey($p) {
|
||||
$strName = fxGetBatchTeamDisplayName($p);
|
||||
if ($strName !== '') {
|
||||
if (function_exists('mb_strtolower')) {
|
||||
return 'n:' . mb_strtolower($strName, 'UTF-8');
|
||||
}
|
||||
|
||||
return 'n:' . strtolower($strName);
|
||||
}
|
||||
|
||||
$intPec = fxGetBatchTeamKey($p);
|
||||
|
||||
return $intPec > 0 ? 'p:' . $intPec : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* MSIN-4379 — Persiste le mode équipe envoyé par l'UI (Simuler / GO).
|
||||
* Évite la course : radio cochée mais save_team_mode AJAX pas encore terminé.
|
||||
*
|
||||
* @return int Mode effectif (1 ou 3), 0 si rien à appliquer
|
||||
*/
|
||||
@ -8939,7 +8981,57 @@ function fxBibSyncTeamModeFromRequest($epr_id) {
|
||||
}
|
||||
|
||||
/**
|
||||
* MSIN-4433 — Mode équipe 3 : dossard déjà posé sur un coéquipier (batch par paquets).
|
||||
* MSIN-4433 / MSIN-4379 — Mode 3 : dossard déjà posé sur un coéquipier (même nom d'équipe).
|
||||
*/
|
||||
function fxGetExistingTeamBibByShareKeyInDb($epr_id, $p) {
|
||||
global $objDatabase;
|
||||
|
||||
$epr_id = (int)$epr_id;
|
||||
$sqlBibNum = fxBibSqlNoBibUnsigned('p.no_bib');
|
||||
$strName = fxGetBatchTeamDisplayName($p);
|
||||
$strEscName = $objDatabase->fxEscape($strName);
|
||||
|
||||
if ($epr_id <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($strName !== '') {
|
||||
$sql = "
|
||||
SELECT $sqlBibNum
|
||||
FROM resultats_participants p
|
||||
LEFT JOIN resultats_epreuves_commandees c
|
||||
ON c.pec_id_original = p.pec_id
|
||||
AND c.epr_id = p.epr_id
|
||||
WHERE p.epr_id = $epr_id
|
||||
AND p.is_cancelled = 0
|
||||
AND $sqlBibNum > 0
|
||||
AND LOWER(TRIM(IFNULL(NULLIF(c.pec_nom_equipe, ''), IFNULL(p.par_nom_equipe, ''))))
|
||||
= LOWER('$strEscName')
|
||||
LIMIT 1
|
||||
";
|
||||
} else {
|
||||
$teamKey = fxGetBatchTeamKey($p);
|
||||
if ($teamKey <= 0) {
|
||||
return null;
|
||||
}
|
||||
$sql = "
|
||||
SELECT $sqlBibNum
|
||||
FROM resultats_participants p
|
||||
WHERE p.epr_id = $epr_id
|
||||
AND p.pec_id = $teamKey
|
||||
AND p.is_cancelled = 0
|
||||
AND $sqlBibNum > 0
|
||||
LIMIT 1
|
||||
";
|
||||
}
|
||||
|
||||
$bib = (int)$objDatabase->fxGetVar($sql);
|
||||
|
||||
return $bib > 0 ? $bib : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated MSIN-4379 — préférer fxGetExistingTeamBibByShareKeyInDb (nom d'équipe).
|
||||
*/
|
||||
function fxGetExistingTeamBibInDb($epr_id, $teamKey) {
|
||||
global $objDatabase;
|
||||
@ -9027,24 +9119,29 @@ function fxCountBatchAssignUnits($epr_id, $participants = null) {
|
||||
$teams = [];
|
||||
|
||||
foreach ($participants as $p) {
|
||||
$teamKey = fxGetBatchTeamKey($p);
|
||||
$strShareKey = fxGetBatchTeamShareKey($p);
|
||||
|
||||
if ($teamKey > 0) {
|
||||
$teams[$teamKey] = true;
|
||||
if ($strShareKey !== '') {
|
||||
$teams[$strShareKey] = true;
|
||||
}
|
||||
}
|
||||
|
||||
return count($teams);
|
||||
}
|
||||
|
||||
$strTeamName = "TRIM(IFNULL(NULLIF(c.pec_nom_equipe, ''), IFNULL(p.par_nom_equipe, '')))";
|
||||
$strTeamUnit = "IF($strTeamName <> '', LOWER($strTeamName), CONCAT('pec:', p.pec_id))";
|
||||
|
||||
return (int)$objDatabase->fxGetVar("
|
||||
SELECT COUNT(DISTINCT p.pec_id)
|
||||
SELECT COUNT(DISTINCT $strTeamUnit)
|
||||
FROM resultats_participants p
|
||||
LEFT JOIN resultats_epreuves_commandees c
|
||||
ON c.pec_id_original = p.pec_id
|
||||
AND c.epr_id = p.epr_id
|
||||
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
|
||||
");
|
||||
}
|
||||
|
||||
@ -9107,12 +9204,17 @@ function fxProcessBatchAssignmentsEquipe($epr_id, $participants, $tabRanges, $mo
|
||||
$teamNumber = 0;
|
||||
$foundBib = null;
|
||||
|
||||
// MSIN-4379 — Mode 1 équipe = 1 dossard : un numéro pour toute l'équipe (même pec_id).
|
||||
if ($teamMode === 3 && $teamKey > 0) {
|
||||
if (isset($teamBibMap[$teamKey])) {
|
||||
$foundBib = $teamBibMap[$teamKey];
|
||||
// MSIN-4379 — Mode 1 équipe = 1 dossard : regrouper sur le NOM d'équipe (colonne Équipe).
|
||||
if ($teamMode === 3) {
|
||||
$strShareKey = fxGetBatchTeamShareKey($p);
|
||||
if ($strShareKey === '') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isset($teamBibMap[$strShareKey])) {
|
||||
$foundBib = $teamBibMap[$strShareKey];
|
||||
} else {
|
||||
$foundBib = fxGetExistingTeamBibInDb($epr_id, $teamKey);
|
||||
$foundBib = fxGetExistingTeamBibByShareKeyInDb($epr_id, $p);
|
||||
}
|
||||
|
||||
if ($foundBib === null) {
|
||||
@ -9127,14 +9229,16 @@ function fxProcessBatchAssignmentsEquipe($epr_id, $participants, $tabRanges, $mo
|
||||
if ($foundBib === null) {
|
||||
break;
|
||||
}
|
||||
// Premier membre déjà écrit en execute par fxTryAssignNextBibForParticipant.
|
||||
if ($mode === 'execute') {
|
||||
$processedParIds[$par_id] = true;
|
||||
$assignments[] = fxBuildBatchAssignmentRow($p, $foundBib, $foundBib);
|
||||
if ($teamKey > 0) {
|
||||
fxApplyBatchTeamNumber($epr_id, $teamKey, $foundBib, $updatedTeams);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$teamBibMap[$teamKey] = (int)$foundBib;
|
||||
$teamBibMap[$strShareKey] = (int)$foundBib;
|
||||
$teamNumber = (int)$foundBib;
|
||||
|
||||
foreach ($participants as $mate) {
|
||||
@ -9142,23 +9246,22 @@ function fxProcessBatchAssignmentsEquipe($epr_id, $participants, $tabRanges, $mo
|
||||
if ($mateId <= 0 || isset($processedParIds[$mateId])) {
|
||||
continue;
|
||||
}
|
||||
if (fxGetBatchTeamKey($mate) !== $teamKey) {
|
||||
if (fxGetBatchTeamShareKey($mate) !== $strShareKey) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($mode === 'execute') {
|
||||
// 0 affected = déjà ce dossard (paquet précédent) : OK, on continue le regroupement.
|
||||
fxApplyBatchParticipantBib($epr_id, $mateId, $teamNumber);
|
||||
$matePec = fxGetBatchTeamKey($mate);
|
||||
if ($matePec > 0) {
|
||||
fxApplyBatchTeamNumber($epr_id, $matePec, $teamNumber, $updatedTeams);
|
||||
}
|
||||
}
|
||||
|
||||
$assignments[] = fxBuildBatchAssignmentRow($mate, $teamNumber, $teamNumber);
|
||||
$processedParIds[$mateId] = true;
|
||||
}
|
||||
|
||||
if ($mode === 'execute') {
|
||||
fxApplyBatchTeamNumber($epr_id, $teamKey, $teamNumber, $updatedTeams);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
* Constantes *
|
||||
*
|
||||
**************/
|
||||
define('_VERSION_CODE', '4.72.911'); // MSIN-4379 — GO batch 1 équipe = 1 dossard (mode UI + regroupement)
|
||||
define('_VERSION_CODE', '4.72.912'); // MSIN-4379 — 1 équipe = 1 dossard : regroupement sur nom d'équipe
|
||||
define('_DATE_CODE', '2026-07-30');
|
||||
//MSIN-4290
|
||||
define('QR_SECRET_KEY', 'ms1_qr_2026_cle_secrete_longue_et_fixe');
|
||||
|
||||
Reference in New Issue
Block a user