Jedes Zahlenfeld (inputmode="decimal") zeigt rechts ein Rechnersymbol. Klick darauf oder Alt+R öffnet einen Taschenrechner mit Grundrechenarten und Klammern, komplett per Tastatur bedienbar: Ziffern, + - * / ( ), Backspace, Entf, Pfeiltasten, C löscht alles, = setzt das Ergebnis ein, Enter überträgt ins Feld, Escape schließt und fokussiert das Feld. Das Ergebnis steht nach jedem Tastendruck unter der Rechnung. Das Symbol ist ein Hintergrundbild (kein Wrapper-Element, kein Eingriff in die Layouts); gerechnet wird mit eigenem Parser statt eval. In modalen Dialogen wandert der Rechner mit hinein. Stück/Kurs übernehmen 6, Zinssätze 3 Nachkommastellen. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
265 lines
12 KiB
PHP
265 lines
12 KiB
PHP
<?php
|
||
|
||
use Finanzmanager\Models\Kredit;
|
||
use Finanzmanager\View;
|
||
|
||
/**
|
||
* @var list<array<string,mixed>> $kredite
|
||
* @var array<string,mixed>|null $kredit
|
||
* @var array<string,mixed>|null $plan
|
||
* @var list<array<string,mixed>> $konten
|
||
* @var string $csrfToken
|
||
*/
|
||
|
||
include __DIR__ . '/../layout/kopf.php';
|
||
?>
|
||
|
||
<div class="tableiste">
|
||
<a href="/vertraege" class="tab">Verträge</a>
|
||
<a href="/vertraege/adressen" class="tab">Adressen</a>
|
||
<a href="/vertraege/sparziele" class="tab">Sparziele</a>
|
||
<span class="tab aktiv" title="Annuitätendarlehen mit gleichbleibender Rate: Der Zinsanteil sinkt, die Tilgung wächst. Der Tilgungsplan wird aus Betrag, Zins, Rate und Beginn gerechnet, nicht gespeichert.">Kredite</span>
|
||
</div>
|
||
|
||
<div class="seitenaktionen">
|
||
<button type="button" class="knopf primaer" id="neu-knopf" data-neudialog="neudialog">+ Neu</button>
|
||
</div>
|
||
|
||
<?php if ($kredite !== []): ?>
|
||
<table class="liste zahlen">
|
||
<thead>
|
||
<tr>
|
||
<th>Kredit</th><th class="rechts">Darlehen</th><th class="rechts">Zins</th>
|
||
<th class="rechts">Rate</th><th>Rhythmus</th><th class="rechts">Restschuld heute</th>
|
||
<th class="rechts">Aktion</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<?php foreach ($kredite as $eintrag): ?>
|
||
<tr<?= (int)$eintrag['aktiv'] === 1 ? '' : ' class="inaktiv"' ?>>
|
||
<td>
|
||
<a href="/vertraege/kredite?kredit=<?= (int)$eintrag['id'] ?>">
|
||
<?= View::h($eintrag['name']) ?>
|
||
</a>
|
||
</td>
|
||
<td class="rechts"><?= View::betrag($eintrag['darlehensbetrag']) ?></td>
|
||
<td class="rechts"><?= View::h(number_format((float)$eintrag['zinssatz'], 2, ',', '.')) ?> %</td>
|
||
<td class="rechts"><?= View::betrag($eintrag['rate']) ?></td>
|
||
<td><?= View::h(Kredit::RHYTHMUS_NAMEN[$eintrag['rhythmus']] ?? $eintrag['rhythmus']) ?></td>
|
||
<td class="rechts"><?= View::betrag($eintrag['restschuld']) ?></td>
|
||
<td class="rechts">
|
||
<form method="post" action="/vertraege/kredite/<?= (int)$eintrag['id'] ?>/loeschen"
|
||
class="inline" data-bestaetigen="Kredit „<?= View::h($eintrag['name']) ?>“ löschen?">
|
||
<input type="hidden" name="csrf_token" value="<?= View::h($csrfToken) ?>">
|
||
<button type="submit" class="knopf klein gefahr">Löschen</button>
|
||
</form>
|
||
</td>
|
||
</tr>
|
||
<?php endforeach; ?>
|
||
</tbody>
|
||
</table>
|
||
<?php endif; ?>
|
||
|
||
<?php if ($kredit !== null && $plan !== null): ?>
|
||
<h3>Tilgungsplan: <?= View::h($kredit['name']) ?></h3>
|
||
|
||
<?php if (!$plan['tilgt']): ?>
|
||
<p class="meldung meldung-fehler" role="status">
|
||
Die Rate deckt nicht einmal die Zinsen der ersten Periode – so würde die
|
||
Restschuld wachsen statt zu sinken. Bitte Rate oder Zinssatz prüfen.
|
||
</p>
|
||
<?php else: ?>
|
||
<div class="kennzahlenleiste">
|
||
<div class="kennzahlkachel">
|
||
<span class="kennzahltitel">Laufzeit</span>
|
||
<span class="kennzahl"><?= (int)round($plan['laufzeit_monate'] / 12) ?> J.</span>
|
||
<span class="nebentext"><?= (int)$plan['laufzeit_monate'] ?> Monate</span>
|
||
</div>
|
||
<div class="kennzahlkachel">
|
||
<span class="kennzahltitel">Letzte Rate</span>
|
||
<span class="kennzahl klein"><?= View::h(View::datum($plan['letzte_rate_am'])) ?></span>
|
||
</div>
|
||
<div class="kennzahlkachel">
|
||
<span class="kennzahltitel">Zinsen gesamt</span>
|
||
<span class="kennzahl negativ"><?= View::betrag($plan['zinsen']) ?></span>
|
||
</div>
|
||
<?php if ($plan['restschuld_zinsbindung'] !== null): ?>
|
||
<div class="kennzahlkachel">
|
||
<span class="kennzahltitel">Rest bei Zinsbindungsende</span>
|
||
<span class="kennzahl"><?= View::betrag($plan['restschuld_zinsbindung']) ?></span>
|
||
</div>
|
||
<?php endif; ?>
|
||
</div>
|
||
|
||
<?php
|
||
// Bei langen Laufzeiten sind alle Raten zu viel; gezeigt werden die
|
||
// nächsten zwei Jahre und das Ende.
|
||
$zeilen = $plan['zeilen'];
|
||
$gekuerzt = count($zeilen) > 30;
|
||
$anzeige = $gekuerzt
|
||
? array_merge(array_slice($zeilen, 0, 24), array_slice($zeilen, -3))
|
||
: $zeilen;
|
||
?>
|
||
<table class="liste zahlen">
|
||
<thead>
|
||
<tr>
|
||
<th class="rechts">Nr.</th><th>Fällig</th><th class="rechts">Zahlung</th>
|
||
<th class="rechts">Zinsen</th><th class="rechts">Tilgung</th><th class="rechts">Restschuld</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<?php $vorige = 0; ?>
|
||
<?php foreach ($anzeige as $zeile): ?>
|
||
<?php if ($gekuerzt && $zeile['nummer'] > $vorige + 1): ?>
|
||
<tr class="luecke">
|
||
<td colspan="6" class="nebentext">
|
||
… <?= (int)($zeile['nummer'] - $vorige - 1) ?> weitere Raten …
|
||
</td>
|
||
</tr>
|
||
<?php endif; ?>
|
||
<tr>
|
||
<td class="rechts"><?= (int)$zeile['nummer'] ?></td>
|
||
<td><?= View::h(View::datum($zeile['datum'])) ?></td>
|
||
<td class="rechts"><?= View::betrag($zeile['zahlung']) ?></td>
|
||
<td class="rechts"><?= View::betrag($zeile['zinsen']) ?></td>
|
||
<td class="rechts"><?= View::betrag($zeile['tilgung']) ?></td>
|
||
<td class="rechts"><?= View::betrag($zeile['restschuld']) ?></td>
|
||
</tr>
|
||
<?php $vorige = (int)$zeile['nummer']; ?>
|
||
<?php endforeach; ?>
|
||
</tbody>
|
||
</table>
|
||
<?php endif; ?>
|
||
|
||
<form method="post" action="/vertraege/kredite/<?= (int)$kredit['id'] ?>" class="formular breit">
|
||
<input type="hidden" name="csrf_token" value="<?= View::h($csrfToken) ?>">
|
||
<h3>Kredit bearbeiten</h3>
|
||
|
||
<label for="b_name">Name</label>
|
||
<input type="text" id="b_name" name="name" value="<?= View::h($kredit['name']) ?>" required>
|
||
|
||
<div class="feldpaar">
|
||
<div>
|
||
<label for="b_betrag">Darlehensbetrag</label>
|
||
<input type="text" id="b_betrag" name="darlehensbetrag" inputmode="decimal"
|
||
value="<?= View::h(number_format((float)$kredit['darlehensbetrag'], 2, ',', '')) ?>">
|
||
</div>
|
||
<div>
|
||
<label for="b_zins">Zinssatz (%)</label>
|
||
<input type="text" id="b_zins" name="zinssatz" inputmode="decimal" data-nachkommastellen="3"
|
||
value="<?= View::h(number_format((float)$kredit['zinssatz'], 3, ',', '')) ?>">
|
||
</div>
|
||
<div>
|
||
<label for="b_rate">Rate</label>
|
||
<input type="text" id="b_rate" name="rate" inputmode="decimal"
|
||
value="<?= View::h(number_format((float)$kredit['rate'], 2, ',', '')) ?>">
|
||
</div>
|
||
</div>
|
||
|
||
<div class="feldpaar">
|
||
<div>
|
||
<label for="b_rhythmus">Rhythmus</label>
|
||
<select id="b_rhythmus" name="rhythmus">
|
||
<?php foreach (Kredit::RHYTHMUS_NAMEN as $schluessel => $name): ?>
|
||
<option value="<?= View::h($schluessel) ?>"
|
||
<?= $kredit['rhythmus'] === $schluessel ? 'selected' : '' ?>>
|
||
<?= View::h($name) ?>
|
||
</option>
|
||
<?php endforeach; ?>
|
||
</select>
|
||
</div>
|
||
<div>
|
||
<label for="b_beginn">Beginn</label>
|
||
<input type="date" id="b_beginn" name="beginn" value="<?= View::h((string)$kredit['beginn']) ?>">
|
||
</div>
|
||
<div>
|
||
<label for="b_bindung">Zinsbindung bis</label>
|
||
<input type="date" id="b_bindung" name="zinsbindung_bis"
|
||
value="<?= View::h((string)($kredit['zinsbindung_bis'] ?? '')) ?>">
|
||
</div>
|
||
</div>
|
||
|
||
<label for="b_sonder">Jährliche Sondertilgung <span class="optional">(im Dezember)</span></label>
|
||
<input type="text" id="b_sonder" name="sondertilgung" inputmode="decimal"
|
||
value="<?= View::h(number_format((float)$kredit['sondertilgung'], 2, ',', '')) ?>">
|
||
|
||
<label for="b_konto">Konto</label>
|
||
<select id="b_konto" name="konto_id">
|
||
<option value="">– keines –</option>
|
||
<?php foreach ($konten as $konto): ?>
|
||
<option value="<?= (int)$konto['id'] ?>"
|
||
<?= (int)$kredit['konto_id'] === (int)$konto['id'] ? 'selected' : '' ?>>
|
||
<?= View::h($konto['name']) ?>
|
||
</option>
|
||
<?php endforeach; ?>
|
||
</select>
|
||
|
||
<label class="ankreuzfeld">
|
||
<input type="checkbox" name="aktiv" value="1" <?= (int)$kredit['aktiv'] === 1 ? 'checked' : '' ?>>
|
||
aktiv
|
||
</label>
|
||
|
||
<div class="knopfleiste">
|
||
<button type="submit" class="knopf primaer">Speichern</button>
|
||
</div>
|
||
</form>
|
||
<?php endif; ?>
|
||
|
||
<dialog id="neudialog" class="splitdialog neudialog">
|
||
<form method="post" action="/vertraege/kredite/neu" class="formular breit">
|
||
<input type="hidden" name="csrf_token" value="<?= View::h($csrfToken) ?>">
|
||
<h2>Neuer Kredit</h2>
|
||
<p class="feldhinweis">
|
||
Gerechnet wird als Annuitätendarlehen: gleichbleibende Rate, sinkender Zinsanteil.
|
||
Der Tilgungsplan entsteht aus diesen Angaben und wird nicht gespeichert.
|
||
</p>
|
||
|
||
<label for="name">Name</label>
|
||
<input type="text" id="name" name="name" required placeholder="z. B. Baufinanzierung">
|
||
|
||
<div class="feldpaar">
|
||
<div>
|
||
<label for="darlehensbetrag">Darlehensbetrag</label>
|
||
<input type="text" id="darlehensbetrag" name="darlehensbetrag" inputmode="decimal" required>
|
||
</div>
|
||
<div>
|
||
<label for="zinssatz">Zinssatz (%)</label>
|
||
<input type="text" id="zinssatz" name="zinssatz" inputmode="decimal" data-nachkommastellen="3" required>
|
||
</div>
|
||
<div>
|
||
<label for="rate">Rate</label>
|
||
<input type="text" id="rate" name="rate" inputmode="decimal" required>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="feldpaar">
|
||
<div>
|
||
<label for="rhythmus">Rhythmus</label>
|
||
<select id="rhythmus" name="rhythmus">
|
||
<?php foreach (Kredit::RHYTHMUS_NAMEN as $schluessel => $name): ?>
|
||
<option value="<?= View::h($schluessel) ?>"><?= View::h($name) ?></option>
|
||
<?php endforeach; ?>
|
||
</select>
|
||
</div>
|
||
<div>
|
||
<label for="beginn">Beginn</label>
|
||
<input type="date" id="beginn" name="beginn" value="<?= View::h(date('Y-m-d')) ?>" required>
|
||
</div>
|
||
<div>
|
||
<label for="zinsbindung_bis">Zinsbindung bis</label>
|
||
<input type="date" id="zinsbindung_bis" name="zinsbindung_bis">
|
||
</div>
|
||
</div>
|
||
|
||
<label class="ankreuzfeld">
|
||
<input type="checkbox" name="aktiv" value="1" checked> aktiv
|
||
</label>
|
||
|
||
<div class="knopfleiste">
|
||
<button type="submit" class="knopf primaer">Kredit anlegen</button>
|
||
<button type="submit" class="knopf" formmethod="dialog" formnovalidate>Abbrechen</button>
|
||
</div>
|
||
</form>
|
||
</dialog>
|
||
|
||
<?php include __DIR__ . '/../layout/fuss.php'; ?>
|