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

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

import cn.hutool.core.collection.CollectionUtil;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
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.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.dal.dataobject.order.OrderDO;
import cn.iocoder.yudao.module.order.service.order.OrderBusinessService;
import cn.iocoder.yudao.module.order.service.order.OrderQueryService;
import cn.iocoder.yudao.module.order.service.order.OrderService;
import cn.iocoder.yudao.module.order.service.order.OrderSpecialNeedService;
import cn.iocoder.yudao.module.order.vo.order.ApplyInfoVO;
import cn.iocoder.yudao.module.order.vo.order.OrderBackVO;
import cn.iocoder.yudao.module.product.dto.FeeDto;
import cn.iocoder.yudao.module.system.enums.DictTypeConstants;
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.update.LambdaUpdateWrapper;
import org.apache.commons.lang.StringUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import cn.iocoder.yudao.framework.mybatis.core.vo.PageVO;
import cn.iocoder.yudao.framework.mybatis.core.service.AbstractService;
import cn.iocoder.yudao.module.order.vo.orderSpecialNeed.*;
import cn.iocoder.yudao.module.order.dal.dataobject.orderSpecialNeed.OrderSpecialNeedDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.order.convert.orderSpecialNeed.OrderSpecialNeedConvert;
import cn.iocoder.yudao.module.order.dal.mysql.orderSpecialNeed.OrderSpecialNeedMapper;

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

/**
 * 特需 Service 实现类
 *
 * @author 系统管理员
 */
@Service
@Validated
public class OrderSpecialNeedServiceImpl extends AbstractService<OrderSpecialNeedMapper, OrderSpecialNeedDO> implements OrderSpecialNeedService {

    @Resource
    private OrderSpecialNeedMapper orderSpecialNeedMapper;

    @Resource
    private ReceivableService receivableService;

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

    @Resource
    @Lazy
    private OrderQueryService orderQueryService;

    @Resource
    private CurrencyService currencyService;

    @Override
    public void createOrderSpecialNeed(List<OrderSpecialNeedCreateReqVO> createReqVOList) {
        createOrderSpecialNeed(createReqVOList, true);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createOrderSpecialNeed(List<OrderSpecialNeedCreateReqVO> createReqVOList, boolean flag) {
        List<ApplyInfoVO> list = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(createReqVOList)) {
            //该订单是否有待处理异常或待处理审核则抛出异常
            if (flag) {
                orderQueryService.throwPendingExceptionOrProcessingApproval(createReqVOList.get(0).getOrderId());
                checkWarehouseIn(createReqVOList.get(0).getOrderId());
            }
        }

        // 插入特需
        StringBuffer stringBuffer = new StringBuffer();
        if (createReqVOList != null && createReqVOList.size() > 0) {
            for (OrderSpecialNeedCreateReqVO reqVO : createReqVOList) {
                Long aLong = orderSpecialNeedMapper.selectCount(new LambdaQueryWrapperX<OrderSpecialNeedDO>()
                        .eq(OrderSpecialNeedDO::getOrderId, reqVO.getOrderId())
                        .eq(OrderSpecialNeedDO::getAdvanceType, reqVO.getAdvanceType()));
                if (aLong > 0L) {
                    throw exception(ORDER_SPECIAL_NEED_IS_EXISTS);
                }
                DictDataRespDTO dictDataFromCache = DictFrameworkUtils.getDictDataFromCache(DictTypeConstants.ORDER_SPECIAL_NEED, String.valueOf(reqVO.getAdvanceType()));
                CurrencyDO currency = currencyService.getCurrency(reqVO.getTransCurrency());
                ApplyInfoVO applyInfoVO = new ApplyInfoVO();
                applyInfoVO.setName("新增特需名称");
                applyInfoVO.setNewValue(I18nMessage.getLang() == 0 ? dictDataFromCache.getLabel() : dictDataFromCache.getLabelEn());
                ApplyInfoVO applyInfoVO1 = new ApplyInfoVO();
                applyInfoVO1.setName("金额");
                applyInfoVO1.setNewValue(reqVO.getTransFee() == null ? "0" : String.valueOf(reqVO.getTransFee().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);
                OrderSpecialNeedDO orderSpecialNeed = OrderSpecialNeedConvert.INSTANCE.convert(reqVO);
                orderSpecialNeedMapper.insert(orderSpecialNeed);
                stringBuffer.append(reqVO.getAdvanceType() + ",");
            }
        }
        changeOrderAdvanceType(OrderSpecialNeedConvert.INSTANCE.convert(createReqVOList.get(0)), stringBuffer.deleteCharAt(stringBuffer.length() - 1).toString());

        List<FeeDto> feeDtos = new ArrayList<>();
        createReqVOList.stream().forEach(item -> {
            FeeDto feeDto = new FeeDto();
            feeDto.setFeeType(Integer.valueOf(item.getAdvanceType()));
            feeDto.setAmount(item.getTransFee());
            feeDto.setCurrencyId(item.getTransCurrency());
            feeDtos.add(feeDto);
        });
        orderService.addOrderOtherFee(createReqVOList.get(0).getOrderId(), feeDtos);
        orderBusinessService.addOrderOperateLog(createReqVOList.get(0).getOrderId(), "", "新增特需", list);
        // 返回
        // 插入应收款
    }

    private void changeOrderAdvanceType(OrderSpecialNeedDO orderSpecialNeedDO, String packageType) {
        LambdaUpdateWrapper<OrderDO> orderDOLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        orderDOLambdaUpdateWrapper.eq(OrderDO::getOrderId, orderSpecialNeedDO.getOrderId());
        if (StringUtils.isNotBlank(packageType)) {
            orderDOLambdaUpdateWrapper.set(OrderDO::getPackageType, packageType);
        } else {
            orderDOLambdaUpdateWrapper.set(OrderDO::getPackageType, "");
        }
        if (StringUtils.isNotBlank(orderSpecialNeedDO.getTodoDetail())) {
            orderDOLambdaUpdateWrapper.set(OrderDO::getPackageRemarks, orderSpecialNeedDO.getTodoDetail());
        }
        orderService.update(orderDOLambdaUpdateWrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateOrderSpecialNeed(OrderSpecialNeedUpdateReqVO updateReqVO) {
        // 校验存在
        this.validateOrderSpecialNeedExists(updateReqVO.getId());
        OrderDO orderDO = orderService.selectOne(OrderDO::getOrderId, updateReqVO.getOrderId());
        checkWarehouseIn(updateReqVO.getOrderId());
        if (orderDO.getStatus() >= 11) {
            throw exception(ORDER_SPECIAL_NEED_UPDATE_ERROR);
        }
        // 更新
        OrderSpecialNeedDO orderSpecialNeedDOOld = orderSpecialNeedMapper.selectById(updateReqVO.getId());
        if (orderSpecialNeedDOOld.getReceivableId() != null && orderSpecialNeedDOOld.getReceivableId() > 0L) {
            DictDataRespDTO dictDto = DictFrameworkUtils.getDictDataFromCache("receivable_fee_type", updateReqVO.getAdvanceType());
            try {
                ReceivableDO receivableDO = new ReceivableDO();
                receivableDO.setId(orderSpecialNeedDOOld.getReceivableId());
                receivableDO.setCurrencyId(Long.valueOf(updateReqVO.getTransCurrency()));
                receivableDO.setTitleEn(dictDto.getLabelEn());
                receivableDO.setTitleZh(dictDto.getLabel());
                receivableDO.setFeeType(Integer.valueOf(updateReqVO.getAdvanceType()));
                receivableDO.setCollectionType(updateReqVO.getPayType());
                receivableDO.setState(0);
                receivableDO.setUnitPrice(updateReqVO.getTransFee());
                receivableDO.setTotalAmount(updateReqVO.getTransFee());
                receivableService.updateReceivableById(receivableDO);
            } catch (ServiceException e) {
                throw e;
            }
        }
        OrderSpecialNeedDO updateObj = OrderSpecialNeedConvert.INSTANCE.convert(updateReqVO);
        orderSpecialNeedMapper.updateById(updateObj);
        List<OrderSpecialNeedDO> orderSpecialNeedDOS = orderSpecialNeedMapper.selectList(OrderSpecialNeedDO::getOrderId, updateObj.getOrderId());
        StringBuffer stringBuffer = new StringBuffer();
        orderSpecialNeedDOS.stream().forEach(item -> stringBuffer.append(item.getAdvanceType() + ","));
        changeOrderAdvanceType(updateObj, stringBuffer.deleteCharAt(stringBuffer.length() - 1).toString());

//        FeeDto feeDto = new FeeDto();
//        feeDto.setFeeType(Integer.valueOf(updateReqVO.getAdvanceType()));
//        feeDto.setAmount(updateReqVO.getTransFee().subtract(orderSpecialNeedDOOld.getTransFee()));
//        feeDto.setCurrencyId(updateReqVO.getTransCurrency());
//        List<FeeDto> feeDtos = new ArrayList<>();
//        feeDtos.add(feeDto);
//        orderService.addOrderOtherFee(updateReqVO.getOrderId(), feeDtos);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteOrderSpecialNeed(Long id) {
        // 校验存在
        this.validateOrderSpecialNeedExists(id);
        // 删除
        OrderSpecialNeedDO orderSpecialNeedDO = orderSpecialNeedMapper.selectById(id);
        if (Objects.nonNull(orderSpecialNeedDO)) {
            try {
                if (orderSpecialNeedDO.getReceivableId() != null && orderSpecialNeedDO.getReceivableId() > 0L) {
                    receivableService.cancelReceivable(orderSpecialNeedDO.getReceivableId());
                }
            } catch (ServiceException e) {
                throw exception(ORDER_SPECIAL_NEED_ERROR);
            }
            orderSpecialNeedMapper.deleteById(id);
        }
        StringBuffer stringBuffer = new StringBuffer();
        List<OrderSpecialNeedDO> orderSpecialNeedDOS = orderSpecialNeedMapper.selectList(OrderSpecialNeedDO::getOrderId, orderSpecialNeedDO.getOrderId());

        if (CollectionUtil.isNotEmpty(orderSpecialNeedDOS)) {
            orderSpecialNeedDOS.stream().forEach(item -> stringBuffer.append(item.getAdvanceType()).append(","));
        }
        changeOrderAdvanceType(orderSpecialNeedDO, stringBuffer.length() <= 0 ? "" : stringBuffer.deleteCharAt(stringBuffer.length() - 1).toString());
        List<FeeDto> feeDtos = new ArrayList<>();
        if (Objects.nonNull(orderSpecialNeedDO)) {
            FeeDto feeDto = new FeeDto();
            feeDto.setFeeType(Integer.valueOf(orderSpecialNeedDO.getAdvanceType()));
            feeDto.setCurrencyId(orderSpecialNeedDO.getTransCurrency());
            feeDto.setAmount(new BigDecimal(0).subtract(orderSpecialNeedDO.getTransFee()));
            feeDtos.add(feeDto);
        }
        orderService.addOrderOtherFee(orderSpecialNeedDO.getOrderId(), feeDtos);
    }

    private void validateOrderSpecialNeedExists(Long id) {
        if (orderSpecialNeedMapper.selectById(id) == null) {
            throw exception(ORDER_SPECIAL_NEED_NOT_EXISTS);
        }
    }

    @Override
    public OrderSpecialNeedDO getOrderSpecialNeed(Long id) {
        return orderSpecialNeedMapper.selectById(id);
    }

    @Override
    public List<OrderSpecialNeedDO> getOrderSpecialNeedList(Collection<Long> ids) {
        return orderSpecialNeedMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<OrderSpecialNeedDO> getOrderSpecialNeedPage(OrderSpecialNeedQueryVO query, PageVO page) {
        return orderSpecialNeedMapper.selectPage(page, query);
    }

    @Override
    public List<OrderSpecialNeedDO> getOrderSpecialNeedList(OrderSpecialNeedQueryVO query) {
        return orderSpecialNeedMapper.selectList(query);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteByOrderId(OrderSpecialNeedQueryVO orderSpecialNeedQueryVO) {
        OrderSpecialNeedDO orderSpecialNeedDO = orderSpecialNeedMapper.selectOne(new LambdaQueryWrapperX<OrderSpecialNeedDO>()
                .eq(OrderSpecialNeedDO::getOrderId, orderSpecialNeedQueryVO.getOrderId())
                .eq(OrderSpecialNeedDO::getAdvanceType, orderSpecialNeedQueryVO.getAdvanceType()));
        try {
            if (orderSpecialNeedDO.getReceivableId() != null && orderSpecialNeedDO.getReceivableId() > 0L) {
                receivableService.cancelReceivable(orderSpecialNeedDO.getReceivableId());
            }
        } catch (ServiceException e) {
            throw exception(ORDER_SPECIAL_NEED_ERROR);
        }
        orderSpecialNeedMapper.deleteById(orderSpecialNeedDO);
        List<OrderSpecialNeedDO> orderSpecialNeedDOS = orderSpecialNeedMapper.selectList(OrderSpecialNeedDO::getOrderId, orderSpecialNeedQueryVO.getOrderId());
        StringBuffer stringBuffer = new StringBuffer();
        orderSpecialNeedDOS.stream().forEach(item -> stringBuffer.append(item.getAdvanceType() + ","));
        LambdaUpdateWrapper<OrderDO> orderDOLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        orderDOLambdaUpdateWrapper.eq(OrderDO::getOrderId, orderSpecialNeedQueryVO.getOrderId());
        if (StringUtils.isNotBlank(stringBuffer.toString())) {
            orderDOLambdaUpdateWrapper.set(OrderDO::getPackageType, stringBuffer.deleteCharAt(stringBuffer.length() - 1).toString());
        } else {
            orderDOLambdaUpdateWrapper.set(OrderDO::getPackageType, "");
        }
        orderService.update(orderDOLambdaUpdateWrapper);
    }

    @Override
    public List<OrderSpecialNeedDO> getListByOrderId(Long orderId) {
        return orderSpecialNeedMapper.selectList(OrderSpecialNeedDO::getOrderId, orderId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateOrderSpecialNeedBatch(List<OrderSpecialNeedUpdateReqVO> updateReqVOList) throws Exception {
        List<ApplyInfoVO> list = new ArrayList();
        if (updateReqVOList != null && updateReqVOList.size() > 0) {
            checkWarehouseIn(updateReqVOList.get(0).getOrderId());
            for (OrderSpecialNeedUpdateReqVO reqVO : updateReqVOList) {
                if ("add".equals(reqVO.getOper())) {
                    OrderSpecialNeedDO orderSpecialNeedDO = OrderSpecialNeedConvert.INSTANCE.convert(reqVO);
                    orderSpecialNeedMapper.insert(orderSpecialNeedDO);
                    List<OrderSpecialNeedDO> orderSpecialNeedDOS = orderSpecialNeedMapper.selectList(OrderSpecialNeedDO::getOrderId, orderSpecialNeedDO.getOrderId());
                    StringBuffer stringBuffer = new StringBuffer();
                    orderSpecialNeedDOS.stream().forEach(item -> stringBuffer.append(item.getAdvanceType()).append(","));
                    changeOrderAdvanceType(orderSpecialNeedDO, stringBuffer.deleteCharAt(stringBuffer.length() - 1).toString());
                    DictDataRespDTO dictDataFromCache = DictFrameworkUtils.getDictDataFromCache(DictTypeConstants.ORDER_SPECIAL_NEED, String.valueOf(reqVO.getAdvanceType()));
                    CurrencyDO currency = currencyService.getCurrency(reqVO.getTransCurrency());
                    ApplyInfoVO applyInfoVO = new ApplyInfoVO();
                    applyInfoVO.setName("新增特需名称");
                    applyInfoVO.setNewValue(I18nMessage.getLang() == 0 ? dictDataFromCache.getLabel() : dictDataFromCache.getLabelEn());
                    ApplyInfoVO applyInfoVO1 = new ApplyInfoVO();
                    applyInfoVO1.setName("金额");
                    applyInfoVO1.setNewValue(reqVO.getTransFee() == null ? "" : String.valueOf(reqVO.getTransFee().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);
                } else if ("del".equals(reqVO.getOper())) {
                    OrderSpecialNeedDO orderSpecialNeedDO = orderSpecialNeedMapper.selectOne(new LambdaQueryWrapperX<OrderSpecialNeedDO>()
                            .eq(OrderSpecialNeedDO::getOrderId, reqVO.getOrderId())
                            .eq(OrderSpecialNeedDO::getAdvanceType, reqVO.getAdvanceType()));
                    try {
                        if (orderSpecialNeedDO.getReceivableId() != null && orderSpecialNeedDO.getReceivableId() > 0L) {
                            receivableService.cancelReceivable(orderSpecialNeedDO.getReceivableId());
                        }
                    } catch (ServiceException e) {
                        throw exception(ORDER_SPECIAL_NEED_ERROR);
                    }
                    orderSpecialNeedMapper.deleteById(orderSpecialNeedDO);
                    List<OrderSpecialNeedDO> orderSpecialNeedDOS = orderSpecialNeedMapper.selectList(OrderSpecialNeedDO::getOrderId, reqVO.getOrderId());
                    StringBuffer stringBuffer = new StringBuffer();
                    orderSpecialNeedDOS.stream().forEach(item -> stringBuffer.append(item.getAdvanceType() + ","));
                    LambdaUpdateWrapper<OrderDO> orderDOLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
                    orderDOLambdaUpdateWrapper.eq(OrderDO::getOrderId, reqVO.getOrderId());
                    if (StringUtils.isNotBlank(stringBuffer.toString())) {
                        orderDOLambdaUpdateWrapper.set(OrderDO::getPackageType, stringBuffer.deleteCharAt(stringBuffer.length() - 1).toString());
                    } else {
                        orderDOLambdaUpdateWrapper.set(OrderDO::getPackageType, "");
                    }
                    orderService.update(orderDOLambdaUpdateWrapper);
                } else {
                    orderSpecialNeedMapper.updateById(OrderSpecialNeedConvert.INSTANCE.convert(reqVO));
//                    orderSpecialNeedMapper.update(OrderSpecialNeedConvert.INSTANCE.convert(reqVO), new LambdaQueryWrapperX<OrderSpecialNeedDO>().eq(OrderSpecialNeedDO::getOrderId, reqVO.getOrderId())
//                            .eq(OrderSpecialNeedDO::getAdvanceType, reqVO.getAdvanceType()));
                }
            }
            if (CollectionUtil.isNotEmpty(list)) {
                orderBusinessService.addOrderOperateLog(updateReqVOList.get(0).getOrderId(), "", "新增特需", list);
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void buildSpecialReceivable(Long orderId, int type) {
        List<OrderSpecialNeedDO> orderSpecialNeedDOS =
                orderSpecialNeedMapper.selectList(OrderSpecialNeedDO::getOrderId,
                        orderId);
        //垫付的内陆运输费用 getTransFee
        if (CollectionUtil.isNotEmpty(orderSpecialNeedDOS)) {
            orderSpecialNeedDOS.stream().filter(
                    item -> item.getTransFee().compareTo(BigDecimal.ZERO) == 1).
                    forEach(item -> build(item, type));
        }
    }

    private void build(OrderSpecialNeedDO orderSpecialNeed, int type) {
        // 插入应收款
        // 预付在完成入仓时生成应收
        DictDataRespDTO dictDto =
                DictFrameworkUtils.getDictDataFromCache("receivable_fee_type",
                        orderSpecialNeed.getAdvanceType());

        //付款类型 getPayType 付款类型
        /*
        if (type == 1 && orderSpecialNeed.getPayType() != null
                && orderSpecialNeed.getPayType() != 4) {*/

        if (type == 1 && orderSpecialNeed.getPayType() != null)
        {
            //完成入仓可多次，故先删除掉已有应收再重新生成
            if (orderSpecialNeed.getReceivableId() != null &&
                    orderSpecialNeed.getReceivableId() > 0L) {
                receivableService.deleteReceivable(orderSpecialNeed.getReceivableId());
            }
            OrderBackVO order = orderQueryService.getOrder(orderSpecialNeed.getOrderId());
            ReceivableCreateReqVO receivableCreateReqVO = new ReceivableCreateReqVO();
            receivableCreateReqVO.setAuthor(String.valueOf(orderSpecialNeed.getAdvanceWho() == null ? 0 : orderSpecialNeed.getAdvanceWho()));
            receivableCreateReqVO.setCurrencyId(Long.valueOf(orderSpecialNeed.getTransCurrency() == null ? 0 : orderSpecialNeed.getTransCurrency()));
            receivableCreateReqVO.setTitleEn(dictDto.getLabelEn());
            receivableCreateReqVO.setTitleZh(dictDto.getLabel());
            receivableCreateReqVO.setFeeType(Integer.valueOf(orderSpecialNeed.getAdvanceType()));
            receivableCreateReqVO.setOrderId(orderSpecialNeed.getOrderId());
            receivableCreateReqVO.setCollectionType(orderSpecialNeed.getPayType());
            receivableCreateReqVO.setState(0);
            receivableCreateReqVO.setOrderNo(order.getOrderNo());
            receivableCreateReqVO.setUnitPrice(orderSpecialNeed.getTransFee());
            receivableCreateReqVO.setTotalAmount(orderSpecialNeed.getTransFee());
            receivableCreateReqVO.setUnitPrice(orderSpecialNeed.getTransFee());
            receivableCreateReqVO.setPaymentUser(String.valueOf(order.getDrawee() != 3 ? order.getDrawee() : orderQueryService.customDrawee(OrderConvert.INSTANCE.convert(order), Integer.valueOf(orderSpecialNeed.getAdvanceType()))));
            receivableCreateReqVO.setFeeSource(3);
            Long receivableId = receivableService.createReceivable(
                    receivableCreateReqVO);
            orderSpecialNeed.setReceivableId(receivableId);
            orderSpecialNeedMapper.updateById(orderSpecialNeed);

        } else if (type == 2 && orderSpecialNeed.getPayType() != null
                && orderSpecialNeed.getPayType() == 4) {
            //装柜反审后再审批，故先删除掉已有应收再重新生成
            if (orderSpecialNeed.getReceivableId() != null &&
                    orderSpecialNeed.getReceivableId() > 0L) {
                receivableService.deleteReceivable(orderSpecialNeed.getReceivableId());
            }
            OrderBackVO order = orderQueryService.getOrder(orderSpecialNeed.getOrderId());
            ReceivableCreateReqVO receivableCreateReqVO = new ReceivableCreateReqVO();
            receivableCreateReqVO.setAuthor(String.valueOf(orderSpecialNeed.getAdvanceWho() == null ? 0 : orderSpecialNeed.getAdvanceWho()));
            receivableCreateReqVO.setCurrencyId(Long.valueOf(orderSpecialNeed.getTransCurrency() == null ? 0 : orderSpecialNeed.getTransCurrency()));
            receivableCreateReqVO.setTitleEn(dictDto.getLabelEn());
            receivableCreateReqVO.setTitleZh(dictDto.getLabel());
            receivableCreateReqVO.setFeeType(Integer.valueOf(orderSpecialNeed.getAdvanceType()));
            receivableCreateReqVO.setOrderId(orderSpecialNeed.getOrderId());
            receivableCreateReqVO.setCollectionType(orderSpecialNeed.getPayType());
            receivableCreateReqVO.setState(0);
            receivableCreateReqVO.setOrderNo(order.getOrderNo());
            receivableCreateReqVO.setUnitPrice(orderSpecialNeed.getTransFee());
            receivableCreateReqVO.setTotalAmount(orderSpecialNeed.getTransFee());
            receivableCreateReqVO.setPaymentUser(String.valueOf(order.getDrawee() != 3 ? order.getDrawee() : orderQueryService.customDrawee(OrderConvert.INSTANCE.convert(order), Integer.valueOf(orderSpecialNeed.getAdvanceType()))));
            receivableCreateReqVO.setFeeSource(3);
            Long receivableId = receivableService.createReceivable(receivableCreateReqVO);
            orderSpecialNeed.setReceivableId(receivableId);
            orderSpecialNeedMapper.updateById(orderSpecialNeed);
        }
    }

    @Override
    public boolean updateBatchById(Collection<OrderSpecialNeedDO> entityList) {
        List<ApplyInfoVO> list = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(entityList)) {
            entityList.stream().forEach(item -> {
                if (item.getTransFee() == null) {
                    item.setTransFee(BigDecimal.ZERO);
                }
                OrderSpecialNeedDO orderSpecialNeedDO = orderSpecialNeedMapper.selectById(item.getId());
                if (orderSpecialNeedDO.getTransFee().compareTo(item.getTransFee()) != 0 || orderSpecialNeedDO.getTransCurrency() != item.getTransCurrency()) {
                    DictDataRespDTO dictDataFromCache = DictFrameworkUtils.getDictDataFromCache(DictTypeConstants.ORDER_SPECIAL_NEED, String.valueOf(item.getAdvanceType()));
                    CurrencyDO currencyOld = currencyService.getCurrency(orderSpecialNeedDO.getTransCurrency());
                    CurrencyDO currencyNew = currencyService.getCurrency(item.getTransCurrency());
                    ApplyInfoVO applyInfoVO1 = new ApplyInfoVO();
                    applyInfoVO1.setName(I18nMessage.getLang() == 0 ? dictDataFromCache.getLabel() : dictDataFromCache.getLabelEn());
                    applyInfoVO1.setOrgValue(String.valueOf(orderSpecialNeedDO.getTransFee() == null ? "" : orderSpecialNeedDO.getTransFee().doubleValue()) + (I18nMessage.getLang() == 0 ? currencyOld.getTitleZh() : currencyOld.getTitleEn()));
                    applyInfoVO1.setNewValue(String.valueOf(item.getTransFee().doubleValue()) + (I18nMessage.getLang() == 0 ? currencyNew.getTitleZh() : currencyNew.getTitleEn()));
                    list.add(applyInfoVO1);
                }
            });
            if (CollectionUtil.isNotEmpty(list)) {
                List<Long> collect = entityList.stream().map(OrderSpecialNeedDO::getOrderId).collect(Collectors.toList());
                orderBusinessService.addOrderOperateLog(collect.get(0), "", "修改特需", list);
            }
        }
        return super.updateBatchById(entityList);
    }

    private void checkWarehouseIn(Long orderId) {
        OrderDO orderDO = orderService.getById(orderId);
        if (orderDO.getStatus() >= 5) {
            throw exception(ORDER_ALREADY_WAREHOUSE_IN);
        }
    }
}
