package thyyxxk.webserver.service.yibao;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.ListUtils;
import org.springframework.beans.BeanUtils;
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.XiangMuLuRuDao;
import thyyxxk.webserver.entity.ResultVo;
import thyyxxk.webserver.entity.datamodify.GetDropdownBox;
import thyyxxk.webserver.entity.datamodify.ZyDetailCharge;
import thyyxxk.webserver.entity.yibao.ZyActpatient;
import thyyxxk.webserver.service.PublicServer;
import thyyxxk.webserver.utils.*;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
*
* 描述: 项目录入
*
*
* @author xc
* @date 2021-08-02 10:37
*/
@Service
@Slf4j
public class XiangMuLuRuService {
private final XiangMuLuRuDao dao;
private final PublicServer publicServer;
@Autowired
public XiangMuLuRuService(XiangMuLuRuDao dao, PublicServer publicServer) {
this.dao = dao;
this.publicServer = publicServer;
}
/**
* 获取患者费用
* 费用 类型 1 - 医嘱 2 - 项目费用 3 - 医技 4 - 全部 5 -药品费用
*
* @param param 查询条件
* @return 返回患者费用
*/
public ResultVo> getHuanZheFeiYong(ZyDetailCharge param) {
if (StringUtil.isBlank(param.getInpatientNo()) || param.getAdmissTimes() == null) {
return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "住院号或住院次数为空
๑乛◡乛๑");
}
Integer ledgerSn = publicServer.getLedgerSn(param.getInpatientNo(), param.getAdmissTimes());
log.info("查询患者费用==》住院号{},住院次数:{},项目名称:{},费用类型:{},科室:{},当前页:{},页大小:{},退费:{},总数:{},账页号:{}", param.getInpatientNo(), param.getAdmissTimes(), param.getChargeCode(), param.getOrderNo(), param.getDept(), param.getCurrentPage(), param.getPageSize(), param.getTuiFeiFlag(), param.getTotal(), ledgerSn);
int infantFlag = 0;
// 如果是婴儿的话那么就需要截取 字符串了 在通过婴儿标识来判断
if (param.getInpatientNo().contains("$")) {
param.setInpatientNo(param.getInpatientNo().split("\\$")[0]);
infantFlag = 1;
}
if (param.getTuiFeiFlag() == null) {
param.setTuiFeiFlag(2);
}
Page page = new Page<>();
if (param.getFeiYongLeiXingCode() == 0) {
if (param.getTotal() == 0) {
page.setTotal(dao.huanZheFeiYongToatal(param.getInpatientNo(), param.getAdmissTimes(), ledgerSn, param.getChargeCode(), infantFlag, param.getStartTime(), param.getEndTime(), param.getOrderNo(), param.getDept(), param.getTuiFeiFlag()));
}
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()));
} else {
if (param.getTotal() == 0) {
page.setTotal(dao.huanZheYaoPinFeiYongTotal(param.getInpatientNo(), param.getAdmissTimes(), ledgerSn, param.getChargeCode(), infantFlag, param.getStartTime(), param.getEndTime(), param.getOrderNo(), param.getDept(), param.getTuiFeiFlag()));
}
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()));
}
if (ListUtil.isBlank(page.getRecords())) {
return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST, "没有查询到符合费用。");
}
return ResultVoUtil.success(page);
}
/**
* 搜索项目信息
*
* @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, Boolean panDuanYaoPing) {
List yongHuJueSe = dao.huoQuJueSe(TokenUtil.getTokenUserId());
if (!yongHuJueSe.contains(36) && !yongHuJueSe.contains(1)) {
return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "您没有权限退费。");
}
if (param.getList() == null || param.getList().isEmpty()) {
return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "请先选择需要退费的数据,一次性退费不得超过100条");
} else if (param.getList().size() > 100) {
return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "项目退费一次性大于100条数据");
}
if (StringUtil.isBlank(param.getInpatientNo()) || param.getAdmissTimes() == null || param.getList().size() == 0) {
return ResultVoUtil.fail(ExceptionEnum.NULL_POINTER, "患者信息不全");
}
if (dao.getHuanZheSFZaiYuan(param.getInpatientNo(), param.getAdmissTimes()) == 0) {
return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "该患者已出院");
}
int infantFlag = 0;
// 判断是否为婴儿
if (param.getInpatientNo().contains("$")) {
param.setInpatientNo(param.getInpatientNo().split("\\$")[0]);
infantFlag = 1;
}
Integer ledgerSn = publicServer.getLedgerSn(param.getInpatientNo(), param.getAdmissTimes());
// 判断数据是否为 退费数据
List chaKanSFtuiFei = dao.chaKanSFYiJingTuiFeiLe(param.getInpatientNo(), param.getAdmissTimes(), ledgerSn, param.getList());
for (ZyDetailCharge charge : chaKanSFtuiFei) {
return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, String.format("流水号为:【%s】已退费,请勿重复退费。", charge.getOriDetailSn()));
}
if (dao.getHuanZheSFJieSuan(param.getInpatientNo(), param.getAdmissTimes()) == null || dao.getHuanZheSFJieSuan(param.getInpatientNo(), param.getAdmissTimes()) != 0) {
return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "该患者已经结算了");
}
// 获取原来的数据
List yuanTuiFeiList = dao.huoQuJuTiFeiYong(param.getInpatientNo(), param.getAdmissTimes(), ledgerSn, param.getList());
// 获取患者的总费用
BigDecimal sum = new BigDecimal(0);
// 退费的list
// 获取最大值
Integer maxDetailSn = publicServer.getMaxDetailSn(param.getInpatientNo(), param.getAdmissTimes());
List yaoPingDan = new ArrayList<>();
List genXingZhenShuTuiFeiLiuShui = new ArrayList<>();
List tuiFeiList = new ArrayList<>();
// 获取到用户角色 管理员角色可以无视
List zhiXinKeShi = dao.chaXunZhiZXinKeShi(param.getDeptCode());
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 (pojo.getChargeCode().startsWith("BILL")) {
yaoPingDan.add(pojo);
}
// 在这里判断执行科室
ResultVo LOGICAL_ERROR = getStringResultVo(yongHuJueSe, zhiXinKeShi, param, pojo, panDuanYaoPing);
if (LOGICAL_ERROR != null) {
return LOGICAL_ERROR;
}
// 数据库有个 触发器 如果带了医嘱号且有篆刻那么这里就需要改成 0
if (BigUtils.bigDaYu(pojo.getOrderNo(), 10)) {
pojo.setOrderNo(new BigDecimal(0));
}
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);
genXingZhenShuTuiFeiLiuShui.add(pojo.getOriDetailSn());
}
// 执行退费的操作 20 条的退费
if (tuiFeiList.isEmpty()) {
return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "查询不到患者原数据,请联系管理员。");
} else {
log.info("操作项目退费 ==》 操作人:{},数据:{}", TokenUtil.getTokenUserId(), JSON.toJSONString(tuiFeiList));
List> fenGe = ListUtils.partition(tuiFeiList, 20);
if (ListUtil.notBlank(yaoPingDan)) {
dao.shenQingYaoPing(param, yaoPingDan, infantFlag, publicServer.getLedgerSn(param.getInpatientNo(), param.getAdmissTimes()), TokenUtil.getTokenUserId());
}
fenGe.forEach(dao::xiangMuTuiFei);
dao.genXinZhenShuTuiFeiLiuShui(param.getInpatientNo(), param.getAdmissTimes(), publicServer.getLedgerSn(param.getInpatientNo(), param.getAdmissTimes()), genXingZhenShuTuiFeiLiuShui);
return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "项目退费操作成功。乁( ˙ ω˙乁)");
}
}
private ResultVo getStringResultVo(List yongHuJueSe, List zhiXinKeShi, ZyDetailCharge xuYaoTuiDeShuJu, ZyDetailCharge piPeiDeShuJu, Boolean panDuanYaoPin) {
// 获取到用户角色 管理员角色可以无视
if (!yongHuJueSe.contains(1) && !yongHuJueSe.contains(8)) {
// 科室开头 是 8 就不是医技科室 只有医技科室可以退药品
if (xuYaoTuiDeShuJu.getDeptCode().startsWith("8")) {
//获取到这个人是否属于这个科室
if (!zhiXinKeShi.contains(piPeiDeShuJu.getExecUnit())) {
return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, String.format("流水号为【%s】,请对应的执行科室进行退费。", piPeiDeShuJu.getDetailSn()));
}
// 护士是不可以退药品的
if (panDuanYaoPin) {
if (piPeiDeShuJu.getChargeCode().startsWith("BILL")) {
return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, String.format("流水号为【%s】,包含药品费用,无法退费。", piPeiDeShuJu.getDetailSn()));
}
}
} else if (panDuanYaoPin) {
if (!xuYaoTuiDeShuJu.getDeptCode().equals(piPeiDeShuJu.getExecUnit())) {
return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, String.format("流水号为【%s】,请对应的执行科室进行退费。", piPeiDeShuJu.getDetailSn()));
} else if ((BigUtils.bigDaYu(piPeiDeShuJu.getOrderNo(), 100) || BigUtils.bigXiaoYu(piPeiDeShuJu.getOrderNo(), 0)) && "01".equals(piPeiDeShuJu.getSerial())) {
return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, String.format("流水号为【%s】,只能退本科室录入的药品。", piPeiDeShuJu.getDetailSn()));
}
}
}
return null;
}
/**
* 获取模板
*
* @param deptCode 根据科室搜索
* @return 返回模板
*/
public ResultVo> getMuBan(String deptCode, long currentPage, long pageSize, long total) {
IPage page = new Page<>(currentPage, pageSize, total == 0);
QueryWrapper> qw = new QueryWrapper<>();
qw.ne("isnull(pattern_name,'')", "''");
if (publicServer.noNeedRule()) {
qw.eq("op_dept", deptCode);
}
dao.getMuBan(page, qw);
return ResultVoUtil.success(page);
}
/**
* 获取模板的具体信息
*
* @param patternName 模板名称
* @param opIdCode 存模板的人
* @return 返回具体的模板
*/
public ResultVo> getMuBanXinXi(String patternName, String opIdCode) {
return ResultVoUtil.success(dao.getMuBanXinXi(patternName, opIdCode));
}
/**
* 获取科室
*
* @return 返回科室信息
*/
public ResultVo> getDept() {
return ResultVoUtil.success(dao.getDpet());
}
/**
* 获取病区
*
* @return 返回科室信息
*/
public ResultVo> getWard() {
return ResultVoUtil.success(dao.getWard());
}
/**
* 通过拼音码 来搜索项目
*
* @param pyCode 拼音码
* @param xiangMuHuoYaoPinFlag 判断是查询项目还是药品 0 - 项目 1- 药品
* @return 返回项目
*/
public ResultVo> queryXiangMu(String pyCode, Integer xiangMuHuoYaoPinFlag) {
if (xiangMuHuoYaoPinFlag == 0) {
return ResultVoUtil.success(dao.queryXiangMu("%" + pyCode.toUpperCase() + "%"));
}
return ResultVoUtil.success(dao.queryYaoPin("%" + 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条");
}
StringBuilder errorStr = new StringBuilder();
if (StringUtil.isBlank(param.getInpatientNo()) || param.getAdmissTimes() == null) {
errorStr.append("住院号和住院次数为空
");
}
if (param.getList().size() == 0) {
errorStr.append("没有要录入的项目
");
}
if (StringUtil.isBlank(param.getWard())) {
errorStr.append("病区为空
");
}
if (StringUtil.isBlank(param.getDept())) {
errorStr.append("申请科室为空
");
}
if (StringUtil.isBlank(param.getZySerialNo())) {
errorStr.append("住院流水号为空
");
}
if (dao.getHuanZheSFZaiYuan(param.getInpatientNo(), param.getAdmissTimes()) == 0) {
errorStr.append("没有患者的在院信息
");
}
if (errorStr.length() > 0) {
return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, errorStr.toString());
}
// 收费项目的编码
List shiFouTingYongXiangMu = new ArrayList<>();
param.getList().forEach(item -> {
shiFouTingYongXiangMu.add(item.getChargeCodeMx());
});
List yiTingYong = dao.chaXunFeiYongShiFouTingYong(shiFouTingYongXiangMu);
// 药品没有库存这个限制先放开
// List meiYouKuCun = dao.kuCun(shiFouTingYongXiangMu);
// if (ListUtil.notBlank(meiYouKuCun)) {
// return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "费用录入错误,药品无库存 【" + JSON.toJSONString(meiYouKuCun) + "】");
// }
if (ListUtil.notBlank(yiTingYong)) {
return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "费用录入错误,包含已停用的项目 【" + JSON.toJSONString(yiTingYong) + "】");
}
// 婴儿 要特殊处理
// 如果带有这个 $ 说明是婴儿
int infantFlag = publicServer.getInfantFlag(param.getInpatientNo());
param.setInpatientNo(publicServer.getInpatientNo(param.getInpatientNo()));
// 获取最大流水号
Integer maxDetailSn = publicServer.getMaxDetailSn(param.getInpatientNo(), param.getAdmissTimes());
// 获取项目的 总费用
BigDecimal sum = new BigDecimal(0);
// 录入人的id
param.setOpIdCode(TokenUtil.getTokenUserId());
List yaoPingShenQingDan = new ArrayList<>();
// 药品
for (ZyDetailCharge zyDetailCharge : param.getList()) {
switch (zyDetailCharge.getBillItemCode()) {
case "001":
zyDetailCharge.setSerial("01");
zyDetailCharge.setChargeCode("BILL01");
break;
case "002":
zyDetailCharge.setSerial("01");
zyDetailCharge.setChargeCode("BILL02");
break;
case "028":
zyDetailCharge.setSerial("01");
zyDetailCharge.setChargeCode("BILL28");
break;
default:
// Serial 00 项目标志 01 药品标志
zyDetailCharge.setSerial("00");
zyDetailCharge.setChargeCode(zyDetailCharge.getChargeCodeMx());
break;
}
if (zyDetailCharge.getChargeAmount() == null || zyDetailCharge.getAmount() == null) {
return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "数量或金额不能为空。");
}
// 判断患者的费用是否存在负数
if (zyDetailCharge.getChargeAmount().signum() == -1 || zyDetailCharge.getAmount().signum() == -1) {
return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "不能录入负数");
}
if (zyDetailCharge.getChargeAmount().compareTo(new BigDecimal(0)) == 0 || zyDetailCharge.getAmount().compareTo(new BigDecimal(0)) == 0) {
return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "录入费用为 0");
}
if (StringUtil.isBlank(zyDetailCharge.getChargeCodeMx())) {
return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "项目编码空值。");
}
if (StringUtil.isBlank(zyDetailCharge.getDeptCode())) {
return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "执行科室为空。");
}
if (zyDetailCharge.getChargeCodeMx() == null) {
zyDetailCharge.setChargeCodeMx(zyDetailCharge.getChargeCode());
}
if (dao.getHuanZheSFJieSuan(param.getInpatientNo(), param.getAdmissTimes()) == null || dao.getHuanZheSFJieSuan(param.getInpatientNo(), param.getAdmissTimes()) != 0) {
return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "该患者已经结算了");
}
// 0 - 住院费用 3 - 门急诊 6 - 医技
if (param.getOrderNo() != null) {
zyDetailCharge.setOrderNo(param.getOrderNo());
} else {
return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "医嘱号为空");
}
sum = sum.add(zyDetailCharge.getChargeAmount().multiply(zyDetailCharge.getAmount()));
// 这里不会保存单价 只会总价
zyDetailCharge.setChargeAmount(zyDetailCharge.getChargeAmount().multiply(zyDetailCharge.getAmount()));
zyDetailCharge.setDetailSn(maxDetailSn += 1);
if ("01".equals(zyDetailCharge.getSerial())) {
ZyDetailCharge shenQing = new ZyDetailCharge();
BeanUtils.copyProperties(zyDetailCharge, shenQing);
shenQing.setChargeFee(zyDetailCharge.getChargeAmount());
shenQing.setChargeAmount((zyDetailCharge.getAmount()));
yaoPingShenQingDan.add(shenQing);
}
}
Integer ledgerSn = publicServer.getLedgerSn(param.getInpatientNo(), param.getAdmissTimes());
// 在此处 插入费用
dao.chaRuFeiYong(param, param.getList(), infantFlag, ledgerSn);
if (ListUtil.notBlank(yaoPingShenQingDan)) {
dao.shenQingYaoPing(param, yaoPingShenQingDan, infantFlag, ledgerSn, TokenUtil.getTokenUserId());
}
log.info("项目录入费用上传 ==》 操作人:{},数据:{}", param.getOpIdCode(), JSON.toJSONString(param));
return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "费用上传成功。<( ̄︶ ̄)>");
}
/**
* 上传以及修改项目录入模板
*
* @param zyDetailCharge 模板的一些数据
* @return 返回成功提示
*/
@Transactional(rollbackFor = Exception.class)
public ResultVo shangChuanMuBan(ZyDetailCharge zyDetailCharge) {
if (dao.chaKanMuBanMingChengSFcunZi(zyDetailCharge.getName(), TokenUtil.getTokenUserId()) > 0) {
return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "模板名称重复,๐·°(৹˃̵﹏˂̵৹)°·๐");
}
zyDetailCharge.setOpIdCode(TokenUtil.getTokenUserId());
for (ZyDetailCharge detailCharge : zyDetailCharge.getList()) {
if (StringUtil.notBlank(zyDetailCharge.getBillItemCode())) {
if ("001".equals(detailCharge.getBillItemCode()) || "002".equals(detailCharge.getBillItemCode())) {
detailCharge.setSerial("01");
detailCharge.setGroupNo("73");
} else if ("028".equals(zyDetailCharge.getBillItemCode())) {
zyDetailCharge.setSerial("01");
zyDetailCharge.setChargeCode("BILL28");
} else {
// Serial 00 项目标志 01 药品标志
detailCharge.setSerial("00");
}
}
}
// 在创建新的模板之前 需要先删除 原来的
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 返回是否匹配成功
*/
@Transactional(rollbackFor = Exception.class)
public ResultVo yiZhuTuiFeiPiPei(String inpatientNo, Integer admissTimes, String deptCode) {
if (StringUtil.isBlank(inpatientNo) || admissTimes == null || StringUtil.isBlank(deptCode)) {
return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "患者信息不全。");
}
int infantFlag = publicServer.getInfantFlag(inpatientNo);
inpatientNo = publicServer.getInpatientNo(inpatientNo);
Integer ledgerSn = publicServer.getLedgerSn(inpatientNo, admissTimes);
List keShiLeiBiao = publicServer.huoQuBingFangDeKeShi(deptCode);
// 获取正的医嘱费用
List getYiZhuFeiYongZhenShu = dao.getYiZhuFeiYong(inpatientNo, admissTimes, ledgerSn, ">", infantFlag, keShiLeiBiao);
// 获取负的医嘱费用
List getYiZhuFeiYongFuShu = dao.getYiZhuFeiYong(inpatientNo, admissTimes, ledgerSn, "<", infantFlag, keShiLeiBiao);
// 获取负数的退费数据 主要是用来判断 这一条正的是否退费了。
List tuiFeiList = dao.tuiFeiList(inpatientNo, admissTimes, infantFlag);
if (!tuiFeiList.isEmpty()) {
Map map = new HashMap<>();
for (ZyDetailCharge zyDetailCharge : tuiFeiList) {
map.put(zyDetailCharge.getOriDetailSn(), zyDetailCharge.getDetailSn());
}
getYiZhuFeiYongZhenShu.forEach(item -> {
if (map.containsKey(item.getDetailSn())) {
item.setTuiFeiFlag(1);
}
});
}
// 需要保存需要匹配的一些流水数据
List piPei = new ArrayList<>();
// 此处是需要二次匹配的 list
List erCiPiPei = new ArrayList<>();
// 用map 来保存正数的信息,但是有可能匹配的条件中map 的 key会一致 所以在这里使用 java8 的新特性 stream 流来进行分组 这样就不会因为key 一样导致数据被覆盖了
// 第一次 匹配 根据 医嘱号 收费时间 项目编码 数量 账页号
Map> zhenShuMap = getYiZhuFeiYongZhenShu.stream().collect(Collectors.groupingBy(item -> item.getOrderNo() + DateUtil.formatDatetime(item.getChargeDate()) + item.getChargeCodeMx() + item.getChargeAmount() + item.getChargeFee() + item.getLedgerSn()));
// 用负数拼接的 key 去查找
for (ZyDetailCharge fuShu : getYiZhuFeiYongFuShu) {
String key = fuShu.getOrderNo() + DateUtil.formatDatetime(fuShu.getChargeDate()) + fuShu.getChargeCodeMx() + fuShu.getChargeAmount().negate() + fuShu.getChargeFee().negate() + fuShu.getLedgerSn();
if (zhenShuMap.containsKey(key)) {
for (ZyDetailCharge zyDetailCharge : zhenShuMap.get(key)) {
if (zyDetailCharge.getTuiFeiFlag() == null && zyDetailCharge.getOriDetailSn() == null) {
fuShu.setOriDetailSn(zyDetailCharge.getDetailSn());
zyDetailCharge.setTuiFeiFlag(1);
piPei.add(fuShu);
log.info("第一次匹配==》流水:{},匹配流水:{},", fuShu.getDetailSn(), fuShu.getOriDetailSn());
break;
}
}
} else {
// 这个是需要进行二次匹配的
erCiPiPei.add(fuShu);
}
}
// 下面是二次匹配
if (erCiPiPei.size() > 0) {
// 二次匹配 条件为 执行科室 项目编码 数量 账页号
Map> erCiPiPeiZhenShu = getYiZhuFeiYongZhenShu.stream().collect(Collectors.groupingBy(item -> item.getExecUnit() + item.getChargeCodeMx() + item.getChargeAmount() + item.getChargeFee() + item.getLedgerSn()));
// 开始二次匹配
for (ZyDetailCharge zyDetailCharge : erCiPiPei) {
String key = zyDetailCharge.getExecUnit() + zyDetailCharge.getChargeCodeMx() + zyDetailCharge.getChargeAmount().negate() + zyDetailCharge.getChargeFee().negate() + zyDetailCharge.getLedgerSn();
if (erCiPiPeiZhenShu.containsKey(key)) {
for (ZyDetailCharge detailCharge : erCiPiPeiZhenShu.get(key)) {
if (detailCharge.getTuiFeiFlag() == null && detailCharge.getOriDetailSn() == null) {
zyDetailCharge.setOriDetailSn(detailCharge.getDetailSn());
detailCharge.setTuiFeiFlag(1);
piPei.add(zyDetailCharge);
log.info("第二次匹配==》流水:{},匹配流水:{}", zyDetailCharge.getDetailSn(), zyDetailCharge.getOriDetailSn());
break;
}
}
}
}
}
// 开始匹配
if (piPei.size() > 0) {
// 100 条的更新 ListUtils.partition 用来拆分 list size 是拆分的条数
List> fenDuan = ListUtils.partition(piPei, 100);
for (List list : fenDuan) {
dao.yiZhuTuiFeiPiPei(inpatientNo, admissTimes, list, infantFlag);
}
publicServer.genXingYuanLiuShuiBiaoZhi(inpatientNo, admissTimes, ledgerSn);
log.info("医嘱退费匹配 ==》 操作人:{},住院号:{},住院次数:{}", TokenUtil.getTokenUserId(), inpatientNo, admissTimes);
return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, String.format("匹配成功共:{%d}条,匹配成功:{%s}条", getYiZhuFeiYongFuShu.size(), piPei.size()));
}
publicServer.genXingYuanLiuShuiBiaoZhi(inpatientNo, admissTimes, ledgerSn);
return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST, String.format("该患者有【%d】条,未能匹配 |д・)っ", getYiZhuFeiYongFuShu.size()));
}
/**
* 此处删除模板 这个模板是录入住院费用的 模板
*
* @param patterName 模板名称
* @param opIdCode 创建模板人的姓名
* @return 返回提示
*/
public ResultVo shanChuMuBan(String patterName, String opIdCode) {
log.info("删除项目模板 ==》操作人:{},模板名称:{}", TokenUtil.getTokenUserId(), patterName);
dao.delMuBan(patterName, opIdCode);
return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "删除成功,o(^▽^)o");
}
/**
* 生成拼音和五笔码
*
* @param inputStr 中文
* @return 返回编码
*/
public ResultVo getPyCode(String inputStr) {
ZyDetailCharge zyDetailCharge = new ZyDetailCharge();
zyDetailCharge.setPyCode(PingYinUtils.pyShouZiMuDaXie(inputStr));
zyDetailCharge.setWbCode(PingYinUtils.getWBCode(inputStr));
return ResultVoUtil.success(zyDetailCharge);
}
/**
* 根据对应的病区来获取科室
*
* @param ward 科室编码
* @return 返回对应的
*/
public ResultVo> getBingQuDuiYingKeShi(String ward) {
return ResultVoUtil.success(dao.getBingQuDuiYingKeShi(ward));
}
@Transactional(rollbackFor = Exception.class)
public ResultVo cheXiaoTuiFei(String inpatientNo, Integer admissTimes, Integer ledger, Integer detailSn) {
if (StringUtil.isBlank(inpatientNo) || admissTimes == null || ledger == null || detailSn == null) {
return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "患者信息不全。");
}
inpatientNo = publicServer.getInpatientNo(inpatientNo);
ZyDetailCharge zyDetailCharge = dao.beiTuiFeiYongXinXi(inpatientNo, admissTimes, ledger, detailSn);
if (zyDetailCharge == null) {
return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "未查询到对应信息,可能该费用可能已经被撤销了或被正负相抵了。");
}
if (!"0".equals(zyDetailCharge.getTransFlagYb())) {
return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "费用已经被上传了,无法撤销。");
}
if (zyDetailCharge.getOriDetailSn() != null && zyDetailCharge.getOriDetailSn() == -1) {
return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "被退数据无法删除。");
}
dao.cheXiaoFeiYong(inpatientNo, admissTimes, ledger, detailSn);
dao.cheXiaoHouHuanYuanZhenShuJu(inpatientNo, admissTimes, ledger, zyDetailCharge.getOriDetailSn());
log.info("撤销退费 ==> 操作人:{},住院号:{},住院次数:{},账页号:{},流水号:{},原流水号:{}", TokenUtil.getTokenUserId(), inpatientNo, admissTimes, ledger, detailSn, zyDetailCharge.getOriDetailSn());
return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "撤销成功,请刷新数据。");
}
@Transactional(rollbackFor = Exception.class)
public ResultVo weiGuiFeiYongFenXi(String inpatientNo, String execUnit) {
ZyActpatient patient = publicServer.huoQuHuanZheXinXi(inpatientNo);
List keShi = publicServer.huoQuBingFangDeKeShi(execUnit);
publicServer.genXingYuanLiuShuiBiaoZhi(patient.getInpatientNo(), patient.getAdmissTimes(), patient.getLedgerSn());
// 药品 分大包装和小包装 可能大包装 匹配了 小包装没有 匹配 所以这里编码同步 一下
List yaoPingBianMaTongBu = dao.weiGuiYaoPinInt(patient.getInpatientNo(), patient.getAdmissTimes(), patient.getLedgerSn(), patient.getInfantFlag());
// 这里退药 医嘱 有可能会没有携带 执行科室
List huoQuYaoPingZhongKeShiWeiKongDe = dao.huoQuYaoPingZhongKeShiWeiKongDe(inpatientNo, patient.getAdmissTimes(), patient.getLedgerSn());
if (!huoQuYaoPingZhongKeShiWeiKongDe.isEmpty()) {
dao.yiZhuTuiFeiGenXingZhiXingKeShi(inpatientNo, patient.getAdmissTimes(), patient.getLedgerSn(), huoQuYaoPingZhongKeShiWeiKongDe);
}
if (yaoPingBianMaTongBu.size() > 0) {
dao.genXinYaoPingPiPeiXinXi(yaoPingBianMaTongBu);
}
patient.setWeiPiPei(new ArrayList<>());
patient.setWeiXieDaiYuanLiuShui(new ArrayList<>());
if ("al".equals(patient.getResponceType())) {
patient.getWeiPiPei().addAll(dao.gongShangWeiPiPei(patient.getInpatientNo(), patient.getAdmissTimes(), patient.getLedgerSn(), patient.getInfantFlag()));
} else {
patient.getWeiPiPei().addAll(dao.weiGuiYaoPin(patient.getInpatientNo(), patient.getAdmissTimes(), patient.getLedgerSn(), patient.getInfantFlag()));
patient.getWeiPiPei().addAll(dao.weiGuiXiangMu(patient.getInpatientNo(), patient.getAdmissTimes(), patient.getLedgerSn(), patient.getInfantFlag()));
}
patient.getWeiXieDaiYuanLiuShui().addAll(dao.weiXieDaiYuanLiuShuiXiangMu(patient.getInpatientNo(), patient.getAdmissTimes(), patient.getLedgerSn(), patient.getInfantFlag(), keShi, patient.getChuYuanYiZhu()));
patient.getWeiXieDaiYuanLiuShui().addAll(dao.weiXieDaiYuanLiuShuiYaoPing(patient.getInpatientNo(), patient.getAdmissTimes(), patient.getLedgerSn(), patient.getInfantFlag(), keShi, patient.getChuYuanYiZhu()));
return ResultVoUtil.success(patient);
}
public ResultVo> huoQuZhenShuKePiPei(String inpatientNo, Integer admissTimes, Integer ledgerSn, String chargeCodeMx, String execUnit, String orderNo, String startTime, String endTime, String riQiPaiXu) {
execUnit = StringUtil.isBlank(execUnit) ? null : execUnit;
List zhenShuFeiYong = dao.weiGuiZhenShuPiPei(publicServer.getInpatientNo(inpatientNo), admissTimes, ledgerSn, publicServer.getInfantFlag(inpatientNo), chargeCodeMx, execUnit, orderNo, startTime, endTime, riQiPaiXu);
if (ListUtil.isBlank(zhenShuFeiYong)) {
zhenShuFeiYong.addAll(dao.weiGuiZhenShuPiPei(publicServer.getInpatientNo(inpatientNo), admissTimes, ledgerSn, publicServer.getInfantFlag(inpatientNo), chargeCodeMx, null, orderNo, startTime, endTime, riQiPaiXu));
}
if (ListUtil.isBlank(zhenShuFeiYong)) {
return ResultVoUtil.fail(ExceptionEnum.NO_DATA_EXIST, "没有查询到该负数费用的对应正数。", dao.genJuBianMaChaZhaoZhenShuFeiYong(publicServer.getInpatientNo(inpatientNo), admissTimes, ledgerSn, publicServer.getInfantFlag(inpatientNo), chargeCodeMx, startTime, endTime, riQiPaiXu));
}
List yuEr = dao.tuiFeiYuEr1(publicServer.getInpatientNo(inpatientNo), admissTimes, ledgerSn, chargeCodeMx, execUnit);
Map yuErPiPei = new HashMap<>();
for (ZyDetailCharge item : yuEr) {
String key = item.getInpatientNo() + item.getAdmissTimes() + item.getDetailSn() + item.getChargeCodeMx();
yuErPiPei.put(key, item);
}
// TODO: 2022/1/11 这里需要优化 把计算余额的放到程序里面来计算
for (int i = 0, len = zhenShuFeiYong.size(); i < len; i++) {
ZyDetailCharge zy = zhenShuFeiYong.get(i);
String key = zy.getInpatientNo() + zy.getAdmissTimes() + zy.getDetailSn() + zy.getChargeCodeMx();
if (yuErPiPei.containsKey(key)) {
if (BigUtils.dengYu(yuErPiPei.get(key).getYiTuiFei(), 0)) {
zhenShuFeiYong.remove(i);
len--;
i--;
} else {
// 这里是 set 退费的余额
zy.setYiTuiFei(yuErPiPei.get(key).getYiTuiFei());
}
}
}
return ResultVoUtil.success(zhenShuFeiYong);
}
@Transactional(rollbackFor = Exception.class)
public ResultVo caiFenPiPei(ZyDetailCharge zyDetailCharge) {
String inpatientNo = publicServer.getInpatientNo(zyDetailCharge.getInpatientNo());
Integer infantFlag = publicServer.getInfantFlag(zyDetailCharge.getInpatientNo());
if (ListUtil.isBlank(zyDetailCharge.getList())) {
return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "请选择数据。");
}
int[] detailSnList = new int[zyDetailCharge.getList().size()];
for (int i = 0; i < zyDetailCharge.getList().size(); i++) {
detailSnList[i] = zyDetailCharge.getList().get(i).getDetailSn();
}
ZyDetailCharge zy = dao.piPeiXinXiFuShu(inpatientNo, zyDetailCharge.getAdmissTimes(), zyDetailCharge.getLedgerSn(), infantFlag, zyDetailCharge.getDetailSn());
if (zy == null) {
return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "未找到负数费用信息,可能已经被删除了,请刷新页面重试。");
} else if (zy.getOriDetailSn() != null || "2".equals(zy.getTransFlagYb())) {
return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "该负数费用已被正负相抵。");
}
List zhenShuShuJu = dao.piPeiXinXi(inpatientNo, zyDetailCharge.getAdmissTimes(), zyDetailCharge.getLedgerSn(), infantFlag, detailSnList);
Map tuiFeiYuErPiPei = dao.tuiFeiYuEr2(inpatientNo, zyDetailCharge.getAdmissTimes(), zyDetailCharge.getLedgerSn(), infantFlag, detailSnList).stream().collect(Collectors.toMap(ZyDetailCharge::getOriDetailSn, a -> a, (k1, k2) -> k1));
BigDecimal chargeFeeSum = new BigDecimal(0);
BigDecimal chargeAmountSum = new BigDecimal(0);
List yongHuJueSe = dao.huoQuJueSe(TokenUtil.getTokenUserId());
List zhiXinKeShi = dao.chaXunZhiZXinKeShi(zyDetailCharge.getDeptCode());
for (ZyDetailCharge detailCharge : zhenShuShuJu) {
if (!BigUtils.dengYu(detailCharge.getOrderNo(), zyDetailCharge.getOrderNo())) {
ResultVo LOGICAL_ERROR = getStringResultVo(yongHuJueSe, zhiXinKeShi, zyDetailCharge, detailCharge, false);
if (LOGICAL_ERROR != null) {
return LOGICAL_ERROR;
}
}
if ("2".equals(detailCharge.getTransFlagYb())) {
return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, String.format("流水号为:{%d},已被正负抵消。", detailCharge.getDetailSn()));
}
if (tuiFeiYuErPiPei.containsKey(detailCharge.getDetailSn())) {
detailCharge.setChargeFee(detailCharge.getChargeFee().add(tuiFeiYuErPiPei.get(detailCharge.getDetailSn()).getChargeFee()));
}
chargeFeeSum = chargeFeeSum.add(detailCharge.getChargeFee());
chargeAmountSum = chargeAmountSum.add(detailCharge.getChargeAmount());
}
if (zhenShuShuJu.size() == 1) {
if (BigUtils.bigDaYu(chargeFeeSum, zy.getChargeFee().negate()) || BigUtils.dengYu(chargeFeeSum, zy.getChargeFee().negate())) {
dao.zhiYouYiGeJiuGenXingFuShuLiuShui(zyDetailCharge.getInpatientNo(), zyDetailCharge.getAdmissTimes(), zyDetailCharge.getLedgerSn(), zyDetailCharge.getDetailSn(), zhenShuShuJu.get(0).getDetailSn());
publicServer.genXingYuanLiuShuiBiaoZhi(inpatientNo, zyDetailCharge.getAdmissTimes(), zyDetailCharge.getLedgerSn());
return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_NOTIFICATION, "费用匹配成功。");
}
return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, String.format("负数费用:{%.2f},匹配费用:{%.2f} \n 负数数量:{%.2f},匹配数量:{%.2f}", zy.getChargeFee().negate(), chargeFeeSum, zy.getChargeAmount().negate(), chargeAmountSum));
} else {
return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "每次只能匹配一条。");
}
}
public void exportExcel(HttpServletResponse response, ZyDetailCharge param) {
log.info("导出患者费用数据:{}", JSONObject.toJSONStringWithDateFormat(param, DateUtil.DEFAULT_PATTERN));
param.setPageSize(param.getTotal());
param.setCurrentPage(1);
List list = getHuanZheFeiYong(param).getData().getRecords();
String[] title = {"流水号", "医嘱号", "录入日期", "项目编码", "项目名称", "药品名称", "执行时间", "执行科室", "申请科室", "金额", "数量", "状态", "录入人", "账单码"};
String[][] content = new String[list.size()][];
for (int i = 0; i < list.size(); i++) {
content[i] = new String[title.length];
ZyDetailCharge pojo = list.get(i);
content[i][0] = String.valueOf(pojo.getDetailSn());
content[i][1] = String.valueOf(pojo.getOrderNo());
content[i][2] = DateUtil.formatDatetime(pojo.getChargeDate());
content[i][3] = pojo.getChargeCodeMx();
content[i][4] = pojo.getChargeName();
content[i][5] = pojo.getDrugname();
content[i][6] = DateUtil.formatDatetime(pojo.getGenTime());
content[i][7] = pojo.getExecDept();
content[i][8] = pojo.getDeptCode();
content[i][9] = pojo.getChargeFee().toString();
content[i][10] = pojo.getChargeAmount().toString();
content[i][11] = "1".equals(pojo.getChargeStatus()) ? "录入" : "2".equals(pojo.getChargeStatus()) ? "上账" : "结算";
content[i][12] = pojo.getOpName();
content[i][13] = pojo.getBillItemName();
}
ExcelUtil.exportExcel(response, title, content);
}
}