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

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 cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zfire.mall.manager.bean.admin.AdminUserCom;
import com.zfire.mall.manager.bean.engin.deposit.DepositManageRecordBean;
import com.zfire.mall.manager.bean.k3.bill.SalesReturnBean;
import com.zfire.mall.manager.bean.k3.bill.SalesReturnItemBean;
import com.zfire.mall.manager.bean.k3.bill.result.BillItem;
import com.zfire.mall.manager.bean.k3.bill.result.ResultEntity;
import com.zfire.mall.manager.bean.sale.SaleOrderBean;
import com.zfire.mall.manager.bean.sale.SaleOrderBody;
import com.zfire.mall.manager.bean.sale.SaleOrderData;
import com.zfire.mall.manager.bean.sale.SaleRetreatOrderBody;
import com.zfire.mall.manager.bean.wallet.CustomerWalletAmountBean;
import com.zfire.mall.manager.commonmapper.InvoiceMapper;
import com.zfire.mall.manager.commonmapper.SaleOrderMapper;
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.invoice.InvoiceLogic;
import com.zfire.mall.manager.logic.k3.K3CustomerLogic;
import com.zfire.mall.manager.logic.k3.K3MaterialLogic;
import com.zfire.mall.manager.logic.k3.bill.GeJiangInStockLogic;
import com.zfire.mall.manager.logic.k3.bill.SalesOrderLogic;
import com.zfire.mall.manager.logic.k3.bill.SalesOutStockLogic;
import com.zfire.mall.manager.logic.k3.bill.SalesReturnLogic;
import com.zfire.mall.manager.logic.pick.PickLogic;
import com.zfire.mall.manager.logic.retail.RetailOrderLogic;
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 lombok.extern.slf4j.Slf4j;
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 org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.stream.Collectors;

/**
 * 销售出库单
 *
 * @author Administrator
 */
@Slf4j
@Service
public class SaleRetreatOrderLogic {

    @Autowired
    SaleOrderMapper saleOrderMapper;

    @Autowired
    RetailOrderLogic retailOrderLogic;

    @Autowired
    SalesOrderService salesOrderService;

    @Autowired
    InvoiceApplicationOrderService invoiceApplicationOrderService;

    @Autowired
    InvoiceApplicationService invoiceApplicationService;

    @Autowired
    EnginOrderService enginOrderService;

    @Autowired
    EnginOrderItemService enginOrderItemService;

    @Autowired
    DisplaceOrderService displaceOrderService;

    @Autowired
    DisplaceOrderItemService displaceOrderItemService;

    @Autowired
    PickManagerShipService pickManagerService;


    @Autowired
    CommonLogic commonLogic;


    @Autowired
    StockCommonLogic stockCommonLogic;

    @Autowired
    SalesOrderLogic salesOrderLogic;

    @Autowired
    K3CustomerLogic k3CustomerLogic;

    @Autowired
    SalesOutStockLogic salesOutStockLogic;

    @Autowired
    StockCorrespondPositionService stockCorrespondPositionService;

    @Autowired
    KingDeeStockService kingDeeStockService;

    @Autowired
    InvoiceLogic invoiceLogic;

    @Autowired
    SalesOrderItemService salesOrderItemService;

    @Autowired
    RedisUtil redisUtil;

    @Autowired
    AdminWebsitService adminWebsitService;

    @Autowired
    PickLogic pickLogic;

    @Autowired
    SalesReturnLogic salesReturnLogic;

    @Autowired
    K3MaterialLogic k3MaterialLogic;


    @Autowired
    RetailOrderItemService retailOrderItemService;

    @Autowired
    EnginInfoOrderItemService enginInfoOrderItemService;

    @Autowired
    RequisitionOrderItemService requisitionOrderItemService;

    @Autowired
    CustomerWalletService customerWalletService;

    @Autowired
    WalletLogic walletLogic;

    @Autowired
    DepositManageLogic depositManageLogic;

    @Autowired
    CustomerProductTypeLogic customerProductTypeLogic;
    @Autowired
    StockService stockService;

    @Autowired
    InvoiceMapper invoiceMapper;


    @Autowired
    OrderExecRecordService orderExecRecordService;

    @Autowired
    RetailOrderService retailOrderService;

    @Autowired
    SalesOrderPictureService salesOrderPictureService;

    @Autowired
    GeJiangInStockLogic geJiangInStockLogic;

    @Autowired
    RedisLockRegistry redisLockRegistry;



    public IPage<SaleOrderBean> salesList(String id,String mainOrderId,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 = saleOrderMapper.listSaleOrder(new Page<>(pageNum, pageSize),id ,mainOrderId,correspondName, materialNumber, orderNo, customerName, correspondId, specification, materialName,
                customerNumber, startTime, endTime, customerId, adminUser.getServiceIds(),adminUser.getK3CategoryIds());
        return list;
    }

    @Transactional(rollbackFor = Exception.class)
    public void add(SaleRetreatOrderBody saleRetreatOrderBody, HttpServletRequest request) {
        //生成销售出库单
        SalesOrder salesOrder = salesOrderService.getById(saleRetreatOrderBody.getId());
        salesOrder.setSalesOrderNo(salesOrder.getId());

        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.setId(orderWater+s);
        salesOrder.setRemark(saleRetreatOrderBody.getRemark());
        salesOrder.setType(2);
        salesOrder.setOrderTime(new Date());
        salesOrder.setExamineStatus("WAIT");
        salesOrder.setCorrespondId(saleRetreatOrderBody.getCorrespondId());
        salesOrder.setCorrespondName(saleRetreatOrderBody.getCorrespondName());
        salesOrder.setFileName(saleRetreatOrderBody.getFileName());
        salesOrder.setFileUrl(saleRetreatOrderBody.getFileUrl());
        salesOrder.setCreateBy(null);
        salesOrder.setCreateTime(null);
        salesOrder.setSyncStatus(null);
        salesOrder.setApprovalName(null);
        salesOrder.setApprovalRemark(null);
        salesOrder.setApprovalTime(null);
        salesOrder.insert();

        List<SalesOrderItem> salesOrders = new ArrayList<>();

        List<String> collect1 = saleRetreatOrderBody.getSaleOrderData().stream().map(SalesOrderItem::getSalesOrderNo).distinct().collect(Collectors.toList());
        if (1 != collect1.size()) {
            throw new RemoteServiceException("退库单销售库存单号需要一致");
        }

        for (SalesOrderItem salesOrderItem : saleRetreatOrderBody.getSaleOrderData()) {
            SalesOrderItem salesOrderItem1 = salesOrderItemService.getById(salesOrderItem.getSalesOrderItemId());
            List<SalesOrderItem> list = salesOrderItemService.lambdaQuery().eq(SalesOrderItem::getSalesOrderItemId, salesOrderItem.getSalesOrderItemId()).list();
            Integer refund = 0;
            if (!CollectionUtils.isEmpty(list))
                refund = list.stream().mapToInt(SalesOrderItem::getRefundableQty).sum();
            if (salesOrderItem1.getRefundableQty() + salesOrderItem.getRefundableQty()+refund < 0)
                throw new RemoteServiceException("数量不能为超过可退货数量");

            salesOrderItem1.setRefundableQty(salesOrderItem.getInvoiceNum());
            salesOrderItem1.setApprovalNumber(salesOrderItem.getInvoiceNum());
            salesOrderItem1.setSinglePayPrice(salesOrderItem1.getSinglePayPrice());
            salesOrderItem1.setServiceId(salesOrderItem1.getServiceId());
            salesOrderItem1.setServiceName(salesOrderItem1.getServiceName());
            salesOrderItem1.setPayAmount(salesOrderItem1.getSinglePayPrice()
                    .multiply(new BigDecimal(Convert.toStr(salesOrderItem1.getRefundableQty()))));

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

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

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

            salesOrderItem1.setAfterTaxPrice(salesOrderItem1.getSinglePayPrice().subtract(salesOrderItem1.getSinglePayPrice().multiply(salesOrderItem1.getTax())));
            salesOrderItem1.setNoTotalAmount(salesOrderItem1.getPayAmount().subtract(salesOrderItem1.getPayAmount().multiply(salesOrderItem1.getTax())));

            salesOrderItem1.setSalesOrderItemId(salesOrderItem1.getId());
            salesOrderItem1.setSalesOrderId(salesOrderItem1.getSalesOrderNo());

            salesOrderItem1.setSalesOrderNo(salesOrder.getId());

            salesOrderItem1.setRequisitionItemId(salesOrderItem1.getRequisitionItemId());
            salesOrderItem1.setRequisitionId(salesOrderItem1.getRequisitionId());
            salesOrderItem1.setK3ServiceName(salesOrderItem1.getK3ServiceName());
            salesOrderItem1.setK3ServiceId(salesOrderItem1.getK3ServiceId());
            salesOrderItem1.setHeaderRemark(salesOrderItem.getHeaderRemark());
            salesOrderItem1.setRemark(salesOrderItem.getRemark());
            salesOrderItem1.setId(null);
            salesOrderItem1.setInvoiceItemId(null);
            salesOrderItem1.setInvoiceId(null);
            salesOrders.add(salesOrderItem1);
        }


        salesOrderItemService.saveBatch(salesOrders);


        for (SalesOrderPicture salesOrderPicture : saleRetreatOrderBody.getSalesOrderPictures()) {
            salesOrderPicture.setSalesId(salesOrder.getId());
        }
        salesOrderPictureService.saveBatch(saleRetreatOrderBody.getSalesOrderPictures());
    }

    @Transactional(rollbackFor = Exception.class)
    public void approval(SalesOrder salesOrder) throws Exception {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        SaleOrderBody detail = saleOrderMapper.detail(salesOrder.getId());
        if (detail.getExamineStatus().equals(ExamineStatusEnum.OK.toString()))
            throw new RemoteServiceException("此订单已审批通过，无法再次审批");

        if (salesOrder.getExamineStatus().equals(ExamineStatusEnum.FAIL.toString())){
            detail.deleteById();
            salesOrderItemService.lambdaUpdate().eq(SalesOrderItem::getSalesOrderNo,detail.getId()).remove();
            return;
        }

        detail.setExamineStatus(salesOrder.getExamineStatus());
        detail.setApprovalRemark(salesOrder.getApprovalRemark());
        detail.setApprovalName(adminUser.getNickName());
        detail.setApprovalTime(new Date());
        detail.updateById();


        if (salesOrder.getExamineStatus().equals(ExamineStatusEnum.OK.toString())) {

            // 同步到金蝶
            List<String> ids = new ArrayList<>();


            //生成订单流水号
            //2，添加发货申请单
            //生成负数已通过申请发货单
            SalesOrder salesOrderInvoice = salesOrderService.getById(detail.getSalesOrderNo());
            InvoiceApplication invoiceApplicationServiceById = invoiceApplicationService.getById(salesOrderInvoice.getOrderNo());

            String substring = detail.getOrderNo().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, detail.getOrderNo().substring(0, 1) + orderWater + s).count() > 0) {
                throw new RemoteServiceException("请勿频繁新增，稍等一会");
            }
            redisUtil.set(Constant.RedisPrefix.INVOICE_APPLICATION + orderWater, s, 2726560);

            invoiceApplicationServiceById.setId(substring + orderWater + s);
            invoiceApplicationServiceById.setExamineStatus(ExamineStatusEnum.OK.toString());
            invoiceApplicationServiceById.setCreateTime(new Date());
            invoiceApplicationServiceById.setApprovalTime(new Date());
            invoiceApplicationServiceById.setOrderTime(new Date());
            invoiceApplicationServiceById.setSalesOrderId(detail.getSalesOrderNo());
            invoiceApplicationServiceById.setSalesId(detail.getId());
            invoiceApplicationServiceById.setType(2);
            invoiceApplicationServiceById.setRemark(detail.getRemark());
            invoiceApplicationServiceById.setCorrespondName(detail.getCorrespondName());
            invoiceApplicationServiceById.setCorrespondId(detail.getCorrespondId());

            invoiceApplicationServiceById.setCreateBy(detail.getCreateBy());
            invoiceApplicationServiceById.setUpdateBy(detail.getUpdateBy());
            invoiceApplicationServiceById.setApprovalName(detail.getApprovalName());
            invoiceApplicationServiceById.setApprovalRemark(detail.getApprovalRemark());
            invoiceApplicationServiceById.setFileUrl(detail.getFileUrl());
            boolean save = invoiceApplicationService.save(invoiceApplicationServiceById);

            invoiceApplicationServiceById.setCreateBy(detail.getCreateBy());
            invoiceApplicationServiceById.setUpdateBy(detail.getUpdateBy());
            invoiceApplicationServiceById.updateById();

            SalesOrder salesOrder1 = new SalesOrder();
            salesOrder1.setId(detail.getId());
            salesOrder1.setOrderNo(invoiceApplicationServiceById.getId());
            salesOrder1.updateById();



            List<InvoiceApplicationOrder> invoiceAp = new ArrayList<>();
            for (SaleOrderData order : detail.getSaleOrderData()) {
                SalesOrderItem salesOrderItem = salesOrderItemService.getById(order.getSalesOrderItemId());
                InvoiceApplicationOrder invoiceApplicationOrder = BeanUtil.toBean(order, InvoiceApplicationOrder.class);
                invoiceApplicationOrder.setId(null);
                invoiceApplicationOrder.setInvoiceId(invoiceApplicationServiceById.getId());
                invoiceApplicationOrder.setSalesOrderItemId(order.getId());
                invoiceApplicationOrder.setFileNo(salesOrderItem.getFileNo());
                invoiceApplicationOrder.setHeaderRemark(salesOrderItem.getHeaderRemark());
                invoiceApplicationOrder.setRemark(salesOrderItem.getRemark());
                invoiceApplicationOrder.setInvoiceNum(salesOrderItem.getRefundableQty());

                ids.add(salesOrderItem.getKingDeeOrderId());

                if (order.getRefundableQty() + salesOrderItem.getRefundableQty() < 0)
                    throw new RemoteServiceException("数量不能为超过可退货数量");
                invoiceApplicationOrderService.save(invoiceApplicationOrder);
                SalesOrderItem salesOrderItem1 = new SalesOrderItem();
                salesOrderItem1.setId(order.getId());
                salesOrderItem1.setInvoiceItemId(invoiceApplicationOrder.getId());
                salesOrderItem1.updateById();

                //记录台账记录
                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()));
                    retailOrderItem.setHasSendQty((retailOrderItem.getHasSendQty()+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()));
                    enginOrderItem.setHasSendQty((enginOrderItem.getHasSendQty()+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("TRADE")) {
                        EnginInfoOrderItem one = enginInfoOrderItemService.lambdaQuery().eq(EnginInfoOrderItem::getEnginInfoNo, enginOrderItem.getRefEnginRecordNo())
                                .eq(EnginInfoOrderItem::getSaleTypeId, enginOrderItem.getSaleTypeId())
                                .eq(EnginInfoOrderItem::getMaterialNumber, enginOrderItem.getMaterialNumber())
                                .one();

                        if (one != null) {
                            one.setHasDeliverQty(one.getHasDeliverQty() + order.getRefundableQty());
                            one.updateById();
                        }
                    }

                }
                } finally {
                    obtain.unlock();
                }


                CustomerWallet customerWallet = customerWalletService.getById(customerWalletId);

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


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

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

                StockCorrespondPosition stockCorrespondPosition = stockCorrespondPositionService.lambdaQuery()
                        .eq(StockCorrespondPosition::getCorrespondId, detail.getCorrespondId())
                        .last("limit 1").one();

                Stock stock = stockService.lambdaQuery().eq(Stock::getMaterialId, order.getMaterialId()).eq(Stock::getStockId, stockCorrespondPosition.getStockId())
                        .last("limit 1").one();

            if (stock != null) {
                stock.setStockQty(stock.getStockQty().add(new BigDecimal(StrUtil.toString(-1 * order.getRefundableQty()))));

                stock.updateById();
            }else {
                Stock stockNew = new Stock();
                stockNew.setStockQty(new BigDecimal(StrUtil.toString(-1 * order.getRefundableQty())));
                stockNew.setMaterialId(order.getMaterialId());
                stockNew.setStockId(stockCorrespondPosition.getStockId());
                stockNew.setSyncTime(new Date());
                stockNew.insert();
            }
            }

            SalesOrderKingSync salesOrderKingSync = new SalesOrderKingSync();
            salesOrderKingSync.setSalesId(salesOrder.getId());
            salesOrderKingSync.insert();




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

            if (CollectionUtils.isEmpty(ids))
                return;

          /*  ResultEntity resultEntity = salesOutStockLogic.pushRet(detail.getSalesOrderNo(), ids);
            // 回填金蝶信息
            for (BillItem item : resultEntity.getItems()) {
                for (InvoiceApplicationOrder invoiceApplicationOrder : detail.getSaleOrderData()) {
                    if (invoiceApplicationOrder.getOrderId().equals(item.getSupplyColVal())) {
                        invoiceApplicationOrder.setKingSaleId(resultEntity.getId());
                        invoiceApplicationOrder.setKingDeeOrderSeq(item.getSeq());
                        invoiceApplicationOrder.setKingDeeOrderId(item.getEntryId());
                        invoiceApplicationOrder.updateById();
                    }
                }
            }
            List<InvoiceApplicationOrder> invoiceApplicationOrders = BeanUtil.copyToList(detail.getSaleOrderData(), InvoiceApplicationOrder.class);
            //金蝶审核成功
            toK3(resultEntity, detail, invoiceApplicationOrders);*/

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


        }
        invoiceMapper.updateStatus(salesOrder.getOrderNo());
        saleOrderMapper.updateInvoice(salesOrder.getId());
        if (!StringUtils.isEmpty(detail.getEnginOrderNo())) {
            invoiceMapper.updateSaleTaiZhang(detail.getId());
            invoiceMapper.updateSaleOrderTaiZhang(detail.getEnginOrderNo());
        }
        orderRefundInsert(detail.getId());
    }


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

        List<SalesOrderItem> list = salesOrderItemService.lambdaQuery().eq(SalesOrderItem::getSalesOrderNo, invoiceApplication.getId()).list();

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

        for (SalesOrderItem invoiceApplicationOrder : list) {

            String orderId = org.apache.commons.lang3.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);
    }



    private void refundRequistion(SaleOrderBody invoiceRequestJson, SaleOrderData 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(),
                    "直接调拨单销售退库单订单返利退款-退货单", invoiceRequestJson.getOrderTime(), order.getOrderId(), 2, "add"));

        }
        // 现金退款
        if (refundPayAmount.doubleValue() > 0) {
            customerWalletAmountBeans.add(new CustomerWalletAmountBean(requisitionOrderItem.getCustomerWalletId(), refundPayAmount, requisitionOrderItem.getRemark(),
                    "直接调拨单销售退库单订单退款-退货单", invoiceRequestJson.getOrderTime(), order.getOrderId(), 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(SaleOrderBody retreatDocumentRequest, SaleOrderData 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(SaleOrderBody retreatDocumentRequest, SaleOrderData 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(), retreatDocumentOrder.getOrderId(), 2, "add"));

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

        walletLogic.doWalletAmount(customerWalletAmountBeans);
    }


    private void toK3(ResultEntity resultEntity, SaleOrderBody detail, List<InvoiceApplicationOrder> invoiceApplicationOrders) {
        SalesReturnBean salesOutStockBean = new SalesReturnBean();
        salesOutStockBean.setBillNo(detail.getId());
        salesOutStockBean.setId(resultEntity.getId());
        salesOutStockBean.setDate(DateUtil.formatDate(detail.getCreateTime()));
        salesOutStockBean.setHeadNote(detail.getRemark());

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

        List<SalesReturnItemBean> salesOutStockItemBeans = new ArrayList<>();
        for (BillItem item : resultEntity.getItems()) {
            for (InvoiceApplicationOrder invoiceApplicationOrder : invoiceApplicationOrders) {
                if (invoiceApplicationOrder.getOrderId().equals(item.getSupplyColVal())) {
                    SalesReturnItemBean salesOutStockItem = new SalesReturnItemBean();


                    CustomerProductTypeRela byCustomerWalletId = customerProductTypeLogic.getByCustomerWalletId(invoiceApplicationOrder.getCustomerWalletId());
                    if (byCustomerWalletId != null && !StringUtils.isEmpty(byCustomerWalletId.getK3OrgNumber()))
                        salesOutStockItem.setKls(byCustomerWalletId.getK3OrgNumber());


                    salesOutStockItem.setEntryId(item.getEntryId());
                    salesOutStockItem.setUnit(k3MaterialLogic.queryUnitCode(kingDeeMaterials, invoiceApplicationOrder.getUnit()));

                    //仓库编码
                    StockCorrespondPosition one = stockCorrespondPositionService.lambdaQuery().eq(StockCorrespondPosition::getCorrespondId, detail.getCorrespondId()).one();
                    KingDeeStock kingDeeStock = kingDeeStockService.getById(one.getStockId());
                    salesOutStockItem.setStock(kingDeeStock.getNumber());

                    salesOutStockItem.setMustQty(new BigDecimal(Convert.toStr(-1 * invoiceApplicationOrder.getRefundableQty())));
                    salesOutStockItem.setRealQty(new BigDecimal(Convert.toStr(-1 * invoiceApplicationOrder.getRefundableQty())));
                    salesOutStockItem.setSalesTypeName(invoiceApplicationOrder.getSaleTypeName()+"|"+invoiceApplicationOrder.getSaleTypeCode());
                    salesOutStockItem.setSalesTypId(invoiceApplicationOrder.getSaleTypeId());
                    salesOutStockItem.setSupplyColVal(invoiceApplicationOrder.getId());
                    salesOutStockItemBeans.add(salesOutStockItem);
                    invoiceApplicationOrder.setKingBillNo(salesOutStockBean.getBillNo());
                    invoiceApplicationOrder.updateById();
                }
            }
        }

        salesOutStockBean.setEntry(salesOutStockItemBeans);
        ResultEntity resultEntitySales = salesReturnLogic.syncPushBillData(salesOutStockBean);
    }

    @Transactional(rollbackFor = Exception.class)
    public void trialApproval(String id, String examineStatus, String approvalRemark) throws InterruptedException {
        SalesOrder salesOrder = salesOrderService.getById(id);
        if (!salesOrder.getSyncStatus().equals(1))
            throw new RemoteServiceException("订单尚未同步，无法反审");
        if (!salesOrder.getExamineStatus().equals(ExamineStatusEnum.OK.toString()))
            throw new RemoteServiceException("此订单弃审，无法再次审批");
        salesOrder.setExamineStatus(ExamineStatusEnum.WAIT.toString());
        salesOrder.setApprovalRemark(approvalRemark);
        salesOrder.setSyncStatus(0);
        salesOrder.updateById();
        List<SalesOrderItem> list = salesOrderItemService.lambdaQuery().eq(SalesOrderItem::getSalesOrderNo, id).list();
        String billNo = salesOrder.getId();
        for (SalesOrderItem order : list) {
            //记录台账记录
            String customerWalletId = null;
            if (order.getOrderType().equals("RETAIL") || order.getOrderType().equals("RETAIL_POLICY")) {
                RetailOrderItem retailOrderItem = retailOrderItemService.getById(order.getOrderId());
                retailOrderItem.setRefundProductQty(retailOrderItem.getRefundProductQty() + (-1 * order.getRefundableQty()));
                retailOrderItem.setHasSendQty((retailOrderItem.getHasSendQty()+(-1 * order.getRefundableQty())));
                BigDecimal tdQty = BigDecimal.valueOf(-1 * order.getRefundableQty());
                retailOrderItem.setRefundProductAmount(retailOrderItem.getSinglePayPrice().multiply(Convert.toBigDecimal(retailOrderItem.getRefundProductQty())));
                retailOrderItem.updateById();
                customerWalletId = retailOrderItem.getCustomerWalletId();
            }

            if (order.getOrderType().equals("TRADE") || order.getOrderType().equals("HOME")) {
                EnginOrderItem enginOrderItem = enginOrderItemService.getById(order.getOrderId());
                enginOrderItem.setRefundProductQty(enginOrderItem.getRefundProductQty() + (-1 * order.getRefundableQty()));
                enginOrderItem.setHasSendQty((enginOrderItem.getHasSendQty()+(-1 * order.getRefundableQty())));
                BigDecimal tdQty = BigDecimal.valueOf(-1 * order.getRefundableQty());
                enginOrderItem.setRefundProductAmount(enginOrderItem.getSinglePayPrice().multiply(Convert.toBigDecimal(enginOrderItem.getRefundProductQty())));
                enginOrderItem.updateById();
                customerWalletId = enginOrderItem.getCustomerWalletId();

                if (order.getOrderType().equals("TRADE")) {
                    EnginInfoOrderItem one = enginInfoOrderItemService.lambdaQuery().eq(EnginInfoOrderItem::getEnginInfoNo, enginOrderItem.getRefEnginRecordNo())
                            .eq(EnginInfoOrderItem::getSaleTypeId, enginOrderItem.getSaleTypeId())
                            .eq(EnginInfoOrderItem::getMaterialNumber, enginOrderItem.getMaterialNumber())
                            .one();

                    if (one != null) {
                        one.setHasDeliverQty(one.getHasDeliverQty() - order.getRefundableQty());
                        one.updateById();
                    }
                }

            }


            CustomerWallet customerWallet = customerWalletService.getById(customerWalletId);

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


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

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



            StockCorrespondPosition stockCorrespondPosition = stockCorrespondPositionService.lambdaQuery()
                    .eq(StockCorrespondPosition::getCorrespondId, salesOrder.getCorrespondId())
                    .last("limit 1").one();

            Stock stock = stockService.lambdaQuery().eq(Stock::getMaterialId, order.getMaterialId()).eq(Stock::getStockId, stockCorrespondPosition.getStockId())
                    .last("limit 1").one();



            stock.setStockQty( stock.getStockQty().subtract(new BigDecimal(StrUtil.toString(-1*order.getRefundableQty()))));
            if (stock.getStockQty().compareTo(BigDecimal.ZERO) == -1)
                throw new RemoteServiceException(order.getMaterialName()+":"+order.getSpecification()+"库存不足,无法反审");

            stock.updateById();
        }

        InvoiceApplication one = invoiceApplicationService.lambdaQuery().eq(InvoiceApplication::getSalesId, id).one();

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

        invoiceApplicationService.lambdaUpdate().eq(InvoiceApplication::getSalesId, id).remove();
        invoiceApplicationOrderService.lambdaUpdate().eq(InvoiceApplicationOrder::getInvoiceId, one.getId()).remove();

        if (billNo == null)
            throw new RemoteServiceException("销售出库单未同步金蝶，无法反审");
        boolean b = salesReturnLogic.unAuditByBillNo(billNo);
        if (!b)
            throw new RemoteServiceException("反审失败");

        invoiceMapper.updateStatus(salesOrder.getOrderNo());
        saleOrderMapper.updateInvoice(salesOrder.getId());
        orderRefundTrial(salesOrder.getId());
    }


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

        List<SalesOrderItem> list = salesOrderItemService.lambdaQuery().eq(SalesOrderItem::getSalesOrderNo, invoiceApplication.getId()).list();

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

        for (SalesOrderItem invoiceApplicationOrder : list) {

            String orderId = org.apache.commons.lang3.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(), salesOrder.getEnginOrderNo(), 2, "sub"));

        }
        // 现金退款
        if (refundPayAmount.doubleValue() > 0) {
            customerWalletAmountBeans.add(new CustomerWalletAmountBean(enginOrderItem.getCustomerWalletId(), refundPayAmount, enginOrderItem.getRemark(),
                    enginName + "工程发货销售退库单订单退款-反审退货单", salesOrder.getOrderTime(), salesOrder.getEnginOrderNo(), 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.getId(), 2, "sub"));

        }
        // 现金退款
        if (refundPayAmount.doubleValue() > 0) {
            customerWalletAmountBeans.add(new CustomerWalletAmountBean(retailOrderItem.getCustomerWalletId(), refundPayAmount, retailOrderItem.getRemark(),
                    "政策零售订单销售退库单订单退款-反审退货单", salesOrder.getOrderTime(), order.getMainOrderId()+"&"+salesOrder.getId(), 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.getOrderId(), 2, "sub"));

        }
        // 现金退款
        if (refundPayAmount.doubleValue() > 0) {
            customerWalletAmountBeans.add(new CustomerWalletAmountBean(displaceOrderItem.getCustomerWalletId(), refundPayAmount, displaceOrderItem.getRemark(),
                    "置换单工程销售退库单订单退款-反审退货单", salesOrder.getOrderTime(), order.getOrderId(), 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(), order.getMainOrderId(), 2, "sub"));

        }
        // 现金退款
        if (refundPayAmount.doubleValue() > 0) {
            customerWalletAmountBeans.add(new CustomerWalletAmountBean(requisitionOrderItem.getCustomerWalletId(), refundPayAmount, requisitionOrderItem.getRemark(),
                    "直接调拨单销售退库单订单退款-反审退货单", salesOrder.getOrderTime(), order.getMainOrderId(), 2, "sub"));
        }

        walletLogic.doWalletAmount(customerWalletAmountBeans);
    }

    @Transactional(rollbackFor = Exception.class)
    public void update(SaleRetreatOrderBody saleRetreatOrderBody, HttpServletRequest request) {
        //生成销售出库单

        saleRetreatOrderBody.updateById();

        List<SalesOrderItem> salesOrders = new ArrayList<>();

        List<String> collect1 = saleRetreatOrderBody.getSaleOrderData().stream().map(SalesOrderItem::getSalesOrderNo).distinct().collect(Collectors.toList());
        if (1 != collect1.size()) {
            throw new RemoteServiceException("退库单销售库存单号需要一致");
        }

        for (SalesOrderItem salesOrderItem : saleRetreatOrderBody.getSaleOrderData()) {
            SalesOrderItem salesOrderItemOrder = salesOrderItemService.getById(salesOrderItem.getId());
            SalesOrderItem salesOrderItem1 = salesOrderItemService.getById(salesOrderItem.getSalesOrderItemId());
            List<SalesOrderItem> list = salesOrderItemService.lambdaQuery().eq(SalesOrderItem::getSalesOrderItemId, salesOrderItem.getSalesOrderItemId()).list();
            Integer refund = 0;
            if (!CollectionUtils.isEmpty(list))
                refund = list.stream().mapToInt(SalesOrderItem::getRefundableQty).sum();
            if (salesOrderItem1.getRefundableQty() + salesOrderItem.getRefundableQty()+refund-salesOrderItemOrder.getRefundableQty() < 0)
                throw new RemoteServiceException("数量不能为超过可退货数量,可退货数量为"+(salesOrderItem1.getRefundableQty()+refund-salesOrderItemOrder.getRefundableQty()));

            salesOrderItem.setPayAmount(salesOrderItem1.getSinglePayPrice()
                    .multiply(new BigDecimal(Convert.toStr(salesOrderItem.getRefundableQty()))));

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

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

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

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


            salesOrderItemService.updateById(salesOrderItem);
        }
        salesOrderPictureService.lambdaUpdate().eq(SalesOrderPicture::getSalesId,saleRetreatOrderBody.getId()).remove();
        for (SalesOrderPicture salesOrderPicture : saleRetreatOrderBody.getSalesOrderPictures()) {
            salesOrderPicture.setSalesId(saleRetreatOrderBody.getId());
        }
        salesOrderPictureService.saveBatch(saleRetreatOrderBody.getSalesOrderPictures());
    }
}