package thyyxxk.webserver.service.yibao; import com.alibaba.fastjson.JSON; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.ListUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import thyyxxk.webserver.config.exception.ExceptionEnum; import thyyxxk.webserver.dao.his.yibao.TransferInOfExpensesDao; import thyyxxk.webserver.dao.his.yibao.XiangMuLuRuDao; import thyyxxk.webserver.entity.ResultVo; import thyyxxk.webserver.entity.datamodify.FeiYongLeiXin; import thyyxxk.webserver.entity.datamodify.GetDropdownBox; import thyyxxk.webserver.entity.datamodify.ZyDetailCharge; import thyyxxk.webserver.utils.*; import java.math.BigDecimal; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** *

* 描述: 项目录入 *

* * @author xc * @date 2021-08-02 10:37 */ @Service @Slf4j public class XiangMuLuRuService { private final XiangMuLuRuDao dao; private final TransferInOfExpensesDao transferInOfExpensesDao; @Autowired public XiangMuLuRuService(XiangMuLuRuDao dao, TransferInOfExpensesDao transferInOfExpensesDao) { this.dao = dao; this.transferInOfExpensesDao = transferInOfExpensesDao; } /** * 获取患者费用 * * @param param 查询条件 * @return 返回患者费用 */ public ResultVo> getHuanZheFeiYong(ZyDetailCharge param) { log.info("查询患者费用==》住院号{},住院次数:{},项目名称:{},录入日期:{},费用类型:{}", param.getInpatientNo(), param.getAdmissTimes(), param.getChargeCode(), param.getStartTime(), param.getOrderNo()); int infantFlag = 0; // 如果是婴儿的话那么就需要截取 字符串了 在通过婴儿标识来判断 if (param.getInpatientNo().contains("$")) { param.setInpatientNo(param.getInpatientNo().split("\\$")[0]); infantFlag = 1; } List list = dao.getHuanZheFeiYong(param.getInpatientNo(), param.getAdmissTimes(), param.getChargeCode(), infantFlag, param.getStartTime(), param.getOrderNo()); Map map = new HashMap<>(); for (int i = 0; i < list.size(); i++) { // 判断一下这一条数据 是否为 退费数据 再把原数据和 本身添加一个退费的 flag if (map.containsKey(list.get(i).getOriDetailSn())) { // 把当前的数据 添加一个有 退费标志的 list.get(i).setTuiFeiFlag(1); // 在吧 对应退费的原数据 也添加一个 list.get(map.get(list.get(i).getOriDetailSn())).setTuiFeiFlag(1); } else { // 保存下标 map.put(list.get(i).getDetailSn(), i); } } return ResultVoUtil.success(list); } /** * 搜索项目信息 * * @param pyCode 拼音码 * @return 返回项目信息 */ public ResultVo> getChargeCode(String pyCode) { return ResultVoUtil.success(dao.getChargeCode(StringUtil.isContainChinese(pyCode))); } /** * @param param 需要生成退费 的数据 * @return 返回 */ @Transactional(rollbackFor = Exception.class) public ResultVo xiangMuTuiFei(ZyDetailCharge param) { if (param.getList().size() > 100) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "项目退费一次性大于100条数据"); } if (StringUtil.isBlank(param.getInpatientNo()) || param.getAdmissTimes() == null || param.getLedgerSn() == null || param.getList().size() == 0) { return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, "患者信息不全"); } // 判断数据是否为 退费数据 List chaKanSFtuiFei = dao.chaKanSFYiJingTuiFeiLe(param.getInpatientNo(), param.getAdmissTimes(), param.getLedgerSn(), param.getList()); for (ZyDetailCharge charge : chaKanSFtuiFei) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, String.format("流水号为:【%s】已退费,请勿重复退费", charge.getOriDetailSn())); } // 判断是否为婴儿 if (param.getInpatientNo().contains("$")) { param.setInpatientNo(param.getInpatientNo().split("\\$")[0]); } // 获取到用户角色 List yongHuJueSe = dao.huoQuJueSe(TokenUtil.getTokenUserId()); //获取到这个人是否属于这个科室 List zhiXinKeShi = dao.chaXunZhiZXinKeShi(param.getDeptCode()); // 获取原来的数据 List yuanTuiFeiList = dao.huoQuJuTiFeiYong(param.getInpatientNo(), param.getAdmissTimes(), param.getLedgerSn(), param.getList()); // 获取患者的总费用 BigDecimal sum = new BigDecimal(0); // 退费的list // 获取最大值 Integer maxDetailSn = transferInOfExpensesDao.getMaxDetailSn(param.getInpatientNo(), param.getAdmissTimes()); List tuiFeiList = new ArrayList<>(); for (ZyDetailCharge pojo : yuanTuiFeiList) { // 判断患者的费用是否存在负数 if (pojo.getChargeFee().signum() == -1 || pojo.getChargeAmount().signum() == -1) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, String.format("患者费用存在负数,流水号:【%s】,该数据为退费数据", pojo.getDetailSn())); } // 管理员角色可以无视 if (!yongHuJueSe.contains(1)) { if (!zhiXinKeShi.contains(pojo.getExecUnit())) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, String.format("流水号为【%s】,请对应的执行科室进行退费。", pojo.getDetailSn())); } } // 判断如果这个药品的医嘱号 大于0 那么就不能退 if (pojo.getChargeCode().equals("BILL01") || pojo.getChargeCode().equals("BILL02")) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, String.format("流水号为【%s】,中草药费或西药费,无法退费。", pojo.getDetailSn())); } sum = sum.add(pojo.getChargeFee().multiply(pojo.getChargeAmount())); pojo.setChargeFee(pojo.getChargeFee().negate()); pojo.setChargeAmount(pojo.getChargeAmount().negate()); pojo.setOpIdCode(TokenUtil.getTokenUserId()); pojo.setOriDetailSn(pojo.getDetailSn()); pojo.setDetailSn(maxDetailSn += 1); pojo.setOldGenTime(DateUtil.formatDatetime(pojo.getGenTime(), DateUtil.DEFAULT_PATTERN)); // 向退费 list 里面添加 tuiFeiList.add(pojo); } // 总费用计算 FeiYongLeiXin fy = JiSuanFeiYong.jiSuan(yuanTuiFeiList, false); // 计算出这一次 总退的费用 fy.setTotalCharge(sum.negate()); // 执行退费的操作 20 条的退费 if (tuiFeiList.isEmpty()) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "查询不到患者原数据,请联系管理员。"); } else { List> fenGe = ListUtils.partition(tuiFeiList, 20); fenGe.forEach(dao::xiangMuTuiFei); dao.huanZheZongFeiYong(fy, param.getInpatientNo(), param.getAdmissTimes(), "zy_actpatient"); log.info("操作项目退费 ==》 操作人:{},数据:{}", TokenUtil.getTokenUserId(), JSON.toJSONString(tuiFeiList)); return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "项目退费操作成功。"); } } /** * 获取模板 * * @param deptCode 根据科室搜索 * @return 返回模板 */ public ResultVo> getMuBan(String deptCode) { return ResultVoUtil.success(dao.getMuBan(deptCode)); } /** * 获取模板的具体信息 * * @param patternName 模板名称 * @param opIdCode 存模板的人 * @return 返回具体的模板 */ public ResultVo> getMuBanXinXi(String patternName, String opIdCode) { return ResultVoUtil.success(dao.getMuBanXinXi(patternName, opIdCode)); } /** * 通过拼音码 来搜索项目 * * @param pyCode 拼音码 * @return 返回项目 */ public ResultVo> queryXiangMu(String pyCode) { return ResultVoUtil.success(dao.queryXiangMu(pyCode.toUpperCase() + "%")); } /** * 这个项目录入 * * @param param 参数 * @return 返回提示语句 */ @Transactional(rollbackFor = Exception.class) public ResultVo xiangMuFeiYongShangChuan(ZyDetailCharge param) { if (param.getList().size() > 50) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "一次性项目录入大于50条"); } if (StringUtil.isBlank(param.getInpatientNo()) || param.getAdmissTimes() == null || param.getLedgerSn() == null || param.getList().size() == 0 || StringUtil.isBlank(param.getWard()) || StringUtil.isBlank(param.getDept()) || StringUtil.isBlank(param.getZySerialNo())) { return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, "患者信息不全。"); } // 婴儿 要特殊处理 int infantFlag = 0; // 如果带有这个 $ 说明是婴儿 if (param.getInpatientNo().contains("$")) { infantFlag = 1; param.setInpatientNo(param.getInpatientNo().split("\\$")[0]); } // 获取最大流水号 Integer maxDetailSn = transferInOfExpensesDao.getMaxDetailSn(param.getInpatientNo(), param.getAdmissTimes()); // 获取项目的 总费用 BigDecimal sum = new BigDecimal(0); // 录入人的id param.setOpIdCode(TokenUtil.getTokenUserId()); for (ZyDetailCharge zyDetailCharge : param.getList()) { zyDetailCharge.setDetailSn(maxDetailSn += 1); // 判断患者的费用是否存在负数 if (zyDetailCharge.getChargeAmount().signum() == -1 || zyDetailCharge.getAmount().signum() == -1) { return ResultVoUtil.fail(ExceptionEnum.EXIST_NEGATIVE_FEES); } sum = sum.add(zyDetailCharge.getChargeAmount().multiply(zyDetailCharge.getAmount())); // 这里不会保存 zyDetailCharge.setChargeAmount(zyDetailCharge.getChargeAmount().multiply(zyDetailCharge.getAmount())); if (StringUtil.isBlank(zyDetailCharge.getChargeCode())) { return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, "项目编码空值。"); } if (StringUtil.isBlank(zyDetailCharge.getDeptCode())) { return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, "执行科室为空。"); } } FeiYongLeiXin fy = JiSuanFeiYong.jiSuan(param.getList(), true); fy.setTotalCharge(sum); // 在此处 插入费用 dao.chaRuFeiYong(param, param.getList(), infantFlag); dao.huanZheZongFeiYong(fy, param.getInpatientNo(), param.getAdmissTimes(), "zy_actpatient"); log.info("项目录入费用上传 ==》 操作人:{},数据:{}", param.getOpIdCode(), JSON.toJSONString(param)); return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "费用上传成功。"); } /** * 上传以及修改项目录入模板 * * @param zyDetailCharge 模板的一些数据 * @return 返回成功提示 */ public ResultVo shangChuanMuBan(ZyDetailCharge zyDetailCharge) { if (dao.chaKanMuBanMingChengSFcunZi(zyDetailCharge.getName(), TokenUtil.getTokenUserId()) > 0) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "模板名称重复"); } zyDetailCharge.setOpIdCode(TokenUtil.getTokenUserId()); // 在创建新的模板之前 需要先删除 原来的 dao.delMuBan(zyDetailCharge.getName(), zyDetailCharge.getOpIdCode()); dao.baoCunMuBan(zyDetailCharge); log.info("保存项目录入模板 ==》 操作人 :{},数据:{}", zyDetailCharge.getOpIdCode(), JSON.toJSONString(zyDetailCharge)); return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "保存模板成功。"); } /** * 医嘱退费匹配 * * @param inpatientNo 住院号 * @param admissTimes 住院次数 * @return 返回是否匹配成功 */ public ResultVo yiZhuTuiFeiPiPei(String inpatientNo, Integer admissTimes) { // 获取正的医嘱费用 List getYiZhuFeiYongZhenShu = dao.getYiZhuFeiYong(inpatientNo, admissTimes, ">"); // 获取负的医嘱费用 List getYiZhuFeiYongFuShu = dao.getYiZhuFeiYong(inpatientNo, admissTimes, "<"); // 需要保存需要匹配的一些流水数据 List piPei = new ArrayList<>(); // 保存正数的数据用 map 来匹配 Map zhenShuMap = new HashMap<>(); for (ZyDetailCharge zhenShu : getYiZhuFeiYongZhenShu) { String key = zhenShu.getOrderNo() + DateUtil.formatDatetime(zhenShu.getChargeDate()) + zhenShu.getChargeCodeMx() + zhenShu.getChargeAmount(); zhenShuMap.put(key, zhenShu); } // 用负数拼接的 key 去查找 for (ZyDetailCharge fuShu : getYiZhuFeiYongFuShu) { String key = fuShu.getOrderNo() + DateUtil.formatDatetime(fuShu.getChargeDate()) + fuShu.getChargeCodeMx() + fuShu.getChargeAmount().negate(); if (zhenShuMap.containsKey(key)) { fuShu.setOriDetailSn(zhenShuMap.get(key).getDetailSn()); piPei.add(fuShu); } } // 开始匹配 if (piPei.size() > 0) { // 100 条的更新 ListUtils.partition 用来拆分 list size 是拆分的条数 List> fenDuan = ListUtils.partition(piPei, 100); for (List list : fenDuan) { dao.yiZhuTuiFeiPiPei(inpatientNo, admissTimes, list); } log.info("医嘱退费匹配 ==》 操作人:{},住院号:{},住院次数:{}", TokenUtil.getTokenUserId(), inpatientNo, admissTimes); return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, String.format("医嘱退费匹配,共有【%d】条,匹配成功【%d】条", getYiZhuFeiYongFuShu.size(), piPei.size())); } else { return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST, "该患者没有可以匹配的医嘱退费"); } } public ResultVo shanChuMuBan(String patterName, String opIdCode) { log.info("删除项目模板 ==》操作人:{},模板名称:{}", TokenUtil.getTokenUserId(), patterName); dao.delMuBan(patterName, opIdCode); return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "删除成功"); } }