7 date_default_timezone_set('Europe/Paris');
9 //XXX: Append FPDF paths and qrlib to include_path
10 ini_set('include_path', ini_get('include_path') . PATH_SEPARATOR
. '/usr/share/php/fpdf' . PATH_SEPARATOR
. '/usr/share/php/fpdf/font' . PATH_SEPARATOR
. '../vendor/phpqrcode');
13 define('FPDF_FONTPATH', '../vendor/font');
23 $reasons = ['travail', 'achats', 'sante', 'famille', 'handicap', 'sport_animaux', 'convocation', 'missions', 'enfants'];
27 empty($_REQUEST['type']) ||
28 empty($_REQUEST['lastname']) ||
29 empty($_REQUEST['firstname']) ||
30 empty($_REQUEST['birthdate']) ||
31 empty($_REQUEST['birthplace']) ||
32 empty($_REQUEST['address']) ||
33 empty($_REQUEST['zipcode']) ||
34 empty($_REQUEST['city']) ||
35 empty($_REQUEST['function']) ||
36 empty($_REQUEST['location']) ||
37 empty($_REQUEST['date']) ||
38 empty($_REQUEST['time'])
41 //XXX: round it to previous 5 minute
42 $time = floor(strtotime('now')/300)*300;
48 if (empty($_REQUEST['type'])) {
49 if (!empty($_SERVER['SCRIPT_URL'])) {
50 if ($_SERVER['SCRIPT_URL'] == '/bnp') {
52 } elseif ($_SERVER['SCRIPT_URL'] == '/poltrone') {
53 $selected = 'poltrone';
54 } elseif ($_SERVER['SCRIPT_URL'] == '/convoc') {
55 $selected = 'convocation';
56 } elseif ($_SERVER['SCRIPT_URL'] == '/achat') {
58 } elseif ($_SERVER['SCRIPT_URL'] == '/sport') {
59 $selected = 'sport_animaux';
60 } elseif ($_SERVER['SCRIPT_URL'] == '/travail') {
61 $selected = 'travail';
65 if ($_REQUEST['type'] == 'bnp' || $_REQUEST['type'] == 'poltrone' || in_array($_REQUEST['type'], $reasons)) {
66 $selected = $_REQUEST['type'];
73 <title
>Ausweis generator
</title
>
86 justify
-content
: space
-between
;
96 border
: .1rem solid black
;
98 box
-sizing
: border
-box
;
103 border
-color
: #c33333;
104 background
-color
: #f9c3c3;
109 background
-color
: #c3f9c3;
110 border
-color
: #33c333;
119 input
[type
="submit"] {
120 background
-color
: #efefef;
125 input
[type
="submit"]:first
-child
,
126 input
[type
="submit"]:last
-child
{
133 <h1
>Generateur d
'attestation</h1>
134 <p>Tous les champs sont obligatoires, format de date jj/mm/aaaa, format horaire hh:mm</p>
135 <form action="<?php echo htmlspecialchars($_SERVER['REQUEST_URI
']); ?>" method="post" autocomplete="on">
138 <label for="type">Type</label>
139 <select id="type" name="type" required="required">
140 <optgroup label="Professional">
141 <option value="bnp"<?php echo empty($selected)||$selected=='bnp
'?' selected
="selected"':''; ?>>Bnp</option>
142 <option value="poltrone"<?php echo !empty($selected)&&$selected=='poltrone
'?' selected
="selected"':''; ?>>Poltrone</option>
144 <optgroup label="Personnal">
145 <option value="travail"<?php echo !empty($selected)&&$selected=='travail
'?' selected
="selected"':''; ?>>Travail</option>
146 <option value="achats"<?php echo !empty($selected)&&$selected=='achats
'?' selected
="selected"':''; ?>>Achat</option>
147 <option value="sante"<?php echo !empty($selected)&&$selected=='sante
'?' selected
="selected"':''; ?>>Sante</option>
148 <option value="famille"<?php echo !empty($selected)&&$selected=='famille
'?' selected
="selected"':''; ?>>Famille</option>
149 <option value="handicap"<?php echo !empty($selected)&&$selected=='handicap
'?' selected
="selected"':''; ?>>Handicap</option>
150 <option value="sport_animaux"<?php echo !empty($selected)&&$selected=='sport_animaux
'?' selected
="selected"':''; ?>>Sport</option>
151 <option value="convocation"<?php echo !empty($selected)&&$selected=='convocation
'?' selected
="selected"':''; ?>>Convocation</option>
152 <option value="missions"<?php echo !empty($selected)&&$selected=='missions
'?' selected
="selected"':''; ?>>Mission</option>
153 <option value="enfants"<?php echo !empty($selected)&&$selected=='enfants
'?' selected
="selected"':''; ?>>Enfant</option>
160 <label for="firstname">Prénom</label>
161 <input type="text" id="firstname" name="firstname" value="<?php echo htmlspecialchars($_REQUEST['firstname
']??''); ?>" autocomplete="given-name" required="required" />
169 <label for="lastname">Nom</label>
170 <input type="text" id="lastname" name="lastname" value="<?php echo htmlspecialchars($_REQUEST['lastname
']??''); ?>" autocomplete="family-name" required="required" />
178 <label for="birthdate">Date de naissance</label>
179 <input type="date" id="birthdate" name="birthdate" value="<?php echo htmlspecialchars($_REQUEST['birthdate
']??''); ?>" autocomplete="bday" required="required" />
182 <span>01/01/1970</span>
187 <label for="birthplace">Lieu de naissance</label>
188 <input type="text" id="birthplace" name="birthplace" value="<?php echo htmlspecialchars($_REQUEST['birthplace
']??''); ?>" required="required" />
196 <label for="address">Adresse</label>
197 <input type="text" id="address" name="address" value="<?php echo htmlspecialchars($_REQUEST['address
']??''); ?>" autocomplete="address-line1" required="required" />
200 <span>10 rue Colbert</span>
205 <label for="zipcode">Code postal</label>
206 <input type="text" id="zipcode" name="zipcode" value="<?php echo htmlspecialchars($_REQUEST['zipcode
']??''); ?>" autocomplete="postal-code" required="required" />
214 <label for="city">Ville</label>
215 <input type="text" id="city" name="city" value="<?php echo htmlspecialchars($_REQUEST['city
']??''); ?>" autocomplete="address-level2" required="required" />
223 <label for="function">Fonction</label>
224 <input type="text" id="function" name="function" value="<?php echo htmlspecialchars($_REQUEST['function']??'Technicien(e
) d\'
astreint(e
)'); ?>" autocomplete="organization-title" required="required" />
227 <span>Technicien(e) d'astreint(e
)</span
>
232 <label
for="location">Fait à
</label
>
233 <input type
="text" id
="location" name
="location" value
="<?php echo htmlspecialchars($_REQUEST['location']??'Paris'); ?>" autocomplete
="address-level2" required
="required" />
241 <label
for="date">Sortie
</label
>
242 <input type
="date" id
="date" name
="date" value
="<?php echo htmlspecialchars($_REQUEST['date']??date('Y-m-d', $time)); ?>" required
="required" />
243 <label
for="time">a
</label
>
244 <?php
/*<datalist id="timelist">
245 <?php for($h = 0; $h < 24; $h++): for($m = 0; $m < 55; $m += 5): ?>
246 <option value="<?php printf('%02d:%02d', $h, $m); ?>"<?php if ($_REQUEST['time']??date('H:i', $time) == sprintf('%02d:%02d', $h, $m)): ?> selected="selected"<?php endif; ?>>
247 <?php endfor; endfor ?>
249 <input type
="time" id
="time" name
="time" value
="<?php echo htmlspecialchars($_REQUEST['time']??date('H:i', $time)); ?>" step
="300"<?php
# list="timelist" ?> required="required" />
253 document
.getElementById("time").onchange
= function () {
255 var time
= document
.getElementById("time").value
.split(':');
256 //Floor time minutes to closest value
257 time
[1] = (parseInt(time
[1]/5)*5).toString().padStart(2, "0");
259 document
.getElementById("time").value
= time
.join(':');
264 <input type
="submit" value
="Afficher" />
265 <input type
="submit" name
="download" value
="Télécharger" />
266 <input type
="submit" name
="download" value
="iBug" />
277 if (!empty($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] != 'GET' && !empty($_REQUEST['download']) && $_REQUEST['download'] == 'iBug') {
278 header('Location: '.$_SERVER['REQUEST_URI'].'?'.http_build_query($_REQUEST));
289 static function fixDate($date) {
290 $return = preg_replace(
292 '%^([0-9]{4})-([0-9]{2})-([0-9]{2})$%',
293 '%^([0-9]{2})/([0-9]{2})/([0-9]{4})$%',
294 '%^([0-9]{2})/([0-9]{2})/([0-9]{2})$%',
295 '%^([0-9]{2})([0-9]{2})([0-9]{4})$%',
296 '%^([0-9]{2})([0-9]{2})([0-9]{2})$%'
307 if (!preg_match('/^[0-9]{4}-[0-9]{2}-[0-9]{2}$/', $return)) {
308 die('Unable to fix date "'.$date.'" please use dd/mm/aaaa format');
316 static function fixTime($time) {
317 $return = preg_replace(
319 '%^([0-9]{2}):([0-9]{2})%',
320 '%^([0-9]{2})h([0-9]{2})%',
321 '%^([0-9]{2})([0-9]{2})%'
330 if (!preg_match('/^[0-9]{2}:[0-9]{2}$/', $return)) {
331 die('Unable to fix time "'.$time.'" please use HH:ii format');
337 * Add ausweis attestation
339 static function addAttestation($p, $reason, $firstname, $lastname, $birthdate, $birthplace, $address, $location, $date, $time) {
355 //Disable auto page break
356 $p->SetAutoPageBreak(false, 0);
359 $p->SetMargins(23.8, 0);
365 $p->setFont('LiberationSerif', 'B', 17);
368 $p->Cell(0, 20, utf8_decode('ATTESTATION DE DÉPLACEMENT DÉROGATOIRE'), 0, 0, 'C');
374 $p->setFont('MicrosoftSansSerif', '', 10.5);
377 $p->Cell(0, 4, utf8_decode('En application du décret n°2020-1310 du 29 octobre 2020 prescrivant les mesures générales'), 0, 1, 'C');
378 $p->Cell(0, 4, utf8_decode('nécessaires pour faire face à l\'épidémie de Covid19 dans le cadre de l\'état d\'urgence sanitaire'), 0, 1, 'C');
384 $p->Cell(0, 4, utf8_decode('Je soussigné(e),'), 0, 1, 'L');
390 $posName = $p->getY();
393 $p->Cell(0, 8, utf8_decode('Mme/M. :'), 0, 1, 'L');
396 $posBirth = $p->getY();
399 $p->Cell(75, 8, utf8_decode('Né(e) le :'), 0, 0, 'L');
400 $p->Cell(0, 8, utf8_decode('à :'), 0, 1, 'L');
403 $posAddress = $p->getY();
406 $p->Cell(0, 8, utf8_decode('Demeurant :'), 0, 1, 'L');
412 $p->Cell(0, 4.2, utf8_decode('certifie que mon déplacement est lié au motif suivant (cocher la case) autorisé par le décret'), 0, 1, 'L');
413 $p->Cell(0, 4.2, utf8_decode('n°2020-1310 du 29 octobre 2020 prescrivant les mesures générales nécessaires pour faire face à'), 0, 1, 'L');
414 $p->Cell(0, 4.2, utf8_decode('l\'épidémie de Covid19 dans le cadre de l\'état d\'urgence sanitaire¹ :'), 0, 1, 'L');
426 $p->SetLeftMargin(37.5, 0);
429 $p->MultiCell(148, 4.25, utf8_decode('Déplacements entre le domicile et le lieu d\'exercice de l\'activité professionnelle ou un établissement d\'enseignement ou de formation, déplacements professionnels ne pouvant être différés², déplacements pour un concours ou un examen'), 0, 'J');
431 //Save travail position
432 $pos['travail'] = $y +
($p->getY() - $y) / 2 - $boxSize / 2;
441 $p->MultiCell(148, 4.25, utf8_decode('Déplacements pour effectuer des achats de fournitures nécessaires à l\'activité professionnelle, des achats de première nécessité³ dans des établissements dont les activités demeurent autorisées, le retrait de commande et les livraisons à domicile'), 0, 'J');
443 //Save achats position
444 $pos['achats'] = $y +
($p->getY() - $y) / 2 - $boxSize / 2;
453 $p->MultiCell(148, 4.25, utf8_decode('Consultations, examens et soins ne pouvant être ni assurés à distance et l\'achat de médicaments'), 0, 'J');
455 //Save sante position
456 $pos['sante'] = $y +
($p->getY() - $y) / 2 - $boxSize / 2;
465 $p->MultiCell(148, 4.25, utf8_decode('Déplacements pour motif familial impérieux, pour l\'assistance aux personnes vulnérables et précaires ou la garde d\'enfants'), 0, 'J');
467 //Save famille position
468 $pos['famille'] = $y +
($p->getY() - $y) / 2 - $boxSize / 2;
477 $p->MultiCell(148, 4.25, utf8_decode('Déplacement des personnes en situation de handicap et leur accompagnant'), 0, 'J');
479 //Save handicap position
480 $pos['handicap'] = $y +
($p->getY() - $y) / 2 - $boxSize / 2;
489 $p->MultiCell(148, 4.25, utf8_decode('Déplacements brefs, dans la limite d\'une heure quotidienne et dans un rayon maximal d\'un kilomètre autour du domicile, liés soit à l\'activité physique individuelle des personnes, à l\'exclusion de toute pratique sportive collective et de toute proximité avec d\'autres personnes, soit à la promenade avec les seules personnes regroupées dans un même domicile, soit aux besoins des animaux de compagnie'), 0, 'J');
491 //Save sport_animaux position
492 $pos['sport_animaux'] = $y +
($p->getY() - $y) / 2 - $boxSize / 2;
501 $p->MultiCell(148, 4.25, utf8_decode('Convocation judiciaire ou administrative et pour se rendre dans un service public'), 0, 'J');
503 //Save convocation position
504 $pos['convocation'] = $y +
($p->getY() - $y) / 2 - $boxSize / 2;
513 $p->MultiCell(148, 4.25, utf8_decode('Participation à des missions d\'intérêt général sur demande de l\'autorité administrative'), 0, 'J');
515 //Save missions position
516 $pos['missions'] = $y +
($p->getY() - $y) / 2 - $boxSize / 2;
525 $p->MultiCell(148, 4.25, utf8_decode('Déplacement pour chercher les enfants à l\'école et à l\'occasion de leurs activités périscolaires'), 0, 'J');
527 //Save enfants position
528 $pos['enfants'] = $y +
($p->getY() - $y) / 2 - $boxSize / 2;
531 $p->SetLineWidth(0.5);
534 foreach($pos as $k => $v) {
535 $p->Rect(27.75, $v, 5.85, 5.85);
539 $p->SetLeftMargin(23.9, 0);
542 $p->SetY('-64.9', true);
545 $posLocation = $p->getY();
547 //Add creation location
548 $p->Cell(0, 4, utf8_decode('Fait à :'), 0, 1, 'L');
551 $p->SetY('-56.9', true);
554 $posDate = $p->getY();
557 $p->Cell(60.1, 4, utf8_decode('Le :'), 0, 0, 'L');
558 $p->Cell(0, 4, utf8_decode('à :'), 0, 1, 'L');
561 $p->SetY('-51', true);
564 $p->setFont('MicrosoftSansSerif', '', 10);
566 //Add creation mentions
567 $p->Cell(0, 4, utf8_decode('(Date et heure de début de sortie à mentionner obligatoirement)'), 0, 1, 'L');
570 $p->setFont('MicrosoftSansSerif', '', 10.5);
573 $p->SetY('-45.3', true);
576 $p->Cell(12, 4, utf8_decode('Signature :'), 0, 0, 'L');
580 $p->SetY('-33.25', true);
583 $p->setFont('MicrosoftSansSerif', '', 8);
586 $p->Cell(12.5, 3.5, utf8_decode('¹'), 0, 0, 'C');
587 $p->MultiCell(0, 3.5, utf8_decode('Les personnes souhaitant bénéficier de l\'une de ces exceptions doivent se munir s\'il y a lieu, lors de leurs'."\n".'déplacements hors de leur domicile, d\'un document leur permettant de justifier que le déplacement considéré entre'."\n".'dans le champ de l\'une de ces exceptions'), 0, 'L');
589 $p->Cell(12.5, 3.5, utf8_decode('²'), 0, 0, 'C');
590 $p->MultiCell(0, 3.5, utf8_decode('A utiliser par les travailleurs non-salariés, lorsqu\'ils ne peuvent disposer d\'un justificatif de déplacement établi par leur'."\n".'employeur'), 0, 'L');
592 $p->Cell(12.5, 3.5, utf8_decode('³'), 0, 0, 'C');
593 $p->MultiCell(0, 3.5, utf8_decode('Y compris les acquisitions à titre gratuit (distribution de denrées alimentaires...) et les déplacements liés à la'."\n".'perception de prestations sociales et au retrait d\'espèces'), 0, 'L');
597 $p->setFont('Helvetica', '', 11);
600 $p->setXY(41, $posName);
603 $p->Cell(0, 8, utf8_decode($firstname.' '.$lastname), 0, 0, 'L');
606 $p->setXY(41, $posBirth);
609 $birthdate = self
::fixDate($birthdate);
612 $p->Cell(63, 8, utf8_decode(date('d/m/Y', strtotime($birthdate))), 0, 0, 'L');
613 $p->Cell(0, 8, utf8_decode($birthplace), 0, 0, 'L');
616 $p->setXY(46, $posAddress);
619 $p->Cell(0, 7, utf8_decode($address), 0, 0, 'L');
622 $p->setXY(27.75, $pos[$reason]);
625 $p->setXY(36, $posLocation);
628 $p->Cell(0, 4, utf8_decode($location), 0, 0, 'L');
631 $p->setXY(31, $posDate);
634 $date = self
::fixDate($date);
637 $time = self
::fixTime($time);
640 $p->Cell(58, 4, utf8_decode(date('d/m/Y', strtotime($date))), 0, 0, 'L');
641 $p->Cell(0, 4, utf8_decode($time), 0, 0, 'L');
644 $p->setXY(27.75, $pos[$reason]);
647 $p->setFont('Helvetica', '', 16);
650 $p->Cell(0, 6.5, 'X', 0, 0, 'L');
653 $delay = rand(30, 60);
657 'Cree le: '.date('d/m/Y \a H\hi', strtotime('-'.$delay.' minutes', strtotime($date.' '.$time))),
659 'Prenom: '.$firstname,
660 'Naissance: '.date('d/m/Y', strtotime($birthdate)).' a '.$birthplace,
661 'Adresse: '.$address,
662 'Sortie: '.date('d/m/Y \a H:i', strtotime($date.' '.$time)),
667 $qrText = implode(";\n ", $qrData);
673 $qrPath = stream_get_meta_data($qrFile)['uri'];
677 QRcode
::png($qrText, $qrPath, QR_ECLEVEL_M
, 6, 4, false);
678 #$qrPng = ob_get_contents();
682 $p->Image($qrPath, 146, 221, 40, 40, 'PNG');
685 //XXX: add the attestation de déplacement dérogatoire page
689 $p->Image($qrPath, 12.5, 12.5, 117, 0, 'PNG');
694 * Add ausweis quittance
696 static function addQuittance($p, $firstname, $lastname, $address, $titleowner, $firstowner, $lastowner, $addressowner, $sign, $loyer, $charge) {
707 $p->SetMargins(30, 0);
709 //Disable auto page break
710 $p->SetAutoPageBreak(false, 0);
713 $p->SetY($lineHeight);
716 $p->setFont('Helvetica', 'B', 18);
719 $p->Cell(0, 20, utf8_decode('QUITTANCE DE LOYER'), 0, 0, 'C');
725 $p->setFont('Times', '', 9);
728 $p->Cell(0, 5, utf8_decode('Quittance de loyer pour la période du '.date('01/m/Y', strtotime('-1 month')).' au '.date('d/m/Y', strtotime('-1 day', strtotime('first day of now')))), 0, 0, 'C');
735 $p->setFont('Times', 'BU', 10);
738 $p->Cell($labelLength, 5, utf8_decode('Bailleur :'), 0, 0, 'L');
739 $p->Cell(0, 5, utf8_decode('Colocataire :'), 0, 0, 'L');
745 $p->setFont('Times', '', 9);
748 $p->Cell($labelLength, 5, utf8_decode($titleowner.' '.$firstowner.' '.$lastowner), 0, 0, 'L');
749 $p->Cell(0, 5, utf8_decode($firstname.' '.$lastname), 0, 0, 'L');
751 $p->Cell($labelLength, 5, utf8_decode($addressowner), 0, 0, 'L');
752 $p->Cell(0, 5, utf8_decode($address), 0, 0, 'L');
755 $p->Ln($lineHeight*1.5);
758 $p->Cell(0, 5, utf8_decode('Angers le '.date('07/m/Y', strtotime('-1 month'))), 0, 0, 'R');
764 $p->setFont('Times', 'BU', 10);
767 $p->Cell(0, 5, utf8_decode('Adresse de location :'), 0, 0, 'L');
771 $p->setFont('Times', 'B', 9);
774 $p->Cell(0, 5, utf8_decode($address), 0, 0, 'L');
780 $p->setFont('Times', '', 10);
783 $total = $loyer +
$charge;
786 $p->MultiCell(0, 5, utf8_decode('Je soussigné '.$titleowner.' '.$firstowner.' '.$lastowner.', usufruitier du logement situé au '.$address.', déclare avoir reçu de '.$firstname.' '.$lastname.', colocataire de ce logement, la somme de '.str_replace('.', ',', sprintf('%.2f', $total)).' euros correspondant au loyer et aux charges dus pour la période allant du '.date('01/m/Y', strtotime('-1 month')).' au '.date('d/m/Y', strtotime('-1 day', strtotime('first day of now'))).'. Cette somme correspond aux montants suivants :'), 0, 'J');
792 $p->Cell(0, 5, utf8_decode('Loyer hors charge :'), 0, 0, 'L');
796 $p->setFont('Times', '', 9);
798 $p->Cell(0, 5, utf8_decode(str_replace('.', ',', sprintf('%.2f', $loyer)).' euros'), 0, 0, 'L');
804 $p->setFont('Times', '', 10);
807 $p->Cell(0, 5, utf8_decode('Provision pour charges :'), 0, 0, 'L');
811 $p->setFont('Times', '', 9);
813 $p->Cell(0, 5, utf8_decode(str_replace('.', ',', sprintf('%.2f', $charge)).' euros'), 0, 0, 'L');
819 $p->setFont('Times', 'BU', 10);
822 $p->Cell(0, 5, utf8_decode('Somme totale reçue :'), 0, 0, 'L');
826 $p->setFont('Times', 'B', 9);
828 $p->Cell(0, 5, utf8_decode(str_replace('.', ',', sprintf('%.2f', $total)).' euros'), 0, 0, 'L');
834 $p->setFont('Times', '', 10);
837 $p->Cell(0, 5, utf8_decode('Date du paiement :'), 0, 0, 'L');
841 $p->setFont('Times', '', 9);
842 $p->Cell(0, 5, utf8_decode(date('05/m/Y', strtotime('-1 month')).' par virement'), 0, 0, 'L');
851 $p->setFont('Times', '', 10);
853 //Add creation location
854 $p->Cell(0, 5, utf8_decode('Fait à Angers le '.date('07/m/Y', strtotime('-1 month'))), 0, 0, 'L');
858 $p->Cell(12, 5, utf8_decode('Signature :'), 0, 0, 'L');
862 $p->Image($sign, 45, 245, 30, 0, 'PNG');
865 $p->setFont('Times', '', 10);
871 $p->MultiCell(0, 5, utf8_decode('La présente quittance est valable sous réserve d\'encaissement des sommes indiquées et de tous droits ou instances en cours. Elle n\'est libératoire que pour la période indiquée et n\'implique pas présomption de paiement des échéances antérieures qui pourraient rester dues.'), 0, 'J');
875 * Add ausweis employer
877 static function addEmployer($p, $employerTitle, $employerFunction, $employerCompany, $employerCity, $logo, $stamp, $sign, $workplaces, $firstname, $lastname, $birthdate, $birthplace, $address, $function) {
883 'Transport en commun',
891 $labelLength = 51.75;
900 $p->SetMargins(25, 0);
902 //Disable auto page break
903 $p->SetAutoPageBreak(false, 0);
906 #$p->Ln($titleHeight);
907 $p->SetY($titleHeight);
910 $p->setFont('TrebuchetMS', 'B', 16);
913 $p->Cell(0, 20, utf8_decode('JUSTIFICATIF DE DÉPLACEMENT PROFESSIONNEL'), 0, 0, 'C');
919 $p->setFont('Times', '', 10);
922 $p->Cell(0, 5, utf8_decode('En application du décret n°2020-1310 du 29 octobre 2020 prescrivant les mesures générales nécessaires pour'), 0, 1, 'C');
923 $p->Cell(0, 5, utf8_decode('faire face à l\'épidémie de Covid19 dans le cadre de l\'état d\'urgence sanitaire'), 0, 1, 'C');
929 $p->Cell(0, 5, utf8_decode('Je soussigné(e),'), 0, 0, 'L');
935 $p->Cell($labelLength, 5, utf8_decode('Nom et prénom de l\'employeur :'), 0, 0, 'L');
936 $p->Cell(0, 5, utf8_decode($employerTitle), 0, 0, 'L');
942 $p->Cell($labelLength, 5, utf8_decode('Fonctions :'), 0, 0, 'L');
943 $p->Cell(0, 5, utf8_decode($employerFunction), 0, 0, 'L');
949 $p->MultiCell(0, 5, utf8_decode('Certifie que les déplacements de la personne ci-après, entre son domicile et le ou les lieux d\'exercice de son activité professionnelle ou à l\'occasion de l\'exercice de ses fonctions, ne peuvent être différés ou sont indispensables à l\'exercice d\'activités ne pouvant être organisées sous forme de télétravail :'), 0, 'J');
952 $p->Ln($lineHeight-5);
955 $p->Cell($labelLength, 5, utf8_decode('Nom :'), 0, 0, 'L');
956 $p->Cell(0, 5, utf8_decode($lastname), 0, 0, 'L');
958 $p->Cell($labelLength, 5, utf8_decode('Prénom :'), 0, 0, 'L');
959 $p->Cell(0, 5, utf8_decode($firstname), 0, 0, 'L');
961 $p->Cell($labelLength, 5, utf8_decode('Date de naissance :'), 0, 0, 'L');
962 $p->Cell(0, 5, utf8_decode($birthdate), 0, 0, 'L');
964 $p->Cell($labelLength, 5, utf8_decode('Lieu de naissance :'), 0, 0, 'L');
965 $p->Cell(0, 5, utf8_decode($birthplace), 0, 0, 'L');
967 $p->Cell($labelLength, 5, utf8_decode('Adresse du domicile :'), 0, 0, 'L');
968 $p->Cell(0, 5, utf8_decode($address), 0, 0, 'L');
970 $p->Cell($labelLength, 5, utf8_decode('Nature de l\'activité professionnelle :'), 0, 0, 'L');
971 $p->Cell(0, 5, utf8_decode($function), 0, 0, 'L');
975 $p->Cell($labelLength, 5, utf8_decode('Moyens de déplacement :'), 0, 0, 'L');
976 $p->Cell(0, 5, /*' '.*/implode(', ', $conveyances), 0, 0, 'L');
982 $p->Cell($labelLength, 5, utf8_decode('Durée de validité :'), 0, 0, 'L');
983 $p->Cell(0, 5, utf8_decode('6 mois'), 0, 0, 'L');
989 $p->Cell(0, 5, utf8_decode('Lieux d\'exercice de l\'activité professionnelle :'), 0, 0, 'L');
990 foreach($workplaces as $siret => $location) {
992 #$p->cell($labelLength/1.5, 5, ' '.$siret.' :', 0, 0, 'l');
993 $p->cell(0, 5, ' '.utf8_decode($location), 0, 0, 'l');
997 #$p->Ln($lineHeight*2);
1000 $p->SetY('-65', true);
1003 $p->Cell($labelLength, 5, utf8_decode('Nom et cachet de l\'employeur :'), 0, 0, 'L');
1004 $p->Cell(0, 5, utf8_decode($employerCompany), 0, 0, 'L');
1007 $p->Ln($lineHeight);
1010 $p->Cell($labelLength, 5, utf8_decode('Fait à :'), 0, 0, 'L');
1011 $p->Cell(0, 5, utf8_decode($employerCity), 0, 0, 'L');
1014 $p->Ln($lineHeight);
1017 $p->Cell($labelLength, 5, utf8_decode('Le :'), 0, 0, 'L');
1018 $p->Cell(0, 5, utf8_decode('02 novembre 2020'), 0, 0, 'L');
1021 $p->Ln($lineHeight);
1024 $p->SetY('-40', true);
1027 $p->setFont('MicrosoftSansSerif', '', 7);
1030 $p->Cell(0, 4, utf8_decode('Ce document, établi par l\'employeur, est suffisant pour justifier les déplacements professionnels d\'un salarié, qu\'il s\'agisse :'), 0, 0, 'L');
1031 $p->Ln($lineHeight/2);
1032 $p->Cell(0, 4, utf8_decode('- du trajet habituel entre le domicile et le lieu de travail du salarié ou des déplacements entre les différents lieux de travail lorsque la nature'), 0, 0, 'L');
1033 $p->Ln($lineHeight/2);
1034 $p->Cell(0, 4, utf8_decode('de ses fonctions l\'exige'), 0, 0, 'L');
1035 $p->Ln($lineHeight/2);
1036 $p->Cell(0, 4, utf8_decode('- des déplacements de nature professionnelle qui ne peuvent pas être différés, à la demande de l\'employeur.'), 0, 0, 'L');
1037 $p->Ln($lineHeight/2);
1038 $p->Cell(0, 4, utf8_decode('Il n\'est donc pas nécessaire que le salarié se munisse, en plus de ce justificatif, de l\'attestation de déplacement dérogatoire.'), 0, 0, 'L');
1039 $p->Ln($lineHeight/2);
1040 $p->Cell(0, 4, utf8_decode('Les travailleurs non-salariés, pour lesquels ce justificatif ne peut être établi, doivent en revanche se munir de l\'attestation de déplacement'), 0, 0, 'L');
1041 $p->Ln($lineHeight/2);
1042 $p->Cell(0, 4, utf8_decode('dérogatoire en cochant le premier motif de déplacement'), 0, 0, 'L');
1045 $p->Image($logo, 10, 8, 40, 0, 'PNG');
1046 $p->Image($stamp, 130, 210, 60, 0, 'PNG');
1047 $p->Image($sign, 110, 215, 25, 0, 'PNG');
1059 if ($_REQUEST['type'] == 'bnp') {
1061 $data['employer'] = [
1062 'title' => 'Jean-Laurent Bonnafé',
1063 'function' => 'Administrateur Directeur Général de BNP Paribas',
1064 'company' => 'BNP PARIBAS',
1065 'address' => '16 Boulevard des Italiens 75009 Paris',
1067 'vat' => 'FR76662042449'
1071 $data['workplaces'] = [
1072 //TODO: add others...
1073 66204244932405 => '37 place du Marché St Honoré 75001 Paris',
1074 66204244932355 => '36b avenue de l\'Opéra 75002 Paris',
1075 66204244920376 => '67 rue de Bretagne 75003 Paris',
1076 66204244919998 => '48 rue des Archives 75004 Paris',
1077 66204244915558 => '50 boulevard de Saint Marcel 75005 Paris',
1078 66204244920368 => '1 rue de Medicis 75006 Paris',
1079 66204244941596 => '64 rue de Sèvres 75007 Paris',
1080 66204244943238 => '10 boulevard Malesherbes 75008 Paris',
1081 66204244900014 => '16 boulevard des Italiens 75009 Paris',
1082 66204244932454 => '150 rue du fbg Poissonniere 75010 Paris',
1083 66204244941539 => '41 rue Basfroi 75011 Paris',
1084 66204244943733 => '47 boulevard Diderot 75012 Paris',
1085 66204244920897 => '109 rue de Tolbiac 75013 Paris',
1086 66204244941265 => '160 boulevard Macdonald 75019 Paris',
1087 66204244925110 => '4 place Saint Fargeau 75020 Paris',
1088 00000000000000 => 'Toute l\'Île-de-France',
1089 99999999999999 => 'Toute la France'
1093 $data['sign'] = '../picture/ausweis/bnp/sign.png';
1094 $data['stamp'] = '../picture/ausweis/bnp/stamp.png';
1095 $data['logo'] = '../picture/ausweis/bnp/logo.png';
1098 $data['reason'] = 'travail';
1102 } elseif ($_REQUEST['type'] == 'poltrone') {
1104 $data['employer'] = [
1105 'title' => 'M Renzo Ricci',
1106 'function' => 'Président',
1107 'company' => 'POLTRONESOFA \'FRANCE',
1108 'address' => '6 Rue Jean Jaures 92800 Puteaux',
1109 'city' => 'Puteaux',
1110 'vat' => 'FR88422036905'
1114 $data['workplaces'] = [
1115 42203690500020 => 'Place du Marché St Honoré 75001 Paris',
1116 42203690500558 => '72 Boulevard de Sébastopol 75003 Paris',
1117 42203690500756 => 'Avenue de Fontainebleau 94320 Thiais',
1118 //42203690500749 => 'Cc Opensky Lot A03 78200 Buchelay',
1119 //42203690500681 => 'L\'oseraie 95520 Osny',
1120 42203690500533 => '1 rue de la Mare au Chanvre 91700 Sainte-Geneviève-des-Bois',
1121 42203690500483 => '23 rue Alexandre Chatrian 77410 Claye-Souilly',
1122 42203690500434 => 'Route Nationale 10 78210 Coignières',
1123 42203690500186 => 'Avenue Henri Barbusse 78340 Les Clayes-sous-Bois',
1124 42203690500152 => 'La Saussaie Beauclair 93110 Rosny-sous-Bois',
1125 42203690500095 => '234 Boulevard du Havre 95220 Pierrelaye',
1126 00000000000000 => 'Toute l\'Île-de-France',
1127 99999999999999 => 'Toute la France'
1131 $data['sign'] = '../picture/ausweis/poltrone/sign.png';
1132 $data['stamp'] = '../picture/ausweis/poltrone/stamp.png';
1133 $data['logo'] = '../picture/ausweis/poltrone/logo.png';
1136 $data['reason'] = 'travail';
1140 } elseif ($_REQUEST['type'] == 'sport_animaux') {
1142 $data['reason'] = 'sport_animaux';
1143 $data['sign'] = '../picture/ausweis/bnp/sign.png';
1147 } elseif ($_REQUEST['type'] == 'achats') {
1149 $data['reason'] = 'achats';
1150 $data['sign'] = '../picture/ausweis/bnp/sign.png';
1158 * - sport_animaux: 358,
1159 * - convocation: 295,
1163 } elseif (in_array($_REQUEST['type'], $reasons)) {
1165 $data['reason'] = $_REQUEST['type'];
1174 //XXX: was Ausweis_ now we use Travail_firstname_lastname.pdf
1175 $fileName = ucfirst($data['reason']).'_'.preg_replace(['/[^a-zA-Z0-9]/', '/__+/'], ['_', '_'], $_REQUEST['firstname'].'_'.$_REQUEST['lastname']).'_'.date('Ymd_Hi', strtotime(Ausweis
::fixDate($_REQUEST['date']).' '.Ausweis
::fixTime($_REQUEST['time']))).'.pdf';
1178 $p = new FPDF('P', 'mm', 'A4');
1181 #$p->AddFont('Marianne-Bold', '', 'marianne-bold.php');
1182 #$p->AddFont('Marianne-Bold', 'B', 'marianne-bold.php');
1183 #$p->AddFont('Marianne-Bold', 'BI', 'marianne-bold.php');
1184 #$p->AddFont('Marianne-Bold', 'I', 'marianne-bold.php');
1186 //Add mariane regular
1187 #$p->AddFont('Marianne-Regular', '', 'marianne-regular.php');
1188 #$p->AddFont('Marianne-Regular', 'B', 'marianne-regular.php');
1189 #$p->AddFont('Marianne-Regular', 'BI', 'marianne-regular.php');
1190 #$p->AddFont('Marianne-Regular', 'I', 'marianne-regular.php');
1193 $p->AddFont('TrebuchetMS', '', 'trebuc.php');
1194 $p->AddFont('TrebuchetMS', 'B', 'trebucb.php');
1195 $p->AddFont('TrebuchetMS', 'BI', 'trebucbi.php');
1196 $p->AddFont('TrebuchetMS', 'I', 'trebuci.php');
1198 //Add liberation serif
1199 $p->AddFont('LiberationSerif', '', 'liberationserif.php');
1200 $p->AddFont('LiberationSerif', 'B', 'liberationserifb.php');
1201 $p->AddFont('LiberationSerif', 'BI', 'liberationserifbi.php');
1202 $p->AddFont('LiberationSerif', 'I', 'liberationserifi.php');
1204 //Add microsoft sans serif
1205 $p->AddFont('MicrosoftSansSerif', '', 'micross.php');
1206 $p->AddFont('MicrosoftSansSerif', 'B', 'micross.php');
1207 $p->AddFont('MicrosoftSansSerif', 'BI', 'micross.php');
1208 $p->AddFont('MicrosoftSansSerif', 'I', 'micross.php');
1211 $p->SetTitle('Justificatif de déplacement professionnel', true);
1212 $p->SetCreator($_SERVER['PHP_SELF'], true);
1213 $p->SetAuthor('Französischer Kommandantur', true);
1214 $p->SetSubject('Verkehrsausweis', true);
1219 Ausweis
::addAttestation(
1222 $_REQUEST['firstname'],
1223 $_REQUEST['lastname'],
1224 $_REQUEST['birthdate'],
1225 $_REQUEST['birthplace'],
1226 $_REQUEST['address'].' '.$_REQUEST['zipcode'].' '.$_REQUEST['city'],
1227 $_REQUEST['location'],
1233 * Employer attestation type
1235 //XXX: add the justificatif de déplacement professionnel page
1236 if (!empty($data['employer'])) {
1238 * Add employer attestation
1240 Ausweis
::addEmployer(
1242 $data['employer']['title'],
1243 $data['employer']['function'],
1244 $data['employer']['company'],
1245 $data['employer']['city'],
1249 $data['workplaces'],
1250 $_REQUEST['firstname'],
1251 $_REQUEST['lastname'],
1252 $_REQUEST['birthdate'],
1253 $_REQUEST['birthplace'],
1254 $_REQUEST['address'].' '.$_REQUEST['zipcode'].' '.$_REQUEST['city'],
1255 $_REQUEST['function']
1260 * Personnal sport and buy attestation type
1262 if ($data['reason'] == 'sport_animaux' || $data['reason'] == 'achats') {
1264 * Add quittance attestation
1266 Ausweis
::addQuittance(
1268 $_REQUEST['firstname'],
1269 $_REQUEST['lastname'],
1270 $_REQUEST['address'].' '.$_REQUEST['zipcode'].' '.$_REQUEST['city'],
1274 '6 chemin Bas des Plaines 49000 Angers',
1275 '../picture/ausweis/bnp/sign.png',
1284 //Send common headers
1285 header('Content-Type: application/pdf');
1287 //Send download headers
1288 if (!empty($_REQUEST['download'])) {
1289 if ($_REQUEST['download'] == 'iBug') {
1290 header('Content-Type: application/octet-stream');
1292 header('Content-Disposition: attachment; filename="'.rawurlencode($fileName).'"');
1293 //Send display headers
1295 header('Content-Disposition: inline; filename="'.rawurlencode($fileName).'"');
1298 //Send remaining headers
1299 header('Cache-Control: private, max-age=0, must-revalidate');
1300 header('Pragma: public');
1303 $output = $p->Output('S');
1305 //Send content-length
1306 header('Content-Length: '.strlen($output));