package com.prolog.rdc.tms.app.service.business.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.prolog.common.util.DateUtils;
import com.prolog.common.util.ToolKits;
import com.prolog.framework.common.message.RestMessage;
import com.prolog.framework.core.exception.BizException;
import com.prolog.framework.core.exception.ParameterException;
import com.prolog.framework.core.exception.PrologException;
import com.prolog.framework.core.pojo.Page;
import com.prolog.framework.core.restriction.Criteria;
import com.prolog.framework.core.restriction.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.product.core.framework.entity.UserEntity;
import com.prolog.product.core.framework.util.PlgFxUsrUtils;
import com.prolog.rdc.tms.app.constant.BussinessConstant;
import com.prolog.rdc.tms.app.constant.DataDictionaryConstant;
import com.prolog.rdc.tms.app.constant.SeriaNnumberConstant;
import com.prolog.rdc.tms.app.constant.StatusConstant;
import com.prolog.rdc.tms.app.constant.enums.PickUpHandleTypeEnum;
import com.prolog.rdc.tms.app.constant.enums.RelationThirdSystemEnum;
import com.prolog.rdc.tms.app.dao.mapper.TmsLoadingBillDetailMapper;
import com.prolog.rdc.tms.app.dao.mapper.TmsLoadingBillHeaderMapper;
import com.prolog.rdc.tms.app.dao.mapper.TmsShipbillContainerTempMapper;
import com.prolog.rdc.tms.app.dao.mapper.TmsShipbillDetailMapper;
import com.prolog.rdc.tms.app.dao.mapper.TmsShipbillDetailTempMapper;
import com.prolog.rdc.tms.app.dao.mapper.TmsShipbillHeaderMapper;
import com.prolog.rdc.tms.app.dao.mapper.TmsShipbillHeaderTempMapper;
import com.prolog.rdc.tms.app.dao.mapper.TmsShipbillPackageMapper;
import com.prolog.rdc.tms.app.dao.mapper.TmsShipbillTransportLogMapper;
import com.prolog.rdc.tms.app.model.dto.business.PendingDisPackageDTO;
import com.prolog.rdc.tms.app.model.dto.business.WaitDeliveredItemDTO;
import com.prolog.rdc.tms.app.model.dto.business.WaitPickUpGoodsQueryByShipbillDTO;
import com.prolog.rdc.tms.app.model.entity.TmsLoadingBillDetailModel;
import com.prolog.rdc.tms.app.model.entity.TmsLoadingBillHeaderModel;
import com.prolog.rdc.tms.app.model.entity.TmsShipbillContainerTemp;
import com.prolog.rdc.tms.app.model.entity.TmsShipbillDetailModel;
import com.prolog.rdc.tms.app.model.entity.TmsShipbillDetailTempModel;
import com.prolog.rdc.tms.app.model.entity.TmsShipbillHeaderModel;
import com.prolog.rdc.tms.app.model.entity.TmsShipbillHeaderTempModel;
import com.prolog.rdc.tms.app.model.entity.TmsShipbillPackageModel;
import com.prolog.rdc.tms.app.model.entity.TmsShipbillTransLogModel;
import com.prolog.rdc.tms.app.model.vo.StartShipmentDetailVO;
import com.prolog.rdc.tms.app.model.vo.business.ShipbillNodeTrackingSaveNewVO;
import com.prolog.rdc.tms.app.model.vo.business.ShipbillOperateLogSaveNewVO;
import com.prolog.rdc.tms.app.model.vo.business.WaitDeliveredSignVO;
import com.prolog.rdc.tms.app.model.vo.business.WaitPickUpGoodsQueryByShipbillVO;
import com.prolog.rdc.tms.app.model.vo.business.WaitPickUpGoodsStartShipmentVO;
import com.prolog.rdc.tms.app.proxy.MainDataProxy;
import com.prolog.rdc.tms.app.service.business.LoadingBillService;
import com.prolog.rdc.tms.app.service.business.ShipbillNodeTrackingService;
import com.prolog.rdc.tms.app.service.business.ShipbillOperateLogService;
import com.prolog.rdc.tms.app.service.business.WaitPickUpGoodsService;
import com.prolog.rdc.tms.app.util.AutoSignJudge;
import com.prolog.rdc.tms.app.util.DistanceUtil;
import com.prolog.rdc.tms.app.util.MessageUtil;
import com.prolog.rdc.tms.app.util.StrategyUtil;
import com.prolog.rdc.tms.model.constant.RedisConstant;
import com.prolog.rdc.tms.model.dto.DeviceByOneDTO;
import com.prolog.rdc.tms.model.dto.basicData.ItemCheckDTO;
import com.prolog.rdc.tms.model.dto.message.SendMessageDTO;
import com.prolog.rdc.tms.model.enums.MessageOrderTypeEnum;
import com.prolog.rdc.tms.model.enums.MessageTypeEnum;
import com.prolog.rdc.tms.model.vo.basicConfigure.ApprovalOpenVO;
import com.prolog.rdc.tms.model.vo.basicData.ItemCheckVO;
import com.prolog.rdc.tms.rmi.feign.MaindataFeign;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * 待提货实现层
 *
 * @author xiaoyf
 * @since 2022/6/8 10:45
 */
@Slf4j
@Service
public class WaitPickUpGoodsServiceImpl implements WaitPickUpGoodsService {

	@Autowired
	private TmsLoadingBillDetailMapper tmsLoadingBillDetailMapper;

	@Autowired
	private TmsLoadingBillHeaderMapper tmsLoadingBillHeaderMapper;

	@Autowired
	private TmsShipbillHeaderMapper tmsShipbillHeaderMapper;

	@Autowired
	private ShipbillOperateLogService shipbillOperateLogService;

	@Autowired
	private ShipbillNodeTrackingService shipbillNodeTrackingService;

	@Autowired
	private TmsShipbillTransportLogMapper tmsShipbillTransportLogMapper;

	@Autowired
	private TmsShipbillDetailMapper tmsShipbillDetailMapper;

	@Autowired
	private TmsShipbillPackageMapper tmsShipbillPackageMapper;

	@Autowired
	private MaindataFeign maindataTmsResource;

	@Autowired
	private AutoSignJudge autoSignJudge;

	@Autowired
	private MainDataProxy mainDataProxy;

	@Autowired
	private TmsShipbillHeaderTempMapper tmsShipbillHeaderTempMapper;

	@Autowired
	private TmsShipbillDetailTempMapper tmsShipbillDetailTempMapper;

	@Autowired
	private StrategyUtil strategyUtil;

	@Autowired
	private RedisTemplate redisTemplate;

	@Autowired
	private LoadingBillService loadingBillService;

	@Autowired
	private TmsShipbillContainerTempMapper shipbillContainerTempMapper;

	/**
	 * 运单分页查询
	 *
	 * @param
	 * @return
	 */
	@SuppressWarnings("resource")
	@Override
	public Page<WaitPickUpGoodsQueryByShipbillDTO> queryShipbill(WaitPickUpGoodsQueryByShipbillVO vo) {
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");

		if (ObjectUtil.notEqual(user.getUserType(), BussinessConstant.USER_TYPE_ZY) && ObjectUtil.notEqual(user.getUserType(), BussinessConstant.USER_TYPE_CYS)) {
			ToolKits.isParamNull(user, "当前人员没有操作权限");
		}

		vo.setEnterpriseId(user.getEnterpriseId());
		vo.setUserType(user.getUserType());
		// 自有账号
		if (ObjectUtil.equal(user.getUserType(), BussinessConstant.USER_TYPE_ZY)) {
			vo.setDepts(user.getDepts().stream().toArray(String[]::new));
			// 部门权限
			if (BussinessConstant.USER_DEPARTMENT_AUTH_Y.equals(user.getOwnedAllDataAuthFlag())) {
				vo.setIsDept(StatusConstant.IS_DEPT_YES);
			}
			// 业务员权限
			else {
				vo.setIsDept(StatusConstant.IS_DEPT_NO);
				vo.setCustomers(user.getCustomers().stream().toArray(Long[]::new));
				vo.setSuppliers(user.getSuppliers().stream().toArray(Long[]::new));
				vo.setWsarehouses(user.getWarehouses().stream().toArray(Long[]::new));
				vo.setConsignors(user.getConsignors().stream().toArray(Long[]::new));
			}
		}
		if (ObjectUtil.equal(user.getUserType(), BussinessConstant.USER_TYPE_CYS)) {
			vo.setCarrierId(Long.valueOf(user.getLoginUserCompanyInfo().getId()));
		}

		PageUtils.startPage(vo.getPageNum(), vo.getPageSize());
		List<TmsLoadingBillDetailModel> list = tmsLoadingBillDetailMapper.queryWaitPickUpGoods(vo);

		List<WaitPickUpGoodsQueryByShipbillDTO> dtos = Lists.newArrayList();
		for (TmsLoadingBillDetailModel model : list) {
			WaitPickUpGoodsQueryByShipbillDTO dto = new WaitPickUpGoodsQueryByShipbillDTO();
			BeanUtils.copyProperties(model, dto);
			dto.setShipperPickUpSign(ToolKits.isEmpty(model.getShipperPickUpSign()) ? 0 : model.getShipperPickUpSign());
			TmsLoadingBillHeaderModel tmsLoadingBillHeaderModel = tmsLoadingBillHeaderMapper.findById(model.getLoadingBillId(), TmsLoadingBillHeaderModel.class);
			if (ObjectUtil.isNotNull(tmsLoadingBillHeaderModel)) {
				dto.setVehiclePlateNumber(tmsLoadingBillHeaderModel.getVehiclePlateNumber());
			}
			if (ObjectUtil.equal(model.getShipperType(), DataDictionaryConstant.SHIPPER_TYPE_KH) || ObjectUtil.equal(model.getShipperType(), DataDictionaryConstant.SHIPPER_TYPE_GYS)) {
				dto.setShipperName(model.getShipperUnitName() + "/" + model.getShipperName());
			}

			if (ObjectUtil.equal(model.getShipperType(), DataDictionaryConstant.CONSIGNEE_TYPE_KH) || ObjectUtil.equal(model.getShipperType(), DataDictionaryConstant.CONSIGNEE_TYPE_GYS)) {
				dto.setConsigneeName(model.getConsigneeUnitName() + "/" + model.getConsigneeName());
			}

			// 电话/手机号
			StringBuffer tel = new StringBuffer();
			// STD-DEVELOP20220823 lhb 20220823 小程序电话显示修改的需求新增 start
			if (ToolKits.isNotEmpty(model.getConsigneePhoneNumber())) {
				tel.append(model.getConsigneePhoneNumber());
			} else if (ToolKits.isNotEmpty(model.getConsigneeLandlineNumber())) {
				tel.append(model.getConsigneeLandlineNumber());
			}
			// STD-DEVELOP20220823 lhb 20220823 小程序电话显示修改的需求新增 end
			if (ToolKits.isNotEmpty(tel.toString())) {
				dto.setContact(tel.toString());
			}

			// STD-DEVELOP20220823 lhb 自动签到 20220907 start
			// 判断是否 自动提货签到
			if (ToolKits.isNotEmpty(vo.getDriverLongitude()) && ToolKits.isNotEmpty(vo.getDriverLatitude())) {
				if (ToolKits.isNotEmpty(model.getShipperPickUpRail()) && model.getShipperPickUpRail().doubleValue() > 0 && model.getStatus().intValue() == DataDictionaryConstant.SHIPBILL_STATUS_QY.intValue() && ToolKits.isNotEmpty(model.getShipperLongitude()) && ToolKits.isNotEmpty(model.getShipperLatitude()) && ToolKits.isNotEmpty(model.getShipperPickUpSign()) && ToolKits.isNotEmpty(model.getShipperAutoPickUpSign()) && model.getShipperPickUpSign().intValue() > 0 && model.getShipperAutoPickUpSign().intValue() > 0) {
					// 司机和仓库之间的距离
					double pos = DistanceUtil.getDistance(vo.getDriverLongitude().doubleValue(), vo.getDriverLatitude().doubleValue(), model.getShipperLongitude().doubleValue(), model.getShipperLatitude().doubleValue());
					if (Double.compare(pos, model.getShipperPickUpRail().doubleValue()) <= 0 && autoSignJudge.autoSignJudge(model.getShipbillId(),"1")) {
						// 调用自动签到
						WaitDeliveredSignVO signVo = new WaitDeliveredSignVO();
						signVo.setShipbillId(model.getShipbillId());
						signVo.setId(model.getId());
						try {
							sign(signVo);
						} catch (Exception e) {
							throw new PrologException("运单【" + model.getShipbillId() + "】待提货自动签到失败.");
						}
						dto.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_THQD);
					}
				}
			}
			// 获取包裹信息
			Criteria criteriaPkg = Criteria.forClass(TmsShipbillPackageModel.class);
			Restriction r27 = Restrictions.eq(TmsShipbillPackageModel::getShipbillId, dto.getShipbillId());
			Restriction r28 = Restrictions.eq(TmsShipbillPackageModel::getEnterpriseId, user.getEnterpriseId());
			criteriaPkg.setRestriction(Restrictions.and(r27, r28));
			criteriaPkg.setOrder(Order.newInstance().desc(new String[] { "updatetime" }));

			List<TmsShipbillPackageModel> tmsShipbillPackageModels = tmsShipbillPackageMapper.findByCriteria(criteriaPkg);

			List<PendingDisPackageDTO> loadingPackageDTOList = Lists.newArrayList();
			for (TmsShipbillPackageModel packageModel : tmsShipbillPackageModels) {
				PendingDisPackageDTO packageDTO = new PendingDisPackageDTO();
				BeanUtils.copyProperties(packageModel, packageDTO);
				loadingPackageDTOList.add(packageDTO);
			}
			dto.setPackageDetail(loadingPackageDTOList);

			if (loadingPackageDTOList.size() == 0) {
				// 获取商品信息
				Criteria criteriaDetail = Criteria.forClass(TmsShipbillDetailModel.class);
				criteriaDetail.setRestriction(Restrictions.and(r27, r28));
				criteriaDetail.setOrder(Order.newInstance().desc(new String[] { "updatetime" }));
				List<TmsShipbillDetailModel> tmsShipbillDetailModels = tmsShipbillDetailMapper.findByCriteria(criteriaDetail);

				List<WaitDeliveredItemDTO> detailDTOList = Lists.newArrayList();
				for (TmsShipbillDetailModel detailModel : tmsShipbillDetailModels) {
					WaitDeliveredItemDTO detailDTO = new WaitDeliveredItemDTO();
					BeanUtils.copyProperties(detailModel, detailDTO);
					// STD-BUG20220823 xiaoyf 29729字段显示修复 start
					detailDTO.setQty(ToolKits.isEmpty(detailModel.getPcs()) ? 0 : detailModel.getPcs().intValue());
					// STD-BUG20220823 xiaoyf 29729字段显示修复 end
					detailDTO.setScratchArea(ToolKits.isEmpty(detailModel.getStagingLocation()) ? "" : detailModel.getStagingLocation());
					detailDTOList.add(detailDTO);
				}
				// 商品信息
				dto.setItemDetail(detailDTOList);
			}
			// STD-DEVELOP20220823 lhb 自动签到 20220907 end
			dtos.add(dto);
		}

		Page<WaitPickUpGoodsQueryByShipbillDTO> page = PageUtils.getPage(dtos);
		if (list instanceof com.github.pagehelper.Page) {
			com.github.pagehelper.Page<TmsLoadingBillDetailModel> p0 = (com.github.pagehelper.Page<TmsLoadingBillDetailModel>) list;
			page.setPageCount(p0.getPages());
			page.setPageNum(p0.getPageNum());
			page.setPageSize(p0.getPageSize());
			page.setTotalCount(p0.getTotal());
			page.setStartRow(p0.getStartRow());
			page.setEndRow(p0.getEndRow());
		}
		return page;
	}

	/**
	 * 签到
	 *
	 * @param
	 * @return
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void sign(WaitDeliveredSignVO vo) throws Exception {
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");

		Date date = DateUtil.date();

		TmsLoadingBillDetailModel tmsLoadingBillDetailModel = tmsLoadingBillDetailMapper.findById(vo.getId(), TmsLoadingBillDetailModel.class);

		if (ToolKits.isNotEmpty(tmsLoadingBillDetailModel)) {
			// 原状态
			Integer oldStatus = tmsLoadingBillDetailModel.getStatus();

			tmsLoadingBillDetailModel.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_THQD);
			tmsLoadingBillDetailModel.setUpdateperson(user.getNickname());
			tmsLoadingBillDetailModel.setUpdatetime(DateUtil.date());
			tmsLoadingBillDetailMapper.update(tmsLoadingBillDetailModel);

			ShipbillOperateLogSaveNewVO shipbillOperateLogSaveNewVO = new ShipbillOperateLogSaveNewVO();
			shipbillOperateLogSaveNewVO.setShipbillId(tmsLoadingBillDetailModel.getShipbillId());
			shipbillOperateLogSaveNewVO.setShipbillNo(tmsLoadingBillDetailModel.getShipbillId());
			shipbillOperateLogSaveNewVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_STATUSNAME_QYQD);
			shipbillOperateLogSaveNewVO.setOldStatus(oldStatus);
			shipbillOperateLogSaveNewVO.setNewStatus(DataDictionaryConstant.SHIPBILL_STATUS_QY);
			shipbillOperateLogSaveNewVO.setOperateDate(DateUtil.date());
			shipbillOperateLogSaveNewVO.setEnterpriseId(user.getEnterpriseId());
			shipbillOperateLogSaveNewVO.setEnterpriseName(user.getEnterpriseName());
			shipbillOperateLogSaveNewVO.setUserId(user.getUserid());
			shipbillOperateLogSaveNewVO.setUserName(user.getNickname());
			shipbillOperateLogService.addShipbillOperateLogNewData(shipbillOperateLogSaveNewVO);

			Map<String, Object> mapUpdate = Maps.newHashMap();
			mapUpdate.put("departureSignTime", date);
			mapUpdate.put("updateperson", user.getNickname());
			mapUpdate.put("updatetime", date);

			// 更新运输记录表
			Criteria criteriaTransportLog = Criteria.forClass(TmsShipbillTransLogModel.class);
			Restriction r4 = Restrictions.eq(TmsShipbillTransLogModel::getEnterpriseId, tmsLoadingBillDetailModel.getEnterpriseId());
			Restriction r5 = Restrictions.eq(TmsShipbillTransLogModel::getShipbillId, tmsLoadingBillDetailModel.getShipbillId());
			criteriaTransportLog.setRestriction(Restrictions.and(r4, r5));
			tmsShipbillTransportLogMapper.updateMapByCriteria(mapUpdate, criteriaTransportLog);
		} else {
			throw new ParameterException("装车单ID【" + vo.getId() + "】不存在");
		}
	}

	/**
	 * 启运登记
	 *
	 * @param
	 */
	@SuppressWarnings("unchecked")
	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean startShipmentData(WaitPickUpGoodsStartShipmentVO vo) {
		ToolKits.isParamNull(vo.getShipbillId(), "运单ID不能为空");
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前人员没有操作权限");
		if (!user.getUserType().equals(BussinessConstant.USER_TYPE_ZY) && !user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
			ToolKits.isParamNull(user, "当前人员没有操作权限");
		}

		// 当前时间
		Date date = DateUtils.nowDate();
		StringBuffer nodeEvent = new StringBuffer();
		nodeEvent.append("启运登记");
		TmsShipbillHeaderModel tmsShipbillHeaderModel = tmsShipbillHeaderMapper.findById(vo.getShipbillId(), TmsShipbillHeaderModel.class);
		String relationThirdSystem = mainDataProxy.getSystemParamByCode(RelationThirdSystemEnum.ENUM_NAME);
		if (!DataDictionaryConstant.TEMPERATURE_REQUIREMENT_CW.equals(tmsShipbillHeaderModel.getTemperatureRequirement())) {
//			if (Boolean.TRUE.equals(vo.getShowDepartureTemperature()) && ObjectUtil.isNull(vo.getDepartureTemperature())) {
//				throw new BizException("启运温度不能为空");
//			}
			if (!DataDictionaryConstant.VEHICLE_TYPE_CATEGORY_LC.equals(tmsShipbillHeaderModel.getVehicleTypeCategory())) {
				if (relationThirdSystem.contains(RelationThirdSystemEnum.GPS.getCode())) {
					if (StrUtil.isBlank(vo.getVehicleDeviceId())) {
						throw new BizException("运单" + tmsShipbillHeaderModel.getShipbillId() + "未绑定设备，请先输入设备号");
					}
				}
				if(relationThirdSystem.contains(RelationThirdSystemEnum.TEMPERATURE.getCode()) || relationThirdSystem.contains(RelationThirdSystemEnum.CONTAINER.getCode())){
					if (StrUtil.isBlank(vo.getContainerId())) {
						throw new BizException("运单" + tmsShipbillHeaderModel.getShipbillId() + "未绑定保温箱，请先选择容器号");
					}
				}
			}
		}
		String pickUpCheckDtlSystem = mainDataProxy.getSystemParamByCode(DataDictionaryConstant.PICK_UP_CHECK_DETAIL_SWITCH);
		if (DataDictionaryConstant.WHETHER_YES.toString().equals(pickUpCheckDtlSystem)
				&& ToolKits.isEmpty(vo.getCheckDetails())) {
			throw new BizException("启运登记检查清单不为空");
		}
		// STD-DEVELOP20220823 lhb 自动签到 20220907 start
		if (ToolKits.isNotEmpty(tmsShipbillHeaderModel.getShipperPickUpPicture()) && tmsShipbillHeaderModel.getShipperPickUpPicture().equals(DataDictionaryConstant.WHETHER_YES) && ToolKits.isEmpty(vo.getDeparturePhoto())) {
			throw new PrologException("货物图片不能为空");
		}
		// STD-DEVELOP20220823 lhb 自动签到 20220907 end

		if (Boolean.TRUE.equals(vo.getShowContainerTemperature())) {
			if (CollectionUtil.isEmpty(vo.getTemperatureVOList())) {
				throw new BizException("容器温度集合不存在");
			}
			vo.getTemperatureVOList().forEach(temperatureVO -> {
				if (ObjectUtil.isNull(temperatureVO.getTemperature())) {
					throw new BizException("容器" + temperatureVO.getName() + "温度为空");
				}
			});
			Criteria criteria = Criteria.forClass(TmsShipbillContainerTemp.class);
			Restriction r1 = Restrictions.eq(TmsShipbillContainerTemp::getEnterpriseId, user.getEnterpriseId());
			Restriction r2 = Restrictions.eq(TmsShipbillContainerTemp::getShipbillId, tmsShipbillHeaderModel.getShipbillId());
			criteria.setRestriction(Restrictions.and(r1, r2));
			shipbillContainerTempMapper.deleteByCriteria(criteria);
			vo.getTemperatureVOList().forEach(temperatureVO -> {
				TmsShipbillContainerTemp temp = new TmsShipbillContainerTemp();
				temp.setId(mainDataProxy.getCodeNumberByCode(SeriaNnumberConstant.TMS_SHIPBILL_CONTAINER_TEMP_ID));
				temp.setShipbillId(tmsShipbillHeaderModel.getShipbillId());
				temp.setContainerId(temperatureVO.getId());
				temp.setContainerCode(temperatureVO.getCode());
				temp.setContainerName(temperatureVO.getName());
				temp.setDepartureTemp(temperatureVO.getTemperature());
				temp.setDepartureTempTime(DateUtil.date());
				temp.setCreatetime(DateUtil.date());
				temp.setCreateperson(user.getNickname());
				temp.setUpdatetime(DateUtil.date());
				temp.setUpdateperson(user.getNickname());
				temp.setEnterpriseId(user.getEnterpriseId());
				temp.setEnterpriseName(user.getEnterpriseName());
				shipbillContainerTempMapper.save(temp);
			});
		}


		List<StartShipmentDetailVO> detailVOList = vo.getDetailVOList();
		Map<String, StartShipmentDetailVO> detailVOMap = detailVOList.stream().collect(
				Collectors.toMap(t1 -> t1.getId(), t2 -> t2, (t1, t2) -> t2));

		String pickupHandleType = mainDataProxy.getSystemParamByCode(PickUpHandleTypeEnum.ENUM_NAME);
		if (PickUpHandleTypeEnum.SHOW.getCode().equals(pickupHandleType) && CollectionUtil.isNotEmpty(vo.getDetailVOList())) {
			if (detailVOList.stream().anyMatch(detailVO -> NumberUtil.isGreater(detailVO.getQty(), detailVO.getPickUpPcs()))) {
				TmsShipbillHeaderTempModel tempModel = BeanUtil.copyProperties(tmsShipbillHeaderModel, TmsShipbillHeaderTempModel.class);
				tempModel.setVehicleDeviceId(vo.getVehicleDeviceId());
				tempModel.setVehicleDeviceCode(vo.getVehicleDeviceCode());
				tempModel.setVehicleDeviceName(vo.getVehicleDeviceName());
				tempModel.setContainerId(vo.getContainerId());
				tempModel.setContainerCode(vo.getContainerCode());
				tempModel.setContainerName(vo.getContainerName());
				tempModel.setDepartureTemperature(vo.getDepartureTemperature());
				tempModel.setDepartureTime(date);
				tempModel.setMemo(vo.getDeparturePhoto());
				tmsShipbillHeaderTempMapper.save(tempModel);
				tmsShipbillHeaderModel.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_QYSH);
				tmsShipbillHeaderModel.setUpdateperson(user.getNickname());
				tmsShipbillHeaderModel.setUpdatetime(date);
				tmsShipbillHeaderMapper.update(tmsShipbillHeaderModel);

				Criteria criteria = Criteria.forClass(TmsLoadingBillDetailModel.class);
				Restriction r1 = Restrictions.eq("shipbillId", tmsShipbillHeaderModel.getShipbillId());
				Restriction r2 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
				criteria.setRestriction(Restrictions.and(r1, r2));
				criteria.setOrder(Order.newInstance().desc(TmsLoadingBillDetailModel::getCreatetime));
				List<TmsLoadingBillDetailModel> loadingBillDetailModels = tmsLoadingBillDetailMapper.findByCriteria(criteria);
				ToolKits.isParamNull(loadingBillDetailModels, "未找到对应的调度单明细");
				TmsLoadingBillDetailModel loadingBillDetailModel = loadingBillDetailModels.get(0);
				loadingBillDetailModel.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_QYSH);
				loadingBillDetailModel.setUpdateperson(user.getNickname());
				loadingBillDetailModel.setUpdatetime(date);
				tmsLoadingBillDetailMapper.update(loadingBillDetailModel);

				// 声明节点实体
				ShipbillNodeTrackingSaveNewVO shipbillNodeTrackingSaveNewVO = new ShipbillNodeTrackingSaveNewVO();
				// 声明日志实体
				ShipbillOperateLogSaveNewVO shipbillOperateLogSaveNewVO = new ShipbillOperateLogSaveNewVO();
				// 节点保存
				shipbillNodeTrackingSaveNewVO.setNodeEvent(DataDictionaryConstant.SHIPBILL_STATUSNAME_QYSH);
				shipbillNodeTrackingSaveNewVO.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_QYSH);
				shipbillNodeTrackingSaveNewVO.setShipbillId(tmsShipbillHeaderModel.getShipbillId());
				shipbillNodeTrackingSaveNewVO.setShipbillNo(tmsShipbillHeaderModel.getShipbillNo());
				shipbillNodeTrackingSaveNewVO.setNodeDate(date);
				shipbillNodeTrackingSaveNewVO.setUserId(user.getUserid());
				shipbillNodeTrackingSaveNewVO.setUserName(user.getNickname());
				shipbillNodeTrackingSaveNewVO.setEnterpriseId(user.getEnterpriseId());
				shipbillNodeTrackingSaveNewVO.setEnterpriseName(user.getEnterpriseName());
				shipbillNodeTrackingService.addShipbillNodeTrackingNewData(shipbillNodeTrackingSaveNewVO);

				shipbillOperateLogSaveNewVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_STATUSNAME_QYSH);
				shipbillOperateLogSaveNewVO.setOldStatus(tmsShipbillHeaderModel.getStatus());
				shipbillOperateLogSaveNewVO.setNewStatus(DataDictionaryConstant.SHIPBILL_STATUS_QYSH);
				shipbillOperateLogSaveNewVO.setShipbillId(tmsShipbillHeaderModel.getShipbillId());
				shipbillOperateLogSaveNewVO.setShipbillNo(tmsShipbillHeaderModel.getShipbillNo());
				shipbillOperateLogSaveNewVO.setUserId(user.getUserid());
				shipbillOperateLogSaveNewVO.setUserName(user.getNickname());
				shipbillOperateLogSaveNewVO.setEnterpriseId(user.getEnterpriseId());
				shipbillOperateLogSaveNewVO.setEnterpriseName(user.getEnterpriseName());
				shipbillOperateLogSaveNewVO.setOperateDate(date);
				shipbillOperateLogService.addShipbillOperateLogNewData(shipbillOperateLogSaveNewVO);
				List<TmsShipbillDetailModel> tmsShipbillDetailModelList = tmsShipbillDetailMapper.findByIds(TmsShipbillDetailModel.class,
						detailVOList.stream().map(StartShipmentDetailVO::getId).toArray(), null);
				tmsShipbillDetailModelList.forEach(detailModel -> {
					TmsShipbillDetailTempModel tempModel2 = BeanUtil.copyProperties(detailModel, TmsShipbillDetailTempModel.class);
					StartShipmentDetailVO detailVO = detailVOMap.get(detailModel.getId());
					if (ObjectUtil.isNotNull(detailVO)) {
						tempModel2.setPickUpPcs(detailVO.getPickUpPcs());
					}
					tmsShipbillDetailTempMapper.save(tempModel2);
				});

				// 封装判断所需数据
				ApprovalOpenVO approvalOpenVO = new ApprovalOpenVO();
				approvalOpenVO.setApprovalFlowType(DataDictionaryConstant.APPROVAL_FLOW_TYPE_START_SHIP);
				approvalOpenVO.setApprovalObjectId(tmsShipbillHeaderModel.getShipbillId());
				approvalOpenVO.setApprovalObjectCode(tmsShipbillHeaderModel.getShipbillId());
				approvalOpenVO.setApprovalObjectName(tmsShipbillHeaderModel.getShipbillId());
				approvalOpenVO.setInitiatedUserId(user.getUserid());
				approvalOpenVO.setInitiatedUserName(user.getNickname());
				approvalOpenVO.setDeliveryMethodType(tmsShipbillHeaderModel.getDeliveryMethodType());
				approvalOpenVO.setShipperType(tmsShipbillHeaderModel.getShipperType());
				approvalOpenVO.setShipperUnitId(tmsShipbillHeaderModel.getShipperUnitId());
				approvalOpenVO.setConsigneeType(tmsShipbillHeaderModel.getConsigneeType());
				approvalOpenVO.setConsigneeUnitId(tmsShipbillHeaderModel.getConsigneeUnitId());
				approvalOpenVO.setOrderType(tmsShipbillHeaderModel.getOrderType());
				approvalOpenVO.setOrderBusinessType(tmsShipbillHeaderModel.getOrderBusinessType());
				approvalOpenVO.setTransportType(tmsShipbillHeaderModel.getTransportType());
				approvalOpenVO.setTemperatureRequirement(tmsShipbillHeaderModel.getTemperatureRequirement());
				approvalOpenVO.setCargoOwnerId(tmsShipbillHeaderModel.getCargoOwnerId());
				approvalOpenVO.setDepartmentId(tmsShipbillHeaderModel.getDepartmentId());
				RestMessage<Boolean> restMessage1 = maindataTmsResource.openExecute(approvalOpenVO);
				if (!restMessage1.isSuccess()) {
					throw new BizException("调用maindata服务是否开启审批流接口失败:" + restMessage1.getMessage());
				}
				if (restMessage1.getData()) {
					return Boolean.TRUE;
				}
			}
		}


		Criteria criteriaTransport = Criteria.forClass(TmsShipbillTransLogModel.class);
		Map<String, Object> mapTransportLogUpdate = Maps.newHashMap();
		mapTransportLogUpdate.put("updateperson", user.getNickname());
		mapTransportLogUpdate.put("updatetime", date);
		mapTransportLogUpdate.put("departureTime", date);

		// STD-BUG20220823 lhb 启运登记修改运单明细发货件数 20220920 start
		// 修改运单明细的商品信息
		Criteria criteriaShipbillDetail = Criteria.forClass(TmsShipbillDetailModel.class);
		Restriction r11 = Restrictions.eq(TmsShipbillDetailModel::getShipbillId, tmsShipbillHeaderModel.getShipbillId());
		Restriction r12 = Restrictions.eq(TmsShipbillDetailModel::getEnterpriseId, user.getEnterpriseId());
		Restriction r13 = Restrictions.ge(TmsShipbillDetailModel::getPcs, BigDecimal.ZERO);
		criteriaShipbillDetail.setRestriction(Restrictions.and(r11, r12, r13));
		List<TmsShipbillDetailModel> shipbillDetailModels = tmsShipbillDetailMapper.findByCriteria(criteriaShipbillDetail);
		BigDecimal totalDeliveryPcs = new BigDecimal(0);
		BigDecimal totalDeliveryVolume = new BigDecimal(0);
		BigDecimal totalDeliveryWeight = new BigDecimal(0);

		if (ToolKits.isNotEmpty(shipbillDetailModels)) {
			for (TmsShipbillDetailModel shipbillDetailModel : shipbillDetailModels) {
				ItemCheckVO itemCheckVO = new ItemCheckVO();
				itemCheckVO.setItemId(shipbillDetailModel.getItemId());
				RestMessage<ItemCheckDTO> restMessage3 = maindataTmsResource.getItem(itemCheckVO);
				if (!restMessage3.isSuccess()) {
					throw new RuntimeException("取商品资料信息失败:" + restMessage3.getMessage());
				}
				ItemCheckDTO rsItemInfo = restMessage3.getData();
				StartShipmentDetailVO detailVO = detailVOMap.get(shipbillDetailModel.getId());
				if (ObjectUtil.isNotNull(detailVO)) {
					shipbillDetailModel.setDeliveryPcs(detailVO.getPickUpPcs());
					shipbillDetailModel.setPcs(NumberUtil.sub(shipbillDetailModel.getPcs(), detailVO.getPickUpPcs()));
					shipbillDetailModel.setPickUpPcs(detailVO.getPickUpPcs());
					shipbillDetailModel.setVolume(NumberUtil.mul(shipbillDetailModel.getPcs(), rsItemInfo.getVolume()));
					shipbillDetailModel.setWeight(NumberUtil.mul(shipbillDetailModel.getPcs(), rsItemInfo.getWeight()));
				} else {
					shipbillDetailModel.setDeliveryPcs(shipbillDetailModel.getPcs());
					shipbillDetailModel.setPickUpPcs(shipbillDetailModel.getPcs());
					shipbillDetailModel.setPcs(BigDecimal.ZERO);
					shipbillDetailModel.setVolume(BigDecimal.ZERO);
					shipbillDetailModel.setWeight(BigDecimal.ZERO);
				}
				tmsShipbillDetailMapper.update(shipbillDetailModel);
				BigDecimal fatherDeliveryPcs = new BigDecimal(0);

				fatherDeliveryPcs = fatherDeliveryPcs.add(shipbillDetailModel.getDeliveryPcs());

				totalDeliveryPcs = totalDeliveryPcs.add(shipbillDetailModel.getDeliveryPcs());
				totalDeliveryVolume = totalDeliveryVolume.add(shipbillDetailModel.getDeliveryPcs().multiply(rsItemInfo.getVolume()));
				totalDeliveryWeight = totalDeliveryWeight.add(shipbillDetailModel.getDeliveryPcs().multiply(rsItemInfo.getWeight()));

				// 拆分主单对应的运单明细
				String fatherShipbillIdForDetail = tmsShipbillHeaderModel.getShipbillId();
				while (ToolKits.isNotEmpty(fatherShipbillIdForDetail)) {
					fatherShipbillIdForDetail = updateFatherShipbillDetail(fatherShipbillIdForDetail, shipbillDetailModel, fatherDeliveryPcs, date, user, rsItemInfo);
				}
			}
		}
		// STD-BUG20220823 lhb 启运登记修改运单明细发货件数 20220920 end

		// 修改运单
		tmsShipbillHeaderModel.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_SD);
		tmsShipbillHeaderModel.setUpdateperson(user.getNickname());
		tmsShipbillHeaderModel.setUpdatetime(date);
		tmsShipbillHeaderModel.setTransportStatus(DataDictionaryConstant.TRANSPORT_STATUS_SHIPPING);

		tmsShipbillHeaderModel.setTotalDeliveryPcs(totalDeliveryPcs);
		tmsShipbillHeaderModel.setTotalDeliveryWeight(totalDeliveryWeight);
		tmsShipbillHeaderModel.setTotalDeliveryVolume(totalDeliveryVolume);

		tmsShipbillHeaderModel.setTotalPcs(tmsShipbillHeaderModel.getTotalPcs().subtract(totalDeliveryPcs));
		tmsShipbillHeaderModel.setTotalVolume(tmsShipbillHeaderModel.getTotalVolume().subtract(totalDeliveryVolume));
		tmsShipbillHeaderModel.setTotalWeight(tmsShipbillHeaderModel.getTotalWeight().subtract(totalDeliveryWeight));
		tmsShipbillHeaderModel.setActualTotalPcs(tmsShipbillHeaderModel.getTotalPcs());
		tmsShipbillHeaderModel.setActualTotalVolume(tmsShipbillHeaderModel.getTotalVolume());
		tmsShipbillHeaderModel.setActualTotalWeight(tmsShipbillHeaderModel.getTotalWeight());
		tmsShipbillHeaderModel.setDepartureTime(date);
		tmsShipbillHeaderModel.setVehicleDeviceId(vo.getVehicleDeviceId());
		tmsShipbillHeaderModel.setVehicleDeviceCode(vo.getVehicleDeviceCode());
		tmsShipbillHeaderModel.setVehicleDeviceName(vo.getVehicleDeviceName());
		tmsShipbillHeaderModel.setDepartureTemperature(vo.getDepartureTemperature());
		tmsShipbillHeaderModel.setContainerId(vo.getContainerId());
		tmsShipbillHeaderModel.setContainerCode(vo.getContainerCode());
		tmsShipbillHeaderModel.setContainerName(vo.getContainerName());
		tmsShipbillHeaderMapper.update(tmsShipbillHeaderModel);

		// 同步修改运单对应的装车单明细状态
		Criteria criteriaLoadingBillDetail = Criteria.forClass(TmsLoadingBillDetailModel.class);
		Restriction r1 = Restrictions.eq("shipbillId", tmsShipbillHeaderModel.getShipbillId());
		Restriction r2 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
		criteriaLoadingBillDetail.setRestriction(Restrictions.and(r1, r2));
		criteriaLoadingBillDetail.setOrder(Order.newInstance().desc(TmsLoadingBillDetailModel::getCreatetime));
		List<TmsLoadingBillDetailModel> tmsLoadingBillDetailModels = tmsLoadingBillDetailMapper.findByCriteria(criteriaLoadingBillDetail);
		ToolKits.isParamNull(tmsLoadingBillDetailModels, "未找到对应的调度单明细");
		TmsLoadingBillDetailModel loadingBillDetailModel = tmsLoadingBillDetailModels.get(0);

		loadingBillDetailModel.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_SD);
		loadingBillDetailModel.setUpdateperson(user.getNickname());
		loadingBillDetailModel.setUpdatetime(date);
		loadingBillDetailModel.setTransportStatus(DataDictionaryConstant.TRANSPORT_STATUS_SHIPPING);

		loadingBillDetailModel.setTotalDeliveryPcs(totalDeliveryPcs);
		loadingBillDetailModel.setTotalDeliveryWeight(totalDeliveryWeight);
		loadingBillDetailModel.setTotalDeliveryVolume(totalDeliveryVolume);

		loadingBillDetailModel.setTotalPcs(loadingBillDetailModel.getTotalPcs().subtract(totalDeliveryPcs));
		loadingBillDetailModel.setTotalVolume(loadingBillDetailModel.getTotalVolume().subtract(totalDeliveryVolume));
		loadingBillDetailModel.setTotalWeight(loadingBillDetailModel.getTotalWeight().subtract(totalDeliveryWeight));
		loadingBillDetailModel.setActualTotalPcs(loadingBillDetailModel.getTotalPcs());
		loadingBillDetailModel.setActualTotalVolume(loadingBillDetailModel.getTotalVolume());
		loadingBillDetailModel.setActualTotalWeight(loadingBillDetailModel.getTotalWeight());
		loadingBillDetailModel.setVehicleDeviceId(vo.getVehicleDeviceId());
		loadingBillDetailModel.setVehicleDeviceCode(vo.getVehicleDeviceCode());
		loadingBillDetailModel.setVehicleDeviceName(vo.getVehicleDeviceName());
		loadingBillDetailModel.setDepartureTime(date);
		loadingBillDetailModel.setDepartureTemperature(vo.getDepartureTemperature());
		loadingBillDetailModel.setContainerId(vo.getContainerId());
		loadingBillDetailModel.setContainerCode(vo.getContainerCode());
		loadingBillDetailModel.setContainerName(vo.getContainerName());
		tmsLoadingBillDetailMapper.update(loadingBillDetailModel);

		Restriction eq = Restrictions.eq("shipbillId", tmsShipbillHeaderModel.getShipbillId());
		criteriaTransport.setRestriction(eq);
		// 更新订单运输记录表
		tmsShipbillTransportLogMapper.updateMapByCriteria(mapTransportLogUpdate, criteriaTransport);

		// 签到时间是否为空
		boolean departureSignTime = false;
		ShipbillNodeTrackingSaveNewVO shipbillNodeTrackingSaveNewVO = new ShipbillNodeTrackingSaveNewVO();
		ShipbillOperateLogSaveNewVO shipbillOperateLogSaveNewVO = new ShipbillOperateLogSaveNewVO();
		String memo = StrUtil.EMPTY;
		if (CollectionUtil.isNotEmpty(vo.getDetailVOList())) {
			memo = vo.getDetailVOList().stream().map(detailVO ->
					detailVO.getItemName() + ",计划提货件数:" + NumberUtil.null2Zero(detailVO.getPlanDeliveryPcs()).stripTrailingZeros().toPlainString() + "件,实际提货件数:" + detailVO.getPickUpPcs().stripTrailingZeros().toPlainString() + "件").collect(Collectors.joining(" "));
		}
		// 运单节点保存
		shipbillNodeTrackingSaveNewVO.setNodeDate(date);
		shipbillNodeTrackingSaveNewVO.setShipbillId(tmsShipbillHeaderModel.getShipbillId());
		shipbillNodeTrackingSaveNewVO.setShipbillNo(tmsShipbillHeaderModel.getShipbillId());
		shipbillNodeTrackingSaveNewVO.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_SD);
		shipbillNodeTrackingSaveNewVO.setNodeEvent(nodeEvent.toString() + " " + memo + " " + vo.getCheckDetails());
		shipbillNodeTrackingSaveNewVO.setUserId(user.getUserid());
		shipbillNodeTrackingSaveNewVO.setUserName(user.getNickname());
		shipbillNodeTrackingSaveNewVO.setEnterpriseId(user.getEnterpriseId());
		shipbillNodeTrackingSaveNewVO.setEnterpriseName(user.getEnterpriseName());
		shipbillNodeTrackingSaveNewVO.setPicUrl(vo.getDeparturePhoto());
		shipbillNodeTrackingService.addShipbillNodeTrackingNewData(shipbillNodeTrackingSaveNewVO);

		// 运单日志保存
		shipbillOperateLogSaveNewVO.setShipbillId(tmsShipbillHeaderModel.getShipbillId());
		shipbillOperateLogSaveNewVO.setShipbillNo(tmsShipbillHeaderModel.getShipbillId());
		shipbillOperateLogSaveNewVO.setOperateEvent(nodeEvent.toString() + " " + memo+ " " + vo.getCheckDetails());
		shipbillOperateLogSaveNewVO.setOldStatus(DataDictionaryConstant.SHIPBILL_STATUS_ZX_CONFIRM);
		shipbillOperateLogSaveNewVO.setNewStatus(DataDictionaryConstant.SHIPBILL_STATUS_SD);
		shipbillOperateLogSaveNewVO.setOperateDate(date);
		shipbillOperateLogSaveNewVO.setEnterpriseId(user.getEnterpriseId());
		shipbillOperateLogSaveNewVO.setEnterpriseName(user.getEnterpriseName());
		shipbillOperateLogSaveNewVO.setUserId(user.getUserid());
		shipbillOperateLogSaveNewVO.setUserName(user.getNickname());
		shipbillOperateLogService.addShipbillOperateLogNewData(shipbillOperateLogSaveNewVO);

		departureSignTime = true;

		// 父运单的同步启运
		String fatherShipbillId = tmsShipbillHeaderModel.getShipbillId();
		while (ToolKits.isNotEmpty(fatherShipbillId)) {
			fatherShipbillId = fatherStartShipment(fatherShipbillId, date, user, departureSignTime, shipbillNodeTrackingSaveNewVO, mapTransportLogUpdate);
			departureSignTime = false;
		}

		// STD-BUG20220823 lhb 4649启运登记、送达确认 需要同步回写 派车单的状态 20220915 start
		// 更新调度单状态
		Restriction r3 = Restrictions.eq("loadingBillId", loadingBillDetailModel.getLoadingBillId());
		Restriction r4 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
		criteriaLoadingBillDetail.setRestriction(Restrictions.and(r3, r4));
		List<TmsLoadingBillDetailModel> firstLoadingBillDetailModels = tmsLoadingBillDetailMapper.findByCriteria(criteriaLoadingBillDetail);
		int cnt = 0;
		if (ToolKits.isNotEmpty(firstLoadingBillDetailModels)) {
			TmsLoadingBillHeaderModel secondLoadingBillHeaderModel = tmsLoadingBillHeaderMapper.findById(loadingBillDetailModel.getLoadingBillId(), TmsLoadingBillHeaderModel.class);

			// 运单，第一次调度，调度给承运商，第二次调度，承运商调度给司机或者承运商时，根据第二调度单，查询第一次的调度单
			r1 = Restrictions.eq(TmsLoadingBillDetailModel::getShipbillId, tmsShipbillHeaderModel.getShipbillId());
			r2 = Restrictions.eq(TmsLoadingBillDetailModel::getEnterpriseId, user.getEnterpriseId());
			r3 = Restrictions.ne(TmsLoadingBillDetailModel::getLoadingBillId, loadingBillDetailModel.getLoadingBillId());
			criteriaLoadingBillDetail.setRestriction(Restrictions.and(r1, r2, r3));
			List<TmsLoadingBillDetailModel> firstLoadingBillDetails = tmsLoadingBillDetailMapper.findByCriteria(criteriaLoadingBillDetail);

			cnt = tmsLoadingBillDetailModels.stream().filter(t -> t.getStatus().intValue() < DataDictionaryConstant.SHIPBILL_STATUS_SD.intValue()).collect(Collectors.toList()).size();
			if (cnt == 0) {
				// 更新状态为启运
				secondLoadingBillHeaderModel.setStatus(DataDictionaryConstant.LOADING_BILL_STATUS_QY);
				loadingBillService.setLoadingBillDelivery(secondLoadingBillHeaderModel);
				tmsLoadingBillHeaderMapper.update(secondLoadingBillHeaderModel);
				// 第一次调度单状态更新
				if (ToolKits.isNotEmpty(firstLoadingBillDetails)) {
					TmsLoadingBillHeaderModel firstLoadingBillHeaderModel = tmsLoadingBillHeaderMapper.findById(firstLoadingBillDetails.get(0).getLoadingBillId(), TmsLoadingBillHeaderModel.class);
					firstLoadingBillHeaderModel.setStatus(DataDictionaryConstant.LOADING_BILL_STATUS_QY);
					firstLoadingBillHeaderModel.setVehicleDeviceId(vo.getVehicleDeviceId());
					firstLoadingBillHeaderModel.setVehicleDeviceCode(vo.getVehicleDeviceCode());
					firstLoadingBillHeaderModel.setVehicleDeviceName(vo.getVehicleDeviceName());
					firstLoadingBillHeaderModel.setContainerId(vo.getContainerId());
					firstLoadingBillHeaderModel.setContainerCode(vo.getContainerCode());
					firstLoadingBillHeaderModel.setContainerName(vo.getContainerName());
					loadingBillService.setLoadingBillDelivery(firstLoadingBillHeaderModel);
					tmsLoadingBillHeaderMapper.update(firstLoadingBillHeaderModel);
				}
			} else {
				// 更新状态为部分启运
				if (!secondLoadingBillHeaderModel.getStatus().equals(DataDictionaryConstant.LOADING_BILL_STATUS_QY_PART)) {
					secondLoadingBillHeaderModel.setStatus(DataDictionaryConstant.LOADING_BILL_STATUS_QY_PART);
					secondLoadingBillHeaderModel.setVehicleDeviceId(vo.getVehicleDeviceId());
					secondLoadingBillHeaderModel.setVehicleDeviceCode(vo.getVehicleDeviceCode());
					secondLoadingBillHeaderModel.setVehicleDeviceName(vo.getVehicleDeviceName());
					secondLoadingBillHeaderModel.setContainerId(vo.getContainerId());
					secondLoadingBillHeaderModel.setContainerCode(vo.getContainerCode());
					secondLoadingBillHeaderModel.setContainerName(vo.getContainerName());
					loadingBillService.setLoadingBillDelivery(secondLoadingBillHeaderModel);
					tmsLoadingBillHeaderMapper.update(secondLoadingBillHeaderModel);
					// 第一次调度单状态更新
					if (ToolKits.isNotEmpty(firstLoadingBillDetails)) {
						TmsLoadingBillHeaderModel firstLoadingBillHeaderModel = tmsLoadingBillHeaderMapper.findById(firstLoadingBillDetails.get(0).getLoadingBillId(), TmsLoadingBillHeaderModel.class);
						firstLoadingBillHeaderModel.setStatus(DataDictionaryConstant.LOADING_BILL_STATUS_QY_PART);
						firstLoadingBillHeaderModel.setVehicleDeviceId(vo.getVehicleDeviceId());
						firstLoadingBillHeaderModel.setVehicleDeviceCode(vo.getVehicleDeviceCode());
						firstLoadingBillHeaderModel.setVehicleDeviceName(vo.getVehicleDeviceName());
						firstLoadingBillHeaderModel.setContainerId(vo.getContainerId());
						firstLoadingBillHeaderModel.setContainerCode(vo.getContainerCode());
						firstLoadingBillHeaderModel.setContainerName(vo.getContainerName());
						loadingBillService.setLoadingBillDelivery(firstLoadingBillHeaderModel);
						tmsLoadingBillHeaderMapper.update(firstLoadingBillHeaderModel);
					}
				}
			}
		}

		TmsLoadingBillHeaderModel tmsLoadingBillHeaderModel = tmsLoadingBillHeaderMapper.findById(loadingBillDetailModel.getLoadingBillId(), TmsLoadingBillHeaderModel.class);
		if (StrUtil.isNotBlank(tmsLoadingBillHeaderModel.getVehicleDeviceId()) && StrUtil.isNotBlank(tmsLoadingBillHeaderModel.getVehicleDeviceCode())) {
			String deviceId = tmsLoadingBillHeaderModel.getVehicleDeviceId().split(",")[0];
			try {
				RestMessage<DeviceByOneDTO> restMessage1 = maindataTmsResource.deviceGetOne(Long.valueOf(deviceId));
				DeviceByOneDTO deviceByOneDTO = restMessage1.getData();
				if (BussinessConstant.E6.equals(deviceByOneDTO.getCompanyName())) {
					redisTemplate.opsForSet().add(RedisConstant.PULL_GPS_DEVICE_E6_KEY, tmsLoadingBillHeaderModel.getVehicleDeviceCode());
					log.info("易流 add loadingBillId={},vehicle={},deviceCode={}", loadingBillDetailModel.getLoadingBillId(), tmsLoadingBillHeaderModel.getVehiclePlateNumber(), deviceByOneDTO.getCode());
				} else if (BussinessConstant.G7.equals(deviceByOneDTO.getCompanyName())) {
					redisTemplate.opsForSet().add(RedisConstant.PULL_GPS_DEVICE_G7_KEY, tmsLoadingBillHeaderModel.getVehicleDeviceCode());
					log.info("g7 add loadingBillId={},vehicle={},deviceCode={}", loadingBillDetailModel.getLoadingBillId(), tmsLoadingBillHeaderModel.getVehiclePlateNumber(), deviceByOneDTO.getCode());
				}
			} catch (Exception e) {
				log.error("增加redis队列错误", e);
			}
		}
		// STD-BUG20220823 lhb 4649启运登记、送达确认 需要同步回写 派车单的状态 20220915 end
		MessageUtil.addMessage(new SendMessageDTO(MessageOrderTypeEnum.SHIP_NO.getCode(), MessageTypeEnum.START_SHIP.getCode(), Lists.newArrayList(vo.getShipbillId())));
		return Boolean.FALSE;
	}

	// STD-BUG20220823 lhb 启运登记修改运单明细发货件数 20220920 start
	/**
	 * 同步更新父运单商品明细
	 *
	 * @param shipbillId
	 * @param date
	 * @param user
	 * @return
	 */
	public String updateFatherShipbillDetail(String shipbillId, TmsShipbillDetailModel subShipbillDetailModel, BigDecimal totalDeliveryPcs, Date date, UserEntity user, ItemCheckDTO rsItemInfo) {
		// 查询运单
		TmsShipbillHeaderModel tmsShipbillHeaderModel = tmsShipbillHeaderMapper.findById(shipbillId, TmsShipbillHeaderModel.class);
		// 判断是否为原始单号
		if (ToolKits.isNotEmpty(tmsShipbillHeaderModel.getFatherShipbillId()) && !tmsShipbillHeaderModel.getFatherShipbillId().equals(shipbillId)) {
			// 查找父级单号
			TmsShipbillHeaderModel fatherShipbillHeaderModel = tmsShipbillHeaderMapper.findById(tmsShipbillHeaderModel.getFatherShipbillId(), TmsShipbillHeaderModel.class);

			Criteria criteriaShipbillDetail = Criteria.forClass(TmsShipbillDetailModel.class);
			Restriction r11 = Restrictions.eq(TmsShipbillDetailModel::getShipbillId, fatherShipbillHeaderModel.getShipbillId());
			Restriction r12 = Restrictions.eq(TmsShipbillDetailModel::getEnterpriseId, user.getEnterpriseId());
			Restriction r13 = Restrictions.eq(TmsShipbillDetailModel::getItemId, subShipbillDetailModel.getItemId());
			Restriction r14 = Restrictions.gt(TmsShipbillDetailModel::getPcs, BigDecimal.valueOf(0));
			criteriaShipbillDetail.setRestriction(Restrictions.and(r11, r12, r13, r14));
			List<TmsShipbillDetailModel> shipbillDetailModels = tmsShipbillDetailMapper.findByCriteria(criteriaShipbillDetail);

			if (ToolKits.isEmpty(shipbillDetailModels)) {
				throw new PrologException("运单【" + shipbillId + "】的父运单的运单商品明细【" + subShipbillDetailModel.getItemName() + "】不存在");
			}
			BigDecimal detailDeliveryPcs = totalDeliveryPcs;
			for (TmsShipbillDetailModel fatherShipbillDetailModel : shipbillDetailModels) {
				if (detailDeliveryPcs.intValue() <= 0) {
					break;
				}
				if (fatherShipbillDetailModel.getPcs().intValue() >= detailDeliveryPcs.intValue()) {
					fatherShipbillDetailModel.setDeliveryPcs(fatherShipbillDetailModel.getDeliveryPcs().add(detailDeliveryPcs));
					fatherShipbillDetailModel.setPickUpPcs(NumberUtil.add(fatherShipbillDetailModel.getPickUpPcs(), subShipbillDetailModel.getPickUpPcs()));

					// 剩余件数
					fatherShipbillDetailModel.setUpdateperson(user.getNickname());
					fatherShipbillDetailModel.setUpdatetime(date);
					fatherShipbillDetailModel.setPcs(fatherShipbillDetailModel.getOrigPcs().subtract(fatherShipbillDetailModel.getClosingPcs()).subtract(fatherShipbillDetailModel.getDeliveryPcs()));
					fatherShipbillDetailModel.setVolume(fatherShipbillDetailModel.getPcs().multiply(rsItemInfo.getVolume()));
					fatherShipbillDetailModel.setWeight(fatherShipbillDetailModel.getPcs().multiply(rsItemInfo.getWeight()));
					tmsShipbillDetailMapper.update(fatherShipbillDetailModel);
					detailDeliveryPcs = BigDecimal.valueOf(0);
					break;
				} else {
					fatherShipbillDetailModel.setDeliveryPcs(fatherShipbillDetailModel.getDeliveryPcs().add(fatherShipbillDetailModel.getDeliveryPcs()));
					detailDeliveryPcs = detailDeliveryPcs.subtract(fatherShipbillDetailModel.getDeliveryPcs());
					fatherShipbillDetailModel.setPickUpPcs(NumberUtil.add(fatherShipbillDetailModel.getPickUpPcs(), subShipbillDetailModel.getPickUpPcs()));

					// 剩余件数
					fatherShipbillDetailModel.setUpdateperson(user.getNickname());
					fatherShipbillDetailModel.setUpdatetime(date);
					fatherShipbillDetailModel.setPcs(fatherShipbillDetailModel.getOrigPcs().subtract(fatherShipbillDetailModel.getClosingPcs()).subtract(fatherShipbillDetailModel.getDeliveryPcs()));
					fatherShipbillDetailModel.setVolume(fatherShipbillDetailModel.getPcs().multiply(rsItemInfo.getVolume()));
					fatherShipbillDetailModel.setWeight(fatherShipbillDetailModel.getPcs().multiply(rsItemInfo.getWeight()));
					tmsShipbillDetailMapper.update(fatherShipbillDetailModel);
				}
			}
			if (detailDeliveryPcs.intValue() > 0) {
				throw new PrologException("运单【" + shipbillId + "】的商品【" + subShipbillDetailModel.getItemName() + "】的件数>父运单的件数");
			}

			// 更新运单
			if (ToolKits.isEmpty(fatherShipbillHeaderModel.getTotalDeliveryPcs())) {
				fatherShipbillHeaderModel.setTotalDeliveryPcs(totalDeliveryPcs);
			} else {
				fatherShipbillHeaderModel.setTotalDeliveryPcs(fatherShipbillHeaderModel.getTotalDeliveryPcs().add(totalDeliveryPcs));
			}

			fatherShipbillHeaderModel.setTotalDeliveryVolume(fatherShipbillHeaderModel.getTotalDeliveryPcs().multiply(rsItemInfo.getVolume()));
			fatherShipbillHeaderModel.setTotalDeliveryWeight(fatherShipbillHeaderModel.getTotalDeliveryPcs().multiply(rsItemInfo.getWeight()));

			if (ToolKits.isEmpty(fatherShipbillHeaderModel.getDepartureTime())) {
				fatherShipbillHeaderModel.setDepartureTime(new Date());
			}

			fatherShipbillHeaderModel.setTotalPcs(fatherShipbillHeaderModel.getTotalPcs().subtract(totalDeliveryPcs));
			fatherShipbillHeaderModel.setTotalVolume(fatherShipbillHeaderModel.getTotalPcs().multiply(rsItemInfo.getVolume()));
			fatherShipbillHeaderModel.setTotalWeight(fatherShipbillHeaderModel.getTotalPcs().multiply(rsItemInfo.getWeight()));
			fatherShipbillHeaderModel.setActualTotalPcs(fatherShipbillHeaderModel.getTotalPcs());
			fatherShipbillHeaderModel.setActualTotalVolume(fatherShipbillHeaderModel.getTotalVolume());
			fatherShipbillHeaderModel.setActualTotalWeight(fatherShipbillHeaderModel.getTotalWeight());

			fatherShipbillHeaderModel.setUpdateperson(user.getNickname());
			fatherShipbillHeaderModel.setUpdatetime(date);
			tmsShipbillHeaderMapper.update(fatherShipbillHeaderModel);

			return fatherShipbillHeaderModel.getShipbillId();
		}
		return null;
	}
	// STD-BUG20220823 lhb 启运登记修改运单明细发货件数 20220920 end

	/**
	 * 父运单启运确认
	 *
	 * @param shipbillId
	 * @param date
	 * @param user
	 * @return
	 */
	public String fatherStartShipment(String shipbillId, Date date, UserEntity user, boolean whether, ShipbillNodeTrackingSaveNewVO shipbillNodeTrackingSaveNewVO, Map<String, Object> mapTransportLogUpdate) {
		// 查询运单
		TmsShipbillHeaderModel tmsShipbillHeaderModel = tmsShipbillHeaderMapper.findById(shipbillId, TmsShipbillHeaderModel.class);
		// 判断是否为原始单号
		if (ToolKits.isNotEmpty(tmsShipbillHeaderModel.getFatherShipbillId()) && !tmsShipbillHeaderModel.getFatherShipbillId().equals(shipbillId)) {
			// 查找父级单号
			TmsShipbillHeaderModel fatherShipbillHeaderModel = tmsShipbillHeaderMapper.findById(tmsShipbillHeaderModel.getFatherShipbillId(), TmsShipbillHeaderModel.class);

			// 判断父级单号的状态是否为开始启运
			if (fatherShipbillHeaderModel.getStatus() != DataDictionaryConstant.SHIPBILL_STATUS_SD) {
				// 修改父级运单状态
				fatherShipbillHeaderModel.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_SD);
				fatherShipbillHeaderModel.setUpdatetime(date);
				fatherShipbillHeaderModel.setUpdateperson(user.getNickname());
				fatherShipbillHeaderModel.setTransportStatus(DataDictionaryConstant.TRANSPORT_STATUS_SHIPPING);
				if (ToolKits.isEmpty(fatherShipbillHeaderModel.getDepartureTime())) {
					fatherShipbillHeaderModel.setDepartureTime(date);
				}
				tmsShipbillHeaderMapper.update(fatherShipbillHeaderModel);

				// 同步修改运单对应的装车单明细状态
				Map<String, Object> queryMap = Maps.newHashMap();
				queryMap.put("shipbillId", fatherShipbillHeaderModel.getShipbillId());
				queryMap.put("enterpriseId", user.getEnterpriseId());
				List<TmsLoadingBillDetailModel> tmsLoadingBillDetails = tmsLoadingBillDetailMapper.findByMap(queryMap, TmsLoadingBillDetailModel.class);
				if (ToolKits.isNotEmpty(tmsLoadingBillDetails) && tmsLoadingBillDetails.size() > 0) {
					TmsLoadingBillDetailModel tmsLoadingBillDetail = tmsLoadingBillDetails.get(0);
					tmsLoadingBillDetail.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_SD);
					tmsLoadingBillDetail.setUpdateperson(user.getNickname());
					tmsLoadingBillDetail.setUpdatetime(date);
					tmsLoadingBillDetailMapper.update(tmsLoadingBillDetail);
				}

				// 修改父级运单运输记录表
				Criteria criteriaTransport = Criteria.forClass(TmsShipbillTransLogModel.class);
				Restriction r1 = Restrictions.eq("shipbillId", fatherShipbillHeaderModel.getShipbillId());
				criteriaTransport.setRestriction(r1);
				// 更新订单运输记录表
				tmsShipbillTransportLogMapper.updateMapByCriteria(mapTransportLogUpdate, criteriaTransport);

				// 运单日志信息
				ShipbillOperateLogSaveNewVO shipbillOperateLogSaveNewVO = new ShipbillOperateLogSaveNewVO();
				shipbillOperateLogSaveNewVO.setShipbillId(fatherShipbillHeaderModel.getShipbillId());
				shipbillOperateLogSaveNewVO.setShipbillNo(fatherShipbillHeaderModel.getShipbillId());
				shipbillOperateLogSaveNewVO.setOperateDate(date);
				shipbillOperateLogSaveNewVO.setEnterpriseId(user.getEnterpriseId());
				shipbillOperateLogSaveNewVO.setEnterpriseName(user.getEnterpriseName());
				shipbillOperateLogSaveNewVO.setUserId(user.getUserid());
				shipbillOperateLogSaveNewVO.setUserName(user.getNickname());

				// 判断第一个子单是否有签到时间
				if (whether) {
					// 运单节点信息
					ShipbillNodeTrackingSaveNewVO nodeTrackingSaveNewVO = new ShipbillNodeTrackingSaveNewVO();
					nodeTrackingSaveNewVO.setNodeDate(date);
					nodeTrackingSaveNewVO.setShipbillId(fatherShipbillHeaderModel.getShipbillId());
					nodeTrackingSaveNewVO.setShipbillNo(fatherShipbillHeaderModel.getShipbillId());
					nodeTrackingSaveNewVO.setUserId(user.getUserid());
					nodeTrackingSaveNewVO.setUserName(user.getNickname());
					nodeTrackingSaveNewVO.setEnterpriseId(user.getEnterpriseId());
					nodeTrackingSaveNewVO.setEnterpriseName(user.getEnterpriseName());
					nodeTrackingSaveNewVO.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_QY);
					nodeTrackingSaveNewVO.setNodeEvent(DataDictionaryConstant.SHIPBILL_STATUSNAME_QYQD);
					shipbillNodeTrackingService.addShipbillNodeTrackingNewData(nodeTrackingSaveNewVO);

					// 运单日志保存
					shipbillOperateLogSaveNewVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_STATUSNAME_QYQD);
					shipbillOperateLogSaveNewVO.setOldStatus(DataDictionaryConstant.SHIPBILL_STATUS_ZX_CONFIRM);
					shipbillOperateLogSaveNewVO.setNewStatus(DataDictionaryConstant.SHIPBILL_STATUS_QY);
					shipbillOperateLogService.addShipbillOperateLogNewData(shipbillOperateLogSaveNewVO);
				}
				// 运单节点保存
				shipbillNodeTrackingSaveNewVO.setShipbillId(fatherShipbillHeaderModel.getShipbillId());
				shipbillNodeTrackingSaveNewVO.setShipbillNo(fatherShipbillHeaderModel.getShipbillId());
				shipbillNodeTrackingService.addShipbillNodeTrackingNewData(shipbillNodeTrackingSaveNewVO);

				// 运单日志保存
				shipbillOperateLogSaveNewVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_STATUSNAME_QY);
				shipbillOperateLogSaveNewVO.setOldStatus(DataDictionaryConstant.SHIPBILL_STATUS_ZX_CONFIRM);
				shipbillOperateLogSaveNewVO.setNewStatus(DataDictionaryConstant.SHIPBILL_STATUS_QY);
				shipbillOperateLogService.addShipbillOperateLogNewData(shipbillOperateLogSaveNewVO);

				return fatherShipbillHeaderModel.getShipbillId();
			}
		}
		return null;
	}

}
