package com.gree.mall.manager.logic.order;

import cn.hutool.http.HttpUtil;
import com.gree.mall.manager.bean.order.*;
import com.gree.mall.manager.enums.material.DirectFlagEnum;
import com.gree.mall.manager.enums.material.GoodsMaterialStockAccBillTypeEnum;
import com.gree.mall.manager.logic.goods.GoodsMaterialStockAccLogic;
import com.gree.mall.manager.logic.goods.JxGoodsLogic;
import org.apache.commons.lang3.StringUtils;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.gree.mall.manager.bean.ExcelData;
import com.gree.mall.manager.bean.admin.AdminUserCom;
import com.gree.mall.manager.bean.admin.AdminWebsitBean;
import com.gree.mall.manager.commonmapper.OrderRefundInfoMapper;
import com.gree.mall.manager.constant.Constant;
import com.gree.mall.manager.enums.*;
import com.gree.mall.manager.exception.RemoteServiceException;
import com.gree.mall.manager.logic.common.CommonLogic;
import com.gree.mall.manager.logic.common.WechatLogic;
import com.gree.mall.manager.logic.coupon.CouponLogic;
import com.gree.mall.manager.plus.entity.*;
import com.gree.mall.manager.plus.service.*;
import com.gree.mall.manager.utils.ArithUtils;
import com.gree.mall.manager.utils.CommonUtils;
import com.gree.mall.manager.utils.DateUtils;
import com.gree.mall.manager.utils.StringUtil;
import com.gree.mall.manager.utils.excel.ExcelUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class OrderRefundLogic {

    @Autowired
    OrderShareLogic orderShareLogic;
    @Autowired
    OrderLogic orderLogic;
    @Autowired
    WechatLogic wechatLogic;
    @Autowired
    CommonLogic commonLogic;
//    @Autowired
//    GongdanLogic gongdanLogic;
    @Autowired
    CouponLogic couponLogic;
    @Autowired
    OrderInfoService orderInfoService;
    @Autowired
    OrderRefundService orderRefundService;
    @Autowired
    OrderDetailService orderDetailService;
    @Autowired
    ExpressInfoService expressInfoService;
    @Autowired
    OrderRefundInfoMapper orderRefundInfoMapper;
    @Autowired
    OrderRequestService orderRequestService;

    @Autowired
    JxGoodsLogic jxGoodsLogic;

    @Autowired
    GoodsMaterialStockAccLogic goodsMaterialStockAccLogic;

    @Autowired
    OrderRefundCodeService orderRefundCodeService;

    @Autowired
    GoodsMaterialItemService goodsMaterialItemService;
    @Autowired
    OrderOfflineRefundService orderOfflineRefundService;

    @Autowired
    GoodsSpecService goodsSpecService;

    @Autowired
    OrderDeliveryService orderDeliveryService;

    @Autowired
    OrderDeliveryDetailService orderDeliveryDetailService;

    /**
     * 订单列表
     *
     * @return
     */
    public IPage<OrderRefundDetailBean> list(HttpServletRequest request, String orderId, String orderRefundId, String userName, String phone, String orderStatus,
                                             String startCreateTime, String endCreateTime, String startExamineTime, String endExamineTime,
                                             Integer pageNum, Integer pageSize) {
        AdminUserCom adminUser = commonLogic.getAdminUser(request);

        IPage page = orderRefundService.lambdaQuery()
                .like(StringUtils.isNotBlank(orderId), OrderRefund::getOrderId, orderId)
                .in(CollectionUtils.isNotEmpty(adminUser.getCompanyWechatIds()),OrderRefund::getCompanyWechatId,adminUser.getCompanyWechatIds())
                ////.//in(CollectionUtils.isNotEmpty(adminUser.getAdminWebsitIds()),OrderRefund::getWebsitId,adminUser.getAdminWebsitIds())
                .like(StringUtils.isNotBlank(orderRefundId), OrderRefund::getOrderRefundId, orderRefundId)
                .like(StringUtils.isNotBlank(userName), OrderRefund::getUserName, userName)
                .and(StringUtils.isNotBlank(phone), v -> v.like(OrderRefund::getPhone,phone).or().like(OrderRefund::getRecePhone,phone))
                .eq(StringUtils.isNotBlank(orderStatus), OrderRefund::getOrderStatus, orderStatus)
                .between(StringUtils.isNotBlank(startCreateTime) && StringUtils.isNotBlank(endCreateTime), OrderRefund::getCreateTime, startCreateTime, endCreateTime + " 23:59:59")
                .between(StringUtils.isNotBlank(startExamineTime) && StringUtils.isNotBlank(endExamineTime), OrderRefund::getExamineTime, startExamineTime, endExamineTime + " 23:59:59")
                .orderByDesc(OrderRefund::getCreateTime).page(new Page<>(pageNum, pageSize));

        List<OrderRefundDetailBean> list = new ArrayList<>();
        for (Object o : page.getRecords()) {
            OrderRefund orderInfo = (OrderRefund) o;
            OrderRefundDetailBean detailBean = new OrderRefundDetailBean();
            BeanUtils.copyProperties(orderInfo, detailBean);
            //查询订单详情
            List<OrderDetail> orderDetails = orderDetailService.lambdaQuery().eq(OrderDetail::getOrderId, orderInfo.getOrderId()).list();
            detailBean.setOrderDetails(orderDetails);


            Integer count = orderRequestService.lambdaQuery().eq(OrderRequest::getOrderId, orderInfo.getOrderId()).count();
            detailBean.setToWorkOrder(count > 0);

            list.add(detailBean);
        }
        page.setRecords(list);
        return page;
    }


    /**
     * 售后订单详情
     *
     * @param orderRefundId
     * @return
     */
    public OrderRefundDetailBean orderRefundDetail(String orderRefundId) {
        OrderRefund orderRefund = orderRefundService.getById(orderRefundId);
        List<OrderDetail> list = orderDetailService.lambdaQuery().eq(OrderDetail::getOrderId, orderRefund.getOrderId()).list();

        OrderRefundDetailBean orderRefundDetailBean = new OrderRefundDetailBean();
        BeanUtils.copyProperties(orderRefund, orderRefundDetailBean);
        orderRefundDetailBean.setOrderDetails(list);
        //售后凭证
        List<CommonFile> commonFiles = commonLogic.queryFileByObjId(orderRefund.getOrderId(), Constant.Img.ORDER_REFUND_WLPZ);
        List<CommonFile> commonFiles2 = commonLogic.queryFileByObjId(orderRefund.getOrderId(), Constant.Img.ORDER_REFUND_TKPZ);
        orderRefundDetailBean.setFiles(commonFiles);
        orderRefundDetailBean.setTkFiles(commonFiles2);
        //工单信息
        List<OrderRequest> orderRequests = orderRequestService.lambdaQuery().eq(OrderRequest::getOrderId, orderRefund.getOrderId()).list();
        orderRefundDetailBean.setOrderRequests(orderRequests);
        return orderRefundDetailBean;
    }

    /**
     * 审核
     */
    @Transactional
    public void examine(String orderRefundId, String examineStatus,String refundMessage,RefundOrderBody refundOrderBody) throws Exception {

        OrderRefund orderRefund = orderRefundService.getById(orderRefundId);
        OrderInfo orderInfo = orderInfoService.getById(orderRefund.getOrderId());

        //判断是否存在线下退货单待审核的状态，如果存在，需要先处理
        Integer count = orderOfflineRefundService.lambdaQuery()
                .eq(OrderOfflineRefund::getOrderId, orderInfo.getOrderId())
                .eq(OrderOfflineRefund::getExamineStatus, ExamineStatusEnum.WAIT.getKey()).count();
        if(count > 0){
            throw new RemoteServiceException("存在待处理的线下退货单，请优先处理");
        }

        if (examineStatus.equals(OrderExamineEnum.FAIL.toString())) {
            orderRefundService.lambdaUpdate()
                    .eq(OrderRefund::getOrderRefundId, orderRefundId)
                    .set(OrderRefund::getExamineStatus, examineStatus)
                    .set(OrderRefund::getRefundMessage,refundMessage)
                    .set(OrderRefund::getExamineTime, new Date())
                    .set(OrderRefund::getOrderStatus, OrderStatusEnum.CLOSE.toString())
                    .update();
            orderDetailService.lambdaUpdate()
                    .eq(OrderDetail::getOrderId, orderRefund.getOrderId())
                    .set(OrderDetail::getRefundNum, 0)
                    .set(OrderDetail::getRefundAmount, new BigDecimal("0.00"))
                    .set(OrderDetail::getUserRefundNum,0)
                    .set(OrderDetail::getUserRefundAmount,0)
                    .set(OrderDetail::getRefund, false)
                    .set(OrderDetail::getRefundTime,null)
                    .set(OrderDetail::getRefundBy,"")
                    .update();

            //恢复订单状态
            orderInfo.setOrderStatus(orderInfo.getLastOrderStatus());
            orderInfo.setRefundFlag(RefundFlagEnum.COMMONLY.toString());
            orderInfo.updateById();
            //恢复分佣状态
            orderShareLogic.updateOrderShare(orderInfo.getOrderId(),OrderShareStatusEnum.ING.toString());
            return;
        }

        if (examineStatus.equals(OrderExamineEnum.OK.toString())) {

            List<OrderShare> orderShareList = orderShareLogic.getOrderShareList(orderInfo.getOrderId());
            if(orderShareList.size() > 0 && orderShareList.get(0).getStatus().equals(OrderShareStatusEnum.OVER.toString())){
                throw new RemoteServiceException("退款失败,订单已结算");
            }
            //退货退款
            if (orderRefund.getRefundType().equals(OrderRefundTypeEnum.REFUND_GOODS.toString())) {
                orderRefundService.lambdaUpdate()
                        .eq(OrderRefund::getOrderRefundId, orderRefundId)
                        .set(OrderRefund::getExamineStatus, examineStatus)
                        .set(OrderRefund::getRefundMessage,refundMessage)
                        .set(OrderRefund::getExamineTime, new Date())
                        .set(OrderRefund::getOrderStatus, OrderStatusEnum.DMJCL.toString())
                        .update();

                this.examineRefundV2(refundOrderBody);

                return;
            }

            //仅退款
            if (orderRefund.getRefundType().equals(OrderRefundTypeEnum.REFUND_AMOUNT.toString())) {
                this.refundOrder(orderRefund,refundMessage,true);


                //库存扣除 // 库存变更台账
                List<OrderDetail> orderDetails = orderDetailService.lambdaQuery().eq(OrderDetail::getOrderId, orderRefund.getOrderId()).list();
                for (OrderDetail orderDetail : orderDetails) {
                    if (orderDetail.getIsVr() || StringUtil.isEmpty(orderDetail.getGoodsMaterialId()))
                        continue;

                    GoodsSpec goodsSpec = goodsSpecService.getById(orderDetail.getGoodsSpecId());

                    if (goodsSpec == null || StringUtil.isEmpty(goodsSpec.getGoodsCode()))
                        throw new RemoteServiceException("未找到对应商品规格");

                    orderDetail.setGoodsMaterialId(goodsSpec.getGoodsCode());

                    if (orderDetail.getRefund() && !orderDetail.getRefundNum().equals(0)) {


                        List<OrderDeliveryDetail> orderDeliveryDetails = orderDeliveryDetailService.lambdaQuery().eq(OrderDeliveryDetail::getOrderDetailId, orderDetail.getOrderDetailId())
                                .eq(OrderDeliveryDetail::getRefundNum, 0).list();

                        Integer refundNum = orderDetail.getRefundNum();

                        if (CollectionUtils.isEmpty(orderDeliveryDetails))
                            orderDetail.setBeforeRefundNum(refundNum);

                        for (OrderDeliveryDetail orderDeliveryDetail : orderDeliveryDetails) {

                            if (refundNum < 1)
                                break;

                            if ((orderDeliveryDetail.getSendNum()-orderDeliveryDetail.getRefundNum()) < 1)
                                continue;

                            OrderDelivery orderDelivery = orderDeliveryService.getById(orderDeliveryDetail.getDeliveryId());
                            if (refundNum <= (orderDeliveryDetail.getSendNum()-orderDeliveryDetail.getRefundNum()) && refundNum > 0) {

                                orderDeliveryDetail.setRefundNum(orderDeliveryDetail.getRefundNum()+refundNum);
                                orderDelivery.setRefundNum(orderDelivery.getRefundNum()+refundNum);

                                jxGoodsLogic.addMaterialStock(orderDetail.getGoodsMaterialId(), refundNum, orderDelivery.getStorageStockId(), orderDelivery.getStorageStockId());

                                goodsMaterialStockAccLogic.add(orderDetail.getGoodsMaterialId(), orderDetail.getPrice(), refundNum, DirectFlagEnum.ADD,
                                        orderRefund.getOrderRefundId(), GoodsMaterialStockAccBillTypeEnum.D, orderDelivery.getStorageStockId(), orderDelivery.getStorageStockName());

                                refundNum = 0;
                            } else {

                                orderDeliveryDetail.setRefundNum((orderDeliveryDetail.getSendNum()));
                                orderDelivery.setRefundNum(orderDelivery.getRefundNum()+refundNum);
                                jxGoodsLogic.addMaterialStock(orderDetail.getGoodsMaterialId(), (orderDeliveryDetail.getSendNum()-orderDeliveryDetail.getRefundNum()), orderDelivery.getStorageStockId(), orderDelivery.getStorageStockId());

                                goodsMaterialStockAccLogic.add(orderDetail.getGoodsMaterialId(), orderDetail.getPrice(), (orderDeliveryDetail.getSendNum()-orderDeliveryDetail.getRefundNum()), DirectFlagEnum.ADD,
                                        orderRefund.getOrderRefundId(), GoodsMaterialStockAccBillTypeEnum.D, orderDelivery.getStorageStockId(), orderDelivery.getStorageStockName());

                                refundNum = refundNum - orderDeliveryDetail.getSendNum();
                            }

                            if (orderDelivery.getSendNum().equals(orderDelivery.getRefundNum())){
                                orderDelivery.setStatus("REFUND_PRICE");
                            }else {
                                orderDelivery.setStatus("PART_REFUND");
                            }

                            orderDelivery.setType("NO");
                            orderDelivery.setRefundId(orderRefund.getOrderRefundId());
                            orderDelivery.updateById();
                        }


                        orderDetail.setBeforeRefundNum(refundNum);
                        orderDetail.updateById();

                    }

                    }
                }

        }

    }


    private void refundOrder(OrderRefund orderRefund,String refundMessage,Boolean exam) throws WxPayException {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        OrderInfo orderInfo = orderInfoService.getById(orderRefund.getOrderId());

        orderRefundService.lambdaUpdate()
                .eq(OrderRefund::getOrderRefundId, orderRefund.getOrderRefundId())
                .set(exam,OrderRefund::getExamineStatus, OrderExamineEnum.OK.toString())
                .set(exam,OrderRefund::getRefundMessage,refundMessage)
                .set(exam,OrderRefund::getExamineTime, new Date())
                .set(OrderRefund::getOrderStatus, OrderStatusEnum.OVER.toString())
                .set(OrderRefund::getOverTime,new Date())
                .update();
        //退款
        this.refund(orderRefund);

        String orderId = orderRefund.getOrderId();
        int totalNum = orderInfo.getTotalNum();
        List<OrderDetail> orderDetails = orderDetailService.lambdaQuery()
                .eq(OrderDetail::getOrderId, orderId)
                .eq(OrderDetail::getRefund,true)
                .list();

        orderDetails.forEach(v -> v.setRefundTime(new Date()).setRefundBy(adminUser.getNickName()));
        orderDetailService.updateBatchById(orderDetails);

        int refundNum = orderDetails.stream().filter(OrderDetail::getRefund).collect(Collectors.reducing(0, OrderDetail::getRefundNum, (i, j) -> i + j));
        if (totalNum - refundNum == 0) {
            orderInfoService.lambdaUpdate()
                    .eq(OrderInfo::getOrderId, orderId)
                    .set(OrderInfo::getOrderStatus, OrderStatusEnum.CLOSE.toString())
                    .set(OrderInfo::getRefundFlag, RefundFlagEnum.ALL.toString())
                    .update();
            //退优惠券
            couponLogic.refundCoupon(orderInfo.getUserCouponId());
        } else {
            orderInfoService.lambdaUpdate()
                    .eq(OrderInfo::getOrderId, orderId)
                    .set(OrderInfo::getOrderStatus,orderInfo.getLastOrderStatus())
                    .set(OrderInfo::getRefundFlag, RefundFlagEnum.PARTLY.toString())
                    .update();
        }
    }



    /**
     * 商家确认收货
     */
    @Transactional
    public void ack(String orderRefundId) throws RemoteServiceException, WxPayException {

        OrderRefund orderRefund = orderRefundService.getById(orderRefundId);

        this.refundOrder(orderRefund,"",false);
    }

    /**
     * 查看物流
     */
    public List<ExpressInfo> queryExpressInfo(String logisticsNo){
        List<ExpressInfo> list = expressInfoService.lambdaQuery()
                .eq(ExpressInfo::getLogisticsNo, logisticsNo).list();
        if (CollectionUtils.isNotEmpty(list)){
            return list;
        }
        return null;
    }






    /**
     * 备注
     */
    public void remark(String orderRefundId, String remark) {
        orderRefundService.lambdaUpdate().set(OrderRefund::getRemark, remark).eq(OrderRefund::getOrderRefundId, orderRefundId).update();
    }




    /**
     * 退款
     *
     * @param orderRefund
     * @throws RemoteServiceException
     * @throws WxPayException
     */
    public void refund(OrderRefund orderRefund) throws RemoteServiceException{
        String orderId = orderRefund.getOrderId();
        List<OrderDetail> list = orderDetailService.lambdaQuery()
                .eq(OrderDetail::getOrderId, orderId)
                .eq(OrderDetail::getRefund, true).list();

        OrderInfo orderInfo = orderInfoService.getById(orderId);

        for (OrderDetail orderDetail : list) {
            double div = ArithUtils.div(orderDetail.getRefundNum(), orderDetail.getNum(), 4);
            double mul = ArithUtils.mul(orderDetail.getShareAmount().doubleValue(), div, 2);
            BigDecimal totalShareAmount  = BigDecimal.valueOf(mul);

            //1=非团购商品 2=团购商品
            log.info("【退款开始：】重置结算flag={}金额，需要减掉的金额{}",1, totalShareAmount.doubleValue());
            orderShareLogic.reloadAmount(orderId, totalShareAmount,1);
        }

        log.info("【退款开始：】退款金额{}", orderRefund.getRefundAmount().doubleValue());
        if(orderRefund.getPayAmount().doubleValue() == 0){
            return;
        }
        wechatLogic.refund(orderInfo.getTransactionId(), orderRefund.getOrderRefundId(), orderRefund.getPayAmount().doubleValue()
                , orderRefund.getRefundAmount().doubleValue(),orderRefund.getCompanyWechatId(),orderInfo.getSource());
    }


    /**
     * 导出报表
     */
    public void downLoadOrderRefundExcel(HttpServletRequest request, HttpServletResponse response,
                                         String orderId, String orderRefundId, String userName, String phone, String orderStatus,
                                         String startCreateTime, String endCreateTime, String startExamineTime, String endExamineTime
    ) throws Exception {
        AdminUserCom adminUser = commonLogic.getAdminUser(request);

        SimpleDateFormat simpleDateFormat=new SimpleDateFormat();
        List<List<Object>> rowList=new ArrayList<>();

        String[] titles ={"订单号", "商品名称", "规格型号", "数量", "单位", "销售单价", "优惠后单价", "实际收款", "收货人姓名",
                "手机号", "收货地址","订单状态", "售后状态", "退款金额(小项)", "退款数量(小项)", "备注", "下单时间", "买家昵称", "购买渠道",
                "买家备注", "卖家备注", "网点", "业务员/网点","分佣金额","团长名称","团长手机号","团购活动id","退货说明","商户名称"};
        ExcelData excelData=new ExcelData();
        excelData.setTitles(Arrays.asList(titles));
        excelData.setName("维权订单");
        excelData.setRows(rowList);

        List<OrderDetailListBean> orderRefundDetailList = orderRefundInfoMapper.getOrderRefundDetailList(
                orderId, orderRefundId, userName, phone, orderStatus, startCreateTime, endCreateTime, startExamineTime, endExamineTime,adminUser.getCompanyWechatIds());

        for (OrderDetailListBean orderDetailListBean:orderRefundDetailList) {
            List<Object> row=new ArrayList<>();
            rowList.add(row);

            row.add(orderDetailListBean.getOrderId());
            row.add(orderDetailListBean.getGoodsName());
            row.add(orderDetailListBean.getGoodsSpecValue());
            row.add(orderDetailListBean.getNum());
            row.add("台");
            row.add(orderDetailListBean.getPrice());
            row.add(orderDetailListBean.getPayAmount().divide(new BigDecimal(orderDetailListBean.getNum()), 2, BigDecimal.ROUND_HALF_UP));
            row.add(orderDetailListBean.getPayAmount());
            row.add(orderDetailListBean.getReceUserName());
            row.add(orderDetailListBean.getRecePhone());
            row.add(orderDetailListBean.getAddress());
            if(StringUtils.isNotBlank(orderDetailListBean.getOrderStatus())){
                row.add(Enum.valueOf(OrderStatusEnum.class,orderDetailListBean.getOrderStatus()).getName());
            }else{
                row.add("");
            }
            if (StringUtils.isNotBlank(orderDetailListBean.getRefundFlag())) {
                row.add(RefundFlagEnum.valueOf(orderDetailListBean.getRefundFlag()).getName());
            }else{
                row.add("");
            }
            row.add(orderDetailListBean.getRefundAmount());
            row.add(orderDetailListBean.getRefundNum());
            row.add(orderDetailListBean.getRemark());
            row.add(DateUtils.formatDate(orderDetailListBean.getCreateTime()));
            row.add(orderDetailListBean.getUserName());
            row.add(orderDetailListBean.getWorkerName());
            row.add(orderDetailListBean.getBuyerMsg());
            row.add(orderDetailListBean.getRefundMessage());
            row.add(orderDetailListBean.getWebsitName());
            row.add(orderDetailListBean.getWorkerNameWithWebsitName());
            row.add(orderDetailListBean.getShareAmount());
            row.add(orderDetailListBean.getNickName());
            row.add(orderDetailListBean.getMobile());
            row.add(orderDetailListBean.getPromotionGroupId());
            row.add(orderDetailListBean.getRefundExplain());
            row.add(orderDetailListBean.getCompanyWechatName());
        }


        ExcelUtils.exportExcel(request,response,String.format("维权订单导出%s.xlsx", simpleDateFormat.format(new Date())),excelData);

    }

    @Transactional(rollbackFor = Exception.class)
    public void examineRefund(RefundOrderBody refundOrderBody) throws Exception {

        this.examine(refundOrderBody.getOrderRefundId(), refundOrderBody.getExamineStatus(),refundOrderBody.getRefundMessage(),refundOrderBody);



    }

    public void examineRefundV2(RefundOrderBody refundOrderBody) throws Exception {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        OrderRefund orderRefund = orderRefundService.getById(refundOrderBody.getOrderRefundId());

        List<OrderDetail> list = orderDetailService.lambdaQuery().eq(OrderDetail::getOrderId, orderRefund.getOrderId()).list();
        List<OrderRefundCode> orderDetailCodes = orderRefundCodeService.lambdaQuery()
                .eq(OrderRefundCode::getOrderId, orderRefund.getOrderId()).list();

        refundOrderBody.setOrderRefundCodes(orderDetailCodes);



        if (!orderRefund.getRefundType().equals("REFUND_GOODS"))
            return;



        if (adminUser.getJoinCode().equals("CODE")){


            this.checkCode(list,refundOrderBody);

        }

        Boolean isR=false;


        //库存扣除 // 库存变更台账
        List<OrderDetail> orderDetails = orderDetailService.lambdaQuery().eq(OrderDetail::getOrderId, orderRefund.getOrderId()).list();
        for (OrderDetail orderDetail : orderDetails) {
            if (orderDetail.getIsVr() || StringUtil.isEmpty(orderDetail.getGoodsMaterialId()))
                continue;

            GoodsSpec goodsSpec = goodsSpecService.getById(orderDetail.getGoodsSpecId());

            if (goodsSpec == null || StringUtil.isEmpty(goodsSpec.getGoodsCode()))
                throw new RemoteServiceException("未找到对应商品规格");

            orderDetail.setGoodsMaterialId(goodsSpec.getGoodsCode());

            if (orderDetail.getRefund() && !orderDetail.getRefundNum().equals(0)) {


                List<OrderDeliveryDetail> orderDeliveryDetails = orderDeliveryDetailService.lambdaQuery().eq(OrderDeliveryDetail::getOrderDetailId, orderDetail.getOrderDetailId())
                        .eq(OrderDeliveryDetail::getRefundNum, 0).list();

                Integer refundNum = orderDetail.getRefundNum();

                for (OrderDeliveryDetail orderDeliveryDetail : orderDeliveryDetails) {

                    if (refundNum < 1)
                        break;

                    if ((orderDeliveryDetail.getSendNum()-orderDeliveryDetail.getRefundNum()) < 1)
                        continue;

                    OrderDelivery orderDelivery = orderDeliveryService.getById(orderDeliveryDetail.getDeliveryId());
                    if (refundNum <= orderDeliveryDetail.getSendNum() && refundNum > 0) {

                        orderDeliveryDetail.setRefundNum(orderDeliveryDetail.getRefundNum()+refundNum);
                        orderDelivery.setRefundNum(orderDelivery.getRefundNum()+refundNum);

                        jxGoodsLogic.addMaterialStock(orderDetail.getGoodsMaterialId(), orderDetail.getRefundNum(), orderDelivery.getStorageStockId(), orderDelivery.getStorageStockId());

                        goodsMaterialStockAccLogic.add(orderDetail.getGoodsMaterialId(), orderDetail.getPrice(), orderDetail.getRefundNum(), DirectFlagEnum.ADD,
                                orderRefund.getOrderRefundId(), GoodsMaterialStockAccBillTypeEnum.D, orderDelivery.getStorageStockId(), orderDelivery.getStorageStockName());

                        refundNum = 0;
                    }else {

                        orderDeliveryDetail.setRefundNum(orderDeliveryDetail.getRefundNum()+refundNum);
                        orderDelivery.setRefundNum(orderDelivery.getRefundNum()+refundNum);

                        jxGoodsLogic.addMaterialStock(orderDetail.getGoodsMaterialId(), orderDeliveryDetail.getSendNum(), orderDelivery.getStorageStockId(), orderDelivery.getStorageStockId());

                        goodsMaterialStockAccLogic.add(orderDetail.getGoodsMaterialId(), orderDetail.getPrice(), orderDeliveryDetail.getSendNum(), DirectFlagEnum.ADD,
                                orderRefund.getOrderRefundId(), GoodsMaterialStockAccBillTypeEnum.D, orderDelivery.getStorageStockId(), orderDelivery.getStorageStockName());

                        refundNum = refundNum - orderDeliveryDetail.getSendNum();
                    }

                    if (orderDelivery.getSendNum().equals(orderDelivery.getRefundNum())){
                        orderDelivery.setStatus("REFUND");
                    }else {
                        orderDelivery.setStatus("PART_REFUND");
                    }

                    orderDeliveryDetail.updateById();

                    orderDelivery.setType("NO");
                    orderDelivery.setRefundId(orderRefund.getOrderRefundId());
                    orderDelivery.updateById();
                }


                if (adminUser.getJoinCode().equals("CODE") && !isR) {
                    //加条码
                    jxGoodsLogic.addCodeAcc(refundOrderBody.getOrderRefundCodes());

                    isR = true;
                }

                //变更销售台账退货记录
                jxGoodsLogic.subGoodsSaleLedger(orderRefund.getOrderRefundId());
            }
        }

    }

        private void checkCode(List<OrderDetail> list,RefundOrderBody refundOrderBody) {

            if (CollectionUtils.isEmpty(refundOrderBody.getOrderRefundCodes()))
                throw new RemoteServiceException("条码不能为空");

        for (OrderDetail orderDetail : list) {
            if (orderDetail.getIsVr() || StringUtil.isEmpty(orderDetail.getGoodsMaterialId()))
                continue;

            if (orderDetail.getRefund() && orderDetail.getRefundNum() > 0) {

                List<GoodsMaterialItem> goodsMaterialItems = goodsMaterialItemService.lambdaQuery()
                        .eq(GoodsMaterialItem::getGoodsMaterialId, orderDetail.getGoodsMaterialId()).list();
                for (GoodsMaterialItem goodsMaterialItem : goodsMaterialItems) {

                    //需要条码数量
                    Integer num = goodsMaterialItem.getQty() * orderDetail.getRefundNum();

                    if (goodsMaterialItem.getUniqueCode().equals(IsYesNoEnum.YES.getKey())) {
                        List<OrderRefundCode> collect = refundOrderBody.getOrderRefundCodes().stream()
                                .filter(item -> item.getGoodsMaterialItemId().equals(goodsMaterialItem.getId())
                                        && item.getOrderDetailId().equals(orderDetail.getOrderDetailId())
                                )
                                .collect(Collectors.toList());

                        if (collect.size() != num)
                            throw new RemoteServiceException(goodsMaterialItem.getName() + "此条码名称数量不对，条码数量" + collect.size() + "需要数量" + num);

                    } else {
                        List<OrderRefundCode> collect = refundOrderBody.getOrderRefundCodes().stream()
                                .filter(item -> item.getGoodsMaterialItemId().equals(goodsMaterialItem.getId())
                                        && item.getOrderDetailId().equals(orderDetail.getOrderDetailId())
                                )
                                .collect(Collectors.toList());

                        if (!collect.get(0).getStockQty().equals(num))
                            throw new RemoteServiceException(goodsMaterialItem.getName() + "此条码名称数量不对，条码数量" + collect.size() + "需要数量" + num);
                    }
                }
            }
        }
    }

    public String test() {

        String s = HttpUtil.get("https://geo.datav.aliyun.com/areas_v3/bound/geojson?code=100000_full");
        return s;
    }
}
