import Link from "next/link"; import { ContentHeader } from "@/components/layout/ContentHeader"; import { StatusHaken } from "@/components/rechnungen/StatusHaken"; import { Badge } from "@/components/ui/Badges"; import { Callout } from "@/components/ui/Callout"; import { Card } from "@/components/ui/Card"; import { CopyableCode } from "@/components/ui/CopyableCode"; import { InfoBox } from "@/components/ui/SmallBox"; import { prisma } from "@/lib/db"; import { formatDatum, formatEuro, tageBis } from "@/lib/format"; import { anzahlVorschlaege, laufzeitJahre, rechnungsListe, type RechnungsFilter, } from "@/server/queries/rechnungen"; export const metadata = { title: "Rechnungen" }; type SuchParameter = Promise>; function einzeln(wert: string | string[] | undefined): string | undefined { const text = Array.isArray(wert) ? wert[0] : wert; return text && text.length > 0 ? text : undefined; } export default async function RechnungenSeite({ searchParams }: { searchParams: SuchParameter }) { const roh = await searchParams; const filter: RechnungsFilter = { status: (einzeln(roh.status) as RechnungsFilter["status"]) ?? "offen", kunde: einzeln(roh.kunde), jahr: einzeln(roh.jahr), q: einzeln(roh.q), }; const [{ zeilen, summen }, jahre, kunden, vorschlaege] = await Promise.all([ rechnungsListe(filter), laufzeitJahre(), prisma.kunde.findMany({ orderBy: { name: "asc" }, select: { id: true, name: true } }), anzahlVorschlaege(), ]); const heute = new Date(); function adresse(aenderung: Record) { const params = new URLSearchParams(); for (const [schluessel, wert] of Object.entries({ ...filter, ...aenderung })) { if (wert) params.set(schluessel, String(wert)); } const text = params.toString(); return text ? `/rechnungen?${text}` : "/rechnungen"; } return ( <>
{vorschlaege > 0 && filter.status !== "vorschlaege" ? ( Ansehen } > Die Agents haben neue Ablaufdaten gemeldet. Bestätige die Laufzeit und trage die Rechnungsdaten ein. ) : null}

Summen beziehen sich auf die aktuelle Auswahl ({zeilen.length} Laufzeiten).

{( [ ["offen", "Offen"], ["erledigt", "Erledigt"], ["alle", "Alle"], ["vorschlaege", `Vorschläge${vorschlaege ? ` (${vorschlaege})` : ""}`], ] as const ).map(([wert, text]) => ( {text} ))}
} >
{zeilen.map((zeile) => { const faelligIn = tageBis(zeile.einkaufFaelligAm, heute); return ( ); })} {zeilen.length === 0 ? ( ) : null}
Kunde Host Laufzeit Proxmox-Rechnung Netto Bezahlt Kundenrechnung Netto Erstellt Bezahlt Marge
{zeile.kunde ? ( {zeile.kunde.name} ) : ( Nicht zugeordnet )} {zeile.hostname} {formatDatum(zeile.start)} – {formatDatum(zeile.ende)} {zeile.vorschlag ? Vorschlag : null} {zeile.einkaufBezahlt === false && faelligIn !== null && faelligIn <= 7 ? (
fällig {formatDatum(zeile.einkaufFaelligAm)}
) : null}
{formatEuro(zeile.einkaufBetrag)} {formatEuro(zeile.verkaufBetrag)} = 0 ? "pl-text-success" : "pl-text-danger"}> {zeile.marge === null ? "–" : formatEuro(zeile.marge)}
Nichts gefunden. Alle anzeigen

Die Häkchen wirken sofort. Für Rechnungsnummer, Beträge und PDF die Laufzeit öffnen.

); }