import { CatalogEntityKind, LabTaskStatus, Prisma } from '@prisma/client'; import { normalizeCatalogLocale } from '../catalog/catalog-label.service'; type TransactionClient = Prisma.TransactionClient; export async function generateLabCaseTasks( tx: TransactionClient, labCaseId: string, localeInput?: string | null, ): Promise { const existingCount = await tx.labCaseTask.count({ where: { labCaseId } }); if (existingCount > 0) { return 0; } const locale = normalizeCatalogLocale(localeInput); const toothProsthesisRows = await tx.labCaseToothProsthesis.findMany({ where: { labCaseId }, include: { detail: { select: { id: true, treatmentType: true } }, }, }); if (toothProsthesisRows.length === 0) { return 0; } const prosthesisCodes = [...new Set(toothProsthesisRows.map((r) => r.prosthesisTypeCode))]; const prosthesisTypes = await tx.prosthesisType.findMany({ where: { code: { in: prosthesisCodes }, isActive: true }, include: { steps: { orderBy: { stepOrder: 'asc' }, include: { labWorkflowStep: { select: { code: true } } }, }, }, }); const stepsByProsthesisCode = new Map( prosthesisTypes.map((type) => [ type.code, type.steps.map((s) => ({ stepOrder: s.stepOrder, workflowStepCode: s.labWorkflowStep.code, })), ]), ); const allStepCodes = [ ...new Set( prosthesisTypes.flatMap((type) => type.steps.map((s) => s.labWorkflowStep.code), ), ), ]; const stepLabels = await resolveStepLabels(tx, allStepCodes, locale); const taskRows: Prisma.LabCaseTaskCreateManyInput[] = []; for (const row of toothProsthesisRows) { const typeSteps = stepsByProsthesisCode.get(row.prosthesisTypeCode) ?? []; if (typeSteps.length === 0) { continue; } for (const step of typeSteps) { taskRows.push({ labCaseId, treatmentDetailId: row.treatmentDetailId, tooth: row.tooth, treatmentType: row.detail.treatmentType, prosthesisTypeCode: row.prosthesisTypeCode, workflowStepCode: step.workflowStepCode, stepOrder: step.stepOrder, stepLabel: stepLabels.get(step.workflowStepCode) ?? step.workflowStepCode, status: LabTaskStatus.PENDING, }); } } if (taskRows.length === 0) { return 0; } await tx.labCaseTask.createMany({ data: taskRows }); return taskRows.length; } async function resolveStepLabels( tx: TransactionClient, stepCodes: string[], locale: string, ): Promise> { if (stepCodes.length === 0) { return new Map(); } const rows = await tx.catalogTranslation.findMany({ where: { entityKind: CatalogEntityKind.LAB_WORKFLOW_STEP, entityCode: { in: stepCodes }, locale: { in: [locale, 'en'] }, }, select: { entityCode: true, locale: true, label: true }, }); const byCode = new Map(); for (const row of rows) { const entry = byCode.get(row.entityCode) ?? {}; if (row.locale === 'en') entry.en = row.label; if (row.locale === locale) entry.locale = row.label; byCode.set(row.entityCode, entry); } const result = new Map(); for (const code of stepCodes) { const entry = byCode.get(code); result.set(code, entry?.locale ?? entry?.en ?? code); } return result; }