import { toast } from "react-toastify"; import type { WorkOrderTablePatch } from "@/domain/work-orders/types/work-order-table-row"; import type { VendorAssignmentFields } from "@/domain/work-orders/utils/vendor-assignment-patch"; import { toVendorTablePatch } from "@/domain/work-orders/utils/vendor-assignment-patch"; type PersistPatchFn = ( id: string | number, patch: WorkOrderTablePatch, options?: { onSuccess?: () => void; onError?: (error: Error) => void; }, ) => void; export function workOrderCanceledMessage(woNumber: string) { return `Work order #${woNumber} canceled.`; } /** * AAP Work Orders board has no vendor-assign toast (bundle audit 2026-08-26). * SH-119 names that silence as the gap to close; this copy is WO-specific. */ export function vendorAssignedMessage() { return "Vendor assigned"; } export function notifyWorkOrderCanceled(woNumber: string) { toast.warning(workOrderCanceledMessage(woNumber)); } export function notifyVendorAssigned() { toast.success(vendorAssignedMessage()); } export function isVendorAssignmentPatch(patch: WorkOrderTablePatch): boolean { return Object.prototype.hasOwnProperty.call(patch, "vendorId"); } export function notifyVendorAssignedIfPatched(patch: WorkOrderTablePatch) { if (isVendorAssignmentPatch(patch)) notifyVendorAssigned(); } export function patchWorkOrderAsCanceled( patchField: PersistPatchFn, row: { id: string | number; woNumber: string }, ) { patchField( row.id, { status: "Canceled" }, { onSuccess: () => notifyWorkOrderCanceled(row.woNumber), }, ); } /** AAP completes via document generate toast, not a dedicated Complete WO toast. */ export function patchWorkOrderAsCompleted(patchField: PersistPatchFn, id: string | number) { patchField(id, { status: "Completed" }); } export function applyVendorTableSave( onPatch: PersistPatchFn, id: string | number, fields: VendorAssignmentFields, ) { onPatch(id, toVendorTablePatch(fields), { onSuccess: notifyVendorAssigned }); }