requireAccess($session::SECTION_ACCOUNTING, $session::ACCESS_READ); f(['id' => 'required|numeric']); $id = (int) qg('id'); $sign_tag = UserTemplate\Functions::signature(); $h = static function ($value): string { return htmlspecialchars_decode( htmlentities($value, ENT_NOQUOTES, 'UTF-8', false), ENT_NOQUOTES ); }; $br = static function ($value) use ($h): string { return nl2br($h($value)); }; $format_identifier = static function ($value) use ($h): string { $value = preg_replace('/\s+/', '', (string) $value); return $value !== '' ? $h(implode(' ', str_split($value, 3))) : ''; }; $detail_line = static function (string $label, $value) use ($h, $br): string { if ($value === null || trim((string) $value) === '') { return ''; } return sprintf('
%s%s
', $h($label), $br($value)); }; // Vérification que le document existe if (!$f = $facture->get($id)) { throw new UserException("Ce document n'existe pas."); } $moyen_paiement = $facture->getMoyenPaiement($f->moyen_paiement); // Récupération infos membre/client dans un objet normalisé pour le rendu if ($f->receveur_membre) { $user = Users\Users::get($f->receveur_id); if (!$user) { throw new UserException("Ce membre n'existe plus."); } $nom_client = Users\DynamicFields::getNameFromArray($user) ?: '** ABSENT **'; $user_fields = Users\DynamicFields::getInstance()->listAssocNames(); $get_user_field = static function (?string $configured, string $fallback) use ($user, $user_fields) { $field = $configured ?: $fallback; return array_key_exists($field, $user_fields) ? ($user->$field ?? null) : null; }; $c = (object) [ 'nom' => $nom_client, 'adresse' => $get_user_field($plugin->getConfig('adresse_client'), 'adresse') ?: '[À RENSEIGNER DANS LA FICHE MEMBRE]', 'code_postal' => $get_user_field($plugin->getConfig('code_postal_client'), 'code_postal') ?: '[À RENSEIGNER]', 'ville' => $get_user_field($plugin->getConfig('ville_client'), 'ville') ?: '[À RENSEIGNER]', 'siret' => null, 'email' => Users\DynamicFields::getFirstEmailField() ? ($user->{Users\DynamicFields::getFirstEmailField()} ?? null) : null, 'telephone' => null, ]; } else { $client_data = $client->get($f->receveur_id); if (!$client_data) { throw new UserException("Ce client n'existe plus."); } $nom_client = $client_data->nom; $c = $client_data; } // Formatage dates $emission = $f->date_emission->format('d/m/Y'); if (isset($f->date_echeance)) { $echeance = $f->date_echeance->format('d/m/Y'); } // -- Création du PDF // Génération factures, devis et cotisation if ($f->type_facture != CERFA) { $labels = [ FACT => ['Facture', 'Émise le', 'Adressée à', 'Échéance de paiement'], DEVIS => ['Devis', 'Émis le', 'Adressé à', 'Échéance du devis'], COTIS => ['Reçu de cotisation', 'Émis le', 'Adressé à', 'Date du reçu'], ]; [$document_label, $emission_label, $recipient_label, $due_label] = $labels[$f->type_facture] ?? $labels[FACT]; $doc = sprintf('%s n° %s', $document_label, $f->numero); $theme = $plugin->getConfig('invoice_theme') ?: 'modern'; $theme = in_array($theme, ['modern', 'classic', 'minimal'], true) ? $theme : 'modern'; $accent = $plugin->getConfig('invoice_accent_color') ?: '#4656A5'; $accent = preg_match('/^#[0-9A-Fa-f]{6}$/', $accent) ? $accent : '#4656A5'; $show_address_borders = $plugin->getConfig('invoice_show_address_borders') !== false; $show_email = $plugin->getConfig('invoice_show_email') !== false; $show_web = $plugin->getConfig('invoice_show_web') !== false; $address_border_class = $show_address_borders ? 'invoice-address-borders' : 'invoice-no-address-borders'; $currency = $config->get('currency') ?: '€'; $total = Utils::money_format($f->total, ',', ' '); $ttc = $plugin->getConfig('ttc') ? 'TTC' : 'HT'; if ($plugin->getConfig('rue_asso') && $plugin->getConfig('cp_asso') && $plugin->getConfig('ville_asso')) { $adresse = trim(($plugin->getConfig('numero_rue_asso') ? $plugin->getConfig('numero_rue_asso') . ' ' : '') . $plugin->getConfig('rue_asso')) . "\n" . $plugin->getConfig('cp_asso') . ' ' . $plugin->getConfig('ville_asso'); } else { $adresse = $config->get('org_address_public') ?: $config->get('org_address') ?: ''; } $logo = ''; if ($plugin->getConfig('logo') && ($logo_url = $config->fileURL('logo'))) { $logo = sprintf('', $h($logo_url)); } $asso_details = '' . $h($config->get('org_name')) . ''; $asso_details .= $adresse ? '

' . $br($adresse) . '

' : ''; $asso_details .= ($t = $plugin->getConfig('rna_asso')) ? $detail_line('RNA', $t) : ''; $asso_details .= ($t = $plugin->getConfig('siret_asso')) ? '
SIRET' . $format_identifier($t) . '
' : ''; $asso_details .= $show_email && ($t = $config->get('org_email')) ? $detail_line('Email', $t) : ''; $asso_details .= ($t = $config->get('org_phone')) ? $detail_line('Tel.', $t) : ''; $asso_details .= $show_web && ($t = $config->get('org_web')) ? $detail_line('Web', $t) : ''; $brand_summary = '
' . $logo . '' . $h($config->get('org_name')) . '
'; $receveur = '' . $h($nom_client) . ''; $receveur .= ($t = ($f->nom_contact ?? null)) ? $detail_line('Contact', $t) : ''; $receveur .= '

' . $br($c->adresse ?? '') . '
' . $h(trim(($c->code_postal ?? '') . ' ' . ($c->ville ?? ''))) . '

'; $receveur .= ($t = $c->siret ?? null) ? '
SIREN/SIRET' . $format_identifier($t) . '
' : ''; $receveur .= $show_email && ($t = $c->email ?? null) ? $detail_line('Email', $t) : ''; $receveur .= ($t = $c->telephone ?? null) ? $detail_line('Tel.', $t) : ''; $receveur .= $f->type_facture == FACT && ($t = ($f->numero_commande ?? null)) ? $detail_line('Commande', $t) : ''; $receveur .= $f->type_facture == FACT && ($t = ($f->reference_acheteur ?? null)) ? $detail_line('Référence', $t) : ''; if ($f->type_facture != COTIS) { $rows = ''; foreach($f->contenu as $v) { $rows .= sprintf( '%s%s %s', $br($v['designation']), $h(Utils::money_format($v['prix'], ',', ' ')), $h($currency) ); } $payment_terms = trim((string) ($plugin->getConfig('payment_terms') ?: '')); $invoice_note = trim((string) ($plugin->getConfig('invoice_note') ?: '')); $status = ''; if ($plugin->getConfig('invoice_show_status') && $f->type_facture == FACT) { $status_class = $f->reglee ? 'paid' : 'pending'; $status_label = $f->reglee ? 'Facture réglée' : 'En attente de règlement'; $status = sprintf('

%s

', $status_class, $h($status_label)); } $approval = $f->type_facture == DEVIS ? '
Bon pour accordDate, nom et signature
' : ''; $note = $invoice_note !== '' ? '

' . $br($invoice_note) . '

' : ''; $terms = $payment_terms !== '' ? $detail_line('Conditions', $payment_terms) : ''; $footer = $br($plugin->getConfig('footer') ?? '[Pied de page à configurer]'); $echeance_html = $detail_line($due_label, $echeance ?? ''); $moyen_html = $detail_line('Moyen de paiement', $moyen_paiement); $content = << $rows
Désignation Montant
$echeance_html $terms $moyen_html $status
Total $ttc $total {$h($currency)} Net à payer
$note $approval HTML; } else { $lieu = $plugin->getConfig('ville_asso') ?: ''; $intitule = $f->contenu['intitule']; $souscription = date('d/m/Y', strtotime($f->contenu['souscription'])); $expiration = $f->contenu['expiration'] == '1970-01-01' ? "le jour même, s'agissant d'une cotisation ponctuelle" : 'le ' . date('d/m/Y', strtotime($f->contenu['expiration'])); $footer = $br($plugin->getConfig('footer') ?? ''); $content = <<

À {$h($lieu)}, le {$h($emission)},

Bonjour,

Nous accusons réception de votre cotisation « {$h($intitule)} » reçue le {$h($emission)} et nous vous en remercions.

Nous reconnaissons que vous avez acquitté la somme de {$h($total)} {$h($currency)}. Votre adhésion sera donc effective à compter du {$h($souscription)} jusqu'à {$h($expiration)}.

Nous vous prions de recevoir nos meilleures salutations.

Pour {$h($config->get('org_name'))}

HTML; } $html_title = $h($doc . '_' . $emission); $doc_html = $h($doc); $txtemis = $h($emission_label . ' ' . $emission); $txtdest = $h($recipient_label); $html = << $html_title
$brand_summary

$doc_html

$txtemis

Émetteur

$asso_details

$txtdest

$receveur
$content
HTML; } // Génération du CERFA elseif ($f->type_facture == CERFA) { $doc = 'Reçu de don n°'. $f->numero; $url = WWW_URL; $libelles = $facture->listTextesCerfa(false); $t['numero'] = $f->numero; $t['org_name'] = $config->get('org_name'); $t['n_rue_asso'] = $plugin->getConfig('numero_rue_asso'); $t['rue_asso'] = $plugin->getConfig('rue_asso'); $t['cp_asso'] = $plugin->getConfig('cp_asso'); $t['ville_asso'] = $plugin->getConfig('ville_asso'); $t['objet0'] = $plugin->getConfig('objet_0'); $t['objet1'] = $plugin->getConfig('objet_1'); $t['objet2'] = $plugin->getConfig('objet_2'); $t['nom'] = $nom_client; $t['adresse'] = $c->adresse ?? ''; $t['cp'] = $c->code_postal ?? ''; $t['ville'] = $c->ville ?? ''; $t['total'] = '***'.Utils::money_format($f->total).'***'; $t['total_lettre'] = numfmt_create('fr_FR', \NumberFormatter::SPELLOUT)->format($f->total/100). ' euros'; $t['d'] = ($f->date_emission->format('d')); $t['m'] = ($f->date_emission->format('m')); $t['Y'] = ($f->date_emission->format('Y')); $t['forme'] = $f->contenu['forme']; $t['nature'] = $f->contenu['nature']; $t['texte'] = $libelles[$f->contenu['texte']]; $t['art200'] = $t['art238'] = $t['art885'] = ''; if($plugin->getConfig('droit_art200')){ $t['art200'] = 'X'; } if($plugin->getConfig('droit_art238bis')){ $t['art238'] = 'X'; } if($plugin->getConfig('droit_art885-0VbisA')){ $t['art885'] = 'X'; } // forme du don switch ($t['forme']){ case '1': $t['frm'] = 'left: 15mm;'; break; case '2': $t['frm'] = 'left: 57.3mm;'; break; case '3': $t['frm'] = 'left: 115.2mm;'; break; case '4': $t['frm'] = 'left: 175.2mm;'; } // nature du don switch ($t['nature']){ case '1': $t['nat'] = 'left: 15mm;'; break; case '2': $t['nat'] = 'left: 57.3mm;'; break; case '3': $t['nat'] = 'left: 115.2mm;'; } // moyen de paiement switch ($f->moyen_paiement){ case 'ES': $t['pos'] = 'left: 15mm;'; break; case 'CH': $t['pos'] = 'left: 57.3mm;'; break; default: $t['pos'] = 'left: 115.2mm;'; } $t['d2'] = ($f->date_echeance->format('d')); $t['m2'] = ($f->date_echeance->format('m')); $t['Y2'] = ($f->date_echeance->format('Y')); ob_start(); echo << {$doc}_{$emission}
{$t['numero']}
{$t['org_name']}
{$t['n_rue_asso']}
{$t['rue_asso']}
{$t['cp_asso']}
{$t['ville_asso']}
{$t['objet0']}
{$t['objet1']}
{$t['objet2']}
X
{$t['nom']}
{$t['adresse']}
{$t['cp']}
{$t['ville']}
{$t['total']}
{$t['total_lettre']}
{$t['d']}
{$t['m']}
{$t['Y']}
{$t['art200']}
{$t['art238']}
{$t['art885']}
X
X
{$t['texte']}
X
{$t['d2']}
{$t['m2']}
{$t['Y2']}
{$sign_tag}
EOF; $html = ob_get_clean(); } // End if cerfa if(qg('d') !== null) { $filename = 'Print'; if (preg_match('!(.*)!U', $html, $match)) { $filename = str_replace(" ", "_", trim($match[1])); } header('Content-type: application/pdf'); header(sprintf('Content-Disposition: attachment; filename="%s.pdf"', Utils::safeFileName($filename))); Utils::streamPDF($html); } else { echo $html; }