Im Rahmen der Veranstaltung "CS3330 - Projektpraktikum MedizinischeInformatik" an der Universität zu Lübeck entstandenes Krankenhausinformationssystem (KIS).
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

268 行
12 KiB

  1. package de.uniluebeck.mi.projmi6.hapi;
  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 HL7Receiver<T extends AbstractMessage> implements ReceivingApplication {
  28. private final Class<T> type;
  29. private final MainController mainctrl;
  30. public HL7Receiver(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. return type.isInstance(message);
  52. }
  53. private Message generateACK(Message message) throws HL7Exception {
  54. try {
  55. return message.generateACK();
  56. } catch (IOException e) {
  57. throw new HL7Exception(e);
  58. }
  59. }
  60. private Message generateACKWithAR(Message message, String s) throws HL7Exception {
  61. try {
  62. return message.generateACK(AcknowledgmentCode.AR, new HL7Exception(s, ErrorCode.UNKNOWN_KEY_IDENTIFIER));
  63. } catch (IOException e) {
  64. throw new HL7Exception(e);
  65. }
  66. }
  67. private Message processBAR_P05(Message message, Map<String, Object> metadata) throws HL7Exception {
  68. BAR_P05 bar_p05 = (BAR_P05) message;
  69. MSH msh = bar_p05.getMSH();
  70. PID pid = bar_p05.getPID();
  71. int patid = Integer.parseInt(pid.getPatientID().encode());
  72. Patient patient = mainctrl.getStammdaten().getPatienten().stream().filter(p -> p.getPatID() == patid).findFirst().orElse(null);
  73. if (patient == null) {
  74. HL7Util.logInHL7MessageToDatabase(message, msh, metadata);
  75. updateUI(new HL7Message(null, -1, LocalDateTime.now(), "Patient nicht gefunden.", true));
  76. return generateACKWithAR(message, "Patient nicht gefunden.");
  77. } // TODO: Patienten und Fall neu anlegen??? Nicht verlangt!
  78. List<BAR_P05_VISIT> visits = bar_p05.getVISITAll();
  79. List<Integer> updatedFallIDs = new ArrayList<>();
  80. // Ab hier wird es dirty.
  81. for (BAR_P05_VISIT visit : visits) {
  82. PV1 pv1 = visit.getPV1();
  83. int fallid = Integer.parseInt(pv1.getVisitNumber().encode());
  84. List<Integer> fallids = new ArrayList<>();
  85. try {
  86. fallids = DBHandler.getAlleFallIdsByPatID(patient.getPatID());
  87. } catch (SQLException e) {
  88. e.printStackTrace();
  89. }
  90. if (fallids.isEmpty() || !fallids.contains(fallid)) {
  91. HL7Util.logInHL7MessageToDatabase(message, msh, metadata);
  92. updateUI(new HL7Message(patient, -1, LocalDateTime.now(), "Fall nicht gefunden.?", true));
  93. return generateACKWithAR(message, "Fall nicht gefunden.");
  94. }
  95. Fall fall = new Fall();
  96. fall.setFallID(fallid);
  97. fall.setPatient(patient);
  98. List<Diagnose> diagnosen = new ArrayList<>();
  99. List<Untersuchung> untersuchungen = new ArrayList<>();
  100. // Station(PV1-3-1), Fachabteilung(PV1-3-4), Aufnahmedatum(PV1-44), Entlassungsdatum(PV1-45), Fallnummer(PV1-19)
  101. String stat = pv1.getAssignedPatientLocation().getPointOfCare().encode();
  102. Station station = mainctrl.getStammdaten().getStationen().stream().filter(s -> s.getStation().equals(stat)).findFirst().orElse(null);
  103. // TODO: Stationen mit falschen Abteilungen werden einfach umgeschrieben^^
  104. if (station == null) {
  105. HL7Util.logInHL7MessageToDatabase(message, msh, metadata);
  106. updateUI(new HL7Message(patient, -1, LocalDateTime.now(), "Station nicht gefunden.", true));
  107. return generateACKWithAR(message, "Station nicht gefunden.");
  108. }
  109. StationsHistorie hist = new StationsHistorie(); // TODO: StationsHist schreiben/schon vorhanden!
  110. hist.setStationKey(station.getStation());
  111. hist.setAufnahmeDatum(HL7Util.parseLocalDateTime(pv1.getAdmitDateTime().getTime()));
  112. hist.setEntlassungsDatum(HL7Util.parseLocalDateTime(pv1.getDischargeDateTime()[0].getTime())); // TODO: null?
  113. hist.setFallID(fallid);
  114. List<DG1> dg1s = visit.getDG1All();
  115. for (DG1 dg1 : dg1s) {
  116. Diagnose diagnose = new Diagnose();
  117. diagnose.setErsteller(99999);
  118. diagnose.setBearbeiter(99999);
  119. diagnose.setFall(fall);
  120. String icd10 = dg1.getDiagnosisCodeDG1().getIdentifier().encode();
  121. Icd10Code icd10code = mainctrl.getStammdaten().getIcd10Codes().stream().filter(i -> i.getCode().equals(icd10)).findFirst().orElse(null);
  122. if (icd10code == null) {
  123. // TODO: Oder einfach ueberspringen?
  124. continue;
  125. // TODO: Behandeln von sonder Codes. K35.9V (Verdacht...)
  126. // logInHL7MessageToDatabase(message, msh, metadata);
  127. // updateUI(new HL7Message(patient, -1, LocalDateTime.now(), "ICD10 Code nicht gefunden.", true));
  128. // return generateACKWithAR(message, "ICD10 Code nicht gefunden.");
  129. }
  130. diagnose.setIcd10code(icd10code);
  131. // Mitarbeiter ID anhand von EinweisenderArzt erkennen.
  132. Mitarbeiter mitarbeiter;
  133. if (dg1.getDiagnosingClinician().length != 0) {
  134. String einweisenderarzt = dg1.getDiagnosingClinician(0).encode(); // Wir holen uns immer den ersten der verantwortlichen Aerzte... // (DG1-16)
  135. mitarbeiter = mainctrl.getStammdaten().getMitarbeiter().stream().filter(m -> m.getEinweisenderArzt().equals(einweisenderarzt)).findFirst().orElse(null);
  136. if (mitarbeiter == null) {
  137. HL7Util.logInHL7MessageToDatabase(message, msh, metadata);
  138. updateUI(new HL7Message(patient, -1, LocalDateTime.now(), "Mitarbeiter nicht gefunden.", true));
  139. return generateACKWithAR(message, "Mitarbeiter nicht gefunden.");
  140. }
  141. } else {
  142. mitarbeiter = new Mitarbeiter(99999);
  143. }
  144. diagnose.setArzt(mitarbeiter);
  145. // (DG1-6) // TODO: Enum umstellen? Neeee...
  146. String diagart = dg1.getDiagnosisType().encode();
  147. switch (diagart) {
  148. case "A":
  149. diagnose.setDiagArt(DiagArt.EINWEISUNG);
  150. break;
  151. case "F":
  152. diagnose.setDiagArt(DiagArt.ENTLASSUNG);
  153. break;
  154. case "W":
  155. default:
  156. diagnose.setDiagArt(DiagArt.VERDACHT);
  157. }
  158. diagnose.setFreiText(dg1.getDiagnosisDescription().encode());
  159. diagnosen.add(diagnose);
  160. }
  161. List<BAR_P05_PROCEDURE> procedures = visit.getPROCEDUREAll();
  162. for (BAR_P05_PROCEDURE procedure : procedures) {
  163. PR1 pr1 = procedure.getPR1();
  164. Untersuchung untersuchung = new Untersuchung();
  165. untersuchung.setErsteller(99999);
  166. untersuchung.setBearbeiter(99999);
  167. untersuchung.setFall(fall);
  168. String ops = pr1.getProcedureCode().encode();
  169. OpsCode opscode = mainctrl.getStammdaten().getOpsCodes().stream().filter(o -> o.getOpsCode().equals(ops)).findFirst().orElse(null);
  170. if (opscode == null) {
  171. // TODO: Oder einfach ueberspringen?
  172. continue;
  173. // TODO: Behandeln von sonder Codes.
  174. // logInHL7MessageToDatabase(message, msh, metadata);
  175. // updateUI(new HL7Message(patient, -1, LocalDateTime.now(), "OPS Code nicht gefunden.", true));
  176. // return generateACKWithAR(message, "OPS Code nicht gefunden.");
  177. }
  178. untersuchung.setOpscode(opscode);
  179. untersuchung.setUntersuchungsdatum(HL7Util.parseLocalDateTime(pr1.getProcedureDateTime().getTime()));
  180. // Mitarbeiter ID anhand von EinweisenderArzt erkennen.
  181. Mitarbeiter mitarbeiter;
  182. if (pr1.getProcedurePractitioner().length != 0) {
  183. String einweisenderarzt = pr1.getProcedurePractitioner(0).encode(); // Wir holen uns immer den ersten der verantwortlichen Aerzte...
  184. mitarbeiter = mainctrl.getStammdaten().getMitarbeiter().stream().filter(m -> m.getEinweisenderArzt().equals(einweisenderarzt)).findFirst().orElse(null);
  185. if (mitarbeiter == null) {
  186. HL7Util.logInHL7MessageToDatabase(message, msh, metadata);
  187. updateUI(new HL7Message(patient, -1, LocalDateTime.now(), "Mitarbeiter nicht gefunden.", true));
  188. return generateACKWithAR(message, "Mitarbeiter nicht gefunden.");
  189. }
  190. } else {
  191. mitarbeiter = new Mitarbeiter(99999);
  192. }
  193. untersuchung.setDurchfuehrenderArzt(mitarbeiter);
  194. untersuchungen.add(untersuchung);
  195. }
  196. // Hier jeweils Untersuchung und Diagnose in die Datenbank schreiben.
  197. diagnosen.forEach(d -> {
  198. try {
  199. DBHandler.setDiagnose(d);
  200. } catch (SQLException e) {
  201. e.printStackTrace();
  202. }
  203. });
  204. untersuchungen.forEach(u -> {
  205. try {
  206. DBHandler.setUntersuchung(u, 99999, false);
  207. } catch (SQLException e) {
  208. e.printStackTrace();
  209. }
  210. });
  211. // Remember welche Faelle geaendert wurden
  212. updatedFallIDs.add(fallid);
  213. }
  214. // HL7 Nachricht loggen.
  215. HL7Util.logInHL7MessageToDatabase(message, msh, metadata);
  216. updatedFallIDs.forEach(id -> updateUI(new HL7Message(patient, id, LocalDateTime.now(), "", false)));
  217. return generateACK(message);
  218. }
  219. private Message processADT_A01(Message message, Map<String, Object> metadata) throws HL7Exception {
  220. ADT_A01 adt_a01 = (ADT_A01) message;
  221. System.out.println(adt_a01.toString());
  222. return generateACK(message);
  223. }
  224. private void updateUI(HL7Message hl7message) {
  225. Platform.runLater(() -> mainctrl.getMessageController().addMessage(hl7message));
  226. }
  227. }