fix: deduplicate specimen elements in medipost XML generation
- Fix duplicate <Proov> elements when multiple analysis elements use same material type - Ensure analysis elements reference correct specimen order numbers - Move XML composition logic to separate service for better separation of concerns
This commit is contained in:
@@ -62,9 +62,19 @@ export async function composeOrderXML({
|
||||
'id',
|
||||
);
|
||||
|
||||
const specimenSection = [];
|
||||
const analysisSection = [];
|
||||
let order = 1;
|
||||
// First, collect all unique materials across all analysis groups
|
||||
const uniqueMaterials = new Map<string, {
|
||||
MaterjaliTyypOID: string;
|
||||
MaterjaliTyyp: string;
|
||||
MaterjaliNimi: string;
|
||||
ProovinouKoodOID?: string;
|
||||
ProovinouKood?: string;
|
||||
order: number;
|
||||
}>();
|
||||
|
||||
let specimenOrder = 1;
|
||||
|
||||
// Collect all materials from all analysis groups
|
||||
for (const currentGroup of analysisGroups) {
|
||||
let relatedAnalysisElement = analysisElements?.find(
|
||||
(element) => element.analysis_groups.id === currentGroup.id,
|
||||
@@ -89,31 +99,86 @@ export async function composeOrderXML({
|
||||
|
||||
for (const group of relatedAnalysisElement?.material_groups as MaterjalideGrupp[]) {
|
||||
const materials = toArray(group.Materjal);
|
||||
const specimenXml = materials.flatMap(
|
||||
({ MaterjaliNimi, MaterjaliTyyp, MaterjaliTyypOID, Konteiner }) => {
|
||||
return toArray(Konteiner).map((container) =>
|
||||
getSpecimen(
|
||||
for (const material of materials) {
|
||||
const { MaterjaliNimi, MaterjaliTyyp, MaterjaliTyypOID, Konteiner } = material;
|
||||
const containers = toArray(Konteiner);
|
||||
|
||||
for (const container of containers) {
|
||||
// Use MaterialTyyp as the key for deduplication
|
||||
const materialKey = MaterjaliTyyp;
|
||||
|
||||
if (!uniqueMaterials.has(materialKey)) {
|
||||
uniqueMaterials.set(materialKey, {
|
||||
MaterjaliTyypOID,
|
||||
MaterjaliTyyp,
|
||||
MaterjaliNimi,
|
||||
order,
|
||||
container.ProovinouKoodOID,
|
||||
container.ProovinouKood,
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
ProovinouKoodOID: container.ProovinouKoodOID,
|
||||
ProovinouKood: container.ProovinouKood,
|
||||
order: specimenOrder++,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
specimenSection.push(...specimenXml);
|
||||
// Generate specimen section from unique materials
|
||||
const specimenSection = Array.from(uniqueMaterials.values()).map(material =>
|
||||
getSpecimen(
|
||||
material.MaterjaliTyypOID,
|
||||
material.MaterjaliTyyp,
|
||||
material.MaterjaliNimi,
|
||||
material.order,
|
||||
material.ProovinouKoodOID,
|
||||
material.ProovinouKood,
|
||||
)
|
||||
);
|
||||
|
||||
// Generate analysis section with correct specimen references
|
||||
const analysisSection = [];
|
||||
for (const currentGroup of analysisGroups) {
|
||||
let relatedAnalysisElement = analysisElements?.find(
|
||||
(element) => element.analysis_groups.id === currentGroup.id,
|
||||
);
|
||||
const relatedAnalyses = analyses?.filter((analysis) => {
|
||||
return analysis.analysis_elements.analysis_groups.id === currentGroup.id;
|
||||
});
|
||||
|
||||
if (!relatedAnalysisElement) {
|
||||
relatedAnalysisElement = relatedAnalyses?.find(
|
||||
(relatedAnalysis) =>
|
||||
relatedAnalysis.analysis_elements.analysis_groups.id ===
|
||||
currentGroup.id,
|
||||
)?.analysis_elements;
|
||||
}
|
||||
|
||||
if (!relatedAnalysisElement || !relatedAnalysisElement.material_groups) {
|
||||
throw new Error(
|
||||
`Failed to find related analysis element for group ${currentGroup.name} (id: ${currentGroup.id})`,
|
||||
);
|
||||
}
|
||||
|
||||
// Find the specimen order number for this analysis group
|
||||
let specimenOrderNumber = 1;
|
||||
for (const group of relatedAnalysisElement?.material_groups as MaterjalideGrupp[]) {
|
||||
const materials = toArray(group.Materjal);
|
||||
for (const material of materials) {
|
||||
const materialKey = material.MaterjaliTyyp;
|
||||
const uniqueMaterial = uniqueMaterials.get(materialKey);
|
||||
if (uniqueMaterial) {
|
||||
specimenOrderNumber = uniqueMaterial.order;
|
||||
break; // Use the first material's order number
|
||||
}
|
||||
}
|
||||
if (specimenOrderNumber > 1) break; // Found a specimen, use it
|
||||
}
|
||||
|
||||
const groupXml = getAnalysisGroup(
|
||||
currentGroup.original_id,
|
||||
currentGroup.name,
|
||||
order,
|
||||
specimenOrderNumber,
|
||||
relatedAnalysisElement,
|
||||
);
|
||||
order++;
|
||||
analysisSection.push(groupXml);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user