Merge branch 'features/feature-facture-and-devis-new-model' into releases/release-h2f

This commit is contained in:
Tiavina 2025-01-20 09:27:22 +03:00
commit 4a9dae4862
27 changed files with 1865 additions and 366 deletions

View File

@ -126,5 +126,19 @@ 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'],
//certificate
['name' => 'page#exportCareCertificate', 'url' => '/defunt/exportCareCertificate', 'verb' => 'POST'],
]
];

File diff suppressed because one or more lines are too long

View File

@ -25,12 +25,6 @@
* MIT Licensed
*/
/*!
* html2canvas 1.4.1 <https://html2canvas.hertzen.com>
* Copyright (c) 2022 Niklas von Hertzen <https://hertzen.com>
* Released under MIT License
*/
/*!
* jQuery JavaScript Library v3.6.3
* https://jquery.com/
@ -45,335 +39,8 @@
* Date: 2022-12-20T21:28Z
*/
/*! *****************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/*! @license DOMPurify 2.4.4 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/2.4.4/LICENSE */
/*! DataTables 1.13.2
* ©2008-2023 SpryMedia Ltd - datatables.net/license
*/
/**
* @license
Copyright (c) 2008, Adobe Systems Incorporated
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Adobe Systems Incorporated nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @license
*
* Copyright (c) 2014 James Robb, https://github.com/jamesbrobb
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ====================================================================
*/
/**
* @license
*
* Licensed under the MIT License.
* http://opensource.org/licenses/mit-license
*/
/**
* @license
* (c) Dean McNamee <dean@gmail.com>, 2013.
*
* https://github.com/deanm/omggif
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
* omggif is a JavaScript implementation of a GIF 89a encoder and decoder,
* including animation and compression. It does not rely on any specific
* underlying system, so should run in the browser, Node, or Plask.
*/
/**
* @license
* Copyright (c) 2014 Steven Spungin (TwelveTone LLC) steven@twelvetone.tv
*
* Licensed under the MIT License.
* http://opensource.org/licenses/mit-license
*/
/**
* @license
* Copyright (c) 2017 Aras Abbasi
*
* Licensed under the MIT License.
* http://opensource.org/licenses/mit-license
*/
/**
* @license
* Copyright (c) 2018 Aras Abbasi
*
* Licensed under the MIT License.
* http://opensource.org/licenses/mit-license
*/
/**
* @license
* Copyright (c) 2019 Aras Abbasi
*
* Licensed under the MIT License.
* http://opensource.org/licenses/mit-license
*/
/**
* @license
* FPDF is released under a permissive license: there is no usage restriction.
* You may embed it freely in your application (commercial or not), with or
* without modifications.
*
* Reference: http://www.fpdf.org/en/script/script37.php
*/
/**
* @license
* Joseph Myers does not specify a particular license for his work.
*
* Author: Joseph Myers
* Accessed from: http://www.myersdaily.org/joseph/javascript/md5.js
*
* Modified by: Owen Leong
*/
/**
* @license
* Licensed under the MIT License.
* http://opensource.org/licenses/mit-license
* Author: Owen Leong (@owenl131)
* Date: 15 Oct 2020
* References:
* https://www.cs.cmu.edu/~dst/Adobe/Gallery/anon21jul01-pdf-encryption.txt
* https://github.com/foliojs/pdfkit/blob/master/lib/security.js
* http://www.fpdf.org/en/script/script37.php
*/
/**
* @license
* Licensed under the MIT License.
* http://opensource.org/licenses/mit-license
*/
/**
* @license
* Unicode Bidi Engine based on the work of Alex Shensis (@asthensis)
* MIT License
*/
/**
* @license
* jsPDF fileloading PlugIn
* Copyright (c) 2018 Aras Abbasi (aras.abbasi@gmail.com)
*
* Licensed under the MIT License.
* http://opensource.org/licenses/mit-license
*/
/**
* @license
* jsPDF filters PlugIn
* Copyright (c) 2014 Aras Abbasi
*
* Licensed under the MIT License.
* http://opensource.org/licenses/mit-license
*/
/**
* @license
* jsPDF virtual FileSystem functionality
*
* Licensed under the MIT License.
* http://opensource.org/licenses/mit-license
*/
/**
* A class to parse color values
* @author Stoyan Stefanov <sstoo@gmail.com>
* {@link http://www.phpied.com/rgb-color-parser-in-javascript/}
* @license Use it if you like it
*/
/** ====================================================================
* @license
* jsPDF XMP metadata plugin
* Copyright (c) 2016 Jussi Utunen, u-jussi@suomi24.fi
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ====================================================================
*/
/** @license
* Copyright (c) 2017 Dominik Homberger
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
https://webpjs.appspot.com
WebPRiffParser dominikhlbg@gmail.com
*/
/** @license
*
* jsPDF - PDF Document creation from JavaScript
* Version 2.5.1 Built on 2022-01-28T15:37:57.791Z
* CommitID 00000000
*
* Copyright (c) 2010-2021 James Hall <james@parall.ax>, https://github.com/MrRio/jsPDF
* 2015-2021 yWorks GmbH, http://www.yworks.com
* 2015-2021 Lukas Holländer <lukas.hollaender@yworks.com>, https://github.com/HackbrettXXX
* 2016-2018 Aras Abbasi <aras.abbasi@gmail.com>
* 2010 Aaron Spike, https://github.com/acspike
* 2012 Willow Systems Corporation, https://github.com/willowsystems
* 2012 Pablo Hess, https://github.com/pablohess
* 2012 Florian Jenett, https://github.com/fjenett
* 2013 Warren Weckesser, https://github.com/warrenweckesser
* 2013 Youssef Beddad, https://github.com/lifof
* 2013 Lee Driscoll, https://github.com/lsdriscoll
* 2013 Stefan Slonevskiy, https://github.com/stefslon
* 2013 Jeremy Morel, https://github.com/jmorel
* 2013 Christoph Hartmann, https://github.com/chris-rock
* 2014 Juan Pablo Gaviria, https://github.com/juanpgaviria
* 2014 James Makes, https://github.com/dollaruw
* 2014 Diego Casorran, https://github.com/diegocr
* 2014 Steven Spungin, https://github.com/Flamenco
* 2014 Kenneth Glassey, https://github.com/Gavvers
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* Contributor(s):
* siefkenj, ahwolf, rickygu, Midnith, saintclair, eaparango,
* kim3er, mfo, alnorth, Flamenco
*/
/** @license
* Copyright (c) 2012 Willow Systems Corporation, https://github.com/willowsystems
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* ====================================================================
*/

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -17,8 +17,11 @@ use \Datetime;
use \DatetimeImmutable;
use \IntlDateFormatter;
use \FPDF;
use OCA\Gestion\Service\Certificate\CertificateService;
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');
@ -27,6 +30,7 @@ class PageController extends Controller {
private $myDb;
// private $src_path = "/var/www/html/apps/gestion/img/";
private $src_path = "/var/www/html/custom_apps/gestion/img/";
private const H2F_DEFAULT_ADMIN = "Emmanuelle";
private $urlGenerator;
private $mailer;
private $config;
@ -43,6 +47,15 @@ class PageController extends Controller {
/** @var ExportClientStatisticService */
private $exportClientStatisticService;
/** @var InvoicePdfService */
private $invoicePdfService;
/** @var DevisPdfService */
private $devisPdfService;
/** @var CertificateService */
private $certificateService;
/**
* Constructor
*/
@ -57,7 +70,10 @@ class PageController extends Controller {
IUserSession $userSession,
IGroupManager $groupManager,
ExportThanatoStatisticService $exportThanatoStatisticService,
ExportClientStatisticService $exportClientStatisticService,){
ExportClientStatisticService $exportClientStatisticService,
InvoicePdfService $invoicePdfService,
DevisPdfService $devisPdfService,
CertificateService $certificateService){
parent::__construct($AppName, $request);
@ -68,6 +84,9 @@ class PageController extends Controller {
$this->config = $config;
$this->exportThanatoStatisticService = $exportThanatoStatisticService;
$this->exportClientStatisticService = $exportClientStatisticService;
$this->invoicePdfService = $invoicePdfService;
$this->devisPdfService = $devisPdfService;
$this->certificateService = $certificateService;
//$this->fpdf = $fpdf;
if ($userSession->isLoggedIn()) {
@ -1218,7 +1237,8 @@ class PageController extends Controller {
* @NoCSRFRequired
*/
public function getConfiguration() {
return $this->myDb->getConfiguration($this->idNextcloud);
$idNextcloud = self::H2F_DEFAULT_ADMIN;
return $this->myDb->getConfiguration($idNextcloud);
}
/**
@ -2650,4 +2670,89 @@ 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) { }
}
/**
* @NoAdminRequired
* @NoCSRFRequired
* @param int $defuntId
*/
public function exportCareCertificate($defuntId){
try{
$careCertificateFilename = $this->certificateService->generateCareCertificate($defuntId,$this->idNextcloud);
return $careCertificateFilename;
}
catch(\OCP\Files\NotFoundException $e) { }
}
}

View File

@ -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,270 @@ 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;
}
public function getDevisOfDefunt($defuntId){
$sql = "SELECT
devis.id as id,
devis.date as devis_date,
devis.id_defunt as defunt_id,
devis.id_lieu as lieu_id,
lieu.nom as lieu_nom,
lieu.adresse as lieu_adresse,
defunt.nom as defunt_nom,
defunt.sexe as defunt_sexe,
client.nom as client_nom,
client.prenom as client_prenom,
client.entreprise as client_entreprise,
client.adresse as client_adresse,
thanato.nom as thanato_nom,
thanato.prenom as thanato_prenom,
thanato.reference as thanato_reference,
thanato.date_habilitation as thanato_date_habilitation
FROM ".$this->tableprefix."devis as devis
LEFT JOIN ".$this->tableprefix."lieu as lieu on devis.id_lieu = lieu.id
LEFT JOIN ".$this->tableprefix."defunt as defunt on devis.id_defunt = defunt.id
LEFT JOIN ".$this->tableprefix."client as client on devis.id_client = client.id
LEFT JOIN ".$this->tableprefix."thanato as thanato on devis.id_thanato = thanato.id
WHERE devis.id_defunt = ? ;";
$devisOfDefunt = $this->execSQLNoJsonReturn($sql, [$defuntId]);
if(!empty( $devisOfDefunt)){
return $devisOfDefunt[0];
}
return null;
}
}

View File

@ -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');

View File

@ -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]);

View File

@ -0,0 +1,136 @@
<?php
declare(strict_types=1);
/**
* Calendar App
*
* @copyright 2021 Anna Larch <anna.larch@gmx.net>
*
* @author Anna Larch <anna.larch@gmx.net>
* @author Richard Steinmetz <richard@steinmetz.cloud>
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Gestion\Service\Certificate;
use DateTime;
use DateTimeImmutable;
use OCA\Gestion\Db\Bdd;
use OCA\Gestion\Helpers\DateHelpers;
use OCA\Gestion\Service\Certificate\PdfHandler\CareCertificatePdfHandler;
use OCP\Files\IRootFolder;
class CertificateService {
/** @var Bdd */
private $gestionBdd;
/** @var IRootFolder */
private $rootFolder;
private const DEFAULT_NEXTCLOUD_ADMIN = "admin";
private const DEFAULT_NEXTCLOUD_H2F_ADMIN = "Emmanuelle";
public function __construct(
Bdd $gestionBdd,
IRootFolder $rootFolder) {
$this->gestionBdd = $gestionBdd;
$this->rootFolder = $rootFolder;
}
private function signatureImageExists(){
$storage = $this->rootFolder->getUserFolder(self::DEFAULT_NEXTCLOUD_ADMIN);
try{
if(isset($storage)){
$storage->get("/.gestion/sign.png");
$signatureExist = true;
}else{
$signatureExist = false;
}
}
catch(\OCP\Files\NotFoundException $e) {
$signatureExist = false;
}
return $signatureExist;
}
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 generateCareCertificate($defuntId,$idNextCloud){
$storage = $this->rootFolder->getUserFolder($idNextCloud);
$configs = json_decode($this->gestionBdd->getConfiguration(self::DEFAULT_NEXTCLOUD_H2F_ADMIN));
$currentConfig = $configs[0];
$logo = $this->getLogo();
$devisOfDefunt = $this->gestionBdd->getDevisOfDefunt($defuntId);
if($devisOfDefunt == null){
return null;
}
$devisOfDefunt["configuration"] = $currentConfig;
$devisOfDefunt["thanato_date_habilitation"] = new DateTimeImmutable($devisOfDefunt["thanato_date_habilitation"]);
$devisOfDefunt["devis_date"] = new DateTimeImmutable($devisOfDefunt["devis_date"]);
$clean_folder = html_entity_decode(string: $currentConfig->path).'/';
$careCertificateFolder = $this->getCareCertificateFolder($devisOfDefunt);
$folderDestination = $clean_folder.$careCertificateFolder;
$pdfFilename = $this->GetCareCertificateFilename($devisOfDefunt);
$filenamePath = $clean_folder.$careCertificateFolder.$pdfFilename.'.pdf';
$pdf = new CareCertificatePdfHandler();
$signatureImageExist = $this->signatureImageExists();
$pdf->SetCareCertificateData($devisOfDefunt,$logo,$signatureImageExist);
$pdf->SetCareCertificate();
try {
$storage->newFolder($folderDestination);
}
catch(\OCP\Files\NotPermittedException $e) {
}
$pdfContent = $pdf->Output('','S');
$storage->newFile($filenamePath);
$pdfFile = $storage->get($filenamePath);
$pdfFile->putContent($pdfContent);
return $filenamePath;
}
private function getCareCertificateFolder($devisOfDefunt){
$careCertificateFolder = 'CLIENTS/'
.strtoupper($devisOfDefunt["client_entreprise"])
.'/DEFUNTS/'
.strtoupper($devisOfDefunt["defunt_nom"]).'/'
.'ATTESTATION/';
return $careCertificateFolder;
}
private function GetCareCertificateFilename($devisOfDefunt){
$filename = 'ATTESTATION_SOIN_'.strtoupper($devisOfDefunt['defunt_nom']);
return $filename;
}
}

View File

@ -0,0 +1,178 @@
<?php
declare(strict_types=1);
/**
* Calendar App
*
* @copyright 2021 Anna Larch <anna.larch@gmx.net>
*
* @author Anna Larch <anna.larch@gmx.net>
* @author Richard Steinmetz <richard@steinmetz.cloud>
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Gestion\Service\Certificate\PdfHandler;
use DateTime;
use \FPDF;
use OCA\Gestion\Helpers\DateHelpers;
use OCA\Gestion\Helpers\FileExportHelpers;
use OCA\Gestion\Helpers\PriceHelpers;
class CareCertificatePdfHandler extends FPDF {
private $devisOfDefunt = [];
private $logo = null;
private $signatureImageExist = false;
private $imagePath = "/var/www/html/data/admin/files/.gestion/";
function Header()
{
if($this->logo != "nothing"){
$this->Image($this->imagePath."logo.png", 10, 10, 75, 25);
}
else{
$this->Cell(55,30,'');
}
}
function Footer()
{
$this->SetY(-18);
$this->SetFont('Arial', '', 10);
$this->MultiCell(0, 5, utf8_decode(html_entity_decode($this->devisOfDefunt['configuration']->legal_one)), 0, 'C');
$this->MultiCell(0, 5, utf8_decode(html_entity_decode($this->devisOfDefunt['configuration']->adresse)), 0,'C');
}
public function SetCareCertificateData(array $devisOfDefunt,$logo = null,$signatureImageExist = false){
$this->devisOfDefunt = $devisOfDefunt;
$this->logo = $logo;
$this->signatureImageExist = $signatureImageExist;
}
public function SetCareCertificate(){
$this->AddPage();
$this->SetMargins(left:20,top:0,right:20);
$this->SetCareCertificateTitle();
$this->SetCareCertificateContent();
$this->SetSigning();
}
private function SetSigning(){
$this->SetXY(140,$this->GetY() + 30);
$this->Cell(0,10,'Cachet et signature');
if($this->signatureImageExist){
$this->Image($this->imagePath."sign.png", 135, $this->GetY() + 12, 55, 30);
}
}
private function SetCareCertificateContent(){
$this->SetFont('Arial', '', 14);
$this->MultiCell(0,7,FileExportHelpers::FormatTextForExport('La Société '. $this->devisOfDefunt['configuration']->entreprise. ' habilitée sous le numéro ' . $this->devisOfDefunt['thanato_reference'] . ' certifie par la présente que: '));
$this->SetFont('Arial', 'B', 14);
$this->Cell(0,12, 'Mr/Mlle ' . FileExportHelpers::FormatTextForExport($this->devisOfDefunt['thanato_nom'] . ' ' . $this->devisOfDefunt['thanato_prenom']),0,1);
$this->SetFont('Arial', '', 14);
$this->MultiCell(0,7, FileExportHelpers::FormatTextForExport('Employé au sein de notre société et titulaire du diplôme national de Thanatopracteur a effectué des soins de conservation sur le corps du défunt:'));
$this->SetFont('Arial', 'B', 14);
$this->Cell(0,12, 'M./Mme '.$this->devisOfDefunt['defunt_nom'],0,1);
$this->SetFont('Arial', '', 14);
$this->Cell(0,12, FileExportHelpers::FormatTextForExport("Qui reposait à l'adresse suivante") . ': ',0,1);
$this->SetFont('Arial', 'B', 14);
$this->Cell(0,12, FileExportHelpers::FormatTextForExport($this->devisOfDefunt['configuration']->adresse),0,1);
$this->SetFont('Arial', '', 14);
$this->Cell(0,12, FileExportHelpers::FormatTextForExport("La présente attestion est établie pour faire valoir ce que de droit."),0,5);
$this->Ln(5);
$this->Cell(0,12,FileExportHelpers::FormatTextForExport('Fait à '). FileExportHelpers::FormatTextForExport($this->devisOfDefunt['configuration']->adresse));
$this->SetX(140);
$this->Cell(0,12,'le '. $this->devisOfDefunt['devis_date']->format('d/m/Y'),0);
}
private function SetCareCertificateTitle(){
$this->SetY(60);
$this->SetFont('Arial', 'B', 20);
$this->Cell(0, 10, 'ATTESTATION DE SOINS DE CONSERVATION', 0, 1,'C');
$this->Ln(20);
}
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;
}
}

View File

@ -0,0 +1,294 @@
<?php
declare(strict_types=1);
/**
* Calendar App
*
* @copyright 2021 Anna Larch <anna.larch@gmx.net>
*
* @author Anna Larch <anna.larch@gmx.net>
* @author Richard Steinmetz <richard@steinmetz.cloud>
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
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_entreprise']), 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, 'LIEU', 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['lieu_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;
}
}

View File

@ -0,0 +1,191 @@
<?php
declare(strict_types=1);
/**
* Calendar App
*
* @copyright 2021 Anna Larch <anna.larch@gmx.net>
*
* @author Anna Larch <anna.larch@gmx.net>
* @author Richard Steinmetz <richard@steinmetz.cloud>
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
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";
private const DEFAULT_NEXTCLOUD_H2F_ADMIN = "Emmanuelle";
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('&nbsp;',' ',$devisData['defunt_nom']);
$devisLocation = str_replace('&nbsp;',' ',$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_H2F_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_H2F_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;
}
}

View File

@ -0,0 +1,326 @@
<?php
declare(strict_types=1);
/**
* Calendar App
*
* @copyright 2021 Anna Larch <anna.larch@gmx.net>
*
* @author Anna Larch <anna.larch@gmx.net>
* @author Richard Steinmetz <richard@steinmetz.cloud>
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
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('&nbsp;',' ',$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_entreprise']), 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, 'LIEU', 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['lieu_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;
}
}

View File

@ -0,0 +1,149 @@
<?php
declare(strict_types=1);
/**
* Calendar App
*
* @copyright 2021 Anna Larch <anna.larch@gmx.net>
*
* @author Anna Larch <anna.larch@gmx.net>
* @author Richard Steinmetz <richard@steinmetz.cloud>
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
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";
private const DEFAULT_NEXTCLOUD_H2F_ADMIN = "Emmanuelle";
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_H2F_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_H2F_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;
}
}

View File

@ -654,6 +654,17 @@
"node": ">= 8"
}
},
"node_modules/@popperjs/core": {
"version": "2.11.8",
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
"integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==",
"dev": true,
"peer": true,
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/popperjs"
}
},
"node_modules/@skjnldsv/sanitize-svg": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@skjnldsv/sanitize-svg/-/sanitize-svg-1.0.2.tgz",
@ -2520,6 +2531,13 @@
"node": ">=8.0.0"
}
},
"node_modules/ical.js": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/ical.js/-/ical.js-1.5.0.tgz",
"integrity": "sha512-7ZxMkogUkkaCx810yp0ZGKvq1ZpRgJeornPttpoxe6nYZ3NLesZe1wWMXDdwTkj/b5NtXT+Y16Aakph/ao98ZQ==",
"dev": true,
"peer": true
},
"node_modules/iconv-lite": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
@ -3011,6 +3029,13 @@
"linkifyjs": "^4.0.0"
}
},
"node_modules/linkifyjs": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/linkifyjs/-/linkifyjs-4.2.0.tgz",
"integrity": "sha512-pCj3PrQyATaoTYKHrgWRF3SJwsm61udVh+vuls/Rl6SptiDhgE7ziUIudAedRY9QEfynmM7/RmLEfPUyw1HPCw==",
"dev": true,
"peer": true
},
"node_modules/loader-runner": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz",
@ -4540,6 +4565,16 @@
"base64-arraybuffer": "^1.0.2"
}
},
"node_modules/uuid": {
"version": "8.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
"integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
"dev": true,
"peer": true,
"bin": {
"uuid": "dist/bin/uuid"
}
},
"node_modules/v-click-outside": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/v-click-outside/-/v-click-outside-3.2.0.tgz",

View File

@ -4,13 +4,17 @@ import "../css/mycss.css";
import { globalConfiguration } from "./modules/mainFunction.mjs";
import "./listener/main_listener";
import { getPDF } from "./pdf";
import { exportClientDevisByMonthAndYearToPdf } from "./modules/ajaxRequest.mjs";
window.addEventListener("DOMContentLoaded", function () {
globalConfiguration();
var pdf = document.getElementById("pdfDevis");
pdf.addEventListener("click",async ()=>{
getPDF('devis');
const urlParams = new URLSearchParams(window.location.search);
const clientId = urlParams.get('cli');
const year = urlParams.get('annee');
const month = urlParams.get('mois');
var exportMultipleDevisToPdfButton = this.document.getElementById("exportMultipleDevisToPdf");
exportMultipleDevisToPdfButton.addEventListener("click",function(){
exportClientDevisByMonthAndYearToPdf(clientId,year,month);
});
});

View File

@ -4,16 +4,17 @@ import "../css/mycss.css";
import { globalConfiguration } from "./modules/mainFunction.mjs";
import "./listener/main_listener";
import "./listener/invoiceListener";
import { getPDF } from "./pdf";
import { saveDocumentRecap } from "./modules/ajaxRequest.mjs";
window.addEventListener("DOMContentLoaded", function () {
globalConfiguration();
var pdf = document.getElementById("pdfFactures");
pdf.addEventListener("click",async ()=>{
getPDF('facture');
});
// var pdf = document.getElementById("pdfFactures");
// pdf.addEventListener("click",async ()=>{
// getPDF('facture');
// });
var documentRecap = document.getElementById("documentrecap");
documentRecap.addEventListener("click", async ()=> {

View File

@ -4,7 +4,7 @@ import "../css/mycss.css";
import { globalConfiguration } from "./modules/mainFunction.mjs";
import "./listener/main_listener";
import { getBibliotheques, getBijouxById, getHypodermiquesyId, getObservationsById, getproduits, saveAttestationPacemaker, saveRapportBijoux, saveRapportSoin, updateDB } from "./modules/ajaxRequest.mjs";
import { getBibliotheques, exportCareCertificate, getBijouxById, getHypodermiquesyId, getObservationsById, getproduits, saveAttestationPacemaker, saveRapportBijoux, saveRapportSoin, updateDB } from "./modules/ajaxRequest.mjs";
let bibliotheques = [];
let sortedBibliotheques = [];
@ -71,6 +71,11 @@ window.addEventListener("DOMContentLoaded", function () {
var pacemakerBtn = document.getElementById("pacemakerBtn");
var rapportSoinBtn = document.getElementById("rapportSoinBtn");
var rapportBijouxBtn = document.getElementById("rapportBijouxBtn");
var exportCareCertificateButton = document.getElementById("exportCareCertificate");
exportCareCertificateButton.addEventListener("click",function(){
exportCareCertificate({defuntId : defuntid});
})
pacemakerBtn.addEventListener("click", function(){
saveAttestationPacemaker({ numdefunt: defuntid });

View File

@ -2,7 +2,7 @@ import "@nextcloud/dialogs/dist/index.css";
import "datatables.net-dt/css/jquery.dataTables.css";
import "../css/mycss.css";
import { getArticlesById, getMailServerFrom, getProduitsById, savePdfToNextcloud} from "./modules/ajaxRequest.mjs";
import { getArticlesById, getMailServerFrom, getProduitsById, savePdfToNextcloud,exportDevisToPdf} from "./modules/ajaxRequest.mjs";
import { globalConfiguration } from "./modules/mainFunction.mjs";
import "./listener/main_listener";
import { Client } from "./objects/client.mjs";
@ -12,20 +12,14 @@ import { showError } from "@nextcloud/dialogs";
window.addEventListener("DOMContentLoaded", function () {
globalConfiguration();
const devisId = $("#devisid").data("id");
Client.getClientByIdDevis($("#devisid").data("id"));
getProduitsById();
getArticlesById();
var pdf = document.getElementById("pdf");
pdf.addEventListener("click",function(){
if(!!!document.getElementById("etp").innerText) {
showError("S'il vous plait! Veuillez d'abord selectionner un client.");
} else {
let defunt = document.getElementById("nomdefunt").innerText;
let lieusoin = document.getElementById("lieusoin").innerText;
let etp = document.getElementById("etp").innerText;
captureDevisFacture(savePdfToNextcloud, document.getElementById("dateContext").innerText, defunt, lieusoin, etp);
}
var exportDevisToPdfButton = this.document.getElementById("exportDevisToPdf");
exportDevisToPdfButton.addEventListener("click",function(){
exportDevisToPdf(devisId);
});
var mail = document.getElementById("mailGestion");

View File

@ -0,0 +1,32 @@
import {showError, showSuccess } from "@nextcloud/dialogs";
import {baseUrl} from "../modules/mainFunction.mjs";
$('body').on('click', '#exportMultipleFactureToPdf', function () {
// Access specific parameter values
const urlParams = new URLSearchParams(window.location.search);
const clientId = urlParams.get('cli');
const year = urlParams.get('annee');
const month = urlParams.get('mois');
var exportMultipleFacturePayload = {
clientId : clientId,
month : month,
year : year
};
$.ajax({
url: baseUrl + '/facture/exportFactureByClientAndMonthYearToPdf',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify(exportMultipleFacturePayload)
}).done(function (response) {
var fileName = response;
if(fileName != null){
showSuccess('Sauvegardé dans' + fileName);
return;
}
showError(t('gestion', "Les données pour sauvegarde sont vides"));
}).fail(function (response, code) {
showError(t('gestion', "Erreur dans la génération de facture multiple"));
});
});

View File

@ -736,4 +736,84 @@ export function genererDefunts() {
showMessage(t('gestion', 'There is an error'));
error(response);
});
};
/**
* Export devis to pdf
* @param {*} devisId
*/
export function exportDevisToPdf(devisId) {
if(devisId == null){
showError('Devis non trouvé');
return;
}
let payload = {
devisId : devisId
}
$.ajax({
url: baseUrl + '/devis/exportDevisToPdf',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify(payload)
}).done(function (response) {
if(response == null) {
showMessage('Le devis n\'existe pas');
return;
}
var fileNames = JSON.parse(response);
fileNames.forEach(fileName => {
showSuccess('Sauvegardé dans' + fileName);
});
}).fail(function (response, code) {
showMessage(t('gestion', 'Erreur dans l\'export du devis en PDF'));
error(response);
});
};
/**
* Export multiple devis to pdf
* @param {*} devisId
*/
export function exportClientDevisByMonthAndYearToPdf(clientId,year,month) {
let payload = {
clientId: clientId,
month : month,
year : year
};
$.ajax({
url: baseUrl + '/devis/exportDevisByClientAndMonthYearToPdf',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify(payload)
}).done(function (response) {
if(response != null) {
showSuccess('Sauvegardé dans' + response);
return;
}
showError(t('gestion', "Les données pour sauvegarde sont vides"));
}).fail(function (response, code) {
showError(t('gestion', "Erreur dans la génération de devis multiple"));
});
};
/**
* Export care certificate
* @param {*} defuntIdPayload
*/
export function exportCareCertificate(defuntIdPayload) {
$.ajax({
url: baseUrl + '/defunt/exportCareCertificate',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify(defuntIdPayload)
}).done(function (response) {
if(response == null) {
showMessage('Ce defunt n\'appartient à aucun devis.');
} else {
showSuccess('Sauvegardé dans '+ response );
}
}).fail(function (response, code) {
showMessage(t('gestion', 'There is an error'));
error(response);
});
};

View File

@ -61,7 +61,7 @@
});
if(strcmp($_GET['cli'], '')!=0 && sizeof($devis)>0) {
?>
<button class="btn btn-secondary" type="button" id="pdfDevis"><?php p($l->t('Save in Nextcloud'));?></button>
<button class="btn btn-secondary" type="button" id="exportMultipleDevisToPdf"><?php p($l->t('Save in Nextcloud'));?></button>
<?php
}
}

View File

@ -61,7 +61,7 @@
if(sizeof($factures)>0) {
?>
<?php if($showRecapButton) {?><button class="btn btn-secondary" type="button" id="documentrecap">Generer le document recapitulatif</button><?php }?>
<button class="btn btn-secondary ml-2" type="button" id="pdfFactures"><?php p($l->t('Save in Nextcloud'));?></button>
<button class="btn btn-secondary ml-2" type="button" id="exportMultipleFactureToPdf"><?php p($l->t('Save in Nextcloud'));?></button>
<?php
}
}

View File

@ -22,7 +22,10 @@
<div class="container-fluid">
<div class="d-flex justify-content-between">
<h2>Aperçu du défunt</h2>
<button id="pacemakerBtn" class="btn btn-secondary" type="button">Générer l'attestation pacemaker</button>
<div>
<button id="exportCareCertificate" class="btn btn-secondary" type="button">Générer l'attestation de soins</button>
<button id="pacemakerBtn" class="btn btn-secondary" type="button">Générer l'attestation pacemaker</button>
</div>
</div>
<hr>
<div class="col-6" style="margin-bottom: 32px">

View File

@ -109,7 +109,7 @@
</div>
<hr>
<div>
<button id="pdf" type="button" class="mb-2 btn btn-outline-success" data-html2canvas-ignore data-name=""><?php p($l->t('Save in Nextcloud'));?></button>
<button id="exportDevisToPdf" type="button" class="mb-2 btn btn-outline-success"><?php p($l->t('Save in Nextcloud'));?></button>
<button id="mailGestion" type="button" class="mb-2 btn btn-outline-success sendmail" data-html2canvas-ignore data-name=""><?php p($l->t('Send by email'));?></button>
</div>
<div class="mt-0 table-responsive">