package cn.hnthyy.thmz.controller.mz;

import cn.hnthyy.thmz.Utils.DateTimeUtils;
import cn.hnthyy.thmz.Utils.DateUtil;
import cn.hnthyy.thmz.Utils.ExcelUtil;
import cn.hnthyy.thmz.Utils.TokenUtil;
import cn.hnthyy.thmz.comment.UserLoginToken;
import cn.hnthyy.thmz.common.Constants;
import cn.hnthyy.thmz.entity.MzException;
import cn.hnthyy.thmz.entity.his.mz.*;
import cn.hnthyy.thmz.entity.his.zd.ZdChequeType;
import cn.hnthyy.thmz.entity.thmz.Mzmxsr;
import cn.hnthyy.thmz.entity.thmz.User;
import cn.hnthyy.thmz.enums.PayMarkEnum;
import cn.hnthyy.thmz.enums.YesNoEnum;
import cn.hnthyy.thmz.service.his.mz.*;
import cn.hnthyy.thmz.service.his.zd.ZdChequeTypeService;
import cn.hnthyy.thmz.service.his.zd.ZdUnitCodeService;
import cn.hnthyy.thmz.service.thmz.MzmxsrService;
import cn.hnthyy.thmz.service.thmz.UserService;
import cn.hnthyy.thmz.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@RestController
public class ChargeFeeVoController {
    @Autowired
    private ChargeFeeVoService chargeFeeVoService;
    @Autowired
    private ZdUnitCodeService zdUnitCodeService;
    @Autowired
    private MzyZdChargeTypeService mzyZdChargeTypeService;
    @Autowired
    private ZdChequeTypeService zdChequeTypeService;
    @Autowired
    private EmployeeService employeeService;
    @Autowired
    private UserService userService;
    @Autowired
    private MzBillItemService mzBillItemService;
    @Autowired
    private MzPatientMiService mzPatientMiService;
    @Autowired
    private MzmxsrService mzmxsrService;
    @Autowired
    private MzReceiptSerialService mzReceiptSerialService;
    /**
     * 查询日结列表收费清单 未结账
     *
     * @return
     */
    @UserLoginToken
    @RequestMapping(value = "/getChargeFeeVoUnAccount", method = {RequestMethod.GET, RequestMethod.POST})
    public Map<String, Object> getChargeFeeVoUnAccount(HttpServletRequest httpServletRequest) {
        Map<String, Object> resultMap = new HashMap<>();
        try {
            User tokenUser = TokenUtil.getUser(httpServletRequest);
            resultMap.put("code", 0);
            resultMap.put("message", "查询日结列表收费清单成功");
            List<ChargeFeeVo> chargeFeeVos = chargeFeeVoService.queryChargeFeeVoUnAccount(tokenUser.getUserIdCode());
            fomartChargeVo(chargeFeeVos, YesNoEnum.NO);
            resultMap.put("data", chargeFeeVos);
            return resultMap;
        } catch (MzException e) {
            log.error("查询日结列表收费清单失败，错误信息{}", e);
            resultMap.put("code", -1);
            resultMap.put("message", "查询日结列表收费清单失败");
            return resultMap;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("查询日结列表收费清单失败，错误信息{}", e.getMessage());
            resultMap.put("code", -1);
            resultMap.put("message", "查询日结列表收费清单失败");
            return resultMap;
        }
    }

    private void fomartChargeVo(List<ChargeFeeVo> chargeFeeVos, YesNoEnum fitEmpName) {
        if (chargeFeeVos != null && chargeFeeVos.size() > 0) {
            List<ZdChequeType> chequeTypes = zdChequeTypeService.queryAllZdChequeTypeForMz();
            Map<String, String> employeeMap = null;
            if (YesNoEnum.YES.equals(fitEmpName)) {
                Set<String> opIds = chargeFeeVos.stream().filter(u -> StringUtils.isNotBlank(u.getOpId())).map(u -> u.getOpId()).collect(Collectors.toSet());
                if (opIds != null) {
                    List<Employee> employees = employeeService.queryByCodes(new ArrayList<>(opIds));
                    if (employees != null) {
                        employeeMap = employees.stream().collect(Collectors.toMap(Employee::getEmployeeCode, Employee::getEmployeeName));
                    }
                }
            }
            Map<String, String> chequeTypeMap = chequeTypes.stream().collect(Collectors.toMap(ZdChequeType::getCode, ZdChequeType::getName));
            Map<String, List<ChargeFeeVo>> chargeFeeMap = new HashMap();
            for (ChargeFeeVo co : chargeFeeVos) {
                PayMarkEnum payMark = PayMarkEnum.getPayMarkByCode(co.getPayMark());
                co.setPayMark(payMark == null ? co.getPayMark() : payMark.name);
                if (Constants.BRZZJF_CODE.equalsIgnoreCase(co.getOpId())) {
                    if (Constants.WX.equalsIgnoreCase(co.getChequeType()) || Constants.BYJZ.equalsIgnoreCase(co.getChequeType())) {
                        co.setChequeType(Constants.ZZWX);
                    } else if (Constants.ZFB.equalsIgnoreCase(co.getChequeType())) {
                        co.setChequeType(Constants.ZZZFB);
                    }
                }
                co.setChequeType(chequeTypeMap.get(co.getChequeType()));
                if (YesNoEnum.YES.equals(fitEmpName)) {
                    co.setOpId(employeeMap.get(co.getOpId()));
                }
                List<ChargeFeeVo> tempList = chargeFeeMap.get(co.getSerialNo());
                if (tempList == null) {
                    tempList = new ArrayList<>();
                    chargeFeeMap.put(co.getSerialNo(), tempList);
                }
                tempList.add(co);
            }
            for (String key : chargeFeeMap.keySet()) {
                if (StringUtils.isNotBlank(key)) {
                    List<ChargeFeeVo> tempList = chargeFeeMap.get(key);
                    if (tempList.size() > 1) {
                        for (ChargeFeeVo co : tempList) {
                            if ((Constants.BYJZ_NAME.equals(co.getChequeType()) && StringUtils.isNotBlank(co.getReceiptBill())) || (!Constants.BYJZ_NAME.equals(co.getChequeType()) && StringUtils.isBlank(co.getReceiptBill()))) {
                                chargeFeeVos.remove(co);
                            }
                        }
                    }
                }
            }
        }
    }

//    private User getUser(HttpServletRequest httpServletRequest) throws MzException {
//        String token = TokenUtil.getToken(httpServletRequest);
//        if (StringUtils.isBlank(token)) {
//            throw new MzException("业务处理失败,用户Token不存在");
//        }
//        DecodedJWT decodedJWT = TokenUtil.parseJWT(token);
//        return (User) JsonUtil.jsontoObject(decodedJWT.getSubject(), User.class);
//    }


    /**
     * 日结汇总的收费清单
     *
     * @return
     */
    @UserLoginToken
    @RequestMapping(value = "/getChargeFeeVoCollect", method = {RequestMethod.GET, RequestMethod.POST})
    public Map<String, Object> getChargeFeeVoCollect(@RequestBody ChargeFeeParamsVo chargeFeeParamsVo) {
        Map<String, Object> resultMap = new HashMap<>();
        try {
            if (chargeFeeParamsVo == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "日结汇总的收费清单失败,参数为空");
                return resultMap;
            }
            if (chargeFeeParamsVo.getBeginDate() == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "日结汇总的收费清单失败,开始时间为空");
                return resultMap;
            }
            if (chargeFeeParamsVo.getEndDate() == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "日结汇总的收费清单失败,结束时间为空");
                return resultMap;
            }
            if (chargeFeeParamsVo.getHisData() == null) {
                chargeFeeParamsVo.setHisData(YesNoEnum.NO);
            }
            if (StringUtils.isBlank(chargeFeeParamsVo.getCaseType())) {
                chargeFeeParamsVo.setCaseType(YesNoEnum.NO.code.toString());
            }
            resultMap.put("code", 0);
            resultMap.put("message", "日结汇总的收费清单成功");
            List<ChargeFeeVo> chargeFeeVos = chargeFeeVoService.queryChargeFeeVoCollect(chargeFeeParamsVo.getHisData(), chargeFeeParamsVo.getCaseType(), chargeFeeParamsVo.getBeginDate(), chargeFeeParamsVo.getEndDate());
            fomartChargeVo(chargeFeeVos, YesNoEnum.YES);
            resultMap.put("data", chargeFeeVos);
            return resultMap;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("日结汇总的收费清单失败，错误信息{}", e.getMessage());
            resultMap.put("code", -1);
            resultMap.put("message", "日结汇总的收费清单失败");
            return resultMap;
        }
    }


    /**
     * 重打结算单的收费清单
     *
     * @return
     */
    @UserLoginToken
    @RequestMapping(value = "/getChargeFeeVoReprint", method = {RequestMethod.GET, RequestMethod.POST})
    public Map<String, Object> getChargeFeeVoReprint(@RequestBody ChargeFeeParamsVo chargeFeeParamsVo) {
        Map<String, Object> resultMap = new HashMap<>();
        try {
            if (chargeFeeParamsVo == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "重打结算单的收费清单失败,参数为空");
                return resultMap;
            }
            if (StringUtils.isBlank(chargeFeeParamsVo.getCaseType())) {
                chargeFeeParamsVo.setCaseType(YesNoEnum.NO.code.toString());
            }
            if (chargeFeeParamsVo.getDcountDate() == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "重打结算单的收费清单失败,结算时间为空");
                return resultMap;
            }
            resultMap.put("code", 0);
            resultMap.put("message", "重打结算单的收费清单成功");
            List<ChargeFeeVo> chargeFeeVos = chargeFeeVoService.queryChargeFeeVoReprint(chargeFeeParamsVo.getOpId(), chargeFeeParamsVo.getCaseType(), chargeFeeParamsVo.getDcountDate());
            fomartChargeVo(chargeFeeVos, YesNoEnum.NO);
            resultMap.put("data", chargeFeeVos);
            return resultMap;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("重打结算单的收费清单失败，错误信息{}", e.getMessage());
            resultMap.put("code", -1);
            resultMap.put("message", "重打结算单的收费清单失败");
            return resultMap;
        }
    }


    /**
     * 日结列表的挂号清单 未结账
     *
     * @return
     */
    @UserLoginToken
    @RequestMapping(value = "/getReqrecVoUnAccount", method = {RequestMethod.GET, RequestMethod.POST})
    public Map<String, Object> getReqrecVoUnAccount(HttpServletRequest httpServletRequest) {
        Map<String, Object> resultMap = new HashMap<>();
        try {
            User tokenUser = TokenUtil.getUser(httpServletRequest);
            resultMap.put("code", 0);
            resultMap.put("message", "查询日结列表的挂号清单成功");
            List<ReqrecVo> reqrecVos = chargeFeeVoService.queryReqrecVoUnAccount(tokenUser.getUserIdCode());
            frmartReQrecVo(reqrecVos, YesNoEnum.NO);
            resultMap.put("data", reqrecVos);
            return resultMap;
        } catch (MzException e) {
            log.error("查询日结列表的挂号清单失败，错误信息{}", e);
            resultMap.put("code", -1);
            resultMap.put("message", "查询日结列表的挂号清单失败");
            return resultMap;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("查询日结列表的挂号清单失败，错误信息{}", e.getMessage());
            resultMap.put("code", -1);
            resultMap.put("message", "查询日结列表的挂号清单失败");
            return resultMap;
        }
    }

    private void frmartReQrecVo(List<ReqrecVo> reqrecVos, YesNoEnum fitEmpName) {
        if (reqrecVos != null && reqrecVos.size() > 0) {
            List<MzyZdChargeType> mzyZdChargeTypes = mzyZdChargeTypeService.queryAllMzyZdChargeType();
            Map<String, String> chargeTypeMap = mzyZdChargeTypes.stream().collect(Collectors.toMap(MzyZdChargeType::getCode, MzyZdChargeType::getName));
            Map<String, String> employeeMap = null;
            if (YesNoEnum.YES.equals(fitEmpName)) {
                Set<String> opIds = reqrecVos.stream().filter(u -> StringUtils.isNotBlank(u.getOpId())).map(u -> u.getOpId()).collect(Collectors.toSet());
                if (opIds != null) {
                    List<Employee> employees = employeeService.queryByCodes(new ArrayList<>(opIds));
                    if (employees != null) {
                        employeeMap = employees.stream().collect(Collectors.toMap(Employee::getEmployeeCode, Employee::getEmployeeName));
                    }
                }
            }
            List<ZdChequeType> chequeTypes = zdChequeTypeService.queryAllZdChequeTypeForMz();
            Map<String, String> chequeTypeMap = chequeTypes.stream().collect(Collectors.toMap(ZdChequeType::getCode, ZdChequeType::getName));
            for (ReqrecVo ro : reqrecVos) {
                ro.setUnitCode(zdUnitCodeService.queryDeptNameByIdInCache(ro.getUnitCode()));
                ro.setChargeType(chargeTypeMap.get(ro.getChargeType()));
                ro.setCancelMark(YesNoEnum.YES.code.equals(ro.getCancelMark()) ? "退费" : "正常");
                if (YesNoEnum.YES.equals(fitEmpName)) {
                    ro.setOpId(employeeMap.get(ro.getOpId()));
                }

                if (Constants.BRZZJF_CODE.equalsIgnoreCase(ro.getOpId())) {
                    if (Constants.WX.equalsIgnoreCase(ro.getPaymode()) || Constants.BYJZ.equalsIgnoreCase(ro.getPaymode())) {
                        ro.setPaymode(Constants.ZZWX);
                    } else if (Constants.ZFB.equalsIgnoreCase(ro.getPaymode())) {
                        ro.setPaymode(Constants.ZZZFB);
                    }
                }
                ro.setPaymode(chequeTypeMap.get(ro.getPaymode()));
            }
        }
    }


    /**
     * 重打日结列表的挂号清单 已结账
     *
     * @return
     */
    @UserLoginToken
    @RequestMapping(value = "/getReqrecVoReprint", method = {RequestMethod.GET, RequestMethod.POST})
    public Map<String, Object> getReqrecVoReprint(@RequestBody ChargeFeeParamsVo chargeFeeParamsVo) {
        Map<String, Object> resultMap = new HashMap<>();
        try {
            if (chargeFeeParamsVo == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "查询重打日结列表的挂号清单失败,参数为空");
                return resultMap;
            }
            if (StringUtils.isBlank(chargeFeeParamsVo.getCaseType())) {
                chargeFeeParamsVo.setCaseType(YesNoEnum.NO.code.toString());
            }
            if (chargeFeeParamsVo.getDcountDate() == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "查询重打日结列表的挂号清单失败,结算时间为空");
                return resultMap;
            }
            resultMap.put("code", 0);
            resultMap.put("message", "查询重打日结列表的挂号清单成功");
            List<ReqrecVo> reqrecVos = chargeFeeVoService.queryReqrecVoReprint(chargeFeeParamsVo.getOpId(), chargeFeeParamsVo.getCaseType(), chargeFeeParamsVo.getDcountDate());
            frmartReQrecVo(reqrecVos, YesNoEnum.NO);
            resultMap.put("data", reqrecVos);
            return resultMap;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("查询重打日结列表的挂号清单失败，错误信息{}", e.getMessage());
            resultMap.put("code", -1);
            resultMap.put("message", "查询重打日结列表的挂号清单失败");
            return resultMap;
        }
    }


    /**
     * 费用汇总挂号清单
     *
     * @return
     */
    @UserLoginToken
    @RequestMapping(value = "/getReqrecVoCollect", method = {RequestMethod.GET, RequestMethod.POST})
    public Map<String, Object> getReqrecVoCollect(@RequestBody ChargeFeeParamsVo chargeFeeParamsVo) {
        Map<String, Object> resultMap = new HashMap<>();
        try {
            if (chargeFeeParamsVo == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "查询费用汇总挂号清单失败,参数为空");
                return resultMap;
            }
            if (chargeFeeParamsVo.getBeginDate() == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "查询费用汇总挂号清单失败,开始时间为空");
                return resultMap;
            }
            if (chargeFeeParamsVo.getEndDate() == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "查询费用汇总挂号清单失败,结束时间为空");
                return resultMap;
            }
            if (chargeFeeParamsVo.getHisData() == null) {
                chargeFeeParamsVo.setHisData(YesNoEnum.NO);
            }
            if (StringUtils.isBlank(chargeFeeParamsVo.getCaseType())) {
                chargeFeeParamsVo.setCaseType(YesNoEnum.NO.code.toString());
            }
            resultMap.put("code", 0);
            resultMap.put("message", "查询费用汇总挂号清单成功");
            List<ReqrecVo> reqrecVos = chargeFeeVoService.queryReqrecVoCollect(chargeFeeParamsVo.getHisData(), chargeFeeParamsVo.getCaseType(), chargeFeeParamsVo.getBeginDate(), chargeFeeParamsVo.getEndDate());
            frmartReQrecVo(reqrecVos, YesNoEnum.YES);
            resultMap.put("data", reqrecVos);
            return resultMap;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("查询费用汇总挂号清单失败，错误信息{}", e.getMessage());
            resultMap.put("code", -1);
            resultMap.put("message", "查询费用汇总挂号清单失败");
            return resultMap;
        }
    }


    /**
     * 收费与挂号列表导出
     *
     * @param opId        报表归属人id
     * @param type        类型  1 重打日结收费列表  2 重打日结挂号列表  3 费用汇总收费列表  4 费用汇总挂号列表
     * @param hisData     是否历史数据
     * @param dcountDate  第一个日期
     * @param dcountDate2 第二个日期
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/excelChargeFeeVoReprint", method = {RequestMethod.GET})
    public Map<String, Object> excelChargeFeeVoReprint(@RequestParam("opId") String opId, @RequestParam("type") Integer type, Integer hisData, @RequestParam("dcountDate") String dcountDate, @RequestParam("dcountDate2") String dcountDate2, HttpServletRequest request, HttpServletResponse response) {
        if (type == 1 || type == 2) {
            if (StringUtils.isBlank(opId) || StringUtils.isBlank(dcountDate)) {
                return null;
            }
            Date dcountDateD = null;
            try {
                dcountDateD = DateUtils.parseDate(dcountDate, "yyyy-MM-dd HH:mm:ss:SSS");
            } catch (ParseException e) {
                log.error("开始时间转换错误：{}", e.getMessage());
                return null;
            }
            //重打日结收费清单
            if (type == 1) {
                List<ChargeFeeVo> chargeFeeVos = chargeFeeVoService.queryChargeFeeVoReprint(opId, YesNoEnum.NO.code.toString(), dcountDateD);
                fomartChargeVo(chargeFeeVos, YesNoEnum.NO);
                ExcelUtil.exportExcelForChargeDetail(request, response, chargeFeeVos);
                return null;
            }
            //重打日结挂号清单
            List<ReqrecVo> reqrecVos = chargeFeeVoService.queryReqrecVoReprint(opId, YesNoEnum.NO.code.toString(), dcountDateD);
            frmartReQrecVo(reqrecVos, YesNoEnum.NO);
            ExcelUtil.exportExcelForReqrec(request, response, reqrecVos);
            return null;
        } else if (type == 3 || type == 4) {
            if (hisData == null || StringUtils.isBlank(dcountDate) || StringUtils.isBlank(dcountDate2)) {
                return null;
            }
            YesNoEnum yesNoEnum = YesNoEnum.getYesNoByCode(hisData);
            Date dcountDateD = null;
            try {
                dcountDateD = DateUtils.parseDate(dcountDate, "yyyy-MM-dd HH:mm:ss");
            } catch (ParseException e) {
                log.error("开始时间转换错误：{}", e.getMessage());
                return null;
            }
            Date dcountDate2D = null;
            try {
                dcountDate2D = DateUtils.parseDate(dcountDate2, "yyyy-MM-dd HH:mm:ss");
            } catch (ParseException e) {
                log.error("开始时间转换错误：{}", e.getMessage());
                return null;
            }
            if (type == 3) {
                List<ChargeFeeVo> chargeFeeVos = chargeFeeVoService.queryChargeFeeVoCollect(yesNoEnum, YesNoEnum.NO.code.toString(), dcountDateD, dcountDate2D);
                fomartChargeVo(chargeFeeVos, YesNoEnum.YES);
                ExcelUtil.exportExcelForChargeDetail(request, response, chargeFeeVos);
                return null;
            }
            List<ReqrecVo> reqrecVos = chargeFeeVoService.queryReqrecVoCollect(yesNoEnum, YesNoEnum.NO.code.toString(), dcountDateD, dcountDate2D);
            frmartReQrecVo(reqrecVos, YesNoEnum.YES);
            ExcelUtil.exportExcelForReqrec(request, response, reqrecVos);
            return null;
        }
        return null;
    }


    /**
     * 费用日结报表
     *
     * @return
     */
    @UserLoginToken
    @RequestMapping(value = "/getFullChargeUnAccount", method = {RequestMethod.GET, RequestMethod.POST})
    public Map<String, Object> getFullChargeUnAccount(HttpServletRequest httpServletRequest) {
        Map<String, Object> resultMap = new HashMap<>();
        try {
            User tokenUser = TokenUtil.getUser(httpServletRequest);
//            //数据清洗，将已经做了日结的发票数据清洗,
//            chargeFeeVoService.setPayId();
            //挂号收入构成表格数据
            ReqrecVo reqrecVo = chargeFeeVoService.queryMzReceiptSerialCount(tokenUser.getUserIdCode(), null, null, null).get(0);
            reqrecVo.fomartReqrecVo();
            resultMap.put("ghsrgcmx", reqrecVo);
            MzReceiptSerial mzReceiptSerial = chargeFeeVoService.queryMzReceiptSerial(tokenUser.getUserIdCode(), null, null, null).get(0);
            mzReceiptSerial.setCharge1(reqrecVo.getHjss());
            resultMap.put("mzReceiptSerial", mzReceiptSerial);
            ChargeCountVo chargeCountVo = chargeFeeVoService.queryChargeCountVo(tokenUser.getUserIdCode(), null, null, null).get(0);
            chargeCountVo.fomartChargeCountVo();
            resultMap.put("chargeCountVo", chargeCountVo);
            //收费所用票号
            List<ReceiptBillVo> sfReceipts = chargeFeeVoService.querySfReceiptBillVoUnAccount(tokenUser.getUserIdCode());
            //挂号所用票号
            List<ReceiptBillVo> ghReceipts = chargeFeeVoService.queryGhReceiptBillVoUnAccount(tokenUser.getUserIdCode());
            sfReceipts.addAll(ghReceipts);
            List<ReceiptBillVo> notFpList = new ArrayList<>();
            sfReceipts.forEach(s -> {
                if (s.getReceiptBill() != null && s.getReceiptBill().length() != 8) {
                    s.setReceiptBill(null);
                }
                if (s.getReceiptBill() == null || "00000000".equals(s.getReceiptBill())) {
                    notFpList.add(s);
                }
            });
            sfReceipts.removeAll(notFpList);
            Collections.sort(sfReceipts); // 按发票号排序
            List<String> receiptBills = getStrings(sfReceipts);
            resultMap.put("receiptBills", receiptBills);
            Integer sffps = chargeFeeVoService.countReceipt(tokenUser.getUserIdCode(), PayMarkEnum.CHARGED.code, null);
            Integer tpzs = chargeFeeVoService.countReceipt(tokenUser.getUserIdCode(), PayMarkEnum.RETURN_PREMIUM.code, null);
            Integer zffps = chargeFeeVoService.countReceipt(tokenUser.getUserIdCode(), PayMarkEnum.CANCELLATION.code, null);
            Integer ghfps = chargeFeeVoService.countReqrecReceipt(tokenUser.getUserIdCode(), YesNoEnum.NO.code.toString(), null, null, null);
            Integer ghtpzs = chargeFeeVoService.countReqrecReceipt(tokenUser.getUserIdCode(), YesNoEnum.YES.code.toString(), null, null, null);
            //收费发票总数
            resultMap.put("sffps", sffps + ghfps);
            //退费发票张数
            resultMap.put("tpzs", tpzs + ghtpzs);
            //作废收费发票张数
            resultMap.put("zffps", zffps);
            //收费作废发票明细
            List<ReceiptVo> sfzffpmx = chargeFeeVoService.queryReceiptVo(tokenUser.getUserIdCode(), null);
            //退号发票明细
            List<ReceiptVo> thzffpmx = chargeFeeVoService.queryThMzReceiptSerial(tokenUser.getUserIdCode(), null);
            sfzffpmx.addAll(thzffpmx);
            List<ReceiptVo> notFpGhList = new ArrayList<>();
            sfzffpmx.forEach(s -> {
                if (s.getReceiptBill() != null && s.getReceiptBill().length() != 8) {
                    s.setReceiptBill(null);
                }
                if (s.getReceiptBill() == null || "00000000".equals(s.getReceiptBill())) {
                    notFpGhList.add(s);
                }
            });
            sfzffpmx.removeAll(notFpGhList);
            Collections.sort(sfzffpmx); // 按发票号排序
            resultMap.put("zffpmx", sfzffpmx);
            resultMap.put("zizhufpmx", chargeFeeVoService.queryZiZhuReceiptVo(tokenUser.getUserIdCode(), null));
            resultMap.put("user", tokenUser);
            resultMap.put("code", 0);
            resultMap.put("message", "查询费用日结报表成功");
            return resultMap;
        } catch (MzException e) {
            log.error("查询费用日结报表失败，错误信息{}", e);
            resultMap.put("code", -1);
            resultMap.put("message", "查询费用日结报表失败");
            return resultMap;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("查询费用日结报表失败，错误信息{}", e.getMessage());
            resultMap.put("code", -1);
            resultMap.put("message", "查询费用日结报表失败");
            return resultMap;
        }
    }


    /**
     * 重打费用日结报表
     *
     * @return
     */
    @UserLoginToken
    @RequestMapping(value = "/getFullChargeReprint", method = {RequestMethod.GET, RequestMethod.POST})
    public Map<String, Object> getFullChargeReprint(@RequestBody ChargeFeeParamsVo chargeFeeParamsVo) {
        Map<String, Object> resultMap = new HashMap<>();
        try {
            if (chargeFeeParamsVo == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "查询重打费用日结报表失败,参数为空");
                return resultMap;
            }
            if (StringUtils.isBlank(chargeFeeParamsVo.getCaseType())) {
                chargeFeeParamsVo.setCaseType(YesNoEnum.NO.code.toString());
            }
            if (chargeFeeParamsVo.getDcountDate() == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "查询重打费用日结报表失败,结算时间为空");
                return resultMap;
            }
            //数据清洗，将在老系统日结的数据清洗一次
            //      chargeFeeVoService.refeshPayManData(chargeFeeParamsVo.getOpId(), chargeFeeParamsVo.getDcountDate());
            //门诊部日结没有设置收费人id ，需要清洗
            chargeFeeVoService.modifyMzService();
            User tokenUser = userService.queryUserByUserIdCode(chargeFeeParamsVo.getOpId());
            resultMap.put("user", tokenUser);
            //挂号收入构成表格数据
            ReqrecVo reqrecVo = chargeFeeVoService.queryMzReceiptSerialCount(chargeFeeParamsVo.getOpId(), chargeFeeParamsVo.getDcountDate(), null, null).get(0);
            reqrecVo.fomartReqrecVo();
            resultMap.put("ghsrgcmx", reqrecVo);
            MzReceiptSerial mzReceiptSerial = chargeFeeVoService.queryMzReceiptSerial(chargeFeeParamsVo.getOpId(), chargeFeeParamsVo.getDcountDate(), null, null).get(0);
            mzReceiptSerial.setCharge1(reqrecVo.getHjss());
            resultMap.put("mzReceiptSerial", mzReceiptSerial);
            ChargeCountVo chargeCountVo = chargeFeeVoService.queryChargeCountVo(chargeFeeParamsVo.getOpId(), chargeFeeParamsVo.getDcountDate(), null, null).get(0);
            chargeCountVo.fomartChargeCountVo();
            resultMap.put("chargeCountVo", chargeCountVo);
            //收费所用票号
            List<ReceiptBillVo> sfReceipts = chargeFeeVoService.querySfReceiptBillVoReprint(chargeFeeParamsVo.getOpId(), chargeFeeParamsVo.getDcountDate());
            //挂号所用票号
            List<ReceiptBillVo> ghReceipts = chargeFeeVoService.queryGhReceiptBillVoReprint(chargeFeeParamsVo.getOpId(), chargeFeeParamsVo.getDcountDate());
            sfReceipts.addAll(ghReceipts);
            List<ReceiptBillVo> notFpList = new ArrayList<>();
            sfReceipts.forEach(s -> {
                if (s.getReceiptBill() != null && s.getReceiptBill().length() != 8) {
                    s.setReceiptBill(null);
                }
                if (s.getReceiptBill() == null || "00000000".equals(s.getReceiptBill())) {
                    notFpList.add(s);
                }
            });
            sfReceipts.removeAll(notFpList);
            Collections.sort(sfReceipts); // 按发票号排序
            List<String> receiptBills = getStrings(sfReceipts);
            resultMap.put("receiptBills", receiptBills);
            //收费发票张数
            Integer sffps = chargeFeeVoService.countReceipt(chargeFeeParamsVo.getOpId(), PayMarkEnum.CHARGED.code, chargeFeeParamsVo.getDcountDate());
            //退费发票张数
            Integer tpzs = chargeFeeVoService.countReceipt(chargeFeeParamsVo.getOpId(), PayMarkEnum.RETURN_PREMIUM.code, chargeFeeParamsVo.getDcountDate());
            //作废收费发票张数
            Integer zffps = chargeFeeVoService.countReceipt(chargeFeeParamsVo.getOpId(), PayMarkEnum.CANCELLATION.code, chargeFeeParamsVo.getDcountDate());
            //挂号发票张数
            Integer ghfps = chargeFeeVoService.countReqrecReceipt(chargeFeeParamsVo.getOpId(), YesNoEnum.NO.code.toString(), chargeFeeParamsVo.getDcountDate(), null, null);
            //退号发票张数
            Integer ghtpzs = chargeFeeVoService.countReqrecReceipt(chargeFeeParamsVo.getOpId(), YesNoEnum.YES.code.toString(), chargeFeeParamsVo.getDcountDate(), null, null);
            //收费发票总数
            resultMap.put("sffps", sffps + ghfps);
            //退费发票张数
            resultMap.put("tpzs", tpzs + ghtpzs);
            //作废收费发票张数
            resultMap.put("zffps", zffps);
            //收费作废发票明细
            List<ReceiptVo> sfzffpmx = chargeFeeVoService.queryReceiptVo(chargeFeeParamsVo.getOpId(), chargeFeeParamsVo.getDcountDate());
            //退号发票明细
            List<ReceiptVo> thzffpmx = chargeFeeVoService.queryThMzReceiptSerial(chargeFeeParamsVo.getOpId(), chargeFeeParamsVo.getDcountDate());
            sfzffpmx.addAll(thzffpmx);
            List<ReceiptVo> notFpGhList = new ArrayList<>();
            sfzffpmx.forEach(s -> {
                if (s.getReceiptBill() != null && s.getReceiptBill().length() != 8) {
                    s.setReceiptBill(null);
                }
                if (s.getReceiptBill() == null || "00000000".equals(s.getReceiptBill())) {
                    notFpGhList.add(s);
                }
            });
            sfzffpmx.removeAll(notFpGhList);
            Collections.sort(sfzffpmx); // 按发票号排序
            resultMap.put("zffpmx", sfzffpmx);
            resultMap.put("zizhufpmx", chargeFeeVoService.queryZiZhuReceiptVo(chargeFeeParamsVo.getOpId(), chargeFeeParamsVo.getDcountDate()));
            resultMap.put("code", 0);
            resultMap.put("message", "查询重打费用日结报表成功");
            return resultMap;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("查询重打费用日结报表失败，错误信息{}", e.getMessage());
            resultMap.put("code", -1);
            resultMap.put("message", "查询重打费用日结报表失败");
            return resultMap;
        }
    }


    /**
     * 费用汇总报表
     *
     * @return
     */
    @UserLoginToken
    @RequestMapping(value = "/getFullChargeCollect", method = {RequestMethod.GET, RequestMethod.POST})
    public Map<String, Object> getFullChargeCollect(@RequestBody ChargeFeeParamsVo chargeFeeParamsVo, HttpServletRequest httpServletRequest) {
        Map<String, Object> resultMap = new HashMap<>();
        try {
            // User tokenUser = TokenUtil.getUser(httpServletRequest);
            if (chargeFeeParamsVo == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "查询费用汇总报表失败,参数为空");
                return resultMap;
            }
            if (StringUtils.isBlank(chargeFeeParamsVo.getCaseType())) {
                chargeFeeParamsVo.setCaseType(YesNoEnum.NO.code.toString());
            }
            if (chargeFeeParamsVo.getBeginDate() == null || chargeFeeParamsVo.getEndDate() == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "查询费用汇总报表失败,查询时间为空");
                return resultMap;
            }
            //门诊部日结没有设置收费人id ，需要清洗
            chargeFeeVoService.modifyMzService();
            //挂号收入构成表格数据
            ReqrecVo reqrecVo = chargeFeeVoService.queryMzReceiptSerialCount(null, null, chargeFeeParamsVo.getBeginDate(), chargeFeeParamsVo.getEndDate()).get(0);
            reqrecVo.fomartReqrecVo();
            resultMap.put("ghsrgcmx", reqrecVo);
            MzReceiptSerial mzReceiptSerial = chargeFeeVoService.queryMzReceiptSerial(null, null, chargeFeeParamsVo.getBeginDate(), chargeFeeParamsVo.getEndDate()).get(0);
            mzReceiptSerial.setCharge1(reqrecVo.getHjss());
            resultMap.put("mzReceiptSerial", mzReceiptSerial);
            ChargeCountVo chargeCountVo = chargeFeeVoService.queryChargeCountVo(null, null, chargeFeeParamsVo.getBeginDate(), chargeFeeParamsVo.getEndDate()).get(0);
            chargeCountVo.fomartChargeCountVo();
            resultMap.put("chargeCountVo", chargeCountVo);
            List<WorkloadVo> ghWorkloadVos = chargeFeeVoService.queryGhWorkloadVo(chargeFeeParamsVo.getHisData(), chargeFeeParamsVo.getBeginDate(), chargeFeeParamsVo.getEndDate(), null, YesNoEnum.YES);
            frmartWorkloadVo(ghWorkloadVos);
            resultMap.put("ghWorkloadVos", ghWorkloadVos);
            List<WorkloadVo> sfWorkloadVos = chargeFeeVoService.querySfWorkloadVo(chargeFeeParamsVo.getHisData(), chargeFeeParamsVo.getBeginDate(), chargeFeeParamsVo.getEndDate(), null, YesNoEnum.YES);
            frmartWorkloadVo(sfWorkloadVos);
            resultMap.put("sfWorkloadVos", sfWorkloadVos);
            //resultMap.put("user", tokenUser);
            resultMap.put("code", 0);
            resultMap.put("message", "查询费用汇总报表成功");
            return resultMap;
        }
//        catch (MzException e) {
//            log.error("查询费用汇总报表失败，错误信息{}", e.getMessage());
//            resultMap.put("code", -1);
//            resultMap.put("message", "查询费用汇总报表失败");
//            return resultMap;
//        }
        catch (Exception e) {
            e.printStackTrace();
            log.error("查询费用汇总报表失败，错误信息{}", e.getMessage());
            resultMap.put("code", -1);
            resultMap.put("message", "查询费用汇总报表失败");
            return resultMap;
        }
    }


    /**
     * 收费员挂号与收费工作量统计
     *
     * @return
     */
    @UserLoginToken
    @RequestMapping(value = "/getCasherWorkCount", method = {RequestMethod.GET, RequestMethod.POST})
    public Map<String, Object> getCasherWorkCount(@RequestBody ChargeFeeParamsVo chargeFeeParamsVo) {
        Map<String, Object> resultMap = new HashMap<>();
        try {
            if (chargeFeeParamsVo == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "收费员挂号与收费工作量统计失败,参数为空");
                return resultMap;
            }
            if (StringUtils.isBlank(chargeFeeParamsVo.getOpId())) {
                chargeFeeParamsVo.setOpId(null);
            }
            if (chargeFeeParamsVo.getBeginDate() == null || chargeFeeParamsVo.getEndDate() == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "收费员挂号与收费工作量统计失败,查询时间为空");
                return resultMap;
            }
            List<WorkloadVo> ghWorkloadVos = chargeFeeVoService.queryGhWorkloadVo(chargeFeeParamsVo.getHisData(), chargeFeeParamsVo.getBeginDate(), chargeFeeParamsVo.getEndDate(), chargeFeeParamsVo.getOpId(), null);
            frmartWorkloadVo(ghWorkloadVos);
            List<WorkloadVo> sfWorkloadVos = chargeFeeVoService.querySfWorkloadVo(chargeFeeParamsVo.getHisData(), chargeFeeParamsVo.getBeginDate(), chargeFeeParamsVo.getEndDate(), chargeFeeParamsVo.getOpId(), null);
            frmartWorkloadVo(sfWorkloadVos);
            List<Map<String, Object>> resultList = new ArrayList<>();
            Map<String, Map<String, Object>> allMap = new HashMap<>();
            for (WorkloadVo workloadVo : ghWorkloadVos) {
                if(workloadVo.getOpId()==null){
                    continue;
                }
                Map<String, Object> temp = new HashMap<>();
                temp.put("opId", workloadVo.getOpId());
                temp.put("opName", workloadVo.getOpName());
                temp.put("ghCount", workloadVo.getPtCount());
                temp.put("ghAmount", workloadVo.getPtAmount());
                temp.put("thCount", workloadVo.getThCount());
                temp.put("thAmount", workloadVo.getThAmount());
                resultList.add(temp);
                allMap.put(workloadVo.getOpId(), temp);
            }
            for (WorkloadVo workloadVo : sfWorkloadVos) {
                if(workloadVo.getOpId()==null){
                    continue;
                }
                Map<String, Object> temp = allMap.get(workloadVo.getOpId());
                if (temp == null) {
                    temp = new HashMap<>();
                    resultList.add(temp);
                    allMap.put(workloadVo.getOpId(), temp);
                    temp.put("opId", workloadVo.getOpId());
                    temp.put("opName", workloadVo.getOpName());
                }
                temp.put("sfCount", workloadVo.getPtCount());
                temp.put("sfAmount", workloadVo.getPtAmount());
                temp.put("tfCount", workloadVo.getThCount());
                temp.put("tfAmount", workloadVo.getThAmount());
            }
            resultMap.put("code", 0);
            resultMap.put("message", "收费员挂号与收费工作量统计成功");
            resultMap.put("data", resultList);
            return resultMap;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("收费员挂号与收费工作量统计失败，错误信息{}", e.getMessage());
            resultMap.put("code", -1);
            resultMap.put("message", "收费员挂号与收费工作量统计失败");
            return resultMap;
        }
    }


    private void frmartWorkloadVo(List<WorkloadVo> workloadVos) {
        if (workloadVos != null && workloadVos.size() > 0) {
            WorkloadVo totalWorkloadVo = new WorkloadVo();
            Map<String, String> employeeMap = null;
            Set<String> opIds = workloadVos.stream().filter(u -> StringUtils.isNotBlank(u.getOpId())).map(u -> u.getOpId()).collect(Collectors.toSet());
            if (opIds != null) {
                List<Employee> employees = employeeService.queryByCodes(new ArrayList<>(opIds));
                if (employees != null) {
                    employeeMap = employees.stream().collect(Collectors.toMap(Employee::getEmployeeCode, Employee::getEmployeeName));
                }
            }
            for (WorkloadVo wo : workloadVos) {
                wo.setOpName(employeeMap.get(wo.getOpId()));
                if (totalWorkloadVo.getPtCount() == null) {
                    totalWorkloadVo.setPtCount(wo.getPtCount());
                } else {
                    totalWorkloadVo.setPtCount(totalWorkloadVo.getPtCount() + wo.getPtCount());
                }

                if (totalWorkloadVo.getThCount() == null) {
                    totalWorkloadVo.setThCount(wo.getThCount());
                } else {
                    totalWorkloadVo.setThCount(totalWorkloadVo.getThCount() + wo.getThCount());
                }

                if (totalWorkloadVo.getPtAmount() == null) {
                    totalWorkloadVo.setPtAmount(wo.getPtAmount());
                } else {
                    totalWorkloadVo.setPtAmount(totalWorkloadVo.getPtAmount().add(wo.getPtAmount()));
                }

                if (totalWorkloadVo.getThAmount() == null) {
                    totalWorkloadVo.setThAmount(wo.getThAmount());
                } else {
                    totalWorkloadVo.setThAmount(totalWorkloadVo.getThAmount().add(wo.getThAmount()));
                }

                if (totalWorkloadVo.getTotalAmount() == null) {
                    totalWorkloadVo.setTotalAmount(wo.getTotalAmount());
                } else {
                    totalWorkloadVo.setTotalAmount(totalWorkloadVo.getTotalAmount().add(wo.getTotalAmount()));
                }
            }
            workloadVos.add(totalWorkloadVo);
        }
    }


    /**
     * 将发票号转成字符串形式
     *
     * @param sfReceiptBills
     * @return
     */
    private List<String> getStrings(List<ReceiptBillVo> sfReceiptBills) {
        List<String> temp = new ArrayList<>();
        String lastReceiptBill = null;
        String tempBill = null;
        for (ReceiptBillVo rb : sfReceiptBills) {
            if (StringUtils.isBlank(rb.getReceiptBill())) {
                continue;
            }
            if (lastReceiptBill == null) {
                tempBill = rb.getReceiptBill();
                lastReceiptBill = rb.getReceiptBill();
            } else if (Long.valueOf(lastReceiptBill) + 1 < Long.valueOf(rb.getReceiptBill())) {
                temp.add(tempBill + "--" + lastReceiptBill);
                tempBill = rb.getReceiptBill();
                lastReceiptBill = rb.getReceiptBill();
            } else if (Long.valueOf(lastReceiptBill) + 1 == Long.valueOf(rb.getReceiptBill())) {
                lastReceiptBill = rb.getReceiptBill();
            }
        }
        if (tempBill != null && lastReceiptBill != null) {
            temp.add(tempBill + "--" + lastReceiptBill);
        }
        return temp;
    }


    /**
     * 日报结算
     *
     * @return
     */
    @UserLoginToken
    @RequestMapping(value = "/dcountCharge", method = {RequestMethod.GET, RequestMethod.POST})
    public Map<String, Object> dcountCharge(HttpServletRequest httpServletRequest) {
        Map<String, Object> resultMap = new HashMap<>();
        try {
            User tokenUser = TokenUtil.getUser(httpServletRequest);
            Integer count = chargeFeeVoService.queryCountCanDaily(tokenUser.getUserIdCode());
            if (count == null || count == 0) {
                resultMap.put("code", -1);
                resultMap.put("message", "费用结算失败，无可结算费用");
                return resultMap;
            }
            count = chargeFeeVoService.queryTFWDFPCount(tokenUser.getUserIdCode());
            if (count > 0) {
                resultMap.put("code", -1);
                resultMap.put("message", "存在退费后发票未重打的发票信息，请 处理后再结账！");
                return resultMap;
            }
            Date dcountDate = chargeFeeVoService.dcountCharge(tokenUser.getUserIdCode());
            resultMap.put("dcountDate", dcountDate);
            //resultMap.put("dcountDate", new Date());
            resultMap.put("code", 0);
            resultMap.put("message", "费用结算成功");
            return resultMap;
        } catch (MzException e) {
            log.error("费用结算失败，错误信息{}", e);
            resultMap.put("code", -1);
            resultMap.put("message", "费用结算失败");
            return resultMap;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("费用结算失败，错误信息{}", e.getMessage());
            resultMap.put("code", -1);
            resultMap.put("message", "费用结算失败");
            return resultMap;
        }
    }


    /**
     * 查询给定日期内收费员列表
     *
     * @return
     */
    @UserLoginToken
    @RequestMapping(value = "/getAllOperator", method = {RequestMethod.GET, RequestMethod.POST})
    public Map<String, Object> getAllOperator(@RequestBody ChargeFeeParamsVo chargeFeeParamsVo) {
        Map<String, Object> resultMap = new HashMap<>();
        try {
            if (chargeFeeParamsVo == null || chargeFeeParamsVo.getBeginDate() == null || chargeFeeParamsVo.getEndDate() == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "查询给定日期内收费员列表失败，给定时间不能为空");
                return resultMap;
            }
            Date beginDate = chargeFeeParamsVo.getBeginDate();
            Date endDate = chargeFeeParamsVo.getEndDate();
            List<String> operaotors = chargeFeeVoService.queryAllOperatorFromReceipt(beginDate, endDate);
            List<String> ghOperaotors = chargeFeeVoService.queryAllOperatorFromReqrec(beginDate, endDate);
            ghOperaotors.forEach(o -> {
                if (!operaotors.contains(o)) {
                    operaotors.add(o);
                }
            });
            List<Employee> employees = employeeService.queryByCodes(operaotors);
            resultMap.put("employees", employees);
            resultMap.put("code", 0);
            resultMap.put("message", "查询给定日期内收费员列表成功");
            return resultMap;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("查询给定日期内收费员列表失败，错误信息{}", e.getMessage());
            resultMap.put("code", -1);
            resultMap.put("message", "查询给定日期内收费员列表失败");
            return resultMap;
        }
    }


    /**
     * 查询可以被重打结算列表用户与日期列表
     *
     * @return
     */
    @UserLoginToken
    @RequestMapping(value = "/getDcountDateList", method = {RequestMethod.GET, RequestMethod.POST})
    public Map<String, Object> getDcountDateList(@RequestBody ChargeFeeParamsVo chargeFeeParamsVo) {
        Map<String, Object> resultMap = new HashMap<>();
        try {
            if (chargeFeeParamsVo == null || chargeFeeParamsVo.getBeginDate() == null || chargeFeeParamsVo.getEndDate() == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "查询可以被重打结算列表用户与日期列表失败，给定时间不能为空");
                return resultMap;
            }
            if (StringUtils.isBlank(chargeFeeParamsVo.getOpId())) {
                resultMap.put("code", -1);
                resultMap.put("message", "查询可以被重打结算列表用户与日期列表失败，请选择要查询的收费员");
                return resultMap;
            }
            Date beginDate = DateUtil.getFirstSecond(chargeFeeParamsVo.getBeginDate());
            Date endDate = DateUtil.getLastSecond(chargeFeeParamsVo.getEndDate());
            List<DcountDateListVo> dcountDateListVos = chargeFeeVoService.queryDcountDateList(chargeFeeParamsVo.getOpId(), beginDate, endDate);
            resultMap.put("dcountDateListVos", dcountDateListVos);
            resultMap.put("code", 0);
            resultMap.put("message", "查询可以被重打结算列表用户与日期列表成功");
            return resultMap;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("查询可以被重打结算列表用户与日期列表失败，错误信息{}", e.getMessage());
            resultMap.put("code", -1);
            resultMap.put("message", "查询可以被重打结算列表用户与日期列表失败");
            return resultMap;
        }
    }


    /**
     * 查询门诊收费明细
     *
     * @return
     */
    @UserLoginToken
    @RequestMapping(value = "/getThmzmxsr", method = {RequestMethod.POST})
    public Map<String, Object> getThmzmxsr(@RequestBody ThmzmxsrParamsVo thmzmxsrParamsVo) {
        Map<String, Object> resultMap = new HashMap<>();
        try {
            if (thmzmxsrParamsVo == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "查询日结列表收费清单失败,参数为空");
                return resultMap;
            }
            if (thmzmxsrParamsVo.getBeginDate() == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "查询门诊收费明细失败,开始时间为空");
                return resultMap;
            }
            if (thmzmxsrParamsVo.getEndDate() == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "查询门诊收费明细失败,结束时间为空");
                return resultMap;
            }
            if (thmzmxsrParamsVo.getPageSize() == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "查询门诊收费明细失败,每页显示数据大小不能为空");
                return resultMap;
            }
            List<MzPatientMi> mzPatientMis = mzPatientMiService.queryByCommonParams(thmzmxsrParamsVo.getCommonParams());
            if (mzPatientMis != null && mzPatientMis.size() > 0) {
                List<String> patientIds = mzPatientMis.stream().filter(m -> StringUtils.isNotBlank(m.getPatientId())).map(m -> m.getPatientId()).collect(Collectors.toList());
                if (patientIds != null && patientIds.size() > 0) {
                    thmzmxsrParamsVo.setPatientIds(patientIds);
                }
            }
            if (StringUtils.isBlank(thmzmxsrParamsVo.getCaseType())) {
                thmzmxsrParamsVo.setCaseType(YesNoEnum.NO.code.toString());
            }
            if (StringUtils.isBlank(thmzmxsrParamsVo.getJzSqDept())) {
                thmzmxsrParamsVo.setJzSqDept(null);
            }
            if (StringUtils.isBlank(thmzmxsrParamsVo.getJzSqDoctor())) {
                thmzmxsrParamsVo.setJzSqDoctor(null);
            }
            if (StringUtils.isBlank(thmzmxsrParamsVo.getExecDept())) {
                thmzmxsrParamsVo.setExecDept(null);
            }
            if (StringUtils.isBlank(thmzmxsrParamsVo.getHsm())) {
                thmzmxsrParamsVo.setHsm(null);
            }
            if (StringUtils.isBlank(thmzmxsrParamsVo.getParentCode())) {
                thmzmxsrParamsVo.setParentCode(null);
            }
            if (StringUtils.isBlank(thmzmxsrParamsVo.getXmm())) {
                thmzmxsrParamsVo.setXmm(null);
            }
            resultMap.put("code", 0);
            resultMap.put("message", "查询门诊收费明细成功");
            List<Mzmxsr> mzmxsrs=mzmxsrService.queryMzmxsrWithPage(thmzmxsrParamsVo);
            fomartThmzmxsr(mzmxsrs);
            resultMap.put("data", mzmxsrs);
            Integer total =thmzmxsrParamsVo.getTotal();
            if(total<0){
                total=mzmxsrService.queryCountMzmxsr(thmzmxsrParamsVo);
            }
            resultMap.put("total", total);
            BigDecimal amount=thmzmxsrParamsVo.getAmount();
            if(amount==null){
                amount=mzmxsrService.querySumAmount(thmzmxsrParamsVo);
            }
            resultMap.put("totalAmount",amount==null?BigDecimal.ZERO:amount .setScale(2, BigDecimal.ROUND_FLOOR));
            return resultMap;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("查询门诊收费明细失败，错误信息{}", e.getMessage());
            resultMap.put("code", -1);
            resultMap.put("message", "查询门诊收费明细失败");
            return resultMap;
        }
    }


    private void fomartThmzmxsr(List<Mzmxsr> mzmxsrs) {
        Map<String, String> mzBillItemMap = null;
        Map<String, String> employeeMap = null;
        if (mzmxsrs != null && mzmxsrs.size() > 0) {
            List<BillItem> mzBillItems = mzBillItemService.queryZyBillItem();
            if (mzBillItems != null) {
                mzBillItemMap = mzBillItems.stream().collect(Collectors.toMap(BillItem::getCode, BillItem::getName));
            }
            List<Employee> employees = employeeService.queryAll();
            if (employees != null) {
                employeeMap = employees.stream().collect(Collectors.toMap(Employee::getEmployeeCode, Employee::getEmployeeName));
            }
        }
        if (mzmxsrs != null && mzmxsrs.size() > 0) {
            for (Mzmxsr mzmxsr : mzmxsrs) {
                getBigDecimal(mzBillItemMap, employeeMap, mzmxsr);
            }
        }
    }

    private void getBigDecimal(Map<String, String> mzBillItemMap, Map<String, String> employeeMap, Mzmxsr mzmxsr) {
        if (mzBillItemMap != null) {
            mzmxsr.setParentCode(mzBillItemMap.get(mzmxsr.getParentCode()));
        }
        mzmxsr.setJzSqDept(zdUnitCodeService.queryDeptNameByIdInCache(mzmxsr.getJzSqDept()));
        mzmxsr.setExecDept(zdUnitCodeService.queryDeptNameByIdInCache(mzmxsr.getExecDept()));
        String jzSqDoctor = mzmxsr.getJzSqDoctor();
        if (StringUtils.isNotBlank(jzSqDoctor)) {
            jzSqDoctor = jzSqDoctor.trim();
        }
        mzmxsr.setJzSqDoctor(employeeMap.get(jzSqDoctor));
        BigDecimal price =mzmxsr.getPrice();
        if (price == null) {
            price = BigDecimal.ZERO;
        }
        mzmxsr.setPrice(price.setScale(2, BigDecimal.ROUND_FLOOR));
    }


    /**
     * 门诊收入明细导出
     *
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/excelThmzmxsr", method = {RequestMethod.GET})
    public Map<String, Object> excelThmzmxsr(@RequestParam("commonParams") String commonParams, @RequestParam("caseType") String caseType, @RequestParam("beginDate") String beginDate,
                                             @RequestParam("endDate") String endDate, @RequestParam("jzSqDept") String jzSqDept, @RequestParam("jzSqDoctor") String jzSqDoctor,
                                             @RequestParam("execDept") String execDept, @RequestParam("hsm") String hsm,
                                             @RequestParam("parentCode") String parentCode, @RequestParam("xmm") String xmm,@RequestParam("pageSize") String pageSize, HttpServletRequest request, HttpServletResponse response) {

        if (StringUtils.isBlank(caseType)) {
            caseType = YesNoEnum.NO.code.toString();
        }
        if (StringUtils.isBlank(jzSqDept)) {
            jzSqDept = null;
        }
        if (StringUtils.isBlank(jzSqDoctor)) {
            jzSqDoctor = null;
        }
        if (StringUtils.isBlank(execDept)) {
            execDept = null;
        }
        if (StringUtils.isBlank(hsm)) {
            hsm = null;
        }
        if (StringUtils.isBlank(parentCode)) {
            parentCode = null;
        }
        if (StringUtils.isBlank(xmm)) {
            xmm = null;
        }
        Map<String, Object> resultMap = new HashMap<>();
        ThmzmxsrParamsVo thmzmxsrParamsVo = new ThmzmxsrParamsVo();
        thmzmxsrParamsVo.setCommonParams(commonParams);
        thmzmxsrParamsVo.setCaseType(caseType);
        thmzmxsrParamsVo.setBeginDate(DateUtil.pase(beginDate, "yyyy-MM-dd HH:mm:ss"));
        thmzmxsrParamsVo.setEndDate(DateUtil.pase(endDate, "yyyy-MM-dd HH:mm:ss"));
        thmzmxsrParamsVo.setJzSqDept(jzSqDept);
        thmzmxsrParamsVo.setJzSqDoctor(jzSqDoctor);
        thmzmxsrParamsVo.setExecDept(execDept);
        thmzmxsrParamsVo.setHsm(hsm);
        thmzmxsrParamsVo.setParentCode(parentCode);
        thmzmxsrParamsVo.setXmm(xmm);
        thmzmxsrParamsVo.setOffset(0);
        if(DateTimeUtils.periodDays(DateTimeUtils.date2LocalDate(thmzmxsrParamsVo.getBeginDate()), DateTimeUtils.date2LocalDate(thmzmxsrParamsVo.getEndDate()))>180){
            resultMap.put("code", -1);
            resultMap.put("message", "查询门诊收费明细失败,时间跨度不能大于六个月");
            return resultMap;
        }
        Integer total =Integer.valueOf(pageSize);
        if(total<0){
            total=mzmxsrService.queryCountMzmxsr(thmzmxsrParamsVo);
        }
        thmzmxsrParamsVo.setPageSize(total);
        List<MzPatientMi> mzPatientMis = mzPatientMiService.queryByCommonParams(commonParams);
        if (mzPatientMis != null && mzPatientMis.size() > 0) {
            List<String> patientIds = mzPatientMis.stream().filter(m -> StringUtils.isNotBlank(m.getPatientId())).map(m -> m.getPatientId()).collect(Collectors.toList());
            if (patientIds != null && patientIds.size() > 0) {
                thmzmxsrParamsVo.setPatientIds(patientIds);
            }
        }
        List<Mzmxsr> mzmxsrs=mzmxsrService.queryMzmxsrWithPage(thmzmxsrParamsVo);
        fomartThmzmxsr(mzmxsrs);
        ExcelUtil.exportExcelForThmzmxsrs(request, response, mzmxsrs);
        return null;
    }




    /**
     * 查询费用不一致接口
     *
     * @return
     */
    @RequestMapping(value = "/getDiff", method = {RequestMethod.GET})
    public Map<String, Object> getDiff(@RequestParam("beginDate") String beginDate,@RequestParam("endDate") String endDate) {
        List<String> mzPatientIds = mzmxsrService.queryAllPatientId(beginDate,endDate);
        if (mzPatientIds != null && mzPatientIds.size() > 0) {
            ThmzmxsrParamsVo thmzmxsrParamsVo = new ThmzmxsrParamsVo();
            thmzmxsrParamsVo.setCaseType(YesNoEnum.NO.code.toString());
            thmzmxsrParamsVo.setBeginDate(DateUtil.pase(beginDate, "yyyy-MM-dd HH:mm:ss"));
            thmzmxsrParamsVo.setEndDate(DateUtil.pase(endDate, "yyyy-MM-dd HH:mm:ss"));
            thmzmxsrParamsVo.setOffset(0);
            for (String str :mzPatientIds){
                thmzmxsrParamsVo.setPatientIds(Arrays.asList(str));
                BigDecimal amount=mzmxsrService.querySumAmount(thmzmxsrParamsVo).setScale(1, BigDecimal.ROUND_HALF_UP);
                BigDecimal fpAmount= mzReceiptSerialService.querySumByPatientId(beginDate,endDate,str).setScale(1, BigDecimal.ROUND_HALF_UP);
                if(amount.compareTo(fpAmount)!=0){
                    log.info("--------------费用明细统计金额 {}，发票金额 {}，病人id {}-----------------",amount,fpAmount,str);
                }
            }
            System.out.println("计算结束");
        }
        return null;
    }



}
