package com.sckw.transport.service;

import cn.hutool.core.util.ArrayUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.sckw.contract.api.RemoteContractService;
import com.sckw.contract.api.model.dto.res.ContractCommonInfoResDto;
import com.sckw.core.common.enums.NumberConstant;
import com.sckw.core.common.enums.StringConstant;
import com.sckw.core.common.enums.enums.DictTypeEnum;
import com.sckw.core.exception.BusinessException;
import com.sckw.core.model.enums.CarWaybillEnum;
import com.sckw.core.model.enums.LogisticsOrderEnum;
import com.sckw.core.model.page.PageResult;
import com.sckw.core.utils.*;
import com.sckw.core.web.constant.HttpStatus;
import com.sckw.core.web.context.LoginUserHolder;
import com.sckw.core.web.response.HttpResult;
import com.sckw.excel.utils.DateUtil;
import com.sckw.excel.utils.ValidUtil;
import com.sckw.fleet.api.RemoteFleetService;
import com.sckw.fleet.api.model.vo.RTruckVo;
import com.sckw.manage.api.RemoteManageService;
import com.sckw.mongo.enums.BusinessTypeEnum;
import com.sckw.mongo.model.SckwLogisticsOrder;
import com.sckw.mongo.model.SckwWaybillOrder;
import com.sckw.order.api.dubbo.TradeOrderInfoService;
import com.sckw.product.api.dubbo.GoodsInfoService;
import com.sckw.product.api.model.KwpGoods;
import com.sckw.stream.model.SckwBusSum;
import com.sckw.system.api.RemoteSystemService;
import com.sckw.system.api.model.dto.res.EntCacheResDto;
import com.sckw.system.api.model.dto.res.SysDictResDto;
import com.sckw.transport.dao.*;
import com.sckw.transport.model.*;
import com.sckw.transport.model.dto.*;
import com.sckw.transport.model.param.DriverParam;
import com.sckw.transport.model.vo.*;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.stream.function.StreamBridge;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author lfdc
 * @description 承运订单service
 * @date 2023-06-26 16:06:11
 */
@Slf4j
@Service
public class AcceptCarriageOrderService {

    @DubboReference(version = "2.0.0", group = "design", check = false, timeout = 8000)
    RemoteSystemService remoteSystemService;
    @DubboReference(version = "2.0.0", group = "design", check = false, timeout = 8000)
    TradeOrderInfoService tradeOrderInfoService;

    @DubboReference(version = "2.0.0", group = "design", check = false, timeout = 8000)
    GoodsInfoService goodsInfoService;

    @DubboReference(version = "2.0.0", group = "design", check = false, timeout = 8000)
    RemoteFleetService fleetService;

    @DubboReference(version = "2.0.0", group = "design", check = false, timeout = 6000)
    RemoteContractService remoteContractService;

    @DubboReference(version = "2.0.0", group = "design", check = false, timeout = 6000)
    RemoteManageService remoteManageService;

    @Resource
    private StreamBridge streamBridge;

    @Autowired
    private KwtLogisticsOrderMapper logisticsOrderMapper;

    @Autowired
    private KwtLogisticsOrderTrackMapper logisticsOrderTrackMapper;

    @Autowired
    private KwtWaybillOrderMapper waybillOrderMapper;

    @Autowired
    private KwtWaybillOrderTrackMapper waybillOrderTrackMapper;

    @Autowired
    public KwtLogisticsOrderGoodsMapper kwtLogisticsOrderGoodsMapper;

    @Autowired
    public KwtLogisticsOrderContractMapper kwtLogisticsOrderContractMapper;

    @Autowired
    public KwtLogisticsOrderMapper kwtLogisticsOrderMapper;

    @Autowired
    private KwtLogisticsOrderCirculateMapper logisticsOrderCirculateMapper;

    @Autowired
    private KwtLogisticsOrderAddressMapper logisticsOrderAddressMapper;

    @Autowired
    public KwtLogisticsOrderUnitMapper logisticsOrderUnitMapper;

    @Autowired
    private MongoTemplate mongoTemplate;


    /**
     * 承运订单-分包托运
     *
     * @param bo
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public HttpResult subcontractConsignment(SubcontractConsignmentDTO bo) {
        HttpResult httpResult = ValidUtil.serviceValid(bo);
        if (!String.valueOf(HttpStatus.SUCCESS_CODE).equals(String.valueOf(httpResult.getCode()))) {
            httpResult.setMsg(httpResult.getMsg());
            httpResult.setCode(HttpStatus.GLOBAL_EXCEPTION_CODE);
            return httpResult;
        }
        KwtLogisticsOrder logisticsOrder = logisticsOrderMapper.selectOne(new LambdaQueryWrapper<KwtLogisticsOrder>()
                .eq(KwtLogisticsOrder::getId, bo.getLOrderId()));
        if (logisticsOrder == null) {
            log.error("订单id查找失败:{},订单编号:{}", bo.getLOrderId(), bo.getLOrderNo());
            throw new BusinessException("单据错误,数据不存在");
        }
        //todo  校验当前登录角色是否具有4P物流角色
        EntCacheResDto entCacheResDto = remoteSystemService.queryEntCacheById(LoginUserHolder.getEntId());
        if (entCacheResDto == null) {
            log.info("承运订单-分包托运 用户id:{}", LoginUserHolder.getUserId());
            throw new RuntimeException("企业信息查询异常");
        }
        if (!entCacheResDto.getEntTypes().contains(String.valueOf(NumberConstant.THREE))) {
            throw new RuntimeException("当前用户企业不具有分包功能权限！");
        }
        KwtLogisticsOrder order = new KwtLogisticsOrder();
        if (!bo.getIsFullDose()) {
            Long amount = bo.getAmount();
            Long carryingCapacity = bo.getCarryingCapacity();
            if (carryingCapacity > amount) {
                log.error("运订单分包托运-可分配量分配错误:{}", bo.getLOrderId());
                throw new RuntimeException("可分配量分配错误");
            }
            if (ArrayUtil.isEmpty(bo.getCarryingCapacity())) {
                throw new RuntimeException("不是全量分配时,分配量不能为空!");
            }
            order.setAmount(new BigDecimal(bo.getCarryingCapacity()));
            order.setUnit(bo.getCarryingCapacityUnit());
        } else {
            order.setAmount(new BigDecimal(NumberConstant.ZERO));
            order.setSubcontractAmount(new BigDecimal(NumberConstant.ZERO));
            order.setUnit(bo.getCarryingCapacityUnit());
        }
        String lOrderNo = com.sckw.transport.utils.StringUtils.getLOrderNo();
        Long orderId = new IdWorker(NumberConstant.ONE).nextId();
        /**分包托运需要判断处于哪一级分包托运
         * 需要记录当前分包数据-分包上游数据
         * */
        /**
         * 判断是否已存在分包【当前分包只允许加上主单一共三级】*/
        Long count = logisticsOrderMapper.selectCount(new LambdaQueryWrapper<KwtLogisticsOrder>()
                .in(KwtLogisticsOrder::getPids, bo.getLOrderId()));
        if (count > NumberConstant.TWO) {
            throw new RuntimeException("分包次数已达上限!");
        }
        String pids = logisticsOrder.getPids();
        if (StringUtils.isNotBlank(pids)) {
            pids = pids + StringConstant.COMMA + orderId;
        } else {
            pids = bo.getLOrderId() + StringConstant.COMMA + orderId;
        }
        /**判断生成物流订单应生成哪一种单据状态*/
        List<Long> contractList = new ArrayList<>();
        contractList.add(Long.parseLong(bo.getContractId()));
        Map<Long, ContractCommonInfoResDto> longContractCommonInfoResDtoMap = remoteContractService.queryContractBaseInfo(contractList);
        if (CollectionUtils.isEmpty(longContractCommonInfoResDtoMap)) {
            throw new RuntimeException("并未有对应合同,应先签约合同");
        }
        if (longContractCommonInfoResDtoMap.get(Long.parseLong(bo.getContractId())) == null) {
            throw new RuntimeException("并未有对应合同,应先签约合同");
        }
        ContractCommonInfoResDto infoResDto = longContractCommonInfoResDtoMap.get(Long.parseLong(bo.getContractId()));
        /**状态判断
         * 是否是已签约合同
         * */
        // 0 已签约 1待签约
        Integer status = infoResDto.getStatus();
        Integer orderStatus = LogisticsOrderEnum.PENDING_ORDER.getCode();
        if (NumberConstant.ONE == status) {
            orderStatus = LogisticsOrderEnum.TO_BE_PLANNED.getCode();
        } else if (NumberConstant.ZERO == status) {
            orderStatus = LogisticsOrderEnum.PENDING_ORDER.getCode();
        } else {
            log.info("承运订单-分包托运物流托运 承运订单id:{}," +
                            "承运订单编号:{},合同id:{},合同信息:{}",
                    bo.getLOrderId(), bo.getLOrderNo(),
                    bo.getContractId(), JSONObject.toJSONString(infoResDto));
            throw new RuntimeException("生成物流托运合同异常");
        }
        insertSubcontractLogisticsGoods(bo, lOrderNo, orderId);
        insertSubcontractLogisticsOrder(bo, lOrderNo, order, orderId, pids, orderStatus, logisticsOrder);
        insertSubcontractLogisticsOrderContract(bo, orderId);
        insertSubcontractLogisticsOrderUnit(bo, orderId);
        insertSubcontractLogisticsOrderAddress(bo, orderId, logisticsOrder);
        insertLogisticsOrderTrack(bo, orderId, orderStatus);
        //修改上级分配量以及可分配量委托量等
        logisticsOrder.setSubcontractAmount(logisticsOrder.getSubcontractAmount().add(new BigDecimal(bo.getCarryingCapacity())));
        logisticsOrderMapper.updateById(logisticsOrder);
        //修改父级mongodb数据
        //更新mongodb
        SckwLogisticsOrder lOrder = new SckwLogisticsOrder();
        lOrder.set_id(order.getId());
        lOrder.setLOrderId(order.getId());
        lOrder.setEntrustAmount(order.getEntrustAmount());
        lOrder.setStatus(String.valueOf(order.getStatus()));
        lOrder.setUpdateTime(order.getUpdateTime());
        lOrder.setUpdateBy(order.getUpdateBy());
        lOrder.setUpdateByName(LoginUserHolder.getUserName());
        lOrder.setSubcontractAmount(logisticsOrder.getSubcontractAmount().add(new BigDecimal(bo.getCarryingCapacity())));        //rabbitMq业务汇总数据发送/消费对象
        SckwBusSum busSum = new SckwBusSum();
        //业务汇总类型
        busSum.setBusSumType(BusinessTypeEnum.LOGISTICS_ORDER_TYPE.getName());
        //操作对象（1新增/2修改/3替换数据）
        busSum.setMethod(2);
        //业务汇总数据对象
        busSum.setObject(lOrder);
        busSum.setBusSumType(BusinessTypeEnum.LOGISTICS_ORDER_TYPE.getName());
        busSum.setMethod(NumberConstant.TWO);
        streamBridge.send("sckw-busSum", com.alibaba.fastjson2.JSON.toJSONString(busSum));
        //新增当前分包mongodb数据
        subcontractSendMongoDB(lOrderNo, orderId, bo, logisticsOrder, orderStatus);
        return HttpResult.ok();
    }

    /**
     * 推送数据到MongoDB
     *
     * @param lOrderNo          物流订单编号
     * @param orderId           物流订单id
     * @param bo                页面传输实体
     * @param kwtLogisticsOrder 物流订单数据(上一级)
     */
    private void subcontractSendMongoDB(String lOrderNo, Long orderId, SubcontractConsignmentDTO bo, KwtLogisticsOrder kwtLogisticsOrder, Integer orderStatus) {
        SckwLogisticsOrder logisticsOrder = new SckwLogisticsOrder();
        logisticsOrder.setStatus(String.valueOf(orderStatus));
        logisticsOrder.setLOrderId(orderId);
        logisticsOrder.setLOrderNo(lOrderNo);
        logisticsOrder.setLOrderPid(Long.parseLong(bo.getLOrderId()));
        logisticsOrder.setSettlementCycle(bo.getSettlementCycle());
        logisticsOrder.setPrice(new BigDecimal(bo.getPrice()));
        logisticsOrder.setPriceType(remoteSystemService.queryDictByTypeAndValue(DictTypeEnum.PRICE_TYPE.getType(), bo.getPriceType()) == null ?
                null : Long.parseLong(remoteSystemService.queryDictByTypeAndValue(DictTypeEnum.PRICE_TYPE.getType(), bo.getPriceType()).getValue()));
        if (!bo.getIsFullDose()) {
            if (ArrayUtil.isEmpty(bo.getCarryingCapacity())) {
                throw new RuntimeException("不是全量分配时,分配量不能为空!");
            }
            logisticsOrder.setAmount(new BigDecimal(bo.getCarryingCapacity()));
            logisticsOrder.setUnit(bo.getCarryingCapacityUnit());
            logisticsOrder.setCarryingCapacity(bo.getCarryingCapacity());
        } else {
            logisticsOrder.setAmount(new BigDecimal(NumberConstant.ZERO));
            logisticsOrder.setSubcontractAmount(new BigDecimal(NumberConstant.ZERO));
            logisticsOrder.setCarryingCapacity(0L);
        }
        logisticsOrder.setLoss(bo.getLoss() == null ? null : bo.getLoss());
        logisticsOrder.setLossUnit(bo.getLossUnit());
        logisticsOrder.setGoodsPrice(bo.getGoodsPrice() == null ? null : new BigDecimal(bo.getGoodsPrice()));
        BigDecimal decimal = new BigDecimal(NumberConstant.ZERO);
        logisticsOrder.setSubcontractAmount(decimal);
        logisticsOrder.setEntrustAmount(decimal);
        logisticsOrder.setUnloadAmount(decimal);
        logisticsOrder.setLoadAmount(decimal);
        logisticsOrder.setIgnoreAmount(decimal);
        logisticsOrder.setDeficitPrice(decimal);
        logisticsOrder.setPayment(Long.parseLong(bo.getPayment()));
        logisticsOrder.setTaxRate(bo.getTaxRate() == null ? null : new BigDecimal(bo.getTaxRate()));
        logisticsOrder.setRemark(bo.getRemark());
        logisticsOrder.setEntId(LoginUserHolder.getEntId());
        logisticsOrder.setFirmName(remoteSystemService.queryEntCacheById(LoginUserHolder.getEntId()).getFirmName());
        logisticsOrder.setGoodsId(Long.parseLong(bo.getGoodsId()));
        KwpGoods goods = goodsInfoService.getGoodsById(Long.parseLong(bo.getGoodsId()));
        logisticsOrder.setGoodsType(goods == null ? null : goods.getGoodsType());
        logisticsOrder.setGoodsSpec(goods == null ? null : goods.getSpec());
        logisticsOrder.setContractId(bo.getContractId());
        logisticsOrder.setContractNo(bo.getContractNo());
        logisticsOrder.setContractName(bo.getContractName());
        logisticsOrder.setContractSigningWay(bo.getPayment());
        logisticsOrder.setCheckEntId(Long.parseLong(bo.getCheckCompanyId()));
        logisticsOrder.setCheckFirmName(bo.getCheckCompany());
        logisticsOrder.setCheckContacts(bo.getCheckContacts());
        logisticsOrder.setCheckPhone(bo.getCheckContactPhone());
        logisticsOrder.setCarrierEntId(Long.parseLong(bo.getConsignCompanyId()));
        logisticsOrder.setCarrierFirmName(bo.getConsignCompany());
        logisticsOrder.setCarrierContacts(bo.getConsignContacts());
        KwtLogisticsOrderAddress orderLoadAddress = logisticsOrderAddressMapper.selectOne(new LambdaQueryWrapper<KwtLogisticsOrderAddress>()
                .eq(KwtLogisticsOrderAddress::getLOrderId, kwtLogisticsOrder.getId())
                .eq(KwtLogisticsOrderAddress::getAddressType, NumberConstant.ONE));
        KwtLogisticsOrderAddress orderUnLoadAddress = logisticsOrderAddressMapper.selectOne(new LambdaQueryWrapper<KwtLogisticsOrderAddress>()
                .eq(KwtLogisticsOrderAddress::getLOrderId, kwtLogisticsOrder.getId())
                .eq(KwtLogisticsOrderAddress::getAddressType, NumberConstant.TWO));
        if (!ObjectUtils.isEmpty(orderLoadAddress)) {
            logisticsOrder.setLoadType(orderLoadAddress.getType());
            logisticsOrder.setLoadCityCode(orderLoadAddress.getCityCode());
            logisticsOrder.setLoadCityName(orderLoadAddress.getCityName());
            logisticsOrder.setLoadDetailAddress(orderLoadAddress.getDetailAddress());
            logisticsOrder.setLoadLat(orderLoadAddress.getLat());
            logisticsOrder.setLoadPhone(orderLoadAddress.getPhone());
            logisticsOrder.setLoadLng(orderLoadAddress.getLng());
            logisticsOrder.setLoadContacts(orderLoadAddress.getContacts());
        }
        if (!ObjectUtils.isEmpty(orderUnLoadAddress)) {
            logisticsOrder.setUnloadType(orderUnLoadAddress.getType());
            logisticsOrder.setUnloadPhone(orderUnLoadAddress.getPhone());
            logisticsOrder.setUnloadCityCode(orderUnLoadAddress.getCityCode());
            logisticsOrder.setUnloadCityName(orderUnLoadAddress.getCityName());
            logisticsOrder.setUnloadDetailAddress(orderUnLoadAddress.getDetailAddress());
            logisticsOrder.setUnloadLat(orderUnLoadAddress.getLat());
            logisticsOrder.setUnloadLng(orderUnLoadAddress.getLng());
            logisticsOrder.setUnloadContacts(orderUnLoadAddress.getContacts());
        }
        //TODO 生成时并无时间
//        logisticsOrder.setLoadTime();
//        logisticsOrder.setunLoadTime();
        logisticsOrder.setCreateBy(LoginUserHolder.getUserId());
        logisticsOrder.setCreateByName(LoginUserHolder.getUserName());
        logisticsOrder.setCreateTime(new Date());
        logisticsOrder.setUpdateBy(LoginUserHolder.getUserId());
        logisticsOrder.setUpdateByName(LoginUserHolder.getUserName());
        logisticsOrder.setUpdateTime(new Date());
        logisticsOrder.setGoodsPriceUnit(bo.getGoodsPriceUnit());
        logisticsOrder.setContractName(bo.getContractName());
        logisticsOrder.setBillingMode(bo.getBillingMode());
        //rabbitMq业务汇总数据发送/消费对象
        SckwBusSum busSum = new SckwBusSum();
        //业务汇总类型
        busSum.setBusSumType(BusinessTypeEnum.LOGISTICS_ORDER_TYPE.getName());
        //操作对象（1新增/2修改）
        busSum.setMethod(1);
        //业务汇总数据对象
        busSum.setObject(logisticsOrder);
        streamBridge.send("sckw-busSum", JSON.toJSONString(busSum));
    }

    /**
     * 分包托运-承运订单-单据状态
     *
     * @param bo
     * @param orderId
     */
    private void insertLogisticsOrderTrack(SubcontractConsignmentDTO bo, Long orderId, Integer orderStatus) {
        KwtLogisticsOrderTrack entity = new KwtLogisticsOrderTrack();
        entity.setId(new IdWorker(NumberConstant.ONE).nextId());
        entity.setLOrderId(orderId);
        entity.setStatus(orderStatus);
        entity.setCreateTime(new Date());
        entity.setUpdateTime(new Date());
        entity.setCreateBy(LoginUserHolder.getUserId());
        entity.setUpdateBy(LoginUserHolder.getUserId());
        entity.setRemark(bo.getRemark());
        logisticsOrderTrackMapper.insert(entity);
    }

    /**
     * 分包托运-承运订单-装卸货地址信息
     *
     * @param bo
     * @param orderId
     * @param logisticsOrder
     */
    private void insertSubcontractLogisticsOrderAddress(SubcontractConsignmentDTO bo, Long orderId, KwtLogisticsOrder logisticsOrder) {
        KwtLogisticsOrderAddress loadOrderAddress = new KwtLogisticsOrderAddress();
        KwtLogisticsOrderAddress unloadOrderAddress = new KwtLogisticsOrderAddress();
        KwtLogisticsOrderAddress orderLoadAddress = logisticsOrderAddressMapper.selectOne(new LambdaQueryWrapper<KwtLogisticsOrderAddress>()
                .eq(KwtLogisticsOrderAddress::getLOrderId, logisticsOrder.getId())
                .eq(KwtLogisticsOrderAddress::getAddressType, NumberConstant.ONE));
        KwtLogisticsOrderAddress orderUnLoadAddress = logisticsOrderAddressMapper.selectOne(new LambdaQueryWrapper<KwtLogisticsOrderAddress>()
                .eq(KwtLogisticsOrderAddress::getLOrderId, logisticsOrder.getId())
                .eq(KwtLogisticsOrderAddress::getAddressType, NumberConstant.TWO));
        if (!ObjectUtils.isEmpty(orderLoadAddress)) {
            loadOrderAddress.setId(new IdWorker(NumberConstant.ONE).nextId());
            loadOrderAddress.setAddressType(NumberConstant.ONE);
            loadOrderAddress.setDetailAddress(orderLoadAddress.getDetailAddress());
            loadOrderAddress.setContacts(orderLoadAddress.getContacts());
            loadOrderAddress.setLOrderId(orderId);
            loadOrderAddress.setLat(orderLoadAddress.getLat());
            loadOrderAddress.setFence(orderLoadAddress.getFence());
            loadOrderAddress.setCityName(orderLoadAddress.getCityName());
            loadOrderAddress.setEntryType(NumberConstant.FOUR);
            loadOrderAddress.setCreateTime(new Date());
            loadOrderAddress.setPhone(orderLoadAddress.getPhone());
            loadOrderAddress.setCreateBy(LoginUserHolder.getUserId());
            loadOrderAddress.setUpdateBy(LoginUserHolder.getUserId());
            loadOrderAddress.setUpdateTime(new Date());
            loadOrderAddress.setName(orderLoadAddress.getName());
            loadOrderAddress.setType(orderLoadAddress.getType());
            loadOrderAddress.setCityCode(orderLoadAddress.getCityCode());
            loadOrderAddress.setLng(orderLoadAddress.getLng());
            loadOrderAddress.setRemark(orderLoadAddress.getRemark());
            loadOrderAddress.setStatus(orderLoadAddress.getStatus());
            logisticsOrderAddressMapper.insert(loadOrderAddress);
        }
        if (!ObjectUtils.isEmpty(orderUnLoadAddress)) {
            unloadOrderAddress.setId(new IdWorker(NumberConstant.ONE).nextId());
            unloadOrderAddress.setAddressType(NumberConstant.TWO);
            unloadOrderAddress.setId(new IdWorker(NumberConstant.ONE).nextId());
            unloadOrderAddress.setContacts(orderUnLoadAddress.getContacts());
            unloadOrderAddress.setLOrderId(orderId);
            unloadOrderAddress.setLat(orderUnLoadAddress.getLat());
            unloadOrderAddress.setFence(orderUnLoadAddress.getFence());
            unloadOrderAddress.setCityName(orderUnLoadAddress.getCityName());
            unloadOrderAddress.setEntryType(NumberConstant.FOUR);
            unloadOrderAddress.setPhone(orderUnLoadAddress.getPhone());
            unloadOrderAddress.setDetailAddress(orderUnLoadAddress.getDetailAddress());
            unloadOrderAddress.setCreateTime(new Date());
            unloadOrderAddress.setCreateBy(LoginUserHolder.getUserId());
            unloadOrderAddress.setUpdateBy(LoginUserHolder.getUserId());
            unloadOrderAddress.setUpdateTime(new Date());
            unloadOrderAddress.setName(orderUnLoadAddress.getName());
            unloadOrderAddress.setType(orderUnLoadAddress.getType());
            unloadOrderAddress.setCityCode(orderUnLoadAddress.getCityCode());
            unloadOrderAddress.setLng(orderUnLoadAddress.getLng());
            unloadOrderAddress.setRemark(orderUnLoadAddress.getRemark());
            unloadOrderAddress.setStatus(orderUnLoadAddress.getStatus());
            logisticsOrderAddressMapper.insert(unloadOrderAddress);
        }
    }

    /**
     * 分包托运-承运订单-单位信息
     *
     * @param bo
     * @param orderId
     */
    private void insertSubcontractLogisticsOrderUnit(SubcontractConsignmentDTO bo, Long orderId) {
        KwtLogisticsOrderUnit checkUnit = new KwtLogisticsOrderUnit()
                .setLOrderId(orderId)
                .setId(new IdWorker(NumberConstant.ONE).nextId())
                .setUnitType(NumberConstant.ONE)
                .setFirmName(bo.getCheckCompany())
                .setRemark(bo.getRemark())
                .setEntId(Long.parseLong(bo.getCheckCompanyId()))
                .setContacts(bo.getCheckContacts())
                .setPhone(bo.getCheckContactPhone())
                .setCreateBy(LoginUserHolder.getUserId())
                .setCreateTime(new Date())
                .setUpdateBy(LoginUserHolder.getUserId())
                .setUpdateTime(new Date());
        logisticsOrderUnitMapper.insert(checkUnit);

        KwtLogisticsOrderUnit consignUnit = new KwtLogisticsOrderUnit()
                .setLOrderId(orderId)
                .setId(new IdWorker(NumberConstant.ONE).nextId())
                .setUnitType(NumberConstant.TWO)
                .setFirmName(bo.getConsignCompany())
                .setRemark(bo.getRemark())
                .setEntId(Long.parseLong(bo.getConsignCompanyId()))
                .setContacts(bo.getConsignContacts())
                .setPhone(bo.getConsignContactPhone())
                .setCreateBy(LoginUserHolder.getUserId())
                .setCreateTime(new Date())
                .setUpdateBy(LoginUserHolder.getUserId())
                .setUpdateTime(new Date());
        logisticsOrderUnitMapper.insert(consignUnit);
    }

    /**
     * 分包托运-承运订单-合同信息
     *
     * @param bo
     * @param orderId
     */
    private void insertSubcontractLogisticsOrderContract(SubcontractConsignmentDTO bo, Long orderId) {
        KwtLogisticsOrderContract kwtLogisticsOrderContract = new KwtLogisticsOrderContract();
        kwtLogisticsOrderContract.setId(new IdWorker(NumberConstant.ONE).nextId());
        kwtLogisticsOrderContract.setLOrderId(orderId);
        kwtLogisticsOrderContract.setContractId(Long.parseLong(bo.getContractId()));
        kwtLogisticsOrderContract.setRemark(bo.getRemark());
        kwtLogisticsOrderContract.setCreateBy(LoginUserHolder.getUserId());
        kwtLogisticsOrderContract.setUpdateBy(LoginUserHolder.getUserId());
        kwtLogisticsOrderContract.setCreateTime(new Date());
        kwtLogisticsOrderContract.setUpdateTime(new Date());
        kwtLogisticsOrderContractMapper.insert(kwtLogisticsOrderContract);
    }

    /**
     * 分包托运-承运订单-主体
     *
     * @param bo             页面填写分包数据
     * @param lOrderNo       当前分包物流订单编号
     * @param order          当前物流订单数据
     * @param orderId        当前订单主键id
     * @param pids           组装的pids
     * @param orderStatus    当前单据状态
     * @param logisticsOrder 父级物流订单
     */
    private void insertSubcontractLogisticsOrder(SubcontractConsignmentDTO bo, String lOrderNo,
                                                 KwtLogisticsOrder order,
                                                 Long orderId, String pids, Integer orderStatus, KwtLogisticsOrder logisticsOrder) {
        order.setId(orderId);
        order.setEntId(LoginUserHolder.getEntId());
        order.setType(logisticsOrder.getType());
        order.setTOrderId(logisticsOrder.getTOrderId());
        order.setTOrderNo(logisticsOrder.getTOrderNo());
        order.setLOrderNo(lOrderNo);
        //分包时,存放分包上级id
        order.setPid(Long.parseLong(bo.getLOrderId()));
        //存放所有的分包的父级id
        order.setPids(pids);
        order.setSettlementCycle(bo.getSettlementCycle());
        order.setPrice(new BigDecimal(bo.getPrice()));
        order.setPriceType(remoteSystemService.queryDictByTypeAndValue(DictTypeEnum.PRICE_TYPE.getType(), bo.getPriceType()) == null ?
                null : Long.parseLong(remoteSystemService.queryDictByTypeAndValue(DictTypeEnum.PRICE_TYPE.getType(), bo.getPriceType()).getValue()));
        order.setAmount(new BigDecimal(bo.getCarryingCapacity()));
        order.setBillingMode(bo.getBillingMode());
        order.setLoss(bo.getLoss());
//        order.setLossUnit(bo.getLossUnit());
        order.setLossUnit(remoteSystemService.queryDictByTypeAndValue(DictTypeEnum.UNIT_TYPE.getType(), bo.getLossUnit()) == null ?
                null : remoteSystemService.queryDictByTypeAndValue(DictTypeEnum.UNIT_TYPE.getType(), bo.getLossUnit()).getValue());
        order.setGoodsPrice(new BigDecimal(bo.getGoodsPrice()));
        order.setGoodsPriceUnit(remoteSystemService.queryDictByTypeAndValue(DictTypeEnum.PRICE_TYPE.getType(), bo.getGoodsPriceUnit()) == null ?
                null : remoteSystemService.queryDictByTypeAndValue(DictTypeEnum.PRICE_TYPE.getType(), bo.getGoodsPriceUnit()).getValue());
        order.setGoodsPriceUnit(bo.getGoodsPriceUnit());
        order.setStartTime(bo.getShipmentsDateTime());
        order.setEndTime(bo.getReceiveGoodsDateTime());
        order.setRemark(bo.getRemark());
        order.setPayment(Long.parseLong(bo.getPayment()));
        order.setTaxRate(new BigDecimal(bo.getTaxRate()));
        order.setCreateBy(LoginUserHolder.getUserId());
        order.setCreateTime(new Date());
        order.setUpdateBy(LoginUserHolder.getUserId());
        order.setUpdateTime(new Date());
        order.setStatus(orderStatus);
        /**补充默认值*/
        BigDecimal decimal = new BigDecimal(NumberConstant.ZERO);
        order.setEntrustAmount(decimal);
        order.setSubcontractAmount(decimal);
        order.setLoadAmount(decimal);
        order.setUnloadAmount(decimal);
        order.setIgnoreAmount(decimal);
        order.setDeficitPrice(decimal);
        order.setDeficitAmount(decimal);
        kwtLogisticsOrderMapper.insert(order);
    }

    /**
     * 分包托运-承运订单-商品信息
     *
     * @param bo
     * @param lOrderNo
     * @param orderId
     */
    private void insertSubcontractLogisticsGoods(SubcontractConsignmentDTO bo, String lOrderNo, Long orderId) {
        KwtLogisticsOrderGoods kwtLogisticsOrderGoods = new KwtLogisticsOrderGoods();
        kwtLogisticsOrderGoods.setId(new IdWorker(NumberConstant.ONE).nextId());
//        kwtLogisticsOrderGoods.setGoodsId(Long.parseLong(bo.getGoodsId()));
        kwtLogisticsOrderGoods.setGoodsName(bo.getGoodsName());
//        kwtLogisticsOrderGoods.setSkuId(StringUtils.isBlank(bo.getSkuId()) ? null : Long.parseLong(bo.getSkuId()));
        kwtLogisticsOrderGoods.setLOrderId(orderId);
        kwtLogisticsOrderGoods.setLOrderNo(lOrderNo);
        kwtLogisticsOrderGoods.setUpdateBy(LoginUserHolder.getUserId());
        kwtLogisticsOrderGoods.setUpdateTime(new Date());
        kwtLogisticsOrderGoods.setCreateBy(LoginUserHolder.getUserId());
        kwtLogisticsOrderGoods.setCreateTime(new Date());
        kwtLogisticsOrderGoodsMapper.insert(kwtLogisticsOrderGoods);
    }


    /**
     * 是否接单
     *
     * @param orderDTO
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public HttpResult orderTaking(OrderTakingDTO orderDTO) {
        log.info("接单操作接收数据:{}", JSONObject.toJSONString(orderDTO));
        HttpResult result = new HttpResult();
        result.setCode(HttpStatus.SUCCESS_CODE);
        HttpResult httpResult = ValidUtil.serviceValid(orderDTO);
        if (!String.valueOf(httpResult.getCode()).equals(String.valueOf(HttpStatus.SUCCESS_CODE))) {
            result.setMsg(httpResult.getMsg());
            return result;
        }
        KwtLogisticsOrder logisticsOrder = logisticsOrderMapper.selectOne(new LambdaQueryWrapper<KwtLogisticsOrder>()
                .eq(StringUtils.isNotBlank(orderDTO.getLOrderId()), KwtLogisticsOrder::getId, orderDTO.getLOrderId())
                .eq(StringUtils.isNotBlank(orderDTO.getLOrderNo()), KwtLogisticsOrder::getLOrderNo, orderDTO.getLOrderNo())
                .eq(KwtLogisticsOrder::getEntId, LoginUserHolder.getEntId()));
        if (logisticsOrder == null) {
            result.setMsg("单据不存在!");
            return result;
        }
        if (!LogisticsOrderEnum.PENDING_ORDER.getStatus().equals(String.valueOf(logisticsOrder.getStatus()))) {
            result.setMsg("该【" + orderDTO.getLOrderNo() + "】单号并不是待接单状态!");
            return result;
        }
        KwtLogisticsOrderContract contract = kwtLogisticsOrderContractMapper.selectOne(new LambdaQueryWrapper<KwtLogisticsOrderContract>()
                .eq(KwtLogisticsOrderContract::getLOrderId, orderDTO.getLOrderId()));
        if (contract == null) {
            result.setMsg("该订单并未存在合同信息!");
            return result;
        }
        /**
         * 根据合同是否已签约 变更物流订单状态 已签约->待派车  未签约->签约中
         * */
        /**判断生成物流订单应生成哪一种单据状态*/
        List<Long> contractList = new ArrayList<>();
        contractList.add(contract.getContractId());
        Map<Long, ContractCommonInfoResDto> longContractCommonInfoResDtoMap = remoteContractService.queryContractBaseInfo(contractList);
        if (CollectionUtils.isEmpty(longContractCommonInfoResDtoMap)) {
            throw new BusinessException("并未有对应合同,应先签约合同");
        }
        if (longContractCommonInfoResDtoMap.get(contract.getContractId()) == null) {
            throw new BusinessException("并未有对应合同,应先签约合同");
        }
        ContractCommonInfoResDto infoResDto = longContractCommonInfoResDtoMap.get(contract.getContractId());
        /**状态判断
         * 是否是已签约合同
         * */
        // 0 已签约 1待签约
        Integer status = infoResDto.getStatus();
        //todo 2023-08-09 验证必须是合同已签约才能进行接单操作
        if (NumberConstant.ZERO != status) {
            result.setMsg("该订单合同未签约!");
            result.setCode(HttpStatus.GLOBAL_EXCEPTION_CODE);
            return result;
        }
        Integer orderStatus = LogisticsOrderEnum.PENDING_ORDER.getCode();
        if (NumberConstant.ONE == status) {
            orderStatus = LogisticsOrderEnum.PENDING_ORDER.getCode();
        } else if (NumberConstant.ZERO == status) {
            orderStatus = LogisticsOrderEnum.WAIT_DELIVERY.getCode();
        } else {
            log.info("接单 物流订单id:{}," +
                            "物流订单编号:{},合同id:{},合同信息:{}",
                    orderDTO.getLOrderId(), orderDTO.getLOrderNo(),
                    contract.getContractId(), JSONObject.toJSONString(infoResDto));
            throw new RuntimeException("物流订单-接单异常");
        }
        if (orderDTO.getType()) {
            //修改单据状态
            logisticsOrderMapper.update(null, new LambdaUpdateWrapper<KwtLogisticsOrder>()
                    .eq(StringUtils.isNotBlank(orderDTO.getLOrderId()), KwtLogisticsOrder::getId, orderDTO.getLOrderId())
                    .eq(StringUtils.isNotBlank(orderDTO.getLOrderNo()), KwtLogisticsOrder::getLOrderNo, orderDTO.getLOrderNo())
                    .set(KwtLogisticsOrder::getStatus, orderStatus)
                    .set(KwtLogisticsOrder::getUpdateTime, new Date())
                    .set(KwtLogisticsOrder::getUpdateBy, LoginUserHolder.getUserId()));
        } else {
            orderStatus = LogisticsOrderEnum.REJECT_ORDER.getCode();
            //todo 当前为删除订单 后续要改为拒绝接单  数据统计在页面已退回状态中
            //删除订单
            logisticsOrderMapper.update(null, new LambdaUpdateWrapper<KwtLogisticsOrder>()
                    .eq(StringUtils.isNotBlank(orderDTO.getLOrderId()), KwtLogisticsOrder::getId, orderDTO.getLOrderId())
                    .eq(StringUtils.isNotBlank(orderDTO.getLOrderNo()), KwtLogisticsOrder::getLOrderNo, orderDTO.getLOrderNo())
                    .set(KwtLogisticsOrder::getStatus, orderStatus)
                    .set(KwtLogisticsOrder::getUpdateTime, new Date())
                    .set(KwtLogisticsOrder::getUpdateBy, LoginUserHolder.getUserId()));
        }
        //状态表新增状态数据
        KwtLogisticsOrderTrack track = logisticsOrderTrackMapper.selectOne(new LambdaQueryWrapper<KwtLogisticsOrderTrack>()
                .eq(KwtLogisticsOrderTrack::getLOrderId, orderDTO.getLOrderId()).eq(KwtLogisticsOrderTrack::getStatus, orderStatus));
        if (track == null) {
            KwtLogisticsOrderTrack orderTrack = new KwtLogisticsOrderTrack();
            orderTrack.setId(new IdWorker(NumberConstant.ONE).nextId());
            orderTrack.setLOrderId(Long.parseLong(orderDTO.getLOrderId()));
            orderTrack.setRemark(orderDTO.getRemark());
            orderTrack.setStatus(orderStatus);
            orderTrack.setCreateBy(LoginUserHolder.getUserId());
            orderTrack.setCreateTime(new Date());
            orderTrack.setUpdateBy(LoginUserHolder.getUserId());
            orderTrack.setUpdateTime(new Date());
            logisticsOrderTrackMapper.insert(orderTrack);
        } else {
            track.setRemark(orderDTO.getRemark());
            track.setUpdateTime(new Date());
            track.setUpdateBy(LoginUserHolder.getUserId());
            track.setStatus(orderStatus);
            logisticsOrderTrackMapper.updateById(track);
        }
        //修改mongodb状态
        SckwLogisticsOrder order = new SckwLogisticsOrder();
        order.set_id(logisticsOrder.getId());
        order.setLOrderId(logisticsOrder.getId());
        order.setStatus(String.valueOf(orderStatus));
        order.setUpdateTime(new Date());
        order.setUpdateByName(LoginUserHolder.getUserName());
        SckwBusSum busSum = new SckwBusSum();
        busSum.setBusSumType(BusinessTypeEnum.LOGISTICS_ORDER_TYPE.getName());
        busSum.setMethod(NumberConstant.TWO);
        busSum.setObject(order);
        streamBridge.send("sckw-busSum", com.alibaba.fastjson2.JSON.toJSONString(busSum));
        return result;
    }

    /**
     * 承运订单-获取运单详情
     *
     * @param wOrderId
     * @return
     */
    public HttpResult getWaybillData(String wOrderId) {
        SckwWaybillOrder sckwWaybillOrder = mongoTemplate.findById(Long.parseLong(wOrderId), SckwWaybillOrder.class);
        WaybillDetailVO vo = new WaybillDetailVO();
        if (!ObjectUtils.isEmpty(sckwWaybillOrder)) {
            vo.setFleetName(sckwWaybillOrder.getCarrierFirmName());
            vo.setTruckNo(sckwWaybillOrder.getTruckNo());
            vo.setDriverName(sckwWaybillOrder.getDriverName());
            vo.setSendCarWeigh(sckwWaybillOrder.getEntrustAmount());
            vo.setLoadAmount(sckwWaybillOrder.getLoadAmount());
            vo.setStowageDateTime(sckwWaybillOrder.getLoadTime());
            vo.setWaybillType(sckwWaybillOrder.getType());
            vo.setUnloadAmount(sckwWaybillOrder.getUnloadAmount());
            vo.setUnloadDateTime(sckwWaybillOrder.getUnloadTime());
            vo.setAppointor(sckwWaybillOrder.getCreateByName());
            vo.setLoss(sckwWaybillOrder.getLoss());
            vo.setGoodsPrice(sckwWaybillOrder.getGoodsPrice());
            vo.setStartTime(sckwWaybillOrder.getStartTime());
            vo.setEndTime(sckwWaybillOrder.getEndTime());
        }
        return HttpResult.ok(vo);
    }

    /**
     * 获取承运订单-分包托运列表数据
     *
     * @param lOrderIds 物流订单主键id
     * @param page      当前页
     * @param pageSize  每页条数
     * @return
     */
    public HttpResult getSubcontractConsignment(String lOrderIds, Integer page, Integer pageSize) {
        List<String> stringList = StringUtils.splitStrToList(lOrderIds, String.class);
        if (CollectionUtils.isEmpty(stringList)) {
            return HttpResult.ok();
        }
        /**运价方式*/
        Map<String, String> priceDictData = getDictData(DictTypeEnum.PRICE_TYPE.getType());
        /**车载计算方式*/
        Map<String, String> weightDictData = getDictData(DictTypeEnum.WEIGHT_CAR.getType());
        /**签约方式*/
        Map<String, String> singDictData = getDictData(DictTypeEnum.SIGNING_TYPE.getType());
        /**计费方式*/
        Map<String, String> chargingDictData = getDictData(DictTypeEnum.CHARGING_TYPE.getType());
        /**结算周期*/
        Map<String, String> settlementDictData = getDictData(DictTypeEnum.SETTLEMENT_CYCLE.getType());
        List<SubcontractConsignmentVO> allList = new ArrayList<>();
        for (String lOrderId : stringList) {
            List<SubcontractConsignmentVO> list = logisticsOrderMapper.getSubcontractConsignmentNotPage(lOrderId);
            //联查数据
            if (CollectionUtils.isNotEmpty(list)) {
                for (SubcontractConsignmentVO subcontractConsignmentVO : list) {
                    subcontractConsignmentVO.setStatusLabel(CarWaybillEnum.getWaybillOrderDestination(subcontractConsignmentVO.getStatus()));
                    subcontractConsignmentVO.setPriceType(priceDictData == null ? null : priceDictData.get(subcontractConsignmentVO.getPriceType()));
                    subcontractConsignmentVO.setLossUnit(weightDictData == null ? null : weightDictData.get(subcontractConsignmentVO.getLossUnit()));
                    subcontractConsignmentVO.setGoodsPriceUnit(priceDictData == null ? null : priceDictData.get(subcontractConsignmentVO.getGoodsPriceUnit()));
                    //分包托运不需要展示签约方式
//                subcontractConsignmentVO.setContractSigningWay(singDictData == null ? null : singDictData.get(subcontractConsignmentVO.getContractSigningWay()));
                    subcontractConsignmentVO.setBillingMode(chargingDictData == null ? null : chargingDictData.get(subcontractConsignmentVO.getBillingMode()));
                    subcontractConsignmentVO.setSettlementCycle(settlementDictData == null ? null : settlementDictData.get(subcontractConsignmentVO.getSettlementCycle()));
                }
                allList.addAll(list);
            }
        }
        List<SubcontractConsignmentVO> returnList = allList.stream().skip((page - 1) * pageSize).limit(pageSize).collect(Collectors.toList());
        PageResult build = PageResult.build(page, pageSize, allList.stream().count(), returnList);
        return HttpResult.ok(build);
    }


    /**
     * 分包列表下方数据统计
     *
     * @param lOrderId 物流订单id
     * @return
     */
    public HttpResult getSubcontractConsignmentCount(String lOrderId) {
        /**页面数据统计*/
        List<Map> countList = logisticsOrderMapper.countSubcontractConsignmentById(lOrderId);
        return HttpResult.ok(countList);
    }

    public String getDictData(String type, String value) {
        if (ObjectUtils.isEmpty(value)) {
            return null;
        }
        if (remoteSystemService.queryDictByTypeAndValue(type, value) == null) {
            return null;
        } else {
            return remoteSystemService.queryDictByTypeAndValue(type, value).getLabel();
        }
    }

    public Map<String, String> getDictData(String type) {
        Map<String, String> maps = new HashMap<>(NumberConstant.SIXTEEN);
        List<SysDictResDto> list = remoteSystemService.queryDictByType(type);
        if (CollectionUtils.isNotEmpty(list)) {
            maps = list.stream().collect(Collectors.toMap(SysDictResDto::getValue, SysDictResDto::getLabel, (key1, key2) -> key2));
        }
        return maps;
    }

    /**
     * 设置停止接单数据查询
     *
     * @param driverParam
     * @return
     */
    public HttpResult stopDocumentDetail(DriverParam driverParam) {
        HttpResult result = new HttpResult();
        result.setCode(HttpStatus.SUCCESS_CODE);
        HttpResult httpResult = ValidUtil.serviceValid(driverParam);
        if (HttpStatus.SUCCESS_CODE != httpResult.getCode()) {
            result.setMsg(httpResult.getMsg());
            return result;
        }
        /**请求参数校验*/
        checkParam(driverParam);
        List<DriverListVo> list = logisticsOrderMapper.selectDriverListById(driverParam);
        for (DriverListVo driverListVo : list) {
            List<String> objects = new ArrayList<>();
            objects.add(driverListVo.getTruckNo());
            Map<String, RTruckVo> truck = fleetService.findTruck(objects);
            if (!ObjectUtils.isEmpty(truck)) {
                driverListVo.setCarType(truck.get(driverListVo.getDriverId()).getTruckType());
            }
        }
        result.setData(list);
        return result;
    }

    private void checkParam(DriverParam driverParam) {
        if (StringUtils.isNotBlank(driverParam.getDriverName())) {
            if (driverParam.getTruckNo().trim().length() > NumberConstant.TWENTY_FOUR) {
                throw new RuntimeException("司机姓名位数不正确");
            }
            if (!RegularUtils.matchs(RegularUtils.CHINESE, driverParam.getDriverName())) {
                throw new RuntimeException("司机姓名格式不正确");
            }
        }
        //2023-07-25 去除车牌查询格式校验
//        if (StringUtils.isNotBlank(driverParam.getTruckNo())) {
//            int length = driverParam.getTruckNo().trim().length();
//            if (driverParam.getTruckNo().trim().length() > NumberConstant.EIGHT || driverParam.getTruckNo().trim().length() < NumberConstant.SEVEN) {
//                throw new RuntimeException("车牌号位数不正确");
//            }
//            if (driverParam.getTruckNo().trim().length() == NumberConstant.EIGHT) {
//                if (!RegularUtils.matchs(RegularUtils.TRUCK_NUMBER_SIX, driverParam.getTruckNo())) {
//                    throw new RuntimeException("车牌号格式不正确");
//                }
//            } else if (driverParam.getTruckNo().trim().length() == NumberConstant.SEVEN) {
//                if (!RegularUtils.matchs(RegularUtils.TRUCK_NUMBER_FIVE, driverParam.getTruckNo())) {
//                    throw new RuntimeException("车牌号格式不正确");
//                }
//            }
//
//        }
        if (StringUtils.isNotBlank(driverParam.getDriverPhone())) {
            if (driverParam.getDriverPhone().trim().length() > NumberConstant.ELEVEN) {
                throw new RuntimeException("手机号不正确");
            }
            if (!RegularUtils.matchs(RegularUtils.PHONE_REG, driverParam.getDriverPhone())) {
                throw new RuntimeException("手机号格式不正确");
            }
        }
    }

    /**
     * 设置停止接单-针对于循环单
     *
     * @param stopOrderTakingDTO
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public HttpResult stopDocumentCommit(StopOrderTakingDTO stopOrderTakingDTO) {
        List<String> stringList = StringUtils.splitStrToList(stopOrderTakingDTO.getIds(), ",", String.class);
        List<Long> wOrderIds = logisticsOrderCirculateMapper.selectEntityBylOrderIdAndOrderIds(stopOrderTakingDTO.getLOrderId(), stringList);
        List<JSONObject> list = new ArrayList<>(stringList.size());
        if (CollectionUtils.isNotEmpty(wOrderIds)) {
            wOrderIds.forEach(wOrderId -> {
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("wOrderId", wOrderId);
                KwtWaybillOrder waybillOrder = waybillOrderMapper.selectOne(new LambdaUpdateWrapper<KwtWaybillOrder>().eq(KwtWaybillOrder::getId, wOrderId));
                if (waybillOrder == null) {
                    jsonObject.put("status", HttpStatus.GLOBAL_EXCEPTION_CODE);
                    jsonObject.put("message", "单据不存在或者单据异常");
                } else {
                    logisticsOrderCirculateMapper.update(null, new LambdaUpdateWrapper<KwtLogisticsOrderCirculate>()
                            .set(KwtLogisticsOrderCirculate::getStatus, NumberConstant.ONE)
                            .eq(KwtLogisticsOrderCirculate::getWOrderId, wOrderId));
//                    /**更新MongoDB*/
                    SckwWaybillOrder order = new SckwWaybillOrder();
                    order.setStatus(NumberConstant.ONE);
                    SckwBusSum busSum = new SckwBusSum();
                    busSum.setBusSumType(BusinessTypeEnum.WAYBILL_ORDER_TYPE.getName());
                    busSum.setMethod(NumberConstant.TWO);
                    busSum.setObject(order);
                    streamBridge.send("sckw-busSum", com.alibaba.fastjson2.JSON.toJSONString(busSum));
                    jsonObject.put("status", HttpStatus.SUCCESS_CODE);
                    jsonObject.put("message", "停止接单成功");
                }
                list.add(jsonObject);
            });
        }
        return HttpResult.ok(list);
    }

    /**
     * 承运订单-取消派车
     *
     * @param ids
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public HttpResult cancelDelivery(List<String> ids) {
        List<JSONObject> list = new ArrayList<>();
        JSONObject result = new JSONObject(NumberConstant.THREE);
        for (String id : ids) {
            result.put("id", id);
            KwtWaybillOrder waybillOrder = waybillOrderMapper.selectOne(new LambdaUpdateWrapper<KwtWaybillOrder>()
                    .eq(KwtWaybillOrder::getId, Long.parseLong(id)).eq(KwtWaybillOrder::getType, NumberConstant.ONE));
            if (waybillOrder == null) {
                result.put("status", HttpStatus.GLOBAL_EXCEPTION_CODE);
                result.put("message", "单据不存在");
                list.add(result);
                continue;
            }
            if (!CarWaybillEnum.PENDING_ORDER.getCode().equals(waybillOrder.getStatus())) {
                result.put("status", HttpStatus.GLOBAL_EXCEPTION_CODE);
                result.put("message", "单据不是待接单状态,不可取消!");
                list.add(result);
                continue;
            }
            /**针对于趟次车，需要将可派单数量溯源回归于物流订单中*/
            KwtLogisticsOrder logisticsOrder = logisticsOrderMapper.selectOne(new LambdaQueryWrapper<KwtLogisticsOrder>()
                    .eq(KwtLogisticsOrder::getId, waybillOrder.getLOrderId()));
            //已委托量
            BigDecimal entrustAmount = logisticsOrder.getEntrustAmount().add(waybillOrder.getEntrustAmount());
            //分包量
            BigDecimal subcontractAmount = logisticsOrder.getSubcontractAmount().subtract(waybillOrder.getEntrustAmount());
            logisticsOrderMapper.update(null, new LambdaUpdateWrapper<KwtLogisticsOrder>()
                    .set(KwtLogisticsOrder::getSubcontractAmount, subcontractAmount)
                    .set(KwtLogisticsOrder::getEntrustAmount, entrustAmount)
                    .set(KwtLogisticsOrder::getUpdateTime, new Date())
                    .set(KwtLogisticsOrder::getUpdateBy, LoginUserHolder.getUserId())
                    .eq(KwtLogisticsOrder::getId, logisticsOrder.getId()));
            waybillOrderMapper.update(null, new LambdaUpdateWrapper<KwtWaybillOrder>()
                    .eq(KwtWaybillOrder::getType, NumberConstant.ONE)
                    .eq(KwtWaybillOrder::getId, Long.parseLong(id))
                    .set(KwtWaybillOrder::getStatus, CarWaybillEnum.REVOKED.getCode())
                    .set(KwtWaybillOrder::getUpdateBy, LoginUserHolder.getUserId())
                    .set(KwtWaybillOrder::getUpdateTime, new Date()));
            /**变更单据状态*/
            KwtWaybillOrderTrack waybillOrderTrack = waybillOrderTrackMapper.selectOne(new LambdaQueryWrapper<KwtWaybillOrderTrack>()
                    .eq(KwtWaybillOrderTrack::getWOrderId, id)
                    .eq(KwtWaybillOrderTrack::getStatus, CarWaybillEnum.REVOKED.getCode())
            );
            if (waybillOrderTrack == null) {
                KwtWaybillOrderTrack orderTrack = new KwtWaybillOrderTrack();
                orderTrack.setId(new IdWorker(NumberConstant.ONE).nextId());
                orderTrack.setWOrderId(Long.parseLong(id));
                orderTrack.setStatus(CarWaybillEnum.REVOKED.getCode());
                orderTrack.setDelFlag(NumberConstant.ZERO);
                orderTrack.setCreateBy(LoginUserHolder.getUserId());
                orderTrack.setCreateTime(new Date());
                orderTrack.setUpdateBy(LoginUserHolder.getUserId());
                orderTrack.setUpdateTime(new Date());
                waybillOrderTrackMapper.insert(orderTrack);
            }else {
                waybillOrderTrack.setUpdateTime(new Date());
                waybillOrderTrack.setUpdateBy(LoginUserHolder.getUserId());
                waybillOrderTrackMapper.updateById(waybillOrderTrack);
            }

            /**修改mongodb*/
            //mongodb更新订单状态
            SckwWaybillOrder updateParam = new SckwWaybillOrder();
            updateParam.setWOrderId(Long.parseLong(id)).setStatus(CarWaybillEnum.REVOKED.getCode())
                    .setUpdateBy(LoginUserHolder.getUserId()).setUpdateByName(LoginUserHolder.getUserName()).setUpdateTime(new Date());
            SckwBusSum busSum = new SckwBusSum();
            busSum.setBusSumType(BusinessTypeEnum.WAYBILL_ORDER_TYPE.getName());
            busSum.setMethod(NumberConstant.TWO);
            busSum.setObject(updateParam);
            streamBridge.send("sckw-busSum", com.alibaba.fastjson2.JSON.toJSONString(busSum));
            SckwLogisticsOrder order = new SckwLogisticsOrder();
            order.set_id(logisticsOrder.getId());
            order.setLOrderId(logisticsOrder.getId());
            order.setEntrustAmount(entrustAmount);
            order.setSubcontractAmount(subcontractAmount);
            order.setUpdateByName(LoginUserHolder.getUserName());
            order.setUpdateTime(new Date());
            SckwBusSum orderBusSum = new SckwBusSum();
            orderBusSum.setBusSumType(BusinessTypeEnum.LOGISTICS_ORDER_TYPE.getName());
            orderBusSum.setMethod(NumberConstant.TWO);
            orderBusSum.setObject(order);
            streamBridge.send("sckw-busSum", com.alibaba.fastjson2.JSON.toJSONString(busSum));
            result.put("status", HttpStatus.SUCCESS_CODE);
            result.put("message", "取消成功");
            list.add(result);
        }
        return HttpResult.ok(list);
    }

    /**
     * 承运订单-分包托运-完结订单
     *
     * @param orderFinishDTO
     * @return
     */
    public HttpResult commitAcceptCarriageOrderFinish(OrderFinishDTO orderFinishDTO) {
        /** 订单完结 物流运单状态为【待派车】、【运输中】可操作*/
        /**完结拦截 必须车辆运单无正在运输中的单据才能完结 状态有 待接单之后已核弹之前的状态 都不能完结*/
        /**完结订单-对应物流订单下子订单都要进行完结*/
        /**完结订单 不做页面填写数量与数据库数量进行计算验证-直接获取页面填写数据进行保存处理*/
        //物流订单id
        String id = orderFinishDTO.getId();
        KwtLogisticsOrder logisticsOrder = kwtLogisticsOrderMapper.selectOne(new LambdaQueryWrapper<KwtLogisticsOrder>()
                .eq(KwtLogisticsOrder::getId, id));
        if (logisticsOrder == null) {
            throw new RuntimeException("承运订单-完结订单-物流单据不存在!");
        }
        if (logisticsOrder.getLoadAmount().compareTo(orderFinishDTO.getLoadAmount()) > 0) {
            throw new BusinessException("完结订单,实装量不能大于分配量");
        }
        /**订单状态验证*/
        if (!LogisticsOrderEnum.WAIT_DELIVERY.getStatus().equals(String.valueOf(logisticsOrder.getStatus()))
                && !LogisticsOrderEnum.IN_TRANSIT.getStatus().equals(String.valueOf(logisticsOrder.getStatus()))) {
            throw new RuntimeException("当前运单并不属于【待派车】,【运输中】状态");
        }
        /**完结拦截*/
        List<Integer> statusList = new ArrayList<>();
        statusList.add(CarWaybillEnum.PENDING_VEHICLE.getCode());
        statusList.add(CarWaybillEnum.EXIT_COMPLETED.getCode());
        statusList.add(CarWaybillEnum.WAIT_LOADING.getCode());
        statusList.add(CarWaybillEnum.COMPLETION_LOADING.getCode());
        statusList.add(CarWaybillEnum.WAIT_UNLOADING.getCode());
        statusList.add(CarWaybillEnum.COMPLETION_UNLOADING.getCode());
        int count = waybillOrderMapper.selectDataByLorderId(id, statusList);
        if (count > NumberConstant.ZERO) {
            throw new RuntimeException("检测您现在有运单正在执行中,该订单目前不可完结,请先将运单执行完毕");
        }
        /**完结订单-对应物流订单下子订单都要进行完结*/
        List<KwtLogisticsOrder> kwtLogisticsOrders = kwtLogisticsOrderMapper.selectList(new LambdaQueryWrapper<KwtLogisticsOrder>()
                .in(KwtLogisticsOrder::getPids, Long.parseLong(orderFinishDTO.getId())));
        if (CollectionUtils.isNotEmpty(kwtLogisticsOrders)) {
            for (KwtLogisticsOrder kwtLogisticsOrder : kwtLogisticsOrders) {
                String[] split = kwtLogisticsOrder.getPids().split(StringConstant.COMMA);
                if (split.length > NumberConstant.ONE) {
                    for (String s : split) {
                        if (String.valueOf(kwtLogisticsOrder.getId()).equals(s)) {
                            //本身订单
                            //只存在当前订单无分包订单
                            /**单据完结修改状态以及数据*/
                            updateDataByItself(logisticsOrder, orderFinishDTO);
                        } else {
                            //修改分包后的订单-代表存在分包订单
                            /**单据完结修改状态以及数据*/
                            updateDataBySubset(orderFinishDTO, s);
                        }
                    }
                } else {
                    //只存在当前订单无分包订单
                    /**单据完结修改状态以及数据*/
                    updateDataByItself(logisticsOrder, orderFinishDTO);
                }
            }
        }
        return HttpResult.ok("承运订单-分包托运完结订单成功");
    }


    /**
     * 承运订单-分包托运-完结订单-修改本身数据
     *
     * @param logisticsOrder 本身物流订单数据
     * @param orderFinishDTO 页面传递数据
     */
    private void updateDataByItself(KwtLogisticsOrder logisticsOrder, OrderFinishDTO orderFinishDTO) {
        logisticsOrder.setStatus(LogisticsOrderEnum.HAVE_FINISHED.getCode());
        logisticsOrder.setLoadAmount(orderFinishDTO.getLoadAmount());
        logisticsOrder.setUnloadAmount(orderFinishDTO.getUnloadAmount());
        logisticsOrder.setUpdateBy(LoginUserHolder.getUserId());
        logisticsOrder.setUpdateTime(new Date());
        logisticsOrder.setRemark(orderFinishDTO.getRemark());
        kwtLogisticsOrderMapper.updateById(logisticsOrder);
        KwtLogisticsOrderTrack track = new KwtLogisticsOrderTrack();
        track.setId(new IdWorker(NumberConstant.ONE).nextId());
        track.setLOrderId(logisticsOrder.getId());
        track.setStatus(LogisticsOrderEnum.HAVE_FINISHED.getCode());
        track.setCreateTime(new Date());
        track.setRemark(orderFinishDTO.getRemark());
        track.setCreateBy(LoginUserHolder.getUserId());
        track.setUpdateBy(LoginUserHolder.getUserId());
        track.setUpdateTime(new Date());
        logisticsOrderTrackMapper.insert(track);
        /**单据完结修改Mongodb*/
        SckwLogisticsOrder updateParam = new SckwLogisticsOrder();
        updateParam.setLOrderId(Long.parseLong(orderFinishDTO.getId()))
                .setStatus(LogisticsOrderEnum.HAVE_FINISHED.getStatus())
                .setUpdateBy(LoginUserHolder.getUserId())
                .setUpdateByName(LoginUserHolder.getUserName())
                .setUpdateTime(new Date())
                .setLoadAmount(orderFinishDTO.getLoadAmount())
                .setUnloadAmount(orderFinishDTO.getUnloadAmount())
        ;
        SckwBusSum busSum = new SckwBusSum();
        busSum.setBusSumType(BusinessTypeEnum.LOGISTICS_ORDER_TYPE.getName());
        busSum.setMethod(2);
        busSum.setObject(updateParam);
        streamBridge.send("sckw-busSum", com.alibaba.fastjson2.JSON.toJSONString(busSum));
    }

    /**
     * 承运订单-分包托运-完结订单-修改分包订单
     *
     * @param orderFinishDTO
     * @param orderId        分包物流订单id
     */
    private void updateDataBySubset(OrderFinishDTO orderFinishDTO, String orderId) {
        KwtLogisticsOrder kwtLogisticsOrder = kwtLogisticsOrderMapper.selectOne(new LambdaQueryWrapper<KwtLogisticsOrder>()
                .eq(KwtLogisticsOrder::getId, Long.parseLong(orderId)));
        if (kwtLogisticsOrder != null) {
            kwtLogisticsOrder.setStatus(LogisticsOrderEnum.HAVE_FINISHED.getCode());
            kwtLogisticsOrder.setUpdateBy(LoginUserHolder.getUserId());
            kwtLogisticsOrder.setUpdateTime(new Date());
            kwtLogisticsOrder.setRemark(orderFinishDTO.getRemark());
            kwtLogisticsOrderMapper.updateById(kwtLogisticsOrder);
            KwtLogisticsOrderTrack track = new KwtLogisticsOrderTrack();
            track.setId(new IdWorker(NumberConstant.ONE).nextId());
            track.setLOrderId(kwtLogisticsOrder.getId());
            track.setStatus(LogisticsOrderEnum.HAVE_FINISHED.getCode());
            track.setCreateTime(new Date());
            track.setRemark(orderFinishDTO.getRemark());
            track.setCreateBy(LoginUserHolder.getUserId());
            track.setUpdateBy(LoginUserHolder.getUserId());
            track.setUpdateTime(new Date());
            logisticsOrderTrackMapper.insert(track);
            /**单据完结修改Mongodb*/
            SckwLogisticsOrder updateParam = new SckwLogisticsOrder();
            updateParam.setLOrderId(kwtLogisticsOrder.getId())
                    .setStatus(LogisticsOrderEnum.HAVE_FINISHED.getStatus())
                    .setUpdateBy(LoginUserHolder.getUserId())
                    .setUpdateByName(LoginUserHolder.getUserName())
                    .setUpdateTime(new Date())
            ;
            SckwBusSum busSum = new SckwBusSum();
            busSum.setBusSumType(BusinessTypeEnum.LOGISTICS_ORDER_TYPE.getName());
            busSum.setMethod(2);
            busSum.setObject(updateParam);
            streamBridge.send("sckw-busSum", com.alibaba.fastjson2.JSON.toJSONString(busSum));
        }
    }

    /**
     * 承运订单-获取撤销驳回原因
     *
     * @param id 物流订单id
     * @return
     */
    public HttpResult getCancelReason(String id) {
        KwtLogisticsOrderTrack track = logisticsOrderTrackMapper.selectOne(new LambdaQueryWrapper<KwtLogisticsOrderTrack>()
                .eq(KwtLogisticsOrderTrack::getLOrderId, Long.parseLong(id))
                .eq(KwtLogisticsOrderTrack::getStatus, LogisticsOrderEnum.SEND_BACK.getCode()));
        return HttpResult.ok(track == null ? null : track.getRemark());
    }

    /**
     * 承运订单-分包托运-订单详情
     *
     * @param id 物流订单id
     * @return
     */
    public HttpResult subcontractConsignmentOrderDetail(String id) {
        KwtLogisticsOrder logisticsOrder = logisticsOrderMapper.selectOne(new LambdaQueryWrapper<KwtLogisticsOrder>()
                        .eq(KwtLogisticsOrder::getId, Long.parseLong(id))
                /**.eq(KwtLogisticsOrder::getEntId, LoginUserHolder.getEntId())*/);
        if (logisticsOrder == null) {
            log.info("查无单据 物流订单id:{}", id);
            throw new RuntimeException("查无单据");
        }
        KwtLogisticsOrderContract contract = kwtLogisticsOrderContractMapper.selectOne(new LambdaQueryWrapper<KwtLogisticsOrderContract>()
                .eq(StringUtils.isNotBlank(Long.parseLong(id)), KwtLogisticsOrderContract::getLOrderId, Long.parseLong(id)));
        KwtLogisticsOrderUnit unitOne = logisticsOrderUnitMapper.selectOne(new LambdaQueryWrapper<KwtLogisticsOrderUnit>()
                .eq(StringUtils.isNotBlank(Long.parseLong(id)), KwtLogisticsOrderUnit::getLOrderId, Long.parseLong(id))
                .eq(KwtLogisticsOrderUnit::getUnitType, NumberConstant.ONE));
        KwtLogisticsOrderUnit unitTwo = logisticsOrderUnitMapper.selectOne(new LambdaQueryWrapper<KwtLogisticsOrderUnit>()
                .eq(StringUtils.isNotBlank(Long.parseLong(id)), KwtLogisticsOrderUnit::getLOrderId, Long.parseLong(id))
                .eq(KwtLogisticsOrderUnit::getUnitType, NumberConstant.TWO));
        KwtLogisticsOrderAddress loadOrderAddress = logisticsOrderAddressMapper.selectOne(new LambdaQueryWrapper<KwtLogisticsOrderAddress>()
                .eq(StringUtils.isNotBlank(Long.parseLong(id)), KwtLogisticsOrderAddress::getLOrderId, Long.parseLong(id))
                .eq(KwtLogisticsOrderAddress::getAddressType, NumberConstant.ONE));
        KwtLogisticsOrderAddress unloadOrderAddress = logisticsOrderAddressMapper.selectOne(new LambdaQueryWrapper<KwtLogisticsOrderAddress>()
                .eq(StringUtils.isNotBlank(Long.parseLong(id)), KwtLogisticsOrderAddress::getLOrderId, Long.parseLong(id))
                .eq(KwtLogisticsOrderAddress::getAddressType, NumberConstant.TWO));
        KwtLogisticsOrderGoods orderGoods = kwtLogisticsOrderGoodsMapper.selectOne(new LambdaQueryWrapper<KwtLogisticsOrderGoods>()
                .eq(StringUtils.isNotBlank(logisticsOrder.getId()), KwtLogisticsOrderGoods::getLOrderId, logisticsOrder.getId()));
        OrderDetailVO orderDetailVO = new OrderDetailVO();
        orderDetailVO.setId(String.valueOf(logisticsOrder.getId()));
        if (contract != null) {
            orderDetailVO.setContractId(contract.getContractId() == null ? null : String.valueOf(contract.getContractId()));
            //todo 接口调用合同服务查询合同信息
            List<Long> list = new ArrayList<>(NumberConstant.SIXTEEN);
            list.add(contract.getContractId());
            Map<Long, ContractCommonInfoResDto> contractBaseInfo = remoteContractService.queryContractBaseInfo(list);
            if (CollectionUtils.isNotEmpty(contractBaseInfo) && !ObjectUtils.isEmpty(contractBaseInfo.get(contract.getContractId()))) {
                orderDetailVO.setContractName(contractBaseInfo.get(contract.getContractId()).getContactName());
                orderDetailVO.setContractNo(contractBaseInfo.get(contract.getContractId()).getContractCode());
            }
        }
        if (unitOne != null) {
            orderDetailVO.setConsignCompanyId(unitOne.getId());
            orderDetailVO.setConsignCompany(unitOne.getFirmName());
            orderDetailVO.setConsignContacts(unitOne.getContacts());
            orderDetailVO.setConsignPhone(unitOne.getPhone());
            orderDetailVO.setCollectionCompany(unitOne.getFirmName());
        }
        if (unitTwo != null) {
            orderDetailVO.setCarrierCompanyId(unitTwo.getId());
            orderDetailVO.setCarrierCompany(unitTwo.getFirmName());
            orderDetailVO.setCarrierContacts(unitTwo.getContacts());
            orderDetailVO.setCarrierPhone(unitTwo.getPhone());
        }
        orderDetailVO.setGoodsName(orderGoods == null ? null : orderGoods.getGoodsName());
        orderDetailVO.setNumber(logisticsOrder.getAmount() == null ? null : String.valueOf(logisticsOrder.getAmount()));
        orderDetailVO.setPrice(logisticsOrder.getPrice() == null ? null : String.valueOf(logisticsOrder.getPrice()));
        orderDetailVO.setLoss(logisticsOrder.getLoss() == null ? null : String.valueOf(logisticsOrder.getLoss()));
        orderDetailVO.setDeduct(logisticsOrder.getGoodsPrice() == null ? null : String.valueOf(logisticsOrder.getGoodsPrice()));
        orderDetailVO.setLoadAddress(loadOrderAddress.getName());
        orderDetailVO.setLoadContacts(loadOrderAddress.getContacts());
        orderDetailVO.setLoadPhone(loadOrderAddress.getPhone());
        orderDetailVO.setLoadAddressDetail(loadOrderAddress.getDetailAddress());
        orderDetailVO.setUnloadAddress(unloadOrderAddress.getName());
        orderDetailVO.setUnloadContacts(unloadOrderAddress.getContacts());
        orderDetailVO.setUnloadPhone(unloadOrderAddress.getPhone());
        orderDetailVO.setUnloadAddressDetail(unloadOrderAddress.getDetailAddress());
        orderDetailVO.setSettlementCycle(logisticsOrder.getSettlementCycle() == null ? null : String.valueOf(logisticsOrder.getSettlementCycle()));
        orderDetailVO.setBillingMode(logisticsOrder.getBillingMode());
        orderDetailVO.setScheduleStartTime(logisticsOrder.getStartTime() == null ? null : DateUtil.getDateTime(logisticsOrder.getStartTime()));
        orderDetailVO.setScheduleEndTime(logisticsOrder.getEndTime() == null ? null : DateUtil.getDateTime(logisticsOrder.getEndTime()));
        orderDetailVO.setPerformanceAmount(logisticsOrder.getLoadAmount() == null ? null : String.valueOf(logisticsOrder.getLoadAmount()));
        return HttpResult.ok(orderDetailVO);
    }

    /**
     * 承运订单-完结订单-数据查询展示
     *
     * @param orderId 物流订单id
     * @return
     */
    public HttpResult acceptCarriageOrderFinishDetail(String orderId) {
        OrderFinishVO orderFinishVO = kwtLogisticsOrderMapper.selectOrderFinishData(orderId);
        return HttpResult.ok(orderFinishVO);
    }

    /**
     * 承运订单-页面新建订单
     *
     * @param orderDTO
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public HttpResult addOrder(AddOrderDTO orderDTO) throws ParseException {
        HttpResult httpResult = ValidUtil.serviceValid(orderDTO);
        if (!String.valueOf(HttpStatus.SUCCESS_CODE).equals(String.valueOf(httpResult.getCode()))) {
            return HttpResult.error(httpResult.getMsg());
        }
        checkAddOrderParam(orderDTO);
        /**保存新建数据*/
        Long lOrderId = new IdWorker(NumberConstant.ONE).nextId();
        /**生成订单编号*/
        String lOrderNo = com.sckw.transport.utils.StringUtils.getLOrderNo();
        /**根据合同计算当前单据状态*/
        /**判断生成物流订单应生成哪一种单据状态*/
        List<Long> contractList = new ArrayList<>();
        contractList.add(Long.parseLong(orderDTO.getContractId()));
        Map<Long, ContractCommonInfoResDto> longContractCommonInfoResDtoMap = remoteContractService.queryContractBaseInfo(contractList);
        if (CollectionUtils.isEmpty(longContractCommonInfoResDtoMap)) {
            throw new RuntimeException("承运订单新建订单-并未有对应合同,应先签约合同");
        }
        if (longContractCommonInfoResDtoMap.get(Long.parseLong(orderDTO.getContractId())) == null) {
            throw new RuntimeException("承运订单新建订单-并未有对应合同,应先签约合同");
        }
        ContractCommonInfoResDto infoResDto = longContractCommonInfoResDtoMap.get(Long.parseLong(orderDTO.getContractId()));
        /**状态判断
         * 是否是已签约合同
         * */
        // 0 已签约 1待签约
        Integer status = infoResDto.getStatus();
        Integer orderStatus = LogisticsOrderEnum.PENDING_ORDER.getCode();
        if (NumberConstant.ONE == status) {
            orderStatus = LogisticsOrderEnum.TO_BE_PLANNED.getCode();
        } else if (NumberConstant.ZERO == status) {
            orderStatus = LogisticsOrderEnum.WAIT_DELIVERY.getCode();
        } else {
            log.info("承运订单创建订单异常");
            throw new RuntimeException("自建订单异常");
        }
        /**2023-08-04 自建订单商品可以不需要关联查询*/
//        /**获取商品信息*/
//        KwpGoods goods = goodsInfoService.getGoodsById(Long.parseLong(orderDTO.getGoodsId()));
//        if (goods == null) {
//            log.info("自建订单获取商品信息失败 商品id:{},商品名称:{}", orderDTO.getGoodsId(), orderDTO.getGoodsName());
//            throw new BusinessException("商品信息获取失败");
//        }
        saveLogisticsOrder(orderDTO, lOrderId, orderStatus, lOrderNo);
        saveLogisticsOrderAddress(orderDTO, lOrderId);
        saveLogisticsOrderGoods(orderDTO, lOrderId, lOrderNo);
        saveLogisticsOrderContract(orderDTO, lOrderId);
        saveLogisticsOrderTrack(lOrderId, orderStatus);
        saveLogisticsOrderUnit(orderDTO, lOrderId);
        saveMongoDb(orderDTO, orderStatus, lOrderId, lOrderNo, infoResDto);
        return HttpResult.ok();
    }

    /**
     * 承运订单-页面新增订单-商品信息
     *
     * @param orderDTO 页面参数
     * @param lOrderId 订单id
     * @param lOrderNo 订单编号
     */
    private void saveLogisticsOrderGoods(AddOrderDTO orderDTO, Long lOrderId, String lOrderNo) {
        KwtLogisticsOrderGoods goods = new KwtLogisticsOrderGoods();
        goods.setId(new IdWorker(NumberConstant.ONE).nextId());
        goods.setLOrderId(lOrderId);
        goods.setLOrderNo(lOrderNo);
//        goods.setGoodsId();
        goods.setGoodsName(orderDTO.getGoodsName());
        goods.setStatus(NumberConstant.ZERO);
        goods.setCreateBy(LoginUserHolder.getUserId());
        goods.setCreateTime(new Date());
        goods.setUpdateBy(LoginUserHolder.getUserId());
        goods.setUpdateTime(new Date());
        kwtLogisticsOrderGoodsMapper.insert(goods);
    }

    /**
     * 校验请求参数
     *
     * @param orderDTO
     */
    private void checkAddOrderParam(AddOrderDTO orderDTO) {
        if (!ObjectUtils.isEmpty(orderDTO.getTaxRate())) {
            if (orderDTO.getTaxRate().compareTo(new BigDecimal(NumberConstant.ZERO)) < 0) {
                throw new BusinessException("税率填写格式错误!");
            }
        }
        if (!ObjectUtils.isEmpty(orderDTO.getLoss())) {
            if (orderDTO.getLoss().compareTo(new BigDecimal(NumberConstant.ZERO)) < 0) {
                throw new BusinessException("合理损耗填写格式错误!");
            }
        }
        if (!ObjectUtils.isEmpty(orderDTO.getGoodsPrice())) {
            if (orderDTO.getGoodsPrice().compareTo(new BigDecimal(NumberConstant.ZERO)) < 0) {
                throw new BusinessException("扣亏货值填写格式错误!");
            }
        }
    }

    /**
     * 承运订单-新建订单-保存mongodb
     *
     * @param orderDTO    页面请求参数
     * @param orderStatus 主体单据状态
     * @param lOrderId    主体订单id
     * @param lOrderNo    主体订单编号
     * @param infoResDto  合同信息
     */
    private void saveMongoDb(AddOrderDTO orderDTO, Integer orderStatus, Long lOrderId, String lOrderNo, ContractCommonInfoResDto infoResDto) {
        SckwLogisticsOrder order = new SckwLogisticsOrder();
        order.set_id(lOrderId);
        order.setLOrderId(lOrderId);
        order.setLOrderNo(lOrderNo);
        order.setLOrderPid(null);
        order.setLOrderPids(String.valueOf(lOrderId));
        order.setType(NumberConstant.TWO);
        order.setSettlementCycle(orderDTO.getSettlementCycle());
        order.setPrice(orderDTO.getPrice());
        order.setPriceType(order.getPriceType());
        order.setAmount(orderDTO.getAmount());
        order.setUnit(orderDTO.getAmountUnit());
        order.setLoss(orderDTO.getLoss());
        order.setLossUnit(orderDTO.getLossUnit());
        order.setGoodsPrice(orderDTO.getGoodsPrice() == null ? null : orderDTO.getGoodsPrice());
        order.setGoodsPriceUnit(orderDTO.getGoodsPriceUnit());
        BigDecimal decimal = new BigDecimal(NumberConstant.ZERO);
        order.setSubcontractAmount(decimal);
        order.setEntrustAmount(decimal);
        order.setUnloadAmount(decimal);
        order.setLoadAmount(decimal);
        order.setIgnoreAmount(decimal);
        order.setDeficitAmount(decimal);
        order.setDeficitPrice(decimal);
        order.setPayment(orderDTO.getPayment());
        order.setTaxRate(orderDTO.getTaxRate());
        order.setRemark(orderDTO.getRemark());
        order.setStatus(String.valueOf(orderStatus));
        order.setEntId(LoginUserHolder.getEntId());
        order.setFirmName(LoginUserHolder.getEntName());
//        order.setGoodsId(Long.parseLong(orderDTO.getGoodsId()));
//        order.setGoodsCode(goods == null ? null : goods.getCode());
        order.setGoodsName(orderDTO.getGoodsName());
//        order.setGoodsType(goods == null ? null : goods.getGoodsType());
////        order.setGoodsIndustry(goods == null ? null : goods.get);
//        order.setGoodsSpec(goods == null ? null : goods.getSpec());
        order.setContractId(orderDTO.getContractId());
        order.setContractNo(infoResDto.getContractCode());
        order.setContractName(infoResDto.getContactName());
        order.setContractSigningWay(String.valueOf(infoResDto.getSigningWay()));
        order.setCheckEntId(Long.parseLong(orderDTO.getConsignCompanyId()));
        order.setCheckFirmName(orderDTO.getConsignCompany());
        order.setCheckContacts(orderDTO.getConsignContacts());
        order.setCheckPhone(orderDTO.getConsignContactPhone());
        order.setCarrierEntId(Long.parseLong(orderDTO.getAcceptCompanyId()));
        order.setCarrierFirmName(orderDTO.getAcceptCompany());
        order.setCarrierContacts(orderDTO.getAcceptContacts());
        order.setCarrierPhone(orderDTO.getAcceptContactPhone());
//        order.setLoadType();
        order.setLoadContacts(orderDTO.getLoadContacts());
        order.setLoadPhone(orderDTO.getLoadPhone());
        order.setLoadCityCode(orderDTO.getLoadCityCode());
        order.setLoadCityName(orderDTO.getLoadCityName());
        order.setLoadDetailAddress(orderDTO.getLoadDetailAddress());
        order.setLoadLat(orderDTO.getLoadLat());
        order.setLoadLng(orderDTO.getLoadLng());
//        order.setUnloadType();
        order.setUnloadContacts(orderDTO.getUnloadContacts());
        order.setUnloadPhone(orderDTO.getUnloadPhone());
        order.setUnloadCityCode(orderDTO.getUnloadCityCode());
        order.setUnloadCityName(orderDTO.getUnloadCityName());
        order.setUnloadDetailAddress(orderDTO.getUnloadDetailAddress());
        order.setUnloadLat(orderDTO.getUnloadLat());
        order.setUnloadLng(orderDTO.getUnloadLng());
        order.setCreateBy(LoginUserHolder.getUserId());
        order.setCreateByName(LoginUserHolder.getUserName());
        order.setCreateTime(new Date());
        order.setUpdateBy(LoginUserHolder.getUserId());
        order.setUpdateByName(LoginUserHolder.getUserName());
        order.setUpdateTime(new Date());
        order.setWOrderNo(lOrderNo);
        order.setCarryingCapacity(orderDTO.getAmount().longValue());
        order.setBillingMode(orderDTO.getBillingMode());
        SckwBusSum busSum = new SckwBusSum();
        busSum.setBusSumType(BusinessTypeEnum.LOGISTICS_ORDER_TYPE.getName());
        busSum.setMethod(NumberConstant.ONE);
        busSum.setObject(order);
        streamBridge.send("sckw-busSum", com.alibaba.fastjson2.JSON.toJSONString(busSum));

    }

    /**
     * 承运订单-页面新增订单-订单对应企业单位
     *
     * @param orderDTO 页面请求参数
     * @param lOrderId 主体id
     */
    private void saveLogisticsOrderUnit(AddOrderDTO orderDTO, Long lOrderId) {
        //托运
        KwtLogisticsOrderUnit consignUnit = new KwtLogisticsOrderUnit();
        consignUnit.setId(new IdWorker(NumberConstant.ONE).nextId());
        consignUnit.setLOrderId(lOrderId);
        consignUnit.setUnitType(NumberConstant.ONE);
        consignUnit.setEntId(Long.parseLong(orderDTO.getConsignCompanyId()));
        consignUnit.setFirmName(orderDTO.getConsignCompany());
        consignUnit.setContacts(orderDTO.getConsignContacts());
        consignUnit.setPhone(orderDTO.getConsignContactPhone());
        consignUnit.setRemark(orderDTO.getRemark());
        consignUnit.setStatus(NumberConstant.ZERO);
        consignUnit.setCreateBy(LoginUserHolder.getUserId());
        consignUnit.setCreateTime(new Date());
        consignUnit.setUpdateBy(LoginUserHolder.getUserId());
        consignUnit.setUpdateTime(new Date());
        //承运
        KwtLogisticsOrderUnit unit = new KwtLogisticsOrderUnit();
        unit.setId(new IdWorker(NumberConstant.TWO).nextId());
        unit.setLOrderId(lOrderId);
        unit.setUnitType(NumberConstant.TWO);
        unit.setEntId(Long.parseLong(orderDTO.getAcceptCompanyId()));
        unit.setFirmName(orderDTO.getAcceptCompany());
        unit.setContacts(orderDTO.getAcceptContacts());
        unit.setPhone(orderDTO.getAcceptContactPhone());
        unit.setRemark(orderDTO.getRemark());
        unit.setStatus(NumberConstant.ZERO);
        unit.setCreateBy(LoginUserHolder.getUserId());
        unit.setCreateTime(new Date());
        unit.setUpdateBy(LoginUserHolder.getUserId());
        unit.setUpdateTime(new Date());
        logisticsOrderUnitMapper.insert(consignUnit);
        logisticsOrderUnitMapper.insert(unit);

    }

    /**
     * 承运订单-页面新增订单-订单状态
     *
     * @param lOrderId    主体id
     * @param orderStatus 主体单据状态
     */
    private void saveLogisticsOrderTrack(Long lOrderId, Integer orderStatus) {
        KwtLogisticsOrderTrack track = new KwtLogisticsOrderTrack();
        track.setId(new IdWorker(NumberConstant.ONE).nextId());
        track.setLOrderId(lOrderId);
        track.setStatus(orderStatus);
        track.setCreateBy(LoginUserHolder.getUserId());
        track.setCreateTime(new Date());
        track.setUpdateBy(LoginUserHolder.getUserId());
        track.setUpdateTime(new Date());
        logisticsOrderTrackMapper.insert(track);
    }

    /**
     * 承运订单-新建订单-地址信息保存
     *
     * @param orderDTO 页面请求参数
     * @param lOrderId 主体id
     */
    private void saveLogisticsOrderAddress(AddOrderDTO orderDTO, Long lOrderId) {
        KwtLogisticsOrderAddress loadAddress = new KwtLogisticsOrderAddress();
        loadAddress.setId(new IdWorker(NumberConstant.ONE).nextId());
        loadAddress.setLOrderId(lOrderId);
        loadAddress.setAddressType(NumberConstant.ONE);
//        loadAddress.setName();
//        loadAddress.setType();
        loadAddress.setContacts(orderDTO.getLoadContacts());
        loadAddress.setPhone(orderDTO.getLoadPhone());
        loadAddress.setCityCode(orderDTO.getLoadCityCode());
        loadAddress.setCityName(orderDTO.getLoadCityName());
        loadAddress.setDetailAddress(orderDTO.getLoadDetailAddress());
        loadAddress.setLat(orderDTO.getLoadLat());
        loadAddress.setLng(orderDTO.getLoadLng());
        loadAddress.setEntryType(NumberConstant.FOUR);
        loadAddress.setStatus(NumberConstant.ZERO);
        loadAddress.setCreateBy(LoginUserHolder.getUserId());
        Date date = new Date();
        loadAddress.setCreateTime(date);
        loadAddress.setUpdateBy(LoginUserHolder.getUserId());
        loadAddress.setUpdateTime(date);

        KwtLogisticsOrderAddress unloadAddress = new KwtLogisticsOrderAddress();
        unloadAddress.setId(new IdWorker(NumberConstant.TWO).nextId());
        unloadAddress.setLOrderId(lOrderId);
        unloadAddress.setAddressType(NumberConstant.TWO);
//        unloadAddress.setName();
//        unloadAddress.setType();
        unloadAddress.setContacts(orderDTO.getUnloadContacts());
        unloadAddress.setPhone(orderDTO.getUnloadPhone());
        unloadAddress.setCityCode(orderDTO.getUnloadCityCode());
        unloadAddress.setCityName(orderDTO.getUnloadCityName());
        unloadAddress.setDetailAddress(orderDTO.getUnloadDetailAddress());
        unloadAddress.setLat(orderDTO.getUnloadLat());
        unloadAddress.setLng(orderDTO.getUnloadLng());
        unloadAddress.setEntryType(NumberConstant.FOUR);
        unloadAddress.setStatus(NumberConstant.ZERO);
        unloadAddress.setCreateBy(LoginUserHolder.getUserId());
        unloadAddress.setCreateTime(date);
        unloadAddress.setUpdateBy(LoginUserHolder.getUserId());
        unloadAddress.setUpdateTime(date);
        logisticsOrderAddressMapper.insert(loadAddress);
        logisticsOrderAddressMapper.insert(unloadAddress);
    }

    /**
     * 承运订单-新建订单-合体主体
     *
     * @param orderDTO 页面请求参数
     * @param lOrderId 主体id
     */
    private void saveLogisticsOrderContract(AddOrderDTO orderDTO, Long lOrderId) {
        KwtLogisticsOrderContract contract = new KwtLogisticsOrderContract();
        contract.setId(new IdWorker(NumberConstant.ONE).nextId());
        contract.setContractId(Long.parseLong(orderDTO.getContractId()));
        contract.setLOrderId(lOrderId);
        contract.setStatus(NumberConstant.ZERO);
        contract.setCreateBy(LoginUserHolder.getUserId());
        contract.setCreateTime(new Date());
        contract.setUpdateBy(LoginUserHolder.getUserId());
        contract.setUpdateTime(new Date());
        kwtLogisticsOrderContractMapper.insert(contract);
    }

    /**
     * 承运订单-页面新增订单-订单主体
     *
     * @param orderDTO    页面请求参数
     * @param lOrderId    主体id
     * @param orderStatus 订单状态
     * @param lOrderNo    主体订单编号
     */
    private void saveLogisticsOrder(AddOrderDTO orderDTO, Long lOrderId, Integer orderStatus, String lOrderNo) throws ParseException {
        KwtLogisticsOrder order = new KwtLogisticsOrder();
        order.setId(lOrderId);
        order.setEntId(LoginUserHolder.getEntId());
        order.setType(String.valueOf(NumberConstant.TWO));
        order.setLOrderNo(lOrderNo);
        order.setPids(lOrderId.toString());
        order.setSettlementCycle(orderDTO.getSettlementCycle());
        order.setBillingMode(orderDTO.getBillingMode());
        order.setPrice(orderDTO.getPrice());
        order.setPriceType(orderDTO.getPriceType());
        order.setPayment(orderDTO.getPayment());
        order.setAmount(orderDTO.getAmount());
        order.setUnit(orderDTO.getAmountUnit());
        order.setLoss(orderDTO.getLoss() == null ? null : orderDTO.getLoss());
        order.setLossUnit(orderDTO.getLossUnit());
        order.setGoodsPrice(orderDTO.getGoodsPrice() == null ? null : orderDTO.getGoodsPrice());
        order.setGoodsPriceUnit(orderDTO.getGoodsPriceUnit());
        order.setStartTime(org.apache.commons.lang3.StringUtils.isBlank(orderDTO.getStartTime()) ?
                null : DateUtil.stringPatchingStartToDateTime(orderDTO.getStartTime()));
        order.setEndTime(org.apache.commons.lang3.StringUtils.isBlank(orderDTO.getEndTime()) ?
                null : DateUtil.stringPatchingEndToDateTime(orderDTO.getEndTime()));
        BigDecimal decimal = new BigDecimal(NumberConstant.ZERO);
        order.setSubcontractAmount(decimal);
        order.setEntrustAmount(decimal);
        order.setUnloadAmount(decimal);
        order.setLoadAmount(decimal);
        order.setIgnoreAmount(decimal);
        order.setDeficitAmount(decimal);
        order.setDeficitPrice(decimal);
        order.setTaxRate(orderDTO.getTaxRate());
        order.setRemark(orderDTO.getRemark());
        order.setStatus(orderStatus);
        order.setCreateBy(LoginUserHolder.getUserId());
        order.setCreateTime(new Date());
        order.setUpdateBy(LoginUserHolder.getUserId());
        order.setUpdateTime(new Date());
        logisticsOrderMapper.insert(order);
    }
}
