MSIN-4469 — Refactor fxBibProductionBuildOrderXml function to improve handling of Excel row counts and remove unnecessary empty rows. Update logic for shifting rows and add validation for printer lines in the output. Increment version code.

This commit is contained in:
2026-07-23 12:50:47 -04:00
parent d15a68285c
commit f93f6d14ff
3 changed files with 122 additions and 43 deletions

View File

@ -467,17 +467,37 @@ function fxBibProductionBuildOrderXml($strXml, array $tabSnapshot, array $tabLab
}
}
$intSlotCount = max(9, count($tabOrderRows));
$intExtraRows = ($intSlotCount - 9) * 3;
$intTotalRow = 31 + $intExtraRows;
// MSIN-4469 — Le gabarit a 9 emplacements ; on n'en garde que le nombre
// réel de séquences (sinon lignes jaunes vides avant le TOTAL).
$intTemplateSlots = 9;
$intSlotCount = count($tabOrderRows);
$intRowDelta = ($intSlotCount - $intTemplateSlots) * 3;
$intTotalRow = 31 + $intRowDelta;
$tabRemove = [];
foreach ($objXpath->query('//m:sheetData/m:row') as $objRow) {
if (!($objRow instanceof DOMElement)) {
continue;
}
$intCurrentRow = (int)$objRow->getAttribute('r');
if ($intCurrentRow >= 31 && $intExtraRows > 0) {
$intShiftedRow = $intCurrentRow + $intExtraRows;
if ($intCurrentRow >= 4 && $intCurrentRow <= 30) {
$tabRemove[] = $objRow;
}
}
foreach ($tabRemove as $objRow) {
$objSheetData->removeChild($objRow);
}
if ($intRowDelta !== 0) {
foreach ($objXpath->query('//m:sheetData/m:row') as $objRow) {
if (!($objRow instanceof DOMElement)) {
continue;
}
$intCurrentRow = (int)$objRow->getAttribute('r');
if ($intCurrentRow < 31) {
continue;
}
$intShiftedRow = $intCurrentRow + $intRowDelta;
$objRow->setAttribute('r', (string)$intShiftedRow);
foreach ($objRow->childNodes as $objCell) {
if ($objCell instanceof DOMElement && $objCell->localName === 'c') {
@ -486,34 +506,17 @@ function fxBibProductionBuildOrderXml($strXml, array $tabSnapshot, array $tabLab
}
}
}
}
if ($intExtraRows > 0) {
foreach ($objXpath->query('//m:mergeCell') as $objMerge) {
if (!($objMerge instanceof DOMElement)) {
continue;
}
$objMerge->setAttribute(
'ref',
fxBibProductionXmlShiftReference($objMerge->getAttribute('ref'), 31, $intExtraRows)
fxBibProductionXmlShiftReference($objMerge->getAttribute('ref'), 31, $intRowDelta)
);
}
}
$tabRemove = [];
foreach ($objXpath->query('//m:sheetData/m:row') as $objRow) {
if (!($objRow instanceof DOMElement)) {
continue;
}
$intCurrentRow = (int)$objRow->getAttribute('r');
if ($intCurrentRow >= 4 && $intCurrentRow < $intTotalRow) {
$tabRemove[] = $objRow;
}
}
foreach ($tabRemove as $objRow) {
$objSheetData->removeChild($objRow);
}
$objTotal = fxBibProductionXmlFindRow($objXpath, $intTotalRow);
if (!$objTotal) {
throw new Exception('MSIN-4469 total row missing');
@ -525,21 +528,23 @@ function fxBibProductionBuildOrderXml($strXml, array $tabSnapshot, array $tabLab
$objSecondRow = fxBibProductionXmlCloneRow($objBaseSecond, $intRow + 1);
$objBlankRow = fxBibProductionXmlCloneRow($objBaseBlank, $intRow + 2);
if (isset($tabOrderRows[$intSlot])) {
$tabRow = $tabOrderRows[$intSlot];
$objCellF = fxBibProductionXmlFindCell($objEventRow, 'F');
$strStyleK = $objCellF ? (string)$objCellF->getAttribute('s') : '';
fxBibProductionXmlSetInlineString($objDom, $objEventRow, 'A', $intRow, $tabRow['label']);
fxBibProductionXmlSetNumber($objDom, $objEventRow, 'F', $intRow, $tabRow['quantity']);
fxBibProductionXmlSetNumber($objDom, $objEventRow, 'G', $intRow, $tabRow['start']);
fxBibProductionXmlSetNumber($objDom, $objEventRow, 'H', $intRow, $tabRow['finish']);
fxBibProductionXmlSetFormula($objDom, $objEventRow, 'I', $intRow, 'H' . $intRow . '-G' . $intRow . '+1');
fxBibProductionXmlSetFormula($objDom, $objEventRow, 'J', $intRow, 'I' . $intRow . '=F' . $intRow);
// MSIN-4469 — À côté de la quantité : lignes Imprimeur pour cette séquence.
fxBibProductionXmlSetNumber($objDom, $objEventRow, 'K', $intRow, $tabRow['quantity'], $strStyleK);
// MSIN-4469 — V1 : une puce par dossard, avec le même numéro.
fxBibProductionXmlSetNumber($objDom, $objEventRow, 'L', $intRow, $tabRow['quantity']);
fxBibProductionXmlSetNumber($objDom, $objEventRow, 'M', $intRow, $tabRow['start']);
fxBibProductionXmlSetNumber($objDom, $objEventRow, 'N', $intRow, $tabRow['finish']);
fxBibProductionXmlSetFormula($objDom, $objEventRow, 'O', $intRow, 'G' . $intRow . '=M' . $intRow);
fxBibProductionXmlSetFormula($objDom, $objEventRow, 'P', $intRow, 'H' . $intRow . '=N' . $intRow);
}
$objSheetData->insertBefore($objEventRow, $objTotal);
$objSheetData->insertBefore($objSecondRow, $objTotal);
@ -557,14 +562,40 @@ function fxBibProductionBuildOrderXml($strXml, array $tabSnapshot, array $tabLab
);
}
// MSIN-4469 — Colonne K : validation quantité vs lignes onglet Imprimeur (hors vides).
$objHeaderRow = fxBibProductionXmlFindRow($objXpath, 3);
if ($objHeaderRow) {
$objHeaderCellF = fxBibProductionXmlFindCell($objHeaderRow, 'F');
$strHeaderStyleK = $objHeaderCellF
? (string)$objHeaderCellF->getAttribute('s')
: '';
fxBibProductionXmlSetInlineString(
$objDom,
$objHeaderRow,
'K',
3,
$tabLabels['printer_lines'],
$strHeaderStyleK
);
}
fxBibProductionXmlSetInlineString($objDom, $objTotal, 'A', $intTotalRow, $tabLabels['total']);
fxBibProductionXmlSetFormula($objDom, $objTotal, 'F', $intTotalRow, 'SUM(F4:F' . ($intTotalRow - 1) . ')');
fxBibProductionXmlSetFormula($objDom, $objTotal, 'I', $intTotalRow, 'SUM(I4:I' . ($intTotalRow - 1) . ')');
fxBibProductionXmlSetFormula($objDom, $objTotal, 'L', $intTotalRow, 'SUM(L4:L' . ($intTotalRow - 1) . ')');
// COUNT ne compte que les numéros (ignore en-tête texte et lignes blanches entre épreuves).
fxBibProductionXmlSetFormula($objDom, $objTotal, 'K', $intTotalRow, 'COUNT(Imprimeur!A:A)');
fxBibProductionXmlSetFormula(
$objDom,
$objTotal,
'J',
$intTotalRow,
'F' . $intTotalRow . '=K' . $intTotalRow
);
$objDimension = $objXpath->query('//m:dimension')->item(0);
if ($objDimension instanceof DOMElement) {
$objDimension->setAttribute('ref', 'A1:Q' . (48 + $intExtraRows));
$objDimension->setAttribute('ref', 'A1:Q' . (48 + $intRowDelta));
}
return $objDom->saveXML();
}
@ -768,6 +799,7 @@ function fxBibProductionCreateOfficialOrder($intEveId, $strLangue = 'fr') {
'race' => fxBibTexte('bib_v5_production_col_race', 0),
'total' => fxBibTexte('bib_v5_production_total', 0),
'title' => fxBibTexte('bib_v5_production_excel_title', 0),
'printer_lines' => fxBibTexte('bib_v5_production_col_printer_lines', 0),
]
);

View File

@ -3671,6 +3671,7 @@ function fxBibStaticFallback($clef) {
'bib_v5_production_file_missing' => ['fr' => 'Le fichier Excel enregistré est introuvable.', 'en' => 'The saved Excel file could not be found.'],
'bib_v5_production_col_bib' => ['fr' => 'Numéro de dossard', 'en' => 'Bib number'],
'bib_v5_production_col_race' => ['fr' => 'Épreuve', 'en' => 'Race'],
'bib_v5_production_col_printer_lines' => ['fr' => 'Lignes Imprimeur', 'en' => 'Printer lines'],
'bib_v5_production_total' => ['fr' => 'TOTAL', 'en' => 'TOTAL'],
'bib_v5_production_locked_error' => ['fr' => 'Les séquences sont verrouillées parce que le fichier est en impression.', 'en' => 'The ranges are locked because the file is in print.'],
'bib_v5_production_print_lock_col' => ['fr' => 'Impression', 'en' => 'Printing'],

View File

@ -0,0 +1,46 @@
-- MSIN-4469 — Colonne validation « Lignes Imprimeur » (Commande MS1)
-- Prérequis : MSIN-4469-production-excel-dossards.sql
-- Notes : exécution UNIQUEMENT sur dev préprod ; autres env = Navicat structure + sync_static_db
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
src.info_clef,
src.info_langue,
src.info_texte,
src.info_aide,
'compte.php',
'MSIN-4469',
0,
1,
'',
'',
'',
NOW()
FROM (
SELECT 'bib_v5_production_col_printer_lines' info_clef, 'fr' info_langue,
'Lignes Imprimeur' info_texte,
'Nombre de lignes de longlet Imprimeur (hors lignes vides). Doit égaler la quantité de dossards.' info_aide
UNION ALL SELECT 'bib_v5_production_col_printer_lines', 'en',
'Printer lines',
'Number of rows on the Printer sheet (excluding blank rows). Must match the bib quantity.'
) src
WHERE NOT EXISTS (
SELECT 1
FROM info current_info
WHERE current_info.info_clef = src.info_clef
AND current_info.info_langue = src.info_langue
AND current_info.info_prg = 'compte.php'
);