package cn.iocoder.yudao.module.order.service.order.impl;

import cn.iocoder.yudao.framework.apollo.core.event.Order.OrderApprovalTypeCheckEvent;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.dict.core.dto.DictDataRespDTO;
import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils;
import cn.iocoder.yudao.framework.i18n.core.I18nMessage;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.service.AbstractService;
import cn.iocoder.yudao.framework.mybatis.core.vo.PageVO;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.bpm.api.BpmCreateServiceFactory;
import cn.iocoder.yudao.module.bpm.enums.WorkFlowEmus;
import cn.iocoder.yudao.module.depository.dal.mysql.warehouse.WarehouseLineMapper;
import cn.iocoder.yudao.module.depository.dto.LogisticsInfoDto;
import cn.iocoder.yudao.module.ecw.dal.dataobject.currency.CurrencyDO;
import cn.iocoder.yudao.module.ecw.service.currency.CurrencyService;
import cn.iocoder.yudao.module.order.convert.order.OrderConvert;
import cn.iocoder.yudao.module.order.convert.orderFeeApplication.OrderFeeApplicationConvert;
import cn.iocoder.yudao.module.order.dal.dataobject.approval.OrderApprovalDO;
import cn.iocoder.yudao.module.order.dal.dataobject.order.OrderDO;
import cn.iocoder.yudao.module.order.dal.dataobject.orderFeeApplication.OrderFeeApplicationDO;
import cn.iocoder.yudao.module.order.dal.mysql.orderFeeApplication.OrderFeeApplicationMapper;
import cn.iocoder.yudao.module.order.enums.ApprovalResultStatusEnum;
import cn.iocoder.yudao.module.order.enums.OrderApprovalTypeEnum;
import cn.iocoder.yudao.module.order.enums.OrderApprovalTypeResultEnum;
import cn.iocoder.yudao.module.order.service.approval.OrderApprovalService;
import cn.iocoder.yudao.module.order.service.order.OrderBusinessService;
import cn.iocoder.yudao.module.order.service.order.OrderFeeApplicationService;
import cn.iocoder.yudao.module.order.service.order.OrderQueryService;
import cn.iocoder.yudao.module.order.service.order.OrderService;
import cn.iocoder.yudao.module.order.vo.order.ApplyInfoVO;
import cn.iocoder.yudao.module.order.vo.order.OrderBackVO;
import cn.iocoder.yudao.module.order.vo.orderFeeApplication.*;
import cn.iocoder.yudao.module.product.dto.FeeDto;
import cn.iocoder.yudao.module.system.enums.DictTypeConstants;
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
import cn.iocoder.yudao.module.wealth.dal.dataobject.receivable.ReceivableDO;
import cn.iocoder.yudao.module.wealth.service.receivable.ReceivableService;
import cn.iocoder.yudao.module.wealth.vo.receivable.ReceivableCreateReqVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Objects;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.order.enums.ErrorCodeConstants.*;
import static cn.iocoder.yudao.module.order.enums.OrderApprovalTypeEnum.ORDER_UPDATE;
import static cn.iocoder.yudao.module.order.enums.OrderApprovalTypeEnum.expense_apply;

/**
 * 订单费用申请 Service 实现类
 *
 * @author 系统管理员
 */
@Service
@Validated
public class OrderFeeApplicationServiceImpl extends AbstractService<OrderFeeApplicationMapper, OrderFeeApplicationDO> implements OrderFeeApplicationService {

    @Resource
    private OrderFeeApplicationMapper feeApplicationMapper;

    @Resource
    private BpmCreateServiceFactory bpmCreateServiceFactory;

    @Resource
    private ReceivableService receivableService;

    @Resource
    @Lazy
    private OrderService orderService;
    @Resource
    @Lazy
    private OrderBusinessService orderBusinessService;
    @Resource
    @Lazy
    private OrderQueryService orderQueryService;

    @Resource
    private WarehouseLineMapper warehouseLineMapper;

    @Resource
    private AdminUserService adminUserService;

    @Resource
    private CurrencyService currencyService;
    @Resource
    private OrderApprovalService orderApprovalService;
    @Resource
    private ApplicationContext applicationContext;

    @Transactional
    @Override
    public Long createFeeApplication(OrderFeeApplicationCreateReqVO createReqVO) throws Exception {
        //该订单是否有待处理异常或待处理审核则抛出异常
//        orderService.throwPendingExceptionOrProcessingApproval(createReqVO.getOrderId());
        //有未处理的审核单
//        Integer waitApprovalCount = orderService.getAllProcessingApprovalCount(createReqVO.getOrderId());
//        OrderBackVO order = orderService.getOrder(createReqVO.getOrderId());
//        if (waitApprovalCount > 0) {
//            throw exception(ORDER_HAS_PROCESSING_APPROVAL, order.getOrderNo());
//        }

        Long aLong = feeApplicationMapper.selectCount(new LambdaQueryWrapperX<OrderFeeApplicationDO>()
                .eq(OrderFeeApplicationDO::getOrderId, createReqVO.getOrderId())
                .eq(OrderFeeApplicationDO::getStatus, 1));
        if (aLong != null && aLong > 0L) {
            throw exception(ORDER_FEE_APPLICATION_EXIST);
        }
        // 插入
        OrderFeeApplicationDO feeApplication = OrderFeeApplicationConvert.INSTANCE.convert(createReqVO);
        feeApplicationMapper.insert(feeApplication);
        // 返回
        Long userId = SecurityFrameworkUtils.getLoginUserId();
        //创建审批流
        OrderDO orderDO = orderService.selectOne(OrderDO::getOrderId, createReqVO.getOrderId());
        String bpmProcessId = bpmCreateServiceFactory.createBmp(userId, feeApplication.getId(), WorkFlowEmus.ORDER_FREE_APPLY.getKey(), orderDO.getOrderNo(), createReqVO.getCopyUserId());
        orderService.updateStatus(orderDO.getOrderId(), null, null, null, null, null, OrderApprovalTypeResultEnum.expense_apply_processing.getType(), OrderApprovalTypeResultEnum.expense_apply_processing.getDesc());
        feeApplication.setBpmProcessId(bpmProcessId);
        feeApplicationMapper.updateById(feeApplication);
        DictDataRespDTO dictDataFromCache = DictFrameworkUtils.getDictDataFromCache(DictTypeConstants.RECEIVABLE_FEE_TYPE, String.valueOf(createReqVO.getFeeType()));
        CurrencyDO currency = currencyService.getCurrency(createReqVO.getApplicationFeeCurrency());
        List<ApplyInfoVO> list = new ArrayList<>();
        ApplyInfoVO applyInfoVO = new ApplyInfoVO();
        applyInfoVO.setName("申请费用名称");
        applyInfoVO.setNewValue(I18nMessage.getLang() == 0 ? dictDataFromCache.getLabel() : dictDataFromCache.getLabelEn());
        ApplyInfoVO applyInfoVO1 = new ApplyInfoVO();
        applyInfoVO1.setName("金额");
        applyInfoVO1.setNewValue(String.valueOf(createReqVO.getApplicationFee().doubleValue()));
        ApplyInfoVO applyInfoVO2 = new ApplyInfoVO();
        applyInfoVO2.setName("币种");
        applyInfoVO2.setNewValue(I18nMessage.getLang() == 0 ? currency.getTitleZh() : currency.getTitleEn());
        list.add(applyInfoVO);
        list.add(applyInfoVO1);
        list.add(applyInfoVO2);
        orderBusinessService.addOrderOperateLog(createReqVO.getOrderId(), "", "提交费用申请", list);
        return feeApplication.getId();
    }

    @Override
    @Transactional
    public void createFeeBatchApplication(OrderFeeBatchApplicationCreateReqVO createReqVO) {
//        OrderDO orderDO = orderService.getById(createReqVO.getOrderId());
//        if (orderDO.getAuditType() != 0) {
//            throw exception(ORDER_HAS_PROCESSING_APPROVAL, orderDO.getOrderNo());
//        }
//        LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapperX<OrderApprovalDO>()
//                .eq(OrderApprovalDO::getOrderId, createReqVO.getOrderId())
//                .eq(OrderApprovalDO::getType, expense_apply.getValue())
//                .eq(OrderApprovalDO::getStatus, ApprovalResultStatusEnum.processing.getValue());
//        if (orderApprovalService.count(lambdaQueryWrapper) > 0) {
//            throw exception(ORDER_FEE_APPLICATION_EXIST);
//        }
        OrderApprovalTypeCheckEvent approvalTypeCheckEvent = new OrderApprovalTypeCheckEvent(createReqVO.getOrderId(), null, expense_apply.getValue(), null, false);
        applicationContext.publishEvent(approvalTypeCheckEvent);
        if (approvalTypeCheckEvent.getResult()) {
            throw exception(ORDER_IS_APPROVAL_IN_PROCESS);
        }

        // 批量插入费用
        List<OrderFeeApplicationCreateReqVO> baseVOList = createReqVO.getOrderFeeApplicationCreateReqVOList();

        List<OrderFeeApplicationDO> batchFeeList = new ArrayList<>();
        for (OrderFeeApplicationCreateReqVO vo : baseVOList) {
            OrderFeeApplicationDO feeApplication = OrderFeeApplicationConvert.INSTANCE.convert(vo);
            feeApplicationMapper.insert(feeApplication);
            batchFeeList.add(feeApplication);
        }

        //创建审批单，发起流程
        OrderApprovalDO orderApprovalDO = new OrderApprovalDO();
        orderApprovalDO.setFollowUpSalesmanId(String.valueOf(SecurityFrameworkUtils.getLoginUserId()));
        orderApprovalDO.setOrderId(createReqVO.getOrderId());
        //批量费用申请
        orderApprovalDO.setType(expense_apply.getValue());
        orderApprovalDO.setStatus(ApprovalResultStatusEnum.processing.getValue());
        Long bpmProcessId = orderApprovalService.applyAndCreate(orderApprovalDO, WorkFlowEmus.ORDER_BATCH_FREE_APPLY, createReqVO.getCopyUserId());


        //创建审批流
        OrderDO orderDO = orderService.selectOne(OrderDO::getOrderId, createReqVO.getOrderId());

        orderService.updateStatus(orderDO.getOrderId(), null, null, null, null, null, OrderApprovalTypeResultEnum.expense_apply_processing.getType(), OrderApprovalTypeResultEnum.expense_apply_processing.getDesc());

        //更新费用列表对应的流程申请ID
        for (OrderFeeApplicationDO feeApplication : batchFeeList) {
            feeApplication.setBatchBpmBusinessId(String.valueOf(bpmProcessId));
            feeApplication.setStatus(ApprovalResultStatusEnum.processing.getValue());
            feeApplicationMapper.updateById(feeApplication);
        }
    }

    @Override
    public void updateFeeApplication(OrderFeeApplicationUpdateReqVO updateReqVO) {

        OrderDO orderDO = orderService.getById(updateReqVO.getOrderId());
        OrderApprovalTypeCheckEvent approvalTypeCheckEvent = new OrderApprovalTypeCheckEvent(updateReqVO.getOrderId(), null, expense_apply.getValue(), null, false);
        applicationContext.publishEvent(approvalTypeCheckEvent);
        if (approvalTypeCheckEvent.getResult()) {
            throw exception(ORDER_HAS_PROCESSING_APPROVAL, orderDO.getOrderNo());
        }
        OrderFeeApplicationDO orderFeeApplicationDOOld = feeApplicationMapper.selectById(updateReqVO.getId());
        // 校验存在
        if (orderFeeApplicationDOOld == null) {
            throw exception(FEE_APPLICATION_NOT_EXISTS);
        }
        // 更新
        OrderFeeApplicationDO updateObj = OrderFeeApplicationConvert.INSTANCE.convert(updateReqVO);
        Long userId = SecurityFrameworkUtils.getLoginUserId();
        String bpmProcessId = bpmCreateServiceFactory.createBmp(userId, updateObj.getId(), WorkFlowEmus.ORDER_FREE_APPLY.getKey(), orderDO.getOrderNo(), updateReqVO.getCopyUserId());
        Integer auditType = OrderApprovalTypeResultEnum.expense_apply_processing.getType();
        orderService.updateStatus(orderDO.getOrderId(), null, null, null, null, null, auditType, OrderApprovalTypeResultEnum.expense_apply_processing.getDesc());
        updateObj.setBpmProcessId(bpmProcessId);
        feeApplicationMapper.updateById(updateObj);
        DictDataRespDTO dictDataFromCacheOld = DictFrameworkUtils.getDictDataFromCache(DictTypeConstants.RECEIVABLE_FEE_TYPE, String.valueOf(orderFeeApplicationDOOld.getFeeType()));
        DictDataRespDTO dictDataFromCache = DictFrameworkUtils.getDictDataFromCache(DictTypeConstants.RECEIVABLE_FEE_TYPE, String.valueOf(updateReqVO.getFeeType()));
        CurrencyDO currency = currencyService.getCurrency(updateReqVO.getApplicationFeeCurrency());
        CurrencyDO currencyOld = currencyService.getCurrency(orderFeeApplicationDOOld.getApplicationFeeCurrency());
        List<ApplyInfoVO> list = new ArrayList<>();
        ApplyInfoVO applyInfoVO = new ApplyInfoVO();
        applyInfoVO.setName("申请费用名称");
        applyInfoVO.setOrgValue(I18nMessage.getLang() == 0 ? dictDataFromCacheOld.getLabel() : dictDataFromCacheOld.getLabelEn());
        applyInfoVO.setNewValue(I18nMessage.getLang() == 0 ? dictDataFromCache.getLabel() : dictDataFromCache.getLabelEn());
        ApplyInfoVO applyInfoVO1 = new ApplyInfoVO();
        applyInfoVO1.setName("金额");
        applyInfoVO1.setOrgValue(String.valueOf(orderFeeApplicationDOOld.getApplicationFee().doubleValue()));
        applyInfoVO1.setNewValue(String.valueOf(updateReqVO.getApplicationFee().doubleValue()));
        ApplyInfoVO applyInfoVO2 = new ApplyInfoVO();
        applyInfoVO2.setName("币种");
        applyInfoVO2.setOrgValue(I18nMessage.getLang() == 0 ? currencyOld.getTitleZh() : currencyOld.getTitleEn());
        applyInfoVO2.setNewValue(I18nMessage.getLang() == 0 ? currency.getTitleZh() : currency.getTitleEn());
        list.add(applyInfoVO);
        list.add(applyInfoVO1);
        list.add(applyInfoVO2);
        orderBusinessService.addOrderOperateLog(updateObj.getOrderId(), "", "费用修改提交审核", list);
    }

    @Override
    public void deleteFeeApplication(Long id) {
        OrderFeeApplicationDO orderFeeApplicationDO = feeApplicationMapper.selectById(id);
        // 校验存在
        if (orderFeeApplicationDO == null) {
            throw exception(FEE_APPLICATION_NOT_EXISTS);
        }
        // 当费用金额为0时，可以不经审批直接删除
        // 判断金额是否为0
        if (orderFeeApplicationDO.getApplicationFee().compareTo(BigDecimal.ZERO) != 0){
            throw exception(FEE_APPLICATION_NOT_IS_ZERO);
        }
        // 删除可能的应收单
        if (orderFeeApplicationDO.getReceivableId() != null &&
                orderFeeApplicationDO.getReceivableId() > 0) {
            long idTemp = (long) orderFeeApplicationDO.getReceivableId();
            ReceivableDO rDo = receivableService.getReceivable(idTemp);
            if(Objects.nonNull(rDo)){
                receivableService.removeById(rDo.getId());
            }
        }
        // 删除费用申请记录
        feeApplicationMapper.deleteById(id);
        CurrencyDO currency = currencyService.getCurrency(orderFeeApplicationDO.getApplicationFeeCurrency());
        String currencyName = Objects.nonNull(currency) ? (I18nMessage.getLang() == 0 ? currency.getTitleZh() : currency.getTitleEn()) : (I18nMessage.getLang() == 0 ? "未知" : "NUKNOWN");
        DictDataRespDTO dictDataFromCache = DictFrameworkUtils.getDictDataFromCache(DictTypeConstants.RECEIVABLE_FEE_TYPE, String.valueOf(orderFeeApplicationDO.getFeeType()));
        List<ApplyInfoVO> list = new ArrayList<>();
        ApplyInfoVO applyInfoVO = new ApplyInfoVO();
        applyInfoVO.setName("申请费用名称");
        applyInfoVO.setNewValue(I18nMessage.getLang() == 0 ? dictDataFromCache.getLabel() : dictDataFromCache.getLabelEn());
        list.add(applyInfoVO);
        applyInfoVO = new ApplyInfoVO();
        applyInfoVO.setName("金额");
        applyInfoVO.setNewValue(String.valueOf(orderFeeApplicationDO.getApplicationFee().doubleValue()));
        list.add(applyInfoVO);
        applyInfoVO = new ApplyInfoVO();
        applyInfoVO.setName("币种");
        applyInfoVO.setNewValue(currencyName);
        list.add(applyInfoVO);
        orderBusinessService.addOrderOperateLog(orderFeeApplicationDO.getOrderId(), "订单操作", "费用申请删除", list);
    }

    private void validateFeeApplicationExists(Long id) {
        if (feeApplicationMapper.selectById(id) == null) {
            throw exception(FEE_APPLICATION_NOT_EXISTS);
        }
    }

    @Override
    public OrderFeeApplicationDO getFeeApplication(Long id) {
        return feeApplicationMapper.selectById(id);
    }

    @Override
    public List<OrderFeeApplicationDO> getFeeApplicationList(Collection<Long> ids) {
        return feeApplicationMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<OrderFeeApplicationDO> getFeeApplicationPage(OrderFeeApplicationQueryVO query, PageVO page) {
        return feeApplicationMapper.selectPage(page, query);
    }

    @Override
    public List<OrderFeeApplicationDO> getFeeApplicationList(OrderFeeApplicationQueryVO query) {
        return feeApplicationMapper.selectList(query);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateFeeApproveResult(String id, int result) {
        OrderFeeApplicationDO orderFeeApplicationDO =
                feeApplicationMapper.selectById(id);
        if (orderFeeApplicationDO != null) {
            orderFeeApplicationDO.setStatus(result);
            feeApplicationMapper.updateById(orderFeeApplicationDO);
            List<FeeDto> feeDtos = new ArrayList<>();
            if (result == 2) {
                OrderBackVO order = orderQueryService.getOrder(orderFeeApplicationDO.getOrderId());
                //生成应收
                DictDataRespDTO dictDto = DictFrameworkUtils.getDictDataFromCache("receivable_fee_type", String.valueOf(orderFeeApplicationDO.getFeeType()));
                //修复应收款记录不存在的BUG,
                //添加应收款记录是否存在的判断
                ReceivableDO rDo = null;
                if (orderFeeApplicationDO.getReceivableId() != null &&
                        orderFeeApplicationDO.getReceivableId() > 0) {
                    long idTemp = (long) orderFeeApplicationDO.getReceivableId();
                    rDo = receivableService.getReceivable(idTemp);
                }
                //end  修复应收款记录不存在的BUG

                if (orderFeeApplicationDO.getReceivableId() != null &&
                        orderFeeApplicationDO.getReceivableId() > 0 &&
                        rDo != null) {
                    ReceivableDO receivableDO = new ReceivableDO();
                    //orderFeeApplicationDO 审批信息关联的应收款ID
                    // 添加的注释
                    receivableDO.setId(Long.valueOf(orderFeeApplicationDO.getReceivableId()));
                    receivableDO.setTitleZh(dictDto.getLabel());
                    receivableDO.setTitleEn(dictDto.getLabelEn());
                    receivableDO.setOrderId(orderFeeApplicationDO.getOrderId());
                    receivableDO.setOrderNo(order.getOrderNo());
                    receivableDO.setTotalAmount(orderFeeApplicationDO.getApplicationFee());
                    receivableDO.setCollectionType(orderFeeApplicationDO.getPayType());
                    receivableDO.setUnitPrice(orderFeeApplicationDO.getApplicationFee());
                    receivableDO.setCurrencyId(Long.valueOf(orderFeeApplicationDO.getApplicationFeeCurrency()));
                    receivableDO.setFeeType(orderFeeApplicationDO.getFeeType());
                    receivableDO.setIsPayAdvance(orderFeeApplicationDO.getPayType() == 4 ? 0 : 1);
                    receivableDO.setState(orderFeeApplicationDO.getReceiveFlag());
                    receivableDO.setPaymentUser(String.valueOf(order.getDrawee() != 3 ? order.getDrawee() : orderQueryService.customDrawee(OrderConvert.INSTANCE.convert(order), orderFeeApplicationDO.getFeeType())));//6待修改
                    receivableDO.setFeeSource(2);
                    receivableDO.setAuthor(orderFeeApplicationDO.getApplicationAuthor());
                    receivableDO.setRemark(orderFeeApplicationDO.getRemarks());
                    //应收款此处报应收款不存在的BUG
                    receivableService.updateReceivableById(receivableDO);
                } else {
                    ReceivableCreateReqVO receivableCreateReqVO =
                            new ReceivableCreateReqVO();
                    receivableCreateReqVO.setTitleZh(dictDto.getLabel());
                    receivableCreateReqVO.setTitleEn(dictDto.getLabelEn());
                    receivableCreateReqVO.setOrderId(orderFeeApplicationDO.getOrderId());
                    receivableCreateReqVO.setOrderNo(order.getOrderNo());
                    receivableCreateReqVO.setTotalAmount(orderFeeApplicationDO.getApplicationFee());
                    receivableCreateReqVO.setUnitPrice(orderFeeApplicationDO.getApplicationFee());
                    receivableCreateReqVO.setCollectionType(orderFeeApplicationDO.getPayType());
                    receivableCreateReqVO.setCurrencyId(Long.valueOf(orderFeeApplicationDO.getApplicationFeeCurrency()));
                    receivableCreateReqVO.setFeeType(orderFeeApplicationDO.getFeeType());
                    receivableCreateReqVO.setIsPayAdvance(orderFeeApplicationDO.getPayType() == 4 ? 0 : 1);
                    receivableCreateReqVO.setState(orderFeeApplicationDO.getReceiveFlag());
                    receivableCreateReqVO.setPaymentUser(String.valueOf(order.getDrawee() != 3 ? order.getDrawee() : orderQueryService.customDrawee(OrderConvert.INSTANCE.convert(order), orderFeeApplicationDO.getFeeType())));//6待修改
                    receivableCreateReqVO.setFeeSource(2);
                    receivableCreateReqVO.setAuthor(orderFeeApplicationDO.getApplicationAuthor());
                    receivableCreateReqVO.setRemark(orderFeeApplicationDO.getRemarks());

                    Long receivableId = receivableService.createReceivable(receivableCreateReqVO);
                    //把创建的应收款信息关联到审批主表中
                    orderFeeApplicationDO.setReceivableId(receivableId.intValue());
                }

                feeApplicationMapper.updateById(orderFeeApplicationDO);
                FeeDto feeDto = new FeeDto();
                feeDto.setFeeType(orderFeeApplicationDO.getFeeType());
                feeDto.setAmount(orderFeeApplicationDO.getApplicationFee());
                feeDto.setCurrencyId(orderFeeApplicationDO.getApplicationFeeCurrency());
                feeDtos.add(feeDto);
                orderService.addOrderOtherFee(orderFeeApplicationDO.getOrderId(), feeDtos);
                orderService.updateStatus(orderFeeApplicationDO.getOrderId(), null, null, null, null, null, 0, OrderApprovalTypeResultEnum.expense_apply_pass.getDesc());
//                orderBusinessService.addOrderOperateLog(orderFeeApplicationDO.getOrderId(),"","提交费用申请成功","");
            } else if (result == 4) {
                feeApplicationMapper.deleteById(id);
                orderService.updateStatus(orderFeeApplicationDO.getOrderId(), null, null, null, null, null, 0, OrderApprovalTypeResultEnum.expense_apply_cancel.getDesc());
                //bpmCreateServiceFactory.cancelBmpById(SecurityFrameworkUtils.getLoginUserId(),orderFeeApplicationDO.getBpmProcessId(),null);
//                orderBusinessService.addOrderOperateLog(orderFeeApplicationDO.getOrderId(),"","取消费用申请","");
            } else if (result == 3) {
                orderService.updateStatus(orderFeeApplicationDO.getOrderId(), null, null, null, null, null, 0, OrderApprovalTypeResultEnum.expense_apply_reject.getDesc());
//                orderBusinessService.addOrderOperateLog(orderFeeApplicationDO.getOrderId(),"","提交费用申请失败","");
            }
        }
    }

    /*
    //result
    1, "处理中",
    2, "通过",
    3, "不通过",
    4, "取消"
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateFeeApproveBatchResult(String id, int result) {
        OrderApprovalDO orderApprovalDO = orderApprovalService.getApproval(Long.parseLong(id));
        if (orderApprovalDO != null) {
            orderApprovalDO.setStatus(result);
            orderApprovalService.updateById(orderApprovalDO);
            if (result == ApprovalResultStatusEnum.pass.getValue()) {
                List<FeeDto> feeDtos = new ArrayList<>();
                OrderBackVO order = orderQueryService.getOrder(orderApprovalDO.getOrderId());
                LambdaQueryWrapper<OrderFeeApplicationDO> lambdaQueryWrapper = new LambdaQueryWrapper();
                lambdaQueryWrapper.eq(OrderFeeApplicationDO::getOrderId, orderApprovalDO.getOrderId());
                lambdaQueryWrapper.eq(OrderFeeApplicationDO::getBatchBpmBusinessId, orderApprovalDO.getOrderApprovalId());
                List<OrderFeeApplicationDO> batchFeeList = this.list(lambdaQueryWrapper);
                for (OrderFeeApplicationDO feeApplicationDO : batchFeeList) {
                    //生成应收
                    DictDataRespDTO dictDto = DictFrameworkUtils.getDictDataFromCache("receivable_fee_type", String.valueOf(feeApplicationDO.getFeeType()));
                    if (feeApplicationDO.getReceivableId() != null && feeApplicationDO.getReceivableId() > 0) {
                        ReceivableDO receivableDO = new ReceivableDO();
                        //应收款ID
                        receivableDO.setId(Long.valueOf(feeApplicationDO.getReceivableId()));
                        receivableDO.setTitleZh(dictDto.getLabel());
                        receivableDO.setTitleEn(dictDto.getLabelEn());
                        receivableDO.setOrderId(feeApplicationDO.getOrderId());
                        receivableDO.setOrderNo(order.getOrderNo());
                        receivableDO.setTotalAmount(feeApplicationDO.getApplicationFee());
                        receivableDO.setCollectionType(feeApplicationDO.getPayType());
                        receivableDO.setUnitPrice(feeApplicationDO.getApplicationFee());
                        receivableDO.setCurrencyId(Long.valueOf(feeApplicationDO.getApplicationFeeCurrency()));
                        receivableDO.setFeeType(feeApplicationDO.getFeeType());
                        receivableDO.setIsPayAdvance(feeApplicationDO.getPayType() == 4 ? 0 : 1);
                        receivableDO.setState(feeApplicationDO.getReceiveFlag());
                        receivableDO.setPaymentUser(String.valueOf(order.getDrawee() != 3 ? order.getDrawee() : orderQueryService.customDrawee(OrderConvert.INSTANCE.convert(order), feeApplicationDO.getFeeType())));//6待修改
                        receivableDO.setFeeSource(2);
                        receivableDO.setAuthor(feeApplicationDO.getApplicationAuthor());
                        receivableDO.setRemark(feeApplicationDO.getRemarks());
                        //订单费用申请，是申请付给我们的费用，
                        // 所以要更新应收款信息
                        receivableService.updateReceivableById(receivableDO);
                    } else {
                        ReceivableCreateReqVO receivableCreateReqVO = new ReceivableCreateReqVO();
                        receivableCreateReqVO.setTitleZh(dictDto.getLabel());
                        receivableCreateReqVO.setTitleEn(dictDto.getLabelEn());
                        receivableCreateReqVO.setOrderId(feeApplicationDO.getOrderId());
                        receivableCreateReqVO.setOrderNo(order.getOrderNo());
                        receivableCreateReqVO.setTotalAmount(feeApplicationDO.getApplicationFee());
                        receivableCreateReqVO.setUnitPrice(feeApplicationDO.getApplicationFee());
                        receivableCreateReqVO.setCollectionType(feeApplicationDO.getPayType());
                        receivableCreateReqVO.setCurrencyId(Long.valueOf(feeApplicationDO.getApplicationFeeCurrency()));
                        receivableCreateReqVO.setFeeType(feeApplicationDO.getFeeType());
                        receivableCreateReqVO.setIsPayAdvance(feeApplicationDO.getPayType() == 4 ? 0 : 1);
                        receivableCreateReqVO.setState(feeApplicationDO.getReceiveFlag());
                        receivableCreateReqVO.setPaymentUser(String.valueOf(order.getDrawee() != 3 ? order.getDrawee() : orderQueryService.customDrawee(OrderConvert.INSTANCE.convert(order), feeApplicationDO.getFeeType())));//6待修改
                        receivableCreateReqVO.setFeeSource(2);
                        receivableCreateReqVO.setAuthor(feeApplicationDO.getApplicationAuthor());
                        receivableCreateReqVO.setRemark(feeApplicationDO.getRemarks());
                        Long receivableId = receivableService.createReceivable(receivableCreateReqVO);
                        feeApplicationDO.setReceivableId(receivableId.intValue());
                    }
                    feeApplicationDO.setStatus(ApprovalResultStatusEnum.pass.getValue());
                    feeApplicationMapper.updateById(feeApplicationDO);
                    FeeDto feeDto = new FeeDto();
                    feeDto.setFeeType(feeApplicationDO.getFeeType());
                    feeDto.setAmount(feeApplicationDO.getApplicationFee());
                    feeDto.setCurrencyId(feeApplicationDO.getApplicationFeeCurrency());
                    feeDtos.add(feeDto);

                }

                orderService.addOrderOtherFee(orderApprovalDO.getOrderId(), feeDtos);
                orderService.updateStatus(orderApprovalDO.getOrderId(), null, null, null, null, null, 0, OrderApprovalTypeResultEnum.expense_apply_pass.getDesc());
            }

            if (result == ApprovalResultStatusEnum.reject.getValue()) {
                LambdaUpdateWrapper<OrderFeeApplicationDO> lambdaUpdateWrapper = new LambdaUpdateWrapper();
                lambdaUpdateWrapper.eq(OrderFeeApplicationDO::getOrderId, orderApprovalDO.getOrderId());
                lambdaUpdateWrapper.eq(OrderFeeApplicationDO::getBatchBpmBusinessId, orderApprovalDO.getOrderApprovalId());
                lambdaUpdateWrapper.set(OrderFeeApplicationDO::getStatus, ApprovalResultStatusEnum.reject.getValue());
                this.update(lambdaUpdateWrapper);
                orderService.updateStatus(orderApprovalDO.getOrderId(), null, null, null, null, null, 0, OrderApprovalTypeResultEnum.expense_apply_reject.getDesc());
            }

            if (result == ApprovalResultStatusEnum.cancel.getValue()) {
                LambdaQueryWrapper<OrderFeeApplicationDO> lambdaQueryWrapper = new LambdaQueryWrapper();
                lambdaQueryWrapper.eq(OrderFeeApplicationDO::getOrderId, orderApprovalDO.getOrderId());
                lambdaQueryWrapper.eq(OrderFeeApplicationDO::getBatchBpmBusinessId, orderApprovalDO.getOrderApprovalId());
                this.remove(lambdaQueryWrapper);
                orderService.updateStatus(orderApprovalDO.getOrderId(), null, null, null, null, null, 0, OrderApprovalTypeResultEnum.expense_apply_cancel.getDesc());
            }
        }
    }

    @Override
    public List<OrderFeeApplicationDO> getFeeApplicationListByOrderId(Long orderId) {
        List<OrderFeeApplicationDO> feeApplicationList = feeApplicationMapper.getFeeApplicationListByOrderId(orderId);
        feeApplicationList.stream().forEach(item -> {
            item.setApplicationAuthor(adminUserService.getUser(Long.valueOf(item.getCreator())).getUsername());
            if (item.getReceivableId() != null && item.getReceivableId() != 0) {
                ReceivableDO receivable = receivableService.getReceivable(Long.valueOf(item.getReceivableId()));
                if (receivable != null) {
                    item.setReceiveFlag(receivable.getState());
                } else {
                    item.setReceiveFlag(0);
                }
            } else {
                item.setReceiveFlag(0);
            }
        });
        return feeApplicationList;
    }

    @Override
    public OrderFeeApplicationBackVO getOrderByProcessId(String processId) {
        OrderFeeApplicationDO orderFeeApplicationDO = feeApplicationMapper.selectOne(OrderFeeApplicationDO::getBpmProcessId, processId);
        OrderFeeApplicationBackVO convert = OrderFeeApplicationConvert.INSTANCE.convert(orderFeeApplicationDO);
        if (orderFeeApplicationDO != null) {
            OrderBackVO order = orderQueryService.getOrder(orderFeeApplicationDO.getOrderId());
            LogisticsInfoDto startInfoAndDestInfoByLineId = warehouseLineMapper.getStartInfoAndDestInfoByLineId(order.getLineId());
            convert.setStartWarehouse(startInfoAndDestInfoByLineId.getStartTitleZh());
            convert.setDestWarehouse(startInfoAndDestInfoByLineId.getDestTitleZh());
            convert.setOrderBackVO(order);
        }
        return convert;
    }

    @Override
    public List<OrderFeeApplicationBackVO> getBatchFeeByProcessId(String processId) {
        List<OrderFeeApplicationDO> orderFeeApplicationDOList = feeApplicationMapper.selectList(OrderFeeApplicationDO::getBatchBpmBusinessId, processId);
        return OrderFeeApplicationConvert.INSTANCE.convertList(orderFeeApplicationDOList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelFeeApplication(OrderFeeApplicationUpdateReqVO orderFeeApplicationUpdateReqVO) {
        //只管取消,这些东西应该在回调里面处理
        //OrderFeeApplicationDO orderFeeApplicationDO = feeApplicationMapper.selectOne(OrderFeeApplicationDO::getBpmProcessId, orderFeeApplicationUpdateReqVO.getBpmProcessId());
        //feeApplicationMapper.delete(new LambdaQueryWrapperX<OrderFeeApplicationDO>().eq(OrderFeeApplicationDO::getBpmProcessId, orderFeeApplicationUpdateReqVO.getBpmProcessId()));
        bpmCreateServiceFactory.cancelBmpById(SecurityFrameworkUtils.getLoginUserId(), orderFeeApplicationUpdateReqVO.getBpmProcessId(), orderFeeApplicationUpdateReqVO.getHuifu());
        //Integer auditType = OrderApprovalTypeResultEnum.expense_apply_cancel.getType();
        //orderService.updateStatus(orderFeeApplicationDO.getOrderId(), null, null, null, null, null, 0, OrderApprovalTypeResultEnum.expense_apply_cancel.getDesc());
//        orderBusinessService.addOrderOperateLog(orderFeeApplicationUpdateReqVO.getOrderId(),"","取消费用申请","");
    }
}
