package open.dolphin.hiro; import java.awt.Desktop; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.logging.Level; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JOptionPane; import javax.swing.JTextField; import javax.swing.SwingWorker; import javax.swing.UIManager; import open.dolphin.client.Chart; import open.dolphin.client.ClientContext; import open.dolphin.delegater.OrcaDelegater; import open.dolphin.delegater.OrcaDelegaterFactory; import open.dolphin.helper.InfiniteProgressBar; import open.dolphin.infomodel.BundleMed; import open.dolphin.infomodel.ClaimConst; import open.dolphin.infomodel.ClaimItem; import open.dolphin.infomodel.DocumentModel; import open.dolphin.infomodel.IInfoModel; import open.dolphin.infomodel.ModelUtils; import open.dolphin.infomodel.ModuleModel; import open.dolphin.infomodel.PriscriptionModel; import open.dolphin.project.Project; /** * * @author Hiro Clinic MASATO * minagawa 2012-09-07 OpenDolphin へポート */ public class PrescriptionMaker { /** 処方せん記載確認パネル */ private PostConfirmPanel prePanel; /** 処方せん記載確認ダイアログ */ private JDialog dialog; /** 患者情報記載有無フラグ */ private boolean chkPatientInfo; /** 麻薬施用者番号記載有無フラグ */ private boolean chkUseDrugInfo; /** 在宅記載有無フラグ */ private boolean chkHomeMedical; /** 処方せん使用期間 */ private Date period; // @009 /** 現在日 */ private Date now; // @009 // @003 private final String LICENSE_DOCTOR = "doctor"; /** * @002 2009/09/11 追加 * 患者情報転記確認ダイアログを生成する。 */ private Chart chart; private DocumentModel docModel; private InfiniteProgressBar progressBar; public void setChart(Chart chart) { this.chart = chart; } public void setDocumentModel(DocumentModel docModel) { this.docModel = docModel; } public void start() { // Dialog のViewを生成する prePanel = new PostConfirmPanel(); // Options final JButton okBtn = new JButton("PDF作成"); final JButton cancelBtn = new JButton((String)UIManager.get("OptionPane.cancelButtonText")); Object[] options = new Object[]{okBtn, cancelBtn}; // ダイアログを生成する JOptionPane jop = new JOptionPane(prePanel, JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION, null, options, okBtn); dialog = jop.createDialog(chart.getFrame(), ClientContext.getFrameTitle("処方せん出力")); // 備考欄に「在宅」を記入 default=true; chkHomeMedical = true; prePanel.getChkHomeMedical().setSelected(chkHomeMedical); // 患者氏名、住所を転帰 default=true; chkPatientInfo = true; prePanel.getChkPatientInfo().setSelected(chkPatientInfo); // 麻薬施用者免許番号を転帰 chkUseDrugInfo = false; prePanel.getChkUseDrugInfo().setSelected(chkUseDrugInfo); // 麻薬施用者免許番号 新規属性 2012090 String useDrugId = Project.getUserModel().getUseDrugId(); prePanel.getUseDrugId().setText(useDrugId); // @003 2009/09/14 仕様変更:麻薬施用者免許証番号が登録されていない場合は、非活性にする if (useDrugId == null || "".equals(useDrugId)) { prePanel.getChkUseDrugInfo().setEnabled(false); prePanel.getUseDrugId().setEnabled(false); prePanel.getLblUseDrugId().setEnabled(false); prePanel.getLblNarcoticsPractitioner().setEnabled(false); } else { prePanel.getChkUseDrugInfo().setEnabled(true); prePanel.getUseDrugId().setEnabled(true); prePanel.getLblUseDrugId().setEnabled(true); prePanel.getLblNarcoticsPractitioner().setEnabled(true); // login user prePanel.getNarcoticsPractitioner().setText(Project.getUserModel().getCommonName()); } // ********** @009 2010/07/01 ↓↓ ********** // 使用期間 PopupListener pl = new PopupListener(prePanel.getTfPeriod()); // ********** @009 2010/07/01 ↑↑ ********** //minagawa^ 保険医療機関コードの取得を促す prePanel.getFacilitCodeField().setText(Project.getBasicInfo()); prePanel.getFacilitCodeField().setEnabled(false); // 一般名で出力する boolean check = Project.getBoolean("prescription.output.general"); prePanel.getGeneralChk().setSelected(check); //minagawa$ /* OKボタンアクションリスナー設定 */ okBtn.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (chkDate() > 0) { return; // @009 2010/07/01 } dialog.setVisible(false); dialog.dispose(); createPDF(); } }); /* キャンセルボタンアクションリスナー設定 */ cancelBtn.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { dialog.setVisible(false); dialog.dispose(); } }); /* 患者住所氏名転記チェックボックスアクションリスナー設定 */ prePanel.getChkPatientInfo().addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (chkPatientInfo) { chkPatientInfo = false; } else { chkPatientInfo = true; } } }); /* 麻薬施用者免許証番号転記チェックボックスアクションリスナー設定 */ prePanel.getChkUseDrugInfo().addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (chkUseDrugInfo) { if (!prePanel.getChkPatientInfo().isEnabled()) { prePanel.getChkPatientInfo().setEnabled(true); } chkUseDrugInfo = false; } else { chkUseDrugInfo = true; prePanel.getChkPatientInfo().setSelected(true); chkPatientInfo = true; prePanel.getChkPatientInfo().setEnabled(false); } } }); /* 備考欄に「在宅」を記載するかどうかのチェックボックスアイテムリスナーの設定 */ prePanel.getChkHomeMedical().addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (chkHomeMedical) { chkHomeMedical = false; } else { chkHomeMedical = true; prePanel.getChkPatientInfo().setSelected(true); } } }); // 一般名出力 prePanel.getGeneralChk().addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent ae) { Project.setBoolean("prescription.output.general",prePanel.getGeneralChk().isSelected()); } }); // ダイアログ表示 dialog.setVisible(true); } // ********** @009 2010/07/01 ↓↓ ********** /** * 処方せん出力確認ダイアログの入力項目チェックメソッド * 日付の前後チェックなどを行う。 * @return int 0:エラーなし 0以外:エラーあり */ private int chkDate() { String errTitle = "入力エラー"; //String alertTitle = "年月日アラート"; String errMsg = "は「2010-05-10」形式で入力してください。"; //String alertMsg = "が今日より前の日付ですがよろしいですか?"; int ret = 0; // チェック結果 //int select = 0; // メッセージダイアログのボタン選択値 try { Date delivery = Utils.chkDate(Utils.getDateFormat().format(docModel.getStarted())); now = Utils.chkDate(Utils.getDateFormat().format(new Date())); // 現在日 // 使用期間入力チェック period = null; JTextField chkTarget = prePanel.getTfPeriod(); if (!"".equals(chkTarget.getText())) { // 使用期間が入力あり period = Utils.chkDate(chkTarget.getText()); if (period == null) { // 使用期間の日付チェックエラー ret = 1; JOptionPane.showMessageDialog(prePanel, chkTarget.getName() + errMsg, errTitle, JOptionPane.ERROR_MESSAGE); chkTarget.requestFocus(); } else if ((delivery != null) && period.before(delivery)) { JOptionPane.showMessageDialog(prePanel, chkTarget.getName() + "に交付年月日より前の日が入力されています。", errTitle, JOptionPane.ERROR_MESSAGE); chkTarget.requestFocus(); ret = 1; } else if (period.before(now)) { JOptionPane.showMessageDialog(prePanel, chkTarget.getName() + "に今日より前の日が入力されています。", errTitle, JOptionPane.ERROR_MESSAGE); chkTarget.requestFocus(); ret = 1; } } } catch (Exception e) { ret = 2; java.util.logging.Logger.getLogger(this.getClass().getName()).log(Level.WARNING, "{0}{1}", new Object[]{e.getMessage(), e.getCause()}); } return ret; } // ********** @009 2010/07/01 ↑↑ ********** //minagawa^ // 内用かどうかを返す private boolean bundleIsNaiyo(BundleMed med) { // 内用のみ ClaimItem[] items = med.getClaimItem(); boolean naiyo = (items!=null && items.length>0); if (naiyo) { for (ClaimItem item : items) { if (item.getYkzKbn()==null || (!item.getYkzKbn().equals(ClaimConst.YKZ_KBN_NAIYO))) { naiyo = false; break; } } } return naiyo; } private void createPDF() { final SwingWorker worker = new SwingWorker<String,Void>() { @Override protected String doInBackground() throws Exception { List<BundleMed> naiyoList = new ArrayList<>(); List<BundleMed> otherList = new ArrayList<>(); Collection<ModuleModel> modules = docModel.getModules(); // 院外処方のみ集める for (ModuleModel module : modules) { String entity = module.getModuleInfoBean().getEntity(); IInfoModel model = module.getModel(); if (IInfoModel.ENTITY_MED_ORDER.equals(entity) && model instanceof BundleMed) { BundleMed med = (BundleMed)model; // 院外処方 if (med.getClassCode()!=null && med.getClassCode().endsWith("2")) { // クローン生成 BundleMed clone = ModelUtils.cloneBundleMed(med); if (clone!=null) { // 内用のみ if (bundleIsNaiyo(med)) { //臨時の診療行為コードを変換する if (clone.getClassCode().startsWith("29")) { clone.setClassCode("212"); // 臨時の内用を内用に } naiyoList.add(clone); } else { //臨時の診療行為コードを変換する if (clone.getClassCode().startsWith("29")) { clone.setClassCode("232"); // 臨時の外用を外用に } otherList.add(clone); } } } } } // 内用の同じ用法をまとめる if (!naiyoList.isEmpty()) { HashMap<String,BundleMed> map = new HashMap<>(); for (BundleMed test : naiyoList) { String key = test.getAdminCode()+test.getBundleNumber(); if (map.get(key)!=null) { BundleMed same = map.get(key); same.merge(test); } else { map.put(key, test); } } // Map から新規に内用のリストを作る naiyoList.clear(); naiyoList.addAll(map.values()); map.clear(); } List<BundleMed> allList = new ArrayList<BundleMed>(naiyoList.size()+otherList.size()); allList.addAll(naiyoList); allList.addAll(otherList); naiyoList.clear(); otherList.clear(); // 一般名に変更する if (Project.getBoolean("prescription.output.general")) { for (BundleMed med : allList) { ClaimItem[] items = med.getClaimItem(); if (items==null || items.length==0) { continue; } for (ClaimItem item : items) { // 薬剤ではない if (!item.getClassCode().equals("2")) { continue; } // 一般名を検索し名称を入れ替える OrcaDelegater odl = OrcaDelegaterFactory.create(); String gname = odl.getGeneralName(item.getCode()); item.setName("【般】" + gname); } } } PriscriptionModel pkg = new PriscriptionModel(); pkg.setPatientId(chart.getPatient().getPatientId()); pkg.setPatientName(chart.getPatient().getFullName()); pkg.setPatientKana(chart.getPatient().getKanaName()); pkg.setPatientSex(chart.getPatient().getGenderDesc()); pkg.setPatientBirthday(chart.getPatient().getBirthday()); if (chart.getPatient().getSimpleAddressModel()!=null) { pkg.setPatientZipcode(chart.getPatient().getSimpleAddressModel().getZipCode()); pkg.setPatientAddress(chart.getPatient().getSimpleAddressModel().getAddress()); } pkg.setPatientTelephone(chart.getPatient().getTelephone()); pkg.setPriscriptionList(allList); pkg.setIssuanceDate(docModel.getStarted()); pkg.setApplyedInsurance(chart.getHealthInsuranceToApply(docModel.getDocInfoModel().getHealthInsuranceGUID())); pkg.setInstitutionNumber(Project.getBasicInfo()); pkg.setPhysicianName(Project.getUserModel().getCommonName()); pkg.setDrugLicenseNumber(Project.getUserModel().getUseDrugId()); pkg.setInstitutionName(Project.getUserModel().getFacilityModel().getFacilityName()); pkg.setInstitutionZipcode(Project.getUserModel().getFacilityModel().getZipCode()); pkg.setInstitutionAddress(Project.getUserModel().getFacilityModel().getAddress()); pkg.setInstitutionTelephone(Project.getUserModel().getFacilityModel().getTelephone()); pkg.setChkPatientInfo(chkPatientInfo); pkg.setChkUseDrugInfo(chkUseDrugInfo); pkg.setChkHomeMedical(chkHomeMedical); pkg.setPeriod(period); PrescriptionPDFMaker maker = new PrescriptionPDFMaker(pkg); if (Project.getString(Project.LOCATION_PDF)!=null) { maker.setDocumentDir(Project.getString(Project.LOCATION_PDF)); } else { maker.setDocumentDir(ClientContext.getPDFDirectory()); } String pathToPDF = maker.output(); return pathToPDF; } @Override protected void done() { try { String pathToPDF = get(); if (pathToPDF!=null) { try { Desktop.getDesktop().open(new File(pathToPDF)); } catch (IOException ex) { ex.printStackTrace(System.err); JOptionPane.showMessageDialog(chart.getFrame(), ex.getMessage(), "処方せん出力エラー", JOptionPane.ERROR_MESSAGE); } } } catch (InterruptedException ex) { ex.printStackTrace(System.err); } catch (ExecutionException ex) { ex.printStackTrace(System.err); JOptionPane.showMessageDialog(chart.getFrame(), ex.getMessage(), "処方せん出力エラー", JOptionPane.ERROR_MESSAGE); } } }; worker.addPropertyChangeListener(new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent e) { if (e.getNewValue()==SwingWorker.StateValue.STARTED) { progressBar = new InfiniteProgressBar("処方せん出力", "処方せんを作成中です...", chart.getFrame()); progressBar.start(); } else if (e.getNewValue()==SwingWorker.StateValue.DONE) { progressBar.stop(); progressBar = null; worker.removePropertyChangeListener(this); } } }); worker.execute(); //minagawa$ } }