From 69099e71871269d804e2395945cf463f07720c13 Mon Sep 17 00:00:00 2001 From: Tiavina Date: Sun, 2 Mar 2025 15:18:13 +0300 Subject: [PATCH 1/3] finish funecap facture, wip ogf facture --- .../Constants/ClientTemplateTypeConstant.php | 10 ++ gestion/lib/Db/Bdd.php | 10 +- .../InvoiceFunecapPdfHandler.php | 156 ++++++++++++++++++ .../InvoiceGroupPdfHandler.php | 58 ++++--- gestion/lib/Service/InvoicePdfService.php | 10 +- 5 files changed, 214 insertions(+), 30 deletions(-) create mode 100644 gestion/lib/Constants/ClientTemplateTypeConstant.php create mode 100644 gestion/lib/Service/InvoiceGroupPdfHandler/InvoiceFunecapPdfHandler.php diff --git a/gestion/lib/Constants/ClientTemplateTypeConstant.php b/gestion/lib/Constants/ClientTemplateTypeConstant.php new file mode 100644 index 0000000..f89af76 --- /dev/null +++ b/gestion/lib/Constants/ClientTemplateTypeConstant.php @@ -0,0 +1,10 @@ +tableprefix."devis as devis LEFT JOIN ".$this->tableprefix."client as client on devis.id_client = client.id LEFT JOIN ".$this->tableprefix."defunt as defunt on devis.id_defunt = defunt.id @@ -4337,7 +4342,8 @@ class Bdd { client_group_facturation.city as group_city, client_group_facturation.email as group_email, client_group_facturation.siret_number as group_siret_number, - client_group_facturation.tva_intracommu as group_tva_intracommu + client_group_facturation.tva_intracommu as group_tva_intracommu, + client_group_facturation.fk_template_type_key as fk_template_type_key FROM ".$this->tableprefix."devis as devis LEFT JOIN ".$this->tableprefix."client as client on devis.id_client = client.id LEFT JOIN ".$this->tableprefix."defunt as defunt on devis.id_defunt = defunt.id diff --git a/gestion/lib/Service/InvoiceGroupPdfHandler/InvoiceFunecapPdfHandler.php b/gestion/lib/Service/InvoiceGroupPdfHandler/InvoiceFunecapPdfHandler.php new file mode 100644 index 0000000..fa07dab --- /dev/null +++ b/gestion/lib/Service/InvoiceGroupPdfHandler/InvoiceFunecapPdfHandler.php @@ -0,0 +1,156 @@ + + * + * @author Anna Larch + * @author Richard Steinmetz + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see . + * + */ + +namespace OCA\Gestion\Service\InvoiceGroupPdfHandler; + +use DateTime; +use OCA\Gestion\Helpers\FileExportHelpers; +use OCA\Gestion\Helpers\PriceHelpers; + +class InvoiceFunecapPdfHandler extends InvoiceGroupPdfHandler { + public int $maxArticlePerPage = 6; + + public function DrawInvoiceClientInfo(){ + $this->SetFont('ComicSans', '', 10); + $clientName = $this->factureData['group_name']; + $clientInfoXAxis = 125; + + $clientAddress = $this->factureData['client_real_adress']; + $clientAdressWidth = $this->GetStringWidth($clientAddress); + $maxWidth = $this->GetPageWidth(); + $availableWidhtForClientInfo = $maxWidth - 10 - $clientInfoXAxis; + $clientAdressIsMultiline = $clientAdressWidth > $availableWidhtForClientInfo; + + $clientInfoYAxis = $clientAdressIsMultiline ? 35 : 40; + $this->SetXY($clientInfoXAxis,$clientInfoYAxis); + $this->Cell(0, 5, FileExportHelpers::FormatTextForExport($clientName)); + $clientInfoYAxis += 5; + $this->SetXY($clientInfoXAxis,$clientInfoYAxis); + $this->MultiCell( 0, 5, trim(FileExportHelpers::FormatTextForExport($clientAddress))); + if($clientAdressIsMultiline){ + $clientInfoYAxis += 5; + } + $clientInfoYAxis += 5; + $this->SetXY($clientInfoXAxis,$clientInfoYAxis); + $this->Cell(0, 5, trim(FileExportHelpers::FormatTextForExport($this->factureData['client_adress_city']))); + } + public function DrawInvoiceInfoTable(){ + $this->setY(67); + $factureDatePaiement = $this->factureData['date_paiement']; + $factureDatePaiement = DateTime::createFromFormat('Y-m-d',$factureDatePaiement); + $factureDateEcheance = $factureDatePaiement; + $factureDatePaiement = $factureDatePaiement->format('d-m-Y'); + $factureDateEcheance->modify('last day of next month'); + $factureDateEcheance = $factureDateEcheance->format('d-m-Y'); + $this->SetFont('ComicSans', 'B', 11); + $this->Cell(30, 7, 'DATE', 1, 0, 'C'); + $this->Cell(94, 7, 'CLIENT', 1, 0, 'C'); + $this->Cell(40, 7, 'FACTURE', 1, 0, 'C'); + $this->Cell(40, 7, 'ECHEANCE', 1, 1, 'C'); + + $this->SetFont('ComicSans', '', 10); + $this->Cell(30, 7, $factureDatePaiement, 1, 0, 'C'); + $this->Cell(94, 7, utf8_decode(html_entity_decode($this->factureData['group_name'])), 1, 0, 'C'); + $this->Cell(40, 7, $this->factureData['num'], 1, 0, 'C'); + $this->Cell(40, 7, $factureDateEcheance, 1, 1, 'C'); + + $this->startingYOfArticlesTable = 85; + } + + public function DrawArticlesTableValue(){ + $this->SetFont('ComicSans','',10); + $devisData = $this->factureData['devis']; + $tvaValue = $this->factureData["configuration"]->tva_default; + $totalHt = 0; + $totalTtc = 0; + $totalTva = 0; + $yValue = $this->startingYOfArticlesTable + 11; + $maxDescriptionWidth = 98; + $currentIndexPosition = $this->currentIndexPosition; + for($currentIndexPosition;$currentIndexPosition<($this->initialIndexPosition + $this->devisCountToGet);$currentIndexPosition++){ + $currentDevis = $devisData[$currentIndexPosition]; + $devisDate = $currentDevis['devis_date']; + $devisDate = DateTime::createFromFormat('Y-m-d',$devisDate); + $devisDate = $devisDate->format('d-m-Y'); + $products = $currentDevis["products"]; + $subcontractorOrderNumberText = "Numéro de sous traitance ".$currentDevis["order_number"]; + $subcontractorCaseNumberText = "Numéro de dossier ".$currentDevis["case_number"]; + $this->SetXY( 35,$yValue ); + $this->MultiAlignCell(100, 6, FileExportHelpers::FormatTextForExport($subcontractorOrderNumberText),0,'0',); + $yValue += 6; + + $this->SetXY( 35,$yValue ); + $this->MultiAlignCell(100, 6, FileExportHelpers::FormatTextForExport($subcontractorCaseNumberText),0,'0',); + $yValue += 6; + foreach($products as $product){ + $valueHt = $product['produit_price']; + $valueTtc = PriceHelpers::calculPriceWithVatValue($valueHt,$tvaValue); + $totalHt+=$valueHt; + $totalTtc+=$valueTtc; + $productDescription = $product["produit_description"] ?? ""; + $dateValue = ""; + if($product === end($products)){ + $dateValue = $devisDate; + $productDescription .= " de " . $currentDevis["defunt_nom"] ?? ""; + } + $productDescriptionWidth = $this->GetStringWidth($productDescription); + $productDescriptionIsMultiline = $productDescriptionWidth > $maxDescriptionWidth; + $tvaAmount = $valueTtc - $valueHt; + + $this->SetXY( 8,$yValue ); + $this->Cell(20, 6, $dateValue, 0,0); + + $this->SetXY( 35,$yValue ); + $this->MultiAlignCell(100, 6, FileExportHelpers::FormatTextForExport($productDescription),0,'0',); + + $this->SetXY( 138,$yValue ); + $this->Cell(20, 6, number_format($valueHt,2,'.','').chr(128), 0, 0, 'C'); + + $this->SetXY( 160,$yValue ); + $this->Cell(20, 6, number_format($tvaAmount,2,'.','').chr(128), 0, 0, 'C'); + + $this->SetXY( 181,$yValue ); + $this->Cell(25, 6, number_format($valueTtc,2,'.','').chr(128), 0, 1, 'C'); + $yValue += 6; + $totalTva += $tvaAmount; + if($productDescriptionIsMultiline){ + $yValue += 6; + } + } + $yValue += 2; + } + $this->currentIndexPosition = $currentIndexPosition; + $this->initialIndexPosition = $this->currentIndexPosition; + $chargedDevisCount = $this->currentIndexPosition + 1; + var_dump("CURRENT POSITION : ".$this->currentIndexPosition); + var_dump("CHARGED DEVIS COUNT : ".$chargedDevisCount); + $devisLeftToGet = $this->devisCount - $chargedDevisCount; + var_dump("LEFT TO GET : ".$devisLeftToGet); + $this->devisCountToGet = ($devisLeftToGet <= $this->maxArticlePerPage) ? $devisLeftToGet + 1 : $this->maxArticlePerPage; + var_dump("DEVIS COUNT TO GET : ".$this->devisCountToGet); + } + +} diff --git a/gestion/lib/Service/InvoiceGroupPdfHandler/InvoiceGroupPdfHandler.php b/gestion/lib/Service/InvoiceGroupPdfHandler/InvoiceGroupPdfHandler.php index 4785971..36a6df1 100644 --- a/gestion/lib/Service/InvoiceGroupPdfHandler/InvoiceGroupPdfHandler.php +++ b/gestion/lib/Service/InvoiceGroupPdfHandler/InvoiceGroupPdfHandler.php @@ -32,25 +32,25 @@ use OCA\Gestion\Helpers\FileExportHelpers; use OCA\Gestion\Helpers\PriceHelpers; class InvoiceGroupPdfHandler extends FPDF { - private $factureData = []; - private $logo = null; + public $factureData = []; + public $logo = null; - private $productsCount = 0; + public $productsCount = 0; - private $totalPrices = []; - private $devisCount = 0; - private $logoPath = "/var/www/html/data/admin/files/.gestion/"; + public $totalPrices = []; + public $devisCount = 0; + public $logoPath = "/var/www/html/data/admin/files/.gestion/"; - private $currentIndexPosition = 0; - private $initialIndexPosition = 0; + public $currentIndexPosition = 0; + public $initialIndexPosition = 0; - private $devisCountToGet = 0; - private $devisList = []; + public $devisCountToGet = 0; + public $devisList = []; - private $thereIsOrderOrCaseNumber = false; - private $startingYOfArticlesTable = 95; - private const MAX_ARTICLES_PER_PAGE = 19; - private $additionalArticlesLineBasedOnMultiline = 0; + public $thereIsOrderOrCaseNumber = false; + public $startingYOfArticlesTable = 95; + public int $maxArticlePerPage = 19; + public $additionalArticlesLineBasedOnMultiline = 0; function Header() { if($this->logo != "nothing"){ @@ -82,7 +82,7 @@ class InvoiceGroupPdfHandler extends FPDF { $this->productsCount = $this->factureData["productsCount"]; $this->devisCount = count($this->factureData['devis']); $this->totalPrices = $this->factureData["totalPrices"]; - $this->devisCountToGet = ($this->devisCount <= self::MAX_ARTICLES_PER_PAGE ) ? $this->devisCount : self::MAX_ARTICLES_PER_PAGE; + $this->devisCountToGet = ($this->devisCount <= $this->maxArticlePerPage ) ? $this->devisCount : $this->maxArticlePerPage; $this->devisList = $this->factureData['devis']; $this->logo = $logo; } @@ -94,13 +94,13 @@ class InvoiceGroupPdfHandler extends FPDF { return $this->factureData['configuration']->facture_prefixe.'_'.$factureNum.'_'.mb_strtoupper($clientName,'UTF-8'); } - private function DrawPageNumbersText($pageNumber,$pageCount){ + public function DrawPageNumbersText($pageNumber,$pageCount){ $this->SetXY( 120, 5 ); $this->Cell( 160, 8, $pageNumber . '/' . $pageCount, 0, 0, 'C'); } - private function DrawArticlesTable(){ - $pageCount = ceil($this->devisCount / self::MAX_ARTICLES_PER_PAGE); + public function DrawArticlesTable(){ + $pageCount = ceil($this->devisCount / $this->maxArticlePerPage); $pageNumber = 1; while($pageNumber <= $pageCount){ if($pageNumber > 1){ @@ -114,7 +114,7 @@ class InvoiceGroupPdfHandler extends FPDF { } } - private function DrawInvoiceCompanyInfo(){ + public function DrawInvoiceCompanyInfo(){ $this->SetY(40); $this->SetFont('ComicSans', '', 10); $this->Cell(0, 5, FileExportHelpers::FormatTextForExport($this->factureData['configuration']->entreprise), 0, 1); @@ -123,7 +123,7 @@ class InvoiceGroupPdfHandler extends FPDF { $this->Cell(0, 5, FileExportHelpers::FormatTextForExport('Tél : ') . FileExportHelpers::FormatTextForExport($this->factureData['configuration']->telephone),0,1); $this->Cell(0, 5, 'Mail : ' . $this->factureData['configuration']->mail, 0, 1); } - private function DrawInvoiceClientInfo(){ + public function DrawInvoiceClientInfo(){ $this->SetFont('ComicSans', '', 10); $clientName = $this->factureData['group_name']; $clientInfoXAxis = 125; @@ -154,12 +154,12 @@ class InvoiceGroupPdfHandler extends FPDF { $this->Cell(0, 5, FileExportHelpers::FormatTextForExport('Mail : ') . $this->factureData['client_mail']); } - private function DrawInvoiceCompanyAndClientInfo(){ + public function DrawInvoiceCompanyAndClientInfo(){ $this->DrawInvoiceCompanyInfo(); $this->DrawInvoiceClientInfo(); } - private function DrawInvoiceInfoTable(){ + public function DrawInvoiceInfoTable(){ $this->setY(67); $factureDatePaiement = $this->factureData['date_paiement']; $factureDatePaiement = DateTime::createFromFormat('Y-m-d',$factureDatePaiement); @@ -184,7 +184,7 @@ class InvoiceGroupPdfHandler extends FPDF { $this->startingYOfArticlesTable = 85; } - private function DrawArticlesTableRect(){ + public function DrawArticlesTableRect(){ $this->SetLineWidth(0.2); $gapBetweenStartingOfArticlesTableAndColumnName = 10; $tableHeight = $this->thereIsOrderOrCaseNumber ? 137 : 137 + 10; @@ -198,7 +198,7 @@ class InvoiceGroupPdfHandler extends FPDF { $this->Line(180, $this->startingYOfArticlesTable, 180, 232); } - private function DrawArticlesTableHeader(){ + public function DrawArticlesTableHeader(){ $tvaValue = $this->factureData["configuration"]->tva_default; $columnNameY = $this->startingYOfArticlesTable + 1; $this->SetFont('ComicSans','',10); @@ -271,13 +271,17 @@ class InvoiceGroupPdfHandler extends FPDF { } } $this->currentIndexPosition = $currentIndexPosition; - $this->initialIndexPosition += $this->currentIndexPosition; + $this->initialIndexPosition = $this->currentIndexPosition; $chargedDevisCount = $this->currentIndexPosition + 1; + var_dump("CURRENT POSITION : ".$this->currentIndexPosition); + var_dump("CHARGED DEVIS COUNT : ".$chargedDevisCount); $devisLeftToGet = $this->devisCount - $chargedDevisCount; - $this->devisCountToGet = ($devisLeftToGet <= self::MAX_ARTICLES_PER_PAGE) ? $devisLeftToGet + 1 : self::MAX_ARTICLES_PER_PAGE; + var_dump("LEFT TO GET : ".$devisLeftToGet); + $this->devisCountToGet = ($devisLeftToGet <= $this->maxArticlePerPage) ? $devisLeftToGet + 1 : $this->maxArticlePerPage; + var_dump("DEVIS COUNT TO GET : ".$this->devisCountToGet); } - private function DrawBankAndTotalPriceInfo(){ + public function DrawBankAndTotalPriceInfo(){ $this->SetY(235); $this->SetFont('ComicSans', '', 7); $this->MultiCell(0,5,utf8_decode(html_entity_decode("Paiement à votre convenance par chèque à l'ordre de ". $this->factureData['configuration']->entreprise))); diff --git a/gestion/lib/Service/InvoicePdfService.php b/gestion/lib/Service/InvoicePdfService.php index 18e38ca..f715957 100644 --- a/gestion/lib/Service/InvoicePdfService.php +++ b/gestion/lib/Service/InvoicePdfService.php @@ -28,10 +28,12 @@ namespace OCA\Gestion\Service; use DateTime; use OCA\Gestion\Constants\BddConstant; +use OCA\Gestion\Constants\ClientTemplateTypeConstant; use OCA\Gestion\Constants\FactureTypeConstant; use OCA\Gestion\Constants\MultipleFactureTypeConstant; 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\InvoiceRecap\InvoiceRecapService; use OCP\DB\Exception; @@ -156,9 +158,15 @@ class InvoicePdfService { if($invoicePdfData == null){ return ""; } + $templateType = $invoicePdfData['template_type_key']; $clean_folder = html_entity_decode(string: $currentConfig->path).'/'; $factureFolders = $this->getGroupFactureFolder($invoicePdfData,$clean_folder); - $pdf = new InvoiceGroupPdfHandler(); + if($templateType == ClientTemplateTypeConstant::FUNECAP){ + $pdf = new InvoiceFunecapPdfHandler(); + } + else{ + $pdf = new InvoiceGroupPdfHandler(); + } $pdf->AddFont('ComicSans','','Comic Sans MS.php'); $pdf->AddFont('ComicSans','B','comic-sans-bold.php'); $pdf->InvoicePdfFactory($invoicePdfData,$logo); From 9c6ba888f9dcb40f9df04932ebf54dab19ca2b58 Mon Sep 17 00:00:00 2001 From: Tiavina Date: Sun, 2 Mar 2025 15:27:50 +0300 Subject: [PATCH 2/3] finish 3 different templates for group devis to pdf --- .../InvoiceFunecapPdfHandler.php | 51 ---------- .../InvoiceGroupPdfHandler.php | 18 +--- .../InvoiceOgfPdfHandler.php | 92 +++++++++++++++++++ gestion/lib/Service/InvoicePdfService.php | 18 +++- 4 files changed, 110 insertions(+), 69 deletions(-) create mode 100644 gestion/lib/Service/InvoiceGroupPdfHandler/InvoiceOgfPdfHandler.php diff --git a/gestion/lib/Service/InvoiceGroupPdfHandler/InvoiceFunecapPdfHandler.php b/gestion/lib/Service/InvoiceGroupPdfHandler/InvoiceFunecapPdfHandler.php index fa07dab..37237a6 100644 --- a/gestion/lib/Service/InvoiceGroupPdfHandler/InvoiceFunecapPdfHandler.php +++ b/gestion/lib/Service/InvoiceGroupPdfHandler/InvoiceFunecapPdfHandler.php @@ -33,53 +33,6 @@ use OCA\Gestion\Helpers\PriceHelpers; class InvoiceFunecapPdfHandler extends InvoiceGroupPdfHandler { public int $maxArticlePerPage = 6; - public function DrawInvoiceClientInfo(){ - $this->SetFont('ComicSans', '', 10); - $clientName = $this->factureData['group_name']; - $clientInfoXAxis = 125; - - $clientAddress = $this->factureData['client_real_adress']; - $clientAdressWidth = $this->GetStringWidth($clientAddress); - $maxWidth = $this->GetPageWidth(); - $availableWidhtForClientInfo = $maxWidth - 10 - $clientInfoXAxis; - $clientAdressIsMultiline = $clientAdressWidth > $availableWidhtForClientInfo; - - $clientInfoYAxis = $clientAdressIsMultiline ? 35 : 40; - $this->SetXY($clientInfoXAxis,$clientInfoYAxis); - $this->Cell(0, 5, FileExportHelpers::FormatTextForExport($clientName)); - $clientInfoYAxis += 5; - $this->SetXY($clientInfoXAxis,$clientInfoYAxis); - $this->MultiCell( 0, 5, trim(FileExportHelpers::FormatTextForExport($clientAddress))); - if($clientAdressIsMultiline){ - $clientInfoYAxis += 5; - } - $clientInfoYAxis += 5; - $this->SetXY($clientInfoXAxis,$clientInfoYAxis); - $this->Cell(0, 5, trim(FileExportHelpers::FormatTextForExport($this->factureData['client_adress_city']))); - } - public function DrawInvoiceInfoTable(){ - $this->setY(67); - $factureDatePaiement = $this->factureData['date_paiement']; - $factureDatePaiement = DateTime::createFromFormat('Y-m-d',$factureDatePaiement); - $factureDateEcheance = $factureDatePaiement; - $factureDatePaiement = $factureDatePaiement->format('d-m-Y'); - $factureDateEcheance->modify('last day of next month'); - $factureDateEcheance = $factureDateEcheance->format('d-m-Y'); - $this->SetFont('ComicSans', 'B', 11); - $this->Cell(30, 7, 'DATE', 1, 0, 'C'); - $this->Cell(94, 7, 'CLIENT', 1, 0, 'C'); - $this->Cell(40, 7, 'FACTURE', 1, 0, 'C'); - $this->Cell(40, 7, 'ECHEANCE', 1, 1, 'C'); - - $this->SetFont('ComicSans', '', 10); - $this->Cell(30, 7, $factureDatePaiement, 1, 0, 'C'); - $this->Cell(94, 7, utf8_decode(html_entity_decode($this->factureData['group_name'])), 1, 0, 'C'); - $this->Cell(40, 7, $this->factureData['num'], 1, 0, 'C'); - $this->Cell(40, 7, $factureDateEcheance, 1, 1, 'C'); - - $this->startingYOfArticlesTable = 85; - } - public function DrawArticlesTableValue(){ $this->SetFont('ComicSans','',10); $devisData = $this->factureData['devis']; @@ -145,12 +98,8 @@ class InvoiceFunecapPdfHandler extends InvoiceGroupPdfHandler { $this->currentIndexPosition = $currentIndexPosition; $this->initialIndexPosition = $this->currentIndexPosition; $chargedDevisCount = $this->currentIndexPosition + 1; - var_dump("CURRENT POSITION : ".$this->currentIndexPosition); - var_dump("CHARGED DEVIS COUNT : ".$chargedDevisCount); $devisLeftToGet = $this->devisCount - $chargedDevisCount; - var_dump("LEFT TO GET : ".$devisLeftToGet); $this->devisCountToGet = ($devisLeftToGet <= $this->maxArticlePerPage) ? $devisLeftToGet + 1 : $this->maxArticlePerPage; - var_dump("DEVIS COUNT TO GET : ".$this->devisCountToGet); } } diff --git a/gestion/lib/Service/InvoiceGroupPdfHandler/InvoiceGroupPdfHandler.php b/gestion/lib/Service/InvoiceGroupPdfHandler/InvoiceGroupPdfHandler.php index 36a6df1..b35d21c 100644 --- a/gestion/lib/Service/InvoiceGroupPdfHandler/InvoiceGroupPdfHandler.php +++ b/gestion/lib/Service/InvoiceGroupPdfHandler/InvoiceGroupPdfHandler.php @@ -66,7 +66,7 @@ class InvoiceGroupPdfHandler extends FPDF { function Footer() { $this->SetY(-35); - $this->SetFont('ComicSans', '', 7); + $this->SetFont('ComicSans', '', size: 7); $this->MultiCell(0,5,utf8_decode(html_entity_decode('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.'))); $this->Ln(1); $this->MultiCell(0,5,utf8_decode(html_entity_decode('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 ). @@ -146,12 +146,6 @@ class InvoiceGroupPdfHandler extends FPDF { $clientInfoYAxis += 5; $this->SetXY($clientInfoXAxis,$clientInfoYAxis); $this->Cell(0, 5, trim(FileExportHelpers::FormatTextForExport($this->factureData['client_adress_city']))); - $clientInfoYAxis += 5; - $this->SetXY($clientInfoXAxis,$clientInfoYAxis); - $this->Cell(0, 5, FileExportHelpers::FormatTextForExport('Numéro') . ' Siret: ' . $this->factureData['siret']); - $clientInfoYAxis += 5; - $this->SetXY($clientInfoXAxis,$clientInfoYAxis); - $this->Cell(0, 5, FileExportHelpers::FormatTextForExport('Mail : ') . $this->factureData['client_mail']); } public function DrawInvoiceCompanyAndClientInfo(){ @@ -169,17 +163,15 @@ class InvoiceGroupPdfHandler extends FPDF { $factureDateEcheance = $factureDateEcheance->format('d-m-Y'); $this->SetFont('ComicSans', 'B', 11); $this->Cell(30, 7, 'DATE', 1, 0, 'C'); - $this->Cell(60, 7, 'CLIENT', 1, 0, 'C'); + $this->Cell(94, 7, 'CLIENT', 1, 0, 'C'); $this->Cell(40, 7, 'FACTURE', 1, 0, 'C'); - $this->Cell(40, 7, 'ECHEANCE', 1, 0, 'C'); - $this->Cell(34, 7, 'COMMANDE', 1, 1, 'C'); + $this->Cell(40, 7, 'ECHEANCE', 1, 1, 'C'); $this->SetFont('ComicSans', '', 10); $this->Cell(30, 7, $factureDatePaiement, 1, 0, 'C'); - $this->Cell(60, 7, utf8_decode(html_entity_decode($this->factureData['group_name'])), 1, 0, 'C'); + $this->Cell(94, 7, utf8_decode(html_entity_decode($this->factureData['group_name'])), 1, 0, 'C'); $this->Cell(40, 7, $this->factureData['num'], 1, 0, 'C'); - $this->Cell(40, 7, $factureDateEcheance, 1, 0, 'C'); - $this->Cell(34, 7, $this->factureData["order_number"], 1, 1, 'C'); + $this->Cell(40, 7, $factureDateEcheance, 1, 1, 'C'); $this->startingYOfArticlesTable = 85; } diff --git a/gestion/lib/Service/InvoiceGroupPdfHandler/InvoiceOgfPdfHandler.php b/gestion/lib/Service/InvoiceGroupPdfHandler/InvoiceOgfPdfHandler.php new file mode 100644 index 0000000..c1c69e4 --- /dev/null +++ b/gestion/lib/Service/InvoiceGroupPdfHandler/InvoiceOgfPdfHandler.php @@ -0,0 +1,92 @@ + + * + * @author Anna Larch + * @author Richard Steinmetz + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see . + * + */ + +namespace OCA\Gestion\Service\InvoiceGroupPdfHandler; + +use DateTime; +use OCA\Gestion\Helpers\FileExportHelpers; +use OCA\Gestion\Helpers\PriceHelpers; + +class InvoiceOgfPdfHandler extends InvoiceGroupPdfHandler { + + public function DrawInvoiceClientInfo(){ + $this->SetFont('ComicSans', '', 10); + $clientName = $this->factureData['group_name']; + $clientInfoXAxis = 125; + + $clientAddress = $this->factureData['client_real_adress']; + $clientAdressWidth = $this->GetStringWidth($clientAddress); + $maxWidth = $this->GetPageWidth(); + $availableWidhtForClientInfo = $maxWidth - 10 - $clientInfoXAxis; + $clientAdressIsMultiline = $clientAdressWidth > $availableWidhtForClientInfo; + + $clientInfoYAxis = $clientAdressIsMultiline ? 35 : 40; + $this->SetXY($clientInfoXAxis,$clientInfoYAxis); + $this->Cell(0, 5, FileExportHelpers::FormatTextForExport($clientName)); + $clientInfoYAxis += 5; + $this->SetXY($clientInfoXAxis,$clientInfoYAxis); + $this->MultiCell( 0, 5, trim(FileExportHelpers::FormatTextForExport($clientAddress))); + if($clientAdressIsMultiline){ + $clientInfoYAxis += 5; + } + $clientInfoYAxis += 5; + $this->SetXY($clientInfoXAxis,$clientInfoYAxis); + $this->Cell(0, 5, trim(FileExportHelpers::FormatTextForExport($this->factureData['client_adress_city']))); + $clientInfoYAxis += 5; + $this->SetXY($clientInfoXAxis,$clientInfoYAxis); + $this->Cell(0, 5, FileExportHelpers::FormatTextForExport('Numéro') . ' Siret: ' . $this->factureData['siret']); + $clientInfoYAxis += 5; + $this->SetXY($clientInfoXAxis,$clientInfoYAxis); + $this->Cell(0, 5, FileExportHelpers::FormatTextForExport('Mail : ') . $this->factureData['client_mail']); + } + + public function DrawInvoiceInfoTable(){ + $this->setY(67); + $factureDatePaiement = $this->factureData['date_paiement']; + $factureDatePaiement = DateTime::createFromFormat('Y-m-d',$factureDatePaiement); + $factureDateEcheance = $factureDatePaiement; + $factureDatePaiement = $factureDatePaiement->format('d-m-Y'); + $factureDateEcheance->modify('last day of next month'); + $factureDateEcheance = $factureDateEcheance->format('d-m-Y'); + $this->SetFont('ComicSans', 'B', 11); + $this->Cell(30, 7, 'DATE', 1, 0, 'C'); + $this->Cell(60, 7, 'CLIENT', 1, 0, 'C'); + $this->Cell(40, 7, 'FACTURE', 1, 0, 'C'); + $this->Cell(40, 7, 'ECHEANCE', 1, 0, 'C'); + $this->Cell(34, 7, 'COMMANDE', 1, 1, 'C'); + + $this->SetFont('ComicSans', '', 10); + $this->Cell(30, 7, $factureDatePaiement, 1, 0, 'C'); + $this->Cell(60, 7, utf8_decode(html_entity_decode($this->factureData['group_name'])), 1, 0, 'C'); + $this->Cell(40, 7, $this->factureData['num'], 1, 0, 'C'); + $this->Cell(40, 7, $factureDateEcheance, 1, 0, 'C'); + $this->Cell(34, 7, $this->factureData["order_number"], 1, 1, 'C'); + + $this->startingYOfArticlesTable = 85; + } + + +} diff --git a/gestion/lib/Service/InvoicePdfService.php b/gestion/lib/Service/InvoicePdfService.php index f715957..2e9d84b 100644 --- a/gestion/lib/Service/InvoicePdfService.php +++ b/gestion/lib/Service/InvoicePdfService.php @@ -35,6 +35,7 @@ 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; @@ -161,11 +162,18 @@ class InvoicePdfService { $templateType = $invoicePdfData['template_type_key']; $clean_folder = html_entity_decode(string: $currentConfig->path).'/'; $factureFolders = $this->getGroupFactureFolder($invoicePdfData,$clean_folder); - if($templateType == ClientTemplateTypeConstant::FUNECAP){ - $pdf = new InvoiceFunecapPdfHandler(); - } - else{ - $pdf = new InvoiceGroupPdfHandler(); + switch ($templateType) { + case ClientTemplateTypeConstant::FUNECAP: + $pdf = new InvoiceFunecapPdfHandler(); + break; + + case ClientTemplateTypeConstant::OGF: + $pdf = new InvoiceOgfPdfHandler(); + break; + + default: + $pdf = new InvoiceGroupPdfHandler(); + break; } $pdf->AddFont('ComicSans','','Comic Sans MS.php'); $pdf->AddFont('ComicSans','B','comic-sans-bold.php'); From 4cbf598b125177fc71a6fb0d2b8b5c99e406e38a Mon Sep 17 00:00:00 2001 From: Tiavina Date: Sun, 2 Mar 2025 16:04:59 +0300 Subject: [PATCH 3/3] facture type --- gestion/appinfo/routes.php | 1 + gestion/js/apercusTousDevis.app.js | 2 +- gestion/js/apercusToutesFactures.app.js | 2 +- gestion/js/article.app.js | 2 +- gestion/js/bibliotheque.app.js | 2 +- gestion/js/client.app.js | 2 +- gestion/js/clientGroup.app.js | 2 +- gestion/js/clientGroupDiscount.app.js | 2 +- gestion/js/clientGroupFacturation.app.js | 2 +- gestion/js/configuration.app.js | 2 +- gestion/js/defunt.app.js | 2 +- gestion/js/defuntShow.app.js | 2 +- gestion/js/devis.app.js | 2 +- gestion/js/devisShow.app.js | 2 +- gestion/js/facture.app.js | 2 +- gestion/js/factureShow.app.js | 2 +- gestion/js/legalnotice.app.js | 2 +- gestion/js/lieu.app.js | 2 +- gestion/js/produit.app.js | 2 +- gestion/js/statistique.app.js | 2 +- gestion/js/thanatopracteur.app.js | 2 +- gestion/js/trajet.app.js | 2 +- gestion/js/trajetdetails.app.js | 2 +- gestion/lib/Controller/PageController.php | 9 + gestion/lib/Db/Bdd.php | 7 +- .../InvoiceGroupPdfHandler.php | 16 +- gestion/src/js/listener/main_listener.js | 3 + .../src/js/objects/clientGroupFacturation.mjs | 334 +++++++++++++----- .../content/clientGroupFacturation.php | 1 + 29 files changed, 289 insertions(+), 126 deletions(-) diff --git a/gestion/appinfo/routes.php b/gestion/appinfo/routes.php index e55254f..ee676a6 100644 --- a/gestion/appinfo/routes.php +++ b/gestion/appinfo/routes.php @@ -172,5 +172,6 @@ return [ //group of devis and facture ['name' => 'page#exportGroupOfDevisIntoFacture','url' => '/devis/exportGroupOfDevisIntoFacture', 'verb' => 'POST'], + ['name' => 'page#getClientTemplateTypes','url' => '/client/getClientTemplateTypes', 'verb' => 'PROPFIND'], ] ]; diff --git a/gestion/js/apercusTousDevis.app.js b/gestion/js/apercusTousDevis.app.js index 7dda299..11cfee4 100644 --- a/gestion/js/apercusTousDevis.app.js +++ b/gestion/js/apercusTousDevis.app.js @@ -1,2 +1,2 @@ /*! For license information please see apercusTousDevis.app.js.LICENSE.txt */ -(()=>{var n={2:(n,t,e)=>{var r=e(6926),a=e(9310);(n.exports=function(n,t){return a[n]||(a[n]=void 0!==t?t:{})})("versions",[]).push({version:"3.28.0",mode:r?"pure":"global",copyright:"© 2014-2023 Denis Pushkarev (zloirock.ru)",license:"https://github.com/zloirock/core-js/blob/v3.28.0/LICENSE",source:"https://github.com/zloirock/core-js"})},54:(n,t,e)=>{"use strict";var r,a,o=e(2368),i=e(281),l=e(5362),s=e(6844),d=e(2192),c=e(2),p=e(3105),u=e(9206).get,m=e(1036),f=e(8121),g=c("native-string-replace",String.prototype.replace),b=RegExp.prototype.exec,h=b,v=i("".charAt),x=i("".indexOf),y=i("".replace),w=i("".slice),T=(a=/b*/g,o(b,r=/a/,"a"),o(b,a,"a"),0!==r.lastIndex||0!==a.lastIndex),_=d.BROKEN_CARET,k=void 0!==/()??/.exec("")[1];(T||k||_||m||f)&&(h=function(n){var t,e,r,a,i,d,c,m=this,f=u(m),S=l(n),C=f.raw;if(C)return C.lastIndex=m.lastIndex,t=o(h,C,S),m.lastIndex=C.lastIndex,t;var D=f.groups,L=_&&m.sticky,A=o(s,m),E=m.source,j=0,F=S;if(L&&(A=y(A,"y",""),-1===x(A,"g")&&(A+="g"),F=w(S,m.lastIndex),m.lastIndex>0&&(!m.multiline||m.multiline&&"\n"!==v(S,m.lastIndex-1))&&(E="(?: "+E+")",F=" "+F,j++),e=new RegExp("^(?:"+E+")",A)),k&&(e=new RegExp("^"+E+"$(?!\\s)",A)),T&&(r=m.lastIndex),a=o(b,L?e:m,F),L?a?(a.input=w(a.input,j),a[0]=w(a[0],j),a.index=m.lastIndex,m.lastIndex+=a[0].length):m.lastIndex=0:T&&a&&(m.lastIndex=m.global?a.index+a[0].length:r),k&&a&&a.length>1&&o(g,a[0],e,(function(){for(i=1;i{"use strict";var r=e(9070),a=e(2368),o=e(281),i=e(779),l=e(2074),s=e(3938),d=e(8420),c=e(8406),p=e(9328),u=e(3747),m=e(5362),f=e(1229),g=e(7234),b=e(6457),h=e(4433),v=e(6793),x=e(1602)("replace"),y=Math.max,w=Math.min,T=o([].concat),_=o([].push),k=o("".indexOf),S=o("".slice),C="$0"==="a".replace(/./,"$0"),D=!!/./[x]&&""===/./[x]("a","$0");i("replace",(function(n,t,e){var o=D?"$":"$0";return[function(n,e){var r=f(this),o=c(n)?void 0:b(n,x);return o?a(o,n,r,e):a(t,m(r),n,e)},function(n,a){var i=s(this),l=m(n);if("string"==typeof a&&-1===k(a,o)&&-1===k(a,"$<")){var c=e(t,i,l,a);if(c.done)return c.value}var f=d(a);f||(a=m(a));var b=i.global;if(b){var x=i.unicode;i.lastIndex=0}for(var C=[];;){var D=v(i,l);if(null===D)break;if(_(C,D),!b)break;""===m(D[0])&&(i.lastIndex=g(l,u(i.lastIndex),x))}for(var L,A="",E=0,j=0;j=E&&(A+=S(l,E,N)+M,E=N+F.length)}return A+S(l,E)}]}),!!l((function(){var n=/./;return n.exec=function(){var n=[];return n.groups={a:"7"},n},"7"!=="".replace(n,"$")}))||!C||D)},200:(n,t,e)=>{var r=function(n){return n&&n.Math==Math&&n};n.exports=r("object"==typeof globalThis&&globalThis)||r("object"==typeof window&&window)||r("object"==typeof self&&self)||r("object"==typeof e.g&&e.g)||function(){return this}()||Function("return this")()},281:(n,t,e)=>{var r=e(8823),a=Function.prototype,o=a.call,i=r&&a.bind.bind(o,o);n.exports=r?i:function(n){return function(){return o.apply(n,arguments)}}},290:n=>{n.exports=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"]},353:(n,t,e)=>{var r=e(2368),a=e(6490),o=e(7658),i=e(6844),l=RegExp.prototype;n.exports=function(n){var t=n.flags;return void 0!==t||"flags"in l||a(n,"flags")||!o(l,n)?t:r(i,n)}},540:n=>{"use strict";n.exports=function(n){var t=document.createElement("style");return n.setAttributes(t,n.attributes),n.insert(t,n.options),t}},580:n=>{"use strict";var t=/["'&<>]/;n.exports=function(n){var e,r=""+n,a=t.exec(r);if(!a)return r;var o="",i=0,l=0;for(i=a.index;i{var r=e(281),a=0,o=Math.random(),i=r(1..toString);n.exports=function(n){return"Symbol("+(void 0===n?"":n)+")_"+i(++a+o,36)}},779:(n,t,e)=>{"use strict";e(7136);var r=e(3091),a=e(7485),o=e(54),i=e(2074),l=e(1602),s=e(7712),d=l("species"),c=RegExp.prototype;n.exports=function(n,t,e,p){var u=l(n),m=!i((function(){var t={};return t[u]=function(){return 7},7!=""[n](t)})),f=m&&!i((function(){var t=!1,e=/a/;return"split"===n&&((e={}).constructor={},e.constructor[d]=function(){return e},e.flags="",e[u]=/./[u]),e.exec=function(){return t=!0,null},e[u](""),!t}));if(!m||!f||e){var g=r(/./[u]),b=t(u,""[n],(function(n,t,e,a,i){var l=r(n),s=t.exec;return s===o||s===c.exec?m&&!i?{done:!0,value:g(t,e,a)}:{done:!0,value:l(e,t,a)}:{done:!1}}));a(String.prototype,n,b[0]),a(c,u,b[1])}p&&s(c[u],"sham",!0)}},874:(n,t,e)=>{var r=e(2368),a=e(5335),o=e(2328),i=e(6457),l=e(9751),s=e(1602),d=TypeError,c=s("toPrimitive");n.exports=function(n,t){if(!a(n)||o(n))return n;var e,s=i(n,c);if(s){if(void 0===t&&(t="default"),e=r(s,n,t),!a(e)||o(e))return e;throw d("Can't convert object to primitive value")}return void 0===t&&(t="number"),l(n,t)}},1036:(n,t,e)=>{var r=e(2074),a=e(200).RegExp;n.exports=r((function(){var n=a(".","s");return!(n.dotAll&&n.exec("\n")&&"s"===n.flags)}))},1113:n=>{"use strict";n.exports=function(n,t){if(t.styleSheet)t.styleSheet.cssText=n;else{for(;t.firstChild;)t.removeChild(t.firstChild);t.appendChild(document.createTextNode(n))}}},1144:n=>{"use strict";n.exports="data:image/svg+xml,%3csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 16 16%27 fill=%27%23fff%27%3e%3cpath d=%27M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z%27/%3e%3c/svg%3e"},1229:(n,t,e)=>{var r=e(8406),a=TypeError;n.exports=function(n){if(r(n))throw a("Can't call method on "+n);return n}},1479:n=>{"use strict";n.exports="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTYiIHdpZHRoPSIxNiI+CiAgPHBhdGggZD0iTTE0IDEyLjNMMTIuMyAxNCA4IDkuNyAzLjcgMTQgMiAxMi4zIDYuMyA4IDIgMy43IDMuNyAyIDggNi4zIDEyLjMgMiAxNCAzLjcgOS43IDh6IiBzdHlsZT0iZmlsbC1vcGFjaXR5OjE7ZmlsbDojZmZmZmZmIi8+Cjwvc3ZnPgo="},1601:n=>{"use strict";n.exports=function(n){return n[1]}},1602:(n,t,e)=>{var r=e(200),a=e(2),o=e(6490),i=e(665),l=e(2072),s=e(5225),d=r.Symbol,c=a("wks"),p=s?d.for||d:d&&d.withoutSetter||i;n.exports=function(n){return o(c,n)||(c[n]=l&&o(d,n)?d[n]:p("Symbol."+n)),c[n]}},1605:(n,t,e)=>{var r=e(200),a=e(7632).f,o=e(7712),i=e(7485),l=e(9430),s=e(4361),d=e(4977);n.exports=function(n,t){var e,c,p,u,m,f=n.target,g=n.global,b=n.stat;if(e=g?r:b?r[f]||l(f,{}):(r[f]||{}).prototype)for(c in t){if(u=t[c],p=n.dontCallGetSet?(m=a(e,c))&&m.value:e[c],!d(g?c:f+(b?".":"#")+c,n.forced)&&void 0!==p){if(typeof u==typeof p)continue;s(u,p)}(n.sham||p&&p.sham)&&o(u,"sham",!0),i(e,c,u,n)}}},1641:(n,t,e)=>{var r=e(6347),a=e(290);n.exports=Object.keys||function(n){return r(n,a)}},1688:(n,t,e)=>{"use strict";var r=e(5077),a=e(281),o=e(2368),i=e(2074),l=e(1641),s=e(8916),d=e(9304),c=e(2612),p=e(8664),u=Object.assign,m=Object.defineProperty,f=a([].concat);n.exports=!u||i((function(){if(r&&1!==u({b:1},u(m({},"a",{enumerable:!0,get:function(){m(this,"b",{value:3,enumerable:!1})}}),{b:2})).b)return!0;var n={},t={},e=Symbol(),a="abcdefghijklmnopqrst";return n[e]=7,a.split("").forEach((function(n){t[n]=n})),7!=u({},n)[e]||l(u({},t)).join("")!=a}))?function(n,t){for(var e=c(n),a=arguments.length,i=1,u=s.f,m=d.f;a>i;)for(var g,b=p(arguments[i++]),h=u?f(l(b),u(b)):l(b),v=h.length,x=0;v>x;)g=h[x++],r&&!o(m,b,g)||(e[g]=b[g]);return e}:u},2071:(n,t,e)=>{var r=e(5077),a=e(6490),o=Function.prototype,i=r&&Object.getOwnPropertyDescriptor,l=a(o,"name"),s=l&&"something"===function(){}.name,d=l&&(!r||r&&i(o,"name").configurable);n.exports={EXISTS:l,PROPER:s,CONFIGURABLE:d}},2072:(n,t,e)=>{var r=e(6845),a=e(2074);n.exports=!!Object.getOwnPropertySymbols&&!a((function(){var n=Symbol();return!String(n)||!(Object(n)instanceof Symbol)||!Symbol.sham&&r&&r<41}))},2074:n=>{n.exports=function(n){try{return!!n()}catch(n){return!0}}},2192:(n,t,e)=>{var r=e(2074),a=e(200).RegExp,o=r((function(){var n=a("a","y");return n.lastIndex=2,null!=n.exec("abcd")})),i=o||r((function(){return!a("a","y").sticky})),l=o||r((function(){var n=a("^r","gy");return n.lastIndex=2,null!=n.exec("str")}));n.exports={BROKEN_CARET:l,MISSED_STICKY:i,UNSUPPORTED_Y:o}},2328:(n,t,e)=>{var r=e(6492),a=e(8420),o=e(7658),i=e(5225),l=Object;n.exports=i?function(n){return"symbol"==typeof n}:function(n){var t=r("Symbol");return a(t)&&o(t.prototype,l(n))}},2349:(n,t,e)=>{"use strict";var r=e(2074);n.exports=function(n,t){var e=[][n];return!!e&&r((function(){e.call(null,t||function(){return 1},1)}))}},2368:(n,t,e)=>{var r=e(8823),a=Function.prototype.call;n.exports=r?a.bind(a):function(){return a.apply(a,arguments)}},2612:(n,t,e)=>{var r=e(1229),a=Object;n.exports=function(n){return a(r(n))}},2838:function(n){n.exports=function(){"use strict";function n(t){return n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(n){return typeof n}:function(n){return n&&"function"==typeof Symbol&&n.constructor===Symbol&&n!==Symbol.prototype?"symbol":typeof n},n(t)}function t(n,e){return t=Object.setPrototypeOf||function(n,t){return n.__proto__=t,n},t(n,e)}function e(n,r,a){return e=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(n){return!1}}()?Reflect.construct:function(n,e,r){var a=[null];a.push.apply(a,e);var o=new(Function.bind.apply(n,a));return r&&t(o,r.prototype),o},e.apply(null,arguments)}function r(n){return function(n){if(Array.isArray(n))return a(n)}(n)||function(n){if("undefined"!=typeof Symbol&&null!=n[Symbol.iterator]||null!=n["@@iterator"])return Array.from(n)}(n)||function(n,t){if(n){if("string"==typeof n)return a(n,t);var e=Object.prototype.toString.call(n).slice(8,-1);return"Object"===e&&n.constructor&&(e=n.constructor.name),"Map"===e||"Set"===e?Array.from(n):"Arguments"===e||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(e)?a(n,t):void 0}}(n)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function a(n,t){(null==t||t>n.length)&&(t=n.length);for(var e=0,r=new Array(t);e1?e-1:0),a=1;a/gm),G=p(/\${[\w\W]*}/gm),W=p(/^data-[\-\w.\u00B7-\uFFFF]/),J=p(/^aria-[\-\w]+$/),X=p(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),V=p(/^(?:\w+script|data):/i),Y=p(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),K=p(/^html$/i),Z=function(){return"undefined"==typeof window?null:window};return function t(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:Z(),a=function(n){return t(n)};if(a.version="2.4.4",a.removed=[],!e||!e.document||9!==e.document.nodeType)return a.isSupported=!1,a;var o=e.document,i=e.document,l=e.DocumentFragment,s=e.HTMLTemplateElement,d=e.Node,p=e.Element,u=e.NodeFilter,m=e.NamedNodeMap,f=void 0===m?e.NamedNodeMap||e.MozNamedAttrMap:m,g=e.HTMLFormElement,b=e.DOMParser,L=e.trustedTypes,Q=p.prototype,nn=j(Q,"cloneNode"),tn=j(Q,"nextSibling"),en=j(Q,"childNodes"),rn=j(Q,"parentNode");if("function"==typeof s){var an=i.createElement("template");an.content&&an.content.ownerDocument&&(i=an.content.ownerDocument)}var on=function(t,e){if("object"!==n(t)||"function"!=typeof t.createPolicy)return null;var r=null,a="data-tt-policy-suffix";e.currentScript&&e.currentScript.hasAttribute(a)&&(r=e.currentScript.getAttribute(a));var o="dompurify"+(r?"#"+r:"");try{return t.createPolicy(o,{createHTML:function(n){return n},createScriptURL:function(n){return n}})}catch(n){return console.warn("TrustedTypes policy "+o+" could not be created."),null}}(L,o),ln=on?on.createHTML(""):"",sn=i,dn=sn.implementation,cn=sn.createNodeIterator,pn=sn.createDocumentFragment,un=sn.getElementsByTagName,mn=o.importNode,fn={};try{fn=E(i).documentMode?i.documentMode:{}}catch(n){}var gn={};a.isSupported="function"==typeof rn&&dn&&void 0!==dn.createHTMLDocument&&9!==fn;var bn,hn,vn=q,xn=B,yn=G,wn=W,Tn=J,_n=V,kn=Y,Sn=X,Cn=null,Dn=A({},[].concat(r(F),r(N),r(O),r(I),r(M))),Ln=null,An=A({},[].concat(r(z),r(H),r(U),r($))),En=Object.seal(Object.create(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),jn=null,Fn=null,Nn=!0,On=!0,Pn=!1,In=!0,Rn=!1,Mn=!1,zn=!1,Hn=!1,Un=!1,$n=!1,qn=!1,Bn=!0,Gn=!1,Wn=!0,Jn=!1,Xn={},Vn=null,Yn=A({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","style","svg","template","thead","title","video","xmp"]),Kn=null,Zn=A({},["audio","video","img","source","image","track"]),Qn=null,nt=A({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),tt="http://www.w3.org/1998/Math/MathML",et="http://www.w3.org/2000/svg",rt="http://www.w3.org/1999/xhtml",at=rt,ot=!1,it=null,lt=A({},[tt,et,rt],w),st=["application/xhtml+xml","text/html"],dt=null,ct=i.createElement("form"),pt=function(n){return n instanceof RegExp||n instanceof Function},ut=function(t){dt&&dt===t||(t&&"object"===n(t)||(t={}),t=E(t),bn=bn=-1===st.indexOf(t.PARSER_MEDIA_TYPE)?"text/html":t.PARSER_MEDIA_TYPE,hn="application/xhtml+xml"===bn?w:y,Cn="ALLOWED_TAGS"in t?A({},t.ALLOWED_TAGS,hn):Dn,Ln="ALLOWED_ATTR"in t?A({},t.ALLOWED_ATTR,hn):An,it="ALLOWED_NAMESPACES"in t?A({},t.ALLOWED_NAMESPACES,w):lt,Qn="ADD_URI_SAFE_ATTR"in t?A(E(nt),t.ADD_URI_SAFE_ATTR,hn):nt,Kn="ADD_DATA_URI_TAGS"in t?A(E(Zn),t.ADD_DATA_URI_TAGS,hn):Zn,Vn="FORBID_CONTENTS"in t?A({},t.FORBID_CONTENTS,hn):Yn,jn="FORBID_TAGS"in t?A({},t.FORBID_TAGS,hn):{},Fn="FORBID_ATTR"in t?A({},t.FORBID_ATTR,hn):{},Xn="USE_PROFILES"in t&&t.USE_PROFILES,Nn=!1!==t.ALLOW_ARIA_ATTR,On=!1!==t.ALLOW_DATA_ATTR,Pn=t.ALLOW_UNKNOWN_PROTOCOLS||!1,In=!1!==t.ALLOW_SELF_CLOSE_IN_ATTR,Rn=t.SAFE_FOR_TEMPLATES||!1,Mn=t.WHOLE_DOCUMENT||!1,Un=t.RETURN_DOM||!1,$n=t.RETURN_DOM_FRAGMENT||!1,qn=t.RETURN_TRUSTED_TYPE||!1,Hn=t.FORCE_BODY||!1,Bn=!1!==t.SANITIZE_DOM,Gn=t.SANITIZE_NAMED_PROPS||!1,Wn=!1!==t.KEEP_CONTENT,Jn=t.IN_PLACE||!1,Sn=t.ALLOWED_URI_REGEXP||Sn,at=t.NAMESPACE||rt,t.CUSTOM_ELEMENT_HANDLING&&pt(t.CUSTOM_ELEMENT_HANDLING.tagNameCheck)&&(En.tagNameCheck=t.CUSTOM_ELEMENT_HANDLING.tagNameCheck),t.CUSTOM_ELEMENT_HANDLING&&pt(t.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)&&(En.attributeNameCheck=t.CUSTOM_ELEMENT_HANDLING.attributeNameCheck),t.CUSTOM_ELEMENT_HANDLING&&"boolean"==typeof t.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements&&(En.allowCustomizedBuiltInElements=t.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements),Rn&&(On=!1),$n&&(Un=!0),Xn&&(Cn=A({},r(M)),Ln=[],!0===Xn.html&&(A(Cn,F),A(Ln,z)),!0===Xn.svg&&(A(Cn,N),A(Ln,H),A(Ln,$)),!0===Xn.svgFilters&&(A(Cn,O),A(Ln,H),A(Ln,$)),!0===Xn.mathMl&&(A(Cn,I),A(Ln,U),A(Ln,$))),t.ADD_TAGS&&(Cn===Dn&&(Cn=E(Cn)),A(Cn,t.ADD_TAGS,hn)),t.ADD_ATTR&&(Ln===An&&(Ln=E(Ln)),A(Ln,t.ADD_ATTR,hn)),t.ADD_URI_SAFE_ATTR&&A(Qn,t.ADD_URI_SAFE_ATTR,hn),t.FORBID_CONTENTS&&(Vn===Yn&&(Vn=E(Vn)),A(Vn,t.FORBID_CONTENTS,hn)),Wn&&(Cn["#text"]=!0),Mn&&A(Cn,["html","head","body"]),Cn.table&&(A(Cn,["tbody"]),delete jn.tbody),c&&c(t),dt=t)},mt=A({},["mi","mo","mn","ms","mtext"]),ft=A({},["foreignobject","desc","title","annotation-xml"]),gt=A({},["title","style","font","a","script"]),bt=A({},N);A(bt,O),A(bt,P);var ht=A({},I);A(ht,R);var vt=function(n){x(a.removed,{element:n});try{n.parentNode.removeChild(n)}catch(t){try{n.outerHTML=ln}catch(t){n.remove()}}},xt=function(n,t){try{x(a.removed,{attribute:t.getAttributeNode(n),from:t})}catch(n){x(a.removed,{attribute:null,from:t})}if(t.removeAttribute(n),"is"===n&&!Ln[n])if(Un||$n)try{vt(t)}catch(n){}else try{t.setAttribute(n,"")}catch(n){}},yt=function(n){var t,e;if(Hn)n=""+n;else{var r=T(n,/^[\r\n\t ]+/);e=r&&r[0]}"application/xhtml+xml"===bn&&at===rt&&(n=''+n+"");var a=on?on.createHTML(n):n;if(at===rt)try{t=(new b).parseFromString(a,bn)}catch(n){}if(!t||!t.documentElement){t=dn.createDocument(at,"template",null);try{t.documentElement.innerHTML=ot?ln:a}catch(n){}}var o=t.body||t.documentElement;return n&&e&&o.insertBefore(i.createTextNode(e),o.childNodes[0]||null),at===rt?un.call(t,Mn?"html":"body")[0]:Mn?t.documentElement:o},wt=function(n){return cn.call(n.ownerDocument||n,n,u.SHOW_ELEMENT|u.SHOW_COMMENT|u.SHOW_TEXT,null,!1)},Tt=function(t){return"object"===n(d)?t instanceof d:t&&"object"===n(t)&&"number"==typeof t.nodeType&&"string"==typeof t.nodeName},_t=function(n,t,e){gn[n]&&h(gn[n],(function(n){n.call(a,t,e,dt)}))},kt=function(n){var t,e;if(_t("beforeSanitizeElements",n,null),(e=n)instanceof g&&("string"!=typeof e.nodeName||"string"!=typeof e.textContent||"function"!=typeof e.removeChild||!(e.attributes instanceof f)||"function"!=typeof e.removeAttribute||"function"!=typeof e.setAttribute||"string"!=typeof e.namespaceURI||"function"!=typeof e.insertBefore||"function"!=typeof e.hasChildNodes))return vt(n),!0;if(C(/[\u0080-\uFFFF]/,n.nodeName))return vt(n),!0;var r=hn(n.nodeName);if(_t("uponSanitizeElement",n,{tagName:r,allowedTags:Cn}),n.hasChildNodes()&&!Tt(n.firstElementChild)&&(!Tt(n.content)||!Tt(n.content.firstElementChild))&&C(/<[/\w]/g,n.innerHTML)&&C(/<[/\w]/g,n.textContent))return vt(n),!0;if("select"===r&&C(/