/* eslint-disable */ /* © 2026 K2B NETWORK SOLUTIONS LLC. All rights reserved. */ // RC20 (fops) — two small screens for the fixed-ops server commands: // FopsRecentTickets Parts Ticket › 🧾 Recent tickets: the parts invoices the SERVER stored, with Reprint (a reprint prints the stored // invoice and never moves stock or money again). // FopsNotInBooks Accounting (GLINQ) and Acct Office, office logins only: repair orders closed and parts sold since RC16 that have // NO journal entry (the server refused the station's own posting — owner-reviewer R1), with "Post it now" per item. // Posting uses the same server mapping and calculation as Close RO / Cash Out, on the original date when that month // is open; stock is never moved again; a second click finds the entry and does nothing. // Global names are prefixed Fops* (one shared Babel scope). const fopsMoney = (c) => "$" + ((Number(c) || 0) / 100).toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 }); const fopsDay = (iso) => { const d = new Date(iso); return isNaN(d) ? "" : d.toLocaleDateString("en-US", { month: "2-digit", day: "2-digit", year: "numeric" }); }; const FopsRecentTickets = ({ onClose, onPrint }) => { const [st, setSt] = React.useState({ loading: true, sales: [], msg: "" }); const [ret, setRet] = React.useState(null); // RC26 (inv): the ticket a Return is being written against (PartsUi.jsx.txt PartsReturnDialog) React.useEffect(() => { let live = true; DMS.partsSales(25).then((r) => { if (live) setSt({ loading: false, sales: r.sales || [], msg: r.ok ? "" : r.msg }); }); return () => { live = false; }; }, []); const th = { textAlign: "left", fontSize: 10.5, textTransform: "uppercase", letterSpacing: "0.04em", color: "var(--jb-text-muted)", padding: "5px 8px", background: "var(--jb-surface-2)" }; const td = { padding: "5px 8px", borderTop: "1px solid var(--jb-border)", fontSize: 12.5 }; return ( Close}> {st.loading &&
Loading…
} {st.msg &&
{st.msg}
} {!st.loading && !st.sales.length && !st.msg &&
No tickets yet.
} {st.sales.length > 0 && (
{["Ticket", "Date", "Customer", "Clerk", "Total", ""].map((h) => )} {st.sales.map((x) => ( ))}
{h}
{x.saleId}{x.catchUp ? " (posted late)" : ""} {fopsDay(x.date || x.createdAt)} {(x.customer && x.customer.name) || "COUNTER SALE"} {(x.clerk && (x.clerk.name || x.clerk.id)) || x.createdByName || ""} {fopsMoney(x.totalCents)} {typeof PartsReturnDialog === "function" && }
)} {ret && typeof PartsReturnDialog === "function" && setRet(null)} onPrint={onPrint} />}
); }; const FopsNotInBooks = () => { const office = !!(window.DMS && DMS.fopsIsOffice && DMS.fopsIsOffice()); const [st, setSt] = React.useState({ loading: true, data: null }); const [busy, setBusy] = React.useState(null); const [open, setOpen] = React.useState(true); const load = React.useCallback(() => { DMS.fopsUnposted().then((r) => setSt({ loading: false, data: r })); }, []); React.useEffect(() => { if (office) load(); }, [office, load]); if (!office) return null; const d = st.data; const bar = { margin: "6px 12px 0", padding: "6px 10px", borderRadius: 6, fontSize: 12.5, fontFamily: "var(--jb-font, sans-serif)" }; if (st.loading) return
Checking the books for repair orders and parts sales without a journal entry…
; if (!d || !d.ok) return
Not in the books: {(d && d.msg) || "could not load the list."}
; // RC24: an "other" posting a lane's catch-up command can post (svcm: payments after close / voids / refunds / body-shop closes / policy; // RC26 inv: counts / PO receipts / core steps / bulk deliveries a station tried before RC26 — keyed by the record, posted once) // carries cmd + postBody from the server and is listed with its own "Post it now"; the rest stay a note for Doc Entry. const postable = (d.other || []).filter((o) => o && o.postable && o.cmd); const items = [].concat((d.ros || []).map((r) => Object.assign({ key: "ro:" + r.roId }, r)), (d.parts || []).map((p) => Object.assign({ key: "pt:" + p.saleId }, p)), postable.map((o) => Object.assign({ key: "ot:" + o.auditId, type: "other" }, o))); const other = (d.other || []).filter((o) => !(o && o.postable && o.cmd)); const otherLine = other.length ?
Also refused since {fopsDay(d.since)}: {other.length} other posting{other.length === 1 ? "" : "s"} a station made itself ({Array.from(new Set(other.map((o) => o.journalId.split("-")[0]))).join(", ")}) that no catch-up command can read — post those by hand in Doc Entry if they belong on the books.
: null; if (!items.length) return
✓ Not in the books: nothing — every repair order closed and every parts sale since {fopsDay(d.since)} has its journal entry.{otherLine}
; const post = async (it) => { setBusy(it.key); const r = await DMS.fopsPostMissing(it); setBusy(null); window.k2bToast && window.k2bToast(r.msg, r.ok ? "ok" : "warn", r.ok ? 4500 : 9000); load(); }; const th = { textAlign: "left", fontSize: 10.5, textTransform: "uppercase", color: "#7a5a00", padding: "4px 6px" }; const td = { padding: "4px 6px", borderTop: "1px solid #EBD9A8", fontSize: 12.5 }; return (
Not in the books:{d.summary.line}. Since {fopsDay(d.since)} — these were closed or sold, but their journal entry was refused (a non-office login posted it under RC16–RC19).
{otherLine} {open && (
{["What", "Number", "Date", "By", "Customer", "Total", ""].map((h) => )} {items.map((it) => ( ))}
{h}
{it.type === "ro" ? "Repair order" : it.type === "other" ? (it.kindLabel || "Service posting") : "Parts sale"} {it.type === "ro" ? it.roId : it.type === "other" ? (it.roId ? it.roId + " " + (it.receiptNo || "") : it.jobId || it.policyId || it.journalId) : it.journalId} {fopsDay(it.type === "ro" ? it.closedAt : it.at)} {it.type === "ro" ? it.closedBy : it.type === "other" ? it.by : it.soldBy} {it.customer}{it.type === "parts" && it.lines && it.lines[0] && it.lines[0].part ? " · " + it.lines[0].part + (it.lines[0].qty ? " x" + it.lines[0].qty : "") : ""}{it.type === "other" && it.desc ? " · " + it.desc : ""} {fopsMoney(it.totalCents)}
)}
); }; Object.assign(window, { FopsRecentTickets, FopsNotInBooks });