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

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.prolog.common.util.ToolKits;
import com.prolog.cs.basic.chain.model.cargo.BaseCargoOwnerMst;
import com.prolog.cs.basic.chain.model.customer.BaseCustomerMst;
import com.prolog.cs.basic.chain.model.supplier.BaseSupplierMst;
import com.prolog.cs.basic.common.model.BaseCommonDict;
import com.prolog.cs.basic.item.model.BaseMtlItemMst;
import com.prolog.cs.basic.warehouse.model.BaseWmsWarehouseMst;
import com.prolog.cs.biz.inbound.constant.BizConstant;
import com.prolog.cs.biz.inbound.constant.BussinessConstant;
import com.prolog.cs.biz.inbound.constant.InboundBizConstant;
import com.prolog.cs.biz.inbound.dao.OmsAsnBillDMapper;
import com.prolog.cs.biz.inbound.dao.OmsAsnBillHMapper;
import com.prolog.cs.biz.inbound.dao.SupervisionCodeMapper;
import com.prolog.cs.biz.inbound.dao.rcv.RcvHeadersMapper;
import com.prolog.cs.biz.inbound.dao.rcv.RcvInstockLinesMapper;
import com.prolog.cs.biz.inbound.dto.*;
import com.prolog.cs.biz.inbound.dto.rcv.RcvInstockLinesDTO;
import com.prolog.cs.biz.inbound.model.OmsAsnBillD;
import com.prolog.cs.biz.inbound.model.OmsAsnBillH;
import com.prolog.cs.biz.inbound.model.SupervisionCode;
import com.prolog.cs.biz.inbound.model.rcv.RcvHeaders;
import com.prolog.cs.biz.inbound.model.rcv.RcvInstockLines;
import com.prolog.cs.biz.inbound.remote.BaseItemRemoteCaller;
import com.prolog.cs.biz.inbound.remote.BaseWmsWarehouseCaller;
import com.prolog.cs.biz.inbound.remote.ChainRemoteCaller;
import com.prolog.cs.biz.inbound.remote.CommonCaller;
import com.prolog.cs.biz.inbound.remote.dto.OmsAsnBillDQueryVO;
import com.prolog.cs.biz.inbound.remote.dto.OmsAsnBillHQueryVO;
import com.prolog.cs.biz.inbound.service.OmsAsnBillDService;
import com.prolog.cs.biz.inbound.service.rcv.RcvInstockLinesService;
import com.prolog.cs.biz.inbound.utils.HttpClientUtil;
import com.prolog.cs.biz.inbound.utils.ObjectUtils;
import com.prolog.cs.biz.inbound.utils.UserUtils;
import com.prolog.cs.biz.inbound.vo.CancelOrderOmsVO;
import com.prolog.cs.biz.inbound.vo.OmsAsnBillDVO;
import com.prolog.cs.biz.inbound.vo.OmsAsnBillHVO;
import com.prolog.cs.biz.inbound.vo.RcvInstockLinesQueryVO;
import com.prolog.cs.data.exchange.client.ExchangeSender;
import com.prolog.cs.data.exchange.client.core.EtlMessage;
import com.prolog.cs.data.exchange.client.core.EtlTypeConstants;
import com.prolog.framework.authority.core.dto.UserDTO;
import com.prolog.framework.beans.BeanUtils;
import com.prolog.framework.bz.common.search.SearchApi;
import com.prolog.framework.common.message.RestMessage;
import com.prolog.framework.core.exception.BizException;
import com.prolog.framework.core.pojo.Page;
import com.prolog.framework.core.restriction.Criteria;
import com.prolog.framework.core.restriction.Order;
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 lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

import static com.prolog.cs.biz.inbound.constant.InboundBizConstant.P_ENTERPRISE_NAME;

@Slf4j
@Service
public class OmsAsnBillHServiceImpl implements OmsAsnBillDService {

    @Resource
    private UserUtils userUtils;

    @Resource
    private OmsAsnBillDMapper omsAsnBillDMapper;

    @Resource
    private OmsAsnBillHMapper omsAsnBillHMapper;

    @Resource
    private SupervisionCodeMapper supervisionCodeMapper;

    @Resource
    private RcvInstockLinesMapper instockMapper;

    @Resource
    private RcvHeadersMapper rcvHeadersMapper;

    @Autowired
    private BaseItemRemoteCaller baseItemRemoteCaller;

    @Autowired
    private ChainRemoteCaller chainRemoteCaller;

    @Autowired
    private BaseWmsWarehouseCaller warehouseCaller;

    @Resource
    private CommonCaller commonCaller;


    @Value("${erp.pull.url}")
    private String pullUrl;

    @Value("${erp.report.url}")
    private String reportUrl;

    /**
     * 查询已预约的asn订单
     */
    @Override
    public Page<OmsAsnBillH> queryOmsAsnBillHAudit(OmsAsnBillHQueryVO vo) {
        ToolKits.isParamNull(vo, "请求参数不能为空");
        ToolKits.isParamNull(vo.getPageNum(), "页码不能为空");
        ToolKits.isParamNull(vo.getPageSize(), "页码数不能为空");

        UserDTO userDTO = userUtils.getUserDTO();
        String enterpriseid = userDTO.getEnterpriseId();
        ToolKits.isParamNull(enterpriseid, "当前用户没有企业权限");

        Criteria criteria = Criteria.forClass(OmsAsnBillH.class);
        Restriction r1 = Restrictions.eq("pEnterpriseid", enterpriseid);
        Restriction r2 = Restrictions.in("status", new String[]{BussinessConstant.OMS_ASN_BILL_H_STATUS_YY}); // 状态为已预约的
        //        Restriction r3 = Restrictions.in("billtype", new String[]{BussinessConstant.OMS_ASN_BILL_H_BILLTYPE_CGRK});
        //        Restriction r4 = Restrictions.eq("refBilltype", BussinessConstant.OMS_ASN_BILL_H_REFBILLTYPE_CG);
        //		Restriction r5 = Restrictions.notIn("examineState",
        //				new String[] { BussinessConstant.OMS_ASN_BILL_H_EXAMINE_STATE_YBH,
        //						BussinessConstant.OMS_ASN_BILL_H_EXAMINE_STATE_YTG });
        Restriction r6 = null;
        if (ToolKits.isNotEmpty(vo.getSdate()) && ToolKits.isEmpty(vo.getEdate())) {
            r6 = Restrictions.between("createdate", vo.getSdate(), new GregorianCalendar(3000, 1, 1).getTime());
        }
        if (ToolKits.isEmpty(vo.getSdate()) && ToolKits.isNotEmpty(vo.getEdate())) {
            r6 = Restrictions.between("createdate", new GregorianCalendar(1700, 1, 1).getTime(), vo.getEdate());
        }
        if (ToolKits.isNotEmpty(vo.getSdate()) && ToolKits.isNotEmpty(vo.getEdate())) {
            r6 = Restrictions.between("createdate", vo.getSdate(), vo.getEdate());
        }

        Restriction r7 = null;
        if (ToolKits.isNotEmpty(vo.getsAttainDate()) && ToolKits.isEmpty(vo.geteAttainDate())) {
            r7 = Restrictions.between("attainDate", vo.getsAttainDate(), new GregorianCalendar(3000, 1, 1).getTime());
        }
        if (ToolKits.isEmpty(vo.getsAttainDate()) && ToolKits.isNotEmpty(vo.geteAttainDate())) {
            r7 = Restrictions.between("attainDate", new GregorianCalendar(1700, 1, 1).getTime(), vo.geteAttainDate());
        }
        if (ToolKits.isNotEmpty(vo.getsAttainDate()) && ToolKits.isNotEmpty(vo.geteAttainDate())) {
            r7 = Restrictions.between("attainDate", vo.getsAttainDate(), vo.geteAttainDate());
        }

        Restriction r8 = ToolKits.isEmpty(vo.getConsignorid()) ? null
          : Restrictions.eq("consignorid", vo.getConsignorid());
        Restriction r9 = ToolKits.isEmpty(vo.getShipperId()) ? null : Restrictions.eq("shipperId", vo.getShipperId());
        Restriction r10 = ToolKits.isEmpty(vo.getBranchid()) ? null : Restrictions.eq("branchid", vo.getBranchid());

        Restriction r12 = ToolKits.isEmpty(vo.getBillno()) ? null
          : Restrictions.like("billno", "%" + vo.getBillno() + "%");
        Restriction r13 = ToolKits.isEmpty(vo.getRefBillno()) ? null
          : Restrictions.like("refBillno", "%" + vo.getRefBillno() + "%");
        Restriction r14 = ToolKits.isEmpty(vo.getCreateby()) ? null
          : Restrictions.like("createby", "%" + vo.getCreateby() + "%");
        Restriction r15 = ToolKits.isEmpty(vo.getArrivalMode()) ? null
          : Restrictions.eq("arrivalMode", vo.getArrivalMode());

        criteria.setRestriction(Restrictions.and(r1, r2, r6, r7, r8, r9, r10, r12, r13, r14, r15));
        //		criteria.setOrder(Order.newInstance().asc("createdate"));
        criteria.setOrder(Order.newInstance().desc("lastmodifydate"));
        PageUtils.startPage(vo.getPageNum(), vo.getPageSize());

        // TODO 此处应该过滤处理完的asn单 原生sql实现
        List<OmsAsnBillH> findByCriteria = omsAsnBillHMapper.findByCriteria(criteria);

        return PageUtils.getPage(findByCriteria);
    }

    /**
     * 查询已经下发了的asn数据明细
     */
    @Override
    public Page<OmsAsnBillD> queryOmsAsnBillD(OmsAsnBillDQueryVO vo) {
        ToolKits.isParamNull(vo, "请求参数不能为空");
        ToolKits.isParamNull(vo.getPageNum(), "页码不能为空");
        ToolKits.isParamNull(vo.getPageSize(), "页码数不能为空");
        ToolKits.isParamNull(vo.getBillid(), "单据id不能为空");
        //		ToolKits.isParamNull(vo.getBillno(), "单据编号不能为空");

        UserDTO userDTO = userUtils.getUserDTO();
        String enterpriseid = userDTO.getEnterpriseId();
        ToolKits.isParamNull(enterpriseid, "当前用户没有企业权限");

        Criteria criteria = Criteria.forClass(OmsAsnBillD.class);
        Restriction r1 = Restrictions.eq("pEnterpriseid", enterpriseid);
        // 已下发的
        //		Restriction r2 = Restrictions.in("status", new String[] { BussinessConstant.OMS_ASN_BILL_D_STATUS_YXF });
        Restriction r3 = Restrictions.eq("billid", vo.getBillid());
        //		Restriction r4 = Restrictions.eq("billno", vo.getBillno());

        criteria.setRestriction(Restrictions.and(r1, r3));
        //		criteria.setOrder(Order.newInstance().asc("createdate"));
        criteria.setOrder(Order.newInstance().desc("lastmodifydate"));

        PageUtils.startPage(vo.getPageNum(), vo.getPageSize());

        // 此处应当用原生sql实现 TODO
        List<OmsAsnBillD> findByCriteria = omsAsnBillDMapper.findByCriteria(criteria);

        return PageUtils.getPage(findByCriteria);
    }

    @Override
    public List<Map<String, Object>> queryOmsAsnBillDRemainQty(OmsAsnBillDQueryVO vo) {
        // 此处应当用原生sql实现 TODO
        return omsAsnBillDMapper.queryOmsAsnBillDRemainQty(vo);
    }

    @Override
    public Object clear(List<String> ids) {
        AssertUtils.isNotEmpty(ids, "操作的集合不可为空!");
        Criteria crt = Criteria.forClass(OmsAsnBillH.class);
        crt.setRestriction(Restrictions.in("billid", ids.toArray(new String[ids.size()])));
        omsAsnBillHMapper.updateMapByCriteria(MapUtils.put("status", "500").getMap(), crt);
        return true;
    }

    /**
     * 手动回传erp入库订单
     */
    @Override
    public Object call2erp(String cargoOwnerId, String billNo, String rcvNo, String[] rcvIds) {
        if (StringUtils.isBlank(cargoOwnerId)) {
            throw new BizException("货主id不可为空!");
        }
        if (StringUtils.isBlank(billNo) && StringUtils.isBlank(rcvNo) && (rcvIds == null || rcvIds.length == 0)) {
            throw new BizException("请至少填写一种查询条件!");
        }
        // 找到所有的收货单
        Criteria crt = Criteria.forClass(RcvHeaders.class);
        Restriction eq = StringUtils.isBlank(billNo) ? null : Restrictions.eq("asnAutoBillNum", billNo);
        Restriction eq2 = StringUtils.isBlank(rcvNo) ? null : Restrictions.eq("autoBillNum", rcvNo);
        Restriction eq3 = ObjectUtils.isNull(rcvIds) ? null : Restrictions.in("rcvHeaderId", rcvIds);
        crt.setRestriction(Restrictions.and(eq, eq2, eq3));
        List<RcvHeaders> rcvList = rcvHeadersMapper.findByCriteria(crt);
        if (ObjectUtils.isNull(rcvList)) {
            throw new BizException("回传的收货单数据为空!请检查重试!");
        }
        Map<String, Object> queryMap = new HashMap<>();
        queryMap.put("cargoOwnerId", cargoOwnerId);
        List<Map> searchForMap = null;
        Integer isOneReturnErp = 0;
        try {
            searchForMap = searchApi.searchForMap("getCargoOwnerProp", queryMap);
        } catch (Exception e1) {
            logger.info("找寻货主属性失败,原因{}", e1);
        }
        if (searchForMap != null) {
            Map map = searchForMap.get(0);
            if (map != null && map.containsKey("isOneReturnErp")) {
                isOneReturnErp = (Integer) map.get("isOneReturnErp");
            }
        }

        Map<String, List<RcvHeaders>> collect = rcvList.stream()
          .collect(Collectors.groupingBy(RcvHeaders::getAsnAutoBillNum));
        for (List<RcvHeaders> rList : collect.values()) {
            RcvHeaders rcvHeaders = rList.get(0);
            String asnHeaderId = rcvHeaders.getAsnHeaderId();
            if (isOneReturnErp != null && isOneReturnErp == 1) {
                excuteCallBackErpBybillId(asnHeaderId, rList);
            } else {
                excuteCallBackErpByRcvId(rList);
            }
        }
        return null;
    }

    private void excuteCallBackErpByRcvId(List<RcvHeaders> rList) {
        for (RcvHeaders r : rList) {
            String rcvHeaderId = r.getRcvHeaderId();
            BigDecimal remainQty = this.rcvHeadersMapper.getRemainQty(rcvHeaderId);
            if (remainQty != null && BigDecimal.ZERO.compareTo(remainQty) == 0) {
                // 整单拒收
                excuteCallBackErp(rcvHeaderId);
            } else {
                throw new BizException(String.format("收货单[%s]没有需要回传的数据!", r.getAutoBillNum()));
            }
            RcvInstockLinesQueryVO queryVO = new RcvInstockLinesQueryVO();
            queryVO.setRcvHeaderId(rcvHeaderId);
            List<RcvInstockLinesDTO> instockDtoList = instockMapper.findList(queryVO);
            List<RcvInstockLines> instockList = new ArrayList<>();
            for (RcvInstockLinesDTO rcvInstockLinesDTO : instockDtoList) {
                RcvInstockLines rcvInstockLines = new RcvInstockLines();
                BeanUtils.copyProperties(rcvInstockLinesDTO, rcvInstockLines);
                instockList.add(rcvInstockLines);
            }
            rcvInstockLinesService.excuteExtCallBack(instockList);
        }
    }

    private void excuteCallBackErpBybillId(String asnHeaderId, List<RcvHeaders> rList) {
        if (vaildateBillComplete(asnHeaderId)) {
            String rcvIdsByBillId = rcvHeadersMapper.getRcvIdsByBillId(asnHeaderId);
            String[] split = rcvIdsByBillId.split(",");
            for (String rcvId : split) {
                // 需要根据asnHeaderId获取所有收货单id
                EtlMessage em = new EtlMessage();
                em.setId(rcvId);
                em.setEtlType(EtlTypeConstants.in_asn_w2o);
                try {
                    logger.info("整个订单上架回传给data-exchange数据:{}", JsonUtils.toString(em));
                    exchangeSender.send(em);
                    logger.info("整个订单上架回传给data-exchange成功!");
                } catch (Exception e) {
                    logger.error("整个订单上架回传失败,原因->{}", e);
                }
            }
            for (RcvHeaders r : rList) {
                String rcvHeaderId = r.getRcvHeaderId();
                RcvInstockLinesQueryVO queryVO = new RcvInstockLinesQueryVO();
                queryVO.setRcvHeaderId(rcvHeaderId);
                List<RcvInstockLinesDTO> instockDtoList = instockMapper.findList(queryVO);
                List<RcvInstockLines> instockList = new ArrayList<>();
                for (RcvInstockLinesDTO rcvInstockLinesDTO : instockDtoList) {
                    RcvInstockLines rcvInstockLines = new RcvInstockLines();
                    BeanUtils.copyProperties(rcvInstockLinesDTO, rcvInstockLines);
                    instockList.add(rcvInstockLines);
                }
                rcvInstockLinesService.excuteExtCallBack(instockList);
            }
        }

    }

    private void excuteCallBackErp(String masterId) {
        // 校验是否收货全部完成
        String rcvHeaderId = masterId;
        logger.info("收货回传开始-------------------------------");
        // 校验是否已经回传过oms数据
        vaildateCallBackErpComplete(masterId);

        EtlMessage em = new EtlMessage();
        em.setId(rcvHeaderId);
        em.setEtlType(EtlTypeConstants.in_asn_w2o);
        try {
            logger.info("收货回传给data-exchange数据:{}", JsonUtils.toString(em));
            exchangeSender.send(em);
            logger.info("收货回传data-exchange成功!");
        } catch (Exception e) {
            logger.error("收货回传失败,原因->{}", e);
        }

    }

    private void vaildateCallBackErpComplete(String masterId) {
        Map<String, Object> queryMap = new HashMap<>();
        queryMap.put("billid", masterId);
        List<Map> searchForMap = null;
        try {
            searchForMap = searchApi.searchForMap("vaildateCallBackErpComplete", queryMap);
        } catch (Exception e1) {
            logger.info("找寻oms回传数据失败,原因{}", e1);
        }
        if (searchForMap != null) {
            Map map = searchForMap.get(0);
            if (map != null && map.containsKey("count")) {
                Integer count = (Integer) map.get("count");
                if (count != null && count == 1) {
                    throw new BizException(String.format("回传单据id[%s]已经回传,无需重复操作!", masterId));
                }
            }
        }
    }

    private boolean vaildateBillComplete(String asnHeaderId) {
        // 校验整个采购单是否收货上架完毕
        BigDecimal qty = null;
        try {
            qty = rcvHeadersMapper.getRemainQtyByBillId(asnHeaderId);
            logger.info("剩余未上架数量" + qty.toString());
        } catch (Exception e) {
            logger.info("调用sql错误原因{}", e);
        }
        if (qty != null && qty.compareTo(BigDecimal.ZERO) == 0) {
            return true;
        }
        return false;
    }

	@Resource
	@Lazy
	private RcvInstockLinesService rcvInstockLinesService;

    @Resource
    private ExchangeSender exchangeSender;

    @Resource
    private SearchApi searchApi;

    private static Logger logger = LoggerFactory.getLogger(OmsAsnBillHServiceImpl.class);

	@Override
	public Object autoClear(Integer clearDays, String enterpriseId, String warehouseId, String cargoOwnerId) {
		if (clearDays == null) {
			clearDays = 30;
		}
		clearDays = -clearDays;
		Date date = new Date();
		Date endDate = ObjectUtils.calculateEndDate(date, clearDays);
		logger.info("清理时间->"+endDate);

		Criteria crt = Criteria.forClass(OmsAsnBillH.class);
		Restriction eq = StringUtils.isBlank(enterpriseId) ? null : Restrictions.eq("pEnterpriseid", enterpriseId);
		Restriction eq2 = StringUtils.isBlank(warehouseId) ? null : Restrictions.eq("branchid", warehouseId);
		Restriction eq3 = StringUtils.isBlank(cargoOwnerId) ? null : Restrictions.eq("consignorid", cargoOwnerId);
		Restriction lt = Restrictions.lt("billDate", endDate);
		crt.setRestriction(Restrictions.and(eq, eq2, eq3, lt));
		List<OmsAsnBillH> findByCriteria = omsAsnBillHMapper.findByCriteria(crt);
		if (!ObjectUtils.isNull(findByCriteria)) {
			Set<String> collect = findByCriteria.stream().map(OmsAsnBillH::getBillid).collect(Collectors.toSet());
			// 更新订单明细
			Criteria crt2 = Criteria.forClass(OmsAsnBillD.class);
			crt2.setRestriction(Restrictions.in("billid", collect.toArray()));
			omsAsnBillDMapper.updateMapByCriteria(MapUtils.put("status", "2000").getMap(), crt2);
			omsAsnBillHMapper.updateMapByCriteria(MapUtils.put("status", "2000").getMap(), crt);

			// TODO 回传erp,缺接口
		}
		return null;
	}

    @Override
    public Object autoClear(Integer clearDays) {
        if (clearDays == null) {
            clearDays = 30;
        }
        Date date = new Date();
        Date endDate = ObjectUtils.calculateEndDate(date, clearDays);

        Criteria crt = Criteria.forClass(OmsAsnBillH.class);
        crt.setRestriction(Restrictions.lt("billDate", endDate));
        List<OmsAsnBillH> findByCriteria = omsAsnBillHMapper.findByCriteria(crt);
        if (!ObjectUtils.isNull(findByCriteria)) {
            Set<String> collect = findByCriteria.stream().map(OmsAsnBillH::getBillid).collect(Collectors.toSet());
            // 更新订单明细
            Criteria crt2 = Criteria.forClass(OmsAsnBillD.class);
            crt2.setRestriction(Restrictions.in("billid", collect.toArray()));
            omsAsnBillDMapper.updateMapByCriteria(MapUtils.put("status", "2000").getMap(), crt2);
            omsAsnBillHMapper.updateMapByCriteria(MapUtils.put("status", "2000").getMap(), crt);

            // TODO 回传erp,缺接口
        }
        return null;
    }

    @Override
    public Object errorHandling(List<Map<String, Object>> errorMap) {
        // TODO 收货时入库订单异常信息回传erp 缺接口


        return null;
    }

    /**
     * 分页查询ASN主单信息
     *
     * @param query
     * @return
     */
    @Override
    public Page<OmsAsnBillHVO> queryOmsAsnBillH(OmsAsnBillHQueryVO query) {
        // 生成条件
        Restriction restriction = this.buildRestriction(query);
        Criteria crt = Criteria.forClass(OmsAsnBillH.class);
        crt.setRestriction(restriction);
        crt.setOrder(Order.newInstance().asc("createdate"));

        PageUtils.startPage(query.getPageNum(), query.getPageSize());
        List<OmsAsnBillH> omsAsnBillHS = omsAsnBillHMapper.findByCriteria(crt);

        List<OmsAsnBillHVO> vos = omsAsnBillHS.stream().map(entity -> {
              try {
                  return BeanUtils.copyProperties(entity, OmsAsnBillHVO.class);
              } catch (Exception e) {
                  logger.error("ASN单主要信息查询实体转VO发生错误,原因->{}", e);
              }
              return null;
          })
          .collect(Collectors.toList());

        // 修复分页 - by Huanglh 2022-02-15
        Page<OmsAsnBillH> pageH = PageUtils.getPage(omsAsnBillHS);
        Page<OmsAsnBillHVO> pageHVO = new Page<>();
        pageHVO.setStartRow(pageH.getStartRow());
        pageHVO.setEndRow(pageH.getEndRow());
        pageHVO.setPageCount(pageH.getPageCount());
        pageHVO.setPageNum(pageH.getPageNum());
        pageHVO.setPageSize(pageH.getPageSize());
        pageHVO.setTotalCount(pageH.getTotalCount());
        pageHVO.setList(vos);

        return pageHVO;
    }

    /**
     * 分页依据主单ID查询ASN明细数据
     *
     * @param billId
     * @param pageSize
     * @param pageNum
     * @return
     */
    @Override
    public Page<OmsAsnBillDVO> queryOmsAsnBillDByBillid(String billId, Integer pageSize, Integer pageNum) {
        ToolKits.isParamNull(billId, "请求主单BillId不能为空");
        Criteria crt = Criteria.forClass(OmsAsnBillD.class);
        crt.setRestriction(Restrictions.eq("billid", billId));
        crt.setOrder(Order.newInstance().desc("createdate"));

        PageUtils.startPage(pageNum, pageSize);
        List<OmsAsnBillD> details = omsAsnBillDMapper.findByCriteria(crt);
        List<OmsAsnBillDVO> vos = details.stream().map(entity -> {
              try {
                  return BeanUtils.copyProperties(entity, OmsAsnBillDVO.class);
              } catch (Exception e) {
                  logger.error("ASN单明细信息查询实体转VO发生错误,原因->{}", e);
              }
              return null;
          })
          .collect(Collectors.toList());

        // 修复分页 - by Huanglh 2022-02-15
        Page<OmsAsnBillD> pageD = PageUtils.getPage(details);
        Page<OmsAsnBillDVO> pageDVO = new Page<>();
        pageDVO.setStartRow(pageD.getStartRow());
        pageDVO.setEndRow(pageD.getEndRow());
        pageDVO.setPageCount(pageD.getPageCount());
        pageDVO.setPageNum(pageD.getPageNum());
        pageDVO.setPageSize(pageD.getPageSize());
        pageDVO.setTotalCount(pageD.getTotalCount());
        pageDVO.setList(vos);

        return pageDVO;
    }

    /**
     * 保存ASN单据主表及明细表信息
     *
     * @param saveDTOs
     */
    @Override
    @Transactional
    public void saveOmsAsnBill(List<OmsAsnBillSaveDTO> saveDTOs) {
        ToolKits.isParamNull(saveDTOs, "保存的单据不能为空");

        // 用户信息
        UserDTO userDTO = this.getUserDTO();
        Date date = new Date();

        // 待新增的数据
        List<OmsAsnBillH> hSaves = new ArrayList<>();
        List<OmsAsnBillD> dSaves = new ArrayList<>();
        // 待修改的数据
        List<OmsAsnBillH> hEdit = new ArrayList<>();
        List<OmsAsnBillD> dEdit = new ArrayList<>();
        for (OmsAsnBillSaveDTO saveDTO : saveDTOs) {
            // 构建主表数据
            OmsAsnBillH omsAsnBillH = new OmsAsnBillH();
            BeanUtils.copyProperties(saveDTO, omsAsnBillH);
            // 判断BillId为空则新增
            Boolean newHFlag = false;
            if (ObjectUtils.isNull(omsAsnBillH.getBillid())) {
                String billId = String.valueOf(SnowFlakeUtils.getId());
                omsAsnBillH.setBillid(billId);
                // 疑问：
                // 1. ASN单类型
                // 2. ASN单号生成规则
                // 3. 状态说明
                omsAsnBillH.setBillno(billId);
                // 类型给 "1"
                omsAsnBillH.setBilltype(saveDTO.getBilltype());
                // 状态默认给 "20"-审核
                omsAsnBillH.setStatus(BussinessConstant.OMS_ASN_BILL_H_STATUS_SH);
                // 当前用户信息
                omsAsnBillH.setCreateby(userDTO.getUsername());
                omsAsnBillH.setCreatedate(com.prolog.common.util.DateUtils.nowDate());
                omsAsnBillH.setpEnterpriseid(userDTO.getEnterpriseId());
                omsAsnBillH.setpEnterprisename(userDTO.getEnterpriseName());
                
                omsAsnBillH.setAttrStr14("wms");

                newHFlag = true;
            }

            // 构造明细表数据
            Integer seqNo = 0;
            BigDecimal zero = new BigDecimal("0");
            BigDecimal totPcs = new BigDecimal("0");  // 总件数
            BigDecimal totQty = new BigDecimal("0");  // 总数量
            BigDecimal totWeight = new BigDecimal("0");  // 总重量
            BigDecimal totVolume = new BigDecimal("0");  // 总体积
            BigDecimal totNetamt = new BigDecimal("0");  // 总未税金额
            BigDecimal totAmt = new BigDecimal("0");  // 总含税金额
            for (OmsAsnBillD omsAsnBillD : saveDTO.getDetailList()) {
                // 判断LineId为空则新增
                Boolean newDFlag = false;
                if (ObjectUtils.isNull(omsAsnBillD.getLineid())) {
                    String billDetailId = String.valueOf(SnowFlakeUtils.getId());
                    omsAsnBillD.setLineid(billDetailId);
                    omsAsnBillD.setSeqno((seqNo++).toString());
                    // 复制主表属性
                    omsAsnBillD.setBillid(omsAsnBillH.getBillid());
                    omsAsnBillD.setBillno(omsAsnBillH.getBillno());
                    omsAsnBillD.setBranchid(omsAsnBillH.getBranchid());
                    omsAsnBillD.setBranchcode(omsAsnBillH.getBranchcode());
                    omsAsnBillD.setBranchname(omsAsnBillH.getBranchname());
                    omsAsnBillD.setBranchareaid(omsAsnBillH.getBranchareaid());
                    omsAsnBillD.setBrancharea(omsAsnBillH.getBrancharea());
                    omsAsnBillD.setConsignorid(omsAsnBillH.getConsignorid());
                    omsAsnBillD.setConsignorname(omsAsnBillH.getConsignorname());
                    // 默认给 "10"-录入
                    omsAsnBillD.setStatus(BussinessConstant.OMS_ASN_BILL_D_STATUS_LR);

                    // 当前用户信息
                    omsAsnBillD.setCreateby(userDTO.getUsername());
                    omsAsnBillD.setCreatedate(date);
                    omsAsnBillD.setPEnterpriseid(userDTO.getEnterpriseId());
                    omsAsnBillD.setPEnterprisename(userDTO.getEnterpriseName());

                    newDFlag = true;
                    dSaves.add(omsAsnBillD);
                }

                // 计算回填主表数据的汇总数据
                totPcs = totPcs.add(ObjectUtils.isNull(omsAsnBillD.getItemPcs()) ? zero : omsAsnBillD.getItemPcs());
                totQty = totQty.add(ObjectUtils.isNull(omsAsnBillD.getItemQty()) ? zero : omsAsnBillD.getItemQty());
                totWeight = totWeight.add(ObjectUtils.isNull(omsAsnBillD.getItemWeight()) ? zero : omsAsnBillD.getItemWeight());
                totVolume = totVolume.add(ObjectUtils.isNull(omsAsnBillD.getItemVolume()) ? zero : omsAsnBillD.getItemVolume());
                totNetamt = totNetamt.add(ObjectUtils.isNull(omsAsnBillD.getTniAmt()) ? zero : omsAsnBillD.getTniAmt());
                totAmt = totAmt.add(ObjectUtils.isNull(omsAsnBillD.getAmt()) ? zero : omsAsnBillD.getAmt());

                if (!newDFlag) {
                    dEdit.add(omsAsnBillD);
                }
            }

            // 汇总数据回填主表数据
            omsAsnBillH.setTotPcs(totPcs);
            omsAsnBillH.setTotQty(totQty);
            omsAsnBillH.setTotWeight(totWeight);
            omsAsnBillH.setTotVolume(totVolume);
            omsAsnBillH.setTotnetamt(totNetamt);
            omsAsnBillH.setTotamt(totAmt);

            if (newHFlag) {
                hSaves.add(omsAsnBillH);
            } else {
                hEdit.add(omsAsnBillH);
            }
        }
        // 批量保存主表和明细表数据
        if (ObjectUtils.isNotNull(hSaves)) {
            omsAsnBillHMapper.saveBatch(hSaves);
        }
        if (ObjectUtils.isNotNull(dSaves)) {
            omsAsnBillDMapper.saveBatch(dSaves);
        }
        // 更新主表和明细表数据
        if (ObjectUtils.isNotNull(hEdit)) {
            this.updateOmsAsnBillH(hEdit, userDTO, date);
        }
        if (ObjectUtils.isNotNull(dEdit)) {
            this.updateOmsAsnBillD(dEdit, userDTO, date);
        }
    }

    @Override
    @Transactional
    public void saveAsnBillByOms(List<OmsAsnBillSaveByOmsDTO> saveDTOs) {
        ToolKits.isParamNull(saveDTOs, "保存的单据不能为空");

        Date date = new Date();

        // 待新增的数据
        List<OmsAsnBillH> hSaves = new ArrayList<>();
        List<OmsAsnBillD> dSaves = new ArrayList<>();

        //获取仓库信息
        //仓库编码集合
        Set<String> warehouseCodes = saveDTOs.stream().map(x -> x.getContent().getBranchcode()).collect(Collectors.toSet());
        List<BaseWmsWarehouseMst> warehouseMstList = null;
        if(warehouseCodes.size()>0){
            RestMessage<Map<String, BaseWmsWarehouseMst>> byWarehouseCode = warehouseCaller.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 = saveDTOs.stream().map(x -> x.getContent().getConsignorcode()).collect(Collectors.toSet());
        List<BaseCargoOwnerMst> cargoOwnerMstList = null;
        if(consignorCodes.size()>0){
            RestMessage<Map<String, BaseCargoOwnerMst>> byCode = chainRemoteCaller.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> supperCodes = saveDTOs.stream().filter(x->!x.getContent().getBilltype().equals("2")).map(x -> x.getContent().getShippercode()).collect(Collectors.toSet());
        Set<String> customCodes = saveDTOs.stream().filter(x->x.getContent().getBilltype().equals("2")).map(x -> x.getContent().getShippercode()).collect(Collectors.toSet());
        List<BaseSupplierMst> supplierMstList = new ArrayList<>();
        if(supperCodes.size()>0){
            RestMessage<List<BaseSupplierMst>> byCode = chainRemoteCaller.getBySupperCode(supperCodes);
            if(byCode.getData()!=null&&byCode.isSuccess()){
                supplierMstList = byCode.getData();
                if(supplierMstList.size()==0){
                    throw new BizException("供应商信息查询失败");
                }
            }else{
                throw new BizException("供应商信息查询失败");
            }
        }
        List<BaseCustomerMst> customerMstList = new ArrayList<>();
        if(customCodes.size()>0){
            RestMessage<List<BaseCustomerMst>> byCode = chainRemoteCaller.getByCustomerCode(customCodes);
            if(byCode.getData()!=null&&byCode.isSuccess()){
                customerMstList = byCode.getData();
                if(customerMstList.size()==0){
                    throw new BizException("客户信息查询失败");
                }
            }else{
                throw new BizException("客户信息查询失败");
            }
        }
        //获取商品信息
        List<OmsAsnBillD> detailList = new ArrayList<>();
        saveDTOs.stream().forEach(x->{
            List<OmsAsnBillD> 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 = baseItemRemoteCaller.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("商品信息查询失败");
                }
            }
        }

        for (OmsAsnBillSaveByOmsDTO omsAsnBillSaveDTO : saveDTOs) {
            // 构建主表数据
            OmsAsnBillH omsAsnBillH = new OmsAsnBillH();
            OmsAsnBillH saveDTO = omsAsnBillSaveDTO.getContent();
            BeanUtils.copyProperties(saveDTO, omsAsnBillH);
            // 判断BillId为空则新增
            String billId = String.valueOf(SnowFlakeUtils.getId());
            omsAsnBillH.setBillid(billId);
            // 状态默认给 "20"-审核
            omsAsnBillH.setStatus(BussinessConstant.OMS_ASN_BILL_H_STATUS_SH);
            omsAsnBillH.setCreateby("OMS");
            omsAsnBillH.setCreatedate(com.prolog.common.util.DateUtils.nowDate());

            //仓库信息
            BaseWmsWarehouseMst baseWmsWarehouseMst = warehouseMstList.stream().filter(x -> x.getWarehouseCode().equals(saveDTO.getBranchcode())).findFirst().orElse(null);
            if(baseWmsWarehouseMst!=null){
                omsAsnBillH.setBranchid(baseWmsWarehouseMst.getWarehouseId());
                omsAsnBillH.setBranchname(baseWmsWarehouseMst.getWarehouseName());
            }

            //货主信息
            BaseCargoOwnerMst baseCargoOwnerMst = cargoOwnerMstList.stream().filter(x -> x.getCargoOwnerCode().equals(saveDTO.getConsignorcode())).findFirst().orElse(null);
            if(baseCargoOwnerMst!=null){
                omsAsnBillH.setConsignorid(baseCargoOwnerMst.getCargoOwnerId());
                omsAsnBillH.setConsignorname(baseCargoOwnerMst.getCargoOwnerName());
            }

            //供应商信息
            if(supplierMstList.size()>0){
                BaseSupplierMst baseSupplierMst = supplierMstList.stream().filter(x -> x.getSupplierCode().equals(saveDTO.getShippercode())).findFirst().orElse(null);
                if(baseSupplierMst!=null){
                    omsAsnBillH.setShipperid(baseSupplierMst.getSupplierId());
                    omsAsnBillH.setShippername(baseSupplierMst.getSupplierName());
                }
            }
            //客户信息
            if(customerMstList.size()>0){
                BaseCustomerMst baseCustomerMst = customerMstList.stream().filter(x -> x.getCustomerCode().equals(saveDTO.getShippercode())).findFirst().orElse(null);
                if(baseCustomerMst!=null){
                    omsAsnBillH.setShipperid(baseCustomerMst.getCustomerId());
                    omsAsnBillH.setShippername(baseCustomerMst.getCustomerName());
                }
            }

            omsAsnBillH.setAttrStr14("wms");

            // 构造明细表数据
            BigDecimal zero = new BigDecimal("0");
            BigDecimal totPcs = new BigDecimal("0");  // 总件数
            BigDecimal totQty = new BigDecimal("0");  // 总数量
            BigDecimal totWeight = new BigDecimal("0");  // 总重量
            BigDecimal totVolume = new BigDecimal("0");  // 总体积
            BigDecimal totNetamt = new BigDecimal("0");  // 总未税金额
            BigDecimal totAmt = new BigDecimal("0");  // 总含税金额
            for (OmsAsnBillD omsAsnBillD : omsAsnBillSaveDTO.getDetailList()) {
                // 判断LineId为空则新增
                String billDetailId = String.valueOf(SnowFlakeUtils.getId());
                omsAsnBillD.setLineid(billDetailId);
                // 复制主表属性
                omsAsnBillD.setBillid(omsAsnBillH.getBillid());
                omsAsnBillD.setBillno(omsAsnBillH.getBillno());
                omsAsnBillD.setBranchid(omsAsnBillH.getBranchid());
                omsAsnBillD.setBranchcode(omsAsnBillH.getBranchcode());
                omsAsnBillD.setBranchname(omsAsnBillH.getBranchname());
                omsAsnBillD.setBranchareaid(omsAsnBillH.getBranchareaid());
                omsAsnBillD.setBrancharea(omsAsnBillH.getBrancharea());
                omsAsnBillD.setConsignorid(omsAsnBillH.getConsignorid());
                omsAsnBillD.setConsignorname(omsAsnBillH.getConsignorname());
                omsAsnBillD.setConsignorcode(omsAsnBillH.getConsignorcode());
                // 默认给 "10"-录入
                omsAsnBillD.setStatus(BussinessConstant.OMS_ASN_BILL_D_STATUS_LR);

                // 当前用户信息
                omsAsnBillD.setCreateby("OMS");
                omsAsnBillD.setCreatedate(date);
                omsAsnBillD.setPEnterpriseid(omsAsnBillH.getpEnterpriseid());
                omsAsnBillD.setPEnterprisename(omsAsnBillH.getpEnterprisename());
                if(!StringUtils.isEmpty(omsAsnBillD.getPdateFrom())){
                    Date parseDate = DateUtils.parse(omsAsnBillD.getPdateFrom(), "yyyy-MM-dd hh:mm:ss");
                    omsAsnBillD.setAttrStr2(DateUtils.format(parseDate,"yyyyMMdd"));
                }
                if(!StringUtils.isEmpty(omsAsnBillD.getValidUntil())){
                    Date parseDate = DateUtils.parse(omsAsnBillD.getValidUntil(), "yyyy-MM-dd hh:mm:ss");
                    omsAsnBillD.setAttrStr3(DateUtils.format(parseDate,"yyyyMMdd"));
                }

                //商品信息
                BaseMtlItemMst baseMtlItemMst = itemMstList.stream().filter(x -> x.getItemCode().equals(omsAsnBillD.getItemcode()) && x.getCargoOwnerId().equals(omsAsnBillH.getConsignorid())).findFirst().orElse(null);
                if(baseMtlItemMst!=null){
                    omsAsnBillD.setItemid(baseMtlItemMst.getItemId());
                    omsAsnBillD.setItemname(baseMtlItemMst.getItemName());
                }
                dSaves.add(omsAsnBillD);

                // 计算回填主表数据的汇总数据
                totPcs = totPcs.add(ObjectUtils.isNull(omsAsnBillD.getItemPcs()) ? zero : omsAsnBillD.getItemPcs());
                totQty = totQty.add(ObjectUtils.isNull(omsAsnBillD.getItemQty()) ? zero : omsAsnBillD.getItemQty());
                totWeight = totWeight.add(ObjectUtils.isNull(omsAsnBillD.getItemWeight()) ? zero : omsAsnBillD.getItemWeight());
                totVolume = totVolume.add(ObjectUtils.isNull(omsAsnBillD.getItemVolume()) ? zero : omsAsnBillD.getItemVolume());
                totNetamt = totNetamt.add(ObjectUtils.isNull(omsAsnBillD.getTniAmt()) ? zero : omsAsnBillD.getTniAmt());
                totAmt = totAmt.add(ObjectUtils.isNull(omsAsnBillD.getAmt()) ? zero : omsAsnBillD.getAmt());
            }

            // 汇总数据回填主表数据
            omsAsnBillH.setTotPcs(totPcs);
            omsAsnBillH.setTotQty(totQty);
            omsAsnBillH.setTotWeight(totWeight);
            omsAsnBillH.setTotVolume(totVolume);
            omsAsnBillH.setTotnetamt(totNetamt);
            omsAsnBillH.setTotamt(totAmt);

            hSaves.add(omsAsnBillH);
        }
        // 批量保存主表和明细表数据
        if (ObjectUtils.isNotNull(hSaves)) {
            omsAsnBillHMapper.saveBatch(hSaves);
        }
        if (ObjectUtils.isNotNull(dSaves)) {
            omsAsnBillDMapper.saveBatch(dSaves);
        }
    }

    @Override
    public List<CancelOrderOmsVO> cancelOrderOms(List<CancelOrderOmsVO> cancelList) {
        if(CollectionUtil.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<OmsAsnBillH> byMap = omsAsnBillHMapper.findByMap(MapUtils.put("billno", cancelOrder.getBillno())
                    .put("branchcode", cancelOrder.getBranchcode())
                    .put("consignorcode", cancelOrder.getConsignorcode())
                    .put("pEnterpriseid", cancelOrder.getPenterpriseid()).getMap(), OmsAsnBillH.class);
            if(byMap.size()==0){
                cancelOrder.setSuccess(false);
                cancelOrder.setMessage("未查找到对应单据");
                continue;
            }
            OmsAsnBillH omsAsnBillH = byMap.get(0);
            //校验是否有收货单据
            List<RcvHeaders> rcvHeadersList = rcvHeadersMapper.findByMap(MapUtils.put("asnHeaderId", omsAsnBillH.getBillid()).getMap(), RcvHeaders.class);
            if(rcvHeadersList.size()>0){
                cancelOrder.setSuccess(false);
                cancelOrder.setMessage("已有收货单据无法取消");
                continue;
            }
            //取消ASN单
            omsAsnBillHMapper.updateMapById(omsAsnBillH.getBillid(),MapUtils.put("status","500")
                    .put("closedReason",cancelOrder.getCancelReason())
                    .put("attrStr1",cancelOrder.getOrderType())
                    .put("attrStr2",cancelOrder.getRemark())
                    .put("attrStr3",cancelOrder.getExtendProps()).getMap(),OmsAsnBillH.class);
            cancelOrder.setSuccess(true);
            cancelOrder.setMessage("取消成功");
        }
        return cancelList;
    }

    /**
     * 依据BillId查询ASN主表及明细数据
     *
     * @param billId
     * @return
     */
    @Override
    public OmsAsnBillHVO queryOmsAsnBillHById(String billId) {
        ToolKits.isParamNull(billId, "请求主单BillId不能为空");
        OmsAsnBillH hData = omsAsnBillHMapper.findById(billId, OmsAsnBillH.class);
        OmsAsnBillHVO resVo = new OmsAsnBillHVO();
        BeanUtils.copyProperties(hData, resVo);

        return resVo;
    }

    /**
     * 拉取入库订单，ERP中间库(调用接口平台)
     *
     * @param
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void pullAsn() {
        //调用接口平台获取数据
        String json = null;
        try {
            json = HttpClientUtil.getInstance().post(pullUrl, "");
        } catch (IOException e) {
            e.printStackTrace();
        }

        Map map = JSONUtil.toBean(json, Map.class);

        Object o = map.get("data");
        if(ToolKits.isEmpty(o)){
            return;
        }
        List<ErpInfCgddBillDto> list = JSONObject.parseArray(JSONObject.toJSONString(o), ErpInfCgddBillDto.class);
        List<OmsAsnBillH> omsAsnBillHList = Lists.newArrayList();
        List<OmsAsnBillD> omsAsnBillDList = Lists.newArrayList();

        //查询商品
        Set<String> itemIdSet = list.stream().map(ErpInfCgddBillDto::getSpid).collect(Collectors.toSet());
        RestMessage<List<BaseMtlItemMst>> msg =
                baseItemRemoteCaller.getListByIds(itemIdSet);
        ToolKits.isMsgSuccess(msg);
        List<BaseMtlItemMst> data = msg.getData();
        if(ToolKits.isEmpty(data)){
            log.info("商品查询为空!");
            return;
        }
        Map<String, BaseMtlItemMst> itemIdToModel = data.stream().collect(Collectors.toMap(BaseMtlItemMst::getItemId,obj -> obj));

        //查询货主
        Set<String> idSet = list.stream().map(ErpInfCgddBillDto::getYzid).collect(Collectors.toSet());
        RestMessage<Map<String, BaseCargoOwnerMst>> cargoMsg = chainRemoteCaller.getByIds(idSet);
        ToolKits.isMsgSuccess(cargoMsg);
        Map<String, BaseCargoOwnerMst> idToModel = cargoMsg.getData();
        List<ErpReportDto> erpReportDtos = Lists.newArrayList();

        //查询供应商
        Set<String> dwidSet = list.stream().map(ErpInfCgddBillDto::getDwid).collect(Collectors.toSet());
        RestMessage<Object> supplierMstByIds = chainRemoteCaller.getSupplierMstByIds(dwidSet);
        ToolKits.isMsgSuccess(supplierMstByIds);
        String str = JSON.toJSONString(supplierMstByIds.getData());
        Map maps = (Map)JSON.parse(str);
        if(ToolKits.isEmpty(maps)){
            log.info("供应商查询为空!");
            return;
        }
        //将订单根据单据编号分组
        Map<String, List<ErpInfCgddBillDto>> djbhToDto = list.stream().collect(Collectors.groupingBy(a -> a.getDjbh()));
        for (String djbh : djbhToDto.keySet()) {
            List<ErpInfCgddBillDto> dtos = djbhToDto.get(djbh);
            BaseCargoOwnerMst baseCargoOwnerMst = idToModel.get(dtos.get(0).getYzid());
            if(ToolKits.isEmpty(baseCargoOwnerMst)){
                log.info("单据:"+djbh+",货主"+dtos.get(0).getYzid()+"查询为空!");
                continue;
            }
            OmsAsnBillH asnBillH = this.buildOmsAsnBillH(dtos,baseCargoOwnerMst);
            Object objMap = maps.get(dtos.get(0).getDwid());
            if(ToolKits.isEmpty(objMap)){
                log.info("单据:"+djbh+",供应商"+dtos.get(0).getDwid()+"查询为空!");
                continue;
            }
            Map<String, String> parse = (Map<String, String>) JSON.parse(JSON.toJSONString(objMap));
            asnBillH.setShippername(parse.get("supplierName"));
            omsAsnBillHList.add(asnBillH);
            BigDecimal totPcs = new BigDecimal("0");  // 总件数
            BigDecimal totQty = new BigDecimal("0");  // 总数量
            for (ErpInfCgddBillDto dto : dtos) {
                BaseMtlItemMst baseMtlItemMst = itemIdToModel.get(dto.getSpid());
                if(ToolKits.isEmpty(baseMtlItemMst)){
                    log.info("单据:"+djbh+",物料"+dto.getSpid()+"查询为空!");
                    continue;
                }
                OmsAsnBillD asnBillD = this.buildOmsAsnBillD(dto,baseMtlItemMst,asnBillH);
                omsAsnBillDList.add(asnBillD);

                ErpReportDto erpReportDto = new ErpReportDto();
                erpReportDto.setDjbh(djbh);
                erpReportDto.setDjSort(dto.getDj_sort());
                erpReportDto.setYzid(dto.getYzid());
                erpReportDto.setWmflg("Y");
                erpReportDto.setXgtime(com.prolog.common.util.DateUtils.format(com.prolog.common.util.DateUtils.nowDate(), com.prolog.common.util.DateUtils.PATTERN_SIMPLE));
                erpReportDtos.add(erpReportDto);

                totPcs = totPcs.add(asnBillD.getItemPcs());
                totQty = totQty.add(asnBillD.getItemQty());
            }
            asnBillH.setTotPcs(totPcs);
            asnBillH.setTotQty(totQty);
        }
        if(ToolKits.isNotEmpty(omsAsnBillDList)){
            omsAsnBillHMapper.saveBatch(omsAsnBillHList);
        }

        if(ToolKits.isNotEmpty(omsAsnBillHList)){
            omsAsnBillDMapper.saveBatch(omsAsnBillDList);
        }

        //调用接口平台回告修改标识
        Map<String,List<ErpReportDto>> params = Maps.newHashMap();
        params.put("dtoList",erpReportDtos);
        String result = null;
        try {
            result = HttpClientUtil.getInstance().post(reportUrl, JSON.toJSONString(params));
        } catch (IOException e) {
            log.info("接口平台调用失败:"+e.getMessage());
            return;
        }

    }

    private OmsAsnBillD buildOmsAsnBillD(ErpInfCgddBillDto dto,BaseMtlItemMst baseMtlItemMst,OmsAsnBillH asnBillH){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        OmsAsnBillD omsAsnBillD = new OmsAsnBillD();
        omsAsnBillD.setBillid(dto.getDjbh());
        omsAsnBillD.setBillno(dto.getDjbh());
        omsAsnBillD.setBranchid(InboundBizConstant.WAREHOUSE_ID);
        omsAsnBillD.setBranchname(InboundBizConstant.WAREHOUSE_NAME);
        omsAsnBillD.setLineid(ToolKits.convertToString(dto.getDj_sort()));
        omsAsnBillD.setItemid(dto.getSpid());
        omsAsnBillD.setSeqno(ToolKits.convertToString(dto.getDj_sort()));
        omsAsnBillD.setItemid(baseMtlItemMst.getItemId());
        omsAsnBillD.setItemcode(baseMtlItemMst.getItemCode());
        omsAsnBillD.setItemname(baseMtlItemMst.getItemName());
        omsAsnBillD.setBranchcode(asnBillH.getBranchcode());
        omsAsnBillD.setCreateby(InboundBizConstant.CREATE_BY);
        omsAsnBillD.setCreatedate(com.prolog.common.util.DateUtils.nowDate());
        BigDecimal sl = dto.getSl();//数量
        BigDecimal lss = dto.getLss();//零散
        BigDecimal js = dto.getJs();//件数
        //包装数量 =（数量-零散数）/件数
        omsAsnBillD.setPackSize((sl.subtract(lss).divide(js)));
        omsAsnBillD.setItemQty(sl);
        omsAsnBillD.setItemPcs(js);
        omsAsnBillD.setItemOdd(lss);
        omsAsnBillD.setLotNo(dto.getPh());
        omsAsnBillD.setPEnterpriseid(asnBillH.getPEnterpriseid());
        omsAsnBillD.setPEnterprisename(asnBillH.getPEnterprisename());
        omsAsnBillD.setPdateFrom(dto.getRq_sc());
        omsAsnBillD.setValidUntil(dto.getYxqz());
        omsAsnBillD.setPackUnits(baseMtlItemMst.getPieceUom());
        omsAsnBillD.setStatus(BizConstant.ASND_STATUS);
        omsAsnBillD.setFreeQty(new BigDecimal(0.0));
        omsAsnBillD.setAttrStr1(dto.getMjph());//灭菌批号(销售退回有值)
        omsAsnBillD.setAttrStr2(dto.getJkzczh());//进口药品注册批号(销售退回有值)
        omsAsnBillD.setConsignorid(asnBillH.getConsignorid());
        omsAsnBillD.setConsignorname(asnBillH.getConsignorname());
        omsAsnBillD.setConsignorcode(asnBillH.getConsignorcode());
        return omsAsnBillD;
    }

    private OmsAsnBillH buildOmsAsnBillH(List<ErpInfCgddBillDto> dtos,BaseCargoOwnerMst baseCargoOwnerMst) {
        OmsAsnBillH omsAsnBillH = new OmsAsnBillH();
        omsAsnBillH.setBillid(dtos.get(0).getDjbh());
        omsAsnBillH.setBillno(dtos.get(0).getDjbh());
        omsAsnBillH.setBilltype(dtos.get(0).getRktype());
        omsAsnBillH.setRefBilltype(dtos.get(0).getRktype());
        omsAsnBillH.setRefBillid(dtos.get(0).getDjbh());
        omsAsnBillH.setRefBillno(dtos.get(0).getDjbh());
        omsAsnBillH.setShipperType(InboundBizConstant.SHIPPER_TYPE);
        omsAsnBillH.setCreateby(InboundBizConstant.CREATE_BY);
        omsAsnBillH.setCreatedate(com.prolog.common.util.DateUtils.nowDate());
        omsAsnBillH.setpEnterpriseid(InboundBizConstant.P_ENTERPRISEID);
        omsAsnBillH.setpEnterprisename(P_ENTERPRISE_NAME);
        omsAsnBillH.setBranchid(InboundBizConstant.WAREHOUSE_ID);
        omsAsnBillH.setBranchcode(InboundBizConstant.WAREHOUSE_CODE);
        omsAsnBillH.setBranchname(InboundBizConstant.WAREHOUSE_NAME);
        omsAsnBillH.setTotWeight(new BigDecimal(0.0));
        omsAsnBillH.setTotVolume(new BigDecimal(0.0));
        omsAsnBillH.setTotnetamt(new BigDecimal(0.0));
        omsAsnBillH.setTotamt(new BigDecimal(0.0));
        omsAsnBillH.setBillDate(com.prolog.common.util.DateUtils.parse(dtos.get(0).getRq()));
        //到货日期，默认9999
        omsAsnBillH.setAttainDate(com.prolog.common.util.DateUtils.parse(InboundBizConstant.ATTAIN_DATE));
        omsAsnBillH.setStatus(BizConstant.ASN_STATUS);
        omsAsnBillH.setConsignorid(dtos.get(0).getYzid());
        omsAsnBillH.setConsignorname(baseCargoOwnerMst.getCargoOwnerName());
        omsAsnBillH.setConsignorcode(baseCargoOwnerMst.getCargoOwnerCode());
        omsAsnBillH.setShipperid(dtos.get(0).getDwid());
        /*omsAsnBillH.setShippername();*/
        omsAsnBillH.setBuyerName(dtos.get(0).getCgy());
        /*omsAsnBillH.setPriorityLevel("1");*/

        return omsAsnBillH;
    }

    // region 私有方法

    /**
     * 更新ASN单主表信息
     *
     * @param omsAsnBillHList
     * @param userDTO
     * @param date
     */
    private void updateOmsAsnBillH(List<OmsAsnBillH> omsAsnBillHList, UserDTO userDTO, Date date) {
        for (OmsAsnBillH omsAsnBillH : omsAsnBillHList) {
            // 修改人信息
            omsAsnBillH.setLastmodifyby(userDTO.getUsername());
            omsAsnBillH.setLastmodifydate(date);
            // 更新
            this.omsAsnBillHMapper.updateWithValidate(omsAsnBillH,
              p -> ObjectUtils.isNotNull(p) && ObjectUtils.isNotNull(p.getValue()));
        }
    }

    /**
     * 更新ASN单明细表信息
     *
     * @param omsAsnBillDList
     * @param userDTO
     * @param date
     */
    private void updateOmsAsnBillD(List<OmsAsnBillD> omsAsnBillDList, UserDTO userDTO, Date date) {
        for (OmsAsnBillD omsAsnBillD : omsAsnBillDList) {
            // 修改人信息
            omsAsnBillD.setLastmodifyby(userDTO.getUsername());
            omsAsnBillD.setLastmodifydate(date);
            // 更新
            this.omsAsnBillDMapper.updateWithValidate(omsAsnBillD,
//              p -> ObjectUtils.isNotNull(p) && ObjectUtils.isNotNull(p.getValue()));
            	// 上面可能应该值为空的而却没置为空bug
              p -> ObjectUtils.isNotNull(p));
        }
    }

    /**
     * 获取用户信息
     *
     * @return
     */
    private UserDTO getUserDTO() {
        UserDTO userDTO = userUtils.getUserDTO();

        ToolKits.isParamNull(userDTO, "用户信息获取失败");
        return userDTO;
    }

    /**
     * 生成查询条件
     *
     * @param query
     * @return
     */
    private Restriction buildRestriction(OmsAsnBillHQueryVO query) {
        ToolKits.isParamNull(query, "请求参数不能为空");
        ToolKits.isParamNull(query.getPageNum(), "页码不能为空");
        ToolKits.isParamNull(query.getPageSize(), "页码数不能为空");

        UserDTO userDTO = this.getUserDTO();
        String enterpriseid = userDTO.getEnterpriseId();
        ToolKits.isParamNull(enterpriseid, "当前用户没有企业权限");

        Restriction r1 = Restrictions.eq("pEnterpriseid", enterpriseid);
        // 订单紧急等级
        Restriction r2 = ToolKits.isEmpty(query.getPriorityLevel()) ? null
          : Restrictions.eq("priorityLevel", query.getPriorityLevel());

        Restriction r6 = null;
        if (ToolKits.isNotEmpty(query.getSdate()) && ToolKits.isEmpty(query.getEdate())) {
            // 只有起始日期: >= 起始日期
            r6 = Restrictions.ge("createdate", query.getSdate());
        }
        if (ToolKits.isEmpty(query.getSdate()) && ToolKits.isNotEmpty(query.getEdate())) {
            // 只有结束日期: <= 结束日期
            r6 = Restrictions.le("createdate", query.getEdate());
        }
        if (ToolKits.isNotEmpty(query.getSdate()) && ToolKits.isNotEmpty(query.getEdate())) {
            // 起始结束日期都有: between
            r6 = Restrictions.between("createdate", query.getSdate(), query.getEdate());
        }

        Restriction r7 = null;
        if (ToolKits.isNotEmpty(query.getsAttainDate()) && ToolKits.isEmpty(query.geteAttainDate())) {
            // 只有到货起始日期: >= 起到货始日期
            r7 = Restrictions.ge("attainDate", query.getsAttainDate());
        }
        if (ToolKits.isEmpty(query.getsAttainDate()) && ToolKits.isNotEmpty(query.geteAttainDate())) {
            // 只有到货结束日期: <= 到货结束日期
            r7 = Restrictions.le("attainDate", query.geteAttainDate());
        }
        if (ToolKits.isNotEmpty(query.getsAttainDate()) && ToolKits.isNotEmpty(query.geteAttainDate())) {
            // 到货起始结束日期都有: between
            r7 = Restrictions.between("attainDate", query.getsAttainDate(), query.geteAttainDate());
        }

        // 货主id
        Restriction r8 = ToolKits.isEmpty(query.getConsignorid()) ? null
          : Restrictions.eq("consignorid", query.getConsignorid());
        // 供应商id
        Restriction r9 = ToolKits.isEmpty(query.getShipperId()) ? null : Restrictions.eq("shipperid", query.getShipperId());
        // 入库仓库编号
        Restriction r10 = ToolKits.isEmpty(query.getBranchid()) ? null : Restrictions.eq("branchid", query.getBranchid());
        // ASN单号
        Restriction r12 = ToolKits.isEmpty(query.getBillno()) ? null
          : Restrictions.like("billno", "%" + query.getBillno() + "%");
        // 来源单据号
        Restriction r13 = ToolKits.isEmpty(query.getRefBillno()) ? null
          : Restrictions.like("refBillno", "%" + query.getRefBillno() + "%");
        // 录入员
        Restriction r14 = ToolKits.isEmpty(query.getCreateby()) ? null
          : Restrictions.like("createby", "%" + query.getCreateby() + "%");
        // 到货方式
        Restriction r15 = ToolKits.isEmpty(query.getArrivalMode()) ? null
          : Restrictions.eq("arrivalMode", query.getArrivalMode());
        // 采购员
        Restriction r16 = ToolKits.isEmpty(query.getBuyerName()) ? null
          : Restrictions.like("buyerName", "%" + query.getBuyerName() + "%");
        // 运输条件
        Restriction r17 = ToolKits.isEmpty(query.getShipTerm()) ? null
          : Restrictions.eq("shipTerm", query.getShipTerm());
        // 运输条件
        Restriction r18 = ToolKits.isEmpty(query.getAsnAutoBillNum()) ? null
                : Restrictions.like("billno", "%" + query.getAsnAutoBillNum() + "%");
        // 单据类型
        Restriction r19 = ToolKits.isEmpty(query.getBilltype()) ? null
                : Restrictions.eq("billtype", query.getBilltype());
        Restriction eq = Restrictions.eq("attrStr14", "wms"); // 只展示wms制作的
        return Restrictions.and(eq, r1, r2, r6, r7, r8, r9, r10, r12, r13, r14, r15, r16, r17, r18,r19);
    }
    // endregion

    @SneakyThrows
    @Override
    @Transactional
    public void saveAsnBill(List<ReceiveAsnDTO> saveDTOs) {
        ToolKits.isParamNull(saveDTOs, "保存的单据不能为空");
        // 待新增的数据
        List<OmsAsnBillH> hSaves = new ArrayList<>();
        List<OmsAsnBillD> dSaves = new ArrayList<>();
        List<SupervisionCode> supSaves = new ArrayList<>();

        //取消单据处理需要提前处理
        List<ReceiveAsnDTO> cancleList = saveDTOs.stream().filter((x -> "30".equals(x.getBillState()))).collect(Collectors.toList());
        if(ToolKits.isNotEmpty(cancleList) && cancleList.size()>0){
            for (ReceiveAsnDTO asnDTO : cancleList) {
                //查询asn主表数据
                Criteria criteriaBillH = Criteria.forClass(OmsAsnBillH.class);
                Restriction r1 = Restrictions.eq("billno", asnDTO.getBillNo());
                criteriaBillH.setRestriction(r1);
                List<OmsAsnBillH> asnBillHS = omsAsnBillHMapper.findByCriteria(criteriaBillH);
                if (asnBillHS.size() > 1) {
                    throw new RuntimeException(String.format("ASN单表中ASN单号+货主编码【%s%s】重复", asnDTO.getBillNo(), asnDTO.getConsignorCode()));
                }

                if ("30".equals(asnDTO.getBillState())) {//取消单据
                    if (asnBillHS.size() == 0) {
                        throw new RuntimeException(String.format("ASN单号【%s】未查询到对应单据，无法取消", asnDTO.getBillNo()));
                    }
                    if (asnBillHS.size() == 1) {
                        OmsAsnBillH omsAsnBillH = asnBillHS.get(0);
                        if (!omsAsnBillH.getStatus().equals(BussinessConstant.OMS_ASN_BILL_H_STATUS_SH)) {
                            throw new RuntimeException(String.format("ASN单号【%s】不是初始状态，无法取消", asnDTO.getBillNo()));
                        }
                        Criteria criteriaBillD = Criteria.forClass(OmsAsnBillD.class);
                        Restriction r3 = Restrictions.eq("billid", omsAsnBillH.getBillid());
                        criteriaBillD.setRestriction(Restrictions.and(r3));
                        List<OmsAsnBillD> asnBillDList = omsAsnBillDMapper.findByCriteria(criteriaBillD);
                        Set<String> statusSet = asnBillDList.stream().map(OmsAsnBillD::getStatus).filter(x -> !x.equals(BussinessConstant.OMS_ASN_BILL_D_STATUS_LR)).collect(Collectors.toSet());
                        if (statusSet.size() > 0) {
                            throw new RuntimeException(String.format("ASN单号【%s】存在不是初始状态的明细数据，无法取消", asnDTO.getBillNo()));
                        }
                        omsAsnBillH.setStatus("500");
                        omsAsnBillHMapper.update(omsAsnBillH);
                    }
                }
            }
        }

        //查询出非取消的单据
        saveDTOs = saveDTOs.stream().filter((x -> !"30".equals(x.getBillState()))).collect(Collectors.toList());
        if(ToolKits.isEmpty(saveDTOs)){
            return;
        }

        //获取仓库信息
        Set<String> warehouseCodes = saveDTOs.stream().map(x -> x.getBranchCode()).collect(Collectors.toSet());
        List<BaseWmsWarehouseMst> warehouseMstList = null;
        if(warehouseCodes.size()>0){
            RestMessage<Map<String, BaseWmsWarehouseMst>> byWarehouseCode = warehouseCaller.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 = saveDTOs.stream().map(x -> x.getConsignorCode()).collect(Collectors.toSet());
        List<BaseCargoOwnerMst> cargoOwnerMstList = null;
        if(consignorCodes.size()>0){
            RestMessage<Map<String, BaseCargoOwnerMst>> byCode = chainRemoteCaller.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> supperCodes = saveDTOs.stream().filter(x->x.getShipperType().equals("2")).map(x -> x.getShipperCode()).collect(Collectors.toSet());
        Set<String> customCodes = saveDTOs.stream().filter(x->x.getShipperType().equals("1")).map(x -> x.getShipperCode()).collect(Collectors.toSet());
        List<BaseSupplierMst> supplierMstList = new ArrayList<>();
        if(supperCodes.size()>0){
            RestMessage<List<BaseSupplierMst>> byCode = chainRemoteCaller.getBySupperCode(supperCodes);
            if(byCode.getData()!=null&&byCode.isSuccess()){
                supplierMstList = byCode.getData();
                if(supplierMstList.size()==0){
                    throw new BizException("供应商信息查询失败");
                }
            }else{
                throw new BizException("供应商信息查询失败");
            }
        }
        List<BaseCustomerMst> customerMstList = new ArrayList<>();
        if(customCodes.size()>0){
            RestMessage<List<BaseCustomerMst>> byCode = chainRemoteCaller.getByCustomerCode(customCodes);
            if(byCode.getData()!=null&&byCode.isSuccess()){
                customerMstList = byCode.getData();
                if(customerMstList.size()==0){
                    throw new BizException("客户信息查询失败");
                }
            }else{
                throw new BizException("客户信息查询失败");
            }
        }
        //获取商品信息,从明细中和监管码中获取
        List<ReceiveAsnDetailDTO> detailList = new ArrayList<>();
        saveDTOs.stream().forEach(x->{
            List<ReceiveAsnDetailDTO> billDList = x.getDetailList();
            detailList.addAll(billDList);
        });
//        for (ReceiveAsnDTO saveDTO : saveDTOs) {
//            if("6".equals(saveDTO.getBillType()) && (saveDTO.getSupervisionList() == null || saveDTO.getSupervisionList().size() <= 0)){
//                throw new BizException("直通入库，监管码不能为空!");
//            }
//        }
        List<ReceiveSupervisionDTO> supervisionList= new ArrayList<>();
        saveDTOs.stream().forEach(x->{
            if(x.getSupervisionList() != null && x.getSupervisionList().size() > 0){
                List<ReceiveSupervisionDTO> supList = x.getSupervisionList();
                supervisionList.addAll(supList);
            }
        });
        Set<String> itemCodes1 = detailList.stream().map(x->x.getItemCode()).collect(Collectors.toSet());
        Set<String> itemCodes2 = supervisionList.stream().map(x->x.getItemCode()).collect(Collectors.toSet());
        Set<String> itemCodes = Stream.concat(itemCodes1.stream(), itemCodes2.stream()).collect(Collectors.toSet());
        //请求商品信息
        List<BaseMtlItemMst> itemMstList = null;
        if(cargoOwnerMstList.size()>0){
            for (BaseCargoOwnerMst baseCargoOwnerMst : cargoOwnerMstList) {
                RestMessage<List<BaseMtlItemMst>> itemResult = baseItemRemoteCaller.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("商品信息查询失败");
                }
            }
        }

        //校验商品大类
        Set<String> categoryIds = detailList.stream().map(ReceiveAsnDetailDTO::getCategoryId).collect(Collectors.toSet());
        //获取物料大类字典
        RestMessage<List<BaseCommonDict>> commonRest = commonCaller.getDictBasicListByCodes("item_health_category", null);
        if(!commonRest.isSuccess()&&CollectionUtil.isEmpty(commonRest.getData())){
            throw new BizException("商品大类字典查询失败");
        }
        List<BaseCommonDict> baseCommonDicts = commonRest.getData();
        Set<String> dictCodes = baseCommonDicts.stream().map(BaseCommonDict::getDictCode).collect(Collectors.toSet());
        boolean anyMatch = categoryIds.stream().anyMatch(item -> !dictCodes.contains(item));
        if(anyMatch){
            throw new BizException("商品大类不正确!");
        }

        BaseWmsWarehouseMst baseWmsWarehouseMst = warehouseMstList.get(0);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        for (ReceiveAsnDTO asnDTO : saveDTOs) {
//            ToolKits.isParamNull(asnDTO.getBillState(), "单据状态不能为空");
            ToolKits.isParamNull(asnDTO.getDetailList(), "单据明细不能为空");
            //查询asn主表数据
            Criteria criteriaBillH=Criteria.forClass(OmsAsnBillH.class);
            Restriction r1 = Restrictions.eq("billno",asnDTO.getBillNo());
            Restriction r2 = Restrictions.eq("consignorcode",asnDTO.getConsignorCode());
            criteriaBillH.setRestriction(Restrictions.and(r1,r2));
            List<OmsAsnBillH> asnBillHS = omsAsnBillHMapper.findByCriteria(criteriaBillH);
            if(asnBillHS.size()>1){
                throw new RuntimeException(String.format("ASN单表中ASN单号+货主编码【%s%s】重复",asnDTO.getBillNo(),asnDTO.getConsignorCode()));
            }

            if(asnBillHS.size()== 1){ //更新操作
                OmsAsnBillH omsAsnBillH = asnBillHS.get(0);
                if(!omsAsnBillH.getStatus().equals(BussinessConstant.OMS_ASN_BILL_H_STATUS_SH)){
                    throw new RuntimeException(String.format("ASN单号【%s】不是初始状态，无法更新",asnDTO.getBillNo()));
                }
                Criteria criteriaBillD=Criteria.forClass(OmsAsnBillD.class);
                Restriction r3 = Restrictions.eq("billid",omsAsnBillH.getBillid());
                criteriaBillD.setRestriction(Restrictions.and(r3));
                List<OmsAsnBillD>  asnBillDList = omsAsnBillDMapper.findByCriteria(criteriaBillD);
                Set<String> statusSet = asnBillDList.stream().map(OmsAsnBillD ::getStatus).filter(x -> !x.equals(BussinessConstant.OMS_ASN_BILL_D_STATUS_LR)).collect(Collectors.toSet());
                if(statusSet.size()>0){
                    throw new RuntimeException(String.format("ASN单号【%s】存在不是初始状态的明细数据，无法更新",asnDTO.getBillNo()));
                }
                log.info("接收erp下传入库单，asn单明细查询结果：{}",JSON.toJSONString(asnBillDList));

                omsAsnBillH.setCreateby("ERP");
                omsAsnBillH.setCreatedate(com.prolog.common.util.DateUtils.nowDate());

                omsAsnBillH.setBranchcode(asnDTO.getBranchCode());
                omsAsnBillH.setBranchname(asnDTO.getBranchName());

                omsAsnBillH.setConsignorcode(asnDTO.getConsignorCode());
                omsAsnBillH.setConsignorname(asnDTO.getConsignorName());

                omsAsnBillH.setBillno(asnDTO.getBillNo());
                omsAsnBillH.setBilltype(asnDTO.getBillType());
                omsAsnBillH.setRefBilltype(asnDTO.getRefBillType());
                omsAsnBillH.setRefBillno(asnDTO.getRefBillNo());
                omsAsnBillH.setShipperType(asnDTO.getShipperType());
                omsAsnBillH.setShippercode(asnDTO.getShipperCode());
                omsAsnBillH.setShipTerm(asnDTO.getShipTerm());
                omsAsnBillH.setArrivalMode(asnDTO.getArrivalMode());
                omsAsnBillH.setPriorityLevel(asnDTO.getPriorityLevel());
                omsAsnBillH.setDelivererContactTel(asnDTO.getDelivererContactTel());
                omsAsnBillH.setShipLineId(asnDTO.getShipLineId());
                omsAsnBillH.setCarriercode(asnDTO.getCarrierCode());
                omsAsnBillH.setCarrierName(asnDTO.getCarrierName());
                omsAsnBillH.setBuyerName(asnDTO.getBuyerName());
                omsAsnBillH.setBuyerTel(asnDTO.getBuyerTel());
                omsAsnBillH.setBillDate(simpleDateFormat.parse(asnDTO.getBillDate()));
                if(!StringUtils.isEmpty(asnDTO.getAttainDate())){
                    omsAsnBillH.setAttainDate(DateUtils.parse(asnDTO.getAttainDate(), "yyyy-MM-dd hh:mm:ss"));
                }
                omsAsnBillH.setExamineState(asnDTO.getExamineState());
                omsAsnBillH.setClosedReason(asnDTO.getClosedReason());
                omsAsnBillH.setRtReason(asnDTO.getRtReason());
                omsAsnBillH.setRemark(asnDTO.getRemark());
                omsAsnBillH.setPurorgCode(asnDTO.getPurorgCode());
                omsAsnBillH.setPurorgName(asnDTO.getPurorgName());
                omsAsnBillH.setShippingType(asnDTO.getShippingType());
                omsAsnBillH.setTransportUnit(asnDTO.getTransportUnit());
                if(!StringUtils.isEmpty(asnDTO.getShipmentDate())){
                    omsAsnBillH.setShipmentDate(DateUtils.parse(asnDTO.getShipmentDate(), "yyyy-MM-dd hh:mm:ss"));
                }
                omsAsnBillH.setShipmentPlace(asnDTO.getShipmentPlace());
                omsAsnBillH.setTransitTime(asnDTO.getTransitTime());
                omsAsnBillH.setItemHealthIndustry(asnDTO.getItemHealthIndustry());
                omsAsnBillH.setCarrierUnit(asnDTO.getCarrierUnit());

                //供应商信息
                if(supplierMstList.size()>0){
                    BaseSupplierMst baseSupplierMst = supplierMstList.stream().filter(x -> x.getSupplierCode().equals(asnDTO.getShipperCode())).findFirst().orElse(null);
                    if(baseSupplierMst!=null){
                        omsAsnBillH.setShipperid(baseSupplierMst.getSupplierId());
                        omsAsnBillH.setShippername(baseSupplierMst.getSupplierName());
                    }
                }
                //客户信息
                if(customerMstList.size()>0){
                    BaseCustomerMst baseCustomerMst = customerMstList.stream().filter(x -> x.getCustomerCode().equals(asnDTO.getShipperCode())).findFirst().orElse(null);
                    if(baseCustomerMst!=null){
                        omsAsnBillH.setShipperid(baseCustomerMst.getCustomerId());
                        omsAsnBillH.setShippername(baseCustomerMst.getCustomerName());
                    }
                }
                omsAsnBillH.setAttrStr14("wms");


                // 构造明细表数据
                BigDecimal zero = new BigDecimal("0");
                BigDecimal totPcs = new BigDecimal("0");  // 总件数
                BigDecimal totQty = new BigDecimal("0");  // 总数量
                BigDecimal totWeight = new BigDecimal("0");  // 总重量
                BigDecimal totVolume = new BigDecimal("0");  // 总体积
                BigDecimal totNetamt = new BigDecimal("0");  // 总未税金额
                BigDecimal totAmt = new BigDecimal("0");  // 总含税金额
                for (ReceiveAsnDetailDTO asnDetailDTO : asnDTO.getDetailList()) {
                    //把明细行号作为唯一标识更新，不是的话就需要修改代码
                    OmsAsnBillD omsAsnBillD = asnBillDList.stream().filter(x -> x.getSeqno().equals(asnDetailDTO.getSeqNo())).findFirst().orElse(null);
                    if(omsAsnBillD == null){
//                            throw new BizException("根据单号："+omsAsnBillH.getBillno()+",行号："+asnDetailDTO.getSeqNo()+"匹配明细失败!");
                        //新增明细行
                        omsAsnBillD =new OmsAsnBillD();

                        String billDetailId = String.valueOf(SnowFlakeUtils.getId());
                        omsAsnBillD.setLineid(billDetailId);
                        // 复制主表属性
                        omsAsnBillD.setBillid(omsAsnBillH.getBillid());
                        omsAsnBillD.setBillno(omsAsnBillH.getBillno());
                        omsAsnBillD.setBranchid(omsAsnBillH.getBranchid());
                        omsAsnBillD.setBranchcode(omsAsnBillH.getBranchcode());
                        omsAsnBillD.setBranchname(omsAsnBillH.getBranchname());
                        omsAsnBillD.setBranchareaid(omsAsnBillH.getBranchareaid());
                        omsAsnBillD.setBrancharea(omsAsnBillH.getBrancharea());
                        omsAsnBillD.setConsignorid(omsAsnBillH.getConsignorid());
                        omsAsnBillD.setConsignorname(omsAsnBillH.getConsignorname());
                        omsAsnBillD.setConsignorcode(omsAsnBillH.getConsignorcode());
                        // 默认给 "10"-录入
                        omsAsnBillD.setStatus(BussinessConstant.OMS_ASN_BILL_D_STATUS_LR);

                        // 当前用户信息
                        omsAsnBillD.setCreateby("ERP");
                        omsAsnBillD.setCreatedate(com.prolog.common.util.DateUtils.nowDate());
                        omsAsnBillD.setPEnterpriseid(omsAsnBillH.getpEnterpriseid());
                        omsAsnBillD.setPEnterprisename(omsAsnBillH.getpEnterprisename());
                        if(!StringUtils.isEmpty(asnDetailDTO.getPdateFrom())){
                            Date parseDate = DateUtils.parse(asnDetailDTO.getPdateFrom(), "yyyy-MM-dd hh:mm:ss");
                            omsAsnBillD.setAttrStr2(DateUtils.format(parseDate,"yyyyMMdd"));
                        }
                        if(!StringUtils.isEmpty(asnDetailDTO.getValidUntil())){
                            Date parseDate = DateUtils.parse(asnDetailDTO.getValidUntil(), "yyyy-MM-dd hh:mm:ss");
                            omsAsnBillD.setAttrStr3(DateUtils.format(parseDate,"yyyyMMdd"));
                        }

                        //商品信息
                        BaseMtlItemMst baseMtlItemMst = itemMstList.stream().filter(x -> x.getItemCode().equals(asnDetailDTO.getItemCode()) && x.getCargoOwnerId().equals(omsAsnBillH.getConsignorid())).findFirst().orElse(null);
                        if(baseMtlItemMst!=null){
                            omsAsnBillD.setItemid(baseMtlItemMst.getItemId());
                            omsAsnBillD.setItemname(baseMtlItemMst.getItemName());
                        }else {
                            throw new BizException(String.format("根据货主【%s】和物料编码【%s】获取物料信息失败",omsAsnBillH.getConsignorid(),asnDetailDTO.getItemCode()) );
                        }
                        omsAsnBillD.setSeqno(asnDetailDTO.getSeqNo());
                        omsAsnBillD.setItemcode(asnDetailDTO.getItemCode());
//                            omsAsnBillD.setItemname(asnDetailDTO.getItemName());
                        omsAsnBillD.setPrice(fillBigDecimalByString(asnDetailDTO.getPrice()));
                        omsAsnBillD.setTniPrice(fillBigDecimalByString(asnDetailDTO.getTniPrice()));
                        omsAsnBillD.setAmt(fillBigDecimalByString(asnDetailDTO.getAmt()));
                        omsAsnBillD.setTniAmt(fillBigDecimalByString(asnDetailDTO.getTniAmt()));
                        omsAsnBillD.setApprovalNumber(asnDetailDTO.getApprovalNumber());
                        omsAsnBillD.setCategoryId(asnDetailDTO.getCategoryId());
                        BaseCommonDict baseCommonDict = baseCommonDicts.stream().filter(item -> item.getDictCode().equals(asnDetailDTO.getCategoryId())).findFirst().orElse(null);
                        if(baseCommonDict == null){
                            throw new BizException("商品大类："+asnDetailDTO.getCategoryId()+"未在通用参照中维护!");
                        }
                        omsAsnBillD.setTypeName(baseCommonDict.getDictName());
                        omsAsnBillD.setPackSize(fillBigDecimalByString(asnDetailDTO.getPackSize()));
                        omsAsnBillD.setPackUnits(asnDetailDTO.getPackUnits());
                        omsAsnBillD.setItemPcs(fillBigDecimalByString(asnDetailDTO.getItemPcs()));
                        omsAsnBillD.setItemOdd(fillBigDecimalByString(asnDetailDTO.getItemOdd()));
                        omsAsnBillD.setItemQty(fillBigDecimalByString(asnDetailDTO.getItemQty()));
                        omsAsnBillD.setLotNo(asnDetailDTO.getLotNo());
                        omsAsnBillD.setBatchNo(asnDetailDTO.getBatchNo());
                        omsAsnBillD.setSterilizelotno(asnDetailDTO.getSterilizelotno());
                        omsAsnBillD.setPdateFrom(asnDetailDTO.getPdateFrom());
                        omsAsnBillD.setValidUntil(asnDetailDTO.getValidUntil());
                        omsAsnBillD.setRtreason(asnDetailDTO.getRtReason());
                        omsAsnBillD.setLineRemark(asnDetailDTO.getLineRemark());
                        omsAsnBillDMapper.save(omsAsnBillD);
                    }else {
                        // 复制主表属性
                        omsAsnBillD.setBillid(omsAsnBillH.getBillid());
                        omsAsnBillD.setBillno(omsAsnBillH.getBillno());
                        omsAsnBillD.setBranchid(omsAsnBillH.getBranchid());
                        omsAsnBillD.setBranchcode(omsAsnBillH.getBranchcode());
                        omsAsnBillD.setBranchname(omsAsnBillH.getBranchname());
                        omsAsnBillD.setBranchareaid(omsAsnBillH.getBranchareaid());
                        omsAsnBillD.setBrancharea(omsAsnBillH.getBrancharea());
                        omsAsnBillD.setConsignorid(omsAsnBillH.getConsignorid());
                        omsAsnBillD.setConsignorname(omsAsnBillH.getConsignorname());
                        omsAsnBillD.setConsignorcode(omsAsnBillH.getConsignorcode());
                        // 默认给 "10"-录入
                        omsAsnBillD.setStatus(BussinessConstant.OMS_ASN_BILL_D_STATUS_LR);

                        // 当前用户信息
                        omsAsnBillD.setCreateby("ERP");
                        omsAsnBillD.setCreatedate(com.prolog.common.util.DateUtils.nowDate());
                        omsAsnBillD.setPEnterpriseid(omsAsnBillH.getpEnterpriseid());
                        omsAsnBillD.setPEnterprisename(omsAsnBillH.getpEnterprisename());
                        if(!StringUtils.isEmpty(asnDetailDTO.getPdateFrom())){
                            Date parseDate = DateUtils.parse(asnDetailDTO.getPdateFrom(), "yyyy-MM-dd hh:mm:ss");
                            omsAsnBillD.setAttrStr2(DateUtils.format(parseDate,"yyyyMMdd"));
                        }
                        if(!StringUtils.isEmpty(asnDetailDTO.getValidUntil())){
                            Date parseDate = DateUtils.parse(asnDetailDTO.getValidUntil(), "yyyy-MM-dd hh:mm:ss");
                            omsAsnBillD.setAttrStr3(DateUtils.format(parseDate,"yyyyMMdd"));
                        }

                        //商品信息
                        BaseMtlItemMst baseMtlItemMst = itemMstList.stream().filter(x -> x.getItemCode().equals(asnDetailDTO.getItemCode()) && x.getCargoOwnerId().equals(omsAsnBillH.getConsignorid())).findFirst().orElse(null);
                        if(baseMtlItemMst!=null){
                            omsAsnBillD.setItemid(baseMtlItemMst.getItemId());
                            omsAsnBillD.setItemname(baseMtlItemMst.getItemName());
                        }
                        omsAsnBillD.setSeqno(asnDetailDTO.getSeqNo());
                        omsAsnBillD.setItemcode(asnDetailDTO.getItemCode());
//                            omsAsnBillD.setItemname(asnDetailDTO.getItemName());
                        omsAsnBillD.setPrice(fillBigDecimalByString(asnDetailDTO.getPrice()));
                        omsAsnBillD.setTniPrice(fillBigDecimalByString(asnDetailDTO.getTniPrice()));
                        omsAsnBillD.setAmt(fillBigDecimalByString(asnDetailDTO.getAmt()));
                        omsAsnBillD.setTniAmt(fillBigDecimalByString(asnDetailDTO.getTniAmt()));
                        omsAsnBillD.setApprovalNumber(asnDetailDTO.getApprovalNumber());
                        omsAsnBillD.setCategoryId(asnDetailDTO.getCategoryId());
                        BaseCommonDict baseCommonDict = baseCommonDicts.stream().filter(item -> item.getDictCode().equals(asnDetailDTO.getCategoryId())).findFirst().orElse(null);
                        if(baseCommonDict == null){
                            throw new BizException("商品大类："+asnDetailDTO.getCategoryId()+"未在通用参照中维护!");
                        }
                        omsAsnBillD.setTypeName(baseCommonDict.getDictName());
                        omsAsnBillD.setPackSize(fillBigDecimalByString(asnDetailDTO.getPackSize()));
                        omsAsnBillD.setPackUnits(asnDetailDTO.getPackUnits());
                        omsAsnBillD.setItemPcs(fillBigDecimalByString(asnDetailDTO.getItemPcs()));
                        omsAsnBillD.setItemOdd(fillBigDecimalByString(asnDetailDTO.getItemOdd()));
                        omsAsnBillD.setItemQty(fillBigDecimalByString(asnDetailDTO.getItemQty()));
                        omsAsnBillD.setLotNo(asnDetailDTO.getLotNo());
                        omsAsnBillD.setBatchNo(asnDetailDTO.getBatchNo());
                        omsAsnBillD.setSterilizelotno(asnDetailDTO.getSterilizelotno());
                        omsAsnBillD.setPdateFrom(asnDetailDTO.getPdateFrom());
                        omsAsnBillD.setValidUntil(asnDetailDTO.getValidUntil());
                        omsAsnBillD.setRtreason(asnDetailDTO.getRtReason());
                        omsAsnBillD.setLineRemark(asnDetailDTO.getLineRemark());

                        omsAsnBillDMapper.update(omsAsnBillD);
                    }
                }
                //判断明细是否删除
                //下发行号
                Set<String> seqNos = asnDTO.getDetailList().stream().map(ReceiveAsnDetailDTO::getSeqNo).collect(Collectors.toSet());
                //库里行号
                asnBillDList = omsAsnBillDMapper.findByMap(MapUtils.put("billno",omsAsnBillH.getBillno()).getMap(),OmsAsnBillD.class);
                Set<String> dbSeqNos = asnBillDList.stream().map(OmsAsnBillD::getSeqno).collect(Collectors.toSet());
                Set<String> delSeqNos = dbSeqNos.stream().filter(item -> !seqNos.contains(item)).collect(Collectors.toSet());
                if(delSeqNos != null && delSeqNos.size() > 0 ){
                    for (String delSeqNo : delSeqNos) {
                        omsAsnBillDMapper.deleteByMap(MapUtils.put("billid",omsAsnBillH.getBillid()).put("seqno",delSeqNo).getMap(),OmsAsnBillD.class);
                    }
                }
                List<OmsAsnBillD> omsAsnBillDS = omsAsnBillDMapper.findByMap(MapUtils.put("billid", omsAsnBillH.getBillid()).getMap(), OmsAsnBillD.class);
                // 计算回填主表数据的汇总数据
                totPcs = omsAsnBillDS.stream().map(OmsAsnBillD::getItemPcs).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
//                    totPcs = totPcs.add(ObjectUtils.isNull(omsAsnBillD.getItemPcs()) ? zero : omsAsnBillD.getItemPcs());
                totQty = omsAsnBillDS.stream().map(OmsAsnBillD::getItemQty).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
//                    totQty = totQty.add(ObjectUtils.isNull(omsAsnBillD.getItemQty()) ? zero : omsAsnBillD.getItemQty());
                totWeight = omsAsnBillDS.stream().filter(item -> item.getItemWeight() != null).map(OmsAsnBillD::getItemWeight).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
//                    totWeight = totWeight.add(ObjectUtils.isNull(omsAsnBillD.getItemWeight()) ? zero : omsAsnBillD.getItemWeight());
                totVolume = omsAsnBillDS.stream().filter(item -> item.getItemVolume() != null).map(OmsAsnBillD::getItemVolume).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
//                    totVolume = totVolume.add(ObjectUtils.isNull(omsAsnBillD.getItemVolume()) ? zero : omsAsnBillD.getItemVolume());
                totNetamt = omsAsnBillDS.stream().filter(item -> item.getTniAmt() != null).map(OmsAsnBillD::getTniAmt).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
//                    totNetamt = totNetamt.add(ObjectUtils.isNull(omsAsnBillD.getTniAmt()) ? zero : omsAsnBillD.getTniAmt());
                totAmt = omsAsnBillDS.stream().filter(item -> item.getAmt() != null).map(OmsAsnBillD::getAmt).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
//                    totAmt = totAmt.add(ObjectUtils.isNull(omsAsnBillD.getAmt()) ? zero : omsAsnBillD.getAmt());

                // 汇总数据回填主表数据
                omsAsnBillH.setTotPcs(totPcs);
                omsAsnBillH.setTotQty(totQty);
                omsAsnBillH.setTotWeight(totWeight);
                omsAsnBillH.setTotVolume(totVolume);
                omsAsnBillH.setTotnetamt(totNetamt);
                omsAsnBillH.setTotamt(totAmt);
                omsAsnBillHMapper.update(omsAsnBillH);

                // 更新监管码数据 todo

            }else {//新增操作
                // 构建主表数据
                OmsAsnBillH omsAsnBillH = new OmsAsnBillH();
                String billId = String.valueOf(SnowFlakeUtils.getId());
                omsAsnBillH.setBillid(billId);
                // 状态默认给 "20"-审核
                omsAsnBillH.setStatus(BussinessConstant.OMS_ASN_BILL_H_STATUS_SH);
                omsAsnBillH.setCreateby("ERP");
                omsAsnBillH.setCreatedate(DateUtil.date());

                omsAsnBillH.setBranchid(baseWmsWarehouseMst.getWarehouseId());
                omsAsnBillH.setBranchcode(asnDTO.getBranchCode());
                omsAsnBillH.setBranchname(asnDTO.getBranchName());

                omsAsnBillH.setpEnterpriseid(baseWmsWarehouseMst.getEnterpriseId());
                omsAsnBillH.setpEnterprisename(P_ENTERPRISE_NAME);

                omsAsnBillH.setConsignorid(cargoOwnerMstList.get(0).getCargoOwnerId());//暂时写死
                omsAsnBillH.setConsignorcode(asnDTO.getConsignorCode());
                omsAsnBillH.setConsignorname(asnDTO.getConsignorName());

                omsAsnBillH.setBillno(asnDTO.getBillNo());
                omsAsnBillH.setBilltype(asnDTO.getBillType());
                omsAsnBillH.setRefBilltype(asnDTO.getRefBillType());
                omsAsnBillH.setRefBillno(asnDTO.getRefBillNo());
                omsAsnBillH.setShipperType(asnDTO.getShipperType());
                omsAsnBillH.setShippercode(asnDTO.getShipperCode());
                omsAsnBillH.setShipTerm(asnDTO.getShipTerm());
                omsAsnBillH.setArrivalMode(asnDTO.getArrivalMode());
                omsAsnBillH.setPriorityLevel(asnDTO.getPriorityLevel());
                omsAsnBillH.setDelivererContactTel(asnDTO.getDelivererContactTel());
                omsAsnBillH.setShipLineId(asnDTO.getShipLineId());
                omsAsnBillH.setCarriercode(asnDTO.getCarrierCode());
                omsAsnBillH.setCarrierName(asnDTO.getCarrierName());
                omsAsnBillH.setBuyerName(asnDTO.getBuyerName());
                omsAsnBillH.setBuyerTel(asnDTO.getBuyerTel());
                omsAsnBillH.setBillDate(DateUtils.parse(asnDTO.getBillDate(), "yyyy-MM-dd hh:mm:ss"));
                if(!StringUtils.isEmpty(asnDTO.getAttainDate())){
                    omsAsnBillH.setAttainDate(DateUtils.parse(asnDTO.getAttainDate(), "yyyy-MM-dd hh:mm:ss"));
                }

                omsAsnBillH.setExamineState(asnDTO.getExamineState());
                omsAsnBillH.setClosedReason(asnDTO.getClosedReason());
                omsAsnBillH.setRtReason(asnDTO.getRtReason());
                omsAsnBillH.setRemark(asnDTO.getRemark());
                omsAsnBillH.setPurorgCode(asnDTO.getPurorgCode());
                omsAsnBillH.setPurorgName(asnDTO.getPurorgName());
                omsAsnBillH.setShippingType(asnDTO.getShippingType());
                omsAsnBillH.setTransportUnit(asnDTO.getTransportUnit());
                if(!StringUtils.isEmpty(asnDTO.getShipmentDate())){
                    omsAsnBillH.setShipmentDate(DateUtils.parse(asnDTO.getShipmentDate(), "yyyy-MM-dd hh:mm:ss"));
                }

                omsAsnBillH.setShipmentPlace(asnDTO.getShipmentPlace());
                omsAsnBillH.setTransitTime(asnDTO.getTransitTime());
                omsAsnBillH.setItemHealthIndustry(asnDTO.getItemHealthIndustry());
                omsAsnBillH.setCarrierUnit(asnDTO.getCarrierUnit());

                //供应商信息
                if(supplierMstList.size()>0){
                    BaseSupplierMst baseSupplierMst = supplierMstList.stream().filter(x -> x.getSupplierCode().equals(asnDTO.getShipperCode())).findFirst().orElse(null);
                    if(baseSupplierMst!=null){
                        omsAsnBillH.setShipperid(baseSupplierMst.getSupplierId());
                        omsAsnBillH.setShippername(baseSupplierMst.getSupplierName());
                    }
                }
                //客户信息
                if(customerMstList.size()>0){
                    BaseCustomerMst baseCustomerMst = customerMstList.stream().filter(x -> x.getCustomerCode().equals(asnDTO.getShipperCode())).findFirst().orElse(null);
                    if(baseCustomerMst!=null){
                        omsAsnBillH.setShipperid(baseCustomerMst.getCustomerId());
                        omsAsnBillH.setShippername(baseCustomerMst.getCustomerName());
                    }
                }
                omsAsnBillH.setAttrStr14("wms");
                omsAsnBillH.setStraightTaskCompleteFlag("0");

                // 构造明细表数据
                BigDecimal zero = new BigDecimal("0");
                BigDecimal totPcs = new BigDecimal("0");  // 总件数
                BigDecimal totQty = new BigDecimal("0");  // 总数量
                BigDecimal totWeight = new BigDecimal("0");  // 总重量
                BigDecimal totVolume = new BigDecimal("0");  // 总体积
                BigDecimal totNetamt = new BigDecimal("0");  // 总未税金额
                BigDecimal totAmt = new BigDecimal("0");  // 总含税金额
                for (ReceiveAsnDetailDTO asnDetailDTO : asnDTO.getDetailList()) {
                    OmsAsnBillD omsAsnBillD =new OmsAsnBillD();

                    String billDetailId = String.valueOf(SnowFlakeUtils.getId());
                    omsAsnBillD.setLineid(billDetailId);
                    // 复制主表属性
                    omsAsnBillD.setBillid(omsAsnBillH.getBillid());
                    omsAsnBillD.setBillno(omsAsnBillH.getBillno());
                    omsAsnBillD.setBranchid(omsAsnBillH.getBranchid());
                    omsAsnBillD.setBranchcode(omsAsnBillH.getBranchcode());
                    omsAsnBillD.setBranchname(omsAsnBillH.getBranchname());
                    omsAsnBillD.setBranchareaid(omsAsnBillH.getBranchareaid());
                    omsAsnBillD.setBrancharea(omsAsnBillH.getBrancharea());
                    omsAsnBillD.setConsignorid(omsAsnBillH.getConsignorid());
                    omsAsnBillD.setConsignorname(omsAsnBillH.getConsignorname());
                    omsAsnBillD.setConsignorcode(omsAsnBillH.getConsignorcode());
                    // 默认给 "10"-录入
                    omsAsnBillD.setStatus(BussinessConstant.OMS_ASN_BILL_D_STATUS_LR);

                    // 当前用户信息
                    omsAsnBillD.setCreateby("ERP");
                    omsAsnBillD.setCreatedate(com.prolog.common.util.DateUtils.nowDate());
                    omsAsnBillD.setPEnterpriseid(omsAsnBillH.getpEnterpriseid());
                    omsAsnBillD.setPEnterprisename(omsAsnBillH.getpEnterprisename());
                    if(!StringUtils.isEmpty(asnDetailDTO.getPdateFrom())){
                        Date parseDate = DateUtils.parse(asnDetailDTO.getPdateFrom(), "yyyy-MM-dd hh:mm:ss");
                        omsAsnBillD.setAttrStr2(DateUtils.format(parseDate,"yyyyMMdd"));
                    }
                    if(!StringUtils.isEmpty(asnDetailDTO.getValidUntil())){
                        Date parseDate = DateUtils.parse(asnDetailDTO.getValidUntil(), "yyyy-MM-dd hh:mm:ss");
                        omsAsnBillD.setAttrStr3(DateUtils.format(parseDate,"yyyyMMdd"));
                    }

                    //商品信息
                    BaseMtlItemMst baseMtlItemMst = itemMstList.stream().filter(x -> x.getItemCode().equals(asnDetailDTO.getItemCode()) && x.getCargoOwnerId().equals(omsAsnBillH.getConsignorid())).findFirst().orElse(null);
                    if(baseMtlItemMst!=null){
                        omsAsnBillD.setItemid(baseMtlItemMst.getItemId());
                        omsAsnBillD.setItemname(baseMtlItemMst.getItemName());
                    }else {
                        throw new BizException(String.format("根据货主【%s】和物料编码【%s】获取物料信息失败",omsAsnBillH.getConsignorid(),asnDetailDTO.getItemCode()) );
                    }
                    omsAsnBillD.setSeqno(asnDetailDTO.getSeqNo());
                    omsAsnBillD.setItemcode(asnDetailDTO.getItemCode());
//                        omsAsnBillD.setItemname(asnDetailDTO.getItemName());
                    omsAsnBillD.setPrice(fillBigDecimalByString(asnDetailDTO.getPrice()));
                    omsAsnBillD.setTniPrice(fillBigDecimalByString(asnDetailDTO.getTniPrice()));
                    omsAsnBillD.setAmt(fillBigDecimalByString(asnDetailDTO.getAmt()));
                    omsAsnBillD.setTniAmt(fillBigDecimalByString(asnDetailDTO.getTniAmt()));
                    omsAsnBillD.setApprovalNumber(asnDetailDTO.getApprovalNumber());
                    omsAsnBillD.setCategoryId(asnDetailDTO.getCategoryId());
                    BaseCommonDict baseCommonDict = baseCommonDicts.stream().filter(item -> item.getDictCode().equals(asnDetailDTO.getCategoryId())).findFirst().orElse(null);
                    if(baseCommonDict == null){
                        throw new BizException("商品大类："+asnDetailDTO.getCategoryId()+"未在通用参照中维护!");
                    }
                    omsAsnBillD.setTypeName(baseCommonDict.getDictName());
                    omsAsnBillD.setPackSize(fillBigDecimalByString(asnDetailDTO.getPackSize()));
                    omsAsnBillD.setPackUnits(asnDetailDTO.getPackUnits());
                    omsAsnBillD.setItemPcs(fillBigDecimalByString(asnDetailDTO.getItemPcs()));
                    omsAsnBillD.setItemOdd(fillBigDecimalByString(asnDetailDTO.getItemOdd()));
                    omsAsnBillD.setItemQty(fillBigDecimalByString(asnDetailDTO.getItemQty()));
                    omsAsnBillD.setLotNo(asnDetailDTO.getLotNo());
                    omsAsnBillD.setBatchNo(asnDetailDTO.getBatchNo());
                    omsAsnBillD.setSterilizelotno(asnDetailDTO.getSterilizelotno());
                    omsAsnBillD.setPdateFrom(asnDetailDTO.getPdateFrom());
                    omsAsnBillD.setValidUntil(asnDetailDTO.getValidUntil());
                    omsAsnBillD.setRtreason(asnDetailDTO.getRtReason());
                    omsAsnBillD.setLineRemark(asnDetailDTO.getLineRemark());


                    dSaves.add(omsAsnBillD);

                    // 计算回填主表数据的汇总数据
                    totPcs = totPcs.add(ObjectUtils.isNull(omsAsnBillD.getItemPcs()) ? zero : omsAsnBillD.getItemPcs());
                    totQty = totQty.add(ObjectUtils.isNull(omsAsnBillD.getItemQty()) ? zero : omsAsnBillD.getItemQty());
                    totWeight = totWeight.add(ObjectUtils.isNull(omsAsnBillD.getItemWeight()) ? zero : omsAsnBillD.getItemWeight());
                    totVolume = totVolume.add(ObjectUtils.isNull(omsAsnBillD.getItemVolume()) ? zero : omsAsnBillD.getItemVolume());
                    totNetamt = totNetamt.add(ObjectUtils.isNull(omsAsnBillD.getTniAmt()) ? zero : omsAsnBillD.getTniAmt());
                    totAmt = totAmt.add(ObjectUtils.isNull(omsAsnBillD.getAmt()) ? zero : omsAsnBillD.getAmt());
                }

                // 汇总数据回填主表数据
                omsAsnBillH.setTotPcs(totPcs);
                omsAsnBillH.setTotQty(totQty);
                omsAsnBillH.setTotWeight(totWeight);
                omsAsnBillH.setTotVolume(totVolume);
                omsAsnBillH.setTotnetamt(totNetamt);
                omsAsnBillH.setTotamt(totAmt);
                hSaves.add(omsAsnBillH);

                // 构造监管码数据
                if(ToolKits.isNotEmpty(asnDTO.getSupervisionList())){
                    for (ReceiveSupervisionDTO asnDetailDTO : asnDTO.getSupervisionList()) {
                        SupervisionCode supervision =new SupervisionCode();
                        String supervisionId = String.valueOf(SnowFlakeUtils.getId());
                        supervision.setId(supervisionId);
                        supervision.setEnterpriseId(omsAsnBillH.getPEnterpriseid());
                        supervision.setWarehouseCode(asnDTO.getBranchCode());
                        supervision.setCargoOwnerCode(asnDTO.getConsignorCode());
                        //先用asn的billId保存数据，后续直通流程完成后用wms_in_rcv_lines的RCV_HEADER_ID和RCV_LINE_ID更新
                        supervision.setRefBillId(omsAsnBillH.getBillid());
//                            supervision.setRefBillLineId(omsAsnBillH.getBillid());
                        supervision.setScanName("青牛WMS");
                        supervision.setScanDate(new Date());
                        supervision.setUploadFlag("0");
                        supervision.setCodeType("1");
                        supervision.setPackLevel("0");
                        supervision.setStatus("10");
                        supervision.setBillType("1");
                        supervision.setStage(0);
                        BaseMtlItemMst baseMtlItemMst = itemMstList.stream().filter(x -> x.getItemCode().equals(asnDetailDTO.getItemCode())).findFirst().orElse(null);
                        supervision.setItemId(baseMtlItemMst.getItemId());
                        supervision.setItemName(baseMtlItemMst.getItemName());
                        supervision.setItemCode(asnDetailDTO.getItemCode());
                        OmsAsnBillD omsAsnBillD = dSaves.stream().filter(x -> x.getItemcode().equals(asnDetailDTO.getItemCode())).findFirst().orElse(null);
                        supervision.setPackSize(omsAsnBillD.getPackSize().toString());
                        supervision.setWarehouseId(omsAsnBillD.getBranchid());
                        supervision.setCargoOwnerId(omsAsnBillD.getConsignorid());
                        supervision.setUnlock(0);
                        supervision.setSrcCode(asnDTO.getRefBillNo());
                        supervision.setCreatorName("青牛WMS");
                        supervision.setModifierName("青牛WMS");
                        supervision.setSupervisionCode(asnDetailDTO.getSupervisionCode());
                        supervision.setManufacturerLotNum(asnDetailDTO.getLotNo());
                        if("大".equals(asnDetailDTO.getSupervisionType())){
                            supervision.setSupervisionType(0);
                        }
                        if("中".equals(asnDetailDTO.getSupervisionType())){
                            supervision.setSupervisionType(1);
                        }
                        if("小".equals(asnDetailDTO.getSupervisionType())){
                            supervision.setSupervisionType(2);
                        }
                        supSaves.add(supervision);
                    }
                }
            }
        }

        // 批量保存主表和明细表数据
        if (ObjectUtils.isNotNull(hSaves)) {
            omsAsnBillHMapper.saveBatch(hSaves);
        }
        if (ObjectUtils.isNotNull(dSaves)) {
            omsAsnBillDMapper.saveBatch(dSaves);
        }
        if (ObjectUtils.isNotNull(supSaves)) {
            supervisionCodeMapper.saveBatch(supSaves);
        }
    }

    private BigDecimal fillBigDecimalByString(String amt) {
        return StrUtil.isNotEmpty(amt) ? new BigDecimal(amt.toString()) : BigDecimal.ZERO;
    }
}
