257 lines
9.3 KiB
JavaScript
257 lines
9.3 KiB
JavaScript
// Event-Listener für das Laden der Seite
|
|
window.addEventListener('DOMContentLoaded', () => {
|
|
const savedYear = localStorage.getItem('selectedYear');
|
|
const savedMonth = localStorage.getItem('selectedMonth');
|
|
|
|
document.getElementById('jahr').value = savedYear || new Date().getFullYear();
|
|
document.getElementById('monat').value = savedMonth || String(new Date().getMonth() + 1).padStart(2, '0');
|
|
|
|
loadData();
|
|
});
|
|
|
|
document.getElementById('jahr').addEventListener('change', loadData);
|
|
document.getElementById('monat').addEventListener('change', loadData);
|
|
document.getElementById('eintrag').addEventListener('click', addNewEntry);
|
|
document.getElementById('export').addEventListener('click', async () => {
|
|
try {
|
|
const res = await fetch('/api/ordner-oeffnen');
|
|
const data = await res.json();
|
|
console.log(data.message);
|
|
} catch (err) {
|
|
console.error('Fehler beim Öffnen des Ordners:', err);
|
|
alert('Ordner konnte nicht geöffnet werden');
|
|
}
|
|
});
|
|
document.getElementById('path').addEventListener('click', async () => {
|
|
try {
|
|
const res = await fetch('/api/pfad-aendern', { method: 'POST' });
|
|
const data = await res.json();
|
|
alert(`Pfad geändert: ${data.path || 'Abgebrochen'}`);
|
|
} catch (err) {
|
|
console.error(err);
|
|
alert('Fehler beim Ändern des Pfades');
|
|
}
|
|
});
|
|
|
|
|
|
function zeigeNachricht(text, typ = 'erfolg') {
|
|
const nachrichtContainer = document.getElementById('nachricht-container');
|
|
nachrichtContainer.textContent = text;
|
|
nachrichtContainer.className = `nachricht ${typ}`;
|
|
nachrichtContainer.style.display = 'block';
|
|
setTimeout(() => nachrichtContainer.style.display = 'none', 3000);
|
|
}
|
|
|
|
function getMonthName(monthNumber) {
|
|
const months = ['Januar','Februar','März','April','Mai','Juni','Juli','August','September','Oktober','November','Dezember'];
|
|
return months[parseInt(monthNumber)-1];
|
|
}
|
|
|
|
async function loadData() {
|
|
const selectedYear = document.getElementById('jahr').value;
|
|
const selectedMonth = document.getElementById('monat').value;
|
|
|
|
localStorage.setItem('selectedYear', selectedYear);
|
|
localStorage.setItem('selectedMonth', selectedMonth);
|
|
|
|
const tableBody = document.querySelector('#buchhaltung-tabelle tbody');
|
|
tableBody.innerHTML = '';
|
|
|
|
try {
|
|
const response = await fetch(`/api/daten/${selectedYear}/${selectedMonth}`);
|
|
let data = [];
|
|
|
|
if (response.ok) {
|
|
data = await response.json();
|
|
} else {
|
|
console.warn('Daten nicht gefunden, erzeuge leere Tabelle');
|
|
}
|
|
|
|
if (!data || data.length === 0) {
|
|
addNewEntry(true);
|
|
zeigeNachricht(`Für den Monat ${getMonthName(selectedMonth)} gibt es keine Daten!`, 'fehler');
|
|
} else {
|
|
data.forEach((row, idx) => {
|
|
const tr = document.createElement('tr');
|
|
tr.dataset.rowIndex = idx;
|
|
|
|
row.forEach(cell => {
|
|
const td = document.createElement('td');
|
|
td.contentEditable = true;
|
|
td.textContent = cell || '';
|
|
tr.appendChild(td);
|
|
});
|
|
|
|
const betragZelle = tr.querySelector('td');
|
|
betragZelle.addEventListener('blur', () => {
|
|
betragZelle.textContent = formatAsEuro(betragZelle.textContent);
|
|
});
|
|
|
|
tr.appendChild(createButtonCell(tr));
|
|
tableBody.appendChild(tr);
|
|
});
|
|
}
|
|
|
|
updateSumme();
|
|
} catch (err) {
|
|
console.error(err);
|
|
addNewEntry(true);
|
|
updateSumme();
|
|
zeigeNachricht('Keine Verbindung zum Server - arbeite offline.', 'fehler');
|
|
}
|
|
}
|
|
|
|
function addNewEntry(suppressMessage = false) {
|
|
const tableBody = document.querySelector('#buchhaltung-tabelle tbody');
|
|
const tr = document.createElement('tr');
|
|
const rowIndex = tableBody.children.length;
|
|
tr.dataset.rowIndex = rowIndex;
|
|
|
|
const today = new Date();
|
|
const formattedDate = `${String(today.getDate()).padStart(2,'0')}.${String(today.getMonth()+1).padStart(2,'0')}.${today.getFullYear()}`;
|
|
|
|
const ausgabeTd = createEditableCell();
|
|
ausgabeTd.addEventListener('blur', () => ausgabeTd.textContent = formatAsEuro(ausgabeTd.textContent));
|
|
const kategorieTd = createEditableCell();
|
|
const datumTd = document.createElement('td');
|
|
datumTd.textContent = formattedDate;
|
|
datumTd.contentEditable = false;
|
|
|
|
tr.appendChild(ausgabeTd);
|
|
tr.appendChild(kategorieTd);
|
|
tr.appendChild(datumTd);
|
|
tr.appendChild(createButtonCell(tr));
|
|
|
|
tableBody.appendChild(tr);
|
|
if (!suppressMessage) zeigeNachricht('Neue Zeile hinzugefügt!', 'erfolg');
|
|
}
|
|
|
|
function createEditableCell() {
|
|
const td = document.createElement('td');
|
|
td.contentEditable = true;
|
|
return td;
|
|
}
|
|
|
|
function createButtonCell(tr) {
|
|
const td = document.createElement('td');
|
|
td.style.textAlign = 'center';
|
|
td.innerHTML = `<button class="speichern-btn">Speichern</button><button class="loeschen-btn">Löschen</button>`;
|
|
|
|
td.querySelector('.speichern-btn').addEventListener('click', () => saveRowData(tr));
|
|
td.querySelector('.loeschen-btn').addEventListener('click', () => handleDeleteButtonClick(tr));
|
|
|
|
return td;
|
|
}
|
|
|
|
async function saveRowData(tr) {
|
|
const rowIndex = parseInt(tr.dataset.rowIndex, 10);
|
|
const updatedRowData = Array.from(tr.querySelectorAll('td')).slice(0, -1).map(td => td.textContent);
|
|
|
|
// Immer aktuelle Dropdown-Werte nehmen
|
|
const selectedYear = document.getElementById('jahr').value;
|
|
const selectedMonth = document.getElementById('monat').value;
|
|
|
|
// In LocalStorage speichern
|
|
localStorage.setItem('selectedYear', selectedYear);
|
|
localStorage.setItem('selectedMonth', selectedMonth);
|
|
|
|
try {
|
|
const response = await fetch('/api/zeile-speichern', {
|
|
method: 'POST',
|
|
headers: {'Content-Type': 'application/json'},
|
|
body: JSON.stringify({
|
|
rowIndex,
|
|
updatedRowData,
|
|
jahr: selectedYear,
|
|
monat: selectedMonth
|
|
})
|
|
});
|
|
|
|
if (!response.ok) {
|
|
const errData = await response.json();
|
|
throw new Error(errData.error || 'Fehler beim Speichern');
|
|
}
|
|
|
|
zeigeNachricht('Daten gespeichert!', 'erfolg');
|
|
} catch (err) {
|
|
console.error(err);
|
|
zeigeNachricht(`Fehler beim Speichern der Zeile: ${err.message}`, 'fehler');
|
|
}
|
|
updateSumme();
|
|
}
|
|
|
|
|
|
function handleDeleteButtonClick(tr) {
|
|
const popup = document.getElementById('confirm-popup');
|
|
const yes = document.getElementById('confirm-yes');
|
|
const no = document.getElementById('confirm-no');
|
|
if (!popup) return console.error('Popup nicht gefunden!');
|
|
|
|
popup.style.display = 'grid';
|
|
yes.replaceWith(yes.cloneNode(true));
|
|
no.replaceWith(no.cloneNode(true));
|
|
|
|
document.getElementById('confirm-yes').addEventListener('click', () => { deleteRow(tr); popup.style.display='none'; });
|
|
document.getElementById('confirm-no').addEventListener('click', () => popup.style.display='none');
|
|
}
|
|
|
|
async function deleteRow(tr) {
|
|
const rowIndex = parseInt(tr.dataset.rowIndex, 10);
|
|
const selectedYear = document.getElementById('jahr').value;
|
|
const selectedMonth = document.getElementById('monat').value;
|
|
|
|
try {
|
|
const response = await fetch('/api/zeile-loeschen', {
|
|
method: 'POST',
|
|
headers: {'Content-Type':'application/json'},
|
|
body: JSON.stringify({
|
|
zeileIndex: rowIndex, // korrekt benennen
|
|
jahr: localStorage.getItem('selectedYear'),
|
|
monat: localStorage.getItem('selectedMonth')
|
|
})
|
|
});
|
|
if (!response.ok) throw new Error((await response.json()).error || 'Fehler beim Löschen');
|
|
tr.remove();
|
|
updateSumme();
|
|
zeigeNachricht('Zeile erfolgreich gelöscht!', 'erfolg');
|
|
} catch (err) {
|
|
console.error(err);
|
|
zeigeNachricht(`Fehler: ${err.message}`, 'fehler');
|
|
}
|
|
}
|
|
|
|
function updateSumme() {
|
|
const rows = document.querySelectorAll('#buchhaltung-tabelle tbody tr');
|
|
let summe = 0;
|
|
|
|
rows.forEach(row => {
|
|
let val = row.querySelector('td').textContent.trim();
|
|
|
|
// Punkte als Tausender-Trennzeichen entfernen
|
|
val = val.replace(/\./g, '');
|
|
|
|
// Komma als Dezimaltrennzeichen in Punkt konvertieren
|
|
val = val.replace(',', '.');
|
|
|
|
const num = parseFloat(val);
|
|
summe += isNaN(num) ? 0 : num;
|
|
});
|
|
|
|
const summeZelle = document.getElementById('summe-zelle');
|
|
if (summeZelle) summeZelle.textContent = `Summe: ${new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(summe)}`;
|
|
}
|
|
|
|
document.getElementById('suche').addEventListener('input', function() {
|
|
const term = this.value.toLowerCase().trim();
|
|
document.querySelectorAll('#buchhaltung-tabelle tbody tr').forEach(row => {
|
|
const kategorie = row.querySelectorAll('td')[1]?.textContent.toLowerCase().trim();
|
|
row.style.display = kategorie?.includes(term) ? '' : 'none';
|
|
});
|
|
});
|
|
|
|
function formatAsEuro(value) {
|
|
const parsed = parseFloat(value.replace(/[^\d,.-]/g,'').replace(',','.'));
|
|
if (isNaN(parsed)) return '';
|
|
return new Intl.NumberFormat('de-DE',{style:'currency',currency:'EUR',minimumFractionDigits:2,maximumFractionDigits:2}).format(parsed);
|
|
}
|