feat: fix and add several things

This commit is contained in:
2026-04-28 01:48:11 +00:00
parent c3d55b898f
commit db727e0a9d
17 changed files with 541 additions and 135 deletions
+47 -2
View File
@@ -468,11 +468,11 @@ function ok(
/**
* Build the `customFields` array for a CW activity with Optima_Type set,
* and optionally a QuoteID.
* and optionally a QuoteID, CloseDate, or ParentActivity.
*/
function buildCustomFields(
optimaType: OptimaTypeValue,
opts?: { quoteId?: string; closeDate?: string },
opts?: { quoteId?: string; closeDate?: string; parentActivityCwId?: number },
) {
const fields: any[] = [
{
@@ -507,6 +507,17 @@ function buildCustomFields(
});
}
if (opts?.parentActivityCwId != null) {
fields.push({
id: PARENT_ACTIVITY_FIELD_ID,
caption: "Parent_Activity",
type: "Text",
entryMethod: "EntryField",
numberOfDecimals: 0,
value: String(opts.parentActivityCwId),
});
}
return fields;
}
@@ -523,6 +534,7 @@ export async function createWorkflowActivity(opts: {
quoteId?: string;
dateStart?: string;
dateEnd?: string;
parentActivityCwId?: number | null;
}): Promise<ActivityController> {
const shouldStayOpen = STAYS_OPEN_TYPES.has(opts.optimaType);
@@ -546,6 +558,7 @@ export async function createWorkflowActivity(opts: {
value: buildCustomFields(opts.optimaType, {
quoteId: opts.quoteId,
closeDate: now,
parentActivityCwId: opts.parentActivityCwId ?? undefined,
}),
},
];
@@ -562,6 +575,38 @@ export async function createWorkflowActivity(opts: {
return patched;
}
/**
* Resolve the parent activity CW ID for a newly generated quote activity.
*
* Finds the most recently created workflow activity (by CW ID descending) for
* the opportunity, excluding QuoteGenerated and ScheduleEntry types. This
* ensures the quote activity is nested under the current workflow state's
* activity regardless of whether that activity is open or closed.
*/
export async function resolveQuoteParentActivityCwId(
opportunityCwId: number,
): Promise<number | null> {
try {
const existingActivities = await activityCw.fetchByOpportunityDirect(opportunityCwId);
// Sort descending by CW id so the most recently created comes first
const sorted = [...existingActivities].sort((a, b) => (b.id ?? 0) - (a.id ?? 0));
for (const raw of sorted) {
const optimaField = raw.customFields?.find(
(f: any) => f.id === OptimaType.FIELD_ID,
);
if (!optimaField?.value) continue;
// Skip QuoteGenerated and ScheduleEntry — these should not be parents
if (optimaField.value === OptimaType.QuoteGenerated) continue;
if (optimaField.value === OptimaType.ScheduleEntry) continue;
return raw.id;
}
return null;
} catch (err) {
console.warn(`[Workflow:QuoteParent] Could not resolve parent activity: ${err}`);
return null;
}
}
/**
* Handle optional time entry: submit to CW if timeStart and timeEnd are provided.
*/