Compare commits
No commits in common. "72999b9fc663dd9365669fee5174b6bfdd7e9e27" and "57e6ad09f92af2f5c87c1efd8a10bc9bfd9cb65b" have entirely different histories.
72999b9fc6
...
57e6ad09f9
@ -21,10 +21,14 @@ $db = DB::getInstance();
|
||||
$step = false;
|
||||
$radio = $liste = $designations = $prix = [];
|
||||
|
||||
$fields = $facture->recu_fields;
|
||||
|
||||
$moyens_paiement = $facture->listMoyensPaiement(true);
|
||||
|
||||
$tpl->assign('moyens_paiement', $moyens_paiement);
|
||||
$tpl->assign('moyen_paiement', f('moyen_paiement') ?: 'ES');
|
||||
$tpl->assign('moyen_paiement_cerfa', f('moyen_paiement_cerfa') ?: 'ES');
|
||||
|
||||
$tpl->assign('formes_don', array('1' => 'Acte authentique',
|
||||
'2' => 'Acte sous seing privé',
|
||||
'3' => 'Don manuel',
|
||||
@ -32,6 +36,7 @@ $tpl->assign('formes_don', array('1' => 'Acte authentique',
|
||||
$tpl->assign('natures_don', array('1' => 'Numéraire',
|
||||
'2' => 'Chèque',
|
||||
'3' => 'Virement, CB; ...'));
|
||||
$tpl->assign('textes_don', $facture->listTextesCerfa());
|
||||
|
||||
if ( !$target ) {
|
||||
f(['id' => 'required|numeric']);
|
||||
@ -80,6 +85,16 @@ $form->runIf(f('save') && !$form->hasErrors(),
|
||||
$data['total'] = $data['toto'];
|
||||
unset($data['toto']);
|
||||
}
|
||||
elseif ( f('type') == CERFA )
|
||||
{
|
||||
$data['moyen_paiement'] = f('moyen_paiement_cerfa');
|
||||
$data['contenu'] = [
|
||||
'forme' => f('forme_don'),
|
||||
'nature' => f('nature_don'),
|
||||
'texte' => f('texte_don')];
|
||||
$data['total'] = Utils::moneyToInteger(f('total'));
|
||||
unset($data['toto']);
|
||||
}
|
||||
if (f('base_receveur') == 'client')
|
||||
{
|
||||
$data['receveur_membre'] = 0;
|
||||
@ -103,9 +118,62 @@ $form->runIf(f('save') && !$form->hasErrors(),
|
||||
|
||||
}, $csrf_key);
|
||||
|
||||
$form->runIf(f('select_cotis') && !$form->hasErrors(),
|
||||
function () use ($step)
|
||||
{
|
||||
$step = true;
|
||||
}, 'add_cotis_1');
|
||||
|
||||
$form->runIf(f('add_cotis') && !$form->hasErrors(),
|
||||
function () use ($radio, $fields, $facture, $form)
|
||||
{
|
||||
$radio['type'] = f('cotisation');
|
||||
try
|
||||
{
|
||||
$num = (int) str_replace('cotis_', '', $radio['type']);
|
||||
foreach($fields as $field)
|
||||
{
|
||||
$cotis[$field] = f($field.'_'.$num);
|
||||
}
|
||||
|
||||
$r = $facture->getCotis(f('membre_cotis'), $cotis['id']);
|
||||
$r = $r[0];
|
||||
|
||||
$data = [
|
||||
'type_facture' => COTIS,
|
||||
'numero' => f('numero_facture'),
|
||||
'receveur_membre' => 1,
|
||||
'receveur_id' => f('membre_cotis'),
|
||||
'date_emission' => f('date_emission'),
|
||||
'moyen_paiement' => 'AU',
|
||||
'total' => $r->paid_amount ?? $r->amount,
|
||||
'contenu' => ['id' => $cotis['id'],
|
||||
'intitule' => $cotis['label'],
|
||||
'souscription' => $cotis['date'],
|
||||
'expiration' => $cotis['expiry'] ]
|
||||
];
|
||||
|
||||
}
|
||||
catch (UserException $e)
|
||||
{
|
||||
$form->addError($e->getMessage());
|
||||
}
|
||||
}, 'add_cotis_2');
|
||||
|
||||
if (! $form->hasErrors())
|
||||
{
|
||||
if (count($data) > 0)
|
||||
if ($step)
|
||||
{
|
||||
try
|
||||
{
|
||||
$liste = $facture->getCotis((int)f('membre_cotis'));
|
||||
}
|
||||
catch (UserException $e)
|
||||
{
|
||||
$form->addError($e->getMessage());
|
||||
}
|
||||
}
|
||||
elseif (count($data) > 0)
|
||||
{
|
||||
if ($target)
|
||||
{
|
||||
@ -137,13 +205,19 @@ if ($target)
|
||||
$doc['base_receveur'] = $f->receveur_membre ? 'membre' : 'client';
|
||||
$doc['client'] = $f->receveur_id;
|
||||
$doc['membre'] = $f->receveur_id;
|
||||
|
||||
if ( $f->type_facture == CERFA ) {
|
||||
$doc['forme_don'] = $f->contenu['forme'];
|
||||
$doc['nature_don'] = $f->contenu['nature'];
|
||||
$doc['texte_don'] = $f->contenu['texte'];
|
||||
}
|
||||
}
|
||||
|
||||
// Type du document:
|
||||
$type = qg('t') ? (int) qg('t') : null;
|
||||
|
||||
// Si le type est défini dans l'URL
|
||||
if (in_array($type, [DEVIS, FACT], true))
|
||||
if (in_array($type, [DEVIS, FACT, CERFA, COTIS], true))
|
||||
{
|
||||
$radio['type'] = $type;
|
||||
} // ... s'il a été rempli dans le formulaire envoyé
|
||||
@ -172,6 +246,14 @@ else
|
||||
|
||||
$doc['date_emission'] = f('date_emission') ?: $f->date_emission;
|
||||
$doc['date_echeance'] = f('date_echeance')?: $f->date_echeance; // Smarty m'a saoulé pour utiliser form_field|date_fr:---
|
||||
/* modif DD -- CERFA -------------------------------------- */
|
||||
if ( $f->type_facture == CERFA ) {
|
||||
$doc['total'] = $f->total;
|
||||
$doc['forme_don'] = $f->contenu['forme'];
|
||||
$doc['nature_don'] = $f->contenu['nature'];
|
||||
$doc['texte_don'] = $f->contenu['texte'];
|
||||
}
|
||||
|
||||
$radio['type'] = f('type')??$doc['type'];
|
||||
}
|
||||
$tpl->assign('types_details', $facture->types);
|
||||
|
@ -7,6 +7,8 @@ use Paheko\Utils;
|
||||
|
||||
define('DEVIS', 0);
|
||||
define('FACT', 1);
|
||||
define('CERFA', 2);
|
||||
define('COTIS', 3);
|
||||
|
||||
const PATTERNS_LIST = [
|
||||
null => 'Aucun, le numéro sera à spécifier manuellement pour chaque document',
|
||||
@ -46,11 +48,11 @@ $tpl->register_function('money_fac', function (array $params)
|
||||
|
||||
if (!isset($user)) {
|
||||
$user = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($name))
|
||||
{
|
||||
$name = 'prix[]';
|
||||
$name = 'prix[]';
|
||||
}
|
||||
|
||||
if (null !== $current_value && !$user) {
|
||||
@ -60,7 +62,7 @@ $tpl->register_function('money_fac', function (array $params)
|
||||
if (null !== $current_value) {
|
||||
$current_value = htmlspecialchars($current_value, ENT_QUOTES, 'UTF-8');
|
||||
}
|
||||
|
||||
|
||||
$currency = Config::getInstance()->get('monnaie');
|
||||
return sprintf('<td><nobr><input type="text" pattern="[0-9]*([.,][0-9]{1,2})?" inputmode="decimal" size="8" class="money" style="width: 60%%" onchange="updateSum();" name="%s" value="%s" /><b>%s</b></nobr></td>', $name, $current_value, $currency);
|
||||
}
|
||||
|
386
admin/pdf.php
386
admin/pdf.php
@ -67,74 +67,82 @@ if (isset($f->date_echeance))
|
||||
|
||||
// -- Création du PDF
|
||||
|
||||
// Génération factures, devis
|
||||
switch ($f->type_facture)
|
||||
// Génération factures, devis et cotisation
|
||||
if ($f->type_facture != CERFA)
|
||||
{
|
||||
case FACT:
|
||||
$doc = 'Facture n° '. $f->numero;
|
||||
$txtemis = $doc . " - Émise le " . $emission;
|
||||
$txtdest = "Adressée à :";
|
||||
break;
|
||||
case DEVIS:
|
||||
$doc = 'Devis n° '. $f->numero;
|
||||
$txtemis = $doc . " - Émis le " . $emission;
|
||||
$txtdest = "Adressé à :";
|
||||
break;
|
||||
}
|
||||
switch ($f->type_facture)
|
||||
{
|
||||
case FACT:
|
||||
$doc = 'Facture n° '. $f->numero;
|
||||
$txtemis = $doc . " - Émise le " . $emission;
|
||||
$txtdest = "Adressée à :";
|
||||
break;
|
||||
case DEVIS:
|
||||
$doc = 'Devis n° '. $f->numero;
|
||||
$txtemis = $doc . " - Émis le " . $emission;
|
||||
$txtdest = "Adressé à :";
|
||||
break;
|
||||
case COTIS:
|
||||
$doc = 'Reçu de cotisation n° '. $f->numero;
|
||||
$txtemis = $doc . " - Émis le " . $emission;
|
||||
$txtdest = "Adressé à :";
|
||||
break;
|
||||
}
|
||||
|
||||
// utiliser l'adresse configurée dans le plugin sinon celle de l'asso sinon rien !
|
||||
if ($plugin->getConfig('rue_asso') != null &&
|
||||
$plugin->getConfig('cp_asso') != null &&
|
||||
$plugin->getConfig('ville_asso') != null)
|
||||
{
|
||||
$adresse =
|
||||
(($plugin->getConfig('numero_rue_asso') != null) ? $plugin->getConfig('numero_rue_asso') . " " : "") .
|
||||
$plugin->getConfig('rue_asso') . "<br>" .
|
||||
$plugin->getConfig('cp_asso') . " " .
|
||||
$plugin->getConfig('ville_asso');
|
||||
}
|
||||
else if ($config->get('org_address') != null)
|
||||
{
|
||||
$adresse = str_replace("\n", '<br>', $config->get('org_address'));
|
||||
}
|
||||
else {
|
||||
$adresse = "";
|
||||
}
|
||||
// utiliser l'adresse configurée dans le plugin sinon celle de l'asso sinon rien !
|
||||
if ($plugin->getConfig('rue_asso') != null &&
|
||||
$plugin->getConfig('cp_asso') != null &&
|
||||
$plugin->getConfig('ville_asso') != null)
|
||||
{
|
||||
$adresse =
|
||||
(($plugin->getConfig('numero_rue_asso') != null) ? $plugin->getConfig('numero_rue_asso') . " " : "") .
|
||||
$plugin->getConfig('rue_asso') . "<br>" .
|
||||
$plugin->getConfig('cp_asso') . " " .
|
||||
$plugin->getConfig('ville_asso');
|
||||
}
|
||||
else if ($config->get('org_address') != null)
|
||||
{
|
||||
$adresse = str_replace("\n", '<br>', $config->get('org_address'));
|
||||
}
|
||||
else {
|
||||
$adresse = "";
|
||||
}
|
||||
|
||||
$logo='';
|
||||
if ($plugin->getConfig('logo')) {
|
||||
$logo = '<img id="logo" src="' . $config->fileURL('logo') . '" />';
|
||||
}
|
||||
$asso =
|
||||
// 'Émis par :<br><br>'.
|
||||
'<b>'.$config->get('org_name')."</b><br>".
|
||||
$adresse ."<br>".
|
||||
(($t = $plugin->getConfig('rna_asso'))?"RNA : $t<br>":'').
|
||||
(($t = $plugin->getConfig('siret_asso'))?"SIRET : " . implode(' ', str_split($t, 3)) . "<br>":'').
|
||||
(($t = $config->get('email_asso'))?"Email : $t<br>":'').
|
||||
(($t = $config->get('site_asso'))?"Site web : $t<br>":'');
|
||||
$logo='';
|
||||
if ($plugin->getConfig('logo')) {
|
||||
$logo = '<img id="logo" src="' . $config->fileURL('logo') . '" />';
|
||||
}
|
||||
$asso =
|
||||
// 'Émis par :<br><br>'.
|
||||
'<b>'.$config->get('org_name')."</b><br>".
|
||||
$adresse ."<br>".
|
||||
(($t = $plugin->getConfig('rna_asso'))?"RNA : $t<br>":'').
|
||||
(($t = $plugin->getConfig('siret_asso'))?"SIRET : " . implode(' ', str_split($t, 3)) . "<br>":'').
|
||||
(($t = $config->get('email_asso'))?"Email : $t<br>":'').
|
||||
(($t = $config->get('site_asso'))?"Site web : $t<br>":'');
|
||||
|
||||
$receveur =
|
||||
$txtdest.'<br>'.
|
||||
'<b>'.$c->nom.'</b><br>'.
|
||||
$c->adresse."<br>".
|
||||
$c->code_postal.' '.$c->ville."<br>".
|
||||
(($t = $c->siret)?"SIREN/SIRET : " . implode(' ', str_split($t, 3)) . "<br>":'').
|
||||
(($t = $c->email)?"Email : $t<br>":'').
|
||||
(($t = $c->telephone)?"Tel : $t<br>":'');
|
||||
$receveur =
|
||||
$txtdest.'<br>'.
|
||||
'<b>'.$c->nom.'</b><br>'.
|
||||
$c->adresse."<br>".
|
||||
$c->code_postal.' '.$c->ville."<br>".
|
||||
(($t = $c->siret)?"SIREN/SIRET : " . implode(' ', str_split($t, 3)) . "<br>":'').
|
||||
(($t = $c->email)?"Email : $t<br>":'').
|
||||
(($t = $c->telephone)?"Tel : $t<br>":'');
|
||||
|
||||
$total = Utils::money_format($f->total, ',', ' ');
|
||||
$total = Utils::money_format($f->total, ',', ' ');
|
||||
|
||||
// Devis et facture
|
||||
{
|
||||
$echeance = ($f->type_facture?'Échéance de paiement':'Échéance du devis')." : ".$echeance;
|
||||
$reglee = !$f->reglee?'Cette facture est en attente de règlement.':'Cette facture a été réglée.';
|
||||
$footer = str_replace("\n", '<br>', $plugin->getConfig('footer') ?? '[Pied de page à configurer]');
|
||||
$ttc = $plugin->getConfig('ttc') ? 'TTC':'HT';
|
||||
// Devis et facture
|
||||
if ($f->type_facture != COTIS)
|
||||
{
|
||||
$echeance = ($f->type_facture?'Échéance de paiement':'Échéance du devis')." : ".$echeance;
|
||||
$reglee = !$f->reglee?'Cette facture est en attente de règlement.':'Cette facture a été réglée.';
|
||||
$footer = str_replace("\n", '<br>', $plugin->getConfig('footer') ?? '[Pied de page à configurer]');
|
||||
$ttc = $plugin->getConfig('ttc') ? 'TTC':'HT';
|
||||
|
||||
// Génération du contenu de la facture
|
||||
ob_start();
|
||||
echo <<<EOF
|
||||
// Génération du contenu de la facture
|
||||
ob_start();
|
||||
echo <<<EOF
|
||||
<div class="h2">
|
||||
<span>Contenu</span> - $doc
|
||||
</div>
|
||||
@ -154,18 +162,18 @@ $total = Utils::money_format($f->total, ',', ' ');
|
||||
<tbody>
|
||||
EOF;
|
||||
|
||||
$i = 1;
|
||||
foreach($f->contenu as $k=>$v)
|
||||
{
|
||||
echo '<tr><td>';
|
||||
echo str_replace("\n", '<br>', $v['designation']);
|
||||
echo '</td><td>';
|
||||
echo Utils::money_format($v['prix'], ',', ' ') .' €';
|
||||
echo '</td></tr>';
|
||||
$i++;
|
||||
}
|
||||
$i = 1;
|
||||
foreach($f->contenu as $k=>$v)
|
||||
{
|
||||
echo '<tr><td>';
|
||||
echo str_replace("\n", '<br>', $v['designation']);
|
||||
echo '</td><td>';
|
||||
echo Utils::money_format($v['prix'], ',', ' ') .' €';
|
||||
echo '</td></tr>';
|
||||
$i++;
|
||||
}
|
||||
|
||||
echo <<<EOF
|
||||
echo <<<EOF
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
@ -188,14 +196,52 @@ EOF;
|
||||
</footer>
|
||||
EOF;
|
||||
|
||||
$content = ob_get_clean();
|
||||
$content = ob_get_clean();
|
||||
|
||||
}
|
||||
}
|
||||
else // Reçu de cotisation
|
||||
{
|
||||
$lieu = $plugin->getConfig('ville_asso');
|
||||
$intitule = $f->contenu['intitule'];
|
||||
|
||||
//-- Layout du document
|
||||
$souscription = date('d/m/Y', strtotime($f->contenu['souscription']));
|
||||
|
||||
ob_start();
|
||||
echo <<<EOF
|
||||
if($f->contenu['expiration'] == '1970-01-01')
|
||||
{
|
||||
$expiration = "jour même, s'agissant d'une cotisation ponctuelle.";
|
||||
}
|
||||
else {
|
||||
$expiration = date('d/m/Y', strtotime($f->contenu['expiration']));
|
||||
}
|
||||
|
||||
// Génération du contenu du reçu de cotisation
|
||||
$content = <<<EOF
|
||||
<div class="h2">
|
||||
<span>Reçu de votre cotisation</span> - $doc
|
||||
</div>
|
||||
<hr>
|
||||
<div class="contenuTexte">
|
||||
<p>À $lieu, le $emission,</p>
|
||||
<p>Bonjour,</p>
|
||||
|
||||
<p>Nous accusons réception de votre cotisation « $intitule » reçue le $emission et nous vous en remercions.</p>
|
||||
<p>Nous reconnaissons que vous avez acquitté la somme de {$total} €.<br>111
|
||||
Votre adhésion sera donc effective à compter du $souscription jusqu’au $expiration.</p>
|
||||
<br>
|
||||
|
||||
<p>Nous vous prions de recevoir, chère adhérente, cher adhérent, nos meilleures salutations,</p>
|
||||
<br>
|
||||
<p>-représentant·e de l'asso-</p>
|
||||
<br>
|
||||
<p><i>Nous vous rappelons que la cotisation n’est pas soumise à la TVA et qu’elle ne donne pas lieu à la délivrance d’une facture. Elle n’ouvre pas droit au bénéfice des dispositions des articles 200, 238 bis et 885-0 V bis A du code général des impôts.</i></p>
|
||||
</div>
|
||||
EOF;
|
||||
}
|
||||
|
||||
//-- Layout du document
|
||||
|
||||
ob_start();
|
||||
echo <<<EOF
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
@ -309,7 +355,191 @@ echo <<<EOF
|
||||
</html>
|
||||
EOF;
|
||||
|
||||
$html = ob_get_clean();
|
||||
$html = ob_get_clean();
|
||||
|
||||
} // 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'] = $c->nom;
|
||||
$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 <<<EOF
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>{$doc}_{$emission}</title>
|
||||
<style>
|
||||
@page {
|
||||
size: A4 portrait;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: Helvetica, Arial, sans;
|
||||
font-size: 10pt;
|
||||
background: white;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.page div {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.page {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
break-after: always;
|
||||
width: 210mm;
|
||||
height: 297mm;
|
||||
background-size: cover;
|
||||
background-position: -5mm -4.8mm;
|
||||
}
|
||||
|
||||
#p1 {
|
||||
background-image: url('{$url}p/facturation/cerfa-1.png');
|
||||
}
|
||||
|
||||
#p2 {
|
||||
background-image: url('{$url}p/facturation/cerfa-2.png');
|
||||
position: relative;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="page" id="p1">
|
||||
<div style="top: 10mm; left: 170mm;">{$t['numero']}</div>
|
||||
|
||||
<div style="top: 35mm; left: 20mm;">{$t['org_name']}</div>
|
||||
<div style="top: 46mm; left: 20mm;">{$t['n_rue_asso']}</div>
|
||||
<div style="top: 46mm; left: 40mm;">{$t['rue_asso']}</div>
|
||||
<div style="top: 51.5mm; left: 37mm;">{$t['cp_asso']}</div>
|
||||
<div style="top: 51.5mm; left: 75mm;">{$t['ville_asso']}</div>
|
||||
|
||||
<div style="top: 62mm; left: 18mm;">{$t['objet0']}</div>
|
||||
<div style="top: 66.5mm; left: 18mm;">{$t['objet1']}</div>
|
||||
<div style="top: 70.8mm; left: 18mm;">{$t['objet2']}</div>
|
||||
|
||||
<div style="top: 128.5mm; left: 15mm;">X</div>
|
||||
</div>
|
||||
<div class="page" id="p2">
|
||||
<div style="top: 18mm; left: 18mm;">{$t['nom']}</div>
|
||||
<div style="top: 32mm; left: 18mm;">{$t['adresse']}</div>
|
||||
<div style="top: 37mm; left: 40mm;">{$t['cp']}</div>
|
||||
<div style="top: 37mm; left: 80mm;">{$t['ville']}</div>
|
||||
|
||||
<div style="top: 63mm; left: 87mm;">{$t['total']}</div>
|
||||
<div style="top: 73mm; left: 58mm;">{$t['total_lettre']}</div>
|
||||
|
||||
<div style="top: 82mm; left: 69mm;">{$t['d']}</div>
|
||||
<div style="top: 82mm; left: 82mm;">{$t['m']}</div>
|
||||
<div style="top: 82mm; left: 99mm;">{$t['Y']}</div>
|
||||
|
||||
<div style="top: 96mm; left: 53mm;">{$t['art200']}</div>
|
||||
<div style="top: 96mm; left: 103mm;">{$t['art238']}</div>
|
||||
<div style="top: 96mm; left: 153.0mm;">{$t['art885']}</div>
|
||||
<div style="top: 113mm; {$t['frm']}">X</div>
|
||||
<div style="top: 136mm; {$t['nat']}">X</div>
|
||||
<div style="top: 142mm; left: 25mm;">{$t['texte']}</div>
|
||||
<div style="top: 158.2mm; {$t['pos']}">X</div>
|
||||
|
||||
<div style="top: 239mm; left: 139mm;">{$t['d2']}</div>
|
||||
<div style="top: 239mm; left: 148mm;">{$t['m2']}</div>
|
||||
<div style="top: 239mm; left: 156mm;">{$t['Y2']}</div>
|
||||
|
||||
<div style="top: 243mm; left: 137mm;">{$sign_tag}</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
EOF;
|
||||
|
||||
$html = ob_get_clean();
|
||||
|
||||
} // End if cerfa
|
||||
|
||||
|
||||
if(qg('d') !== null)
|
||||
|
@ -15,15 +15,17 @@ class Facture
|
||||
const TYPES_NAMES = [
|
||||
DEVIS => 'Devis',
|
||||
FACT => 'Facture',
|
||||
CERFA => 'Reçu fiscal',
|
||||
COTIS => 'Reçu de cotisation',
|
||||
];
|
||||
|
||||
private $keys = [
|
||||
'type_facture', // 0 : devis, 1 : facture
|
||||
'type_facture', // 0 : devis, 1 : facture, 2 : reçu cerfa, 3 : reçu cotis
|
||||
'numero',
|
||||
'receveur_membre',
|
||||
'receveur_id',
|
||||
'date_emission',
|
||||
'date_echeance',
|
||||
'date_emission', // Reçus : date du don
|
||||
'date_echeance', // Reçus : date d'édition du reçu
|
||||
'reglee',
|
||||
'archivee',
|
||||
'moyen_paiement',
|
||||
@ -42,6 +44,16 @@ class Facture
|
||||
'accounts' => [],
|
||||
'label' => 'Facture',
|
||||
'help' => ''],
|
||||
CERFA => [
|
||||
'id' => CERFA,
|
||||
'accounts' => [],
|
||||
'label' => 'Reçu fiscal',
|
||||
'help' => 'Reçu fiscal pour un don (membre ou client)'],
|
||||
COTIS => [
|
||||
'id' => COTIS,
|
||||
'accounts' => [],
|
||||
'label' => 'Reçu de cotisation',
|
||||
'help' => 'Reçu pour une cotisation payée par un·e membre'],
|
||||
];
|
||||
|
||||
public function __construct()
|
||||
@ -76,12 +88,18 @@ class Facture
|
||||
}
|
||||
if ($datas[$k] < 2) {
|
||||
$fac = true;
|
||||
$cerfa = false;
|
||||
$recu = false;
|
||||
}
|
||||
elseif ($datas[$k] == 2) {
|
||||
$fac = false;
|
||||
$cerfa = true;
|
||||
$recu = false;
|
||||
}
|
||||
elseif ($datas[$k] == 3) {
|
||||
$fac = false;
|
||||
$cerfa = false;
|
||||
$recu = true;
|
||||
}
|
||||
break;
|
||||
case 'receveur_membre':
|
||||
@ -144,9 +162,21 @@ class Facture
|
||||
throw new UserException("Toutes les désignations/prix sont vides.");
|
||||
}
|
||||
}
|
||||
elseif ($cerfa)
|
||||
{
|
||||
|
||||
}
|
||||
elseif ($recu)
|
||||
{
|
||||
// $fields = ['id', 'intitule', 'date', 'expiration'];
|
||||
// foreach ($datas[$k]as $)
|
||||
}
|
||||
$datas[$k] = json_encode($datas[$k]);
|
||||
break;
|
||||
case 'total':
|
||||
if ($cerfa && $datas[$k] < 1) {
|
||||
throw new UserException('Le total ne peut être inférieur à 1€ pour les reçus (bug encore non résolu).');
|
||||
}
|
||||
if ($fac && !isset($datas['contenu'])) {
|
||||
throw new UserException("Pas de contenu fourni pour vérifier le total.");
|
||||
}
|
||||
@ -200,6 +230,15 @@ class Facture
|
||||
$type = 'FACT';
|
||||
$t = 'F';
|
||||
}
|
||||
elseif ($type == CERFA) {
|
||||
$type = 'CERFA';
|
||||
$t = 'RF';
|
||||
}
|
||||
else {
|
||||
$type = 'COTIS';
|
||||
$t = 'RC';
|
||||
}
|
||||
|
||||
$year = $date->format('Y');
|
||||
$y = $date->format('y');
|
||||
|
||||
@ -376,9 +415,21 @@ class Facture
|
||||
// Remplir le contenu
|
||||
$content = json_decode((string)$row->contenu);
|
||||
|
||||
$row->contenu = implode("\n", array_map(function ($row) use ($currency) {
|
||||
return sprintf('%s : %s %s', $row->designation, Utils::money_format($row->prix), $currency);
|
||||
}, (array)$content));
|
||||
if ($row->type_facture == COTIS && isset($content->intitule, $content->souscription)) {
|
||||
$row->contenu = sprintf("Cotisation %s\nSouscrite le %s",
|
||||
$content->intitule,
|
||||
Utils::date_fr($content->souscription, 'd/m/Y')
|
||||
);
|
||||
}
|
||||
elseif ($row->type_facture != CERFA) {
|
||||
$row->contenu = implode("\n", array_map(function ($row) use ($currency) {
|
||||
return sprintf('%s : %s %s', $row->designation, Utils::money_format($row->prix), $currency);
|
||||
}, (array)$content));
|
||||
}
|
||||
else
|
||||
{
|
||||
$row->contenu = '';
|
||||
}
|
||||
});
|
||||
|
||||
return $list;
|
||||
@ -448,6 +499,31 @@ class Facture
|
||||
return DB::getInstance()->test('plugin_facturation_factures', 'receveur_membre = ? AND receveur_id = ?', $base, $id);
|
||||
}
|
||||
|
||||
// ** Pour type reçu **
|
||||
|
||||
public $recu_fields = ['id', 'label', 'amount', 'date', 'expiry', 'paid', 'paid_amount'];
|
||||
|
||||
public function getCotis(int $user_id, int $su_id = null)
|
||||
{
|
||||
$where = 'WHERE su.id_user = ?';
|
||||
if (null !== $su_id)
|
||||
{
|
||||
$where .= ' AND su.id = '.$su_id;
|
||||
}
|
||||
|
||||
$sql = 'SELECT su.id, s.label, su.date, MAX(su.expiry_date) as expiry, sf.label as fee, sf.amount as amount, su.paid, SUM(tl.debit) as paid_amount
|
||||
FROM services_users su
|
||||
INNER JOIN services s ON s.id = su.id_service
|
||||
LEFT JOIN services_fees sf ON sf.id = su.id_fee
|
||||
LEFT JOIN acc_transactions_users tu ON tu.id_service_user = su.id
|
||||
LEFT JOIN acc_transactions_lines tl ON tl.id_transaction = tu.id_transaction
|
||||
'.$where.'
|
||||
GROUP BY su.id
|
||||
ORDER BY su.date;';
|
||||
|
||||
return DB::getInstance()->get($sql, $user_id);
|
||||
}
|
||||
|
||||
public function listMoyensPaiement($assoc = false)
|
||||
{
|
||||
$db = DB::getInstance();
|
||||
@ -462,6 +538,17 @@ class Facture
|
||||
}
|
||||
}
|
||||
|
||||
/* modif DD -- lecture et retour des textes de CERFA -- */
|
||||
public function listTextesCerfa($menu = true)
|
||||
{
|
||||
$db = DB::getInstance();
|
||||
|
||||
$sel = ($menu) ? 'id, menu' : 'id, texte';
|
||||
$query = 'SELECT '.$sel.' FROM "plugin_facturation_txt_cerfa" WHERE 1 ORDER BY id ;';
|
||||
|
||||
return $db->getAssoc($query);
|
||||
}
|
||||
|
||||
public function getMoyenPaiement($code)
|
||||
{
|
||||
$db = DB::getInstance();
|
||||
|
BIN
public/cerfa-1.png
Normal file
BIN
public/cerfa-1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 121 KiB |
BIN
public/cerfa-2.png
Normal file
BIN
public/cerfa-2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 72 KiB |
@ -24,6 +24,8 @@
|
||||
<fieldset>
|
||||
<legend data-types="t0">Créer un devis</legend>
|
||||
<legend data-types="t1">Créer une facture</legend>
|
||||
<legend data-types="t2">Créer un reçu fiscal</legend>
|
||||
<legend data-types="t3">Créer un reçu de cotisation</legend>
|
||||
<dl>
|
||||
|
||||
{input type="text" name="numero_facture" maxlength=18 label="Numéro du document" required=$require_number source=$doc}
|
||||
@ -36,21 +38,27 @@
|
||||
{/if}
|
||||
|
||||
{input type="date" name="date_emission" default=$date label="Date d'émission" required=1 source=$doc}
|
||||
<div data-types="t0 t1">
|
||||
<dd class="help" data-types="t2">
|
||||
<p>Date du versemen du don</p>
|
||||
</dd>
|
||||
<div data-types="t0 t1 t2">
|
||||
{input type="date" name="date_echeance" default=$date label="Date d'échéance" required=1 source=$doc}
|
||||
<dd class="help" data-types="t2">
|
||||
<p>Date d'établissement du document</p>
|
||||
</dd>
|
||||
</div>
|
||||
|
||||
<dt><label>Statut</label></dt>
|
||||
|
||||
|
||||
{input type="checkbox" name="reglee" value="1" label="Réglée" source=$doc data-types="t1"}
|
||||
<div data-types="t0 t1">
|
||||
<div data-types="t0 t1 t2">
|
||||
{input type="checkbox" name="archivee" value="1" label="Archivée" source=$doc disabled="disabled"}
|
||||
</div>
|
||||
|
||||
</dl>
|
||||
</fieldset>
|
||||
|
||||
<fieldset data-types="t0 t1">
|
||||
<fieldset data-types="t0 t1 t2">
|
||||
<legend>Client</legend>
|
||||
|
||||
<dl>
|
||||
@ -105,14 +113,14 @@
|
||||
<td class="fact_rm_line">{button label="Enlever" title="Enlever la ligne" shape="minus" min="2" name="remove_line"}</td>
|
||||
</tr>
|
||||
|
||||
{foreach from=$designations item=designation key=key}
|
||||
{foreach from=$designations item=designation key=key}
|
||||
<tr>
|
||||
<td><textarea name="designation[]" style="width:98%;">{$designation}</textarea></td>
|
||||
{money_fac value=$prix[$key] user=$from_user}
|
||||
<td class="fact_rm_line">{button label="Enlever" title="Enlever la ligne" shape="minus" min="2" name="remove_line"}</td>
|
||||
</tr>
|
||||
{/foreach}
|
||||
{else}
|
||||
{else}
|
||||
<tr id="Line1" class="hidden">
|
||||
<td><textarea name="designation_tpl[]" style="width:98%;"></textarea></td>
|
||||
{money_fac name="prix_tpl[]"}
|
||||
@ -131,12 +139,102 @@
|
||||
</dd>
|
||||
</dl>
|
||||
</fieldset>
|
||||
|
||||
<fieldset data-types="t2">
|
||||
<legend>Contenu</legend>
|
||||
<dl>
|
||||
{input type="money" name="total" label="Montant du don" required=1 source=$doc default="0,0"}
|
||||
{input type="select" name="forme_don" required=1 label="Forme du don" source=$doc options=$formes_don default=$doc.forme_don}
|
||||
{input type="select" name="nature_don" required=1 label="Nature du don" source=$doc options=$natures_don default=$doc.nature_don}
|
||||
{input type="select" name="texte_don" required=1 label="Texte explicatif" source=$doc options=$textes_don default=$doc.texte_don}
|
||||
{input type="select" name="moyen_paiement_cerfa" required=1 label="Moyen de paiement" source=$doc options=$moyens_paiement default=$doc.moyen_paiement_cerfa}
|
||||
</dl>
|
||||
|
||||
<p class="submit" data-types="t0 t1">
|
||||
</fieldset>
|
||||
|
||||
<p class="submit" data-types="t0 t1 t2">
|
||||
{csrf_field key=$csrf_key}
|
||||
{button type="submit" name="save" label="Enregistrer" shape="right" class="main"}
|
||||
</p>
|
||||
|
||||
<fieldset data-types="t3">
|
||||
<legend>Membre</legend>
|
||||
<dl>
|
||||
<dt><label>Reçu adressée à :</label></dt>
|
||||
<dd>
|
||||
{input type="select" name="membre_cotis" label="Membre" options=$users required=1 default=$doc.membre}
|
||||
</dd>
|
||||
</dl>
|
||||
</fieldset>
|
||||
|
||||
<p class="submit" data-types="t3">
|
||||
{csrf_field key="add_cotis_1"}
|
||||
{button type="submit" name="select_cotis" label="Sélectionner" shape="right" class="main"}
|
||||
</p>
|
||||
|
||||
|
||||
{if $step}
|
||||
<fieldset data-types="t3">
|
||||
<legend>Cotisation</legend>
|
||||
{if count($liste)}
|
||||
<dl>
|
||||
<dt>Sélectionnez la cotisation concernée :</dt>
|
||||
|
||||
<table class='list'>
|
||||
<thead>
|
||||
<td></td>
|
||||
<td>Id</td>
|
||||
<td>Intitulé</td>
|
||||
<td>Date d'inscription</td>
|
||||
<td>Expiration d'expiration</td>
|
||||
<td>Tarif</td>
|
||||
<td>Montant</td>
|
||||
<td>Somme payée</td>
|
||||
</thead>
|
||||
|
||||
{foreach from=$liste item=cotis key=i}
|
||||
{if !$cotis.paid}
|
||||
{continue}
|
||||
{/if}
|
||||
<tr>
|
||||
<td>
|
||||
{input type="radio" name="cotisation" value="%s"|args:$i}
|
||||
</td>
|
||||
{foreach from=$cotis item=element key=key}
|
||||
{if $key == 'paid'}
|
||||
{continue}
|
||||
{/if}
|
||||
<td>
|
||||
<label for="f_cotisation_{$i}">
|
||||
{if ($key == 'date' || $key == 'expiry') && $element > 0}
|
||||
{$element|date_short}
|
||||
{elseif $key == 'amount' OR $key == 'paid_amount'}
|
||||
{$element|raw|money_currency}
|
||||
{else}
|
||||
{$element}
|
||||
{/if}
|
||||
|
||||
<input type="hidden" name="{$key}_{$i}" value="{$element}">
|
||||
</label>
|
||||
</td>
|
||||
{/foreach}
|
||||
</tr>
|
||||
{/foreach}
|
||||
</table>
|
||||
|
||||
</dl>
|
||||
</fieldset>
|
||||
|
||||
<p class="submit" data-types="t3">
|
||||
{csrf_field key="add_cotis_2"}
|
||||
{button type="submit" name="add_cotis" label="Enregistrer" shape="right" class="main"}
|
||||
</p>
|
||||
{else}
|
||||
<p>Ce membre n'a aucune cotisation payée.</p>
|
||||
</fieldset>
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
</form>
|
||||
|
||||
{include file="%s/templates/_js.tpl"|args:$plugin_root}
|
||||
|
@ -19,8 +19,8 @@
|
||||
function plus(){
|
||||
var newdiv = document.createElement('tr');
|
||||
newdiv.innerHTML = document.getElementById('Line1').innerHTML;
|
||||
newdiv.getElementsByTagName('textarea')[0].setAttribute('name', 'designation[]');
|
||||
newdiv.getElementsByTagName('input')[0].setAttribute('name', 'prix[]');
|
||||
newdiv.getElementsByTagName('textarea')[0].setAttribute('name', 'designation[]');
|
||||
newdiv.getElementsByTagName('input')[0].setAttribute('name', 'prix[]');
|
||||
newdiv.querySelector('.fact_rm_line button').onclick = function(){
|
||||
this.parentNode.parentNode.parentNode.removeChild(this.parentNode.parentNode);
|
||||
updateSum();
|
||||
@ -33,12 +33,12 @@
|
||||
|
||||
$('#ajouter_ligne').onclick = plus;
|
||||
|
||||
a = document.querySelectorAll('[name="remove_line"]');
|
||||
a = document.querySelectorAll('[name="remove_line"]');
|
||||
l = a.length;
|
||||
for(i = 0; i < l; i++) {
|
||||
a[i].onclick = function(){
|
||||
this.parentNode.parentNode.parentNode.removeChild(this.parentNode.parentNode);
|
||||
updateSum();
|
||||
updateSum();
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,8 @@
|
||||
</dl>
|
||||
</fieldset>
|
||||
|
||||
<p>Pensez à mettre une image en signature (cela sert pour les reçus fiscaux), cela se passe dans la {link href="!config/custom.php" label="configuration de Paheko, onglet personnalisation"}. Il est préférable d'avoir un fond transparent.
|
||||
</p>
|
||||
<ul>
|
||||
<li>Pour créer un reçu sur une cotisation, il vaut mieux utiliser le module {link href="!config/ext" label="Reçu de paiement"} intégré à Paheko.</li>
|
||||
<li>Pour créer un reçu fiscal, il vaut mieux utiliser le module {link href="!config/ext" label="Reçus fiscaux"} intégré à Paheko.</li>
|
||||
|
@ -14,7 +14,7 @@
|
||||
<?php continue; ?>
|
||||
{/if}
|
||||
{if $key == 'siret'}
|
||||
<?php
|
||||
<?php
|
||||
if (null === $value) { $value = ""; }
|
||||
$value = implode(' ', str_split($value, 3));
|
||||
?>
|
||||
|
@ -27,6 +27,25 @@
|
||||
{input type="text" name="ville_asso" source=$conf label="Ville"}
|
||||
</dl>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>Objet</legend>
|
||||
<dl>
|
||||
<dt><label>L'objet (but) de l'association doit tenir sur 3 lignes, chaque ligne pouvant accueillir un maximum de 100 caractères.</label><b title="(Champ obligatoire)">obligatoire pour reçus fiscaux</b></dt>
|
||||
{input type="text" name="objet_0" source=$conf label="Ligne 1" maxlength=95}
|
||||
{input type="text" name="objet_1" source=$conf label="Ligne 2" maxlength=95}
|
||||
{input type="text" name="objet_2" source=$conf label="Ligne 3" maxlength=95}
|
||||
</dl>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<legend>Droit à la réduction d'impôt</legend>
|
||||
<dl>
|
||||
<dt><label>Articles concernés par l'association :</label> <b title="(Champ obligatoire)">obligatoire pour reçus fiscaux</b></dt>
|
||||
{input type="checkbox" name="droit_art200" value="1" source=$conf label="Article 200"}
|
||||
{input type="checkbox" name="droit_art238bis" value="1" source=$conf label="Article 238 bis"}
|
||||
{input type="checkbox" name="droit_art885_0VbisA" value="1" source=$conf label="Article 885-0V bis A"}
|
||||
</dl>
|
||||
</fieldset>
|
||||
|
||||
</fieldset>
|
||||
|
||||
@ -55,7 +74,7 @@
|
||||
{input type="checkbox" name="unique_client_name" value="1" source=$conf label="Noms des clients uniques"}
|
||||
{input type="select" name="pattern" label="Format de numéro de document" required=false options=$patterns source=$conf}
|
||||
<dd class="help">
|
||||
F = Facture, D = Devis
|
||||
F = Facture, D = Devis, RF = Reçu fiscal, RC = Reçu cotisation
|
||||
</dd>
|
||||
</dl>
|
||||
<i>Pour personnaliser l'apparence de la facture, il faut pour l'instant se retrousser les manches et éditer soi-même le fichier www/admin/pdf.php du plugin ! </i>
|
||||
|
Loading…
Reference in New Issue
Block a user