improvement: new prosthesis type data structure implemented and finally working!

This commit is contained in:
2026-09-01 21:03:04 +03:30
parent dc71c73ced
commit a3c14a18c1
51 changed files with 3306 additions and 1117 deletions

View File

@@ -9,3 +9,87 @@ export function normalizeTaskTeeth(value: Prisma.JsonValue | null | undefined):
.filter((v): v is string | number => typeof v === 'string' || typeof v === 'number')
.map((v) => String(v));
}
export function sortProsthesisTeeth(teeth: readonly string[]): string[] {
return [...teeth].sort((a, b) => {
const rank = (tooth: string) => (tooth === 'UA' ? 0 : tooth === 'LA' ? 1 : 2);
const diff = rank(a) - rank(b);
if (diff !== 0) return diff;
return a.localeCompare(b, undefined, { numeric: true });
});
}
/** Group ids that span more than one tooth (bridges). */
export function connectedSelectionGroupIds(
rows: Array<{
selectionGroupId?: string | null;
tooth?: string;
teeth?: Prisma.JsonValue;
}>,
): Set<string> {
const byGroup = new Map<string, Set<string>>();
for (const row of rows) {
const id = row.selectionGroupId?.trim();
if (!id) continue;
const teeth =
row.tooth != null && row.tooth !== ''
? [row.tooth]
: normalizeTaskTeeth(row.teeth);
const set = byGroup.get(id) ?? new Set<string>();
for (const tooth of teeth) set.add(tooth);
byGroup.set(id, set);
}
const connected = new Set<string>();
for (const [id, teeth] of byGroup) {
if (teeth.size > 1) connected.add(id);
}
return connected;
}
export function aggregateProsthesisGroupsFromTasks(
tasks: Array<{
prosthesisTypeCode: string;
teeth: Prisma.JsonValue;
selectionGroupId?: string | null;
}>,
): Array<{
prosthesisTypeCode: string;
teeth: string[];
connected?: boolean;
selectionGroupId?: string;
}> {
const connectedIds = connectedSelectionGroupIds(tasks);
const byKey = new Map<
string,
{ prosthesisTypeCode: string; teeth: string[]; selectionGroupId: string }
>();
for (const task of tasks) {
if (!task.prosthesisTypeCode) continue;
const selectionGroupId = task.selectionGroupId?.trim() ?? '';
const teeth = normalizeTaskTeeth(task.teeth);
const key = `${teeth.join(',')}::${task.prosthesisTypeCode}`;
const entry = byKey.get(key) ?? {
prosthesisTypeCode: task.prosthesisTypeCode,
teeth: [],
selectionGroupId,
};
entry.teeth.push(...teeth);
if (!entry.selectionGroupId && selectionGroupId) {
entry.selectionGroupId = selectionGroupId;
}
byKey.set(key, entry);
}
return [...byKey.values()]
.map((group) => {
const teeth = sortProsthesisTeeth([...new Set(group.teeth)]);
return {
prosthesisTypeCode: group.prosthesisTypeCode,
teeth,
selectionGroupId: group.selectionGroupId || undefined,
connected: Boolean(group.selectionGroupId) && connectedIds.has(group.selectionGroupId),
};
})
.sort((a, b) => a.prosthesisTypeCode.localeCompare(b.prosthesisTypeCode));
}