feat(kunden): Eigenbedarf fuer eigene Hosts (#044)

Eigene Hosts brauchen einen Kunden - sonst stehen sie unter "Nicht
zugeordnet" und fehlen in jeder Auswertung. Als gewoehnlicher Kunde erzeugen
sie aber Aufgaben, die es nicht gibt: Kundenrechnung erstellen, Kundenrechnung
unbezahlt, dazu eine negative Marge in jeder Summe.

Das Kennzeichen Eigenbedarf am Kunden nimmt die Verkaufsseite heraus: kein
Formular fuer die Kundenrechnung, keine Warnungen darueber, keine Aufgabe,
keine Marge - und in den Summen zaehlt der Einkauf mit, Verkauf und Marge
nicht.

Die Einkaufsseite bleibt vollstaendig: Eigene Hosts kosten echtes Geld, und
die Rechnung von Proxmox will bezahlt werden.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-10-04 06:54:43 +02:00
co-authored by Claude Opus 5
parent 5e5028c53d
commit 840e902b26
21 changed files with 231 additions and 15 deletions
@@ -38,6 +38,7 @@ export default async function KundeBearbeitenSeite({ params }: { params: Promise
ansprechpartner: kunde.ansprechpartner,
email: kunde.email,
telefon: kunde.telefon,
eigenbedarf: kunde.eigenbedarf,
notizen: kunde.notizen,
}}
/>
+3
View File
@@ -60,6 +60,9 @@ export default async function KundenSeite() {
<Link href={`/kunden/${kunde.id}`} className="fw-semibold text-decoration-none">
{kunde.name}
</Link>
{kunde.eigenbedarf ? (
<span className="badge pl-bg-neutral ms-2">Eigenbedarf</span>
) : null}
<div className="small text-body-secondary">{kunde.ansprechpartner ?? "–"}</div>
</td>
<td className="pl-mono" data-label="Kundennummer">
+15 -2
View File
@@ -55,6 +55,7 @@ export default async function LaufzeitSeite({ params }: { params: Promise<{ id:
verkaufBetrag ??
(einkaufBetrag === null ? null : Math.round(einkaufBetrag * (1 + vorgaben.margeProzent / 100) * 100) / 100);
const eigenbedarf = laufzeit.host.kunde?.eigenbedarf ?? false;
const zeitraum = `${formatDatum(laufzeit.start)} – ${formatDatum(laufzeit.ende)}`;
return (
@@ -226,11 +227,22 @@ export default async function LaufzeitSeite({ params }: { params: Promise<{ id:
<Card
titel="Kundenrechnung (Verkauf)"
rahmen={verkauf?.erstellt ? "info" : "warning"}
rahmen={eigenbedarf ? "keiner" : verkauf?.erstellt ? "info" : "warning"}
werkzeuge={
<VerkaufBadge erstellt={verkauf?.erstellt ?? false} bezahlt={verkauf?.bezahlt ?? false} />
eigenbedarf ? (
<span className="badge pl-bg-neutral">Eigenbedarf</span>
) : (
<VerkaufBadge erstellt={verkauf?.erstellt ?? false} bezahlt={verkauf?.bezahlt ?? false} />
)
}
>
{eigenbedarf ? (
<p className="mb-0 text-body-secondary">
<strong>{laufzeit.host.kunde?.name}</strong> ist als Eigenbedarf gekennzeichnet – diese
Hosts werden nicht weiterberechnet. Deshalb gibt es hier keine Kundenrechnung, keine
Warnung darüber und keine Marge. Die Proxmox-Rechnung wird weiterhin geführt.
</p>
) : (
<KundenrechnungFormular
laufzeitId={laufzeit.id}
hostId={laufzeit.host.id}
@@ -247,6 +259,7 @@ export default async function LaufzeitSeite({ params }: { params: Promise<{ id:
anhangName: verkauf?.anhang?.dateiname ?? null,
}}
/>
)}
</Card>
</div>
</div>