Add SQL functions for duplicate unit count and anomaly detection in bib management

This commit introduces two new SQL functions: `fxBibSqlDuplicateUnitCount`, which counts the number of units sharing a `no_bib` for an event, and `fxBibSqlIsBibDuplicateAnomaly`, which checks for duplicate anomalies excluding legitimate team sharing. These functions enhance the existing bib management logic by improving the accuracy of duplicate detection. Additionally, the existing SQL queries in `fxInfosBibRange` and `fxBibAnomalyDuplicateBibs` are updated to utilize the new functions for better clarity and efficiency.
This commit is contained in:
2026-06-19 10:56:09 -04:00
parent a8bcd26cdd
commit fd1d136842

View File

@ -3844,6 +3844,35 @@ function fxBibSqlNoBibUnsigned($strColumn = 'no_bib') {
return "CAST(NULLIF(TRIM($strColumn), '') AS UNSIGNED)";
}
/**
* 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).
*/
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)";
return "(CASE WHEN $strTeamMode = 3 THEN (
SELECT COUNT(DISTINCT IF(p2.pec_id > 0, p2.pec_id, p2.par_id))
FROM resultats_participants p2
WHERE p2.epr_id = ($strEprIdExpr)
AND $strBibP2 = ($strBibNumExpr)
AND p2.is_cancelled = 0
) ELSE (
SELECT COUNT(*)
FROM resultats_participants p2
WHERE p2.epr_id = ($strEprIdExpr)
AND $strBibP2 = ($strBibNumExpr)
AND p2.is_cancelled = 0
) END)";
}
/** SQL — vrai doublon (anomalie), hors partage légitime entre coéquipiers (mode équipe 3). */
function fxBibSqlIsBibDuplicateAnomaly($strEprIdExpr, $strBibNumExpr) {
return fxBibSqlDuplicateUnitCount($strEprIdExpr, $strBibNumExpr) . ' > 1';
}
function fxInfosBibRange($epr_id = 0, $epr_bib_id = 0){
global $objDatabase, $vDomaine;
@ -3865,7 +3894,6 @@ function fxInfosBibRange($epr_id = 0, $epr_bib_id = 0){
$sqlBibNumP = fxBibSqlNoBibUnsigned('p.no_bib');
$sqlBibNumRp = fxBibSqlNoBibUnsigned('rp.no_bib');
$sqlBibNumRp2 = fxBibSqlNoBibUnsigned('rp2.no_bib');
$sqlBibStats = "
SELECT
@ -3949,13 +3977,9 @@ function fxInfosBibRange($epr_id = 0, $epr_bib_id = 0){
SELECT GROUP_CONCAT(DISTINCT $sqlBibNumRp ORDER BY $sqlBibNumRp SEPARATOR ',')
FROM resultats_participants rp
WHERE rp.epr_id = b.epr_id
AND rp.is_cancelled = 0
AND $sqlBibNumRp BETWEEN b.epr_bib_start AND b.epr_bib_finish
AND (
SELECT COUNT(*)
FROM resultats_participants rp2
WHERE rp2.epr_id = rp.epr_id
AND $sqlBibNumRp2 = $sqlBibNumRp
) > 1
AND " . fxBibSqlIsBibDuplicateAnomaly('rp.epr_id', $sqlBibNumRp) . "
) AS liste_doublons
FROM inscriptions_epreuves_bib b
@ -4033,13 +4057,7 @@ function fxBibAnomalyDuplicateBibs($int_eve_id, $strLangue = 'fr') {
WHERE e.eve_id = $int_eve_id
AND b.epr_bib_start IS NOT NULL
AND b.epr_bib_finish IS NOT NULL
AND (
SELECT COUNT(*)
FROM resultats_participants p2
WHERE p2.epr_id = b.epr_id
AND p2.is_cancelled = 0
AND " . fxBibSqlNoBibUnsigned('p2.no_bib') . " = $sqlBibNumP
) > 1
AND " . fxBibSqlIsBibDuplicateAnomaly('b.epr_id', $sqlBibNumP) . "
ORDER BY b.epr_id, b.epr_bib_start, $sqlBibNumP, p.par_nom, p.par_prenom
";