Réorganistion fichiers ; ajout gestion versements totaux par personne ;

montants gérés en centimes

FossilOrigin-Name: e1e11bdd898e24dc30d3a6f150e9679ed2d6bf915ac828cdfbb830b118651b8f
This commit is contained in:
engel 2022-01-26 11:12:42 +00:00
parent c72996befe
commit 46a88944fc
11 changed files with 308 additions and 127 deletions

View File

@ -33,7 +33,7 @@ class Services
services_fees.id as idTarif, services_fees.id as idTarif,
services_fees.label as titreTarif, services_fees.label as titreTarif,
services_fees.description as descTarif, services_fees.description as descTarif,
printf(\"%.2f\", services_fees.amount/100) as montantTarif services_fees.amount as montantTarif
FROM services_fees FROM services_fees
WHERE services_fees.id_service = ?", WHERE services_fees.id_service = ?",
$activite $activite
@ -92,9 +92,9 @@ class Services
services_fees.id as idTarif, services_fees.id as idTarif,
services.label as activite, services.label as activite,
services_fees.label as tarif, services_fees.label as tarif,
printf(\"%8.2f\", services_fees.amount/100) as montant, services_fees.amount as montant,
acc_transactions_users.id_user as idUser, acc_transactions_users.id_user as idUser,
printf(\"%8.2f\", acc_transactions_lines.credit/100) as versement, acc_transactions_lines.credit as versement,
membres.id as idMembre, membres.id as idMembre,
membres.nom as nom, membres.nom as nom,
membres.adresse as adresse, membres.adresse as adresse,
@ -132,9 +132,9 @@ class Services
services_fees.id as idTarif, services_fees.id as idTarif,
services.label as activite, services.label as activite,
services_fees.label as tarif, services_fees.label as tarif,
printf(\"%8.2f\", services_fees.amount/100) as montant, services_fees.amount as montant,
acc_transactions_users.id_user as idUser, acc_transactions_users.id_user as idUser,
printf(\"%8.2f\", acc_transactions_lines.credit/100) as versement, acc_transactions_lines.credit as versement,
membres.nom as nom, membres.nom as nom,
acc_transactions.date as Date, acc_transactions.date as Date,
acc_transactions_users.id_transaction as idTrans acc_transactions_users.id_transaction as idTrans
@ -157,6 +157,40 @@ class Services
return DB::getInstance()->get($sql, $annee, $activite, $tarif); return DB::getInstance()->get($sql, $annee, $activite, $tarif);
} }
/**
* liste du total de versements par personne pour une année donnée
* @param année
*/
public static function getVersementsTotaux($annee) {
$sql =
"SELECT
acc_transactions_users.id_user as id,
membres.nom as nom,
sum(acc_transactions_lines.credit) AS montant,
membres.adresse as adresse,
membres.code_postal as codePostal,
membres.ville as ville
FROM
acc_transactions_users,
membres,
acc_transactions
INNER JOIN acc_transactions_lines
ON acc_transactions_lines.id_transaction = acc_transactions.id
WHERE (
strftime('%Y', acc_transactions.date) = ?
AND
acc_transactions_lines.credit > 0
AND
acc_transactions_users.id_transaction = acc_transactions.id
AND
acc_transactions_users.id_user = membres.id
)
GROUP by acc_transactions_users.id_user
ORDER by membres.nom COLLATE NOCASE;
";
return DB::getInstance()->get($sql, $annee);
}
/** /**
* @return nom de l'association * @return nom de l'association
*/ */

11
templates/_nav.tpl Normal file
View File

@ -0,0 +1,11 @@
<!-- title -->
{include file="admin/_head.tpl" title="%s"|args:$plugin.nom current="plugin_%s"|args:$plugin.id}
<!-- nav bar -->
<nav class="tabs">
<ul>
<li{if $current_nav == 'index'} class="current"{/if}><a href="{plugin_url}">Versements totaux par personne</a></li>
<li{if $current_nav == 'versements'} class="current"{/if}><a href="{plugin_url file="versements.php"}">Tous les versements</a></li>
<li{if $current_nav == 'activites'} class="current"{/if}><a href="{plugin_url file="activites.php"}">Activités et tarifs</a></li>
</ul>
</nav>

31
templates/activites.tpl Normal file
View File

@ -0,0 +1,31 @@
<!-- nav bar -->
{include file="%s/templates/_nav.tpl"|args:$plugin_root current_nav="activites"}
<h2>Liste des activités, cotisations et comptes associés</h2>
<table class="list">
<thead>
<tr>
<th>Nom</th>
<th>Description</th>
<th>Tarif</th>
<th>Description</th>
<th>N° Compte</th>
<th>Nom Compte</th>
</tr>
</thead>
<tbody>
{foreach from=$activitesTarifsComptes item="activite"}
<tr>
<td>{$activite.label}</td>
<td>{$activite.descService}</td>
<td>{$activite.tarif}</td>
<td>{$activite.descTarif}</td>
<td>{$activite.numero_cpt}</td>
<td>{$activite.nom_cpt}</td>
</tr>
{/foreach}
</tbody>
</table>
<!-- footer -->
{include file="admin/_foot.tpl"}

View File

@ -1,91 +1,48 @@
{include file="admin/_head.tpl" title="%s"|args:$plugin.nom current="plugin_%s"|args:$plugin.id} <!-- nav bar -->
{include file="%s/templates/_nav.tpl"|args:$plugin_root current_nav="index"}
<h2>Liste des versements par activité et tarif</h2> <h2>Liste des versements totaux par personne</h2>
{* TODO : vérifier le détail de ce div *} <form method="post" action="" class="memberList">
<div class="year-header 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" action="action.php" class="memberList"> {* Itération sur les perssonnes *}
<table class="list">
<fieldset class="versements" id="versements_global"> <thead class="userOrder">
<tr>
<th class="check">
<input <input
type="checkbox" type="checkbox"
class="check_global" title="Tout cocher / décocher"
id="check_global" id="f_all" />
onclick="cocherDecocherTout(check_global)" /> <label for="f_all"></label>
<label for="check_global">Cliquer pour cocher toutes les lignes</label> </th>
</fieldset> <th>Id</th>
<th>Nom Prénom</th>
{* Itération sur les activités *} <th>Montant</th>
{foreach from=$listeParActiviteEtTarif item="activite"} <th>Adresse</th>
<th>Ville</th>
{* Itération sur les tarifs de l'activité *} <th>Code postal</th>
{foreach from=$activite->tarifs item="tarif"} </tr>
</thead>
<details open="open"> <tbody>
<summary class="activite"> {foreach from=$lesVersementsTotaux item="versement"}
<h3>Activité « {$activite->label} »</h3> <tr>
{if !empty($activite->description)} <td class="check">
<h4>{$activite->description}</h4> {input
{/if}
<h4>tarif « {$tarif->titreTarif} », montant : {if $tarif->montantTarif > 0}{$tarif->montantTarif}
{else}libre
{/if}
</h4>
</summary>
{*
Itération sur les versements d'un tarif d'une activité
présentation : une table pour les versements d'une personne
*}
<?php $currentUser = -1; $firstUser = true; ?>
{foreach from=$lesVersements key="rang" item="versement"}
{if $versement.idActivite == $activite->id &&
$versement.idTarif == $tarif->idTarif}
{if $versement.idUser != $currentUser}
{* changement de personne *}
{if $firstUser}
<?php $firstUser = false; ?>
{else}
{* fermer le tableau précédent *}
</fieldset>
{/if}
{* Afficher les infos de la personne *}
<?php $idVersements = $versement->idTarif."_".$versement->idUser; ?>
<h3 class="personne">Versements de {$versement.nom} : <span id="total_{$idVersements}">0,00 €</span></h3>
<fieldset class="versements" id="versements_{$idVersements}">
<input
type="checkbox" type="checkbox"
class="check_{$idVersements}"
id="check_{$idVersements}"
onclick="cocherDecocherPersonne(check_{$idVersements}, total_{$idVersements})" />
<label for="check_{$idVersements}">Cliquer pour cocher toutes les lignes</label>
<br />
<hr>
<?php $currentUser = $versement->idUser; ?>
{/if}
{* afficher les infos du versement de la personne*}
<div {if $rang%2==0}class="pair"{else}class="impair"{/if}>
<input
type="checkbox"
class="check_{$idVersements}"
id="check_{$idVersements}_{$rang}"
name="selected[]" name="selected[]"
value={$rang} value=$versement.id}
onclick="cocherDecocherVersement(check_{$idVersements}_{$rang}, total_{$idVersements})" /> </td>
<label for=check_{$idVersements}_{$rang}></label> <td>{$versement.id}</td>
<span class="montant">{$versement.versement}</span> <td>{$versement.nom}</td>
<span>{$versement.date|date_format:"%d/%m/%Y"}</span> <td class="montant">{$versement.montant|raw|money}</td>
</div> <td>{$versement.adresse}</td>
{/if} <td>{$versement.ville}</td>
{/foreach} {* Itération sur les versements *} <td>{$versement.codePostal}</td>
</fieldset> </tr>
</details> {/foreach}
{/foreach} {* Itération sur les tarifs de l'activité *} </tbody>
{/foreach} {* Itération sur les activités *} </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>
@ -93,21 +50,5 @@
{* scripts pour cases à cocher *} {* scripts pour cases à cocher *}
<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"}

114
templates/versements.tpl Normal file
View File

@ -0,0 +1,114 @@
<!-- nav bar -->
{include file="%s/templates/_nav.tpl"|args:$plugin_root current_nav="versements"}
<h2>Liste des versements par activité et tarif</h2>
{* TODO : vérifier le détail de ce div *}
<div class="year-header 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" action="action.php" class="memberList">
<fieldset class="versements" id="versements_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>
</fieldset>
{* Itération sur les activités *}
{foreach from=$listeParActiviteEtTarif item="activite"}
{* Itération sur les tarifs de l'activité *}
{foreach from=$activite->tarifs item="tarif"}
<details open="open">
<summary class="activite">
<h3>Activité « {$activite->label} »</h3>
{if !empty($activite->description)}
<h4>{$activite->description}</h4>
{/if}
<h4>tarif « {$tarif->titreTarif} », montant : {if $tarif->montantTarif > 0}{$tarif->montantTarif}
{else}libre
{/if}
</h4>
</summary>
{*
Itération sur les versements d'un tarif d'une activité
présentation : une table pour les versements d'une personne
*}
<?php $currentUser = -1; $firstUser = true; ?>
{foreach from=$lesVersements key="rang" item="versement"}
{if $versement.idActivite == $activite->id &&
$versement.idTarif == $tarif->idTarif}
{if $versement.idUser != $currentUser}
{* changement de personne *}
{if $firstUser}
<?php $firstUser = false; ?>
{else}
{* fermer le tableau précédent *}
</fieldset>
{/if}
{* Afficher les infos de la personne *}
<?php $idVersements = $versement->idTarif."_".$versement->idUser; ?>
<h3 class="personne">Versements de {$versement.nom} : <span id="total_{$idVersements}">0,00 €</span></h3>
<fieldset class="versements" id="versements_{$idVersements}">
<input
type="checkbox"
class="check_{$idVersements}"
id="check_{$idVersements}"
onclick="cocherDecocherPersonne(check_{$idVersements}, total_{$idVersements})" />
<label for="check_{$idVersements}">Cliquer pour cocher toutes les lignes</label>
<br />
<hr>
<?php $currentUser = $versement->idUser; ?>
{/if}
{* afficher les infos du versement de la personne*}
<div {if $rang%2==0}class="pair"{else}class="impair"{/if}>
<input
type="checkbox"
class="check_{$idVersements}"
id="check_{$idVersements}_{$rang}"
name="selected[]"
value={$rang}
onclick="cocherDecocherVersement(check_{$idVersements}_{$rang}, total_{$idVersements})" />
<label for=check_{$idVersements}_{$rang}></label>
<span class="montant">{$versement.versement|raw|money}</span>
<span>{$versement.date|date_format:"%d/%m/%Y"}</span>
</div>
{/if}
{/foreach} {* Itération sur les versements *}
</fieldset>
</details>
{/foreach} {* Itération sur les tarifs de l'activité *}
{/foreach} {* Itération sur les activités *}
<input type="submit" value="Générer les reçus" onclick="return verifierChoix(this.form)">
</form>
{* scripts pour cases à cocher *}
<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 -->
{include file="admin/_foot.tpl"}

View File

@ -50,7 +50,7 @@ foreach ($totalPersonnes as $idPersonne => $personne) {
} }
$pdf->imprimer_recu( $pdf->imprimer_recu(
$annee_recu, $annee_recu,
$personne->id, //$num_recu, $personne->id,
$personne->nomPrenom, $personne->nomPrenom,
$lesMontants, $lesMontants,
$personne->adresse, $personne->adresse,
@ -103,7 +103,7 @@ function cumulerVersements($versements)
$totalPersonnes["$idPersonne_courant"]->ajouterVersement( $totalPersonnes["$idPersonne_courant"]->ajouterVersement(
$idActivite_courant, $idActivite_courant,
$idTarif_courant, $idTarif_courant,
$totalVersements $totalVersements/100
); );
} }
$idActivite_courant = $ligne->idActivite; $idActivite_courant = $ligne->idActivite;
@ -130,7 +130,7 @@ function cumulerVersements($versements)
$totalPersonnes["$idPersonne_courant"]->ajouterVersement( $totalPersonnes["$idPersonne_courant"]->ajouterVersement(
$idActivite_courant, $idActivite_courant,
$idTarif_courant, $idTarif_courant,
$totalVersements $totalVersements/100
); );
return $totalPersonnes; return $totalPersonnes;

14
www/admin/activites.php Normal file
View File

@ -0,0 +1,14 @@
<?php
namespace Garradin;
use Garradin\Plugin\RecusFiscaux\Services;
// liste des activités, cotisations et comptes associés
$activitesTarifsComptes = Services::getActivitesTarifsEtComptes();
// préparation de l'affichage
$tpl->assign('activitesTarifsComptes', $activitesTarifsComptes);
// envoyer au template
$tpl->display(PLUGIN_ROOT . '/templates/activites.tpl');

View File

@ -4,24 +4,11 @@ namespace Garradin;
use Garradin\Plugin\RecusFiscaux\Services; use Garradin\Plugin\RecusFiscaux\Services;
// liste des activités, cotisations et comptes associés // liste du total des versements par personne
$activitesTarifsComptes = Services::getActivitesTarifsEtComptes(); $_SESSION['lesVersementsTotaux'] = Services::getVersementsTotaux("2021");
// liste des versements pour activités
$_SESSION['lesVersements'] = Services::getTousLesVersements("2021");
// liste des activités
$activites = Services::getActivites();
foreach ($activites as $num => $activite)
{
// ajouter les tarifs de l'activité
$activite->{'tarifs'} = Services::getTarifs($activite->{'id'});
}
// préparation de l'affichage // préparation de l'affichage
$tpl->assign('activitesTarifsComptes', $activitesTarifsComptes); $tpl->assign('lesVersementsTotaux', $_SESSION['lesVersementsTotaux']);
$tpl->assign('lesVersements', $_SESSION['lesVersements']);
$tpl->assign('listeParActiviteEtTarif', $activites);
$tpl->assign('plugin_css', ['style.css']); $tpl->assign('plugin_css', ['style.css']);
// envoyer au template // envoyer au template

View File

@ -85,7 +85,7 @@ function calculerTotal(listeCases, listeMontants, idTotal) {
for (var i = 1; i < listeCases.length; ++i) for (var i = 1; i < listeCases.length; ++i)
{ {
if (listeCases[i].checked) { if (listeCases[i].checked) {
total += Number(listeMontants[i-1].textContent); total += parseFloat(listeMontants[i-1].textContent);
} }
} }
// "afficher" le total // "afficher" le total
@ -117,3 +117,25 @@ function verifierChoix(formulaire)
} }
return ok; return ok;
} }
/**
* Associer un écouteur à la première case à cocher de chaque table
* @remarks : n'est plus utile
*/
function activerListener() {
// parcourir les tables
const lesTables = document.querySelectorAll("table.list");
for (let i = 0; i < lesTables.length; ++i) {
// vérifier si c'est l'une des tables qui nous intéresse
// l'id est du genre : versements_xx où xx est un entier
const id = lesTables[i].id;
const re = /^versements_[0-9]+/;
console.log("id = " + id + " => " + re.test(id));
if (re.test(id)) {
// chercher le premier élément input
const premierInput = lesTables[i].querySelector("input");
// associer un écouteur à la première case à cocher
premierInput.addEventListener('change', cocherDecocher);
}
}
}

View File

@ -1,10 +1,10 @@
/* liste de versements */ /* liste des versements */
div.pair { div.pair {
padding : 0.2em; padding : 0.1em;
background: rgba(var(--gSecondColor), 0.2); background: rgba(var(--gSecondColor), 0.2);
} }
div.impair { div.impair {
padding : 0.2em; padding : 0.1em;
} }
fieldset { fieldset {
border:2px solid brown; border:2px solid brown;
@ -18,6 +18,9 @@ div span {
padding-left : 0.5em; padding-left : 0.5em;
padding-right : 0.5em; padding-right : 0.5em;
} }
td.montant {
text-align : right;
}
summary.activite { summary.activite {
background: rgba(var(--gMainColor), 0.25); background: rgba(var(--gMainColor), 0.25);
} }

24
www/admin/versements.php Normal file
View File

@ -0,0 +1,24 @@
<?php
namespace Garradin;
use Garradin\Plugin\RecusFiscaux\Services;
// liste des versements pour activités
$_SESSION['lesVersements'] = Services::getTousLesVersements("2021");
// liste des activités
$activites = Services::getActivites();
foreach ($activites as $num => $activite)
{
// ajouter les tarifs de l'activité
$activite->{'tarifs'} = Services::getTarifs($activite->{'id'});
}
// préparation de l'affichage
$tpl->assign('lesVersements', $_SESSION['lesVersements']);
$tpl->assign('listeParActiviteEtTarif', $activites);
$tpl->assign('plugin_css', ['style.css']);
// envoyer au template
$tpl->display(PLUGIN_ROOT . '/templates/versements.tpl');