sdetrjhsae

This commit is contained in:
cay 2026-03-27 13:40:49 +00:00
parent ff7e7441f3
commit 528cbf5436
2 changed files with 32 additions and 18 deletions

View File

@ -163,7 +163,7 @@ router.post('/chargebacks/add', requireAdmin, async (req, res) => {
res.redirect('/admin/finance?success=Rückläufer+eingetragen'); res.redirect('/admin/finance?success=Rückläufer+eingetragen');
} catch (err) { } catch (err) {
console.error(err); console.error(err);
res.redirect('/admin/finance?error=Fehler+beim+Eintragen'); res.redirect('/admin/finance?error=Fehler+beim+Eintragen#chargebacks');
} }
}); });
@ -224,16 +224,16 @@ router.post('/dunning/add', requireAdmin, async (req, res) => {
'INSERT INTO dunning_fees (membership_id, invoice_id, amount, reason, issued_date, notes) VALUES (?,?,?,?,?,?)', 'INSERT INTO dunning_fees (membership_id, invoice_id, amount, reason, issued_date, notes) VALUES (?,?,?,?,?,?)',
[membership_id, invoice_id || null, amount, reason || 'Mahngebühr', issued_date, notes || null] [membership_id, invoice_id || null, amount, reason || 'Mahngebühr', issued_date, notes || null]
); );
res.redirect('/admin/finance?success=Mahngebühr+eingetragen'); res.redirect('/admin/finance?success=Mahngeb%C3%BChr+eingetragen#dunning');
} catch (err) { } catch (err) {
res.redirect('/admin/finance?error=Fehler+beim+Eintragen'); res.redirect('/admin/finance?error=Fehler+beim+Eintragen#chargebacks');
} }
}); });
router.post('/dunning/:id/paid', requireAdmin, async (req, res) => { router.post('/dunning/:id/paid', requireAdmin, async (req, res) => {
try { try {
await db.query("UPDATE dunning_fees SET status='paid', paid_at=NOW() WHERE id=?", [req.params.id]); await db.query("UPDATE dunning_fees SET status='paid', paid_at=NOW() WHERE id=?", [req.params.id]);
res.redirect('/admin/finance?success=Mahngebühr+als+bezahlt+markiert'); res.redirect('/admin/finance?success=Mahngeb%C3%BChr+bezahlt#dunning');
} catch (err) { } catch (err) {
res.redirect('/admin/finance?error=Fehler'); res.redirect('/admin/finance?error=Fehler');
} }
@ -242,7 +242,7 @@ router.post('/dunning/:id/paid', requireAdmin, async (req, res) => {
router.post('/dunning/:id/cancel', requireAdmin, async (req, res) => { router.post('/dunning/:id/cancel', requireAdmin, async (req, res) => {
try { try {
await db.query("UPDATE dunning_fees SET status='cancelled' WHERE id=?", [req.params.id]); await db.query("UPDATE dunning_fees SET status='cancelled' WHERE id=?", [req.params.id]);
res.redirect('/admin/finance?success=Mahngebühr+storniert'); res.redirect('/admin/finance?success=Mahngeb%C3%BChr+storniert#dunning');
} catch (err) { } catch (err) {
res.redirect('/admin/finance?error=Fehler'); res.redirect('/admin/finance?error=Fehler');
} }
@ -270,10 +270,10 @@ router.post('/chargebacks/dunning-all', requireAdmin, async (req, res) => {
); );
count++; count++;
} }
res.redirect(`/admin/finance?success=${count}+Mahngebühren+eingetragen#chargebacks`); res.redirect('/admin/finance?success=Mahngeb%C3%BChren+eingetragen#chargebacks');
} catch (err) { } catch (err) {
console.error(err); console.error(err);
res.redirect('/admin/finance?error=Fehler+beim+Eintragen'); res.redirect('/admin/finance?error=Fehler+beim+Eintragen#chargebacks');
} }
}); });
@ -287,7 +287,7 @@ router.post('/dunning/add-from-chargeback', requireAdmin, async (req, res) => {
'INSERT INTO dunning_fees (membership_id, amount, reason, issued_date, notes) VALUES (?,?,?,?,?)', 'INSERT INTO dunning_fees (membership_id, amount, reason, issued_date, notes) VALUES (?,?,?,?,?)',
[cbs[0].membership_id, amount, reason || 'Mahngebühr Rücklastschrift', issued_date, notes || null] [cbs[0].membership_id, amount, reason || 'Mahngebühr Rücklastschrift', issued_date, notes || null]
); );
res.redirect('/admin/finance?success=Mahngebühr+eingetragen'); res.redirect('/admin/finance?success=Mahngeb%C3%BChr+eingetragen#dunning');
} catch (err) { } catch (err) {
res.redirect('/admin/finance?error=Fehler'); res.redirect('/admin/finance?error=Fehler');
} }

View File

@ -69,12 +69,12 @@
<!-- ===== TABS ===== --> <!-- ===== TABS ===== -->
<div class="finance-tabs"> <div class="finance-tabs">
<button class="ftab active" onclick="showTab('chart')">📈 Umsatzverlauf</button> <button class="ftab active" onclick="showTab('chart', this)">📈 Umsatzverlauf</button>
<button class="ftab" onclick="showTab('open')">🔴 Offene Posten</button> <button class="ftab" onclick="showTab('open', this)">🔴 Offene Posten</button>
<button class="ftab" onclick="showTab('chargebacks')">↩️ Rückläufer</button> <button class="ftab" onclick="showTab('chargebacks', this)">↩️ Rückläufer</button>
<button class="ftab" onclick="showTab('dunning')">📬 Mahngebühren</button> <button class="ftab" onclick="showTab('dunning', this)">📬 Mahngebühren</button>
<button class="ftab" onclick="showTab('expiring')">⏳ Auslaufende Verträge</button> <button class="ftab" onclick="showTab('expiring', this)">⏳ Auslaufende Verträge</button>
<button class="ftab" onclick="showTab('settings')">⚙️ Einstellungen</button> <button class="ftab" onclick="showTab('settings', this)">⚙️ Einstellungen</button>
</div> </div>
<!-- ===== TAB: UMSATZVERLAUF ===== --> <!-- ===== TAB: UMSATZVERLAUF ===== -->
@ -175,8 +175,8 @@
<td> <td>
<div style="display:flex;gap:6px;flex-wrap:wrap"> <div style="display:flex;gap:6px;flex-wrap:wrap">
<% if (c.status === 'open') { %> <% if (c.status === 'open') { %>
<button class="btn btn-sm btn-warning" <button type="button" class="btn btn-sm btn-warning"
onclick="openDunningModal(<%= c.id %>, '<%= c.last_name %>, <%= c.first_name %>', <%= c.amount %>, '<%= c.period %>')"> onclick="openDunningModal(<%= c.id %>, '<%= c.last_name %>, <%= c.first_name %>', <%= c.amount %>, '<%= c.period %>');event.stopPropagation()">
📬 Mahnen 📬 Mahnen
</button> </button>
<form method="POST" action="/admin/finance/chargebacks/<%= c.id %>/resolve" style="display:inline"> <form method="POST" action="/admin/finance/chargebacks/<%= c.id %>/resolve" style="display:inline">
@ -578,13 +578,27 @@ new Chart(ctx, {
}); });
// Tabs // Tabs
function showTab(name) { const tabMap = {
chart: 0, open: 1, chargebacks: 2, dunning: 3, expiring: 4, settings: 5
};
function showTab(name, el) {
document.querySelectorAll('.ftab-content').forEach(t => t.classList.remove('active')); document.querySelectorAll('.ftab-content').forEach(t => t.classList.remove('active'));
document.querySelectorAll('.ftab').forEach(t => t.classList.remove('active')); document.querySelectorAll('.ftab').forEach(t => t.classList.remove('active'));
document.getElementById('tab-' + name).classList.add('active'); document.getElementById('tab-' + name).classList.add('active');
event.target.classList.add('active'); const btn = el || document.querySelectorAll('.ftab')[tabMap[name]];
if (btn) btn.classList.add('active');
history.replaceState(null, '', '#' + name);
} }
// Beim Laden Hash auswerten
document.addEventListener('DOMContentLoaded', () => {
const hash = window.location.hash.replace('#', '');
if (hash && document.getElementById('tab-' + hash)) {
showTab(hash);
}
});
function toggleModal(id) { function toggleModal(id) {
document.getElementById(id).classList.toggle('hidden'); document.getElementById(id).classList.toggle('hidden');
} }