Implement locking mechanism for bib ranges with AJAX support
This commit introduces a locking feature for bib ranges, allowing users to lock or unlock sequences via a new AJAX endpoint. The PHP code is updated to check for locked statuses before performing actions, enhancing data integrity. Additionally, new JavaScript functions are added to handle user interactions for locking and unlocking, along with corresponding CSS styles for visual feedback. This improves the user experience by preventing modifications to locked sequences and providing clear confirmation messages.
This commit is contained in:
@ -73,6 +73,20 @@ if ($action == 'delete') {
|
||||
|
||||
if ($id > 0) {
|
||||
|
||||
$rowLock = $objDatabase->fxGetRow("
|
||||
SELECT epr_bib_locked
|
||||
FROM inscriptions_epreuves_bib
|
||||
WHERE epr_bib_id = $id
|
||||
");
|
||||
|
||||
if ($rowLock && (int)($rowLock['epr_bib_locked'] ?? 0) === 1) {
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => fxBibMsg('bib_v4_ajax_range_locked')
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$range = fxInfosBibRange(0,$id);
|
||||
|
||||
$epr_id = $range[1]["epr_id"];
|
||||
@ -169,8 +183,20 @@ if ($action == 'save') {
|
||||
// =====================
|
||||
if (!$is_new) {
|
||||
|
||||
$sqlGet = "SELECT epr_id FROM inscriptions_epreuves_bib WHERE epr_bib_id = $id";
|
||||
$epr_id = (int)$objDatabase->fxGetVar($sqlGet);
|
||||
$sqlGet = "SELECT epr_id, epr_bib_locked FROM inscriptions_epreuves_bib WHERE epr_bib_id = $id";
|
||||
$rowRange = $objDatabase->fxGetRow($sqlGet);
|
||||
|
||||
if (!$rowRange || (int)($rowRange['epr_id'] ?? 0) <= 0) {
|
||||
echo json_encode(['success' => false, 'message' => fxBibMsg('bib_v4_ajax_range_not_found')]);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ((int)($rowRange['epr_bib_locked'] ?? 0) === 1) {
|
||||
echo json_encode(['success' => false, 'message' => fxBibMsg('bib_v4_ajax_range_locked')]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$epr_id = (int)$rowRange['epr_id'];
|
||||
|
||||
if ($epr_id <= 0) {
|
||||
echo json_encode(['success' => false, 'message' => fxBibMsg('bib_v4_ajax_range_not_found')]);
|
||||
@ -373,6 +399,15 @@ if ($action == 'batch_go') {
|
||||
// Liste des ranges sélectionnés (JSON → array PHP)
|
||||
$ranges = json_decode($_POST['ranges'] ?? '[]', true);
|
||||
|
||||
$lockCheck = fxBibAssertRangesUnlocked($epr_id, is_array($ranges) ? $ranges : []);
|
||||
if (!$lockCheck['success']) {
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => $lockCheck['message'] ?? fxBibMsg('bib_v4_ajax_range_locked')
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Ordre choisi (table bib_assignements)
|
||||
$ba_id = intval($_POST['ba_id'] ?? 0);
|
||||
|
||||
@ -444,6 +479,15 @@ if ($action == 'batch_apply') {
|
||||
$ranges = json_decode($_POST['ranges'] ?? '[]', true);
|
||||
$ba_id = intval($_POST['ba_id'] ?? 0);
|
||||
|
||||
$lockCheck = fxBibAssertRangesUnlocked($epr_id, is_array($ranges) ? $ranges : []);
|
||||
if (!$lockCheck['success']) {
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => $lockCheck['message'] ?? fxBibMsg('bib_v4_ajax_range_locked')
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$participants = fxGetParticipantsForBatchAssign($epr_id, $ba_id);
|
||||
$tabRanges = fxGetRangesForBatchAssign($epr_id, $ranges);
|
||||
|
||||
@ -506,6 +550,15 @@ if ($action == 'reset_preview') {
|
||||
|
||||
$ranges = json_decode($_POST['ranges'] ?? '[]', true);
|
||||
|
||||
$lockCheck = fxBibAssertRangesUnlocked($epr_id, is_array($ranges) ? $ranges : []);
|
||||
if (!$lockCheck['success']) {
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => $lockCheck['message'] ?? fxBibMsg('bib_v4_ajax_range_locked')
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$participants = fxGetParticipantsForBatchReset($epr_id, $ranges);
|
||||
|
||||
$html = renderBibView(
|
||||
@ -535,6 +588,15 @@ if ($action == 'reset_apply') {
|
||||
|
||||
$ranges = json_decode($_POST['ranges'] ?? '[]', true);
|
||||
|
||||
$lockCheck = fxBibAssertRangesUnlocked($epr_id, is_array($ranges) ? $ranges : []);
|
||||
if (!$lockCheck['success']) {
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => $lockCheck['message'] ?? fxBibMsg('bib_v4_ajax_range_locked')
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$participants = fxGetParticipantsForBatchReset($epr_id, $ranges);
|
||||
|
||||
$count = 0;
|
||||
@ -611,6 +673,51 @@ if ($action == 'save_team_mode') {
|
||||
exit;
|
||||
}
|
||||
|
||||
// MSIN-4379 — Verrouillage séquence (cadenas ouvert/fermé)
|
||||
if ($action == 'toggle_lock') {
|
||||
|
||||
if (!fxBibRequirePromoteurSession()) {
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => fxBibMsg('bib_v4_ajax_session_invalid')
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!fxBibValidateCsrf($_POST['csrf_token'] ?? '')) {
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => fxBibMsg('bib_v4_ajax_unauthorized')
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$epr_bib_id = intval($_POST['epr_bib_id'] ?? 0);
|
||||
$epr_id = intval($_POST['epr_id'] ?? 0);
|
||||
$locked = intval($_POST['locked'] ?? 0) === 1;
|
||||
|
||||
$result = fxBibSetRangeLocked($epr_bib_id, $locked, $epr_id);
|
||||
|
||||
if (!$result['success']) {
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => $result['message'] ?? fxBibMsg('bib_v4_ajax_error')
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$epr_id = (int)$result['epr_id'];
|
||||
$tabBibStats = fxInfosBibRange($epr_id);
|
||||
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'locked' => !empty($result['locked']),
|
||||
'auto_active' => fxIsBibAutoActive($epr_id),
|
||||
'html' => renderBibRanges($tabBibStats, $epr_id, 'assign')
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// MSIN-4379 — Étape 2
|
||||
// Endpoint AJAX : sauvegarde ou désactivation de la config auto (epr_bib_auto).
|
||||
// Paramètres : epr_id, active (0|1), ranges (JSON des epr_bib_id), csrf_token.
|
||||
|
||||
@ -1813,10 +1813,11 @@ a.ms1-trad-link.btn-aide-trad{
|
||||
width:100%;
|
||||
}
|
||||
|
||||
/* MSIN-4379 — View/OK/Suppr icônes ; stats regroupées ; badge auto à droite. */
|
||||
/* MSIN-4379 — Cadenas + view/OK/stats ; badge auto à droite. */
|
||||
.epr-line{
|
||||
display:grid;
|
||||
grid-template-columns:
|
||||
32px
|
||||
40px
|
||||
58px
|
||||
58px
|
||||
@ -1832,6 +1833,7 @@ a.ms1-trad-link.btn-aide-trad{
|
||||
|
||||
.bib-container.batch-mode .epr-line{
|
||||
grid-template-columns:
|
||||
32px
|
||||
40px
|
||||
58px
|
||||
58px
|
||||
@ -1841,6 +1843,52 @@ a.ms1-trad-link.btn-aide-trad{
|
||||
28px;
|
||||
}
|
||||
|
||||
.epr-col-lock{
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
min-width:0;
|
||||
}
|
||||
|
||||
.btn-bib-lock{
|
||||
width:100%;
|
||||
padding-left:0;
|
||||
padding-right:0;
|
||||
border-width:1px;
|
||||
border-style:solid;
|
||||
}
|
||||
|
||||
.btn-bib-lock--open{
|
||||
background-color:#28a745;
|
||||
border-color:#218838;
|
||||
color:#fff;
|
||||
}
|
||||
|
||||
.btn-bib-lock--open:hover,
|
||||
.btn-bib-lock--open:focus{
|
||||
background-color:#218838;
|
||||
border-color:#1e7e34;
|
||||
color:#fff;
|
||||
}
|
||||
|
||||
.btn-bib-lock--closed{
|
||||
background-color:#dc3545;
|
||||
border-color:#c82333;
|
||||
color:#fff;
|
||||
}
|
||||
|
||||
.btn-bib-lock--closed:hover,
|
||||
.btn-bib-lock--closed:focus{
|
||||
background-color:#c82333;
|
||||
border-color:#bd2130;
|
||||
color:#fff;
|
||||
}
|
||||
|
||||
.bib-range--locked .bib-start,
|
||||
.bib-range--locked .bib-end{
|
||||
background-color:#f1f3f5;
|
||||
}
|
||||
|
||||
.epr-col-stats{
|
||||
display:grid;
|
||||
grid-template-columns:56px 48px 48px;
|
||||
|
||||
@ -1975,6 +1975,10 @@ if ($strLangue == 'fr') {
|
||||
return moduleBib.dataset[attr] || '';
|
||||
}
|
||||
|
||||
function bibJsConfirm(attr) {
|
||||
return bibJs(attr).replace(/\\n/g, '\n');
|
||||
}
|
||||
|
||||
function bibJsFmt(attr) {
|
||||
var tpl = bibJs(attr);
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
@ -2546,6 +2550,59 @@ if ($strLangue == 'fr') {
|
||||
return;
|
||||
}
|
||||
|
||||
// =====================
|
||||
// LOCK / UNLOCK SEQUENCE
|
||||
// =====================
|
||||
let btnLock = e.target.closest('.btn-bib-lock');
|
||||
if (btnLock) {
|
||||
e.preventDefault();
|
||||
|
||||
let row = btnLock.closest('.epr-row');
|
||||
if (!row) return;
|
||||
|
||||
let isLocked = btnLock.dataset.locked === '1';
|
||||
let confirmMsg = isLocked
|
||||
? bibJsConfirm('jsUnlockConfirm')
|
||||
: bibJsConfirm('jsLockConfirm');
|
||||
|
||||
if (!confirm(confirmMsg)) {
|
||||
return;
|
||||
}
|
||||
|
||||
fetch('/ajax_bib_range.php', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
},
|
||||
body:
|
||||
'action=toggle_lock'
|
||||
+ '&epr_bib_id=' + encodeURIComponent(btnLock.dataset.rangeId)
|
||||
+ '&epr_id=' + encodeURIComponent(btnLock.dataset.eprId || row.dataset.eprId)
|
||||
+ '&locked=' + encodeURIComponent(isLocked ? '0' : '1')
|
||||
+ '&csrf_token=' + encodeURIComponent(bibCsrfToken())
|
||||
+ bibAjaxLangSuffix()
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
|
||||
if (!data.success) {
|
||||
alert(data.message || bibJs('jsErrGeneric'));
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof data.auto_active !== 'undefined') {
|
||||
row.dataset.autoActive = data.auto_active ? '1' : '0';
|
||||
syncAutoUiState(row, data.auto_active);
|
||||
}
|
||||
|
||||
if (data.html) {
|
||||
setBibContainerHtml(row, data.html);
|
||||
}
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// =====================
|
||||
// DELETE
|
||||
// =====================
|
||||
|
||||
@ -2917,6 +2917,8 @@ function fxBibModuleJsDataAttrs() {
|
||||
'batch-summary-short' => 'bib_v4_ajax_sim_summary',
|
||||
'batch-reset-count' => 'bib_v4_ajax_reset_preview_count',
|
||||
'auto-select-hint' => 'bib_v4_auto_select_hint',
|
||||
'lock-confirm' => 'bib_v4_js_lock_confirm',
|
||||
'unlock-confirm' => 'bib_v4_js_unlock_confirm',
|
||||
];
|
||||
$html = '';
|
||||
foreach ($map as $attr => $clef) {
|
||||
@ -3073,9 +3075,122 @@ function fxBibIsRangeAvailableForAuto($epr_id, $epr_bib_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fxBibRangeIsLocked($rows[1])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return fxBibRangeDispoFromRow($rows[1]) > 0;
|
||||
}
|
||||
|
||||
/** Séquence verrouillée (epr_bib_locked = 1) — plus de modification ni assignation. */
|
||||
function fxBibRangeIsLocked(array $range) {
|
||||
return (int)($range['epr_bib_locked'] ?? 0) === 1;
|
||||
}
|
||||
|
||||
/** Vérifie qu'aucune des séquences listées n'est verrouillée. */
|
||||
function fxBibAssertRangesUnlocked($epr_id, $rangeIds) {
|
||||
global $objDatabase;
|
||||
|
||||
$epr_id = (int)$epr_id;
|
||||
|
||||
if ($epr_id <= 0 || empty($rangeIds) || !is_array($rangeIds)) {
|
||||
return ['success' => true];
|
||||
}
|
||||
|
||||
$ids = array_values(array_filter(array_map('intval', $rangeIds)));
|
||||
|
||||
if (empty($ids)) {
|
||||
return ['success' => true];
|
||||
}
|
||||
|
||||
$strIds = implode(',', $ids);
|
||||
|
||||
$sql = "
|
||||
SELECT COUNT(*)
|
||||
FROM inscriptions_epreuves_bib
|
||||
WHERE epr_id = $epr_id
|
||||
AND epr_bib_id IN ($strIds)
|
||||
AND epr_bib_locked = 1
|
||||
";
|
||||
|
||||
if ((int)$objDatabase->fxGetVar($sql) > 0) {
|
||||
return ['success' => false, 'message' => fxBibMsg('bib_v4_ajax_range_locked')];
|
||||
}
|
||||
|
||||
return ['success' => true];
|
||||
}
|
||||
|
||||
/** Bascule le verrou d'une séquence (0 = ouvert, 1 = fermé). */
|
||||
function fxBibSetRangeLocked($epr_bib_id, $locked, $epr_id = 0) {
|
||||
global $objDatabase;
|
||||
|
||||
$epr_bib_id = (int)$epr_bib_id;
|
||||
$epr_id = (int)$epr_id;
|
||||
$locked = $locked ? 1 : 0;
|
||||
|
||||
if ($epr_bib_id <= 0) {
|
||||
return ['success' => false, 'message' => fxBibMsg('bib_v4_ajax_id_invalid')];
|
||||
}
|
||||
|
||||
$sqlGet = "
|
||||
SELECT epr_id
|
||||
FROM inscriptions_epreuves_bib
|
||||
WHERE epr_bib_id = $epr_bib_id
|
||||
";
|
||||
$rowEprId = (int)$objDatabase->fxGetVar($sqlGet);
|
||||
|
||||
if ($rowEprId <= 0) {
|
||||
return ['success' => false, 'message' => fxBibMsg('bib_v4_ajax_range_not_found')];
|
||||
}
|
||||
|
||||
if ($epr_id > 0 && $rowEprId !== $epr_id) {
|
||||
return ['success' => false, 'message' => fxBibMsg('bib_v4_ajax_seq_invalid')];
|
||||
}
|
||||
|
||||
$objDatabase->fxQuery("
|
||||
UPDATE inscriptions_epreuves_bib
|
||||
SET epr_bib_locked = $locked
|
||||
WHERE epr_bib_id = $epr_bib_id
|
||||
");
|
||||
|
||||
if ($locked === 1) {
|
||||
$objDatabase->fxQuery("
|
||||
UPDATE inscriptions_epreuves_bib
|
||||
SET epr_bib_auto = 0
|
||||
WHERE epr_bib_id = $epr_bib_id
|
||||
");
|
||||
}
|
||||
|
||||
return [
|
||||
'success' => true,
|
||||
'epr_id' => $rowEprId,
|
||||
'locked' => $locked === 1,
|
||||
];
|
||||
}
|
||||
|
||||
/** Bouton cadenas (vert ouvert / rouge fermé) devant une séquence enregistrée. */
|
||||
function fxBibRenderRangeLockButton(array $range, $epr_id = 0) {
|
||||
if ((int)($range['epr_bib_id'] ?? 0) <= 0) {
|
||||
return '<div class="epr-col-lock"></div>';
|
||||
}
|
||||
|
||||
$locked = fxBibRangeIsLocked($range);
|
||||
$strClass = $locked ? 'btn-bib-lock--closed' : 'btn-bib-lock--open';
|
||||
$strIcon = $locked ? 'fa-lock' : 'fa-unlock';
|
||||
$strTip = $locked ? 'bib_v4_tip_lock_closed' : 'bib_v4_tip_lock_open';
|
||||
|
||||
return '<button type="button"'
|
||||
. ' class="btn btn-sm btn-bib-lock ' . $strClass . '"'
|
||||
. ' data-range-id="' . (int)$range['epr_bib_id'] . '"'
|
||||
. ' data-epr-id="' . (int)$epr_id . '"'
|
||||
. ' data-locked="' . ($locked ? '1' : '0') . '"'
|
||||
. ' aria-pressed="' . ($locked ? 'true' : 'false') . '"'
|
||||
. fxBibTippyAttr($strTip)
|
||||
. '>'
|
||||
. '<i class="fa ' . $strIcon . '" aria-hidden="true"></i>'
|
||||
. '</button>';
|
||||
}
|
||||
|
||||
/** Badge « Assignation automatique » sur une ligne de séquence (epr_bib_auto = 1). */
|
||||
function fxBibRenderRangeAutoBadge(array $range, $mode = 'assign') {
|
||||
if ($mode !== 'assign') {
|
||||
@ -3087,6 +3202,9 @@ function fxBibRenderRangeAutoBadge(array $range, $mode = 'assign') {
|
||||
if ((int)($range['epr_bib_auto'] ?? 0) !== 1) {
|
||||
return '';
|
||||
}
|
||||
if (fxBibRangeIsLocked($range)) {
|
||||
return '';
|
||||
}
|
||||
if (fxBibRangeDispoFromRow($range) <= 0) {
|
||||
return '';
|
||||
}
|
||||
@ -3302,6 +3420,7 @@ function renderBibRangeHeader() {
|
||||
ob_start();
|
||||
?>
|
||||
<div class="epr-line epr-line-header">
|
||||
<div class="epr-col-lock"><?php echo fxBibColHeader('bib_v4_col_lock'); ?></div>
|
||||
<div><?php echo fxBibColHeader('bib_v4_col_view'); ?></div>
|
||||
<div><?php echo fxBibColHeader('bib_v4_col_start'); ?></div>
|
||||
<div><?php echo fxBibColHeader('bib_v4_col_end'); ?></div>
|
||||
@ -3617,6 +3736,7 @@ function fxInfosBibRange($epr_id = 0, $epr_bib_id = 0){
|
||||
b.epr_bib_start,
|
||||
b.epr_bib_finish,
|
||||
b.epr_bib_auto, /* MSIN-4379 — Étape 1 : flag par séquence (pool auto). */
|
||||
b.epr_bib_locked,
|
||||
|
||||
COUNT(p.no_bib) AS nb_utilises,
|
||||
MAX(p.no_bib) AS dernier_bib,
|
||||
@ -3713,7 +3833,8 @@ function fxInfosBibRange($epr_id = 0, $epr_bib_id = 0){
|
||||
b.epr_id,
|
||||
b.epr_bib_start,
|
||||
b.epr_bib_finish,
|
||||
b.epr_bib_auto
|
||||
b.epr_bib_auto,
|
||||
b.epr_bib_locked
|
||||
|
||||
ORDER BY b.epr_bib_start
|
||||
";
|
||||
@ -3741,6 +3862,7 @@ function fxIsBibAutoActive($epr_id) {
|
||||
FROM inscriptions_epreuves_bib
|
||||
WHERE epr_id = $epr_id
|
||||
AND epr_bib_auto = 1
|
||||
AND epr_bib_locked = 0
|
||||
";
|
||||
|
||||
return (int)$objDatabase->fxGetVar($sql) > 0;
|
||||
@ -3802,6 +3924,11 @@ function fxSaveBibAutoConfig($epr_id, $ranges, $active = true) {
|
||||
}
|
||||
}
|
||||
|
||||
$lockCheck = fxBibAssertRangesUnlocked($epr_id, $ids);
|
||||
if (!$lockCheck['success']) {
|
||||
return $lockCheck;
|
||||
}
|
||||
|
||||
$objDatabase->fxQuery("
|
||||
UPDATE inscriptions_epreuves_bib
|
||||
SET epr_bib_auto = 1
|
||||
@ -3830,6 +3957,7 @@ function fxGetAutoBibRangeIds($epr_id) {
|
||||
FROM inscriptions_epreuves_bib
|
||||
WHERE epr_id = $epr_id
|
||||
AND epr_bib_auto = 1
|
||||
AND epr_bib_locked = 0
|
||||
ORDER BY epr_bib_start
|
||||
";
|
||||
|
||||
@ -4095,10 +4223,16 @@ $nb_utilises = (int)($range['nb_utilises'] ?? 0);
|
||||
|
||||
$mem_dispo = max(0, $nb_total - $nb_utilises);
|
||||
|
||||
$blnRangeLocked = fxBibRangeIsLocked($range);
|
||||
|
||||
|
||||
?>
|
||||
|
||||
<div class="bib-range epr-line" data-id="<?php echo $range['epr_bib_id']; ?>">
|
||||
<div class="bib-range epr-line<?php echo $blnRangeLocked ? ' bib-range--locked' : ''; ?>"
|
||||
data-id="<?php echo $range['epr_bib_id']; ?>"
|
||||
data-locked="<?php echo $blnRangeLocked ? '1' : '0'; ?>">
|
||||
|
||||
<?php echo fxBibRenderRangeLockButton($range, $epr_id); ?>
|
||||
|
||||
<?php if ((int)$range['epr_bib_id'] > 0) { ?>
|
||||
<button type="button"
|
||||
@ -4113,22 +4247,26 @@ $mem_dispo = max(0, $nb_total - $nb_utilises);
|
||||
|
||||
<input type="number"
|
||||
class="form-control form-control-sm bib-start"
|
||||
value="<?php echo $range['epr_bib_start']; ?>">
|
||||
value="<?php echo $range['epr_bib_start']; ?>"
|
||||
<?php echo $blnRangeLocked ? 'readonly' : ''; ?>>
|
||||
|
||||
<input type="number"
|
||||
class="form-control form-control-sm bib-end"
|
||||
value="<?php echo $range['epr_bib_finish']; ?>">
|
||||
value="<?php echo $range['epr_bib_finish']; ?>"
|
||||
<?php echo $blnRangeLocked ? 'readonly' : ''; ?>>
|
||||
|
||||
<button type="button"
|
||||
class="btn btn-sm btn-primary btn-save-range"
|
||||
data-id="<?php echo $range['epr_bib_id']; ?>"
|
||||
data-epr-id="<?php echo (int)$epr_id; ?>">
|
||||
data-epr-id="<?php echo (int)$epr_id; ?>"
|
||||
<?php echo $blnRangeLocked ? 'disabled' : ''; ?>>
|
||||
<?php fxBibTexte('bib_v4_btn_ok', 1); ?>
|
||||
</button>
|
||||
<?php if ((int)$range['epr_bib_id'] > 0) { ?>
|
||||
<button type="button"
|
||||
class="btn btn-sm btn-danger btn-delete-range"
|
||||
data-id="<?php echo $range['epr_bib_id']; ?>">
|
||||
data-id="<?php echo $range['epr_bib_id']; ?>"
|
||||
<?php echo $blnRangeLocked ? 'disabled' : ''; ?>>
|
||||
<i class="fa fa-trash"></i>
|
||||
</button>
|
||||
<?php } else { ?>
|
||||
@ -4148,28 +4286,28 @@ $mem_dispo = max(0, $nb_total - $nb_utilises);
|
||||
|
||||
$showCheckbox = false;
|
||||
|
||||
if (
|
||||
if (!$blnRangeLocked && (
|
||||
$mode === 'assign'
|
||||
&& $mem_dispo > 0
|
||||
&& (int)$range['epr_bib_id'] > 0
|
||||
) {
|
||||
)) {
|
||||
$showCheckbox = true;
|
||||
}
|
||||
|
||||
if (
|
||||
if (!$blnRangeLocked && (
|
||||
$mode === 'reset'
|
||||
&& (int)$range['nb_utilises'] > 0
|
||||
&& (int)$range['epr_bib_id'] > 0
|
||||
) {
|
||||
)) {
|
||||
$showCheckbox = true;
|
||||
}
|
||||
|
||||
// MSIN-4379 — Étape 2 : mode « auto » — séquences avec dossards disponibles seulement.
|
||||
if (
|
||||
if (!$blnRangeLocked && (
|
||||
$mode === 'auto'
|
||||
&& $mem_dispo > 0
|
||||
&& (int)$range['epr_bib_id'] > 0
|
||||
) {
|
||||
)) {
|
||||
$showCheckbox = true;
|
||||
}
|
||||
|
||||
|
||||
5
sql/MSIN-4379-bib_v4-range-lock-column.sql
Normal file
5
sql/MSIN-4379-bib_v4-range-lock-column.sql
Normal file
@ -0,0 +1,5 @@
|
||||
-- MSIN-4379 — Verrouillage de séquence de dossards (cadenas ouvert/fermé)
|
||||
|
||||
ALTER TABLE inscriptions_epreuves_bib
|
||||
ADD COLUMN epr_bib_locked TINYINT(1) NOT NULL DEFAULT 0
|
||||
AFTER epr_bib_auto;
|
||||
43
sql/MSIN-4379-bib_v4-range-lock-i18n.sql
Normal file
43
sql/MSIN-4379-bib_v4-range-lock-i18n.sql
Normal file
@ -0,0 +1,43 @@
|
||||
-- MSIN-4379 — i18n verrouillage séquences de dossards
|
||||
|
||||
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_col_lock', 'fr', '', 'Verrouiller ou déverrouiller la séquence.', 'compte.php', '', 0, 1, '', '', '', NOW()
|
||||
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM info WHERE info_clef = 'bib_v4_col_lock' 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_col_lock', 'en', '', 'Lock or unlock the sequence.', 'compte.php', '', 0, 1, '', '', '', NOW()
|
||||
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM info WHERE info_clef = 'bib_v4_col_lock' 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_tip_lock_open', 'fr', 'Séquence ouverte', 'Cliquez pour verrouiller : la plage, les dossards et les assignations ne pourront plus être modifiés.', 'compte.php', '', 0, 1, '', '', '', NOW()
|
||||
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM info WHERE info_clef = 'bib_v4_tip_lock_open' 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_tip_lock_open', 'en', 'Sequence unlocked', 'Click to lock: range, bibs and assignments can no longer be changed.', 'compte.php', '', 0, 1, '', '', '', NOW()
|
||||
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM info WHERE info_clef = 'bib_v4_tip_lock_open' 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_tip_lock_closed', 'fr', 'Séquence verrouillée', 'Cliquez pour déverrouiller (confirmation requise).', 'compte.php', '', 0, 1, '', '', '', NOW()
|
||||
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM info WHERE info_clef = 'bib_v4_tip_lock_closed' 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_tip_lock_closed', 'en', 'Sequence locked', 'Click to unlock (confirmation required).', 'compte.php', '', 0, 1, '', '', '', NOW()
|
||||
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM info WHERE info_clef = 'bib_v4_tip_lock_closed' 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_lock_confirm', 'fr', 'Verrouiller cette séquence ?\n\nTant qu''elle est verrouillée, vous ne pourrez plus modifier la plage de numéros, supprimer la séquence, réinitialiser les dossards ni l''utiliser pour l''assignation automatique ou groupée.', '', 'compte.php', '', 0, 1, '', '', '', NOW()
|
||||
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM info WHERE info_clef = 'bib_v4_js_lock_confirm' 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_lock_confirm', 'en', 'Lock this sequence?\n\nWhile locked, you cannot change the number range, delete the sequence, reset bibs, or use it for automatic or batch assignment.', '', 'compte.php', '', 0, 1, '', '', '', NOW()
|
||||
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM info WHERE info_clef = 'bib_v4_js_lock_confirm' 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_unlock_confirm', 'fr', 'Déverrouiller cette séquence ?\n\nAttention : des dossards peuvent déjà avoir été imprimés ou communiqués. Déverrouiller pourrait compromettre la cohérence de vos données.\n\nConfirmez-vous le déverrouillage ?', '', 'compte.php', '', 0, 1, '', '', '', NOW()
|
||||
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM info WHERE info_clef = 'bib_v4_js_unlock_confirm' 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_unlock_confirm', 'en', 'Unlock this sequence?\n\nWarning: bibs may already have been printed or distributed. Unlocking could compromise your data.\n\nDo you confirm unlocking?', '', 'compte.php', '', 0, 1, '', '', '', NOW()
|
||||
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM info WHERE info_clef = 'bib_v4_js_unlock_confirm' 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_ajax_range_locked', 'fr', 'Cette séquence est verrouillée et ne peut pas être modifiée', '', 'compte.php', '', 0, 1, '', '', '', NOW()
|
||||
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM info WHERE info_clef = 'bib_v4_ajax_range_locked' 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_range_locked', 'en', 'This sequence is locked and cannot be modified', '', 'compte.php', '', 0, 1, '', '', '', NOW()
|
||||
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM info WHERE info_clef = 'bib_v4_ajax_range_locked' AND info_langue = 'en' AND info_prg = 'compte.php');
|
||||
Reference in New Issue
Block a user