package thyyxxk.webserver.service.yibao; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import thyyxxk.webserver.config.exception.BizException; import thyyxxk.webserver.config.exception.ExceptionEnum; import thyyxxk.webserver.dao_his.yibao.DismissDao; import thyyxxk.webserver.pojo.ResultVo; import thyyxxk.webserver.pojo.dictionary.PureCodeName; import thyyxxk.webserver.pojo.yibao.dismiss.ActOrderDetail; import thyyxxk.webserver.pojo.yibao.dismiss.ActOrderGroup; import thyyxxk.webserver.pojo.yibao.dismiss.ReceiptFeePojo; import thyyxxk.webserver.pojo.yibao.dismiss.YbSettleFeePojo; import thyyxxk.webserver.pojo.yibao.patient.OverviewPojo; import thyyxxk.webserver.pojo.yibao.patient.PatientPojo; import thyyxxk.webserver.utils.*; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import static thyyxxk.webserver.utils.YibaoHttpUtil.equalizeUpload; import static thyyxxk.webserver.utils.YibaoHttpUtil.httpPost; @Slf4j @Service public class DismissService { private final DismissDao dao; @Autowired public DismissService(DismissDao dao) { this.dao = dao; } public ResultVo> getActOrders(String inpatientNo, Integer admissTimes) { final Integer ledgerSn = dao.getLedgerSn(inpatientNo, admissTimes); if (ledgerSn < 1) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "获取帐页数失败。"); } dao.acceptFeeStepOne(inpatientNo, admissTimes); if(dao.acceptFeeStepTwo(inpatientNo, admissTimes) < 0) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "接收费用失败。"); } if (dao.getOrderList(inpatientNo, admissTimes) < 0) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "查询医嘱失败。"); } List allOrders = dao.getActOrderDetail(); if (allOrders == null) { return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "查询医嘱失败。"); } return analyzeActOrders(allOrders); } private ResultVo> analyzeActOrders(List allOrders) { HashMap temp = new HashMap<>(); for (ActOrderDetail item : allOrders) { String actOrderNo = item.getActOrderNo(); String fee = item.getChargeFee(); if (!temp.containsKey(actOrderNo)) { ActOrderGroup aModel = new ActOrderGroup(actOrderNo, fee, item.getChargeStatus(), item.getCxFlag()); if (aModel.getList() == null) { aModel.setList(new ArrayList<>()); } aModel.getList().add(item); temp.put(actOrderNo, aModel); } else { temp.get(actOrderNo).setFee(DecimalUtil.add(fee, temp.get(actOrderNo).getFee())); temp.get(actOrderNo).getList().add(item); } } List list = new ArrayList<>(); for (HashMap.Entry modelEntry : temp.entrySet()) { list.add(modelEntry.getValue()); } return ResultVoUtil.success(list); } public ResultVo> calculateForDismiss(PatientPojo param) { final String inpatientNo = param.getInpatientNo(); final Integer admissTimes = param.getAdmissTimes(); if (param.getDismissFlag() == 1) { int disActOrderCount = dao.countDisActOrders(inpatientNo, admissTimes); if (disActOrderCount < 1) { ExceptionEnum exception = ExceptionEnum.LOGICAL_ERROR; exception.setMessage("此患者没有出院医嘱,请检查。"); throw new BizException(exception); } if (disActOrderCount > 1) { ExceptionEnum exception = ExceptionEnum.LOGICAL_ERROR; exception.setMessage("此患者的出院医嘱不止一条,请检查。"); throw new BizException(exception); } } if (null == param.getAdmissDate()) { ExceptionEnum exception = ExceptionEnum.LOGICAL_ERROR; exception.setMessage("没有找到入院时间,请重新获取病人信息。"); throw new BizException(exception); } Date actOrderDisDate = getDismissDate(param.getDismissFlag(), inpatientNo, admissTimes, param.getZjdzDatetime()); final int ledgerSn = dao.getLedgerSn(inpatientNo, admissTimes); if (dao.hasUnsettledStepOne(inpatientNo, admissTimes, ledgerSn) < 0) { ExceptionEnum exception = ExceptionEnum.LOGICAL_ERROR; exception.setMessage("获取记账信息失败。"); throw new BizException(exception); } if (dao.hasUnsettledStepTwo(inpatientNo, admissTimes) > 0) { ExceptionEnum exception = ExceptionEnum.LOGICAL_ERROR; exception.setMessage("此患者有未结算的记账金额,请联系收费窗口。"); throw new BizException(exception); } if (dao.hasNotAccounted(inpatientNo, admissTimes) > 0) { ExceptionEnum exception = ExceptionEnum.LOGICAL_ERROR; exception.setMessage("此患者有未上账金额。"); throw new BizException(exception); } if (dao.hasUnreceivedDrugList(inpatientNo, admissTimes) > 0) { ExceptionEnum exception = ExceptionEnum.LOGICAL_ERROR; exception.setMessage("此患者有未接收的药单。"); throw new BizException(exception); } if (dao.hasUnreceivedFees(inpatientNo, admissTimes, actOrderDisDate) > 0) { ExceptionEnum exception = ExceptionEnum.LOGICAL_ERROR; exception.setMessage("此患者有未接收的费用。"); throw new BizException(exception); } if (dao.hasUnSubmitDrugList(inpatientNo, admissTimes) > 0) { ExceptionEnum exception = ExceptionEnum.LOGICAL_ERROR; exception.setMessage("此患者有未提交的药单。"); throw new BizException(exception); } if (dao.hasUntreatedDrugWithdrawalOrder(inpatientNo, admissTimes) > 0) { ExceptionEnum exception = ExceptionEnum.LOGICAL_ERROR; exception.setMessage("此患者有未处理的药品退药单。"); throw new BizException(exception); } if (dao.hasUnconfirmedMedicalTech(inpatientNo, admissTimes, actOrderDisDate) > 0) { ExceptionEnum exception = ExceptionEnum.LOGICAL_ERROR; exception.setMessage("此患者有未确认的医技。"); throw new BizException(exception); } List feeNegativeList = dao.feeOrderNegative(inpatientNo, admissTimes); if (feeNegativeList.size() > 0) { return ResultVoUtil.fail(ExceptionEnum.EXIST_NEGATIVE_FEES, "此患者费用清单存在负数。", feeNegativeList); } dao.deleteTemporaryTable(inpatientNo, admissTimes); final Integer transFlag = param.getDismissFlag() == 1 ? 0 : 2; if (dao.calculateCost(inpatientNo, admissTimes, ledgerSn, param.getStaffId(), param.getAdmissDate(), actOrderDisDate, param.getAdmissWard(), param.getAdmissDept(), transFlag) == null) { ExceptionEnum exception = ExceptionEnum.LOGICAL_ERROR; exception.setMessage("费用计算失败。执行zy_cngl_fyjs过程出错。"); throw new BizException(exception); } if (dao.hasSettled(inpatientNo, admissTimes, ledgerSn) != 0) { ExceptionEnum exception = ExceptionEnum.LOGICAL_ERROR; exception.setMessage("此患者已存在结算信息。"); throw new BizException(exception); } if (dao.hasUncheckedFee(inpatientNo, admissTimes, ledgerSn) > 0) { ExceptionEnum exception = ExceptionEnum.LOGICAL_ERROR; exception.setMessage("此患者有未结账的费用。"); throw new BizException(exception); } if (dao.getFeeOffset(inpatientNo, admissTimes, ledgerSn) > 0) { ExceptionEnum exception = ExceptionEnum.LOGICAL_ERROR; exception.setMessage("此患者明细费用与账页费用不一致。"); throw new BizException(exception); } String responce = param.getResponceType(); Date lastZjdzDatetime = null; if (!responce.equals("01")) { String hisTotalCharge; if (param.getDismissFlag() == 2) { lastZjdzDatetime = ledgerSn == 1 ? param.getAdmissDate() : dao.getLastZjdzDatetime(inpatientNo, admissTimes, ledgerSn - 1); hisTotalCharge = dao.getTotalChargeForZjdz(inpatientNo, admissTimes, ledgerSn, lastZjdzDatetime, actOrderDisDate); } else { hisTotalCharge = dao.getTotalChargeForCyjs(inpatientNo, admissTimes, ledgerSn); } ResultVo resultVo = YibaoHttpUtil.httpPost("preCalculateCost", param, responce); if (resultVo.getCode() != 200 && resultVo.getCode() != 2002) { ExceptionEnum exception = ExceptionEnum.LOGICAL_ERROR; exception.setMessage(resultVo.getMessage()); throw new BizException(exception); } else { HashMap obj = FilterUtil.cast(resultVo.getData()); String ybTotalCharge = obj.get("totalCost"); if (DecimalUtil.compare(hisTotalCharge, ybTotalCharge) != 0) { if (param.getDismissFlag() == 1) { int count = dao.hasFeeNotUpload(inpatientNo, admissTimes, ledgerSn); String message = "此患者明细费用与医保中心费用不一致。"; if (count > 0) { message += "(有未上传的费用【" + count + "】条)"; } ExceptionEnum exception = ExceptionEnum.LOGICAL_ERROR; exception.setMessage(message); throw new BizException(exception); } else { int count = dao.hasFeeNotUploadWithZjdz(param.getInpatientNo(), param.getAdmissTimes(), lastZjdzDatetime, param.getZjdzDatetime()); if (responce.equals("02")) { String message = "此患者明细费用与医保中心费用不一致。"; if (count > 0) { message += "(有未上传的费用【" + count + "】条)"; } ExceptionEnum exception = ExceptionEnum.LOGICAL_ERROR; exception.setMessage(message); throw new BizException(exception); } if (count == 0) { httpPost("cancelUploadFee", param, param.getResponceType()); } dao.updateTransFlagForZjdz(inpatientNo, admissTimes, ledgerSn, 1, param.getZjdzDatetime()); OverviewPojo overview = makeOverview(param); if (responce.equals("04")) { resultVo = httpPost("uploadFee", overview, responce); } else { if (responce.equals("03") || responce.equals("09")) { resultVo = equalizeUpload("cssyb", "single", null, overview, responce); } else { resultVo = equalizeUpload("hnsyb", "single", null, overview, responce); } } dao.updateTransFlagForZjdz(inpatientNo, admissTimes, ledgerSn, 0, param.getZjdzDatetime()); if (resultVo.getCode() != 200 && resultVo.getCode() != 2002) { ExceptionEnum exception = ExceptionEnum.LOGICAL_ERROR; exception.setMessage(resultVo.getMessage()); throw new BizException(exception); } else { obj = FilterUtil.cast(resultVo.getData()); ybTotalCharge = obj.get("totalCost"); if (DecimalUtil.compare(hisTotalCharge, ybTotalCharge) != 0) { ExceptionEnum exception = ExceptionEnum.LOGICAL_ERROR; exception.setMessage("此患者明细费用与医保中心费用不一致。"); throw new BizException(exception); } } } } } } return ResultVoUtil.success(); } private OverviewPojo makeOverview(PatientPojo param) { OverviewPojo overview = new OverviewPojo(); overview.setStaffId(param.getStaffId()); overview.setInpatientNo(param.getInpatientNo()); overview.setAdmissTimes(param.getAdmissTimes()); overview.setName(param.getName()); overview.setSex(param.getSex()); overview.setBedNo(param.getBedNo()); overview.setResponceType(param.getResponceType()); overview.setSid(param.getSid()); return overview; } @Transactional(rollbackFor = Exception.class) public ResultVo doDismiss(YbSettleFeePojo settleFee) throws BizException { updateHicNo(settleFee.getInpatientNo()); settleFee.setLedgerSn(dao.getLedgerSn(settleFee.getInpatientNo(), settleFee.getAdmissTimes())); if (!settleFee.getResponceType().trim().equals("01")) { // 自费病人不进行医保结算 int write; dao.deleteZyLedgerFileYb(settleFee.getInpatientNo(), settleFee.getAdmissTimes(), settleFee.getLedgerSn()); String cashPay = settleFee.getXjzf(); String fundPay = settleFee.getTczf(); // 如果医院支付为正,则 现金支付 = 现金支付 + 医院支付 if (!settleFee.getHospitalPay().startsWith("-")) { cashPay = DecimalUtil.add(cashPay, settleFee.getHospitalPay()); } if (settleFee.getYzsCzdd() == null || settleFee.getYzsCzdd().trim().equals("") || settleFee.getYzsCzdd().trim().equals("null")) { write = dao.writeYbSettleTableStepTwoShort(settleFee.getInpatientNo(), settleFee.getAdmissTimes(), settleFee.getLedgerSn(), settleFee.getTotalCost(), fundPay, settleFee.getGrzhzf(), settleFee.getDbzf(), cashPay, settleFee.getFullSelfPay(), settleFee.getPartSelfPay(), settleFee.getHospitalPay()); } else { write = dao.writeYbSettleTableStepTwoLong(settleFee.getInpatientNo(), settleFee.getAdmissTimes(), settleFee.getLedgerSn(), settleFee.getTotalCost(), fundPay, settleFee.getGrzhzf(), settleFee.getDbzf(), cashPay, settleFee.getYzsXjzf(), settleFee.getYzsThbz(), settleFee.getYzsMzjz(), settleFee.getYzsYyjm(), settleFee.getYzsCzdd(), settleFee.getYzsFplx(), settleFee.getYzsMzlx(), settleFee.getFullSelfPay(), settleFee.getPartSelfPay(), settleFee.getHospitalPay()); } if (write < 1) { ExceptionEnum exception = ExceptionEnum.LOGICAL_ERROR; exception.setMessage("写医保结算表失败。"); throw new BizException(exception); } } if (writeReceiptTable(settleFee) < 1) { ExceptionEnum exception = ExceptionEnum.LOGICAL_ERROR; exception.setMessage("写发票表失败。"); throw new BizException(exception); } int code = settleFee.getFlag() == 1 ? setHisStatusOut(settleFee) : hisMiddleSettle(settleFee); if (updateCostStatusToSettled(settleFee) < 1) { ExceptionEnum exception = ExceptionEnum.LOGICAL_ERROR; exception.setMessage("更新费用状态失败。"); throw new BizException(exception); } if (code < 1) { ExceptionEnum exception = ExceptionEnum.LOGICAL_ERROR; exception.setMessage("更新操作日志失败。" + code); throw new BizException(exception); } return ResultVoUtil.success(); } private int writeReceiptTable(YbSettleFeePojo indata) { if (dao.beforeWriteReceiptTable(indata.getInpatientNo(), indata.getAdmissTimes(), indata.getLedgerSn()) < 1) return -1; final int infantFlag = dao.selectInfantFlag(indata.getInpatientNo(), indata.getAdmissTimes(), indata.getLedgerSn()); // =0 无婴儿,>0 有婴儿 final Date dismissDate = getDismissDate(indata.getFlag(), indata.getInpatientNo(), indata.getAdmissTimes(), indata.getZjdzDatetime()); final Integer transFlag = indata.getFlag() == 1 ? 0 : 2; final Date admissDate = dao.selectAdmissDate(indata.getInpatientNo(), indata.getAdmissTimes()); final List fees = dao.calculateCost(indata.getInpatientNo(), indata.getAdmissTimes(), indata.getLedgerSn(), indata.getStaffId(), admissDate, dismissDate, indata.getWardCode(), indata.getDeptCode(), transFlag); if (fees == null || fees.isEmpty()) return -1; String totalCharge = getTotalCharge(fees, false); if (dao.writeReceiptTable(indata.getInpatientNo(), indata.getAdmissTimes(), indata.getLedgerSn(), 1, admissDate, dismissDate, indata.getWardCode(), indata.getDeptCode(), dismissDate, "01", indata.getStaffId(), totalCharge, fees.get(0).getChargePercent(), fees.get(1).getChargePercent(), fees.get(2).getChargePercent(), fees.get(3).getChargePercent(), fees.get(4).getChargePercent(), fees.get(5).getChargePercent(), fees.get(6).getChargePercent(), fees.get(7).getChargePercent(), fees.get(8).getChargePercent(), fees.get(9).getChargePercent(), fees.get(10).getChargePercent(), fees.get(11).getChargePercent(), fees.get(12).getChargePercent(), fees.get(13).getChargePercent(), fees.get(14).getChargePercent(), fees.get(15).getChargePercent(), fees.get(16).getChargePercent(), fees.get(17).getChargePercent(), fees.get(18).getChargePercent(), fees.get(19).getChargePercent(), fees.get(20).getChargePercent(), fees.get(21).getChargePercent(), fees.get(22).getChargePercent(), fees.get(23).getChargePercent(), fees.get(24).getChargePercent(), fees.get(25).getChargePercent(), fees.get(26).getChargePercent(), fees.get(27).getChargePercent()) < 1) return -1; if (infantFlag > 0) { totalCharge = getTotalCharge(fees, true); return dao.writeReceiptTable(indata.getInpatientNo(), indata.getAdmissTimes(), indata.getLedgerSn(), 4, admissDate, dismissDate, indata.getWardCode(), indata.getDeptCode(), dismissDate, "04", indata.getStaffId(), totalCharge, fees.get(0).getChargeInfant(), fees.get(1).getChargeInfant(), fees.get(2).getChargeInfant(), fees.get(3).getChargeInfant(), fees.get(4).getChargeInfant(), fees.get(5).getChargeInfant(), fees.get(6).getChargeInfant(), fees.get(7).getChargeInfant(), fees.get(8).getChargeInfant(), fees.get(9).getChargeInfant(), fees.get(10).getChargeInfant(), fees.get(11).getChargeInfant(), fees.get(12).getChargeInfant(), fees.get(13).getChargeInfant(), fees.get(14).getChargeInfant(), fees.get(15).getChargeInfant(), fees.get(16).getChargeInfant(), fees.get(17).getChargeInfant(), fees.get(18).getChargeInfant(), fees.get(19).getChargeInfant(), fees.get(20).getChargeInfant(), fees.get(21).getChargeInfant(), fees.get(22).getChargeInfant(), fees.get(23).getChargeInfant(), fees.get(24).getChargeInfant(), fees.get(25).getChargeInfant(), fees.get(26).getChargeInfant(), fees.get(27).getChargeInfant()); } return 1; } private String getTotalCharge(List fees, boolean infant) { String totalCharge = "0.00"; for (ReceiptFeePojo item : fees) { totalCharge = mathAdd(totalCharge, infant ? item.getChargeInfant() : item.getChargePercent()); } return totalCharge; } private Date getDismissDate(Integer flag, String inpatientNo, Integer admissTimes, Date zjdzDate) { return flag == 1 ? dao.selectActOrderDisDate(inpatientNo, admissTimes) : zjdzDate; } private int updateCostStatusToSettled(YbSettleFeePojo indata) { Date date = indata.getFlag() == 1 ? new Date() : indata.getZjdzDatetime(); final int code; if (indata.getResponceType().equals("01")) { code = dao.updateZifeiCostStatus(indata.getInpatientNo(), indata.getAdmissTimes(), indata.getLedgerSn(), indata.getWardCode(), indata.getDeptCode(), indata.getStaffId(), date); } else { final int hasInfant = dao.hasInfant(indata.getInpatientNo(), indata.getAdmissTimes()); code = hasInfant == 0 ? dao.updateCostStatusWithoutInfant(indata.getInpatientNo(), indata.getAdmissTimes(), indata.getLedgerSn(), indata.getWardCode(), indata.getDeptCode(), indata.getStaffId(), date, indata.getResponceType()) : dao.updateCostStatusWithInfant(indata.getInpatientNo(), indata.getAdmissTimes(), indata.getLedgerSn(), indata.getWardCode(), indata.getDeptCode(), indata.getStaffId(), date, indata.getResponceType()); } if (code < 1) return -1; return dao.updateZyDetailCharge(indata.getInpatientNo(), indata.getAdmissTimes(), indata.getLedgerSn()); } private int setHisStatusOut(YbSettleFeePojo indata) { final Date disDate = dao.selectActOrderDisDate(indata.getInpatientNo(), indata.getAdmissTimes()); if (dao.updateZyActpatient(indata.getInpatientNo(), indata.getAdmissTimes(), disDate, indata.getStaffId()) < 1) return -1; dao.deleteZyInactpatient(indata.getInpatientNo(), indata.getAdmissTimes()); if (dao.insertZyInactpatient(indata.getInpatientNo(), indata.getAdmissTimes()) < 1) return -2; final String inpatientNo1 = indata.getInpatientNo() + "$1"; final String inpatientNo6 = indata.getInpatientNo() + "$6"; dao.updateZyActpatientAgain(inpatientNo1, inpatientNo6, indata.getAdmissTimes(), disDate); dao.insertZyInactpatientAgain(inpatientNo1, inpatientNo6, indata.getAdmissTimes()); if (dao.updateZyAdt(indata.getInpatientNo(), indata.getAdmissTimes(), indata.getWardCode(), indata.getDeptCode(), indata.getBedNo(), disDate) < 1) return -3; if (dao.updateZyBedMi(indata.getInpatientNo(), indata.getAdmissTimes()) < 1) return -4; if (dao.deleteZyActpatient(indata.getInpatientNo()) < 1) return -5; dao.deleteZyActpatientAgain(inpatientNo1, inpatientNo6, indata.getAdmissTimes()); return insertNewZyWorkLog(indata); } private int insertNewZyWorkLog(YbSettleFeePojo indata) { final String userName = dao.getOperateName(indata.getStaffId()); return dao.insertNewZyWorkLog(indata.getInpatientNo(), indata.getAdmissTimes(), indata.getLedgerSn(), indata.getWardCode(), indata.getDeptCode(), indata.getStaffId(), userName); } private int hisMiddleSettle(YbSettleFeePojo indata) { indata.setLedgerSn(dao.getLedgerSn(indata.getInpatientNo(), indata.getAdmissTimes())); int newLedgerSn = indata.getLedgerSn() + 1; dao.updateTimesBilledByIncreaseOne(indata.getInpatientNo(), indata.getAdmissTimes()); dao.insertNewLedgerFile(indata.getInpatientNo(), indata.getAdmissTimes(), newLedgerSn); dao.updateFeesLedgerSn(indata.getInpatientNo(), indata.getAdmissTimes(), newLedgerSn, indata.getLedgerSn(), indata.getZjdzDatetime()); dao.updateZyLedgerFileTotalCharge(indata.getInpatientNo(), indata.getAdmissTimes(), indata.getLedgerSn()); dao.updateZyLedgerFileTotalCharge(indata.getInpatientNo(), indata.getAdmissTimes(), newLedgerSn); dao.retractYbsf1(indata.getInpatientNo(), indata.getAdmissTimes()); dao.retractYbsf2(indata.getInpatientNo(), indata.getAdmissTimes()); return insertNewZyWorkLog(indata); } private String mathAdd(String a, String b) { BigDecimal d1 = new BigDecimal(a); BigDecimal d2 = new BigDecimal(b); return d1.add(d2).toString(); } private void updateHicNo(String zyh) { String hicNoNew = dao.getHicNoNew(zyh); if (null != hicNoNew) { if (hicNoNew.length() > 16) { hicNoNew = hicNoNew.substring(0, 16); } dao.updateCpy(zyh, hicNoNew); if (hicNoNew.length() > 10) { hicNoNew = hicNoNew.substring(0, 10); } dao.updateHic(zyh, hicNoNew); } } }