package de.uniluebeck.mi.projmi6.hapi; import ca.uhn.hl7v2.AcknowledgmentCode; import ca.uhn.hl7v2.ErrorCode; import ca.uhn.hl7v2.HL7Exception; import ca.uhn.hl7v2.model.AbstractMessage; import ca.uhn.hl7v2.model.Message; import ca.uhn.hl7v2.model.v251.group.BAR_P05_PROCEDURE; import ca.uhn.hl7v2.model.v251.group.BAR_P05_VISIT; import ca.uhn.hl7v2.model.v251.message.ADT_A01; import ca.uhn.hl7v2.model.v251.message.BAR_P05; import ca.uhn.hl7v2.model.v251.segment.*; import ca.uhn.hl7v2.protocol.ReceivingApplication; import ca.uhn.hl7v2.protocol.ReceivingApplicationException; import de.uniluebeck.mi.projmi6.controller.MainController; import de.uniluebeck.mi.projmi6.db.DBHandler; import de.uniluebeck.mi.projmi6.model.*; import javafx.application.Platform; import java.io.IOException; import java.sql.SQLException; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * Created by nils on 20.11.2015. */ public class HL7Receiver implements ReceivingApplication { private final Class type; private final MainController mainctrl; public HL7Receiver(Class type, MainController mainctrl) { this.type = type; this.mainctrl = mainctrl; } @Override public Message processMessage(Message message, Map metadata) throws ReceivingApplicationException, HL7Exception { if (type == ADT_A01.class) { return processADT_A01(message, metadata); } if (type == BAR_P05.class) { return processBAR_P05(message, metadata); } // TODO: Handle unknown Messages, maybe write to database, send ACK and go on. try { return message.generateACK(); } catch (IOException e) { throw new HL7Exception(e); } } @Override public boolean canProcess(Message message) { return type.isInstance(message); } private Message generateACK(Message message) throws HL7Exception { try { return message.generateACK(); } catch (IOException e) { throw new HL7Exception(e); } } private Message generateACKWithAR(Message message, String s) throws HL7Exception { try { return message.generateACK(AcknowledgmentCode.AR, new HL7Exception(s, ErrorCode.UNKNOWN_KEY_IDENTIFIER)); } catch (IOException e) { throw new HL7Exception(e); } } private Message processBAR_P05(Message message, Map metadata) throws HL7Exception { BAR_P05 bar_p05 = (BAR_P05) message; MSH msh = bar_p05.getMSH(); PID pid = bar_p05.getPID(); int patid = Integer.parseInt(pid.getPatientID().encode()); Patient patient = mainctrl.getStammdaten().getPatienten().stream().filter(p -> p.getPatID() == patid).findFirst().orElse(null); if (patient == null) { HL7Util.logInHL7MessageToDatabase(message, msh, metadata); updateUI(new HL7Message(null, -1, LocalDateTime.now(), "Patient nicht gefunden.", true)); return generateACKWithAR(message, "Patient nicht gefunden."); } // TODO: Patienten und Fall neu anlegen??? Nicht verlangt! List visits = bar_p05.getVISITAll(); List updatedFallIDs = new ArrayList<>(); // Ab hier wird es dirty. for (BAR_P05_VISIT visit : visits) { PV1 pv1 = visit.getPV1(); int fallid = Integer.parseInt(pv1.getVisitNumber().encode()); List fallids = new ArrayList<>(); try { fallids = DBHandler.getAlleFallIdsByPatID(patient.getPatID()); } catch (SQLException e) { e.printStackTrace(); } if (fallids.isEmpty() || !fallids.contains(fallid)) { HL7Util.logInHL7MessageToDatabase(message, msh, metadata); updateUI(new HL7Message(patient, -1, LocalDateTime.now(), "Fall nicht gefunden.?", true)); return generateACKWithAR(message, "Fall nicht gefunden."); } Fall fall = new Fall(); fall.setFallID(fallid); fall.setPatient(patient); List diagnosen = new ArrayList<>(); List untersuchungen = new ArrayList<>(); // Station(PV1-3-1), Fachabteilung(PV1-3-4), Aufnahmedatum(PV1-44), Entlassungsdatum(PV1-45), Fallnummer(PV1-19) String stat = pv1.getAssignedPatientLocation().getPointOfCare().encode(); Station station = mainctrl.getStammdaten().getStationen().stream().filter(s -> s.getStation().equals(stat)).findFirst().orElse(null); // TODO: Stationen mit falschen Abteilungen werden einfach umgeschrieben^^ if (station == null) { HL7Util.logInHL7MessageToDatabase(message, msh, metadata); updateUI(new HL7Message(patient, -1, LocalDateTime.now(), "Station nicht gefunden.", true)); return generateACKWithAR(message, "Station nicht gefunden."); } StationsHistorie hist = new StationsHistorie(); // TODO: StationsHist schreiben/schon vorhanden! hist.setStationKey(station.getStation()); hist.setAufnahmeDatum(HL7Util.parseLocalDateTime(pv1.getAdmitDateTime().getTime())); hist.setEntlassungsDatum(HL7Util.parseLocalDateTime(pv1.getDischargeDateTime()[0].getTime())); // TODO: null? hist.setFallID(fallid); List dg1s = visit.getDG1All(); for (DG1 dg1 : dg1s) { Diagnose diagnose = new Diagnose(); diagnose.setErsteller(99999); diagnose.setBearbeiter(99999); diagnose.setFall(fall); String icd10 = dg1.getDiagnosisCodeDG1().getIdentifier().encode(); Icd10Code icd10code = mainctrl.getStammdaten().getIcd10Codes().stream().filter(i -> i.getCode().equals(icd10)).findFirst().orElse(null); if (icd10code == null) { // TODO: Oder einfach ueberspringen? continue; // TODO: Behandeln von sonder Codes. K35.9V (Verdacht...) // logInHL7MessageToDatabase(message, msh, metadata); // updateUI(new HL7Message(patient, -1, LocalDateTime.now(), "ICD10 Code nicht gefunden.", true)); // return generateACKWithAR(message, "ICD10 Code nicht gefunden."); } diagnose.setIcd10code(icd10code); // Mitarbeiter ID anhand von EinweisenderArzt erkennen. Mitarbeiter mitarbeiter; if (dg1.getDiagnosingClinician().length != 0) { String einweisenderarzt = dg1.getDiagnosingClinician(0).encode(); // Wir holen uns immer den ersten der verantwortlichen Aerzte... // (DG1-16) mitarbeiter = mainctrl.getStammdaten().getMitarbeiter().stream().filter(m -> m.getEinweisenderArzt().equals(einweisenderarzt)).findFirst().orElse(null); if (mitarbeiter == null) { HL7Util.logInHL7MessageToDatabase(message, msh, metadata); updateUI(new HL7Message(patient, -1, LocalDateTime.now(), "Mitarbeiter nicht gefunden.", true)); return generateACKWithAR(message, "Mitarbeiter nicht gefunden."); } } else { mitarbeiter = new Mitarbeiter(99999); } diagnose.setArzt(mitarbeiter); // (DG1-6) // TODO: Enum umstellen? Neeee... String diagart = dg1.getDiagnosisType().encode(); switch (diagart) { case "A": diagnose.setDiagArt(DiagArt.EINWEISUNG); break; case "F": diagnose.setDiagArt(DiagArt.ENTLASSUNG); break; case "W": default: diagnose.setDiagArt(DiagArt.VERDACHT); } diagnose.setFreiText(dg1.getDiagnosisDescription().encode()); diagnosen.add(diagnose); } List procedures = visit.getPROCEDUREAll(); for (BAR_P05_PROCEDURE procedure : procedures) { PR1 pr1 = procedure.getPR1(); Untersuchung untersuchung = new Untersuchung(); untersuchung.setErsteller(99999); untersuchung.setBearbeiter(99999); untersuchung.setFall(fall); String ops = pr1.getProcedureCode().encode(); OpsCode opscode = mainctrl.getStammdaten().getOpsCodes().stream().filter(o -> o.getOpsCode().equals(ops)).findFirst().orElse(null); if (opscode == null) { // TODO: Oder einfach ueberspringen? continue; // TODO: Behandeln von sonder Codes. // logInHL7MessageToDatabase(message, msh, metadata); // updateUI(new HL7Message(patient, -1, LocalDateTime.now(), "OPS Code nicht gefunden.", true)); // return generateACKWithAR(message, "OPS Code nicht gefunden."); } untersuchung.setOpscode(opscode); untersuchung.setUntersuchungsdatum(HL7Util.parseLocalDateTime(pr1.getProcedureDateTime().getTime())); // Mitarbeiter ID anhand von EinweisenderArzt erkennen. Mitarbeiter mitarbeiter; if (pr1.getProcedurePractitioner().length != 0) { String einweisenderarzt = pr1.getProcedurePractitioner(0).encode(); // Wir holen uns immer den ersten der verantwortlichen Aerzte... mitarbeiter = mainctrl.getStammdaten().getMitarbeiter().stream().filter(m -> m.getEinweisenderArzt().equals(einweisenderarzt)).findFirst().orElse(null); if (mitarbeiter == null) { HL7Util.logInHL7MessageToDatabase(message, msh, metadata); updateUI(new HL7Message(patient, -1, LocalDateTime.now(), "Mitarbeiter nicht gefunden.", true)); return generateACKWithAR(message, "Mitarbeiter nicht gefunden."); } } else { mitarbeiter = new Mitarbeiter(99999); } untersuchung.setDurchfuehrenderArzt(mitarbeiter); untersuchungen.add(untersuchung); } // Hier jeweils Untersuchung und Diagnose in die Datenbank schreiben. diagnosen.forEach(d -> { try { DBHandler.setDiagnose(d); } catch (SQLException e) { e.printStackTrace(); } }); untersuchungen.forEach(u -> { try { DBHandler.setUntersuchung(u, 99999, false); } catch (SQLException e) { e.printStackTrace(); } }); // Remember welche Faelle geaendert wurden updatedFallIDs.add(fallid); } // HL7 Nachricht loggen. HL7Util.logInHL7MessageToDatabase(message, msh, metadata); updatedFallIDs.forEach(id -> updateUI(new HL7Message(patient, id, LocalDateTime.now(), "", false))); return generateACK(message); } private Message processADT_A01(Message message, Map metadata) throws HL7Exception { ADT_A01 adt_a01 = (ADT_A01) message; System.out.println(adt_a01.toString()); return generateACK(message); } private void updateUI(HL7Message hl7message) { Platform.runLater(() -> mainctrl.getMessageController().addMessage(hl7message)); } }