"use server"; import { auth } from "@/auth"; import { db } from "@/lib/db"; import { hasPermission } from "@/lib/permissions"; import { geocodePincode } from "@/lib/geo"; import { revalidatePath } from "next/cache"; import { z } from "zod"; const siteSchema = z.object({ name: z.string().min(1, "Name is required"), code: z.string().min(1, "Code is required").max(20).toUpperCase(), address: z.string().optional(), pincode: z.string().optional(), latitude: z.coerce.number().optional(), longitude: z.coerce.number().optional(), }); type Result = { ok: true } | { error: string }; export async function createSite(formData: FormData): Promise { const session = await auth(); if (!session?.user || !hasPermission(session.user.role, "manage_sites")) return { error: "Forbidden" }; const parsed = siteSchema.safeParse(Object.fromEntries(formData)); if (!parsed.success) return { error: parsed.error.errors[0].message }; const { name, code, address, pincode, latitude, longitude } = parsed.data; let lat = latitude, lng = longitude; if (!lat && pincode) { const geo = await geocodePincode(pincode); if (geo) { lat = geo.lat; lng = geo.lng; } } try { await db.site.create({ data: { name, code, address: address ?? null, latitude: lat ?? null, longitude: lng ?? null } }); } catch { return { error: "A site with that code already exists." }; } revalidatePath("/admin/sites"); return { ok: true }; } export async function updateSite(id: string, formData: FormData): Promise { const session = await auth(); if (!session?.user || !hasPermission(session.user.role, "manage_sites")) return { error: "Forbidden" }; const parsed = siteSchema.safeParse(Object.fromEntries(formData)); if (!parsed.success) return { error: parsed.error.errors[0].message }; const { name, code, address, pincode, latitude, longitude } = parsed.data; let lat = latitude, lng = longitude; if (!lat && pincode) { const geo = await geocodePincode(pincode); if (geo) { lat = geo.lat; lng = geo.lng; } } await db.site.update({ where: { id }, data: { name, code, address: address ?? null, latitude: lat ?? null, longitude: lng ?? null } }); revalidatePath("/admin/sites"); revalidatePath(`/admin/sites/${id}`); return { ok: true }; } export async function toggleSiteActive(id: string): Promise { const session = await auth(); if (!session?.user || !hasPermission(session.user.role, "manage_sites")) return { error: "Forbidden" }; const site = await db.site.findUnique({ where: { id }, select: { isActive: true } }); if (!site) return { error: "Not found" }; await db.site.update({ where: { id }, data: { isActive: !site.isActive } }); revalidatePath("/admin/sites"); return { ok: true }; } export async function deleteSite(id: string): Promise { const session = await auth(); if (!session?.user || !hasPermission(session.user.role, "manage_sites")) return { error: "Forbidden" }; const blocked = await db.purchaseOrder.findFirst({ where: { siteId: id, status: { not: "DRAFT" } }, }); if (blocked) return { error: "Cannot delete: site is referenced in submitted or active purchase orders." }; await db.$transaction(async (tx) => { await tx.purchaseOrder.updateMany({ where: { siteId: id, status: "DRAFT" }, data: { siteId: null } }); await tx.itemConsumption.deleteMany({ where: { siteId: id } }); await tx.itemInventory.deleteMany({ where: { siteId: id } }); await tx.vessel.updateMany({ where: { siteId: id }, data: { siteId: null } }); await tx.site.delete({ where: { id } }); }); revalidatePath("/admin/sites"); return { ok: true }; } export async function recordConsumption(formData: FormData): Promise { const session = await auth(); if (!session?.user) return { error: "Unauthorized" }; const schema = z.object({ siteId: z.string().min(1), productId: z.string().min(1), date: z.string().min(1), quantity: z.coerce.number().positive(), note: z.string().optional(), }); const parsed = schema.safeParse(Object.fromEntries(formData)); if (!parsed.success) return { error: parsed.error.errors[0].message }; const { siteId, productId, date, quantity, note } = parsed.data; await db.itemConsumption.upsert({ where: { productId_siteId_date: { productId, siteId, date: new Date(date) } }, update: { quantity, note: note ?? null, recordedById: session.user.id }, create: { productId, siteId, date: new Date(date), quantity, note: note ?? null, recordedById: session.user.id }, }); revalidatePath(`/admin/sites/${siteId}`); return { ok: true }; }