diff --git a/inc_footer_scripts.php b/inc_footer_scripts.php
index 8857256..b6ecee3 100644
--- a/inc_footer_scripts.php
+++ b/inc_footer_scripts.php
@@ -1988,6 +1988,45 @@ if ($strLangue == 'fr') {
});
}
+ function bibRowPendingBibs(row) {
+ if (!row) return 0;
+ return parseInt(row.dataset.bibAAssigner || '0', 10) || 0;
+ }
+
+ function bibSyncEprBibStats(row, info) {
+ if (!row || !info) return;
+
+ if (info.total !== undefined) {
+ let totalEl = row.querySelector('.bib-total');
+ if (totalEl) totalEl.textContent = info.total;
+ }
+ if (info.avec_bib !== undefined) {
+ let avecEl = row.querySelector('.bib-avec');
+ if (avecEl) avecEl.textContent = info.avec_bib;
+ }
+
+ let pending = (info.a_assigner !== undefined && info.a_assigner !== null)
+ ? info.a_assigner
+ : (info.sans_bib || 0);
+ row.dataset.bibAAssigner = String(parseInt(pending, 10) || 0);
+ }
+
+ function bibAlertAutoPendingBibs(row) {
+ alert(bibJsFmt('jsAutoPendingBibs', bibRowPendingBibs(row)).replace(/\\n/g, '\n'));
+ }
+
+ /** Bloque l'entrée en mode auto si des inscriptions n'ont pas encore de dossard. */
+ function bibBlockAutoActivation(row) {
+ if (!row || row.dataset.autoActive === '1') {
+ return false;
+ }
+ if (bibRowPendingBibs(row) > 0) {
+ bibAlertAutoPendingBibs(row);
+ return true;
+ }
+ return false;
+ }
+
// MSIN-4379 — Réduire / développer les blocs gestion et assignation (en-tête seul visible).
moduleBib.addEventListener('click', function (e) {
let btnToggle = e.target.closest('.epr-block-toggle');
@@ -2235,6 +2274,10 @@ if ($strLangue == 'fr') {
return;
}
+ if (bibBlockAutoActivation(row)) {
+ return;
+ }
+
row.classList.add('auto-mode');
let container = row.querySelector('.bib-container');
@@ -2361,19 +2404,9 @@ if ($strLangue == 'fr') {
if (!data.success) return;
- let totalEl = row.querySelector('.bib-total');
- let avecEl = row.querySelector('.bib-avec');
-
- if (totalEl) totalEl.textContent = data.info.total;
- if (avecEl) avecEl.textContent = data.info.avec_bib;
+ bibSyncEprBibStats(row, data.info);
syncBibUiState(row);
- 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 sansBib = bibRowPendingBibs(row);
let isResetMode = row.dataset.mode === 'reset';
let message = '';
@@ -3183,11 +3216,7 @@ if ($strLangue == 'fr') {
if (!stats.success) return;
- let totalEl = row.querySelector('.bib-total');
- let avecEl = row.querySelector('.bib-avec');
-
- if (totalEl) totalEl.textContent = stats.info.total;
- if (avecEl) avecEl.textContent = stats.info.avec_bib;
+ bibSyncEprBibStats(row, stats.info);
syncBibUiState(row);
});
});
@@ -3220,6 +3249,11 @@ if ($strLangue == 'fr') {
return;
}
+ if (bibRowPendingBibs(row) > 0) {
+ bibAlertAutoPendingBibs(row);
+ return;
+ }
+
// MSIN-4379 — Persiste epr_bib_auto=1 sur les séquences choisies (save_auto_config).
fetch('/ajax_bib_range.php', {
method: 'POST',
diff --git a/php/inc_fx_promoteur.php b/php/inc_fx_promoteur.php
index 98147d6..709de4c 100644
--- a/php/inc_fx_promoteur.php
+++ b/php/inc_fx_promoteur.php
@@ -2919,6 +2919,7 @@ function fxBibModuleJsDataAttrs() {
'auto-select-hint' => 'bib_v4_auto_select_hint',
'lock-confirm' => 'bib_v4_js_lock_confirm',
'unlock-confirm' => 'bib_v4_js_unlock_confirm',
+ 'auto-pending-bibs' => 'bib_v4_js_auto_pending_bibs',
];
$html = '';
foreach ($map as $attr => $clef) {
@@ -3585,7 +3586,8 @@ function fxShowBibTool4($str_code, $int_eve_id, $strLangue){
data-batch-label-cancel=""
data-reset-label=""
data-reset-cancel-label=""
- data-go-label="">
+ data-go-label=""
+ data-bib-a-assigner="">
@@ -3870,6 +3872,21 @@ function fxIsBibAutoActive($epr_id) {
return (int)$objDatabase->fxGetVar($sql) > 0;
}
+/** MSIN-4379 — Refuse l'activation auto tant qu'il reste des inscriptions sans dossard. */
+function fxBibAssertAllBibsAssignedForAuto($epr_id) {
+ $info = fxInfosBibEpreuve(intval($epr_id));
+ $nbPending = (int)($info['a_assigner'] ?? 0);
+
+ if ($nbPending > 0) {
+ return [
+ 'success' => false,
+ 'message' => fxBibMsg('bib_v4_ajax_auto_pending_bibs', $nbPending),
+ ];
+ }
+
+ return ['success' => true];
+}
+
/**
* MSIN-4379 — Étape 2
* Enregistre la config auto : remet toutes les séquences à 0, puis marque
@@ -3896,6 +3913,11 @@ function fxSaveBibAutoConfig($epr_id, $ranges, $active = true) {
return ['success' => true, 'auto_active' => false];
}
+ $pendingCheck = fxBibAssertAllBibsAssignedForAuto($epr_id);
+ if (!$pendingCheck['success']) {
+ return $pendingCheck;
+ }
+
if (empty($ranges) || !is_array($ranges)) {
return ['success' => false, 'message' => fxBibMsg('bib_v4_ajax_no_seq_selected')];
}
diff --git a/php/inc_settings.php b/php/inc_settings.php
index 79c8deb..2109660 100644
--- a/php/inc_settings.php
+++ b/php/inc_settings.php
@@ -7,7 +7,7 @@
* Constantes *
*
**************/
-define('_VERSION_CODE', '4.72.663');
+define('_VERSION_CODE', '4.72.664');
define('_DATE_CODE', '2026-06-18');
//MSIN-4290
define('QR_SECRET_KEY', 'ms1_qr_2026_cle_secrete_longue_et_fixe');
diff --git a/sql/MSIN-4379-bib_v4-auto-pending-bibs.sql b/sql/MSIN-4379-bib_v4-auto-pending-bibs.sql
new file mode 100644
index 0000000..2b67729
--- /dev/null
+++ b/sql/MSIN-4379-bib_v4-auto-pending-bibs.sql
@@ -0,0 +1,17 @@
+-- MSIN-4379 — Assignation auto : refus si des inscriptions n'ont pas encore de dossard
+
+INSERT INTO info (info_clef, info_langue, info_texte, info_aide, info_prg, info_description, info_trie, info_actif, info_option1, info_option2, info_option3, info_creation)
+SELECT 'bib_v4_ajax_auto_pending_bibs', 'fr', 'Terminez d''assigner les dossards à toutes les inscriptions de cette épreuve avant d''activer l''assignation automatique.\n\n%d inscription(s) sans dossard.', '', 'compte.php', '', 0, 1, '', '', '', NOW()
+FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM info WHERE info_clef = 'bib_v4_ajax_auto_pending_bibs' AND info_langue = 'fr' AND info_prg = 'compte.php');
+
+INSERT INTO info (info_clef, info_langue, info_texte, info_aide, info_prg, info_description, info_trie, info_actif, info_option1, info_option2, info_option3, info_creation)
+SELECT 'bib_v4_ajax_auto_pending_bibs', 'en', 'Finish assigning bib numbers to all registrations in this race before enabling automatic assignment.\n\n%d registration(s) without a bib number.', '', 'compte.php', '', 0, 1, '', '', '', NOW()
+FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM info WHERE info_clef = 'bib_v4_ajax_auto_pending_bibs' AND info_langue = 'en' AND info_prg = 'compte.php');
+
+INSERT INTO info (info_clef, info_langue, info_texte, info_aide, info_prg, info_description, info_trie, info_actif, info_option1, info_option2, info_option3, info_creation)
+SELECT 'bib_v4_js_auto_pending_bibs', 'fr', 'Terminez d''assigner les dossards à toutes les inscriptions de cette épreuve avant d''activer l''assignation automatique.\n\n%d inscription(s) sans dossard.', '', 'compte.php', '', 0, 1, '', '', '', NOW()
+FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM info WHERE info_clef = 'bib_v4_js_auto_pending_bibs' AND info_langue = 'fr' AND info_prg = 'compte.php');
+
+INSERT INTO info (info_clef, info_langue, info_texte, info_aide, info_prg, info_description, info_trie, info_actif, info_option1, info_option2, info_option3, info_creation)
+SELECT 'bib_v4_js_auto_pending_bibs', 'en', 'Finish assigning bib numbers to all registrations in this race before enabling automatic assignment.\n\n%d registration(s) without a bib number.', '', 'compte.php', '', 0, 1, '', '', '', NOW()
+FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM info WHERE info_clef = 'bib_v4_js_auto_pending_bibs' AND info_langue = 'en' AND info_prg = 'compte.php');