"use server"; import { revalidatePath } from "next/cache"; import { z } from "zod"; import { pbCreate, pbDelete, pbUpdate } from "@/lib/pocketbase"; import { getAuth } from "@/lib/auth"; import { pbId } from "@/lib/pb"; import { DELIVERY_STATUSES } from "@/lib/types"; import { getCustomerPriceForDate, cleanEmpty, } from "@/lib/delivery-notes"; const noteSchema = z.object({ number: z.string().min(1, "Note # is required"), date: z.string().min(1, "Date is required"), customer: z.string().min(1, "Customer is required"), vehicle_registration: z.string().optional().default(""), qty_litres_supplied: z.coerce.number().positive("Qty must be > 0"), plant_dispensing: z.string().optional().default(""), status: z.string().optional().default("Pending"), price_per_litre: z.coerce.number().optional(), total_value: z.coerce.number().optional(), pricing_source: z.string().optional().default(""), }); export type ActionResult = { ok: true } | { ok: false; error: string }; export async function createDeliveryNote(_: unknown, formData: FormData): Promise { const { token } = await getAuth(); if (!token) return { ok: false, error: "Not signed in" }; const raw = { number: formData.get("number"), date: formData.get("date"), customer: formData.get("customer"), vehicle_registration: formData.get("vehicle_registration") || "", qty_litres_supplied: formData.get("qty_litres_supplied"), plant_dispensing: formData.get("plant_dispensing") || "", status: formData.get("status") || "Pending", price_per_litre: formData.get("price_per_litre") || undefined, total_value: formData.get("total_value") || undefined, pricing_source: formData.get("pricing_source") || "", }; const parsed = noteSchema.safeParse(raw); if (!parsed.success) { return { ok: false, error: parsed.error.issues[0]?.message ?? "Invalid input" }; } // Auto-fill price/total if not provided let price = parsed.data.price_per_litre; let total = parsed.data.total_value; let source = parsed.data.pricing_source; if (!price) { const p = await getCustomerPriceForDate(parsed.data.customer, parsed.data.date, token); price = p.price; source = p.source; } if (price && !total) { total = Number((price * parsed.data.qty_litres_supplied).toFixed(2)); } try { await pbCreate( "delivery_notes", { id: pbId(), ...cleanEmpty({ ...parsed.data, price_per_litre: price, total_value: total, pricing_source: source }), }, token, ); } catch (err: any) { return { ok: false, error: err?.message || "Failed to create delivery note" }; } revalidatePath("/delivery-notes"); revalidatePath("/dashboard"); return { ok: true }; } export async function updateDeliveryNote(id: string, _: unknown, formData: FormData): Promise { const { token } = await getAuth(); if (!token) return { ok: false, error: "Not signed in" }; const raw = { number: formData.get("number"), date: formData.get("date"), customer: formData.get("customer"), vehicle_registration: formData.get("vehicle_registration") || "", qty_litres_supplied: formData.get("qty_litres_supplied"), plant_dispensing: formData.get("plant_dispensing") || "", status: formData.get("status") || "Pending", price_per_litre: formData.get("price_per_litre") || undefined, total_value: formData.get("total_value") || undefined, pricing_source: formData.get("pricing_source") || "", }; const parsed = noteSchema.safeParse(raw); if (!parsed.success) { return { ok: false, error: parsed.error.issues[0]?.message ?? "Invalid input" }; } try { await pbUpdate("delivery_notes", id, cleanEmpty(parsed.data), token); } catch (err: any) { return { ok: false, error: err?.message || "Failed to update delivery note" }; } revalidatePath("/delivery-notes"); revalidatePath(`/delivery-notes/${id}`); revalidatePath("/dashboard"); return { ok: true }; } export async function deleteDeliveryNote(id: string): Promise { const { token } = await getAuth(); if (!token) return { ok: false, error: "Not signed in" }; try { await pbDelete("delivery_notes", id, token); } catch (err: any) { return { ok: false, error: err?.message || "Failed to delete" }; } revalidatePath("/delivery-notes"); revalidatePath("/dashboard"); return { ok: true }; } export async function updateStatus(id: string, status: string): Promise { const { token } = await getAuth(); if (!token) return { ok: false, error: "Not signed in" }; try { await pbUpdate("delivery_notes", id, { status }, token); } catch (err: any) { return { ok: false, error: err?.message || "Failed to update status" }; } revalidatePath("/delivery-notes"); return { ok: true }; } export async function bulkUpdateStatus(ids: string[], status: string): Promise { const { token } = await getAuth(); if (!token) return { ok: false, error: "Not signed in" }; try { await Promise.all(ids.map((id) => pbUpdate("delivery_notes", id, { status }, token))); } catch (err: any) { return { ok: false, error: err?.message || "Failed to bulk update" }; } revalidatePath("/delivery-notes"); return { ok: true }; }