231 lines
13 KiB
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>
|