"use server"; import { revalidatePath } from "next/cache"; import { moduleGuard } from "@/server/action-guard"; import { formObject, toActionError, type ActionState } from "@/server/api/action-state"; import { ctxFromGuard, type ServiceCtx } from "@/server/services/context"; import { assignEmergencySite, assignEmergencyToCustomer, completeEmergencyOrderData, confirmEmergencyCustomer, correctEmergencySite, mergeEmergencyCustomer, releaseEmergencyForBilling, } from "@/server/services/emergency/review"; /** Backoffice review of emergency call-outs (/work-orders/emergency-review/[id]). */ const guard = moduleGuard("emergency"); function done(workOrderId: string): ActionState { revalidatePath("/work-orders/emergency-review"); revalidatePath(`/work-orders/emergency-review/${workOrderId}`); revalidatePath(`/work-orders/${workOrderId}`); return { status: "ok" }; } async function run(workOrderId: string, fn: () => Promise): Promise { try { await fn(); } catch (err) { return toActionError(err); } return done(workOrderId); } const version = (fd: FormData) => { const v = Number(fd.get("baseVersion")); return Number.isInteger(v) && v > 0 ? v : undefined; }; export async function confirmCustomerAction(workOrderId: string): Promise { let ctx: ServiceCtx; try { ctx = ctxFromGuard(await guard("emergency:review", "customer:write")); } catch (err) { return toActionError(err); } return run(workOrderId, () => confirmEmergencyCustomer(ctx, workOrderId)); } export async function assignCustomerAction(workOrderId: string, _prev: ActionState, fd: FormData): Promise { let ctx: ServiceCtx; try { ctx = ctxFromGuard(await guard("emergency:review", "customer:write", "work_order:write")); } catch (err) { return toActionError(err); } return run(workOrderId, async () => assignEmergencyToCustomer(ctx, { workOrderId, targetCustomerId: await targetCustomer(ctx, fd) })); } /** Target from the candidate select or, as a fallback, from an entered customer number (tenant-bound lookup). */ async function targetCustomer(ctx: ServiceCtx, fd: FormData): Promise { const id = String(fd.get("targetCustomerId") ?? "").trim(); if (id) return id; const customerNumber = String(fd.get("targetCustomerNumber") ?? "").trim(); if (!customerNumber) return ""; const c = await ctx.db.customer.findFirst({ where: { customerNumber, deletedAt: null }, select: { id: true } }); return c?.id ?? "__unknown__"; } export async function mergeCustomerAction(workOrderId: string, _prev: ActionState, fd: FormData): Promise { let ctx: ServiceCtx; try { ctx = ctxFromGuard(await guard("emergency:review", "customer:merge")); } catch (err) { return toActionError(err); } const confirm = fd.get("confirm") === "on" || fd.get("confirm") === "1"; return run(workOrderId, async () => mergeEmergencyCustomer(ctx, { workOrderId, targetCustomerId: await targetCustomer(ctx, fd), confirm })); } export async function correctSiteAction(workOrderId: string, _prev: ActionState, fd: FormData): Promise { let ctx: ServiceCtx; try { ctx = ctxFromGuard(await guard("emergency:review", "site:write")); } catch (err) { return toActionError(err); } const values = formObject(fd, ["name", "street", "houseNumber", "postalCode", "city", "onSiteContact", "phone", "accessNotes"]); const patch = { ...values, name: values.name ?? undefined }; const confirm = fd.get("confirm") === "on" || fd.get("confirm") === "1"; return run(workOrderId, () => correctEmergencySite(ctx, { workOrderId, patch, confirm })); } export async function assignSiteAction(workOrderId: string, _prev: ActionState, fd: FormData): Promise { let ctx: ServiceCtx; try { ctx = ctxFromGuard(await guard("emergency:review", "work_order:write")); } catch (err) { return toActionError(err); } const siteId = String(fd.get("siteId") ?? ""); return run(workOrderId, () => assignEmergencySite(ctx, { workOrderId, siteId })); } export async function completeOrderAction(workOrderId: string, _prev: ActionState, fd: FormData): Promise { let ctx: ServiceCtx; try { ctx = ctxFromGuard(await guard("emergency:review", "work_order:write")); } catch (err) { return toActionError(err); } const values = formObject(fd, ["title", "description", "orderTypeId", "billingType"]); return run(workOrderId, () => completeEmergencyOrderData(ctx, { workOrderId, ...values, baseVersion: version(fd) })); } export async function releaseBillingAction(workOrderId: string, _prev: ActionState, fd: FormData): Promise { let ctx: ServiceCtx; try { ctx = ctxFromGuard(await guard("emergency:review", "work_order:release_billing")); } catch (err) { return toActionError(err); } return run(workOrderId, () => releaseEmergencyForBilling(ctx, { workOrderId, baseVersion: version(fd) })); }