import { fetchData, deleteData, sseUrl } from "./api.js"; const urlParams = new URLSearchParams(window.location.search); const euroFormat = new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }); let backendEntries = []; let entries = []; // Verbindung zum SSE-Endpunkt herstellen const eventSource = new EventSource(sseUrl); // Auf Update reagieren eventSource.addEventListener('update', () => { console.log("refreshing...") start(); }); function start() { fetchData(`accounts/${urlParams.get('account')}`).then((data) => { const root = document.getElementById("detail-container"); root.innerHTML = ""; const title = document.createElement("div"); title.innerHTML = `${data.number} - ${data.name}` title.setAttribute("class", "detail-title"); root.append(title); createDescriptionTable(root, data); if (data.description) { const description = document.createElement("div"); description.innerHTML = data.description; root.append(description); } backendEntries = [...data.entries]; entries = [...backendEntries]; if (entries.length > 0) { document.getElementById("table-container").style.display = "flex"; //Standardmäßig soll absteigend nach Buchungsdatum sortiert werden entries = entries.sort((a, b) => (a.postingDate < b.postingDate) ? 1 : ((b.postingDate < a.postingDate) ? -1 : 0)); //Standardmäßig sollen nur Buchungen des laufenden Kalenderjahres angezeigt werden entries = entries.filter(element => new Date(element.postingDate) >= new Date(new Date().getFullYear(), 0, 1) && new Date(element.valueDate) >= new Date(new Date().getFullYear(), 0, 1)); document.getElementById("beginDate").value = `${new Date().getFullYear()}-01-01`; createEntryTable(entries); } if (entries.length < 10) document.getElementById("pagination-div").style.display = "none"; }); } /** * Erzeugt die Tabelle und errechnet die anzuzeigenden Einträge * @param {array} data */ function createEntryTable(data) { const rootElement = document.querySelector(".table tbody"); rootElement.innerHTML = null; const bookingDate = document.getElementById("bookingDate"); bookingDate.onclick = () => sortTable("postingDate", bookingDate.innerHTML, bookingDate); const valuta = document.getElementById("valuta"); valuta.onclick = () => sortTable("valueDate", valuta.innerHTML, valuta); const pageInfo = document.getElementById("page-info"); const arrayEntriesStart = (pageInfo.innerHTML - 1) * getBookingsPerPage(); const arrayEntriesEnd = (pageInfo.innerHTML) * getBookingsPerPage(); data = data.slice(arrayEntriesStart, arrayEntriesEnd); data.forEach(element => { rootElement.append(createEntryTableRow(element)); }); } /** * Erzeugt die einzelnen Tabellenzeilen * @param {object} entry * @returns DOMElement */ function createEntryTableRow(entry) { const tr = document.createElement("tr"); tr.setAttribute("class", "entry-table-tr"); const bookingDate = document.createElement("td"); bookingDate.setAttribute("class", "entry-table-td"); bookingDate.innerHTML = new Date(entry.postingDate).toLocaleDateString("de-DE"); tr.append(bookingDate); const valuta = document.createElement("td"); valuta.setAttribute("class", "entry-table-td"); valuta.innerHTML = new Date(entry.valueDate).toLocaleDateString("de-DE"); tr.append(valuta); const title = document.createElement("td"); title.setAttribute("class", "entry-table-td"); title.innerHTML = entry.title; tr.append(title); const offsetAccount = document.createElement("td"); offsetAccount.setAttribute("class", "entry-table-td"); offsetAccount.innerHTML = entry.offsetAccounts; tr.append(offsetAccount); const amount = document.createElement("td"); amount.setAttribute("class", "entry-table-td"); amount.innerHTML = euroFormat.format(entry.amount); tr.append(amount); console.log(entry) const action = document.createElement("td"); action.setAttribute("class", "entry-table-td"); action.style.textAlign="center"; const editBtn = document.createElement("input"); editBtn.setAttribute("class", "action-button-edit"); editBtn.type = "button"; editBtn.value = "edit"; editBtn.onclick = () => window.location.href = `transaction.html?account=${urlParams.get('account')}&id=${entry.id}`; action.append(editBtn); const deleteBtn = document.createElement("input"); deleteBtn.setAttribute("class", "action-button"); deleteBtn.type = "button"; deleteBtn.value = "x"; deleteBtn.onclick = () => deleteTransaction(entry); action.append(deleteBtn); tr.append(action); return tr; } /** * triggert das löschen der Transaktion * @param {object} transaction */ function deleteTransaction(transaction) { deleteData(`transactions/${transaction.id}`).then(response => { if(response) window.location.reload(); }) } /** * navigiert zur Seite, zum anlegen neuer Transaktionen */ document.getElementById("add-transaction").addEventListener("click", () => { window.location.href = `transaction.html?account=${urlParams.get('account')}` }); /** * Erstellt die Detailtabelle * @param {DOMElement} rootElement * @param {object} data */ function createDescriptionTable(rootElement, data) { const table = document.createElement("table"); table.setAttribute("class", "description-table"); table.setAttribute("border", "1px"); if (data.description) table.append(createDescriptionTableRow("Kontoart:", data.type)); table.append(createDescriptionTableRow("Bilanz (mit Unterkonten):", euroFormat.format(data.balance))); table.append(createDescriptionTableRow("Bilanz (ohne Unterkonten):", euroFormat.format(data.localBalance))); table.append(createDescriptionTableRow("Aktionen", `EDIT`)); rootElement.append(table); } /** * Erzeugt die einzelnen Tabellenzeilen * @param {string} title * @param {string} value * @returns */ function createDescriptionTableRow(title, value) { const accounttype = document.createElement("tr"); accounttype.setAttribute("class", "description-table-tr"); const accounttypeHeader = document.createElement("th"); accounttypeHeader.setAttribute("class", "description-table-th"); accounttypeHeader.innerHTML = title; const accounttypeValue = document.createElement("td"); accounttypeValue.setAttribute("class", "description-table-td"); accounttypeValue.innerHTML = value; accounttype.append(accounttypeHeader); accounttype.append(accounttypeValue); return accounttype; } /** * Eventhandler für das sortieren der Tabellen Datumsspalten * Managed die Pfeile zur Sortierrichtung und sortiert das entries array * @param {string} column * @param {string} columnName * @param {DOMElement} docElement */ function sortTable(column, columnName, docElement) { document.querySelectorAll(".clickable").forEach(element => { if (element.innerHTML.slice(-1) === "↓" || element.innerHTML.slice(-1) === "↑") element.innerHTML = element.innerHTML.slice(0, -1); }); if (columnName.slice(-1) === "↓") { // ASC docElement.innerHTML = `${docElement.innerHTML.slice(0, columnName.length - 1)}↑`; entries = entries.sort((a, b) => (a[column] > b[column]) ? 1 : ((b[column] > a[column]) ? -1 : 0)); } else if (columnName.slice(-1) === "↑") { // default docElement.innerHTML = `${docElement.innerHTML.slice(0, columnName.length - 1)}`; entries = backendEntries; } else { // DESC docElement.innerHTML = `${docElement.innerHTML} ↓`; entries = entries.sort((a, b) => (a[column] < b[column]) ? 1 : ((b[column] < a[column]) ? -1 : 0)); } createEntryTable(entries); } // Fügt den Eventhandler für die Filter Eingabefelder hinzu document.getElementsByName("dateFilter").forEach(element => element.addEventListener("change", filterAll)); document.getElementsByName("textFilter").forEach(element => element.addEventListener("keyup", filterAll)); // Eventhandler um die Datumsfelder zurückzusetzen document.getElementById("resetDates").addEventListener("click", () => { document.getElementById("beginDate").value = ""; document.getElementById("endDate").value = ""; filterAll(); }); /** * Filtert die Daten aus dem Backend nach den Filterfeldern */ function filterAll() { let filteredEntries = backendEntries; filteredEntries = filterDates(filteredEntries); filteredEntries = filterText(filteredEntries); filteredEntries = filterAmount(filteredEntries); createEntryTable(filteredEntries); } /** * Filtert die Daten anhand der Datumsfelder * @param {array} array * @returns array */ function filterDates(array) { const begin = document.getElementById("beginDate").value; const end = document.getElementById("endDate").value; if (begin !== "" && end !== "") { return array.filter(element => (new Date(element.postingDate) >= new Date(begin) && new Date(element.valueDate) >= new Date(begin)) && (new Date(element.postingDate) <= new Date(end) && new Date(element.valueDate) <= new Date(end))); } else if (begin !== "") { return array.filter(element => new Date(element.postingDate) >= new Date(begin) && new Date(element.valueDate) >= new Date(begin)); } else if (end !== "") { return array.filter(element => new Date(element.postingDate) <= new Date(end) && new Date(element.valueDate) <= new Date(end)); } return array; } /** * Filtert die Daten anhand der des Freitextfeldes * @param {array} array * @returns array */ function filterText(array) { const searchString = document.getElementById("searchText").value; if (searchString !== "") { return array.filter(element => element.title.toLowerCase().includes(searchString.toLowerCase())); } return array; } /** * Filtert die Daten anhand der des min. und max. Betrags * @param {array} array * @returns array */ function filterAmount(array) { const begin = document.getElementById("beginAmount").value; const end = document.getElementById("endAmount").value; if (begin !== "" && end !== "") { return array.filter(element => (element.amount >= begin) && (element.amount <= end)); } else if (begin !== "") { return array.filter(element => element.amount >= begin); } else if (end !== "") { return array.filter(element => element.amount <= end); } return array; } /** * Eventhandler für Pagination "Seite Vorwärts Button" */ document.getElementById("forward-page").addEventListener("click", () => { const pageInfo = document.getElementById("page-info"); let pageNumber = ++pageInfo.innerHTML; const maxPage = Math.ceil(entries.length / getBookingsPerPage()); if (pageNumber > maxPage) pageNumber = 1; pageInfo.innerHTML = pageNumber; createEntryTable(entries); }); /** * Eventhandler für Pagination "Seite Rückwärts Button" */ document.getElementById("backward-page").addEventListener("click", () => { const pageInfo = document.getElementById("page-info"); let pageNumber = --pageInfo.innerHTML; const maxPage = Math.ceil(entries.length / getBookingsPerPage()); if (pageNumber < 1) pageNumber = maxPage; pageInfo.innerHTML = pageNumber; createEntryTable(entries); }); /** * Eventhandler für Selectbox Änderung */ document.getElementById("table-range").addEventListener("change", () => { document.getElementById("page-info").innerHTML = 1; //reset page createEntryTable(entries); }); /** * Liefert die Anzahl der Einträge aus der Selectbox zurück bzw. die Array länge, bei Auswahl von "Alle" * @returns integer */ function getBookingsPerPage() { if (document.getElementById("table-range").value === "Alle") return entries.length; return Number.parseInt(document.getElementById("table-range").value); } start();