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

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.netflix.hystrix.strategy.concurrency.HystrixRequestContext;
import com.prolog.cs.platform.power.model.Organization;
import com.prolog.framework.authority.util.HystrixVarUtil;
import com.prolog.framework.common.message.RestMessage;
import com.prolog.framework.core.exception.ParameterException;
import com.prolog.framework.core.exception.PrologException;
import com.prolog.framework.core.pojo.Page;
import com.prolog.framework.core.restriction.Criteria;
import com.prolog.framework.core.restriction.Order;
import com.prolog.framework.core.restriction.Restriction;
import com.prolog.framework.core.restriction.Restrictions;
import com.prolog.framework.dao.util.PageUtils;
import com.prolog.framework.lock.DistributedLock;
import com.prolog.product.core.easyexcel.util.ExcelUtils;
import com.prolog.product.core.framework.entity.UserEntity;
import com.prolog.product.core.framework.util.PlgFxUsrUtils;
import com.prolog.product.core.tools.util.JsonMapper;
import com.prolog.product.core.tools.util.ToolKits;
import com.prolog.rdc.tms.constant.BmsConstant;
import com.prolog.rdc.tms.dao.mapper.*;
import com.prolog.rdc.tms.model.dto.*;
import com.prolog.rdc.tms.model.dto.basicConfigure.StandardTemplateDetailsListDTO;
import com.prolog.rdc.tms.model.dto.basicData.BranchByNameDTO;
import com.prolog.rdc.tms.model.dto.basicData.CargoOwnerByEncodingNameDTO;
import com.prolog.rdc.tms.model.dto.basicData.ItemByEncodingNameDTO;
import com.prolog.rdc.tms.model.entity.*;
import com.prolog.rdc.tms.model.vo.*;
import com.prolog.rdc.tms.model.vo.basicConfigure.ImportLogAddVO;
import com.prolog.rdc.tms.model.vo.basicData.BranchByNameVO;
import com.prolog.rdc.tms.model.vo.basicData.CargoOwnerByEncodingNameVO;
import com.prolog.rdc.tms.model.vo.basicData.ItemByEncodingNameVO;
import com.prolog.rdc.tms.rmi.feign.MaindataFeign;
import com.prolog.rdc.tms.rmi.feign.UserFeign;
import com.prolog.rdc.tms.service.BillIncomeCostStrategyService;
import com.prolog.rdc.tms.service.ShipBillService;
import com.prolog.rdc.tms.service.ShipCostStrategyService;
import com.prolog.rdc.tms.util.ConvertorUtil;
import com.prolog.rdc.tms.util.FileUtils;
import com.prolog.rdc.tms.util.ImportUtils;
import com.prolog.rdc.tms.util.PublicMethods;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.plugin.PluginException;
import org.redisson.api.RLock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ShipBillServiceImpl implements ShipBillService {

    private final Logger logger = LoggerFactory.getLogger(ShipBillServiceImpl.class);

    @Autowired
    private ShipBillHeadMapper shipBillHeadMapper;
    @Autowired
    private LoadingBillHeadMapper loadingBillHeadMapper;
    @Autowired
    private ShipBillDetailMapper shipBillDetailMapper;
    @Autowired
    private MaindataFeign maindataTmsResource;
    @Autowired
    private ConvertorUtil convertorUtil;
    @Autowired
    private BmsLogOperationMapper logOperationMapper;
    @Autowired
    private BmsShipBillAdjustMapper shipBillAdjustMapper;
    @Autowired
    private BmsShipBillPackageMapper shipBillPackageMapper;
    @Autowired
    private ShipBillFeeDetailMapper shipBillFeeDetailMapper;
    @Autowired
    private UserFeign userTmsResource;
    @Autowired
    private ExpenseManagementMapper managementMapper;
    @Autowired
    private ExpenseAccountMapper accountMapper;
    @Autowired
    private ShipCostStrategyService shipCostStrategyService;
    @Autowired
    private BillIncomeCostStrategyService billIncomeCostStrategyService;
    @Autowired
    private ShipBillFeeTemporaryDetailMapper temporaryDetailMapper;

    @Autowired
    private DistributedLock distributedLock;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(ShipBillVO vo) {
        logger.info("运单管理新增：" + JSONObject.toJSONString(vo));
        UserEntity user = new UserEntity();
        try {
            user = PlgFxUsrUtils.getUserEntity();
        } catch (Exception exception) {
            user.setOrganizationId(vo.getOrganizationId());
            user.setOrgnaizationName(vo.getOrganizationName());
            user.setNickname(vo.getNickname());
            user.setEnterpriseId(vo.getEnterpriseId());
            user.setEnterpriseName(vo.getEnterpriseName());
        }

        BmsShipBillHeaderModel model = new BmsShipBillHeaderModel();
        BeanUtils.copyProperties(vo, model);
        try {
            // 获取运单汇总ID
            String shipBillno = "";
            if (ObjectUtil.isNotEmpty(vo.getShipbillNo())) {
                shipBillno = vo.getShipbillNo();
                model.setSource(BmsConstant.TMS_DOWN);
                model.setSynchronousStatus(BmsConstant.SYNCHRONOUS_STATUS_SUCCESS);
            } else {
                if (ObjectUtil.isEmpty(vo.getShipperType())) {
                    throw new PrologException("发货方类型不能为空");
                }
                if (ObjectUtil.isEmpty(vo.getShipperUnitCode())) {
                    throw new PrologException("发货方单位不能为空");
                }
                if (ObjectUtil.isEmpty(vo.getShipperAddress())) {
                    throw new PrologException("发货方详细地址不能为空");
                }
                if (ObjectUtil.isEmpty(vo.getConsigneeType())) {
                    throw new PrologException("收货方类型不能为空");
                }
                if (ObjectUtil.isEmpty(vo.getConsigneeUnitCode())) {
                    throw new PrologException("收货方单位编码不能为空");
                }
                if (ObjectUtil.isEmpty(vo.getConsigneeAddress())) {
                    throw new PrologException("收货方详细地址不能为空");
                }

                RestMessage<String> restMessage = maindataTmsResource.getCodeNumberByCode(BmsConstant.SHIP_BILL_HEAD_ID, "L");
                if (!restMessage.isSuccess()) {
                    throw new RuntimeException("生成运单汇总ID失败");
                }
                shipBillno = restMessage.getData();
                model.setSource(BmsConstant.SOURCE_ADD);
            }

            model.setShipbillNo(shipBillno);
            model.setOrganizationId(user.getOrganizationId());
            model.setOrganizationCode(String.valueOf(user.getOrganizationId()));
            model.setOrganizationName(user.getOrgnaizationName());
            model.setCreateperson(user.getNickname());
            model.setCreatetime(DateUtil.date());
            model.setUpdateperson(user.getNickname());
            model.setUpdatetime(DateUtil.date());
            model.setEnterpriseId(user.getEnterpriseId());
            model.setEnterpriseName(user.getEnterpriseName());

            model.setStatus(BmsConstant.SHIPBILL_STATUS_END);
            model.setShipBillStatus(BmsConstant.SHIPBILL_STATUS_END);
            model.setShipperProvinceCityDistrict(vo.getShipperProvinceName() + "" + vo.getShipperCityName() + "" + vo.getShipperDistrictName());
            model.setConsigneeProvinceCityDistrict(vo.getConsigneeProvinceName() + "" + vo.getConsigneeCityName() + "" + vo.getConsigneeDistrictName());
            model.setCompletionDate(DateUtil.date());
            if (ObjectUtil.isNotEmpty(vo.getIsAccount())) {
                if (vo.getIsAccount().intValue() == 0) {
                    model.setSettlementStatus(BmsConstant.SETTLEMENT_STATUS_0);
                } else {
                    model.setSettlementStatus(BmsConstant.SETTLEMENT_STATUS_1);
                }
            } else {
                model.setSettlementStatus(BmsConstant.SETTLEMENT_STATUS_0);
            }
            List<BmsShipBillDetailVO> list = vo.getList();
            List<BmsShipBillDetailModel> models = Lists.newArrayList();
            AtomicInteger seqNo = new AtomicInteger(1);

            RestMessage<SySParameterDTO> parameterModel = maindataTmsResource.queryParameter();
            if (ObjectUtil.isEmpty(parameterModel) || !parameterModel.isSuccess()) {
                throw new PluginException("请先配置系统参数");
            }
            Integer weightPrecision = parameterModel.getData().getWeightPrecision();
            Integer weightInteger = parameterModel.getData().getWeightInteger();

            Integer volumePrecision = parameterModel.getData().getVolumePrecision();
            Integer volumeInteger = parameterModel.getData().getVolumeInteger();
            BigDecimal totWeight = new BigDecimal(0);
            BigDecimal totVolume = new BigDecimal(0);
            for (BmsShipBillDetailVO shipBillDetailVO : list) {
                log.info("运单明细数据:" + JSON.toJSONString(list));
                BmsShipBillDetailModel detailModel = new BmsShipBillDetailModel();
                BeanUtils.copyProperties(shipBillDetailVO, detailModel);
                BigDecimal weight = shipBillDetailVO.getWeight();
                BigDecimal volume = shipBillDetailVO.getVolume();

                // 四舍五入
                if (weightInteger == 1) {
                    detailModel.setWeight(weight.divide(BigDecimal.valueOf(1), weightPrecision, RoundingMode.HALF_UP));
                }
                // 向上取整
                if (weightInteger == 2) {
                    detailModel.setWeight(weight.divide(BigDecimal.valueOf(1), weightPrecision, RoundingMode.UP));
                }
                // 向下取整
                if (weightInteger == 3) {
                    detailModel.setWeight(weight.divide(BigDecimal.valueOf(1), weightPrecision, RoundingMode.DOWN));
                }

                // 四舍五入
                if (volumeInteger == 1) {
                    detailModel.setVolume(volume.divide(BigDecimal.valueOf(1), volumePrecision, RoundingMode.HALF_UP));
                }
                // 向上取整
                if (volumeInteger == 2) {
                    detailModel.setVolume(volume.divide(BigDecimal.valueOf(1), volumePrecision, RoundingMode.UP));
                }
                // 向下取整
                if (volumeInteger == 3) {
                    detailModel.setVolume(volume.divide(BigDecimal.valueOf(1), volumePrecision, RoundingMode.DOWN));
                }
                detailModel.setShipbillNo(model.getShipbillNo());
                detailModel.setCreateperson(user.getNickname());
                detailModel.setCreatetime(DateUtil.date());
                detailModel.setUpdateperson(user.getNickname());
                detailModel.setUpdatetime(DateUtil.date());
                detailModel.setEnterpriseId(user.getEnterpriseId());
                detailModel.setEnterpriseName(user.getEnterpriseName());
                detailModel.setSeqno(seqNo.get());

                shipBillDetailMapper.save(detailModel);
                totWeight = totWeight.add(detailModel.getWeight());
                totVolume = totVolume.add(detailModel.getVolume());
                seqNo.getAndIncrement();
                // models.add(detailModel);
            }
            /*
             * if (ObjectUtil.isNotEmpty(models)) { shipBillDetailMapper.saveBatch(models);
             * }
             */

            List<BmsShipBillPackVO> packList = vo.getPackList();
            List<BmsShipBillPackageModel> packageModelList = Lists.newArrayList();
            AtomicInteger packSeqNo = new AtomicInteger(1);
            BigDecimal packageTotalVolume = BigDecimal.valueOf(0);
            BigDecimal packageTotalWeight = BigDecimal.valueOf(0);
            if (ObjectUtil.isNotEmpty(packList)) {
                for (BmsShipBillPackVO shipBillDetailVO : packList) {
                    BmsShipBillPackageModel detailModel = new BmsShipBillPackageModel();
                    BeanUtils.copyProperties(shipBillDetailVO, detailModel);
                    detailModel.setShipbillNo(model.getShipbillNo());
                    detailModel.setCreateperson(user.getNickname());
                    detailModel.setCreatetime(DateUtil.date());
                    BigDecimal packageVolume = detailModel.getPackageTotalVolume();
                    packageTotalVolume = packageTotalVolume.add(packageVolume);
                    BigDecimal packageWeight = detailModel.getPackageTotalWeight();
                    packageTotalWeight = packageTotalVolume.add(packageWeight);
                    detailModel.setUpdateperson(user.getNickname());
                    detailModel.setUpdatetime(DateUtil.date());
                    detailModel.setEnterpriseId(user.getEnterpriseId());
                    detailModel.setEnterpriseName(user.getEnterpriseName());
                    detailModel.setSeqNo(packSeqNo.get());
                    packSeqNo.getAndIncrement();
                    packageModelList.add(detailModel);
                }
            }
            if (ObjectUtil.isNotEmpty(packageModelList)) {
                shipBillPackageMapper.saveBatch(packageModelList);
            }
            // 调整单
            BmsShipBillAdjustModel adjustModel = new BmsShipBillAdjustModel();
            adjustModel.setShipbillNo(shipBillno);
            adjustModel.setAdjustMemo("新增件数" + model.getTotalPcs());
            adjustModel.setAdjustDate(DateUtil.date());
            adjustModel.setAdjustName(user.getNickname());
            adjustModel.setCreateperson(user.getNickname());
            adjustModel.setCreatetime(DateUtil.date());
            adjustModel.setUpdateperson(user.getNickname());
            adjustModel.setUpdatetime(DateUtil.date());
            adjustModel.setEnterpriseId(user.getEnterpriseId());
            adjustModel.setEnterpriseName(user.getEnterpriseName());
            shipBillAdjustMapper.save(adjustModel);

            // 日志操作
            BmsLogOperationModel logVO = new BmsLogOperationModel();
            logVO.setCreatetime(DateUtil.date());
            logVO.setCreateperson(user.getNickname());
            logVO.setEnterpriseId(user.getEnterpriseId());
            logVO.setEnterpriseName(user.getEnterpriseName());
            logVO.setOrderNo(shipBillno);
            logVO.setLogMemo("新增运单");
            logVO.setLogType(1);
            logOperationMapper.save(logVO);

            model.setPackageTotalVolume(packageTotalVolume);
            model.setPackageTotalWeight(packageTotalWeight);
            model.setAbnormalStatus(0);
            model.setTotalWeight(vo.getTotalWeight());
            model.setTotalVolume(vo.getTotalVolume());
            // 核算
            if (vo.getIsAccount().intValue() == 1) {
                // 核算待提交
                model.setSettlementStatus(BmsConstant.SETTLEMENT_STATUS_1);
            } else {
                // 未核算
                model.setSettlementStatus(BmsConstant.SETTLEMENT_STATUS_0);
            }
            BmsShipBillDTO dto = new BmsShipBillDTO();
            dto.setDetailModelList(models);
            dto.setModel(model);
            List<ShipBillPriceDTO> costStrategy = shipCostStrategyService.costStrategy(dto, "1");
            if (ObjectUtil.isEmpty(costStrategy)) {
                throw new PluginException("没有匹配到价格数据,或者价格数据重复");
            }
            for (ShipBillPriceDTO priceDTO : costStrategy) {
                model.setCostContract(priceDTO.getCostContract());
                model.setCostDate(DateUtil.date());
                // 支出总价 类型为支出的含税金额
                // model.setPayAmount(priceDTO.getPayAmount());
                // 类型为支出的来源是价格表生成 含税金额
                // model.setContractPayAmount(priceDTO.getContractPayAmount());
                model.setTransportationPrice(priceDTO.getPrice());
                model.setSettlementCompanyId(priceDTO.getFirstPartyId());
                model.setSettlementCompanyCode(priceDTO.getFirstPartyCode());
                model.setSettlementCompany(priceDTO.getFirstPartyName());
                model.setAbnormalStatus(0);
                model.setCostStatus(1);

                BmsLogOperationModel feeVo = new BmsLogOperationModel();
                feeVo.setCreatetime(DateUtil.date());
                feeVo.setCreateperson(user.getNickname());
                feeVo.setEnterpriseId(user.getEnterpriseId());
                feeVo.setEnterpriseName(user.getEnterpriseName());
                feeVo.setOrderNo(shipBillno);
                feeVo.setLogMemo("匹配价格表" + priceDTO.getCostPriceTable());
                feeVo.setLogType(1);
                logOperationMapper.save(feeVo);
            }
            // 支出总价 类型为支出的含税金额
            BigDecimal payAmount = getShipbillTaxAmt(model.getShipbillNo(), null);
            model.setPayAmount(payAmount);
            // 类型为支出的来源是价格表生成 含税金额
            BigDecimal contractPayAmount = getShipbillTaxAmt(model.getShipbillNo(), 1);
            model.setContractPayAmount(contractPayAmount);
        } catch (Exception exception) {
            model.setCostFailReason(exception.getMessage());
            model.setAbnormalStatus(1);
            model.setCostStatus(2);
            model.setSettlementStatus(BmsConstant.SETTLEMENT_STATUS_0);

        }
        if (ObjectUtil.isNotEmpty(vo.getShipbillNo())) {
            model.setSynchronousStatus(BmsConstant.SYNCHRONOUS_STATUS_FAILED);
        }
        model.setSettlementDepartment(vo.getSettlementDepartment());
        model.setSettlementDepartmentId(vo.getSettlementDepartmentId());
        model.setSettlementDepartmentCode(vo.getSettlementDepartmentCode());
        if (ObjectUtil.isNotEmpty(vo.getShipbillNo())) {
            model.setDepartmentName(vo.getDepartmentName());
        }
        shipBillHeadMapper.save(model);
    }

    @Override
    public Page<ShipBillDTO> findList(ShipBillManagementQueryVO vo) throws ParseException {
        UserEntity user = PlgFxUsrUtils.getUserEntity();
        if (!user.getUserType().equals(BmsConstant.USER_TYPE_ZY)) {
            throw new PluginException("当前人员没有操作权限！");
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Criteria criteria = Criteria.forClass(BmsShipBillHeaderModel.class);
        Restriction r1 = ObjectUtil.isEmpty(vo.getCargoOwnerName()) ? null : Restrictions.like("cargoOwnerName", "%" + vo.getCargoOwnerName() + "%");
        Restriction r2 = ObjectUtil.isEmpty(vo.getOrderNo()) ? null : Restrictions.like("orderNo", "%" + vo.getOrderNo() + "%");
        Restriction r3 = ObjectUtil.isEmpty(vo.getShipbillNo()) ? null : Restrictions.like("shipbillNo", "%" + vo.getShipbillNo() + "%");
        Restriction r4 = ObjectUtil.isEmpty(vo.getOrderBusinessType()) ? null : Restrictions.eq("orderBusinessType", vo.getOrderBusinessType());
        Restriction r5 = null;
        Restriction r6 = null;
        Restriction r7 = null;
        Restriction r8 = null;
        Restriction r9 = null;
        if (ObjectUtil.isNotEmpty(vo.getStartDate())) {
            String[] split = vo.getStartDate().split(",");
            Date startRunDate = sdf.parse(split[0]);
            Date endRunDate = sdf.parse(split[1]);
            String start = sdf.format(startRunDate);
            String end = sdf.format(endRunDate);
            r5 = Restrictions.between("startDate", start + " 00:00:00", end + " 23:59:59");
        }
        if (ObjectUtil.isNotEmpty(vo.getDeliveryDate())) {
            String[] split = vo.getDeliveryDate().split(",");
            Date deliveryStartDate = sdf.parse(split[0]);
            Date deliveryEndDate = sdf.parse(split[1]);
            String start = sdf.format(deliveryStartDate);
            String end = sdf.format(deliveryEndDate);
            r6 = Restrictions.between("deliveryDate", start + " 00:00:00", end + " 23:59:59");
        }
        if (ObjectUtil.isNotEmpty(vo.getReceiptDate())) {
            String[] split = vo.getReceiptDate().split(",");
            Date receiptStartDate = sdf.parse(split[0]);
            Date receiptEndDate = sdf.parse(split[1]);
            String start = sdf.format(receiptStartDate);
            String end = sdf.format(receiptEndDate);
            r7 = Restrictions.between("receiptDate", start + " 00:00:00", end + " 23:59:59");
        }
        if (ObjectUtil.isNotEmpty(vo.getOriginalBackDate())) {
            String[] split = vo.getOriginalBackDate().split(",");
            Date originalBackStartDate = sdf.parse(split[0]);
            Date originalBackEndDate = sdf.parse(split[1]);
            String start = sdf.format(originalBackStartDate);
            String end = sdf.format(originalBackEndDate);
            r8 = Restrictions.between("originalBackDate", start + " 00:00:00", end + " 23:59:59");
        }
        if (ObjectUtil.isNotEmpty(vo.getCompleteDate())) {
            String[] split = vo.getCompleteDate().split(",");
            Date completeStartDate = sdf.parse(split[0]);
            Date completeEndDate = sdf.parse(split[1]);
            String start = sdf.format(completeStartDate);
            String end = sdf.format(completeEndDate);
            r9 = Restrictions.between("completeDate", start + " 00:00:00", end + " 23:59:59");
        }
        Restriction r10 = ObjectUtil.isEmpty(vo.getShipperProvinceCityDistrict()) ? null : Restrictions.like("shipperProvinceCityDistrict", "%" + vo.getShipperProvinceCityDistrict() + "%");
        Restriction r11 = ObjectUtil.isEmpty(vo.getConsigneeProvinceCityDistrict()) ? null : Restrictions.like("consigneeProvinceCityDistrict", "%" + vo.getConsigneeProvinceCityDistrict() + "%");
        Restriction r12 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
        Restriction r13 = null;
        Restriction r14 = null;
        Restriction r15 = null;
        Restriction r16 = null;
        Restriction r17 = null;
        Restriction r20 = null;
        if (user.getOwnedAllDataAuthFlag().equals(BmsConstant.USER_DEPARTMENT_AUTH_Y)) {
            r13 = Restrictions.in(BmsShipBillHeaderModel::getSettlementDepartmentId, user.getDepts().toArray(new String[0]));
        } else {
            r13 = Restrictions.in(BmsShipBillHeaderModel::getSettlementDepartmentId, user.getDepts().toArray(new String[0]));
            r14 = Restrictions.in("branchId", user.getWarehouses().toArray(new Long[0]));
            r15 = Restrictions.in("cargoOwnerId", user.getConsignors().toArray(new Long[0]));
            r20 = Restrictions.and(r13, r14, r15);
        }
        if (ObjectUtil.isNotEmpty(vo.getStartTime())) {
            r16 = Restrictions.ge("createtime", vo.getStartTime());
        }
        if (ObjectUtil.isNotEmpty(vo.getEndTime())) {
            r17 = Restrictions.lt("createtime", vo.getEndTime());
        }
        Restriction r18 = ObjectUtil.isEmpty(vo.getShipperUnitName()) ? null : Restrictions.like("shipperUnitName", "%" + vo.getShipperUnitName() + "%");
        Restriction r19 = ObjectUtil.isEmpty(vo.getConsigneeUnitName()) ? null : Restrictions.like("consigneeUnitName", "%" + vo.getConsigneeUnitName() + "%");
        Restriction r21 = ObjectUtil.isEmpty(vo.getSynchronousStatus()) ? null : Restrictions.eq(BmsShipBillHeaderModel::getSynchronousStatus, vo.getSynchronousStatus());
        Restriction r22 = ObjectUtil.isEmpty(vo.getSettlementStatus()) ? null : Restrictions.eq(BmsShipBillHeaderModel::getSettlementStatus, vo.getSettlementStatus());

        Restriction r30 = ObjectUtil.isEmpty(vo.getShipperName()) ? null : Restrictions.like(BmsShipBillHeaderModel::getShipperName, "%" + vo.getShipperName() + "%");
        Restriction r31 = ObjectUtil.isEmpty(vo.getConsigneeName()) ? null : Restrictions.like(BmsShipBillHeaderModel::getConsigneeName, "%" + vo.getConsigneeName() + "%");
        Restriction r32 = ObjectUtil.isEmpty(vo.getOrderDateStart()) ? null : Restrictions.ge(BmsShipBillHeaderModel::getOrderDate, vo.getOrderDateStart());
        Restriction r33 = ObjectUtil.isEmpty(vo.getOrderDateEnd()) ? null : Restrictions.le(BmsShipBillHeaderModel::getOrderDate, vo.getOrderDateEnd());

        criteria.setRestriction(Restrictions.and(r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r20, r16, r17, r18, r19, r21, r22 , r30, r31, r32, r33));
        criteria.setOrder(Order.newInstance().desc("createtime"));

        PageUtils.startPage(vo.getPageNum(), vo.getPageSize());
        List<BmsShipBillHeaderModel> models = shipBillHeadMapper.findByCriteria(criteria);
        List<ShipBillDTO> dtos = Lists.newArrayList();

        List<SysRefdatadModel> dicData = convertorUtil.getDictionary(new String[]{BmsConstant.SHIPBILL_STATUS, // 运单状态
                BmsConstant.SHIPPER_TYPE, // 运输状态
                BmsConstant.ABNORMAL_STATUS, // 异常状态
                BmsConstant.ORDER_TYPE, // 订单类型
                BmsConstant.CONSIGNEE_TYPE, // 收货方类型
                BmsConstant.ORDER_BUSINESS_TYPE, // 订单业务类型
                BmsConstant.SETTLEMENT_STATUS, // 核算状态
                BmsConstant.SOURCE, // 来源
                BmsConstant.COST_STATUS, // 计费状态
                BmsConstant.SYNCHRONOUS_STATUS, // 同步状态
                BmsConstant.TEMPERATURE_REQUIREMENT// 温度要求
        });

        for (BmsShipBillHeaderModel model : models) {
            ShipBillDTO shipBillDTO = new ShipBillDTO();
            BeanUtils.copyProperties(model, shipBillDTO);
            shipBillDTO.setOrderTypeName(ConvertorUtil.getName(dicData, BmsConstant.ORDER_TYPE, String.valueOf(model.getOrderType())));
            shipBillDTO.setOrderBusinessTypeName(ConvertorUtil.getName(dicData, BmsConstant.ORDER_BUSINESS_TYPE, String.valueOf(model.getOrderBusinessType())));
            shipBillDTO.setTemperatureRequirementName(ConvertorUtil.getName(dicData, BmsConstant.TEMPERATURE_REQUIREMENT, String.valueOf(model.getTemperatureRequirement())));
            shipBillDTO.setShipperTypeName(ConvertorUtil.getName(dicData, BmsConstant.SHIPPER_TYPE, String.valueOf(model.getShipperType())));
            shipBillDTO.setConsigneeTypeName(ConvertorUtil.getName(dicData, BmsConstant.CONSIGNEE_TYPE, String.valueOf(model.getConsigneeType())));
            shipBillDTO.setDeliveryMethodTypeName(model.getDeliveryMethodType() == 1 ? "配送" : "自提");
            shipBillDTO.setTransportTypeName(model.getTransportType() == 1 ? "整车" : "零担");
            shipBillDTO.setStatusName(ConvertorUtil.getName(dicData, BmsConstant.SHIPBILL_STATUS, String.valueOf(model.getStatus())));
            shipBillDTO.setSourceName(ConvertorUtil.getName(dicData, BmsConstant.SOURCE, String.valueOf(model.getSource())));
            shipBillDTO.setSettlementStatusName(ConvertorUtil.getName(dicData, BmsConstant.SETTLEMENT_STATUS, String.valueOf(model.getSettlementStatus())));
            shipBillDTO.setShipBillStatusName(ConvertorUtil.getName(dicData, BmsConstant.SHIPBILL_STATUS, String.valueOf(model.getShipBillStatus())));
            shipBillDTO.setCostStatusName(ConvertorUtil.getName(dicData, BmsConstant.COST_STATUS, String.valueOf(model.getCostStatus())));
            shipBillDTO.setSynchronousStatusName(ConvertorUtil.getName(dicData, BmsConstant.SYNCHRONOUS_STATUS, String.valueOf(model.getSynchronousStatus())));
            shipBillDTO.setCarrierTypeName(model.getCarrierType() == 1 ? "承运商" : "司机");
            shipBillDTO.setAbnormalStatusName(model.getAbnormalStatus() == 1 ? "异常" : "非异常");
            if (model.getCarrierType().intValue() == 2) {
                shipBillDTO.setCarrierName(model.getDriverName());
            }
            shipBillDTO.setIsSettlement(1);
            // 查询费用单的结算状态
            if (ObjectUtil.isNotEmpty(model.getCostContract())) {
                Criteria criteriaFeeDetail = Criteria.forClass(BmsShipBillFeeDetailModel.class);
                //r1 = Restrictions.eq(BmsShipBillFeeDetailModel::getShipbillNo, model.getShipbillNo());
                r2 = Restrictions.eq(BmsShipBillFeeDetailModel::getEnterpriseId, user.getEnterpriseId());
                r3 = Restrictions.gt(BmsShipBillFeeDetailModel::getCheckStatus, 0);
                criteriaFeeDetail.setRestriction(Restrictions.and(r1, r2, r3));
                List<BmsShipBillFeeDetailModel> feeDetailModels = shipBillFeeDetailMapper.findByCriteria(criteriaFeeDetail);
                if (ObjectUtil.isNotEmpty(feeDetailModels) && feeDetailModels.size() > 0) {
                    shipBillDTO.setIsSettlement(0);
                }
            }
            dtos.add(shipBillDTO);
        }
        Page<ShipBillDTO> page = PageUtils.getPage(dtos);
        if (models instanceof com.github.pagehelper.Page) {
            com.github.pagehelper.Page<BmsShipBillHeaderModel> p0 = (com.github.pagehelper.Page<BmsShipBillHeaderModel>) models;
            page.setPageCount(p0.getPages());
            page.setPageNum(p0.getPageNum());
            page.setPageSize(p0.getPageSize());
            page.setTotalCount(p0.getTotal());
            page.setStartRow(p0.getStartRow());
            page.setEndRow(p0.getEndRow());
        }
        return page;
    }

    @Override
    public ShipBillDTO detail(Long id) {
        if (ObjectUtil.isEmpty(id)) {
            throw new PluginException("查询条件不能为空");
        }
        ShipBillDTO shipBillDTO = new ShipBillDTO();
        BmsShipBillHeaderModel headerModel = shipBillHeadMapper.findById(id, BmsShipBillHeaderModel.class);
        BeanUtils.copyProperties(headerModel, shipBillDTO);

        List<SysRefdatadModel> dicData = convertorUtil.getDictionary(new String[]{BmsConstant.SHIPBILL_STATUS, // 运单状态
                BmsConstant.SHIPPER_TYPE, // 运输状态
                BmsConstant.ABNORMAL_STATUS, // 异常状态
                BmsConstant.ORDER_TYPE, // 订单类型
                BmsConstant.CONSIGNEE_TYPE, // 收货方类型
                BmsConstant.ORDER_BUSINESS_TYPE, // 订单业务类型
                BmsConstant.SOURCE, // 来源
                BmsConstant.SETTLEMENT_STATUS, // 核算状态
                BmsConstant.COST_STATUS, // 计费状态
                BmsConstant.TEMPERATURE_REQUIREMENT// 温度要求
        });

        shipBillDTO.setOrderTypeName(ConvertorUtil.getName(dicData, BmsConstant.ORDER_TYPE, String.valueOf(headerModel.getOrderType())));
        shipBillDTO.setOrderBusinessTypeName(ConvertorUtil.getName(dicData, BmsConstant.ORDER_BUSINESS_TYPE, String.valueOf(headerModel.getOrderBusinessType())));
        shipBillDTO.setTemperatureRequirementName(ConvertorUtil.getName(dicData, BmsConstant.TEMPERATURE_REQUIREMENT, String.valueOf(headerModel.getTemperatureRequirement())));
        shipBillDTO.setShipperTypeName(ConvertorUtil.getName(dicData, BmsConstant.SHIPPER_TYPE, String.valueOf(headerModel.getShipperType())));
        shipBillDTO.setConsigneeTypeName(ConvertorUtil.getName(dicData, BmsConstant.CONSIGNEE_TYPE, String.valueOf(headerModel.getConsigneeType())));
        shipBillDTO.setDeliveryMethodTypeName(headerModel.getDeliveryMethodType() == 1 ? "配送" : "自提");
        shipBillDTO.setTransportTypeName(headerModel.getTransportType() == 1 ? "整车" : "零担");
        shipBillDTO.setStatusName(ConvertorUtil.getName(dicData, BmsConstant.SHIPBILL_STATUS, String.valueOf(headerModel.getStatus())));
        shipBillDTO.setSourceName(ConvertorUtil.getName(dicData, BmsConstant.SOURCE, String.valueOf(headerModel.getSource())));
        shipBillDTO.setCostStatusName(ConvertorUtil.getName(dicData, BmsConstant.COST_STATUS, String.valueOf(headerModel.getCostStatus())));
        shipBillDTO.setCarrierTypeName(headerModel.getCarrierType() == 1 ? "承运商" : "司机");

        Criteria criteria = Criteria.forClass(BmsShipBillDetailModel.class);
        Restriction r1 = Restrictions.eq("shipbillNo", headerModel.getShipbillNo());
        criteria.setRestriction(Restrictions.and(r1));
        List<BmsShipBillDetailModel> detailModels = shipBillDetailMapper.findByCriteria(criteria);

        List<ShipBillDetailDTO> list = Lists.newArrayList();
        for (BmsShipBillDetailModel detailModel : detailModels) {
            ShipBillDetailDTO dto = new ShipBillDetailDTO();
            BeanUtils.copyProperties(detailModel, dto);
            dto.setCargoThermosphereName(ConvertorUtil.getName(dicData, BmsConstant.TEMPERATURE_REQUIREMENT, String.valueOf(detailModel.getCargoThermosphere())));
            list.add(dto);
        }
        shipBillDTO.setList(list);
        return shipBillDTO;
    }

    @Override
    public void update(ShipBillVO vo) {
        if (ObjectUtil.isEmpty(vo.getId())) {
            throw new PluginException("运单ID不能为空");
        }
        if (ObjectUtil.isEmpty(vo.getShipperType())) {
            throw new PrologException("发货方类型不能为空");
        }
        if (ObjectUtil.isEmpty(vo.getShipperUnitCode())) {
            throw new PrologException("发货方单位不能为空");
        }
        if (ObjectUtil.isEmpty(vo.getShipperAddress())) {
            throw new PrologException("发货方详细地址不能为空");
        }
        if (ObjectUtil.isEmpty(vo.getConsigneeType())) {
            throw new PrologException("收货方类型不能为空");
        }
        if (ObjectUtil.isEmpty(vo.getConsigneeUnitCode())) {
            throw new PrologException("收货方单位编码不能为空");
        }
        if (ObjectUtil.isEmpty(vo.getConsigneeAddress())) {
            throw new PrologException("收货方详细地址不能为空");
        }
        UserEntity user = PlgFxUsrUtils.getUserEntity();
        BmsShipBillHeaderModel headerModel = shipBillHeadMapper.findById(vo.getId(), BmsShipBillHeaderModel.class);
        // 判断能都修改
        if (ObjectUtil.isEmpty(headerModel)) {
            throw new PluginException("查询运单信息为空");
        }
        Integer settlementStatus = headerModel.getSettlementStatus();
        if (settlementStatus == 1) {
            throw new PluginException("核算待提交不能修改");
        }
        if (settlementStatus == 2) {
            throw new PluginException("核算审批中不能修改");
        }
        try {
            BigDecimal totalPcs = headerModel.getTotalPcs();
            BeanUtils.copyProperties(vo, headerModel);
            headerModel.setUpdateperson(user.getNickname());
            headerModel.setUpdatetime(DateUtil.date());
            headerModel.setOrganizationId(user.getOrganizationId());
            headerModel.setOrganizationCode(String.valueOf(user.getOrganizationId()));
            headerModel.setOrganizationName(user.getOrgnaizationName());
            headerModel.setSettlementStatus(BmsConstant.SETTLEMENT_STATUS_0);
            headerModel.setShipBillStatus(BmsConstant.SHIPBILL_STATUS_END);
            headerModel.setStatus(BmsConstant.SHIPBILL_STATUS_END);
            headerModel.setShipperProvinceCityDistrict(vo.getShipperProvinceName() + "" + vo.getShipperCityName() + "" + vo.getShipperDistrictName());
            headerModel.setConsigneeProvinceCityDistrict(vo.getConsigneeProvinceName() + "" + vo.getConsigneeCityName() + "" + vo.getConsigneeDistrictName());
            headerModel.setCompletionDate(DateUtil.date());
            // 删除明细
            Criteria criteria = Criteria.forClass(BmsShipBillDetailModel.class);
            Restriction r1 = Restrictions.eq("shipbillNo", headerModel.getShipbillNo());
            criteria.setRestriction(Restrictions.and(r1));
            shipBillDetailMapper.deleteByCriteria(criteria);

            // 获取运单汇总ID
            List<BmsShipBillDetailVO> list = vo.getList();

            List<BmsShipBillDetailModel> models = Lists.newArrayList();
            AtomicInteger seqNo = new AtomicInteger(1);

            RestMessage<SySParameterDTO> parameterModel = maindataTmsResource.queryParameter();
            if (ObjectUtil.isEmpty(parameterModel) || !parameterModel.isSuccess()) {
                throw new PluginException("请先配置系统参数");
            }
            Integer weightPrecision = parameterModel.getData().getWeightPrecision();
            Integer weightInteger = parameterModel.getData().getWeightInteger();

            Integer volumePrecision = parameterModel.getData().getVolumePrecision();
            Integer volumeInteger = parameterModel.getData().getVolumeInteger();
            BigDecimal totWeight = new BigDecimal(0);
            BigDecimal totVolume = new BigDecimal(0);

            for (BmsShipBillDetailVO shipBillDetailVO : list) {
                BmsShipBillDetailModel detailModel = new BmsShipBillDetailModel();
                BeanUtils.copyProperties(shipBillDetailVO, detailModel);

                BigDecimal weight = shipBillDetailVO.getWeight();
                BigDecimal volume = shipBillDetailVO.getVolume();

                // 四舍五入
                if (weightInteger == 1) {
                    detailModel.setWeight(weight.divide(BigDecimal.valueOf(1), weightPrecision, RoundingMode.HALF_UP));
                }
                // 向上取整
                if (weightInteger == 2) {
                    detailModel.setWeight(weight.divide(BigDecimal.valueOf(1), weightPrecision, RoundingMode.UP));
                }
                // 向下取整
                if (weightInteger == 3) {
                    detailModel.setWeight(weight.divide(BigDecimal.valueOf(1), weightPrecision, RoundingMode.DOWN));
                }

                // 四舍五入
                if (volumeInteger == 1) {
                    detailModel.setVolume(volume.divide(BigDecimal.valueOf(1), volumePrecision, RoundingMode.HALF_UP));
                }
                // 向上取整
                if (volumeInteger == 2) {
                    detailModel.setVolume(volume.divide(BigDecimal.valueOf(1), volumePrecision, RoundingMode.UP));
                }
                // 向下取整
                if (volumeInteger == 3) {
                    detailModel.setVolume(volume.divide(BigDecimal.valueOf(1), volumePrecision, RoundingMode.DOWN));
                }

                detailModel.setShipbillNo(headerModel.getShipbillNo());
                detailModel.setCreateperson(user.getNickname());
                detailModel.setCreatetime(DateUtil.date());
                detailModel.setUpdateperson(user.getNickname());
                detailModel.setUpdatetime(DateUtil.date());
                detailModel.setEnterpriseId(user.getEnterpriseId());
                detailModel.setEnterpriseName(user.getEnterpriseName());
                detailModel.setSeqno(seqNo.get());

                totWeight = totWeight.add(detailModel.getWeight());
                totVolume = totVolume.add(detailModel.getVolume());

                seqNo.getAndIncrement();
                models.add(detailModel);
            }
            if (ObjectUtil.isNotEmpty(models)) {
                shipBillDetailMapper.saveBatch(models);
            }

            // 核算
            BmsShipBillDTO dto = new BmsShipBillDTO();
            dto.setDetailModelList(models);
            dto.setModel(headerModel);
            List<ShipBillPriceDTO> costStrategy = shipCostStrategyService.costStrategy(dto, "1");
            if (ObjectUtil.isEmpty(costStrategy)) {
                throw new PluginException("没有匹配到价格数据,或者价格数据重复");
            }
            ShipBillPriceDTO priceDTO = costStrategy.get(0);
            BigDecimal totPrice = costStrategy.stream().map(ShipBillPriceDTO::getPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
            headerModel.setCostContract(priceDTO.getCostContract());
            headerModel.setContractPayAmount(totPrice);
            headerModel.setTransportationPrice(priceDTO.getPrice());
            headerModel.setSettlementCompanyId(priceDTO.getFirstPartyId());
            headerModel.setSettlementCompanyCode(priceDTO.getFirstPartyCode());
            headerModel.setSettlementCompany(priceDTO.getFirstPartyName());
            headerModel.setSettlementDepartment(vo.getSettlementDepartment());
            headerModel.setSettlementDepartmentId(vo.getSettlementDepartmentId());
            headerModel.setSettlementDepartmentCode(vo.getSettlementDepartmentCode());
            headerModel.setTotalVolume(totVolume);
            headerModel.setTotalWeight(totWeight);
            headerModel.setCostStatus(1);
            headerModel.setCostFailReason(null);
            BmsLogOperationModel feeVo = new BmsLogOperationModel();
            feeVo.setCreatetime(DateUtil.date());
            feeVo.setCreateperson(user.getNickname());
            feeVo.setEnterpriseId(user.getEnterpriseId());
            feeVo.setEnterpriseName(user.getEnterpriseName());
            feeVo.setOrderNo(headerModel.getShipbillNo());
            feeVo.setLogMemo("匹配价格表" + priceDTO.getCostPriceTable());
            feeVo.setLogType(1);
            logOperationMapper.save(feeVo);
            // 核算
            if (vo.getIsAccount().intValue() == 1) {
                // 核算待提交
                headerModel.setSettlementStatus(BmsConstant.SETTLEMENT_STATUS_1);
            } else {
                // 未核算
                headerModel.setSettlementStatus(BmsConstant.SETTLEMENT_STATUS_0);
            }
            // 调整单
            BmsShipBillAdjustModel adjustModel = new BmsShipBillAdjustModel();
            adjustModel.setShipbillNo(headerModel.getShipbillNo());
            adjustModel.setAdjustMemo("将数量从" + totalPcs + "件调整到" + headerModel.getTotalPcs());
            adjustModel.setAdjustDate(DateUtil.date());
            adjustModel.setAdjustName(user.getNickname());
            adjustModel.setCreateperson(user.getNickname());
            adjustModel.setCreatetime(DateUtil.date());
            adjustModel.setUpdateperson(user.getNickname());
            adjustModel.setUpdatetime(DateUtil.date());
            adjustModel.setEnterpriseId(user.getEnterpriseId());
            adjustModel.setEnterpriseName(user.getEnterpriseName());
            if (!Objects.equals(totalPcs, headerModel.getTotalPcs())) {
                shipBillAdjustMapper.save(adjustModel);
            }

            // 日志操作
            BmsLogOperationModel logVO = new BmsLogOperationModel();
            logVO.setCreatetime(DateUtil.date());
            logVO.setCreateperson(user.getNickname());
            logVO.setEnterpriseId(user.getEnterpriseId());
            logVO.setEnterpriseName(user.getEnterpriseName());
            logVO.setOrderNo(headerModel.getShipbillNo());
            logVO.setLogMemo("运单修改");
            logVO.setLogType(1);
            logOperationMapper.save(logVO);

            // 支出总价 类型为支出的含税金额
            BigDecimal payAmount = getShipbillTaxAmt(headerModel.getShipbillNo(), null);
            headerModel.setPayAmount(payAmount);
            // 类型为支出的来源是价格表生成 含税金额
            BigDecimal contractPayAmount = getShipbillTaxAmt(headerModel.getShipbillNo(), 1);
            headerModel.setContractPayAmount(contractPayAmount);
        } catch (Exception exception) {
            headerModel.setCostFailReason(exception.getMessage());
            headerModel.setCostStatus(2);
        }
        headerModel.setEnterpriseId(user.getEnterpriseId());
        headerModel.setEnterpriseName(user.getEnterpriseName());
        shipBillHeadMapper.update(headerModel);
    }

    @Override
    public void copy(ShipBillVO vo) {
        logger.info("运单管理新增：" + JSONObject.toJSONString(vo));
        UserEntity user = PlgFxUsrUtils.getUserEntity();
        // 获取运单汇总ID
        RestMessage<String> restMessage = maindataTmsResource.getCodeNumberByCode(BmsConstant.SHIP_BILL_HEAD_ID, "L");
        if (!restMessage.isSuccess()) {
            throw new RuntimeException("生成运单汇总ID失败");
        }
        BmsShipBillHeaderModel model = new BmsShipBillHeaderModel();
        try {
            if (ObjectUtil.isEmpty(vo.getShipperType())) {
                throw new PrologException("发货方类型不能为空");
            }
            if (ObjectUtil.isEmpty(vo.getShipperUnitCode())) {
                throw new PrologException("发货方单位不能为空");
            }
            if (ObjectUtil.isEmpty(vo.getShipperAddress())) {
                throw new PrologException("发货方详细地址不能为空");
            }
            if (ObjectUtil.isEmpty(vo.getConsigneeType())) {
                throw new PrologException("收货方类型不能为空");
            }
            if (ObjectUtil.isEmpty(vo.getConsigneeUnitCode())) {
                throw new PrologException("收货方单位编码不能为空");
            }
            if (ObjectUtil.isEmpty(vo.getConsigneeAddress())) {
                throw new PrologException("收货方详细地址不能为空");
            }
            BeanUtils.copyProperties(vo, model);
            model.setId(null);
            model.setShipbillNo(restMessage.getData());
            model.setOrganizationId(user.getOrganizationId());
            model.setOrganizationCode(String.valueOf(user.getOrganizationId()));
            model.setOrganizationName(user.getOrgnaizationName());
            model.setCreateperson(user.getNickname());
            model.setCreatetime(DateUtil.date());
            model.setUpdateperson(user.getNickname());
            model.setUpdatetime(DateUtil.date());
            model.setEnterpriseId(user.getEnterpriseId());
            model.setEnterpriseName(user.getEnterpriseName());

            model.setStatus(BmsConstant.SHIPBILL_STATUS_END);
            model.setShipBillStatus(BmsConstant.SHIPBILL_STATUS_END);
            model.setShipperProvinceCityDistrict(vo.getShipperProvinceName() + "" + vo.getShipperCityName() + "" + vo.getShipperDistrictName());
            model.setConsigneeProvinceCityDistrict(vo.getConsigneeProvinceName() + "" + vo.getConsigneeCityName() + "" + vo.getConsigneeDistrictName());
            model.setCompletionDate(DateUtil.date());
            if (vo.getIsAccount().intValue() == 1) {
                model.setSettlementStatus(BmsConstant.SETTLEMENT_STATUS_1);
            } else {
                model.setSettlementStatus(BmsConstant.SETTLEMENT_STATUS_0);
            }
            List<BmsShipBillDetailVO> list = vo.getList();
            List<BmsShipBillDetailModel> models = Lists.newArrayList();
            AtomicInteger seqNo = new AtomicInteger(1);

            RestMessage<SySParameterDTO> parameterModel = maindataTmsResource.queryParameter();
            if (ObjectUtil.isEmpty(parameterModel) || !parameterModel.isSuccess()) {
                throw new PluginException("请先配置系统参数");
            }
            Integer weightPrecision = parameterModel.getData().getWeightPrecision();
            Integer weightInteger = parameterModel.getData().getWeightInteger();

            Integer volumePrecision = parameterModel.getData().getVolumePrecision();
            Integer volumeInteger = parameterModel.getData().getVolumeInteger();
            BigDecimal totWeight = new BigDecimal(0);
            BigDecimal totVolume = new BigDecimal(0);
            for (BmsShipBillDetailVO shipBillDetailVO : list) {
                BmsShipBillDetailModel detailModel = new BmsShipBillDetailModel();
                BeanUtils.copyProperties(shipBillDetailVO, detailModel);
                BigDecimal weight = shipBillDetailVO.getWeight();
                BigDecimal volume = shipBillDetailVO.getVolume();

                // 四舍五入
                if (weightInteger == 1) {
                    detailModel.setWeight(weight.divide(BigDecimal.valueOf(1), weightPrecision, RoundingMode.HALF_UP));
                }
                // 向上取整
                if (weightInteger == 2) {
                    detailModel.setWeight(weight.divide(BigDecimal.valueOf(1), weightPrecision, RoundingMode.UP));
                }
                // 向下取整
                if (weightInteger == 3) {
                    detailModel.setWeight(weight.divide(BigDecimal.valueOf(1), weightPrecision, RoundingMode.DOWN));
                }

                // 四舍五入
                if (volumeInteger == 1) {
                    detailModel.setVolume(volume.divide(BigDecimal.valueOf(1), volumePrecision, RoundingMode.HALF_UP));
                }
                // 向上取整
                if (volumeInteger == 2) {
                    detailModel.setVolume(volume.divide(BigDecimal.valueOf(1), volumePrecision, RoundingMode.UP));
                }
                // 向下取整
                if (volumeInteger == 3) {
                    detailModel.setVolume(volume.divide(BigDecimal.valueOf(1), volumePrecision, RoundingMode.DOWN));
                }
                detailModel.setShipbillNo(model.getShipbillNo());
                detailModel.setCreateperson(user.getNickname());
                detailModel.setCreatetime(DateUtil.date());
                detailModel.setUpdateperson(user.getNickname());
                detailModel.setUpdatetime(DateUtil.date());
                detailModel.setEnterpriseId(user.getEnterpriseId());
                detailModel.setEnterpriseName(user.getEnterpriseName());
                detailModel.setSeqno(seqNo.get());

                totWeight = totWeight.add(detailModel.getWeight());
                totVolume = totVolume.add(detailModel.getVolume());
                seqNo.getAndIncrement();
                models.add(detailModel);
            }
            if (ObjectUtil.isNotEmpty(models)) {
                shipBillDetailMapper.saveBatch(models);
            }

            List<BmsShipBillPackVO> packList = vo.getPackList();
            List<BmsShipBillPackageModel> packageModelList = Lists.newArrayList();
            AtomicInteger packSeqNo = new AtomicInteger(1);
            BigDecimal packageTotalVolume = BigDecimal.valueOf(0);
            BigDecimal packageTotalWeight = BigDecimal.valueOf(0);
            if (ObjectUtil.isNotEmpty(packList)) {
                for (BmsShipBillPackVO shipBillDetailVO : packList) {
                    BmsShipBillPackageModel detailModel = new BmsShipBillPackageModel();
                    BeanUtils.copyProperties(shipBillDetailVO, detailModel);
                    detailModel.setShipbillNo(model.getShipbillNo());
                    detailModel.setCreateperson(user.getNickname());
                    detailModel.setCreatetime(DateUtil.date());
                    BigDecimal packageVolume = detailModel.getPackageTotalVolume();
                    packageTotalVolume = packageTotalVolume.add(packageVolume);
                    BigDecimal packageWeight = detailModel.getPackageTotalWeight();
                    packageTotalWeight = packageTotalVolume.add(packageWeight);
                    detailModel.setUpdateperson(user.getNickname());
                    detailModel.setUpdatetime(DateUtil.date());
                    detailModel.setEnterpriseId(user.getEnterpriseId());
                    detailModel.setEnterpriseName(user.getEnterpriseName());
                    detailModel.setSeqNo(packSeqNo.get());
                    packSeqNo.getAndIncrement();
                    packageModelList.add(detailModel);
                }
            }
            if (ObjectUtil.isNotEmpty(packageModelList)) {
                shipBillPackageMapper.saveBatch(packageModelList);
            }
            // 调整单
            BmsShipBillAdjustModel adjustModel = new BmsShipBillAdjustModel();
            adjustModel.setShipbillNo(model.getShipbillNo());
            adjustModel.setAdjustMemo("新增件数" + model.getTotalPcs());
            adjustModel.setAdjustDate(DateUtil.date());
            adjustModel.setAdjustName(user.getNickname());
            adjustModel.setCreateperson(user.getNickname());
            adjustModel.setCreatetime(DateUtil.date());
            adjustModel.setUpdateperson(user.getNickname());
            adjustModel.setUpdatetime(DateUtil.date());
            adjustModel.setEnterpriseId(user.getEnterpriseId());
            adjustModel.setEnterpriseName(user.getEnterpriseName());
            shipBillAdjustMapper.save(adjustModel);

            // 日志操作
            BmsLogOperationModel logVO = new BmsLogOperationModel();
            logVO.setCreatetime(DateUtil.date());
            logVO.setCreateperson(user.getNickname());
            logVO.setEnterpriseId(user.getEnterpriseId());
            logVO.setEnterpriseName(user.getEnterpriseName());
            logVO.setOrderNo(model.getShipbillNo());
            logVO.setLogMemo("运单新增");
            logVO.setLogType(1);
            logOperationMapper.save(logVO);

            model.setPackageTotalVolume(packageTotalVolume);
            model.setPackageTotalWeight(packageTotalWeight);
            model.setAbnormalStatus(0);
            model.setTotalWeight(totWeight);
            model.setTotalVolume(totVolume);
            // 核算
            if (vo.getIsAccount().intValue() == 1) {
                // 核算待提交
                model.setSettlementStatus(BmsConstant.SETTLEMENT_STATUS_1);
            } else {
                // 未核算
                model.setSettlementStatus(BmsConstant.SETTLEMENT_STATUS_0);
            }
            BmsShipBillDTO dto = new BmsShipBillDTO();
            dto.setDetailModelList(models);
            dto.setModel(model);
            List<ShipBillPriceDTO> costStrategy = shipCostStrategyService.costStrategy(dto, "1");
            if (ObjectUtil.isEmpty(costStrategy)) {
                throw new PluginException("没有匹配到价格数据,或者价格数据重复");
            }
            for (ShipBillPriceDTO priceDTO : costStrategy) {
                model.setCostContract(priceDTO.getCostContract());
                model.setCostDate(DateUtil.date());
                // 支出总价 类型为支出的含税金额
                // model.setPayAmount(priceDTO.getPayAmount());
                // 类型为支出的来源是价格表生成 含税金额
                // model.setContractPayAmount(priceDTO.getContractPayAmount());
                model.setTransportationPrice(priceDTO.getPrice());
                model.setSettlementCompanyId(priceDTO.getFirstPartyId());
                model.setSettlementCompanyCode(priceDTO.getFirstPartyCode());
                model.setSettlementCompany(priceDTO.getFirstPartyName());

                /*
                 * model.setSettlementDepartment(vo.getDepartmentName());
                 * model.setSettlementDepartmentId(vo.getDepartmentId());
                 * model.setSettlementDepartmentCode(vo.getDepartmentCode());
                 */
                // model.setSettlementStatus(BmsConstant.SETTLEMENT_STATUS_1);
                model.setAbnormalStatus(0);
                model.setCostStatus(1);
                BmsLogOperationModel feeVo = new BmsLogOperationModel();
                feeVo.setCreatetime(DateUtil.date());
                feeVo.setCreateperson(user.getNickname());
                feeVo.setEnterpriseId(user.getEnterpriseId());
                feeVo.setEnterpriseName(user.getEnterpriseName());
                feeVo.setOrderNo(model.getShipbillNo());
                feeVo.setLogMemo("匹配价格表" + priceDTO.getCostPriceTable());
                feeVo.setLogType(1);
                logOperationMapper.save(feeVo);
            }
            // 支出总价 类型为支出的含税金额
            BigDecimal payAmount = getShipbillTaxAmt(model.getShipbillNo(), null);
            model.setPayAmount(payAmount);
            // 类型为支出的来源是价格表生成 含税金额
            BigDecimal contractPayAmount = getShipbillTaxAmt(model.getShipbillNo(), 1);
            model.setContractPayAmount(contractPayAmount);

        } catch (Exception exception) {
            model.setCostFailReason(exception.getMessage());
            model.setAbnormalStatus(1);
            model.setCostStatus(2);
            model.setSettlementStatus(BmsConstant.SETTLEMENT_STATUS_0);
        }
        model.setSource(1);
        model.setSettlementDepartment(vo.getSettlementDepartment());
        model.setSettlementDepartmentId(vo.getSettlementDepartmentId());
        model.setSettlementDepartmentCode(vo.getSettlementDepartmentCode());
        shipBillHeadMapper.save(model);
    }

    @Override
    public void submit(List<String> ids) {
        ToolKits.isParamNull(ids, "派车单ID不为空");

        UserEntity user = PlgFxUsrUtils.getUserEntity();
        ToolKits.isParamNull(user, "当前人员没有操作权限");
        if (!user.getUserType().equals(BmsConstant.USER_TYPE_ZY) && !user.getUserType().equals(BmsConstant.USER_TYPE_CYS)) {
            ToolKits.isParamNull(user, "当前人员没有操作权限");
        }
        // 判断有没有审核流
        for (String id : ids) {
            // 查询运单信息
            BmsShipBillHeaderModel headerModel = shipBillHeadMapper.findById(id, BmsShipBillHeaderModel.class);
            headerModel.setSettlementStatus(BmsConstant.SETTLEMENT_STATUS_3);
            headerModel.setStatus(BmsConstant.SHIPBILL_STATUS_END);
            headerModel.setUpdateperson(user.getNickname());
            headerModel.setUpdatetime(DateUtil.date());
            shipBillHeadMapper.update(headerModel);
        }
    }

    @Override
    public void adjustAccounts(List<String> ids) {
        ToolKits.isParamNull(ids, "核算ID不为空");
        UserEntity user = PlgFxUsrUtils.getUserEntity();
        for (String id : ids) {
            BmsShipBillHeaderModel headerModel = shipBillHeadMapper.findById(id, BmsShipBillHeaderModel.class);
            List<ShipBillPriceDTO> costStrategy = Lists.newArrayList();
            String costFailReason = "";
            try {
                // 核算
                Criteria criteria = Criteria.forClass(BmsShipBillDetailModel.class);
                Restriction r1 = Restrictions.eq("shipbillNo", headerModel.getShipbillNo());
                Restriction r2 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
                criteria.setRestriction(Restrictions.and(r1, r2));
                List<BmsShipBillDetailModel> models = shipBillDetailMapper.findByCriteria(criteria);
                BmsShipBillDTO dto = new BmsShipBillDTO();
                dto.setDetailModelList(models);
                dto.setModel(headerModel);
                costStrategy = shipCostStrategyService.costStrategy(dto, "1");
                if (ObjectUtil.isEmpty(costStrategy)) {
                    throw new PluginException("没有匹配到价格数据,或者价格数据重复");
                }
            } catch (Exception exception) {
                costFailReason = exception.getMessage();
            }
            if (ObjectUtil.isEmpty(costStrategy) || costStrategy.size() < 1) {
                headerModel.setCostFailReason(costFailReason);
                shipBillHeadMapper.update(headerModel);
            } else {
                headerModel.setCostFailReason(null);
                Map<String, List<ShipBillPriceDTO>> costStrategyMap = costStrategy.stream().collect(Collectors.groupingBy(ShipBillPriceDTO::getShipbillNo));
                for (Map.Entry<String, List<ShipBillPriceDTO>> stringListEntry : costStrategyMap.entrySet()) {
                    List<ShipBillPriceDTO> shipBillPriceDTOS = stringListEntry.getValue();
                    ShipBillPriceDTO priceDTO = shipBillPriceDTOS.get(0);
                    Criteria forClass = Criteria.forClass(BmsShipBillHeaderModel.class);
                    Restriction r3 = Restrictions.eq("shipbillNo", shipBillPriceDTOS.get(0).getShipbillNo());
                    forClass.setRestriction(Restrictions.and(r3));
                    List<BmsShipBillHeaderModel> mapper = shipBillHeadMapper.findByCriteria(forClass);
                    BmsShipBillHeaderModel model = mapper.get(0);
                    model.setCostContract(priceDTO.getCostContract());
                    BigDecimal surcharge = priceDTO.getSurcharge() == null ? BigDecimal.valueOf(0) : priceDTO.getSurcharge();
                    model.setContractPayAmount(priceDTO.getPrice().add(surcharge));
                    model.setTransportationPrice(priceDTO.getPrice());
                    model.setSettlementStatus(BmsConstant.SETTLEMENT_STATUS_1);
                    model.setSettlementCompanyId(priceDTO.getFirstPartyId());
                    model.setSettlementCompanyCode(priceDTO.getFirstPartyCode());
                    model.setSettlementCompany(priceDTO.getFirstPartyName());
                    model.setSettlementDate(DateUtil.date());
                    model.setCostStatus(1);

                    // 记录
                    BmsLogOperationModel feeVo = new BmsLogOperationModel();
                    feeVo.setCreatetime(DateUtil.date());
                    feeVo.setCreateperson(user.getNickname());
                    feeVo.setEnterpriseId(user.getEnterpriseId());
                    feeVo.setEnterpriseName(user.getEnterpriseName());
                    feeVo.setOrderNo(model.getShipbillNo());
                    feeVo.setLogMemo("费用单生成");
                    feeVo.setLogType(1);
                    logOperationMapper.save(feeVo);

                    model.setCostFailReason("");

                    // 支出总价 类型为支出的含税金额
                    BigDecimal payAmount = getShipbillTaxAmt(model.getShipbillNo(), null);
                    model.setPayAmount(payAmount);
                    // 类型为支出的来源是价格表生成 含税金额
                    BigDecimal contractPayAmount = getShipbillTaxAmt(model.getShipbillNo(), 1);
                    model.setContractPayAmount(contractPayAmount);
                    shipBillHeadMapper.update(model);
                }
            }
        }
    }

    @Override
    public void shipBillFeeSave(ShipBillFeeSaveDTO dto) {
        List<ShipBillFeeSave> list = dto.getList();
        UserEntity user = PlgFxUsrUtils.getUserEntity();
        List<BmsShipBillFeeDetailModel> models = Lists.newArrayList();
        BigDecimal size = BigDecimal.valueOf(list.size());

        RestMessage<SySParameterDTO> parameterModel = maindataTmsResource.queryParameter();
        if (ObjectUtil.isEmpty(parameterModel) || !parameterModel.isSuccess()) {
            throw new PluginException("获取系统参数异常");
        }
        Integer costPrecision = parameterModel.getData().getCostPrecision();
        Integer costInteger = parameterModel.getData().getCostInteger();
        AtomicInteger num = new AtomicInteger(0);
        for (ShipBillFeeSave shipBillFeeSave : list) {
            List<ShipBillFeeDetail> detailList = shipBillFeeSave.getDetailList();
            String shipbillNo = shipBillFeeSave.getShipbillNo();

            for (ShipBillFeeDetail shipBillFeeDetail : detailList) {
                BmsShipBillFeeDetailModel model = new BmsShipBillFeeDetailModel();
                BeanUtils.copyProperties(shipBillFeeDetail, model);
                RestMessage<String> expenseNo = maindataTmsResource.getCodeNumberByCode(BmsConstant.SHIP_BILL_EXPENSE_NO, "L");
                if (!expenseNo.isSuccess() || ObjectUtil.isEmpty(expenseNo)) {
                    throw new PluginException("获取费用单号为空");
                }
                model.setExpenseNo(expenseNo.getData());
                model.setShipbillNo(shipbillNo);
                // 金额
                BigDecimal amount = shipBillFeeDetail.getAmount();
                // 税率
                String taxPoint = shipBillFeeDetail.getTaxPoint();
                // 1.分到每一单，0：每一单
                Integer isShare = shipBillFeeDetail.getIsShare();
                // 不含税金额
                if (shipBillFeeDetail.getIsPreTax() == 0) {
                    if (isShare == 1) {
                        // 最后一个
                        if (size.subtract(BigDecimal.valueOf(1)).compareTo(BigDecimal.valueOf(num.get())) == 0) {
                            if (costInteger == 1) {
                                BigDecimal taxAmt = amount.multiply(BigDecimal.valueOf(1).add(BigDecimal.valueOf(Integer.parseInt(taxPoint)).divide(BigDecimal.valueOf(100))));
                                BigDecimal divide = amount.divide(size, costPrecision, RoundingMode.HALF_UP);
                                BigDecimal decimal = taxAmt.divide(size, costPrecision, RoundingMode.HALF_UP);
                                model.setNoTaxAmt(amount.subtract(divide.multiply(size.subtract(BigDecimal.valueOf(1)))));
                                model.setTaxAmt(taxAmt.subtract(decimal.multiply(size.subtract(BigDecimal.valueOf(1)))));
                            }
                            if (costInteger == 2) {
                                BigDecimal taxAmt = amount.multiply(BigDecimal.valueOf(1).add(BigDecimal.valueOf(Integer.parseInt(taxPoint)).divide(BigDecimal.valueOf(100))));
                                BigDecimal divide = amount.divide(size, costPrecision, RoundingMode.UP);
                                BigDecimal decimal = taxAmt.divide(size, costPrecision, RoundingMode.UP);
                                model.setNoTaxAmt(amount.subtract(divide.multiply(size.subtract(BigDecimal.valueOf(1)))));
                                model.setTaxAmt(taxAmt.subtract(decimal.multiply(size.subtract(BigDecimal.valueOf(1)))));
                            }
                            if (costInteger == 3) {
                                BigDecimal taxAmt = amount.multiply(BigDecimal.valueOf(1).add(BigDecimal.valueOf(Integer.parseInt(taxPoint)).divide(BigDecimal.valueOf(100))));
                                BigDecimal divide = amount.divide(size, costPrecision, RoundingMode.DOWN);
                                BigDecimal decimal = taxAmt.divide(size, costPrecision, RoundingMode.DOWN);
                                model.setNoTaxAmt(amount.subtract(divide.multiply(size.subtract(BigDecimal.valueOf(1)))));
                                model.setTaxAmt(taxAmt.subtract(decimal.multiply(size.subtract(BigDecimal.valueOf(1)))));
                            }

                        } else {
                            // 四舍五入
                            if (costInteger == 1) {
                                BigDecimal taxAmt = amount.multiply(BigDecimal.valueOf(1).add(BigDecimal.valueOf(Integer.parseInt(taxPoint)).divide(BigDecimal.valueOf(100))));
                                BigDecimal divide = amount.divide(size, costPrecision, RoundingMode.HALF_UP);
                                BigDecimal decimal = taxAmt.divide(size, costPrecision, RoundingMode.HALF_UP);
                                model.setNoTaxAmt(divide);
                                model.setTaxAmt(decimal);
                            }
                            // 向上取整
                            if (costInteger == 2) {
                                BigDecimal taxAmt = amount.multiply(BigDecimal.valueOf(1).add(BigDecimal.valueOf(Integer.parseInt(taxPoint)).divide(BigDecimal.valueOf(100))));
                                model.setNoTaxAmt(amount.divide(size, costPrecision, RoundingMode.UP));
                                model.setTaxAmt(taxAmt.divide(size, costPrecision, RoundingMode.UP));
                            }
                            // 向上取整
                            if (costInteger == 3) {
                                BigDecimal taxAmt = amount.multiply(BigDecimal.valueOf(1).add(BigDecimal.valueOf(Integer.parseInt(taxPoint)).divide(BigDecimal.valueOf(100))));
                                model.setNoTaxAmt(amount.divide(size, costPrecision, RoundingMode.DOWN));
                                model.setTaxAmt(taxAmt.divide(size, costPrecision, RoundingMode.DOWN));
                            }
                        }
                    } else {
                        if (costInteger == 1) {
                            BigDecimal taxAmt = amount.multiply(BigDecimal.valueOf(1).add(BigDecimal.valueOf(Integer.parseInt(taxPoint)).divide(BigDecimal.valueOf(100))));
                            model.setNoTaxAmt(amount);
                            model.setTaxAmt(taxAmt);
                        }
                        if (costInteger == 2) {
                            BigDecimal taxAmt = amount.multiply(BigDecimal.valueOf(1).add(BigDecimal.valueOf(Integer.parseInt(taxPoint)).divide(BigDecimal.valueOf(100))));
                            model.setNoTaxAmt(amount);
                            model.setTaxAmt(taxAmt);
                        }
                        if (costInteger == 3) {
                            BigDecimal taxAmt = amount.multiply(BigDecimal.valueOf(1).add(BigDecimal.valueOf(Integer.parseInt(taxPoint)).divide(BigDecimal.valueOf(100))));
                            model.setNoTaxAmt(amount);
                            model.setTaxAmt(taxAmt);
                        }
                    }
                } else {
                    if (isShare == 1) {
                        if (size.subtract(BigDecimal.valueOf(1)).compareTo(BigDecimal.valueOf(num.get())) == 0) {
                            if (costInteger == 1) {
                                BigDecimal notTaxAmt = amount.divide(BigDecimal.valueOf(1).add(BigDecimal.valueOf(Integer.parseInt(taxPoint)).divide(BigDecimal.valueOf(100))), costPrecision, RoundingMode.HALF_UP);
                                BigDecimal divide = notTaxAmt.divide(size, costPrecision, RoundingMode.HALF_UP);
                                BigDecimal decimal = amount.divide(size, costPrecision, RoundingMode.HALF_UP);
                                model.setNoTaxAmt(notTaxAmt.subtract(divide.multiply(size.subtract(BigDecimal.valueOf(1)))));
                                model.setTaxAmt(amount.subtract(decimal.multiply(size.subtract(BigDecimal.valueOf(1)))));
                            }
                            if (costInteger == 2) {
                                BigDecimal notTaxAmt = amount.divide(BigDecimal.valueOf(1).add(BigDecimal.valueOf(Integer.parseInt(taxPoint)).divide(BigDecimal.valueOf(100))), costPrecision, RoundingMode.UP);
                                BigDecimal divide = notTaxAmt.divide(size, costPrecision, RoundingMode.UP);
                                BigDecimal decimal = amount.divide(size, costPrecision, RoundingMode.UP);
                                model.setNoTaxAmt(notTaxAmt.subtract(divide.multiply(size.subtract(BigDecimal.valueOf(1)))));
                                model.setTaxAmt(amount.subtract(decimal.multiply(size.subtract(BigDecimal.valueOf(1)))));
                            }
                            if (costInteger == 3) {
                                BigDecimal notTaxAmt = amount.divide(BigDecimal.valueOf(1).add(BigDecimal.valueOf(Integer.parseInt(taxPoint)).divide(BigDecimal.valueOf(100))), costPrecision, RoundingMode.DOWN);
                                BigDecimal divide = notTaxAmt.divide(size, costPrecision, RoundingMode.DOWN);
                                BigDecimal decimal = amount.divide(size, costPrecision, RoundingMode.DOWN);
                                model.setNoTaxAmt(notTaxAmt.subtract(divide.multiply(size.subtract(BigDecimal.valueOf(1)))));
                                model.setTaxAmt(amount.subtract(decimal.multiply(size.subtract(BigDecimal.valueOf(1)))));
                            }

                        } else {
                            // 四舍五入
                            if (costInteger == 1) {
                                BigDecimal notTaxAmt = amount.divide(BigDecimal.valueOf(1).add(BigDecimal.valueOf(Integer.parseInt(taxPoint)).divide(BigDecimal.valueOf(100))), costPrecision, RoundingMode.HALF_UP);
                                model.setNoTaxAmt(notTaxAmt.divide(size, costPrecision, RoundingMode.HALF_UP));
                                model.setTaxAmt(amount.divide(size, costPrecision, RoundingMode.HALF_UP));
                            }
                            // 向上取整
                            if (costInteger == 2) {
                                BigDecimal notTaxAmt = amount.divide(BigDecimal.valueOf(1).add(BigDecimal.valueOf(Integer.parseInt(taxPoint)).divide(BigDecimal.valueOf(100))), costPrecision, RoundingMode.UP);
                                model.setNoTaxAmt(notTaxAmt.divide(size, costPrecision, RoundingMode.UP));
                                model.setTaxAmt(amount.divide(size, costPrecision, RoundingMode.UP));
                            }
                            // 向上取整
                            if (costInteger == 3) {
                                BigDecimal notTaxAmt = amount.divide(BigDecimal.valueOf(1).add(BigDecimal.valueOf(Integer.parseInt(taxPoint)).divide(BigDecimal.valueOf(100))), costPrecision, RoundingMode.DOWN);
                                model.setNoTaxAmt(notTaxAmt.divide(size, costPrecision, RoundingMode.DOWN));
                                model.setTaxAmt(amount.divide(size, costPrecision, RoundingMode.DOWN));
                            }
                        }

                    } else {
                        if (costInteger == 1) {
                            BigDecimal notTaxAmt = amount.divide(BigDecimal.valueOf(1).add(BigDecimal.valueOf(Integer.parseInt(taxPoint)).divide(BigDecimal.valueOf(100))), costPrecision, RoundingMode.HALF_UP);
                            model.setNoTaxAmt(notTaxAmt);
                        }
                        if (costInteger == 2) {
                            BigDecimal notTaxAmt = amount.divide(BigDecimal.valueOf(1).add(BigDecimal.valueOf(Integer.parseInt(taxPoint)).divide(BigDecimal.valueOf(100))), costPrecision, RoundingMode.UP);
                            model.setNoTaxAmt(notTaxAmt);
                        }
                        if (costInteger == 3) {
                            BigDecimal notTaxAmt = amount.divide(BigDecimal.valueOf(1).add(BigDecimal.valueOf(Integer.parseInt(taxPoint)).divide(BigDecimal.valueOf(100), costPrecision, RoundingMode.DOWN)), costPrecision, RoundingMode.DOWN);
                            model.setNoTaxAmt(notTaxAmt);
                        }
                        model.setTaxAmt(amount);
                    }
                }
                model.setExpenseType(shipBillFeeDetail.getExpenseType());
                model.setTax(model.getTaxAmt().subtract(model.getNoTaxAmt()));
                model.setTaxPoint(taxPoint);
                model.setExpenseStatus(0);
                model.setCreateperson(user.getNickname());
                model.setCreatetime(DateUtil.date());
                model.setUpdateperson(user.getNickname());
                model.setUpdatetime(DateUtil.date());
                model.setEnterpriseId(user.getEnterpriseId());
                model.setEnterpriseName(user.getEnterpriseName());
                model.setBillingSource(2);
                model.setCheckStatus(0);
                models.add(model);
                num.getAndIncrement();
            }
        }
        shipBillFeeDetailMapper.saveBatch(models);

    }

    @Override
    public ShipBillFeeDTO shipBillFeeDetail(Long id) {
        if (ObjectUtil.isEmpty(id)) {
            throw new PluginException("查询条件不能为空");
        }
        // 查询费用信息
        BmsShipBillFeeDetailModel detailModels = shipBillFeeDetailMapper.findById(id, BmsShipBillFeeDetailModel.class);
        if (ObjectUtil.isEmpty(detailModels)) {
            throw new PluginException("费用详情信息为空");
        }
        // 查询运单信息
        Criteria criteria = Criteria.forClass(BmsShipBillHeaderModel.class);
        Restriction r1 = Restrictions.eq("shipbillNo", detailModels.getShipbillNo());
        criteria.setRestriction(Restrictions.and(r1));
        List<BmsShipBillHeaderModel> headerModels = shipBillHeadMapper.findByCriteria(criteria);
        if (ObjectUtil.isEmpty(headerModels)) {
            throw new PluginException("查询运单信息为空");
        }
        BmsShipBillHeaderModel headerModel = headerModels.get(0);
        ShipBillFeeDTO shipBillDTO = new ShipBillFeeDTO();
        BeanUtils.copyProperties(headerModel, shipBillDTO);

        List<SysRefdatadModel> dicData = convertorUtil.getDictionary(new String[]{BmsConstant.SHIPBILL_STATUS, // 运单状态
                BmsConstant.SHIPPER_TYPE, // 运输状态
                BmsConstant.ABNORMAL_STATUS, // 异常状态
                BmsConstant.ORDER_TYPE, // 订单类型
                BmsConstant.CONSIGNEE_TYPE, // 收货方类型
                BmsConstant.ORDER_BUSINESS_TYPE, // 订单业务类型
                BmsConstant.SOURCE, // 来源
                BmsConstant.TEMPERATURE_REQUIREMENT// 温度要求
        });

        shipBillDTO.setOrderTypeName(ConvertorUtil.getName(dicData, BmsConstant.ORDER_TYPE, String.valueOf(headerModel.getOrderType())));
        shipBillDTO.setOrderBusinessTypeName(ConvertorUtil.getName(dicData, BmsConstant.ORDER_BUSINESS_TYPE, String.valueOf(headerModel.getOrderBusinessType())));
        shipBillDTO.setTemperatureRequirementName(ConvertorUtil.getName(dicData, BmsConstant.TEMPERATURE_REQUIREMENT, String.valueOf(headerModel.getTemperatureRequirement())));
        shipBillDTO.setShipperTypeName(ConvertorUtil.getName(dicData, BmsConstant.SHIPPER_TYPE, String.valueOf(headerModel.getShipperType())));
        shipBillDTO.setConsigneeTypeName(ConvertorUtil.getName(dicData, BmsConstant.CONSIGNEE_TYPE, String.valueOf(headerModel.getConsigneeType())));
        shipBillDTO.setDeliveryMethodTypeName(headerModel.getDeliveryMethodType() == 1 ? "配送" : "自提");
        shipBillDTO.setTransportTypeName(headerModel.getTransportType() == 1 ? "整车" : "零担");
        shipBillDTO.setStatusName(ConvertorUtil.getName(dicData, BmsConstant.SHIPBILL_STATUS, String.valueOf(headerModel.getStatus())));
        shipBillDTO.setSourceName(ConvertorUtil.getName(dicData, BmsConstant.SOURCE, String.valueOf(headerModel.getSource())));
        shipBillDTO.setCarrierTypeName(headerModel.getCarrierType() == 1 ? "承运商" : "司机");

        List<ShipBillFeeDetail> list = Lists.newArrayList();
        ShipBillFeeDetail detail = new ShipBillFeeDetail();
        BeanUtils.copyProperties(detailModels, detail);
        list.add(detail);

        Criteria dCriteria = Criteria.forClass(BmsShipBillDetailModel.class);
        Restriction r2 = Restrictions.eq("shipbillNo", headerModel.getShipbillNo());
        dCriteria.setRestriction(Restrictions.and(r2));
        List<BmsShipBillDetailModel> itemDetail = shipBillDetailMapper.findByCriteria(dCriteria);

        List<ShipBillDetailDTO> itemList = Lists.newArrayList();
        for (BmsShipBillDetailModel detailModel : itemDetail) {
            ShipBillDetailDTO dto = new ShipBillDetailDTO();
            BeanUtils.copyProperties(detailModel, dto);
            dto.setCargoThermosphereName(ConvertorUtil.getName(dicData, BmsConstant.TEMPERATURE_REQUIREMENT, String.valueOf(detailModel.getCargoThermosphere())));
            itemList.add(dto);
        }
        shipBillDTO.setList(list);
        shipBillDTO.setItemList(itemList);
        return shipBillDTO;
    }

    @Override
    public List<BmsShipBillDetailModel> findListForItem(Long id) {
        UserEntity user = PlgFxUsrUtils.getUserEntity();
        BmsShipBillFeeDetailModel feeDetailModel = shipBillFeeDetailMapper.findById(id, BmsShipBillFeeDetailModel.class);
        String shipbillNo = "";
        if (ObjectUtil.isEmpty(feeDetailModel)) {
            BmsShipBillHeaderModel headerModel = shipBillHeadMapper.findById(id, BmsShipBillHeaderModel.class);
            shipbillNo = headerModel.getShipbillNo();
        } else {
            shipbillNo = feeDetailModel.getShipbillNo();
        }
        Criteria pCriteria = Criteria.forClass(BmsShipBillDetailModel.class);
        Restriction r3 = Restrictions.eq("shipbillNo", shipbillNo);
        Restriction r4 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
        pCriteria.setRestriction(Restrictions.and(r3, r4));
        return shipBillDetailMapper.findByCriteria(pCriteria);
    }

    @Override
    public List<BmsShipBillPackageModel> findListForPack(Long id) {

        UserEntity user = PlgFxUsrUtils.getUserEntity();
        BmsShipBillFeeDetailModel feeDetailModel = shipBillFeeDetailMapper.findById(id, BmsShipBillFeeDetailModel.class);
        String shipbillNo = "";
        if (ObjectUtil.isEmpty(feeDetailModel)) {
            BmsShipBillHeaderModel headerModel = shipBillHeadMapper.findById(id, BmsShipBillHeaderModel.class);
            shipbillNo = headerModel.getShipbillNo();
        } else {
            shipbillNo = feeDetailModel.getShipbillNo();
        }
        Criteria pCriteria = Criteria.forClass(BmsShipBillPackageModel.class);
        Restriction r1 = Restrictions.eq("shipbillNo", shipbillNo);
        Restriction r2 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
        pCriteria.setRestriction(Restrictions.and(r1, r2));
        return shipBillPackageMapper.findByCriteria(pCriteria);
    }

    @Override
    public List<BmsShipBillAdjustModel> findListForAdjust(Long id) {
        UserEntity user = PlgFxUsrUtils.getUserEntity();
        BmsShipBillFeeDetailModel feeDetailModel = shipBillFeeDetailMapper.findById(id, BmsShipBillFeeDetailModel.class);
        String shipbillNo = "";
        if (ObjectUtil.isEmpty(feeDetailModel)) {
            BmsShipBillHeaderModel headerModel = shipBillHeadMapper.findById(id, BmsShipBillHeaderModel.class);
            shipbillNo = headerModel.getShipbillNo();
        } else {
            shipbillNo = feeDetailModel.getShipbillNo();
        }
        Criteria aCriteria = Criteria.forClass(BmsShipBillAdjustModel.class);
        Restriction r1 = Restrictions.eq("shipbillNo", shipbillNo);
        Restriction r2 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
        aCriteria.setRestriction(Restrictions.and(r1, r2));
        return shipBillAdjustMapper.findByCriteria(aCriteria);
    }

    @Override
    public List<BmsLogOperationModel> findListForLog(Long id) {
        UserEntity user = PlgFxUsrUtils.getUserEntity();
        String shipbillNo;
        BmsShipBillFeeDetailModel feeDetailModel = shipBillFeeDetailMapper.findById(id, BmsShipBillFeeDetailModel.class);
        if (ObjectUtil.isEmpty(feeDetailModel)) {
            BmsShipBillHeaderModel headerModel = shipBillHeadMapper.findById(id, BmsShipBillHeaderModel.class);
            shipbillNo = headerModel.getShipbillNo();
        } else {
            shipbillNo = feeDetailModel.getShipbillNo();
        }

        Criteria lCriteria = Criteria.forClass(BmsLogOperationModel.class);
        Restriction r12 = Restrictions.eq("orderNo", shipbillNo);
        Restriction r13 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
        lCriteria.setRestriction(Restrictions.and(r12, r13));
        return logOperationMapper.findByCriteria(lCriteria);
    }

    @Override
    public void importShipbillData(MultipartFile file) {
        // 导入文件判断
        FileUtils.multipartFileJudge(file);

        // 获取导入批次号
        RestMessage<String> restMessage = maindataTmsResource.getCodeNumberByCode(BmsConstant.IMPORT_BATCHNO, "L");
        if (!restMessage.isSuccess()) {
            throw new ParameterException("获取导入批次号调用失败 :" + restMessage.getMessage());
        }
        String importBatchNumber = restMessage.getData();
        ToolKits.isParamNull(importBatchNumber, "导入批次号生成失败");

        // 导入日志对象
        ImportLogAddVO logAddVO = new ImportLogAddVO();
        logAddVO.setImportObjNo(BmsConstant.BMS_SHIP_BILL_IMPORT);
        logAddVO.setImportBatchNumber(importBatchNumber);

        // 导入统计
        int count = 0;
        try {
            // 导入执行
            count = this.importProcess(file);

            logAddVO.setStatus(BmsConstant.IMPORT_STATUS_YES);
            logAddVO.setSuccessNum(count);
            logAddVO.setFailNum(0);
            RestMessage<String> restMessage1 = maindataTmsResource.addImportLogExecute(logAddVO);
            if (!restMessage1.isSuccess()) {
                throw new ParameterException(restMessage1.getMessage());
            }
        } catch (Exception e) {
            e.printStackTrace();

            logAddVO.setStatus(BmsConstant.IMPORT_STATUS_NO);
            logAddVO.setSuccessNum(0);
            logAddVO.setFailNum(count);
            logAddVO.setFailReason(e.getMessage());
            RestMessage<String> restMessage1 = maindataTmsResource.addImportLogExecute(logAddVO);
            if (!restMessage1.isSuccess()) {
                throw new ParameterException(restMessage1.getMessage());
            }

            throw new ParameterException(e.getMessage());
        }
    }

    @Override
    public void feeSubmit(List<String> ids) {
        UserEntity user = PlgFxUsrUtils.getUserEntity();
        for (String id : ids) {
            BmsShipBillFeeDetailModel detailModel = shipBillFeeDetailMapper.findById(id, BmsShipBillFeeDetailModel.class);
            if (ObjectUtil.isEmpty(detailModel)) {
                throw new PluginException("查询费用详情为空");
            }
            detailModel.setUpdatetime(DateUtil.date());
            detailModel.setUpdateperson(user.getNickname());
            detailModel.setBillingStatus(1);
            detailModel.setExpenseStatus(2);
            shipBillFeeDetailMapper.update(detailModel);
        }
    }

    @Override
    public void shipBillFeeUpdate(ShipBillFeeSaveDTO dto) {
        UserEntity user = PlgFxUsrUtils.getUserEntity();
        List<ShipBillFeeSave> list = dto.getList();
        for (ShipBillFeeSave shipBillFeeSave : list) {
            Criteria criteria = Criteria.forClass(BmsShipBillHeaderModel.class);
            Restriction r1 = Restrictions.eq("shipbillNo", shipBillFeeSave.getShipbillNo());
            criteria.setRestriction(Restrictions.and(r1));
            List<BmsShipBillHeaderModel> headerModel = shipBillHeadMapper.findByCriteria(criteria);
            if (ObjectUtil.isEmpty(headerModel)) {
                throw new PluginException("查询运单信息不存在");
            }
            // 删除详情
            Criteria dCriteria = Criteria.forClass(BmsShipBillFeeDetailModel.class);
            Restriction r2 = Restrictions.eq("shipbillNo", shipBillFeeSave.getShipbillNo());
            dCriteria.setRestriction(Restrictions.and(r2));
            shipBillFeeDetailMapper.deleteByCriteria(dCriteria);

            // 新增
            List<ShipBillFeeDetail> details = shipBillFeeSave.getDetailList();
            List<BmsShipBillFeeDetailModel> models = Lists.newArrayList();
            for (ShipBillFeeDetail shipBillFeeDetail : details) {
                BmsShipBillFeeDetailModel detailModel = new BmsShipBillFeeDetailModel();
                BeanUtils.copyProperties(shipBillFeeDetail, detailModel);
                //detailModel.setShipbillNo(shipBillFeeSave.getShipbillNo());
                detailModel.setCreateperson(user.getNickname());
                detailModel.setCreatetime(DateUtil.date());
                detailModel.setUpdateperson(user.getNickname());
                detailModel.setUpdatetime(DateUtil.date());
                detailModel.setEnterpriseId(user.getEnterpriseId());
                detailModel.setEnterpriseName(user.getEnterpriseName());
                models.add(detailModel);
            }
            shipBillFeeDetailMapper.saveBatch(models);
        }

    }

    @Override
    public List<ShipBillFeeDetail> queryFeeInfo(Long id) {
        if (ObjectUtil.isEmpty(id)) {
            throw new PluginException("查询条件不能为空");
        }
        BmsShipBillHeaderModel headerModel = shipBillHeadMapper.findById(id, BmsShipBillHeaderModel.class);
        if (ObjectUtil.isEmpty(headerModel)) {
            throw new PluginException("查询运单信息不存在");
        }

        UserEntity user = PlgFxUsrUtils.getUserEntity();
        Criteria criteria = Criteria.forClass(BmsShipBillFeeDetailModel.class);
        Restriction r1 = Restrictions.eq("shipbillNo", headerModel.getShipbillNo());
        Restriction r2 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
        criteria.setRestriction(Restrictions.and(r1, r2));
        List<BmsShipBillFeeDetailModel> detailModels = shipBillFeeDetailMapper.findByCriteria(criteria);
        List<ShipBillFeeDetail> list = Lists.newArrayList();

        List<SysRefdatadModel> dicData = convertorUtil.getDictionary(new String[]{BmsConstant.EXPENSE_STATUS, // 费用状态
                BmsConstant.BILLING_STATUS // 计费状态
        });

        for (BmsShipBillFeeDetailModel detailModel : detailModels) {
            ShipBillFeeDetail feeDetail = new ShipBillFeeDetail();
            BeanUtils.copyProperties(detailModel, feeDetail);
            feeDetail.setExpenseStatusName(ConvertorUtil.getName(dicData, BmsConstant.EXPENSE_STATUS, String.valueOf(feeDetail.getExpenseStatus())));
            feeDetail.setBillingSourceName(detailModel.getBillingSource() == 1 ? "价格表生成" : "手工录入");
            feeDetail.setBillingTypeName(detailModel.getBillingType());
            feeDetail.setBillingStatusName(ConvertorUtil.getName(dicData, BmsConstant.BILLING_STATUS, String.valueOf(detailModel.getBillingStatus())));
            feeDetail.setExpenseCode(detailModel.getExpenseCode());
            feeDetail.setExpenseName(detailModel.getExpenseName());
            feeDetail.setExpenseAccountCode(detailModel.getExpenseAccountCode());
            feeDetail.setExpenseAccountName(detailModel.getExpenseAccountName());
            list.add(feeDetail);
        }
        return list;
    }

    @Override
    public Page<FeeManagementPopDTO> feeManagement(ExpenseManagementQueryVO vo) {
        UserEntity user = PlgFxUsrUtils.getUserEntity();

        Criteria criteria = Criteria.forClass(BmsExpenseManagementModel.class);
        Restriction r1 = ObjectUtil.isEmpty(vo.getExpenseCode()) ? null : Restrictions.like("expenseCode", "%" + vo.getExpenseCode() + "%");
        Restriction r2 = ObjectUtil.isEmpty(vo.getExpenseName()) ? null : Restrictions.like("expenseName", "%" + vo.getExpenseName() + "%");
        Restriction r3 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
        Restriction r4 = ObjectUtil.isNull(vo.getExpenseClassify()) ? null : Restrictions.eq(BmsExpenseManagementModel::getExpenseClassify, vo.getExpenseClassify());
        Restriction r5 = ObjectUtil.isNull(vo.getStatus()) ? null : Restrictions.eq(BmsExpenseManagementModel::getStatus, vo.getStatus());
        criteria.setRestriction(Restrictions.and(r1, r2, r3, r4, r5));
        criteria.setOrder(Order.newInstance().desc("updatetime"));

        PageUtils.startPage(vo.getPageNum(), vo.getPageSize());
        List<BmsExpenseManagementModel> list = managementMapper.findByCriteria(criteria);

        List<FeeManagementPopDTO> dtos = Lists.newArrayList();
        for (BmsExpenseManagementModel expenseAccountModel : list) {
            FeeManagementPopDTO dto = new FeeManagementPopDTO();
            BeanUtils.copyProperties(expenseAccountModel, dto);
            dto.setStatusName(expenseAccountModel.getStatus() == 1 ? "启用" : "停用");
            dto.setExpenseTypeName(expenseAccountModel.getExpenseClassify() == 1 ? "收入" : "支出");
            dto.setExpenseType(expenseAccountModel.getExpenseClassify());

            // 查询费用科目
			/*String expenseAccountCode = expenseAccountModel.getExpenseAccountCode();
			Criteria aClass = Criteria.forClass(ExpenseAccountModel.class);
			Restriction r4 = Restrictions.eq("expenseCode", expenseAccountCode);
			Restriction r5 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
			aClass.setRestriction(Restrictions.and(r4, r5));
			List<ExpenseAccountModel> accountModels = accountMapper.findByCriteria(aClass);
			if (ObjectUtil.isNotEmpty(accountModels)) {
				ExpenseAccountModel model = accountModels.get(0);

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

    @Override
    public Page<ShipBillFeeListDTO> feeList(ShipBillQueryVO vo) {
        UserEntity user = PlgFxUsrUtils.getUserEntity();
        if (!user.getUserType().equals(BmsConstant.USER_TYPE_ZY)) {
            throw new PluginException("当前人员没有操作权限！");
        }
        vo.setUserType(user.getUserType());
        if (user.getOwnedAllDataAuthFlag().equals(BmsConstant.USER_DEPARTMENT_AUTH_Y)) {
            vo.setDepartmentIds(user.getDepts().toArray(new String[0]));
            vo.setIsDept(BmsConstant.IS_DEPT_YES);
        } else {
            vo.setIsDept(BmsConstant.IS_DEPT_NO);
            vo.setBranchIds(user.getWarehouses());
            vo.setCargoOwnerIds(user.getConsignors());
        }
        PageUtils.startPage(vo.getPageNum(), vo.getPageSize());
        List<ShipBillFeeListDTO> feeList = shipBillHeadMapper.findFeeListForTra(vo, user.getEnterpriseId());

        List<SysRefdatadModel> dicData = convertorUtil.getDictionary(new String[]{BmsConstant.SHIPBILL_STATUS, // 运单状态
                BmsConstant.SHIPPER_TYPE, // 运输状态
                BmsConstant.ABNORMAL_STATUS, // 异常状态
                BmsConstant.ORDER_TYPE, // 订单类型
                BmsConstant.CONSIGNEE_TYPE, // 收货方类型
                BmsConstant.ORDER_BUSINESS_TYPE, // 订单业务类型
                BmsConstant.SETTLEMENT_STATUS, // 核算状态
                BmsConstant.SOURCE, // 来源
                BmsConstant.TEMPERATURE_REQUIREMENT, // 温度要求
                BmsConstant.SYNCHRONOUS_STATUS, // 同步状态
                BmsConstant.BILLING_STATUS, // 计费状态
                BmsConstant.EXPENSE_STATUS // 费用状态
        });
        for (ShipBillFeeListDTO feeListDTO : feeList) {
            feeListDTO.setExpenseStatusName(ConvertorUtil.getName(dicData, BmsConstant.EXPENSE_STATUS, String.valueOf(feeListDTO.getExpenseStatus())));
            feeListDTO.setSourceName(ConvertorUtil.getName(dicData, BmsConstant.SOURCE, String.valueOf(feeListDTO.getSource())));
            feeListDTO.setSynchronousStatusName(ConvertorUtil.getName(dicData, BmsConstant.SYNCHRONOUS_STATUS, String.valueOf(feeListDTO.getSynchronousStatus())));
            feeListDTO.setBillingStatusName(ConvertorUtil.getName(dicData, BmsConstant.BILLING_STATUS, String.valueOf(feeListDTO.getBillingStatus())));
            feeListDTO.setSettlementStatusName(ConvertorUtil.getName(dicData, BmsConstant.SETTLEMENT_STATUS, String.valueOf(feeListDTO.getSettlementStatus())));

            feeListDTO.setOrderTypeName(ConvertorUtil.getName(dicData, BmsConstant.ORDER_TYPE, String.valueOf(feeListDTO.getOrderType())));
            feeListDTO.setOrderBusinessTypeName(ConvertorUtil.getName(dicData, BmsConstant.ORDER_BUSINESS_TYPE, String.valueOf(feeListDTO.getOrderBusinessType())));
            feeListDTO.setTemperatureRequirementName(ConvertorUtil.getName(dicData, BmsConstant.TEMPERATURE_REQUIREMENT, String.valueOf(feeListDTO.getTemperatureRequirement())));
            feeListDTO.setShipperTypeName(ConvertorUtil.getName(dicData, BmsConstant.SHIPPER_TYPE, String.valueOf(feeListDTO.getShipperType())));
            feeListDTO.setConsigneeTypeName(ConvertorUtil.getName(dicData, BmsConstant.CONSIGNEE_TYPE, String.valueOf(feeListDTO.getConsigneeType())));
            feeListDTO.setDeliveryMethodTypeName(feeListDTO.getDeliveryMethodType() == 1 ? "配送" : "自提");
            feeListDTO.setTransportTypeName(feeListDTO.getTransportType() == 1 ? "整车" : "零担");
            feeListDTO.setStatusName(ConvertorUtil.getName(dicData, BmsConstant.SHIPBILL_STATUS, String.valueOf(feeListDTO.getStatus())));
            feeListDTO.setShipBillStatusName(ConvertorUtil.getName(dicData, BmsConstant.SHIPBILL_STATUS, String.valueOf(feeListDTO.getShipBillStatus())));
            feeListDTO.setCarrierTypeName(feeListDTO.getCarrierType() == 1 ? "承运商" : "司机");
            feeListDTO.setAbnormalStatusName(feeListDTO.getAbnormalStatus() == 1 ? "异常" : "非异常");
            if (feeListDTO.getCarrierType().intValue() == 2) {
                feeListDTO.setCarrierName(feeListDTO.getDriverName());
            }

            feeListDTO.setBillingSourceName(feeListDTO.getBillingSource().intValue() == 1 ? "价格表生成" : "手工录入");
        }
        return PageUtils.getPage(feeList);
    }

    @Override
    public ShipBillFeeDTO shipBillFeeDetailForTran(Long id, String source) {
        if (ObjectUtil.isEmpty(id)) {
            throw new PluginException("查询条件不能为空");
        }
        ShipBillFeeDTO shipBillDTO = new ShipBillFeeDTO();
        BmsShipBillHeaderModel headerModel = shipBillHeadMapper.findById(id, BmsShipBillHeaderModel.class);
        BeanUtils.copyProperties(headerModel, shipBillDTO);

        List<SysRefdatadModel> dicData = convertorUtil.getDictionary(new String[]{BmsConstant.SHIPBILL_STATUS, // 运单状态
                BmsConstant.SHIPPER_TYPE, // 运输状态
                BmsConstant.ABNORMAL_STATUS, // 异常状态
                BmsConstant.ORDER_TYPE, // 订单类型
                BmsConstant.CONSIGNEE_TYPE, // 收货方类型
                BmsConstant.ORDER_BUSINESS_TYPE, // 订单业务类型
                BmsConstant.SOURCE, // 来源
                BmsConstant.EXPENSE_STATUS, // 费用状态
                BmsConstant.TEMPERATURE_REQUIREMENT// 温度要求
        });

        shipBillDTO.setOrderTypeName(ConvertorUtil.getName(dicData, BmsConstant.ORDER_TYPE, String.valueOf(headerModel.getOrderType())));
        shipBillDTO.setOrderBusinessTypeName(ConvertorUtil.getName(dicData, BmsConstant.ORDER_BUSINESS_TYPE, String.valueOf(headerModel.getOrderBusinessType())));
        shipBillDTO.setTemperatureRequirementName(ConvertorUtil.getName(dicData, BmsConstant.TEMPERATURE_REQUIREMENT, String.valueOf(headerModel.getTemperatureRequirement())));
        shipBillDTO.setShipperTypeName(ConvertorUtil.getName(dicData, BmsConstant.SHIPPER_TYPE, String.valueOf(headerModel.getShipperType())));
        shipBillDTO.setConsigneeTypeName(ConvertorUtil.getName(dicData, BmsConstant.CONSIGNEE_TYPE, String.valueOf(headerModel.getConsigneeType())));
        shipBillDTO.setDeliveryMethodTypeName(headerModel.getDeliveryMethodType() == 1 ? "配送" : "自提");
        shipBillDTO.setTransportTypeName(headerModel.getTransportType() == 1 ? "整车" : "零担");
        shipBillDTO.setStatusName(ConvertorUtil.getName(dicData, BmsConstant.SHIPBILL_STATUS, String.valueOf(headerModel.getStatus())));
        shipBillDTO.setSourceName(ConvertorUtil.getName(dicData, BmsConstant.SOURCE, String.valueOf(headerModel.getSource())));
        shipBillDTO.setCarrierTypeName(headerModel.getCarrierType() == 1 ? "承运商" : "司机");

        // 运单费用
        Criteria criteria = Criteria.forClass(BmsShipBillFeeDetailModel.class);
        Restriction r1 = Restrictions.eq("shipbillNo", headerModel.getShipbillNo());
        criteria.setRestriction(Restrictions.and(r1));
        List<BmsShipBillFeeDetailModel> detailModels = shipBillFeeDetailMapper.findByCriteria(criteria);

        List<ShipBillFeeDetail> list = Lists.newArrayList();
        for (BmsShipBillFeeDetailModel detailModel : detailModels) {
            ShipBillFeeDetail detail = new ShipBillFeeDetail();
            BeanUtils.copyProperties(detailModel, detail);
            detail.setExpenseStatusName(ConvertorUtil.getName(dicData, BmsConstant.EXPENSE_STATUS, String.valueOf(detailModel.getExpenseStatus())));
            detail.setBillingSourceName(detailModel.getBillingSource() == 1 ? "价格表生成" : "手工录入");
            detail.setBillingTypeName(detailModel.getBillingType());
            list.add(detail);
        }

        Criteria dCriteria = Criteria.forClass(BmsShipBillDetailModel.class);
        Restriction r2 = Restrictions.eq("shipbillNo", headerModel.getShipbillNo());
        dCriteria.setRestriction(Restrictions.and(r2));
        List<BmsShipBillDetailModel> itemDetail = shipBillDetailMapper.findByCriteria(dCriteria);

        List<ShipBillDetailDTO> itemList = Lists.newArrayList();
        for (BmsShipBillDetailModel detailModel : itemDetail) {
            ShipBillDetailDTO dto = new ShipBillDetailDTO();
            BeanUtils.copyProperties(detailModel, dto);
            dto.setCargoThermosphereName(ConvertorUtil.getName(dicData, BmsConstant.TEMPERATURE_REQUIREMENT, String.valueOf(detailModel.getCargoThermosphere())));
            itemList.add(dto);
        }
        // 查询费用信息
        Criteria fcriteria = Criteria.forClass(BmsShipBillFeeTemporaryDetailModel.class);
        Restriction r3 = Restrictions.eq("shipbillNo", headerModel.getShipbillNo());
        fcriteria.setRestriction(Restrictions.and(r3));
        List<BmsShipBillFeeTemporaryDetailModel> feeDetailModel = temporaryDetailMapper.findByCriteria(fcriteria);
        if (ObjectUtil.isNotEmpty(source) && Objects.equals(source, "1") && ObjectUtil.isNotEmpty(feeDetailModel)) {
            List<ShipBillFeeDetail> feeDetails = Lists.newArrayList();
            for (BmsShipBillFeeTemporaryDetailModel temporaryDetailModel : feeDetailModel) {
                ShipBillFeeDetail shipBillFeeDetail = new ShipBillFeeDetail();
                BeanUtils.copyProperties(temporaryDetailModel, shipBillFeeDetail);
                feeDetails.add(shipBillFeeDetail);
            }
            shipBillDTO.setList(feeDetails);
        } else {
            shipBillDTO.setList(list);
        }
        shipBillDTO.setItemList(itemList);
        return shipBillDTO;
    }

    @Override
    public List<ShipBillDTO> shipbillPop(List<String> shipbillNos) {
        shipbillNos = shipbillNos.stream().distinct().collect(Collectors.toList());
        UserEntity user = PlgFxUsrUtils.getUserEntity();
        Criteria criteria = Criteria.forClass(BmsShipBillHeaderModel.class);
        Restriction r1 = Restrictions.in("shipbillNo", shipbillNos.stream().distinct().toArray());
        Restriction r2 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
        criteria.setRestriction(Restrictions.and(r1, r2));
        criteria.setOrder(Order.newInstance().asc("updatetime"));
        List<BmsShipBillHeaderModel> models = shipBillHeadMapper.findByCriteria(criteria);
        List<ShipBillDTO> dtos = Lists.newArrayList();

        List<SysRefdatadModel> dicData = convertorUtil.getDictionary(new String[]{BmsConstant.SHIPBILL_STATUS, // 运单状态
                BmsConstant.SHIPPER_TYPE, // 运输状态
                BmsConstant.ABNORMAL_STATUS, // 异常状态
                BmsConstant.ORDER_TYPE, // 订单类型
                BmsConstant.SETTLEMENT_STATUS, // 核算状态
                BmsConstant.CONSIGNEE_TYPE, // 收货方类型
                BmsConstant.ORDER_BUSINESS_TYPE, // 订单业务类型
                BmsConstant.SOURCE, // 来源
                BmsConstant.TEMPERATURE_REQUIREMENT// 温度要求
        });

        for (BmsShipBillHeaderModel model : models) {
            ShipBillDTO shipBillDTO = new ShipBillDTO();
            BeanUtils.copyProperties(model, shipBillDTO);
            shipBillDTO.setOrderTypeName(ConvertorUtil.getName(dicData, BmsConstant.ORDER_TYPE, String.valueOf(model.getOrderType())));
            shipBillDTO.setOrderBusinessTypeName(ConvertorUtil.getName(dicData, BmsConstant.ORDER_BUSINESS_TYPE, String.valueOf(model.getOrderBusinessType())));
            shipBillDTO.setTemperatureRequirementName(ConvertorUtil.getName(dicData, BmsConstant.TEMPERATURE_REQUIREMENT, String.valueOf(model.getTemperatureRequirement())));
            shipBillDTO.setShipperTypeName(ConvertorUtil.getName(dicData, BmsConstant.SHIPPER_TYPE, String.valueOf(model.getShipperType())));
            shipBillDTO.setConsigneeTypeName(ConvertorUtil.getName(dicData, BmsConstant.CONSIGNEE_TYPE, String.valueOf(model.getConsigneeType())));
            shipBillDTO.setDeliveryMethodTypeName(model.getDeliveryMethodType() == 1 ? "配送" : "自提");
            shipBillDTO.setTransportTypeName(model.getTransportType() == 1 ? "整车" : "零担");
            shipBillDTO.setStatusName(ConvertorUtil.getName(dicData, BmsConstant.SHIPBILL_STATUS, String.valueOf(model.getStatus())));
            shipBillDTO.setSourceName(ConvertorUtil.getName(dicData, BmsConstant.SOURCE, String.valueOf(model.getSource())));
            shipBillDTO.setSettlementStatusName(ConvertorUtil.getName(dicData, BmsConstant.SETTLEMENT_STATUS, String.valueOf(model.getSettlementStatus())));
            shipBillDTO.setCarrierTypeName(model.getCarrierType() == 1 ? "承运商" : "司机");
            dtos.add(shipBillDTO);
        }
        return dtos;
    }

    @Override
    public ShipBillFeeDTO shipBillDetail(String shipbillNo) {
        if (ObjectUtil.isEmpty(shipbillNo)) {
            throw new PluginException("查询条件不能为空");
        }
        UserEntity user = PlgFxUsrUtils.getUserEntity();
        ShipBillFeeDTO shipBillDTO = new ShipBillFeeDTO();
        Criteria hCriteria = Criteria.forClass(BmsShipBillHeaderModel.class);
        Restriction r1 = Restrictions.eq("shipbillNo", shipbillNo);
        Restriction r2 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
        hCriteria.setRestriction(Restrictions.and(r1, r2));
        hCriteria.setOrder(Order.newInstance().asc("updatetime"));
        List<BmsShipBillHeaderModel> models = shipBillHeadMapper.findByCriteria(hCriteria);
        if (ObjectUtil.isEmpty(models) || models.size() > 1) {
            throw new PluginException("获取运单信息异常");
        }
        BmsShipBillHeaderModel headerModel = models.get(0);
        BeanUtils.copyProperties(headerModel, shipBillDTO);

        List<SysRefdatadModel> dicData = convertorUtil.getDictionary(new String[]{BmsConstant.SHIPBILL_STATUS, // 运单状态
                BmsConstant.SHIPPER_TYPE, // 运输状态
                BmsConstant.ABNORMAL_STATUS, // 异常状态
                BmsConstant.ORDER_TYPE, // 订单类型
                BmsConstant.CONSIGNEE_TYPE, // 收货方类型
                BmsConstant.ORDER_BUSINESS_TYPE, // 订单业务类型
                BmsConstant.SOURCE, // 来源
                BmsConstant.EXPENSE_STATUS, // 费用状态
                BmsConstant.TEMPERATURE_REQUIREMENT// 温度要求
        });

        shipBillDTO.setOrderTypeName(ConvertorUtil.getName(dicData, BmsConstant.ORDER_TYPE, String.valueOf(headerModel.getOrderType())));
        shipBillDTO.setOrderBusinessTypeName(ConvertorUtil.getName(dicData, BmsConstant.ORDER_BUSINESS_TYPE, String.valueOf(headerModel.getOrderBusinessType())));
        shipBillDTO.setTemperatureRequirementName(ConvertorUtil.getName(dicData, BmsConstant.TEMPERATURE_REQUIREMENT, String.valueOf(headerModel.getTemperatureRequirement())));
        shipBillDTO.setShipperTypeName(ConvertorUtil.getName(dicData, BmsConstant.SHIPPER_TYPE, String.valueOf(headerModel.getShipperType())));
        shipBillDTO.setConsigneeTypeName(ConvertorUtil.getName(dicData, BmsConstant.CONSIGNEE_TYPE, String.valueOf(headerModel.getConsigneeType())));
        shipBillDTO.setDeliveryMethodTypeName(headerModel.getDeliveryMethodType() == 1 ? "配送" : "自提");
        shipBillDTO.setTransportTypeName(headerModel.getTransportType() == 1 ? "整车" : "零担");
        shipBillDTO.setStatusName(ConvertorUtil.getName(dicData, BmsConstant.SHIPBILL_STATUS, String.valueOf(headerModel.getStatus())));
        shipBillDTO.setSourceName(ConvertorUtil.getName(dicData, BmsConstant.SOURCE, String.valueOf(headerModel.getSource())));
        shipBillDTO.setCarrierTypeName(headerModel.getCarrierType() == 1 ? "承运商" : "司机");

        // 运单费用
        Criteria criteria = Criteria.forClass(BmsShipBillFeeDetailModel.class);
        Restriction r3 = Restrictions.eq("shipbillNo", headerModel.getShipbillNo());
        Restriction r4 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
        criteria.setRestriction(Restrictions.and(r3, r4));
        List<BmsShipBillFeeDetailModel> detailModels = shipBillFeeDetailMapper.findByCriteria(criteria);

        List<ShipBillFeeDetail> list = Lists.newArrayList();
        for (BmsShipBillFeeDetailModel detailModel : detailModels) {
            ShipBillFeeDetail detail = new ShipBillFeeDetail();
            BeanUtils.copyProperties(detailModel, detail);
            detail.setExpenseStatusName(ConvertorUtil.getName(dicData, BmsConstant.EXPENSE_STATUS, String.valueOf(detailModel.getExpenseStatus())));
            detail.setBillingSourceName(detailModel.getBillingSource() == 1 ? "价格表生成" : "手工录入");
            detail.setBillingTypeName(detailModel.getBillingType());
            list.add(detail);
        }

        Criteria dCriteria = Criteria.forClass(BmsShipBillDetailModel.class);
        Restriction r5 = Restrictions.eq("shipbillNo", headerModel.getShipbillNo());
        Restriction r6 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
        dCriteria.setRestriction(Restrictions.and(r5, r6));
        List<BmsShipBillDetailModel> itemDetail = shipBillDetailMapper.findByCriteria(dCriteria);

        List<ShipBillDetailDTO> itemList = Lists.newArrayList();
        for (BmsShipBillDetailModel detailModel : itemDetail) {
            ShipBillDetailDTO dto = new ShipBillDetailDTO();
            BeanUtils.copyProperties(detailModel, dto);
            dto.setCargoThermosphereName(ConvertorUtil.getName(dicData, BmsConstant.TEMPERATURE_REQUIREMENT, String.valueOf(detailModel.getCargoThermosphere())));
            itemList.add(dto);
        }
        shipBillDTO.setList(list);
        shipBillDTO.setItemList(itemList);
        return shipBillDTO;
    }

    @Override
    public List<BmsLogOperationModel> findListForTraLog(Long id) {

        UserEntity user = PlgFxUsrUtils.getUserEntity();
        BmsShipBillHeaderModel headerModel = shipBillHeadMapper.findById(id, BmsShipBillHeaderModel.class);
        String shipbillNo = headerModel.getShipbillNo();
        Criteria lCriteria = Criteria.forClass(BmsLogOperationModel.class);
        Restriction r12 = Restrictions.eq("orderNo", shipbillNo);
        Restriction r13 = Restrictions.eq("enterpriseId", user.getEnterpriseId());
        lCriteria.setRestriction(Restrictions.and(r12, r13));
        return logOperationMapper.findByCriteria(lCriteria);
    }

    public int importProcess(MultipartFile file) {
        // 人员权限
        UserEntity user = PlgFxUsrUtils.getUserEntity();
        ToolKits.isParamNull(user, "当前人员没有操作权限");

        // 当前时间
        Date date = new Date();

        int impCnt = 0;

        Properties properties = new Properties();

        // 待转换的对象
        Class<BmsShipBillImportVO> importVOClass = BmsShipBillImportVO.class;

        // 标准模板查询
        RestMessage<List<StandardTemplateDetailsListDTO>> restMessage = maindataTmsResource.listStandardTemplateDetailsExecute(BmsConstant.BMS_SHIP_BILL_IMPORT);
        if (!restMessage.isSuccess()) {
            throw new ParameterException("标准模板详情查询失败:" + restMessage.getMessage());
        }

        List<StandardTemplateDetailsListDTO> standardTemplateDetailsListDTOs = restMessage.getData();
        ToolKits.isParamNull(standardTemplateDetailsListDTOs, "运单标准模板未配置");

        for (StandardTemplateDetailsListDTO standardTemplateDetailsListDTO : standardTemplateDetailsListDTOs) {
            // 属性字段和注解属性字段值 键值对
            properties.setProperty(standardTemplateDetailsListDTO.getStdColNo(), standardTemplateDetailsListDTO.getCustColName());
        }

        // @ExcelProperty注解属性修改
        ImportUtils.setHeaderValue(properties, importVOClass);

        // EXCEL转对象
        List<BmsShipBillImportVO> bmsShipBillImportVOS = null;
        try {
            bmsShipBillImportVOS = ExcelUtils.read(file, importVOClass);
        } catch (Exception e) {
            e.printStackTrace();

            throw new ParameterException("EXCEL转对象失败:" + e.getMessage());
        }

        ToolKits.isParamNull(bmsShipBillImportVOS, "EXCEL文件内容为空,请重新导入");
        log.info("运单导入详情:{}", JsonMapper.toJson(bmsShipBillImportVOS));

        for (BmsShipBillImportVO bmsShipBillImportVO : bmsShipBillImportVOS) {
            ToolKits.isParamNull(bmsShipBillImportVO.getCargoOwnerCode(), "货主编码不为空");
            ToolKits.isParamNull(bmsShipBillImportVO.getCargoOwnerName(), "货主名称不为空");
            ToolKits.isParamNull(bmsShipBillImportVO.getOrderType(), "订单类型不为空");
            ToolKits.isParamNull(bmsShipBillImportVO.getOrderBusinessType(), "订单业务类型不为空");
            ToolKits.isParamNull(bmsShipBillImportVO.getDeliveryMethodType(), "配送方式不为空");
            ToolKits.isParamNull(bmsShipBillImportVO.getTransportType(), "运输模式不为空");
            ToolKits.isParamNull(bmsShipBillImportVO.getTemperatureRequirement(), "温度要求不为空");
            ToolKits.isParamNull(bmsShipBillImportVO.getShipperType(), "发货方类型不为空");
            ToolKits.isParamNull(bmsShipBillImportVO.getShipperUnitCode(), "发货方单位编码不为空");
            ToolKits.isParamNull(bmsShipBillImportVO.getShipperUnitName(), "发货方单位名称不为空");
            ToolKits.isParamNull(bmsShipBillImportVO.getShipperProvinceName(), "发货方省名称不为空");
            ToolKits.isParamNull(bmsShipBillImportVO.getShipperCityName(), "发货方市名称不为空");
            ToolKits.isParamNull(bmsShipBillImportVO.getShipperDistrictName(), "发货方区/县名称不为空");
            ToolKits.isParamNull(bmsShipBillImportVO.getShipperAddress(), "发货方详细地址不为空");
            ToolKits.isParamNull(bmsShipBillImportVO.getConsigneeType(), "收货方类型不为空");
            ToolKits.isParamNull(bmsShipBillImportVO.getConsigneeUnitCode(), "收货方单位编码不为空");
            ToolKits.isParamNull(bmsShipBillImportVO.getConsigneeUnitName(), "收货方单位名称不为空");
            ToolKits.isParamNull(bmsShipBillImportVO.getConsigneeProvinceName(), "收货方省名称不为空");
            ToolKits.isParamNull(bmsShipBillImportVO.getConsigneeCityName(), "收货方市名称不为空");
            ToolKits.isParamNull(bmsShipBillImportVO.getConsigneeDistrictName(), "收货方区/县名称不为空");
            ToolKits.isParamNull(bmsShipBillImportVO.getConsigneeAddress(), "收货方详细地址不为空");
            ToolKits.isParamNull(bmsShipBillImportVO.getTotalPcs(), "总件数不为空");
            ToolKits.isParamNull(bmsShipBillImportVO.getItemCode(), "商品编码不为空");
            ToolKits.isParamNull(bmsShipBillImportVO.getItemName(), "商品名称不为空");
            ToolKits.isParamNull(bmsShipBillImportVO.getPcs(), "商品件数不为空");

            ToolKits.isParamNull(bmsShipBillImportVO.getDepartmentName(), "所属部门名称不为空");

            List<Organization> data1;
            // 所属部门名称判定是否存在
            RestMessage<List<Organization>> departMents = userTmsResource.search(null, bmsShipBillImportVO.getDepartmentName(), null, String.valueOf(user.getEnterpriseId()));
            if (!departMents.isSuccess()) {
                throw new RuntimeException("部门【" + bmsShipBillImportVO.getDepartmentName() + "】不存在!");
            } else {
                data1 = departMents.getData();

                if (!user.getDepts().contains(data1.get(0).getId())) {
                    throw new RuntimeException("部门【" + bmsShipBillImportVO.getDepartmentName() + "】不存在，请先维护部门!");
                }
            }

            // 获取运单汇总ID
            RestMessage<String> restMessage1 = maindataTmsResource.getCodeNumberByCode(BmsConstant.SHIP_BILL_HEAD_ID, "L");
            if (!restMessage1.isSuccess()) {
                throw new ParameterException("生成运单汇总ID失败:" + restMessage1.getMessage());
            }
            String shipbillId = restMessage1.getData();

            // 运单对象
            BmsShipBillHeaderModel headerModel = new BmsShipBillHeaderModel();
            BeanUtils.copyProperties(bmsShipBillImportVO, headerModel);

            // 运单明细对象
            BmsShipBillDetailModel tmsShipbillDetailModel = new BmsShipBillDetailModel();
            BeanUtils.copyProperties(bmsShipBillImportVO, tmsShipbillDetailModel);

            // 订单类型数据字典
            PublicMethods.referenceDataProcessing(headerModel, maindataTmsResource, BmsConstant.ORDER_TYPE, "orderType", bmsShipBillImportVO.getOrderType());
            // 订单业务类型数据字典
            PublicMethods.referenceDataProcessing(headerModel, maindataTmsResource, BmsConstant.ORDER_BUSINESS_TYPE, "orderBusinessType", bmsShipBillImportVO.getOrderBusinessType());
            // 配送方式数据字典
            PublicMethods.referenceDataProcessing(headerModel, maindataTmsResource, BmsConstant.DELIVERY_METHOD_TYPE, "deliveryMethodType", bmsShipBillImportVO.getDeliveryMethodType());
            // 运输模式数据字典
            PublicMethods.referenceDataProcessing(headerModel, maindataTmsResource, BmsConstant.TRANSPORT_TYPE, "transportType", bmsShipBillImportVO.getTransportType());
            // 温度要求数据字典
            PublicMethods.referenceDataProcessing(headerModel, maindataTmsResource, BmsConstant.TEMPERATURE_REQUIREMENT, "temperatureRequirement", bmsShipBillImportVO.getTemperatureRequirement());
            // 发货方类型数据字典
            PublicMethods.referenceDataProcessing(headerModel, maindataTmsResource, BmsConstant.SHIPPER_TYPE, "shipperType", bmsShipBillImportVO.getShipperType());
            // 收货方类型数据字典
            PublicMethods.referenceDataProcessing(headerModel, maindataTmsResource, BmsConstant.CONSIGNEE_TYPE, "consigneeType", bmsShipBillImportVO.getConsigneeType());
            // 商品包装类型数据字典
            PublicMethods.referenceDataProcessing(tmsShipbillDetailModel, maindataTmsResource, BmsConstant.PACK_TYPE, "packType", bmsShipBillImportVO.getPackType());

            // 商品货物温层数据字典
            PublicMethods.referenceDataProcessing(tmsShipbillDetailModel, maindataTmsResource, BmsConstant.CARGO_THERMOSPHERE, "cargoThermosphere", bmsShipBillImportVO.getCargoThermosphere());

            // 货主校验
            CargoOwnerByEncodingNameVO cargoOwnerByEncodingNameVO = new CargoOwnerByEncodingNameVO();
            cargoOwnerByEncodingNameVO.setCargoOwnerCode(bmsShipBillImportVO.getCargoOwnerCode());
            cargoOwnerByEncodingNameVO.setCargoOwnerName(bmsShipBillImportVO.getCargoOwnerName());
            RestMessage<CargoOwnerByEncodingNameDTO> cargoOwnerRestMessage = maindataTmsResource.getCargoOwnerByEncodingNameExecute(cargoOwnerByEncodingNameVO);
            if (cargoOwnerRestMessage.isSuccess()) {
                headerModel.setCargoOwnerId(cargoOwnerRestMessage.getData().getCargoOwnerId());
            } else {
                throw new ParameterException(cargoOwnerRestMessage.getMessage());
            }

            // 判断商品资料
            ItemByEncodingNameDTO itemByEncodingNameDTO = null;
            ItemByEncodingNameVO itemByEncodingNameVO = new ItemByEncodingNameVO();
            itemByEncodingNameVO.setCargoOwnerId(headerModel.getCargoOwnerId());
            itemByEncodingNameVO.setCode(bmsShipBillImportVO.getItemCode());
            itemByEncodingNameVO.setName(bmsShipBillImportVO.getItemName());
            RestMessage<ItemByEncodingNameDTO> itemMessage = maindataTmsResource.getItemByEncodingNameExecute(itemByEncodingNameVO);
            if (itemMessage.isSuccess()) {
                itemByEncodingNameDTO = itemMessage.getData();
            } else {
                throw new ParameterException(itemMessage.getMessage());
            }

            // 判断仓资料
            BranchByNameDTO branchByNameDTO = null;
            if (ToolKits.isNotEmpty(bmsShipBillImportVO.getBranchName())) {
                BranchByNameVO branchByNameVO = new BranchByNameVO();
                branchByNameVO.setName(bmsShipBillImportVO.getBranchName());
                RestMessage<BranchByNameDTO> branchRestMessage = maindataTmsResource.getBranchByNameExecute(branchByNameVO);
                if (branchRestMessage.isSuccess()) {
                    branchByNameDTO = branchRestMessage.getData();
                } else {
                    throw new ParameterException(branchRestMessage.getMessage());
                }
            }

            // 汇总赋值
            headerModel.setShipbillNo(shipbillId);
            headerModel.setOrderId(bmsShipBillImportVO.getOrderNo());
            headerModel.setWmsOrderId(bmsShipBillImportVO.getWmsOrderNo());
            headerModel.setStatus(BmsConstant.SHIPBILL_STATUS_END);
            headerModel.setSource(BmsConstant.SOURCE_EXCEL);

            headerModel.setEnterpriseId(user.getEnterpriseId());
            headerModel.setEnterpriseName(user.getEnterpriseName());
            headerModel.setCreateperson(user.getNickname());
            headerModel.setCreatetime(date);
            headerModel.setUpdateperson(user.getNickname());
            headerModel.setUpdatetime(date);

            headerModel.setDepartmentId(data1.get(0).getId());
            headerModel.setDepartmentCode(data1.get(0).getCode());
            headerModel.setDepartmentName(data1.get(0).getName());

            shipBillHeadMapper.save(headerModel);

            // 运单明细赋值
            tmsShipbillDetailModel.setShipbillNo(headerModel.getShipbillNo());
            tmsShipbillDetailModel.setBranchId(branchByNameDTO == null ? null : branchByNameDTO.getId());
            tmsShipbillDetailModel.setBranchCode(branchByNameDTO == null ? null : branchByNameDTO.getCode());
            tmsShipbillDetailModel.setBranchName(branchByNameDTO == null ? null : branchByNameDTO.getName());
            tmsShipbillDetailModel.setCargoOwnerId(headerModel.getCargoOwnerId());
            tmsShipbillDetailModel.setCargoOwnerCode(headerModel.getCargoOwnerCode());
            tmsShipbillDetailModel.setCargoOwnerName(headerModel.getCargoOwnerName());
            tmsShipbillDetailModel.setSeqno(1);
            tmsShipbillDetailModel.setItemId(itemByEncodingNameDTO.getItemId());
            tmsShipbillDetailModel.setItemCategoryId(itemByEncodingNameDTO.getItemCategoryId());
            tmsShipbillDetailModel.setItemCategoryCode(itemByEncodingNameDTO.getItemCategoryCode());
            tmsShipbillDetailModel.setItemCategoryName(itemByEncodingNameDTO.getItemCategoryName());
            tmsShipbillDetailModel.setEnterpriseId(user.getEnterpriseId());
            tmsShipbillDetailModel.setEnterpriseName(user.getEnterpriseName());
            tmsShipbillDetailModel.setCreateperson(user.getNickname());
            tmsShipbillDetailModel.setCreatetime(date);
            tmsShipbillDetailModel.setUpdateperson(user.getNickname());
            tmsShipbillDetailModel.setUpdatetime(date);
            shipBillDetailMapper.save(tmsShipbillDetailModel);

            // 调整单
            BmsShipBillAdjustModel adjustModel = new BmsShipBillAdjustModel();
            adjustModel.setShipbillNo(headerModel.getShipbillNo());
            adjustModel.setAdjustMemo("新增件数" + headerModel.getTotalPcs());
            adjustModel.setAdjustDate(DateUtil.date());
            adjustModel.setAdjustName(user.getNickname());
            adjustModel.setCreateperson(user.getNickname());
            adjustModel.setCreatetime(DateUtil.date());
            adjustModel.setUpdateperson(user.getNickname());
            adjustModel.setUpdatetime(DateUtil.date());
            adjustModel.setEnterpriseId(user.getEnterpriseId());
            adjustModel.setEnterpriseName(user.getEnterpriseName());
            shipBillAdjustMapper.save(adjustModel);

            // 日志操作
            BmsLogOperationModel logVO = new BmsLogOperationModel();
            logVO.setCreatetime(DateUtil.date());
            logVO.setCreateperson(user.getNickname());
            logVO.setEnterpriseId(user.getEnterpriseId());
            logVO.setEnterpriseName(user.getEnterpriseName());
            logVO.setOrderNo(headerModel.getShipbillNo());
            logVO.setLogMemo("新增");
            logVO.setLogType(1);
            logOperationMapper.save(logVO);

            impCnt++;

        }
        return impCnt;
    }

    public BigDecimal getShipbillTaxAmt(String shipbillNo, Integer billingSource) {
        BigDecimal taxAmt = BigDecimal.ZERO;

        Criteria bmsFeeCriteria = Criteria.forClass(BmsShipBillFeeDetailModel.class);
        Restriction r2 = Restrictions.eq(BmsShipBillFeeDetailModel::getShipbillNo, shipbillNo);
        Restriction r3 = Restrictions.eq(BmsShipBillFeeDetailModel::getExpenseType, 2);
        Restriction r4 = ObjectUtil.isEmpty(billingSource) ? null : Restrictions.eq(BmsShipBillFeeDetailModel::getBillingSource, billingSource);
        bmsFeeCriteria.setRestriction(Restrictions.and(r2, r3, r4));
        List<BmsShipBillFeeDetailModel> feeDetailModels = shipBillFeeDetailMapper.findByCriteria(bmsFeeCriteria);
        if (ObjectUtil.isNotEmpty(feeDetailModels)) {
            feeDetailModels = feeDetailModels.stream().filter(fee -> ObjectUtil.isNotEmpty(fee.getTaxAmt())).collect(Collectors.toList());
            for (BmsShipBillFeeDetailModel fee : feeDetailModels) {
                taxAmt = taxAmt.add(fee.getTaxAmt());
            }
        }
        return taxAmt;
    }

}