package com.prolog.cs.biz.outbound.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.esotericsoftware.minlog.Log;
import com.github.pagehelper.PageHelper;
import com.prolog.cs.basic.chain.model.cargo.BaseCargoOwnerMst;
import com.prolog.cs.basic.chain.model.carrier.BaseCarrierMst;
import com.prolog.cs.basic.chain.model.customer.BaseCustomerMst;
import com.prolog.cs.basic.chain.model.supplier.BaseSupplierMst;
import com.prolog.cs.basic.chain.vo.carrier.BaseCarrierMstRequestVO;
import com.prolog.cs.basic.common.model.BaseBizFile;
import com.prolog.cs.basic.common.model.BaseCommonDict;
import com.prolog.cs.basic.item.model.BaseMtlItemMst;
import com.prolog.cs.basic.item.model.vo.ItemMstQueryVO;
import com.prolog.cs.basic.item.model.vo.ItemMstVO2;
import com.prolog.cs.basic.warehouse.model.BaseWmsWarehouseMst;
import com.prolog.cs.biz.inbound.constant.InboundBizConstant;
import com.prolog.cs.biz.inbound.model.SupervisionCode;
import com.prolog.cs.biz.inbound.vo.CancelOrderOmsVO;
import com.prolog.cs.biz.outbound.convert.TmsConvert;
import com.prolog.cs.biz.outbound.dao.*;
import com.prolog.cs.biz.outbound.enums.PickTaskDFLowStatus;
import com.prolog.cs.biz.outbound.enums.PickTaskHStatus;
import com.prolog.cs.biz.outbound.model.OmsDoBillHDO;
import com.prolog.cs.biz.outbound.model.PickTaskD;
import com.prolog.cs.biz.outbound.model.PickTaskH;
import com.prolog.cs.biz.outbound.model.SaleRedRecord;
import com.prolog.cs.biz.outbound.model.dto.LicenseImageDTO;
import com.prolog.cs.biz.outbound.model.dto.OmsDoBillHDTO;
import com.prolog.cs.biz.outbound.model.dto.WavesCreateDTO;
import com.prolog.cs.biz.outbound.model.entity.*;
import com.prolog.cs.biz.outbound.model.tms.TmsShipBill;
import com.prolog.cs.biz.outbound.model.tms.TmsShipBillItem;
import com.prolog.cs.biz.outbound.model.vo.*;
import com.prolog.cs.biz.outbound.resource.*;
import com.prolog.cs.biz.outbound.service.BillDPrePositionService;
import com.prolog.cs.biz.outbound.service.IOmsDoBillHService;
import com.prolog.cs.biz.outbound.service.MqOutBoundProducer;
import com.prolog.cs.biz.outbound.service.WavesSpecialService;
import com.prolog.entity.vo.CancelTasksVO;
import com.prolog.enums.CancelTasksEnum;
import com.prolog.framework.authority.core.dto.UserDTO;
import com.prolog.framework.authority.user.UserTemplate;
import com.prolog.framework.bz.core.model.ModelUtils;
import com.prolog.framework.common.message.RestMessage;
import com.prolog.framework.core.exception.BizException;
import com.prolog.framework.core.exception.ParameterException;
import com.prolog.framework.core.exception.PrologException;
import com.prolog.framework.core.pojo.Page;
import com.prolog.framework.core.restriction.Criteria;
import com.prolog.framework.core.restriction.FieldSelector;
import com.prolog.framework.core.restriction.Restriction;
import com.prolog.framework.core.restriction.Restrictions;
import com.prolog.framework.dao.util.PageUtils;
import com.prolog.framework.utils.*;
import com.prolog.inte.EisHandler;
import com.prolog.upcloud.base.inventory.model.WmsInvBatchNumbers;
import com.prolog.upcloud.base.inventory.vo.AskIntegrationVo;
import com.prolog.upcloud.base.inventory.vo.WmsInvStockQtyVO;
import com.prolog.upcloud.base.strategy.model.BusinessControl;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * 出库单业务处理类
 *
 * @author lihao
 * @since 2021/12/18
 */
@Slf4j
@Service
public class OmsDoBillHServiceImpl implements IOmsDoBillHService {

    @Autowired
    private CommonClient commonClient;

    @Autowired
    private ItemClient itemClient;

    @Autowired
    private UserTemplate userTemplate;

    @Autowired
    private OmsDoBillHMapper omsDoBillHMapper;

    @Autowired
    private OmsDoBillDMapper omsDoBillDMapper;

    @Value("${prolog.dao.keyGenerator.snowFlake.dataCenterId:15}")
    private long dataCenterId;

    @Value("${prolog.dao.keyGenerator.snowFlake.machineId:2}")
    private long machineId;

    @Autowired
    private WarehouseResource warehouseResource;

    @Autowired
    private ChainResource chainResource;

    @Autowired
    private InBoundClient inBoundClient;

    @Autowired
    private WaveMapper waveMapper;

    @Autowired
    private WaveBillMapper billMapper;

    @Autowired
    private SaleRedRecordMapper saleRedRecordMapper;

    @Resource
    private InventoryResource inventoryResource;

    @Resource
    private MqOutBoundProducer producer;
    @Resource
    private TmsConvert convert;

    @Autowired
    private BillDPrePositionService billDPrePositionService;
    @Autowired
    private WavesSpecialService wavesSpecialService;
    @Autowired
    private PickTaskHMapper pickTaskHMapper;
    @Autowired
    private PickTaskDMapper pickTaskDMapper;
    @Autowired
    private BarcodeHMapper barcodeHMapper;
    @Autowired
    private BarcodeDMapper barcodeDMapper;
    @Resource
    private EisHandler eisHandler;
    @Resource
    private WaveBillMapper waveBillMapper;
    @Autowired
    private InvoicePdfDOMapper invoicePdfDOMapper;

    @Autowired
    private StrategyResource strategyResource;

    @Override
    public Page<OmsDoBillHDO> queryDoBillHList(OmsDoBillHDO omsDoBillHDO) {
        //        UserDTO userDTO = userTemplate.getUserDTO();
        PageHelper.startPage(omsDoBillHDO.getPageNum(), omsDoBillHDO.getPageSize());
        Criteria crt = Criteria.forClass(OmsDoBillHDO.class);
        Restriction r1 = StringUtils.isBlank(omsDoBillHDO.getBillno()) ? null : Restrictions.like("billno", "%" + omsDoBillHDO.getBillno() + "%");
        Restriction r2 = omsDoBillHDO.getBillDateStart() == null ? null : Restrictions.between("createdate", omsDoBillHDO.getBillDateStart(), omsDoBillHDO.getBillDateEnd());
        Restriction r3 = StringUtils.isBlank(omsDoBillHDO.getBranchid()) ? null : Restrictions.eq("branchid", omsDoBillHDO.getBranchid());
        Restriction r4 = StringUtils.isBlank(omsDoBillHDO.getConsignorid()) ? null : Restrictions.eq("consignorid", omsDoBillHDO.getConsignorid());
        Restriction r5 = StringUtils.isBlank(omsDoBillHDO.getShipperid()) ? null : Restrictions.eq("shipperid", omsDoBillHDO.getShipperid());
        Restriction r6 = StringUtils.isBlank(omsDoBillHDO.getArrivalMode()) ? null : Restrictions.eq("arrivalMode", omsDoBillHDO.getArrivalMode());
        crt.setRestriction(Restrictions.and(r1, r2, r3, r4, r5, r6));
        List<OmsDoBillHDO> list = omsDoBillHMapper.findByCriteria(crt);
        return PageUtils.getPage(list);
    }

    @Override
    @Transactional
    public Boolean saveDoBillH(OmsDoBillHDTO omsDoBillHDTO) {
        Date now = new Date();
        UserDTO userDTO = userTemplate.getUserDTO();
        List<OmsDoBillHDO> insertItems = omsDoBillHDTO.getInsertItems();
        List<OmsDoBillHDO> updateItems = omsDoBillHDTO.getUpdateItems();
        List<OmsDoBillHDO> deleteItems = omsDoBillHDTO.getDeleteItems();
        String billNo = String.valueOf(SnowFlakeUtils.getId(dataCenterId, machineId));
        if (CollectionUtil.isNotEmpty(insertItems)) {
            for (OmsDoBillHDO omsDoBillHDO : insertItems) {
                omsDoBillHDO.setBillid(billNo);
                omsDoBillHDO.setBillno(billNo);
                omsDoBillHDO.setBilltype("1");
                omsDoBillHDO.setRefBilltype("1");
                omsDoBillHDO.setRefBillid(billNo);
                omsDoBillHDO.setRefBillno(billNo);
                omsDoBillHDO.setShipperType("2"); // 客户
                omsDoBillHDO.setReceiveAddress("qn");
                omsDoBillHDO.setStatus("10");
                omsDoBillHDO.setCreateby(userDTO.getUsername());
                omsDoBillHDO.setCreatedate(now);
                omsDoBillHDO.setEnterpriseId(userDTO.getEnterpriseId());
                omsDoBillHDO.setEnterpriseName(userDTO.getEnterpriseName());
                for (OmsDoBillDDO omsDoBillDDO : omsDoBillHDO.getOmsDoBillDDOList()) {
                    omsDoBillDDO.setLineid(String.valueOf(SnowFlakeUtils.getId(dataCenterId, machineId)));
                    omsDoBillDDO.setSeqno(billNo);
                    omsDoBillDDO.setBillno(billNo);
                    omsDoBillDDO.setBranchid(omsDoBillHDO.getBranchid());
                    omsDoBillDDO.setBranchcode(omsDoBillHDO.getBranchcode());
                    omsDoBillDDO.setBranchname(omsDoBillHDO.getBranchname());
                    omsDoBillDDO.setConsignorid(omsDoBillHDO.getConsignorid());
                    omsDoBillDDO.setConsignorname(omsDoBillHDO.getConsignorname());
                    omsDoBillDDO.setCreateby(userDTO.getUsername());
                    omsDoBillDDO.setCreatedate(now);
                    omsDoBillDDO.setEnterpriseId(userDTO.getEnterpriseId());
                    omsDoBillDDO.setEnterpriseName(userDTO.getEnterpriseName());
                    omsDoBillDDO.setPdateFrom(null);
                    omsDoBillDDO.setValidUntil(null);
                }
            }
            omsDoBillHMapper.saveBatch(insertItems);
            if (CollectionUtil.isNotEmpty(insertItems.get(0).getOmsDoBillDDOList())) {
                for (OmsDoBillDDO omsDoBillDDO : insertItems.get(0).getOmsDoBillDDOList()) {
                    omsDoBillDDO.setBillid(insertItems.get(0).getBillid());
                }
                omsDoBillDMapper.saveBatch(insertItems.get(0).getOmsDoBillDDOList());
            }
        }
        if (CollectionUtil.isNotEmpty(updateItems)) {
            for (OmsDoBillHDO omsDoBillHDO : updateItems) {
                omsDoBillHDO.setRefBilltype("1");
                omsDoBillHDO.setRefBillid(billNo);
                omsDoBillHDO.setRefBillno(billNo);
                omsDoBillHDO.setShipperType("2"); // 客户
                omsDoBillHDO.setCreateby(userDTO.getUsername());
                omsDoBillHDO.setCreatedate(now);
                omsDoBillHMapper.update(omsDoBillHDO);
                for (OmsDoBillDDO omsDoBillDDO : omsDoBillHDO.getOmsDoBillDDOList()) {
                    omsDoBillDMapper.update(omsDoBillDDO);
                }
            }
        }
        if (CollectionUtil.isNotEmpty(deleteItems)) {
            for (OmsDoBillHDO omsDoBillHDO : deleteItems) {
                omsDoBillHMapper.deleteById(omsDoBillHDO.getBillid(), OmsDoBillHDO.class);
                for (OmsDoBillDDO omsDoBillDDO : omsDoBillHDO.getOmsDoBillDDOList()) {
                    omsDoBillDMapper.deleteById(omsDoBillDDO.getBillid(), OmsDoBillDDO.class);
                }
            }
        }
        return true;
    }

    @Override
    public List<OmsDoBillHDO> getDoBillHByBillNos(String[] billNos, String warehouseId) {
        UserDTO user = userTemplate.getUserDTO();
        Criteria crt = Criteria.forClass(OmsDoBillHDO.class);
        Restriction r1 = Restrictions.in("billno", billNos);
        Restriction r2 = Restrictions.eq("branchid", warehouseId);
        Restriction r3 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
        crt.setRestriction(Restrictions.and(r1, r2, r3));
        return omsDoBillHMapper.findByCriteria(crt);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean receiveOmsBill(List<OmsBillReceiveVo> omsBillReceiveVoList) {
        if (CollUtil.isEmpty(omsBillReceiveVoList)){
            log.error("出库单下发异常：{}", "下发数据为空");
            throw new ParameterException("下发数据为空");
        }

        for (OmsBillReceiveVo omsBillReceiveVo : omsBillReceiveVoList) {
            OmsBillHReceiveVo content = omsBillReceiveVo.getContent();
            if (null == content){
                log.error("出库单下发异常：{}", "订单数据为空");
                throw new ParameterException("订单数据为空");
            }
            List<OmsBillDReceiveVo> detailList = omsBillReceiveVo.getDetailList();
            if (CollUtil.isEmpty(detailList)){
                log.error("出库单下发异常：{}", "订单号【" + omsBillReceiveVo.getContent().getBillid() + "】下明细数据为空");
                throw new ParameterException("订单号【" + omsBillReceiveVo.getContent().getBillid() + "】下明细数据为空");
            }
            OmsDoBillHDO omsDoBillHDO;
            omsDoBillHDO = omsDoBillHMapper.findById(content.getBillid(), OmsDoBillHDO.class);
            if (omsDoBillHDO != null && !Objects.equals(omsDoBillHDO.getStatus(), "10")){
                log.info("出库单下发异常：{}", "订单号【" + omsBillReceiveVo.getContent().getBillid() + "】已下发，跳过！");
                continue;
            }
            if (omsDoBillHDO != null){
                if (omsDoBillHDO.getStatus().equals("10")) {
                    //已接收的订单，但还未下发，进行修改操作
                    this.updateOmsBill(omsBillReceiveVo, omsDoBillHDO);
                }else {
                    log.error("出库单下发异常：{}", "订单号【" + omsBillReceiveVo.getContent().getBillid() + "】已经创建波次，不能修改");
                    throw new ParameterException("订单号【" + omsBillReceiveVo.getContent().getBillid() + "】已经创建波次，不能修改");
                }
                continue;
            }
            this.insertOmsBill(omsBillReceiveVo);
        }
        return true;
    }

    @Override
    public List<CancelOrderOmsVO> cancelOrderOms(List<CancelOrderOmsVO> cancelList) {
        if (CollUtil.isEmpty(cancelList)) {
            throw new BizException("参数集合不能为空");
        }
        for (CancelOrderOmsVO cancelOrder : cancelList) {
            if (StringUtils.isEmpty(cancelOrder.getBillno())) {
                cancelOrder.setSuccess(false);
                cancelOrder.setMessage("订单编号不能为空");
                continue;
            }
            if (StringUtils.isEmpty(cancelOrder.getConsignorcode())) {
                cancelOrder.setSuccess(false);
                cancelOrder.setMessage("货主编号不能为空");
                continue;
            }
            if (StringUtils.isEmpty(cancelOrder.getBranchcode())) {
                cancelOrder.setSuccess(false);
                cancelOrder.setMessage("仓库编号不能为空");
                continue;
            }
            if (StringUtils.isEmpty(cancelOrder.getPenterpriseid())) {
                cancelOrder.setSuccess(false);
                cancelOrder.setMessage("企业ID不能为空");
                continue;
            }
            List<OmsDoBillHDO> byMap = omsDoBillHMapper.findByMap(MapUtils.put("billno", cancelOrder.getBillno())
                    .put("branchcode", cancelOrder.getBranchcode())
                    .put("consignorcode", cancelOrder.getConsignorcode())
                    .put("enterpriseId", cancelOrder.getPenterpriseid()).getMap(), OmsDoBillHDO.class);
            if (CollUtil.isEmpty(byMap)) {
                cancelOrder.setSuccess(false);
                cancelOrder.setMessage("未查找到对应单据");
                continue;
            }
            OmsDoBillHDO omsDoBillHDO = byMap.get(0);
            // 校验单据是否下发过
            if (!omsDoBillHDO.getStatus().equals("10") || omsDoBillHDO.getStatus().equals("5")) {
                cancelOrder.setSuccess(false);
                cancelOrder.setMessage("订单已下发或已取消,不可操作");
                continue;
            }
            // 更新出库单
            omsDoBillHMapper.updateMapById(omsDoBillHDO.getBillid(),MapUtils.put("status","5")
                    .put("closedReason",cancelOrder.getCancelReason())
                    .put("isCancelled", 1)
                    .put("attrStr1",cancelOrder.getOrderType())
                    .put("attrStr2",cancelOrder.getRemark())
                    .put("attrStr3",cancelOrder.getExtendProps()).getMap(),OmsDoBillHDO.class);
            Criteria crt = Criteria.forClass(OmsDoBillDDO.class);
            Restriction r1 = Restrictions.eq("billid", omsDoBillHDO.getBillid());
            crt.setRestriction(Restrictions.and(r1));
            omsDoBillDMapper.updateMapByCriteria(MapUtils.put("status", 5).getMap(),crt);
            cancelOrder.setSuccess(true);
            cancelOrder.setMessage("取消成功");
        }
        return cancelList;
    }

    @Override
    public RestMessage<List<LicenseImageDTO>> licenseImageDownload(List<LicenseImageDTO> imageList) {
        if (CollUtil.isEmpty(imageList)) {
            throw new BizException("参数集合不能为空");
        }
        List<LicenseImageDTO> cList = imageList.stream().filter(l->StrUtil.isBlank(l.getConsignorcode())).collect(Collectors.toList());
        List<LicenseImageDTO> comList = imageList.stream().filter(l->StrUtil.isBlank(l.getCompanycode())).collect(Collectors.toList());
        List<LicenseImageDTO> ctList = imageList.stream().filter(l->StrUtil.isBlank(l.getCertificateType())).collect(Collectors.toList());
        List<LicenseImageDTO> cuList = imageList.stream().filter(l->StrUtil.isBlank(l.getCertificateUrl())).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(cList)) {
            cList.forEach(licenseImageDTO->{
                licenseImageDTO.setSuccess(false);
                licenseImageDTO.setMessage("货主编号不能为空");
            });
            return new RestMessage(false,"500", "货主编号不能为空", cList);
        }
        if (CollUtil.isNotEmpty(comList)) {
            comList.forEach(licenseImageDTO->{
                licenseImageDTO.setSuccess(false);
                licenseImageDTO.setMessage("单位编号不能为空");
            });
            return new RestMessage(false,"500", "单位编号不能为空", comList);
        }
        if (CollUtil.isNotEmpty(ctList)) {
            ctList.forEach(licenseImageDTO->{
                licenseImageDTO.setSuccess(false);
                licenseImageDTO.setMessage("证照类型不能为空");
            });
            return new RestMessage(false,"500", "证照类型不能为空", ctList);
        }
        if (CollUtil.isNotEmpty(cuList)) {
            cuList.forEach(licenseImageDTO->{
                licenseImageDTO.setSuccess(false);
                licenseImageDTO.setMessage("证照URL不能为空");
            });
            return new RestMessage(false,"500", "证照URL不能为空", cuList);
        }
        // 商品信息
        List<BaseMtlItemMst> itemMstList = null;
        List<LicenseImageDTO> iList = imageList.stream().filter(l->l.getCertificateType().equals("1")).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(iList)) {
            List<String> itemIds = imageList.stream().map(var -> var.getCompanycode().trim()).collect(Collectors.toList());
            // 查询商品信息
            RestMessage<List<BaseMtlItemMst>> itemMsg = itemClient.getListByIds(new HashSet<>(itemIds));
            if (!itemMsg.isSuccess() || CollUtil.isEmpty(itemMsg.getData())) {
                throw new BizException("获取商品信息失败,商品code = " + String.join(",", itemIds));
            }
            itemMstList = itemMsg.getData();
        }
        // 供应商信息
        List<BaseSupplierMst> supplierMstList = null;
        List<LicenseImageDTO> sList = imageList.stream().filter(l->l.getCertificateType().equals("V")).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(sList)) {
            Set<String> supplierCodeList = imageList.stream().map(var -> var.getCompanycode().trim()).collect(Collectors.toSet());
            // 查询商品信息
            RestMessage<List<BaseSupplierMst>> supplierMstMsg = chainResource.getSupplierMstByCode(supplierCodeList);
            if (!supplierMstMsg.isSuccess() || CollUtil.isEmpty(supplierMstMsg.getData())) {
                throw new PrologException("获取客户信息失败,code = " + String.join(",", supplierCodeList));
            }
            supplierMstList = supplierMstMsg.getData();
        }
        // 客户信息
        List<BaseCustomerMst> customerMstList = null;
        List<LicenseImageDTO> customerList = imageList.stream().filter(l->l.getCertificateType().equals("C")).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(customerList)) {
            Set<String> customerCodeList = imageList.stream().map(var -> var.getCompanycode().trim()).collect(Collectors.toSet());
            // 查询商品信息
            RestMessage<List<BaseCustomerMst>> customerMstMsg = chainResource.getCustomerByCode(customerCodeList);
            if (!customerMstMsg.isSuccess() || CollUtil.isEmpty(customerMstMsg.getData())) {
                throw new PrologException("获取客户信息失败,code = " + String.join(",", customerCodeList));
            }
            customerMstList = customerMstMsg.getData();
        }

        // 图片集合
        List<BaseBizFile> bizFileList = new ArrayList<BaseBizFile>();
        BaseBizFile baseBizFile = null;
        for (LicenseImageDTO licenseImageDTO : imageList) {
            licenseImageDTO.setSuccess(true);
            licenseImageDTO.setMessage("操作成功");
            if (licenseImageDTO.getCertificateType().equals("1")) {
                // 商品,certificateType="1"
                if (CollUtil.isEmpty(itemMstList)) {
                    throw new BizException("获取商品信息失败");
                }
                BaseMtlItemMst baseMtlItemMst = itemMstList.stream().filter(var -> var.getItemId().equals(licenseImageDTO.getCompanycode())).findFirst().orElse(null);
                if (null == baseMtlItemMst) {
                    throw new BizException("获取商品信息失败");
                }
                baseBizFile = new BaseBizFile();
                baseBizFile.setBizType("02");
            } else if (licenseImageDTO.getCertificateType().equals("V")) {
                // 供应商,certificateType="V"
                if (CollUtil.isEmpty(supplierMstList)) {
                    throw new BizException("获取供应商信息失败");
                }
                BaseSupplierMst baseSupplierMst = supplierMstList.stream().filter(var -> var.getSupplierCode().equals(licenseImageDTO.getCompanycode())).findFirst().orElse(null);
                if (null == supplierMstList) {
                    throw new BizException("获取供应商信息失败");
                }
                baseBizFile = new BaseBizFile();
                baseBizFile.setBizType("01");
            } else {
                // 客户,certificateType="C"
                if (CollUtil.isEmpty(customerMstList)) {
                    throw new BizException("获取客户信息失败");
                }
                BaseCustomerMst baseCustomerMst = customerMstList.stream().filter(var -> var.getCustomerCode().equals(licenseImageDTO.getCompanycode())).findFirst().orElse(null);
                if (null == baseCustomerMst) {
                    throw new BizException("获取客户信息失败");
                }
                baseBizFile = new BaseBizFile();
                baseBizFile.setBizType("06");
            }
            baseBizFile.setBizId(licenseImageDTO.getCompanycode());
            baseBizFile.setName(licenseImageDTO.getFileName());
            baseBizFile.setCode("");
            baseBizFile.setDataType("");
            baseBizFile.setFileType(licenseImageDTO.getFileType());
            baseBizFile.setFileName(licenseImageDTO.getFileName());
            baseBizFile.setFileUrl(licenseImageDTO.getCertificateUrl());
            baseBizFile.setCreateBy("OMS");
            baseBizFile.setCreateDate(DateUtil.date());
            baseBizFile.setCreateName("OMS");
            baseBizFile.setLastmodifyBy("OMS");
            baseBizFile.setLastmodifyDate(DateUtil.date());
            baseBizFile.setLastmodifyName("OMS");
            bizFileList.add(baseBizFile);
        }
        if (CollUtil.isNotEmpty(bizFileList)) {
            try {
                Log.info("同步给图片管理数据=>" + JsonUtils.toString(bizFileList));
                RestMessage<Object> add = commonClient.add(bizFileList);
                if (add == null || !add.isSuccess()) {
                    String msg = "";
                    if (add != null) {
                        msg = add.getMessage();
                    }
                    log.error("远程调用图片管理新增异常,错误原因=>" + msg);
                }
            } catch (Exception e) {
                log.error("远程调用图片管理新增接口异常,错误原因=>" + e.getMessage());
                e.printStackTrace();
            }
        }
        return new RestMessage(true,"200", "下传成功", imageList);
    }

    @Override
    public void stockOutInvoice() {
        //查询已下发完成，未推送开票通知的波次
        Criteria criteria = Criteria.forClass(WaveDO.class);
        Restriction r1 = Restrictions.eq("status","COMPLETED");
        Restriction r2 = Restrictions.eq("seedNoticeFlag", "0");
        Restriction r3 = Restrictions.isnull("seedNoticeFlag");
        criteria.setRestriction( Restrictions.and(r1,Restrictions.or(r2, r3)));
        List<WaveDO> waveDOList = waveMapper.findByCriteria(criteria);
        if (CollectionUtil.isEmpty(waveDOList)) {
            return;
        }else {
            //取第一条数据
            WaveDO waveDO = waveDOList.get(0);
            //组装数据
            StockOutInvoiceBackErpVO backErpVO =new StockOutInvoiceBackErpVO();
            backErpVO.setWaveNo(waveDO.getId());
            List<StockOutInvoiceOrder> orderList =new ArrayList<>();

            //查询波次订单表
            Criteria crtWaveBill = Criteria.forClass(WaveBillDO.class);
            Restriction r4 = Restrictions.eq("waveId",waveDO.getId());
            crtWaveBill.setRestriction(r4);
            List<WaveBillDO> waveBillS = billMapper.findByCriteria(crtWaveBill);
            for (WaveBillDO waveBill : waveBillS) {
                //查询OMS交货单主表
                OmsDoBillHDO billDOH= omsDoBillHMapper.findById(waveBill.getSrcId(),OmsDoBillHDO.class);

                String isReverse ="0";
                StockOutInvoiceOrder invoiceOrder = new StockOutInvoiceOrder();
                invoiceOrder.setOrderNo(billDOH.getBillno());
                invoiceOrder.setIndustryline(billDOH.getItemHealthIndustry());

                //查询冲红记录表
                Criteria crtRedRecord = Criteria.forClass(SaleRedRecord.class);
                Restriction r5 = Restrictions.eq("srcId",waveDO.getId());
                crtRedRecord.setRestriction(r5);
                List<SaleRedRecord> redRecords = saleRedRecordMapper.findByCriteria(crtRedRecord);
                if(CollectionUtil.isNotEmpty(redRecords)){
                    List<StockOutInvoiceReverse> invoiceReverses = new ArrayList<>();
                    Map<String, List<SaleRedRecord>> whMoveList = redRecords.stream().filter(x -> ObjectUtil.isNotEmpty(x.getItemId())).collect(Collectors.groupingBy(SaleRedRecord::getItemId));
                    for (Map.Entry<String, List<SaleRedRecord>> entry : whMoveList.entrySet()) {
                        StockOutInvoiceReverse stockOutInvoiceReverse =new StockOutInvoiceReverse();
                        Double sumQty = entry.getValue().stream().mapToDouble(e -> e.getQty().doubleValue()).sum();
                        stockOutInvoiceReverse.setReverseNum(sumQty.toString());
                        stockOutInvoiceReverse.setGoodSn(entry.getKey());
                        invoiceReverses.add(stockOutInvoiceReverse);
                    }
                    isReverse ="1";//存在冲红数据
                    invoiceOrder.setReverseData(invoiceReverses);
                }
                invoiceOrder.setIsReverse(isReverse);
                orderList.add(invoiceOrder);
            }
            backErpVO.setOrderList(orderList);
            try {
                AskIntegrationVo vo = new AskIntegrationVo();
                vo.setIntegrationCode("stockOutInvoice");
                vo.setParam(backErpVO);
//                RestMessage<?> msg = inventoryResource.askIntegration(vo);
                RestMessage<?> restMessage = this.askIntegration("stockOutInvoice", backErpVO);
                if("1".equals(restMessage.getCode())){
                    Criteria crt = Criteria.forClass(WaveDO.class);
                    crt.restrictionBuilder().eq("id",waveDO.getId());
                    crt.buildRestriction();
                    waveMapper.updateMapByCriteria(MapUtils.put("seedNoticeFlag","1").getMap(),crt);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }


        }
    }

    /**
     * insert新接收的数据
     * @param omsBillReceiveVo 接收的数据
     */
    private void insertOmsBill(OmsBillReceiveVo omsBillReceiveVo){
        OmsDoBillHDO omsDoBillHDO = new OmsDoBillHDO();
        BeanUtil.copyProperties(omsBillReceiveVo.getContent(), omsDoBillHDO);
        omsDoBillHDO.setStatus("10");//默认是10
        omsDoBillHDO.setCreateby("OMS");
        omsDoBillHDO.setCreatedate(DateUtil.date());
        if (StrUtil.isEmpty(omsDoBillHDO.getEnterpriseId())){
            log.error("出库单下发异常：{}", "订单号【" + omsBillReceiveVo.getContent().getBillid() + "】下的【enterpriseId】为空");
            throw new ParameterException("企业id不能为空！");
        }
        if (StrUtil.isEmpty(omsDoBillHDO.getBranchcode())){
            log.error("出库单下发异常：{}", "订单号【" + omsBillReceiveVo.getContent().getBillid() + "】下的【branchcode】为空");
            throw new ParameterException("仓code不能为空！");
        }
        //查询收货人信息
        if (null == omsDoBillHDO.getShipperType()) {
            //不确定则先查询客户，客户不存在则查询供应商
            RestMessage<List<BaseCustomerMst>> restMessage = chainResource.getCustomerByCode(Collections.singleton(omsBillReceiveVo.getContent().getShipperCode()));
            if (!restMessage.isSuccess() || CollUtil.isEmpty(restMessage.getData())) {
                //查询供应商
                RestMessage<List<BaseSupplierMst>> supplierMst = chainResource.getSupplierMstByCode(Collections.singleton(omsBillReceiveVo.getContent().getShipperCode()));
                if (!supplierMst.isSuccess() || CollUtil.isEmpty(supplierMst.getData())) {
                    throw new PrologException("获取客户信息失败4 客户 code = " + omsBillReceiveVo.getContent().getShipperCode());
                }else {
                    BaseSupplierMst customer = supplierMst.getData().stream().filter(var -> var.getSupplierCode().equals(omsBillReceiveVo.getContent().getShipperCode())).findFirst().orElse(null);
                    if (null == customer) {
                        throw new PrologException("获取客户信息失败3 客户 code = " + omsBillReceiveVo.getContent().getShipperCode());
                    }
                    omsDoBillHDO.setShipperid(customer.getSupplierId());
                    omsDoBillHDO.setShippername(customer.getSupplierName());
                    omsDoBillHDO.setShipperType("1");
                }
            }else {
                BaseCustomerMst customer = restMessage.getData().stream().filter(var -> var.getCustomerCode().equals(omsBillReceiveVo.getContent().getShipperCode())).findFirst().orElse(null);
                if (null == customer) {
                    throw new PrologException("获取客户信息失败3 客户 code = " + omsBillReceiveVo.getContent().getShipperCode());
                }
                omsDoBillHDO.setShipperid(customer.getCustomerId());
                omsDoBillHDO.setShippername(customer.getCustomerName());
                omsDoBillHDO.setShipperType("2");
            }
        }else if (omsDoBillHDO.getShipperType().equals("2")){
            //2 代表客户
            RestMessage<List<BaseCustomerMst>> restMessage = chainResource.getCustomerByCode(Collections.singleton(omsBillReceiveVo.getContent().getShipperCode()));
            if (!restMessage.isSuccess()) {
                throw new PrologException("获取客户信息失败1 客户 code = " + omsBillReceiveVo.getContent().getShipperCode());
            }
            if (!restMessage.isSuccess() || CollUtil.isEmpty(restMessage.getData())) {
                throw new PrologException("获取客户信息失败2 客户 code = " + omsBillReceiveVo.getContent().getShipperCode());
            }
            BaseCustomerMst customer = restMessage.getData().stream().filter(var -> var.getCustomerCode().equals(omsBillReceiveVo.getContent().getShipperCode())).findFirst().orElse(null);
            if (null == customer) {
                throw new PrologException("获取客户信息失败3 客户 code = " + omsBillReceiveVo.getContent().getShipperCode());
            }
            omsDoBillHDO.setShipperid(customer.getCustomerId());
            omsDoBillHDO.setShippername(customer.getCustomerName());
            omsDoBillHDO.setShipperType("2");
        }else if (omsDoBillHDO.getShipperType().equals("1")){
            //查询供应商
            RestMessage<List<BaseSupplierMst>> supplierMst = chainResource.getSupplierMstByCode(Collections.singleton(omsBillReceiveVo.getContent().getShipperCode()));
            if (!supplierMst.isSuccess() || CollUtil.isEmpty(supplierMst.getData())) {
                throw new PrologException("获取客户信息失败5 客户 code = " + omsBillReceiveVo.getContent().getShipperCode());
            }
            BaseSupplierMst customer = supplierMst.getData().stream().filter(var -> var.getSupplierCode().equals(omsBillReceiveVo.getContent().getShipperCode())).findFirst().orElse(null);
            if (null == customer) {
                throw new PrologException("获取客户信息失败3 客户 code = " + omsBillReceiveVo.getContent().getShipperCode());
            }
            omsDoBillHDO.setShipperid(customer.getSupplierId());
            omsDoBillHDO.setShippername(customer.getSupplierName());
            omsDoBillHDO.setShipperType("1");
        }else {
            throw new BizException("客户类型不正确 只能是1：供应商 2：客户");
        }
        omsDoBillHDO.setRefBilltype(omsDoBillHDO.getBilltype());
        omsDoBillHDO.setRefBillid(omsDoBillHDO.getBillid());
        omsDoBillHDO.setRefBillno(omsDoBillHDO.getBillno());
        //查询仓信息
        RestMessage<Map<String,BaseWmsWarehouseMst>>  warehouseMsg = warehouseResource.getByWarehouseCode(Collections.singleton(omsBillReceiveVo.getContent().getBranchcode()));
        if (warehouseMsg == null || CollUtil.isEmpty(warehouseMsg.getData())){
            throw new BizException("获取仓信息失败1 仓 code = " + omsBillReceiveVo.getContent().getBranchcode());
        }
        List<BaseWmsWarehouseMst> warehouseList = new ArrayList<>();
        for (String s : warehouseMsg.getData().keySet()) {
            warehouseList.add(warehouseMsg.getData().get(s));
        }
        BaseWmsWarehouseMst warehouse = warehouseList.stream().filter(var-> var.getWarehouseCode().equals(omsBillReceiveVo.getContent().getBranchcode())).findFirst().orElse(null);
        if (warehouse == null){
            throw new BizException("获取仓信息失败2 仓 code = " + omsBillReceiveVo.getContent().getBranchcode());
        }
        omsDoBillHDO.setBranchid(warehouse.getWarehouseId());
        omsDoBillHDO.setBranchcode(warehouse.getWarehouseCode());
        omsDoBillHDO.setBranchname(warehouse.getWarehouseName());
        if (StrUtil.isEmpty(omsBillReceiveVo.getContent().getConsignorcode())){
            log.error("出库单下发异常：{}", "订单号【" + omsBillReceiveVo.getContent().getBillid() + "】下的【consignorcode】为空");
            throw new ParameterException("货主code不能为空！");
        }

        RestMessage<Map<String, BaseCargoOwnerMst>> cargoMsg = chainResource.getByCode(Collections.singleton(omsBillReceiveVo.getContent().getConsignorcode()));
        if (cargoMsg == null || CollUtil.isEmpty(cargoMsg.getData())){
            throw new BizException("查询货主信息失败！1货主code = " + omsBillReceiveVo.getContent().getConsignorcode());
        }
        List<BaseCargoOwnerMst> cargoOwnerMsts = new ArrayList<>();
        for (String s : cargoMsg.getData().keySet()) {
            cargoOwnerMsts.add(cargoMsg.getData().get(s));
        }
        BaseCargoOwnerMst cargoOwnerMst = cargoOwnerMsts.stream().filter(var->var.getCargoOwnerCode().equals(omsBillReceiveVo.getContent().getConsignorcode())).findFirst().orElse(null);
        if (null == cargoOwnerMst){
            throw new BizException("查询货主信息失败！ 2货主code = " + omsBillReceiveVo.getContent().getConsignorcode());
        }
        omsDoBillHDO.setConsignorcode(omsBillReceiveVo.getContent().getConsignorcode());
        omsDoBillHDO.setConsignorid(cargoOwnerMst.getCargoOwnerId());
        if (StrUtil.isEmpty(omsDoBillHDO.getArrivalMode())){
            omsDoBillHDO.setArrivalMode(String.valueOf(omsDoBillHDO.getTakeMode()));
        }
        omsDoBillHMapper.save(omsDoBillHDO);
        List<OmsBillDReceiveVo> detailList = omsBillReceiveVo.getDetailList();
        List<OmsDoBillDDO> insertDList = new ArrayList<>();
        List<String> itemIds = detailList.stream().map(var -> var.getItemid().trim()).collect(Collectors.toList());
        //查询商品信息
        RestMessage<List<BaseMtlItemMst>> itemMsg = itemClient.getListByIds(new HashSet<>(itemIds));
//        List<String> itemCodes = detailList.stream().map(var -> var.getItemcode().trim()).collect(Collectors.toList());
//        RestMessage<List<BaseMtlItemMst>> itemPage = itemClient.getByItemCodesE(omsDoBillHDO.getConsignorid(), new HashSet<>(itemCodes), omsDoBillHDO.getEnterpriseId());
        if (!itemMsg.isSuccess() || CollUtil.isEmpty(itemMsg.getData())){
            throw new BizException("获取商品信息失败，商品code = " + String.join(",", itemIds));
        }
        for (OmsBillDReceiveVo omsBillDReceiveVo : detailList) {
            BaseMtlItemMst itemInfoVO = itemMsg.getData().stream().filter(var -> var.getItemId().equals(omsBillDReceiveVo.getItemid())).findFirst().orElse(null);
            if (null == itemInfoVO){
                throw new BizException("获取商品信息失败，商品code = " + omsBillDReceiveVo.getItemid());
            }
            OmsDoBillDDO omsDoBillDDO = new OmsDoBillDDO();
            BeanUtil.copyProperties(omsBillDReceiveVo, omsDoBillDDO);
            omsDoBillDDO.setConsignorid(omsDoBillHDO.getConsignorid());
            omsDoBillDDO.setConsignorname(omsDoBillHDO.getConsignorname());
            omsDoBillDDO.setCreateby("OMS");
            omsDoBillDDO.setCreatedate(DateUtil.date());
            omsDoBillDDO.setLotNo(omsBillDReceiveVo.getLotNo());
            omsDoBillDDO.setPdateFrom(StrUtil.isEmpty(omsDoBillDDO.getPdateFrom())?null:omsDoBillDDO.getPdateFrom());
            omsDoBillDDO.setValidUntil(StrUtil.isEmpty(omsDoBillDDO.getValidUntil())?null:omsDoBillDDO.getValidUntil());
            omsDoBillDDO.setItemSpecs(itemInfoVO.getSpecification());
            omsDoBillDDO.setPackTypeNum(itemInfoVO.getCaseConversionRate());
            omsDoBillDDO.setPackUnits(itemInfoVO.getCaseUom());
            omsDoBillDDO.setItemid(itemInfoVO.getItemId());
            omsDoBillDDO.setItemname(itemInfoVO.getItemName());
            omsDoBillDDO.setBranchid(warehouse.getWarehouseId());
            omsDoBillDDO.setBranchcode(warehouse.getWarehouseCode());
            omsDoBillDDO.setBranchname(warehouse.getWarehouseName());
            insertDList.add(omsDoBillDDO);
        }
        omsDoBillDMapper.saveBatch(insertDList);
    }

    /**
     * 更新已接收但还未下发的订单信息
     * @param omsBillReceiveVo 接收的数据
     * @param omsDoBillHDO 数据库的数据
     */
    private void updateOmsBill(OmsBillReceiveVo omsBillReceiveVo, OmsDoBillHDO omsDoBillHDO){
        CopyOptions copyOptions = new CopyOptions();
        copyOptions.setIgnoreNullValue(true);
        BeanUtil.copyProperties(omsBillReceiveVo.getContent(), omsDoBillHDO, copyOptions);
        omsDoBillHDO.setBillno(omsBillReceiveVo.getContent().getBillno());
        omsDoBillHDO.setLastmodifyby("OMS");
        omsDoBillHDO.setLastmodifydate(DateUtil.date());
        if (StrUtil.isEmpty(omsDoBillHDO.getEnterpriseId())){
            log.error("出库单下发异常：{}", "订单号【" + omsBillReceiveVo.getContent().getBillid() + "】下的【enterpriseId】为空");
            throw new ParameterException("企业id不能为空！");
        }
        if (StrUtil.isEmpty(omsDoBillHDO.getEnterpriseId())){
            log.error("出库单下发异常：{}", "订单号【" + omsBillReceiveVo.getContent().getShipLineId() + "】下的【shipLineId】为空");
            throw new ParameterException("收货人id不能为空！");
        }
        //查询收货人信息
        if (null == omsDoBillHDO.getShipperType()) {
            //不确定则先查询客户，客户不存在则查询供应商
            RestMessage<List<BaseCustomerMst>> restMessage = chainResource.getCustomerByCode(Collections.singleton(omsBillReceiveVo.getContent().getShipperCode()));
            if (!restMessage.isSuccess() || CollUtil.isEmpty(restMessage.getData())) {
                //查询供应商
                RestMessage<List<BaseSupplierMst>> supplierMst = chainResource.getSupplierMstByCode(Collections.singleton(omsBillReceiveVo.getContent().getShipperCode()));
                if (!supplierMst.isSuccess() || CollUtil.isEmpty(supplierMst.getData())) {
                    throw new PrologException("获取客户信息失败4 客户 code = " + omsBillReceiveVo.getContent().getShipperCode());
                }else {
                    BaseSupplierMst customer = supplierMst.getData().stream().filter(var -> var.getSupplierCode().equals(omsBillReceiveVo.getContent().getShipperCode())).findFirst().orElse(null);
                    if (null == customer) {
                        throw new PrologException("获取客户信息失败3 客户 code = " + omsBillReceiveVo.getContent().getShipperCode());
                    }
                    omsDoBillHDO.setShipperid(customer.getSupplierId());
                    omsDoBillHDO.setShippername(customer.getSupplierName());
                    omsDoBillHDO.setShipperType("1");
                }
            }else {
                BaseCustomerMst customer = restMessage.getData().stream().filter(var -> var.getCustomerCode().equals(omsBillReceiveVo.getContent().getShipperCode())).findFirst().orElse(null);
                if (null == customer) {
                    throw new PrologException("获取客户信息失败3 客户 code = " + omsBillReceiveVo.getContent().getShipperCode());
                }
                omsDoBillHDO.setShipperid(customer.getCustomerId());
                omsDoBillHDO.setShippername(customer.getCustomerName());
                omsDoBillHDO.setShipperType("2");
            }
        }else if (omsDoBillHDO.getShipperType().equals("2")){
            //2 代表客户
            RestMessage<List<BaseCustomerMst>> restMessage = chainResource.getCustomerByCode(Collections.singleton(omsBillReceiveVo.getContent().getShipperCode()));
            if (!restMessage.isSuccess()) {
                throw new PrologException("获取客户信息失败1 客户 code = " + omsBillReceiveVo.getContent().getShipperCode());
            }
            if (!restMessage.isSuccess() || CollUtil.isEmpty(restMessage.getData())) {
                throw new PrologException("获取客户信息失败2 客户 code = " + omsBillReceiveVo.getContent().getShipperCode());
            }
            BaseCustomerMst customer = restMessage.getData().stream().filter(var -> var.getCustomerCode().equals(omsBillReceiveVo.getContent().getShipperCode())).findFirst().orElse(null);
            if (null == customer) {
                throw new PrologException("获取客户信息失败3 客户 code = " + omsBillReceiveVo.getContent().getShipperCode());
            }
            omsDoBillHDO.setShipperid(customer.getCustomerId());
            omsDoBillHDO.setShippername(customer.getCustomerName());
            omsDoBillHDO.setShipperType("2");
        }else if (omsDoBillHDO.getShipperType().equals("1")){
            //查询供应商
            RestMessage<List<BaseSupplierMst>> supplierMst = chainResource.getSupplierMstByCode(Collections.singleton(omsBillReceiveVo.getContent().getShipperCode()));
            if (!supplierMst.isSuccess() || CollUtil.isEmpty(supplierMst.getData())) {
                throw new PrologException("获取客户信息失败4 客户 code = " + omsBillReceiveVo.getContent().getShipperCode());
            }
            BaseSupplierMst customer = supplierMst.getData().stream().filter(var -> var.getSupplierCode().equals(omsBillReceiveVo.getContent().getShipperCode())).findFirst().orElse(null);
            if (null == customer) {
                throw new PrologException("获取客户信息失败5 客户 code = " + omsBillReceiveVo.getContent().getShipperCode());
            }
            omsDoBillHDO.setShipperid(customer.getSupplierId());
            omsDoBillHDO.setShippername(customer.getSupplierName());
            omsDoBillHDO.setShipperType("1");
        }else {
            throw new BizException("客户类型不正确 只能是1：供应商 2：客户");
        }
        omsDoBillHDO.setRefBilltype(omsDoBillHDO.getBilltype());
        omsDoBillHDO.setRefBillid(omsDoBillHDO.getBillid());
        omsDoBillHDO.setRefBillno(omsDoBillHDO.getBillno());
        //查询仓信息
        RestMessage<Map<String,BaseWmsWarehouseMst>>  warehouseMsg = warehouseResource.getByWarehouseCode(Collections.singleton(omsBillReceiveVo.getContent().getBranchcode()));
        if (warehouseMsg == null || CollUtil.isEmpty(warehouseMsg.getData())){
            throw new BizException("获取仓信息失败 仓 code = " + omsBillReceiveVo.getContent().getBranchcode());
        }
        List<BaseWmsWarehouseMst> warehouseList = new ArrayList<>();
        for (String s : warehouseMsg.getData().keySet()) {
            warehouseList.add(warehouseMsg.getData().get(s));
        }
        BaseWmsWarehouseMst warehouse = warehouseList.stream().filter(var-> var.getWarehouseCode().equals(omsBillReceiveVo.getContent().getBranchcode())).findFirst().orElse(null);
        if (warehouse == null){
            throw new BizException("获取仓信息失败 仓 code = " + omsBillReceiveVo.getContent().getBranchcode());
        }
        omsDoBillHDO.setBranchid(warehouse.getWarehouseId());
        omsDoBillHDO.setBranchcode(warehouse.getWarehouseCode());
        omsDoBillHDO.setBranchname(warehouse.getWarehouseName());

        RestMessage<Map<String, BaseCargoOwnerMst>> cargoMsg = chainResource.getByCode(Collections.singleton(omsBillReceiveVo.getContent().getConsignorcode()));
        if (cargoMsg == null || CollUtil.isEmpty(cargoMsg.getData())){
            throw new BizException("查询货主信息失败！");
        }
        List<BaseCargoOwnerMst> cargoOwnerMsts = new ArrayList<>();
        for (String s : cargoMsg.getData().keySet()) {
            cargoOwnerMsts.add(cargoMsg.getData().get(s));
        }
        BaseCargoOwnerMst cargoOwnerMst = cargoOwnerMsts.stream().filter(var->var.getCargoOwnerCode().equals(omsBillReceiveVo.getContent().getConsignorcode())).findFirst().orElse(null);
        if (null == cargoOwnerMst){
            throw new BizException("查询货主信息失败！ 货主code = " + omsBillReceiveVo.getContent().getConsignorcode());
        }
        omsDoBillHDO.setConsignorid(cargoOwnerMst.getCargoOwnerId());
        if (StrUtil.isEmpty(omsDoBillHDO.getArrivalMode())){
            omsDoBillHDO.setArrivalMode(String.valueOf(omsDoBillHDO.getTakeMode()));
        }
        omsDoBillHMapper.update(omsDoBillHDO);
        List<OmsBillDReceiveVo> detailList = omsBillReceiveVo.getDetailList();
        List<OmsDoBillDDO> omsDoBillDDOList = omsDoBillDMapper.findByMap(MapUtils.put("billid",omsDoBillHDO.getBillid()).getMap(), OmsDoBillDDO.class);
//        List<String> itemCodes = detailList.stream().map(var -> var.getItemcode().trim()).collect(Collectors.toList());
        List<String> itemIds = detailList.stream().map(var -> var.getItemid().trim()).collect(Collectors.toList());
        //查询商品信息
        RestMessage<List<BaseMtlItemMst>> itemMsg = itemClient.getListByIds(new HashSet<>(itemIds));
//        RestMessage<List<BaseMtlItemMst>> itemPage = itemClient.getByItemCodesE(omsDoBillHDO.getConsignorid(), new HashSet<>(itemCodes), omsDoBillHDO.getEnterpriseId());
        if (!itemMsg.isSuccess() || CollUtil.isEmpty(itemMsg.getData())){
            throw new BizException("获取商品信息失败，商品code = " + String.join(",", itemIds));
        }
        for (OmsBillDReceiveVo omsBillDReceiveVo : detailList) {
            if (CollUtil.isEmpty(omsDoBillDDOList)) {
                BaseMtlItemMst itemInfoVO = itemMsg.getData().stream().filter(var -> var.getItemId().equals(omsBillDReceiveVo.getItemid())).findFirst().orElse(null);
                if (null == itemInfoVO){
                    throw new BizException("获取商品信息失败，商品code = " + omsBillDReceiveVo.getItemid());
                }
                OmsDoBillDDO omsDoBillDDO = new OmsDoBillDDO();
                BeanUtil.copyProperties(omsBillDReceiveVo, omsDoBillDDO);
                omsDoBillDDO.setBillid(omsDoBillHDO.getBillid());
                omsDoBillDDO.setBillno(omsDoBillHDO.getBillno());
                omsDoBillDDO.setConsignorid(omsDoBillHDO.getConsignorid());
                omsDoBillDDO.setConsignorname(omsDoBillHDO.getConsignorname());
                omsDoBillDDO.setCreateby("OMS");
                omsDoBillDDO.setLotNo(omsBillDReceiveVo.getLotNo());
                omsDoBillDDO.setCreatedate(DateUtil.date());
                omsDoBillDDO.setPdateFrom(StrUtil.isEmpty(omsDoBillDDO.getPdateFrom())?null:omsDoBillDDO.getPdateFrom());
                omsDoBillDDO.setValidUntil(StrUtil.isEmpty(omsDoBillDDO.getValidUntil())?null:omsDoBillDDO.getValidUntil());
                omsDoBillDDO.setItemSpecs(itemInfoVO.getSpecification());
                omsDoBillDDO.setPackTypeNum(itemInfoVO.getCaseConversionRate());
                omsDoBillDDO.setPackUnits(itemInfoVO.getCaseUom());
                omsDoBillDDO.setItemid(itemInfoVO.getItemId());
                omsDoBillDDO.setItemname(itemInfoVO.getItemName());
                omsDoBillDDO.setBranchid(warehouse.getWarehouseId());
                omsDoBillDDO.setBranchcode(warehouse.getWarehouseCode());
                omsDoBillDDO.setBranchname(warehouse.getWarehouseName());
                omsDoBillDMapper.save(omsDoBillDDO);
            }else {
                boolean isExist = false;
                for (OmsDoBillDDO omsDoBillDDO : omsDoBillDDOList) {
                    if (omsDoBillDDO.getLineid().equals(omsBillDReceiveVo.getLineid())){
                        BaseMtlItemMst itemInfoVO = itemMsg.getData().stream().filter(var -> var.getItemId().equals(omsBillDReceiveVo.getItemid())).findFirst().orElse(null);
                        if (null == itemInfoVO){
                            throw new BizException("获取商品信息失败，商品code = " + omsBillDReceiveVo.getItemid());
                        }
                        //如果存在，则做更新操作
                        isExist = true;
                        BeanUtil.copyProperties(omsBillDReceiveVo, omsDoBillDDO, copyOptions);
                        omsDoBillDDO.setLastmodifyby("OMS");
                        omsDoBillDDO.setLastmodifydate(DateUtil.date());
                        omsDoBillDDO.setPdateFrom(StrUtil.isEmpty(omsDoBillDDO.getPdateFrom())?null:omsDoBillDDO.getPdateFrom());
                        omsDoBillDDO.setValidUntil(StrUtil.isEmpty(omsDoBillDDO.getValidUntil())?null:omsDoBillDDO.getValidUntil());
                        omsDoBillDDO.setBranchid(warehouse.getWarehouseId());
                        omsDoBillDDO.setBranchcode(warehouse.getWarehouseCode());
                        omsDoBillDDO.setBranchname(warehouse.getWarehouseName());
                        omsDoBillDDO.setItemSpecs(itemInfoVO.getSpecification());
                        omsDoBillDDO.setPackTypeNum(itemInfoVO.getCaseConversionRate());
                        omsDoBillDDO.setPackUnits(itemInfoVO.getCaseUom());
                        omsDoBillDDO.setItemid(itemInfoVO.getItemId());
                        omsDoBillDDO.setItemname(itemInfoVO.getItemName());
                        omsDoBillDMapper.update(omsDoBillDDO);
                    }
                }
                if (!isExist){
                    //不存在则新增
                    BaseMtlItemMst itemInfoVO = itemMsg.getData().stream().filter(var -> var.getItemId().equals(omsBillDReceiveVo.getItemid())).findFirst().orElse(null);
                    if (null == itemInfoVO){
                        throw new BizException("获取商品信息失败，商品code = " + omsBillDReceiveVo.getItemid());
                    }
                    OmsDoBillDDO omsDoBillDDO = new OmsDoBillDDO();
                    BeanUtil.copyProperties(omsBillDReceiveVo, omsDoBillDDO);
                    omsDoBillDDO.setBillid(omsDoBillHDO.getBillid());
                    omsDoBillDDO.setBillno(omsDoBillHDO.getBillno());
                    omsDoBillDDO.setConsignorid(omsDoBillHDO.getConsignorid());
                    omsDoBillDDO.setConsignorname(omsDoBillHDO.getConsignorname());
                    omsDoBillDDO.setCreateby("OMS");
                    omsDoBillDDO.setLotNo(omsBillDReceiveVo.getLotNo());
                    omsDoBillDDO.setCreatedate(DateUtil.date());
                    omsDoBillDDO.setPdateFrom(StrUtil.isEmpty(omsDoBillDDO.getPdateFrom())?null:omsDoBillDDO.getPdateFrom());
                    omsDoBillDDO.setValidUntil(StrUtil.isEmpty(omsDoBillDDO.getValidUntil())?null:omsDoBillDDO.getValidUntil());
                    omsDoBillDDO.setItemSpecs(itemInfoVO.getSpecification());
                    omsDoBillDDO.setPackTypeNum(itemInfoVO.getCaseConversionRate());
                    omsDoBillDDO.setPackUnits(itemInfoVO.getCaseUom());
                    omsDoBillDDO.setItemid(itemInfoVO.getItemId());
                    omsDoBillDDO.setItemname(itemInfoVO.getItemName());
                    omsDoBillDDO.setBranchid(warehouse.getWarehouseId());
                    omsDoBillDDO.setBranchcode(warehouse.getWarehouseCode());
                    omsDoBillDDO.setBranchname(warehouse.getWarehouseName());
                    omsDoBillDMapper.save(omsDoBillDDO);
                }
            }
        }
//        //判断是否需要删除
//        for (OmsDoBillDDO omsDoBillDDO : omsDoBillDDOList) {
//            boolean isExist = false;
//            for (OmsBillDReceiveVo omsBillDReceiveVo : detailList) {
//                if (omsDoBillDDO.getLineid().equals(omsBillDReceiveVo.getLineid())) {
//                    isExist = true;
//                    break;
//                }
//            }
//            if (!isExist){
//                omsDoBillDMapper.deleteById(omsDoBillDDO.getLineid(), OmsDoBillDDO.class);
//            }
//        }
    }

    public void insertBill(RefBillVo billVo, Map<String, String> billTypes, Map<String, String> arrivalModes, Map<String, String> departments) {
        RefDoHVo refDoHVo = billVo.getDoH();
        Map<String, Object> map = new HashMap<>();
        map.put("refBillno", refDoHVo.getDjbh().trim());
        map.put("attrStr2", refDoHVo.getYzid().trim());
        List<OmsDoBillHDO> omsDoBillHDOList = omsDoBillHMapper.findByMap(map, OmsDoBillHDO.class);
        if (CollUtil.isNotEmpty(omsDoBillHDOList)) {
            throw new BizException(StrUtil.format("订单【{}-{}】已存在", refDoHVo.getDjbh(), refDoHVo.getYzid()));
        }
        //REF转OmsDoBillHDTO
        List<String> itemIds = billVo.getDoDList().stream().map(var -> var.getSpid().trim()).collect(Collectors.toList());
        ItemMstQueryVO itemMstQueryVO = new ItemMstQueryVO();
        itemMstQueryVO.setItemIds(new HashSet<>(itemIds));
        itemMstQueryVO.setPageNum(1);
        itemMstQueryVO.setPageSize(itemIds.size());
        //查询商品信息
        RestMessage<List<BaseMtlItemMst>> itemMsg = itemClient.getListByIds(new HashSet<>(itemIds));
        RestMessage<Page<ItemMstVO2>> itemPage = itemClient.pagebyRelated(itemMstQueryVO);
        List<BaseMtlItemMst> itemVOs = itemMsg.getData();
        OmsDoBillHDO omsDoBillHDO = new OmsDoBillHDO();
        RestMessage<Map<String, BaseCargoOwnerMst>> cargoMstMsg = chainResource.getCargoOwnerByIds(itemVOs.stream().map(BaseMtlItemMst::getCargoOwnerId).collect(Collectors.toSet()));
        Map<String, BaseCargoOwnerMst> cargoOwnerMstMap = cargoMstMsg.getData();
        String billNo = String.valueOf(SnowFlakeUtils.getId(dataCenterId, machineId));
        omsDoBillHDO.setBillid(billNo);
        omsDoBillHDO.setBillno(billNo);
        omsDoBillHDO.setRefBillid(null == refDoHVo.getDjbh() ? null : refDoHVo.getDjbh().trim());
        omsDoBillHDO.setRefBillno(null == refDoHVo.getDjbh() ? null : refDoHVo.getDjbh().trim());
        omsDoBillHDO.setAttrStr1(null == refDoHVo.getDwid() ? null : refDoHVo.getDwid().trim());
        omsDoBillHDO.setBillDate(refDoHVo.getRq());
        omsDoBillHDO.setSalespersonName(null == refDoHVo.getRy_ywy() ? null : refDoHVo.getRy_ywy().trim());
        omsDoBillHDO.setCaozy(null == refDoHVo.getZdr() ? refDoHVo.getZdr() : refDoHVo.getZdr().trim());
        String thfs = null == refDoHVo.getThfs()? null: refDoHVo.getThfs().trim();
        omsDoBillHDO.setArrivalMode(arrivalModes.get(thfs));
        String bmmc = null == refDoHVo.getBmmc()? null: refDoHVo.getBmmc().trim();
        omsDoBillHDO.setDepartment(departments.get(bmmc));
        omsDoBillHDO.setShipperType("1");
        //目前的值有正常销售、移库开票
        omsDoBillHDO.setBilltype(billTypes.get(refDoHVo.getDdlx().trim().equals("移库开票") ? "调拨出库" : "销售出库"));
        omsDoBillHDO.setRefBilltype(null == refDoHVo.getDdlx() ? null : refDoHVo.getDdlx().trim());
        omsDoBillHDO.setCusRemark(null == refDoHVo.getKhbz() ? null : refDoHVo.getKhbz().trim());
        omsDoBillHDO.setReceiveAddress(null == refDoHVo.getShdz() ? null : refDoHVo.getShdz().trim());
        omsDoBillHDO.setEnterpriseId(null == refDoHVo.getP_enterpriseid() ? null : refDoHVo.getP_enterpriseid().trim());
        omsDoBillHDO.setBranchid(null == refDoHVo.getBranchid() ? null : refDoHVo.getBranchid().trim());
        omsDoBillHDO.setCustPerson(null == refDoHVo.getShr() ? null : refDoHVo.getShr().trim());
        omsDoBillHDO.setCustPersonTel(null == refDoHVo.getLxfs() ? null : refDoHVo.getLxfs().trim());
        omsDoBillHDO.setSfZzdy(null == refDoHVo.getSf_zzdy() ? null : refDoHVo.getSf_zzdy().trim());
        omsDoBillHDO.setPrinttemplateno(null == refDoHVo.getMb_bh() ? null : refDoHVo.getMb_bh().trim());
        omsDoBillHDO.setCarrierName(null == refDoHVo.getWlmc() ? null : refDoHVo.getWlmc().trim());
        omsDoBillHDO.setRemark(null == refDoHVo.getBeizhu() ? null : refDoHVo.getBeizhu().trim());
        omsDoBillHDO.setJjk(refDoHVo.getJjk());
        omsDoBillHDO.setOperationlicenseno(null == refDoHVo.getJyxkzh() ? null : refDoHVo.getJyxkzh().trim());
        omsDoBillHDO.setCxMemberno(null == refDoHVo.getCxhykh() ? null : refDoHVo.getCxhykh().trim());
        omsDoBillHDO.setCxMembername(null == refDoHVo.getCxhymch() ? null : refDoHVo.getCxhymch().trim());
        omsDoBillHDO.setIdcard(null == refDoHVo.getIdcard() ? null : refDoHVo.getIdcard().trim());
        omsDoBillHDO.setAttrStr2(null == refDoHVo.getYzid() ? null : refDoHVo.getYzid().trim());
        //        omsDoBillHDO.setConsignorid(null == refDoHVo.getYzid()?null:refDoHVo.getYzid().trim());
        omsDoBillHDO.setStatus("10");
        omsDoBillHDO.setCreateby("sys");
        omsDoBillHDO.setCreatedate(DateUtil.date());
        omsDoBillHDO.setAttrDte1(refDoHVo.getRq());
//        omsDoBillHDO.setArrivalMode(StrUtil.isEmpty(refDoHVo.getWlmc())?"1":refDoHVo.getWlmc().trim().equals("其他")?"1":"2");
        String warehouseId = "759131791285161984";
        RestMessage<BaseWmsWarehouseMst> warehouseMstRestMessage = warehouseResource.warehouse(warehouseId);
        if (warehouseMstRestMessage.isSuccess() && warehouseMstRestMessage.getData() != null) {
            BaseWmsWarehouseMst wmsWarehouseMst = warehouseMstRestMessage.getData();
            //扫描监管码节点：0=整件拣货、零货拣货 1=整件外复核、零货拣货 2=整件拣货、零货内复核 3=整件外复核、零货内复核
            if (wmsWarehouseMst != null) {
                omsDoBillHDO.setBranchcode(wmsWarehouseMst.getWarehouseCode());
                omsDoBillHDO.setBranchname(wmsWarehouseMst.getWarehouseName());
            }
        }
        omsDoBillHDO.setBranchid(warehouseId);
        AssertUtils.isNotEmpty(itemVOs, "商品不存在！");
        omsDoBillHDO.setEnterpriseId(itemVOs.get(0).getEnterpriseId());
        omsDoBillHDO.setConsignorid(itemVOs.get(0).getCargoOwnerId());
        omsDoBillHDO.setConsignorname(cargoOwnerMstMap.get(omsDoBillHDO.getConsignorid()).getCargoOwnerName());
        omsDoBillHMapper.save(omsDoBillHDO);
        omsDoBillHDO = omsDoBillHMapper.findByMap(Collections.singletonMap("billno", billNo), OmsDoBillHDO.class).get(0);
        List<OmsDoBillDDO> ddos = new ArrayList<>();
        for (RefDoDVo doDVo : billVo.getDoDList()) {
            BaseMtlItemMst itemInfoVO = null;
            for (BaseMtlItemMst itemVO : itemVOs) {
                if (itemVO.getItemId().equals(doDVo.getSpid().trim())) {
                    itemInfoVO = itemVO;
                }
            }
            if (itemInfoVO == null) {
                throw new BizException("商品不存在");
            }
            String cargoOwnerId = itemInfoVO.getCargoOwnerId();
            String cargoOwnerName = cargoOwnerMstMap.get(cargoOwnerId).getCargoOwnerName();
            String enterpriseId = itemInfoVO.getEnterpriseId();
            OmsDoBillDDO omsDoBillDDO = new OmsDoBillDDO();
            omsDoBillDDO.setConsignorid(cargoOwnerId);
            omsDoBillDDO.setConsignorname(cargoOwnerName);
            omsDoBillDDO.setEnterpriseId(enterpriseId);
            omsDoBillDDO.setLineid(String.valueOf(SnowFlakeUtils.getId(dataCenterId, machineId)));
            omsDoBillDDO.setSeqno(doDVo.getDj_sort());
            omsDoBillDDO.setItemid(null == doDVo.getSpid() ? null : doDVo.getSpid().trim());
            omsDoBillDDO.setItemQty(doDVo.getSl());
            omsDoBillDDO.setItemPcs(doDVo.getJs());
            omsDoBillDDO.setItemOdd(doDVo.getLss());
            omsDoBillDDO.setLotNo(null == doDVo.getPh() ? null : doDVo.getPh().trim());
            omsDoBillDDO.setPrice(doDVo.getPrice());
            omsDoBillDDO.setBillid(omsDoBillHDO.getBillid());
            omsDoBillDDO.setBillno(omsDoBillHDO.getBillno());
            omsDoBillDDO.setBranchid(null == omsDoBillHDO.getBranchid() ? null : omsDoBillHDO.getBranchid().trim());
            omsDoBillDDO.setBranchcode(null == omsDoBillHDO.getBranchcode() ? null : omsDoBillHDO.getBranchcode().trim());
            //            omsDoBillDDO.setConsignorid(null == omsDoBillHDO.getConsignorid()?null:omsDoBillHDO.getConsignorid().trim());
            omsDoBillDDO.setCreateby("sys");
            omsDoBillDDO.setCreatedate(DateUtil.date());
            omsDoBillDDO.setItemcode(itemInfoVO.getItemCode());
            omsDoBillDDO.setItemname(itemInfoVO.getItemName());
            //
            ItemMstVO2 itemMstVO2 = itemPage.getData().getList().stream().filter(var -> var.getItemId().equals(doDVo.getSpid().trim())).findFirst().orElse(null);
            omsDoBillDDO.setManufacturer(itemMstVO2.getManufacturerName());
            omsDoBillDDO.setItemSpecs(itemInfoVO.getSpecification());
            omsDoBillDDO.setPackTypeNum(itemInfoVO.getCaseConversionRate());
            omsDoBillDDO.setPackUnits(itemInfoVO.getCaseUom());
            omsDoBillDDO.setAttrStr1(omsDoBillDDO.getItemPcs().doubleValue() < 1?"2":"1");
            ddos.add(omsDoBillDDO);
        }
        omsDoBillDMapper.saveBatch(ddos);
    }

    @SneakyThrows
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean receiveDoBill(List<ReceiveDoBillVO> receiveDoBillVOS) {
        if (CollUtil.isEmpty(receiveDoBillVOS)){
            log.error("出库单下发异常：{}", "下发数据为空");
            throw new ParameterException("下发数据为空");
        }
        checkReceiveDoBillParam(receiveDoBillVOS);
        List<ReceiveDoBillVO> dels = receiveDoBillVOS.stream().filter(item -> "30".equals(item.getBillState())).collect(Collectors.toList());
        if(dels.size() > 0){
            List<String> billNos = dels.stream().map(ReceiveDoBillVO::getBillNo).collect(Collectors.toList());
            //判断订单是否已下发波次
            Criteria crt = Criteria.forClass(WaveBillDO.class);
            Restriction r1 = Restrictions.in("srcCode", billNos.toArray());
            crt.setRestriction(Restrictions.and(r1));
            long count = waveBillMapper.findCountByCriteria(crt);
            if(count > 0){
                throw new BizException("订单："+JSON.toJSONString(billNos)+"已下发波次，不能取消!");
            }
            //取消订单
            Criteria criteria = Criteria.forClass(OmsDoBillHDO.class);
            criteria.setRestriction(Restrictions.in("billno", billNos.toArray()));
            omsDoBillHMapper.updateMapByCriteria(MapUtils.put("isCancelled",1).put("status","5").put("remark",receiveDoBillVOS.get(0).getRemark()).getMap(),criteria);
        }
        long count = receiveDoBillVOS.stream().filter(item -> !"30".equals(item.getBillState())).count();
        if (count == 0){
            return true;
        }
        // 待新增的数据
        List<OmsDoBillHDO> hSaves = new ArrayList<>();
        List<OmsDoBillDDO> dSaves = new ArrayList<>();
        List<SupervisionCode> supSaves = new ArrayList<>();
        List<TmsShipBill> tmsShipBills = new ArrayList<>();

        //获取仓库信息
        Set<String> warehouseCodes = receiveDoBillVOS.stream().map(x -> x.getBranchCode()).collect(Collectors.toSet());
        List<BaseWmsWarehouseMst> warehouseMstList = null;
        if(warehouseCodes.size()>0){
            RestMessage<Map<String, BaseWmsWarehouseMst>> byWarehouseCode = warehouseResource.getByWarehouseCode(warehouseCodes);
            if(byWarehouseCode.getData()!=null&&byWarehouseCode.isSuccess()){
                Map<String, BaseWmsWarehouseMst> warehouseMstMap = byWarehouseCode.getData();
                warehouseMstList = new ArrayList<>(warehouseMstMap.values());
                if(warehouseMstList.size()==0){
                    throw new BizException("仓库信息查询失败");
                }
            }else{
                throw new BizException("仓库信息查询失败");
            }
        }

        //获取货主信息
        Set<String> consignorCodes = receiveDoBillVOS.stream().map(x -> x.getConsignorCode()).collect(Collectors.toSet());
        List<BaseCargoOwnerMst> cargoOwnerMstList = null;
        if(consignorCodes.size()>0){
            RestMessage<Map<String, BaseCargoOwnerMst>> byCode = chainResource.getByCode(consignorCodes);
            if(byCode.getData()!=null&&byCode.isSuccess()){
                Map<String, BaseCargoOwnerMst> cargoOwnerMstMap = byCode.getData();
                cargoOwnerMstList = new ArrayList<>(cargoOwnerMstMap.values());
                if(cargoOwnerMstList.size()==0){
                    throw new BizException("货主信息查询失败");
                }
            }else{
                throw new BizException("货主信息查询失败");
            }
        }

        //获取客户信息
        Set<String> customCodes = receiveDoBillVOS.stream().map(x -> x.getShipperCode()).collect(Collectors.toSet());
        List<BaseCustomerMst> customerMstList = new ArrayList<>();
        if(customCodes.size()>0){
            RestMessage<List<BaseCustomerMst>> byCode = chainResource.getCustomerByCode(customCodes);
            if(byCode.getData() == null || !byCode.isSuccess()){
                throw new BizException("客户信息查询失败");
            }else{
                customerMstList = byCode.getData();
            }
        }
        //根据客户id查询历史出库单
        Criteria crt = Criteria.forClass(OmsDoBillHDO.class);
        Restriction res1 = Restrictions.in("shipperCode", customCodes.toArray());
        Restriction res2 = Restrictions.eq("shipperType", "2");
        crt.setRestriction(Restrictions.and(res1, res2));
        List<OmsDoBillHDO> hisCustomer = omsDoBillHMapper.findByCriteria(crt);

        // 供应商信息
        List<BaseSupplierMst> supplierMstList = new ArrayList<>();
        Set<String> supplierCodeList =receiveDoBillVOS.stream().map(x -> x.getShipperCode()).collect(Collectors.toSet());
        // 查询商品信息
        RestMessage<List<BaseSupplierMst>> supplierMstMsg = chainResource.getSupplierMstByCode(supplierCodeList);
        if (supplierMstMsg == null || !supplierMstMsg.isSuccess()) {
            throw new PrologException("获取客户信息失败,code = " + String.join(",", supplierCodeList));
        }
        supplierMstList = supplierMstMsg.getData();
        if(customerMstList.size() <= 0 && supplierMstList.size() <= 0){
            throw new BizException("查询客户或供应商失败!");
        }

        //获取商品信息
        List<ReceiveDoBillDetailVO> detailList = new ArrayList<>();
        receiveDoBillVOS.stream().forEach(x->{
            List<ReceiveDoBillDetailVO> billDList = x.getDetailList();
            detailList.addAll(billDList);
        });
        Set<String> itemCodes = detailList.stream().map(x->x.getItemCode()).collect(Collectors.toSet());
        //请求商品信息
        List<BaseMtlItemMst> itemMstList = null;
        if(cargoOwnerMstList.size()>0){
            for (BaseCargoOwnerMst baseCargoOwnerMst : cargoOwnerMstList) {
                RestMessage<List<BaseMtlItemMst>> itemResult = itemClient.getByItemCodesE(baseCargoOwnerMst.getCargoOwnerId(),itemCodes,baseCargoOwnerMst.getEnterpriseId());
                if(itemResult.getData()!=null&&itemResult.isSuccess()){
                    itemMstList = itemResult.getData();
                    if(itemMstList.size()==0){
                        throw new BizException("商品信息查询失败");
                    }
                }else{
                    throw new BizException("商品信息查询失败");
                }
            }
        }

        //获取承运商信息
        List<BaseCarrierMst> carrierMstList = new ArrayList<>();
        BaseCarrierMstRequestVO baseCarrierMstRequestVO = new BaseCarrierMstRequestVO();
        Set<String> carrierCodes = receiveDoBillVOS.stream().map(ReceiveDoBillVO::getCarrierCode).collect(Collectors.toSet());
        if(carrierCodes.size() > 0){
            baseCarrierMstRequestVO.setCarrierCode(String.join(",",carrierCodes));
            RestMessage<List<BaseCarrierMst>> carrierMstRest = chainResource.findAll(baseCarrierMstRequestVO);
            if(carrierMstRest == null || !carrierMstRest.isSuccess() || carrierMstRest.getData() == null || carrierMstRest.getData().size() <= 0){
                throw new BizException("承运商信息查询失败！");
            }
            carrierMstList = carrierMstRest.getData();
        }

        //查询批次信息
        List<WmsInvBatchNumbers> batchNumbersList = new ArrayList<>();
        List<String> batchNos = detailList.stream().filter(item -> !StringUtils.isBlank(item.getLotNo()) && item.getLotNo().length() > 0).map(ReceiveDoBillDetailVO::getLotNo).collect(Collectors.toList());
        if(batchNos != null && batchNos.size() > 0){
            RestMessage<List<WmsInvBatchNumbers>> restMessage = inventoryResource.getListByManufacturerLotNums(String.join(",", batchNos));
            if(restMessage == null || !restMessage.isSuccess()){
                throw new BizException("查询批次失败!");
            }
            batchNumbersList = restMessage.getData();
            if(batchNumbersList == null || batchNumbersList.size() <= 0){
                throw new BizException("批次："+JSON.toJSONString(batchNos)+"不存在!");
            }
        }

        List<ReceiveDoBillVO> updateBillList = new ArrayList<>();
        List<ReceiveDoBillVO> saveBillList = new ArrayList<>();

        //查询asn主表数据
        List<String> billNos = receiveDoBillVOS.stream().map(ReceiveDoBillVO::getBillNo).collect(Collectors.toList());
        List<OmsDoBillHDO> extBillHDOS = omsDoBillHMapper.findByIds(OmsDoBillHDO.class,billNos.toArray(),null);
        if(extBillHDOS == null || extBillHDOS.size() <= 0){
            saveBillList = receiveDoBillVOS;
        }else if(extBillHDOS.size() > 0){

            List<String> extBillNos = extBillHDOS.stream().map(OmsDoBillHDO::getBillno).collect(Collectors.toList());
            List<String> hBillNos = extBillHDOS.stream().filter(item -> !("10".equals(item.getStatus()) || "5".equals(item.getStatus()) )).map(OmsDoBillHDO :: getBillno).collect(Collectors.toList());
            if(hBillNos != null && hBillNos.size() > 0){
                throw new BizException("单据："+JSON.toJSONString(hBillNos) + "对应的出库单不是初始状态，无法取消或修改!");
            }
            updateBillList = receiveDoBillVOS.stream().filter(item -> extBillNos.contains(item.getBillNo())).collect(Collectors.toList());
            saveBillList = receiveDoBillVOS.stream().filter(item -> !extBillNos.contains(item.getBillNo())).collect(Collectors.toList());
        }
        if(updateBillList.size() > 0 ){
            List<String> updateBillNos = updateBillList.stream().map(ReceiveDoBillVO::getBillNo).collect(Collectors.toList());
            //先删除后新增
            omsDoBillHMapper.deleteByIds(updateBillNos.toArray(),OmsDoBillHDO.class);
            Criteria criteriaBillD=Criteria.forClass(OmsDoBillDDO.class);
            Restriction r1 = Restrictions.in("billno",updateBillNos.toArray());
            criteriaBillD.setRestriction(Restrictions.and(r1));
            omsDoBillDMapper.deleteByCriteria(criteriaBillD);
        }
        saveBillList.addAll(updateBillList);
        if(saveBillList.size() > 0){
            for (ReceiveDoBillVO receiveDoBillVO : saveBillList) {
                convertOmsBill(receiveDoBillVO,warehouseMstList,itemMstList,cargoOwnerMstList,customerMstList,supplierMstList,carrierMstList,batchNumbersList,hSaves,dSaves,supSaves,tmsShipBills, hisCustomer);
            }
        }

//        for (ReceiveDoBillVO rcvDoH : receiveDoBillVOS) {
//            List<ReceiveDoBillDetailVO> doBillDetailVOS = rcvDoH.getDetailList();
//            if(StringUtils.isEmpty(rcvDoH.getBillState())){
//                throw new ParameterException("订单号【" + rcvDoH.getBillNo() + "】单据状态不能为空");
//            }
//            if (CollUtil.isEmpty(doBillDetailVOS)){
//                log.error("出库单下发异常：{}", "订单号【" + rcvDoH.getBillNo() + "】下明细数据为空");
//                throw new ParameterException("订单号【" + rcvDoH.getBillNo() + "】下明细数据不能为空");
//            }
//            //查询asn主表数据
//            Criteria criteriaBillH=Criteria.forClass(OmsDoBillHDO.class);
//            Restriction r1 = Restrictions.eq("billno",rcvDoH.getBillNo());
//            Restriction r2 = Restrictions.eq("consignorcode",rcvDoH.getConsignorCode());
//            criteriaBillH.setRestriction(Restrictions.and(r1,r2));
//            List<OmsDoBillHDO> doBillHDOS = omsDoBillHMapper.findByCriteria(criteriaBillH);
//            if(doBillHDOS.size()>1){
//                throw new RuntimeException(String.format("do_bill_h单表中单号+货主编码【%s%s】重复",rcvDoH.getBillNo(),rcvDoH.getConsignorCode()));
//            }
//
//            if("30".equals(rcvDoH.getBillState())){//取消单据
//                if(doBillHDOS.size()== 0){
//                    throw new RuntimeException(String.format("单号【%s】未查询到对应单据，无法取消",rcvDoH.getBillNo()));
//                }
//                if(doBillHDOS.size()== 1){
//                    OmsDoBillHDO omsDoBillHDO = doBillHDOS.get(0);
//                    if(!omsDoBillHDO.getStatus().equals("10")){
//                        throw new RuntimeException(String.format("单号【%s】对应的出库单不是初始状态，无法取消",rcvDoH.getBillNo()));
//                    }
//                    omsDoBillHDO.setStatus("5");//更新为5 取消的状态
//                    omsDoBillHMapper.update(omsDoBillHDO);
//                }
//            }else {
//                if(doBillHDOS.size()== 1){////更新操作
//                    OmsDoBillHDO omsDoBillHDO = doBillHDOS.get(0);
//                    if(!omsDoBillHDO.getStatus().equals("10")){
//                        throw new RuntimeException(String.format("单号【%s】对应的出库单不是初始状态，无法更新",rcvDoH.getBillNo()));
//                    }
//                    omsDoBillHDO.setBranchid(warehouseMstList.get(0).getWarehouseId());
//                    omsDoBillHDO.setBranchcode(rcvDoH.getBranchCode());
//                    omsDoBillHDO.setBranchname(warehouseMstList.get(0).getWarehouseName());
//
//                    omsDoBillHDO.setConsignorid(cargoOwnerMstList.get(0).getCargoOwnerId());
//                    omsDoBillHDO.setConsignorcode(rcvDoH.getConsignorCode());
//                    omsDoBillHDO.setConsignorname(rcvDoH.getConsignorName());
//
//                    omsDoBillHDO.setEnterpriseId(InboundBizConstant.P_ENTERPRISEID);
//                    omsDoBillHDO.setEnterpriseName(InboundBizConstant.P_ENTERPRISE_NAME);
//
//                    omsDoBillHDO.setBillno(rcvDoH.getBillNo());
//                    omsDoBillHDO.setBilltype(rcvDoH.getBillType());
//                    omsDoBillHDO.setBillDate(simpleDateFormat.parse(rcvDoH.getBillDate()));
//                    if(!StringUtils.isBlank(rcvDoH.getPlanDeliveryDate())){
//                        omsDoBillHDO.setPlanDeliveryDate(simpleDateFormat.parse(rcvDoH.getPlanDeliveryDate()));
//                    }
//
//                    omsDoBillHDO.setDeliveryName(rcvDoH.getDeliveryName());
//                    omsDoBillHDO.setShipperCode(rcvDoH.getShipperCode());
//                    omsDoBillHDO.setShippername(rcvDoH.getShipperName());
//                    omsDoBillHDO.setShipperid(customerMstList.get(0).getCustomerId());
//                    omsDoBillHDO.setShipperType("2");//客户
//
//                    omsDoBillHDO.setShopcode(rcvDoH.getShopCode());
//                    omsDoBillHDO.setShopname(rcvDoH.getShopName());
//                    omsDoBillHDO.setRemark(rcvDoH.getRemark());
//                    omsDoBillHDO.setCustPersonTel(rcvDoH.getCustPersonTel());
//                    omsDoBillHDO.setCustPerson(rcvDoH.getCustPerson());
//                    omsDoBillHDO.setReceiveProvinceName(rcvDoH.getReceiveProvinceName());
//                    omsDoBillHDO.setReceiveCityName(rcvDoH.getReceiveCityName());
//                    omsDoBillHDO.setReceiveDistrictName(rcvDoH.getReceiveDistrictName());
//                    omsDoBillHDO.setReceiveTownName(rcvDoH.getReceiveTownName());
//                    omsDoBillHDO.setReceiveAddress(rcvDoH.getReceiveAddress());
//                    omsDoBillHDO.setReceiveCommunityName(rcvDoH.getReceiveCommunityName());
//                    omsDoBillHDO.setSalespersonName(rcvDoH.getSalesPersonName());
//                    omsDoBillHDO.setSalespersonTel(rcvDoH.getSalesPersonTel());
//                    omsDoBillHDO.setPreparedBy(rcvDoH.getPreparedBy());
//                    if(!StringUtils.isBlank(rcvDoH.getPayTime())){
//                        omsDoBillHDO.setPaytime(simpleDateFormat.parse(rcvDoH.getPayTime()));
//                    }
//                    if(!StringUtils.isBlank(rcvDoH.getPayAmount())){
//                        omsDoBillHDO.setPayamount(new BigDecimal(rcvDoH.getPayAmount()));
//                    }
//                    if(!StringUtils.isBlank(rcvDoH.getFreight())){
//                        omsDoBillHDO.setFreight(new BigDecimal(rcvDoH.getFreight()));
//                    }
//                    omsDoBillHDO.setPaysn(rcvDoH.getPaySn());
//                    omsDoBillHDO.setCarrierName(rcvDoH.getCarrierName());
//                    omsDoBillHDO.setCarrierId(rcvDoH.getCarrierCode());
//
//                    omsDoBillHDO.setShipBillNo(rcvDoH.getShipBillNo());
//                    omsDoBillHDO.setLineCode(rcvDoH.getLineCode());
//                    omsDoBillHDO.setLineName(rcvDoH.getLineName());
//                    omsDoBillHDO.setPriorityLevel(rcvDoH.getPriorityLevel());
//                    omsDoBillHDO.setArrivalMode(rcvDoH.getArrivalMode());
//                    List<String> transportModes = CollUtil.toList("01","02","03","04");
//                    if(!StringUtils.isBlank(rcvDoH.getTransportMode()) && transportModes.contains(rcvDoH.getTransportMode())){
//                        omsDoBillHDO.setTransportMode(Integer.parseInt(rcvDoH.getTransportMode()));
//                    }
//                    if(!StringUtils.isBlank(rcvDoH.getPartlyRed())){
//                        omsDoBillHDO.setPartlyRed(new BigDecimal(rcvDoH.getPartlyRed()));
//                    }
//
//                    omsDoBillHDO.setSrcPlate(rcvDoH.getSrcPlate());
//                    omsDoBillHDO.setSrcPlateBillno(rcvDoH.getSrcPlateBillno());
//
//                    if(!StringUtils.isBlank(rcvDoH.getTotQty())){
//                        omsDoBillHDO.setTotQty(new BigDecimal(rcvDoH.getTotQty()));
//                    }
//                    if(!StringUtils.isBlank(rcvDoH.getTotPcs())){
//                        omsDoBillHDO.setTotPcs(new BigDecimal(rcvDoH.getTotPcs()));
//                    }
//                    if(!StringUtils.isBlank(rcvDoH.getTotamt())){
//                        omsDoBillHDO.setTotamt(new BigDecimal(rcvDoH.getTotamt()));
//                    }
//                    if(!StringUtils.isBlank(rcvDoH.getTotVolume())){
//                        omsDoBillHDO.setTotVolume(new BigDecimal(rcvDoH.getTotVolume()));
//                    }
//                    if(!StringUtils.isBlank(rcvDoH.getTotWeight())){
//                        omsDoBillHDO.setTotWeight(new BigDecimal(rcvDoH.getTotWeight()));
//                    }
//
//                    omsDoBillHMapper.update(omsDoBillHDO);
//
//                }else {//新增操作
//
//                }
//            }
//        }

        // 批量保存主表和明细表数据
        if (ObjectUtils.isNotNull(hSaves)) {
            omsDoBillHMapper.saveBatch(hSaves);
        }
        if (ObjectUtils.isNotNull(dSaves)) {
            omsDoBillDMapper.saveBatch(dSaves);
        }
        if (ObjectUtils.isNotNull(supSaves)) {
            //调用远程服务保存监管码信息
            inBoundClient.batchAddSupCode(supSaves);
        }

        if (CollUtil.isNotEmpty(tmsShipBills)) {
            //同步订单到tms
            tmsShipBills.forEach(producer::tmsShipBill);
        }
        //处理直通出库单
        List<OmsDoBillHDO> ztBillhs = hSaves.stream().filter(item -> "6".equals(item.getBilltype())).collect(Collectors.toList());
        if(ztBillhs != null && ztBillhs.size() > 0){
            List<String> ztBillIds = ztBillhs.stream().map(OmsDoBillHDO::getBillid).collect(Collectors.toList());
            List<OmsDoBillDDO> ztBillds = dSaves.stream().filter(item -> ztBillIds.contains(item.getBillid())).collect(Collectors.toList());
            handleZtBills(ztBillhs,ztBillds);
        }
        return  true;
    }

    /**
     * 入参校验
     * @param receiveDoBillVOS
     */
    private void checkReceiveDoBillParam(List<ReceiveDoBillVO> receiveDoBillVOS) {
        ReceiveDoBillVO billVO = receiveDoBillVOS.get(0);
        String billState = billVO.getBillState();
        if("30".equals(billState)){
            if(StringUtils.isBlank(billVO.getBillNo())){
                throw new BizException("billNo字段不能为空！");
            }

        }else {
            for (ReceiveDoBillVO receiveDoBillVO : receiveDoBillVOS) {
                if(StringUtils.isBlank(receiveDoBillVO.getBillNo())){
                    throw new BizException("billNo字段不能为空！");
                }
                if(StringUtils.isBlank(receiveDoBillVO.getBillType())){
                    throw new BizException("billType字段不能为空！");
                }
                if(StringUtils.isBlank(receiveDoBillVO.getBillDate())){
                    throw new BizException("billDate字段不能为空！");
                }
//            if(StringUtils.isBlank(receiveDoBillVO.getBillState())){
//                throw new BizException("billState字段不能为空！");
//            }
//            List<String> billStates = CollUtil.toList("10","20","30");
//            if(!billStates.contains(receiveDoBillVO.getBillState())){
//                throw new BizException("billState不正确！");
//            }
                if(StringUtils.isBlank(receiveDoBillVO.getConsignorCode())){
                    throw new BizException("consignorCode字段不能为空！");
                }
                if(StringUtils.isBlank(receiveDoBillVO.getShipperCode())){
                    throw new BizException("shipperCode字段不能为空！");
                }
                if(StringUtils.isBlank(receiveDoBillVO.getArrivalMode())){
                    throw new BizException("arrivalMode字段不能为空！");
                }
                if(StringUtils.isBlank(receiveDoBillVO.getCarrierCode())){
                    throw new BizException("carrierCode字段不能为空！");
                }
                List<String> arrivalModes = CollUtil.toList("1","2","3","4","5");
                if(!arrivalModes.contains(receiveDoBillVO.getArrivalMode())){
                    throw new BizException("arrivalMode 不正确！");
                }
//            if(StringUtils.isBlank(receiveDoBillVO.getIsSupportZmd())){
//                throw new BizException("isSupportZmd字段不能为空！");
//            }

                if(StringUtils.isBlank(receiveDoBillVO.getIsPrintFp())){
                    throw new BizException("isPrintFp字段不能为空！");
                }

                if(StringUtils.isBlank(receiveDoBillVO.getIsPrintSy())){
                    throw new BizException("isPrintSy字段不能为空！");
                }

                if(StringUtils.isBlank(receiveDoBillVO.getIsPrintZj())){
                    throw new BizException("isPrintZj字段不能为空！");
                }

                if(StringUtils.isBlank(receiveDoBillVO.getPrintDetailMode())){
                    throw new BizException("printDetailMode段不能为空！");
                }

                if(StringUtils.isBlank(receiveDoBillVO.getReceiveAddress())){
                    throw new BizException("receiveAddress段不能为空！");
                }

                if(StringUtils.isBlank(receiveDoBillVO.getReceiveProvinceName())){
                    throw new BizException("receiveProvinceName段不能为空！");
                }

                if(StringUtils.isBlank(receiveDoBillVO.getReceiveCityName())){
                    throw new BizException("receiveCityName段不能为空！");
                }

                if(StringUtils.isBlank(receiveDoBillVO.getReceiveDistrictName())){
                    throw new BizException("receiveDistrictName段不能为空！");
                }

                List<ReceiveDoBillDetailVO> detailList = receiveDoBillVO.getDetailList();
                if(detailList != null && detailList.size() > 0){
                    for (ReceiveDoBillDetailVO detailVO : detailList) {
                        if(StringUtils.isBlank(detailVO.getBillNo())){
                            throw new BizException("billNo字段不能为空！");
                        }
                        if(StringUtils.isBlank(detailVO.getSeqNo())){
                            throw new BizException("seqNo字段不能为空！");
                        }
                        if(StringUtils.isBlank(detailVO.getItemCode())){
                            throw new BizException("itemCode字段不能为空！");
                        }
                        if(StringUtils.isBlank(detailVO.getPackTypeNum())){
                            throw new BizException("packTypeNum字段不能为空！");
                        }
                        if("0".equals(detailVO.getPackTypeNum())){
                            throw new BizException("packTypeNum字段不能为0！");
                        }
                        if(StringUtils.isBlank(detailVO.getItemQty())){
                            throw new BizException("itemQty字段不能为空！");
                        }
                        if(StringUtils.isBlank(detailVO.getIsGift())){
                            throw new BizException("isGift字段不能为空！");
                        }
                    }
                }

                List<ReceiveDoBillSupervisionVO> supervisionList = receiveDoBillVO.getSupervisionList();
                if(supervisionList != null && supervisionList.size() > 0){
                    for (ReceiveDoBillSupervisionVO supervisionVO : supervisionList) {
                        if(StringUtils.isBlank(supervisionVO.getSupervisionCode())){
                            throw new BizException("supervisionCode字段不能为空！");
                        }
                        if(StringUtils.isBlank(supervisionVO.getItemCode())){
                            throw new BizException("监管码itemCode字段不能为空！");
                        }
                        if(StringUtils.isBlank(supervisionVO.getLotNo())){
                            throw new BizException("监管码lotNo字段不能为空！");
                        }
                        if(StringUtils.isBlank(supervisionVO.getSupervisionType())){
                            throw new BizException("supervisionType字段不能为空！");
                        }
                        List<String> supervisionTypes = CollUtil.toList("大","中","小");
                        if(!supervisionTypes.contains(supervisionVO.getSupervisionType())){
                            throw new BizException("supervisionType不正确！");
                        }
                    }
                }

                if(StringUtils.isEmpty(receiveDoBillVO.getPriorityLevel())){
                    receiveDoBillVO.setPriorityLevel("99");
                }
            }
        }

    }

    /**
     * 转换omsbill对象
     * @param rcvDoH
     * @param warehouseMstList
     * @param itemMstList
     * @param cargoOwnerMstList
     * @param customerMstList
     * @param hSaves
     * @param dSaves
     * @param supSaves
     * @param tmsShipBills
     */
    private void convertOmsBill(ReceiveDoBillVO rcvDoH,
                                List<BaseWmsWarehouseMst> warehouseMstList,
                                List<BaseMtlItemMst> itemMstList,
                                List<BaseCargoOwnerMst> cargoOwnerMstList,
                                List<BaseCustomerMst> customerMstList,
                                List<BaseSupplierMst> supplierMstList,
                                List<BaseCarrierMst> carrierMstList,
                                List<WmsInvBatchNumbers> batchNumbersList,
                                List<OmsDoBillHDO> hSaves ,
                                List<OmsDoBillDDO> dSaves ,
                                List<SupervisionCode> supSaves ,
                                List<TmsShipBill> tmsShipBills,
                                List<OmsDoBillHDO> hisCustomer){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // 构建主表数据
        OmsDoBillHDO omsDoBillHDO = new OmsDoBillHDO();
        omsDoBillHDO.setBillid(rcvDoH.getBillNo());
        omsDoBillHDO.setRefBilltype(rcvDoH.getBillType());
        omsDoBillHDO.setRefBillid(rcvDoH.getBillNo());
        omsDoBillHDO.setRefBillno(rcvDoH.getBillNo());

        omsDoBillHDO.setStatus("10");//默认是10
        omsDoBillHDO.setCreateby("ERP");
        omsDoBillHDO.setCreatedate(DateUtil.date());

        BaseWmsWarehouseMst baseWmsWarehouseMst = warehouseMstList.stream().filter(item -> item.getWarehouseCode().equals(rcvDoH.getBranchCode())).findFirst().orElse(null);
        if(baseWmsWarehouseMst == null){
            throw new BizException(rcvDoH.getBranchCode() + "未匹配到仓信息！");
        }
        omsDoBillHDO.setBranchid(baseWmsWarehouseMst.getWarehouseId());
        omsDoBillHDO.setBranchcode(rcvDoH.getBranchCode());
        omsDoBillHDO.setBranchname(baseWmsWarehouseMst.getWarehouseName());

        BaseCargoOwnerMst baseCargoOwnerMst = cargoOwnerMstList.stream().filter(item -> item.getCargoOwnerCode().equals(rcvDoH.getConsignorCode())).findFirst().orElse(null);
        if(baseCargoOwnerMst == null){
            throw new BizException(rcvDoH.getConsignorCode() + "未匹配到货主信息！");
        }
        omsDoBillHDO.setConsignorid(baseCargoOwnerMst.getCargoOwnerId());
        omsDoBillHDO.setConsignorcode(rcvDoH.getConsignorCode());
        omsDoBillHDO.setConsignorname(baseCargoOwnerMst.getCargoOwnerName());

        omsDoBillHDO.setEnterpriseId(baseWmsWarehouseMst.getEnterpriseId());
        omsDoBillHDO.setEnterpriseName(InboundBizConstant.P_ENTERPRISE_NAME);

        omsDoBillHDO.setBillno(rcvDoH.getBillNo());
        omsDoBillHDO.setBilltype(rcvDoH.getBillType());
        try {
            omsDoBillHDO.setBillDate(simpleDateFormat.parse(rcvDoH.getBillDate()));
        } catch (ParseException e) {
            throw new BizException("billDate格式不正确!");
        }
        if(!StringUtils.isBlank(rcvDoH.getPlanDeliveryDate())){
            try {
                omsDoBillHDO.setPlanDeliveryDate(simpleDateFormat.parse(rcvDoH.getPlanDeliveryDate()));
            } catch (ParseException e) {
                throw new BizException("planDeliveryDate格式不正确!");
            }
        }
        omsDoBillHDO.setDeliveryName(rcvDoH.getDeliveryName());
        omsDoBillHDO.setShipperCode(rcvDoH.getShipperCode());
        omsDoBillHDO.setShippername(rcvDoH.getShipperName());
        BaseCustomerMst baseCustomerMst = customerMstList.stream().filter(item -> item.getCustomerCode().equals(rcvDoH.getShipperCode())).findFirst().orElse(null);
        if(baseCustomerMst == null ){
            BaseSupplierMst baseSupplierMst = supplierMstList.stream().filter(item -> item.getSupplierCode().equals(rcvDoH.getShipperCode())).findFirst().orElse(null);
            if(baseSupplierMst == null){
                throw new BizException(rcvDoH.getShipperCode() +"未匹配到客户/供应商信息！");
            }else {
                omsDoBillHDO.setShipperid(baseSupplierMst.getSupplierId());
                omsDoBillHDO.setShippername(baseSupplierMst.getSupplierName());
                omsDoBillHDO.setShipperType("1");//客户
            }

        }else {
            omsDoBillHDO.setShipperid(baseCustomerMst.getCustomerId());
            omsDoBillHDO.setShippername(baseCustomerMst.getCustomerName());
            omsDoBillHDO.setShipperType("2");//客户
        }

        OmsDoBillHDO hdo = hisCustomer.stream().filter(item -> item.getShipperCode().equals(rcvDoH.getShipperCode())).findFirst().orElse(null);
        if(hdo == null) {
            omsDoBillHDO.setAttrNum3(new BigDecimal(1));
        } else {
            omsDoBillHDO.setAttrNum3(new BigDecimal(0));
        }

        omsDoBillHDO.setShopcode(rcvDoH.getShopCode());
        omsDoBillHDO.setShopname(rcvDoH.getShopName());

        omsDoBillHDO.setRemark(rcvDoH.getRemark());
        omsDoBillHDO.setCustPersonTel(rcvDoH.getCustPersonTel());
        omsDoBillHDO.setCustPerson(rcvDoH.getCustPerson());
        omsDoBillHDO.setReceiveProvinceName(rcvDoH.getReceiveProvinceName());
        omsDoBillHDO.setReceiveCityName(rcvDoH.getReceiveCityName());
        omsDoBillHDO.setReceiveDistrictName(rcvDoH.getReceiveDistrictName());
        omsDoBillHDO.setReceiveTownName(rcvDoH.getReceiveTownName());
        omsDoBillHDO.setReceiveAddress(rcvDoH.getReceiveAddress());
        omsDoBillHDO.setReceiveCommunityName(rcvDoH.getReceiveCommunityName());
        omsDoBillHDO.setSalespersonName(rcvDoH.getSalesPersonName());
        omsDoBillHDO.setSalespersonTel(rcvDoH.getSalesPersonTel());
        omsDoBillHDO.setPreparedBy(rcvDoH.getPreparedBy());
        if(!StringUtils.isBlank(rcvDoH.getPayTime())){
            try {
                omsDoBillHDO.setPaytime(simpleDateFormat.parse(rcvDoH.getPayTime()));
            } catch (ParseException e) {
                throw new BizException("payTime格式不正确!");
            }
        }
        if(!StringUtils.isEmpty(rcvDoH.getPayAmount())){
            omsDoBillHDO.setPayamount(new BigDecimal(rcvDoH.getPayAmount()));
        }
        omsDoBillHDO.setPaysn(rcvDoH.getPaySn());

        if(!StringUtils.isBlank(rcvDoH.getCarrierCode())){
            BaseCarrierMst baseCarrierMst = carrierMstList.stream().filter(item -> item.getCarrierCode().equals(rcvDoH.getCarrierCode())).findFirst().orElse(null);
            if(baseCarrierMst == null){
                throw new BizException(rcvDoH.getCarrierCode() + "未匹配到承运商信息!");
            }
            omsDoBillHDO.setCarrierName(baseCarrierMst.getCarrierName());
            omsDoBillHDO.setCarrierId(baseCarrierMst.getCarrierId());
            omsDoBillHDO.setCarrierCode(baseCarrierMst.getCarrierCode());
            omsDoBillHDO.setCarrierType(baseCarrierMst.getCarrierType());
            if("JD".equals(omsDoBillHDO.getCarrierCode())){
                omsDoBillHDO.setCarrierType("3");
            }
            if("1".equals(baseCarrierMst.getCarrierType()) && StringUtils.isBlank(rcvDoH.getCustPersonTel())){
                throw new BizException("单号："+rcvDoH.getBillNo()+"，承运商："+baseCarrierMst.getCarrierCode()+"为物流商，custPersonTel不能为空!");
            }
        }
        if(!StringUtils.isEmpty(rcvDoH.getFreight())){
            omsDoBillHDO.setFreight(new BigDecimal(rcvDoH.getFreight()));
        }
        omsDoBillHDO.setShipBillNo(rcvDoH.getShipBillNo());
        omsDoBillHDO.setLineCode(rcvDoH.getLineCode());
        omsDoBillHDO.setLineName(rcvDoH.getLineName());
        omsDoBillHDO.setPriorityLevel(rcvDoH.getPriorityLevel());
        omsDoBillHDO.setArrivalMode(rcvDoH.getArrivalMode());
        List<String> transportModes = CollUtil.toList("01","02","03","04");
        if(!StringUtils.isBlank(rcvDoH.getTransportMode()) && transportModes.contains(rcvDoH.getTransportMode())){
            omsDoBillHDO.setTransportMode(Integer.parseInt(rcvDoH.getTransportMode()));
        }

        if(!StringUtils.isBlank(rcvDoH.getPartlyRed())){
            omsDoBillHDO.setPartlyRed(new BigDecimal(rcvDoH.getPartlyRed()));
        }
        omsDoBillHDO.setSrcPlate(rcvDoH.getSrcPlate());
        omsDoBillHDO.setSrcPlateBillno(rcvDoH.getSrcPlateBillno());
        if(!StringUtils.isBlank(rcvDoH.getTotQty())){
            omsDoBillHDO.setTotQty(new BigDecimal(rcvDoH.getTotQty()));
        }
        if(!StringUtils.isBlank(rcvDoH.getTotPcs())){
            omsDoBillHDO.setTotPcs(new BigDecimal(rcvDoH.getTotPcs()));
        }
        if(!StringUtils.isBlank(rcvDoH.getTotamt())){
            omsDoBillHDO.setTotamt(new BigDecimal(rcvDoH.getTotamt()));
        }
        if(!StringUtils.isBlank(rcvDoH.getTotVolume())){
            omsDoBillHDO.setTotVolume(new BigDecimal(rcvDoH.getTotVolume()));
        }
        if(!StringUtils.isBlank(rcvDoH.getTotWeight())){
            omsDoBillHDO.setTotWeight(new BigDecimal(rcvDoH.getTotWeight()));
        }
        omsDoBillHDO.setItemHealthIndustry(rcvDoH.getItemHealthIndustry());

        omsDoBillHDO.setAttrStr3(rcvDoH.getIsPrintSy());
        omsDoBillHDO.setAttrStr4(rcvDoH.getIsPrintZj());
        omsDoBillHDO.setAttrStr5(rcvDoH.getIsPrintFp());
        omsDoBillHDO.setAttrStr7(rcvDoH.getPrintDetailMode());

        hSaves.add(omsDoBillHDO);

        BigDecimal totalVolume = BigDecimal.ZERO,totalWeight = BigDecimal.ZERO;
        int totalPcs = 0;

        List<TmsShipBillItem> tmsShipBillItems = new ArrayList<>();
        // 构造明细表数据
        for (ReceiveDoBillDetailVO rcvDoD : rcvDoH.getDetailList()) {
            OmsDoBillDDO omsDoBillDDO =new OmsDoBillDDO();

            String billDetailId = String.valueOf(SnowFlakeUtils.getId());
            omsDoBillDDO.setLineid(billDetailId);
            // 复制主表属性
            omsDoBillDDO.setBillid(omsDoBillHDO.getBillid());
            omsDoBillDDO.setBillno(omsDoBillHDO.getBillno());
            omsDoBillDDO.setBranchid(omsDoBillHDO.getBranchid());
            omsDoBillDDO.setBranchcode(omsDoBillHDO.getBranchcode());
            omsDoBillDDO.setBranchname(omsDoBillHDO.getBranchname());
            omsDoBillDDO.setBranchareaid(omsDoBillHDO.getBranchareaid());
            omsDoBillDDO.setBrancharea(omsDoBillHDO.getBrancharea());
            omsDoBillDDO.setConsignorid(omsDoBillHDO.getConsignorid());
            omsDoBillDDO.setConsignorname(omsDoBillHDO.getConsignorname());
            omsDoBillDDO.setStatus("20");// 默认给 "20"
            omsDoBillDDO.setCreateby("ERP");// 当前用户信息
            omsDoBillDDO.setCreatedate(DateUtil.date());
            omsDoBillDDO.setEnterpriseId(omsDoBillHDO.getEnterpriseId());
            omsDoBillDDO.setEnterpriseName(omsDoBillHDO.getEnterpriseName());

            //商品信息
            BaseMtlItemMst baseMtlItemMst = itemMstList.stream().filter(x -> x.getItemCode().equals(rcvDoD.getItemCode()) && x.getCargoOwnerId().equals(omsDoBillHDO.getConsignorid())).findFirst().orElse(null);
            if(baseMtlItemMst!=null){
                omsDoBillDDO.setItemid(baseMtlItemMst.getItemId());
                omsDoBillDDO.setItemname(baseMtlItemMst.getItemName());
                omsDoBillDDO.setTypeCode(baseMtlItemMst.getItemCategoryCode());
                omsDoBillDDO.setTypeName(baseMtlItemMst.getItemCategoryName());
                omsDoBillDDO.setManufacturer(baseMtlItemMst.getManufacturerId());
                omsDoBillDDO.setPackUnits(baseMtlItemMst.getCaseUom());
                //包装数量
                BigDecimal conversionRate = baseMtlItemMst.getBaseMtlItemUomConversionsList().get(0).getConversionRate();
                //物料数量
                BigDecimal qty = new BigDecimal(rcvDoD.getItemQty());

                BigDecimal volume = baseMtlItemMst.getBaseMtlItemUomConversionsList().get(0).getVolume();
                BigDecimal pcs = qty.divide(conversionRate,2,BigDecimal.ROUND_HALF_UP);
                totalVolume = totalVolume.add(volume.multiply(pcs));
                BigDecimal weight = baseMtlItemMst.getBaseMtlItemUomConversionsList().get(0).getWeight();
                totalWeight =  totalWeight.add(weight.multiply(pcs));

                omsDoBillDDO.setItemVolume(volume);
                omsDoBillDDO.setItemWeight(weight);

                omsDoBillDDO.setItemOdd(qty.remainder(conversionRate));
                omsDoBillDDO.setItemPcs(new BigDecimal(qty.divide(conversionRate,2,BigDecimal.ROUND_HALF_UP).intValue()));

                omsDoBillDDO.setAttrStr5(baseMtlItemMst.getBaseMtlItemUomConversionsList().get(0).getUom());

                int value = qty.divide(conversionRate, 0, BigDecimal.ROUND_UP).intValue();
                totalPcs += value;

            }else {
                throw new BizException(rcvDoD.getItemCode() +"未匹配到商品信息!");
            }
            omsDoBillDDO.setSeqno(rcvDoD.getSeqNo());
            omsDoBillDDO.setItemcode(rcvDoD.getItemCode());
//            omsDoBillDDO.setItemname(rcvDoD.getItemName());
            omsDoBillDDO.setPackUnits(rcvDoD.getPackUnits());
            omsDoBillDDO.setItemSpecs(rcvDoD.getItemSpecs());
            omsDoBillDDO.setPackTypeNum(new BigDecimal(rcvDoD.getPackTypeNum()));
            if(!StringUtils.isBlank(rcvDoD.getItemWeight())){
                omsDoBillDDO.setItemWeight(new BigDecimal(rcvDoD.getItemWeight()));
            }
            if(!StringUtils.isBlank(rcvDoD.getItemVolume())){
                omsDoBillDDO.setItemVolume(new BigDecimal(rcvDoD.getItemVolume()));
            }
            if(!StringUtils.isBlank(rcvDoD.getRedQty())){
                omsDoBillDDO.setRedQty(new BigDecimal(rcvDoD.getRedQty()));
            }
            if(!StringUtils.isBlank(rcvDoD.getDeliveryQty())){
                omsDoBillDDO.setDeliveryQty(new BigDecimal(rcvDoD.getDeliveryQty()));
            }
            if(!StringUtils.isBlank(rcvDoD.getPrice())){
                omsDoBillDDO.setPrice(new BigDecimal(rcvDoD.getPrice()));
            }
            if(!StringUtils.isBlank(rcvDoD.getAmt())){
                omsDoBillDDO.setAmt(new BigDecimal(rcvDoD.getAmt()));
            }
            if(!StringUtils.isBlank(rcvDoD.getDiscountPrice())){
                omsDoBillDDO.setDiscountPrice(new BigDecimal(rcvDoD.getDiscountPrice()));
            }
            if(!StringUtils.isBlank(rcvDoD.getDiscountAmt())){
                omsDoBillDDO.setDiscountAmt(new BigDecimal(rcvDoD.getDiscountAmt()));
            }

            omsDoBillDDO.setItemQty(new BigDecimal(rcvDoD.getItemQty()));

            if(!StringUtils.isBlank(rcvDoD.getLotNo()) && rcvDoD.getLotNo().length() > 0){
                WmsInvBatchNumbers wmsInvBatchNumbers = batchNumbersList.stream().filter(item -> item.getManufacturerLotNum().equals(rcvDoD.getLotNo())).findFirst().orElse(null);
                if(wmsInvBatchNumbers == null){
                    throw new BizException("批次号："+rcvDoD.getLotNo()+"不存在!");
                }
                omsDoBillDDO.setBatchNo(wmsInvBatchNumbers.getBatchNum());
                omsDoBillDDO.setLotNo(rcvDoD.getLotNo());
            }else {
                omsDoBillDDO.setBatchNo(rcvDoD.getBatchNo());
                omsDoBillDDO.setLotNo(rcvDoD.getLotNo());
            }

            omsDoBillDDO.setSterilizationLotno(rcvDoD.getSterilizationBatchNo());
            if(!StringUtils.isBlank(rcvDoD.getSterilizationTime())){
                try {
                    omsDoBillDDO.setSterilizationDate(simpleDateFormat.parse(rcvDoD.getSterilizationTime()));
                } catch (ParseException e) {
                    throw new BizException("sterilizationTime格式不正确!");
                }
            }
            if(!StringUtils.isBlank(rcvDoD.getPdateFrom())){
                String format = "yyyy-MM-dd";
                if(!isDateValid(rcvDoD.getPdateFrom(),format)){
                    throw new BizException("pdateFrom时间格式不正确！");
                }
                omsDoBillDDO.setPdateFrom(rcvDoD.getPdateFrom());
            }
            if(!StringUtils.isBlank(rcvDoD.getValidUntil())){
                String format = "yyyy-MM-dd";
                if(!isDateValid(rcvDoD.getValidUntil(),format)){
                    throw new BizException("validUntil时间格式不正确！");
                }
                omsDoBillDDO.setValidUntil(rcvDoD.getValidUntil());
            }

            omsDoBillDDO.setAttrStr2(rcvDoD.getIsGift());
            if(!StringUtils.isBlank(rcvDoD.getIsGift()) && "1".equals(rcvDoD.getIsGift())){
                omsDoBillDDO.setFreeQty(omsDoBillDDO.getItemQty());
            }

            dSaves.add(omsDoBillDDO);
            TmsShipBillItem shipBillItem = convert.parse2TmsShipBillItem(omsDoBillDDO,omsDoBillHDO);
            tmsShipBillItems.add(shipBillItem);
        }
        omsDoBillHDO.setTotVolume(totalVolume);
        omsDoBillHDO.setTotWeight(totalWeight);
        TmsShipBill bill = convert.parse2TmsShipBill(omsDoBillHDO);
        bill.setDetails(tmsShipBillItems);
        if(totalPcs == 0){
            totalPcs = 1;
        }
        bill.setTotalPcs(totalPcs);
        omsDoBillHDO.setTotPcs(new BigDecimal(totalPcs));
        if("YUNDA".equals(omsDoBillHDO.getCarrierCode())){
            if(totalPcs >1){
                omsDoBillHDO.setCarrierType("3");
            }
        }
        tmsShipBills.add(bill);

        // 构造监管码数据
        if(!CollUtil.isEmpty(rcvDoH.getSupervisionList())){
            for (ReceiveDoBillSupervisionVO supervisionVO : rcvDoH.getSupervisionList()) {
                SupervisionCode supervision =new SupervisionCode();
                String supervisionId = String.valueOf(SnowFlakeUtils.getId());
                supervision.setId(supervisionId);
                supervision.setEnterpriseId(omsDoBillHDO.getEnterpriseId());
                supervision.setWarehouseId(rcvDoH.getBranchCode());
                supervision.setWarehouseCode(rcvDoH.getBranchCode());
                supervision.setCargoOwnerId(rcvDoH.getConsignorCode());
                supervision.setCargoOwnerCode(rcvDoH.getConsignorCode());
                supervision.setSupervisionCode(supervisionVO.getSupervisionCode());
                supervision.setItemCode(supervisionVO.getItemCode());
                supervision.setManufacturerLotNum(supervisionVO.getLotNo());
                if("大".equals(supervisionVO.getSupervisionType())){
                    supervision.setSupervisionType(0);
                }
                if("中".equals(supervisionVO.getSupervisionType())){
                    supervision.setSupervisionType(1);
                }
                if("小".equals(supervisionVO.getSupervisionType())){
                    supervision.setSupervisionType(2);
                }
                supervision.setUploadFlag("0");
                supervision.setDownFlag(0);
                supervision.setSaveType(0);
                supSaves.add(supervision);
            }
        }
    }

    @Override
    @Transactional
    public void autoCheckZtBill() {
        List<PickTaskH> pickTaskHList = pickTaskHMapper.getZtBills();
        if(pickTaskHList == null || pickTaskHList.size() <= 0){
            return;
        }
        UserDTO userDTO = userTemplate.getUserDTO();
        List<String> pickTaskIds = pickTaskHList.stream().map(PickTaskH::getPickTaskId).collect(Collectors.toList());
        //查询pick_task_d
        Criteria cd = Criteria.forClass(PickTaskD.class);
        Restriction rd1 = Restrictions.in("pickTaskId", pickTaskIds.toArray());
        cd.setRestriction(rd1);
        List<PickTaskD> pickTaskDS = pickTaskDMapper.findByCriteria(cd);
        if(pickTaskDS == null || pickTaskDS.size() <= 0){
            throw new BizException("查询直通出库拣货任务明细失败！");
        }
        //生成barcode数据
        for (PickTaskH pickTaskH : pickTaskHList) {
            List<PickTaskD> taskDList = pickTaskDS.stream().filter(item -> item.getPickTaskId().equals(pickTaskH.getPickTaskId())).collect(Collectors.toList());
            if(taskDList == null || taskDList.size() <= 0){
                throw new BizException("匹配直通出库拣货任务明细失败！");
            }
            saveZtBarcode(pickTaskH,taskDList,userDTO);
        }
        //更新任务
        updatePickTaskStatus(pickTaskIds,userDTO);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelBill(String billId) {

        OmsDoBillHDO hdr = omsDoBillHMapper.findById(billId, OmsDoBillHDO.class);
        Assert.notNull(hdr, "根据订单号【{}】订单信息失败", billId);

        if ("5".equals(hdr.getStatus())) {
            throw new BizException("请勿重复取消");
        }

        FieldSelector fs1 = FieldSelector.newInstance().include("billId", "status", "lastmodifyby", "lastmodifydate");

        List<OmsDoBillDDO> dtls = omsDoBillDMapper.findFieldsByMap(fs1, MapUtils.put("billId", billId).getMap(), OmsDoBillDDO.class);
        Assert.notEmpty(dtls, "获取订单明细失败");

        DateTime now = DateUtil.date();
        UserDTO user = userTemplate.getUserDTO();
        hdr.setStatus("5");
        hdr.setIsCancelled(1);
        hdr.setLastmodifyby(user.getId());
        hdr.setLastmodifydate(now);

        dtls.forEach(t -> {
            t.setStatus("5");
            t.setLastmodifyby(user.getId());
            t.setLastmodifydate(now);
            omsDoBillDMapper.updateFields(t, fs1);
        });

        omsDoBillHMapper.updateFields(hdr, FieldSelector.newInstance().include("isCancelled", "status", "lastmodifyby", "lastmodifydate"));

        List<WaveBillDO> waves = waveBillMapper.findFieldsByMap(FieldSelector.newInstance().include("status"), MapUtils.put("srcId", billId).getMap(), WaveBillDO.class);
        //波次未下发
        if (CollUtil.isEmpty(waves)) {
            return;
        }
        boolean isDistributed = waves.stream().anyMatch(w -> "DISTRIBUTED".equals(w.getStatus()));
        FieldSelector fs3 = FieldSelector.newInstance().include("warehouseId", "pickModel", "containerCode", "pickTaskDId", "pickTaskId", "flowStatus");
        List<PickTaskD> taskList = pickTaskDMapper.findFieldsByMap(fs3, MapUtils.put("billId", billId).put("warehouseId", hdr.getBranchid()).getMap(), PickTaskD.class);
        //波次已下发&&拣货任务不存在进行拦截，待波次执行完再取消
        if (CollUtil.isEmpty(taskList) && isDistributed) {
            throw new BizException("波次已下发，请等波次执行完后再操作");
        }

        boolean isPicking = taskList.stream().anyMatch(t -> Integer.parseInt(t.getFlowStatus()) > Integer.parseInt(PickTaskDFLowStatus.GENERATE.getCode()));
        Assert.isFalse(isPicking, "取消失败，拣货任务已开始");

        FieldSelector fs4 = FieldSelector.newInstance().include("status", "pickTaskId", "modifierName", "gmtModified");
        String[] taskIds = taskList.stream().map(PickTaskD::getPickTaskId).distinct().toArray(String[]::new);
        List<PickTaskH> taskHs = pickTaskHMapper.findByIds(PickTaskH.class, taskIds, fs4);
        Assert.notEmpty(taskHs, "获取拣货汇总失败");

        List<PickTaskD> deviceTasks = taskList.stream().filter(t -> "Device".equals(t.getPickModel())).collect(Collectors.toList());
        if (CollUtil.isEmpty(deviceTasks)) {
            return;
        }

        taskList.forEach(t -> {
            t.setFlowStatus("99");
            t.setModifierName(user.getUsername());
            t.setGmtModified(now);
            pickTaskDMapper.updateFields(t, fs3);
        });

        taskHs.forEach(t -> {
            t.setStatus("99");
            t.setModifierName(user.getUsername());
            t.setGmtModified(now);
            pickTaskHMapper.updateFields(t, fs4);
        });

        List<CancelTasksVO> cancelList = packCancelTasksVoList(hdr, deviceTasks);

        eisHandler.cancelTasks(cancelList);
    }

    @Override
    public List<String> getInvoices(String billno) {
        if(StringUtils.isBlank(billno)){
            throw new ParameterException("订单编号不能为空!");
        }
        List<InvoicePdfDO> invoicePdfDOS = invoicePdfDOMapper.findByMap(MapUtils.put("orderNo", billno).getMap(), InvoicePdfDO.class);
        if(invoicePdfDOS == null || invoicePdfDOS.size() <= 0){
            return null;
        }
        return invoicePdfDOS.stream().map(InvoicePdfDO ::getPdfUrl).collect(Collectors.toList());
    }

    private static List<CancelTasksVO> packCancelTasksVoList(OmsDoBillHDO billH, List<PickTaskD> deviceTasks) {
        CancelTasksEnum cancelTasksEnum = CancelTasksEnum.get(billH.getBilltype());
        List<CancelTasksVO> cancelList = deviceTasks.stream().map(t -> {
            CancelTasksVO vo = new CancelTasksVO();
            vo.setMsgId(IdUtil.fastSimpleUUID());
            vo.setEnterpriseId(billH.getEnterpriseId());
            vo.setWarehouseId(t.getWarehouseId());
            vo.setWorkType(cancelTasksEnum.getWorkType());
            vo.setBusinessType(cancelTasksEnum.getBusinessType());
            vo.setTaskId(t.getPickTaskId());
            vo.setBillNo(billH.getBillno());
            vo.setContainerNo(t.getContainerCode());
            vo.setTaskLineId(t.getPickTaskDId());
            return vo;
        }).collect(Collectors.toList());
        return cancelList;
    }

    /**
     * 处理直通出库
     * @param ztBillhs
     * @param ztBillds
     */
    private void handleZtBills(List<OmsDoBillHDO> ztBillhs, List<OmsDoBillDDO> ztBillds) {
        for (OmsDoBillHDO ztBillh : ztBillhs) {
            List<OmsDoBillDDO> omsDoBillDDOS = ztBillds.stream().filter(item -> item.getBillid().equals(ztBillh.getBillid())).collect(Collectors.toList());
            //指定批次
            assignPosition(ztBillh,omsDoBillDDOS);
        }
        //特殊订单波次创建下发
        List<String> billIds = ztBillhs.stream().map(OmsDoBillHDO::getBillid).collect(Collectors.toList());
        WavesCreateDTO wavesCreateDTO = new WavesCreateDTO();
        wavesCreateDTO.setBillIdList(billIds);
        wavesCreateDTO.setWarehouseId(ztBillds.get(0).getBranchid());
        ztWaveCreate(wavesCreateDTO);
    }

    /**
     * 指定货位
     * @param omsDoBillHDO
     * @param ztBillds
     */
    private void assignPosition(OmsDoBillHDO omsDoBillHDO,List<OmsDoBillDDO> ztBillds){
        //获取直通货位
        RestMessage<String> locatorIdByCategory = warehouseResource.getLocatorIdByCategory("ZTK", omsDoBillHDO.getBranchid());
        if(locatorIdByCategory == null || !locatorIdByCategory.isSuccess() || StringUtils.isBlank(locatorIdByCategory.getData())){
            throw new BizException("获取直通库区货位失败!");
        }
        for (OmsDoBillDDO ztBilld : ztBillds) {
            //查询库存
            RestMessage<Page<WmsInvStockQtyVO>> pageRestMessage = inventoryResource.getAvailableQuantityPage(omsDoBillHDO.getConsignorid(), omsDoBillHDO.getBranchid(), omsDoBillHDO.getBillid(), ztBilld.getBillDId(), ztBilld.getItemid(), ztBilld.getLotNo(),locatorIdByCategory.getData());
            if(pageRestMessage == null || !pageRestMessage.isSuccess() || pageRestMessage.getData() == null || pageRestMessage.getData().getList() == null || pageRestMessage.getData().getList().size() <= 0){
                throw new BizException("直通出库，查询库存明细失败");
            }
            List<WmsInvStockQtyVO> stockQtyVOS = pageRestMessage.getData().getList();
            stockQtyVOS = stockQtyVOS.stream().filter(item -> item.getManufacturerLotNum().equals(ztBilld.getLotNo())).collect(Collectors.toList());
            //根据数量排序
            stockQtyVOS = stockQtyVOS.stream().sorted(Comparator.comparing(WmsInvStockQtyVO::getQuantity)).collect(Collectors.toList());
            List<BillDPrePositionVO> positions = new ArrayList<>();
            BigDecimal itemQty = ztBilld.getItemQty();
            for (WmsInvStockQtyVO stockQtyVO : stockQtyVOS) {
                if(itemQty.compareTo(BigDecimal.ZERO) <= 0){
                    return;
                }
                BillDPrePositionVO prePositionVO = new BillDPrePositionVO();
                prePositionVO.setAreaCategory(stockQtyVO.getInwarehouseAreaCategory());
                prePositionVO.setAreaCode(stockQtyVO.getWarehouseAreaCode());
                prePositionVO.setAreaId(stockQtyVO.getWarehouseAreaId());
                prePositionVO.setBatchId(stockQtyVO.getBatchId());
                prePositionVO.setBillDId(ztBilld.getLineid());
                prePositionVO.setBillId(ztBilld.getBillid());
                prePositionVO.setConversionRate(stockQtyVO.getCaseConversionRate());
                prePositionVO.setItemId(ztBilld.getItemid());
                prePositionVO.setLocationId(stockQtyVO.getLocatorId());
                prePositionVO.setLocationType(stockQtyVO.getLocatorType());
                prePositionVO.setManufacturerLotNum(stockQtyVO.getManufacturerLotNum());
                if(stockQtyVO.getQuantity().compareTo(itemQty) < 0){
                    prePositionVO.setQty(stockQtyVO.getQuantity());
                }else {
                    prePositionVO.setQty(itemQty);
                }
                itemQty.subtract(prePositionVO.getQty());
                positions.add(prePositionVO);
            }

            if(positions.size() <= 0){
                throw new BizException("直通出库，指定批次失败!");
            }
            billDPrePositionService.assignPosition(positions);
        }
    }

    /**
     * 直通出库波次下发
     * @param wavesCreateDTO
     */
    private void ztWaveCreate(WavesCreateDTO wavesCreateDTO){
        wavesSpecialService.wavesCreateAndSend(wavesCreateDTO);
    }

    /**
     * pick_task_h、pick_task_d更新
     * @param pickTaskIds
     */
    public void updatePickTaskStatus(List<String> pickTaskIds,UserDTO userDTO){
        Criteria ch = Criteria.forClass(PickTaskH.class);
        Restriction rh1 = Restrictions.in("pickTaskId", pickTaskIds.toArray());
        ch.setRestriction(rh1);
//        List<PickTaskH> pickTaskHS = pickTaskHMapper.findByCriteria(ch);
//        if(pickTaskHS == null || pickTaskHS.size() <= 0){
//            throw new BizException("查询直通出库拣货任务汇总失败！");
//        }
//
//        Criteria cd = Criteria.forClass(PickTaskD.class);
//        Restriction rd1 = Restrictions.in("pickTaskId", pickTaskIds.toArray());
//        cd.setRestriction(rd1);
//        List<PickTaskD> pickTaskDS = pickTaskDMapper.findByCriteria(cd);
//        if(pickTaskDS == null || pickTaskDS.size() <= 0){
//            throw new BizException("查询直通出库拣货任务明细失败！");
//        }

        //更新pick_task_h
        pickTaskHMapper.updateMapByCriteria(MapUtils.put("status", PickTaskHStatus.FINISHED.getCode()).getMap(),ch);
        //更新pick_task_d更新
        long updateZtPickTaskD = pickTaskDMapper.updateZtPickTaskD(userDTO,userDTO.getUserBizModel().getEmployeeNo(), DateUtil.now(), PickTaskDFLowStatus.OUT_REVIEW_CONFIRMED.getCode(), pickTaskIds);
        if(updateZtPickTaskD <= 0){
            throw new BizException("更新拣货任务明细失败!");
        }

    }


    private boolean saveZtBarcode(
            PickTaskH pickTaskH,
            List<PickTaskD> pickTaskDs,
            UserDTO userDTO
    ) {

        BarcodeHDO barCodeHDO = new BarcodeHDO();
        barCodeHDO.setBarcode(null);
        barCodeHDO.setBarcodeType("1");
        barCodeHDO.setId(UUIDUtils.generateWithoutSeperator());
        barCodeHDO.setType("0");
        barCodeHDO.setBillGroupId(pickTaskH.getBillGroupId());
        barCodeHDO.setStatus('0');
        barCodeHDO.setCheckStatus("5");

        barCodeHDO.setCheckerId("946760036036775936");
        barCodeHDO.setCheckerNo("10006");
        barCodeHDO.setCheckerName("廖美娟");

        barCodeHDO.setCheckerId2("946760036036775936");
        barCodeHDO.setCheckerNo2("10006");
        barCodeHDO.setCheckerName2("946760036036775936");

        RestMessage<Map<String, BusinessControl>> rest = strategyResource.getControlByCodes(new String[]{"zt_checker"}, userDTO.getUserBizModel().getDefaultWarehouseId(), null, userDTO.getEnterpriseId(), null);
        if (rest.isSuccess() && rest.getData() != null) {
            Map<String,BusinessControl> conMap = rest.getData();
            if (conMap.containsKey("zt_checker")) {
                BusinessControl businessControl = conMap.get("zt_checker");

                barCodeHDO.setCheckerId(businessControl.getRemark());
                barCodeHDO.setCheckerNo(businessControl.getRegValue());
                barCodeHDO.setCheckerName(businessControl.getRegName());

                barCodeHDO.setCheckerId2(businessControl.getRemark());
                barCodeHDO.setCheckerNo2(businessControl.getRegValue());
                barCodeHDO.setCheckerName2(businessControl.getRegName());
            }
        }

        barCodeHDO.setWarehouseId(pickTaskH.getWarehouseId());
        barCodeHDO.setBldgId(pickTaskH.getBldgId());
        barCodeHDO.setBldgName(pickTaskH.getBldgName());
        ModelUtils.generateBaseData(barCodeHDO, userTemplate::getUserDTO);
        barcodeHMapper.save(barCodeHDO);
        List<BarCodeDDO> barCodeDDOS = new ArrayList<>();
        for (PickTaskD pickTaskD : pickTaskDs) {
            BarCodeDDO barCodeDDO = new BarCodeDDO();
            barCodeDDO.setId(UUIDUtils.generateWithoutSeperator());
            ModelUtils.generateBaseData(barCodeDDO, userTemplate::getUserDTO);
            barCodeDDO.setBarcodeId(barCodeHDO.getId());
            barCodeDDO.setWmsPickTaskDId(pickTaskD.getPickTaskDId());
            barCodeDDO.setEnterpriseId(pickTaskH.getEnterpriseId());
            barCodeDDO.setWarehouseId(pickTaskH.getWarehouseId());
            Map<String, String> itemMap = pickTaskHMapper.getItemCode(pickTaskD.getPickTaskDId(), pickTaskH.getWarehouseId());
            if (itemMap != null && itemMap.containsKey("ITEM_ID")) {
                barCodeDDO.setItemCode(itemMap.get("ITEM_CODE"));
                barCodeDDO.setItemId(itemMap.get("ITEM_ID"));
            }
            barCodeDDO.setIsPiece(0);
            barCodeDDO.setCheckStatus("5");
            barCodeDDO.setQty(pickTaskD.getQty());
            barCodeDDOS.add(barCodeDDO);
        }

        barcodeDMapper.saveBatch(barCodeDDOS);
        return true;
    }


    /**
     * 调用接口平台
     * @param interfaceId 接口地址
     * @param param 参数
     * @return 调用结果
     */
    private RestMessage<?> askIntegration(String interfaceId, Object param){
        RestMessage<List<BaseCommonDict>> billtypeList = commonClient.getDictBasicListByCodes("integrationUrl", null);
        if (!billtypeList.isSuccess() || CollUtil.isEmpty(billtypeList.getData())){
            log.error("接口平台地址未配置，请在通用参照中增加配置 integrationUrl");
            return RestMessage.doError("integration未配置, 请求EIS/OMS失败");
        }
        BaseCommonDict dict = billtypeList.getData().stream().filter(var -> var.getDictCode().equals(interfaceId)).findFirst().orElse(null);
        if (null == dict){
            log.error("接口平台地址未配置，请在通用参照中增加配置integrationUrl的配置项： " + interfaceId);
            return RestMessage.doError("integration未配置, 请求EIS/OMS失败");
        }
        String paramJson = JSONObject.toJSONString(param);
        log.info("开始请求第三方接口：[{}], pram = 【{}】", dict.getDictName(), paramJson);
        HttpResponse response = HttpRequest.post(dict.getDictName()).body(paramJson).execute();
        log.info("结束请求第三方接口：[{}], 返回的结果为:【{}】", dict.getDictName(), response.body());
        return JSONObject.parseObject(response.body(), new TypeReference<RestMessage<?>>(){});
    }

    /**
     * 校验时间格式
     * @param date
     * @param format
     * @return
     */
    public  boolean isDateValid(String date, String format) {
        try {
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            sdf.setLenient(false);
            sdf.parse(date);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

}
