fusion branche dev

FossilOrigin-Name: e18f048e309427c850c2181cb8445fac5b4ae7d6b8f64b103247337b311e8cb3
This commit is contained in:
engel 2022-04-04 10:12:06 +00:00
commit 181ebc1cf8
19 changed files with 770 additions and 827 deletions

View File

@ -2,7 +2,7 @@ nom="Reçus fiscaux"
description="Génération de reçus fiscaux pour les dons des membres" description="Génération de reçus fiscaux pour les dons des membres"
auteur="jce" auteur="jce"
url="https://git.roflcopter.fr/lesanges/recus-fiscaux-garradin" url="https://git.roflcopter.fr/lesanges/recus-fiscaux-garradin"
version="0.6.2" version="0.6.4"
menu=1 menu=1
config=1 config=1
min_version="1.1" min_version="1.1"

View File

@ -13,7 +13,7 @@ class Personne
public $codePostal; public $codePostal;
public $ville; public $ville;
public $courriel; public $courriel;
public $versements; // tableau des versements totaux par activité/tarif public $versements; // versements par taux de réduction
public function __construct( public function __construct(
$id, $id,
@ -30,7 +30,7 @@ class Personne
$this->codePostal = $codePostal; $this->codePostal = $codePostal;
$this->ville = $ville; $this->ville = $ville;
$this->courriel = $courriel; $this->courriel = $courriel;
$this->versements = array(); $this->versements = array(); // clé = tarif, valeur = montant
} }
/** /**
@ -49,24 +49,21 @@ class Personne
/** /**
* ajouter un versement * ajouter un versement
* @param $idActivite
* @param $idTarif
* @param $montant
* @param $tauxReduction * @param $tauxReduction
* @param $montant
*/ */
public function ajouterVersement( public function ajouterVersement(
$idActivite, $tauxReduction,
$idTarif, $montant
$montant,
$tauxReduction
) )
{ {
$this->versements[] = if (array_key_exists($tauxReduction, $this->versements))
new Versement( {
$idActivite, $this->versements[$tauxReduction] += $montant;
$idTarif, }
$montant, else
$tauxReduction {
); $this->versements[$tauxReduction] = $montant;
}
} }
} }

View File

@ -1,257 +0,0 @@
<?php
namespace Garradin\Plugin\RecusFiscaux;
// génération du formulaire
class RecusHTML
{
private $nomAsso;
private $adresseAsso;
private $logoAsso;
private $objetAsso;
private $nomResponsable;
private $fonctionResponsable;
private $villeAsso;
private $articlesCGI;
private $signature;
/**
* initialize global data
*/
function __construct($nomAsso,
$adresseAsso,
$logoAsso,
$objetAsso,
$nomResponsable,
$fonctionResponsable,
$villeAsso,
$articlesCGI,
$signature)
{
$this->nomAsso = $nomAsso;
$this->adresseAsso = $adresseAsso;
$this->logoAsso = $logoAsso;
$this->objetAsso = $objetAsso;
$this->nomResponsable = $nomResponsable;
$this->fonctionResponsable = $fonctionResponsable;
$this->villeAsso = $villeAsso;
$this->signature = $signature;
$this->articlesCGI = $articlesCGI;
$this->html = $this->entete();
}
function get()
{
return $this->html;
}
// imprimer le reçu
function imprimer_recu($annee_recu,
$numero,
$nom,
$lesMontants,
$adresse,
$code_postal,
$ville)
{
ob_start();
echo <<<FDD
<div id="numRecu">
<p class="important">Reçu numéro {$annee_recu}/{$numero}</p>
</div>
</div>
<div class="cartouche" id="beneficiaire">
<h3 class="rubrique">Bénéficiaire des versements</h3>
<p class="important">Association « {$this->nomAsso} »<br />
{$this->adresseAsso}<br />
<span class="titre">Objet : </span><span class="libelle">{$this->objetAsso}</span></p>
</div>
<div class="cartouche" id="donateur">
<h3 class="rubrique">Donateur</h3>
<p>{$nom}<br />
{$adresse}<br />
{$code_postal} {$ville}</p>
</div>
<div class="cartouche" id="versements">
<p>Le bénéficiaire reconnaît avoir reçu au titre des dons et versements ouvrant droit à réduction d'impôt :</p>
<ul>
FDD;
foreach ($lesMontants as $taux => $montant)
{
$this->imprimer_montant($montant,
Utils::getLigneReduction($taux));
}
echo "</ul>\n";
$this->imprimer_description("Date des versements :",
"année {$annee_recu}");
$this->imprimer_description("Nature du don : ",
"Numéraire");
$this->imprimer_description("Mode de versement : ",
"chèque et/ou virement");
// articles du CGI
$nbArticles = count($this->articlesCGI);
if ($nbArticles == 1)
{
echo "<p>Le bénéficiaire certifie sur lhonneur que les dons et versements quil reçoit ouvrent droit à la réduction d'impôt prévue à larticle ";
printf("%s du code général des impôts</p>\n", $this->articlesCGI[0]);
}
else if ($nbArticles > 1)
{
echo "<p>Le bénéficiaire certifie sur lhonneur que les dons et versements quil reçoit ouvrent droit à la réduction d'impôt prévue aux articles ";
for ($i = 0; $i < $nbArticles; ++$i) {
printf("%s", $this->articlesCGI[$i]);
if ($i < $nbArticles - 2) {
echo ", ";
}
else if ($i == $nbArticles - 2) {
echo " et ";
}
}
echo " du code général des impôts</p>\n";
}
echo "</div>\n";
// cartouche final
$date = date("j/m/Y");
echo <<<FDD
<div class="cartouche" id="final">
<p>{$this->villeAsso} le {$date}<br />
<img id="signature" src="$this->signature" />
</p>
<div>
<span id="nom">$this->nomResponsable</span><br />
<span id="fonction">$this->fonctionResponsable</span>
</div>
</div>
</body>
</html>
FDD;
$this->html .= ob_get_clean();
}
// imprimer un libellé précédé de son titre en gras
function imprimer_description($titre, $libelle)
{
echo <<<FDD
<p><span class="titre">{$titre}</span><span class="libelle"> {$libelle}</span></p>
FDD;
}
// imprimer le montant du versement et un libellé
function imprimer_montant($montant, $libelle = "")
{
$valeur = number_format($montant, 2, ',', '');
echo "<li>la somme de <b>***{$valeur}*** euros</b>";
if ($libelle != "") {
echo " ({$libelle})";
}
echo "</li>\n";
}
protected function entete()
{
ob_start();
echo <<<FDD
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<style>
@page
{
size: A4 portrait;
margin: 1cm;
}
body
{
font-family: Serif;
font-size: 11pt;
background-color: white;
width : 19cm;
}
#entete
{
position : relative;
}
#logo
{
position : fixed;
max-width : 4cm;
max-height : 4cm;
}
#titre
{
position : fixed;
margin : 0 4.5cm 0 4.5cm;
top : 1cm;
text-align : center;
font-size : 14pt;
font-weight: bold;
}
#articles
{
position : fixed;
margin : 0 4.5cm 0 4.5cm; /* idem titre */
top : 6em;
text-align : center;
}
#numRecu
{
position : relative;
text-align : right;
top : 8em;
right: 1em;
}
#beneficiaire, #donateur, #versements, #final
{
position : relative;
top : 9em;
}
#versements
{
position : relative;
top : 9em;
border-top: 1px solid rgb(0, 0, 128);
border-bottom: 1px solid rgb(0, 0, 128);
}
.rubrique
{
background-color : rgb(200, 200, 250);
padding : 2mm;
}
.titre, .important
{
font-weight:bold;
}
.libelle
{
font-weight: normal;
}
#signature
{
display: block;
max-width : 7cm;
max-height : 4cm;
margin: 0 auto;
padding-bottom : 2mm;
}
</style>
</head>
<body>
<div class="cartouche" id="entete">
<img id="logo" src="$this->logoAsso" />
<p id="titre">Reçu au titre des dons à certains organismes d'intérêt général</p>
<p id="articles">Articles 200, 238 bis et 978 du code général des impôts</p>
FDD;
return ob_get_clean();
}
}

View File

@ -39,8 +39,40 @@ class Utils
return $db->get($sql); return $db->get($sql);
} }
/**
* @return versements correspondants à l'année donnée
* @param $annee
* @param array $champsNom : liste non vide des champs de nom/prénom
*/
public static function getVersementsPersonnes($annee, $champsNom)
{
$db = DB::getInstance();
$tri = Utils::combinerTri($champsNom);
$sql = sprintf(
'SELECT
membres.id as idUser,
acc_transactions_lines.credit as versement,
acc_transactions.date
FROM acc_transactions_users
INNER JOIN membres on acc_transactions_users.id_user = membres.id
INNER JOIN acc_transactions on acc_transactions_users.id_transaction = acc_transactions.id
INNER JOIN services_users on acc_transactions_users.id_service_user = services_users.id
INNER JOIN acc_transactions_lines on acc_transactions_lines.id_transaction = acc_transactions.id
WHERE
(strftime(%s, acc_transactions.date) = "%d"
AND
acc_transactions_lines.credit > 0)
ORDER by %s, acc_transactions.date',
'"%Y"',
$annee,
$tri
);
return $db->get($sql);
}
/** /**
* @return versements correspondants à l'année et aux tarifs donnés * @return versements correspondants à l'année et aux tarifs donnés
* triés par tarif, nom, date
* @param $annee * @param $annee
* @param array $tarifs * @param array $tarifs
* @param array $champsNom : liste non vide des champs de nom/prénom * @param array $champsNom : liste non vide des champs de nom/prénom
@ -76,6 +108,42 @@ class Utils
return $db->get($sql); return $db->get($sql);
} }
/**
* @return versements correspondants à l'année et aux comptes donnés
* @param $annee
* @param array $comptes
* @param array $champsNom : liste non vide des champs de nom/prénom
*/
public static function getVersementsComptes($annee, $comptes, $champsNom)
{
$db = DB::getInstance();
$tri = Utils::combinerTri($champsNom);
$sql = sprintf(
'SELECT
acc_accounts.code as compte,
membres.id as idUser,
acc_transactions_lines.credit as versement,
acc_transactions.date
FROM acc_transactions_users
INNER JOIN membres on acc_transactions_users.id_user = membres.id
INNER JOIN acc_transactions on acc_transactions_users.id_transaction = acc_transactions.id
INNER JOIN services_users on acc_transactions_users.id_service_user = services_users.id
INNER JOIN acc_transactions_lines on acc_transactions_lines.id_transaction = acc_transactions.id
WHERE
(strftime(%s, acc_transactions.date) = "%d"
AND
acc_accounts.%s
AND
acc_transactions_lines.credit > 0)
ORDER by acc_accounts.code, %s, acc_transactions.date',
'"%Y"',
$annee,
$db->where('code', $comptes),
$tri
);
return $db->get($sql);
}
/** /**
* Versements totaux par personne pour une année donnée * Versements totaux par personne pour une année donnée
* @param année * @param année
@ -142,7 +210,7 @@ class Utils
* @param $annee * @param $annee
* @param array $champsNom : champs qui définissent le nom et le prénom d'une personne * @param array $champsNom : champs qui définissent le nom et le prénom d'une personne
*/ */
public static function getDonateurs($annee, $champsNom) public static function getDonateurs($annee, $champsNom) : array
{ {
// concaténer les champs nom/prénoms pour la sélection // concaténer les champs nom/prénoms pour la sélection
$nom = 'trim(' . Utils::combinerChamps($champsNom) . ') as nom,'; $nom = 'trim(' . Utils::combinerChamps($champsNom) . ') as nom,';
@ -174,7 +242,16 @@ class Utils
GROUP by membres.id GROUP by membres.id
ORDER by " . $tri . " COLLATE U_NOCASE ORDER by " . $tri . " COLLATE U_NOCASE
"; ";
return DB::getInstance()->get($sql, $annee); $donateurs = array();
foreach (DB::getInstance()->iterate($sql, $annee) as $personne)
{
$donateurs[$personne->idUser] = new Personne($personne->idUser,
$personne->nom,
$personne->adresse,
$personne->codePostal,
$personne->ville);
}
return $donateurs;
} }
public static function getLignesReduction($lesTaux) public static function getLignesReduction($lesTaux)
@ -219,32 +296,11 @@ class Utils
); );
} }
/**
* @return nom de l'association
*/
public static function getNomAsso() {
return DB::getInstance()->first(
"SELECT value
FROM config
WHERE key = 'nom_asso'"
)->value;
}
/**
* @return adresse de l'association
*/
public static function getAdresseAsso() {
return DB::getInstance()->first(
"SELECT value
FROM config
WHERE key = 'adresse_asso'"
)->value;
}
/** /**
* @return liste des années fiscales * @return liste des années fiscales
*/ */
public static function getAnneesFiscales() { public static function getAnneesFiscales() : array
{
$rows = DB::getInstance()->get( $rows = DB::getInstance()->get(
"SELECT strftime('%Y', start_date) as annee "SELECT strftime('%Y', start_date) as annee
FROM acc_years FROM acc_years
@ -277,7 +333,7 @@ class Utils
{ {
if (stristr($title, 'nom')) if (stristr($title, 'nom'))
{ {
// retenir les champs dont le titre contient le term 'nom' // retenir les champs dont le titre contient le terme 'nom'
// est-il présent dans la config du plugin ? // est-il présent dans la config du plugin ?
if (! array_key_exists($name, $champsNom)) if (! array_key_exists($name, $champsNom))
{ {

View File

@ -5,8 +5,8 @@
<nav class="tabs"> <nav class="tabs">
<ul> <ul>
<li{if $current_nav == 'index'} class="current"{/if}><a href="{plugin_url}">Accueil</a></li> <li{if $current_nav == 'index'} class="current"{/if}><a href="{plugin_url}">Accueil</a></li>
<li{if $current_nav == 'personne'} class="current"{/if}><a href="{plugin_url file="versements_personnes.php"}">Versements totaux par personne</a></li> <li{if $current_nav == 'personne'} class="current"{/if}><a href="{plugin_url file="action.php?action=personne"}">Versements par personne</a></li>
<li{if $current_nav == 'versements'} class="current"{/if}><a href="{plugin_url file="versements_activites.php"}">Versements par activité et tarif</a></li> <li{if $current_nav == 'versements'} class="current"{/if}><a href="{plugin_url file="action.php?action=activite"}">Versements par activité et tarif</a></li>
{if $session->canAccess($session::SECTION_ACCOUNTING, $session::ACCESS_WRITE)} {if $session->canAccess($session::SECTION_ACCOUNTING, $session::ACCESS_WRITE)}
<li{if $current_nav == 'config'} class="current"{/if}><a href="{plugin_url file="config.php"}">Configuration</a></li> <li{if $current_nav == 'config'} class="current"{/if}><a href="{plugin_url file="config.php"}">Configuration</a></li>
{/if} {/if}

View File

@ -20,15 +20,15 @@
{* <legend>Choisir une des méthodes</legend> *} {* <legend>Choisir une des méthodes</legend> *}
<dl> <dl>
<dd class="radio-btn"> <dd class="radio-btn">
<input type="radio" id="radio_tous_versements" name="choix_versements" value="tous_versements" <input type="radio" id="radio_versements_personne" name="choix_versements" value="personne"
onclick="afficherMasquer(this.form, '.tous', '.activites');" /> onclick="choixMethodeGeneration(this.form, 'personne', '.tous', '.activites');" />
<label for="radio_tous_versements"> <label for="radio_versements_personne">
<div class="explications"> <div class="explications">
<h5> <h5>
Tous les versements des membres font l'objet d'un reçu, sans Tous les versements des membres font l'objet d'un reçu, sans
tenir compte des activités et tarifs tenir compte des activités et tarifs
</h5> </h5>
<p>Choisissez cette option si vous voulez sélectionner tous les versements d'une, plusieurs <p>Choisissez cette option si vous voulez sélectionner les versements d'une, plusieurs
ou toutes les personnes</p> ou toutes les personnes</p>
</div> </div>
</label> </label>
@ -36,7 +36,7 @@
<dd class="radio-btn"> <dd class="radio-btn">
<input type="radio" id="radio_versements_activites" name="choix_versements" <input type="radio" id="radio_versements_activites" name="choix_versements"
value="versements_activites" onclick="afficherMasquer(this.form, '.activites', '.tous');" /> value="activite" onclick="choixMethodeGeneration(this.form, 'activite', '.activites', '.tous');" />
<label for="radio_versements_activites"> <label for="radio_versements_activites">
<div class="explications"> <div class="explications">
<h5> <h5>
@ -55,6 +55,7 @@
</fieldset> </fieldset>
</div> </div>
{* Toutes les personnes *}
<div id="div_taux_reduc" class="tous hidden"> <div id="div_taux_reduc" class="tous hidden">
<h2>Choisir le taux de réduction</h2> <h2>Choisir le taux de réduction</h2>
<fieldset> <fieldset>
@ -87,6 +88,7 @@
</p> </p>
</div> </div>
{* Activités et tarifs *}
<div id="liste_activites_tarifs" class="activites hidden"> <div id="liste_activites_tarifs" class="activites hidden">
<h2>Choisir les activités et tarifs concernés par les reçus ainsi que le taux de réduction</h2> <h2>Choisir les activités et tarifs concernés par les reçus ainsi que le taux de réduction</h2>
<fieldset> <fieldset>

141
templates/recu.skel Normal file
View File

@ -0,0 +1,141 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
<head>
<meta charset="utf-8" />
<style>
@page
{
size: A4 portrait;
margin: 1cm;
}
body
{
font-family: Serif;
font-size: 11pt;
background-color: white;
width : 19cm;
}
#entete
{
position : relative;
}
#logo
{
position : fixed;
max-width : 4cm;
max-height : 4cm;
}
#titre
{
position : fixed;
margin : 0 4.5cm 0 4.5cm;
top : 1cm;
text-align : center;
font-size : 14pt;
font-weight: bold;
}
#articles
{
position : fixed;
margin : 0 4.5cm 0 4.5cm; /* idem titre */
top : 6em;
text-align : center;
}
#numRecu
{
position : relative;
text-align : right;
top : 8em;
right: 1em;
}
#beneficiaire, #donateur, #versements, #final
{
position : relative;
top : 9em;
}
#versements
{
position : relative;
top : 9em;
border-top: 1px solid rgb(0, 0, 128);
border-bottom: 1px solid rgb(0, 0, 128);
}
.rubrique
{
background-color : rgb(200, 200, 250);
padding : 2mm;
}
.titre, .important
{
font-weight:bold;
}
.libelle
{
font-weight: normal;
}
#signature
{
display: block;
max-width : 7cm;
max-height : 4cm;
margin: 0 auto;
padding-bottom : 2mm;
}
</style>
</head>
<body>
<div class="cartouche" id="entete">
<img id="logo" src="{{$logo_asso}}" />
<p id="titre">Reçu au titre des dons à certains organismes d'intérêt général</p>
<p id="articles">Articles 200, 238 bis et 978 du code général des impôts</p>
<div id="numRecu">
<p class="important">Reçu numéro {{$annee_recu}}/{{$numero}}</p>
</div>
</div>
<div class="cartouche" id="beneficiaire">
<h3 class="rubrique">Bénéficiaire des versements</h3>
<p class="important">Association « {{$config.nom_asso}} »<br />
{{$config.adresse_asso}}<br />
<span class="titre">Objet : </span><span class="libelle">{{$objet_asso}}</span></p>
</div>
<div class="cartouche" id="donateur">
<h3 class="rubrique">Donateur</h3>
<p>{{$nom}}<br />
{{$adresse}}<br />
{{$code_postal}} {{$ville}}</p>
</div>
<div class="cartouche" id="versements">
<p>Le bénéficiaire reconnaît avoir reçu au titre des dons et versements ouvrant droit à réduction d'impôt :</p>
<ul>
{{#versements}}
<li>
la somme de <b>***{{$montant|raw|money}}*** euros</b>
{{if $libelle != ""}}
({{$libelle}})
{{/if}}
</li>
{{/versements}}
</ul>
{{#informations}}
<p><span class="titre">{{$titre}}</span><span class="libelle"> {{$libelle}}</span></p>
{{/informations}}
<p>Le bénéficiaire certifie sur lhonneur que les dons et versements quil reçoit ouvrent droit à la réduction d'impôt prévue {{$texteArticles}} du code général des impôts.</p>
</div>
<div class="cartouche" id="final">
<p>{{$ville_asso}} le {{$date}}<br />
<img id="signature" src="{{$signature}}" />
</p>
<div>
<span id="nom">{{$nom_responsable}}</span><br />
<span id="fonction">{{$fonction_responsable}}</span>
</div>
</div>
</body>
</html>

View File

@ -3,17 +3,14 @@
<h2>Versements par activité et tarif</h2> <h2>Versements par activité et tarif</h2>
<div class="year-header noprint"> <fieldset class="noprint">
<button type="button" data-icon="↓" class="icn-btn" id="open_details">Déplier toutes les activités</button>
<button type="button" data-icon="↑" class="icn-btn" id="close_details">Replier toutes les activités</button>
</div>
<form method="post" id="versements_activites" action="generer_activites.php">
<fieldset class="versements" id="versements_global">
<input type="checkbox" class="check_global" id="check_global" onclick="cocherDecocherTout(check_global)" /> <input type="checkbox" class="check_global" id="check_global" onclick="cocherDecocherTout(check_global)" />
<label for="check_global">Cliquer pour cocher toutes les lignes</label> <label for="check_global">Cliquer pour cocher toutes les lignes</label>
</fieldset> <button type="button" data-icon="↑" class="icn-btn" id="close_details_activite" onclick="montrerMasquerDetails(this.id, 'details.activite', 'toutes les activités')">Replier toutes les activités</button>
<button type="button" data-icon="↑" class="icn-btn" id="close_details_personne" onclick="montrerMasquerDetails(this.id, 'details.personne', 'toutes les personnes')">Replier toutes les personnes</button>
</fieldset>
<form method="post" id="versements_activites" action="generer_recus.php?type=activite">
{* Itération sur les versements *} {* Itération sur les versements *}
{foreach from=$lesVersements key="i" item="versement"} {foreach from=$lesVersements key="i" item="versement"}
@ -24,59 +21,46 @@
$personneCourante = $versement->idUser; $personneCourante = $versement->idUser;
?> ?>
{afficher_debut_tarif versement=$versement} {afficher_debut_tarif versement=$versement}
{afficher_debut_personne versement=$versement} {afficher_debut_personne user=$personneCourante idVersement="%s_%s"|args:$tarifCourant,$personneCourante}
{afficher_versement versement=$versement rang=$i} {afficher_versement versement=$versement idVersement="%s_%s"|args:$tarifCourant,$personneCourante rang=$i}
{else} {else}
{* autre versement *} {* autre versement *}
{if $versement.idTarif != $tarifCourant} {if $versement.idTarif != $tarifCourant}
{* changement de tarif *} {* changement de tarif *}
</fieldset> {* fin versements d'une personne *} </fieldset> {* fin versements d'une personne *}
</details> </details> {* fin versements d'une personne *}
</details> {* fin tarif *}
<?php <?php
$tarifCourant = $versement->idTarif; $tarifCourant = $versement->idTarif;
$personneCourante = $versement->idUser; $personneCourante = $versement->idUser;
?> ?>
{afficher_debut_tarif versement=$versement} {afficher_debut_tarif versement=$versement}
{afficher_debut_personne versement=$versement} {afficher_debut_personne user=$personneCourante idVersement="%s_%s"|args:$tarifCourant,$personneCourante}
{afficher_versement versement=$versement rang=$i} {afficher_versement versement=$versement idVersement="%s_%s"|args:$tarifCourant,$personneCourante rang=$i}
{elseif $versement.idUser != $personneCourante} {elseif $versement.idUser != $personneCourante}
{* changement de personne *} {* changement de personne *}
</fieldset> </fieldset>
</details>
<?php <?php
$personneCourante = $versement->idUser; $personneCourante = $versement->idUser;
?> ?>
{afficher_debut_personne versement=$versement} {afficher_debut_personne user=$personneCourante idVersement="%s_%s"|args:$tarifCourant,$personneCourante}
{afficher_versement versement=$versement rang=$i} {afficher_versement versement=$versement idVersement="%s_%s"|args:$tarifCourant,$personneCourante rang=$i}
{else} {else}
{* même personne *} {* même personne *}
{afficher_versement versement=$versement rang=$i} {afficher_versement versement=$versement idVersement="%s_%s"|args:$tarifCourant,$personneCourante rang=$i}
{/if} {/if}
{/if} {/if}
{/foreach} {* Itération sur les versements *} {/foreach} {* Itération sur les versements *}
</fieldset> </fieldset> {* fin versements d'une personne *}
</details> </details> {* fin versements d'une personne *}
</details> {* fin tarif *}
<input type="submit" value="Générer les reçus" onclick="return verifierChoix(this.form)"> <input type="submit" value="Générer les reçus" onclick="return verifierChoix(this.form)">
</form> </form>
{* scripts pour cases à cocher *} {* scripts divers *}
<script src="script.js"></script> <script src="script.js"></script>
{literal}
<script type="text/javascript">
// ouvrir/fermer les détails
document.querySelector('#open_details').onclick = () => {
document.querySelectorAll('details').forEach((e) => {
e.setAttribute('open', 'open');
});
};
document.querySelector('#close_details').onclick = () => {
document.querySelectorAll('details').forEach((e) => {
e.removeAttribute('open');
});
};
</script>
{/literal}
<!-- footer --> <!-- footer -->
{include file="admin/_foot.tpl"} {include file="admin/_foot.tpl"}

View File

@ -1,50 +1,47 @@
<!-- nav bar --> <!-- nav bar -->
{include file="%s/templates/_nav.tpl"|args:$plugin_root current_nav="personne"} {include file="%s/templates/_nav.tpl"|args:$plugin_root current_nav="personne"}
<h2>Versements totaux par personne</h2> <h2>Versements par personne</h2>
<form method="post" action="generer_personnes.php"> <fieldset class="noprint">
<input type="checkbox" class="check_global" id="check_global"
onclick="cocherDecocherToutesLesPersonnes(check_global)" />
<label for="check_global">Cliquer pour cocher toutes les lignes</label>
<button type="button" data-icon="↑" class="icn-btn" id="close_details_personne" onclick="montrerMasquerDetails(this.id, 'details.personne', 'toutes les personnes')">Replier toutes les personnes</button>
</fieldset>
<form method="post" id="versements_personnes" action="generer_recus.php?type=personne">
{* Itération sur les personnes *} {* Itération sur les personnes *}
<table class="list"> {foreach from=$lesVersements key="i" item="versement"}
<thead> {if $i == 0}
<tr> {* 1ère personne *}
<th class="check"> <?php
<input type="checkbox" title="Tout cocher / décocher" id="f_all" /> $personneCourante = $versement->idUser;
<label for="f_all"></label> ?>
</th> {afficher_debut_personne user=$personneCourante idVersement=$personneCourante}
<th>Id</th> {afficher_versement versement=$versement idVersement=$personneCourante rang=$i}
<th>Nom Prénom</th> {elseif $versement.idUser != $personneCourante}
<th>Montant</th> {* changement de personne *}
<th>Adresse</th> </fieldset>
<th>Code postal</th> </details>
<th>Ville</th> <?php
</tr> $personneCourante = $versement->idUser;
</thead> ?>
<tbody> {afficher_debut_personne user=$personneCourante idVersement=$personneCourante}
{foreach from=$lesVersementsTotaux key=rang item="versement"} {afficher_versement versement=$versement idVersement=$personneCourante rang=$i}
<tr> {else}
<td class="check"> {* même personne *}
{input {afficher_versement versement=$versement idVersement=$personneCourante rang=$i}
type="checkbox" {/if}
name="selected[]" {/foreach} {* Itération sur les personnes *}
value=$rang} </fieldset>
</td> </details>
<td>{$versement.idUser}</td>
<td>{$lesDonateurs[$versement.idUser]->nomPrenom}</td>
<td class="montant">{$versement.versement|raw|money}</td>
<td>{$lesDonateurs[$versement.idUser]->adresse}</td>
<td>{$lesDonateurs[$versement.idUser]->codePostal}</td>
<td>{$lesDonateurs[$versement.idUser]->ville}</td>
</tr>
{/foreach}
</tbody>
</table>
<input type="submit" value="Générer les reçus" onclick="return verifierChoix(this.form)"> <input type="submit" value="Générer les reçus" onclick="return verifierChoix(this.form)">
</form> </form>
{* scripts pour cases à cocher *} {* scripts divers *}
<script src="script.js"></script> <script src="script.js"></script>
<!-- footer --> <!-- footer -->

View File

@ -1,16 +0,0 @@
<?php
namespace Garradin;
$old_version = $plugin->getInfos('version');
if (version_compare($old_version, '0.6.2', '<'))
{
// changement de nom de la configuration des champs nom
$champsNom = $plugin->getConfig('nomChamps');
if (null !== $champsNom)
{
$plugin->setConfig('champsNom', $champsNom);
$plugin->setConfig('nomChamps', null);
}
}

View File

@ -2,7 +2,138 @@
namespace Garradin; namespace Garradin;
if ($_POST['choix_versements'] == 'tous_versements') { use Garradin\Plugin\RecusFiscaux\Utils;
// ------------------------------------------------------------------------
// opérations communes
// ------------------------------------------------------------------------
// vérifier si l'année a bien été sélectionnée au préalable
$_SESSION['annee_recu'] = f('annee_recu');
if (! isset($_SESSION['annee_recu']) || $_SESSION['annee_recu'] == "") {
\Garradin\Utils::redirect(PLUGIN_URL . 'index.php');
}
// champs pour le nom et prénom
$confNoms = Utils::getChampsNom($config, $plugin);
uasort($confNoms, function ($a, $b)
{
return $a->position - $b->position;
});
$champsNom = array();
foreach ($confNoms as $nom => $champ)
{
if ($champ->position != 0) { $champsNom[] = $nom; }
}
// membres donateurs
$_SESSION['membresDonateurs'] = Utils::getDonateurs($_SESSION['annee_recu'],
$champsNom);
// ------------------------------------------------------------------------
// fonctions pour l'affichage
// ------------------------------------------------------------------------
// afficher les informations d'une activité et d'un tarif
$tpl->register_function('afficher_debut_tarif', function ($params)
{
$versement = $params['versement'];
$idTarif = $versement->idTarif;
$tarif = $_SESSION['lesTarifs'][$idTarif];
$idActivite = $tarif->idActivite;
$activite = $_SESSION['lesActivites'][$idActivite];
$out = '<details class="activite" open="open">
<summary class="activite">';
$out .= sprintf('
<h3>Activité « %s »</h3>', $activite->label);
if (!empty($activite->description)) {
$out .= sprintf('
<h4>%s</h4>', $activite->description);
}
$out .= sprintf('
<h4>tarif « %s »', $tarif->label);
if ($tarif->montant > 0) {
$out .= sprintf(' montant : %.2f €', $tarif->montant/100);
} else {
$out .= ' montant : libre';
}
$out .= '</h4>
</summary>';
return $out;
});
// Afficher les informations d'une personne
$tpl->register_function('afficher_debut_personne', function ($params)
{
$idUser = $params['user'];
$idVersement = $params['idVersement'];
$personne = $_SESSION['membresDonateurs'][$idUser];
$out = '<details class="personne" open="open">
<summary class="personne">';
$out .= sprintf('<h4 class="personne">Versements de %s : <span class="total" id="total_%s">0,00 €</span></h4>',
$personne->nomPrenom,
$idVersement);
$out .= '</summary>';
$out .= sprintf('
<fieldset class="versements" id="versements_%s">',
$idVersement);
$out .= sprintf('
<input type="checkbox" id="check_%s"',
$idVersement);
$out .= sprintf(' onclick="cocherDecocherPersonne(check_%s, total_%s)" />',
$idVersement,
$idVersement);
$out .= sprintf('
<label for="check_%s">Cliquer pour cocher toutes les lignes</label>',
$idVersement);
$out .= '<br />
<hr>';
return $out;
});
// afficher un versement
$tpl->register_function('afficher_versement', function ($params)
{
$versement = $params['versement'];
$idVersement = $params['idVersement'];
$rang = $params['rang'];
$out = '<div class="';
$out .= ($rang%2==0) ? 'pair">' : 'impair">';
$out .= sprintf('
<input type="checkbox"
class="check_%s"
id="check_%s_%s"
name="selected[]"
value="%s"
onclick="cocherDecocherVersement(check_%s_%s, total_%s)" />',
$idVersement,
$idVersement, $rang,
$rang,
$idVersement, $rang, $idVersement
);
$out .= sprintf('
<label for="check_%s_%s"></label>',
$idVersement, $rang
);
$out .= sprintf('
<span class="montant">%.2f</span>',
$versement->versement/100
);
$out .= sprintf('
<span>%s</span>
</div>',
date_format(date_create($versement->date),"d/m/Y"));
return $out;
});
// ------------------------------------------------------------------------
// aiguillage
// ------------------------------------------------------------------------
if ($_GET['action'] == 'personne') {
require('versements_personnes.php'); require('versements_personnes.php');
} else { } else {
require('versements_activites.php'); require('versements_activites.php');

View File

@ -1,6 +1,7 @@
<?php <?php
namespace Garradin; namespace Garradin;
use Garradin\Files\Files; use Garradin\Files\Files;
use Garradin\Entities\Files\File; use Garradin\Entities\Files\File;
use Garradin\Plugin\RecusFiscaux\Utils; use Garradin\Plugin\RecusFiscaux\Utils;

View File

@ -1,147 +0,0 @@
<?php
namespace Garradin;
use Garradin\Files\Files;
use Garradin\Entities\Files\File;
use Garradin\Plugin\RecusFiscaux\RecusHTML;
use Garradin\Plugin\RecusFiscaux\Utils;
use Garradin\Plugin\RecusFiscaux\Personne;
// récupérer les lignes sélectionnées
$lesLignes = f('selected');
// filtrer les versements sélectionnés
$versementsSelectionnes = array();
foreach ($lesLignes as $ligne) {
$versementsSelectionnes[] = $_SESSION['lesVersements'][$ligne];
}
// cumuler les versements d'une personne
$totalPersonnes = cumulerVersements($versementsSelectionnes);
// informations pour les reçus
$nomAsso = $config->get('nom_asso');
$adresseAsso = $config->get('adresse_asso');
$signature =
(null !== $plugin->getConfig('signature')) ?
Files::get($plugin->getConfig('signature'))->fullpath() :
"";
// logo
$logo_file = Files::get(File::CONTEXT_CONFIG . '/logo.png');
$logoAsso =
(null !== $logo_file) ?
Files::get($logo_file->path)->fullpath() :
"";
// articles du CGI
$articlesCGI = array();
foreach ($plugin->getConfig('articlesCGI') as $article)
{
if ($article->valeur == 1) {
$articlesCGI[] = $article->titre;
}
}
$listeFichiers = array(); // fichiers pdf générés
foreach ($totalPersonnes as $idPersonne => $personne)
{
// générer un fichier par reçu
$html = new RecusHTML(
$nomAsso,
$adresseAsso,
$logoAsso,
$plugin->getConfig('objet_asso'),
$plugin->getConfig('nom_responsable'),
$plugin->getConfig('fonction_responsable'),
$plugin->getConfig('ville_asso'),
$articlesCGI,
$signature
);
// extraire les montants des versements
$lesMontants = array();
foreach ($personne->versements as $versement)
{
if (array_key_exists($versement->tauxReduction, $lesMontants)) {
$lesMontants[$versement->tauxReduction] += $versement->montant;
}
else {
$lesMontants[$versement->tauxReduction] = $versement->montant;
}
}
$html->imprimer_recu(
$_SESSION['annee_recu'],
$personne->id,
$personne->nomPrenom,
$lesMontants,
$personne->adresse,
$personne->codePostal,
$personne->ville
);
// fabriquer le fichier PDF
$nomPDF = \Garradin\Utils::filePDF($html->get());
// changer le nom du fichier
$nom = str_replace(' ', '_', $personne->nomPrenom);
$nom = str_replace("'", "", $nom);
$nomFichier = "recu_" . $_SESSION['annee_recu'] . "_" . $nom . ".pdf";
rename($nomPDF, $nomFichier);
// ajouter le nom du fichier à la liste pour mettre dans une archive
$listeFichiers[] = $nomFichier;
}
// faire une archive zip
$fichierZip = Utils::makeArchive(
$listeFichiers,
$_SESSION['annee_recu'],
PLUGIN_ROOT . "/zip"
);
/**
* Cumuler les versements de chaque personne par tarif
* @param tableau des versements triés par idTarif, idUser, date
* @return tableau des versements cumulés : id => Personne
*/
function cumulerVersements($versements)
{
$totalPersonnes = array();
$idTarif_courant = -1;
$idPersonne_courant = -1;
$totalVersements = 0;
foreach ($versements as $ligne)
{
if (
$ligne->idTarif != $idTarif_courant ||
$ligne->idUser != $idPersonne_courant
)
{
if ($idTarif_courant != -1) {
$totalPersonnes[$idPersonne_courant]->ajouterVersement(
$_SESSION['lesTarifs'][$idTarif_courant]->idActivite,
$idTarif_courant,
$totalVersements/100,
$_SESSION['tauxSelectionnes'][$idTarif_courant]
);
}
$idTarif_courant = $ligne->idTarif;
$idPersonne_courant = $ligne->idUser;
$totalVersements = $ligne->versement;
// créer les infos de la personne, sauf si elle est déjà présente
if (!array_key_exists($idPersonne_courant, $totalPersonnes))
{
$totalPersonnes["$idPersonne_courant"] = $_SESSION['membresDonateurs'][$ligne->idUser]->clone();
}
} else {
// cumuler versements
$totalVersements += $ligne->versement;
}
}
// et le dernier
$totalPersonnes[$idPersonne_courant]->ajouterVersement(
$_SESSION['lesTarifs'][$idTarif_courant]->idActivite,
$idTarif_courant,
$totalVersements/100,
$_SESSION['tauxSelectionnes'][$idTarif_courant]
);
return $totalPersonnes;
}

View File

@ -1,91 +0,0 @@
<?php
namespace Garradin;
use Garradin\Files\Files;
use Garradin\Entities\Files\File;
use Garradin\Plugin\RecusFiscaux\RecusHTML;
use Garradin\Plugin\RecusFiscaux\Utils;
use Garradin\Plugin\RecusFiscaux\Personne;
// récupérer les lignes sélectionnées
$lesLignes = f('selected');
// filtrer les versements sélectionnés
$versementsSelectionnes = array();
foreach ($lesLignes as $ligne) {
$versementsSelectionnes[] = $_SESSION['lesVersementsTotaux'][$ligne];
}
// informations pour les reçus
$nomAsso = $config->get('nom_asso');
$adresseAsso = $config->get('adresse_asso');
$signature =
(null !== $plugin->getConfig('signature'))
?
Files::get($plugin->getConfig('signature'))->fullpath()
:
"";
// logo
$logo_file = Files::get(File::CONTEXT_CONFIG . '/logo.png');
$logoAsso =
(null !== $logo_file)
?
Files::get($logo_file->path)->fullpath()
:
"";
// articles du CGI
$articlesCGI = array();
foreach ($plugin->getConfig('articlesCGI') as $article)
{
if ($article->valeur == 1) {
$articlesCGI[] = $article->titre;
}
}
$listeFichiers = array(); // fichiers pdf générés
foreach ($versementsSelectionnes as $ligne)
{
// générer un fichier par reçu
$html = new RecusHTML(
$nomAsso,
$adresseAsso,
$logoAsso,
$plugin->getConfig('objet_asso'),
$plugin->getConfig('nom_responsable'),
$plugin->getConfig('fonction_responsable'),
$plugin->getConfig('ville_asso'),
$articlesCGI,
$signature
);
// extraire les montants des versements
$lesMontants[$_SESSION['taux_reduction']] = $ligne->versement/100;
$personne = $_SESSION['membresDonateurs'][$ligne->idUser];
$html->imprimer_recu(
$_SESSION['annee_recu'],
$personne->id,
$personne->nomPrenom,
$lesMontants,
$personne->adresse,
$personne->codePostal,
$personne->ville
);
// fabriquer le fichier PDF
$nomPDF = \Garradin\Utils::filePDF($html->get());
// changer le nom du fichier
$nom = str_replace(' ', '_', $personne->nomPrenom);
$nom = str_replace("'", "", $nom);
$nomFichier = "recu_" . $_SESSION['annee_recu'] . "_" . $nom . ".pdf";
rename($nomPDF, $nomFichier);
// ajouter le nom du fichier à la liste pour mettre dans une archive
$listeFichiers[] = $nomFichier;
}
// faire une archive zip
$fichierZip = Utils::makeArchive(
$listeFichiers,
$_SESSION['annee_recu'],
PLUGIN_ROOT . "/zip"
);

232
www/admin/generer_recus.php Normal file
View File

@ -0,0 +1,232 @@
<?php
namespace Garradin;
use Garradin\Files\Files;
use Garradin\Entities\Files\File;
use Garradin\UserTemplate\UserTemplate;
//use Garradin\Plugin\RecusFiscaux\RecusHTML;
use Garradin\Plugin\RecusFiscaux\Utils;
use Garradin\Plugin\RecusFiscaux\Personne;
// signature
$signature =
(null !== $plugin->getConfig('signature')) ?
Files::get($plugin->getConfig('signature'))->fullpath() :
"";
// logo
$logo_file = Files::get(File::CONTEXT_CONFIG . '/logo.png');
$logo_asso =
(null !== $logo_file) ?
Files::get($logo_file->path)->fullpath() :
"";
// articles du CGI
$articlesCGI = array();
foreach ($plugin->getConfig('articlesCGI') as $article)
{
if ($article->valeur == 1) {
$articlesCGI[] = $article->titre;
}
}
$nbArticles = count($articlesCGI);
if ($nbArticles == 1)
{
$texteArticles = 'à larticle ' . $articlesCGI[0];
}
elseif ($nbArticles > 1)
{
$texteArticles = 'aux articles ';
for ($i = 0; $i < $nbArticles; ++$i) {
$texteArticles .= $articlesCGI[$i];
if ($i < $nbArticles - 2) {
$texteArticles .= ", ";
}
else if ($i == $nbArticles - 2) {
$texteArticles .= " et ";
}
}
}
// filtrer les versements sélectionnés
$lesLignes = f('selected');
$versementsSelectionnes = array();
foreach ($lesLignes as $ligne) {
$versementsSelectionnes[] = $_SESSION['lesVersements'][$ligne];
}
// cumuler les versements
if ($_GET['type'] == 'personne')
{
$totalPersonnes = cumulerVersementsPersonne($versementsSelectionnes);
}
elseif ($_GET['type'] == 'activite')
{
$totalPersonnes = cumulerVersementsTarif($versementsSelectionnes);
}
// générer les reçus
$listeFichiersPDF = array();
foreach ($totalPersonnes as $idPersonne => $personne)
{
$tpl = new UserTemplate();
$tpl->setSource(PLUGIN_ROOT . '/templates/recu.skel');
$tpl->assignArray(compact('signature', 'logo_asso', 'texteArticles'));
$tpl->assign('objet_asso', $plugin->getConfig('objet_asso'));
$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"));
// les versements
$tpl->registerSection('versements',
function () use($personne)
{
foreach ($personne->versements as $taux => $montant)
{
$ligne['montant'] = $montant;
$ligne['libelle'] = Utils::getLigneReduction($taux);
yield $ligne;
}
});
// mentions complémentaires
$donnees = array(
'Date des versements : ' => "année " . $_SESSION['annee_recu'],
'Nature du don : ' => "Numéraire",
'Mode de versement : ' => "chèque et/ou virement"
);
$infos = array();
foreach ($donnees as $titre => $libelle)
{
$elem = new \stdClass();
$elem->titre = $titre;
$elem->libelle = $libelle;
$infos[] = $elem;
}
$tpl->registerSection('informations',
function () use ($infos)
{
foreach ($infos as $elem)
{
yield (array) $elem;
}
});
// fabriquer le fichier PDF
$result = $tpl->fetch();
$nomPDF = \Garradin\Utils::filePDF($result);
// changer le nom du fichier
$nom = str_replace(' ', '_', $personne->nomPrenom);
$nom = str_replace("'", "", $nom);
$nomFichier = "recu_" . $_SESSION['annee_recu'] . "_" . $nom . ".pdf";
rename($nomPDF, $nomFichier);
// ajouter le nom du fichier à la liste pour mettre dans une archive
$listeFichiersPDF[] = $nomFichier;
}
// faire une archive zip
$fichierZip = Utils::makeArchive(
$listeFichiersPDF,
$_SESSION['annee_recu'],
PLUGIN_ROOT . "/zip"
);
/**
* Cumuler les versements de chaque personne
* @param tableau des versements triés par idUser, date
* @return tableau des versements cumulés : id => Personne
*/
function cumulerVersementsPersonne($versements)
{
$totalPersonnes = array();
$idPersonneCourant = -1;
$totalVersements = 0;
foreach ($versements as $ligne)
{
if ($ligne->idUser != $idPersonneCourant)
{
// changement de personne
if ($idPersonneCourant != -1)
{
$totalPersonnes[$idPersonneCourant]->ajouterVersement(
$_SESSION['taux_reduction'],
$totalVersements
);
}
$idPersonneCourant = $ligne->idUser;
$totalVersements = $ligne->versement;
// créer les infos de la personne, sauf si elle est déjà présente
if (!array_key_exists($idPersonneCourant, $totalPersonnes))
{
$totalPersonnes["$idPersonneCourant"] = $_SESSION['membresDonateurs'][$ligne->idUser]->clone();
}
} else {
// cumuler versements
$totalVersements += $ligne->versement;
}
}
// et le dernier
$totalPersonnes[$idPersonneCourant]->ajouterVersement(
$_SESSION['taux_reduction'],
$totalVersements
);
return $totalPersonnes;
}
/**
* Cumuler les versements de chaque personne par tarif
* @param tableau des versements triés par idTarif, idUser, date
* @return tableau des versements cumulés : id => Personne
*/
function cumulerVersementsTarif($versements)
{
$totalPersonnes = array();
$idTarifCourant = -1;
$idPersonneCourant = -1;
$totalVersements = 0;
foreach ($versements as $ligne)
{
if (
$ligne->idTarif != $idTarifCourant ||
$ligne->idUser != $idPersonneCourant
)
{
if ($idTarifCourant != -1)
{
// changement de tarif ou de personne
$totalPersonnes[$idPersonneCourant]->ajouterVersement(
$_SESSION['tauxSelectionnes'][$idTarifCourant],
$totalVersements
);
}
$idTarifCourant = $ligne->idTarif;
$idPersonneCourant = $ligne->idUser;
$totalVersements = $ligne->versement;
// créer les infos de la personne, sauf si elle est déjà présente
if (!array_key_exists($idPersonneCourant, $totalPersonnes))
{
$totalPersonnes["$idPersonneCourant"] = $_SESSION['membresDonateurs'][$ligne->idUser]->clone();
}
} else {
// cumuler versements
$totalVersements += $ligne->versement;
}
}
// et le dernier
$totalPersonnes[$idPersonneCourant]->ajouterVersement(
$_SESSION['tauxSelectionnes'][$idTarifCourant],
$totalVersements
);
return $totalPersonnes;
}

View File

@ -5,66 +5,71 @@
*/ */
function cocherDecocherTout(idCaseGlobale) function cocherDecocherTout(idCaseGlobale)
{ {
// chercher le formulaire englobant
var formulaire = idCaseGlobale.closest("form");
// itérer sur la liste des éléments détails : 1 par couple <activité, tarif> // itérer sur la liste des éléments détails : 1 par couple <activité, tarif>
var lesDetails = formulaire.querySelectorAll("details"); var lesDetails = document.querySelectorAll("details.activite");
for (var i = 0; i < lesDetails.length; ++i) { for (var i = 0; i < lesDetails.length; ++i)
{
// itérer sur les personnes // itérer sur les personnes
var lesH3 = lesDetails[i].querySelectorAll("h3.personne"); var lesPersonnes = lesDetails[i].querySelectorAll("h4.personne");
for (var j = 0; j < lesH3.length; ++j) { cocherDecocherLesPersonnes(idCaseGlobale, lesPersonnes);
}
// changer le message
changerMessage(idCaseGlobale.nextElementSibling, idCaseGlobale);
}
/**
* idem dans le cas des versements des personnes
*/
function cocherDecocherToutesLesPersonnes(idCaseGlobale)
{
var lesPersonnes = document.querySelectorAll("h4.personne");
cocherDecocherLesPersonnes(idCaseGlobale, lesPersonnes);
changerMessage(idCaseGlobale.nextElementSibling, idCaseGlobale);
}
function cocherDecocherLesPersonnes(idCaseGlobale, lesPersonnes)
{
for (var j = 0; j < lesPersonnes.length; ++j)
{
// trouver l'élément total de la personne // trouver l'élément total de la personne
var idTotal = lesH3[j].querySelector("span"); var idTotal = lesPersonnes[j].querySelector("span");
// puis la case à cocher // puis la case à cocher
var fieldset = lesH3[j].nextElementSibling; var fieldset = lesPersonnes[j].closest("details").querySelector("fieldset");
var idCase = fieldset.querySelector("input"); var idCase = fieldset.querySelector("input");
idCase.checked = idCaseGlobale.checked; idCase.checked = idCaseGlobale.checked;
// puis traiter toutes les cases de la personne // puis traiter toutes les cases de la personne
cocherDecocherPersonne(idCase, idTotal); cocherDecocherPersonne(idCase, idTotal, false);
}
}
// changer le message
var message = idCaseGlobale.nextElementSibling;
if (idCaseGlobale.checked) {
message.innerHTML = "Cliquer pour dé-cocher toutes les lignes";
} else {
message.innerHTML = "Cliquer pour cocher toutes les lignes";
} }
} }
/** /**
* Fonction appelée quand on ()coche la case d'une personne * Fonction appelée quand on ()coche la case globale d'une personne
* - ()sélectionner toutes les cases à cocher * - ()sélectionner toutes les cases à cocher
* - faire le total des cases cochées et l'afficher * - faire le total des cases cochées et l'afficher
* *
* @param id de la case qui a été cochée * @param id de la case qui a été cochée
* @param id de l'élément afficher le total * @param id de l'élément afficher le total
* @param changer : vrai, s'il faut changer le message de la personne
*/ */
function cocherDecocherPersonne(idCase, idTotal) function cocherDecocherPersonne(idCase, idTotal, changer = true)
{ {
// chercher le fieldset englobant // chercher le fieldset des versements
var fieldset = idCase.closest("fieldset"); var fieldset = idCase.closest("details").querySelector("fieldset");
var listeCases = fieldset.querySelectorAll("input[type=checkbox]"); var listeCases = fieldset.querySelectorAll("input[type=checkbox]");
for (var i = 1; i < listeCases.length; ++i) for (var i = 0; i < listeCases.length; ++i)
{ {
listeCases[i].checked = idCase.checked; listeCases[i].checked = idCase.checked;
} }
// changer le message
var message = idCase.nextElementSibling;
if (idCase.checked) {
message.innerHTML = "Cliquer pour dé-cocher toutes les lignes";
} else {
message.innerHTML = "Cliquer pour cocher toutes les lignes";
}
// calculer et afficher le total // calculer et afficher le total
var listeMontants = fieldset.querySelectorAll("span.montant"); var listeMontants = fieldset.querySelectorAll("span.montant");
calculerTotal(listeCases, listeMontants, idTotal); calculerTotal(listeCases, listeMontants, idTotal);
// changer le message
if (changer) { changerMessage(idCase.nextElementSibling, idCase); }
} }
/** /**
* Fonction appelée quand on ()coche la case d'un versement * Fonction appelée quand on ()coche la case d'un versement
* - ()sélectionner cette case (?) * Faire le total des cases cochées et l'afficher
* - faire le total des cases cochées et l'afficher
* *
* @param id de la case qui a été cochée * @param id de la case qui a été cochée
* @param id de l'élément afficher le total * @param id de l'élément afficher le total
@ -98,6 +103,18 @@ function calculerTotal(listeCases, listeMontants, idTotal)
minimumFractionDigits: 2}); minimumFractionDigits: 2});
} }
/**
* changer le message en fonction de l'état coché de la case
*/
function changerMessage(message, idCase)
{
if (idCase.checked) {
message.innerHTML = "Cliquer pour dé-cocher toutes les lignes";
} else {
message.innerHTML = "Cliquer pour cocher toutes les lignes";
}
}
/** /**
* fonction appelée lors de la validation du formulaire * fonction appelée lors de la validation du formulaire
* @return vrai si au moins un choix a été fait * @return vrai si au moins un choix a été fait
@ -122,9 +139,12 @@ function verifierChoix(formulaire)
return ok; return ok;
} }
/** function choixMethodeGeneration(formulaire, action, nomClasse1, nomClasse2)
* fonction appelée pour afficher et masquer des portions de formulaire {
*/ formulaire.setAttribute('action', 'action.php?action=' + action);
afficherMasquer(formulaire, nomClasse1, nomClasse2);
}
function afficherMasquer(formulaire, nomClasse1, nomClasse2) function afficherMasquer(formulaire, nomClasse1, nomClasse2)
{ {
for (var elem of formulaire.querySelectorAll(nomClasse1)) { for (var elem of formulaire.querySelectorAll(nomClasse1)) {
@ -178,3 +198,30 @@ function verifierRadio(idElem)
alert("Erreur : il faut sélectionner un taux de réduction"); alert("Erreur : il faut sélectionner un taux de réduction");
return false; return false;
} }
function montrerMasquerDetails(idElem, classe, texte)
{
var lesDetails = document.querySelectorAll(classe);
if (lesDetails.length > 0)
{
var leBouton = document.getElementById(idElem);
if (leBouton.textContent.startsWith('Replier'))
{
// masquer
lesDetails.forEach((e) => {
e.removeAttribute('open');
});
leBouton.textContent = "Déplier " + texte;
leBouton.setAttribute('data-icon', '↓');
}
else
{
// montrer
lesDetails.forEach((e) => {
e.setAttribute('open', 'open');
});
leBouton.textContent = "Replier " + texte;
leBouton.setAttribute('data-icon', '↑');
}
}
}

View File

@ -22,11 +22,21 @@ span.montant {
width : 5em; width : 5em;
text-align : right; text-align : right;
} }
span.total
{
font-weight : bold;
}
summary.activite { summary.activite {
background: rgba(var(--gMainColor), 0.25); background: rgba(var(--gMainColor), 0.25);
margin-bottom : 0.5em;
} }
h3.personne { summary.personne
background: rgba(var(--gSecondColor), 0.35); {
margin-bottom : 0.5em;
}
h3.personne, h4.personne {
font-weight : normal;
background: rgba(var(--gSecondColor), 0.15);
} }
#signature #signature
{ {
@ -48,3 +58,7 @@ div.actions
{ {
display : inline; display : inline;
} }
input.check_global
{
margin : 0.2em 0.5em;
}

View File

@ -7,24 +7,6 @@ use Garradin\Plugin\RecusFiscaux\Personne;
use Garradin\Plugin\RecusFiscaux\Tarif; use Garradin\Plugin\RecusFiscaux\Tarif;
use Garradin\Plugin\RecusFiscaux\Utils; use Garradin\Plugin\RecusFiscaux\Utils;
// vérifier si l'année a bien été sélectionnée au préalable
$_SESSION['annee_recu'] = f('annee_recu');
if (! isset($_SESSION['annee_recu']) || $_SESSION['annee_recu'] == "") {
\Garradin\Utils::redirect(PLUGIN_URL . 'index.php');
}
// champs pour le nom et prénom
$confNoms = Utils::getChampsNom($config, $plugin);
uasort($confNoms, function ($a, $b)
{
return $a->position - $b->position;
});
$champsNom = array();
foreach ($confNoms as $nom => $champ)
{
if ($champ->position != 0) { $champsNom[] = $nom; }
}
// récupérer les infos du formulaire // récupérer les infos du formulaire
$tarifsSelectionnes = f('tarifs') ?: []; $tarifsSelectionnes = f('tarifs') ?: [];
@ -56,104 +38,6 @@ $_SESSION['lesVersements'] = Utils::getVersementsTarifs($_SESSION['annee_recu'],
$tarifsSelectionnes, $tarifsSelectionnes,
$champsNom); $champsNom);
// membres donateurs
$versementsMembres = Utils::getDonateurs($_SESSION['annee_recu'],
$champsNom);
$membresDonateurs = array();
foreach ($versementsMembres as $versement) {
$membresDonateurs[$versement->idUser] = new Personne($versement->idUser,
$versement->nom,
$versement->adresse,
$versement->codePostal,
$versement->ville);
}
$_SESSION['membresDonateurs'] = $membresDonateurs;
// ------------------------------------------------------------------------
// fonctions pour l'affichage
// afficher les informations d'une activité et d'un tarif
$tpl->register_function('afficher_debut_tarif', function ($params)
{
$versement = $params['versement'];
$idTarif = $versement->idTarif;
$tarif = $_SESSION['lesTarifs'][$idTarif];
$idActivite = $tarif->idActivite;
$activite = $_SESSION['lesActivites'][$idActivite];
$out = '<details open="open">
<summary class="activite">';
$out .= sprintf('
<h3>Activité « %s »</h3>', $activite->label);
if (!empty($activite->description)) {
$out .= sprintf('
<h4>%s</h4>', $activite->description);
}
$out .= sprintf('
<h4>tarif « %s »', $tarif->label);
if ($tarif->montant > 0) {
$out .= sprintf(' montant : %.2f €', $tarif->montant/100);
} else {
$out .= ' montant : libre';
}
$out .= '</h4>
</summary>';
return $out;
});
// afficher les informations d'une personne
$tpl->register_function('afficher_debut_personne', function ($params)
{
$versement = $params['versement'];
$idUser = $versement->idUser;
$personne = $_SESSION['membresDonateurs'][$idUser];
$idVersement = $versement->idTarif . "_" . $versement->idUser;
$out = sprintf('<h3 class="personne">Versements de %s : <span id="total_%s">0,00 €</span></h3>',
$personne->nomPrenom,
$idVersement);
$out .= sprintf('
<fieldset class="versements" id="versements_%s">',
$idVersement);
$out .= sprintf('
<input type="checkbox" class="check_%s" id="check_%s"',
$idVersement,
$idVersement);
$out .= sprintf(' onclick="cocherDecocherPersonne(check_%s, total_%s)" />',
$idVersement,
$idVersement);
$out .= sprintf('
<label for="check_%s">Cliquer pour cocher toutes les lignes</label>',
$idVersement);
$out .= '<br />
<hr>';
return $out;
});
// afficher un versement
$tpl->register_function('afficher_versement', function ($params)
{
$versement = $params['versement'];
$rang = $params['rang'];
$idVersement = $versement->idTarif . "_" . $versement->idUser;
$out = '<div class="';
$out .= ($rang%2==0) ? 'pair">' : 'impair">';
$out .= sprintf('
<input type="checkbox" class="check_%s" id="check_%s_%s"
name="selected[]" value="%s"
onclick="cocherDecocherVersement(check_%s_%s, total_%s)" />
<label for="check_%s_%s"></label>
<span class="montant">%.2f</span>
<span>%s</span>
</div>',
$idVersement, $idVersement,
$rang, $rang,
$idVersement, $rang, $idVersement, $idVersement, $rang,
$versement->versement/100,
date_format(date_create($versement->date),"d/m/Y"));
return $out;
});
// ------------------------------------------------------------------------
// préparation de l'affichage // préparation de l'affichage
$tpl->assign('lesActivites', $lesActivites); $tpl->assign('lesActivites', $lesActivites);
$tpl->assign('lesTarifs', $lesTarifs); $tpl->assign('lesTarifs', $lesTarifs);

View File

@ -5,46 +5,14 @@ namespace Garradin;
use Garradin\Plugin\RecusFiscaux\Personne; use Garradin\Plugin\RecusFiscaux\Personne;
use Garradin\Plugin\RecusFiscaux\Utils; use Garradin\Plugin\RecusFiscaux\Utils;
// vérifier si l'année a bien été sélectionnée au préalable
$_SESSION['annee_recu'] = f('annee_recu');
if (! isset($_SESSION['annee_recu']) || $_SESSION['annee_recu'] == "") {
\Garradin\Utils::redirect(PLUGIN_URL . 'index.php');
}
$_SESSION['taux_reduction'] = $_POST['taux_reduction']; $_SESSION['taux_reduction'] = $_POST['taux_reduction'];
// champs pour le nom et prénom // versements par personne
$confNoms = Utils::getChampsNom($config, $plugin); $_SESSION['lesVersements'] = Utils::getVersementsPersonnes($_SESSION['annee_recu'],
uasort($confNoms, function ($a, $b)
{
return $a->position - $b->position;
});
$champsNom = array();
foreach ($confNoms as $nom => $champ)
{
if ($champ->position != 0) { $champsNom[] = $nom; }
}
// versements totaux par personne
$_SESSION['lesVersementsTotaux'] =
Utils::getVersementsTotaux($_SESSION['annee_recu'],
$champsNom); $champsNom);
// membres donateurs
$versementsMembres = Utils::getDonateurs($_SESSION['annee_recu'],
$champsNom);
$membresDonateurs = array();
foreach ($versementsMembres as $versement) {
$membresDonateurs[$versement->idUser] = new Personne($versement->idUser,
$versement->nom,
$versement->adresse,
$versement->codePostal,
$versement->ville);
}
$_SESSION['membresDonateurs'] = $membresDonateurs;
// préparation de l'affichage // préparation de l'affichage
$tpl->assign('lesVersementsTotaux', $_SESSION['lesVersementsTotaux']); $tpl->assign('lesVersements', $_SESSION['lesVersements']);
$tpl->assign('lesDonateurs', $membresDonateurs);
$tpl->assign('plugin_css', ['style.css']); $tpl->assign('plugin_css', ['style.css']);
// envoyer au template // envoyer au template