|
- 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;
-
- /**
- * Manages all HL7 receiving tasks
- *
- * @param <T>
- */
- public class HL7Receiver<T extends AbstractMessage> implements ReceivingApplication {
- private final Class<T> type;
- private final MainController mainctrl;
-
- public HL7Receiver(Class<T> type, MainController mainctrl) {
- this.type = type;
- this.mainctrl = mainctrl;
- }
-
-
- @Override
- public Message processMessage(Message message, Map<String, Object> 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);
- }
-
- /**
- * generates an ACK of received message, throws Exception otherwise
- *
- * @param message to generate ACK
- * @return ACK of message
- * @throws HL7Exception
- */
- private Message generateACK(Message message) throws HL7Exception {
- try {
- return message.generateACK();
- } catch (IOException e) {
- throw new HL7Exception(e);
- }
- }
-
- /**
- * generates an ACK with error code and log
- *
- * @param message to generate ACK
- * @param s error string
- * @return ACK with error code
- * @throws HL7Exception
- */
- private Message generateACKWithAR(Message message, String s) throws HL7Exception {
- try {
- Message returnMessage = message.generateACK(AcknowledgmentCode.AR, new HL7Exception(s, ErrorCode.UNKNOWN_KEY_IDENTIFIER));
- HL7LogEntry entry = new HL7LogEntry();
- entry.setMessage(returnMessage.encode());
- entry.setSource("127.0.0.1:1234"); // TODO: Naja...
- entry.setTimestamp(LocalDateTime.now());
- entry.setDirection(HL7LogEntry.Direction.OUT);
- HL7Utils.logHL7MessageToDatabase(entry);
- return returnMessage;
- } catch (IOException e) {
- throw new HL7Exception(e);
- }
- }
-
- /**
- * encodes incoming message and save changes in database
- *
- * @param message received
- * @param metadata //TODO
- * @return ACK of message
- * @throws HL7Exception
- */
- private Message processBAR_P05(Message message, Map<String, Object> metadata) throws HL7Exception {
- BAR_P05 bar_p05 = (BAR_P05) message;
-
- MSH msh = bar_p05.getMSH();
- PID pid = bar_p05.getPID();
- //get patient of the message
- int patid = Integer.parseInt(pid.getPatientID().encode());
- Patient patient = mainctrl.getStammdaten().getPatienten().stream().filter(p -> p.getPatID() == patid).findFirst().orElse(null);
-
- //error by unknown patient
- if (patient == null) {
- HL7Utils.logInHL7MessageToDatabase(message, msh, metadata);
- updateUI(new HL7Message(null, -1, LocalDateTime.now(), "Patient nicht gefunden.", true));
- return generateACKWithAR(message, "Patient nicht gefunden.");
- }
-
- List<BAR_P05_VISIT> visits = bar_p05.getVISITAll();
-
- List<Integer> updatedFallIDs = new ArrayList<>();
-
- for (BAR_P05_VISIT visit : visits) {
- //get current fall
- PV1 pv1 = visit.getPV1();
- int fallid = Integer.parseInt(pv1.getVisitNumber().getIDNumber().encode());
-
- List<Integer> fallids = new ArrayList<>();
- try {
- fallids = DBHandler.getAlleFallIdsByPatID(patient.getPatID());
- } catch (SQLException e) {
- e.printStackTrace();
- }
- //log error by unknown fall
- if (fallids.isEmpty() || !fallids.contains(fallid)) {
- HL7Utils.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<Diagnose> diagnosen = new ArrayList<>();
- List<Untersuchung> 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 ATTENTION wrong abteilungen may write down here
-
- //error message when station not exists
- if (station == null) {
- HL7Utils.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();
- hist.setStationKey(station.getStation());
- if (pv1.getAdmitDateTime().isEmpty()) {
- HL7Utils.logInHL7MessageToDatabase(message, msh, metadata);
- updateUI(new HL7Message(patient, -1, LocalDateTime.now(), "Visit ohne Aufnahmedatum.", true));
- return generateACKWithAR(message, "Visit ohne Aufnahmedatum.");
- }
- hist.setAufnahmeDatum(HL7Utils.parseLocalDateTime(pv1.getAdmitDateTime().getTime()));
- if (pv1.getDischargeDateTime().length >= 1) {
- hist.setEntlassungsDatum(HL7Utils.parseLocalDateTime(pv1.getDischargeDateTime()[0].getTime()));
- }
- hist.setFallID(fallid);
-
- //diagnosis
- List<DG1> dg1s = visit.getDG1All();
- for (DG1 dg1 : dg1s) {
- Diagnose diagnose = new Diagnose();
- //default value by OPS ersteller and bearbeiter
- 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) {
- HL7Utils.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();
- diagnose.setDiagID(DiagArt.parseString(diagart).id());
- diagnose.setFreiText(dg1.getDiagnosisDescription().encode());
-
- diagnosen.add(diagnose);
- }
- List<BAR_P05_PROCEDURE> 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(HL7Utils.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) {
- HL7Utils.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();
- }
- });
-
- try {
- // TODO: keine Updates moeglich, man muesste dazu viel implementieren.
- DBHandler.setStationsHistorie(hist, false);
- } catch (SQLException e) {
- e.printStackTrace();
- }
-
- // Remember welche Faelle geaendert wurden
- updatedFallIDs.add(fallid);
- }
-
- // HL7 Nachricht loggen.
- HL7Utils.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<String, Object> metadata) throws HL7Exception {
- return generateACK(message);
- }
-
- private void updateUI(HL7Message hl7message) {
- Platform.runLater(() -> mainctrl.getMessageController().addMessage(hl7message));
- }
- }
|