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

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import com.google.common.collect.Lists;
import com.prolog.common.util.ToolKits;
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.Restriction;
import com.prolog.framework.core.restriction.Restrictions;
import com.prolog.framework.dao.util.PageUtils;
import com.prolog.product.core.framework.entity.UserEntity;
import com.prolog.product.core.framework.util.PlgFxUsrUtils;
import com.prolog.rdc.tms.constant.BmsConstant;
import com.prolog.rdc.tms.constant.enums.LogTypeEnum;
import com.prolog.rdc.tms.dao.mapper.BmsBillPayFeeDetailMapper;
import com.prolog.rdc.tms.dao.mapper.BmsBillPayFeeHeaderMapper;
import com.prolog.rdc.tms.dao.mapper.LoadingBillHeadMapper;
import com.prolog.rdc.tms.dao.mapper.ShipBillHeadMapper;
import com.prolog.rdc.tms.model.dto.DriverledgerBillDTO;
import com.prolog.rdc.tms.model.dto.DriverledgerShipBillDTO;
import com.prolog.rdc.tms.model.dto.SySParameterDTO;
import com.prolog.rdc.tms.model.dto.pay.BmsBillPayFeeDetailDTO;
import com.prolog.rdc.tms.model.dto.shipbill.BmsLogOperationDTO;
import com.prolog.rdc.tms.model.dto.shipbill.BmsShipBillDTO;
import com.prolog.rdc.tms.model.dto.shipbill.BmsShipBillDetailDTO;
import com.prolog.rdc.tms.model.dto.shipbill.BmsShipBillPackageDTO;
import com.prolog.rdc.tms.model.entity.BmsBillPayFeeDetailModel;
import com.prolog.rdc.tms.model.entity.BmsBillPayFeeHeaderModel;
import com.prolog.rdc.tms.model.entity.BmsShipBillHeaderModel;
import com.prolog.rdc.tms.model.entity.SysRefdatadModel;
import com.prolog.rdc.tms.model.vo.DriverledgerBillPageVO;
import com.prolog.rdc.tms.model.vo.DriverledgerBillViewVO;
import com.prolog.rdc.tms.model.vo.pay.BmsPayDetailAddVO;
import com.prolog.rdc.tms.model.vo.pay.BmsPayFeeAddVO;
import com.prolog.rdc.tms.proxy.MainDataProxy;
import com.prolog.rdc.tms.service.BmsBillLogService;
import com.prolog.rdc.tms.service.BmsLoadingBillService;
import com.prolog.rdc.tms.service.BmsShipBillService;
import com.prolog.rdc.tms.service.DriverledgerBillService;
import com.prolog.rdc.tms.util.ConvertorUtil;

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

/**
 *
 * 费用管理-司机台账实现层
 *
 * @className :DriverledgerBillServiceImpl
 * @author :fanzw
 * @date :2023/4/25
 * @description :
 *
 * @version :1.2.1
 *
 */
@Slf4j
@Service
public class DriverledgerBillServiceImpl implements DriverledgerBillService {

	@Resource
	private LoadingBillHeadMapper loadingBillHeadMapper;

	@Resource
	private BmsShipBillService shipBillService;

	@Resource
	private ShipBillHeadMapper shipBillHeadMapper;

	@Resource
	private MainDataProxy mainDataProxy;

	@Resource
	private ConvertorUtil convertorUtil;

	@Resource
	private BmsBillPayFeeHeaderMapper payFeeHeaderMapper;

	@Resource
	private BmsBillPayFeeDetailMapper payFeeDetailMapper;

	@Resource
	private BmsLoadingBillService loadingBillService;

	@Autowired
	private BmsBillLogService logService;

	/**
	 * 司机台账查询
	 *
	 * @param driverledgerBillPageVO 入参
	 *
	 * @return Page<DriverledgerBillDTO>
	 */
	@Override
	public Page<DriverledgerBillDTO> pageDriverledgerBillDate(DriverledgerBillPageVO driverledgerBillPageVO) {
		ToolKits.isParamNull(driverledgerBillPageVO, "请求不为空！");
		ToolKits.isParamNull(driverledgerBillPageVO.getPageNum(), "当前页码不为空");
		ToolKits.isParamNull(driverledgerBillPageVO.getPageSize(), "每页条数不为空");

		// 用户权限
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前用户没有操作权限");
		ToolKits.isParamNull(user.getDepts(), "当前用户没有部门权限");

		// 权限控制 仅支持自有账号
		if (ObjectUtil.notEqual(user.getUserType(), BmsConstant.USER_TYPE_ZY)) {
			throw new PrologException("当前人员没有查询权限");
		}

		// 权限赋值
		driverledgerBillPageVO.setEnterpriseId(user.getEnterpriseId());
		driverledgerBillPageVO.setSettlementDepartmentTds(user.getDepts().stream().toArray(String[]::new));

		// 执行查询
		PageUtils.startPage(driverledgerBillPageVO.getPageNum(), driverledgerBillPageVO.getPageSize());
		List<DriverledgerBillDTO> driverledgerBillDTOs = loadingBillHeadMapper.pageDriverledgerBillSql(driverledgerBillPageVO);
		if (CollectionUtil.isNotEmpty(driverledgerBillDTOs)) {
			// 获取翻译字典
			List<SysRefdatadModel> dicData = getDic();

			for (DriverledgerBillDTO driverledgerBillDTO : driverledgerBillDTOs) {
				this.convert(driverledgerBillDTO, dicData);
			}
		}

		return PageUtils.getPage(driverledgerBillDTOs);
	}

	/**
	 * 派车单翻译赋值
	 *
	 * @param driverledgerBillDTO
	 * @param dicData
	 *
	 */
	private DriverledgerBillDTO convert(DriverledgerBillDTO driverledgerBillDTO, List<SysRefdatadModel> dicData) {
		driverledgerBillDTO.setFeeCltTypeName(ConvertorUtil.getName(dicData, BmsConstant.FEE_CLT_TYPE, String.valueOf(driverledgerBillDTO.getFeeCltType())));
		driverledgerBillDTO.setVehicleAscriptionName(ConvertorUtil.getName(dicData, BmsConstant.VEHICLE_TYPE, String.valueOf(driverledgerBillDTO.getVehicleAscription())));
		driverledgerBillDTO.setVehicleTypeCategoryName(ConvertorUtil.getName(dicData, BmsConstant.VEHICLE_TYPE_CATEGORY, String.valueOf(driverledgerBillDTO.getVehicleTypeCategory())));
		driverledgerBillDTO.setSynchronousStatusName(ConvertorUtil.getName(dicData, BmsConstant.SYNCHRONOUS_STATUS, String.valueOf(driverledgerBillDTO.getSynchronousStatus())));
		driverledgerBillDTO.setCostStatusName(ConvertorUtil.getName(dicData, BmsConstant.COST_STATUS, String.valueOf(driverledgerBillDTO.getCostStatus())));
		driverledgerBillDTO.setSettlementStatusName(ConvertorUtil.getName(dicData, BmsConstant.SETTLEMENT_STATUS, String.valueOf(driverledgerBillDTO.getSettlementStatus())));
		driverledgerBillDTO.setStatusName(ConvertorUtil.getName(dicData, BmsConstant.LOADING_BILL_STATUS, String.valueOf(driverledgerBillDTO.getStatus())));
		driverledgerBillDTO.setPayFeeCltTypeName(ConvertorUtil.getName(dicData, BmsConstant.FEE_CLT_TYPE, String.valueOf(driverledgerBillDTO.getPayFeeCltType())));
		driverledgerBillDTO.setCarrierTypeName(ConvertorUtil.getName(dicData, BmsConstant.LINE_CARRIER_TYPE, String.valueOf(driverledgerBillDTO.getCarrierType())));
		return driverledgerBillDTO;
	}

	/**
	 * 派车单翻译数据字典
	 */
	private List<SysRefdatadModel> getDic() {
		return convertorUtil.getDictionary(new String[] {
				// 核算状态
				BmsConstant.SETTLEMENT_STATUS,
				// 计费状态
				BmsConstant.COST_STATUS,
				// 同步状态
				BmsConstant.SYNCHRONOUS_STATUS,
				// 承运方类型
				BmsConstant.LINE_CARRIER_TYPE,
				// 车辆类别
				BmsConstant.VEHICLE_TYPE_CATEGORY, BmsConstant.VEHICLE_TYPE,
				// 费用计算类型
				BmsConstant.FEE_CLT_TYPE,
				// 来源
				BmsConstant.SOURCE, BmsConstant.LOADING_BILL_STATUS, BmsConstant.CHECK_STATUS });
	}

	/**
	 * 司机台账查看
	 *
	 * @param id 入参
	 * @return
	 */
	@Override
	public DriverledgerBillDTO viewDriverledgerBillDate(Long id) {
		ToolKits.isParamNull(id, "派车单ID不为空");

		// 用户权限
		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前用户没有操作权限");
		ToolKits.isParamNull(user.getDepts(), "当前用户没有部门权限");

		DriverledgerBillViewVO driverledgerBillViewVO = new DriverledgerBillViewVO();
		driverledgerBillViewVO.setId(id);

		// 权限赋值
		driverledgerBillViewVO.setEnterpriseId(user.getEnterpriseId());

		// 执行查询
		List<DriverledgerBillDTO> driverledgerBillDTOs = loadingBillHeadMapper.viewDriverledgerBillSql(driverledgerBillViewVO);
		Assert.isTrue(driverledgerBillDTOs.size() != 0, "装车单ID【" + id + "】不存在");
		Assert.isTrue(driverledgerBillDTOs.size() == 1, "装车单ID【" + id + "】单据重复");

		// 响应对象
		DriverledgerBillDTO driverledgerBillDTO = driverledgerBillDTOs.get(0);
		this.convert(driverledgerBillDTO, getDic());
		driverledgerBillDTO.setBillNo(driverledgerBillDTO.getLoadingBillNo());

		// 获取运单信息
		Criteria criteria = Criteria.forClass(BmsShipBillHeaderModel.class);
		Restriction r1 = Restrictions.eq(BmsShipBillHeaderModel::getLoadingBillNo, driverledgerBillDTO.getLoadingBillNo());
		Restriction r2 = Restrictions.eq(BmsShipBillHeaderModel::getEnterpriseId, user.getEnterpriseId());
		criteria.setRestriction(Restrictions.and(r1, r2));
		List<BmsShipBillHeaderModel> tmsShipbillPackageModels = shipBillHeadMapper.findByCriteria(criteria);

		List<DriverledgerShipBillDTO> driverledgerShipBillDTOS = Lists.newArrayList();
		// 获取翻译字典
		List<SysRefdatadModel> dicData = getShipbillDic();
		for (BmsShipBillHeaderModel tmsShipbillPackageModel : tmsShipbillPackageModels) {
			DriverledgerShipBillDTO driverledgerShipBillDTO = new DriverledgerShipBillDTO();
			BeanUtils.copyProperties(tmsShipbillPackageModel, driverledgerShipBillDTO);
			this.modelToBmsShipBillDTO(driverledgerShipBillDTO, dicData);
			driverledgerShipBillDTOS.add(driverledgerShipBillDTO);
		}

		driverledgerBillDTO.setShipBillList(driverledgerShipBillDTOS);
		driverledgerBillDTO.setFeeList(this.listFeeData(id));

		return driverledgerBillDTO;
	}

	/**
	 * 运单翻译赋值
	 */
	private DriverledgerShipBillDTO modelToBmsShipBillDTO(DriverledgerShipBillDTO driverledgerShipBillDTO, List<SysRefdatadModel> dicData) {
		driverledgerShipBillDTO.setOrderTypeName(ConvertorUtil.getName(dicData, BmsConstant.ORDER_TYPE, String.valueOf(driverledgerShipBillDTO.getOrderType())));
		driverledgerShipBillDTO.setOrderBusinessTypeName(ConvertorUtil.getName(dicData, BmsConstant.ORDER_BUSINESS_TYPE, String.valueOf(driverledgerShipBillDTO.getOrderBusinessType())));
		driverledgerShipBillDTO.setTemperatureRequirementName(ConvertorUtil.getName(dicData, BmsConstant.TEMPERATURE_REQUIREMENT, String.valueOf(driverledgerShipBillDTO.getTemperatureRequirement())));
		driverledgerShipBillDTO.setShipperTypeName(ConvertorUtil.getName(dicData, BmsConstant.SHIPPER_TYPE, String.valueOf(driverledgerShipBillDTO.getShipperType())));
		driverledgerShipBillDTO.setConsigneeTypeName(ConvertorUtil.getName(dicData, BmsConstant.CONSIGNEE_TYPE, String.valueOf(driverledgerShipBillDTO.getConsigneeType())));
		driverledgerShipBillDTO.setStatusName(ConvertorUtil.getName(dicData, BmsConstant.SHIPBILL_STATUS, String.valueOf(driverledgerShipBillDTO.getStatus())));
		driverledgerShipBillDTO.setSourceName(ConvertorUtil.getName(dicData, BmsConstant.SOURCE, String.valueOf(driverledgerShipBillDTO.getSource())));
		driverledgerShipBillDTO.setShipBillStatusName(ConvertorUtil.getName(dicData, BmsConstant.SHIPBILL_STATUS, String.valueOf(driverledgerShipBillDTO.getShipBillStatus())));
		driverledgerShipBillDTO.setSynchronousStatusName(ConvertorUtil.getName(dicData, BmsConstant.SYNCHRONOUS_STATUS, String.valueOf(driverledgerShipBillDTO.getSynchronousStatus())));
		driverledgerShipBillDTO.setAbnormalStatusName(ConvertorUtil.getName(dicData, BmsConstant.ABNORMAL_STATUS, String.valueOf(driverledgerShipBillDTO.getAbnormalStatus())));
		driverledgerShipBillDTO.setDeliveryMethodTypeName(ConvertorUtil.getName(dicData, BmsConstant.DELIVERY_METHOD_TYPE, String.valueOf(driverledgerShipBillDTO.getDeliveryMethodType())));
		driverledgerShipBillDTO.setTransportTypeName(ConvertorUtil.getName(dicData, BmsConstant.TRANSPORT_TYPE, String.valueOf(driverledgerShipBillDTO.getTransportType())));
		driverledgerShipBillDTO.setFeeCltTypeName(ConvertorUtil.getName(dicData, BmsConstant.FEE_CLT_TYPE, String.valueOf(driverledgerShipBillDTO.getFeeCltType())));
		driverledgerShipBillDTO.setPayFeeCltTypeName(ConvertorUtil.getName(dicData, BmsConstant.FEE_CLT_TYPE, String.valueOf(driverledgerShipBillDTO.getPayFeeCltType())));
		driverledgerShipBillDTO.setCarrierTypeName(ConvertorUtil.getName(dicData, BmsConstant.LINE_CARRIER_TYPE, String.valueOf(driverledgerShipBillDTO.getCarrierType())));

		return driverledgerShipBillDTO;
	}

	/**
	 * 运单翻译数据字典
	 */
	private List<SysRefdatadModel> getShipbillDic() {
		return 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,
				// 承运方类型
				BmsConstant.LINE_CARRIER_TYPE,
				// 配送方式
				BmsConstant.DELIVERY_METHOD_TYPE,
				// 运输模式
				BmsConstant.TRANSPORT_TYPE,
				// 费用计算类型
				BmsConstant.FEE_CLT_TYPE, BmsConstant.CHECK_STATUS });
	}

	/**
	 * 费用录入
	 *
	 * @param bmsPayFeeAddVO
	 * @return
	 */
	@Override
	public void addFeeData(BmsPayFeeAddVO bmsPayFeeAddVO) {
		ToolKits.isParamNull(bmsPayFeeAddVO, "请求不为空！");
		ToolKits.isParamNull(bmsPayFeeAddVO.getIdList(), "请选择需要录入费用的台账");
		ToolKits.isParamNull(bmsPayFeeAddVO.getDetailAddVOList(), "请录入费用");

		UserEntity user = PlgFxUsrUtils.getUserEntity();
		ToolKits.isParamNull(user, "当前用户没有操作权限");
		ToolKits.isParamNull(user.getDepts(), "当前用户没有部门权限");

		SySParameterDTO parameterData = mainDataProxy.queryParameter();
		// 费用精度
		Integer costPrecision = parameterData.getCostPrecision();
		// 费用取整
		Integer costInteger = parameterData.getCostInteger();
		RoundingMode roundingMode = null;
		if (costInteger == 1) {
			roundingMode = RoundingMode.HALF_UP;
		} else if (costInteger == 2) {
			roundingMode = RoundingMode.UP;
		} else if (costInteger == 3) {
			roundingMode = RoundingMode.DOWN;
		}

		// 查询支出费用单
		List<BmsBillPayFeeHeaderModel> headerModelList = payFeeHeaderMapper.findByIds(BmsBillPayFeeHeaderModel.class, bmsPayFeeAddVO.getIdList().toArray(), null);
		RoundingMode finalRoundingMode = roundingMode;
		bmsPayFeeAddVO.getDetailAddVOList().forEach(detailAddVO -> {
			BigDecimal taxAmt = detailAddVO.getTaxAmt();
			BigDecimal noTaxAmt = NumberUtil.div(taxAmt, NumberUtil.add(BigDecimal.ONE, NumberUtil.div(new BigDecimal(detailAddVO.getTaxPoint()), new BigDecimal("100"))), costPrecision, finalRoundingMode);
			BigDecimal avgTaxAmt = taxAmt;
			BigDecimal avgNoTaxAmt = noTaxAmt;
			// 分摊到每一单处理
			if (detailAddVO.getIsShare() == 1) {
				avgTaxAmt = NumberUtil.div(taxAmt, headerModelList.size(), costPrecision, finalRoundingMode);
				avgNoTaxAmt = NumberUtil.div(noTaxAmt, headerModelList.size(), costPrecision, finalRoundingMode);
			}

			BigDecimal tax = NumberUtil.sub(avgTaxAmt, avgNoTaxAmt);
			detailAddVO.setTaxAmt(avgTaxAmt);
			detailAddVO.setTax(tax);
			detailAddVO.setNoTaxAmt(avgNoTaxAmt);
			for (int i = 0; i < headerModelList.size(); i++) {
				if (detailAddVO.getIsShare() == 1 && i == headerModelList.size() - 1) {
					detailAddVO.setTaxAmt(NumberUtil.sub(taxAmt, NumberUtil.mul(avgTaxAmt, (headerModelList.size() - 1))));
					detailAddVO.setNoTaxAmt(NumberUtil.sub(noTaxAmt, NumberUtil.mul(avgNoTaxAmt, (headerModelList.size() - 1))));
					detailAddVO.setTax(NumberUtil.sub(detailAddVO.getTaxAmt(), detailAddVO.getNoTaxAmt()));
				}
				addDetail(headerModelList.get(i), detailAddVO, user);
			}
		});

		headerModelList.forEach(headerModel -> {
			List<BmsBillPayFeeDetailModel> detailModelList = findDetailModel(headerModel);
			if (CollectionUtil.isNotEmpty(detailModelList)) {
				headerModel.setContractPayAmount(detailModelList.stream().filter(bmsBillPayFeeDetailModel -> bmsBillPayFeeDetailModel.getBillingSource() == 1).map(BmsBillPayFeeDetailModel::getTaxAmt).reduce(BigDecimal.ZERO, NumberUtil::add));
				headerModel.setPayAmount(detailModelList.stream().map(BmsBillPayFeeDetailModel::getTaxAmt).reduce(BigDecimal.ZERO, NumberUtil::add));
			} else {
				headerModel.setContractPayAmount(BigDecimal.ZERO);
				headerModel.setPayAmount(BigDecimal.ZERO);
			}
			headerModel.setUpdateperson(user.getNickname());
			headerModel.setUpdatetime(DateUtil.date());
			payFeeHeaderMapper.update(headerModel);
		});
	}

	/**
	 * 运单信息查询
	 *
	 * @param id
	 * @return
	 */
	@Override
	public List<BmsShipBillDTO> listShipBillData(Long id) {
		ToolKits.isParamNull(id, "派车单ID不为空");
		// 查询支出派车单费用
		BmsBillPayFeeHeaderModel headerModel = payFeeHeaderMapper.findById(id, BmsBillPayFeeHeaderModel.class);
		return loadingBillService.getShipBill(headerModel.getBillId());
	}

	/**
	 * 运单商品信息查询
	 *
	 * @param id
	 * @return
	 */
	@Override
	public List<BmsShipBillDetailDTO> listItemData(Long id) {
		ToolKits.isParamNull(id, "派车单ID不为空");

		List<BmsShipBillDetailDTO> list = Lists.newArrayList();
		List<Long> shipBillIdList = getShipBillIdList(id);
		if (CollectionUtil.isNotEmpty(shipBillIdList)) {
			list = shipBillIdList.stream().flatMap(shipBillId -> shipBillService.getItem(shipBillId).stream()).collect(Collectors.toList());
		}
		return list;
	}

	/**
	 * 查询运单主键
	 * 
	 * @param id
	 * @return
	 */
	private List<Long> getShipBillIdList(Long id) {
		List<Long> shipBillIdList = Lists.newArrayList();
		BmsBillPayFeeHeaderModel headerModel = payFeeHeaderMapper.findById(id, BmsBillPayFeeHeaderModel.class);
		if (headerModel.getBillType() == 10) {
			shipBillIdList.add(headerModel.getBillId());
		} else {
			Criteria criteria = Criteria.forClass(BmsShipBillHeaderModel.class);
			Restriction r1 = Restrictions.eq(BmsShipBillHeaderModel::getLoadingId, headerModel.getBillId());
			Restriction r2 = Restrictions.eq(BmsShipBillHeaderModel::getEnterpriseId, headerModel.getEnterpriseId());
			criteria.setRestriction(Restrictions.and(r1, r2));
			List<BmsShipBillHeaderModel> modelList = shipBillHeadMapper.findByCriteria(criteria);
			if (CollectionUtil.isNotEmpty(modelList)) {
				shipBillIdList = modelList.stream().map(BmsShipBillHeaderModel::getId).collect(Collectors.toList());
			}
		}
		return shipBillIdList;
	}

	/**
	 * 运单包裹信息查询
	 *
	 * @param id
	 * @return
	 */
	@Override
	public List<BmsShipBillPackageDTO> listPackageData(Long id) {
		ToolKits.isParamNull(id, "派车单ID不为空");

		List<BmsShipBillPackageDTO> list = Lists.newArrayList();
		List<Long> shipBillIdList = getShipBillIdList(id);
		if (CollectionUtil.isNotEmpty(shipBillIdList)) {
			list = shipBillIdList.stream().flatMap(shipBillId -> shipBillService.getPackage(shipBillId).stream()).collect(Collectors.toList());
		}
		return list;
	}

	/**
	 * 审批信息查询
	 *
	 * @param id
	 * @return
	 */
	@Override
	public List<Object> listAuditData(Long id) {
		return null;
	}

	/**
	 * 费用信息查询
	 *
	 * @param id
	 * @return
	 */
	@Override
	public List<BmsBillPayFeeDetailDTO> listFeeData(Long id) {
		ToolKits.isParamNull(id, "派车单ID不为空");

		BmsBillPayFeeHeaderModel headerModel = payFeeHeaderMapper.findById(id, BmsBillPayFeeHeaderModel.class);
		List<BmsBillPayFeeDetailDTO> dtoList = Lists.newArrayList();
		List<BmsBillPayFeeDetailModel> modelList = findDetailModel(headerModel);
		if (CollectionUtil.isNotEmpty(modelList)) {
			List<SysRefdatadModel> dicData = convertorUtil.getDictionary(new String[] {
					// 费用状态
					BmsConstant.EXPENSE_STATUS,
					// 计费状态
					BmsConstant.BILLING_STATUS });

			dtoList = modelList.stream().map(dto -> {
				BmsBillPayFeeDetailDTO detailDTO = BeanUtil.copyProperties(dto, BmsBillPayFeeDetailDTO.class);
				detailDTO.setExpenseStatusName(ConvertorUtil.getName(dicData, BmsConstant.EXPENSE_STATUS, String.valueOf(detailDTO.getExpenseStatus())));
				detailDTO.setBillingSourceName(detailDTO.getBillingSource() == 1 ? "价格表生成" : "手工录入");
				detailDTO.setBillingTypeName(detailDTO.getBillingType());
				detailDTO.setBillingStatusName(ConvertorUtil.getName(dicData, BmsConstant.BILLING_STATUS, String.valueOf(detailDTO.getBillingStatus())));
				return detailDTO;
			}).collect(Collectors.toList());
		}
		return dtoList;
	}

	/**
	 * 费用信息提交
	 *
	 * @param idList
	 */
	@Override
	public void submitFeeData(List<Long> idList) {
		ToolKits.isParamNull(idList, "派车单ID不为空");

		UserEntity user = PlgFxUsrUtils.getUserEntity();

		List<BmsBillPayFeeDetailModel> detailModelList = payFeeDetailMapper.findByIds(BmsBillPayFeeDetailModel.class, idList.toArray(), null);
		detailModelList.forEach(detailModel -> {
			if (BmsConstant.EXPENSE_STATUS_0.equals(detailModel.getExpenseStatus())) {
				detailModel.setExpenseStatus(BmsConstant.EXPENSE_STATUS_2);
				detailModel.setUpdateperson(user.getNickname());
				detailModel.setUpdatetime(DateUtil.date());
				payFeeDetailMapper.update(detailModel);
			}
		});
	}

	/**
	 * 操作日志查询
	 *
	 * @param id
	 * @return
	 */
	@Override
	public List<BmsLogOperationDTO> listLogData(Long id) {
		ToolKits.isParamNull(id, "派车单ID不为空");
		return logService.getLog(LogTypeEnum.PAY_FEE, id.toString());
	}

	/**
	 * 生成支出费用明细
	 * 
	 * @param headerModel
	 * @param detailAddVO
	 * @return
	 */
	private BmsBillPayFeeDetailModel addDetail(BmsBillPayFeeHeaderModel headerModel, BmsPayDetailAddVO detailAddVO, UserEntity user) {
		String expenseNo = mainDataProxy.getCodeNumberByCode(BmsConstant.SHIP_BILL_EXPENSE_NO);
		// 生成支出费用明细
		BmsBillPayFeeDetailModel detailModel = new BmsBillPayFeeDetailModel();
		detailModel.setBillNo(headerModel.getBillNo());
		detailModel.setBillId(headerModel.getBillId());
		detailModel.setPayFeeType(headerModel.getPayFeeType());
		detailModel.setExpenseCode(detailAddVO.getExpenseCode());
		detailModel.setExpenseName(detailAddVO.getExpenseName());
		detailModel.setExpenseType(detailAddVO.getExpenseType());
		detailModel.setExpenseTypeName(detailAddVO.getExpenseTypeName());
		detailModel.setExpenseAccountCode(detailAddVO.getExpenseAccountCode());
		detailModel.setExpenseAccountName(detailAddVO.getExpenseAccountName());
		detailModel.setAmount(detailAddVO.getTaxAmt());
		detailModel.setTaxPoint(detailAddVO.getTaxPoint());
		detailModel.setTaxAmt(detailAddVO.getTaxAmt());
		detailModel.setIsPreTax(detailAddVO.getIsPreTax());
		detailModel.setNoTaxAmt(detailAddVO.getNoTaxAmt());
		detailModel.setTax(detailAddVO.getTax());
		detailModel.setIsShare(detailAddVO.getIsShare().toString());
		detailModel.setMemo(detailAddVO.getMemo());
		detailModel.setExpenseNo(expenseNo);
		detailModel.setExpenseStatus(0);
		detailModel.setCheckStatus(BmsConstant.CHECK_STATUS_0);
		detailModel.setBillingSource(2);
		detailModel.setBillingStatus(1);
		detailModel.setBillingDate(DateUtil.date());
//        detailModel.setBillingContract();
//        detailModel.setBillingPrice();
//        detailModel.setBillingType();
//        detailModel.setBillingFailReason();
		detailModel.setCreateperson(user.getNickname());
		detailModel.setCreatetime(DateUtil.date());
		detailModel.setUpdateperson(user.getNickname());
		detailModel.setUpdatetime(DateUtil.date());
		detailModel.setEnterpriseId(user.getEnterpriseId());
		detailModel.setEnterpriseName(user.getEnterpriseName());
		payFeeDetailMapper.save(detailModel);
		return detailModel;
	}

	/**
	 * 查询支出费用明细
	 * 
	 * @param headerModel
	 * @return
	 */
	private List<BmsBillPayFeeDetailModel> findDetailModel(BmsBillPayFeeHeaderModel headerModel) {
		Criteria criteria = Criteria.forClass(BmsBillPayFeeDetailModel.class);
		Restriction r1 = Restrictions.eq(BmsBillPayFeeDetailModel::getBillId, headerModel.getBillId());
		Restriction r2 = Restrictions.eq(BmsBillPayFeeDetailModel::getBillNo, headerModel.getBillNo());
		Restriction r3 = Restrictions.eq(BmsBillPayFeeDetailModel::getEnterpriseId, headerModel.getEnterpriseId());
		criteria.setRestriction(Restrictions.and(r1, r2, r3));
		return payFeeDetailMapper.findByCriteria(criteria);
	}

	/**
	 * 司机费用查询
	 *
	 * @param driverledgerBillPageVO
	 * @return List<DriverledgerBillDTO>
	 */
	public List<DriverledgerBillDTO> queryDriverFeeByBillData(DriverledgerBillPageVO driverledgerBillPageVO) {
		ToolKits.isParamNull(driverledgerBillPageVO, "请求不为空！");
		ToolKits.isParamNull(driverledgerBillPageVO.getLoadingBillNos(), "派车单不为空");

		// 执行查询
		return loadingBillHeadMapper.queryDriverFeeByBillNos(driverledgerBillPageVO);
	}

}
