THANASOFT-HFC/gestion/lib/Service/Devis/DevisPdfGenerator.php
2025-12-16 09:07:49 +03:00

170 lines
6.1 KiB
PHP

<?php
namespace OCA\Gestion\Service\Devis;
use OCP\Files\IRootFolder;
use OCP\Files\NotPermittedException;
class DevisPdfGenerator
{
/** @var IRootFolder */
private $rootFolder;
/** @var DevisPdfLayoutManager */
private $layoutManager;
/** @var DevisPdfTableRenderer */
private $tableRenderer;
public const DEFAULT_NEXTCLOUD_ADMIN = 'admin';
public function __construct(IRootFolder $rootFolder)
{
$this->rootFolder = $rootFolder;
$this->layoutManager = new DevisPdfLayoutManager($rootFolder);
$this->tableRenderer = new DevisPdfTableRenderer();
}
public function generatePdfDocument($storage, $currentConfig, $data_devis, $clientInfo, $month, $year, $montant)
{
$configurationAddresses = \OCA\Gestion\Helpers\FileExportHelpers::GetAddressAndCityFromAddress($currentConfig->adresse);
$configurationAddress = $configurationAddresses["address"];
$configurationAddressCity = $configurationAddresses["city"];
$pdf = $this->createPdfInstance();
$folderPath = $this->createDestinationFolder($storage, $currentConfig, $data_devis[0], $month, $year);
// Créer le contexte une seule fois
$context = new PageContext($pdf, $currentConfig, $configurationAddress, $configurationAddressCity, $data_devis, $clientInfo, $year, $montant);
$this->generatePdfPages($context);
return $this->savePdfFile($storage, $pdf, $folderPath, $clientInfo, $month, $year);
}
public function createPdfInstance()
{
$pdf = new \FPDF();
$pdf->AddFont('Arial', '', 'Comic Sans MS.php');
$pdf->AddFont('Arial', 'B', 'comic-sans-bold.php');
return $pdf;
}
public function createDestinationFolder($storage, $currentConfig, $firstDevis, $month, $year)
{
$date_temp = date("t-m-Y", strtotime($firstDevis['devis_date']));
$formatter = new \IntlDateFormatter('fr_FR', \IntlDateFormatter::LONG, \IntlDateFormatter::NONE);
$date_formated = $formatter->format(\DateTime::createFromFormat('d-m-Y', $date_temp));
$folderPath = html_entity_decode($currentConfig->path) . '/DOCUMENTS RECAPITULATIFS/' . $year . '/' .
str_pad($month, 2, '0', STR_PAD_LEFT) . ' ' .
strtoupper(\OCA\Gestion\Helpers\FileExportHelpers::ConvertSpecialChar(explode(' ', $date_formated)[1])) . '/';
try {
$storage->newFolder($folderPath);
} catch(NotPermittedException $e) {
// Le dossier existe déjà
}
return $folderPath;
}
private function generatePdfPages(PageContext $context)
{
$pagination = $this->calculatePagination(count($context->dataDevis));
$totals = ['ht' => 0, 'tva' => 0, 'ttc' => 0];
for ($num_page = 1; $num_page <= $pagination['nb_pages']; $num_page++) {
$this->generateSinglePage($context, $num_page, $pagination, $totals);
}
}
private function calculatePagination($totalItems)
{
if ($totalItems <= 8) {
// Tout sur 1 page
return [
'nb_pages' => 1,
'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
];
}
private function generateSinglePage(PageContext $context, $num_page, &$pagination, &$totals)
{
$startIndex = $pagination['current_index'];
$remainingItems = count($context->dataDevis) - $startIndex;
$context->pdf->AddPage();
$context->pdf->SetAutoPagebreak(false);
$context->pdf->SetMargins(0, 0, 10);
$this->layoutManager->addPageHeader($context->pdf, $context->currentConfig, $context->configurationAddress, $context->configurationAddressCity);
$this->layoutManager->addPageNumber($context->pdf, $num_page, $pagination['nb_pages']);
$this->layoutManager->addClientInfoSection($context->pdf, $context->clientInfo, $context->dataDevis[0]);
$this->layoutManager->addDocumentTitle($context->pdf, $context->dataDevis[0], $context->year);
// ✅ 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 = [
'pagination' => $pagination,
'itemsToProcess' => $itemsToProcess,
'numPage' => $num_page,
'nbPage' => $pagination['nb_pages'],
'totals' => &$totals,
'sansMontant' => $context->montant
];
$finalY = $this->tableRenderer->createDevisTable(
$context->pdf,
$context->dataDevis,
$config
);
$this->layoutManager->addLegalFooter($context->pdf, $context->currentConfig);
$pagination['current_index'] += $itemsToProcess;
}
private function savePdfFile($storage, $pdf, $folderPath, $clientInfo, $month, $year)
{
$filename = $this->generateDevisRecapFilename($clientInfo, $month, $year);
$fullPdfPath = $folderPath . $filename . '.pdf';
$storage->newFile($fullPdfPath);
$pdfContent = $pdf->Output('', 'S');
$file_pdf = $storage->get($fullPdfPath);
$file_pdf->putContent($pdfContent);
return $fullPdfPath;
}
private function generateDevisRecapFilename($clientInfo, $month, $year)
{
$monthName = strtoupper(\OCA\Gestion\Helpers\FileExportHelpers::ConvertSpecialChar(date('F', mktime(0, 0, 0, $month, 10))));
$clientName = strtoupper(\OCA\Gestion\Helpers\FileExportHelpers::ConvertSpecialChar($clientInfo['name']));
return $clientName . '_RECAP_DEVIS_' . $monthName . '_' . $year;
}
}