mirror of
https://github.com/renee-png/acmcc.git
synced 2026-06-21 01:40:01 +00:00
Import G/L: use buildium_gl source, name-first matching, keep parent rows
- Post imported entries as external_source "buildium_gl" (matching the nightly buildium-gl-sync) so the sync's dedupe recognizes them and won't re-pull the same transactions as duplicates. A separate "buildium_gl_csv" source is invisible to that dedupe and double-counts on the next sync. - Match accounts by name first, then code: account numbers can differ between Buildium and the platform chart (and a number can mean different things), so name is the more reliable key; code is the fallback. - Keep IsParent rows. In some exports a parent account carries its own real postings rather than a rollup duplicate; the per-transaction balance check flags genuine double-emits instead of silently dropping lines. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -20,12 +20,16 @@ import { money } from "../lib/format";
|
||||
// entry. Parent rollup accounts (IsParent) and the cash book (IsCashPosting)
|
||||
// are skipped so the accrual book isn't double-counted.
|
||||
//
|
||||
// Accounts are matched to the association's chart of accounts by code
|
||||
// (AccountNumber) first, then by name (GLAccountName, leading code stripped).
|
||||
// Transactions are keyed on the Buildium `Id` (external_id) so re-importing the
|
||||
// same file is a no-op — already-imported transactions are skipped.
|
||||
|
||||
const EXTERNAL_SOURCE = "buildium_gl_csv";
|
||||
// Accounts are matched to the association's chart of accounts by name first
|
||||
// (GLAccountName, leading code stripped) then code (AccountNumber) — name-first
|
||||
// avoids code collisions where the same number means different things in the two
|
||||
// charts. Transactions are keyed on the Buildium `Id` (external_id) so
|
||||
// re-importing the same file is a no-op.
|
||||
//
|
||||
// The source is "buildium_gl" — the same source the nightly buildium-gl-sync
|
||||
// uses — so its watermark/dedupe (which only recognizes "buildium_gl") treats
|
||||
// these as already-imported and won't re-pull them as duplicates.
|
||||
const EXTERNAL_SOURCE = "buildium_gl";
|
||||
|
||||
type CoaAccount = { id: string; code: string | null; name: string; type: string };
|
||||
|
||||
@@ -118,8 +122,12 @@ export default function GLImportDialog({
|
||||
return m;
|
||||
}, [accounts]);
|
||||
|
||||
// Name-first, then code: the chart's account *number* can differ between
|
||||
// Buildium and the platform (and the same number can mean different things),
|
||||
// so a name match is more reliable; fall back to code for "-- "-prefixed
|
||||
// reserve components and the like whose names won't match verbatim.
|
||||
const resolveAccount = (code: string, name: string): CoaAccount | null =>
|
||||
(code && byCode.get(code.trim())) || byName.get(norm(name)) || null;
|
||||
byName.get(norm(stripLeadingCode(name))) || (code && byCode.get(code.trim())) || byName.get(norm(name)) || null;
|
||||
|
||||
function reset() {
|
||||
setLines([]); setError(null); setFileName("");
|
||||
@@ -152,7 +160,10 @@ export default function GLImportDialog({
|
||||
const isTrue = (v: string) => ["true", "1", "yes", "y"].includes(String(v).trim().toLowerCase());
|
||||
const out: ParsedLine[] = [];
|
||||
for (const r of rows) {
|
||||
if (col.isParent && isTrue(r[col.isParent])) continue; // skip rollup parents
|
||||
// NOTE: IsParent rows are kept — in some exports a parent account carries
|
||||
// its own postings (not a rollup duplicate). The per-transaction balance
|
||||
// check below is the safeguard: a file that double-emits parent+child
|
||||
// won't balance and is flagged rather than silently dropped.
|
||||
if (col.isCash && isTrue(r[col.isCash])) continue; // skip cash book (accrual only)
|
||||
const amount = Number(String(r[col.amount]).replace(/[$,]/g, "")) || 0;
|
||||
if (amount === 0) continue;
|
||||
|
||||
Reference in New Issue
Block a user