Quelltext des aktuellen Standes
<?php $this->layout('layouts/main', [
'page_title' => 'Kostenübersicht',
'current_route' => 'costs',
'full_width' => true,
]); ?>
<?php
$vertraege = $vertraege ?? [];
$lizenzen = $lizenzen ?? [];
$nachKategorie = $nach_kategorie ?? [];
$mitLizenzen = !empty($mit_lizenzen);
/** Betrag in der eingestellten Währung, auf den Cent genau (Tabellen). */
$euro = fn (float $b): string => $this->money($b, 2);
/** Betrag fuer die Kacheln: ohne Nachkommastellen, damit die Zeile nicht abgeschnitten wird. */
$euroKurz = fn (float $b): string => $this->money($b, 0);
/** Zahlungsintervall in Worten. */
$intervall = static fn (string $i): string => match ($i) {
'monthly' => 'Monatlich',
'quarterly' => 'Vierteljährlich',
'yearly' => 'Jährlich',
'one_time' => 'Einmalig',
default => $i,
};
?>
<div>
<div class="content-header">
<div>
<h1><?= $this->te('Kostenübersicht') ?></h1>
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="/"><?= $this->te('Home') ?></a></li>
<li class="breadcrumb-item active"><?= $this->te('Kostenübersicht') ?></li>
</ol>
</div>
</div>
<div class="page-body">
<div class="kpi-row">
<div class="kpi-col">
<div class="small-box bg-primary">
<div class="inner">
<h3><?= $this->e($euroKurz((float)($monatlich ?? 0))) ?></h3>
<p><?= $this->te('Laufend pro Monat') ?></p>
</div>
<div class="icon"><i class="fas fa-coins"></i></div>
</div>
</div>
<div class="kpi-col">
<div class="small-box bg-info">
<div class="inner">
<h3><?= $this->e($euroKurz((float)($jaehrlich ?? 0))) ?></h3>
<p><?= $this->te('Laufend pro Jahr') ?></p>
</div>
<div class="icon"><i class="fas fa-calendar"></i></div>
</div>
</div>
<div class="kpi-col">
<div class="small-box bg-secondary">
<div class="inner">
<h3><?= $this->e($euroKurz((float)($vertraege_monatlich ?? 0))) ?></h3>
<p><?= $this->t('davon Verträge') ?> (<?= count($vertraege) ?>)</p>
</div>
<div class="icon"><i class="fas fa-file-contract"></i></div>
</div>
</div>
<?php if ($mitLizenzen): ?>
<div class="kpi-col">
<div class="small-box bg-secondary">
<div class="inner">
<h3><?= $this->e($euroKurz((float)($lizenzen_monatlich ?? 0))) ?></h3>
<p><?= $this->te('davon Lizenzen ohne Vertrag') ?></p>
</div>
<div class="icon"><i class="fas fa-certificate"></i></div>
</div>
</div>
<?php endif; ?>
</div>
<?php if ($mitLizenzen && (int)($abgedeckt_anzahl ?? 0) > 0): ?>
<div class="alert alert-info">
<?= $this->t(
(int)$abgedeckt_anzahl === 1
? '<strong>{anzahl} Lizenz nicht mitgerechnet.</strong> Sie ist einem Vertrag zugeordnet und gilt damit als über ihn abgerechnet – ihr Betrag steckt bereits in den Vertragskosten. Das wären {betrag} pro Monat, die sonst doppelt in der Summe stünden. In der Tabelle unten ist sie gekennzeichnet.'
: '<strong>{anzahl} Lizenzen nicht mitgerechnet.</strong> Sie sind einem Vertrag zugeordnet und gelten damit als über ihn abgerechnet – ihre Beträge stecken bereits in den Vertragskosten. Zusammen wären das {betrag} pro Monat, die sonst doppelt in der Summe stünden. In der Tabelle unten sind sie gekennzeichnet.',
['anzahl' => (int)$abgedeckt_anzahl, 'betrag' => $this->e($euro((float)($abgedeckt_monatlich ?? 0)))]
) ?>
</div>
<?php endif; ?>
<?php if ((float)($einmalig ?? 0) > 0): ?>
<p class="text-muted" style="margin:-.4rem 0 1rem;">
<?= $this->t('Dazu kommen <strong>{betrag}</strong> an einmaligen Zahlungen. Sie gehen bewusst nicht in die laufenden Kosten ein.', ['betrag' => $this->e($euro((float)$einmalig))]) ?>
</p>
<?php endif; ?>
<?php if ($nachKategorie !== []): ?>
<section class="detail-card">
<div class="detail-card-header"><span class="detail-card-title"><?= $this->te('Wofür geht das Geld – pro Monat') ?></span></div>
<div class="detail-card-body">
<div class="table-wrapper">
<table class="data-table">
<thead><tr><th scope="col"><?= $this->te('Kategorie') ?></th><th scope="col" style="text-align:right;"><?= $this->te('Pro Monat') ?></th><th scope="col" style="text-align:right;"><?= $this->te('Anteil') ?></th></tr></thead>
<tbody>
<?php $gesamt = max(0.01, (float)($monatlich ?? 0)); ?>
<?php foreach ($nachKategorie as $name => $betrag): ?>
<tr>
<td><?= $this->e((string)$name) ?></td>
<td style="text-align:right;font-variant-numeric:tabular-nums;"><?= $this->e($euro((float)$betrag)) ?></td>
<td style="text-align:right;color:var(--gray-500);"><?= $this->number((float)$betrag / $gesamt * 100, 1) ?> %</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</section>
<?php endif; ?>
<section class="detail-card">
<div class="detail-card-header"><span class="detail-card-title"><?= $this->te('Verträge') ?></span></div>
<div class="detail-card-body">
<?php if ($vertraege === []): ?>
<div class="empty-state">
<span class="empty-icon"><i class="fas fa-file-contract"></i></span>
<strong><?= $this->te('Keine laufenden Verträge mit hinterlegten Kosten') ?></strong>
<p><?= $this->te('Erfasst werden laufende und auslaufende Verträge, bei denen ein Betrag eingetragen ist.') ?></p>
</div>
<?php else: ?>
<div class="table-wrapper">
<table class="data-table">
<thead><tr><th scope="col"><?= $this->te('Vertrag') ?></th><th scope="col"><?= $this->te('Kategorie') ?></th><th scope="col"><?= $this->te('Zahlung') ?></th><th scope="col" style="text-align:right;"><?= $this->te('Betrag') ?></th><th scope="col" style="text-align:right;"><?= $this->te('Pro Monat') ?></th></tr></thead>
<tbody>
<?php foreach ($vertraege as $v): ?>
<tr>
<td><a class="table-link" href="/contracts/<?= (int)$v['id'] ?>"><?= $this->e((string)$v['title']) ?></a></td>
<td><?= $this->e((string)$v['kategorie']) ?></td>
<td><span class="badge"><?= $this->e($intervall((string)$v['cost_interval'])) ?></span></td>
<td style="text-align:right;font-variant-numeric:tabular-nums;"><?= $this->e($euro((float)$v['cost_amount'])) ?></td>
<td style="text-align:right;font-variant-numeric:tabular-nums;"><?= $this->e($euro((float)$v['monatlich'])) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endif; ?>
</div>
</section>
<?php if ($mitLizenzen): ?>
<section class="detail-card">
<div class="detail-card-header"><span class="detail-card-title"><?= $this->te('Lizenzen') ?></span></div>
<div class="detail-card-body">
<?php if ($lizenzen === []): ?>
<div class="empty-state">
<span class="empty-icon"><i class="fas fa-certificate"></i></span>
<strong><?= $this->te('Keine aktiven Lizenzen mit hinterlegten Kosten') ?></strong>
</div>
<?php else: ?>
<div class="table-wrapper">
<table class="data-table">
<thead><tr><th scope="col"><?= $this->te('Lizenz') ?></th><th scope="col"><?= $this->te('Hersteller') ?></th><th scope="col"><?= $this->te('Zahlung') ?></th><th scope="col" style="text-align:right;"><?= $this->te('Betrag') ?></th><th scope="col" style="text-align:right;"><?= $this->te('Pro Monat') ?></th></tr></thead>
<tbody>
<?php foreach ($lizenzen as $l): ?>
<tr<?= $l['ueber_vertrag'] ? ' style="color:var(--gray-500);"' : '' ?>>
<td>
<a class="table-link" href="/licenses/<?= (int)$l['id'] ?>"><?= $this->e((string)$l['name']) ?></a>
<?php if ($l['ueber_vertrag']): ?>
<span class="status-pill status-pill--neutral" title="<?= $this->te('Über einen Vertrag abgerechnet – nicht in der Summe') ?>"><?= $this->te('über Vertrag') ?></span>
<?php endif; ?>
</td>
<td><?= $this->e((string)($l['vendor'] ?? '')) ?></td>
<td><span class="badge"><?= $this->e($intervall((string)$l['cost_interval'])) ?></span></td>
<td style="text-align:right;font-variant-numeric:tabular-nums;"><?= $this->e($euro((float)$l['cost_amount'])) ?></td>
<td style="text-align:right;font-variant-numeric:tabular-nums;">
<?= $l['ueber_vertrag'] ? '<span title="Steckt in den Vertragskosten">—</span>' : $this->e($euro((float)$l['monatlich'])) ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endif; ?>
</div>
</section>
<?php endif; ?>
<p class="text-muted" style="margin-top:1.5rem;font-size:.85rem;">
<?= $this->te('Gezählt werden laufende und auslaufende Verträge sowie aktive Lizenzen, bei denen ein Betrag hinterlegt ist. Vierteljährliche und jährliche Zahlungen sind auf den Monat umgerechnet.') ?>
</p>
</div>
</div>