drawTableStructure($pdf, $numPage, $nbPage, $sansMontant); $this->addTableHeaders($pdf, $sansMontant); $this->populateTableData($pdf, $dataDevis, $startIndex, $itemsThisPage, $totals, $sansMontant); // Totaux seulement sur la dernière page if ($numPage == $nbPage && !$sansMontant) { $this->addTableTotals($pdf, $totals); } } private function drawTableStructure($pdf, $numPage, $nbPage, $sansMontant) { $pdf->SetLineWidth(0.2); $pdf->Rect(5, 105, 200, 130, "D"); $pdf->Line(5, 115, 205, 115); $endY = ($numPage == $nbPage && !$sansMontant) ? 225 : 235; if (!$sansMontant) { // Ajustement final des positions des lignes verticales // Article et Défunt de même taille, TTC réduit $verticalLines = [22, 39, 56, 75, 105, 135, 155, 170, 185]; } else { // Pour sans montant: Article et Défunt de même taille $verticalLines = [27, 47, 67, 85, 115, 145]; } foreach ($verticalLines as $x) { $pdf->Line($x, 105, $x, $endY); } } private function addTableHeaders($pdf, $sansMontant) { $pdf->SetFont('Arial', 'B', 7); if (!$sansMontant) { $headers = [ [5, 17, "N° Devis"], [22, 17, "N° Dossier"], [39, 17, "N° Commande"], [56, 19, "Date"], [75, 30, "Article"], // Taille augmentée [105, 30, "Lieu du soin"], [135, 20, "Défunt"], // Taille réduite pour équilibrer [155, 15, "H.T."], [170, 15, "TVA"], [185, 15, "T.T.C"] // Taille réduite ]; } else { $headers = [ [5, 22, "N° Devis"], [27, 20, "N° Dossier"], [47, 20, "N° Commande"], [67, 18, "Date"], [85, 30, "Article"], // Même taille que Défunt [115, 30, "Lieu du soin"], [145, 30, "Défunt"] // Même taille que Article ]; } foreach ($headers as $header) { $pdf->SetXY($header[0] + 1, 106); $pdf->Cell($header[1] - 2, 8, mb_convert_encoding($header[2], 'ISO-8859-1', 'UTF-8'), 0, 0, 'C'); } } private function populateTableData($pdf, $dataDevis, $startIndex, $itemsToProcess, &$totals, $sansMontant) { $formatterDate = new \IntlDateFormatter('fr_FR', \IntlDateFormatter::SHORT, \IntlDateFormatter::NONE); $formatterDate->setPattern('dd-MMM'); $yDevis = 115; for ($i = $startIndex; $i < $startIndex + $itemsToProcess && $i < count($dataDevis); $i++) { $devis = $dataDevis[$i]; $dateSoin = new \DateTime($devis['devis_date']); $this->addTableRow($pdf, $devis, $formatterDate, $dateSoin, $yDevis, $sansMontant); // Calculer les totaux seulement si on affiche les montants if (!$sansMontant) { $totals['ht'] += $devis['montant_htc']; $totals['tva'] += $devis['montant_tva']; $totals['ttc'] += $devis['montant_ttc']; } $yDevis += 10; } } private function addTableRow($pdf, $devis, $formatterDate, $dateSoin, $yDevis, $sansMontant) { $pdf->SetFont('Arial', '', 7); $addSmartCell = function ($pdf, $x, $y, $width, $text, $align = 'L') use ($yDevis) { $textWidth = $pdf->GetStringWidth($text); $maxWidth = $width - 2; if ($textWidth > $maxWidth && strlen($text) > 10) { $pdf->SetXY($x, $y); $pdf->MultiCell($width, 2.5, $text, 0, $align); } else { $pdf->SetXY($x, $y); $pdf->Cell($width, 5, $text, 0, 0, $align); } }; if (!$sansMontant) { // LARGEURS ÉQUILIBRÉES avec Article et Défunt de même taille $addSmartCell($pdf, 6, $yDevis, 16, $devis['devis_full_number']); $addSmartCell($pdf, 23, $yDevis, 16, $devis['case_number'] ?? ''); $addSmartCell($pdf, 40, $yDevis, 16, $devis['order_number'] ?? ''); $addSmartCell($pdf, 57, $yDevis, 18, mb_convert_encoding($formatterDate->format($dateSoin), 'ISO-8859-1', 'UTF-8')); $articleText = \OCA\Gestion\Helpers\FileExportHelpers::FormatTextForExport($devis['article'] ?? 'SOINS'); $addSmartCell($pdf, 76, $yDevis, 29, $articleText); // Article agrandi $lieuText = \OCA\Gestion\Helpers\FileExportHelpers::FormatTextForExport($devis['lieu_nom'] ?? ''); $addSmartCell($pdf, 106, $yDevis, 29, $lieuText); $defuntText = \OCA\Gestion\Helpers\FileExportHelpers::FormatTextForExport($devis['defunt_nom'] ?? ''); $addSmartCell($pdf, 136, $yDevis, 19, $defuntText); // Défunt réduit $addSmartCell($pdf, 156, $yDevis, 14, number_format($devis['montant_htc'], 2, '.', '') . chr(128), 'R'); $addSmartCell($pdf, 171, $yDevis, 14, number_format($devis['montant_tva'], 2, '.', '') . chr(128), 'R'); $addSmartCell($pdf, 186, $yDevis, 14, number_format($devis['montant_ttc'], 2, '.', '') . chr(128), 'R'); // TTC réduit } else { // Pour sans montant: Article et Défunt de même taille $addSmartCell($pdf, 6, $yDevis, 21, $devis['devis_full_number']); $addSmartCell($pdf, 28, $yDevis, 19, $devis['case_number'] ?? ''); $addSmartCell($pdf, 48, $yDevis, 19, $devis['order_number'] ?? ''); $addSmartCell($pdf, 68, $yDevis, 17, mb_convert_encoding($formatterDate->format($dateSoin), 'ISO-8859-1', 'UTF-8')); $articleText = \OCA\Gestion\Helpers\FileExportHelpers::FormatTextForExport($devis['article'] ?? 'SOINS'); $addSmartCell($pdf, 86, $yDevis, 29, $articleText); // Article agrandi $lieuText = \OCA\Gestion\Helpers\FileExportHelpers::FormatTextForExport($devis['lieu_nom'] ?? ''); $addSmartCell($pdf, 116, $yDevis, 29, $lieuText); $defuntText = \OCA\Gestion\Helpers\FileExportHelpers::FormatTextForExport($devis['defunt_nom'] ?? ''); $addSmartCell($pdf, 146, $yDevis, 29, $defuntText); // Défunt réduit } } private function addTableTotals($pdf, $totals) { $pdf->Line(5, 225, 205, 225); $pdf->SetFont('Arial', 'B', 8); // Alignement des totaux avec les colonnes HT, TVA, TTC $pdf->SetXY(5, 225); $pdf->Cell(130, 8, 'TOTAL', 0, 0, 'C'); // POSITIONS alignées avec les colonnes du tableau $pdf->SetXY(155, 225); $pdf->Cell(15, 8, number_format($totals['ht'], 2, '.', '') . chr(128), 0, 0, 'R'); $pdf->SetXY(170, 225); $pdf->Cell(15, 8, number_format($totals['tva'], 2, '.', '') . chr(128), 0, 0, 'R'); $pdf->SetXY(185, 225); $pdf->Cell(15, 8, number_format($totals['ttc'], 2, '.', '') . chr(128), 0, 0, 'R'); // CADRE TOTAL TTC - Texte à l'intérieur du cadre aligné à droite $pdf->SetXY(155, 240); $pdf->Cell(30, 8, 'TOTAL TTC', 0, 0, 'C'); // Valeur alignée avec la fin du tableau tout à droite $pdf->SetXY(185, 240); $pdf->Cell(15, 8, number_format($totals['ttc'], 2, '.', '') . chr(128), 0, 0, 'R'); // Cadre TOTAL TTC aligné avec la fin du tableau (205) $lines = [ [155, 240, 155, 248], // Ligne verticale gauche [185, 240, 185, 248], // Ligne de séparation [205, 240, 205, 248], // Ligne verticale droite (alignée avec fin du tableau) [155, 240, 205, 240], // Ligne horizontale haute [155, 248, 205, 248] // Ligne horizontale basse ]; foreach ($lines as $line) { $pdf->Line($line[0], $line[1], $line[2], $line[3]); } } }