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

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.dao.*;
import com.hzya.frame.plugin.lets.entity.*;
import com.hzya.frame.plugin.lets.ofsvo.QueryOfsSoSaleOutVo;
import com.hzya.frame.plugin.lets.queryvo.QueryIntegrationTaskLivingDetails;
import com.hzya.frame.plugin.lets.queryvo.StartAndEndVo;
import com.hzya.frame.plugin.lets.u8cdto.*;
import com.hzya.frame.plugin.lets.util.*;
import com.hzya.frame.split.SplitListByCountUtil;
import com.hzya.frame.sysnew.integtationTaskLivingDetails.entity.IntegrationTaskLivingDetailsEntity;
import com.hzya.frame.ttxofs.dto.ofspoorder.OfsPoOrderData;
import com.hzya.frame.ttxofs.dto.ofspoorder.OfsPoOrderDetails;
import com.hzya.frame.ttxofs.dto.ofspoorder.OfsPoOrderHeader;
import com.hzya.frame.ttxofs.dto.ofspurchasereturnorder.PurchaseReturnOrder;
import com.hzya.frame.ttxofs.dto.ofspurchasereturnorder.PurchaseReturnOrderDetails;
import com.hzya.frame.ttxofs.dto.ofspurchasereturnorder.PurchaseReturnOrderHeader;
import com.hzya.frame.ttxofs.dto.ofssaleorderoutsearch.DetailsDto;
import com.hzya.frame.ttxofs.dto.ofssaleorderoutsearch.HeaderDetailsDto;
import com.hzya.frame.ttxofs.dto.ofssaleorderoutsearch.HeaderDto;
import com.hzya.frame.ttxofs.dto.stock.StockinOrderSearchResponse;
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.util.*;

/**
 * O采退出库 -> (关联之前正向的委外订单)U8C红字委外入库单
 *
 * @Author：liuyang
 * @Package：com.hzya.frame.plugin.lets.plugin.outsourc
 * @Project：kangarooDataCenterV3
 * @name：ConsignmachiningIn
 * @Date：2024年8月26日 15:34:34
 * @Filename：ConsignmachiningIn
 */
public class ConsignmachiningInReturn extends PluginBaseEntity {

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

    @Autowired
    private QueryBdBusitypeUtil queryBdBusitypeUtil;

    @Autowired
    private IBdCorpDao iBdCorpDao;

    @Autowired
    private IBdInvmandocDao iBdInvmandocDao;

    @Autowired
    private IBdCalbodyDao iBdCalbodyDao;

    @Autowired
    private RdclUtil rdclUtil;

    @Autowired
    private OfsStandardUtil ofsStandardUtil;

    @Autowired
    private IBdCumandocDao iBdCumandocDao;

    @Autowired
    private IBdCubasdocDao iBdCubasdocDao;

    @Autowired
    private IBdPurorgDao iBdPurorgDao;

    @Autowired
    private OnlyImplementProxyOrderUtil onlyImplementProxyOrder;

    @Autowired
    private IScOrderDao iScOrderDao;

    @Autowired
    private IScOrderBDao iScOrderBDao;

    @Autowired
    private IBdStordocDao iBdStordocDao;

    @Autowired
    private SaveOrUpdateBusinessLogUtil saveOrUpdateBusinessLogUtil;

    @Autowired
    private IntegrationTaskLivingDetailsUtil integrationTaskLivingDetailsUtil;

    @Autowired
    private OffsetTimeTime offsetTimeTime;

    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 "outsourc.ConsignmachiningInReturn";
    }

    @Override
    public String getPluginName() {
        return "OFS采退出库单生成U8C红字委外订单(关联原委外订单)";
    }

    @Override
    public String getPluginLabel() {
        return "OFS采退出库单生成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"));
            if (ProfilesActiveConstant.TYPE_VBILLCODE.equals(requestJson.get("type"))) {
                //按单号推送
                if (param != null && !"".equals(param)) {
                    startImplement(param);
                }
            } else if (ProfilesActiveConstant.TYPE_TIME_FRAME.equals(requestJson.get("type"))) {
                //前台页面功能日期推送，或者接口调用也行
                String craeteDateStr = offsetTimeTime.computingTime(param);
                if (craeteDateStr != null && !"".equals(craeteDateStr)) {
                    splitDateAndPush(craeteDateStr);
                }
            } else {
                if (ProfilesActiveConstant.LETS_PROFILES_ACTIVE.equals(PROD_FILED)) {
                    //默认被定时器执行，实时执行，计算时间偏移量
                    StartAndEndVo startAndEndVo = offsetTimeTime.offsetTime();
                    startImplementByTime(startAndEndVo.getStart_time(), startAndEndVo.getEnd_time());
                }
            }
        } catch (Exception e) {
            logger.error("executeBusiness方法异常", e);
        }
        long endMillis = System.currentTimeMillis();
        logger.info("executeBusiness方法调用结束：" + getPluginName() + "-插件 执行耗时：{}", (endMillis - startMillis));
        return null;
    }

    /**
     * 根据时间范围查询
     *
     * @author liuyang
     */
    public void startImplementByTime(String startTime, String endTime) {
        long startMillis = System.currentTimeMillis();
        String threadNameStrStart = StrUtil.format("开始（委外采退）OFS采退出库单生成U8红字C委外订单 开始时间：{} 结束时间：{}", startTime, endTime);
        logger.info(threadNameStrStart);

        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    //OFS采退出库
                    List<HeaderDetailsDto> returnGoodHeaderDetailsDataDtoArrayList = new ArrayList<>();
                    QueryOfsSoSaleOutVo queryOfsSoSaleOutVo = new QueryOfsSoSaleOutVo();
                    queryOfsSoSaleOutVo.setClosedAt_start(startTime);
                    queryOfsSoSaleOutVo.setClosedAt_end(endTime);
                    queryOfsSoSaleOutVo.setClientCode("LETS");
                    queryOfsSoSaleOutVo.setPageNo(1L);
                    queryOfsSoSaleOutVo.setPageSize(50L);
                    queryOfsSoSaleOutVo.setInternalInstructionType("PURCHASE_RETURN");
                    queryOfsSoSaleOutVo.setStatus(900L);
                    ofsStandardUtil.queryOfsSaleOrder(queryOfsSoSaleOutVo, returnGoodHeaderDetailsDataDtoArrayList, 1L, "ofs.shipment.search");
                    logger.info("数据返回行数：{}", returnGoodHeaderDetailsDataDtoArrayList.size());
                    if (returnGoodHeaderDetailsDataDtoArrayList.size() > 0) {
                        getSet(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采退出库单生成U8红字C委外订单 开始时间：{} 结束时间：{} 耗时：{}", startTime, endTime, (endMillis - startMillis));
        logger.info(threadNameStrEnd);
    }

    /**
     * 根据单号查询
     *
     * @author liuyang
     */
    public void startImplement(String code) {
        long startMillis = System.currentTimeMillis();
        String threadNameStrStart = StrUtil.format("开始（委外采退）OFS采退出库单生成U8红字C委外订单 OFS采购入库单号：{}", code);
        logger.info(threadNameStrStart);

        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    List<HeaderDetailsDto> returnGoodHeaderDetailsDataDtoArrayList = new ArrayList<>();
                    QueryOfsSoSaleOutVo queryOfsSoSaleOutVo = new QueryOfsSoSaleOutVo();
                    queryOfsSoSaleOutVo.setClientCode("LETS");
                    queryOfsSoSaleOutVo.setPageNo(1L);
                    queryOfsSoSaleOutVo.setPageSize(50L);
                    queryOfsSoSaleOutVo.setCode(code);
                    queryOfsSoSaleOutVo.setInternalInstructionType("PURCHASE_RETURN");
                    queryOfsSoSaleOutVo.setStatus(900L);
                    ofsStandardUtil.queryOfsSaleOrder(queryOfsSoSaleOutVo, returnGoodHeaderDetailsDataDtoArrayList, 1L, "ofs.shipment.search");
                    logger.info("数据返回行数：{}", returnGoodHeaderDetailsDataDtoArrayList.size());
                    if (returnGoodHeaderDetailsDataDtoArrayList.size() > 0) {
                        getSet(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采退出库单生成U8红字C委外订单 OFS采购入库单号：{} 耗时：{}", code, (endMillis - startMillis));
        logger.info(threadNameStrEnd);
    }

    /**
     * 环境预配置
     *
     * @param returnGoodHeaderDetailsDataDtoArrayList 采退出库单
     * @author liuyang
     */
    private void getSet(List<HeaderDetailsDto> returnGoodHeaderDetailsDataDtoArrayList) throws Exception {
        //过滤成功的数据
        List<HeaderDetailsDto> headerDetailsDtos = filterData(returnGoodHeaderDetailsDataDtoArrayList);
        //执行推送主逻辑
        implement(headerDetailsDtos);
    }

    /**
     * 过滤掉成功的数据
     *
     * @author liuyang
     */
    private List<HeaderDetailsDto> filterData(List<HeaderDetailsDto> returnGoodHeaderDetailsDataDtoArrayList) {
        //过滤完毕后的数据集合
        List<HeaderDetailsDto> headerDetailsDtoList1 = new ArrayList<>();
        //查询得到已经成功的日志，成功或者已处理
        List<IntegrationTaskLivingDetailsEntity> successIntegrationTaskLivingDetails = new ArrayList<>();
        try {
            if (returnGoodHeaderDetailsDataDtoArrayList != null && returnGoodHeaderDetailsDataDtoArrayList.size() > 0) {
                //每100个开始拆分
                List<List<HeaderDetailsDto>> headerDetailsDtoList = SplitListByCountUtil.splitListByCount(returnGoodHeaderDetailsDataDtoArrayList, 100);
                for (int i = 0; i < headerDetailsDtoList.size(); i++) {
                    List<HeaderDetailsDto> headerDetailsDtos = headerDetailsDtoList.get(i);
                    String primaryKey = fieldConcaten(headerDetailsDtos);

                    List<IntegrationTaskLivingDetailsEntity> integrationTaskLivingDetailsEntities = integrationTaskLivingDetailsUtil.queryIntegrationTaskLivingDetails(primaryKey, getPluginId());
                    successIntegrationTaskLivingDetails.addAll(integrationTaskLivingDetailsEntities);
                }

                for (int i = 0; i < returnGoodHeaderDetailsDataDtoArrayList.size(); i++) {
                    HeaderDetailsDto headerDetailsDto = returnGoodHeaderDetailsDataDtoArrayList.get(i);
                    HeaderDto header = headerDetailsDto.getHeader();
                    List<DetailsDto> details = headerDetailsDto.getDetails();

                    boolean isExi = false;
                    for (int j = 0; j < successIntegrationTaskLivingDetails.size(); j++) {
                        IntegrationTaskLivingDetailsEntity integrationTaskLivingDetailsEntity = successIntegrationTaskLivingDetails.get(j);
                        if (integrationTaskLivingDetailsEntity.getRootAppPk().equals(header.getId())) {
                            isExi = true;
                        }
                    }
                    if (!isExi) {
                        headerDetailsDtoList1.add(headerDetailsDto);
                    }
                }
            }
        } catch (Exception e) {
            logger.error("过滤成功的数据抛出异常", e);
        }
        return headerDetailsDtoList1;
    }

    /**
     * 字段拼接
     */
    private String fieldConcaten(List<HeaderDetailsDto> headerDetailsDtos) {
        if (headerDetailsDtos != null && headerDetailsDtos.size() > 0) {
            StringBuilder result = new StringBuilder();
            for (HeaderDetailsDto obj : headerDetailsDtos) {
                HeaderDto header = obj.getHeader();
//                if (result.length() > 0) {
//                    result.append(",");
//                }
                result.append("'").append(header.getId()).append("'").append(",");
            }
            return result.substring(0, result.length() - 1);
        }
        return null;
    }

    /**
     * 执行主逻辑
     *
     * @author liuyang
     */
    private void implement(List<HeaderDetailsDto> returnGoodHeaderDetailsDataDtoArrayList) throws Exception {
        if (returnGoodHeaderDetailsDataDtoArrayList != null) {
            logger.info("查询到的采退出库单数量(委外退货业务)：{}", returnGoodHeaderDetailsDataDtoArrayList.size());
        }
        if (returnGoodHeaderDetailsDataDtoArrayList != null && returnGoodHeaderDetailsDataDtoArrayList.size() > 0) {
            try {
                //OFS转换U8C档案
                List<ReturnOrderHeaderDto> returnOrderHeaderDtos = queryBasicArchives(returnGoodHeaderDetailsDataDtoArrayList);
                //查询采购收发类别
                BdRdclEntity bdRdclEntity = rdclUtil.queryRdClObject("105");
                //代理委外入库业务流程
                BdBusitypeEntity bdBusitypeEntity = u8cOperationFlow();

                if (returnOrderHeaderDtos != null && returnOrderHeaderDtos.size() > 0) {
                    for (int i = 0; i < returnOrderHeaderDtos.size(); i++) {
                        ReturnOrderHeaderDto returnOrderHeaderDto = returnOrderHeaderDtos.get(i);
                        List<DetailsDto> details = returnOrderHeaderDto.getDetails();

                        String generateBusinessDate = null;
                        try {
                            generateBusinessDate = createGenerateBusinessDate(returnOrderHeaderDto); //生成业务日期
                            PurchaseReturnOrder purchaseReturnOrder = returnOrderHeaderDto.getPurchaseReturnOrder();//OFS采退订单
                            ScOrderEntity scOrderEntity = returnOrderHeaderDto.getScOrderEntity();//U8C委外订单
                            List<ScOrderBEntity> scOrderBEntityList = returnOrderHeaderDto.getScOrderBEntityList();//U8C委外订单明细行
                            BdCorpEntity bdCorpEntity = returnOrderHeaderDto.getBdCorpEntity();//公司
                            BdCalbodyEntity bdCalbodyEntity = returnOrderHeaderDto.getBdCalbodyEntity();//库存组织
                            BdStordocEntity bdStordocEntity = returnOrderHeaderDto.getBdStordocEntity();//仓库
                            OfsPoOrderData ofsPoOrder = returnOrderHeaderDto.getOfsPoOrder();//OFS原正向的采购订单

                            //委外入库表头
                            ConsignmachiningInHeadDto poOrderParentDto = new ConsignmachiningInHeadDto();
                            poOrderParentDto.setPk_corp(bdCorpEntity.getPkCorp());
                            poOrderParentDto.setCoperatorid(OverallConstant.getOverAllValue("u8cApiZdrPK"));
                            poOrderParentDto.setCwarehouseid(bdStordocEntity.getPkStordoc());
                            poOrderParentDto.setPk_calbody(bdCalbodyEntity.getPkCalbody());
                            poOrderParentDto.setCbiztype(bdBusitypeEntity.getPkBusitype());
                            poOrderParentDto.setCdispatcherid(bdRdclEntity.getPkRdcl());//收发类别
                            poOrderParentDto.setDbilldate(generateBusinessDate);//入库日期
                            poOrderParentDto.setFreplenishflag(true);//是否退货

                            //委外入库表头明细行
                            List<ConsignmachiningInBodyDto> consignmachiningInBodyDtoArrayList = new ArrayList<>();
                            for (int j = 0; j < details.size(); j++) {
                                DetailsDto detailsDto = details.get(j);
                                //匹配U8C采购订单明细行
                                ScOrderBEntity u8cPoOrderDetail = findOfsPoOrderDetailAndU8cPoOrderDetail(detailsDto, purchaseReturnOrder, ofsPoOrder, scOrderBEntityList);
                                //通过O采退出库库单明细行，联查OFS采退订单明细行
                                PurchaseReturnOrderDetails ofsPoOrderDetailRowTraget = findOfsPoOrderDetailRowTraget(detailsDto, purchaseReturnOrder);
                                //查询存货管理档案
//                            BdInvmandocEntity bdInvmandocEntity = queryInventoryMan(stockinB, bdCorpEntity.getPkCorp());
                                BdInvmandocEntity bdInvmandocEntity = null;

                                //计算含税单价
                                BigDecimal noriginalcurprice = null;
                                String receivedQty = detailsDto.getShipQty();//实收数量
                                String fulfillAmount = ofsPoOrderDetailRowTraget.getFulfillAmount();//实收累计总金额
                                try {
                                    noriginalcurprice = new BigDecimal(fulfillAmount).divide(new BigDecimal(receivedQty), 20, BigDecimal.ROUND_HALF_UP).setScale(4, BigDecimal.ROUND_HALF_UP);
                                } catch (Exception e) {
                                    logger.error("计算采退出库单原币含税单价失败", e);
                                    Assert.state(false, "计算采退出库单原币含税单价失败 原因：{}", e.getMessage());
                                }

                                ConsignmachiningInBodyDto consignmachiningInBodyDto = new ConsignmachiningInBodyDto();
                                consignmachiningInBodyDto.setCinventoryid(bdInvmandocEntity.getPkInvmandoc());//存货主键
                                consignmachiningInBodyDto.setNinnum("-" + new BigDecimal(receivedQty).stripTrailingZeros().toPlainString());//实收数量
                                consignmachiningInBodyDto.setNprice(noriginalcurprice.stripTrailingZeros().toPlainString());//单价（含税单价）
                                consignmachiningInBodyDto.setCsourcetype("61");//来源单据类型
                                consignmachiningInBodyDto.setVsourcerowno(u8cPoOrderDetail.getCrowno());//来源单据行号
                                consignmachiningInBodyDto.setVsourcebillcode(scOrderEntity.getVordercode());//来源单据号
//                            consignmachiningInBodyDto.setWriteofftype("按备料发料核销");//核销方式，和妮姐已经确认，不用传递
                                consignmachiningInBodyDto.setDbizdate(generateBusinessDate);//	入库日期
                                consignmachiningInBodyDtoArrayList.add(consignmachiningInBodyDto);
                            }

                            List<ConsignmachiningInHeadBodyDto> consignmachiningInHeadBodyDtoArrayList = new ArrayList<>();
                            ConsignmachiningInHeadBodyDto consignmachiningInHeadBodyDto = new ConsignmachiningInHeadBodyDto();
                            consignmachiningInHeadBodyDto.setParentvo(poOrderParentDto);
                            consignmachiningInHeadBodyDto.setChildrenvo(consignmachiningInBodyDtoArrayList);
                            consignmachiningInHeadBodyDtoArrayList.add(consignmachiningInHeadBodyDto);

                            Map<String, List<ConsignmachiningInHeadBodyDto>> stringStringMap = new HashMap<>();
                            stringStringMap.put("GeneralBillVO", consignmachiningInHeadBodyDtoArrayList);
                            //2024年8月26日 14:41:46 委外入库核销方式传不了！已经提交总部，2024年8月30日 14:05:25 已经解决，和妮姐确认不用填写
                            //2024年8月26日 14:42:19 无法超委外订单数量入库！已经提交给总部
                            //2024年9月3日 18:28:24 退货不会出现超订单出库的情况
                            IcGeneralHResultDto icGeneralHResultDto = sendU8cConsignmachiningIn(JSON.toJSONString(stringStringMap));

                            String cgeneralhid = null;
                            String vbillcode = null;
                            IcGeneralHResultHeadDto parentvo = icGeneralHResultDto.getParentvo();
                            List<IcGeneralHResultBodyDto> childrenvo = icGeneralHResultDto.getChildrenvo();
                            if (parentvo != null) {
                                cgeneralhid = parentvo.getCgeneralhid();
                                vbillcode = parentvo.getVbillcode();
                            }
                            logger.info("推送U8C红字委外入库成功！委外入库单主键：{} 委外入库单编码：{} 公司名称：{}", cgeneralhid, vbillcode, bdCorpEntity.getUnitname());
                            // 成功记录日志
                            IntegrationTaskLivingDetailsEntity integrationTaskLivingDetailsEntity = new IntegrationTaskLivingDetailsEntity();
                            integrationTaskLivingDetailsEntity.setNewState(ProfilesActiveConstant.LOG_STATUS_Y);
                            integrationTaskLivingDetailsEntity.setRootAppNewData(JSON.toJSONString(returnOrderHeaderDto));//原始数据json
                            integrationTaskLivingDetailsEntity.setNewTransmitInfo(JSON.toJSONString(icGeneralHResultDto));//返回结果
                            integrationTaskLivingDetailsEntity.setNewPushDate(new Date());
                            integrationTaskLivingDetailsEntity.setBusinessDate(generateBusinessDate);
                            integrationTaskLivingDetailsEntity.setRootAppPk(returnOrderHeaderDto.getId());
                            integrationTaskLivingDetailsEntity.setRootAppBill(returnOrderHeaderDto.getCode());
                            integrationTaskLivingDetailsEntity.setPluginId(getPluginId());
                            integrationTaskLivingDetailsEntity.setNewSystemNumber(vbillcode);//下游单据编码
                            integrationTaskLivingDetailsEntity.setNewSystemPrimary(cgeneralhid);//下游单据主键
                            saveOrUpdateBusinessLogUtil.saveOrUpdate(integrationTaskLivingDetailsEntity);
                        } catch (Exception e) {
                            logger.error("推送U8C红字委外入库单失败", e);

                            String message = e.getMessage();
                            if (message == null) {
                                message = "未知错误";
                            }
                            // 失败记录日志
                            IntegrationTaskLivingDetailsEntity integrationTaskLivingDetailsEntity = new IntegrationTaskLivingDetailsEntity();
                            integrationTaskLivingDetailsEntity.setNewState(ProfilesActiveConstant.LOG_STATUS_N);
                            integrationTaskLivingDetailsEntity.setRootAppNewData(JSON.toJSONString(returnOrderHeaderDto));//原始数据json
                            integrationTaskLivingDetailsEntity.setNewTransmitInfo(JSON.toJSONString(message));//返回结果
                            integrationTaskLivingDetailsEntity.setNewPushDate(new Date());
                            integrationTaskLivingDetailsEntity.setBusinessDate(generateBusinessDate);
                            integrationTaskLivingDetailsEntity.setRootAppPk(returnOrderHeaderDto.getId());
                            integrationTaskLivingDetailsEntity.setRootAppBill(returnOrderHeaderDto.getCode());
                            integrationTaskLivingDetailsEntity.setPluginId(getPluginId());
                            saveOrUpdateBusinessLogUtil.saveOrUpdate(integrationTaskLivingDetailsEntity);
                        }
                    }
                } else {
                    logger.info("poOrderSonDto.size为0！");
                }
            } catch (Exception e) {
                logger.error("implement方法抛出异常", e);
            }
        }
    }

    /**
     * 档案转换(OFS->U8C)
     * 2024年8月23日 12:02:47 和妮姐沟通，单据流程U8C成品委外订单 -> 备料计划 -> U8C委外发料(核销)
     *
     * @author liuyang
     */
    private List<ReturnOrderHeaderDto> queryBasicArchives(List<HeaderDetailsDto> returnGoodHeaderDetailsDataDtoList) throws Exception {
        List<ReturnOrderHeaderDto> consignmachiningInSonDtoArrayList = new ArrayList<>();

        if (returnGoodHeaderDetailsDataDtoList != null && returnGoodHeaderDetailsDataDtoList.size() > 0) {
            try {
                for (int i = 0; i < returnGoodHeaderDetailsDataDtoList.size(); i++) {
                    HeaderDetailsDto headerDetailsDto = returnGoodHeaderDetailsDataDtoList.get(i);
                    HeaderDto header = headerDetailsDto.getHeader();
                    List<DetailsDto> details = headerDetailsDto.getDetails();

                    String generateBusinessDate = null;
                    try {
                        generateBusinessDate = createGenerateBusinessDatev2(header);

                        //2024年8月27日 17:14:47 查询OFS采退订单
                        PurchaseReturnOrder purchaseReturnOrder = queryPurchaseReturnOrder(header.getRefOrderCode());
                        Assert.notNull(purchaseReturnOrder, "无法查询到采退订单 refOrderCode:{}", header.getRefOrderCode());
                        PurchaseReturnOrderHeader ofsWithdrawalHead = purchaseReturnOrder.getHeader();
                        List<PurchaseReturnOrderDetails> ofsWithdrawalDetails = purchaseReturnOrder.getDetails();

                        //如果该O采购订单对应的类型为：委外加工，则继续代码逻辑，否则就跳过代码逻辑
                        boolean checkResult = onlyImplementProxyOrder.onlyImplementProxyOrder(purchaseReturnOrder, "WWJG");
                        if (!checkResult) {
                            continue;
                        }

                        //2024年8月30日 13:28:46 查询原委外订单(取的是钉钉推送到U8C的委外订单)，查询逻辑：OFS采退出库单 -> OFS采退订单 -> OFS采购订单
                        OfsPoOrderData ofsPoOrder = queryOfsPoOrder(purchaseReturnOrder);

                        //2024年8月30日 13:35:16 根据OFS采购订单，查询OFS委外订单
                        ScOrderEntity scOrderEntity = queryScOrder(ofsPoOrder.getHeader().getId());

                        //2024年8月27日 17:14:51 查询U8C委外订单，如果这一步报错，后续的逻辑就没有必要执行了
//                    String ofsId = ofsWithdrawalHead.getId();
//                    Assert.notNull(ofsId, "通过接口查询到OFS采退订单，但是没有采退订单主键(id)，业务逻辑无法完成");
//                    ScOrderEntity scOrderEntity = queryScOrder(ofsId);

                        //2024年8月27日 17:14:57 根据U8C委外订单id，查询U8C委外订单表体明细行
                        List<ScOrderBEntity> scOrderBEntityList = queryScOrderDetail(scOrderEntity.getCorderid());

                        //2024年8月27日 17:15:02 委外入库公司，取委外订单上的公司，已经和妮姐确认，没有必要通过O的公司转换，因为不存在跨组织的问题
                        Assert.notNull(scOrderEntity.getPkCorp(), "O表头公司不能为空");
                        BdCorpEntity bdCorpEntity = new BdCorpEntity();
                        bdCorpEntity.setDr(0);
                        bdCorpEntity.setDataSourceCode("lets_u8c");
                        bdCorpEntity.setPkCorp(scOrderEntity.getPkCorp());
                        List<BdCorpEntity> bdCorpEntityList = iBdCorpDao.query(bdCorpEntity);
                        if (bdCorpEntityList.size() == 0) {
                            Assert.state(false, "根据委外订单公司主键:{}，无法匹配到委外入库单", scOrderEntity.getPkCorp());
                        } else if (bdCorpEntityList.size() >= 2) {
                            Assert.state(false, "根据委外订单公司主键:{}，匹配到{}个委外入库单", scOrderEntity.getPkCorp(), bdCorpEntityList.size());
                        }

                        // 2024年8月27日 17:15:09 收货库存组织，应该是通过收货公司查询得出收货库存组织，目前收货公司和采购公司保持一致，那么就以采购公司带出！这个逻辑已经和佳妮确认
                        BdCalbodyEntity bdCalbodyEntity = new BdCalbodyEntity();
                        bdCalbodyEntity.setDr(0);
                        bdCalbodyEntity.setDataSourceCode("lets_u8c");
                        bdCalbodyEntity.setPkCorp(bdCorpEntityList.get(0).getPkCorp());
                        List<BdCalbodyEntity> bdCalbodyEntities = iBdCalbodyDao.query(bdCalbodyEntity);
                        if (bdCalbodyEntities.size() == 0) {
                            Assert.state(false, "根据U8C采购公司{}，无法匹配到U8C发货库存组织", bdCorpEntityList.get(0).getPkCorp());
                        } else if (bdCalbodyEntities.size() >= 2) {
                            Assert.state(false, "根据U8C采购公司{}，匹配到U8C发货库存组织{}个", bdCorpEntityList.get(0).getPkCorp(), bdCalbodyEntities.size());
                        }

                        //入库仓库
                        String facilityCode = header.getFacilityCode();
                        Assert.notNull(facilityCode, "O售后入库单仓库facilityCode字段不能为空");
                        BdStordocEntity bdStordocEntity = new BdStordocEntity();
                        bdStordocEntity.setDr(0L);
                        bdStordocEntity.setDataSourceCode("lets_u8c");
                        bdStordocEntity.setPkCalbody(bdCalbodyEntities.get(0).getPkCalbody());
                        bdStordocEntity.setStorcode(facilityCode);
                        List<BdStordocEntity> bdStordocEntityList = iBdStordocDao.query(bdStordocEntity);
                        if (bdStordocEntityList.size() == 0) {
                            Assert.state(false, "根据O仓库编码+U8C收货库存组织主键，无法匹配到U8C仓库", facilityCode, bdCalbodyEntities.get(0).getPkCalbody());
                        } else if (bdStordocEntityList.size() >= 2) {
                            Assert.state(false, "根据O仓库编码+U8C收货库存组织主键，匹配到U8C仓库多个", facilityCode, bdCalbodyEntities.get(0).getPkCalbody());
                        }

                        ReturnOrderHeaderDto returnOrderHeaderDto = new ReturnOrderHeaderDto();
                        returnOrderHeaderDto.setPurchaseReturnOrder(purchaseReturnOrder);
                        returnOrderHeaderDto.setScOrderEntity(scOrderEntity);
                        returnOrderHeaderDto.setScOrderBEntityList(scOrderBEntityList);
                        returnOrderHeaderDto.setBdCorpEntity(bdCorpEntityList.get(0));
                        returnOrderHeaderDto.setBdCalbodyEntity(bdCalbodyEntities.get(0));
                        returnOrderHeaderDto.setBdStordocEntity(bdStordocEntityList.get(0));
                        returnOrderHeaderDto.setDetails(details);
                        returnOrderHeaderDto.setOfsPoOrder(ofsPoOrder);

                        BeanUtil.copyPropertiesV2(header, returnOrderHeaderDto);
                        consignmachiningInSonDtoArrayList.add(returnOrderHeaderDto);
                    } catch (Exception e) {
                        logger.error("采购入库单OFS档案转换错误", e);

                        String message = e.getMessage();
                        if (message == null) {
                            message = "未知错误";
                        }
                        //失败
                        IntegrationTaskLivingDetailsEntity integrationTaskLivingDetailsEntity = new IntegrationTaskLivingDetailsEntity();
                        integrationTaskLivingDetailsEntity.setNewState(ProfilesActiveConstant.LOG_STATUS_N);
                        integrationTaskLivingDetailsEntity.setRootAppNewData(JSON.toJSONString(headerDetailsDto));//原始数据json
                        integrationTaskLivingDetailsEntity.setNewTransmitInfo(JSON.toJSONString(message));//返回结果
                        integrationTaskLivingDetailsEntity.setNewPushDate(new Date());
                        integrationTaskLivingDetailsEntity.setBusinessDate(generateBusinessDate);
                        integrationTaskLivingDetailsEntity.setRootAppPk(header.getId());
                        integrationTaskLivingDetailsEntity.setRootAppBill(header.getCode());
                        integrationTaskLivingDetailsEntity.setPluginId(getPluginId());
                        saveOrUpdateBusinessLogUtil.saveOrUpdate(integrationTaskLivingDetailsEntity);
                    }
                }
                //成功
            } catch (Exception e) {
                logger.error("委外入库OFS档案转换", e);
                //失败
            }
        } else {
            logger.info("queryBasicArchives对应returnGoodHeaderDetailsDataDtoList.size为0");
        }
        return consignmachiningInSonDtoArrayList;
    }

    /**
     * 查询委外订单表头对象
     *
     * @author liuyang
     */
//    private ScOrderEntity queryScOrder(String ofsPoOrderId) {
//        Assert.notNull(ofsPoOrderId, "ofsPoOrderId不能为空!");
//        Assert.state(!"".equals(ofsPoOrderId.trim()), "ofsPoOrderId不能为空");
//
//        ScOrderEntity scOrderEntity = new ScOrderEntity();
//        scOrderEntity.setVdef20(ofsPoOrderId);
//        scOrderEntity.setDr("0");
//        scOrderEntity.setDataSourceCode("lets_u8c");
//        List<ScOrderEntity> scOrderEntityList = iScOrderDao.query(scOrderEntity);
//        if (scOrderEntityList == null || scOrderEntityList.size() == 0) {
//            Assert.state(false, "根据O采购订单主键:{}(u委外订单自定义项20存储O采购订单主键)，无法匹配到U8C委外订单", ofsPoOrderId);
//        } else if (scOrderEntityList.size() >= 2) {
//            Assert.state(false, "根据O采购订单主键:{}(u委外订单自定义项20存储O采购订单主键)，匹配到{}个U8C委外订单", ofsPoOrderId, scOrderEntityList.size());
//        }
//        return scOrderEntityList.get(0);
//    }

    /**
     * 2024年8月25日 14:11:31 查询U8C委外订单明细
     *
     * @param corderid 委外订单表头主键
     * @author liuyang
     */
//    private List<ScOrderBEntity> queryScOrderDetail(String corderid) throws Exception {
//        Assert.notNull(corderid, "委外订单表头主键不能为空！");
//        Assert.state(!"".equals(corderid), "委外订单表头主键不能为空！");
//
//        ScOrderBEntity scOrderBEntity = new ScOrderBEntity();
//        scOrderBEntity.setCorderid(corderid);
//        scOrderBEntity.setDr("0");
//        scOrderBEntity.setDataSourceCode("lets_u8c");
//        List<ScOrderBEntity> scOrderBEntityList = iScOrderBDao.query(scOrderBEntity);
//        if (scOrderBEntityList == null || scOrderBEntityList.size() == 0) {
//            //2024年8月25日 14:16:31 这个验证非常要必要，单据如果没有表体没有行，是很可疑的
//            Assert.state(false, "根据U8C委外订单主键({})无法查询到委外订单表体明细行！", corderid);
//        }
//        return scOrderBEntityList;
//    }

    /**
     * 匹配U8C采购订单明细行
     * 通过O采购入库单明细行，得到采购订单明细行，最后查找到U8C采购订单明细行
     *
     * @param stockinB           OFS采购入库单明细行
     * @param ofsPoOrderData     OFS采购订单
     * @param scOrderBEntityList U8C委外订单明细行
     * @author liuyang
     */
//    private ScOrderBEntity findOfsPoOrderDetailAndU8cPoOrderDetail(StockinOrderSearchResponse.StockinOrder.StockinB stockinB, OfsPoOrderData ofsPoOrderData, List<ScOrderBEntity> scOrderBEntityList) {
//        Assert.notNull(stockinB, "stockinB不能为空");
//        Assert.notNull(ofsPoOrderData, "ofsPoOrderData不能为空");
//        Assert.notNull(scOrderBEntityList, "scOrderBEntityList删除不能为空");
//
////        OfsPoOrderHeader header = ofsPoOrderData.getHeader();
//        List<OfsPoOrderDetails> details = ofsPoOrderData.getDetails();
//
//        //查找采购订单明细行
//        OfsPoOrderDetails tarGetOfsPoOrderDetails = null;
//        for (int i = 0; i < details.size(); i++) {
//            OfsPoOrderDetails ofsPoOrderDetails = details.get(i);
//            if (ofsPoOrderDetails.getId().equals(stockinB.getRefOrderDetailId())) {
//                tarGetOfsPoOrderDetails = ofsPoOrderDetails;
//            }
//        }
//        Assert.notNull(tarGetOfsPoOrderDetails, "无法匹配到采购订单明细行！ 目标主键：{}", stockinB.getRefOrderDetailId());
//
//        //根据采购订单明细行主键，查找U8C采购订单明细行
//        for (int i = 0; i < scOrderBEntityList.size(); i++) {
//            ScOrderBEntity scOrderBEntity = scOrderBEntityList.get(i);
//            Assert.notNull(scOrderBEntity.getVdef20(), "委外订单明细行v20不能为空(明细行v20存储O采购订单明细行主键)！");
//            Assert.state(!"".equals(scOrderBEntity.getVdef20()), "委外订单明细行v20不能为空(明细行v20存储O采购订单明细行主键)！");
//            if (tarGetOfsPoOrderDetails.getId().equals(scOrderBEntity.getVdef20())) {
//                return scOrderBEntity;
//            }
//        }
//        Assert.state(false, "通过U8C采购订单明细行主键层层匹配到U8C采购明细失败！");
//        return null;
//    }


    /**
     * 匹配U8C采购订单明细行
     * 通过O采购入库单明细行，得到采购订单明细行，最后查找到U8C采购订单明细行
     *
     * @param stockinB       OFS采购入库单明细行
     * @param ofsPoOrderData OFS采购订单
     * @author liuyang
     */
//    private OfsPoOrderDetails findOfsPoOrderDetailRowTraget(StockinOrderSearchResponse.StockinOrder.StockinB stockinB, OfsPoOrderData ofsPoOrderData) {
//        Assert.notNull(stockinB, "stockinB不能为空");
//        Assert.notNull(ofsPoOrderData, "ofsPoOrderData不能为空");
//
//        List<OfsPoOrderDetails> details = ofsPoOrderData.getDetails();
//        for (int i = 0; i < details.size(); i++) {
//            OfsPoOrderDetails ofsPoOrderDetails = details.get(i);
//            if (ofsPoOrderDetails.getId().equals(stockinB.getRefOrderDetailId())) {
//                return ofsPoOrderDetails;
//            }
//        }
//        Assert.state(false, "通过OFS采购入库单，无法匹配到OFS采购订单明细行！ 目标主键：{}", stockinB.getRefOrderDetailId());
//        return null;
//    }

    /**
     * 查询存货管理档案
     *
     * @param pkCorp     发货公司主键
     * @param detailsDto 采购入库单明细行
     * @author liuyang
     */
    private BdInvmandocEntity queryInventoryMan(DetailsDto detailsDto, String pkCorp) throws Exception {
        Assert.notNull(detailsDto, "sonDetailsDto不能为空");
        Assert.notNull(detailsDto.getSkuCode(), "O存货商家编码不能为空");
        Assert.notNull(pkCorp, "发货公司主键不能为空");

        BdInvmandocEntity bdInvmandocEntity = new BdInvmandocEntity();
        bdInvmandocEntity.setInvcode(detailsDto.getSkuCode());
        bdInvmandocEntity.setPkCorp(pkCorp);
        List<BdInvmandocEntity> bdInvmandocEntity2 = iBdInvmandocDao.queryBdInvmandocByInvcodeList(bdInvmandocEntity);
        if (bdInvmandocEntity2.size() == 0) {
            Assert.state(false, "根据O商家编码：{} U8C发货公司主键：{}没有查询到存货管理档案", detailsDto.getSkuCode(), pkCorp);
        } else if (bdInvmandocEntity2.size() >= 2) {
            Assert.state(false, "根据O商家编码：{} U8C发货公司主键：{}没有查询到存货管理档案", detailsDto.getSkuCode(), pkCorp);
        }
        return bdInvmandocEntity2.get(0);
    }

    /**
     * 2024年8月25日 15:12:22
     * 推送U8C委外订单
     *
     * @param param 原数据json
     * @author liuyang
     */
    public IcGeneralHResultDto sendU8cScorder(String param) throws Exception {
        long startLong = System.currentTimeMillis();
        logger.info("U8C委外订单推送开始，推送参数：" + param + ",U8C_URL:" + OverallConstant.getOverAllValue("u8c_url"));
        String apiCode = "8000370037";
        String result = HttpRequest.post(OverallConstant.getOverAllValue("u8c_url")).header("appId", "800037")//头信息，多个头信息多次调用此方法即可
                .header("usercode", "admin").header("password", "21232f297a57a5a743894a0e4a801fc3").header("system", "lz").header("trantype", "PK").header("apiCode", apiCode)//头信息，多个头信息多次调用此方法即可
                .header("publicKey", "ZJYAWb7lhAUTYqekPkU+uHJv1/ObJxb7dT7sD8HPRDGAgyhCe7eDIk+3zDUT+v578prj")//头信息，多个头信息多次调用此方法即可
                .header("secretKey", "fviZnLBsQUAGF8w8FSOdJi7XlIm/XAZclMxRagDLfTyJFlvnIBF3w66Hrpfzs8cYj3JzOP8MtA1LSGvL+2BWG8c/o7DKi92S4mr3zcGearA=")//头信息，多个头信息多次调用此方法即可
                .body(param)//表单内容
                .timeout(600000)//超时，毫秒
                .execute().body();
        logger.info("U8C委外订单推送结束，返回参数：" + result);
        long endLong = System.currentTimeMillis();
        logger.info("U8C委外订单推送耗时：" + (endLong - startLong));

        if (result == null) {
            result = "";
        }

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

        boolean isSuccess = false;
        IcGeneralHResultDto icGeneralHResultDto = null;
        if (result != null && !"".equals(result)) {
            ReusltStrDto reusltStrDto = JSON.parseObject(result, ReusltStrDto.class);
            if ("success".equals(reusltStrDto.getStatus())) {
                icGeneralHResultDto = resultDataHandle(reusltStrDto.getData());
                isSuccess = true;
            }
        }
        if (!isSuccess) {
            Assert.state(false, "O采购入库业务推送U8C委外订单失败 接口返回结果：{}", result);
        }
        return icGeneralHResultDto;
    }

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

    /**
     * 查询采退订单
     *
     * @param code 采退订单号
     * @author liuyang
     */
    private PurchaseReturnOrder queryPurchaseReturnOrder(String code) throws Exception {
        List<PurchaseReturnOrder> headerDetailsDtoList = new ArrayList<>();
        QueryOfsSoSaleOutVo queryOfsSoSaleOutVo = new QueryOfsSoSaleOutVo();
        queryOfsSoSaleOutVo.setCode(code);
        queryOfsSoSaleOutVo.setClientCode("LETS");
        queryOfsSoSaleOutVo.setPageNo(1L);
        queryOfsSoSaleOutVo.setPageSize(50L);
        ofsStandardUtil.queryPurchaseReturnOrder(queryOfsSoSaleOutVo, headerDetailsDtoList, 1L, "ofs.purchaseReturnOrder.search");
        if (headerDetailsDtoList.size() > 0) {
            return headerDetailsDtoList.get(0);
        }
        Assert.state(false, "根据OFS采购订单号:{}无法查询到OFS采购订单信息", code);
        return null;
    }

    /**
     * 2024年8月20日 15:46:10
     * 生成业务日期，以发货时间作为业务日期
     *
     * @author liuyang
     */
    private String createGenerateBusinessDate(ReturnOrderHeaderDto returnOrderHeaderDto) throws Exception {
        if (returnOrderHeaderDto != null && returnOrderHeaderDto.getShipAt() != null) {
            String shipAt = returnOrderHeaderDto.getShipAt();
            String businessFormat = null;
            try {
                Date dbill = DateUtil.parse(shipAt);
                businessFormat = DateUtil.format(dbill, "yyyy-MM-dd");
            } catch (Exception e) {
                logger.error("业务日期生成失败!", e);
            }
            return businessFormat;
        } else {
            logger.error("生成采退出库日期失败，或者shipAt为空! json：{}", JSON.toJSON(returnOrderHeaderDto));
            Assert.state(false, "生成采退出库日期失败，或者shipAt为空! json：{}", JSON.toJSON(returnOrderHeaderDto));
            return null;
        }
    }

    /**
     * 2024年8月20日 15:46:10
     * 生成业务日期，以发货时间作为业务日期
     *
     * @author liuyang
     */
    private String createGenerateBusinessDatev2(HeaderDto header) throws Exception {
        if (header != null) {
            String shipAt = header.getShipAt();
            String businessFormat = null;
            try {
                Date dbill = DateUtil.parse(shipAt);
                businessFormat = DateUtil.format(dbill, "yyyy-MM-dd");
            } catch (Exception e) {
                logger.error("业务日期生成失败!", e);
            }
            return businessFormat;
        } else {
            logger.error("生成采退出库日期失败，或者shipAt为空! json：{}", JSON.toJSON(header));
            Assert.state(false, "生成采退出库日期失败，或者shipAt为空! json：{}", JSON.toJSON(header));
            return null;
        }
    }

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

    /**
     * 2024年8月20日 16:42:14
     * 查找对应的采购订单明细行
     * 2024年8月20日 17:42:15
     * 应该通过明细行主键匹配，但是只能根据sku匹配目前的实现逻辑
     * 查找OFS采购订单明细行，主要是为了带出实付金额，通过实付金额/实收数量=含税单价
     *
     * @param ofsPoOrderDataDetails OFS采退订单明细行所有对象
     * @param detailsDto            OFS采退入库单明细行对象
     * @author liuyang
     */
    private PurchaseReturnOrderDetails findOfsPoOrderDetail(List<PurchaseReturnOrderDetails> ofsPoOrderDataDetails, DetailsDto detailsDto) {
        if (ofsPoOrderDataDetails != null && ofsPoOrderDataDetails.size() > 0 && detailsDto != null) {
            for (int i = 0; i < ofsPoOrderDataDetails.size(); i++) {
                Assert.notNull(ofsPoOrderDataDetails.get(i).getId(), "采退订单明细行主键不能为空!");

                Assert.notNull(detailsDto.getRefOrderDetailId(), "采退出库单明细行对应的关联采退订单的明细行主键不能为空！");
                if (ofsPoOrderDataDetails.get(i).getId().equals(detailsDto.getRefOrderDetailId())) {
                    return ofsPoOrderDataDetails.get(0);
                }
            }
        } else {
            logger.error("findOfsPoOrderDetail方法对应的ofsPoOrderDataDetails不能为空！否则业务目标无法完成！");
        }
        Assert.state(false, "无法匹配到采退订单明细行，业务逻辑无法完成！");
        return null;
    }

    /**
     * 查询委外订单表头对象
     *
     * @param ofsPoOrderId OFS采退订单主键
     * @author liuyang
     */
    private ScOrderEntity queryScOrder(String ofsPoOrderId) {
        Assert.notNull(ofsPoOrderId, "OFS采退订单主键不能为空!");
        Assert.state(!"".equals(ofsPoOrderId.trim()), "OFS采退订单主键不能为空!");

        ScOrderEntity scOrderEntity = new ScOrderEntity();
        scOrderEntity.setVdef17(ProfilesActiveConstant.sourceSystem1);
        scOrderEntity.setVdef20(ofsPoOrderId);
        scOrderEntity.setDr("0");
        scOrderEntity.setDataSourceCode("lets_u8c");
        List<ScOrderEntity> scOrderEntityList = iScOrderDao.query(scOrderEntity);
        if (scOrderEntityList == null || scOrderEntityList.size() == 0) {
            Assert.state(false, "根据O采购订单主键:{}(u委外订单自定义项20存储O采购订单主键)，无法匹配到U8C委外订单", ofsPoOrderId);
        } else if (scOrderEntityList.size() >= 2) {
            Assert.state(false, "根据O采购订单主键:{}(u委外订单自定义项20存储O采购订单主键)，匹配到{}个U8C委外订单", ofsPoOrderId, scOrderEntityList.size());
        }
        return scOrderEntityList.get(0);
    }

    /**
     * 2024年8月25日 14:11:31 查询U8C委外订单明细
     *
     * @param corderid 委外订单表头主键
     * @author liuyang
     */
    private List<ScOrderBEntity> queryScOrderDetail(String corderid) throws Exception {
        Assert.notNull(corderid, "委外订单表头主键不能为空！");
        Assert.state(!"".equals(corderid), "委外订单表头主键不能为空！");

        ScOrderBEntity scOrderBEntity = new ScOrderBEntity();
        scOrderBEntity.setCorderid(corderid);
        scOrderBEntity.setDr("0");
        scOrderBEntity.setDataSourceCode("lets_u8c");
        List<ScOrderBEntity> scOrderBEntityList = iScOrderBDao.query(scOrderBEntity);
        if (scOrderBEntityList == null || scOrderBEntityList.size() == 0) {
            //2024年8月25日 14:16:31 这个验证非常要必要，单据如果没有表体没有行，是很可疑的
            Assert.state(false, "根据U8C委外订单主键({})无法查询到委外订单表体明细行！", corderid);
        }
        return scOrderBEntityList;
    }

    /**
     * 2024年8月6日 10:59:03 查询U8C业务流程
     *
     * @author liuyang
     */
    private BdBusitypeEntity u8cOperationFlow() throws Exception {
//        Assert.notNull(pkCorp, "公司主键不能为空！");
//        Assert.state(!"".equals(pkCorp.trim()), "公司主键不能为空！");
        //查询业务流程
        //2024年8月6日 11:33:07 具体的业务流程名称，还需要实施提供
        String processName = "委外加工";
        BdBusitypeEntity bdBusitypeEntity = queryBdBusitypeUtil.queryBdBusitype(processName);
        Assert.notNull(bdBusitypeEntity, "根据业务流程名称({})没有查询到业务流程", processName);
        return bdBusitypeEntity;
    }

    /**
     * 匹配U8C采购订单明细行
     * 通过O采退出库单明细行，匹配到O采退订单明细行，再匹配到O采购订单明细行，最后匹配到U8C采购订单明细行
     *
     * @param detailsDto          OFS采退出库单明细行
     * @param purchaseReturnOrder O采退订单
     * @param ofsPoOrderData      O采购订单
     * @param scOrderBEntityList  U8C委外订单明细行
     * @author liuyang
     */
    private ScOrderBEntity findOfsPoOrderDetailAndU8cPoOrderDetail(DetailsDto detailsDto, PurchaseReturnOrder purchaseReturnOrder, OfsPoOrderData ofsPoOrderData, List<ScOrderBEntity> scOrderBEntityList) throws Exception {
        Assert.notNull(detailsDto, "detailsDto不能为空！");
        Assert.notNull(purchaseReturnOrder, "purchaseReturnOrder不能为空！");
        Assert.notNull(ofsPoOrderData, "ofsPoOrderData不能为空！");
        Assert.notNull(scOrderBEntityList, "scOrderBEntityList删除不能为空！");

        //通过O采退出库单明细行，匹配到O采退订单明细行
        PurchaseReturnOrderDetails targetPurchaseReturnOrderDetails = null;
        List<PurchaseReturnOrderDetails> details = purchaseReturnOrder.getDetails();
        for (int i = 0; i < details.size(); i++) {
            PurchaseReturnOrderDetails purchaseReturnOrderDetails = details.get(i);
            if (detailsDto.getRefOrderDetailId().equals(purchaseReturnOrderDetails.getId())) {
                targetPurchaseReturnOrderDetails = purchaseReturnOrderDetails;
            }
        }
        Assert.notNull(targetPurchaseReturnOrderDetails, "通过O采退出库单明细行关联主键，无法匹配到O采退订单明细行！", detailsDto.getRefOrderDetailId());

        //通过O采退订单明细行，再匹配到O采购订单明细行
        OfsPoOrderDetails targetOfsPoOrderDetails = null;
        List<OfsPoOrderDetails> details1 = ofsPoOrderData.getDetails();
        for (int i = 0; i < details1.size(); i++) {
            OfsPoOrderDetails ofsPoOrderDetails = details1.get(i);
            if (ofsPoOrderDetails.getId().equals(targetPurchaseReturnOrderDetails.getSourceLineNum())) {
                targetOfsPoOrderDetails = ofsPoOrderDetails;
            }
        }
        Assert.notNull(targetOfsPoOrderDetails, "通过O采退订单明细行的sourceLineNum，无法匹配采退订单明细的id，匹配失败!", targetPurchaseReturnOrderDetails.getSourceLineNum());

        //通过O采购订单明细行，匹配到U8C委外订单明细行
        for (int i = 0; i < scOrderBEntityList.size(); i++) {
            ScOrderBEntity scOrderBEntity = scOrderBEntityList.get(i);
            if (targetOfsPoOrderDetails.getId().equals(scOrderBEntity.getVdef20())) {
                return scOrderBEntity;
            }
        }
        Assert.state(false, "通过O采购订单明细行：{}，无法匹配到U8C委外订单明细行！", targetOfsPoOrderDetails.getId());
        return null;
    }

    /**
     * 根据采退订单，关联查询到OFS采购订单
     *
     * @author liuyang
     */
    private OfsPoOrderData queryOfsPoOrder(PurchaseReturnOrder purchaseReturnOrder) throws Exception {
        Assert.notNull(purchaseReturnOrder, "purchaseReturnOrder不能为空");
        PurchaseReturnOrderHeader header = purchaseReturnOrder.getHeader();
        List<PurchaseReturnOrderDetails> details = purchaseReturnOrder.getDetails();

        String refOrderCode = header.getRefOrderCode();
        OfsPoOrderData ofsPoOrderData = ofsStandardUtil.queryOfsPoOrder(refOrderCode);
        Assert.notNull(ofsPoOrderData, "根据编码：{}无法查询到OFS采购订单", refOrderCode);
        OfsPoOrderHeader header1 = ofsPoOrderData.getHeader();
        List<OfsPoOrderDetails> details1 = ofsPoOrderData.getDetails();
        if (header1 == null) {
            Assert.state(false, "根据编码：{}查询到的OFS采购订单，没有表头对象", refOrderCode);
        }
        if (details1 == null) {
            Assert.state(false, "根据编码：{}查询到的OFS采购订单，没有明细对象", refOrderCode);
        }
        return ofsPoOrderData;
    }

    /**
     * 2024年8月30日 14:09:26
     * 推送U8C入库单
     *
     * @param param 原数据json
     * @author liuyang
     */
    public IcGeneralHResultDto sendU8cConsignmachiningIn(String param) throws Exception {
        long startLong = System.currentTimeMillis();
        logger.info("U8C委外入库推送开始，推送参数：" + param + ",U8C_URL:" + OverallConstant.getOverAllValue("u8c_url"));
        String apiCode = "8000370056";
        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("U8C委外入库推送结束，返回参数：" + result);
        long endLong = System.currentTimeMillis();
        logger.info("U8C委外入库推送耗时：" + (endLong - startLong));

        if (result == null) {
            result = "";
        }

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

        boolean isSuccess = false;
        IcGeneralHResultDto icGeneralHResultDto = null;
        if (result != null && !"".equals(result)) {
            ReusltStrDto reusltStrDto = JSON.parseObject(result, ReusltStrDto.class);
            if ("success".equals(reusltStrDto.getStatus())) {
                icGeneralHResultDto = resultDataHandle(reusltStrDto.getData());
                isSuccess = true;
            }
        }
        if (!isSuccess) {
            Assert.state(false, "O采购入库业务推送U8C委外入库失败 接口返回结果：{}", result);
        }
        return icGeneralHResultDto;
    }

    /**
     * 匹配U8C采购订单明细行
     * 通过O采购入库单明细行，得到采购订单明细行，最后查找到U8C采购订单明细行
     *
     * @param detailsDto          OFS采退出库单明细行
     * @param purchaseReturnOrder OFS采退订单
     * @author liuyang
     */
    private PurchaseReturnOrderDetails findOfsPoOrderDetailRowTraget(DetailsDto detailsDto, PurchaseReturnOrder purchaseReturnOrder) {
        Assert.notNull(detailsDto, "detailsDto不能为空");
        Assert.notNull(purchaseReturnOrder, "purchaseReturnOrder不能为空");

        List<PurchaseReturnOrderDetails> details = purchaseReturnOrder.getDetails();
        for (int i = 0; i < details.size(); i++) {
            PurchaseReturnOrderDetails purchaseReturnOrderDetails = details.get(i);
            if (purchaseReturnOrderDetails.getId().equals(detailsDto.getRefOrderDetailId())) {
                return purchaseReturnOrderDetails;
            }
        }
        Assert.state(false, "通过OFS采退出库单，无法匹配到OFS采退订单明细行！ 目标主键：{}", detailsDto.getRefOrderDetailId());
        return null;
    }


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

            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(",");
                        startImplementByTime(split[0], split[1]);
                    }
                }
            } else {
                String[] split = param.split(",");
                startImplementByTime(split[0], split[1]);
            }
        } catch (Exception e) {
            logger.error("记录splitDateAndPush方法抛出的异常", e);
        }
    }
}