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

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.EnumUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zfire.mall.manager.bean.admin.AdminUserCom;
import com.zfire.mall.manager.bean.displace.order.DisplaceOrderBean;
import com.zfire.mall.manager.bean.displace.order.DisplaceOrderListBean;
import com.zfire.mall.manager.bean.k3.K3CustomerBean;
import com.zfire.mall.manager.bean.k3.bill.SalesOrderBean;
import com.zfire.mall.manager.bean.k3.bill.SalesOrderItemBean;
import com.zfire.mall.manager.bean.k3.bill.result.BillItem;
import com.zfire.mall.manager.bean.k3.bill.result.ResultEntity;
import com.zfire.mall.manager.bean.wallet.CustomerWalletAmountBean;
import com.zfire.mall.manager.commonmapper.displace.order.DisplaceOrderReserveMapper;
import com.zfire.mall.manager.enums.ExamineStatusEnum;
import com.zfire.mall.manager.enums.K3SyncStatusEnum;
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.CustomerEnginDepositLogic;
import com.zfire.mall.manager.logic.k3.K3CustomerLogic;
import com.zfire.mall.manager.logic.k3.bill.SalesOrderLogic;
import com.zfire.mall.manager.logic.wallet.RebateOrderLogic;
import com.zfire.mall.manager.logic.wallet.WalletLogic;
import com.zfire.mall.manager.plus.entity.*;
import com.zfire.mall.manager.plus.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@Slf4j
public class DisplaceOrderLogic {

    @Resource
    DisplaceOrderReserveMapper displaceOrderReserveMapper;
    @Resource
    CommonLogic commonLogic;
    @Resource
    DisplaceOrderService displaceOrderService;
    @Resource
    DisplaceOrderItemService displaceOrderItemService;
    @Resource
    DisplaceOrderOriginItemService displaceOrderOriginItemService;
    @Resource
    RetailOrderService retailOrderService;
    @Resource
    RetailOrderItemService retailOrderItemService;
    @Resource
    EnginOrderService enginOrderService;
    @Resource
    EnginOrderItemService enginOrderItemService;
    @Resource
    WalletLogic walletLogic;
    @Resource
    CustomerEnginDepositLogic customerEnginDepositLogic;
    @Resource
    RebateOrderLogic rebateOrderLogic;
    @Resource
    DisplaceOrderRefundNoteService displaceOrderRefundNoteService;
    @Resource
    K3CustomerLogic k3CustomerLogic;
    @Resource
    SalesOrderLogic salesOrderLogic;
    @Resource
    KingDeeMaterialService kingDeeMaterialService;

    public IPage<DisplaceOrderListBean> listPage(String customerKeyword, String displaceOrderId, String originOrderNo,
                                                 String orderType, String productName, String startOrderTime, String endOrderTime,
                                                 String createName, String confirmName, String examineStatus,
                                                 String serviceId, Integer pageNum, Integer pageSize) {
        AdminUserCom adminUser = commonLogic.getAdminUser(true);
        String customerId = adminUser.getIsCustomer() ? adminUser.getCustomerId() : "";
        return displaceOrderReserveMapper.listPage(new Page<>(pageNum, pageSize), customerKeyword, displaceOrderId,
                originOrderNo, orderType, productName, startOrderTime, endOrderTime, createName, confirmName,
                examineStatus, serviceId, adminUser.getAdminCompanyIds(), adminUser.getServiceIds(), customerId);
    }

    public DisplaceOrderBean detail(String id) {
        AdminUserCom adminUser = commonLogic.getAdminUser(true);
        List<String> adminCompanyIds = adminUser.getAdminCompanyIds();
        String customerId = adminUser.getIsCustomer() ? adminUser.getCustomerId() : "";
        DisplaceOrderBean detail = displaceOrderReserveMapper.detail(id, adminCompanyIds, adminUser.getServiceIds(), customerId);
        detail.setOriginItems(displaceOrderOriginItemService.lambdaQuery()
                .eq(DisplaceOrderOriginItem::getParentId, id)
                .list());
        return detail;
    }

    public DisplaceOrderBean queryRefDetail(String originOrderNo) throws Exception {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        List<String> adminCompanyIds = adminUser.getAdminCompanyIds();
        String customerId = null;
        if (adminUser.getIsCustomer()) {
            customerId = adminUser.getCustomerId();
        }
        DisplaceOrderBean displaceOrderBean = new DisplaceOrderBean();
        if (originOrderNo.contains("LS")
                || originOrderNo.contains("ZC")) {
            RetailOrder retailOrder = retailOrderService.lambdaQuery()
                    .in(CollectionUtil.isNotEmpty(adminCompanyIds), RetailOrder::getAdminCompanyId, adminCompanyIds)
                    .eq(adminUser.getIsCustomer(), RetailOrder::getCustomerId, customerId)
                    .eq(RetailOrder::getType, originOrderNo.contains("LS") ? 1 : 2)
                    .eq(RetailOrder::getId, originOrderNo)
                    .eq(RetailOrder::getExamineStatus, ExamineStatusEnum.OK.toString())
                    .one();
            if (Objects.isNull(retailOrder)) {
                throw new RemoteServiceException(originOrderNo + "：订单不存在");
            }
            List<RetailOrderItem> retailOrderItems = retailOrderItemService.lambdaQuery()
                    .eq(RetailOrderItem::getRetailOrderId, originOrderNo)
                    .and(v -> v.eq(RetailOrderItem::getDirectTransferStatus, true)
                            .or()
                            .eq(RetailOrderItem::getIsDirectTransfer, false))
                    .gt(RetailOrderItem::getRefundableQty, 0)
                    .list();

            if (CollectionUtil.isEmpty(retailOrderItems)) {
                throw new RemoteServiceException(originOrderNo + "：订单明细直调未完结或者没有可退产品");
            }

            // 检查能否置换
            Map<String, KingDeeMaterial> kingDeeMaterialMap = this.checkProductStatus(originOrderNo, retailOrderItems.stream()
                    .map(RetailOrderItem::getMaterialId)
                    .collect(Collectors.toList()));
            List<RetailOrderItem> newRetailOrderItems = new ArrayList<>();
            for (RetailOrderItem retailOrderItem : retailOrderItems) {
                if (Objects.nonNull(kingDeeMaterialMap.get(retailOrderItem.getMaterialId()))) {
                    newRetailOrderItems.add(retailOrderItem);
                }
            }

            displaceOrderBean.handleRetailOrderInfo(retailOrder, newRetailOrderItems);
        } else {
            EnginOrder enginOrder = enginOrderService.lambdaQuery()
                    .in(CollectionUtil.isNotEmpty(adminCompanyIds), EnginOrder::getAdminCompanyId, adminCompanyIds)
                    .eq(adminUser.getIsCustomer(), EnginOrder::getCustomerId, customerId)
                    .eq(EnginOrder::getEnginOrderType, originOrderNo.contains("EOH") ? OrderTypeEnum.HOME.getKey() : OrderTypeEnum.TRADE.getKey())
                    .eq(EnginOrder::getEnginOrderNo, originOrderNo)
                    .eq(EnginOrder::getExamineStatus, ExamineStatusEnum.OK.toString())
                    .one();
            if (Objects.isNull(enginOrder)) {
                throw new RemoteServiceException(originOrderNo + "：订单不存在");
            }
            List<EnginOrderItem> orderItems = enginOrderItemService.lambdaQuery()
                    .eq(EnginOrderItem::getEnginOrderNo, originOrderNo)
                    .and(v -> v.eq(EnginOrderItem::getDirectTransferStatus, true)
                            .or()
                            .eq(EnginOrderItem::getIsDirectTransfer, false))
                    .gt(EnginOrderItem::getRefundableQty, 0)
                    .list();

            if (CollectionUtil.isEmpty(orderItems)) {
                throw new RemoteServiceException(originOrderNo + "：订单明细直调未完结或者没有可退产品");
            }

            // 检查能否置换
            Map<String, KingDeeMaterial> kingDeeMaterialMap = this.checkProductStatus(originOrderNo, orderItems.stream()
                    .map(EnginOrderItem::getMaterialId)
                    .collect(Collectors.toList()));
            List<EnginOrderItem> newOrderItems = new ArrayList<>();
            for (EnginOrderItem item : orderItems) {
                if (Objects.nonNull(kingDeeMaterialMap.get(item.getMaterialId()))) {
                    newOrderItems.add(item);
                }
            }
            displaceOrderBean.handleEnginOrderInfo(enginOrder, newOrderItems);
        }
        return displaceOrderBean;
    }

    private Map<String, KingDeeMaterial> checkProductStatus(String originOrderNo, List<String> ids) {
        List<KingDeeMaterial> kingDeeMaterials = kingDeeMaterialService.lambdaQuery()
                .in(KingDeeMaterial::getId, ids)
                .eq(KingDeeMaterial::getIsDisplace, true)
                .list();

        if (CollectionUtil.isEmpty(kingDeeMaterials)) {
            throw new RemoteServiceException(originOrderNo + "：订单明细没有可置换产品");
        }

        return kingDeeMaterials.stream().collect(Collectors.toMap(KingDeeMaterial::getId, Function.identity()));
    }

    @Transactional(rollbackFor = Exception.class)
    public String add(DisplaceOrderBean displaceOrderBean) throws Exception {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        DisplaceOrderBean queryRefDetail = this.queryRefDetail(displaceOrderBean.getOrderNo());
        this.setAddCommonOrderInfo(adminUser, displaceOrderBean, queryRefDetail);

        // 检查引用单号唯一
        checkOnlyOrderNoRecord(displaceOrderBean);

        // 保存主表
        DisplaceOrder displaceOrder = displaceOrderBean.handleAddOrderInfo(adminUser);
        displaceOrder.insert();

        // 保存明细
        displaceOrderBean.handleAddOriginItem();
        displaceOrderBean.handleAddOrderItem(walletLogic, customerEnginDepositLogic);

        displaceOrderItemService.saveBatch(displaceOrderBean.getItems());
        displaceOrderOriginItemService.saveBatch(displaceOrderBean.getOriginItems());

        return displaceOrder.getDisplaceOrderId();
    }

    private void setAddCommonOrderInfo(AdminUserCom adminUser, DisplaceOrderBean displaceOrderBean, DisplaceOrderBean queryRefDetail) {
        if (StringUtils.isBlank(displaceOrderBean.getOrderNo())) {
            throw new RemoteServiceException("引用单号不能为空");
        }
        if (Objects.isNull(displaceOrderBean.getOrderDate())) {
            throw new RemoteServiceException("订单日期不能为空");
        }
        if (adminUser.getIsCustomer()) {
            // 经销商建单
            displaceOrderBean.setCustomerId(adminUser.getCustomerId());
            displaceOrderBean.setCustomerNumber(adminUser.getCustomerNumber());
            displaceOrderBean.setCustomerName(adminUser.getCustomerName());
        } else {
            throw new RemoteServiceException("不是经销商账号不能建单");
        }

        String orderType;
        if (displaceOrderBean.getOrderNo().contains("LS")) {
            orderType = OrderTypeEnum.RETAIL.getKey();
        } else if (displaceOrderBean.getOrderNo().contains("ZC")) {
            orderType = OrderTypeEnum.RETAIL_POLICY.getKey();
        } else if (displaceOrderBean.getOrderNo().contains("EOH")) {
            orderType = OrderTypeEnum.HOME.getKey();
        } else {
            orderType = OrderTypeEnum.TRADE.getKey();
        }
        // 注入公司编号
        displaceOrderBean.setAdminCompanyId(adminUser.getAdminCompanyId());
        displaceOrderBean.setDisplaceOrderId("DO" + IdWorker.getIdStr());
        displaceOrderBean.setExamineStatus(ExamineStatusEnum.SAVE.toString());
        displaceOrderBean.setOrderType(orderType);
        displaceOrderBean.setMainId(queryRefDetail.getMainId());
        displaceOrderBean.setMainName(queryRefDetail.getMainName());
        displaceOrderBean.setEnginRecordNo(queryRefDetail.getEnginRecordNo());
        displaceOrderBean.setProjectNo(queryRefDetail.getProjectNo());
        displaceOrderBean.setProjectName(queryRefDetail.getProjectName());
        displaceOrderBean.setUseUnit(queryRefDetail.getUseUnit());
        displaceOrderBean.setInstallAddress(queryRefDetail.getInstallAddress());
        displaceOrderBean.setPolicyId(queryRefDetail.getPolicyId());
        displaceOrderBean.setPolicyCode(queryRefDetail.getPolicyCode());
        displaceOrderBean.setPolicyTitle(queryRefDetail.getPolicyTitle());
        displaceOrderBean.setPolicyRemark(queryRefDetail.getPolicyRemark());
        displaceOrderBean.setServiceId(queryRefDetail.getServiceId());
        displaceOrderBean.setServiceName(queryRefDetail.getServiceName());
        displaceOrderBean.setTakeDeposit(queryRefDetail.getTakeDeposit());
    }

    private void checkOnlyOrderNoRecord(DisplaceOrderBean displaceOrderBean) {
        Integer count = displaceOrderService.lambdaQuery()
                .eq(DisplaceOrder::getAdminCompanyId, displaceOrderBean.getAdminCompanyId())
                .eq(DisplaceOrder::getCustomerId, displaceOrderBean.getCustomerId())
                .eq(DisplaceOrder::getOrderNo, displaceOrderBean.getOrderNo())
                .in(DisplaceOrder::getExamineStatus, ExamineStatusEnum.SAVE.toString(), ExamineStatusEnum.WAIT.toString())
                .count();
        if (count > 0) {
            throw new RemoteServiceException(displaceOrderBean.getOrderNo() + " 的引用单已存在一张的订单！不能再添加");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void edit(DisplaceOrderBean displaceOrderBean) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        boolean update = displaceOrderService.update(new DisplaceOrder(), new LambdaUpdateWrapper<DisplaceOrder>()
                .set(DisplaceOrder::getOrderDate, displaceOrderBean.getOrderDate())
                .set(DisplaceOrder::getRemark, displaceOrderBean.getRemark())
                .set(DisplaceOrder::getUpdateName, adminUser.getNickName())
                .eq(DisplaceOrder::getDisplaceOrderId, displaceOrderBean.getDisplaceOrderId())
                .eq(DisplaceOrder::getExamineStatus, ExamineStatusEnum.SAVE.toString())
                .eq(adminUser.getIsCustomer(), DisplaceOrder::getCustomerId, adminUser.getCustomerId()));

        if (!update) {
            throw new RemoteServiceException("单据内容已发生变化，处理失败");
        }

        displaceOrderItemService.remove(new LambdaUpdateWrapper<DisplaceOrderItem>()
                .eq(DisplaceOrderItem::getParentId, displaceOrderBean.getDisplaceOrderId()));
        displaceOrderOriginItemService.remove(new LambdaUpdateWrapper<DisplaceOrderOriginItem>()
                .eq(DisplaceOrderOriginItem::getParentId, displaceOrderBean.getDisplaceOrderId()));

        displaceOrderBean.handleAddOriginItem();
        displaceOrderBean.handleAddOrderItem(walletLogic, customerEnginDepositLogic);

        displaceOrderItemService.saveBatch(displaceOrderBean.getItems());
        displaceOrderOriginItemService.saveBatch(displaceOrderBean.getOriginItems());
    }

    public void submit(String id) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        DisplaceOrder displaceOrder = displaceOrderService.getById(id);
        if(!displaceOrder.getExamineStatus().equals(ExamineStatusEnum.SAVE.toString())){
            throw new RemoteServiceException("请勿重复提审");
        }
        displaceOrder.setUpdateName(adminUser.getNickName())
                .setSubmitBy(adminUser.getAdminUserId())
                .setSubmitName(adminUser.getNickName())
                .setSubmitTime(DateUtil.date())
                .setExamineStatus(ExamineStatusEnum.WAIT.toString());
        displaceOrder.updateById();
    }


    public void revoke(String id) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        DisplaceOrder displaceOrder = displaceOrderService.getById(id);
        if(!displaceOrder.getExamineStatus().equals(ExamineStatusEnum.WAIT.toString())){
            throw new RemoteServiceException("无法撤回提审");
        }
        displaceOrder.setUpdateName(adminUser.getNickName())
                .setSubmitBy(null)
                .setSubmitName(null)
                .setSubmitTime(null)
                .setExamineStatus(ExamineStatusEnum.SAVE.toString());
        displaceOrder.updateById();
    }

    @Transactional(rollbackFor = Exception.class)
    public void examine(DisplaceOrderBean displaceOrderBean) throws Exception {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        boolean update = displaceOrderService.update(new DisplaceOrder(), new LambdaUpdateWrapper<DisplaceOrder>()
                .set(DisplaceOrder::getExamineNote, displaceOrderBean.getExamineNote())
                .set(DisplaceOrder::getConfirmBy, adminUser.getAdminUserId())
                .set(DisplaceOrder::getConfirmName, adminUser.getNickName())
                .set(DisplaceOrder::getConfirmTime, DateUtil.date())
                .set(DisplaceOrder::getExamineStatus, displaceOrderBean.isExamineResult() ? ExamineStatusEnum.OK.toString() : ExamineStatusEnum.FAIL.toString())
                .eq(DisplaceOrder::getDisplaceOrderId, displaceOrderBean.getDisplaceOrderId())
                .eq(DisplaceOrder::getExamineStatus, ExamineStatusEnum.WAIT.toString())
                .eq(adminUser.getIsCustomer(), DisplaceOrder::getCustomerId, adminUser.getCustomerId()));

        if (!update) {
            throw new RemoteServiceException("单据内容已发生变化，处理失败");
        }

        DisplaceOrder displaceOrder = displaceOrderService.lambdaQuery()
                .eq(DisplaceOrder::getDisplaceOrderId, displaceOrderBean.getDisplaceOrderId())
                .one();
        displaceOrderBean.setOrderNo(displaceOrder.getOrderNo());

        displaceOrderItemService.remove(new LambdaUpdateWrapper<DisplaceOrderItem>()
                .eq(DisplaceOrderItem::getParentId, displaceOrderBean.getDisplaceOrderId()));
//        displaceOrderOriginItemService.remove(new LambdaUpdateWrapper<DisplaceOrderOriginItem>()
//                .eq(DisplaceOrderOriginItem::getParentId, displaceOrderBean.getDisplaceOrderId()));

//        displaceOrderBean.handleAddOriginItem();
        displaceOrderBean.handleAddOrderItem(walletLogic, customerEnginDepositLogic);

        displaceOrderItemService.saveBatch(displaceOrderBean.getItems());
//        displaceOrderOriginItemService.saveBatch(displaceOrderBean.getOriginItems());

        // 审批通过时处理
        if (displaceOrderBean.isExamineResult()) {
            Map<String, Object> enumMap = EnumUtil.getNameFieldMap(OrderTypeEnum.class, "value");

            List<DisplaceOrderOriginItem> originItems = displaceOrderOriginItemService.lambdaQuery()
                    .eq(DisplaceOrderOriginItem::getParentId, displaceOrderBean.getDisplaceOrderId())
                    .list();
            List<DisplaceOrderItem> orderItems = displaceOrderItemService.lambdaQuery()
                    .eq(DisplaceOrderItem::getParentId, displaceOrderBean.getDisplaceOrderId())
                    .list();
            List<CustomerWalletAmountBean> walletAmountBeans = new ArrayList<>();
            // 退回原明细的钱款
            for(DisplaceOrderOriginItem item : originItems) {
                // 更新原订单明细可退数量
                displaceOrderBean.updOriginRefundableQty(retailOrderItemService, enginOrderItemService, item);
                walletAmountBeans.add(new CustomerWalletAmountBean(item.getCustomerWalletId(), item.getPayAmount(), item.getRemark(),
                        enumMap.get(displaceOrder.getOrderType()) + "订单退款-置换"
                        , displaceOrder.getCreateTime(), displaceOrder.getDisplaceOrderId(),2, "add"));
                if (item.getPayRebateAmount().doubleValue() > 0) {
                    walletAmountBeans.add(new CustomerWalletAmountBean(item.getCustomerWalletId2(), item.getPayRebateAmount(), item.getRemark(),
                            enumMap.get(displaceOrder.getOrderType()) + "返利单退款-置换"
                            , displaceOrder.getCreateTime(), displaceOrder.getDisplaceOrderId(), 0, "add"));
                }
            }
            // 扣钱款
            for (DisplaceOrderItem orderItem : orderItems) {
                //检查是否存在未确认的返利单
                rebateOrderLogic.checkNeedAck(orderItem.getCustomerWalletId2());
                //扣现金钱包
                walletAmountBeans.add(new CustomerWalletAmountBean(orderItem.getCustomerWalletId(), orderItem.getPayAmount(),
                        orderItem.getRemark(), "置换单扣款",
                        displaceOrder.getCreateTime(), displaceOrder.getDisplaceOrderId(), 2, "sub"));
                //扣返利钱包
                if (orderItem.getPayRebateAmount().doubleValue() > 0) {
                    walletAmountBeans.add(new CustomerWalletAmountBean(orderItem.getCustomerWalletId2(), orderItem.getPayRebateAmount(),
                            orderItem.getRemark(), "置换单返利扣款",
                            displaceOrder.getCreateTime(), displaceOrder.getDisplaceOrderId(), 0, "sub"));
                }
            }
            walletLogic.doWalletAmount(walletAmountBeans);

            // 推送金蝶销售订单
            this.syncK3Order(displaceOrder, orderItems);

            displaceOrder.updateById();
            displaceOrderItemService.saveOrUpdateBatch(orderItems);

        }
    }

    private void syncK3Order(DisplaceOrder displaceOrder, List<DisplaceOrderItem> orderItems) {
        // 推送金蝶销售订单
        ResultEntity resultEntity = this.toK3(displaceOrder, orderItems);
        if(Objects.isNull(resultEntity)) {
            throw new RemoteServiceException("同步金蝶单据失败");
        }
        // 回填金蝶信息
        displaceOrder.setKingDeeId(resultEntity.getId());
        displaceOrder.setKingDeeSync(StringUtils.isNotBlank(resultEntity.getId()) ? K3SyncStatusEnum.SALES.toString() : K3SyncStatusEnum.NOT.toString());
        if (StringUtils.isNotBlank(resultEntity.getId())) {
            Map<String, BillItem> map = resultEntity.getItems().stream()
                    .collect(Collectors.toMap(BillItem::getSupplyColVal, Function.identity()));
            for (DisplaceOrderItem item : orderItems) {
                BillItem billItem = map.get(item.getId());
                item.setKingDeeSeq(billItem.getSeq());
                item.setKingDeeEntryId(billItem.getEntryId());
            }
        }
    }

    private ResultEntity toK3(DisplaceOrder displaceOrder, List<DisplaceOrderItem> orderItems) {
        K3CustomerBean customer = k3CustomerLogic.detail(displaceOrder.getCustomerId());
        SalesOrderBean salesOrderBean = new SalesOrderBean();
        salesOrderBean.setBillNo(displaceOrder.getDisplaceOrderId());
        salesOrderBean.setCustomerNumber(customer.getNumber());
        salesOrderBean.setOrgNumber(customer.getUseOrgNumber());
        salesOrderBean.setDate(DateUtil.formatDate(displaceOrder.getCreateTime()));

        List<SalesOrderItemBean> k3Items = new ArrayList<>();
        for (DisplaceOrderItem item : orderItems) {
            SalesOrderItemBean k3Item = new SalesOrderItemBean();
            k3Item.setSupplyColVal(item.getId());
            k3Item.setMaterialNumber(item.getMaterialNumber());
            k3Item.setQty(BigDecimal.valueOf(item.getQty()));
            k3Item.setTaxPrice(item.getPrice());
            k3Item.setDiscount(item.getTotalDiscAmount().add(item.getPayRebateAmount()));
            k3Item.setEntryNote(item.getRemark());
            k3Item.setWalletNumber(item.getCustomerWalletNumber());
            k3Item.setfOrderEntryPlan(salesOrderBean.getDate());
            k3Items.add(k3Item);
        }
        salesOrderBean.setOrderItems(k3Items);

        return salesOrderLogic.syncBillData(salesOrderBean);
    }

    @Transactional(rollbackFor = Exception.class)
    public void del(List<String> ids) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        List<String> collect = ids.stream().distinct().collect(Collectors.toList());
        boolean remove = displaceOrderService.lambdaUpdate()
                .eq(DisplaceOrder::getAdminCompanyId, adminUser.getAdminCompanyId())
                .eq(adminUser.getIsCustomer(), DisplaceOrder::getCustomerId, adminUser.getCustomerId())
                .eq(DisplaceOrder::getExamineStatus, ExamineStatusEnum.SAVE.toString())
                .in(DisplaceOrder::getDisplaceOrderId, collect)
                .remove();
        if (!remove) {
            throw new RemoteServiceException("单据状态已发生改变，删除失败");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void refund(DisplaceOrderBean displaceOrderBean) throws Exception {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        DisplaceOrder displaceOrder = displaceOrderService.lambdaQuery()
                .eq(DisplaceOrder::getDisplaceOrderId, displaceOrderBean.getDisplaceOrderId())
                .eq(adminUser.getIsCustomer(), DisplaceOrder::getCustomerId, adminUser.getCustomerId())
                .eq(DisplaceOrder::getAdminCompanyId, adminUser.getAdminCompanyId())
                .eq(DisplaceOrder::getExamineStatus, ExamineStatusEnum.OK.toString())
                .one();

        if (Objects.isNull(displaceOrder)) {
            throw new RemoteServiceException("单据不存在");
        }

        Map<String, DisplaceOrderItem> itemBeanMap = displaceOrderBean.getItems().stream()
                .collect(Collectors.toMap(DisplaceOrderItem::getMaterialId, Function.identity(), (key1, key2) -> key2));

        List<DisplaceOrderItem> list = displaceOrderItemService.lambdaQuery()
                .eq(DisplaceOrderItem::getParentId, displaceOrderBean.getDisplaceOrderId())
                .list();
        List<CustomerWalletAmountBean> walletAmountBeans = new ArrayList<>();
        for(DisplaceOrderItem item : list){
            DisplaceOrderItem itemBean = itemBeanMap.get(item.getMaterialId());
            if (Objects.isNull(itemBean)) {
                continue;
            }

            if(itemBean.getRetiredQty() == null || itemBean.getRetiredQty() == 0){
                continue;
            }
            if (itemBean.getRetiredQty().compareTo(item.getRefundableQty()) > 0){
                throw new RemoteServiceException("机型:" + itemBean.getMaterialName() + "退货数量不可大于可退数量");
            }
            BigDecimal tdQty = BigDecimal.valueOf(itemBean.getRetiredQty());
            //需要退的钱
            BigDecimal refundPayAmount = item.getSinglePayPrice().multiply(tdQty);
            //需要退的返利金额
            BigDecimal refundRebateAmount = item.getSingleRebateAmount().multiply(tdQty);
            //返利单退款
            if (refundRebateAmount.doubleValue() > 0) {
                walletAmountBeans.add(new CustomerWalletAmountBean(item.getCustomerWalletId2(), refundRebateAmount, item.getRemark(),"置换单返利退款-退订"
                        , displaceOrderBean.getCreateTime(), displaceOrderBean.getDisplaceOrderId(), 0, "add"));
            }
            // 现金退款
            if (refundPayAmount.doubleValue() > 0) {
                walletAmountBeans.add(new CustomerWalletAmountBean(item.getCustomerWalletId(), refundPayAmount, item.getRemark(),"置换单退款-退订"
                        , displaceOrderBean.getCreateTime(), displaceOrderBean.getDisplaceOrderId(),2, "add"));
            }

            item.setRetiredQty(item.getRetiredQty() + itemBean.getRetiredQty()); // 变更已退数量
            item.setRefundableQty(item.getRefundableQty() - itemBean.getRetiredQty());
        }

        walletLogic.doWalletAmount(walletAmountBeans);

        displaceOrderItemService.saveOrUpdateBatch(list);
        // 插入退订说明
        displaceOrderRefundNoteService.save(new DisplaceOrderRefundNote()
                .setParentId(displaceOrderBean.getDisplaceOrderId())
                .setRefundNote(displaceOrderBean.getRefundNote()));
    }
}
