Quelltext des aktuellen Standes
<?php
$this->layout('layouts/main', [
'page_title' => 'Budget bearbeiten',
'current_route' => 'budget',
'full_width' => true,
'breadcrumbs' => [],
]);
?>
<div class="cf-wrap">
<!-- Content Header -->
<div class="content-header">
<div>
<h1><?= $this->te('Budget bearbeiten') ?></h1>
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="/"><?= $this->te('Home') ?></a></li>
<li class="breadcrumb-item"><a href="/budget"><?= $this->te('Budget') ?></a></li>
<li class="breadcrumb-item"><a href="/budget/<?= (int)$budget['id'] ?>"><?= $this->e($budget['title']) ?></a></li>
<li class="breadcrumb-item active"><?= $this->te('Bearbeiten') ?></li>
</ol>
</div>
</div>
<form action="/budget/<?= (int)$budget['id'] ?>" method="POST" class="cf-layout" id="budgetForm">
<input type="hidden" name="_csrf" value="<?= $this->csrf() ?>">
<input type="hidden" name="_method" value="PUT">
<!-- ── LINKE SPALTE ──────────────────────────────────── -->
<div class="cf-main">
<section class="cf-card">
<h2 class="cf-section-head">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16"><rect x="2" y="7" width="20" height="14" rx="2"/><path d="M16 7V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v2"/></svg>
<?= $this->te('Grunddaten') ?>
</h2>
<div class="cf-card-body">
<!-- Budget-Modus -->
<div class="cf-field">
<label><?= $this->te('Budgetmodus') ?> <span class="cf-req">*</span></label>
<div class="bm-mode-toggle">
<label class="bm-mode-opt">
<input type="radio" name="budget_mode" value="structured"
<?= ($budget['budget_mode'] ?? 'structured') === 'structured' ? 'checked' : '' ?>
onchange="onModeChange(this.value)">
<span class="bm-mode-btn">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="14" height="14"><line x1="8" y1="6" x2="21" y2="6"/><line x1="8" y1="12" x2="21" y2="12"/><line x1="8" y1="18" x2="21" y2="18"/><line x1="3" y1="6" x2="3.01" y2="6"/><line x1="3" y1="12" x2="3.01" y2="12"/><line x1="3" y1="18" x2="3.01" y2="18"/></svg>
<?= $this->te('Strukturiert') ?>
<small><?= $this->te('Geplante Positionen mit einzelnen Beträgen') ?></small>
</span>
</label>
<label class="bm-mode-opt">
<input type="radio" name="budget_mode" value="lump_sum"
<?= ($budget['budget_mode'] ?? '') === 'lump_sum' ? 'checked' : '' ?>
onchange="onModeChange(this.value)">
<span class="bm-mode-btn">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="14" height="14"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>
<?= $this->te('Pauschal') ?>
<small><?= $this->te('Gesamtbetrag, Belege direkt abziehen') ?></small>
</span>
</label>
</div>
</div>
<div class="cf-field" id="totalAmountField"
style="<?= ($budget['budget_mode'] ?? '') !== 'lump_sum' ? 'display:none;' : '' ?>">
<label for="total_amount"><?= $this->te('Pauschalbudget ({cur}, netto)', ['cur' => $this->currency()]) ?> <span class="cf-req">*</span></label>
<input type="number" id="total_amount" name="total_amount"
step="0.01" min="0" class="cf-input-sm"
value="<?= !empty($budget['total_amount']) ? $this->e($budget['total_amount']) : '' ?>"
<?= ($budget['budget_mode'] ?? '') === 'lump_sum' ? 'required' : '' ?>>
<span class="cf-hint"><?= $this->te('Nettobetrag des Budgets — Belege werden brutto dagegen gebucht; beide Größen zeigt die Budget-Seite') ?></span>
</div>
<div class="cf-field">
<label for="tax_rate"><?= $this->te('MwSt-Satz für Planwerte (%)') ?></label>
<input type="number" id="tax_rate" name="tax_rate"
step="0.01" min="0" max="100" class="cf-input-sm"
value="<?= isset($budget['tax_rate']) && $budget['tax_rate'] !== null ? $this->e(rtrim(rtrim(number_format((float)$budget['tax_rate'], 2, '.', ''), '0'), '.')) : '' ?>" placeholder="<?= $this->e($default_tax_rate ?? '19') ?>">
<span class="cf-hint"><?= $this->t('Leer lassen für die Vorgabe aus der Verwaltung ({satz} %). Belege bringen ihren eigenen Satz mit.', ['satz' => $this->e($default_tax_rate ?? '19')]) ?></span>
</div>
<div class="cf-field">
<label for="title"><?= $this->te('Titel') ?> <span class="cf-req">*</span></label>
<input type="text" id="title" name="title" required maxlength="255"
value="<?= $this->e($budget['title']) ?>">
</div>
<div class="cf-row-2">
<div class="cf-field">
<label for="budget_type"><?= $this->te('Budgettyp') ?> <span class="cf-req">*</span></label>
<select id="budget_type" name="budget_type" required>
<option value="department" <?= $budget['budget_type'] === 'department' ? 'selected' : '' ?>><?= $this->te('Abteilungsbudget') ?></option>
<option value="project" <?= $budget['budget_type'] === 'project' ? 'selected' : '' ?>><?= $this->te('Projektbudget') ?></option>
</select>
</div>
<div class="cf-field">
<label for="department"><?= $this->te('Abteilung / Projektname') ?></label>
<input type="text" id="department" name="department" maxlength="255"
value="<?= $this->e($budget['department'] ?? '') ?>">
</div>
</div>
<div class="cf-field">
<label for="description"><?= $this->te('Beschreibung') ?></label>
<textarea id="description" name="description" rows="3"><?= $this->e($budget['description'] ?? '') ?></textarea>
</div>
</div>
</section>
<section class="cf-card">
<h2 class="cf-section-head">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16"><rect x="3" y="4" width="18" height="18" rx="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/></svg>
<?= $this->te('Laufzeit & Planungszeitraum') ?>
</h2>
<div class="cf-card-body">
<div class="cf-row-2">
<div class="cf-field">
<label for="period_start"><?= $this->te('Beginn') ?></label>
<input type="date" id="period_start" name="period_start"
value="<?= $this->e($budget['period_start'] ?? '') ?>">
</div>
<div class="cf-field">
<label for="period_end"><?= $this->te('Ende') ?></label>
<input type="date" id="period_end" name="period_end"
value="<?= $this->e($budget['period_end'] ?? '') ?>">
</div>
</div>
<div class="cf-row-2">
<div class="cf-field">
<label for="fiscal_year"><?= $this->te('Geschäftsjahr') ?></label>
<input type="number" id="fiscal_year" name="fiscal_year"
min="2000" max="2099"
value="<?= !empty($budget['fiscal_year']) ? (int)$budget['fiscal_year'] : '' ?>">
</div>
<div class="cf-field"> </div>
</div>
</div>
</section>
</div><!-- /cf-main -->
<!-- ── RECHTE SPALTE (Sidebar) ───────────────────────── -->
<aside class="cf-sidebar">
<section class="cf-card">
<h2 class="cf-section-head">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
<?= $this->te('Status & Verantwortung') ?>
</h2>
<div class="cf-card-body">
<div class="cf-field">
<label for="status"><?= $this->te('Status') ?></label>
<select id="status" name="status">
<option value="draft" <?= $budget['status'] === 'draft' ? 'selected' : '' ?>><?= $this->te('Entwurf') ?></option>
<option value="active" <?= $budget['status'] === 'active' ? 'selected' : '' ?>><?= $this->te('Aktiv') ?></option>
<option value="closed" <?= $budget['status'] === 'closed' ? 'selected' : '' ?>><?= $this->te('Abgeschlossen') ?></option>
<option value="archived" <?= $budget['status'] === 'archived' ? 'selected' : '' ?>><?= $this->te('Archiviert') ?></option>
</select>
</div>
<div class="cf-field">
<label for="responsible_user_id"><?= $this->te('Verantwortlich') ?></label>
<select id="responsible_user_id" name="responsible_user_id">
<option value=""><?= $this->te('Nicht zugewiesen') ?></option>
<?php foreach ($users as $u): ?>
<option value="<?= (int)$u['id'] ?>"
<?= (int)($budget['responsible_user_id'] ?? 0) === (int)$u['id'] ? 'selected' : '' ?>>
<?= $this->e($u['display_name']) ?>
</option>
<?php endforeach; ?>
</select>
</div>
<div class="cf-field">
<label for="alert_threshold_pct"><?= $this->te('Warnschwelle (% Auslastung)') ?></label>
<input type="number" id="alert_threshold_pct" name="alert_threshold_pct"
min="0" max="100" class="cf-input-sm"
value="<?= (int)($budget['alert_threshold_pct'] ?? 80) ?>">
<span class="cf-hint"><?= $this->te('Benachrichtigt die verantwortliche Person ab dieser Auslastung (0 = aus).') ?></span>
</div>
</div>
</section>
<section class="cf-card">
<h2 class="cf-section-head">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="16" height="16"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/></svg>
<?= $this->te('Notizen') ?>
</h2>
<div class="cf-card-body">
<div class="cf-field">
<textarea id="notes" name="notes" rows="4"><?= $this->e($budget['notes'] ?? '') ?></textarea>
</div>
</div>
</section>
<div class="cf-actions">
<button type="submit" class="cf-btn cf-btn-primary">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" width="14" height="14"><path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/><polyline points="17 21 17 13 7 13 7 21"/><polyline points="7 3 7 8 15 8"/></svg>
<?= $this->te('Änderungen speichern') ?>
</button>
<a href="/budget/<?= (int)$budget['id'] ?>" class="cf-btn cf-btn-cancel"><?= $this->te('Abbrechen') ?></a>
</div>
</aside><!-- /cf-sidebar -->
</form>
</div><!-- /cf-wrap -->
<script>
function onModeChange(mode) {
var f = document.getElementById('totalAmountField');
var inp = document.getElementById('total_amount');
if (mode === 'lump_sum') {
f.style.display = '';
inp.required = true;
} else {
f.style.display = 'none';
inp.required = false;
}
}
</script>
<style>
<?php include __DIR__ . '/../contracts/_contract_form.css.php'; ?>
.cf-wrap { display:flex; flex-direction:column; }
<?php include __DIR__ . '/_budget_mode_toggle.css.php'; ?>
</style>