Build standalone CiviCRM check-in middleware
This commit is contained in:
67
lib/prefill.ts
Normal file
67
lib/prefill.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* Per-field-most-recent prefill walk.
|
||||
*
|
||||
* Loads all `Org Engagement Submission` activities for an organization,
|
||||
* sorted DESC by activity_date_time. For each field name we care about,
|
||||
* walk the list and take the first non-null value found.
|
||||
*
|
||||
* This closes the v1 prefill gap that Webform CiviCRM cannot express in
|
||||
* its admin UI: load latest values per-field across multiple activities,
|
||||
* without coupling to update-mode.
|
||||
*/
|
||||
|
||||
import { civi } from "./civicrm";
|
||||
import type { FieldConfig } from "@/types/form";
|
||||
|
||||
interface ActivityRow {
|
||||
id: number;
|
||||
activity_date_time: string;
|
||||
// CiviCRM returns custom fields under their machine names like
|
||||
// `custom_42` or `Stage_0_Core.peer_group_participation`.
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
export interface PrefillResult {
|
||||
/** Form-side keys → most-recent non-null value. */
|
||||
values: Record<string, unknown>;
|
||||
/** Number of submission activities walked. */
|
||||
activityCount: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Walk Org Engagement Submission activities for the org, returning per-field
|
||||
* most-recent values keyed by FieldConfig.name. Only fields with a `civiField`
|
||||
* are looked up; transient fields are ignored.
|
||||
*/
|
||||
export async function loadPrefill(
|
||||
orgId: number,
|
||||
fields: FieldConfig[],
|
||||
activityTypeName = "Org Engagement Submission",
|
||||
): Promise<PrefillResult> {
|
||||
const civiSelected = fields.filter((f) => f.civiField);
|
||||
const select = ["id", "activity_date_time", ...new Set(civiSelected.map((f) => f.civiField!))];
|
||||
|
||||
const res = await civi<ActivityRow>("Activity", "get", {
|
||||
select,
|
||||
where: [
|
||||
["activity_type_id:name", "=", activityTypeName],
|
||||
["target_contact_id", "=", orgId],
|
||||
],
|
||||
orderBy: { activity_date_time: "DESC" },
|
||||
limit: 200,
|
||||
});
|
||||
const rows = res.values ?? [];
|
||||
|
||||
const out: Record<string, unknown> = {};
|
||||
for (const f of civiSelected) {
|
||||
for (const row of rows) {
|
||||
const v = row[f.civiField!];
|
||||
if (v !== null && v !== undefined && v !== "") {
|
||||
out[f.name] = v;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { values: out, activityCount: rows.length };
|
||||
}
|
||||
Reference in New Issue
Block a user