Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com>
This commit is contained in:
gpt-engineer-app[bot]
2026-05-01 14:43:13 +00:00
co-authored by renee-png
parent 986350319b
commit 80ea414e92
+67
View File
@@ -692,6 +692,73 @@ const IMPORTERS: ImporterConfig[] = [
return r;
},
},
// Trust ledger
{
key: "trust_ledger",
label: "Trust ledger → Trust accounting",
description:
"Trust account deposits and withdrawals. Expected columns: Date, Client, Type (deposit/withdrawal), Amount, Note, optional Case (case number or title), optional ExternalId, optional Debit/Credit (use instead of Type+Amount). Archived clients are accepted. Rows that don't match a client are SKIPPED.",
table: "trust_ledger_entries",
conflict: "external_id",
required: ["client_id", "entry_type", "amount"],
aliases: {
id: "external_id", externalid: "external_id", trustid: "external_id",
clientid: "_clientext", clientexternalid: "_clientext",
client: "_clientname", clientname: "_clientname", hoa: "_clientname", association: "_clientname",
caseid: "_caseext", matterid: "_caseext", casenumber: "_casenum",
casename: "_casename", casetitle: "_casename", matter: "_casename", mattername: "_casename",
type: "_type", entrytype: "_type", txtype: "_type", transactiontype: "_type",
amount: "_amount", total: "_amount",
deposit: "_deposit", credit: "_deposit",
withdrawal: "_withdrawal", debit: "_withdrawal", payment: "_withdrawal",
date: "entry_date", entrydate: "entry_date", txdate: "entry_date",
note: "note", notes: "note", memo: "note", description: "note",
},
numeric: ["_amount", "_deposit", "_withdrawal"],
dateCols: ["entry_date"],
transform: (r, ctx) => {
// Resolve client (allow archived)
const cidExt = r._clientext ? ctx.clientByExt.get(String(r._clientext)) : null;
const cidName = r._clientname
? ctx.clientByName.get(String(r._clientname).toLowerCase().trim())
: null;
r.client_id = cidExt ?? cidName ?? null;
delete r._clientext; delete r._clientname;
if (!r.client_id) return null;
// Resolve case (optional, archived ok — use full caseByTitle/Number maps)
r.case_id =
(r._caseext && ctx.caseByExt.get(String(r._caseext))) ||
(r._casenum && ctx.caseByNumber.get(String(r._casenum))) ||
(r._casename && ctx.caseByTitle.get(String(r._casename).toLowerCase().trim())) ||
null;
delete r._caseext; delete r._casenum; delete r._casename;
// Resolve type + amount. Support Type+Amount or separate Debit/Credit columns.
const dep = Number(r._deposit) || 0;
const wdr = Number(r._withdrawal) || 0;
let amount = Number(r._amount) || 0;
let type: string | null = null;
if (r._type) {
const t = String(r._type).toLowerCase().trim();
if (["deposit", "credit", "in", "+"].includes(t)) type = "deposit";
else if (["withdrawal", "withdraw", "debit", "out", "-", "payment"].includes(t)) type = "withdrawal";
}
if (!type && dep > 0) { type = "deposit"; amount = dep; }
else if (!type && wdr > 0) { type = "withdrawal"; amount = wdr; }
// Negative amount → withdrawal
if (!type && amount < 0) { type = "withdrawal"; amount = Math.abs(amount); }
if (!type && amount > 0) { type = "deposit"; }
delete r._type; delete r._amount; delete r._deposit; delete r._withdrawal;
if (!type || !amount || amount <= 0) return null;
r.entry_type = type;
r.amount = Math.abs(amount);
if (!r.entry_date) r.entry_date = new Date().toISOString().slice(0, 10);
r.created_by = ctx.userId;
return r;
},
},
];
interface ImportResult {