Merge lane/abrechnung in feature/craftvia-mvp

Konflikte gelöst (additiv): Benachrichtigungstexte (Planung + Meilensteine), Event-Typen,
Navigation, Job-Queues/Prozessoren (geocode-site, planning-watch, billing-pdf), OpenAPI-Tags,
Smoke-Prüfungen (zweiter Mandant: Planung + Abrechnung).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-15 10:37:52 +02:00
co-authored by Claude Opus 5
79 changed files with 4481 additions and 40 deletions
+3 -1
View File
@@ -18,6 +18,7 @@ import {
ReportsTab,
TimesTab,
} from "@/components/work-orders/detail-tabs";
import { WorkOrderBillingTab } from "@/components/billing/work-order-billing-tab";
import { pageContext } from "@/components/work-orders/page-context";
import { Field, inputCls, LinkTabs, StatusBadge } from "@/components/work-orders/ui";
import { WorkOrderFields } from "@/components/work-orders/work-order-fields";
@@ -30,7 +31,7 @@ import { customerDisplayName, customerOption, teamOptions, userOptions } from "@
import { listOrderTypes } from "@/server/services/work-orders/settings";
import { reasonRequired } from "@/server/services/work-orders/transition";
const TABS = ["overview", "checklist", "material", "times", "photos", "notes", "reports", "documents", "history"] as const;
const TABS = ["overview", "checklist", "material", "times", "photos", "notes", "reports", "billing", "documents", "history"] as const; // L14: billing
type Tab = (typeof TABS)[number];
type SP = Record<string, string | string[] | undefined>;
const one = (v: string | string[] | undefined) => (Array.isArray(v) ? v[0] : v);
@@ -202,6 +203,7 @@ export default async function WorkOrderDetailPage({ params, searchParams }: { pa
}
/>
)}
{tab === "billing" && <WorkOrderBillingTab ctx={ctx} wo={wo} locale={locale} tz={tz} />}
{tab === "documents" && <DocumentsTab {...tabProps} uploadError={one(sp.uploadError)} uploaded={one(sp.uploaded) === "1"} />}
{tab === "history" && <HistoryTab {...tabProps} />}
</div>