package com.zd.chemical.service.impl;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.atomic.LongAdder;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

import cn.hutool.core.util.NumberUtil;
import com.alibaba.nacos.shaded.org.checkerframework.checker.nullness.Opt;
import com.zd.chemical.domain.*;
import com.zd.chemical.domain.vo.*;
import com.zd.chemical.mapper.*;
import com.zd.chemical.service.IActAuditconfigService;
import com.zd.common.core.domain.per.PerPrefix;
import com.zd.common.core.utils.DateUtils;
import com.zd.common.core.utils.SecurityUtils;
import com.zd.common.core.utils.StringUtils;
import com.zd.common.datascope.annotation.DataScope;
import com.zd.common.security.utils.SaveUtil;

import com.zd.system.api.laboratory.RemoteLaboratoryService;
import com.zd.system.api.laboratory.domain.LabMessageContent;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.zd.chemical.service.IActHxpapplyService;

import javax.swing.text.html.Option;

/**
 * 化学品申购Service业务层处理
 *
 * @author zd
 * @date 2022-08-17
 */
@Service
public class ActHxpapplyServiceImpl implements IActHxpapplyService
{
    @Autowired
    private ActHxpapplyMapper actHxpapplyMapper;

    @Autowired
    private ActHxpapplyDetailMapper actHxpapplyDetailMapper;

    @Autowired
    private ActApplytaskMapper actApplytaskMapper;

    @Autowired
    private ActApplytaskNodeMapper actApplytaskNodeMapper;

    @Autowired
    private IActAuditconfigService actAuditconfigService;

    @Autowired
    private ActAudituserMapper actAudituserMapper;

    @Autowired
    private RemoteLaboratoryService remoteLaboratoryService;

    /**
     * 查询化学品申购
     *
     * @param id 化学品申购主键
     * @return 化学品申购
     */
    @Override
    public ActHxpapplyInfoVo selectActHxpapplyById(Long id,Integer tickStatus)
    {
        // 利用申请的id,查询出工作流对应的配置节点
        ActApplytask actApplytask = new ActApplytask();
        actApplytask.setTaskId(id);
        List <ActApplytask> actApplytasks = actApplytaskMapper.selectActApplytaskList(actApplytask);
        Function<List <ActApplytask>,ActApplytask> function = x->x.stream().findFirst().orElse(null);
        ActApplytask apply = function.apply(actApplytasks);
        Predicate<List <ActApplytask>> pre = p->p.size()>0;
        // 查询申请单相关的化学品详细信息列表
        ActHxpapplyInfoVo actHxpapplyInfoVo = actHxpapplyMapper.selectActHxpapplyById(id);
        ActHxpapplyDetail actHxpapplyDetail = new ActHxpapplyDetail();
        actHxpapplyDetail.setHxpapplyId(id);
        actHxpapplyDetail.setTickStatus(tickStatus);
        Consumer<List<ActHxpapplyDetailVo>> consumer = x->Optional.ofNullable(x).orElseGet(Collections::emptyList)
                .stream().forEach(b->{
                    ActRestStockVo actRestStockVo = new ActRestStockVo();
                    actRestStockVo.setDeptId(actHxpapplyInfoVo.getDeptId());
                    actRestStockVo.setSubId(actHxpapplyInfoVo.getSubId());
                    actRestStockVo.setCabinetId(b.getCabinetId());
                    actRestStockVo.setChemicalId(b.getChemicalId());
//                    Map <String, String> restStock = iActHxpapplyService.getRestStock(actRestStockVo);
//                    b.setRemainingStorage(restStock.get("restStock"));
                    if(pre.test(actApplytasks)){
                        getRestStockClassif(actRestStockVo,b,actHxpapplyInfoVo.getUserId(),apply.getApprovalStatus().intValue());
                    }else{
                        getRestStockClassif(actRestStockVo,b,actHxpapplyInfoVo.getUserId(),-1);
                    }
                });
        List <ActHxpapplyDetailVo> actHxpapplyDetailVos = actHxpapplyDetailMapper.selectApplyDetailList(actHxpapplyDetail);
        consumer.accept(actHxpapplyDetailVos);
        actHxpapplyInfoVo.setActHxpapplyDetailList(actHxpapplyDetailVos);

        // 查出工作流子节点
        if(pre.test(actApplytasks)){
            actHxpapplyInfoVo.setActApplytask(apply);
            actHxpapplyInfoVo.setApprovalStatus(apply.getApprovalStatus());
            ActApplytaskNode actApplytaskNode = new ActApplytaskNode();
            actApplytaskNode.setApplytaskId(apply.getId());
            List <ActApplytaskNodeVo> actApplytaskNodes = actApplytaskNodeMapper.selectActApplytaskNodeInfoList(actApplytaskNode);
            List <Long> nodeCollect = Optional.ofNullable(actApplytaskNodes).orElseGet(Collections::emptyList)
                    .stream().map(ActApplytaskNodeVo::getAuditconfigId).collect(Collectors.toList());
            List <ActAuditconfig> listByConfig = actAuditconfigService.getListByIds(nodeCollect);
            List <ActAuditconfigInfoVo> configInfoList = Optional.ofNullable(listByConfig).orElseGet(Collections::emptyList)
                    .stream()
                    .map(c -> {
                        ActAuditconfigInfoVo actAuditconfigInfoVo = new ActAuditconfigInfoVo();
                        BeanUtils.copyProperties(c, actAuditconfigInfoVo);
                        //判断审批的环节状态
                        Map<String,Integer> applyTaskStatus = new HashMap <>();
                        applyTaskStatus.put("applyTaskStatus",0);
                        //获取环节审批的最后一个人审批的时间
                        Map<String,Date> applyTaskTime = new HashMap <>();
                        List <ActApplytaskNodeVo> collect = Optional.ofNullable(actApplytaskNodes).orElseGet(Collections::emptyList)
                                .stream().filter(n -> n.getAuditconfigId() == c.getId())
                                .map(n->{
                                    if(StringUtils.isNotNull(n.getUpdateTime())){
                                        applyTaskTime.put("applyTaskTime",n.getUpdateTime());
                                    }
                                    if(n.getNodeStatus()==1){
                                        applyTaskStatus.put("applyTaskStatus",n.getNodeStatus());
                                    }else if(n.getNodeStatus()==2){
                                        applyTaskStatus.put("applyTaskStatus",n.getNodeStatus());
                                        actAuditconfigInfoVo.setRefuseContent(n.getNodeContent());
                                    }else if(n.getNodeStatus()==0 && applyTaskStatus.get("applyTaskStatus")!=2){
                                        applyTaskStatus.put("applyTaskStatus",n.getNodeStatus());
                                    }

                                    String[] applyUserArr = n.getApplyUserInfo().split(";");
                                    Arrays.asList(applyUserArr).stream()
                                            .forEach(arr->{
                                                String[] arrInfo = arr.split(",");
                                                Map<String,String> userInfo = new HashMap<>();
                                                userInfo.put("id",arrInfo[0]);
                                                userInfo.put("name",arrInfo[1]);
                                                userInfo.put("avatar",arrInfo[2]);
                                                userInfo.put("postName",arrInfo[3]);
                                                n.getApplyUserList().add(userInfo);
                                            });
                                    return n;
                                })
                                .collect(Collectors.toList());
                        actAuditconfigInfoVo.setActApplytaskNodeList(collect);
                        actAuditconfigInfoVo.setApplyTaskStatus(applyTaskStatus.get("applyTaskStatus"));
                        actAuditconfigInfoVo.setApplyTaskTime(applyTaskTime.get("applyTaskTime"));
                        return actAuditconfigInfoVo;
                    }).collect(Collectors.toList());
            actHxpapplyInfoVo.setConfigInfoList(configInfoList);
        }else{
            // 如果是草稿箱的，需要查询机柜化学品剩余量的计算值
            List <Long> cabinetCollect = Optional.ofNullable(actHxpapplyDetailVos).orElseGet(Collections::emptyList)
                    .stream()
                    .map(ActHxpapplyDetailVo::getCabinetId)
                    .collect(Collectors.toList());
            List <Long> chemicalCollect = Optional.ofNullable(actHxpapplyDetailVos).orElseGet(Collections::emptyList)
                    .stream()
                    .map(ActHxpapplyDetailVo::getChemicalId)
                    .collect(Collectors.toList());

            ActRestStockManySearch actRestStockVo = new ActRestStockManySearch();
            actRestStockVo.setChemicalIds(chemicalCollect);
            actRestStockVo.setCabinetIds(cabinetCollect);
            List <ActRestStockManyVo> restStockByManyCabinetAndChemical = this.getRestStockByManyCabinetAndChemical(actRestStockVo);


            Optional.ofNullable(actHxpapplyDetailVos)
                    .orElseGet(Collections::emptyList)
                    .stream()
                    .forEach(a->Optional.ofNullable(restStockByManyCabinetAndChemical)
                    .orElseGet(Collections::emptyList)
                    .stream()
                    .filter(b->(b.getCabinetId().longValue()==a.getCabinetId().longValue()&&b.getChemicalId().longValue()==a.getChemicalId().longValue()))
                    .forEach(c->{
                        a.setRemainingStorage(c.getRestStock());
                    }));

        }
        return actHxpapplyInfoVo;
    }


    /**
     * 获取化学品剩余可存放量分类统计
     *
     * @param actRestStockVo 机柜主键主键
     * @return 化学品申购
     */
    public void getRestStockClassif(ActRestStockVo actRestStockVo,ActHxpapplyDetailVo b,Long applyUserId,int approvalStatus)
    {
        actRestStockVo.setApplyUserId(applyUserId);
        List<ActRestStockVo> restStock = actHxpapplyMapper.getRestStockClassif(actRestStockVo);
        Optional.ofNullable(restStock).orElseGet(Collections::emptyList)
                .stream()
                .forEach(a->{
                    if(a.getChemicalId()==1){
                        b.setCollegeInventory(a.getRestStock());
                    }else if(a.getChemicalId()==2){
                        b.setSubInventory(a.getRestStock());
                    }else if(a.getChemicalId()==3){
                        b.setCabinetStorage(a.getRestStock());
                    }else if(a.getChemicalId()==4){
                        if(approvalStatus!=1){
                            b.setRemainingStorage(a.getRestStock());
                        }
                    }
                });
    }


    /**
     * 查询化学品申购列表
     *
     * @param actHxpapplySearch 化学品申购
     * @return 化学品申购
     */
    @Override
    @DataScope(deptAlias = "st", userAlias = "ah", permi = PerPrefix.ACT_HXP_APPLY)
    public List<ActHxpapplyListVo> selectActHxpapplyList(ActHxpapplySearch actHxpapplySearch)
    {
        actHxpapplySearch.setLoginUserId(SecurityUtils.getUserId());
        List <ActHxpapplyListVo> actHxpapplyListVos = actHxpapplyMapper.selectActHxpapplyList(actHxpapplySearch);
        Optional.ofNullable(actHxpapplyListVos).orElseGet(Collections::emptyList)
                .stream()
                .forEach(a->{
                    Predicate<String> pre = p->StringUtils.isNotEmpty(p);
                    if(pre.test(a.getCurrentApprover())){
                        String[] userList = a.getCurrentApprover().split(",");
                        a.getCurrentUserList().addAll(userChengeList(userList));
                    }
                    if(pre.test(a.getHistoryApprover())){
                        String[] userList = a.getHistoryApprover().split(",");
                        a.getHistoryUserList().addAll(userChengeList(userList));
                    }
                });
        return actHxpapplyListVos;
    }

    /**
     * 查询化学品申购列表(草稿箱)
     *
     * @param actHxpapplySearch 化学品申购
     * @return 化学品申购
     */
    @Override
    public List<ActHxpapplyDraftsListVo> draftsList(ActHxpapplySearch actHxpapplySearch)
    {
        List <ActHxpapplyDraftsListVo> actHxpapplyListVos = actHxpapplyMapper.draftsList(actHxpapplySearch);
        return actHxpapplyListVos;
    }


    private List<LinkedHashMap<String,String>> userChengeList(String[] userList){
        List<LinkedHashMap<String,String>> userAllList = new ArrayList <>();
        for(int x=0;x<userList.length;x++){
            LinkedHashMap<String,String> userMap = new LinkedHashMap <>();
            String[] userInfo = userList[x].split(";");
            userMap.put("id",userInfo[0]);
            userMap.put("name",userInfo[1]);
            userAllList.add(userMap);
        }

        return userAllList;
    }

    @Override
    public List<ActHxpapply> getListByIds(List<Long> ids){
        if (ids.isEmpty()){
            new ArrayList <>();
        }
        return actHxpapplyMapper.getListByIds(ids);
    }

    /**
     * 新增化学品申购
     *
     * @param actHxpapplyVo 化学品申购
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertActHxpapply(ActHxpapplyVo actHxpapplyVo)
    {
        //查询vo如果有id,就是修改，需要删除原来的数据，重新添加。
        String historyNum = "";
        if(StringUtils.isNotNull(actHxpapplyVo.getId())){
            ActHxpapplyInfoVo actHxpapplyInfoVo = actHxpapplyMapper.selectActHxpapplyById(actHxpapplyVo.getId());
            historyNum = actHxpapplyInfoVo.getApplyNum();
            //删除原来的化学品申请单
            actHxpapplyDetailMapper.deleteActHxpapplyDetailByApplyId(actHxpapplyVo.getId());
            actHxpapplyMapper.deleteActHxpapplyById(actHxpapplyVo.getId());
        }
        ActHxpapply actHxpapply = new ActHxpapply();
        BeanUtils.copyProperties(actHxpapplyVo,actHxpapply);
        //设置其他公共字段
        SaveUtil.setCommonAttr(actHxpapply);
        if(StringUtils.isNotEmpty(historyNum)){
            actHxpapply.setApplyNum(historyNum);
        }else{
            actHxpapply.setApplyNum(generateApplyNum());
        }
        actHxpapplyMapper.insertActHxpapply(actHxpapply);
        Optional.ofNullable(actHxpapplyVo.getActHxpapplyDetailList()).orElseGet(Collections::emptyList)
                .stream()
                .forEach(a->{
                    a.setHxpapplyId(actHxpapply.getId());
                    actHxpapplyDetailMapper.insertActHxpapplyDetail(a);
                });
        if(actHxpapplyVo.getApplyStatus()==1){
            Long createUserId = actHxpapply.getUserId();
            //这里启动工作流
            ActApplytask actApplytask = new ActApplytask();
            actApplytask.setTaskId(actHxpapply.getId());
            actApplytask.setTaskName("化学品申请工作流");
            actApplytask.setTaskType(1);
            actApplytask.setCreateTime(new Date());
            actApplytaskMapper.insertActApplytask(actApplytask);
            //这里需要动态生成工作流的节点任务
            generateNode(actApplytask,createUserId);
        }
        return 1;
    }

    // 生成申购编号
    private String generateApplyNum(){
        LocalDateTime localDateTime = LocalDateTime.now();
        return localDateTime.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
    }

    public void generateNode(ActApplytask actApplytask,Long createUserId){
        ActAuditconfig actAuditconfig = new ActAuditconfig();
        actAuditconfig.setAuditStatus(1);
        List<ActAuditconfig> actAuditconfigList = actAuditconfigService.selectActAuditconfigList(actAuditconfig);
        Function <List<ActAuditconfig>,List<Long>> function = x-> x.parallelStream().map(ActAuditconfig::getId).collect(Collectors.toList());
        List<ActAudituser> actAudituserList = actAudituserMapper.getListByIds(function.apply(actAuditconfigList));
        LongAdder countAdder = new LongAdder();
        //当前步数和下一步的map
        Map<String,Long> stepMap = new HashMap <>();
        stepMap.put("nowStep",-1L);
        stepMap.put("nextStep",-1L);
        //这里做一个跳过审核的map，暂时这么写吧，没有想到更好的办法了，啊啊啊啊，头疼（1表示第一次申请人就是审批人的需要跳过,2表示需要结束跳过）
        Map<String,Long> jumpApply = new HashMap<>();
        jumpApply.put("jumpApply",1L);
        Predicate<List <ActAudituser>> pre = x->Optional.ofNullable(x).orElseGet(Collections::emptyList).stream().filter(y->y.getAuditUserId().longValue()==createUserId.longValue()).count()>0;
        Optional.ofNullable(actAuditconfigList).orElseGet(Collections::emptyList)
                .stream()
                .map(a->{
                    if(a.getAuditType()==2){
                        countAdder.add(1);
                        List <ActAudituser> collect = Optional.ofNullable(actAudituserList).orElseGet(Collections::emptyList).stream()
                                .filter(b->b.getConfigId()==a.getId())
                                .sorted((s1, s2) -> NumberUtil.compare(s1.getAuditOrder(), s2.getAuditOrder()))
                                .collect(Collectors.toList());

                        ActApplytaskNode actApplytaskNode = new ActApplytaskNode();
                        StringBuffer stringBuffer = new StringBuffer();
                        //这里生成或签的规则。
                        jumpApplyFun(pre,collect,jumpApply,actApplytaskNode,actApplytask);
                        Optional.ofNullable(collect).orElseGet(Collections::emptyList)
                                .stream()
                                .forEach(c1->{
                                    stringBuffer.append(",");
                                    stringBuffer.append(c1.getAuditUserId());

                                });

                        if(stringBuffer.length()>0){
                            actApplytaskNode.setNodeName("流程节点："+countAdder.sum());
                            actApplytaskNode.setApplytaskId(actApplytask.getId());
                            actApplytaskNode.setApplyUserIds(stringBuffer.substring(1));
                            actApplytaskNode.setNodeOrder(Integer.parseInt(countAdder.sum()+""));
                            actApplytaskNode.setAuditconfigId(a.getId());
                            insertNodeSave(actApplytaskNode);
                        }
                    }
                    return a;
                })
                .forEach(a->{
                    if(a.getAuditType()==1){
                        //这里生成依次审批规则。
                        Optional.ofNullable(actAudituserList).orElseGet(Collections::emptyList).stream()
                                .filter(b->b.getConfigId()==a.getId())
                                .sorted((s1, s2) -> NumberUtil.compare(s1.getAuditOrder(), s2.getAuditOrder()))
                                .collect(Collectors.toList())
                                .stream()
                                .forEach(f->{
                                    countAdder.add(1);
                                    ActApplytaskNode actApplytaskNode = new ActApplytaskNode();
                                    actApplytaskNode.setNodeName("流程节点："+countAdder.sum());
                                    actApplytaskNode.setApplytaskId(actApplytask.getId());
                                    actApplytaskNode.setApplyUserIds(f.getAuditUserId()+"");
                                    actApplytaskNode.setNodeOrder(Integer.parseInt(countAdder.sum()+""));
                                    jumpApplyFun(createUserId,f.getAuditUserId(),jumpApply,actApplytaskNode,actApplytask);
                                    actApplytaskNode.setAuditconfigId(a.getId());
                                    insertNodeSave(actApplytaskNode);
                                });
                    }
                });
        //调用回填步数的方法
        proStep(stepMap,actApplytask,createUserId);
    }

    // 这里做了执行task回填步数
    private void proStep(Map<String,Long> stepMap,ActApplytask actApplytask,Long createUserId){
        actApplytask.setNowStep(stepMap.get("nowStep"));
        actApplytask.setNextStep(stepMap.get("nextStep"));
        ActApplytaskNode actApplytaskNode = new ActApplytaskNode();
        actApplytaskNode.setNodeStatus(0);
        actApplytaskNode.setApplytaskId(actApplytask.getId());
        List <ActApplytaskNode> actApplytaskNodes = actApplytaskNodeMapper.selectActApplytaskNodeList(actApplytaskNode);
        for(int i=0;i<actApplytaskNodes.size();i++){
            if(i==0){
                actApplytask.setNowStep(actApplytaskNodes.get(i).getId());
            }
            if(i==1){
                actApplytask.setNextStep(actApplytaskNodes.get(i).getId());
            }
        }
        if(actApplytaskNodes.size()==0){
            actApplytask.setOverTime(new Date());
            actApplytask.setApprovalStatus(1);
            //发送审批通过的消息
            LabMessageContent labMessageContent = new LabMessageContent();
            labMessageContent.setSendRange(3);
            labMessageContent.setMessClass(1);
            labMessageContent.setContent("你的采购申请审批已通过，请尽快存放入库。");
            labMessageContent.setUserIds(createUserId+"");
            labMessageContent.setUserId(-2L);
            labMessageContent.setCreateTime(new Date());
            labMessageContent.setCreateBy("系统");
            remoteLaboratoryService.publishMess(labMessageContent);
        }
        actApplytaskMapper.updateActApplytask(actApplytask);
    }

    // 这里处理一下跳过审核，只有当前审批人是申请人的时候，才做审批通过（或审）
    private void jumpApplyFun(Predicate<List <ActAudituser>> pre,List <ActAudituser> actAuditusers,Map<String,Long> jumpApply,ActApplytaskNode actApplytaskNode,ActApplytask actApplytask){
        if(pre.test(actAuditusers) && jumpApply.get("jumpApply")==1){
            actApplytaskNode.setNodeStatus(1);
            actApplytaskNode.setApplyUserid(SecurityUtils.getUserId());
            actApplytaskNode.setUpdateTime(new Date());
            //todo 这里如果是当前用户跳过的，需要把事情的化学品全部修改为勾选
            ActHxpapplyDetail actHxpapplyDetail = new ActHxpapplyDetail();
            actHxpapplyDetail.setHxpapplyId(actApplytask.getTaskId());
            actHxpapplyDetailMapper.updateActHxpapplyDetailByPass(actHxpapplyDetail);
            jumpApply.put("jumpApply",1L);
        }else{
            jumpApply.put("jumpApply",2L);
        }
    }

    // 这里处理一下跳过审核，只有当前审批人是申请人的时候，才做审批通过(依次审批)
    private void jumpApplyFun(Long createUserId,Long auditUserId,Map<String,Long> jumpApply,ActApplytaskNode actApplytaskNode,ActApplytask actApplytask){
        if(createUserId.longValue() == auditUserId.longValue() && jumpApply.get("jumpApply")==1){
            actApplytaskNode.setNodeStatus(1);
            actApplytaskNode.setApplyUserid(SecurityUtils.getUserId());
            actApplytaskNode.setUpdateTime(new Date());
            //todo 这里如果是当前用户跳过的，需要把事情的化学品全部修改为勾选
            ActHxpapplyDetail actHxpapplyDetail = new ActHxpapplyDetail();
            actHxpapplyDetail.setHxpapplyId(actApplytask.getTaskId());
            actHxpapplyDetailMapper.updateActHxpapplyDetailByPass(actHxpapplyDetail);
            jumpApply.put("jumpApply",1L);
        }else{
            jumpApply.put("jumpApply",2L);
        }
    }

    // 提出工作流节点保存
    private void insertNodeSave(ActApplytaskNode actApplytaskNode){
        actApplytaskNodeMapper.insertActApplytaskNode(actApplytaskNode);
    }


    /**
     * 修改化学品申购
     *
     * @param actHxpapply 化学品申购
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateActHxpapply(ActHxpapply actHxpapply)
    {
        actHxpapply.setUpdateTime(DateUtils.getNowDate());
        actHxpapply.setUpdateBy(SecurityUtils.getUsername());
        return actHxpapplyMapper.updateActHxpapply(actHxpapply);
    }

    /**
     * 批量删除化学品申购
     *
     * @param ids 需要删除的化学品申购主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteActHxpapplyByIds(Long[] ids)
    {
        //删除原来的化学品申请单
        actHxpapplyDetailMapper.deleteActHxpapplyDetailByApplyId(ids[0]);
        return actHxpapplyMapper.deleteActHxpapplyByIds(ids);
    }

    /**
     * 删除化学品申购信息
     *
     * @param id 化学品申购主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteActHxpapplyById(Long id)
    {
        return actHxpapplyMapper.deleteActHxpapplyById(id);
    }


    /**
     * 获取化学品剩余可存放量
     *
     * @param actRestStockVo 机柜主键主键
     * @return 化学品申购
     */
    @Override
    public Map <String, String> getRestStock(ActRestStockVo actRestStockVo)
    {
        actRestStockVo.setApplyUserId(SecurityUtils.getUserId());
        Predicate<Map <String, String>> pre = x->StringUtils.isNotNull(x);
        Map <String, String> restStock = actHxpapplyMapper.getRestStock(actRestStockVo);
        if(pre.test(restStock)){
            return restStock;
        }else{
            restStock = new HashMap <>();
            restStock.put("chemicalId",actRestStockVo.getChemicalId()+"");
            restStock.put("restStock","0");
            return restStock;
        }
    }


    /**
     * 获取化学品剩余可存放量
     *
     * @param actRestStockVo 机柜主键主键
     * @return 化学品申购
     */
    @Override
    public List<ActRestStockManyVo> getRestStockByManyCabinet(ActRestStockManySearch actRestStockVo)
    {
        List<ActRestStockManyVo> actRestStockManyVoList = new ArrayList <>();
        Optional.ofNullable(actRestStockVo.getCabinetIds()).orElseGet(Collections::emptyList).stream().forEach(a->{
            ActRestStockManyVo manyVo = new ActRestStockManyVo();
            manyVo.setCabinetId(a.longValue());
            manyVo.setRestStock("0");
            actRestStockManyVoList.add(manyVo);
        });
        actRestStockVo.setApplyUserId(SecurityUtils.getUserId());
        List <ActRestStockManyVo> restStockByManyCabinet = actHxpapplyMapper.getRestStockByManyCabinet(actRestStockVo);
        Optional.ofNullable(actRestStockManyVoList).orElseGet(Collections::emptyList)
                .stream()
                .forEach(a->Optional.ofNullable(restStockByManyCabinet).orElseGet(Collections::emptyList).stream()
                .filter(b->b.getCabinetId()==a.getCabinetId()).forEach(c->{
                                    a.setRestStock(c.getRestStock());
                                })
                );

        return actRestStockManyVoList;
    }



    /**
     * 获取化学品剩余可存放量（多个化学品和多个机柜返回的计算）
     *
     * @param actRestStockVo 机柜主键主键
     * @return 化学品申购
     */
    public List<ActRestStockManyVo> getRestStockByManyCabinetAndChemical(ActRestStockManySearch actRestStockVo)
    {
        actRestStockVo.setApplyUserId(SecurityUtils.getUserId());
        List <ActRestStockManyVo> restStockByManyCabinet = actHxpapplyMapper.getRestStockByManyCabinetAndChemical(actRestStockVo);
        return restStockByManyCabinet;
    }
}
