Ajout calcul total général case cochées

FossilOrigin-Name: 3a1cdc3cd5b81be5a45684569107bbe48f547d471a6873aaa508652cf8103b0b
This commit is contained in:
engel 2025-12-30 09:35:39 +00:00
parent 358c44d23c
commit 57f0d77527
5 changed files with 120 additions and 73 deletions

View file

@ -71,8 +71,8 @@ $tpl->register_function('afficher_debut_tarif', function ($params)
<summary class="activite"> <summary class="activite">
<div class="activite"> <div class="activite">
<input type="checkbox" id="check_%1$s" <input type="checkbox" id="check_%1$s"
onclick="cocherDecocherTarif(check_%1$s)" />', onclick="cocherDecocherTarif(check_%1$s, %2$s)" />',
$idTarif); $idTarif, "total_general");
if ($idTarif == 0) { if ($idTarif == 0) {
// versement sur un compte non rattaché à une activité // versement sur un compte non rattaché à une activité
$out .= sprintf(' $out .= sprintf('
@ -122,7 +122,7 @@ $tpl->register_function('afficher_debut_personne', function ($params)
<summary class="personne"> <summary class="personne">
<div class="personne"> <div class="personne">
<input type="checkbox" id="check_%1$s" <input type="checkbox" id="check_%1$s"
onclick="cocherDecocherPersonne(check_%1$s, total_%1$s)" /> onclick="cocherDecocherPersonne(check_%1$s, total_%1$s, %3$s)" />
<label for="check_%1$s"> <label for="check_%1$s">
%2$s : <span class="total" id="total_%1$s">0,00 </span> %2$s : <span class="total" id="total_%1$s">0,00 </span>
</label> </label>
@ -130,7 +130,8 @@ $tpl->register_function('afficher_debut_personne', function ($params)
</summary> </summary>
<div class="versements">', <div class="versements">',
$idVersement, $idVersement,
$personne->nomPrenom $personne->nomPrenom,
"total_general"
); );
return $out; return $out;
}); });
@ -163,7 +164,7 @@ $tpl->register_function('afficher_versement', function ($params)
id="check_%1$s_%2$s" id="check_%1$s_%2$s"
name="selected[]" name="selected[]"
value="%2$s" value="%2$s"
onclick="cocherDecocherVersement(check_%1$s_%2$s, total_%1$s)" /> onclick="cocherDecocherCase(check_%1$s_%2$s, total_%1$s, %5$s)" />
<label for="check_%1$s_%2$s"><span class="montant">%3$s</span> <label for="check_%1$s_%2$s"><span class="montant">%3$s</span>
<span>%4$s</span> <span>%4$s</span>
</label> </label>
@ -176,7 +177,8 @@ $tpl->register_function('afficher_versement', function ($params)
",", ",",
"&nbsp;" "&nbsp;"
), ),
date_format(date_create($versement->date),"d/m/Y") date_format(date_create($versement->date),"d/m/Y"),
"total_general"
); );
return $out; return $out;
}); });

View file

@ -1,5 +1,26 @@
"use strict"; "use strict";
/**
* renvoyer la valeur numérique d'un montant formaté en
* @param texte qui représente nu nombre
*/
function getNumber(texte) {
return Number(texte.replace(/[^0-9,]/g, '').replace(/,/, '.'));
}
/**
* afficher un montant au format monétaire
* @param montant à afficher
* @param idElem : élément faire l'affichage
*/
function displayNumber(montant, idElem) {
idElem.innerHTML =
montant.toLocaleString('fr-FR', {
style: 'currency', currency: 'EUR',
minimumFractionDigits: 2
});
}
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// actions sur la liste des versements // actions sur la liste des versements
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -8,14 +29,15 @@
* Fonction appelée quand on ()coche la case globale * Fonction appelée quand on ()coche la case globale
* ()sélectionner toutes les cases de toutes les activités * ()sélectionner toutes les cases de toutes les activités
* @param {HTMLInputElement} idCaseGlobale id de la case globale * @param {HTMLInputElement} idCaseGlobale id de la case globale
* @param {HTMLSpanElement} idTotalGeneral id du total général
*/ */
function cocherDecocherTout(idCaseGlobale) { function cocherDecocherTout(idCaseGlobale, idTotalGeneral) {
// 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>
let lesDetails = document.querySelectorAll("details.activite"); let lesDetails = document.querySelectorAll("details.activite");
for (let i = 0; i < lesDetails.length; ++i) { for (let i = 0; i < lesDetails.length; ++i) {
let idCase = lesDetails[i].querySelector("input[type=checkbox]"); let idCase = lesDetails[i].querySelector("input[type=checkbox]");
idCase.checked = idCaseGlobale.checked; idCase.checked = idCaseGlobale.checked;
cocherDecocherTarif(idCase); cocherDecocherTarif(idCase, idTotalGeneral);
} }
// changer le message // changer le message
changerMessage(idCaseGlobale.nextElementSibling, idCaseGlobale); changerMessage(idCaseGlobale.nextElementSibling, idCaseGlobale);
@ -25,35 +47,37 @@ function cocherDecocherTout(idCaseGlobale) {
* Fonction appelée quand on ()coche la case d'activité * Fonction appelée quand on ()coche la case d'activité
* ()sélectionner toutes les cases de cette activité * ()sélectionner toutes les cases de cette activité
* @param {HTMLInputElement} idCaseGlobale id de la case d'activité * @param {HTMLInputElement} idCaseGlobale id de la case d'activité
* @param {HTMLSpanElement} idTotalGeneral id du total général
*/ */
function cocherDecocherTarif(idCaseGlobale) { function cocherDecocherTarif(idCaseGlobale, idTotalGeneral) {
let lesPersonnes = idCaseGlobale.closest("details").querySelectorAll("div.personne"); let lesPersonnes = idCaseGlobale.closest("details").querySelectorAll("div.personne");
cocherDecocherLesPersonnes(idCaseGlobale, lesPersonnes); cocherDecocherLesPersonnes(idCaseGlobale, lesPersonnes, idTotalGeneral);
} }
/** /**
* idem dans le cas des versements des personnes * idem dans le cas des versements des personnes
* @param {HTMLInputElement} idCaseGlobale id case à cocher d'une personne * @param {HTMLInputElement} idCaseGlobale id case à cocher d'une personne
*/ */
function cocherDecocherToutesLesPersonnes(idCaseGlobale) { function cocherDecocherToutesLesPersonnes(idCaseGlobale, idTotalGeneral) {
let lesPersonnes = document.querySelectorAll("div.personne"); let lesPersonnes = document.querySelectorAll("summary.personne");
cocherDecocherLesPersonnes(idCaseGlobale, lesPersonnes); cocherDecocherLesPersonnes(idCaseGlobale, lesPersonnes, idTotalGeneral);
changerMessage(idCaseGlobale.nextElementSibling, idCaseGlobale); changerMessage(idCaseGlobale.nextElementSibling, idCaseGlobale);
} }
/** /**
* @param {HTMLInputElement} idCaseGlobale * @param {HTMLInputElement} idCaseGlobale
* @param {NodeListOf<Element>} lesPersonnes * @param {NodeListOf<Element>} lesPersonnes
*/ * @param {HTMLSpanElement} idTotalGeneral id du total général
function cocherDecocherLesPersonnes(idCaseGlobale, lesPersonnes) { */
function cocherDecocherLesPersonnes(idCaseGlobale, lesPersonnes, idTotalGeneral) {
for (let j = 0; j < lesPersonnes.length; ++j) { for (let j = 0; j < lesPersonnes.length; ++j) {
// trouver l'élément total de la personne // trouver l'élément total de la personne
let idTotal = lesPersonnes[j].querySelector("span"); let idTotal = lesPersonnes[j].querySelector("span.total");
// puis la case à cocher // puis la case à cocher
let idCase = lesPersonnes[j].closest("summary").querySelector("input"); let idCase = lesPersonnes[j].querySelector("input[type=checkbox]");
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, idTotalGeneral);
} }
} }
@ -62,51 +86,45 @@ function cocherDecocherLesPersonnes(idCaseGlobale, lesPersonnes) {
* - ()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 {HTMLInputElement} idCase id de la case qui a été cochée * @param {HTMLInputElement} idCase id de la case qui a été cochée
* @param {HTMLSpanElement} idTotal id de l'élément afficher le total * @param {HTMLSpanElement} idTotal id de l'élément afficher le total de la personne
* @param {HTMLSpanElement} idTotalGeneral id de l'élément afficher le total général
*/ */
function cocherDecocherPersonne(idCase, idTotal) { function cocherDecocherPersonne(idCase, idTotal, idTotalGeneral) {
// chercher le fieldset des versements let conteneur = idCase.closest("details").querySelector("div.versements");
let fieldset = idCase.closest("details").querySelector("div.versements"); let listeCases = conteneur.querySelectorAll("input[type=checkbox]");
let listeCases = fieldset.querySelectorAll("input[type=checkbox]");
for (let i = 0; i < listeCases.length; ++i) { for (let i = 0; i < listeCases.length; ++i) {
listeCases[i].checked = idCase.checked; if (listeCases[i].checked != idCase.checked) {
cocherDecocherVersement(listeCases[i], idTotal); listeCases[i].checked = idCase.checked;
} cocherDecocherVersement(listeCases[i], idTotal, idTotalGeneral);
}
}
} }
/** /**
* Fonction appelée quand on ()coche la case d'un versement * Fonction appelée quand on ()coche la case d'un versement
* Faire le total des cases cochées et l'afficher * Mettre à jour le total des cases cochées et le total global et les afficher
* *
* @param {HTMLInputElement} idCase id de la case qui a été cochée * @param {HTMLInputElement} idCase id de la case qui a été ()cochée
* @param {HTMLSpanElement} idTotal id de l'élément afficher le total * @param {HTMLSpanElement} idTotal id du total de la personne
* @param {HTMLSpanElement} idTotalGeneral id du total général
*/ */
function cocherDecocherVersement(idCase, idTotal) {
let fieldset = idCase.closest("div.versements");
let listeCases = fieldset.querySelectorAll("input[type=checkbox]");
let listeMontants = fieldset.querySelectorAll("span.montant");
calculerTotal(listeCases, listeMontants, idTotal);
}
/** function cocherDecocherVersement(idCase, idTotal, idTotalGeneral) {
* Faire le total des cases cochées et l'afficher let div = idCase.closest("div");
* @param {NodeListOf<Element>} listeCases liste des cases let idmontant = div.querySelector("span.montant");
* @param {NodeListOf<Element>} listeMontants liste des montants associés let montant = getNumber(idmontant.textContent);
* @param {HTMLSpanElement} idTotal id de l'élément afficher le total let totalPersonne = getNumber(idTotal.textContent);
*/ let totalGeneral = getNumber(idTotalGeneral.textContent);
function calculerTotal(listeCases, listeMontants, idTotal) { if (idCase.checked) {
let total = 0; totalPersonne += montant;
for (let i = 0; i < listeCases.length; ++i) { totalGeneral += montant;
if (listeCases[i].checked) { } else {
total += parseFloat(listeMontants[i].textContent.replace(/\s/g, "").replace(",", ".")); totalPersonne -= montant;
} totalGeneral -= montant;
} }
// afficher le total displayNumber(totalPersonne, idTotal);
idTotal.innerHTML = displayNumber(totalGeneral, idTotalGeneral);
total.toLocaleString('fr-FR', {
style: 'currency', currency: 'EUR',
minimumFractionDigits: 2
});
} }
/** /**
@ -273,4 +291,4 @@ function changerStyle(document) {
if (sheet.href.includes('imprimer_recu.css')) { sheet.media = 'print'; } if (sheet.href.includes('imprimer_recu.css')) { sheet.media = 'print'; }
} }
// console.log(styles); // console.log(styles);
} }

View file

@ -2,6 +2,10 @@
* liste des versements * liste des versements
*/ */
label.strong {
font-weight : bold;
}
div.pair { div.pair {
background-color: rgba(var(--gSecondColor), 0.15); background-color: rgba(var(--gSecondColor), 0.15);
} }

View file

@ -4,15 +4,24 @@
<h2>Année {$annee_recu} : versements par activité et tarif</h2> <h2>Année {$annee_recu} : versements par activité et tarif</h2>
<fieldset class="noprint"> <fieldset class="noprint">
<input type="checkbox" class="check_global" id="check_global" onclick="cocherDecocherTout(check_global)" /> <dl>
<dd>
<label class="strong">Total des cases cochées : </label>
<span class="total" id="total_general">0,00 €</span>
</dd>
<dd>
<input type="checkbox" class="check_global" id="check_global" onclick="cocherDecocherTout(check_global, total_general)" />
<label for="check_global">Cliquer pour cocher toutes les lignes</label> <label for="check_global">Cliquer pour cocher toutes les lignes</label>
</dd>
<dd>
<button type="button" data-icon="↑" class="icn-btn" id="close_details_activite" <button type="button" data-icon="↑" class="icn-btn" id="close_details_activite"
onclick="montrerMasquerDetails(this.id, 'details.activite', 'toutes les activités')"> onclick="montrerMasquerDetails(this.id, 'details.activite', 'toutes les activités')">
Replier toutes les activités</button> Replier toutes les activités</button>
<button type="button" data-icon="↑" class="icn-btn" id="close_details_personne" <button type="button" data-icon="↑" class="icn-btn" id="close_details_personne"
onclick="montrerMasquerDetails(this.id, 'details.personne', 'toutes les personnes')"> onclick="montrerMasquerDetails(this.id, 'details.personne', 'toutes les personnes')">
Replier toutes les personnes</button> Replier toutes les personnes</button>
<br /> </dd>
<dd>
{button type="submit" label="Télécharger les reçus au format PDF" shape="download" {button type="submit" label="Télécharger les reçus au format PDF" shape="download"
form="versements_activites" form="versements_activites"
formaction="generer_recus.php?type=activite&format=pdf" formaction="generer_recus.php?type=activite&format=pdf"
@ -21,6 +30,8 @@
form="versements_activites" form="versements_activites"
formaction="generer_recus.php?type=activite&format=print" formaction="generer_recus.php?type=activite&format=print"
onclick="return verifierChoix(this.form)"} onclick="return verifierChoix(this.form)"}
</dd>
</dl>
</fieldset> </fieldset>
<form method="post" target="_blank" id="versements_activites"> <form method="post" target="_blank" id="versements_activites">

View file

@ -4,21 +4,33 @@
<h2>Année {$annee_recu} : versements par personne</h2> <h2>Année {$annee_recu} : versements par personne</h2>
<fieldset class="noprint"> <fieldset class="noprint">
<input type="checkbox" class="check_global" id="check_global" <dl>
onclick="cocherDecocherToutesLesPersonnes(check_global)" />
<label for="check_global">Cliquer pour cocher toutes les lignes</label> <dd>
<button type="button" data-icon="↑" class="icn-btn" id="close_details_personne" <label class="strong">Total des cases cochées : </label>
onclick="montrerMasquerDetails(this.id, 'details.personne', 'toutes les personnes')"> <span class="total" id="total_general">0,00 €</span>
Replier toutes les personnes</button> </dd>
<br /> <dd>
{button type="submit" label="Télécharger les reçus au format PDF" shape="download" <input type="checkbox" class="check_global" id="check_global"
form="versements_personnes" onclick="cocherDecocherToutesLesPersonnes(check_global, total_general)" />
formaction="generer_recus.php?type=personne&format=pdf" <label for="check_global">Cliquer pour cocher toutes les lignes</label>
onclick="return verifierChoix(this.form)"} </dd>
{button type="submit" label="Imprimer les reçus" shape="print" <dd>
form="versements_personnes" <button type="button" data-icon="↑" class="icn-btn" id="close_details_personne"
formaction="generer_recus.php?type=personne&format=print" onclick="montrerMasquerDetails(this.id, 'details.personne', 'toutes les personnes')">
onclick="return verifierChoix(this.form)"} Replier toutes les personnes</button>
</dd>
<dd>
{button type="submit" label="Télécharger les reçus au format PDF" shape="download"
form="versements_personnes"
formaction="generer_recus.php?type=personne&format=pdf"
onclick="return verifierChoix(this.form)"}
{button type="submit" label="Imprimer les reçus" shape="print"
form="versements_personnes"
formaction="generer_recus.php?type=personne&format=print"
onclick="return verifierChoix(this.form)"}
</dd>
</dl>
</fieldset> </fieldset>
<form method="post" target="_dialog" id="versements_personnes"> <form method="post" target="_dialog" id="versements_personnes">