diff --git a/data/schema.sql b/data/schema.sql
index 59af3f8..43b7d84 100644
--- a/data/schema.sql
+++ b/data/schema.sql
@@ -10,9 +10,9 @@ CREATE TABLE IF NOT EXISTS plugin_facturation_factures (
archivee INTEGER DEFAULT 0, -- bool
moyen_paiement TEXT NOT NULL,
contenu TEXT NOT NULL,
- total REAL DEFAULT 0,
+ total REAL DEFAULT 0
- FOREIGN KEY(moyen_paiement) REFERENCES compta_moyens_paiement(code)
+ -- FOREIGN KEY(moyen_paiement) REFERENCES compta_moyens_paiement(code)
);
CREATE TABLE IF NOT EXISTS plugin_facturation_clients (
@@ -27,6 +27,22 @@ CREATE TABLE IF NOT EXISTS plugin_facturation_clients (
email TEXT
);
+
+CREATE TABLE IF NOT EXISTS plugin_facturation_paiement
+-- Moyens de paiement
+(
+ code TEXT NOT NULL PRIMARY KEY,
+ nom TEXT NOT NULL
+);
+
+--INSERT INTO compta_moyens_paiement (code, nom) VALUES ('AU', 'Autre');
+INSERT OR IGNORE INTO plugin_facturation_paiement (code, nom) VALUES ('CB', 'Carte bleue');
+INSERT OR IGNORE INTO plugin_facturation_paiement (code, nom) VALUES ('CH', 'Chèque');
+INSERT OR IGNORE INTO plugin_facturation_paiement (code, nom) VALUES ('ES', 'Espèces');
+INSERT OR IGNORE INTO plugin_facturation_paiement (code, nom) VALUES ('PR', 'Prélèvement');
+INSERT OR IGNORE INTO plugin_facturation_paiement (code, nom) VALUES ('TI', 'TIP');
+INSERT OR IGNORE INTO plugin_facturation_paiement (code, nom) VALUES ('VI', 'Virement');
+
-- CREATE TABLE IF NOT EXISTS plugin_facturation_produits (
-- id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE,
-- designation TEXT,
diff --git a/data/schema_remove.sql b/data/schema_remove.sql
index 87f1d60..2a3e2dc 100644
--- a/data/schema_remove.sql
+++ b/data/schema_remove.sql
@@ -1,3 +1,4 @@
DROP TABLE `plugin_facturation_factures`;
DROP TABLE `plugin_facturation_clients`;
+DROP TABLE `plugin_facturation_paiement`;
-- DROP TABLE `plugin_facturation_produits`;
\ No newline at end of file
diff --git a/garradin_plugin.ini b/garradin_plugin.ini
index 3eac1d7..08b577b 100644
--- a/garradin_plugin.ini
+++ b/garradin_plugin.ini
@@ -2,7 +2,7 @@ nom="Facturation"
description="Permet d'éditer des factures, devis et reçus à ses membres ainsi qu'à une base de clients supplémentaire."
auteur="zou"
url="https://gitlab.com/ramoloss/garradin-plugin-facturation/"
-version="0.3.0"
+version="0.4.0"
menu=1
config=1
min_version="0.9.2"
\ No newline at end of file
diff --git a/lib/Client.php b/lib/Client.php
index d3ca58d..1bd92b6 100644
--- a/lib/Client.php
+++ b/lib/Client.php
@@ -45,7 +45,7 @@ class Client
if($key == 'ville')
{
- $data[$key] = mb_strtoupper($data[$key]);
+ $data[$key] = strtoupper($data[$key]);
}
elseif ($key == 'code_postal')
{
diff --git a/lib/Facture.php b/lib/Facture.php
index 4f3068f..1745828 100644
--- a/lib/Facture.php
+++ b/lib/Facture.php
@@ -2,8 +2,10 @@
namespace Garradin\Plugin\Facturation;
+use DateTime;
use Garradin\DB;
use Garradin\UserException;
+use Garradin\Services\Services_User;
class Facture
{
@@ -21,12 +23,28 @@ class Facture
'total'
];
- public $type = [
- 0 => 'devis',
- 1 => 'facture',
- 2 => 'cerfa',
- 3 => 'cotis',
- ];
+ public $types = [
+ DEVIS => [
+ 'id' => DEVIS,
+ 'accounts' => [],
+ 'label' => 'Devis',
+ 'help' => ''],
+ FACT => [
+ 'id' => FACT,
+ '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()
{
@@ -51,11 +69,10 @@ class Facture
throw new UserException("La valeur de $k est vide");
}
-
switch($k)
{
case 'type_facture':
- if (!array_key_exists($datas[$k], $this->type)) {
+ if (!array_key_exists($datas[$k], $this->types)) {
throw new UserException("$k est de type non-attendue ($data).");
}
if ($datas[$k] < 2) {
@@ -87,24 +104,19 @@ class Facture
}
break;
case 'date_emission':
- if (!strtotime($datas[$k])) {
- throw new UserException("La date d'émission est non-attendue ($data).");
- }
+ $datas[$k] = \DateTime::createFromFormat('!d/m/Y', $data)->format('Y-m-d');
break;
case 'date_echeance':
- if (!strtotime($datas[$k])) {
- throw new UserException("La date d'émission est non-attendue ($data).");
- }
- if (isset($datas['date_emission']) && (strtotime($datas[$k]) < strtotime($datas['date_emission']))) {
+ $datas[$k] = \DateTime::createFromFormat('!d/m/Y', $data)->format('Y-m-d');
+ if (DateTime::createFromFormat('!Y-m-d', $datas[$k])->format('U') < DateTime::createFromFormat('!Y-m-d', $datas['date_emission'])->format('U'))
+ {
throw new UserException("La date d'échéance est antérieure à la date d'émission ($data).");
}
break;
case 'moyen_paiement':
- $cats = new \Garradin\Compta\Categories;
- if (!array_key_exists($datas[$k], $cats->listMoyensPaiement())) {
+ if (!array_key_exists($datas[$k], $this->listMoyensPaiement())) {
throw new UserException("Le moyen de paiement ne correspond pas à la liste interne ($data).");
}
- unset($cats);
break;
case 'contenu':
if ($fac)
@@ -176,9 +188,7 @@ class Facture
{
$db = DB::getInstance();
- $r = $db->first('SELECT *, strftime(\'%s\', date_emission) AS date_emission,
- strftime(\'%s\', date_echeance) AS date_echeance
- FROM plugin_facturation_factures WHERE id = ? LIMIT 1;', (int)$id);
+ $r = $db->first('SELECT * FROM plugin_facturation_factures WHERE id = ? LIMIT 1;', (int)$id);
if(!$r)
{
@@ -190,6 +200,12 @@ class Facture
$r->contenu = json_decode($r->contenu, true);
}
+ $r->date_emission = \DateTime::createFromFormat('!Y-m-d', $r->date_emission);
+ if ($r->date_echeance)
+ {
+ $r->date_echeance= \DateTime::createFromFormat('!Y-m-d', $r->date_echeance);
+ }
+
return $r;
}
@@ -276,26 +292,47 @@ class Facture
// ** Pour type reçu **
- public $recu_fields = ['id', 'intitule', 'montant', 'date', 'expiration'];
+ public $recu_fields = ['id', 'label', 'amount', 'date', 'expiry', 'paid', 'paid_amount'];
- public function getCotis($membre_id = 1)
+ public function getCotis(int $user_id, int $su_id = null)
{
- // C un peu overkill nn?
- // Copié/modifié de Membres\Cotisations::listSubscriptionsForMember($id)
- $db = DB::getInstance();
- return $db->get('SELECT cm.id, c.intitule, strftime(\'%s\', c.debut) AS debut, strftime(\'%s\', c.fin) AS fin, c.montant, strftime(\'%s\', cm.date) AS date,
- CASE WHEN c.duree IS NOT NULL THEN date(cm.date, \'+\'||c.duree||\' days\') >= date()
- WHEN c.fin IS NOT NULL THEN (cm.id IS NOT NULL AND cm.date <= c.fin AND cm.date >= c.debut)
- WHEN cm.id IS NOT NULL THEN 1 ELSE 0 END AS a_jour,
- strftime(\'%s\', CASE WHEN c.duree IS NOT NULL THEN date(cm.date, \'+\'||c.duree||\' days\')
- WHEN c.fin IS NOT NULL THEN c.fin ELSE 1 END ) AS expiration,
- (julianday(date()) - julianday(CASE WHEN c.duree IS NOT NULL THEN date(cm.date, \'+\'||c.duree||\' days\')
- WHEN c.fin IS NOT NULL THEN c.fin END)) AS nb_jours
- FROM cotisations_membres AS cm
- INNER JOIN cotisations AS c ON c.id = cm.id_cotisation
- WHERE cm.id_membre = ?
- AND ((c.fin IS NOT NULL AND cm.date <= c.fin AND cm.date >= c.debut) OR c.fin IS NULL)
- GROUP BY cm.id_cotisation
- ORDER BY cm.date DESC;', (int)$membre_id);
+ $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();
+
+ $query = 'SELECT code, nom FROM plugin_facturation_paiement ORDER BY nom COLLATE NOCASE;';
+
+ if ($assoc) {
+ return $db->getAssoc($query);
+ }
+ else {
+ return $db->getGrouped($query);
+ }
+ }
+
+ public function getMoyenPaiement($code)
+ {
+ $db = DB::getInstance();
+ return $db->firstColumn('SELECT nom FROM plugin_facturation_paiement WHERE code = ?;', $code);
+ }
+
}
diff --git a/templates/_js.tpl b/templates/_js.tpl
index fa2d0a1..6c2da5c 100644
--- a/templates/_js.tpl
+++ b/templates/_js.tpl
@@ -15,12 +15,26 @@
function plus(){
var newdiv = document.createElement('tr');
newdiv.innerHTML = document.getElementById('Line1').innerHTML;
+ newdiv.querySelector('.fact_rm_line button').onclick = function(){
+ this.parentNode.parentNode.parentNode.removeChild(this.parentNode.parentNode);
+ updateSum();
+ };
document.getElementById('Lines').appendChild(newdiv);
}
plus();
+ updateSum();
$('#ajouter_ligne').onclick = plus;
+ 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();
+ };
+ }
+
function changeTypeSaisie(type)
{
g.toggle(['.type_client', '.type_membre'], false);
@@ -39,5 +53,40 @@
}
} ());
+
+
+ // Hide type specific parts of the form
+ function hideAllTypes() {
+ g.toggle('[data-types]', false);
+ }
+
+ // Toggle parts of the form when a type is selected
+ function selectType(v) {
+ hideAllTypes();
+ g.toggle('[data-types~=t' + v + ']', true);
+ g.toggle('[data-types=all-but-advanced]', v != 0);
+ // Disable required form elements, or the form won't be able to be submitted
+ $('[data-types=all-but-advanced] input[required]').forEach((e) => {
+ e.disabled = v == 'advanced' ? true : false;
+ });
+
+ }
+
+ var radios = $('fieldset input[type=radio][name=type]');
+
+ radios.forEach((e) => {
+ e.onchange = () => {
+ document.querySelectorAll('fieldset').forEach((e, k) => {
+ if (k == 0 || e.dataset.types) return;
+ g.toggle(e, true);
+ g.toggle('p.submit', true);
+ });
+ console.log(e.value);
+ selectType(e.value);
+ };
+ });
+
+ hideAllTypes();
{/literal}
+ selectType({$radio.type});
\ No newline at end of file
diff --git a/templates/_list_actions.tpl b/templates/_list_actions.tpl
index 8a16600..c99c888 100644
--- a/templates/_list_actions.tpl
+++ b/templates/_list_actions.tpl
@@ -1,13 +1,13 @@
- {if $session->canAccess('membres', Membres::DROIT_ADMIN)} {/if}
-
- Pour les membres cochés :
+
+
+
+ PAS FONCTIONNEL - Pour les client·es coché·es :
{csrf_field key="membres_action"}
— Choisir une action à effectuer —
Exporter en tableau CSV
- Exporter en classeur Office
Supprimer
diff --git a/templates/_menu.tpl b/templates/_menu.tpl
index f947524..82016d2 100644
--- a/templates/_menu.tpl
+++ b/templates/_menu.tpl
@@ -1,4 +1,8 @@
-
+
+
+
+
\ No newline at end of file
diff --git a/templates/_menu_client.tpl b/templates/_menu_client.tpl
index e7ee19e..c993bbb 100644
--- a/templates/_menu_client.tpl
+++ b/templates/_menu_client.tpl
@@ -1,4 +1,5 @@
-
+
+
+
\ No newline at end of file
diff --git a/templates/_style.css b/templates/_style.css
new file mode 100644
index 0000000..89a586e
--- /dev/null
+++ b/templates/_style.css
@@ -0,0 +1,10 @@
+{literal}
+.tabs {
+ text-align: right;
+}
+
+#Line1 > .fact_rm_line {
+ display: none;
+}
+
+{/literal}
\ No newline at end of file
diff --git a/templates/aide.tpl b/templates/aide.tpl
index b92d517..b86b428 100644
--- a/templates/aide.tpl
+++ b/templates/aide.tpl
@@ -8,25 +8,6 @@
Pour l'instant, il y a des choses encore brouillonnes. Notamment, dans les factures et devis, c'est l'adresse postale renseignée dans la configuration de Garradin qui fait foi plutôt que celle dans le plugin (qui sert en revanche pour les reçus).
Pensez à mettre une image en signature aussi, il me semble que les reçus fiscales peuvent méfonctionner sans ça :o (j'ai copié cette partie d'un ancien plugin, alors je connais pas bien).
- Il y a un problème entre les bibliothèques pour importer le cerfa (reçu fiscal) et l'autoloader de Garradin. Il faut pour cela, en attendant la nouvelle version, faire une petite modif dans le fichier include/init.php, au niveau de la ligne 111:
- {literal}
-
- if (!file_exists($path))
- {
- return false;
- }
-
- à la place de la ligne :
-
-
- if (!file_exists($path))
- {
- throw new \Exception('File '.$path.' doesn\'t exists');
- };
- {/literal}
-
- Ne vous en faites pas, ça va pas tout casser, et c'est réglé dans la version 1.0 de Garradin, et ça sert seulement pour éditer des reçus fiscaux.
-
- Pour créer un reçu sur une cotisation, il faut pour le moment que cette cotisation soit attachée à la compta.
- Pour créer un reçu fiscal, l'interface est pour l'instant la même que pour créer une facture/devis. Les champs correspondent mais les noms/labels autour ne sont pas adaptés. Vous pouvez de toutes façons tester, et si le résultat est pas celui attendu, remodifiez derrière :)
- La partie « Droit à la réduction d'impôt » peut faire peur, elle correspond simplement à des cases du cerfa pour les reçus fiscaux. Je n'y connais pas grand chose pour le moment, je ne peux vous éclairer davantage, il va falloir se retourner vers légifrance :(
diff --git a/templates/client.tpl b/templates/client.tpl
index 3f15feb..add06e2 100644
--- a/templates/client.tpl
+++ b/templates/client.tpl
@@ -59,7 +59,7 @@
{foreach from=$docs item=facture}
- {if $facture.type_facture == 1}Facture{else}Devis{/if}
+ {$f_obj->types[$facture.type_facture]['label'] }
{$facture.numero}
{$facture.date_emission|date_fr:'d/m/Y'}
{$facture.date_echeance|date_fr:'d/m/Y'}
diff --git a/templates/clients.tpl b/templates/clients.tpl
index 19e3743..801e551 100644
--- a/templates/clients.tpl
+++ b/templates/clients.tpl
@@ -20,7 +20,10 @@
{foreach from=$clients item="membre"}
- {if $session->canAccess('membres', Membres::DROIT_ADMIN)} {/if}
+ {if $session->canAccess('membres', Membres::DROIT_ADMIN)}
+ {input type="checkbox" name="selected" value=$membre.id default=0}
+
+ {/if}
{foreach from=$champs key="c" item="cfg"}
{if $c == 'nom'}{/if}
@@ -28,7 +31,7 @@
{if $c == 'nom'} {/if}
{/foreach}
-
+
👤
{if $session->canAccess('membres', Membres::DROIT_ECRITURE)}✎ {/if}
@@ -36,7 +39,7 @@
{/foreach}
{if $session->canAccess('membres', Membres::DROIT_ADMIN)}
- {include file="%s/templates/_list_actions.tpl"|args:$plugin_root colspan=count((array)$champs)+1}
+ {include file="%s/templates/_list_actions.tpl"|args:$plugin_root colspan=count((array)$champs)}
{/if}
{else}
diff --git a/templates/config.tpl b/templates/config.tpl
index 6766d4f..7aa4b70 100644
--- a/templates/config.tpl
+++ b/templates/config.tpl
@@ -2,7 +2,7 @@
{include file="%s/templates/_menu.tpl"|args:$plugin_root current="config"}
{if $ok && !$form->hasErrors()}
-
+
La configuration a bien été enregistrée.
{/if}
@@ -13,38 +13,26 @@
Informations de l'association
- RNA de l'assocation
-
-
- SIRET de l'assocation
-
+ {input type="text" name="rna_asso" label="RNA de l'association" source=$plugin.config}
+ {input type="text" name="siret_asso" label="SIRET de l'association" source=$plugin.config}
Adresse
-
- Numéro de rue obligatoire
-
-
- Rue obligatoire
-
-
- Code postal obligatoire
-
-
- Ville obligatoire
-
-
+ {input type="text" name="numero_rue_asso" source=$plugin.config label="Numéro de rue" required=1 maxlength=5}
+ {input type="text" name="rue_asso" source=$plugin.config label="Nom de rue" required=1}
+ {input type="text" name="cp_asso" source=$plugin.config label="Code postal" required=1}
+ {input type="text" name="ville_asso" source=$plugin.config label="Ville" required=1}
Objet
L'objet (but) de l'association doit tenir sur 3 lignes, chaque ligne pouvant accueillir un maximum de 100 caractères. obligatoire pour reçus fiscaux
-
-
-
+ {input type="text" name="objet_0" source=$plugin.config label="Ligne 1" maxlength=95}
+ {input type="text" name="objet_1" source=$plugin.config label="Ligne 2" maxlength=95}
+ {input type="text" name="objet_2" source=$plugin.config label="Ligne 3" maxlength=95}
@@ -52,9 +40,9 @@
Droit à la réduction d'impôt
Articles concernés par l'association : obligatoire pour reçus fiscaux
- Article 200
- Article 238 bis
- Article 885-0V bis A
+ {input type="checkbox" name="droit_art200" value="1" source=$plugin.config label="Article 200"}
+ {input type="checkbox" name="droit_art238bis" value="1" source=$plugin.config label="Article 238 bis"}
+ {input type="checkbox" name="droit_art885-0VbisA" value="1" source=$plugin.config label="Article 885-0V bis A"}
@@ -72,16 +60,15 @@
Configuration du plugin
- Vérifier le code postal lors de saisie/modification de client (seulement FR)
- Noms des clients uniques
-
+ {input type="checkbox" name="validate_cp" value="1" source=$plugin.config label="Vérifier le code postal lors de saisie/modification de client (seulement FR)"}
+ {input type="checkbox" name="unique_client_name" value="1" source=$plugin.config label="Noms des clients uniques"}
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 !
{csrf_field key="facturation_config"}
-
+ {button type="submit" name="save" label="Enregistrer" shape="right" class="main"}
@@ -102,7 +89,7 @@
{csrf_field key="signature_config"}
-
+ {button type="submit" name="upload" label="Envoyer le fichier" shape="right" class="main"}
diff --git a/templates/cotis_ajouter.tpl b/templates/cotis_ajouter.tpl
deleted file mode 100644
index c3c6d83..0000000
--- a/templates/cotis_ajouter.tpl
+++ /dev/null
@@ -1,109 +0,0 @@
-{include file="admin/_head.tpl" title="Créer un reçu — %s"|args:$plugin.nom current="plugin_%s"|args:$plugin.id js=1}
-{include file="%s/templates/_menu.tpl"|args:$plugin_root current="facture"}
-
-
-
-{form_errors}
-
-
-{/if}
-
-{include file="%s/templates/_js.tpl"|args:$plugin_root}
-{include file="admin/_foot.tpl"}
diff --git a/templates/cotis_modifier.tpl b/templates/cotis_modifier.tpl
deleted file mode 100644
index 0a8dd7a..0000000
--- a/templates/cotis_modifier.tpl
+++ /dev/null
@@ -1,109 +0,0 @@
-{include file="admin/_head.tpl" title="Modifier un reçu — %s"|args:$plugin.nom current="plugin_%s"|args:$plugin.id js=1}
-{include file="%s/templates/_menu.tpl"|args:$plugin_root current="index"}
-
-
-
-{form_errors}
-
-
-{* {/if} *}
-
-{include file="%s/templates/_js.tpl"|args:$plugin_root}
-{include file="admin/_foot.tpl"}
diff --git a/templates/facture.tpl b/templates/facture.tpl
index 77d167a..ba7c69b 100644
--- a/templates/facture.tpl
+++ b/templates/facture.tpl
@@ -4,11 +4,7 @@
{form_errors}
{if $session->canAccess('compta', Membres::DROIT_ECRITURE)}
- {if $type == 3}
-
- {else}
-
- {/if}
+
Modifier ce document
{/if}
diff --git a/templates/facture_ajouter.tpl b/templates/facture_ajouter.tpl
index f23ea96..9b014e9 100644
--- a/templates/facture_ajouter.tpl
+++ b/templates/facture_ajouter.tpl
@@ -1,75 +1,84 @@
{include file="admin/_head.tpl" title="Créer un document — %s"|args:$plugin.nom current="plugin_%s"|args:$plugin.id js=1}
{include file="%s/templates/_menu.tpl"|args:$plugin_root current="facture"}
-
-
{form_errors}
- Ajouter une ligne
- {include file="%s/templates/_js.tpl"|args:$plugin_root}
-
-
+
{csrf_field key="ajout_facture"}
-
+ {button type="submit" name="add" label="Enregistrer" shape="right" class="main"}
+
+
+ Membre
+
+ Reçu adressée à :
+
+ {input type="select" name="membre" label="Membre" options=$membres required=1}
+
+
+
+
+
+ {csrf_field key="add_cotis_1"}
+ {button type="submit" name="select_cotis" label="Sélectionner" shape="right" class="main"}
+
+
+
+{if $step}
+
+ Cotisation
+ {if count($liste)}
+
+ Sélectionnez la cotisation concernée :
+
+
+
+
+ Id
+ Intitulé
+ Date d'inscription
+ Expiration d'expiration
+ Tarif
+ Montant
+ Somme payée
+
+
+ {foreach from=$liste item=cotis key=i}
+ {if !$cotis.paid}
+ {continue}
+ {/if}
+
+
+ {input type="radio" name="cotisation" value="%s"|args:$i}
+
+ {foreach from=$cotis item=element key=key}
+ {if $key == 'paid'}
+ {continue}
+ {/if}
+
+
+ {if ($key == 'date' || $key == 'expiry') && $element > 0}
+ {$element|date_short}
+ {elseif $key == 'amount' OR $key == 'paid_amount'}
+ {$element|raw|money_currency}
+ {else}
+ {$element}
+ {/if}
+
+
+
+
+ {/foreach}
+
+ {/foreach}
+
+
+
+
+
+
+ {csrf_field key="add_cotis_2"}
+ {button type="submit" name="add_cotis" label="Enregistrer" shape="right" class="main"}
+
+ {else}
+ Ce membre n'a aucune cotisation payée.
+
+ {/if}
+{/if}
+
+{include file="%s/templates/_js.tpl"|args:$plugin_root}
+
{include file="admin/_foot.tpl"}
diff --git a/templates/facture_modifier.tpl b/templates/facture_modifier.tpl
index 314ede5..7f6baeb 100644
--- a/templates/facture_modifier.tpl
+++ b/templates/facture_modifier.tpl
@@ -3,86 +3,86 @@
{form_errors}
-
-
-{form_errors}
-
-
- Créer une facture
+ Type d'écriture
-
- Numéro facture obligatoire et unique
-
- Chaque facture 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.
-
-
- Date d'émission obligatoire
-
-
- Date d'échéance obligatoire
-
-
- Réglée
-
-
- Archivée
-
-
+ {foreach from=$types_details item="type"}
+
+ {input type="radio" name="type" value=$type.id source=$radio label=null}
+
+
+
{$type.label}
+ {if !empty($type.help)}
+
{$type.help}
+ {/if}
+
+
+
+ {/foreach}
+ Créer un devis
+ Créer une facture
+ Créer un reçu fiscal
+ Créer un reçu de cotisation
+
+
+ {input type="text" name="numero_facture" maxlength=12 label="Numéro du document" required=1 source=$doc help="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."}
+
+ {input type="date" name="date_emission" default=$date label="Date d'émission" required=1 source=$doc}
+
+ Date du versemen du don
+
+
+ {input type="date" name="date_echeance" default=$date label="Date d'échéance" required=1 source=$doc}
+
+ Date d'établissement du document
+
+
+
+ Statut
+
+ {input type="checkbox" name="reglee" value="1" label="Réglée" source=$doc data-types="t1"}
+
+ {input type="checkbox" name="archivee" value="1" label="Archivée" source=$doc disabled="disabled"}
+
+
+
+
+
+
Client
- Facture adressée à un·e :
+ Document adressée à :
+ {if !empty($clients)}
- Membre
- Client·e
+ {input type="radio" name="base_receveur" value="membre" source=$doc label="Un·e membre"}
+ {input type="radio" name="base_receveur" value="client" source=$doc label="Un·e client·e"}
- Client obligatoire
-
-
- {foreach from=$membres item="membre"}
- {$membre->$identite}
- {/foreach}
-
-
- {foreach from=$clients item="client"}
- {$client.nom}
- {/foreach}
-
-
+ {/if}
+
+ {input type="select" name="membre" label="Membre" options=$membres required=1 source=$doc}
+
+
+ {if !empty($clients)}
+
+ {input type="select" name="client" label="Client" options=$clients required=1 source=$doc class="type_client"}
+
+ {/if}
-
+
Contenu
- Moyen de paiement obligatoire
-
-
- {foreach from=$doc.moyens_paiement item="moyen"}
- {$moyen.nom}
- {/foreach}
-
-
+ {input type="select" name="moyen_paiement" required=1 label="Moyen de paiement" source=$doc options=$doc.moyens_paiement}
Contenu du document
@@ -104,7 +104,7 @@
€
- Supprimer
+ {button label="Enlever" title="Enlever la ligne" shape="minus" min="2" name="remove_line"}
{foreach from=$designations item=designation key=key}
@@ -112,7 +112,7 @@
{$designation}
€
- Supprimer
+ {button label="Enlever" title="Enlever la ligne" shape="minus" min="2" name="remove_line"}
{/foreach}
@@ -122,7 +122,7 @@
€
- Supprimer
+ {button label="Enlever" title="Enlever la ligne" shape="minus" min="2" name="remove_line"}
{/if}
@@ -130,22 +130,99 @@
Total :
0.00 €
-
+ {button label="Ajouter" title="Ajouter une ligne" id="ajouter_ligne" shape="plus"}
- Ajouter une ligne
- {include file="%s/templates/_js.tpl"|args:$plugin_root}
-
-
+
{csrf_field key="modifier_facture"}
-
+ {button type="submit" name="save" label="Enregistrer" shape="right" class="main"}
+
+
+ Membre
+
+ Reçu adressée à :
+
+ {input type="select" name="membre" label="Membre" options=$membres required=1 source=$doc}
+
+
+
+
+
+ {csrf_field key="add_cotis_1"}
+ {button type="submit" name="select_cotis" label="Sélectionner" shape="right" class="main"}
+
+
+
+{if $step}
+
+ Cotisation
+ {if count($liste)}
+
+ Sélectionnez la cotisation concernée :
+
+
+
+
+ Id
+ Intitulé
+ Date d'inscription
+ Expiration d'expiration
+ Tarif
+ Montant
+ Somme payée
+
+
+ {foreach from=$liste item=cotis key=i}
+ {if !$cotis.paid}
+ {continue}
+ {/if}
+
+
+ {input type="radio" name="cotisation" value="%s"|args:$i}
+
+ {foreach from=$cotis item=element key=key}
+ {if $key == 'paid'}
+ {continue}
+ {/if}
+
+
+ {if ($key == 'date' || $key == 'expiry') && $element > 0}
+ {$element|date_short}
+ {elseif $key == 'amount' OR $key == 'paid_amount'}
+ {$element|raw|money_currency}
+ {else}
+ {$element}
+ {/if}
+
+
+
+
+ {/foreach}
+
+ {/foreach}
+
+
+
+
+
+
+ {csrf_field key="add_cotis_2"}
+ {button type="submit" name="add_cotis" label="Enregistrer" shape="right" class="main"}
+
+ {else}
+ Ce membre n'a aucune cotisation payée.
+
+ {/if}
+{/if}
+
+{include file="%s/templates/_js.tpl"|args:$plugin_root}
-{include file="admin/_foot.tpl"}
\ No newline at end of file
+{include file="admin/_foot.tpl"}
diff --git a/upgrade.php b/upgrade.php
index 5c69f93..e7d902b 100644
--- a/upgrade.php
+++ b/upgrade.php
@@ -30,4 +30,49 @@ if (version_compare($infos->version, '0.3.0', '<'))
}
}
$db->exec('DROP TABLE `plugin_facturation_config`;');
+}
+
+// 0.3.0 - Migration Facturation\Config vers la table plugins
+if (version_compare($infos->version, '0.4.0', '<'))
+{
+ $db->exec(<<get('champ_identite');
\ No newline at end of file
+$tpl->assign('f_obj', $facture);
+
+$identite = (string) Config::getInstance()->get('champ_identite');
diff --git a/www/admin/_upgrade_trick.php b/www/admin/_upgrade_trick.php
new file mode 100644
index 0000000..c6aac1b
--- /dev/null
+++ b/www/admin/_upgrade_trick.php
@@ -0,0 +1,13 @@
+needUpgrade())
+{
+ $plugin->upgrade();
+}
+
+unset($plugin);
\ No newline at end of file
diff --git a/www/admin/config.php b/www/admin/config.php
index 0985a58..128dde8 100644
--- a/www/admin/config.php
+++ b/www/admin/config.php
@@ -12,10 +12,10 @@ if (f('save') && $form->check('facturation_config'))
$plugin->setConfig('rna_asso', trim(f('rna_asso')));
$plugin->setConfig('siret_asso', trim(f('siret_asso')));
- $plugin->setConfig('numero_rue_asso', trim(f('numero_rue')));
- $plugin->setConfig('rue_asso', trim(f('rue')));
- $plugin->setConfig('cp_asso', trim(f('codepostal')));
- $plugin->setConfig('ville_asso', trim(f('ville')));
+ $plugin->setConfig('numero_rue_asso', trim(f('numero_rue_asso')));
+ $plugin->setConfig('rue_asso', trim(f('rue_asso')));
+ $plugin->setConfig('cp_asso', trim(f('cp_asso')));
+ $plugin->setConfig('ville_asso', trim(f('ville_asso')));
$plugin->setConfig('droit_art200', (bool)f('droit_art200'));
$plugin->setConfig('droit_art238bis', (bool)f('droit_art238bis'));
@@ -27,7 +27,7 @@ if (f('save') && $form->check('facturation_config'))
$plugin->setConfig('footer', f('footer'));
$plugin->setConfig('validate_cp', (bool)f('validate_cp'));
- $plugin->setConfig('unique_client_name', (bool)f('unique_name'));
+ $plugin->setConfig('unique_client_name', (bool)f('unique_client_name'));
Utils::redirect(PLUGIN_URL . 'config.php?ok');
}
diff --git a/www/admin/cotis_ajouter.php b/www/admin/cotis_ajouter.php
deleted file mode 100644
index a70ba50..0000000
--- a/www/admin/cotis_ajouter.php
+++ /dev/null
@@ -1,122 +0,0 @@
-requireAccess('compta', Membres::DROIT_ECRITURE);
-
-use Garradin\DB;
-
-$db = DB::getInstance();
-
-
-$step = $radio = false;
-$liste = [];
-
-$fields = $facture->recu_fields;
-
-if (f('select'))
-{
- $form->check('add_cotis_1',[
- 'numero_facture' => 'required|string',
- 'date_emission' => 'required|date',
- 'membre' => 'required|numeric',
- ]);
-
- $step = true;
-}
-elseif (f('add'))
-{
- $form->check('add_cotis_2',[
- 'numero_facture' => 'required|string',
- 'date_emission' => 'required|date',
- 'membre' => 'required|numeric',
- 'cotisation' => 'required',
- ]);
-
- $radio = f('cotisation');
-
- if (!$form->hasErrors())
- {
- try
- {
- $num = (int) str_replace('cotis_', '', $radio);
- foreach($fields as $field)
- {
- $cotis[$field] = f($field.'_'.$num);
- }
-
- $cotis['date'] = date('Y-m-d', $cotis['date']);
- $cotis['expiration'] = date('Y-m-d', $cotis['expiration']);
-
- $r = $db->get('SELECT moyen_paiement, montant FROM membres_operations AS mo INNER JOIN compta_journal AS cj ON cj.id = mo.id_operation
- WHERE mo.id_cotisation = ?;', (int)$cotis['id']);
- $r = $r[0];
-
- $data = [
- 'type_facture' => 3,
- 'numero' => f('numero_facture'),
- 'receveur_membre' => 1,
- 'receveur_id' => f('membre'),
- 'date_emission' => f('date_emission'),
- 'moyen_paiement' => $r->moyen_paiement,
- 'total' => $r->montant,
- 'contenu' => ['id' => $cotis['id'],
- 'intitule' => $cotis['intitule'],
- 'souscription' => $cotis['date'],
- 'expiration' => $cotis['expiration'] ]
- ];
-
- $id = $facture->add($data);
-
- Utils::redirect(PLUGIN_URL . 'facture.php?id='.(int)$id);
- }
- catch (UserException $e)
- {
- $form->addError($e->getMessage());
- }
- }
-
- $step = true;
-}
-
-
-if ($step)
-{
- try
- {
- $r = $facture->getCotis((int)f('membre'));
- // Passe les expiration nulles (cotis ponctuelle) à 0 pour avoir moins d'embrouilles
- foreach ($r as $i=>$cotis)
- {
- foreach($cotis as $k=>$v)
- {
- if (in_array($k, $fields))
- {
- $liste[$i][$k] = $v;
- }
- }
- if($liste[$i]['expiration'] < 0)
- {
- $liste[$i]['expiration'] = 0;
- }
- }
-
- }
- catch (UserException $e)
- {
- $form->addError($e->getMessage());
- }
-}
-
-
-$tpl->assign('liste', $liste);
-$tpl->assign('radio', $radio);
-
-$tpl->assign('step', $step);
-$tpl->assign('identite', $identite);
-$tpl->assign('membre_id', f('membre') ?: -1);
-$tpl->assign('membres', (array)DB::getInstance()->get('SELECT id, '.$identite.' FROM membres WHERE id_categorie != -2 NOT IN (SELECT id FROM membres_categories WHERE cacher = 1);'));
-
-$tpl->display(PLUGIN_ROOT . '/templates/cotis_ajouter.tpl');
\ No newline at end of file
diff --git a/www/admin/cotis_modifier.php b/www/admin/cotis_modifier.php
deleted file mode 100644
index 4ce990f..0000000
--- a/www/admin/cotis_modifier.php
+++ /dev/null
@@ -1,141 +0,0 @@
-requireAccess('compta', Membres::DROIT_ECRITURE);
-
-use Garradin\DB;
-
-$db = DB::getInstance();
-
-
-qv(['id' => 'required|numeric']);
-$id = (int) qg('id');
-
-if (!$f = $facture->get($id))
-{
- throw new UserException("Ce document n'existe pas.");
-}
-
-$fields = $facture->recu_fields;
-
-$membre_id = f('membre') ?: $f->receveur_id;
-
-$values['numero_facture'] = $f->numero;
-$values['date_emission'] = date('Y-m-d', $f->date_emission);
-
-$radio = '';
-$liste = [];
-
-
-if (f('select'))
-{
- $form->check('add_cotis_1',[
- 'numero_facture' => 'required|string',
- 'date_emission' => 'required|date',
- 'membre' => 'required|numeric',
- ]);
-
-}
-elseif (f('add'))
-{
- $form->check('add_cotis_2',[
- 'numero_facture' => 'required|string',
- 'date_emission' => 'required|date',
- 'membre' => 'required|numeric',
- 'cotisation' => 'required',
- ]);
-
- $radio = f('cotisation');
-
- if (!$form->hasErrors())
- {
- try
- {
- $num = (int) str_replace('cotis_', '', $radio);
- foreach($fields as $field)
- {
- $cotis[$field] = f($field.'_'.$num);
- }
-
- $cotis['date'] = date('Y-m-d', $cotis['date']);
- $cotis['expiration'] = date('Y-m-d', $cotis['expiration']);
-
- $r = $db->get('SELECT moyen_paiement, montant FROM membres_operations AS mo INNER JOIN compta_journal AS cj ON cj.id = mo.id_operation
- WHERE mo.id_cotisation = ?;', (int)$cotis['id']);
- $r = $r[0];
-
- $data = [
- 'type_facture' => 3,
- 'numero' => f('numero_facture'),
- 'receveur_membre' => 1,
- 'receveur_id' => f('membre'),
- 'date_emission' => f('date_emission'),
- 'moyen_paiement' => $r->moyen_paiement,
- 'total' => $r->montant,
- 'contenu' => ['id' => $cotis['id'],
- 'intitule' => $cotis['intitule'],
- 'souscription' => $cotis['date'],
- 'expiration' => $cotis['expiration'] ]
- ];
-
- if($facture->edit($id, $data))
- {
- Utils::redirect(PLUGIN_URL . 'facture.php?id='.(int)$id);
- }
- throw new UserException('Erreur d\'édition du reçu');
- }
- catch (UserException $e)
- {
- $form->addError($e->getMessage());
- }
- }
-
-}
-
-
-try
-{
- $r = $facture->getCotis((int)$membre_id);
- // Garde seulement les champs requis
- // Rattrape le bouton radio à pré-sélectionner
- // Passe les expiration nulles (cotis ponctuelle) à 0 pour avoir moins d'embrouilles
- foreach ($r as $i=>$cotis)
- {
- foreach($cotis as $k=>$v)
- {
- if (in_array($k, $fields))
- {
- $liste[$i][$k] = $v;
- }
- }
-
- if($liste[$i]['id'] == $f->contenu['id'])
- {
- $radio = 'cotis_'.$i;
- }
-
- if($liste[$i]['expiration'] < 0)
- {
- $liste[$i]['expiration'] = 0;
- }
- }
-}
-catch (UserException $e)
-{
- $form->addError($e->getMessage());
-}
-
-
-$tpl->assign('liste', $liste);
-$tpl->assign('radio', $radio);
-$tpl->assign('values', $values);
-
-// $tpl->assign('step', $step);
-$tpl->assign('identite', $identite);
-$tpl->assign('membre_id', $membre_id);
-$tpl->assign('membres', (array)DB::getInstance()->get('SELECT id, '.$identite.' FROM membres WHERE id_categorie != -2 NOT IN (SELECT id FROM membres_categories WHERE cacher = 1);'));
-
-$tpl->display(PLUGIN_ROOT . '/templates/cotis_modifier.tpl');
diff --git a/www/admin/facture_ajouter.php b/www/admin/facture_ajouter.php
index 825898e..7069e11 100644
--- a/www/admin/facture_ajouter.php
+++ b/www/admin/facture_ajouter.php
@@ -7,24 +7,31 @@ require_once __DIR__ . '/_inc.php';
$session->requireAccess('compta', Membres::DROIT_ECRITURE);
use Garradin\DB;
+use stdClass;
-$cats = new Compta\Categories;
-$tpl->assign('moyens_paiement', $cats->listMoyensPaiement());
+$db = DB::getInstance();
+
+$step = $radio = false;
+$liste = [];
+
+$fields = $facture->recu_fields;
+
+$tpl->assign('moyens_paiement', $facture->listMoyensPaiement());
$tpl->assign('moyen_paiement', f('moyen_paiement') ?: 'ES');
if (f('add'))
{
$form->check('ajout_facture', [
- 'type' => 'required|in:facture,devis,cerfa,cotis',
+ 'type' => 'required|in:'.implode(',', [DEVIS, FACT, CERFA]),
'numero_facture' => 'required|string',
- 'date_emission' => 'required|date',
- 'date_echeance' => 'required|date',
+ 'date_emission' => 'required|date_format:d/m/Y',
+ 'date_echeance' => 'required|date_format:d/m/Y',
// 'reglee' => '',
// 'archivee' => '',
'base_receveur' => 'required|in:membre,client',
// 'client' => '',
// 'membre' => '',
- 'moyen_paiement' => 'required|in:' . implode(',', array_keys($cats->listMoyensPaiement())),
+ 'moyen_paiement' => 'required|in:' . implode(',', array_keys($facture->listMoyensPaiement())),
'designation' => 'array|required',
'prix' => 'array|required'
]);
@@ -36,33 +43,29 @@ if (f('add'))
if ( count(f('designation')) !== count(f('prix')) )
{
throw new UserException('Nombre de désignations et de prix reçus différent.');
- }
-
- $truc = [
+ }
+
+ $truc = [
'numero' =>f('numero_facture'),
'date_emission' => f('date_emission'),
'date_echeance' => f('date_echeance'),
- 'reglee' => f('reglee') == 'on'?1:0,
- 'archivee' => f('archivee') == 'on'?1:0,
+ 'reglee' => f('reglee') == 1?1:0,
+ 'archivee' => f('archivee') == 1?1:0,
'moyen_paiement' => f('moyen_paiement'),
'toto' => 0
];
- if (f('type') == 'devis')
+ if (f('type') == DEVIS)
{
- $truc['type_facture'] = 0;
+ $truc['type_facture'] = DEVIS;
}
- elseif (f('type') == 'facture')
+ elseif (f('type') == FACT)
{
- $truc['type_facture'] = 1;
+ $truc['type_facture'] = FACT;
}
- elseif (f('type') == 'cerfa')
+ elseif (f('type') == CERFA)
{
- $truc['type_facture'] = 2;
- }
- elseif (f('type') == 'cotis')
- {
- $truc['type_facture'] = 3;
+ $truc['type_facture'] = CERFA;
}
foreach(f('designation') as $k=>$value)
@@ -97,26 +100,97 @@ if (f('add'))
}
}
-
-$type = qg('t');
-$radio = [];
-if (is_numeric($type))
+elseif (f('select_cotis'))
{
- switch($type)
+ $form->check('add_cotis_1',[
+ 'numero_facture' => 'required|string',
+ 'date_emission' => 'required|date_format:d/m/Y',
+ 'membre' => 'required|numeric',
+ ]);
+
+ $step = true;
+}
+elseif (f('add_cotis'))
+{
+ $form->check('add_cotis_2',[
+ 'numero_facture' => 'required|string',
+ 'date_emission' => 'required|date_format:d/m/Y',
+ 'membre' => 'required|numeric',
+ 'cotisation' => 'required',
+ ]);
+
+ $radio['type'] = f('cotisation');
+
+ if (!$form->hasErrors())
{
- case 0:
- $radio['type'] = 'devis';
- break;
- case 2:
- $radio['type'] = 'cerfa';
- break;
- case 1:
- default:
- $radio['type'] = 'facture';
- break;
+ try
+ {
+ $num = (int) str_replace('cotis_', '', $radio['type']);
+ foreach($fields as $field)
+ {
+ $cotis[$field] = f($field.'_'.$num);
+ }
+
+ $r = $facture->getCotis(f('membre'), $cotis['id']);
+ $r = $r[0];
+
+ $data = [
+ 'type_facture' => COTIS,
+ 'numero' => f('numero_facture'),
+ 'receveur_membre' => 1,
+ 'receveur_id' => f('membre'),
+ 'date_emission' => f('date_emission'),
+ 'moyen_paiement' => f('moyen_paiement'),
+ 'total' => $r->paid_amount ?? $r->amount,
+ 'contenu' => ['id' => $cotis['id'],
+ 'intitule' => $cotis['label'],
+ 'souscription' => $cotis['date'],
+ 'expiration' => $cotis['expiry'] ]
+ ];
+
+ $id = $facture->add($data);
+
+ Utils::redirect(PLUGIN_URL . 'facture.php?id='.(int)$id);
+ }
+ catch (UserException $e)
+ {
+ $form->addError($e->getMessage());
+ }
+ }
+
+ $step = true;
+}
+
+if ($step)
+{
+ try
+ {
+ $liste = $facture->getCotis((int)f('membre'));
+ }
+ catch (UserException $e)
+ {
+ $form->addError($e->getMessage());
}
}
-$tpl->assign('radio', $radio);
+
+
+$type = qg('t') ? (int) qg('t') : null;
+
+if (in_array($type, [DEVIS, FACT, CERFA, COTIS], true))
+{
+ $radio['type'] = $type;
+}
+elseif (null !== f('type'))
+{
+ $radio['type'] = f('type');
+}
+else
+{
+ $radio['type'] = FACT;
+}
+
+
+$tpl->assign('types_details', $facture->types);
$tpl->assign('client_id', f('client') ?: -1);
$tpl->assign('membre_id', f('membre') ?: -1);
@@ -139,10 +213,17 @@ else {
$designations = ['Exemple'];
$prix = [1.5];
}
+
+$tpl->assign(compact('liste', 'radio', 'step'));
+
+$date = new \DateTime;
+$date->setTimestamp(time());
+$tpl->assign('date', $date->format('d/m/Y'));
+
$tpl->assign('designations', $designations);
$tpl->assign('prix', $prix);
$tpl->assign('identite', $identite);
-$tpl->assign('membres', (array)DB::getInstance()->get('SELECT id, '.$identite.' FROM membres WHERE id_categorie != -2 NOT IN (SELECT id FROM membres_categories WHERE cacher = 1);'));
-$tpl->assign('clients', $client->listAll());
+$tpl->assign('membres', $db->getAssoc('SELECT id, '.$identite.' FROM membres WHERE id_categorie != -2 NOT IN (SELECT id FROM membres_categories WHERE cacher = 1);'));
+$tpl->assign('clients', $db->getAssoc('SELECT id, nom FROM plugin_facturation_clients;'));
$tpl->display(PLUGIN_ROOT . '/templates/facture_ajouter.tpl');
diff --git a/www/admin/facture_modifier.php b/www/admin/facture_modifier.php
index d14b8a4..df7ba2a 100644
--- a/www/admin/facture_modifier.php
+++ b/www/admin/facture_modifier.php
@@ -8,6 +8,16 @@ $session->requireAccess('compta', Membres::DROIT_ECRITURE);
use Garradin\DB;
+$db = DB::getInstance();
+
+$step = false;
+$liste = [];
+
+$fields = $facture->recu_fields;
+
+$tpl->assign('moyens_paiement', $facture->listMoyensPaiement());
+$tpl->assign('moyen_paiement', f('moyen_paiement') ?: 'ES');
+
qv(['id' => 'required|numeric']);
$id = (int) qg('id');
@@ -16,23 +26,21 @@ if (!$f = $facture->get($id))
throw new UserException("Ce document n'existe pas.");
}
-$cats = new Compta\Categories;
-
// Traitement
if(f('save'))
{
$form->check('modifier_facture', [
- 'type' => 'required|in:facture,devis,cerfa,cotis',
+ 'type' => 'required|in:'.implode(',', [DEVIS, FACT, CERFA]),
'numero_facture' => 'required|string',
- 'date_emission' => 'required|date',
- 'date_echeance' => 'required|date',
+ 'date_emission' => 'required|date_format:d/m/Y',
+ 'date_echeance' => 'required|date_format:d/m/Y',
// 'reglee' => '',
// 'archivee' => '',
'base_receveur' => 'required|in:membre,client',
// 'client' => '',
// 'membre' => '',
- 'moyen_paiement' => 'required|in:' . implode(',', array_keys($cats->listMoyensPaiement())),
+ 'moyen_paiement' => 'required|in:' . implode(',', array_keys($facture->listMoyensPaiement())),
'designation' => 'array|required',
'prix' => 'array|required'
]);
@@ -51,27 +59,27 @@ if(f('save'))
'numero' => f('numero_facture'),
'date_emission' => f('date_emission'),
'date_echeance' => f('date_echeance'),
- 'reglee' => f('reglee') == 'on'?1:0,
- 'archivee' => f('archivee') == 'on'?1:0,
+ 'reglee' => f('reglee') == 1?1:0,
+ 'archivee' => f('archivee') == 1?1:0,
'moyen_paiement' => f('moyen_paiement'),
'toto' => 0
];
- if (f('type') == 'devis')
+ if (f('type') == DEVIS)
{
- $truc['type_facture'] = 0;
+ $truc['type_facture'] = DEVIS;
}
- elseif (f('type') == 'facture')
+ elseif (f('type') == FACT)
{
- $truc['type_facture'] = 1;
+ $truc['type_facture'] = FACT;
}
- elseif (f('type') == 'cerfa')
+ elseif (f('type') == CERFA)
{
- $truc['type_facture'] = 2;
+ $truc['type_facture'] = CERFA;
}
- elseif (f('type') == 'cotis')
+ elseif (f('type') == COTIS)
{
- $truc['type_facture'] = 3;
+ $truc['type_facture'] = COTIS;
}
foreach(f('designation') as $k=>$value)
@@ -86,12 +94,12 @@ if(f('save'))
if (f('base_receveur') == 'client')
{
$truc['receveur_membre'] = 0;
- $truc['receveur_id'] = f('client_id');
+ $truc['receveur_id'] = f('client');
}
elseif (f('base_receveur') == 'membre')
{
$truc['receveur_membre'] = 1;
- $truc['receveur_id'] = f('membre_id');
+ $truc['receveur_id'] = f('membre');
}
$r = $facture->edit($id, $truc);
@@ -106,53 +114,159 @@ if(f('save'))
}
}
+
+// Cotis
+
+$fields = $facture->recu_fields;
+
+$membre_id = f('membre') ?: $f->receveur_id;
+
+$values['numero_facture'] = $f->numero;
+$values['date_emission'] = $f->date_emission;
+
+$radio = $liste = [];
+
+if (f('select_cotis'))
+{
+ $form->check('add_cotis_1',[
+ 'numero_facture' => 'required|string',
+ 'date_emission' => 'required|date',
+ 'membre' => 'required|numeric',
+ ]);
+
+ $step = true;
+}
+elseif (f('add_cotis'))
+{
+ $form->check('add_cotis_2',[
+ 'numero_facture' => 'required|string',
+ 'date_emission' => 'required|date',
+ 'membre' => 'required|numeric',
+ 'cotisation' => 'required',
+ ]);
+
+ $radio['type'] = f('cotisation');
+
+ if (!$form->hasErrors())
+ {
+ try
+ {
+ $num = (int) str_replace('cotis_', '', $radio['type']);
+ foreach($fields as $field)
+ {
+ $cotis[$field] = f($field.'_'.$num);
+ }
+
+ $r = $facture->getCotis(f('membre'), $cotis['id']);
+ $r = $r[0];
+
+ $data = [
+ 'type_facture' => 3,
+ 'numero' => f('numero_facture'),
+ 'receveur_membre' => 1,
+ 'receveur_id' => f('membre'),
+ 'date_emission' => f('date_emission'),
+ 'moyen_paiement' => f('moyen_paiement'),
+ 'total' => $r->paid_amount ?? $r->amount,
+ 'contenu' => ['id' => $cotis['id'],
+ 'intitule' => $cotis['label'],
+ 'souscription' => $cotis['date'],
+ 'expiration' => $cotis['expiry'] ]
+ ];
+
+ if($facture->edit($id, $data))
+ {
+ Utils::redirect(PLUGIN_URL . 'facture.php?id='.(int)$id);
+ }
+ throw new UserException('Erreur d\'édition du reçu');
+ }
+ catch (UserException $e)
+ {
+ $form->addError($e->getMessage());
+ }
+ }
+
+ $step = true;
+}
+
+if ($step)
+{
+ try
+ {
+ $liste = $facture->getCotis((int)f('membre'));
+ }
+ catch (UserException $e)
+ {
+ $form->addError($e->getMessage());
+ }
+}
+
+
// Affichage
-$doc['moyens_paiement'] = $cats->listMoyensPaiement();
+$doc['moyens_paiement'] = $facture->listMoyensPaiement(true);
+// $doc['moyen_paiement'] = $doc['moyens_paiement'][$f->moyen_paiement];
$doc['moyen_paiement'] = $f->moyen_paiement;
-$doc['type'] = $facture->type[$f->type_facture];
+$doc['type'] = $f->type_facture;
$doc['numero_facture'] = $f->numero;
-$doc['reglee'] = $f->reglee?'on':'off';
+$doc['reglee'] = $f->reglee;
$doc['base_receveur'] = $f->receveur_membre?'membre':'client';
-$doc['client_id'] = $f->receveur_id;
-$doc['membre_id'] = $f->receveur_id;
+$doc['client'] = $f->receveur_id;
+$doc['membre'] = $f->receveur_id;
+
+$doc['date_emission'] = strtotime(f('date_emission')) ?: $f->date_emission;
+$doc['date_echeance'] = strtotime(f('date_echeance')) ?: $f->date_echeance; // Smarty m'a saoulé pour utiliser form_field|date_fr:---
$tpl->assign('doc', $doc);
-$tpl->assign('date_emission', strtotime(f('date_emission')) ?: $f->date_emission); // Smarty m'a saoulé pour utiliser form_field|date_fr:---
-$tpl->assign('date_echeance', strtotime(f('date_echeance')) ?: $f->date_echeance); // Du coup j'utilise form_field pour ces champs
+$radio['type'] = f('type')??$doc['type'];
+$tpl->assign('types_details', $facture->types);
+$tpl->assign('client_id', f('client') ?: -1);
+$tpl->assign('membre_id', f('membre') ?: -1);
+
+$tpl->assign(compact('liste', 'radio', 'step'));
// C'est un peu l'équivalent de form_field, mais j'avais écrit ça avant
// et oulala, c'est un peu complexe, faudrait réfléchir keskivomieux
-if (($d = f('designation')) && ($p = f('prix')))
+if ($f->type_facture != COTIS)
{
- foreach($d as $k=>$v)
+
+
+ if (($d = f('designation')) && ($p = f('prix')))
{
- if ($v == '' && $p[$k] == 0)
+ foreach($d as $k=>$v)
{
- continue;
+ if ($v == '' && $p[$k] == 0)
+ {
+ continue;
+ }
+ $designations[] = $v;
+ $prix[] = $p[$k];
+ }
+ }
+ else
+ {
+ foreach($f->contenu as $k=>$v)
+ {
+ if ($v['designation'] == '' && $v['prix'] == 0)
+ {
+ continue;
+ }
+ $designations[] = $v['designation'];
+ $prix[] = $v['prix'];
}
- $designations[] = $v;
- $prix[] = $p[$k];
}
}
-else
-{
- foreach($f->contenu as $k=>$v)
- {
- if ($v['designation'] == '' && $v['prix'] == 0)
- {
- continue;
- }
- $designations[] = $v['designation'];
- $prix[] = $v['prix'];
- }
-}
-$tpl->assign('designations', $designations);
-$tpl->assign('prix', $prix);
+
+$tpl->assign('designations', $designations??[]);
+$tpl->assign('prix', $prix??[]);
$tpl->assign('identite', $identite);
-$tpl->assign('membres', (array)DB::getInstance()->get('SELECT id, '.$identite.' FROM membres WHERE id_categorie != -2 NOT IN (SELECT id FROM membres_categories WHERE cacher = 1);'));
-$tpl->assign('clients', $client->listAll());
+$tpl->assign('membres', $db->getAssoc('SELECT id, '.$identite.' FROM membres WHERE id_categorie != -2 NOT IN (SELECT id FROM membres_categories WHERE cacher = 1);'));
+$tpl->assign('clients', $db->getAssoc('SELECT id, nom FROM plugin_facturation_clients;'));
+
+$date = new \DateTime;
+$date->setTimestamp(time());
+$tpl->assign('date', $date->format('d/m/Y'));
$tpl->display(PLUGIN_ROOT . '/templates/facture_modifier.tpl');
\ No newline at end of file
diff --git a/www/admin/index.php b/www/admin/index.php
index c317f2a..51526c3 100644
--- a/www/admin/index.php
+++ b/www/admin/index.php
@@ -2,19 +2,19 @@
namespace Garradin;
+require_once __DIR__ . '/_upgrade_trick.php';
require_once __DIR__ . '/_inc.php';
$session->requireAccess('compta', Membres::DROIT_ACCES);
$membres = new Membres;
-$cats = new Compta\Categories;
-$tpl->assign('moyens_paiement', $cats->listMoyensPaiement());
+$tpl->assign('moyens_paiement', $facture->listMoyensPaiement());
foreach($factures = $facture->listAll() as $k=>$f)
{
$factures[$k]->receveur = $f->receveur_membre? $membres->get($f->receveur_id) : $client->get($f->receveur_id);
- $factures[$k]->moyen_paiement = $cats->getMoyenPaiement($f->moyen_paiement);
+ $factures[$k]->moyen_paiement = $facture->getMoyenPaiement($f->moyen_paiement);
}
$tpl->assign('identite', $identite);
diff --git a/www/admin/pdf.php b/www/admin/pdf.php
index 84786e1..ff53fae 100644
--- a/www/admin/pdf.php
+++ b/www/admin/pdf.php
@@ -17,8 +17,7 @@ if (!$f = $facture->get($id))
throw new UserException("Ce document n'existe pas.");
}
-$cats = new Compta\Categories;
-$moyen_paiement = $cats->getMoyenPaiement($f->moyen_paiement);
+$moyen_paiement = $facture->getMoyenPaiement($f->moyen_paiement);
try
{
@@ -55,6 +54,11 @@ $pdf = new \Mpdf\Mpdf([
$pdf->SetAuthor($config->get('nom_asso'));
+$emission = $f->date_emission->format('d/m/Y');
+if (isset($f->date_echeance))
+{
+ $echeance = $f->date_echeance->format('d/m/Y');
+}
// Génération factures et devis
if ($f->type_facture < 2)
@@ -62,7 +66,6 @@ if ($f->type_facture < 2)
ob_start();
$doc = ($f->type_facture?'Facture':'Devis').' n°'.$f->numero;
- $emission = date('d/m/Y' ,$f->date_emission);
$pdf->SetTitle($doc.' - '.$emission);
$asso =
@@ -83,7 +86,6 @@ if ($f->type_facture < 2)
(($t = $c->telephone)?"Tel : $t ":'');
$total = number_format($f->total, 2, ',', ' ');
- $echeance = date('d/m/Y' ,$f->date_echeance);
$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é reglée.';
$footer = str_replace("\n", ' ', $plugin->getConfig('footer'));
@@ -263,11 +265,11 @@ elseif ($f->type_facture == 2)
$pdf->WriteText(81, 45, $c->ville);
$pdf->WriteText(90, 70, utf8_decode("***".$f->total."***"));
// numfmt a l'air de patauger avec des valeurs < 1
- $pdf->WriteText(62, 80, utf8_decode(numfmt_create('fr_FR', \NumberFormatter::SPELLOUT)->format($f->total)) . ' euros');
+ $pdf->WriteText(62, 80, numfmt_create('fr_FR', \NumberFormatter::SPELLOUT)->format($f->total) . ' euros');
- $pdf->WriteText(73, 89.5, utf8_decode(strftime('%d', $f->date_emission)));
- $pdf->WriteText(84, 89.5, utf8_decode(strftime('%m', $f->date_emission)));
- $pdf->WriteText(100, 89.5, utf8_decode(strftime('%Y', $f->date_emission)));
+ $pdf->WriteText(73, 89.5, utf8_decode($f->date_emission->format('d')));
+ $pdf->WriteText(84, 89.5, utf8_decode($f->date_emission->format('m')));
+ $pdf->WriteText(100, 89.5, utf8_decode($f->date_emission->format('Y')));
if($plugin->getConfig('droit_art200')){
$pdf->WriteText(57.5, 103.5, "X");
@@ -299,9 +301,9 @@ elseif ($f->type_facture == 2)
}
// Date d'édition du document
- $pdf->WriteText(144.4, 246.2, utf8_decode(strftime('%d', $f->date_echeance)));
- $pdf->WriteText(152.2, 246.2, utf8_decode(strftime('%m', $f->date_echeance)));
- $pdf->WriteText(160, 246.2, utf8_decode(strftime('%Y', $f->date_echeance)));
+ $pdf->WriteText(144.4, 246.2, utf8_decode($f->date_echeance->format('d')));
+ $pdf->WriteText(152.2, 246.2, utf8_decode($f->date_echeance->format('m')));
+ $pdf->WriteText(160, 246.2, utf8_decode($f->date_echeance->format('Y')));
// Signature
$img = new Fichiers($plugin->getConfig('signaturetxt'));
@@ -322,7 +324,6 @@ elseif ($f->type_facture == 3)
ob_start();
$doc = 'Reçu n°'.$f->numero;
- $emission = date('d/m/Y',$f->date_emission);
$pdf->SetTitle($doc.' - '.$emission);
$asso =
@@ -342,7 +343,8 @@ elseif ($f->type_facture == 3)
(($t = $c->email)?"Email : $t ":'').
(($t = $c->telephone)?"Tel : $t ":'');
- $total = number_format($f->total, 2, ',', ' ');
+ $total = $f->total / 100;
+ $total = number_format($total, 2, ',', ' ');
$lieu = $plugin->getConfig('ville_asso');
$intitule = $f->contenu['intitule'];
@@ -445,7 +447,7 @@ Bonjour,
Nous accusons réception de votre cotisation « $intitule » reçue le $emission et nous vous en remercions.
-Nous reconnaissons que vous avez acquitté la somme de $total € par $moyen_paiement .
+Nous reconnaissons que vous avez acquitté la somme de {$total} €.
Votre adhésion sera donc effective à compter du $souscription jusqu’au $expiration.
@@ -474,5 +476,5 @@ else
$pdf->Output(
($f->type_facture?'Facture':'Devis').' '.$f->numero
- . ' du '.date('d-m-Y' ,$f->date_emission)
+ . ' du '.$emission
.'.pdf', $t);