package com.prolog.rdc.tms.service.impl.planMng;

import cn.hutool.core.bean.BeanUtil;
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 com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.prolog.common.util.ToolKits;
import com.prolog.framework.common.message.RestMessage;
import com.prolog.framework.core.pojo.Page;
import com.prolog.framework.core.restriction.*;
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.constant.BussinessConstant;
import com.prolog.rdc.tms.constant.DataDictionaryConstant;
import com.prolog.rdc.tms.constant.SeriaNnumberConstant;
import com.prolog.rdc.tms.constant.StatusConstant;
import com.prolog.rdc.tms.dao.mapper.TmsShipbillDetailMapper;
import com.prolog.rdc.tms.dao.mapper.TmsShipbillHeaderMapper;
import com.prolog.rdc.tms.dao.mapper.TmsTransPlanBillDetailMapper;
import com.prolog.rdc.tms.dao.mapper.TmsTransPlanBillHeaderMapper;
import com.prolog.rdc.tms.model.dto.basicConfigure.StrategyBusinessMatchingDTO;
import com.prolog.rdc.tms.model.dto.planMng.*;
import com.prolog.rdc.tms.model.entity.*;
import com.prolog.rdc.tms.model.vo.ShipbillNodeTrackingSaveVO;
import com.prolog.rdc.tms.model.vo.ShipbillOperateLogSaveVO;
import com.prolog.rdc.tms.model.vo.planMng.PlanBillDetailQueryVO;
import com.prolog.rdc.tms.model.vo.planMng.TransportPlanBillDetailVO;
import com.prolog.rdc.tms.model.vo.planMng.TransportPlanBillVO;
import com.prolog.rdc.tms.model.vo.planMng.TransportPlanQueryVO;
import com.prolog.rdc.tms.rmi.feign.MaindataFeign;
import com.prolog.rdc.tms.service.ShipbillNodeTrackingService;
import com.prolog.rdc.tms.service.ShipbillOperateLogService;
import com.prolog.rdc.tms.service.planMng.TransportPlanBillService;
import com.prolog.rdc.tms.util.ConvertorUtil;
import com.prolog.rdc.tms.util.StrategyUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.plugin.PluginException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * 调度管理-待调度实现层
 *
 * @author lhb
 * @since 2022-04-13 14:45:00
 */
@Service
@Slf4j
public class TransportPlanBillServiceImpl implements TransportPlanBillService {

    @Autowired
    private TmsShipbillHeaderMapper tmsShipbillHeaderMapper;

    @Autowired
    private TmsShipbillDetailMapper tmsShipbillDetailMapper;

    @Autowired
    private TmsTransPlanBillHeaderMapper tmsTransPlanBillHeaderMapper;

    @Autowired
    private TmsTransPlanBillDetailMapper tmsTransPlanBillDetailMapper;

    @Autowired
    private MaindataFeign maindataTmsResource;


    @Autowired
    private ConvertorUtil convertorUtil;

    @Autowired
    private StrategyUtil strategyUtil;

    @Autowired
    private ShipbillNodeTrackingService shipbillNodeTrackingService;

    @Autowired
    private ShipbillOperateLogService shipbillOperateLogService;


    /**
     * 待排计划单分页查询
     *
     * @param vo
     * @return
     */
    @SuppressWarnings("resource")
    @Override
    public Page<PendingPlanBillQueryDTO> pagePendingPlanBillData(TransportPlanQueryVO vo) {
        ToolKits.isParamNull(vo, "待排计划单分页查询请求不为空");
        ToolKits.isParamNull(vo.getPageNum(), "当前页码不为空");
        ToolKits.isParamNull(vo.getPageSize(), "每页条数不为空");

        UserEntity user = PlgFxUsrUtils.getUserEntity();
        ToolKits.isParamNull(user, "当前人员没有操作权限");

        vo.setUserType(user.getUserType());
        vo.setEnterpriseId(user.getEnterpriseId());
        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.setConsignors(user.getConsignors().stream().toArray(Long[]::new));
                // 客户
                vo.setCustomers(user.getCustomers().stream().toArray(Long[]::new));
                // 供应商
                vo.setSuppliers(user.getSuppliers().stream().toArray(Long[]::new));
                // 仓库
                vo.setWsarehouses(user.getWarehouses().stream().toArray(Long[]::new));
            }
        } else {
            throw new PluginException("当前人员没有操作权限");
        }

        // 数据字典翻译数据集合
        List<SysRefdatadModel> dicData = convertorUtil.getDictionary(new String[]{DataDictionaryConstant.WHETHER, // 配送方式
                DataDictionaryConstant.ORDER_BUSINESS_TYPE, // 订单业务类型
                DataDictionaryConstant.SHIPBILL_STATUS
        });

        PageUtils.startPage(vo.getPageNum(), vo.getPageSize());
        List<PendingPlanBillQueryDTO> transportPlanQueryDTOS = tmsShipbillHeaderMapper.queryPendingPlanBillData(vo);

        for (PendingPlanBillQueryDTO dto : transportPlanQueryDTOS) {
            dto.setIsTransfiniteName(ConvertorUtil.getName(dicData, DataDictionaryConstant.WHETHER, String.valueOf(dto.getIsTransfinite())));
            dto.setStatusName(ConvertorUtil.getName(dicData, DataDictionaryConstant.SHIPBILL_STATUS, String.valueOf(dto.getStatus())));
            if (!DataDictionaryConstant.WHETHER_YES.equals(dto.getIsTransfinite())) {
                dto.setColorTagBgdColor(null);
                dto.setColorTagFontColor(null);
                dto.setRecordTagWord(null);
            }
        }

        return PageUtils.getPage(transportPlanQueryDTOS);
    }

    /**
     * 计划单保存
     *
     * @param vo
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public String savePlanBillData(TransportPlanBillVO vo) {
        ToolKits.isParamNull(vo, "计划单保存请求不为空");
        ToolKits.isParamNull(vo.getCarrierType(), "承运方类型不为空");
        ToolKits.isParamNull(vo.getPlanTotalPcs(), "计划箱数不为空");
        ToolKits.isParamNull(vo.getPlanTotalVehicleNumber(), "计划车数不为空");
        ToolKits.isParamNull(vo.getPlanDeliveryDate(), "计划发运日期不为空");
        ToolKits.isParamNull(vo.getIsWeigh(), "是否过磅不为空");
        ToolKits.isParamNull(vo.getTransportPlanBillDetailVOS(), "计划单明细不为空");

        if (vo.getTransportPlanBillDetailVOS().stream().anyMatch(detail -> ToolKits.isEmpty(detail.getShipbillId()))) {
            throw new PluginException("待排计划单运单不为空");
        }
        if (vo.getTransportPlanBillDetailVOS().stream().anyMatch(detail -> ToolKits.isEmpty(detail.getShipbillDetailId()))) {
            throw new PluginException("待排计划单运单明细不为空");
        }
        if (DataDictionaryConstant.LINE_CARRIER_TYPE_SJ.equals(vo.getCarrierType()) && ToolKits.isEmpty(vo.getDriverName())) {
            throw new PluginException("司机不为空");
        }
        if (DataDictionaryConstant.LINE_CARRIER_TYPE_CYF.equals(vo.getCarrierType()) && ToolKits.isEmpty(vo.getCarrierName())) {
            throw new PluginException("承运商不为空");
        }

        UserEntity user = PlgFxUsrUtils.getUserEntity();
        ToolKits.isParamNull(user, "当前人员没有操作权限");
        List<String> shipbillIds = vo.getTransportPlanBillDetailVOS().stream().map(TransportPlanBillDetailVO::getShipbillId).distinct().collect(Collectors.toList());
        List<TmsShipbillHeaderModel> shipbillHeaderModels = tmsShipbillHeaderMapper.findByIds(TmsShipbillHeaderModel.class, shipbillIds.stream().toArray(), null);

        if (ToolKits.isEmpty(shipbillHeaderModels)) {
            throw new PluginException(StrUtil.format("运单{}不存在", shipbillIds.stream().collect(Collectors.joining(","))));
        }
        if (shipbillHeaderModels.stream().map(TmsShipbillHeaderModel::getCargoOwnerId).distinct().collect(Collectors.toList()).size() != 1) {
            throw new PluginException("待排运单的货主不相同");
        }
        if (shipbillHeaderModels.stream().map(TmsShipbillHeaderModel::getConsigneeId).distinct().collect(Collectors.toList()).size() != 1) {
            throw new PluginException("待排运单的收货方不相同");
        }
        shipbillHeaderModels.stream().forEach(model -> {
            if (!DataDictionaryConstant.SHIPBILL_STATUS_PENDING_PLAN.equals(model.getStatus())
                    && !DataDictionaryConstant.SHIPBILL_STATUS_REVIEW.equals(model.getStatus())) {
                throw new PluginException(StrUtil.format("运单{}已调度,不能做计划单", model.getShipbillNo()));
            }
            if (!DataDictionaryConstant.SPLIT_ORDER_STATUS_UN.equals(model.getSplitOrderStatus())) {
                throw new PluginException(StrUtil.format("运单{}已被拆单,不能做计划单", model.getShipbillNo()));
            }
        });
        RestMessage<SysParamConfigModel> restMessageTransfinite = maindataTmsResource.getValue(DataDictionaryConstant.GOODS_TRANSFINITE_ENABLED);
        if (!restMessageTransfinite.isSuccess()) {
            throw new RuntimeException("获取是否启用商品超限的系统参数失败!");
        }
        SysParamConfigModel sysParamConfigModel = restMessageTransfinite.getData();
        if (DataDictionaryConstant.GOODS_TRANSFINITE_ENABLED_YES.equals(sysParamConfigModel.getValue())) {
            StrategyBusinessMatchingDTO businessData = strategyUtil.shipbillMatchBusinessRule(shipbillHeaderModels.get(0), null);
            if (ToolKits.isNotEmpty(businessData)) {
                if (Integer.valueOf(10).equals(businessData.getTransfiniteCmtDtEnable()) && ToolKits.isEmpty(vo.getTransfiniteCommitDate())) {
                    throw new PluginException("超限提交日期不为空");
                }
                if (Integer.valueOf(10).equals(businessData.getTransfiniteDescriptionEnable()) && ToolKits.isEmpty(vo.getTransfiniteDescription())) {
                    throw new PluginException("超限说明不为空");
                }
                if (Integer.valueOf(10).equals(businessData.getLoadingLocationEnable()) && ToolKits.isEmpty(vo.getLoadingLocation())) {
                    throw new PluginException("装车地点不为空");
                }
            }
        }

        // 获取计划单主表表ID
        RestMessage<String> restMessageId = maindataTmsResource.getCodeNumberByCode(SeriaNnumberConstant.TMS_TRANSPORT_PLAN_BILL_HEADER_ID, "L");
        if (!restMessageId.isSuccess()) {
            throw new RuntimeException("生成计划单主表ID失败");
        }
        String id = restMessageId.getData();

        TmsTransPlanBillHeaderModel planBillHeaderModel = new TmsTransPlanBillHeaderModel();
        BeanUtil.copyProperties(vo, planBillHeaderModel);

        planBillHeaderModel.setPlanBillId(id);
        planBillHeaderModel.setPlanBillNo(id);
        planBillHeaderModel.setCargoOwnerId(shipbillHeaderModels.get(0).getCargoOwnerId());
        planBillHeaderModel.setCargoOwnerCode(shipbillHeaderModels.get(0).getCargoOwnerCode());
        planBillHeaderModel.setCargoOwnerName(shipbillHeaderModels.get(0).getCargoOwnerName());
        planBillHeaderModel.setConsigneeId(shipbillHeaderModels.get(0).getConsigneeId());
        planBillHeaderModel.setConsigneeCode(shipbillHeaderModels.get(0).getConsigneeCode());
        planBillHeaderModel.setConsigneeName(shipbillHeaderModels.get(0).getConsigneeName());
        if (ToolKits.isNotEmpty(vo.getProductName())) {
            planBillHeaderModel.setProductName(vo.getProductName());
        } else {
            planBillHeaderModel.setProductName(shipbillHeaderModels.stream().map(TmsShipbillHeaderModel::getProductName).collect(Collectors.joining(",")));
        }
        planBillHeaderModel.setStatus(DataDictionaryConstant.PLAN_BILL_STATUS_PENDING_DISPATCH);
        planBillHeaderModel.setEnterpriseId(user.getEnterpriseId());
        planBillHeaderModel.setEnterpriseName(user.getEnterpriseName());
        planBillHeaderModel.setCreateperson(user.getNickname());
        planBillHeaderModel.setCreatetime(DateUtil.date());
        planBillHeaderModel.setPlanDate(DateUtil.date());
        planBillHeaderModel.setDepartmentId(shipbillHeaderModels.get(0).getDepartmentId());
        planBillHeaderModel.setDepartmentCode(shipbillHeaderModels.get(0).getDepartmentCode());
        planBillHeaderModel.setDepartmentName(shipbillHeaderModels.get(0).getDepartmentName());
        tmsTransPlanBillHeaderMapper.save(planBillHeaderModel);

        planDetailSave(planBillHeaderModel, vo.getTransportPlanBillDetailVOS(), shipbillHeaderModels, user,"S");
        return planBillHeaderModel.getPlanBillId();
    }

    /**
     * 计划单修改
     *
     * @param vo
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public String updatePlanBillData(TransportPlanBillVO vo) {
        ToolKits.isParamNull(vo, "计划单修改请求不为空");
        ToolKits.isParamNull(vo.getPlanBillId(), "计划单ID不为空");
        ToolKits.isParamNull(vo.getPlanBillNo(), "计划单编号不为空");
        ToolKits.isParamNull(vo.getCarrierType(), "承运方类型不为空");
        ToolKits.isParamNull(vo.getPlanTotalPcs(), "计划箱数不为空");
        ToolKits.isParamNull(vo.getPlanTotalVehicleNumber(), "计划车数不为空");
        ToolKits.isParamNull(vo.getPlanDeliveryDate(), "计划发运日期不为空");
        ToolKits.isParamNull(vo.getIsWeigh(), "是否过磅不为空");
        ToolKits.isParamNull(vo.getTransportPlanBillDetailVOS(), "计划单明细不为空");

        if (vo.getTransportPlanBillDetailVOS().stream().anyMatch(detail -> ToolKits.isEmpty(detail.getShipbillId()))) {
            throw new PluginException("待排计划单运单不为空");
        }
        if (vo.getTransportPlanBillDetailVOS().stream().anyMatch(detail -> ToolKits.isEmpty(detail.getShipbillDetailId()))) {
            throw new PluginException("待排计划单运单明细不为空");
        }
        if (DataDictionaryConstant.LINE_CARRIER_TYPE_SJ.equals(vo.getCarrierType()) && ToolKits.isEmpty(vo.getDriverName())) {
            throw new PluginException("司机不为空");
        }
        if (DataDictionaryConstant.LINE_CARRIER_TYPE_CYF.equals(vo.getCarrierType()) && ToolKits.isEmpty(vo.getCarrierName())) {
            throw new PluginException("承运商不为空");
        }
        List<String> shipbillIds = vo.getTransportPlanBillDetailVOS().stream().map(TransportPlanBillDetailVO::getShipbillId).distinct().collect(Collectors.toList());
        List<TmsShipbillHeaderModel> shipbillHeaderModels = tmsShipbillHeaderMapper.findByIds(TmsShipbillHeaderModel.class, shipbillIds.stream().toArray(), null);
        if (ToolKits.isEmpty(shipbillHeaderModels)) {
            throw new PluginException(StrUtil.format("运单{}不存在", shipbillIds.stream().collect(Collectors.joining(","))));
        }
        if (shipbillHeaderModels.stream().map(TmsShipbillHeaderModel::getCargoOwnerId).distinct().collect(Collectors.toList()).size() != 1) {
            throw new PluginException("待排运单的货主不相同");
        }
        if (shipbillHeaderModels.stream().map(TmsShipbillHeaderModel::getConsigneeId).distinct().collect(Collectors.toList()).size() != 1) {
            throw new PluginException("待排运单的收货方不相同");
        }
        if (shipbillHeaderModels.stream().allMatch(model->!DataDictionaryConstant.SHIPBILL_STATUS_PENDING_PLAN.equals(model.getStatus())
                && !DataDictionaryConstant.SHIPBILL_STATUS_REVIEW.equals(model.getStatus()))) {
            throw new PluginException(StrUtil.format("计划单下所有运单已调度,不能做计划单"));
        }
        if (shipbillHeaderModels.stream().allMatch(model->!DataDictionaryConstant.SPLIT_ORDER_STATUS_UN.equals(model.getSplitOrderStatus()))) {
            throw new PluginException(StrUtil.format("计划单下所有运单已被拆分,不能做计划单"));
        }

        TmsTransPlanBillHeaderModel headerModel = tmsTransPlanBillHeaderMapper.findById(vo.getPlanBillId(), TmsTransPlanBillHeaderModel.class);
        if (ToolKits.isEmpty(headerModel)) {
            throw new PluginException(StrUtil.format("计划单{}不存在", vo.getPlanBillId()));
        }

        if (headerModel.getStatus().intValue() > 10) {
            throw new PluginException(StrUtil.format("计划单{}已调度,不能修改", headerModel.getPlanBillNo()));
        }


        UserEntity user = PlgFxUsrUtils.getUserEntity();
        ToolKits.isParamNull(user, "当前人员没有操作权限");

        RestMessage<SysParamConfigModel> restMessageTransfinite = maindataTmsResource.getValue(DataDictionaryConstant.GOODS_TRANSFINITE_ENABLED);
        if (!restMessageTransfinite.isSuccess()) {
            throw new RuntimeException("获取是否启用商品超限的系统参数失败!");
        }
        SysParamConfigModel sysParamConfigModel = restMessageTransfinite.getData();
        if (DataDictionaryConstant.GOODS_TRANSFINITE_ENABLED_YES.equals(sysParamConfigModel.getValue())) {
            StrategyBusinessMatchingDTO businessData = strategyUtil.shipbillMatchBusinessRule(shipbillHeaderModels.get(0), null);
            if (ToolKits.isNotEmpty(businessData)) {
                if (Integer.valueOf(10).equals(businessData.getTransfiniteCmtDtEnable()) && ToolKits.isEmpty(vo.getTransfiniteCommitDate())) {
                    throw new PluginException("超限提交日期不为空");
                }
                if (Integer.valueOf(10).equals(businessData.getTransfiniteDescriptionEnable()) && ToolKits.isEmpty(vo.getTransfiniteDescription())) {
                    throw new PluginException("超限说明不为空");
                }
                if (Integer.valueOf(10).equals(businessData.getLoadingLocationEnable()) && ToolKits.isEmpty(vo.getLoadingLocation())) {
                    throw new PluginException("装车地点不为空");
                }
            }
        }

        headerModel.setCargoOwnerId(shipbillHeaderModels.get(0).getCargoOwnerId());
        headerModel.setCargoOwnerCode(shipbillHeaderModels.get(0).getCargoOwnerCode());
        headerModel.setCargoOwnerName(shipbillHeaderModels.get(0).getCargoOwnerName());
        headerModel.setConsigneeId(shipbillHeaderModels.get(0).getConsigneeId());
        headerModel.setConsigneeCode(shipbillHeaderModels.get(0).getConsigneeCode());
        headerModel.setConsigneeName(shipbillHeaderModels.get(0).getConsigneeName());
        if (ToolKits.isNotEmpty(vo.getProductName())) {
            headerModel.setProductName(vo.getProductName());
        } else {
            headerModel.setProductName(shipbillHeaderModels.stream().map(TmsShipbillHeaderModel::getProductName).collect(Collectors.joining(",")));
        }
        headerModel.setStatus(DataDictionaryConstant.PLAN_BILL_STATUS_PENDING_DISPATCH);

        headerModel.setCarrierType(vo.getCarrierType());
        headerModel.setCarrierId(vo.getCarrierId());
        headerModel.setCarrierCode(vo.getCarrierCode());
        headerModel.setCarrierName(vo.getCarrierName());

        headerModel.setDriverId(vo.getDriverId());
        headerModel.setDriverCode(vo.getDriverCode());
        headerModel.setDriverName(vo.getDriverName());
        headerModel.setDriverPhoneNumber(vo.getDriverPhoneNumber());

        headerModel.setVehicleId(vo.getVehicleId());
        headerModel.setVehicleCode(vo.getVehicleCode());
        headerModel.setVehicleName(vo.getVehicleName());
        headerModel.setVehiclePlateNumber(vo.getVehiclePlateNumber());

        headerModel.setPlanTotalPcs(vo.getPlanTotalPcs());
        headerModel.setPlanTotalVehicleNumber(vo.getPlanTotalVehicleNumber());
        headerModel.setPlanDeliveryDate(vo.getPlanDeliveryDate());
        headerModel.setTransfiniteCommitDate(vo.getTransfiniteCommitDate());
        headerModel.setDeliveryDescription(vo.getDeliveryDescription());

        headerModel.setActualTotalPcs(vo.getActualTotalPcs());
        headerModel.setActualTotalVehicleNumber(vo.getActualTotalVehicleNumber());

        headerModel.setEnterpriseId(user.getEnterpriseId());
        headerModel.setEnterpriseName(user.getEnterpriseName());
        headerModel.setUpdateperson(user.getNickname());
        headerModel.setUpdatetime(DateUtil.date());
        headerModel.setPlanDate(DateUtil.date());
        headerModel.setProductName(vo.getProductName());
        headerModel.setIsWeigh(vo.getIsWeigh());
        headerModel.setLoadingLocation(vo.getLoadingLocation());
        headerModel.setTransfiniteDescription(vo.getTransfiniteDescription());
        tmsTransPlanBillHeaderMapper.update(headerModel);

        Criteria criteriaPlanBillDetail = Criteria.forClass(TmsTransPlanBillDetailModel.class);
        Restriction r1 = Restrictions.eq(TmsTransPlanBillDetailModel::getPlanBillId, headerModel.getPlanBillId());
        Restriction r2 = Restrictions.eq(TmsTransPlanBillDetailModel::getEnterpriseId, user.getEnterpriseId());
        criteriaPlanBillDetail.setRestriction(Restrictions.and(r1, r2));

        long delCnt = tmsShipbillDetailMapper.deleteByCriteria(criteriaPlanBillDetail);
        log.info("计划单{}元明细删除{}件", headerModel.getPlanBillId(), delCnt);

        planDetailSave(headerModel, vo.getTransportPlanBillDetailVOS(), shipbillHeaderModels, user,"U");
        return headerModel.getPlanBillId();
    }

    public void planDetailSave(TmsTransPlanBillHeaderModel headerModel, List<TransportPlanBillDetailVO> transportPlanBillDetailVOS,
                               List<TmsShipbillHeaderModel> shipbillHeaderModels, UserEntity user,String isMdy) {
        for (TransportPlanBillDetailVO detailVO : transportPlanBillDetailVOS) {
            TmsShipbillDetailModel detailModel = tmsShipbillDetailMapper.findById(detailVO.getShipbillDetailId(), TmsShipbillDetailModel.class);
            if (ToolKits.isEmpty(detailModel)) {
                throw new RuntimeException(StrUtil.format("运单{}的明细数据不存在", detailVO.getShipbillNo()));
            }
            if (!"U".equals(isMdy) && ToolKits.isNotEmpty(detailModel.getPlanStatus())) {
                throw new RuntimeException(StrUtil.format("运单{}的商品{}已作成计划单", detailVO.getShipbillNo(), detailModel.getItemName()));
            }
            TmsTransPlanBillDetailModel billDetailModel = new TmsTransPlanBillDetailModel();
            // 获取预约明细表ID
            RestMessage<String> restMessageDetailId = maindataTmsResource.getCodeNumberByCode(SeriaNnumberConstant.TMS_TRANSPORT_PLAN_BILL_DETAIL_ID, "L");
            if (!restMessageDetailId.isSuccess()) {
                throw new RuntimeException("生成计划单明细表ID失败");
            }
            String detailId = restMessageDetailId.getData();

            BeanUtil.copyProperties(detailVO, billDetailModel);
            billDetailModel.setId(detailId);
            billDetailModel.setPlanBillId(headerModel.getPlanBillId());
            billDetailModel.setPlanBillNo(headerModel.getPlanBillNo());
            List<TmsShipbillHeaderModel> oneShipbill = shipbillHeaderModels.stream().filter(h -> h.getShipbillId().equals(detailVO.getShipbillId())).collect(Collectors.toList());
            billDetailModel.setCargoOwnerId(oneShipbill.get(0).getCargoOwnerId());
            billDetailModel.setCargoOwnerCode(oneShipbill.get(0).getCargoOwnerCode());
            billDetailModel.setCargoOwnerName(oneShipbill.get(0).getCargoOwnerName());
            billDetailModel.setConsigneeId(oneShipbill.get(0).getConsigneeId());
            billDetailModel.setConsigneeCode(oneShipbill.get(0).getConsigneeCode());
            billDetailModel.setConsigneeName(oneShipbill.get(0).getConsigneeName());
            billDetailModel.setProductName(oneShipbill.get(0).getProductName());
            billDetailModel.setOrderBusinessType(oneShipbill.get(0).getOrderBusinessType());
            billDetailModel.setConsigneeType(oneShipbill.get(0).getConsigneeType());
            billDetailModel.setOrderId(oneShipbill.get(0).getOrderId());
            billDetailModel.setOrderNo(oneShipbill.get(0).getOrderNo());
            billDetailModel.setMesOrderNo(oneShipbill.get(0).getMesOrderNo());

            billDetailModel.setShipbillDetailId(detailVO.getShipbillDetailId());
            billDetailModel.setItemId(detailModel.getItemId());
            billDetailModel.setItemCode(detailModel.getItemCode());
            billDetailModel.setItemName(detailModel.getItemName());
            billDetailModel.setEnterpriseId(user.getEnterpriseId());
            billDetailModel.setEnterpriseName(user.getEnterpriseName());
            billDetailModel.setCreateperson(user.getNickname());
            billDetailModel.setCreatetime(DateUtil.date());

            billDetailModel.setDepartmentId(headerModel.getDepartmentId());
            billDetailModel.setDepartmentCode(headerModel.getDepartmentCode());
            billDetailModel.setDepartmentName(headerModel.getDepartmentName());

            billDetailModel.setPlanPcs(detailModel.getPcs());
            billDetailModel.setPlanWeight(detailModel.getWeight());
            billDetailModel.setMemo(detailModel.getMemo());

            billDetailModel.setIsTransfinite(detailModel.getIsTransfinite());
            billDetailModel.setPlanDeliveryDate(DateUtil.format(headerModel.getPlanDeliveryDate(),"yyyy-MM-dd"));
            billDetailModel.setCarrierName(headerModel.getCarrierName());
            billDetailModel.setStatus(10);

            tmsTransPlanBillDetailMapper.save(billDetailModel);

            if (ToolKits.isNotEmpty(headerModel.getPlanDeliveryDate())) {
                detailModel.setPlanDeliveryDate(headerModel.getPlanDeliveryDate());
            } else {
                detailModel.setPlanDeliveryDate(detailVO.getPlanDeliveryDate());
            }
            detailModel.setPlanStatus(10);
            detailModel.setUpdateperson(user.getNickname());
            detailModel.setUpdatetime(DateUtil.date());
            tmsShipbillDetailMapper.update(detailModel);
        }
        List<TmsShipbillHeaderModel> updateShipbillHeaderModels =
                shipbillHeaderModels.stream().filter(h -> !DataDictionaryConstant.SHIPBILL_STATUS_REVIEW.equals(h.getStatus())).collect(Collectors.toList());
        if (ToolKits.isEmpty(updateShipbillHeaderModels)) {
            return;
        }
        updateShipbillHeaderModels.stream().forEach(model -> {
            model.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);
            model.setUpdatetime(DateUtil.date());
            model.setUpdateperson(user.getNickname());
            tmsShipbillHeaderMapper.update(model);

            // 声明日志实体
            ShipbillOperateLogSaveVO shipbillOperateLogSaveVO = new ShipbillOperateLogSaveVO();

            shipbillOperateLogSaveVO.setOperateEvent(DataDictionaryConstant.SHIPBILL_STATUSNAME_PLAN);
            shipbillOperateLogSaveVO.setOldStatus(DataDictionaryConstant.SHIPBILL_STATUS_PENDING_PLAN);
            shipbillOperateLogSaveVO.setNewStatus(DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);
            shipbillOperateLogSaveVO.setShipbillId(model.getShipbillId());
            shipbillOperateLogSaveVO.setShipbillNo(model.getShipbillNo());
            shipbillOperateLogService.addShipbillOperateLogData(shipbillOperateLogSaveVO);

            // 运单节点保存
            ShipbillNodeTrackingSaveVO shipbillNodeTrackingSaveVO = new ShipbillNodeTrackingSaveVO();
            shipbillNodeTrackingSaveVO.setShipbillId(model.getShipbillId());
            shipbillNodeTrackingSaveVO.setShipbillNo(model.getShipbillNo());
            shipbillNodeTrackingSaveVO.setStatus(DataDictionaryConstant.SHIPBILL_STATUS_REVIEW);
            shipbillNodeTrackingSaveVO.setNodeEvent(DataDictionaryConstant.SHIPBILL_NODE_STATUSNAME_PLAN);
            shipbillNodeTrackingService.addShipbillNodeTrackingData(shipbillNodeTrackingSaveVO);
        });
    }

    /**
     * 计划单删除
     *
     * @param planBillIds
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public void deletePlanBillData(List<String> planBillIds) {
        ToolKits.isParamNull(planBillIds, "计划单删除请求不为空");

        UserEntity user = PlgFxUsrUtils.getUserEntity();
        ToolKits.isParamNull(user, "当前人员没有操作权限");

        if (!ObjectUtil.equal(user.getUserType(), BussinessConstant.USER_TYPE_ZY)) {
            throw new PluginException("当前人员没有操作权限");
        }

        Map<String, Object> mapShipbillHeadUpdate = Maps.newHashMap();
        mapShipbillHeadUpdate.put("updateperson", user.getNickname());
        mapShipbillHeadUpdate.put("updatetime", DateUtil.date());
        mapShipbillHeadUpdate.put("status", DataDictionaryConstant.SHIPBILL_STATUS_PENDING_PLAN);

        for (String planBillId : planBillIds) {
            TmsTransPlanBillHeaderModel headerModel = tmsTransPlanBillHeaderMapper.findById(planBillId, TmsTransPlanBillHeaderModel.class);
            if (ToolKits.isEmpty(headerModel)) {
                throw new PluginException(StrUtil.format("计划单{}不存在", planBillId));
            }

            if (headerModel.getStatus().intValue() > 20) {
                throw new PluginException(StrUtil.format("计划单{}已发运,不能删除", headerModel.getPlanBillNo()));
            }

            tmsTransPlanBillHeaderMapper.deleteById(headerModel.getPlanBillId(), TmsTransPlanBillHeaderModel.class);

            Criteria planDetailCriteria = Criteria.forClass(TmsTransPlanBillDetailModel.class);
            Restriction r1 = Restrictions.eq(TmsTransPlanBillDetailModel::getPlanBillId, headerModel.getPlanBillId());
            planDetailCriteria.setRestriction(Restrictions.and(r1));
            List<TmsTransPlanBillDetailModel> planBillDetailModels = tmsTransPlanBillDetailMapper.findByCriteria(planDetailCriteria);

            if (ToolKits.isEmpty(planBillDetailModels)) {
                continue;
            }
            List<String> ids = planBillDetailModels.stream().map(TmsTransPlanBillDetailModel::getId).collect(Collectors.toList());
            tmsTransPlanBillDetailMapper.deleteByIds(ids.stream().toArray(), TmsTransPlanBillDetailModel.class);

            List<String> shipbillIds = planBillDetailModels.stream().map(TmsTransPlanBillDetailModel::getShipbillId).distinct().collect(Collectors.toList());
            Criteria shipbillHeaderCriteria = Criteria.forClass(TmsShipbillHeaderModel.class);
            r1 = Restrictions.in(TmsShipbillHeaderModel::getShipbillId, shipbillIds.stream().toArray());
            shipbillHeaderCriteria.setRestriction(Restrictions.and(r1));
            tmsShipbillHeaderMapper.updateMapByCriteria(mapShipbillHeadUpdate, shipbillHeaderCriteria);

            List<String> shipbillDetailIds = planBillDetailModels.stream().map(TmsTransPlanBillDetailModel::getShipbillDetailId).distinct().collect(Collectors.toList());
            shipbillDetailIds.stream().forEach(id -> {
                TmsShipbillDetailModel detailModel = tmsShipbillDetailMapper.findById(id, TmsShipbillDetailModel.class);
                if (ToolKits.isNotEmpty(detailModel)) {
                    detailModel.setPlanStatus(null);
                    detailModel.setUpdatetime(DateUtil.date());
                    detailModel.setUpdateperson(user.getNickname());
                    tmsShipbillDetailMapper.update(detailModel);
                }
            });

        }
    }


    /**
     * 计划单分页查询
     *
     * @param vo
     * @return
     */
    public Page<PlanBillQueryDTO> pagePlanBillData(TransportPlanQueryVO vo) {
        ToolKits.isParamNull(vo, "计划单分页查询请求不为空");
        ToolKits.isParamNull(vo.getPageNum(), "当前页码不为空");
        ToolKits.isParamNull(vo.getPageSize(), "每页条数不为空");

        UserEntity user = PlgFxUsrUtils.getUserEntity();
        ToolKits.isParamNull(user, "当前人员没有操作权限");

        vo.setUserType(user.getUserType());
        vo.setEnterpriseId(user.getEnterpriseId());
        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.setConsignors(user.getConsignors().stream().toArray(Long[]::new));
            }
        } else if (user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
            vo.setCarrierId(Long.valueOf(user.getLoginUserCompanyInfo().getId()));
        } else {
            throw new PluginException("当前人员没有操作权限");
        }

        if (ToolKits.isNotEmpty(vo.getShipbillNo()) || ToolKits.isNotEmpty(vo.getOrderNo())
                || ToolKits.isNotEmpty(vo.getOrderBusinessType()) || ToolKits.isNotEmpty(vo.getMesOrderNo())
                || ToolKits.isNotEmpty(vo.getConsigneeType())
                || ToolKits.isNotEmpty(vo.getConsigneeName())
                || ToolKits.isNotEmpty(vo.getItemName())) {
            vo.setPlanBillDetailCondition("has");
        }

        // 数据字典翻译数据集合
        List<SysRefdatadModel> dicData = convertorUtil.getDictionary(new String[]{DataDictionaryConstant.WHETHER,
                DataDictionaryConstant.PLAN_BILL_STATUS,
                DataDictionaryConstant.LINE_CARRIER_TYPE,
                DataDictionaryConstant.ORDER_BUSINESS_TYPE // 订单业务类型
        });

        PageUtils.startPage(vo.getPageNum(), vo.getPageSize());
        List<PlanBillQueryDTO> planBillQueryDTOS = tmsTransPlanBillHeaderMapper.queryPlanBillData(vo);

        for (PlanBillQueryDTO dto : planBillQueryDTOS) {
            dto.setCarrierTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.LINE_CARRIER_TYPE, String.valueOf(dto.getCarrierType())));
            dto.setStatusName(ConvertorUtil.getName(dicData, DataDictionaryConstant.PLAN_BILL_STATUS, String.valueOf(dto.getStatus())));
            dto.setIsWeighName(ConvertorUtil.getName(dicData, DataDictionaryConstant.WHETHER, String.valueOf(dto.getIsWeigh())));
        }
        return PageUtils.getPage(planBillQueryDTOS);
    }

    /**
     * 周日历计划单查询
     *
     * @param vo
     * @return
     */
    public List<PlanBillCalendarDTO> queryWeekPlanBillData(TransportPlanQueryVO vo) {
        ToolKits.isParamNull(vo, "周历计划单查询请求不为空");
        ToolKits.isParamNull(vo.getPlanStartDate(), "开始日期不为空");
        ToolKits.isParamNull(vo.getPlanEndDate(), "结束日期不为空");

        UserEntity user = PlgFxUsrUtils.getUserEntity();
        ToolKits.isParamNull(user, "当前人员没有操作权限");

        vo.setUserType(user.getUserType());
        vo.setEnterpriseId(user.getEnterpriseId());
        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.setConsignors(user.getConsignors().stream().toArray(Long[]::new));
            }
        } else if (user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
            vo.setCarrierId(Long.valueOf(user.getLoginUserCompanyInfo().getId()));
        } else {
            throw new PluginException("当前人员没有操作权限");
        }
        Date weekStartDate = vo.getPlanStartDate();
        Date weekEndDate = vo.getPlanEndDate();

        List<PlanBillCalendarDTO> planBillWeekDTOS = Lists.newArrayList();
        List<Date> planDateList = Lists.newArrayList();
        Date currentDt = DateUtil.offsetDay(weekStartDate, 0);
        while (DateUtil.compare(currentDt,weekEndDate) <= 0) {
            planDateList.add(currentDt);
            currentDt = DateUtil.offsetDay(currentDt, 1);
        }
        List<PlanBillHeaderQueryDTO> planBillQueryByWeekDTOS = tmsTransPlanBillHeaderMapper.queryWeekPlanBillData(vo);

        for (Date date : planDateList) {
            PlanBillCalendarDTO weekDTO = new PlanBillCalendarDTO();
            weekDTO.setPlanDate(DateUtil.format(date, "yyyy-MM-dd"));
            weekDTO.setPlanDateDD(DateUtil.format(date, "d"));
            weekDTO.setPlanCalendar(DateUtil.dayOfWeekEnum(date).toChinese().replace("星期", ""));

            List<PlanBillHeaderQueryDTO> planBillOfDayByOrderDTOS = Lists.newArrayList();
            if (ToolKits.isNotEmpty(planBillQueryByWeekDTOS)) {
                List<PlanBillHeaderQueryDTO> planBillOfDayDTOS =
                        planBillQueryByWeekDTOS.stream().filter(plan -> DateUtil.format(date, "yyyy-MM-dd").equals(DateUtil.format(plan.getPlanDate(), "yyyy-MM-dd"))).collect(Collectors.toList());
                if (ToolKits.isNotEmpty(planBillOfDayDTOS)) {
                    for (PlanBillHeaderQueryDTO queryByWeekDTO : planBillOfDayDTOS) {
                        List<PlanBillDetailCalendarDTO> planBillDetailDTOS = tmsTransPlanBillDetailMapper.queryOrderByPlanBill(queryByWeekDTO.getPlanBillId());
                        if (ToolKits.isEmpty(planBillDetailDTOS)) {
                            continue;
                        }
                        for (PlanBillDetailCalendarDTO detailDTO : planBillDetailDTOS) {
                            PlanBillHeaderQueryDTO billQueryByWeekDTO = new PlanBillHeaderQueryDTO();
                            BeanUtil.copyProperties(queryByWeekDTO, billQueryByWeekDTO);

                            billQueryByWeekDTO.setOrderNo(detailDTO.getOrderNo());
                            billQueryByWeekDTO.setTotalPcs("(" + billQueryByWeekDTO.getTotalPcs() + ")");
                            billQueryByWeekDTO.setTotalVehicleNumber("(" + billQueryByWeekDTO.getTotalVehicleNumber() + ")");

                            List<TmsShipbillDetailModel> shipbillDetailModels = tmsShipbillDetailMapper.findByIds(TmsShipbillDetailModel.class,
                                    detailDTO.getShipbillDetailIds().split(","), null);
                            if (ToolKits.isNotEmpty(shipbillDetailModels) && shipbillDetailModels.stream().anyMatch(d -> Integer.valueOf("1").equals(d.getIsTransfinite()))) {
                                billQueryByWeekDTO.setIsTransfiniteName("超限");
                            }
                            planBillOfDayByOrderDTOS.add(billQueryByWeekDTO);
                        }
                    }
                }
            }
            weekDTO.setPlanBillDTOS(planBillOfDayByOrderDTOS);
            planBillWeekDTOS.add(weekDTO);
        }

        return planBillWeekDTOS;
    }

    /**
     * 月日历计划单查询
     *
     * @param vo
     * @return
     */
    public List<PlanBillCalendarDTO> queryMonthPlanBillData(TransportPlanQueryVO vo) {
        ToolKits.isParamNull(vo, "月日历计划单查询请求不为空");
        ToolKits.isParamNull(vo.getPlanStartDate(), "开始日期不为空");
        ToolKits.isParamNull(vo.getPlanEndDate(), "结束日期不为空");

        UserEntity user = PlgFxUsrUtils.getUserEntity();
        ToolKits.isParamNull(user, "当前人员没有操作权限");

        vo.setUserType(user.getUserType());
        vo.setEnterpriseId(user.getEnterpriseId());
        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.setConsignors(user.getConsignors().stream().toArray(Long[]::new));
            }
        } else if (user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
            vo.setCarrierId(Long.valueOf(user.getLoginUserCompanyInfo().getId()));
        } else {
            throw new PluginException("当前人员没有操作权限");
        }
        Date monthStartDate = vo.getPlanStartDate();
        Date monthEndDate = vo.getPlanEndDate();

        Date currentMonthStartDate = DateUtil.beginOfMonth(DateUtil.date());
        Date currentMonthEndDate = DateUtil.endOfMonth(DateUtil.date());

        List<PlanBillCalendarDTO> planBillMonthDTOS = Lists.newArrayList();
        List<Date> planDateList = Lists.newArrayList();
        Date currentDt = monthStartDate;
        while (DateUtil.compare(currentDt,monthEndDate) <= 0) {
            planDateList.add(currentDt);
            currentDt = DateUtil.offsetDay(currentDt, 1);
        }
        List<PlanBillHeaderQueryDTO> planBillQueryByMonthDTOS = tmsTransPlanBillHeaderMapper.queryMonthPlanBillData(vo);

        for (Date date : planDateList) {
            PlanBillCalendarDTO monthDTO = new PlanBillCalendarDTO();
            monthDTO.setPlanDate(DateUtil.format(date, "yyyy-MM-dd"));
            monthDTO.setPlanCalendar(DateUtil.format(date, "d"));

            if (ToolKits.isNotEmpty(planBillQueryByMonthDTOS)) {
                List<PlanBillHeaderQueryDTO> planBillOfDayDTOS =
                        planBillQueryByMonthDTOS.stream().filter(plan -> DateUtil.format(date, "yyyy-MM-dd").equals(DateUtil.format(plan.getPlanDate(), "yyyy-MM-dd"))).collect(Collectors.toList());
                monthDTO.setPlanBillDTOS(planBillOfDayDTOS);
            }
            if (DateUtil.compare(currentMonthStartDate, date) > 0 || DateUtil.compare(currentMonthEndDate, date) < 0) {
                monthDTO.setIsGrey("1");
            } else {
                monthDTO.setIsGrey("0");
            }

            planBillMonthDTOS.add(monthDTO);
        }

        return planBillMonthDTOS;
    }

    /**
     * 计划单详情查询
     *
     * @param vo
     * @return
     */
    public PlanBillViewQueryDTO queryPlanBillViewData(TransportPlanQueryVO vo) {
        ToolKits.isParamNull(vo, "计划单详情查询请求不为空");
        ToolKits.isParamNull(vo.getPlanBillId(), "计划单ID不为空");

        UserEntity user = PlgFxUsrUtils.getUserEntity();
        ToolKits.isParamNull(user, "当前人员没有操作权限");
        PlanBillViewQueryDTO viewQueryDTO = new PlanBillViewQueryDTO();


        // 数据字典翻译数据集合
        List<SysRefdatadModel> dicData = convertorUtil.getDictionary(new String[]{DataDictionaryConstant.WHETHER,
                DataDictionaryConstant.PLAN_BILL_STATUS,
                DataDictionaryConstant.SHIPBILL_STATUS,
                DataDictionaryConstant.ORDER_BUSINESS_TYPE // 订单业务类型
        });
        List<PlanBillQueryDTO> planBillQueryDTOS = tmsTransPlanBillHeaderMapper.queryPlanBillData(vo);
        if (ToolKits.isEmpty(planBillQueryDTOS)) {
            throw new PluginException(StrUtil.format("计划单{}不存在", vo.getPlanBillId()));
        }
        PlanBillQueryDTO planBillQueryDTO = planBillQueryDTOS.get(0);
        BeanUtil.copyProperties(planBillQueryDTO, viewQueryDTO);

        viewQueryDTO.setStatusName(ConvertorUtil.getName(dicData, DataDictionaryConstant.PLAN_BILL_STATUS, String.valueOf(planBillQueryDTO.getStatus())));
        viewQueryDTO.setIsWeighName(ConvertorUtil.getName(dicData, DataDictionaryConstant.WHETHER, String.valueOf(planBillQueryDTO.getIsWeigh())));
        if (ToolKits.isEmpty(viewQueryDTO.getProductName())) {
            viewQueryDTO.setProductName("");
        }
        PlanBillDetailQueryVO detailQueryVO = new PlanBillDetailQueryVO();
        detailQueryVO.setPlanBillId(vo.getPlanBillId());
        List<PlanBillDetailDTO> planBillDetailDTOS = tmsTransPlanBillDetailMapper.queryPlanBillDetail(detailQueryVO);

        if (ToolKits.isEmpty(planBillDetailDTOS)) {
            throw new PluginException(StrUtil.format("计划单的明细{}不存在", vo.getPlanBillId()));
        }
        List<TmsShipbillHeaderModel> colorCfglist = getShipbillColorCfg(planBillDetailDTOS.stream().map(PlanBillDetailDTO::getShipbillId).distinct().collect(Collectors.toList()));
        for (PlanBillDetailDTO detailDTO : planBillDetailDTOS) {
            detailDTO.setOrderBusinessTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.ORDER_BUSINESS_TYPE, String.valueOf(detailDTO.getOrderBusinessType())));
            detailDTO.setIsTransfiniteName(ConvertorUtil.getName(dicData, DataDictionaryConstant.WHETHER, String.valueOf(detailDTO.getIsTransfinite())));
            detailDTO.setPlanPcs(planBillQueryDTO.getPlanTotalPcs());
            detailDTO.setActualPcs(planBillQueryDTO.getActualTotalPcs());
            detailDTO.setTransfiniteCommitDate(planBillQueryDTO.getTransfiniteCommitDate());
            detailDTO.setTransfiniteDescription(planBillQueryDTO.getTransfiniteDescription());
            detailDTO.setIsWeighName(ConvertorUtil.getName(dicData, DataDictionaryConstant.WHETHER, String.valueOf(planBillQueryDTO.getIsWeigh())));

            if (ToolKits.isEmpty(colorCfglist)) {
                continue;
            }
            List<TmsShipbillHeaderModel> currShipbillCfg = colorCfglist.stream().filter(c->c.getShipbillId().equals(detailDTO.getShipbillId())).collect(Collectors.toList());
            if (ToolKits.isEmpty(currShipbillCfg)) {
                continue;
            }
            detailDTO.setStatus(currShipbillCfg.get(0).getStatus());
            detailDTO.setStatusName(ConvertorUtil.getName(dicData, DataDictionaryConstant.SHIPBILL_STATUS, String.valueOf(currShipbillCfg.get(0).getStatus())));

            if (!DataDictionaryConstant.WHETHER_YES.equals(detailDTO.getIsTransfinite())) {
                continue;
            }
            detailDTO.setColorTagBgdColor(currShipbillCfg.get(0).getColorTagBgdColor());
            detailDTO.setColorTagFontColor(currShipbillCfg.get(0).getColorTagFontColor());
            detailDTO.setRecordTagWord(currShipbillCfg.get(0).getRecordTagWord());
        }
        viewQueryDTO.setPlanBillDetailDTOS(planBillDetailDTOS);

        viewQueryDTO.setTotalPcs(planBillDetailDTOS.stream().map(PlanBillDetailDTO::getPcs).reduce(BigDecimal.ZERO, NumberUtil::add));
        viewQueryDTO.setTotalWeight(planBillDetailDTOS.stream().map(PlanBillDetailDTO::getWeight).reduce(BigDecimal.ZERO, NumberUtil::add));
        viewQueryDTO.setTotalVolume(planBillDetailDTOS.stream().map(PlanBillDetailDTO::getVolume).reduce(BigDecimal.ZERO, NumberUtil::add));

        return viewQueryDTO;
    }

    /**
     * 计划单运单明细详情查询
     *
     * @param vo
     * @return
     */
    public List<PlanBillDetailDTO> queryPlanBillDetailViewData(TransportPlanQueryVO vo) {
        ToolKits.isParamNull(vo, "计划单详情查询请求不为空");
        ToolKits.isParamNull(vo.getPlanBillId(), "计划单ID不为空");

        UserEntity user = PlgFxUsrUtils.getUserEntity();
        ToolKits.isParamNull(user, "当前人员没有操作权限");

        // 数据字典翻译数据集合
        List<SysRefdatadModel> dicData = convertorUtil.getDictionary(new String[]{DataDictionaryConstant.WHETHER,
                DataDictionaryConstant.PLAN_BILL_STATUS,
                DataDictionaryConstant.SHIPBILL_STATUS,
                DataDictionaryConstant.ORDER_BUSINESS_TYPE // 订单业务类型
        });

        PlanBillDetailQueryVO detailQueryVO = new PlanBillDetailQueryVO();
        detailQueryVO.setPlanBillId(vo.getPlanBillId());
        detailQueryVO.setIsDispatch(vo.getIsDispatch());
        List<PlanBillDetailDTO> planBillDetailDTOS = tmsTransPlanBillDetailMapper.queryPlanBillDetail(detailQueryVO);
        if (ToolKits.isEmpty(planBillDetailDTOS)) {
            return planBillDetailDTOS;
        }
        List<TmsTransPlanBillHeaderModel> planBillHeaderModels = tmsTransPlanBillHeaderMapper.findByIds(TmsTransPlanBillHeaderModel.class,planBillDetailDTOS.stream().map(PlanBillDetailDTO::getPlanBillId).distinct().toArray(),null);
        if (ToolKits.isEmpty(planBillHeaderModels)) {
            return planBillDetailDTOS;
        }
        List<TmsShipbillHeaderModel> colorCfglist = null;
        colorCfglist = getShipbillColorCfg(planBillDetailDTOS.stream().map(PlanBillDetailDTO::getShipbillId).distinct().collect(Collectors.toList()));
        for (PlanBillDetailDTO detailDTO : planBillDetailDTOS) {
            detailDTO.setOrderBusinessTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.ORDER_BUSINESS_TYPE, String.valueOf(detailDTO.getOrderBusinessType())));
            detailDTO.setIsTransfiniteName(ConvertorUtil.getName(dicData, DataDictionaryConstant.WHETHER, String.valueOf(detailDTO.getIsTransfinite())));

            List<TmsTransPlanBillHeaderModel> currPlanBillHeaderModels = planBillHeaderModels.stream().filter(h->h.getPlanBillId().equals(detailDTO.getPlanBillId())).collect(Collectors.toList());
            if (ToolKits.isNotEmpty(currPlanBillHeaderModels)) {
                detailDTO.setIsWeighName(ConvertorUtil.getName(dicData, DataDictionaryConstant.WHETHER, String.valueOf(currPlanBillHeaderModels.get(0).getIsWeigh())));
                detailDTO.setTransfiniteCommitDate(currPlanBillHeaderModels.get(0).getTransfiniteCommitDate());
            }
            if (ToolKits.isEmpty(colorCfglist)) {
                continue;
            }
            List<TmsShipbillHeaderModel> currShipbillCfg = colorCfglist.stream().filter(c->c.getShipbillId().equals(detailDTO.getShipbillId())).collect(Collectors.toList());
            if (ToolKits.isEmpty(currShipbillCfg)) {
                continue;
            }
            detailDTO.setStatus(currShipbillCfg.get(0).getStatus());
            detailDTO.setStatusName(ConvertorUtil.getName(dicData, DataDictionaryConstant.SHIPBILL_STATUS, String.valueOf(currShipbillCfg.get(0).getStatus())));

            if (!DataDictionaryConstant.WHETHER_YES.equals(detailDTO.getIsTransfinite())) {
                continue;
            }
            detailDTO.setColorTagBgdColor(currShipbillCfg.get(0).getColorTagBgdColor());
            detailDTO.setColorTagFontColor(currShipbillCfg.get(0).getColorTagFontColor());
            detailDTO.setRecordTagWord(currShipbillCfg.get(0).getRecordTagWord());

        }
        return planBillDetailDTOS;
    }

    private List<TmsShipbillHeaderModel> getShipbillColorCfg(List<String> shipbillIds) {
        FieldSelector hfield = FieldSelector.newInstance().include(new String[] { "status","shipbillId", "colorTagBgdColor", "colorTagFontColor","recordTagWord" });
        List<TmsShipbillHeaderModel> colorCfglist = tmsShipbillHeaderMapper.findByIds(TmsShipbillHeaderModel.class,shipbillIds.stream().toArray(),hfield);
        return colorCfglist;
    }


    /**
     * 所有计划单导出
     *
     * @param
     * @return
     */
    public List<PlanBillExportDTO> export(TransportPlanQueryVO vo) throws Exception {
        ToolKits.isParamNull(vo, "所有计划单导出请求不为空");

        UserEntity user = PlgFxUsrUtils.getUserEntity();
        ToolKits.isParamNull(user, "当前人员没有操作权限");

        vo.setUserType(user.getUserType());
        vo.setEnterpriseId(user.getEnterpriseId());
        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.setConsignors(user.getConsignors().stream().toArray(Long[]::new));
            }
        }  else if (user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
            vo.setCarrierId(Long.valueOf(user.getLoginUserCompanyInfo().getId()));
        } else {
            throw new PluginException("当前人员没有操作权限");
        }

        if (ToolKits.isNotEmpty(vo.getShipbillNo()) || ToolKits.isNotEmpty(vo.getOrderNo())
                || ToolKits.isNotEmpty(vo.getOrderBusinessType()) || ToolKits.isNotEmpty(vo.getMesOrderNo())
                || ToolKits.isNotEmpty(vo.getConsigneeType())
                || ToolKits.isNotEmpty(vo.getConsigneeName())
                || ToolKits.isNotEmpty(vo.getItemName())) {
            vo.setPlanBillDetailCondition("has");
        }

        // 数据字典翻译数据集合
        List<SysRefdatadModel> dicData = convertorUtil.getDictionary(new String[]{DataDictionaryConstant.WHETHER,
                DataDictionaryConstant.PLAN_BILL_STATUS,
                DataDictionaryConstant.LINE_CARRIER_TYPE,
                DataDictionaryConstant.ORDER_BUSINESS_TYPE // 订单业务类型
        });

        List<PlanBillQueryDTO> planBillQueryDTOS = tmsTransPlanBillHeaderMapper.queryPlanBillData(vo);

        List<PlanBillExportDTO> planBillExportDTOS = Lists.newArrayList();
        for (PlanBillQueryDTO dto : planBillQueryDTOS) {
            PlanBillExportDTO exportDTO = new PlanBillExportDTO();
            BeanUtil.copyProperties(dto, exportDTO);
            exportDTO.setCarrierTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.LINE_CARRIER_TYPE, String.valueOf(dto.getCarrierType())));
            exportDTO.setStatusName(ConvertorUtil.getName(dicData, DataDictionaryConstant.PLAN_BILL_STATUS, String.valueOf(dto.getStatus())));
            planBillExportDTOS.add(exportDTO);
        }
        return planBillExportDTOS;
    }

    /**
     * 计划单分页导出
     *
     * @param
     * @return
     */
    public List<PlanBillExportDTO> exportPage(TransportPlanQueryVO vo) throws Exception {
        ToolKits.isParamNull(vo, "计划单分页导出请求不为空");
        ToolKits.isParamNull(vo.getPageNum(), "当前页码不为空");
        ToolKits.isParamNull(vo.getPageSize(), "每页条数不为空");

        UserEntity user = PlgFxUsrUtils.getUserEntity();
        ToolKits.isParamNull(user, "当前人员没有操作权限");

        vo.setUserType(user.getUserType());
        vo.setEnterpriseId(user.getEnterpriseId());
        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.setConsignors(user.getConsignors().stream().toArray(Long[]::new));
            }
        }  else if (user.getUserType().equals(BussinessConstant.USER_TYPE_CYS)) {
            vo.setCarrierId(Long.valueOf(user.getLoginUserCompanyInfo().getId()));
        } else {
            throw new PluginException("当前人员没有操作权限");
        }

        if (ToolKits.isNotEmpty(vo.getShipbillNo()) || ToolKits.isNotEmpty(vo.getOrderNo())
                || ToolKits.isNotEmpty(vo.getOrderBusinessType()) || ToolKits.isNotEmpty(vo.getMesOrderNo())
                || ToolKits.isNotEmpty(vo.getConsigneeType())
                || ToolKits.isNotEmpty(vo.getConsigneeName())
                || ToolKits.isNotEmpty(vo.getItemName())) {
            vo.setPlanBillDetailCondition("has");
        }

        // 数据字典翻译数据集合
        List<SysRefdatadModel> dicData = convertorUtil.getDictionary(new String[]{DataDictionaryConstant.WHETHER,
                DataDictionaryConstant.PLAN_BILL_STATUS,
                DataDictionaryConstant.LINE_CARRIER_TYPE,
                DataDictionaryConstant.ORDER_BUSINESS_TYPE // 订单业务类型
        });

        PageUtils.startPage(vo.getPageNum(), vo.getPageSize());
        List<PlanBillQueryDTO> planBillQueryDTOS = tmsTransPlanBillHeaderMapper.queryPlanBillData(vo);

        List<PlanBillExportDTO> planBillExportDTOS = Lists.newArrayList();
        for (PlanBillQueryDTO dto : planBillQueryDTOS) {
            PlanBillExportDTO exportDTO = new PlanBillExportDTO();
            BeanUtil.copyProperties(dto, exportDTO);
            exportDTO.setCarrierTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.LINE_CARRIER_TYPE, String.valueOf(dto.getCarrierType())));
            exportDTO.setStatusName(ConvertorUtil.getName(dicData, DataDictionaryConstant.PLAN_BILL_STATUS, String.valueOf(dto.getStatus())));
            planBillExportDTOS.add(exportDTO);
        }
        return planBillExportDTOS;
    }

    /**
     * 计划单选择行导出
     *
     * @param
     * @return
     */
    public List<PlanBillExportDTO> exportSelected(List<String> planBillIds) throws Exception {
        ToolKits.isParamNull(planBillIds, "计划单选择行导出请求不为空");

        UserEntity user = PlgFxUsrUtils.getUserEntity();
        ToolKits.isParamNull(user, "当前人员没有操作权限");


        // 数据字典翻译数据集合
        List<SysRefdatadModel> dicData = convertorUtil.getDictionary(new String[]{DataDictionaryConstant.WHETHER,
                DataDictionaryConstant.PLAN_BILL_STATUS,
                DataDictionaryConstant.LINE_CARRIER_TYPE,
                DataDictionaryConstant.ORDER_BUSINESS_TYPE // 订单业务类型
        });
        Criteria criteriaPlanBillHeader = Criteria.forClass(TmsTransPlanBillHeaderModel.class);
        Restriction r1 = Restrictions.in(TmsTransPlanBillHeaderModel::getPlanBillId, planBillIds.stream().toArray());
        Restriction r2 = Restrictions.eq(TmsTransPlanBillHeaderModel::getEnterpriseId, user.getEnterpriseId());
        criteriaPlanBillHeader.setRestriction(Restrictions.and(r1, r2));
        criteriaPlanBillHeader.setOrder(Order.newInstance().desc(new String[]{"updatetime"}));
        List<TmsTransPlanBillHeaderModel> planBillQueryDTOS = tmsTransPlanBillHeaderMapper.findByCriteria(criteriaPlanBillHeader);

        List<PlanBillExportDTO> planBillExportDTOS = Lists.newArrayList();
        for (TmsTransPlanBillHeaderModel dto : planBillQueryDTOS) {
            PlanBillExportDTO exportDTO = new PlanBillExportDTO();
            BeanUtil.copyProperties(dto, exportDTO);
            exportDTO.setCarrierTypeName(ConvertorUtil.getName(dicData, DataDictionaryConstant.LINE_CARRIER_TYPE, String.valueOf(dto.getCarrierType())));
            exportDTO.setStatusName(ConvertorUtil.getName(dicData, DataDictionaryConstant.PLAN_BILL_STATUS, String.valueOf(dto.getStatus())));
            planBillExportDTOS.add(exportDTO);
        }
        return planBillExportDTOS;
    }

}
