/* 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. */ // K2B Network Solutions — GM Standard Accounting (GMACCT). // The "factory side" of the back office: financial statement build, // journal entry, schedule inquiry, and GMDS financial submission. // Account numbers, page numbers and column headers track the GM // Standard Accounting Manual (GMSAM v3.0). // ─── data ───────────────────────────────────────────────────────────────── // Statement period = the ledger's OPEN accounting period (DMS.periodStatus), // never a literal. gmPer() → "09 / 2026"; gmPerKey() → "2026-09". const gmPerKey = () => (typeof glOpenPeriod === "function" ? glOpenPeriod() : ((window.DMS && window.DMS.periodStatus && window.DMS.periodStatus().open) || new Date().toISOString().slice(0, 7))); const gmPer = () => { const [y, m] = gmPerKey().split("-"); return m + " / " + y; }; const gmFileName = () => `GMFS_${GM_DEALER.code}_${gmPerKey().replace("-", "")}.GMX`; const gmStamp = () => new Date().toLocaleString("en-US", { month: "2-digit", day: "2-digit", year: "numeric", hour: "2-digit", minute: "2-digit", second: "2-digit", hour12: false }).replace(",", ""); const gmLastLockout = () => { const D = window.DMS; const closed = (D && D.periodStatus ? D.periodStatus().closed : []) || []; if (!closed.length) return "none yet"; const last = closed.slice().sort().pop(); return D.periodRange ? D.periodRange(last).endLabel : last; }; // RC35 (brd): the ACTIVE store's GM codes and names (Owner Panel > Stores) - read when used, never written here const GM_DEALER = { get bac() { return K2BPrint.brand().gm.bac; }, get code() { return K2BPrint.brand().gm.dealerCode; }, get name() { return K2BPrint.party.print(); }, get zone() { return K2BPrint.brand().gm.zone; }, get region() { return K2BPrint.brand().gm.region; }, get state() { return K2BPrint.brand().state; }, get license() { return K2BPrint.party.licenseNo(); } }; const GM_STMT_REV = "12 — Rev D"; const fmt = (n, paren = true) => { if (n === 0 || n === undefined || n === null) return ""; const a = Math.abs(n).toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 }); return n < 0 ? (paren ? `(${a})` : `-${a}`) : a; }; const fmt0 = (n) => { if (n === 0 || n == null) return ""; const a = Math.abs(n).toLocaleString("en-US"); return n < 0 ? `(${a})` : a; }; const pct = (n) => (n == null ? "" : (n >= 0 ? " " : "") + n.toFixed(1) + "%"); // Departmental P&L recap — GMSAM page 1 layout. // Columns: Sales / Cost / Gross / Sell+Pers / Semi+Fix / Net. const GM_DEPTS = [ { k: "NV", num: "01", name: "New Vehicle", sales: 4_212_840.22, cogs: 3_891_204.18, gross: 321_636.04, expSell: 168_402.55, expSemi: 88_402.10, expFix: 162_801.00, net: -97_969.61 }, { k: "UV", num: "02", name: "Used Vehicle", sales: 1_842_018.10, cogs: 1_512_402.00, gross: 329_616.10, expSell: 78_402.50, expSemi: 44_201.20, expFix: 102_881.40, net: 104_131.00 }, { k: "MS", num: "03", name: "Mechanical Service",sales: 612_402.00, cogs: 281_188.10, gross: 331_213.90, expSell: 42_182.10, expSemi: 61_402.00, expFix: 88_910.10, net: 138_719.70 }, { k: "BS", num: "04", name: "Body Shop", sales: 188_402.10, cogs: 82_188.20, gross: 106_213.90, expSell: 12_188.00, expSemi: 18_402.10, expFix: 31_402.10, net: 44_221.70 }, { k: "PT", num: "05", name: "Parts", sales: 742_188.05, cogs: 512_402.40, gross: 229_785.65, expSell: 24_188.00, expSemi: 38_402.10, expFix: 62_402.20, net: 104_793.35 }, { k: "LR", num: "06", name: "Lease & Rental", sales: 44_812.18, cogs: 18_402.00, gross: 26_410.18, expSell: 3_188.00, expSemi: 2_188.10, expFix: 4_402.00, net: 16_632.08 }, { k: "FI", num: "07", name: "F & I", sales: 208_402.55, cogs: 18_402.00, gross: 190_000.55, expSell: 42_188.00, expSemi: 18_402.00, expFix: 22_802.00, net: 106_608.55 }, ]; const GM_TOTAL = GM_DEPTS.reduce((t, d) => ({ sales: t.sales + d.sales, cogs: t.cogs + d.cogs, gross: t.gross + d.gross, expSell: t.expSell + d.expSell, expSemi: t.expSemi + d.expSemi, expFix: t.expFix + d.expFix, net: t.net + d.net, }), { sales: 0, cogs: 0, gross: 0, expSell: 0, expSemi: 0, expFix: 0, net: 0 }); // Balance sheet — collapsed to GMSAM page 2 outline const GM_BAL = { assets: [ { sect: "Cash & Receivables", rows: [ ["201", "Cash on Hand", 18_402.10], ["202", "Cash in Bank — Operating", 412_188.50], ["205", "Cash in Bank — Payroll", 88_402.00], ["220", "Contracts in Transit", 482_018.20], ["230", "Customer Accounts Receivable", 188_402.55], ["234", "Warranty Claims Receivable", 62_188.10], ]}, { sect: "Inventories", rows: [ ["240", "New Vehicle Inventory", 4_211_840.22], ["244", "Used Vehicle Inventory", 872_310.55], ["246", "Lease & Rental Vehicles", 118_400.00], ["260", "Parts Inventory", 241_882.10], ["262", "Tires", 18_402.10], ["266", "Body Shop Materials", 12_402.00], ]}, { sect: "Fixed Assets", rows: [ ["270", "Land", 188_000.00], ["271", "Buildings & Improvements", 812_000.00], ["275", "Machinery, Shop & Service Equip.", 244_188.00], ["278", "Accum. Depreciation", -288_402.00], ]}, ], liabEq: [ { sect: "Current Liabilities", rows: [ ["300", "Notes Payable — New Vehicles", -3_980_223.18], ["311", "Notes Payable — Used Vehicles", -512_900.00], ["318", "Accounts Payable — Trade", -244_188.30], ["321", "Salaries, Wages & Comm. Payable", -84_192.45], ["324", "Sales Tax Payable", -23_811.20], ["330", "Customer Deposits", -28_402.10], ["340", "Allow. for Doubtful Accounts", -12_400.00], ]}, { sect: "Long-Term Liabilities", rows: [ ["360", "Mortgage Payable", -688_402.00], ["365", "Notes Payable — Officers", -100_000.00], ]}, { sect: "Owners' Equity", rows: [ ["368", "Capital Stock", -250_000.00], ["369", "Paid-In Capital", -188_402.00], ["370", "Retained Earnings", -1_447_182.06], ["375", "Current YTD Net Profit", -417_137.27], ]}, ], }; // Pacing — monthly net profit by department, last 6 months const GM_PACE = { months: ["DEC", "JAN", "FEB", "MAR", "APR", "MAY"], rows: [ { name: "Dealership Total", v: [ 188_402, 142_188, 68_402, 188_402, 244_188, 417_137], goal: 320_000 }, { name: "New Vehicle", v: [ -28_188, -88_402, -118_402, -44_188, 18_402, -97_969], goal: 40_000 }, { name: "Used Vehicle", v: [ 72_188, 88_402, 44_188, 98_402, 118_402, 104_131], goal: 90_000 }, { name: "Service", v: [ 142_188, 112_402, 98_402, 138_402, 142_188, 138_719], goal: 140_000 }, { name: "Body Shop", v: [ 18_402, 22_188, 18_402, 28_402, 38_402, 44_221], goal: 38_000 }, { name: "Parts", v: [ 88_402, 72_188, 68_402, 98_402, 102_188, 104_793], goal: 100_000 }, { name: "F & I", v: [ 82_402, 88_402, 72_188, 88_402, 98_402, 106_608], goal: 95_000 }, ], }; // Schedule 240 — New Vehicle Inventory drill const SCHED_240 = [ { stock: "C26-1184", vin: "1G1ZD5ST*RF128442", model: "2026 MALIBU LT", days: 18, cost: 29_184.20 }, { stock: "T26-2018", vin: "3GCUKEED*PG211884", model: "2026 SILVERADO 1500 LT", days: 42, cost: 52_184.18 }, { stock: "T26-2099", vin: "1GNERGKW*PJ200712", model: "2026 TRAVERSE LT AWD", days: 31, cost: 48_910.00 }, { stock: "C26-1188", vin: "1G1ZD5ST*RF128501", model: "2026 MALIBU LT", days: 18, cost: 28_902.55 }, { stock: "T26-2102", vin: "1GNERGKW*PJ200804", model: "2026 TRAVERSE Premier", days: 102, cost: 56_188.00 }, { stock: "T26-2110", vin: "1GCUKEED*PG211999", model: "2026 SILVERADO TRAIL", days: 74, cost: 61_402.10 }, { stock: "B26-3018", vin: "5GAEVAKW*PJ141880", model: "2026 BLAZER RS", days: 22, cost: 44_802.30 }, { stock: "T26-2118", vin: "1GKKNML4*PZ128002", model: "2026 ACADIA AT4", days: 88, cost: 52_018.40 }, { stock: "S26-4002", vin: "1GNEVHKW*PJ188224", model: "2026 SUBURBAN LT", days: 124, cost: 68_402.55 }, { stock: "C26-1199", vin: "1G1ZD5ST*RF128711", model: "2026 MALIBU 2LT", days: 12, cost: 31_018.18 }, { stock: "T26-2122", vin: "3GCUKEED*PG212018", model: "2026 SILVERADO LTZ", days: 8, cost: 58_402.20 }, ]; // Trial balance — re-use the GLINQ list but condensed const GM_TRIAL = [ ["201", "Cash on Hand", 18_402.10, 0], ["202", "Cash in Bank — Operating", 412_188.50, 0], ["230", "Customer A/R", 188_402.55, 0], ["240", "New Vehicle Inventory", 4_211_840.22, 0], ["244", "Used Vehicle Inventory", 872_310.55, 0], ["260", "Parts Inventory", 241_882.10, 0], ["300", "Notes Payable — New Vehicles", 0, 3_980_223.18], ["311", "Notes Payable — Used Vehicles", 0, 512_900.00], ["318", "Accounts Payable — Trade", 0, 244_188.30], ["321", "Salaries & Comm. Payable", 0, 84_192.45], ["370", "Retained Earnings", 0, 1_447_182.06], ["400", "New Cars — Retail (ICE)", 0, 742_188.05], ["405", "New Trucks — Retail (ICE)", 0, 881_402.99], ["460A","Customer Labor — C&LDT", 0, 188_402.50], ["660A","Cost — Customer Labor (C&LDT)", 71_002.85, 0], ["740", "F & I Income — New", 0, 98_402.10], ["855", "F & I Compensation — New", 32_188.00, 0], ]; const GM_PAGES = [ { k: "cover", num: "—", label: "Cover" }, { k: "p1", num: "P-1", label: "Operating Report" }, { k: "p2", num: "P-2", label: "Balance Sheet" }, { k: "p9", num: "P-9", label: "Pacing & Trends" }, { sep: true }, { k: "tb", num: "TB", label: "Trial Balance" }, { k: "sched", num: "SCH", label: "Schedule Inquiry" }, { k: "je", num: "JE", label: "Journal Entry" }, { sep: true }, { k: "coa", num: "COA", label: "Chart of Accounts" }, { k: "depts", num: "DPT", label: "Departments" }, { k: "jtpl", num: "JTL", label: "Std Journals" }, { k: "rpts", num: "RPT", label: "Reports" }, { sep: true }, { k: "sub", num: "SBM", label: "GMDS Submit" }, ]; // ─── shared atoms ───────────────────────────────────────────────────────── const SectHead = ({ children, right }) => (
{children} {right ? {right} : null}
); const FieldChip = ({ label, value, w = 110, hot, valColor }) => ( {label} {value} ); // ─── page components ────────────────────────────────────────────────────── const PageCover = () => (
General Motors Dealer Financial Statement
GMSAM v3.0 — Statement Form 12 (Rev D)
Dealer Name......: {GM_DEALER.name} Business Code....: {GM_DEALER.bac} DMS Dealer Id....: {GM_DEALER.code} Make.............: CHEVROLET / GMC / BUICK Zone — Region....: {GM_DEALER.zone} — {GM_DEALER.region} Statement Period.: {gmPer()} Statement Rev....: {GM_STMT_REV} Prepared By......: {(window.DMS && window.DMS.userId && window.DMS.userId()) || "—"} Submission Status: OPEN — last lockout {gmLastLockout()}
This screen builds the GM Dealer Financial Statement directly from the K2B general ledger. Departmental totals on P-1 are summed from posted journal entries through period close; schedules (SCH) drill any control account to the supporting subledger. GMDS Submit transmits the finished statement to GM via the established SFTP submission window.

Use the page selector on the left to walk pages. All values shown reflect the open period {gmPer()}.
Period at a Glance
Net Profit MTD.. {fmt(GM_TOTAL.net)} Sales MTD....... {fmt(GM_TOTAL.sales)} Gross Profit.... {fmt(GM_TOTAL.gross)} G/P %........... {pct(GM_TOTAL.gross / GM_TOTAL.sales * 100)} Goal Variance... {fmt(GM_TOTAL.net - 320_000)}
Open period checks — {gmPer()}
{((window.DMS && window.DMS.monthEndChecklist) ? window.DMS.monthEndChecklist() : []).map(c => { const ok = c.ok != null ? c.ok : c.done; return
[{ok ? "✓" : "!"}] {c.label}{ok ? "" : " — " + c.detail}
; })}
); // P-1 Operating Report — the marquee page const PageOperating = () => { const Row = ({ d, total }) => ( {d.num || ""} {d.name} {fmt(d.sales)} {fmt(d.cogs)} {fmt(d.gross)} {pct(d.gross / d.sales * 100)} {fmt(d.expSell)} {fmt(d.expSemi)} {fmt(d.expFix)} {fmt(d.net)} ); return (
Departmental Income / (Loss)
{GM_DEPTS.map((d) => )}
Dpt Department Sales Cost of Sales Gross Profit G/P % Sell + Pers Semi-Fix Fixed Net Profit
{/* Bottom strip — comparisons */}
{[ ["MTD Net", GM_TOTAL.net, "vs Goal " + fmt(320000)], ["YTD Net", GM_TOTAL.net * 4.7, "vs PYTD " + fmt(GM_TOTAL.net * 3.8)], ["Sales MTD", GM_TOTAL.sales, "vs Goal " + fmt(7_400_000)], ["Gross G/P %", null, pct(GM_TOTAL.gross / GM_TOTAL.sales * 100)], ].map(([label, val, sub], i) => (
{label}
{val != null ? fmt(val) : {sub}}
{val != null ?
{sub}
: null}
))}
); }; // P-2 Balance Sheet const PageBalance = () => { const totals = (groups) => groups.reduce((s, g) => s + g.rows.reduce((sg, r) => sg + r[2], 0), 0); const assetTotal = totals(GM_BAL.assets); const liabTotal = totals(GM_BAL.liabEq); const Block = ({ title, groups, sign }) => (
0 ? "Debit balance" : "Credit balance"}`}>{title} {groups.map((g, gi) => ( {g.rows.map((r, ri) => ( ))} ))}
{g.sect}
{r[0]} {r[1]} {fmt(Math.abs(r[2]))}
Subtotal {fmt(Math.abs(g.rows.reduce((s, r) => s + r[2], 0)))}
); const balanced = Math.abs(assetTotal + liabTotal) < 1; return (
Statement of Financial Position
Total Assets
{fmt(assetTotal)}
Total Liab. + Equity
{fmt(Math.abs(liabTotal))}
Balance Check
{balanced ? "IN BALANCE" : fmt(assetTotal + liabTotal)}
); }; // P-9 Pacing const PagePacing = () => { const maxAbs = Math.max(...GM_PACE.rows.flatMap(r => r.v.map(Math.abs))); return (
Net Profit by Department
{GM_PACE.months.map(m => )} {GM_PACE.rows.map((r, i) => { const cur = r.v[r.v.length - 1]; const variance = cur - r.goal; return ( {r.v.map((n, j) => ( ))} ); })}
Department{m}Goal Var Trend
{r.name} {fmt0(Math.round(n))} {fmt0(r.goal)} {fmt0(variance)}
); }; const Sparkbar = ({ values, max }) => ( {values.map((v, i) => { const h = Math.max(2, Math.round(Math.abs(v) / max * 16)); return ( ); })} ); // Trial Balance const PageTrial = () => { let dr = 0, cr = 0; GM_TRIAL.forEach(r => { dr += r[2]; cr += r[3]; }); const balanced = Math.abs(dr - cr) < 0.01; return (
Pre-Close Trial
{GM_TRIAL.map((r, i) => ( ))}
Acct Description Debit Credit
{r[0]} {r[1]} {r[2] ? fmt(r[2]) : ""} {r[3] ? fmt(r[3]) : ""}
Totals {fmt(dr)} {fmt(cr)}
{balanced ? "TRIAL BALANCE IS IN BALANCE" : "OUT OF BALANCE: " + fmt(dr - cr)}
); }; // Schedule Inquiry — drill account 240 const PageSchedule = () => { const total = SCHED_240.reduce((s, r) => s + r.cost, 0); return (
{Math.abs(4_211_840.22 - total) < 1 ? "RECONCILES" : "OUT " + fmt(4_211_840.22 - total)}
{SCHED_240.map((r, i) => ( ))}
Stock # VIN Model Days Inv Cost
{r.stock} {r.vin} {r.model} 90 ? "var(--k2b-maroon)" : r.days > 60 ? "#B26A00" : "var(--k2b-blue-data-dk)", fontWeight: r.days > 90 ? 700 : 400 }}>{r.days} {fmt(r.cost)}
Total — {SCHED_240.length} units {SCHED_240.reduce((s, r) => s + r.days, 0)} {fmt(total)}
Aging   0–30: {SCHED_240.filter(r => r.days <= 30).length}    31–60: {SCHED_240.filter(r => r.days > 30 && r.days <= 60).length}    61–90: {SCHED_240.filter(r => r.days > 60 && r.days <= 90).length}    90+: {SCHED_240.filter(r => r.days > 90).length}
); }; // Journal Entry — interactive posting form const PageJournal = ({ seed }) => { const [lines, setLines] = React.useState(seed?.lines || [ { acct: "", desc: "", dr: "", cr: "" }, { acct: "", desc: "", dr: "", cr: "" }, { acct: "", desc: "", dr: "", cr: "" }, { acct: "", desc: "", dr: "", cr: "" }, { acct: "", desc: "", dr: "", cr: "" }, ]); const [ref, setRef] = React.useState(""); // assigned by the ledger on post const [date, setDate] = React.useState(() => typeof glDefaultEntryIso === "function" ? glDefaultEntryIso() : new Date().toISOString().slice(0, 10)); const [memo, setMemo] = React.useState(seed?.memo || ""); // When seed changes (user clicked Load on a template), replace lines + memo React.useEffect(() => { if (seed) { setLines(seed.lines); if (seed.memo) setMemo(seed.memo); } }, [seed]); const totalDr = lines.reduce((s, l) => s + (parseFloat(l.dr) || 0), 0); const totalCr = lines.reduce((s, l) => s + (parseFloat(l.cr) || 0), 0); const out = totalDr - totalCr; const set = (i, k, v) => setLines(L => L.map((l, j) => j === i ? { ...l, [k]: v } : l)); return (
Date...: setDate(e.target.value)} style={{ background: "var(--k2b-yellow)", border: "1px solid #808080", color: "var(--k2b-navy)", padding: "0 6px", fontFamily: "'Courier Prime', monospace" }} /> { const [y, m] = String(date).split("-"); return m && y ? m + " / " + y : gmPer(); })()} w={90} /> Memo...: setMemo(e.target.value)} style={{ background: "#FFFFE1", border: "1px solid #808080", color: "var(--k2b-blue-data-dk)", padding: "0 6px", flex: 1, fontFamily: "'Courier Prime', monospace" }} />
{lines.map((l, i) => ( ))}
Ln Acct Description Debit Credit
{String(i + 1).padStart(2, "0")} set(i, "acct", e.target.value)} style={{ width: "100%", background: "#FFFFE1", border: "1px solid #C0C0C0", fontFamily: "'Courier Prime', monospace", color: "var(--k2b-blue-data-dk)" }} /> set(i, "desc", e.target.value)} style={{ width: "100%", background: "#FFFFE1", border: "1px solid #C0C0C0", fontFamily: "'Courier Prime', monospace", color: "var(--k2b-blue-data-dk)" }} /> set(i, "dr", e.target.value)} style={{ width: "100%", textAlign: "right", background: "#FFFFE1", border: "1px solid #C0C0C0", fontFamily: "'Courier Prime', monospace", color: "var(--k2b-blue-data-dk)" }} /> set(i, "cr", e.target.value)} style={{ width: "100%", textAlign: "right", background: "#FFFFE1", border: "1px solid #C0C0C0", fontFamily: "'Courier Prime', monospace", color: "var(--k2b-blue-data-dk)" }} />
Totals {fmt(totalDr)} {fmt(totalCr)}
{Math.abs(out) < 0.005 ? `BALANCED — Dr ${fmt(totalDr)} = Cr ${fmt(totalCr)}` : `OUT OF BALANCE: ${fmt(out)}`}
setLines(L => [...L, { acct: "", desc: "", dr: "", cr: "" }])}>F3-Add Line { if (Math.abs(out) >= 0.005) { window.k2bToast && window.k2bToast(`Cannot post — out of balance by ${fmt(out)}.`, "warn", 3200); return; } const D = window.DMS; const r = D && D.postJournalEntry ? D.postJournalEntry({ date: typeof glUsFromIso === "function" ? glUsFromIso(date) : date, desc: memo || "GM general journal entry", jrn: 80, src: "Accounting", lines: lines.filter(l => l.acct).map(l => ({ acct: String(l.acct).trim(), dr: parseFloat(l.dr) || 0, cr: parseFloat(l.cr) || 0, desc: l.desc || "" })), }) : { ok: false, msg: "Ledger unavailable." }; window.k2bToast && window.k2bToast(r.msg, r.ok ? "ok" : "warn", 4200); if (r.ok) { setRef(r.id); setLines([0, 1, 2, 3, 4].map(() => ({ acct: "", desc: "", dr: "", cr: "" }))); setMemo(""); } }}>F5-Post { const html = `${window.dealerHeadHtml()}
JOURNAL ENTRY
${ref} · ${date} · Period ${gmPer()} · ${memo}
${lines.filter(l => l.acct).map(l => ``).join("")}
AcctDescriptionDebitCredit
${l.acct}${l.desc}${l.dr ? fmt(parseFloat(l.dr)) : ""}${l.cr ? fmt(parseFloat(l.cr)) : ""}
Totals${fmt(totalDr)}${fmt(totalCr)}
Prepared By · Date
Approved By · Date
`; window.k2bPrint && window.k2bPrint(html, { title: "Journal Entry " + ref }); }}>🖨 F6-Print
window.k2bToast && window.k2bToast(`Saved as recurring template "${memo.slice(0, 32)}".`, "ok", 2400)}>F8-Save Recurring
); }; // GMDS Submit const PageSubmit = () => { const [running, setRunning] = React.useState(false); const [log, setLog] = React.useState(() => { const jes = typeof glJEsIn === "function" ? glJEsIn(gmPerKey()) : []; return [ `[${gmStamp()}] Statement build for period ${gmPer()} — ${jes.length} journal entr${jes.length === 1 ? "y" : "ies"} in the ledger`, `[${gmStamp()}] Statement file: ${gmFileName()} (download with F8)`, `[${gmStamp()}] Direct GMDS transmission is not configured on this station.`, ]; }); const run = () => { if (running) return; setLog(L => [...L, `[${gmStamp()}] Submit requested by ${(window.DMS && window.DMS.userId && window.DMS.userId()) || "operator"} — no GMDS connection configured. Download the .GMX (F8) and upload it in GM's dealer portal.`]); }; return (
Submit Dealer Financial Statement to GM
{[ ["File........", gmFileName()], ["Generated...", gmStamp()], ["Transmission", "manual upload"], ["BAC.........", GM_DEALER.bac], ["Period......", gmPer()], ["Schedules...", "5 reconciled"], ].map((r, i) => (
{r[0]} {r[1]}
))}
{log.join("\n")} {running ? "\n_" : ""}
F5-Submit to GMDS { const html = `${window.dealerHeadHtml()}
GM DEALER FINANCIAL STATEMENT
Form 12 (Rev D) · Period ${gmPer()} · BAC ${GM_DEALER.bac} · Dealer Code ${GM_DEALER.code}

Departmental Net Income

${GM_DEPTS.map(d => ``).join("")}
DepartmentSalesGrossNet
${d.name}${fmt(d.sales)}${fmt(d.gross)}${fmt(d.net)}
Total Dealership${fmt(GM_TOTAL.sales)}${fmt(GM_TOTAL.gross)}${fmt(GM_TOTAL.net)}
Prepared By — Controller
Dealer Principal — ${K2BPrint.esc(K2BPrint.party.print())}
`; window.k2bPrint && window.k2bPrint(html, { title: "GM Financial Statement " + gmPer() }); }}>🖨 F6-Print Statement
{ // Build a minimal pipe-delimited .GMX manifest and trigger a download. const lines = [ `HEADER|GMFS|${GM_DEALER.bac}|${GM_DEALER.code}|${gmPerKey().replace("-", "")}|FORM12`, ...GM_DEPTS.map(d => `DEPT|${d.num}|${d.k}|${d.sales.toFixed(2)}|${d.cogs.toFixed(2)}|${d.gross.toFixed(2)}|${d.net.toFixed(2)}`), `TOTAL|99|ALL|${GM_TOTAL.sales.toFixed(2)}|${GM_TOTAL.cogs.toFixed(2)}|${GM_TOTAL.gross.toFixed(2)}|${GM_TOTAL.net.toFixed(2)}`, `EOF`, ]; const blob = new Blob([lines.join("\n")], { type: "text/plain" }); const url = URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; a.download = gmFileName(); a.click(); URL.revokeObjectURL(url); window.k2bToast && window.k2bToast(".GMX file downloaded.", "ok"); }}>F8-Download .GMX window.k2bToast && window.k2bToast(`No GMDS receipt on file for ${gmPer()} — this station doesn't transmit to GM directly.`, "info", 3600)}>F9-View Receipt
); }; // ─── COA / Departments / Std Journals / Reports (GM Manual full coverage) ─── const PageCoa = () => { const [q, setQ] = React.useState(""); const [type, setType] = React.useState("ALL"); const types = ["ALL", "A", "CA", "L", "E", "R", "COGS", "X"]; const typeName = { A: "Asset", CA: "Contra-Asset", L: "Liability", E: "Equity", R: "Revenue", COGS: "COGS", X: "Expense" }; const list = (window.GM_COA || []).filter(r => { if (type !== "ALL" && r[2] !== type) return false; if (q) { const qq = q.toLowerCase(); return r[0].toLowerCase().includes(qq) || r[1].toLowerCase().includes(qq) || r[4].toLowerCase().includes(qq); } return true; }); // group by section const groups = {}; list.forEach(r => { (groups[r[4]] = groups[r[4]] || []).push(r); }); return (
Chart of Accounts (GM Standard)
Find: setQ(e.target.value)} placeholder="acct # or text" style={{ background: "var(--k2b-yellow)", border: "1px solid #808080", color: "var(--k2b-navy)", padding: "0 6px", width: 280, fontFamily: "'Courier Prime', monospace" }} /> Type: {types.map(t => ( ))}
{Object.entries(groups).map(([section, rows]) => ( {rows.map((r, i) => ( ))} ))}
Acct Description Type Bal Section
▸ {section} · {rows.length}
{r[0]} {r[1]} {typeName[r[2]] || r[2]} {r[3]} {r[4]}
Department-coded expenses: any expense account (e.g. 013) combines with a 2-digit department code (e.g. 01 = New Vehicles) to form the posting account — 013-01 Delivery Expense (New). See the Departments tab for the full code list.
); }; const PageDepts = () => (
Departmental Code Structure
Expenses are distributed to each department by creating sub-accounts formed by combining the three-digit expense account number with the two-digit department code. For example, Delivery Expenses charged to the New Vehicle Department post to account 013-01, Delivery Expense (New). Freight for Parts shipments posts to account 033-07, Freight (Parts).
{(window.GM_DEPT_CODES || []).map((d, i) => ( ))}
Code Department Typical posting example
{d.code} {d.name} {d.code === "01" && "013-01 Delivery Expense · 011-01 Sales Comp · 065-01 Advertising"} {d.code === "02" && "013-02 Delivery Expense · 011-02 Sales Comp · 065-02 Advertising"} {d.code === "03" && "087-03 Utilities · 056-03 Insurance (lease units)"} {d.code === "04" && "855-04 F&I Comp · 070-04 Travel & Ent."} {d.code === "05" && "023-05 Other Wages · 061-05 Other Supplies"} {d.code === "06" && "061-06 Other Supplies · 090-06 Repairs-Equipment"} {d.code === "07" && "033-07 Postage/Freight · 069-07 Outside Services"} {d.code === "09" && "022-09 Salaries Clerical · 070-09 Travel & Ent. · 068-09 IT Services"}
); const PageJournalTpls = ({ onLoad }) => { const [open, setOpen] = React.useState(null); const list = window.GM_JOURNAL_TEMPLATES || []; return (
Standard Journals
{list.map((t, i) => ( {open === t.code && ( )} ))}
Code Description Journal Reference Lines
{t.code} {t.title} {t.journal} {t.ref} {t.lines.length}
{t.lines.map((l, j) => ( ))}
Acct Description Debit Credit
{l.acct} {l.desc} {l.dr ? fmt(l.dr) : ""} {l.cr ? fmt(l.cr) : ""}
Totals {fmt(t.lines.reduce((s, l) => s + (l.dr || 0), 0))} {fmt(t.lines.reduce((s, l) => s + (l.cr || 0), 0))}
Tip: Click Load on any template to copy it onto a new Journal Entry (JE) page, change the amounts, and post.
); }; const PageReports = () => (
Standard Reports Library
{(window.GM_REPORTS || []).map((r) => (
{r.name} {r.code}
{r.desc}
))}
); // ─── main shell ─────────────────────────────────────────────────────────── const GmAccounting = ({ onClose, go }) => { const [page, setPage] = React.useState("p1"); const [jeSeed, setJeSeed] = React.useState(null); const loadTemplate = (t) => { // Build JE lines from template const seed = t.lines.map(l => ({ acct: l.acct, desc: l.desc, dr: l.dr ? Number(l.dr).toFixed(2) : "", cr: l.cr ? Number(l.cr).toFixed(2) : "", })); while (seed.length < 5) seed.push({ acct: "", desc: "", dr: "", cr: "" }); setJeSeed({ memo: `${t.code} — ${t.title}`, lines: seed }); setPage("je"); window.k2bToast && window.k2bToast(`Loaded template "${t.title}" into Journal Entry.`, "ok", 2400); }; const body = (() => { switch (page) { case "cover": return ; case "p1": return ; case "p2": return ; case "p9": return ; case "tb": return ; case "sched": return ; case "je": return ; case "coa": return ; case "depts": return ; case "jtpl": return ; case "rpts": return ; case "sub": return ; default: return ; } })(); return (
{}} onMax={() => {}} />
{/* top strip */}
OPEN PERIOD
{/* main: left rail + body */}
Statement Pages
{GM_PAGES.map((p, i) => p.sep ? (
) : (
setPage(p.k)} style={{ padding: "2px 8px", cursor: "default", fontSize: 13, background: page === p.k ? "var(--k2b-navy)" : "transparent", color: page === p.k ? "#FFFFFF" : "var(--k2b-navy)", display: "grid", gridTemplateColumns: "40px 1fr", gap: 4, }}> {p.num} {p.label}
))}
GMSAM v3.0
Statement {GM_STMT_REV}
{body}
{/* bottom F-key bar */}
ESC-Close alert("GM Standard Accounting (GMACCT)\n\nESC Close\nF1 Help\nF2 Open Schedule Inquiry\nF3 New Journal Entry\nF4 Trial Balance\nF5 Recalculate current page\nF6 Print current page\nF7 GMDS Feeds\nF8 Submit to GMDS\nF9 Top (Operating Report)\n\nLeft rail walks the statement (P-1 → P-9), schedules, journals, COA, depts, standard journals & reports.")}>F1-Help setPage("sched")}>F2-Sched setPage("je")}>F3-New JE setPage("tb")}>F4-Trial window.k2bToast && window.k2bToast(`Recalculated — ${page.toUpperCase()} refreshed from G/L snapshot.`, "ok")}>F5-Recalc window.k2bToast && window.k2bToast(`Page ${page.toUpperCase()} sent to printer.`, "ok")}>🖨 F6-Print Pg go && go("gmds")}>F7-GMDS Feeds setPage("sub")}>F8-Submit setPage("p1")}>F9-Top Use the page rail at left to walk the statement. ESC to leave.
); }; Object.assign(window, { GmAccounting, GM_DEPTS, GM_BAL, GM_PACE, SCHED_240, GM_TRIAL });