Im Rahmen der Veranstaltung "CS3330 - Projektpraktikum MedizinischeInformatik" an der Universität zu Lübeck entstandenes Krankenhausinformationssystem (KIS).
Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

288 linhas
12 KiB

  1. package de.uniluebeck.mi.projmi6.hapi2;
  2. import ca.uhn.hl7v2.AcknowledgmentCode;
  3. import ca.uhn.hl7v2.ErrorCode;
  4. import ca.uhn.hl7v2.HL7Exception;
  5. import ca.uhn.hl7v2.model.AbstractMessage;
  6. import ca.uhn.hl7v2.model.Message;
  7. import ca.uhn.hl7v2.model.v251.group.BAR_P05_PROCEDURE;
  8. import ca.uhn.hl7v2.model.v251.group.BAR_P05_VISIT;
  9. import ca.uhn.hl7v2.model.v251.message.ADT_A01;
  10. import ca.uhn.hl7v2.model.v251.message.BAR_P05;
  11. import ca.uhn.hl7v2.model.v251.segment.*;
  12. import ca.uhn.hl7v2.protocol.ReceivingApplication;
  13. import ca.uhn.hl7v2.protocol.ReceivingApplicationException;
  14. import de.uniluebeck.mi.projmi6.controller.MainController;
  15. import de.uniluebeck.mi.projmi6.db.DBHandler;
  16. import de.uniluebeck.mi.projmi6.model.*;
  17. import javafx.application.Platform;
  18. import java.io.IOException;
  19. import java.sql.SQLException;
  20. import java.time.LocalDateTime;
  21. import java.util.ArrayList;
  22. import java.util.List;
  23. import java.util.Map;
  24. /**
  25. * Created by nils on 20.11.2015.
  26. */
  27. public class HL7Receiver2<T extends AbstractMessage> implements ReceivingApplication {
  28. private final Class<T> type;
  29. private final MainController mainctrl;
  30. public HL7Receiver2(Class<T> type, MainController mainctrl) {
  31. this.type = type;
  32. this.mainctrl = mainctrl;
  33. }
  34. @Override
  35. public Message processMessage(Message message, Map<String, Object> metadata) throws ReceivingApplicationException, HL7Exception {
  36. if (type == ADT_A01.class) {
  37. return processADT_A01(message, metadata);
  38. }
  39. if (type == BAR_P05.class) {
  40. return processBAR_P05(message, metadata);
  41. }
  42. // TODO: Handle unknown Messages, maybe write to database, send ACK and go on.
  43. try {
  44. return message.generateACK();
  45. } catch (IOException e) {
  46. throw new HL7Exception(e);
  47. }
  48. }
  49. @Override
  50. public boolean canProcess(Message message) {
  51. // TODO: Erstmal alles processen.
  52. return true;
  53. }
  54. private Message generateACK(Message message) throws HL7Exception {
  55. try {
  56. return message.generateACK();
  57. } catch (IOException e) {
  58. throw new HL7Exception(e);
  59. }
  60. }
  61. private Message generateACKWithAR(Message message, String s) throws HL7Exception {
  62. try {
  63. return message.generateACK(AcknowledgmentCode.AR, new HL7Exception(s, ErrorCode.UNKNOWN_KEY_IDENTIFIER));
  64. } catch (IOException e) {
  65. throw new HL7Exception(e);
  66. }
  67. }
  68. private Message processBAR_P05(Message message, Map<String, Object> metadata) throws HL7Exception {
  69. BAR_P05 bar_p05 = (BAR_P05) message;
  70. MSH msh = bar_p05.getMSH();
  71. PID pid = bar_p05.getPID();
  72. int patid = Integer.parseInt(pid.getPatientID().encode());
  73. Patient patient = mainctrl.getStammdaten().getPatienten().stream().filter(p -> p.getPatID() == patid).findFirst().orElse(null);
  74. if (patient == null) {
  75. logInHL7MessageToDatabase(message, msh, metadata);
  76. updateUI(new HL7Message(patient, -1, LocalDateTime.now(), "Patient nicht gefunden.", true));
  77. return generateACKWithAR(message, "Patient nicht gefunden.");
  78. }
  79. List<BAR_P05_VISIT> visits = bar_p05.getVISITAll();
  80. List<Integer> updatedFallIDs = new ArrayList<>();
  81. // Ab hier wird es dirty.
  82. for (BAR_P05_VISIT visit : visits) {
  83. PV1 pv1 = visit.getPV1();
  84. int fallid = Integer.parseInt(pv1.getVisitNumber().encode());
  85. List<Integer> fallids = new ArrayList<>();
  86. try {
  87. fallids = DBHandler.getAlleFallIdsByPatID(patient.getPatID());
  88. } catch (SQLException e) {
  89. e.printStackTrace();
  90. }
  91. if (fallids.isEmpty() || !fallids.contains(fallid)) {
  92. logInHL7MessageToDatabase(message, msh, metadata);
  93. updateUI(new HL7Message(patient, -1, LocalDateTime.now(), "Fall nicht gefunden.?", true));
  94. return generateACKWithAR(message, "Fall nicht gefunden.");
  95. }
  96. Fall fall = new Fall();
  97. fall.setFallID(fallid);
  98. fall.setPatient(patient);
  99. List<Diagnose> diagnosen = new ArrayList<>();
  100. List<Untersuchung> untersuchungen = new ArrayList<>();
  101. // Station(PV1-3-1), Fachabteilung(PV1-3-4), Aufnahmedatum(PV1-44), Entlassungsdatum(PV1-45), Fallnummer(PV1-19)
  102. Station station = new Station();
  103. station.setStation(pv1.getAssignedPatientLocation().getPointOfCare().encode());
  104. station.setAbteilung(pv1.getAssignedPatientLocation().getFacility().encode());
  105. StationsHistorie hist = new StationsHistorie();
  106. hist.setStationKey(station.getStation());
  107. hist.setAufnahmeDatum(HL7Util2.parseLocalDateTime(pv1.getAdmitDateTime().getTime()));
  108. hist.setEntlassungsDatum(HL7Util2.parseLocalDateTime(pv1.getDischargeDateTime()[0].getTime())); // TODO: null?
  109. hist.setFallID(fallid);
  110. List<DG1> dg1s = visit.getDG1All();
  111. for (DG1 dg1 : dg1s) {
  112. Diagnose diagnose = new Diagnose();
  113. diagnose.setErsteller(99999);
  114. diagnose.setBearbeiter(99999);
  115. diagnose.setFall(fall);
  116. String icd10 = dg1.getDiagnosisCodeDG1().getIdentifier().encode();
  117. Icd10Code icd10code = mainctrl.getStammdaten().getIcd10Codes().stream().filter(i -> i.getCode().equals(icd10)).findFirst().orElse(null);
  118. if (icd10code == null) {
  119. // TODO: Oder einfach ueberspringen?
  120. continue;
  121. // TODO: Behandeln von sonder Codes. K35.9V (Verdacht...)
  122. // logInHL7MessageToDatabase(message, msh, metadata);
  123. // updateUI(new HL7Message(patient, -1, LocalDateTime.now(), "ICD10 Code nicht gefunden.", true));
  124. // return generateACKWithAR(message, "ICD10 Code nicht gefunden.");
  125. }
  126. diagnose.setIcd10code(icd10code);
  127. // Mitarbeiter ID anhand von EinweisenderArzt erkennen.
  128. Mitarbeiter mitarbeiter;
  129. if (dg1.getDiagnosingClinician().length != 0) {
  130. String einweisenderarzt = dg1.getDiagnosingClinician(0).encode(); // Wir holen uns immer den ersten der verantwortlichen Aerzte... // (DG1-16)
  131. mitarbeiter = mainctrl.getStammdaten().getMitarbeiter().stream().filter(m -> m.getEinweisenderArzt().equals(einweisenderarzt)).findFirst().orElse(null);
  132. if (mitarbeiter == null) {
  133. logInHL7MessageToDatabase(message, msh, metadata);
  134. updateUI(new HL7Message(patient, -1, LocalDateTime.now(), "Mitarbeiter nicht gefunden.", true));
  135. return generateACKWithAR(message, "Mitarbeiter nicht gefunden.");
  136. }
  137. } else {
  138. mitarbeiter = new Mitarbeiter(99999);
  139. }
  140. diagnose.setArzt(mitarbeiter);
  141. // (DG1-6) // TODO: Enum umstellen? Neeee...
  142. String diagart = dg1.getDiagnosisType().encode();
  143. switch (diagart) {
  144. case "A":
  145. diagnose.setDiagArt(DiagArt.EINWEISUNG);
  146. break;
  147. case "F":
  148. diagnose.setDiagArt(DiagArt.ENTLASSUNG);
  149. break;
  150. case "W":
  151. default:
  152. diagnose.setDiagArt(DiagArt.VERDACHT);
  153. }
  154. diagnosen.add(diagnose);
  155. }
  156. List<BAR_P05_PROCEDURE> procedures = visit.getPROCEDUREAll();
  157. for (BAR_P05_PROCEDURE procedure : procedures) {
  158. PR1 pr1 = procedure.getPR1();
  159. Untersuchung untersuchung = new Untersuchung();
  160. untersuchung.setErsteller(99999);
  161. untersuchung.setBearbeiter(99999);
  162. untersuchung.setFall(fall);
  163. String ops = pr1.getProcedureCode().encode();
  164. OpsCode opscode = mainctrl.getStammdaten().getOpsCodes().stream().filter(o -> o.getOpsCode().equals(ops)).findFirst().orElse(null);
  165. if (opscode == null) {
  166. // TODO: Oder einfach ueberspringen?
  167. continue;
  168. // TODO: Behandeln von sonder Codes.
  169. // logInHL7MessageToDatabase(message, msh, metadata);
  170. // updateUI(new HL7Message(patient, -1, LocalDateTime.now(), "OPS Code nicht gefunden.", true));
  171. // return generateACKWithAR(message, "OPS Code nicht gefunden.");
  172. }
  173. untersuchung.setOpscode(opscode);
  174. untersuchung.setUntersuchungsdatum(HL7Util2.parseLocalDateTime(pr1.getProcedureDateTime().getTime()));
  175. // Mitarbeiter ID anhand von EinweisenderArzt erkennen.
  176. Mitarbeiter mitarbeiter;
  177. if (pr1.getProcedurePractitioner().length != 0) {
  178. String einweisenderarzt = pr1.getProcedurePractitioner(0).encode(); // Wir holen uns immer den ersten der verantwortlichen Aerzte...
  179. mitarbeiter = mainctrl.getStammdaten().getMitarbeiter().stream().filter(m -> m.getEinweisenderArzt().equals(einweisenderarzt)).findFirst().orElse(null);
  180. if (mitarbeiter == null) {
  181. logInHL7MessageToDatabase(message, msh, metadata);
  182. updateUI(new HL7Message(patient, -1, LocalDateTime.now(), "Mitarbeiter nicht gefunden.", true));
  183. return generateACKWithAR(message, "Mitarbeiter nicht gefunden.");
  184. }
  185. } else {
  186. mitarbeiter = new Mitarbeiter(99999);
  187. }
  188. untersuchung.setDurchfuehrenderArzt(mitarbeiter);
  189. untersuchungen.add(untersuchung);
  190. }
  191. // Hier jeweils Untersuchung und Diagnose in die Datenbank schreiben.
  192. diagnosen.forEach(d -> {
  193. try {
  194. DBHandler.setDiagnose(d);
  195. } catch (SQLException e) {
  196. e.printStackTrace();
  197. }
  198. });
  199. untersuchungen.forEach(u -> {
  200. try {
  201. DBHandler.setUntersuchung(u, 99999, false);
  202. } catch (SQLException e) {
  203. e.printStackTrace();
  204. }
  205. });
  206. // Remember welche Faelle geaendert wurden
  207. updatedFallIDs.add(fallid);
  208. }
  209. // HL7 Nachricht loggen.
  210. logInHL7MessageToDatabase(message, msh, metadata);
  211. // TODO: Runnable...??? Jojo???
  212. updatedFallIDs.forEach(id -> updateUI(new HL7Message(patient, id, LocalDateTime.now(), "Was soll hier wohl stehen?", false)));
  213. return generateACK(message);
  214. }
  215. private Message processADT_A01(Message message, Map<String, Object> metadata) throws HL7Exception {
  216. ADT_A01 adt_a01 = (ADT_A01) message;
  217. System.out.println(adt_a01.toString());
  218. return generateACK(message);
  219. }
  220. private void logHL7MessageToDatabase(Message message, MSH msh, Map<String, Object> metadata, HL7LogEntry.Direction direction) throws HL7Exception {
  221. String sendind_ip = metadata.get("SENDING_IP").toString();
  222. String sendind_port = metadata.get("SENDING_PORT").toString();
  223. LocalDateTime ldt = HL7Util2.parseLocalDateTime(msh.getDateTimeOfMessage().getTime());
  224. HL7LogEntry entry = new HL7LogEntry();
  225. entry.setMessage(message.encode());
  226. entry.setTimestamp(ldt);
  227. entry.setSource(sendind_ip + ":" + sendind_port);
  228. entry.setDirection(direction);
  229. try {
  230. // DBHandler.setHL7Nachricht(message.encode(), ldt, sendind_ip + ":" + sendind_port);
  231. DBHandler.setHL7LogEntry(entry);
  232. } catch (SQLException e) {
  233. e.printStackTrace();
  234. }
  235. }
  236. private void logInHL7MessageToDatabase(Message message, MSH msh, Map<String, Object> metadata) throws HL7Exception {
  237. logHL7MessageToDatabase(message, msh, metadata, HL7LogEntry.Direction.IN);
  238. }
  239. private void updateUI(HL7Message hl7message) {
  240. Platform.runLater(() -> mainctrl.getMessageController().addMessage(hl7message));
  241. }
  242. }