123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320 |
- 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;
- /**
- * <p>
- * 描述: 项目录入
- * </p>
- *
- * @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<List<ZyDetailCharge>> 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<ZyDetailCharge> list = dao.getHuanZheFeiYong(param.getInpatientNo(), param.getAdmissTimes(), param.getChargeCode(), infantFlag,
- param.getStartTime(), param.getOrderNo());
- Map<Integer, Integer> 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<List<GetDropdownBox>> getChargeCode(String pyCode) {
- return ResultVoUtil.success(dao.getChargeCode(StringUtil.isContainChinese(pyCode)));
- }
- /**
- * @param param 需要生成退费 的数据
- * @return 返回
- */
- @Transactional(rollbackFor = Exception.class)
- public ResultVo<String> 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<ZyDetailCharge> 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<Integer> yongHuJueSe = dao.huoQuJueSe(TokenUtil.getTokenUserId());
- //获取到这个人是否属于这个科室
- List<String> zhiXinKeShi = dao.chaXunZhiZXinKeShi(param.getDeptCode());
- // 获取原来的数据
- List<ZyDetailCharge> 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<ZyDetailCharge> 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<List<ZyDetailCharge>> 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<List<ZyDetailCharge>> getMuBan(String deptCode) {
- return ResultVoUtil.success(dao.getMuBan(deptCode));
- }
- /**
- * 获取模板的具体信息
- *
- * @param patternName 模板名称
- * @param opIdCode 存模板的人
- * @return 返回具体的模板
- */
- public ResultVo<List<ZyDetailCharge>> getMuBanXinXi(String patternName, String opIdCode) {
- return ResultVoUtil.success(dao.getMuBanXinXi(patternName, opIdCode));
- }
- /**
- * 通过拼音码 来搜索项目
- *
- * @param pyCode 拼音码
- * @return 返回项目
- */
- public ResultVo<List<ZyDetailCharge>> queryXiangMu(String pyCode) {
- return ResultVoUtil.success(dao.queryXiangMu(pyCode.toUpperCase() + "%"));
- }
- /**
- * 这个项目录入
- *
- * @param param 参数
- * @return 返回提示语句
- */
- @Transactional(rollbackFor = Exception.class)
- public ResultVo<String> 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<String> 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<String> yiZhuTuiFeiPiPei(String inpatientNo, Integer admissTimes) {
- // 获取正的医嘱费用
- List<ZyDetailCharge> getYiZhuFeiYongZhenShu = dao.getYiZhuFeiYong(inpatientNo, admissTimes, ">");
- // 获取负的医嘱费用
- List<ZyDetailCharge> getYiZhuFeiYongFuShu = dao.getYiZhuFeiYong(inpatientNo, admissTimes, "<");
- // 需要保存需要匹配的一些流水数据
- List<ZyDetailCharge> piPei = new ArrayList<>();
- // 保存正数的数据用 map 来匹配
- Map<String, ZyDetailCharge> 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<List<ZyDetailCharge>> fenDuan = ListUtils.partition(piPei, 100);
- for (List<ZyDetailCharge> 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<String> shanChuMuBan(String patterName, String opIdCode) {
- log.info("删除项目模板 ==》操作人:{},模板名称:{}", TokenUtil.getTokenUserId(), patterName);
- dao.delMuBan(patterName, opIdCode);
- return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "删除成功");
- }
- }
|