package com.gree.mall.manager.logic.material.manage;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gree.mall.manager.bean.PayDetail;
import com.gree.mall.manager.bean.admin.AdminUserCom;
import com.gree.mall.manager.bean.material.manage.*;
import com.gree.mall.manager.bean.material.stock.WebsitSalesCategoryVO;
import com.gree.mall.manager.bean.material.stock.WebsitSalesGoodsVO;
import com.gree.mall.manager.commonmapper.MaterialMapper;
import com.gree.mall.manager.constant.SybConstants;
import com.gree.mall.manager.enums.IsYesNoEnum;
import com.gree.mall.manager.enums.UserTypeEnum;
import com.gree.mall.manager.enums.admin.AdminWebsitTypeEnum;
import com.gree.mall.manager.enums.base.BaseEnum;
import com.gree.mall.manager.enums.engin.ItemSourceTypeEnum;
import com.gree.mall.manager.enums.material.*;
import com.gree.mall.manager.exception.RemoteServiceException;
import com.gree.mall.manager.logic.common.AllInPayLogic;
import com.gree.mall.manager.logic.common.CommonLogic;
import com.gree.mall.manager.logic.common.WechatLogic;
import com.gree.mall.manager.logic.engin.WebsitGoodsMangerLogic;
import com.gree.mall.manager.logic.material.stock.WebitSalesStockLogic;
import com.gree.mall.manager.logic.material.stock.WorkSalesStockLogic;
import com.gree.mall.manager.plus.entity.*;
import com.gree.mall.manager.plus.service.*;
import com.gree.mall.manager.utils.CommonUtils;
import com.gree.mall.manager.utils.excel.ExcelUtils;
import com.gree.mall.manager.zfire.bean.WebsitSalesParamBean;
import com.gree.mall.manager.zfire.util.FieldUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

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

@Slf4j
@Service
@RequiredArgsConstructor
public class WebsitSalesLogic {

    private final CommonLogic commonLogic;
    private final MaterialMapper materialMapper;
    private final WebsitSalesService websitSalesService;
    private final WebsitSalesItemService websitSalesItemService;
    private final WebsitSalesPayOrderService websitSalesPayOrderService;
    private final WebsitGoodsService websitGoodsService;
    private final WebitSalesStockLogic webitSalesStockLogic;
    private final WorkSalesStockLogic workSalesStockLogic;
    private final WebsitStockService websitStockService;
    private final WechatLogic wechatLogic;
    private final WebsitGoodsMangerLogic websitGoodsMangerLogic;
    private final OrderEnginBaseService orderEnginBaseService;
    private final WebsitNormChargeService websitNormChargeService;
    private final OrderEnginBaseItemService orderEnginBaseItemService;
    private final AdminWebsitService adminWebsitService;
    private final UserService userService;
    private final WebsitGoodsCategoryService websitGoodsCategoryService;
    private final StorageService storageService;
    private final AllInPayLogic allInPayLogic;
    private final AdminWebsitPayConfigService adminWebsitPayConfigService;
    private final WorkerGoodsRelaService workerGoodsRelaService;
    private final WorkerGoodsService workerGoodsService;
    private final MaterialConfigService materialConfigService;

    public IPage<WebsitSalesVO> page(WebsitSalesParamBean zfireParamBean) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        FieldUtils.materialParam(zfireParamBean, WebsitSalesVO.class, adminUser);

        return materialMapper.websitSalesPage(new Page(zfireParamBean.getPageNum(), zfireParamBean.getPageSize()), zfireParamBean,
                zfireParamBean.getGoodsName(),zfireParamBean.getGoodsSpecification(),zfireParamBean.getIsFilter());

    }

    public WebsitSalesBean detail(String salesId) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        WebsitSalesBean bean = new WebsitSalesBean();
        WebsitSales sales = websitSalesService.getById(salesId);
        if (sales == null)
            throw new RemoteServiceException("没有这个订单");
        BeanUtils.copyProperties(sales, bean);
        String companyId = Objects.isNull(adminUser.getAdminCompanyWechat()) ? null : adminUser.getAdminCompanyWechat().getCompanyWechatId();
        List<WebsitSalesItemBean> list = websitSalesItemService.lambdaQuery()
                .eq(StringUtils.isNotBlank(companyId), WebsitSalesItem::getCompanyWechatId, companyId)
                .eq(WebsitSalesItem::getSalesId, salesId)
                .list()
                .stream()
                .map(v -> {
                    WebsitSalesItemBean item = new WebsitSalesItemBean();
                    BeanUtils.copyProperties(v, item);
                    return item;
                }).collect(Collectors.toList());
        bean.setItems(list);

        // 当前库存数量
        if (bean.getFlag().equals(MaterialSalesFlagEnum.SAVE.getKey())) {
            List<WebsitStock> stocks = websitStockService.lambdaQuery()
                    .in(WebsitStock::getGoodsId, list.stream().map(WebsitSalesItemBean::getGoodsId).collect(Collectors.toList()))
                    .eq(WebsitStock::getCompanyWechatId, bean.getCompanyWechatId())
                    .eq(WebsitStock::getStorageId, bean.getStorageId())
                    .eq(WebsitStock::getWebsitId, bean.getWebsitId())
                    .list();
            if (CollectionUtil.isNotEmpty(stocks)) {
                Map<String, BigDecimal> stockMap = stocks.stream().collect(Collectors.toMap(WebsitStock::getGoodsId, WebsitStock::getQty));
                for (WebsitSalesItemBean itemBean : list) {
                    itemBean.setStockQty(stockMap.getOrDefault(itemBean.getGoodsId(), BigDecimal.ZERO));
                }
            }
        }

        if (bean.getFlag().equals(MaterialSalesFlagEnum.PAY_NOT_TAKE.getKey())
                || bean.getFlag().equals(MaterialSalesFlagEnum.PAY_TAKE.getKey()) ) {
            WebsitSalesPayOrder order = websitSalesPayOrderService.lambdaQuery()
                    .eq(WebsitSalesPayOrder::getCompanyWechatId, sales.getCompanyWechatId())
                    .eq(WebsitSalesPayOrder::getWebsitId, sales.getWebsitId())
                    .eq(WebsitSalesPayOrder::getOrderId, sales.getSalesId())
                    .last("limit 1")
                    .one();
            bean.setPayOrder(order);
        }
        return bean;
    }

    @Transactional(rollbackFor = Exception.class)
    public void add(WebsitSalesBean bean) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        if (Objects.isNull(adminUser.getAdminCompanyWechat())) {
            throw new RemoteServiceException("平台账号禁用操作");
        }
        bean.setCompanyWechatId(adminUser.getAdminCompanyWechat().getCompanyWechatId());
        bean.setCompanyWechatName(adminUser.getAdminCompanyWechat().getCompanyName());

        // 根据配置是否注入仓位
        final Storage storage = webitSalesStockLogic.handleStorage(adminUser, bean.getWebsitId(), bean.getGoodsType(), bean.getStorageId());
        bean.setStorageId(storage.getStorageId());
        bean.setStorageName(storage.getStorageName());

        bean.setFlag(MaterialFlagEnum.SAVE.getKey());
        bean.setOrderSource(SourceSalesEnum.SELF.getKey());

        if (bean.getSalesType().equals(WebsitSalesTypeEnum.ENGIN.getName())) {
            this.getOrderEnginBaseInfo(bean);
            bean.setBuyPeople(BuyPeopleEnum.CUSTOMER.getKey());
        }

        String salesId = commonLogic.generateNo("X" + bean.getGoodsType(), "SalesOrder" + bean.getGoodsType(), 15);
        WebsitSales sales = new WebsitSales();
        BeanUtils.copyProperties(bean, sales);

        if (CollectionUtil.isNotEmpty(bean.getItems())) {
            List<WebsitSalesItem> itemList = new ArrayList<>();
            BigDecimal totalAmount = BigDecimal.ZERO;
            for (WebsitSalesItemBean itemBean : bean.getItems()) {
                WebsitSalesItem item = new WebsitSalesItem();
                BeanUtils.copyProperties(itemBean, item);
                item.setCompanyWechatId(sales.getCompanyWechatId())
                        .setSalesId(salesId)
                        .setWebsitId(sales.getWebsitId())
                        .setWebsitName(sales.getWebsitName())
                        .setGoodsType(sales.getGoodsType())
                        .setSaleAmount(item.getPrice().multiply(item.getSalesQty()).setScale(2, BigDecimal.ROUND_HALF_UP));

                itemList.add(item);
            }

            this.goodsConditionHandle(sales, itemList);

            for (WebsitSalesItem item : itemList) {
                totalAmount = totalAmount.add(item.getSaleAmount());
            }
            sales.setTotalAmount(totalAmount);

            websitSalesItemService.saveBatch(itemList);
        }

        if (sales.getBuyPeople().equals(BuyPeopleEnum.CUSTOMER.getKey())) {
            sales.setWorkerId(null);
        }

        sales.setSalesId(salesId)
                .insert();
    }

    private void getOrderEnginBaseInfo(WebsitSalesBean bean) {
        if (StringUtils.isBlank(bean.getOrderEnginBaseId())) {
            throw new RemoteServiceException("请选择工程基础资料");
        }
        OrderEnginBase base = orderEnginBaseService.lambdaQuery()
                .eq(OrderEnginBase::getCompanyWechatId, bean.getCompanyWechatId())
                .eq(OrderEnginBase::getId, bean.getOrderEnginBaseId())
                .one();
        if (Objects.isNull(base)) {
            throw new RemoteServiceException("工程基础资料不存在");
        }

        bean.setProjectName(base.getProjectName())
                .setProjectNo(base.getProjectNo())
                .setManger(base.getManger())
                .setMobile(base.getMobile())
                .setStartTime(base.getStartTime())
                .setEndTime(base.getEndTime())
                .setProvince(base.getProvince())
                .setProvinceId(base.getProvinceId())
                .setCity(base.getCity())
                .setCityId(base.getCityId())
                .setArea(base.getArea())
                .setAreaId(base.getAreaId())
                .setStreet(base.getStreet())
                .setStreetId(base.getStreetId())
                .setAddress(base.getAddress());
    }

    private void goodsConditionHandle(WebsitSales sales, List<WebsitSalesItem> itemList) {
        List<WebsitGoods> goodsList = websitGoodsService.lambdaQuery()
                .eq(WebsitGoods::getCompanyWechatId, sales.getCompanyWechatId())
                .in(WebsitGoods::getGoodsId, itemList.stream().map(WebsitSalesItem::getGoodsId).collect(Collectors.toList()))
                .list();

        Map<String, List<WebsitSalesItem>> listMap = itemList.stream().collect(Collectors.groupingBy(WebsitSalesItem::getGoodsId));
        for (Map.Entry<String, List<WebsitSalesItem>> entry : listMap.entrySet()) {
            if (entry.getValue().size() > 1) {
                throw new RemoteServiceException("发现重复的\"" + entry.getValue().get(0).getGoodsName() + "\", 请检查!");
            }
        }

        Map<String, WebsitGoods> goodsMap = goodsList.stream().collect(Collectors.toMap(WebsitGoods::getGoodsId, Function.identity()));

        for (WebsitSalesItem item : itemList) {
            if (!goodsMap.containsKey(item.getGoodsId())) {
                throw new RemoteServiceException("找不到商品信息:" + item.getGoodsName());
            }
            WebsitGoods goods = goodsMap.get(item.getGoodsId());
            item.setGoodsSalesUnit(goods.getGoodsSalesUnit())
                    .setGoodsStockUnit(goods.getGoodsStockUnit())
                    .setGoodsSpecification(goods.getGoodsSpecification())
                    .setGoodsSalesConvertQty(goods.getGoodsSalesConvertQty())
                    .setConvertBitScale(1)
                    .setManageWorkerStock(goods.getManageWorkerStock());

            // 商品类型为配件时单价要先乘倍率
            if (sales.getGoodsType().equals(WebsitGoodsTypeEnum.P.getKey())) {
                final MaterialConfig config = materialConfigService.lambdaQuery()
                        .eq(MaterialConfig::getCompanyWechatId, goods.getCompanyWechatId())
                        .one();
                BigDecimal afterPrice;
                switch (goods.getPartType()) {
                    case "空调":
                        afterPrice = goods.getMarketPrice().multiply(config.getPriceRate1());
                        break;
                    case "冰箱":
                        afterPrice = goods.getMarketPrice().multiply(config.getPriceRate2());
                        break;
                    case "生活电器":
                        afterPrice = goods.getMarketPrice().multiply(config.getPriceRate3());
                        break;
                    default:
                        throw new RemoteServiceException("未找到对应配件类型倍率");
                }
                item.setPrice(afterPrice);
                item.setOrigPartsPrice(goods.getMarketPrice());
            }

            // 商品类型为辅材并且库存单位与销售单位一致时转换系数为1
            if (sales.getGoodsType().equals(WebsitGoodsTypeEnum.M.getKey())
                    && StrUtil.equals(StrUtil.trim(goods.getGoodsStockUnit()), StrUtil.trim(goods.getGoodsSalesUnit()))) {
                goods.setGoodsSalesConvertQty(BigDecimal.ONE);
            }

            BigDecimal convertQty = item.getSalesQty().divide(goods.getGoodsSalesConvertQty(), 1, BigDecimal.ROUND_UP);
            BigDecimal totalSaleValue = item.getSalesQty().multiply(item.getPrice());
            BigDecimal convertPrice = totalSaleValue.divide(convertQty, 2, BigDecimal.ROUND_DOWN);

            if (sales.getGoodsType().equals(WebsitGoodsTypeEnum.P.getKey()) || goods.getGoodsSalesConvertQty().compareTo(BigDecimal.ONE) == 0) {
                convertQty = item.getSalesQty();
                convertPrice = item.getPrice();
                item.setSaleAmount(totalSaleValue);
            }

            // 类型为辅材时注入师傅辅材id
            if (sales.getGoodsType().equals(WebsitGoodsTypeEnum.M.getKey())
                    && (StringUtils.isBlank(item.getManageWorkerStock()) || item.getManageWorkerStock().equals(IsYesNoEnum.YES.getKey()))) {
                final WorkerGoodsRela goodsRela = workerGoodsRelaService.lambdaQuery()
                        .eq(WorkerGoodsRela::getCompanyWechatId, goods.getCompanyWechatId())
                        .eq(WorkerGoodsRela::getWebsitGoodsId, goods.getGoodsId())
                        .one();
                if (Objects.nonNull(goodsRela)) {
                    final WorkerGoods workerGoods = workerGoodsService.getById(goodsRela.getWorkerGoodsId());
                    if (workerGoods.getStatus().equals(StateEnum.ON.getKey())) {
                        item.setWorkerGoodsId(goodsRela.getWorkerGoodsId())
                                .setWorkerGoodsName(goodsRela.getWorkerGoodsName());
                    }
                }
            }

            item.setConvertQty(convertQty)
                .setConvertPrice(convertPrice);
        }

    }

    @Transactional(rollbackFor = Exception.class)
    public void edit(WebsitSalesBean bean) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        if (Objects.isNull(adminUser.getAdminCompanyWechat())) {
            throw new RemoteServiceException("平台账号禁用操作");
        }

        WebsitSales sales = websitSalesService.getById(bean.getSalesId());
        if (!sales.getFlag().equals(MaterialFlagEnum.SAVE.getKey())) {
            throw new RemoteServiceException("销售单非\"保存\"状态，不能再编辑");
        }

        bean.setCompanyWechatId(adminUser.getAdminCompanyWechat().getCompanyWechatId());
        bean.setCompanyWechatName(adminUser.getAdminCompanyWechat().getCompanyName());

        // 根据配置是否注入仓位
        final Storage storage = webitSalesStockLogic.handleStorage(adminUser, sales.getWebsitId(), sales.getGoodsType(), bean.getStorageId());
        bean.setStorageId(storage.getStorageId());
        bean.setStorageName(storage.getStorageName());

        bean.setFlag(MaterialFlagEnum.SAVE.getKey());
        bean.setGoodsType(sales.getGoodsType());

        if (bean.getSalesType().equals(WebsitSalesTypeEnum.ENGIN.getName())) {
            this.getOrderEnginBaseInfo(bean);
            bean.setBuyPeople(BuyPeopleEnum.CUSTOMER.getKey());
        }

        sales = new WebsitSales();
        BeanUtils.copyProperties(bean, sales);

        if (CollectionUtil.isNotEmpty(bean.getItems())) {
            websitSalesItemService.lambdaUpdate()
                    .eq(WebsitSalesItem::getCompanyWechatId, bean.getCompanyWechatId())
                    .eq(WebsitSalesItem::getSalesId, bean.getSalesId())
                    .remove();
            List<WebsitSalesItem> itemList = new ArrayList<>();
            BigDecimal totalAmount = BigDecimal.ZERO;
            for (WebsitSalesItemBean itemBean : bean.getItems()) {
                WebsitSalesItem item = new WebsitSalesItem();
                BeanUtils.copyProperties(itemBean, item);
                item.setCompanyWechatId(sales.getCompanyWechatId())
                        .setSalesId(sales.getSalesId())
                        .setWebsitId(sales.getWebsitId())
                        .setWebsitName(sales.getWebsitName())
                        .setGoodsType(sales.getGoodsType())
                        .setSaleAmount(item.getPrice().multiply(item.getSalesQty()).setScale(2, BigDecimal.ROUND_HALF_UP));
                itemList.add(item);
            }

            this.goodsConditionHandle(sales, itemList);

            for (WebsitSalesItem item : itemList) {
                totalAmount = totalAmount.add(item.getSaleAmount());
            }
            sales.setTotalAmount(totalAmount);

            websitSalesItemService.saveBatch(itemList);
        }

        if (sales.getBuyPeople().equals(BuyPeopleEnum.CUSTOMER.getKey())) {
            sales.setWorkerId(null);
        }

        sales.updateById();
    }

    @Transactional(rollbackFor = Exception.class)
    public void submit(String salesId, BigDecimal price, String urlPrc, String remark) throws Exception {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        WebsitSales sales = websitSalesService.getById(salesId);
        if (!sales.getCompanyWechatId().equals(adminUser.getCompanyWechatId())) {
            throw new RuntimeException("关键信息错误");
        }

        sales.setSubmitTime(DateUtil.date());
        sales.setFlag(MaterialSalesFlagEnum.SUBMIT.getKey());

        if (sales.getPayType().equals(PayTypeEnum.CASH.getKey())
                || sales.getPayType().equals(PayTypeEnum.ENGIN.getKey())) {
            sales.setFlag(MaterialSalesFlagEnum.PAY_NOT_TAKE.getKey())
                    .setPayFlag(JudgeEnum.YES.getKey());

            if (sales.getPayType().equals(PayTypeEnum.CASH.getKey())) {
                // 生成现金支付记录
                WebsitSalesPayOrder order = new WebsitSalesPayOrder();
                order.setCompanyWechatId(sales.getCompanyWechatId());
                order.setCompanyWechatName(sales.getCompanyWechatName());
                order.setGoodsType(sales.getGoodsType());
                order.setWebsitId(sales.getWebsitId());
                order.setWebsitName(sales.getWebsitName());
                order.setOrderId(sales.getSalesId());
                order.setPayType(PayTypeEnum.CASH.getKey());
                order.setPayFlag(JudgeEnum.YES.getKey());
                order.setPayTime(sales.getSubmitTime());
                order.setPayValue(sales.getTotalAmount());
                order.setOrderType(PayOrderTypeEnum.S.getKey());
                order.setOrderSource(sales.getGoodsType().equals(WebsitGoodsTypeEnum.M.getKey()) ? OrderSourceEnum.M_SALES.getKey() : OrderSourceEnum.P_SALES.getKey());
                order.insert();
            }

        }

        websitSalesService.lambdaUpdate()
                .set(WebsitSales::getFlag, sales.getFlag())
                .set(WebsitSales::getPayFlag, sales.getPayFlag())
                .set(WebsitSales::getSubmitBy, adminUser.getNickName())
                .set(WebsitSales::getSubmitTime, sales.getSubmitTime())
                .eq(WebsitSales::getSalesId, salesId)
                .update();

        if (sales.getSalesType().equals(WebsitSalesTypeEnum.ENGIN.getName())
                && (sales.getPayType().equals(PayTypeEnum.CASH.getKey()) || sales.getPayType().equals(PayTypeEnum.ENGIN.getKey()))) {

            if (sales.getPayType().equals(PayTypeEnum.CASH.getKey())) {
                price = sales.getTotalAmount();
            }

            if(Objects.nonNull(price)) {

                if (price.compareTo(new BigDecimal("0")) == -1)
                    throw new RemoteServiceException("金额不能为负数");
                if (sales.getTotalAmount().compareTo(price) == -1)
                    throw new RemoteServiceException("收取金额，超过了应收金额");
                websitGoodsMangerLogic.givePrice(price, sales.getOrderEnginBaseId(), urlPrc, remark, salesId, sales.getGoodsType());
            }


            websitGoodsMangerLogic.upManage(sales.getOrderEnginBaseId(),sales.getGoodsType());

        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void confirm(String salesId, String storageId) throws Exception {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        WebsitSales sales = websitSalesService.getById(salesId);
        if (!sales.getCompanyWechatId().equals(adminUser.getCompanyWechatId())) {
            throw new RuntimeException("关键信息错误");
        }
        if (!sales.getFlag().equals(MaterialSalesFlagEnum.PAY_NOT_TAKE.getKey())) {
            MaterialSalesFlagEnum flagEnum = BaseEnum.keyToEnumNotNull(MaterialSalesFlagEnum.class, sales.getFlag());
            throw new RemoteServiceException("销售单为\"" + flagEnum.getRemark() + "\"状态，不能确认提货");
        }

        if ((sales.getIsImport() || sales.getOrderSource().equals(SourceSalesEnum.ONLINE.getKey())) && StringUtils.isBlank(storageId) ) {
            throw new RemoteServiceException("请选择仓库");
        }
        Storage storage = null;
        if (sales.getIsImport() || sales.getOrderSource().equals(SourceSalesEnum.ONLINE.getKey())) {
            storage = webitSalesStockLogic.handleStorage(adminUser, sales.getWebsitId(), sales.getGoodsType(), storageId);
            sales.setStorageId(storageId)
                    .setStorageName(storage.getStorageName());
        }

        sales.setConfirmTime(DateUtil.date())
                .setConfirmBy(adminUser.getNickName())
                .setFlag(MaterialSalesFlagEnum.PAY_TAKE.getKey());

        websitSalesService.lambdaUpdate()
                .set(WebsitSales::getFlag, sales.getFlag())
                .set(WebsitSales::getConfirmBy, sales.getConfirmBy())
                .set(WebsitSales::getConfirmTime, sales.getConfirmTime())
                .set(Objects.nonNull(storage), WebsitSales::getStorageId, sales.getStorageId())
                .set(Objects.nonNull(storage), WebsitSales::getStorageName, sales.getStorageName())
                .eq(WebsitSales::getSalesId, sales.getSalesId())
                .update();
        // 已支付提货减库存
        if (sales.getFlag().equals(MaterialSalesFlagEnum.PAY_TAKE.getKey())) {
            List<WebsitSalesItem> salesItems = websitSalesItemService.lambdaQuery()
                    .eq(WebsitSalesItem::getCompanyWechatId, adminUser.getCompanyWechatId())
                    .eq(WebsitSalesItem::getSalesId, salesId)
                    .list();
            // 处理网点库存
            webitSalesStockLogic.newSalesStock(sales, salesItems, "销售订单");

            if (StringUtils.isNotBlank(sales.getWorkerId())) {
                // 处理师傅库存
                workSalesStockLogic.salesInStock(sales, salesItems, "销售订单");
            }
        }
    }

    /**
     * 改变支付方式 （师傅在线下单后改变现金）
     * @param salesId
     */
    public void changeCash(String salesId) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        WebsitSales sales = websitSalesService.getById(salesId);
        if (!sales.getCompanyWechatId().equals(adminUser.getCompanyWechatId())) {
            throw new RuntimeException("关键信息错误");
        }
        websitSalesService.lambdaUpdate()
                .set(WebsitSales::getFlag, MaterialSalesFlagEnum.PAY_NOT_TAKE.getKey())
                .set(WebsitSales::getPayType, PayTypeEnum.CASH.getKey())
                .eq(WebsitSales::getSalesId, salesId)
                .update();

        if (sales.getSalesType().equals(WebsitSalesTypeEnum.ENGIN.getName())) {

            websitGoodsMangerLogic.givePrice(sales.getTotalAmount(), sales.getOrderEnginBaseId(), null, null, salesId, sales.getGoodsType());
            websitGoodsMangerLogic.upManage(sales.getOrderEnginBaseId(), sales.getGoodsType());
        }
    }

    public List<WebsitSalesCategoryVO> existStockCategory(String websitId) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        List<WebsitSalesCategoryVO> categoryList = materialMapper.existStockCategory(adminUser.getCompanyWechatId(), websitId);
        // 分组分类
        Map<String, WebsitSalesCategoryVO> parentMap = categoryList.stream()
                .collect(Collectors.toMap(WebsitSalesCategoryVO::getParentCategoryId, Function.identity(), (key1, key2) -> key1));

        Map<String, List<WebsitSalesCategoryVO>> listMap = categoryList.stream()
                .collect(Collectors.groupingBy(WebsitSalesCategoryVO::getParentCategoryId));

        List<WebsitSalesCategoryVO> voList = new ArrayList<>();
        for (Map.Entry<String, WebsitSalesCategoryVO> entry : parentMap.entrySet()) {
            WebsitSalesCategoryVO categoryVO = entry.getValue();

            List<WebsitSalesCategoryVO> categoryVOList = listMap.get(categoryVO.getParentCategoryId());

            WebsitSalesCategoryVO newCategory = new WebsitSalesCategoryVO();
            newCategory.setParentCategoryId("0");
            newCategory.setParentCategoryName("0");
            newCategory.setCategoryId(categoryVO.getParentCategoryId());
            newCategory.setCategoryName(categoryVO.getParentCategoryName());
            newCategory.setItems(categoryVOList);

            voList.add(newCategory);
        }

        return voList;
    }

    public List<WebsitSalesGoodsVO> existStockGoods(String saleType, String websitId, String categoryId, WebsitGoodsTypeEnum type,
                                                    String goodsName, String orderEnginBaseId) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        String companyId = "";
        if (Objects.nonNull(adminUser.getAdminCompanyWechat())) {
            companyId = adminUser.getAdminCompanyWechat().getCompanyWechatId();
        }

        if (saleType.equals(WebsitSalesTypeEnum.ENGIN.getName()) && StringUtils.isBlank(orderEnginBaseId)) {
                throw new RemoteServiceException("请先选择工程基础资料");
        }
        List<WebsitSalesGoodsVO> goodsList;
        if (type.getKey().equals(WebsitGoodsTypeEnum.M.getKey())) {
            goodsList = materialMapper.existStockGoods(companyId, websitId, type.getKey(), categoryId, goodsName, null);
        } else {
            goodsList = materialMapper.notStockGoods(companyId, websitId, type.getKey(), goodsName);
        }

        if (saleType.equals(WebsitSalesTypeEnum.ENGIN.getName())) {
            if (StringUtils.isBlank(orderEnginBaseId)) {
                throw new RemoteServiceException("请先选择工程基础资料");
            }

            // 查询出工程基础资料明细对应辅材和配件价格
            List<OrderEnginBaseItem> items = orderEnginBaseItemService.lambdaQuery()
                    .eq(OrderEnginBaseItem::getGoodsType, type.getKey())
                    .eq(OrderEnginBaseItem::getOrderEnginBaseId, orderEnginBaseId)
                    .list();

            if (CollectionUtil.isNotEmpty(items)) {
                Map<String, OrderEnginBaseItem> itemMap = items.stream()
                        .collect(Collectors.toMap(OrderEnginBaseItem::getGoodsId, Function.identity()));
                for (WebsitSalesGoodsVO vo : goodsList) {
                    if (itemMap.containsKey(vo.getGoodsId())) {
                        OrderEnginBaseItem item = itemMap.get(vo.getGoodsId());
                        vo.setPrice(item.getNormAmount())
                                .setItemSourceType(ItemSourceTypeEnum.ENGIN.getKey())
                                .setItemSourceId(item.getId());
                    }
                }
            }
        }

        return goodsList;
    }

    @Transactional
    public PayDetail pay(String salesId, String payConfigId, HttpServletRequest request) throws Exception {
        WebsitSales sales = websitSalesService.getById(salesId);
        if (Objects.isNull(sales)) {
            throw new RemoteServiceException("销售单号不存在");
        }

        final AdminWebsitPayConfig payConfig = adminWebsitPayConfigService.getById(payConfigId);
        if (Objects.isNull(payConfig) || !payConfig.getStatus()) {
            throw new RemoteServiceException("支付配置信息异常");
        }

        // 微信扫码支付改为通联
//        String ip = IpUtil.getIpAddr(request);
//        wechatLogic.paymentNATIVE(salesId, sales.getTotalAmount(), "", "N", ip,sales.getCompanyWechatId());

        WebsitSalesPayOrder payOrder = new WebsitSalesPayOrder();
        payOrder.setId(IdWorker.getIdStr())
                .setCompanyWechatId(sales.getCompanyWechatId())
                .setCompanyWechatName(sales.getCompanyWechatName())
                .setGoodsType(sales.getGoodsType())
                .setWebsitId(sales.getWebsitId())
                .setWebsitName(sales.getWebsitName())
                .setOrderId(sales.getSalesId())
                .setOutTradeNo(payOrder.getId())
                .setPayType(PayTypeEnum.ALLINPAY.getKey())
                .setOrderCreateTime(sales.getCreateTime())
                .setPayValue(sales.getTotalAmount())
                .setOrgId(payConfig.getOrgId())
                .setMchNo(payConfig.getMchNo())
                .setAppid(payConfig.getAppid())
                .setOrderType(PayOrderTypeEnum.S.getKey())
                .setRunTime(DateUtil.offsetSecond(DateUtil.date(), 15))
                .setOrderSource(sales.getGoodsType().equals(WebsitGoodsTypeEnum.M.getKey()) ? OrderSourceEnum.M_SALES.getKey() : OrderSourceEnum.P_SALES.getKey())
                .setIsDeliver(false);


        // 请求通联得到结果
        Map<String, String> resMap = allInPayLogic.serviceUnifiedOrder(payOrder, SybConstants.PAY_TYPE_W01);

        if (!resMap.get("trxstatus").equals("0000")) {
            throw new RemoteServiceException("通联统一支付接口执行失败：" + resMap.get("errmsg"));
        }

        payOrder.setOrderNo(resMap.get("trxid"))
                .insert();

        PayDetail payDetail = new PayDetail();
        payDetail.setCodeUrl(resMap.get("payinfo"));
        payDetail.setId(payOrder.getId());
        log.info("通联支付payDetail:{}", JSONObject.toJSONString(payDetail));
        return payDetail;
    }


    public List<WebsitSalesGoodsVO> existStockGoodsList(String websitId, String categoryId, WebsitGoodsTypeEnum type,
                                                        String goodsName, String goodsSpecification) {

        AdminUserCom adminUser = commonLogic.getAdminUser();
        String companyId = "";
        if (Objects.nonNull(adminUser.getAdminCompanyWechat())) {
            companyId = adminUser.getAdminCompanyWechat().getCompanyWechatId();
        }

        List<WebsitSalesGoodsVO> goodsList = materialMapper.existStockGoods(companyId, websitId, type.getKey(), categoryId, goodsName,goodsSpecification);
        if (CollectionUtil.isNotEmpty(goodsList) && WebsitGoodsTypeEnum.P.getKey().equals(type.getKey())) {
            for (WebsitSalesGoodsVO vo : goodsList) {
                this.computeSalesPrice(companyId, vo);
            }
        }
        return goodsList;

    }

    private void computeSalesPrice(String companyId, WebsitSalesGoodsVO vo) {
        final MaterialConfig materialConfig = materialConfigService.lambdaQuery()
                .eq(MaterialConfig::getCompanyWechatId, companyId)
                .one();
        switch (Optional.ofNullable(vo.getPartType()).orElse("")) {
            case "空调":
                vo.setSalesPrice(vo.getMarketPrice().multiply(materialConfig.getPriceRate1()).setScale(2, BigDecimal.ROUND_HALF_UP));
                break;
            case "冰箱":
                vo.setSalesPrice(vo.getMarketPrice().multiply(materialConfig.getPriceRate2()).setScale(2, BigDecimal.ROUND_HALF_UP));
                break;
            case "生活电器":
                vo.setSalesPrice(vo.getMarketPrice().multiply(materialConfig.getPriceRate3()).setScale(2, BigDecimal.ROUND_HALF_UP));
                break;
            default:
                vo.setSalesPrice(vo.getMarketPrice().multiply(new BigDecimal("1.2")).setScale(2, BigDecimal.ROUND_HALF_UP));
                break;
        }
    }

    @Transactional
    public String importMaterialData(MultipartFile file) throws Exception {
        String batchId = StrUtil.uuid();
        AdminUserCom adminUser = commonLogic.getAdminUser();

        String companyWechatId = Objects.nonNull(adminUser.getAdminCompanyWechat()) ? adminUser.getAdminCompanyWechat().getCompanyWechatId() : null;
        String companyName = Objects.nonNull(adminUser.getAdminCompanyWechat()) ? adminUser.getAdminCompanyWechat().getCompanyName() : null;

        List<WebsitGoods> websitGoods = websitGoodsService.lambdaQuery()
                .eq(WebsitGoods::getCompanyWechatId, companyWechatId)
                .eq(WebsitGoods::getGoodsType, WebsitGoodsTypeEnum.M.getKey())
//                .eq(WebsitGoods::getStatus, StateEnum.ON.getKey())
                .eq(WebsitGoods::getNormType, NormTypeEnum.M.getKey())
                .list();

        List<AdminWebsit> websitList = adminWebsitService.lambdaQuery()
                .eq(AdminWebsit::getCompanyWechatId, companyWechatId)
                .eq(AdminWebsit::getType, AdminWebsitTypeEnum.C.getKey())
//                .eq(AdminWebsit::getStatus, true)
                .list();

        List<User> userList = userService.lambdaQuery()
                .eq(User::getCompanyWechatId, companyWechatId)
                .eq(User::getApplyType, UserTypeEnum.WORKER.getKey())
                .isNotNull(User::getWorkerNumber)
//                .eq(User::getStatus, true)
                .list();

        List<WebsitGoodsCategory> categoryList = websitGoodsCategoryService.lambdaQuery()
                .eq(WebsitGoodsCategory::getCompanyWechatId, companyWechatId)
                .list();

        Map<String, WebsitGoods> goodsMap;

        try {
            goodsMap = websitGoods.stream()
                    .collect(Collectors.toMap(WebsitGoods::getGoodsName, Function.identity()));
        } catch (Exception e) {
            throw new RemoteServiceException("系统里的辅材名称信息有重复");
        }

        Map<String, AdminWebsit> websitMap = websitList.stream()
                .collect(Collectors.toMap(AdminWebsit::getName, Function.identity()));

        Map<String, User> userMap = userList.stream()
                    .collect(Collectors.toMap(User::getMobile, Function.identity(), (k1, k2) -> k2));

        Map<String, User> existUserMap = userList.stream()
                    .collect(Collectors.toMap(User::getUserId, Function.identity()));

        Map<String, WebsitGoodsCategory> categoryMap = categoryList.stream()
                .collect(Collectors.toMap(WebsitGoodsCategory::getCategoryId, Function.identity()));

        List<Object> objects = ExcelUtils.importExcel(file);
        List<ImportMaterialSalesBean> beanList = new ArrayList<>();

        final List<Storage> storageList = storageService.lambdaQuery()
                .eq(Storage::getCompanyWechatId, companyWechatId)
                .eq(Storage::getStatus, true)
                .like(Storage::getType, "辅材")
                .list();

        Map<String, Storage> storageMap = storageList.stream()
                .collect(Collectors.toMap(v -> v.getWebsitId() + v.getStorageName(), Function.identity()));

        Map<String, Storage> storageIdMap = storageList.stream()
                .collect(Collectors.toMap(Storage::getStorageId, Function.identity()));

        final Map<String, Storage> defaultStorageMap = storageList.stream()
                .filter(Storage::getIsDefault)
                .collect(Collectors.toMap(Storage::getWebsitId, Function.identity()));


        for (int i = 0; i < objects.size(); i++) {
            List<Object> row = (List<Object>) objects.get(i);
            if (row.size() < 6) {
                row.add("");
            }

            if (row.size() < 7) {
                row.add("");
                row.add("");
            }

            if (Objects.isNull(row.get(0))) {
                throw new RemoteServiceException("第" + (i+1) + "行, 网点名称不能为空");
            }
            if (Objects.isNull(row.get(1))) {
                throw new RemoteServiceException("第" + (i+1) + "行, 师傅联系电话不能为空");
            }
            if (Objects.isNull(row.get(2))) {
                throw new RemoteServiceException("第" + (i+1) + "行, 辅材名称不能为空");
            }
            if (Objects.isNull(row.get(3))) {
                throw new RemoteServiceException("第" + (i+1) + "行, 数量不能为空");
            }
            if (Objects.isNull(row.get(4))) {
                throw new RemoteServiceException("第" + (i+1) + "行, 销售价格不能为空");
            }
//            if (Objects.isNull(row.get(5))) {
//                throw new RemoteServiceException("第" + (i+1) + "行, 销售时间不能为空");
//            }

            String websitStr = (String) row.get(0);
            String mobileStr = (String) row.get(1);
            String goodsNameStr = (String) row.get(2);
            String qtyStr = (String) row.get(3);
            String salesPriceStr = (String) row.get(4);
            String customerStr = (String) row.get(5);
            String storageStr = (String) row.get(6);

            if (!websitMap.containsKey(websitStr)) {
                throw new RemoteServiceException("第" + (i+1) + "行, 网点名称不存在");
            }
            if (!userMap.containsKey(mobileStr)) {
//                throw new RemoteServiceException("第" + (i+1) + "行, 师傅联系电话不存在");
                if (StringUtils.isBlank(mobileStr)) {
                    throw new RemoteServiceException("第" + (i+1) + "行, 手机号不能为空");
                }
                if (StringUtils.isBlank(customerStr)) {
                    throw new RemoteServiceException("第" + (i+1) + "行, 客户名称不能为空");
                }
                if (!userMap.containsKey(customerStr + mobileStr)) {
                    User user = new User();
                    user.setUserId(customerStr + mobileStr)
                            .setNickName(customerStr)
                            .setMobile(mobileStr);
                    userMap.put(customerStr + mobileStr, user);
                }
            }
            if (!goodsMap.containsKey(goodsNameStr)) {
                throw new RemoteServiceException("第" + (i+1) + "行, 辅材名称不存在");
            }
            BigDecimal qty;
            try {
                qty = new BigDecimal(qtyStr);
                if (qty.compareTo(BigDecimal.ZERO) <= 0) {
                    throw new RemoteServiceException("第" + (i+1) + "行, 请输入有效数量");
                }
            } catch (Exception e) {
                throw new RemoteServiceException("第" + (i+1) + "行, 数量转换异常");
            }
            BigDecimal salesPrice;
            try {
                salesPrice = new BigDecimal(salesPriceStr);
                if (qty.compareTo(BigDecimal.ZERO) < 0) {
                    throw new RemoteServiceException("第" + (i+1) + "行, 请输入有效销售价格");
                }
            } catch (Exception e) {
                throw new RemoteServiceException("第" + (i+1) + "行, 销售价格转换异常");
            }

            ImportMaterialSalesBean bean = new ImportMaterialSalesBean();

            bean.setIndex(i+1);
            bean.setAdminWebsit(websitMap.get(websitStr));
            bean.setUser(userMap.containsKey(mobileStr) ? userMap.get(mobileStr) : userMap.get(customerStr + mobileStr));
            bean.setGoods(goodsMap.get(goodsNameStr));
            bean.setQty(qty);
            bean.setPrice(salesPrice);

            if (StringUtils.isNotBlank(storageStr) && storageMap.containsKey(bean.getAdminWebsit().getWebsitId() + storageStr)) {
                bean.setStorageId(storageMap.get(bean.getAdminWebsit().getWebsitId() + storageStr).getStorageId());
            }

            beanList.add(bean);
        }

        if (CollectionUtil.isNotEmpty(beanList)) {
            List<WebsitSales> salesList = new ArrayList<>();
            List<WebsitSalesItem> salesItemList = new ArrayList<>();
            DateTime curDate = DateUtil.date();
            // 先按网点、师傅、仓库分组
            Map<String, List<ImportMaterialSalesBean>> groupWebsitWorkerMap = beanList.stream()
                    .collect(Collectors.groupingBy(v -> v.getAdminWebsit().getWebsitId() + v.getUser().getUserId() + v.getStorageId()));

            for (Map.Entry<String, List<ImportMaterialSalesBean>> entry : groupWebsitWorkerMap.entrySet()) {
                List<WebsitSalesBean> salesBeanList = new ArrayList<>();
                List<WebsitSalesItemBean> salesItemBeanList = new ArrayList<>();
                List<WebsitSalesItemBean> salesItemBeanAfterList = new ArrayList<>();

                ImportMaterialSalesBean importMaterialSalesBean = entry.getValue().get(0);

                boolean isUser = existUserMap.containsKey(importMaterialSalesBean.getUser().getUserId());

                WebsitSalesBean salesBean = new WebsitSalesBean();
                salesBean.setReason(batchId);
                salesBean.setCompanyWechatId(companyWechatId);
                salesBean.setCompanyWechatName(companyName);
                salesBean.setWebsitId(importMaterialSalesBean.getAdminWebsit().getWebsitId());
                salesBean.setWebsitName(importMaterialSalesBean.getAdminWebsit().getName());
                salesBean.setGoodsType(WebsitGoodsTypeEnum.M.getKey());
                salesBean.setBuyPeople(isUser ? BuyPeopleEnum.WORKER.getKey() : BuyPeopleEnum.CUSTOMER.getKey());
                salesBean.setWorkerId(isUser ? importMaterialSalesBean.getUser().getWorkerNumber() : null);
                salesBean.setWorkerName(importMaterialSalesBean.getUser().getNickName());
                salesBean.setWorkerMobile(importMaterialSalesBean.getUser().getMobile());
                salesBean.setSalesType(WebsitSalesTypeEnum.RETAIL.getName());
                salesBean.setIdentity(importMaterialSalesBean.getUser().getIdCard());
                salesBean.setSalesTime(curDate);
                salesBean.setPayType(PayTypeEnum.CASH.getKey());
                salesBean.setPayFlag(IsYesNoEnum.YES.getKey());
                salesBean.setOrderSource(SourceSalesEnum.SELF.getKey());
                salesBean.setFlag(MaterialSalesFlagEnum.IMPORT_WAIT.getKey());
                salesBean.setRemark("导入单据");
                salesBean.setSubmitBy(adminUser.getNickName());
                salesBean.setSubmitTime(curDate);
                salesBean.setConfirmBy(adminUser.getNickName());
                salesBean.setConfirmTime(curDate);

                if (StringUtils.isNotBlank(importMaterialSalesBean.getStorageId())) {
                    // 有仓库id
                    salesBean.setStorageId(storageIdMap.get(importMaterialSalesBean.getStorageId()).getStorageId())
                            .setStorageName(storageIdMap.get(importMaterialSalesBean.getStorageId()).getStorageName());
                } else {
                    // 没有仓库id找默认仓库填充
                    salesBean.setStorageId(defaultStorageMap.get(salesBean.getWebsitId()).getStorageId())
                            .setStorageName(defaultStorageMap.get(salesBean.getWebsitId()).getStorageName());
                }

                for (ImportMaterialSalesBean bean : entry.getValue()) {
                    Map<String, WebsitSalesItemBean> itemBeanMap = salesItemBeanList.stream()
                            .collect(Collectors.toMap(v -> v.getGoodsId() + v.getPrice(), Function.identity()));

                    WebsitSalesItemBean itemBean = itemBeanMap.get(bean.getGoods().getGoodsId() + bean.getPrice());

                    if (Objects.isNull(itemBean)) {
                        WebsitGoodsCategory parentCategory = categoryMap.get(bean.getGoods().getParentCategoryId());
                        WebsitGoodsCategory category = categoryMap.get(bean.getGoods().getGoodsCategoryId());
                        WebsitSalesItemBean salesItemBean = new WebsitSalesItemBean();
                        salesItemBean.setId(IdWorker.getIdStr());
                        salesItemBean.setGoodsType(salesBean.getGoodsType());
                        salesItemBean.setWebsitId(salesBean.getWebsitId());
                        salesItemBean.setWebsitName(salesBean.getWebsitName());
                        salesItemBean.setGoodsId(bean.getGoods().getGoodsId());
                        salesItemBean.setGoodsName(bean.getGoods().getGoodsName());
                        salesItemBean.setSalesQty(bean.getQty());
                        salesItemBean.setPrice(bean.getPrice());
                        salesItemBean.setSaleAmount(bean.getQty().multiply(bean.getPrice()));
                        salesItemBean.setNormPrice(bean.getGoods().getNormAmount());
                        salesItemBean.setGoodsStockUnit(bean.getGoods().getGoodsStockUnit());
                        salesItemBean.setGoodsSalesUnit(bean.getGoods().getGoodsSalesUnit());
                        salesItemBean.setGoodsSpecification(bean.getGoods().getGoodsSpecification());
                        salesItemBean.setGoodsSalesConvertQty(bean.getGoods().getGoodsSalesConvertQty());
                        salesItemBean.setConvertBitScale(bean.getGoods().getConvertBitScale());
                        salesItemBean.setParentCategoryId(bean.getGoods().getParentCategoryId());
                        salesItemBean.setParentCategoryName(Objects.nonNull(parentCategory) ? parentCategory.getCategoryName() : null);
                        salesItemBean.setGoodsCategoryId(bean.getGoods().getGoodsCategoryId());
                        salesItemBean.setGoodsCategoryName(Objects.nonNull(category) ? category.getCategoryName() : null);
                        salesItemBean.setPayType(salesBean.getPayType());
                        salesItemBean.setManageWorkerStock(bean.getGoods().getManageWorkerStock());

                        if (StrUtil.equals(salesItemBean.getGoodsStockUnit(), salesItemBean.getGoodsSalesUnit())) {
                            bean.getGoods().setGoodsSalesConvertQty(BigDecimal.ONE);
                        }

                        BigDecimal convertQty = salesItemBean.getSalesQty().divide(bean.getGoods().getGoodsSalesConvertQty(), 1, BigDecimal.ROUND_UP);
                        BigDecimal totalSaleValue = salesItemBean.getSalesQty().multiply(salesItemBean.getPrice());
                        BigDecimal convertPrice = totalSaleValue.divide(convertQty, 2, BigDecimal.ROUND_DOWN);

                        if (StringUtils.isBlank(salesItemBean.getManageWorkerStock())
                                || salesItemBean.getManageWorkerStock().equals(IsYesNoEnum.YES.getKey())) {
                            final WorkerGoodsRela goodsRela = workerGoodsRelaService.lambdaQuery()
                                    .eq(WorkerGoodsRela::getCompanyWechatId, bean.getGoods().getCompanyWechatId())
                                    .eq(WorkerGoodsRela::getWebsitGoodsId, bean.getGoods().getGoodsId())
                                    .one();
                            if (Objects.nonNull(goodsRela)) {
                                final WorkerGoods workerGoods = workerGoodsService.getById(goodsRela.getWorkerGoodsId());
                                if (workerGoods.getStatus().equals(StateEnum.ON.getKey())) {
                                    salesItemBean.setWorkerGoodsId(goodsRela.getWorkerGoodsId());
                                    salesItemBean.setWorkerGoodsName(goodsRela.getWorkerGoodsName());
                                }
                            }
                        }

                        salesItemBean.setConvertQty(convertQty);
                        salesItemBean.setConvertPrice(convertPrice);
                        salesItemBean.setItemSourceType(ItemSourceTypeEnum.BASE.getKey());
                        salesItemBean.setItemSourceId(bean.getGoods().getGoodsId());
                        salesItemBean.setNormType(bean.getGoods().getNormType());

                        salesItemBeanList.add(salesItemBean);
                    } else {
                        itemBean.setSalesQty(itemBean.getSalesQty().add(bean.getQty()));
                        itemBean.setSaleAmount(itemBean.getSalesQty().multiply(bean.getPrice()));
                    }
                }

                // 递归检查销售明细是否还有需要产生新销售单的明细
                this.checkIsWaitSalesSheet(salesBeanList, salesBean, salesItemBeanList, salesItemBeanAfterList);

                // 按销售单号分组
                Map<String, List<WebsitSalesItemBean>> itemMap = salesItemBeanList.stream()
                        .collect(Collectors.groupingBy(WebsitSalesItemBean::getSalesId));

                // 注入销售单和明细
                for (WebsitSalesBean websitSalesBean : salesBeanList) {
                    WebsitSales sales = new WebsitSales();
                    BeanUtils.copyProperties(websitSalesBean, sales);

                    BigDecimal totalAmount = BigDecimal.ZERO;

                    List<WebsitSalesItemBean> itemBeans = itemMap.get(sales.getSalesId());


                    for (WebsitSalesItemBean itemBean : itemBeans) {
                        WebsitSalesItem item = new WebsitSalesItem();
                        BeanUtils.copyProperties(itemBean, item);

                        totalAmount = totalAmount.add(item.getSaleAmount());
                        item.setCompanyWechatId(sales.getCompanyWechatId());

                        salesItemList.add(item);
                    }

                    sales.setTotalAmount(totalAmount)
                            .setIsImport(true);

                    salesList.add(sales);
                }
            }

            websitSalesService.saveBatch(salesList);
            websitSalesItemService.saveBatch(salesItemList);
        }

        return batchId;
    }

    public String importPartsData(MultipartFile file) throws Exception {
        String batchId = StrUtil.uuid();
        AdminUserCom adminUser = commonLogic.getAdminUser();

        if (adminUser.getType() == 2) {
            throw new RemoteServiceException("平台账号禁止操作");
        }

        String companyWechatId = Objects.nonNull(adminUser.getAdminCompanyWechat()) ? adminUser.getAdminCompanyWechat().getCompanyWechatId() : null;
        String companyName = Objects.nonNull(adminUser.getAdminCompanyWechat()) ? adminUser.getAdminCompanyWechat().getCompanyName() : null;

        List<WebsitGoods> websitGoods = websitGoodsService.lambdaQuery()
                .eq(WebsitGoods::getCompanyWechatId, companyWechatId)
                .eq(WebsitGoods::getGoodsType, WebsitGoodsTypeEnum.P.getKey())
//                .eq(WebsitGoods::getStatus, StateEnum.ON.getKey())
                .eq(WebsitGoods::getNormType, NormTypeEnum.M.getKey())
                .isNotNull(WebsitGoods::getGoodsCode)
                .list();

        List<AdminWebsit> websitList = adminWebsitService.lambdaQuery()
                .eq(AdminWebsit::getCompanyWechatId, companyWechatId)
                .eq(AdminWebsit::getType, AdminWebsitTypeEnum.C.getKey())
//                .eq(AdminWebsit::getStatus, true)
                .list();

        List<User> userList = userService.lambdaQuery()
                .eq(User::getCompanyWechatId, companyWechatId)
                .eq(User::getApplyType, UserTypeEnum.WORKER.getKey())
//                .eq(User::getStatus, true)
                .list();

        Map<String, WebsitGoods> goodsMap;

        try {
            goodsMap = websitGoods.stream()
                    .collect(Collectors.toMap(WebsitGoods::getGoodsCode, Function.identity()));;
        } catch (Exception e) {
            throw new RemoteServiceException("系统里的配件编码信息有重复");
        }

        Map<String, AdminWebsit> websitMap = websitList.stream()
                .collect(Collectors.toMap(AdminWebsit::getName, Function.identity()));

        Map<String, User> userMap = userList.stream()
                .collect(Collectors.toMap(User::getMobile, Function.identity(), (k1, k2) -> k2));

        Map<String, User> existUserMap = userList.stream()
                .collect(Collectors.toMap(User::getUserId, Function.identity()));

        final List<Storage> storageList = storageService.lambdaQuery()
                .eq(Storage::getCompanyWechatId, companyWechatId)
                .eq(Storage::getStatus, true)
                .like(Storage::getType, "配件")
                .list();

        Map<String, Storage> storageMap = storageList.stream()
                .collect(Collectors.toMap(v -> v.getWebsitId() + v.getStorageName(), Function.identity()));

        Map<String, Storage> storageIdMap = storageList.stream()
                .collect(Collectors.toMap(Storage::getStorageId, Function.identity()));

        final Map<String, Storage> defaultStorageMap = storageList.stream()
                .filter(Storage::getIsDefault)
                .collect(Collectors.toMap(Storage::getWebsitId, Function.identity()));

        final MaterialConfig config = materialConfigService.lambdaQuery()
                .eq(MaterialConfig::getCompanyWechatId, companyWechatId)
                .one();

        List<Object> objects = ExcelUtils.importExcel(file);
        List<ImportMaterialSalesBean> beanList = new ArrayList<>();

        for (int i = 0; i < objects.size(); i++) {
            List<Object> row = (List<Object>) objects.get(i);
            CommonUtils.initList2(row, 10);
            if (row.size() < 6) {
                row.add("");
            }
            if (row.size() < 7) {
                row.add("");
                row.add("");
            }
            if (Objects.isNull(row.get(0))) {
                throw new RemoteServiceException("第" + (i+1) + "行, 网点名称不能为空");
            }
            if (Objects.isNull(row.get(1))) {
                throw new RemoteServiceException("第" + (i+1) + "行, 师傅联系电话不能为空");
            }
            if (Objects.isNull(row.get(2))) {
                throw new RemoteServiceException("第" + (i+1) + "行, 配件编码不能为空");
            }
            if (Objects.isNull(row.get(3))) {
                throw new RemoteServiceException("第" + (i+1) + "行, 数量不能为空");
            }
//            if (Objects.isNull(row.get(4))) {
//                throw new RemoteServiceException("第" + (i+1) + "行, 销售价格不能为空");
//            }
//            if (Objects.isNull(row.get(5))) {
//                throw new RemoteServiceException("第" + (i+1) + "行, 销售时间不能为空");
//            }

            String websitStr = (String) row.get(0);
            String mobileStr = (String) row.get(1);
            String goodsNameStr = (String) row.get(2);
            String qtyStr = (String) row.get(3);
//            String salesPriceStr = (String) row.get(4);
            String customerStr = (String) row.get(4);
            String storageStr = (String) row.get(5);

            if (!websitMap.containsKey(websitStr)) {
                throw new RemoteServiceException("第" + (i+1) + "行, 网点名称不存在");
            }
            if (!userMap.containsKey(mobileStr)) {
//                throw new RemoteServiceException("第" + (i+1) + "行, 师傅联系电话不存在");
                if (StringUtils.isBlank(mobileStr)) {
                    throw new RemoteServiceException("第" + (i+1) + "行, 手机号不能为空");
                }
                if (StringUtils.isBlank(customerStr)) {
                    throw new RemoteServiceException("第" + (i+1) + "行, 客户名称不能为空");
                }
                if (!userMap.containsKey(customerStr + mobileStr)) {
                    User user = new User();
                    user.setUserId(customerStr + mobileStr)
                            .setNickName(customerStr)
                            .setMobile(mobileStr);
                    userMap.put(customerStr + mobileStr, user);
                }
            }
            if (!goodsMap.containsKey(goodsNameStr)) {
                throw new RemoteServiceException("第" + (i+1) + "行, 配件编码不存在");
            }
            BigDecimal qty;
            try {
                qty = new BigDecimal(qtyStr);
                if (qty.compareTo(BigDecimal.ZERO) <= 0) {
                    throw new RemoteServiceException("第" + (i+1) + "行, 请输入有效数量");
                }
            } catch (Exception e) {
                throw new RemoteServiceException("第" + (i+1) + "行, 数量转换异常");
            }
            BigDecimal salesPrice;
//            try {
//                salesPrice = new BigDecimal(salesPriceStr);
//                if (qty.compareTo(BigDecimal.ZERO) < 0) {
//                    throw new RemoteServiceException("第" + (i+1) + "行, 请输入有效销售价格");
//                }
//            } catch (Exception e) {
//                throw new RemoteServiceException("第" + (i+1) + "行, 销售价格转换异常");
//            }

            final WebsitGoods goods = goodsMap.get(goodsNameStr);
            switch (goods.getPartType()) {
                case "空调":
                    salesPrice = goods.getMarketPrice().multiply(config.getPriceRate1());
                    break;
                case "冰箱":
                    salesPrice = goods.getMarketPrice().multiply(config.getPriceRate2());
                    break;
                case "生活电器":
                    salesPrice = goods.getMarketPrice().multiply(config.getPriceRate3());
                    break;
                default:
                    throw new RemoteServiceException("未找到对应配件类型倍率");
            }
            BigDecimal origPrice = goods.getMarketPrice();

            ImportMaterialSalesBean bean = new ImportMaterialSalesBean();

            bean.setIndex(i+1);
            bean.setAdminWebsit(websitMap.get(websitStr));
            bean.setUser(userMap.containsKey(mobileStr) ? userMap.get(mobileStr) : userMap.get(customerStr + mobileStr));
            bean.setGoods(goods);
            bean.setQty(qty);
            bean.setPrice(salesPrice);
            bean.setOrigPrice(origPrice);

            if (StringUtils.isNotBlank(storageStr) && storageMap.containsKey(bean.getAdminWebsit().getWebsitId() + storageStr)) {
                bean.setStorageId(storageMap.get(bean.getAdminWebsit().getWebsitId() + storageStr).getStorageId());
            }

            beanList.add(bean);
        }

        if (CollectionUtil.isNotEmpty(beanList)) {
            List<WebsitSales> salesList = new ArrayList<>();
            List<WebsitSalesItem> salesItemList = new ArrayList<>();
            DateTime curDate = DateUtil.date();
            // 先按网点师傅分组
            Map<String, List<ImportMaterialSalesBean>> groupWebsitWorkerMap = beanList.stream()
                    .collect(Collectors.groupingBy(v -> v.getAdminWebsit().getWebsitId() + v.getUser().getUserId() + v.getStorageId()));

            for (Map.Entry<String, List<ImportMaterialSalesBean>> entry : groupWebsitWorkerMap.entrySet()) {
                List<WebsitSalesBean> salesBeanList = new ArrayList<>();
                List<WebsitSalesItemBean> salesItemBeanList = new ArrayList<>();
                List<WebsitSalesItemBean> salesItemBeanAfterList = new ArrayList<>();

                ImportMaterialSalesBean importMaterialSalesBean = entry.getValue().get(0);

                boolean isUser = existUserMap.containsKey(importMaterialSalesBean.getUser().getUserId());

                WebsitSalesBean salesBean = new WebsitSalesBean();
                salesBean.setReason(batchId);
                salesBean.setCompanyWechatId(companyWechatId);
                salesBean.setCompanyWechatName(companyName);
                salesBean.setWebsitId(importMaterialSalesBean.getAdminWebsit().getWebsitId());
                salesBean.setWebsitName(importMaterialSalesBean.getAdminWebsit().getName());
                salesBean.setGoodsType(WebsitGoodsTypeEnum.P.getKey());
                salesBean.setBuyPeople(isUser ? BuyPeopleEnum.WORKER.getKey() : BuyPeopleEnum.CUSTOMER.getKey());
                salesBean.setWorkerId(isUser ? importMaterialSalesBean.getUser().getWorkerNumber() : null);
                salesBean.setWorkerName(importMaterialSalesBean.getUser().getNickName());
                salesBean.setWorkerMobile(importMaterialSalesBean.getUser().getMobile());
                salesBean.setSalesType(WebsitSalesTypeEnum.RETAIL.getName());
                salesBean.setIdentity(importMaterialSalesBean.getUser().getIdCard());
                salesBean.setSalesTime(curDate);
                salesBean.setPayType(PayTypeEnum.CASH.getKey());
                salesBean.setPayFlag(IsYesNoEnum.YES.getKey());
                salesBean.setOrderSource(SourceSalesEnum.SELF.getKey());
                salesBean.setFlag(MaterialSalesFlagEnum.IMPORT_WAIT.getKey());
                salesBean.setRemark("导入单据");
                salesBean.setSubmitBy(adminUser.getNickName());
                salesBean.setSubmitTime(curDate);
                salesBean.setConfirmBy(adminUser.getNickName());
                salesBean.setConfirmTime(curDate);

                if (StringUtils.isNotBlank(importMaterialSalesBean.getStorageId())) {
                    // 有仓库id
                    salesBean.setStorageId(storageIdMap.get(importMaterialSalesBean.getStorageId()).getStorageId())
                            .setStorageName(storageIdMap.get(importMaterialSalesBean.getStorageId()).getStorageName());
                } else {
                    // 没有仓库id找默认仓库填充
                    salesBean.setStorageId(defaultStorageMap.get(salesBean.getWebsitId()).getStorageId())
                            .setStorageName(defaultStorageMap.get(salesBean.getWebsitId()).getStorageName());
                }

                for (ImportMaterialSalesBean bean : entry.getValue()) {
                    Map<String, WebsitSalesItemBean> itemBeanMap = salesItemBeanList.stream()
                            .collect(Collectors.toMap(v -> v.getGoodsId() + v.getPrice(), Function.identity()));

                    WebsitSalesItemBean itemBean = itemBeanMap.get(bean.getGoods().getGoodsId() + bean.getPrice());

                    if (Objects.isNull(itemBean)) {
                        WebsitSalesItemBean salesItemBean = new WebsitSalesItemBean();
                        salesItemBean.setId(IdWorker.getIdStr());
                        salesItemBean.setGoodsType(salesBean.getGoodsType());
                        salesItemBean.setWebsitId(salesBean.getWebsitId());
                        salesItemBean.setWebsitName(salesBean.getWebsitName());
                        salesItemBean.setGoodsId(bean.getGoods().getGoodsId());
                        salesItemBean.setGoodsName(bean.getGoods().getGoodsName());
                        salesItemBean.setSalesQty(bean.getQty());
                        salesItemBean.setPrice(bean.getPrice());
                        salesItemBean.setSaleAmount(bean.getQty().multiply(bean.getPrice()));
                        salesItemBean.setNormPrice(bean.getGoods().getNormAmount());
                        salesItemBean.setGoodsStockUnit(bean.getGoods().getGoodsStockUnit());
                        salesItemBean.setGoodsSalesUnit(bean.getGoods().getGoodsSalesUnit());
                        salesItemBean.setGoodsSpecification(bean.getGoods().getGoodsSpecification());
                        salesItemBean.setGoodsSalesConvertQty(bean.getGoods().getGoodsSalesConvertQty());
                        salesItemBean.setConvertBitScale(bean.getGoods().getConvertBitScale());
                        salesItemBean.setBrand(bean.getGoods().getBrandRelaName());
                        salesItemBean.setProductCategory(bean.getGoods().getProductRelaName());
                        salesItemBean.setPayType(salesBean.getPayType());
                        salesItemBean.setManageWorkerStock(bean.getGoods().getManageWorkerStock());
                        salesItemBean.setConvertPrice(bean.getPrice());
                        salesItemBean.setConvertQty(bean.getQty());
                        salesItemBean.setItemSourceType(ItemSourceTypeEnum.BASE.getKey());
                        salesItemBean.setItemSourceId(bean.getGoods().getGoodsId());
                        salesItemBean.setNormType(bean.getGoods().getNormType());
                        salesItemBean.setOrigPartsPrice(bean.getOrigPrice());

                        salesItemBeanList.add(salesItemBean);
                    } else {
                        itemBean.setSalesQty(itemBean.getSalesQty().add(bean.getQty()));
                        itemBean.setConvertQty(itemBean.getConvertQty().add(bean.getQty()));
                        itemBean.setSaleAmount(itemBean.getSalesQty().multiply(bean.getPrice()));
                    }
                }

                // 递归检查销售明细是否还有需要产生新销售单的明细
                this.checkIsWaitSalesSheet(salesBeanList, salesBean, salesItemBeanList, salesItemBeanAfterList);

                // 按销售单号分组
                Map<String, List<WebsitSalesItemBean>> itemMap = salesItemBeanList.stream()
                        .collect(Collectors.groupingBy(WebsitSalesItemBean::getSalesId));

                // 注入销售单和明细
                for (WebsitSalesBean websitSalesBean : salesBeanList) {
                    WebsitSales sales = new WebsitSales();
                    BeanUtils.copyProperties(websitSalesBean, sales);

                    BigDecimal totalAmount = BigDecimal.ZERO;

                    List<WebsitSalesItemBean> itemBeans = itemMap.get(sales.getSalesId());


                    for (WebsitSalesItemBean itemBean : itemBeans) {
                        WebsitSalesItem item = new WebsitSalesItem();
                        BeanUtils.copyProperties(itemBean, item);

                        totalAmount = totalAmount.add(item.getSaleAmount());

                        item.setCompanyWechatId(sales.getCompanyWechatId());

                        salesItemList.add(item);
                    }

                    sales.setIsImport(true)
                            .setTotalAmount(totalAmount);

                    salesList.add(sales);
                }
            }

            websitSalesService.saveBatch(salesList);
            websitSalesItemService.saveBatch(salesItemList);
        }

        return batchId;
    }

    private void checkIsWaitSalesSheet(List<WebsitSalesBean> salesBeanList, WebsitSalesBean salesBean, List<WebsitSalesItemBean> salesItemBeanList, List<WebsitSalesItemBean> salesItemBeanAfterList) {
        long count = salesItemBeanList.stream().filter(v -> StringUtils.isBlank(v.getSalesId())).count();
        if (count > 0) {
            // 发现saleId为空的明细先产生新的sales单据
            WebsitSalesBean newSalesBean = new WebsitSalesBean();
            BeanUtils.copyProperties(salesBean, newSalesBean);
            String salesId = commonLogic.generateNo("X" + salesBean.getGoodsType(), "SalesOrder" + salesBean.getGoodsType(), 15);
            newSalesBean.setSalesId(salesId);

            salesBeanList.add(newSalesBean);

            // 过滤销售明细saleId为空的对象, 按商品、单价分组，组的第一个对象设置saleId
            Map<String, List<WebsitSalesItemBean>> goodsPriceMap = salesItemBeanList.stream()
                    .filter(v -> StringUtils.isBlank(v.getSalesId()))
                    .collect(Collectors.groupingBy(WebsitSalesItemBean::getGoodsId));

//            salesItemBeanList.clear();

            for (Map.Entry<String, List<WebsitSalesItemBean>> priceEntry : goodsPriceMap.entrySet()) {
                priceEntry.getValue().get(0).setSalesId(newSalesBean.getSalesId());
//                salesItemBeanList.addAll(priceEntry.getValue());
            }

        } else {
            return;
        }
        checkIsWaitSalesSheet(salesBeanList, salesBean, salesItemBeanList, salesItemBeanAfterList);
    }

    public ImportResultBean queryImportResult(String importBatchId) {
        Integer count = websitSalesService.lambdaQuery()
                .eq(WebsitSales::getFlag, MaterialSalesFlagEnum.IMPORT_WAIT.getKey())
                .like(WebsitSales::getReason, importBatchId)
                .count();

        ImportResultBean bean = new ImportResultBean();
        bean.setWaitCount(count);
        bean.setErrList(new ArrayList<>());

        if (count == 0) {
            List<WebsitSales> salesList = websitSalesService.lambdaQuery()
                    .eq(WebsitSales::getFlag, MaterialSalesFlagEnum.IMPORT_ERR.getKey())
                    .like(WebsitSales::getReason, importBatchId)
                    .list();
            if (CollectionUtil.isNotEmpty(salesList)) {
                for (WebsitSales sales : salesList) {
                    bean.getErrList().add(sales.getReason());
                }
            }
        }

        return bean;
    }

    public void testRefund(String salesId, HttpServletRequest request) {
        final WebsitSalesPayOrder payOrder = websitSalesPayOrderService.lambdaQuery()
                .eq(WebsitSalesPayOrder::getPayFlag, IsYesNoEnum.YES.getKey())
                .eq(WebsitSalesPayOrder::getOrderId, salesId)
                .one();
        allInPayLogic.serviceRefundOrder(payOrder, null, payOrder.getPayValue());
    }
}
