feat change template facture not vat
This commit is contained in:
parent
572d7708ec
commit
351801d4ac
@ -15,6 +15,7 @@
|
||||
"symfony/framework-bundle": "^5.4"
|
||||
},
|
||||
"require": {
|
||||
"setasign/fpdf": "^1.8"
|
||||
"setasign/fpdf": "^1.8",
|
||||
"dompdf/dompdf": "^3.1"
|
||||
}
|
||||
}
|
||||
|
||||
298
gestion/composer.lock
generated
298
gestion/composer.lock
generated
@ -4,8 +4,296 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "79912f1c84e373fcd7778fb095176063",
|
||||
"content-hash": "2cbec79cf4e2f6e464d23e0fd4df0b09",
|
||||
"packages": [
|
||||
{
|
||||
"name": "dompdf/dompdf",
|
||||
"version": "v3.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/dompdf/dompdf.git",
|
||||
"reference": "a51bd7a063a65499446919286fb18b518177155a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/dompdf/dompdf/zipball/a51bd7a063a65499446919286fb18b518177155a",
|
||||
"reference": "a51bd7a063a65499446919286fb18b518177155a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"dompdf/php-font-lib": "^1.0.0",
|
||||
"dompdf/php-svg-lib": "^1.0.0",
|
||||
"ext-dom": "*",
|
||||
"ext-mbstring": "*",
|
||||
"masterminds/html5": "^2.0",
|
||||
"php": "^7.1 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-gd": "*",
|
||||
"ext-json": "*",
|
||||
"ext-zip": "*",
|
||||
"mockery/mockery": "^1.3",
|
||||
"phpunit/phpunit": "^7.5 || ^8 || ^9 || ^10 || ^11",
|
||||
"squizlabs/php_codesniffer": "^3.5",
|
||||
"symfony/process": "^4.4 || ^5.4 || ^6.2 || ^7.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-gd": "Needed to process images",
|
||||
"ext-gmagick": "Improves image processing performance",
|
||||
"ext-imagick": "Improves image processing performance",
|
||||
"ext-zlib": "Needed for pdf stream compression"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Dompdf\\": "src/"
|
||||
},
|
||||
"classmap": [
|
||||
"lib/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"LGPL-2.1"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "The Dompdf Community",
|
||||
"homepage": "https://github.com/dompdf/dompdf/blob/master/AUTHORS.md"
|
||||
}
|
||||
],
|
||||
"description": "DOMPDF is a CSS 2.1 compliant HTML to PDF converter",
|
||||
"homepage": "https://github.com/dompdf/dompdf",
|
||||
"support": {
|
||||
"issues": "https://github.com/dompdf/dompdf/issues",
|
||||
"source": "https://github.com/dompdf/dompdf/tree/v3.1.0"
|
||||
},
|
||||
"time": "2025-01-15T14:09:04+00:00"
|
||||
},
|
||||
{
|
||||
"name": "dompdf/php-font-lib",
|
||||
"version": "1.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/dompdf/php-font-lib.git",
|
||||
"reference": "6137b7d4232b7f16c882c75e4ca3991dbcf6fe2d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/dompdf/php-font-lib/zipball/6137b7d4232b7f16c882c75e4ca3991dbcf6fe2d",
|
||||
"reference": "6137b7d4232b7f16c882c75e4ca3991dbcf6fe2d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-mbstring": "*",
|
||||
"php": "^7.1 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/phpunit-bridge": "^3 || ^4 || ^5 || ^6"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"FontLib\\": "src/FontLib"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"LGPL-2.1-or-later"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "The FontLib Community",
|
||||
"homepage": "https://github.com/dompdf/php-font-lib/blob/master/AUTHORS.md"
|
||||
}
|
||||
],
|
||||
"description": "A library to read, parse, export and make subsets of different types of font files.",
|
||||
"homepage": "https://github.com/dompdf/php-font-lib",
|
||||
"support": {
|
||||
"issues": "https://github.com/dompdf/php-font-lib/issues",
|
||||
"source": "https://github.com/dompdf/php-font-lib/tree/1.0.1"
|
||||
},
|
||||
"time": "2024-12-02T14:37:59+00:00"
|
||||
},
|
||||
{
|
||||
"name": "dompdf/php-svg-lib",
|
||||
"version": "1.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/dompdf/php-svg-lib.git",
|
||||
"reference": "eb045e518185298eb6ff8d80d0d0c6b17aecd9af"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/dompdf/php-svg-lib/zipball/eb045e518185298eb6ff8d80d0d0c6b17aecd9af",
|
||||
"reference": "eb045e518185298eb6ff8d80d0d0c6b17aecd9af",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-mbstring": "*",
|
||||
"php": "^7.1 || ^8.0",
|
||||
"sabberworm/php-css-parser": "^8.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.5"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Svg\\": "src/Svg"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"LGPL-3.0-or-later"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "The SvgLib Community",
|
||||
"homepage": "https://github.com/dompdf/php-svg-lib/blob/master/AUTHORS.md"
|
||||
}
|
||||
],
|
||||
"description": "A library to read, parse and export to PDF SVG files.",
|
||||
"homepage": "https://github.com/dompdf/php-svg-lib",
|
||||
"support": {
|
||||
"issues": "https://github.com/dompdf/php-svg-lib/issues",
|
||||
"source": "https://github.com/dompdf/php-svg-lib/tree/1.0.0"
|
||||
},
|
||||
"time": "2024-04-29T13:26:35+00:00"
|
||||
},
|
||||
{
|
||||
"name": "masterminds/html5",
|
||||
"version": "2.10.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Masterminds/html5-php.git",
|
||||
"reference": "fcf91eb64359852f00d921887b219479b4f21251"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Masterminds/html5-php/zipball/fcf91eb64359852f00d921887b219479b4f21251",
|
||||
"reference": "fcf91eb64359852f00d921887b219479b4f21251",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-dom": "*",
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8 || ^9"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.7-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Masterminds\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Matt Butcher",
|
||||
"email": "technosophos@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Matt Farina",
|
||||
"email": "matt@mattfarina.com"
|
||||
},
|
||||
{
|
||||
"name": "Asmir Mustafic",
|
||||
"email": "goetas@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "An HTML5 parser and serializer.",
|
||||
"homepage": "http://masterminds.github.io/html5-php",
|
||||
"keywords": [
|
||||
"HTML5",
|
||||
"dom",
|
||||
"html",
|
||||
"parser",
|
||||
"querypath",
|
||||
"serializer",
|
||||
"xml"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/Masterminds/html5-php/issues",
|
||||
"source": "https://github.com/Masterminds/html5-php/tree/2.10.0"
|
||||
},
|
||||
"time": "2025-07-25T09:04:22+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sabberworm/php-css-parser",
|
||||
"version": "v8.9.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/MyIntervals/PHP-CSS-Parser.git",
|
||||
"reference": "d8e916507b88e389e26d4ab03c904a082aa66bb9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/MyIntervals/PHP-CSS-Parser/zipball/d8e916507b88e389e26d4ab03c904a082aa66bb9",
|
||||
"reference": "d8e916507b88e389e26d4ab03c904a082aa66bb9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-iconv": "*",
|
||||
"php": "^5.6.20 || ^7.0.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "5.7.27 || 6.5.14 || 7.5.20 || 8.5.41",
|
||||
"rawr/cross-data-providers": "^2.0.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-mbstring": "for parsing UTF-8 CSS"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "9.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Sabberworm\\CSS\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Raphael Schweikert"
|
||||
},
|
||||
{
|
||||
"name": "Oliver Klee",
|
||||
"email": "github@oliverklee.de"
|
||||
},
|
||||
{
|
||||
"name": "Jake Hotson",
|
||||
"email": "jake.github@qzdesign.co.uk"
|
||||
}
|
||||
],
|
||||
"description": "Parser for CSS Files written in PHP",
|
||||
"homepage": "https://www.sabberworm.com/blog/2010/6/10/php-css-parser",
|
||||
"keywords": [
|
||||
"css",
|
||||
"parser",
|
||||
"stylesheet"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/MyIntervals/PHP-CSS-Parser/issues",
|
||||
"source": "https://github.com/MyIntervals/PHP-CSS-Parser/tree/v8.9.0"
|
||||
},
|
||||
"time": "2025-07-11T13:20:48+00:00"
|
||||
},
|
||||
{
|
||||
"name": "setasign/fpdf",
|
||||
"version": "1.8.5",
|
||||
@ -4777,10 +5065,10 @@
|
||||
],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": [],
|
||||
"stability-flags": {},
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": [],
|
||||
"platform-dev": [],
|
||||
"plugin-api-version": "2.3.0"
|
||||
"platform": {},
|
||||
"platform-dev": {},
|
||||
"plugin-api-version": "2.6.0"
|
||||
}
|
||||
|
||||
7
gestion/lib/Exception/TemplateException.php
Normal file
7
gestion/lib/Exception/TemplateException.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace OCA\Gestion\Exception;
|
||||
|
||||
class TemplateException extends \Exception
|
||||
{
|
||||
}
|
||||
126
gestion/lib/Service/HtmlToPdfService.php
Normal file
126
gestion/lib/Service/HtmlToPdfService.php
Normal file
@ -0,0 +1,126 @@
|
||||
<?php
|
||||
|
||||
namespace OCA\Gestion\Service;
|
||||
|
||||
use Throwable;
|
||||
use Dompdf\Dompdf;
|
||||
use Dompdf\Options;
|
||||
use OCA\Gestion\Exception\TemplateException;
|
||||
|
||||
class HtmlToPdfService
|
||||
{
|
||||
private $templatesPath;
|
||||
private $assetsPath;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->templatesPath = __DIR__ . '/../../templates/pdf/';
|
||||
$this->assetsPath = '/var/www/html/data/admin/files/.gestion/';
|
||||
}
|
||||
|
||||
public function generatePdf($templateName, $data, $options = [])
|
||||
{
|
||||
try {
|
||||
$htmlContent = $this->renderPhpTemplate($templateName, $data);
|
||||
return $this->convertToPdf($htmlContent, $options);
|
||||
} catch (\Exception $e) {
|
||||
error_log('HtmlToPdfService Error: ' . $e->getMessage());
|
||||
throw new TemplateException('Erreur génération PDF: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rend un template PHP avec les données
|
||||
*/
|
||||
private function renderPhpTemplate($templateName, $data)
|
||||
{
|
||||
$templateFile = $this->templatesPath . $templateName . '.php';
|
||||
|
||||
if (!file_exists($templateFile)) {
|
||||
throw new TemplateException("Template introuvable: " . $templateFile);
|
||||
}
|
||||
|
||||
try {
|
||||
$templateData = array_merge($data, [
|
||||
'logo_base64' => $this->getLogoBase64()
|
||||
]);
|
||||
|
||||
extract($templateData);
|
||||
|
||||
ob_start();
|
||||
include $templateFile;
|
||||
return ob_get_clean();
|
||||
|
||||
} catch (Throwable $e) {
|
||||
ob_end_clean();
|
||||
throw new TemplateException("Erreur lors du rendu du template: " . $e->getMessage(), 0, $e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Récupère le logo en base64
|
||||
*/
|
||||
private function getLogoBase64()
|
||||
{
|
||||
$logoPath = $this->assetsPath . 'logo.png';
|
||||
|
||||
if (file_exists($logoPath)) {
|
||||
return base64_encode(file_get_contents($logoPath));
|
||||
}
|
||||
|
||||
// Retour d'un pixel transparent si pas de logo
|
||||
return 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==';
|
||||
}
|
||||
|
||||
/**
|
||||
* Convertit HTML en PDF
|
||||
*/
|
||||
private function convertToPdf($htmlContent, $options = [])
|
||||
{
|
||||
$dompdfOptions = new Options();
|
||||
$dompdfOptions->set('defaultFont', 'DejaVu Sans');
|
||||
$dompdfOptions->set('isRemoteEnabled', true);
|
||||
$dompdfOptions->set('isHtml5ParserEnabled', true);
|
||||
$dompdfOptions->set('enable_css_float', true);
|
||||
$dompdfOptions->set('enable_font_subsetting', true);
|
||||
|
||||
$paper = $options['paper'] ?? 'A4';
|
||||
$orientation = $options['orientation'] ?? 'portrait';
|
||||
|
||||
$dompdf = new Dompdf($dompdfOptions);
|
||||
$dompdf->loadHtml($htmlContent);
|
||||
$dompdf->setPaper($paper, $orientation);
|
||||
$dompdf->render();
|
||||
|
||||
return $dompdf->output();
|
||||
}
|
||||
|
||||
public function generateInvoiceFilename($factureData, $prefix = 'FACTURE')
|
||||
{
|
||||
$numero = str_pad($factureData['num'] ?? '', 6, '0', STR_PAD_LEFT);
|
||||
$month = str_pad($factureData['month'] ?? date('m'), 2, '0', STR_PAD_LEFT);
|
||||
$year = $factureData['year'] ?? date('Y');
|
||||
|
||||
return "{$prefix}_{$numero}_{$month}_{$year}.pdf";
|
||||
}
|
||||
|
||||
/**
|
||||
* Debug template PHP
|
||||
*/
|
||||
public function debugTemplate($templateName, $data)
|
||||
{
|
||||
echo "=== DONNÉES REÇUES ===\n";
|
||||
var_dump($data);
|
||||
|
||||
echo "\n=== TEMPLATE PHP UTILISÉ ===\n";
|
||||
$templateFile = $this->templatesPath . $templateName . '.php';
|
||||
echo "Fichier: $templateFile\n";
|
||||
echo "Existe: " . (file_exists($templateFile) ? "OUI" : "NON") . "\n";
|
||||
|
||||
echo "\n=== HTML GÉNÉRÉ ===\n";
|
||||
$html = $this->renderPhpTemplate($templateName, $data);
|
||||
echo substr($html, 0, 2000) . "...\n";
|
||||
|
||||
return $html;
|
||||
}
|
||||
}
|
||||
@ -27,19 +27,21 @@ declare(strict_types=1);
|
||||
namespace OCA\Gestion\Service;
|
||||
|
||||
use DateTime;
|
||||
use OCA\Gestion\Constants\BddConstant;
|
||||
use OCA\Gestion\Constants\ClientTemplateTypeConstant;
|
||||
use OCA\Gestion\Constants\DevisMentionConstant;
|
||||
use OCA\Gestion\Constants\FactureTypeConstant;
|
||||
use OCA\Gestion\Constants\MultipleFactureTypeConstant;
|
||||
use Exception;
|
||||
use OCA\Gestion\Db\Bdd;
|
||||
use OCA\Gestion\Helpers\DateHelpers;
|
||||
use OCA\Gestion\Service\InvoiceGroupPdfHandler\InvoiceFunecapPdfHandler;
|
||||
use OCA\Gestion\Service\InvoiceGroupPdfHandler\InvoiceGroupPdfHandler;
|
||||
use OCA\Gestion\Service\InvoiceGroupPdfHandler\InvoiceOgfPdfHandler;
|
||||
use OCA\Gestion\Service\InvoiceRecap\InvoiceRecapService;
|
||||
use OCP\DB\Exception;
|
||||
use OCP\Files\IRootFolder;
|
||||
use OCA\Gestion\Helpers\DateHelpers;
|
||||
use OCA\Gestion\Constants\BddConstant;
|
||||
use OCA\Gestion\Service\HtmlToPdfService;
|
||||
use OCA\Gestion\Exception\TemplateException;
|
||||
use OCA\Gestion\Constants\FactureTypeConstant;
|
||||
use OCA\Gestion\Constants\DevisMentionConstant;
|
||||
use OCA\Gestion\Constants\ClientTemplateTypeConstant;
|
||||
use OCA\Gestion\Constants\MultipleFactureTypeConstant;
|
||||
use OCA\Gestion\Service\InvoiceRecap\InvoiceRecapService;
|
||||
use OCA\Gestion\Service\InvoiceGroupPdfHandler\InvoiceOgfPdfHandler;
|
||||
use OCA\Gestion\Service\InvoiceGroupPdfHandler\InvoiceGroupPdfHandler;
|
||||
use OCA\Gestion\Service\InvoiceGroupPdfHandler\InvoiceFunecapPdfHandler;
|
||||
|
||||
class InvoicePdfService
|
||||
{
|
||||
@ -52,6 +54,8 @@ class InvoicePdfService
|
||||
/** @var InvoiceRecapService */
|
||||
private $invoiceRecapService;
|
||||
|
||||
private $htmlToPdfService;
|
||||
|
||||
private const DEFAULT_NEXTCLOUD_ADMIN = "admin";
|
||||
public function __construct(
|
||||
Bdd $gestionBdd,
|
||||
@ -61,6 +65,7 @@ class InvoicePdfService
|
||||
$this->gestionBdd = $gestionBdd;
|
||||
$this->rootFolder = $rootFolder;
|
||||
$this->invoiceRecapService = $invoiceRecapService;
|
||||
$this->htmlToPdfService = new HtmlToPdfService();
|
||||
}
|
||||
|
||||
private function getLogo()
|
||||
@ -174,6 +179,12 @@ class InvoicePdfService
|
||||
if($invoicePdfData == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// NOUVELLE LOGIQUE : Vérifier si TVA exonérée
|
||||
if ($this->isTvaExempt($invoicePdfData)) {
|
||||
return $this->generateWithHtmlTemplate($invoicePdfData, $storage);
|
||||
}
|
||||
|
||||
$templateType = $invoicePdfData['template_type_key'];
|
||||
$clean_folder = html_entity_decode(string: $currentConfig->path).'/';
|
||||
$factureFolders = $this->getGroupFactureFolder($invoicePdfData, $clean_folder);
|
||||
@ -200,17 +211,20 @@ class InvoicePdfService
|
||||
$pdfContent = $pdf->Output('', 'S');
|
||||
$pdfFilename = $pdf->GetInvoiceFilename();
|
||||
$filenames = [];
|
||||
|
||||
foreach($factureFolders as $folder) {
|
||||
try {
|
||||
$storage->newFolder($folder);
|
||||
} catch(\OCP\Files\NotPermittedException $e) {
|
||||
} catch(TemplateException $e) {
|
||||
// Ignore si le dossier existe déjà
|
||||
}
|
||||
$ff_pdf = $folder.$pdfFilename.'.pdf';
|
||||
$ff_pdf = $folder.$pdfFilename;
|
||||
$storage->newFile($ff_pdf);
|
||||
$file_pdf = $storage->get($ff_pdf);
|
||||
$file_pdf->putContent($pdfContent);
|
||||
$filenames[] = $ff_pdf;
|
||||
}
|
||||
|
||||
$this->gestionBdd->setFactureGeneratedDate($factureId);
|
||||
return [
|
||||
"content" => $pdfContent,
|
||||
@ -218,6 +232,19 @@ class InvoicePdfService
|
||||
];
|
||||
}
|
||||
|
||||
public function sanitizePathDev(string $path): string
|
||||
{
|
||||
$path = ltrim($path, '/');
|
||||
// Remplacer accents UTF-8 par ASCII
|
||||
$path = iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $path);
|
||||
// Supprimer caractères interdits par Nextcloud/Docker
|
||||
$path = preg_replace('#[<>:"/\\|?*]#', '_', $path);
|
||||
// Supprimer doublons d'espaces
|
||||
$path = preg_replace('#\s+#', ' ', $path);
|
||||
return trim($path);
|
||||
}
|
||||
|
||||
|
||||
public function generateFacturePdfByFactureIds(array $factureIds, $idNextCloud)
|
||||
{
|
||||
foreach($factureIds as $factureId) {
|
||||
@ -338,4 +365,305 @@ class InvoicePdfService
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* NOUVELLE MÉTHODE : Génération avec template HTML
|
||||
*/
|
||||
private function generateWithHtmlTemplate($invoicePdfData, $storage)
|
||||
{
|
||||
try {
|
||||
// Préparer les données pour le template HTML
|
||||
$templateData = $this->prepareHtmlTemplateData($invoicePdfData);
|
||||
|
||||
// Générer le PDF avec le nouveau système
|
||||
$pdfContent = $this->htmlToPdfService->generatePdf('facture_dv_thanato', $templateData);
|
||||
|
||||
// Nom du fichier
|
||||
$pdfFilename = $this->htmlToPdfService->generateInvoiceFilename($invoicePdfData);
|
||||
|
||||
// Sauvegarder dans Nextcloud
|
||||
$clean_folder = html_entity_decode(string: $invoicePdfData['configuration']->path).'/';
|
||||
$factureFolders = $this->getGroupFactureFolder($invoicePdfData, $clean_folder);
|
||||
$filenames = [];
|
||||
|
||||
foreach ($factureFolders as $folder) {
|
||||
|
||||
// --- GESTION DU CHEMIN ---
|
||||
if (($_ENV['APP_ENV'] ?? 'prod') === 'dev') {
|
||||
// En dev : remplacer les accents et caractères spéciaux pour Docker
|
||||
$relativeFolder = $this->sanitizePathDev($folder);
|
||||
$pdfFileNameSafe = $this->sanitizePathDev($pdfFilename);
|
||||
} else {
|
||||
// En prod : garder UTF-8, juste retirer slash initial
|
||||
$relativeFolder = ltrim($folder, '/');
|
||||
$pdfFileNameSafe = $pdfFilename;
|
||||
}
|
||||
|
||||
// --- CREATION DU DOSSIER ---
|
||||
try {
|
||||
if (!$storage->nodeExists($relativeFolder)) {
|
||||
$storage->newFolder($relativeFolder);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
echo "ERROR creating folder '$relativeFolder': " . $e->getMessage();
|
||||
exit;
|
||||
}
|
||||
|
||||
// --- CHEMIN COMPLET DU FICHIER ---
|
||||
$ff_pdf = rtrim($relativeFolder, '/') . '/' . $pdfFileNameSafe . '.pdf';
|
||||
|
||||
// --- CREATION OU MISE A JOUR DU FICHIER ---
|
||||
try {
|
||||
if ($storage->nodeExists($ff_pdf)) {
|
||||
$file_pdf = $storage->get($ff_pdf);
|
||||
} else {
|
||||
$file_pdf = $storage->newFile($ff_pdf);
|
||||
}
|
||||
$file_pdf->putContent($pdfContent);
|
||||
$filenames[] = $ff_pdf;
|
||||
} catch (\Throwable $e) {
|
||||
echo "ERROR on file '$ff_pdf': " . $e->getMessage();
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
$this->gestionBdd->setFactureGeneratedDate($invoicePdfData['id']);
|
||||
|
||||
return [
|
||||
"content" => $pdfContent,
|
||||
"filenames" => $filenames
|
||||
];
|
||||
|
||||
} catch (TemplateException $e) {
|
||||
error_log('HTML Template PDF Error: ' . $e->getMessage());
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* NOUVELLE MÉTHODE : Détecte si TVA exonérée
|
||||
*/
|
||||
private function isTvaExempt($invoicePdfData)
|
||||
{
|
||||
// Vérifier si c'est un client unique avec TVA = 0
|
||||
if (isset($invoicePdfData['fk_client_id']) && $invoicePdfData['fk_client_id'] != null && $invoicePdfData['fk_client_id'] != 0) {
|
||||
$client = $this->gestionBdd->getClientById($invoicePdfData['fk_client_id']);
|
||||
if (isset($client['tva']) && $client['tva'] == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Vérification alternative dans les totaux si la première méthode ne fonctionne pas
|
||||
if (isset($invoicePdfData['totalPrices'])) {
|
||||
foreach ($invoicePdfData['totalPrices'] as $label => $amount) {
|
||||
if (strpos($label, 'TVA') !== false && (strpos($label, 'exonéré') !== false || $amount == 0)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prépare les données pour le template HTML - Version refactorisée
|
||||
*/
|
||||
private function prepareHtmlTemplateData($invoicePdfData)
|
||||
{
|
||||
return [
|
||||
'company' => $this->prepareCompanyData($invoicePdfData),
|
||||
'client' => $this->prepareClientData($invoicePdfData),
|
||||
'facture' => $this->prepareInvoiceData($invoicePdfData),
|
||||
'groupedArticles' => $this->prepareGroupedArticles($invoicePdfData),
|
||||
'totals' => $this->prepareTotals($invoicePdfData),
|
||||
'bank' => $this->prepareBankData($invoicePdfData),
|
||||
'legal_text' => $this->getLegalText()
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Prépare les données de l'entreprise
|
||||
*/
|
||||
private function prepareCompanyData($invoicePdfData)
|
||||
{
|
||||
$config = $invoicePdfData['configuration'];
|
||||
|
||||
return [
|
||||
'name' => $config->entreprise ?? 'DV Thanato',
|
||||
'address' => $invoicePdfData['configuration_adresse'] ?? '47 rue Boldoduc',
|
||||
'city' => $invoicePdfData['configuration_adresse_city'] ?? '59800 Lille',
|
||||
'phone' => $config->telephone ?? '06.13.57.29.84',
|
||||
'email' => $config->mail ?? 'soins@dvthanato.fr',
|
||||
'logo' => 'logo_dv_thanato.png'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Prépare les données du client
|
||||
*/
|
||||
private function prepareClientData($invoicePdfData)
|
||||
{
|
||||
return [
|
||||
'name' => $invoicePdfData['group_name'] ?? '',
|
||||
'address' => $invoicePdfData['client_real_adress'] ?? '',
|
||||
'city' => $invoicePdfData['client_adress_city'] ?? '',
|
||||
'siret' => $invoicePdfData['siret'] ?? ''
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Prépare les données de la facture
|
||||
*/
|
||||
private function prepareInvoiceData($invoicePdfData)
|
||||
{
|
||||
$numero = $invoicePdfData['num'] ?? '';
|
||||
|
||||
return [
|
||||
'date' => date('d-m-Y'),
|
||||
'number' => 'FAC' . str_pad((string)$numero, 6, '0', STR_PAD_LEFT),
|
||||
'echeance' => date('d-m-Y', strtotime('+30 days')),
|
||||
'period_start' => date('d/m/Y', strtotime($invoicePdfData['date'] ?? 'now')),
|
||||
'period_end' => date('d/m/Y', strtotime($invoicePdfData['date_paiement'] ?? 'now'))
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Prépare les articles groupés par date et défunt
|
||||
*/
|
||||
private function prepareGroupedArticles($invoicePdfData)
|
||||
{
|
||||
if (!isset($invoicePdfData['devis']) || !is_array($invoicePdfData['devis'])) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$groupedByDate = [];
|
||||
|
||||
foreach ($invoicePdfData['devis'] as $devis) {
|
||||
$this->processDevis($devis, $groupedByDate);
|
||||
}
|
||||
|
||||
return $this->convertToIndexedArray($groupedByDate);
|
||||
}
|
||||
|
||||
/**
|
||||
* Traite un devis et l'ajoute aux données groupées
|
||||
*/
|
||||
private function processDevis($devis, &$groupedByDate)
|
||||
{
|
||||
$dateDevis = date('d/m/Y', strtotime($devis['devis_date'] ?? 'now'));
|
||||
$defuntNom = $devis['defunt_nom'] ?? 'Non défini';
|
||||
|
||||
$this->initializeDateGroup($groupedByDate, $dateDevis);
|
||||
$this->initializeDefuntGroup($groupedByDate, $dateDevis, $defuntNom);
|
||||
$this->addServicesToDefunt($groupedByDate, $dateDevis, $defuntNom, $devis['products'] ?? []);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise un groupe de date
|
||||
*/
|
||||
private function initializeDateGroup(&$groupedByDate, $dateDevis)
|
||||
{
|
||||
if (!isset($groupedByDate[$dateDevis])) {
|
||||
$groupedByDate[$dateDevis] = [
|
||||
'date' => $dateDevis,
|
||||
'defunts' => []
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise un groupe de défunt
|
||||
*/
|
||||
private function initializeDefuntGroup(&$groupedByDate, $dateDevis, $defuntNom)
|
||||
{
|
||||
if (!isset($groupedByDate[$dateDevis]['defunts'][$defuntNom])) {
|
||||
$groupedByDate[$dateDevis]['defunts'][$defuntNom] = [
|
||||
'nom' => $defuntNom,
|
||||
'services' => []
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajoute les services à un défunt
|
||||
*/
|
||||
private function addServicesToDefunt(&$groupedByDate, $dateDevis, $defuntNom, $products)
|
||||
{
|
||||
foreach ($products as $product) {
|
||||
$service = $this->createServiceFromProduct($product);
|
||||
$groupedByDate[$dateDevis]['defunts'][$defuntNom]['services'][] = $service;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Crée un service à partir d'un produit
|
||||
*/
|
||||
private function createServiceFromProduct($product)
|
||||
{
|
||||
$prixHt = ($product['produit_price'] ?? 0) * ($product['quantite'] ?? 1);
|
||||
|
||||
return [
|
||||
'reference' => $product['produit_reference'] ?? '',
|
||||
'description' => $product['produit_description'] ?? 'Produit inconnu',
|
||||
'prix_ht' => number_format($prixHt, 2, ',', ' '),
|
||||
'quantite' => number_format($product['quantite'] ?? 1, 2, ',', ' '),
|
||||
'prix_ttc' => number_format($prixHt, 2, ',', ' ')
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Convertit les données groupées en array indexé
|
||||
*/
|
||||
private function convertToIndexedArray($groupedByDate)
|
||||
{
|
||||
$groupedArticles = [];
|
||||
|
||||
foreach ($groupedByDate as $dateGroup) {
|
||||
$defuntsArray = array_values($dateGroup['defunts']);
|
||||
$dateGroup['defunts'] = $defuntsArray;
|
||||
$groupedArticles[] = $dateGroup;
|
||||
}
|
||||
|
||||
return $groupedArticles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prépare les totaux
|
||||
*/
|
||||
private function prepareTotals($invoicePdfData)
|
||||
{
|
||||
$totalPrices = $invoicePdfData['totalPrices'] ?? [];
|
||||
|
||||
return [
|
||||
'total_ht' => number_format($totalPrices['TOTAL HT'] ?? 0, 2, ',', ' '),
|
||||
'total_tva' => '0,00',
|
||||
'total_ttc' => number_format($totalPrices['TOTAL TTC'] ?? 0, 2, ',', ' '),
|
||||
'tva_label' => 'TVA (exonéré)'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Prépare les données bancaires
|
||||
*/
|
||||
private function prepareBankData($invoicePdfData)
|
||||
{
|
||||
$config = $invoicePdfData['configuration'];
|
||||
|
||||
return [
|
||||
'iban' => 'FR76 1670 6052 4453 9757 9734 871',
|
||||
'swift' => 'AGRI FR PP867',
|
||||
'rcs' => $config->legal_one ?? '901 115 931 R.C.S Lille Métropole'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Texte légal
|
||||
*/
|
||||
private function getLegalText()
|
||||
{
|
||||
return "Tout retard de paiement entraînera de plein droit une pénalité de retard de 3 fois le taux légal " .
|
||||
"(Loi 2008-776 du 4 août 2008) et une indemnité forfaitaire de 40 EUR pour frais de recouvrement sera appliquée.\n" .
|
||||
"Si les frais de recouvrement sont supérieurs à ce montant forfaitaire, une indemnisation complémentaire " .
|
||||
"sera due sur présentation de justificatifs (articles L 441-3 et L 441-6 du code de commerce).";
|
||||
}
|
||||
}
|
||||
|
||||
194
gestion/templates/pdf/facture_dv_thanato.php
Normal file
194
gestion/templates/pdf/facture_dv_thanato.php
Normal file
@ -0,0 +1,194 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Facture DV Thanato</title>
|
||||
<style>
|
||||
@page { margin: 20mm 15mm; size: A4; }
|
||||
body { font-family: Arial, sans-serif; font-size: 11px; line-height: 1.4; color: #000; margin: 0; padding: 0; }
|
||||
.container { width: 100%; }
|
||||
|
||||
/* LOGO EN HAUT */
|
||||
.logo-section { margin-bottom: 20px; }
|
||||
.logo { width: 180px; height: auto; }
|
||||
|
||||
/* HEADER AVEC TABLE POUR ALIGNEMENT */
|
||||
.header-table { width: 100%; margin-bottom: 30px; }
|
||||
.header-table td { vertical-align: top; padding: 0; }
|
||||
.header-left { width: 45%; }
|
||||
.header-right { width: 55%; text-align: right; }
|
||||
|
||||
/* INFORMATIONS GAUCHE */
|
||||
.invoice-info { line-height: 1.6; }
|
||||
.info-line { margin: 5px 0; }
|
||||
.info-line strong { display: inline-block; width: 140px; font-weight: bold; }
|
||||
|
||||
/* INFORMATIONS CLIENT DROITE */
|
||||
.client-info { text-align: right; line-height: 1.5; font-size: 12px; }
|
||||
.client-info strong { display: block; margin-bottom: 3px; font-size: 13px; }
|
||||
|
||||
.invoice-header { margin: 25px 0; }
|
||||
.invoice-header h2 { font-size: 14px; margin: 5px 0; font-weight: bold; }
|
||||
.invoice-period { font-size: 11px; margin: 5px 0; }
|
||||
|
||||
/* TABLEAU SERVICES */
|
||||
.services-table { width: 100%; border-collapse: collapse; margin: 20px 0; }
|
||||
.services-table th { background-color: #f0f0f0; border: 1px solid #ccc; padding: 8px; text-align: left; font-weight: bold; font-size: 11px; }
|
||||
.services-table td { border: 1px solid #ccc; padding: 6px 8px; vertical-align: top; font-size: 10px; }
|
||||
|
||||
.ref-col { width: 12%; }
|
||||
.label-col { width: 48%; }
|
||||
.price-col { width: 13%; text-align: right; }
|
||||
.qty-col { width: 10%; text-align: center; }
|
||||
.amount-col { width: 17%; text-align: right; }
|
||||
|
||||
/* LIGNES SPÉCIALES */
|
||||
.date-row { background-color: #f8f8f8; font-weight: bold; }
|
||||
.date-row td { padding: 8px; border: none; border-bottom: 1px solid #ddd; text-align: center; }
|
||||
|
||||
.deceased-row { font-style: italic; background-color: #fafafa; }
|
||||
.deceased-row td { padding: 8px; border: none; font-weight: bold; }
|
||||
|
||||
/* TOTAUX */
|
||||
.totals-section { margin-top: 30px; }
|
||||
.totals-table { width: 300px; float: right; border-collapse: collapse; }
|
||||
.totals-table td { padding: 8px 12px; font-size: 12px; }
|
||||
.total-label { text-align: right; font-weight: bold; width: 60%; }
|
||||
.total-amount { text-align: right; font-weight: bold; width: 40%; }
|
||||
.total-row-ht { border-top: 1px solid #ccc; }
|
||||
.total-row-final { border-top: 2px solid #000; font-size: 13px; }
|
||||
|
||||
/* CLEAR FLOAT */
|
||||
.clear { clear: both; }
|
||||
|
||||
/* MENTIONS LÉGALES */
|
||||
.legal-section { margin-top: 40px; padding-top: 20px; border-top: 1px solid #ccc; }
|
||||
.legal-text { font-size: 9px; line-height: 1.4; margin-bottom: 20px; text-align: justify; }
|
||||
.bank-info { margin: 20px 0; font-size: 10px; line-height: 1.5; }
|
||||
.bank-info strong { display: inline-block; width: 150px; }
|
||||
.company-footer { margin-top: 30px; padding: 15px; background-color: #f5f5f5; font-size: 10px; line-height: 1.5; }
|
||||
.company-footer strong { display: block; margin-bottom: 5px; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<!-- Logo en haut à gauche -->
|
||||
<div class="logo-section">
|
||||
<img src="data:image/png;base64,<?= $logo_base64 ?>" alt="<?= htmlspecialchars($company['name']) ?>" class="logo">
|
||||
</div>
|
||||
|
||||
<!-- Header avec table pour compatibilité dompdf -->
|
||||
<table class="header-table">
|
||||
<tr>
|
||||
<td class="header-left">
|
||||
<div class="invoice-info">
|
||||
<div class="info-line">
|
||||
<strong>Date :</strong><?= htmlspecialchars($facture['date']) ?>
|
||||
</div>
|
||||
<div class="info-line">
|
||||
<strong>Échéance :</strong><?= htmlspecialchars($facture['echeance']) ?>
|
||||
</div>
|
||||
<div class="info-line">
|
||||
<strong>Mode de paiement :</strong>Virement
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="header-right">
|
||||
<div class="client-info">
|
||||
<strong><?= htmlspecialchars($client['name']) ?></strong>
|
||||
<?= htmlspecialchars($client['address']) ?><br>
|
||||
<?= htmlspecialchars($client['city']) ?><br>
|
||||
<?php if (!empty($client['siret'])): ?>
|
||||
SIRET: <?= htmlspecialchars($client['siret']) ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- Numéro de facture -->
|
||||
<div class="invoice-header">
|
||||
<h2>Facture <?= htmlspecialchars($facture['number']) ?></h2>
|
||||
<div class="invoice-period">Période : du <?= htmlspecialchars($facture['period_start']) ?> au <?= htmlspecialchars($facture['period_end']) ?></div>
|
||||
</div>
|
||||
|
||||
<!-- Tableau des services -->
|
||||
<table class="services-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="ref-col">Référence</th>
|
||||
<th class="label-col">Libellé</th>
|
||||
<th class="price-col">P.U HT</th>
|
||||
<th class="qty-col">Quantité</th>
|
||||
<th class="amount-col">Montant HT</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php foreach ($groupedArticles as $dateGroup): ?>
|
||||
<!-- Ligne de date centrée -->
|
||||
<tr class="date-row">
|
||||
<td colspan="5"><strong><?= htmlspecialchars($dateGroup['date']) ?></strong></td>
|
||||
</tr>
|
||||
|
||||
<?php foreach ($dateGroup['defunts'] as $defunt): ?>
|
||||
<!-- Ligne du défunt -->
|
||||
<tr class="deceased-row">
|
||||
<td colspan="5"><?= htmlspecialchars($defunt['nom']) ?></td>
|
||||
</tr>
|
||||
|
||||
<!-- Services pour ce défunt -->
|
||||
<?php foreach ($defunt['services'] as $service): ?>
|
||||
<tr>
|
||||
<td class="ref-col"><?= htmlspecialchars($service['reference']) ?></td>
|
||||
<td class="label-col"><?= htmlspecialchars($service['description']) ?></td>
|
||||
<td class="price-col"><?= htmlspecialchars($service['prix_ht']) ?> €</td>
|
||||
<td class="qty-col"><?= htmlspecialchars($service['quantite']) ?></td>
|
||||
<td class="amount-col"><?= htmlspecialchars($service['prix_ttc']) ?> €</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php endforeach; ?>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<!-- Section totaux -->
|
||||
<div class="totals-section">
|
||||
<table class="totals-table">
|
||||
<tr class="total-row-ht">
|
||||
<td class="total-label">Total HT</td>
|
||||
<td class="total-amount"><?= htmlspecialchars($totals['total_ht']) ?> €</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="total-label"><?= htmlspecialchars($totals['tva_label']) ?></td>
|
||||
<td class="total-amount"><?= htmlspecialchars($totals['total_tva']) ?> €</td>
|
||||
</tr>
|
||||
<tr class="total-row-final">
|
||||
<td class="total-label">Montant total</td>
|
||||
<td class="total-amount"><?= htmlspecialchars($totals['total_ttc']) ?> €</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
|
||||
<!-- Mentions légales -->
|
||||
<div class="legal-section">
|
||||
<div class="legal-text">
|
||||
<?= nl2br(htmlspecialchars($legal_text)) ?>
|
||||
</div>
|
||||
|
||||
<div class="bank-info">
|
||||
<div><strong>Coordonnées bancaires</strong></div>
|
||||
<div><strong>IBAN:</strong> <?= htmlspecialchars($bank['iban']) ?></div>
|
||||
<div><strong>BIC:</strong> <?= htmlspecialchars($bank['swift']) ?></div>
|
||||
</div>
|
||||
|
||||
<div class="company-footer">
|
||||
<strong><?= htmlspecialchars($company['name']) ?></strong>
|
||||
<?= htmlspecialchars($company['address']) ?>, <?= htmlspecialchars($company['city']) ?><br>
|
||||
<?= htmlspecialchars($bank['rcs']) ?> - Code NAF 9603Z
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
303
gestion/vendor/composer/installed.json
vendored
303
gestion/vendor/composer/installed.json
vendored
@ -125,6 +125,240 @@
|
||||
],
|
||||
"install-path": "../doctrine/instantiator"
|
||||
},
|
||||
{
|
||||
"name": "dompdf/dompdf",
|
||||
"version": "v3.1.0",
|
||||
"version_normalized": "3.1.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/dompdf/dompdf.git",
|
||||
"reference": "a51bd7a063a65499446919286fb18b518177155a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/dompdf/dompdf/zipball/a51bd7a063a65499446919286fb18b518177155a",
|
||||
"reference": "a51bd7a063a65499446919286fb18b518177155a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"dompdf/php-font-lib": "^1.0.0",
|
||||
"dompdf/php-svg-lib": "^1.0.0",
|
||||
"ext-dom": "*",
|
||||
"ext-mbstring": "*",
|
||||
"masterminds/html5": "^2.0",
|
||||
"php": "^7.1 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-gd": "*",
|
||||
"ext-json": "*",
|
||||
"ext-zip": "*",
|
||||
"mockery/mockery": "^1.3",
|
||||
"phpunit/phpunit": "^7.5 || ^8 || ^9 || ^10 || ^11",
|
||||
"squizlabs/php_codesniffer": "^3.5",
|
||||
"symfony/process": "^4.4 || ^5.4 || ^6.2 || ^7.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-gd": "Needed to process images",
|
||||
"ext-gmagick": "Improves image processing performance",
|
||||
"ext-imagick": "Improves image processing performance",
|
||||
"ext-zlib": "Needed for pdf stream compression"
|
||||
},
|
||||
"time": "2025-01-15T14:09:04+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Dompdf\\": "src/"
|
||||
},
|
||||
"classmap": [
|
||||
"lib/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"LGPL-2.1"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "The Dompdf Community",
|
||||
"homepage": "https://github.com/dompdf/dompdf/blob/master/AUTHORS.md"
|
||||
}
|
||||
],
|
||||
"description": "DOMPDF is a CSS 2.1 compliant HTML to PDF converter",
|
||||
"homepage": "https://github.com/dompdf/dompdf",
|
||||
"support": {
|
||||
"issues": "https://github.com/dompdf/dompdf/issues",
|
||||
"source": "https://github.com/dompdf/dompdf/tree/v3.1.0"
|
||||
},
|
||||
"install-path": "../dompdf/dompdf"
|
||||
},
|
||||
{
|
||||
"name": "dompdf/php-font-lib",
|
||||
"version": "1.0.1",
|
||||
"version_normalized": "1.0.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/dompdf/php-font-lib.git",
|
||||
"reference": "6137b7d4232b7f16c882c75e4ca3991dbcf6fe2d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/dompdf/php-font-lib/zipball/6137b7d4232b7f16c882c75e4ca3991dbcf6fe2d",
|
||||
"reference": "6137b7d4232b7f16c882c75e4ca3991dbcf6fe2d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-mbstring": "*",
|
||||
"php": "^7.1 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/phpunit-bridge": "^3 || ^4 || ^5 || ^6"
|
||||
},
|
||||
"time": "2024-12-02T14:37:59+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"FontLib\\": "src/FontLib"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"LGPL-2.1-or-later"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "The FontLib Community",
|
||||
"homepage": "https://github.com/dompdf/php-font-lib/blob/master/AUTHORS.md"
|
||||
}
|
||||
],
|
||||
"description": "A library to read, parse, export and make subsets of different types of font files.",
|
||||
"homepage": "https://github.com/dompdf/php-font-lib",
|
||||
"support": {
|
||||
"issues": "https://github.com/dompdf/php-font-lib/issues",
|
||||
"source": "https://github.com/dompdf/php-font-lib/tree/1.0.1"
|
||||
},
|
||||
"install-path": "../dompdf/php-font-lib"
|
||||
},
|
||||
{
|
||||
"name": "dompdf/php-svg-lib",
|
||||
"version": "1.0.0",
|
||||
"version_normalized": "1.0.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/dompdf/php-svg-lib.git",
|
||||
"reference": "eb045e518185298eb6ff8d80d0d0c6b17aecd9af"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/dompdf/php-svg-lib/zipball/eb045e518185298eb6ff8d80d0d0c6b17aecd9af",
|
||||
"reference": "eb045e518185298eb6ff8d80d0d0c6b17aecd9af",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-mbstring": "*",
|
||||
"php": "^7.1 || ^8.0",
|
||||
"sabberworm/php-css-parser": "^8.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.5"
|
||||
},
|
||||
"time": "2024-04-29T13:26:35+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Svg\\": "src/Svg"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"LGPL-3.0-or-later"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "The SvgLib Community",
|
||||
"homepage": "https://github.com/dompdf/php-svg-lib/blob/master/AUTHORS.md"
|
||||
}
|
||||
],
|
||||
"description": "A library to read, parse and export to PDF SVG files.",
|
||||
"homepage": "https://github.com/dompdf/php-svg-lib",
|
||||
"support": {
|
||||
"issues": "https://github.com/dompdf/php-svg-lib/issues",
|
||||
"source": "https://github.com/dompdf/php-svg-lib/tree/1.0.0"
|
||||
},
|
||||
"install-path": "../dompdf/php-svg-lib"
|
||||
},
|
||||
{
|
||||
"name": "masterminds/html5",
|
||||
"version": "2.10.0",
|
||||
"version_normalized": "2.10.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Masterminds/html5-php.git",
|
||||
"reference": "fcf91eb64359852f00d921887b219479b4f21251"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Masterminds/html5-php/zipball/fcf91eb64359852f00d921887b219479b4f21251",
|
||||
"reference": "fcf91eb64359852f00d921887b219479b4f21251",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-dom": "*",
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8 || ^9"
|
||||
},
|
||||
"time": "2025-07-25T09:04:22+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.7-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Masterminds\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Matt Butcher",
|
||||
"email": "technosophos@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Matt Farina",
|
||||
"email": "matt@mattfarina.com"
|
||||
},
|
||||
{
|
||||
"name": "Asmir Mustafic",
|
||||
"email": "goetas@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "An HTML5 parser and serializer.",
|
||||
"homepage": "http://masterminds.github.io/html5-php",
|
||||
"keywords": [
|
||||
"HTML5",
|
||||
"dom",
|
||||
"html",
|
||||
"parser",
|
||||
"querypath",
|
||||
"serializer",
|
||||
"xml"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/Masterminds/html5-php/issues",
|
||||
"source": "https://github.com/Masterminds/html5-php/tree/2.10.0"
|
||||
},
|
||||
"install-path": "../masterminds/html5"
|
||||
},
|
||||
{
|
||||
"name": "myclabs/deep-copy",
|
||||
"version": "1.11.0",
|
||||
@ -1318,6 +1552,75 @@
|
||||
},
|
||||
"install-path": "../psr/log"
|
||||
},
|
||||
{
|
||||
"name": "sabberworm/php-css-parser",
|
||||
"version": "v8.9.0",
|
||||
"version_normalized": "8.9.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/MyIntervals/PHP-CSS-Parser.git",
|
||||
"reference": "d8e916507b88e389e26d4ab03c904a082aa66bb9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/MyIntervals/PHP-CSS-Parser/zipball/d8e916507b88e389e26d4ab03c904a082aa66bb9",
|
||||
"reference": "d8e916507b88e389e26d4ab03c904a082aa66bb9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-iconv": "*",
|
||||
"php": "^5.6.20 || ^7.0.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "5.7.27 || 6.5.14 || 7.5.20 || 8.5.41",
|
||||
"rawr/cross-data-providers": "^2.0.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-mbstring": "for parsing UTF-8 CSS"
|
||||
},
|
||||
"time": "2025-07-11T13:20:48+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "9.0.x-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Sabberworm\\CSS\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Raphael Schweikert"
|
||||
},
|
||||
{
|
||||
"name": "Oliver Klee",
|
||||
"email": "github@oliverklee.de"
|
||||
},
|
||||
{
|
||||
"name": "Jake Hotson",
|
||||
"email": "jake.github@qzdesign.co.uk"
|
||||
}
|
||||
],
|
||||
"description": "Parser for CSS Files written in PHP",
|
||||
"homepage": "https://www.sabberworm.com/blog/2010/6/10/php-css-parser",
|
||||
"keywords": [
|
||||
"css",
|
||||
"parser",
|
||||
"stylesheet"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/MyIntervals/PHP-CSS-Parser/issues",
|
||||
"source": "https://github.com/MyIntervals/PHP-CSS-Parser/tree/v8.9.0"
|
||||
},
|
||||
"install-path": "../sabberworm/php-css-parser"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/cli-parser",
|
||||
"version": "1.0.1",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user