SiMzFeeService.java 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670
  1. package thyyxxk.simzfeeoprnsystm.service;
  2. import com.alibaba.fastjson.JSONArray;
  3. import com.alibaba.fastjson.JSONObject;
  4. import org.springframework.beans.factory.annotation.Value;
  5. import thyyxxk.simzfeeoprnsystm.dao.SiLogDao;
  6. import thyyxxk.simzfeeoprnsystm.dao.SiMzDao;
  7. import thyyxxk.simzfeeoprnsystm.dao.SiSetldetailDao;
  8. import thyyxxk.simzfeeoprnsystm.dao.SiSetlinfoDao;
  9. import thyyxxk.simzfeeoprnsystm.dicts.*;
  10. import thyyxxk.simzfeeoprnsystm.external.WebHisSrvc;
  11. import thyyxxk.simzfeeoprnsystm.pojo.*;
  12. import thyyxxk.simzfeeoprnsystm.pojo.ResultVo;
  13. import thyyxxk.simzfeeoprnsystm.pojo.SiPatInfo;
  14. import thyyxxk.simzfeeoprnsystm.pojo.onlinepayment.EcTokenParams;
  15. import thyyxxk.simzfeeoprnsystm.pojo.registration.InsuInfo;
  16. import thyyxxk.simzfeeoprnsystm.pojo.registration.PsnBaseInfo;
  17. import thyyxxk.simzfeeoprnsystm.utils.*;
  18. import lombok.extern.slf4j.Slf4j;
  19. import org.springframework.beans.factory.annotation.Autowired;
  20. import org.springframework.stereotype.Service;
  21. import java.math.RoundingMode;
  22. import java.util.ArrayList;
  23. import java.util.List;
  24. import java.util.Map;
  25. @Slf4j
  26. @Service
  27. public class SiMzFeeService {
  28. private final SiMzDao mzDao;
  29. private final SiSetlinfoDao setlinfoDao;
  30. private final SiSetldetailDao setldetailDao;
  31. private final ExecService exec;
  32. private final WebHisSrvc webHisSrvc;
  33. private static final String RESULT_CODE = "infcode";
  34. private static final String ERROR_MESSAGE = "err_msg";
  35. private static final String OUTPUT = "output";
  36. private final SiLogDao logDao;
  37. @Value("${web-his-url}")
  38. private String webHisUrl;
  39. @Autowired
  40. public SiMzFeeService(SiMzDao mzDao, SiSetlinfoDao setlinfoDao,
  41. SiSetldetailDao setldetailDao, ExecService exec, WebHisSrvc webHisSrvc, SiLogDao logDao) {
  42. this.mzDao = mzDao;
  43. this.setlinfoDao = setlinfoDao;
  44. this.setldetailDao = setldetailDao;
  45. this.exec = exec;
  46. this.webHisSrvc = webHisSrvc;
  47. this.logDao = logDao;
  48. }
  49. public ResultVo<String> outpatientRegistration(MzPatientInfo p) {
  50. Regstrtn regstrtn = mzDao.selectRegstrtn(p.getPatNo(), p.getTimes());
  51. if (null == regstrtn) {
  52. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "mz_visit_table患者信息为空,请联系医生重开处方。");
  53. }
  54. ReadCardBizType readCardBizType = ReadCardBizType.get(p.getReadCardBizType());
  55. if (readCardBizType != ReadCardBizType.REGISTRATION && !p.getInsuplcAdmdvs().startsWith("43")) {
  56. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "省外异地的患者请读社保卡或医保电子凭证登记!");
  57. }
  58. if (readCardBizType == ReadCardBizType.REGISTRATION) {
  59. MdtrtCertType mdtrtCertType = MdtrtCertType.getByLabel(p.getMdtrtCertType());
  60. regstrtn.setMdtrtCertType(mdtrtCertType.getCode());
  61. if (mdtrtCertType == MdtrtCertType.SOCIAL_SECURITY_CARD) {
  62. String[] out = p.getReadCardResult().split("\\|");
  63. if (!p.getName().trim().equals(out[4].trim())) {
  64. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "社保卡姓名与HIS姓名不一致,请确认是否人证相符。");
  65. }
  66. regstrtn.setMdtrtCertNo(out[2]);
  67. regstrtn.setCardSn(out[3]);
  68. } else if (mdtrtCertType == MdtrtCertType.MEDICAL_INSURANCE_ELECTRONIC_VOUCHER) {
  69. JSONObject qrinfo = JSONObject.parseObject(p.getReadCardResult());
  70. if (!p.getName().trim().equals(qrinfo.getString("userName").trim())) {
  71. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "电子医保凭证姓名与HIS姓名不一致,请确认是否人证相符。");
  72. }
  73. if (!p.getSocialNo().trim().equals(qrinfo.getString("idNo").trim())) {
  74. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "电子医保凭证身份证与HIS身份证不一致,请确认是否人证相符。");
  75. }
  76. regstrtn.setMdtrtCertNo(qrinfo.getString("ecToken"));
  77. }
  78. }
  79. JSONObject input = exec.makeTradeHeaderWithInsureArea(SiFunction.OUTPATIENT_REGISTRATION,
  80. p.getInsuplcAdmdvs(), p.getStaffId());
  81. regstrtn.setInsutype(p.getInsutype());
  82. regstrtn.setPsnType(p.getPsnType());
  83. regstrtn.setIptOtpNo(p.getPatNo());
  84. String ref = JSONObject.toJSONStringWithDateFormat(regstrtn, "yyyy-MM-dd HH:mm:ss");
  85. input.getJSONObject("input").put("data", JSONObject.parseObject(ref));
  86. JSONObject result = exec.executeTrade(input, SiFunction.OUTPATIENT_REGISTRATION);
  87. log.info("【操作员:{}】,门诊挂号:\n参数:{},\n结果:{}", p.getStaffId(), input, result);
  88. if (null == result) {
  89. return ResultVoUtil.fail(ExceptionEnum.NETWORK_ERROR);
  90. }
  91. Integer infcode = result.getInteger(RESULT_CODE);
  92. logDao.insert(new SiLog(input, result, p.getPatNo(), p.getTimes(), infcode, regstrtn.getPsnNo()));
  93. if (null == infcode) {
  94. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "医保中心报错:" + result.getString("message"));
  95. }
  96. if (infcode == 0) {
  97. JSONObject output = result.getJSONObject(OUTPUT).getJSONObject("data");
  98. p.setMdtrtId(output.getString("mdtrt_id"));
  99. p.setVisitDate(regstrtn.getBegntime());
  100. mzDao.afterRegistrtn(p);
  101. return ResultVoUtil.success("挂号成功。");
  102. }
  103. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, result.getString(ERROR_MESSAGE));
  104. }
  105. public ResultVo<String> revokeOutpatientRegistration(MzPatientInfo p) {
  106. if (null == p.getTimes()) {
  107. p.setTimes(mzDao.selectMaxTimes(p.getPatNo()));
  108. }
  109. SiPatInfo siPatInfo = mzDao.selectSiPatInfoForMz(p.getPatNo(), p.getTimes());
  110. if (null == siPatInfo || StringUtil.isBlank(siPatInfo.getMdtrtId())) {
  111. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "此患者没有有效的医保挂号信息。");
  112. }
  113. JSONObject input = exec.makeTradeHeaderWithInsureArea(SiFunction.REVOKE_OUTPATIENT_REGISTRATION,
  114. siPatInfo.getInsuplcAdmdvs(), p.getStaffId());
  115. JSONObject data = new JSONObject();
  116. data.put("psn_no", siPatInfo.getPsnNo());
  117. data.put("mdtrt_id", siPatInfo.getMdtrtId());
  118. data.put("ipt_otp_no", p.getPatNo());
  119. input.getJSONObject("input").put("data", data);
  120. JSONObject result = exec.executeTrade(input, SiFunction.REVOKE_OUTPATIENT_REGISTRATION);
  121. log.info("【操作员:{}】,取消门诊挂号:\n参数:{},\n结果:{}", p.getStaffId(), input, result);
  122. if (null == result) {
  123. return ResultVoUtil.fail(ExceptionEnum.NETWORK_ERROR);
  124. }
  125. Integer infcode = result.getInteger(RESULT_CODE);
  126. logDao.insert(new SiLog(input, result, p.getPatNo(), p.getTimes(), infcode, siPatInfo.getPsnNo()));
  127. if (null == infcode) {
  128. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "医保中心报错:" + result.getString("message"));
  129. }
  130. if (infcode == 0) {
  131. mzDao.clearMdtrtIdForMz(p.getPatNo(), p.getTimes(), null);
  132. return ResultVoUtil.success("取消门诊挂号成功。");
  133. }
  134. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, result.getString(ERROR_MESSAGE));
  135. }
  136. private ResultVo<String> uploadOutpatientInfo(SpcChrDiseAcct indise, SiPatInfo siPatInfo, String staffId) {
  137. JSONObject input = exec.makeTradeHeaderWithInsureArea(SiFunction.UPLOAD_OUTPATIENT_INFO,
  138. siPatInfo.getInsuplcAdmdvs(), staffId);
  139. JSONObject mdtrtinfo = new JSONObject();
  140. List<Diseinfo> diseinfo;
  141. if (StringUtil.notBlank(indise.getOpspDiseCode())) {
  142. diseinfo = new ArrayList<>();
  143. Diseinfo diag = mzDao.selectDiseinfo(siPatInfo.getPatNo(), siPatInfo.getTimes());
  144. diag.setDiagCode(indise.getOpspDiseCode());
  145. diag.setDiagName(indise.getOpspDiseName());
  146. diseinfo.add(diag);
  147. mzDao.updatePatDiseinfo(siPatInfo.getPatNo(), siPatInfo.getTimes(), diag.getDiagCode(), diag.getDiagName());
  148. } else {
  149. if (siPatInfo.getFromDirectReg()) {
  150. String icdCodeNew = mzDao.selectIcdCodeNew(siPatInfo.getPatNo(), siPatInfo.getTimes());
  151. if (StringUtil.isBlank(icdCodeNew)) {
  152. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "患者的门诊诊断为空,请联系医生填写。");
  153. }
  154. diseinfo = new ArrayList<>();
  155. Diseinfo base = mzDao.selectDiseinfo(siPatInfo.getPatNo(), siPatInfo.getTimes());
  156. String[] icds = icdCodeNew.split(",");
  157. for (int i = 0; i < icds.length; i++) {
  158. String icd = icds[i];
  159. String icdTextNew = mzDao.selectIcdTextNew(icd);
  160. Diseinfo diag = new Diseinfo();
  161. diag.setDiagCode(icd);
  162. diag.setDiagName(icdTextNew);
  163. diag.setDiagSrtNo(i + 1);
  164. diag.setDiagType("1");
  165. diag.setValiFlag("1");
  166. diag.setDiagDept(base.getDiagDept());
  167. diag.setDiagTime(base.getDiagTime());
  168. diag.setDiseDorNo(base.getDiseDorNo());
  169. diag.setDiseDorName(base.getDiseDorName());
  170. diseinfo.add(diag);
  171. }
  172. indise.setOpspDiseCode(diseinfo.get(0).getDiagCode());
  173. indise.setOpspDiseName(diseinfo.get(0).getDiagName());
  174. } else {
  175. diseinfo = mzDao.selectMzDiags(siPatInfo.getPatNo(), siPatInfo.getTimes());
  176. if (null == diseinfo || diseinfo.isEmpty()) {
  177. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "患者的门诊诊断为空,请联系医生填写,或者自行补录。");
  178. }
  179. }
  180. }
  181. mdtrtinfo.put("mdtrt_id", siPatInfo.getMdtrtId());
  182. mdtrtinfo.put("psn_no", siPatInfo.getPsnNo());
  183. mdtrtinfo.put("med_type", siPatInfo.getMedType());
  184. mdtrtinfo.put("begntime", DateUtil.formatDatetime(siPatInfo.getVisitDatetime()));
  185. mdtrtinfo.put("main_cond_dscr", indise.getOpspDiseName());
  186. mdtrtinfo.put("dise_codg", indise.getOpspDiseCode());
  187. mdtrtinfo.put("dise_name", indise.getOpspDiseName());
  188. mdtrtinfo.put("birctrl_type", "");
  189. mdtrtinfo.put("birctrl_matn_date", "");
  190. String ref = JSONObject.toJSONString(diseinfo);
  191. input.getJSONObject("input").put("mdtrtinfo", mdtrtinfo);
  192. input.getJSONObject("input").put("diseinfo", JSONArray.parse(ref));
  193. JSONObject result = exec.executeTrade(input, SiFunction.UPLOAD_OUTPATIENT_INFO);
  194. log.info("【操作员:{}】门诊就诊信息上传:\n参数:{},\n结果:{}", staffId, input, result);
  195. Integer infcode = result.getInteger(RESULT_CODE);
  196. logDao.insert(new SiLog(input, result, siPatInfo.getPatNo(), siPatInfo.getTimes(), infcode, siPatInfo.getPsnNo()));
  197. if (result.getIntValue(RESULT_CODE) == 0) {
  198. return ResultVoUtil.success("门诊就诊信息上传成功。");
  199. }
  200. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, result.getString(ERROR_MESSAGE));
  201. }
  202. public ResultVo<SiPatInfo> uploadOutpatientFeeDetails(SpcChrDiseAcct p) {
  203. String patNo = p.getPatNo();
  204. if (null == p.getTimes()) {
  205. p.setTimes(mzDao.selectMaxTimes(patNo));
  206. }
  207. SiPatInfo siPatInfo = mzDao.selectSiPatInfoForMz(patNo, p.getTimes());
  208. if (null == siPatInfo || StringUtil.isBlank(siPatInfo.getMdtrtId())) {
  209. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "【门诊号:" + patNo +
  210. "】未找到此患者的医保挂号信息,请核实。");
  211. }
  212. if (!p.getFromDirectReg()) {
  213. ResultVo<String> uplRes = uploadOutpatientInfo(p, siPatInfo, p.getStaffId());
  214. if (null != uplRes && uplRes.getCode() != ExceptionEnum.SUCCESS.getCode()) {
  215. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, uplRes.getMessage());
  216. }
  217. }
  218. List<FeeDetail> feeDetails = mzDao.selectOutpatientFees(patNo, p.getTimes());
  219. if (null == feeDetails || feeDetails.isEmpty()) {
  220. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "此患者没有需要上传的费用。");
  221. }
  222. String batchNo = patNo + "_" + p.getTimes();
  223. feeDetails.forEach(item -> {
  224. item.setMdtrtId(siPatInfo.getMdtrtId());
  225. item.setPsnNo(siPatInfo.getPsnNo());
  226. item.setChrgBchno(batchNo);
  227. item.setRxCircFlag(YesOrNo.NO.getCodeStr());
  228. item.setHospApprFlag(YesOrNo.YES.getCodeStr());
  229. if (siPatInfo.getMedType().equals("51")) {
  230. item.setMatnFeeFlag("1");
  231. }
  232. });
  233. JSONObject input = exec.makeTradeHeaderWithInsureArea(SiFunction.UPLOAD_OUTPATIENT_FEE_DETAILS,
  234. siPatInfo.getInsuplcAdmdvs(), p.getStaffId());
  235. String ref = JSONArray.toJSONString(feeDetails);
  236. JSONArray feedetail = JSONArray.parseArray(ref);
  237. input.getJSONObject("input").put("feedetail", feedetail);
  238. JSONObject result = exec.executeTrade(input, SiFunction.UPLOAD_OUTPATIENT_FEE_DETAILS);
  239. log.info("【操作员:{}】门诊费用明细信息上传:\n参数:{},\n结果:{}", p.getStaffId(), input, result);
  240. if (null == result) {
  241. return ResultVoUtil.fail(ExceptionEnum.NETWORK_ERROR);
  242. }
  243. Integer infcode = result.getInteger(RESULT_CODE);
  244. logDao.insert(new SiLog(input, result, p.getPatNo(), p.getTimes(), infcode, siPatInfo.getPsnNo()));
  245. if (null == infcode) {
  246. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "医保中心报错:" + result.getString("message"));
  247. }
  248. if (infcode == 0) {
  249. JSONArray feeRes = result.getJSONObject(OUTPUT).getJSONArray("result");
  250. double fulamtOwnpayAmt = 0d;
  251. double overlmtAmt = 0d;
  252. double preselfpayAmt = 0d;
  253. double inscpScpAmt = 0d;
  254. for (int i = 0; i < feeRes.size(); i++) {
  255. JSONObject fee = feeRes.getJSONObject(i);
  256. fulamtOwnpayAmt += fee.getDoubleValue("fulamt_ownpay_amt");
  257. overlmtAmt += fee.getDoubleValue("overlmt_amt");
  258. preselfpayAmt += fee.getDoubleValue("preselfpay_amt");
  259. inscpScpAmt += fee.getDoubleValue("inscp_scp_amt");
  260. String detlSn = fee.getString("feedetl_sn");
  261. String chrgLv = fee.getString("chrgitm_lv");
  262. String chrgType = fee.getString("med_chrgitm_type");
  263. String[] sns = detlSn.split("_");
  264. int times = Integer.parseInt(sns[1]);
  265. int recNo = Integer.parseInt(sns[2]);
  266. int odrNo = Integer.parseInt(sns[3]);
  267. int itmNo = Integer.parseInt(sns[4]);
  268. mzDao.afterUploadFees(patNo, times, recNo, odrNo, itmNo, chrgLv, chrgType);
  269. }
  270. siPatInfo.setFulamtOwnpayAmt(fulamtOwnpayAmt);
  271. siPatInfo.setOverlmtAmt(overlmtAmt);
  272. siPatInfo.setPreselfpayAmt(preselfpayAmt);
  273. siPatInfo.setInscpScpAmt(inscpScpAmt);
  274. mzDao.updateSortOfAmt(siPatInfo);
  275. return ResultVoUtil.success(siPatInfo);
  276. }
  277. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, result.getString(ERROR_MESSAGE));
  278. }
  279. public ResultVo<String> revokeOutpatientFeeDetails(MzPatientInfo p) {
  280. if (null == p.getTimes()) {
  281. p.setTimes(mzDao.selectMaxTimes(p.getPatNo()));
  282. }
  283. SiPatInfo siPatInfo = mzDao.selectSiPatInfoForMz(p.getPatNo(), p.getTimes());
  284. if (null == siPatInfo || StringUtil.isBlank(siPatInfo.getMdtrtId())) {
  285. return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, "没有此患者的医保挂号信息!");
  286. }
  287. JSONObject input = exec.makeTradeHeaderWithInsureArea(SiFunction.REVOKE_OUTPATIENT_FEE_DETAILS,
  288. siPatInfo.getInsuplcAdmdvs(), p.getStaffId());
  289. JSONObject data = new JSONObject();
  290. data.put("mdtrt_id", siPatInfo.getMdtrtId());
  291. data.put("psn_no", siPatInfo.getPsnNo());
  292. data.put("chrg_bchno", "0000");
  293. input.getJSONObject("input").put("data", data);
  294. JSONObject result = exec.executeTrade(input, SiFunction.REVOKE_OUTPATIENT_FEE_DETAILS);
  295. log.info("【操作员:{}】门诊费用明细信息撤销,参数:{},结果:{}", p.getStaffId(), input, result);
  296. if (null == result) {
  297. return ResultVoUtil.fail(ExceptionEnum.NETWORK_ERROR);
  298. }
  299. Integer infcode = result.getInteger(RESULT_CODE);
  300. logDao.insert(new SiLog(input, result, p.getPatNo(), p.getTimes(), infcode, siPatInfo.getPsnNo()));
  301. if (null == infcode) {
  302. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "医保中心报错:" + result.getString("message"));
  303. }
  304. if (infcode == 0) {
  305. mzDao.afterRevokeFees(p.getPatNo(), p.getTimes());
  306. return ResultVoUtil.success("门诊费用明细信息撤销成功。");
  307. }
  308. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, result.getString(ERROR_MESSAGE));
  309. }
  310. public ResultVo<FundDetail> outpatientPreSettlement(MzPatientInfo p) {
  311. if (null == p.getTimes()) {
  312. p.setTimes(mzDao.selectMaxTimes(p.getPatNo()));
  313. }
  314. ResultVo<FundDetail> fundDetail1 = getFundDetailResultVo(p);
  315. if (fundDetail1 != null) return fundDetail1;
  316. MzPreSetlmt mzPreSetlmt = mzDao.selectPreSetlmt(p.getPatNo(), p.getTimes());
  317. ReadCardBizType readCardBizType = ReadCardBizType.get(p.getReadCardBizType());
  318. if (readCardBizType == ReadCardBizType.SETTLEMENT) {
  319. MdtrtCertType mdtrtCertType = MdtrtCertType.getByLabel(p.getMdtrtCertType());
  320. mzPreSetlmt.setMdtrtCertType(mdtrtCertType.getCode());
  321. if (mdtrtCertType == MdtrtCertType.SOCIAL_SECURITY_CARD) {
  322. String[] out = p.getReadCardResult().split("\\|");
  323. if (!p.getName().trim().equals(out[4].trim())) {
  324. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "社保卡姓名与HIS姓名不一致,请确认是否人证相符。");
  325. }
  326. mzPreSetlmt.setMdtrtCertNo(out[2]);
  327. mzPreSetlmt.setCardSn(out[3]);
  328. } else if (mdtrtCertType == MdtrtCertType.MEDICAL_INSURANCE_ELECTRONIC_VOUCHER) {
  329. JSONObject qrinfo = JSONObject.parseObject(p.getReadCardResult());
  330. if (!p.getName().trim().equals(qrinfo.getString("userName").trim())) {
  331. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "电子医保凭证姓名与HIS姓名不一致,请确认是否人证相符。");
  332. }
  333. if (!p.getSocialNo().trim().equals(qrinfo.getString("idNo").trim())) {
  334. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "电子医保凭证身份证与HIS身份证不一致,请确认是否人证相符。");
  335. }
  336. mzPreSetlmt.setMdtrtCertNo(qrinfo.getString("ecToken"));
  337. }
  338. }
  339. mzPreSetlmt.setMedfeeSumamt(mzPreSetlmt.getMedfeeSumamt().setScale(2, RoundingMode.HALF_UP));
  340. JSONObject input = exec.makeTradeHeaderWithInsureArea(SiFunction.OUTPATIENT_PRE_SETTLEMENT,
  341. mzPreSetlmt.getInsuplcAdmdvs(), p.getStaffId());
  342. mzPreSetlmt.setPsnSetlway(PsnSetlWay.SETTLE_BY_ITEMS.getCode());
  343. mzPreSetlmt.setAcctUsedFlag(p.getAcctUsedFlag());
  344. mzPreSetlmt.setChrgBchno(p.getPatNo() + "_" + p.getTimes());
  345. String ref = JSONObject.toJSONString(mzPreSetlmt);
  346. input.getJSONObject("input").put("data", JSONObject.parseObject(ref));
  347. JSONObject result = exec.executeTrade(input, SiFunction.OUTPATIENT_PRE_SETTLEMENT);
  348. log.info("【操作员:{}】门诊预结算:\n参数:{},\n结果:{}", p.getStaffId(), input, result);
  349. if (null == result) {
  350. return ResultVoUtil.fail(ExceptionEnum.NETWORK_ERROR);
  351. }
  352. Integer infcode = result.getInteger(RESULT_CODE);
  353. logDao.insert(new SiLog(input, result, p.getPatNo(), p.getTimes(), infcode, mzPreSetlmt.getPsnNo()));
  354. if (null == infcode) {
  355. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "医保中心报错:" + result.getString("message"));
  356. }
  357. if (infcode == 0) {
  358. JSONObject setlinfo = result.getJSONObject(OUTPUT).getJSONObject("setlinfo");
  359. FundDetail fundDetail = new FundDetail();
  360. fundDetail.setTotalCost(setlinfo.getString("medfee_sumamt"));
  361. fundDetail.setFundPay(setlinfo.getString("fund_pay_sumamt"));
  362. fundDetail.setCashPay(setlinfo.getString("psn_cash_pay"));
  363. fundDetail.setAcctPay(setlinfo.getString("acct_pay"));
  364. fundDetail.setSelfPay(setlinfo.getString("psn_part_amt"));
  365. return ResultVoUtil.success(fundDetail);
  366. }
  367. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, result.getString(ERROR_MESSAGE));
  368. }
  369. private ResultVo<FundDetail> getFundDetailResultVo(MzPatientInfo p) {
  370. SiSetlinfo sisetl = mzDao.selectSettledInfo(p.getPatNo(), p.getTimes(), 0);
  371. if (null != sisetl && null != sisetl.getSetlId()) {
  372. return getFundDetailResultVo(sisetl);
  373. }
  374. return null;
  375. }
  376. private ResultVo<FundDetail> getFundDetailResultVo(SiSetlinfo sisetl) {
  377. FundDetail fundDetail = new FundDetail();
  378. fundDetail.setTotalCost(String.valueOf(sisetl.getMedfeeSumamt()));
  379. fundDetail.setFundPay(String.valueOf(sisetl.getFundPaySumamt()));
  380. fundDetail.setCashPay(String.valueOf(sisetl.getPsnCashPay()));
  381. fundDetail.setAcctPay(String.valueOf(sisetl.getAcctPay()));
  382. fundDetail.setSelfPay(String.valueOf(sisetl.getPsnPartAmt()));
  383. if (sisetl.getRevoked() == 1) {
  384. fundDetail.reverseAll();
  385. }
  386. return ResultVoUtil.success(fundDetail);
  387. }
  388. public ResultVo<FundDetail> outpatientSettlement(MzPatientInfo p) {
  389. ResultVo<FundDetail> fundDetail1 = getFundDetailResultVo(p);
  390. if (fundDetail1 != null) return fundDetail1;
  391. Setlmt setlmt = mzDao.selectSetlmt(p.getPatNo(), p.getTimes());
  392. JSONObject input = exec.makeTradeHeaderWithInsureArea(SiFunction.OUTPATIENT_SETTLEMENT,
  393. setlmt.getInsuplcAdmdvs(), p.getStaffId());
  394. ReadCardBizType readCardBizType = ReadCardBizType.get(p.getReadCardBizType());
  395. if (readCardBizType == ReadCardBizType.SETTLEMENT) {
  396. MdtrtCertType mdtrtCertType = MdtrtCertType.getByLabel(p.getMdtrtCertType());
  397. setlmt.setMdtrtCertType(mdtrtCertType.getCode());
  398. if (mdtrtCertType == MdtrtCertType.SOCIAL_SECURITY_CARD) {
  399. String[] out = p.getReadCardResult().split("\\|");
  400. if (!p.getName().trim().equals(out[4].trim())) {
  401. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "社保卡姓名与HIS姓名不一致,请确认是否人证相符。");
  402. }
  403. setlmt.setMdtrtCertNo(out[2]);
  404. setlmt.setCardSn(out[3]);
  405. } else if (mdtrtCertType == MdtrtCertType.MEDICAL_INSURANCE_ELECTRONIC_VOUCHER) {
  406. JSONObject qrinfo = JSONObject.parseObject(p.getReadCardResult());
  407. if (!p.getName().trim().equals(qrinfo.getString("userName").trim())) {
  408. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "电子医保凭证姓名与HIS姓名不一致,请确认是否人证相符。");
  409. }
  410. if (!p.getSocialNo().trim().equals(qrinfo.getString("idNo").trim())) {
  411. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "电子医保凭证身份证与HIS身份证不一致,请确认是否人证相符。");
  412. }
  413. setlmt.setMdtrtCertNo(qrinfo.getString("ecToken"));
  414. }
  415. }
  416. setlmt.setMedfeeSumamt(setlmt.getMedfeeSumamt().setScale(2, RoundingMode.HALF_UP));
  417. setlmt.setPsnSetlway(PsnSetlWay.SETTLE_BY_ITEMS.getCode());
  418. setlmt.setChrgBchno(p.getPatNo() + "_" + p.getTimes());
  419. setlmt.setAcctUsedFlag(p.getAcctUsedFlag());
  420. setlmt.setInvono(SnowFlakeId.getInstance().nextId());
  421. String ref = JSONObject.toJSONString(setlmt);
  422. input.getJSONObject("input").put("data", JSONObject.parseObject(ref));
  423. JSONObject result = exec.executeTrade(input, SiFunction.OUTPATIENT_SETTLEMENT);
  424. log.info("【操作员:{}】门诊结算:\n参数:{},\n结果:{}", p.getStaffId(), input, result);
  425. if (null == result) {
  426. return ResultVoUtil.fail(ExceptionEnum.NETWORK_ERROR, "与医保中心的连接出现网络异常!");
  427. }
  428. Integer infcode = result.getInteger(RESULT_CODE);
  429. logDao.insert(new SiLog(input, result, p.getPatNo(), p.getTimes(), infcode, setlmt.getPsnNo()));
  430. if (null == infcode) {
  431. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "医保中心报错:" + result.getString("message"));
  432. }
  433. if (infcode == 0) {
  434. JSONObject setlinfo = result.getJSONObject(OUTPUT).getJSONObject("setlinfo");
  435. SiSetlinfo setlEntity = JSONObject.parseObject(setlinfo.toJSONString(), SiSetlinfo.class);
  436. setlEntity.setPatNo(p.getPatNo());
  437. setlEntity.setTimes(p.getTimes());
  438. setlEntity.setLedgerSn(0);
  439. setlEntity.setStaffId(p.getStaffId());
  440. setlEntity.setRevoked(YesOrNo.NO.getCode());
  441. setlEntity.setSetlType(ClrType.OUTPATIENT.getCode());
  442. setlEntity.setInsuplcAdmdvs(setlmt.getInsuplcAdmdvs());
  443. setlEntity.setBegntime(mzDao.selectBegntime(p.getPatNo(), p.getTimes()));
  444. setlEntity.setEndtime(setlEntity.getSetlTime());
  445. setlEntity.setMzSaved(p.getSaved());
  446. setlinfoDao.insert(setlEntity);
  447. setlinfoDao.updateSiZyInfoSetlId(p.getPatNo(), p.getTimes(), 0, setlEntity.getSetlId(),
  448. setlEntity.getMedinsSetlId(), input.getString("msgid"));
  449. JSONArray setldetail = result.getJSONObject(OUTPUT).getJSONArray("setldetail");
  450. for (int i = 0; i < setldetail.size(); i++) {
  451. SiSetldetail setldetailEntity = JSONObject.parseObject(setldetail.getJSONObject(i).toJSONString(),
  452. SiSetldetail.class);
  453. setldetailEntity.setPatNo(p.getPatNo());
  454. setldetailEntity.setTimes(p.getTimes());
  455. setldetailEntity.setLedgerSn(0);
  456. setldetailDao.insert(setldetailEntity);
  457. }
  458. return getFundDetailResultVo(setlEntity);
  459. }
  460. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, result.getString(ERROR_MESSAGE));
  461. }
  462. public ResultVo<FundDetail> revokeOutpatientSettlement(MzPatientInfo p) {
  463. if (null == p.getTimes()) {
  464. p.setTimes(mzDao.selectMaxTimes(p.getPatNo()));
  465. }
  466. SiSetlinfo setlinfo = mzDao.selectSettledInfo(p.getPatNo(), p.getTimes(), 0);
  467. if (null == setlinfo) {
  468. setlinfo = mzDao.selectSettledInfo(p.getPatNo(), p.getTimes(), 1);
  469. return getFundDetailResultVo(setlinfo);
  470. }
  471. JSONObject input = exec.makeTradeHeaderWithInsureArea(SiFunction.REVOKE_OUTPATIENT_SETTLEMENT,
  472. mzDao.selectAdmdvs(setlinfo.getPatNo(), setlinfo.getTimes(), setlinfo.getLedgerSn()), p.getStaffId());
  473. JSONObject data = new JSONObject();
  474. data.put("setl_id", setlinfo.getSetlId());
  475. data.put("mdtrt_id", setlinfo.getMdtrtId());
  476. data.put("psn_no", setlinfo.getPsnNo());
  477. input.getJSONObject("input").put("data", data);
  478. JSONObject result = exec.executeTrade(input, SiFunction.REVOKE_OUTPATIENT_SETTLEMENT);
  479. log.info("【操作员:{}】门诊结算撤销:\n参数:{},\n结果:{}", p.getStaffId(), input, result);
  480. if (null == result) {
  481. return ResultVoUtil.fail(ExceptionEnum.NETWORK_ERROR);
  482. }
  483. Integer infcode = result.getInteger(RESULT_CODE);
  484. logDao.insert(new SiLog(input, result, p.getPatNo(), p.getTimes(), infcode, setlinfo.getPsnNo()));
  485. if (null == infcode) {
  486. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "医保中心报错:" + result.getString("message"));
  487. }
  488. if (infcode == 0) {
  489. mzDao.deleteSetlInfo(p.getPatNo(), p.getTimes());
  490. mzDao.deleteSetlDetail(p.getPatNo(), p.getTimes());
  491. mzDao.updateRvkSetlMsgid(p.getPatNo(), p.getTimes(), input.getString("msgid"));
  492. return getFundDetailResultVo(setlinfo);
  493. }
  494. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, result.getString(ERROR_MESSAGE));
  495. }
  496. public void revokeOutpatientSettlementForTask(SiSetlinfo setlinfo) {
  497. JSONObject input = exec.makeTradeHeaderWithInsureArea(SiFunction.REVOKE_OUTPATIENT_SETTLEMENT,
  498. mzDao.selectAdmdvs(setlinfo.getPatNo(), setlinfo.getTimes(), setlinfo.getLedgerSn()), "99999");
  499. JSONObject data = new JSONObject();
  500. data.put("setl_id", setlinfo.getSetlId());
  501. data.put("mdtrt_id", setlinfo.getMdtrtId());
  502. data.put("psn_no", setlinfo.getPsnNo());
  503. input.getJSONObject("input").put("data", data);
  504. JSONObject result = exec.executeTrade(input, SiFunction.REVOKE_OUTPATIENT_SETTLEMENT);
  505. Integer infcode = result.getInteger(RESULT_CODE);
  506. logDao.insert(new SiLog(input, result, setlinfo.getPatNo(), setlinfo.getTimes(), infcode, setlinfo.getPsnNo()));
  507. if (null != infcode && infcode == 0) {
  508. mzDao.deleteSetlInfo(setlinfo.getPatNo(), setlinfo.getTimes());
  509. mzDao.deleteSetlDetail(setlinfo.getPatNo(), setlinfo.getTimes());
  510. mzDao.updateRvkSetlMsgid(setlinfo.getPatNo(), setlinfo.getTimes(), input.getString("msgid"));
  511. MzPatientInfo mzPatientInfo = new MzPatientInfo();
  512. mzPatientInfo.setPatNo(setlinfo.getPatNo());
  513. mzPatientInfo.setTimes(setlinfo.getTimes());
  514. mzPatientInfo.setStaffId("99999");
  515. revokeOutpatientFeeDetails(mzPatientInfo);
  516. revokeOutpatientRegistration(mzPatientInfo);
  517. }
  518. }
  519. public ResultVo<FundDetail> directRegistration(EcTokenParams ecpms) {
  520. // 查询参保信息
  521. MzPatientInfo mzptnt = new MzPatientInfo();
  522. mzptnt.setStaffId(ecpms.getStaffId());
  523. mzptnt.setPatNo(ecpms.getPatientId());
  524. mzptnt.setTimes(ecpms.getTimes());
  525. mzptnt.setAcctUsedFlag(String.valueOf(ecpms.getAcctUsedFlag()));
  526. int hasSiPatInfo = mzDao.updateMzTimes(mzptnt.getPatNo(), mzptnt.getTimes());
  527. if (hasSiPatInfo == 0) {
  528. Map<String, Object> map = webHisSrvc.queryInsuinfo(webHisUrl, ecpms);
  529. if (null == map) {
  530. return ResultVoUtil.fail(ExceptionEnum.NETWORK_ERROR);
  531. }
  532. if ((int) map.get("code") == -1) {
  533. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, map.get("msg").toString());
  534. }
  535. }
  536. // 查询到职工参保信息后挂号登记(执行到这一步,siPatInfo必不为空,所以无需作非空判断)
  537. SiPatInfo siPatInfo = mzDao.selectSiPatInfoForMz(mzptnt.getPatNo(), mzptnt.getTimes());
  538. mzptnt.setInsuplcAdmdvs(siPatInfo.getInsuplcAdmdvs());
  539. mzptnt.setInsutype(siPatInfo.getInsutype());
  540. mzptnt.setPsnType(siPatInfo.getPsnType());
  541. mzptnt.setName(siPatInfo.getPsnName());
  542. mzptnt.setSocialNo(siPatInfo.getCertno());
  543. if (StringUtil.notBlank(ecpms.getEcIndexNo())) {
  544. mzptnt.setMdtrtCertType(MdtrtCertType.MEDICAL_INSURANCE_ELECTRONIC_VOUCHER.getLabel());
  545. mzptnt.setReadCardBizType(ReadCardBizType.REGISTRATION.getCode());
  546. mzptnt.setReadCardResult(JSONObject.toJSONString(ecpms));
  547. }
  548. ResultVo<String> regres = outpatientRegistration(mzptnt);
  549. if (null == regres) {
  550. return ResultVoUtil.fail(ExceptionEnum.NETWORK_ERROR);
  551. }
  552. if (regres.getCode() != ExceptionEnum.SUCCESS.getCode()) {
  553. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, regres.getMessage());
  554. }
  555. // 挂号登记成功后上传就诊信息
  556. siPatInfo = mzDao.selectSiPatInfoForMz(mzptnt.getPatNo(), mzptnt.getTimes());
  557. siPatInfo.setFromDirectReg(true);
  558. SpcChrDiseAcct spcChrDiseAcct = new SpcChrDiseAcct();
  559. ResultVo<String> upldMdtrtRes = uploadOutpatientInfo(spcChrDiseAcct, siPatInfo, ecpms.getStaffId());
  560. if (null == upldMdtrtRes) {
  561. revokeOutpatientRegistration(mzptnt);
  562. return ResultVoUtil.fail(ExceptionEnum.NETWORK_ERROR);
  563. }
  564. if (upldMdtrtRes.getCode() != ExceptionEnum.SUCCESS.getCode()) {
  565. revokeOutpatientRegistration(mzptnt);
  566. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, upldMdtrtRes.getMessage());
  567. }
  568. // 上传就诊信息成功后生成门诊医保费用
  569. ResultVo<List<Map<String, Object>>> getMzRcptRes = webHisSrvc.getMzReceipts(webHisUrl, mzptnt);
  570. if (null == getMzRcptRes) {
  571. revokeOutpatientRegistration(mzptnt);
  572. return ResultVoUtil.fail(ExceptionEnum.NETWORK_ERROR);
  573. }
  574. if (getMzRcptRes.getCode() != ExceptionEnum.SUCCESS.getCode()) {
  575. revokeOutpatientRegistration(mzptnt);
  576. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, getMzRcptRes.getMessage());
  577. }
  578. List<MzReceipt> mzReceipts = new ArrayList<>();
  579. for (Map<String, Object> item : getMzRcptRes.getData()) {
  580. Map<Integer, List<MzReceipt>> orderReceiptsMap = FilterUtil.cast(item.get("mzReceipts"));
  581. for (Map.Entry<Integer, List<MzReceipt>> entry : orderReceiptsMap.entrySet()) {
  582. mzReceipts.addAll(entry.getValue());
  583. }
  584. }
  585. ResultVo<String> insertSiMzFeeRes = webHisSrvc.insertSiMzFees(webHisUrl, mzReceipts);
  586. if (null == insertSiMzFeeRes) {
  587. revokeOutpatientRegistration(mzptnt);
  588. return ResultVoUtil.fail(ExceptionEnum.NETWORK_ERROR);
  589. }
  590. if (insertSiMzFeeRes.getCode() != ExceptionEnum.SUCCESS.getCode()) {
  591. revokeOutpatientRegistration(mzptnt);
  592. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, insertSiMzFeeRes.getMessage());
  593. }
  594. // 生成费用成功后上传到医保
  595. spcChrDiseAcct.setStaffId(ecpms.getStaffId());
  596. spcChrDiseAcct.setPatNo(mzptnt.getPatNo());
  597. spcChrDiseAcct.setTimes(mzptnt.getTimes());
  598. spcChrDiseAcct.setFromDirectReg(true);
  599. ResultVo<SiPatInfo> upldFeeRes = uploadOutpatientFeeDetails(spcChrDiseAcct);
  600. if (null == upldFeeRes) {
  601. revokeOutpatientRegistration(mzptnt);
  602. return ResultVoUtil.fail(ExceptionEnum.NETWORK_ERROR);
  603. }
  604. if (upldFeeRes.getCode() != ExceptionEnum.SUCCESS.getCode()) {
  605. revokeOutpatientRegistration(mzptnt);
  606. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, upldFeeRes.getMessage());
  607. }
  608. // 上传完成之后结算并返回结算结果
  609. return outpatientSettlement(mzptnt);
  610. }
  611. private InsuInfo getEmployeeInsuInfo(List<InsuInfo> list) {
  612. for (InsuInfo info : list) {
  613. if (info.getInsutype().equals("310")) {
  614. return info;
  615. }
  616. }
  617. return null;
  618. }
  619. // public ResultVo<String> payOnline(EcTokenParams params) {
  620. //
  621. //
  622. // }
  623. // private ResultVo<EcTokenUpldRslt> ecTokenUploadFees(EcTokenParams params) {
  624. // EcTokenUpldDetl upldDetl = mzDao.selectEcTokenUpldDetl(params.getPatientId(), params.getTimes());
  625. // if (null == upldDetl || StringUtil.isBlank(upldDetl.getMdtrtId())) {
  626. // return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "患者有没有效的医保登记信息,请核实。");
  627. // }
  628. // upldDetl.setIdNo(params.getIdNo());
  629. // upldDetl.setUserName(params.getUserName());
  630. // upldDetl.setIdType(params.getIdType());
  631. // upldDetl.setEcToken(params.getEcToken());
  632. // upldDetl.setInsuCode(params.getInsuOrg());
  633. // upldDetl.setIptOtpNo(params.getPatientId());
  634. //
  635. // upldDetl.setDiseinfoList(null);
  636. // upldDetl.setFeedetailList(null);
  637. //
  638. // JSONObject input = exec.makeTradeHeaderWithInsureArea(SiFunction.ECTOKEN_UPLOAD_FEE_DETAIL,
  639. // params.getInsuOrg(), params.getStaffId());
  640. // }
  641. }