Files
ms1inscription-v5/php/inc_fx_bib_ops.php

257 lines
10 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* MSIN-4578 — Tableau de bord temporaire gestionnaire de dossards (ops MS1).
* Pont avant CRM : kit compte « gestionnaire_dossards », pas un extra dévénement.
*/
if (!function_exists('fxBibOpsUserCanAccessGlobal')) {
/** Kit compte gestionnaire_dossards (personne). Pas de bypass super-admin. */
function fxBibOpsUserCanAccessGlobal() {
$intComId = (int)($_SESSION['com_id'] ?? 0);
return $intComId > 0
&& function_exists('fxEveAccesCanBibOpsGlobal')
&& fxEveAccesCanBibOpsGlobal($intComId);
}
function fxBibOpsUserCanAccessCommande($intEveId) {
$intEveId = (int)$intEveId;
if ($intEveId <= 0) {
return false;
}
if (function_exists('fxBibProductionUserCanManageEvent')
&& fxBibProductionUserCanManageEvent($intEveId)) {
return true;
}
return fxBibOpsUserCanAccessGlobal();
}
function fxBibOpsHubUrl($strLangue = 'fr') {
global $vDomaine;
return rtrim((string)$vDomaine, '/')
. (($strLangue === 'en') ? '/account/promoteur_hub' : '/compte/promoteur_hub');
}
/**
* Événements actifs à venir qui ont au moins une séquence de dossard.
* @return array<int, array<string, mixed>>
*/
function fxBibOpsLoadUpcomingBibEvents($strLangue = 'fr') {
global $objDatabase;
$strLangue = ($strLangue === 'en') ? 'en' : 'fr';
$strAlt = ($strLangue === 'fr') ? 'en' : 'fr';
$tabOut = [];
$tabEvents = $objDatabase->fxGetResults(
"SELECT e.eve_id, e.eve_nom_fr, e.eve_nom_en,
e.eve_date_debut, e.eve_date_fin
FROM inscriptions_evenements e
WHERE e.eve_actif = 1
AND (
(e.eve_date_fin IS NOT NULL
AND e.eve_date_fin <> '0000-00-00'
AND e.eve_date_fin >= CURDATE())
OR ((e.eve_date_fin IS NULL OR e.eve_date_fin = '0000-00-00')
AND e.eve_date_debut IS NOT NULL
AND e.eve_date_debut <> '0000-00-00'
AND e.eve_date_debut >= CURDATE())
)
AND EXISTS (
SELECT 1
FROM inscriptions_epreuves ep
INNER JOIN inscriptions_epreuves_bib b ON b.epr_id = ep.epr_id
WHERE ep.eve_id = e.eve_id
AND ep.epr_actif = 1
)
ORDER BY e.eve_date_debut ASC, e.eve_nom_fr ASC"
);
if (!is_array($tabEvents)) {
return $tabOut;
}
$tabEveIds = [];
foreach ($tabEvents as $tabRow) {
$intEveId = (int)($tabRow['eve_id'] ?? 0);
if ($intEveId <= 0) {
continue;
}
$tabEveIds[] = $intEveId;
$strNom = trim((string)($tabRow['eve_nom_' . $strLangue] ?? ''));
if ($strNom === '') {
$strNom = trim((string)($tabRow['eve_nom_' . $strAlt] ?? ''));
}
$tabOut[$intEveId] = [
'eve_id' => $intEveId,
'nom' => $strNom,
'date_label' => fxBibOpsFormatEventDate($tabRow),
'milestones' => [],
];
if (function_exists('fxBibCommandeMilestoneKinds')) {
foreach (fxBibCommandeMilestoneKinds() as $strKind) {
$tabOut[$intEveId]['milestones'][$strKind] = [
'due' => null,
'done_at' => null,
];
}
}
}
if (empty($tabEveIds) || !function_exists('fxBibCommandeHasMilestoneTable')
|| !fxBibCommandeHasMilestoneTable()) {
return array_values($tabOut);
}
$strIds = implode(',', array_map('intval', $tabEveIds));
$tabMs = $objDatabase->fxGetResults(
"SELECT eve_id, bcm_kind, bcm_due, bcm_done_at
FROM inscriptions_bib_commande_milestones
WHERE eve_id IN ($strIds)"
);
if (!is_array($tabMs)) {
return array_values($tabOut);
}
foreach ($tabMs as $tabRow) {
$intEveId = (int)($tabRow['eve_id'] ?? 0);
$strKind = function_exists('fxBibCommandeNormalizeKind')
? fxBibCommandeNormalizeKind($tabRow['bcm_kind'] ?? '')
: '';
if ($intEveId <= 0 || $strKind === '' || !isset($tabOut[$intEveId])) {
continue;
}
$tabOut[$intEveId]['milestones'][$strKind] = [
'due' => ($tabRow['bcm_due'] ?? '') !== '' && $tabRow['bcm_due'] !== '0000-00-00'
? (string)$tabRow['bcm_due']
: null,
'done_at' => ($tabRow['bcm_done_at'] ?? '') !== '' && $tabRow['bcm_done_at'] !== '0000-00-00 00:00:00'
? (string)$tabRow['bcm_done_at']
: null,
];
}
return array_values($tabOut);
}
function fxBibOpsFormatEventDate(array $tabRow) {
$strDebut = trim((string)($tabRow['eve_date_debut'] ?? ''));
$strFin = trim((string)($tabRow['eve_date_fin'] ?? ''));
if ($strDebut === '' || strpos($strDebut, '0000-00-00') === 0) {
return '';
}
$strFmtDebut = substr($strDebut, 0, 10);
if ($strFin === '' || strpos($strFin, '0000-00-00') === 0 || substr($strFin, 0, 10) === $strFmtDebut) {
return $strFmtDebut;
}
return $strFmtDebut . ' — ' . substr($strFin, 0, 10);
}
function fxBibOpsDueIsOverdue($strDue, $strDoneAt) {
$strDue = trim((string)$strDue);
$strDoneAt = trim((string)$strDoneAt);
if ($strDue === '' || $strDoneAt !== '') {
return false;
}
$intTs = strtotime($strDue);
if ($intTs <= 0) {
return false;
}
return $intTs < strtotime(date('Y-m-d'));
}
/** Date seule (Y-m-d) pour le rapport ops — pas lheure. */
function fxBibOpsFormatReportDate($strValue) {
$strValue = trim((string)$strValue);
if ($strValue === '' || strpos($strValue, '0000-00-00') === 0) {
return '';
}
$intTs = strtotime($strValue);
if ($intTs <= 0) {
return '';
}
return date('Y-m-d', $intTs);
}
function fxBibOpsRenderDashboard($strLangue = 'fr') {
$strLangue = ($strLangue === 'en') ? 'en' : 'fr';
$tabEvents = fxBibOpsLoadUpcomingBibEvents($strLangue);
$tabKinds = function_exists('fxBibCommandeMilestoneKinds')
? fxBibCommandeMilestoneKinds()
: [];
$strEmptyDue = fxBibTexte('bib_v5_ops_due_empty', 0);
$strOverdue = fxBibTexte('bib_v5_ops_overdue', 0);
$strOpen = fxBibTexte('bib_v5_ops_open', 0);
$strJalon = fxBibTexte('bib_v5_cmd_jalon', 0);
$strRealite = fxBibTexte('bib_v5_cmd_realite', 0);
$html = '<div class="bib-ops-page">';
$html .= '<div class="bib-cmd-pagebar">';
$html .= '<div>';
$html .= '<h1>' . fxBibEsc(fxBibTexte('bib_v5_ops_page_title', 0)) . '</h1>';
$html .= '<p class="text-muted mb-0">' . fxBibEsc(fxBibTexte('bib_v5_ops_intro', 0)) . '</p>';
$html .= '</div>';
$html .= '<a class="btn btn-outline-secondary rounded-pill ml-auto" href="'
. fxBibEsc(fxBibOpsHubUrl($strLangue)) . '">'
. fxBibEsc(fxBibTexte('bib_v5_ops_back', 0)) . '</a>';
$html .= '</div>';
if (empty($tabEvents)) {
$html .= '<div class="alert alert-info">' . fxBibEsc(fxBibTexte('bib_v5_ops_empty', 0)) . '</div>';
$html .= '</div>';
return $html;
}
$html .= '<div class="table-responsive bib-ops-table-wrap">';
$html .= '<table class="table table-sm bib-ops-table">';
$html .= '<thead>';
$html .= '<tr>';
$html .= '<th rowspan="2">' . fxBibEsc(fxBibTexte('bib_v5_ops_col_event', 0)) . '</th>';
$html .= '<th rowspan="2">' . fxBibEsc(fxBibTexte('bib_v5_ops_col_dates', 0)) . '</th>';
foreach ($tabKinds as $strKind) {
$html .= '<th class="bib-ops-th-ms" colspan="2">'
. fxBibEsc(fxBibTexte('bib_v5_cmd_ms_' . $strKind, 0)) . '</th>';
}
$html .= '<th rowspan="2"></th>';
$html .= '</tr><tr>';
foreach ($tabKinds as $strKind) {
$html .= '<th class="bib-ops-th-sub">' . fxBibEsc($strJalon) . '</th>';
$html .= '<th class="bib-ops-th-sub">' . fxBibEsc($strRealite) . '</th>';
}
$html .= '</tr></thead><tbody>';
foreach ($tabEvents as $tabEve) {
$intEveId = (int)$tabEve['eve_id'];
$strCmdUrl = function_exists('fxBibCommandePageUrl')
? fxBibCommandePageUrl($intEveId, $strLangue)
: '#';
$html .= '<tr>';
$html .= '<td>' . fxBibEsc($tabEve['nom']) . '</td>';
$html .= '<td class="text-nowrap">' . fxBibEsc($tabEve['date_label']) . '</td>';
foreach ($tabKinds as $strKind) {
$tabMs = $tabEve['milestones'][$strKind] ?? ['due' => null, 'done_at' => null];
$strDue = fxBibOpsFormatReportDate($tabMs['due'] ?? '');
$strDoneAt = fxBibOpsFormatReportDate($tabMs['done_at'] ?? '');
$blnOverdue = fxBibOpsDueIsOverdue($strDue, $strDoneAt);
$strDueClass = 'bib-ops-jalon';
if ($blnOverdue) {
$strDueClass .= ' is-overdue';
}
$html .= '<td class="' . $strDueClass . '"';
if ($blnOverdue) {
$html .= ' title="' . fxBibEsc($strOverdue) . '"';
}
$html .= '>' . fxBibEsc($strDue !== '' ? $strDue : $strEmptyDue) . '</td>';
$html .= '<td class="bib-ops-real">'
. fxBibEsc($strDoneAt !== '' ? $strDoneAt : $strEmptyDue) . '</td>';
}
$html .= '<td class="text-nowrap"><a class="btn btn-sm btn-outline-primary rounded-pill" href="'
. fxBibEsc($strCmdUrl) . '">' . fxBibEsc($strOpen) . '</a></td>';
$html .= '</tr>';
}
$html .= '</tbody></table></div></div>';
return $html;
}
}