Steuerkram/src/Views/belege/_vorschau.php

212 lines
13 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php use Steuerkram\View; ?>
<!-- Split-Pane: Vorschau + Buchungsformular -->
<div class="beleg-layout" id="beleg-split-layout">
<!-- Linke Seite: Dokumentvorschau -->
<div class="beleg-preview" id="beleg-preview-pane">
<?php if (in_array($beleg['mime_type'], ['application/pdf'])): ?>
<iframe src="/belege/<?= $h($beleg['id']) ?>/file" title="Belegvorschau"></iframe>
<?php elseif (str_starts_with($beleg['mime_type'], 'image/')): ?>
<div class="img-zoom-controls">
<button type="button" class="btn btn-secondary btn-sm" onclick="imgZoom(-1)" title="Verkleinern (Strg+–)">−</button>
<button type="button" class="btn btn-secondary btn-sm" onclick="imgZoom(+1)" title="Vergrößern (Strg++)">+</button>
<button type="button" class="btn btn-secondary btn-sm" onclick="imgZoomReset()" title="Zurücksetzen (Strg+0)">↺</button>
<span id="img-zoom-level">100 %</span>
</div>
<div id="img-zoom-wrap" class="img-zoom-wrap">
<img id="beleg-img" src="/belege/<?= $h($beleg['id']) ?>/file" alt="Belegvorschau">
</div>
<?php elseif (str_contains($beleg['mime_type'], 'xml')): ?>
<div style="padding:1.5rem">
<div class="badge badge-blue mb-2">XML / eRechnung</div>
<p class="text-muted text-sm">XML-Datei kann nicht direkt angezeigt werden.</p>
<a href="/belege/<?= $h($beleg['id']) ?>/file" class="btn btn-secondary mt-2" download>XML herunterladen</a>
</div>
<?php endif; ?>
</div>
<!-- Trennlinie (Drag-Handle) -->
<div class="split-handle" id="beleg-split-handle" title="Ziehen zum Anpassen der Breite"></div>
<!-- Rechte Seite: Buchungen -->
<div class="beleg-layout-right">
<!-- Vorhandene Buchungen -->
<div class="card mb-2">
<div class="card-header">
<div class="card-title">Buchungszeilen (<?= count($bookings) ?>)</div>
</div>
<div class="table-wrap">
<table>
<thead>
<tr>
<th>Buchungsnr.<br>Datum<br>Typ</th>
<th>Kategorie</th>
<th>Zahlungskonto</th>
<th class="td-right">Wert</th>
<th>Text</th>
<th></th>
</tr>
</thead>
<tbody>
<?php foreach ($bookings as $bk):
$isReversed = !empty($bk['reversed_by']);
$isReversal = (bool)$bk['is_reversal'];
?>
<tr style="<?= ($isReversed || $isReversal) ? 'opacity:.55;background:#fff5f5' : '' ?>">
<td class="td-mono text-sm">
<?= $h($bk['buchungs_nr']) ?><br>
<span class="td-muted"><?= View::formatDate($bk['buchungs_datum']) ?></span><br>
<span class="badge <?= $bk['buchungstyp'] === 'Einnahme' ? 'badge-green' : 'badge-red' ?>"><?= $h($bk['buchungstyp']) ?></span>
</td>
<td class="td-mono text-sm"><?= $h($bk['kategorie_nr']) ?><br><span class="td-muted"><?= $h($bk['kategorie_name']) ?></span></td>
<td class="td-mono text-sm"><?= $h($bk['zahlungs_nr']) ?><br><span class="td-muted"><?= $h($bk['zahlungs_name']) ?></span></td>
<td class="td-right td-mono"><?= $fmt($bk['betrag_netto']) ?></td>
<td class="text-sm">
<?= $h($bk['buchungstext']) ?>
<?php if ($isReversal): ?>
<span class="badge badge-red">Storno</span>
<?php elseif ($isReversed): ?>
<span class="badge badge-red">Storniert</span>
<?php endif; ?>
</td>
<td>
<?php if (!$bk['locked'] && !$isReversal && !$isReversed): ?>
<div style="display:flex;gap:.35rem">
<button type="button" class="btn btn-danger btn-sm"
data-modal-open="modal-storno-<?= $h($bk['id']) ?>">
Storno
</button>
<?php if ($testMode): ?>
<form method="post" action="/bookings/<?= $h($bk['id']) ?>/delete"
data-confirm="Buchung <?= $h($bk['buchungs_nr']) ?> wirklich löschen? (Nur im Testmodus – nicht GoBD-konform!)">
<input type="hidden" name="beleg_id" value="<?= $h($beleg['id']) ?>">
<button type="submit" class="btn btn-danger btn-sm" title="Löschen (Testmodus)">
Löschen
</button>
</form>
<?php endif; ?>
</div>
<!-- Storno-Modal -->
<div class="modal-overlay" id="modal-storno-<?= $h($bk['id']) ?>">
<div class="modal">
<div class="modal-title">Buchung stornieren</div>
<p class="text-sm text-muted mb-2">Die Buchung <?= $h($bk['buchungs_nr']) ?> wird durch eine Gegenbuchung storniert (GoBD-konform).</p>
<form method="post" action="/bookings/<?= $h($bk['id']) ?>/reverse">
<div class="form-group">
<label>Stornogrund</label>
<input type="text" name="reason" required placeholder="Grund für die Stornierung">
</div>
<div class="modal-actions">
<button type="button" class="btn btn-secondary" data-modal-close>Abbrechen</button>
<button type="submit" class="btn btn-danger">Stornieren</button>
</div>
</form>
</div>
</div>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
<?php if (empty($bookings)): ?>
<tr><td colspan="6" class="text-center text-muted" style="padding:1rem">Noch keine Buchungen.</td></tr>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
<!-- Gespeicherte Bankbuchungs-Verknüpfung -->
<?php if ($linkedBankTx ?? null): ?>
<?php $lbt = $linkedBankTx; $lbwert = (float)$lbt['wert']; ?>
<div class="card mb-2" style="border-left:4px solid var(--color-success)">
<div class="card-body" style="padding:.6rem 1.25rem">
<div style="display:flex;align-items:center;gap:.75rem;flex-wrap:wrap">
<span class="badge badge-green" style="font-size:.8rem">Bankbuchung</span>
<a href="/bank/<?= (int)$lbt['id'] ?>" style="display:contents;text-decoration:none;color:inherit">
<span class="td-mono text-sm"><?= View::formatDate($lbt['wertstellung']) ?></span>
<?php if ($lbt['vorgang']): ?>
<span class="text-sm text-muted"><?= $h($lbt['vorgang']) ?></span>
<?php endif; ?>
<span class="text-sm" style="flex:1;min-width:0;display:inline-flex;align-items:baseline;gap:.35rem;overflow:hidden">
<?php if (!empty($lbt['kuerzel'])): ?>
<?php $kf = $lbt['farbe'] ?? '#6366f1'; ?>
<span class="kuerzel-badge" style="background:<?= $h($kf) ?>;color:<?= $kTextClr($kf) ?>"><?= $h($lbt['kuerzel']) ?></span>
<?php endif; ?>
<span style="overflow:hidden;text-overflow:ellipsis;white-space:nowrap"
title="<?= $h($lbt['buchungstext']) ?>"><?= $h($lbt['buchungstext']) ?></span>
</span>
<strong style="white-space:nowrap;color:<?= $lbwert >= 0 ? 'var(--color-success)' : 'var(--color-danger)' ?>">
<?= $lbwert >= 0 ? '+' : '' ?><?= number_format($lbwert, 2, ',', '.') ?> €
<?php if (!empty($lbt['alloc_betrag']) && (float)$lbt['alloc_betrag'] !== abs($lbwert)): ?>
<span class="text-muted" style="font-weight:normal;font-size:.85em">
(zugeordnet: <?= number_format((float)$lbt['alloc_betrag'], 2, ',', '.') ?> €)
</span>
<?php endif; ?>
</strong>
</a>
<form method="post" action="/bank/<?= (int)$lbt['id'] ?>/unlink"
data-confirm="Verknüpfung mit dieser Bankbuchung wirklich aufheben?">
<input type="hidden" name="beleg_id" value="<?= (int)$beleg['id'] ?>">
<input type="hidden" name="redirect_to" value="/belege/<?= (int)$beleg['id'] ?>">
<button type="submit" class="btn btn-secondary btn-sm">Verknüpfung aufheben</button>
</form>
</div>
</div>
</div>
<?php endif; ?>
<!-- BankBuchung-Badge (ersetzt KI-Badge wenn aus Bank-Kontext) -->
<?php if (!$beleg['locked'] && ($bankTx ?? null)): ?>
<div class="card mb-2" style="border-left:4px solid var(--color-primary,#3b82f6)">
<div class="card-body" style="padding:.75rem 1.25rem">
<div style="display:flex;align-items:center;gap:.75rem;flex-wrap:wrap">
<span class="badge badge-blue" style="font-size:.8rem">Bankbuchung</span>
<span class="td-mono text-sm"><?= View::formatDate($bankTx['wertstellung']) ?></span>
<span class="text-sm"><?= $h($bankTx['vorgang']) ?></span>
<span class="text-sm" style="flex:1;min-width:0;display:inline-flex;align-items:baseline;gap:.35rem;overflow:hidden">
<?php if (!empty($bankTx['kuerzel'])): ?>
<?php $kf = $bankTx['farbe'] ?? '#6366f1'; ?>
<span class="kuerzel-badge" style="background:<?= $h($kf) ?>;color:<?= $kTextClr($kf) ?>"><?= $h($bankTx['kuerzel']) ?></span>
<?php endif; ?>
<span style="overflow:hidden;text-overflow:ellipsis;white-space:nowrap"
title="<?= $h($bankTx['buchungstext']) ?>"><?= $h($bankTx['buchungstext']) ?></span>
</span>
<?php $bwert = (float)$bankTx['wert']; ?>
<strong style="color:<?= $bwert >= 0 ? 'var(--color-success)' : 'var(--color-danger)' ?>;white-space:nowrap">
<?= $bwert >= 0 ? '+' : '' ?><?= number_format($bwert, 2, ',', '.') ?> €
</strong>
</div>
</div>
</div>
<?php elseif (!$beleg['locked'] && ($kiSektion ?? false)): ?>
<!-- KI-Kontierungsvorschlag -->
<div id="ki-badge" style="margin-bottom:1rem"
data-beleg-id="<?= $h($beleg['id']) ?>"
data-ki-aktiv="<?= $h(json_encode((bool)($kiAktiv ?? false))) ?>"
data-ki-vorschlag="<?= $h(json_encode($kiVorschlag ?? null)) ?>"></div>
<?php endif; ?>
<!-- Buchungsvorlagen-Badge -->
<?php if (!$beleg['locked'] && !empty($vorlagen)): ?>
<div class="card mb-2" style="border-left:4px solid var(--color-warning,#f59e0b);margin-bottom:.75rem">
<div class="card-body" style="padding:.65rem 1.25rem">
<div style="display:flex;align-items:center;gap:.75rem">
<span class="badge badge-yellow" style="font-size:.8rem;white-space:nowrap">Vorlage</span>
<select id="vorlage-select"
data-beleg-id="<?= $h($beleg['id']) ?>"
<?php if (!empty($bankTx)): ?>data-bank-tx="<?= $h($bankTx['id']) ?>"<?php endif; ?>
class="form-control form-control-sm" style="flex:1;max-width:340px">
<option value="">— Vorlage auswählen —</option>
<?php foreach ($vorlagen as $v): ?>
<option value="<?= $h($v['id']) ?>"><?= $h($v['name']) ?></option>
<?php endforeach; ?>
</select>
</div>
</div>
</div>
<div id="vorlage-modal-container"></div>
<?php endif; ?>