Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions core/term/controller/snomed.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,25 @@ export interface ISnomedController {
* Busca un array de conceptos SNOMED.
*/

getConcepts(conceptsIds: String[]);
getConcepts(conceptsIds: String[], form?: String);

/**
* Busca conceptos por un texto.
* Para el buscador de RUP.
*/

searchTerms(text: String, options: { semanticTags?: String[]; languageCode?: 'es' | 'en'; expression?: string });
searchTerms(text: String, options: { semanticTags?: String[]; languageCode?: 'es' | 'en'; expression?: string; form?: String });

/**
* Busca valores concretos por relaciones entre conceptos
*/

getValuesByRelationships(expression: String, type: string);

/**
* Busca conceptos por expresión utilizando browser (trae relaciones)
*/
searchTermWithRelationship(options: { text: String; languageCode?: 'es' | 'en'; expression?: String; semanticTags?: String[] });
}

export const SnomedCtr: ISnomedController = SnomedSnowstorm as any;
53 changes: 50 additions & 3 deletions core/term/controller/snomed.snowstorm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,15 +115,15 @@ export async function getChildren(sctid, { all = false, completed = true, leaf =
return null;
}

export async function getConcepts(conceptsIds: string[]) {
export async function getConcepts(conceptsIds: string[], form = 'stated') {
const response = await httpGetSnowstorm(`${snomed.snowstormBranch}/concepts`, {
limit: 1000,
conceptIds: conceptsIds
});
if (response) {
const items = response.items;
const ps = items.map(async (concept) => {
const parents = await httpGetSnowstorm(`browser/${snomed.snowstormBranch}/concepts/${concept.conceptId}/parents`, { limit: 1000, form: 'stated' });
const parents = await httpGetSnowstorm(`browser/${snomed.snowstormBranch}/concepts/${concept.conceptId}/parents`, { limit: 1000, form });
if (parents) {
concept.relationships = parents;
concept.relationships = filterRelationships(concept, { parent: true });
Expand Down Expand Up @@ -204,6 +204,7 @@ async function searchByExpression({ text, languageCode, expression, semanticTags
ecl: expression
};
const response = await httpGetSnowstorm(`${snomed.snowstormBranch}/concepts`, qs, languageCode);

if (response) {
let { items } = response;
items = items.map(cpt => {
Expand All @@ -222,8 +223,54 @@ async function searchByExpression({ text, languageCode, expression, semanticTags
return [];
}

export async function searchTermWithRelationship({ text, languageCode, expression, semanticTags }) {
const qs: any = {
term: text,
activeFilter: true,
termActive: true,
language: languageCode,
limit: 20,
ecl: expression
};
const response = await httpGetSnowstorm(`${snomed.snowstormBranch}/concepts`, qs, languageCode);

if (response) {
let items = [];
if (response.items) {
const conceptIds = response.items.map(c => c.conceptId);
if (conceptIds.length > 0) {
const qsConcepts = { conceptIds };
const concepts = await httpGetSnowstorm(`browser/${snomed.snowstormBranch}/concepts`, qsConcepts, languageCode);
items = concepts.items.map(cpt => {
const relationships = cpt.relationships ? cpt.relationships.filter(rel => rel.active && rel.typeId === IsASct && rel.target).map(rel => {
return {
conceptId: rel.target.conceptId,
term: rel.target.pt?.term || rel.target.fsn?.term,
fsn: rel.target.fsn?.term,
type: rel.characteristicType === 'INFERRED_RELATIONSHIP' ? 'inferred' : 'stated'
};
}) : [];

return {
conceptId: cpt.conceptId,
term: cpt.pt?.term || cpt.fsn?.term,
fsn: cpt.fsn?.term,
semanticTag: cpt.fsn?.term ? getSemanticTagFromFsn(cpt.fsn.term) : '',
relationships
};
});
}
}
if (semanticTags) {
items = items.filter(concept => semanticTags.includes(concept.semanticTag));
}
return items;
}
return [];
}

export async function getValuesByRelationships(expression: string, type: string) {
const response = await searchTerms(null, { semanticTags:null, languageCode: 'es',expression });
const response = await searchTerms(null, { semanticTags: null, languageCode: 'es', expression });
if (response) {
const ps = response.map(async (concept) => {
const concreteValues = await httpGetSnowstorm(`${snomed.snowstormBranch}/relationships?active=true&source=${concept.conceptId}&type=${type}`, { limit: 1000 });
Expand Down
22 changes: 21 additions & 1 deletion core/term/routes/snomed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import * as express from 'express';
import * as utils from '../../../utils/utils';
import * as cie10 from '../schemas/cie10';
import { SnomedCIE10Mapping } from './../controller/mapping';

import { SnomedCtr } from '../controller/snomed.controller';
import { ECLQueriesCtr } from './../../../core/tm/eclqueries.routes';

const router = express.Router();

Expand Down Expand Up @@ -37,6 +37,26 @@ router.get('/snomed', async (req, res, next) => {
}
});

/** * Busca medicamentos genéricos y comerciales por termino */
router.get('/snomed/medicamentos', async (req, res, next) => {
const term = req.query.term as string;
if (!term) {
return res.json([]);
}
try {
const ecl = await ECLQueriesCtr.findOne({ key: 'receta:buscarTerminos' });
const expression = ecl.valor;
const results = await SnomedCtr.searchTermWithRelationship({ text: term, expression, languageCode: 'es', semanticTags: ['fármaco de uso clínico', 'fármaco de uso clínico comercial'] });

if (results.length > 0) {
return res.json(results);
}

return res.json([]);
} catch (e) {
return next(e);
}
});
/**
* Mapea un concepto de snomed
*
Expand Down
42 changes: 42 additions & 0 deletions core/term/routes/snomedv2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,46 @@ router.get('/snomed/relationships', async (req, res, next) => {
}
});

/**
* Busca medicamentos por nombre comercial y devuelve el concepto con sus padres (genéricos)
*/
router.get('/snomed/medicamentos/comercial', async (req, res, next) => {
const term = req.query.term as string;
if (!term) {
return res.json([]);
}
try {
const results = await SnomedCtr.searchTerms(term, { expression: '<<373873005', languageCode: 'es' });
const ids = results.slice(0, 20).map(r => r.conceptId);
if (ids.length > 0) {
const concepts = await SnomedCtr.getConcepts(ids);
return res.json(concepts);
}
return res.json([]);
} catch (e) {
return next(e);
}
});

/**
* Busca el concepto genérico asociado a un concepto comercial
*/
router.get('/snomed/medicamentos/comercial/:sctid/generico', async (req, res, next) => {
const sctid = req.params.sctid;
try {
const concepts = await SnomedCtr.getConcepts([sctid], 'inferred');
if (concepts && concepts.length > 0) {
const concept = concepts[0];
if (concept.relationships && concept.relationships.length > 0) {
const parentIds = concept.relationships.map(r => r.conceptId);
const generics = await SnomedCtr.getConcepts(parentIds, 'inferred');
return res.json(generics);
}
}
return res.json([]);
} catch (e) {
return next(e);
}
});

export = router;