package thyyxxk.webserver.service.executeItem;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import thyyxxk.webserver.config.exception.ExceptionEnum;
import thyyxxk.webserver.dao.his.executeItem.GenerateYzDao;
import thyyxxk.webserver.dao.his.executeItem.YzActOccDao;
import thyyxxk.webserver.dao.his.executeItem.YzYpZyOrderDao;
import thyyxxk.webserver.dao.his.executeItem.YzZyPatientFeeDao;
import thyyxxk.webserver.dao.his.medicine.YpZdGroupNameDao;
import thyyxxk.webserver.entity.ResultVo;
import thyyxxk.webserver.entity.datamodify.YzActOrder;
import thyyxxk.webserver.entity.executeItem.*;
import thyyxxk.webserver.entity.inpatient.ZyActpatient;
import thyyxxk.webserver.entity.medicaladvice.medicamanage.common.YzSequence;
import thyyxxk.webserver.entity.medicaladvice.medicamanage.drugmanage.PageClassEnum;
import thyyxxk.webserver.entity.medicine.YpZdDictVo;
import thyyxxk.webserver.entity.medicine.YpZdGroupName;
import thyyxxk.webserver.service.medicaladvice.common.MedicalCommonService;
import thyyxxk.webserver.utils.*;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Description:
 * @Author:lihong
 * @Date: 2024/1/8
 */
@Service
@Slf4j
public class GenerateYzService {
    @Resource
    private GenerateYzDao dao;
    @Resource
    private YzActOccDao yzActOccDao;
    @Resource
    private YzYpZyOrderDao yzYpZyOrderDao;
    @Resource
    private YzZyPatientFeeDao yzZyPatientFeeDao;
    @Resource
    private MedicalCommonService medicalCommonService;
    @Resource
    YpZdGroupNameDao ypZdGroupNameDao;

    private static final String prefixWeek = "week";
    private static final String prefixDay = "day";
    private static final String KF = "d";
    private static final String DSY = "i";
    private static final String ZCY = "z";
    //自备药
    private static final String ZBY = "b";
    private static final String FREQ_CODE_ONCE = "ONCE";

    public List<ZyActpatient> queryGenerateYzList(String wardCode) {
        AssertUtil.isnotBlank(wardCode, "病室编码不能为空");
        List<ZyActpatient> list = dao.selectGenerateYzList(wardCode);
        CommonUtil.BeanTrim(list);
        return list;
    }

    private static long betweenDay(Date beginDate, Date endDate, boolean isReset,boolean isAbs){
        if (isReset) {
            beginDate = DateUtil.beginOfDay(beginDate);
            endDate = DateUtil.beginOfDay(endDate);
        }
        return DateUtil.between(beginDate, endDate, DateUnit.DAY,isAbs);
    }

    @Transactional(rollbackFor = Exception.class)
    public ResultVo<Set<String>> generateYpOrZl(GenerateYzVo param) {
        //这里只查前后两天的
        Date now = new Date();
        AssertUtil.isnotBlank(param.getWardCode(), "病室不能为空");
        AssertUtil.isnotBlank(param.getYzDate(), "医嘱时间不能为空");
        AssertUtil.isnotBlank(param.getZyActpatients(), "请选择病人");
        AssertUtil.isnotBlank(param.getYpOrZlFlag(), "请选择生成药品或诊疗");
        if (betweenDay(DateUtil.parseDate(param.getYzDate()), now, true,false) > 7) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "最多只能生成7天前的医嘱");
        }
        if (betweenDay(now, DateUtil.parseDate(param.getYzDate()), true,false) >= 1) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "医嘱日期不能大于明天日期!");
        }
        String startTime = DateUtil.formatDate(DateUtil.offsetDay(DateUtil.parseDate(param.getYzDate()), -2)) + " 00:00:00";
        String endTime = DateUtil.formatDate(DateUtil.offsetDay(DateUtil.parseDate(param.getYzDate()), 2)) + " 23:59:59";
        param.setStartTime(startTime);
        param.setEndTime(endTime);
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("dept_code", param.getWardCode());
        queryWrapper.eq("ward_code", param.getWardCode());
        queryWrapper.ge("occ_time", param.getStartTime());
        queryWrapper.le("occ_time", param.getEndTime());
        List<YzActOcc> yzActOccs = yzActOccDao.selectList(queryWrapper);
        List<YzZyPatientFee> yzZyPatientFees = yzZyPatientFeeDao.selectList(queryWrapper);
        List<YzYpZyOrder> yzYpZyOrders = yzYpZyOrderDao.selectList(queryWrapper);
        param.setCheckYzActOccs(yzActOccs);
        param.setCheckYzYpZyOrders(yzYpZyOrders);
        param.setCheckYzZyPatientFees(yzZyPatientFees);
        //已选择生成医嘱的病人
        List<ZyActpatient> zyActpatients = param.getZyActpatients();
        List<YzActOrder> yzActOrderList;
        //科室所有的药品和诊疗医嘱数据
        if (NumberEnum.ONE.getCode().equals(param.getYpOrZlFlag())) {
            yzActOrderList = dao.selectYpYz(param.getWardCode());
        } else {
            yzActOrderList = dao.selectZlYz(param.getWardCode());
        }
        if (CollUtil.isEmpty(yzActOrderList)) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "没有可以生成的医嘱");
        }
        CommonUtil.BeanTrim(yzActOrderList);
        //频率
        List<YzOrderFrequency> yzOrderFrequencyList = dao.selectYzOrderFrequency();
        CommonUtil.BeanTrim(yzOrderFrequencyList);
        if (CollUtil.isEmpty(yzOrderFrequencyList)) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "执行频率未维护");
        }
        //药房
        List<YpZdGroupName> ypZdGroupNames = ypZdGroupNameDao.selectAll();
        CommonUtil.BeanTrim(ypZdGroupNames);
        Map<String, YpZdGroupName> zdGroupMap = ypZdGroupNames.stream().collect(Collectors.toMap(YpZdGroupName::getGroupNo, ypZdGroupName -> ypZdGroupName));

        List<YzSupplyCharge> yzSupplyCharges = dao.selectYzSupplyChargeAll();
        CommonUtil.BeanTrim(yzSupplyCharges);
        param.setYzSupplyCharges(yzSupplyCharges);

        List<String> yjDeptList = dao.selectYjDept();
        param.setYjDeptCodes(yjDeptList);
        YzSequence yzSequence = medicalCommonService.queryYzSequence();
        String startTimeKf = dao.selectStartDayTimeKfDept(param.getWardCode());
        param.setItStartTime(yzSequence.getStartDayTime());
        if(StrUtil.isNotBlank(startTimeKf)){
            param.setItStartTimeKf(startTimeKf);
        }else {
            param.setItStartTimeKf(StrUtil.isNotBlank(yzSequence.getStartDayTimeKf()) ? yzSequence.getStartDayTimeKf() : yzSequence.getStartDayTime());
        }
        Map<String, YzOrderFrequency> frequencyMap = yzOrderFrequencyList.stream().collect(Collectors.toMap(YzOrderFrequency::getCode, a -> a, (k1, k2) -> k1));
        //判断病人是否欠费或者是否补交费用
        for (ZyActpatient zyActpatient : zyActpatients) {
            BeanUtil.trimStrFields(zyActpatient);
            ZyLedgerFile zyLedgerFile = dao.selectBalancefromZyLedgerFile(zyActpatient.getInpatientNo(), zyActpatient.getAdmissTimes());
            if (zyLedgerFile!=null && Convert.toBigDecimal(zyLedgerFile.getBalance(), BigDecimal.ZERO).add(Convert.toBigDecimal(zyLedgerFile.getChargeYb(), BigDecimal.ZERO)).compareTo(BigDecimal.ZERO) <= 0) {
                //更新own_flag = '1' 欠费
                zyActpatient.setOweFlag("1");
                zyActpatient.setOwnTime(null);
                dao.updateOwnFlagfromZyActpatient(zyActpatient.getInpatientNo(), zyActpatient.getAdmissTimes(), "1");
            } else if (zyLedgerFile!=null && Convert.toBigDecimal(zyLedgerFile.getBalance(), BigDecimal.ZERO).add(Convert.toBigDecimal(zyLedgerFile.getChargeYb(), BigDecimal.ZERO)).compareTo(BigDecimal.ZERO) > 0 && NumberEnum.ONE.getCode().equals(zyActpatient.getOweFlag())) {
                //更新own_flag = '2'
                zyActpatient.setOweFlag("2");
                zyActpatient.setOwnTime(now);
                dao.updateOwnFlagfromZyActpatient(zyActpatient.getInpatientNo(), zyActpatient.getAdmissTimes(), "2");
            }
            List<YzActOrder> patientYzActOrder = yzActOrderList.stream().filter(item -> zyActpatient.getInpatientNo().equals(StrUtil.trim(item.getInpatientNo())) && zyActpatient.getAdmissTimes().equals(item.getAdmissTimes())).collect(Collectors.toList());
            if (CollUtil.isEmpty(patientYzActOrder)) {
                continue;
            }
            realGenerateYz(patientYzActOrder, param, frequencyMap, now,zyActpatient,zdGroupMap);
            removeData(param, zyActpatient);
        }
        if(CollUtil.isNotEmpty(param.getYzActOccs())){
            log.info("最终生成的执行医嘱:{}",param.getYzActOccs());
            List<List<YzActOcc>> tempOccList = CollUtil.split(param.getYzActOccs(), 50);
            for(List<YzActOcc> temp : tempOccList){
                yzActOccDao.batchInsertYzActOcc(temp);
            }
        }

        if(CollUtil.isNotEmpty(param.getYzZyPatientFees())){
            log.info("最终生成的费用医嘱:{}",param.getYzZyPatientFees());
            List<List<YzZyPatientFee>> tempYzPatientFee = CollUtil.split(param.getYzZyPatientFees(), 50);
            for(List<YzZyPatientFee> temp : tempYzPatientFee){
                yzZyPatientFeeDao.batchInsertData(temp);
            }
        }
        if(CollUtil.isNotEmpty(param.getYzYpZyOrders())){
            log.info("最终生成的药品医嘱:{}",param.getYzYpZyOrders());
//            List<YpZyPatient> ypZyPatientList = createYpZyPatient(param.getYzYpZyOrders());
//            if(CollUtil.isNotEmpty(ypZyPatientList)){
//                log.info("自动上账的医嘱:{}",ypZyPatientList);
//                List<List<YpZyPatient>> tempYpZyPatientList = CollUtil.split(ypZyPatientList, 50);
//                for(List<YpZyPatient> temp : tempYpZyPatientList){
//                    yzYpZyOrderDao.batchInsertYpZyPatient(temp);
//                }
//            }
            ListUtil.batchList(param.getYzYpZyOrders(),YzYpZyOrderDao.class, YzYpZyOrderDao::insertOne);
//            List<List<YzYpZyOrder>> tempYzYpZyOrder = CollUtil.split(param.getYzYpZyOrders(),50);
//            for(List<YzYpZyOrder> temp : tempYzYpZyOrder){
//                yzYpZyOrderDao.batchInsertData(temp);
//            }
        }
//        新增执行时间大于结束时间的药品数据
        List<YzYpZyOrder> yzYpZyOrdersEnd = yzYpZyOrderDao.selectYzYpZyOrderByEnd(param.getWardCode());
        if(CollUtil.isNotEmpty(yzYpZyOrdersEnd)){
            yzYpZyOrderDao.deleteYzYpZyOrderEnd(param.getWardCode());
            for(YzYpZyOrder item : yzYpZyOrdersEnd){
                item.setAmount(item.getAmount().negate());
                item.setStatusFlag("3");
                item.setPaySelf("0");
                item.setPageClass(null);
            }
            ListUtil.batchList(yzYpZyOrdersEnd,YzYpZyOrderDao.class, YzYpZyOrderDao::insertOne);
        }
        //修改状态
        if(CollUtil.isNotEmpty(param.getUpdateStatusYzActOrders())) {
            for (BigDecimal key : param.getUpdateStatusYzActOrders().keySet()) {
                YzActOrder tempYzActOrder = param.getUpdateStatusYzActOrders().get(key);
                log.info("修改状态医嘱 医嘱号={},状态={}", tempYzActOrder.getActOrderNo(), tempYzActOrder.getStatusFlag());
//                if(NumberEnum.FIVE.getCode().equals(tempYzActOrder.getStatusFlag()) && !FREQ_CODE_ONCE.equals(tempYzActOrder.getFrequCode())){
//                 List<YpZyPatient> tfYpZyPatientList = yzYpZyOrderDao.selectYpZyPatientByOccTime(tempYzActOrder.getActOrderNoStr(),DateUtil.formatDateTime(tempYzActOrder.getEndTime()));
//                    yzYpZyOrderDao.updateTfAmount(tempYzActOrder.getActOrderNoStr(), DateUtil.formatDateTime(tempYzActOrder.getEndTime()));
//                 if(CollUtil.isNotEmpty(tfYpZyPatientList)){
//                     for(YpZyPatient item : tfYpZyPatientList){
//                         item.setAmount(BigDecimal.ZERO.subtract(item.getAmount()));
//                         item.setAcctSign("0");
//                     }
//                     log.info("长期医嘱需要退费的数据:{}",tfYpZyPatientList);
//                     List<List<YpZyPatient>> tempYpZyPatientList = CollUtil.split(tfYpZyPatientList, 50);
//                     for(List<YpZyPatient> temp : tempYpZyPatientList){
//                         yzYpZyOrderDao.batchInsertYpZyPatient(temp);
//                     }
//                 }
//                }
                dao.updateYzActOrderStatusFlag(tempYzActOrder);
            }
           if(CollUtil.isNotEmpty(param.getYzActOccs())){
               Set<BigDecimal> collect = param.getYzActOccs().stream().map(obj -> Convert.toBigDecimal(obj.getActOrderNoStr()).abs()).collect(Collectors.toSet());
               List<List<BigDecimal>> split = CollUtil.split(collect, 50);
               for(List<BigDecimal> item : split){
                   String yzActNos = CollUtil.join(item, ",");
                   log.info("修改执行时间的医嘱={}",yzActNos);
                   dao.updateYzActOrderPerformanceTime(yzActNos, DateUtil.parseDate(param.getYzDate()));
               }
           }
        }
        //最后的执行
        yzYpZyOrderDao.updateStatusFlag(param.getWardCode());
        yzYpZyOrderDao.updateAmountAndStatusFlag(param.getWardCode());
        yzZyPatientFeeDao.updateChargeStatus(param.getWardCode());
        yzZyPatientFeeDao.updateChargeStatusAndOrderCount(param.getWardCode());
        yzActOccDao.updateStatusFlag(param.getWardCode());
        String ypOrZlFlagStr = NumberEnum.ONE.getCode().equals(param.getYpOrZlFlag()) ? "生成药品成功" : "生成诊疗成功";
        return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_EL_MESSAGE,ypOrZlFlagStr,param.getWarMessage());
    }

    private void removeData(GenerateYzVo param, ZyActpatient zyActpatient) {
       if(CollUtil.isNotEmpty(param.getYzActOccs())){
           log.info("初始生成的执行医嘱数据:{}",param.getYzActOccs());
           List<YzActOcc> yzActOccList = param.getYzActOccs().stream().filter(item -> !NumberEnum.TWO.getCode().equals(zyActpatient.getOweFlag())
                   || DateUtil.between(addDateTime(DateUtil.formatDate(zyActpatient.getOwnTime()), " 00:00:00", false), item.getOccTime(), DateUnit.SECOND, false) >= 0
                   || "8000160".equals(zyActpatient.getDeptCode())).collect(Collectors.toList());
           if(CollUtil.isEmpty(yzActOccList)){
               param.getYzActOccs().clear();
           }else {
               param.getYzActOccs().clear();
               if(CollUtil.isNotEmpty(param.getCheckYzActOccs())){
                   CommonUtil.BeanTrim(param.getCheckYzActOccs());
                   List<YzActOcc> insertYzActOcc = CollUtil.subtractToList(yzActOccList,param.getCheckYzActOccs());
                   if(CollUtil.isNotEmpty(insertYzActOcc)){
                       param.getYzActOccs().addAll(insertYzActOcc);
                   }
               }
               else {
                   param.getYzActOccs().addAll(yzActOccList);
               }
           }
       }

        if(CollUtil.isNotEmpty(param.getYzZyPatientFees())){
            log.info("初始生成的医嘱费用数据:{}",param.getYzZyPatientFees());
            List<YzZyPatientFee> yzZyPatientFeeList = param.getYzZyPatientFees().stream().filter(item -> !NumberEnum.TWO.getCode().equals(zyActpatient.getOweFlag())
                    || DateUtil.between(addDateTime(DateUtil.formatDate(zyActpatient.getOwnTime()), " 00:00:00", false), item.getOccTime(), DateUnit.SECOND, false) >= 0
                    || "8000160".equals(zyActpatient.getDeptCode())).collect(Collectors.toList());
            if(CollUtil.isEmpty(yzZyPatientFeeList)){
                param.getYzZyPatientFees().clear();
            }else {
                param.getYzZyPatientFees().clear();
                if(CollUtil.isNotEmpty(param.getCheckYzZyPatientFees())){
                    CommonUtil.BeanTrim(param.getCheckYzZyPatientFees());
                    List<YzZyPatientFee> insertYzZyPatientFee = CollUtil.subtractToList(yzZyPatientFeeList,param.getCheckYzZyPatientFees());
                    if(CollUtil.isNotEmpty(insertYzZyPatientFee)){
                        param.getYzZyPatientFees().addAll(insertYzZyPatientFee);
                    }
                }
                else {
                    param.getYzZyPatientFees().addAll(yzZyPatientFeeList);
                }
            }
        }


        if(CollUtil.isNotEmpty(param.getYzYpZyOrders())){
            log.info("初始生成的医嘱药品费用数据:{}",param.getYzYpZyOrders());
            List<YzYpZyOrder> yzYpZyOrderList = param.getYzYpZyOrders().stream().filter(item -> !NumberEnum.TWO.getCode().equals(zyActpatient.getOweFlag())
                    || DateUtil.between(addDateTime(DateUtil.formatDate(zyActpatient.getOwnTime()), " 00:00:00", false), item.getOccTime(), DateUnit.SECOND, false) >= 0
                    || "8000160".equals(zyActpatient.getDeptCode())).collect(Collectors.toList());
            if(CollUtil.isEmpty(yzYpZyOrderList)){
                param.getYzYpZyOrders().clear();
            }else {
                param.getYzYpZyOrders().clear();
                if(CollUtil.isNotEmpty(param.getCheckYzYpZyOrders())){
                    CommonUtil.BeanTrim(param.getCheckYzYpZyOrders());
                    List<YzYpZyOrder> insertYzYpZyOrder = CollUtil.subtractToList(yzYpZyOrderList,param.getCheckYzYpZyOrders());
                    if(CollUtil.isNotEmpty(insertYzYpZyOrder)){
                        param.getYzYpZyOrders().addAll(insertYzYpZyOrder);
                    }
                }
                else {
                    param.getYzYpZyOrders().addAll(yzYpZyOrderList);
                }
            }
        }
    }



    private void realGenerateYz(List<YzActOrder> patientYzActOrder, GenerateYzVo param, Map<String, YzOrderFrequency> frequencyMap,  Date now,ZyActpatient zyActpatient,Map<String, YpZdGroupName> zdGroupMap) {
        Date yzDate = DateUtil.parseDate(param.getYzDate());
        Date ldCurDay = DateUtil.offsetDay(yzDate, -2);
        Date ldEndDay;
        //生成药品(生成后一天数据) 诊疗生成当天
        if (NumberEnum.ONE.getCode().equals(param.getYpOrZlFlag())) {
            ldEndDay = DateUtil.offsetDay(yzDate, 1);
        } else {
            ldEndDay = yzDate;
        }
        //生成几天的数据
        long liDay = betweenDay(ldCurDay, ldEndDay, true,false) + 1;
        Date ldCurDayNew = DateUtil.offsetDay(ldCurDay, -1);

        Set<String> supplyCodes = patientYzActOrder.stream().map(item -> Convert.toStr(item.getSupplyCode(), "")).collect(Collectors.toSet());
        List<YzSupplyType> yzSupplyTypeList = dao.selectYzSupplyType(CommonUtil.toInStringSql(CollUtil.newArrayList(supplyCodes)));
        Map<String, YzSupplyType> supplyMap = null;
        if (CollUtil.isNotEmpty(yzSupplyTypeList)) {
            supplyMap = yzSupplyTypeList.stream().collect(Collectors.toMap(YzSupplyType::getSupplyCode, a -> a, (k1, k2) -> k1));
        }
        for (YzActOrder item : patientYzActOrder) {
            if (item.getStartTime() == null) {
                continue;
            }
            BeanUtil.trimStrFields(item);
            dealYzAct(supplyMap, item);
            //查询药品信息
            YpZdDictVo ypZdDictVo = getYpZdDictBase(item);
            //24小时开始时间
            String itStartTime = param.getItStartTime();
            for (int i = 1; i <= liDay; i++) {
                //处理长期口服西药 只生成一天的单日口服药品执行
                if (!FREQ_CODE_ONCE.equals(item.getFrequCode()) && ("001".equals(item.getSupplyCode()) || NumberEnum.ONE.getCode().equals(item.getSupplyClass()))) {
                    itStartTime = param.getItStartTimeKf();
                    if(i == 4){
                        continue;
                    }
                }
                //确定当前日期
                ldCurDay = DateUtil.offsetDay(ldCurDayNew, i);
                String ldCurDayStr = DateUtil.formatDate(ldCurDay);
                //下一天
                Date LdCurDayNext = DateUtil.offsetDay(ldCurDay, 1);
                String LdCurDayNextStr = DateUtil.formatDate(LdCurDayNext);
                //录入日期加系统的时间为生成执行的时间
                String LdCurrent = DateUtil.formatDate(ldCurDay)+" "+DateUtil.format(now,"HH:mm:ss");
                if(item.getEndTime() != null && DateUtil.parseDateTime(DateUtil.formatDateTime(item.getEndTime())).getTime() <= addDateTime(DateUtil.formatDate(ldCurDay),itStartTime,true).getTime()){
                    item.setStatusFlag("5");
                    item.setStatusTime(item.getEndTime());
                    param.getUpdateStatusYzActOrders().put(item.getActOrderNo(),item);
                    continue;
                }
                else{
                    if(item.getPerformanceTime()!= null && item.getEndTime()!=null && (DateUtil.parseDateTime(DateUtil.formatDateTime(item.getEndTime())).getTime() < addDateTime(DateUtil.formatDate(item.getPerformanceTime()),itStartTime,true).getTime())){
                        item.setStatusFlag("5");
                        item.setStatusTime(item.getEndTime());
                        param.getUpdateStatusYzActOrders().put(item.getActOrderNo(),item);
                    }
                }
                if(item.getPerformanceTime()!= null && betweenDay(ldCurDay,item.getPerformanceTime(),true,false) >= 0){
                    continue;
                }
                //如果该医嘱不到开始时间则不产生执行
                if(parseDateTimeDay(item.getStartTime()).getTime() >= addDateTime(DateUtil.formatDate(LdCurDayNext),itStartTime,true).getTime()){
                    continue;
                }
                if(FREQ_CODE_ONCE.equals(item.getFrequCode()) && !(parseDateTimeDay(item.getStartTime()).getTime() >= addDateTime(ldCurDayStr,itStartTime,true).getTime()
                        && parseDateTimeDay(item.getStartTime()).getTime() <= addDateTime(LdCurDayNextStr,itStartTime,true).getTime())){
                    continue;
                }

                YzOrderFrequency yzOrderFrequency = frequencyMap.get(item.getFrequCode());
                List<String> occTimeStrList = getOccTimeStr(yzOrderFrequency);
                //周几执行
                List<Integer> occWeekList = getOccWeek(yzOrderFrequency);
                log.info("医嘱号={},执行频率={},周执行={}",item.getActOrderNoStr(),item.getFrequCode(),occWeekList);
                //有执行时间
                if(CollUtil.isNotEmpty(occTimeStrList)){
                    //如果执行时间小于24小时定义的起始时间,那么执行时间
                    //在日期上应该加1
                    //例如:24小时定义的起始时间为08:00,而取出的执行时间
                    //为06:00,则执行时间应该是第二天的06:00;
                    for(String occTimeStr : occTimeStrList){
                        Date occTimeTemp ;
                        if (addDateTime(DateUtil.formatDate(now), occTimeStr,false).getTime() < addDateTime(DateUtil.formatDate(now), itStartTime,true).getTime()) {
                            occTimeTemp = addDateTime(LdCurDayNextStr, occTimeStr, false);
                        }else {
                            occTimeTemp = addDateTime(ldCurDayStr, occTimeStr, false);
                        }
                        //检查隔日一次
                        if(item.getFrequCode().startsWith("QOD") || item.getFrequCode().startsWith("Q0D") || item.getFrequCode().startsWith("Q2D")){
                            if(betweenDay(item.getStartTime(),occTimeTemp,true,false) % 2 != 0){
                                continue;
                            }
                        }
                        int numQd = getQmDFreCode(item.getFrequCode());
                        if(numQd > 0){
                            if(betweenDay(item.getStartTime(),occTimeTemp,true,false) % numQd != 0 ){
                                continue;
                            }
                        }
                        //是周执行
                        if(CollUtil.isNotEmpty(occWeekList)){
                            if(!occWeekList.contains(Convert.toInt(DateUtil.dayOfWeek(occTimeTemp)))){
                                continue;
                            }
                        }
                        if(occTimeTemp.getTime() < parseDateTimeDay(item.getStartTime()).getTime()){
                            continue;
                        }
                        //如果执行时间小于停止时间,或者停止时间为空,则产生执行
                        //否则不产生执行
                        //例如:一个TID的医嘱,在停止的那一天,可以只执行两次
                        if(item.getEndTime() == null || occTimeTemp.getTime() <= parseDateTimeDay(item.getEndTime()).getTime()){
                            //根据医嘱类型'o','h','d','i',分四种情况处理,并生成执行记录
                            // wf_order_insert_occ()
                            orderInsertOcc(item, occTimeTemp, zyActpatient,param,ypZdDictVo,zdGroupMap);
                            //置STATUS_FLAG状态
                            changeOrderStatus(item, LdCurrent,param);
                        }

                    }
                }
                else {
                    //执行频率中没有执行时间,取开始时间中的时间;
                    //执行频率为ALWAYS,IRREG,取执行时间为24小时的开始时间;
                    //这样的医嘱只产生一条执行;
                    Date occTimeTemp;
                    if(FREQ_CODE_ONCE.equals(item.getFrequCode())){
                        occTimeTemp = now;
                    }
                   else if(DateUtil.between(now,addDateTime(DateUtil.formatDate(now), itStartTime, true), DateUnit.SECOND,false) > 0){
                        occTimeTemp = addDateTime(LdCurDayNextStr, itStartTime, true);
                    }
                    else {
                        occTimeTemp = addDateTime(ldCurDayStr, itStartTime, true);
                    }
                    if( DateUtil.between(item.getStartTime(), occTimeTemp, DateUnit.SECOND, false)< 0 ){
                        continue;
                    }
                    if(item.getEndTime() == null || occTimeTemp.getTime() <= parseDateTimeDay(item.getEndTime()).getTime()){
                        //根据医嘱类型'o','h','d','i',分四种情况处理,并生成执行记录
                        // wf_order_insert_occ()
                        orderInsertOcc(item, occTimeTemp, zyActpatient,param,ypZdDictVo,zdGroupMap);
                        //置STATUS_FLAG状态
                        changeOrderStatus(item, LdCurrent,param);
                    }
                }
            }
        }
    }

    private void changeOrderStatus(YzActOrder item, String ldCurrent,GenerateYzVo param) {
        if(CollUtil.isNotEmpty(param.getWarMessageActOrders())){
            for(String actOrderStr : param.getWarMessageActOrders()){
                if(actOrderStr.equals(item.getActOrderNoStr())){
                    return;
                }
            }
        }
        //置STATUS_FLAG状态;2 :确认 3 :第一次执行 4 : 执行 5 :停止
        if(NumberEnum.TWO.getCode().equals(item.getStatusFlag())){
            item.setStatusFlag(NumberEnum.ThREE.getCode());
            item.setStatusTime(DateUtil.parseDateTime(ldCurrent));
            param.getUpdateStatusYzActOrders().put(item.getActOrderNo(),item);
        }
        else if(NumberEnum.ThREE.getCode().equals(item.getStatusFlag())){
            item.setStatusFlag(NumberEnum.FOUR.getCode());
            item.setStatusTime(DateUtil.parseDateTime(ldCurrent));
            param.getUpdateStatusYzActOrders().put(item.getActOrderNo(),item);
        }
        else if(NumberEnum.FOUR.getCode().equals(item.getStatusFlag())){
            item.setStatusTime(DateUtil.parseDateTime(ldCurrent));
            param.getUpdateStatusYzActOrders().put(item.getActOrderNo(),item);
        }
        if(FREQ_CODE_ONCE.equals(item.getFrequCode())){
            item.setStatusFlag(NumberEnum.FIVE.getCode());
            item.setStatusTime(DateUtil.parseDateTime(ldCurrent));
            item.setEndTime(item.getStartTime());
            param.getUpdateStatusYzActOrders().put(item.getActOrderNo(),item);
        }
    }

    private YpZdDictVo getYpZdDictBase(YzActOrder item) {
        YpZdDictVo ypZdDictVo = null;
        if(!"00".equals(item.getGroupNo())){
            if(Convert.toInt(item.getGroupNo(),0) >= 71){
                ypZdDictVo =  dao.selectYpZdDictBase(item.getOrderCode(), item.getSerial(), item.getGroupNo());
            }else {
                ypZdDictVo = dao.selectYpZdDict(item.getOrderCode(), item.getSerial());
            }
        }
        return ypZdDictVo;
    }

    /**
     * @description: 插入医嘱执行
     * @author: lihong
     * @date: 2025/3/12 17:25
     * @param: yzActOrder
     * @param: occTime
     * @param: zyActpatient
     **/
    private void orderInsertOcc(YzActOrder yzActOrder, Date occTime, ZyActpatient zyActpatient,GenerateYzVo param,YpZdDictVo ypZdDictVo,Map<String, YpZdGroupName> zdGroupMap) {
        String drugFlag = yzActOrder.getDrugFlag();
        //h:护理常规;t:成组医嘱
        if("h".equals(drugFlag) || "t".equals(drugFlag)){
            ZdChargeItem zdChargeItem = new ZdChargeItem();
            zdChargeItem.setCode("nurse");
            String occName = yzActOrder.getIbBuyName() + yzActOrder.getOrderName();
            zdChargeItem.setName("*" +StrUtil.trim(occName));
            zdChargeItem.setChargeAmount(BigDecimal.ZERO);
            param.getYzActOccs().add(convert2YzActOcc(zyActpatient, yzActOrder, zdChargeItem, occTime,null,zdGroupMap));
        }
        //o:医嘱;x:材料医嘱,p:手术,s:输血类
        else if("o".equals(drugFlag) || "x".equals(drugFlag) || "p".equals(drugFlag) || "s".equals(drugFlag)){
            yzActOrder.setOccType("o");
            //根据该医嘱是否有对应的执行项目,分别处理:
            //1.有对应项目:
            //  取ZD_CHARGE_ITEM的内容,在YZ_ACT_OCC和YZ_ZY_PATIENT_FEE
            //  中分别插入记录
            //2.没有对应项目:
            //  取YZ_ORDER_ITEM的内容,只在YZ_ACT_OCC中插入记录;
            //3.费用标志为'1'(自备)或'2'(嘱托):
            //  根据以上两种情况判断取ZD_CHARGE_ITEM的内容还是
            //  取YZ_ORDER_ITEM的内容,但只在YZ_ACT_OCC中插入记录;
          List<ZdChargeItem> zdChargeItemList =  dao.selectOccZdChargeItemByOrderCode(yzActOrder.getOrderCode());
          if(CollUtil.isNotEmpty(zdChargeItemList)){
              for(ZdChargeItem zdChargeItem : zdChargeItemList){
                  // 对于非材料类项目，以录入医嘱时的执行科室为准
                  if(StrUtil.isNotBlank(yzActOrder.getExecUnit()) && StrUtil.isNotBlank(zdChargeItem.getClCode()) && !zdChargeItem.getCode().startsWith("F")){
                      zdChargeItem.setExecUnit(yzActOrder.getExecUnit());
                  }
                  zdChargeItem.setName(Convert.toStr(yzActOrder.getIbBuyName(),"") + zdChargeItem.getName());
                  //向yz_act_occ中插入一条记录;
                  param.getYzActOccs().add(convert2YzActOcc(zyActpatient, yzActOrder, zdChargeItem, occTime,null,zdGroupMap));
                  if(!yzActOrder.getBuyFlag()){
                      //向yz_zy_patient_fee中插入一条记录;
                      param.getYzZyPatientFees().add(convert2YzZyPatientFee(zyActpatient, yzActOrder, zdChargeItem, occTime,param));
                  }
              }
          }
          else {
              //没有对应的执行项目;
              //向yz_act_occ中插入一条记录;
              ZdChargeItem zdChargeItem = new ZdChargeItem();
              zdChargeItem.setCode("ord");
              zdChargeItem.setName("*"+StrUtil.trim(Convert.toStr(yzActOrder.getIbBuyName(),""))+StrUtil.trim(yzActOrder.getOrderName()));
              param.getYzActOccs().add(convert2YzActOcc(zyActpatient, yzActOrder, zdChargeItem, occTime, null, zdGroupMap));
          }
        }
        //d 西药
        else if(KF.equals(drugFlag) || DSY.equals(drugFlag) || ZCY.equals(drugFlag) || ZBY.equals(drugFlag)){
            if(DSY.equals(drugFlag)){
                yzActOrder.setOccType(DSY);
            }
           else if("001".equals(yzActOrder.getSupplyCode()) || NumberEnum.ONE.getCode().equals(yzActOrder.getSupplyClass())){
                yzActOrder.setOccType(KF);
            }else {
                yzActOrder.setOccType("j");
            }
           //b 自备药
           if(ZBY.equals(drugFlag)){
               if(ypZdDictVo == null){
                   ypZdDictVo = new YpZdDictVo();
                   ypZdDictVo.setName(yzActOrder.getIbBuyName()+yzActOrder.getOrderName());
                   ypZdDictVo.setCode(yzActOrder.getOrderCode());
               }
               param.getYzActOccs().add(convert2YzActOcc(zyActpatient, yzActOrder, null, occTime, ypZdDictVo, zdGroupMap));
           }
           else {
               if(ypZdDictVo == null || StrUtil.isBlank(ypZdDictVo.getName()) || Convert.toBigDecimal(ypZdDictVo.getPackRetprice(),BigDecimal.ZERO).compareTo(BigDecimal.ZERO) == 0){
                 String message =  StrUtil.format("床号={},医嘱号={}, 医嘱名={}:药品编码,GROUP_NO 为{},{},医嘱时间={},的医嘱找不到原药品纪录，请通知药房!",
                           yzActOrder.getBedNo(), yzActOrder.getActOrderNo(), yzActOrder.getOrderName(), yzActOrder.getOrderCode(), yzActOrder.getGroupNo(),DateUtil.formatDateTime(occTime));
                   log.error("生成药品错误消息:{}",message);
                   param.getWarMessage().add(message);
                   param.getWarMessageActOrders().add(yzActOrder.getActOrderNoStr());
                   return;
               }
               //禁用
               else if(KF.equals(drugFlag) && NumberEnum.ONE.getCode().equals(ypZdDictVo.getVisibleFlag())){
                   String message = StrUtil.format("床号={},医嘱号={}, 医嘱名={}:药品编码,GROUP_NO 为{},{},医嘱时间={}的药品药房已禁用，请更改此医嘱!", yzActOrder.getBedNo(), yzActOrder.getActOrderNo(), yzActOrder.getOrderName(), yzActOrder.getOrderCode(), yzActOrder.getGroupNo(),DateUtil.formatDateTime(occTime));
                   log.error("生成药品错误消息:{}",message);
                   param.getWarMessage().add(message);
                   param.getWarMessageActOrders().add(yzActOrder.getActOrderNoStr());
                   return;
               }
               else {
                   ypZdDictVo.setName(yzActOrder.getIbBuyName()+yzActOrder.getOrderName());
                   param.getYzActOccs().add(convert2YzActOcc(zyActpatient, yzActOrder, null, occTime, ypZdDictVo, zdGroupMap));
                   if(!yzActOrder.getBuyFlag()){
                       //向yz_yp_zy_order中插入一条记录;
                       param.getYzYpZyOrders().add(convert2YzYpZyOrder(zyActpatient, yzActOrder, ypZdDictVo, occTime,zdGroupMap));
                   }
               }
           }

           //如果给药方式附带执行,则生成相应执行,附加费;
            List<YzSupplyCharge> yzSupplyCharges = param.getYzSupplyCharges();
           if(CollUtil.isNotEmpty(yzSupplyCharges) && StrUtil.isNotBlank(yzActOrder.getSupplyCode())){
               List<YzSupplyCharge> yzSupplyChargeList = yzSupplyCharges.stream().filter(item -> item.getSupplyCode().equals(yzActOrder.getSupplyCode())).collect(Collectors.toList());
               if(CollUtil.isNotEmpty(yzSupplyChargeList)){
                    for(YzSupplyCharge tempSupplyCharge : yzSupplyChargeList){
                        ZdChargeItem zdChargeItem = dao.selectZdChargeItemByCode(tempSupplyCharge.getChargeCode());
                        if(zdChargeItem != null ){
                            YzActOrder tempYzActOrder = new YzActOrder();
                            BeanUtil.copyProperties(yzActOrder,tempYzActOrder);
                            tempYzActOrder.setActOrderNo(yzActOrder.getActOrderNo().negate());
                            tempYzActOrder.setPaySelf("0");
                            tempYzActOrder.setOccType("o");
                            tempYzActOrder.setDrugOcc(BigDecimal.ONE);
                            tempYzActOrder.setDrugQuan(BigDecimal.ONE);
                            tempYzActOrder.setExecUnit(null);
                            param.getYzActOccs().add(convert2YzActOcc(zyActpatient, tempYzActOrder, zdChargeItem, occTime, null, zdGroupMap));
                            if(Convert.toBigDecimal(zdChargeItem.getChargeAmount(),BigDecimal.ZERO).compareTo(BigDecimal.ZERO) > 0){
                                param.getYzZyPatientFees().add(convert2YzZyPatientFee(zyActpatient, tempYzActOrder, zdChargeItem, occTime,param));
                            }
                        }
                    }
               }
           }
        }
    }


    private List<YpZyPatient> createYpZyPatient(List<YzYpZyOrder> yzYpZyOrders){
        List<YpZyPatient> list = new ArrayList<>();
        for(YzYpZyOrder yzYpZyOrder : yzYpZyOrders){
            //基数药自动上账
            if(NumberEnum.ThREE.getCode().equals(yzYpZyOrder.getStatusFlag()) && !NumberEnum.ONE.getCode().equals(yzYpZyOrder.getPaySelf())){
                YpZyPatient ypZyPatient = convert2YpZyPatient(yzYpZyOrder,"j");
                list.add(ypZyPatient);
                yzYpZyOrder.setStatusFlag(NumberEnum.FOUR.getCode());
            }
            //大输液自动上账
            if(DSY.equals(yzYpZyOrder.getDrugClass()) && NumberEnum.ONE.getCode().equals(yzYpZyOrder.getStatusFlag()) && !NumberEnum.ONE.getCode().equals(yzYpZyOrder.getPaySelf()) && yzYpZyOrder.getAmount().compareTo(BigDecimal.ZERO) > 0){
                YpZyPatient ypZyPatient = convert2YpZyPatient(yzYpZyOrder,"d");
                list.add(ypZyPatient);
                yzYpZyOrder.setStatusFlag(NumberEnum.FOUR.getCode());
            }
        }
        return list;
    }

    private YpZyPatient convert2YpZyPatient(YzYpZyOrder yzYpZyOrder,String supplyCode){
        YpZyPatient ypZyPatient = new YpZyPatient();
        ypZyPatient.setOrderDate(yzYpZyOrder.getOccTime());
        ypZyPatient.setOutSeri(1);
        ypZyPatient.setDeptCode(yzYpZyOrder.getDeptCode());
        ypZyPatient.setWardCode(yzYpZyOrder.getWardCode());
        ypZyPatient.setInpatientNo(yzYpZyOrder.getInpatientNo());
        ypZyPatient.setName(yzYpZyOrder.getName());
        ypZyPatient.setBedNo(yzYpZyOrder.getBedNo());
        ypZyPatient.setChargeCode(yzYpZyOrder.getChargeCode());
        ypZyPatient.setSerial(yzYpZyOrder.getSerial());
        ypZyPatient.setAmount(yzYpZyOrder.getAmount());
        ypZyPatient.setDrawer(yzYpZyOrder.getDrawer());
        ypZyPatient.setRetprice(yzYpZyOrder.getRetprice());
        ypZyPatient.setInfantFlag(yzYpZyOrder.getInfantFlag());
        ypZyPatient.setAlwaysFlag(yzYpZyOrder.getAlwaysFlag());
        ypZyPatient.setDrugClass(yzYpZyOrder.getDrugClass());
        ypZyPatient.setAcctSign("0");
        ypZyPatient.setTotalFlag("0");
        ypZyPatient.setAdmissTimes(yzYpZyOrder.getAdmissTimes());
        ypZyPatient.setSupplyCode(supplyCode);
        ypZyPatient.setActOrderNo(yzYpZyOrder.getActOrderNo());
        ypZyPatient.setPageNo(Convert.toInt(yzYpZyOrder.getPageNo()));
        ypZyPatient.setPaySelf(yzYpZyOrder.getPaySelf());
        ypZyPatient.setSelfFlag(yzYpZyOrder.getSelfFlag());
        ypZyPatient.setSeparateFlag(yzYpZyOrder.getSeparateFlag());
        ypZyPatient.setSupriceFlag(yzYpZyOrder.getSupriceFlag());
        ypZyPatient.setDrugFlag(yzYpZyOrder.getDrugFlag());
        ypZyPatient.setGroupNo(yzYpZyOrder.getGroupNo());
        return ypZyPatient;
    }


    /**
     * @description: 获取周几执行  1表示周日，2表示周一  1,7  2,1 3,2  4,3  5,4 6,5 7,6
     * @author: lihong
     * @date: 2025/3/12 15:16
     * @param: yzOrderFrequency
     * @return: java.util.List<java.lang.Integer>
     **/
    private List<Integer> getOccWeek(YzOrderFrequency yzOrderFrequency) {
        List<Integer> weekList = new ArrayList<>();
        if(Convert.toStr(yzOrderFrequency.getWeekDay(),"N").equals("Y")){
            Field[] fields = ReflectUtil.getFields(YzOrderFrequency.class);
            for(Field field : fields){
                String fieldName = ReflectUtil.getFieldName(field);
                if(fieldName.startsWith(prefixWeek) && Convert.toInt(ReflectUtil.getFieldValue(yzOrderFrequency,fieldName),0) == 1){
                    switch (calcWeekFreqOccTime(fieldName)){
                        case "1" :
                            weekList.add(2);
                            break;
                        case "2" :
                            weekList.add(3);
                            break;
                        case "3" :
                            weekList.add(4);
                            break;
                        case "4" :
                            weekList.add(5);
                            break;
                        case "5" :
                            weekList.add(6);
                            break;
                        case "6" :
                            weekList.add(7);
                            break;
                        case "7" :
                            weekList.add(1);
                            break;
                    }
                }
            }
        }
        return weekList;
    }

    /**
     * @description: 频率 是否 是 Q3D 格式 * 为 3 到 9 开头
     * @author: lihong
     * @date: 2025/3/12 15:02
     * @param: frequCode
     * @return: boolean
     **/
    private int getQmDFreCode(String frequCode) {
        for (int i = 3; i <=9 ; i++) {
            if(frequCode.startsWith("Q"+i+"D")){
                return i;
            }
        }
        return -1;
    }

    /**
     * @description: 获取执行时间 HH:mm:ss
     * @author: lihong
     * @date: 2025/3/12 11:02
     * @param: yzOrderFrequency
     * @return: java.lang.String
     **/
    private List<String> getOccTimeStr(YzOrderFrequency yzOrderFrequency) {
        List<String> occTimeList = new ArrayList<>();
        Field[] fields = ReflectUtil.getFields(YzOrderFrequency.class);
        for(Field field : fields){
            String fieldName = ReflectUtil.getFieldName(field);
            if(fieldName.startsWith("day")){
              Integer value = Convert.toInt(ReflectUtil.getFieldValue(yzOrderFrequency, fieldName),0);
              if(value == 1){
                  occTimeList.add(calcDayOccTime(fieldName));
              }
            }
        }
        return occTimeList;
    }

    /**
     * @description: 格式化 不到毫秒
     * @author: lihong
     * @date: 2025/3/12 10:42
     * @param: date
     * @return: java.util.Date
     **/
    private Date parseDateTimeDay(Date date){
        return DateUtil.parseDateTime(DateUtil.formatDateTime(date));
    }

    /**
     * @description: 拼接 日期天 加时间 date yyyy-MM-dd + time HH:mm:ss  flag 是否 加后缀 :00
     * @author: lihong
     * @date: 2025/3/12 10:29
     * @param: date
     * @param: time
     * @return: java.util.Date
     **/
    private Date addDateTime(String date,String time,boolean flag){
        if(flag){
            return DateUtil.parseDateTime(date + " "+time +":00");
        }else {
            return DateUtil.parseDateTime(date + " "+time);
        }
    }


    private void dealYzAct(Map<String, YzSupplyType> supplyMap, YzActOrder item) {
        item.setDrugQuan(Convert.toBigDecimal(item.getDrugQuan(), BigDecimal.ONE));
        item.setDrugOcc(Convert.toBigDecimal(item.getDrugQuan(), BigDecimal.ONE));
        if (FREQ_CODE_ONCE.equals(item.getFrequCode())) {
            item.setEndTime(null);
        }
        //d:西药;i:大输液;z:中成药
        //if ("d".equals(item.getDrugFlag()) || "i".equals(item.getDrugFlag()) || "z".equals(item.getDrugFlag())) {
        //        //    item.setDrugQuan(BigDecimal.ZERO);
        //        //    item.setDrugOcc(BigDecimal.ZERO);
        //        //}
        item.setInfantFlag(item.getInpatientNo().contains("$") ? "1" : "0");
        if (CollUtil.isNotEmpty(supplyMap) && StrUtil.isNotBlank(item.getSupplyCode())) {
            item.setSupplyClass(supplyMap.get(item.getSupplyCode()) != null ? supplyMap.get(item.getSupplyCode()).getSupplyClass() : null);
        }
        item.setSerial(StrUtil.isBlank(item.getSerial()) ? "01" : item.getSerial());
        item.setPaySelf("007".equals(item.getSupplyCode()) ? "1" : item.getPaySelf());
        item.setAlwaysFlag(item.getStartTime().equals(item.getEndTime()) || FREQ_CODE_ONCE.equals(item.getFrequCode()) ? "t" : "a");
        //自备赋值
        item.setBuyFlag(false);
        if(NumberEnum.ONE.getCode().equals(item.getSelfBuy())){
            item.setBuyFlag(true);
            item.setIbBuyName("（自备）");
        }else if(NumberEnum.TWO.getCode().equals(item.getSelfBuy())){
            item.setBuyFlag(true);
            item.setIbBuyName("（嘱托）");
        }else if(NumberEnum.ThREE.getCode().equals(item.getSelfBuy())){
            item.setIbBuyName("（基数药）");
        }else {
            item.setIbBuyName("");
        }
    }


    /***
     * @description: 获取周的执行时间
     * @author: lihong
     * @date: 2024/1/9 14:47
     * @param: filedName
     * @return: java.lang.String  返回  7 1 2 ... 周几
     **/
    private static String calcWeekFreqOccTime(String filedName) {
        if (!filedName.startsWith(prefixWeek)) {
            throw new IllegalArgumentException("周频率字段格式不对[" + filedName + "]");
        }
        return StrUtil.removePrefix(filedName, "week");
    }

    /**
     * @description: 获取频率执行时间
     * @author: lihong
     * @date: 2024/1/9 15:02
     * @param: filedName 字段名称  day2400  day130
     * @return: java.lang.String 返回格式 时分秒 HH:mm:ss
     **/
    private static String calcDayOccTime(String filedName) {
        if (!filedName.startsWith(prefixDay)) {
            throw new IllegalArgumentException("天频率字段格式不对[" + filedName + "]");
        }
        String dayOccTime = StrUtil.removePrefix(filedName, prefixDay);
        if ("2400".equals(dayOccTime)) {
            return "00:00:00";
        } else if (dayOccTime.length() == Integer.valueOf(NumberEnum.ThREE.getCode())) {
            return StrUtil.format("0{}:{}:00", dayOccTime.substring(0, 1), dayOccTime.substring(1));
        } else if (dayOccTime.length() == Integer.valueOf(NumberEnum.FOUR.getCode())) {
            return StrUtil.format("{}:{}:00", dayOccTime.substring(0, 2), dayOccTime.substring(2));
        } else {
            log.info("字段:{}不符合格式", filedName);
            throw new IllegalArgumentException("天频率字段格式不对[" + filedName + "]");
        }
    }

    /**
     * @description: 转换为医嘱药品数据
     * @author: lihong
     * @date: 2024/1/9 16:53
     * @param: zyActpatient
     * @param: yzActOrder
     * @param: occTime
     * @param: zdChargeItem
     * @return: thyyxxk.webserver.entity.executeItem.YzYpZyOrder
     **/
    private static YzYpZyOrder convert2YzYpZyOrder(ZyActpatient zyActpatient, YzActOrder yzActOrder, YpZdDictVo ypZdDictVo, Date occTime,Map<String, YpZdGroupName> zdGroupMap) {
        YzYpZyOrder yzYpZyOrder = YzYpZyOrder.builder()
                .actOrderNoStr(yzActOrder.getActOrderNo().toPlainString())
                .inpatientNo(zyActpatient.getInpatientNo())
                .admissTimes(zyActpatient.getAdmissTimes())
                .actOrderNo(yzActOrder.getActOrderNo())
                .alwaysFlag(yzActOrder.getAlwaysFlag())
                //待定 待核对
                .amount(Convert.toBigDecimal(yzActOrder.getDrugQuan(),BigDecimal.ONE).compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ONE : Convert.toBigDecimal(yzActOrder.getDrugQuan(),BigDecimal.ONE))
                .bedNo(zyActpatient.getBedNo())
                .chargeCode(ypZdDictVo.getCode())
                .chargeDate(DateUtil.parseDate(DateUtil.formatDate(occTime)))
                .deptCode(zyActpatient.getDeptCode())
                .drawer(TokenUtil.getInstance().getTokenUserId())
                .drugClass(yzActOrder.getOccType())
                .infantFlag(zyActpatient.getInpatientNo().contains("$") ? "1" : "0")
                .name(zyActpatient.getName())
                //默认给1
                .statusFlag(PageClassEnum.JSY.getCode().equals(yzActOrder.getSelfBuy()) ? "3" : "1")
                .wardCode(zyActpatient.getWardCode())
                .retprice(ypZdDictVo.getPackRetprice())
                .serial(ypZdDictVo.getSerial())
                .serail(0)
                .groupNo(yzActOrder.getGroupNo())
                .doctorName(yzActOrder.getPhysician())
                //需要计算暂时不给
                .pageClass(getPageClass(yzActOrder,ypZdDictVo,zdGroupMap))
                .drugFlag(ypZdDictVo.getDrugFlag())
                .occTime(occTime)
                .pageNo(BigDecimal.ZERO)
                .paySelf(yzActOrder.getPaySelf())
                .supriceFlag(Convert.toStr(ypZdDictVo.getSupriceFlag()))
                .separateFlag(ypZdDictVo.getSeparateFlag())
                .zySerialNo(zyActpatient.getZySerialNo())
                .selfFlag(ypZdDictVo.getSelfFlag())
                .build();
        return yzYpZyOrder;
    }

    /**
     * @description: 转换为医嘱执行数据
     * @author: lihong
     * @date: 2024/1/9 16:52
     * @param: zyActpatient
     * @param: yzActOrder
     * @param: occTime
     * @param: zdChargeItem
     * @return: thyyxxk.webserver.entity.executeItem.YzActOcc
     **/
    private static YzActOcc convert2YzActOcc(ZyActpatient zyActpatient, YzActOrder yzActOrder, ZdChargeItem zdChargeItem, Date occTime,YpZdDictVo ypZdDictVo,Map<String, YpZdGroupName> zdGroupMap) {
        String parentSort = null;
        String orderName = yzActOrder.getOrderName();
        BigDecimal parentNo = yzActOrder.getParentNo();
        if(!"00".equals(yzActOrder.getGroupNo())){
            if(yzActOrder.getActOrderNo().compareTo(BigDecimal.ZERO) < 0){
                parentSort = yzActOrder.getActOrderNo().abs() + ".";
                parentNo = yzActOrder.getActOrderNo().abs();
            }else {
                orderName = !yzActOrder.getOrderName().startsWith("--") && yzActOrder.getParentNo() != null ? "--"+yzActOrder.getOrderName() : yzActOrder.getOrderName();
                parentSort = yzActOrder.getParentNo() != null ? Convert.toStr(yzActOrder.getParentNo()) + "." + DateUtil.format(new Date(), DatePattern.PURE_TIME_PATTERN) : null;
            }
        }
        YzActOcc yzActOcc = YzActOcc.builder()
                .actOrderNoStr(yzActOrder.getActOrderNo().toPlainString())
                .actOrderNo(yzActOrder.getActOrderNo())
                .admissTimes(zyActpatient.getAdmissTimes())
                .alwaysFlag("ONCE".equals(yzActOrder.getFrequCode()) ? "t" : "a")
                .bedNo(zyActpatient.getBedNo())
                .chargeCode(ypZdDictVo != null ? yzActOrder.getOrderCode() : zdChargeItem.getCode())
                .deptCode(zyActpatient.getDeptCode())
                .wardCode(zyActpatient.getWardCode())
                .discription(yzActOrder.getDiscription())
                .infantFlag(zyActpatient.getInpatientNo().contains("$") ? "1" : "0")
                .inpatientName(zyActpatient.getName())
                .inpatientNo(zyActpatient.getInpatientNo())
                .occName(ypZdDictVo != null ? StrUtil.sub(ypZdDictVo.getName(),0,20) : StrUtil.sub(zdChargeItem.getName(),0,20))
                .occTime(occTime)
                .occType(yzActOrder.getOccType())
                .phyName(yzActOrder.getPhysician())
                .parentNo(parentNo)
                //待定  有 附加费 啥的
                .specification("00".equals(yzActOrder.getGroupNo()) ? "诊疗项目" : yzActOrder.getActOrderNo().compareTo(BigDecimal.ZERO) < 0 ? "附加收费" : yzActOrder.getDrugSpecification())
                .occOper(TokenUtil.getInstance().getTokenUserId())
                //这个没啥用随便给
                .parentSort(parentSort)
                .drugQuan(Convert.toBigDecimal(yzActOrder.getDrugOcc(),BigDecimal.ONE).multiply(zdChargeItem ==null ? BigDecimal.ONE: Convert.toBigDecimal(zdChargeItem.getAmount(),BigDecimal.ONE)))
                .drugQuan2(Convert.toBigDecimal(yzActOrder.getDrugQuan(),BigDecimal.ONE).multiply(zdChargeItem ==null ? BigDecimal.ONE: Convert.toBigDecimal(zdChargeItem.getAmount(),BigDecimal.ONE)))
                .execUnit(zdChargeItem !=null && StrUtil.isNotBlank(zdChargeItem.getExecUnit()) ? zdChargeItem.getExecUnit() : yzActOrder.getExecUnit())
                .dose(Convert.toStr(yzActOrder.getDose()))
                .pageNo(0)
                .orderName(orderName)
                .paySelf(yzActOrder.getPaySelf())
                .groupNo(yzActOrder.getGroupNo())
                .frequCode(yzActOrder.getFrequCode())
                .retprice(zdChargeItem != null ? Convert.toBigDecimal(zdChargeItem.getChargeAmount(),BigDecimal.ZERO) : ypZdDictVo.getPackRetprice())
                .serial(yzActOrder.getSerial())
                .doseUnit(yzActOrder.getDoseUnit())
                .pageClass(getPageClass(yzActOrder,ypZdDictVo,zdGroupMap))
                .supplyCode(yzActOrder.getSupplyCode())
                .instruction(StrUtil.sub(yzActOrder.getInstruction(),0,20))
                .zySerialNo(zyActpatient.getZySerialNo())
                .build();
        if(Convert.toBigDecimal(yzActOcc.getDrugQuan(),BigDecimal.ONE).compareTo(BigDecimal.ZERO) == 0){
            yzActOcc.setDrugQuan(BigDecimal.ONE);
        }
        if(Convert.toBigDecimal(yzActOcc.getDrugQuan2(),BigDecimal.ONE).compareTo(BigDecimal.ZERO) == 0){
            yzActOcc.setDrugQuan2(BigDecimal.ONE);
        }
        return yzActOcc;
    }



    private static String getPageClass(YzActOrder yzActOrder,YpZdDictVo ypZdDictVo,Map<String, YpZdGroupName> zdGroupMap) {
        String pageClass = "";
        if(!"00".equals(yzActOrder.getGroupNo()) && StrUtil.isNotBlank(yzActOrder.getGroupNo())){
            //出院带药
            if(NumberEnum.FOUR.getCode().equals(yzActOrder.getSelfBuy())){
                pageClass = PageClassEnum.CYDY.getCode();
            }else {
                if(ypZdDictVo != null && Convert.toInt(ypZdDictVo.getDrugFlag(),0) > 0){
                    pageClass = PageClassEnum.DMY.getCode();
                }
                else if(PageClassEnum.JSY.getCode().equals(yzActOrder.getSelfBuy())){
                    pageClass = PageClassEnum.JSY.getCode();
                }
                else if(DSY.equals(yzActOrder.getOccType())){
                    pageClass = PageClassEnum.DSY.getCode();
                }
                else if(KF.equals(yzActOrder.getOccType())){
                    if("a".equals(yzActOrder.getAlwaysFlag())){
                        pageClass = PageClassEnum.CQKF.getCode();
                    }else {
                        pageClass = PageClassEnum.LSKF.getCode();
                    }
                }
                else {
                    YpZdGroupName ypZdGroupName = zdGroupMap.get(yzActOrder.getGroupNo());
                    if(ypZdGroupName != null){
                        if(NumberEnum.ONE.getCode().equals(ypZdGroupName.getMzFlag())){
                            pageClass = PageClassEnum.MZLYD.getCode();
                        }else {
                            pageClass = PageClassEnum.TLD.getCode();
                        }
                    }
                }
            }
        }
        return pageClass;
    }



    /**
     * @description: 转换为医嘱病人接口数据 收费信息
     * @author: lihong
     * @date: 2024/1/9 16:52
     * @param: zyActpatient
     * @param: yzActOrder
     * @param: occTime
     * @param: zdChargeItem
     * @return: thyyxxk.webserver.entity.executeItem.YzZyPatientFee
     **/
    private static YzZyPatientFee convert2YzZyPatientFee(ZyActpatient zyActpatient, YzActOrder yzActOrder, ZdChargeItem zdChargeItem, Date occTime,GenerateYzVo param) {
        List<String> yjDeptCodes = param.getYjDeptCodes();
        String execUnit = yzActOrder.getExecUnit();
        String chargeStatus = "1";
        if(execUnit != null && CollUtil.isNotEmpty(yjDeptCodes)){
            if(yjDeptCodes.stream().anyMatch(obj -> obj.equals(execUnit))){
                chargeStatus = "3";
            }
        }
        YzZyPatientFee yzZyPatientFee = YzZyPatientFee.builder()
                .actOrderNoStr(yzActOrder.getActOrderNo().toPlainString())
                .inpatientNo(zyActpatient.getInpatientNo())
                .admissTimes(zyActpatient.getAdmissTimes())
                .actOrderNo(yzActOrder.getActOrderNo())
                .detailSn(0)
                .chargeCode(zdChargeItem.getCode())
                .chargeDate(DateUtil.parseDate(DateUtil.formatDate(occTime)))
                .chargeFee(zdChargeItem.getChargeAmount())
                .chargeStatus(chargeStatus)
                .infantFlag(zyActpatient.getInpatientNo().contains("$") ? "1" : "0")
                .opIdCode(TokenUtil.getInstance().getTokenUserId())
                .occTime(occTime)
                .deptCode(zyActpatient.getDeptCode())
                .wardCode(zyActpatient.getWardCode())
                .orderCount(Convert.toBigDecimal(yzActOrder.getDrugQuan(),BigDecimal.ONE).multiply(Convert.toBigDecimal(zdChargeItem.getAmount(),BigDecimal.ONE)))
                .paySelf(yzActOrder.getPaySelf())
                .execUnit(execUnit)
                .selfFlag(Convert.toStr(zdChargeItem.getSelfFlag()))
                .zySerialNo(zyActpatient.getZySerialNo())
                .separateFlag(zdChargeItem.getSeparateFlag())
                .suppressFlag(Convert.toStr(zdChargeItem.getSuppressFlag()))
                .build();
        return yzZyPatientFee;
    }


}
