365 lines
14 KiB
PHP
365 lines
14 KiB
PHP
<?php
|
|
|
|
require_once(__DIR__ .'/../vendor/tecnickcom/tcpdf/tcpdf.php'); // Include the main TCPDF library
|
|
require_once(__DIR__ .'/../vendor/phpqrcode/qrlib.php');
|
|
|
|
|
|
class MYPDF extends TCPDF {
|
|
public function Header() {
|
|
$this->Image('images/logo_koriolan.png', 10, 10, 60, 0, 'PNG', 'https://koriolan.tech');
|
|
}
|
|
|
|
public function Footer() {
|
|
$this->SetFont('helvetica', '', 7);
|
|
$this->SetTextColor(150, 150, 150);
|
|
|
|
// Partie gauche :
|
|
$this->SetXY(10, -23);
|
|
$this->Cell(90, 10, 'Koriolan', 0, false, 'L');
|
|
$this->SetXY(10, -19);
|
|
$this->Cell(90, 10, 'SASU au capital social de 50 000€', 0, false, 'L');
|
|
$this->SetXY(10, -15);
|
|
$this->Cell(90, 10, '6 rue Grange Bruyère - 69110 Sainte-Foy-Lès-Lyon - FRANCE', 0, false, 'L');
|
|
|
|
// Partie droite :
|
|
$this->SetXY(110, -23);
|
|
$this->Cell(90, 10, 'RCS Lyon 879 809 341', 0, false, 'R');
|
|
$this->SetXY(110, -19);
|
|
$this->Cell(90, 10, 'SIRET 879 809 341 00016', 0, false, 'R');
|
|
$this->SetXY(110, -15);
|
|
$this->Cell(90, 10, 'TVA Intraco. FR29 879 809 341', 0, false, 'R');
|
|
}
|
|
|
|
public function CreateTextBox($textval, $x = 0, $y = 0, $width = 0, $height = 10, $fontsize = 10, $fontstyle = '', $align = 'L', $border = 0) {
|
|
$this->SetXY($x, $y);
|
|
$this->SetFont('helvetica', $fontstyle, $fontsize);
|
|
$this->Cell($width, $height, $textval, 0, false, $align);
|
|
}
|
|
}
|
|
|
|
|
|
//********************************************************************************************************************************
|
|
// Fonction : Génère le document PDF à partir des données reçues en paramètres
|
|
// Reçoit : une autre concernant la pièce ('Commande', 'Facture') et ses attributs, une variable concernant le client,
|
|
// et une autre contenant les lignes de la pièce. Le fichier généré est stocké dans 'documents/commandes' ou 'documents/factures'.
|
|
// Retour : 0 si Ok, -1 si erreur
|
|
//********************************************************************************************************************************
|
|
function document_pdf($piece, $client, $lignes)
|
|
{
|
|
|
|
switch($piece['type'])
|
|
{
|
|
case "commande":
|
|
{
|
|
$nom_piece = $_SESSION['textes']['fonctions_pdf']['document']['piece']['type_commande'];
|
|
$rep = "commandes";
|
|
break;
|
|
}
|
|
case "facture":
|
|
{
|
|
$nom_piece = $_SESSION['textes']['fonctions_pdf']['document']['piece']['type_facture'];
|
|
$rep = "factures";
|
|
break;
|
|
}
|
|
default: return(-1);
|
|
}
|
|
|
|
$pdf = new MYPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
|
|
|
|
// set document (meta) information :
|
|
$pdf->SetCreator(PDF_CREATOR);
|
|
$pdf->SetAuthor('Koriolan');
|
|
$pdf->SetTitle($nom_piece.' '.$piece['no']);
|
|
$pdf->SetSubject('ShipHeart');
|
|
$pdf->SetKeywords('ShipHeart by Koriolan');
|
|
|
|
$pdf->SetTextColor(0, 69, 99);
|
|
$pdf->SetFont('helvetica', '', 10);
|
|
|
|
$pdf->AddPage();
|
|
|
|
// L'abscisse x varie de 10 à 200 (soit une marge de 10 à gauche et 10 à droite)
|
|
|
|
// ---------------------------------------------------------
|
|
// Adresse du client :
|
|
$x = 120; // Doit rester < 200 qui est la marge droite !
|
|
$y = 30;
|
|
$pdf->CreateTextBox($client['entreprise'], $x, $y, (200 - $x), 12, 12, 'B', 'L');
|
|
$y += 6;
|
|
$pdf->CreateTextBox($client['nom_complet'], $x, $y, (200 - $x), 10, 10, '', 'L');
|
|
$y += 5;
|
|
$pdf->CreateTextBox($client['rue'], $x, $y, (200 - $x), 10, 10, '', 'L');
|
|
$y += 5;
|
|
$pdf->CreateTextBox($client['ville_complete'], $x, $y, (200 - $x), 10, 10, '', 'L');
|
|
$y += 5;
|
|
$pdf->CreateTextBox($client['libelle_pays'], $x, $y, (200 - $x), 10, 10, '', 'L');
|
|
|
|
|
|
// ---------------------------------------------------------
|
|
// N° de commande :
|
|
$x = 10;
|
|
$y += 10;
|
|
$pdf->CreateTextBox($nom_piece.' '.$piece['no'], $x, $y, (200 - $x), 20, 20, 'B', 'L');
|
|
|
|
// ---------------------------------------------------------
|
|
// Date :
|
|
$x = 120;
|
|
$y += 15;
|
|
|
|
$pdf->CreateTextBox('Date : '.date(''.$_SESSION['textes']['all']['all']['date']['format_d_m_y'].''), $x, $y, (200 - $x), 10, 10, '', 'R');
|
|
|
|
// ---------------------------------------------------------
|
|
// Tableau
|
|
$x = 10;
|
|
$y += 15;
|
|
$pdf->Line($x, $y, (210 - $x), $y); // Ligne horizontale
|
|
|
|
$x = 10;
|
|
// $y += 5;
|
|
$largeur_1 = 90;
|
|
$largeur_2 = 20;
|
|
$largeur_3 = 30;
|
|
$largeur_4 = 20;
|
|
$largeur_5 = 30;
|
|
$pdf->CreateTextBox($_SESSION['textes']['fonctions_pdf']['document']['piece']['designation_titre'], $x, $y, $largeur_1, 10, 10, 'B', 'L', 1); // Ligne d'entête
|
|
$x += $largeur_1;
|
|
$pdf->CreateTextBox($_SESSION['textes']['fonctions_pdf']['document']['piece']['quantite_titre'], $x, $y, $largeur_2, 10, 10, 'B', 'C', 1);
|
|
$x += $largeur_2;
|
|
$pdf->CreateTextBox($_SESSION['textes']['fonctions_pdf']['document']['piece']['pu_ht_titre'], $x, $y, $largeur_3, 10, 10, 'B', 'R', 1);
|
|
$x += $largeur_3;
|
|
$pdf->CreateTextBox($_SESSION['textes']['fonctions_pdf']['document']['piece']['taux_tva_titre'], $x, $y, $largeur_4, 10, 10, 'B', 'C', 1);
|
|
$x += $largeur_4;
|
|
$pdf->CreateTextBox($_SESSION['textes']['fonctions_pdf']['document']['piece']['pt_ttc_titre'], $x, $y, $largeur_5, 10, 10, 'B', 'R', 1);
|
|
|
|
$x = 10;
|
|
$y += 10;
|
|
$pdf->Line($x, $y, (210 - $x), $y); // Ligne horizontale
|
|
|
|
$x = 10;
|
|
// $y += 5;
|
|
for ($i = 0; $i < $piece['nb_lignes']; $i ++)
|
|
{
|
|
$pdf->CreateTextBox($lignes[$i]['designation'],
|
|
$x, $y, $largeur_1, 10, 10, '', 'L');
|
|
$x += $largeur_1;
|
|
$pdf->CreateTextBox($lignes[$i]['qte'],
|
|
$x, $y, $largeur_2, 10, 10, '', 'C');
|
|
$x += $largeur_2;
|
|
$pdf->CreateTextBox(number_format($lignes[$i]['pu_ht'], 2, ".", " ").' €',
|
|
$x, $y, $largeur_3, 10, 10, '', 'R');
|
|
$x += $largeur_3;
|
|
$pdf->CreateTextBox(number_format($lignes[$i]['taux_tva'], 2, ".", " ").' %',
|
|
$x, $y, $largeur_4, 10, 10, '', 'C');
|
|
$x += $largeur_4;
|
|
$pdf->CreateTextBox(number_format(($lignes[$i]['qte'] * $lignes[$i]['pu_ht'] * (1 + ($lignes[$i]['taux_tva']/100))), 2, ".", " ").' €',
|
|
$x, $y, $largeur_5, 10, 10, '', 'R');
|
|
$x = 10;
|
|
$y += 5;
|
|
|
|
if ($y > 260) // Détection d'un saut de page nécessaire
|
|
{
|
|
$y = 30;
|
|
$pdf->AddPage();
|
|
}
|
|
}
|
|
|
|
// Ligne horizontale :
|
|
$x = 10;
|
|
$y += 5;
|
|
$pdf->Line($x, $y, (210 - $x), $y);
|
|
|
|
// ---------------------------------------------------------
|
|
// Vérification si un saut de page est nécessaire :
|
|
if ($y > 260)
|
|
{
|
|
$y = 30;
|
|
$pdf->AddPage();
|
|
}
|
|
|
|
// ---------------------------------------------------------
|
|
// Totaux :
|
|
$x = 10;
|
|
// $y += 5;
|
|
$pdf->CreateTextBox('TOTAL', $x, $y, $largeur_1, 10, 11, 'B', 'R');
|
|
$x += $largeur_1;
|
|
$x += $largeur_2;
|
|
$pdf->CreateTextBox(number_format($piece['total_ht'], 2, ".", " ").' €',
|
|
$x, $y, $largeur_3, 10, 11, '', 'R');
|
|
$x += $largeur_3;
|
|
$x += $largeur_4;
|
|
$pdf->CreateTextBox(number_format($piece['total_ttc'], 2, ".", " ").' €',
|
|
$x, $y, $largeur_5, 10, 11, 'B', 'R');
|
|
|
|
|
|
// ---------------------------------------------------------
|
|
// Commentaire :
|
|
if ($piece['commentaire'] != "")
|
|
{
|
|
if ($y > 260) // Vérification si un saut de page est nécessaire
|
|
{
|
|
$y = 30;
|
|
$pdf->AddPage();
|
|
}
|
|
|
|
$x = 10;
|
|
$y += 30;
|
|
$pdf->SetFont('helvetica', '', 10);
|
|
$pdf->MultiCell((200 - $x), 10, $piece['commentaire'],
|
|
'TRBL', 'J', 0, 1, $x, $y, true, 0, true, true);
|
|
}
|
|
|
|
|
|
// ---------------------------------------------------------
|
|
// Ajout des numéros de page :
|
|
// NB : les fonctions usuelles ('getAliasNumPage()' et 'getAliasNbPages()') dans le Header ou le Footer fonctionnent bien mais posent des soucis d'alignement...
|
|
$nb_pages = $pdf->getNumPages();
|
|
|
|
for($i = 1; $i < ($nb_pages + 1); $i ++)
|
|
{
|
|
$pdf->setPage($i);
|
|
$pdf->SetFont('helvetica', '', 10);
|
|
$pdf->SetTextColor(0, 69, 99);
|
|
$pdf->SetXY(150,10);
|
|
$pdf->Cell(50, 10, 'Page '.$i.'/'.$nb_pages, 0, false, 'R');
|
|
}
|
|
|
|
// ---------------------------------------------------------
|
|
// Fermeture de l'objet PDF et enreigistrement du fichier :
|
|
ob_clean(); // Semble nécessaire ; sinon erreur du 'output' suivant
|
|
$pdf_string = $pdf->Output('pseudo.pdf', 'S'); // export du flux dans une chaine (le nom du fichier est ignoré...)
|
|
|
|
// Copie de cette chaine dans le fichier final (cette solution en 2 temps permet d'éviter de devoir utiliser un nom de fichier absolu (semble obligatoire avec Output et l'option 'F')
|
|
file_put_contents('../../documents/'.$rep.'/'.$piece['no'].'.pdf', $pdf_string);
|
|
|
|
return(0);
|
|
}
|
|
|
|
|
|
|
|
class MYPDF2 extends TCPDF {
|
|
public function Header() {
|
|
// $this->Image('images/logo_shipheart.png', 10, 10, 60, 0, 'PNG', 'https://shipheart.tech');
|
|
}
|
|
|
|
public function CreateTextBox($textval, $x = 0, $y = 0, $width = 0, $height = 10, $fontsize = 10, $fontstyle = '', $align = 'J', $border = 0) {
|
|
$this->SetXY($x, $y);
|
|
$this->SetFont('helvetica', $fontstyle, $fontsize);
|
|
$this->SetFillColor(255,255,255);
|
|
$this->MultiCell($width, $height, $textval, 0, $align, false);
|
|
}
|
|
}
|
|
|
|
|
|
//********************************************************************************************************************************
|
|
// Fonction : Génère le document PDF à partir des données reçues en paramètres
|
|
// Reçoit : type du document (1er code généré pour le bateau, code généré par un autre utilisateur)
|
|
// client concerné a qui on envoie le pdf et le code d'accès pour générer le code QR.
|
|
// Retour : 0 si Ok, -1 si erreur
|
|
//********************************************************************************************************************************
|
|
function code_acces_pdf($code, $no, $no_serie = "XX:XX:XX:XX:XX:XX", $client = "")
|
|
{
|
|
$nom_piece = $no."_Code_acces_bateau_".$no_serie;
|
|
|
|
|
|
|
|
$pdf = new MYPDF2('LANDSCAPE', 'px', 'A4', true, 'UTF-8', false);
|
|
|
|
// set document (meta) information :
|
|
$pdf->SetCreator(PDF_CREATOR);
|
|
$pdf->SetAuthor('Koriolan');
|
|
$pdf->SetTitle($nom_piece);
|
|
$pdf->SetSubject('ShipHeart');
|
|
$pdf->SetKeywords('ShipHeart by Koriolan');
|
|
|
|
$pdf->SetTextColor(0, 69, 99);
|
|
$pdf->SetFont('helvetica', '', 10);
|
|
|
|
$pdf->AddPage();
|
|
$pdf->SetDrawColor(217,217,217);
|
|
$pdf->Line(421, 0, 421, 595);
|
|
|
|
// First page
|
|
$pdf->Image('images/logo_shipheart.png', 506, 214, 252, 167, 'PNG', 'https://shipheart.tech');
|
|
|
|
// Firth page
|
|
$pdf->Image('images/logo_shipheart.png', 12, 12, 64, 45, 'PNG', 'https://shipheart.tech');
|
|
|
|
$pdf->CreateTextBox("Nous vous remercions pour votre confiance et sommes ravis de vous offrir un accès complet aux informations de votre bateau via notre platforme Ship2net.
|
|
|
|
We thank you for your trust and are delighted to offer you full access to your boat information via our Ship2net platform.", 52, 166, 317, 195, 12);
|
|
|
|
$pdf->CreateTextBox($no_serie, 0, 520, 421, 46, 12, '', 'C', 0);
|
|
|
|
// $pdf->AddPage();
|
|
$pdf->SetDrawColor(217,217,217);
|
|
$pdf->Line(421, 0, 421, 595);
|
|
|
|
// Second page
|
|
$pdf->Image('images/logo_shipheart.png', 12, 12, 64, 45, 'PNG', 'https://shipheart.tech');
|
|
|
|
$pdf->Image('images/logo_shipheart.png', 766, 12, 64, 45, 'PNG', 'https://shipheart.tech');
|
|
|
|
$pdf->CreateTextBox("Pour activer votre accès au bateau merci de scanner le QR code ci-joint et de vous connecter à votre profil ShipMember existant ou d'en créer un.
|
|
|
|
To activate your boat access please scan the attached QR code and log in to your existing ShipMember profile or create one.", 52, 218, 317, 160, 12);
|
|
|
|
// Third page
|
|
$pdf->Image(generateCode($code), 546, 216, 164, 164, 'PNG', Url_activation_code_acces($code));
|
|
|
|
|
|
// ---------------------------------------------------------
|
|
// Fermeture de l'objet PDF et enreigistrement du fichier :
|
|
ob_clean(); // Semble nécessaire ; sinon erreur du 'output' suivant
|
|
$pdf_string = $pdf->Output('pseudo.pdf', 'S'); // export du flux dans une chaine (le nom du fichier est ignoré...)
|
|
|
|
// Copie de cette chaine dans le fichier final (cette solution en 2 temps permet d'éviter de devoir utiliser un nom de fichier absolu (semble obligatoire avec Output et l'option 'F')
|
|
file_put_contents('temp/PDF/'.$nom_piece.'.pdf', $pdf_string);
|
|
|
|
$_SESSION['pdf']['src'] = 'temp/PDF/'.$nom_piece.'.pdf';
|
|
|
|
// Sauvegarder le pdf automatiquement
|
|
header("Cache-Control: public");
|
|
header("Content-Description: File Transfer");
|
|
header("Content-Disposition: attachment; filename=".$nom_piece.".pdf");
|
|
header("Content-Type: application/zip");
|
|
header("Content-Transfer-Encoding: binary");
|
|
|
|
// Read the file
|
|
readfile($_SESSION['pdf']['src']);
|
|
|
|
// Suppression du pdf et codeqr du serveur
|
|
unlink('temp/CodeQR/'.$code.'.png');
|
|
unlink($_SESSION['pdf']['src']);
|
|
return(0);
|
|
}
|
|
|
|
//********************************************************************************************************************************
|
|
// Fonction : URL d'activation d'un code d'accès bateau, portée par le QR code ET par le lien cliquable du PDF d'invitation.
|
|
// Construite à partir de URL_SITE (definitions.php) : plus d'adresse écrite en dur (synthèse §47).
|
|
// Reçoit : le code d'accès
|
|
// Retour : l'URL complète
|
|
//********************************************************************************************************************************
|
|
function Url_activation_code_acces($code)
|
|
{
|
|
return 'https://'.URL_SITE.'/shipmembers.php?code_acces='.urlencode($code);
|
|
}
|
|
|
|
function generateCode($code){
|
|
$tempDir = "temp/CodeQR/";
|
|
|
|
$codeContents = Url_activation_code_acces($code);
|
|
|
|
$fileName = $code.'.png';
|
|
|
|
$pngAbsoluteFilePath = $tempDir.$fileName;
|
|
$urlRelativeFilePath = $tempDir.$fileName;
|
|
|
|
// generating
|
|
if (!file_exists($pngAbsoluteFilePath)) {
|
|
QRcode::png($codeContents, $pngAbsoluteFilePath);
|
|
}
|
|
return $urlRelativeFilePath;
|
|
}
|
|
|
|
|