feat: deutsche Betragsanzeige (eur-Filter) und deutsche GUI-Labels
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -13,8 +13,8 @@
|
||||
{% for r in recurring %}
|
||||
<tr>
|
||||
<td>{{ r.name }}</td>
|
||||
<td class="{{ 'neg' if r.amount < 0 else '' }}">{{ '%.2f'|format(r.amount) }} €</td>
|
||||
<td>{{ r.rhythm }}</td>
|
||||
<td class="{{ 'neg' if r.amount < 0 else '' }}">{{ r.amount|eur }} €</td>
|
||||
<td>{{ r.rhythm|de_label }}</td>
|
||||
<td>{{ r.due_day }}</td>
|
||||
<td>{{ category_names.get(r.category_id, '–') }}</td>
|
||||
<td>
|
||||
@@ -39,7 +39,7 @@
|
||||
<label>Betrag <input type="text" name="amount" placeholder="-49.99" required></label>
|
||||
<label>Rhythmus
|
||||
<select name="rhythm" data-type="str">
|
||||
{% for rh in rhythms %}<option value="{{ rh }}">{{ rh }}</option>{% endfor %}
|
||||
{% for rh in rhythms %}<option value="{{ rh }}">{{ rh|de_label }}</option>{% endfor %}
|
||||
</select>
|
||||
</label>
|
||||
<label>Fälligkeitstag <input type="number" name="due_day" data-type="int" min="1" max="31" required></label>
|
||||
@@ -64,8 +64,8 @@
|
||||
{% for s in suggestions %}
|
||||
<tr>
|
||||
<td>{{ s.name }}</td>
|
||||
<td class="{{ 'neg' if s.amount < 0 else '' }}">{{ '%.2f'|format(s.amount) }} €</td>
|
||||
<td>{{ s.rhythm }}</td>
|
||||
<td class="{{ 'neg' if s.amount < 0 else '' }}">{{ s.amount|eur }} €</td>
|
||||
<td>{{ s.rhythm|de_label }}</td>
|
||||
<td>{{ s.due_day }}</td>
|
||||
<td>
|
||||
<form class="inline-form" hx-ext="json-form" hx-post="/api/recurring" hx-swap="none"
|
||||
@@ -98,7 +98,7 @@
|
||||
{% for p in planned %}
|
||||
<tr>
|
||||
<td>{{ p.name }}</td>
|
||||
<td class="{{ 'neg' if p.amount < 0 else '' }}">{{ '%.2f'|format(p.amount) }} €</td>
|
||||
<td class="{{ 'neg' if p.amount < 0 else '' }}">{{ p.amount|eur }} €</td>
|
||||
<td>{{ p.due.strftime('%d.%m.%Y') }}</td>
|
||||
<td>{{ category_names.get(p.category_id, '–') }}</td>
|
||||
<td>
|
||||
@@ -143,11 +143,11 @@
|
||||
{% for l in loans %}
|
||||
<tr>
|
||||
<td>{{ l.name }}</td>
|
||||
<td>{{ '%.2f'|format(l.principal) }} €</td>
|
||||
<td>{{ '%.2f'|format(l.annual_rate_pct) }} %</td>
|
||||
<td>{{ l.principal|eur }} €</td>
|
||||
<td>{{ l.annual_rate_pct|eur }} %</td>
|
||||
<td>{{ l.term_months }} Monate</td>
|
||||
<td>{{ l.payout_date.strftime('%d.%m.%Y') }}</td>
|
||||
<td>{{ l.repayment_type }}</td>
|
||||
<td>{{ l.repayment_type|de_label }}</td>
|
||||
<td>
|
||||
<form class="inline-form" hx-delete="/api/loans/{{ l.id }}" hx-swap="none"
|
||||
hx-confirm="„{{ l.name }}“ wirklich löschen?"
|
||||
@@ -181,7 +181,7 @@
|
||||
<label>Auszahlungsdatum <input type="date" name="payout_date" required></label>
|
||||
<label>Tilgungsart
|
||||
<select name="repayment_type" data-type="str">
|
||||
{% for rt in repayment_types %}<option value="{{ rt }}">{{ rt }}</option>{% endfor %}
|
||||
{% for rt in repayment_types %}<option value="{{ rt }}">{{ rt|de_label }}</option>{% endfor %}
|
||||
</select>
|
||||
</label>
|
||||
<button type="submit">Anlegen</button>
|
||||
@@ -227,8 +227,8 @@
|
||||
{% if m.target_type == "category" %}Kategorie: {{ category_names.get(m.target_id, m.target_id) }}
|
||||
{% else %}Posten: {{ recurring_names.get(m.target_id, m.target_id) }}{% endif %}
|
||||
</td>
|
||||
<td>{{ m.kind }}</td>
|
||||
<td>{{ '%.2f'|format(m.value) }}</td>
|
||||
<td>{{ m.kind|de_label }}</td>
|
||||
<td>{{ m.value|eur }}</td>
|
||||
<td>
|
||||
<form class="inline-form" hx-delete="/api/scenarios/{{ sc.id }}/modifiers/{{ m.id }}" hx-swap="none"
|
||||
hx-on::after-request="if(event.detail.successful){window.location.reload()}">
|
||||
@@ -266,7 +266,7 @@
|
||||
</span>
|
||||
<label>Art
|
||||
<select name="kind" data-type="str">
|
||||
{% for k in modifier_kinds %}<option value="{{ k }}">{{ k }}</option>{% endfor %}
|
||||
{% for k in modifier_kinds %}<option value="{{ k }}">{{ k|de_label }}</option>{% endfor %}
|
||||
</select>
|
||||
</label>
|
||||
<label>Wert <input type="text" name="value" value="0"></label>
|
||||
@@ -281,7 +281,7 @@
|
||||
|
||||
{% if row.result %}
|
||||
<p>
|
||||
Tiefpunkt: {{ '%.2f'|format(row.result.low_point_balance) }} € am {{ row.result.low_point_date.strftime('%d.%m.%Y') }}<br>
|
||||
Tiefpunkt: {{ row.result.low_point_balance|eur }} € am {{ row.result.low_point_date.strftime('%d.%m.%Y') }}<br>
|
||||
{% if row.result.below_zero_date %}Unterschreitet 0 € ab {{ row.result.below_zero_date.strftime('%d.%m.%Y') }}<br>{% endif %}
|
||||
{% if row.result.below_threshold_date %}Unterschreitet Warnschwelle ab {{ row.result.below_threshold_date.strftime('%d.%m.%Y') }}<br>{% endif %}
|
||||
Kurven in <a href="http://{{ request.url.hostname or '127.0.0.1' }}:8097" target="_blank" rel="noopener">Grafana</a> ansehen.
|
||||
@@ -343,6 +343,9 @@
|
||||
var parts = iso.split('-');
|
||||
return parts[2] + '.' + parts[1] + '.' + parts[0];
|
||||
}
|
||||
function fmtEur(n) {
|
||||
return Number(n).toLocaleString('de-DE', {minimumFractionDigits: 2, maximumFractionDigits: 2});
|
||||
}
|
||||
function loadLoanSchedule(loanId) {
|
||||
if (loadedSchedules[loanId]) return;
|
||||
loadedSchedules[loanId] = true;
|
||||
@@ -353,10 +356,10 @@
|
||||
+ '<th>Tilgung</th><th>Restschuld</th></tr></thead><tbody>';
|
||||
rows.forEach(function (r) {
|
||||
html += '<tr><td>' + formatIsoDate(r.due) + '</td>'
|
||||
+ '<td>' + Number(r.payment).toFixed(2) + ' €</td>'
|
||||
+ '<td>' + Number(r.interest).toFixed(2) + ' €</td>'
|
||||
+ '<td>' + Number(r.principal).toFixed(2) + ' €</td>'
|
||||
+ '<td>' + Number(r.remaining).toFixed(2) + ' €</td></tr>';
|
||||
+ '<td>' + fmtEur(r.payment) + ' €</td>'
|
||||
+ '<td>' + fmtEur(r.interest) + ' €</td>'
|
||||
+ '<td>' + fmtEur(r.principal) + ' €</td>'
|
||||
+ '<td>' + fmtEur(r.remaining) + ' €</td></tr>';
|
||||
});
|
||||
html += '</tbody></table>';
|
||||
document.getElementById('schedule-' + loanId).innerHTML = html;
|
||||
|
||||
Reference in New Issue
Block a user