/* eslint-disable */ /* © 2026 K2B NETWORK SOLUTIONS LLC. All rights reserved. Proprietary and confidential. Unauthorized copying, distribution, or use of this file, via any medium, is strictly prohibited. Original work product. */ // RC36 (lane fpd36) — FLOORPLAN RECONCILIATION. The owner (10/29): "the floorplan needs to reconcile with the inventory floored". // window.FloorplanRecon Accounting › Floorplan: the floored units in stock (amount, lender, floor date, curtailments) + the sold units // whose payoff is owed, per floorplan account next to the books (310 / 314 …) with the difference and what it most // likely means; the lender's statement compared unit by unit (missing from the statement, not in stock / sold // — payoff owed: Pay Off ▸ (the RC33 payoff command), amount differences); the units in stock NOT floored (cash in // inventory) — "Take the floored amounts from the statement" (a server command, no entry) for the ones the lender lists. // window.FpReviewTie the same tie-out on an import's review (Inventory / Floorplan statement parts — the server answers run.floorplan). // Reads GET /api/floorplan/reconcile (the ACTIVE store only). Every amount is integer cents from the server; nothing is added up in dollars here. (function () { const D = () => window.DMS; const m$ = (c) => { const n = Math.round(+c || 0); const neg = n < 0; const a = Math.abs(n); return (neg ? "-$" : "$") + Math.floor(a / 100).toLocaleString("en-US") + "." + String(a % 100).padStart(2, "0"); }; const errText = (e) => (e && e.body && e.body.error) || (e && e.message) || "The server did not answer."; const useNarrow = () => { const [n, setN] = React.useState(typeof window !== "undefined" && window.innerWidth < 720); React.useEffect(() => { const f = () => setN(window.innerWidth < 720); window.addEventListener("resize", f); return () => window.removeEventListener("resize", f); }, []); return n; }; const box = { background: "#FFF", border: "1px solid var(--jb-border, #D5DCE3)", borderRadius: 8 }; const cell = { padding: "5px 8px", borderTop: "1px solid #EEF1F4", fontSize: 12, verticalAlign: "top" }; const hcell = { padding: "5px 8px", fontSize: 11, textAlign: "left", color: "#555", fontWeight: 700, background: "#F4F6F8", whiteSpace: "nowrap" }; const num = { textAlign: "right", fontFamily: "var(--jb-mono, monospace)", whiteSpace: "nowrap" }; /** a list as a table on a laptop, as stacked cards on a phone (no sideways scrolling) */ function FpList({ rows, cols, narrow, testid, empty, rowKey, extra }) { if (!rows || !rows.length) return
{empty || "None."}
; if (narrow) return (
{rows.map((r, i) => (
{cols.map((c) => { const v = c.render ? c.render(r) : r[c.key]; if (v === undefined || v === null || v === "") return null; return (
{c.label}{v}
); })} {extra ? extra(r) : null}
))}
); return (
{cols.map((c) => )}{extra ? : null}{rows.map((r, i) => ( {cols.map((c) => )} {extra ? : null} ))}
{c.label}
{c.render ? c.render(r) : r[c.key]}{extra(r)}
); } /** the tie per floorplan account (the screen and the import review share it) */ function FpAccounts({ accounts, narrow, asOf }) { const cols = [ { label: "Account", render: (a) => {a.acct} {a.name} }, { label: "Floored in stock", num: true, render: (a) => m$(a.flooredCents) + (a.units ? ` (${a.units})` : "") }, { label: "Sold, payoff owed", num: true, render: (a) => m$(a.soldOwedCents) + (a.sold ? ` (${a.sold})` : "") }, { label: "K2B list", num: true, render: (a) => m$(a.listCents) }, { label: "Books " + (asOf || ""), num: true, render: (a) => m$(a.glCents) }, { label: "Difference", num: true, render: (a) => {m$(a.diffCents)} }, { label: "What it most likely means", render: (a) =>
{(a.causes || []).map((c, i) =>
{c}
)}
}, ]; return a.acct} empty="No floorplan account in the chart." />; } /** the lender statement compared (counts + lists); act = { take(stocks), payoff(stock) } on the screen, none on the review */ function FpCompare({ cmp, narrow, act, may, limit }) { const [pick, setPick] = React.useState({}); if (!cmp) return null; const lim = (a) => (limit ? (a || []).slice(0, limit) : (a || [])); const st = cmp.statement; const can = (cmp.flooredFromStatement || []).filter((x) => x.canTake); const picked = can.filter((x) => pick[x.stock]).map((x) => x.stock); const sec = (key, title, rows, cols, tone, extra, foot) => (
{title} — {(cmp.counts || {})[key] || 0}
(r.stock || r.vin || "") + i} empty="None." extra={extra} /> {foot || null}
); const veh = { label: "Vehicle", key: "desc" }; const stk = { label: "Stock #", render: (r) => {r.stock || "—"} }; const why = { label: "What it most likely means", render: (r) => {r.cause} }; return (
Lender statement {st.lender ? "· " + st.lender : ""} · dated {st.date} · {st.units} unit{st.units === 1 ? "" : "s"} · {m$(st.totalCents)} {st.fileName ? · {st.fileName} : null}
Matched {(cmp.counts || {}).matched || 0} unit{(cmp.counts || {}).matched === 1 ? "" : "s"}: K2B {m$(cmp.totals.matchedOursCents)} vs the lender {m$(cmp.totals.matchedStatementCents)}.
{sec("flooredFromStatement", "On the statement, NOT floored in K2B (cash in inventory the lender floors)", cmp.flooredFromStatement, [stk, veh, { label: "Lender says owed", num: true, render: (r) => m$(r.statementCents) }, { label: "Cost", num: true, render: (r) => m$(r.costCents) }, why], "#8A4B00", act && may && may.fromStatement ? (r) => r.canTake ? : null : null, act && may && may.fromStatement && can.length ? (
No entry is posted — the books already carry the floorplan balance; the server refuses it if the list would be more than the books.
) : null)} {sec("missingFromStatement", "Floored in K2B, NOT on the statement", cmp.missingFromStatement, [stk, veh, { label: "K2B owes", num: true, render: (r) => m$(r.owedCents) }, { label: "Lender", key: "lender" }, why], "#A02234")} {sec("soldPayoffOwed", "Sold — the lender still carries it (payoff owed)", cmp.soldPayoffOwed, [stk, veh, { label: "Lender says owed", num: true, render: (r) => m$(r.statementCents) }, { label: "Sold", key: "soldDate" }, why], "#A02234", act && may && may.payoff ? (r) => r.payoffCents ? : null : null)} {sec("soldPaid", "Sold and paid off in K2B — the lender still lists it", cmp.soldPaid, [stk, veh, { label: "Lender says owed", num: true, render: (r) => m$(r.statementCents) }, { label: "Paid", key: "paidDate" }, why])} {sec("notInStock", "On the statement, not in K2B inventory", cmp.notInStock, [stk, { label: "VIN", key: "vin" }, veh, { label: "Lender says owed", num: true, render: (r) => m$(r.statementCents) }, why], "#A02234")} {sec("amountDiff", "Amount differences", cmp.amountDiff, [stk, veh, { label: "K2B", num: true, render: (r) => m$(r.oursCents) }, { label: "Lender", num: true, render: (r) => m$(r.statementCents) }, { label: "Difference", num: true, render: (r) => {m$(r.diffCents)} }, why], "#A02234")} {(cmp.counts || {}).otherLender ? sec("otherLender", "Floored with another lender (not on this statement)", cmp.otherLender, [stk, veh, { label: "Lender", key: "lender" }, { label: "K2B owes", num: true, render: (r) => m$(r.owedCents) }]) : null}
); } /* ═══════════════ the import review's floorplan section (rv.run.floorplan) ═══════════════ */ function FpReviewTie({ fp, go }) { const narrow = useNarrow(); if (!fp) return null; if (fp.error) return
{fp.error}
; const t = fp.totals || {}; return (
Floorplan tie-out as if approved — the floored units (and the sold units awaiting payoff) next to the books' floorplan accounts, as of {fp.asOf}
{(fp.words || []).map((w, i) =>
{w}
)}
In stock, not floored (cash in inventory): {t.notFlooredUnits || 0} unit{t.notFlooredUnits === 1 ? "" : "s"} · {m$(t.notFlooredCostCents)} at cost.
{fp.compare ? : null} {go ?
: null}
); } /* ═══════════════ Accounting › Floorplan ═══════════════ */ function FloorplanRecon({ onClose, go }) { const Dm = D(); const narrow = useNarrow(); const [asOf, setAsOf] = React.useState(""); const [stmt, setStmt] = React.useState("latest"); const [stmts, setStmts] = React.useState([]); const [data, setData] = React.useState(null); const [err, setErr] = React.useState(""); const [msg, setMsg] = React.useState(null); const [busy, setBusy] = React.useState(false); const [pay, setPay] = React.useState(null); // { stock, method, ref } const load = React.useCallback(async (a, s) => { if (!Dm || typeof Dm._apiGet !== "function") { setErr("This DMS page is older than the server — reload it (Ctrl+F5)."); return; } setErr(""); try { const q = []; if (a) q.push("asOf=" + encodeURIComponent(a)); if (s) q.push("statement=" + encodeURIComponent(s)); const d = await Dm._apiGet("/floorplan/reconcile" + (q.length ? "?" + q.join("&") : "")); setData(d); if (!a) setAsOf(d.asOf); const l = await Dm._apiGet("/floorplan/statements"); setStmts(l.statements || []); } catch (e) { setErr(errText(e)); } }, []); React.useEffect(() => { load("", "latest"); }, []); // eslint-disable-line React.useEffect(() => (Dm && Dm.subscribe) ? Dm.subscribe(() => {}) : undefined, []); const act = { take: async (statementId, stocks) => { setBusy(true); setMsg(null); const key = Dm._newIdemKey("fps"); const r = await Dm._command("/floorplan/from-statement", { statementId, stocks }, key, "/money/op/"); setBusy(false); if (r.ok) { try { Dm._applyServerRecords(r.res.records || []); } catch (e) {} setMsg({ ok: true, text: r.res.message }); load(asOf, stmt); } else setMsg({ ok: false, text: (r.err && r.err.body && r.err.body.error) || (r.unknown ? `The server did not answer — look again before trying (the office can look up ${key}).` : "Refused — nothing was changed.") }); }, payoff: (stock) => setPay({ stock, method: "ach", ref: "" }), }; const doPay = async () => { if (!pay) return; setBusy(true); setMsg(null); const r = await Dm.payoffFloorplan(pay.stock, pay.method === "check" ? { method: "check" } : { method: pay.method, ref: pay.ref.trim() }); setBusy(false); setMsg({ ok: !!(r && r.ok), text: (r && r.msg) || "Done." }); if (r && r.ok) { setPay(null); load(asOf, stmt); } }; const t = (data && data.totals) || {}; const tile = (label, cents, sub, tone, testid) => (
{label}
{m$(cents)}
{sub ?
{sub}
: null}
); const stk = { label: "Stock #", render: (r) => {r.stock} }; return (
{err ?
{err}
: null} {msg ?
{msg.text}
: null} {!data && !err ?
Loading…
: null} {data ? <>
{tile("Floored in stock", t.flooredCents, `${t.flooredUnits || 0} unit${t.flooredUnits === 1 ? "" : "s"}${t.curtailCents ? " · curtailments " + m$(t.curtailCents) : ""}`, null, "fp-t-floored")} {tile("Sold — payoff owed", t.soldOwedCents, `${t.soldOwedUnits || 0} unit${t.soldOwedUnits === 1 ? "" : "s"}`, t.soldOwedUnits ? "#A02234" : null, "fp-t-sold")} {tile("K2B floored list", t.listCents, "what K2B says is owed", null, "fp-t-list")} {tile("Books (floorplan accounts)", t.glCents, "as of " + data.asOf, null, "fp-t-gl")} {tile("Difference", t.diffCents, t.diffCents ? "books minus K2B's list" : "ties to the books", t.diffCents ? "#A02234" : "#176A38", "fp-t-diff")} {tile("Not floored (cash)", t.notFlooredCostCents, `${t.notFlooredUnits || 0} unit${t.notFlooredUnits === 1 ? "" : "s"} at cost`, "#8A4B00", "fp-t-nf")}
The books vs K2B's floored list, by account
{(data.unreadable || []).length ?
Not readable (left out of the totals — correct them): {data.unreadable.map((u) => `${u.stock} ${u.what} "${u.value}"`).join("; ")}
: null}
{pay ? (
Pay off {pay.stock} {pay.method !== "check" ? setPay(Object.assign({}, pay, { ref: e.target.value }))} style={{ font: "inherit", width: 150 }} /> : null}
) : null} {data.compare ? : (
No lender statement {stmt === "none" ? "chosen" : "on file"}. Bring the lender's floorplan statement in with the Upload tool (destination "Floorplan statement" — the template is Floorplan_Statement.csv); after the owner approves it, this screen compares it unit by unit.
)}
Sold — payoff owed ({(data.soldOwed || []).length})
r.stock} empty="No payoff owed." cols={[stk, { label: "Vehicle", key: "desc" }, { label: "Lender", key: "lender" }, { label: "Sold", key: "soldDate" }, { label: "Deal", key: "deal" }, { label: "Owed", num: true, render: (r) => m$(r.owedCents) }, { label: "Account", key: "acct" }]} extra={data.may && data.may.payoff ? (r) => : null} />
Floored units in stock ({t.flooredUnits || 0})
r.stock} empty="No floored unit in stock." cols={[stk, { label: "Vehicle", key: "desc" }, { label: "Lender", key: "lender" }, { label: "Floor date", key: "floorDate" }, { label: "Age", num: true, render: (r) => r.ageDays + "d" }, { label: "Floored", num: true, render: (r) => m$(r.advanceCents) }, { label: "Curtailments", num: true, render: (r) => r.curtailCents ? m$(r.curtailCents) : "—" }, { label: "Owed", num: true, render: (r) => m$(r.owedCents) }, { label: "Account", key: "acct" }]} />
In stock, NOT floored — cash in inventory ({t.notFlooredUnits || 0} · {m$(t.notFlooredCostCents)} at cost)
r.stock} empty="Every unit in stock is floored." cols={[stk, { label: "Vehicle", key: "desc" }, { label: "Type", key: "type" }, { label: "Age", num: true, render: (r) => r.ageDays + "d" }, { label: "Cost", num: true, render: (r) => m$(r.costCents) }, { label: "Floor it", render: (r) => {data.compare && (data.compare.flooredFromStatement || []).some((x) => x.stock === r.stock) ? "the lender's statement lists it — take the amount above" : "ask your floorplan lender to advance on it"} }]} /> {data.truncated ?
The longest lists show the first 400 units; every unit is in the totals.
: null}
: null}
ESC-Close go && go("deadmoney")}>Dead Money go && go("reconcile")}>Reconcile Inventory
); } Object.assign(window, { FloorplanRecon, FpReviewTie, FpAccounts, FpCompare }); })();