package open.dolphin.msg; import java.io.*; import java.net.Socket; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Properties; import java.util.logging.Logger; import open.dolphin.infomodel.*; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.Velocity; /** * Claim 送信クラス。 * オリジナルは元町皮ふ科 * 2012-05 * 在宅医療をサポートするため、CLAIM 送信を JMS+MDBへ移行 * そのため DocInfo から CLAIM 送信に必要な全ての情報を取得する * @author kazushi Minagawa. */ public class DiagnosisSender { private static final int EOT = 0x04; private static final int ACK = 0x06; private static final int NAK = 0x15; private static final String ACK_STR = "ACK: "; private static final String NAK_STR = "NAK: "; private static final String OBJECT_NAME = "diseaseHelper"; //s.oh^ 2014/03/13 傷病名削除診療科対応 private static final String TEMPLATE_NAME = "diseaseHelper.vm"; // private static final String TEMPLATE_NAME = "diseaseHelper_02.vm"; //s.oh$ private static final String TEMPLATE_ENC = "SHIFT_JIS"; private static final String DORCA_UPDATED = "DORCA_UPDATED"; //s.oh^ 2013/05/10 傷病名対応 // 傷病名手入力時につけるコード private static final String HAND_CODE = "0000999"; //s.oh$ private String host; private int port; private String enc; private boolean DEBUG; public DiagnosisSender() { } public DiagnosisSender(String host, int port, String enc) { this(); this.host = host; this.port = port; this.enc = enc; //minagawa^ CLAIM Log DEBUG = Logger.getLogger("dolphin.claim").getLevel().equals(java.util.logging.Level.FINE); //minagawa$ } /** * CLAIM送信を行う。 * @param sendModel 送信するDocuentModel * @throws Exception */ public void send(DiagnosisSendWrapper wrapper) throws Exception { //s.oh^ 2013/12/10 傷病名のCLAIM送信する/しない Properties config = new Properties(); StringBuilder sbPath = new StringBuilder(); sbPath.append(System.getProperty("jboss.home.dir")); sbPath.append(File.separator); sbPath.append("custom.properties"); File f = new File(sbPath.toString()); FileInputStream fin = new FileInputStream(f); InputStreamReader isr = new InputStreamReader(fin, "JISAutoDetect"); config.load(isr); isr.close(); String claimSend = config.getProperty("diagnosis.claim.send"); if(claimSend != null && claimSend.equals("false")) { return; } //s.oh$ // 新規病名 List<RegisteredDiagnosisModel> addedDiagnosis = wrapper.getAddedDiagnosis(); // 更新病名 List<RegisteredDiagnosisModel> updatedDiagnosis = wrapper.getUpdatedDiagnosis(); //minagawa^ LSC 1.4 傷病名の削除 2013/06/24 // 削除病名 List<RegisteredDiagnosisModel> deletedDiagnosis = wrapper.getDeletedDiagnosis(); //minagawa$ // 実際にCLAIM送信する病名 List<RegisteredDiagnosisModel> actualList = new ArrayList<RegisteredDiagnosisModel>(); //s.oh^ 2014/11/11 傷病名送信順番の変更 // // 新規病名を送信する // if (addedDiagnosis!=null && addedDiagnosis.size()>0) { // // for (RegisteredDiagnosisModel rdm : addedDiagnosis) { // if (isDorcaUpdatedDisease(rdm) || isPureDisease(rdm)) { // actualList.add(rdm); // } // } // // if (!actualList.isEmpty()) { // if (DEBUG) { // debug("-------- Send Diagnosis List to add ----------------"); // for (RegisteredDiagnosisModel r : actualList) { // debug(r.getDiagnosis()); // } // } // } // } // // // 更新された病名を CLAIM 送信する // // detuched object のみ // if (updatedDiagnosis!=null && updatedDiagnosis.size()>0) { // if (DEBUG) { // debug("-------- Send Diagnosis List to update ----------------"); // for (RegisteredDiagnosisModel r : updatedDiagnosis) { // debug(r.getDiagnosis()); // } // } // actualList.addAll(updatedDiagnosis); // } // ////minagawa^ LSC 1.4 傷病名の削除 2013/06/24 // if (deletedDiagnosis!=null && deletedDiagnosis.size()>0) { // if (DEBUG) { // debug("-------- Send Diagnosis List to delete ----------------"); // for (RegisteredDiagnosisModel r : updatedDiagnosis) { // debug(r.getDiagnosis()); // } // } // actualList.addAll(deletedDiagnosis); // } // // if (actualList.isEmpty()) { // return; // } ////minagawa$ if(deletedDiagnosis != null && deletedDiagnosis.size() > 0) { actualList.addAll(deletedDiagnosis); } if(updatedDiagnosis != null && updatedDiagnosis.size() > 0) { actualList.addAll(updatedDiagnosis); } if(addedDiagnosis != null && addedDiagnosis.size() > 0) { for(RegisteredDiagnosisModel rdm : addedDiagnosis) { if(isDorcaUpdatedDisease(rdm) || isPureDisease(rdm)) { actualList.add(rdm); } } } if (actualList.isEmpty()) { return; } Collections.sort(actualList, new DiagnosisSendComparator()); //s.oh$ // DocInfo & RD をカプセル化したアイテムを生成する ArrayList<DiagnosisModuleItem> moduleItems = new ArrayList<DiagnosisModuleItem>(); for (RegisteredDiagnosisModel rd : actualList) { DocInfoModel docInfo = new DocInfoModel(); docInfo.setDocId(GUIDGenerator.generate(docInfo)); //docInfo.setTitle(IInfoModel.DEFAULT_DIAGNOSIS_TITLE); docInfo.setTitle("RegisteredDiagnosis"); docInfo.setPurpose(IInfoModel.PURPOSE_RECORD); docInfo.setFirstConfirmDate(ModelUtils.getDateTimeAsObject(rd.getConfirmDate())); docInfo.setConfirmDate(ModelUtils.getDateTimeAsObject(rd.getFirstConfirmDate())); //s.oh^ 2013/05/10 傷病名対応 rd.setDiagnosisCode(HAND_CODE); // ORCAから取り込んだ場合、コードに0000999を設定する //s.oh$ DiagnosisModuleItem mItem = new DiagnosisModuleItem(); mItem.setDocInfo(docInfo); mItem.setRegisteredDiagnosisModule(rd); moduleItems.add(mItem); } // ヘルパー用の値を生成する String confirmDate = wrapper.getConfirmDate(); // ヘルパークラスを生成する DiseaseHelper dhl = new DiseaseHelper(); dhl.setPatientId(wrapper.getPatientId()); // 患者ID dhl.setConfirmDate(confirmDate); // 確定日 dhl.setDiagnosisModuleItems(moduleItems); // RD+DocInfo dhl.setGroupId(GUIDGenerator.generate(dhl)); // GroupId dhl.setDepartment(wrapper.getDepartment()); // 診療科コード dhl.setDepartmentDesc(wrapper.getDepartmentDesc()); // 診療科名 dhl.setCreatorName(wrapper.getCreatorName()); // 担当医名 dhl.setCreatorId(wrapper.getCreatorLicense()); // 担当医コード dhl.setJmariCode(wrapper.getJamariCode()); // JMARI code dhl.setCreatorLicense(wrapper.getCreatorLicense()); // 医療資格 dhl.setFacilityName(wrapper.getFacilityName()); // 施設名 if (DEBUG) { debug("患者ID=" + dhl.getPatientId()); debug("確定日=" + dhl.getConfirmDate()); debug("GroupId=" + dhl.getGroupId()); debug("診療科コード=" + dhl.getDepartment()); debug("診療科名=" + dhl.getDepartmentDesc()); debug("担当医名=" + dhl.getCreatorName()); debug("担当医コード=" + dhl.getCreatorId()); debug("JMARI code=" + dhl.getJmariCode()); debug("医療資格=" + dhl.getCreatorLicense()); debug("施設名=" + dhl.getFacilityName()); } // ログのために基本情報を生成する StringBuilder sb = new StringBuilder(); sb.append(confirmDate).append(" "); sb.append(wrapper.getPatientId()).append(" "); sb.append(wrapper.getPatientName()).append(" "); sb.append(wrapper.getPatientGender()); String baseInfo = sb.toString(); //-------------------------------------------------------- // CLIAM message を生成する //-------------------------------------------------------- VelocityContext context = VelocityHelper.getContext(); context.put(OBJECT_NAME, dhl); StringWriter sw = new StringWriter(); BufferedWriter bw = new BufferedWriter(sw); Velocity.mergeTemplate(TEMPLATE_NAME, TEMPLATE_ENC, context, bw); bw.flush(); bw.close(); String claimMessage = sw.toString(); //minagawa^ CLAIM Log log(claimMessage); // if (DEBUG) { // debug(claimMessage); // } //minagawa$ //-------------------------------------------------------- // ORCAへ接続する Socket socket = new Socket(host, port); OutputStream out = socket.getOutputStream(); DataOutputStream dout = new DataOutputStream(out); BufferedOutputStream writer = new BufferedOutputStream(dout); InputStream in = socket.getInputStream(); DataInputStream din = new DataInputStream(in); BufferedInputStream reader = new BufferedInputStream(din); // Writes UTF8 data writer.write(claimMessage.getBytes(enc)); writer.write(EOT); writer.flush(); // Reads result int c = reader.read(); if (c == ACK) { sb = new StringBuilder(); sb.append(ACK_STR).append(baseInfo); log(sb.toString()); } else if (c == NAK) { sb = new StringBuilder(); sb.append(NAK_STR).append(baseInfo); log(sb.toString()); } writer.close(); reader.close(); socket.close(); } //s.oh^ 2014/11/11 傷病名送信順番の変更 class DiagnosisSendComparator implements Comparator { public DiagnosisSendComparator() {} @Override public int compare(Object o1, Object o2) { if(o1 == null && o2 == null) { return 0; }else if(o1 == null) { return 1; }else if(o2 == null) { return -1; } RegisteredDiagnosisModel val1 = (RegisteredDiagnosisModel)o1; RegisteredDiagnosisModel val2 = (RegisteredDiagnosisModel)o2; if(val1.getDiagnosisOutcomeModel() == null && val2.getDiagnosisOutcomeModel() == null) { return 0; }else if(val1.getDiagnosisOutcomeModel() == null) { return 1; }else if(val2.getDiagnosisOutcomeModel() == null) { return -1; } if(val1.getDiagnosisCategoryModel() == null && val2.getDiagnosisCategoryModel() == null) { return 0; }else if(val1.getDiagnosisCategoryModel() == null) { return 1; }else if(val2.getDiagnosisCategoryModel() == null) { return -1; } if(val1.getEnded() == null && val2.getEnded() == null) { return 0; }else if(val1.getEnded() == null) { return 1; }else if(val2.getEnded() == null) { return -1; } return 0; } } //s.oh$ //minagawa^ CLAIM Log private void log(String msg) { Logger.getLogger("dolphin.claim").info(msg); } private void debug(String msg) { Logger.getLogger("dolphin.claim").fine(msg); } private void warning(String msg) { Logger.getLogger("dolphin.claim").warning(msg); } //minagawa$ private boolean isDorcaUpdatedDisease(RegisteredDiagnosisModel test) { return (test!=null && test.getStatus()!=null && test.getStatus().equals(DORCA_UPDATED)); } private boolean isPureDisease(RegisteredDiagnosisModel test) { return (test!=null && test.getStatus()!=null && test.getStatus().equals(IInfoModel.STATUS_FINAL)); } }