package thyyxxk.webserver.service.inpatient.charge;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;
import thyyxxk.webserver.config.auth.PassToken;
import thyyxxk.webserver.config.exception.BizException;
import thyyxxk.webserver.config.exception.ExceptionEnum;
import thyyxxk.webserver.constants.ZyDepositFileStatusEnum;
import thyyxxk.webserver.dao.his.inpatient.charge.CashierProcessDao;
import thyyxxk.webserver.dao.his.inpatient.charge.MzsfBillnoRecDao;
import thyyxxk.webserver.dao.his.medicaladvice.common.DictDataDao;
import thyyxxk.webserver.entity.ResultVo;
import thyyxxk.webserver.entity.executeItem.NumberEnum;
import thyyxxk.webserver.entity.executeItem.ZyLedgerFile;
import thyyxxk.webserver.entity.inpatient.ZyActpatient;
import thyyxxk.webserver.entity.inpatient.charge.MzsfBillnoRec;
import thyyxxk.webserver.entity.inpatient.charge.PatientParam;
import thyyxxk.webserver.entity.inpatient.charge.ZyDepositFile;
import thyyxxk.webserver.entity.inpatient.charge.ZyReceipt;
import thyyxxk.webserver.utils.AssertUtil;
import thyyxxk.webserver.utils.CommonUtil;
import thyyxxk.webserver.utils.ResultVoUtil;
import thyyxxk.webserver.utils.TokenUtil;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description: 出纳处理
 * @Author:lihong
 * @Date: 2024/9/9
 */
@Slf4j
@Service
public class CashierProcessService {
    private final CashierProcessDao dao;
    private final DictDataDao dictDataDao;
    private final MzsfBillnoRecDao mzsfBillnoRecDao;
    private final RestTemplate template;
    @Value("${thmz-api-url}")
    private String thmzApiUrl;

    private static final String SETT_TYPE_JN = "交纳";
    private static final String SETT_TYPE_TK = "退款";

    @Autowired
    public CashierProcessService(CashierProcessDao dao, DictDataDao dictDataDao, MzsfBillnoRecDao mzsfBillnoRecDao, RestTemplate template) {
        this.dao = dao;
        this.dictDataDao = dictDataDao;
        this.mzsfBillnoRecDao = mzsfBillnoRecDao;
        this.template = template;
    }

    public Map<String, Object> queryPatientInfoPage(PatientParam param) {
        Map<String, Object> result = new HashMap<>();
        if (Convert.toInt(param.getInOutFlag(), 0) == 0) {
            param.setTableName(ZyActpatient.ZY_ACTPATIENT);
        } else {
            param.setTableName(ZyActpatient.ZY_INACTPATIENT);
        }
        if (StrUtil.isNotBlank(param.getInpatientNo())) {
            param.setInpatientNo(param.getInpatientNo() + "%");
        }
        List<ZyActpatient> list = dao.selectPatientInfoPage(param);
        CommonUtil.BeanTrim(list);
        if(CollUtil.isNotEmpty(list)){
            List<ZyActpatient> collect = list.stream().skip((param.getCurrentPage() - 1) * param.getPageSize()).limit(param.getPageSize()).collect(Collectors.toList());
            result.put("data", collect);
        }else {
            result.put("data", list);
        }
        result.put("total", list.size());
        return result;
    }

    /**
     * @description: 查询出纳标识  0 未出纳  1 已经出纳
     * @author: lihong
     * @date: 2024/9/9 17:33
     * @param: param
     * @return: java.util.Map<java.lang.String, java.lang.Object>
     **/
    public Map<String, Object> queryCashFlag(PatientParam param) {
        check(param);
        Map<String, Object> result = new HashMap<>();
        Integer flag = 0;
        List<ZyLedgerFile> list = dao.selectZyLedgerFile(param);
        if (CollUtil.isNotEmpty(list) && list.stream().anyMatch(item -> item.getCashDate() != null)) {
            //0 未出纳  1 已经出纳
            flag = 1;
        }
        result.put("cashFlag", flag);
        return result;
    }

    /**
     * @description: 查询出纳处理页面所有数据
     * @author: lihong
     * @date: 2024/9/10 17:09
     * @param: param
     * @return: java.util.Map<java.lang.String, java.lang.Object>
     **/
    public Map<String, Object> queryCashierProcessInfo(PatientParam param) {
        checkLedgerSn(param);
        Map<String, Object> result = new HashMap<>();
        //查询结算信息
        ZyLedgerFile settData = dao.selectSettData(param);
        if (settData != null) {
            BigDecimal settle = settData.getSettle();

            // 当医院负担金额大于0，并且有待补交的金额
            if(settData.getHospPartamt() != null && settData.getHospPartamt().compareTo(BigDecimal.ZERO) > 0
                && settData.getSettle().compareTo(BigDecimal.ZERO) < 0) {
                BigDecimal add = settle.add(settData.getHospPartamt());
                settData.setSettle(add);
            }

            if (settData.getSettle() != null) {
                settData.setSettleName(settData.getSettle().compareTo(BigDecimal.ZERO) >= 0 ? "退款:" : "补交:");
            }
            //0未结算  1是出院结算  3是中间结算  4是 已出纳
            settData.setSettleTypeName(ZyLedgerFile.SettTypeEnum.getByCode(settData.getSettleType()).name);
        }
        result.put("settData", settData);
        return result;
    }

    private void checkLedgerSn(PatientParam param) {
        check(param);
        AssertUtil.isnotBlank(param.getLedgerSn(), "账页号不能为空");
    }

    private void check(PatientParam param) {
        AssertUtil.isnotBlank(param.getInpatientNo(), "住院号不能为空");
        AssertUtil.isnotBlank(param.getAdmissTimes(), "住院次数不能为空");
        BeanUtil.trimStrFields(param);
    }

    /**
     * @description: 出纳处理页面数据效验
     * @author: lihong
     * @date: 2024/9/10 17:11
     * @param: param
     * @return: java.util.Map<java.lang.String, java.lang.Object>
     **/
    public Map<String, Object> checkCashierProcess(PatientParam param) {
        //检查是否有门诊 本院记账
        checkLedgerSn(param);
        Map<String, Object> result = new HashMap<>();
        String mzNo = dao.selectMzNo(param.getInpatientNo());
        List<ZyLedgerFile> zyLedgerFiles = dao.selectZyLedgerFile(param);
        if (CollUtil.isNotEmpty(zyLedgerFiles)) {
            ZyLedgerFile zyLedgerFile = zyLedgerFiles.get(0);
            result.put("zyLedgerFile", zyLedgerFile);
        }
        if (StrUtil.isNotBlank(mzNo)) {
            BigDecimal totalCharge = dao.selectMzByJz(mzNo);
            if (totalCharge != null && totalCharge.compareTo(BigDecimal.ZERO) > 0) {
                result.put("mzByJz", totalCharge.setScale(2, RoundingMode.HALF_UP));
            }
        }
        BigDecimal zYTotalFee = dao.selectZyLedgerFileTotal(param);
        BigDecimal mxTotalFee = dao.selectZyDetailChargeTotal(param);
        if (Convert.toBigDecimal(zYTotalFee, BigDecimal.ZERO).compareTo(Convert.toBigDecimal(mxTotalFee, BigDecimal.ZERO)) != 0) {
            result.put("zYTotalFee", zYTotalFee);
            result.put("mxTotalFee", mxTotalFee);
        }
        return result;
    }

    public List<ZyLedgerFile> queryPatientZyLedgerFile(PatientParam param) {
        check(param);
        return dao.selectZyLedgerFile(param);
    }

    /**
     * @description:查询可出纳列表
     * @author: lihong
     * @date: 2024/9/12 9:15
     * @param: param
     * @return: java.lang.Object
     **/
    public List<Map<String, Object>> queryKyCashierList(PatientParam param) {
        return dao.queryKyCashierList(param);
    }

    /**
     * @description: 保存出纳数据
     * @author: lihong
     * @date: 2024/9/13 9:37
     * @param: param
     * @return: thyyxxk.webserver.entity.ResultVo<java.lang.String>
     **/
    @Transactional(rollbackFor = Exception.class)
    public ResultVo<String> saveCashierData(PatientParam param) {
        checkLedgerSn(param);
        ZyLedgerFile zyLedgerFile = dao.selectSettData(param);
        AssertUtil.isnotBlank(zyLedgerFile, "账页信息不能为空");
        AssertUtil.isnotBlank(param.getDepositFileList(), "交款信息不能为空");
        BeanUtil.trimStrFields(param);
        //结算金额
        BigDecimal settleFee = zyLedgerFile.getSettle();
        if (zyLedgerFile.getAccountDate() == null) {
            throw new BizException(ExceptionEnum.LOGICAL_ERROR, "该病人未结算");
        }
        if (zyLedgerFile.getCashDate() != null) {
            throw new BizException(ExceptionEnum.LOGICAL_ERROR, "该病人已经出纳,请不要重复操作");
        }
        if (dao.countWsjFee(param) > 0) {
            throw new BizException(ExceptionEnum.LOGICAL_ERROR, "该病人有未结算的费用明细");
        }
        if (dao.countWjsYp(param) > 0) {
            throw new BizException(ExceptionEnum.LOGICAL_ERROR, "该病人有未接收的药单");
        }
        if (dao.countWjYzFee(param) > 0) {
            throw new BizException(ExceptionEnum.LOGICAL_ERROR, "该病人有未接收的费用");
        }
        if (dao.countWtjYp(param) > 0) {
            throw new BizException(ExceptionEnum.LOGICAL_ERROR, "该病人有未提交的药单");
        }
        if (dao.countWclYp(param) > 0) {
            throw new BizException(ExceptionEnum.LOGICAL_ERROR, "该病人有未处理的药单，请联系药房处理");
        }
        if (dao.countWqrFy(param) > 0) {
            throw new BizException(ExceptionEnum.LOGICAL_ERROR, "该病人有未确认的费用");
        }
        param.setOpDate(new Date());
        if (StrUtil.isBlank(param.getOpId())) {
            param.setOpId(TokenUtil.getInstance().getTokenUserId());
        }
        if (settleFee != null && settleFee.compareTo(BigDecimal.ZERO) != 0) {
            List<ZyDepositFile> depositFileList = param.getDepositFileList();
            Integer maxDepoTimes = dao.selectMaxDepoTimes(param);
            if (null == maxDepoTimes) {
                maxDepoTimes = 0;
            }
            int index = 1;
            for (ZyDepositFile depositFile : depositFileList) {
                if (depositFile.getDepoAmount() == null || depositFile.getDepoAmount().compareTo(BigDecimal.ZERO) == 0) {
                    continue;
                }
                depositFile.setInpatientNo(param.getInpatientNo());
                depositFile.setAdmissTimes(param.getAdmissTimes());
                depositFile.setLedgerSn(param.getLedgerSn());
                if (StrUtil.isBlank(depositFile.getOpIdCode())) {
                    depositFile.setOpIdCode(param.getOpId());
                }
                depositFile.setDepoDate(param.getOpDate());
                if (StrUtil.isBlank(depositFile.getWindowNo())) {
                    depositFile.setWindowNo(NumberEnum.TWO.getCode());
                }
                depositFile.setDepoTimes(Convert.toInt(maxDepoTimes,0) + index);
                dao.insetZyDepositFile(depositFile);
                ++index;
            }
        }
        dao.updateCnZyLedgerFile(param);
        dao.updateCnZyDepositFile(param);
        if (dao.countZy(param) > 0) {
            param.setTableName(ZyActpatient.ZY_ACTPATIENT);
        } else {
            param.setTableName(ZyActpatient.ZY_INACTPATIENT);
        }
        dao.updateZyPatientBalance(param);
        return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_EL_MESSAGE);
    }


    public Map<String, Object> queryZyDepositFileList(PatientParam param) {
        check(param);
        Map<String, Object> result = new HashMap<>();
        //已交押金
        List<ZyDepositFile> yjYj = dao.selectZyDepositFile(param);
        ZyActpatient info = dao.selectNameAndWardName(param.getInpatientNo());
        Integer yjZs = 0;
        BigDecimal yjHj = BigDecimal.ZERO;
        BigDecimal ztHj = BigDecimal.ZERO;
        BigDecimal sjYj;
        if (CollUtil.isNotEmpty(yjYj)) {
            List<ZyDepositFile> yjList = yjYj.stream().filter(item -> ZyDepositFileStatusEnum.PREPAY.code.equals(item.getStatus())).collect(Collectors.toList());
            if (CollUtil.isNotEmpty(yjList)) {
                yjZs = yjList.size();
                yjHj = yjList.stream().map(ZyDepositFile::getDepoAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            }
            List<ZyDepositFile> ztList = yjYj.stream().filter(item -> ZyDepositFileStatusEnum.STRAIGHT_BACK.code.equals(item.getStatus())).collect(Collectors.toList());
            if (CollUtil.isNotEmpty(ztList)) {
                ztHj = ztList.stream().map(ZyDepositFile::getDepoAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
            }
        }
        sjYj = yjHj.add(ztHj).setScale(2, RoundingMode.HALF_UP);
        result.put("sjYj", sjYj);
        result.put("yjZs", yjZs);
        result.put("yjHj", yjHj);
        result.put("ztHj", ztHj);
        result.put("yjYj", yjYj);
        result.put("patInfo", info);
        return result;

    }

    public List<ZyReceipt> queryZyReceipt(PatientParam param) {
        List<ZyReceipt> zyReceipt = dao.selectZyReceipt(param);
        if (CollUtil.isNotEmpty(zyReceipt)) {
            CommonUtil.BeanTrim(zyReceipt);
            ZyReceipt temp = new ZyReceipt();
            temp.setTotalCharge(zyReceipt.stream().map(item -> Convert.toBigDecimal(item.getTotalCharge(), BigDecimal.ZERO)).reduce(BigDecimal.ZERO, BigDecimal::add));
            zyReceipt.add(temp);
        }
        return zyReceipt;
    }

    @Transactional(rollbackFor = Exception.class)
    public ResultVo<String> cancelCashierData(PatientParam param) {
        checkCashierProcess(param);
        AssertUtil.isnotBlank(param.getLedgerSn(), "账页号不能为空");
        ZyLedgerFile zyLedgerFile = dao.selectSettData(param);
        AssertUtil.isnotBlank(zyLedgerFile, "没有账页信息");
        AssertUtil.isnotBlank(zyLedgerFile.getCashDate(), "未出纳,不能[取消出纳]操作");
        BeanUtil.trimStrFields(param);
        // 已经 确费的不能取消出纳 90天以内的可以取消出纳
        if (NumberEnum.ONE.getCode().equals(zyLedgerFile.getDcountNo())) {
            throw new BizException(ExceptionEnum.LOGICAL_ERROR, "病人已经结账不能[取消出纳]操作");
        }
        String qxCnXzts = dictDataDao.getDictValueByDictName("2.8", "qx_cn_xzts");
        int day = Convert.toInt(zyLedgerFile.getDiffCashDate(), 0) / 24;
        int xzts = Convert.toInt(qxCnXzts, 90);
        if (day > xzts) {
            throw new BizException(ExceptionEnum.LOGICAL_ERROR, "病人已经出纳超过" + xzts + "天,不能[取消出纳]操作");
        }
        dao.clearZyLedgerFileCashier(param);
        dao.clearZyReceiptCashier(param);
        dao.clearZyDepositFileHsr(param);
        dao.delZyDepositFileCashier(param);
        return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_EL_MESSAGE);
    }

    public List<Map<String, Object>> queryZdChequeType() {
        return dao.selectZdChequeType();
    }

    /**
     * @description: 更新打印住院发票数据
     * @author: lihong
     * @date: 2024/9/14 9:16
     * @param: param
     * @return: thyyxxk.webserver.entity.ResultVo<java.lang.String>
     **/
    @Transactional(rollbackFor = Exception.class)
    public ResultVo<String> updatePrintZyFpData(PatientParam param) {
        checkLedgerSn(param);
        AssertUtil.isnotBlank(param.getReceiptNo(), "发票号不能为空");
        if (StrUtil.isBlank(param.getOpId())) {
            param.setOpId(TokenUtil.getInstance().getTokenUserId());
        }
        boolean flag = false;
        if (NumberEnum.ONE.getCode().equals(param.getPrintFlag())) {
            MzsfBillnoRec mzsfBillnoRec = mzsfBillnoRecDao.selectCurMzsfBillnoRec(param.getOpId());
            if (mzsfBillnoRec == null || mzsfBillnoRec.getCurrentNo() == null) {
                throw new BizException(ExceptionEnum.LOGICAL_ERROR, "没有发票号了,请及时登记收费发票");
            }
            if (!mzsfBillnoRec.getCurrentNo().equals(mzsfBillnoRec.getEndNo())) {
                mzsfBillnoRecDao.updateCurrentNo(param.getOpId());
            } else {
                flag = true;
            }
            dao.updateZyLedgerFileReceiptNo(param);
            dao.updateZyDepositFileReceiptNo(param);
        }
        dao.updatezyReceipt(param);
        if (flag) {
            return ResultVoUtil.success(ExceptionEnum.INTERNAL_SERVER_ERROR, "当前发票已经是最后一张了,请及时登记新的发票!");
        }
        return ResultVoUtil.success();
    }

    public ZyReceipt queryPrintZyFpData(PatientParam param) {
        checkLedgerSn(param);
       String fpVersion = Convert.toStr(queryFpVersion().getData());
        String fpVersionStr = NumberEnum.ZERO.getCode().equals(fpVersion) ? "打印" : "上传";
        if(Convert.toInt(NumberEnum.FOUR.getCode()).equals(Convert.toInt(param.getReceiptSn(),1))){
            param.setResponceUnit("04");
        }else {
            param.setResponceUnit("01");
        }
        ZyReceipt zyReceipt = dao.selectPrintZyFpData(param);
        AssertUtil.isnotBlank(zyReceipt, "没可打印发票信息");
        BeanUtil.trimStrFields(zyReceipt);
        List<ZyLedgerFile> list = dao.selectZyLedgerFile(param);
        AssertUtil.isnotBlank(list, "没有账页信息");
        ZyActpatient zyActpatient = dao.selectApatienInfo(param.getInpatientNo());
        zyReceipt.setName(Convert.toInt(NumberEnum.FOUR.getCode()).equals(Convert.toInt(param.getReceiptSn(),1)) ? zyActpatient.getName()+"(婴儿)":zyActpatient.getName());
        zyReceipt.setStartDate(DateUtil.format(zyReceipt.getDate1(), "yyyy-MM-dd"));
        zyReceipt.setEndDate(DateUtil.format(zyReceipt.getDate2(), "yyyy-MM-dd"));
        long diff = DateUtil.betweenDay(DateUtil.parseDate(zyReceipt.getStartDate()), DateUtil.parseDate(zyReceipt.getEndDate()), true);
        zyReceipt.setSexName(zyActpatient.getSexName());
        zyReceipt.setZyTs(diff == 0 ? 1 : diff + 1);
        ZyLedgerFile zyLedgerFile = list.get(0);
        param.setSerialNo(zyLedgerFile.getZySerialNo());
        if(NumberEnum.ONE.getCode().equals(fpVersion) && zyLedgerFile.getAccountDate() == null && Convert.toInt(param.getTypeFlag(),0) == 3){
            throw new BizException(ExceptionEnum.LOGICAL_ERROR, "未结算处理,不能"+fpVersionStr+"发票");
        }
        if(NumberEnum.ZERO.getCode().equals(fpVersion)){
            if (zyLedgerFile.getCashDate() == null) {
                throw new BizException(ExceptionEnum.LOGICAL_ERROR, "未出纳处理,不能"+fpVersionStr+"发票");
            }
        }
        if(Convert.toInt(NumberEnum.FOUR.getCode()).equals(Convert.toInt(param.getReceiptSn(),1))){
            zyReceipt.setGrZfHjJe(zyReceipt.getGrZfJe());
            zyReceipt.setGrZfHjJeChinese(Convert.digitToChinese(zyReceipt.getGrZfHjJe()));
        }else {
            zyReceipt.setYbTcZfJe(Convert.toBigDecimal(zyLedgerFile.getFundPaySumamt(), BigDecimal.ZERO).setScale(2, BigDecimal.ROUND_HALF_UP));
            zyReceipt.setGrZhZfJe(Convert.toBigDecimal(zyLedgerFile.getAcctPay(), BigDecimal.ZERO).setScale(2, BigDecimal.ROUND_HALF_UP));
            zyReceipt.setGrZfJe(zyReceipt.getTotalCharge().subtract(zyReceipt.getYbTcZfJe()).subtract(zyReceipt.getGrZhZfJe()));
            zyReceipt.setGrZfHjJe(zyReceipt.getGrZfJe());
            zyReceipt.setGrZfHjJeChinese(Convert.digitToChinese(zyReceipt.getGrZfHjJe()));
            zyReceipt.setResponceTypeName(zyLedgerFile.getResponceTypeName());
            zyReceipt.setYsHjJe(zyLedgerFile.getDeposit());
            if (Convert.toBigDecimal(zyLedgerFile.getSettle(), BigDecimal.ZERO).compareTo(BigDecimal.ZERO) >= 0) {
                zyReceipt.setTkHjJe(zyLedgerFile.getSettle());
                zyReceipt.setBsHjJe(BigDecimal.ZERO);
            } else {
                zyReceipt.setBsHjJe(zyLedgerFile.getSettle().abs());
                zyReceipt.setTkHjJe(BigDecimal.ZERO);
            }
            zyReceipt.setYsHjJe(Convert.toBigDecimal(zyLedgerFile.getDeposit(), BigDecimal.ZERO));
        }
        if(NumberEnum.ONE.getCode().equals(fpVersion)){
             //小孩  加 $1
            if(Convert.toInt(NumberEnum.FOUR.getCode()).equals(param.getReceiptSn())){
                param.setInpatientNo(param.getInpatientNo()+"$1");
            }
            ResultVo resultVo = uploadDzInvoice(param);
            String typeFlagName = param.getTypeFlag() == 3 ? "上传电子发票" : "作废电子发票";
            if(resultVo == null){
                throw new BizException(typeFlagName+"失败");
            }
            if(resultVo.getCode() ==-1){
                throw new BizException(resultVo.getMessage());
            }
        }
        return zyReceipt;
    }

    @PassToken
    public ResultVo uploadDzInvoice(PatientParam param){
        Map<String, Object> paramMap = dealInvoiceParam(param);
        paramMap.put("opId", TokenUtil.getInstance().getTokenUserId());
        ResultVo response = template.postForObject(thmzApiUrl +"/uploadZyInvoice", paramMap, ResultVo.class);
        return response;
    }

    @NotNull
    private Map<String, Object> dealInvoiceParam(PatientParam param) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("patientId", param.getInpatientNo());
        paramMap.put("times", param.getAdmissTimes());
        paramMap.put("typeFlag", param.getTypeFlag());
        paramMap.put("receiptNo", param.getLedgerSn());
        paramMap.put("serialNo", param.getSerialNo());
        if(StrUtil.isNotBlank(param.getRemark())){
            paramMap.put("remark", param.getRemark());
        }
        return paramMap;
    }

    @Transactional(rollbackFor = Exception.class)
    public ResultVo<String> cashierDataTx(PatientParam param) {
        check(param);
        Integer maxLedgerSn = dao.hasCashierDataTx(param);
        if(maxLedgerSn == null){
            throw new BizException(ExceptionEnum.LOGICAL_ERROR, "未出纳不能费用冲销");
        }
       Integer minLed =  dao.selectMinLedgerSn(param);
       if(minLed == null){
           throw new BizException(ExceptionEnum.LOGICAL_ERROR, "没有账页信息");
       }
        param.setLedgerSn(maxLedgerSn);
       if(StrUtil.isBlank(param.getOpId())){
           param.setOpId(TokenUtil.getInstance().getTokenUserId());
       }
        Integer oneLedgerSn = minLed -1;
        Integer twoLedgerSn = minLed -2;
        dao.zyLedgerFileTx(param, oneLedgerSn, "0", 1);
        dao.zyLedgerFileTx(param, twoLedgerSn, "1", -1);

        dao.zyReceiptTx(param, oneLedgerSn, "0", 1);
        dao.zyReceiptTx(param, twoLedgerSn, "1", -1);

        dao.zyDetailChargeTx(param, oneLedgerSn, 1);
        dao.zyDetailChargeTx(param, twoLedgerSn, -1);

        dao.zyDepositFileTx(param, oneLedgerSn, "0", 1);
        dao.zyDepositFileTx(param, twoLedgerSn, "1", -1);

        dao.clearZyLedgerFileCashier(param);
        dao.clearZyReceiptCashier(param);
        dao.clearZyDepositFileHsr(param);
        dao.delZyDepositFileCashier(param);
        return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_EL_MESSAGE);
    }

    public ResultVo<ZyActpatient> queryZyActpatientFeeDetail(PatientParam param) {
        check(param);
       return ResultVoUtil.success(dao.selectZyActpatientFeeDetail(param));
    }

    public ResultVo<Map<String, Object>> queryMaxAndMinLedgerSn(PatientParam param) {
        check(param);
        return ResultVoUtil.success(dao.selectMaxAndMinLedgerSn(param));
    }

    public ResultVo<Map<String, Object>> selectDzfpUploadAboutSerialNo(String inpatientNo,String admissTimes) {
//        check(param);
        return ResultVoUtil.success(dao.selectDzfpUploadAboutSerialNo(inpatientNo,admissTimes));
    }

    public ResultVo<Map<String, Object>> downDzInvoice(PatientParam param) {
        if(Convert.toInt(NumberEnum.FOUR.getCode()).equals(Convert.toInt(param.getReceiptSn(),1))){
            param.setResponceUnit("04");
        }else {
            param.setResponceUnit("01");
        }
        ZyReceipt zyReceipt = dao.selectPrintZyFpData(param);
        AssertUtil.isnotBlank(zyReceipt, "没有发票信息");
        ZyLedgerFile zyLedgerFile = dao.selectSettData(param);
        AssertUtil.isnotBlank(zyReceipt, "没有账页信息");
        zyReceipt.setYsHjJe(Convert.toBigDecimal(zyLedgerFile.getDeposit(),BigDecimal.ZERO));
        if(Convert.toBigDecimal(zyLedgerFile.getSettle(), BigDecimal.ZERO).compareTo(BigDecimal.ZERO) >= 0){
            zyReceipt.setTkHjJe(Convert.toBigDecimal(zyLedgerFile.getSettle(),BigDecimal.ZERO));
            zyReceipt.setBsHjJe(BigDecimal.ZERO);
        }else {
            zyReceipt.setTkHjJe(BigDecimal.ZERO);
            zyReceipt.setBsHjJe(zyLedgerFile.getSettle().abs());
        }
        ZyActpatient zyActpatient = dao.selectApatienInfo(param.getInpatientNo());
        zyReceipt.setName(Convert.toInt(NumberEnum.FOUR.getCode()).equals(Convert.toInt(param.getReceiptSn(),1)) ? zyActpatient.getName()+"(婴儿)":zyActpatient.getName());
        if(Convert.toInt(NumberEnum.FOUR.getCode()).equals(param.getReceiptSn())){
            param.setInpatientNo(param.getInpatientNo()+"$1");
        }
        //    下载二维码 直接查数据库
        Map<String, Object> fpInfo = new HashMap<>();
        if(NumberEnum.ONE.getCode().equals(param.getType())){
            Map<String,Object> dzfpMap =  dao.selectDzfpNo(param);
            AssertUtil.isnotBlank(dzfpMap,"没有查询到电子发票");
            AssertUtil.isnotBlank(dzfpMap.get("qrcode"),"没有查询到电子发票");
            fpInfo.put("qrcode", dzfpMap.get("qrcode"));
            fpInfo.put("pdfFileStr", "");
        }else {
            Map<String, Object> paramMap = dealInvoiceParam(param);
            ResultVo response = template.postForObject(thmzApiUrl +"/queryInvoiceFile", paramMap, ResultVo.class);
            if(response == null ){
                return ResultVoUtil.fail(ExceptionEnum.LOGICAL_HTML_ERROR, "下载电子发票错误");
            }
            if(response.getCode() == -1 ){
                return ResultVoUtil.fail(ExceptionEnum.LOGICAL_HTML_ERROR, response.getMessage());
            }
            fpInfo = (Map)response.getData();
            if(Convert.toInt(NumberEnum.ThREE.getCode()).equals(param.getTypeFlag())){
                Map<String,Object> dzfpNoMap =  dao.selectDzfpNo(param);
                String dzfpNo = dzfpNoMap != null && dzfpNoMap.get("fp_no") != null? Convert.toStr(dzfpNoMap.get("fp_no")) : null;
                if(StrUtil.isNotBlank(dzfpNo)){
                    param.setReceiptNo(dzfpNo);
                    dao.updateZyLedgerFileReceiptNo(param);
                    dao.updateZyDepositFileReceiptNo(param);
                    dao.updatezyReceiptDzfpNo(param);
                }else {
                    //    查询是否有冲红的发票
                    param.setTypeFlag(4);
                    Map<String,Object> zfDzfpNoMap =  dao.selectDzfpNo(param);
                    String zfDzfpNo = zfDzfpNoMap != null && zfDzfpNoMap.get("fp_no") != null? Convert.toStr(zfDzfpNoMap.get("fp_no")) : null;
                    if(StrUtil.isNotBlank(zfDzfpNo)){
                        dao.clearZyReceiptDzfpNo(param);
                    }
                }
            }
        }
        Map<String, Object> res = new HashMap<>();
        res.put("zyReceipt", zyReceipt);
        res.put("fpInfo", fpInfo);
        return ResultVoUtil.success(ExceptionEnum.SUCCESS,res);
    }

    public ResultVo<String> queryFpVersion() {
        String fpVersion = dictDataDao.getDictValueByDictName("3.5", "fp_version");
        return ResultVoUtil.success(Convert.toStr(fpVersion,"0"));
    }
}
