diff --git a/css/gamutable.css b/css/gamutable.css
index cb25742..5eef102 100644
--- a/css/gamutable.css
+++ b/css/gamutable.css
@@ -1,3 +1,8 @@
+tfoot th {
+ color: inherit;
+ background: var(--spip-color-theme-lighter);
+}
+
.verte {
color: #00b800;
}
@@ -116,6 +121,9 @@ th .vue-select {
.gamutable table thead {
border: 1px solid rgb(119, 119, 119);
}
+.gamutable table tfoot {
+ border: 1px solid rgb(119, 119, 119);
+}
.gamutable table .gt_labels {
display: -ms-flexbox;
diff --git a/json_gamutable.json.html b/json_gamutable.json.html
index b68fae7..aaaafbe 100644
--- a/json_gamutable.json.html
+++ b/json_gamutable.json.html
@@ -14,6 +14,18 @@
"checkbox_a_valider": "a valider",
"statut": "statut"
},
+"footer": [
+{"source": "affiche", "champs" : [
+ {"nom": "type_mission", "legende" : "Somme Affiché"},
+ {"nom": "nom_champ_ttc", "fonction": "somme_monnaie"},
+ {"nom": "nom_champ_ht", "fonction": "somme_monnaie"}
+]},
+{"source": "total", "champs" : [
+ {"nom": "type_mission", "legende" : "Somme totale"},
+ {"nom": "nom_champ_ttc", "fonction": "somme_monnaie"},
+ {"nom": "nom_champ_ht", "fonction": "somme_monnaie"}
+]}
+],
"crayons":{
"titre" : "article",
"nom": "auteur"
diff --git a/src/components/gamuTable.vue b/src/components/gamuTable.vue
index 7616a5f..99649ec 100644
--- a/src/components/gamuTable.vue
+++ b/src/components/gamuTable.vue
@@ -138,6 +138,18 @@
+
+
+
+ {{footer_affiche[head]}}
+ |
+
+
+
+ {{footer_total[head]}}
+ |
+
+
@@ -261,6 +273,9 @@ let table = ref([]);
let header_top = ref({});
let header_class_header_top = ref([]);
let header = ref([]);
+let footer = ref([]);
+let footer_affiche = ref({});
+let footer_total = ref({});
let crayons = ref([]);
let classes = ref([]);
let checkbox = ref([]);
@@ -422,6 +437,66 @@ const tableau = computed(() => {
});
function saveTriCol() { }
+
+function majFooterTotal() {
+ let r = {};
+ footer.value.filter((d) => d.source === 'total')[0]?.champs.forEach((d) => {
+ let valeur = 0;
+ if (d.fonction === "somme") {
+ valeur = footerSomme(d.nom, table.value);
+ } else if (d.fonction === "somme_monnaie") {
+ valeur = footerSommeMonnaie(d.nom, table.value);
+ } else if (d.legende !== undefined) {
+ valeur = d.legende ?? 'toto';
+ }
+ r[d.nom] = valeur
+ });
+ footer_total.value = r;
+
+}
+function majFooterAffiche() {
+ let r = {};
+ footer.value.filter((d) => d.source === 'affiche')[0]?.champs.forEach((d) => {
+ let valeur = 0;
+ if (d.fonction === "somme") {
+ valeur = footerSomme(d.nom, tableau.value);
+ } else if (d.fonction === "somme_monnaie") {
+ valeur = footerSommeMonnaie(d.nom, tableau.value);
+ } else if (d.legende !== undefined) {
+ valeur = d.legende ?? 'toto';
+ }
+ r[d.nom] = valeur
+ });
+ footer_affiche.value = r;
+}
+function footerSomme(champ, data) {
+ let r = 0;
+ data.map((d) => d.search).forEach((d) => {
+ Object.entries(d).forEach(([c, v]) => {
+ if (c === champ) {
+ r += v;
+ }
+ })
+ })
+ return r;
+}
+
+function footerSommeMonnaie(champ, data) {
+ let r = 0;
+ data.map((d) => d.search).forEach((d) => {
+ Object.entries(d).forEach(([c, v]) => {
+ if (c === champ) {
+ r += v;
+ }
+ })
+ })
+ const euro = new Intl.NumberFormat('fr-FR', {
+ style: 'currency',
+ currency: 'EUR',
+ minimumFractionDigits: 2
+ });
+ return euro.format(r);
+}
//~~~~~~~~~~~~~~~~~~~~~~~~~
// les watchers
//~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -440,6 +515,7 @@ watch(parPageSelect, (e) => {
watch(table, () => {
saveHeader();
localforage.setItem(nameLocalStorage, JSON.stringify(table.value));
+ majFooterTotal();
});
watch(tableau, () => {
@@ -460,6 +536,7 @@ watch(tableau, () => {
filtreColVal.value[col] = Tval;
});
}
+ majFooterAffiche();
});
watch(
@@ -501,6 +578,11 @@ function gererConfig(config) {
})
header_class_header_top.value = r;
}
+ if (config.footer !== undefined) {
+ footer.value = config.footer;
+ } else {
+ footer.value = [];
+ }
if (config.crayons !== undefined) {
crayons.value = config.crayons;
}
@@ -749,6 +831,7 @@ function saveHeader() {
let $header = {
header: header.value,
header_top: header_top.value,
+ footer: footer.value,
crayons: crayons.value,
classes: classes.value,
filtreCol: filtreColType.value,