package com.hzya.frame.plugin.lets.plugin.sales;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.hzya.frame.base.PluginBaseEntity;
import com.hzya.frame.beanutil.BeanUtil;
import com.hzya.frame.plugin.lets.constant.OverallConstant;
import com.hzya.frame.plugin.lets.constant.ProfilesActiveConstant;
import com.hzya.frame.plugin.lets.entity.*;
import com.hzya.frame.plugin.lets.ofs.dao.ITocofsReturngoodsDao;
import com.hzya.frame.plugin.lets.ofs.dao.ITocofsReturngoodsDetailedDao;
import com.hzya.frame.plugin.lets.ofs.entity.TocofsReturngoodsDetailedEntity;
import com.hzya.frame.plugin.lets.ofs.entity.TocofsReturngoodsEntity;
import com.hzya.frame.plugin.lets.ofs.entity.TocofsSaleoutDetailedEntity;
import com.hzya.frame.plugin.lets.ofsvo.QueryOfsSoSaleOutVo;
import com.hzya.frame.plugin.lets.queryvo.StartAndEndVo;
import com.hzya.frame.plugin.lets.resultvo.CacheTocMapVoV2;
import com.hzya.frame.plugin.lets.resultvo.CalculateDateVo;
import com.hzya.frame.plugin.lets.u8cdto.*;
import com.hzya.frame.plugin.lets.util.*;
import com.hzya.frame.split.SplitListByCountUtil;
import com.hzya.frame.ttxofs.dto.ofssaleorderoutsearch.HeaderDetailsDto;
import com.hzya.frame.ttxofs.dto.ofssaleorderoutsearch.HeaderDto;
import com.hzya.frame.ttxofs.dto.ofssalesordersearch.DetailsDto;
import com.hzya.frame.ttxofs.dto.returngoodordersearch.RerturnGoodsOrderSearchData;
import com.hzya.frame.ttxofs.dto.returngoodordersearch.RerturnGoodsOrderSearchDetails;
import com.hzya.frame.ttxofs.dto.returngoodordersearch.RerturnGoodsOrderSearchHeader;
import com.hzya.frame.ttxofs.dto.stock.StockinOrderSearchResponse;
import com.hzya.frame.ttxofs.service.OfsUnifiedService;
import com.hzya.frame.u8c.ax.entity.Ass;
import com.hzya.frame.web.entity.JsonResultEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors;

/**
 * OFS售后入库单(TOC)生成U8C红字销售订单、交易成功关联原单
 *
 * @author makejava
 * @since 2023-08-16 15:49:55
 */
public class SoSaleReturnPluginInitializerToC extends PluginBaseEntity {

    Logger logger = LoggerFactory.getLogger(SoSaleReturnPluginInitializerToC.class);

    private static final ReentrantLock LOCK = new ReentrantLock(true);

    private static final String STOCK = "stock";

    private static final String TRAN = "tran";

    private static final String PROD_FILED = "prod";

    @Override
    public void initialize() {
        logger.info(getPluginLabel() + "執行初始化方法initialize()");
    }

    @Override
    public void destroy() {
        logger.info(getPluginLabel() + "執行銷毀方法destroy()");
    }

    @Override
    public String getPluginId() {
        return "sales.SoSaleReturnPluginInitializerToC";
    }

    @Override
    public String getPluginName() {
        return "OFS售后入库单(TOC)生成U8C红字销售订单";
    }

    @Override
    public String getPluginLabel() {
        return "OFS售后入库单(TOC)生成U8C红字销售订单";
    }

    @Override
    public String getPluginType() {
        return "3";
    }

    @Override
    public JsonResultEntity executeBusiness(JSONObject requestJson) throws Exception {
        long startMillis = System.currentTimeMillis();
        logger.info("executeBusiness方法调用开始：" + getPluginName() + "-插件");

        try {
            String param = String.valueOf(requestJson.get("param"));
            String sceneType = String.valueOf(requestJson.get("sceneType"));//sceneType：stock、tran
            if (ProfilesActiveConstant.TYPE_VBILLCODE.equals(requestJson.get("type"))) {
                //按单号
                if (param != null && !"".equals(param)) {
                    startImplementByCode(param, sceneType);
                }
            } else if (ProfilesActiveConstant.TYPE_TIME_FRAME.equals(requestJson.get("type"))) {
                //前台页面功能日期推送，或者接口调用也行
                String craeteDateStr = computingTime(param);
                if (craeteDateStr != null && !"".equals(craeteDateStr)) {
                    splitDateAndPush(craeteDateStr, sceneType);
                }
            } else {
                if (ProfilesActiveConstant.LETS_PROFILES_ACTIVE.equals(PROD_FILED)) {
                    //默认被定时器执行，每天晚上凌晨0点5分
                    //暂定先同步TOC销售库存、再推送TOC销售确认收入
                    List<StartAndEndVo> startAndEndVos = calculateCalculateEntireDayPeriod(null);
                    startImplementStockByTime(startAndEndVos.get(0).getStart_time(), startAndEndVos.get(0).getEnd_time());
                    startImplementByTradeTime(startAndEndVos.get(0).getStart_time(), startAndEndVos.get(0).getEnd_time());
                }
            }
        } catch (Exception e) {
            logger.error("executeBusiness方法异常", e);
        }
        long endMillis = System.currentTimeMillis();
        logger.info("executeBusiness方法调用结束：" + getPluginName() + "-插件 执行耗时：{}", (endMillis - startMillis));
        return null;
    }

    @Autowired
    private OfsUnifiedService ofsUnifiedService;

    @Autowired
    private QueryBdBusitypeUtil queryBdBusitypeUtil;

    private static final String NOTHING = "无";

    private static final String ADD = "@0216@";

    @Autowired
    private ITocofsReturngoodsDao iTocofsReturngoodsDao;

    @Autowired
    private ITocofsReturngoodsDetailedDao iTocofsReturngoodsDetailedDao;

    @Autowired
    private TocReturnBasicArchivesCacheUtil tocReturnBasicArchivesCacheUtil;

    @Autowired
    private ShopTobOrToCUtil shopTobOrToCUtil;

    @Autowired
    private OfsStandardUtil ofsStandardUtil;

    @Autowired
    private AfterSalesOrderUtil afterSalesOrderUtil;

    @Autowired
    private RdclUtil rdclUtil;

    /**
     * 库存同步，根据时间范围拉取
     *
     * @author liuyang
     */
    public void startImplementStockByTime(String startTime, String endTime) {
        long startMillis = System.currentTimeMillis();
        String threadNameStrStart = StrUtil.format("开始-OFS销售出库(TOC)同步U8C销售订单 开始时间：{} 结束时间：{}", startTime, endTime);
        logger.info(threadNameStrStart);

        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                LOCK.lock();
                try {
                    Assert.notNull(startTime, "开始时间不能为空");
                    Assert.notNull(endTime, "结束时间不能为空");

                    String tocShop = shopTobOrToCUtil.getCommaShop("TOC");
//                    CalculateDateVo calculateDateVo = DateStrUtil.calculateCalculateEntireDayPeriod(dateStr);

                    List<StockinOrderSearchResponse.StockinOrder> returnGoodHeaderDetailsDataDtoArrayList = new ArrayList<>();
                    QueryOfsSoSaleOutVo queryOfsSoSaleOutVo = new QueryOfsSoSaleOutVo();
                    queryOfsSoSaleOutVo.setCreated_start(startTime);
                    queryOfsSoSaleOutVo.setCreated_end(endTime);
                    queryOfsSoSaleOutVo.setClientCode("LETS");
                    queryOfsSoSaleOutVo.setInternalInstructionType("SALES");
                    //2024年8月22日 14:02:13 已经和O确认，这个字段取消传递！
//                    queryOfsSoSaleOutVo.setCompanyCode("SHLZ");
                    queryOfsSoSaleOutVo.setStatus(900L);
                    queryOfsSoSaleOutVo.setPageNo(1L);
                    queryOfsSoSaleOutVo.setPageSize(50L);
                    queryOfsSoSaleOutVo.setStoreCode(tocShop);
                    queryOfsSoSaleOutVo.setInternalInstructionType("RETURN");
//                    queryOfsSoSaleOutVo.setCode("LETS-RE2024071600000001");
                    ofsStandardUtil.queryOfsReturnGoods(queryOfsSoSaleOutVo, returnGoodHeaderDetailsDataDtoArrayList, 1L, "ofs.receipt.search");
                    logger.info("TOC退货数据返回行数：{}", returnGoodHeaderDetailsDataDtoArrayList.size());
                    if (returnGoodHeaderDetailsDataDtoArrayList.size() > 0) {
                        getSetStock(returnGoodHeaderDetailsDataDtoArrayList);
                    } else {
                        logger.info("没有查询到任何数据！不需要同步");
                    }
                } catch (Exception e) {
                    logger.error("startImplement方法抛出异常", e);
                } finally {
//                    try {
//                        tocReturnBasicArchivesCacheUtil.clearCache();
//                    } catch (Exception e) {
//                        logger.info("清理档案缓存失败", e);
//                    }
                    LOCK.unlock();
                }
            }
        }, threadNameStrStart);
        thread.start();
        try {
            thread.join();
        } catch (Exception e) {
            logger.error("thread.join()异常", e);
        }
        long endMillis = System.currentTimeMillis();
        String threadNameStrEnd = StrUtil.format("结束-OFS销售出库(TOC)同步U8C销售订单 开始时间：{} 结束时间：{} 耗时：{}", startTime, endTime, (endMillis - startMillis));
        logger.info(threadNameStrEnd);
    }

    /**
     * 根据编码、场景类型拉取
     *
     * @param code      编码
     * @param sceneType 场景类型
     * @author liuyang
     */
    public void startImplementByCode(String code, String sceneType) {
        long startMillis = System.currentTimeMillis();
        String threadNameStrStart = StrUtil.format("开始-OFS销售出库(TOC)同步U8C销售订单 同步单据号：{} 业务场景：{}", code, sceneType);
        logger.info(threadNameStrStart);

        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                LOCK.lock();
                try {
                    Assert.notNull(code, "code不能为空");
                    Assert.notNull(sceneType, "sceneType不能为空");

                    String tocShop = shopTobOrToCUtil.getCommaShop("TOC");

                    List<StockinOrderSearchResponse.StockinOrder> returnGoodHeaderDetailsDataDtoList = new ArrayList<>();
                    QueryOfsSoSaleOutVo queryOfsSoSaleOutVo = new QueryOfsSoSaleOutVo();
                    queryOfsSoSaleOutVo.setClientCode("LETS");
                    queryOfsSoSaleOutVo.setInternalInstructionType("SALES");
                    queryOfsSoSaleOutVo.setStatus(900L);
                    queryOfsSoSaleOutVo.setPageNo(1L);
                    queryOfsSoSaleOutVo.setPageSize(50L);
                    queryOfsSoSaleOutVo.setStoreCode(tocShop);
                    queryOfsSoSaleOutVo.setCode(code);
                    queryOfsSoSaleOutVo.setInternalInstructionType("RETURN");
                    ofsStandardUtil.queryOfsReturnGoods(queryOfsSoSaleOutVo, returnGoodHeaderDetailsDataDtoList, 1L, "ofs.receipt.search");
                    logger.info("数据返回行数：{}", returnGoodHeaderDetailsDataDtoList.size());
                    if (returnGoodHeaderDetailsDataDtoList.size() > 0) {
                        if (sceneType.equals("stock")) {
                            getSetStock(returnGoodHeaderDetailsDataDtoList);
                        } else if (sceneType.equals("tran")) {
                            getSetTran(returnGoodHeaderDetailsDataDtoList);
                        }
                    } else {
                        logger.info("没有查询到任何数据！不需要同步");
                    }
                } catch (Exception e) {
                    logger.error("startImplement方法抛出异常", e);
                } finally {
//                    try {
//                        tocReturnBasicArchivesCacheUtil.clearCache();
//                    } catch (Exception e) {
//                        logger.info("清理档案缓存失败", e);
//                    }
                    LOCK.unlock();
                }
            }
        }, threadNameStrStart);
        thread.start();
        try {
            thread.join();
        } catch (Exception e) {
            logger.error("thread.join()异常", e);
        }
        long endMillis = System.currentTimeMillis();
        String threadNameStrEnd = StrUtil.format("结束-OFS销售出库(TOC)同步U8C销售订单 同步单据号：{} 业务场景：{} 耗时：{}", code, sceneType, (endMillis - startMillis));
        logger.info(threadNameStrEnd);
    }

    /**
     * 交易采购，按指定时间拉取
     *
     * @author liuyang
     */
    public void startImplementByTradeTime(String startTime, String endTime) {
        long startMillis = System.currentTimeMillis();
        String threadNameStrStart = StrUtil.format("OFS售后入库(TOB)同步U8C销售订单(库存同步) 开始时间：{} 结束时间：{}", startTime, endTime);
        logger.info(threadNameStrStart);

        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Assert.notNull(startTime, "startTime不能为空");
                    Assert.notNull(endTime, "endTime不能为空");
                    //生成一个时间范围
//                    StartAndEndVo startAndEndVo = offsetTimeTime.offsetTime();
                    //2024年8月19日 15:47:51 查询出U8C里标记的店铺TOB属性
                    String tocShop = shopTobOrToCUtil.getCommaShop("TOC");

                    List<StockinOrderSearchResponse.StockinOrder> returnGoodHeaderDetailsDataDtoArrayList = new ArrayList<>();
                    QueryOfsSoSaleOutVo queryOfsSoSaleOutVo = new QueryOfsSoSaleOutVo();
                    queryOfsSoSaleOutVo.setRefundedAt_start(startTime);
                    queryOfsSoSaleOutVo.setRefundedAt_end(endTime);
                    queryOfsSoSaleOutVo.setClientCode("LETS");
                    queryOfsSoSaleOutVo.setPageNo(1L);
                    queryOfsSoSaleOutVo.setPageSize(50L);
                    queryOfsSoSaleOutVo.setStoreCode(tocShop);
                    queryOfsSoSaleOutVo.setInternalInstructionType("RETURN");
                    queryOfsSoSaleOutVo.setRefundStatus("900");
//                    queryOfsSoSaleOutVo.setCode("LETS-RE2024081900000001");
                    ofsStandardUtil.queryOfsReturnGoods(queryOfsSoSaleOutVo, returnGoodHeaderDetailsDataDtoArrayList, 1L, "ofs.receipt.search");
                    logger.info("数据返回行数：{}", returnGoodHeaderDetailsDataDtoArrayList.size());
                    if (returnGoodHeaderDetailsDataDtoArrayList.size() > 0) {
                        getSetTran(returnGoodHeaderDetailsDataDtoArrayList);
                    } else {
                        logger.info("没有查询到任何数据！不需要同步");
                    }
                } catch (Exception e) {
                    logger.error("startImplement方法抛出异常", e);
                }
            }
        }, threadNameStrStart);
        thread.start();
        try {
            thread.join();
        } catch (Exception e) {
            logger.error("thread.join()异常", e);
        }
        long endMillis = System.currentTimeMillis();
        String threadNameStrEnd = StrUtil.format("OFS售后入库(TOB)同步U8C销售订单(库存同步) 开始时间：{} 结束时间：{} 耗时：{}", startTime, endTime, (endMillis - startMillis));
        logger.info(threadNameStrEnd);
    }

    /**
     * 库存同步，预备执行逻辑
     *
     * @author liuyang
     */
    private void getSetStock(List<StockinOrderSearchResponse.StockinOrder> returnGoodHeaderDetailsDataDtoArrayList) throws Exception {
        //保存到mysql
        batchInsert(returnGoodHeaderDetailsDataDtoArrayList);
        //过滤成功的数据
        List<StockinOrderSearchResponse.StockinOrder> stockinOrderList = filterDataStock(returnGoodHeaderDetailsDataDtoArrayList);
        //执行推送主逻辑
        implementStock(stockinOrderList);
    }

    /**
     * 确认收入：预备执行逻辑
     *
     * @author liuyang
     */
    private void getSetTran(List<StockinOrderSearchResponse.StockinOrder> returnGoodHeaderDetailsDataDtoArrayList) throws Exception {
        //保存到mysql
        batchInsert(returnGoodHeaderDetailsDataDtoArrayList);
        //过滤成功的数据
        List<StockinOrderSearchResponse.StockinOrder> stockinOrderList = filterDataTran(returnGoodHeaderDetailsDataDtoArrayList);
        //执行推送主逻辑
        implementTran(stockinOrderList);
    }

    /**
     * 库存同步，过滤掉成功的数据
     *
     * @author liuyang
     */
    private List<StockinOrderSearchResponse.StockinOrder> filterDataStock(List<StockinOrderSearchResponse.StockinOrder> returnGoodHeaderDetailsDataDtoArrayList) throws Exception {
//        List<StockinOrderSearchResponse.StockinOrder> headerDetailsDtoList1 = new ArrayList<>();
        List<TocofsReturngoodsDetailedEntity> tocofsReturngoodsDetailedEntityList = new ArrayList<>();
        if (returnGoodHeaderDetailsDataDtoArrayList != null && returnGoodHeaderDetailsDataDtoArrayList.size() > 0) {
            List<List<StockinOrderSearchResponse.StockinOrder>> splitListByCount = SplitListByCountUtil.splitListByCount(returnGoodHeaderDetailsDataDtoArrayList, 100);
            for (int i = 0; i < splitListByCount.size(); i++) {
                List<StockinOrderSearchResponse.StockinOrder> stockinOrderList = splitListByCount.get(i);
                String idStr = commaConcatenatedPrimaryKeyStock(stockinOrderList);
                List<TocofsReturngoodsDetailedEntity> tocofsReturngoodsDetailedEntities = queryStockTocOutLog(idStr);
                tocofsReturngoodsDetailedEntityList.addAll(tocofsReturngoodsDetailedEntities);
            }
        }
        return filterDataRowsAsPushOrFailedStock(tocofsReturngoodsDetailedEntityList, returnGoodHeaderDetailsDataDtoArrayList);
    }

    /**
     * 确认收入，过滤掉成功的数据
     *
     * @author liuyang
     */
    private List<StockinOrderSearchResponse.StockinOrder> filterDataTran(List<StockinOrderSearchResponse.StockinOrder> returnGoodHeaderDetailsDataDtoArrayList) throws Exception {
        List<TocofsReturngoodsDetailedEntity> tocofsReturngoodsDetailedEntityList = new ArrayList<>();
        if (returnGoodHeaderDetailsDataDtoArrayList != null && returnGoodHeaderDetailsDataDtoArrayList.size() > 0) {
            List<List<StockinOrderSearchResponse.StockinOrder>> splitListByCount = SplitListByCountUtil.splitListByCount(returnGoodHeaderDetailsDataDtoArrayList, 100);
            for (int i = 0; i < splitListByCount.size(); i++) {
                List<StockinOrderSearchResponse.StockinOrder> stockinOrderList = splitListByCount.get(i);
                String idStr = commaConcatenatedPrimaryKeyStock(stockinOrderList);
                List<TocofsReturngoodsDetailedEntity> tocofsReturngoodsDetailedEntities = queryStockTocOutLog(idStr);
                tocofsReturngoodsDetailedEntityList.addAll(tocofsReturngoodsDetailedEntities);
            }
        }
        return filterDataRowsAsPushOrFailedTran(tocofsReturngoodsDetailedEntityList, returnGoodHeaderDetailsDataDtoArrayList);
    }

    /**
     * 逗号拼接字符串主键，作为批处理的一部分，方便下一步的批量查询操作
     *
     * @author liuyang
     */
    private String commaConcatenatedPrimaryKeyStock(List<StockinOrderSearchResponse.StockinOrder> headerDetailsDtoList2) throws Exception {
        StringBuffer idStr = new StringBuffer();
        if (headerDetailsDtoList2 != null && headerDetailsDtoList2.size() > 0) {
            for (int i = 0; i < headerDetailsDtoList2.size(); i++) {
                StockinOrderSearchResponse.StockinOrder stockinOrder = headerDetailsDtoList2.get(i);
                StockinOrderSearchResponse.StockinOrder.StockinH header = stockinOrder.getHeader();
                List<StockinOrderSearchResponse.StockinOrder.StockinB> details = stockinOrder.getDetails();
                for (int j = 0; j < details.size(); j++) {
                    StockinOrderSearchResponse.StockinOrder.StockinB stockinB = details.get(j);
                    Assert.notNull(stockinB.getId(), "O明细主键不能为空！");
                    Assert.state(!"".equals(stockinB.getId()), "O明细主键不能为空！");
                    idStr.append(stockinB.getId());
                    idStr.append(",");
                }
            }
        }
        if (idStr.length() > 0) {
            return idStr.substring(0, idStr.length() - 1);
        }
        return null;
    }

    /**
     * 批查询toc退货入库日志，查询的量由splitListByCount方法控制
     *
     * @author liuyang
     */
    private List<TocofsReturngoodsDetailedEntity> queryStockTocOutLog(String idStr) throws Exception {
        List<TocofsReturngoodsDetailedEntity> tocofsReturngoodsDetailedEntities = null;
        if (idStr != null && !"".equals(idStr.trim())) {
            TocofsReturngoodsDetailedEntity tocofsReturngoodsDetailedEntity = new TocofsReturngoodsDetailedEntity();
            tocofsReturngoodsDetailedEntity.setIds(idStr);
            tocofsReturngoodsDetailedEntities = iTocofsReturngoodsDetailedDao.query(tocofsReturngoodsDetailedEntity);
        } else {
            logger.error("idStr为空，无法查询数据！");
        }
        return tocofsReturngoodsDetailedEntities;
    }

    /**
     * 保存抓取到的数据到mysql底表，如果底表里已经存在，则会忽略
     *
     * @param returnGoodHeaderDetailsDataDtoArrayList mysql数据行
     */
    private void batchInsert(List<StockinOrderSearchResponse.StockinOrder> returnGoodHeaderDetailsDataDtoArrayList) throws Exception {
        if (returnGoodHeaderDetailsDataDtoArrayList != null && returnGoodHeaderDetailsDataDtoArrayList.size() > 0) {
            List<StockinOrderSearchResponse.StockinOrder.StockinH> headerDetailsDtoList1 = new ArrayList<>();
            List<StockinOrderSearchResponse.StockinOrder.StockinB> headerDetailsDtoList2 = new ArrayList<>();

            for (StockinOrderSearchResponse.StockinOrder index : returnGoodHeaderDetailsDataDtoArrayList) {
                StockinOrderSearchResponse.StockinOrder.StockinH header = index.getHeader();// 主表
                List<StockinOrderSearchResponse.StockinOrder.StockinB> details = index.getDetails();//明细表

                for (int i = 0; i < details.size(); i++) {
                    StockinOrderSearchResponse.StockinOrder.StockinB stockinB = details.get(i);
                    stockinB.setReturnGoodSearchHeaderDto(header);
                }

                headerDetailsDtoList1.add(header);
                headerDetailsDtoList2.addAll(details);
            }

            //每250作为一个批次插入主表，根据主键（id）判断是否重复，如果重复的，则不进行插入
            List<List<StockinOrderSearchResponse.StockinOrder.StockinH>> lists = SplitListByCountUtil.splitListByCount(headerDetailsDtoList1, 100);
            for (int i = 0; i < lists.size(); i++) {
                List<StockinOrderSearchResponse.StockinOrder.StockinH> stockinHS = lists.get(i);
                List<TocofsReturngoodsEntity> tocofsReturngoodsEntities = copyHeaderDto(stockinHS);
                if (tocofsReturngoodsEntities.size() > 0) {
                    logger.info("插入底表{}个对象（表头）", tocofsReturngoodsEntities.size());
                    iTocofsReturngoodsDao.entityInsertOrUpdateBatch(tocofsReturngoodsEntities);
                } else {
                    logger.info("tocofsReturngoodsEntities：没有对象被插入表头底表");
                }
            }

            //插入明细表
            List<List<StockinOrderSearchResponse.StockinOrder.StockinB>> lists1 = SplitListByCountUtil.splitListByCount(headerDetailsDtoList2, 100);
            for (int i = 0; i < lists1.size(); i++) {
                List<StockinOrderSearchResponse.StockinOrder.StockinB> stockinBS = lists1.get(i);
                List<TocofsReturngoodsDetailedEntity> tocofsReturngoodsDetailedEntities = copyDetailsDto(stockinBS);
                if (tocofsReturngoodsDetailedEntities.size() > 0) {
                    logger.info("插入底表{}个对象（表体）", tocofsReturngoodsDetailedEntities.size());
                    iTocofsReturngoodsDetailedDao.entityInsertOrUpdateBatch(tocofsReturngoodsDetailedEntities);
                } else {
                    logger.info("tocofsReturngoodsDetailedEntities：没有对象被插入表头底表");
                }
            }
        }
    }

    /**
     * 查询OFS售后退货入库单
     *
     * @param queryOfsSoSaleOutVo  查询参数
     * @param headerDetailsDtoList 查询结果集
     * @param pageNo               从第pageNo页开始查询
     */
//    private void queryOfsReturnGoods(QueryOfsSoSaleOutVo queryOfsSoSaleOutVo, List<ReturnGoodHeaderDetailsDataDto> headerDetailsDtoList, Long pageNo) throws Exception {
//
//        Long pageSize = 200L;
//        queryOfsSoSaleOutVo.setPageNo(pageNo);
//        queryOfsSoSaleOutVo.setPageSize(pageSize);
//
//        InterfaceParamDto interfaceParamDto = new InterfaceParamDto();
//        interfaceParamDto.setApi("ofs.receipt.search");
//        interfaceParamDto.setData(JSON.toJSONString(queryOfsSoSaleOutVo));
//        RertunGoodsRootBean rertunGoodsRootBean = (RertunGoodsRootBean) ofsUnifiedService.unified(interfaceParamDto);
//        if (rertunGoodsRootBean != null) {
//            if ("false".equals(rertunGoodsRootBean.getError()) && "0".equals(rertunGoodsRootBean.getCode()) && "Success".equals(rertunGoodsRootBean.getMsg())) {
//                List<ReturnGoodHeaderDetailsDataDto> returnGoodHeaderDetailsDataDtoList = rertunGoodsRootBean.getData();
//                if (returnGoodHeaderDetailsDataDtoList != null && returnGoodHeaderDetailsDataDtoList.size() > 0) {
//                    headerDetailsDtoList.addAll(returnGoodHeaderDetailsDataDtoList);
//
//                    //OFS没有提供分页字段，等待开发
//                }
//            } else {
//                logger.error("查询失败，失败原因:{}", JSON.toJSON(interfaceParamDto));
//            }
//        } else {
//            logger.error("rertunGoodsRootBean为空！interfaceParamDto对象的结果集json：{}", JSON.toJSON(interfaceParamDto));
//        }
//    }

//    public void queryOfsSaleOrder() throws Exception {
//        QueryOfsSoSaleOutVo queryOfsSoSaleOutVo = new QueryOfsSoSaleOutVo();
//        queryOfsSoSaleOutVo.setCreated_start("2024-07-05 16:38:00");
//        queryOfsSoSaleOutVo.setCreated_end("2024-07-05 16:40:30");
//        queryOfsSoSaleOutVo.setClientCode("LETS");
////        queryOfsSoSaleOutVo.setInternalInstructionType("SALES");
//        queryOfsSoSaleOutVo.setCompanyCode("SHLZ");
////        queryOfsSoSaleOutVo.setStatus(900L);
//        queryOfsSoSaleOutVo.setPageNo(1L);
//        queryOfsSoSaleOutVo.setPageSize(50L);
//        queryOfsSoSaleOutVo.setCode("LETS-SH2024070500000003");
//
//        InterfaceParamDto interfaceParamDto = new InterfaceParamDto();
//        interfaceParamDto.setApi("ofs.shipment.search");
//        interfaceParamDto.setData(JSON.toJSONString(queryOfsSoSaleOutVo));
//        SaleOutReturnMessageDto saleOutReturnMessageDto = (SaleOutReturnMessageDto) ofsUnifiedService.unified(interfaceParamDto);
//        System.out.println(saleOutReturnMessageDto);
//    }

    /**
     * 库存同步，代码同步逻辑
     *
     * @param returnGoodHeaderDetailsDataDtoList1 查询得到的O售后入库单对象
     * @author liuyang
     */
    private void implementStock(List<StockinOrderSearchResponse.StockinOrder> returnGoodHeaderDetailsDataDtoList1) throws Exception {
        if (returnGoodHeaderDetailsDataDtoList1 != null) {
            logger.info("TOC退货业务：{}行需要进行数据转换", returnGoodHeaderDetailsDataDtoList1.size());
        }
        if (returnGoodHeaderDetailsDataDtoList1 != null && returnGoodHeaderDetailsDataDtoList1.size() > 0) {
            try {
                // 查询基本档案
                String sceneType = "stock";
                List<GoodsRertunSonDetailsDto> goodsRertunSonDetailsDtos = queryBasicArchivesStock(returnGoodHeaderDetailsDataDtoList1, sceneType);
                // 分组汇总
                Map<String, List<GoodsRertunSonDetailsDto>> summaryDimensionMap = groupSummary(goodsRertunSonDetailsDtos);
                // 查询U8C业务流程
                BdBusitypeEntity bdBusitypeEntity = u8cOperationFlow();
                // 查询销售收发类别
//                BdRdclEntity bdRdclEntity = rdclUtil.queryRdClObject("202");

                if (bdBusitypeEntity != null && summaryDimensionMap != null) {
                    Iterator<Map.Entry<String, List<GoodsRertunSonDetailsDto>>> iterator = summaryDimensionMap.entrySet().iterator();
                    while (iterator.hasNext()) {
                        Map.Entry<String, List<GoodsRertunSonDetailsDto>> entry = iterator.next();
                        String keyGroup = entry.getKey();
                        List<GoodsRertunSonDetailsDto> oldValue = entry.getValue();

                        StockinOrderSearchResponse.StockinOrder.StockinH header = oldValue.get(0).getHeader();
                        BdCorpEntity bdCorpEntity = oldValue.get(0).getBdCorpEntity();//表头销售公司
                        BdCorpEntity deliverGoodsCorp = oldValue.get(0).getDeliverGoodsCorp();//发货公司
                        BdCalbodyEntity bdCalbodyEntity = oldValue.get(0).getBdCalbodyEntity();//发货仓库组织
                        BdStordocEntity bdStordocEntity = oldValue.get(0).getBdStordocEntity();//发货仓库
                        BdCalbodyEntity bdCalbodyEntity1 = oldValue.get(0).getBdCalbodyEntity1();//收货库存组织
                        BdStordocEntity bdStordocEntity1 = oldValue.get(0).getBdStordocEntity1();//收货仓库
                        BdSalestruEntity bdSalestruEntity = oldValue.get(0).getBdSalestruEntity();//销售组织
                        BdDeptdocEntity bdDeptdocEntity = oldValue.get(0).getBdDeptdocEntity();//业务部门
                        BdCumandocEntity bdCumandocEntity = oldValue.get(0).getBdCumandocEntity();//客商管理档案
                        BdCubasdocEntity bdCubasdocEntity = oldValue.get(0).getBdCubasdocEntity();//客商基本档案
                        BdDefdocEntity platformArchives = oldValue.get(0).getPlatformArchives();//U8C平台档案
                        BdDefdocEntity shopArchives = oldValue.get(0).getShopArchives();//U8C店铺档案
                        BdRdclEntity bdRdclEntity = oldValue.get(0).getBdRdclEntity();//U8C收发类别

                        try {
//                            checkArchives(oldValue.get(0));
                            //生成业务日期
                            String generateBusinessDate = createGenerateBusinessDate(header);

                            SaleorderRequestDto saleorderRequestDto = new SaleorderRequestDto();
                            SaleorderRequestParentDto saleorderRequestParentDto = new SaleorderRequestParentDto();
                            saleorderRequestParentDto.setDbilldate(generateBusinessDate);//单据日期
                            saleorderRequestParentDto.setBretinvflag("Y");//退货标记
                            saleorderRequestParentDto.setCbiztype(bdBusitypeEntity.getPkBusitype());//业务流程
                            saleorderRequestParentDto.setCcalbodyid(bdCalbodyEntity.getPkCalbody());//库存组织
                            saleorderRequestParentDto.setCcustomerid(bdCumandocEntity.getPkCumandoc());//客户=开票单位=收货单位=表体收货单位=收货单位
                            saleorderRequestParentDto.setCdeptid(bdDeptdocEntity.getPkDeptdoc());//部门
                            saleorderRequestParentDto.setCemployeeid(null);//业务员
                            saleorderRequestParentDto.setCoperatorid(OverallConstant.getOverAllValue("u8cApiZdrPK"));//制单人
                            saleorderRequestParentDto.setCreceiptcorpid(bdCumandocEntity.getPkCumandoc());//开票单位
                            saleorderRequestParentDto.setCreceiptcustomerid(bdCumandocEntity.getPkCumandoc());//收货单位
                            saleorderRequestParentDto.setCsalecorpid(bdSalestruEntity.getCsalestruid());//销售组织
                            saleorderRequestParentDto.setCwarehouseid(bdStordocEntity.getPkStordoc());//仓库
                            saleorderRequestParentDto.setDapprovedate(generateBusinessDate);//审核日期
                            saleorderRequestParentDto.setNdiscountrate("100.000000");//整单折扣
                            saleorderRequestParentDto.setPk_corp(bdCorpEntity.getPkCorp());//公司id
                            //汇总单号=汇总维度
                            saleorderRequestParentDto.setVdef18(keyGroup);
                            //平台
                            saleorderRequestParentDto.setPk_defdoc2(platformArchives.getPkDefdoc());
                            saleorderRequestParentDto.setVdef2(platformArchives.getDocname());
                            saleorderRequestParentDto.setVdef17(ProfilesActiveConstant.sourceSystem1);//来源系统

                            //收发类别
                            saleorderRequestParentDto.setPk_defdoc3(bdRdclEntity.getPkRdcl());
                            saleorderRequestParentDto.setVdef3(bdRdclEntity.getRdname());

                            //2024年8月8日 17:17:58 店铺档案自定义项1，先不传，后续维护好之后再传!
                            //店铺
                            saleorderRequestParentDto.setPk_defdoc1(shopArchives.getPkDefdoc());
                            saleorderRequestParentDto.setVdef1(shopArchives.getDocname());

                            saleorderRequestDto.setParentvo(saleorderRequestParentDto);

                            List<SaleorderRequestChildrenDto> saleorderRequestChildrenDtoList = new ArrayList<>();
                            saleorderRequestDto.setChildrenvo(saleorderRequestChildrenDtoList);

                            //把汇总好的出库单明细行合并成一行
                            GoodsRertunSonDetailsDto goodsRertunSonDetailsDto = groupMergeDetailedRows(oldValue);
                            //存货管理档案：取发货公司的存货管理档案
                            BdInvmandocEntity bdInvmandocEntity = oldValue.get(0).getBdInvmandocEntity();
                            //存货基础档案
                            BdInvbasdocEntity bdInvbasdocEntity = oldValue.get(0).getBdInvbasdocEntity();
                            //根据存货基础档案编码，查询当前存货的税率
                            BdTaxitemsEntity bdTaxitemsEntity1 = oldValue.get(0).getBdTaxitemsEntity();

                            String tax = "0." + new BigDecimal(bdTaxitemsEntity1.getTaxratio()).stripTrailingZeros().toPlainString();
                            BigDecimal noriginalcurprice = null;//无税单价
                            BigDecimal noriginalcurmny = null;//无税金额
                            BigDecimal noriginalcurtaxprice = null;//含税单价
                            BigDecimal noriginalcursummny = null;//价税合计
                            BigDecimal noriginalcurtaxmny = null;//税额=价税合计-无税金额
                            try {
                                noriginalcurtaxprice = goodsRertunSonDetailsDto.getGroupTotalPayAmount().divide(goodsRertunSonDetailsDto.getGroupShipQty(), 20, BigDecimal.ROUND_HALF_UP).setScale(4, BigDecimal.ROUND_HALF_UP);
                                noriginalcurprice = noriginalcurtaxprice.divide(new BigDecimal(1).add(new BigDecimal(tax)), 20, BigDecimal.ROUND_HALF_UP).setScale(4, BigDecimal.ROUND_HALF_UP);
                                noriginalcurmny = noriginalcurprice.multiply(goodsRertunSonDetailsDto.getGroupShipQty()).setScale(2, BigDecimal.ROUND_HALF_UP);
                                noriginalcursummny = noriginalcurtaxprice.multiply(goodsRertunSonDetailsDto.getGroupShipQty()).setScale(2, BigDecimal.ROUND_HALF_UP);
                                noriginalcurtaxmny = noriginalcursummny.subtract(noriginalcurmny).setScale(2, BigDecimal.ROUND_HALF_UP);
                            } catch (Exception e) {
                                logger.error("TOC金额计算错误", e);
                                Assert.state(false, "U8C红字销售订单，金额计算错误，原因：{}", e.getMessage());
                            }

                            //判断是否为赠品
                            Boolean isblargessflag = false;
                            if (noriginalcursummny.longValue() == 0) {
                                isblargessflag = true;
                            }

                            SaleorderRequestChildrenDto saleorderRequestChildrenDto = new SaleorderRequestChildrenDto();
                            saleorderRequestChildrenDto.setBlargessflag(isblargessflag);//是否赠品
                            saleorderRequestChildrenDto.setCadvisecalbodyid(bdCalbodyEntity.getPkCalbody());//发货库存组织
                            saleorderRequestChildrenDto.setCbodywarehouseid(bdStordocEntity.getPkStordoc());//发货仓库
                            saleorderRequestChildrenDto.setCconsigncorpid(deliverGoodsCorp.getPkCorp());//发货公司
                            saleorderRequestChildrenDto.setCcurrencytypeid("00010000000000000001");//币种
                            saleorderRequestChildrenDto.setCinventoryid(bdInvmandocEntity.getPkInvmandoc());//存货id
                            saleorderRequestChildrenDto.setCreceiptcorpid(bdCumandocEntity.getPkCumandoc());//收货单位
                            saleorderRequestChildrenDto.setDconsigndate(generateBusinessDate);//计划发货日期
                            saleorderRequestChildrenDto.setDdeliverdate(generateBusinessDate);//	要求收货日期
                            saleorderRequestChildrenDto.setNexchangeotobrate("1.00000000");//折本汇率
                            saleorderRequestChildrenDto.setNitemdiscountrate("100.000000");//单品折扣
                            saleorderRequestChildrenDto.setNnumber("-" + goodsRertunSonDetailsDto.getGroupShipQty().stripTrailingZeros().toPlainString());//数量
                            saleorderRequestChildrenDto.setNoriginalcurdiscountmny("0");//折扣额
                            saleorderRequestChildrenDto.setNoriginalcurmny("-" + noriginalcurmny.stripTrailingZeros().toPlainString());//无税金额
//                            saleorderRequestChildrenDto.setNoriginalcurnetprice(noriginalcurprice.stripTrailingZeros().toPlainString());//无税净价
//                            saleorderRequestChildrenDto.setNoriginalcurprice(noriginalcurprice.stripTrailingZeros().toPlainString());//无税单价
                            saleorderRequestChildrenDto.setNoriginalcursummny("-" + noriginalcursummny.stripTrailingZeros().toPlainString());//价税合计
                            saleorderRequestChildrenDto.setNoriginalcurtaxmny("-" + noriginalcurtaxmny.stripTrailingZeros().toPlainString());//税额
                            saleorderRequestChildrenDto.setNoriginalcurtaxnetprice(noriginalcurtaxprice.stripTrailingZeros().toPlainString());//含税净价
                            saleorderRequestChildrenDto.setNoriginalcurtaxprice(noriginalcurtaxprice.stripTrailingZeros().toPlainString());//含税单价
                            saleorderRequestChildrenDto.setNtaxrate(new BigDecimal(bdTaxitemsEntity1.getTaxratio()).stripTrailingZeros().toPlainString());//税率
                            saleorderRequestChildrenDtoList.add(saleorderRequestChildrenDto);

                            //销售订单单据推送到u8c
                            List<SaleorderRequestDto> saleorderRequestDtoList = new ArrayList<>();
                            saleorderRequestDtoList.add(saleorderRequestDto);
                            Map<String, List<SaleorderRequestDto>> stringStringMap = new HashMap<>();
                            stringStringMap.put("saleorder", saleorderRequestDtoList);
                            SoSaleResultRootDto soSaleResultRootDto = sendU8CTOCOrder(JSON.toJSONString(stringStringMap));
                            String vreceiptcode = null;
                            String pk_corp = null;
                            String csaleid = null;
                            if (soSaleResultRootDto != null && soSaleResultRootDto.getParentvo() != null) {
                                vreceiptcode = soSaleResultRootDto.getParentvo().getVreceiptcode();
                                pk_corp = soSaleResultRootDto.getParentvo().getPk_corp();
                                csaleid = soSaleResultRootDto.getParentvo().getCsaleid();
                            }
                            logger.info("TOC销售订单编号：{} 主键：{} 销售公司：{}", vreceiptcode, csaleid, pk_corp);
                            //记录成功
                            updateSuccessOrFail1(oldValue, "Y", "success", vreceiptcode, csaleid);
                        } catch (Exception e) {
                            logger.error("TOC退货业务转换成U8C对象过程中、或者单据推送到U8C出现异常！", e);
                            //记录失败
                            String message = e.getMessage();
                            if (message == null) {
                                message = "未知错误";
                            }
                            updateSuccessOrFail1(oldValue, "N", message, null, null);
                        }
                    }
                } else {
                    //2024年8月6日 11:28:54此处不记录失败，不认为是错误
                    logger.info("summaryDimensionMap变量或者bdBusitypeEntity变量为空，因此主要的推送逻辑不会被执行！");
                }
            } catch (Exception e) {
                logger.error("外层转换逻辑抛出异常", e);
                // 记录失败
            }
        }
    }

    /**
     * 到账成功：代码同步逻辑
     *
     * @param returnGoodHeaderDetailsDataDtoList1 查询得到的O售后入库单对象
     * @author liuyang
     */
    private void implementTran(List<StockinOrderSearchResponse.StockinOrder> returnGoodHeaderDetailsDataDtoList1) throws Exception {
        logger.info("TOC退货业务：{}行需要进行数据转换", returnGoodHeaderDetailsDataDtoList1.size());
        if (returnGoodHeaderDetailsDataDtoList1 != null && returnGoodHeaderDetailsDataDtoList1.size() > 0) {
            try {
                // 查询基本档案
                String sceneType = "tran";
                List<GoodsRertunSonDetailsDto> goodsRertunSonDetailsDtos = queryBasicArchivesStock(returnGoodHeaderDetailsDataDtoList1, sceneType);
                // 分组汇总
                Map<String, List<GoodsRertunSonDetailsDto>> summaryDimensionMap = groupSummary(goodsRertunSonDetailsDtos);
                // 查询U8C业务流程
                BdBusitypeEntity bdBusitypeEntity = u8cOperationFlowV2();

                if (bdBusitypeEntity != null && summaryDimensionMap != null) {
                    Iterator<Map.Entry<String, List<GoodsRertunSonDetailsDto>>> iterator = summaryDimensionMap.entrySet().iterator();
                    while (iterator.hasNext()) {
                        Map.Entry<String, List<GoodsRertunSonDetailsDto>> entry = iterator.next();
                        String keyGroup = entry.getKey();
                        List<GoodsRertunSonDetailsDto> oldValue = entry.getValue();

                        StockinOrderSearchResponse.StockinOrder.StockinH header = oldValue.get(0).getHeader();
                        BdCorpEntity bdCorpEntity = oldValue.get(0).getBdCorpEntity();//表头销售公司
                        BdCorpEntity deliverGoodsCorp = oldValue.get(0).getDeliverGoodsCorp();//发货公司
                        BdCalbodyEntity bdCalbodyEntity = oldValue.get(0).getBdCalbodyEntity();//发货仓库组织
                        BdStordocEntity bdStordocEntity = oldValue.get(0).getBdStordocEntity();//发货仓库
                        BdCalbodyEntity bdCalbodyEntity1 = oldValue.get(0).getBdCalbodyEntity1();//收货库存组织
                        BdStordocEntity bdStordocEntity1 = oldValue.get(0).getBdStordocEntity1();//收货仓库
                        BdSalestruEntity bdSalestruEntity = oldValue.get(0).getBdSalestruEntity();//销售组织
                        BdDeptdocEntity bdDeptdocEntity = oldValue.get(0).getBdDeptdocEntity();//业务部门
                        BdCumandocEntity bdCumandocEntity = oldValue.get(0).getBdCumandocEntity();//客商管理档案
                        BdCubasdocEntity bdCubasdocEntity = oldValue.get(0).getBdCubasdocEntity();//客商基本档案
                        BdDefdocEntity platformArchives = oldValue.get(0).getPlatformArchives();//U8C平台档案
                        BdDefdocEntity shopArchives = oldValue.get(0).getShopArchives();//U8C店铺档案
                        BdRdclEntity bdRdclEntity = oldValue.get(0).getBdRdclEntity();//U8C收发类别

                        try {
//                            checkArchives(oldValue.get(0));
                            //生成业务日期
                            String generateBusinessDate = createGenerateBusinessDate(header);

                            SaleorderRequestDto saleorderRequestDto = new SaleorderRequestDto();
                            SaleorderRequestParentDto saleorderRequestParentDto = new SaleorderRequestParentDto();
                            saleorderRequestParentDto.setDbilldate(generateBusinessDate);//单据日期
                            saleorderRequestParentDto.setBretinvflag("Y");//退货标记
                            saleorderRequestParentDto.setCbiztype(bdBusitypeEntity.getPkBusitype());//业务流程
                            saleorderRequestParentDto.setCcalbodyid(bdCalbodyEntity.getPkCalbody());//库存组织
                            saleorderRequestParentDto.setCcustomerid(bdCumandocEntity.getPkCumandoc());//客户=开票单位=收货单位=表体收货单位=收货单位
                            saleorderRequestParentDto.setCdeptid(bdDeptdocEntity.getPkDeptdoc());//部门
                            saleorderRequestParentDto.setCemployeeid(null);//业务员
                            saleorderRequestParentDto.setCoperatorid(OverallConstant.getOverAllValue("u8cApiZdrPK"));//制单人
                            saleorderRequestParentDto.setCreceiptcorpid(bdCumandocEntity.getPkCumandoc());//开票单位
                            saleorderRequestParentDto.setCreceiptcustomerid(bdCumandocEntity.getPkCumandoc());//收货单位
                            saleorderRequestParentDto.setCsalecorpid(bdSalestruEntity.getCsalestruid());//销售组织
                            saleorderRequestParentDto.setCwarehouseid(bdStordocEntity.getPkStordoc());//仓库
                            saleorderRequestParentDto.setDapprovedate(generateBusinessDate);//审核日期
                            saleorderRequestParentDto.setNdiscountrate("100.000000");//整单折扣
                            saleorderRequestParentDto.setPk_corp(bdCorpEntity.getPkCorp());//公司id
                            //汇总单号=汇总维度
                            saleorderRequestParentDto.setVdef18(keyGroup);
                            //平台
                            saleorderRequestParentDto.setPk_defdoc2(platformArchives.getPkDefdoc());
                            saleorderRequestParentDto.setVdef2(platformArchives.getDocname());
                            saleorderRequestParentDto.setVdef17(ProfilesActiveConstant.sourceSystem1);//来源系统

                            //收发类别
                            saleorderRequestParentDto.setPk_defdoc3(bdRdclEntity.getPkRdcl());
                            saleorderRequestParentDto.setVdef3(bdRdclEntity.getRdname());

                            //2024年8月8日 17:17:58 店铺档案自定义项1，先不传，后续维护好之后再传!
                            //店铺
                            saleorderRequestParentDto.setPk_defdoc1(shopArchives.getPkDefdoc());
                            saleorderRequestParentDto.setVdef1(shopArchives.getDocname());

                            saleorderRequestDto.setParentvo(saleorderRequestParentDto);

                            List<SaleorderRequestChildrenDto> saleorderRequestChildrenDtoList = new ArrayList<>();
                            saleorderRequestDto.setChildrenvo(saleorderRequestChildrenDtoList);

                            //把汇总好的出库单明细行合并成一行
                            GoodsRertunSonDetailsDto goodsRertunSonDetailsDto = groupMergeDetailedRows(oldValue);
                            //存货管理档案：取发货公司的存货管理档案
                            BdInvmandocEntity bdInvmandocEntity = oldValue.get(0).getBdInvmandocEntity();
                            //存货基础档案
                            BdInvbasdocEntity bdInvbasdocEntity = oldValue.get(0).getBdInvbasdocEntity();
                            //根据存货基础档案编码，查询当前存货的税率
                            BdTaxitemsEntity bdTaxitemsEntity1 = oldValue.get(0).getBdTaxitemsEntity();

                            String tax = "0." + new BigDecimal(bdTaxitemsEntity1.getTaxratio()).stripTrailingZeros().toPlainString();
                            BigDecimal noriginalcurprice = null;//无税单价
                            BigDecimal noriginalcurmny = null;//无税金额
                            BigDecimal noriginalcurtaxprice = null;//含税单价
                            BigDecimal noriginalcursummny = null;//价税合计
                            BigDecimal noriginalcurtaxmny = null;//税额=价税合计-无税金额
                            try {
                                noriginalcurtaxprice = goodsRertunSonDetailsDto.getGroupTotalPayAmount().divide(goodsRertunSonDetailsDto.getGroupShipQty(), 20, BigDecimal.ROUND_HALF_UP).setScale(4, BigDecimal.ROUND_HALF_UP);
                                noriginalcurprice = noriginalcurtaxprice.divide(new BigDecimal(1).add(new BigDecimal(tax)), 20, BigDecimal.ROUND_HALF_UP).setScale(4, BigDecimal.ROUND_HALF_UP);
                                noriginalcurmny = noriginalcurprice.multiply(goodsRertunSonDetailsDto.getGroupShipQty()).setScale(2, BigDecimal.ROUND_HALF_UP);
                                noriginalcursummny = noriginalcurtaxprice.multiply(goodsRertunSonDetailsDto.getGroupShipQty()).setScale(2, BigDecimal.ROUND_HALF_UP);
                                noriginalcurtaxmny = noriginalcursummny.subtract(noriginalcurmny).setScale(2, BigDecimal.ROUND_HALF_UP);
                            } catch (Exception e) {
                                logger.error("TOC退货-确认收入，金额计算错误", e);
                                Assert.state(false, "U8C红字销售订单，金额计算错误，原因：{}", e.getMessage());
                            }

                            //判断是否为赠品
                            Boolean isblargessflag = false;
                            if (noriginalcursummny.longValue() == 0) {
                                isblargessflag = true;
                            }

                            SaleorderRequestChildrenDto saleorderRequestChildrenDto = new SaleorderRequestChildrenDto();
                            saleorderRequestChildrenDto.setBlargessflag(isblargessflag);//是否赠品
                            saleorderRequestChildrenDto.setCadvisecalbodyid(bdCalbodyEntity.getPkCalbody());//发货库存组织
                            saleorderRequestChildrenDto.setCbodywarehouseid(bdStordocEntity.getPkStordoc());//发货仓库
                            saleorderRequestChildrenDto.setCconsigncorpid(deliverGoodsCorp.getPkCorp());//发货公司
                            saleorderRequestChildrenDto.setCcurrencytypeid("00010000000000000001");//币种
                            saleorderRequestChildrenDto.setCinventoryid(bdInvmandocEntity.getPkInvmandoc());//存货id
                            saleorderRequestChildrenDto.setCreceiptcorpid(bdCumandocEntity.getPkCumandoc());//收货单位
                            saleorderRequestChildrenDto.setDconsigndate(generateBusinessDate);//计划发货日期
                            saleorderRequestChildrenDto.setDdeliverdate(generateBusinessDate);//	要求收货日期
                            saleorderRequestChildrenDto.setNexchangeotobrate("1.00000000");//折本汇率
                            saleorderRequestChildrenDto.setNitemdiscountrate("100.000000");//单品折扣
                            saleorderRequestChildrenDto.setNnumber("-" + goodsRertunSonDetailsDto.getGroupShipQty().stripTrailingZeros().toPlainString());//数量
                            saleorderRequestChildrenDto.setNoriginalcurdiscountmny("0");//折扣额
                            saleorderRequestChildrenDto.setNoriginalcurmny("-" + noriginalcurmny.stripTrailingZeros().toPlainString());//无税金额
//                            saleorderRequestChildrenDto.setNoriginalcurnetprice(noriginalcurprice.stripTrailingZeros().toPlainString());//无税净价
//                            saleorderRequestChildrenDto.setNoriginalcurprice(noriginalcurprice.stripTrailingZeros().toPlainString());//无税单价
                            saleorderRequestChildrenDto.setNoriginalcursummny("-" + noriginalcursummny.stripTrailingZeros().toPlainString());//价税合计
                            saleorderRequestChildrenDto.setNoriginalcurtaxmny("-" + noriginalcurtaxmny.stripTrailingZeros().toPlainString());//税额
                            saleorderRequestChildrenDto.setNoriginalcurtaxnetprice(noriginalcurtaxprice.stripTrailingZeros().toPlainString());//含税净价
                            saleorderRequestChildrenDto.setNoriginalcurtaxprice(noriginalcurtaxprice.stripTrailingZeros().toPlainString());//含税单价
                            saleorderRequestChildrenDto.setNtaxrate(new BigDecimal(bdTaxitemsEntity1.getTaxratio()).stripTrailingZeros().toPlainString());//税率
                            saleorderRequestChildrenDtoList.add(saleorderRequestChildrenDto);

                            //销售订单单据推送到u8c
                            List<SaleorderRequestDto> saleorderRequestDtoList = new ArrayList<>();
                            saleorderRequestDtoList.add(saleorderRequestDto);
                            Map<String, List<SaleorderRequestDto>> stringStringMap = new HashMap<>();
                            stringStringMap.put("saleorder", saleorderRequestDtoList);
                            SoSaleResultRootDto soSaleResultRootDto = sendU8CTOCOrder(JSON.toJSONString(stringStringMap));

                            String vreceiptcode = null;
                            String pk_corp = null;
                            String csaleid = null;
                            if (soSaleResultRootDto != null && soSaleResultRootDto.getParentvo() != null) {
                                vreceiptcode = soSaleResultRootDto.getParentvo().getVreceiptcode();
                                pk_corp = soSaleResultRootDto.getParentvo().getPk_corp();
                                csaleid = soSaleResultRootDto.getParentvo().getCsaleid();
                            }
                            logger.info("TOC销售订单编号：{} 销售订单主键：{} 销售公司：{}", vreceiptcode, csaleid, pk_corp);
                            //记录成功
                            updateSuccessOrFail2(oldValue, "Y", "success", vreceiptcode, csaleid);
                        } catch (Exception e) {
                            logger.error("TOC退货业务转换成U8C对象过程中、或者单据推送到U8C出现异常！", e);
                            //记录失败
                            String message = e.getMessage();
                            if (message == null) {
                                message = "未知错误";
                            }
                            updateSuccessOrFail2(oldValue, "N", message, null, null);
                        }
                    }
                } else {
                    //2024年8月6日 11:28:54此处不记录失败，不认为是错误
                    logger.info("summaryDimensionMap变量或者bdBusitypeEntity变量为空，因此主要的推送逻辑不会被执行！");
                }
            } catch (Exception e) {
                logger.error("外层转换逻辑抛出异常", e);
                // 记录失败
            }
        }
    }

    /**
     * 2024年8月9日 15:43:13
     * 生成业务日期：取「入库时间」、还是取「结束收货时间」
     *
     * @author liuyang
     */
    private String createGenerateBusinessDate(StockinOrderSearchResponse.StockinOrder.StockinH header) {
        if (header != null && header.getCheckInTo() != null) {
            //TOC以出库日期作为业务日期
            String checkInTo = header.getCheckInTo();
            String businessFormat = null;
            try {
                Date dbill = DateUtil.parse(checkInTo);
                businessFormat = DateUtil.format(dbill, "yyyy-MM-dd");
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("业务日期转换失败", e);
            }
            return businessFormat;
        } else {
            logger.error("生成入库日期失败，或者checkInTo为空! json：{}", JSON.toJSON(header));
            Assert.state(false, "生成入库日期失败，或者checkInTo为空! json：{}", JSON.toJSON(header));
            return null;
        }
    }

    /**
     * 档案转换(OFS->U8C)
     *
     * @param returnGoodHeaderDetailsDataDtoList1 OFS售后入库单对象
     * @author liuyang
     */
    private List<GoodsRertunSonDetailsDto> queryBasicArchivesStock(List<StockinOrderSearchResponse.StockinOrder> returnGoodHeaderDetailsDataDtoList1, String sceneType) {
        Assert.notNull(returnGoodHeaderDetailsDataDtoList1, "returnGoodHeaderDetailsDataDtoList1不能为空");
        Assert.notNull(sceneType, "sceneType不能为空");

        List<GoodsRertunSonDetailsDto> sonDetailsDtoList = new ArrayList<>();
        List<ErrorHeaderDetailsDtoDtoV2> errorHeaderDetailsDtoDtoList = new ArrayList<>();

        if (returnGoodHeaderDetailsDataDtoList1 != null && returnGoodHeaderDetailsDataDtoList1.size() > 0) {
            try {
                //初始化档案缓存
                CacheTocMapVoV2 cacheTocMapVoV2 = tocReturnBasicArchivesCacheUtil.initCache(returnGoodHeaderDetailsDataDtoList1);
                //查询OFS售后入库单对应的售后订单
                List<RerturnGoodsOrderSearchData> rerturnGoodsOrderSearchData = queryBatchAfterSalesOrder(returnGoodHeaderDetailsDataDtoList1);
                findAfterSalesOrder(rerturnGoodsOrderSearchData, returnGoodHeaderDetailsDataDtoList1);
                //查询OFS售后订单对应的OFS销售订单
                List<com.hzya.frame.ttxofs.dto.ofssalesordersearch.HeaderDetailsDto> headerDetailsDtos = queryBatchOfsOrder(returnGoodHeaderDetailsDataDtoList1);
                findOfsOrder(headerDetailsDtos, returnGoodHeaderDetailsDataDtoList1);

                for (int i = 0; i < returnGoodHeaderDetailsDataDtoList1.size(); i++) {
                    StockinOrderSearchResponse.StockinOrder stockinOrder = returnGoodHeaderDetailsDataDtoList1.get(i);
                    StockinOrderSearchResponse.StockinOrder.StockinH header = stockinOrder.getHeader();
                    List<StockinOrderSearchResponse.StockinOrder.StockinB> details = stockinOrder.getDetails();

                    try {
                        //OFS售后订单
                        RerturnGoodsOrderSearchData rerturnGoodsOrderSearchData1 = header.getRerturnGoodsOrderSearchData();
                        Assert.notNull(rerturnGoodsOrderSearchData1, "无法关联到OFS售后订单 售后入库单号：{}", header.getCode());
                        //OFS销售订单
                        com.hzya.frame.ttxofs.dto.ofssalesordersearch.HeaderDetailsDto headerDetailsDto = header.getHeaderDetailsDto();
                        com.hzya.frame.ttxofs.dto.ofssalesordersearch.HeaderDto header1 = headerDetailsDto.getHeader();
                        List<DetailsDto> details1 = headerDetailsDto.getDetails();
                        Assert.notNull(headerDetailsDto, "无法关联到OFS销售订单 售后入库单号：{}", header.getCode());

                        //如果不存在，则默认一个
                        if (header1.getSubOrderType() == null || "".equals(header1.getSubOrderType())) {
                            header1.setSubOrderType("SALES");
                        }
                        BdRdclEntity bdRdclEntity = cacheTocMapVoV2.getStringBdRdclEntityMap().get(header1.getSubOrderType());
                        Assert.notNull(bdRdclEntity, "根据业务类型({})没有匹配到U8C业务类型", header1.getSubOrderType());

                        //表头公司：通过名称匹配U8C公司
//                    String corpName = "上海丽知品牌管理有限公司";
                        //TODO 测试SHOF
                        header.setCompanyCode("SHOF");
                        Assert.notNull(header.getCompanyCode(), "O货主编码不能为空");
                        BdCorpEntity bdCorpEntity = cacheTocMapVoV2.getStringBdCorpEntityMap().get(header.getCompanyCode());
                        Assert.notNull(bdCorpEntity, "根据O公司编码(货主编码)({})没有匹配到U8C公司档案", header.getCompanyCode());

                        //发货库存组织
                        BdCalbodyEntity bdCalbodyEntity = cacheTocMapVoV2.getStringBdCalbodyEntityMap().get(bdCorpEntity.getPkCorp());
                        Assert.notNull(bdCalbodyEntity, "根据公司主键没有查询到发货库存组织 公司主键：{}", bdCorpEntity.getPkCorp());

                        //发货公司，暂时把O表头公司作为发货公司，正常情况下需要把O库存地点对于的公司作为发货公司

                        //发货仓库
                        //2024年8月5日 15:06:38 仓库O与U两边仓库编码是一致的，和妮姐确认过了
                        String facilityCode = header.getFacilityCode();
                        Assert.notNull(facilityCode, "O仓库编码不能为空");
                        BdStordocEntity bdStordocEntity = cacheTocMapVoV2.getStringBdStordocEntityMap().get(facilityCode + bdCalbodyEntity.getPkCalbody());
                        Assert.notNull(bdStordocEntity, "没有匹配到发货仓库 发货库存组织主键：{} O库存地点编码：{}", facilityCode, bdCalbodyEntity.getPkCalbody());

                        //2024年8月5日 15:25:07 收货库存组织、收货仓库、默认和发货库存组织、发货仓库一致，已经和佳妮确认
                        //收货库存组织：速网来看收货库存组织对应表头工具
                        //收货仓库：通过收货库存组织+仓库编码，确定收货仓库

                        //销售组织2024年8月5日 15:33:40 和妮姐确认，销售组织和表头公司，作为一对一的关系，
                        BdSalestruEntity bdSalestruEntity = cacheTocMapVoV2.getStringBdSalestruEntityMap().get(bdCorpEntity.getUnitname());
                        Assert.notNull(bdSalestruEntity, "无匹配到销售组织 表头公司名称：{}", bdCorpEntity.getUnitname());

                        //业务部门：暂定的部门名称：其他，2024年8月5日 15:39:42 已经和妮姐确认
                        BdDeptdocEntity bdDeptdocEntity = cacheTocMapVoV2.getStringBdDeptdocEntityMap().get(bdCorpEntity.getPkCorp());
                        Assert.notNull(bdDeptdocEntity, "无法匹配到业务部门 部门名称：其他 对应公司名称：{}", bdCorpEntity.getPkCorp());

                        //客商基本档案
                        //2024年8月8日 12:05:10 O店铺的业务编码=U8C客商自定义项1，O没有店铺信息查询接口，因此无法通过出库单的店铺编码，查询到O店铺档案对应的业务编码，接口上线之后需要补充这一部分逻辑
//                    String custName = "天猫intoyou旗舰店-自营";
                        String storeCode = header.getStoreCode();
                        Assert.notNull(storeCode, "O店铺编码不能为空，没有办法完成业务逻辑！");
                        Assert.state(!"".equals(storeCode.trim()), "O店铺编码不能为空，没有办法完成业务逻辑！");
                        BdCubasdocEntity bdCubasdocEntity = cacheTocMapVoV2.getStringBdCubasdocEntityMap().get(storeCode);
                        Assert.notNull(bdCubasdocEntity, "无法匹配到客户档案 客商名称：{}", storeCode);

                        //客商管理档案：2024年8月5日 15:41:54 TOC店铺名称查询U8C客商档案，已经和妮姐确认
                        //2024年8月5日 15:49:49 先根据O店铺编码，得到店铺档案信息，取到名称，通过U8C接口查询出来
                        //目前O店铺信息查询接口还没有，等待开发，所以我这里先写所一个名字
                        BdCumandocEntity bdCumandocEntity = cacheTocMapVoV2.getStringBdCumandocEntityMap().get(bdCubasdocEntity.getPkCubasdoc() + bdCorpEntity.getPkCorp());
                        Assert.notNull(bdCumandocEntity, "无法匹配到客商档案 店铺名称：{}", "天猫intoyou旗舰店-自营");

                        //查找平台
                        String sourcePlatformCode = header.getSourcePlatformCode();
                        Assert.notNull(sourcePlatformCode, "O平台编码不能为空！");
                        BdDefdocEntity bdDefdocEntity = cacheTocMapVoV2.getStringBdDefdocEntityMap().get(sourcePlatformCode);
                        Assert.notNull(bdDefdocEntity, "根据O平台编码({})无法匹配到U8C平台档案", header.getSourcePlatformCode());

                        //查找店铺
//                    String storeCode2 = header.getStoreCode();
//                    Assert.notNull(storeCode2, "O店铺编码不能为空！");
                        BdDefdocEntity bdDefdocEntity1 = cacheTocMapVoV2.getStringBdDefdocEntityMap1().get(storeCode);
                        Assert.notNull(bdDefdocEntity1, "根据O店铺编码({})无法匹配到U8C店铺档案", storeCode);

                        //字段拷贝
                        for (int j = 0; j < details.size(); j++) {
                            StockinOrderSearchResponse.StockinOrder.StockinB stockinB = details.get(j);

                            //存货管理档案，是发货公司的存货档案
                            BdInvmandocEntity bdInvmandocEntity = cacheTocMapVoV2.getStringBdInvmandocEntityMap().get(stockinB.getSkuCode() + bdCorpEntity.getPkCorp());
                            Assert.notNull(bdInvmandocEntity, "无法匹配到存货管理档案 货品sku：{} 公司：{}", stockinB.getSkuCode(), bdCorpEntity.getPkCorp());
                            //存货基本档案
                            BdInvbasdocEntity bdInvbasdocEntity = cacheTocMapVoV2.getStringBdInvbasdocEntityMap().get(stockinB.getSkuCode());
                            Assert.notNull(bdInvbasdocEntity, "无法匹配到存货基本档案 存货编码：{}", stockinB.getSkuCode());
                            //存货税率
                            BdTaxitemsEntity bdTaxitemsEntity = cacheTocMapVoV2.getStringBdTaxitemsEntityMap().get(bdInvmandocEntity.getInvcode());
                            Assert.notNull(bdTaxitemsEntity, "无法匹配到存货税率 存货编码：{}", bdInvmandocEntity.getInvcode());

                            //2024年8月6日 10:16:22 通过O出库单的表头，查询得出U8C档案，放在表体的原因是方便分组汇总
                            //下一个步骤的分组汇总，是通过表体明细完成的
                            GoodsRertunSonDetailsDto goodsRertunSonDetailsDto = new GoodsRertunSonDetailsDto();
                            goodsRertunSonDetailsDto.setHeader(header);
                            goodsRertunSonDetailsDto.setBdCorpEntity(bdCorpEntity);
                            goodsRertunSonDetailsDto.setDeliverGoodsCorp(bdCorpEntity);
                            goodsRertunSonDetailsDto.setBdCalbodyEntity(bdCalbodyEntity);
                            goodsRertunSonDetailsDto.setBdStordocEntity(bdStordocEntity);
                            goodsRertunSonDetailsDto.setBdCalbodyEntity1(bdCalbodyEntity);
                            goodsRertunSonDetailsDto.setBdStordocEntity1(bdStordocEntity);
                            goodsRertunSonDetailsDto.setBdSalestruEntity(bdSalestruEntity);
                            goodsRertunSonDetailsDto.setBdDeptdocEntity(bdDeptdocEntity);
                            goodsRertunSonDetailsDto.setBdCumandocEntity(bdCumandocEntity);
                            goodsRertunSonDetailsDto.setBdCubasdocEntity(bdCubasdocEntity);
                            goodsRertunSonDetailsDto.setPlatformArchives(bdDefdocEntity);
                            goodsRertunSonDetailsDto.setBdRdclEntity(bdRdclEntity);
                            goodsRertunSonDetailsDto.setShopArchives(bdDefdocEntity1);
                            goodsRertunSonDetailsDto.setBdInvmandocEntity(bdInvmandocEntity);
                            goodsRertunSonDetailsDto.setBdInvbasdocEntity(bdInvbasdocEntity);
                            goodsRertunSonDetailsDto.setBdTaxitemsEntity(bdTaxitemsEntity);

                            BeanUtil.copyPropertiesV2(stockinB, goodsRertunSonDetailsDto);
                            sonDetailsDtoList.add(goodsRertunSonDetailsDto);
                            //成功收集进入到集合
                        }
                    } catch (Exception e) {
                        logger.error("档案转换抛出异常", e);

                        //失败
                        String message = e.getMessage();
                        if (message == null) {
                            message = "未知错误";
                        }
                        ErrorHeaderDetailsDtoDtoV2 errorHeaderDetailsDtoDto = new ErrorHeaderDetailsDtoDtoV2();
                        errorHeaderDetailsDtoDto.setNewPushDate(getNewDateStr());
                        errorHeaderDetailsDtoDto.setNewTransmitInfo(message);
                        errorHeaderDetailsDtoDto.setNewstate("N");
                        errorHeaderDetailsDtoDto.setHeader(header);
                        errorHeaderDetailsDtoDto.setDetails(details);
                        errorHeaderDetailsDtoDtoList.add(errorHeaderDetailsDtoDto);
                    }
                }
            } catch (Exception e) {
                logger.error("OFS销售出库单关联查询U8C档案失败", e);
            }
        } else {
            logger.info("queryBasicArchives方法headerDetailsDtoList.size为0");
        }
        //错误日志同步到数据
        if (errorHeaderDetailsDtoDtoList.size() > 0) {
            updateFailOrSuccessTocofsSaleoutDetailedArchiveInquiry(errorHeaderDetailsDtoDtoList, sceneType);
        }
        return sonDetailsDtoList;
    }

    /**
     * 对象拷贝 bean copy
     * 2024年8月9日 11:23:57
     */
    private List<TocofsReturngoodsEntity> copyHeaderDto(List<StockinOrderSearchResponse.StockinOrder.StockinH> stockinHS) {
        List<TocofsReturngoodsEntity> tocofsReturngoodsEntityArrayList = new ArrayList<>();
        if (stockinHS != null && stockinHS.size() > 0) {
            for (int i = 0; i < stockinHS.size(); i++) {
                StockinOrderSearchResponse.StockinOrder.StockinH stockinH = stockinHS.get(i);

                TocofsReturngoodsEntity tocofsReturngoodsEntity = new TocofsReturngoodsEntity();
                BeanUtil.copyPropertiesV2(stockinH, tocofsReturngoodsEntity);
                tocofsReturngoodsEntityArrayList.add(tocofsReturngoodsEntity);
            }
        } else {
            logger.info("需要复制{}个bean对象(O表头)", stockinHS.size());
        }
        return tocofsReturngoodsEntityArrayList;
    }

    /**
     * 对象拷贝 bean copy
     * 2024年8月9日 11:24:01
     */
    private List<TocofsReturngoodsDetailedEntity> copyDetailsDto(List<StockinOrderSearchResponse.StockinOrder.StockinB> stockinBS) {
        List<TocofsReturngoodsDetailedEntity> tocofsSaleoutDetailedEntityArrayList = new ArrayList<>();
        if (stockinBS != null && stockinBS.size() > 0) {
            for (int i = 0; i < stockinBS.size(); i++) {
                StockinOrderSearchResponse.StockinOrder.StockinB stockinB = stockinBS.get(i);

                //表头
                StockinOrderSearchResponse.StockinOrder.StockinH returnGoodSearchHeaderDto = stockinB.getReturnGoodSearchHeaderDto();

                TocofsReturngoodsDetailedEntity tocofsReturngoodsDetailedEntity = new TocofsReturngoodsDetailedEntity();
                BeanUtil.copyPropertiesV2(stockinB, tocofsReturngoodsDetailedEntity);
                //补充额外的字段信息
                createPrimaryKeyAndBusinessDateAndBusinessType(tocofsReturngoodsDetailedEntity, returnGoodSearchHeaderDto);
                tocofsSaleoutDetailedEntityArrayList.add(tocofsReturngoodsDetailedEntity);
            }
        } else {
            logger.info("需要复制{}个bean对象(O表体)", tocofsSaleoutDetailedEntityArrayList.size());
        }
        return tocofsSaleoutDetailedEntityArrayList;
    }

    /**
     * 分组汇总：公司+店铺+仓库+SKU+出库类型，数量合并相加
     * 修改为：公司+店铺+仓库+SKU+收发类别+部门，数量合并相加
     *
     * @author liuyang
     */
    private Map<String, List<GoodsRertunSonDetailsDto>> groupSummary(List<GoodsRertunSonDetailsDto> goodsRertunSonDetailsDtos) {
        if (goodsRertunSonDetailsDtos != null && goodsRertunSonDetailsDtos.size() > 0) {
            for (int i = 0; i < goodsRertunSonDetailsDtos.size(); i++) {
                GoodsRertunSonDetailsDto goodsRertunSonDetailsDto = goodsRertunSonDetailsDtos.get(i);
                //2024年8月6日 10:35:25表头对象用于带出表头相关的分组汇总信息
                StockinOrderSearchResponse.StockinOrder.StockinH header = goodsRertunSonDetailsDto.getHeader();
                RerturnGoodsOrderSearchData rerturnGoodsOrderSearchData = header.getRerturnGoodsOrderSearchData();//OFS售后订单
                com.hzya.frame.ttxofs.dto.ofssalesordersearch.HeaderDetailsDto headerDetailsDto = header.getHeaderDetailsDto();//OFS销售订单

                //公司
                BdCorpEntity bdCorpEntity = goodsRertunSonDetailsDto.getBdCorpEntity();
                //店铺（主要是店铺编码）
                String storeCode = header.getStoreCode();
                //仓库
                String facilityCode = header.getFacilityCode();
                //SKU
                String skuCode = goodsRertunSonDetailsDto.getSkuCode();
                //出库类型
//                String refOrderType = header.getRefOrderType();
                //收发类别
                BdRdclEntity bdRdclEntity = goodsRertunSonDetailsDto.getBdRdclEntity();

                StringBuffer summaryDimensionStr = new StringBuffer();
                if (bdCorpEntity != null && bdCorpEntity.getPkCorp() != null) {
                    summaryDimensionStr.append(bdCorpEntity.getPkCorp());
                } else {
                    summaryDimensionStr.append(NOTHING);
                }
                summaryDimensionStr.append(ADD);

                if (storeCode != null && !"".equals(storeCode)) {
                    summaryDimensionStr.append(storeCode);
                } else {
                    summaryDimensionStr.append(NOTHING);
                }
                summaryDimensionStr.append(ADD);

                if (facilityCode != null && !"".equals(facilityCode)) {
                    summaryDimensionStr.append(facilityCode);
                } else {
                    summaryDimensionStr.append(NOTHING);
                }
                summaryDimensionStr.append(ADD);

                if (skuCode != null && !"".equals(skuCode)) {
                    summaryDimensionStr.append(skuCode);
                } else {
                    summaryDimensionStr.append(NOTHING);
                }
                summaryDimensionStr.append(ADD);

//                if (refOrderType != null && !"".equals(refOrderType)) {
//                    summaryDimensionStr.append(refOrderType);
//                } else {
//                    summaryDimensionStr.append(NOTHING);
//                }

                if (bdRdclEntity != null && bdRdclEntity.getRdcode() != null) {
                    summaryDimensionStr.append(bdRdclEntity.getRdcode());
                } else {
                    summaryDimensionStr.append(NOTHING);
                }

                //TODO 部门？O还未开发好，待定

                goodsRertunSonDetailsDto.setSummaryDimensionStr(summaryDimensionStr.toString());
            }
            logger.info("TOC：{} 个出库单对象需要汇总", goodsRertunSonDetailsDtos.size());
            return goodsRertunSonDetailsDtos.stream().collect(Collectors.groupingBy(GoodsRertunSonDetailsDto::getSummaryDimensionStr));
        }
        logger.info("TOC：0个对象需要汇总");
        return null;
    }

    /**
     * 2024年8月6日 10:59:03 查询U8C业务流程
     *
     * @author liuyang
     */
    private BdBusitypeEntity u8cOperationFlow() throws Exception {
        //查询业务流程
        //2024年8月6日 11:33:07 具体的业务流程名称，还需要实施提供
        String processName = "TOC销售";
        BdBusitypeEntity bdBusitypeEntity = queryBdBusitypeUtil.queryBdBusitype(processName);
        Assert.notNull(bdBusitypeEntity, "根据业务流程名称({})没有查询到业务流程", processName);
        return bdBusitypeEntity;
    }

    /**
     * 2024年8月6日 10:59:03 查询U8C业务流程
     *
     * @author liuyang
     */
    private BdBusitypeEntity u8cOperationFlowV2() throws Exception {
        //查询业务流程
        //2024年8月6日 11:33:07 具体的业务流程名称，还需要实施提供
        String processName = "TOC售后完成";
        BdBusitypeEntity bdBusitypeEntity = queryBdBusitypeUtil.queryBdBusitype(processName);
        Assert.notNull(bdBusitypeEntity, "根据业务流程名称({})没有查询到业务流程", processName);
        return bdBusitypeEntity;
    }

    /**
     * 检查参数是否为空
     * 2024年8月6日 11:40:19 保险的做法，最好还是验证一下
     *
     * @author liuyang
     */
    private void checkArchives(GoodsRertunSonDetailsDto sonDetailsDto) {
        Assert.notNull(sonDetailsDto, "sonDetailsDto不能为空 对象json：{}", JSON.toJSONString(sonDetailsDto));
        Assert.notNull(sonDetailsDto.getHeader(), "header对象不能为空 对象json：{}", JSON.toJSONString(sonDetailsDto));
        Assert.notNull(sonDetailsDto.getBdCorpEntity(), "表头公司不能为空 对象json：{}", JSON.toJSONString(sonDetailsDto));
        Assert.notNull(sonDetailsDto.getBdCalbodyEntity(), "发货库存组织不能为空 对象json：{}", JSON.toJSONString(sonDetailsDto));
        Assert.notNull(sonDetailsDto.getBdStordocEntity(), "发货仓库不能为空 对象json：{}", JSON.toJSONString(sonDetailsDto));
        Assert.notNull(sonDetailsDto.getBdCalbodyEntity1(), "收货库存组织不能为空 对象json：{}", JSON.toJSONString(sonDetailsDto));
        Assert.notNull(sonDetailsDto.getBdStordocEntity1(), "收货库存不能为空 对象json：{}", JSON.toJSONString(sonDetailsDto));
        Assert.notNull(sonDetailsDto.getBdSalestruEntity(), "销售组织不能为空 对象json：{}", JSON.toJSONString(sonDetailsDto));
        Assert.notNull(sonDetailsDto.getBdDeptdocEntity(), "业务部门不能为空 对象json：{}", JSON.toJSONString(sonDetailsDto));
        Assert.notNull(sonDetailsDto.getBdCumandocEntity(), "客商档案不能为空 对象json：{}", JSON.toJSONString(sonDetailsDto));
    }

    /**
     * 查询存货管理档案
     *
     * @param pkCorp                   发货公司主键
     * @param goodsRertunSonDetailsDto 出库单存货明细行
     * @author liuyang
     */
//    private BdInvmandocEntity queryInventoryMan(GoodsRertunSonDetailsDto goodsRertunSonDetailsDto, String pkCorp) {
//        Assert.notNull(goodsRertunSonDetailsDto, "sonDetailsDto不能为空");
//        Assert.notNull(goodsRertunSonDetailsDto.getSkuCode(), "O存货商家编码不能为空");
//        Assert.notNull(pkCorp, "发货公司主键不能为空");
//
//        BdInvmandocEntity bdInvmandocEntity = TocReturnBasicArchivesCacheUtil.stringBdInvmandocEntityMap.get(goodsRertunSonDetailsDto.getSkuCode() + pkCorp);
//        Assert.notNull(bdInvmandocEntity, "无法匹配到存货管理档案 存货商家编码：{} 存货发货公司：{}", goodsRertunSonDetailsDto.getSkuCode(), pkCorp);
//        return bdInvmandocEntity;
//    }

    /**
     * 合并明细行
     * 单价计算公式：sum(实付金额/实发数量) 最后除以条数
     *
     * @param sonDetailsDtoList 汇总过后的售后入库单明细
     * @author liuyang
     */
    private GoodsRertunSonDetailsDto groupMergeDetailedRows(List<GoodsRertunSonDetailsDto> sonDetailsDtoList) throws Exception {
        if (sonDetailsDtoList != null && sonDetailsDtoList.size() > 0) {
            BigDecimal groupTotalPayAmount = new BigDecimal("0");
            BigDecimal groupShipQty = new BigDecimal("0");

            for (int i = 0; i < sonDetailsDtoList.size(); i++) {
                GoodsRertunSonDetailsDto goodsRertunSonDetailsDto = sonDetailsDtoList.get(i);
                StockinOrderSearchResponse.StockinOrder.StockinH header = goodsRertunSonDetailsDto.getHeader();
                RerturnGoodsOrderSearchData rerturnGoodsOrderSearchData = header.getRerturnGoodsOrderSearchData();

                //取对应的售后订单明细，主要是取这个价格
                RerturnGoodsOrderSearchDetails afterSalesOrder = findAfterSalesOrderV2(goodsRertunSonDetailsDto, rerturnGoodsOrderSearchData);

                //实付金额/实发数量
                Assert.notNull(afterSalesOrder.getTotalAmount(), "退货入库单总金额不能为空 明细行对象:{}", JSON.toJSONString(goodsRertunSonDetailsDto));
                Assert.notNull(goodsRertunSonDetailsDto.getReceivedQty(), "实收数量不能为空  明细行对象:{}", JSON.toJSONString(goodsRertunSonDetailsDto));
                BigDecimal totalPayAmountBigDecimal = new BigDecimal(afterSalesOrder.getTotalAmount());
                BigDecimal shipQtyBigDecimal = new BigDecimal(goodsRertunSonDetailsDto.getReceivedQty());

                groupTotalPayAmount = groupTotalPayAmount.add(totalPayAmountBigDecimal);
                groupShipQty = groupShipQty.add(shipQtyBigDecimal);
            }
            GoodsRertunSonDetailsDto goodsRertunSonDetailsDto = sonDetailsDtoList.get(0);
            goodsRertunSonDetailsDto.setGroupShipQty(groupShipQty);
            goodsRertunSonDetailsDto.setGroupTotalPayAmount(groupTotalPayAmount);
            logger.info("TOB{}个明细行发生了合并！", sonDetailsDtoList.size());
            return goodsRertunSonDetailsDto;
        } else {
            logger.info("sonDetailsDtoList集合是空的！");
        }
        return null;
    }

    /**
     * 2024年8月7日 10:25:29
     * 查询基础档案，根据公司、管理档案主键查询
     *
     * @author liuyang
     */
//    private BdInvbasdocEntity queryStockBasicArchives(String pkInvmandoc, String pkCorp) {
//        Assert.notNull(pkInvmandoc, "存货管理档案不能为空");
//        Assert.notNull(pkCorp, "公司档案不能为空");
//        BdInvbasdocEntity bdInvbasdocEntity = TocReturnBasicArchivesCacheUtil.stringBdInvbasdocEntityHashMap.get(pkInvmandoc + pkCorp);
//        Assert.notNull(bdInvbasdocEntity, "根据公司主键：{} 和存货管理档案主键：{} 没有查询到存货基本档案", pkCorp, pkInvmandoc);
//        return bdInvbasdocEntity;
//    }

    /**
     * 2024年8月7日 14:58:34
     * 查询税目档案
     *
     * @author liuyang
     */
//    private BdTaxitemsEntity queryBdTaxitems(String invcode) {
//        Assert.notNull(invcode, "存货编码不能为空");
//        BdTaxitemsEntity bdTaxitemsEntity = TocReturnBasicArchivesCacheUtil.stringBdTaxitemsEntityHashMap.get(invcode);
//        Assert.notNull(bdTaxitemsEntity, "根据存货编码({})，无法匹配到税率！", invcode);
//        return bdTaxitemsEntity;
//    }

    /**
     * 2024年8月8日 10:54:48
     * 推送U8C销售订单方法
     *
     * @author liuyang
     */
    public SoSaleResultRootDto sendU8CTOCOrder(String param) {
        long startLong = System.currentTimeMillis();
        logger.info("TOC推送开始，推送参数：" + param + ",U8C_URL:" + OverallConstant.getOverAllValue("u8c_url"));
        String apiCode = "8000370006";
        String result = HttpRequest.post(OverallConstant.getOverAllValue("u8c_url")).header("appId", OverallConstant.getOverAllValue("appId"))//头信息，多个头信息多次调用此方法即可
                .header("usercode", OverallConstant.getOverAllValue("u8cApiUsercodePK")).header("password", OverallConstant.getOverAllValue("u8cApiPasswordPK")).header("system", OverallConstant.getOverAllValue("u8cApiSystemPK")).header("trantype", OverallConstant.getOverAllValue("u8cApiTrantypePK")).header("apiCode", apiCode)//头信息，多个头信息多次调用此方法即可
                .header("publicKey", OverallConstant.getOverAllValue("publicKey"))//头信息，多个头信息多次调用此方法即可
                .header("secretKey", OverallConstant.getOverAllValue("secretKey"))//头信息，多个头信息多次调用此方法即可
                .body(param)//表单内容
                .timeout(600000)//超时，毫秒
                .execute().body();
        logger.info("TOC推送结束，返回参数：" + result);
        long endLong = System.currentTimeMillis();
        logger.info("TOC接口请求耗时：" + (endLong - startLong));

        JSONObject jsonObject = JSON.parseObject(result);
        result = String.valueOf(jsonObject.get("attribute"));

        boolean isSuccess = false;
        SoSaleResultRootDto soSaleResultRootDto = null;
        if (result != null && !"".equals(result)) {
            ReusltStrDto reusltStrDto = JSON.parseObject(result, ReusltStrDto.class);
            if ("success".equals(reusltStrDto.getStatus())) {
                soSaleResultRootDto = resultDataHandle(reusltStrDto.getData());
                isSuccess = true;
            }
        }
        if (!isSuccess) {
            Assert.state(false, "TOC业务O出库单推送U8C销售订单失败 接口返回结果：{}", result);
        }
        return soSaleResultRootDto;
    }

    /**
     * 返回结果解析处理，在确认了success后调用
     *
     * @author liuyang
     */
    private SoSaleResultRootDto resultDataHandle(String resultData) {
        try {
            if (resultData != null && !"".equals(resultData)) {
                if (resultData.contains("[")) {
                    resultData = resultData.substring(1, resultData.length() - 1);
                }
                return JSON.parseObject(resultData, SoSaleResultRootDto.class);
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("解析返回参数失败的错误", e);
            //如果解析失败，记录原因，但是不能影响结果的记录
        }
        return null;
    }

    /**
     * 填充主表主键、业务日期、业务类型
     * 2024年8月15日 17:31:54
     *
     * @param tocofsReturngoodsDetailedEntity dao明细行对象
     * @param returnGoodSearchHeaderDto       OFS售后入库单表头对象
     */
    private void createPrimaryKeyAndBusinessDateAndBusinessType(TocofsReturngoodsDetailedEntity tocofsReturngoodsDetailedEntity, StockinOrderSearchResponse.StockinOrder.StockinH returnGoodSearchHeaderDto) {
        if (tocofsReturngoodsDetailedEntity != null && returnGoodSearchHeaderDto != null) {
            //主表主键
            if (returnGoodSearchHeaderDto.getId() != null) {
                tocofsReturngoodsDetailedEntity.setMaintableid(returnGoodSearchHeaderDto.getId());
            }
            //业务日期-入库时间
            if (returnGoodSearchHeaderDto.getCheckInFrom() != null) {
                tocofsReturngoodsDetailedEntity.setBusinessdate(returnGoodSearchHeaderDto.getCheckInFrom());
            }
            //业务日期-退款完成时间
            if (returnGoodSearchHeaderDto.getRefundedAt() != null) {
                tocofsReturngoodsDetailedEntity.setRefundedat(returnGoodSearchHeaderDto.getRefundedAt());
            }
            //业务类型
            tocofsReturngoodsDetailedEntity.setBusinesstype("TOC_RETURN");
        }
    }

    /**
     * 通过OFS销售出库单，联查OFS销售订单
     *
     * @param headerDetailsDtoList OFS销售出库单
     */
    private List<com.hzya.frame.ttxofs.dto.ofssalesordersearch.HeaderDetailsDto> queryOfsOrder(List<com.hzya.frame.ttxofs.dto.ofssaleorderoutsearch.HeaderDetailsDto> headerDetailsDtoList) throws Exception {
        List<com.hzya.frame.ttxofs.dto.ofssalesordersearch.HeaderDetailsDto> allHeaderDetailsDtoArrayList = new ArrayList<>();
        try {
            if (headerDetailsDtoList != null && headerDetailsDtoList.size() > 0) {
                List<List<HeaderDetailsDto>> splitListByCount = SplitListByCountUtil.splitListByCount(headerDetailsDtoList, 100);
                for (int i = 0; i < splitListByCount.size(); i++) {
                    List<HeaderDetailsDto> headerDetailsDtos = splitListByCount.get(i);

                    StringBuffer stringBuffer = new StringBuffer();
                    if (headerDetailsDtos != null && headerDetailsDtos.size() > 0) {
                        for (int j = 0; j < headerDetailsDtos.size(); j++) {
                            HeaderDetailsDto headerDetailsDto = headerDetailsDtos.get(j);
                            HeaderDto header = headerDetailsDto.getHeader();
//                List<DetailsDto> details = headerDetailsDto.getDetails();
//                stringBuffer.append("'");
                            stringBuffer.append(header.getRefOrderCode());
//                stringBuffer.append("'");
                            stringBuffer.append(",");
                        }
                    }
                    String substring = stringBuffer.substring(0, stringBuffer.length());

                    List<com.hzya.frame.ttxofs.dto.ofssalesordersearch.HeaderDetailsDto> headerDetailsDtoArrayList = new ArrayList<>();
                    QueryOfsSoSaleOutVo queryOfsSoSaleOutVo = new QueryOfsSoSaleOutVo();
                    queryOfsSoSaleOutVo.setCode(substring);
                    ofsStandardUtil.getOfsSaleOrder(queryOfsSoSaleOutVo, headerDetailsDtoArrayList, 1L);
                    allHeaderDetailsDtoArrayList.addAll(headerDetailsDtoArrayList);
                }
            }
        } catch (Exception e) {
            logger.error("queryOfsOrder方法抛出异常", e);
        }
        return allHeaderDetailsDtoArrayList;
    }

    /**
     * 批量查询售后订单
     *
     * @param returnGoodHeaderDetailsDataDtoList1 OFS售后入库单
     * @author liuyang
     */
    private List<RerturnGoodsOrderSearchData> queryBatchAfterSalesOrder(List<StockinOrderSearchResponse.StockinOrder> returnGoodHeaderDetailsDataDtoList1) {
        List<RerturnGoodsOrderSearchData> rerturnGoodsOrderSearchDataList = new ArrayList<>();
        if (returnGoodHeaderDetailsDataDtoList1 != null && returnGoodHeaderDetailsDataDtoList1.size() > 0) {
            try {
                List<List<StockinOrderSearchResponse.StockinOrder>> splitListByCount = SplitListByCountUtil.splitListByCount(returnGoodHeaderDetailsDataDtoList1, 50);
                for (int i = 0; i < splitListByCount.size(); i++) {
                    List<StockinOrderSearchResponse.StockinOrder> stockinOrderList = splitListByCount.get(i);
                    //50个原始一个批次进行分割
                    StringBuffer idStr = new StringBuffer();
                    for (int j = 0; j < stockinOrderList.size(); j++) {
                        StockinOrderSearchResponse.StockinOrder stockinOrder = stockinOrderList.get(j);
                        StockinOrderSearchResponse.StockinOrder.StockinH header = stockinOrder.getHeader();
                        List<StockinOrderSearchResponse.StockinOrder.StockinB> details = stockinOrder.getDetails();

                        idStr.append(header.getRefOrderCode());
                        idStr.append(",");
                    }
                    String idsStr = idStr.substring(0, idStr.length() - 1);

                    QueryOfsSoSaleOutVo queryOfsSoSaleOutVo = new QueryOfsSoSaleOutVo();
                    queryOfsSoSaleOutVo.setCode(idsStr);
                    afterSalesOrderUtil.getBatchOfsRertunOrder(queryOfsSoSaleOutVo, rerturnGoodsOrderSearchDataList, 1L);
                }
            } catch (Exception e) {
                logger.error("批量查询售后订单", e);
            }
        }
        return rerturnGoodsOrderSearchDataList;
    }

    /**
     * 匹配售后订单
     *
     * @param rerturnGoodsOrderSearchDataList     OFS售后订单集合
     * @param returnGoodHeaderDetailsDataDtoList1 OFS售后入库单集合
     * @author liuyang
     */
    private void findAfterSalesOrder(List<RerturnGoodsOrderSearchData> rerturnGoodsOrderSearchDataList, List<StockinOrderSearchResponse.StockinOrder> returnGoodHeaderDetailsDataDtoList1) throws Exception {
        if (rerturnGoodsOrderSearchDataList != null && rerturnGoodsOrderSearchDataList.size() > 0 && returnGoodHeaderDetailsDataDtoList1 != null && returnGoodHeaderDetailsDataDtoList1.size() > 0) {
            try {
                for (int i = 0; i < returnGoodHeaderDetailsDataDtoList1.size(); i++) {
                    StockinOrderSearchResponse.StockinOrder stockinOrder = returnGoodHeaderDetailsDataDtoList1.get(i);
                    StockinOrderSearchResponse.StockinOrder.StockinH header = stockinOrder.getHeader();
                    List<StockinOrderSearchResponse.StockinOrder.StockinB> details = stockinOrder.getDetails();

                    Assert.notNull(header.getId(), "OFS售后入库单主键不能为空！");
                    for (int j = 0; j < rerturnGoodsOrderSearchDataList.size(); j++) {
                        RerturnGoodsOrderSearchData rerturnGoodsOrderSearchData = rerturnGoodsOrderSearchDataList.get(j);
                        RerturnGoodsOrderSearchHeader header1 = rerturnGoodsOrderSearchData.getHeader();
                        List<RerturnGoodsOrderSearchDetails> details1 = rerturnGoodsOrderSearchData.getDetails();
                        if (header.getRefOrderId().equals(header1.getId())) {
                            header.setRerturnGoodsOrderSearchData(rerturnGoodsOrderSearchData);
                        }
                    }
                }
            } catch (Exception e) {
                logger.error("findAfterSalesOrder方法抛出异常", e);
            }
        }
    }

    /**
     * 通过售后入库单明细行，查找售后订单明细行
     *
     * @param stockinB       售后订单明细行
     * @param ofsRertunOrder OFS售后订单
     * @author liuyang
     */
    private RerturnGoodsOrderSearchDetails findAfterSalesOrderV2(StockinOrderSearchResponse.StockinOrder.StockinB stockinB, RerturnGoodsOrderSearchData ofsRertunOrder) {
        Assert.notNull(stockinB, "stockinB不能为空！");
        Assert.notNull(ofsRertunOrder, "saleOrderMessageDto不能为空！");

        Assert.notNull(ofsRertunOrder.getHeader(), "售后订表头不能为空！");
        Assert.notNull(ofsRertunOrder.getDetails(), "售后订单表头");
        RerturnGoodsOrderSearchHeader header = ofsRertunOrder.getHeader();
        List<RerturnGoodsOrderSearchDetails> details1 = ofsRertunOrder.getDetails();
        if (details1 == null || details1.size() == 0) {
            Assert.state(false, "售后订单明细行不能为空，size不能为0！");
        }
        for (int i = 0; i < details1.size(); i++) {
            RerturnGoodsOrderSearchDetails rerturnGoodsOrderSearchDetails = details1.get(i);
            if (rerturnGoodsOrderSearchDetails.getId().equals(stockinB.getRefOrderDetailId())) {
                return rerturnGoodsOrderSearchDetails;
            }
        }
        Assert.state(false, "通过售后入库单号({})无法匹配到售后订单", stockinB.getId());
        return null;
    }

    /**
     * 通过售后订单，匹配OFS销售订单
     *
     * @param returnGoodHeaderDetailsDataDtoList1 OFS售后入库单集合
     * @author liuyang
     */
    private List<com.hzya.frame.ttxofs.dto.ofssalesordersearch.HeaderDetailsDto> queryBatchOfsOrder(List<StockinOrderSearchResponse.StockinOrder> returnGoodHeaderDetailsDataDtoList1) throws Exception {
        List<com.hzya.frame.ttxofs.dto.ofssalesordersearch.HeaderDetailsDto> headerDetailsDtoArrayList = new ArrayList<>();

        if (returnGoodHeaderDetailsDataDtoList1 != null && returnGoodHeaderDetailsDataDtoList1.size() > 0) {
            try {
                //每50个作为一批，拆分
                List<List<StockinOrderSearchResponse.StockinOrder>> splitListByCount = SplitListByCountUtil.splitListByCount(returnGoodHeaderDetailsDataDtoList1, 50);
                for (int i = 0; i < splitListByCount.size(); i++) {
                    List<StockinOrderSearchResponse.StockinOrder> stockinOrderList = splitListByCount.get(i);

                    StringBuffer codes = new StringBuffer();
                    for (int j = 0; j < stockinOrderList.size(); j++) {
                        StockinOrderSearchResponse.StockinOrder stockinOrder = stockinOrderList.get(j);
                        StockinOrderSearchResponse.StockinOrder.StockinH header = stockinOrder.getHeader();
                        List<StockinOrderSearchResponse.StockinOrder.StockinB> details = stockinOrder.getDetails();
                        RerturnGoodsOrderSearchData rerturnGoodsOrderSearchData1 = header.getRerturnGoodsOrderSearchData();//OFS售后订单
                        if (rerturnGoodsOrderSearchData1 != null) {
                            RerturnGoodsOrderSearchHeader header1 = rerturnGoodsOrderSearchData1.getHeader();
                            List<RerturnGoodsOrderSearchDetails> details1 = rerturnGoodsOrderSearchData1.getDetails();
                            codes.append(header1.getRefOrderCode());
                            codes.append(",");
                        }
                    }
                    String codesStr = codes.substring(0, codes.length() - 1);

                    QueryOfsSoSaleOutVo queryOfsSoSaleOutVo = new QueryOfsSoSaleOutVo();
                    queryOfsSoSaleOutVo.setCode(codesStr);
                    ofsStandardUtil.getOfsSaleOrder(queryOfsSoSaleOutVo, headerDetailsDtoArrayList, 1L);
                }
            } catch (Exception e) {
                logger.error("queryBatchOfsOrder方法抛出异常", e);
            }
        }
        return headerDetailsDtoArrayList;
    }

    /**
     * 匹配OFS销售订单
     *
     * @param headerDetailsDtoList                OFS销售订单
     * @param returnGoodHeaderDetailsDataDtoList1 ofs售后入库单
     * @author liuyang
     */
    private void findOfsOrder(List<com.hzya.frame.ttxofs.dto.ofssalesordersearch.HeaderDetailsDto> headerDetailsDtoList, List<StockinOrderSearchResponse.StockinOrder> returnGoodHeaderDetailsDataDtoList1) {
        if (headerDetailsDtoList != null && headerDetailsDtoList.size() > 0 && returnGoodHeaderDetailsDataDtoList1 != null && returnGoodHeaderDetailsDataDtoList1.size() > 0) {
            try {
                for (int i = 0; i < returnGoodHeaderDetailsDataDtoList1.size(); i++) {
                    StockinOrderSearchResponse.StockinOrder stockinOrder = returnGoodHeaderDetailsDataDtoList1.get(i);
                    StockinOrderSearchResponse.StockinOrder.StockinH header = stockinOrder.getHeader();
                    List<StockinOrderSearchResponse.StockinOrder.StockinB> details = stockinOrder.getDetails();

                    RerturnGoodsOrderSearchData rerturnGoodsOrderSearchData = header.getRerturnGoodsOrderSearchData();//OFS售后订单
                    RerturnGoodsOrderSearchHeader header2 = rerturnGoodsOrderSearchData.getHeader();
                    List<RerturnGoodsOrderSearchDetails> details2 = rerturnGoodsOrderSearchData.getDetails();

                    for (int j = 0; j < headerDetailsDtoList.size(); j++) {
                        com.hzya.frame.ttxofs.dto.ofssalesordersearch.HeaderDetailsDto headerDetailsDto = headerDetailsDtoList.get(j);
                        com.hzya.frame.ttxofs.dto.ofssalesordersearch.HeaderDto header1 = headerDetailsDto.getHeader();
                        List<DetailsDto> details1 = headerDetailsDto.getDetails();
                        if (header2.getRefOrderId().equals(header1.getId())) {
                            header.setHeaderDetailsDto(headerDetailsDto);
                        }
                    }
                }
            } catch (Exception e) {
                logger.error("findOfsOrder方法抛出异常", e);
            }
        }
    }

    /**
     * 生成当前日期
     *
     * @author liuyang
     */
    private String getNewDateStr() {
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        return now.format(formatter);
    }

    /**
     * 批量修改成功、或者失败，适合档案查询的部分
     *
     * @param errorHeaderDetailsDtoDtoList 错误日志
     * @param sceneType                    场景类型
     * @author liuyang
     */
    private void updateFailOrSuccessTocofsSaleoutDetailedArchiveInquiry(List<ErrorHeaderDetailsDtoDtoV2> errorHeaderDetailsDtoDtoList, String sceneType) {
        Assert.notNull(errorHeaderDetailsDtoDtoList, "errorHeaderDetailsDtoDtoList不能为空！");

        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    if (errorHeaderDetailsDtoDtoList != null && errorHeaderDetailsDtoDtoList.size() > 0) {
                        List<TocofsReturngoodsDetailedEntity> tocofsSaleoutDetailedEntityList = new ArrayList<>();
                        for (int i = 0; i < errorHeaderDetailsDtoDtoList.size(); i++) {
                            ErrorHeaderDetailsDtoDtoV2 errorHeaderDetailsDtoDtoV2 = errorHeaderDetailsDtoDtoList.get(i);
                            StockinOrderSearchResponse.StockinOrder.StockinH header = errorHeaderDetailsDtoDtoV2.getHeader();
                            List<StockinOrderSearchResponse.StockinOrder.StockinB> details = errorHeaderDetailsDtoDtoV2.getDetails();
                            String newstate = errorHeaderDetailsDtoDtoV2.getNewstate();
                            String newPushDate = errorHeaderDetailsDtoDtoV2.getNewPushDate();
                            String newTransmitInfo = errorHeaderDetailsDtoDtoV2.getNewTransmitInfo();

                            //如果报错内容太长了，则仅保留500个长度
                            if (newTransmitInfo != null && !"".equals(newTransmitInfo.trim()) && newTransmitInfo.length() >= 400) {
                                newTransmitInfo = newTransmitInfo.substring(0, 400);
                            }

                            for (int j = 0; j < details.size(); j++) {
                                StockinOrderSearchResponse.StockinOrder.StockinB stockinB = details.get(j);

                                TocofsReturngoodsDetailedEntity tocofsReturngoodsDetailedEntity = new TocofsReturngoodsDetailedEntity();

                                tocofsReturngoodsDetailedEntity.setId(stockinB.getId());
                                if (sceneType.equals("stock")) {
                                    tocofsReturngoodsDetailedEntity.setNewpushdate3(newPushDate);
                                    tocofsReturngoodsDetailedEntity.setNewtransmitinfo3(newTransmitInfo);
                                    tocofsReturngoodsDetailedEntity.setNewstate3(newstate);
                                    tocofsReturngoodsDetailedEntity.setNewsystemnumber3(null);
                                    tocofsReturngoodsDetailedEntity.setNewsystemprimary3(null);
                                } else if (sceneType.equals("tran")) {
                                    tocofsReturngoodsDetailedEntity.setNewpushdate4(newPushDate);
                                    tocofsReturngoodsDetailedEntity.setNewtransmitinfo4(newTransmitInfo);
                                    tocofsReturngoodsDetailedEntity.setNewstate4(newstate);
                                    tocofsReturngoodsDetailedEntity.setNewsystemnumber4(null);
                                    tocofsReturngoodsDetailedEntity.setNewsystemprimary4(null);
                                }
                                tocofsSaleoutDetailedEntityList.add(tocofsReturngoodsDetailedEntity);
                            }
                        }

                        //以50行为一个批次更新状态
                        if (tocofsSaleoutDetailedEntityList.size() > 0) {
                            List<List<TocofsReturngoodsDetailedEntity>> splitListByCount = SplitListByCountUtil.splitListByCount(tocofsSaleoutDetailedEntityList, 50);
                            for (int i = 0; i < splitListByCount.size(); i++) {
                                List<TocofsReturngoodsDetailedEntity> tocofsReturngoodsDetailedEntities = splitListByCount.get(i);
                                if (sceneType.equals("stock")) {
                                    //库存
                                    iTocofsReturngoodsDetailedDao.entityInsertOrUpdateBatchByTocRerturnStock(tocofsReturngoodsDetailedEntities);
                                } else if (sceneType.equals("tran")) {
                                    //确认收入
                                    iTocofsReturngoodsDetailedDao.entityInsertOrUpdateBatchByTocRerturnTran(tocofsReturngoodsDetailedEntities);
                                }
                            }
                        }
                    }
                } catch (Exception e) {
                    logger.error("TOB业务，填充出库明细日志抛出异常", e);
                }
            }
        });
        thread.start();
        try {
            thread.join();
        } catch (Exception e) {
            logger.error("updateFailOrSuccessTocofsSaleoutDetailedArchiveInquiry方法现场抛出异常", e);
        }
    }

    /**
     * 处理TOC-库存同步的成功、失败错误逻辑
     *
     * @author liuyang
     */
    private void updateSuccessOrFail1(List<GoodsRertunSonDetailsDto> sonDetailsDtoList, String newstate, String newTransmitInfo, String newsystemnumber, String newsystemprimary) {
        if (newTransmitInfo != null && !"".equals(newTransmitInfo.trim()) && newTransmitInfo.length() >= 400) {
            newTransmitInfo = newTransmitInfo.substring(0, 400);
        }

        String finalNewTransmitInfo = newTransmitInfo;
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    String successY = "Y";
                    if (sonDetailsDtoList != null && sonDetailsDtoList.size() > 0) {
                        List<TocofsReturngoodsDetailedEntity> tocofsReturngoodsDetailedEntityArrayList = new ArrayList<>();
                        for (int i = 0; i < sonDetailsDtoList.size(); i++) {
                            GoodsRertunSonDetailsDto goodsRertunSonDetailsDto = sonDetailsDtoList.get(i);

                            TocofsReturngoodsDetailedEntity tocofsReturngoodsDetailedEntity = new TocofsReturngoodsDetailedEntity();
                            tocofsReturngoodsDetailedEntity.setId(goodsRertunSonDetailsDto.getId());
                            tocofsReturngoodsDetailedEntity.setNewpushdate3(getNewDateStr());
                            tocofsReturngoodsDetailedEntity.setNewtransmitinfo3(finalNewTransmitInfo);
                            tocofsReturngoodsDetailedEntity.setNewstate3(newstate);
                            if (successY.equals(newstate)) {
                                tocofsReturngoodsDetailedEntity.setNewsystemnumber3(newsystemnumber);
                                tocofsReturngoodsDetailedEntity.setNewsystemprimary3(newsystemprimary);
                            }
                            tocofsReturngoodsDetailedEntityArrayList.add(tocofsReturngoodsDetailedEntity);
                        }

                        //以50行为一个批次，推送到Mysql
                        if (tocofsReturngoodsDetailedEntityArrayList.size() > 0) {
                            List<List<TocofsReturngoodsDetailedEntity>> splitListByCount = SplitListByCountUtil.splitListByCount(tocofsReturngoodsDetailedEntityArrayList, 50);
                            for (int i = 0; i < splitListByCount.size(); i++) {
                                List<TocofsReturngoodsDetailedEntity> tocofsReturngoodsDetailedEntities = splitListByCount.get(i);
                                iTocofsReturngoodsDetailedDao.entityInsertOrUpdateBatchByTocRerturnStock(tocofsReturngoodsDetailedEntities);
                            }
                        }
                    }
                } catch (Exception e) {
                    logger.error("TOC库存同步日志，抛出异常", e);
                }
            }
        });
        thread.start();
        try {
            thread.join();
        } catch (Exception e) {
            logger.error("updateSuccessOrFail1方法现场抛出异常", e);
        }
    }

    /**
     * 处理TOC-库存同步的成功、失败错误逻辑
     *
     * @author liuyang
     */
    private void updateSuccessOrFail2(List<GoodsRertunSonDetailsDto> sonDetailsDtoList, String newstate, String newTransmitInfo, String newsystemnumber, String newsystemprimary) {
        if (newTransmitInfo != null && !"".equals(newTransmitInfo.trim()) && newTransmitInfo.length() >= 400) {
            newTransmitInfo = newTransmitInfo.substring(0, 400);
        }

        String finalNewTransmitInfo = newTransmitInfo;
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    String successY = "Y";
                    if (sonDetailsDtoList != null && sonDetailsDtoList.size() > 0) {
                        List<TocofsReturngoodsDetailedEntity> tocofsReturngoodsDetailedEntityArrayList = new ArrayList<>();
                        for (int i = 0; i < sonDetailsDtoList.size(); i++) {
                            GoodsRertunSonDetailsDto goodsRertunSonDetailsDto = sonDetailsDtoList.get(i);

                            TocofsReturngoodsDetailedEntity tocofsReturngoodsDetailedEntity = new TocofsReturngoodsDetailedEntity();
                            tocofsReturngoodsDetailedEntity.setId(goodsRertunSonDetailsDto.getId());
                            tocofsReturngoodsDetailedEntity.setNewpushdate4(getNewDateStr());
                            tocofsReturngoodsDetailedEntity.setNewtransmitinfo4(finalNewTransmitInfo);
                            tocofsReturngoodsDetailedEntity.setNewstate4(newstate);
                            if (successY.equals(newstate)) {
                                tocofsReturngoodsDetailedEntity.setNewsystemnumber4(newsystemnumber);
                                tocofsReturngoodsDetailedEntity.setNewsystemprimary4(newsystemprimary);
                            }
                            tocofsReturngoodsDetailedEntityArrayList.add(tocofsReturngoodsDetailedEntity);
                        }

                        //以50行为一个批次，推送到Mysql
                        if (tocofsReturngoodsDetailedEntityArrayList.size() > 0) {
                            List<List<TocofsReturngoodsDetailedEntity>> splitListByCount = SplitListByCountUtil.splitListByCount(tocofsReturngoodsDetailedEntityArrayList, 50);
                            for (int i = 0; i < splitListByCount.size(); i++) {
                                List<TocofsReturngoodsDetailedEntity> tocofsReturngoodsDetailedEntities = splitListByCount.get(i);
                                iTocofsReturngoodsDetailedDao.entityInsertOrUpdateBatchByTocRerturnTran(tocofsReturngoodsDetailedEntities);
                            }
                        }
                    }
                } catch (Exception e) {
                    logger.error("TOC确认收入同步日志，抛出异常", e);
                }
            }
        });
        thread.start();
        try {
            thread.join();
        } catch (Exception e) {
            logger.error("updateSuccessOrFail1方法现场抛出异常", e);
        }
    }

    /**
     * 筛选出未推送、或者失败的数据行，过滤库存同步业务
     *
     * @param tocofsReturngoodsDetailedEntityList     日志行状态
     * @param returnGoodHeaderDetailsDataDtoArrayList 返回结果
     * @author liuyang
     */
    private List<StockinOrderSearchResponse.StockinOrder> filterDataRowsAsPushOrFailedStock(List<TocofsReturngoodsDetailedEntity> tocofsReturngoodsDetailedEntityList, List<StockinOrderSearchResponse.StockinOrder> returnGoodHeaderDetailsDataDtoArrayList) throws Exception {
        List<StockinOrderSearchResponse.StockinOrder> targetHeaderDetailsDtoList = new ArrayList<>();

        if (returnGoodHeaderDetailsDataDtoArrayList != null && returnGoodHeaderDetailsDataDtoArrayList.size() > 0) {
            //字段Y(成功)或者为H(待处理)可以视为成功，完成了小段业务闭环的数据行
            String succeseeY = "Y";
            String succeseeH = "H";
            for (int i = 0; i < returnGoodHeaderDetailsDataDtoArrayList.size(); i++) {
                StockinOrderSearchResponse.StockinOrder stockinOrder = returnGoodHeaderDetailsDataDtoArrayList.get(i);
                StockinOrderSearchResponse.StockinOrder.StockinH header = stockinOrder.getHeader();
                List<StockinOrderSearchResponse.StockinOrder.StockinB> details = stockinOrder.getDetails();

                List<StockinOrderSearchResponse.StockinOrder.StockinB> targetDetails = new ArrayList<>();
                for (int j = 0; j < details.size(); j++) {
                    StockinOrderSearchResponse.StockinOrder.StockinB stockinB = details.get(j);
                    Boolean isSuccess = false;
                    String newstate = null;
                    if (tocofsReturngoodsDetailedEntityList != null && tocofsReturngoodsDetailedEntityList.size() > 0) {
                        for (int k = 0; k < tocofsReturngoodsDetailedEntityList.size(); k++) {
                            TocofsReturngoodsDetailedEntity tocofsReturngoodsDetailedEntity = tocofsReturngoodsDetailedEntityList.get(k);
                            if (tocofsReturngoodsDetailedEntity.getId().equals(stockinB.getId())) {
                                newstate = tocofsReturngoodsDetailedEntity.getNewstate3();
                                if (succeseeY.equals(newstate) || succeseeH.equals(newstate)) {
                                    isSuccess = true;
                                }
                            }
                        }
                    }
                    if (!isSuccess) {
                        stockinB.setNewstate3(newstate);
                        targetDetails.add(stockinB);
                    }
                }
                if (targetDetails.size() > 0) {
                    //如果明细行中，还存在未推送或者失败的数据，则需要更新明细行
                    stockinOrder.setDetails(targetDetails);
                    targetHeaderDetailsDtoList.add(stockinOrder);
                }
            }
        }
        return targetHeaderDetailsDtoList;
    }

    /**
     * 筛选出未推送、或者失败的数据行，过滤库存同步业务
     *
     * @param tocofsReturngoodsDetailedEntityList     日志行状态
     * @param returnGoodHeaderDetailsDataDtoArrayList 返回结果
     * @author liuyang
     */
    private List<StockinOrderSearchResponse.StockinOrder> filterDataRowsAsPushOrFailedTran(List<TocofsReturngoodsDetailedEntity> tocofsReturngoodsDetailedEntityList, List<StockinOrderSearchResponse.StockinOrder> returnGoodHeaderDetailsDataDtoArrayList) throws Exception {
        Assert.notNull(tocofsReturngoodsDetailedEntityList, "tocofsReturngoodsDetailedEntityList不能为空");
        Assert.notNull(returnGoodHeaderDetailsDataDtoArrayList, "returnGoodHeaderDetailsDataDtoArrayList不能为空");

        List<StockinOrderSearchResponse.StockinOrder> targetHeaderDetailsDtoList = new ArrayList<>();

        if (tocofsReturngoodsDetailedEntityList != null && tocofsReturngoodsDetailedEntityList.size() > 0 && returnGoodHeaderDetailsDataDtoArrayList != null && returnGoodHeaderDetailsDataDtoArrayList.size() > 0) {
            //字段Y(成功)或者为H(待处理)可以视为成功，完成了小段业务闭环的数据行
            String succeseeY = "Y";
            String succeseeH = "H";
            for (int i = 0; i < returnGoodHeaderDetailsDataDtoArrayList.size(); i++) {
                StockinOrderSearchResponse.StockinOrder stockinOrder = returnGoodHeaderDetailsDataDtoArrayList.get(i);
                StockinOrderSearchResponse.StockinOrder.StockinH header = stockinOrder.getHeader();
                List<StockinOrderSearchResponse.StockinOrder.StockinB> details = stockinOrder.getDetails();

                List<StockinOrderSearchResponse.StockinOrder.StockinB> targetDetails = new ArrayList<>();
                for (int j = 0; j < details.size(); j++) {
                    StockinOrderSearchResponse.StockinOrder.StockinB stockinB = details.get(j);
                    Boolean isSuccess = false;
                    String newstate = null;
                    for (int k = 0; k < tocofsReturngoodsDetailedEntityList.size(); k++) {
                        TocofsReturngoodsDetailedEntity tocofsReturngoodsDetailedEntity = tocofsReturngoodsDetailedEntityList.get(k);
                        if (tocofsReturngoodsDetailedEntity.getId().equals(stockinB.getId())) {
                            newstate = tocofsReturngoodsDetailedEntity.getNewstate4();
                            if (succeseeY.equals(newstate) || succeseeH.equals(newstate)) {
                                isSuccess = true;
                            }
                        }
                    }
                    if (!isSuccess) {
                        stockinB.setNewstate4(newstate);
                        targetDetails.add(stockinB);
                    }
                }
                if (targetDetails.size() > 0) {
                    //如果明细行中，还存在未推送或者失败的数据，则需要更新明细行
                    stockinOrder.setDetails(targetDetails);
                    targetHeaderDetailsDtoList.add(stockinOrder);
                }
            }
        }
        return targetHeaderDetailsDtoList;
    }

    /**
     * 计算时间间隔
     *
     * @author liuyang
     */
    public String computingTime(String param) {
        if (param != null && !"".equals(param)) {
            String[] split = param.split("/");
            if (!(split.length == 2)) {
                Assert.state(false, "传递的日期格式不完整 格式参考：2024-04-01/2024-04-30");
            }

            LocalDate startDate = LocalDate.parse(split[0]);
            LocalDate endDate = LocalDate.parse(split[1]);

            List<String> stringArrayList = new ArrayList<>();
            List<String> dateRange = getDateRange(startDate, endDate);
            if (dateRange != null && dateRange.size() > 0) {
                for (int i = 0; i < dateRange.size(); i++) {
                    String dateStr = dateRange.get(i);
                    StringBuffer stringBuffer = new StringBuffer();
                    stringBuffer.append(dateStr);
                    stringBuffer.append(" 00:00:00");
                    stringBuffer.append(",");
                    stringBuffer.append(dateStr);
                    stringBuffer.append(" 23:59:59");
                    stringArrayList.add(stringBuffer.toString());
                }
            }
            String collectDateStr = stringArrayList.stream().collect(Collectors.joining("*"));
            logger.info("类型：time_frame 生成的日期范围：" + collectDateStr);
            return collectDateStr;
        }
        return null;
    }

    /**
     * 分割日期之后，再进行推送
     *
     * @author liuyang
     */
    public void splitDateAndPush(String param, String sceneType) throws Exception {
        try {
            Assert.notNull(param, "param不能为空!");
            Assert.state(!"".equals(param), "param不能为空！");

            Assert.notNull(sceneType, "sceneType不能为空！");
            Assert.state(!"".equals(sceneType), "sceneType不能为空！");

            if (param.contains("*")) {
                String[] params = param.split("\\*");
                if (params.length > 0) {
                    for (int i = 0; i < params.length; i++) {
                        String indexStr = params[i];
                        String[] split = indexStr.split(",");
                        logger.info("splitDateAndPush方法正在执行主要的逻辑 开始时间：{} 结束时间：{}", split[0], split[1]);
                        if (sceneType.equals(STOCK)) {
                            startImplementStockByTime(split[0], split[1]);
                        } else if (sceneType.equals(TRAN)) {
                            startImplementByTradeTime(split[0], split[1]);
                        }
                    }
                }
            } else {
                String[] split = param.split(",");
                logger.info("splitDateAndPush方法正在执行主要的逻辑 开始时间：{} 结束时间：{}", split[0], split[1]);
                if (sceneType.equals(STOCK)) {
                    startImplementStockByTime(split[0], split[1]);
                } else if (sceneType.equals(TRAN)) {
                    startImplementByTradeTime(split[0], split[1]);
                }
            }
        } catch (Exception e) {
            logger.error("记录splitDateAndPush方法抛出的异常", e);
        }
    }

    /**
     * 计算全天时间段
     *
     * @author liuyang
     */
    public List<StartAndEndVo> calculateCalculateEntireDayPeriod(String dateStr) {
        List<StartAndEndVo> startAndEnd = new ArrayList<>();

        String calculateYesterdayStr = null;
        if (dateStr != null) {
            calculateYesterdayStr = dateStr;
        } else {
            calculateYesterdayStr = calculateYesterdayDate();//拉取'昨天'的日期
        }
        logger.info("OFS销售出库单同步U8C销售订单，目标拉取时间：" + calculateYesterdayStr);

        for (int i = 0; i <= 23; i++) {
            String iStr = null;
            if (i <= 9) {
                iStr = "0" + i;
            } else {
                iStr = String.valueOf(i);
            }
            String startTime = calculateYesterdayStr + " " + iStr + ":00:00";
            String endTime = calculateYesterdayStr + " " + iStr + ":59:59";

            StartAndEndVo startAndEndVo = new StartAndEndVo();
            startAndEndVo.setStart_time(startTime);
            startAndEndVo.setEnd_time(endTime);
            startAndEnd.add(startAndEndVo);
        }
        return startAndEnd;
    }

    /**
     * 计算昨天的单据日期，基于定时器在凌晨5分执行的情况下
     *
     * @author liuyang
     */
    public String calculateYesterdayDate() {
        DateTime yesterdayDate = DateUtil.yesterday();
        return DateUtil.format(yesterdayDate, "yyyy-MM-dd");
    }

    /**
     * 计算时间范围对应的字符串集合
     *
     * @author liuyang
     */
    private List<String> getDateRange(LocalDate startDate, LocalDate endDate) {
        List<String> dateRange = new ArrayList<>();
        LocalDate currentDate = startDate;
        while (!currentDate.isAfter(endDate)) {
            dateRange.add(currentDate.format(DateTimeFormatter.ISO_DATE));
            currentDate = currentDate.plusDays(1);
        }
        return dateRange;
    }
}