package com.zbf.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zbf.common.annotation.DataScope;
import com.zbf.common.annotation.Log;
import com.zbf.common.enums.custom.InboundFictitiousFlag;
import com.zbf.common.enums.custom.InboundLevelType;
import com.zbf.common.enums.custom.InboundNoticeReceivingStatus;
import com.zbf.common.enums.custom.InboundNoticeTabInStatus;
import com.zbf.common.enums.custom.InboundNoticeTabReceivingStatus;
import com.zbf.common.enums.custom.InboundNoticeTabStatus;
import com.zbf.common.enums.custom.InboundOngoodsshelfInStatus;
import com.zbf.common.enums.custom.InboundResourceLockStatus;
import com.zbf.common.enums.custom.InboundResourceOccupancyStatus;
import com.zbf.common.enums.custom.InboundStorageMode;
import com.zbf.common.enums.custom.InboundTaskStatus;
import com.zbf.common.enums.custom.InboundTaskType;
import com.zbf.common.exception.ServiceException;
import com.zbf.common.utils.DateUtils;
import com.zbf.common.utils.OrderCodeFactory;
import com.zbf.common.utils.SecurityUtils;
import com.zbf.common.utils.StringUtils;
import com.zbf.common.utils.bean.BeanUtils;
import com.zbf.common.utils.uuid.IdUtils;
import com.zbf.system.domain.*;
import com.zbf.system.mapper.*;
import com.zbf.system.service.*;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
//import sun.security.util.AuthResources_it;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import javax.validation.Validator;
import java.math.BigDecimal;
import java.security.cert.X509Certificate;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 入库通知单Service业务层处理
 *
 * @author tony
 * @date 2024-06-18
 */
@Service
public class TRkWareNoticeServiceImpl extends ServiceImpl<TRkWareNoticeMapper, TRkWareNotice>
        implements ITRkWareNoticeService // 修改
{
    private final Logger logger = LoggerFactory.getLogger(TRkWareNoticeServiceImpl.class);
    @Autowired
    private TRkWareNoticeMapper tRkWareNoticeMapper;

    @Autowired
    private TRkWareNoticeBakMapper tRkWareNoticeBakMapper;

    @Autowired
    private TOngoodsshelfMapper tOngoodsshelfMapper;

    @Autowired
    private TOngoodsshelfBakMapper tOngoodsshelfBakMapper;

    @Autowired
    private TRkReceivingGoodsMapper tRkReceivingGoodsMapper;

    @Autowired
    private TBaseStorageMapper tBaseStorageMapper;

    @Autowired
    private TMiStockMapper tMiStockMapper;

    @Autowired
    private TMiStockFMapper tMiStockFMapper;

    @Autowired
    private SysConfigMapper sysConfigMapper;

    @Autowired
    private IPlcService plcService;

    @Autowired
    private ITCallNoticeService tNoticeService;

    @Autowired
    private TBaseStorageAreaLocationMapper tBaseStorageAreaLocationMapper;

    @Autowired
    private ISysConfigService configService;
    @Autowired
    protected Validator validator;
    @Autowired
    private TRkWareNoticeTabMapper tRkWareNoticeTabMapper;

    @Autowired
    private PlcMapper plcMapper;

    @Autowired
    private TBasePalletMapper palletMapper;

    @Autowired
    private TBaseStorageAreaLocationMapper service;

    @Autowired
    private ITCallNoticeOrderService tNoticeOrderService;

    @Autowired
    private SysDictDataMapper sysDictDataMapper;


    @Autowired
    private TCallNoticeOrderMapper callNoticeOrderMapper;

    @Autowired
    private TBaseGoodsMapper tBaseGoodsMapper;

    @Autowired
    private TCallNoticeOrderMapper mappers;

    @Autowired
    private TOngoodsshelfMapper tOgoodsshelfMapper;

    @Autowired
    private SysUserMapper sysUserMapper;


    /**
     * 查询入库通知单
     *
     * @param id 入库通知单主键
     * @return 入库通知单
     */
    @Override
    public TRkWareNotice selectTRkWareNoticeById(String id) {
        return tRkWareNoticeMapper.selectTRkWareNoticeById(id);
    }

    /**
     * 查询入库通知单
     *
     * @param id 入库通知单主键
     * @return 入库通知单
     */
    @Override
    public TRkWareNotice selectTRkWareNoticeByNoticeId(String id) {
        return tRkWareNoticeMapper.selectTRkWareNoticeByNoticeId(id);
    }

    /**
     * 查询入库通知单
     *
     * @param id 入库通知单主键
     * @return 入库通知单
     */
    @Override
    public TRkWareNotice selectTRkWareNoticeByDeliveryId(String id) {
        return tRkWareNoticeMapper.selectTRkWareNoticeByDeliveryId(id);
    }

    /**
     * 查询入库通知单列表
     *
     * @param tRkWareNotice 入库通知单
     * @return 入库通知单
     */
    @Override
    @DataScope(deptAlias = "d")
    public List<TRkWareNotice> selectTRkWareNoticeList(TRkWareNotice tRkWareNotice) {
        return tRkWareNoticeMapper.selectTRkWareNoticeList(tRkWareNotice);
    }

    /**
     * 导出入库通知单列表
     *
     * @param tRkWareNotice 入库通知单
     * @return 入库通知单
     */
    @Override
    @DataScope(deptAlias = "a")
    public List<TRkWareNotice> exportTRkWareNoticeList(TRkWareNotice tRkWareNotice) {
        return tRkWareNoticeMapper.exportTRkWareNoticeList(tRkWareNotice);
    }

    /**
     * 新增入库通知单
     *
     * @param tRkWareNotice 入库通知单
     * @return 结果
     */
    @Transactional
    @Override
    public int insertTRkWareNotice(TRkWareNotice tRkWareNotice) {

        // 来源单号
        int cnt = tRkWareNoticeMapper.selectTRkWareNoticeByOrginalId(tRkWareNotice.getDeliveryId());

        if (cnt > 0) {
            throw new RuntimeException("来源单号重复");
        }

        tRkWareNotice.setCreateTime(DateUtils.getNowDate());
        int rows = tRkWareNoticeMapper.insertTRkWareNotice(tRkWareNotice);
        // insertTRkWareNoticeTab(tRkWareNotice);
        return rows;
    }

    /**
     * 修改入库通知单
     *
     * @param tRkWareNotice 入库通知单
     * @return 结果
     */
    @Transactional
    @Override
    public int updateTRkWareNotice(TRkWareNotice tRkWareNotice) {

        // 来源单号
        int cnt = tRkWareNoticeMapper.selectTRkWareNoticeByOrginalId(tRkWareNotice.getDeliveryId());

        if (cnt > 0) {
            throw new RuntimeException("来源单号重复");
        }

        tRkWareNotice.setUpdateTime(DateUtils.getNowDate());
        tRkWareNoticeMapper.deleteTRkWareNoticeTabByNoticeId(tRkWareNotice.getId());
        // insertTRkWareNoticeTab(tRkWareNotice);
        return tRkWareNoticeMapper.updateTRkWareNotice(tRkWareNotice);
    }

    /**
     * 批量删除入库通知单
     *
     * @param ids 需要删除的入库通知单主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteTRkWareNoticeByIds(String[] ids) {
        tRkWareNoticeMapper.deleteTRkWareNoticeTabByNoticeIds(ids);
        LambdaQueryWrapper<TCallNoticeOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(TCallNoticeOrder::getTaskId, ids);

        List<TCallNoticeOrder> orders = mappers.selectList(wrapper);
        if (orders.size() > 0) {
            List<String> collect = orders.stream().map(TCallNoticeOrder::getId).collect(Collectors.toList());
            mappers.deleteTCallNoticeOrderByIds(collect.toArray(new String[0]));
        }


        return tRkWareNoticeMapper.deleteTRkWareNoticeByIds(ids);
    }

    /**
     * 删除入库通知单信息
     *
     * @param id 入库通知单主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteTRkWareNoticeById(String id) {
        tRkWareNoticeMapper.deleteTRkWareNoticeTabByNoticeId(id);
        return tRkWareNoticeMapper.deleteTRkWareNoticeById(id);
    }

    /**
     * 批量禁用
     *
     * @param ids 入库通知单主键
     * @return 结果
     */
    @Transactional
    @Override
    public int disabledTRkWareNoticeByIds(String[] ids) {
        return tRkWareNoticeMapper.disabledTRkWareNoticeByIds(ids);
    }

    /**
     * 批量启用
     *
     * @param ids 入库通知单主键
     * @return 结果
     */
    @Transactional
    @Override
    public int enableTRkWareNoticeByIds(String[] ids) {
        return tRkWareNoticeMapper.enableTRkWareNoticeByIds(ids);
    }

    /**
     * 修改状态
     *
     * @param tRkWareNotice 工序管理主键
     * @return 结果
     */
    @Transactional
    @Override
    public int updateStatus(TRkWareNotice tRkWareNotice) {
        return tRkWareNoticeMapper.updateTRkWareNotice(tRkWareNotice);
    }

    /**
     * 新增入库通知单明细信息
     *
     * @param tRkWareNotice 入库通知单对象
     */
    public void insertTRkWareNoticeTab(TRkWareNotice tRkWareNotice) {
        List<TRkWareNoticeTab> tRkWareNoticeTabList = tRkWareNotice.getTRkWareNoticeTabList();
        String id = tRkWareNotice.getId();
        if (StringUtils.isNotNull(tRkWareNoticeTabList)) {
            List<TRkWareNoticeTab> list = new ArrayList<TRkWareNoticeTab>();
            for (TRkWareNoticeTab tRkWareNoticeTab : tRkWareNoticeTabList) {
                tRkWareNoticeTab.setNoticeId(id);
                list.add(tRkWareNoticeTab);
            }
            if (list.size() > 0) {
                tRkWareNoticeMapper.batchTRkWareNoticeTab(list);
            }
        }
    }

    /**
     * 收货
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    /* 先进行一系列的防呆判断
     * 然后根据传参confirmRequest去更新数据库内的入库单明细表
     * 之后生成入库任务, 最后通知手持
     * 这个方法没有更新主表通知单状态
     * 也没有把明细 receivingStatus 改成完成
     *
     */
    // 入库流程
    public Map<String, String> confirmNoticeTab(TRkWareNoticeTabUpdate confirmRequest) {

        // 返回结果
        Map<String, String> resultMap = new HashMap<>();

        // 查询入库通知单明细
        TRkWareNotice inboundNotice = tRkWareNoticeMapper.selectTRkWareNoticeById(confirmRequest.getId());

        // 手持通知信息
        TCallNotice inboundCallNotice = new TCallNotice();
        inboundCallNotice.setId(IdUtils.randomUUID());
        confirmRequest.getParams().put("callNoticeId", inboundCallNotice.getId());

        if (inboundNotice == null) {
            resultMap.put("error", "入库通知单不存在");
            throw new RuntimeException("入库通知单不存在");

        }

        // 托盘号为空
        if (ObjectUtils.isEmpty(confirmRequest.getCtlNo())) {
            // 查询PLC表
            List<Plc> plcList = plcService.selectPlcList();
            Plc currentPlc = plcList.get(0);

            // 到达9999999 则自动从0开始
            if (currentPlc.getPlcid() == 9999999) {
                currentPlc.setPlcid(0L);
            } else {
                currentPlc.setPlcid(currentPlc.getPlcid() + 1);
            }

            currentPlc.setId(1);
            plcService.updatePlc(currentPlc);

            confirmRequest.getParams().put("plcId", currentPlc.getPlcid());

        } else {

            // 校验同一托盘号在库存中是否存在
            TMiStock stockQuery = new TMiStock();
            stockQuery.setCtl(confirmRequest.getCtlNo());
            List<TMiStock> matchedStocks = tMiStockMapper.selectTMiStockList(stockQuery);

            if (!matchedStocks.isEmpty()) {
                resultMap.put("error", "托盘【" + confirmRequest.getCtlNo() + "】已占用，请更换");
                throw new RuntimeException("托盘" + confirmRequest.getCtlNo() + "已占用，请更换");
            }


            //校验托盘容器是否正确
            LambdaQueryWrapper<TBasePallet> palletQueryWrapper = new LambdaQueryWrapper<>();
            palletQueryWrapper.eq(TBasePallet::getPalletId, confirmRequest.getCtlNo());
            List<TBasePallet> palletMatches = palletMapper.selectList(palletQueryWrapper);
            if (palletMatches.isEmpty()) {
                resultMap.put("error", "托盘不存在");
                throw new RuntimeException("托盘" + confirmRequest.getCtlNo() + "不存在");
            }

            TBasePallet targetPallet = palletMatches.get(0);
            if (InboundResourceLockStatus.LOCKED.getCode().equals(targetPallet.getIsLock())) {
                resultMap.put("error", "托盘号【" + confirmRequest.getCtlNo() + "】已禁用");
                log.error("托盘号【" + confirmRequest.getCtlNo() + "】已禁用");
                throw new RuntimeException("托盘号【" + confirmRequest.getCtlNo() + "】已禁用");
            }
            if (InboundResourceOccupancyStatus.EMPTY.getCode().equals(targetPallet.getStatus())
                    || StringUtils.isBlank(targetPallet.getStatus())) {
                TBasePallet palletOccupancyUpdate = new TBasePallet();
                palletOccupancyUpdate.setStatus(InboundResourceOccupancyStatus.OCCUPIED.getCode());
                palletOccupancyUpdate.setId(targetPallet.getId());
                palletOccupancyUpdate.setUpdateBy(confirmRequest.getUserName());
                palletOccupancyUpdate.setUpdateTime(new Date());
                palletMapper.updateTBasePallet(palletOccupancyUpdate);
            }
        }

        // 通知单明细map
        Map<String, TRkWareNoticeTab> noticeTabFromDbById = new HashMap<>();
        for (int i = 0; i < inboundNotice.getTRkWareNoticeTabList().size(); i++) {
            TRkWareNoticeTab noticeTab = inboundNotice.getTRkWareNoticeTabList().get(i);
            noticeTabFromDbById.put(noticeTab.getId(), noticeTab);
        }

        if ("".equals(confirmRequest.getUserName())) {
            confirmRequest.setUserName(confirmRequest.getRecordPerson());
        }

        List<TRkWareNoticeTab> updatedNoticeTabs = new ArrayList<>();
        List<TOngoodsshelf> inboundTasksToCreate = new ArrayList<>();


        //冻结校验
        List<TRkWareNoticeTab> submittedNoticeTabs = confirmRequest.getTrkWareNoticeTabList();
        for (TRkWareNoticeTab submittedNoticeTab : submittedNoticeTabs) {
            TRkWareNoticeTab noticeTabInDb = noticeTabFromDbById.get(submittedNoticeTab.getId());
            if (noticeTabInDb == null) {
                resultMap.put("error", "物料【" + submittedNoticeTab.getGoodsName() + "】的通知单明细不存在");
                throw new RuntimeException("物料【" + submittedNoticeTab.getGoodsName() + "】的通知单明细不存在");
            }
            if (InboundNoticeTabInStatus.LOCKED.getCode().equals(noticeTabInDb.getInStatus())) {
                resultMap.put("error", "物料【" + noticeTabInDb.getGoodsName() + "】已冻结，不可收货");
                log.error("物料【" + noticeTabInDb.getInStatus() + "】已冻结，不可收货");
                throw new RuntimeException("物料【" + noticeTabInDb.getInStatus() + noticeTabInDb.getGoodsName() + " 】已冻结，不可收货");
            }
        }


        // 遍历提交的通知单明细数据
        for (TRkWareNoticeTab submittedNoticeTab : confirmRequest.getTrkWareNoticeTabList()) {
            TRkWareNoticeTab noticeTabToUpdate = noticeTabFromDbById.get(submittedNoticeTab.getId());

            if (noticeTabToUpdate == null) {
                resultMap.put("error", "物料【" + submittedNoticeTab.getGoodsName() + "】的通知单明细不存在");
                throw new RuntimeException("物料【" + submittedNoticeTab.getGoodsName() + "】的通知单明细不存在");
            }


            // 仓库ID
            String resolvedStorageId = confirmRequest.getStorageId();
            if (!ObjectUtils.isEmpty(submittedNoticeTab.getStorageId())) {
                resolvedStorageId = submittedNoticeTab.getStorageId();
            }

            // 获取仓库信息
            TBaseStorage storageQuery = new TBaseStorage();
            storageQuery.setStorageId(null);
            List<TBaseStorage> availableStorages = tBaseStorageMapper.selectTBaseStorageList(storageQuery);

            if (availableStorages.size() > 0) {
                TBaseStorage storage = availableStorages.get(0);

                // 判断是否为AGV库 TODO
                if ("1".equals(storage.getIsAgv())) {

                    // 更新入库通知单明细状态

                    // 创建入库任务：待执行

                    // 调用AGV接口

                    continue;
                }
            } else {
                resultMap.put("error", "物料【" + submittedNoticeTab.getGoodsName() + "】设置的仓库【" + resolvedStorageId + "】不存在");
                throw new RuntimeException("物料【" + submittedNoticeTab.getGoodsName() + "】设置的仓库【" + resolvedStorageId + "】不存在");
            }


            BigDecimal currentReceivedQuantity = submittedNoticeTab.getRecNumNow() == null ? BigDecimal.ZERO : submittedNoticeTab.getRecNumNow();
            if (currentReceivedQuantity.compareTo(BigDecimal.ZERO) == 0) {
                throw new RuntimeException("物料【" + submittedNoticeTab.getGoodsName() + "】的收货数量不能为0");
            }

            BigDecimal accumulatedReceivedQuantity = noticeTabToUpdate.getRecNum() == null ? BigDecimal.ZERO : noticeTabToUpdate.getRecNum();
            BigDecimal plannedReceivingQuantity = noticeTabToUpdate.getReceivingNum() == null ? BigDecimal.ZERO : noticeTabToUpdate.getReceivingNum();

            // 本次收货量 + 已累计收货量 不能超过这条明细的目标收货量，否则就是超收
            if (currentReceivedQuantity.add(accumulatedReceivedQuantity).compareTo(plannedReceivingQuantity) > 0) {
                resultMap.put("error", "物料【" + submittedNoticeTab.getGoodsName() + "】的收货数量不能大于签收数量");
                throw new RuntimeException("物料【" + submittedNoticeTab.getGoodsName() + "】的收货数量不能大于签收数量");
            }

            // 设置更新信息
            noticeTabToUpdate.setRecNum(currentReceivedQuantity.add(accumulatedReceivedQuantity));

            // 收满了, 已达到目标收货量
            if (noticeTabToUpdate.getRecNum().compareTo(plannedReceivingQuantity) == 0) {
                // 物料明细冻结
                noticeTabToUpdate.setInStatus(InboundNoticeTabInStatus.LOCKED.getCode());
            }

            noticeTabToUpdate.setRecNumNow(currentReceivedQuantity);
            noticeTabToUpdate.setStorageId(resolvedStorageId);
            // 托盘
            noticeTabToUpdate.setCtl(confirmRequest.getCtlNo());

            noticeTabToUpdate.setUpdateBy(confirmRequest.getUserName());
            noticeTabToUpdate.setUpdateTime(new Date());

            // 仓库名称
            if (availableStorages.size() > 0) {
                TBaseStorage storage = availableStorages.get(0);
                noticeTabToUpdate.setStorageShortName(storage.getStorageShortName());
            }

            updatedNoticeTabs.add(noticeTabToUpdate);

            tRkWareNoticeTabMapper.updateTRkWareNoticeTab(noticeTabToUpdate);

            // 生成入库任务
            inboundTasksToCreate.add(buildInboundTask(inboundNotice, noticeTabToUpdate, confirmRequest));
        }

        // 生成入库任务
        if (inboundTasksToCreate.size() > 0) {
            for (TOngoodsshelf inboundTaskToInsert : inboundTasksToCreate) {
                tOngoodsshelfMapper.insertTOngoodsshelf(inboundTaskToInsert);
            }

            // 仓库id
            inboundCallNotice.setStorageId(confirmRequest.getStorageId());
            // 托盘号
            inboundCallNotice.setCtl(confirmRequest.getCtlNo());

            inboundCallNotice.setPlcid((Long) confirmRequest.getParams().get("plcId"));
            // 任务类型 0:入库任务
            inboundCallNotice.setTaskType(InboundTaskType.INBOUND.getCode());
            // 物料编码
            // inboundCallNotice.setGoodsId(inboundTaskToInsert.getGoodsId());
            // 物料名称
            // inboundCallNotice.setGoodsName(inboundTaskToInsert.getGoodsName());
            // 入库任务ID
            // inboundCallNotice.setRukuId(inboundTaskToInsert.getId());
            // 创建者
            inboundCallNotice.setCreateBy(confirmRequest.getCreateBy());
            // 时间
            inboundCallNotice.setCreateTime(new Date());
            // 状态 0：未处理
            inboundCallNotice.setStatus(InboundTaskStatus.PENDING.getCode());
            // 虚拟入库任务
            inboundCallNotice.setFictitious(confirmRequest.getFictitious());
            // 通知单号
            inboundCallNotice.setTaskId(inboundNotice.getNoticeId());

            tNoticeService.sendNotice(inboundCallNotice);

        }


        resultMap.put("success", "收货成功");
        resultMap.put("error", "");
        return resultMap;
    }

    private TOngoodsshelf buildInboundTask(TRkWareNotice inboundNotice, TRkWareNoticeTab inboundNoticeTab,
                                           TRkWareNoticeTabUpdate confirmRequest) {
        TOngoodsshelf inboundTask = new TOngoodsshelf();
        // 入库数量 TODO
        inboundTask.setAccNum(inboundNoticeTab.getRecNumNow());
        // 需求数量 TODO
        // inboundTask.setStoNum();

        inboundTask.setId(OrderCodeFactory.getOrderCode("S", ""));

        // 中标供应商
        inboundTask.setProviderId(inboundNotice.getProviderId());
        // 单位
        inboundTask.setUnit(inboundNoticeTab.getUnit());
        // 子需求编号
        inboundTask.setSalesOrderNumber(inboundNoticeTab.getSalesOrderNumber());
        // 物料名称
        inboundTask.setGoodsName(inboundNoticeTab.getGoodsName());
        // 规格型号
        inboundTask.setSpecification(inboundNoticeTab.getSpecification());
        // 物料描述
        inboundTask.setRecoil(inboundNoticeTab.getRecoil());
        // 招标员
        inboundTask.setCustomerId(inboundNotice.getTenderer());
        // 需求组织
        inboundTask.setOperatorId(inboundNotice.getOperatorId());
        // 申请部门
        inboundTask.setSupplier(inboundNoticeTab.getSupplier());
        // 创建时间
        inboundTask.setOperateDate(inboundNoticeTab.getOperateDate());
        // 上报时间
        inboundTask.setReportTime(inboundNoticeTab.getReportTime());
        // 申请单号 设置为来源单号 发货单号 TODO
        inboundTask.setLotId(inboundNotice.getPurchaseId());
        // 申请人
        inboundTask.setApplicant(inboundNotice.getApplicant());
        // 主管部门 TODO
        // inboundTask.setRespDept(null);
        // 计划日期
        inboundTask.setPlanDate(inboundNoticeTab.getPlanDate());
        // 计划期间
        inboundTask.setPlanTime(inboundNoticeTab.getPlanTime());
        // 需求周期
        inboundTask.setNeedCycle(inboundNoticeTab.getNeedCycle());
        // 需求类型
        inboundTask.setNeedType(inboundNoticeTab.getNeedType());
        // 物料编码
        inboundTask.setGoodsId(inboundNoticeTab.getGoodsId());
        // 物料分类
        inboundTask.setGoodsTypeId(inboundNoticeTab.getGoodsTypeId());
        // 品牌
        inboundTask.setBrand(inboundNoticeTab.getBrand());
        // 计划单价（含税）
        inboundTask.setPrice(inboundNoticeTab.getPrice());
        // 计划金额
        inboundTask.setTotalMoney(inboundNoticeTab.getTotalMoney());
        // 需求时间
        inboundTask.setExpiryDate(inboundNoticeTab.getExpiryDate());
        // 建议供应商名称 TODO
        inboundTask.setProviderName(inboundNotice.getProviderName());
        // 收货人
        inboundTask.setReceiver(inboundNotice.getReceiver());
        // 需求部门
        inboundTask.setNeedDept(inboundNoticeTab.getNeedDept());
        // 采购组织
        inboundTask.setPurchaseDept(inboundNotice.getPurchaseDept());
        // 收货组织
        inboundTask.setProduclotId(inboundNotice.getProduclotId());
        // 收货人部门
        inboundTask.setReceiverDept(inboundNotice.getReceiverDept());
        // 送货区域
        inboundTask.setReceivingArea(inboundNotice.getReceivingArea());
        // 技术需求附件
        inboundTask.setPackageId(inboundNoticeTab.getPackageId());
        // 物资计划明细备注
        inboundTask.setRemark(inboundNoticeTab.getRemark());
        // 用途
        inboundTask.setUseType(inboundNoticeTab.getUseType());
        // 中标供应商联系方式
        inboundTask.setTelephone(inboundNotice.getTelephone());
        // wms订单号
        inboundTask.setAcceId(inboundNotice.getNoticeId());


        // 状态 0:未执行
        inboundTask.setInStatus(InboundOngoodsshelfInStatus.PENDING.getCode());
        // 打印状态
        inboundTask.setPrintSts("0");
        // 打印次数
        inboundTask.setPrintCs(BigDecimal.ZERO);
        // 生产日期
        inboundTask.setProductionDate(inboundNoticeTab.getProductionDate());
        // 入库类型
        inboundTask.setStorageMode(confirmRequest.getStorageMode());
        // 仓库编号
        inboundTask.setStorageId(inboundNoticeTab.getStorageId());
        inboundTask.setStorageShortName(inboundNoticeTab.getStorageShortName());
        // 库位
        inboundTask.setLocationId(inboundNoticeTab.getStorageLocation());
        // 入库方式 TODO
        // inboundTask.setPurchaseType(inboundNoticeTab.getpu.getPurchaseType()));
        // 入库时间
        inboundTask.setOndate(DateUtils.getTime());
        // 是否人工码盘
        inboundTask.setManualTrayState("1");
        // 增加采购入库单号 TODO 交货单号
        inboundTask.setWmsOrderId(inboundNotice.getDeliveryId());
        // 增加外部批次号
        inboundTask.setBatchNo(inboundNoticeTab.getBatchNo());
        // 条码
        inboundTask.setBarcode(inboundNoticeTab.getBarcode());

        // 通知单明细编号
        inboundTask.setNoticeTabId(inboundNoticeTab.getId());

        // 托盘
        inboundTask.setCtl(confirmRequest.getCtlNo());

        if (ObjectUtils.isEmpty(confirmRequest.getCtlNo())) {
            inboundTask.setPlcId((Long) confirmRequest.getParams().get("plcId"));
            // 状态 2:任务完成 待确认
            inboundTask.setInStatus(InboundOngoodsshelfInStatus.PLC_ASSIGNED.getCode());
        }

        inboundTask.setDeptId(confirmRequest.getDeptId());

        inboundTask.setCreateBy(SecurityUtils.getUserNick());
        inboundTask.setCreateTime(new Date());

        // 入库级别
        inboundTask.setLevelType(inboundNoticeTab.getLevelType());
        //申请人
        inboundTask.setNeedPerson(inboundNoticeTab.getNeedPerson());
        inboundTask.setNeedTel(inboundNoticeTab.getNeedTel());

        inboundTask.setRfidEpc(confirmRequest.getRfidEpc());

        inboundTask.setRfidTid(confirmRequest.getRfidTid());
        // 呼叫任务号
        if (!ObjectUtils.isEmpty(confirmRequest.getParams().get("callNoticeId"))) {
            inboundTask.setCallNoticeId((String) confirmRequest.getParams().get("callNoticeId"));
        }

        return inboundTask;
    }

    /**
     * 编辑库存信息
     *
     * @return
     */
    private TMiStock buildRealStockRecord(TRkWareNotice inboundNotice, TRkWareNoticeTab inboundNoticeTab,
                                          TRkWareNoticeTabUpdate shelfConfirmRequest, TOngoodsshelf storedInboundTask) {
        TMiStock realStockRecord = new TMiStock();

        // 需求数量 TODO
        // realStockRecord.setStoNum();

        realStockRecord.setId(OrderCodeFactory.getOrderCode("TMI", ""));

        // 上架数量

        realStockRecord.setShelvesNum(inboundNoticeTab.getAmount());

        // 中标供应商
        realStockRecord.setProviderId(inboundNotice.getProviderId());
        // 单位
        realStockRecord.setUnit(inboundNoticeTab.getUnit());
        // 子需求编号
        realStockRecord.setSalesOrderNumber(inboundNoticeTab.getSalesOrderNumber());
        // 物料名称
        realStockRecord.setGoodsName(inboundNoticeTab.getGoodsName());
        // 规格型号
        realStockRecord.setSpecification(inboundNoticeTab.getSpecification());
        // 物料描述
        realStockRecord.setRecoil(inboundNoticeTab.getRecoil());
        // 招标员
        realStockRecord.setCustomerId(inboundNotice.getTenderer());
        // 需求组织
        realStockRecord.setOperatorId(inboundNotice.getOperatorId());
        // 申请部门
        realStockRecord.setSupplier(inboundNoticeTab.getSupplier());
        // 创建时间
        realStockRecord.setOperateDate(inboundNoticeTab.getOperateDate());
        // 上报时间
        if (StringUtils.isNotBlank(inboundNoticeTab.getReportTime())) {
            realStockRecord.setReportTime(inboundNoticeTab.getReportTime());
        } else {
            realStockRecord.setReportTime(DateUtils.getDate());
        }
        // 申请单号 设置为来源单号 发货单号 TODO
        if (StringUtils.isNotBlank(inboundNotice.getDeliveryId())) {
            realStockRecord.setLotId(inboundNotice.getDeliveryId());
        } else if (StringUtils.isNotBlank(inboundNotice.getPurchaseId())) {
            realStockRecord.setLotId(inboundNotice.getPurchaseId());
        } else if (StringUtils.isNotBlank(inboundNoticeTab.getSourceNum())) {
            realStockRecord.setLotId(inboundNoticeTab.getSourceNum());
        } else {
            realStockRecord.setLotId(inboundNoticeTab.getPurchaseId());
        }
        // 申请人
        realStockRecord.setApplicant(inboundNotice.getApplicant());
        // 计划日期
        realStockRecord.setPlanDate(inboundNoticeTab.getPlanDate());
        // 计划期间
        realStockRecord.setPlanTime(inboundNoticeTab.getPlanTime());
        // 需求周期
        realStockRecord.setNeedCycle(inboundNoticeTab.getNeedCycle());
        // 需求类型
        realStockRecord.setNeedType(inboundNoticeTab.getNeedType());
        // 物料编码
        realStockRecord.setGoodsId(inboundNoticeTab.getGoodsId());
        // 物料分类
        realStockRecord.setGoodsTypeId(inboundNoticeTab.getGoodsTypeId());
        // 品牌
        realStockRecord.setBrand(inboundNoticeTab.getBrand());
        // 计划单价（含税）
        realStockRecord.setPrice(inboundNoticeTab.getPrice() != null ? inboundNoticeTab.getPrice().toString() : null);
        // 计划金额
        realStockRecord.setTotalMoney(inboundNoticeTab.getTotalMoney());
        // 需求时间
        realStockRecord.setExpiryDate(inboundNoticeTab.getExpiryDate());
        // 建议供应商名称 TODO
        realStockRecord.setProviderName(inboundNotice.getProviderName());
        // 收货人
        realStockRecord.setReceiver(inboundNotice.getReceiver());
        // 需求部门
        realStockRecord.setNeedDept(inboundNoticeTab.getNeedDept());
        // 采购组织
        realStockRecord.setPurchaseDept(inboundNotice.getPurchaseDept());
        // 收货组织
        realStockRecord.setProduclotId(inboundNotice.getProduclotId());
        // 收货人部门
        realStockRecord.setReceiverDept(inboundNotice.getReceiverDept());
        // 送货区域
        realStockRecord.setReceivingArea(inboundNotice.getReceivingArea());
        // 技术需求附件
        realStockRecord.setPackageId(inboundNoticeTab.getPackageId());
        // 物资计划明细备注
        realStockRecord.setRemark(inboundNoticeTab.getRemark());
        // 用途
        realStockRecord.setUseType(inboundNoticeTab.getUseType());
        // 中标供应商联系方式
        realStockRecord.setTelephone(inboundNotice.getTelephone());
        // wms订单号 入库通知单号
        realStockRecord.setNoticeId(inboundNotice.getId());
        // 生产日期
        realStockRecord.setProductionDate(inboundNoticeTab.getProductionDate());
        // 入库类型
        realStockRecord.setStorageMode(shelfConfirmRequest.getStorageMode());
        // 仓库编号
        realStockRecord.setStorageId(inboundNoticeTab.getStorageId());


        TBaseStorage storage = tBaseStorageMapper.getName(inboundNoticeTab.getStorageId());
        realStockRecord.setStorageShortName(storage.getStorageShortName());
        // 库位
        realStockRecord.setLocationId(inboundNoticeTab.getStorageLocation());
        // 增加外部批次号
        realStockRecord.setBatchNo(inboundNoticeTab.getBatchNo());
        // 条码
        realStockRecord.setBarcode(inboundNoticeTab.getBarcode());
        // 入库级别
        realStockRecord.setLevelType(inboundNoticeTab.getLevelType());

        // 标准超期呆滞
        realStockRecord.setStandard(shelfConfirmRequest.getExtras().get("extraTime"));

        // 托盘
        realStockRecord.setCtl(shelfConfirmRequest.getCtlNo());

        realStockRecord.setRecordPerson(shelfConfirmRequest.getRecordPerson());

        // 入库时间

        realStockRecord.setWareDate(DateUtils.getTime());

        realStockRecord.setDeptId(shelfConfirmRequest.getDeptId());
        realStockRecord.setNeedPerson(inboundNoticeTab.getNeedPerson());
        realStockRecord.setNeedTel(inboundNoticeTab.getNeedTel());
        realStockRecord.setExpiryDate(inboundNoticeTab.getExpiryDate());

        realStockRecord.setCreateBy(shelfConfirmRequest.getUserName());
        realStockRecord.setUpdateBy(shelfConfirmRequest.getUserName());

        realStockRecord.setCreateTime(new Date());
        realStockRecord.setPurchaseId(inboundNoticeTab.getPurchaseId());

        realStockRecord.setUpdateTime(new Date());
        realStockRecord.setOperateDate(new Date());

        realStockRecord.setRfidEpc(storedInboundTask.getRfidEpc());

        realStockRecord.setRfidTid(storedInboundTask.getRfidTid());
        return realStockRecord;
    }

    /**
     * 编辑库存信息
     *
     */
    private TMiStockF buildVirtualStockRecord(TRkWareNotice inboundNotice, TRkWareNoticeTab inboundNoticeTab,
                                              TRkWareNoticeTabUpdate shelfConfirmRequest) {
        TMiStockF virtualStockRecord = new TMiStockF();

        // 需求数量 TODO
        // virtualStockRecord.setStoNum();

        virtualStockRecord.setId(OrderCodeFactory.getOrderCode("TMI", ""));

        // 上架数量
        virtualStockRecord.setShelvesNum(inboundNoticeTab.getAmount());
        // 中标供应商
        virtualStockRecord.setProviderId(inboundNotice.getProviderId());
        // 单位
        virtualStockRecord.setUnit(inboundNoticeTab.getUnit());
        // 子需求编号
        virtualStockRecord.setSalesOrderNumber(inboundNoticeTab.getSalesOrderNumber());
        // 物料名称
        virtualStockRecord.setGoodsName(inboundNoticeTab.getGoodsName());
        // 规格型号
        virtualStockRecord.setSpecification(inboundNoticeTab.getSpecification());
        // 物料描述
        virtualStockRecord.setRecoil(inboundNoticeTab.getRecoil());
        // 招标员
        virtualStockRecord.setCustomerId(inboundNotice.getTenderer());
        // 需求组织
        virtualStockRecord.setOperatorId(inboundNotice.getOperatorId());
        // 申请部门
        virtualStockRecord.setSupplier(inboundNoticeTab.getSupplier());
        // 创建时间
        virtualStockRecord.setOperateDate(inboundNoticeTab.getOperateDate());
        // 上报时间
        virtualStockRecord.setReportTime(DateUtils.getDate());
        // 申请单号 设置为来源单号 发货单号 TODO
        virtualStockRecord.setLotId(inboundNotice.getPurchaseId());
        // 申请人
        virtualStockRecord.setApplicant(inboundNotice.getApplicant());
        // 计划日期
        virtualStockRecord.setPlanDate(inboundNoticeTab.getPlanDate());
        // 计划期间
        virtualStockRecord.setPlanTime(inboundNoticeTab.getPlanTime());
        // 需求周期
        virtualStockRecord.setNeedCycle(inboundNoticeTab.getNeedCycle());
        // 需求类型
        virtualStockRecord.setNeedType(inboundNoticeTab.getNeedType());
        // 物料编码
        virtualStockRecord.setGoodsId(inboundNoticeTab.getGoodsId());
        // 物料分类
        virtualStockRecord.setGoodsTypeId(inboundNoticeTab.getGoodsTypeId());
        // 品牌
        virtualStockRecord.setBrand(inboundNoticeTab.getBrand());
        // 计划单价（含税）
        virtualStockRecord.setPrice(inboundNoticeTab.getPrice() != null ? inboundNoticeTab.getPrice().toString() : null);
        // 计划金额
        virtualStockRecord.setTotalMoney(inboundNoticeTab.getTotalMoney());
        // 需求时间
        virtualStockRecord.setExpiryDate(inboundNoticeTab.getExpiryDate());
        // 建议供应商名称 TODO
        virtualStockRecord.setProviderName(inboundNotice.getProviderName());
        // 收货人
        virtualStockRecord.setReceiver(inboundNotice.getReceiver());
        // 需求部门
        virtualStockRecord.setNeedDept(inboundNoticeTab.getNeedDept());
        // 采购组织
        virtualStockRecord.setPurchaseDept(inboundNotice.getPurchaseDept());
        // 收货组织
        virtualStockRecord.setProduclotId(inboundNotice.getProduclotId());
        // 收货人部门
        virtualStockRecord.setReceiverDept(inboundNotice.getReceiverDept());
        // 送货区域
        virtualStockRecord.setReceivingArea(inboundNotice.getReceivingArea());
        // 技术需求附件
        virtualStockRecord.setPackageId(inboundNoticeTab.getPackageId());
        // 物资计划明细备注
        virtualStockRecord.setRemark(inboundNoticeTab.getRemark());
        // 用途
        virtualStockRecord.setUseType(inboundNoticeTab.getUseType());
        // 中标供应商联系方式
        virtualStockRecord.setTelephone(inboundNotice.getTelephone());
        // wms订单号 入库通知单号
        virtualStockRecord.setNoticeId(inboundNotice.getNoticeId());
        // 生产日期
        virtualStockRecord.setProductionDate(inboundNoticeTab.getProductionDate());
        // 入库类型
        virtualStockRecord.setStorageMode(shelfConfirmRequest.getStorageMode());
        // 仓库编号
        virtualStockRecord.setStorageId(inboundNoticeTab.getStorageId());
        virtualStockRecord.setStorageShortName(inboundNoticeTab.getStorageShortName());
        // 库位
        virtualStockRecord.setLocationId(inboundNoticeTab.getStorageLocation());
        // 增加外部批次号
        virtualStockRecord.setBatchNo(inboundNoticeTab.getBatchNo());
        // 条码
        virtualStockRecord.setBarcode(inboundNoticeTab.getBarcode());
        // 入库级别
        virtualStockRecord.setLevelType(inboundNoticeTab.getLevelType());

        // 标准超期呆滞
        virtualStockRecord.setStandard(shelfConfirmRequest.getExtras().get("extraTime"));

        // 托盘
        virtualStockRecord.setCtl(shelfConfirmRequest.getCtlNo());

        virtualStockRecord.setCreateBy(shelfConfirmRequest.getUserName());
        virtualStockRecord.setCreateTime(new Date());
        virtualStockRecord.setRecordPerson(shelfConfirmRequest.getRecordPerson());

        // 入库时间
        DateFormat wareDateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        virtualStockRecord.setWareDate(wareDateFormatter.format(new Date()));

        virtualStockRecord.setDeptId(shelfConfirmRequest.getDeptId());

        virtualStockRecord.setNoticeTabId(inboundNoticeTab.getId());

        return virtualStockRecord;
    }

    /**
     * 删除入库通知单明细
     */
    @Transactional
    @Override
    public Map<String, String> deleteTRkWareNoticeTabByIds(String[] ids) {

        Map<String, String> resultMap = new HashMap<>();

        // 查询是否存在部分收货
        int num = tRkWareNoticeMapper.selectTRkWareNoticeTabByIds(ids);

        if (num != ids.length) {
            resultMap.put("error", "存在部分收货或全部收货的明细数据，不能删除");
            return resultMap;
        }

        tRkWareNoticeMapper.deleteTRkWareNoticeTabByIds(ids);

        resultMap.put("success", "删除成功");
        resultMap.put("error", "");

        return resultMap;
    }

    /**
     * 保存通知单明细
     */
    @Override
    @Transactional
    public Map<String, String> saveNoticeTab(TRkWareNoticeTabUpdate saveRequest) {
        // 返回结果
        Map<String, String> resultMap = new HashMap<>();

        // 查询入库通知单明细
        TRkWareNotice inboundNotice = tRkWareNoticeMapper.selectTRkWareNoticeById(saveRequest.getId());

        if (inboundNotice == null) {
            resultMap.put("error", "入库通知单不存在");
            return resultMap;
        }

        if (InboundNoticeReceivingStatus.COMPLETED.getCode().equals(inboundNotice.getReceivingStatus())) {
            resultMap.put("error", "入库通知单已全部收货，请刷新");
            return resultMap;
        }

        // 通知单明细map
        Map<String, TRkWareNoticeTab> existingNoticeTabById = new HashMap<String, TRkWareNoticeTab>();
        for (int i = 0; i < inboundNotice.getTRkWareNoticeTabList().size(); i++) {
            TRkWareNoticeTab noticeTab = inboundNotice.getTRkWareNoticeTabList().get(i);
            existingNoticeTabById.put(noticeTab.getId(), noticeTab);
        }

        List<TRkWareNoticeTab> noticeTabsToInsert = new ArrayList<TRkWareNoticeTab>();

        // 遍历提交的通知单明细数据
        for (TRkWareNoticeTab noticeTabToInsert : saveRequest.getTrkWareNoticeTabList()) {

            if (StringUtils.isNotBlank(noticeTabToInsert.getId()) && existingNoticeTabById.containsKey(noticeTabToInsert.getId())) {
                throw new RuntimeException(
                        "通知单明细ID【" + noticeTabToInsert.getId() + "】已存在. ");
            }

            if (ObjectUtils.isEmpty(noticeTabToInsert.getGoodsId())) {
                resultMap.put("error", "物料编码不能为空");
                return resultMap;
            }

            if (ObjectUtils.isEmpty(noticeTabToInsert.getGoodsName())) {
                resultMap.put("error", "物料名称不能为空");
                return resultMap;
            }

            BigDecimal plannedReceivingQuantity = noticeTabToInsert.getReceivingNum() == null ? BigDecimal.ZERO : noticeTabToInsert.getReceivingNum();
            BigDecimal arrivedQuantity = noticeTabToInsert.getArraMount() == null ? BigDecimal.ZERO : noticeTabToInsert.getArraMount();

            // if (recNumNowNew.compareTo(BigDecimal.ZERO) > 0
            // || recNumNew.compareTo(BigDecimal.ZERO) > 0) {
            // resultMap.put("error", "物料【" + noticeTabToInsert.getGoodsName() + "】的签收数量不为0");
            // return resultMap;
            // }

            if (plannedReceivingQuantity.compareTo(BigDecimal.ZERO) <= 0) {
                resultMap.put("error", "物料【" + noticeTabToInsert.getGoodsName() + "】的签收数量必须大于0");
                return resultMap;
            }

            if (arrivedQuantity.compareTo(BigDecimal.ZERO) <= 0) {
                resultMap.put("error", "物料【" + noticeTabToInsert.getGoodsName() + "】的到货数量必须大于0");
                return resultMap;
            }
            if (plannedReceivingQuantity.compareTo(arrivedQuantity) > 0) {
                resultMap.put("error", "物料【" + noticeTabToInsert.getGoodsName() + "】签收数量不能大于到货数量");
                return resultMap;
            }

            if (plannedReceivingQuantity.compareTo(arrivedQuantity) < 0) {
                //拒绝数量
                noticeTabToInsert.setRejectNum(arrivedQuantity.subtract(plannedReceivingQuantity));
            }

            /** 在途 */
            noticeTabToInsert.setReceivingStatus(InboundNoticeTabReceivingStatus.PENDING.getCode());
            noticeTabToInsert.setNoticeId(inboundNotice.getId());
            noticeTabToInsert.setId(OrderCodeFactory.getOrderCode("TRKTAB", ""));

            // 托盘
            // noticeTabToInsert.setCtl(saveRequest.getCtlNo());

            noticeTabToInsert.setCreateBy(SecurityUtils.getUserNick());
            noticeTabToInsert.setCreateTime(new Date());
            noticeTabToInsert.setUpdateBy(SecurityUtils.getUserNick());
            noticeTabToInsert.setUpdateTime(new Date());
            // 二级库
            noticeTabToInsert.setLevelType(InboundLevelType.LEVEL_TWO.getCode());

            noticeTabToInsert.setSourceNum(inboundNotice.getDeliveryId());
            noticeTabToInsert.setDeliveryId(inboundNotice.getDeliveryId());

            noticeTabsToInsert.add(noticeTabToInsert);
        }

        if (noticeTabsToInsert.size() > 0) {
            // 入库通知单明细批量插入
            tRkWareNoticeMapper.batchTRkWareNoticeTab(noticeTabsToInsert);
        }

        resultMap.put("success", "保存成功");
        resultMap.put("error", "");

        return resultMap;
    }

    /**
     * 手动完成通知单明细
     */
    @Override
    @Transactional
    public Map<String, String> manualCompletion(TRkWareNoticeTabUpdate completionRequest) {
        // 返回结果
        Map<String, String> resultMap = new HashMap<>();

        List<TRkWareNoticeTab> completedNoticeTabs = new ArrayList<>();
        for (TRkWareNoticeTab submittedNoticeTab : completionRequest.getTrkWareNoticeTabList()) {
            TRkWareNoticeTab noticeTabToComplete = tRkWareNoticeMapper.selectTRkWareNoticeTabById(submittedNoticeTab.getId());
            /** 查询是否存在未完成的入库任务 */
            TOngoodsshelf pendingInboundTaskQuery = new TOngoodsshelf();
            pendingInboundTaskQuery.setNoticeTabId(noticeTabToComplete.getId());
            pendingInboundTaskQuery.setInStatus(InboundOngoodsshelfInStatus.PLC_ASSIGNED.getCode());
            List<TOngoodsshelf> pendingInboundTasks = tOngoodsshelfMapper.selectTOngoodsshelfList(pendingInboundTaskQuery);

            if (pendingInboundTasks.size() > 0) {
                resultMap.put("error", "通知单明细[" + noticeTabToComplete.getId() + "]存在未完成的任务，不能删除");
                return resultMap;
            }

            // 人工设置为全部收货
            noticeTabToComplete.setReceivingStatus(InboundNoticeTabReceivingStatus.COMPLETED.getCode());
            noticeTabToComplete.setUpdateTime(new Date());
            noticeTabToComplete.setUpdateBy(completionRequest.getUserName());

            completedNoticeTabs.add(noticeTabToComplete);

            tRkWareNoticeTabMapper.updateTRkWareNoticeTab(noticeTabToComplete);
        }

        /** 设置通知单明细为完成状态 */
//        if (completedNoticeTabs.size() > 0) {
//            tRkWareNoticeMapper.updateForeach(completedNoticeTabs);
//        }

        // 查询入库通知单明细
        TRkWareNotice inboundNotice = tRkWareNoticeMapper.selectTRkWareNoticeById(completionRequest.getId());

        if (inboundNotice == null) {
            resultMap.put("error", "入库通知单不存在");
            return resultMap;
        }

        boolean allNoticeTabsCompleted = true;
        for (TRkWareNoticeTab noticeTab : inboundNotice.getTRkWareNoticeTabList()) {
            if (InboundNoticeTabReceivingStatus.COMPLETED.getCode().equals(noticeTab.getReceivingStatus())) {
                allNoticeTabsCompleted = false;
                break;
            }
        }

        // 更细入库通知单状态
        if (allNoticeTabsCompleted) {
            // 2:全部收货
            inboundNotice.setReceivingStatus(InboundNoticeReceivingStatus.COMPLETED.getCode());
            inboundNotice.setUpdateBy(completionRequest.getUserName());
            inboundNotice.setUpdateTime(new Date());
            tRkWareNoticeMapper.updateTRkWareNotice(inboundNotice);
        }

        // 查询存货表数据
        TRkReceivingGoods receivingGoods = tRkReceivingGoodsMapper
                .selectTRkReceivingGoodsByNoticeId(inboundNotice.getNoticeId());

        String receivingGoodsId = OrderCodeFactory.getOrderCode("R", "");
        if (receivingGoods != null) {
            receivingGoods.setReceivingStatus(inboundNotice.getReceivingStatus());
            receivingGoods.setUpdateBy(completionRequest.getUserName());
            receivingGoods.setUpdateTime(new Date());
            tRkReceivingGoodsMapper.updateTRkReceivingGoods(receivingGoods);

            receivingGoodsId = receivingGoods.getId();
        } else {
            TRkReceivingGoods receivingGoodsToInsert = new TRkReceivingGoods();
            BeanUtils.copyProperties(inboundNotice, receivingGoodsToInsert);
            receivingGoodsToInsert.setId(receivingGoodsId);
            receivingGoodsToInsert.setUpdateBy(completionRequest.getUserName());
            receivingGoodsToInsert.setUpdateTime(new Date());
            receivingGoodsToInsert.setCreateBy(completionRequest.getUserName());
            receivingGoodsToInsert.setCreateTime(new Date());
            tRkReceivingGoodsMapper.insertTRkReceivingGoods(receivingGoodsToInsert);
        }

        // 查询是否存在收货表数据
        if (inboundNotice.getTRkWareNoticeTabList().size() > 0) {

            Map<String, TRkReceivingGoodsTab> receivingGoodsTabById = new HashMap<String, TRkReceivingGoodsTab>();

            if (receivingGoods != null) {

                for (TRkReceivingGoodsTab receivingGoodsTab : receivingGoods.getTRkReceivingGoodsTabList()) {
                    receivingGoodsTabById.put(receivingGoodsTab.getId(), receivingGoodsTab);
                }
            }
            List<TRkReceivingGoodsTab> receivingGoodsTabsToInsert = new ArrayList<>();
            // 存货表更新集合
            List<TRkReceivingGoodsTab> receivingGoodsTabsToUpdate = new ArrayList<TRkReceivingGoodsTab>();

            for (TRkWareNoticeTab noticeTab : inboundNotice.getTRkWareNoticeTabList()) {
                TRkReceivingGoodsTab receivingGoodsTabToUpdate = receivingGoodsTabById.get(noticeTab.getId());
                if (receivingGoodsTabToUpdate != null) {
                    receivingGoodsTabToUpdate.setRecNum(noticeTab.getRecNum());
                    receivingGoodsTabToUpdate.setReceivingStatus(noticeTab.getReceivingStatus());
                    receivingGoodsTabToUpdate.setUpdateBy(completionRequest.getUserName());
                    receivingGoodsTabToUpdate.setUpdateTime(new Date());
                    receivingGoodsTabsToUpdate.add(receivingGoodsTabToUpdate);
                } else {
                    TRkReceivingGoodsTab receivingGoodsTabToInsert = new TRkReceivingGoodsTab();
                    BeanUtils.copyProperties(noticeTab, receivingGoodsTabToInsert);
                    receivingGoodsTabToInsert.setNoticeId(receivingGoodsId);
//                    receivingGoodsTabToInsert.setId(OrderCodeFactory.getOrderCode("RTAB", ""));
                    receivingGoodsTabsToInsert.add(receivingGoodsTabToInsert);
                }
            }

            if (receivingGoodsTabsToUpdate.size() > 0) {
                // 批量更新存货明细表
                tRkReceivingGoodsMapper.updateForeach(receivingGoodsTabsToUpdate);
            }

            if (receivingGoodsTabsToInsert.size() > 0) {
                tRkReceivingGoodsMapper.batchTRkReceivingGoodsTab(receivingGoodsTabsToInsert);
            }
        }

        // 入库通知单及明细数据 移到 bak表
        if (allNoticeTabsCompleted) {
            // 查询入库通知单明细
            inboundNotice = tRkWareNoticeMapper.selectTRkWareNoticeByNoticeId(completionRequest.getNoticeId());
            TRkWareNoticeBak inboundNoticeBakRecord = new TRkWareNoticeBak();
            BeanUtils.copyProperties(inboundNotice, inboundNoticeBakRecord);
//            String inboundNoticeBakId = OrderCodeFactory.getOrderCode("TRKBAK", "");
//            inboundNoticeBakRecord.setId(inboundNoticeBakId);
            tRkWareNoticeBakMapper.insertTRkWareNoticeBak(inboundNoticeBakRecord);

            List<TRkWareNoticeTabBak> inboundNoticeTabBakRecords = new ArrayList<TRkWareNoticeTabBak>();
            for (TRkWareNoticeTab inboundNoticeTab : inboundNotice.getTRkWareNoticeTabList()) {
                TRkWareNoticeTabBak inboundNoticeTabBakRecord = new TRkWareNoticeTabBak();
//                inboundNoticeTab.setId(OrderCodeFactory.getOrderCode("TRKTABBAK", ""));
//                inboundNoticeTab.setNoticeId(inboundNoticeBakId);
                BeanUtils.copyProperties(inboundNoticeTab, inboundNoticeTabBakRecord);
                inboundNoticeTabBakRecord.setPurchaser(inboundNotice.getPurchaser());
                inboundNoticeTabBakRecord.setSendeDate(inboundNotice.getSendeDate());
                inboundNoticeTabBakRecord.setProviderName(inboundNotice.getProviderName());
                inboundNoticeTabBakRecord.setRecPerson(inboundNotice.getRecPerson());
                inboundNoticeTabBakRecords.add(inboundNoticeTabBakRecord);
            }
            if (inboundNoticeTabBakRecords.size() > 0) {
                tRkWareNoticeBakMapper.batchTRkWareNoticeTabBak(inboundNoticeTabBakRecords);
            }

            // 删除入库通知单和明细
            tRkWareNoticeMapper.deleteTRkWareNoticeById(inboundNotice.getId());
            tRkWareNoticeMapper.deleteNoticeTabByNoticeId(inboundNotice.getId());
        }

        resultMap.put("success", "通知单明细已人工完成");
        resultMap.put("error", "");

        return resultMap;
    }

    /**
     * 入库任务上架确认
     */
    @Override
    @Transactional
    // 入库流程
    public Map<String, String> shelvesConfirm(TRkWareNoticeTabUpdate shelfConfirmRequest) {
        // 返回结果
        Map<String, String> resultMap = new HashMap<>();
        // 库位
        if (ObjectUtils.isEmpty(shelfConfirmRequest.getStorageLocation())) {
            resultMap.put("error", "库位不能为空");
            return resultMap;
        }

        LambdaQueryWrapper<TBaseStorageAreaLocation> storageLocationQueryWrapper = new LambdaQueryWrapper<>();
        storageLocationQueryWrapper.eq(TBaseStorageAreaLocation::getLocationId, shelfConfirmRequest.getStorageLocation());
        List<TBaseStorageAreaLocation> storageLocationMatches = tBaseStorageAreaLocationMapper.selectList(storageLocationQueryWrapper);
        if (storageLocationMatches.isEmpty()) {
            throw new RuntimeException("库位号错误");
        }

        TBaseStorageAreaLocation targetStorageLocation = storageLocationMatches.get(0);
        if (InboundResourceLockStatus.LOCKED.getCode().equals(targetStorageLocation.getIsLock())) {
            resultMap.put("error", "库位【" + shelfConfirmRequest.getStorageLocation() + "】已禁用");
            log.error("库位【" + shelfConfirmRequest.getStorageLocation() + "】已禁用");
            throw new RuntimeException("库位【" + shelfConfirmRequest.getStorageLocation() + "】已禁用");
        }

        if (InboundResourceOccupancyStatus.EMPTY.getCode().equals(targetStorageLocation.getStatus())
                || StringUtils.isBlank(targetStorageLocation.getStatus())) {
            TBaseStorageAreaLocation storageLocationOccupancyUpdate = new TBaseStorageAreaLocation();
            storageLocationOccupancyUpdate.setStatus(InboundResourceOccupancyStatus.OCCUPIED.getCode());
            storageLocationOccupancyUpdate.setId(targetStorageLocation.getId());
            storageLocationOccupancyUpdate.setUpdateBy(shelfConfirmRequest.getUserName());
            storageLocationOccupancyUpdate.setUpdateTime(new Date());
            tBaseStorageAreaLocationMapper.updateTBaseStorageAreaLocation(storageLocationOccupancyUpdate);
        }


        if (StringUtils.isNotBlank(shelfConfirmRequest.getCtlNo())) {
            //校验托盘容器是否正确
            LambdaQueryWrapper<TBasePallet> palletQueryWrapper = new LambdaQueryWrapper<>();
            palletQueryWrapper.eq(TBasePallet::getPalletId, shelfConfirmRequest.getCtlNo());
            List<TBasePallet> palletMatches = palletMapper.selectList(palletQueryWrapper);
            if (!palletMatches.isEmpty()) {
                TBasePallet targetPallet = palletMatches.get(0);
                if (InboundResourceLockStatus.LOCKED.getCode().equals(targetPallet.getIsLock())) {
                    resultMap.put("error", "托盘号【" + shelfConfirmRequest.getCtlNo() + "】已禁用");
                    log.error("托盘号【" + shelfConfirmRequest.getCtlNo() + "】已禁用");
                    throw new RuntimeException("托盘号【" + shelfConfirmRequest.getCtlNo() + "】已禁用");
                }

                if (InboundResourceOccupancyStatus.EMPTY.getCode().equals(targetPallet.getStatus())
                        || StringUtils.isBlank(targetPallet.getStatus())) {
                    TBasePallet palletOccupancyUpdate = new TBasePallet();
                    palletOccupancyUpdate.setStatus(InboundResourceOccupancyStatus.OCCUPIED.getCode());
                    palletOccupancyUpdate.setId(targetPallet.getId());
                    palletOccupancyUpdate.setUpdateBy(shelfConfirmRequest.getUserName());
                    palletOccupancyUpdate.setUpdateTime(new Date());
                    palletMapper.updateTBasePallet(palletOccupancyUpdate);
                }
            }
        }

        // 校验同一库位是否占用
        TMiStock stockDupOccupyQuery = new TMiStock();
        stockDupOccupyQuery.setLocationId(shelfConfirmRequest.getStorageLocation());
        List<TMiStock> stockDupOccupyList = tMiStockMapper.selectTMiStockList(stockDupOccupyQuery);
        if (stockDupOccupyList != null && !stockDupOccupyList.isEmpty()) {
            resultMap.put("error", "库位【" + shelfConfirmRequest.getCtlNo() + "】已占用，请更换");
            return resultMap;
        }

        // 超期呆滞时间获取
        SysConfig overdueStagnationConfigQuery = new SysConfig();
        overdueStagnationConfigQuery.setConfigKey("overdue.stagnation");
        List<SysConfig> overdueStagnationConfigList = sysConfigMapper.selectConfigList(overdueStagnationConfigQuery);

        if (!overdueStagnationConfigList.isEmpty()) {
            shelfConfirmRequest.getExtras().put("extraTime", overdueStagnationConfigList.get(0).getConfigValue());
        } else {
            shelfConfirmRequest.getExtras().put("extraTime", "");
        }


        List<TRkWareNoticeTab> updatedNoticeTabs = new ArrayList<>();
        List<TMiStock> realStockRecordsToInsert = new ArrayList<>();
        List<TMiStockF> virtualStockRecordsToInsert = new ArrayList<>();

        // 判断通知单明细是否存在为完成的
        boolean allNoticeTabsCompleted = true;

        String inboundNoticeId = "";
        TRkWareNotice inboundNotice = null;

        String callNoticeId = "";

        // 遍历提交的入库任务列表
        for (TOngoodsshelf submittedInboundTask : shelfConfirmRequest.getTOngoodsshelfList()) {
            TOngoodsshelf storedInboundTask = tOngoodsshelfMapper.selectTOngoodsshelfById(submittedInboundTask.getId());
            if (storedInboundTask == null) {
                resultMap.put("error", "入库任务不存在，请刷新后重试");
                return resultMap;
            }

            // 备份呼叫任务号
            callNoticeId = storedInboundTask.getCallNoticeId();
            if (StringUtils.isBlank(callNoticeId)) {
                callNoticeId = submittedInboundTask.getCallNoticeId();
            }

            if (StringUtils.isBlank(inboundNoticeId)) {

                inboundNoticeId = storedInboundTask.getAcceId();
                if (StringUtils.isBlank(inboundNoticeId)) {
                    inboundNoticeId = submittedInboundTask.getAcceId();
                }

                // 查询入库通知单
                inboundNotice = tRkWareNoticeMapper.selectTRkWareNoticeByNoticeId(inboundNoticeId);

                if (inboundNotice == null) {
                    resultMap.put("error", "入库通知单不存在");
                    return resultMap;
                }

                if (InboundNoticeReceivingStatus.COMPLETED.getCode().equals(inboundNotice.getReceivingStatus())) {
                    resultMap.put("error", "入库通知单已全部收货，请刷新");
                    return resultMap;
                }
            }
            // 根据ID查询入库通知单明细数据
            TRkWareNoticeTab noticeTabToUpdate = tRkWareNoticeMapper.selectTRkWareNoticeTabById(storedInboundTask.getNoticeTabId());

            if (noticeTabToUpdate == null) {
                resultMap.put("error", "物料的通知单明细不存在");
                return resultMap;
            }

            if (InboundNoticeTabReceivingStatus.COMPLETED.getCode().equals(noticeTabToUpdate.getReceivingStatus())) {
                continue;
            }

            // 累计收货数量
            BigDecimal receivedQuantity = noticeTabToUpdate.getRecNum() == null ? BigDecimal.ZERO : noticeTabToUpdate.getRecNum();
            //累计入库数量
            BigDecimal accumulatedShelvedQuantity = noticeTabToUpdate.getAcceNum() == null ? BigDecimal.ZERO : noticeTabToUpdate.getAcceNum();
            // 本次上架数量
            BigDecimal currentShelvedQuantity = submittedInboundTask.getAccNum() == null
                    ? (storedInboundTask.getAccNum() == null ? BigDecimal.ZERO : storedInboundTask.getAccNum())
                    : submittedInboundTask.getAccNum();

            if (currentShelvedQuantity.compareTo(BigDecimal.ZERO) == 0) {
                resultMap.put("error", "物料【" + noticeTabToUpdate.getGoodsName() + "】的上架数量不能为0");
                return resultMap;
            }

            // 收货状态：全部收货
            String updatedReceivingStatus = InboundNoticeTabReceivingStatus.COMPLETED.getCode();

            BigDecimal totalShelvedQuantity = currentShelvedQuantity.add(accumulatedShelvedQuantity);

            if (totalShelvedQuantity.compareTo(receivedQuantity) < 0) {
                /** 部分收货 */
                updatedReceivingStatus = InboundNoticeTabReceivingStatus.PARTIAL.getCode();
            }

            // 设置更新信息
            noticeTabToUpdate.setReceivingStatus(updatedReceivingStatus);
            // 本次上架数量
            noticeTabToUpdate.setAmount(currentShelvedQuantity);
            // 累计上架数量
            noticeTabToUpdate.setAcceNum(totalShelvedQuantity);
            // 托盘
            noticeTabToUpdate.setCtl(shelfConfirmRequest.getCtlNo());

            noticeTabToUpdate.setUpdateBy(shelfConfirmRequest.getUserName());
            noticeTabToUpdate.setUpdateTime(new Date());

            // 仓库信息
            noticeTabToUpdate.setStorageId(submittedInboundTask.getStorageId());
            noticeTabToUpdate.setStorageLocation(shelfConfirmRequest.getStorageLocation());
            noticeTabToUpdate.setApplicant(shelfConfirmRequest.getUserName());
            //更新明细
            tRkWareNoticeTabMapper.updateTRkWareNoticeTab(noticeTabToUpdate);
            updatedNoticeTabs.add(noticeTabToUpdate);

            storedInboundTask.setStatus(InboundTaskStatus.CONFIRMED.getCode());
            storedInboundTask.setAccNum(currentShelvedQuantity);
            // 库位
            storedInboundTask.setLocationId(shelfConfirmRequest.getStorageLocation());
            // 托盘号
            storedInboundTask.setCtl(shelfConfirmRequest.getCtlNo());

            // 入库时间
            storedInboundTask.setOndate(DateUtils.getTime());
            storedInboundTask.setUpdateBy(shelfConfirmRequest.getUserName());
            storedInboundTask.setUpdateTime(new Date());

            // 生成入库任务bak数据
            TOngoodsshelfBak inboundTaskArchive = new TOngoodsshelfBak();
            BeanUtils.copyProperties(storedInboundTask, inboundTaskArchive);
//            inboundTaskArchive.setId(OrderCodeFactory.getOrderCode("TSB", ""));
            tOngoodsshelfBakMapper.insertTOngoodsshelfBak(inboundTaskArchive);

            // 生成库存信息
            if (InboundFictitiousFlag.REAL.getCode().equals(shelfConfirmRequest.getFictitious())) {
                realStockRecordsToInsert.add(buildRealStockRecord(inboundNotice, noticeTabToUpdate, shelfConfirmRequest, storedInboundTask));
            } else {
                virtualStockRecordsToInsert.add(buildVirtualStockRecord(inboundNotice, noticeTabToUpdate, shelfConfirmRequest));
            }

            // 删除入库任务
            tOngoodsshelfMapper.deleteTOngoodsshelfById(storedInboundTask.getId());
        }

        if (!StringUtils.isEmpty(callNoticeId)) {
            TOngoodsshelf remainingTaskQuery = new TOngoodsshelf();
            remainingTaskQuery.setCallNoticeId(callNoticeId);
            List<TOngoodsshelf> remainingInboundTasks = tOngoodsshelfMapper.selectTOngoodsshelfList(remainingTaskQuery);

            if (remainingInboundTasks.isEmpty()) {
                // 关闭入库任务通知
                TCallNotice callNoticeUpdate = new TCallNotice();
                callNoticeUpdate.setId(callNoticeId);
                callNoticeUpdate.setTaskType(InboundTaskType.INBOUND.getCode());
                callNoticeUpdate.setUpdateBy(shelfConfirmRequest.getUserName());
                callNoticeUpdate.setUpdateTime(new Date());
                tNoticeService.updateTaskStatus(callNoticeUpdate);
            }
        }

        if (InboundFictitiousFlag.REAL.getCode().equals(shelfConfirmRequest.getFictitious())) {
            // 更新库存信息
            if (realStockRecordsToInsert.size() > 0) {
                for (TMiStock realStockRecord : realStockRecordsToInsert) {
                    String goodsId = realStockRecord.getGoodsId();
                    LambdaQueryWrapper<TBaseGoods> goodsQueryWrapper = new LambdaQueryWrapper<>();
                    goodsQueryWrapper.eq(TBaseGoods::getGoodsId, goodsId);
                    TBaseGoods baseGoods = tBaseGoodsMapper.selectOne(goodsQueryWrapper);
                    //原来仓库
                    if (baseGoods == null) {
                        throw new RuntimeException("物料ID:" + goodsId + "在基础物料没维护，请先维护！");
                    }
                    realStockRecord.setOriginal(baseGoods.getStorageId());
                    realStockRecord.setPrice(String.valueOf(baseGoods.getPrice()));

                    //总价
                    BigDecimal shelvedQuantity = realStockRecord.getShelvesNum();
                    BigDecimal unitPrice = baseGoods.getPrice();
                    if (unitPrice == null || unitPrice.compareTo(BigDecimal.ZERO) == 0) {
                        unitPrice = BigDecimal.ONE; // 默认值为 1
                    }

                    if (shelvedQuantity.compareTo(BigDecimal.ZERO) == 0) {
                        throw new RuntimeException("入库数量为0异常");
                    }

                    BigDecimal totalPrice = unitPrice.multiply(shelvedQuantity);
                    realStockRecord.setTotalMoney(totalPrice);
                    realStockRecord.setPrice(String.valueOf(unitPrice));
                    tMiStockMapper.insertTMiStock(realStockRecord);
                }
            }
        } else {
            // 更新虚拟库存信息
            if (virtualStockRecordsToInsert.size() > 0) {
                for (TMiStockF virtualStockRecord : virtualStockRecordsToInsert) {
                    tMiStockFMapper.insertTMiStock(virtualStockRecord);
                }
            }
        }

        // 获取最新的通知单信息，判断是否全部完成
        inboundNotice = tRkWareNoticeMapper.selectTRkWareNoticeByNoticeId(inboundNoticeId);
        for (TRkWareNoticeTab noticeTab : inboundNotice.getTRkWareNoticeTabList()) {
            if (!InboundNoticeTabReceivingStatus.COMPLETED.getCode().equals(noticeTab.getReceivingStatus())) {
                allNoticeTabsCompleted = false;
                break;
            }
        }

        // 更细入库通知单状态
        if (allNoticeTabsCompleted) {
            // 2:全部收货
            inboundNotice.setReceivingStatus(InboundNoticeReceivingStatus.COMPLETED.getCode());
            inboundNotice.setUpdateBy(shelfConfirmRequest.getUserName());
            inboundNotice.setUpdateTime(new Date());
            tRkWareNoticeMapper.updateTRkWareNotice(inboundNotice);
        }

        // 查询存货表数据
        TRkReceivingGoods receivingGoods = tRkReceivingGoodsMapper
                .selectTRkReceivingGoodsByNoticeId(inboundNotice.getNoticeId());

        String receivingGoodsId = OrderCodeFactory.getOrderCode("R", "");
        if (receivingGoods != null) {
            receivingGoods.setReceivingStatus(inboundNotice.getReceivingStatus());
            receivingGoods.setUpdateBy(shelfConfirmRequest.getUserName());
            receivingGoods.setUpdateTime(new Date());
            tRkReceivingGoodsMapper.updateTRkReceivingGoods(receivingGoods);

            receivingGoodsId = receivingGoods.getId();
        } else {
            TRkReceivingGoods receivingGoodsToInsert = new TRkReceivingGoods();
            BeanUtils.copyProperties(inboundNotice, receivingGoodsToInsert);
            receivingGoodsToInsert.setId(receivingGoodsId);
            receivingGoodsToInsert.setUpdateBy(shelfConfirmRequest.getUserName());
            receivingGoodsToInsert.setUpdateTime(new Date());
            receivingGoodsToInsert.setCreateBy(shelfConfirmRequest.getUserName());
            receivingGoodsToInsert.setCreateTime(new Date());
            tRkReceivingGoodsMapper.insertTRkReceivingGoods(receivingGoodsToInsert);
        }

        // 查询是否存在收货表数据
        if (!updatedNoticeTabs.isEmpty()) {

            Map<String, TRkReceivingGoodsTab> receivingGoodsTabById = new HashMap<>();

            if (receivingGoods != null) {
                for (TRkReceivingGoodsTab receivingGoodsTab : receivingGoods.getTRkReceivingGoodsTabList()) {
                    receivingGoodsTabById.put(receivingGoodsTab.getId(), receivingGoodsTab);
                }
            }

            List<TRkReceivingGoodsTab> receivingGoodsTabsToInsert = new ArrayList<>();
            // 存货表更新集合
            List<TRkReceivingGoodsTab> receivingGoodsTabsToUpdate = new ArrayList<>();

            for (TRkWareNoticeTab updatedNoticeTab : updatedNoticeTabs) {
                TRkReceivingGoodsTab receivingGoodsTabToUpdate = receivingGoodsTabById.get(updatedNoticeTab.getId());
                if (receivingGoodsTabToUpdate != null) {
                    receivingGoodsTabToUpdate.setRecNum(updatedNoticeTab.getRecNum());
                    receivingGoodsTabToUpdate.setReceivingStatus(updatedNoticeTab.getReceivingStatus());
                    receivingGoodsTabToUpdate.setUpdateBy(shelfConfirmRequest.getUserName());
                    receivingGoodsTabToUpdate.setUpdateTime(new Date());
                    receivingGoodsTabsToUpdate.add(receivingGoodsTabToUpdate);
                } else {
                    TRkReceivingGoodsTab receivingGoodsTabToInsert = new TRkReceivingGoodsTab();
                    BeanUtils.copyProperties(updatedNoticeTab, receivingGoodsTabToInsert);
                    receivingGoodsTabToInsert.setNoticeId(receivingGoodsId);
//                    receivingGoodsTabToInsert.setId(OrderCodeFactory.getOrderCode("RTAB", ""));
                    receivingGoodsTabsToInsert.add(receivingGoodsTabToInsert);
                }
            }

            if (receivingGoodsTabsToUpdate.size() > 0) {
                // 批量更新存货明细表
                tRkReceivingGoodsMapper.updateForeach(receivingGoodsTabsToUpdate);
            }

            if (receivingGoodsTabsToInsert.size() > 0) {
                tRkReceivingGoodsMapper.batchTRkReceivingGoodsTab(receivingGoodsTabsToInsert);
            }
        }

        // 入库通知单及明细数据 移到 bak表
        if (allNoticeTabsCompleted) {
            // 查询入库通知单明细
            inboundNotice = tRkWareNoticeMapper.selectTRkWareNoticeByNoticeId(inboundNotice.getNoticeId());
            TRkWareNoticeBak inboundNoticeBakRecord = new TRkWareNoticeBak();
            BeanUtils.copyProperties(inboundNotice, inboundNoticeBakRecord);
//            String inboundNoticeBakId = OrderCodeFactory.getOrderCode("TRKBAK", "");
//            inboundNoticeBakRecord.setId(inboundNoticeBakId);
            tRkWareNoticeBakMapper.insertTRkWareNoticeBak(inboundNoticeBakRecord);

            List<TRkWareNoticeTabBak> inboundNoticeTabBakRecords = new ArrayList<>();
            for (TRkWareNoticeTab inboundNoticeTab : inboundNotice.getTRkWareNoticeTabList()) {
                TRkWareNoticeTabBak inboundNoticeTabBakRecord = new TRkWareNoticeTabBak();
//                inboundNoticeTab.setId(OrderCodeFactory.getOrderCode("TRKTABBAK", ""));
//                inboundNoticeTab.setNoticeId(inboundNoticeBakId);
                BeanUtils.copyProperties(inboundNoticeTab, inboundNoticeTabBakRecord);
                inboundNoticeTabBakRecord.setPurchaser(inboundNotice.getPurchaser());
                inboundNoticeTabBakRecord.setSendeDate(inboundNotice.getSendeDate());
                inboundNoticeTabBakRecord.setProviderName(inboundNotice.getProviderName());
                inboundNoticeBakRecord.setRecPerson(inboundNotice.getRecPerson());
                inboundNoticeTabBakRecords.add(inboundNoticeTabBakRecord);
            }
            if (inboundNoticeTabBakRecords.size() > 0) {
                tRkWareNoticeBakMapper.batchTRkWareNoticeTabBak(inboundNoticeTabBakRecords);
            }

            // 删除入库通知单和明细
            tRkWareNoticeMapper.deleteTRkWareNoticeById(inboundNotice.getId());
            tRkWareNoticeMapper.deleteNoticeTabByNoticeId(inboundNotice.getId());

            // 关闭入库通知单任务消息
            TCallNoticeOrder callNoticeOrderStatusUpdate = new TCallNoticeOrder();
            callNoticeOrderStatusUpdate.setTaskId(inboundNotice.getId());
            callNoticeOrderStatusUpdate.setTaskType(InboundTaskType.INBOUND.getCode());
            callNoticeOrderStatusUpdate.setUpdateBy(shelfConfirmRequest.getUserName());
            callNoticeOrderStatusUpdate.setUpdateTime(new Date());
            tNoticeOrderService.updateTaskStatus(callNoticeOrderStatusUpdate);
        }

        resultMap.put("success", "上架成功");
        resultMap.put("error", "");

        return resultMap;
    }


    /**
     * 导入入库通知单数据
     *
     * @return 结果
     */
    @Override
    @Transactional
    // 入库流程
    public String importData(List<TRkWareNoticeTab> importedNoticeTabs, boolean isUpdateSupport, String operName) {
        if (StringUtils.isNull(importedNoticeTabs) || importedNoticeTabs.isEmpty()) {
            throw new ServiceException("导入入库通知单数据不能为空！");
        }
        int successCount = 0;
        int failureCount = 0;
        StringBuilder successMessage = new StringBuilder();
        StringBuilder failureMessage = new StringBuilder();
        TRkWareNoticeTab firstImportedNoticeTab = importedNoticeTabs.get(0);
        TRkWareNotice importedNotice = new TRkWareNotice();

        importedNotice.setDeliveryId(firstImportedNoticeTab.getDeliveryId());
        List<TRkWareNotice> duplicateNotices = tRkWareNoticeMapper.selectTRkWareNoticeList(importedNotice);
        if (duplicateNotices.isEmpty()) {
            setTrkNotice(importedNotice, firstImportedNoticeTab, operName);
            importedNotice.setReceivingStatus(InboundNoticeReceivingStatus.CREATED.getCode());
            importedNotice.setStorageMode(InboundStorageMode.STANDARD.getCode());
            tRkWareNoticeMapper.insertTRkWareNotice(importedNotice);

        } else if (isUpdateSupport) {
            List<String> noticeIdsToDelete = duplicateNotices.stream().map(TRkWareNotice::getId).collect(Collectors.toList());
            tRkWareNoticeMapper.deleteTRkWareNoticeByIds(noticeIdsToDelete.toArray(new String[noticeIdsToDelete.size()]));
            setTrkNotice(importedNotice, firstImportedNoticeTab, operName);
            tRkWareNoticeMapper.insertTRkWareNotice(importedNotice);

        } else {
            throw new ServiceException("来源单号 " + firstImportedNoticeTab.getDeliveryId() + " 重复导入异常！");
        }

        for (int importIndex = 0; importIndex < importedNoticeTabs.size(); importIndex++) {
            try {

                //校验必输字段
                TRkWareNoticeTab importedNoticeTab = importedNoticeTabs.get(importIndex);
                validateImportedNoticeTab(importIndex, importedNoticeTab);
                // 验证是否存在该明细
                TRkWareNoticeTab noticeTabQuery = new TRkWareNoticeTab();
                noticeTabQuery.setSalesOrderNumber(importedNoticeTab.getSalesOrderNumber());
                noticeTabQuery.setGoodsId(importedNoticeTab.getGoodsId());
                noticeTabQuery.setReceivingStatus(InboundNoticeTabReceivingStatus.PENDING.getCode());
                noticeTabQuery.setInStatus(InboundNoticeTabInStatus.INITIAL.getCode());
                noticeTabQuery.setDataSource(InboundLevelType.LEVEL_TWO.getDescription());

                importedNoticeTab.setLevelType(InboundLevelType.LEVEL_TWO.getCode());
                importedNoticeTab.setDataSource(InboundLevelType.LEVEL_TWO.getDescription());

                List<TRkWareNoticeTab> duplicateNoticeTabs = tRkWareNoticeTabMapper.selectTRkWareNoticeTabList(noticeTabQuery);

                if (duplicateNoticeTabs.isEmpty()) {
                    initializeNoticeTabForInsert(importedNoticeTab, importedNotice.getId(), operName);
                    importedNoticeTab.setDeliveryId(firstImportedNoticeTab.getDeliveryId());
                    importedNoticeTab.setSourceNum(firstImportedNoticeTab.getDeliveryId());
                    importedNoticeTab.setRecNumNow(null);
                    importedNoticeTab.setRecNum(null);
                    importedNoticeTab.setReceivingNum(importedNoticeTab.getArraMount());
                    tRkWareNoticeTabMapper.insertTRkWareNoticeTab(importedNoticeTab);
                    successCount++;
                    successMessage.append("<br/>" + successCount + "、物料编号 " + importedNoticeTab.getGoodsId() + " 导入成功");
                } else if (isUpdateSupport) {
                    List<String> noticeTabIdsToDelete = duplicateNoticeTabs.stream().map(TRkWareNoticeTab::getId).collect(Collectors.toList());
                    tRkWareNoticeTabMapper.deleteTRkWareNoticeTabByIds(noticeTabIdsToDelete.toArray(new String[noticeTabIdsToDelete.size()]));
                    initializeNoticeTabForInsert(importedNoticeTab, importedNotice.getId(), operName);
                    importedNoticeTab.setDeliveryId(firstImportedNoticeTab.getDeliveryId());
                    importedNoticeTab.setSourceNum(firstImportedNoticeTab.getDeliveryId());
                    importedNoticeTab.setRecNumNow(null);
                    importedNoticeTab.setRecNum(null);
                    importedNoticeTab.setReceivingNum(importedNoticeTab.getArraMount());
                    tRkWareNoticeTabMapper.insertTRkWareNoticeTab(importedNoticeTab);
                    successCount++;
                    successMessage.append("<br/>" + successCount + "、物料编号 " + importedNoticeTab.getGoodsId() + " 更新成功");
                } else {
                    failureCount++;
                    failureMessage.append("<br/>" + failureCount + "、物料编号 " + importedNoticeTab.getGoodsId() + " 已存在");
                }
            } catch (Exception e) {
                failureCount++;
                String msg = "<br/>" + failureCount + "、来源单号 " + firstImportedNoticeTab.getDeliveryId() + " 导入失败：";
                failureMessage.append(msg + e.getMessage());
                log.error(msg, e);
            }
        }
        if (failureCount > 0) {
            failureMessage.insert(0, "很抱歉，导入失败！共 " + failureCount + " 条数据格式不正确，错误如下：");
            throw new ServiceException(failureMessage.toString());
        } else {
            successMessage.insert(0, "恭喜您，数据已全部导入成功！共 " + successCount + " 条，数据如下：");
        }
        return successMessage.toString();
    }

    /**
     * 导入一级库入库通知单数据
     *
     * @return 结果
     */
    @Override
    @Transactional
    // 入库流程
    public String importExcelData(List<TRkWareNoticeTabExcel> importedExcelNoticeTabs, boolean isUpdateSupport, String operName) {
        if (StringUtils.isNull(importedExcelNoticeTabs) || importedExcelNoticeTabs.isEmpty()) {
            throw new ServiceException("导入入库通知单数据不能为空！");
        }
        int successCount = 0;
        int failureCount = 0;
        StringBuilder successMessage = new StringBuilder();
        StringBuilder failureMessage = new StringBuilder();
        TRkWareNoticeTabExcel firstImportedNoticeTab = importedExcelNoticeTabs.get(0);
        TRkWareNotice importedNotice = new TRkWareNotice();

        //一级库发货单号唯一
        importedNotice.setDeliveryId(firstImportedNoticeTab.getPurchaseId());
        List<TRkWareNotice> duplicateNotices = tRkWareNoticeMapper.selectTRkWareNoticeList(importedNotice);
        if (duplicateNotices.isEmpty()) {
            setExcelTrkNotice(importedNotice, firstImportedNoticeTab, operName);
            importedNotice.setReceivingStatus(InboundNoticeReceivingStatus.CREATED.getCode());
            importedNotice.setStorageMode(InboundStorageMode.STANDARD.getCode());
            tRkWareNoticeMapper.insertTRkWareNotice(importedNotice);

        } else if (isUpdateSupport) {
            List<String> noticeIdsToDelete = duplicateNotices.stream().map(TRkWareNotice::getId).collect(Collectors.toList());
            tRkWareNoticeMapper.deleteTRkWareNoticeByIds(noticeIdsToDelete.toArray(new String[noticeIdsToDelete.size()]));
            setExcelTrkNotice(importedNotice, firstImportedNoticeTab, operName);
            importedNotice.setReceivingStatus(InboundNoticeReceivingStatus.CREATED.getCode());
            importedNotice.setStorageMode(InboundStorageMode.STANDARD.getCode());
            tRkWareNoticeMapper.insertTRkWareNotice(importedNotice);

        } else {
            throw new ServiceException("来源单号 " + firstImportedNoticeTab.getDeliveryId() + " 重复导入异常！");
        }

        for (TRkWareNoticeTabExcel importedExcelNoticeTab : importedExcelNoticeTabs) {
            try {

                // 校验必输字段
//                validateImportedNoticeTab(importIndex, importedExcelNoticeTab);
                // 验证是否存在该明细

                TRkWareNoticeTab noticeTabQuery = new TRkWareNoticeTab();
                noticeTabQuery.setSalesOrderNumber(importedExcelNoticeTab.getSalesOrderNumber());
                noticeTabQuery.setGoodsId(importedExcelNoticeTab.getGoodsId());
                noticeTabQuery.setReceivingStatus(InboundNoticeTabReceivingStatus.PENDING.getCode());
                noticeTabQuery.setInStatus(InboundNoticeTabInStatus.INITIAL.getCode());
                noticeTabQuery.setDataSource(InboundLevelType.LEVEL_ONE.getDescription());

                importedExcelNoticeTab.setDataSource(InboundLevelType.LEVEL_ONE.getDescription());
                importedExcelNoticeTab.setLevelType(InboundLevelType.LEVEL_ONE.getCode());
                importedExcelNoticeTab.setDeliveryId(importedExcelNoticeTab.getPurchaseId());

                SimpleDateFormat originalFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US);
                SimpleDateFormat targetFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                try {
                    if (StringUtils.isNotBlank(importedExcelNoticeTab.getExpiryDate())) {
                        Date expiryDate = originalFormat.parse(importedExcelNoticeTab.getExpiryDate());
                        Date planDate = originalFormat.parse(importedExcelNoticeTab.getPlanDate());
                        String formattedExpiryDate = targetFormat.format(expiryDate);
                        String formattedPlanDate = targetFormat.format(planDate);
                        System.out.println(formattedExpiryDate);
                        importedExcelNoticeTab.setExpiryDate(formattedExpiryDate);
                        importedExcelNoticeTab.setPlanDate(formattedPlanDate);
                    }
                } catch (ParseException e) {
//                    e.printStackTrace();
                }

                TRkWareNoticeTab noticeTabToInsert = new TRkWareNoticeTab();
                BeanUtils.copyProperties(importedExcelNoticeTab, noticeTabToInsert);
                noticeTabToInsert.setDeliveryId(firstImportedNoticeTab.getDeliveryId());
                noticeTabToInsert.setSourceNum(firstImportedNoticeTab.getDeliveryId());
                List<TRkWareNoticeTab> duplicateNoticeTabs = tRkWareNoticeTabMapper.selectTRkWareNoticeTabList(noticeTabQuery);
                if (duplicateNoticeTabs.isEmpty()) {
                    logger.info("createBy:{}", noticeTabToInsert.getCreateBy());
                    initializeNoticeTabForInsert(noticeTabToInsert, importedNotice.getId(), operName);
                    noticeTabToInsert.setReceivingNum(importedExcelNoticeTab.getArraMount());
                    tRkWareNoticeTabMapper.insertTRkWareNoticeTab(noticeTabToInsert);
                    successCount++;
                    successMessage.append("<br/>" + successCount + "、物料编号 " + importedExcelNoticeTab.getGoodsId() + " 导入成功");
                } else if (isUpdateSupport) {
                    List<String> noticeTabIdsToDelete = duplicateNoticeTabs.stream().map(TRkWareNoticeTab::getId).collect(Collectors.toList());
                    tRkWareNoticeTabMapper.deleteTRkWareNoticeTabByIds(noticeTabIdsToDelete.toArray(new String[noticeTabIdsToDelete.size()]));
                    initializeNoticeTabForInsert(noticeTabToInsert, importedNotice.getId(), operName);
                    noticeTabToInsert.setReceivingNum(importedExcelNoticeTab.getArraMount());
                    tRkWareNoticeTabMapper.insertTRkWareNoticeTab(noticeTabToInsert);
                    successCount++;
                    successMessage.append("<br/>" + successCount + "、物料编号 " + importedExcelNoticeTab.getGoodsId() + " 更新成功");
                } else {
                    failureCount++;
                    failureMessage.append("<br/>" + failureCount + "、物料编号 " + importedExcelNoticeTab.getGoodsId() + " 已存在");
                }
            } catch (Exception e) {
                failureCount++;
                String msg = "<br/>" + failureCount + "、来源单号 " + firstImportedNoticeTab.getDeliveryId() + " 导入失败：";
                failureMessage.append(msg + e.getMessage());
                log.error(msg, e);
            }
        }
        if (failureCount > 0) {
            failureMessage.insert(0, "很抱歉，导入失败！共 " + failureCount + " 条数据格式不正确，错误如下：");
            throw new ServiceException(failureMessage.toString());
        } else {
            successMessage.insert(0, "恭喜您，数据已全部导入成功！共 " + successCount + " 条，数据如下：");
        }
        return successMessage.toString();
    }


    private void initializeNoticeTabForInsert(TRkWareNoticeTab noticeTabToInsert, String noticeId, String operName) {
        noticeTabToInsert.setId(OrderCodeFactory.getOrderCode("", ""));
        noticeTabToInsert.setNoticeId(noticeId);
        noticeTabToInsert.setCreateBy(operName);
        noticeTabToInsert.setInStatus(InboundNoticeTabInStatus.INITIAL.getCode());
        noticeTabToInsert.setStatus(InboundNoticeTabStatus.ENABLED.getCode());
        noticeTabToInsert.setCreateTime(DateUtils.getNowDate());


    }

    private void setExcelTrkNotice(TRkWareNotice inboundNotice, TRkWareNoticeTabExcel importedNoticeTab, String operName) {
        inboundNotice.setId(OrderCodeFactory.getOrderCode("", ""));
        inboundNotice.setNoticeId(OrderCodeFactory.getOrderCode("TWO", ""));
        inboundNotice.setDeptId(SecurityUtils.getLoginUser().getDeptId());
        if (StringUtils.isBlank(importedNoticeTab.getApplicant())) {
            inboundNotice.setApplicant(importedNoticeTab.getPurchaser());
        } else {
            inboundNotice.setApplicant(importedNoticeTab.getApplicant());
        }
        inboundNotice.setOperatorId(SecurityUtils.getUserNick());
        inboundNotice.setOrderType(importedNoticeTab.getOrderType());
        inboundNotice.setReceiveAddr(importedNoticeTab.getReceiveAddr());
        inboundNotice.setReceiver(importedNoticeTab.getReceiver());
        inboundNotice.setReceiverDept(importedNoticeTab.getReceiverDept());
        inboundNotice.setProviderId(importedNoticeTab.getProviderId());
        inboundNotice.setProviderName(importedNoticeTab.getProviderName());
        inboundNotice.setShippingDept(importedNoticeTab.getShippingDept());
        inboundNotice.setContact(importedNoticeTab.getContact());
        inboundNotice.setTelephone(importedNoticeTab.getNeedTel());
        inboundNotice.setSendeDate(importedNoticeTab.getSendeDate());
        inboundNotice.setPurchaseDept(importedNoticeTab.getPurchaseDept());
        inboundNotice.setUseReceiver(importedNoticeTab.getUseReceiver());
        inboundNotice.setUseCustodian(importedNoticeTab.getUseCustodian());
        inboundNotice.setUseLeader(importedNoticeTab.getUseLeader());
        inboundNotice.setReceiverDept(importedNoticeTab.getReceiverDept());
        inboundNotice.setTenderer(importedNoticeTab.getTenderer());
        inboundNotice.setCreateBy(operName);
        inboundNotice.setCreateTime(DateUtils.getNowDate());
        inboundNotice.setRecPerson(importedNoticeTab.getRecPerson());
        inboundNotice.setPurchaser(importedNoticeTab.getPurchaser());
        inboundNotice.setArraDate(importedNoticeTab.getArraDate());
        inboundNotice.setDocumentStatus(importedNoticeTab.getDocumentStatus());
        inboundNotice.setDeliveryId(importedNoticeTab.getPurchaseId());
    }

    private void setTrkNotice(TRkWareNotice inboundNotice, TRkWareNoticeTab sourceNoticeTab, String operName) {
        inboundNotice.setId(OrderCodeFactory.getOrderCode("", ""));
        inboundNotice.setNoticeId(OrderCodeFactory.getOrderCode("TWO", ""));
        inboundNotice.setDeptId(SecurityUtils.getLoginUser().getDeptId());
        inboundNotice.setApplicant(sourceNoticeTab.getApplicant());
        inboundNotice.setOrderType(sourceNoticeTab.getOrderType());
        inboundNotice.setReceiveAddr(sourceNoticeTab.getReceiveAddr());
        inboundNotice.setReceiver(sourceNoticeTab.getReceiver());
        inboundNotice.setReceiverDept(sourceNoticeTab.getReceiverDept());
        inboundNotice.setProviderId(sourceNoticeTab.getProviderId());
        inboundNotice.setProviderName(sourceNoticeTab.getProviderName());
        inboundNotice.setShippingDept(sourceNoticeTab.getShippingDept());
        inboundNotice.setContact(sourceNoticeTab.getContact());
        inboundNotice.setTelephone(sourceNoticeTab.getTelephone());
        inboundNotice.setSendeDate(sourceNoticeTab.getSendeDate());
        inboundNotice.setPurchaseDept(sourceNoticeTab.getPurchaseDept());
        inboundNotice.setUseReceiver(sourceNoticeTab.getUseReceiver());
        inboundNotice.setUseCustodian(sourceNoticeTab.getUseCustodian());
        inboundNotice.setUseLeader(sourceNoticeTab.getUseLeader());
        inboundNotice.setReceiverDept(sourceNoticeTab.getReceiverDept());
        inboundNotice.setTenderer(sourceNoticeTab.getTenderer());
        inboundNotice.setCreateBy(operName);
        inboundNotice.setCreateTime(DateUtils.getNowDate());
        inboundNotice.setRecPerson(sourceNoticeTab.getRecPerson());
        inboundNotice.setPurchaser(sourceNoticeTab.getPurchaser());
        inboundNotice.setArraDate(sourceNoticeTab.getArraDate());
        inboundNotice.setDocumentStatus(sourceNoticeTab.getDocumentStatus());
    }

    private void validateImportedNoticeTab(int index, TRkWareNoticeTab importedNoticeTab) {
        //来源单号
        if (StringUtils.isBlank(importedNoticeTab.getDeliveryId())) {
            throw new RuntimeException("导入明细第" + (index + 1) + "条来源单号为空");
        }

        if (StringUtils.isBlank(importedNoticeTab.getDeliveryId())) {
            throw new RuntimeException("导入明细第" + (index + 1) + "条来源单号为空");
        }


        if (StringUtils.isBlank(importedNoticeTab.getGoodsId())) {
            throw new RuntimeException("导入明细第" + (index + 1) + "条物料编码为空");
        }
        if (StringUtils.isBlank(importedNoticeTab.getGoodsName())) {
            throw new RuntimeException("导入明细第" + (index + 1) + "条物料名称为空");
        }
        if (StringUtils.isBlank(importedNoticeTab.getUnit())) {
            throw new RuntimeException("导入明细第" + (index + 1) + "条物料单位为空");
        }

        if (importedNoticeTab.getArraMount() == null) {
            throw new RuntimeException("导入明细第" + (index + 1) + "条到货数量为空");
        }
        /*if (StringUtils.isBlank(trdata.getApplicant())) {
            throw new RuntimeException("导入明细第" + (index + 1) + "条申请人为空");
        }*/
        /*if (StringUtils.isBlank(trdata.getSupplier())) {
            throw new RuntimeException("导入明细第" + (index + 1) + "条申请部门为空");
        }*/
    }

    @Override
    @Transactional
    public Map<String, String> sendOrderNotice(TRkWareNoticeTabUpdate noticePushRequest) {
        Map<String, String> resultMap = new HashMap<>();

        LambdaQueryWrapper<TCallNoticeOrder> noticeOrderQueryWrapper = new LambdaQueryWrapper<>();
        noticeOrderQueryWrapper.eq(TCallNoticeOrder::getTaskId, noticePushRequest.getId());
        noticeOrderQueryWrapper.eq(TCallNoticeOrder::getStatus, "0");
        TCallNoticeOrder pendingNoticeOrder = callNoticeOrderMapper.selectOne(noticeOrderQueryWrapper);
        if (pendingNoticeOrder != null) {
            resultMap.put("error", "已经推送手持设备，请相关人员查看");
            return resultMap;
        }


        // 获取通知单信息
        TRkWareNotice inboundNotice = tRkWareNoticeMapper.selectTRkWareNoticeById(noticePushRequest.getId());

        if (ObjectUtils.isEmpty(inboundNotice)) {
            resultMap.put("error", "待发送消息的入库通知单不存在");
            return resultMap;
        }

        if (inboundNotice.getTRkWareNoticeTabList() == null || inboundNotice.getTRkWareNoticeTabList().isEmpty()) {
            resultMap.put("error", "待发送消息的入库通知单没有物料明细数据");
            return resultMap;
        }

        // 发送呼叫任务
        TCallNoticeOrder noticeOrderToSend = new TCallNoticeOrder();
        // 通知单编号
        noticeOrderToSend.setTaskId(inboundNotice.getId());
        // 任务类型 0:通知单入库
        noticeOrderToSend.setTaskType("0");
        // 状态
        noticeOrderToSend.setStatus("0");
        // 创建者
        noticeOrderToSend.setCreateBy(noticePushRequest.getCreateBy());
        noticeOrderToSend.setCreateTime(new Date());
        noticeOrderToSend.setUpdateBy(noticePushRequest.getCreateBy());
        noticeOrderToSend.setUpdateTime(new Date());

        // 0:正常任务
        noticeOrderToSend.setFictitious("0");
        // 来源单号
        noticeOrderToSend.setDeliveryId(inboundNotice.getDeliveryId());
        // 供应商名
        noticeOrderToSend.setProviderName(inboundNotice.getProviderName());
        // 部门ID
        noticeOrderToSend.setDeptId(noticePushRequest.getDeptId());
        // 订单类型
        String storageModeLabel = sysDictDataMapper.selectDictLabel("warehouse_type", inboundNotice.getStorageMode());
        noticeOrderToSend.setOrderType(storageModeLabel);
        tNoticeOrderService.sendNotice(noticeOrderToSend);

        resultMap.put("success", "消息发送成功");
        resultMap.put("error", "");
        return resultMap;
    }

    @Override
    @Transactional
    public Map<String, String> handAddGoodsTab(TRkWareNoticeTabUpdate manualInboundRequest) {

//        List<TRkWareNoticeTab> noticeTabList = manualInboundRequest.getTrkWareNoticeTabList();
        /*noticeTabList.forEach(e->{
            String ctl = e.getCtl();
            String goodsId = e.getGoodsId();
            TOngoodsshelf ongoodsshelf = new TOngoodsshelf();
            ongoodsshelf.setCtl(ctl);
            ongoodsshelf.setGoodsId(goodsId);
            List<TOngoodsshelf> tOngoodsshelves = tOgoodsshelfMapper.selectTOngoodsshelfList(ongoodsshelf);
            if (tOngoodsshelves.isEmpty()){
                throw new RuntimeException(ctl+"已经创建入库任务不允许重复收货");
            }
        });*/
        // 生成一个以"AGV"开头的12位数字字符串
        String prefix = "AGV";
        int numberLength = 6; // 需要生成的数字长度
        StringBuilder numberBuilder = new StringBuilder();
        for (int i = 0; i < numberLength; i++) {
            numberBuilder.append(random.nextInt(10)); // 生成一个0到9的随机数
        }
        String generatedRfid = prefix + numberBuilder.toString();

        Map<String, String> resultMap = new HashMap<>();

        String agvStorageFlag = tBaseStorageMapper.getIsAgvByStorageId(manualInboundRequest.getStorageId());


        if (agvStorageFlag.equals("1")) {
            TRkWareNotice manualInboundNotice = buildManualInboundNotice(manualInboundRequest);
            List<TRkWareNoticeTab> noticeTabsToInsert = new ArrayList<>();
            for (TRkWareNoticeTab noticeTabToInsert : manualInboundRequest.getTrkWareNoticeTabList()) {
                noticeTabsToInsert.add(buildAgvInboundNoticeTab(noticeTabToInsert, generatedRfid, manualInboundRequest));
            }
            tRkWareNoticeMapper.insertTRkWareNotice(manualInboundNotice);
            if (!noticeTabsToInsert.isEmpty()) {
                tRkWareNoticeMapper.batchTRkWareNoticeTab(noticeTabsToInsert);
            }
            Map<String, String> iwmsSyncResult = sendIwmsUnified(manualInboundRequest);


            if (iwmsSyncResult.containsKey("success")) {
                resultMap.put("success", iwmsSyncResult.get("success"));
            } else {
                resultMap.put("error", iwmsSyncResult.get("error"));
            }

            return resultMap;
        } else {
            //绑定库位直接上架
            if (StringUtils.isNotBlank(manualInboundRequest.getLocationId())) {

                LambdaQueryWrapper<TBaseStorageAreaLocation> locationQueryWrapper = new LambdaQueryWrapper<>();
                locationQueryWrapper.eq(TBaseStorageAreaLocation::getLocationId, manualInboundRequest.getLocationId());
                List<TBaseStorageAreaLocation> matchedLocations = service.selectList(locationQueryWrapper);
                if (!matchedLocations.isEmpty()) {
                    TBaseStorageAreaLocation targetLocation = matchedLocations.get(0);
                    if ("1".equals(targetLocation.getIsLock())) {
                        resultMap.put("error", "库位【" + manualInboundRequest.getLocationId() + "】已禁用");
                        log.error("库位【" + manualInboundRequest.getLocationId() + "】已禁用");
                        return resultMap;
                    }
                }

                if (!ObjectUtils.isEmpty(manualInboundRequest.getCtlNo())) {

                    //校验托盘容器是否正确
                    LambdaQueryWrapper<TBasePallet> palletQueryWrapper = new LambdaQueryWrapper<>();
                    palletQueryWrapper.eq(TBasePallet::getPalletId, manualInboundRequest.getCtlNo());
                    List<TBasePallet> palletMatches = palletMapper.selectList(palletQueryWrapper);
                    if (!palletMatches.isEmpty()) {
                        TBasePallet targetPallet = palletMatches.get(0);
                        if ("1".equals(targetPallet.getIsLock())) {
                            resultMap.put("error", "托盘号【" + manualInboundRequest.getCtlNo() + "】已禁用");
                            log.error("托盘号【" + manualInboundRequest.getCtlNo() + "】已禁用");
                            return resultMap;
                        }
                    }
                }

                List<TRkWareNoticeTab> submittedNoticeTabs = manualInboundRequest.getTrkWareNoticeTabList();
                for (TRkWareNoticeTab submittedNoticeTab : submittedNoticeTabs) {

                    LambdaQueryWrapper<TBaseGoods> goodsQueryWrapper = new LambdaQueryWrapper<>();
                    goodsQueryWrapper.eq(TBaseGoods::getGoodsId, submittedNoticeTab.getGoodsId());
                    //物料信息
                    TBaseGoods baseGoods = tBaseGoodsMapper.selectOne(goodsQueryWrapper);

                    if (baseGoods == null) {
                        resultMap.put("error", "暂无物料信息");
                        return resultMap;
                    }

                    TMiStock realStockRecord = new TMiStock();
                    realStockRecord.setId(OrderCodeFactory.getOrderCode("TMI", ""));

                    // 上架数量
                    realStockRecord.setShelvesNum(submittedNoticeTab.getRecNum());
                    // 中标供应商
                    realStockRecord.setProviderId(submittedNoticeTab.getProviderId());
                    // 单位
                    realStockRecord.setUnit(submittedNoticeTab.getUnit());
                    // 子需求编号
                    realStockRecord.setSalesOrderNumber(OrderCodeFactory.getOrderCode("SJ", ""));
                    // 物料名称
                    realStockRecord.setGoodsName(baseGoods.getGoodsName());
                    // 规格型号
                    realStockRecord.setSpecification(baseGoods.getSpecification());
                    // 物料描述
                    realStockRecord.setRecoil(baseGoods.getRecoil());
                    // 招标员
                    realStockRecord.setCustomerId("");
                    // 需求组织
                    realStockRecord.setOperatorId(SecurityUtils.getUserNick());
                    // 申请部门
                    realStockRecord.setSupplier(SecurityUtils.getDeptName());
                    // 创建时间
                    realStockRecord.setOperateDate(new Date());
                    // 上报时间
                    realStockRecord.setReportTime(DateUtils.getDate());
                    // 申请单号 设置为来源单号 发货单号 TODO
                    realStockRecord.setLotId(OrderCodeFactory.getOrderCode("RK", ""));
                    // 申请人
                    realStockRecord.setApplicant(SecurityUtils.getUserNick());
                    // 计划日期
                    realStockRecord.setPlanDate("");
                    // 计划期间
                    realStockRecord.setPlanTime("");
                    // 需求周期
                    realStockRecord.setNeedCycle(submittedNoticeTab.getNeedCycle());
                    // 需求类型
                    realStockRecord.setNeedType(submittedNoticeTab.getNeedType());
                    // 物料编码
                    realStockRecord.setGoodsId(submittedNoticeTab.getGoodsId());
                    // 物料分类
                    realStockRecord.setGoodsTypeId(submittedNoticeTab.getGoodsTypeId());
                    // 品牌
                    realStockRecord.setBrand(submittedNoticeTab.getBrand());
                    // 计划单价（含税）
                    realStockRecord.setPrice(submittedNoticeTab.getPrice() != null ? submittedNoticeTab.getPrice().toString() : null);
                    // 计划金额

                    BigDecimal shelvedQuantity = submittedNoticeTab.getRecNum();
                    BigDecimal unitPrice = baseGoods.getPrice();
                    if (unitPrice == null || unitPrice.compareTo(BigDecimal.ZERO) == 0) {
                        unitPrice = BigDecimal.ZERO; // 默认值为 1
                    }


                    realStockRecord.setTotalMoney(unitPrice.multiply(shelvedQuantity));
                    // 需求时间
                    realStockRecord.setExpiryDate(submittedNoticeTab.getExpiryDate());
                    // 建议供应商名称 TODO
                    realStockRecord.setProviderName(submittedNoticeTab.getProviderName());
                    // 收货人
                    realStockRecord.setReceiver(SecurityUtils.getUserNick());
                    // 需求部门
                    realStockRecord.setNeedDept(SecurityUtils.getDeptName());
                    // 采购组织
                    realStockRecord.setPurchaseDept(SecurityUtils.getDeptName());
                    // 收货组织
                    realStockRecord.setProduclotId(SecurityUtils.getDeptName());
                    // 收货人部门
                    realStockRecord.setReceiverDept(SecurityUtils.getDeptName());
                    // 送货区域
                    realStockRecord.setReceivingArea(submittedNoticeTab.getReceivingArea());
                    // 技术需求附件
                    realStockRecord.setPackageId(submittedNoticeTab.getPackageId());
                    // 物资计划明细备注
                    realStockRecord.setRemark(submittedNoticeTab.getRemark());
                    // 用途
                    realStockRecord.setUseType(submittedNoticeTab.getUseType());
                    // 中标供应商联系方式
                    realStockRecord.setTelephone(submittedNoticeTab.getTelephone());
                    // wms订单号 入库通知单号
                    realStockRecord.setNoticeId(submittedNoticeTab.getNoticeId());
                    // 生产日期
                    realStockRecord.setProductionDate(submittedNoticeTab.getProductionDate());
                    // 入库类型
                    realStockRecord.setStorageMode("1");
                    // 仓库编号
                    realStockRecord.setStorageId(manualInboundRequest.getStorageId());
                    TBaseStorage targetStorage = tBaseStorageMapper.getName(manualInboundRequest.getStorageId());

                    realStockRecord.setStorageShortName(targetStorage.getStorageShortName());
                    // 库位
                    realStockRecord.setLocationId(manualInboundRequest.getStorageLocation());
                    // 增加外部批次号
                    realStockRecord.setBatchNo(submittedNoticeTab.getBatchNo());
                    // 条码
                    realStockRecord.setBarcode(submittedNoticeTab.getBarcode());
                    // 入库级别

                    realStockRecord.setLevelType(manualInboundRequest.getTypes());

                    realStockRecord.setStandard("180");

                    // 托盘
                    realStockRecord.setCtl(manualInboundRequest.getCtlNo());
                    realStockRecord.setOriginal(baseGoods.getStorageId());

                    realStockRecord.setCreateBy(SecurityUtils.getUserNick());
                    realStockRecord.setCreateTime(new Date());
                    realStockRecord.setRecordPerson("");
                    realStockRecord.setLocationId(manualInboundRequest.getLocationId());

                    // 入库时间
                    realStockRecord.setWareDate(DateUtils.getTime());

                    realStockRecord.setDeptId(SecurityUtils.getDeptId());
                    realStockRecord.setNeedPerson(submittedNoticeTab.getNeedPerson());
                    realStockRecord.setNeedTel(submittedNoticeTab.getNeedTel());
                    tMiStockMapper.insertTMiStock(realStockRecord);
                }
                resultMap.put("success", "入库成功");
                return resultMap;
            }

            //原来的逻辑
            handleNonAgvManualInbound(manualInboundRequest, resultMap);
        }
        return resultMap;
    }

    private TRkWareNotice buildManualInboundNotice(TRkWareNoticeTabUpdate manualInboundRequest) {
        TRkWareNotice manualInboundNotice = new TRkWareNotice();
        manualInboundNotice.setId(manualInboundRequest.getId());
        manualInboundNotice.setNoticeId(manualInboundRequest.getNoticeId());
        manualInboundNotice.setUpdateBy(manualInboundRequest.getRecordPerson());
        manualInboundNotice.setUpdateTime(new Date());
        manualInboundNotice.setCreateBy(manualInboundRequest.getRecordPerson());
        manualInboundNotice.setCreateTime(new Date());
        manualInboundNotice.setStorageMode("3");
        manualInboundNotice.setReceivingStatus("3");
        manualInboundNotice.setDeptId(manualInboundRequest.getDeptId());
        return manualInboundNotice;
    }

    private TRkWareNoticeTab buildAgvInboundNoticeTab(TRkWareNoticeTab noticeTabToInsert, String generatedRfid,
                                                      TRkWareNoticeTabUpdate manualInboundRequest) {
        noticeTabToInsert.setSalesOrderNumber(generatedRfid);
        noticeTabToInsert.setReceivingStatus("3");
        noticeTabToInsert.setInStatus("1");
        noticeTabToInsert.setRecNumNow(noticeTabToInsert.getRecNum());
        noticeTabToInsert.setArraMount(noticeTabToInsert.getRecNum());
        noticeTabToInsert.setReceivingNum(noticeTabToInsert.getRecNum());
        noticeTabToInsert.setUpdateBy(manualInboundRequest.getRecordPerson());
        noticeTabToInsert.setUpdateTime(new Date());
        noticeTabToInsert.setCreateBy(manualInboundRequest.getRecordPerson());
        noticeTabToInsert.setCreateTime(new Date());
        noticeTabToInsert.setNoticeId(manualInboundRequest.getId());
        noticeTabToInsert.setId(OrderCodeFactory.getOrderCode("TRKTAB", ""));
        noticeTabToInsert.setLevelType("2");
        return noticeTabToInsert;
    }

    private void handleNonAgvManualInbound(TRkWareNoticeTabUpdate manualInboundRequest, Map<String, String> resultMap) {
        if (ObjectUtils.isEmpty(manualInboundRequest.getCtlNo())) {
            List<Plc> plcList = plcService.selectPlcList();
            Plc currentPlc = plcList.get(0);
            if (currentPlc.getPlcid() == 9999999) {
                currentPlc.setPlcid(0L);
            } else {
                currentPlc.setPlcid(currentPlc.getPlcid() + 1);
            }
            currentPlc.setId(1);
            plcService.updatePlc(currentPlc);
            manualInboundRequest.getParams().put("plcId", currentPlc.getPlcid());
        } else {
            LambdaQueryWrapper<TBasePallet> palletQueryWrapper = new LambdaQueryWrapper<>();
            palletQueryWrapper.eq(TBasePallet::getPalletId, manualInboundRequest.getCtlNo());
            List<TBasePallet> palletMatches = palletMapper.selectList(palletQueryWrapper);
            if (palletMatches.isEmpty()) {
                resultMap.put("error", "托盘不存在");
                return;
            }

            TBasePallet targetPallet = palletMatches.get(0);
            if ("1".equals(targetPallet.getIsLock())) {
                resultMap.put("error", "托盘号【" + manualInboundRequest.getCtlNo() + "】已禁用");
                log.error("托盘号【" + manualInboundRequest.getCtlNo() + "】已禁用");
                throw new RuntimeException("托盘号【" + manualInboundRequest.getCtlNo() + "】已禁用");
            }
        }

        TCallNotice inboundCallNotice = new TCallNotice();
        inboundCallNotice.setId(IdUtils.randomUUID());
        manualInboundRequest.getParams().put("callNoticeId", inboundCallNotice.getId());

        TRkWareNotice manualInboundNotice = new TRkWareNotice();
        manualInboundNotice.setId(manualInboundRequest.getId());
        manualInboundNotice.setNoticeId(manualInboundRequest.getNoticeId());
        manualInboundNotice.setUpdateBy(manualInboundRequest.getRecordPerson());
        manualInboundNotice.setUpdateTime(new Date());
        manualInboundNotice.setCreateBy(manualInboundRequest.getRecordPerson());
        manualInboundNotice.setCreateTime(new Date());
        manualInboundNotice.setStorageMode("3");
        manualInboundNotice.setReceivingStatus("0");
        tRkWareNoticeMapper.insertTRkWareNotice(manualInboundNotice);

        List<TRkWareNoticeTab> noticeTabsToInsert = new ArrayList<TRkWareNoticeTab>();
        List<TOngoodsshelf> inboundTasksToInsert = new ArrayList<TOngoodsshelf>();

        // 遍历提交的物料数据明细
        int subDemandSequence = 0;
        TBaseStorage storageQuery = new TBaseStorage();
        TBaseStorage storage = new TBaseStorage();
        // 获取仓库信息
        if (!ObjectUtils.isEmpty(manualInboundRequest.getStorageId())) {
            storageQuery.setStorageId(manualInboundRequest.getStorageId());
            List<TBaseStorage> matchedStorages = tBaseStorageMapper.selectTBaseStorageList(storageQuery);

            if (matchedStorages.size() > 0) {
                storage = matchedStorages.get(0);
            }
        }

        for (TRkWareNoticeTab noticeTabToInsert : manualInboundRequest.getTrkWareNoticeTabList()) {
            // 仓库名称
            noticeTabToInsert.setStorageShortName(storage.getStorageShortName());

            // 子需求编号
            noticeTabToInsert.setSalesOrderNumber(String.valueOf(subDemandSequence));
            subDemandSequence++;
            // 在途
            noticeTabToInsert.setReceivingStatus("0");
            // 冻结
            noticeTabToInsert.setInStatus("1");
            noticeTabToInsert.setRecNumNow(noticeTabToInsert.getRecNum());
            noticeTabToInsert.setUpdateBy(manualInboundRequest.getRecordPerson());
            noticeTabToInsert.setUpdateTime(new Date());
            noticeTabToInsert.setCreateBy(manualInboundRequest.getRecordPerson());
            noticeTabToInsert.setCreateTime(new Date());
            noticeTabToInsert.setNoticeId(manualInboundRequest.getId());
            noticeTabToInsert.setStorageId(manualInboundRequest.getStorageId());
            noticeTabToInsert.setId(OrderCodeFactory.getOrderCode("TRKTAB", ""));
            noticeTabToInsert.setLevelType(manualInboundRequest.getTypes());
            noticeTabsToInsert.add(noticeTabToInsert);
            inboundTasksToInsert.add(buildInboundTask(manualInboundNotice, noticeTabToInsert, manualInboundRequest));
        }

        // 生成入库任务
        if (inboundTasksToInsert.size() > 0) {
            for (TOngoodsshelf inboundTaskToInsert : inboundTasksToInsert) {
                inboundTaskToInsert.setStorageId(manualInboundRequest.getStorageId());
                tOngoodsshelfMapper.insertTOngoodsshelf(inboundTaskToInsert);
            }
            inboundCallNotice.setStorageId(manualInboundRequest.getStorageId());
            inboundCallNotice.setStorageShortName(manualInboundRequest.getStorageShortName());
            inboundCallNotice.setCtl(manualInboundRequest.getCtlNo());
            if (StringUtils.isEmpty(manualInboundRequest.getCtlNo())) {
                // pLCID
                inboundCallNotice.setPlcid((Long) manualInboundRequest.getParams().get("plcId"));
            }
            inboundCallNotice.setTaskType("0");
            inboundCallNotice.setCreateBy(manualInboundRequest.getRecordPerson());
            inboundCallNotice.setCreateTime(new Date());
            inboundCallNotice.setStatus("0");
            inboundCallNotice.setFictitious("0");
            inboundCallNotice.setTaskId(manualInboundNotice.getNoticeId());
            tNoticeService.sendNotice(inboundCallNotice);
        }

        if (noticeTabsToInsert.size() > 0) {
            // 入库通知单明细批量插入
            tRkWareNoticeMapper.batchTRkWareNoticeTab(noticeTabsToInsert);
        }
        resultMap.put("success", "收货成功");
        resultMap.put("error", "");
    }


    @Override
    @Transactional
    @Log(title = "入库推送")
    public Map<String, String> sendIwmsUnified(TRkWareNoticeTabUpdate iwmsPushRequest) {
        Map<String, String> resultMap = new HashMap<>();
        List<TRkWareNoticeTab> submittedNoticeTabs = iwmsPushRequest.getTrkWareNoticeTabList();

        if (submittedNoticeTabs != null) {
            for (TRkWareNoticeTab submittedNoticeTab : submittedNoticeTabs) {
                // 获取推送过来的数量
                BigDecimal currentReceivedQuantity = submittedNoticeTab.getRecNumNow();
                String noticeTabId = submittedNoticeTab.getId();

                // 查询数据库中的当前数量
                TRkWareNoticeTab noticeTabInDb = tRkWareNoticeTabMapper.selectTRkWareNoticeTabById(noticeTabId);
                BigDecimal plannedReceivingQuantity = noticeTabInDb.getReceivingNum();
                if (plannedReceivingQuantity == null) {
                    plannedReceivingQuantity = noticeTabInDb.getArraMount();
                }

                TRkWareNoticeTab noticeTabQuantityUpdate = new TRkWareNoticeTab();
                // 检查数量是否不一致
                if (currentReceivedQuantity.compareTo(plannedReceivingQuantity) < 0) { // 使用 compareTo 进行 BigDecimal 比较
                    // 计算差值
                    BigDecimal remainingQuantity = plannedReceivingQuantity.subtract(currentReceivedQuantity); // 计算剩余数量

                    // 创建新的入库单记录剩余数量
                    if (remainingQuantity.compareTo(BigDecimal.ZERO) > 0) { // 如果剩余数量大于 0
                        TRkWareNoticeTab remainingNoticeTab = new TRkWareNoticeTab();
                        BeanUtils.copyProperties(noticeTabInDb, remainingNoticeTab);
                        remainingNoticeTab.setRecNum(null); // 设置剩余数量
                        remainingNoticeTab.setReceivingNum(remainingQuantity);
                        remainingNoticeTab.setArraMount(remainingQuantity); // 设置剩余数量
                        // 这里可以设置其他必要的字段，例如物料编号、入库单号等
                        remainingNoticeTab.setId(OrderCodeFactory.getOrderCode("TRKTAB", ""));
                        tRkWareNoticeTabMapper.insertTRkWareNoticeTab(remainingNoticeTab); // 插入新的入库单
//                        noticeTabQuantityUpdate.setReceivingStatus("1");
                    }
                }
                // 更新当前入库单的数量
                noticeTabQuantityUpdate.setId(noticeTabId);
                noticeTabQuantityUpdate.setRecNum(currentReceivedQuantity);
                noticeTabQuantityUpdate.setInStatus("1");
                tRkWareNoticeTabMapper.updateNum(noticeTabQuantityUpdate);
            }
        } else {
            resultMap.put("error", "收货明细为空异常");
            return resultMap;
        }

        // 获取通知单信息
        if (StringUtils.isBlank(iwmsPushRequest.getCtlNo())) {
            resultMap.put("error", "推送机器人请扫描托盘号");
            return resultMap;
        }
        TRkWareNotice inboundNotice = tRkWareNoticeMapper.selectTRkWareNoticeById(iwmsPushRequest.getId());
        if (ObjectUtils.isEmpty(inboundNotice)) {
            resultMap.put("error", "待发送消息的入库通知单不存在");
            return resultMap;
        }
        if (inboundNotice.getTRkWareNoticeTabList() == null || inboundNotice.getTRkWareNoticeTabList().isEmpty()) {
            resultMap.put("error", "待发送消息的入库通知单没有物料明细数据");
            return resultMap;
        }

        // 根据 ctl 判断使用哪个 URL
        /*final String url = iwmsPushRequest.getCtlNo() != null && iwmsPushRequest.getCtlNo().startsWith("A1") ?
                "https://172.18.29.101/wms/api/RestJsonService/pushIntoOrder" :
                "http://172.18.29.101:32130/wms/api/flow/3c/pushIntoOrderBox";*/

        String iwmsPushUrl = "https://172.18.29.101/wms/api/RestJsonService/pushIntoOrder";
        ObjectMapper objectMapper = new ObjectMapper();
        String requestCode = generateRandomHexCode(20);

        // 请求主体
        Map<String, Object> requestData = new HashMap<>();
        requestData.put("reqCode", requestCode);
        List<TRkWareNoticeTab> noticeTabsToPush = iwmsPushRequest.getTrkWareNoticeTabList();
        List<TRkWareNoticeTab> pushedNoticeTabs = new ArrayList<>();
        List<Map<String, Object>> dataList = new ArrayList<>();
        for (TRkWareNoticeTab noticeTabToPush : noticeTabsToPush) {
            Map<String, Object> dataObject = new HashMap<>();
            populateDataObject(dataObject, noticeTabToPush, iwmsPushRequest);
            dataList.add(dataObject);
            // Update tab status
//            noticeTabToPush.setInStatus("1");
//            noticeTabToPush.setRecNum(noticeTabToPush.getRe);
//            pushedNoticeTabs.add(noticeTabToPush);
        }

        requestData.put("data", dataList); // 循环结束后，将列表赋值给requestData的data键
        //测试 不用就关闭注释
//        updateNoticeAndOrderStatus(inboundNotice, iwmsPushRequest, pushedNoticeTabs);
        String requestBody = "";
        try {
            requestBody = objectMapper.writeValueAsString(requestData);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }

        try (CloseableHttpClient httpClient = createHttpClient()) {
            HttpPost httpPost = new HttpPost(iwmsPushUrl);
            httpPost.setHeader("Accept", "application/json");
            httpPost.setHeader("Content-type", "application/json");
            httpPost.setEntity(new StringEntity(requestBody));
            HttpResponse response = httpClient.execute(httpPost);
            String responseString = EntityUtils.toString(response.getEntity(), "UTF-8");

            // Parse the JSON response
            JsonNode responseJson = objectMapper.readTree(responseString);
            if (responseJson.get("code").asInt() == 0) {
                resultMap.put("success", "消息发送成功");
                updateNoticeAndOrderStatus(inboundNotice, iwmsPushRequest, pushedNoticeTabs);
            } else {
                resultMap.put("error", "消息发送失败: " + responseJson.get("message").asText());
            }
        } catch (Exception e) {
            e.printStackTrace();
            resultMap.put("error", "系统异常: " + e.getMessage());
        }
//                resultMap.put("success", "消息发送成功");
        return resultMap;
    }

    private String generateRandomHexCode(int length) {
        // 生成一个以"rfid"开头的随机数字串
        String prefix = "rfid";
        int numberLength = length; // 需要生成的数字长度
        StringBuilder numberBuilder = new StringBuilder();
        for (int i = 0; i < numberLength; i++) {
            numberBuilder.append(random.nextInt(10)); // 生成一个0到9的随机数
        }
        String generatedCode = prefix + numberBuilder.toString();
        return generatedCode;
    }

    private void populateDataObject(Map<String, Object> dataObject, TRkWareNoticeTab noticeTab, TRkWareNoticeTabUpdate iwmsPushRequest) {
        dataObject.put("operType", "A");
        dataObject.put("orderType", iwmsPushRequest.getCtlNo() != null && iwmsPushRequest.getCtlNo().startsWith("A1") ? "4" : "1");
        dataObject.put("orderNum", iwmsPushRequest.getId());
        dataObject.put("orderItem", noticeTab.getId());
        dataObject.put("orderKeyThird", noticeTab.getSalesOrderNumber());
        dataObject.put("whCode", "RZ01");
        dataObject.put("ownerCode", "8000");
        dataObject.put("matCode", noticeTab.getGoodsId());
        dataObject.put("matQty", noticeTab.getRecNumNow());
        dataObject.put("traceCode", iwmsPushRequest.getCtlNo() == null ? noticeTab.getCtl() : iwmsPushRequest.getCtlNo());
        dataObject.put("intoOrderStr2", iwmsPushRequest.getCtlNo() != null && iwmsPushRequest.getCtlNo().startsWith("A1") ? "KQTRAY" : "KQ2LBOX");

        if (iwmsPushRequest.getCtlNo() != null && iwmsPushRequest.getCtlNo().startsWith("A1")) {
            dataObject.put("batchAttr07", "1");
            dataObject.put("intoOrderStr2", "KQTRAY");
        } else {
            dataObject.put("intoOrderBox2", "KQ2LBOX");
            dataObject.put("boxAttr07", "2");
            dataObject.put("boxCode", generateRandomHexCode(8));
            dataObject.put("boxQty", noticeTab.getArraMount());
        }
/*
        dataObject.put("createUser", noticeTab.getApplicant());
*/


    }

    private void updateNoticeAndOrderStatus(TRkWareNotice inboundNotice, TRkWareNoticeTabUpdate iwmsPushRequest, List<TRkWareNoticeTab> pushedNoticeTabs) {
        inboundNotice.setReceiver(SecurityUtils.getUserNick());
//        List<TRkWareNoticeTab> noticeTabsToUpdate = pushedNoticeTabs;
//        for (TRkWareNoticeTab noticeTab : noticeTabsToUpdate) {
//            if(noticeTab.getRecNum() == null)
//                noticeTab.setRecNum(BigDecimal.ZERO);
//            noticeTab.setRecNum(noticeTab.getRecNum().add(noticeTab.getRecNumNow()));
//            tRkWareNoticeTabMapper.updateTRkWareNoticeTab(noticeTab);
//        }
//        tRkWareNoticeMapper.updateForeach(pushedNoticeTabs);
        //获取最新的通知单
        TRkWareNotice latestInboundNotice = selectTRkWareNoticeById(iwmsPushRequest.getId());
        List<TRkWareNoticeTab> latestNoticeTabs = latestInboundNotice.getTRkWareNoticeTabList();
        int pendingNoticeTabCount = (int) latestNoticeTabs.stream().filter(noticeTab -> noticeTab.getInStatus().equals("0")).count();

        if (pendingNoticeTabCount == 0) {
            inboundNotice.setReceivingStatus("1");
        }
        if (iwmsPushRequest.getTrkWareNoticeTabList() == null) {
            inboundNotice.setReceivingStatus("3");
            LambdaQueryWrapper<TCallNoticeOrder> noticeOrderQueryWrapper = new LambdaQueryWrapper<>();
            noticeOrderQueryWrapper.eq(TCallNoticeOrder::getTaskId, iwmsPushRequest.getNoticeId());
        }
        tRkWareNoticeMapper.updateTRkWareNotice(inboundNotice);


    }


    private SSLContext createTrustAllSslContext() throws Exception {
        TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    public void checkClientTrusted(X509Certificate[] chain, String authType) {
                    }

                    public void checkServerTrusted(X509Certificate[] chain, String authType) {
                    }


                    public X509Certificate[] getAcceptedIssuers() {
                        return new X509Certificate[]{};
                    }
                }
        };

        SSLContext sslContext = SSLContext.getInstance("SSL");
        sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
        return sslContext;
    }

    private CloseableHttpClient createHttpClient() throws Exception {
        return HttpClients.custom()
                .setSslcontext(createTrustAllSslContext())
                .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
                .build();
    }

    private static HashSet<Integer> usedNumbers = new HashSet<>();
    private static Random random = new Random();

    public static String generateUniqueSalesOrderNumber() {
        int uniqueNumber;
        do {
            uniqueNumber = 1000 + random.nextInt(9000); // 生成1000到9999之间的随机数
        } while (usedNumbers.contains(uniqueNumber));
        usedNumbers.add(uniqueNumber);
        return "AGV" + uniqueNumber;
    }


    /**
     * 虚拟库位上架
     *
     * @param
     * @return
     */
    @Override
    public Map<String, String> virtualListing(TCkOrders stockTransferOrder) {
        Map<String, String> resultMap = new HashMap<>();

        TRkWareNotice virtualInboundNotice = new TRkWareNotice();
        virtualInboundNotice.setId(OrderCodeFactory.getOrderCode("", ""));
        virtualInboundNotice.setNoticeId(OrderCodeFactory.getOrderCode("TWO", ""));
        virtualInboundNotice.setDeptId(SecurityUtils.getLoginUser().getDeptId());
        virtualInboundNotice.setApplicant(SecurityUtils.getUserNick());
        virtualInboundNotice.setOrderType("3");
        virtualInboundNotice.setCreateBy(SecurityUtils.getUserNick());
        virtualInboundNotice.setCreateTime(DateUtils.getNowDate());
        virtualInboundNotice.setIsAvgExec("1");
        int insertedNoticeCount = insertTRkWareNotice(virtualInboundNotice);
        TMiStock matchedStock = new TMiStock();
        for (TCkOrderdetail outboundOrderDetail : stockTransferOrder.getTckOrderdetailList()) {

            if (!ObjectUtils.isEmpty(outboundOrderDetail.getLocationId())) {
                LambdaQueryWrapper<TBaseStorageAreaLocation> locationQueryWrapper = new LambdaQueryWrapper<>();
                locationQueryWrapper.eq(TBaseStorageAreaLocation::getLocationId, outboundOrderDetail.getLocationId());
                List<TBaseStorageAreaLocation> matchedLocations = service.selectList(locationQueryWrapper);
                if (!matchedLocations.isEmpty()) {
                    TBaseStorageAreaLocation targetLocation = matchedLocations.get(0);
                    if ("1".equals(targetLocation.getIsLock())) {
                        resultMap.put("error", "库位【" + outboundOrderDetail.getLocationId() + "】已禁用");
                        log.error("库位【" + outboundOrderDetail.getLocationId() + "】已禁用");
                        return resultMap;
                    }
                }
            }

            if (!ObjectUtils.isEmpty(outboundOrderDetail.getCtl())) {

                //校验托盘容器是否正确
                LambdaQueryWrapper<TBasePallet> palletQueryWrapper = new LambdaQueryWrapper<>();
                palletQueryWrapper.eq(TBasePallet::getPalletId, outboundOrderDetail.getCtl());
                List<TBasePallet> palletMatches = palletMapper.selectList(palletQueryWrapper);
                if (!palletMatches.isEmpty()) {
                    TBasePallet targetPallet = palletMatches.get(0);
                    if ("1".equals(targetPallet.getIsLock())) {
                        resultMap.put("error", "托盘号【" + outboundOrderDetail.getCtl() + "】已禁用");
                        log.error("托盘号【" + outboundOrderDetail.getCtl() + "】已禁用");
                        return resultMap;
                    }
                }
            }

            List<TRkWareNoticeTab> noticeTabsToInsert = new ArrayList<>();
            LambdaQueryWrapper<TMiStock> stockQueryWrapper = new LambdaQueryWrapper<>();
            stockQueryWrapper.eq(TMiStock::getCtl, outboundOrderDetail.getCtl());
            stockQueryWrapper.eq(TMiStock::getGoodsId, outboundOrderDetail.getGoodsId());
            stockQueryWrapper.eq(TMiStock::getGoodsName, outboundOrderDetail.getGoodsName());
            stockQueryWrapper.eq(TMiStock::getLocationId, outboundOrderDetail.getLocationId());
            stockQueryWrapper.eq(TMiStock::getStorageId, outboundOrderDetail.getStorageId());
            stockQueryWrapper.eq(TMiStock::getShelvesNum, outboundOrderDetail.getShelvesNum());
            matchedStock = tMiStockMapper.selectOne(stockQueryWrapper);
            if (matchedStock != null) {
                TRkWareNoticeTab noticeTab = new TRkWareNoticeTab();
                noticeTab.setStorageId(stockTransferOrder.getStorageId());
                noticeTab.setStorageShortName(stockTransferOrder.getStorageShortName());
                noticeTab.setRecNum(outboundOrderDetail.getShelvesNum());
                noticeTab.setArraMount(matchedStock.getShelvesNum());
                noticeTab.setRecNumNow(outboundOrderDetail.getShelvesNum());
                noticeTab.setId(OrderCodeFactory.getOrderCode("TR", ""));
                noticeTab.setNoticeId(virtualInboundNotice.getId());
                noticeTab.setGoodsId(outboundOrderDetail.getGoodsId());
                noticeTab.setGoodsName(outboundOrderDetail.getGoodsName());
                noticeTab.setUnit(outboundOrderDetail.getUnit());
                noticeTab.setSpecification(outboundOrderDetail.getSpecification());
                noticeTab.setAbc(outboundOrderDetail.getAbc());
                noticeTab.setApplicant(SecurityUtils.getUserNick());
                noticeTab.setCreateBy(SecurityUtils.getUserNick());
                noticeTab.setLevelType("1");
                noticeTab.setCtl(outboundOrderDetail.getCtl());
                noticeTab.setCreateTime(new Date());
                //已经收货
                noticeTab.setInStatus("2");
                //来源单号
                noticeTab.setSalesOrderNumber(generateUniqueSalesOrderNumber());
                noticeTabsToInsert.add(noticeTab);

                //通知明显
                if (insertedNoticeCount >= 1) {
                    tRkWareNoticeMapper.batchTRkWareNoticeTab(noticeTabsToInsert);
                }
                tMiStockMapper.deleteById(matchedStock.getId());
                //删除 库存等待过账
            } else {
                resultMap.put("error", "暂无库存信息");
                return resultMap;
            }
        }
        // 所有明细单插入完成后调用
        TRkWareNoticeTabUpdate iwmsPushRequest = new TRkWareNoticeTabUpdate();
        iwmsPushRequest.setId(virtualInboundNotice.getId());

        /*Map<String, String> iwmsPushResult = sendIwmsUnified(iwmsPushRequest);
        if (iwmsPushResult.get("code").equals("0")) {
            //删除库存 过账
            if (matchedStock != null) {
                tMiStockMapper.deleteById(matchedStock);
            }
            resultMap.put("success", "机器人收货成功");
        } else {
            resultMap.put("error", "操作失败请联系管理员");
        }*/


        resultMap.put("success", "机器人上架");
        return resultMap;
    }

    @Override
    public Map<String, String> workshopReturn(TckOrdersBak returnOrder) {
        Map<String, String> resultMap = new HashMap<String, String>();

        if (ObjectUtils.isEmpty(returnOrder.getTckOrderdetailBakList())) {
            resultMap.put("error", "物料列表为空");
            return resultMap;
        }

        // 生成入库通知单
        TRkWareNotice returnInboundNotice = new TRkWareNotice();
        returnInboundNotice.setId(OrderCodeFactory.getOrderCode("", ""));
        returnInboundNotice.setNoticeId(OrderCodeFactory.getOrderCode("TWO", ""));
        returnInboundNotice.setUpdateBy(returnOrder.getApplicant());
        returnInboundNotice.setUpdateTime(new Date());
        returnInboundNotice.setCreateBy(returnOrder.getApplicant());
        returnInboundNotice.setCreateTime(new Date());
        returnInboundNotice.setStorageMode("2");
        returnInboundNotice.setReceivingStatus("0");
        returnInboundNotice.setApplicant(SecurityUtils.getUserNick());
        returnInboundNotice.setSendeDate(DateUtils.getDate());
        returnInboundNotice.setDeptId(returnOrder.getDeptId());

        String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        Date currentTime = new Date();
        String timestampMillis = String.valueOf(currentTime.getTime());
        SimpleDateFormat timeFormatter = new SimpleDateFormat("HHmmss");
        String formattedTime = timeFormatter.format(currentTime);
        String randomSuffixLetter = String.valueOf(alphabet.charAt(random.nextInt(25)));

        // String deliveryId = String.valueOf(Math.floor(1000 + Math.random() * 9000));
        String deliveryId = timestampMillis + formattedTime + randomSuffixLetter;
        returnInboundNotice.setDeliveryId(deliveryId);
        tRkWareNoticeMapper.insertTRkWareNotice(returnInboundNotice);

        // 入库通知单明细
        List<TRkWareNoticeTab> noticeTabsToInsert = new ArrayList<TRkWareNoticeTab>();

        // 遍历提交的物料数据明细
        int subDemandSequence = 0;
        for (TckOrderdetailBak returnOrderDetail : returnOrder.getTckOrderdetailBakList()) {

            if (returnOrderDetail.getTrNum().compareTo(returnOrderDetail.getRecNumNow()) < 0) {
                resultMap.put("error", "退库数量不能大于出库数量，物料【" + returnOrderDetail.getGoodsName() + "】");
                return resultMap;
            }

            TRkWareNoticeTab noticeTabToInsert = new TRkWareNoticeTab();

            // 物料编码
            noticeTabToInsert.setGoodsId(returnOrderDetail.getGoodsId());
            noticeTabToInsert.setGoodsName(returnOrderDetail.getGoodsName());
            noticeTabToInsert.setSpecification(returnOrderDetail.getSpecification());
            noticeTabToInsert.setUnit(returnOrderDetail.getUnit());
            noticeTabToInsert.setRecoil(returnOrderDetail.getRecoil());
            noticeTabToInsert.setArraMount(returnOrderDetail.getRecNumNow());
            noticeTabToInsert.setStorageId(returnOrderDetail.getStorageId());
            noticeTabToInsert.setStorageShortName(returnOrderDetail.getStorageShortName());
            noticeTabToInsert.setStorageLocation(returnOrderDetail.getLocationId());
            noticeTabToInsert.setGoodsTypeId(returnOrderDetail.getGoodsTypeId());
            noticeTabToInsert.setApplicant(returnOrder.getApplicant());
            noticeTabToInsert.setBarcode(returnOrderDetail.getBarcode());

            // 子需求编号
            noticeTabToInsert.setSalesOrderNumber(String.valueOf(subDemandSequence));
            subDemandSequence++;
            // 在途
            noticeTabToInsert.setReceivingStatus("0");
            // 冻结
            noticeTabToInsert.setInStatus("0");
            noticeTabToInsert.setRecNumNow(noticeTabToInsert.getRecNum());
            noticeTabToInsert.setUpdateBy(returnOrder.getRecordPerson());
            noticeTabToInsert.setUpdateTime(new Date());
            noticeTabToInsert.setCreateBy(returnOrder.getRecordPerson());
            noticeTabToInsert.setCreateTime(new Date());
            noticeTabToInsert.setNoticeId(returnInboundNotice.getId());
            noticeTabToInsert.setId(OrderCodeFactory.getOrderCode("TRKTAB", ""));
            noticeTabToInsert.setLevelType("1");
            noticeTabsToInsert.add(noticeTabToInsert);
        }

        if (noticeTabsToInsert.size() > 0) {
            // 入库通知单明细批量插入
            tRkWareNoticeMapper.batchTRkWareNoticeTab(noticeTabsToInsert);
        }

        resultMap.put("deliveryId", deliveryId);
        resultMap.put("noticeId", returnInboundNotice.getNoticeId());
        resultMap.put("id", returnInboundNotice.getId());
        resultMap.put("success", "车间退货入库");
        resultMap.put("error", "");

        return resultMap;
    }
}
