fix recap pdf

This commit is contained in:
Tolotsoa 2025-12-16 09:07:49 +03:00
parent 8cacac1efc
commit d2bb1a9cc6
3 changed files with 89 additions and 43 deletions

View File

@ -81,16 +81,31 @@ class DevisPdfGenerator
private function calculatePagination($totalItems) private function calculatePagination($totalItems)
{ {
if ($totalItems <= 8) {
// Tout sur 1 page
return [ return [
'nb_pages' => ceil($totalItems / 12), // RÉDUIRE à 12 par page 'nb_pages' => 1,
'items_per_page' => 12, 'items_per_page' => 15,
'current_index' => 0
];
}
// Réserver 8 items pour dernière page
$itemsAvantDernierePage = $totalItems - 8;
$nbPagesNormales = ceil($itemsAvantDernierePage / 15);
return [
'nb_pages' => $nbPagesNormales + 1,
'items_per_page' => 15,
'current_index' => 0 'current_index' => 0
]; ];
} }
// VOICI LA FONCTION CORRIGÉE - 4 paramètres au lieu de 10
private function generateSinglePage(PageContext $context, $num_page, &$pagination, &$totals) private function generateSinglePage(PageContext $context, $num_page, &$pagination, &$totals)
{ {
$startIndex = $pagination['current_index'];
$remainingItems = count($context->dataDevis) - $startIndex;
$context->pdf->AddPage(); $context->pdf->AddPage();
$context->pdf->SetAutoPagebreak(false); $context->pdf->SetAutoPagebreak(false);
$context->pdf->SetMargins(0, 0, 10); $context->pdf->SetMargins(0, 0, 10);
@ -100,7 +115,17 @@ class DevisPdfGenerator
$this->layoutManager->addClientInfoSection($context->pdf, $context->clientInfo, $context->dataDevis[0]); $this->layoutManager->addClientInfoSection($context->pdf, $context->clientInfo, $context->dataDevis[0]);
$this->layoutManager->addDocumentTitle($context->pdf, $context->dataDevis[0], $context->year); $this->layoutManager->addDocumentTitle($context->pdf, $context->dataDevis[0], $context->year);
$itemsToProcess = min($pagination['items_per_page'], count($context->dataDevis) - $pagination['current_index']); // ✅ Calculer items
$isLastPage = ($num_page == $pagination['nb_pages']);
$hasAmounts = !$context->montant;
if ($isLastPage && $hasAmounts) {
// Dernière page avec totaux : max 8 items
$itemsToProcess = min(8, $remainingItems);
} else {
// Pages normales : 15 items
$itemsToProcess = min(15, $remainingItems);
}
$config = [ $config = [
'pagination' => $pagination, 'pagination' => $pagination,
@ -111,7 +136,7 @@ class DevisPdfGenerator
'sansMontant' => $context->montant 'sansMontant' => $context->montant
]; ];
$this->tableRenderer->createDevisTable( $finalY = $this->tableRenderer->createDevisTable(
$context->pdf, $context->pdf,
$context->dataDevis, $context->dataDevis,
$config $config

View File

@ -63,17 +63,18 @@ class DevisPdfLayoutManager
); );
} }
public function addLegalFooter($pdf, $config) public function addLegalFooter($pdf, $config, $tableEndY = 0)
{ {
$y0 = 260; $y0 = 280;
$pageWidth = $pdf->GetPageWidth(); $pageWidth = $pdf->GetPageWidth();
$pdf->SetFont('Arial', '', 6); $pdf->SetFont('Arial', '', 6);
$pdf->SetXY(1, $y0 + 4); $pdf->SetXY(1, $y0);
$pdf->Cell($pageWidth, 5, mb_convert_encoding(html_entity_decode($config->legal_one), 'ISO-8859-1', 'UTF-8'), 0, 0, 'C'); $pdf->Cell($pageWidth, 5, mb_convert_encoding(html_entity_decode($config->legal_one), 'ISO-8859-1', 'UTF-8'), 0, 0, 'C');
$pdf->SetXY(1, $y0 + 8); $pdf->SetXY(1, $y0 + 4);
$pdf->Cell($pageWidth, 5, mb_convert_encoding(html_entity_decode($config->legal_two), 'ISO-8859-1', 'UTF-8'), 0, 0, 'C'); $pdf->Cell($pageWidth, 5, mb_convert_encoding(html_entity_decode($config->legal_two), 'ISO-8859-1', 'UTF-8'), 0, 0, 'C');
$pdf->SetXY(1, $y0 + 12); $pdf->SetXY(1, $y0 + 8);
$pdf->Cell($pageWidth, 5, mb_convert_encoding(html_entity_decode($config->telephone), 'ISO-8859-1', 'UTF-8'), 0, 0, 'C'); $pdf->Cell($pageWidth, 5, mb_convert_encoding(html_entity_decode($config->telephone), 'ISO-8859-1', 'UTF-8'), 0, 0, 'C');
} }

View File

@ -13,40 +13,59 @@ class DevisPdfTableRenderer
$totals = &$config['totals']; $totals = &$config['totals'];
$sansMontant = $config['sansMontant'] ?? false; $sansMontant = $config['sansMontant'] ?? false;
// Système de pagination comme les factures
$maxItemsPerPage = 22; // Nombre maximum d'éléments par page
$startIndex = $pagination['current_index']; $startIndex = $pagination['current_index'];
$itemsThisPage = min($itemsToProcess, count($dataDevis) - $startIndex); $itemsThisPage = min($itemsToProcess, count($dataDevis) - $startIndex);
$this->drawTableStructure($pdf, $numPage, $nbPage, $sansMontant); $tableEndY = $this->drawTableStructure($pdf, $numPage, $nbPage, $sansMontant, $itemsThisPage);
$this->addTableHeaders($pdf, $sansMontant); $this->addTableHeaders($pdf, $sansMontant);
$this->populateTableData($pdf, $dataDevis, $startIndex, $itemsThisPage, $totals, $sansMontant); $this->populateTableData($pdf, $dataDevis, $startIndex, $itemsThisPage, $totals, $sansMontant);
// Totaux seulement sur la dernière page
if ($numPage == $nbPage && !$sansMontant) { if ($numPage == $nbPage && !$sansMontant) {
$this->addTableTotals($pdf, $totals); $finalY = $this->addTableTotals($pdf, $totals, $tableEndY);
} } else {
$finalY = $tableEndY;
} }
private function drawTableStructure($pdf, $numPage, $nbPage, $sansMontant) return $finalY;
}
private function drawTableStructure($pdf, $numPage, $nbPage, $sansMontant, $itemsOnPage)
{ {
$pdf->SetLineWidth(0.2); $pdf->SetLineWidth(0.2);
$pdf->Rect(5, 105, 200, 130, "D");
$headerHeight = 10;
$rowHeight = 10;
$tableHeight = $headerHeight + ($itemsOnPage * $rowHeight);
$endY = 105 + $tableHeight;
$isLastPage = ($numPage == $nbPage);
$hasAmounts = !$sansMontant;
if ($isLastPage && $hasAmounts) {
// Dessiner 3 côtés seulement (haut, gauche, droite)
$pdf->Line(5, 105, 205, 105); // Haut
$pdf->Line(5, 105, 5, $endY); // Gauche
$pdf->Line(205, 105, 205, $endY); // Droite
// Pas de ligne du bas - elle sera tracée dans addTableTotals
} else {
// Dessiner rectangle complet
$pdf->Rect(5, 105, 200, $tableHeight, "D");
}
$pdf->Line(5, 115, 205, 115); $pdf->Line(5, 115, 205, 115);
$endY = ($numPage == $nbPage && !$sansMontant) ? 225 : 235;
if (!$sansMontant) { if (!$sansMontant) {
// Ajout de la colonne Thanatopracteur entre Défunt et H.T.
$verticalLines = [24, 41, 58, 77, 102, 127, 147, 167, 178, 189]; $verticalLines = [24, 41, 58, 77, 102, 127, 147, 167, 178, 189];
} else { } else {
// Pour sans montant: ajout de Thanatopracteur à la fin
$verticalLines = [27, 47, 67, 85, 110, 135, 160]; $verticalLines = [27, 47, 67, 85, 110, 135, 160];
} }
foreach ($verticalLines as $x) { foreach ($verticalLines as $x) {
$pdf->Line($x, 105, $x, $endY); $pdf->Line($x, 105, $x, $endY);
} }
return $endY;
} }
private function addTableHeaders($pdf, $sansMontant) private function addTableHeaders($pdf, $sansMontant)
@ -176,43 +195,44 @@ class DevisPdfTableRenderer
} }
} }
private function addTableTotals($pdf, $totals) private function addTableTotals($pdf, $totals, $tableEndY)
{ {
$pdf->Line(5, 225, 205, 225); $totalEndY = $tableEndY + 8;
$pdf->SetLineWidth(0.2);
// Juste les lignes horizontales haut et bas
$pdf->Line(5, $tableEndY, 205, $tableEndY);
$pdf->Line(5, $totalEndY, 205, $totalEndY);
$pdf->Line(5, $tableEndY, 5, $totalEndY);
$pdf->Line(205, $tableEndY, 205, $totalEndY);
$pdf->SetFont('Arial', 'B', 8); $pdf->SetFont('Arial', 'B', 8);
// Alignement des totaux avec les colonnes HT, TVA, TTC avec espaces entre les valeurs $pdf->SetXY(5, $tableEndY);
$pdf->SetXY(5, 225);
$pdf->Cell(162, 8, 'TOTAL', 0, 0, 'C'); $pdf->Cell(162, 8, 'TOTAL', 0, 0, 'C');
// POSITIONS avec espaces entre les valeurs - plus d'espace entre HT et TVA $pdf->SetXY(167, $tableEndY);
$pdf->SetXY(167, 225);
$pdf->Cell(9, 8, number_format($totals['ht'], 2, '.', '') . chr(128), 0, 0, 'R'); $pdf->Cell(9, 8, number_format($totals['ht'], 2, '.', '') . chr(128), 0, 0, 'R');
$pdf->SetXY(181, 225); $pdf->SetXY(181, $tableEndY);
$pdf->Cell(9, 8, number_format($totals['tva'], 2, '.', '') . chr(128), 0, 0, 'R'); $pdf->Cell(9, 8, number_format($totals['tva'], 2, '.', '') . chr(128), 0, 0, 'R');
$pdf->SetXY(189, 225); $pdf->SetXY(189, $tableEndY);
$pdf->Cell(16, 8, number_format($totals['ttc'], 2, '.', '') . chr(128), 0, 0, 'R'); $pdf->Cell(16, 8, number_format($totals['ttc'], 2, '.', '') . chr(128), 0, 0, 'R');
// CADRE TOTAL TTC - Cadre encore plus agrandi $cadreY = $totalEndY + 3;
$pdf->SetXY(170, 241);
$pdf->SetXY(170, $cadreY + 1);
$pdf->Cell(19, 6, 'TOTAL TTC', 0, 0, 'C'); $pdf->Cell(19, 6, 'TOTAL TTC', 0, 0, 'C');
$pdf->SetXY(189, 241); $pdf->SetXY(189, $cadreY + 1);
$pdf->Cell(16, 6, number_format($totals['ttc'], 2, '.', '') . chr(128), 0, 0, 'C'); $pdf->Cell(16, 6, number_format($totals['ttc'], 2, '.', '') . chr(128), 0, 0, 'C');
// Cadre TOTAL TTC aligné avec la fin du tableau (205) $pdf->Rect(170, $cadreY, 35, 8, 'D');
$lines = [ $pdf->Line(189, $cadreY, 189, $cadreY + 8);
[170, 240, 170, 248], // Ligne verticale gauche (déplacée de 173 à 170 pour agrandir)
[189, 240, 189, 248], // Ligne de séparation (alignée avec colonne T.T.C)
[205, 240, 205, 248], // Ligne verticale droite (alignée avec fin du tableau)
[170, 240, 205, 240], // Ligne horizontale haute
[170, 248, 205, 248] // Ligne horizontale basse
];
foreach ($lines as $line) { return $cadreY + 8;
$pdf->Line($line[0], $line[1], $line[2], $line[3]);
}
} }
} }