"use client"; import { useState } from "react"; import { useRouter } from "next/navigation"; import { approvePo, rejectPo, requestEdits, requestVendorId } from "./actions"; import { formatCurrency } from "@/lib/utils"; import type { POStatus } from "@prisma/client"; // Resolve the slider percent (whole number) into an absolute advance amount. // 100% is the exact total (no rounding loss on paise); partial advances are // rounded to whole rupees — the slider is convenience, the amount is the record. function advanceAmount(total: number, percent: number): number { if (percent >= 100) return total; if (percent <= 0) return 0; return Math.round((total * percent) / 100); } export function ApprovalActions({ poId, poStatus, totalAmount = 0, currency = "INR", }: { poId: string; poStatus: POStatus; totalAmount?: number; currency?: string; }) { const router = useRouter(); const [note, setNote] = useState(""); const [advancePercent, setAdvancePercent] = useState(100); const [activeAction, setActiveAction] = useState(null); const [pending, setPending] = useState(null); const [error, setError] = useState(""); const advance = advanceAmount(totalAmount, advancePercent); async function dispatch(action: string, requireNote = false) { if (requireNote && !note.trim()) { setError("A note is required for this action."); return; } setPending(action); setError(""); let result: { ok: true } | { error: string } | undefined; // Approvals carry the Manager's advance decision (resolved amount, not %). if (action === "approve") result = await approvePo({ poId, note, suggestedAdvancePayment: advance }); else if (action === "approve_note") result = await approvePo({ poId, note, withNote: true, suggestedAdvancePayment: advance }); else if (action === "reject") result = await rejectPo({ poId, note }); else if (action === "request_edits") result = await requestEdits({ poId, note }); else if (action === "request_vendor_id") result = await requestVendorId({ poId }); if (result && "error" in result) { setError(result.error); setPending(null); } else { router.push("/approvals"); router.refresh(); } } return (

Decision

{/* Advance payment (issue #92) — Manager decides how much Accounts pays first. 100% = full payment; lower values seed the first part-payment. */}
{advancePercent}% · {formatCurrency(advance, currency)}
setAdvancePercent(Number(e.target.value))} className="w-full accent-primary-600" />

{advancePercent >= 100 ? "Full payment — Accounts will be prompted to pay the whole PO value." : `Accounts will be prompted to pay ${formatCurrency(advance, currency)} first; the balance of ${formatCurrency( Math.max(totalAmount - advance, 0), currency )} follows the usual part-payment flow.`}

{(activeAction === "reject" || activeAction === "request_edits" || activeAction === "approve_note") && (