"use server"; import { auth } from "@/auth"; import { db } from "@/lib/db"; import { canPerformAction } from "@/lib/po-state-machine"; import { notify } from "@/lib/notifier"; import { revalidatePath } from "next/cache"; type ActionResult = { ok: true } | { error: string }; export async function approvepo({ poId, note, withNote = false, }: { poId: string; note?: string; withNote?: boolean; }): Promise { const session = await auth(); if (!session?.user) return { error: "Unauthorized" }; const po = await db.purchaseOrder.findUnique({ where: { id: poId }, include: { submitter: true }, }); if (!po) return { error: "PO not found" }; const action = withNote ? "approve_with_note" : "approve"; if (!canPerformAction(po.status, action, session.user.role)) { return { error: "You cannot approve this PO." }; } if (!po.vendorId) { return { error: "A vendor must be assigned before approving this PO." }; } await db.purchaseOrder.update({ where: { id: poId }, data: { status: "MGR_APPROVED", approvedAt: new Date(), managerNote: note ?? null, actions: { create: { actionType: withNote ? "APPROVED_WITH_NOTE" : "APPROVED", note: note ?? null, actorId: session.user.id, }, }, }, }); const accounts = await db.user.findMany({ where: { role: "ACCOUNTS", isActive: true } }); await notify({ event: withNote ? "PO_APPROVED_WITH_NOTE" : "PO_APPROVED", po, recipients: [po.submitter, ...accounts], note, }); revalidatePath("/approvals"); revalidatePath(`/po/${poId}`); return { ok: true }; } export async function rejectPo({ poId, note, }: { poId: string; note: string; }): Promise { const session = await auth(); if (!session?.user) return { error: "Unauthorized" }; const po = await db.purchaseOrder.findUnique({ where: { id: poId }, include: { submitter: true }, }); if (!po) return { error: "PO not found" }; if (!canPerformAction(po.status, "reject", session.user.role)) { return { error: "You cannot reject this PO." }; } await db.purchaseOrder.update({ where: { id: poId }, data: { status: "REJECTED", managerNote: note, actions: { create: { actionType: "REJECTED", note, actorId: session.user.id }, }, }, }); await notify({ event: "PO_REJECTED", po, recipients: [po.submitter], note }); revalidatePath("/approvals"); revalidatePath(`/po/${poId}`); return { ok: true }; } export async function requestEdits({ poId, note, }: { poId: string; note: string; }): Promise { const session = await auth(); if (!session?.user) return { error: "Unauthorized" }; const po = await db.purchaseOrder.findUnique({ where: { id: poId }, include: { submitter: true }, }); if (!po) return { error: "PO not found" }; if (!canPerformAction(po.status, "request_edits", session.user.role)) { return { error: "You cannot request edits on this PO." }; } await db.purchaseOrder.update({ where: { id: poId }, data: { status: "EDITS_REQUESTED", managerNote: note, actions: { create: { actionType: "EDITS_REQUESTED", note, actorId: session.user.id }, }, }, }); await notify({ event: "EDITS_REQUESTED", po, recipients: [po.submitter], note }); revalidatePath("/approvals"); revalidatePath(`/po/${poId}`); return { ok: true }; } export async function requestVendorId({ poId }: { poId: string }): Promise { const session = await auth(); if (!session?.user) return { error: "Unauthorized" }; const po = await db.purchaseOrder.findUnique({ where: { id: poId }, include: { submitter: true }, }); if (!po) return { error: "PO not found" }; if (!canPerformAction(po.status, "request_vendor_id", session.user.role)) { return { error: "You cannot request a vendor ID for this PO." }; } await db.purchaseOrder.update({ where: { id: poId }, data: { status: "VENDOR_ID_PENDING", actions: { create: { actionType: "VENDOR_ID_REQUESTED", actorId: session.user.id }, }, }, }); await notify({ event: "VENDOR_ID_REQUESTED", po, recipients: [po.submitter] }); revalidatePath("/approvals"); revalidatePath(`/po/${poId}`); return { ok: true }; }