Compare commits
12 commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
4aafa3f44f | ||
![]() |
aff20099aa | ||
![]() |
950a6b8b2c | ||
![]() |
4ee3f65d0a | ||
![]() |
060802a43d | ||
![]() |
f63f3b6ecd | ||
![]() |
6e2ee31670 | ||
![]() |
38494a1a85 | ||
![]() |
6248904bd8 | ||
![]() |
f6eef8897e | ||
![]() |
201682f4d7 | ||
![]() |
77180a38ff |
23 changed files with 839 additions and 161 deletions
|
@ -1,3 +1,11 @@
|
|||
0.12
|
||||
- Ajout Mollie à la table moyens de paiement
|
||||
0.11
|
||||
- Changement mention finale pour devis
|
||||
0.9
|
||||
- Ajout possibilité choisir champs identité et adresse membre
|
||||
0.8.8
|
||||
- correction typo
|
||||
0.8.7
|
||||
- correction typo
|
||||
0.8.6
|
||||
|
|
|
@ -24,7 +24,7 @@ le dossier plugins de Paheko.
|
|||
- **Configuration** :
|
||||
- Possibilité d'ajouter un numéro RNA et SIRET de l'association si elle en possède (apparait alors sur les documents)
|
||||
- Possibilité de choisir certains champs à faire figurer sur la facture (adresse, code postal, ville)
|
||||
- Modification du pied de page des documents (notament pour y inscrire des mentions légales)
|
||||
- Modification du pied de page des documents (notamment pour y inscrire des mentions légales)
|
||||
- Vérifier le code postal : si coché, lors d'ajout ou de modification de client, le plugin vérifiera que le code postal entré est bien formaté (par rapport aux codes postaux français seulement)
|
||||
- Noms de client·es uniques : si coché, lors d'ajout ou de modification de client·e, le nom du/de la client·e ne pourra pas être le même que celui d'un·e client·e déjà existant
|
||||
- (obsolète) Informations relatives au CERFA pour les reçus fiscaux
|
||||
|
|
|
@ -43,10 +43,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',
|
||||
|
@ -54,6 +58,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']);
|
||||
|
@ -84,6 +89,7 @@ $form->runIf(f('save') && !$form->hasErrors(),
|
|||
'reglee' => f('reglee') == 1?1:0,
|
||||
'archivee' => f('archivee') == 1?1:0,
|
||||
'moyen_paiement' => f('moyen_paiement'),
|
||||
'nom_contact' => f('nom_contact'),
|
||||
'toto' => 0
|
||||
];
|
||||
$data['type_facture'] = f('type');
|
||||
|
@ -91,8 +97,13 @@ $form->runIf(f('save') && !$form->hasErrors(),
|
|||
{
|
||||
foreach(f('designation') as $k=>$value)
|
||||
{
|
||||
if ($value != '' && f('prix')[$k] == null) {
|
||||
if (empty($value) && f('prix')[$k] != null) {
|
||||
throw new UserException("Il manque la désignation de la ligne " . $k+1 . " !!");
|
||||
}
|
||||
elseif ($value != '' && f('prix')[$k] == null) {
|
||||
throw new UserException('Il manque le prix sur la ligne '. $k+1 . ' !!');
|
||||
} elseif (empty($value) && f('prix')[$k] == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$data['contenu'][$k]['designation'] = $value;
|
||||
|
@ -100,6 +111,23 @@ $form->runIf(f('save') && !$form->hasErrors(),
|
|||
$data['toto'] += Utils::moneyToInteger(f('prix')[$k]);
|
||||
}
|
||||
$data['total'] = $data['toto'];
|
||||
unset($data['toto']);
|
||||
if (! isset($data['contenu'])) {
|
||||
throw new UserException("Aucune désignation ni aucun prix saisi !!");
|
||||
}
|
||||
if (f('type') == FACT) {
|
||||
$data['numero_commande'] = f('numero_commande');
|
||||
$data['reference_acheteur'] = f('reference_acheteur');
|
||||
}
|
||||
}
|
||||
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')
|
||||
|
@ -125,9 +153,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)
|
||||
{
|
||||
|
@ -159,13 +240,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é
|
||||
|
@ -194,6 +281,17 @@ 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:---
|
||||
$doc['nom_contact'] = $f->nom_contact;
|
||||
$doc['numero_commande'] = $f->numero_commande;
|
||||
$doc['reference_acheteur'] = $f->reference_acheteur;
|
||||
/* 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);
|
||||
|
@ -232,8 +330,10 @@ if (in_array($radio['type'], [DEVIS, FACT]))
|
|||
}
|
||||
}
|
||||
else {
|
||||
/*
|
||||
$designations = ['Exemple'];
|
||||
$prix = [250];
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -244,6 +344,7 @@ $tpl->assign('date', $date->format('d/m/Y'));
|
|||
$tpl->assign(compact('liste', 'radio', 'step', 'designations', 'prix', 'from_user', 'identite', 'csrf_key', 'doc'));
|
||||
$tpl->assign('users', toArray($db->get('SELECT id, '.$identite.' FROM users WHERE id_category != -2 NOT IN (SELECT id FROM users_categories WHERE hidden = 1) ORDER BY ' .$identite. ';'), 'id', " "));
|
||||
$tpl->assign('clients', $db->getAssoc('SELECT id, nom FROM plugin_facturation_clients;'));
|
||||
$tpl->assign('contacts', $db->getAssoc('SELECT id, nom_contact FROM plugin_facturation_clients;'));
|
||||
$tpl->assign('require_number', $require_number);
|
||||
$tpl->assign('number_pattern', PATTERNS_LIST[$plugin->getConfig('pattern')]);
|
||||
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -28,7 +28,9 @@ $form->runIf(f('save') && !$form->hasErrors(),
|
|||
'ville' => f('ville'),
|
||||
'siret' => f('siret'),
|
||||
'telephone' => f('telephone'),
|
||||
'email' => f('email')
|
||||
'email' => f('email'),
|
||||
'nom_contact' => f('nom_contact'),
|
||||
'note' => f('note')
|
||||
]);
|
||||
|
||||
$r ? Utils::redirect(PLUGIN_ADMIN_URL . 'client.php?id='.(int)$id):'';
|
||||
|
|
|
@ -18,7 +18,9 @@ $form->runIf(f('add') && !$form->hasErrors(),
|
|||
'ville' => f('ville'),
|
||||
'siret' => f('siret'),
|
||||
'telephone' => f('telephone'),
|
||||
'email' => f('email')
|
||||
'email' => f('email'),
|
||||
'nom_contact' => f('nom_contact'),
|
||||
'note' => f('note')
|
||||
]);
|
||||
|
||||
$id ? Utils::redirect(PLUGIN_ADMIN_URL . 'client.php?id='.(int)$id):'';
|
||||
|
|
|
@ -20,18 +20,9 @@ $form->runIf('save', function () use ($plugin) {
|
|||
$plugin->setConfigProperty('cp_asso', trim(f('cp_asso')));
|
||||
$plugin->setConfigProperty('ville_asso', trim(f('ville_asso')));
|
||||
|
||||
$plugin->setConfigProperty('droit_art200', (bool)f('droit_art200'));
|
||||
$plugin->setConfigProperty('droit_art238bis', (bool)f('droit_art238bis'));
|
||||
$plugin->setConfigProperty('droit_art885_0VbisA', (bool)f('droit_art885_0VbisA'));
|
||||
$plugin->setConfigProperty('objet_0', trim(f('objet_0')));
|
||||
$plugin->setConfigProperty('objet_1', trim(f('objet_1')));
|
||||
$plugin->setConfigProperty('objet_2', trim(f('objet_2')));;
|
||||
|
||||
$plugin->setConfigProperty('logo', (bool)f('logo'));
|
||||
$plugin->setConfigProperty('footer', f('footer'));
|
||||
|
||||
$plugin->setConfigProperty('nom_client', f('nom_client'));
|
||||
$plugin->setConfigProperty('prenom_client', f('prenom_client'));
|
||||
$plugin->setConfigProperty('adresse_client', f('adresse_client'));
|
||||
$plugin->setConfigProperty('code_postal_client', f('code_postal_client'));
|
||||
$plugin->setConfigProperty('ville_client', f('ville_client'));
|
||||
|
|
251
admin/pdf.php
251
admin/pdf.php
|
@ -71,7 +71,9 @@ if (isset($f->date_echeance))
|
|||
|
||||
// -- Création du PDF
|
||||
|
||||
// Génération factures, devis
|
||||
// Génération factures, devis et cotisation
|
||||
if ($f->type_facture != CERFA)
|
||||
{
|
||||
switch ($f->type_facture)
|
||||
{
|
||||
case FACT:
|
||||
|
@ -82,6 +84,11 @@ switch ($f->type_facture)
|
|||
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;
|
||||
}
|
||||
|
@ -121,18 +128,28 @@ $asso =
|
|||
$receveur =
|
||||
$txtdest.'<br>'.
|
||||
'<b>'.$nom_client.'</b><br>'.
|
||||
(($t = $f->nom_contact)?"Contact : $t<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>":'');
|
||||
|
||||
if ($f->type_facture == FACT) {
|
||||
$receveur .=
|
||||
(($t = $f->numero_commande)?"Commande N° : $t<br>":'').
|
||||
(($t = $f->reference_acheteur)?"Référence : $t<br>":'');
|
||||
}
|
||||
$total = Utils::money_format($f->total, ',', ' ');
|
||||
|
||||
// Devis et facture
|
||||
if ($f->type_facture != COTIS)
|
||||
{
|
||||
$echeance = ($f->type_facture?'Échéance de paiement':'Échéance du devis')." : ".$echeance;
|
||||
if ($f->type_facture == FACT) {
|
||||
$reglee = !$f->reglee?'Cette facture est en attente de règlement.':'Cette facture a été réglée.';
|
||||
} else {
|
||||
$reglee = "";
|
||||
}
|
||||
$footer = str_replace("\n", '<br>', $plugin->getConfig('footer') ?? '[Pied de page à configurer]');
|
||||
$ttc = $plugin->getConfig('ttc') ? 'TTC':'HT';
|
||||
|
||||
|
@ -185,16 +202,59 @@ EOF;
|
|||
$echeance <br>
|
||||
$reglee
|
||||
Moyen de paiement : $moyen_paiement
|
||||
|
||||
<p>
|
||||
$footer
|
||||
</p>
|
||||
</footer>
|
||||
|
||||
EOF;
|
||||
if ($f->type_facture == DEVIS) {
|
||||
echo <<<EOF
|
||||
<p><b>Bon pour accord, date et signature<b></p>
|
||||
EOF;
|
||||
}
|
||||
|
||||
$content = ob_get_clean();
|
||||
|
||||
}
|
||||
else // Reçu de cotisation
|
||||
{
|
||||
$lieu = $plugin->getConfig('ville_asso');
|
||||
$intitule = $f->contenu['intitule'];
|
||||
|
||||
$souscription = date('d/m/Y', strtotime($f->contenu['souscription']));
|
||||
|
||||
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
|
||||
|
||||
|
@ -315,6 +375,191 @@ EOF;
|
|||
|
||||
$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'] = $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 <<<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)
|
||||
{
|
||||
$filename = 'Print';
|
||||
|
|
|
@ -10,7 +10,10 @@ CREATE TABLE IF NOT EXISTS plugin_facturation_factures (
|
|||
archivee INTEGER DEFAULT 0, -- bool
|
||||
moyen_paiement TEXT NOT NULL,
|
||||
contenu TEXT NOT NULL,
|
||||
total INTEGER DEFAULT 0
|
||||
total INTEGER DEFAULT 0,
|
||||
nom_contact TEXT,
|
||||
numero_commande TEXT,
|
||||
reference_acheteur TEXT
|
||||
|
||||
-- FOREIGN KEY(moyen_paiement) REFERENCES compta_moyens_paiement(code)
|
||||
);
|
||||
|
@ -24,7 +27,9 @@ CREATE TABLE IF NOT EXISTS plugin_facturation_clients (
|
|||
siret TEXT,
|
||||
date_creation TEXT NOT NULL DEFAULT CURRENT_DATE CHECK (date(date_creation) IS NOT NULL AND date(date_creation) = date_creation), -- Date d\'inscription
|
||||
telephone TEXT,
|
||||
email TEXT
|
||||
email TEXT,
|
||||
nom_contact TEXT,
|
||||
note TEXT
|
||||
);
|
||||
|
||||
|
||||
|
@ -43,6 +48,7 @@ INSERT OR IGNORE INTO plugin_facturation_paiement (code, nom) VALUES ('PR', 'Pr
|
|||
INSERT OR IGNORE INTO plugin_facturation_paiement (code, nom) VALUES ('TI', 'TIP');
|
||||
INSERT OR IGNORE INTO plugin_facturation_paiement (code, nom) VALUES ('VI', 'Virement');
|
||||
INSERT OR IGNORE INTO plugin_facturation_paiement (code, nom) VALUES ('HA', 'HelloAsso');
|
||||
INSERT OR IGNORE INTO plugin_facturation_paiement (code, nom) VALUES ('MO', 'Mollie');
|
||||
INSERT OR IGNORE INTO plugin_facturation_paiement (code, nom) VALUES ('AU', 'Autre');
|
||||
|
||||
-- Modif DD -- ajout de la table des textes associés aux CERFA
|
||||
|
|
|
@ -17,7 +17,9 @@ class Client
|
|||
'ville',
|
||||
'siret',
|
||||
'telephone',
|
||||
'email'
|
||||
'email',
|
||||
'nom_contact',
|
||||
'note'
|
||||
];
|
||||
|
||||
private $config = [
|
||||
|
@ -40,7 +42,7 @@ class Client
|
|||
{
|
||||
$data[$key] = trim($data[$key]);
|
||||
|
||||
if($data[$key] == '' && ($key != 'siret' && $key != 'telephone' && $key != 'email'))
|
||||
if($data[$key] == '' && ! in_array($key, ['siret', 'telephone', 'email', 'nom_contact', 'note']))
|
||||
{
|
||||
throw new UserException('Le champs '.$key.' doit être renseigné.');
|
||||
}
|
||||
|
@ -136,6 +138,12 @@ class Client
|
|||
'email' => [
|
||||
'label' => 'E-Mail',
|
||||
],
|
||||
'nom_contact' => [
|
||||
'label' => 'Contact',
|
||||
],
|
||||
'note' => [
|
||||
'label' => 'Note',
|
||||
],
|
||||
'nb_documents' => [
|
||||
'label' => 'Nombre de documents',
|
||||
'select' => '(SELECT COUNT(*) FROM plugin_facturation_factures WHERE receveur_id = c.id)',
|
||||
|
|
|
@ -15,20 +15,25 @@ 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',
|
||||
'contenu',
|
||||
'total'
|
||||
'total',
|
||||
'nom_contact',
|
||||
'numero_commande',
|
||||
'reference_acheteur'
|
||||
];
|
||||
|
||||
public $types = [
|
||||
|
@ -63,7 +68,7 @@ class Facture
|
|||
if(!is_array($data) && null !== $data){
|
||||
$datas[$k] = trim($data);
|
||||
}
|
||||
if ($datas[$k] === '' && $k != 'numero')
|
||||
if ($datas[$k] === '' && ! in_array($k, ['numero', 'nom_contact', 'numero_commande', 'reference_acheteur']))
|
||||
{
|
||||
throw new UserException("La valeur de $k est vide");
|
||||
}
|
||||
|
@ -76,12 +81,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':
|
||||
|
@ -126,10 +137,13 @@ class Facture
|
|||
unset($datas[$k]['prix']);
|
||||
continue;
|
||||
}
|
||||
elseif (empty($r['prix']))
|
||||
elseif (! is_numeric($r['prix']) && empty($r['prix']))
|
||||
{
|
||||
$datas[$k]['prix'] = 0;
|
||||
}
|
||||
elseif (empty($r['designation'])) {
|
||||
throw new UserException("Une au moins des désignations est absente.");
|
||||
}
|
||||
|
||||
if (!is_int($r['prix']))
|
||||
{
|
||||
|
@ -139,14 +153,26 @@ class Facture
|
|||
$total += $r['prix'];
|
||||
}
|
||||
|
||||
if($fac && !$total)
|
||||
if ($fac && count($datas['contenu']) == 0)
|
||||
{
|
||||
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 +226,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 +411,21 @@ class Facture
|
|||
// Remplir le contenu
|
||||
$content = json_decode((string)$row->contenu);
|
||||
|
||||
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 +495,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 +534,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();
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
name="Facturation"
|
||||
description="Permet d'éditer des factures, devis et reçus à ses membres ainsi qu'à une base de clients supplémentaire."
|
||||
description="Permet d'éditer des factures et devis à ses membres ainsi qu'à une base de clients supplémentaire."
|
||||
author="zou ; adapté par jce"
|
||||
url="https://git.roflcopter.fr/lesanges/paheko-plugin-facturation"
|
||||
version="0.8.7"
|
||||
version="0.15"
|
||||
menu=true
|
||||
restrict_section="accounting"
|
||||
restrict_level="read"
|
||||
|
|
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 |
|
@ -3,7 +3,7 @@
|
|||
<form method="post" action="{$self_url}">
|
||||
|
||||
<fieldset>
|
||||
<legend>Type d'écriture</legend>
|
||||
<legend>Type de document</legend>
|
||||
<dl>
|
||||
{foreach from=$types_details item="type"}
|
||||
<dd class="radio-btn">
|
||||
|
@ -30,28 +30,34 @@
|
|||
|
||||
<dd class="help">
|
||||
{if $require_number}
|
||||
Chaque document doit comporter un numéro unique délivré chronologiquement et de façon continue. Il faut que le système adopté par l'association garantisse que deux factures émises la même année ne peuvent pas porter le même numéro.
|
||||
Chaque document doit comporter un numéro unique délivré chronologiquement et de façon continue. Il faut que le système adopté par l'association garantisse que deux factures émises la même année ne puissent pas porter le même numéro.
|
||||
{else}
|
||||
Laisser vide pour qu'un numéro soit automatiquement affecté au format <code>{$number_pattern}</code>.
|
||||
{/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">
|
||||
<legend>Client</legend>
|
||||
<fieldset data-types="t0 t1 t2">
|
||||
<legend>Destinataire</legend>
|
||||
|
||||
<dl>
|
||||
<dt><label>Document adressé à :</label></dt>
|
||||
|
@ -64,18 +70,30 @@
|
|||
</dl>
|
||||
|
||||
<dl class="type_membre">
|
||||
{input type="select" name="membre" label="Membre" options=$users required=1 source=$doc}
|
||||
{input type="select" name="membre" label="Membre" options=$users required=1 source=$doc default_empty="— Choisir un membre —"}
|
||||
</dl>
|
||||
|
||||
{if !empty($clients)}
|
||||
<dl class="type_client">
|
||||
{input type="select" name="client" label="Client" options=$clients required=1 class="type_client" source=$doc}
|
||||
{input type="select" name="client" label="Client" options=$clients required=1 class="type_client" source=$doc default_empty="— Choisir un client —"}
|
||||
</dl>
|
||||
{else}
|
||||
<input type="hidden" name="base_receveur" value="membre" />
|
||||
{/if}
|
||||
</fieldset>
|
||||
|
||||
<fieldset data-types="t0 t1">
|
||||
<legend>Autres informations</legend>
|
||||
{input type="text" name="nom_contact" label="Nom du contact" source=$doc}
|
||||
<div class="hidden">
|
||||
{input type="select" name="contact_list" options=$contacts}
|
||||
</div>
|
||||
<div data-types="t1">
|
||||
{input type="text" name="numero_commande" label="Numéro de commande" source=$doc}
|
||||
{input type="text" name="reference_acheteur" label="Référence acheteur" source=$doc}
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset data-types="t0 t1">
|
||||
<legend>Contenu</legend>
|
||||
|
||||
|
@ -132,11 +150,101 @@
|
|||
</dl>
|
||||
</fieldset>
|
||||
|
||||
<p class="submit" data-types="t0 t1">
|
||||
<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>
|
||||
|
||||
</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}
|
||||
|
|
|
@ -51,6 +51,18 @@
|
|||
}
|
||||
}
|
||||
|
||||
function modifierContact(client, idlist, idcontact)
|
||||
{
|
||||
let contactlist = document.querySelector(idlist);
|
||||
let options = contactlist.querySelectorAll('option');
|
||||
for (i=0; i < options.length; ++i) {
|
||||
if (options[i].value == client.value) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
document.querySelector(idcontact).value = options[i].textContent;
|
||||
}
|
||||
|
||||
const form = document.querySelector('#f_numero_facture').form;
|
||||
changeTypeSaisie(form.base_receveur.value);
|
||||
|
||||
|
@ -63,6 +75,11 @@
|
|||
};
|
||||
}
|
||||
|
||||
const selclient = document.querySelector('#f_client');
|
||||
selclient.addEventListener("change", () => {
|
||||
modifierContact(selclient, '#f_contact_list', '#f_nom_contact');
|
||||
});
|
||||
|
||||
} ());
|
||||
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -48,6 +48,24 @@
|
|||
{/if}
|
||||
</dd>
|
||||
|
||||
<dt>Nom du contact</dt>
|
||||
<dd>
|
||||
{if empty($client.nom_contact)}
|
||||
<em>(Non renseigné)</em>
|
||||
{else}
|
||||
{$client.nom_contact}
|
||||
{/if}
|
||||
</dd>
|
||||
|
||||
<dt>Note</dt>
|
||||
<dd>
|
||||
{if empty($client.note)}
|
||||
<em>(Non renseigné)</em>
|
||||
{else}
|
||||
{$client.note}
|
||||
{/if}
|
||||
</dd>
|
||||
|
||||
<dt>Date d'ajout</dt>
|
||||
<dd>{$client.date_creation|date:'d/m/Y'}</dd>
|
||||
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
{input type="text" name="siret" label="SIREN/SIRET" source=$client}
|
||||
{input type="tel" name="telephone" label="Téléphone" source=$client}
|
||||
{input type="email" name="email" label="Adresse e-mail" source=$client}
|
||||
{input type="text" name="nom_contact" label="Nom du contact" source=$client}
|
||||
{input type="textarea" cols="60" rows="3" name="note" label="Note" source=$client}
|
||||
</dl>
|
||||
</fieldset>
|
||||
|
||||
|
|
|
@ -61,6 +61,8 @@
|
|||
{input type="text" name="siret" label="SIREN/SIRET"}
|
||||
{input type="tel" name="telephone" label="Téléphone"}
|
||||
{input type="email" name="email" label="Adresse e-mail"}
|
||||
{input type="text" name="nom_contact" label="Nom contact"}
|
||||
{input type="textarea" cols="60" rows="3" name="note" label="Note"}
|
||||
</dl>
|
||||
</fieldset>
|
||||
|
||||
|
|
|
@ -19,7 +19,10 @@
|
|||
</dl>
|
||||
<br>
|
||||
<fieldset>
|
||||
<legend>Adresse</legend>
|
||||
<legend>Adresse de l'association</legend>
|
||||
<dd class="help">
|
||||
à saisir uniquement si elle n'est pas dans la configuration de la compta ou si elle doit remplacer celle qui est définie dans la configuration de la compta
|
||||
</dd>
|
||||
<dl>
|
||||
{input type="text" name="numero_rue_asso" source=$conf label="Numéro de rue" maxlength=5}
|
||||
{input type="text" name="rue_asso" source=$conf label="Nom de rue"}
|
||||
|
@ -27,18 +30,17 @@
|
|||
{input type="text" name="ville_asso" source=$conf label="Ville"}
|
||||
</dl>
|
||||
</fieldset>
|
||||
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<legend>Factures</legend>
|
||||
<legend>Factures et devis</legend>
|
||||
<dl>
|
||||
{input type="checkbox" name="logo" value="1" source=$conf label="Imprimer le logo de l'association"}
|
||||
{input type="textarea" class="full-width" rows="5" name="footer" source=$conf label="Pied de document — informations légales" required=true}
|
||||
</dl>
|
||||
<fieldset>
|
||||
<legend>
|
||||
Choisir les champs à faire figurer sur la facture
|
||||
Choisir les champs à faire figurer sur la facture ou le devis pour l'adresse d'un membre
|
||||
</legend>
|
||||
<dl>
|
||||
{input type="select" name="adresse_client" label="Adresse" required=true options=$champsPaheko source=$conf}
|
||||
|
|
83
upgrade.php
83
upgrade.php
|
@ -6,7 +6,7 @@ use Paheko\Entities\Files\File;
|
|||
|
||||
$db = DB::getInstance();
|
||||
$old_version = $plugin->oldVersion();
|
||||
error_log("upgrade::version = " . $old_version);
|
||||
error_log("upgrade:: à partir de la version = " . $old_version);
|
||||
|
||||
// 0.2.0 - Stock le contenu en json plutôt qu'en serialized
|
||||
if (version_compare($old_version, '0.2.0', '<'))
|
||||
|
@ -211,7 +211,6 @@ if (version_compare($old_version, '0.8.1', '<'))
|
|||
}
|
||||
|
||||
// 0.8.5 Ajout champs SIREN/SIRET à la table clients
|
||||
|
||||
if (version_compare($old_version, '0.8.5', '<'))
|
||||
{
|
||||
$db->exec(<<<EOT
|
||||
|
@ -243,3 +242,83 @@ if (version_compare($old_version, '0.8.5', '<'))
|
|||
);
|
||||
}
|
||||
|
||||
// 0.12 Ajout Mollie à la table moyens de paiement
|
||||
if (version_compare($old_version, '0.12', '<'))
|
||||
{
|
||||
$db->exec(<<<EOT
|
||||
INSERT OR IGNORE INTO plugin_facturation_paiement
|
||||
(code, nom) VALUES ('MO', 'Mollie');
|
||||
EOT
|
||||
);
|
||||
}
|
||||
|
||||
// version 0.15
|
||||
// Ajout champs note et contact à la table clients
|
||||
// Ajout divers champs à la table factures
|
||||
if (version_compare($old_version, '0.15', '<'))
|
||||
{
|
||||
$db->exec(<<<EOT
|
||||
CREATE TABLE IF NOT EXISTS plugin_facturation_clients_tmp
|
||||
(
|
||||
id INTEGER PRIMARY KEY,
|
||||
nom TEXT NOT NULL,
|
||||
adresse TEXT NOT NULL,
|
||||
code_postal TEXT NOT NULL,
|
||||
ville TEXT NOT NULL,
|
||||
siret TEXT,
|
||||
date_creation TEXT NOT NULL DEFAULT CURRENT_DATE CHECK (date(date_creation) IS NOT NULL AND date(date_creation) = date_creation),
|
||||
telephone TEXT,
|
||||
email TEXT,
|
||||
nom_contact TEXT,
|
||||
note TEXT
|
||||
);
|
||||
EOT
|
||||
);
|
||||
// copier les clients dans la table temporaire
|
||||
$sql = 'SELECT * FROM plugin_facturation_clients';
|
||||
foreach ($db->iterate($sql) as $client)
|
||||
{
|
||||
$db->insert('plugin_facturation_clients_tmp', $client);
|
||||
}
|
||||
// remplacer l'ancienne table par la nouvelle
|
||||
$db->exec(<<<EOT
|
||||
DROP TABLE plugin_facturation_clients;
|
||||
ALTER TABLE plugin_facturation_clients_tmp RENAME TO plugin_facturation_clients;
|
||||
EOT
|
||||
);
|
||||
|
||||
$db->exec(<<<EOT
|
||||
CREATE TABLE IF NOT EXISTS plugin_facturation_factures_tmp(
|
||||
id INTEGER PRIMARY KEY,
|
||||
type_facture INTEGER NOT NULL DEFAULT 0,
|
||||
numero TEXT NOT NULL UNIQUE,
|
||||
receveur_membre INTEGER NOT NULL, -- bool
|
||||
receveur_id INTEGER NOT NULL,
|
||||
date_emission TEXT NOT NULL, -- CHECK (date(date_emission) IS NOT NULL AND date(date_emission) = date_emission),
|
||||
date_echeance TEXT NOT NULL, -- CHECK (date(date_echeance) IS NOT NULL AND date(date_echeance) = date_echeance),
|
||||
reglee INTEGER DEFAULT 0, -- bool
|
||||
archivee INTEGER DEFAULT 0, -- bool
|
||||
moyen_paiement TEXT NOT NULL,
|
||||
contenu TEXT NOT NULL,
|
||||
total INTEGER DEFAULT 0,
|
||||
nom_contact TEXT,
|
||||
numero_commande TEXT,
|
||||
reference_acheteur TEXT
|
||||
);
|
||||
EOT
|
||||
);
|
||||
|
||||
// copier les factures dans la table temporaire
|
||||
$sql = 'SELECT * FROM plugin_facturation_factures';
|
||||
foreach ($db->iterate($sql) as $facture)
|
||||
{
|
||||
$db->insert('plugin_facturation_factures_tmp', $facture);
|
||||
}
|
||||
// remplacer l'ancienne table par la nouvelle
|
||||
$db->exec(<<<EOT
|
||||
DROP TABLE plugin_facturation_factures;
|
||||
ALTER TABLE plugin_facturation_factures_tmp RENAME TO plugin_facturation_factures;
|
||||
EOT
|
||||
);
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue