Skip to main content
Glama
condition.ts6.93 kB
// SPDX-FileCopyrightText: Copyright Orangebot, Inc. and Medplum contributors // SPDX-License-Identifier: Apache-2.0 import { generateId } from '@medplum/core'; import type { CompositionSection, Condition } from '@medplum/fhirtypes'; import { mapFhirToCcdaDate, mapFhirToCcdaDateTime } from '../../datetime'; import { OID_ACT_CLASS_CODE_SYSTEM, OID_HEALTH_CONCERN_ACT, OID_LOINC_CODE_SYSTEM, OID_PROBLEM_ACT, OID_PROBLEM_OBSERVATION, OID_SNOMED_CT_CODE_SYSTEM, } from '../../oids'; import { LOINC_CLINICAL_FINDING, LOINC_CONDITION, LOINC_HEALTH_CONCERNS_SECTION, LOINC_PROBLEMS_SECTION, mapCodeableConceptToCcdaValue, PROBLEM_STATUS_MAPPER, } from '../../systems'; import type { CcdaEntry, CcdaEntryRelationship, CcdaId } from '../../types'; import type { FhirToCcdaConverter } from '../convert'; import { createTextFromExtensions, mapEffectivePeriod, mapIdentifiers } from '../utils'; export function createConditionEntry( converter: FhirToCcdaConverter, section: CompositionSection, condition: Condition ): CcdaEntry | undefined { const sectionCode = section.code?.coding?.[0]?.code; if (sectionCode === LOINC_PROBLEMS_SECTION) { return createProblemEntry(converter, condition); } if (sectionCode === LOINC_HEALTH_CONCERNS_SECTION) { return createHealthConcernEntry(converter, condition); } return undefined; } export function createProblemEntry(converter: FhirToCcdaConverter, problem: Condition): CcdaEntry { return { act: [ { '@_classCode': 'ACT', '@_moodCode': 'EVN', templateId: [{ '@_root': OID_PROBLEM_ACT }, { '@_root': OID_PROBLEM_ACT, '@_extension': '2015-08-01' }], id: mapIdentifiers(problem.id, undefined), code: { '@_code': 'CONC', '@_codeSystem': OID_ACT_CLASS_CODE_SYSTEM, }, statusCode: { '@_code': PROBLEM_STATUS_MAPPER.mapFhirToCcdaWithDefault(problem.clinicalStatus?.coding?.[0]?.code, 'active'), }, effectiveTime: mapEffectivePeriod(problem.recordedDate, undefined), entryRelationship: [ { '@_typeCode': 'SUBJ', observation: [ { '@_classCode': 'OBS', '@_moodCode': 'EVN', templateId: [ { '@_root': OID_PROBLEM_OBSERVATION }, { '@_root': OID_PROBLEM_OBSERVATION, '@_extension': '2015-08-01' }, ], id: problem.identifier ? mapIdentifiers(undefined, problem.identifier) : [ { '@_root': generateId(), }, ], text: createTextFromExtensions(problem.extension), code: { '@_code': '55607006', '@_codeSystem': OID_SNOMED_CT_CODE_SYSTEM, '@_codeSystemName': 'SNOMED CT', '@_displayName': 'Problem', translation: [ { '@_code': LOINC_CONDITION, '@_codeSystem': OID_LOINC_CODE_SYSTEM, '@_codeSystemName': 'LOINC', '@_displayName': 'Condition', }, ], }, statusCode: { '@_code': 'completed' }, effectiveTime: [ { low: problem.onsetDateTime ? { '@_value': mapFhirToCcdaDate(problem.onsetDateTime) } : undefined, high: problem.abatementDateTime ? { '@_value': mapFhirToCcdaDateTime(problem.abatementDateTime) } : undefined, }, ], value: mapCodeableConceptToCcdaValue(problem.code), author: converter.mapAuthor(problem.asserter, problem.recordedDate), }, ], }, ], }, ], }; } export function createHealthConcernEntry(converter: FhirToCcdaConverter, healthConcern: Condition): CcdaEntry { const entryRelationship: CcdaEntryRelationship[] = []; if (healthConcern.evidence) { for (const evidence of healthConcern.evidence) { if (evidence.detail) { for (const detailRef of evidence.detail) { const detail = converter.findResourceByReference(detailRef); if (detail?.resourceType === 'Observation') { entryRelationship.push({ '@_typeCode': 'REFR', observation: [ { '@_classCode': 'OBS', '@_moodCode': 'EVN', templateId: [ { '@_root': OID_PROBLEM_OBSERVATION }, { '@_root': OID_PROBLEM_OBSERVATION, '@_extension': '2015-08-01' }, ], id: mapIdentifiers(detail.id, detail.identifier) as CcdaId[], text: createTextFromExtensions(detail.extension), code: { '@_code': '404684003', '@_codeSystem': OID_SNOMED_CT_CODE_SYSTEM, '@_codeSystemName': 'SNOMED CT', '@_displayName': 'Clinical finding (finding)', translation: [ { '@_code': LOINC_CLINICAL_FINDING, '@_codeSystem': OID_LOINC_CODE_SYSTEM, '@_codeSystemName': 'LOINC', '@_displayName': 'Clinical finding', }, ], }, statusCode: { '@_code': 'completed' }, effectiveTime: mapEffectivePeriod(detail.effectivePeriod?.start, detail.effectivePeriod?.end, true), value: mapCodeableConceptToCcdaValue(detail.valueCodeableConcept), author: converter.mapAuthor(detail.performer?.[0], detail.effectiveDateTime), }, ], }); } } } } } return { act: [ { '@_classCode': 'ACT', '@_moodCode': 'EVN', templateId: [ { '@_root': OID_HEALTH_CONCERN_ACT, '@_extension': '2015-08-01' }, { '@_root': OID_HEALTH_CONCERN_ACT, '@_extension': '2022-06-01' }, ], id: mapIdentifiers(healthConcern.id, undefined), code: { '@_code': LOINC_HEALTH_CONCERNS_SECTION, '@_codeSystem': OID_LOINC_CODE_SYSTEM, '@_codeSystemName': 'LOINC', '@_displayName': 'Health Concern', }, statusCode: { '@_code': PROBLEM_STATUS_MAPPER.mapFhirToCcdaWithDefault( healthConcern.clinicalStatus?.coding?.[0]?.code, 'active' ), }, effectiveTime: mapEffectivePeriod(healthConcern.recordedDate, undefined), entryRelationship, }, ], }; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/medplum/medplum'

If you have feedback or need assistance with the MCP directory API, please join our Discord server