Steuerkram/src/Views/buchungsvorlagen/form.php

231 lines
13 KiB
PHP

<?php
declare(strict_types=1);
$isEdit = !empty($vorlage['id']);
$action = $isEdit ? "/einstellungen/buchungsvorlagen/{$vorlage['id']}" : '/einstellungen/buchungsvorlagen';
$feldTypen = ['text','date','number','readonly','ust_zeile','account_select'];
$bedOptn = ['neq_zero' => 'wenn ≠ 0', 'always' => 'immer'];
?>
<form method="post" action="<?= $h($action) ?>">
<?php if (!empty($errors)): ?>
<div class="flash flash-error" style="margin-bottom:1rem">
<?= implode('<br>', array_map(fn($k, $v) => "<strong>$k:</strong> $v", array_keys($errors), $errors)) ?>
</div>
<?php endif; ?>
<!-- Grunddaten -->
<div class="card" style="margin-bottom:1rem">
<div class="card-header"><div class="card-title">Grunddaten</div></div>
<div class="card-body">
<div class="form-group">
<label>Name <span style="color:var(--color-danger)">*</span></label>
<input type="text" name="name" value="<?= $h($vorlage['name'] ?? '') ?>" required class="form-control">
</div>
<div class="form-group">
<label>Beschreibung</label>
<textarea name="beschreibung" rows="2" class="form-control"><?= $h($vorlage['beschreibung'] ?? '') ?></textarea>
</div>
<div class="form-group">
<label>Standard-Lieferant</label>
<input type="text" name="standard_lieferant" value="<?= $h($vorlage['standard_lieferant'] ?? '') ?>"
class="form-control" placeholder="Wird im Buchungsdialog vorbelegt">
</div>
<div style="display:flex;gap:1.5rem">
<div class="form-group" style="flex:0 0 auto">
<label>Reihenfolge</label>
<input type="number" name="sort_order" value="<?= (int)($vorlage['sort_order'] ?? 0) ?>" min="0" class="form-control" style="width:100px">
</div>
<div class="form-group" style="flex:0 0 auto">
<label>Status</label>
<div style="padding-top:.35rem">
<label style="display:inline-flex;align-items:center;gap:.4rem;cursor:pointer">
<input type="checkbox" name="aktiv" value="1"<?= !isset($vorlage['aktiv']) || $vorlage['aktiv'] ? ' checked' : '' ?>>
Aktiv
</label>
</div>
</div>
</div>
</div>
</div>
<!-- Felder -->
<div class="card" style="margin-bottom:1rem">
<div class="card-header" style="display:flex;align-items:center;justify-content:space-between">
<div class="card-title">Eingabefelder</div>
<button type="button" class="btn btn-secondary" style="font-size:.8rem;padding:.25rem .6rem" data-action="vorlage-add-feld">+ Feld</button>
</div>
<div class="card-body" style="padding:0">
<table class="data-table" id="vorlage-felder-table">
<thead>
<tr>
<th>Gruppe</th>
<th>Reihenfolge</th>
<th>Feldname</th>
<th>Label</th>
<th>Typ</th>
<th>USt-%</th>
<th>Meta-Key</th>
<th></th>
</tr>
</thead>
<tbody id="vorlage-felder-body">
<?php foreach ($felder as $i => $feld): ?>
<tr>
<td><input type="number" name="felder[<?= $i ?>][gruppe_nr]" value="<?= (int)$feld['gruppe_nr'] ?>" min="1" max="9" class="form-control form-control-sm" style="width:60px"></td>
<td><input type="number" name="felder[<?= $i ?>][sort_order]" value="<?= (int)$feld['sort_order'] ?>" min="0" class="form-control form-control-sm" style="width:70px"></td>
<td><input type="text" name="felder[<?= $i ?>][feldname]" value="<?= $h($feld['feldname']) ?>" class="form-control form-control-sm" style="width:120px"></td>
<td><input type="text" name="felder[<?= $i ?>][label]" value="<?= $h($feld['label']) ?>" class="form-control form-control-sm"></td>
<td>
<select name="felder[<?= $i ?>][typ]" class="form-control form-control-sm">
<?php foreach ($feldTypen as $t): ?>
<option value="<?= $h($t) ?>"<?= $feld['typ'] === $t ? ' selected' : '' ?>><?= $h($t) ?></option>
<?php endforeach; ?>
</select>
</td>
<td><input type="number" name="felder[<?= $i ?>][ust_satz]" value="<?= $h($feld['ust_satz'] ?? '') ?>" step="0.01" min="0" class="form-control form-control-sm" style="width:70px"></td>
<td><input type="text" name="felder[<?= $i ?>][meta_key]" value="<?= $h($feld['meta_key'] ?? '') ?>" class="form-control form-control-sm" style="width:130px"></td>
<td><button type="button" class="btn btn-danger" style="font-size:.75rem;padding:.2rem .5rem" data-action="remove-tr">✕</button></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
<!-- Buchungsregeln -->
<div class="card" style="margin-bottom:1rem">
<div class="card-header" style="display:flex;align-items:center;justify-content:space-between">
<div class="card-title">Buchungsregeln</div>
<button type="button" class="btn btn-secondary" style="font-size:.8rem;padding:.25rem .6rem" data-action="vorlage-add-regel">+ Regel</button>
</div>
<div class="card-body" style="padding:0">
<div id="vorlage-regeln-container">
<?php foreach ($regeln as $ri => $regel): ?>
<div class="vorlage-regel-block" style="border-bottom:1px solid var(--color-border);padding:1rem">
<div style="display:flex;align-items:center;gap:.75rem;margin-bottom:.75rem">
<strong style="font-size:.85rem">Regel <?= $ri + 1 ?></strong>
<label style="font-size:.85rem;margin:0">Wenn Feld:</label>
<input type="text" name="regeln[<?= $ri ?>][bedingung_feld]" value="<?= $h($regel['bedingung_feld']) ?>"
class="form-control form-control-sm" style="width:120px" placeholder="z.B. netto_7">
<select name="regeln[<?= $ri ?>][bedingung_op]" class="form-control form-control-sm" style="width:120px">
<?php foreach ($bedOptn as $val => $lbl): ?>
<option value="<?= $h($val) ?>"<?= ($regel['bedingung_op'] ?? 'neq_zero') === $val ? ' selected' : '' ?>><?= $h($lbl) ?></option>
<?php endforeach; ?>
</select>
<input type="number" name="regeln[<?= $ri ?>][sort_order]" value="<?= (int)($regel['sort_order'] ?? ($ri * 10)) ?>"
class="form-control form-control-sm" style="width:70px" placeholder="Sortierung">
<button type="button" class="btn btn-danger" style="font-size:.75rem;padding:.2rem .5rem;margin-left:auto" data-action="remove-regel-block">✕</button>
</div>
<table class="data-table" style="margin:0">
<thead>
<tr>
<th>Betrag-Referenz</th>
<th>Ziel-Kontonummer</th>
<th><button type="button" class="btn btn-secondary" style="font-size:.75rem;padding:.15rem .4rem" data-action="vorlage-add-buchung" data-ri="<?= $ri ?>">+ Buchung</button></th>
</tr>
</thead>
<tbody id="vorlage-buchungen-<?= $ri ?>">
<?php foreach ($regel['buchungen'] as $bi => $buch): ?>
<tr>
<td><input type="text" name="regeln[<?= $ri ?>][buchungen][<?= $bi ?>][betrag_ref]"
value="<?= $h($buch['betrag_ref']) ?>" class="form-control form-control-sm" placeholder="z.B. netto_7"></td>
<td><input type="text" name="regeln[<?= $ri ?>][buchungen][<?= $bi ?>][nach_konto]"
value="<?= $h($buch['nach_konto']) ?>" class="form-control form-control-sm" placeholder="z.B. 4656"></td>
<td><button type="button" class="btn btn-danger" style="font-size:.75rem;padding:.2rem .5rem" data-action="remove-tr">✕</button></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endforeach; ?>
</div>
</div>
</div>
<div style="display:flex;gap:.75rem">
<button type="submit" class="btn btn-primary"><?= $isEdit ? 'Speichern' : 'Anlegen' ?></button>
<a href="/einstellungen/buchungsvorlagen" class="btn btn-secondary">Abbrechen</a>
</div>
</form>
<script>
var _vorlFeldIdx = <?= count($felder) ?>;
var _vorlRegelIdx = <?= count($regeln) ?>;
function vorlageAddFeld() {
var i = _vorlFeldIdx++;
var row = document.createElement('tr');
row.innerHTML = `
<td><input type="number" name="felder[${i}][gruppe_nr]" value="1" min="1" max="9" class="form-control form-control-sm" style="width:60px"></td>
<td><input type="number" name="felder[${i}][sort_order]" value="${i*10}" min="0" class="form-control form-control-sm" style="width:70px"></td>
<td><input type="text" name="felder[${i}][feldname]" value="" class="form-control form-control-sm" style="width:120px"></td>
<td><input type="text" name="felder[${i}][label]" value="" class="form-control form-control-sm"></td>
<td><select name="felder[${i}][typ]" class="form-control form-control-sm">
<?php foreach ($feldTypen as $t): ?><option value="<?= $h($t) ?>"><?= $h($t) ?></option><?php endforeach; ?>
</select></td>
<td><input type="number" name="felder[${i}][ust_satz]" value="" step="0.01" min="0" class="form-control form-control-sm" style="width:70px"></td>
<td><input type="text" name="felder[${i}][meta_key]" value="" class="form-control form-control-sm" style="width:130px"></td>
<td><button type="button" class="btn btn-danger" style="font-size:.75rem;padding:.2rem .5rem" data-action="remove-tr">✕</button></td>`;
document.getElementById('vorlage-felder-body').appendChild(row);
}
function vorlageAddRegel() {
var ri = _vorlRegelIdx++;
var div = document.createElement('div');
div.className = 'vorlage-regel-block';
div.style.cssText = 'border-bottom:1px solid var(--color-border);padding:1rem';
div.innerHTML = `
<div style="display:flex;align-items:center;gap:.75rem;margin-bottom:.75rem">
<strong style="font-size:.85rem">Regel ${ri+1}</strong>
<label style="font-size:.85rem;margin:0">Wenn Feld:</label>
<input type="text" name="regeln[${ri}][bedingung_feld]" value=""
class="form-control form-control-sm" style="width:120px" placeholder="z.B. netto_7">
<select name="regeln[${ri}][bedingung_op]" class="form-control form-control-sm" style="width:120px">
<option value="neq_zero">wenn ≠ 0</option>
<option value="always">immer</option>
</select>
<input type="number" name="regeln[${ri}][sort_order]" value="${ri*10}"
class="form-control form-control-sm" style="width:70px">
<button type="button" class="btn btn-danger" style="font-size:.75rem;padding:.2rem .5rem;margin-left:auto" data-action="remove-regel-block">✕</button>
</div>
<table class="data-table" style="margin:0">
<thead><tr>
<th>Betrag-Referenz</th>
<th>Ziel-Kontonummer</th>
<th><button type="button" class="btn btn-secondary" style="font-size:.75rem;padding:.15rem .4rem" data-action="vorlage-add-buchung" data-ri="${ri}">+ Buchung</button></th>
</tr></thead>
<tbody id="vorlage-buchungen-${ri}"></tbody>
</table>`;
document.getElementById('vorlage-regeln-container').appendChild(div);
vorlageAddBuchung(div.querySelector('[data-action="vorlage-add-buchung"]'), ri);
}
function vorlageAddBuchung(btn, ri) {
var tbody = document.getElementById('vorlage-buchungen-' + ri);
if (!tbody) return;
var bi = tbody.querySelectorAll('tr').length;
var tr = document.createElement('tr');
tr.innerHTML = `
<td><input type="text" name="regeln[${ri}][buchungen][${bi}][betrag_ref]"
value="" class="form-control form-control-sm" placeholder="z.B. netto_7"></td>
<td><input type="text" name="regeln[${ri}][buchungen][${bi}][nach_konto]"
value="" class="form-control form-control-sm" placeholder="z.B. 4656"></td>
<td><button type="button" class="btn btn-danger" style="font-size:.75rem;padding:.2rem .5rem" data-action="remove-tr">✕</button></td>`;
tbody.appendChild(tr);
}
// ── Zentrale Event-Delegation statt Inline-Handler (auch für dynamisch erzeugte Zeilen) ──
document.addEventListener('click', function (e) {
var el = e.target.closest('[data-action]');
if (!el) return;
switch (el.dataset.action) {
case 'vorlage-add-feld': vorlageAddFeld(); break;
case 'vorlage-add-regel': vorlageAddRegel(); break;
case 'vorlage-add-buchung': vorlageAddBuchung(el, parseInt(el.dataset.ri, 10)); break;
case 'remove-tr': el.closest('tr').remove(); break;
case 'remove-regel-block': el.closest('.vorlage-regel-block').remove(); break;
}
});
</script>