/*
 * Copyright [2022] [https://www.xiaonuo.vip]
 *
 * Snowy采用APACHE LICENSE 2.0开源协议，您在使用过程中，需要注意以下几点：
 *
 * 1.请不要删除和修改根目录下的LICENSE文件。
 * 2.请不要删除和修改Snowy源码头部的版权声明。
 * 3.本项目代码可免费商业使用，商业使用请保留源码和相关描述文件的项目出处，作者声明等。
 * 4.分发源码时候，请注明软件出处 https://www.xiaonuo.vip
 * 5.不可二次分发开源参与同类竞品，如有想法可联系团队xiaonuobase@qq.com商议合作。
 * 6.若您的项目无法满足以上几点，需要更多功能代码，获取Snowy商业授权许可，请在官网购买授权，地址为 https://www.xiaonuo.vip
 */
package vip.xiaonuo.biz.modular.depotTruckBook.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.logging.log4j.util.Strings;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import vip.xiaonuo.biz.api.cloud.param.DepotCloudAlarmAddParam;
import vip.xiaonuo.biz.core.Const.BizStr;
import vip.xiaonuo.biz.core.exception.BizExceptionEnum;
import vip.xiaonuo.biz.modular.depotAlarm.service.DepotAlarmService;
import vip.xiaonuo.biz.modular.depotGrainInfo.service.DepotGrainInfoFileService;
import vip.xiaonuo.biz.modular.depotGrainInfoPrice.entity.DepotGrainInfoPrice;
import vip.xiaonuo.biz.modular.depotGrainInfoPrice.service.DepotGrainInfoPriceService;
import vip.xiaonuo.biz.modular.depotRepayOrder.entity.DepotRepayOrder;
import vip.xiaonuo.biz.modular.depotRepayOrder.param.DepotRepayOrderPageParam;
import vip.xiaonuo.biz.modular.depotRepayOrder.service.DepotRepayOrderService;
import vip.xiaonuo.biz.modular.depotSampling.entity.DepotSampling;
import vip.xiaonuo.biz.modular.depotSampling.service.DepotSamplingService;
import vip.xiaonuo.biz.modular.depotTruckAdmitFlow.param.DepotTruckAdmitFlowAddParam;
import vip.xiaonuo.biz.modular.depotTruckAdmitFlow.service.DepotTruckAdmitFlowService;
import vip.xiaonuo.biz.modular.depotTruckBook.entity.DepotTruckBook;
import vip.xiaonuo.biz.modular.depotTruckBook.entity.DepotTruckBookBillVo;
import vip.xiaonuo.biz.modular.depotTruckBook.mapper.DepotTruckBookMapper;
import vip.xiaonuo.biz.modular.depotTruckBook.param.*;
import vip.xiaonuo.biz.modular.depotGrain.service.DepotGrainService;
import vip.xiaonuo.biz.modular.depotTruckLade.entity.DepotTruckLade;
import vip.xiaonuo.biz.modular.depotTruckLade.service.DepotTruckLadeService;
import vip.xiaonuo.biz.modular.depotTruckWeighDouble.entity.DepotTruckWeighDouble;
import vip.xiaonuo.biz.modular.depotTruckWeighDouble.service.DepotTruckWeighDoubleService;
import vip.xiaonuo.biz.modular.depotWork.entity.DepotWork;
import vip.xiaonuo.biz.modular.depotWork.param.DepotWorkAddParam;
import vip.xiaonuo.biz.modular.depotWork.service.DepotWorkService;
import vip.xiaonuo.common.enums.CommonSortOrderEnum;
import vip.xiaonuo.common.exception.CommonException;
import vip.xiaonuo.common.page.CommonPageRequest;
import vip.xiaonuo.common.util.BigDecimalUtil;
import vip.xiaonuo.common.util.DatesUtil;
import vip.xiaonuo.dev.api.DevFileApi;
import vip.xiaonuo.dev.modular.file.util.MultipartFileUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 车辆预约表Service接口
 *
 * @author xiang
 * @date 2023/09/13 09:21
 **/
@Service
public class DepotTruckBookService extends ServiceImpl<DepotTruckBookMapper, DepotTruckBook> {

    @Resource
    DepotGrainService depotGrainService;
    @Resource
    DepotTruckWeighDoubleService truckWeighDoubleService;
    @Resource
    DepotWorkService depotWorkService;
    @Resource
    DepotSamplingService samplingService;
    @Resource
    DepotRepayOrderService repayOrderService;
    @Resource
    DepotTruckAdmitFlowService truckAdmitFlowService;
    @Resource
    DepotGrainInfoPriceService grainInfoPriceService;
    @Resource
    DevFileApi devFileApi;
    @Resource
    DepotGrainInfoFileService depotGrainInfoFileService;
    @Resource
    DepotAlarmService depotAlarmService;
    @Resource
    DepotGrainInfoPriceService depotGrainInfoPriceService;
    @Resource
    DepotTruckLadeService depotTruckLadeService;

    /**
     * 获取车辆预约表分页
     *
     * @author xiang
     * @date 2023/09/13 09:21
     */
    public Page<DepotTruckBook> page(DepotTruckBookPageParam param) {
        QueryWrapper<DepotTruckBook> wrapper = new QueryWrapper<>();
        putWrapper(wrapper, param);
        Page page = this.page(CommonPageRequest.defaultPage(), wrapper);
        //匹配粮库名称
        depotGrainService.putDepotName(page.getRecords());
        return page;
    }

    /**
     * 获取车辆预约表
     *
     * @author xiang
     * @date 2023/09/13 09:21
     */
    public List<DepotTruckBook> list(DepotTruckBookPageParam param) {
        QueryWrapper<DepotTruckBook> wrapper = new QueryWrapper<>();
        putWrapper(wrapper, param);
        List<DepotTruckBook> list = this.list(wrapper);
        //匹配粮库名称
        depotGrainService.putDepotName(list);
        return list;
    }

    /**
     * 获取车辆已预约未结束表
     *
     * @author xiang
     * @date 2023/09/13 09:21
     */
    public List<DepotTruckBook> bookingLst(String depotId) {
        if (depotId == null) return new LinkedList<>();
        DepotTruckBook param = new DepotTruckBook();
        param.setDepotId(depotId);
        param.setBookState(BizStr.BOOK_RIGHT);
        param.setDepotOpApprovalState(BizStr.STATE_APPROVAL_Y);
        return lst(param);
    }

    /**
     * 获取车辆预约表
     *
     * @author xiang
     * @date 2023/09/13 09:21
     */
    public List<DepotTruckBook> lst(DepotTruckBook param) {
        return list(new LambdaQueryWrapper<>(param));
    }

    private void putWrapper(QueryWrapper<DepotTruckBook> wrapper, DepotTruckBookPageParam param) {
        List<String> depotIdLst = param.getDepotIdLst() != null && param.getDepotIdLst().isEmpty() ? depotGrainService.lstOrgGrep() : param.getDepotIdLst();
        if ("增加扦样".equals(param.getBizFlowName())) {
            param.setDepotBizType(BizStr.KU_RU);
            param.setBookState(BizStr.BOOK_RIGHT);
            param.setDepotOpApprovalState(BizStr.STATE_APPROVAL_Y);
            param.setBizFlowName(null);
            //已入场、已至扦样区
            param.setBizFlowNameLst(Arrays.asList(BizStr.FLOW_RU_CHANG, BizStr.FLOW_QIAN_YANG_IN));
            param.setBizFlowState(BizStr.STATE_TRUCK_Y);
        } else if ("扦样选择".equals(param.getBizFlowName())) {
            param.setDepotBizType(BizStr.KU_RU);
            param.setBookState(BizStr.BOOK_RIGHT);
            param.setBizFlowName(null);
            /*param.setDepotBizType(BizStr.KU_RU);
            param.setDepotOpApprovalState(BizStr.STATE_APPROVAL_Y);
            param.setBizFlowName(BizStr.FLOW_QIAN_YANG_IN);
            param.setBizFlowState(BizStr.STATE_TRUCK_Y);*/
            wrapper.lambda().in(DepotTruckBook::getTruckBookId, samplingService.waitSampling(depotIdLst));
        } else if ("补单选择".equals(param.getBizFlowName())) {
            param.setBizFlowState(BizStr.STATE_TRUCK_Y);
            param.setBookState(BizStr.BOOK_RIGHT);
            param.setDepotOpApprovalState(BizStr.STATE_APPROVAL_Y);
            param.setBizFlowName(null);
            param.setBizFlowNameNullFlag(true);
        }
        wrapper.and(Strings.isNotEmpty(param.getSearchKey()), w ->
                w.lambda().like(DepotTruckBook::getRepayOrderNo, param.getSearchKey())
                        .or().like(DepotTruckBook::getLicensePlate, param.getSearchKey())
                        .or().like(DepotTruckBook::getLicensePlateBack, param.getSearchKey())
                        .or().like(DepotTruckBook::getDriverName, param.getSearchKey())
                        .or().like(DepotTruckBook::getDriverMobile, param.getSearchKey())
                        .or().like(DepotTruckBook::getKeeperCitizenId, param.getSearchKey())
                        .or().like(DepotTruckBook::getCompanyName, param.getSearchKey())
                        .or().like(DepotTruckBook::getCompanySalesmanName, param.getSearchKey())
                        .or().like(DepotTruckBook::getCompanySalesmanMobile, param.getSearchKey())
                        .or().like(DepotTruckBook::getPayeeName, param.getSearchKey())
                        .or().like(DepotTruckBook::getPayeeMobile, param.getSearchKey())
                        .or().like(DepotTruckBook::getPayeeBank, param.getSearchKey())
                        .or().like(DepotTruckBook::getPayeeBankBillNo, param.getSearchKey()));
        wrapper.lambda().in(CollUtil.isNotEmpty(depotIdLst), DepotTruckBook::getDepotId, depotIdLst);
        wrapper.lambda().eq(ObjectUtil.isNotEmpty(param.getDepotId()), DepotTruckBook::getDepotId, param.getDepotId());
        wrapper.lambda().like(Strings.isNotBlank(param.getRepayOrderNo()), DepotTruckBook::getRepayOrderNo, param.getRepayOrderNo());
        wrapper.lambda().like(Strings.isNotBlank(param.getTruckBookId()), DepotTruckBook::getTruckBookId, param.getTruckBookId());
        wrapper.lambda().eq(ObjectUtil.isNotEmpty(param.getDepotBizType()), DepotTruckBook::getDepotBizType, param.getDepotBizType());
        wrapper.and(Strings.isNotEmpty(param.getLicensePlate()), w ->
                w.lambda().like(DepotTruckBook::getLicensePlate, param.getLicensePlate())
                        .or().like(DepotTruckBook::getLicensePlateBack, param.getLicensePlate()));
        if (ObjectUtil.isNotEmpty(param.getDriverName()))
            wrapper.lambda().like(DepotTruckBook::getDriverName, param.getDriverName());
        if (ObjectUtil.isNotEmpty(param.getDriverMobile()))
            wrapper.lambda().like(DepotTruckBook::getDriverMobile, param.getDriverMobile());
        if (ObjectUtil.isNotEmpty(param.getDriverTravel()))
            wrapper.lambda().like(DepotTruckBook::getDriverTravel, param.getDriverTravel());
        if (ObjectUtil.isNotEmpty(param.getDriverLicense()))
            wrapper.lambda().like(DepotTruckBook::getDriverLicense, param.getDriverLicense());
        wrapper.lambda().like(Strings.isNotBlank(param.getKeeperCitizenId()), DepotTruckBook::getKeeperCitizenId, param.getKeeperCitizenId());
        if (ObjectUtil.isNotEmpty(param.getCompanyName()))
            wrapper.lambda().like(DepotTruckBook::getCompanyName, param.getCompanyName());
        if (ObjectUtil.isNotEmpty(param.getCompanySalesmanName()))
            wrapper.lambda().like(DepotTruckBook::getCompanySalesmanName, param.getCompanySalesmanName());
        if (ObjectUtil.isNotEmpty(param.getCompanySalesmanMobile()))
            wrapper.lambda().like(DepotTruckBook::getCompanySalesmanMobile, param.getCompanySalesmanMobile());
        if (ObjectUtil.isNotEmpty(param.getGrainGroup()))
            wrapper.lambda().eq(DepotTruckBook::getGrainGroup, param.getGrainGroup());
        if (ObjectUtil.isNotEmpty(param.getGrainType()))
            wrapper.lambda().eq(DepotTruckBook::getGrainType, param.getGrainType());
        if (ObjectUtil.isNotEmpty(param.getPayeeName()))
            wrapper.lambda().like(DepotTruckBook::getPayeeName, param.getPayeeName());
        if (ObjectUtil.isNotEmpty(param.getPayeeMobile()))
            wrapper.lambda().like(DepotTruckBook::getPayeeMobile, param.getPayeeMobile());
        if (ObjectUtil.isNotEmpty(param.getPayeeBank()))
            wrapper.lambda().like(DepotTruckBook::getPayeeBank, param.getPayeeBank());
        if (ObjectUtil.isNotEmpty(param.getPayeeBankBillNo()))
            wrapper.lambda().like(DepotTruckBook::getPayeeBankBillNo, param.getPayeeBankBillNo());
        wrapper.lambda().eq(Strings.isNotEmpty(param.getBookState()), DepotTruckBook::getBookState, param.getBookState());
        wrapper.lambda().eq(Strings.isNotBlank(param.getDepotOpApprovalState()), DepotTruckBook::getDepotOpApprovalState, param.getDepotOpApprovalState());
        wrapper.lambda().eq(Strings.isNotBlank(param.getBizFlowName()), DepotTruckBook::getBizFlowName, param.getBizFlowName());
        wrapper.lambda().in(CollUtil.isNotEmpty(param.getBizFlowNameLst()), DepotTruckBook::getBizFlowName, param.getBizFlowNameLst());
        wrapper.lambda().isNull(param.getBizFlowNameNullFlag(), DepotTruckBook::getBizFlowName);
        wrapper.lambda().eq(Strings.isNotBlank(param.getBizFlowState()), DepotTruckBook::getBizFlowState, param.getBizFlowState());
        if (ObjectUtil.isNotEmpty(param.getStartCreateTime()) && ObjectUtil.isNotEmpty(param.getEndCreateTime()))
            wrapper.lambda().between(DepotTruckBook::getCreateTime, param.getStartCreateTime(), param.getEndCreateTime());
        if (ObjectUtil.isAllNotEmpty(param.getSortField(), param.getSortOrder())) {
            CommonSortOrderEnum.validate(param.getSortOrder());
            wrapper.orderBy(true, param.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
                    StrUtil.toUnderlineCase(param.getSortField()));
        } else {
            wrapper.lambda().orderByDesc(DepotTruckBook::getId);
        }
    }

    /**
     * 获取车辆预约唯一
     *
     * @author xiang
     * @date 2023/09/13 09:21
     */
    public DepotTruckBook getOneByBookId(String bookId) {
        List<DepotTruckBook> books = list(new LambdaQueryWrapper<>(new DepotTruckBook(bookId)));
        return books.isEmpty() ? null : books.get(0);
    }

    /**
     * 获取车辆预约唯一
     *
     * @author xiang
     * @date 2023/09/13 09:21
     */
    public DepotTruckBook oneByBookLicensePlate(String depotId, String licensePlate, String bookState) {
        LambdaQueryWrapper<DepotTruckBook> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DepotTruckBook::getDepotId, depotId);
        wrapper.eq(DepotTruckBook::getLicensePlate, licensePlate);
        wrapper.eq(DepotTruckBook::getBookState, bookState);
        List<DepotTruckBook> books = list(wrapper);
        return books.isEmpty() ? null : books.get(0);
    }

    /**
     * 获取车辆票单信息
     *
     * @author xiang
     * @date 2023/09/13 09:21
     */
    public DepotTruckBookBillVo bill(String bookId) {
        DepotTruckBookBillVo vo = new DepotTruckBookBillVo();
        try {
            if (Strings.isBlank(bookId)) return vo;
            DepotTruckBook one = getOneByBookId(bookId);
            if (one == null) return vo;
            BeanUtil.copyProperties(one, vo);
            //水份
            DepotSampling sampling = samplingService.getOneByBookId(bookId);
            if (sampling != null) {
                if (BigDecimalUtil.isNotNullOrEqZero(sampling.getSamplingShuiFen()))
                    vo.setSamplingShuiFen(sampling.getSamplingShuiFen());
                if (BigDecimalUtil.isNullOrEqZero(vo.getSamplingPrice()))
                    vo.setSamplingPrice(sampling.getSamplingPrice());
            }
            DepotTruckLade lade = depotTruckLadeService.getOneByBookId(bookId);
            if (lade != null)
                vo.setShedName(lade.getShedName());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return vo;
    }

    /**
     * 获取车辆预约待入场
     *
     * @author xiang
     * @date 2023/09/13 09:21
     */
    public DepotTruckBook onWait(String depotId, String licensePlate) {
        if (Strings.isBlank(depotId) || Strings.isBlank(licensePlate))
            throw new CommonException(500, "缺少参数");
        LambdaQueryWrapper<DepotTruckBook> wrapper = new LambdaQueryWrapper<>(new DepotTruckBook(depotId, null, BizStr.STATE_APPROVAL_Y, BizStr.BOOK_RIGHT));
        wrapper.eq(DepotTruckBook::getLicensePlate, licensePlate);
        wrapper.eq(DepotTruckBook::getBizFlowState, BizStr.STATE_TRUCK_Y);
        wrapper.isNull(DepotTruckBook::getBizFlowName);
        List<DepotTruckBook> books = list(wrapper);
        if (books.size() > 1)
            throw new CommonException(500, "有多条预约记录");
        return books.size() == 1 ? books.get(0) : null;
    }

    /**
     * 获取待处理
     *
     * @author xiang
     * @date 2023/09/13 09:21
     */
    public List<DepotTruckBook> waitProcess(List<String> depotIdLst) {
        LambdaQueryWrapper<DepotTruckBook> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(CollUtil.isNotEmpty(depotIdLst), DepotTruckBook::getDepotId, depotIdLst);
        wrapper.eq(DepotTruckBook::getBookState, BizStr.BOOK_RIGHT);
        wrapper.eq(DepotTruckBook::getDepotOpApprovalState, BizStr.STATE_APPROVAL_N);
        return list(wrapper.orderByDesc(DepotTruckBook::getId));
    }

    /**
     * 添加车辆预约表
     *
     * @author xiang
     * @date 2023/09/13 09:21
     */
    public void add(DepotTruckBookAddParam param) {
        //检查粮食种类
        grainInfoPriceService.checkGrainGroup(param.getDepotId(), param.getGrainGroup());
        //检查前车牌
        if (Strings.isNotBlank(param.getLicensePlate()) && !Validator.isPlateNumber(param.getLicensePlate()))
            throw new CommonException(BizExceptionEnum.ERROR13006.getMessage() + param.getLicensePlate());
        //检查后车牌
        if (Strings.isNotBlank(param.getLicensePlateBack()) && !Validator.isPlateNumber(param.getLicensePlateBack()))
            throw new CommonException(BizExceptionEnum.ERROR13007.getMessage() + param.getLicensePlateBack());
        DepotTruckBook book = BeanUtil.toBean(param, DepotTruckBook.class);
        //正常预约检查
        if (!lst(new DepotTruckBook(book.getDepotId(), book.getLicensePlate(), BizStr.BOOK_RIGHT, null, null)).isEmpty())
            throw new CommonException(BizExceptionEnum.ERROR13002.getMessage());
        if (BizStr.KU_CHU.equals(book.getDepotBizType())) {
            //还款预约
            List<DepotRepayOrder> repayOrders = repayOrderService.lst(new DepotRepayOrderPageParam(book.getDepotId(), book.getLicensePlate(), book.getGrainGroup(), BizStr.STATE_APPROVAL_Y, BizStr.BOOK_ON));
            if (repayOrders.isEmpty())
                throw new CommonException(BizExceptionEnum.ERROR13001.getMessage());
            //最早一条
            DepotRepayOrder repayOrder = repayOrders.get(repayOrders.size() - 1);
            book.setRepayOrderNo(repayOrder.getRepayOrderNo());
            book.setSamplingPrice(repayOrder.getRepayPrice());
        }
        book.setBizFlowTime(DatesUtil.forDateTime());
        //行驶证 驾驶证
        if (Strings.isNotBlank(book.getDriverTravel()) && book.getDriverTravel().length() > 19)
            book.setDriverTravel(devFileApi.storageFileWithReturnIdLocal(MultipartFileUtils.base64ToMultipart(book.getDriverTravel())));
        if (Strings.isNotBlank(book.getDriverLicense()) && book.getDriverLicense().length() > 19)
            book.setDriverLicense(devFileApi.storageFileWithReturnIdLocal(MultipartFileUtils.base64ToMultipart(book.getDriverLicense())));
        if (Strings.isNotEmpty(book.getDriverTravel()) && book.getDriverTravel().length() == 19)
            book.setDriverTravel(devFileApi.storageFilePathReturnUrlById(book.getDriverTravel()));
        if (Strings.isNotEmpty(book.getDriverLicense()) && book.getDriverLicense().length() == 19)
            book.setDriverLicense(devFileApi.storageFilePathReturnUrlById(book.getDriverLicense()));
        this.save(book);
    }

    /**
     * 一级审批
     *
     * @author xiang
     * @date 2023/09/13 09:21
     */
    public void depotOpApproval(DepotTruckBookApprovalParam param) {
        DepotTruckBook book = this.queryEntity(param.getId());
        //未通过
        if ("不通过".equals(param.getDepotOpApprovalState()) || BizStr.STATE_APPROVAL_G.equals(param.getDepotOpApprovalState())) {
            book.setDepotOpApprovalState(BizStr.STATE_APPROVAL_G);
            book.setBizFlowState(BizStr.STATE_TRUCK_N);
            book.setBookState(BizStr.STATE_REPAY_Y);
        }
        //通过
        else {
            book.setDepotOpApprovalState(BizStr.STATE_APPROVAL_Y);
            book.setBizFlowState(BizStr.STATE_TRUCK_Y);
            //默认干粮价格
            if (BizStr.KU_RU.equals(book.getDepotBizType()))
                book.setSamplingPrice(depotGrainInfoPriceService.getPrice(book.getDepotId(), book.getGrainGroup()).getDryPrice());
        }
        book.setDepotOpApprovalTime(DatesUtil.forDateTime());
        book.setDepotOpApprovalMsg(param.getDepotOpApprovalMsg());
        updateById(book);
    }

    /**
     * 编辑车辆预约表
     *
     * @author xiang
     * @date 2023/09/13 09:21
     */
    public void edit(DepotTruckBookEditParam param) {
        DepotTruckBook book = this.queryEntity(param.getId());
        BeanUtil.copyProperties(param, book);
        this.updateById(book);
    }

    /**
     * 删除车辆预约表
     *
     * @author xiang
     * @date 2023/09/13 09:21
     */
    @Transactional(rollbackFor = Exception.class)
    public void delete(List<DepotTruckBookIdParam> depotTruckBookIdParamList) {
        // 执行删除
        this.removeBatchByIds(CollStreamUtil.toList(depotTruckBookIdParamList, DepotTruckBookIdParam::getId));
    }

    /**
     * 获取车辆预约表详情
     *
     * @author xiang
     * @date 2023/09/13 09:21
     */
    public DepotTruckBook detail(DepotTruckBook param) {
        if (ArrayUtil.isAllEmpty(param.getId(), param.getTruckBookId())) return null;
        DepotTruckBook book = new DepotTruckBook();
        if (Strings.isNotEmpty(param.getId()))
            book = this.queryEntity(param.getId());
        else if (Strings.isNotEmpty(param.getTruckBookId()))
            book = this.getOneByBookId(param.getTruckBookId());
        book.setDepotGrainName(depotGrainService.getNameByDepotId(book.getDepotId()));
        book.setDriverTravel(depotGrainInfoFileService.getFullUrl(book.getDriverTravel()));
        book.setDriverLicense(depotGrainInfoFileService.getFullUrl(book.getDriverLicense()));
        return book;
    }

    /**
     * 获取车辆预约表详情
     *
     * @author xiang
     * @date 2023/09/13 09:21
     */
    public DepotTruckBook detail(DepotTruckBookIdParam depotTruckBookIdParam) {
        DepotTruckBook book = this.queryEntity(depotTruckBookIdParam.getId());
        book.setDepotGrainName(depotGrainService.getNameByDepotId(book.getDepotId()));
        return book;
    }

    /**
     * 获取车辆预约表详情
     *
     * @author xiang
     * @date 2023/09/13 09:21
     **/
    public DepotTruckBook queryEntity(String id) {
        DepotTruckBook depotTruckBook = this.getById(id);
        if (ObjectUtil.isEmpty(depotTruckBook)) {
            throw new CommonException("车辆预约表不存在，id值为：{}", id);
        }
        return depotTruckBook;
    }

    /**
     * 车辆预约过期作废
     * 第四天超时
     *
     * @author xiang
     * @date 2023/09/13 09:21
     **/
    public void bookStateOver(String dateTime) {
        Date date = DatesUtil.addDay(DateUtil.beginOfDay(new Date()), -3);
        List<DepotTruckBook> lst = lst(new DepotTruckBook(null, null, BizStr.STATE_APPROVAL_N, BizStr.BOOK_RIGHT));
        List<String> upIdLst = lst.stream().filter(one -> one.getCreateTime().compareTo(date) < 1).map(DepotTruckBook::getId).collect(Collectors.toList());
        if (upIdLst.size() == 0) return;
        LambdaUpdateWrapper<DepotTruckBook> wrapper = new LambdaUpdateWrapper<>();
        wrapper.in(DepotTruckBook::getId, upIdLst);
        wrapper.set(DepotTruckBook::getBookState, "超时作废");
        wrapper.set(DepotTruckBook::getDepotOpApprovalState, BizStr.STATE_APPROVAL_G);
        wrapper.set(DepotTruckBook::getDepotOpApprovalMsg, "超时3天，自动未通过");
        wrapper.set(DepotTruckBook::getDepotOpApprovalTime, dateTime);
        update(wrapper);
    }

    /**
     * 还款车辆关单
     *
     * @author xiang
     * @date 2023/09/13 09:21
     */
    @Transactional(rollbackFor = Exception.class)
    public List<String> offRepayOrder(String repayOrderNo) {
        List<DepotTruckBook> books = lst(new DepotTruckBook(null, repayOrderNo, null, BizStr.BOOK_RIGHT));
        //未入场车辆自动结束
        List<String> bookIds = books.stream().filter(one -> one.getBizFlowName() == null).map(DepotTruckBook::getId).collect(Collectors.toList());
        if (!bookIds.isEmpty()) {
            LambdaUpdateWrapper<DepotTruckBook> wrapper = new LambdaUpdateWrapper<>();
            wrapper.in(DepotTruckBook::getId, bookIds);
            wrapper.set(DepotTruckBook::getBookState, BizStr.STATE_REPAY_Y);
            wrapper.set(DepotTruckBook::getBizFlowState, BizStr.STATE_TRUCK_N);
            update(wrapper);
        }
        //场内车辆自动发送离场超时报警
        for (DepotTruckBook book : books) {
            if (book.getBizFlowState() == null) continue;
            depotAlarmService.depotWorkAlarmAdd(new DepotCloudAlarmAddParam(book.getTruckBookId(), "24", "还款单已关闭，场内还款预约车辆未及时离场!"));
        }
        return books.stream().map(DepotTruckBook::getTruckBookId).collect(Collectors.toList());
    }

    /**
     * 车辆进程更新
     *
     * @author xiang
     * @date 2023/09/13 09:21
     */
    @Transactional(rollbackFor = Exception.class)
    public DepotTruckBook upTruckBookFlow(String bookId, String flowName, String flowTime) {
        DepotTruckBook book = this.getOneByBookId(bookId);
        upTruckBookFlow(book, flowName, flowTime);
        return book;
    }

    @Transactional(rollbackFor = Exception.class)
    public DepotTruckBook upTruckBookFlow(DepotTruckBook book, String flowName, String flowTime) {
        return upTruckBookFlow(book, flowName, flowTime, null);
    }

    /**
     * 车辆进程更新
     *
     * @param onLade 卸货区开关
     * @author xiang
     * @date 2023/09/13 09:21
     */
    @Transactional(rollbackFor = Exception.class)
    public DepotTruckBook upTruckBookFlow(DepotTruckBook book, String flowName, String flowTime, String onLade) {
        if (book == null) return new DepotTruckBook();
        String bookId = book.getTruckBookId();
        if (Objects.equals(flowName, book.getBizFlowName())) return book;
        //车辆进程
        truckAdmitFlowService.add(BeanUtil.toBean(book, DepotTruckAdmitFlowAddParam.class));
        //已入场
        if (BizStr.FLOW_RU_CHANG.equals(flowName)) {
            //默认价格
            book.setSamplingPrice(grainInfoPriceService.getPrice(book.getDepotId(), book.getGrainGroup()).getDryPrice());
            //添加待扦样
            samplingService.addAuto(book);
        }
        //已至扦样区
        else if (BizStr.FLOW_QIAN_YANG_IN.equals(flowName)) {
            //扦样判断
            if (!BizStr.FLOW_RU_CHANG.equals(book.getBizFlowName()))
                flowName = book.getBizFlowName();
            //扦样判断
            if (BizStr.FLOW_QIAN_YANG_IN.equals(book.getBizFlowName())) {
                DepotSampling sampling = samplingService.getOneByBookId(bookId);
                if (Strings.isNotBlank(sampling.getTruckOutTime()))
                    flowName = BizStr.FLOW_QIAN_YANG_OUT;
            }
        }
        //完成扦样
        else if (BizStr.FLOW_QIAN_YANG_FINISH.equals(flowName)) {
            //扦样判断
            if (BizStr.FLOW_QIAN_YANG_IN.equals(book.getBizFlowName())) {
                DepotSampling sampling = samplingService.getOneByBookId(bookId);
                if (Strings.isNotBlank(sampling.getTruckOutTime()))
                    flowName = BizStr.FLOW_QIAN_YANG_OUT;
            }
        }
        //扦样驳回
        else if (BizStr.FLOW_QIAN_YANG_REJECT.equals(flowName)) {
            book.setBizFlowState(BizStr.STATE_TRUCK_G);
        }
        //离开扦样区
        else if (BizStr.FLOW_QIAN_YANG_OUT.equals(flowName)) {
            //扦样判断
            if (!BizStr.FLOW_QIAN_YANG_IN.equals(book.getBizFlowName())
                    && !BizStr.FLOW_QIAN_YANG_FINISH.equals(book.getBizFlowName()))
                flowName = book.getBizFlowName();
        }
        //完成一次过磅
        else if (BizStr.FLOW_GUO_BANG_ONE.equals(flowName)) {
            //价格
            if (BizStr.KU_RU.equals(book.getDepotBizType()) && BigDecimalUtil.isNullOrEqZero(book.getSamplingPrice())) {
                DepotGrainInfoPrice infoPrice = grainInfoPriceService.oneByGrainGroup(book.getDepotId(), book.getGrainGroup());
                book.setSamplingPrice(infoPrice.getDryPrice());
            }
            //装卸区开关判断
            if (BizStr.KU_RU.equals(book.getDepotBizType()) && !BizStr.STATE_ON.equals(onLade))
                flowName = BizStr.FLOW_LADE_FINISH;
        }
        //完成装卸货
        else if (BizStr.FLOW_LADE_FINISH.equals(flowName)) {
        }
        //完成二次过磅
        else if (BizStr.FLOW_GUO_BANG_TWO.equals(flowName)) {
        }
        //已出场
        else if (BizStr.FLOW_CHU_CHANG.equals(flowName)) {
            //驳回离场
            if (!BizStr.STATE_TRUCK_G.equals(book.getBizFlowState())) {
                DepotTruckWeighDouble weighDouble = truckWeighDoubleService.getOneByBookId(bookId);
                //入库
                if (BizStr.KU_RU.equals(book.getDepotBizType())) {
                    //扦样
                    DepotSampling sampling = samplingService.getOneByBookId(bookId);
                    if (sampling == null)
                        sampling = new DepotSampling();

                    //添加入库
                    DepotWorkAddParam addParam = new DepotWorkAddParam(book, weighDouble, sampling);
                    addParam.setOrderAmount(addParam.getDepotPrice().multiply(addParam.getDepotTonCount()).setScale(2, BigDecimal.ROUND_HALF_UP));
                    DepotGrainInfoPrice infoPrice = grainInfoPriceService.oneByGrainGroup(weighDouble.getDepotId(), weighDouble.getGrainGroup());
                    addParam.setDampRatio(infoPrice.getDampRatio());
                    addParam.setCanonRatio(infoPrice.getCanonRatio());

                    //潮粮水份-标准干粮水份
                    BigDecimal b1 = BigDecimalUtil.addVal(sampling.getSamplingShuiFen(), infoPrice.getCanonRatio().negate()).movePointLeft(2);
                    if (b1.doubleValue() < 0.01)
                        b1 = new BigDecimal("0.01");
                    //1-折干比*
                    BigDecimal b2 = BigDecimalUtil.addVal(infoPrice.getDampRatio().multiply(b1).negate(), BigDecimal.ONE);
                    //干粮数量=潮粮数量*（1-折干比*（潮粮水份-标准干粮水份））
                    addParam.setDryTonCount(addParam.getDepotTonCount().multiply(b2).setScale(4, BigDecimal.ROUND_HALF_UP));
                    //干粮价格
                    if (BigDecimalUtil.isNullOrEqZero(addParam.getDryTonCount()))
                        addParam.setDryPrice(addParam.getDepotPrice().divide(b2, 2, BigDecimal.ROUND_HALF_UP));
                    else
                        addParam.setDryPrice(addParam.getOrderAmount().divide(addParam.getDryTonCount(), 2, BigDecimal.ROUND_HALF_UP));
                    depotWorkService.add(addParam);
                    //种类添加入库数量
                    grainInfoPriceService.inInventory(infoPrice.getId(), addParam.getDepotTonCount(), addParam.getOrderAmount(), addParam.getDryTonCount());
                }
                //出库
                else if (BizStr.KU_CHU.equals(book.getDepotBizType())) {
                    //更新还款单
                    DepotRepayOrder repayOrder = repayOrderService.editRepayTonReal(book.getRepayOrderNo(), weighDouble.getNetWeight().movePointLeft(3));
                    //添加出库
                    DepotWork work = depotWorkService.add(new DepotWorkAddParam(book, repayOrder.getRepayPrice(), weighDouble));
                    //种类添加出库数量
                    grainInfoPriceService.outInventory(book.getDepotId(), book.getGrainGroup(), work.getDepotTonCount(), work.getOrderAmount());
                }
                if ("人工补单".equals(weighDouble.getBillGroup()))
                    flowName = "已补单";
            }
            book.setBookState("已结束");
            book.setBizFlowState(BizStr.STATE_TRUCK_N);
        }
        book.setBizFlowName(flowName);
        book.setBizFlowTime(flowTime);
        this.updateById(book);
        return book;
    }

    /**
     * 车辆异常处理
     *
     * @author xiang
     * @date 2023/09/13 09:21
     */
    public void processTo(String bookId, String flowState) {
        if (ArrayUtil.hasEmpty(bookId, flowState)) return;
        DepotTruckBook book = getOneByBookId(bookId);
        if (book == null || Objects.equals(book.getBizFlowState(), flowState)) return;
        //驳回离场和已出场状态不可改
        if (BizStr.STATE_TRUCK_G.equals(book.getBizFlowState()) || BizStr.FLOW_CHU_CHANG.equals(book.getBizFlowName())) return;
        LambdaUpdateWrapper<DepotTruckBook> wrapper = new LambdaUpdateWrapper<>(new DepotTruckBook(bookId));
        wrapper.set(DepotTruckBook::getBizFlowState, flowState);
        update(wrapper);
    }

    /**
     * 车牌待入场校验
     *
     * @author xiang
     * @date 2023/09/13 09:21
     */
    public Object check_dai_ru_chang(DepotTruckBookLicensePlateCheckParam param) {
        if (ArrayUtil.hasEmpty(param.getDepotId(), param.getLicensePlate(), param.getBookDate()))
            return false;
        List<DepotTruckBook> lst = lst(new DepotTruckBook(param.getDepotId(), param.getLicensePlate(), BizStr.BOOK_RIGHT, BizStr.STATE_APPROVAL_Y, BizStr.STATE_TRUCK_Y));
        return lst.size() == 1 && Strings.isBlank(lst.get(0).getBizFlowName());
    }

    /**
     * 车牌状态校验
     *
     * @param bookId       预约号
     * @param bizFlowName  进程
     * @param bizFlowState 通行状态
     * @author xiang
     * @date 2023/09/13 09:21
     */
    public void check_state(String bookId, String bizFlowName, String bizFlowState) {
        DepotTruckBook book = getOneByBookId(bookId);
        if (book == null)
            throw new CommonException(String.format("没有查到预约记录。预约号:%s", bookId));
        if (Strings.isNotBlank(bizFlowName) && !Objects.equals(book.getBizFlowName(), bizFlowName))
            throw new CommonException(String.format("车辆进程异常。车牌:%s;当前进程:%s", book.getLicensePlate(), book.getBizFlowName()));
        if (Strings.isNotBlank(bizFlowState) && !Objects.equals(book.getBizFlowState(), bizFlowState))
            throw new CommonException(String.format("车辆通行异常。车牌:%s;通行状态:%s", book.getLicensePlate(), book.getBizFlowState()));
    }

}
