From f899b045671bcb7d5cab5739247b00bbe5fc9d0b Mon Sep 17 00:00:00 2001 From: fred Date: Sun, 7 Jan 2024 03:18:46 +0100 Subject: [PATCH] =?UTF-8?q?D=C3=A9penses=20et=20Revenus=20!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- earth/g1gate/changelog.html | 7 + earth/g1gate/index.html | 3 + earth/g1gate/index_fichiers/app.js | 223 +++++++++++++++++++++++------ 3 files changed, 187 insertions(+), 46 deletions(-) diff --git a/earth/g1gate/changelog.html b/earth/g1gate/changelog.html index 75598b3..30d3d77 100644 --- a/earth/g1gate/changelog.html +++ b/earth/g1gate/changelog.html @@ -15,6 +15,13 @@
+
+

2024-jan-07

+
    +
  • Ajout à "Dépenses" de la partie "Revenus".
  • +
+
+

2023-oct-20

    diff --git a/earth/g1gate/index.html b/earth/g1gate/index.html index 8a1b660..e92104b 100644 --- a/earth/g1gate/index.html +++ b/earth/g1gate/index.html @@ -46,6 +46,9 @@
    +
    +
    +
    diff --git a/earth/g1gate/index_fichiers/app.js b/earth/g1gate/index_fichiers/app.js index 6de3a4e..c067c04 100644 --- a/earth/g1gate/index_fichiers/app.js +++ b/earth/g1gate/index_fichiers/app.js @@ -263,9 +263,9 @@ export const fetchExpenses = async (pubkey, minTime, limit = MAX_NB_TX) => { transactions.push({ date: new Date(tx.medianTime).toLocaleDateString(), walletId: pubkey, - income: tx.amount > 0 ? tx.amount / 100 : 0, - outcome: tx.amount < 0 ? -tx.amount / 100 : 0, - comment: "Transaction Comment", // Add your logic to get the comment + income: 0, + outcome: tx.amount, + comment: "Expense Comment", // Add your logic to get the comment }); } @@ -285,6 +285,102 @@ export const fetchExpenses = async (pubkey, minTime, limit = MAX_NB_TX) => { throw new Error("Failed to fetch data from all nodes"); }; +export const query__incomes = (walletPk, minTime, size = MAX_NB_TX) => { + + return { + _source: ["amount", "issuer"] + ,sort: [ + { + "medianTime": "desc" + } + ] + ,size: size + ,query: { + bool: { + filter: [ + { + range: { + "medianTime": { + gte: minTime + } + } + } + ,{ + term: { + "recipient": walletPk + } + } + ] + } + } + }; +}; + +export const fetchIncomes = async (pubkey, minTime, limit = MAX_NB_TX) => { + + shuffle(CESIUM_G1_NODES); // Mélanger la liste des noeuds + + for (let node of CESIUM_G1_NODES) { + try { + const url = `${node}/g1/movement/_search`; + let queryBody = query__incomes(pubkey, minTime, limit); + + console.log('incomes queryBody : \n', JSON.stringify(queryBody)); + + const response = await fetch(url, { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify(queryBody) + }); + + const data = await response.json(); + + console.log('node for the incomes of :\n', pubkey, '\n', node); + console.log('incomes data :\n', data); + + let incomesByIssuer = {}; + let totalAmount = 0; + let transactions = []; + + for (const hit of data.hits.hits) { + + const tx = hit._source; + + if (!(tx.issuer in incomesByIssuer)) { + + incomesByIssuer[tx.issuer] = 0; + } + + incomesByIssuer[tx.issuer] += tx.amount/100; + + totalAmount += tx.amount; + + transactions.push({ + date: new Date(tx.medianTime).toLocaleDateString(), + walletId: pubkey, + income: tx.amount, + outcome: 0, + comment: "Income Comment", // Add your logic to get the comment + }); + + } + + totalAmount = totalAmount/100; + + return { + incomesTotalAmount: totalAmount + ,incomesByIssuer: incomesByIssuer + }; + } catch (error) { + console.error(`Failed to fetch data from ${node}: ${error}`); + // Si une erreur se produit, passez simplement au noeud suivant + } + } + + throw new Error("Failed to fetch data from all nodes"); +}; export const query__cesium_profile = (pubkey) => { @@ -444,40 +540,6 @@ const exportToPDF = (transactions) => { export const displayExpenses = (expensesByRecipient, expensesTotalAmount, recipientsCesiumProfiles, chartColors, currentPubkey, currentProfile) => { - let exportButtonContainer = document.querySelector("#export-button"); - let exportButton = document.createElement("button"); - exportButton.textContent = "Export to PDF"; - exportButton.addEventListener("click", async () => { - try { - const { expensesByRecipient, expensesTotalAmount } = await fetchExpenses( - currentPubkey, - minTime, - txLimit - ); - - let transactions = []; - - for (const recipient in expensesByRecipient) { - transactions.push({ - date: new Date().toLocaleDateString(), - walletId: currentPubkey, - income: expensesByRecipient[recipient], - outcome: 0, - comment: "Transaction Comment", // Add your logic to get the comment - }); - } - - // Export transactions to PDF - exportToPDF(transactions); - } catch (error) { - console.error(`Error exporting to PDF: ${error}`); - } - }); - - // Append the export button to the container - exportButtonContainer.innerHTML = ''; - exportButtonContainer.appendChild(exportButton); - let screenElt = document.querySelector('#expenses'); screenElt.innerHTML = ''; @@ -539,6 +601,69 @@ export const displayExpenses = (expensesByRecipient, expensesTotalAmount, recipi screenElt.scrollIntoView({behavior: 'smooth'}, true); }; +export const displayIncomes = (incomesByIssuer, incomesTotalAmount, issuersCesiumProfiles, chartColors, currentPubkey, currentProfile) => { + + let screenElt = document.querySelector('#incomes'); + screenElt.innerHTML = ''; + + let currentProfileTitleElt = document.createElement('h2'); + screenElt.append(currentProfileTitleElt); + let title = null; + if (currentProfile == undefined) { + title = 'Revenus du portefeuille ' + currentPubkey.substr(0, 8) + ''; + } else { + title = 'Revenus de ' + currentProfile.title + ''; + } + currentProfileTitleElt.innerHTML = title; + + let svgContainer = document.createElement('article'); + screenElt.append(svgContainer); + svgContainer.classList.add("svg-container"); + + let chartData = []; + + // Formatting data + for (const issuer in incomesByIssuer) { + + let issuerObj = {}; + + issuerObj.pk = issuer; + issuerObj.amount = incomesByIssuer[issuer]; + let numberOptions = { roundingMode: 'ceil', minimumFractionDigits: 0, maximumFractionDigits: 0 }; + issuerObj.displayedAmount = G12DU(issuerObj.amount).toLocaleString('fr-FR', numberOptions) + ' DU'; + + if (issuersCesiumProfiles[issuer] != undefined + && issuersCesiumProfiles[issuer].title != undefined + ) { + issuerObj.title = issuersCesiumProfiles[issuer].title; + } else { + issuerObj.title = issuer.substr(0, 8); + } + + chartData.push(issuerObj); + } + + let chart = Treemap(chartData, { + path: d => d.title, + value: d => d.amount, + group: d => d.title, + label: (d, n) => d.title, + title: (d, n) => d.displayedAmount, + link: (d, n) => '#' + d.pk + '', + linkTarget: '_self', + tile: d3.treemapSquarify, + width: 1280, + height: 720, + padding: 0, + colors: chartColors, + fillOpacity: 1 + }); + + svgContainer.append(chart); + + screenElt.scrollIntoView({behavior: 'smooth'}, true); +}; + let formElt = document.querySelector('form#explore'); @@ -550,18 +675,25 @@ const treemapIt = async (pubkey, minTime, maxNbTx = MAX_NB_TX) => { } let { expensesTotalAmount, expensesByRecipient } = await fetchExpenses(pubkey, minTime, maxNbTx); + let { incomesTotalAmount, incomesByIssuer } = await fetchIncomes(pubkey, minTime, maxNbTx); let nbRecipients = Object.keys(expensesByRecipient).length; + let nbIssuers = Object.keys(incomesByIssuer).length; - console.log("nb recipients :\n", nbRecipients); + console.log("nb recipients :\n", nbRecipients); + console.log("nb Issuers :\n", nbIssuers); let recipientsList = Object.keys(expensesByRecipient); let recipientsCesiumProfiles = await fetchCesiumProfiles(recipientsList, maxNbTx); + let issuersList = Object.keys(incomesByIssuer); + let issuersCesiumProfiles = await fetchCesiumProfiles(issuersList, maxNbTx); + let currentProfile = await fetchCesiumProfile(pubkey); - console.log('currentProfile :\n', currentProfile); + console.log('currentProfile :\n', currentProfile); displayExpenses(expensesByRecipient, expensesTotalAmount, recipientsCesiumProfiles, chartColors, pubkey, currentProfile); + displayIncomes(incomesByIssuer, incomesTotalAmount, issuersCesiumProfiles, chartColors, pubkey, currentProfile); let svg = document.querySelector('#expenses svg'); let links = svg.querySelectorAll("a"); @@ -571,7 +703,7 @@ const treemapIt = async (pubkey, minTime, maxNbTx = MAX_NB_TX) => { link.addEventListener('click', (linkEvent) => { // linkEvent.currentTarget.preventDefault(); - console.log('linkEvent.currentTarget :\n', linkEvent.currentTarget); + console.log('linkEvent.currentTarget :\n', linkEvent.currentTarget); let pubkey = linkEvent.currentTarget.getAttribute('href').substr(1); // treemapIt(pubkey, minDate); @@ -589,7 +721,7 @@ const getPkInHash = () => { window.addEventListener("popstate", (popEvent) => { let pk = getPkInHash(); - console.log('\n\n\npubkey :\n', pk); + console.log('\n\n\npubkey :\n', pk); if (pk != '') { treemapIt(pk, minTime, txLimit); @@ -605,7 +737,7 @@ formElt.addEventListener('submit', (formEvent) => { let minDateStr = formEvent.target.querySelector('input[name="minDate"]').value; let minDate = new Date(minDateStr); minTime = Math.floor(minDate.valueOf()/1000); - console.log('minTime :\n', minTime); + console.log('minTime :\n', minTime); let pubkey = formEvent.target.querySelector('input[name="pubkey"]').value; @@ -625,13 +757,12 @@ window.addEventListener('DOMContentLoaded', (loadEvent) => { let aMonthAgo = new Date(now); aMonthAgo.setMonth(aMonthAgo.getMonth() - 1); - console.log('aMonthAgo : ', aMonthAgo); - console.log('aMonthAgo.getMonth() :\n', aMonthAgo.getMonth()); + console.log('aMonthAgo : ', aMonthAgo); + console.log('aMonthAgo.getMonth() :\n', aMonthAgo.getMonth()); let dateStr = aMonthAgo.getFullYear() + '-' + (aMonthAgo.getMonth()+1).toString().padStart(2,0) + '-' + aMonthAgo.getDate().toString().padStart(2,0); - console.log('dateStr : ', dateStr); + console.log('dateStr : ', dateStr); minDateElt.value = dateStr; }); -