package org.springblade.modules.app.manager;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wn.common.perfmonitor.annotation.ServiceTimeLog;
import com.wn.common.validator.Validator;
import org.springblade.core.redis.cache.BladeRedis;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.modules.app.client.ZmtClientService;
import org.springblade.modules.app.common.dto.*;
import org.springblade.modules.app.common.enums.*;
import org.springblade.modules.app.common.query.*;
import org.springblade.modules.app.common.vo.*;
import org.springblade.modules.app.constant.Constants;
import org.springblade.modules.app.constant.ErrorCode;
import org.springblade.modules.app.entity.ApiLog;
import org.springblade.modules.app.entity.UserDO;
import org.springblade.modules.app.entity.WaybillDO;
import org.springblade.modules.app.service.*;
import org.springblade.modules.app.utils.UserUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.springblade.modules.app.vo.CarPush;
import org.springblade.modules.app.vo.CarPushVo;
import org.springblade.modules.app.vo.CarVo;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Component
@RefreshScope
public class WaybillManager {

    @Autowired
    private BladeRedis bladeRedis;
    @Autowired
    private UserUtils userUtils;
    @Autowired
    private IWaybillService waybillService;
    @Autowired
    private ITransportService transportService;
    @Autowired
    private UserManager userManager;
    @Autowired
    private ZmtClientService zmtClientService;
    @Autowired
    private IContractService contractService;
    @Autowired
    private IAppUserService userService;
    @Autowired
    private IPictureInfoService pictureInfoService;
    @Autowired
    private IVerifyStationService verifyStationService;
    @Autowired
    private IApplicationInfoService applicationInfoService;
    @Autowired
    private MessageLoggingManager messageLoggingManager;
    @Autowired
    private ISlaughterBuyerRelationService slaughterBuyerRelationService;
    private final String HEAD = this.getClass().getSimpleName() + ":";


    public List<WaybillListVO> getWaybillList(WaybillClientQuery waybillClientQuery) {
        UserDTO userDTO = userUtils.getUser(waybillClientQuery.getToken());
        log.info(HEAD + "获取调运单列表, 当前用户id:{}", userDTO.getId());
        UserTypeEnum type = UserTypeEnum.findByCode(userDTO.getType());
        WaybillQuery query = new WaybillQuery();
        switch (type) {
            case FARM:
                query.setSalerId(userDTO.getId());
                break;
            case SLAUGHTER:
                query.setBuyerId(userDTO.getId());
                break;
            case SLAUGHTER_HOUSE:
                query.setSlaughterHouseId(userDTO.getId());
                break;
            case AGENT:
                query.setAgentId(userDTO.getId());
                break;
            default:
                Validator.isTrue(false, ErrorCode.NO_POWER_GET);
                break;
        }
        List<Integer> stateList = new ArrayList<>();
        if (waybillClientQuery == null || waybillClientQuery.getState() == null || waybillClientQuery.getState() == WaybillClientStateEnum.Going.getCode()) {
            stateList.add(WaybillStateEnum.UNCHECK.getCode());
            stateList.add(WaybillStateEnum.PASS.getCode());
            stateList.add(WaybillStateEnum.WAYBILL_SLAUGHTER.getCode());
        } else if (waybillClientQuery.getState() == WaybillClientStateEnum.FINISH.getCode()) {
            stateList.add(WaybillStateEnum.FINISH.getCode());
        } else if (waybillClientQuery.getState() == WaybillClientStateEnum.REJECT.getCode()) {
            stateList.add(WaybillStateEnum.REJECT.getCode());
            stateList.add(WaybillStateEnum.UNPASS.getCode());
            stateList.add(WaybillStateEnum.WAYBILL_SLAUGHTER_REJECT.getCode());
        } else if (waybillClientQuery.getState() == WaybillClientStateEnum.ALL.getCode()) {
            stateList = null;
        }
        query.setStateList(stateList);
        List<WaybillListVO> waybillListVOS = waybillService.listWaybill(query);
        if (CollectionUtils.isNotEmpty(waybillListVOS)) {
            ApplicationQuery applicationQuery = new ApplicationQuery();
            for (WaybillListVO waybillListVO : waybillListVOS) {
                WaybillDTO waybill = waybillService.getWaybillById(waybillListVO.getId());
                applicationQuery.setLinkId(waybillListVO.getId());
                applicationQuery.setType(ApplicationTypeEnum.WAYBILL.getCode());
                ApplicationInfoDTO applicationInfoDTO = applicationInfoService.getApplicationInfoByQuery(applicationQuery);
                if (ObjectUtils.isEmpty(applicationInfoDTO) && waybill.getSlaughterHouseId() != null && waybill.getSlaughterHouseId() != 0) {
                    applicationQuery.setType(ApplicationTypeEnum.SLAUGHTER.getCode());
                    applicationInfoDTO = applicationInfoService.getApplicationInfoByQuery(applicationQuery);
                }
//                Validator.notNull(applicationInfoDTO, ErrorCode.APPLY_NULL);
                waybillListVO.setIfCreator(userDTO.getId().equals(applicationInfoDTO.getSubmitUserId()) ? YesNoEnum.YES.getCode() : YesNoEnum.NO.getCode());
            }
        }
        return waybillListVOS;
    }

    public List<WaybillListVO> getbillList(WaybillClientQuery waybillClientQuery) {
        UserDTO userDTO = userUtils.getUser(waybillClientQuery.getToken());
        UserTypeEnum type = UserTypeEnum.findByCode(userDTO.getType());
        WaybillQuery query = new WaybillQuery();
        switch (type) {
            case FARM:
                query.setSalerId(userDTO.getId());
                break;
            case SLAUGHTER:
                query.setBuyerId(userDTO.getId());
                break;
            case SLAUGHTER_HOUSE:
                query.setSlaughterHouseId(userDTO.getId());
                break;
            case AGENT:
                query.setAgentId(userDTO.getId());
                break;
            default:
                Validator.isTrue(false, ErrorCode.NO_POWER_GET);
                break;
        }
        List<Integer> stateList = new ArrayList<>();
        if (waybillClientQuery == null || waybillClientQuery.getState() == null || waybillClientQuery.getState() == WaybillClientStateEnum.Going.getCode()) {
            stateList.add(WaybillStateEnum.UNCHECK.getCode());
            stateList.add(WaybillStateEnum.PASS.getCode());
            stateList.add(WaybillStateEnum.WAYBILL_SLAUGHTER.getCode());
        } else if (waybillClientQuery.getState() == WaybillClientStateEnum.FINISH.getCode()) {
            stateList.add(WaybillStateEnum.FINISH.getCode());
        } else if (waybillClientQuery.getState() == WaybillClientStateEnum.REJECT.getCode()) {
            stateList.add(WaybillStateEnum.REJECT.getCode());
            stateList.add(WaybillStateEnum.UNPASS.getCode());
            stateList.add(WaybillStateEnum.WAYBILL_SLAUGHTER_REJECT.getCode());
        } else if (waybillClientQuery.getState() == WaybillClientStateEnum.ALL.getCode()) {
            stateList = null;
        }
        query.setStateList(stateList);
        List<WaybillListVO> waybillListVOS = waybillService.listWaybill(query);
        if (CollectionUtils.isNotEmpty(waybillListVOS)) {
            ApplicationQuery applicationQuery = new ApplicationQuery();
            for (WaybillListVO waybillListVO : waybillListVOS) {
                WaybillDTO waybill = waybillService.getWaybillById(waybillListVO.getId());
                applicationQuery.setLinkId(waybillListVO.getId());
                applicationQuery.setType(ApplicationTypeEnum.WAYBILL.getCode());
                ApplicationInfoDTO applicationInfoDTO = applicationInfoService.getApplicationInfoByQuery(applicationQuery);
                if (ObjectUtils.isEmpty(applicationInfoDTO) && waybill.getSlaughterHouseId() != null && waybill.getSlaughterHouseId() != 0) {
                    applicationQuery.setType(ApplicationTypeEnum.SLAUGHTER.getCode());
                    applicationInfoDTO = applicationInfoService.getApplicationInfoByQuery(applicationQuery);
                }
                waybillListVO.setType(1);
//                Validator.notNull(applicationInfoDTO, ErrorCode.APPLY_NULL);
                waybillListVO.setIfCreator(userDTO.getId().equals(applicationInfoDTO.getSubmitUserId()) ? YesNoEnum.YES.getCode() : YesNoEnum.NO.getCode());
            }
        }


        TransportQuery transportQuery = new TransportQuery();
        stateList = new ArrayList<>();
        if (waybillClientQuery == null || waybillClientQuery.getState() == null || waybillClientQuery.getState() == WaybillClientStateEnum.Going.getCode()) {
            stateList.add(WaybillStateEnum.UNCHECK.getCode());
            stateList.add(WaybillStateEnum.PASS.getCode());
            stateList.add(WaybillStateEnum.TRANSPORT.getCode());
//            transportQuery.setNeAcceptState(ApplicationStateEnum.REJECT.getCode());
        } else if (waybillClientQuery.getState() == WaybillClientStateEnum.FINISH.getCode()) {
            stateList.add(WaybillStateEnum.FINISH.getCode());
        } else if (waybillClientQuery.getState() == WaybillClientStateEnum.REJECT.getCode()) {
            stateList.add(WaybillStateEnum.REJECT.getCode());
            stateList.add(WaybillStateEnum.UNPASS.getCode());
//            transportQuery.setAcceptState(ApplicationStateEnum.REJECT.getCode());
//            transportQuery.setIsList(YesNoEnum.YES.getCode());
        } else if (waybillClientQuery.getState() == WaybillClientStateEnum.ALL.getCode()) {
            stateList = null;
        }
        transportQuery.setStateList(stateList);

        if (userDTO.getType().equals(UserTypeEnum.SLAUGHTER.getCode())) {
            transportQuery.setBuyerId(userDTO.getId());
        } else if (userDTO.getType().equals(UserTypeEnum.FARM.getCode())) {
            transportQuery.setSalerId(userDTO.getId());
        } else if (userDTO.getType().equals(UserTypeEnum.SLAUGHTER_HOUSE.getCode())) {
            transportQuery.setSlaughterHouseId(userDTO.getId());
        } else if (userDTO.getType().equals(UserTypeEnum.AGENT.getCode())) {
            transportQuery.setAgentId(userDTO.getId());
        } else if (userDTO.getType().equals(UserTypeEnum.DRIVER.getCode())) {
            transportQuery.setDriverId(userDTO.getId());
        } else {
            Validator.isTrue(false, ErrorCode.NO_POWER_GET);
        }
        List<WaybillListVO> waybillListVOList = new ArrayList<>();
        List<TransportDTO> transportDTOS = transportService.listTransport(transportQuery);
        if (CollectionUtils.isNotEmpty(transportDTOS)) {
            for (TransportDTO transportDTO : transportDTOS) {
                WaybillListVO waybillListVO = new WaybillListVO();
                waybillListVO.setState(transportDTO.getState());
//                if (transportDTO.getAcceptState() == ApplicationStateEnum.REJECT.getCode()) {
//                    waybillListVO.setState(WaybillStateEnum.REJECT.getCode());
//                }
                waybillListVO.setBillName(transportDTO.getWaybillName());
                waybillListVO.setCreatedTime(transportDTO.getCreatedTime());
                waybillListVO.setId(transportDTO.getId());
                waybillListVO.setType(2);
                waybillListVO.setTop(transportDTO.getTop());
                waybillListVO.setAcceptState(transportDTO.getAcceptState());
                waybillListVOList.add(waybillListVO);
            }
        }

        if (CollectionUtils.isNotEmpty(waybillListVOList)) {
            ApplicationQuery applicationQuery = new ApplicationQuery();
            applicationQuery.setType(ApplicationTypeEnum.TRANSPORT.getCode());
            for (WaybillListVO waybillListVO : waybillListVOList) {
                applicationQuery.setLinkId(waybillListVO.getId());
                ApplicationInfoDTO applicationInfoDTO = applicationInfoService.getApplicationInfoByQuery(applicationQuery);
                waybillListVO.setIfCreator(userDTO.getId().equals(applicationInfoDTO.getSubmitUserId()) ? YesNoEnum.YES.getCode() : YesNoEnum.NO.getCode());
            }
        }
        if (waybillListVOList.size() > 0) {
            waybillListVOS.addAll(waybillListVOList);
        }
        if (!StringUtil.isEmpty(waybillListVOS) && waybillListVOS.size() > 0) {
            waybillListVOS = waybillListVOS.stream().sorted(Comparator.comparing(WaybillListVO::getTop).reversed()).collect(Collectors.toList());
        }
        return waybillListVOS;
    }

    public WaybillDTO getWaybillDetail(Long waybillId, String token) {

        UserDTO userDTO = userUtils.getUser(token);
        WaybillDTO waybillDTO = waybillService.getWaybillById(waybillId);
        log.info(HEAD + "获取调运单详情, 当前用户id:{}, 请求参数:{}", userDTO.getId(), waybillId);
        TransportManager.checkWaybillPower(userDTO, waybillDTO);
        PictureQuery pictureQuery = new PictureQuery();
        pictureQuery.setLinkId(waybillDTO.getId());
        pictureQuery.setType(PictureTypeEnum.BLOOD_TEST.getCode());
        List<PictureInfoDTO> pictureInfoDTOList = pictureInfoService.listPictureInfo(pictureQuery);
        if (CollectionUtils.isNotEmpty(pictureInfoDTOList)) {
            waybillDTO.setBloodTestList(pictureInfoDTOList.stream().map(PictureInfoDTO::getUrl).collect(Collectors.toList()));
        }
        if (WaybillStateEnum.REJECT.getCode() == waybillDTO.getState()) {
            ApplicationQuery applicationQuery = new ApplicationQuery();
            applicationQuery.setType(ApplicationTypeEnum.WAYBILL.getCode());
            if (waybillDTO.getConfirmUserId() != null && waybillDTO.getConfirmUserId() != 0) {
                applicationQuery.setApplyUserId(waybillDTO.getConfirmUserId());
            }
            applicationQuery.setLinkId(waybillId);
            ApplicationInfoDTO applicationInfoByQuery = applicationInfoService.getApplicationInfoByQuery(applicationQuery);
//            Validator.notNull(applicationInfoByQuery, ErrorCode.APPLY_NULL);
            waybillDTO.setApplyType(UserTypeEnum.FARM.getCode());
            if (ApplicationStateEnum.UNCHECK.getCode() == applicationInfoByQuery.getState() && waybillDTO.getAgentUserId() != null && waybillDTO.getAgentUserId() != 0) {
                applicationQuery.setApplyUserId(waybillDTO.getAgentUserId());
                applicationInfoByQuery = applicationInfoService.getApplicationInfoByQuery(applicationQuery);
                Validator.notNull(applicationInfoByQuery, ErrorCode.APPLY_NULL);
                waybillDTO.setApplyType(UserTypeEnum.AGENT.getCode());
            }
//            Validator.isTrue(ApplicationStateEnum.REJECT.getCode() == applicationInfoByQuery.getState(), ErrorCode.APPLY_NULL);
            waybillDTO.setMessage(applicationInfoByQuery.getMessage());
        }
        if (WaybillStateEnum.UNPASS.getCode() == waybillDTO.getState()) {
            ApplicationQuery applicationQuery = new ApplicationQuery();
            applicationQuery.setType(ApplicationTypeEnum.WAYBILL_APPROVAL.getCode());
            applicationQuery.setLinkId(waybillId);
            ApplicationInfoDTO applicationInfoByQuery = applicationInfoService.getApplicationInfoByQuery(applicationQuery);
            Validator.isTrue(ApplicationStateEnum.REJECT.getCode() == applicationInfoByQuery.getState(), ErrorCode.APPLY_NULL);
            waybillDTO.setMessage(applicationInfoByQuery.getMessage());
            waybillDTO.setApplyType(UserTypeEnum.ANIMAL_BUREAU.getCode());
        }
        if (waybillDTO.getSlaughterHouseId() != null && waybillDTO.getSlaughterHouseId() != 0) {
            UserDTO slaughterHouse = userService.getUserById(waybillDTO.getSlaughterHouseId());
            waybillDTO.setSlaughterHouseName(slaughterHouse.getUserName());
        }
        waybillDTO.setZmtApplyUpdateInfo(null);
        return waybillDTO;
    }

    /**
     * 创建调运单
     *
     * @param waybillDTO
     * @return java.lang.String
     * @author FUXINSHENG
     * @date 2021/11/10 13:44
     * @describe 1、校验用户权限
     * 2、将调运单中的屠宰场信息初始化为用户关联的屠宰场信息，防止篡改
     * 3、校验养殖场与用户关联的屠宰场是否存在合同关系、且合同未过期
     * 4、校验经济人信息是否正确
     * 5、校验基本参数是否为空
     * 6、校验检疫站信息是否正确
     * 6、新增调运单
     * 7、新增调运单审批（养殖场+经纪人）信息
     */
    @ServiceTimeLog
    @Transactional(rollbackFor = Exception.class)
    public String createWaybill(WaybillDTO waybillDTO) {
        UserDTO userDTO = userUtils.getUser(waybillDTO.getToken());
        log.info(HEAD + "创建调运单, 当前用户id:{}, 请求参数:{}", userDTO.getId(), JSON.toJSONString(waybillDTO));
        UserDTO slaughterDTO = userDTO;
        Integer autoApply = 0;
        Validator.isTrue(userDTO.getType().equals(UserTypeEnum.SLAUGHTER.getCode())
                || userDTO.getType().equals(UserTypeEnum.SLAUGHTER_HOUSE.getCode()), ErrorCode.NO_POWER_GET);
        if (userDTO.getType().equals(UserTypeEnum.SLAUGHTER_HOUSE.getCode())) {
            slaughterDTO = userService.getUserById(waybillDTO.getBuyerUserId());
            SlaughterBuyerRelationDTO slaughterBuyerRelationDTO = slaughterBuyerRelationService.queryByHouseIdAndBuyerId(userDTO.getId(), waybillDTO.getBuyerUserId());
            Validator.isTrue(slaughterBuyerRelationDTO != null && slaughterBuyerRelationDTO.getState().intValue() == RelationStateEnum.BIND.getCode(), ErrorCode.RELATION_ISNULL);
            waybillDTO.setSlaughterHouseId(userDTO.getId());
            autoApply = slaughterBuyerRelationDTO.getIfAutoApply();
        }
        waybillDTO.setCompanyOrPeople(slaughterDTO.getZmtName());
        waybillDTO.setCompanyOrPeopleType(slaughterDTO.getZmtType());
        waybillDTO.setRecordUnitId(slaughterDTO.getZmtId());
        waybillDTO.setRecordPeopleId(slaughterDTO.getZmtUserId());
        waybillDTO.setRecordPeople(slaughterDTO.getZmtUserName());

        checkWaybill(waybillDTO, slaughterDTO);
        waybillDTO.setBillName(waybillDTO.getBuyerUserName() + "-" + waybillDTO.getSalerUserName() + "备案单");
        waybillDTO.setBillCode(RandomStringUtils.randomNumeric(16));
        boolean flag = userDTO.getType().equals(UserTypeEnum.SLAUGHTER_HOUSE.getCode()) && YesNoEnum.NO.getCode().equals(autoApply);
        if (flag) {
            waybillDTO.setState(WaybillStateEnum.WAYBILL_SLAUGHTER.getCode());
        }
        waybillDTO.setCreatedTime(null);
        Long waybillId = waybillService.addWaybill(waybillDTO);
        waybillDTO.setId(waybillId);
        if (flag) {
            ApplicationInfoDTO infoFarmDTO = userManager.initApplicationInfo(ApplicationTypeEnum.SLAUGHTER.getCode(), waybillDTO.getId(), slaughterDTO, userDTO);
            infoFarmDTO.setLinkTable(Constants.TB_WAYBILL);
            applicationInfoService.addApplicationInfo(infoFarmDTO);
            messageLoggingManager.messageHandling(waybillDTO.getBuyerUserId(), MessageEnum.WAYBILL_SLAUGHTER.getCode());
        } else {
            ((WaybillManager) AopContext.currentProxy()).initApplication(waybillDTO, userDTO);

            // 向养殖场和经纪人推送消息
            if (ObjectUtils.isNotEmpty(waybillDTO.getSalerUserId())) {
                messageLoggingManager.messageHandling(waybillDTO.getSalerUserId(), MessageEnum.WAYBILL_CREATE.getCode());
            }
            if (ObjectUtils.isNotEmpty(waybillDTO.getAgentUserId())) {
                messageLoggingManager.messageHandling(waybillDTO.getAgentUserId(), MessageEnum.WAYBILL_CREATE.getCode());
            }
        }

        if (!StringUtil.isEmpty(waybillDTO.getAgentUserId())) {
            UserDTO userDO = userManager.getUserByID(waybillDTO.getAgentUserId());
            if (!StringUtil.isEmpty(userDO) && userDO.getAutoSubmit().equals(1)) {
                ApprovalVO approvalVO = new ApprovalVO();
                approvalVO.setApprovalType(ApplicationTypeEnum.WAYBILL.getCode());
                approvalVO.setLinkId(waybillId);
                approvalVO.setToken(waybillDTO.getAgentUserId().toString());
                approvalVO.setResult(1);
                approvalWaybill(approvalVO);
            }
        }

        if (!StringUtil.isEmpty(waybillDTO.getSalerUserId())) {
            UserDTO userDO = userManager.getUserByID(waybillDTO.getSalerUserId());
            if (!StringUtil.isEmpty(userDO) && userDO.getAutoSubmit().equals(1)) {
                ApprovalVO approvalVO = new ApprovalVO();
                approvalVO.setApprovalType(ApplicationTypeEnum.WAYBILL.getCode());
                approvalVO.setLinkId(waybillId);
                approvalVO.setToken(waybillDTO.getSalerUserId().toString());
                approvalVO.setResult(1);
                approvalWaybill(approvalVO);
            }
        }


        if (!StringUtil.isEmpty(waybillDTO.getVerifyId())) {
            bladeRedis.incr(userDTO.getId().toString() + waybillDTO.getVerifyId()).toString();
        }
        return waybillId.toString();
    }

    public void checkWaybill(WaybillDTO waybillDTO, UserDTO slaughterDTO) {
//        Validator.isTrue(waybillDTO.getBuyerUserId() != null && waybillDTO.getBuyerUserId() != 0, ErrorCode.INPUT_PARAMETERS_NULL);
//        Validator.notNull(waybillDTO.getBuyerUserName(), ErrorCode.INPUT_PARAMETERS_NULL);
//        Validator.notNull(waybillDTO.getBuyerUserAddress(), ErrorCode.INPUT_PARAMETERS_NULL);
//        Validator.notNull(waybillDTO.getBuyerBusinessUrl(), ErrorCode.INPUT_PARAMETERS_NULL);
//        Validator.notNull(waybillDTO.getBuyerLivestockPreventionPassUrl(), ErrorCode.INPUT_PARAMETERS_NULL);
//        Validator.notNull(waybillDTO.getBuyerLivestockSlaughterPermitUrl(), ErrorCode.INPUT_PARAMETERS_NULL);
//        Validator.notNull(waybillDTO.getBuyerPollutantDischargePermitLicenseUrl(), ErrorCode.INPUT_PARAMETERS_NULL);
        Validator.isTrue(waybillDTO.getBuyerUserId().equals(slaughterDTO.getId()), ErrorCode.SLAUGHTER_IS_EXP);
        Validator.isTrue(waybillDTO.getBuyerUserName().equals(slaughterDTO.getUserName()), ErrorCode.SLAUGHTER_IS_EXP);
        Validator.isTrue(waybillDTO.getBuyerUserAddress().equals(slaughterDTO.getAddress()), ErrorCode.SLAUGHTER_IS_EXP);

//        Validator.isTrue(waybillDTO.getSalerUserId() != null && waybillDTO.getSalerUserId() != 0, ErrorCode.FARM_INFO_EMPTY);
//        if (StringUtil.isEmpty(waybillDTO.getContact())) {
//
//        }
        if (StringUtil.isEmpty(waybillDTO.getAgentUserId())) {
            UserDTO saler = userService.getUserById(waybillDTO.getSalerUserId());
            Validator.notNull(saler, ErrorCode.FARM_IS_NOT_REGISTERED);
            Validator.isTrue(saler.getType() == UserTypeEnum.FARM.getCode(), ErrorCode.FARM_IS_EXP);
            Validator.isTrue(saler.getState() == UserStateEnum.PASS.getCode(), ErrorCode.FARM_IS_EXP);
        }

        Validator.notNull(waybillDTO.getSalerUserName(), ErrorCode.FARM_INFO_EMPTY);
        UserQuery userQuery = new UserQuery();
        userQuery.setName(waybillDTO.getSalerUserName());


//        ContractQuery contractQuery = new ContractQuery();
//        contractQuery.setSalerId(waybillDTO.getSalerUserId());
//        contractQuery.setBuyerId(slaughterDTO.getId());
//        ContractDTO contractDTO = contractService.getContract(contractQuery);
//        Validator.notNull(contractDTO, ErrorCode.FARM_NOT_CONTRACT);
//        Validator.isTrue(contractDTO.getState().equals(YesNoEnum.YES.getCode()), ErrorCode.FARM_NOT_CONTRACT);

//        Validator.notNull(waybillDTO.getSalerBusinessUrl(), ErrorCode.FARM_INFO_EMPTY);
//        Validator.notNull(waybillDTO.getSalerLivestockPreventionPassUrl(), ErrorCode.FARM_INFO_EMPTY);
//        Validator.notNull(waybillDTO.getSalerNoEpidemicProofPassUrl(), ErrorCode.FARM_INFO_EMPTY);

        if (StringUtils.isNotBlank(waybillDTO.getAgentPhone())) {
            userQuery = new UserQuery();
            userQuery.setPhone(waybillDTO.getAgentPhone());
            UserDTO agent = userService.getOneUser(userQuery);
            Validator.notNull(agent, ErrorCode.AGENT_IS_NULL);
            Validator.isTrue(agent.getType().equals(UserTypeEnum.AGENT.getCode()), ErrorCode.INPUT_PARAMETERS_INVALID);
            Validator.isTrue(agent.getState().equals(UserStateEnum.PASS.getCode()), ErrorCode.INPUT_PARAMETERS_INVALID);
            Validator.isTrue(agent.getId().equals(waybillDTO.getAgentUserId()), ErrorCode.INPUT_PARAMETERS_INVALID);
            Validator.isTrue(agent.getUserName().equals(waybillDTO.getAgentName()), ErrorCode.INPUT_PARAMETERS_INVALID);
        } else {
            waybillDTO.setAgentUserId(0L);
            waybillDTO.setAgentPhone("");
            waybillDTO.setAgentName("");
        }

        Validator.notNull(waybillDTO.getPlanNum(), ErrorCode.PLAN_NUM_EMPTY);
        Validator.notNull(waybillDTO.getPlanTime(), ErrorCode.PLAN_TIME_EMPTY);
        Validator.notNull(waybillDTO.getVerifyId(), ErrorCode.VERIFY_INFO_IS_EMPTY);
        Validator.notNull(waybillDTO.getVerifyName(), ErrorCode.VERIFY_INFO_IS_EMPTY);
        Validator.notNull(waybillDTO.getVerifyAddress(), ErrorCode.VERIFY_INFO_IS_EMPTY);
        VerifyStationDTO verifyStationDTO = verifyStationService.getVerifyById(waybillDTO.getVerifyId());
        Validator.notNull(verifyStationDTO, ErrorCode.VERIFY_INFO_NOT_EXIT);
        Validator.isTrue(waybillDTO.getVerifyName().equals(verifyStationDTO.getName()), ErrorCode.INPUT_PARAMETERS_INVALID);
        Validator.isTrue(waybillDTO.getVerifyAddress().equals(verifyStationDTO.getAddress()), ErrorCode.INPUT_PARAMETERS_INVALID);
    }

    public Boolean topWaybill(ApprovalVO approvalVO) {
        waybillService.update(Wrappers.<WaybillDO>lambdaUpdate().eq(WaybillDO::getId, approvalVO.getLinkId()).set(WaybillDO::getTop, approvalVO.getTop() == 1 ? 1 : 0));
        return true;
    }

    /**
     * 审批合同
     *
     * @param approvalVO
     * @return java.lang.Boolean
     * @author FUXINSHENG
     * @date 2021/11/10 16:17
     * @describe 1、类型和linkid查询审批信息
     * 2、校验用户角色是否具有审批该内容的权限
     * 3、校验审批内容状态是否可以进行审批
     * 4、校验调运单信息是否完整
     * 5、修改审批信息和内容的状态
     */
    @ServiceTimeLog
    @Transactional(rollbackFor = Exception.class)
    public Boolean approvalWaybill(ApprovalVO approvalVO) {
        Validator.notNull(approvalVO, ErrorCode.INPUT_PARAMETERS_NULL);
        Validator.notNull(approvalVO.getLinkId(), ErrorCode.INPUT_PARAMETERS_NULL);
        Validator.notNull(approvalVO.getApprovalType(), ErrorCode.INPUT_PARAMETERS_NULL);
        Validator.notNull(approvalVO.getResult(), ErrorCode.INPUT_PARAMETERS_NULL);
//        UserDTO userDTO = userUtils.getUser(approvalVO.getToken());
        UserDTO userDTO = userService.getUserById(Long.valueOf(approvalVO.getToken()));
        log.info(HEAD + "审批调运单, 当前用户id:{}, 请求参数:{}", userDTO.getId(), JSON.toJSONString(approvalVO));

        Validator.isTrue(userDTO.getType().equals(UserTypeEnum.AGENT.getCode())
                || userDTO.getType().equals(UserTypeEnum.FARM.getCode()), ErrorCode.NO_POWER_GET);
        Validator.isTrue(approvalVO.getApprovalType().equals(ApplicationTypeEnum.WAYBILL.getCode()), ErrorCode.APPLY_TYPE_ERROR);
        WaybillDTO waybillDTO = waybillService.getWaybillById(approvalVO.getLinkId());
        Validator.notNull(waybillDTO, ErrorCode.WAYBILL_INFO_EMPTY);
        Validator.isTrue(waybillDTO.getState().equals(WaybillStateEnum.UNCHECK.getCode()), ErrorCode.ORDER_INFO_STATE_ERROR);
        if (userDTO.getType().equals(UserTypeEnum.AGENT.getCode())) {
            Validator.isTrue(waybillDTO.getAgentUserId().equals(userDTO.getId()), ErrorCode.NO_POWER_GET);
        } else if (userDTO.getType().equals(UserTypeEnum.FARM.getCode())) {
            Validator.isTrue(waybillDTO.getSalerUserId().equals(userDTO.getId()), ErrorCode.NO_POWER_GET);
        } else {
            Validator.isTrue(false, ErrorCode.NO_POWER_GET);
        }

        ApplicationQuery applicationQuery = new ApplicationQuery();
        applicationQuery.setApplyUserId(userDTO.getId());
//        applicationQuery.setSubmitUserId(waybillDTO.getSlaughterHouseId() != null && waybillDTO.getSlaughterHouseId() != 0 ? waybillDTO.getSlaughterHouseId() : waybillDTO.getBuyerUserId());
        applicationQuery.setType(ApplicationTypeEnum.WAYBILL.getCode());
        applicationQuery.setLinkId(waybillDTO.getId());
        ApplicationInfoDTO applicationInfoDTO = applicationInfoService.getApplicationInfoByQuery(applicationQuery);
//        Validator.notNull(applicationInfoDTO, ErrorCode.APPLY_NULL);
//        Validator.isTrue(applicationInfoDTO.getState().equals(ApplicationStateEnum.UNCHECK.getCode()), ErrorCode.APPLY_STATE_ERROR);

        ApplicationInfoDTO applicationInfoByQuery = null;
        if (userDTO.getType().equals(UserTypeEnum.AGENT.getCode())) {
//            applicationQuery.setApplyUserId(waybillDTO.getSalerUserId());
            applicationInfoByQuery = applicationInfoService.getApplicationInfoByQuery(applicationQuery);
        } else if (userDTO.getType().equals(UserTypeEnum.FARM.getCode()) && StringUtils.isNotBlank(waybillDTO.getAgentPhone())) {
//            applicationQuery.setApplyUserId(waybillDTO.getAgentUserId());
            applicationInfoByQuery = applicationInfoService.getApplicationInfoByQuery(applicationQuery);
        }

        if (approvalVO.getResult().equals(YesNoEnum.YES.getCode())) {
//            PictureQuery pictureQuery = new PictureQuery();
//            pictureQuery.setLinkId(waybillDTO.getId());
//            pictureQuery.setType(PictureTypeEnum.BLOOD_TEST.getCode());
//            List<PictureInfoDTO> pictureInfoList = pictureInfoService.listPictureInfo(pictureQuery);
//            Validator.isTrue(CollectionUtils.isNotEmpty(pictureInfoList), ErrorCode.ORDER_INFO_NOT_ENOUGH);
            applicationInfoDTO.setState(ApplicationStateEnum.PASS.getCode());
            waybillDTO.setState(WaybillStateEnum.PASS.getCode());
        } else {
            applicationInfoDTO.setState(ApplicationStateEnum.REJECT.getCode());
            applicationInfoDTO.setMessage(approvalVO.getMessage());
            waybillDTO.setState(WaybillStateEnum.REJECT.getCode());
        }

        if (applicationInfoByQuery != null) {
            Validator.isTrue(applicationInfoByQuery.getState() == ApplicationStateEnum.UNCHECK.getCode(), ErrorCode.WAYBILL_INFO_EXP);
            applicationInfoByQuery.setState(applicationInfoDTO.getState());
            applicationInfoByQuery.setMessage(UserTypeEnum.findByCode(userDTO.getType()).getText() + "审批" + (approvalVO.getResult().equals(YesNoEnum.YES.getCode()) ? "通过" : "驳回"));
            applicationInfoService.updateApplicationInfo(applicationInfoByQuery);
        }
//        applicationInfoService.updateApplicationInfo(applicationInfoDTO);
        waybillDTO.setConfirmTime(new Date());
        waybillDTO.setConfirmUserId(userDTO.getId());
        waybillService.updateWaybill(waybillDTO);

        if (approvalVO.getResult().equals(YesNoEnum.YES.getCode())) {
            log.info(HEAD + "初始化畜牧局审批记录, 当前用户id:{}, 请求参数:{}", userDTO.getId(), JSON.toJSONString(waybillDTO));
            ApplicationInfoDTO applicationBureauDTO = new ApplicationInfoDTO();
            applicationBureauDTO.setLinkTable(Constants.TB_WAYBILL);
            applicationBureauDTO.setLinkId(waybillDTO.getId());
            applicationBureauDTO.setType(ApplicationTypeEnum.WAYBILL_APPROVAL.getCode());
            applicationBureauDTO.setState(ApplicationStateEnum.UNCHECK.getCode());
            applicationBureauDTO.setSubmitUserId(userDTO.getId());
            applicationBureauDTO.setSubmitUserName(userDTO.getUserName());
            applicationBureauDTO.setSubmitPhone(userDTO.getPhone());
            applicationInfoService.addApplicationInfo(applicationBureauDTO);
            OutApiSyncRecordResultVO outApiSyncRecordResultVO = initZmtApply(waybillDTO);
            Validator.notNull(outApiSyncRecordResultVO, ErrorCode.ZMT_RECORD_ERROR);
            waybillDTO.setRegisteredUuid(outApiSyncRecordResultVO.getRegisteredUuid());
            waybillDTO.setOutTradeNo(outApiSyncRecordResultVO.getSimpleNo());
            waybillDTO.setSubmitTime(new Date());
            waybillDTO.setVersion(null);
            waybillService.updateWaybill(waybillDTO);
        }

        // 备案单驳回时消息通知屠宰场和待宰户
        if (approvalVO.getResult().equals(YesNoEnum.NO.getCode())) {
            if (ObjectUtils.isNotEmpty(waybillDTO.getSlaughterHouseId()) && waybillDTO.getSlaughterHouseId() != 0) {
                messageLoggingManager.messageHandling(waybillDTO.getSlaughterHouseId(), MessageEnum.WAYBILL_REJECT.getCode());
            } else {
                messageLoggingManager.messageHandling(waybillDTO.getBuyerUserId(), MessageEnum.WAYBILL_REJECT.getCode());
            }
        }
        return true;
    }

    public OutApiSyncRecordResultVO initZmtApply(WaybillDTO waybillDTO) {
        UserDTO userDTO = userService.getUserById(waybillDTO.getBuyerUserId());
        if (!StringUtil.isEmpty(waybillDTO.getSlaughterHouseId()) && waybillDTO.getSlaughterHouseId() != 0) {
            UserDTO user = userService.getUserById(waybillDTO.getSlaughterHouseId());
            userDTO.setPhone(user.getPhone());
        }
        if (!StringUtil.isEmpty(waybillDTO.getContact())) {
            userDTO.setPhone(waybillDTO.getContact());
        }
        OutApiSyncRecordParamVO recordParamVO = new OutApiSyncRecordParamVO();
        if (StringUtils.isNotBlank(waybillDTO.getRegisteredUuid())) {
            recordParamVO.setRegisteredUuid(waybillDTO.getRegisteredUuid());
        }
        recordParamVO.setCompanyOrPeopleType(userDTO.getZmtType());
        recordParamVO.setCompanyOrPeople(userDTO.getUserName());
        recordParamVO.setTel(userDTO.getPhone());
        recordParamVO.setRecordUnitId(userDTO.getZmtId());
        recordParamVO.setRecordPeople(userDTO.getZmtUserName());
        recordParamVO.setRecordPeopleId(userDTO.getZmtUserId());
        recordParamVO.setRecordTime(new Date());
        recordParamVO.setKindTypeId(1410L);
        recordParamVO.setSupplierId(waybillDTO.getSupplierId());
        recordParamVO.setSupplierType(waybillDTO.getSupplierType());
        recordParamVO.setCount(waybillDTO.getPlanNum());
        recordParamVO.setPurposeId(1572L);
        recordParamVO.setRemark(waybillDTO.getRemark());
        recordParamVO.setAdjustmentTime(waybillDTO.getPlanTime());
        recordParamVO.setIsPassCheckpoint(YesNoEnum.NO.getCode());
        recordParamVO.setInspectCheckpointId(waybillDTO.getVerifyId());
        return zmtClientService.postRegistered(recordParamVO);
    }

    public Boolean cancelBill(WaybillDTO waybillDTO) {
        OutApiSyncAcceptNumParamVO acceptNumParamVO = new OutApiSyncAcceptNumParamVO();
        WaybillDTO waybill = waybillService.getWaybillById(waybillDTO.getId());
        waybill.setState(WaybillStateEnum.CANCEL.getCode());
        waybillService.updateWaybill(waybillDTO);
        Validator.isTrue(waybill.getState().equals(1), ErrorCode.APPLY_TYPE_ERROR);
        acceptNumParamVO.setRegisteredUuid(waybill.getRegisteredUuid());
        zmtClientService.postRegisteredCancel(acceptNumParamVO);
        return true;
    }

    public Boolean carNoPush(CarPushVo carPushVo){
        CarPush carPush = new CarPush();

        List<CarVo> carVos = new ArrayList<CarVo>();
        CarVo carVo = new CarVo();
        carVo.setEntranceTime(carPushVo.getEntranceTime());
        carVo.setPlateNo(carPushVo.getPlateNo());
        carVos.add(carVo);

        carPush.setCheckPointName(carPushVo.getCheckPointName());
        carPush.setCarList(carVos);
        String result = zmtClientService.postCarPush(carPush);
        return true;
    }


    /**
     * 调运单重新提交
     *
     * @param waybillDTO
     * @return java.lang.String
     * @author FUXINSHENG
     * @date 2021/11/12 8:57
     * @describe 1、获取原来的调运单，校验状态为驳回/未通过
     * 2、获取原来的调运单审批记录，校验状态为未通过
     * 3、校验用户角色，是否可以重新进行提交调运单
     * 4、根据创建调运单的逻辑，校验调运单详情
     * 5、创建调运单，并重新创建新的审批记录
     */
    @ServiceTimeLog
    @Transactional(rollbackFor = Exception.class)
    public String resubmit(WaybillDTO waybillDTO) {
        UserDTO userDTO = userUtils.getUser(waybillDTO.getToken());
        Validator.notNull(waybillDTO.getId(), ErrorCode.INPUT_PARAMETERS_NULL);
        log.info(HEAD + "重新提交调运单, 当前用户id:{}, 请求参数:{}", userDTO.getId(), JSON.toJSONString(waybillDTO));
        WaybillDTO waybillById = waybillService.getWaybillById(waybillDTO.getId());
        Validator.notNull(waybillById, ErrorCode.WAYBILL_INFO_EMPTY);
        Validator.isTrue(waybillById.getState().equals(WaybillStateEnum.REJECT.getCode())
                || waybillById.getState().equals(WaybillStateEnum.UNPASS.getCode())
                || waybillById.getState().equals(WaybillStateEnum.WAYBILL_SLAUGHTER_REJECT.getCode())
                || waybillById.getState().equals(WaybillStateEnum.CANCEL.getCode()), ErrorCode.ORDER_INFO_STATE_ERROR);
        if (waybillById.getSlaughterHouseId() != null && waybillById.getSlaughterHouseId() != 0) {
            //Validator.isTrue(waybillById.getSlaughterHouseId().equals(userDTO.getId()), ErrorCode.NO_POWER_GET);
        } else {
            Validator.isTrue(waybillById.getBuyerUserId().equals(userDTO.getId()), ErrorCode.NO_POWER_GET);
        }

        ApplicationQuery query = new ApplicationQuery();
        query.setLinkId(waybillDTO.getId());
        query.setVersion(1);
        if (waybillById.getState().equals(WaybillStateEnum.REJECT.getCode())
                || waybillById.getState().equals(WaybillStateEnum.CANCEL.getCode())) {
            query.setType(ApplicationTypeEnum.WAYBILL.getCode());
        } else if (waybillById.getState().equals(WaybillStateEnum.UNPASS.getCode())) {
            query.setType(ApplicationTypeEnum.WAYBILL_APPROVAL.getCode());
        } else if (waybillById.getState().equals(WaybillStateEnum.WAYBILL_SLAUGHTER_REJECT.getCode())) {
            query.setType(ApplicationTypeEnum.SLAUGHTER.getCode());
        } else {
            Validator.isTrue(false, ErrorCode.ORDER_INFO_STATE_ERROR);
        }
        ApplicationInfoDTO applicationInfoByQuery = applicationInfoService.getApplicationInfoByQuery(query);
        Validator.notNull(applicationInfoByQuery, ErrorCode.ORDER_INFO_STATE_ERROR);
        Validator.isTrue(applicationInfoByQuery.getState().equals(ApplicationStateEnum.REJECT.getCode()) ||
                applicationInfoByQuery.getState().equals(ApplicationStateEnum.CANCEL.getCode()), ErrorCode.APPLY_STATE_ERROR);

        Validator.isTrue(userDTO.getType().equals(UserTypeEnum.SLAUGHTER.getCode())
                || userDTO.getType().equals(UserTypeEnum.SLAUGHTER_HOUSE.getCode()), ErrorCode.NO_POWER_GET);
        UserDTO slaughterDTO = userDTO;
        Integer ifAutoApply = 1;
        if (userDTO.getType().equals(UserTypeEnum.SLAUGHTER_HOUSE.getCode())) {
//            Validator.notNull(waybillDTO.getSlaughterHouseId(), ErrorCode.SLAUGHTER_HOUSE_IS_EMPTY);
//            Validator.isTrue(waybillDTO.getSlaughterHouseId().equals(userDTO.getId()), ErrorCode.INPUT_PARAMETERS_NULL);
//            slaughterDTO = userService.getUserById(userDTO.getSlaughterHouseParentId());
            slaughterDTO = userService.getUserById(waybillDTO.getBuyerUserId());
            SlaughterBuyerRelationDTO slaughterBuyerRelationDTO = slaughterBuyerRelationService.queryByHouseIdAndBuyerId(userDTO.getId(), waybillDTO.getBuyerUserId());
            Validator.isTrue(slaughterBuyerRelationDTO != null && slaughterBuyerRelationDTO.getState().intValue() == RelationStateEnum.BIND.getCode(), ErrorCode.RELATION_ISNULL);
            ifAutoApply = slaughterBuyerRelationDTO.getIfAutoApply();
        }
        checkWaybill(waybillDTO, slaughterDTO);
        if (YesNoEnum.YES.getCode().equals(ifAutoApply)) {
            waybillDTO.setState(WaybillStateEnum.UNCHECK.getCode());
            ((WaybillManager) AopContext.currentProxy()).initApplication(waybillDTO, userDTO);

            // 向养殖场和经纪人推送消息
            if (ObjectUtils.isNotEmpty(waybillDTO.getSalerUserId())) {
                messageLoggingManager.messageHandling(waybillDTO.getSalerUserId(), MessageEnum.WAYBILL_CREATE.getCode());
            }
            if (ObjectUtils.isNotEmpty(waybillDTO.getAgentUserId())) {
                messageLoggingManager.messageHandling(waybillDTO.getAgentUserId(), MessageEnum.WAYBILL_CREATE.getCode());
            }
        } else {
            waybillDTO.setState(WaybillStateEnum.WAYBILL_SLAUGHTER.getCode());
            ApplicationInfoDTO infoFarmDTO = userManager.initApplicationInfo(ApplicationTypeEnum.SLAUGHTER.getCode(), waybillDTO.getId(), slaughterDTO, userDTO);
            infoFarmDTO.setLinkTable(Constants.TB_WAYBILL);
            applicationInfoService.addApplicationInfo(infoFarmDTO);
            messageLoggingManager.messageHandling(waybillDTO.getBuyerUserId(), MessageEnum.WAYBILL_SLAUGHTER.getCode());
        }
        waybillDTO.setVersion(null);
        waybillDTO.setBillName(waybillDTO.getBuyerUserName() + "-" + waybillDTO.getSalerUserName() + "备案单");
        waybillService.updateWaybill(waybillDTO);


        if (!StringUtil.isEmpty(waybillDTO.getAgentUserId())) {
            UserDTO userDO = userManager.getUserByID(waybillDTO.getAgentUserId());
            if (!StringUtil.isEmpty(userDO) && userDO.getAutoSubmit().equals(1)) {
                ApprovalVO approvalVO = new ApprovalVO();
                approvalVO.setApprovalType(ApplicationTypeEnum.WAYBILL.getCode());
                approvalVO.setLinkId(waybillDTO.getId());
                approvalVO.setToken(waybillDTO.getAgentUserId().toString());
                approvalVO.setResult(1);
                approvalWaybill(approvalVO);
            }
        }

        if (!StringUtil.isEmpty(waybillDTO.getSalerUserId())) {
            UserDTO userDO = userManager.getUserByID(waybillDTO.getSalerUserId());
            if (!StringUtil.isEmpty(userDO) && userDO.getAutoSubmit().equals(1)) {
                ApprovalVO approvalVO = new ApprovalVO();
                approvalVO.setApprovalType(ApplicationTypeEnum.WAYBILL.getCode());
                approvalVO.setLinkId(waybillDTO.getId());
                approvalVO.setToken(waybillDTO.getSalerUserId().toString());
                approvalVO.setResult(1);
                approvalWaybill(approvalVO);
            }
        }

        return waybillDTO.getId().toString();
    }

    @Transactional(rollbackFor = Exception.class)
    public void initApplication(WaybillDTO waybillDTO, UserDTO userDTO) {
        log.info(HEAD + "初始化审批记录, 当前用户id:{}, 请求参数:{}", userDTO.getId(), JSON.toJSONString(waybillDTO));
        UserDTO farm = userService.getUserById(waybillDTO.getSalerUserId());
        ApplicationInfoDTO infoFarmDTO = userManager.initApplicationInfo(ApplicationTypeEnum.WAYBILL.getCode(), waybillDTO.getId(), farm, userDTO);
        infoFarmDTO.setLinkTable(Constants.TB_WAYBILL);
        applicationInfoService.addApplicationInfo(infoFarmDTO);

        if (waybillDTO.getAgentUserId() != null && waybillDTO.getAgentUserId() != 0) {
            UserDTO agent = userService.getUserById(waybillDTO.getAgentUserId());
            ApplicationInfoDTO infoAgentDTO = userManager.initApplicationInfo(ApplicationTypeEnum.WAYBILL.getCode(), waybillDTO.getId(), agent, userDTO);
            infoAgentDTO.setLinkTable(Constants.TB_WAYBILL);
            applicationInfoService.addApplicationInfo(infoAgentDTO);
        }
    }

    /**
     * 调运单上传附件
     *
     * @param waybillDTO
     * @return java.lang.Boolean
     * @author FUXINSHENG
     * @date 2021/11/12 11:53
     * @describe 1、校验用户角色为养殖场或经纪人
     * 2、校验用户与调运单的关联
     * 3、修改调运单中的数据
     */
    @ServiceTimeLog
    @Transactional(rollbackFor = Exception.class)
    public Boolean submitPicture(WaybillDTO waybillDTO) {
        UserDTO userDTO = userUtils.getUser(waybillDTO.getToken());
        log.info(HEAD + "调运单上传附件, 当前用户id:{}, 请求参数:{}", userDTO.getId(), JSON.toJSONString(waybillDTO));

        WaybillDTO waybillById = waybillService.getWaybillById(waybillDTO.getId());
        Validator.notNull(waybillById, ErrorCode.WAYBILL_INFO_EMPTY);
        if (userDTO.getType().equals(UserTypeEnum.AGENT.getCode())) {
            Validator.isTrue(waybillById.getAgentUserId().equals(userDTO.getId()), ErrorCode.INPUT_PARAMETERS_INVALID);
        } else if (userDTO.getType().equals(UserTypeEnum.FARM.getCode())) {
            Validator.isTrue(waybillById.getSalerUserId().equals(userDTO.getId()), ErrorCode.INPUT_PARAMETERS_INVALID);
        } else {
            Validator.isTrue(false, ErrorCode.NO_POWER_GET);
        }

        int count = 1;
        PictureQuery query = new PictureQuery();
        query.setLinkId(waybillDTO.getId());
        pictureInfoService.deleteByLinkId(query);
        for (String bloodTest : waybillDTO.getBloodTestList()) {
            PictureInfoDTO pictureInfoDTO = new PictureInfoDTO();
            pictureInfoDTO.setLinkId(waybillById.getId());
            pictureInfoDTO.setLinkTable(Constants.TB_WAYBILL);
            pictureInfoDTO.setSort(count++);
            pictureInfoDTO.setType(PictureTypeEnum.BLOOD_TEST.getCode());
            pictureInfoDTO.setUrl(bloodTest);
            pictureInfoService.addPictureInfo(pictureInfoDTO);
        }
        return true;
    }

    public Page<WaybillDTO> pageWaybill(AdminWaybillQuery waybillQuery) {
        Page<WaybillDTO> page = waybillService.pageWaybill(waybillQuery);
        List<WaybillDTO> records = page.getRecords();
        ApplicationQuery applicationQuery = new ApplicationQuery();
        for (WaybillDTO waybillDTO : records) {
            if (waybillDTO.getState() == WaybillStateEnum.FINISH.getCode()) {
                TransportQuery transportQuery = new TransportQuery();
                transportQuery.setWayBillId(waybillDTO.getId());
                TransportDTO transportDTO = transportService.getTransport(transportQuery);
                if (transportDTO != null) {
                    waybillDTO.setTransportCode(transportDTO.getCode());
                }
            }
            ApplicationInfoDTO applicationInfoByQuery = null;
            if (waybillDTO.getState() == WaybillStateEnum.REJECT.getCode()) {
                applicationQuery.setType(ApplicationTypeEnum.WAYBILL.getCode());
                applicationQuery.setLinkId(waybillDTO.getId());
                applicationInfoByQuery = applicationInfoService.getApplicationInfoByQuery(applicationQuery);
            }
            if (waybillDTO.getState() == WaybillStateEnum.UNPASS.getCode()) {
                applicationQuery.setType(ApplicationTypeEnum.WAYBILL_APPROVAL.getCode());
                applicationQuery.setLinkId(waybillDTO.getId());
                applicationInfoByQuery = applicationInfoService.getApplicationInfoByQuery(applicationQuery);
            }
            if (applicationInfoByQuery != null) {
                waybillDTO.setMessage(applicationInfoByQuery.getMessage());
            }
        }
        return page;
    }

    public List<String> getBloodTest(Long id) {
        PictureQuery pictureQuery = new PictureQuery();
        pictureQuery.setType(PictureTypeEnum.BLOOD_TEST.getCode());
        pictureQuery.setLinkId(id);
        List<PictureInfoDTO> pictureInfoDTOList = pictureInfoService.listPictureInfo(pictureQuery);
        if (CollectionUtils.isNotEmpty(pictureInfoDTOList)) {
            return pictureInfoDTOList.stream().map(PictureInfoDTO::getUrl).collect(Collectors.toList());
        }
        return new ArrayList<>();
    }

    /**
     * 审批调运单
     *
     * @param approvalVO
     * @return java.lang.Boolean
     * @author FUXINSHENG
     * @date 2021/11/26 10:01
     * 1、获取调运单信息
     * 2、校验调运单状态
     * 3、获取调运单审批记录
     * 4、校验记录状态
     * 5、校验参数，若为驳回，在校验审批意见非空
     * 6、修改审批记录状态
     * 7、修改调运单状态，添加外部编码
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean approvalWaybillByBureau(ApprovalVO approvalVO) {
        log.info(HEAD + "管理端手动审批调运单, 请求参数:{}", JSON.toJSONString(approvalVO));
        Validator.notNull(approvalVO, ErrorCode.INPUT_PARAMETERS_NULL);
        Validator.notNull(approvalVO.getLinkId(), ErrorCode.INPUT_PARAMETERS_NULL);
        Validator.notNull(approvalVO.getResult(), ErrorCode.INPUT_PARAMETERS_NULL);
        Validator.notNull(approvalVO.getApprovalType(), ErrorCode.INPUT_PARAMETERS_NULL);
        Validator.isTrue(approvalVO.getApprovalType() == ApplicationTypeEnum.WAYBILL_APPROVAL.getCode(), ErrorCode.INPUT_PARAMETERS_INVALID);
        if (approvalVO.getResult().equals(YesNoEnum.NO.getCode())) {
            Validator.notNull(approvalVO.getMessage(), ErrorCode.INPUT_PARAMETERS_NULL);
        } else if (approvalVO.getResult().equals(YesNoEnum.YES.getCode())) {
            Validator.notNull(approvalVO.getOutTradeNo(), ErrorCode.INPUT_PARAMETERS_NULL);
        } else {
            Validator.notNull(null, ErrorCode.INPUT_PARAMETERS_INVALID);
        }

        WaybillDTO waybill = waybillService.getWaybillById(approvalVO.getLinkId());
        Validator.notNull(waybill, ErrorCode.WAYBILL_INFO_EMPTY);
        Validator.isTrue(waybill.getState() == WaybillStateEnum.PASS.getCode(), ErrorCode.WAYBILL_INFO_EXP);
        ApplicationQuery applicationQuery = new ApplicationQuery();
        applicationQuery.setLinkId(waybill.getId());
        applicationQuery.setType(ApplicationTypeEnum.WAYBILL_APPROVAL.getCode());
        ApplicationInfoDTO applicationInfo = applicationInfoService.getApplicationInfoByQuery(applicationQuery);
        Validator.notNull(applicationInfo, ErrorCode.APPLY_NULL);
        Validator.isTrue(applicationInfo.getState() == ApplicationStateEnum.UNCHECK.getCode(), ErrorCode.APPLY_STATE_ERROR);
        int messageCode = 0;
        applicationInfo.setState(approvalVO.getResult().equals(YesNoEnum.YES.getCode()) ? ApplicationStateEnum.PASS.getCode() : ApplicationStateEnum.REJECT.getCode());
        if (approvalVO.getResult().equals(YesNoEnum.NO.getCode())) {
            applicationInfo.setMessage(approvalVO.getMessage());
            waybill.setState(WaybillStateEnum.UNPASS.getCode());
            messageCode = MessageEnum.WAYBILL_FAIL.getCode();
        } else {
            waybill.setState(WaybillStateEnum.FINISH.getCode());
            waybill.setOutTradeNo(approvalVO.getOutTradeNo());
            messageCode = MessageEnum.WAYBILL_ADOPT.getCode();
        }
        applicationInfoService.updateApplicationInfo(applicationInfo);
        waybillService.updateWaybill(waybill);

        if (ObjectUtils.isNotEmpty(waybill.getAgentUserId()) && waybill.getAgentUserId() != 0) {
            messageLoggingManager.messageHandling(waybill.getAgentUserId(), messageCode);
        }
        if (ObjectUtils.isNotEmpty(waybill.getSalerUserId())) {
            messageLoggingManager.messageHandling(waybill.getSalerUserId(), messageCode);
        }
        if (ObjectUtils.isNotEmpty(waybill.getBuyerUserId())) {
            messageLoggingManager.messageHandling(waybill.getBuyerUserId(), messageCode);
        }
        if (ObjectUtils.isNotEmpty(waybill.getSlaughterHouseId())) {
            messageLoggingManager.messageHandling(waybill.getSlaughterHouseId(), messageCode);
        }
        return true;
    }


    public WaybillDTO getAdminWaybillDetail(Long waybillId) {

        WaybillDTO waybillDTO = waybillService.getWaybillById(waybillId);
        log.info(HEAD + "管理端获取调运单详情, 请求参数:{}", waybillId);
        UserDTO buyer = userService.getUserById(waybillDTO.getBuyerUserId());
        waybillDTO.setBuyerLinkMan(buyer.getBusinessLinkMan());
        waybillDTO.setBuyerPhone(buyer.getPhone());
        UserDTO saler = userService.getUserById(waybillDTO.getSalerUserId());
        waybillDTO.setSalerLinkMan(StringUtil.isEmpty(saler) ? "" : saler.getBusinessLinkMan());
        waybillDTO.setSalerPhone(StringUtil.isEmpty(saler) ? "" : saler.getPhone());
        PictureQuery pictureQuery = new PictureQuery();
        pictureQuery.setLinkId(waybillDTO.getId());
        pictureQuery.setType(PictureTypeEnum.BLOOD_TEST.getCode());
        List<PictureInfoDTO> pictureInfoDTOList = pictureInfoService.listPictureInfo(pictureQuery);
        if (CollectionUtils.isNotEmpty(pictureInfoDTOList)) {
            waybillDTO.setBloodTestList(pictureInfoDTOList.stream().map(PictureInfoDTO::getUrl).collect(Collectors.toList()));
        }
        if (WaybillStateEnum.REJECT.getCode() == waybillDTO.getState()) {
            ApplicationQuery applicationQuery = new ApplicationQuery();
            applicationQuery.setType(ApplicationTypeEnum.WAYBILL.getCode());
            applicationQuery.setLinkId(waybillId);
            applicationQuery.setApplyUserId(waybillDTO.getSalerUserId());
            ApplicationInfoDTO applicationInfoByQuery = applicationInfoService.getApplicationInfoByQuery(applicationQuery);
            Validator.notNull(applicationInfoByQuery, ErrorCode.APPLY_NULL);
            waybillDTO.setApplyType(UserTypeEnum.FARM.getCode());
            if (ApplicationStateEnum.UNCHECK.getCode() == applicationInfoByQuery.getState() && waybillDTO.getAgentUserId() != null && waybillDTO.getAgentUserId() != 0) {
                applicationQuery.setApplyUserId(waybillDTO.getAgentUserId());
                applicationInfoByQuery = applicationInfoService.getApplicationInfoByQuery(applicationQuery);
                Validator.notNull(applicationInfoByQuery, ErrorCode.APPLY_NULL);
                waybillDTO.setApplyType(UserTypeEnum.AGENT.getCode());
                waybillDTO.setApplyUserName(applicationInfoByQuery.getApplyUserName());
            }
            Validator.isTrue(ApplicationStateEnum.REJECT.getCode() == applicationInfoByQuery.getState(), ErrorCode.APPLY_NULL);
            waybillDTO.setMessage(applicationInfoByQuery.getMessage());
        }
        if (WaybillStateEnum.UNPASS.getCode() == waybillDTO.getState()) {
            ApplicationQuery applicationQuery = new ApplicationQuery();
            applicationQuery.setType(ApplicationTypeEnum.WAYBILL_APPROVAL.getCode());
            applicationQuery.setLinkId(waybillId);
            ApplicationInfoDTO applicationInfoByQuery = applicationInfoService.getApplicationInfoByQuery(applicationQuery);
            Validator.isTrue(ApplicationStateEnum.REJECT.getCode() == applicationInfoByQuery.getState(), ErrorCode.APPLY_NULL);
            waybillDTO.setMessage(applicationInfoByQuery.getMessage());
            waybillDTO.setApplyType(UserTypeEnum.ANIMAL_BUREAU.getCode());
            waybillDTO.setApplyUserName(applicationInfoByQuery.getApplyUserName());
        }
        return waybillDTO;
    }

    /**
     * 撤销调运单
     * 1，校验：
     * 1.1 调运单状态小于3（完成之前）
     * 1.2 用户必须是创建调运单的用户（调运单用户从审批信息中获取）
     * 2，更新调运单状态为撤销
     * 3，删除审批信息
     *
     * @param id
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean cancel(Long id) {
        Validator.notNull(id, ErrorCode.INPUT_PARAMETERS_NULL);
        WaybillDTO waybillDTO = waybillService.getWaybillById(id);
        Validator.notNull(waybillDTO, ErrorCode.WAYBILL_INFO_EMPTY);
        //调运单状态必须小于3，用户必须是创建用户
        Validator.isTrue(waybillDTO.getState().intValue() < WaybillStateEnum.FINISH.getCode(), ErrorCode.ORDER_INFO_STATE_NOT_FINISH);
        //通过审批信息获取调运单的创建人id
        ApplicationQuery applicationQuery = new ApplicationQuery();
        applicationQuery.setType(ApplicationTypeEnum.WAYBILL.getCode());
        applicationQuery.setLinkId(waybillDTO.getId());
        ApplicationInfoDTO applicationInfoDTO = applicationInfoService.getApplicationInfoByQuery(applicationQuery);
        Validator.notNull(applicationInfoDTO, ErrorCode.APPLY_NULL);
        long creator = applicationInfoDTO.getSubmitUserId() == null ? 0 : applicationInfoDTO.getSubmitUserId().longValue();
        //Validator.isTrue(creator == userDTO.getId().longValue(), ErrorCode.ORDER_INFO_MAST_CREATOR);
        //更新调运单信息
        waybillDTO.setState(WaybillStateEnum.CANCEL.getCode());
        waybillDTO.setModifiedTime(new Date());
        Validator.isTrue(waybillService.updateWaybill(waybillDTO), ErrorCode.ORDER_INFO_UPDATE_FAIL);
        //更新审核信息状态
        applicationInfoDTO.setState(ApplicationStateEnum.CANCEL.getCode());
        Validator.isTrue(applicationInfoService.updateApplicationInfo(applicationInfoDTO), ErrorCode.UPDATE_DATA_ERROR);
        OutApiSyncAcceptNumParamVO acceptNumParamVO = new OutApiSyncAcceptNumParamVO();
        acceptNumParamVO.setRegisteredUuid(waybillDTO.getRegisteredUuid());
        zmtClientService.postRegisteredCancel(acceptNumParamVO);
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    public Boolean delete(Long id) {
        Validator.notNull(id, ErrorCode.INPUT_PARAMETERS_NULL);
        WaybillDTO waybillDTO = waybillService.getWaybillById(id);
        Validator.notNull(waybillDTO, ErrorCode.WAYBILL_INFO_EMPTY);
        Validator.isTrue(waybillDTO.getState().intValue() == WaybillStateEnum.CANCEL.getCode(), ErrorCode.ORDER_INFO_DELETE_STATE_ERROR);
        Validator.isTrue(waybillService.realDeleteById(id), ErrorCode.ORDER_INFO_DELETE_FAIL);
        //删除审批信息
        ApplicationQuery applicationQuery = new ApplicationQuery();
        applicationQuery.setType(ApplicationTypeEnum.WAYBILL.getCode());
        applicationQuery.setLinkId(id);
        ApplicationInfoDTO applicationInfoDTO = applicationInfoService.getApplicationInfoByQuery(applicationQuery);
        if (applicationInfoDTO != null) {
            Validator.isTrue(applicationInfoService.realDeleteById(applicationInfoDTO.getId()), ErrorCode.APPLY_DELETE_FAIL);
        }

        return true;
    }

    @ServiceTimeLog
    @Transactional(rollbackFor = Exception.class)
    public Boolean approvalOrderBySlaughter(ApprovalVO approvalVO) {
        Validator.notNull(approvalVO, ErrorCode.INPUT_PARAMETERS_NULL);
        Validator.notNull(approvalVO.getLinkId(), ErrorCode.INPUT_PARAMETERS_NULL);
        Validator.notNull(approvalVO.getApprovalType(), ErrorCode.INPUT_PARAMETERS_NULL);
        Validator.notNull(approvalVO.getResult(), ErrorCode.INPUT_PARAMETERS_NULL);
        UserDTO userDTO = userUtils.getUser(approvalVO.getToken());

        log.info(HEAD + "屠宰场审批调运单, 当前用户id:{}, 请求参数:{}", userDTO.getId(), JSON.toJSONString(approvalVO));

        Validator.isTrue(userDTO.getType().equals(UserTypeEnum.SLAUGHTER.getCode()), ErrorCode.NO_POWER_GET);
        Validator.isTrue(approvalVO.getApprovalType().equals(ApplicationTypeEnum.SLAUGHTER.getCode()), ErrorCode.APPLY_TYPE_ERROR);
        WaybillDTO waybillDTO = waybillService.getWaybillById(approvalVO.getLinkId());
        Validator.notNull(waybillDTO, ErrorCode.WAYBILL_INFO_EMPTY);
        Validator.isTrue(waybillDTO.getState().equals(WaybillStateEnum.WAYBILL_SLAUGHTER.getCode()), ErrorCode.ORDER_INFO_STATE_ERROR);

        Validator.isTrue(waybillDTO.getBuyerUserId().equals(userDTO.getId()), ErrorCode.NO_POWER_GET);

        ApplicationQuery applicationQuery = new ApplicationQuery();
        applicationQuery.setApplyUserId(userDTO.getId());
        applicationQuery.setSubmitUserId(waybillDTO.getSlaughterHouseId() != null && waybillDTO.getSlaughterHouseId() != 0 ? waybillDTO.getSlaughterHouseId() : waybillDTO.getBuyerUserId());
        applicationQuery.setType(ApplicationTypeEnum.SLAUGHTER.getCode());
        applicationQuery.setLinkId(waybillDTO.getId());
        ApplicationInfoDTO applicationInfoDTO = applicationInfoService.getApplicationInfoByQuery(applicationQuery);
        Validator.notNull(applicationInfoDTO, ErrorCode.APPLY_NULL);
        Validator.isTrue(applicationInfoDTO.getState().equals(ApplicationStateEnum.UNCHECK.getCode()), ErrorCode.APPLY_STATE_ERROR);


        if (approvalVO.getResult().equals(YesNoEnum.YES.getCode())) {
            applicationInfoDTO.setState(ApplicationStateEnum.PASS.getCode());
            waybillDTO.setState(WaybillStateEnum.UNCHECK.getCode());
            messageLoggingManager.messageHandling(waybillDTO.getSlaughterHouseId(), MessageEnum.WAYBILL_SLAUGHTER_ADOPT.getCode());
        } else {
            applicationInfoDTO.setState(ApplicationStateEnum.REJECT.getCode());
            waybillDTO.setState(WaybillStateEnum.WAYBILL_SLAUGHTER_REJECT.getCode());
            messageLoggingManager.messageHandling(waybillDTO.getSlaughterHouseId(), MessageEnum.WAYBILL_SLAUGHTER_REJECT.getCode());
        }

        applicationInfoService.updateApplicationInfo(applicationInfoDTO);
        waybillService.updateWaybill(waybillDTO);
        if (approvalVO.getResult().equals(YesNoEnum.YES.getCode())) {
            UserDTO slaughterHouse = userService.getUserById(waybillDTO.getSlaughterHouseId());
            ((WaybillManager) AopContext.currentProxy()).initApplication(waybillDTO, slaughterHouse);

            // 向养殖场和经纪人推送消息
            if (ObjectUtils.isNotEmpty(waybillDTO.getSalerUserId())) {
                messageLoggingManager.messageHandling(waybillDTO.getSalerUserId(), MessageEnum.WAYBILL_CREATE.getCode());
            }
            if (ObjectUtils.isNotEmpty(waybillDTO.getAgentUserId()) && waybillDTO.getAgentUserId() != 0) {
                messageLoggingManager.messageHandling(waybillDTO.getAgentUserId(), MessageEnum.WAYBILL_CREATE.getCode());
            }
        }
        return true;

    }
}



















