Changes
Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com>
This commit is contained in:
co-authored by
renee-png
parent
0c10cc5323
commit
a30b62f883
@@ -695,6 +695,16 @@ function ImportPage() {
|
||||
bumpSkip("client not found in existing clients (import companies first)");
|
||||
} else if ((cfg.table === "cases" || cfg.table === "invoices") && !row.client_id) {
|
||||
bumpSkip("client not found");
|
||||
} else if (cfg.table === "time_entries" && !row.work_date) {
|
||||
bumpSkip("missing or invalid work date");
|
||||
} else if (cfg.table === "time_entries" && !row.case_id && !row._caseext && !row._casenum && !row._casename) {
|
||||
bumpSkip("missing case reference");
|
||||
} else if (cfg.table === "time_entries" && (row._caseext || row._casenum || row._casename) && !row.case_id) {
|
||||
bumpSkip("case not found (import cases first or match case title/number)");
|
||||
} else if (cfg.table === "time_entries" && (row.hours == null || row.hours <= 0) && row._time == null) {
|
||||
bumpSkip("missing or invalid hours");
|
||||
} else if (cfg.table === "time_entries" && !row.description && !row._activity) {
|
||||
bumpSkip("missing description/activity");
|
||||
} else {
|
||||
bumpSkip("rejected by transform");
|
||||
}
|
||||
@@ -736,7 +746,55 @@ function ImportPage() {
|
||||
const withConflict = chunk.filter((r) => r[cfg.conflict]);
|
||||
const withoutConflict = chunk.filter((r) => !r[cfg.conflict]);
|
||||
|
||||
if (withConflict.length > 0) {
|
||||
if (cfg.table === "time_entries" && withConflict.length > 0) {
|
||||
const externalIds = withConflict.map((r) => String(r[cfg.conflict]));
|
||||
const { data: existing, error: lookupError } = await supabase
|
||||
.from("time_entries")
|
||||
.select("id, external_id")
|
||||
.in("external_id", externalIds);
|
||||
|
||||
if (lookupError) {
|
||||
errors.push(`Batch ${i / chunkSize + 1} (lookup): ${lookupError.message}`);
|
||||
} else {
|
||||
const existingByExternalId = new Map(
|
||||
(existing ?? []).map((entry: { id: string; external_id: string | null }) => [entry.external_id, entry.id]),
|
||||
);
|
||||
const toUpdate = withConflict
|
||||
.filter((r) => existingByExternalId.has(String(r.external_id)))
|
||||
.map((r) => ({ ...r, id: existingByExternalId.get(String(r.external_id)) }));
|
||||
const toInsert = withConflict.filter((r) => !existingByExternalId.has(String(r.external_id)));
|
||||
|
||||
if (toUpdate.length > 0) {
|
||||
const updateResults = await Promise.all(
|
||||
toUpdate.map(async (entry) => {
|
||||
const { id, ...payload } = entry;
|
||||
return supabase.from("time_entries").update(payload as any).eq("id", id).select("*").single();
|
||||
}),
|
||||
);
|
||||
for (const result of updateResults) {
|
||||
if (result.error) {
|
||||
errors.push(`Batch ${i / chunkSize + 1} (update): ${result.error.message}`);
|
||||
} else if (result.data) {
|
||||
inserted += 1;
|
||||
inserted_rows.push(result.data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (toInsert.length > 0) {
|
||||
const { data, error } = await supabase
|
||||
.from("time_entries")
|
||||
.insert(toInsert as any)
|
||||
.select("*");
|
||||
if (error) {
|
||||
errors.push(`Batch ${i / chunkSize + 1} (insert): ${error.message}`);
|
||||
} else if (data) {
|
||||
inserted += data.length;
|
||||
inserted_rows.push(...data);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (withConflict.length > 0) {
|
||||
const { data, error } = await supabase
|
||||
.from(cfg.table as any)
|
||||
.upsert(withConflict as any, { onConflict: cfg.conflict, ignoreDuplicates: false })
|
||||
|
||||
Reference in New Issue
Block a user