Neues Vorlagen-Badge zwischen Bank-Badge und Buchungsformular in
/belege/{id}. Vorlage auswählen öffnet modalen Dialog mit Feldgruppen
(Metadaten, USt-Zeilen mit Live-Berechnung, Zahlungskonto). Buchungen
werden per VorlageBuchungsService aus JSON-Regeln in der DB erstellt.
Pflege-UI unter /einstellungen/buchungsvorlagen (CRUD inkl. Felder und
Regeln). Initiale Vorlage "Essensbeleg n. abzugsfähig (nur USt.)" via
Migration 080 eingespielt. Test 42 prüft CRUD und Buchungsausführung.
150 lines
9.1 KiB
PHP
150 lines
9.1 KiB
PHP
<?php
|
||
declare(strict_types=1);
|
||
$h = fn($v) => htmlspecialchars((string)$v, ENT_QUOTES, 'UTF-8');
|
||
|
||
// Felder nach Gruppen aufteilen
|
||
$gruppe1 = array_filter($felder, fn($f) => $f['gruppe_nr'] == 1);
|
||
$gruppe2 = array_filter($felder, fn($f) => $f['gruppe_nr'] == 2);
|
||
$gruppe3 = array_filter($felder, fn($f) => $f['gruppe_nr'] == 3);
|
||
|
||
// Vorbelegen aus Beleg-Metadaten
|
||
$vorbelegt = [
|
||
'lieferant' => $beleg['supplier_name'] ?? '',
|
||
'rechnungsnr' => $beleg['rechnungs_nr'] ?? '',
|
||
'belegdatum' => $beleg['beleg_datum'] ?? date('Y-m-d'),
|
||
];
|
||
|
||
// Vorauswahl Zahlungskonto
|
||
$defaultKontonummer = $hatBankbuchung ? '1200' : '1210';
|
||
$defaultKontoId = 0;
|
||
foreach ($zahlungskonten as $zk) {
|
||
if ($zk['kontonummer'] === $defaultKontonummer) {
|
||
$defaultKontoId = $zk['id'];
|
||
break;
|
||
}
|
||
}
|
||
if (!$defaultKontoId && !empty($zahlungskonten)) {
|
||
$defaultKontoId = (int)array_values($zahlungskonten)[0]['id'];
|
||
}
|
||
?>
|
||
<div class="modal-overlay open" id="vorlage-modal">
|
||
<div class="modal" style="max-width:680px;width:100%">
|
||
<div class="modal-header" style="padding:1.25rem 1.5rem;border-bottom:1px solid var(--color-border);display:flex;align-items:center;justify-content:space-between">
|
||
<h3 class="modal-title" style="margin:0;font-size:1rem"><?= $h($vorlage['name']) ?></h3>
|
||
<button type="button" class="btn btn-secondary" data-modal-close style="padding:.25rem .6rem;font-size:.85rem">✕</button>
|
||
</div>
|
||
<div class="modal-body" style="padding:1.25rem 1.5rem">
|
||
<form method="post" action="/belege/<?= $h($belegId) ?>/vorlage/<?= $h($vorlage['id']) ?>/buchen" id="vorlage-buchen-form">
|
||
<input type="hidden" name="buchungs_datum" value="<?= $h($vorbelegt['belegdatum'] ?: date('Y-m-d')) ?>">
|
||
|
||
<?php if (!empty($gruppe1)): ?>
|
||
<!-- Gruppe 1: Metadaten -->
|
||
<div style="margin-bottom:1.25rem">
|
||
<div style="font-weight:600;font-size:.8rem;text-transform:uppercase;letter-spacing:.05em;color:var(--color-text-muted);margin-bottom:.75rem">Belegdaten</div>
|
||
<?php foreach ($gruppe1 as $feld): ?>
|
||
<?php if ($feld['typ'] === 'readonly'): ?>
|
||
<div class="form-group" style="display:flex;align-items:center;gap:.75rem;margin-bottom:.6rem">
|
||
<label style="min-width:130px;margin:0;font-size:.875rem"><?= $h($feld['label']) ?></label>
|
||
<span id="vorlage-field-<?= $h($feld['feldname']) ?>"
|
||
data-feldname="<?= $h($feld['feldname']) ?>"
|
||
style="font-weight:600;font-size:.95rem">0,00 €</span>
|
||
</div>
|
||
<?php elseif ($feld['typ'] === 'date'): ?>
|
||
<div class="form-group" style="display:flex;align-items:center;gap:.75rem;margin-bottom:.6rem">
|
||
<label style="min-width:130px;margin:0;font-size:.875rem"><?= $h($feld['label']) ?></label>
|
||
<input type="date" name="<?= $h($feld['feldname']) ?>"
|
||
value="<?= $h($vorbelegt[$feld['feldname']] ?? '') ?>"
|
||
style="flex:1;max-width:200px" class="form-control form-control-sm">
|
||
</div>
|
||
<?php else: ?>
|
||
<div class="form-group" style="display:flex;align-items:center;gap:.75rem;margin-bottom:.6rem">
|
||
<label style="min-width:130px;margin:0;font-size:.875rem"><?= $h($feld['label']) ?></label>
|
||
<input type="text" name="<?= $h($feld['feldname']) ?>"
|
||
value="<?= $h($vorbelegt[$feld['feldname']] ?? '') ?>"
|
||
style="flex:1" class="form-control form-control-sm">
|
||
</div>
|
||
<?php endif; ?>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
<?php endif; ?>
|
||
|
||
<?php if (!empty($gruppe2)): ?>
|
||
<!-- Gruppe 2: USt-Zeilen -->
|
||
<div style="margin-bottom:1.25rem">
|
||
<div style="font-weight:600;font-size:.8rem;text-transform:uppercase;letter-spacing:.05em;color:var(--color-text-muted);margin-bottom:.75rem">Beträge</div>
|
||
<table style="width:100%;border-collapse:collapse;font-size:.875rem">
|
||
<thead>
|
||
<tr style="color:var(--color-text-muted);font-size:.8rem">
|
||
<th style="text-align:left;padding:.3rem .5rem;font-weight:500">Steuer</th>
|
||
<th style="text-align:right;padding:.3rem .5rem;font-weight:500">Netto (€)</th>
|
||
<th style="text-align:right;padding:.3rem .5rem;font-weight:500">Brutto (€)</th>
|
||
<th style="text-align:right;padding:.3rem .5rem;font-weight:500">USt (€)</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<?php foreach ($gruppe2 as $feld): ?>
|
||
<?php if ($feld['typ'] === 'ust_zeile'): ?>
|
||
<?php
|
||
$satz = (float)$feld['ust_satz'];
|
||
$satzInt = (int)$satz;
|
||
$nKey = $feld['feldname'];
|
||
$uKey = 'ust_' . $satzInt;
|
||
$bKey = 'brutto_' . $satzInt;
|
||
?>
|
||
<tr data-ust-satz="<?= $h($satz) ?>" class="vorlage-ust-row">
|
||
<td style="padding:.3rem .5rem"><?= $h($feld['label']) ?></td>
|
||
<td style="padding:.3rem .5rem">
|
||
<input type="number" name="<?= $h($nKey) ?>" step="0.01" min="0" value=""
|
||
class="form-control form-control-sm vorlage-netto"
|
||
style="text-align:right;width:110px"
|
||
placeholder="0,00">
|
||
</td>
|
||
<td style="padding:.3rem .5rem">
|
||
<input type="number" name="<?= $h($bKey) ?>" step="0.01" min="0" value=""
|
||
class="form-control form-control-sm vorlage-brutto"
|
||
style="text-align:right;width:110px"
|
||
placeholder="0,00">
|
||
</td>
|
||
<td style="padding:.3rem .5rem">
|
||
<input type="number" name="<?= $h($uKey) ?>" step="0.01" value=""
|
||
class="form-control form-control-sm vorlage-ust"
|
||
style="text-align:right;width:90px;background:var(--color-bg-subtle)"
|
||
readonly placeholder="0,00">
|
||
</td>
|
||
</tr>
|
||
<?php endif; ?>
|
||
<?php endforeach; ?>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
<?php endif; ?>
|
||
|
||
<?php if (!empty($gruppe3)): ?>
|
||
<!-- Gruppe 3: Zahlungskonto -->
|
||
<div style="margin-bottom:1.25rem">
|
||
<div style="font-weight:600;font-size:.8rem;text-transform:uppercase;letter-spacing:.05em;color:var(--color-text-muted);margin-bottom:.75rem">Zahlung</div>
|
||
<?php foreach ($gruppe3 as $feld): ?>
|
||
<?php if ($feld['typ'] === 'account_select'): ?>
|
||
<div class="form-group" style="display:flex;align-items:center;gap:.75rem;margin-bottom:.6rem">
|
||
<label style="min-width:130px;margin:0;font-size:.875rem"><?= $h($feld['label']) ?></label>
|
||
<select name="zahlungskonto_id" class="form-control form-control-sm" style="flex:1;max-width:320px">
|
||
<?php foreach ($zahlungskonten as $zk): ?>
|
||
<option value="<?= $h($zk['id']) ?>"<?= (int)$zk['id'] === $defaultKontoId ? ' selected' : '' ?>>
|
||
<?= $h($zk['kontonummer']) ?> – <?= $h($zk['bezeichnung']) ?>
|
||
</option>
|
||
<?php endforeach; ?>
|
||
</select>
|
||
</div>
|
||
<?php endif; ?>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
<?php endif; ?>
|
||
|
||
</form>
|
||
</div>
|
||
<div class="modal-footer" style="padding:1rem 1.5rem;border-top:1px solid var(--color-border);display:flex;justify-content:flex-end;gap:.75rem">
|
||
<button type="button" class="btn btn-secondary" data-modal-close>Abbrechen</button>
|
||
<button type="submit" form="vorlage-buchen-form" class="btn btn-primary">Buchen</button>
|
||
</div>
|
||
</div>
|
||
</div>
|