* * @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\InvoiceRecap\PdfHandler; use DateTime; use \FPDF; use IntlDateFormatter; use OCA\Gestion\Helpers\FileExportHelpers; use OCA\Gestion\Helpers\PriceHelpers; class InvoiceRecapPdfHandler extends FPDF { private $invoices = []; private $logo = null; private $logoPath = "/var/www/html/data/admin/files/.gestion/"; private $configs = []; private $signatureImageExist = false; // 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('ComicSans', '', 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('ComicSans', 'B', 8); // $this->Cell(0, 10, utf8_decode(html_entity_decode($this->devisData['configuration']->legal_one)), 0, 0, 'C'); // } public function SetInvoiceRecapFacture(array $invoices,array $configs,$logo = null,$signatureImageExist = false){ $this->invoices = $invoices; $this->logo = $logo; $this->signatureImageExist = $signatureImageExist; $this->configs = $configs; } public function SetInvoiceRecap(){ $data_temp = $this->invoices; $isLogoExist = $this->logo != null; foreach ($data_temp as $key_annee => $annee) { foreach ($annee as $key_mois => $mois) { foreach ($mois as $key_client => $client) { $pdf = new FPDF(); $pdf->AddFont('ComicSans','','Comic Sans MS.php'); $pdf->AddFont('ComicSans','B','comic-sans-bold.php'); $current_client = ''; $clientAddress = ''; $clientCity = ''; $date_facture = ''; $j=1; foreach ($client as $key => $facture) { if($j==1) { $current_client = $facture['prenoms_client'].' '.$facture['nom_client']; $date_facture = $facture['date_facture']; $clientAddresses = FileExportHelpers::GetAddressAndCityFromAddress($facture['adresse_client']); $clientAddress = $clientAddresses['address']; $clientCity = $clientAddresses['city']; } $j++; } $date_temp = date("t-m-Y", strtotime($date_facture)); $formatter = new IntlDateFormatter('fr_FR', IntlDateFormatter::LONG, IntlDateFormatter::NONE); $date_formated = $formatter->format(DateTime::createFromFormat('d-m-Y', $date_temp)); $pdf->AddPage(); // on sup les 2 cm en bas $pdf->SetAutoPagebreak(False); $pdf->SetMargins(0,0,10); // logo : 80 de largeur et 55 de hauteur if($isLogoExist){ $pdf->Image($this->logoPath."logo.png", 10, 10, 75, 25); } // adresse du facture $pdf->SetFont('ComicSans','B',size: 11); $pdf->SetY(40); $pdf->Cell( 0, 8, utf8_decode($current_client), 0, 1, 'R'); $pdf->Cell( 0, 8, trim(utf8_decode(html_entity_decode($clientAddress))), 0,1,'R'); if($clientCity != ''){ $pdf->Cell( 0, 8, trim(utf8_decode(html_entity_decode($clientCity))), 0, 1, 'R'); } // date facture $pdf->SetFont('ComicSans','',11); $pdf->Cell( 0, 8, "Saint Senoux, le ".utf8_decode($date_formated), 0, 1, 'R'); // observations $pdf->SetFont( "ComicSans", "BU", 10 ); $pdf->SetXY( 10, 85 ) ; $pdf->Cell($pdf->GetStringWidth("Objet:"), 0, "Objet:", 0, "L"); $objet = utf8_decode("Récapitulatif Facturation du mois de ").strtoupper($this->convert_special_char(explode(' ', $date_formated)[1])); $pdf->SetFont( "ComicSans", "", 10 ); $pdf->SetXY( $pdf->GetStringWidth("Objet")+15, 85 ) ; $pdf->Cell($pdf->GetStringWidth($objet), 0, $objet, 0, "L"); $pdf->SetFont( "ComicSans", "", 10 ); $pdf->SetXY( $pdf->GetStringWidth("Objet")+15, 95 ); $pdf->Cell($pdf->GetStringWidth("Madame, Monsieur"), 0, "Madame, Monsieur", 0, "L"); $text1 = utf8_decode("Veuillez trouver ci-dessous le récapitulatif de la facturation du mois de ").strtoupper($this->convert_special_char(explode(' ', $date_formated)[1]))."."; $text2 = utf8_decode("Vous en souhaitant bonne réception."); $text3 = utf8_decode("Veuillez agréer, Madame, Monsieur, mes salutations les meilleures."); $pdf->SetFont( "ComicSans", "", 10 ); $pdf->SetXY( $pdf->GetStringWidth("Objet")+15, 105 ) ; $pdf->Cell($pdf->GetStringWidth($text1), 0, $text1, 0, "L"); $pdf->SetFont( "ComicSans", "", 10 ); $pdf->SetXY( $pdf->GetStringWidth("Objet")+15, 110 ) ; $pdf->Cell($pdf->GetStringWidth($text2), 0, $text2, 0, "L"); $pdf->SetFont( "ComicSans", "", 10 ); $pdf->SetXY( $pdf->GetStringWidth("Objet")+15, 120 ) ; $pdf->Cell($pdf->GetStringWidth($text3), 0, $text3, 0, "L"); // signature $pdf->SetFont('ComicSans','',11); $pdf->SetXY( 145, 145 ); $pdf->Cell( $pdf->GetStringWidth($this->configs[0]->nom.' '.$this->configs[0]->prenom), 0, utf8_decode(html_entity_decode($this->configs[0]->nom.' '.$this->configs[0]->prenom)), 0, 0, 'L'); if($this->signatureImageExist){ $pdf->Image($this->logoPath."sign.png", 135, 150, 55, 30); } $y0 = 260; $pageWidth = $pdf->GetPageWidth(); //Positionnement en bas et tout centrer $pdf->SetFont('ComicSans','',7); $pdf->SetXY( 1, $y0 + 4 ); $pdf->Cell( $pageWidth, 5, utf8_decode(html_entity_decode($this->configs[0]->mentions_default)), 0, 0, 'C'); $pdf->SetXY( 1, $y0 + 8 ); $pdf->Cell( $pageWidth, 5, utf8_decode(html_entity_decode($this->configs[0]->legal_one)), 0, 0, 'C'); $pdf->SetXY( 1, $y0 + 12 ); $pdf->Cell( $pageWidth, 5, utf8_decode(html_entity_decode($this->configs[0]->legal_two)), 0, 0, 'C'); $pdf->SetXY( 1, $y0 + 16 ); $pdf->Cell( $pageWidth, 5, utf8_decode(html_entity_decode($this->configs[0]->telephone)), 0, 0, 'C'); /*$pdf->SetXY( 1, $y0 + 16 ); $pdf->Cell( $pageWidth, 5, utf8_decode("SIREN 751621293"), 0, 0, 'C');*/ $num_page = 1; $nb_page = ceil(sizeof($client) / 26); $index_facture_position = 0; $max_nb_toget = (sizeof($client)<=26)?sizeof($client):26; $montant_ht_total = 0; $montant_tva_total = 0; $montant_ttc_total = 0; while ($num_page <= $nb_page) { $pdf->AddPage(); // on sup les 2 cm en bas $pdf->SetAutoPagebreak(False); $pdf->SetMargins(0,0,10); if($isLogoExist){ $pdf->Image($this->logoPath."logo.png", 10, 10, 75, 25); } // n° page en haute à droite if($nb_page>1){ $pdf->SetXY( 120, 5 ); $pdf->SetFont( "ComicSans", "B", 9 ); $pdf->Cell( 160, 8, $num_page . '/' . $nb_page, 0, 0, 'C'); } // date facture $pdf->SetFont('ComicSans','',11); $pdf->SetY(10); $pdf->Cell( 0, 8,"Saint Senoux, le ".utf8_decode($date_formated), 0, 0, 'R'); // n° facture, date echeance et reglement et obs $pdf->SetLineWidth(0.1); $pdf->SetFillColor(255); $pdf->Rect(114, 20, 85, 8, "DF"); $pdf->SetXY( 114, 20 ); $pdf->SetFont( "ComicSans", "B", 12 ); $pdf->Cell( 85, 8, 'FACTURE N'.utf8_decode('°').' FAC/'.$key_annee.'/'.strtoupper($this->convert_special_char(explode(' ', $date_formated)[1])), 0, 0, 'C'); // adresse du facture $pdf->SetFont('ComicSans','B',11); $pdf->SetY(y: 32); $pdf->Cell( 0, 6, utf8_decode($current_client), 0, 1, 'R'); $pdf->Cell( 0, 6, trim(utf8_decode(html_entity_decode($clientAddress))), 0, 1, 'R'); if($clientCity != ''){ $pdf->Cell( 0, 6, trim(utf8_decode(html_entity_decode($clientCity))), 0, 1, 'R'); } $pdf->Cell( 0, 6, ' Siret: ' . FileExportHelpers::FormatTextForExport($tvaIntraCommuValue), 0, 1, 'R'); $pdf->Cell( 0, 6, 'Email: ' . utf8_decode(html_entity_decode($facture['mail_client'])), 0, 1, 'R'); // *********************** // le cadre des articles // *********************** // cadre avec 18 lignes max ! et 118 de hauteur --> 80 + 118 = 198 pour les traits verticaux $pdf->SetLineWidth(0.1); $pdf->Rect(5, 80, 200, 153, "D"); // cadre titre des colonnes $pdf->Line(5, 90, 205, 90); // les traits verticaux colonnes $pdf->Line(145, 80, 145, 233); $pdf->Line(163, 80, 163, 233); if($num_page == $nb_page) $pdf->Line(183, 80, 183, 240); else $pdf->Line(183, 80, 183, 233); // titre colonne $pdf->SetXY( 1, 81 ); $pdf->SetFont('ComicSans','B',8); $pdf->Cell( 140, 8, "OBJET", 0, 0, 'C'); $pdf->SetXY( 147, 81 ); $pdf->SetFont('ComicSans','B',8); $pdf->Cell( 13, 8, "H.T.", 0, 0, 'C'); $pdf->SetXY( 168, 81 ); $pdf->SetFont('ComicSans','B',8); $pdf->Cell( 10, 8, "TVA 20%", 0, 0, 'C'); $pdf->SetXY( 183, 81 ); $pdf->SetFont('ComicSans','B',8); $pdf->Cell( 22, 8, "T.T.C", 0, 0, 'C'); // (new DateTime($facture['date_soin']))->format('d-M') $formatter_ds = new IntlDateFormatter('fr_FR', IntlDateFormatter::SHORT, IntlDateFormatter::NONE); // Set the pattern for the formatter to "d-MMMM" to display the day and month name in French $formatter_ds->setPattern('dd-MMM'); //recuperation des factures $y_facture = 90; $init_index = $index_facture_position; for ($index_facture_position; $index_facture_position < ($init_index + $max_nb_toget) ; $index_facture_position++) { $date_soin_temp = new DateTime($client[$index_facture_position]['date_soin']); $pdf->SetXY( 6, $y_facture ); $pdf->SetFont('ComicSans','',8); $pdf->Cell( 28, 8, $client[$index_facture_position]['num'], 0, 0, ''); $pdf->SetXY( 32, $y_facture ); $pdf->SetFont('ComicSans','',8); $pdf->Cell( 18, 8, utf8_decode($formatter_ds->format($date_soin_temp)), 0, 0, ''); $pdf->SetXY( 50, $y_facture ); $pdf->SetFont('ComicSans','',8); $pdf->Cell( 38, 8, utf8_decode(html_entity_decode($client[$index_facture_position]['defunt'])), 0, 0, ''); $pdf->SetXY( 90, $y_facture ); $pdf->SetFont('ComicSans','',8); $pdf->Cell( 28, 8, utf8_decode(html_entity_decode($client[$index_facture_position]['produit_references'])), 0, 0, ''); $pdf->SetXY( 147, $y_facture ); $pdf->SetFont('ComicSans','',8); $pdf->Cell( 13, 8, number_format($client[$index_facture_position]['montant_htc'],2,'.','').chr(128), 0, 0, 'C'); $pdf->SetXY( 168, $y_facture ); $pdf->SetFont('ComicSans','',8); $pdf->Cell( 10, 8, number_format($client[$index_facture_position]['montant_tva'],2,'.','').chr(128), 0, 0, 'C'); $pdf->SetXY( 183, $y_facture ); $pdf->SetFont('ComicSans','',8); $pdf->Cell( 22, 8, number_format($client[$index_facture_position]['montant_ttc'],2,'.','').chr(128), 0, 0, 'C'); $montant_ht_total = $montant_ht_total+$client[$index_facture_position]['montant_htc']; $montant_tva_total = $montant_tva_total+$client[$index_facture_position]['montant_tva']; $montant_ttc_total = $montant_ttc_total+$client[$index_facture_position]['montant_ttc']; $y_facture=$y_facture+5; } $nb_facture_chargee = $index_facture_position+1; $reste_a_chargee = sizeof($client) - $nb_facture_chargee; $max_nb_toget = ($reste_a_chargee <= 26) ? $reste_a_chargee+1 : 26; // si derniere page alors afficher cadre des TVA if ($num_page == $nb_page) { $pdf->Line(5, 225, 205, 225); $pdf->SetFont('ComicSans','B',8); $pdf->SetXY( 5, 225 ); $pdf->Cell( 140, 8, 'TOTAL', 0, 0, 'C'); $pdf->SetFont('ComicSans','',8); $pdf->SetXY( 147, 225 ); $pdf->Cell( 13, 8, number_format($montant_ht_total,2,'.','').chr(128), 0, 0, 'C'); $pdf->SetFont('ComicSans','',8); $pdf->SetXY( 168, 225 ); $pdf->Cell( 10, 8, number_format($montant_tva_total,2,'.','').chr(128), 0, 0, 'C'); $pdf->SetFont('ComicSans','',8); $pdf->SetXY( 183, 225 ); $pdf->Cell( 22, 8, number_format($montant_ttc_total,2,'.','').chr(128), 0, 0, 'C'); $pdf->Rect(145, 233, 60, 7, "D"); $pdf->SetFont('ComicSans','B',8); $pdf->SetXY( 147, 233 ); $pdf->Cell( 30, 6.5, 'TOTAL TTC', 0, 0, 'C'); $pdf->SetFont('ComicSans','B',8); $pdf->SetXY( 183, 233 ); $pdf->Cell( 22, 6.5, number_format($montant_ttc_total,2,'.','').chr(128), 0, 0, 'C', true); } $y1 = 245; $pdf->SetFillColor(255); $pdf->SetTextColor(0, 0, 0); $pdf->SetFont('ComicSans','',9); $pdf->SetXY( 10, $y1 );$pdf->Cell( $pdf->GetPageWidth(), 4, utf8_decode("Loi N° 92-442 du 31 décembre 1992: La présente facture est payable en comptant a réception."), 0, 0, 'L'); $pdf->SetXY( 10, $y1 + 4 );$pdf->Cell( $pdf->GetPageWidth(), 4, utf8_decode("Indemnité forfaitaire pour frais de recouvrement due en cas de retard de paiement: 40").chr(128), 0, 0, 'L'); $pdf->SetXY( 10, $y1 + 8 );$pdf->Multicell( $pdf->GetPageWidth()-20, 4, utf8_decode("Toute somme non payée dans les trente jours est susceptible de porter intérets à un taux égal à une fois et demi le taux de l'intéret légal."), 0, 0, 'L'); // ************************** // pied de page // ************************** $pdf->SetFont('ComicSans','',7); $pdf->SetXY( 1, $y0 + 4 ); $pdf->Cell( $pageWidth, 5, utf8_decode(html_entity_decode($this->configs[0]->mentions_default)), 0, 0, 'C'); $pdf->SetXY( 1, $y0 + 8 );$pdf->Cell( $pageWidth, 5, utf8_decode(html_entity_decode($this->configs[0]->legal_one)), 0, 0, 'C'); $pdf->SetXY( 1, $y0 + 12 );$pdf->Cell( $pageWidth, 5, utf8_decode(html_entity_decode($this->configs[0]->legal_two)), 0, 0, 'C'); $pdf->SetXY( 1, $y0 + 16 );$pdf->Cell( $pageWidth, 5, utf8_decode(html_entity_decode($this->configs[0]->telephone)), 0, 0, 'C'); /*$pdf->SetXY( 1, $y0 + 16 ); $pdf->Cell( $pageWidth, 5, utf8_decode("SIREN 751621293"), 0, 0, 'C');*/ $num_page++; } $ff_pdf = html_entity_decode($this->configs[0]->path).'/DOCUMENTS RECAPITULATIFS/'.$key_annee.'/'.$key_mois.' '.strtoupper($this->convert_special_char(explode(' ', $date_formated)[1])).'/'.strtoupper($this->convert_special_char($current_client)).'_RECAP_FACTURE_'.strtoupper($this->convert_special_char(explode(' ', $date_formated)[1])).'_'.$key_annee.'.pdf'; $this->storage->newFile($ff_pdf); $pdfContent = $pdf->Output('','S'); $file_pdf = $this->storage->get($ff_pdf); $file_pdf->putContent($pdfContent); } } } } 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; } }