Artículo
· 9 jun, 2023 Lectura de 16 min

Instalación y adaptación de EMPI en modo Standalone - Personalización de datos de paciente

Empezaré como dice la leyenda que empezó su clase Fray Luís de León tras varios años de condena:

Como decíamos ayer...nuestro EMPI puede recibir datos de múltiples fuentes, vía REST, mensajería HL7, etc. Pero es posible que los campos estándar no sean suficientes y querramos ampliar la información del paciente para ayudar a discriminarlo e identificarlo unívocamente. ¿Cómo podríamos personalizar los datos de paciente? ¿Modificando las clases estándar a nuestro gusto? ¡¡¡¡NOOOOO!!!! bueno, un poco sí, pero no a lo loco, ya que si tocamos clases estándar sin cuidado podremos encontrarnos que en una futura actualización perdamos todas estas modificaciones.

Personalización de los datos de paciente

Muy bien, continuemos con la configuración de nuestro EMPI en el que hemos introducido una serie de pacientes. Imaginad que hemos decidido incluir el grupo sanguíneo como un criterio para ayudar en el proceso del cálculo de pesos. Recordemos que clases definían los datos del paciente.

Por un lado tenemos el objeto que vamos a persistir y que lo encontramos en el Definition Designer:

Por el otro lado tenemos el objeto que vamos a retornar en las búsquedas y que corresponde al "Composite Record" configurado previamente desde la opción de Configuration Registry.

 

Echemos un ojo a HSPI.Data.Patient, en concreto a la declaración de la clase:

Class HSPI.Data.Patient Extends (%Persistent, HSPI.Data.Type.Patient, %MPRL.Linkage.Base) 

Podemos observar que sus propiedades son heredadas de HSPI.Data.Type.Patient, si accedemos a dicha clase veremos que disponemos de una serie de valores correspondiente a las propiedades del objeto paciente. Como hemos dicho, podríamos añadir aquí los campos que necesitáramos...pero eso NO ES RECOMENDABLE, tenemos una opción mejor que no se verá afectada por las actualizaciones de versiones. Si vamos hasta el final de la clase HSPI.Data.Type.Patient nos encontramos la siguiente propiedad:

Property Extension As HS.Local.SDA3.PatientExtension;

Esta propiedad es la que nos permitirá añadir tantos campos como deseemos a nuestro objeto paciente. Como véis, al pertenecer al Local evitará que en los futuros cambios de versión esta información se pierda. Abramos HS.Local.SDA3.PatientExtension e incluyamos la propiedad BloodType como un simple String:

Class HS.Local.SDA3.PatientExtension Extends HS.SDA3.DataType
{

Parameter HSDEPLOY = 0;
Parameter STREAMLETCLASS = "HS.SDA3.Streamlet.Patient";
Property BloodType As %String;
}

Perfecto, nuestro objeto está preparado para recibir dicha información. ¿Cómo podemos enviar esta nueva información a nuestro sistema? Como vimos en el artículo anterior, nuestro EMPI dispone de una configuración por defecto que puede recibir mensajería HL7 y que ya hemos utilizado para añadir pacientes.

Creación de nuevo esquema de HL7

En nuestro ejemplo usaremos un mensaje A28 al que añadiremos un nuevo segmento con la información del tipo sanguineo. Para ello vamos a crear un nuevo esquema basado en el esquema estándar 2.5.1 y vamos a crear un nuevo DocType para el tipo de mensaje A28.

Aquí tenemos nuestro nuevo esquema HealthShare_2.5 que como véis, extiende del estándar 2.5.1 y hemos creado una nueva estructura de mensaje del tipo A28. Para añadir un nuevo segmento crearemos primeramente dicho segmento al que llamaremos ZBTy le añadiremos el campo que contendrá el tipo sanguíneo:

Con el segmento creado sólo necesitamos incluirlo a la estructura del mensaje y podremos empezar a trabajar con estos mensajes personalizados:

Perfecto, mensaje configurado con nuestro segmento ZBT. Veamos ahora un ejemplo del tipo de mensaje que vamos a recibir con el nuevo segmento:

MSH|^~\&|HIS|HULP|EMPI||20230329085239||ADT^A28|72104|P|HealthShare_2.5
EVN|A28|20230329085239|20230329085239|1
PID|||1502935519^^^SERMAS^SN~424392^^^HULP^PI||CABEZUELA SANZ^PEDRO^^^||20160627|M|||PASEO JULIA ÁLVAREZ^395 3 E^MADRID^MADRID^28909^SPAIN||555710791^PRN^^PEDRO.CABEZUELA@GMAIL.COM|||||||||||||||||N|
PV1||N
ZBT|A-

En nuestro ejemplo el paciente Pedro Cabezuela Sanz tiene un tipo sanguíneo A-.

Configuración de la producción del EMPI:

Como vimos en el anterior artículo de configuración del EMPI, disponemos de una producción configurada por defecto que nos permite operar inmediatamente con nuestro EMPI. 

En nuestro ejemplo estamos usando el Business Service EnsLib.HL7.Service.FileService que capturará ficheros con mensajes HL7 de la ruta especificada, para adaptarlo al nuevo tipo de mensajes que vamos a recibir modificaremos el Message Schema Category para hacer referencia al nuevo esquema creado. Echemos un ojo a uno de los ejemplos de los mensajes que enviamos en el ejemplo del artículo anterior para identificar los Business Components por los que pasan nuestros mensaje y poder identificarlos:

Nuestro mensaje entra por EnsLib.HL7.Service.FileService y este se redirige a HS.Hub.Standalone.HL7.Operation, aquí tenemos la configuración de dicho Business Operation:

Observamos que tenemos un atributo llamado HL7ToSDA3Class configurado con la clase HS.Hub.Standalone.HL7.HL7ToSDA3. Abramos la clase y comprobemos cual es su funcionalidad.

 
HS.Hub.Standaline.HL7.HL7ToSDA3

Esta clase pertenece al estándar y no tenemos interés en modificar nada de la misma, por lo que vamos a crear una nueva Local que extenderá de la clase estándar:

Class Local.Hub.Standalone.HL7.HL7ToSDA3 Extends HS.Hub.Standalone.HL7.HL7ToSDA3
{

ClassMethod GetTransformClass(msgType As %String, ByRef pTransformClass As %String) As %Status
{
    {
	set tSC=$$$OK
	set pTransformClass=..OnGetTransformClass() 
	quit:pTransformClass'=""
	set pTransformClass = $CASE(msgType,
              "ADT_A01":"ADTA01ToSDA3", "ADT_A02":"ADTA02ToSDA3", "ADT_A03":"ADTA03ToSDA3",
              "ADT_A04":"ADTA01ToSDA3", "ADT_A05":"ADTA05ToSDA3", "ADT_A06":"ADTA01ToSDA3",
              "ADT_A07":"ADTA01ToSDA3", "ADT_A08":"ADTA01ToSDA3", "ADT_A09":"ADTA01ToSDA3",
              "ADT_A10":"ADTA01ToSDA3", "ADT_A11":"ADTA09ToSDA3", "ADT_A12":"ADTA01ToSDA3",
              "ADT_A13":"ADTA01ToSDA3", "ADT_A16":"ADTA01ToSDA3", "ADT_A17":"ADTA01ToSDA3",
              "ADT_A18":"ADTA18ToSDA3", "ADT_A23":"ADTA21ToSDA3", "ADT_A25":"ADTA01ToSDA3",
              "ADT_A27":"ADTA01ToSDA3", "ADT_A28":"ADTA28ToSDA3", "ADT_A29":"ADTA21ToSDA3",
              "ADT_A30":"ADTA30ToSDA3", "ADT_A31":"ADTA05ToSDA3", "ADT_A34":"ADTA30ToSDA3",
              "ADT_A36":"ADTA30ToSDA3", "ADT_A39":"ADTA40ToSDA3", "ADT_A40":"ADTA40ToSDA3",
              "ADT_A45":"ADTA45ToSDA3", "ADT_A47":"ADTA30ToSDA3", "ADT_A50":"ADTA50ToSDA3",
              "ADT_A60":"ADTA60ToSDA3", "BAR_P12":"BARP12ToSDA3", "MDM_T02":"MDMT02ToSDA3",
              "MDM_T04":"MDMT02ToSDA3", "MDM_T08":"MDMT02ToSDA3", "MDM_T11":"MDMT01ToSDA3",
              "OMP_O09":"OMPO09ToSDA3", "ORM_O01":"ORMO01ToSDA3", "ORU_R01":"ORUR01ToSDA3",
              "PPR_PC1":"PPRPC1ToSDA3", "PPR_PC2":"PPRPC1ToSDA3", "PPR_PC3":"PPRPC1ToSDA3",
              "RDE_O11":"RDEO11ToSDA3", "SIU_S12":"SIUS12ToSDA3", "SIU_S13":"SIUS12ToSDA3",
              "SIU_S14":"SIUS12ToSDA3", "SIU_S15":"SIUS12ToSDA3", "SIU_S16":"SIUS12ToSDA3",
              "SIU_S17":"SIUS12ToSDA3", "SIU_S26":"SIUS12ToSDA3", "VXU_V04":"VXUV04ToSDA3",
              :"Unsupported HL7 Message Type")

	set:pTransformClass="Unsupported HL7 Message Type" tSC = $$$HSError($$$HSErrUnsupportedHL7MessageType,msgType)
 	if $$$ISERR(tSC) quit tSC
 	if (msgType = "ADT_A28") {
 		set tTransformPackage = "Local.Hub.Standalone.HL7.DTL"
 	}
 	else {
 		set tTransformPackage = "HS.Hub.Standalone.HL7.DTL"
 	}
 	set pTransformClass = tTransformPackage_"."_pTransformClass
	
	quit tSC
}

}

De todas sus clases la que más nos interesa es GetTransformClass la cual nos va a indicar que transformación debemos realizar dependiendo del tipo de mensaje recibido. Como en nuestro caso hemos escogido el mensaje A28 como el portador del nuevo segmento con la información del grupo sanguíneo deberemos encontrar dicha transformación dentro del comando $CASE:

"ADT_A28":"ADTA05ToSDA3"

Aquí tenemos nuestra transformación inicial, como podemos ver, la estructura del mensaje ADT_A28 es la de ADT_A05, por ello tiene dicha transformación configurada por defecto, en nuestro caso vamos a crear una nueva transformación copiando la ADTA05ToSDA3 y la denominaremos ADTA28ToSDA3, remplazando el valor que tenía en el $CASE a:

"ADT_A28":"ADTA28ToSDA3"

Si véis hemos incluido una condición para que cuando se reciba un ADT_A28 está utilice la transformación con el package Local.Hub.Standalone.HL7.DTL

Con la clase  Local.Hub.Standalone.HL7.HL7ToSDA3 compilada abreremos nuevamente nuestra producción y definiremos el valor del parámetro HL7ToSDA3Class en el Business Operation HS.Hub.Standalone.HL7.Operation con la nueva clase implementada Local.Hub.Standalone.HL7.HL7ToSDA3

Perfecto, hemos concluido la configuración de nuestra producción. Sólo nos queda un pequeño detalle...¡aún no hemos creado nuestra transformación ADTA28ToSDA3!

Creación de transformación personalizada:

Desde el menú de las lista de transformaciones buscaremos la ADTA05ToSDA3.

Aquí la tenemos, abrámosla y procedamos a guardarla con otro nombre y Package para crear una copia de la misma.

Con la nueva clase creada podemos empezar la transformación, deberemos realizar las siguientes tareas:

  • Modificar el Source Doc Type de 2.5.1:ADT_A05 a HealthShare_2.5:ADT_A28. Recordar que hemos creado una nueva estructura de mensaje A28.
  • Asignar el valor del campo BloodType del segmento ZBT de nuestro mensaje al campo BloodType que encontramos dentro de la propiedad Extension incluida en Patient. Este campo BloodType está disponible al haber añadido la propiedad BloodType en la clase HS.Local.SDA3.PatientExtension.

La transformación quedaría tal que así:

Muy bien, repasemos lo que hemos hecho hasta ahora:

  • Creación del campo BloodType en la clase HS.Local.SDA3.PatientExtension para almacenar la información personalizada.
  • Extensión del esquema 2.5.1 de HL7 para añadir un segmento Z personalizado a los mensajes A28.
  • Extensión de la clase HS.Hub.Standalone.HL7.HL7ToSDA3 para indicar la transformación a realizar al recibir el A28.
  • Creación de la transformación ADTA28ToSDA3.

Con todo lo anterior ya podemos enviar mensajes con el grupo sanguíneo en el nuevo segmento y almacenarlo con los datos del paciente como una extensión. ¿Qué nos faltaría para concluir la personalización? ¡El Local.CompositeRecord.Transient.Definition! Estamos guardando los datos correctamente pero no hemos modificado la clase usada para cargar grupo sanguíneo en los datos relevantes del paciente.

Configuración del CompositeRecord

Veamos como se muestran los datos en el CompositeRecord:

<propertyGroup name="Gender" trustBlock="base" description="Gender - base: all tier 5">
<property>Gender</property>
</propertyGroup>

 Definimos el grupo al que van a pertenecer los nuevos datos y la propiedad del mismo en el objeto paciente. En nuestro caso la propiedad BloodType está colgando de la propiedad Extension, por lo que nuestro nuevo grupo será tal que así:

<propertyGroup name="Extension" trustBlock="base" description="Extension - base: all tier 5">
<property name='Blood Type'>Extension.BloodType</property>
</propertyGroup>

En nuestro caso lo hemos denominado Extension, pero podría ser cualquier otro nombre.

Una vez editado nuestra clase Local.CompositeRecord.Transient.Definition ya podemos lanzar una batería de pruebas con nuestros mensajes A28 personalizados arrancando la producción.

Pruebas:

Comprobemos la traza de uno de los mensajes introducidos:

Ahí tenemos nuestro segmento ZBT con el valor B+. Veamos como se mapea al objeto:

Ahí tenemos nuestro campo Extension con la nueva propiedad BloodType. Lancemos una búsqueda de dicho paciente registrado con el MPIID 100000350.

Aquí está el campo Extension y su valor B+. Podríamos cambiar el nombre de la etiqueta y llamarlo Blood Type sin ningún problema.

Pues esto sería todo, hemos configurado nuestro EMPI para recibir campos personalizados, para registrarlos como datos del paciente y para devolverlos.

Si tenéis alguna pregunta o sugerencia no dudeis en escribir un comentario al respecto.

Comentarios (0)1
Inicie sesión o regístrese para continuar