From e219afb405fb385cdb5d1d8dca1e4d0236e42de1 Mon Sep 17 00:00:00 2001 From: engel <> Date: Thu, 19 Jan 2023 16:54:00 +0000 Subject: [PATCH 1/3] =?UTF-8?q?D=C3=A9but=20ajout=20fonctionnalit=C3=A9s?= =?UTF-8?q?=20demand=C3=A9es=20:=20-=20param=C3=A9trer=20le=20num=C3=A9ro?= =?UTF-8?q?=20de=20re=C3=A7u=20-=20imprimer=20=C3=A0=20la=20demande=20l'ad?= =?UTF-8?q?resse=20de=20courriel?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit FossilOrigin-Name: 10c1ca642474c2b00b7d0197afc736f2c2aca3b453808ac1fda19e14b0acc092 --- config.json | 7 +++- templates/config.tpl | 98 +++++++++++++++++++++++++++++++++----------- www/admin/config.php | 29 ++++++++++--- www/admin/index.php | 5 +++ www/admin/style.css | 20 ++++++++- 5 files changed, 127 insertions(+), 32 deletions(-) diff --git a/config.json b/config.json index 6c0b346..35c9d50 100644 --- a/config.json +++ b/config.json @@ -26,5 +26,10 @@ "remarque" : "aide aux personnes en difficulté", "valeur" : 0 } - ] + ], + "numerotation" : { + "prefixe" : "", + "separateur" : "-", + "defaut" : "%a-%m" + } } diff --git a/templates/config.tpl b/templates/config.tpl index 3bc3e43..e812ef3 100644 --- a/templates/config.tpl +++ b/templates/config.tpl @@ -15,7 +15,7 @@
(obligatoire)
- {input type="textarea" name="objet_asso" source=$plugin.config label="" required="required" cols="50" rows="4" maxlength=300} + {input type="textarea" name="objet_asso" source=$plugin.config label="" required="required" cols="100" rows="3" maxlength=300}
@@ -23,17 +23,19 @@ (obligatoire ; sélectionnez tous les articles qui s'appliquent à l'association) - {foreach from=$plugin_config->articlesCGI key="key" item="article"} - {* +
+ {foreach from=$plugin_config->articlesCGI key="key" item="article"} + {* À VÉRIFIER : {input : checked ne fonctionne pas si l'attribut name est un tableau... {input type="checkbox" name="articlesCGI[]" value=$key label=$article.titre} *} -
- - -
- {/foreach} +
+ + +
+ {/foreach} +
@@ -54,16 +56,37 @@
Nom, fonction et signature du responsable -
-
- {input type="text" name="nom_responsable" source=$plugin.config label="" maxlength=50} -
+
-
-
- {input type="text" name="fonction_responsable" source=$plugin.config label="" maxlength=50} -
+ {* Nom du responsable *} +
+ {* +
+

du responsable

+*} + {input type="text" name="nom_responsable" source=$plugin.config label="Nom" help="du responsable" required=true maxlength=50} +
+ {* Fonction du responsable *} +
+{* +
+

du responsable

+*} + {input type="text" name="fonction_responsable" source=$plugin.config label="Fonction" help="du responsable" maxlength=50} +
+ + {* Ville avant signature *} +
+{* +
+

Précède la date sur le formulaire

+*} + {input type="text" name="ville_asso" source=$plugin.config label="Ville" help="précède la date sur le formulaire" maxlength=50} +
+
+ + {* Signature *}

L'image de la signature doit être d'une taille « raisonnable » et avoir un fond transparent

@@ -78,11 +101,37 @@
Autres informations -
-
-

Précède la date sur le formulaire

- {input type="text" name="ville_asso" source=$plugin.config label="" maxlength=50} -
+ + {* Numérotation des reçus *} +
+
+ {* +
+

%a : année ; %m : numéro membre ; %n : numéro séquentiel ; Exemple : HA-%a-%n donne HA-2022-51

+*} + {input type="text" name="numerotation" default=$chaine_numerotation label="Numérotation des reçus" maxlength=50} +
+ +
+ + Saisir ici un texte qui décrit le format de la numérotation des reçus. + +
+ Symboles spéciaux : +
    +
  • %a : année du reçu
  • +
  • %m : numéro de membre
  • +
  • %n : numéro d'ordre séquentiel (1, 2, ...)
  • +
+ Exemple : HAL-%a-%m donnera « Reçu numéro HAL-2022-51 » pour le membre de numéro 51 +
+
+
+ + {* Adresse de courriel *} +
+ {input type="checkbox" name="afficher_courriel" value=$afficher_courriel label="Imprimer adresse courriel" help="Cocher pour imprimer l'adresse de courriel des membres"} +
{* les champs de nom *} @@ -95,8 +144,9 @@
- - + +
{/foreach} diff --git a/www/admin/config.php b/www/admin/config.php index c5b406a..298ad01 100644 --- a/www/admin/config.php +++ b/www/admin/config.php @@ -18,7 +18,9 @@ if (f('save') && $form->check('recusfiscaux_config')) { try { // objet de l'association - $plugin->setConfig('objet_asso', trim(f('objet_asso'))); + if ($plugin->getConfig('objet_asso') != trim(f('objet_asso'))) { + $plugin->setConfig('objet_asso', trim(f('objet_asso'))); + } // articles du CGI $confArticles = $plugin->getConfig('articlesCGI'); @@ -45,8 +47,14 @@ if (f('save') && $form->check('recusfiscaux_config')) $plugin->setConfig("reduction", $confTaux); // nom, fonction et signature du responsable - $plugin->setConfig('nom_responsable', trim(f('nom_responsable'))); - $plugin->setConfig('fonction_responsable', trim(f('fonction_responsable'))); + if ($plugin->getConfig('nom_responsable') != trim(f('nom_responsable'))) { + $plugin->setConfig('nom_responsable', trim(f('nom_responsable'))); + } + if ($plugin->getConfig('fonction_responsable') != trim(f('fonction_responsable'))) { + $plugin->setConfig('fonction_responsable', trim(f('fonction_responsable'))); + } + + // signature if (isset($_SESSION['sig_file']) && count($_SESSION['sig_file']) > 0) { // supprimer la signature précédente, si besoin @@ -63,7 +71,9 @@ if (f('save') && $form->check('recusfiscaux_config')) // autres informations // ville - $plugin->setConfig('ville_asso', trim(f('ville_asso'))); + if ($plugin->getConfig('ville_asso') != trim(f('ville_asso'))) { + $plugin->setConfig('ville_asso', trim(f('ville_asso'))); + } // champs pour le nom et prénom foreach ($champsNom as $nom => $champ) @@ -85,6 +95,11 @@ if (f('save') && $form->check('recusfiscaux_config')) } } +$conf_numerotation = $plugin->getConfig('numerotation'); +$chaine_numerotation = (isset($conf_numerotation->prefixe) && $conf_numerotation->prefixe != "") ? $conf_numerotation->prefixe : 'XXX'; +$chaine_numerotation .= $conf_numerotation->separateur . $conf_numerotation->defaut; +$afficher_courriel = false; + // trier les champs de nom pour l'affichage uasort($champsNom, function ($a, $b) { @@ -93,9 +108,11 @@ uasort($champsNom, function ($a, $b) $tpl->assign('ok', qg('ok') !== null); $path = qg('path') ?: File::CONTEXT_CONFIG; -$tpl->assign('path', $path); +//$tpl->assign('path', $path); $tpl->assign('default_signature', \Garradin\WWW_URL . "plugin/recusfiscaux/default_signature.png"); $tpl->assign('plugin_config', $plugin->getConfig()); -$tpl->assign('champsNom', $champsNom); +//$tpl->assign('champsNom', $champsNom); $tpl->assign('plugin_css', ['style.css']); +//$tpl->assign('chaine_numerotation', $chaine_numerotation); +$tpl->assign(compact('path', 'champsNom', 'chaine_numerotation', 'afficher_courriel')); $tpl->display(PLUGIN_ROOT . '/templates/config.tpl'); diff --git a/www/admin/index.php b/www/admin/index.php index a7e73a5..284ff06 100644 --- a/www/admin/index.php +++ b/www/admin/index.php @@ -10,6 +10,11 @@ if (! isset($_SESSION['annee_recu']) || $_SESSION['annee_recu'] == "") $_SESSION['annee_recu'] = date("Y") - 1; } +// error_log("config=" . print_r($plugin->getConfig(), true)); +// error_log("articlesCGI=" . print_r($plugin->getConfig('articlesCGI'), true)); +// error_log("reduction=" . print_r($plugin->getConfig('reduction'), true)); +// error_log("numerotation=" . print_r($plugin->getConfig('numerotation'), true)); + // nombre de taux de réduction activés $nbTaux = 0; foreach ($plugin->getConfig('reduction') as $taux) diff --git a/www/admin/style.css b/www/admin/style.css index c79f6f3..82485ec 100644 --- a/www/admin/style.css +++ b/www/admin/style.css @@ -85,7 +85,25 @@ div.versements /* config */ dl.config { - padding : 1ex 0; + padding-bottom : 1ex; + padding-right : 1em; +} +div#articles_cgi +{ + display: flex; +} +div.article +{ + margin-right : 3em; +} +div#config_nom_fonction +{ + display: flex; +} +div#numerotation +{ + display:flex; + align-items: last baseline; } div.champnom { From 25cba953a75de4d261a1f024700bf7b270c30a64 Mon Sep 17 00:00:00 2001 From: engel <> Date: Mon, 23 Jan 2023 17:53:53 +0000 Subject: [PATCH 2/3] =?UTF-8?q?Am=C3=A9lioration=20gestion=20num=C3=A9ro?= =?UTF-8?q?=20de=20re=C3=A7u=20et=20impression=20adresse=20courriel?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit FossilOrigin-Name: 7ec287c7e2886a4a91151abf97e5044eb9bf1617063fc3d0c818b5d7ab88eafb --- config.json | 19 +++-- lib/Personne.php | 8 ++ lib/Utils.php | 4 + templates/config.tpl | 154 ++++++++++++++++++++---------------- templates/recu.skel | 13 ++- www/admin/config.php | 79 +++++++++--------- www/admin/generer_recus.php | 49 ++++++++++-- www/admin/index.php | 2 +- www/admin/script.js | 35 ++++++++ www/admin/style.css | 12 ++- 10 files changed, 249 insertions(+), 126 deletions(-) diff --git a/config.json b/config.json index 35c9d50..622936c 100644 --- a/config.json +++ b/config.json @@ -2,15 +2,15 @@ "articlesCGI" : [ { "titre" : "200", - "valeur" : 0 + "valeur" : false }, { "titre" : "238 bis", - "valeur" : 0 + "valeur" : false }, { "titre" : "978", - "valeur" : 0 + "valeur" : false } ], "reduction" : [ @@ -18,18 +18,21 @@ "taux" : "normal", "ligne" : "UF", "remarque" : "", - "valeur" : 0 + "valeur" : false }, { "taux" : "majoré", "ligne" : "UD", "remarque" : "aide aux personnes en difficulté", - "valeur" : 0 + "valeur" : false } ], "numerotation" : { "prefixe" : "", - "separateur" : "-", - "defaut" : "%a-%m" - } + "annee" : false, + "membre" : false, + "sequentiel" : false, + "valeur_init": 1 + }, + "imprimerCourriel" : false } diff --git a/lib/Personne.php b/lib/Personne.php index 8037c1a..2a58115 100644 --- a/lib/Personne.php +++ b/lib/Personne.php @@ -8,6 +8,8 @@ namespace Garradin\Plugin\RecusFiscaux; class Personne { public $id; + public $numero; + public $courriel; public $rang; // par ordre alpha de nomPrenom ; sert aux tris public $nomPrenom; public $adresse; @@ -17,6 +19,8 @@ class Personne public function __construct( $id, + $numero, + $courriel, $rang, $nomPrenom, $adresse, @@ -25,6 +29,8 @@ class Personne ) { $this->id = $id; + $this->numero = $numero; + $this->courriel = $courriel; $this->rang = $rang; $this->nomPrenom = $nomPrenom; $this->adresse = $adresse; @@ -40,6 +46,8 @@ class Personne { return new Personne( $this->id, + $this->numero, + $this->courriel, $this->rang, $this->nomPrenom, $this->adresse, diff --git a/lib/Utils.php b/lib/Utils.php index 5d6bae6..416cfbf 100644 --- a/lib/Utils.php +++ b/lib/Utils.php @@ -297,6 +297,8 @@ class Utils $sql = sprintf( 'SELECT membres.id as idUser, + membres.numero, + membres.email, row_number() over(order by %s) as rang, %s as nom, membres.adresse as adresse, @@ -327,6 +329,8 @@ class Utils foreach (DB::getInstance()->iterate($sql) as $personne) { $donateurs[$personne->idUser] = new Personne($personne->idUser, + $personne->numero, + $personne->email, $personne->rang, $personne->nom, $personne->adresse, diff --git a/templates/config.tpl b/templates/config.tpl index e812ef3..7fdb7cb 100644 --- a/templates/config.tpl +++ b/templates/config.tpl @@ -38,13 +38,14 @@
+
(obligatoire ; sélectionnez tous les taux qui s'appliquent à l'association)
{foreach from=$plugin_config->reduction key="key" item="taux"} -
+
@@ -99,38 +88,65 @@
+ {* Numérotation des reçus *} +
+ Numérotation des reçus +
+ + Sélectionner les éléments qui doivent faire partie du numéro de reçu + +
+
    +
  • Préfixe : texte qui sera imprimé tel quel au début du numéro (ex : sigle de l'association) ; facultatif
  • +
  • Année fiscale : numéro de l'année fiscale (ex : 2022) ; facultatif
  • +
      + Sélectionner au moins un des deux numéros suivants +
    • Numéro de membre
    • +
    • Numéro séquentiel (1, 2, ...) : numéro d'ordre du reçu
    • +
    +
  • Valeur initiale : si vous avez choisi un numéro séquentiel, indiquez le numéro du premier reçu
  • +
+
+
+
+ + {* Préfixe *} +
+ {input type="text" name="prefixe" source=$numerotation label="Préfixe" maxlength=20} +
+ + {* Autres éléments de la numérotation *} +
+ {input type="checkbox" name="annee" source=$numerotation label="Année fiscale" value=1} +
+ +
+ {input type="checkbox" name="membre" source=$numerotation label="N° de membre" value=1} +
+ +
+ {input type="checkbox" name="sequentiel" source=$numerotation label="N° séquentiel" value=1} +
+ +
+ {input type="number" name="valeur_init" source=$numerotation label="Valeur initiale"} +
+
+
+
Autres informations - {* Numérotation des reçus *} -
-
- {* -
-

%a : année ; %m : numéro membre ; %n : numéro séquentiel ; Exemple : HA-%a-%n donne HA-2022-51

-*} - {input type="text" name="numerotation" default=$chaine_numerotation label="Numérotation des reçus" maxlength=50} -
- -
- - Saisir ici un texte qui décrit le format de la numérotation des reçus. - -
- Symboles spéciaux : -
    -
  • %a : année du reçu
  • -
  • %m : numéro de membre
  • -
  • %n : numéro d'ordre séquentiel (1, 2, ...)
  • -
- Exemple : HAL-%a-%m donnera « Reçu numéro HAL-2022-51 » pour le membre de numéro 51 -
-
-
- {* Adresse de courriel *}
- {input type="checkbox" name="afficher_courriel" value=$afficher_courriel label="Imprimer adresse courriel" help="Cocher pour imprimer l'adresse de courriel des membres"} +
+
+ {if $plugin.config.imprimerCourriel} + {input type="checkbox" name="imprimerCourriel" value="1" checked="checked" label="Imprimer" help="Cocher pour imprimer l'adresse de courriel des membres sur les reçus"} + {else} + {input type="checkbox" name="imprimerCourriel" value="1" label="Imprimer" help="Cocher pour imprimer l'adresse de courriel des membres sur les reçus"} + {/if} +
{* les champs de nom *} @@ -141,14 +157,14 @@
{foreach from=$champsNom key="nom" item="champ"} -
-
-
- - -
+
+
+
+ +
+
{/foreach}
@@ -158,28 +174,30 @@

{csrf_field key="recusfiscaux_config"} - {button type="submit" name="save" label="Enregistrer" shape="right" class="main"} + {button type="submit" name="save" label="Enregistrer" shape="right" class="main" onclick="return verifierConfig(this.form, articles_cgi, taux_reduction)"}

{literal} - -{/literal} \ No newline at end of file + +{/literal} +{* scripts divers *} + diff --git a/templates/recu.skel b/templates/recu.skel index dded5b1..941ce6a 100644 --- a/templates/recu.skel +++ b/templates/recu.skel @@ -90,7 +90,7 @@

Reçu au titre des dons à certains organismes d'intérêt général

Articles 200, 238 bis et 978 du code général des impôts

-

Reçu numéro {{$annee_recu}}/{{$numero}}

+

Reçu {{$numero}}

@@ -103,9 +103,14 @@

Donateur

-

{{$nom}}
- {{$adresse}}
- {{$code_postal}} {{$ville}}

+

+ {{$nom}}
+ {{$adresse}}
+ {{$code_postal}} {{$ville}} + {{if $courriel != ""}} +
courriel : {{$courriel}} + {{/if}} +

diff --git a/www/admin/config.php b/www/admin/config.php index 298ad01..f40b688 100644 --- a/www/admin/config.php +++ b/www/admin/config.php @@ -7,15 +7,14 @@ use Garradin\Entities\Files\File; use Garradin\Plugin\RecusFiscaux\Utils; $session->requireAccess($session::SECTION_CONFIG, $session::ACCESS_ADMIN); -$art_sel = f('articlesCGI') ? : []; -$taux_sel = f('tauxReduction') ? : []; -$noms_sel = f('champsNom') ? : []; +$art_sel = f('articlesCGI') ?: []; +$taux_sel = f('tauxReduction') ?: []; +$noms_sel = f('champsNom') ?: []; -// récupérer les champs des noms +// récupérer les champs des noms $champsNom = Utils::getChampsNom($config, $plugin); -if (f('save') && $form->check('recusfiscaux_config')) -{ +if (f('save') && $form->check('recusfiscaux_config')) { try { // objet de l'association if ($plugin->getConfig('objet_asso') != trim(f('objet_asso'))) { @@ -26,11 +25,11 @@ if (f('save') && $form->check('recusfiscaux_config')) $confArticles = $plugin->getConfig('articlesCGI'); // effacer l'ancienne configuration for ($i = 0; $i < count($confArticles); ++$i) { - $confArticles[$i]->valeur = 0; + $confArticles[$i]->valeur = false; // 0 } // et copier la nouvelle foreach ($art_sel as $article) { - $confArticles[$article]->valeur = 1; + $confArticles[$article]->valeur = true; // 1 } $plugin->setConfig("articlesCGI", $confArticles); @@ -38,28 +37,35 @@ if (f('save') && $form->check('recusfiscaux_config')) $confTaux = $plugin->getConfig('reduction'); // effacer l'ancienne configuration for ($i = 0; $i < count($confTaux); ++$i) { - $confTaux[$i]->valeur = 0; + $confTaux[$i]->valeur = false; // 0 } // et copier la nouvelle foreach ($taux_sel as $taux) { - $confTaux[$taux]->valeur = 1; + $confTaux[$taux]->valeur = true; // 1 } $plugin->setConfig("reduction", $confTaux); - // nom, fonction et signature du responsable + // Informations au sujet du responsable if ($plugin->getConfig('nom_responsable') != trim(f('nom_responsable'))) { $plugin->setConfig('nom_responsable', trim(f('nom_responsable'))); } if ($plugin->getConfig('fonction_responsable') != trim(f('fonction_responsable'))) { $plugin->setConfig('fonction_responsable', trim(f('fonction_responsable'))); } - + // ville + if ($plugin->getConfig('ville_asso') != trim(f('ville_asso'))) { + $plugin->setConfig('ville_asso', trim(f('ville_asso'))); + } // signature - if (isset($_SESSION['sig_file']) && count($_SESSION['sig_file']) > 0) - { + // error_log("SESSION['sig_file'] = " . print_r($_SESSION['sig_file'], true)); + // error_log("plugin->getConfig('signature') = " . $plugin->getConfig('signature')); + + if (isset($_SESSION['sig_file']) && count($_SESSION['sig_file']) > 0) { // supprimer la signature précédente, si besoin - if (null !== $plugin->getConfig('signature')) - { + if ( + null !== $plugin->getConfig('signature') && + $plugin->getConfig('signature') != $_SESSION['sig_file'][0]->path + ) { $sig_file = \Garradin\Files\Files::get($plugin->getConfig('signature')); if (null !== $sig_file) { $sig_file->delete(); @@ -70,49 +76,48 @@ if (f('save') && $form->check('recusfiscaux_config')) } // autres informations - // ville - if ($plugin->getConfig('ville_asso') != trim(f('ville_asso'))) { - $plugin->setConfig('ville_asso', trim(f('ville_asso'))); + // numérotation des reçus + $configNum = $plugin->getConfig('numerotation'); + error_log("configNum=" . print_r($configNum, true)); + $formNum = clone $configNum; + if ($configNum->prefixe != trim(f('prefixe'))) { + $formNum->prefixe = trim(f('prefixe')); } + $formNum->annee = f('annee'); + $formNum->membre = f('membre'); + $formNum->sequentiel = f('sequentiel'); + $formNum->valeur_init = f('valeur_init'); + $plugin->setConfig('numerotation', $formNum); + + // impression des adresses de courriel + $plugin->setConfig('imprimerCourriel', f('imprimerCourriel')); // champs pour le nom et prénom - foreach ($champsNom as $nom => $champ) - { + foreach ($champsNom as $nom => $champ) { $champ->position = 0; } $i = -count($noms_sel); - foreach ($noms_sel as $nom) - { + foreach ($noms_sel as $nom) { $champsNom[$nom]->position = $i++; } $plugin->setConfig('champsNom', $champsNom); \Garradin\Utils::redirect(PLUGIN_URL . 'config.php?ok'); - } - catch (UserException $e) - { + } catch (UserException $e) { $form->addError($e->getMessage()); } } -$conf_numerotation = $plugin->getConfig('numerotation'); -$chaine_numerotation = (isset($conf_numerotation->prefixe) && $conf_numerotation->prefixe != "") ? $conf_numerotation->prefixe : 'XXX'; -$chaine_numerotation .= $conf_numerotation->separateur . $conf_numerotation->defaut; -$afficher_courriel = false; - // trier les champs de nom pour l'affichage -uasort($champsNom, function ($a, $b) -{ +uasort($champsNom, function ($a, $b) { return $a->position - $b->position; }); $tpl->assign('ok', qg('ok') !== null); $path = qg('path') ?: File::CONTEXT_CONFIG; -//$tpl->assign('path', $path); $tpl->assign('default_signature', \Garradin\WWW_URL . "plugin/recusfiscaux/default_signature.png"); $tpl->assign('plugin_config', $plugin->getConfig()); -//$tpl->assign('champsNom', $champsNom); $tpl->assign('plugin_css', ['style.css']); -//$tpl->assign('chaine_numerotation', $chaine_numerotation); -$tpl->assign(compact('path', 'champsNom', 'chaine_numerotation', 'afficher_courriel')); +$tpl->assign('numerotation', $plugin->getConfig('numerotation')); +$tpl->assign(compact('path', 'champsNom')); $tpl->display(PLUGIN_ROOT . '/templates/config.tpl'); diff --git a/www/admin/generer_recus.php b/www/admin/generer_recus.php index d3f654c..25b5d30 100644 --- a/www/admin/generer_recus.php +++ b/www/admin/generer_recus.php @@ -52,6 +52,24 @@ elseif ($nbArticles > 1) // libellés pour les taux de réduction $libelles_taux = Utils::getLignesReduction($plugin->getConfig('reduction')); +$configNum = $plugin->getConfig('numerotation'); +error_log("config num = " . print_r($configNum, true)); +$prefixeNum = ""; +if (isset($configNum->prefixe) && $configNum->prefixe != "") { + $prefixeNum = $configNum->prefixe; +} +if (isset($configNum->annee) && $configNum->annee) { + if ($prefixeNum != "") { $prefixeNum .= "-"; } + $prefixeNum .= $_SESSION['annee_recu']; +} +if (isset($configNum->sequentiel) && $configNum->sequentiel) { + if (isset($configNum->valeur_init) && $configNum->valeur_init !="") { + $numero_sequentiel = $configNum->valeur_init; + } else { + $numero_sequentiel = 1; + } +} + // filtrer les versements sélectionnés $lesLignes = f('selected'); $versementsSelectionnes = array(); @@ -82,14 +100,33 @@ foreach ($totalPersonnes as $idPersonne => $personne) $tpl->assign('nom_responsable', $plugin->getConfig('nom_responsable')); $tpl->assign('fonction_responsable', $plugin->getConfig('fonction_responsable')); $tpl->assign('ville_asso', $plugin->getConfig('ville_asso')); - $tpl->assign('annee_recu', $_SESSION['annee_recu']); - $tpl->assign('numero', $personne->id); $tpl->assign('nom', $personne->nomPrenom); $tpl->assign('adresse', $personne->adresse); $tpl->assign('code_postal', $personne->codePostal); $tpl->assign('ville', $personne->ville); $tpl->assign('date', date("j/m/Y")); + // numéro de reçu + $chaineNum = $prefixeNum; + if (isset($configNum->membre) && $configNum->membre) { + if ($chaineNum != "") { $chaineNum .= "-"; } + $chaineNum .= $personne->numero; + } + if (isset($configNum->sequentiel) && $configNum->sequentiel) { + if ($chaineNum != "") { $chaineNum .= "-"; } + $chaineNum .= $numero_sequentiel; + ++$numero_sequentiel; + } + $tpl->assign('numero', $chaineNum); + // adresse de courriel + if ($plugin->getConfig('imprimerCourriel')) { + $courriel = $personne->courriel; + } + else { + $courriel = ""; + } + $tpl->assign('courriel', $courriel); + // les versements $tpl->registerSection('versements', function () use($personne, $libelles_taux, $fmt) @@ -156,10 +193,10 @@ $fichierZip = Utils::makeArchive( ); //supprimer les fichiers pdf (utile ?) -// foreach ($listeFichiersPDF as $f) -// { -// unlink($f); -// } +foreach ($listeFichiersPDF as $f) +{ + unlink($f); +} /** * Cumuler les versements de chaque personne diff --git a/www/admin/index.php b/www/admin/index.php index 284ff06..a2a240b 100644 --- a/www/admin/index.php +++ b/www/admin/index.php @@ -19,7 +19,7 @@ if (! isset($_SESSION['annee_recu']) || $_SESSION['annee_recu'] == "") $nbTaux = 0; foreach ($plugin->getConfig('reduction') as $taux) { - if ($taux->valeur == 1) { ++$nbTaux; } + if ($taux->valeur) { ++$nbTaux; } } // idem avec les champs nom/prénom diff --git a/www/admin/script.js b/www/admin/script.js index 883517c..fcc700f 100644 --- a/www/admin/script.js +++ b/www/admin/script.js @@ -258,3 +258,38 @@ function montrerMasquerDetails(idElem, classe, texte) } } } + +/** + * + */ +function aumoinsun(conteneur, message) +{ + let listeCheck = conteneur.querySelectorAll('input[type=checkbox]'); + for (let elem of listeCheck) + { + if (elem.checked) { return true; } + } + alert("Erreur : il faut sélectionner au moins " + message); + return false; +} +/** + * vérifier les données saisies dans le formulaire de configuration +*/ +function verifierConfig( + formulaire, + divArticles, + divTauxReduc +) +{ + // articles + if (! aumoinsun(divArticles, "un article")) { return false; } + + // taux de réduction + if (! aumoinsun(divTauxReduc, "un taux de réduction")) { return false; } + + // Nom, fonction, signature + + + // alert("Erreur : il faut sélectionner au moins un versement"); + return true; +} diff --git a/www/admin/style.css b/www/admin/style.css index 82485ec..9aad3a5 100644 --- a/www/admin/style.css +++ b/www/admin/style.css @@ -100,10 +100,10 @@ div#config_nom_fonction { display: flex; } -div#numerotation +div#numero_recus { display:flex; - align-items: last baseline; +/* align-items: last baseline;*/ } div.champnom { @@ -128,3 +128,11 @@ ul.reduction span.radio-btn margin-left : 2em; border-spacing : 0.1em; } +input#f_prefixe +{ + max-width : 8em; +} +input#f_valeur_init +{ + max-width: 4em; +} From de086d9f7265be112b1b3d88139ff0d2238dd0b1 Mon Sep 17 00:00:00 2001 From: engel <> Date: Tue, 24 Jan 2023 13:08:47 +0000 Subject: [PATCH 3/3] =?UTF-8?q?Finalisation=20num=C3=A9ro=20de=20re=C3=A7u?= =?UTF-8?q?=20et=20impression=20adresse=20courriel?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit FossilOrigin-Name: c8806d21d99de18397e95e2a4aae69f3a68dd3c7fbb763aa987d267f0761f863 --- README.md | 6 +- garradin_plugin.ini | 4 +- templates/config.tpl | 84 ++++++++-------- templates/index.tpl | 4 +- www/admin/index.php | 5 - www/admin/script.js | 222 +++++++++++++++++++++---------------------- www/admin/style.css | 81 +++++++++++----- 7 files changed, 214 insertions(+), 192 deletions(-) diff --git a/README.md b/README.md index 42bd53f..83801e5 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,13 @@ # Plugin reçus fiscaux pour Garradin/Paheko Plugin de reçus fiscaux pour le logiciel de gestion d'association Garradin/Paheko (https://paheko.cloud). -Source : https://git.roflcopter.fr/lesanges/recus-fiscaux-garradin ## Installation ### Attention Les archives disponibles sur ce gitlab n'ont pas un format compatible avec Garragin/Paheko et ne peuvent donc être utilisées telles quelles ; il faut soit les transformer pour les rendre compatibles, soit (plus simple) télécharger l'archive indiquée ci-dessous. +### Archive Vous pouvez télécharger [l'archive .tar.gz](https://ncloud6.zaclys.com/index.php/s/RZQK2So8HemkH3w), et la copier dans le dossier plugins de Garradin/Paheko. ## Fonctionnalités @@ -27,4 +27,6 @@ Vous pouvez télécharger [l'archive .tar.gz](https://ncloud6.zaclys.com/index.p - signature (image) - autres - ville (précède la date sur le formulaire) - - champs pour le nom et prénom (le libellé doit contenir le terme 'nom', casse indifférente) + - paramétrage numéro de reçu (préfixe quelconque, année fiscale, numéro de memmbre ou séquentiel) + - possibilité imprimer adresse de courriel + - choix et ordre des champs pour le nom et prénom (le libellé doit contenir le terme 'nom', casse indifférente) diff --git a/garradin_plugin.ini b/garradin_plugin.ini index 81add01..27e3292 100644 --- a/garradin_plugin.ini +++ b/garradin_plugin.ini @@ -1,8 +1,8 @@ nom="Reçus fiscaux" description="Génération de reçus fiscaux pour les dons des membres" auteur="jce" -url="https://git.roflcopter.fr/lesanges/recus-fiscaux-garradin" -version="0.7" +url="https://ncloud6.zaclys.com/index.php/s/RZQK2So8HemkH3w" +version="0.8" menu=1 config=1 min_version="1.1.23" diff --git a/templates/config.tpl b/templates/config.tpl index 7fdb7cb..0e60b4e 100644 --- a/templates/config.tpl +++ b/templates/config.tpl @@ -44,14 +44,14 @@ (obligatoire ; sélectionnez tous les taux qui s'appliquent à l'association) - {foreach from=$plugin_config->reduction key="key" item="taux"} -
+
+ {foreach from=$plugin_config->reduction key="key" item="taux"} {/if} -
- {/foreach} + {/foreach} +
@@ -91,47 +91,49 @@ {* Numérotation des reçus *}
Numérotation des reçus -
- - Sélectionner les éléments qui doivent faire partie du numéro de reçu - -
-
    -
  • Préfixe : texte qui sera imprimé tel quel au début du numéro (ex : sigle de l'association) ; facultatif
  • -
  • Année fiscale : numéro de l'année fiscale (ex : 2022) ; facultatif
  • -
      - Sélectionner au moins un des deux numéros suivants -
    • Numéro de membre
    • -
    • Numéro séquentiel (1, 2, ...) : numéro d'ordre du reçu
    • -
    -
  • Valeur initiale : si vous avez choisi un numéro séquentiel, indiquez le numéro du premier reçu
  • -
-
-
+
+ + Sélectionner les éléments qui doivent faire partie du numéro de reçu + +
+
    +
  • Préfixe : texte qui sera imprimé tel quel au début du numéro (ex : sigle de l'association) ; + facultatif
  • +
  • Année fiscale : numéro de l'année fiscale (ex : 2022) ; facultatif
  • +
      + Sélectionner au moins un des deux numéros suivants +
    • Numéro de membre
    • +
    • Numéro séquentiel (1, 2, ...) : numéro d'ordre du reçu
    • +
    +
  • Valeur initiale : si vous avez choisi un numéro séquentiel, indiquez le numéro du premier reçu +
  • +
+
+
- {* Préfixe *} -
- {input type="text" name="prefixe" source=$numerotation label="Préfixe" maxlength=20} -
+ {* Préfixe *} +
+ {input type="text" name="prefixe" source=$numerotation label="Préfixe" maxlength=20} +
- {* Autres éléments de la numérotation *} -
- {input type="checkbox" name="annee" source=$numerotation label="Année fiscale" value=1} -
+ {* Autres éléments de la numérotation *} +
+ {input type="checkbox" name="annee" source=$numerotation label="Année fiscale" value=1} +
-
- {input type="checkbox" name="membre" source=$numerotation label="N° de membre" value=1} -
+
+ {input type="checkbox" name="membre" source=$numerotation label="N° de membre" value=1} +
-
- {input type="checkbox" name="sequentiel" source=$numerotation label="N° séquentiel" value=1} -
+
+ {input type="checkbox" name="sequentiel" source=$numerotation label="N° séquentiel" value=1} +
-
- {input type="number" name="valeur_init" source=$numerotation label="Valeur initiale"} -
-
+
+ {input type="number" name="valeur_init" source=$numerotation label="Valeur initiale"} +
+
@@ -174,7 +176,7 @@

{csrf_field key="recusfiscaux_config"} - {button type="submit" name="save" label="Enregistrer" shape="right" class="main" onclick="return verifierConfig(this.form, articles_cgi, taux_reduction)"} + {button type="submit" name="save" label="Enregistrer" shape="right" class="main" onclick="return verifierConfig(articles_cgi, taux_reduction)"}

@@ -200,4 +202,4 @@ {/literal} {* scripts divers *} - + \ No newline at end of file diff --git a/templates/index.tpl b/templates/index.tpl index b8621d4..583e1ff 100644 --- a/templates/index.tpl +++ b/templates/index.tpl @@ -78,7 +78,7 @@

{csrf_field key="generer_tous_recus"} - {button type="submit" name="generer_tous" label="Poursuivre" shape="right" class="main" onclick="return verifierRadio('menu_versements');" } + {button type="submit" name="generer_tous" label="Poursuivre" shape="right" class="main" onclick="return verifierTaux(menu_versements);" }

@@ -183,7 +183,7 @@

{csrf_field key="generer_recus_activites"} - {button type="submit" name="generer_activites" label="Poursuivre" shape="right" class="main" onclick="return verifierCases('menu_activites_tarifs');" } + {button type="submit" name="generer_activites" label="Poursuivre" shape="right" class="main" onclick="return verifierActivitésTaux(menu_activites_tarifs);" }

diff --git a/www/admin/index.php b/www/admin/index.php index a2a240b..4c5e0f3 100644 --- a/www/admin/index.php +++ b/www/admin/index.php @@ -10,11 +10,6 @@ if (! isset($_SESSION['annee_recu']) || $_SESSION['annee_recu'] == "") $_SESSION['annee_recu'] = date("Y") - 1; } -// error_log("config=" . print_r($plugin->getConfig(), true)); -// error_log("articlesCGI=" . print_r($plugin->getConfig('articlesCGI'), true)); -// error_log("reduction=" . print_r($plugin->getConfig('reduction'), true)); -// error_log("numerotation=" . print_r($plugin->getConfig('numerotation'), true)); - // nombre de taux de réduction activés $nbTaux = 0; foreach ($plugin->getConfig('reduction') as $taux) diff --git a/www/admin/script.js b/www/admin/script.js index fcc700f..e1b03b0 100644 --- a/www/admin/script.js +++ b/www/admin/script.js @@ -1,5 +1,9 @@ "use strict"; +// ------------------------------------------------------------------------ +// actions sur la liste des versements +// ------------------------------------------------------------------------ + /** * Fonction appelée quand on (dé)coche la case globale * (dé)sélectionner toutes les cases de toutes les activités @@ -128,104 +132,6 @@ function changerMessage(message, idCase) } } -/** - * fonction appelée lors de la validation du formulaire - * @return vrai si au moins un choix a été fait - * @param {HTMLFormElement} formulaire - */ -function verifierChoix(formulaire) -{ - let listeCheck = formulaire.getElementsByTagName("input"); - let ok = false; - for (let i = 1; i < listeCheck.length; ++i) - { - if (listeCheck[i].checked) - { - ok = true; - break; - } - } - if (! ok) - { - alert("Erreur : il faut sélectionner au moins un versement"); - } - return ok; -} - -/** - * positionner l'action déclenchée par l'envoi du formulaire - * afficher et masquer des portions de formulaire selon l'action - * @param {HTMLFormElement} formulaire - * @param {string} action après envoi du formulaire - * @param {any} idElem id de l'élément à afficher - * @param {any} nomClasse classe des éléments à masquer (sauf idElem) - */ -function choixMethodeGeneration(formulaire, action, idElem, nomClasse) -{ - formulaire.setAttribute('action', 'action.php?action=' + action); - for (let elem of formulaire.querySelectorAll(nomClasse)) - { - if (elem.id == idElem) - { - elem.classList.remove('hidden'); - } - else - { - elem.classList.add('hidden'); - } - } -} - -/** - * vérifier - * - qu'au moins une activité/tarif est sélectionnée - * - qu'un radio de chaque activité/tarif sélectionné a été sélectionné :) - * @param {string} idElem id du conteneur des cases à vérifier - */ -function verifierCases(idElem) -{ - let div = document.getElementById(idElem); - let nbChoix = 0; - // parcourir les cases à cocher - for (let idCase of div.querySelectorAll("input[type=checkbox]")) - { - if (idCase.checked) { - ++nbChoix; - // vérifier qu'un radio de la même ligne est sélectionné - let ligneCorrecte = false; - // trouver la ligne englobante - let ligne = idCase.closest("li"); - for (let idRadio of ligne.querySelectorAll('input[type=radio]')) - { - if (idRadio.checked) { ligneCorrecte = true; break; } - } - if (! ligneCorrecte) { - alert("Erreur : il faut sélectionner un taux de réduction dans chaque ligne cochée"); - return false; - } - } - } - if (nbChoix == 0) { - alert("Erreur : il faut sélectionner au moins une ligne"); - } - return nbChoix != 0; -} - -/** - * vérifier qu'un radio a été sélectionné dans la div paramètre - * @param {string} idElem id du conteneur des radios à vérifier - */ -function verifierRadio(idElem) -{ - let div = document.getElementById(idElem); - for (let idRadio of div.querySelectorAll('input[type=radio]')) - { - if (idRadio.checked) { return true; } - } - alert("Erreur : il faut sélectionner un taux de réduction"); - return false; -} - /** * afficher/masquer les détails * @param {string} idElem bouton de masquage/affichage @@ -260,32 +166,100 @@ function montrerMasquerDetails(idElem, classe, texte) } /** - * + * fonction appelée lors de la demande de génération des reçus + * vérifier qu'au moins un versement a été sélectionné + * @return vrai si au moins un choix a été fait + * @param {HTMLFormElement} formulaire */ -function aumoinsun(conteneur, message) +function verifierChoix(formulaire) { - let listeCheck = conteneur.querySelectorAll('input[type=checkbox]'); - for (let elem of listeCheck) - { - if (elem.checked) { return true; } - } - alert("Erreur : il faut sélectionner au moins " + message); - return false; + return verifierCases(formulaire, 'checkbox', "au moins un versement"); } + +// ------------------------------------------------------------------------ +// actions sur la page d'accueil +// ------------------------------------------------------------------------ + +/** + * positionner l'action déclenchée par l'envoi du formulaire + * afficher et masquer des portions de formulaire selon l'action + * @param {HTMLFormElement} formulaire + * @param {string} action après envoi du formulaire + * @param {any} idElem id de l'élément à afficher + * @param {any} nomClasse classe des éléments à masquer (sauf idElem) + */ +function choixMethodeGeneration(formulaire, action, idElem, nomClasse) +{ + formulaire.setAttribute('action', 'action.php?action=' + action); + for (let elem of formulaire.querySelectorAll(nomClasse)) + { + if (elem.id == idElem) + { + elem.classList.remove('hidden'); + } + else + { + elem.classList.add('hidden'); + } + } +} + +/** + * vérifier + * - qu'au moins une activité/tarif est sélectionnée + * - qu'un radio de chaque activité/tarif sélectionné a été sélectionné :) + * @param conteneur des cases à vérifier + */ +function verifierActivitésTaux(conteneur) +{ + let nbChoix = 0; + // parcourir les cases à cocher + for (let idCase of conteneur.querySelectorAll("input[type=checkbox]")) + { + if (idCase.checked) { + ++nbChoix; + // vérifier qu'un radio de la même ligne est sélectionné + let ligneCorrecte = false; + // trouver la ligne englobante + let ligne = idCase.closest("li"); + for (let idRadio of ligne.querySelectorAll('input[type=radio]')) + { + if (idRadio.checked) { ligneCorrecte = true; break; } + } + if (! ligneCorrecte) { + alert("Erreur : il faut sélectionner un taux de réduction dans chaque ligne cochée"); + return false; + } + } + } + if (nbChoix == 0) { + alert("Erreur : il faut sélectionner au moins une ligne"); + } + return nbChoix != 0; +} + +/** + * vérifier qu'un taux a été sélectionné dans le conteneur paramètre + */ +function verifierTaux(conteneur) +{ + return verifierCases(conteneur, 'radio', "un taux de réduction"); +} + +// ------------------------------------------------------------------------ +// actions sur la config +// ------------------------------------------------------------------------ + /** * vérifier les données saisies dans le formulaire de configuration -*/ -function verifierConfig( - formulaire, - divArticles, - divTauxReduc -) + */ +function verifierConfig(divArticles, divTauxReduc) { // articles - if (! aumoinsun(divArticles, "un article")) { return false; } + if (! verifierCases(divArticles, "checkbox", "au moins un article")) { return false; } // taux de réduction - if (! aumoinsun(divTauxReduc, "un taux de réduction")) { return false; } + if (! verifierCases(divTauxReduc, "checkbox", "au moins un taux de réduction")) { return false; } // Nom, fonction, signature @@ -293,3 +267,21 @@ function verifierConfig( // alert("Erreur : il faut sélectionner au moins un versement"); return true; } + +/** + * Vérifier qu'au moins une case est cochée dans le conteneur + * @param conteneur + * @param type de case à vérifier (radio, checkbox) + * @param message à afficher si erreur + */ +function verifierCases(conteneur, type, message) +{ + let selecteur = "input[type=" + type + "]"; + let listeCheck = conteneur.querySelectorAll(selecteur); + for (let elem of listeCheck) + { + if (elem.checked) { return true; } + } + alert("Erreur : il faut sélectionner " + message); + return false; +} diff --git a/www/admin/style.css b/www/admin/style.css index 9aad3a5..eb52c78 100644 --- a/www/admin/style.css +++ b/www/admin/style.css @@ -1,7 +1,11 @@ -/* liste des versements */ +/* + * liste des versements + */ + div.pair { background-color: rgba(var(--gSecondColor), 0.15); } + fieldset.versements { margin-bottom : 0; @@ -9,102 +13,128 @@ fieldset.versements -webkit-border-radius:8px; border-radius:8px; } + div span { padding-left : 0.5em; padding-right : 0.5em; } + td.montant { text-align : right; } + span.montant { width : 5em; text-align : right; } + span.total { font-weight : bold; } + summary.activite { margin-bottom : 0.5em; } + summary.personne { margin-bottom : 0.5em; padding-top : 0; padding-bottom : 0; } + div.activite { background-color: rgba(var(--gSecondColor), 0.3); } + div.personne { font-weight : normal; background-color: rgba(var(--gSecondColor), 0.25); } + h3.activite { display : inline; } + p.activite { margin-left : 2.5em; } -#signature -{ - padding : 1em 0.5em 0 0.5em; - max-width: 300px; - max-height: 150px; -} -div.explications ul -{ - list-style : initial; -} - -div.actions -{ - display : inline; -} input.check_global { margin : 0.2em 0.5em; } -dl#menu -{ - min-width : 40em; - width : 50%; -} + div.versements { margin-left : 4em; display: flex; flex-wrap: wrap; } -/* config */ + +/* + * page d'accueil +*/ + +div.explications ul +{ + list-style : initial; +} + +dl#menu +{ + min-width : 40em; + width : 50%; +} + +/* + * configuration + */ + +#signature +{ + padding : 1em 0.5em 0 0.5em; + max-width: 300px; + max-height: 120px; +} + +div.actions +{ + display : inline; +} + dl.config { padding-bottom : 1ex; padding-right : 1em; } -div#articles_cgi + +div#articles_cgi, div#config_nom_fonction, div#numero_recus { display: flex; } + div.article { margin-right : 3em; } +/* div#config_nom_fonction { display: flex; } + div#numero_recus { display:flex; -/* align-items: last baseline;*/ } +*/ div.champnom { display : flex; @@ -130,7 +160,8 @@ ul.reduction span.radio-btn } input#f_prefixe { - max-width : 8em; + width : 8em; + min-width : 8em; } input#f_valeur_init {