package com.zfire.mall.manager.logic.invoice;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zfire.mall.manager.bean.DirectOrderBean;
import com.zfire.mall.manager.bean.admin.AdminUserCom;
import com.zfire.mall.manager.bean.engin.deposit.DepositManageRecordBean;
import com.zfire.mall.manager.bean.engin.order.EnginOrderBean;
import com.zfire.mall.manager.bean.engin.order.EnginOrderItemBean;
import com.zfire.mall.manager.bean.invoice.InvoiceApplicationOrderRequest;
import com.zfire.mall.manager.bean.invoice.InvoiceApplicationRefundSon;
import com.zfire.mall.manager.bean.invoice.InvoiceRequestJson;
import com.zfire.mall.manager.bean.invoice.InvoiceRequestRefund;
import com.zfire.mall.manager.bean.sale.SaleOrderBean;
import com.zfire.mall.manager.bean.wallet.CustomerWalletAmountBean;
import com.zfire.mall.manager.commonmapper.InvoiceMapper;
import com.zfire.mall.manager.constant.Constant;
import com.zfire.mall.manager.enums.ExamineStatusEnum;
import com.zfire.mall.manager.enums.InvoiceCustomerEnum;
import com.zfire.mall.manager.enums.OrderOperationTypeEnum;
import com.zfire.mall.manager.enums.OrderTypeEnum;
import com.zfire.mall.manager.exception.RemoteServiceException;
import com.zfire.mall.manager.logic.common.CommonLogic;
import com.zfire.mall.manager.logic.customer.CustomerProductTypeLogic;
import com.zfire.mall.manager.logic.engin.deposit.DepositManageLogic;
import com.zfire.mall.manager.logic.k3.K3Logic;
import com.zfire.mall.manager.logic.k3.bill.GeJiangInStockLogic;
import com.zfire.mall.manager.logic.pick.PickLogic;
import com.zfire.mall.manager.logic.reserved.ReservedLogic;
import com.zfire.mall.manager.logic.retail.RetailOrderLogic;
import com.zfire.mall.manager.logic.saletype.SaleRetreatOrderLogic;
import com.zfire.mall.manager.logic.stock.StockCommonLogic;
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.RedisUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.redis.util.RedisLockRegistry;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 申请发货单
 *
 * @author change
 */
@Service
public class InvoiceRefundLogic {

    @Autowired
    InvoiceMapper invoiceMapper;

    @Autowired
    StockCustomerService stockCustomerService;

    @Autowired
    StockCommonLogic stockCommonLogic;

    @Autowired
    KingDeeOrganizationService kingDeeOrganizationService;

    @Autowired
    K3Logic k3Logic;

    @Autowired
    StockService stockService;

    @Autowired
    CommonLogic commonLogic;

    @Autowired
    RetailOrderItemService retailOrderItemService;

    @Autowired
    RetailOrderService retailOrderService;

    @Autowired
    KingDeeCustomerService kingDeeCustomerService;

    @Autowired
    KingDeeMaterialService kingDeeMaterialService;

    @Autowired
    InvoiceApplicationService invoiceApplicationService;

    @Autowired
    InvoiceApplicationOrderService invoiceApplicationOrderService;

    @Autowired
    RetailOrderLogic retailOrderLogic;

    @Autowired
    DisplaceOrderItemService displaceOrderItemService;

    @Autowired
    DisplaceOrderService displaceOrderService;

    @Autowired
    EnginOrderService enginOrderService;

    @Autowired
    EnginOrderItemService enginOrderItemService;

    @Autowired
    DepositManageItemService depositManageItemService;

    @Autowired
    CustomerProductTypeLogic customerProductTypeLogic;

    @Autowired
    DepositManageLogic depositManageLogic;

    @Autowired
    WalletLogic walletLogic;

    @Autowired
    OrderExecRecordService orderExecRecordService;

    @Autowired
    CustomerWalletService customerWalletService;

    @Autowired
    ReservedLogic reservedLogic;

    @Autowired
    SalesOrderService salesOrderService;

    @Autowired
    RetreatDocumentOrderService retreatDocumentOrderService;

    @Autowired
    ShipDocumentService shipDocumentService;

    @Autowired
    PickManagerShipService pickManagerShipService;

    @Autowired
    AdminWebsitService adminWebsitService;

    @Autowired
    RedisUtil redisUtil;

    @Autowired
    PickLogic pickLogic;

    @Autowired
    RequisitionOrderService requisitionOrderService;

    @Autowired
    RequisitionOrderItemService requisitionOrderItemService;

    @Autowired
    SalesOrderItemService salesOrderItemService;

    @Autowired
    KingDeeStockService kingDeeStockService;
    @Autowired
    InvoiceLogic invoiceLogic;

    @Autowired
    StockCorrespondService stockCorrespondService;

    @Autowired
    StockCorrespondPositionService stockCorrespondPositionService;

    @Autowired
    SaleRetreatOrderLogic saleRetreatOrderLogic;

    @Autowired
    GeJiangInStockLogic geJiangInStockLogic;

    @Autowired
    SalesOrderPictureService salesOrderPictureService;


    @Autowired
    RedisLockRegistry redisLockRegistry;


    public IPage<SaleOrderBean> salesList(String categoryName,String mainOrderId, String enginOrderNo, String refEnginRecordNo, String refProjectName, Integer saleType, String id, String orderNo, String correspondName, String materialNumber, String customerName, String correspondId, String specification, String materialName, String customerNumber, String startTime, String endTime, Integer pageNum, Integer pageSize) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        String customerId = adminUser.getIsCustomer() ? adminUser.getCustomerId() : "";

        IPage<SaleOrderBean> list = invoiceMapper.listSaleOrder(new Page<>(pageNum, pageSize),categoryName, mainOrderId, enginOrderNo, refEnginRecordNo, refProjectName, saleType, id, correspondName, materialNumber, orderNo, customerName, correspondId, specification, materialName,
                customerNumber, startTime, endTime, customerId, adminUser.getServiceIds(), adminUser.getK3CategoryIds());
        return list;
    }

    @Transactional(rollbackFor = Exception.class)
    public void add(InvoiceRequestRefund invoiceRequest, HttpServletRequest request) {


        AdminUserCom adminUser = commonLogic.getAdminUser();
        String customerId = adminUser.getIsCustomer() ? adminUser.getCustomerId() : "";

        IPage<SaleOrderBean> list = invoiceMapper.listSaleOrder(new Page<>(1, 10),null, null, null, null, null, null, invoiceRequest.getSalesOrderId(), null,
                null, null, null, null, null, null,
                null, null, null, customerId, adminUser.getServiceIds(), adminUser.getK3CategoryIds());

        if (CollectionUtils.isEmpty(list.getRecords())){
            throw new RemoteServiceException("已退货过，退货数量已变更");
        }

        //2，添加发货申请单
        SalesOrder salesOrder1 = salesOrderService.getById(invoiceRequest.getSalesOrderId());

        if (salesOrder1.getExamineStatus().equals(ExamineStatusEnum.OK))
            throw new RemoteServiceException("销售出库单已通过，请做销售退库单");

        if (salesOrder1 == null)
            throw new RemoteServiceException("销售出库单没有");

        invoiceRequest.setOrderTime(new Date());
        String substring = salesOrder1.getOrderNo().substring(0, 2);
        if (StringUtils.isEmpty(substring))
            throw new RemoteServiceException("该经销商不在区域范围");
        //生成订单流水号
        String yyyyMM = DateUtil.format(new Date(), "yyyyMM");
        String orderWater = yyyyMM.substring(yyyyMM.length() - 4);
        if (redisUtil.get(Constant.RedisPrefix.INVOICE_APPLICATION + orderWater) == null) {
            redisUtil.set(Constant.RedisPrefix.INVOICE_APPLICATION + orderWater, "0000", 2726560);
        }
        Object water = redisUtil.get(Constant.RedisPrefix.INVOICE_APPLICATION + orderWater);
        String s = pickLogic.generateNum(4, Convert.toStr(water));

        if (invoiceApplicationService.lambdaQuery().eq(InvoiceApplication::getId, salesOrder1.getOrderNo().substring(0, 1) + orderWater + s).count() > 0) {
            throw new RemoteServiceException("请勿频繁新增，稍等一会");
        }
        redisUtil.set(Constant.RedisPrefix.INVOICE_APPLICATION + orderWater, s, 2726560);


        StockCorrespond stockCorrespond = stockCorrespondService.getById(invoiceRequest.getCorrespondId());
        InvoiceApplication invoiceApplicationServiceById = invoiceApplicationService.getById(salesOrder1.getOrderNo());
        InvoiceApplication invoiceApplication = BeanUtil.toBean(invoiceApplicationServiceById, InvoiceApplication.class);
        invoiceApplication.setId(substring + orderWater + s);
        invoiceApplication.setType(2);
        invoiceApplication.setEnginOrderNo(invoiceApplicationServiceById.getEnginOrderNo());
        invoiceApplication.setOrderTime(new Date());
        invoiceApplication.setExamineStatus(invoiceRequest.getExamineStatus());
        invoiceApplication.setRemark(invoiceRequest.getRemark());
        invoiceApplication.setFileName(invoiceRequest.getFileName());
        invoiceApplication.setFileUrl(invoiceRequest.getFileUrl());
        invoiceApplication.setCorrespondId(invoiceApplicationServiceById.getCorrespondId());
        invoiceApplication.setCorrespondName(invoiceApplicationServiceById.getCorrespondName());
        invoiceApplication.setSalesOrderId(salesOrder1.getId());
        invoiceApplication.setSalesId(salesOrder1.getId());
        invoiceApplication.setCreateBy(null);
        invoiceApplication.setCreateTime(null);
        boolean save = invoiceApplicationService.save(invoiceApplication);

        //存储图片
        if (!org.springframework.util.CollectionUtils.isEmpty(invoiceRequest.getSalesOrderPictures())){
            for (SalesOrderPicture salesOrderPicture : invoiceRequest.getSalesOrderPictures()) {
                salesOrderPicture.setSalesId(invoiceApplication.getId());
            }
            salesOrderPictureService.saveBatch(invoiceRequest.getSalesOrderPictures());
        }

        List<InvoiceApplicationOrder> invoiceApplicationOrderArrayList = new ArrayList<>();
        for (InvoiceApplicationRefundSon order : invoiceRequest.getOrders()) {
            if (!order.getSalesOrderId().equals(invoiceRequest.getSalesOrderId()))
                throw new RemoteServiceException("不同销售出库单号，无法一起退货");

            if (order.getRefundableQty() == null || order.getRefundableQty().equals(0))
                continue;

            if (order.getRefundableQty() >= 0)
                throw new RemoteServiceException("数量不能为正数");

            SalesOrder salesOrder = salesOrderService.getById(order.getSalesOrderId());
            SalesOrderItem salesOrderItem = salesOrderItemService.getById(order.getSalesOrderItemId());

            if (salesOrderItem.getRefundableQty() + order.getRefundableQty() < 0)
                throw new RemoteServiceException("数量不能为超过可退货数量");

            InvoiceApplicationOrder invoiceApplicationOrder = BeanUtil.toBean(salesOrderItem, InvoiceApplicationOrder.class);
            invoiceApplicationOrder.setSalesOrderItemId(salesOrderItem.getId());
            invoiceApplicationOrder.setRefundableQty(order.getRefundableQty());
            invoiceApplicationOrder.setInvoiceNum(order.getRefundableQty());
            invoiceApplicationOrder.setApprovalNumber(order.getRefundableQty());
            invoiceApplicationOrder.setRemark(order.getRemark());
            invoiceApplicationOrder.setK3CategoryNumber(salesOrderItem.getK3CategoryNumber());
            invoiceApplicationOrder.setK3CategoryName(salesOrderItem.getK3CategoryName());
            invoiceApplicationOrder.setK3CategoryId(salesOrderItem.getK3CategoryId());

            invoiceApplicationOrder.setInvoiceId(invoiceApplication.getId());
            invoiceApplicationOrder.setPayAmount(invoiceApplicationOrder.getSinglePayPrice()
                    .multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));

            invoiceApplicationOrder.setTotalAmount(invoiceApplicationOrder.getPrice().multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));

            invoiceApplicationOrder.setPayRebateAmount(invoiceApplicationOrder.getSingleRebateAmount().multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));

            invoiceApplicationOrder.setTotalDiscAmount(invoiceApplicationOrder.getDiscAmount().multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));
            invoiceApplicationOrder.setId(null);
            invoiceApplicationOrderArrayList.add(invoiceApplicationOrder);
        }
        invoiceApplicationOrderService.saveBatch(invoiceApplicationOrderArrayList);

    }


    @Transactional(rollbackFor = Exception.class)
    public void update(InvoiceRequestJson invoiceRequest, HttpServletRequest request) throws InterruptedException {

        //2，添加发货申请单
        AdminUserCom adminUser = commonLogic.getAdminUser();


        invoiceRequest.updateById();

        //存储图片
        salesOrderPictureService.lambdaUpdate().eq(SalesOrderPicture::getSalesId,invoiceRequest.getId()).remove();
        if (!org.springframework.util.CollectionUtils.isEmpty(invoiceRequest.getSalesOrderPictures())){
            for (SalesOrderPicture salesOrderPicture : invoiceRequest.getSalesOrderPictures()) {
                salesOrderPicture.setSalesId(invoiceRequest.getId());
            }
            salesOrderPictureService.saveBatch(invoiceRequest.getSalesOrderPictures());
        }

        invoiceApplicationOrderService.lambdaUpdate().eq(InvoiceApplicationOrder::getInvoiceId, invoiceRequest.getId()).remove();
        List<InvoiceApplicationOrder> invoiceApplicationOrderArrayList = new ArrayList<>();
        for (InvoiceApplicationOrderRequest order : invoiceRequest.getOrders()) {
            if (order.getRefundableQty() == null || order.getRefundableQty().equals(0))
                continue;

            if (order.getRefundableQty() >= 0)
                throw new RemoteServiceException("数量不能为正数");


            SalesOrderItem salesOrderItem = salesOrderItemService.getById(order.getSalesOrderItemId());
            SalesOrder salesOrder = salesOrderService.getById(salesOrderItem.getSalesOrderId());

            if (salesOrderItem.getRefundableQty() + order.getRefundableQty() < 0)
                throw new RemoteServiceException("数量不能为超过可退货数量");

            InvoiceApplicationOrder invoiceApplicationOrder = BeanUtil.toBean(salesOrderItem, InvoiceApplicationOrder.class);
            invoiceApplicationOrder.setSalesOrderItemId(salesOrderItem.getId());
            invoiceApplicationOrder.setRefundableQty(order.getRefundableQty());
            invoiceApplicationOrder.setVarietyQty(order.getRefundableQty());
            invoiceApplicationOrder.setInvoiceNum(order.getRefundableQty());
            invoiceApplicationOrder.setApprovalNumber(order.getRefundableQty());

            invoiceApplicationOrder.setInvoiceId(invoiceRequest.getId());
            invoiceApplicationOrder.setPayAmount(invoiceApplicationOrder.getSinglePayPrice()
                    .multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));

            invoiceApplicationOrder.setTotalAmount(invoiceApplicationOrder.getPrice().multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));

            invoiceApplicationOrder.setPayRebateAmount(invoiceApplicationOrder.getSingleRebateAmount().multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));

            invoiceApplicationOrder.setTotalDiscAmount(invoiceApplicationOrder.getDiscAmount().multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));
            invoiceApplicationOrder.setId(null);
            invoiceApplicationOrder.setCustomerWalletId(invoiceApplicationOrder.getCustomerWalletId());
            invoiceApplicationOrder.setCustomerWalletName(invoiceApplicationOrder.getCustomerWalletName());
            invoiceApplicationOrder.setCustomerWalletNumber(invoiceApplicationOrder.getCustomerWalletNumber());
            invoiceApplicationOrder.setCustomerWalletId2(invoiceApplicationOrder.getCustomerWalletId2());
            invoiceApplicationOrder.setCustomerWalletName2(invoiceApplicationOrder.getCustomerWalletName2());
            invoiceApplicationOrderArrayList.add(invoiceApplicationOrder);
        }
        invoiceApplicationOrderService.saveBatch(invoiceApplicationOrderArrayList);
        invoiceMapper.updateStatus(invoiceRequest.getId());
        invoiceMapper.updateInvoice(invoiceRequest.getId());
    }


    @Transactional(rollbackFor = Exception.class)
    public void delete(String id) {

        InvoiceApplication byId = invoiceApplicationService.getById(id);
        if (!byId.getExamineStatus().equals("SAVE") && !byId.getExamineStatus().equals(ExamineStatusEnum.FAIL.toString())) {
            throw new RemoteServiceException("该申请单不为保存状态，不可删除");
        }
        List<InvoiceApplicationOrder> list = invoiceApplicationOrderService.lambdaQuery().eq(InvoiceApplicationOrder::getInvoiceId, id).list();
        for (InvoiceApplicationOrder invoiceApplicationOrder : list) {
            //减少经销商暂扣库存
            stockCommonLogic.reduceStockCustomerSuspended(invoiceApplicationOrder.getMaterialId(), byId.getCustomerId(), invoiceApplicationOrder.getRefundableQty());
        }
        invoiceApplicationService.removeById(id);
        invoiceApplicationOrderService.lambdaUpdate().eq(InvoiceApplicationOrder::getInvoiceId, id).remove();
    }


    @Transactional(rollbackFor = Exception.class)
    public void giveUp(String id) throws InterruptedException {

        InvoiceApplication invoiceApplication = invoiceApplicationService.getById(id);
        if (!invoiceApplication.getExamineStatus().equals(ExamineStatusEnum.OK.toString()))
            throw new RemoteServiceException("当前单非审核状态");


        //2返还数量到销售出库单
        List<InvoiceApplicationOrder> list = invoiceApplicationOrderService.lambdaQuery().eq(InvoiceApplicationOrder::getInvoiceId, invoiceApplication.getId()).list();
        for (InvoiceApplicationOrder order : list) {
            SalesOrderItem salesOrderItem = salesOrderItemService.getById(order.getSalesOrderItemId());
            SalesOrder salesOrder = salesOrderService.getById(salesOrderItem.getSalesOrderNo());
            if (salesOrder.getExamineStatus().equals(ExamineStatusEnum.OK.toString()))
                throw new RemoteServiceException("当前销售订单已通过无法弃审");

            InvoiceApplicationOrder invoiceApplicationOrder = invoiceApplicationOrderService.getById(salesOrderItem.getInvoiceItemId());
            invoiceApplicationOrder.setRetiredQty(invoiceApplicationOrder.getRetiredQty() - order.getRetiredQty());
            invoiceApplicationOrder.updateById();

            salesOrderItem.setRefundableQty(salesOrderItem.getRefundableQty() - order.getRefundableQty());
            salesOrderItem.setPayAmount(salesOrderItem.getSinglePayPrice()
                    .multiply(new BigDecimal(Convert.toStr(salesOrderItem.getRefundableQty()))));

            salesOrderItem.setTotalAmount(salesOrderItem.getPrice().multiply(new BigDecimal(Convert.toStr(salesOrderItem.getRefundableQty()))));

            salesOrderItem.setPayRebateAmount(salesOrderItem.getSingleRebateAmount().multiply(new BigDecimal(Convert.toStr(salesOrderItem.getRefundableQty()))));

            salesOrderItem.setTotalDiscAmount(salesOrderItem.getDiscAmount().multiply(new BigDecimal(Convert.toStr(salesOrderItem.getRefundableQty()))));

            salesOrderItem.setAfterTaxPrice(salesOrderItem.getSinglePayPrice().subtract(salesOrderItem.getSinglePayPrice().multiply(salesOrderItem.getTax())));
            salesOrderItem.setNoTotalAmount(salesOrderItem.getPayAmount().subtract(salesOrderItem.getPayAmount().multiply(salesOrderItem.getTax())));
            salesOrderItem.updateById();

            invoiceApplicationOrder.setVarietyQty(invoiceApplicationOrder.getVarietyQty() - order.getRefundableQty());
            invoiceApplicationOrder.setRetiredQty(invoiceApplicationOrder.getRetiredQty() - order.getRefundableQty());
            invoiceApplicationOrder.updateById();

            //记录台账记录
            String customerWalletId = null;
            if (order.getOrderType().equals("RETAIL") || order.getOrderType().equals("RETAIL_POLICY")) {
                RetailOrderItem retailOrderItem = retailOrderItemService.getById(order.getOrderId());
                retailOrderItem.setRefundProductQty(retailOrderItem.getRefundProductQty()-(order.getRefundableQty()));
                BigDecimal tdQty = BigDecimal.valueOf(order.getRefundableQty());
                retailOrderItem.setRefundProductAmount(retailOrderItem.getRefundProductAmount().subtract(retailOrderItem.getSinglePayPrice().multiply(tdQty)));
                retailOrderItem.updateById();
                customerWalletId = retailOrderItem.getCustomerWalletId();
            }

            if (order.getOrderType().equals("TRADE") || order.getOrderType().equals("HOME")) {
                EnginOrderItem enginOrderItem = enginOrderItemService.getById(order.getOrderId());
                enginOrderItem.setRefundProductQty(enginOrderItem.getRefundProductQty()-(order.getRefundableQty()));
                BigDecimal tdQty = BigDecimal.valueOf(order.getRefundableQty());
                enginOrderItem.setRefundProductAmount(enginOrderItem.getRefundProductAmount().subtract(enginOrderItem.getSinglePayPrice().multiply(tdQty)));
                enginOrderItem.updateById();
                customerWalletId = enginOrderItem.getCustomerWalletId();
            }


            CustomerWallet customerWallet = customerWalletService.getById(customerWalletId);


            walletLogic.saveCustomerWalletRecord(customerWallet, order.getPayAmount().multiply(new BigDecimal("-1")), "反审退货单流水", "反审退货单", new Date(),
                    invoiceApplication.getId(), 3, "OUT");

            //1，零售订单退单
            if (order.getOrderType().equals("RETAIL") || order.getOrderType().equals("RETAIL_POLICY"))
                subRefund(salesOrder, salesOrderItem, order.getOrderId(), -1 * order.getRefundableQty(), order.getOrderType());

            //2，工程订单退单
            if (order.getOrderType().equals("TRADE") || order.getOrderType().equals("HOME"))
                subEngin(salesOrder, salesOrderItem, order.getOrderId(), -1 * order.getRefundableQty(), order.getOrderType());


            //更新销售出库单


        }

        if (invoiceApplication.getGejiangSync() != null && invoiceApplication.getGejiangSync().equals(1)){
            geJiangInStockLogic.unAuditByTuiLiaoBillNo(id);
        }

        //3订单改为提审状态
        invoiceApplication.setExamineStatus(ExamineStatusEnum.WAIT.toString());
        invoiceApplication.updateById();
        shipDocumentService.removeById(invoiceApplication.getId());
        invoiceMapper.updateStatus(invoiceApplication.getId());
        invoiceMapper.updateTaiZhang(invoiceApplication.getId());
        invoiceMapper.updateInvoice(invoiceApplication.getId());

        orderRefundTrial(invoiceApplication.getId());
    }

    private void orderRefundTrial(String id) {
        InvoiceApplication invoiceApplication = invoiceApplicationService.getById(id);
        if (invoiceApplication.getExamineStatus().equals(ExamineStatusEnum.OK.getKey()))
            return;

        List<InvoiceApplicationOrder> list = invoiceApplicationOrderService.lambdaQuery().eq(InvoiceApplicationOrder::getInvoiceId, invoiceApplication.getId()).list();

        List<OrderExecRecord> orderExecRecords = new ArrayList<>();

        for (InvoiceApplicationOrder invoiceApplicationOrder : list) {

            String orderId = StringUtils.isEmpty(invoiceApplication.getEnginOrderNo())
                    ?invoiceApplicationOrder.getMainOrderId():invoiceApplication.getEnginOrderNo();
            RetailOrder retailOrder = retailOrderService.getById(orderId);
            RetailOrderItem retailOrderItem = retailOrderItemService.getById(invoiceApplicationOrder.getOrderId());
            EnginOrder enginOrder = enginOrderService.getById(invoiceApplicationOrder.getMainOrderId());
            EnginOrderItem enginOrderItem = enginOrderItemService.getById(invoiceApplicationOrder.getOrderId());
            OrderExecRecord orderExecRecord = new OrderExecRecord();

            orderExecRecord.setOrderCreateTime(enginOrder != null ? enginOrder.getOrderDate() : retailOrder.getCreateTime());

            orderExecRecord.setRefOrderId(orderId+"T");
            orderExecRecord.setRefEnginRecordNo(enginOrder != null ?enginOrder.getRefEnginRecordNo():null);
            orderExecRecord.setRefOrderItemId(invoiceApplicationOrder.getOrderId());
            orderExecRecord.setAdminUserId(enginOrder != null?enginOrder.getAdminUserId():retailOrder.getAdminUserId());
            orderExecRecord.setAdminWebsitId(enginOrder != null?enginOrder.getAdminWebsitId():retailOrder.getAdminWebsitId());
            orderExecRecord.setOrderType(invoiceApplicationOrder.getOrderType());
            orderExecRecord.setSaleTypeCode(invoiceApplicationOrder.getSaleTypeCode());
            orderExecRecord.setSaleTypeId(invoiceApplicationOrder.getSaleTypeId());
            orderExecRecord.setSaleTypeName(invoiceApplicationOrder.getSaleTypeName());
            orderExecRecord.setMaterialId(invoiceApplicationOrder.getMaterialId());
            orderExecRecord.setMaterialCode(invoiceApplicationOrder.getMaterialCode());
            orderExecRecord.setMaterialName(invoiceApplicationOrder.getMaterialName());
            orderExecRecord.setMaterialOldNumber(invoiceApplicationOrder.getMaterialOldNumber());
            orderExecRecord.setK3CategoryId(invoiceApplicationOrder.getK3CategoryId());
            orderExecRecord.setK3CategoryName(invoiceApplicationOrder.getK3CategoryName());
            orderExecRecord.setK3CategoryNumber(invoiceApplicationOrder.getK3CategoryNumber());
            orderExecRecord.setServiceId(invoiceApplicationOrder.getServiceId());
            orderExecRecord.setServiceName(invoiceApplicationOrder.getServiceName());
            orderExecRecord.setSpecification(invoiceApplicationOrder.getSpecification());
            orderExecRecord.setUnit(invoiceApplicationOrder.getUnit());
            orderExecRecord.setPrice(enginOrder != null?enginOrderItem.getPrice():retailOrderItem.getPrice());
            orderExecRecord.setTotalAmount(invoiceApplicationOrder.getTotalAmount().multiply(Convert.toBigDecimal("-1")));
            orderExecRecord.setDiscAmount(enginOrder != null?enginOrderItem.getDiscAmount():retailOrderItem.getDiscAmount());
            orderExecRecord.setTotalDiscAmount(invoiceApplicationOrder.getTotalDiscAmount().multiply(Convert.toBigDecimal("-1")));
            orderExecRecord.setPayAmount(invoiceApplicationOrder.getPayAmount().multiply(Convert.toBigDecimal("-1")));
            orderExecRecord.setPayRebateAmount(invoiceApplicationOrder.getPayRebateAmount().multiply(Convert.toBigDecimal("-1")));
            orderExecRecord.setOrderOperationType(OrderOperationTypeEnum.INVOICE_REFUND.getKey());
            orderExecRecord.setDirection(1);
            orderExecRecord.setQty(-1*invoiceApplicationOrder.getRefundableQty());
            orderExecRecord.setCustomerWalletId(invoiceApplicationOrder.getCustomerWalletId());
            orderExecRecord.setCustomerWalletName(invoiceApplicationOrder.getCustomerWalletName());
            orderExecRecord.setCustomerWalletId2(invoiceApplicationOrder.getCustomerWalletId2());
            orderExecRecord.setCustomerWalletName2(invoiceApplicationOrder.getCustomerWalletName2());
            orderExecRecord.setK3ServiceId(invoiceApplicationOrder.getK3ServiceId());
            orderExecRecord.setK3ServiceName(invoiceApplicationOrder.getK3ServiceName());
            orderExecRecord.setTheTime(invoiceApplication.getOrderTime());
            orderExecRecord.setPolicyId(invoiceApplicationOrder.getPolicyId());
            orderExecRecord.setPolicyCode(invoiceApplicationOrder.getPolicyCode());
            orderExecRecord.setPolicyTitle(invoiceApplicationOrder.getPolicyTitle());
            orderExecRecord.setCustomerId(invoiceApplication.getCustomerId());
            orderExecRecord.setCustomerNumber(invoiceApplication.getCustomerNumber());
            orderExecRecord.setCustomerName(invoiceApplication.getCustomerName());
            orderExecRecord.setOldQty(enginOrder != null?enginOrderItem.getOldQty():retailOrderItem.getOldQty());
            orderExecRecord.setOldPayAmount(enginOrder != null?enginOrderItem.getOldPayAmount():retailOrderItem.getOldPayAmount());
            orderExecRecord.setOrgPrice(enginOrder != null?null:retailOrderItem.getOrgPrice());
            orderExecRecord.setRefType("反审退货单");
            orderExecRecord.setAdminCompanyId(enginOrder != null ?enginOrder.getAdminCompanyId():retailOrder.getAdminCompanyId());
            orderExecRecords.add(orderExecRecord);
        }
        orderExecRecordService.saveBatch(orderExecRecords);
    }

    public void subEngin(SalesOrder salesOrder, SalesOrderItem order, String orderId, Integer tdQtyRefund, String orderType) throws InterruptedException {
        String enginName = orderType.equals(OrderTypeEnum.HOME.getKey()) ? "家用" : "商用";
        EnginOrderItem enginOrderItem = enginOrderItemService.getById(orderId);


        if (tdQtyRefund == null || tdQtyRefund == 0) {
            return;
        }

        BigDecimal tdQty = BigDecimal.valueOf(tdQtyRefund);
        //需要退的钱
        BigDecimal refundPayAmount = enginOrderItem.getSinglePayPrice().multiply(tdQty);
        //需要退的返利金额
        BigDecimal refundRebateAmount = enginOrderItem.getSingleRebateAmount().multiply(tdQty);
        //返利单退款
        List<CustomerWalletAmountBean> customerWalletAmountBeans = new ArrayList<>();
        if (refundRebateAmount.doubleValue() > 0) {
            customerWalletAmountBeans.add(new CustomerWalletAmountBean(enginOrderItem.getCustomerWalletId2(), refundRebateAmount, enginOrderItem.getRemark(),
                    enginName + "工程销售负数申请发货单返利退款-反审申请退货单", salesOrder.getOrderTime(), order.getMainOrderId()+"&"+salesOrder.getOrderNo(), 2, "sub"));

        }
        // 现金退款
        if (refundPayAmount.doubleValue() > 0) {
            customerWalletAmountBeans.add(new CustomerWalletAmountBean(enginOrderItem.getCustomerWalletId(), refundPayAmount, enginOrderItem.getRemark(),
                    enginName + "工程发货负数申请发货单订单退款-反审申请退货单", salesOrder.getOrderTime(), salesOrder.getEnginOrderNo()+"&"+salesOrder.getOrderNo(), 2, "sub"));
        }
        walletLogic.doWalletAmount(customerWalletAmountBeans);


        List<DepositManageRecordBean> depositManageRecordList = new ArrayList<>();

        //工程退押金
        EnginOrderItem orderItem = enginOrderItemService.getById(orderId);
        EnginOrder enginOrder = enginOrderService.getById(orderItem.getParentId());

        if (order.getOrderType().equals("HOME") || order.getOrderType().equals("PERMU_HOME")) {
            DepositManageRecordBean depositManageRecordBean = new DepositManageRecordBean();
            depositManageRecordBean.handleEnginOrderItem(enginOrder, orderItem, tdQtyRefund, orderItem.getSingleDepositAmount().multiply(tdQty));
            depositManageRecordList.add(depositManageRecordBean);
        }

        if (CollectionUtil.isNotEmpty(depositManageRecordList))
        depositManageLogic.addDepositAmount(enginOrder.getRefEnginRecordNo(), depositManageRecordList);

        if (order.getOrderType().equals("HOME") || order.getOrderType().equals("PERMU_HOME")) {
            depositManageLogic.computeOrderSalesQtyData(enginOrder.getRefEnginRecordNo(),orderItem.getMaterialId(),orderItem.getRealMaterialId(),orderItem.getPrice());
        }
    }

    public void subRefund(SalesOrder salesOrder, SalesOrderItem order, String orderId, Integer tdQtyRefund, String orderType) throws InterruptedException {
        RetailOrderItem retailOrderItem = retailOrderItemService.getById(orderId);


        if (retailOrderItem == null || tdQtyRefund == 0) {
            return;
        }

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


        //返利单退款
        List<CustomerWalletAmountBean> customerWalletAmountBeans = new ArrayList<>();
        if (refundRebateAmount.doubleValue() > 0) {
            customerWalletAmountBeans.add(new CustomerWalletAmountBean(retailOrderItem.getCustomerWalletId2(), refundRebateAmount, retailOrderItem.getRemark(),
                    "负数申请发货单返利退款-反审申请退货单", salesOrder.getOrderTime(), order.getMainOrderId()+"("+salesOrder.getOrderNo()+")", 2, "sub"));

        }
        // 现金退款
        if (refundPayAmount.doubleValue() > 0) {
            customerWalletAmountBeans.add(new CustomerWalletAmountBean(retailOrderItem.getCustomerWalletId(), refundPayAmount, retailOrderItem.getRemark(),
                    "负数申请发货单退款-反审申请退货单", salesOrder.getOrderTime(), order.getMainOrderId()+"("+salesOrder.getOrderNo()+")", 2, "sub"));
        }

        walletLogic.doWalletAmount(customerWalletAmountBeans);

    }

    public void subDisplace(SalesOrder salesOrder, SalesOrderItem order, String orderId, Integer tdQtyRefund, String orderType) throws InterruptedException {
        DisplaceOrderItem displaceOrderItem = displaceOrderItemService.getById(orderId);


        if (tdQtyRefund == null || tdQtyRefund == 0) {
            return;
        }

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


        //返利单退款
        List<CustomerWalletAmountBean> customerWalletAmountBeans = new ArrayList<>();
        if (refundRebateAmount.doubleValue() > 0) {
            customerWalletAmountBeans.add(new CustomerWalletAmountBean(displaceOrderItem.getCustomerWalletId2(), refundRebateAmount, displaceOrderItem.getRemark(),
                    "置换单负数申请发货单返利退款-反审申请退货单", salesOrder.getOrderTime(), order.getMainOrderId()+"("+salesOrder.getOrderNo()+")", 2, "sub"));

        }
        // 现金退款
        if (refundPayAmount.doubleValue() > 0) {
            customerWalletAmountBeans.add(new CustomerWalletAmountBean(displaceOrderItem.getCustomerWalletId(), refundPayAmount, displaceOrderItem.getRemark(),
                    "置换单负数申请发货单订单退款-反审申请退货单", salesOrder.getOrderTime(), order.getMainOrderId()+"("+salesOrder.getOrderNo()+")", 2, "sub"));
        }

        walletLogic.doWalletAmount(customerWalletAmountBeans);
    }

    public void subRequistion(SalesOrder salesOrder, SalesOrderItem order, String orderId, Integer tdQtyRefund, String orderType) throws InterruptedException {
        RequisitionOrderItem requisitionOrderItem = requisitionOrderItemService.getById(orderId);


        if (requisitionOrderItem == null || tdQtyRefund == 0) {
            return;
        }

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


        //返利单退款
        List<CustomerWalletAmountBean> customerWalletAmountBeans = new ArrayList<>();
        if (refundRebateAmount.doubleValue() > 0) {
            customerWalletAmountBeans.add(new CustomerWalletAmountBean(requisitionOrderItem.getCustomerWalletId2(), refundRebateAmount, requisitionOrderItem.getRemark(),
                    "直接调拨单负数申请发货单返利退款-反审申请退货单", salesOrder.getOrderTime(), orderId, 2, "sub"));

        }
        // 现金退款
        if (refundPayAmount.doubleValue() > 0) {
            customerWalletAmountBeans.add(new CustomerWalletAmountBean(requisitionOrderItem.getCustomerWalletId(), refundPayAmount, requisitionOrderItem.getRemark(),
                    "直接调拨单负数申请发货单退款-反审申请退货单", salesOrder.getOrderTime(), orderId, 2, "sub"));
        }

        walletLogic.doWalletAmount(customerWalletAmountBeans);
    }


    @Transactional(rollbackFor = Exception.class)
    public void submit(String id, String examineStatus, HttpServletRequest request) {
        InvoiceApplication byId = invoiceApplicationService.getById(id);
        if (!byId.getExamineStatus().equals(ExamineStatusEnum.SAVE.toString()) && !byId.getExamineStatus().equals(ExamineStatusEnum.WAIT.toString())) {
            throw new RemoteServiceException("该申请单不为保存或提审状态");
        }
        List<InvoiceApplicationOrder> list = invoiceApplicationOrderService.lambdaQuery().eq(InvoiceApplicationOrder::getInvoiceId, byId.getId()).list();

        InvoiceApplication invoiceApplication = new InvoiceApplication();
        invoiceApplication.setId(id);
        invoiceApplication.setExamineStatus(examineStatus);
        invoiceApplicationService.updateById(invoiceApplication);
        invoiceMapper.updateStatus(invoiceApplication.getId());
        invoiceMapper.updateInvoice(invoiceApplication.getId());
    }

    @Transactional(rollbackFor = Exception.class)
    public void approvalInvoice(InvoiceRequestJson invoiceRequestJson, HttpServletRequest request) throws Exception {
        //保存申请发货单
        InvoiceApplication invoiceApplication = invoiceApplicationService.getById(invoiceRequestJson.getId());
        if (!invoiceApplication.getExamineStatus().equals(ExamineStatusEnum.WAIT.toString())) {
            throw new RemoteServiceException("非审核单，无法审核");
        }


        AdminUserCom adminUser = commonLogic.getAdminUser(request);

        invoiceRequestJson.setApprovalName(adminUser.getNickName());
        invoiceRequestJson.setApprovalTime(new Date());
        invoiceRequestJson.setSalesOrderId(invoiceApplication.getSalesId());
        invoiceApplicationService.updateById(invoiceRequestJson);

        for (InvoiceApplicationOrderRequest order : invoiceRequestJson.getOrders()) {

            InvoiceApplicationOrder invoiceApplicationOrder = invoiceApplicationOrderService.getById(order.getId());

            SalesOrderItem salesOrderItem = salesOrderItemService.getById(invoiceApplicationOrder.getSalesOrderItemId());
            SalesOrder salesOrder = salesOrderService.getById(salesOrderItem.getSalesOrderNo());
            if (salesOrder.getExamineStatus().equals(ExamineStatusEnum.OK.toString()))
                throw new RemoteServiceException("当前销售出库单已通过无法通过");

            if (pickManagerShipService.lambdaQuery().eq(PickManagerShip::getInvoiceOrderId,invoiceApplicationOrder.getId()).count() > 0)
                throw new RemoteServiceException("当前发货单提货预约了，无法审核通过冲单，请和商家商量是否提货！不提货取消预约，提货取消冲单");


            order.setApprovalNumber(invoiceApplicationOrder.getInvoiceNum());
            order.setRefundableQty(order.getApprovalNumber());

            order.setPayAmount(invoiceApplicationOrder.getSinglePayPrice()
                    .multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));

            order.setTotalAmount(invoiceApplicationOrder.getPrice().multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));

            order.setPayRebateAmount(invoiceApplicationOrder.getSingleRebateAmount().multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));

            order.setTotalDiscAmount(invoiceApplicationOrder.getDiscAmount().multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));

            order.setAfterTaxPrice(invoiceApplicationOrder.getSinglePayPrice().subtract(invoiceApplicationOrder.getSinglePayPrice().multiply(invoiceApplicationOrder.getTax())));
            order.setNoTotalAmount(order.getPayAmount().subtract(order.getPayAmount().multiply(invoiceApplicationOrder.getTax())));
            invoiceApplicationOrderService.updateById(order);
        }
        if (invoiceRequestJson.getExamineStatus().equals("SAVE"))
            return;

        //生成发货单
        ShipDocument shipDocument = BeanUtil.toBean(invoiceApplication, ShipDocument.class);
        shipDocument.setExamineStatus(ExamineStatusEnum.OK.toString());
        shipDocument.insert();

        for (InvoiceApplicationOrderRequest order : invoiceRequestJson.getOrders()) {

            //更新销售出库单
            SalesOrderItem salesOrderItem = salesOrderItemService.getById(order.getSalesOrderItemId());
            InvoiceApplicationOrder invoiceApplicationOrder = invoiceApplicationOrderService.getById(salesOrderItem.getInvoiceItemId());
            invoiceApplicationOrder.setRetiredQty(invoiceApplicationOrder.getRetiredQty() + order.getRefundableQty());
            invoiceApplicationOrder.setVarietyQty(invoiceApplicationOrder.getVarietyQty() + order.getRefundableQty());
            invoiceApplicationOrder.updateById();

            if (salesOrderItem.getRefundableQty() < (-1 * order.getRefundableQty()))
                throw new RemoteServiceException("销售出库单数量小于你的退货数量");
            salesOrderItem.setRefundableQty(salesOrderItem.getRefundableQty() + order.getRefundableQty());
            salesOrderItem.setPayAmount(salesOrderItem.getSinglePayPrice()
                    .multiply(new BigDecimal(Convert.toStr(salesOrderItem.getRefundableQty()))));

            salesOrderItem.setTotalAmount(salesOrderItem.getPrice().multiply(new BigDecimal(Convert.toStr(salesOrderItem.getRefundableQty()))));

            salesOrderItem.setPayRebateAmount(salesOrderItem.getSingleRebateAmount().multiply(new BigDecimal(Convert.toStr(salesOrderItem.getRefundableQty()))));

            salesOrderItem.setTotalDiscAmount(salesOrderItem.getDiscAmount().multiply(new BigDecimal(Convert.toStr(salesOrderItem.getRefundableQty()))));

            salesOrderItem.setAfterTaxPrice(salesOrderItem.getSinglePayPrice().subtract(salesOrderItem.getSinglePayPrice().multiply(salesOrderItem.getTax())));
            salesOrderItem.setNoTotalAmount(salesOrderItem.getPayAmount().subtract(salesOrderItem.getPayAmount().multiply(salesOrderItem.getTax())));
            salesOrderItem.updateById();

            //增加经销商暂扣库存
            if (order.getRefundableQty() - order.getInvoiceNum() >= 0) {
                stockCommonLogic.reduceStockCustomerSuspended(order.getMaterialId(), invoiceApplication.getCustomerId(), order.getRefundableQty());
            }



            //记录台账记录
            String customerWalletId = null;

            Lock obtain = redisLockRegistry.obtain(Constant.RedisPrefix.INVOICE_APPLICATION+order.getOrderId());
            try {
                if (!obtain.tryLock(5, TimeUnit.SECONDS)) {
                    throw new RemoteServiceException("系统繁忙，请稍后再试");
                }


                if (order.getOrderType().equals("RETAIL") || order.getOrderType().equals("RETAIL_POLICY")) {
                RetailOrderItem retailOrderItem = retailOrderItemService.getById(order.getOrderId());
                retailOrderItem.setRefundProductQty(retailOrderItem.getRefundProductQty()+(order.getRefundableQty()));
                BigDecimal tdQty = BigDecimal.valueOf(order.getRefundableQty());
                retailOrderItem.setRefundProductAmount(retailOrderItem.getRefundProductAmount().add(retailOrderItem.getSinglePayPrice().multiply(tdQty)));
                retailOrderItem.updateById();
                customerWalletId = retailOrderItem.getCustomerWalletId();
            }

            if (order.getOrderType().equals("TRADE") || order.getOrderType().equals("HOME")) {
                EnginOrderItem enginOrderItem = enginOrderItemService.getById(order.getOrderId());
                enginOrderItem.setRefundProductQty(enginOrderItem.getRefundProductQty()+(order.getRefundableQty()));
                BigDecimal tdQty = BigDecimal.valueOf(order.getRefundableQty());
                enginOrderItem.setRefundProductAmount(enginOrderItem.getRefundProductAmount().add(enginOrderItem.getSinglePayPrice().multiply(tdQty)));
                enginOrderItem.updateById();
                customerWalletId = enginOrderItem.getCustomerWalletId();
            }
            } finally {
                obtain.unlock();
            }


            CustomerWallet customerWallet = customerWalletService.getById(customerWalletId);

            walletLogic.saveCustomerWalletRecord(customerWallet, order.getPayAmount().multiply(new BigDecimal("-1")), "退货单流水",
                    "退货单", new Date(), invoiceRequestJson.getId(), 3, "IN");


            //1，零售订单退单
            if (order.getOrderType().equals("RETAIL") || order.getOrderType().equals("RETAIL_POLICY")) {
                retailOrderLogic.refund(order.getMainOrderId()+"&"+order.getInvoiceId(), order.getOrderId(), -1 * order.getRefundableQty(), "退货单退单");
            }

            //2，工程订单退单
            if (order.getOrderType().equals("TRADE") || order.getOrderType().equals("HOME"))
                refundEngin(invoiceApplication, invoiceApplicationOrder, order.getOrderId(), -1 * order.getRefundableQty(), order.getOrderType());


        }
        invoiceMapper.updateStatus(invoiceApplication.getId());
        invoiceMapper.updateTaiZhang(invoiceApplication.getId());
        invoiceMapper.updateInvoice(invoiceApplication.getId());

        //格匠同步采购入库单
        if (invoiceApplication.getCustomerNumber().equals(InvoiceCustomerEnum.GEJIANG_FOSHAN.getCode()) ||
                invoiceApplication.getCustomerNumber().equals(InvoiceCustomerEnum.GEJIANG_GUANGZHOU.getCode())){
            InvoiceApplication invoiceApplication1 = new InvoiceApplication();
            invoiceApplication1.setId(invoiceApplication.getId());
            invoiceApplication1.setGejiangSync(0);
            invoiceApplication1.updateById();
            InvoiceApplicationSyncGejiang invoiceApplicationSyncGejiang = new InvoiceApplicationSyncGejiang();
            invoiceApplicationSyncGejiang.setInvoiceId(invoiceApplication.getId());
            invoiceApplicationSyncGejiang.setStatus(0);
            invoiceApplicationSyncGejiang.setType(2);
            invoiceApplicationSyncGejiang.insert();
        }

        orderRefundInsert(invoiceApplication.getId());
    }

    private void orderRefundInsert(String id) {
        InvoiceApplication invoiceApplication = invoiceApplicationService.getById(id);
        if (!invoiceApplication.getExamineStatus().equals(ExamineStatusEnum.OK.getKey()))
            return;

        List<InvoiceApplicationOrder> list = invoiceApplicationOrderService.lambdaQuery().eq(InvoiceApplicationOrder::getInvoiceId, invoiceApplication.getId()).list();

        List<OrderExecRecord> orderExecRecords = new ArrayList<>();

        for (InvoiceApplicationOrder invoiceApplicationOrder : list) {

            String orderId = StringUtils.isEmpty(invoiceApplication.getEnginOrderNo())
                            ?invoiceApplicationOrder.getMainOrderId():invoiceApplication.getEnginOrderNo();
            RetailOrder retailOrder = retailOrderService.getById(orderId);
            RetailOrderItem retailOrderItem = retailOrderItemService.getById(invoiceApplicationOrder.getOrderId());
            EnginOrder enginOrder = enginOrderService.getById(invoiceApplicationOrder.getMainOrderId());
            EnginOrderItem enginOrderItem = enginOrderItemService.getById(invoiceApplicationOrder.getOrderId());
            OrderExecRecord orderExecRecord = new OrderExecRecord();
            orderExecRecord.setRefOrderId(orderId+"T");
            orderExecRecord.setRefEnginRecordNo(enginOrder != null ?enginOrder.getRefEnginRecordNo():null);
            orderExecRecord.setRefOrderItemId(invoiceApplicationOrder.getOrderId());
            orderExecRecord.setAdminUserId(enginOrder != null?enginOrder.getAdminUserId():retailOrder.getAdminUserId());
            orderExecRecord.setAdminWebsitId(enginOrder != null?enginOrder.getAdminWebsitId():retailOrder.getAdminWebsitId());

            orderExecRecord.setTheTime(new Date());
            orderExecRecord.setOrderCreateTime(enginOrder != null ? enginOrder.getOrderDate() : retailOrder.getCreateTime());

            orderExecRecord.setOrderType(invoiceApplicationOrder.getOrderType());
            orderExecRecord.setSaleTypeCode(invoiceApplicationOrder.getSaleTypeCode());
            orderExecRecord.setSaleTypeId(invoiceApplicationOrder.getSaleTypeId());
            orderExecRecord.setSaleTypeName(invoiceApplicationOrder.getSaleTypeName());
            orderExecRecord.setMaterialId(invoiceApplicationOrder.getMaterialId());
            orderExecRecord.setMaterialCode(invoiceApplicationOrder.getMaterialCode());
            orderExecRecord.setMaterialName(invoiceApplicationOrder.getMaterialName());
            orderExecRecord.setMaterialOldNumber(invoiceApplicationOrder.getMaterialOldNumber());
            orderExecRecord.setK3CategoryId(invoiceApplicationOrder.getK3CategoryId());
            orderExecRecord.setK3CategoryName(invoiceApplicationOrder.getK3CategoryName());
            orderExecRecord.setK3CategoryNumber(invoiceApplicationOrder.getK3CategoryNumber());
            orderExecRecord.setServiceId(invoiceApplicationOrder.getServiceId());
            orderExecRecord.setServiceName(invoiceApplicationOrder.getServiceName());
            orderExecRecord.setSpecification(invoiceApplicationOrder.getSpecification());
            orderExecRecord.setUnit(invoiceApplicationOrder.getUnit());
            orderExecRecord.setPrice(enginOrder != null?enginOrderItem.getPrice():retailOrderItem.getPrice());
            orderExecRecord.setTotalAmount(invoiceApplicationOrder.getTotalAmount().multiply(Convert.toBigDecimal("-1")));
            orderExecRecord.setDiscAmount(enginOrder != null?enginOrderItem.getDiscAmount():retailOrderItem.getDiscAmount());
            orderExecRecord.setTotalDiscAmount(invoiceApplicationOrder.getTotalDiscAmount().multiply(Convert.toBigDecimal("-1")));
            orderExecRecord.setPayAmount(invoiceApplicationOrder.getPayAmount().multiply(Convert.toBigDecimal("-1")));
            orderExecRecord.setPayRebateAmount(invoiceApplicationOrder.getPayRebateAmount().multiply(Convert.toBigDecimal("-1")));
            orderExecRecord.setOrderOperationType(OrderOperationTypeEnum.INVOICE_REFUND.getKey());
            orderExecRecord.setDirection(-1);
            orderExecRecord.setQty(-1*invoiceApplicationOrder.getRefundableQty());
            orderExecRecord.setCustomerWalletId(invoiceApplicationOrder.getCustomerWalletId());
            orderExecRecord.setCustomerWalletName(invoiceApplicationOrder.getCustomerWalletName());
            orderExecRecord.setCustomerWalletId2(invoiceApplicationOrder.getCustomerWalletId2());
            orderExecRecord.setCustomerWalletName2(invoiceApplicationOrder.getCustomerWalletName2());
            orderExecRecord.setK3ServiceId(invoiceApplicationOrder.getK3ServiceId());
            orderExecRecord.setK3ServiceName(invoiceApplicationOrder.getK3ServiceName());
            orderExecRecord.setTheTime(invoiceApplication.getOrderTime());
            orderExecRecord.setPolicyId(invoiceApplicationOrder.getPolicyId());
            orderExecRecord.setPolicyCode(invoiceApplicationOrder.getPolicyCode());
            orderExecRecord.setPolicyTitle(invoiceApplicationOrder.getPolicyTitle());
            orderExecRecord.setCustomerId(invoiceApplication.getCustomerId());
            orderExecRecord.setCustomerNumber(invoiceApplication.getCustomerNumber());
            orderExecRecord.setCustomerName(invoiceApplication.getCustomerName());
            orderExecRecord.setOldQty(enginOrder != null?enginOrderItem.getOldQty():retailOrderItem.getOldQty());
            orderExecRecord.setOldPayAmount(enginOrder != null?enginOrderItem.getOldPayAmount():retailOrderItem.getOldPayAmount());
            orderExecRecord.setOrgPrice(enginOrder != null?null:retailOrderItem.getOrgPrice());
            orderExecRecord.setRefType("退货单");
            orderExecRecord.setAdminCompanyId(enginOrder != null ?enginOrder.getAdminCompanyId():retailOrder.getAdminCompanyId());
            orderExecRecords.add(orderExecRecord);
        }
        orderExecRecordService.saveBatch(orderExecRecords);
    }


    @Transactional(rollbackFor = Exception.class)
    public void approvalInvoice(InvoiceApplication invoiceApplicationRequest, HttpServletRequest request, String examineStatus, String approvalRemark) throws Exception {
        //保存申请发货单
        InvoiceApplication invoiceApplication = invoiceApplicationService.getById(invoiceApplicationRequest.getId());
        if (!invoiceApplication.getExamineStatus().equals(ExamineStatusEnum.WAIT.toString())) {
            throw new RemoteServiceException("非审核单，无法审核");
        }


        AdminUserCom adminUser = commonLogic.getAdminUser(request);

        invoiceApplicationRequest.setApprovalName(adminUser.getNickName());
        invoiceApplicationRequest.setApprovalTime(new Date());
        invoiceApplicationRequest.setExamineStatus(examineStatus);
        invoiceApplicationService.updateById(invoiceApplicationRequest);
        List<InvoiceApplicationOrder> list = invoiceApplicationOrderService.lambdaQuery().eq(InvoiceApplicationOrder::getInvoiceId, invoiceApplication.getId()).list();
        for (InvoiceApplicationOrder order : list) {
            order.setApprovalNumber(order.getRefundableQty());
            if (order.getApprovalNumber() == null)
                throw new RemoteServiceException("审批数量不能为空");
            InvoiceApplicationOrder invoiceApplicationOrder = invoiceApplicationOrderService.getById(order.getId());

            SalesOrderItem salesOrderItem = salesOrderItemService.getById(invoiceApplicationOrder.getSalesOrderItemId());
            SalesOrder salesOrder = salesOrderService.getById(salesOrderItem.getSalesOrderNo());
            if (salesOrder.getExamineStatus().equals(ExamineStatusEnum.OK.toString()))
                throw new RemoteServiceException("当前销售订单已通过无法退单");


            order.setRefundableQty(order.getApprovalNumber());

            order.setPayAmount(invoiceApplicationOrder.getSinglePayPrice()
                    .multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));

            order.setTotalAmount(invoiceApplicationOrder.getPrice().multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));

            order.setPayRebateAmount(invoiceApplicationOrder.getSingleRebateAmount().multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));

            order.setTotalDiscAmount(invoiceApplicationOrder.getDiscAmount().multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));

            order.setAfterTaxPrice(invoiceApplicationOrder.getSinglePayPrice().subtract(invoiceApplicationOrder.getSinglePayPrice().multiply(invoiceApplicationOrder.getTax())));
            order.setNoTotalAmount(order.getPayAmount().subtract(order.getPayAmount().multiply(invoiceApplicationOrder.getTax())));
            invoiceApplicationOrderService.updateById(order);
        }
        if (examineStatus.equals("SAVE"))
            return;

        //生成发货单
        ShipDocument shipDocument = BeanUtil.toBean(invoiceApplication, ShipDocument.class);
        shipDocument.setExamineStatus(ExamineStatusEnum.OK.toString());
        shipDocument.insert();

        for (InvoiceApplicationOrder order : list) {

            //更新销售出库单
            SalesOrderItem salesOrderItem = salesOrderItemService.getById(order.getSalesOrderItemId());
            InvoiceApplicationOrder invoiceApplicationOrder = invoiceApplicationOrderService.getById(salesOrderItem.getInvoiceItemId());
            invoiceApplicationOrder.setRetiredQty(invoiceApplicationOrder.getRetiredQty() + order.getRefundableQty());
            invoiceApplicationOrder.setVarietyQty(invoiceApplicationOrder.getVarietyQty() + order.getRefundableQty());
            invoiceApplicationOrder.updateById();

            if (salesOrderItem.getRefundableQty() < (-1 * order.getRefundableQty()))
                throw new RemoteServiceException("销售出库单数量小于你的退货数量");
            salesOrderItem.setRefundableQty(salesOrderItem.getRefundableQty() + order.getRefundableQty());
            salesOrderItem.setPayAmount(salesOrderItem.getSinglePayPrice()
                    .multiply(new BigDecimal(Convert.toStr(salesOrderItem.getRefundableQty()))));

            salesOrderItem.setTotalAmount(salesOrderItem.getPrice().multiply(new BigDecimal(Convert.toStr(salesOrderItem.getRefundableQty()))));

            salesOrderItem.setPayRebateAmount(salesOrderItem.getSingleRebateAmount().multiply(new BigDecimal(Convert.toStr(salesOrderItem.getRefundableQty()))));

            salesOrderItem.setTotalDiscAmount(salesOrderItem.getDiscAmount().multiply(new BigDecimal(Convert.toStr(salesOrderItem.getRefundableQty()))));

            salesOrderItem.setAfterTaxPrice(salesOrderItem.getSinglePayPrice().subtract(salesOrderItem.getSinglePayPrice().multiply(salesOrderItem.getTax())));
            salesOrderItem.setNoTotalAmount(salesOrderItem.getPayAmount().subtract(salesOrderItem.getPayAmount().multiply(salesOrderItem.getTax())));
            salesOrderItem.updateById();

            //增加经销商暂扣库存
            if (order.getRefundableQty() - order.getInvoiceNum() >= 0) {
                stockCommonLogic.reduceStockCustomerSuspended(order.getMaterialId(), invoiceApplication.getCustomerId(), order.getRefundableQty());
            }

            //记录台账记录
            String customerWalletId = null;
            if (order.getOrderType().equals("RETAIL") || order.getOrderType().equals("RETAIL_POLICY")) {
                RetailOrderItem retailOrderItem = retailOrderItemService.getById(order.getOrderId());
                retailOrderItem.setRefundProductQty(retailOrderItem.getRefundProductQty()+(order.getRefundableQty()));
                BigDecimal tdQty = BigDecimal.valueOf(order.getRefundableQty());
                retailOrderItem.setRefundProductAmount(retailOrderItem.getRefundProductAmount().add(retailOrderItem.getSinglePayPrice().multiply(tdQty)));
                retailOrderItem.updateById();
                customerWalletId = retailOrderItem.getCustomerWalletId();
            }

            if (order.getOrderType().equals("TRADE") || order.getOrderType().equals("HOME")) {
                EnginOrderItem enginOrderItem = enginOrderItemService.getById(order.getOrderId());
                enginOrderItem.setRefundProductQty(enginOrderItem.getRefundProductQty()+(order.getRefundableQty()));
                BigDecimal tdQty = BigDecimal.valueOf(order.getRefundableQty());
                enginOrderItem.setRefundProductAmount(enginOrderItem.getRefundProductAmount().add(enginOrderItem.getSinglePayPrice().multiply(tdQty)));
                enginOrderItem.updateById();
                customerWalletId = enginOrderItem.getCustomerWalletId();
            }

            if (order.getOrderType().equals("PERMU_HOME") || order.getOrderType().equals("PERMU_TRADE") || order.getOrderType().equals("PERMU_RETAIL") || order.getOrderType().equals("PERMU_RETAIL_POLICY")) {
                DisplaceOrderItem displaceOrderItem = displaceOrderItemService.getById(order.getOrderId());
                customerWalletId = displaceOrderItem.getCustomerWalletId();
            }

            if (order.getOrderType().equals("REQUISITION_HOME") || order.getOrderType().equals("REQUISITION_TRADE")) {
                RequisitionOrderItem requisitionOrderItem = requisitionOrderItemService.getById(order.getRequisitionItemId());
                EnginOrderItem enginOrderItem = enginOrderItemService.getById(order.getOrderId());
                enginOrderItem.setRefundProductQty(enginOrderItem.getRefundProductQty()+(order.getRefundableQty()));
                BigDecimal tdQty = BigDecimal.valueOf(order.getRefundableQty());
                enginOrderItem.setRefundProductAmount(enginOrderItem.getRefundProductAmount().add(enginOrderItem.getSinglePayPrice().multiply(tdQty)));
                enginOrderItem.updateById();
                customerWalletId = requisitionOrderItem.getCustomerWalletId();
            }
            if (order.getOrderType().equals("REQUISITION_RETAIL") || order.getOrderType().equals("REQUISITION_RETAIL_POLICY")) {
                RequisitionOrderItem requisitionOrderItem = requisitionOrderItemService.getById(order.getRequisitionItemId());
                RetailOrderItem retailOrderItem = retailOrderItemService.getById(requisitionOrderItem.getOrderId());
                retailOrderItem.setRefundProductQty(retailOrderItem.getRefundProductQty()+(order.getRefundableQty()));
                BigDecimal tdQty = BigDecimal.valueOf(order.getRefundableQty());
                retailOrderItem.setRefundProductAmount(retailOrderItem.getRefundProductAmount().add(retailOrderItem.getSinglePayPrice().multiply(tdQty)));
                retailOrderItem.updateById();
                customerWalletId = requisitionOrderItem.getCustomerWalletId();
            }


            CustomerWallet customerWallet = customerWalletService.getById(customerWalletId);

            //1，零售订单退单
            if (order.getOrderType().equals("RETAIL") || order.getOrderType().equals("RETAIL_POLICY")) {
                retailOrderLogic.refund(order.getId(), order.getOrderId(), -1 * order.getRefundableQty(), "退货单退单");
            }

            //2，工程订单退单
            if (order.getOrderType().equals("TRADE") || order.getOrderType().equals("HOME"))
                refundEngin(invoiceApplication, invoiceApplicationOrder, order.getOrderId(), -1 * order.getRefundableQty(), order.getOrderType());

            //3置换单退单
            if (order.getOrderType().equals("PERMU_HOME") || order.getOrderType().equals("PERMU_TRADE") || order.getOrderType().equals("PERMU_RETAIL") || order.getOrderType().equals("PERMU_RETAIL_POLICY"))
                refundDisplace(invoiceApplication, invoiceApplicationOrder, order.getOrderId(), -1 * order.getRefundableQty(), order.getOrderType());

            //3直接调拨单退单
            if (order.getOrderType().equals("REQUISITION_HOME") || order.getOrderType().equals("REQUISITION_TRADE") || order.getOrderType().equals("REQUISITION_RETAIL") || order.getOrderType().equals("REQUISITION_RETAIL_POLICY"))
                refundRequistion(invoiceApplication, invoiceApplicationOrder, order.getRequisitionItemId(), -1 * order.getRefundableQty(), order.getOrderType());


        }
        invoiceMapper.updateStatus(invoiceApplication.getId());
        invoiceMapper.updateInvoice(invoiceApplication.getId());
    }

    public void refundRequistion(InvoiceApplication retreatDocumentRequest, InvoiceApplicationOrder retreatDocumentOrder, String orderId, Integer tdQtyRefund, String orderType) throws InterruptedException {
        RequisitionOrderItem requisitionOrderItem = requisitionOrderItemService.getById(orderId);


        if (requisitionOrderItem == null || tdQtyRefund == 0) {
            return;
        }

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


        //返利单退款
        List<CustomerWalletAmountBean> customerWalletAmountBeans = new ArrayList<>();
        if (refundRebateAmount.doubleValue() > 0) {
            customerWalletAmountBeans.add(new CustomerWalletAmountBean(requisitionOrderItem.getCustomerWalletId2(), refundRebateAmount, requisitionOrderItem.getRemark(),
                    "直接调拨单申请发货订单返利退款-退货单", retreatDocumentRequest.getOrderTime(), orderId, 2, "add"));

        }
        // 现金退款
        if (refundPayAmount.doubleValue() > 0) {
            customerWalletAmountBeans.add(new CustomerWalletAmountBean(requisitionOrderItem.getCustomerWalletId(), refundPayAmount, requisitionOrderItem.getRemark(),
                    "直接调拨单申请发货订单退款-退货单", retreatDocumentRequest.getOrderTime(), orderId, 2, "add"));
        }

        walletLogic.doWalletAmount(customerWalletAmountBeans);

        List<DepositManageRecordBean> depositManageRecordList = new ArrayList<>();

        //工程退押金
        if (orderType.equals("REQUISITION_HOME")) {
            EnginOrderItem orderItem = enginOrderItemService.getById(requisitionOrderItem.getOrderId());
            EnginOrder enginOrder = enginOrderService.getById(orderItem.getParentId());

            if (enginOrder.getEnginOrderType().equals("HOME") || enginOrder.getEnginOrderType().equals("PERMU_HOME")) {
                DepositManageRecordBean depositManageRecordBean = new DepositManageRecordBean();
                depositManageRecordBean.handleEnginOrderItem(enginOrder, orderItem, tdQtyRefund, orderItem.getSingleDepositAmount().multiply(tdQty));
                depositManageRecordList.add(depositManageRecordBean);
            }
            if (CollectionUtil.isNotEmpty(depositManageRecordList))
                depositManageLogic.reduceDepositAmount(enginOrder.getRefEnginRecordNo(), depositManageRecordList);
        }
    }


    @Transactional(rollbackFor = Exception.class)
    public void refundEngin(InvoiceApplication retreatDocumentRequest, InvoiceApplicationOrder retreatDocumentOrder, String retailOrderItemId, Integer tdQtyRefund, String orderType) throws Exception {
        String enginName = orderType.equals(OrderTypeEnum.HOME.getKey()) ? "家用" : "商用";
        EnginOrderItem enginOrderItem = enginOrderItemService.getById(retailOrderItemId);


        if (tdQtyRefund == null || tdQtyRefund == 0) {
            return;
        }

        BigDecimal tdQty = BigDecimal.valueOf(tdQtyRefund);
        //需要退的钱
        BigDecimal refundPayAmount = enginOrderItem.getSinglePayPrice().multiply(tdQty);
        //需要退的返利金额
        BigDecimal refundRebateAmount = enginOrderItem.getSingleRebateAmount().multiply(tdQty);
        //返利单退款
        List<CustomerWalletAmountBean> customerWalletAmountBeans = new ArrayList<>();
        if (refundRebateAmount.doubleValue() > 0) {
            customerWalletAmountBeans.add(new CustomerWalletAmountBean(enginOrderItem.getCustomerWalletId2(), refundRebateAmount, enginOrderItem.getRemark(),
                    enginName + "工程申请发货订单返利退款-退货单", retreatDocumentRequest.getOrderTime(), retreatDocumentRequest.getEnginOrderNo()+"&"+retreatDocumentRequest.getId(), 2, "add"));

        }
        // 现金退款
        if (refundPayAmount.doubleValue() > 0) {
            customerWalletAmountBeans.add(new CustomerWalletAmountBean(enginOrderItem.getCustomerWalletId(), refundPayAmount, enginOrderItem.getRemark(),
                    enginName + "工程发货申请发货订单退款-退货单", retreatDocumentRequest.getOrderTime(), retreatDocumentRequest.getEnginOrderNo()+"&"+retreatDocumentRequest.getId(), 2, "add"));
        }
        walletLogic.doWalletAmount(customerWalletAmountBeans);


        List<DepositManageRecordBean> depositManageRecordList = new ArrayList<>();

        //工程退押金
        EnginOrderItem orderItem = enginOrderItemService.getById(retailOrderItemId);
        EnginOrder enginOrder = enginOrderService.getById(orderItem.getParentId());

        if (retreatDocumentOrder.getOrderType().equals("HOME") || retreatDocumentOrder.getOrderType().equals("PERMU_HOME")) {
            DepositManageRecordBean depositManageRecordBean = new DepositManageRecordBean();
            depositManageRecordBean.handleEnginOrderItem(enginOrder, orderItem, tdQtyRefund, orderItem.getSingleDepositAmount().multiply(tdQty));
            depositManageRecordList.add(depositManageRecordBean);
        }
        if (CollectionUtil.isNotEmpty(depositManageRecordList))
        depositManageLogic.reduceDepositAmount(enginOrder.getRefEnginRecordNo(), depositManageRecordList);

        if (retreatDocumentOrder.getOrderType().equals("HOME") || retreatDocumentOrder.getOrderType().equals("PERMU_HOME")) {

            depositManageLogic.computeOrderSalesQtyData(enginOrder.getRefEnginRecordNo(),orderItem.getMaterialId(),orderItem.getRealMaterialId(),orderItem.getPrice());
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void refundDisplace(InvoiceApplication retreatDocumentRequest, InvoiceApplicationOrder retreatDocumentOrder, String retailOrderItemId, Integer tdQtyRefund, String orderType) throws Exception {
        DisplaceOrderItem displaceOrderItem = displaceOrderItemService.getById(retailOrderItemId);


        if (tdQtyRefund == null || tdQtyRefund == 0) {
            return;
        }

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


        //返利单退款
        List<CustomerWalletAmountBean> customerWalletAmountBeans = new ArrayList<>();
        if (refundRebateAmount.doubleValue() > 0) {
            customerWalletAmountBeans.add(new CustomerWalletAmountBean(displaceOrderItem.getCustomerWalletId2(), refundRebateAmount, displaceOrderItem.getRemark(),
                    "置换单工程申请发货订单返利退款-退货单", retreatDocumentRequest.getOrderTime(), retreatDocumentRequest.getEnginOrderNo(), 2, "add"));

        }
        // 现金退款
        if (refundPayAmount.doubleValue() > 0) {
            customerWalletAmountBeans.add(new CustomerWalletAmountBean(displaceOrderItem.getCustomerWalletId(), refundPayAmount, displaceOrderItem.getRemark(),
                    "置换单工程发货申请发货订单退款-退货单", retreatDocumentRequest.getOrderTime(), retreatDocumentRequest.getEnginOrderNo(), 2, "add"));
        }

        walletLogic.doWalletAmount(customerWalletAmountBeans);
    }


    @Transactional(rollbackFor = Exception.class)
    public void addRak(DirectOrderBean directOrderBean, HttpServletRequest request) {
        String directTransferOrderId = IdWorker.getIdStr();
        RetailOrder retailOrder = retailOrderService.getById(directOrderBean.getOrderNo());

        if (retailOrder.getRequisitionStatus().equals(1)){
            throw new RemoteServiceException("已提前开票无法直调");

        }

        AdminUserCom adminUser = commonLogic.getAdminUser();
        AdminWebsit adminWebsit = adminWebsitService.lambdaQuery().eq(AdminWebsit::getAdminWebsitId, adminWebsitService.getById(retailOrder.getAdminWebsitId()).getAdminWebsitId()).one();
        if (StringUtils.isEmpty(adminWebsit.getWebsitNumber()))
            throw new RemoteServiceException("该经销商不在区域范围");

        List<DirectOrderBean.DirectItem> directItems = directOrderBean.getDirectItems();

        if (!retailOrder.getExamineStatus().equals(ExamineStatusEnum.OK.toString())) {
            throw new RemoteServiceException("请先审核该单");
        }
        String orderType = retailOrder.getType() == 1 ? OrderTypeEnum.RETAIL.getKey() : OrderTypeEnum.RETAIL_POLICY.getKey();
        StockCorrespond stockCorrespond = stockCorrespondService.getById(directOrderBean.getCorrespondId());
        StockCorrespondPosition one = stockCorrespondPositionService.lambdaQuery().eq(StockCorrespondPosition::getCorrespondId, stockCorrespond.getId()).one();
        KingDeeStock kingDeeStock = kingDeeStockService.getById(one.getStockId());

        InvoiceApplication invoiceApplication = BeanUtil.toBean(retailOrder, InvoiceApplication.class);
        invoiceApplication.setOrderTime(new Date());
        invoiceApplication.setCreateTime(new Date());
        invoiceApplication.setUpdateTime(new Date());
        //生成订单流水号
        String yyyyMM = DateUtil.format(new Date(), "yyyyMM");
        String orderWater = yyyyMM.substring(yyyyMM.length() - 4);
        if (redisUtil.get(Constant.RedisPrefix.INVOICE_APPLICATION + orderWater) == null) {
            redisUtil.set(Constant.RedisPrefix.INVOICE_APPLICATION + orderWater, "0000", 2726560);
        }
        Object water = redisUtil.get(Constant.RedisPrefix.INVOICE_APPLICATION + orderWater);
        String s = pickLogic.generateNum(4, Convert.toStr(water));

        if (invoiceApplicationService.lambdaQuery().eq(InvoiceApplication::getId, adminWebsit.getWebsitNumber() + orderWater + s).count() > 0) {
            throw new RemoteServiceException("请勿频繁新增，稍等一会");
        }
        redisUtil.set(Constant.RedisPrefix.INVOICE_APPLICATION + orderWater, s, 2726560);
        invoiceApplication.setId(adminWebsit.getWebsitNumber() + orderWater + s);
        invoiceApplication.setExamineStatus("WAIT");
        invoiceApplication.setCorrespondId(stockCorrespond.getId());
        invoiceApplication.setCorrespondName(stockCorrespond.getName());
        invoiceApplication.setStockId(kingDeeStock.getId());
        invoiceApplication.setStockName(kingDeeStock.getName());
        invoiceApplication.setStockNumber(kingDeeStock.getNumber());
        invoiceApplication.setType(3);
        invoiceApplication.setRemark(directOrderBean.getRemark());


        invoiceApplication.insert();


        // 直调发货容器
        List<InvoiceApplicationOrder> directTransferOrderItems = new ArrayList<>(10);
        HashMap<String, String> mapBool = new HashMap<>();

        for (DirectOrderBean.DirectItem item : directItems) {
            RetailOrderItem retailOrderItem = retailOrderItemService.getById(item.getItemId());
            String retailOrderId = retailOrderItem.getRetailOrderId();

            if (retailOrder == null) {
                retailOrder = retailOrderService.getById(retailOrderId);
            }
            if (!retailOrderItem.getIsDirectTransfer() && item.getQty() != 0) {
                throw new RemoteServiceException(retailOrderItem.getMaterialName() + "不可直调");
            }
            if (retailOrderItem.getDirectTransferStatus()) {
                throw new RemoteServiceException("已直调完成，不可直调发货");
            }

            //检查订单可申请数量是否大于申请数量
            invoiceLogic.invoiceOrder(item.getItemId(), item.getQty());


            if (item.getQty() == 0) {
                continue;
            }
            //判断库存是否足够
            Integer stock = stockCommonLogic.stockVirtualStatus(directOrderBean.getCorrespondId(),kingDeeStock.getId(), retailOrderItem.getMaterialId(),invoiceApplication.getCustomerId());
            if (item.getQty().intValue() > stock.intValue()) {
                throw new RemoteServiceException(retailOrderItem.getMaterialName()+retailOrderItem.getSpecification() + "库存不足");
            }

            //直调数量
            BigDecimal qty = BigDecimal.valueOf(item.getQty());


            InvoiceApplicationOrder order = BeanUtil.toBean(retailOrderItem, InvoiceApplicationOrder.class);

            order.setId(null);
            order.setMainOrderId(retailOrderItem.getRetailOrderId());
            order.setOrderId(retailOrderItem.getId());
            order.setRefundableQty(item.getQty());
            order.setInvoiceNum(item.getQty());
            order.setInvoiceId(invoiceApplication.getId());
            order.setSaleTypeId(retailOrderItem.getSaleTypeId());
            order.setSaleTypeCode(retailOrderItem.getSaleTypeCode());
            order.setSaleTypeName(retailOrderItem.getSaleTypeName());
            order.setTheTime(retailOrder.getTheTime());
            order.setMaterialName(retailOrderItem.getMaterialName());
            order.setMaterialId(retailOrderItem.getMaterialId());
            order.setMaterialCode(retailOrderItem.getMaterialCode());
            order.setMaterialOldNumber(retailOrderItem.getMaterialOldNumber());
            order.setSpecification(retailOrderItem.getSpecification());
            order.setUnit(retailOrderItem.getUnit());
            order.setPrice(retailOrderItem.getPrice());

            order.setPayAmount(retailOrderItem.getSinglePayPrice()
                    .multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));

            order.setTotalAmount(retailOrderItem.getPrice().multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));

            order.setPayRebateAmount(retailOrderItem.getSingleRebateAmount().multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));

            order.setTotalDiscAmount(retailOrderItem.getDiscAmount().multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));

            order.setTax(retailOrderItem.getTax());
            order.setSingleRebateAmount(retailOrderItem.getSingleRebateAmount());
            order.setQty(retailOrderItem.getQty());
            order.setSinglePayPrice(retailOrderItem.getSinglePayPrice());
            order.setServiceId(retailOrderItem.getServiceId());
            order.setServiceName(retailOrderItem.getServiceName());
            order.setDiscAmount(retailOrderItem.getDiscAmount());
            order.setKingDeeSeq(retailOrderItem.getKingDeeSeq());
            order.setKingDeeEntryId(retailOrderItem.getKingDeeEntryId());
            order.setOrderType(orderType);
            order.setK3CategoryId(retailOrderItem.getK3CategoryId());
            order.setK3CategoryName(retailOrderItem.getK3CategoryName());
            order.setK3CategoryNumber(retailOrderItem.getK3CategoryNumber());
            order.setK3ServiceName(retailOrder.getK3ServiceName());
            order.setK3ServiceId(retailOrder.getK3ServiceId());
            order.setCustomerWalletId(retailOrderItem.getCustomerWalletId());
            order.setCustomerWalletName(retailOrderItem.getCustomerWalletName());
            order.setCustomerWalletNumber(retailOrderItem.getCustomerWalletNumber());
            order.setCustomerWalletId2(retailOrderItem.getCustomerWalletId2());
            order.setCustomerWalletName2(retailOrderItem.getCustomerWalletName2());
            order.setFileNo(retailOrder.getFileNo());
            order.setHeaderRemark(retailOrder.getRemark());
            order.setRemark(retailOrderItem.getRemark());
            if (retailOrder.getType().equals(2)) {
                order.setPolicyId(retailOrder.getPolicyId());
                order.setPolicyTitle(retailOrder.getPolicyTitle());
                order.setPolicyCode(retailOrder.getPolicyCode());
            }

            //给订单设置直调发货
            retailOrderItem.setDirectTransferQty(retailOrderItem.getDirectTransferQty() + order.getRefundableQty());
            order.setVarietyQty(order.getRefundableQty());
            retailOrderItem.updateById();

            if ( StringUtils.isEmpty(order.getKingDeeEntryId())) {
                mapBool.put("1","1");
                invoiceApplication.setSyncType(2);
                invoiceApplication.updateById();
            }else if  (!StringUtils.isEmpty(order.getKingDeeEntryId())){
                mapBool.put("2","2");
            }
            if (mapBool.size() > 1){
                throw new RemoteServiceException("新单旧单发货逻辑更改，需分别发货");
            }

            directTransferOrderItems.add(order);
        }
        if (CollectionUtils.isEmpty(directTransferOrderItems)) {
            throw new RemoteServiceException("所有产品明细直调数量都为0，无法直调发货");
        }
        invoiceApplication.updateById();
        invoiceApplicationOrderService.saveBatch(directTransferOrderItems);
        invoiceMapper.updateInvoice(invoiceApplication.getId());
        invoiceMapper.updateWithold(invoiceApplication.getId(),Constant.RETAIL_UPDATE);
    }


    @Transactional(rollbackFor = Exception.class)
    public void addProjectRak(EnginOrderBean enginOrderBean, HttpServletRequest request) throws InterruptedException {
        AdminUserCom adminUser = commonLogic.getAdminUser();


        // 查询原单直调状态
        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();

        AdminWebsit adminWebsit = adminWebsitService.lambdaQuery().eq(AdminWebsit::getAdminWebsitId, enginOrder.getAdminWebsitId()).one();

        if (StringUtils.isEmpty(adminWebsit.getWebsitNumber()))
            throw new RemoteServiceException("该经销商不在区域范围");


        if (Objects.isNull(enginOrder)) {
            throw new RemoteServiceException("订单状态已发生变化");
        }
        // 直调单号
        InvoiceApplication invoiceApplication = BeanUtil.toBean(enginOrder, InvoiceApplication.class);

        invoiceApplication.setOrderTime(new Date());
        //生成订单流水号
        String yyyyMM = DateUtil.format(new Date(), "yyyyMM");
        String orderWater = yyyyMM.substring(yyyyMM.length() - 4);
        if (redisUtil.get(Constant.RedisPrefix.INVOICE_APPLICATION + orderWater) == null) {
            redisUtil.set(Constant.RedisPrefix.INVOICE_APPLICATION + orderWater, "0000", 2726560);
        }
        Object water = redisUtil.get(Constant.RedisPrefix.INVOICE_APPLICATION + orderWater);
        String s = pickLogic.generateNum(4, Convert.toStr(water));

        if (invoiceApplicationService.lambdaQuery().eq(InvoiceApplication::getId, adminWebsit.getWebsitNumber() + orderWater + s).count() > 0) {
            throw new RemoteServiceException("请勿频繁新增，稍等一会");
        }
        redisUtil.set(Constant.RedisPrefix.INVOICE_APPLICATION + orderWater, s, 2726560);
        invoiceApplication.setId(adminWebsit.getWebsitNumber() + orderWater + s);
        StockCorrespond stockCorrespond = stockCorrespondService.getById(enginOrderBean.getCorrespondId());
        StockCorrespondPosition one = stockCorrespondPositionService.lambdaQuery().eq(StockCorrespondPosition::getCorrespondId, stockCorrespond.getId()).one();
        KingDeeStock kingDeeStock = kingDeeStockService.getById(one.getStockId());
        invoiceApplication.setStockId(kingDeeStock.getId());
        invoiceApplication.setExamineStatus("WAIT");
        invoiceApplication.setCorrespondId(stockCorrespond.getId());
        invoiceApplication.setCorrespondName(stockCorrespond.getName());
        invoiceApplication.setStockId(kingDeeStock.getId());
        invoiceApplication.setStockName(kingDeeStock.getName());
        invoiceApplication.setStockNumber(kingDeeStock.getNumber());
        invoiceApplication.setType(3);
        invoiceApplication.setRemark(enginOrderBean.getRemark());
        invoiceApplication.setRefRegionWork(enginOrder.getRefRegionWork());
        invoiceApplication.setRefProjectCategory(enginOrder.getRefProjectCategory());
        invoiceApplication.setRefBuyUnitName(enginOrder.getRefBuyUnitName());
        invoiceApplication.setRefDeclareNo(enginOrder.getRefDeclareNo());
        invoiceApplication.setRefFactoryNo(enginOrder.getRefFactoryNo());
        invoiceApplication.setRefInstallAddress(enginOrder.getRefInstallAddress());
        invoiceApplication.setRefLinkman(enginOrder.getRefLinkman());
        invoiceApplication.setRefMachineType(enginOrder.getRefMachineType());
        invoiceApplication.setRefOtherAnnexIdea(enginOrder.getRefOtherAnnexIdea());
        invoiceApplication.setRefPhone(enginOrder.getRefPhone());
        invoiceApplication.setRefPowerCategory(enginOrder.getRefPowerCategory());
        invoiceApplication.setRefProjectName(enginOrder.getRefProjectName());
        invoiceApplication.setRefProjectNo(enginOrder.getRefProjectNo());
        invoiceApplication.setRefProjectNote(enginOrder.getRefProjectNote());
        invoiceApplication.setRefProjectType(enginOrder.getRefProjectType());
        invoiceApplication.setRefPromiseProvide(enginOrder.getRefPromiseProvide());
        invoiceApplication.setRefPromiseStatus(enginOrder.getRefPromiseStatus());
        invoiceApplication.setRefTel(enginOrder.getRefTel());
        invoiceApplication.setRefTradeCategory(enginOrder.getRefTradeCategory());
        invoiceApplication.setRefUseUnit(enginOrder.getRefUseUnit());

        invoiceApplication.insert();

        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<InvoiceApplicationOrder> directTransferOrderItems = new ArrayList<>(10);

        HashMap<String, String> mapBool = new HashMap<>();
        // 检查直调数量不能大于数量
        for (EnginOrderItem orderItem : orderItems) {
            EnginOrderItemBean itemBean = itemBeanMap.get(orderItem.getMaterialId());
            Integer realDirectTransferQty = itemBean.getRealDirectTransferQty();

            EnginOrderItem enginOrderItem = enginOrderItemService.getById(orderItem.getId());

            if (realDirectTransferQty < 1){
                continue;
            }

            invoiceLogic.invoiceEnginOrder(enginOrderItem.getId(), realDirectTransferQty);


            //判断库存是否足够
            Integer stock = stockCommonLogic.stockVirtualStatus(enginOrderBean.getCorrespondId(),kingDeeStock.getId(), orderItem.getMaterialId(),invoiceApplication.getCustomerId());
            if (realDirectTransferQty > stock) {
                throw new RemoteServiceException(orderItem.getMaterialName()+orderItem.getSpecification() + "库存不足");
            }
            // 更新直调数量
            orderItem.setDirectTransferQty(orderItem.getDirectTransferQty() + realDirectTransferQty);
            orderItem.setDirectDepositAmount(null);
            // 更新可退数量


            // 如果是家用工程押金比例大于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);
            }*/
            // 插入直调发货单明细记录

            InvoiceApplicationOrder order = BeanUtil.toBean(itemBean, InvoiceApplicationOrder.class);


            order.setId(null);
            order.setMainOrderId(enginOrder.getEnginOrderId());
            order.setRefundableQty(realDirectTransferQty);
            order.setInvoiceNum(realDirectTransferQty);
            order.setInvoiceId(invoiceApplication.getId());
            order.setSaleTypeId(itemBean.getSaleTypeId());
            order.setSaleTypeCode(itemBean.getSaleTypeCode());
            order.setSaleTypeName(itemBean.getSaleTypeName());
            order.setTheTime(enginOrder.getOrderDate());
            order.setMaterialName(itemBean.getMaterialName());
            order.setMaterialId(itemBean.getMaterialId());
            order.setMaterialCode(itemBean.getMaterialNumber());
            order.setMaterialOldNumber(itemBean.getMaterialOldNumber());
            order.setSpecification(itemBean.getSpecification());
            order.setUnit(itemBean.getUnit());
            order.setPrice(itemBean.getPrice());

            order.setPayAmount(itemBean.getSinglePayPrice()
                    .multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));

            order.setTotalAmount(itemBean.getPrice().multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));

            order.setPayRebateAmount(itemBean.getSingleRebateAmount().multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));

            order.setTotalDiscAmount(itemBean.getDiscAmount().multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));

            order.setTax(itemBean.getTax());
            order.setSingleRebateAmount(itemBean.getSingleRebateAmount());
            order.setQty(itemBean.getQty());
            order.setVarietyQty(itemBean.getRefundableQty());
            order.setSinglePayPrice(itemBean.getSinglePayPrice());
            order.setServiceId(enginOrderItem.getServiceId());
            order.setServiceName(enginOrderItem.getServiceName());
            order.setDiscAmount(itemBean.getDiscAmount());
            order.setKingDeeEntryId(itemBean.getKingDeeEntryId());
            order.setOrderType(enginOrder.getEnginOrderType());
            order.setMainOrderId(enginOrder.getEnginOrderId());
            order.setOrderId(orderItem.getId());
            order.setKingDeeEntryId(orderItem.getKingDeeEntryId());
            order.setKingDeeSeq(orderItem.getKingDeeSeq());
            order.setK3CategoryId(orderItem.getK3CategoryId());
            order.setK3CategoryName(orderItem.getK3CategoryName());
            order.setK3CategoryNumber(orderItem.getK3CategoryNumber());
            order.setK3ServiceName(enginOrder.getServiceName());
            order.setK3ServiceId(enginOrder.getServiceId());
            order.setCustomerWalletId(orderItem.getCustomerWalletId());
            order.setCustomerWalletName(orderItem.getCustomerWalletName());
            order.setCustomerWalletNumber(orderItem.getCustomerWalletNumber());
            order.setCustomerWalletId2(orderItem.getCustomerWalletId2());
            order.setCustomerWalletName2(orderItem.getCustomerWalletName2());
            order.setFileNo(enginOrder.getFileNo());
            order.setHeaderRemark(enginOrder.getRemark());
            order.setRemark(orderItem.getRemark());
            order.setRealMaterialId(enginOrderItem.getRealMaterialId());
            order.setRealMaterialName(enginOrderItem.getRealMaterialName());
            order.setRealMaterialNumber(enginOrderItem.getMaterialNumber());
            order.setRealMaterialOldNumber(enginOrderItem.getMaterialOldNumber());
            order.setRealSpecification(enginOrderItem.getRealSpecification());


            if ( StringUtils.isEmpty(order.getKingDeeEntryId())) {
                mapBool.put("1","1");
                invoiceApplication.setSyncType(2);
                invoiceApplication.updateById();
            }else if  (!StringUtils.isEmpty(order.getKingDeeEntryId())){
                mapBool.put("2","2");
            }
            if (mapBool.size() > 1){
                throw new RemoteServiceException("新单旧单发货逻辑更改，需分别发货");
            }
            directTransferOrderItems.add(order);
        }
        List<DepositManageRecordBean> depositManageRecordList = new ArrayList<>();

        for (InvoiceApplicationOrder order : directTransferOrderItems) {

            if (order.getOrderType().equals("PERMU_HOME")) {
                DisplaceOrder displaceOrder = displaceOrderService.getById(order.getMainOrderId());
                DisplaceOrderItem displaceOrderItem = displaceOrderItemService.getById(order.getOrderId());
                DepositManageRecordBean depositManageRecordBean = new DepositManageRecordBean();
                depositManageRecordBean.handleEnginOrderItem(displaceOrder, displaceOrderItem, order.getRefundableQty(), displaceOrderItem.getSingleDepositAmount().multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));
                depositManageRecordList.add(depositManageRecordBean);
            }

            //工程扣除押金
            if (order.getOrderType().equals("HOME")) {
                EnginOrder enginOrderNo = enginOrderService.getById(order.getMainOrderId());
                EnginOrderItem orderItem = enginOrderItemService.getById(order.getOrderId());
                DepositManageRecordBean depositManageRecordBean = new DepositManageRecordBean();
                depositManageRecordBean.handleEnginOrderItem(enginOrderNo, orderItem, order.getRefundableQty(), orderItem.getSingleDepositAmount().multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));
                if (!enginOrderNo.getIsFirstOldOrder() && invoiceApplication.getType() != null && invoiceApplication.getType().equals(3)){
                    depositManageRecordBean.setOrderItem(orderItem);
                }

                depositManageRecordList.add(depositManageRecordBean);
            }

        }


        if (CollectionUtil.isNotEmpty(depositManageRecordList))
        depositManageLogic.addDepositAmount(enginOrder.getRefEnginRecordNo(), depositManageRecordList);


        enginOrderItemService.saveOrUpdateBatch(orderItems);
        invoiceApplicationOrderService.saveBatch(directTransferOrderItems);
        invoiceMapper.updateInvoice(invoiceApplication.getId());
        invoiceMapper.updateWithold(invoiceApplication.getId(),Constant.ENGIN_UPDATE);

    }


    @Transactional(rollbackFor = Exception.class)
    public void updateRak(InvoiceRequestJson invoiceRequest, HttpServletRequest request) throws InterruptedException {
        throw new RemoteServiceException("直调不允许编辑");
        //2，添加发货申请单
       /* AdminUserCom adminUser = commonLogic.getAdminUser();
        AdminWebsit adminWebsit = adminWebsitService.lambdaQuery().eq(AdminWebsit::getAdminWebsitId, adminWebsitService.getById(adminUser.getAdminWebsitId())).one();

        if (StringUtils.isNotBlank(adminUser.getCustomerId())) {
            invoiceRequest.setCustomerId(adminUser.getCustomerId());
            invoiceRequest.setCustomerName(adminUser.getCustomerName());
            invoiceRequest.setCustomerNumber(adminUser.getCustomerNumber());
        }
        InvoiceApplication invoiceApplicationServiceById = invoiceApplicationService.getById(invoiceRequest.getId());
        invoiceRequest.updateById();
        List<InvoiceApplicationOrder> applicationOrders = invoiceApplicationOrderService.lambdaQuery().eq(InvoiceApplicationOrder::getInvoiceId, invoiceRequest.getId()).list();
        List<DepositManageRecordBean> depositManageRecordList = new ArrayList<>();
          for (InvoiceApplicationOrder order : applicationOrders) {

                if (order.getOrderType().equals("PERMU_HOME")) {
                    DisplaceOrder displaceOrder = displaceOrderService.getById(order.getMainOrderId());
                    DisplaceOrderItem displaceOrderItem = displaceOrderItemService.getById(order.getOrderId());
                    DepositManageRecordBean depositManageRecordBean = new DepositManageRecordBean();
                    depositManageRecordBean.handleEnginOrderItem(displaceOrder, displaceOrderItem, order.getRefundableQty(), displaceOrderItem.getSingleDepositAmount().multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));
                    depositManageRecordList.add(depositManageRecordBean);
                }

                //工程扣除押金
                if (order.getOrderType().equals("HOME")) {
                    EnginOrder enginOrder = enginOrderService.getById(order.getMainOrderId());
                    EnginOrderItem orderItem = enginOrderItemService.getById(order.getOrderId());
                    DepositManageRecordBean depositManageRecordBean = new DepositManageRecordBean();
                    depositManageRecordBean.setConsumNo(order.getInvoiceId());
                    depositManageRecordBean.handleEnginOrderItem(enginOrder, orderItem, order.getRefundableQty(), orderItem.getSingleDepositAmount().multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));
                    depositManageRecordList.add(depositManageRecordBean);
                }


        }
        if (CollectionUtil.isNotEmpty(depositManageRecordList))
            depositManageLogic.reduceDepositAmount(invoiceApplicationServiceById.getRefEnginRecordNo(), depositManageRecordList);

        List<InvoiceApplicationOrder> invoiceApplicationOrderArrayList = new ArrayList<>();
        for (InvoiceApplicationOrder order : invoiceRequest.getOrders()) {
            if (order.getInvoiceNum() == null || order.getInvoiceNum().equals(0))
                continue;

            order.setInvoiceNum(order.getRefundableQty());
            InvoiceApplicationOrder invoiceApplicationOrder = BeanUtil.toBean(order, InvoiceApplicationOrder.class);
            invoiceApplicationOrder.setVarietyQty(order.getRefundableQty());

            invoiceApplicationOrder.setPayAmount(order.getSinglePayPrice()
                    .multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));

            invoiceApplicationOrder.setTotalAmount(order.getPrice().multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));

            invoiceApplicationOrder.setPayRebateAmount(order.getSingleRebateAmount().multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));

            invoiceApplicationOrder.setTotalDiscAmount(order.getDiscAmount().multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));
            invoiceApplicationOrderArrayList.add(invoiceApplicationOrder);
        }
        invoiceApplicationOrderService.lambdaUpdate().eq(InvoiceApplicationOrder::getInvoiceId, invoiceRequest.getId()).remove();

        List<DepositManageRecordBean> one = new ArrayList<>();
            for (InvoiceApplicationOrder order : invoiceApplicationOrderArrayList) {

                if (order.getInvoiceNum() == null || order.getInvoiceNum().equals(0))
                    continue;
                if (order.getOrderType().equals("PERMU_HOME")) {
                    DisplaceOrder displaceOrder = displaceOrderService.getById(order.getMainOrderId());
                    DisplaceOrderItem displaceOrderItem = displaceOrderItemService.getById(order.getOrderId());
                    DepositManageRecordBean depositManageRecordBean = new DepositManageRecordBean();
                    depositManageRecordBean.handleEnginOrderItem(displaceOrder, displaceOrderItem, order.getInvoiceNum(), displaceOrderItem.getSingleDepositAmount().multiply(new BigDecimal(Convert.toStr(order.getInvoiceNum()))));
                    one.add(depositManageRecordBean);
                }

                //工程扣除押金
                if (order.getOrderType().equals("HOME")) {
                    EnginOrder enginOrder = enginOrderService.getById(order.getMainOrderId());
                    EnginOrderItem orderItem = enginOrderItemService.getById(order.getOrderId());
                    DepositManageRecordBean depositManageRecordBean = new DepositManageRecordBean();
                    depositManageRecordBean.setConsumNo(order.getInvoiceId());
                    depositManageRecordBean.handleEnginOrderItem(enginOrder, orderItem, order.getInvoiceNum(), orderItem.getSingleDepositAmount().multiply(new BigDecimal(Convert.toStr(order.getInvoiceNum()))));
                    one.add(depositManageRecordBean);
                }
        }
        if (!CollectionUtils.isEmpty(one))
            depositManageLogic.addDepositAmount(invoiceRequest.getRefEnginRecordNo(), one);

        invoiceApplicationOrderService.saveBatch(invoiceApplicationOrderArrayList);
        invoiceMapper.updateStatus(invoiceRequest.getId());
        invoiceMapper.updateInvoice(invoiceRequest.getId());*/
    }

    @Transactional(rollbackFor = Exception.class)
    public void deleteRak(String id) throws InterruptedException {

        InvoiceApplication byId = invoiceApplicationService.getById(id);
        if (!byId.getExamineStatus().equals("SAVE")) {
            throw new RemoteServiceException("该申请单不为保存状态，不可删除");
        }
        List<DepositManageRecordBean> depositManageRecordList = new ArrayList<>();
        for (InvoiceApplicationOrder invoiceApplicationOrder : invoiceApplicationOrderService.lambdaQuery().eq(InvoiceApplicationOrder::getInvoiceId, id).list()) {
            //减少经销商暂扣库存
            stockCommonLogic.reduceStockCustomerSuspended(invoiceApplicationOrder.getMaterialId(), byId.getCustomerId(), invoiceApplicationOrder.getRefundableQty());
            //修改直调数量
            if (invoiceApplicationOrder.getOrderType().equals("RETAIL") || invoiceApplicationOrder.getOrderType().equals("RETAIL_POLICY")) {
                RetailOrderItem retailOrderItem = retailOrderItemService.getById(invoiceApplicationOrder.getOrderId());
          /*      if (retailOrderItem.getDirectTransferStatus()) {
                    throw new RemoteServiceException("直调完结，不可删除");
                }*/
                retailOrderItem.setDirectTransferQty(retailOrderItem.getDirectTransferQty() - invoiceApplicationOrder.getRefundableQty());
                retailOrderItem.updateById();
            }


            if (invoiceApplicationOrder.getOrderType().equals("HOME") || invoiceApplicationOrder.getOrderType().equals("TRADE")) {
                EnginOrderItem enginOrderItem = enginOrderItemService.getById(invoiceApplicationOrder.getOrderId());
           /*     if (enginOrderItem.getDirectTransferStatus()) {
                    throw new RemoteServiceException("直调完结，不可删除");
                }*/
                enginOrderItem.setDirectTransferQty(enginOrderItem.getDirectTransferQty() - invoiceApplicationOrder.getRefundableQty());
                enginOrderItem.updateById();
            }


            if (invoiceApplicationOrder.getOrderType().equals("PERMU_HOME")) {
                DisplaceOrder displaceOrder = displaceOrderService.getById(invoiceApplicationOrder.getMainOrderId());
                DisplaceOrderItem displaceOrderItem = displaceOrderItemService.getById(invoiceApplicationOrder.getOrderId());
                DepositManageRecordBean depositManageRecordBean = new DepositManageRecordBean();
                depositManageRecordBean.handleEnginOrderItem(displaceOrder, displaceOrderItem, invoiceApplicationOrder.getRefundableQty(), displaceOrderItem.getSingleDepositAmount().multiply(new BigDecimal(Convert.toStr(invoiceApplicationOrder.getRefundableQty()))));
                depositManageRecordList.add(depositManageRecordBean);
            }

            //工程扣除押金
            if (invoiceApplicationOrder.getOrderType().equals("HOME")) {
                EnginOrder enginOrder = enginOrderService.getById(invoiceApplicationOrder.getMainOrderId());
                EnginOrderItem orderItem = enginOrderItemService.getById(invoiceApplicationOrder.getOrderId());
                DepositManageRecordBean depositManageRecordBean = new DepositManageRecordBean();
                depositManageRecordBean.handleEnginOrderItem(enginOrder, orderItem, invoiceApplicationOrder.getRefundableQty(), orderItem.getSingleDepositAmount().multiply(new BigDecimal(Convert.toStr(invoiceApplicationOrder.getRefundableQty()))));
                depositManageRecordList.add(depositManageRecordBean);
                if (!enginOrder.getIsFirstOldOrder() && byId.getType() != null && byId.getType().equals(3)) {

                    depositManageRecordBean.setOrderItem(orderItem);
                }
            }
        }

        if (CollectionUtil.isNotEmpty(depositManageRecordList))
            depositManageLogic.reduceDepositAmount(byId.getRefEnginRecordNo(), depositManageRecordList);

        invoiceApplicationService.removeById(id);
        invoiceApplicationOrderService.lambdaUpdate().eq(InvoiceApplicationOrder::getInvoiceId, id).remove();
    }


    @Transactional(rollbackFor = Exception.class)
    public String giveUpRak(String id) throws InterruptedException {
        InvoiceApplication invoiceApplication = invoiceApplicationService.getById(id);
        if (StringUtils.isNotBlank(invoiceApplication.getEnginOrderType())) {
            return giveUpProject(id);
        }

        if (invoiceApplication.getGejiangSync() != null && invoiceApplication.getGejiangSync().equals(0))
            throw new RemoteServiceException("当前单未同步采购入库单无法弃审");

        if (!invoiceApplication.getExamineStatus().equals(ExamineStatusEnum.OK.toString()))
            throw new RemoteServiceException("当前单非审核状态");
        SalesOrder salesOrder = salesOrderService.lambdaQuery().eq(SalesOrder::getId, invoiceApplication.getSalesOrderId()).one();
        if (salesOrder.getExamineStatus().equals(ExamineStatusEnum.OK.toString()))
            throw new RemoteServiceException("销售出库单已审核通过无法弃审");

        //1,删除销售出库单和发货单
        salesOrderItemService.lambdaUpdate().eq(SalesOrderItem::getInvoiceId, invoiceApplication.getId()).remove();
        salesOrderService.lambdaUpdate().eq(SalesOrder::getOrderNo, invoiceApplication.getId()).remove();
        shipDocumentService.lambdaUpdate().eq(ShipDocument::getId, invoiceApplication.getId()).remove();



        //生成订单流水号
        String substring = invoiceApplication.getId().substring(0, 2);
        String yyyyMM = DateUtil.format(new Date(), "yyyyMM");
        String orderWater = yyyyMM.substring(yyyyMM.length() - 4);
        if (redisUtil.get(Constant.RedisPrefix.INVOICE_APPLICATION + orderWater) == null) {
            redisUtil.set(Constant.RedisPrefix.INVOICE_APPLICATION + orderWater, "0000", 2726560);
        }
        Object water = redisUtil.get(Constant.RedisPrefix.INVOICE_APPLICATION + orderWater);
        String s = pickLogic.generateNum(4, Convert.toStr(water));

        if (invoiceApplicationService.lambdaQuery().eq(InvoiceApplication::getId, substring + orderWater + s).count() > 0) {
            throw new RemoteServiceException("请勿频繁新增，稍等一会");
        }
        redisUtil.set(Constant.RedisPrefix.INVOICE_APPLICATION + orderWater, s, 2726560);
        invoiceApplicationService.removeById(invoiceApplication.getId());



        //2返还数量到销售订单
        List<InvoiceApplicationOrder> list = invoiceApplicationOrderService.lambdaQuery().eq(InvoiceApplicationOrder::getInvoiceId, invoiceApplication.getId()).list();
        invoiceApplication.setId(substring + orderWater + s);
        for (InvoiceApplicationOrder order : list) {

            if (order.getOrderType().equals("RETAIL") || order.getOrderType().equals("RETAIL_POLICY"))
                retailOrderLogic.changeSubRefundableQty(order.getOrderId(), order.getApprovalNumber() + order.getRetiredQty());

            stockCommonLogic.reduceStockCustomerSuspended(order.getMaterialId(), invoiceApplication.getCustomerId(), order.getRefundableQty());

            //变更可退货数量
            if (order.getOrderType().equals("TRADE") || order.getOrderType().equals("HOME"))
                invoiceLogic.changeAddEnginRefundableQty(order.getOrderId(), order.getApprovalNumber());

            if (order.getOrderType().equals("PERMU_TRADE") || order.getOrderType().equals("PERMU_HOME"))
                invoiceLogic.changeSubDiplaceRefundableQty(order.getOrderId(), order.getApprovalNumber());

            if (order.getOrderType().equals("REQUISITION_TRADE") || order.getOrderType().equals("REQUISITION_HOME"))
                invoiceLogic.changeSubRequisitonRefundableQty(order.getRequisitionItemId(), order.getApprovalNumber());



            //记录台账记录
            String customerWalletId = null;
            if (order.getOrderType().equals("RETAIL") || order.getOrderType().equals("RETAIL_POLICY")) {
                RetailOrderItem retailOrderItem = retailOrderItemService.getById(order.getOrderId());
                if (retailOrderItem.getRefundableQty().equals("0") && retailOrderItem.getIsDirectTransfer() == false) {
                    order.setPayAmount(
                            retailOrderItem.getPayAmount().subtract(new BigDecimal((retailOrderItem.getHasSendQty() - retailOrderItem.getDirectTransferQty())).multiply(retailOrderItem.getSinglePayPrice())));
                }
                customerWalletId = retailOrderItem.getCustomerWalletId();
            }
            if (order.getOrderType().equals("PERMU_RETAIL") || order.getOrderType().equals("PERMU_RETAIL_POLICY")) {
                DisplaceOrderItem displaceOrderItem = displaceOrderItemService.getById(order.getOrderId());
                if (displaceOrderItem.getRefundableQty().equals("0")) {
                    order.setPayAmount(
                            displaceOrderItem.getPayAmount().subtract(new BigDecimal((displaceOrderItem.getHasSendQty())).multiply(displaceOrderItem.getSinglePayPrice())));
                }
                customerWalletId = displaceOrderItem.getCustomerWalletId();
            }

            if (order.getOrderType().equals("REQUISITION_RETAIL") || order.getOrderType().equals("REQUISITION_RETAIL_POLICY")) {
                RequisitionOrderItem requisitionOrderItem = requisitionOrderItemService.getById(order.getRequisitionItemId());
                if (requisitionOrderItem.getRefundableQty().equals("0")) {
                    order.setPayAmount(
                            requisitionOrderItem.getPayAmount().subtract(new BigDecimal((requisitionOrderItem.getHasSendQty())).multiply(requisitionOrderItem.getSinglePayPrice())));
                }
                customerWalletId = requisitionOrderItem.getCustomerWalletId();
            }
            CustomerWallet customerWallet = customerWalletService.getById(customerWalletId);
            walletLogic.saveCustomerWalletRecord(customerWallet, order.getPayAmount(), "申请发货单弃审流水", "申请发货单", new Date(), invoiceApplication.getId(), 3, "IN");

            order.setInvoiceId(invoiceApplication.getId());
            order.updateById();

        }

        //3订单改为提审状态
        invoiceApplication.setExamineStatus(ExamineStatusEnum.WAIT.toString());
        invoiceApplication.setCounterclaim(true);
        invoiceApplication.updateById();
        invoiceApplicationService.save(invoiceApplication);

        if (invoiceApplication.getGejiangSync() != null && invoiceApplication.getGejiangSync().equals(1)){
            geJiangInStockLogic.unAuditByBillNo(id);
        }

        invoiceMapper.updateStatus(invoiceApplication.getId());
        invoiceMapper.updateInvoice(invoiceApplication.getId());
        return invoiceApplication.getId();

    }


    @Transactional(rollbackFor = Exception.class)
    public String giveUpProject(String id) throws InterruptedException {

        InvoiceApplication invoiceApplication = invoiceApplicationService.getById(id);
        if (!invoiceApplication.getExamineStatus().equals(ExamineStatusEnum.OK.toString()))
            throw new RemoteServiceException("当前单非审核状态");
        SalesOrder salesOrder = salesOrderService.lambdaQuery().eq(SalesOrder::getOrderNo, invoiceApplication.getId()).one();
        if (salesOrder.getExamineStatus().equals(ExamineStatusEnum.OK.toString()))
            throw new RemoteServiceException("销售出库单已审核通过无法弃审");
        if (retreatDocumentOrderService.lambdaQuery().eq(RetreatDocumentOrder::getInvoiceId, invoiceApplication.getId()).count() > 0)
            throw new RemoteServiceException("该申请发货单有退货操作不可弃审");

        //1,删除销售出库单和发货单
        salesOrderItemService.lambdaUpdate().eq(SalesOrderItem::getInvoiceId, invoiceApplication.getId()).remove();
        salesOrderService.lambdaUpdate().eq(SalesOrder::getOrderNo, invoiceApplication.getId()).remove();
        shipDocumentService.lambdaUpdate().eq(ShipDocument::getId, invoiceApplication.getId()).remove();




        //生成订单流水号
        String substring = invoiceApplication.getId().substring(0, 2);
        String yyyyMM = DateUtil.format(new Date(), "yyyyMM");
        String orderWater = yyyyMM.substring(yyyyMM.length() - 4);
        if (redisUtil.get(Constant.RedisPrefix.INVOICE_APPLICATION + orderWater) == null) {
            redisUtil.set(Constant.RedisPrefix.INVOICE_APPLICATION + orderWater, "0000", 2726560);
        }
        Object water = redisUtil.get(Constant.RedisPrefix.INVOICE_APPLICATION + orderWater);
        String s = pickLogic.generateNum(4, Convert.toStr(water));

        if (invoiceApplicationService.lambdaQuery().eq(InvoiceApplication::getId, substring + orderWater + s).count() > 0) {
            throw new RemoteServiceException("请勿频繁新增，稍等一会");
        }
        redisUtil.set(Constant.RedisPrefix.INVOICE_APPLICATION + orderWater, s, 2726560);
        invoiceApplicationService.removeById(invoiceApplication.getId());

        //2返还数量到销售订单
        List<InvoiceApplicationOrder> list = invoiceApplicationOrderService.lambdaQuery().eq(InvoiceApplicationOrder::getInvoiceId, invoiceApplication.getId()).list();
        invoiceApplication.setId(substring + orderWater + s);
        List<DepositManageRecordBean> depositManageRecordList = new ArrayList<>();
        for (InvoiceApplicationOrder order : list) {

            if (pickManagerShipService.lambdaQuery().eq(PickManagerShip::getInvoiceOrderId, order.getId()).count() > 0)
                throw new RemoteServiceException("该申请发货单有提货预约操作不可弃审");
            //变更可退货数量
            if (order.getOrderType().equals("TRADE") || order.getOrderType().equals("HOME"))
                invoiceLogic.changeAddEnginRefundableQty(order.getOrderId(), order.getApprovalNumber());

            if (order.getOrderType().equals("PERMU_TRADE") || order.getOrderType().equals("PERMU_HOME"))
                invoiceLogic.changeSubDiplaceRefundableQty(order.getOrderId(), order.getApprovalNumber());

            if (order.getOrderType().equals("REQUISITION_TRADE") || order.getOrderType().equals("REQUISITION_HOME"))
                invoiceLogic.changeSubRequisitonRefundableQty(order.getRequisitionItemId(), order.getApprovalNumber());


            //增加经销商暂扣库存

            stockCommonLogic.reduceStockCustomerSuspended(order.getMaterialId(), invoiceApplication.getCustomerId(), order.getRefundableQty());

            //记录台账记录
            String customerWalletId = null;
            if (order.getOrderType().equals("HOME") || order.getOrderType().equals("TRADE")) {
                EnginOrderItem engin = enginOrderItemService.getById(order.getOrderId());
                if (engin.getRefundableQty().equals("0") && engin.getIsDirectTransfer() == false) {
                    order.setPayAmount(
                            engin.getPayAmount().subtract(new BigDecimal((engin.getHasSendQty() - engin.getDirectTransferQty())).multiply(engin.getSinglePayPrice())));
                }
                customerWalletId = engin.getCustomerWalletId();
            }
            if (order.getOrderType().equals("PERMU_TRADE") || order.getOrderType().equals("PERMU_HOME")) {
                DisplaceOrderItem displaceOrderItem = displaceOrderItemService.getById(order.getOrderId());
                if (displaceOrderItem.getRefundableQty().equals("0")) {
                    order.setPayAmount(
                            displaceOrderItem.getPayAmount().subtract(new BigDecimal((displaceOrderItem.getHasSendQty())).multiply(displaceOrderItem.getSinglePayPrice())));
                }
                customerWalletId = displaceOrderItem.getCustomerWalletId();
            }

            if (order.getOrderType().equals("REQUISITION_TRADE") || order.getOrderType().equals("REQUISITION_HOME")) {
                RequisitionOrderItem requisitionOrderItem = requisitionOrderItemService.getById(order.getOrderId());
                if (requisitionOrderItem.getRefundableQty().equals("0")) {
                    order.setPayAmount(
                            requisitionOrderItem.getPayAmount().subtract(new BigDecimal((requisitionOrderItem.getHasSendQty())).multiply(requisitionOrderItem.getSinglePayPrice())));
                }
                customerWalletId = requisitionOrderItem.getCustomerWalletId();
            }
            CustomerWallet customerWallet = customerWalletService.getById(customerWalletId);
            walletLogic.saveCustomerWalletRecord(customerWallet, order.getPayAmount(), "直调申请发货单弃审流水", "申请发货单", new Date(), invoiceApplication.getId(), 3, "IN");


            //工程扣除押金
            EnginOrder enginOrder = enginOrderService.getById(order.getMainOrderId());
            EnginOrderItem orderItem = enginOrderItemService.getById(order.getOrderId());
/*            if (order.getOrderType().equals("HOME") || order.getOrderType().equals("PERMU_HOME")) {
                DepositManageRecordBean depositManageRecordBean = new DepositManageRecordBean();
                enginOrder.setEnginOrderNo(invoiceApplication.getId());
                enginOrder.setOrderDate(invoiceApplication.getOrderTime());
                depositManageRecordBean.handleEnginOrderItem(enginOrder, orderItem, order.getRefundableQty(), orderItem.getSingleDepositAmount().multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));
                depositManageRecordList.add(depositManageRecordBean);
            }*/
            order.setInvoiceId(invoiceApplication.getId());
            order.updateById();
        }
        if (CollectionUtil.isNotEmpty(depositManageRecordList))
        depositManageLogic.reduceDepositAmount(invoiceApplication.getRefEnginRecordNo(), depositManageRecordList);
        //3订单改为提审状态
        invoiceApplication.setExamineStatus(ExamineStatusEnum.WAIT.toString());
        invoiceApplication.setCounterclaim(true);
        invoiceApplication.updateById();
        invoiceApplicationService.save(invoiceApplication);

        invoiceMapper.updateStatus(invoiceApplication.getId());
        invoiceMapper.updateInvoice(invoiceApplication.getId());
        invoiceMapper.updateTaiZhang(invoiceApplication.getId());

        if (invoiceApplication.getGejiangSync() != null && invoiceApplication.getGejiangSync().equals(1)){
            geJiangInStockLogic.unAuditByBillNo(id);
        }
        return invoiceApplication.getId();
    }

    @Transactional(rollbackFor = Exception.class)
    public void approvalInvoiceRak(InvoiceRequestJson invoiceRequestJson, HttpServletRequest request) throws InterruptedException {
        //保存申请发货单
        InvoiceApplication invoiceApplication = invoiceApplicationService.getById(invoiceRequestJson.getId());
        if (!invoiceApplication.getExamineStatus().equals(ExamineStatusEnum.WAIT.toString())) {
            throw new RemoteServiceException("非审核单，无法审核");
        }
        if (StringUtils.isNotBlank(invoiceApplication.getEnginOrderType())) {
            approvalInvoiceProjecRak(invoiceRequestJson);
            return;
        }

        AdminUserCom adminUser = commonLogic.getAdminUser(request);

        invoiceRequestJson.setApprovalName(adminUser.getNickName());
        invoiceRequestJson.setApprovalTime(new Date());
        invoiceApplicationService.updateById(invoiceRequestJson);
        for (InvoiceApplicationOrderRequest order : invoiceRequestJson.getOrders()) {
            order.setApprovalNumber(order.getRefundableQty());


            //判断库存是否足够
            Integer stock = stockCommonLogic.stockVirtualStatus(invoiceApplication.getId(),invoiceApplication.getStockId(), order.getMaterialId(),invoiceRequestJson.getCustomerId());
            if (order.getApprovalNumber() > stock+order.getApprovalNumber()) {
                throw new RemoteServiceException(order.getMaterialName()+order.getSpecification() + "库存不足");
            }

            InvoiceApplicationOrder invoiceApplicationOrder = invoiceApplicationOrderService.getById(order.getId());
            order.setRefundableQty(order.getApprovalNumber());

            order.setPayAmount(invoiceApplicationOrder.getSinglePayPrice()
                    .multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));

            order.setTotalAmount(invoiceApplicationOrder.getPrice().multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));

            order.setPayRebateAmount(invoiceApplicationOrder.getSingleRebateAmount().multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));

            order.setTotalDiscAmount(invoiceApplicationOrder.getDiscAmount().multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));

            order.setAfterTaxPrice(invoiceApplicationOrder.getSinglePayPrice().subtract(invoiceApplicationOrder.getSinglePayPrice().multiply(invoiceApplicationOrder.getTax())));
            order.setNoTotalAmount(order.getPayAmount().subtract(order.getPayAmount().multiply(invoiceApplicationOrder.getTax())));
            invoiceApplicationOrderService.updateById(order);
        }
        if (invoiceRequestJson.getExamineStatus().equals("SAVE"))
            return;

        //生成发货单
        ShipDocument shipDocument = BeanUtil.toBean(invoiceApplication, ShipDocument.class);
        shipDocument.setExamineStatus(ExamineStatusEnum.OK.toString());
        shipDocument.insert();
        //生成销售出库单
        //生成订单流水号
        String yyyyMM = DateUtil.format(new Date(), "yyyyMM");
        String orderWater = yyyyMM.substring(yyyyMM.length() - 4);
        if (redisUtil.get("sales" + orderWater) == null) {
            redisUtil.set("sales" + orderWater, "0000", 60 * 60 * 24 * 31);
        }
        Object water = redisUtil.get("sales" + orderWater);
        String s = pickLogic.generateNum(4, Convert.toStr(water));

        if (salesOrderService.lambdaQuery().eq(SalesOrder::getId, orderWater + s).count() > 0) {
            throw new RemoteServiceException("请勿频繁新增，稍等一会");
        }
        redisUtil.set("sales" + orderWater, s, 60 * 60 * 24 * 31);


        SalesOrder salesOrder = BeanUtil.toBean(invoiceApplication, SalesOrder.class);
        salesOrder.setId(orderWater + s);

        invoiceRequestJson.setSalesId(orderWater + s);
        invoiceRequestJson.setSalesOrderId(orderWater + s);
        invoiceRequestJson.updateById();

        salesOrder.setOrderNo(invoiceApplication.getId());
        salesOrder.setOrderTime(new Date());
        salesOrder.setExamineStatus("WAIT");
        salesOrder.setType(1);
        salesOrder.setInvoiceType(3);
        salesOrder.insert();
        List<InvoiceApplicationOrder> list = invoiceApplicationOrderService.lambdaQuery().eq(InvoiceApplicationOrder::getInvoiceId, invoiceApplication.getId()).list();
        List<SalesOrderItem> salesOrders = new ArrayList<>();
        for (InvoiceApplicationOrder invoiceApplicationOrder : list) {
            SalesOrderItem salesOrderItem = BeanUtil.toBean(invoiceApplicationOrder, SalesOrderItem.class);
            salesOrderItem.setId(null);
            salesOrderItem.setSalesOrderNo(salesOrder.getId());
            salesOrderItem.setInvoiceItemId(invoiceApplicationOrder.getId());
            salesOrderItem.setFileNo(invoiceApplicationOrder.getFileNo());
            salesOrders.add(salesOrderItem);
        }
        salesOrderItemService.saveBatch(salesOrders);

        for (InvoiceApplicationOrderRequest order : invoiceRequestJson.getOrders()) {

            //增加经销商暂扣库存
            if (order.getRefundableQty() - order.getInvoiceNum() >= 0) {
                stockCommonLogic.inventoryStockCustomerSuspended(order.getMaterialId(), invoiceApplication.getCustomerId(), order.getRefundableQty());
            } else {
                stockCommonLogic.reduceStockCustomerSuspended(order.getMaterialId(), invoiceApplication.getCustomerId(), order.getInvoiceNum() - order.getRefundableQty());
            }

            //变更可退货数量
            //变更可退货数量
            if (order.getOrderType().equals("RETAIL") || order.getOrderType().equals("RETAIL_POLICY"))
                retailOrderLogic.changeRefundableQty(order.getOrderId(), order.getApprovalNumber());

            if (order.getOrderType().equals("PERMU_RETAIL") || order.getOrderType().equals("PERMU_RETAIL_POLICY"))
                changeDiplaceRefundableQty(order.getOrderId(), order.getApprovalNumber());

            if (order.getOrderType().equals("REQUISITION_RETAIL") || order.getOrderType().equals("REQUISITION_RETAIL_POLICY"))
                invoiceLogic.changeRqquisitionEnginRefundableQty(order.getRequisitionItemId(), order.getApprovalNumber());
            //变更可退货数量
            if (order.getOrderType().equals("TRADE") || order.getOrderType().equals("HOME"))
                changeEnginRefundableQty(order.getOrderId(), order.getApprovalNumber());

            //记录台账记录
            String customerWalletId = null;
            if (order.getOrderType().equals("RETAIL") || order.getOrderType().equals("RETAIL_POLICY")) {
                RetailOrderItem retailOrderItem = retailOrderItemService.getById(order.getOrderId());
                if (retailOrderItem.getRefundableQty().equals("0") && retailOrderItem.getIsDirectTransfer() == false) {
                    order.setPayAmount(
                            retailOrderItem.getPayAmount().subtract(new BigDecimal((retailOrderItem.getHasSendQty() - retailOrderItem.getDirectTransferQty())).multiply(retailOrderItem.getSinglePayPrice())));
                }
                customerWalletId = retailOrderItem.getCustomerWalletId();
            }

            if (order.getOrderType().equals("PERMU_RETAIL") || order.getOrderType().equals("PERMU_RETAIL_POLICY")) {
                DisplaceOrderItem displaceOrderItem = displaceOrderItemService.getById(order.getOrderId());
                if (displaceOrderItem.getRefundableQty().equals("0")) {
                    order.setPayAmount(
                            displaceOrderItem.getPayAmount().subtract(new BigDecimal((displaceOrderItem.getHasSendQty())).multiply(displaceOrderItem.getSinglePayPrice())));
                }
                customerWalletId = displaceOrderItem.getCustomerWalletId();
            }

            if (order.getOrderType().equals("REQUISITION_RETAIL") || order.getOrderType().equals("REQUISITION_RETAIL_POLICY")) {
                RequisitionOrderItem requisitionOrderItem = requisitionOrderItemService.getById(order.getRequisitionItemId());
                if (requisitionOrderItem.getRefundableQty().equals("0")) {
                    order.setPayAmount(
                            requisitionOrderItem.getPayAmount().subtract(new BigDecimal((requisitionOrderItem.getHasSendQty())).multiply(requisitionOrderItem.getSinglePayPrice())));
                }
                customerWalletId = requisitionOrderItem.getCustomerWalletId();
            }
            CustomerWallet customerWallet = customerWalletService.getById(customerWalletId);
            walletLogic.saveCustomerWalletRecord(customerWallet, order.getPayAmount(), "直调申请发货单流水", "申请发货单", new Date(), invoiceRequestJson.getId(), 3, "OUT");

            order.updateById();
        }


        //格匠同步采购入库单
        if (invoiceApplication.getCustomerNumber().equals(InvoiceCustomerEnum.GEJIANG_FOSHAN.getCode()) ||
                invoiceApplication.getCustomerNumber().equals(InvoiceCustomerEnum.GEJIANG_GUANGZHOU.getCode())){
            InvoiceApplication invoiceApplication1 = new InvoiceApplication();
            invoiceApplication1.setId(invoiceApplication.getId());
            invoiceApplication1.setGejiangSync(0);
            invoiceApplication1.updateById();
            InvoiceApplicationSyncGejiang invoiceApplicationSyncGejiang = new InvoiceApplicationSyncGejiang();
            invoiceApplicationSyncGejiang.setInvoiceId(invoiceApplication.getId());
            invoiceApplicationSyncGejiang.setStatus(0);
            invoiceApplicationSyncGejiang.insert();
        }

        invoiceMapper.updateStatus(invoiceApplication.getId());
        invoiceMapper.updateInvoice(invoiceApplication.getId());
        invoiceMapper.updateTaiZhang(invoiceApplication.getId());
        invoiceMapper.updateWithold(invoiceApplication.getId(),Constant.RETAIL_UPDATE);
    }

    @Transactional(rollbackFor = Exception.class)
    public void approvalInvoiceRak(InvoiceApplication invoiceApplicationRequest, HttpServletRequest request, String examineStatus, String approvalRemark) throws Exception {
        //保存申请发货单
        InvoiceApplication invoiceApplication = invoiceApplicationService.getById(invoiceApplicationRequest.getId());
        if (!invoiceApplication.getExamineStatus().equals(ExamineStatusEnum.WAIT.toString())) {
            throw new RemoteServiceException("非审核单，无法审核");
        }
        if (StringUtils.isNotBlank(invoiceApplication.getEnginOrderType())) {
            approvalInvoiceProjecRak(invoiceApplicationRequest, examineStatus, approvalRemark);
            return;
        }

        AdminUserCom adminUser = commonLogic.getAdminUser(request);

        invoiceApplicationRequest.setApprovalName(adminUser.getNickName());
        invoiceApplicationRequest.setApprovalTime(new Date());
        invoiceApplicationRequest.setApprovalRemark(approvalRemark);
        invoiceApplicationRequest.setExamineStatus(examineStatus);
        invoiceApplicationService.updateById(invoiceApplicationRequest);
        List<InvoiceApplicationOrder> list = invoiceApplicationOrderService.lambdaQuery().eq(InvoiceApplicationOrder::getInvoiceId, invoiceApplication.getId()).list();
        for (InvoiceApplicationOrder order : list) {
            order.setApprovalNumber(order.getRefundableQty());
            if (order.getApprovalNumber() == null)
                throw new RemoteServiceException("审批数量不能为空");

            //判断库存是否足够
            Integer stock = stockCommonLogic.stockVirtualStatus(invoiceApplication.getCorrespondId(),invoiceApplication.getStockId(), order.getMaterialId(),invoiceApplicationRequest.getCustomerId());
            if (order.getApprovalNumber() > stock) {
                throw new RemoteServiceException(order.getMaterialName() +order.getSpecification()+ "库存不足");
            }

            InvoiceApplicationOrder invoiceApplicationOrder = invoiceApplicationOrderService.getById(order.getId());
            order.setRefundableQty(order.getApprovalNumber());
            order.setApprovalNumber(order.getRefundableQty());
            order.setVarietyQty(order.getApprovalNumber());
            order.setPayAmount(invoiceApplicationOrder.getSinglePayPrice()
                    .multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));

            order.setTotalAmount(invoiceApplicationOrder.getPrice().multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));

            order.setPayRebateAmount(invoiceApplicationOrder.getSingleRebateAmount().multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));

            order.setTotalDiscAmount(invoiceApplicationOrder.getDiscAmount().multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));

            order.setAfterTaxPrice(invoiceApplicationOrder.getSinglePayPrice().subtract(invoiceApplicationOrder.getSinglePayPrice().multiply(invoiceApplicationOrder.getTax())));
            order.setNoTotalAmount(order.getPayAmount().subtract(order.getPayAmount().multiply(invoiceApplicationOrder.getTax())));
            invoiceApplicationOrderService.updateById(order);
        }
        if (examineStatus.equals(ExamineStatusEnum.SAVE.toString()))
            return;

        //生成发货单
        ShipDocument shipDocument = BeanUtil.toBean(invoiceApplication, ShipDocument.class);
        shipDocument.setExamineStatus(ExamineStatusEnum.OK.toString());
        shipDocument.insert();
        //生成销售出库单
        //生成订单流水号
        String yyyyMM = DateUtil.format(new Date(), "yyyyMM");
        String orderWater = yyyyMM.substring(yyyyMM.length() - 4);
        if (redisUtil.get("sales" + orderWater) == null) {
            redisUtil.set("sales" + orderWater, "0000", 60 * 60 * 24 * 31);
        }
        Object water = redisUtil.get("sales" + orderWater);
        String s = pickLogic.generateNum(4, Convert.toStr(water));

        if (salesOrderService.lambdaQuery().eq(SalesOrder::getId, orderWater + s).count() > 0) {
            throw new RemoteServiceException("请勿频繁新增，稍等一会");
        }
        redisUtil.set("sales" + orderWater, s, 60 * 60 * 24 * 31);

        //格匠同步采购入库单
        if (invoiceApplication.getCustomerNumber().equals(InvoiceCustomerEnum.GEJIANG_FOSHAN.getCode()) ||
                invoiceApplication.getCustomerNumber().equals(InvoiceCustomerEnum.GEJIANG_GUANGZHOU.getCode())){
            InvoiceApplication invoiceApplication1 = new InvoiceApplication();
            invoiceApplication1.setId(invoiceApplication.getId());
            invoiceApplication1.setGejiangSync(0);
            invoiceApplication1.updateById();
            InvoiceApplicationSyncGejiang invoiceApplicationSyncGejiang = new InvoiceApplicationSyncGejiang();
            invoiceApplicationSyncGejiang.setInvoiceId(invoiceApplication.getId());
            invoiceApplicationSyncGejiang.setStatus(0);
            invoiceApplicationSyncGejiang.insert();
        }

        SalesOrder salesOrder = BeanUtil.toBean(invoiceApplication, SalesOrder.class);
        salesOrder.setId(orderWater + s);

        invoiceApplicationRequest.setSalesId(orderWater + s);
        invoiceApplicationRequest.setSalesOrderId(orderWater + s);
        invoiceApplicationRequest.updateById();

        salesOrder.setOrderNo(invoiceApplication.getId());
        salesOrder.setOrderTime(new Date());
        salesOrder.setExamineStatus("WAIT");
        salesOrder.setType(1);
        salesOrder.setInvoiceType(3);
        salesOrder.insert();
        List<SalesOrderItem> salesOrders = new ArrayList<>();
        for (InvoiceApplicationOrder invoiceApplicationOrder : list) {
            SalesOrderItem salesOrderItem = BeanUtil.toBean(invoiceApplicationOrder, SalesOrderItem.class);
            salesOrderItem.setId(null);
            salesOrderItem.setSalesOrderNo(salesOrder.getId());
            salesOrderItem.setInvoiceItemId(invoiceApplicationOrder.getId());
            salesOrderItem.setFileNo(invoiceApplicationOrder.getFileNo());
            salesOrders.add(salesOrderItem);
        }
        salesOrderItemService.saveBatch(salesOrders);

        for (InvoiceApplicationOrder order : list) {

            //增加经销商暂扣库存
            if (order.getRefundableQty() - order.getInvoiceNum() >= 0) {
                stockCommonLogic.inventoryStockCustomerSuspended(order.getMaterialId(), invoiceApplication.getCustomerId(), order.getRefundableQty());
            } else {
                stockCommonLogic.reduceStockCustomerSuspended(order.getMaterialId(), invoiceApplication.getCustomerId(), order.getInvoiceNum() - order.getRefundableQty());
            }

            //变更可退货数量
            //变更可退货数量
            if (order.getOrderType().equals("RETAIL") || order.getOrderType().equals("RETAIL_POLICY"))
                retailOrderLogic.changeRefundableQty(order.getOrderId(), order.getApprovalNumber());

            if (order.getOrderType().equals("PERMU_RETAIL") || order.getOrderType().equals("PERMU_RETAIL_POLICY"))
                changeDiplaceRefundableQty(order.getOrderId(), order.getApprovalNumber());

            if (order.getOrderType().equals("REQUISITION_RETAIL") || order.getOrderType().equals("REQUISITION_RETAIL_POLICY"))
                invoiceLogic.changeRqquisitionEnginRefundableQty(order.getRequisitionItemId(), order.getApprovalNumber());
            //变更可退货数量
            if (order.getOrderType().equals("TRADE") || order.getOrderType().equals("HOME"))
                changeEnginRefundableQty(order.getOrderId(), order.getApprovalNumber());

            //记录台账记录
            String customerWalletId = null;
            if (order.getOrderType().equals("RETAIL") || order.getOrderType().equals("RETAIL_POLICY")) {
                RetailOrderItem retailOrderItem = retailOrderItemService.getById(order.getOrderId());
                if (retailOrderItem.getRefundableQty().equals("0") && retailOrderItem.getIsDirectTransfer() == false) {
                    order.setPayAmount(
                            retailOrderItem.getPayAmount().subtract(new BigDecimal((retailOrderItem.getHasSendQty() - retailOrderItem.getDirectTransferQty())).multiply(retailOrderItem.getSinglePayPrice())));
                }
                customerWalletId = retailOrderItem.getCustomerWalletId();
            }

            if (order.getOrderType().equals("PERMU_RETAIL") || order.getOrderType().equals("PERMU_RETAIL_POLICY")) {
                DisplaceOrderItem displaceOrderItem = displaceOrderItemService.getById(order.getOrderId());
                if (displaceOrderItem.getRefundableQty().equals("0")) {
                    order.setPayAmount(
                            displaceOrderItem.getPayAmount().subtract(new BigDecimal((displaceOrderItem.getHasSendQty())).multiply(displaceOrderItem.getSinglePayPrice())));
                }
                customerWalletId = displaceOrderItem.getCustomerWalletId();
            }

            if (order.getOrderType().equals("REQUISITION_RETAIL") || order.getOrderType().equals("REQUISITION_RETAIL_POLICY")) {
                RequisitionOrderItem requisitionOrderItem = requisitionOrderItemService.getById(order.getRequisitionItemId());
                if (requisitionOrderItem.getRefundableQty().equals("0")) {
                    order.setPayAmount(
                            requisitionOrderItem.getPayAmount().subtract(new BigDecimal((requisitionOrderItem.getHasSendQty())).multiply(requisitionOrderItem.getSinglePayPrice())));
                }
                customerWalletId = requisitionOrderItem.getCustomerWalletId();
            }
            CustomerWallet customerWallet = customerWalletService.getById(customerWalletId);
            walletLogic.saveCustomerWalletRecord(customerWallet, order.getPayAmount(), "直调申请发货单流水", "申请发货单", new Date(), invoiceApplicationRequest.getId(), 3, "OUT");

            order.updateById();

        }

        //格匠同步采购入库单
        if (invoiceApplication.getCustomerNumber().equals(InvoiceCustomerEnum.GEJIANG_FOSHAN.getCode()) ||
                invoiceApplication.getCustomerNumber().equals(InvoiceCustomerEnum.GEJIANG_GUANGZHOU.getCode())){
            InvoiceApplication invoiceApplication1 = new InvoiceApplication();
            invoiceApplication1.setId(invoiceApplication.getId());
            invoiceApplication1.setGejiangSync(0);
            invoiceApplication1.updateById();
            InvoiceApplicationSyncGejiang invoiceApplicationSyncGejiang = new InvoiceApplicationSyncGejiang();
            invoiceApplicationSyncGejiang.setInvoiceId(invoiceApplication.getId());
            invoiceApplicationSyncGejiang.setStatus(0);
            invoiceApplicationSyncGejiang.insert();
        }

        invoiceMapper.updateStatus(invoiceApplication.getId());
        invoiceMapper.updateInvoice(invoiceApplication.getId());
    }

    /**
     * 更变可退货数量 -扣除
     *
     * @param orderId 明细id
     * @param qty     数量
     */
    public void changeEnginRefundableQty(String orderId, Integer qty) {
        EnginOrderItem enginOrderItem = enginOrderItemService.getById(orderId);
        if (enginOrderItem == null) {
            return;
        }
        if (enginOrderItem.getRefundableQty().intValue() < qty.intValue()) {
            throw new RemoteServiceException("可退货数量不足!");
        }
        enginOrderItem.setRefundableQty(enginOrderItem.getRefundableQty() - qty);
        enginOrderItem.updateById();
    }

    /**
     * 扣除置换单数量
     */
    public void changeDiplaceRefundableQty(String orderId, Integer qty) {
        DisplaceOrderItem displaceOrderItem = displaceOrderItemService.getById(orderId);
        if (displaceOrderItem == null) {
            return;
        }
        if (displaceOrderItem.getRefundableQty().intValue() < qty.intValue()) {
            throw new RemoteServiceException("可退货数量不足!");
        }
        displaceOrderItem.setRefundableQty(displaceOrderItem.getRefundableQty() - qty);
        displaceOrderItem.updateById();
    }

    public void changeRqquisitionRefundableQty(String orderId, Integer approvalNumber) {
        RequisitionOrderItem requisitionOrderItem = requisitionOrderItemService.getById(orderId);
        if (requisitionOrderItem == null) {
            return;
        }
        if (requisitionOrderItem.getRefundableQty().intValue() < approvalNumber.intValue()) {
            throw new RemoteServiceException("可退货数量不足!");
        }
        requisitionOrderItem.setRefundableQty(requisitionOrderItem.getRefundableQty() - approvalNumber);
        requisitionOrderItem.updateById();
    }


    @Transactional(rollbackFor = Exception.class)
    public void approvalInvoiceProjecRak(InvoiceRequestJson invoiceRequestJson) throws InterruptedException {
        //保存申请发货单
        AdminUserCom adminUser = commonLogic.getAdminUser();

        InvoiceApplication invoiceApplication = invoiceApplicationService.getById(invoiceRequestJson.getId());

        //修改订单
        invoiceRequestJson.setApprovalName(adminUser.getNickName());
        invoiceRequestJson.setApprovalTime(new Date());
        invoiceApplicationService.updateById(invoiceRequestJson);

        for (InvoiceApplicationOrderRequest order : invoiceRequestJson.getOrders()) {
            InvoiceApplicationOrder invoiceApplicationOrder = invoiceApplicationOrderService.getById(order.getId());
            if (order.getApprovalNumber() != null) {
                order.setRefundableQty(order.getApprovalNumber());
            }else {
                order.setApprovalNumber(order.getRefundableQty());
            }

            order.setPayAmount(invoiceApplicationOrder.getSinglePayPrice()
                    .multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));

            order.setTotalAmount(invoiceApplicationOrder.getPrice().multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));

            order.setPayRebateAmount(invoiceApplicationOrder.getSingleRebateAmount().multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));

            order.setTotalDiscAmount(invoiceApplicationOrder.getDiscAmount().multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));

            order.setAfterTaxPrice(invoiceApplicationOrder.getPrice().subtract(invoiceApplicationOrder.getPrice().multiply(invoiceApplicationOrder.getTax())));
            order.setNoTotalAmount(order.getPayAmount().subtract(order.getPayAmount().multiply(invoiceApplicationOrder.getTax())));

            //判断库存是否足够
            Integer stock = stockCommonLogic.stockVirtualStatus(invoiceApplication.getCorrespondId(),invoiceApplication.getStockId(), order.getMaterialId(),invoiceRequestJson.getCustomerId());
            if (order.getApprovalNumber() > stock) {
                throw new RemoteServiceException(order.getMaterialName()+order.getSpecification() + "库存不足");
            }
            invoiceApplicationOrderService.updateById(order);
        }

        if (invoiceRequestJson.getExamineStatus().equals(ExamineStatusEnum.SAVE.toString()))
            return;


        //生成发货单
        ShipDocument shipDocument = BeanUtil.toBean(invoiceApplication, ShipDocument.class);

        shipDocument.setExamineStatus(ExamineStatusEnum.OK.toString());
        shipDocument.insert();


        //生成销售出库单
        String yyyyMM = DateUtil.format(new Date(), "yyyyMM");
        String orderWater = yyyyMM.substring(yyyyMM.length() - 4);
        if (redisUtil.get("sales" + orderWater) == null) {
            redisUtil.set("sales" + orderWater, "0000", 60 * 60 * 24 * 31);
        }
        Object water = redisUtil.get("sales" + orderWater);
        String s = pickLogic.generateNum(4, Convert.toStr(water));

        if (salesOrderService.lambdaQuery().eq(SalesOrder::getId, orderWater + s).count() > 0) {
            throw new RemoteServiceException("请勿频繁新增，稍等一会");
        }
        redisUtil.set("sales" + orderWater, s, 60 * 60 * 24 * 31);


        invoiceRequestJson.setSalesId(orderWater + s);
        invoiceRequestJson.setSalesOrderId(orderWater + s);
        invoiceRequestJson.updateById();


        SalesOrder salesOrder = BeanUtil.toBean(invoiceApplication, SalesOrder.class);
        salesOrder.setId(orderWater + s);
        salesOrder.setOrderNo(invoiceApplication.getId());
        salesOrder.setOrderTime(new Date());
        salesOrder.setType(1);
        salesOrder.setInvoiceType(3);
        salesOrder.setExamineStatus(ExamineStatusEnum.WAIT.toString());
        salesOrder.insert();
        List<InvoiceApplicationOrder> list = invoiceApplicationOrderService.lambdaQuery().eq(InvoiceApplicationOrder::getInvoiceId, invoiceApplication.getId()).list();
        List<SalesOrderItem> salesOrders = new ArrayList<>();
        for (InvoiceApplicationOrder invoiceApplicationOrder : list) {
            SalesOrderItem salesOrderItem = BeanUtil.toBean(invoiceApplicationOrder, SalesOrderItem.class);
            salesOrderItem.setSalesOrderNo(salesOrder.getId());
            salesOrderItem.setInvoiceItemId(invoiceApplicationOrder.getId());
            salesOrders.add(salesOrderItem);
        }
        salesOrderItemService.saveBatch(salesOrders);


        List<DepositManageRecordBean> depositManageRecordList = new ArrayList<>();
        for (InvoiceApplicationOrderRequest order : invoiceRequestJson.getOrders()) {
            //增加经销商暂扣库存
            if (order.getRefundableQty() - order.getInvoiceNum() >= 0) {
                stockCommonLogic.inventoryStockCustomerSuspended(order.getMaterialId(), invoiceApplication.getCustomerId(), order.getRefundableQty());
            } else {
                stockCommonLogic.reduceStockCustomerSuspended(order.getMaterialId(), invoiceApplication.getCustomerId(), order.getInvoiceNum() - order.getRefundableQty());
            }


            //记录台账记录
            String customerWalletId = null;
            if (order.getOrderType().equals("HOME") || order.getOrderType().equals("TRADE")) {
                EnginOrderItem engin = enginOrderItemService.getById(order.getOrderId());
                if (engin.getRefundableQty().equals("0") && engin.getIsDirectTransfer() == false) {
                    order.setPayAmount(
                            engin.getPayAmount().subtract(new BigDecimal((engin.getHasSendQty() - engin.getDirectTransferQty())).multiply(engin.getSinglePayPrice())));
                }
    /*            engin.setRefundProductQty(-1 * order.getRefundableQty());
                BigDecimal tdQty = BigDecimal.valueOf(-1 * order.getRefundableQty());
                engin.setRefundProductAmount(engin.getSinglePayPrice().multiply(tdQty));
                engin.updateById();*/
                customerWalletId = engin.getCustomerWalletId();
            }
            if (order.getOrderType().equals("PERMU_TRADE") || order.getOrderType().equals("PERMU_HOME")) {
                DisplaceOrderItem displaceOrderItem = displaceOrderItemService.getById(order.getOrderId());
                if (displaceOrderItem.getRefundableQty().equals("0")) {
                    order.setPayAmount(
                            displaceOrderItem.getPayAmount().subtract(new BigDecimal((displaceOrderItem.getHasSendQty())).multiply(displaceOrderItem.getSinglePayPrice())));
                }
                customerWalletId = displaceOrderItem.getCustomerWalletId();
            }

            if (order.getOrderType().equals("REQUISITION_TRADE") || order.getOrderType().equals("REQUISITION_HOME")) {
                RequisitionOrderItem requisitionOrderItem = requisitionOrderItemService.getById(order.getOrderId());
                if (requisitionOrderItem.getRefundableQty().equals("0")) {
                    order.setPayAmount(
                            requisitionOrderItem.getPayAmount().subtract(new BigDecimal((requisitionOrderItem.getHasSendQty())).multiply(requisitionOrderItem.getSinglePayPrice())));
                }
  /*              requisitionOrderItem.setRefundProductQty(-1 * order.getRefundableQty());
                BigDecimal tdQty = BigDecimal.valueOf(-1 * order.getRefundableQty());
                requisitionOrderItem.setRefundProductAmount(requisitionOrderItem.getSinglePayPrice().multiply(tdQty));
                requisitionOrderItem.updateById();*/
                customerWalletId = requisitionOrderItem.getCustomerWalletId();
            }
            CustomerWallet customerWallet = customerWalletService.getById(customerWalletId);
            walletLogic.saveCustomerWalletRecord(customerWallet, order.getPayAmount(), "工程申请发货单流水", "申请发货单", new Date(), invoiceRequestJson.getId(), 3, "OUT");


            //变更可退货数量
            if (order.getOrderType().equals("RETAIL") || order.getOrderType().equals("RETAIL_POLICY"))
                retailOrderLogic.changeRefundableQty(order.getOrderId(), order.getApprovalNumber());

            if (order.getOrderType().equals("PERMU_RETAIL") || order.getOrderType().equals("PERMU_RETAIL_POLICY"))
                changeDiplaceRefundableQty(order.getOrderId(), order.getApprovalNumber());

            if (order.getOrderType().equals("REQUISITION_RETAIL") || order.getOrderType().equals("REQUISITION_RETAIL_POLICY"))
                changeRqquisitionRefundableQty(order.getOrderId(), order.getApprovalNumber());
            //变更可退货数量
            if (order.getOrderType().equals("TRADE") || order.getOrderType().equals("HOME"))
                changeEnginRefundableQty(order.getOrderId(), order.getApprovalNumber());

            //工程扣除押金

            EnginOrderItem orderItem = enginOrderItemService.getById(order.getOrderId());
            EnginOrder enginOrder = enginOrderService.getById(orderItem.getParentId());
       /*     if (order.getOrderType().equals("HOME") || order.getOrderType().equals("PERMU_HOME")) {
                DepositManageRecordBean depositManageRecordBean = new DepositManageRecordBean();
                enginOrder.setEnginOrderNo(invoiceApplication.getId());
                enginOrder.setOrderDate(invoiceApplication.getOrderTime());
                depositManageRecordBean.handleEnginOrderItem(enginOrder, orderItem, order.getRefundableQty(), orderItem.getSingleDepositAmount().multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));
                depositManageRecordList.add(depositManageRecordBean);
            }*/
        }
        //格匠同步采购入库单
        if (invoiceApplication.getCustomerNumber().equals(InvoiceCustomerEnum.GEJIANG_FOSHAN.getCode()) ||
                invoiceApplication.getCustomerNumber().equals(InvoiceCustomerEnum.GEJIANG_GUANGZHOU.getCode())){
            InvoiceApplication invoiceApplication1 = new InvoiceApplication();
            invoiceApplication1.setId(invoiceApplication.getId());
            invoiceApplication1.setGejiangSync(0);
            invoiceApplication1.updateById();
            InvoiceApplicationSyncGejiang invoiceApplicationSyncGejiang = new InvoiceApplicationSyncGejiang();
            invoiceApplicationSyncGejiang.setInvoiceId(invoiceApplication.getId());
            invoiceApplicationSyncGejiang.setStatus(0);
            invoiceApplicationSyncGejiang.insert();
        }

        invoiceMapper.updateInvoice(invoiceApplication.getId());
        invoiceMapper.updateStatus(invoiceApplication.getId());
        invoiceMapper.updateSalseOrderId(invoiceApplication.getId());
        invoiceMapper.updateTaiZhang(invoiceApplication.getId());
        invoiceMapper.updateWithold(invoiceApplication.getId(),Constant.ENGIN_UPDATE);
        /*depositManageLogic.addDepositAmount(invoiceApplication.getRefEnginRecordNo(), depositManageRecordList);*/
    }

    @Transactional(rollbackFor = Exception.class)
    public void approvalInvoiceProjecRak(InvoiceApplication invoiceApplicationRequest, String examineStatus, String approvalRemark) throws Exception {
        //保存申请发货单
        AdminUserCom adminUser = commonLogic.getAdminUser();

        InvoiceApplication invoiceApplication = invoiceApplicationService.getById(invoiceApplicationRequest.getId());

        //修改订单
        invoiceApplicationRequest.setApprovalName(adminUser.getNickName());
        invoiceApplicationRequest.setApprovalTime(new Date());
        invoiceApplicationService.updateById(invoiceApplicationRequest);
        List<InvoiceApplicationOrder> list = invoiceApplicationOrderService.lambdaQuery().eq(InvoiceApplicationOrder::getInvoiceId, invoiceApplication.getId()).list();
        for (InvoiceApplicationOrder order : list) {
            InvoiceApplicationOrder invoiceApplicationOrder = invoiceApplicationOrderService.getById(order.getId());
            order.setRefundableQty(order.getApprovalNumber());

            order.setPayAmount(invoiceApplicationOrder.getSinglePayPrice()
                    .multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));

            order.setTotalAmount(invoiceApplicationOrder.getPrice().multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));

            order.setPayRebateAmount(invoiceApplicationOrder.getSingleRebateAmount().multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));

            order.setTotalDiscAmount(invoiceApplicationOrder.getDiscAmount().multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));

            order.setAfterTaxPrice(invoiceApplicationOrder.getPrice().subtract(invoiceApplicationOrder.getPrice().multiply(invoiceApplicationOrder.getTax())));
            order.setNoTotalAmount(order.getPayAmount().subtract(order.getPayAmount().multiply(invoiceApplicationOrder.getTax())));

            //判断库存是否足够
            Integer stock = stockCommonLogic.stockVirtualStatus(invoiceApplication.getCorrespondId(),invoiceApplication.getStockId(), order.getMaterialId(),invoiceApplicationRequest.getCustomerId());
            if (order.getApprovalNumber() > stock) {
                throw new RemoteServiceException(order.getMaterialName() +order.getSpecification()+ "库存不足");
            }
            invoiceApplicationOrderService.updateById(order);
        }

        if (invoiceApplicationRequest.getExamineStatus().equals(ExamineStatusEnum.SAVE.toString()))
            return;


        //生成发货单
        ShipDocument shipDocument = BeanUtil.toBean(invoiceApplication, ShipDocument.class);

        shipDocument.setExamineStatus(ExamineStatusEnum.OK.toString());
        shipDocument.insert();


        //生成销售出库单
        String yyyyMM = DateUtil.format(new Date(), "yyyyMM");
        String orderWater = yyyyMM.substring(yyyyMM.length() - 4);
        if (redisUtil.get("sales" + orderWater) == null) {
            redisUtil.set("sales" + orderWater, "0000", 60 * 60 * 24 * 31);
        }
        Object water = redisUtil.get("sales" + orderWater);
        String s = pickLogic.generateNum(4, Convert.toStr(water));

        if (salesOrderService.lambdaQuery().eq(SalesOrder::getId, orderWater + s).count() > 0) {
            throw new RemoteServiceException("请勿频繁新增，稍等一会");
        }
        redisUtil.set("sales" + orderWater, s, 60 * 60 * 24 * 31);


        invoiceApplicationRequest.setSalesId(orderWater + s);
        invoiceApplicationRequest.setSalesOrderId(orderWater + s);
        invoiceApplicationRequest.updateById();


        SalesOrder salesOrder = BeanUtil.toBean(invoiceApplication, SalesOrder.class);
        salesOrder.setId(orderWater + s);
        salesOrder.setOrderNo(invoiceApplication.getId());
        salesOrder.setOrderTime(new Date());
        salesOrder.setType(1);
        salesOrder.setInvoiceType(3);
        salesOrder.setExamineStatus(ExamineStatusEnum.WAIT.toString());
        salesOrder.insert();
        List<SalesOrderItem> salesOrders = new ArrayList<>();
        for (InvoiceApplicationOrder invoiceApplicationOrder : list) {
            SalesOrderItem salesOrderItem = BeanUtil.toBean(invoiceApplicationOrder, SalesOrderItem.class);
            salesOrderItem.setSalesOrderNo(salesOrder.getId());
            salesOrderItem.setInvoiceItemId(invoiceApplicationOrder.getId());
            salesOrders.add(salesOrderItem);
        }
        salesOrderItemService.saveBatch(salesOrders);


        List<DepositManageRecordBean> depositManageRecordList = new ArrayList<>();
        for (InvoiceApplicationOrder order : list) {
            //增加经销商暂扣库存
            if (order.getRefundableQty() - order.getInvoiceNum() >= 0) {
                stockCommonLogic.inventoryStockCustomerSuspended(order.getMaterialId(), invoiceApplication.getCustomerId(), order.getRefundableQty());
            } else {
                stockCommonLogic.reduceStockCustomerSuspended(order.getMaterialId(), invoiceApplication.getCustomerId(), order.getInvoiceNum() - order.getRefundableQty());
            }


            //记录台账记录
            String customerWalletId = null;
            if (order.getOrderType().equals("HOME") || order.getOrderType().equals("TRADE")) {
                EnginOrderItem engin = enginOrderItemService.getById(order.getOrderId());
                if (engin.getRefundableQty().equals("0") && engin.getIsDirectTransfer() == false) {
                    order.setPayAmount(
                            engin.getPayAmount().subtract(new BigDecimal((engin.getHasSendQty() - engin.getDirectTransferQty())).multiply(engin.getSinglePayPrice())));
                }
    /*            engin.setRefundProductQty(-1 * order.getRefundableQty());
                BigDecimal tdQty = BigDecimal.valueOf(-1 * order.getRefundableQty());
                engin.setRefundProductAmount(engin.getSinglePayPrice().multiply(tdQty));
                engin.updateById();*/
                customerWalletId = engin.getCustomerWalletId();
            }
            if (order.getOrderType().equals("PERMU_TRADE") || order.getOrderType().equals("PERMU_HOME")) {
                DisplaceOrderItem displaceOrderItem = displaceOrderItemService.getById(order.getOrderId());
                if (displaceOrderItem.getRefundableQty().equals("0")) {
                    order.setPayAmount(
                            displaceOrderItem.getPayAmount().subtract(new BigDecimal((displaceOrderItem.getHasSendQty())).multiply(displaceOrderItem.getSinglePayPrice())));
                }
                customerWalletId = displaceOrderItem.getCustomerWalletId();
            }

            if (order.getOrderType().equals("REQUISITION_TRADE") || order.getOrderType().equals("REQUISITION_HOME")) {
                RequisitionOrderItem requisitionOrderItem = requisitionOrderItemService.getById(order.getRequisitionItemId());
                if (requisitionOrderItem.getRefundableQty().equals("0")) {
                    order.setPayAmount(
                            requisitionOrderItem.getPayAmount().subtract(new BigDecimal((requisitionOrderItem.getHasSendQty())).multiply(requisitionOrderItem.getSinglePayPrice())));
                }
  /*              requisitionOrderItem.setRefundProductQty(-1 * order.getRefundableQty());
                BigDecimal tdQty = BigDecimal.valueOf(-1 * order.getRefundableQty());
                requisitionOrderItem.setRefundProductAmount(requisitionOrderItem.getSinglePayPrice().multiply(tdQty));
                requisitionOrderItem.updateById();*/
                customerWalletId = requisitionOrderItem.getCustomerWalletId();
            }
            CustomerWallet customerWallet = customerWalletService.getById(customerWalletId);
            walletLogic.saveCustomerWalletRecord(customerWallet, order.getPayAmount(), "工程申请发货单流水", "申请发货单", new Date(), invoiceApplication.getId(), 3, "OUT");


            //变更可退货数量
            if (order.getOrderType().equals("RETAIL") || order.getOrderType().equals("RETAIL_POLICY"))
                retailOrderLogic.changeRefundableQty(order.getOrderId(), order.getApprovalNumber());

            if (order.getOrderType().equals("PERMU_RETAIL") || order.getOrderType().equals("PERMU_RETAIL_POLICY"))
                changeDiplaceRefundableQty(order.getOrderId(), order.getApprovalNumber());

            if (order.getOrderType().equals("REQUISITION_RETAIL") || order.getOrderType().equals("REQUISITION_RETAIL_POLICY"))
                changeRqquisitionRefundableQty(order.getRequisitionItemId(), order.getApprovalNumber());
            //变更可退货数量
            if (order.getOrderType().equals("TRADE") || order.getOrderType().equals("HOME"))
                changeEnginRefundableQty(order.getOrderId(), order.getApprovalNumber());

            //工程扣除押金

            EnginOrderItem orderItem = enginOrderItemService.getById(order.getOrderId());
            EnginOrder enginOrder = enginOrderService.getById(orderItem.getParentId());
       /*     if (order.getOrderType().equals("HOME") || order.getOrderType().equals("PERMU_HOME")) {
                DepositManageRecordBean depositManageRecordBean = new DepositManageRecordBean();
                enginOrder.setEnginOrderNo(invoiceApplication.getId());
                enginOrder.setOrderDate(invoiceApplication.getOrderTime());
                depositManageRecordBean.handleEnginOrderItem(enginOrder, orderItem, order.getRefundableQty(), orderItem.getSingleDepositAmount().multiply(new BigDecimal(Convert.toStr(order.getRefundableQty()))));
                depositManageRecordList.add(depositManageRecordBean);
            }*/
        }

        //格匠同步采购入库单
        if (invoiceApplication.getCustomerNumber().equals(InvoiceCustomerEnum.GEJIANG_FOSHAN.getCode()) ||
                invoiceApplication.getCustomerNumber().equals(InvoiceCustomerEnum.GEJIANG_GUANGZHOU.getCode())){
            InvoiceApplication invoiceApplication1 = new InvoiceApplication();
            invoiceApplication1.setId(invoiceApplication.getId());
            invoiceApplication1.setGejiangSync(0);
            invoiceApplication1.updateById();
            InvoiceApplicationSyncGejiang invoiceApplicationSyncGejiang = new InvoiceApplicationSyncGejiang();
            invoiceApplicationSyncGejiang.setInvoiceId(invoiceApplication.getId());
            invoiceApplicationSyncGejiang.setStatus(0);
            invoiceApplicationSyncGejiang.insert();
        }

        /*depositManageLogic.addDepositAmount(invoiceApplication.getRefEnginRecordNo(), depositManageRecordList);*/
        invoiceMapper.updateStatus(invoiceApplication.getId());
        invoiceMapper.updateInvoice(invoiceApplication.getId());
    }

    public Boolean ifRak(List<String> id) {
        Boolean ifRak = false;
        for (String s : id) {
            KingDeeMaterial byId = kingDeeMaterialService.getById(s);
            if (byId.getCategoryNumber().equals(Constant.CATEGORY_NUMBER_ONE) || byId.getCategoryNumber().equals(Constant.CATEGORY_NUMBER_TWO)
                    || byId.getCategoryNumber().equals(Constant.CATEGORY_NUMBER_THREE)){
                ifRak= true;
            }
        }
        return ifRak;
    }
}
