MSIN-4445 — Implement free assignment functionality for solo events without sequence creation. Add new actions for analysis, simulation, and planning of free ranges. Update UI components and JavaScript logic to support the new features, including feedback mechanisms for quantity validation. Increment version code to 4.72.828.

This commit is contained in:
2026-07-16 09:51:34 -04:00
parent b72ea70242
commit 77799add6d
7 changed files with 1393 additions and 7 deletions

View File

@ -45,6 +45,10 @@ $arrBibAjaxActions = [
'batch_global_gen_analysis',
'batch_global_gen_simulate',
'batch_global_gen_create',
'batch_global_free_analysis',
'batch_global_free_simulate',
'batch_global_free_plan',
'batch_apply_free_chunk',
'global_batch_panel',
'dist_print_panel',
];
@ -700,6 +704,94 @@ if ($action == 'batch_global_gen_create') {
exit;
}
// MSIN-4445 — Analyse batch global libre (Début/Fin, sans séquence).
if ($action == 'batch_global_free_analysis') {
$int_eve_id = (int)($_POST['eve_id'] ?? 0);
$intStart = (int)($_POST['start_bib'] ?? 0);
$intEnd = (int)($_POST['end_bib'] ?? 0);
list($strSort1, $strSort2) = fxBibParseBatchSortFromPost();
$eprIds = json_decode($_POST['epr_ids'] ?? '[]', true);
$tabEprIds = fxBibParseGlobalBatchGeneratedEprIds(is_array($eprIds) ? $eprIds : [], $int_eve_id);
if ($int_eve_id <= 0 || $intStart <= 0 || $intEnd < $intStart || $strSort1 === '' || empty($tabEprIds)) {
echo json_encode([
'success' => false,
'message' => fxBibMsg('bib_v4_global_batch_free_plan_invalid'),
]);
exit;
}
$tabPlan = fxBibBuildFreeRangePlan($int_eve_id, $tabEprIds, $intStart, $intEnd, $strSort1, $strSort2);
$tabAnalysis = fxBibBuildGlobalBatchFreeAnalysis($tabPlan, $intStart, $intEnd);
echo json_encode([
'success' => true,
'info' => $tabAnalysis['info'],
'stats' => $tabAnalysis['stats'],
'feedback' => $tabAnalysis['feedback'],
]);
exit;
}
// MSIN-4445 — Simulation batch global libre.
if ($action == 'batch_global_free_simulate') {
$int_eve_id = (int)($_POST['eve_id'] ?? 0);
$intStart = (int)($_POST['start_bib'] ?? 0);
$intEnd = (int)($_POST['end_bib'] ?? 0);
list($strSort1, $strSort2) = fxBibParseBatchSortFromPost();
$eprIds = json_decode($_POST['epr_ids'] ?? '[]', true);
$tabEprIds = fxBibParseGlobalBatchGeneratedEprIds(is_array($eprIds) ? $eprIds : [], $int_eve_id);
if ($int_eve_id <= 0 || $intStart <= 0 || $intEnd < $intStart || $strSort1 === '' || empty($tabEprIds)) {
echo json_encode([
'success' => false,
'message' => fxBibMsg('bib_v4_global_batch_free_plan_invalid'),
]);
exit;
}
$tabPlan = fxBibBuildFreeRangePlan($int_eve_id, $tabEprIds, $intStart, $intEnd, $strSort1, $strSort2);
$result = fxBibSimulateGlobalBatchFree(
$int_eve_id,
$tabPlan,
$intStart,
$intEnd,
$strSort1,
$strSort2,
$strLangue
);
echo json_encode($result);
exit;
}
// MSIN-4445 — Prépare les plans GO libres (aucune création de séquence).
if ($action == 'batch_global_free_plan') {
$int_eve_id = (int)($_POST['eve_id'] ?? 0);
$intStart = (int)($_POST['start_bib'] ?? 0);
$intEnd = (int)($_POST['end_bib'] ?? 0);
list($strSort1, $strSort2) = fxBibParseBatchSortFromPost();
$eprIds = json_decode($_POST['epr_ids'] ?? '[]', true);
$tabEprIds = fxBibParseGlobalBatchGeneratedEprIds(is_array($eprIds) ? $eprIds : [], $int_eve_id);
if ($int_eve_id <= 0 || $intStart <= 0 || $intEnd < $intStart || $strSort1 === '' || empty($tabEprIds)) {
echo json_encode([
'success' => false,
'message' => fxBibMsg('bib_v4_global_batch_free_plan_invalid'),
]);
exit;
}
$tabPlan = fxBibBuildFreeRangePlan($int_eve_id, $tabEprIds, $intStart, $intEnd, $strSort1, $strSort2);
$prepare = fxBibPrepareFreeRangePlans($int_eve_id, $tabPlan, $intStart, $intEnd, $strLangue);
echo json_encode($prepare);
exit;
}
if ($action == 'refresh_ranges') {
$epr_id = intval($_POST['epr_id'] ?? $_GET['epr_id'] ?? 0);
@ -965,6 +1057,116 @@ if ($action == 'batch_apply_chunk') {
echo json_encode($arrResponse);
exit;
}
// MSIN-4445 — GO batch par paquets avec plage virtuelle (sans séquence en BD).
if ($action == 'batch_apply_free_chunk') {
$epr_id = intval($_POST['epr_id'] ?? 0);
$intStart = (int)($_POST['start_bib'] ?? 0);
$intEnd = (int)($_POST['end_bib'] ?? 0);
list($strSort1, $strSort2) = fxBibParseBatchSortFromPost();
$intChunkSize = (int)($_POST['chunk_size'] ?? 50);
$intTotalInitial = (int)($_POST['total_initial'] ?? 0);
$blnBatchReset = ((int)($_POST['batch_reset'] ?? 0) === 1);
if ($intChunkSize < 1) {
$intChunkSize = 50;
}
if ($intChunkSize > 100) {
$intChunkSize = 100;
}
if ($epr_id <= 0 || $intStart <= 0 || $intEnd < $intStart) {
echo json_encode([
'success' => false,
'message' => fxBibMsg('bib_v4_global_batch_free_plan_invalid'),
]);
exit;
}
// Même filtre que le panneau : solo sans séquence.
$intEveId = (int)($_POST['eve_id'] ?? 0);
if ($intEveId > 0) {
$checkEpr = fxBibAssertSoloEpreuveForGlobalBatch($epr_id, $intEveId);
if (!$checkEpr['success']) {
echo json_encode($checkEpr);
exit;
}
if (fxBibEpreuveHasAnySequence($epr_id)) {
echo json_encode([
'success' => false,
'message' => fxBibMsg('bib_v4_global_batch_gen_has_seq'),
]);
exit;
}
}
$strSessionKey = fxBibBatchExecSessionKey($epr_id) . '_free';
if ($blnBatchReset) {
$_SESSION[$strSessionKey] = [];
fxBibSaveEpreuveBatchSort($epr_id, $strSort1, $strSort2);
} elseif (!isset($_SESSION[$strSessionKey]) || !is_array($_SESSION[$strSessionKey])) {
$_SESSION[$strSessionKey] = [];
}
$participants = fxGetParticipantsForBatchAssign($epr_id, $strSort1, $strSort2);
if ($intTotalInitial <= 0) {
$intTotalInitial = count($participants) + count($_SESSION[$strSessionKey]);
}
if (empty($participants)) {
$execAll = $_SESSION[$strSessionKey];
unset($_SESSION[$strSessionKey]);
$html = fxBibBuildBatchApplyHtml($epr_id, $execAll, $intTotalInitial, $strLangue);
echo json_encode([
'success' => true,
'complete' => true,
'total_initial' => $intTotalInitial,
'processed' => $intTotalInitial,
'assigned_total' => count($execAll),
'assigned_chunk' => 0,
'html' => $html
]);
exit;
}
$tabChunk = array_slice($participants, 0, $intChunkSize);
$tabRanges = fxBibBuildVirtualRangesForPlan($intStart, $intEnd);
$execChunk = fxProcessBatchAssignments($epr_id, $tabChunk, $tabRanges, 'execute');
$_SESSION[$strSessionKey] = array_merge($_SESSION[$strSessionKey], $execChunk);
$intRemaining = count(fxGetParticipantsForBatchAssign($epr_id, $strSort1, $strSort2));
$intProcessed = max(0, $intTotalInitial - $intRemaining);
$blnComplete = ($intRemaining === 0);
if (!$blnComplete && empty($execChunk)) {
$blnComplete = true;
}
$arrResponse = [
'success' => true,
'complete' => $blnComplete,
'total_initial' => $intTotalInitial,
'processed' => $intProcessed,
'assigned_total' => count($_SESSION[$strSessionKey]),
'assigned_chunk' => count($execChunk),
];
if ($blnComplete) {
$execAll = $_SESSION[$strSessionKey];
unset($_SESSION[$strSessionKey]);
$arrResponse['html'] = fxBibBuildBatchApplyHtml($epr_id, $execAll, $intTotalInitial, $strLangue);
}
echo json_encode($arrResponse);
exit;
}
// =====================
// RESET PREVIEW
// =====================