package com.jeeplus.psimanage.collect.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.jeeplus.common.TokenProvider;
import com.jeeplus.core.query.QueryWrapperGenerator;
import com.jeeplus.flowable.feign.IFlowableApi;
import com.jeeplus.psimanage.collect.domain.*;
import com.jeeplus.psimanage.collect.mapper.*;
import com.jeeplus.psimanage.collect.service.dto.*;
import com.jeeplus.psimanage.psiWareHouse.domain.PsiWareHouseDetailed;
import com.jeeplus.psimanage.psiWareHouse.service.PsiWareHouseBasicService;
import com.jeeplus.psimanage.purchase.service.PsiMaterialService;
import com.jeeplus.psimanage.psiWareHouse.mapper.PsiWareHouseBasicMapper;
import com.jeeplus.psimanage.psiWareHouse.mapper.PsiWareHouseDetailedMapper;
import com.jeeplus.psimanage.psiWareHouse.mapper.PsiWareHouseSummaryMapper;
import com.jeeplus.psimanage.psiWareHouse.service.dto.PsiWareHouseDto;
import com.jeeplus.psimanage.oss.service.dto.WorkAttachmentDto;
import com.jeeplus.psimanage.serialNumTpl.service.PsiSerialnumTplService;
import com.jeeplus.sys.feign.IDictApi;
import com.jeeplus.sys.feign.IRoleApi;
import com.jeeplus.sys.feign.IUserApi;
import com.jeeplus.sys.feign.IWorkAttachmentApi;
import com.jeeplus.sys.service.dto.RoleDTO;
import com.jeeplus.sys.service.dto.UserDTO;
import com.jeeplus.utils.StringUtils;
import org.flowable.bpmn.model.FlowNode;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 领用表
 * @author: 王强
 * @create: 2023-01-03 16:24
 **/
@Service
@Transactional
public class PsiCollectService {

    @Resource
    private PsiCollectBasicMapper basicMapper;

    @Resource
    private PsiCollectDetailedMapper psiDetailedMapper;

    @Resource
    private PsiWareHouseSummaryMapper summaryMapper;

    @Resource
    private PsiSerialnumTplService psiSerialnumTplService;

//    @Resource
//    private OssServiceMapper ossServiceMapper;

    @Resource
    private PsiWareHouseDetailedMapper psiWareHouseDetailedMapper;

    @Resource
    private PsiWareHouseBasicMapper psiWareHouseBasicMapper;

    @Resource
    private IFlowableApi flowTaskService;

    @Resource
    private PsiCollectBasicsReturnMapper returnMapper;

    @Resource
    private PsiCollectBasicsReturnHiMapper returnHiMapper;

//    @Resource
//    private OssService ossService;

    @Resource
    private PsiMaterialService psiMaterialService;

    @Resource
    private PsiWareHouseBasicService psiWareHouseBasicService;

    @Resource
    private PsiCollectDetailedRecordMapper psiCollectDetailedRecordMapper;

    public void updateStatusById(PsiCollectDto dto) {
        basicMapper.updateStatusById(dto.getId(), dto.getStatus());
    }

    public String remove(String id) {
        // 删除基础信息表
        basicMapper.deleteById(id);
        // 删除详情列表 及对应附件信息
        List<PsiCollectDetailed> detailedList = psiDetailedMapper.getByBasicId(id);
        if (null != detailedList){
            detailedList.forEach(de->{
                //附件
                List<WorkAttachmentDto> fileList = psiDetailedMapper.getByAttachmentId(de.getId());
                if ( null != fileList ){
                    fileList.forEach(f->{
                        SpringUtil.getBean ( IWorkAttachmentApi.class ).deleteById(f.getId());
//                        ossServiceMapper.deleteById(f.getId());
                    });
                }
                psiDetailedMapper.deleteById(de.getId());
            });
        }
        // 删除附件信息
        SpringUtil.getBean ( IWorkAttachmentApi.class ).deleteByAttachmentId(id);
//        LambdaQueryWrapper<WorkAttachment> wrapper = new LambdaQueryWrapper<>();
//        wrapper.eq(WorkAttachment::getAttachmentId, id);
//        ossServiceMapper.delete(wrapper);
        return "操作成功";
    }

    /**
     * 发起退回流程
     * @param dto
     * @return
     */
    public String saveReturn(PsiCollectDto dto) {

        if (CollectionUtils.isNotEmpty(dto.getDetailInfos()) && StringUtils.isNotBlank(dto.getId())) {
            for (PsiCollectDetailedRecord detailInfo : dto.getRecordList()) {
                if (StringUtils.isNotBlank(detailInfo.getId()) && StringUtils.isNotBlank(detailInfo.getIsReturn())) {
                    psiDetailedMapper.updateReturnFlagById(detailInfo.getDetailId(), detailInfo.getIsReturn()); // 修改退回状态
                    //修改退回状态，退回数量
                    psiDetailedMapper.updateAuditReturnFlagById(detailInfo); // 修改退回状态
                }
            }
            String returnId = createReturnData(dto.getId());
            psiDetailedMapper.updateByIdReturn(returnId, dto.getStatusReturn(), SpringUtil.getBean(IUserApi.class).getByToken(TokenProvider.getCurrentToken ( )).getId(), dto.getReturnCause());
//            ossService.saveOrUpdateFileList(dto.getReturnFiles(), returnId, "collect_return"); // 修改附件信息列表
            Map<String,String> map = new HashMap<>();
            String fileList = JSON.toJSONString((dto.getReturnFiles()));
            String attachmentId = returnId;
            String attachmentFlag = "collect_return";
            map.put("fileList",fileList);
            map.put("attachmentId",attachmentId);
            map.put("attachmentFlag",attachmentFlag);
            map.put("currentToken", TokenProvider.getCurrentToken ( ));
            SpringUtil.getBean ( IWorkAttachmentApi.class ).saveOrUpdateFileList(map); // 修改附件信息列表
            return returnId;
        } else {
            return "";
        }
    }

    /**
     * 退回流程审核同意
     * @param dto
     */
    public String saveReturnAgree(PsiCollectDto dto) throws Exception {
        // 将数据存储到历史表中
        // 将未修改的数据添加到历史数据表中
        PsiCollectDto byId = this.findById(dto.getId());
        String jsonString = JSON.toJSONString(byId);
        if (ObjectUtil.isNotEmpty(byId) && StringUtils.isNotBlank(byId.getReturnId())) {
            // 清空退回原因
            basicMapper.setCauseEmptyById(byId.getReturnId());
        }
        PsiCollectBasicsReturnHi returnHi = new PsiCollectBasicsReturnHi();
        returnHi.setJsonData(jsonString); // json
        returnHi.setCollectId(dto.getId()); // 领用id
        PsiCollectBasicsReturn collectBasicsReturn = returnMapper.selectOne(new LambdaQueryWrapper<PsiCollectBasicsReturn>().eq(PsiCollectBasicsReturn::getBasicId, dto.getId()));
        if (ObjectUtil.isNotEmpty(collectBasicsReturn) && StringUtils.isNotBlank(collectBasicsReturn.getRequestUser())) {
            returnHi.setReturnUser(collectBasicsReturn.getRequestUser()); // 退回申请人
        }
        List<String> returnGoodsName = new ArrayList<>();
        // 将退回的明细数据删除
        if (CollectionUtils.isNotEmpty(dto.getRecordList())) {
            List<PsiWareHouseDetailed> updateList =new ArrayList<>();
            for (PsiCollectDetailedRecord detailInfo : dto.getRecordList()) {
                if (StringUtils.isNotBlank(detailInfo.getId()) && StringUtils.isNotBlank(detailInfo.getIsReturn())) {
                    if("1".equals(detailInfo.getIsReturn()) || "2".equals(detailInfo.getIsReturn())) { // 退回状态
                        if (StringUtils.isNotBlank(detailInfo.getCollectNumber())) {
                            // 如果数量不是空的话，将小数点后的0去除
                            BigDecimal value = new BigDecimal(detailInfo.getCollectNumber());
                            BigDecimal noZeros = value.stripTrailingZeros();
                            String resultNum = noZeros.toPlainString();
                            returnGoodsName.add(detailInfo.getGoodsName() + "*" + resultNum);
                        } else {
                            returnGoodsName.add(detailInfo.getGoodsName());
                        }
                        //获取最新库存数据
                        PsiWareHouseDetailed psiWareHouseDetailed = psiWareHouseDetailedMapper.getCurrentInventoryById(detailInfo.getInventoryId());
                        //最新的库存量
                        String currentInventory = psiWareHouseDetailed.getCurrentInventory();
                        // 规格，例如：一箱几瓶
                        String spec = psiWareHouseDetailed.getSpec();
                        // 退回数量
                        String surplusStock = detailInfo.getSurplusStock();
                        //已退回数量
                        String returnedNum = detailInfo.getReturnedNum();

                        //根据 退回数量 和 规格 换算
                        double current = Double.parseDouble(StringUtils.isEmpty(currentInventory) ? "0" : currentInventory);
                        int specNum = Integer.parseInt(StringUtils.isEmpty(spec) ? "1" : spec);
                        double backNum = Double.parseDouble(StringUtils.isEmpty(surplusStock) ? "0" : surplusStock);
                        //当前的已退回数量
                        double ybackNum = Double.parseDouble(StringUtils.isEmpty(returnedNum) ? "0" : returnedNum);
                        // 退回瓶数 转成箱数 + 当前库存
                        // 最新库存 = 当前箱数 + (退回瓶数 / 每箱瓶数)
                        double newInventory = current + (backNum / specNum);
                        // 3. 设置回最新库存
                        psiWareHouseDetailed.setCurrentInventory(String.valueOf(newInventory));
                        //修改退回数量和为未退回数量
                        PsiCollectDetailedRecord psiCollectDetailedRecord = new PsiCollectDetailedRecord();
                        psiCollectDetailedRecord.setId(detailInfo.getId());
                        //领用数量
                        double collectNumber = Double.parseDouble(detailInfo.getCollectNumber());
                        //最新已退数量
                        double currentReturnedNum = backNum + ybackNum;
                        //未退回数量  计算  领用数量-退回数量 = 未退回数量
                        double notSurplusStock =  collectNumber - currentReturnedNum;
                        psiCollectDetailedRecord.setNotSurplusStock(String.valueOf(notSurplusStock));
                        psiCollectDetailedRecord.setSurplusStock("0");
                        //已退回数量
                        psiCollectDetailedRecord.setReturnedNum(String.valueOf(currentReturnedNum));
                        psiCollectDetailedRecordMapper.updateById(psiCollectDetailedRecord);
                        //如果全部退回，删除对应领用数据
                        if((backNum + ybackNum) == collectNumber){
                            psiDetailedMapper.delete(new LambdaQueryWrapper<PsiCollectDetailed>().eq(PsiCollectDetailed::getId,detailInfo.getDetailId()));
                        }

                        updateList.add(psiWareHouseDetailed);
                    }
                }
            }
            if(CollectionUtil.isNotEmpty(updateList)){
                psiWareHouseDetailedMapper.updateBatchById(updateList);
            }
        }
        String returnGoods = String.join(",", returnGoodsName);
        if (StringUtils.isNotBlank(returnGoods)) {
            returnHi.setReturnGoods(returnGoods); // 退回的数据（字符串展示）
        }
        returnHiMapper.insert(returnHi); // 将数据存储到历史表中
        // 修改退回流程的状态
        psiDetailedMapper.updateStatusByIdReturn(collectBasicsReturn.getId(), dto.getStatusReturn());
        // 删除退回关联附件
        if(StringUtils.isNotBlank(dto.getStatusReturn()) && dto.getStatusReturn().equals("5")){
            UserDTO userDTO = SpringUtil.getBean(IUserApi.class).getByToken(TokenProvider.getCurrentToken ( ));
            // 通过审批，抄送至仓库管理员
            Map<String, String> keyMap = new HashMap<>();
            keyMap.put("name", "仓库管理员");
            keyMap.put("tenantId", "10009");
            List<RoleDTO> roleDTO = SpringUtil.getBean(IRoleApi.class).getRoleDTOByNameAndTenantId(keyMap);
            RoleDTO role = roleDTO.get(0);
            List<UserDTO> notifiedPartyUsers =SpringUtil.getBean(IUserApi.class).findListByRoleId(role.getId());
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
            String day = format.format(new Date());
            String title = "[领用编号："+dto.getCollectNo()+"]-领用退回申请审批通过";
            //向用户发起通知
            if (null != notifiedPartyUsers) {
                for (UserDTO userDTO1 : notifiedPartyUsers) {
                    //发送通知
                    Map<String ,String > map = new HashMap<>();
                    map.put("taskId",dto.getProcInsIdReturn());
                    map.put("title",title);
                    map.put("defId",dto.getProcessDefinitionIdReturn());
                    map.put("taskName","领用退回申请审批通过");
                    map.put("createUser","管理员");
                    map.put("createTime",day);
                    map.put("noticeName",userDTO1.getLoginName());
                    map.put("noticeId",userDTO1.getId());
                    map.put("createById",userDTO.getId());
                    flowTaskService.add(map);
                }
            }
        }
//        ossService.remove(new LambdaQueryWrapper<WorkAttachment>().eq(WorkAttachment::getAttachmentId, collectBasicsReturn.getId()));
        SpringUtil.getBean ( IWorkAttachmentApi.class ).deleteByAttachmentId(collectBasicsReturn.getId());
        if (ObjectUtil.isNotEmpty(collectBasicsReturn)) {
            return collectBasicsReturn.getId();
        } else {
            return "";
        }
    }

    public void updateStatusByIdReturn(String id, String status) {
        PsiCollectBasicsReturn returnData = returnMapper.selectOne(new LambdaQueryWrapper<PsiCollectBasicsReturn>().eq(PsiCollectBasicsReturn::getBasicId, id));
        if (ObjectUtil.isNotEmpty(returnData) && StringUtils.isNotBlank(returnData.getId())) {
            psiDetailedMapper.updateStatusByIdReturn(returnData.getId(), status); // 修改退回的流程状态
        }
    }

    public String save(PsiCollectDto dto) throws Exception{
        // 获取当前登录人信息
        UserDTO userDTO = SpringUtil.getBean(IUserApi.class).getByToken(TokenProvider.getCurrentToken ( ));
//        UserDTO userDTO = UserUtils.getCurrentUserDTO();
        synchronized (this) {
            if (StringUtils.isNotEmpty(dto.getId()) && !dto.getId().equals("false")) {
                return update(dto, userDTO);
            } else {
                return add(dto, userDTO);
            }
        }

    }

    public String update(PsiCollectDto dto, UserDTO userDTO) throws Exception {
        // 修改基础信息
        PsiCollectBasic info = new PsiCollectBasic();
        BeanUtils.copyProperties(dto, info);
        info.setUpdateById(userDTO.getId());
        info.setHandledBy(dto.getHandledById());
        info.setUpdateTime(new Date());
        if(StringUtils.isNotBlank(info.getProcInsId()) && StringUtils.isBlank(info.getProcessDefinitionId())){
            Map flowMap = flowTaskService.getByNameForFen("进销存-领用申请");
            Object idObj = flowMap.get("id");
            if (idObj != null && idObj instanceof String) {
                info.setProcessDefinitionId((String)idObj) ;
            }
        }
        basicMapper.updateById(info);
        // 修改报销详情列表信息
        // 删除原有数据
//        LambdaQueryWrapper<MaterialDetailed> detailWrapper = new LambdaQueryWrapper<>();
//        detailWrapper.eq(MaterialDetailed::getBasicId, dto.getId());
//        psiDetailedMapper.delete(detailWrapper);
        if (CollectionUtils.isNotEmpty(dto.getDetailInfos())) {

            List<String> idList = psiDetailedMapper.getIdByBasicId(info.getId());
            for (PsiCollectDetailed detailInfo : dto.getDetailInfos()) {
                //删除多余的领用详情
                //根据基础表id获取所有的详情表id
                if (null != idList) {
                    if (idList.contains(detailInfo.getId())){
                        idList.remove(detailInfo.getId());
                    }
                }
            }
            if (null != idList & idList.size()>0) {
                idList.forEach(id->{
                    psiDetailedMapper.deleteById(id);
                });
            }

            if (StringUtils.isNotEmpty(dto.getSign())) {

            } else {
                if(StringUtils.isNotBlank(dto.getStatus()) && !dto.getStatus().equals("5")){
                    if(CollectionUtil.isEmpty( dto.getRecordList())) {
                        QueryWrapper<PsiCollectDetailedRecord> queryWrapper = new QueryWrapper<>();
                        queryWrapper.eq("basic_id", dto.getId());
                        psiCollectDetailedRecordMapper.delete(queryWrapper);
                    }
                }
                List<String> warnInfoList = new ArrayList<>();

                for (PsiCollectDetailed detailInfo : dto.getDetailInfos()) {

                    PsiCollectDetailed materialDetailed = psiDetailedMapper.selectById(detailInfo.getId());
                    if (StringUtils.isEmpty(detailInfo.getCollectNumber())){
                        detailInfo.setCollectNumber("0");
                    }
                    if ( null == materialDetailed) {
                        // 生成id
                        String detailId = UUID.randomUUID().toString().replace("-", "");
                        detailInfo.setId(detailId);
                        detailInfo.setRecipientAgent(detailInfo.getRecipientAgentId());
                        detailInfo.setCollectType(detailInfo.getCollectTypeId());
                        detailInfo.setCreateById(userDTO.getId());
                        detailInfo.setCreateTime(new Date());
                        detailInfo.setUpdateById(userDTO.getId());
                        detailInfo.setUpdateTime(new Date());
                        detailInfo.setDelFlag(0);
                        // 保存基础表信息主键值
                        detailInfo.setBasicId(dto.getId());
                        //获取该商品对应的库存数据
                        PsiWareHouseDto wareHouseDto = psiWareHouseBasicMapper.getByTypeAndGoodsName(detailInfo.getGoodsName(), detailInfo.getCollectTypeId());
                        detailInfo.setSurplusNumber(wareHouseDto.getTradeNumber());
                        psiDetailedMapper.insert(detailInfo);
                        // 修改附件信息列表
                        if (CollectionUtils.isNotEmpty(detailInfo.getFileInfoLost())) {
                            psiMaterialService.saveFiles(detailInfo.getFileInfoLost(), userDTO, detailInfo.getId());
                        }
                    } else {
                        //获取该商品对应的库存数据
                        PsiWareHouseDto wareHouseDto = psiWareHouseBasicMapper.getByTypeAndGoodsName(detailInfo.getGoodsName(), detailInfo.getCollectTypeId());
                        detailInfo.setSurplusNumber(wareHouseDto.getTradeNumber());
                        detailInfo.setRecipientAgent(detailInfo.getRecipientAgentId());
                        detailInfo.setCollectType(detailInfo.getCollectTypeId());
                        detailInfo.setUpdateById(userDTO.getId());
                        detailInfo.setUpdateTime(new Date());
                        detailInfo.setBasicId(dto.getId());
                        psiDetailedMapper.updateById(detailInfo);
                        psiMaterialService.updateFiles(detailInfo.getFileInfoLost(), userDTO, detailInfo.getId());
//                        if (CollectionUtils.isNotEmpty(detailInfo.getFileInfoLost())) {
//                            psiMaterialService.updateFiles(detailInfo.getFileInfoLost(), userDTO, detailInfo.getId());
//                        }
                    }




                    //当流程结束的时候 修改入库汇总表的数量
                    if ( StringUtils.isNotEmpty(info.getStatus()) && info.getStatus().equals("5")){
                        List<PsiCollectDetailedRecord> recordList = dto.getRecordList();
                        List<PsiWareHouseDetailed> infoByProduceDateDesc = new ArrayList<>();
                        for (PsiCollectDetailedRecord psiCollectDetailedRecord : recordList) {
                            //如果领用详情的分类和物品名  跟  领用分配的相同
                            if(detailInfo.getCollectTypeId().equals(psiCollectDetailedRecord.getCollectTypeId()) && detailInfo.getGoodsName().equals(psiCollectDetailedRecord.getGoodsName())){
                                String recordId = UUID.randomUUID().toString().replace("-", "");
                                psiCollectDetailedRecord.setSurplusStock("0");//退回数量
                                psiCollectDetailedRecord.setReturnedNum("0");//已退回数量
                                psiCollectDetailedRecord.setBasicId(info.getId());//id
                                psiCollectDetailedRecord.setRecipientAgent(psiCollectDetailedRecord.getRecipientAgentId());
                                psiCollectDetailedRecord.setCollectType(psiCollectDetailedRecord.getCollectTypeId());//id
                                psiCollectDetailedRecord.setNotSurplusStock(psiCollectDetailedRecord.getCollectNumber());//未退回数量
                                if(StringUtils.isBlank(psiCollectDetailedRecord.getId())){
                                    psiCollectDetailedRecord.setId(recordId);
                                    psiCollectDetailedRecordMapper.insert(psiCollectDetailedRecord);
                                }else{
                                    psiCollectDetailedRecordMapper.updateById(psiCollectDetailedRecord);
                                }
                                PsiWareHouseDetailed psiWareHouseDetailed1 = new PsiWareHouseDetailed();
                                psiWareHouseDetailed1.setCurrentInventory(psiCollectDetailedRecord.getSurplusNumber());
                                psiWareHouseDetailed1.setSpec(psiCollectDetailedRecord.getSpec());
                                psiWareHouseDetailed1.setId(psiCollectDetailedRecord.getInventoryId());
                                psiWareHouseDetailed1.setTradeName(psiCollectDetailedRecord.getGoodsName());
                                psiWareHouseDetailed1.setWarnFlag(psiCollectDetailedRecord.getWarnFlag());
                                psiWareHouseDetailed1.setWarnNum(psiCollectDetailedRecord.getWarnNum());
                                psiWareHouseDetailed1.setCollectNumber(psiCollectDetailedRecord.getCollectNumber());
                                infoByProduceDateDesc.add(psiWareHouseDetailed1);
                            }

                        }
                        if(CollectionUtil.isNotEmpty(infoByProduceDateDesc)){
                            List<PsiWareHouseDetailed> updateList = updateCurrentInventory(detailInfo,infoByProduceDateDesc);
                            // 批量更新数据库
                            if (CollUtil.isNotEmpty(updateList)) {
                                psiWareHouseDetailedMapper.updateBatchById(updateList);
                                //判断是否需要通知
                                for (PsiWareHouseDetailed psiWareHouseDetailed : updateList) {
                                    if(psiWareHouseDetailed.getWarnFlag().equals("1")){
                                        double warnNum = Double.parseDouble(psiWareHouseDetailed.getWarnNum());
                                        double current = Double.parseDouble(psiWareHouseDetailed.getCurrentInventory());
                                        if(current <= warnNum){
                                            warnInfoList.add(psiWareHouseDetailed.getTradeName());
                                        }
                                    }
                                }

                            }
                        }
                    }
                    if(StringUtils.isNotEmpty(info.getStatus()) && !info.getStatus().equals("5")){
                        if(CollectionUtil.isEmpty( dto.getRecordList())){
                            List<PsiWareHouseDetailed> recordList = batchCalculation(detailInfo,"2");
                            for (PsiWareHouseDetailed psiWareHouseDetailed : recordList) {
                                String recordId = UUID.randomUUID().toString().replace("-", "");
                                PsiCollectDetailedRecord psiCollectDetailedRecord = new PsiCollectDetailedRecord();
                                BeanUtils.copyProperties(detailInfo, psiCollectDetailedRecord);
                                psiCollectDetailedRecord.setCollectNumber(psiWareHouseDetailed.getCurrentInventory());
                                psiCollectDetailedRecord.setDetailId(detailInfo.getId());
                                psiCollectDetailedRecord.setId(recordId);
                                psiCollectDetailedRecord.setInventoryId(psiWareHouseDetailed.getId());
                                psiCollectDetailedRecord.setSurplusStock("0");//退回数量
                                psiCollectDetailedRecord.setReturnedNum("0");//已退回数量
                                psiCollectDetailedRecord.setNotSurplusStock(psiWareHouseDetailed.getCurrentInventory());//未退回数量
                                psiCollectDetailedRecordMapper.insert(psiCollectDetailedRecord);
                            }
                        }
                    }

                }


                if(StringUtils.isNotBlank(dto.getStatus()) && dto.getStatus().equals("5")){
                    //审核通过抄送仓库管理员
                        Map<String, String> keyMap = new HashMap<>();
                        keyMap.put("name", "仓库管理员");
                        keyMap.put("tenantId", "10009");
                        List<RoleDTO> roleDTO = SpringUtil.getBean(IRoleApi.class).getRoleDTOByNameAndTenantId(keyMap);
                        RoleDTO role = roleDTO.get(0);
                        List<UserDTO> notifiedPartyUsers =SpringUtil.getBean(IUserApi.class).findListByRoleId(role.getId());
                        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
                        String day = format.format(new Date());
                        String title = "[领用编号："+dto.getCollectNo()+"]-领用申请审批通过";
                        UserDTO initiator = SpringUtil.getBean(IUserApi.class).getById(dto.getHandledById());
                        notifiedPartyUsers.add(initiator);
                        //向用户发起通知
                        if (null != notifiedPartyUsers) {
                            for (UserDTO userDTO1 : notifiedPartyUsers) {
                                //发送通知
                                Map<String ,String > map = new HashMap<>();
                                map.put("taskId",dto.getProcInsId());
                                map.put("title",title);
                                map.put("defId",info.getProcessDefinitionId());
                                map.put("taskName","领用申请审批通过");
                                map.put("createUser","管理员");
                                map.put("createTime",day);
                                map.put("noticeName",userDTO1.getLoginName());
                                map.put("noticeId",userDTO1.getId());
                                map.put("createById",userDTO.getId());
                                flowTaskService.add(map);
                        }
                    }
                }
                //发起提醒操作
                if (CollectionUtil.isNotEmpty(warnInfoList)) {
                    String warnInfo = String.join("、", warnInfoList);
                    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
                    String day = format.format(new Date());
                    String title = "管理员发起了 ["+ warnInfo +"] [物资库存提醒]";
                    //向多个用户发起通知
                    List<UserDTO> usersInfo = psiWareHouseDetailedMapper.getUsersInfo();
                    //获取目前领用流程的taskid，根据procInsId去查taskId
                    String uuid = "";
                    if (null != usersInfo) {
                        for (UserDTO userDTO1 : usersInfo) {
                            uuid = UUID.randomUUID().toString();
                            //发送通知
//                                        flowTaskService.add(uuid, title, "", "库存提醒", userDTO.getLoginName(), day,userDTO1.getLoginName(), userDTO1.getId());
                            Map<String ,String > map = new HashMap<>();
                            map.put("taskId",uuid);
                            map.put("title",title);
                            map.put("defId",dto.getId());
                            map.put("taskName","物资库存提醒");
                            map.put("createUser","管理员");
                            map.put("createTime",day);
                            map.put("noticeName",userDTO1.getLoginName());
                            map.put("noticeId",userDTO1.getId());
                            map.put("createById",userDTO.getId());
                            flowTaskService.add(map);
                        }
                    }
                }
            }

        }
//        basicMapper.updateById(info);
        // 修改附件信息列表
        psiMaterialService.updateFiles(dto.getFiles(), userDTO, dto.getId());
//        if (CollectionUtils.isNotEmpty(dto.getFiles())) {
//            psiMaterialService.updateFiles(dto.getFiles(), userDTO, dto.getId());
//        }
        return dto.getId();
    }

    /**
     * 用户提交领用，根据生产日期和库存数进行分配计算
     * @param detailInfo
     * @param returnType 返回值类型，(1:返回计算完成的库存剩余，2：返回计算完成的分配数量)
     * @return
     */
    public List<PsiWareHouseDetailed> batchCalculation(PsiCollectDetailed detailInfo,String returnType){
        List<PsiWareHouseDetailed> infoByProduceDateDesc = summaryMapper.getInfoByProduceDateDesc(detailInfo.getGoodsName(), detailInfo.getCollectType());
        List<PsiWareHouseDetailed> updateList = new ArrayList<>();
        double collectNumber = Double.parseDouble(detailInfo.getCollectNumber());
        for (PsiWareHouseDetailed psiWareHouseDetailed : infoByProduceDateDesc) {
            if (collectNumber <= 0.001) { // 待扣数 ≤0 就结束
                break;
            }
            double currentNum = Double.parseDouble(psiWareHouseDetailed.getCurrentInventory());
            // 规格：例如  1箱 = 4瓶
            double spec = Double.parseDouble(psiWareHouseDetailed.getSpec());

            // ==============================
            // 当前批次 总数 = 入库数量 × spec
            // ==============================
            double totalBottle = Math.round(currentNum * spec * 100.0) / 100.0;

            if (totalBottle <= 0.001) {
                continue;
            }

            // 要扣的瓶数
            double needBottle = collectNumber;

            // 构建更新对象
            PsiWareHouseDetailed newDto = new PsiWareHouseDetailed();
            newDto.setId(psiWareHouseDetailed.getId());

            if (totalBottle >= needBottle) {
                // ============================
                // 够扣：当前批次瓶数足够
                // ============================
                double remainBottle = totalBottle - needBottle;       // 剩余瓶数
                double remainBox = remainBottle / spec;             // 剩余箱数
                remainBox = Math.round(remainBox * 100.0) / 100.0;   // 保留2位
                if(returnType.equals("1")){
                    newDto.setCurrentInventory(String.valueOf(remainBox)); // 库存
                }else{
                    newDto.setCurrentInventory(String.valueOf(needBottle)); // 使用量
                }
                collectNumber = 0;
            } else {
                // ============================
                // 不够扣：把当前批次扣光
                // ============================
                if(returnType.equals("1")){
                    // 库存
                    newDto.setCurrentInventory("0.00"); // 清零
                }else{
                    // 使用量
                    newDto.setCurrentInventory(String.valueOf(totalBottle));
                }
                collectNumber = Math.round((collectNumber - totalBottle) * 100.0) / 100.0;

            }
            newDto.setWarnNum(psiWareHouseDetailed.getWarnNum());
            newDto.setTradeName(psiWareHouseDetailed.getTradeName());
            newDto.setWarnFlag(psiWareHouseDetailed.getWarnFlag());
            updateList.add(newDto);
        }
        return updateList;
    }

    /**
     * 审批同意领用，根据用户提交数据进行更新计算
     * @return
     */
    public List<PsiWareHouseDetailed> updateCurrentInventory(PsiCollectDetailed detailInfo,List<PsiWareHouseDetailed> infoByProduceDateDesc){
        List<PsiWareHouseDetailed> updateList = new ArrayList<>();
        double collectNumber = Double.parseDouble(detailInfo.getCollectNumber());
        for (PsiWareHouseDetailed psiWareHouseDetailed : infoByProduceDateDesc) {
            //本批次扣除数量
            double MAX_ONCE_LIMIT_BOTTLE  = Double.parseDouble(psiWareHouseDetailed.getCollectNumber());
            if (collectNumber <= 0.001) { // 待扣数 ≤0 就结束
                break;
            }
            double currentNum = Double.parseDouble(psiWareHouseDetailed.getCurrentInventory());
            // 规格：例如  1箱 = 4瓶
            double spec = Double.parseDouble(psiWareHouseDetailed.getSpec());

            // ==============================
            // 当前批次 总数 = 入库数量 × spec
            // ==============================
            double totalBottle = Math.round(currentNum * spec * 100.0) / 100.0;

            if (totalBottle <= 0.001) {
                continue;
            }

            // 要扣的瓶数
            double needBottle = collectNumber;

            // 构建更新对象
            PsiWareHouseDetailed newDto = new PsiWareHouseDetailed();
            newDto.setId(psiWareHouseDetailed.getId());

            if (totalBottle >= MAX_ONCE_LIMIT_BOTTLE) {
                // ============================
                // 够扣：当前批次瓶数足够
                // ============================
                double remainBottle = totalBottle - MAX_ONCE_LIMIT_BOTTLE;       // 库存剩余瓶数
                double remainUndeductedBottle = needBottle - MAX_ONCE_LIMIT_BOTTLE;       // 剩余未扣瓶数
                double remainBox = remainBottle / spec;             // 剩余箱数
                //remainBox = Math.round(remainBox * 100.0) / 100.0;   // 保留2位
                newDto.setCurrentInventory(String.format("%.4f", remainBox)); // 库存
                collectNumber = remainUndeductedBottle;
            }
            //else {
            //    // ============================
            //    // 不够扣：把当前批次扣光
            //    // ============================
            //    // 库存
            //    newDto.setCurrentInventory("0.00"); // 清零
            //    collectNumber = Math.round((collectNumber - totalBottle) * 100.0) / 100.0;
            //
            //}
            newDto.setWarnNum(psiWareHouseDetailed.getWarnNum());
            newDto.setTradeName(psiWareHouseDetailed.getTradeName());
            newDto.setWarnFlag(psiWareHouseDetailed.getWarnFlag());
            updateList.add(newDto);
        }
        return updateList;
    }

    public String add(PsiCollectDto dto, UserDTO userDTO) throws Exception{
        // 生成id
        String id = UUID.randomUUID().toString().replace("-", "");
        // 生成编号
        String no = psiSerialnumTplService.genSerialNum(userDTO.getCompanyDTO().getId(), dto.BIZ_CODE,TokenProvider.getCurrentToken());
        // 保存基础信息表信息
        PsiCollectBasic info = new PsiCollectBasic();
        BeanUtils.copyProperties(dto, info);
        info.setId(id);
        info.setCollectNo(no);
        info.setHandledBy(dto.getHandledById());
        info.setCreateById(userDTO.getId());
        info.setCreateTime(new Date());
        info.setUpdateById(userDTO.getId());
        info.setUpdateTime(new Date());
        info.setDelFlag(0);
        basicMapper.insert(info);
        // 保存详情列表信息
        if (CollectionUtils.isNotEmpty(dto.getDetailInfos())) {
            for (PsiCollectDetailed detailed : dto.getDetailInfos()) {
                // 生成id
                String detailId = UUID.randomUUID().toString().replace("-", "");
                detailed.setId(detailId);
                detailed.setRecipientAgent(detailed.getRecipientAgentId());
                detailed.setCollectType(detailed.getCollectTypeId());
                detailed.setCreateById(userDTO.getId());
                detailed.setCreateTime(new Date());
                detailed.setUpdateById(userDTO.getId());
                detailed.setUpdateTime(new Date());
                detailed.setDelFlag(0);
                // 保存基础表信息主键值
                detailed.setBasicId(id);
                //获取该类商品根据生产日期排序的库存数据
                PsiWareHouseDto wareHouseDto = psiWareHouseBasicMapper.getByTypeAndGoodsName(detailed.getGoodsName(), detailed.getCollectTypeId());
                detailed.setSurplusNumber(wareHouseDto.getTradeNumber());
                //设置当前库存
                detailed.setCurrentInventory(wareHouseDto.getTradeNumber());
                psiDetailedMapper.insert(detailed);
                //保存详情列表附件信息
                if (CollectionUtils.isNotEmpty(detailed.getFileInfoLost())){
                    psiMaterialService.saveFiles(detailed.getFileInfoLost(), userDTO, detailId);
                }

                List<PsiWareHouseDetailed> recordList = batchCalculation(detailed,"2");
                for (PsiWareHouseDetailed psiWareHouseDetailed : recordList) {
                    String recordId = UUID.randomUUID().toString().replace("-", "");
                    PsiCollectDetailedRecord psiCollectDetailedRecord = new PsiCollectDetailedRecord();
                    BeanUtils.copyProperties(detailed, psiCollectDetailedRecord);
                    psiCollectDetailedRecord.setCollectNumber(psiWareHouseDetailed.getCurrentInventory());
                    psiCollectDetailedRecord.setDetailId(detailId);
                    psiCollectDetailedRecord.setId(recordId);
                    psiCollectDetailedRecord.setInventoryId(psiWareHouseDetailed.getId());
                    psiCollectDetailedRecord.setSurplusStock("0");//退回数量
                    psiCollectDetailedRecord.setReturnedNum("0");//已退回数量
                    psiCollectDetailedRecord.setNotSurplusStock(psiWareHouseDetailed.getCurrentInventory());//未退回数量
                    psiCollectDetailedRecordMapper.insert(psiCollectDetailedRecord);
                }


            }
        }
        // 保存附件列表信息
        if (CollectionUtils.isNotEmpty(dto.getFiles())) {
            psiMaterialService.saveFiles(dto.getFiles(), userDTO, id);
        }
        return id;
    }

    public PsiCollectDto findById(String id) throws Exception {
        PsiCollectDto dto = new PsiCollectDto();
        // 查询基础信息表
        PsiCollectBasic info = basicMapper.selectById(id);
        if (ObjectUtils.isNotEmpty(info)) {
            BeanUtils.copyProperties(info, dto);
            //将采购详情数据查出
            List<PsiCollectDetailed> detailedList = psiDetailedMapper.getByBasicId(id);
            if (CollectionUtils.isNotEmpty(detailedList)){
                detailedList.forEach(detailed->{
                    //附件信息
                    List<WorkAttachmentDto> acList = psiDetailedMapper.getByAttachmentId(detailed.getId());
                    if (CollectionUtils.isNotEmpty(acList)) {
                        for (WorkAttachmentDto i : acList) {
                            i.setCreateBy(SpringUtil.getBean ( IUserApi.class ).getById(i.getBy()));
//                            i.setCreateBy(UserUtils.get(i.getBy()));
                        }
                    }
                    detailed.setFileInfoLost(acList);
                });
            }
            dto.setDetailInfos(detailedList);
            // 领用 附件信息
            List<WorkAttachmentDto> files = psiDetailedMapper.getByAttachmentId(info.getId());
            if (CollectionUtils.isNotEmpty(files)) {
                for (WorkAttachmentDto i : files) {
                    i.setCreateBy(SpringUtil.getBean ( IUserApi.class ).getById(i.getBy()));
                }
            }
            //根据经办人id查出经办人的名称
            String name = basicMapper.getUserNameByUserId(info.getHandledBy());
            //根据经办人部门id查询经办人部门名称
            String officeName = basicMapper.getOfficeNameByOfficeId(info.getHandledByOffice());
            dto.setHandledByOfficeName(officeName);
            dto.setHandledBy(name);
            dto.setHandledById(info.getHandledBy());
            dto.setFiles(files);
        }
        // 领用-退回流程信息
        PsiCollectBasicsReturn collectBasicsReturn = basicMapper.selectReturnByBasicId(id);
        if (ObjectUtil.isNotEmpty(collectBasicsReturn)) {
            if (StringUtils.isNotBlank(collectBasicsReturn.getProcessDefinitionId())){
                dto.setProcessDefinitionIdReturn(collectBasicsReturn.getProcessDefinitionId());
            }
            if (StringUtils.isNotBlank(collectBasicsReturn.getProcInsId())){
                dto.setProcInsIdReturn(collectBasicsReturn.getProcInsId());
            }
            if (StringUtils.isNotBlank(collectBasicsReturn.getStatus())){
                dto.setStatusReturn(collectBasicsReturn.getStatus());
            }
            if (StringUtils.isNotBlank(collectBasicsReturn.getId())){
                dto.setReturnId(collectBasicsReturn.getId());
                // 领用-退回 附件信息
                List<WorkAttachmentDto> returnFiles = psiDetailedMapper.getByAttachmentId(collectBasicsReturn.getId());
                if (CollectionUtils.isNotEmpty(returnFiles)) {
                    for (WorkAttachmentDto i : returnFiles) {
                        i.setCreateBy(SpringUtil.getBean ( IUserApi.class ).getById(i.getBy()));
                    }
                }
                dto.setReturnFiles(returnFiles);
            }
            if (StringUtils.isNotBlank(collectBasicsReturn.getRemarks())){
                dto.setReturnCause(collectBasicsReturn.getRemarks());
            }
        }

        //查询审核员页面展示的数据
        LambdaQueryWrapper<PsiCollectDetailedRecord> wrapper = new LambdaQueryWrapper<>();
        if(ObjectUtils.isNotEmpty(info)){
            String isReturn = "0";
            if(ObjectUtil.isNotEmpty(collectBasicsReturn)){
                if(collectBasicsReturn.getStatus().equals("2")){
                    isReturn = "1";
                }
            }
            List<PsiCollectDetailedRecord> psiCollectDetailedRecords =  psiDetailedMapper.getRecordsByBasicId(info.getId(),isReturn);
            if(CollectionUtil.isNotEmpty(psiCollectDetailedRecords)){
                for (PsiCollectDetailedRecord psiCollectDetailedRecord : psiCollectDetailedRecords) {
                    dto.setHandledById(info.getHandledBy());
                    Page<PsiWareHouseDto> page = new Page<>();
                    page.setSize(999);
                    page.setCurrent(1);
                    PsiWareHouseDto psiWareHouseDto = new PsiWareHouseDto();
                    psiWareHouseDto.setTradeName(psiCollectDetailedRecord.getGoodsName());
                    psiWareHouseDto.setWareHouseType(psiCollectDetailedRecord.getCollectTypeId());
                    IPage<PsiWareHouseDto> byProduceDateNotMerge = psiWareHouseBasicService.getByProduceDateNotMerge(page, psiWareHouseDto);
                    if(CollectionUtil.isNotEmpty(byProduceDateNotMerge.getRecords())){
                        psiCollectDetailedRecord.setPsiWareHouseDtoList(byProduceDateNotMerge.getRecords());
                    }
                }
                dto.setRecordList(psiCollectDetailedRecords);
            }
        }




        return dto;
    }

    /**
     * 列表查询
     */
    public IPage<PsiCollectDto> list(Page<PsiCollectDto> page , PsiCollectDto dto) throws Exception{
        QueryWrapper<PsiCollectDto> queryWrapper = QueryWrapperGenerator.buildQueryCondition(dto, PsiCollectDto.class);

        queryWrapper.eq("a.del_flag", "0");
        if (StringUtils.isNotEmpty(dto.getCollectNo())) {
            queryWrapper.like("a.collect_no", dto.getCollectNo());
        }
        if (StringUtils.isNotEmpty(dto.getGoodsName())) {
            queryWrapper.like("b.goods_name", dto.getGoodsName());
        }
        if (StringUtils.isNotEmpty(dto.getHandledBy())) {
            queryWrapper.eq("su.id", dto.getHandledBy());
        }
        if (StringUtils.isNotEmpty(dto.getHandledByOffice())) {
            //先根据id查出是否是父节点，是父节点则查出所有的子节点信息
            List<String> childIds = basicMapper.findChildIds(dto.getHandledByOffice());
            if ( null != childIds & childIds.size()>0){
                childIds.add(dto.getHandledByOffice());
                queryWrapper.in("a.handled_by_office",childIds);
            }else {
                queryWrapper.eq("a.handled_by_office", dto.getHandledByOffice());
            }
        }
        String[] contractDates = dto.getCollectDates();
        if (contractDates != null) {

            queryWrapper.between("a.collect_date", contractDates[0], contractDates[1]);
        }
        if (StringUtils.isNotBlank(dto.getStatusReturn())) {
            if(dto.getStatusReturn().equals("0")){
                queryWrapper.and(w -> w.eq("returna.status", "0")
                        .or()
                        .isNull("returna.status")
                        .or()
                        .eq("returna.status", ""));            }else{
                queryWrapper.eq("returna.status", dto.getStatusReturn());
            }
        }
        IPage<PsiCollectDto> list = basicMapper.findList(page, queryWrapper);
        list.getRecords().stream().forEach(item -> {
            // 领用申请
            if (StringUtils.isNotBlank(item.getTaskId()) && StringUtils.isNotBlank(item.getStatus())) {
                if ("2".equals(item.getStatus())) { // “审核中”的数据要获取数据审核人
                    item.setAuditUserIds(flowTaskService.getTaskAuditUsers(item.getTaskId()));  // 获取数据审核人
                }
            }
            // 领用-退回申请
            if (StringUtils.isNotBlank(item.getTaskIdReturn()) && StringUtils.isNotBlank(item.getStatusReturn())) {
                if ("2".equals(item.getStatusReturn())) { // “审核中”的数据要获取数据审核人
                    item.setAuditUserIdsReturn(flowTaskService.getTaskAuditUsers(item.getTaskIdReturn()));  // 获取数据审核人
                }
            }
        });
        return list;
    }

    /**
     * 列表查询
     */
    public List<PsiCollectExportDto> exportList(Page<PsiCollectDto> page , PsiCollectDto dto) throws Exception{
        List<PsiCollectDto> records = this.list(page, dto).getRecords();
        List<PsiCollectExportDto> result = new ArrayList<>();
        if (CollectionUtils.isEmpty(records)) {
            return result;
        }
        records.forEach(item -> {
            PsiCollectExportDto exportDto = new PsiCollectExportDto();
            exportDto.setId(item.getId());
            exportDto.setCollectNo(item.getCollectNo());
            exportDto.setGoodsName(StringUtils.isBlank(item.getDetailId()) ? "领用物品已全部退回" : item.getGoodsName());
            exportDto.setHandledByName(item.getHandledByName());
            exportDto.setHandledByOfficeName(item.getHandledByOfficeName());
            exportDto.setCollectDate(item.getCollectDate() == null ? "" : new SimpleDateFormat("yyyy-MM-dd").format(item.getCollectDate()));
            exportDto.setStatus(StringUtils.isBlank(item.getStatus()) ? "" : SpringUtil.getBean(IDictApi.class).getDictLabel(item.getStatus(), "cw_status", ""));
            if (StringUtils.isBlank(item.getStatusReturn())) {
                exportDto.setStatusReturn("未发起");
            } else {
                exportDto.setStatusReturn(SpringUtil.getBean(IDictApi.class).getDictLabel(item.getStatusReturn(), "cw_status", ""));
            }
            result.add(exportDto);
        });
        return result;
    }

    public List<PsiCollectExportDto> exportRecordList(Page<PsiCollectDto> page , PsiCollectDto dto) throws Exception{
        List<PsiCollectDto> basicList = this.list(page, dto).getRecords();
        List<PsiCollectExportDto> result = new ArrayList<>();
        if (CollectionUtils.isEmpty(basicList)) {
            return result;
        }
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        List<PsiCollectDto> resultList = basicList.stream()
                .collect(Collectors.toMap(
                        PsiCollectDto::getId,
                        v -> v,
                        (oldVal, newVal) -> oldVal
                ))
                .values()
                .stream()
                .map(item -> {
                    PsiCollectDto newDto = new PsiCollectDto();
                    newDto.setId(item.getId());
                    newDto.setCollectNo(item.getCollectNo());
                    newDto.setCollectDate(item.getCollectDate());
                    return newDto;
                })
                .collect(Collectors.toList());
        resultList.forEach(item -> {
            List<PsiCollectDetailedRecord> recordList = psiDetailedMapper.getRecordsByBasicId(item.getId(), "0");
            if (CollectionUtils.isEmpty(recordList)) {
                return;
            }
            recordList.forEach(record -> {
                PsiCollectExportDto exportDto = new PsiCollectExportDto();
                exportDto.setId(item.getId());
                exportDto.setCollectNo(item.getCollectNo());
                exportDto.setRecipientAgent(record.getRecipientAgent());
                exportDto.setRecipientOffice(record.getRecipientOffice());
                exportDto.setCollectType(record.getCollectType());
                exportDto.setGoodsName(record.getGoodsName());
                exportDto.setProduceDate(record.getProduceDate() == null ? "暂无生产日期" : dateFormat.format(record.getProduceDate()));
                exportDto.setCollectNumber(formatExportNumber(record.getCollectNumber()));
                exportDto.setSurplusNumber(formatExportInventoryNumber(record.getSurplusNumber(), record.getSpec()));
                exportDto.setCollectDate(item.getCollectDate() == null ? "" : dateFormat.format(item.getCollectDate()));
                result.add(exportDto);
            });
        });
        return result;
    }

    public PsiCollectDto exportFileByTemplate(PsiCollectDto dto) throws Exception{
        PsiCollectDto byId = this.findById(dto.getId());
        List<PsiCollectDetailedRecord> recordList = psiDetailedMapper.getRecordsByBasicId(byId.getId(), "0");
        byId.setRecordList(recordList);
        return byId;
    }

    private String formatExportInventoryNumber(String surplusNumber, String spec) {
        if (StringUtils.isBlank(surplusNumber)) {
            return "";
        }
        try {
            if (StringUtils.isNotBlank(spec)) {
                BigDecimal specValue = new BigDecimal(spec);
                BigDecimal surplusValue = new BigDecimal(surplusNumber);
                return specValue.multiply(surplusValue).stripTrailingZeros().toPlainString();
            }
            return new BigDecimal(surplusNumber).stripTrailingZeros().toPlainString();
        } catch (Exception e) {
            return surplusNumber;
        }
    }

    public String formatExportNumber(String value) {
        if (StringUtils.isBlank(value)) {
            return "";
        }
        try {
            return new BigDecimal(value).stripTrailingZeros().toPlainString();
        } catch (Exception e) {
            return value;
        }
    }

    public IPage<PsiWareHouseSummaryDto> wareHouseList(Page<PsiWareHouseSummaryDto> page , PsiWareHouseSummaryDto dto) throws Exception{
        QueryWrapper<PsiWareHouseSummaryDto> queryWrapper = QueryWrapperGenerator.buildQueryCondition(dto, PsiWareHouseSummaryDto.class);

        queryWrapper.eq("a.del_flag", "0");
        queryWrapper.eq("a.ware_house_type", dto.getWareHouseType());
        queryWrapper.gt("a.trade_number", 0);
        if (StringUtils.isNotEmpty(dto.getTradeName())) {
            queryWrapper.like("a.trade_name", dto.getTradeName());
        }

        return basicMapper.findWareHouseList(page, queryWrapper);
    }

    public String createReturnData (String basicId) {
        PsiCollectBasicsReturn returnData = returnMapper.selectOne(new LambdaQueryWrapper<PsiCollectBasicsReturn>().eq(PsiCollectBasicsReturn::getBasicId, basicId));
        if (ObjectUtil.isNotEmpty(returnData)) {
            return returnData.getId();
        } else {
            PsiCollectBasicsReturn collectBasicsReturn = new PsiCollectBasicsReturn();
            collectBasicsReturn.setBasicId(basicId);
            collectBasicsReturn.setStatus("0"); // 未发起状态
            returnMapper.insert(collectBasicsReturn);
            return collectBasicsReturn.getId();
        }
    }

    public PsiCollectDto findByReturnId (String returnId) throws Exception {
        PsiCollectBasicsReturn returnData = returnMapper.selectOne(new LambdaQueryWrapper<PsiCollectBasicsReturn>().eq(PsiCollectBasicsReturn::getId, returnId));
        if (ObjectUtil.isNotEmpty(returnData) && StringUtils.isNotBlank(returnData.getBasicId())) {
            PsiCollectDto byId = this.findById(returnData.getBasicId());
            return byId;
        } else {
            return new PsiCollectDto();
        }
    }

    public void returnRequest(String id) {
        PsiCollectBasicsReturn returnData = returnMapper.selectOne(new LambdaQueryWrapper<PsiCollectBasicsReturn>().eq(PsiCollectBasicsReturn::getBasicId, id));
        if (ObjectUtil.isNotEmpty(returnData) && StringUtils.isNotBlank(returnData.getId())) {
            psiDetailedMapper.updateStatusByIdReturn(returnData.getId(), "0"); // 修改退回的流程状态
            basicMapper.setCauseEmptyById(returnData.getId()); // 清空退回原因
//            ossService.remove(new LambdaQueryWrapper<WorkAttachment>().eq(WorkAttachment::getAttachmentId, returnData.getId())); // 清除退回附件
            SpringUtil.getBean ( IWorkAttachmentApi.class ).deleteByAttachmentId(returnData.getId());
        }
        // 将退回状态的数据全部撤回
        psiDetailedMapper.updateNoReturnByBasicId(id);
        psiDetailedMapper.updateAutditNoReturnByBasicId(id); // 修改退回状态
        ;
        PsiCollectBasicsReturnHi psiCollectBasicsReturnHi = returnHiMapper.selectOne(
                new LambdaQueryWrapper<PsiCollectBasicsReturnHi>()
                        .eq(PsiCollectBasicsReturnHi::getCollectId, id)
                        .orderByDesc(PsiCollectBasicsReturnHi::getCreateTime)
                        .last("limit 1")
        );
        PsiCollectDto psiCollectDto = new PsiCollectDto();
        if (ObjectUtil.isNotEmpty(psiCollectBasicsReturnHi) && StringUtils.isNotBlank(psiCollectBasicsReturnHi.getJsonData())) {
            psiCollectDto = JSON.parseObject(psiCollectBasicsReturnHi.getJsonData(), PsiCollectDto.class); // json字符串解析为java对象
            for (PsiCollectDetailedRecord detailInfo : psiCollectDto.getRecordList()) {
                if (StringUtils.isNotBlank(detailInfo.getId()) && StringUtils.isNotBlank(detailInfo.getIsReturn())) {
                    //修改退回状态，退回数量
                    detailInfo.setIsReturn("0");
                    detailInfo.setSurplusStock("0");
                    psiDetailedMapper.updateAuditReturnFlagById(detailInfo); // 修改退回状态
                }
            }
        }else{
            List<PsiCollectDetailedRecord> recordList = psiDetailedMapper.getRecordsByBasicId(id, "0");
            for (PsiCollectDetailedRecord detailInfo : recordList) {
                if (StringUtils.isNotBlank(detailInfo.getId()) && StringUtils.isNotBlank(detailInfo.getIsReturn())) {
                    detailInfo.setNotSurplusStock(detailInfo.getCollectNumber());
                    detailInfo.setSurplusStock("0");
                    detailInfo.setReturnedNum("0");
                    //修改退回状态，退回数量
                    psiDetailedMapper.updateAuditReturnFlagById(detailInfo); // 修改退回状态
                }
            }
        }



    }

    // 根据领用表id查询其全部历史修改数据
    public List<PsiCollectBasicsReturnHi> findHiById(String collectId) {
        List<PsiCollectBasicsReturnHi> hiById = returnHiMapper.findHiById(collectId);
        return hiById;
    }

    // 根据历史表id查询历史表数据
    public PsiCollectDto findHiByHiId(String hiId) throws Exception {
        PsiCollectDto psiCollectDto = new PsiCollectDto();
        PsiCollectBasicsReturnHi hiByHiId = returnHiMapper.findHiByHiId(hiId); // 根据历史表id查询历史表数据
        if (ObjectUtil.isNotEmpty(hiByHiId) && StringUtils.isNotBlank(hiByHiId.getJsonData())) {
            psiCollectDto = JSON.parseObject(hiByHiId.getJsonData(), PsiCollectDto.class); // json字符串解析为java对象
            if (ObjectUtil.isNotEmpty(psiCollectDto)) {
                // 领用详情中的附件数据获取。
                // 在这里要重新获取一下领用详情附件的原因是，json字符串中的附件createBy值存储不正确，所以重新获取一下
                if(CollectionUtil.isNotEmpty(psiCollectDto.getDetailInfos())) {
                    psiCollectDto.getDetailInfos().forEach(detailed->{
                        List<WorkAttachmentDto> acList = psiDetailedMapper.getByAttachmentId(detailed.getId());
                        if (CollectionUtils.isNotEmpty(acList)) {
                            for (WorkAttachmentDto i : acList) {
                                i.setCreateBy(SpringUtil.getBean ( IUserApi.class ).getById(i.getBy()));
                            }
                        }
                        detailed.setFileInfoLost(acList);
                    });
                }
                // 领用-退回附件信息同上
                if(CollectionUtil.isNotEmpty(psiCollectDto.getReturnFiles())) {
                    psiCollectDto.getReturnFiles().forEach(file->{
                        file.setCreateBy(SpringUtil.getBean ( IUserApi.class ).getById(file.getBy()));
                    });
                }
                //退回历史
                List<PsiCollectDetailedRecord> recordList = psiCollectDto.getRecordList();
                if(CollectionUtil.isNotEmpty(recordList)){
                    psiCollectDto.setRecordList(recordList);
                }
            }

        }
        return psiCollectDto;
    }

    // 根据领用表id查询最近的一个修改历史
    public PsiCollectDto findLastHiByid(String collectId) {
        PsiCollectDto psiCollectDto = new PsiCollectDto();
        PsiCollectBasicsReturnHi hiByHiId = returnHiMapper.findLastHiByid(collectId); // 根据领用表id查询最近的一个修改历史
        if (ObjectUtil.isNotEmpty(hiByHiId) && StringUtils.isNotBlank(hiByHiId.getJsonData())) {
            psiCollectDto = JSON.parseObject(hiByHiId.getJsonData(), PsiCollectDto.class); // json字符串解析为java对象
            if (ObjectUtil.isNotEmpty(psiCollectDto)) {
                // 领用详情中的附件数据获取。
                // 在这里要重新获取一下领用详情附件的原因是，json字符串中的附件createBy值存储不正确，所以重新获取一下
                if(CollectionUtil.isNotEmpty(psiCollectDto.getDetailInfos())) {
                    psiCollectDto.getDetailInfos().forEach(detailed->{
                        List<WorkAttachmentDto> acList = psiDetailedMapper.getByAttachmentId(detailed.getId());
                        if (CollectionUtils.isNotEmpty(acList)) {
                            for (WorkAttachmentDto i : acList) {
                                i.setCreateBy(SpringUtil.getBean ( IUserApi.class ).getById(i.getBy()));
                            }
                        }
                        detailed.setFileInfoLost(acList);
                    });
                }
                // 领用-退回附件信息同上
                if(CollectionUtil.isNotEmpty(psiCollectDto.getReturnFiles())) {
                    psiCollectDto.getReturnFiles().forEach(file->{
                        file.setCreateBy(SpringUtil.getBean ( IUserApi.class ).getById(file.getBy()));
                    });
                }
            }

        }
        return psiCollectDto;
    }


    //用户树形
    public List<TreeUserDto> userTree(String name) {
        List<TreeUserDto> list = new ArrayList<>();
        List<TreeUserDto> filterList = new ArrayList<>();
        List<TreeUserDto> officeList1 =  basicMapper.findOfficeListByTenantId("10009");
        filterList.addAll(officeList1);
        List<TreeUserDto> offices = Lists.newArrayList();
        ArrayList<TreeUserDto> treeUserDtos = new ArrayList<>();
        //查询物资公司所有用户信息
        List<TreeUserDto> UserList=basicMapper.findJxcUserList(name);
        treeUserDtos.addAll(UserList);
        list = disposeUserTree(treeUserDtos, filterList);
        for (TreeUserDto officeDto : officeList1) {
            if("0".equals(officeDto.getParentId())){
                list.add(officeDto);
            }
        }
        for (TreeUserDto officeDto : offices) {
            if("0".equals(officeDto.getParentId())){
                list.add(officeDto);
            }
        }
        //去重
        List<TreeUserDto> newList = list.stream().collect(Collectors.collectingAndThen(
                Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(TreeUserDto::getId))), ArrayList::new)
        );
        return newList;
    }

    /**
     * 用户树形数据处理
     * @param userList
     * @param officeList
     * @return
     */
    public List<TreeUserDto> disposeUserTree(List<TreeUserDto> userList, List<TreeUserDto> officeList){
        List<TreeUserDto> list = new ArrayList<>();
        for (TreeUserDto userDto : userList) {

            for (TreeUserDto officeDto : officeList) {
                if(org.apache.commons.lang3.StringUtils.isNotBlank(userDto.getParentId()) && userDto.getParentId().equals(officeDto.getId())){
                    list.add(officeDto);
                    list.add(userDto);
                    List<TreeUserDto> treeUserDtos = disposeOfficeTree(officeDto, officeList);
                    if(null!= treeUserDtos && treeUserDtos.size()>0){
                        list.addAll(treeUserDtos);
                    }
                }
            }
        }
        return list;
    }


    /**
     * 用户树形数据处理
     * @param officeInfo
     * @param officeList
     * @return
     */
    public List<TreeUserDto> disposeOfficeTree(TreeUserDto officeInfo, List<TreeUserDto> officeList){
        List<TreeUserDto> listAll = Lists.newArrayList();
        for (TreeUserDto officeDto : officeList) {
            if(officeInfo.getParentId().equals(officeDto.getId())){
                listAll.add(officeDto);
                disposeOfficeTree(officeDto,officeList);
            }
        }
        return listAll;
    }

}
