package com.zfire.mall.manager.logic.engin.order;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.EnumUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zfire.mall.manager.bean.ExcelData;
import com.zfire.mall.manager.bean.PoySaleCountBean;
import com.zfire.mall.manager.bean.admin.AdminUserCom;
import com.zfire.mall.manager.bean.engin.order.EnginOrderBean;
import com.zfire.mall.manager.bean.engin.order.EnginOrderItemBean;
import com.zfire.mall.manager.bean.engin.order.EnginOrderListBean;
import com.zfire.mall.manager.bean.invoice.InvoiceApplicationOrderRequest;
import com.zfire.mall.manager.bean.invoice.InvoiceRequestJson;
import com.zfire.mall.manager.bean.k3.K3CustomerBean;
import com.zfire.mall.manager.bean.k3.RequestExcuteOperationBean;
import com.zfire.mall.manager.bean.k3.bill.SalesChangeBean;
import com.zfire.mall.manager.bean.k3.bill.SalesChangeItemBean;
import com.zfire.mall.manager.bean.k3.bill.SalesOrderBean;
import com.zfire.mall.manager.bean.k3.bill.SalesOrderItemBean;
import com.zfire.mall.manager.bean.k3.bill.result.BillItem;
import com.zfire.mall.manager.bean.k3.bill.result.ResultEntity;
import com.zfire.mall.manager.bean.retail.ProductPriceBean;
import com.zfire.mall.manager.bean.wallet.CustomerWalletAmountBean;
import com.zfire.mall.manager.bean.wallet.CustomerWalletBean;
import com.zfire.mall.manager.commonmapper.CommonCountMapper;
import com.zfire.mall.manager.commonmapper.InvoiceMapper;
import com.zfire.mall.manager.commonmapper.engin.order.EnginOrderReserveMapper;
import com.zfire.mall.manager.constant.SysDictConstant;
import com.zfire.mall.manager.enums.*;
import com.zfire.mall.manager.exception.RemoteServiceException;
import com.zfire.mall.manager.helper.ResponseHelper;
import com.zfire.mall.manager.logic.common.CommonLogic;
import com.zfire.mall.manager.logic.customer.CustomerEnginDepositLogic;
import com.zfire.mall.manager.logic.customer.CustomerProductTypeLogic;
import com.zfire.mall.manager.logic.engin.deposit.DepositManageLogic;
import com.zfire.mall.manager.logic.invoice.InvoiceLogic;
import com.zfire.mall.manager.logic.k3.K3CustomerLogic;
import com.zfire.mall.manager.logic.k3.K3MaterialLogic;
import com.zfire.mall.manager.logic.k3.bill.SalesChangeOrderLogic;
import com.zfire.mall.manager.logic.k3.bill.SalesOrderLogic;
import com.zfire.mall.manager.logic.refund.v2.RefundOrderV2Logic;
import com.zfire.mall.manager.logic.retail.RetailOrderLogic;
import com.zfire.mall.manager.logic.wallet.RebateOrderLogic;
import com.zfire.mall.manager.logic.wallet.WalletLogic;
import com.zfire.mall.manager.plus.entity.*;
import com.zfire.mall.manager.plus.service.*;
import com.zfire.mall.manager.utils.CommonUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

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

@Slf4j
@Service
public class EnginOrderLogic {

    @Resource
    EnginOrderReserveMapper enginOrderReserveMapper;
    @Resource
    CommonLogic commonLogic;
    @Resource
    EnginOrderService enginOrderService;
    @Resource
    EnginOrderItemService enginOrderItemService;
    @Resource
    EnginOrderRefundNoteService enginOrderRefundNoteService;
    @Resource
    EnginInfoOrderItemService enginInfoOrderItemService;
    @Resource
    WalletLogic walletLogic;
    @Resource
    CustomerEnginDepositLogic customerEnginDepositLogic;
    @Resource
    DepositManageService depositManageService;
    @Resource
    DepositManageItemService depositManageItemService;
    @Resource
    RebateOrderLogic rebateOrderLogic;
    @Resource
    K3CustomerLogic k3CustomerLogic;
    @Resource
    SalesOrderLogic salesOrderLogic;
    @Resource
    SalesChangeOrderLogic salesChangeOrderLogic;
    @Autowired
    K3MaterialLogic k3MaterialLogic;
    @Autowired
    CustomerProductTypeLogic customerProductTypeLogic;
    @Resource
    InvoiceMapper invoiceMapper;
    @Resource
    ReservedOrderItemService reservedOrderItemService;
    @Resource
    EnginSysLogic enginSysLogic;
    @Resource
    CommonCountMapper commonCountMapper;
    @Resource
    RetailOrderLogic retailOrderLogic;
    @Resource
    AdminUserService adminUserService;
    @Resource
    SaleTypeService saleTypeService;
    @Resource
    KingDeeMaterialService kingDeeMaterialService;
    @Resource
    AdminUserWebsitRelaService adminUserWebsitRelaService;
    @Resource
    DepositManageCheckRecordService depositManageCheckRecordService;
    @Resource
    DepositManageDataService depositManageDataService;
    @Resource
    DepositManageBakService depositManageBakService;
    @Resource
    DepositManageItemBakService depositManageItemBakService;
    @Resource
    DepositManageDataBakService depositManageDataBakService;
    @Resource
    DepositManageCheckRecordBakService depositManageCheckRecordBakService;
    @Resource
    EnginOrderItemDepositRecordService enginOrderItemDepositRecordService;

    @Resource
    InvoiceApplicationService invoiceApplicationService;

    @Resource
    InvoiceLogic invoiceLogic;

    @Resource
    InvoiceApplicationOrderService invoiceApplicationOrderService;
    @Resource
    DepositManageItemCollectService depositManageItemCollectService;
    @Resource
    DepositManageLogic depositManageLogic;
    @Resource
    RefundOrderV2Logic refundOrderV2Logic;
    @Resource
    OrderExecRecordService orderExecRecordService;
    @Resource
    EnginOrderItemBakService enginOrderItemBakService;

    public IPage<EnginOrderListBean> listPage(String customerWalletId,String customerKeyword, List<String> enginOrderNo, String enginOrderType,
                                              String refProjectNo, String refEnginRecordNo, String refProjectCategory,
                                              String refProjectName, String refUseUnit, String refTradeCategory, String startCreateTime,
                                              String endCreateTime, String startOrderTime,String endOrderTime,
                                              String saleTypeId, String createName, String confirmName,
                                              List<String> examineStatus, String serviceId, String specification, String materialNumber,
                                              String materialName, String materialOldNumber, String refRegionWork,
                                              String remark, String geLiInerNote, String refFactoryNo, String refBuyUnitName,
                                              String refPromiseProvide, Boolean isDirectTransfer, Integer pageNum, Integer pageSize) {
        AdminUserCom adminUser = commonLogic.getAdminUser(true);
        String customerId = adminUser.getIsCustomer() ? adminUser.getCustomerId() : "";
        return enginOrderReserveMapper.listPage(new Page<>(pageNum, pageSize),customerWalletId, customerKeyword, enginOrderNo, enginOrderType,
                refProjectNo, refEnginRecordNo, refProjectCategory, refProjectName, refUseUnit, refTradeCategory,
                startCreateTime, endCreateTime,startOrderTime,endOrderTime, saleTypeId, createName,
                confirmName, examineStatus, serviceId, adminUser.getAdminCompanyIds(), specification, adminUser.getServiceIds(),
                customerId, materialNumber, materialName, materialOldNumber, refRegionWork, remark, geLiInerNote, refFactoryNo,
                adminUser.getK3CategoryIds(), refBuyUnitName, refPromiseProvide, isDirectTransfer);
    }


    public PoySaleCountBean listCount(String customerKeyword, List<String> enginOrderNo, String enginOrderType, String refEnginRecordNo,
                                      String refProjectName, String refUseUnit, String startCreateTime, String endCreateTime, String saleTypeId,
                                      String createName, String confirmName, List<String> examineStatus,
                                      String serviceId) {
        AdminUserCom adminUser = commonLogic.getAdminUser(true);
        String customerId = adminUser.getIsCustomer() ? adminUser.getCustomerId() : "";
        return commonCountMapper.enginOrderCount(customerKeyword, enginOrderNo, enginOrderType,
                refEnginRecordNo, refProjectName, refUseUnit, startCreateTime, endCreateTime, saleTypeId, createName,
                confirmName, examineStatus, serviceId, adminUser.getAdminCompanyIds(), adminUser.getServiceIds(), customerId);
    }


    public EnginOrderBean detail(String id) {
        AdminUserCom adminUser = commonLogic.getAdminUser(true);
        String customerId = adminUser.getIsCustomer() ? adminUser.getCustomerId() : "";

        EnginOrderBean detail = enginOrderReserveMapper.detail(id, adminUser.getAdminCompanyIds(), adminUser.getServiceIds(), customerId);
        if (adminUser.getIsCustomer()) {
            detail.setGeLiInerNote(null);
        }
        if (detail == null){
            return null;
        }

        queryItemDataHandle(detail);

        if (detail.getExamineStatus().equals(ExamineStatusEnum.OK.toString())) {
            List<EnginOrderRefundNote> noteList = enginOrderRefundNoteService.lambdaQuery()
                    .eq(EnginOrderRefundNote::getEnginOrderNo, detail.getEnginOrderNo())
                    .list();
            detail.setRefundNoteList(noteList);
        }

        return detail;
    }

    private void queryItemDataHandle(EnginOrderBean detail) {
        List<String> oldNumbers = detail.getItems().stream()
                .map(EnginOrderItemBean::getMaterialOldNumber)
                .collect(Collectors.toList());
        // 获取产品价格列表
        IPage<ProductPriceBean> productPricePage = retailOrderLogic.queryProductList(null, null,
                null, null, null, null, null, detail.getCustomerId(),
                oldNumbers, detail.getEnginOrderType().equals(OrderTypeEnum.HOME.getKey()) ? OrderTypeEnum.HOME.getKey() : OrderTypeEnum.GENERAL.getKey() ,
                1, -1);
        List<ProductPriceBean> records = productPricePage.getRecords();
        Map<String, ProductPriceBean> priceBeanMap = records.stream()
                .collect(Collectors.toMap(v -> v.getSaleCode() + v.getMaterialOldNumber(), Function.identity(), (key1, key2) -> key1));
        for (EnginOrderItemBean item : detail.getItems()) {
            ProductPriceBean priceBean = priceBeanMap.get(item.getSaleTypeCode() + item.getMaterialOldNumber());
            item.setRefundableQty(item.getRefundableQty() - invoiceMapper.selectInvoice(item.getId()));
            // 计算销售数量和金额
//            item.setSalesQty(Optional.ofNullable(item.getOldQty()).orElse(0) - Math.abs(Optional.ofNullable(item.getRefundProductQty()).orElse(0))
//                    - Optional.ofNullable(item.getRetiredQty()).orElse(0));
//            item.setSalesAmount(BigDecimal.valueOf(item.getSalesQty()).multiply(Optional.ofNullable(item.getPrice()).orElse(BigDecimal.ZERO)));
            if (Objects.nonNull(priceBean)) {
                item.getCustomerWalletList().addAll(priceBean.getRebateWallets());
                item.getCustomerWalletList().addAll(priceBean.getWallets());
            }

        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void revokeHome(String id, String refEnginRecordNo, String orderType) throws Exception {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        boolean upd = enginOrderService.lambdaUpdate()
                .set(EnginOrder::getExamineStatus, ExamineStatusEnum.SAVE.toString())
                .set(EnginOrder::getSubmitBy, null)
                .set(EnginOrder::getSubmitName, null)
                .set(EnginOrder::getSubmitTime, null)
                .eq(EnginOrder::getEnginOrderId, id)
                .eq(EnginOrder::getRefEnginRecordNo, refEnginRecordNo)
                .eq(adminUser.getIsCustomer(), EnginOrder::getCustomerId, adminUser.getCustomerId())
                .eq(EnginOrder::getEnginOrderType, orderType)
                .eq(EnginOrder::getExamineStatus, ExamineStatusEnum.WAIT.toString())
                .update();
        if (!upd) {
            throw new RemoteServiceException("非待审订单，撤回失败");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void revokeTrade(String id, String refEnginRecordNo, String orderType) throws Exception {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        EnginOrder enginOrder = enginOrderService.lambdaQuery()
                .eq(EnginOrder::getEnginOrderId, id)
                .eq(EnginOrder::getRefEnginRecordNo, refEnginRecordNo)
                .eq(EnginOrder::getEnginOrderType, orderType)
                .eq(adminUser.getIsCustomer(), EnginOrder::getCustomerId, adminUser.getCustomerId())
                .eq(EnginOrder::getExamineStatus, ExamineStatusEnum.WAIT.toString())
                .one();

        if (Objects.isNull(enginOrder)) {
            throw new RemoteServiceException("非待审订单，撤回失败，请重新加载");
        }
        List<EnginOrderItem> items = enginOrderItemService.lambdaQuery().eq(EnginOrderItem::getParentId, enginOrder.getEnginOrderId()).list();
        // 更新信息单已订数量
        this.updateRefInfoData(enginOrder, items, -1, "");

        if(!enginOrder.getIsPlanOrder()) {
            // 非计划单退款
            walletLogic.doWalletAmount(this.handleWalletMethod(enginOrder, items, true, "工程订单退款-撤回", "工程订单返利退款-撤回"));
            //删除发货单
            InvoiceApplication one = invoiceApplicationService.lambdaQuery().eq(InvoiceApplication::getEnginOrderNo, enginOrder.getEnginOrderNo()).last("limit 1").one();
            invoiceLogic.submitProject(one.getId(), "SAVE");
            invoiceLogic.deleteProject(one.getId());
        }
        enginOrder.setExamineStatus(ExamineStatusEnum.SAVE.toString())
                .setSubmitBy(null)
                .setSubmitName(null)
                .setSubmitTime(null)
                .setAdvanceStatus(false);

        enginOrder.updateById();

    }

    @Transactional(rollbackFor = Exception.class)
    public String homeAdd(EnginOrderBean enginOrderBean, String operType) throws Exception {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        this.setAddCommonOrderInfo(adminUser, enginOrderBean, "3");

        // 检查引用单号唯一并返回引用次数
        Integer refCount = checkEnginOrderRecord(enginOrderBean);

        // 保存主表
        EnginOrder enginOrder = enginOrderBean.handleAddHomeOrderInfo(adminUser, refCount, null);
        if (StringUtils.isBlank(enginOrder.getServiceId())) {
            throw new RemoteServiceException("表头业务员不能为空");
        }
        enginOrder.insert();

        // 保存明细
        List<EnginOrderItem> enginOrderItems = enginOrderBean.handleAddHomeOrderItem(enginOrder);

        // 返利和现金钱包金额处理
        if (Objects.isNull(enginOrder.getTakeDeposit())) {
            enginOrder.setTakeDeposit(false);
        }
        itemWalletHandleHome(enginOrder, enginOrderItems, "", false);

        // 业务员为空时默认钱包第一个业务员
//        if (StringUtils.isEmpty(enginOrder.getServiceId())) {
//            enginOrder.setServiceId(enginOrderItems.get(0).getServiceId());
//            enginOrder.setServiceName(enginOrderItems.get(0).getServiceName());
//            enginOrder.updateById();
//        }

        enginOrderItemService.saveBatch(enginOrderItems);

        //新增销售订单基础 add by ljh 2022-09-19 方便后续统一的订单管理，也方便合并统计
        commonLogic.addOrderBase(enginOrder.getEnginOrderNo(),enginOrder.getEnginOrderType());

        if (StringUtils.isNotBlank(operType) && operType.equals(SysDictConstant.SUBMIT)) {
            enginOrderBean.setTakeDeposit(false);
            enginOrder = this.execHandlerHome(enginOrderBean, operType);
        }

        return enginOrder.getEnginOrderId();
    }

    @Transactional(rollbackFor = Exception.class)
    public String tradeAdd(EnginOrderBean enginOrderBean, String operType) throws Exception {

        if (StringUtils.isEmpty(enginOrderBean.getCorrespondId())) {
            throw new RemoteServiceException("仓库不能为空");
        }
        AdminUserCom adminUser = commonLogic.getAdminUser();
        this.setAddCommonOrderInfo(adminUser, enginOrderBean, "4");

        if (StringUtils.isBlank(enginOrderBean.getServiceId())) {
            throw new RemoteServiceException("表头业务员不能为空");
        }
        // 检查引用单号唯一
//        Integer refCount = checkEnginOrderRecord(enginOrderBean);
        EnginOrder enginOrder = enginOrderBean.handleAddTradeOrderInfo(0, null);
        enginOrder.insert();

        // 保存明细
        enginOrderBean.setEnginOrderId(enginOrder.getEnginOrderId());
        List<EnginOrderItem> orderItems = enginOrderBean.handleAddTradeOrderItem(enginOrder);

        // 返利和现金钱包金额处理
        itemWalletHandleTrade(enginOrder, orderItems, "", false);

        enginOrderItemService.saveBatch(orderItems);

        //新增销售订单基础 add by ljh 2022-09-19 方便后续统一的订单管理，也方便合并统计
        commonLogic.addOrderBase(enginOrder.getEnginOrderNo(),enginOrder.getEnginOrderType());

        if (StringUtils.isNotBlank(operType) && operType.equals(SysDictConstant.SUBMIT)) {
            enginOrderBean.setTakeDeposit(true);
            this.execHandlerTrade(enginOrderBean, operType);
        }

        return enginOrder.getEnginOrderId();
    }

    private void setAddCommonOrderInfo(AdminUserCom adminUser, EnginOrderBean enginOrderBean, String prefixNo) {
        if (StringUtils.isBlank(enginOrderBean.getRefEnginRecordNo())) {
            throw new RemoteServiceException("引用单号不能为空");
        }

        if (adminUser.getIsCustomer()) {
            // 经销商建单
            enginOrderBean.setCustomerId(adminUser.getCustomerId());
            enginOrderBean.setCustomerNumber(adminUser.getCustomerNumber());
            enginOrderBean.setCustomerName(adminUser.getCustomerName());
        }
//        else {
//            throw new RemoteServiceException("不是经销商账号不能建单");
//        }

        enginOrderBean.setOrderDate(DateUtil.date());
        enginOrderBean.setAdminCompanyId(adminUser.getAdminCompanyId());
        enginOrderBean.setAdminUserId(adminUser.getAdminUserId());
        enginOrderBean.setAdminWebsitId(adminUser.getAdminWebsitId());
        enginOrderBean.setEnginOrderNo(commonLogic.generateNo(prefixNo,"enginOrder",13));
        enginOrderBean.setExamineStatus(ExamineStatusEnum.SAVE.toString());
        enginOrderBean.setCreateBy(CommonUtils.getUsername());
        enginOrderBean.setCreateName(CommonUtils.getNickName());
        enginOrderBean.setUpdateBy(CommonUtils.getUsername());
        enginOrderBean.setUpdateName(CommonUtils.getNickName());
    }

    public Integer checkEnginOrderRecord(EnginOrderBean enginOrderBean) {
        Integer count = enginOrderService.lambdaQuery()
                .eq(EnginOrder::getAdminCompanyId, enginOrderBean.getAdminCompanyId())
//                .eq(EnginOrder::getCustomerId, enginOrderBean.getCustomerId())
                .eq(EnginOrder::getRefEnginRecordNo, enginOrderBean.getRefEnginRecordNo())
                .ne(StringUtils.isNotBlank(enginOrderBean.getEnginOrderId()), EnginOrder::getEnginOrderId, enginOrderBean.getEnginOrderId())
                .in(EnginOrder::getExamineStatus, ExamineStatusEnum.SAVE.toString(), ExamineStatusEnum.WAIT.toString())
                .count();
        if (count > 0) {
            throw new RemoteServiceException(enginOrderBean.getRefEnginRecordNo() + " 的引用单已存在一张未审批通过的订单！不能再添加");
        }

        if (enginOrderBean.getEnginOrderType().equals(OrderTypeEnum.HOME.getKey())) {
            DepositManage manage = depositManageService.lambdaQuery()
                    .eq(DepositManage::getRefEnginRecordNo, enginOrderBean.getRefEnginRecordNo())
                    .one();
            if (Objects.nonNull(manage) && !manage.getCustomerId().equals(enginOrderBean.getCustomerId())) {
                throw new RemoteServiceException(enginOrderBean.getRefEnginRecordNo() + " 的引用单已给" + manage.getCustomerName() + "使用");
            }
        }

        return enginOrderService.lambdaQuery()
                .eq(EnginOrder::getAdminCompanyId, enginOrderBean.getAdminCompanyId())
                .eq(EnginOrder::getCustomerId, enginOrderBean.getCustomerId())
                .eq(EnginOrder::getRefEnginRecordNo, enginOrderBean.getRefEnginRecordNo())
                .eq(EnginOrder::getExamineStatus, ExamineStatusEnum.OK.toString())
                .count();
    }

    @Transactional(rollbackFor = Exception.class)
    public void edit(EnginOrderBean enginOrderBean) throws Exception {
        AdminUserCom adminUser = commonLogic.getAdminUser();

        // 查询原单
        EnginOrder enginOrder = orgOrderInfoHandler(adminUser, enginOrderBean, "");

        List<EnginOrderItem> orderItems;
        if (enginOrderBean.getEnginOrderType().equals(OrderTypeEnum.HOME.getKey())) {
            enginOrder = enginOrderBean.handleAddHomeOrderInfo(adminUser, null, enginOrder);
            orderItems = enginOrderBean.handleAddHomeOrderItem(enginOrder);

            if (StringUtils.isBlank(enginOrder.getServiceId())) {
                throw new RemoteServiceException("表头业务员不能为空");
            }
        } else {
            enginOrder = enginOrderBean.handleAddTradeOrderInfo(null, enginOrder);
            orderItems = enginOrderBean.handleAddTradeOrderItem(enginOrder);
        }

        // 更新主表
        boolean update = enginOrderService.update(enginOrder, new LambdaUpdateWrapper<EnginOrder>()
                .eq(EnginOrder::getEnginOrderId, enginOrder.getEnginOrderId())
                .eq(EnginOrder::getExamineStatus, ExamineStatusEnum.SAVE.toString()));
        if (!update) {
            throw new RemoteServiceException("单据非“保存”状态，处理失败");
        }

        if (enginOrder.getEnginOrderType().equals(OrderTypeEnum.HOME.getKey())) {
            // 返利和现金钱包金额处理
            itemWalletHandleHome(enginOrder, orderItems, "", false);
        } else {
            itemWalletHandleTrade(enginOrder, orderItems, "", false);
        }

        // 保存明细
        enginOrderItemService.remove(new LambdaUpdateWrapper<EnginOrderItem>()
                .eq(EnginOrderItem::getParentId, enginOrder.getEnginOrderId()));
        enginOrderItemService.saveBatch(orderItems);
    }

    @Transactional(rollbackFor = Exception.class)
    public void del(EnginOrder order) throws Exception {
        EnginOrder byId = enginOrderService.getById(order.getEnginOrderId());

        if (byId.getExamineStatus().equals(ExamineStatusEnum.SAVE.getKey())
            || byId.getExamineStatus().equals(ExamineStatusEnum.CLOSE.getKey())) {
            EnginOrderBak bak = new EnginOrderBak();
            BeanUtils.copyProperties(byId, bak);

            List<EnginOrderItem> items = enginOrderItemService.lambdaQuery()
                    .eq(EnginOrderItem::getParentId, order.getEnginOrderId())
                    .list();

            List<EnginOrderItemBak> itemBaks = items.stream().map(v -> {
                EnginOrderItemBak itemBak = new EnginOrderItemBak();
                BeanUtils.copyProperties(v, itemBak);
                return itemBak;
            }).collect(Collectors.toList());

            if (CollectionUtil.isNotEmpty(itemBaks))
                enginOrderItemBakService.saveBatch(itemBaks);

            bak.insert();
            byId.deleteById();
            enginOrderItemService.removeByIds(items.stream().map(EnginOrderItem::getId).collect(Collectors.toList()));
        }
    }

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public EnginOrder execHandlerHome(EnginOrderBean enginOrderBean, String operType) throws Exception {
        AdminUserCom adminUser = commonLogic.getAdminUser();

        // 查询原单
        EnginOrder enginOrder = orgOrderInfoHandler(adminUser, enginOrderBean, operType);

        if (operType.equals(SysDictConstant.SUBMIT)) {
            // 检查提交的产品是否为0
            for(int i = 0; i < enginOrderBean.getItems().size(); i++) {
                EnginOrderItemBean orderItemBean = enginOrderBean.getItems().get(i);
                if (Objects.isNull(orderItemBean.getQty()) || orderItemBean.getQty() <= 0) {
                    throw new RemoteServiceException(ResponseHelper.ResponseCode_VALIDATION_ERROR, "第" + (i+1) + "行：数量必须大于0");
                }
                if (Objects.isNull(orderItemBean.getPrice()) || orderItemBean.getPrice().doubleValue() <= 0) {
                    throw new RemoteServiceException(ResponseHelper.ResponseCode_VALIDATION_ERROR, "第" + (i+1) + "行：价格必须大于0");
                }
            }
        }
        enginOrder = enginOrderBean.handleAddHomeOrderInfo(adminUser, null, enginOrder);
        if (adminUser.getIsCustomer() && operType.equals(SysDictConstant.SUBMIT)) {
            // 商家提交时更新订单时间
            enginOrder.setOrderDate(DateUtil.date());
        }
        List<EnginOrderItem> orderItems = enginOrderBean.handleAddHomeOrderItem(enginOrder);

        if (StringUtils.isBlank(enginOrder.getServiceId())) {
            throw new RemoteServiceException("表头业务员不能为空");
        }

        // 提交或审批处理
        if (!operType.equals("")) {
            // 返利和现金钱包金额处理
            itemWalletHandleHome(enginOrder, orderItems, operType, enginOrderBean.isExamineResult());
            // 审批通过处理
            if (enginOrderBean.isExamineResult()) {
                // 插入押金管理
                this.insertDepositManage(enginOrder, orderItems);
                // 推送金蝶销售订单
//                this.syncK3SalesOrder(enginOrder, orderItems);
            }
        }

        // 更新主表
        boolean update = enginOrderService.update(enginOrder, new LambdaUpdateWrapper<EnginOrder>()
                .eq(EnginOrder::getEnginOrderId, enginOrder.getEnginOrderId())
                .eq(operType.equals(SysDictConstant.SUBMIT), EnginOrder::getExamineStatus, ExamineStatusEnum.SAVE.toString())
                .eq(operType.equals(SysDictConstant.EXAMINE), EnginOrder::getExamineStatus, ExamineStatusEnum.WAIT.toString()));
        if (!update) {
            throw new RemoteServiceException("当前单据状态非" + (operType.equals(SysDictConstant.SUBMIT) ? "保存" : "待审核") + "，处理失败");
        }

        if (operType.equals(SysDictConstant.EXAMINE) && !enginOrderBean.isExamineResult()) {
            return null;
        }

        enginOrderBean.setEnginOrderNo(enginOrder.getEnginOrderNo());
        enginOrderBean.setServiceId(enginOrder.getServiceId());

        // 保存明细
        enginOrderItemService.remove(new LambdaUpdateWrapper<EnginOrderItem>()
                .eq(EnginOrderItem::getParentId, enginOrder.getEnginOrderId()));
        enginOrderItemService.saveBatch(orderItems);

        if (operType.equals(SysDictConstant.EXAMINE) && enginOrderBean.isExamineResult()) {
            // 插入订单执行明细
            this.insertOrderRecord(enginOrder, orderItems, OrderOperationTypeEnum.ORDER_EXAMINE, "订单审批");

            //非计划单审核通过
            if (!enginOrder.getIsPlanOrder()) {
                // 非计划单提交生成发货单
                invoiceAddProject(enginOrder, orderItems);
                //审核通过发货单
                invoiceApprovalInvoiceProject(enginOrder, orderItems);
            }
        }
        return enginOrder;
    }

    /**
     * 订单执行记录
     * @param order
     * @param orderItems
     */
    private void insertOrderRecord(EnginOrder order, List<EnginOrderItem> orderItems, OrderOperationTypeEnum type,
                                   String refType) {
        if (type.getKey().equals(OrderOperationTypeEnum.ORDER_EXAMINE.getKey())) {
            orderExecRecordService.lambdaUpdate()
                    .eq(OrderExecRecord::getRefOrderId, order.getEnginOrderNo())
                    .remove();
        }

        List<OrderExecRecord> recordList = new ArrayList<>();
        for (EnginOrderItem item : orderItems) {
            OrderExecRecord record = new OrderExecRecord();
            BeanUtils.copyProperties(item, record);
            record.setCustomerId(order.getCustomerId())
                    .setCustomerName(order.getCustomerName())
                    .setCustomerNumber(order.getCustomerNumber())
                    .setAdminCompanyId(order.getAdminCompanyId())
                    .setOrderType(order.getEnginOrderType())
                    .setTheTime((OrderOperationTypeEnum.ORDER_EXAMINE.getKey().equals(type.getKey()) ? order.getOrderDate() : DateUtil.date()))
                    .setK3ServiceId(order.getServiceId())
                    .setK3ServiceName(order.getServiceName())
                    .setRefOrderId(order.getEnginOrderNo() + (OrderOperationTypeEnum.ORDER_REFUND.getKey().equals(type.getKey()) ? "T" : ""))
                    .setRefEnginRecordNo(order.getRefEnginRecordNo())
                    .setRefOrderItemId(item.getId())
                    .setAdminUserId(order.getAdminUserId())
                    .setAdminWebsitId(order.getAdminWebsitId())
                    .setMaterialCode(item.getMaterialNumber())
                    .setOrderOperationType(type.getKey())
                    .setDirection(type.getKey().equals(OrderOperationTypeEnum.ORDER_EXAMINE.getKey()) ? 1 : -1)
                    .setRefType(refType)
                    .setOrderCreateTime(order.getCreateTime())
                    .setCreateBy(null)
                    .setCreateTime(null);
            recordList.add(record);
        }

        orderExecRecordService.saveBatch(recordList);
    }

    @Transactional(rollbackFor = Exception.class)
    public void execHandlerTrade(EnginOrderBean enginOrderBean, String operType) throws Exception {
        AdminUserCom adminUser = commonLogic.getAdminUser();

        // 查询原单
        EnginOrder enginOrder = orgOrderInfoHandler(adminUser, enginOrderBean, operType);

        enginOrder = enginOrderBean.handleAddTradeOrderInfo(null, enginOrder);
        List<EnginOrderItem> orderItems;
        if (!operType.equals(SysDictConstant.EXAMINE)) {
            // 非审核操作
            orderItems = enginOrderBean.handleAddTradeOrderItem(enginOrder);
        } else {
            // 审核操作
            orderItems = enginOrderItemService.lambdaQuery()
                    .eq(EnginOrderItem::getParentId, enginOrder.getEnginOrderId())
                    .list();
            // 驳回时更新引用单的已订数量
            if (!enginOrderBean.isExamineResult()) {
                this.updateRefInfoData(enginOrder, orderItems, -1, operType);
            }
        }

        if (operType.equals(SysDictConstant.SUBMIT)) {
            // 更新引用单的已订数量
            this.updateRefInfoData(enginOrder, orderItems, 1, operType);
        }

        // 提交或审批处理
        if (!operType.equals("")) {
            // 返利和现金钱包金额处理
            itemWalletHandleTrade(enginOrder, orderItems, operType, enginOrderBean.isExamineResult());
            // TODO 商用订单审批通过不再插入押金表
            // 审批通过处理
//            if (enginOrderBean.isExamineResult()) {
                // 插入押金管理
//                this.insertDepositManage(enginOrder, orderItems);
                // 推送金蝶销售订单
//                this.syncK3SalesOrder(enginOrder, orderItems);
//            }
        }

        // 更新主表
        boolean update = enginOrderService.update(enginOrder, new LambdaUpdateWrapper<EnginOrder>()
                .eq(EnginOrder::getEnginOrderId, enginOrder.getEnginOrderId())
                .eq(operType.equals(SysDictConstant.SUBMIT), EnginOrder::getExamineStatus, ExamineStatusEnum.SAVE.toString())
                .eq(operType.equals(SysDictConstant.EXAMINE), EnginOrder::getExamineStatus, ExamineStatusEnum.WAIT.toString()));
        if (!update) {
            throw new RemoteServiceException("当前单据状态非" + (operType.equals(SysDictConstant.SUBMIT) ? "保存" : "待审核")  + "，处理失败");
        }

        if (operType.equals(SysDictConstant.EXAMINE) && !enginOrderBean.isExamineResult()) {
            return;
        }

        enginOrderBean.setEnginOrderNo(enginOrder.getEnginOrderNo());
        enginOrderBean.setServiceId(enginOrder.getServiceId());

        // 保存明细
        enginOrderItemService.remove(new LambdaUpdateWrapper<EnginOrderItem>()
                .eq(EnginOrderItem::getParentId, enginOrder.getEnginOrderId()));
        enginOrderItemService.saveBatch(orderItems);

        if (operType.equals(SysDictConstant.SUBMIT) && !enginOrder.getIsPlanOrder()) {
            // 非计划单提交生成发货单
            invoiceAddProject(enginOrder,orderItems);
        }


        if (operType.equals(SysDictConstant.EXAMINE) && enginOrderBean.isExamineResult()) {
            // 插入订单执行明细
            this.insertOrderRecord(enginOrder, orderItems, OrderOperationTypeEnum.ORDER_EXAMINE, "订单审批");

            //非计划单审核通过
            if (!enginOrder.getIsPlanOrder()) {
                //审核通过发货单
                invoiceApprovalInvoiceProject(enginOrder,orderItems);
            }

        }
    }

    private void syncK3SalesOrder(EnginOrder enginOrder, List<EnginOrderItem> orderItems) {
        ResultEntity resultEntity = this.toK3SalesOrder(enginOrder, orderItems);
        if(Objects.isNull(resultEntity)) {
            throw new RemoteServiceException("同步金蝶单据失败");
        }
        // 回填金蝶信息
        enginOrder.setKingDeeId(resultEntity.getId());
        enginOrder.setKingDeeSync(StringUtils.isNotBlank(resultEntity.getId()) ? K3SyncStatusEnum.SALES.toString() : K3SyncStatusEnum.NOT.toString());
        if (StringUtils.isNotBlank(resultEntity.getId())) {
            Map<String, BillItem> map = resultEntity.getItems().stream()
                    .collect(Collectors.toMap(BillItem::getSupplyColVal, Function.identity()));
            for (EnginOrderItem item : orderItems) {
                BillItem billItem = map.get(item.getId());
                if (Objects.isNull(billItem)) {
                    throw new RemoteServiceException(item.getMaterialNumber() + item.getMaterialName() + "：金蝶物料不存在");
                }
                item.setKingDeeSeq(billItem.getSeq());
                item.setKingDeeEntryId(billItem.getEntryId());
            }
        }
    }

    private ResultEntity toK3SalesOrder(EnginOrder enginOrder, List<EnginOrderItem> orderItems) {
        K3CustomerBean customer = k3CustomerLogic.detail(enginOrder.getCustomerId());
        SalesOrderBean salesOrderBean = new SalesOrderBean();
        salesOrderBean.setBillNo(enginOrder.getEnginOrderNo());
        salesOrderBean.setCustomerNumber(customer.getNumber());
        salesOrderBean.setOrgNumber(customer.getUseOrgNumber());
        salesOrderBean.setDate(DateUtil.formatDate(enginOrder.getCreateTime()));

        //所有物料单位
        List<KingDeeMaterial> kingDeeMaterials = k3MaterialLogic.allUnit();

        List<SalesOrderItemBean> k3Items = new ArrayList<>();
        for (EnginOrderItem item : orderItems) {
            SalesOrderItemBean k3Item = new SalesOrderItemBean();
            CustomerProductTypeRela customerProductTypeRela = customerProductTypeLogic.getByCustomerWalletId(item.getCustomerWalletId());
            if(customerProductTypeRela != null && StringUtils.isNotEmpty(customerProductTypeRela.getK3OrgNumber())){
                // k3Item.setK3OrgNumber(customerProductTypeRela.getK3OrgNumber());
            }

            k3Item.setSupplyColVal(item.getId());
            k3Item.setMaterialNumber(item.getMaterialNumber());
            k3Item.setQty(BigDecimal.valueOf(item.getQty()));
            k3Item.setTaxPrice(item.getPrice());
            k3Item.setDiscount(item.getTotalDiscAmount().add(item.getPayRebateAmount()));
            k3Item.setUnit(k3MaterialLogic.queryUnitCode(kingDeeMaterials,item.getUnit()));
            k3Item.setEntryNote(item.getRemark());
            k3Item.setWalletNumber(item.getCustomerWalletNumber());
            k3Item.setfOrderEntryPlan(salesOrderBean.getDate());
            k3Items.add(k3Item);
        }
        salesOrderBean.setOrderItems(k3Items);

        return salesOrderLogic.syncBillData(salesOrderBean);
    }

    private void updateRefInfoData(EnginOrder enginOrder, List<EnginOrderItem> orderItems, int direction, String operType) {
        if (enginOrder.getEnginOrderType().equals(OrderTypeEnum.TRADE.getKey())) {
            // 更新商用工程信息单已订数量
            List<EnginInfoOrderItem> infoItems = enginInfoOrderItemService.lambdaQuery()
                    .eq(EnginInfoOrderItem::getEnginInfoNo, enginOrder.getRefEnginRecordNo())
                    .list();
            Map<String, EnginOrderItem> orderItemMap = orderItems.stream()
                    .collect(Collectors.toMap(v -> v.getSaleTypeId() + v.getMaterialId(), Function.identity(), (key1, key2) -> key2));

            for (EnginInfoOrderItem infoItem : infoItems) {
                EnginOrderItem enginOrderItem = orderItemMap.get(infoItem.getSaleTypeId() + infoItem.getMaterialId());
                if (Objects.nonNull(enginOrderItem)) {
                    infoItem.setHasOrderQty(infoItem.getHasOrderQty() + (enginOrderItem.getQty() * direction));
                    if (operType.equals(SysDictConstant.SUBMIT) && infoItem.getHasOrderQty() > infoItem.getQty()) {
                        throw new RemoteServiceException(enginOrderItem.getMaterialOldNumber() + "产品编码：" + enginOrderItem.getMaterialName() + "的数量累计已超过信息单上数量");
                    }
                }
            }

            enginInfoOrderItemService.saveOrUpdateBatch(infoItems);
        }
    }

    private EnginOrder orgOrderInfoHandler(AdminUserCom adminUser, EnginOrderBean enginOrderBean, String operType) {
        EnginOrder enginOrder = enginOrderService.lambdaQuery()
                .eq(EnginOrder::getEnginOrderId, enginOrderBean.getEnginOrderId())
                .in(CollectionUtil.isNotEmpty(adminUser.getAdminCompanyIds()), EnginOrder::getAdminCompanyId, adminUser.getAdminCompanyIds())
                .eq(EnginOrder::getEnginOrderType, enginOrderBean.getEnginOrderType())
                .eq(adminUser.getIsCustomer(), EnginOrder::getCustomerId, adminUser.getCustomerId())
                .one();

        if (Objects.isNull(enginOrder)
                || enginOrder.getExamineStatus().equals(ExamineStatusEnum.OK.toString())
                || enginOrder.getExamineStatus().equals(ExamineStatusEnum.FAIL.toString())
                || enginOrder.getExamineStatus().equals(ExamineStatusEnum.CLOSE.toString())) {
            if (Objects.isNull(enginOrder)) {
                throw new RemoteServiceException("单据不存在");
            }
            throw new RemoteServiceException("当前单据状态：" + ExamineStatusEnum.getMsg(enginOrder.getExamineStatus()) + "，操作失败，请重新加载");
        }

        if (!enginOrder.getRefEnginRecordNo().equals(enginOrderBean.getRefEnginRecordNo())) {
            throw new RemoteServiceException("已保存订单不能更改引用单号");
        }

        if (operType.equals(SysDictConstant.SUBMIT)) {
            enginOrder.setExamineStatus(ExamineStatusEnum.WAIT.toString())
                    .setSubmitBy(CommonUtils.getUsername())
                    .setSubmitName(CommonUtils.getNickName())
                    .setSubmitTime(DateUtil.date());
            enginOrderBean.setOrderDate(DateUtil.date());
        } else if (operType.equals(SysDictConstant.EXAMINE)) {
            if (adminUser.getIsCustomer()) {
                throw new RemoteServiceException("经销商不能审批订单");
            }
            enginOrder.setExamineStatus(enginOrderBean.isExamineResult() ? ExamineStatusEnum.OK.toString() : ExamineStatusEnum.SAVE.toString())
                    .setExamineNote(enginOrderBean.getExamineNote())
                    .setConfirmBy(CommonUtils.getUsername())
                    .setConfirmName(CommonUtils.getNickName())
                    .setConfirmTime(DateUtil.date());
        }
        enginOrder.setUpdateBy(CommonUtils.getUsername());
        enginOrder.setUpdateName(CommonUtils.getNickName());
        enginOrder.setIsPlanOrder(enginOrderBean.getIsPlanOrder());
        enginOrder.setCorrespondId(enginOrderBean.getCorrespondId());
        enginOrder.setCorrespondName(enginOrderBean.getCorrespondName());

        return enginOrder;
    }

    /**
     * 明细钱包处理
     * 1.提交操作时遍历明细，实际支付金额+待审核实际支付金额，如果大于钱包余额+可使用的信用额度，不允许提交
     * 2.审核通过时扣款
     * @param enginOrder
     * @param orderItems
     * @param operType
     * @param examineResult
     * @throws Exception
     */
    private void itemWalletHandleHome(EnginOrder enginOrder, List<EnginOrderItem> orderItems, String operType, boolean examineResult) throws Exception {
        // 审批驳回时退款处理
//        if (operType.equals(SysDictConstant.EXAMINE) && !examineResult) {
//            // 退回提交时的扣款
//            List<EnginOrderItem> itemList = enginOrderItemService.lambdaQuery().eq(EnginOrderItem::getParentId, enginOrder.getEnginOrderId()).list();
//            if (CollectionUtils.isNotEmpty(itemList)) {
//                walletLogic.doWalletAmount(this.handleWalletMethod(enginOrder, itemList, true, "工程订单退款-审批驳回", "工程订单返利单退款-审批驳回"));
//            }
//            enginOrder.setAdvanceStatus(false);
//            return;
//        }

        // 审批通过时把钱在程序处理时虚拟退回钱包
//        if (operType.equals(SysDictConstant.EXAMINE) && examineResult) {
//            // 退回提交时的扣款重新扣款
//            List<EnginOrderItem> itemList = enginOrderItemService.lambdaQuery().eq(EnginOrderItem::getParentId, enginOrder.getEnginOrderId()).list();
//            if (CollectionUtils.isNotEmpty(itemList)) {
//                walletAmountBeans.addAll(this.handleWalletMethod(enginOrder, itemList, true, "工程订单退款-审批通过", "工程订单返利单退款-审批通过"));
//            }
//            enginOrder.setAdvanceStatus(false);
//        }

        BigDecimal depositRate = this.queryOrderTakeDeposit(enginOrder);
        int depositCompare = depositRate.compareTo(BigDecimal.ZERO);

        //查询钱包名称
        List<CustomerWalletBean> customerWalletBeans = walletLogic.queryWalletByCustomerId(enginOrder.getCustomerId(), null,null);
        Map<String, CustomerWalletBean> walletMap = customerWalletBeans.stream()
                .collect(Collectors.toMap(CustomerWalletBean::getCustomerWalletId, v -> v));

        Map<String, EnginOrderItem> waitWalletMap = null;
        // 是否存在直调产品
        boolean isExistDirect = this.checkDirect(orderItems);

        if (operType.equals(SysDictConstant.SUBMIT)) {
            // 提交时查询未审核明细实际支付金额
            List<String> customerWalletIds = orderItems.stream()
                    .map(EnginOrderItem::getCustomerWalletId)
                    .collect(Collectors.toList());
            List<EnginOrderItem> waitWallets = enginOrderReserveMapper.queryWaitPayAmount(enginOrder.getCustomerId(), ExamineStatusEnum.WAIT.toString(), customerWalletIds, null);
            if (CollectionUtil.isNotEmpty(waitWallets)) {
                waitWalletMap = waitWallets.stream().collect(Collectors.toMap(EnginOrderItem::getCustomerWalletId, Function.identity()));
            }
        }


        for(EnginOrderItem orderItem : orderItems){
            // 现金钱包
            CustomerWalletBean amountCustomerWallet = walletMap.get(orderItem.getCustomerWalletId());
            // 返利钱包
            CustomerWalletBean rebateCustomerWallet = walletMap.get(orderItem.getCustomerWalletId2());
            if (amountCustomerWallet == null) {
                throw new RemoteServiceException("请选择现金钱包");
            }
            if (StringUtils.isEmpty(amountCustomerWallet.getServiceId())) {
                throw new RemoteServiceException("钱包【"+amountCustomerWallet.getName()+"】未绑定业务员，无法下单");
            }
            // 单价
            BigDecimal price = orderItem.getPrice();
            // 折扣价
            BigDecimal discAmount = orderItem.getDiscAmount();
            // 数量
            BigDecimal qty = BigDecimal.valueOf(orderItem.getQty());
            // 折后单价
            BigDecimal discPrice = price.subtract(discAmount);
            // 明细订单金额 (单价-折扣价)*数量
            BigDecimal totalAmount = discPrice.multiply(qty);
            // 总折扣价格
            BigDecimal totalDiscAmount = discAmount.multiply(qty);
            // 总返利价格
            BigDecimal totalRebateAmount = new BigDecimal(0);
            // 单个返利
            BigDecimal singleRebateAmount = new BigDecimal(0);
            // 实际使用返利金额
            BigDecimal payRebateAmount = totalRebateAmount;

            if (Objects.nonNull(rebateCustomerWallet) && rebateCustomerWallet.getAmount().doubleValue() > 100) {
                BigDecimal rebateRate = CommonUtils.getRebateRate(rebateCustomerWallet, orderItem.getSaleTypeId());
                singleRebateAmount = discPrice.multiply(rebateRate).setScale(2, BigDecimal.ROUND_DOWN);
                totalRebateAmount = singleRebateAmount.multiply(qty);
                orderItem.setRebateRate(rebateRate);
                if (rebateCustomerWallet.getAmount().doubleValue() < totalRebateAmount.doubleValue()){
                    // 获取截取后2位数后的单个返利金额
                    singleRebateAmount = rebateCustomerWallet.getAmount().divide(qty, 2, BigDecimal.ROUND_DOWN);
                    payRebateAmount = singleRebateAmount.multiply(qty);
                    discPrice = discPrice.subtract(singleRebateAmount);
                    rebateCustomerWallet.setAmount(rebateCustomerWallet.getAmount().subtract(payRebateAmount));
                } else if (rebateCustomerWallet.getAmount().doubleValue() > totalRebateAmount.doubleValue()) {
                    payRebateAmount = totalRebateAmount;
                    discPrice = discPrice.subtract(singleRebateAmount);
                    rebateCustomerWallet.setAmount(rebateCustomerWallet.getAmount().subtract(payRebateAmount));
                }
            }

            // 实际支付价格
            BigDecimal payAmount = totalAmount.subtract(payRebateAmount);

            // 单个押金和押金总额
            BigDecimal singleDepositAmount = depositCompare >= 0 ? discPrice.multiply(depositRate).setScale(2, BigDecimal.ROUND_DOWN) : BigDecimal.ZERO;
            BigDecimal totalDepositAmount = depositCompare >= 0 ? singleDepositAmount.multiply(qty) : BigDecimal.ZERO;

            if (operType.equals(SysDictConstant.SUBMIT)) {
                if (CollectionUtil.isNotEmpty(waitWalletMap)) {
                    // 实际支付金额+待审核实际支付金额，如果大于钱包余额+可使用的信用额度，不允许提交
                    EnginOrderItem waitWallet = waitWalletMap.get(orderItem.getCustomerWalletId());
                    if (Objects.nonNull(waitWallet)) {
                        BigDecimal sumPayAmount = payAmount.add(waitWallet.getPayAmount());

                        // 如果非一期旧单 并且扣押金=扣 并且是直调，加上押金总额
                        if (!enginOrder.getIsFirstOldOrder() && !enginOrder.getTakeDeposit() && isExistDirect) {
                            sumPayAmount = sumPayAmount.add(totalDepositAmount);
                        }

                        if (sumPayAmount.compareTo(amountCustomerWallet.getAmount().add(amountCustomerWallet.getFreeCreditAmount())) > 0) {
                            throw new RemoteServiceException("\"" + orderItem.getMaterialName() + "\"的产品现金钱包余额不足，提交失败");
                        }
                        waitWallet.setPayAmount(sumPayAmount);
                    }
                } else {
                    BigDecimal sumPayAmount = payAmount;
                    // 如果非一期旧单 并且扣押金=扣 并且是直调，加上押金总额
                    if (!enginOrder.getIsFirstOldOrder() && !enginOrder.getTakeDeposit() && isExistDirect) {
                        sumPayAmount = sumPayAmount.add(totalDepositAmount);
                    }

                    // 实际支付金额如果大于（钱包余额+可使用的信用额度-上次遍历相加实际支付金额），不允许提交
                    BigDecimal walletAmount = amountCustomerWallet.getAmount()
                            .add(amountCustomerWallet.getFreeCreditAmount())
                            .subtract(amountCustomerWallet.getComputeSubAmount());
                    if (sumPayAmount.compareTo(walletAmount) > 0) {
                        throw new RemoteServiceException("\"" + orderItem.getMaterialName() + "\"产品现金钱包余额不足，计算后剩余" + walletAmount + "，提交失败");
                    }
                    amountCustomerWallet.setComputeSubAmount(amountCustomerWallet.getComputeSubAmount().add(sumPayAmount));
                }
            }

            orderItem.setCustomerWalletName(amountCustomerWallet.getName());
            orderItem.setCustomerWalletNumber(amountCustomerWallet.getWalletNumber());
            orderItem.setWalletId1(amountCustomerWallet.getWalletRebateId());
            orderItem.setServiceId(amountCustomerWallet.getServiceId());
            orderItem.setServiceName(amountCustomerWallet.getServiceName());
            orderItem.setCustomerWalletName2(null);
            if(Objects.nonNull(rebateCustomerWallet)) {
                orderItem.setCustomerWalletName2(rebateCustomerWallet.getName());
                orderItem.setWalletId2(rebateCustomerWallet.getWalletRebateId());
            }

            orderItem.setId(IdWorker.getIdStr());
            orderItem.setTotalAmount(totalAmount);
            orderItem.setRebateAmount(totalRebateAmount.doubleValue() < 0 ? BigDecimal.valueOf(0) : totalRebateAmount);
            orderItem.setPayAmount(payAmount.doubleValue() < 0 ? BigDecimal.valueOf(0) : payAmount);
            orderItem.setPayRebateAmount(payRebateAmount.doubleValue() <= 0 ? BigDecimal.valueOf(0) : payRebateAmount);
            orderItem.setOldQty(orderItem.getQty());
            orderItem.setOldPayAmount(orderItem.getPayAmount());
            orderItem.setOldRebateAmount(orderItem.getPayRebateAmount());
            orderItem.setTotalDiscAmount(totalDiscAmount);
            orderItem.setSingleRebateAmount(payRebateAmount.doubleValue() <= 0 ? BigDecimal.valueOf(0) : singleRebateAmount);
            orderItem.setSinglePayPrice(discPrice);
//            orderItem.setPayCreditAmount(creditAmount);
//            orderItem.setPayCashAmount(payAmount.subtract(creditAmount));
            orderItem.setRefundableQty(orderItem.getQty());
            // 计算产品押金比例
            orderItem.setDepositRate(depositRate);
            orderItem.setSingleDepositAmount(singleDepositAmount);
            orderItem.setTotalDepositAmount(totalDepositAmount);
            orderItem.setDirectDepositAmount(isExistDirect && !enginOrder.getIsFirstOldOrder() ? totalDepositAmount : BigDecimal.ZERO);
            orderItem.setDirectTransferStatus(enginOrder.getDirectTransferStatus());
        }

//        if (operType.equals(SysDictConstant.SUBMIT)) {
//            walletLogic.doWalletAmount(this.handleWalletMethod(enginOrder, orderItems, false,
//                    "工程订单扣款-提交", "工程订单返利扣款-提交"));
//            enginOrder.setAdvanceStatus(true);
//        }
        if (operType.equals(SysDictConstant.EXAMINE) && examineResult) {
            List<CustomerWalletAmountBean> walletAmountBeans = new ArrayList<>(this.handleWalletMethod(enginOrder,
                    orderItems, false, "工程订单扣款-审批", "工程订单返利扣款-审批"));

            // 如果非一期旧单 并且是否不扣押金=false 并且是直调，扣押金
            if (!enginOrder.getIsFirstOldOrder() && !enginOrder.getTakeDeposit() && isExistDirect) {
                // TODO 订单全扣押金
                List<CustomerWalletAmountBean> beans = this.handleDirectDeposit(enginOrder, orderItems, "家用工程订单押金扣款-审批",
                        WalletDirectionEnum.SUB.getKey(), enginOrder.getCreateTime());
                if (CollectionUtil.isNotEmpty(beans))
                    walletAmountBeans.addAll(beans);
            }

            walletLogic.doWalletAmount(walletAmountBeans);
            enginOrder.setAdvanceStatus(true);
        }
    }

    public List<CustomerWalletAmountBean> handleDirectDeposit(EnginOrder order, List<EnginOrderItem> items,
                                                               String billType, String direction, Date theTime) {
        List<CustomerWalletAmountBean> walletAmountBeans = new ArrayList<>();
        List<EnginOrderItemDepositRecord> recordList = new ArrayList<>();

        String orderNo = order.getEnginOrderNo() + "|" + order.getRefEnginRecordNo();

        for (EnginOrderItem item : items) {
            if (item.getDirectDepositAmount().doubleValue() > 0) {
                walletAmountBeans.add(new CustomerWalletAmountBean(item.getCustomerWalletId(), item.getDirectDepositAmount(), item.getRemark()
                        , billType, theTime, orderNo, 4, direction));

                recordList.add(this.generateEnginDepositRecord(order, item, direction));
            }
        }

        if (CollectionUtil.isNotEmpty(recordList))
            enginOrderItemDepositRecordService.saveBatch(recordList);

        return walletAmountBeans;
    }

    /**
     * 生成工程扣押记录
     * @param order
     * @param item
     * @param direction
     * @return
     */
    private EnginOrderItemDepositRecord generateEnginDepositRecord(EnginOrder order, EnginOrderItem item, String direction) {
        return new EnginOrderItemDepositRecord().setId(IdWorker.getIdStr())
                        .setEnginOrderId(order.getEnginOrderId())
                        .setRefEnginRecordNo(order.getRefEnginRecordNo())
                        .setSaleTypeId(order.getSaleTypeId())
                        .setSaleTypeCode(order.getSaleTypeName())
                        .setSaleTypeName(order.getSaleTypeName())
                        .setMaterialId(item.getMaterialId())
                        .setMaterialName(item.getMaterialName())
                        .setMaterialNumber(item.getMaterialNumber())
                        .setMaterialOldNumber(item.getMaterialOldNumber())
                        .setSpecification(item.getSpecification())
                        .setUnit(item.getUnit())
                        .setPrice(item.getPrice())
                        .setQty(item.getQty())
                        .setRealMaterialId(item.getRealMaterialId())
                        .setRealMaterialName(item.getRealMaterialName())
                        .setRealMaterialNumber(item.getRealMaterialNumber())
                        .setRealMaterialOldNumber(item.getRealMaterialOldNumber())
                        .setRealSpecification(item.getRealSpecification())
                        .setDepositRate(item.getDepositRate())
                        .setSingleDepositAmount(item.getSingleDepositAmount())
                        .setDepositAmount(item.getTotalDepositAmount())
                        .setCustomerWalletId(item.getCustomerWalletId())
                        .setCustomerWalletName(item.getCustomerWalletName())
                        .setRemark(item.getRemark())
                        .setDirection(WalletDirectionEnum.ADD.getKey().equals(direction) ? 1 : -1);
    }

    private boolean checkDirect(List<EnginOrderItem> orderItems) {
        for (EnginOrderItem orderItem : orderItems) {
            if (orderItem.getIsDirectTransfer()) {
                return true;
            }
        }
        return false;
    }

    private void itemWalletHandleTrade(EnginOrder enginOrder, List<EnginOrderItem> orderItems, String operType, boolean examineResult) throws Exception {
        if (operType.equals(SysDictConstant.EXAMINE) && !examineResult && !enginOrder.getIsPlanOrder()) {
            // 非计划单审批驳回时退款处理
            if (CollectionUtil.isNotEmpty(orderItems)) {
                walletLogic.doWalletAmount(this.handleWalletMethod(enginOrder, orderItems, true, "工程订单退款-审批驳回", "工程订单返利单退款-审批驳回"));
            }
            enginOrder.setAdvanceStatus(false);

            //驳回删除发货单
            InvoiceApplication one = invoiceApplicationService.lambdaQuery().eq(InvoiceApplication::getEnginOrderNo, enginOrder.getEnginOrderNo()).last("limit 1").one();
            invoiceLogic.submitProject(one.getId(),"SAVE");
            invoiceLogic.deleteProject(one.getId());
            return;
        } else if (operType.equals(SysDictConstant.EXAMINE) && !examineResult && enginOrder.getIsPlanOrder()) {
            // 计划单审批驳回时不做处理
            return;
        }

        Map<String, EnginOrderItem> waitWalletMap = null;

        if (operType.equals(SysDictConstant.SUBMIT) && enginOrder.getIsPlanOrder()) {
            // 提交时查询未审核明细实际支付金额
            List<String> customerWalletIds = orderItems.stream()
                    .map(EnginOrderItem::getCustomerWalletId)
                    .collect(Collectors.toList());
            List<EnginOrderItem> waitWallets = enginOrderReserveMapper.queryWaitPayAmount(enginOrder.getCustomerId(), ExamineStatusEnum.WAIT.toString(), customerWalletIds, true);
            if (CollectionUtil.isNotEmpty(waitWallets)) {
                waitWalletMap = waitWallets.stream().collect(Collectors.toMap(EnginOrderItem::getCustomerWalletId, Function.identity()));
            }
        }


        BigDecimal depositRate = this.queryOrderTakeDeposit(enginOrder);
        BigDecimal zero = new BigDecimal("0");
        int depositCompare = depositRate.compareTo(zero);

        //查询钱包名称
        List<CustomerWalletBean> customerWalletBeans = walletLogic.queryWalletByCustomerId(enginOrder.getCustomerId(), null,null);
        Map<String, CustomerWalletBean> walletMap = customerWalletBeans.stream()
                .collect(Collectors.toMap(CustomerWalletBean::getCustomerWalletId, v -> v));

        for(EnginOrderItem orderItem : orderItems){
            if (operType.equals(SysDictConstant.EXAMINE) && examineResult && !enginOrder.getIsPlanOrder()) {
                continue;
            }
            // 现金钱包
            CustomerWalletBean amountCustomerWallet = walletMap.get(orderItem.getCustomerWalletId());
            // 返利钱包
            CustomerWalletBean rebateCustomerWallet = walletMap.get(orderItem.getCustomerWalletId2());
            if (amountCustomerWallet == null) {
                throw new RemoteServiceException("请选择现金钱包");
            }
            if (StringUtils.isEmpty(amountCustomerWallet.getServiceId())) {
                throw new RemoteServiceException("钱包【"+amountCustomerWallet.getName()+"】未绑定业务员，无法下单");
            }
            // 单价
            BigDecimal price = orderItem.getPrice();
            // 折扣价
            BigDecimal discAmount = orderItem.getDiscAmount();
            // 数量
            BigDecimal qty = BigDecimal.valueOf(orderItem.getQty());
            // 折后单价
            BigDecimal discPrice = price.subtract(discAmount);
            // 明细订单金额 (单价-折扣价)*数量
            BigDecimal totalAmount = discPrice.multiply(qty);
            // 总折扣价格
            BigDecimal totalDiscAmount = discAmount.multiply(qty);
            // 总返利价格
            BigDecimal totalRebateAmount = new BigDecimal(0);
            // 单个返利
            BigDecimal singleRebateAmount = new BigDecimal(0);
            // 实际使用返利金额
            BigDecimal payRebateAmount = totalRebateAmount;

            if (Objects.nonNull(rebateCustomerWallet) && rebateCustomerWallet.getAmount().doubleValue() > 100) {
                BigDecimal rebateRate = CommonUtils.getRebateRate(rebateCustomerWallet, orderItem.getSaleTypeId());
                singleRebateAmount = discPrice.multiply(rebateRate).setScale(2, BigDecimal.ROUND_DOWN);
                totalRebateAmount = singleRebateAmount.multiply(qty);
                orderItem.setRebateRate(rebateRate);
                if (rebateCustomerWallet.getAmount().doubleValue() < totalRebateAmount.doubleValue()){
                    // 获取截取后2位数后的单个返利金额
                    singleRebateAmount = rebateCustomerWallet.getAmount().divide(qty, 2, BigDecimal.ROUND_DOWN);
                    payRebateAmount = singleRebateAmount.multiply(qty);
                    discPrice = discPrice.subtract(singleRebateAmount);
                    rebateCustomerWallet.setAmount(rebateCustomerWallet.getAmount().subtract(payRebateAmount));
                } else if (rebateCustomerWallet.getAmount().doubleValue() > totalRebateAmount.doubleValue()) {
                    payRebateAmount = totalRebateAmount;
                    discPrice = discPrice.subtract(singleRebateAmount);
                    rebateCustomerWallet.setAmount(rebateCustomerWallet.getAmount().subtract(payRebateAmount));
                }
            }

            //实际支付价格
            BigDecimal payAmount = totalAmount.subtract(payRebateAmount);

            if (operType.equals(SysDictConstant.SUBMIT) && enginOrder.getIsPlanOrder()) {
                if (CollectionUtil.isNotEmpty(waitWalletMap)) {
                    // 实际支付金额+待审核实际支付金额，如果大于钱包余额+可使用的信用额度，不允许提交
                    EnginOrderItem waitWallet = waitWalletMap.get(orderItem.getCustomerWalletId());
                    if (Objects.nonNull(waitWallet)) {
                        BigDecimal sumPayAmount = payAmount.add(waitWallet.getPayAmount());
                        if (sumPayAmount.compareTo(amountCustomerWallet.getAmount().add(amountCustomerWallet.getFreeCreditAmount())) > 0) {
                            throw new RemoteServiceException("\"" + orderItem.getMaterialName() + "\"的产品现金钱包余额不足，提交失败");
                        }
                        waitWallet.setPayAmount(sumPayAmount);
                    }
                } else {
                    // 实际支付金额如果大于（钱包余额+可使用的信用额度-上次遍历相加实际支付金额），不允许提交
                    BigDecimal walletAmount = amountCustomerWallet.getAmount()
                            .add(amountCustomerWallet.getFreeCreditAmount())
                            .subtract(amountCustomerWallet.getComputeSubAmount());
                    if (payAmount.compareTo(walletAmount) > 0) {
                        throw new RemoteServiceException("\"" + orderItem.getMaterialName() + "\"产品现金钱包余额不足，计算后剩余" + walletAmount + "，提交失败");
                    }
                    amountCustomerWallet.setComputeSubAmount(amountCustomerWallet.getComputeSubAmount().add(payAmount));
                }
            }

            orderItem.setCustomerWalletName(amountCustomerWallet.getName());
            orderItem.setCustomerWalletNumber(amountCustomerWallet.getWalletNumber());
            orderItem.setWalletId1(amountCustomerWallet.getWalletRebateId());
            orderItem.setServiceId(amountCustomerWallet.getServiceId());
            orderItem.setServiceName(amountCustomerWallet.getServiceName());
            orderItem.setCustomerWalletName2(null);
            if(Objects.nonNull(rebateCustomerWallet)) {
                orderItem.setCustomerWalletName2(rebateCustomerWallet.getName());
                orderItem.setWalletId2(rebateCustomerWallet.getWalletRebateId());
            }

            orderItem.setId(IdWorker.getIdStr());
            orderItem.setTotalAmount(totalAmount);
            orderItem.setRebateAmount(totalRebateAmount.doubleValue() < 0 ? BigDecimal.valueOf(0) : totalRebateAmount);
            orderItem.setPayAmount(payAmount.doubleValue() < 0 ? BigDecimal.valueOf(0) : payAmount);
            orderItem.setPayRebateAmount(payRebateAmount.doubleValue() <= 0 ? BigDecimal.valueOf(0) : payRebateAmount);
            orderItem.setOldQty(orderItem.getQty());
            orderItem.setOldPayAmount(orderItem.getPayAmount());
            orderItem.setOldRebateAmount(orderItem.getPayRebateAmount());
            orderItem.setTotalDiscAmount(totalDiscAmount);
            orderItem.setSingleRebateAmount(payRebateAmount.doubleValue() <= 0 ? BigDecimal.valueOf(0) : singleRebateAmount);
            orderItem.setSinglePayPrice(discPrice);
            orderItem.setRefundableQty(orderItem.getQty());
            // 计算产品押金比例
            orderItem.setDepositRate(depositRate);
            orderItem.setSingleDepositAmount(depositCompare >= 0 ? orderItem.getSinglePayPrice().multiply(depositRate).setScale(2, BigDecimal.ROUND_DOWN) : zero);
            orderItem.setTotalDepositAmount(depositCompare >= 0 ? orderItem.getSingleDepositAmount().multiply(qty) : zero);
            orderItem.setDirectTransferStatus(enginOrder.getDirectTransferStatus());
        }

        if (operType.equals(SysDictConstant.SUBMIT) && !enginOrder.getIsPlanOrder()) {
            // 非计划单提交扣款
            walletLogic.doWalletAmount(this.handleWalletMethod(enginOrder, orderItems, false,
                    "工程订单扣款-提交", "工程订单返利扣款-提交"));
            enginOrder.setAdvanceStatus(true);
        } else if (operType.equals(SysDictConstant.EXAMINE) && examineResult && enginOrder.getIsPlanOrder()) {
            // 计划单审核通过扣款
            walletLogic.doWalletAmount(this.handleWalletMethod(enginOrder, orderItems, false,
                    "工程订单扣款-审批", "工程订单返利扣款-审批"));
            enginOrder.setAdvanceStatus(true);
        }

    }

    private void invoiceAddProject(EnginOrder enginOrder, List<EnginOrderItem> orderItems) throws Exception {
        InvoiceRequestJson invoiceRequestJson = BeanUtil.toBean(enginOrder, InvoiceRequestJson.class);
        EnginOrder enginOrderServiceById = enginOrderService.getById(enginOrder.getEnginOrderId());
        invoiceRequestJson.setId(null);
        invoiceRequestJson.setExamineStatus("WAIT");
        invoiceRequestJson.setAutomaticStatus(true);
        invoiceRequestJson.setSyncType(2);
        invoiceRequestJson.setCorrespondName(enginOrderServiceById.getCorrespondName());
        invoiceRequestJson.setCorrespondId(enginOrderServiceById.getCorrespondId());
        if (StringUtils.isEmpty(enginOrderServiceById.getCorrespondId()) && enginOrder.getIsPlanOrder() != null && !enginOrder.getIsPlanOrder())
            throw new RemoteServiceException("仓库为空，请选择仓库");
        invoiceRequestJson.setCorrespondId(enginOrderServiceById.getCorrespondId());
        invoiceRequestJson.setCustomerId(enginOrderServiceById.getCustomerId());
        invoiceRequestJson.setCorrespondName(enginOrderServiceById.getCorrespondName());
        List<InvoiceApplicationOrderRequest> invoiceApplicationOrderRequests = new ArrayList<>();
        for (EnginOrderItem orderItem : orderItems) {
            InvoiceApplicationOrderRequest invoiceApplicationOrderRequest = BeanUtil.toBean(orderItem, InvoiceApplicationOrderRequest.class);
            invoiceApplicationOrderRequest.setId(null);
            invoiceApplicationOrderRequest.setMainOrderId(enginOrder.getEnginOrderId());
            invoiceApplicationOrderRequest.setOrderType(enginOrder.getEnginOrderType());
            invoiceApplicationOrderRequest.setOrderId(orderItem.getId());
            invoiceApplicationOrderRequest.setInvoiceNum(orderItem.getRefundableQty());
            invoiceApplicationOrderRequest.setInvoiceNum(orderItem.getRefundableQty());
            invoiceApplicationOrderRequest.setTheTime(enginOrder.getOrderDate());
            invoiceApplicationOrderRequest.setMaterialCode(orderItem.getMaterialNumber());
            invoiceApplicationOrderRequest.setMaterialId(orderItem.getMaterialId());
            invoiceApplicationOrderRequest.setHeaderRemark(enginOrder.getRemark());
            invoiceApplicationOrderRequest.setRemark(orderItem.getRemark());
            invoiceApplicationOrderRequests.add(invoiceApplicationOrderRequest);
        }
        invoiceRequestJson.setOrders(invoiceApplicationOrderRequests);
        invoiceLogic.addProject(invoiceRequestJson);
    }

    private void invoiceApprovalInvoiceProject(EnginOrder enginOrder, List<EnginOrderItem> orderItems) throws Exception {
        InvoiceApplication one = invoiceApplicationService.lambdaQuery().eq(InvoiceApplication::getEnginOrderNo, enginOrder.getEnginOrderNo()).last("limit 1").one();

        InvoiceRequestJson invoiceRequestJson = new InvoiceRequestJson();
        invoiceRequestJson.setId(one.getId());
        invoiceRequestJson.setCorrespondId(enginOrder.getCorrespondId());
        invoiceRequestJson.setCorrespondName(enginOrder.getCorrespondName());
        invoiceRequestJson.setId(one.getId());
        invoiceRequestJson.setRemark(enginOrder.getRemark());
        invoiceRequestJson.setExamineStatus("OK");
        List<InvoiceApplicationOrderRequest> invoiceApplicationOrderRequests = new ArrayList<>();
        for (EnginOrderItem orderItem : orderItems) {
            InvoiceApplicationOrderRequest invoiceApplicationOrderRequest = BeanUtil.toBean(orderItem, InvoiceApplicationOrderRequest.class);
            InvoiceApplicationOrder invoiceApplicationOrder = invoiceApplicationOrderService.lambdaQuery().eq(InvoiceApplicationOrder::getInvoiceId, one.getId())
                    .eq(InvoiceApplicationOrder::getMaterialId, orderItem.getMaterialId()).eq(InvoiceApplicationOrder::getSaleTypeId,orderItem.getSaleTypeId()).one();
            invoiceApplicationOrderRequest.setId(invoiceApplicationOrder.getId());
            invoiceApplicationOrderRequest.setMainOrderId(enginOrder.getEnginOrderId());
            invoiceApplicationOrderRequest.setApprovalNumber(orderItem.getRefundableQty());
            invoiceApplicationOrderRequest.setOrderType(enginOrder.getEnginOrderType());
            invoiceApplicationOrderRequest.setOrderId(orderItem.getId());
            invoiceApplicationOrderRequest.setInvoiceNum(orderItem.getRefundableQty());
            invoiceApplicationOrderRequest.setTheTime(enginOrder.getOrderDate());
            invoiceApplicationOrderRequest.setMaterialCode(orderItem.getMaterialNumber());
            invoiceApplicationOrderRequest.setHeaderRemark(enginOrder.getRemark());
            invoiceApplicationOrderRequest.setRemark(orderItem.getRemark());
            invoiceApplicationOrderRequests.add(invoiceApplicationOrderRequest);
        }
        invoiceRequestJson.setOrders(invoiceApplicationOrderRequests);
        invoiceLogic.approvalInvoiceProject(invoiceRequestJson);
    }

    public BigDecimal queryOrderTakeDeposit(EnginOrder enginOrder) {
        if (Objects.nonNull(enginOrder.getTakeDeposit()) && !enginOrder.getTakeDeposit()) {
            // 查询押金比例
            return customerEnginDepositLogic.findCustomerDepositRate(enginOrder.getCustomerId());
        }
        return new BigDecimal("0");
    }

    @Transactional(rollbackFor = Exception.class)
    public void closeHome(String id, String refEnginRecordNo, String orderType) throws Exception {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        boolean upd = enginOrderService.lambdaUpdate()
                .set(EnginOrder::getExamineStatus, ExamineStatusEnum.CLOSE.toString())
                .set(EnginOrder::getCloseBy, CommonUtils.getUsername())
                .set(EnginOrder::getCloseName, CommonUtils.getNickName())
                .set(EnginOrder::getCloseTime, DateUtil.date())
                .eq(EnginOrder::getEnginOrderId, id)
                .eq(EnginOrder::getRefEnginRecordNo, refEnginRecordNo)
                .eq(adminUser.getIsCustomer(), EnginOrder::getCustomerId, adminUser.getCustomerId())
                .eq(EnginOrder::getEnginOrderType, orderType)
                .in(EnginOrder::getExamineStatus, ExamineStatusEnum.SAVE.toString(),ExamineStatusEnum.WAIT.toString())
                .eq(EnginOrder::getAdminCompanyId, adminUser.getAdminCompanyId())
                .update();
        if (!upd) {
            throw new RemoteServiceException("订单状态不是“保存或待审批”，关闭失败");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void closeTrade(String id, String refEnginRecordNo, String orderType) throws Exception {
        AdminUserCom adminUser = commonLogic.getAdminUser();

        EnginOrder enginOrder = enginOrderService.lambdaQuery()
                .eq(EnginOrder::getEnginOrderId, id)
                .eq(EnginOrder::getRefEnginRecordNo, refEnginRecordNo)
                .eq(adminUser.getIsCustomer(), EnginOrder::getCustomerId, adminUser.getCustomerId())
                .eq(EnginOrder::getEnginOrderType, orderType)
                .in(EnginOrder::getExamineStatus, ExamineStatusEnum.SAVE.toString(),ExamineStatusEnum.WAIT.toString())
                .eq(EnginOrder::getAdminCompanyId, adminUser.getAdminCompanyId())
                .one();

        if (Objects.isNull(enginOrder)) {
            throw new RemoteServiceException("订单状态不是“保存或待审批”，关闭失败，请重新加载");
        }

        if (enginOrder.getExamineStatus().equals(ExamineStatusEnum.WAIT.toString())) {
            List<EnginOrderItem> list = enginOrderItemService.lambdaQuery().eq(EnginOrderItem::getParentId, id).list();
            // 更新信息单已订数量
            this.updateRefInfoData(enginOrder, list, -1, "");
            if (!enginOrder.getIsPlanOrder()) {
                // 非计划单并且等于提审状态的退款
                walletLogic.doWalletAmount(this.handleWalletMethod(enginOrder, list, true, "工程订单退款-关单", "工程订单返利退款-关单"));
                enginOrder.setAdvanceStatus(false);
                //驳回删除发货单
                if (StringUtils.isEmpty(enginOrder.getKingDeeId())) {
//                InvoiceApplication one = invoiceApplicationService.lambdaQuery().eq(InvoiceApplication::getEnginOrderNo, enginOrder.getEnginOrderNo()).last("limit 1").one();
//                invoiceLogic.submitProject(one.getId(), ExamineStatusEnum.SAVE.getMsg());
//                invoiceLogic.deleteProject(one.getId());
                }

                //驳回删除发货单
                InvoiceApplication one = invoiceApplicationService.lambdaQuery().eq(InvoiceApplication::getEnginOrderNo, enginOrder.getEnginOrderNo()).last("limit 1").one();
                invoiceLogic.submitProject(one.getId(), "SAVE");
                invoiceLogic.deleteProject(one.getId());
            }
        }



        enginOrder.setExamineStatus(ExamineStatusEnum.CLOSE.toString())
                .setCloseBy(CommonUtils.getUsername())
                .setCloseName(CommonUtils.getNickName())
                .setCloseTime(DateUtil.date());

        enginOrder.updateById();


    }

//    @Transactional(rollbackFor = Exception.class)
//    public void directTransfer(EnginOrderBean enginOrderBean) throws Exception {
//        AdminUserCom adminUser = commonLogic.getAdminUser();
//        if (Objects.isNull(enginOrderBean.getDeliverDate())) {
//            throw new RemoteServiceException("发货日期不能为空");
//        }
//
//        // 查询原单直调状态
//        EnginOrder enginOrder = enginOrderService.lambdaQuery()
//                .eq(EnginOrder::getEnginOrderId, enginOrderBean.getEnginOrderId())
//                .eq(adminUser.getIsCustomer(), EnginOrder::getCustomerId, adminUser.getCustomerId())
//                .eq(EnginOrder::getEnginOrderType, enginOrderBean.getEnginOrderType())
//                .eq(EnginOrder::getDirectTransferStatus, false)
//                .eq(EnginOrder::getExamineStatus, ExamineStatusEnum.OK.toString())
//                .eq(EnginOrder::getAdminCompanyId, adminUser.getAdminCompanyId())
//                .one();
//
//        if (Objects.isNull(enginOrder)) {
//            throw new RemoteServiceException("订单状态已发生变化");
//        }
//        // 直调单号
//        String directTransferOrderId = IdWorker.getIdStr();
//
//        List<EnginOrderItem> orderItems = enginOrderItemService.lambdaQuery()
//                .in(EnginOrderItem::getMaterialId, enginOrderBean.getItems().stream()
//                        .map(EnginOrderItemBean::getMaterialId)
//                        .collect(Collectors.toList()))
//                .eq(EnginOrderItem::getParentId, enginOrder.getEnginOrderId())
//                .eq(EnginOrderItem::getIsDirectTransfer, true)
//                .eq(EnginOrderItem::getDirectTransferStatus, false)
//                .list();
//
//        if (CollectionUtil.isEmpty(orderItems)) {
//            throw new RemoteServiceException("没有可直调产品");
//        }
//
//        Map<String, EnginOrderItemBean> itemBeanMap = enginOrderBean.getItems().stream()
//                .collect(Collectors.toMap(EnginOrderItemBean::getMaterialId, Function.identity(), (key1, key2) -> key2));
//
//        List<DepositManageRecordBean> depositManageRecordList = new ArrayList<>(10);
//        List<DirectTransferOrderItem> directTransferOrderItems = new ArrayList<>(10);
//        KingDeeStock kingDeeStock = kingDeeStockService.getById(enginOrderBean.getStockId());
//        // 检查直调数量不能大于数量
//        for (EnginOrderItem orderItem : orderItems) {
//            EnginOrderItemBean itemBean = itemBeanMap.get(orderItem.getMaterialId());
//            Integer realDirectTransferQty = itemBean.getRealDirectTransferQty();
//            int surplus = orderItem.getQty() - orderItem.getDirectTransferQty() - realDirectTransferQty;
//            if (surplus < 0) {
//                throw new RemoteServiceException(orderItem.getMaterialName() + "：的直调数量不能超过剩于数量, 请检查");
//            }
//
//            //判断库存是否足够
//            Integer stock = stockCommonLogic.stockVirtualStatus(enginOrderBean.getStockId(), orderItem.getMaterialId());
//            if(realDirectTransferQty > stock){
//                throw new RemoteServiceException(orderItem.getMaterialName() + "库存不足");
//            }
//            // 更新直调数量
//            orderItem.setDirectTransferQty(orderItem.getDirectTransferQty() + realDirectTransferQty);
//            orderItem.setHasSendQty(orderItem.getHasSendQty() + realDirectTransferQty);
//            // 更新可退数量
//            orderItem.setRefundableQty(orderItem.getQty() - orderItem.getDirectTransferQty());
//
//            // 如果是家用工程押金比例大于0执行扣押金
//            if (enginOrder.getEnginOrderType().equals(OrderTypeEnum.HOME.getKey())
//                    && orderItem.getDepositRate().compareTo(new BigDecimal("0")) > 0) {
//                // 扣押金金额
//                BigDecimal subDepositAmount = orderItem.getSingleDepositAmount().multiply(BigDecimal.valueOf(realDirectTransferQty));
//                DepositManageRecordBean depositManageRecordBean = new DepositManageRecordBean();
//                depositManageRecordBean.handleEnginOrderItem(enginOrder, orderItem, realDirectTransferQty, subDepositAmount);
//                depositManageRecordList.add(depositManageRecordBean);
//            }
//            // 插入直调发货单明细记录
//            directTransferOrderItems.add(insertDirectTransferOrderItem(directTransferOrderId, realDirectTransferQty, orderItem, kingDeeStock));
//
//        }
//        if (CollectionUtils.isNotEmpty(depositManageRecordList)) {
//            depositManageLogic.addDepositAmount(enginOrder.getRefEnginRecordNo(), depositManageRecordList);
//        }
//
//        enginOrderItemService.saveOrUpdateBatch(orderItems);
//
//        // 插入直调发货单记录
//        DirectTransferOrder directTransferOrder = insertDirectTransferOrder(directTransferOrderId, enginOrder, enginOrderBean);
//
//        // TODO 同步金蝶下推销售出库单并保存审核
//        k3CommonMethodLogic.syncK3SalesOutStockOrder(directTransferOrder, directTransferOrderItems);
//    }

//    private DirectTransferOrder insertDirectTransferOrder(String directTransferOrderId, EnginOrder enginOrder, EnginOrderBean enginOrderBean) {
//        DirectTransferOrder directTransferOrder = new DirectTransferOrder();
//        directTransferOrder.setId(directTransferOrderId);
//        directTransferOrder.setAdminCompanyId(enginOrder.getAdminCompanyId());
//        directTransferOrder.setCustomerId(enginOrder.getCustomerId());
//        directTransferOrder.setCustomerNumber(enginOrder.getCustomerNumber());
//        directTransferOrder.setCustomerName(enginOrder.getCustomerName());
//        directTransferOrder.setOrderType(enginOrder.getEnginOrderType());
//        directTransferOrder.setOrderNo(enginOrder.getEnginOrderNo());
//        directTransferOrder.setEnginRecordNo(enginOrder.getRefEnginRecordNo());
//        directTransferOrder.setProjectNo(enginOrder.getRefProjectNo());
//        directTransferOrder.setProjectName(enginOrder.getRefProjectName());
//        directTransferOrder.setUseUnit(enginOrder.getRefUseUnit());
//        directTransferOrder.setInstallAddress(enginOrder.getRefInstallAddress());
//        directTransferOrder.setFactoryNo(enginOrder.getRefFactoryNo());
//        directTransferOrder.setPromiseStatus(enginOrder.getRefPromiseStatus());
//        directTransferOrder.setCorrespondId(enginOrderBean.getCorrespondId());
//        directTransferOrder.setStockId(enginOrderBean.getStockId());
//        directTransferOrder.setDeliverDate(DateUtil.date());
//        directTransferOrder.setRefKingDeeId(enginOrder.getKingDeeId());
//        directTransferOrder.insert();
//        return directTransferOrder;
//    }

//    private DirectTransferOrderItem insertDirectTransferOrderItem(String directTransferOrderId, Integer realDirectTransferQty, EnginOrderItem orderItem, KingDeeStock kingDeeStocks) {
//        DirectTransferOrderItem dItem = new DirectTransferOrderItem();
//        dItem.setDirectTransferOrderId(directTransferOrderId);
//        dItem.setRefOrderId(orderItem.getEnginOrderNo());
//        dItem.setRefOrderItemId(orderItem.getId());
//        dItem.setSaleTypeId(orderItem.getSaleTypeId());
//        dItem.setSaleTypeCode(orderItem.getSaleTypeCode());
//        dItem.setSaleTypeName(orderItem.getSaleTypeName());
//        dItem.setMaterialId(orderItem.getMaterialId());
//        dItem.setMaterialNumber(orderItem.getMaterialNumber());
//        dItem.setMaterialName(orderItem.getMaterialName());
//        dItem.setMaterialOldNumber(orderItem.getMaterialOldNumber());
//        dItem.setSpecification(orderItem.getSpecification());
//        dItem.setUnit(orderItem.getUnit());
//        dItem.setPrice(orderItem.getPrice());
//        dItem.setQty(realDirectTransferQty);
//        dItem.setDiscAmount(orderItem.getDiscAmount());
//        dItem.setMustTotalAmount(orderItem.getTotalAmount());
//        dItem.setRealTotalAmount(orderItem.getPayAmount());
//        dItem.setCustomerWalletId2(orderItem.getCustomerWalletId2());
//        dItem.setRebateAmount(orderItem.getPayRebateAmount());
//        dItem.setCustomerWalletId(orderItem.getCustomerWalletId());
//        dItem.setCustomerWalletNumber(orderItem.getCustomerWalletNumber());
//        dItem.setDirectTransferQty(orderItem.getDirectTransferQty());
//        dItem.setSingleDepositAmount(orderItem.getSingleDepositAmount());
//        dItem.setTotalDepositAmount(orderItem.getSingleDepositAmount().multiply(BigDecimal.valueOf(dItem.getDirectTransferQty())));
//        dItem.setTaxRate(orderItem.getTax());
//        dItem.setAfterTaxPrice(orderItem.getPrice().subtract(orderItem.getPrice().multiply(orderItem.getTax())));
//        dItem.setServiceId(orderItem.getServiceId());
//        dItem.setServiceName(orderItem.getServiceName());
//        dItem.setStockId(kingDeeStocks.getId());
//        dItem.setStockNumber(kingDeeStocks.getNumber());
//        dItem.setStockName(kingDeeStocks.getName());
//        dItem.setRefKingDeeEntryId(orderItem.getKingDeeEntryId());
//        dItem.insert();
//        return dItem;
//    }

    @Transactional(rollbackFor = Exception.class)
    public void refundHome(EnginOrderBean enginOrderBean, String orderType) throws Exception {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        EnginOrder enginOrder = enginOrderService.lambdaQuery()
                .eq(EnginOrder::getEnginOrderId, enginOrderBean.getEnginOrderId())
                .eq(EnginOrder::getRefEnginRecordNo, enginOrderBean.getRefEnginRecordNo())
                .eq(EnginOrder::getEnginOrderType, orderType)
                .eq(EnginOrder::getExamineStatus, ExamineStatusEnum.OK.toString())
                .one();

        if (adminUser.getIsCustomer()) {
            throw new RemoteServiceException("经销商没有权限");
        }

        if (Objects.isNull(enginOrder)) {
            throw new RemoteServiceException("非审核通过单据状态，退订失败，请重新加载");
        }

        List<EnginOrderItem> orderItems = enginOrderItemService.lambdaQuery()
                .eq(EnginOrderItem::getParentId, enginOrderBean.getEnginOrderId())
                .list();

        long count = orderItems.stream().filter(EnginOrderItem::getIsDirectTransfer).count();

        // 如果是新单并且直调未完结，不允许退订
        if (!enginOrder.getIsFirstOldOrder() && !enginOrder.getDirectTransferStatus() && count > 0) {
            throw new RemoteServiceException("订单直调未完结，不允许退订操作");
        }

//        Map<String, Object> enumMap = EnumUtil.getNameFieldMap(OrderTypeEnum.class, "value");

        Map<String, EnginOrderItemBean> itemBeanMap = enginOrderBean.getItems().stream()
                .collect(Collectors.toMap(EnginOrderItemBean::getId, Function.identity(), (key1, key2) -> key2));

        List<EnginOrderItem> refundItems = new ArrayList<>();
        List<EnginOrderItem> k3ChangeItems = new ArrayList<>();
        List<String> endItems = new ArrayList<>();
        List<EnginOrderItem> execRecords = new ArrayList<>();
        for (int i = 0; i < orderItems.size(); i++) {
            EnginOrderItem item = orderItems.get(i);
            EnginOrderItemBean itemBean = itemBeanMap.get(item.getId());

            //处理订单数量和金额，但不处理台账等
            Map<String, Object> map = this.refundItem(item, itemBean.getTdQty());
            if(map != null) {
                item = (EnginOrderItem) map.get("item");
                EnginOrderItem refundOrderItem = (EnginOrderItem) map.get("refund");
                EnginOrderItem execRecord = (EnginOrderItem) map.get("execRecord");

                if (Objects.nonNull(refundOrderItem))
                    refundItems.add(refundOrderItem);

                if (Objects.nonNull(execRecord))
                    execRecords.add(execRecord);

                // 业务终止
                if (item.getRefundableQty() == 0 && itemBean.getTdQty() > 0) {
                    endItems.add(item.getKingDeeEntryId());
                }else if(item.getQty() > 0 && itemBean.getTdQty() > 0){
                    k3ChangeItems.add(item);
                }

                //预留单更改，当数量变为0，修改预留单预留为0，关闭
                if (item.getRefundableQty().equals(0)) {
                    reservedOrderItemService.lambdaUpdate().eq(ReservedOrderItem::getOrderId, item.getId())
                            .set(ReservedOrderItem::getStatus, 0)
                            .set(ReservedOrderItem::getReservedNum, 0).update();
                }
            }
        }

        if (CollectionUtil.isEmpty(refundItems)) {
            throw new RemoteServiceException("退订失败，产品退订数量不能为0");
        }

        if (CollectionUtil.isNotEmpty(k3ChangeItems)) {
            Map<String, EnginOrderItem> itemMap = k3ChangeItems.stream()
                    .collect(Collectors.toMap(EnginOrderItem::getId, Function.identity()));
            List<EnginOrderItem> collect = orderItems.stream()
                    .filter(v -> v.getQty() > 0)
                    .collect(Collectors.toList());
            for (EnginOrderItem item : collect) {
                EnginOrderItem orderItem = itemMap.get(item.getId());
                if (Objects.isNull(orderItem)) {
                    k3ChangeItems.add(item);
                }
            }
        }

        this.callbackDepositManageQty(enginOrder, refundItems, "refund");

        List<CustomerWalletAmountBean> amountBeans = this.handleWalletMethod(enginOrder, refundItems, true,
                "工程订单退款-退订", "工程订单返利退款-退订");

        // 钱包添加退款押金记录
//        List<CustomerWalletAmountBean> beans = this.handleDirectDeposit(enginOrder, refundItems, "家用工程订单押金退款-退订",
//                WalletDirectionEnum.ADD.getKey(), DateUtil.date());
//        if (CollectionUtil.isNotEmpty(beans))
//            walletAmountBeans.addAll(beans);

        walletLogic.doWalletAmount(amountBeans);

        // 推送金蝶销售新变更单
        if (StringUtils.isNotBlank(enginOrder.getKingDeeId())) {
            this.pushSalesChange(enginOrder, enginOrderBean, k3ChangeItems, endItems);
        } else {
            enginOrderRefundNoteService.save(new EnginOrderRefundNote()
                    .setEnginOrderNo(enginOrder.getEnginOrderNo())
                    .setRefundNote(enginOrderBean.getRefundNote()));
        }

        this.insertOrderRecord(enginOrder, execRecords, OrderOperationTypeEnum.ORDER_REFUND, "订单退订");
    }

    @Transactional(rollbackFor = Exception.class)
    public void refundTrade(EnginOrderBean enginOrderBean, String orderType) throws Exception {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        EnginOrder enginOrder = enginOrderService.lambdaQuery()
                .eq(EnginOrder::getEnginOrderId, enginOrderBean.getEnginOrderId())
                .eq(EnginOrder::getRefEnginRecordNo, enginOrderBean.getRefEnginRecordNo())
                .eq(EnginOrder::getEnginOrderType, orderType)
                .eq(EnginOrder::getExamineStatus, ExamineStatusEnum.OK.toString())
                .one();

        if (adminUser.getIsCustomer()) {
            throw new RemoteServiceException("经销商没有权限");
        }

        if (Objects.isNull(enginOrder)) {
            throw new RemoteServiceException("非审核通过单据状态，退订失败，请重新加载");
        }

        if (!enginOrder.getIsPlanOrder()) {
            // 非计划单不允许退订
            throw new RemoteServiceException("非计划单不允许退订");
        }

        Map<String, EnginOrderItemBean> itemBeanMap = enginOrderBean.getItems().stream()
                .collect(Collectors.toMap(EnginOrderItemBean::getId, Function.identity(), (key1, key2) -> key2));

        List<EnginOrderItem> orderItems = enginOrderItemService.lambdaQuery().eq(EnginOrderItem::getParentId, enginOrderBean.getEnginOrderId()).list();
        List<EnginOrderItem> refundItems = new ArrayList<>();
        List<EnginOrderItem> k3ChangeItems = new ArrayList<>();
        List<EnginOrderItem> updInfoItems = new ArrayList<>();
        List<EnginOrderItem> execRecords = new ArrayList<>();
        List<String> endItems = new ArrayList<>();
        for (int i = 0; i < orderItems.size(); i++) {
            EnginOrderItem item = orderItems.get(i);
            EnginOrderItemBean itemBean = itemBeanMap.get(item.getId());

            //处理订单数量和金额，但不处理台账等
            Map<String, Object> map = this.refundItem(item, itemBean.getTdQty());
            if(Objects.nonNull(map)) {
                item = (EnginOrderItem) map.get("item");
                EnginOrderItem refundItem = (EnginOrderItem) map.get("refund");
                EnginOrderItem execRecord = (EnginOrderItem) map.get("execRecord");

                if (Objects.nonNull(refundItem))
                    refundItems.add(refundItem);


                if (Objects.nonNull(execRecord))
                    execRecords.add(execRecord);

                // 业务终止
                if (item.getRefundableQty() == 0 && itemBean.getTdQty() > 0) {
                    endItems.add(item.getKingDeeEntryId());
                }else if(item.getQty() > 0 && itemBean.getTdQty() > 0){
                    k3ChangeItems.add(item);
                }

                //预留单更改，当数量变为0，修改预留单预留为0，关闭
                if (item.getRefundableQty().equals(0)) {
                    reservedOrderItemService.lambdaUpdate().eq(ReservedOrderItem::getOrderId, item.getId())
                            .set(ReservedOrderItem::getStatus, 0)
                            .set(ReservedOrderItem::getReservedNum, 0).update();
                }

                // 信息单已订数量
                EnginOrderItem updInfoItem = new EnginOrderItem();
                BeanUtils.copyProperties(item, updInfoItem);
                updInfoItem.setQty(itemBean.getTdQty());
                updInfoItems.add(updInfoItem);
            }

        }

        if (CollectionUtil.isEmpty(refundItems)) {
            throw new RemoteServiceException("退订失败，产品退订数量不能为0");
        }

        // 更新信息单已订数量
        this.updateRefInfoData(enginOrder, updInfoItems, -1, "");

        if (CollectionUtil.isNotEmpty(k3ChangeItems)) {
            Map<String, EnginOrderItem> itemMap = k3ChangeItems.stream()
                    .collect(Collectors.toMap(EnginOrderItem::getId, Function.identity()));
            List<EnginOrderItem> collect = orderItems.stream()
                    .filter(v -> v.getQty() > 0)
                    .collect(Collectors.toList());
            for (EnginOrderItem item : collect) {
                EnginOrderItem orderItem = itemMap.get(item.getId());
                if (Objects.isNull(orderItem)) {
                    k3ChangeItems.add(item);
                }
            }
        }

//        this.callbackDepositManageQty(enginOrder, refundItems, "refund");

        walletLogic.doWalletAmount(this.handleWalletMethod(enginOrder, refundItems, true, "工程订单退款-退订", "工程订单返利退款-退订"));

        // 推送金蝶销售新变更单
        if (StringUtils.isNotBlank(enginOrder.getKingDeeId())) {
            this.pushSalesChange(enginOrder, enginOrderBean, k3ChangeItems, endItems);
        } else {
            enginOrderRefundNoteService.save(new EnginOrderRefundNote()
                    .setEnginOrderNo(enginOrder.getEnginOrderNo())
                    .setRefundNote(enginOrderBean.getRefundNote()));
        }

        this.insertOrderRecord(enginOrder, execRecords, OrderOperationTypeEnum.ORDER_REFUND, "订单退订");
    }

    /**
     * 退订-订单金额数量的处理
     */
    public Map<String, Object> refundItem(EnginOrderItem item, Integer itemTdQty){
        if (Objects.isNull(item) || Objects.isNull(itemTdQty) || itemTdQty <= 0) {
            return null;
        }
        if (item.getRefundableQty() - invoiceMapper.selectInvoice(item.getId()) < itemTdQty) {
            throw new RemoteServiceException("销售类型：" + item.getSaleTypeName() + " 名称：" + item.getSpecification() + "检测到订单可退数量小于退订数量，不可退订");
        }

        if (itemTdQty.compareTo(item.getRefundableQty()) > 0) {
            throw new RemoteServiceException("销售类型：" + item.getSaleTypeName() + " 名称：" + item.getSpecification() + "退订数量不可大于可退数量");
        }

        BigDecimal tdQty = BigDecimal.valueOf(itemTdQty);
        // 需要退的钱
        BigDecimal refundPayAmount = item.getSinglePayPrice().multiply(tdQty);
        // 需要退的返利金额
        BigDecimal refundRebateAmount = item.getSingleRebateAmount().multiply(tdQty);

        // 工程扣押金额
//        BigDecimal refundDepositAmount = item.getDirectDepositAmount().compareTo(BigDecimal.ZERO) > 0 ? item.getSingleDepositAmount().multiply(tdQty) : BigDecimal.ZERO;

        //退订折扣金额
        BigDecimal refundTotalDiscAmount = item.getDiscAmount().multiply(tdQty);

        item.setQty(item.getQty() - itemTdQty);

        // 工程订单数量减退订数量等于0执行全退金额
        if (item.getQty() == 0) {
            refundPayAmount = item.getPayAmount();
            refundRebateAmount = item.getPayRebateAmount();
            refundTotalDiscAmount = item.getTotalDiscAmount();
            // 工程扣押金额大于0剩余全退
//            if (item.getDirectDepositAmount().compareTo(BigDecimal.ZERO) > 0) {
//                refundDepositAmount = item.getDirectDepositAmount();
//            }
        }

        // 退订后实际单价*数量=订单金额
        item.setTotalAmount(item.getPrice().multiply(BigDecimal.valueOf(item.getQty())));
        // 退订后折扣*数量=总折扣金额
        item.setTotalDiscAmount(item.getDiscAmount().multiply(BigDecimal.valueOf(item.getQty())));
        // 退订后支付金额
        item.setPayAmount(item.getPayAmount().subtract(refundPayAmount));
        // 退订后返利金额
        item.setPayRebateAmount(item.getPayRebateAmount().subtract(refundRebateAmount));
        // 更新已退数量
        item.setRetiredQty(item.getRetiredQty() + itemTdQty);
        // 更新可退数量
        item.setRefundableQty(item.getRefundableQty() - itemTdQty);
        // 更新应付总押金金额
        item.setTotalDepositAmount(item.getSingleDepositAmount().multiply(BigDecimal.valueOf(item.getQty())));
        // 更新工程扣押金额
//        item.setDirectDepositAmount(item.getDirectDepositAmount().subtract(refundDepositAmount));

        // 存退订明细
        EnginOrderItem refundItem = new EnginOrderItem();
        BeanUtils.copyProperties(item, refundItem);
        refundItem.setQty(itemTdQty);
        refundItem.setPayAmount(refundPayAmount);
        refundItem.setPayRebateAmount(refundRebateAmount);
//        refundItem.setDirectDepositAmount(refundDepositAmount);

        // 订单执行明细
        EnginOrderItem record = new EnginOrderItem();
        BeanUtils.copyProperties(item, record);
        record.setQty(itemTdQty)
                .setTotalAmount(item.getPrice().multiply(BigDecimal.valueOf(itemTdQty)))
                .setTotalDiscAmount(refundTotalDiscAmount)
                .setPayAmount(refundPayAmount)
                .setPayRebateAmount(refundRebateAmount);

        item.updateById();

        Map<String, Object> map = new HashMap<>();
        map.put("item", item);
        map.put("refund", refundItem);
        map.put("execRecord", record);
        return map;
    }

    private void pushSalesChange(EnginOrder enginOrder, EnginOrderBean enginOrderBean, List<EnginOrderItem> orderItems, List<String> endItems) {
        // 检查是否需要调用业务终止明细
        if (CollectionUtil.isNotEmpty(endItems) && endItems.size() > 0) {
            RequestExcuteOperationBean bean = new RequestExcuteOperationBean();
            bean.setIds(enginOrder.getKingDeeId());
            bean.setPkEntryIds(enginOrder.getKingDeeId(), String.join(",", endItems));
            salesOrderLogic.excuteOperationEnd(bean);
            // 插入终止退订说明
            enginOrderRefundNoteService.save(new EnginOrderRefundNote()
                    .setEnginOrderNo(enginOrder.getEnginOrderNo())
                    .setRefundNote(enginOrderBean.getRefundNote() + ">" + String.join(",", endItems)));
        }

//        if (CollectionUtil.isNotEmpty(endItems) && endItems.size() == orderItems.size()) {
//            return;
//        }

        if (CollectionUtil.isNotEmpty(orderItems)) {
            ResultEntity resultEntity = salesOrderLogic.pushSalesChange(enginOrder.getKingDeeId(), null);
            String refundNo = IdWorker.getIdStr();
            SalesChangeBean salesChangeBean = new SalesChangeBean();
            salesChangeBean.setId(resultEntity.getId());
            salesChangeBean.setBillNo(refundNo);
            salesChangeBean.setNote(enginOrder.getEnginOrderNo());
            salesChangeBean.setRemark(StringUtils.isNotBlank(enginOrderBean.getRefundNote()) ? enginOrderBean.getRefundNote() : "退订");

            Map<String, EnginOrderItem> itemMap = orderItems.stream()
                    .collect(Collectors.toMap(EnginOrderItem::getId, Function.identity()));

            List<SalesChangeItemBean> items = new ArrayList<>(10);
            for (BillItem billItem : resultEntity.getItems()) {
                EnginOrderItem enginOrderItem = itemMap.get(billItem.getSupplyColVal());
                if (Objects.nonNull(enginOrderItem)) {
                    SalesChangeItemBean salesChangeItemBean = new SalesChangeItemBean();
                    salesChangeItemBean.setEntryId(billItem.getEntryId());
                    salesChangeItemBean.setQty(BigDecimal.valueOf(enginOrderItem.getQty()));
                    items.add(salesChangeItemBean);
                }
            }
            salesChangeBean.setOrderItems(items);
            salesChangeOrderLogic.syncBillData(salesChangeBean);

            // 插入退订说明
            enginOrderRefundNoteService.save(new EnginOrderRefundNote()
                    .setEnginOrderNo(enginOrder.getEnginOrderNo())
                    .setRefundNote(enginOrderBean.getRefundNote())
                    .setKingDeeId(resultEntity.getId())
                    .setRefundNo(refundNo));
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void endDirectTransfer(String id, String refEnginRecordNo) throws Exception {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        // 查询原单直调状态
        EnginOrder enginOrder = enginOrderService.lambdaQuery()
                .eq(EnginOrder::getEnginOrderId, id)
                .eq(EnginOrder::getRefEnginRecordNo, refEnginRecordNo)
                .eq(adminUser.getIsCustomer(), EnginOrder::getCustomerId, adminUser.getCustomerId())
                .eq(EnginOrder::getExamineStatus, ExamineStatusEnum.OK.toString())
                .eq(EnginOrder::getDirectTransferStatus, false)
                .eq(EnginOrder::getAdminCompanyId, adminUser.getAdminCompanyId())
                .one();
        if (adminUser.getIsCustomer()) {
            throw new RemoteServiceException("经销商没有权限");
        }

        if (Objects.isNull(enginOrder)) {
            throw new RemoteServiceException("非审核通过或直调未完结单据状态");
        }

        if (enginOrder.getEnginOrderType().equals(OrderTypeEnum.TRADE.getKey())
                && !enginOrder.getIsPlanOrder()) {
            throw new RemoteServiceException("非计划单不允许直调完结");
        }

        List<EnginOrderItem> orderItems = enginOrderItemService.lambdaQuery()
                .eq(EnginOrderItem::getParentId, enginOrder.getEnginOrderId())
                .list();

        enginOrder.setDirectTransferStatus(true)
                .setEndDirectBy(CommonUtils.getUsername())
                .setEndDirectName(CommonUtils.getNickName())
                .setEndDirectTime(DateUtil.date())
                .updateById();

        // 如果非一期旧单 并且是否不扣押金=false，退回剩余工程扣的押金
        if (!enginOrder.getIsFirstOldOrder() && !enginOrder.getTakeDeposit()) {
            List<CustomerWalletAmountBean> beans = this.handleDirectDeposit(enginOrder, orderItems, "工程订单押金退款-直调完结",
                    WalletDirectionEnum.ADD.getKey(), enginOrder.getCreateTime());
            if (CollectionUtil.isNotEmpty(beans))
                walletLogic.doWalletAmount(beans);
        }

        enginOrderItemService.lambdaUpdate()
                .set(EnginOrderItem::getDirectDepositAmount, BigDecimal.ZERO)
                .set(EnginOrderItem::getDirectTransferStatus, true)
                .eq(EnginOrderItem::getParentId, enginOrder.getEnginOrderId())
//                .eq(EnginOrderItem::getIsDirectTransfer, true)
                .update();
    }

    /**
     * 插入押金管理
     * @param enginOrder
     * @param orderItems
     */
    private void insertDepositManage(EnginOrder enginOrder, List<EnginOrderItem> orderItems) {
        String depositManageId = "";

        DepositManage manage = depositManageService.lambdaQuery()
                .eq(DepositManage::getRefEnginRecordNo, enginOrder.getRefEnginRecordNo())
                .one();

        if (Objects.isNull(manage)) {
            depositManageId = "DM" + IdWorker.getIdStr();
        } else {
//            if (manage.getExamineStatus().equals(ExamineStatusEnum.OK.toString())) {
//                throw new RemoteServiceException(enginOrder.getRefEnginRecordNo() + "：已退押的工程订单，不能审核");
//            }
            if (!enginOrder.getCustomerId().equals(manage.getCustomerId())) {
                throw new RemoteServiceException(enginOrder.getRefEnginRecordNo() + "：关联的押金管理已给" + manage.getCustomerName() + "使用");
            }
            depositManageId = manage.getDepositManageId();
        }

        List<DepositManageItem> manageItems = depositManageItemService.lambdaQuery()
                .eq(DepositManageItem::getParentId, depositManageId)
                .list();

        List<DepositManageItemCollect> manageItemCollects = depositManageItemCollectService.lambdaQuery()
                .eq(DepositManageItemCollect::getParentId, depositManageId)
                .list();

        Map<String, DepositManageItem> manageItemMap = manageItems.stream()
                .collect(Collectors.toMap(v -> v.getMaterialId() + "|" + v.getRealMaterialId() + "|" + v.getPrice().setScale(6), Function.identity()));

        Map<String, DepositManageItemCollect> manageItemCollectMap = manageItemCollects.stream()
                .collect(Collectors.toMap(v -> v.getMaterialId() + "|" + v.getCustomerWalletId() + "|" + v.getPrice().setScale(6), Function.identity()));

        Integer totalQty = 0;
        // 以物料id+实装id+单价方式汇总
        List<DepositManageItem> depositManageItems = new ArrayList<>();
        // 以物料id+钱包id+单价方式汇总
        List<DepositManageItemCollect> depositManageItemCollects = new ArrayList<>();

        for (EnginOrderItem orderItem : orderItems) {
            DepositManageItem depositManageItem = manageItemMap.get(orderItem.getMaterialId() + "|" + orderItem.getRealMaterialId() + "|" + orderItem.getPrice().setScale(6));
            if (Objects.isNull(depositManageItem)) {
                depositManageItem = new DepositManageItem();
                depositManageItem.setParentId(depositManageId)
                        .setRefEnginRecordNo(enginOrder.getRefEnginRecordNo())
                        .setMaterialId(orderItem.getMaterialId())
                        .setMaterialName(orderItem.getMaterialName())
                        .setMaterialNumber(orderItem.getMaterialNumber())
                        .setMaterialOldNumber(orderItem.getMaterialOldNumber())
                        .setSpecification(orderItem.getSpecification())
                        .setK3CategoryId(orderItem.getK3CategoryId())
                        .setK3CategoryName(orderItem.getK3CategoryName())
                        .setK3CategoryNumber(orderItem.getK3CategoryNumber())
                        .setUnit(orderItem.getUnit())
                        .setEnginPrice(orderItem.getEnginPrice())
                        .setEnginTotality(orderItem.getEnginTotality())
                        .setEnginNum(orderItem.getEnginNum())
                        .setPrice(orderItem.getPrice())
                        .setQty(orderItem.getQty())
                        .setTotalAmount(orderItem.getTotalAmount())
                        .setCustomerWalletId(orderItem.getCustomerWalletId())
                        .setCustomerWalletNumber(orderItem.getCustomerWalletNumber())
                        .setCustomerWalletName(orderItem.getCustomerWalletName())
                        .setTax(orderItem.getTax())
                        .setDataQty(orderItem.getQty())
                        .setCreateBy(enginOrder.getConfirmBy())
                        .setRealMaterialId(orderItem.getRealMaterialId())
                        .setRealMaterialName(orderItem.getRealMaterialName())
                        .setRealMaterialNumber(orderItem.getRealMaterialNumber())
                        .setRealMaterialOldNumber(orderItem.getRealMaterialOldNumber())
                        .setRealSpecification(orderItem.getRealSpecification())
                        .setSalesQty(orderItem.getQty())
                        .setSalesAmount(orderItem.getPayAmount())
                        .setDepositMaterialId(orderItem.getRealMaterialId())
                        .setDepositMaterialName(orderItem.getRealMaterialName())
                        .setDepositMaterialNumber(orderItem.getRealMaterialNumber())
                        .setDepositMaterialOldNumber(orderItem.getRealMaterialOldNumber())
                        .setDepositSpecification(orderItem.getRealSpecification());
            }else {
                depositManageItem.setQty(depositManageItem.getQty() + orderItem.getQty())
                        .setTotalAmount(orderItem.getPrice().multiply(BigDecimal.valueOf(depositManageItem.getQty())))
//                        .setPrice(orderItem.getPrice())
//                        .setCustomerWalletId(orderItem.getCustomerWalletId())
//                        .setCustomerWalletNumber(orderItem.getCustomerWalletNumber())
//                        .setCustomerWalletName(orderItem.getCustomerWalletName())
//                        .setTax(orderItem.getTax())
                        .setDataQty(depositManageItem.getDataQty() + orderItem.getQty())
                        .setSalesQty(depositManageItem.getSalesQty() + orderItem.getQty())
                        .setSalesAmount(depositManageItem.getSalesAmount().add(orderItem.getPayAmount()));
            }

            depositManageItems.add(depositManageItem);
            totalQty = totalQty + orderItem.getQty();
        }

        for (EnginOrderItem orderItem : orderItems) {
            DepositManageItemCollect collect = manageItemCollectMap.get(orderItem.getMaterialId() + "|" + orderItem.getCustomerWalletId() + "|" + orderItem.getPrice().setScale(6));
            if (Objects.isNull(collect)) {
                collect = new DepositManageItemCollect();
                collect.setParentId(depositManageId)
                        .setRefEnginRecordNo(enginOrder.getRefEnginRecordNo())
                        .setMaterialId(orderItem.getMaterialId())
                        .setMaterialName(orderItem.getMaterialName())
                        .setMaterialNumber(orderItem.getMaterialNumber())
                        .setMaterialOldNumber(orderItem.getMaterialOldNumber())
                        .setSpecification(orderItem.getSpecification())
                        .setK3CategoryId(orderItem.getK3CategoryId())
                        .setK3CategoryName(orderItem.getK3CategoryName())
                        .setK3CategoryNumber(orderItem.getK3CategoryNumber())
                        .setUnit(orderItem.getUnit())
                        .setPrice(orderItem.getPrice())
                        .setCustomerWalletId(orderItem.getCustomerWalletId())
                        .setCustomerWalletNumber(orderItem.getCustomerWalletNumber())
                        .setCustomerWalletName(orderItem.getCustomerWalletName())
                        .setCreateBy(enginOrder.getConfirmBy());
                depositManageItemCollects.add(collect);
            }
        }

        if (Objects.isNull(manage)) {
            DepositManage depositManage = new DepositManage();
            depositManage.setDepositManageId(depositManageId)
                    .setTakeDeposit(enginOrder.getTakeDeposit())
                    .setAdminCompanyId(enginOrder.getAdminCompanyId())
                    .setCustomerId(enginOrder.getCustomerId())
                    .setCustomerNumber(enginOrder.getCustomerNumber())
                    .setCustomerName(enginOrder.getCustomerName())
                    .setPrimaryOrderDate(enginOrder.getOrderDate())
                    .setEnginOrderType(enginOrder.getEnginOrderType())
                    .setRefEnginRecordNo(enginOrder.getRefEnginRecordNo())
                    .setRefProjectCategory(enginOrder.getRefProjectCategory())
                    .setRefProjectName(enginOrder.getRefProjectName())
                    .setRefProjectType(enginOrder.getRefProjectType())
                    .setRefProjectNote(enginOrder.getRefProjectNote())
                    .setRefUseUnit(enginOrder.getRefUseUnit())
                    .setRefInstallAddress(enginOrder.getRefInstallAddress())
                    .setRefProjectNo(enginOrder.getRefProjectNo())
                    .setRefFactoryNo(enginOrder.getRefFactoryNo())
                    .setRefPromiseStatus(enginOrder.getRefPromiseStatus())
                    .setRefTradeCategory(enginOrder.getRefTradeCategory())
                    .setRefLinkman(enginOrder.getRefLinkman())
                    .setRefPhone(enginOrder.getRefPhone())
                    .setRefTel(enginOrder.getRefTel())
                    .setRefDeclareNo(enginOrder.getRefDeclareNo())
                    .setRefPowerCategory(enginOrder.getRefPowerCategory())
                    .setRefMachineType(enginOrder.getRefMachineType())
                    .setRefRegionWork(enginOrder.getRefRegionWork())
                    .setRefBuyUnitName(enginOrder.getRefBuyUnitName())
                    .setRefBuyUnitCallMen(enginOrder.getRefBuyUnitCallMen())
                    .setRefBuyUnitPhone(enginOrder.getRefBuyUnitPhone())
                    .setRefBuyUnitTel(enginOrder.getRefBuyUnitTel())
                    .setRefPromiseProvide(enginOrder.getRefPromiseProvide())
                    .setRefContractIdea(enginOrder.getRefContractIdea())
                    .setRefContractResult(enginOrder.getRefContractResult())
                    .setRefToRetailIdea(enginOrder.getRefToRetailIdea())
                    .setRefToRetailResult(enginOrder.getRefToRetailResult())
                    .setRefDataDelayIdea(enginOrder.getRefDataDelayIdea())
                    .setRefDataDelayResult(enginOrder.getRefDataDelayResult())
                    .setRefOtherAnnexIdea(enginOrder.getRefOtherAnnexIdea())
                    .setRefOtherAnnexResult(enginOrder.getRefOtherAnnexResult())
                    .setRefBillsExpireDate(enginOrder.getRefBillsExpireDate())
                    .setSaleTypeId(enginOrder.getSaleTypeId())
                    .setSaleTypeName(enginOrder.getSaleTypeName())
                    .setServiceId(enginOrder.getServiceId())
                    .setServiceName(enginOrder.getServiceName())
                    .setOrderGeLiInnerNote(enginOrder.getGeLiInerNote())
                    .setGeLiNote(enginOrder.getGeLiNote())
                    .setRealUseUnit(enginOrder.getRefUseUnit())
                    .setRealInstallAddress(enginOrder.getRefInstallAddress())
                    .setExamineStatus(ExamineStatusEnum.SAVE.toString())
                    .setQty(totalQty)
                    .setCreateBy(enginOrder.getConfirmBy())
                    .setCreateName(enginOrder.getConfirmName())
                    .setUpdateBy(enginOrder.getConfirmBy())
                    .setUpdateName(enginOrder.getConfirmName());

            depositManage.insert();
        } else {
//            String geLiInerNote = Optional.ofNullable(manage.getRefGeLiInerNote()).orElse("");
//            String geLiNote = Optional.ofNullable(manage.getRefGeLiNote()).orElse("");
//            if (StringUtils.isNotBlank(enginOrder.getGeLiInerNote()) && !enginOrder.getGeLiInerNote().equals(geLiInerNote)) {
//                if (StringUtils.isBlank(geLiInerNote)) {
//                    manage.setRefGeLiInerNote(enginOrder.getGeLiInerNote());
//                } else {
//                    manage.setRefGeLiInerNote(geLiInerNote + "；" + enginOrder.getGeLiInerNote());
//                }
//            }
//            if (StringUtils.isNotBlank(enginOrder.getGeLiNote()) && !enginOrder.getGeLiNote().equals(geLiNote)) {
//                if (StringUtils.isBlank(geLiNote)) {
//                    manage.setRefGeLiNote(enginOrder.getGeLiNote());
//                } else {
//                    manage.setRefGeLiNote(geLiNote + "；" + enginOrder.getGeLiNote());
//                }
//            }

//            if (StringUtils.isBlank(manage.getOrderGeLiInnerNote())) {
//                manage.setOrderGeLiInnerNote(enginOrder.getGeLiInerNote());
//            }

            if (StringUtils.isNotBlank(enginOrder.getGeLiInerNote())) {
                Integer count = enginOrderService.lambdaQuery()
                        .eq(EnginOrder::getRefEnginRecordNo, enginOrder.getRefEnginRecordNo())
                        .eq(EnginOrder::getExamineStatus, ExamineStatusEnum.OK.getKey())
                        .lt(EnginOrder::getCreateTime, enginOrder.getCreateTime())
                        .count();
                if (count == 0) {
                    manage.setOrderGeLiInnerNote(enginOrder.getGeLiInerNote());
                }
            }

            manage.setQty(manage.getQty() + totalQty)
                    .setUpdateBy(enginOrder.getConfirmBy())
                    .setUpdateName(enginOrder.getConfirmName())
                    .updateById();
        }

        depositManageItemService.saveOrUpdateBatch(depositManageItems);

        if (CollectionUtil.isNotEmpty(depositManageItemCollects))
            depositManageItemCollectService.saveBatch(depositManageItemCollects);

    }

    @Transactional(rollbackFor = Exception.class)
    public void updExamineAfterOrder(EnginOrderBean enginOrderBean) {
        AdminUserCom adminUser = commonLogic.getAdminUser();

        if (Objects.nonNull(enginOrderBean.getOrderDate()) || StringUtils.isNotBlank(enginOrderBean.getGeLiInerNote())) {
            boolean upd = enginOrderService.lambdaUpdate()
                    .set(StringUtils.isNotBlank(enginOrderBean.getGeLiInerNote()), EnginOrder::getGeLiInerNote, enginOrderBean.getGeLiInerNote())
                    .set(Objects.nonNull(enginOrderBean.getOrderDate()), EnginOrder::getOrderDate, enginOrderBean.getOrderDate())
                    .set(EnginOrder::getUpdateBy, CommonUtils.getUsername())
                    .set(EnginOrder::getUpdateName, CommonUtils.getNickName())
                    .set(EnginOrder::getUpdateTime, DateUtil.date())
                    .eq(EnginOrder::getEnginOrderId, enginOrderBean.getEnginOrderId())
                    .eq(EnginOrder::getAdminCompanyId, adminUser.getAdminCompanyId())
                    .eq(adminUser.getIsCustomer(), EnginOrder::getCustomerId, adminUser.getCustomerId())
                    .eq(EnginOrder::getEnginOrderType, enginOrderBean.getEnginOrderType())
                    .update();
            if (!upd) {
                throw new RemoteServiceException("修改失败");
            }

            if (StringUtils.isNotBlank(enginOrderBean.getGeLiInerNote())) {
                EnginOrder order = enginOrderService.getById(enginOrderBean.getEnginOrderId());
                List<EnginOrder> orderList = enginOrderService.lambdaQuery()
                        .eq(EnginOrder::getRefEnginRecordNo, order.getRefEnginRecordNo())
                        .eq(EnginOrder::getExamineStatus, ExamineStatusEnum.OK.getKey())
                        .orderByAsc(EnginOrder::getCreateTime)
                        .list();
                if (CollectionUtil.isNotEmpty(orderList)
                        && orderList.get(0).getEnginOrderId().equals(order.getEnginOrderId())) {
                    depositManageService.lambdaUpdate()
                            .set(DepositManage::getOrderGeLiInnerNote, enginOrderBean.getGeLiInerNote())
                            .set(DepositManage::getUpdateBy, CommonUtils.getUsername())
                            .set(DepositManage::getUpdateName, CommonUtils.getNickName())
                            .eq(DepositManage::getRefEnginRecordNo, order.getRefEnginRecordNo())
                            .update();
                }
            }

        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void abandonHome(String id, String refEnginRecordNo, String orderType) throws Exception {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        EnginOrder order = enginOrderService.lambdaQuery()
                .eq(EnginOrder::getEnginOrderId, id)
                .eq(EnginOrder::getRefEnginRecordNo, refEnginRecordNo)
                .eq(EnginOrder::getEnginOrderType, orderType)
                .eq(EnginOrder::getExamineStatus, ExamineStatusEnum.OK.toString())
                .one();
        if (adminUser.getIsCustomer()) {
            throw new RemoteServiceException("经销商没有权限");
        }

        if (Objects.isNull(order)) {
            throw new RemoteServiceException("非审核通过单据状态，不可弃审，请重新加载");
        }

        DepositManage depositManage = depositManageService.lambdaQuery()
                .eq(DepositManage::getRefEnginRecordNo, order.getRefEnginRecordNo())
                .eq(DepositManage::getCustomerId, order.getCustomerId())
                .one();

        if (Objects.nonNull(depositManage) && depositManage.getExamineStatus().equals(ExamineStatusEnum.OK.toString())) {
            throw new RemoteServiceException("工程登录单号所关联的押金管理已审核通过，不可弃审");
        }

        Integer count = enginOrderService.lambdaQuery()
                .eq(EnginOrder::getAdminCompanyId, order.getAdminCompanyId())
                .eq(EnginOrder::getRefEnginRecordNo, order.getRefEnginRecordNo())
                .in(EnginOrder::getExamineStatus, ExamineStatusEnum.SAVE.toString(), ExamineStatusEnum.WAIT.toString())
                .count();
        if (count > 0) {
            throw new RemoteServiceException(order.getRefEnginRecordNo() + " 的引用单已存在一张未审批通过的订单！弃审失败");
        }

        List<EnginOrderItem> orderItems = enginOrderItemService.lambdaQuery().eq(EnginOrderItem::getParentId, id).list();
        for(EnginOrderItem item : orderItems){
            if (order.getIsPlanOrder() && invoiceMapper.selectInvoice(item.getId()) != 0){
                throw new RemoteServiceException("检测到订单有申请发货，不可弃审");
            }
            if (order.getIsPlanOrder() && item.getOldQty() > item.getRefundableQty()) {
                throw new RemoteServiceException("销售类型：" + item.getSaleTypeName()  + " 名称：" + item.getMaterialName() + "数量发生变更，不可弃审");
            }
            item.setKingDeeSeq("");
            item.setKingDeeEntryId("");
        }
        // 弃单退钱
        List<CustomerWalletAmountBean> walletAmountBeans = this.handleWalletMethod(order, orderItems, true, "工程订单退款-弃审", "工程订单返利退款-弃审");

        // 弃单退押金 旧单不用退
        if (!order.getIsFirstOldOrder()) {
            List<CustomerWalletAmountBean> beans = this.handleDirectDeposit(order, orderItems, "家用工程订单押金退款-弃审",
                    WalletDirectionEnum.ADD.getKey(), order.getCreateTime());
            if (CollectionUtil.isNotEmpty(beans))
                walletAmountBeans.addAll(beans);
        }

        walletLogic.doWalletAmount(walletAmountBeans);

        // 押金管理
        callbackDepositManageQty(order, orderItems, "abandon");

        // 反审核并删除
        if (StringUtils.isNotBlank(order.getKingDeeId())) {
            salesOrderLogic.unAuditByBillNo(id);
        }

        order.setAdvanceStatus(false);
        order.setDirectTransferStatus(false);
        order.setExamineStatus(ExamineStatusEnum.WAIT.toString());
        order.setAbandonBy(CommonUtils.getUsername());
        order.setAbandonName(CommonUtils.getNickName());
        order.setAbandonTime(DateUtil.date());
        order.setKingDeeSync(K3SyncStatusEnum.NOT.toString());
        order.setKingDeeId("");
        order.updateById();
        enginOrderItemService.saveOrUpdateBatch(orderItems);


        //弃审订单，同时弃审申请发货单
        if (!order.getIsPlanOrder() ) {
            InvoiceApplication one = invoiceApplicationService.lambdaQuery().eq(InvoiceApplication::getEnginOrderNo, order.getEnginOrderNo()).last("limit 1").one();
            invoiceLogic.projectGiveUp(one.getId());
            invoiceLogic.submitProject(one.getId(), "SAVE");
            invoiceLogic.deleteProject(one.getId());
        }

        // 删除订单执行明细
        orderExecRecordService.lambdaUpdate()
                .eq(OrderExecRecord::getRefOrderId, order.getEnginOrderNo())
                .remove();

    }

    @Transactional(rollbackFor = Exception.class)
    public void abandonTrade(String id, String refEnginRecordNo, String orderType) throws Exception {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        EnginOrder order = enginOrderService.lambdaQuery()
                .eq(EnginOrder::getEnginOrderId, id)
                .eq(EnginOrder::getRefEnginRecordNo, refEnginRecordNo)
                .eq(EnginOrder::getEnginOrderType, orderType)
                .eq(EnginOrder::getExamineStatus, ExamineStatusEnum.OK.toString())
                .one();

        if (adminUser.getIsCustomer()) {
            throw new RemoteServiceException("经销商没有权限");
        }
        if (Objects.isNull(order)) {
            throw new RemoteServiceException("非审核通过单据状态，不可弃审，请重新加载");
        }

        if (invoiceApplicationService.lambdaQuery().eq(InvoiceApplication::getEnginOrderNo, order.getEnginOrderNo()).eq(InvoiceApplication::getType,2).count() > 0)
            throw new RemoteServiceException("该申请发货单有退货操作不可弃审");

        Integer count = enginOrderService.lambdaQuery()
                .eq(EnginOrder::getAdminCompanyId, order.getAdminCompanyId())
                .eq(EnginOrder::getRefEnginRecordNo, order.getRefEnginRecordNo())
                .in(EnginOrder::getExamineStatus, ExamineStatusEnum.SAVE.toString(), ExamineStatusEnum.WAIT.toString())
                .count();
        if (count > 0) {
            throw new RemoteServiceException(order.getRefEnginRecordNo() + " 的引用单已存在一张未审批通过的订单！弃审失败");
        }

        List<EnginOrderItem> orderItems = enginOrderItemService.lambdaQuery().eq(EnginOrderItem::getParentId, id).list();
        for(EnginOrderItem item : orderItems){
            if (invoiceMapper.selectInvoice(item.getId()) != 0 && order.getIsPlanOrder()){
                throw new RemoteServiceException("检测到订单有申请发货，不可弃审");
            }
            if (item.getOldQty() > item.getRefundableQty() && order.getIsPlanOrder()) {
                throw new RemoteServiceException("销售类型：" + item.getSaleTypeName()  + " 名称：" + item.getMaterialName() + "数量发生变更，不可弃审");
            }
            item.setKingDeeSeq("");
            item.setKingDeeEntryId("");
        }

        // 减引用单已订数量
//        this.updateRefInfoData(order, orderItems, -1, "");

        if (order.getIsPlanOrder()) {
            // 计划单弃单退钱
            walletLogic.doWalletAmount(this.handleWalletMethod(order, orderItems, true, "工程订单退款-弃审", "工程订单返利退款-弃审"));
            order.setAdvanceStatus(false);
        }
        // 押金管理
//        callbackDepositManageQty(order, orderItems, "abandon");

        // 反审核并删除
        if (StringUtils.isNotBlank(order.getKingDeeId())) {
            salesOrderLogic.unAuditByBillNo(id);
        }

        order.setExamineStatus(ExamineStatusEnum.WAIT.toString());
        order.setAbandonBy(CommonUtils.getUsername());
        order.setAbandonName(CommonUtils.getNickName());
        order.setAbandonTime(DateUtil.date());
        order.setKingDeeSync(K3SyncStatusEnum.NOT.toString());
        order.setKingDeeId("");
        order.updateById();
        enginOrderItemService.saveOrUpdateBatch(orderItems);

        //弃审订单，同时弃审申请发货单
        if (!order.getIsPlanOrder() ) {
            InvoiceApplication one = invoiceApplicationService.lambdaQuery()
                    .eq(InvoiceApplication::getEnginOrderNo, order.getEnginOrderNo()).last("limit 1")
                    .one();
            invoiceLogic.projectGiveUp(one.getId());
        }

        // 删除订单执行明细
        orderExecRecordService.lambdaUpdate()
                .eq(OrderExecRecord::getRefOrderId, order.getEnginOrderNo())
                .remove();
    }

    private void callbackDepositManageQty(EnginOrder order, List<EnginOrderItem> orderItems, String type) {
        DepositManage manage = depositManageService.lambdaQuery()
                .eq(DepositManage::getRefEnginRecordNo, order.getRefEnginRecordNo())
                .one();

        if (manage.getExamineStatus().equals(ExamineStatusEnum.OK.toString())) {
            return;
        }

        List<DepositManageItem> manageItems = depositManageItemService.lambdaQuery()
                .eq(DepositManageItem::getParentId, manage.getDepositManageId())
                .list();

        // 重新计算销售数量和销售金额
        depositManageLogic.computeOrderSalesQtyData(manageItems);

        Map<String, DepositManageItem> manageItemMap = manageItems.stream()
                .collect(Collectors.toMap(v -> v.getMaterialId() + "|" + v.getRealMaterialId() + "|" + v.getPrice().setScale(6), Function.identity()));

        Integer totalQty = 0;
        List<DepositManageItem> depositManageItems = new ArrayList<>();
        for (EnginOrderItem orderItem : orderItems) {
            DepositManageItem depositManageItem = manageItemMap.get(orderItem.getMaterialId() + "|" + orderItem.getRealMaterialId() + "|" + orderItem.getPrice().setScale(6));

            depositManageItem.setQty(depositManageItem.getQty() - orderItem.getQty())
                    .setTotalAmount(orderItem.getPrice().multiply(BigDecimal.valueOf(depositManageItem.getQty())))
                    .setDataQty(depositManageItem.getDataQty() - orderItem.getQty())
                    .setSalesQty(depositManageItem.getSalesQty() - orderItem.getQty())
                    .setSalesAmount(depositManageItem.getPrice().multiply(BigDecimal.valueOf(depositManageItem.getSalesQty())));;

            depositManageItems.add(depositManageItem);
            totalQty = totalQty + orderItem.getQty();
        }
        manage.setQty(manage.getQty() - totalQty);

        if (type.equals("refund")) {
            // 退订时处理
            manage.updateById();
            depositManageItemService.saveOrUpdateBatch(depositManageItems);
        } else {
            // 弃审时处理
            if (manage.getQty() > 0) {
                manage.updateById();
                depositManageItemService.saveOrUpdateBatch(depositManageItems);
            } else {
                // 删除原表押金单，复制到押金单
                copyDepositInfo(manage);
                manage.deleteById();
                depositManageItemService.lambdaUpdate().eq(DepositManageItem::getParentId, manage.getDepositManageId()).remove();
                depositManageDataService.lambdaUpdate().eq(DepositManageData::getParentId, manage.getDepositManageId()).remove();
                depositManageCheckRecordService.lambdaUpdate().eq(DepositManageCheckRecord::getDepositManageId, manage.getDepositManageId()).remove();
                depositManageItemCollectService.lambdaUpdate().eq(DepositManageItemCollect::getParentId, manage.getDepositManageId()).remove();
            }
        }
    }

    private void copyDepositInfo(DepositManage manage) {
        DepositManageBak depositManageBak = new DepositManageBak();
        BeanUtils.copyProperties(manage, depositManageBak);
        depositManageBak.insert();
        List<DepositManageItem> depositManageItems = depositManageItemService.lambdaQuery()
                .eq(DepositManageItem::getParentId, manage.getDepositManageId()).list();
        // 复制产品明细
        if (CollectionUtil.isNotEmpty(depositManageItems)) {
            List<DepositManageItemBak> depositManageItemBakList = new ArrayList<>();
            for (DepositManageItem depositManageItem : depositManageItems) {
                DepositManageItemBak depositManageItemBak = new DepositManageItemBak();
                BeanUtils.copyProperties(depositManageItem, depositManageItemBak);
                depositManageItemBakList.add(depositManageItemBak);
            }
            depositManageItemBakService.saveBatch(depositManageItemBakList);
        }

        List<DepositManageData> depositManageDataList = depositManageDataService.lambdaQuery()
                .eq(DepositManageData::getParentId, manage.getDepositManageId()).list();
        // 复制资料
        if (CollectionUtil.isNotEmpty(depositManageDataList)) {
            List<DepositManageDataBak> depositManageDataBakList = new ArrayList<>();
            for (DepositManageData depositManageData : depositManageDataList) {
                DepositManageDataBak depositManageDataBak = new DepositManageDataBak();
                BeanUtils.copyProperties(depositManageData, depositManageDataBak);
                depositManageDataBakList.add(depositManageDataBak);
            }
            depositManageDataBakService.saveBatch(depositManageDataBakList);
        }

        List<DepositManageCheckRecord> depositManageCheckRecords = depositManageCheckRecordService.lambdaQuery()
                .eq(DepositManageCheckRecord::getDepositManageId, manage.getDepositManageId()).list();
        // 复制审核记录
        if (CollectionUtil.isNotEmpty(depositManageCheckRecords)) {
            List<DepositManageCheckRecordBak> depositManageCheckRecordBakList = new ArrayList<>();
            for (DepositManageCheckRecord depositManageCheckRecord : depositManageCheckRecords) {
                DepositManageCheckRecordBak depositManageCheckRecordBak = new DepositManageCheckRecordBak();
                BeanUtils.copyProperties(depositManageCheckRecord, depositManageCheckRecordBak);
                depositManageCheckRecordBakList.add(depositManageCheckRecordBak);
            }
            depositManageCheckRecordBakService.saveBatch(depositManageCheckRecordBakList);
        }
    }

    private List<CustomerWalletAmountBean> handleWalletMethod(EnginOrder order,
                                                              List<EnginOrderItem> items, boolean direction, String afterCashMsg,
                                                              String afterRebateMsg) {
        List<CustomerWalletAmountBean> walletAmountBeans = new ArrayList<>();
        Map<String, Object> enumMap = EnumUtil.getNameFieldMap(OrderTypeEnum.class, "value");

        String orderNo = order.getEnginOrderNo() + "|" + order.getRefEnginRecordNo();

//        if (order.getEnginOrderType().equals(OrderTypeEnum.HOME.getKey())) {
//            orderNo = order.getEnginOrderNo() + "|" + order.getRefEnginRecordNo();
//        }

        for (EnginOrderItem item : items) {
            if (!direction && item.getPayRebateAmount().doubleValue() > 0) {
                // 检查是否存在未确认的返利单
                rebateOrderLogic.checkNeedAck(item.getCustomerWalletId2());
            }

            if (item.getPayAmount().doubleValue() > 0) {
                walletAmountBeans.add(new CustomerWalletAmountBean(item.getCustomerWalletId(), item.getPayAmount(), item.getRemark(),
                        enumMap.get(order.getEnginOrderType()) + afterCashMsg
                        , order.getCreateTime(), orderNo, 2, direction ? WalletDirectionEnum.ADD.getKey() : WalletDirectionEnum.SUB.getKey()));
            }
            if (item.getPayRebateAmount().doubleValue() > 0) {
                walletAmountBeans.add(new CustomerWalletAmountBean(item.getCustomerWalletId2(), item.getPayRebateAmount(), item.getRemark(),
                        enumMap.get(order.getEnginOrderType()) + afterRebateMsg
                        , order.getCreateTime(), orderNo, 0, direction ? WalletDirectionEnum.ADD.getKey() : WalletDirectionEnum.SUB.getKey()));
            }

        }
        return walletAmountBeans;
    }

    public List<EnginOrderListBean> queryPreOrder(String recordNo) {
        return enginOrderReserveMapper.queryPreOrder(recordNo);
    }

    public EnginOrderBean nextWaitOrder(EnginOrderBean enginOrderBean, String operType) {
        if (!operType.equals(SysDictConstant.EXAMINE)) {
            return null;
        }

        AdminUserCom adminUser = commonLogic.getAdminUser();

        List<EnginOrder> enginOrders = enginOrderService.lambdaQuery()
                .eq(!adminUser.getIsCw(), EnginOrder::getServiceId, enginOrderBean.getServiceId())
                .eq(EnginOrder::getExamineStatus, ExamineStatusEnum.WAIT.toString())
//                .le(EnginOrder::getCreateTime, enginOrderBean.getCreateTime())
                .orderByDesc(EnginOrder::getEnginOrderId)
                .list();
        if (CollectionUtil.isEmpty(enginOrders)) {
            return null;
        }

        for (EnginOrder enginOrder : enginOrders) {
            EnginOrderBean detail = this.detail(enginOrder.getEnginOrderId());
            if (detail != null){
                return detail;
            }
        }

        return null;
    }

    public ExcelData exportHome(List<EnginOrderListBean> enginOrderListBeans) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        String[] titles = new String[]{
                "工程订单号","订单日期","单据状态","经销商编码","经销商名称","工程登录编号","项目类别","行业类别",
                "跨区厂编号","使用单位", "安装地址", "销售类型", "联系人","固定电话","移动电话","不扣押金","文件编号", "区域", "业务员",
                "项目说明","项目类型", "购买单位", "保证函",
                "表头备注", "第几次申报", "制单人", "制单日期", "审核人", "审核日期", "最后更新人", "最后更新日期", "关闭日期",
                "审批说明", "序号", "厂产品代码", "物料编码", "产品名称", "规格型号", "单位", "单价", "工程登录数量", "数量",
                "订单金额", "返利类型", "实付返利金额", "格力折扣", "现金钱包", "实付金额", "是否直调", "直调数量", "原订单数量",
                "发货数量", "退货数量", "出库数量", "表体备注", "税率","实装机型名称","实装机型编码","实装机型旧编码","实装机型规格","物料分组","存货类别"
        };
        if (!adminUser.getIsCustomer()) {
            titles = new String[] {
                    "工程订单号", "订单日期", "单据状态", "经销商编码", "经销商名称", "工程登录编号", "项目类别", "行业类别",
                    "跨区厂编号", "使用单位", "安装地址", "销售类型", "联系人", "固定电话", "移动电话", "不扣押金", "文件编号", "区域", "业务员",
                    "项目说明","项目类型", "购买单位", "保证函",
                    "格力内部备注", "表头备注", "第几次申报", "制单人", "制单日期", "审核人", "审核日期", "最后更新人", "最后更新日期", "关闭日期",
                    "审批说明", "序号", "厂产品代码", "物料编码", "产品名称", "规格型号", "单位", "单价", "工程登录数量", "数量",
                    "订单金额", "返利类型", "实付返利金额", "格力折扣", "现金钱包", "实付金额", "是否直调", "直调数量", "原订单数量",
                    "发货数量", "退货数量", "出库数量", "表体备注", "税率","实装机型名称","实装机型编码","实装机型旧编码","实装机型规格","物料分组","存货类别"
            };
        }
        List<List<Object>> rows = new ArrayList<>();

        long index = 1;
        String orderNo = "";
        int sumQty = 0;
        int sumDirectQty = 0;
        int sumOldQty = 0;
        BigDecimal sumTotalAmount = new BigDecimal("0");
        BigDecimal sumRebateAmount = new BigDecimal("0");
        BigDecimal sumDiscAmount = new BigDecimal("0");
        BigDecimal sumPayAmount = new BigDecimal("0");
        for (EnginOrderListBean enginOrderListBean : enginOrderListBeans) {
            sumQty = sumQty + enginOrderListBean.getQty();
            sumDirectQty = sumDirectQty + enginOrderListBean.getDirectTransferQty();
            sumOldQty = sumOldQty + enginOrderListBean.getOldQty();
            sumTotalAmount = sumTotalAmount.add(enginOrderListBean.getTotalAmount());
            sumRebateAmount = sumRebateAmount.add(enginOrderListBean.getPayRebateAmount());
            sumDiscAmount = sumDiscAmount.add(enginOrderListBean.getDiscAmount());
            sumPayAmount = sumPayAmount.add(enginOrderListBean.getPayAmount());
            List<Object> row = new ArrayList<>();
//            boolean isFill = true;
            if (!orderNo.equals(enginOrderListBean.getEnginOrderNo())) {
                orderNo = enginOrderListBean.getEnginOrderNo();
//                isFill = false;
                index = 1;
            }
            row.add(enginOrderListBean.getEnginOrderNo());
            row.add(DateUtil.formatDateTime(enginOrderListBean.getOrderDate()));
//            row.add(ExamineStatusEnum.valueOf(enginOrderListBean.getExamineStatus()).getMsg());
            row.add(EnumUtil.getNameFieldMap(ExamineStatusEnum.class, "value").get(enginOrderListBean.getExamineStatus()));
            row.add(enginOrderListBean.getCustomerNumber());
            row.add(enginOrderListBean.getCustomerName());
            row.add(enginOrderListBean.getRefEnginRecordNo());
            row.add(enginOrderListBean.getRefProjectCategory());
            row.add(enginOrderListBean.getRefTradeCategory());
            row.add(enginOrderListBean.getRefFactoryNo());
            row.add(enginOrderListBean.getRefUseUnit());
            row.add(enginOrderListBean.getRefInstallAddress());
            row.add(enginOrderListBean.getSaleTypeName());
            row.add(enginOrderListBean.getRefLinkman());
            row.add(enginOrderListBean.getRefTel());
            row.add(enginOrderListBean.getRefPhone());
            row.add(enginOrderListBean.getTakeDeposit() ? "不扣" : "扣");
            row.add(enginOrderListBean.getFileNo());
            row.add(enginOrderListBean.getRefRegionWork());
            row.add(enginOrderListBean.getServiceName());
            row.add(enginOrderListBean.getRefProjectNote());
            row.add(enginOrderListBean.getRefProjectType());
            row.add(enginOrderListBean.getRefBuyUnitName());
            row.add(enginOrderListBean.getRefPromiseProvide());
            if (!adminUser.getIsCustomer()) {
                row.add(enginOrderListBean.getGeLiInerNote());
            }
            row.add(enginOrderListBean.getRemark());
            row.add(enginOrderListBean.getRefDeclareNo());
            row.add(enginOrderListBean.getCreateName());
            row.add(DateUtil.formatDateTime(enginOrderListBean.getCreateTime()));
            row.add(enginOrderListBean.getConfirmName());
            row.add(DateUtil.formatDateTime(enginOrderListBean.getConfirmTime()));
            row.add(enginOrderListBean.getUpdateName());
            row.add(DateUtil.formatDateTime(enginOrderListBean.getUpdateTime()));
            row.add(DateUtil.formatDateTime(enginOrderListBean.getCloseTime()));
            row.add(enginOrderListBean.getExamineNote());
            row.add(index);
            row.add(enginOrderListBean.getMaterialOldNumber());
            row.add(enginOrderListBean.getMaterialNumber());
            row.add(enginOrderListBean.getMaterialName());
            row.add(enginOrderListBean.getSpecification());
            row.add(enginOrderListBean.getUnit());
            row.add(enginOrderListBean.getPrice());
            row.add(enginOrderListBean.getEnginNum());
            row.add(enginOrderListBean.getQty());
            row.add(enginOrderListBean.getTotalAmount());
            row.add(enginOrderListBean.getCustomerWalletName2());
            row.add(enginOrderListBean.getPayRebateAmount());
            row.add(enginOrderListBean.getDiscAmount());
            row.add(enginOrderListBean.getCustomerWalletName());
            row.add(enginOrderListBean.getPayAmount());
            row.add(enginOrderListBean.getIsDirectTransfer() ? "是":"否");
            row.add(enginOrderListBean.getDirectTransferQty());
            row.add(enginOrderListBean.getOldQty());
            row.add(enginOrderListBean.getApplySendQty());
            row.add(enginOrderListBean.getRefundProductQty());
            row.add(enginOrderListBean.getHasSendQty());
            row.add(enginOrderListBean.getItemRemark());
            row.add(enginOrderListBean.getTax());
            row.add(enginOrderListBean.getRealMaterialName());
            row.add(enginOrderListBean.getRealMaterialNumber());
            row.add(enginOrderListBean.getRealMaterialOldNumber());
            row.add(enginOrderListBean.getRealSpecification());
            row.add(enginOrderListBean.getMaterialGroupName());
            row.add(enginOrderListBean.getK3CategoryName());
            rows.add(row);
            index++;
        }

        if (CollectionUtil.isNotEmpty(rows)) {
            List<Object> row = new ArrayList<>();
            row.add("合计：");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            if (!adminUser.getIsCustomer()) {
                row.add("");
            }
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add(sumQty);
            row.add(sumTotalAmount);
            row.add("");
            row.add("");
            row.add(sumDiscAmount);
            row.add("");
            row.add(sumPayAmount);
            row.add("");
            row.add(sumDirectQty);
            row.add(sumOldQty);
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            rows.add(row);
        }

        ExcelData excelData = new ExcelData();
        excelData.setRows(rows);
        excelData.setTitles(Arrays.asList(titles));
        return excelData;
    }

    /**
     * 商用工程订单-列表(导出)
     */
    public ExcelData exportTrade(List<EnginOrderListBean> enginOrderListBeans) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        String[] titles = new String[]{
                "工程订单号","订单日期","单据状态","经销商编码","经销商名称","工程登录编号","项目名称","行业类别","工程编号","机型类别","工程登录类型",
                "跨区厂编号","使用单位","安装地址","联系人","固定电话","移动电话","不扣押金","文件编号","业务员","项目说明","项目类型",
                "备注", "制单人", "制单日期", "审核人", "审核日期", "最后更新人", "最更新日期", "关闭日期",
                "审批说明", "序号", "销售类型", "厂产品代码", "物料编码", "产品名称", "规格型号", "单位", "单价", "工程登录数量", "数量",
                "订单金额", "返利类型", "实付返利金额", "格力折扣", "现金钱包", "实付金额", "是否直调", "直调数量", "原订单数量", "表体备注",
                "税率","实装机型名称","实装机型编码","实装机型旧编码","实装机型规格","物料分组","存货类别"
        };
        if (!adminUser.getIsCustomer()) {
            titles = new String[]{
                    "工程订单号","订单日期","单据状态","经销商编码","经销商名称","工程登录编号","项目名称","行业类别","工程编号","机型类别","工程登录类型",
                    "跨区厂编号","使用单位","安装地址","联系人","固定电话","移动电话","不扣押金","文件编号","业务员","项目说明","项目类型",
                    "格力内部备注", "备注", "制单人", "制单日期", "审核人", "审核日期", "最后更新人", "最后更新日期", "关闭日期",
                    "审批说明", "序号", "销售类型", "厂产品代码", "物料编码", "产品名称", "规格型号", "单位", "单价", "工程登录数量", "数量",
                    "订单金额", "返利类型", "实付返利金额", "格力折扣", "现金钱包", "实付金额", "是否直调", "直调数量", "原订单数量", "表体备注",
                    "税率","实装机型名称","实装机型编码","实装机型旧编码","实装机型规格","物料分组","存货类别"
            };
        }
        List<List<Object>> rows = new ArrayList<>();

        long index = 1;
        String orderNo = "";
        int sumQty = 0;
        int sumDirectQty = 0;
        int sumOldQty = 0;
        BigDecimal sumTotalAmount = new BigDecimal("0");
        BigDecimal sumRebateAmount = new BigDecimal("0");
        BigDecimal sumDiscAmount = new BigDecimal("0");
        BigDecimal sumPayAmount = new BigDecimal("0");
        for (EnginOrderListBean enginOrderListBean : enginOrderListBeans) {
            sumQty = sumQty + enginOrderListBean.getQty();
            sumDirectQty = sumDirectQty + enginOrderListBean.getDirectTransferQty();
            sumOldQty = sumOldQty + enginOrderListBean.getOldQty();
            sumTotalAmount = sumTotalAmount.add(enginOrderListBean.getTotalAmount());
            sumRebateAmount = sumRebateAmount.add(enginOrderListBean.getPayRebateAmount());
            sumDiscAmount = sumDiscAmount.add(enginOrderListBean.getDiscAmount());
            sumPayAmount = sumPayAmount.add(enginOrderListBean.getPayAmount());
            List<Object> row = new ArrayList<>();
//            boolean isFill = true;
            if (!orderNo.equals(enginOrderListBean.getEnginOrderNo())) {
                orderNo = enginOrderListBean.getEnginOrderNo();
//                isFill = false;
                index = 1;
            }
            row.add(enginOrderListBean.getEnginOrderNo());
            row.add(DateUtil.formatDateTime(enginOrderListBean.getOrderDate()));
//            row.add(ExamineStatusEnum.valueOf(enginOrderListBean.getExamineStatus()).getMsg());
            row.add(EnumUtil.getNameFieldMap(ExamineStatusEnum.class, "value").get(enginOrderListBean.getExamineStatus()));
            row.add(enginOrderListBean.getCustomerNumber());
            row.add(enginOrderListBean.getCustomerName());
            row.add(enginOrderListBean.getRefEnginRecordNo());
            row.add(enginOrderListBean.getRefProjectName());
            row.add(enginOrderListBean.getRefTradeCategory());
            row.add(enginOrderListBean.getRefProjectNo());
            row.add(enginOrderListBean.getRefMachineType());
            row.add(enginOrderListBean.getRefPromiseStatus());
            row.add(enginOrderListBean.getRefFactoryNo());
            row.add(enginOrderListBean.getRefUseUnit());
            row.add(enginOrderListBean.getRefInstallAddress());
//            row.add(enginOrderListBean.getSaleTypeName());
            row.add(enginOrderListBean.getRefLinkman());
            row.add(enginOrderListBean.getRefTel());
            row.add(enginOrderListBean.getRefPhone());
            row.add(enginOrderListBean.getTakeDeposit() ? "不扣" : "扣");
            row.add(enginOrderListBean.getFileNo());
            row.add(enginOrderListBean.getServiceName());
            row.add(enginOrderListBean.getRefProjectNote());
            row.add(enginOrderListBean.getRefProjectType());
            if (!adminUser.getIsCustomer()) {
                row.add(enginOrderListBean.getGeLiInerNote());
            }
            row.add(enginOrderListBean.getRemark());
            row.add(enginOrderListBean.getCreateName());
            row.add(DateUtil.formatDateTime(enginOrderListBean.getCreateTime()));
            row.add(enginOrderListBean.getConfirmName());
            row.add(DateUtil.formatDateTime(enginOrderListBean.getConfirmTime()));
            row.add(enginOrderListBean.getUpdateName());
            row.add(DateUtil.formatDateTime(enginOrderListBean.getUpdateTime()));
            row.add(DateUtil.formatDateTime(enginOrderListBean.getCloseTime()));
            row.add(enginOrderListBean.getExamineNote());
            row.add(index);
            row.add(enginOrderListBean.getItemSaleTypeName());
            row.add(enginOrderListBean.getMaterialOldNumber());
            row.add(enginOrderListBean.getMaterialNumber());
            row.add(enginOrderListBean.getMaterialName());
            row.add(enginOrderListBean.getSpecification());
            row.add(enginOrderListBean.getUnit());
            row.add(enginOrderListBean.getPrice());
            row.add(enginOrderListBean.getEnginNum());
            row.add(enginOrderListBean.getQty());
            row.add(enginOrderListBean.getTotalAmount());
            row.add(enginOrderListBean.getCustomerWalletName2());
            row.add(enginOrderListBean.getPayRebateAmount());
            row.add(enginOrderListBean.getDiscAmount());
            row.add(enginOrderListBean.getCustomerWalletName());
            row.add(enginOrderListBean.getPayAmount());
            row.add(enginOrderListBean.getIsDirectTransfer() ? "是":"否");
            row.add(enginOrderListBean.getDirectTransferQty());
            row.add(enginOrderListBean.getOldQty());
            row.add(enginOrderListBean.getItemRemark());
            row.add(enginOrderListBean.getTax());
            row.add(enginOrderListBean.getRealMaterialName());
            row.add(enginOrderListBean.getRealMaterialNumber());
            row.add(enginOrderListBean.getRealMaterialOldNumber());
            row.add(enginOrderListBean.getRealSpecification());
            row.add(enginOrderListBean.getMaterialGroupName());
            row.add(enginOrderListBean.getK3CategoryName());
            rows.add(row);
            index++;
        }

        if (CollectionUtil.isNotEmpty(rows)) {
            List<Object> row = new ArrayList<>();
            row.add("合计：");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            if (!adminUser.getIsCustomer()) {
                row.add("");
            }
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add(sumQty);
            row.add(sumTotalAmount);
            row.add("");
            row.add(sumRebateAmount);
            row.add(sumDiscAmount);
            row.add("");
            row.add(sumPayAmount);
            row.add("");
            row.add(sumDirectQty);
            row.add(sumOldQty);
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            row.add("");
            rows.add(row);
        }

        ExcelData excelData = new ExcelData();
        excelData.setRows(rows);
        excelData.setTitles(Arrays.asList(titles));
        return excelData;
    }

    @Transactional(rollbackFor = Exception.class)
    public void importInit(List<Object> datas, Boolean isCreateOrder) {
        List<AdminUser> adminUsers = adminUserService.list();
        List<KingDeeCustomer> kingDeeCustomers = k3CustomerLogic.allList();
        List<SaleType> saleTypes = saleTypeService.list();
        List<KingDeeMaterial> materialds = kingDeeMaterialService.list();

        Map<String, AdminUser> userMap = adminUsers.stream()
                .collect(Collectors.toMap(AdminUser::getUserName, v -> v));
        Map<String, KingDeeCustomer> customerMap = kingDeeCustomers.stream()
                .collect(Collectors.toMap(KingDeeCustomer::getNumber, v -> v));
        Map<String, SaleType> saleMap = saleTypes.stream().collect(Collectors.toMap(SaleType::getSaleCode, v -> v));
        Map<String, KingDeeMaterial> materialMap = materialds.stream().collect(Collectors.toMap(KingDeeMaterial::getNumber, v -> v));

        Map<String,List<Object>> groupDatas = new HashMap<>();
        for(Object o : datas){
            List<Object> row = (List<Object>)o;
            String orderId = (String)row.get(31);
            if (Objects.nonNull(orderId)) {
                if (Objects.isNull(groupDatas.get(orderId))) {
                    List<Object> list = new ArrayList<>();
                    list.add(o);
                    groupDatas.put(orderId, list);
                } else {
                    groupDatas.get(orderId).add(o);
                }
            }
        }

        for(String key : groupDatas.keySet()){

            List<Object> rows = groupDatas.get(key);

            String enginInfoId = IdWorker.getIdStr();
            String enginOrderId = IdWorker.getIdStr();
            String enginInfoNo = commonLogic.generateNo("EIO" ,"enginInfoOrder",15);
            String enginOrderNo = commonLogic.generateNo("4","enginOrder",13);

            for(int i =0 ;i < rows.size() ; i++ ){
                List<Object> row = (List<Object>)rows.get(i);
                String userName = (String)row.get(0);//需要查帐号
                String customerNumber = (String)row.get(1);//需要查经销商
                String orderDate = (String)row.get(2);
                String projectName = (String)row.get(3);
                String machineType = (String)row.get(4);
                String useUnit = (String)row.get(5);
                String installAddress = (String)row.get(6);
                String projectNo = (String)row.get(7);
                String enginFactoryNo = (String)row.get(8);
                String enginSignType = (String)row.get(9);
                String tradeCategory = (String)row.get(10);
                String linkman = (String)row.get(11);
                String phone = (String)row.get(12);
                String tel = (String)row.get(13);
                String powerCategory = (String)row.get(14);
                String geLiNote = (String)row.get(15);
                String geLiInerNote = (String)row.get(16);
                String remark = (String)row.get(17);
                String infoItemRemark = (String)row.get(18);
                String orderItemRemark = (String)row.get(19);
                String k3ServiceUserName = (String)row.get(20);//需要查帐号
                String saleTypeCode = (String)row.get(21);  //需要查销售类型
                String materialNumber = (String)row.get(22);     //需要查物料
                String serviceUserName = (String)row.get(23);
                String walletName = (String)row.get(24); //需要查钱包
                String rebateWalletName = (String)row.get(25); //需要查钱包
                BigDecimal price = new BigDecimal(row.get(26).toString());
                int qty = new BigDecimal(row.get(27).toString()).intValue();
                BigDecimal discAmount = new BigDecimal(row.get(28).toString());
                BigDecimal totalRebateAmount = new BigDecimal(row.get(29).toString());
                String fileNo = (String)row.get(30);
                String orderId = (String)row.get(31);

                AdminUser adminUser = userMap.get(userName);
                SaleType saleType = saleMap.get(saleTypeCode);
                KingDeeCustomer customer = customerMap.get(customerNumber);
                AdminUser serviceUser = userMap.get(k3ServiceUserName);
                AdminUser itemServiceUser = userMap.get(serviceUserName);
                KingDeeMaterial material = materialMap.get(materialNumber);
                AdminUserWebsitRela adminUserWebsitRela = adminUserWebsitRelaService.lambdaQuery()
                        .eq(AdminUserWebsitRela::getAdminUserId, adminUser.getAdminUserId())
                        .one();
                //查询钱包
                List<CustomerWalletBean> customerWalletBeans = walletLogic.queryWalletByCustomerId(customer.getId(), null);
                List<CustomerWalletBean> wallet1 = customerWalletBeans.stream()
                        .filter(v -> v.getName().equals(walletName) && v.getType().equals(WalletTypeEnum.COMMONLY.getKey())).collect(Collectors.toList());
                List<CustomerWalletBean> wallet2 = customerWalletBeans.stream()
                        .filter(v -> v.getName().equals(rebateWalletName) && v.getType().equals(WalletTypeEnum.REBATE.getKey())).collect(Collectors.toList());
                // 工程信息单表体
                EnginInfoOrderItem infoOrderItem = new EnginInfoOrderItem();
                infoOrderItem.setEnginInfoId(enginInfoId);
                infoOrderItem.setEnginInfoNo(enginInfoNo);
                if(Objects.isNull(saleType)) {
                    throw new RemoteServiceException(orderId + "的销售类型为空，处理失败");
                }
                infoOrderItem.setSaleTypeId(saleType.getId());
                infoOrderItem.setSaleTypeCode(saleTypeCode);
                infoOrderItem.setSaleTypeName(saleType.getSaleName());
                infoOrderItem.setMaterialId(material.getId());
                infoOrderItem.setMaterialNumber(material.getNumber());
                infoOrderItem.setMaterialOldNumber(material.getOldNumber());
                infoOrderItem.setMaterialName(material.getName());
                infoOrderItem.setK3CategoryId(material.getCategoryId());
                infoOrderItem.setK3CategoryNumber(material.getCategoryNumber());
                infoOrderItem.setK3CategoryName(material.getCategoryName());
                infoOrderItem.setSpecification(material.getSpecification());
                infoOrderItem.setUnit(material.getBaseUnitId());
                infoOrderItem.setPrice(price);
                infoOrderItem.setQty(qty);
                infoOrderItem.setTotalAmount(price.multiply(BigDecimal.valueOf(qty)));
                infoOrderItem.setRemark(infoItemRemark);
                infoOrderItem.insert();

                if (isCreateOrder) {
                    EnginOrderItem orderItem = new EnginOrderItem();
                    orderItem.setParentId(enginOrderId)
                            .setEnginOrderNo(orderId)
                            .setUseRefCount(0)
                            .setAdminUserId(adminUser.getAdminUserId())
                            .setAdminWebsitId(adminUserWebsitRela.getAdminWebsitId())
                            .setRefEnginRecordNo(enginInfoNo)
                            .setSaleTypeId(saleType.getId())
                            .setSaleTypeCode(saleTypeCode)
                            .setSaleTypeName(saleType.getSaleName())
                            .setMaterialId(material.getId())
                            .setMaterialNumber(material.getNumber())
                            .setMaterialOldNumber(material.getOldNumber())
                            .setMaterialName(material.getName())
                            .setK3CategoryId(material.getCategoryId())
                            .setK3CategoryNumber(material.getCategoryNumber())
                            .setK3CategoryName(material.getCategoryName())
                            .setServiceId(itemServiceUser.getAdminUserId())
                            .setServiceName(itemServiceUser.getNickName())
                            .setSpecification(material.getSpecification())
                            .setUnit(material.getBaseUnitId())
                            .setTax(material.getTaxRateId())
                            .setRemark(orderItemRemark);
                    if(wallet1.size() > 0) {
                        orderItem.setCustomerWalletId(wallet1.get(0).getCustomerWalletId());
                        orderItem.setCustomerWalletNumber(wallet1.get(0).getWalletNumber());
                        orderItem.setCustomerWalletName(wallet1.get(0).getCustomerWalletName());
                    }
                    if(wallet2.size() > 0){
                        orderItem.setCustomerWalletId2(wallet2.get(0).getCustomerWalletId());
                        orderItem.setCustomerWalletName2(wallet2.get(0).getCustomerWalletName());
                    }
                    orderItem.setEnginPrice(price);
                    orderItem.setEnginNum(qty);
                    orderItem.setEnginNum(qty);
                    orderItem.setEnginTotality(price.multiply(BigDecimal.valueOf(qty)));
                    orderItem.setPrice(price);
                    orderItem.setQty(qty);
                    orderItem.setTotalAmount(price.multiply(BigDecimal.valueOf(qty)));
                    orderItem.setDiscAmount(discAmount);
                    orderItem.setTotalDiscAmount(discAmount.multiply(BigDecimal.valueOf(qty)));
                    orderItem.setRebateAmount(totalRebateAmount);
                    orderItem.setPayRebateAmount(orderItem.getRebateAmount());
                    orderItem.setPayAmount(orderItem.getTotalAmount().subtract(totalRebateAmount));
                    orderItem.setSingleRebateAmount(totalRebateAmount.divide(BigDecimal.valueOf(qty),6,BigDecimal.ROUND_HALF_UP));
                    orderItem.setSinglePayPrice(orderItem.getPayAmount().divide(BigDecimal.valueOf(qty),6,BigDecimal.ROUND_HALF_UP));
                    orderItem.setOldQty(qty);
                    orderItem.setOldPayAmount(orderItem.getPayAmount());
                    orderItem.setRemark(remark);
                    orderItem.setRefundableQty(qty);

                    // 返利比例
                    BigDecimal rebateRate = totalRebateAmount.divide(orderItem.getTotalAmount(),6,BigDecimal.ROUND_HALF_UP);
                    orderItem.setRebateRate(rebateRate);
                    orderItem.insert();
                }

                // 表头
                if (i == rows.size() - 1) {
                    // 信息单
                    EnginInfoOrder infoOrder = new EnginInfoOrder();
                    infoOrder.setEnginInfoId(enginInfoId);
                    infoOrder.setEnginInfoNo(enginInfoNo);
                    infoOrder.setAdminCompanyId(adminUser.getAdminCompanyId());
                    infoOrder.setIsOldOrder(true);
                    infoOrder.setCustomerId(customer.getId());
                    infoOrder.setCustomerNumber(customer.getNumber());
                    infoOrder.setCustomerName(customer.getName());
                    infoOrder.setOrderDate(DateUtil.parseDate(orderDate));
                    infoOrder.setProjectName(projectName);
                    infoOrder.setMachineType(machineType);
                    infoOrder.setUseUnit(useUnit);
                    infoOrder.setInstallAddress(installAddress);
                    infoOrder.setProjectNo(projectNo);
                    infoOrder.setEnginFactoryNo(enginFactoryNo);
                    infoOrder.setEnginSignType(enginSignType);
                    infoOrder.setTradeCategory(tradeCategory);
                    infoOrder.setLinkman(linkman);
                    infoOrder.setPhone(phone);
                    infoOrder.setTel(tel);
                    infoOrder.setPowerCategory(powerCategory);
                    infoOrder.setServiceId(serviceUser.getAdminUserId());
                    infoOrder.setServiceName(serviceUser.getNickName());
                    infoOrder.setContractExpireDate(new Date(DateUtil.date().getTime() + (31536L * 1000000)));
                    infoOrder.setGeLiNote(geLiNote);
                    infoOrder.setGeLiInerNote(geLiInerNote);
                    infoOrder.setRemark(remark);
                    infoOrder.setIsOldOrder(true);
                    infoOrder.setExamineNote("导入审核通过");
                    infoOrder.setExamineStatus(ExamineStatusEnum.OK.toString());
                    infoOrder.setCreateBy(CommonUtils.getUsername());
                    infoOrder.setCreateName(CommonUtils.getNickName());
                    infoOrder.setUpdateBy(CommonUtils.getUsername());
                    infoOrder.setUpdateName(CommonUtils.getNickName());
                    infoOrder.setSubmitBy(CommonUtils.getUsername());
                    infoOrder.setSubmitName(CommonUtils.getNickName());
                    infoOrder.setSubmitTime(DateUtil.date());
                    infoOrder.setConfirmBy(CommonUtils.getUsername());
                    infoOrder.setConfirmName(CommonUtils.getNickName());
                    infoOrder.setConfirmTime(DateUtil.date());
                    infoOrder.insert();

                    // 商用工程订单
                    if (isCreateOrder) {
                        EnginOrder enginOrder = new EnginOrder();
                        enginOrder.setEnginOrderId(enginOrderId)
                                .setAdminCompanyId(adminUser.getAdminCompanyId())
                                .setAdminUserId(adminUser.getAdminUserId())
                                .setAdminWebsitId(adminUserWebsitRela.getAdminWebsitId())
                                .setRefCount(0)
                                .setCustomerId(customer.getId())
                                .setCustomerNumber(customer.getNumber())
                                .setCustomerName(customer.getName())
                                .setServiceId(serviceUser.getAdminUserId())
                                .setServiceName(serviceUser.getNickName())
                                .setEnginOrderType(OrderTypeEnum.TRADE.getKey())
                                .setEnginOrderNo(orderId)
                                .setOrderDate(DateUtil.parseDate(orderDate))
                                .setRefEnginRecordNo(enginInfoNo)
                                .setRefProjectName(projectName)
                                .setRefUseUnit(useUnit)
                                .setRefInstallAddress(installAddress)
                                .setRefProjectNo(projectNo)
                                .setRefFactoryNo(enginFactoryNo)
                                .setRefPromiseStatus(enginSignType)
                                .setRefTradeCategory(tradeCategory)
                                .setRefLinkman(linkman)
                                .setRefPhone(phone)
                                .setRefTel(tel)
                                .setRefPowerCategory(powerCategory)
                                .setRefMachineType(machineType)
                                .setFileNo(fileNo)
                                .setTakeDeposit(true)
                                .setGeLiNote(geLiNote)
                                .setGeLiInerNote(geLiInerNote)
                                .setExamineStatus(ExamineStatusEnum.SAVE.toString())
                                .setCreateBy(CommonUtils.getUsername())
                                .setCreateName(CommonUtils.getNickName())
                                .setUpdateBy(CommonUtils.getUsername())
                                .setUpdateName(CommonUtils.getNickName())
                                .insert();
                    }
                }
            }
        }
    }

    public PoySaleCountBean countList(String customerWalletId, String customerKeyword, List<String> enginOrderNo,
                                      String enginOrderType, String refProjectNo, String refEnginRecordNo,
                                      String refProjectCategory, String refProjectName, String refUseUnit,
                                      String refTradeCategory, String startCreateTime, String endCreateTime,
                                      String startOrderTime, String endOrderTime, String saleTypeId, String createName,
                                      String confirmName, List<String> examineStatus, String serviceId, String specification,
                                      String materialNumber, String materialName, String materialOldNumber,
                                      String refRegionWork, String remark, String geLiInerNote, String refFactoryNo,
                                      String refBuyUnitName, String refPromiseProvide, Boolean isDirectTransfer) {
        AdminUserCom adminUser = commonLogic.getAdminUser(true);
        String customerId = adminUser.getIsCustomer() ? adminUser.getCustomerId() : "";
        return enginOrderReserveMapper.countList(customerWalletId, customerKeyword, enginOrderNo, enginOrderType,
                refProjectNo, refEnginRecordNo, refProjectCategory, refProjectName, refUseUnit, refTradeCategory,
                startCreateTime, endCreateTime,startOrderTime,endOrderTime, saleTypeId, createName,
                confirmName, examineStatus, serviceId, adminUser.getAdminCompanyIds(), specification, adminUser.getServiceIds(),
                customerId, materialNumber, materialName, materialOldNumber, refRegionWork, remark, geLiInerNote, refFactoryNo,
                adminUser.getK3CategoryIds(), refBuyUnitName, refPromiseProvide, isDirectTransfer);
    }

    public EnginOrder findOrderById(String id, String orderType) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        return enginOrderService.lambdaQuery()
                .eq(EnginOrder::getAdminCompanyId, adminUser.getAdminCompanyId())
                .eq(adminUser.getIsCustomer(), EnginOrder::getCustomerId, adminUser.getCustomerId())
                .eq(EnginOrder::getEnginOrderId, id)
                .eq(EnginOrder::getEnginOrderType, orderType)
                .in(EnginOrder::getExamineStatus, ExamineStatusEnum.SAVE.toString(), ExamineStatusEnum.CLOSE.toString())
                .one();
    }

    public List<CustomerWalletAmountBean> handleDisplaceRefundWalletMethod(EnginOrder enginOrder, EnginOrderItem refundOrderItem) {
        return this.handleWalletMethod(enginOrder, new ArrayList<EnginOrderItem>() {{this.add(refundOrderItem);}}, true,
                "工程订单退款-置换退订", "工程订单返利退款-置换退订");
    }
}
