XiangMuLuRuService.java 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750
  1. package thyyxxk.webserver.service.yibao;
  2. import com.alibaba.fastjson.JSON;
  3. import com.alibaba.fastjson.JSONObject;
  4. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  5. import com.baomidou.mybatisplus.core.metadata.IPage;
  6. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  7. import lombok.extern.slf4j.Slf4j;
  8. import org.apache.commons.collections4.ListUtils;
  9. import org.springframework.beans.BeanUtils;
  10. import org.springframework.beans.factory.annotation.Autowired;
  11. import org.springframework.stereotype.Service;
  12. import org.springframework.transaction.annotation.Transactional;
  13. import thyyxxk.webserver.config.exception.ExceptionEnum;
  14. import thyyxxk.webserver.dao.his.yibao.XiangMuLuRuDao;
  15. import thyyxxk.webserver.entity.ResultVo;
  16. import thyyxxk.webserver.entity.datamodify.GetDropdownBox;
  17. import thyyxxk.webserver.entity.datamodify.ZyDetailCharge;
  18. import thyyxxk.webserver.entity.yibao.ZyActpatient;
  19. import thyyxxk.webserver.service.PublicServer;
  20. import thyyxxk.webserver.utils.*;
  21. import javax.servlet.http.HttpServletResponse;
  22. import java.math.BigDecimal;
  23. import java.util.ArrayList;
  24. import java.util.HashMap;
  25. import java.util.List;
  26. import java.util.Map;
  27. import java.util.stream.Collectors;
  28. /**
  29. * <p>
  30. * 描述: 项目录入
  31. * </p>
  32. *
  33. * @author xc
  34. * @date 2021-08-02 10:37
  35. */
  36. @Service
  37. @Slf4j
  38. public class XiangMuLuRuService {
  39. private final XiangMuLuRuDao dao;
  40. private final PublicServer publicServer;
  41. @Autowired
  42. public XiangMuLuRuService(XiangMuLuRuDao dao, PublicServer publicServer) {
  43. this.dao = dao;
  44. this.publicServer = publicServer;
  45. }
  46. /**
  47. * 获取患者费用
  48. * 费用 类型 1 - 医嘱 2 - 项目费用 3 - 医技 4 - 全部 5 -药品费用
  49. *
  50. * @param param 查询条件
  51. * @return 返回患者费用
  52. */
  53. public ResultVo<Page<ZyDetailCharge>> getHuanZheFeiYong(ZyDetailCharge param) {
  54. if (StringUtil.isBlank(param.getInpatientNo()) || param.getAdmissTimes() == null) {
  55. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "住院号或住院次数为空 <br/>๑乛◡乛๑");
  56. }
  57. Integer ledgerSn = publicServer.getLedgerSn(param.getInpatientNo(), param.getAdmissTimes());
  58. log.info("查询患者费用==》住院号{},住院次数:{},项目名称:{},费用类型:{},科室:{},当前页:{},页大小:{},退费:{},总数:{},账页号:{}", param.getInpatientNo(), param.getAdmissTimes(), param.getChargeCode(), param.getOrderNo(), param.getDept(), param.getCurrentPage(), param.getPageSize(), param.getTuiFeiFlag(), param.getTotal(), ledgerSn);
  59. int infantFlag = 0;
  60. // 如果是婴儿的话那么就需要截取 字符串了 在通过婴儿标识来判断
  61. if (param.getInpatientNo().contains("$")) {
  62. param.setInpatientNo(param.getInpatientNo().split("\\$")[0]);
  63. infantFlag = 1;
  64. }
  65. if (param.getTuiFeiFlag() == null) {
  66. param.setTuiFeiFlag(2);
  67. }
  68. Page<ZyDetailCharge> page = new Page<>();
  69. if (param.getFeiYongLeiXingCode() == 0) {
  70. if (param.getTotal() == 0) {
  71. page.setTotal(dao.huanZheFeiYongToatal(param.getInpatientNo(), param.getAdmissTimes(), ledgerSn, param.getChargeCode(), infantFlag, param.getStartTime(), param.getEndTime(), param.getOrderNo(), param.getDept(), param.getTuiFeiFlag()));
  72. }
  73. page.setRecords(dao.huanZheXiangMuFeiYong(param.getCurrentPage(), param.getPageSize(), param.getInpatientNo(), param.getAdmissTimes(), ledgerSn, param.getChargeCode(), infantFlag, param.getStartTime(), param.getEndTime(), param.getOrderNo(), param.getDept(), param.getRiQiPaiXu(), param.getTuiFeiFlag()));
  74. } else {
  75. if (param.getTotal() == 0) {
  76. page.setTotal(dao.huanZheYaoPinFeiYongTotal(param.getInpatientNo(), param.getAdmissTimes(), ledgerSn, param.getChargeCode(), infantFlag, param.getStartTime(), param.getEndTime(), param.getOrderNo(), param.getDept(), param.getTuiFeiFlag()));
  77. }
  78. page.setRecords(dao.huanZheYaoPinFeiYong(param.getCurrentPage(), param.getPageSize(), param.getInpatientNo(), param.getAdmissTimes(), ledgerSn, param.getChargeCode(), infantFlag, param.getStartTime(), param.getEndTime(), param.getOrderNo(), param.getDept(), param.getRiQiPaiXu(), param.getTuiFeiFlag()));
  79. }
  80. if (ListUtil.isBlank(page.getRecords())) {
  81. return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST, "没有查询到符合费用。");
  82. }
  83. return ResultVoUtil.success(page);
  84. }
  85. /**
  86. * 搜索项目信息
  87. *
  88. * @param pyCode 拼音码
  89. * @return 返回项目信息
  90. */
  91. public ResultVo<List<GetDropdownBox>> getChargeCode(String pyCode) {
  92. return ResultVoUtil.success(dao.getChargeCode(StringUtil.isContainChinese(pyCode)));
  93. }
  94. /**
  95. * @param param 需要生成退费 的数据
  96. * @return 返回
  97. */
  98. @Transactional(rollbackFor = Exception.class)
  99. public ResultVo<String> xiangMuTuiFei(ZyDetailCharge param, Boolean panDuanYaoPing) {
  100. List<Integer> yongHuJueSe = dao.huoQuJueSe(TokenUtil.getTokenUserId());
  101. if (!yongHuJueSe.contains(36) && !yongHuJueSe.contains(1)) {
  102. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "您没有权限退费。");
  103. }
  104. if (param.getList() == null || param.getList().isEmpty()) {
  105. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "请先选择需要退费的数据,一次性退费不得超过100条");
  106. } else if (param.getList().size() > 100) {
  107. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "项目退费一次性大于100条数据");
  108. }
  109. if (StringUtil.isBlank(param.getInpatientNo()) || param.getAdmissTimes() == null || param.getList().size() == 0) {
  110. return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, "患者信息不全");
  111. }
  112. if (dao.getHuanZheSFZaiYuan(param.getInpatientNo(), param.getAdmissTimes()) == 0) {
  113. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "该患者已出院");
  114. }
  115. int infantFlag = 0;
  116. // 判断是否为婴儿
  117. if (param.getInpatientNo().contains("$")) {
  118. param.setInpatientNo(param.getInpatientNo().split("\\$")[0]);
  119. infantFlag = 1;
  120. }
  121. Integer ledgerSn = publicServer.getLedgerSn(param.getInpatientNo(), param.getAdmissTimes());
  122. // 判断数据是否为 退费数据
  123. List<ZyDetailCharge> chaKanSFtuiFei = dao.chaKanSFYiJingTuiFeiLe(param.getInpatientNo(), param.getAdmissTimes(), ledgerSn, param.getList());
  124. for (ZyDetailCharge charge : chaKanSFtuiFei) {
  125. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, String.format("流水号为:【%s】已退费,请勿重复退费。", charge.getOriDetailSn()));
  126. }
  127. if (dao.getHuanZheSFJieSuan(param.getInpatientNo(), param.getAdmissTimes()) == null || dao.getHuanZheSFJieSuan(param.getInpatientNo(), param.getAdmissTimes()) != 0) {
  128. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "该患者已经结算了");
  129. }
  130. // 获取原来的数据
  131. List<ZyDetailCharge> yuanTuiFeiList = dao.huoQuJuTiFeiYong(param.getInpatientNo(), param.getAdmissTimes(), ledgerSn, param.getList());
  132. // 获取患者的总费用
  133. BigDecimal sum = new BigDecimal(0);
  134. // 退费的list
  135. // 获取最大值
  136. Integer maxDetailSn = publicServer.getMaxDetailSn(param.getInpatientNo(), param.getAdmissTimes());
  137. List<ZyDetailCharge> yaoPingDan = new ArrayList<>();
  138. List<Integer> genXingZhenShuTuiFeiLiuShui = new ArrayList<>();
  139. List<ZyDetailCharge> tuiFeiList = new ArrayList<>();
  140. // 获取到用户角色 管理员角色可以无视
  141. List<String> zhiXinKeShi = dao.chaXunZhiZXinKeShi(param.getDeptCode());
  142. for (ZyDetailCharge pojo : yuanTuiFeiList) {
  143. // 判断患者的费用是否存在负数
  144. if (pojo.getChargeFee().signum() == -1 || pojo.getChargeAmount().signum() == -1) {
  145. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, String.format("患者费用存在负数,流水号:【%s】,该数据为退费数据。", pojo.getDetailSn()));
  146. }
  147. if (pojo.getChargeCode().startsWith("BILL")) {
  148. yaoPingDan.add(pojo);
  149. }
  150. // 在这里判断执行科室
  151. ResultVo<String> LOGICAL_ERROR = getStringResultVo(yongHuJueSe, zhiXinKeShi, param, pojo, panDuanYaoPing);
  152. if (LOGICAL_ERROR != null) {
  153. return LOGICAL_ERROR;
  154. }
  155. // 数据库有个 触发器 如果带了医嘱号且有篆刻那么这里就需要改成 0
  156. if (BigUtils.bigDaYu(pojo.getOrderNo(), 10)) {
  157. pojo.setOrderNo(new BigDecimal(0));
  158. }
  159. sum = sum.add(pojo.getChargeFee().multiply(pojo.getChargeAmount()));
  160. pojo.setChargeFee(pojo.getChargeFee().negate());
  161. pojo.setChargeAmount(pojo.getChargeAmount().negate());
  162. pojo.setOpIdCode(TokenUtil.getTokenUserId());
  163. pojo.setOriDetailSn(pojo.getDetailSn());
  164. pojo.setDetailSn(maxDetailSn += 1);
  165. pojo.setOldGenTime(DateUtil.formatDatetime(pojo.getGenTime(), DateUtil.DEFAULT_PATTERN));
  166. // 向退费 list 里面添加
  167. tuiFeiList.add(pojo);
  168. genXingZhenShuTuiFeiLiuShui.add(pojo.getOriDetailSn());
  169. }
  170. // 执行退费的操作 20 条的退费
  171. if (tuiFeiList.isEmpty()) {
  172. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "查询不到患者原数据,请联系管理员。");
  173. } else {
  174. log.info("操作项目退费 ==》 操作人:{},数据:{}", TokenUtil.getTokenUserId(), JSON.toJSONString(tuiFeiList));
  175. List<List<ZyDetailCharge>> fenGe = ListUtils.partition(tuiFeiList, 20);
  176. if (ListUtil.notBlank(yaoPingDan)) {
  177. dao.shenQingYaoPing(param, yaoPingDan, infantFlag, publicServer.getLedgerSn(param.getInpatientNo(), param.getAdmissTimes()), TokenUtil.getTokenUserId());
  178. }
  179. fenGe.forEach(dao::xiangMuTuiFei);
  180. dao.genXinZhenShuTuiFeiLiuShui(param.getInpatientNo(), param.getAdmissTimes(), publicServer.getLedgerSn(param.getInpatientNo(), param.getAdmissTimes()), genXingZhenShuTuiFeiLiuShui);
  181. return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "项目退费操作成功。乁( ˙ ω˙乁)");
  182. }
  183. }
  184. private ResultVo<String> getStringResultVo(List<Integer> yongHuJueSe, List<String> zhiXinKeShi, ZyDetailCharge xuYaoTuiDeShuJu, ZyDetailCharge piPeiDeShuJu, Boolean panDuanYaoPin) {
  185. // 获取到用户角色 管理员角色可以无视
  186. if (!yongHuJueSe.contains(1) && !yongHuJueSe.contains(8)) {
  187. // 科室开头 是 8 就不是医技科室 只有医技科室可以退药品
  188. if (xuYaoTuiDeShuJu.getDeptCode().startsWith("8")) {
  189. //获取到这个人是否属于这个科室
  190. if (!zhiXinKeShi.contains(piPeiDeShuJu.getExecUnit())) {
  191. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, String.format("流水号为【%s】,请对应的执行科室进行退费。", piPeiDeShuJu.getDetailSn()));
  192. }
  193. // 护士是不可以退药品的
  194. if (panDuanYaoPin) {
  195. if (piPeiDeShuJu.getChargeCode().startsWith("BILL")) {
  196. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, String.format("流水号为【%s】,包含药品费用,无法退费。", piPeiDeShuJu.getDetailSn()));
  197. }
  198. }
  199. } else if (panDuanYaoPin) {
  200. if (!xuYaoTuiDeShuJu.getDeptCode().equals(piPeiDeShuJu.getExecUnit())) {
  201. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, String.format("流水号为【%s】,请对应的执行科室进行退费。", piPeiDeShuJu.getDetailSn()));
  202. } else if ((BigUtils.bigDaYu(piPeiDeShuJu.getOrderNo(), 100) || BigUtils.bigXiaoYu(piPeiDeShuJu.getOrderNo(), 0)) && "01".equals(piPeiDeShuJu.getSerial())) {
  203. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, String.format("流水号为【%s】,只能退本科室录入的药品。", piPeiDeShuJu.getDetailSn()));
  204. }
  205. }
  206. }
  207. return null;
  208. }
  209. /**
  210. * 获取模板
  211. *
  212. * @param deptCode 根据科室搜索
  213. * @return 返回模板
  214. */
  215. public ResultVo<IPage<ZyDetailCharge>> getMuBan(String deptCode, long currentPage, long pageSize, long total) {
  216. IPage<ZyDetailCharge> page = new Page<>(currentPage, pageSize, total == 0);
  217. QueryWrapper<?> qw = new QueryWrapper<>();
  218. qw.ne("isnull(pattern_name,'')", "''");
  219. if (publicServer.noNeedRule()) {
  220. qw.eq("op_dept", deptCode);
  221. }
  222. dao.getMuBan(page, qw);
  223. return ResultVoUtil.success(page);
  224. }
  225. /**
  226. * 获取模板的具体信息
  227. *
  228. * @param patternName 模板名称
  229. * @param opIdCode 存模板的人
  230. * @return 返回具体的模板
  231. */
  232. public ResultVo<List<ZyDetailCharge>> getMuBanXinXi(String patternName, String opIdCode) {
  233. return ResultVoUtil.success(dao.getMuBanXinXi(patternName, opIdCode));
  234. }
  235. /**
  236. * 获取科室
  237. *
  238. * @return 返回科室信息
  239. */
  240. public ResultVo<List<GetDropdownBox>> getDept() {
  241. return ResultVoUtil.success(dao.getDpet());
  242. }
  243. /**
  244. * 获取病区
  245. *
  246. * @return 返回科室信息
  247. */
  248. public ResultVo<List<GetDropdownBox>> getWard() {
  249. return ResultVoUtil.success(dao.getWard());
  250. }
  251. /**
  252. * 通过拼音码 来搜索项目
  253. *
  254. * @param pyCode 拼音码
  255. * @param xiangMuHuoYaoPinFlag 判断是查询项目还是药品 0 - 项目 1- 药品
  256. * @return 返回项目
  257. */
  258. public ResultVo<List<ZyDetailCharge>> queryXiangMu(String pyCode, Integer xiangMuHuoYaoPinFlag) {
  259. if (xiangMuHuoYaoPinFlag == 0) {
  260. return ResultVoUtil.success(dao.queryXiangMu("%" + pyCode.toUpperCase() + "%"));
  261. }
  262. return ResultVoUtil.success(dao.queryYaoPin("%" + pyCode.toUpperCase() + "%"));
  263. }
  264. /**
  265. * 这个项目录入
  266. *
  267. * @param param 参数
  268. * @return 返回提示语句
  269. */
  270. @Transactional(rollbackFor = Exception.class)
  271. public ResultVo<String> xiangMuFeiYongShangChuan(ZyDetailCharge param) {
  272. if (param.getList().size() > 50) {
  273. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "一次性项目录入大于50条");
  274. }
  275. StringBuilder errorStr = new StringBuilder();
  276. if (StringUtil.isBlank(param.getInpatientNo()) || param.getAdmissTimes() == null) {
  277. errorStr.append("住院号和住院次数为空<br />");
  278. }
  279. if (param.getList().size() == 0) {
  280. errorStr.append("没有要录入的项目 <br />");
  281. }
  282. if (StringUtil.isBlank(param.getWard())) {
  283. errorStr.append("病区为空 <br />");
  284. }
  285. if (StringUtil.isBlank(param.getDept())) {
  286. errorStr.append("申请科室为空 <br />");
  287. }
  288. if (StringUtil.isBlank(param.getZySerialNo())) {
  289. errorStr.append("住院流水号为空 <br />");
  290. }
  291. if (dao.getHuanZheSFZaiYuan(param.getInpatientNo(), param.getAdmissTimes()) == 0) {
  292. errorStr.append("没有患者的在院信息 <br />");
  293. }
  294. if (errorStr.length() > 0) {
  295. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, errorStr.toString());
  296. }
  297. // 收费项目的编码
  298. List<String> shiFouTingYongXiangMu = new ArrayList<>();
  299. param.getList().forEach(item -> {
  300. shiFouTingYongXiangMu.add(item.getChargeCodeMx());
  301. });
  302. List<String> yiTingYong = dao.chaXunFeiYongShiFouTingYong(shiFouTingYongXiangMu);
  303. // 药品没有库存这个限制先放开
  304. // List<String> meiYouKuCun = dao.kuCun(shiFouTingYongXiangMu);
  305. // if (ListUtil.notBlank(meiYouKuCun)) {
  306. // return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "费用录入错误,药品无库存 【" + JSON.toJSONString(meiYouKuCun) + "】");
  307. // }
  308. if (ListUtil.notBlank(yiTingYong)) {
  309. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "费用录入错误,包含已停用的项目 【" + JSON.toJSONString(yiTingYong) + "】");
  310. }
  311. // 婴儿 要特殊处理
  312. // 如果带有这个 $ 说明是婴儿
  313. int infantFlag = publicServer.getInfantFlag(param.getInpatientNo());
  314. param.setInpatientNo(publicServer.getInpatientNo(param.getInpatientNo()));
  315. // 获取最大流水号
  316. Integer maxDetailSn = publicServer.getMaxDetailSn(param.getInpatientNo(), param.getAdmissTimes());
  317. // 获取项目的 总费用
  318. BigDecimal sum = new BigDecimal(0);
  319. // 录入人的id
  320. param.setOpIdCode(TokenUtil.getTokenUserId());
  321. List<ZyDetailCharge> yaoPingShenQingDan = new ArrayList<>();
  322. // 药品
  323. for (ZyDetailCharge zyDetailCharge : param.getList()) {
  324. switch (zyDetailCharge.getBillItemCode()) {
  325. case "001":
  326. zyDetailCharge.setSerial("01");
  327. zyDetailCharge.setChargeCode("BILL01");
  328. break;
  329. case "002":
  330. zyDetailCharge.setSerial("01");
  331. zyDetailCharge.setChargeCode("BILL02");
  332. break;
  333. case "028":
  334. zyDetailCharge.setSerial("01");
  335. zyDetailCharge.setChargeCode("BILL28");
  336. break;
  337. default:
  338. // Serial 00 项目标志 01 药品标志
  339. zyDetailCharge.setSerial("00");
  340. zyDetailCharge.setChargeCode(zyDetailCharge.getChargeCodeMx());
  341. break;
  342. }
  343. if (zyDetailCharge.getChargeAmount() == null || zyDetailCharge.getAmount() == null) {
  344. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "数量或金额不能为空。");
  345. }
  346. // 判断患者的费用是否存在负数
  347. if (zyDetailCharge.getChargeAmount().signum() == -1 || zyDetailCharge.getAmount().signum() == -1) {
  348. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "不能录入负数");
  349. }
  350. if (zyDetailCharge.getChargeAmount().compareTo(new BigDecimal(0)) == 0 || zyDetailCharge.getAmount().compareTo(new BigDecimal(0)) == 0) {
  351. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "录入费用为 0");
  352. }
  353. if (StringUtil.isBlank(zyDetailCharge.getChargeCodeMx())) {
  354. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "项目编码空值。");
  355. }
  356. if (StringUtil.isBlank(zyDetailCharge.getDeptCode())) {
  357. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "执行科室为空。");
  358. }
  359. if (zyDetailCharge.getChargeCodeMx() == null) {
  360. zyDetailCharge.setChargeCodeMx(zyDetailCharge.getChargeCode());
  361. }
  362. if (dao.getHuanZheSFJieSuan(param.getInpatientNo(), param.getAdmissTimes()) == null || dao.getHuanZheSFJieSuan(param.getInpatientNo(), param.getAdmissTimes()) != 0) {
  363. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "该患者已经结算了");
  364. }
  365. // 0 - 住院费用 3 - 门急诊 6 - 医技
  366. if (param.getOrderNo() != null) {
  367. zyDetailCharge.setOrderNo(param.getOrderNo());
  368. } else {
  369. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "医嘱号为空");
  370. }
  371. sum = sum.add(zyDetailCharge.getChargeAmount().multiply(zyDetailCharge.getAmount()));
  372. // 这里不会保存单价 只会总价
  373. zyDetailCharge.setChargeAmount(zyDetailCharge.getChargeAmount().multiply(zyDetailCharge.getAmount()));
  374. zyDetailCharge.setDetailSn(maxDetailSn += 1);
  375. if ("01".equals(zyDetailCharge.getSerial())) {
  376. ZyDetailCharge shenQing = new ZyDetailCharge();
  377. BeanUtils.copyProperties(zyDetailCharge, shenQing);
  378. shenQing.setChargeFee(zyDetailCharge.getChargeAmount());
  379. shenQing.setChargeAmount((zyDetailCharge.getAmount()));
  380. yaoPingShenQingDan.add(shenQing);
  381. }
  382. }
  383. Integer ledgerSn = publicServer.getLedgerSn(param.getInpatientNo(), param.getAdmissTimes());
  384. // 在此处 插入费用
  385. dao.chaRuFeiYong(param, param.getList(), infantFlag, ledgerSn);
  386. if (ListUtil.notBlank(yaoPingShenQingDan)) {
  387. dao.shenQingYaoPing(param, yaoPingShenQingDan, infantFlag, ledgerSn, TokenUtil.getTokenUserId());
  388. }
  389. log.info("项目录入费用上传 ==》 操作人:{},数据:{}", param.getOpIdCode(), JSON.toJSONString(param));
  390. return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "费用上传成功。<( ̄︶ ̄)>");
  391. }
  392. /**
  393. * 上传以及修改项目录入模板
  394. *
  395. * @param zyDetailCharge 模板的一些数据
  396. * @return 返回成功提示
  397. */
  398. @Transactional(rollbackFor = Exception.class)
  399. public ResultVo<String> shangChuanMuBan(ZyDetailCharge zyDetailCharge) {
  400. if (dao.chaKanMuBanMingChengSFcunZi(zyDetailCharge.getName(), TokenUtil.getTokenUserId()) > 0) {
  401. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "模板名称重复,๐·°(৹˃̵﹏˂̵৹)°·๐");
  402. }
  403. zyDetailCharge.setOpIdCode(TokenUtil.getTokenUserId());
  404. for (ZyDetailCharge detailCharge : zyDetailCharge.getList()) {
  405. if (StringUtil.notBlank(zyDetailCharge.getBillItemCode())) {
  406. if ("001".equals(detailCharge.getBillItemCode()) || "002".equals(detailCharge.getBillItemCode())) {
  407. detailCharge.setSerial("01");
  408. detailCharge.setGroupNo("73");
  409. } else if ("028".equals(zyDetailCharge.getBillItemCode())) {
  410. zyDetailCharge.setSerial("01");
  411. zyDetailCharge.setChargeCode("BILL28");
  412. } else {
  413. // Serial 00 项目标志 01 药品标志
  414. detailCharge.setSerial("00");
  415. }
  416. }
  417. }
  418. // 在创建新的模板之前 需要先删除 原来的
  419. dao.delMuBan(zyDetailCharge.getName(), zyDetailCharge.getOpIdCode());
  420. dao.baoCunMuBan(zyDetailCharge);
  421. log.info("保存项目录入模板 ==》 操作人 :{},数据:{}", zyDetailCharge.getOpIdCode(), JSON.toJSONString(zyDetailCharge));
  422. return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "保存模板成功。ㄟ(≧◇≦)ㄏ");
  423. }
  424. /**
  425. * 医嘱退费匹配
  426. * 第一次匹配使用 收费日期,数量,项目编码,医嘱号,账页号 来进行匹配
  427. * 第二次匹配使用,数量,项目编码,账页号,执行科室来进行匹配的
  428. *
  429. * @param inpatientNo 住院号
  430. * @param admissTimes 住院次数
  431. * @return 返回是否匹配成功
  432. */
  433. @Transactional(rollbackFor = Exception.class)
  434. public ResultVo<String> yiZhuTuiFeiPiPei(String inpatientNo, Integer admissTimes, String deptCode) {
  435. if (StringUtil.isBlank(inpatientNo) || admissTimes == null || StringUtil.isBlank(deptCode)) {
  436. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "患者信息不全。");
  437. }
  438. int infantFlag = publicServer.getInfantFlag(inpatientNo);
  439. inpatientNo = publicServer.getInpatientNo(inpatientNo);
  440. Integer ledgerSn = publicServer.getLedgerSn(inpatientNo, admissTimes);
  441. List<String> keShiLeiBiao = publicServer.huoQuBingFangDeKeShi(deptCode);
  442. // 获取正的医嘱费用
  443. List<ZyDetailCharge> getYiZhuFeiYongZhenShu = dao.getYiZhuFeiYong(inpatientNo, admissTimes, ledgerSn, ">", infantFlag, keShiLeiBiao);
  444. // 获取负的医嘱费用
  445. List<ZyDetailCharge> getYiZhuFeiYongFuShu = dao.getYiZhuFeiYong(inpatientNo, admissTimes, ledgerSn, "<", infantFlag, keShiLeiBiao);
  446. // 获取负数的退费数据 主要是用来判断 这一条正的是否退费了。
  447. List<ZyDetailCharge> tuiFeiList = dao.tuiFeiList(inpatientNo, admissTimes, infantFlag);
  448. if (!tuiFeiList.isEmpty()) {
  449. Map<Integer, Integer> map = new HashMap<>();
  450. for (ZyDetailCharge zyDetailCharge : tuiFeiList) {
  451. map.put(zyDetailCharge.getOriDetailSn(), zyDetailCharge.getDetailSn());
  452. }
  453. getYiZhuFeiYongZhenShu.forEach(item -> {
  454. if (map.containsKey(item.getDetailSn())) {
  455. item.setTuiFeiFlag(1);
  456. }
  457. });
  458. }
  459. // 需要保存需要匹配的一些流水数据
  460. List<ZyDetailCharge> piPei = new ArrayList<>();
  461. // 此处是需要二次匹配的 list
  462. List<ZyDetailCharge> erCiPiPei = new ArrayList<>();
  463. // 用map 来保存正数的信息,但是有可能匹配的条件中map 的 key会一致 所以在这里使用 java8 的新特性 stream 流来进行分组 这样就不会因为key 一样导致数据被覆盖了
  464. // 第一次 匹配 根据 医嘱号 收费时间 项目编码 数量 账页号
  465. Map<String, List<ZyDetailCharge>> zhenShuMap = getYiZhuFeiYongZhenShu.stream().collect(Collectors.groupingBy(item -> item.getOrderNo() + DateUtil.formatDatetime(item.getChargeDate()) + item.getChargeCodeMx() + item.getChargeAmount() + item.getChargeFee() + item.getLedgerSn()));
  466. // 用负数拼接的 key 去查找
  467. for (ZyDetailCharge fuShu : getYiZhuFeiYongFuShu) {
  468. String key = fuShu.getOrderNo() + DateUtil.formatDatetime(fuShu.getChargeDate()) + fuShu.getChargeCodeMx() + fuShu.getChargeAmount().negate() + fuShu.getChargeFee().negate() + fuShu.getLedgerSn();
  469. if (zhenShuMap.containsKey(key)) {
  470. for (ZyDetailCharge zyDetailCharge : zhenShuMap.get(key)) {
  471. if (zyDetailCharge.getTuiFeiFlag() == null && zyDetailCharge.getOriDetailSn() == null) {
  472. fuShu.setOriDetailSn(zyDetailCharge.getDetailSn());
  473. zyDetailCharge.setTuiFeiFlag(1);
  474. piPei.add(fuShu);
  475. log.info("第一次匹配==》流水:{},匹配流水:{},", fuShu.getDetailSn(), fuShu.getOriDetailSn());
  476. break;
  477. }
  478. }
  479. } else {
  480. // 这个是需要进行二次匹配的
  481. erCiPiPei.add(fuShu);
  482. }
  483. }
  484. // 下面是二次匹配
  485. if (erCiPiPei.size() > 0) {
  486. // 二次匹配 条件为 执行科室 项目编码 数量 账页号
  487. Map<String, List<ZyDetailCharge>> erCiPiPeiZhenShu = getYiZhuFeiYongZhenShu.stream().collect(Collectors.groupingBy(item -> item.getExecUnit() + item.getChargeCodeMx() + item.getChargeAmount() + item.getChargeFee() + item.getLedgerSn()));
  488. // 开始二次匹配
  489. for (ZyDetailCharge zyDetailCharge : erCiPiPei) {
  490. String key = zyDetailCharge.getExecUnit() + zyDetailCharge.getChargeCodeMx() + zyDetailCharge.getChargeAmount().negate() + zyDetailCharge.getChargeFee().negate() + zyDetailCharge.getLedgerSn();
  491. if (erCiPiPeiZhenShu.containsKey(key)) {
  492. for (ZyDetailCharge detailCharge : erCiPiPeiZhenShu.get(key)) {
  493. if (detailCharge.getTuiFeiFlag() == null && detailCharge.getOriDetailSn() == null) {
  494. zyDetailCharge.setOriDetailSn(detailCharge.getDetailSn());
  495. detailCharge.setTuiFeiFlag(1);
  496. piPei.add(zyDetailCharge);
  497. log.info("第二次匹配==》流水:{},匹配流水:{}", zyDetailCharge.getDetailSn(), zyDetailCharge.getOriDetailSn());
  498. break;
  499. }
  500. }
  501. }
  502. }
  503. }
  504. // 开始匹配
  505. if (piPei.size() > 0) {
  506. // 100 条的更新 ListUtils.partition 用来拆分 list size 是拆分的条数
  507. List<List<ZyDetailCharge>> fenDuan = ListUtils.partition(piPei, 100);
  508. for (List<ZyDetailCharge> list : fenDuan) {
  509. dao.yiZhuTuiFeiPiPei(inpatientNo, admissTimes, list, infantFlag);
  510. }
  511. publicServer.genXingYuanLiuShuiBiaoZhi(inpatientNo, admissTimes, ledgerSn);
  512. log.info("医嘱退费匹配 ==》 操作人:{},住院号:{},住院次数:{}", TokenUtil.getTokenUserId(), inpatientNo, admissTimes);
  513. return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, String.format("匹配成功共:{%d}条,匹配成功:{%s}条", getYiZhuFeiYongFuShu.size(), piPei.size()));
  514. }
  515. publicServer.genXingYuanLiuShuiBiaoZhi(inpatientNo, admissTimes, ledgerSn);
  516. return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST, String.format("该患者有【%d】条,未能匹配 |д・)っ", getYiZhuFeiYongFuShu.size()));
  517. }
  518. /**
  519. * 此处删除模板 这个模板是录入住院费用的 模板
  520. *
  521. * @param patterName 模板名称
  522. * @param opIdCode 创建模板人的姓名
  523. * @return 返回提示
  524. */
  525. public ResultVo<String> shanChuMuBan(String patterName, String opIdCode) {
  526. log.info("删除项目模板 ==》操作人:{},模板名称:{}", TokenUtil.getTokenUserId(), patterName);
  527. dao.delMuBan(patterName, opIdCode);
  528. return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "删除成功,o(^▽^)o");
  529. }
  530. /**
  531. * 生成拼音和五笔码
  532. *
  533. * @param inputStr 中文
  534. * @return 返回编码
  535. */
  536. public ResultVo<ZyDetailCharge> getPyCode(String inputStr) {
  537. ZyDetailCharge zyDetailCharge = new ZyDetailCharge();
  538. zyDetailCharge.setPyCode(PingYinUtils.pyShouZiMuDaXie(inputStr));
  539. zyDetailCharge.setWbCode(PingYinUtils.getWBCode(inputStr));
  540. return ResultVoUtil.success(zyDetailCharge);
  541. }
  542. /**
  543. * 根据对应的病区来获取科室
  544. *
  545. * @param ward 科室编码
  546. * @return 返回对应的
  547. */
  548. public ResultVo<List<GetDropdownBox>> getBingQuDuiYingKeShi(String ward) {
  549. return ResultVoUtil.success(dao.getBingQuDuiYingKeShi(ward));
  550. }
  551. @Transactional(rollbackFor = Exception.class)
  552. public ResultVo<String> cheXiaoTuiFei(String inpatientNo, Integer admissTimes, Integer ledger, Integer detailSn) {
  553. if (StringUtil.isBlank(inpatientNo) || admissTimes == null || ledger == null || detailSn == null) {
  554. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "患者信息不全。");
  555. }
  556. inpatientNo = publicServer.getInpatientNo(inpatientNo);
  557. ZyDetailCharge zyDetailCharge = dao.beiTuiFeiYongXinXi(inpatientNo, admissTimes, ledger, detailSn);
  558. if (zyDetailCharge == null) {
  559. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "未查询到对应信息,可能该费用可能已经被撤销了或被正负相抵了。");
  560. }
  561. if (!"0".equals(zyDetailCharge.getTransFlagYb())) {
  562. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "费用已经被上传了,无法撤销。");
  563. }
  564. if (zyDetailCharge.getOriDetailSn() != null && zyDetailCharge.getOriDetailSn() == -1) {
  565. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "被退数据无法删除。");
  566. }
  567. dao.cheXiaoFeiYong(inpatientNo, admissTimes, ledger, detailSn);
  568. dao.cheXiaoHouHuanYuanZhenShuJu(inpatientNo, admissTimes, ledger, zyDetailCharge.getOriDetailSn());
  569. log.info("撤销退费 ==> 操作人:{},住院号:{},住院次数:{},账页号:{},流水号:{},原流水号:{}", TokenUtil.getTokenUserId(), inpatientNo, admissTimes, ledger, detailSn, zyDetailCharge.getOriDetailSn());
  570. return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "撤销成功,请刷新数据。");
  571. }
  572. @Transactional(rollbackFor = Exception.class)
  573. public ResultVo<ZyActpatient> weiGuiFeiYongFenXi(String inpatientNo, String execUnit) {
  574. ZyActpatient patient = publicServer.huoQuHuanZheXinXi(inpatientNo);
  575. List<String> keShi = publicServer.huoQuBingFangDeKeShi(execUnit);
  576. publicServer.genXingYuanLiuShuiBiaoZhi(patient.getInpatientNo(), patient.getAdmissTimes(), patient.getLedgerSn());
  577. // 药品 分大包装和小包装 可能大包装 匹配了 小包装没有 匹配 所以这里编码同步 一下
  578. List<String> yaoPingBianMaTongBu = dao.weiGuiYaoPinInt(patient.getInpatientNo(), patient.getAdmissTimes(), patient.getLedgerSn(), patient.getInfantFlag());
  579. // 这里退药 医嘱 有可能会没有携带 执行科室
  580. List<ZyDetailCharge> huoQuYaoPingZhongKeShiWeiKongDe = dao.huoQuYaoPingZhongKeShiWeiKongDe(inpatientNo, patient.getAdmissTimes(), patient.getLedgerSn());
  581. if (!huoQuYaoPingZhongKeShiWeiKongDe.isEmpty()) {
  582. dao.yiZhuTuiFeiGenXingZhiXingKeShi(inpatientNo, patient.getAdmissTimes(), patient.getLedgerSn(), huoQuYaoPingZhongKeShiWeiKongDe);
  583. }
  584. if (yaoPingBianMaTongBu.size() > 0) {
  585. dao.genXinYaoPingPiPeiXinXi(yaoPingBianMaTongBu);
  586. }
  587. patient.setWeiPiPei(new ArrayList<>());
  588. patient.setWeiXieDaiYuanLiuShui(new ArrayList<>());
  589. if ("al".equals(patient.getResponceType())) {
  590. patient.getWeiPiPei().addAll(dao.gongShangWeiPiPei(patient.getInpatientNo(), patient.getAdmissTimes(), patient.getLedgerSn(), patient.getInfantFlag()));
  591. } else {
  592. patient.getWeiPiPei().addAll(dao.weiGuiYaoPin(patient.getInpatientNo(), patient.getAdmissTimes(), patient.getLedgerSn(), patient.getInfantFlag()));
  593. patient.getWeiPiPei().addAll(dao.weiGuiXiangMu(patient.getInpatientNo(), patient.getAdmissTimes(), patient.getLedgerSn(), patient.getInfantFlag()));
  594. }
  595. patient.getWeiXieDaiYuanLiuShui().addAll(dao.weiXieDaiYuanLiuShuiXiangMu(patient.getInpatientNo(), patient.getAdmissTimes(), patient.getLedgerSn(), patient.getInfantFlag(), keShi, patient.getChuYuanYiZhu()));
  596. patient.getWeiXieDaiYuanLiuShui().addAll(dao.weiXieDaiYuanLiuShuiYaoPing(patient.getInpatientNo(), patient.getAdmissTimes(), patient.getLedgerSn(), patient.getInfantFlag(), keShi, patient.getChuYuanYiZhu()));
  597. return ResultVoUtil.success(patient);
  598. }
  599. public ResultVo<List<ZyDetailCharge>> huoQuZhenShuKePiPei(String inpatientNo, Integer admissTimes, Integer ledgerSn, String chargeCodeMx, String execUnit, String orderNo, String startTime, String endTime, String riQiPaiXu) {
  600. execUnit = StringUtil.isBlank(execUnit) ? null : execUnit;
  601. List<ZyDetailCharge> zhenShuFeiYong = dao.weiGuiZhenShuPiPei(publicServer.getInpatientNo(inpatientNo), admissTimes, ledgerSn, publicServer.getInfantFlag(inpatientNo), chargeCodeMx, execUnit, orderNo, startTime, endTime, riQiPaiXu);
  602. if (ListUtil.isBlank(zhenShuFeiYong)) {
  603. zhenShuFeiYong.addAll(dao.weiGuiZhenShuPiPei(publicServer.getInpatientNo(inpatientNo), admissTimes, ledgerSn, publicServer.getInfantFlag(inpatientNo), chargeCodeMx, null, orderNo, startTime, endTime, riQiPaiXu));
  604. }
  605. if (ListUtil.isBlank(zhenShuFeiYong)) {
  606. return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST, "没有查询到该负数费用的对应正数。", dao.genJuBianMaChaZhaoZhenShuFeiYong(publicServer.getInpatientNo(inpatientNo), admissTimes, ledgerSn, publicServer.getInfantFlag(inpatientNo), chargeCodeMx, startTime, endTime, riQiPaiXu));
  607. }
  608. List<ZyDetailCharge> yuEr = dao.tuiFeiYuEr1(publicServer.getInpatientNo(inpatientNo), admissTimes, ledgerSn, chargeCodeMx, execUnit);
  609. Map<String, ZyDetailCharge> yuErPiPei = new HashMap<>();
  610. for (ZyDetailCharge item : yuEr) {
  611. String key = item.getInpatientNo() + item.getAdmissTimes() + item.getDetailSn() + item.getChargeCodeMx();
  612. yuErPiPei.put(key, item);
  613. }
  614. // TODO: 2022/1/11 这里需要优化 把计算余额的放到程序里面来计算
  615. for (int i = 0, len = zhenShuFeiYong.size(); i < len; i++) {
  616. ZyDetailCharge zy = zhenShuFeiYong.get(i);
  617. String key = zy.getInpatientNo() + zy.getAdmissTimes() + zy.getDetailSn() + zy.getChargeCodeMx();
  618. if (yuErPiPei.containsKey(key)) {
  619. if (BigUtils.dengYu(yuErPiPei.get(key).getYiTuiFei(), 0)) {
  620. zhenShuFeiYong.remove(i);
  621. len--;
  622. i--;
  623. } else {
  624. // 这里是 set 退费的余额
  625. zy.setYiTuiFei(yuErPiPei.get(key).getYiTuiFei());
  626. }
  627. }
  628. }
  629. return ResultVoUtil.success(zhenShuFeiYong);
  630. }
  631. @Transactional(rollbackFor = Exception.class)
  632. public ResultVo<String> caiFenPiPei(ZyDetailCharge zyDetailCharge) {
  633. String inpatientNo = publicServer.getInpatientNo(zyDetailCharge.getInpatientNo());
  634. Integer infantFlag = publicServer.getInfantFlag(zyDetailCharge.getInpatientNo());
  635. if (ListUtil.isBlank(zyDetailCharge.getList())) {
  636. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "请选择数据。");
  637. }
  638. int[] detailSnList = new int[zyDetailCharge.getList().size()];
  639. for (int i = 0; i < zyDetailCharge.getList().size(); i++) {
  640. detailSnList[i] = zyDetailCharge.getList().get(i).getDetailSn();
  641. }
  642. ZyDetailCharge zy = dao.piPeiXinXiFuShu(inpatientNo, zyDetailCharge.getAdmissTimes(), zyDetailCharge.getLedgerSn(), infantFlag, zyDetailCharge.getDetailSn());
  643. if (zy == null) {
  644. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "未找到负数费用信息,可能已经被删除了,请刷新页面重试。");
  645. } else if (zy.getOriDetailSn() != null || "2".equals(zy.getTransFlagYb())) {
  646. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "该负数费用已被正负相抵。");
  647. }
  648. List<ZyDetailCharge> zhenShuShuJu = dao.piPeiXinXi(inpatientNo, zyDetailCharge.getAdmissTimes(), zyDetailCharge.getLedgerSn(), infantFlag, detailSnList);
  649. Map<Integer, ZyDetailCharge> tuiFeiYuErPiPei = dao.tuiFeiYuEr2(inpatientNo, zyDetailCharge.getAdmissTimes(), zyDetailCharge.getLedgerSn(), infantFlag, detailSnList).stream().collect(Collectors.toMap(ZyDetailCharge::getOriDetailSn, a -> a, (k1, k2) -> k1));
  650. BigDecimal chargeFeeSum = new BigDecimal(0);
  651. BigDecimal chargeAmountSum = new BigDecimal(0);
  652. List<Integer> yongHuJueSe = dao.huoQuJueSe(TokenUtil.getTokenUserId());
  653. List<String> zhiXinKeShi = dao.chaXunZhiZXinKeShi(zyDetailCharge.getDeptCode());
  654. for (ZyDetailCharge detailCharge : zhenShuShuJu) {
  655. if (!BigUtils.dengYu(detailCharge.getOrderNo(), zyDetailCharge.getOrderNo())) {
  656. ResultVo<String> LOGICAL_ERROR = getStringResultVo(yongHuJueSe, zhiXinKeShi, zyDetailCharge, detailCharge, false);
  657. if (LOGICAL_ERROR != null) {
  658. return LOGICAL_ERROR;
  659. }
  660. }
  661. if ("2".equals(detailCharge.getTransFlagYb())) {
  662. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, String.format("流水号为:{%d},已被正负抵消。", detailCharge.getDetailSn()));
  663. }
  664. if (tuiFeiYuErPiPei.containsKey(detailCharge.getDetailSn())) {
  665. detailCharge.setChargeFee(detailCharge.getChargeFee().add(tuiFeiYuErPiPei.get(detailCharge.getDetailSn()).getChargeFee()));
  666. }
  667. chargeFeeSum = chargeFeeSum.add(detailCharge.getChargeFee());
  668. chargeAmountSum = chargeAmountSum.add(detailCharge.getChargeAmount());
  669. }
  670. if (zhenShuShuJu.size() == 1) {
  671. if (BigUtils.bigDaYu(chargeFeeSum, zy.getChargeFee().negate()) || BigUtils.dengYu(chargeFeeSum, zy.getChargeFee().negate())) {
  672. dao.zhiYouYiGeJiuGenXingFuShuLiuShui(zyDetailCharge.getInpatientNo(), zyDetailCharge.getAdmissTimes(), zyDetailCharge.getLedgerSn(), zyDetailCharge.getDetailSn(), zhenShuShuJu.get(0).getDetailSn());
  673. publicServer.genXingYuanLiuShuiBiaoZhi(inpatientNo, zyDetailCharge.getAdmissTimes(), zyDetailCharge.getLedgerSn());
  674. return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "费用匹配成功。");
  675. }
  676. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, String.format("负数费用:{%.2f},匹配费用:{%.2f} \n 负数数量:{%.2f},匹配数量:{%.2f}", zy.getChargeFee().negate(), chargeFeeSum, zy.getChargeAmount().negate(), chargeAmountSum));
  677. } else {
  678. return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "每次只能匹配一条。");
  679. }
  680. }
  681. public void exportExcel(HttpServletResponse response, ZyDetailCharge param) {
  682. log.info("导出患者费用数据:{}", JSONObject.toJSONStringWithDateFormat(param, DateUtil.DEFAULT_PATTERN));
  683. param.setPageSize(param.getTotal());
  684. param.setCurrentPage(1);
  685. List<ZyDetailCharge> list = getHuanZheFeiYong(param).getData().getRecords();
  686. String[] title = {"流水号", "医嘱号", "录入日期", "项目编码", "项目名称", "药品名称", "执行时间", "执行科室", "申请科室", "金额", "数量", "状态", "录入人", "账单码"};
  687. String[][] content = new String[list.size()][];
  688. for (int i = 0; i < list.size(); i++) {
  689. content[i] = new String[title.length];
  690. ZyDetailCharge pojo = list.get(i);
  691. content[i][0] = String.valueOf(pojo.getDetailSn());
  692. content[i][1] = String.valueOf(pojo.getOrderNo());
  693. content[i][2] = DateUtil.formatDatetime(pojo.getChargeDate());
  694. content[i][3] = pojo.getChargeCodeMx();
  695. content[i][4] = pojo.getChargeName();
  696. content[i][5] = pojo.getDrugname();
  697. content[i][6] = DateUtil.formatDatetime(pojo.getGenTime());
  698. content[i][7] = pojo.getExecDept();
  699. content[i][8] = pojo.getDeptCode();
  700. content[i][9] = pojo.getChargeFee().toString();
  701. content[i][10] = pojo.getChargeAmount().toString();
  702. content[i][11] = "1".equals(pojo.getChargeStatus()) ? "录入" : "2".equals(pojo.getChargeStatus()) ? "上账" : "结算";
  703. content[i][12] = pojo.getOpName();
  704. content[i][13] = pojo.getBillItemName();
  705. }
  706. ExcelUtil.exportExcel(response, title, content);
  707. }
  708. }