From 2726be3c5ae657694f7b3e2f6d8cab362374bd93 Mon Sep 17 00:00:00 2001 From: Tiavina Date: Fri, 17 Jan 2025 13:23:42 +0300 Subject: [PATCH] export devis and facture in backend , wip frontend part for H2F --- gestion/appinfo/routes.php | 9 + gestion/lib/Controller/PageController.php | 84 ++++- gestion/lib/Db/Bdd.php | 235 ++++++++++++- gestion/lib/Helpers/DateHelpers.php | 18 + gestion/lib/Helpers/FileExportHelpers.php | 4 +- .../lib/Service/Devis/Pdf/DevisPdfHandler.php | 294 ++++++++++++++++ .../lib/Service/Devis/Pdf/DevisPdfService.php | 190 ++++++++++ gestion/lib/Service/InvoicePdfHandler.php | 326 ++++++++++++++++++ gestion/lib/Service/InvoicePdfService.php | 148 ++++++++ 9 files changed, 1304 insertions(+), 4 deletions(-) create mode 100644 gestion/lib/Service/Devis/Pdf/DevisPdfHandler.php create mode 100644 gestion/lib/Service/Devis/Pdf/DevisPdfService.php create mode 100644 gestion/lib/Service/InvoicePdfHandler.php create mode 100644 gestion/lib/Service/InvoicePdfService.php diff --git a/gestion/appinfo/routes.php b/gestion/appinfo/routes.php index 76d3822..e42eafc 100644 --- a/gestion/appinfo/routes.php +++ b/gestion/appinfo/routes.php @@ -126,5 +126,14 @@ return [ //SQL ['name' => 'page#addDevisNumberColumn', 'url' => '/addDevisNumberColumn', 'verb' => 'POST'], ['name' => 'page#addFactureNumberColumn', 'url' => '/addFactureNumberColumn', 'verb' => 'POST'], + + //facture pdf + + ['name' => 'page#exportFactureToPdf', 'url' => '/facture/exportFactureToPdf', 'verb' => 'POST'], + ['name' => 'page#exportFactureByClientAndMonthYearToPdf', 'url' => '/facture/exportFactureByClientAndMonthYearToPdf', 'verb' => 'POST'], + + //devis pdf + ['name' => 'page#exportDevisToPdf', 'url' => '/devis/exportDevisToPdf', 'verb' => 'POST'], + ['name' => 'page#exportDevisByClientAndMonthYearToPdf', 'url' => '/devis/exportDevisByClientAndMonthYearToPdf', 'verb' => 'POST'], ] ]; \ No newline at end of file diff --git a/gestion/lib/Controller/PageController.php b/gestion/lib/Controller/PageController.php index 7a38eef..8d8d8b3 100644 --- a/gestion/lib/Controller/PageController.php +++ b/gestion/lib/Controller/PageController.php @@ -17,8 +17,10 @@ use \Datetime; use \DatetimeImmutable; use \IntlDateFormatter; use \FPDF; +use OCA\Gestion\Service\Devis\Pdf\DevisPdfService; use OCA\Gestion\Service\ExportClientStatisticService; use OCA\Gestion\Service\ExportThanatoStatisticService; +use OCA\Gestion\Service\InvoicePdfService; date_default_timezone_set('Europe/Paris'); @@ -43,6 +45,12 @@ class PageController extends Controller { /** @var ExportClientStatisticService */ private $exportClientStatisticService; + /** @var InvoicePdfService */ + private $invoicePdfService; + + /** @var DevisPdfService */ + private $devisPdfService; + /** * Constructor */ @@ -57,7 +65,9 @@ class PageController extends Controller { IUserSession $userSession, IGroupManager $groupManager, ExportThanatoStatisticService $exportThanatoStatisticService, - ExportClientStatisticService $exportClientStatisticService,){ + ExportClientStatisticService $exportClientStatisticService, + InvoicePdfService $invoicePdfService, + DevisPdfService $devisPdfService){ parent::__construct($AppName, $request); @@ -68,6 +78,8 @@ class PageController extends Controller { $this->config = $config; $this->exportThanatoStatisticService = $exportThanatoStatisticService; $this->exportClientStatisticService = $exportClientStatisticService; + $this->invoicePdfService = $invoicePdfService; + $this->devisPdfService = $devisPdfService; //$this->fpdf = $fpdf; if ($userSession->isLoggedIn()) { @@ -2650,4 +2662,74 @@ class PageController extends Controller { catch(\OCP\Files\NotFoundException $e) { } } + + /** + * @NoAdminRequired + * @NoCSRFRequired + * @param int $factureId + * + */ + + public function exportFactureToPdf($factureId){ + try{ + //for HYTHA 35 , the default admin idnextcloud is Johann, for H2F it is Emmanuelle + // $this->idNextcloud = self::HYTHA_35_DEFAULT_ADMIN; + $factureFilenames = $this->invoicePdfService->generateFacturePdfByFactureId($factureId,$this->idNextcloud); + return json_encode($factureFilenames); + } + catch(\OCP\Files\NotFoundException $e) { } + + } + + /** + * @NoAdminRequired + * @NoCSRFRequired + * @param string $clientId + * @param string $month + * @param string $year + * + */ + + public function exportFactureByClientAndMonthYearToPdf($clientId,$month,$year){ + try{ + $factureFilename = $this->invoicePdfService->generateMultipleInvoicePdfByClientAndMonthYear($clientId,$month,$year,$this->idNextcloud); + return $factureFilename; + } + catch(\OCP\Files\NotFoundException $e) { } + + } + + /** + * @NoAdminRequired + * @NoCSRFRequired + * @param int $devisId + * + */ + + public function exportDevisToPdf($devisId){ + try{ + $devisFilenames = $this->devisPdfService->generateDevisPdfByDevisId($devisId,$this->idNextcloud); + return json_encode($devisFilenames); + } + catch(\OCP\Files\NotFoundException $e) { } + + } + + /** + * @NoAdminRequired + * @NoCSRFRequired + * @param string $clientId + * @param string $month + * @param string $year + * + */ + + public function exportDevisByClientAndMonthYearToPdf($clientId,$month,$year){ + try{ + $devisFilename = $this->devisPdfService->generateMultipleDevisPdfByClientAndMonthYear($clientId,$month,$year,$this->idNextcloud); + return $devisFilename; + } + catch(\OCP\Files\NotFoundException $e) { } + + } } diff --git a/gestion/lib/Db/Bdd.php b/gestion/lib/Db/Bdd.php index 46efe7e..9b5c4c2 100644 --- a/gestion/lib/Db/Bdd.php +++ b/gestion/lib/Db/Bdd.php @@ -6,6 +6,7 @@ use OCA\Gestion\Helpers\VCalendarHelpers; use OCP\IDBConnection; use OCP\IL10N; use \Datetime; +use OCA\Gestion\Helpers\FileExportHelpers; class Bdd { private String $charset = 'utf8mb4'; @@ -1976,7 +1977,7 @@ class Bdd { return $devis; } - private function setDevisStartAndEndTime($devis){ + public function setDevisStartAndEndTime($devis){ $calendarData = $this->getCalendarDataByCalendarObjectUuid($devis["calendar_uuid"]); $devisTimeValue = VCalendarHelpers::GetStartAndEndTimeFromVCalendarString($calendarData); $devis["startTime"] = $devisTimeValue["startTime"]; @@ -2145,4 +2146,236 @@ class Bdd { return true; } + private function getFactureByIdWithDevis($factureId){ + $sql = "SELECT + facture.id, + facture.date, + facture.date_paiement, + facture.num, + devis.id as devis_id, + devis.date as devis_date, + devis.num as calendar_uuid, + devis.comment as devis_comment, + client.nom as client_nom, + client.entreprise as client_entreprise, + client.adresse as client_adresse, + defunt.nom as defunt_nom, + defunt.sexe as defunt_sexe, + lieu.nom as lieu_nom, + lieu.adresse as lieu_adresse, + thanato.nom as thanato_nom, + thanato.prenom as thanato_prenom + FROM ".$this->tableprefix."facture as facture + LEFT JOIN ".$this->tableprefix."devis as devis on facture.id_devis = devis.id + 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 + LEFT JOIN ".$this->tableprefix."lieu as lieu on devis.id_lieu = lieu.id + LEFT JOIN ".$this->tableprefix."thanato as thanato on devis.id_thanato = thanato.id + WHERE facture.id = ? + ;"; + $facture = $this->execSQLNoJsonReturn( + $sql, + [$factureId]); + if(!empty($facture)){ + return $facture[0]; + } + return null; + } + + public function getDevisProduits($devisId){ + $sql = "SELECT + produit_devis.id, + produit_devis.produit_id, + produit_devis.quantite, + produit_devis.discount, + produit_devis.devis_id, + produit.prix_unitaire as produit_price, + produit.reference as produit_reference, + produit.description as produit_description, + produit.vat as produit_vat, + devis.id_client as devis_client_id + FROM ".$this->tableprefix ."produit_devis as produit_devis + LEFT JOIN ".$this->tableprefix."produit as produit on produit_devis.produit_id = produit.id + LEFT JOIN ".$this->tableprefix."devis as devis on produit_devis.devis_id = devis.id + WHERE produit_devis.devis_id = ?;"; + + $produitList = $this->execSQLNoJsonReturn( + $sql, + [$devisId]); + + return $produitList; + } + + public function getFirstClient(){ + $sql = "SELECT * FROM ".$this->tableprefix."client as client LIMIT 1;"; + $client = $this->execSQLNoJsonReturn( + $sql, + []); + + if(!empty($client)){ + return $client[0]; + } + + return null; + } + + public function getInvoicePdfData($factureId,$configuration){ + $factureData = $this->getFactureByIdWithDevis($factureId); + if($factureData == null){ + return null; + } + $products = $this->getDevisProduits($factureData["devis_id"]); + $factureData = $this->setDevisStartAndEndTime($factureData); + + $firstClient = $this->getFirstClient(); + $factureData["siret"] = $firstClient != null ? $firstClient['legal_one'] : ''; + $factureData["products"] = $products; + $factureData["configuration"] = $configuration; + + $clientAdresses = FileExportHelpers::GetAddressAndCityFromAddress($factureData["client_adresse"]); + $factureData["client_real_adress"] = $clientAdresses["address"]; + $factureData["client_adress_city"] = $clientAdresses["city"]; + + $configurationAdresses = FileExportHelpers::GetAddressAndCityFromAddress($configuration->adresse); + $factureData["configuration_adresse"] = $configurationAdresses["address"]; + $factureData["configuration_adresse_city"] = $configurationAdresses["city"]; + return $factureData; + } + + private function getInvoiceByClientAndMonthYear($clientId,$month,$year){ + $sql = "SELECT + facture.id, + facture.date, + facture.date_paiement, + facture.num, + devis.id as devis_id, + devis.date as devis_date, + devis.num as calendar_uuid, + devis.comment as devis_comment, + devis.id_client as devis_id_client, + client.nom as client_nom, + client.entreprise as client_entreprise, + client.adresse as client_adresse, + defunt.nom as defunt_nom, + defunt.sexe as defunt_sexe, + lieu.nom as lieu_nom, + lieu.adresse as lieu_adresse, + thanato.nom as thanato_nom, + thanato.prenom as thanato_prenom + FROM ".$this->tableprefix."facture as facture + LEFT JOIN ".$this->tableprefix."devis as devis on facture.id_devis = devis.id + 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 + LEFT JOIN ".$this->tableprefix."lieu as lieu on devis.id_lieu = lieu.id + LEFT JOIN ".$this->tableprefix."thanato as thanato on devis.id_thanato = thanato.id + WHERE devis.id_client = ? AND + YEAR(facture.date_paiement) = ?"; + + $conditions = [$clientId,$year]; + if($month != 0){ + $conditions[] = $month; + $sql .= " AND MONTH(facture.date_paiement) = ?"; + } + $sql .= ";"; + $factures = $this->execSQLNoJsonReturn( + $sql, + $conditions); + + return $factures; + } + + public function getInvoicePdfDataByClientAndMonthYear($clientId,$month,$year,$configuration){ + $invoices = $this->getInvoiceByClientAndMonthYear($clientId,$month,$year); + $firstClient = $this->getFirstClient(); + foreach($invoices as &$invoice){ + $invoice["siret"] = $firstClient != null ? $firstClient['legal_one'] : ''; + $products = $this->getDevisProduits($invoice["devis_id"]); + $invoice["products"] = $products; + $invoice["configuration"] = $configuration; + + $clientAdresses = FileExportHelpers::GetAddressAndCityFromAddress($invoice["client_adresse"]); + $invoice["client_real_adress"] = $clientAdresses["address"]; + $invoice["client_adress_city"] = $clientAdresses["city"]; + + $configurationAdresses = FileExportHelpers::GetAddressAndCityFromAddress($configuration->adresse); + $invoice["configuration_adresse"] = $configurationAdresses["address"]; + $invoice["configuration_adresse_city"] = $configurationAdresses["city"]; + } + return $invoices; + } + public function getDevisPdfDataByDevisId($devisId){ + $sql = "SELECT + devis.id as devis_id, + devis.date as devis_date, + devis.num as calendar_uuid, + devis.devis_full_number as devis_full_number, + devis.comment as devis_comment, + client.nom as client_nom, + client.entreprise as client_entreprise, + client.adresse as client_adresse, + defunt.nom as defunt_nom, + defunt.sexe as defunt_sexe, + lieu.nom as lieu_nom, + lieu.adresse as lieu_adresse, + thanato.nom as thanato_nom, + thanato.prenom as thanato_prenom + 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 + LEFT JOIN ".$this->tableprefix."lieu as lieu on devis.id_lieu = lieu.id + LEFT JOIN ".$this->tableprefix."thanato as thanato on devis.id_thanato = thanato.id + WHERE devis.id = ? + ;"; + $devis = $this->execSQLNoJsonReturn( + $sql, + [$devisId]); + if(!empty($devis)){ + return $devis[0]; + } + return null; + } + + private function getDevisByClientAndMonthYear($clientId,$month,$year){ + $sql = "SELECT + devis.id as devis_id, + devis.date as devis_date, + devis.num as calendar_uuid, + devis.comment as devis_comment, + devis.id_client as devis_id_client, + devis.devis_full_number as devis_full_number, + client.nom as client_nom, + client.entreprise as client_entreprise, + client.adresse as client_adresse, + defunt.nom as defunt_nom, + defunt.sexe as defunt_sexe, + lieu.nom as lieu_nom, + lieu.adresse as lieu_adresse, + thanato.nom as thanato_nom, + thanato.prenom as thanato_prenom + 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 + LEFT JOIN ".$this->tableprefix."lieu as lieu on devis.id_lieu = lieu.id + LEFT JOIN ".$this->tableprefix."thanato as thanato on devis.id_thanato = thanato.id + WHERE devis.id_client = ? AND + YEAR(devis.date) = ?"; + + $conditions = [$clientId,$year]; + if($month != 0){ + $conditions[] = $month; + $sql .= " AND MONTH(devis.date) = ?"; + } + $sql .= ";"; + $devisList = $this->execSQLNoJsonReturn( + $sql, + $conditions); + + return $devisList; + } + + public function getDevisPdfDataByClientAndMonthYear($clientId,$month,$year,$configuration){ + $devisList = $this->getDevisByClientAndMonthYear($clientId,$month,$year); + return $devisList; + } + } diff --git a/gestion/lib/Helpers/DateHelpers.php b/gestion/lib/Helpers/DateHelpers.php index 1a9f379..19961a7 100644 --- a/gestion/lib/Helpers/DateHelpers.php +++ b/gestion/lib/Helpers/DateHelpers.php @@ -5,6 +5,7 @@ namespace OCA\Gestion\Helpers; use DateTime; use DateTimeZone; use Exception; +use IntlDateFormatter; class DateHelpers { @@ -20,6 +21,23 @@ class DateHelpers } } + public static function GetMonthPlainString($month){ + $formatter = new IntlDateFormatter( + 'fr_FR', + IntlDateFormatter::FULL, + IntlDateFormatter::NONE, + null, + null, + 'MMMM' + ); + + $date = DateTime::createFromFormat('!m', $month); + $monthString = strtoupper($formatter->format($date)); + $normalizedMonth = mb_convert_case($monthString, MB_CASE_UPPER, "UTF-8"); + + return $normalizedMonth; + } + public static function GetDateWithFormatDayAndMonthPlainString(string $date){ $dateTime = new DateTime($date); $formattedDate = $dateTime->format('d F'); diff --git a/gestion/lib/Helpers/FileExportHelpers.php b/gestion/lib/Helpers/FileExportHelpers.php index 4cafb52..7a81732 100644 --- a/gestion/lib/Helpers/FileExportHelpers.php +++ b/gestion/lib/Helpers/FileExportHelpers.php @@ -12,8 +12,8 @@ class FileExportHelpers } public static function GetAddressAndCityFromAddress(string $adresse){ - $adresseResult = ""; - $cityResult = ""; + $adresseResult = "Aucun adresse"; + $cityResult = "Aucune ville"; $adresses = explode("-",$adresse); if(isset($adresses[0])){ $adresseResult = self::RemoveSpaceFromString($adresses[0]); diff --git a/gestion/lib/Service/Devis/Pdf/DevisPdfHandler.php b/gestion/lib/Service/Devis/Pdf/DevisPdfHandler.php new file mode 100644 index 0000000..89045f0 --- /dev/null +++ b/gestion/lib/Service/Devis/Pdf/DevisPdfHandler.php @@ -0,0 +1,294 @@ + + * + * @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\Devis\Pdf; + +use DateTime; +use \FPDF; +use OCA\Gestion\Helpers\FileExportHelpers; +use OCA\Gestion\Helpers\PriceHelpers; + +class DevisPdfHandler extends FPDF { + + private $multipleDevisData = []; + private $devisData = []; + private $logo = null; + private $logoPath = "/var/www/html/data/admin/files/.gestion/"; + function Header() + { + if($this->logo != "nothing"){ + $this->Image($this->logoPath."logo.png", 10, 10, 75, 25); + } + else{ + $this->Cell(55,30,''); + } + } + function Footer() + { + $this->SetY(-40); + $this->SetFont('Arial', '', 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 ). +'))); + + $this->SetY(-15); + $this->SetFont('Arial', 'B', 8); + $this->Cell(0, 10, utf8_decode(html_entity_decode($this->devisData['configuration']->legal_one)), 0, 0, 'C'); + } + + public function SetDevisPdfData(array $devisData,$logo = null){ + $this->devisData = $devisData; + $this->logo = $logo; + } + + public function SetMultipleDevisPdfData(array $multipleDevisData,$logo = null){ + $this->multipleDevisData = $multipleDevisData; + $this->logo = $logo; + } + + private function DrawDevisCompanyAndClientInfo(){ + $this->SetY(40); + $this->SetFont('Arial', '', 12); + $this->Cell(0, 7, FileExportHelpers::FormatTextForExport($this->devisData['configuration']->entreprise), 0, 0); + $this->Cell(0, 7, FileExportHelpers::FormatTextForExport($this->devisData['client_nom']), 0, 1,'R'); + $this->Cell(0, 7, FileExportHelpers::FormatTextForExport($this->devisData['configuration_adresse']), 0, 0); + $this->Cell(0, 7, trim(FileExportHelpers::FormatTextForExport($this->devisData['client_real_adress'])), 0, 1,'R'); + $this->Cell(0, 7, FileExportHelpers::FormatTextForExport($this->devisData['configuration_adresse_city']), 0, 0);border: + $this->Cell(0, 7, trim(FileExportHelpers::FormatTextForExport($this->devisData['client_adress_city'])), 0, 1,'R'); + $this->Cell(0, 7, FileExportHelpers::FormatTextForExport('Tél : ') . FileExportHelpers::FormatTextForExport($this->devisData['configuration']->telephone),0,0); + $this->Cell(0, 7, FileExportHelpers::FormatTextForExport('Numéro') . ' Siret: ' . $this->devisData['siret'], 0, 1,'R'); + $this->Cell(0, 7, 'Mail : ' . $this->devisData['configuration']->mail, 0, 1); + $this->Ln(3); + } + + private function DrawDevisInfoTable(){ + $this->SetFont('Arial', 'B', 11); + $this->Cell(30, 7, 'DATE', 1, 0, 'C'); + $this->Cell(80, 7, 'CLIENT', 1, 0, 'C'); + $this->Cell(40, 7, 'DEVIS', 1, 1, 'C'); + + $this->SetFont('Arial', '', 10); + $this->Cell(30, 7, $this->devisData['devis_date'], 1, 0, 'C'); + $this->Cell(80, 7, utf8_decode(html_entity_decode($this->devisData['client_nom'])), 1, 0, 'C'); + $this->Cell(40, 7, $this->devisData['devis_full_number'], 1, 1, 'C'); + + $this->Ln(8); + } + + private function DrawArticlesTable(){ + $this->SetLineWidth(0.1); + $this->Rect(10, 105, 190, 100, "D"); + // cadre titre des colonnes + $this->Line(10, 115, 200,115); + // les traits verticaux colonnes + $this->Line(35, 105, 35, 205); + $this->Line(135, 105, 135, 205); + $this->Line(155, 105, 155, 205); + $this->Line(175, 105, 175, 205); + } + + private function DrawArticlesTableHeader(){ + $tvaValue = $this->devisData["configuration"]->tva_default; + $this->SetFont('Arial','',10); + $this->SetXY( 10,106 ); + $this->Cell( 20, 8, "Date", 0, 0, 'C'); + + $this->SetXY( 35,106 ); + $this->Cell( 100, 8, "Description", 0, 0, 'C'); + + $this->SetXY( 135,106 ); + $this->Cell( 20, 8, "Prix Uni. HT", 0, 0, 'C'); + + $this->SetXY( 155,106 ); + $this->Cell( 20, 8, 'TVA ' . $tvaValue . '%', 0, 0, 'C'); + + $this->SetXY( 175,106 ); + $this->Cell( 25, 8, "Prix Uni. TTC", 0, 0, 'C'); + + } + + public function DrawArticlesTableValueAndReturnTotalPrice(){ + $this->SetFont('Arial','',10); + $tvaValue = $this->devisData["configuration"]->tva_default; + $totalHt = 0; + $totalTtc = 0; + $totalTva = 0; + $products = $this->devisData["products"]; + $yValue = 116; + 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 = $this->devisData['devis_date']; + $productDescription .= " de " . FileExportHelpers::GetSexeLabel($this->devisData['defunt_sexe']) . ' '. $this->devisData["defunt_nom"]; + } + $tvaAmount = $valueTtc - $valueHt; + $this->SetXY( 10,$yValue ); + $this->Cell(20, 6, $dateValue, 0,0); + + $this->SetXY( 35,$yValue ); + $this->MultiAlignCell(100, 6, utf8_decode(html_entity_decode($productDescription)),0,'0',); + + $this->SetXY( 135,$yValue ); + $this->Cell(20, 6, number_format($valueHt,2,'.','').chr(128), 0, 0, 'C'); + + $this->SetXY( 155,$yValue ); + $this->Cell(20, 6, number_format($tvaAmount,2,'.','').chr(128), 0, 0, 'C'); + + $this->SetXY( 175,$yValue ); + $this->Cell(25, 6, number_format($valueTtc,2,'.','').chr(128), 0, 1, 'C'); + $yValue += 12; + $totalTva += $tvaAmount; + } + + return [ + "TOTAL HT" => $totalHt, + "TVA ".$tvaValue. "%" => $totalTva, + "TOTAL TTC" => $totalTtc + ]; + } + + private function DrawBankAndTotalPriceInfo($totalPriceArray){ + $this->SetY(210); + $this->SetFont('Arial', '', 9); + $this->MultiCell(0,5,utf8_decode(html_entity_decode("Paiement à votre convenance par chèque à l'ordre de ". $this->devisData['configuration']->entreprise))); + $this->MultiCell(0,5,utf8_decode(html_entity_decode("en indiquant le numéro de facture, ou par virement :"))); + + $this->Ln(1); + + //Table IBAN + $this->SetFont('Arial', '', 11); + $ibanWidth = 90; + $ibanCursorY = $this->GetY(); + $this->Cell($ibanWidth, 7, 'IBAN : FR76 1360 6000 1436 5418 1800 038', 1, 1, 'C'); + $ibanCursorX = $this->GetX(); + $this->Cell($ibanWidth, 7, 'Code SWIFT : AGRI FR PP 836', 1, 1, 'C'); + + //TABLE HT + $ibanLastPositionX = $ibanCursorX+$ibanWidth + 20; + $startOfArrayX = $ibanLastPositionX; + $startOfArrayY = $ibanCursorY; + foreach($totalPriceArray as $label => $price){ + $this->SetXY($startOfArrayX,$startOfArrayY); + $this->Cell(40, 7, $label, 1, 1, 'C'); + $this->SetXY($startOfArrayX + 40,$startOfArrayY); + $this->Cell(40, 7, number_format($price,2,'.','').chr(128), 1, 1, 'C'); + $startOfArrayY += 7; + } + } + + public function SetMultipleDevisContent(){ + foreach($this->multipleDevisData as $devisData){ + $this->devisData = $devisData; + $this->SetDevisContent(); + } + } + + public function SetDevisContent(){ + $this->AddPage(); + $this->SetMargins(10,0,10); + $this->DrawDevisCompanyAndClientInfo(); + $this->DrawDevisInfoTable(); + $this->DrawArticlesTable(); + $this->DrawArticlesTableHeader(); + $totalPriceValue = $this->DrawArticlesTableValueAndReturnTotalPrice(); + $this->DrawBankAndTotalPriceInfo($totalPriceValue); + } + + function MultiAlignCell($w,$h,$text,$border=0,$ln=0,$align='L',$fill=false) + { + // Store reset values for (x,y) positions + $x = $this->GetX() + $w; + $y = $this->GetY(); + + // Make a call to FPDF's MultiCell + $this->MultiCell($w,$h,$text,$border,$align,$fill); + + // Reset the line position to the right, like in Cell + if( $ln==0 ) + { + $this->SetXY($x,$y); + } + } + + function NbLines($w, $txt) + { + // Compute the number of lines a MultiCell of width w will take + if(!isset($this->CurrentFont)) + $this->Error('No font has been set'); + $cw = $this->CurrentFont['cw']; + if($w==0) + $w = $this->w-$this->rMargin-$this->x; + $wmax = ($w-2*$this->cMargin)*1000/$this->FontSize; + $s = str_replace("\r",'',(string)$txt); + $nb = strlen($s); + if($nb>0 && $s[$nb-1]=="\n") + $nb--; + $sep = -1; + $i = 0; + $j = 0; + $l = 0; + $nl = 1; + while($i<$nb) + { + $c = $s[$i]; + if($c=="\n") + { + $i++; + $sep = -1; + $j = $i; + $l = 0; + $nl++; + continue; + } + if($c==' ') + $sep = $i; + $l += $cw[$c]; + if($l>$wmax) + { + if($sep==-1) + { + if($i==$j) + $i++; + } + else + $i = $sep+1; + $sep = -1; + $j = $i; + $l = 0; + $nl++; + } + else + $i++; + } + return $nl; + } +} diff --git a/gestion/lib/Service/Devis/Pdf/DevisPdfService.php b/gestion/lib/Service/Devis/Pdf/DevisPdfService.php new file mode 100644 index 0000000..0d7e2cd --- /dev/null +++ b/gestion/lib/Service/Devis/Pdf/DevisPdfService.php @@ -0,0 +1,190 @@ + + * + * @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\Devis\Pdf; + +use DateTime; +use OCA\Gestion\Db\Bdd; +use OCA\Gestion\Helpers\DateHelpers; +use OCA\Gestion\Helpers\FileExportHelpers; +use OCP\Files\IRootFolder; + +class DevisPdfService { + /** @var Bdd */ + private $gestionBdd; + + /** @var IRootFolder */ + private $rootFolder; + + private const DEFAULT_NEXTCLOUD_ADMIN = "admin"; + public function __construct( + Bdd $gestionBdd, + IRootFolder $rootFolder) { + $this->gestionBdd = $gestionBdd; + $this->rootFolder = $rootFolder; + } + + private function getLogo(){ + $storage = $this->rootFolder->getUserFolder(self::DEFAULT_NEXTCLOUD_ADMIN); + try{ + try { + if(isset($storage)){ + $file = $storage->get('/.gestion/logo.png'); + }else{ + return "nothing"; + } + } catch(\OCP\Files\NotFoundException $e) { + $file = $storage->get('/.gestion/logo.jpeg'); + } + } + catch(\OCP\Files\NotFoundException $e) { + return "nothing"; + } + + return base64_encode($file->getContent()); + } + + private function getDevisPdfFilename($devisData){ + $filename = "DEVIS-"; + $defuntNom = str_replace(' ',' ',$devisData['defunt_nom']); + $devisLocation = str_replace(' ',' ',$devisData['lieu_nom']); + return $filename.$defuntNom.'-'.$devisLocation; + } + + private function formatMultipleDevisToPdfFormat($multipleDevisData,$configuration){ + foreach($multipleDevisData as &$devis){ + $devis = $this->formatDevisDataToPdfDataFormat($devis,$configuration); + } + return $multipleDevisData; + } + + private function formatDevisDataToPdfDataFormat($devis,$configuration){ + $devisDate = $devis['devis_date']; + $devisDate = DateTime::createFromFormat('Y-m-d',$devisDate); + $devisDate = $devisDate->format('d-m-Y'); + $devis['devis_date'] = $devisDate; + $devis['configuration'] = $configuration; + $products = $this->gestionBdd->getDevisProduits($devis["devis_id"]); + $devis = $this->gestionBdd->setDevisStartAndEndTime($devis); + $firstClient = $this->gestionBdd->getFirstClient(); + $devis["siret"] = $firstClient != null ? $firstClient['legal_one'] : ''; + $devis["products"] = $products; + $clientAdresses = FileExportHelpers::GetAddressAndCityFromAddress($devis["client_adresse"]); + $devis["client_real_adress"] = $clientAdresses["address"]; + $devis["client_adress_city"] = $clientAdresses["city"]; + $configurationAdresses = FileExportHelpers::GetAddressAndCityFromAddress($configuration->adresse); + $devis["configuration_adresse"] = $configurationAdresses["address"]; + $devis["configuration_adresse_city"] = $configurationAdresses["city"]; + return $devis; + } + + public function generateDevisPdfByDevisId($devisId,$idNextCloud){ + $storage = $this->rootFolder->getUserFolder($idNextCloud); + $configs = json_decode($this->gestionBdd->getConfiguration(self::DEFAULT_NEXTCLOUD_ADMIN)); + $currentConfig = $configs[0]; + $logo = $this->getLogo(); + $devisPdfData = $this->gestionBdd->getDevisPdfDataByDevisId($devisId); + if($devisPdfData == null){ + return null; + } + $devisPdfDataFormatted = $this->formatDevisDataToPdfDataFormat($devisPdfData,$currentConfig); + $clean_folder = html_entity_decode(string: $currentConfig->path).'/'; + $devisPdfFolders = $this->getDevisPdfFolder($devisPdfDataFormatted,$clean_folder); + $pdf = new DevisPdfHandler(); + $pdf->SetDevisPdfData($devisPdfDataFormatted,$logo); + $pdf->SetDevisContent(); + $pdfContent = $pdf->Output('','S'); + $pdfFilename = $this->getDevisPdfFilename($devisPdfDataFormatted); + $filenames = []; + foreach($devisPdfFolders as $folder){ + try { + $storage->newFolder($folder); + } + catch(\OCP\Files\NotPermittedException $e) { + } + $ff_pdf = $folder.$pdfFilename.'.pdf'; + $storage->newFile($ff_pdf); + $file_pdf = $storage->get($ff_pdf); + $file_pdf->putContent($pdfContent); + $filenames[] = $ff_pdf; + } + return $filenames; + } + + private function getDevisPdfFolder(array $devisPdfData,$racinePath){ + $clientRacineFolder = $racinePath.'CLIENTS/'.strtoupper($devisPdfData["client_entreprise"]).'/'; + $defuntsFolder = $clientRacineFolder.'DEFUNTS/'.strtoupper($devisPdfData['defunt_nom']).'/'.'DEVIS'.'/'; + $devisDate = $devisPdfData['devis_date']; + $devisDatetime = new DateTime($devisDate); + $devisDateYear = $devisDatetime->format('Y'); + $devisMonth = DateHelpers::GetDateWithFormatDayAndMonthPlainString($devisPdfData['devis_date']); + $devisByYearFolder = $clientRacineFolder."$devisDateYear".'/'.$devisMonth.'/'.'DEVIS'.'/'; + return [ + $defuntsFolder, + $devisByYearFolder + ]; + } + + private function GetMultipleDevisFilename($multipleDevisData,$month,$year){ + $filename = ""; + foreach($multipleDevisData as $devis){ + $filename = strtoupper($devis["client_entreprise"]); + $filename .= $month != 0 ? '_'.DateHelpers::GetMonthPlainString($month) :''; + $filename .= "_".$year; + break; + } + return $filename; + } + + public function generateMultipleDevisPdfByClientAndMonthYear($clientId,$month,$year,$idNextCloud){ + $storage = $this->rootFolder->getUserFolder($idNextCloud); + $configs = json_decode($this->gestionBdd->getConfiguration(self::DEFAULT_NEXTCLOUD_ADMIN)); + $currentConfig = $configs[0]; + $logo = $this->getLogo(); + $mulitpleDevisData = $this->gestionBdd->getDevisPdfDataByClientAndMonthYear($clientId,$month,$year,$currentConfig); + if(empty($mulitpleDevisData)){ + return null; + } + $multipleDevisDataFormatted = $this->formatMultipleDevisToPdfFormat($mulitpleDevisData,$currentConfig); + $pdf = new DevisPdfHandler(); + $pdf->SetMultipleDevisPdfData($multipleDevisDataFormatted,$logo); + $pdf->SetMultipleDevisContent(); + $racinePath = html_entity_decode(string: $currentConfig->path).'/'; + $clientRacineFolder = $racinePath.'CLIENTS/'.strtoupper($multipleDevisDataFormatted[0]["client_entreprise"]).'/'; + $filename = 'DEVIS'.'_'.$this->GetMultipleDevisFilename($multipleDevisDataFormatted,$month,$year); + $filenamePath = $clientRacineFolder.$filename.'.pdf'; + $pdfContent = $pdf->Output('','S'); + try { + $storage->newFolder($clientRacineFolder); + } + catch(\OCP\Files\NotPermittedException $e) { + } + $storage->newFile($filenamePath); + $file_pdf = $storage->get($filenamePath); + $file_pdf->putContent($pdfContent); + return $filenamePath; + } +} diff --git a/gestion/lib/Service/InvoicePdfHandler.php b/gestion/lib/Service/InvoicePdfHandler.php new file mode 100644 index 0000000..2573dad --- /dev/null +++ b/gestion/lib/Service/InvoicePdfHandler.php @@ -0,0 +1,326 @@ + + * + * @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; + +use DateTime; +use \FPDF; +use OCA\Gestion\Constants\MultipleFactureTypeConstant; +use OCA\Gestion\Helpers\DateHelpers; +use OCA\Gestion\Helpers\FileExportHelpers; +use OCA\Gestion\Helpers\PriceHelpers; + +class InvoicePdfHandler extends FPDF { + + private $multipleFactureData = []; + private $factureData = []; + private $logo = null; + private $logoPath = "/var/www/html/data/admin/files/.gestion/"; + function Header() + { + if($this->logo != "nothing"){ + $this->Image($this->logoPath."logo.png", 10, 10, 75, 25); + } + else{ + $this->Cell(55,30,''); + } + } + function Footer() + { + $this->SetY(-40); + $this->SetFont('Arial', '', 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 ). +'))); + + $this->SetY(-15); + $this->SetFont('Arial', 'B', 8); + $this->Cell(0, 10, utf8_decode(html_entity_decode($this->factureData['configuration']->legal_one)), 0, 0, 'C'); + } + + public function InvoicePdfFactory(array $factureData,$logo = null){ + $this->factureData = $factureData; + $this->logo = $logo; + } + + public function MutlipleInvoicePdfFactory(array $multipleInvoiceData,$logo = null){ + $this->multipleFactureData = $multipleInvoiceData; + $this->logo = $logo; + } + + public function GetMultipleInvoiceFilename($month,$year){ + $filename = ""; + foreach($this->multipleFactureData as $factureData){ + $filename = strtoupper($factureData["client_entreprise"]); + $filename .= $month != 0 ? '_'.DateHelpers::GetMonthPlainString($month) :''; + $filename .= "_".$year; + break; + } + return $filename; + } + + public function GetInvoiceFilename(){ + $factureNum = $this->factureData['num']; + $factureNum = str_replace('/','-',$factureNum); + $defuntNom = str_replace(' ',' ',$this->factureData['defunt_nom']); + return $this->factureData['configuration']->facture_prefixe.'_'.$factureNum.'_'.strtoupper($defuntNom); + } + + private function DrawInvoiceCompanyAndClientInfo(){ + $this->SetY(40); + $this->SetFont('Arial', '', 12); + $this->Cell(0, 7, FileExportHelpers::FormatTextForExport($this->factureData['configuration']->entreprise), 0, 0); + $this->Cell(0, 7, FileExportHelpers::FormatTextForExport($this->factureData['client_nom']), 0, 1,'R'); + $this->Cell(0, 7, FileExportHelpers::FormatTextForExport($this->factureData['configuration_adresse']), 0, 0); + $this->Cell(0, 7, trim(FileExportHelpers::FormatTextForExport($this->factureData['client_real_adress'])), 0, 1,'R'); + $this->Cell(0, 7, FileExportHelpers::FormatTextForExport($this->factureData['configuration_adresse_city']), 0, 0);border: + $this->Cell(0, 7, trim(FileExportHelpers::FormatTextForExport($this->factureData['client_adress_city'])), 0, 1,'R'); + $this->Cell(0, 7, FileExportHelpers::FormatTextForExport('Tél : ') . FileExportHelpers::FormatTextForExport($this->factureData['configuration']->telephone),0,0); + $this->Cell(0, 7, FileExportHelpers::FormatTextForExport('Numéro') . ' Siret: ' . $this->factureData['siret'], 0, 1,'R'); + $this->Cell(0, 7, 'Mail : ' . $this->factureData['configuration']->mail, 0, 1); + $this->Ln(3); + } + + private function DrawInvoiceInfoTable(){ + + $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('Arial', 'B', 11); + $this->Cell(30, 7, 'DATE', 1, 0, 'C'); + $this->Cell(80, 7, 'CLIENT', 1, 0, 'C'); + $this->Cell(40, 7, 'FACTURE', 1, 0, 'C'); + $this->Cell(40, 7, 'ECHEANCE', 1, 1, 'C'); + + $this->SetFont('Arial', '', 10); + $this->Cell(30, 7, $factureDatePaiement, 1, 0, 'C'); + $this->Cell(80, 7, utf8_decode(html_entity_decode($this->factureData['client_nom'])), 1, 0, 'C'); + $this->Cell(40, 7, $this->factureData['num'], 1, 0, 'C'); + $this->Cell(40, 7, $factureDateEcheance, 1, 1, 'C'); + + $this->Ln(8); + } + + private function DrawArticlesTable(){ + $this->SetLineWidth(0.1); + $this->Rect(10, 105, 190, 100, "D"); + // cadre titre des colonnes + $this->Line(10, 115, 200,115); + // les traits verticaux colonnes + $this->Line(35, 105, 35, 205); + $this->Line(135, 105, 135, 205); + $this->Line(155, 105, 155, 205); + $this->Line(175, 105, 175, 205); + } + + private function DrawArticlesTableHeader(){ + $tvaValue = $this->factureData["configuration"]->tva_default; + $this->SetFont('Arial','',10); + $this->SetXY( 10,106 ); + $this->Cell( 20, 8, "Date", 0, 0, 'C'); + + $this->SetXY( 35,106 ); + $this->Cell( 100, 8, "Description", 0, 0, 'C'); + + $this->SetXY( 135,106 ); + $this->Cell( 20, 8, "Prix Uni. HT", 0, 0, 'C'); + + $this->SetXY( 155,106 ); + $this->Cell( 20, 8, 'TVA ' . $tvaValue . '%', 0, 0, 'C'); + + $this->SetXY( 175,106 ); + $this->Cell( 25, 8, "Prix Uni. TTC", 0, 0, 'C'); + + } + + public function DrawArticlesTableValueAndReturnTotalPrice(){ + $this->SetFont('Arial','',10); + $devisDate = $this->factureData['devis_date']; + $devisDate = DateTime::createFromFormat('Y-m-d',$devisDate); + $devisDate = $devisDate->format('d-m-Y'); + $tvaValue = $this->factureData["configuration"]->tva_default; + $totalHt = 0; + $totalTtc = 0; + $totalTva = 0; + $products = $this->factureData["products"]; + $yValue = 116; + 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 " . FileExportHelpers::GetSexeLabel($this->factureData['defunt_sexe']) . ' '. $this->factureData["defunt_nom"]; + } + $tvaAmount = $valueTtc - $valueHt; + $this->SetXY( 10,$yValue ); + $this->Cell(20, 6, $dateValue, 0,0); + + $this->SetXY( 35,$yValue ); + $this->MultiAlignCell(100, 6, utf8_decode(html_entity_decode($productDescription)),0,'0',); + + $this->SetXY( 135,$yValue ); + $this->Cell(20, 6, number_format($valueHt,2,'.','').chr(128), 0, 0, 'C'); + + $this->SetXY( 155,$yValue ); + $this->Cell(20, 6, number_format($tvaAmount,2,'.','').chr(128), 0, 0, 'C'); + + $this->SetXY( 175,$yValue ); + $this->Cell(25, 6, number_format($valueTtc,2,'.','').chr(128), 0, 1, 'C'); + $yValue += 12; + $totalTva += $tvaAmount; + } + + return [ + "TOTAL HT" => $totalHt, + "TVA ".$tvaValue. "%" => $totalTva, + "TOTAL TTC" => $totalTtc + ]; + } + + private function DrawBankAndTotalPriceInfo($totalPriceArray){ + $this->SetY(210); + $this->SetFont('Arial', '', 9); + $this->MultiCell(0,5,utf8_decode(html_entity_decode("Paiement à votre convenance par chèque à l'ordre de ". $this->factureData['configuration']->entreprise))); + $this->MultiCell(0,5,utf8_decode(html_entity_decode("en indiquant le numéro de facture, ou par virement :"))); + + $this->Ln(1); + + //Table IBAN + $this->SetFont('Arial', '', 11); + $ibanWidth = 90; + $ibanCursorY = $this->GetY(); + $this->Cell($ibanWidth, 7, 'IBAN : FR76 1360 6000 1436 5418 1800 038', 1, 1, 'C'); + $ibanCursorX = $this->GetX(); + $this->Cell($ibanWidth, 7, 'Code SWIFT : AGRI FR PP 836', 1, 1, 'C'); + + //TABLE HT + $ibanLastPositionX = $ibanCursorX+$ibanWidth + 20; + $startOfArrayX = $ibanLastPositionX; + $startOfArrayY = $ibanCursorY; + foreach($totalPriceArray as $label => $price){ + $this->SetXY($startOfArrayX,$startOfArrayY); + $this->Cell(40, 7, $label, 1, 1, 'C'); + $this->SetXY($startOfArrayX + 40,$startOfArrayY); + $this->Cell(40, 7, number_format($price,2,'.','').chr(128), 1, 1, 'C'); + $startOfArrayY += 7; + } + } + + public function SetMultipleFactureContent(){ + foreach($this->multipleFactureData as $factureData){ + $this->factureData = $factureData; + $this->SetFactureContent(); + } + } + + public function SetFactureContent(){ + $this->AddPage(); + $this->SetMargins(10,0,10); + $this->DrawInvoiceCompanyAndClientInfo(); + $this->DrawInvoiceInfoTable(); + $this->DrawArticlesTable(); + $this->DrawArticlesTableHeader(); + $totalPriceValue = $this->DrawArticlesTableValueAndReturnTotalPrice(); + $this->DrawBankAndTotalPriceInfo($totalPriceValue); + } + + function MultiAlignCell($w,$h,$text,$border=0,$ln=0,$align='L',$fill=false) + { + // Store reset values for (x,y) positions + $x = $this->GetX() + $w; + $y = $this->GetY(); + + // Make a call to FPDF's MultiCell + $this->MultiCell($w,$h,$text,$border,$align,$fill); + + // Reset the line position to the right, like in Cell + if( $ln==0 ) + { + $this->SetXY($x,$y); + } + } + + function NbLines($w, $txt) + { + // Compute the number of lines a MultiCell of width w will take + if(!isset($this->CurrentFont)) + $this->Error('No font has been set'); + $cw = $this->CurrentFont['cw']; + if($w==0) + $w = $this->w-$this->rMargin-$this->x; + $wmax = ($w-2*$this->cMargin)*1000/$this->FontSize; + $s = str_replace("\r",'',(string)$txt); + $nb = strlen($s); + if($nb>0 && $s[$nb-1]=="\n") + $nb--; + $sep = -1; + $i = 0; + $j = 0; + $l = 0; + $nl = 1; + while($i<$nb) + { + $c = $s[$i]; + if($c=="\n") + { + $i++; + $sep = -1; + $j = $i; + $l = 0; + $nl++; + continue; + } + if($c==' ') + $sep = $i; + $l += $cw[$c]; + if($l>$wmax) + { + if($sep==-1) + { + if($i==$j) + $i++; + } + else + $i = $sep+1; + $sep = -1; + $j = $i; + $l = 0; + $nl++; + } + else + $i++; + } + return $nl; + } +} diff --git a/gestion/lib/Service/InvoicePdfService.php b/gestion/lib/Service/InvoicePdfService.php new file mode 100644 index 0000000..0e790f5 --- /dev/null +++ b/gestion/lib/Service/InvoicePdfService.php @@ -0,0 +1,148 @@ + + * + * @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; + +use DateTime; +use OCA\Gestion\Db\Bdd; +use OCA\Gestion\Helpers\DateHelpers; +use OCP\Files\IRootFolder; + +class InvoicePdfService { + /** @var Bdd */ + private $gestionBdd; + + /** @var IRootFolder */ + private $rootFolder; + + private const DEFAULT_NEXTCLOUD_ADMIN = "admin"; + public function __construct( + Bdd $gestionBdd, + IRootFolder $rootFolder) { + $this->gestionBdd = $gestionBdd; + $this->rootFolder = $rootFolder; + } + + private function getLogo(){ + $storage = $this->rootFolder->getUserFolder(self::DEFAULT_NEXTCLOUD_ADMIN); + try{ + try { + if(isset($storage)){ + $file = $storage->get('/.gestion/logo.png'); + }else{ + return "nothing"; + } + } catch(\OCP\Files\NotFoundException $e) { + $file = $storage->get('/.gestion/logo.jpeg'); + } + } + catch(\OCP\Files\NotFoundException $e) { + return "nothing"; + } + + return base64_encode($file->getContent()); + } + + public function generateFacturePdfByFactureId($factureId,$idNextCloud){ + $storage = $this->rootFolder->getUserFolder($idNextCloud); + $configs = json_decode($this->gestionBdd->getConfiguration(self::DEFAULT_NEXTCLOUD_ADMIN)); + $currentConfig = $configs[0]; + $logo = $this->getLogo(); + $invoicePdfData = $this->gestionBdd->getInvoicePdfData($factureId,$currentConfig); + if($invoicePdfData == null){ + return ""; + } + $clean_folder = html_entity_decode(string: $currentConfig->path).'/'; + $factureFolders = $this->getFacturesFolder($invoicePdfData,$clean_folder); + $pdf = new InvoicePdfHandler(); + $pdf->InvoicePdfFactory($invoicePdfData,$logo); + $pdf->SetFactureContent(); + $pdfContent = $pdf->Output('','S'); + $pdfFilename = $pdf->GetInvoiceFilename(); + $filenames = []; + foreach($factureFolders as $folder){ + try { + $storage->newFolder($folder); + } + catch(\OCP\Files\NotPermittedException $e) { + } + $ff_pdf = $folder.$pdfFilename.'.pdf'; + $storage->newFile($ff_pdf); + $file_pdf = $storage->get($ff_pdf); + $file_pdf->putContent($pdfContent); + $filenames[] = $ff_pdf; + } + return $filenames; + } + + private function getFacturesFolder(array $factureData,$racinePath){ + $clientRacineFolder = $racinePath.'CLIENTS/'.strtoupper($factureData["client_entreprise"]).'/'; + $defuntsFolder = $clientRacineFolder.'DEFUNTS/'.strtoupper($factureData['defunt_nom']).'/'.'FACTURES'.'/'; + $devisDate = $factureData['devis_date']; + $devisDatetime = new DateTime($devisDate); + $devisDateYear = $devisDatetime->format('Y'); + $devisMonth = DateHelpers::GetDateWithFormatDayAndMonthPlainString($factureData['devis_date']); + $factureByYearFolder = $clientRacineFolder."$devisDateYear".'/'.$devisMonth.'/'.'FACTURES'.'/'; + return [ + $defuntsFolder, + $factureByYearFolder + ]; + } + + public function generateFacturePdfByFactureIds(array $factureIds,$idNextCloud){ + foreach( $factureIds as $factureId ){ + $this->generateFacturePdfByFactureId($factureId,$idNextCloud); + } + } + + public function generateMultipleInvoicePdfByClientAndMonthYear($clientId,$month,$year,$idNextCloud){ + $storage = $this->rootFolder->getUserFolder($idNextCloud); + $configs = json_decode($this->gestionBdd->getConfiguration(self::DEFAULT_NEXTCLOUD_ADMIN)); + $currentConfig = $configs[0]; + $logo = $this->getLogo(); + $invoiceData = $this->gestionBdd->getInvoicePdfDataByClientAndMonthYear($clientId,$month,$year,$currentConfig); + if(empty($invoiceData)){ + return null; + } + $pdf = new InvoicePdfHandler(); + $pdf->MutlipleInvoicePdfFactory($invoiceData,$logo); + $pdf->SetMultipleFactureContent(); + $racinePath = html_entity_decode(string: $currentConfig->path).'/'; + $clientRacineFolder = $racinePath.'CLIENTS/'.strtoupper($invoiceData[0]["client_entreprise"]).'/'; + $filename = $currentConfig->facture_prefixe.'_'.$pdf->GetMultipleInvoiceFilename($month,$year); + $filenamePath = $clientRacineFolder.$filename.'.pdf'; + $pdfContent = $pdf->Output('','S'); + try { + $storage->newFolder($clientRacineFolder); + } + catch(\OCP\Files\NotPermittedException $e) { + } + $storage->newFile($filenamePath); + $file_pdf = $storage->get($filenamePath); + $file_pdf->putContent($pdfContent); + return $filenamePath; + } +}