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

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zfire.mall.manager.bean.ExcelData;
import com.zfire.mall.manager.bean.admin.AdminUserCom;
import com.zfire.mall.manager.bean.invoice.StockStatusBean;
import com.zfire.mall.manager.bean.k3.RequestApiBean;
import com.zfire.mall.manager.bean.k3.StockPositionStock;
import com.zfire.mall.manager.bean.sale.SaleOrderBean;
import com.zfire.mall.manager.bean.stock.*;
import com.zfire.mall.manager.commonmapper.stock.StockCommonMapper;
import com.zfire.mall.manager.constant.Constant;
import com.zfire.mall.manager.constant.KingDeeCons;
import com.zfire.mall.manager.enums.ExamineStatusEnum;
import com.zfire.mall.manager.exception.RemoteServiceException;
import com.zfire.mall.manager.logic.common.CommonLogic;
import com.zfire.mall.manager.logic.k3.K3Logic;
import com.zfire.mall.manager.logic.k3.K3OrgLogic;
import com.zfire.mall.manager.logic.k3.K3TransferLogic;
import com.zfire.mall.manager.plus.entity.*;
import com.zfire.mall.manager.plus.service.*;
import com.zfire.mall.manager.zfire.bean.ZfireParamBean;
import com.zfire.mall.manager.zfire.util.FieldUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.beans.Transient;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author Administrator
 */
@Slf4j
@Service
public class StockCommonLogic {

    @Autowired
    StockCommonMapper stockCommonMapper;

    @Autowired
    StockCustomerService stockCustomerService;

    @Autowired
    StockService stockService;

    @Autowired
    K3Logic k3Logic;

    @Autowired
    InvoiceApplicationOrderService invoiceApplicationOrderService;

    @Autowired
    InvoiceApplicationService invoiceApplicationService;


    @Autowired
    StockCorrespondPositionService stockCorrespondPositionService;

    @Autowired
    StockCorrespondService stockCorrespondService;

    @Autowired
    ReservedOrderItemService reservedOrderItemService;

    @Autowired
    KingDeeMaterialService kingDeeMaterialService;

    @Autowired
    ProductCategoryRelaService productCategoryRelaService;

    @Autowired
    ProductCategoryService productCategoryService;

    @Autowired
    KingDeeCustomerService kingDeeCustomerService;

    @Autowired
    KingDeeStockService kingDeeStockService;

    @Autowired
    CommonLogic commonLogic;

    @Autowired
    StockReserveService stockReserveService;

    @Autowired
    ReceiptInvoiceAddedService receiptInvoiceAddedService;

    @Autowired
    ReceiptInvoiceOrdinaryService receiptInvoiceOrdinaryService;

    @Autowired
    SalesOrderService salesOrderService;


    @Autowired
    K3TransferLogic k3TransferLogic;

    @Autowired
    KingDeeTransferService kingDeeTransferService;

    @Autowired
    KingDeeTransferItemService kingDeeTransferItemService;

    @Autowired
    StockCommonLogic stockCommonLogic;

    @Autowired
    AdminUserCategoryRelaService adminUserCategoryRelaService;


    @Autowired
    StockCorrespondCategoryService stockCorrespondCategoryService;

    @Autowired
    AdminUserStockService adminUserStockService;

    @Autowired
    StockForceCategoryService stockForceCategoryService;

    @Autowired
    StockForceService stockForceService;

    @Autowired
    AdminUserForceStockService adminUserForceStockService;

    @Autowired
    KingDeeCategoryService kingDeeCategoryService;

    @Autowired
    MaterialReferPriceService materialReferPriceService;

    final static String orgId = "1";
    final static String orgNum = "100";


    public IPage<StockBean> list(List<String> correspondId, String stockId, List<String> categoryId, String materialOldNumber, String materialName, String materialNumber, String specification, String mainNumber, Integer pageNum, Integer pageSize) {
        IPage<StockBean> list = stockCommonMapper.list(new Page<>(pageNum, pageSize), correspondId, stockId, categoryId, materialOldNumber, materialName, materialNumber, specification, mainNumber);
        List<StockBean> records = list.getRecords();
        List<StockBean> integer = stockCommonMapper.sumKingDeeNumberList(correspondId);
        List<StockBean> adequate = stockCommonMapper.sumKingDeeNumberAdequateList(correspondId);
        List<StockBean> temporay = stockCommonMapper.selectInvoiceCountList(correspondId);
        List<StockBean> num = stockCommonMapper.countAllList(correspondId);
        List<StockBean> reservedNum = stockCommonMapper.countReservedList(correspondId);
        for (StockBean record : records) {
            //可用数量
            List<StockBean> collectAdequate = adequate.stream()
                    .filter(item -> (item.getMaterialId().equals(record.getMaterialId()) && CollectionUtils.isEmpty(correspondId)) ||
                            (item.getMaterialId().equals(record.getMaterialId()) && CollectionUtils.isNotEmpty(correspondId) &&  correspondId.contains(item.getCorrespondId())) )
                    .collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(collectAdequate))
                record.setStockAdequate(collectAdequate.stream().mapToInt(StockBean::getStockAdequate).sum());
            else
                record.setStockAdequate(0);
            //总库存数量
            List<StockBean> collect = integer.stream()
                    .filter(item -> (item.getMaterialId().equals(record.getMaterialId()) && CollectionUtils.isEmpty(correspondId)) ||
                            (item.getMaterialId().equals(record.getMaterialId()) && CollectionUtils.isNotEmpty(correspondId) &&  correspondId.contains(item.getCorrespondId())) )
                    .collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(collect))
                record.setStockQty(collect.stream().mapToInt(StockBean::getStockQty).sum());
            else
                record.setStockQty(0);

            //经销商暂扣库存
            List<StockBean> collectTemporay = temporay.stream()
                    .filter(item -> (item.getMaterialId().equals(record.getMaterialId()) && CollectionUtils.isEmpty(correspondId)) ||
                            (item.getMaterialId().equals(record.getMaterialId()) && CollectionUtils.isNotEmpty(correspondId) &&  correspondId.contains(item.getCorrespondId())))
                    .collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(collectTemporay))
                record.setTemporaryNum(collectTemporay.stream().mapToInt(StockBean::getTemporaryNum).sum());
            else
                record.setTemporaryNum(0);
            //开单未提数量
            List<StockBean> collectNum = num.stream()
                    .filter(item -> (item.getMaterialId().equals(record.getMaterialId()) && CollectionUtils.isEmpty(correspondId)) ||
                            (item.getMaterialId().equals(record.getMaterialId()) && CollectionUtils.isNotEmpty(correspondId) &&  correspondId.contains(item.getCorrespondId())))
                    .collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(collectNum))
                record.setNum(collectNum.stream().mapToInt(StockBean::getNum).sum());
            else
                record.setNum(0);
            //经销商预留库存
            List<StockBean> collectReservedNum = reservedNum.stream()
                    .filter(item -> (item.getMaterialId().equals(record.getMaterialId()) && CollectionUtils.isEmpty(correspondId)) ||
                            (item.getMaterialId().equals(record.getMaterialId()) && CollectionUtils.isNotEmpty(correspondId) &&  correspondId.contains(item.getCorrespondId())))
                    .collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(collectReservedNum))
                record.setReservedNum(collectReservedNum.stream().mapToInt(StockBean::getReservedNum).sum());
            else
                record.setReservedNum(0);
            //可开数量
            record.setOpenNumber(record.getStockAdequate() - record.getNum() - record.getTemporaryNum() - record.getReservedNum());


        }
        list.setRecords(records);
        return list;
    }


    public IPage<StockCustomerReserved> listCustomer(String categoryId, String materialName, String materialNumber, String specification, String customerName,
                                                     String customerNumber, Integer pageNum, Integer pageSize) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        String customerId = adminUser.getIsCustomer() ? adminUser.getCustomerId() : "";
        return stockCommonMapper.listCustomer(new Page<>(pageNum, pageSize),categoryId,materialName,materialNumber,specification,customerName,customerNumber,customerId);
    }

    public void syncStock(String orgId, String orgNumber, String startTime, String endTime) throws Exception {
        // 调用即时库存
        RequestApiBean request = k3Logic.getInstance(orgId, orgNumber, KingDeeCons.STOCK_AMOUNT, startTime, endTime);
        String filterStr = "";
        request.setFieldKeys("FID,FStockId,FMaterialId,FBaseQty");
        request.setFilterString(String.format(filterStr, orgNumber));
        request.setOrderString("");

        String[] fields = new String[]{"id", "stockId", "materialId", "stockQty"};
        List<Stock> objects = k3Logic.allSync(request, fields, Stock.class);
        if (Objects.nonNull(objects)) {
            stockService.saveOrUpdateBatch(objects);
        }
    }

    public List<StockStatusBean> stockStatus(String correspondId, List<String> materialId) {
        List<StockStatusBean> stockStatusBeans = new ArrayList<>();

        AdminUserCom adminUser = commonLogic.getAdminUser();

        for (String s : materialId) {
            KingDeeMaterial kingDeeMaterial = kingDeeMaterialService.getById(s);

            //优先
            if (adminUser.getIsCustomer() && adminUserForceStockService.lambdaQuery()
                    .eq(AdminUserForceStock::getCategoryId, kingDeeMaterial.getCategoryId())
                    .eq(AdminUserForceStock::getCorrespondId,correspondId)
                    .eq(AdminUserForceStock::getAdminUserId,adminUser.getAdminUserId())
                    .count() < 1) {
                //强制仓返回，有强制仓，判断强制是否有库存，有库存都返回0,没返回正常库存
                List<AdminUserForceStock> list = adminUserForceStockService.lambdaQuery()
                        .eq(AdminUserForceStock::getCategoryId, kingDeeMaterial.getCategoryId())
                        .ne(AdminUserForceStock::getCorrespondId, correspondId)
                        .eq(AdminUserForceStock::getAdminUserId,adminUser.getAdminUserId())
                        .list();

                if (!CollectionUtils.isEmpty(list)) {
                    Boolean ifT = false;
                    for (AdminUserForceStock adminUserForceStock : list) {
                        if (stockCorrespondStatus(null, adminUserForceStock.getCorrespondId(), s, null) > 0) {
                            StockStatusBean stockStatusBean = new StockStatusBean();
                            stockStatusBean.setAllStockNum(0);
                            stockStatusBean.setStockNum(0);
                            stockStatusBean.setMaterialId(s);
                            stockStatusBeans.add(stockStatusBean);
                            ifT = true;
                            continue;
                        }
                    }
                    if (ifT) {
                        continue;
                    }

                }
            }


            //用户拥有此仓库，正常返回
            Integer stockCount = adminUserStockService.lambdaQuery().eq(AdminUserStock::getCorrespondId, correspondId)
                    .eq(AdminUserStock::getAdminUserId,adminUser.getAdminUserId()).count();
            if (stockCount > 0){
                StockStatusBean stockStatusBean = new StockStatusBean();
                stockStatusBean.setAllStockNum(stockOpendNumber(correspondId,s));
                stockStatusBean.setStockNum(stockCorrespondStatus(null, correspondId, s,null));
                stockStatusBean.setMaterialId(s);
                stockStatusBeans.add(stockStatusBean);
                continue;
            }


            //仓库无配置分类，无拥有仓库，且无分类,无该仓库
            List<StockCorrespondCategory> stockCorrespondCategories = stockCorrespondCategoryService.lambdaQuery()
                    .in(StockCorrespondCategory::getCorrespondId, correspondId)
                    .eq(StockCorrespondCategory::getCategoryId,kingDeeMaterial.getCategoryId()).list();
            if (org.springframework.util.CollectionUtils.isEmpty(stockCorrespondCategories)){
                StockStatusBean stockStatusBean = new StockStatusBean();
                stockStatusBean.setAllStockNum(0);
                stockStatusBean.setStockNum(0);
                stockStatusBean.setMaterialId(s);
                stockStatusBeans.add(stockStatusBean);
                continue;

            }




            StockStatusBean stockStatusBean = new StockStatusBean();
            stockStatusBean.setAllStockNum(stockOpendNumber(correspondId,s));
            stockStatusBean.setStockNum(stockCorrespondStatus(null, correspondId, s,null));
            stockStatusBean.setMaterialId(s);
            stockStatusBeans.add(stockStatusBean);



        }
        return stockStatusBeans;
    }


    /**
     * 总仓库该物料的库存不扣除暂扣库存
     * 物料ID
     * return 返回该总仓库物料库存情况
     * 总库存数量
     */
    public BigDecimal stockQty(String correspondId,String materialId) {
        //找出该仓库的所有仓位
        List<StockCorrespondPosition> stockCorrespondPosition = stockCorrespondPositionService.lambdaQuery().eq(StringUtils.isNotBlank(correspondId),StockCorrespondPosition::getCorrespondId, correspondId).list();
        List<String> stockIds = stockCorrespondPosition.stream().map(StockCorrespondPosition::getStockId).collect(Collectors.toList());

        //查出该物料得所有仓位的该物料库存
        List<Stock> list = stockService.lambdaQuery().select(Stock::getStockQty, Stock::getStockId)
                .in(StringUtils.isNotBlank(correspondId),Stock::getStockId, stockIds)
                .eq(Stock::getMaterialId, materialId).list();
        BigDecimal count;
        List<String> stockId = list.stream().map(Stock::getStockId).collect(Collectors.toList());
        count = list.stream().map(Stock::getStockQty).reduce(BigDecimal.ZERO, BigDecimal::add);
        if (CollectionUtils.isEmpty(stockId))
            return new BigDecimal("0");
        return count==null?new BigDecimal("0"):count;
    }


    /**
     * 总仓库该物料的库存
     * 物料ID
     * return 返回该总仓库物料库存情况
     * 总库存数量
     */
    public Integer stockAdequate(String correspondId, String materialId) {
        //找出该仓库的所有仓位
        Integer integer = stockKingDeeNumber(correspondId, materialId);
        return integer;
    }

    /**
     * 可开单数量
     * 物料ID
     * return 返回该总仓库物料库存情况
     * 总库存数量
     */
    public Integer stockOpendNumber(String correspondId, String materialId) {

        //查出锁定数量
        Integer integer = materialStock(correspondId, materialId);

        Integer count = stockKingDeeNumber(correspondId, materialId);

        return Convert.toInt(count) - integer;
    }

    /**
     * 该仓库库存数量
     * correspondId 仓库id   物料id
     */
    public Integer stockCorrespondStatus(String orderId,String correspondId, String materialId,String customerIds) {

        //查出锁定数量 申请暂扣
        Integer integer = materialInvoiceStock(correspondId, materialId,orderId);

        //查出锁定仓库 的预留数量
        AdminUserCom adminUser = commonLogic.getAdminUser();
        String customerId = StringUtils.isNotEmpty(customerIds)?customerIds:adminUser.getIsCustomer() ? adminUser.getCustomerId() : "";
        //非仓库扣除预留 除去该订单预留 非该经销商的预留
        Integer resverdNumber = stockCommonMapper.resverdNumber(null, materialId,orderId,customerId);
        //仓库扣除预留 除去该订单预留 非该经销商的预留
        Integer resverdStockNumber = stockCommonMapper.resverdNumber(correspondId, materialId,orderId,customerId);

        //仓库扣除预留 除去该订单预留 该经销商的预留
        Integer resverdStockCustomerNumber = stockCommonMapper.resverdCustomerNumber(correspondId, materialId,orderId,customerId);

        //仓库扣除预留 除去该订单预留 该经销商的预留
        Integer resverdStockNumberRe = stockCommonMapper.resverdCustomerNumberRe(correspondId, materialId,orderId,customerId);

        Integer count = stockKingDeeNumber(correspondId, materialId);


        //总物料预留  变为负数锁定库存
        Integer resverdAllStockNumber = stockCommonMapper.resverdAllStockNumber(null, materialId);
        //总库存数量
        Integer allCount = stockKingDeeNumber(null, materialId);

        Integer resverdStockNumberYUliu = stockCommonMapper.resverdCustomerNumberRe(correspondId, materialId,null,customerId);

        if (resverdStockNumberYUliu > 0){
            return count-integer > resverdStockNumberYUliu ? resverdStockNumberYUliu:count-integer;
        }


        if (resverdAllStockNumber > Convert.toInt(allCount))
            return 0;


        //减去剩余多余预留数量
        int i = stockAdequate(null, materialId) - Convert.toInt(count);
        Integer sum = resverdNumber-i>=0?i:0;
        sum = sum>=0?sum:0;

        if (resverdStockNumberRe > 0){
            return count-integer;
        }
        return Convert.toInt(count) -sum-resverdStockNumber-integer-resverdStockCustomerNumber;

    }


    /**
     * 该仓库库存数量
     * correspondId 仓库id   物料id
     */
    public Integer stockCorrespondStatusRe(String orderId,String correspondId, String materialId,String customerIds) {

        //查出锁定数量 申请暂扣
        Integer integer = materialInvoiceStock(correspondId, materialId,orderId);

        //查出锁定仓库 的预留数量

        //非仓库扣除预留 除去该订单预留 非该经销商的预留
        Integer resverdNumber = stockCommonMapper.resverdNumber(null, materialId,orderId,customerIds);
        //仓库扣除预留 除去该订单预留 非该经销商的预留
        Integer resverdStockNumber = stockCommonMapper.resverdNumber(correspondId, materialId,orderId,customerIds);

        //仓库扣除预留 除去该订单预留 该经销商的预留
        Integer resverdStockCustomerNumber = stockCommonMapper.resverdCustomerNumber(correspondId, materialId,orderId,customerIds);

        //仓库扣除预留 除去该订单预留 该经销商的预留
        Integer resverdStockNumberRe = stockCommonMapper.resverdCustomerNumberRe(correspondId, materialId,orderId,customerIds);

        Integer count = stockKingDeeNumber(correspondId, materialId);


        //总物料预留  变为负数锁定库存
        Integer resverdAllStockNumber = stockCommonMapper.resverdAllStockNumberRE(null, materialId);
        Integer resverdStockNumberA = stockCommonMapper.resverdAllStockNumber(correspondId, materialId);

        //总库存数量
        Integer allCount = stockKingDeeNumber(null, materialId);


        Integer all = materialInvoiceStock(null, materialId,orderId);

        if (allCount-all < resverdAllStockNumber)
            return 0;


       //仓库库存 - 锁定 - 仓库预留
        return Convert.toInt(count) -integer-resverdStockNumberA;

    }

    /**
     * 该仓库库存数量
     * correspondId 仓库id   物料id
     */
    public Integer stockCorrespondStatusNO(String orderId,String correspondId, String materialId,String customerIds) {

        //查出锁定数量 申请暂扣
        Integer integer = materialInvoiceStock(correspondId, materialId,orderId);

        //查出锁定仓库 的预留数量
/*        AdminUserCom adminUser = commonLogic.getAdminUser();
        String customerId = StringUtils.isNotEmpty(customerIds)?customerIds:adminUser.getIsCustomer() ? adminUser.getCustomerId() : "";*/
        //非仓库扣除预留 除去该订单预留 非该经销商的预留
        Integer resverdNumber = stockCommonMapper.resverdNumber(null, materialId,orderId,customerIds);
        //仓库扣除预留 除去该订单预留 非该经销商的预留
        Integer resverdStockNumber = stockCommonMapper.resverdNumber(correspondId, materialId,orderId,customerIds);

        //仓库扣除预留 除去该订单预留 该经销商的预留
        Integer resverdStockCustomerNumber = stockCommonMapper.resverdCustomerNumber(correspondId, materialId,orderId,customerIds);

        //仓库扣除预留 除去该订单预留 该经销商的预留
        Integer resverdStockNumberRe = stockCommonMapper.resverdCustomerNumberRe(correspondId, materialId,orderId,customerIds);

        Integer count = stockKingDeeNumber(correspondId, materialId);


        //总物料预留  变为负数锁定库存
        Integer resverdAllStockNumber = stockCommonMapper.resverdAllStockNumber(null, materialId);
        //总库存数量
        Integer allCount = stockKingDeeNumber(null, materialId);
        if (resverdAllStockNumber > Convert.toInt(allCount))
            return 0;


        //减去剩余多余预留数量
        int i = stockAdequate(null, materialId) - Convert.toInt(count);
        Integer sum = resverdNumber-i>=0?i:0;
        sum = sum>=0?sum:0;

        if (resverdStockNumberRe > 0){
            return count-integer;
        }
        return Convert.toInt(count) -sum-resverdStockNumber-integer-resverdStockCustomerNumber;

    }


    /**
     * 该仓库虚拟仓位库存数量
     * correspondId 仓库id
     * materialId  物料id
     */
    public Integer stockVirtualStatus(String correspondId,String stockId, String materialId,String CustomerId) {
        //查询该仓库库存
        Integer integer = stockCommonLogic.stockCorrespondStatus(null, correspondId, materialId,CustomerId);

        return integer;
    }


    /**
     * 该物料被锁定的库存-申请发货扣除库存
     * 物料materialId
     */
    public Integer materialInvoiceStock(String correspondId, String materialId,String orderId) {
        //申请发货该物料的暂扣库存
        Integer invoice = stockCommonMapper.selectInvoiceCount(correspondId, materialId);
        Integer countInvoice = stockCommonMapper.countAll(correspondId, materialId);
        return invoice  +countInvoice;
    }


    /**
     * 该物料被锁定的库存
     * 物料materialId
     */
    public Integer materialStock(String correspondId, String materialId) {
        //申请发货该物料的暂扣库存
        Integer invoice = stockCommonMapper.selectInvoiceCount(correspondId, materialId);
        Integer countInvoice = stockCommonMapper.countAll(correspondId, materialId);

        //预留单中该物料预留库存   无绑定仓库和指定相应仓库
        List<ReservedOrderItem> reservedOrderItems = reservedOrderItemService.lambdaQuery().eq(ReservedOrderItem::getMaterialId, materialId)
                .eq(ReservedOrderItem::getStatus, 1)
                .select(ReservedOrderItem::getReservedNum).list();
        int sum = reservedOrderItems.stream().mapToInt(ReservedOrderItem::getReservedNum).sum();
        return invoice + sum +countInvoice;
    }

    /**
     * 仓库库存导出
     *
     * @param maps
     * @return
     */
    public ExcelData export(List<StockBean> maps) {
        String[] titles = new String[]{"产品类别", "物料编码", "厂产品代码", "产品名称",
                "规格型号", "单位", "总库存数量", "可用库数","可开单数", "经销商预留库存", "经销商暂扣库存", "开单未提数量","物料分组"};
        List<List<Object>> rows = new ArrayList<>();
        for (StockBean stockBean : maps) {
            List<Object> row = new ArrayList<>();
            row.add(stockBean.getCategoryName());
            row.add(stockBean.getMaterialNumber());
            row.add(stockBean.getMaterialOldNumber());
            row.add(stockBean.getMaterialName());
            row.add(stockBean.getSpecification());
            row.add(stockBean.getBaseUnitId());
            row.add(stockBean.getStockQty());
            row.add(stockBean.getStockAdequate());
            row.add(stockBean.getOpenNumber());
            row.add(stockBean.getReservedNum());
            row.add(stockBean.getTemporaryNum());
            row.add(stockBean.getNum());
            row.add(stockBean.getMaterialGroupName());
            rows.add(row);
        }
        ExcelData excelData = new ExcelData();
        excelData.setRows(rows);
        excelData.setTitles(Arrays.asList(titles));
        return excelData;
    }

    /**
     * 经销商预留库存导出
     *
     * @param stockCustomers
     * @return
     */
    public ExcelData listCustomerExport(List<StockCustomerReserved> stockCustomers) {
        String[] titles = new String[]{"经销商编码", "经销商名称", "产品品类", "厂产品代码", "产品名称",
                "规格型号", "计量单位", "经销商预留库存", "经销商暂扣库存"};
        List<List<Object>> rows = new ArrayList<>();
        for (StockCustomerReserved stockCustomer : stockCustomers) {
            List<Object> row = new ArrayList<>();
            row.add(stockCustomer.getCustomerNumber());
            row.add(stockCustomer.getCustomerName());
            row.add(stockCustomer.getCategoryName());
            row.add(stockCustomer.getMaterialNumber());
            row.add(stockCustomer.getMaterialName());
            row.add(stockCustomer.getSpecification());
            row.add(stockCustomer.getUnit());
            row.add(stockCustomer.getReservedNum());
            rows.add(row);
        }
        ExcelData excelData = new ExcelData();
        excelData.setRows(rows);
        excelData.setTitles(Arrays.asList(titles));
        return excelData;
    }

    /**
     * 金蝶仓位列表
     * correspondId 大仓id
     */
    public List<KingDeeStock> listStockIn(String correspondId) {
        //找出该仓库的所有仓位
        List<StockCorrespondPosition> stockCorrespondPosition = stockCorrespondPositionService.lambdaQuery().eq(StockCorrespondPosition::getCorrespondId, correspondId).list();
        List<String> stockId = stockCorrespondPosition.stream().map(StockCorrespondPosition::getStockId).collect(Collectors.toList());

        //找出虚拟仓
        List<KingDeeStock> kingDeeStocks = kingDeeStockService.lambdaQuery().in(KingDeeStock::getId, stockId).list();

        return kingDeeStocks;
    }


    /**
     * 增加经销商预留库存
     * 物料materialId  经销商customerId   增加数量num
     */
    public void inventoryStockCustomer(String materialId, String customerId, Integer num) {
        //有数据更新数据
        StockCustomer stockCustomer;
        stockCustomer = stockCustomerService.lambdaQuery().eq(StockCustomer::getCustomerId, customerId).eq(StockCustomer::getMaterialId, materialId).one();
        if (stockCustomer != null) {
            stockCustomer.setReservedNum(stockCustomer.getReservedNum() + num);
            stockCustomer.updateById();
            return;
        }

        //无数据添加数据
        KingDeeMaterial kingDeeMaterial = kingDeeMaterialService.getById(materialId);
        KingDeeCustomer kingDeeCustomer = kingDeeCustomerService.getById(customerId);
        stockCustomer = new StockCustomer();
        stockCustomer.setCustomerId(kingDeeCustomer.getId());
        stockCustomer.setCustomerName(kingDeeCustomer.getName());
        stockCustomer.setCustomerNumber(kingDeeCustomer.getNumber());
        stockCustomer.setMaterialName(kingDeeMaterial.getName());
        stockCustomer.setMaterialId(kingDeeMaterial.getId());
        stockCustomer.setMaterialNumber(kingDeeMaterial.getNumber());
        stockCustomer.setSpecification(kingDeeMaterial.getSpecification());
        stockCustomer.setUnit(kingDeeMaterial.getBaseUnitId());
        stockCustomer.setCategoryName(kingDeeMaterial.getCategoryName());
        stockCustomer.setReservedNum(num);
        stockCustomer.insert();

    }


    /**
     * 减少经销商预留库存
     * 物料materialId  经销商customerId   减少数量num
     */
    public void reduceStockCustomer(String materialId, String customerId, Integer num) {
        //有数据更新数据
        StockCustomer stockCustomer;
        stockCustomer = stockCustomerService.lambdaQuery().eq(StockCustomer::getCustomerId, customerId)
                .eq(StockCustomer::getMaterialId, materialId).one();
        if (stockCustomer != null) {
            stockCustomer.setReservedNum(stockCustomer.getReservedNum() - num);
            stockCustomer.updateById();
            return;
        }

    }

    /**
     * 增加经销商暂扣库存
     * 物料materialId  经销商customerId   增加数量num
     */
    public void inventoryStockCustomerSuspended(String materialId, String customerId, Integer num) {
        //有数据更新数据
        StockCustomer stockCustomer;
        stockCustomer = stockCustomerService.lambdaQuery().eq(StockCustomer::getCustomerId, customerId).eq(StockCustomer::getMaterialId, materialId).one();
        if (stockCustomer != null) {
            stockCustomer.setTemporaryNum(stockCustomer.getTemporaryNum() + num);
            stockCustomer.updateById();
            return;
        }

        //无数据添加数据
        KingDeeMaterial kingDeeMaterial = kingDeeMaterialService.getById(materialId);
        KingDeeCustomer kingDeeCustomer = kingDeeCustomerService.getById(customerId);
        stockCustomer = new StockCustomer();
        stockCustomer.setCustomerId(kingDeeCustomer.getId());
        stockCustomer.setCustomerName(kingDeeCustomer.getName());
        stockCustomer.setCustomerNumber(kingDeeCustomer.getNumber());
        stockCustomer.setMaterialName(kingDeeMaterial.getName());
        stockCustomer.setMaterialId(kingDeeMaterial.getId());
        stockCustomer.setMaterialNumber(kingDeeMaterial.getNumber());
        stockCustomer.setSpecification(kingDeeMaterial.getSpecification());
        stockCustomer.setUnit(kingDeeMaterial.getBaseUnitId());
        stockCustomer.setReservedNum(num);
        stockCustomer.insert();
    }


    /**
     * 减少经销商暂扣库存
     * 物料materialId  经销商customerId   减少数量num
     */
    public void reduceStockCustomerSuspended(String materialId, String customerId, Integer num) {
        //有数据更新数据
        StockCustomer stockCustomer;
        stockCustomer = stockCustomerService.lambdaQuery().eq(StockCustomer::getCustomerId, customerId).eq(StockCustomer::getMaterialId, materialId).one();
        if (stockCustomer != null) {
            stockCustomer.setTemporaryNum(stockCustomer.getTemporaryNum() - num);
            stockCustomer.updateById();
            return;
        }

    }

    public IPage<StockPositionStock> listStock(String name, String stockName, Integer pageNum, Integer pageSize,Integer type) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        if (type != null && type.equals(2)) {
            IPage<StockPositionStock> stockPositionStockIPage = stockCommonMapper.listStock(new Page<>(pageNum, pageSize), name, stockName, adminUser.getMasterAdminUserId(), type);
            return stockPositionStockIPage;
        }

        List<AdminUserStock> adminUserStocks = adminUserStockService.lambdaQuery().eq(AdminUserStock::getAdminUserId, adminUser.getAdminUserId()).list();
        List<String> stockId = adminUserStocks.stream().map(AdminUserStock::getCorrespondId).collect(Collectors.toList());
        
        List<AdminUserCategoryRela> list = adminUserCategoryRelaService.lambdaQuery()
                .eq(AdminUserCategoryRela::getAdminUserId, adminUser.getAdminUserId()).select(AdminUserCategoryRela::getK3CategoryId).list();
        if (!CollectionUtils.isEmpty(list)) {
            List<String> collect = list.stream().map(AdminUserCategoryRela::getK3CategoryId).collect(Collectors.toList());
            List<StockCorrespondCategory> stockCorrespondCategories = stockCorrespondCategoryService
                    .lambdaQuery().in(StockCorrespondCategory::getCategoryId, collect).list();
            List<String> stockPositionStockIPage = stockCorrespondCategories.stream().map(StockCorrespondCategory::getCorrespondId).collect(Collectors.toList());

            stockId.addAll(stockPositionStockIPage);
        }

        List<String> stockIds = stockId.stream().distinct().collect(Collectors.toList());

        List<StockCorrespond> stockCorrespond = stockCorrespondService.lambdaQuery().in(StockCorrespond::getId, stockIds).list();

        IPage<StockPositionStock> stockIPage = new Page<>();
        List<StockPositionStock> stockPositionStocks = BeanUtil.copyToList(stockCorrespond, StockPositionStock.class);
        stockIPage.setRecords(stockPositionStocks);

        return stockIPage;
    }


    /**
     * 金蝶仓库库存数量
     * 物料ID
     * return 返回该总仓库物料库存情况
     * 总库存数量
     */
    public Integer stockKingDeeNumber(String correspondId, String materialId) {
        Integer integer = stockCommonMapper.sumKingDeeNumber(correspondId,materialId);
        return integer;
    }

    /**
     * 该仓库库存数量
     * correspondId 仓库id   物料id
     */
    public Integer stockKingDeeCorrespondStatus(String correspondId, String materialId) {


        //找出该仓库的所有仓位
        List<StockCorrespondPosition> stockCorrespondPosition = stockCorrespondPositionService.lambdaQuery().eq(StringUtils.isNotBlank(correspondId),StockCorrespondPosition::getCorrespondId, correspondId).list();
        List<String> stockId = stockCorrespondPosition.stream().map(StockCorrespondPosition::getStockId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(stockId))
            return 0;

        //找出仓位的所有库存数
        //去除不参与计算的仓库
        List<KingDeeStock> kingDeeStock = kingDeeStockService.lambdaQuery().in(KingDeeStock::getId, stockId).eq(KingDeeStock::getNotExpQty, 0).select(KingDeeStock::getId).list();
        List<String> stcokIds = kingDeeStock.stream().map(KingDeeStock::getId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(stcokIds))
            return 0;

        List<Stock> list = stockService.lambdaQuery().select(Stock::getStockQty, Stock::getStockId).eq(Stock::getMaterialId, materialId).in(Stock::getStockId, stcokIds).list();
        BigDecimal count;
        count = list.stream().map(Stock::getStockQty).reduce(BigDecimal.ZERO, BigDecimal::add);

        return Convert.toInt(count);

    }

    /**
     * 去除不计算库存的仓库的库存减去暂扣数量
    * */
    public Integer stockNumber(String materialId, String correspondId) {
        Integer integer = stockOpendNumber(correspondId, materialId);
        return integer;
    }

    public String stockHint(String correspondId, List<String> invoiceOrderIds ,String pickTime) {
        String string= "";
        for (String invoiceOrderId : invoiceOrderIds) {
            InvoiceApplicationOrder invoiceApplicationOrder = invoiceApplicationOrderService.getById(invoiceOrderId);
            KingDeeMaterial kingDeeMaterial = kingDeeMaterialService.getById(invoiceApplicationOrder.getMaterialId());
            if (stockReserveService.lambdaQuery().eq(StockReserve::getCorrespondId,correspondId).eq(StockReserve::getCategoryId,kingDeeMaterial.getCategoryId()).count() > 0){
                StockReserve stockReserve = stockReserveService.lambdaQuery().eq(StockReserve::getCorrespondId, correspondId).eq(StockReserve::getCategoryId, kingDeeMaterial.getCategoryId()).one();
                Date date = DateUtil.parse(pickTime, "yyyy-MM-dd HH:mm:ss");

                //开单数量
                Integer integer = stockCommonMapper.stockHintUnit(correspondId,invoiceApplicationOrder.getMaterialId(),getStartOfDay(date),getEndOfDay(date));
                //提货数量
                Integer tower = stockCommonMapper.stockHintTower(correspondId,invoiceApplicationOrder.getMaterialId(),getStartOfDay(date),getEndOfDay(date));

                if (stockReserve.getNumber() != null && stockReserve.getNumber() < integer)
                    string=string+invoiceApplicationOrder.getMaterialName()+",";

                if (stockReserve.getTowerNum() != null &&  stockReserve.getTowerNum() < tower)
                    string=string+invoiceApplicationOrder.getMaterialName()+",";

            }
        }
        if (StringUtils.isNotBlank(string)){
            return string+"你选择得物料已超过当前仓库预约限制，是否继续预约";
        }
        return null;
    }


    private Date getStartOfDay(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    private Date getEndOfDay(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTime();
    }

    public IPage<StockBeanToDay> listStockToDay(List<String> correspondId, List<String> categoryId, String materialOldNumber, String materialName, String materialNumber, String specification, Integer pageNum, Integer pageSize) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        IPage<StockBeanToDay> list = stockCommonMapper.listStockToDay(new Page<>(pageNum, pageSize), correspondId, categoryId,
                materialOldNumber, materialName, materialNumber, specification,adminUser.getAdminUserId(),null);

        List<StockBean> num = stockCommonMapper.countAllList(correspondId);
        for (StockBeanToDay record : list.getRecords()) {
            //开单未提数量
            //开单未提数量
            List<StockBean> collectNum = num.stream()
                    .filter(item -> (item.getMaterialId().equals(record.getMaterialId()) && StringUtils.isNotEmpty(record.getCorrespondId()) &&  item.getCorrespondId().equals(record.getCorrespondId())))
                    .collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(collectNum))
                record.setNum(collectNum.stream().mapToInt(StockBean::getNum).sum());
            else
                record.setNum(0);
            record.setStockAdequate(record.getBalanceNumber() - record.getNum());
        }

        return list;
    }

    public ExcelData exportStockToDay(List<StockBeanToDay> records) {

        String[] titles = new String[]{"仓库", "物料编码", "厂产品代码", "产品名称", "规格型号",
                "可用数量", "开单未提数量", "结存数量","存货类别"};
        List<List<Object>> rows = new ArrayList<>();
        for (StockBeanToDay stockBeanToDay : records) {
            List<Object> row = new ArrayList<>();
            row.add(stockBeanToDay.getCorrespondName());
            row.add(stockBeanToDay.getMaterialNumber());
            row.add(stockBeanToDay.getMaterialOldNumber());
            row.add(stockBeanToDay.getMaterialName());
            row.add(stockBeanToDay.getSpecification());
            row.add(stockBeanToDay.getStockAdequate());
            row.add(stockBeanToDay.getNum());
            row.add(stockBeanToDay.getBalanceNumber());
            row.add(stockBeanToDay.getCategoryName());

            rows.add(row);
        }
        ExcelData excelData = new ExcelData();
        excelData.setRows(rows);
        excelData.setTitles(Arrays.asList(titles));
        return excelData;
    }

    @Transactional(rollbackFor = Exception.class)
    public String receipt(String startTime,  String endTime) throws Exception {

        //开始时间
        String format = startTime;
        //结束时间
        String formatEnd = endTime;

        // 销售增值发票
        RequestApiBean request = k3Logic.getInstance(orgId, orgNum, KingDeeCons.IV_SALESIC, format, formatEnd);
        String filterStr = "";
        request.setFieldKeys("FID,FBillNo,FIVNUMBER,F_kls_Remarks,FINVOICEDATE");
        request.setFilterString(String.format(filterStr, orgNum));
        request.setOrderString("");

        String[] fields = new String[]{"id", "billNo", "fivNumber","comment","invoiceDate"};
        List<ReceiptInvoiceAdded> objects = k3Logic.allSync(request, fields, ReceiptInvoiceAdded.class);


        // 销售普通发票
        RequestApiBean requestOne = k3Logic.getInstance(orgId, orgNum, KingDeeCons.IV_SALESOC, format, formatEnd);
        String filterStrOne = "";
        requestOne.setFieldKeys("FID,FBillNo,FIVNUMBER,F_kls_Remarks,FINVOICEDATE");
        requestOne.setFilterString(String.format(filterStrOne, orgNum));
        requestOne.setOrderString("");

        String[] fieldsOne = new String[]{"id", "billNo", "fivNumber","comment","invoiceDate"};
        List<ReceiptInvoiceOrdinary> objectsOne = k3Logic.allSync(requestOne, fieldsOne, ReceiptInvoiceOrdinary.class);


        if (Objects.nonNull(objects)) {
            receiptInvoiceAddedService.saveOrUpdateBatch(objects);
        }

        if (Objects.nonNull(objectsOne)) {
            receiptInvoiceOrdinaryService.saveOrUpdateBatch(objectsOne);
        }

        if (CollectionUtils.isNotEmpty(objects)) {
            for (ReceiptInvoiceAdded object : objects) {
                if (StringUtils.isNotEmpty(object.getComment()) && StrUtil.isNotBlank(object.getFivNumber())) {
                    String[] split = object.getComment().split(",");
                    for (String orderId : split) {
                        SalesOrder salesOrder = salesOrderService.getById(orderId);
                        if (StringUtils.isNotEmpty(salesOrder.getBillReceipt()) && !salesOrder.getBillReceipt().contains(object.getFivNumber())) {
                            salesOrder.setBillReceipt(salesOrder.getBillReceipt() + "/" + object.getFivNumber());
                            salesOrder.setBillDate(object.getInvoiceDate());
                        }

                        if (StringUtils.isEmpty(salesOrder.getBillReceipt())) {
                            salesOrder.setBillReceipt(object.getFivNumber());
                            salesOrder.setBillDate(object.getInvoiceDate());
                        }
                        salesOrder.updateById();
                    }
                }
            }
        }

        if (CollectionUtils.isNotEmpty(objectsOne)) {
            for (ReceiptInvoiceOrdinary object : objectsOne) {
                if (StringUtils.isNotEmpty(object.getComment()) && StrUtil.isNotBlank(object.getFivNumber())) {
                    String[] split = object.getComment().split(",");
                    for (String orderId : split) {
                        SalesOrder salesOrder = salesOrderService.getById(orderId);
                        if (StringUtils.isNotEmpty(salesOrder.getBillReceipt()) && !salesOrder.getBillReceipt().contains(object.getFivNumber()))
                            salesOrder.setBillReceipt(salesOrder.getBillReceipt() + "/" + object.getFivNumber());

                        if (StringUtils.isEmpty(salesOrder.getBillReceipt()))
                            salesOrder.setBillReceipt(object.getFivNumber());
                        salesOrder.updateById();
                    }
                }
            }
        }


        return "1";
    }

    public IPage<StockBeanToDay> listStockToDayCustomer(List<String> correspondId, List<String> categoryId, String materialOldNumber, String materialName, String materialNumber, String specification, Integer pageNum, Integer pageSize) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        List<AdminUserCategoryRela> listCategory = adminUserCategoryRelaService.lambdaQuery().eq(AdminUserCategoryRela::getAdminUserId, adminUser.getAdminUserId()).list();
        List<String> categoryList = listCategory.stream().map(AdminUserCategoryRela::getK3CategoryId).collect(Collectors.toList());

        IPage<StockBeanToDay> list = stockCommonMapper.listStockToDay(new Page<>(pageNum, pageSize), correspondId, categoryId,
                materialOldNumber, materialName, materialNumber, specification,adminUser.getAdminUserId(),categoryList);
        
        List<StockBean> integer = stockCommonMapper.sumKingDeeNumberList(correspondId);
        List<StockBean> adequate = stockCommonMapper.sumKingDeeNumberAdequateList(correspondId);
        List<StockBean> temporay = stockCommonMapper.selectInvoiceCountList(correspondId);
        List<StockBean> num = stockCommonMapper.countAllList(correspondId);
        List<StockBean> reservedNum = stockCommonMapper.countReservedList(correspondId);
        for (StockBeanToDay record : list.getRecords()) {
            //可用数量
            List<StockBean> collectAdequate = adequate.stream()
                    .filter(item -> (item.getMaterialId().equals(record.getMaterialId()) && StringUtils.isNotEmpty(record.getCorrespondId()) &&  item.getCorrespondId().equals(record.getCorrespondId())) )
                    .collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(collectAdequate))
                record.setStockAdequate(collectAdequate.stream().mapToInt(StockBean::getStockAdequate).sum());
            else
                record.setStockAdequate(0);
            //总库存数量
            List<StockBean> collect = integer.stream()
                    .filter(item -> (item.getMaterialId().equals(record.getMaterialId()) && StringUtils.isNotEmpty(record.getCorrespondId()) &&  item.getCorrespondId().equals(record.getCorrespondId())) )
                    .collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(collect))
                record.setStockQty(collect.stream().mapToInt(StockBean::getStockQty).sum());
            else
                record.setStockQty(0);

            //经销商暂扣库存
            List<StockBean> collectTemporay = temporay.stream()
                    .filter(item -> (item.getMaterialId().equals(record.getMaterialId()) && StringUtils.isNotEmpty(record.getCorrespondId()) &&  item.getCorrespondId().equals(record.getCorrespondId())))
                    .collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(collectTemporay))
                record.setTemporaryNum(collectTemporay.stream().mapToInt(StockBean::getTemporaryNum).sum());
            else
                record.setTemporaryNum(0);
            //开单未提数量
            List<StockBean> collectNum = num.stream()
                    .filter(item -> (item.getMaterialId().equals(record.getMaterialId()) && StringUtils.isNotEmpty(record.getCorrespondId()) &&  item.getCorrespondId().equals(record.getCorrespondId())))
                    .collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(collectNum))
                record.setNum(collectNum.stream().mapToInt(StockBean::getNum).sum());
            else
                record.setNum(0);
            //经销商预留库存
            List<StockBean> collectReservedNum = reservedNum.stream()
                    .filter(item -> (item.getMaterialId().equals(record.getMaterialId()) && StringUtils.isNotEmpty(record.getCorrespondId()) &&  item.getCorrespondId().equals(record.getCorrespondId())))
                    .collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(collectReservedNum))
                record.setReservedNum(collectReservedNum.stream().mapToInt(StockBean::getReservedNum).sum());
            else
                record.setReservedNum(0);
            //可开数量
            record.setOpenNumber(record.getStockAdequate() - record.getNum() - record.getTemporaryNum() - record.getReservedNum());
        }

        return list;
    }

    public ExcelData exportStockToDayCustomer(List<StockBeanToDay> records) {
        String[] titles = new String[]{"仓库", "物料编码", "厂产品代码", "产品名称", "规格型号",
                "可开单数量"};
        List<List<Object>> rows = new ArrayList<>();
        for (StockBeanToDay stockBeanToDay : records) {
            List<Object> row = new ArrayList<>();
            row.add(stockBeanToDay.getCorrespondName());
            row.add(stockBeanToDay.getMaterialNumber());
            row.add(stockBeanToDay.getMaterialOldNumber());
            row.add(stockBeanToDay.getMaterialName());
            row.add(stockBeanToDay.getSpecification());
            row.add(stockBeanToDay.getOpenNumber() < 51?stockBeanToDay.getOpenNumber():stockBeanToDay.getOpenNumber()<1001?"有货":"充足");

            rows.add(row);
        }
        ExcelData excelData = new ExcelData();
        excelData.setRows(rows);
        excelData.setTitles(Arrays.asList(titles));
        return excelData;
    }

    public void syncStockIn() throws Exception {
        //调拨单
        stockOutInQuanLiang();
        stockOutIn();

    }



    @Transactional(rollbackFor = Exception.class)
    public void stockOutInQuanLiang() throws Exception {

        //全量更新
        // 调用退料单接口
        List<KingDeeTransfer> kingDeeTransfers = kingDeeTransferService.lambdaQuery().eq(KingDeeTransfer::getDocumentStatus, "C")
                .between(KingDeeTransfer::getApproveDate,DateUtil.offset(new Date(), DateField.MONTH, -2),new Date())
                .select(KingDeeTransfer::getId).list();
        if (CollectionUtil.isEmpty(kingDeeTransfers))
            return;
        //获得所有通过的单
        String orderId="";
        for (KingDeeTransfer kingDeeTransfer : kingDeeTransfers) {
            if (StringUtils.isEmpty(orderId)) {
                orderId = kingDeeTransfer.getId();
                continue;
            }
            orderId = orderId+","+kingDeeTransfer.getId();
        }
        RequestApiBean request = k3Logic.getInstance(orgId, orgNum, KingDeeCons.STOCK_TRANSFER, "2002-09-19 16:55:01", "2062-09-19 16:55:01");

        //查找被弃审的单
        String filterStr = "FDocumentStatus != 'C'"+ " AND FID IN ("+orderId+")";
        request.setFieldKeys("FID,FBillNo,FStockOrgId.FName,FStockOutOrgId.FName,FTransferBizType,FNote,FApproverId.FName,FCancellerId.FName,FBillTypeID.FName,FDocumentStatus,FDate,FApproveDate,FCancelDate");
        request.setFilterString(String.format(filterStr, orgNum));
        request.setOrderString("FID ASC");
        request.setNotTime(true);
        String[] fields = new String[]{"id","billNo","stockOrgId","stockOutOrgId","transferBizType","note","approverId","cancellerId","billType","documentStatus","fDate","approveDate","cancelDate"};
        List<KingDeeTransfer> objects = k3Logic.allSync(request, fields, KingDeeTransfer.class);
        /**
         *  全量查询表中不为已审核状态的单，退回数量，再删除数据，等下次审核
         * */
        if (CollectionUtil.isEmpty(objects))
            return;
        for (KingDeeTransfer object : objects) {
            //被弃审的返回数量
            List<KingDeeTransferItem> list = kingDeeTransferItemService.lambdaQuery().eq(KingDeeTransferItem::getFId, object.getId()).list();
            for (KingDeeTransferItem kingDeeTransferItem : list) {
                //查出被反审的内容
                Stock stock = stockService.lambdaQuery().eq(Stock::getStockId, kingDeeTransferItem.getSrcStockId())
                        .eq(Stock::getMaterialId, kingDeeTransferItem.getMaterialId()).last("limit 1").one();

                Stock stockDest = stockService.lambdaQuery().eq(Stock::getStockId, kingDeeTransferItem.getDestStockId())
                        .eq(Stock::getMaterialId, kingDeeTransferItem.getMaterialId()).last("limit 1").one();
                //调出库存加记录
                stockAccLog("全量反审的调拨单仓库加",stock,kingDeeTransferItem.getQty(),kingDeeTransferItem.getFId(),true,"调拨单");
                stock.setStockQty(stock.getStockQty().add(kingDeeTransferItem.getQty()));
                stock.updateById();
                //调入库存减记录
                stockAccLog("全量反审的调拨单仓库减",stockDest,kingDeeTransferItem.getQty(),kingDeeTransferItem.getFId(),false,"调拨单");
                stockDest.setStockQty(stockDest.getStockQty().subtract(kingDeeTransferItem.getQty()));
                stockDest.updateById();
                kingDeeTransferItemService.removeById(kingDeeTransferItem.getId());
            }
            kingDeeTransferService.removeById(object.getId());
        }

    }



    @Transactional(rollbackFor = Exception.class)
    public void stockOutIn() throws Exception {

        //1调拨单入库库存
        List<KingDeeTransferItem> kingDeeTransferItems = allOutInSync(orgId, orgNum, null, null);

        if (CollectionUtil.isNotEmpty(kingDeeTransferItems)) {
            for (KingDeeTransferItem kingDeeTransferItem : kingDeeTransferItems) {
                KingDeeTransferItem byId = kingDeeTransferItemService.getById(kingDeeTransferItem.getId());
                // 入库表表中能找到，相减加库存
                if (byId != null){

                    //新改变仓库 调出扣 调入加
                    Stock stock = stockService.lambdaQuery().eq(Stock::getStockId, kingDeeTransferItem.getSrcStockId())  //调出
                            .eq(Stock::getMaterialId, kingDeeTransferItem.getMaterialId()).last("limit 1").one();
                    stockAccLog("反审的调拨单仓库扣",stock,kingDeeTransferItem.getQty(),kingDeeTransferItem.getFId(),false,"调拨单");
                    stock.setStockQty(stock.getStockQty().subtract(kingDeeTransferItem.getQty()));
                    stock.updateById();

                    Stock stockDest = stockService.lambdaQuery().eq(Stock::getStockId, kingDeeTransferItem.getDestStockId())
                            .eq(Stock::getMaterialId, kingDeeTransferItem.getMaterialId()).last("limit 1").one();  //调入
                    stockAccLog("反审的调拨单仓库加",stockDest,kingDeeTransferItem.getQty(),kingDeeTransferItem.getFId(),true,"调拨单");
                    stockDest.setStockQty(stockDest.getStockQty().add(kingDeeTransferItem.getQty()));
                    stockDest.updateById();

                    //旧改变仓库  调出加  调入扣
                    Stock stockOut = stockService.lambdaQuery().eq(Stock::getStockId, byId.getSrcStockId())
                            .eq(Stock::getMaterialId, kingDeeTransferItem.getMaterialId()).last("limit 1").one();  //调出
                    stockAccLog("反审的调拨单仓库加",stockOut,kingDeeTransferItem.getQty(),kingDeeTransferItem.getFId(),true,"调拨单");
                    stockOut.setStockQty(stockOut.getStockQty().add(kingDeeTransferItem.getQty()));
                    stockOut.updateById();


                    Stock stockIn = stockService.lambdaQuery().eq(Stock::getStockId, byId.getDestStockId())
                            .eq(Stock::getMaterialId, kingDeeTransferItem.getMaterialId()).last("limit 1").one();  //调入
                    stockAccLog("反审的调拨单仓库扣",stockIn,kingDeeTransferItem.getQty(),kingDeeTransferItem.getFId(),false,"调拨单");
                    stockIn.setStockQty(stockIn.getStockQty().subtract(kingDeeTransferItem.getQty()));
                    stockIn.updateById();

                }


                // 入库表不能找到，查看库存表有无记录 ，无库存记录找库存，有库存记录相加
                if (byId == null){
                    //新仓库加减
                    Stock stock = stockService.lambdaQuery().eq(Stock::getStockId, kingDeeTransferItem.getSrcStockId())
                            .eq(Stock::getMaterialId, kingDeeTransferItem.getMaterialId()).last("limit 1").one();

                    Stock stockDest = stockService.lambdaQuery().eq(Stock::getStockId, kingDeeTransferItem.getDestStockId())
                            .eq(Stock::getMaterialId, kingDeeTransferItem.getMaterialId()).last("limit 1").one();
                    //仓库有记录
                    if (stockDest != null){
                        //库存加减记录
                        stockAccLog("调拨单仓库扣",stock,kingDeeTransferItem.getQty(),kingDeeTransferItem.getFId(),false,"调拨单");
                        //调出扣库存
                        stock.setStockQty(stock.getStockQty().subtract(kingDeeTransferItem.getQty()));
                        stock.updateById();

                        //调入仓库加库存
                        stockAccLog("调拨单仓库加",stockDest,kingDeeTransferItem.getQty(),kingDeeTransferItem.getFId(),true,"调拨单");
                        stockDest.setStockQty(stockDest.getStockQty().add(kingDeeTransferItem.getQty()));
                        stockDest.updateById();

                    }
                    //仓库库存记录无记录
                    if (stockDest == null){

                        //库存加减记录
                        stockAccLog("调拨单仓库扣",stock,kingDeeTransferItem.getQty(),kingDeeTransferItem.getFId(),false,"调拨单");
                        //调出扣库存
                        stock.setStockQty(stock.getStockQty().subtract(kingDeeTransferItem.getQty()));
                        stock.updateById();


                        Stock stockIn = stockId( kingDeeTransferItem.getDestStockId(),kingDeeTransferItem.getMaterialId());
                        stockIn.setStockQty(new BigDecimal("0"));
                        //调入仓库加库存
                        stockAccLog("调拨单仓库加",stockIn,kingDeeTransferItem.getQty(),kingDeeTransferItem.getFId(),true,"调拨单");
                        stockIn.setStockQty(stockIn.getStockQty().add(kingDeeTransferItem.getQty()));
                        stockIn.insert();
                    }
                }
            }

            kingDeeTransferItemService.saveOrUpdateBatch(kingDeeTransferItems);
        }

    }

    private Stock stockId(String  stockId,String materialId) throws Exception {
        // 调用即时库存
        RequestApiBean request = k3Logic.getInstance(null, null, KingDeeCons.STOCK_AMOUNT, null, null);

        String filterStr = "FStockId = "+ stockId+"AND FMaterialId="+materialId;
        request.setFieldKeys("FID,FStockId,FMaterialId,FBaseQty,FStockOrgId");
        request.setStartTime(null);
        request.setEndTime(null);
        request.setFilterString(filterStr);
        request.setOrderString("");

        String[] fields = new String[]{"id", "stockId", "materialId", "stockQty", "orgId"};
        List<Stock> objects = k3Logic.allSync(request, fields, Stock.class);
        if (CollectionUtil.isNotEmpty(objects)) {
            return objects.get(0);

        }else {
            throw new RemoteServiceException("数据为空，异常");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void stockAccLog(String remark, Stock stock, BigDecimal number,String FID,Boolean type,String refType) {
        StockAcc stockAcc = new StockAcc();
        stockAcc.setStockId(stock.getStockId());
        stockAcc.setMaterialId(stock.getMaterialId());
        stockAcc.setChangeTime(new Date());
        int i = number.compareTo(BigDecimal.ZERO);
        stockAcc.setDirectFlag(type);
        stockAcc.setStockChangeQty(number);
        stockAcc.setStockCurQty(stock.getStockQty());
        stockAcc.setStockCloseQty(type == true?stock.getStockQty().add(number):stock.getStockQty().subtract(number));
        stockAcc.setRef(FID);
        stockAcc.setRefType(StringUtils.isNotEmpty(refType)?refType:"采购入库单");
        stockAcc.setUpdateTime(new Date());
        stockAcc.setNotes(remark);
        stockAcc.insert();
    }


    public List<KingDeeTransferItem> allOutInSync(String orgId, String orgNumber, String startTime, String endTime) throws Exception {
        // 调用入库单接口

        RequestApiBean request = k3Logic.getInstance(orgId, orgNumber, KingDeeCons.STOCK_TRANSFER, startTime, endTime);
        String filterStr = "FDocumentStatus = 'C' "+ k3Logic.supplySql("FApproveDate", request.getStartTime(), request.getEndTime());
        request.setFieldKeys("FID,FBillNo,FStockOrgId.FName,FStockOutOrgId.FName,FTransferBizType,FNote,FApproverId.FName,FCancellerId.FName,FBillTypeID.FName,FDocumentStatus,FDate,FApproveDate,FCancelDate");
        request.setFilterString(String.format(filterStr, orgNum));
        request.setOrderString("FID ASC");
        request.setNotTime(true);
        String[] fields = new String[]{"id","billNo","stockOrgId","stockOutOrgId","transferBizType","note","approverId","cancellerId","billType","documentStatus","fDate","approveDate","cancelDate"};
        List<KingDeeTransfer> objects = k3Logic.allSync(request, fields, KingDeeTransfer.class);

        if (!org.springframework.util.CollectionUtils.isEmpty(objects)) {
            kingDeeTransferService.saveOrUpdateBatch(objects);
        }

        return allOutInSyncOrder(orgId,orgNumber,startTime,endTime);
    }


    public List<KingDeeTransferItem> allOutInSyncOrder(String orgId, String orgNumber, String startTime, String endTime) throws Exception {
        // 调用入库单接口
        RequestApiBean request = k3Logic.getInstance(orgId, orgNumber, KingDeeCons.STOCK_TRANSFER, startTime, endTime);
        String filterStr = "FDocumentStatus = 'C' "+ k3Logic.supplySql("FApproveDate", request.getStartTime(), request.getEndTime());
        request.setFieldKeys("FBillEntry_FEntryID,FID,FBillNo,FMaterialId,FMaterialId.FNumber,FMaterialName,FSrcStockId,FDestStockId,FQty,FOwnerId,FOwnerOutId," +
                "FModel,FBaseUnitId.FName,FConsignAmount,FConsignPrice,FSrcStockLocId,FDestStockLocId,FAuxPropId,FSrcStockId.FName,FDestStockId.FName,FNoteEntry");
        request.setFilterString(String.format(filterStr, orgNumber));
        request.setOrderString("FID ASC");

        String[] fields = new String[]{"id","fId","billNo","materialId","materialNumber","materialName","srcStockId","destStockId","qty","ownerId","ownerOutId",
                "model","baseUnitId","consignAmount","consignPrice","srcStockLocId","destStockLocId","auxPropId","srcStockName","destStockName","noteEntry"};
        List<KingDeeTransferItem> objects = k3Logic.allSync(request, fields, KingDeeTransferItem.class);
/*        if (CollectionUtil.isNotEmpty(objects)) {
            kingDeePurchaseStockInItemService.saveOrUpdateBatch(objects);
        }*/
        return objects;
    }


    public IPage<StockBeanToDay> listStockToDayV2(ZfireParamBean zfireParamBean) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        zfireParamBean = FieldUtils.supplyParam(zfireParamBean);
        IPage<StockBeanToDay> stockBeanToDayIPage = stockCommonMapper.listStockToDayV2(new Page(zfireParamBean.getPageNum(), zfireParamBean.getPageSize()), zfireParamBean, adminUser.getAdminUserId());
        List<String> collect = stockBeanToDayIPage.getRecords().stream().map(StockBeanToDay::getCorrespondId).collect(Collectors.toList());

        List<StockBean> num = stockCommonMapper.countAllList(null);
        List<StockBean> reservedNum = stockCommonMapper.countReservedList(collect);
        for (StockBeanToDay record : stockBeanToDayIPage.getRecords()) {
            //开单未提数量
            //开单未提数量
            List<StockBean> collectNum = num.stream()
                    .filter(item -> (item.getMaterialId().equals(record.getMaterialId()) && StringUtils.isNotEmpty(record.getCorrespondId()) &&  item.getCorrespondId().equals(record.getCorrespondId())))
                    .collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(collectNum))
                record.setNum(collectNum.stream().mapToInt(StockBean::getNum).sum());
            else
                record.setNum(0);
            record.setStockAdequate(record.getBalanceNumber() - record.getNum());

            //经销商预留库存
            List<StockBean> collectReservedNum = reservedNum.stream()
                    .filter(item -> (item.getMaterialId().equals(record.getMaterialId()) && StringUtils.isEmpty(record.getCorrespondId())) ||
                            (item.getMaterialId().equals(record.getMaterialId()) && StringUtils.isNotEmpty(record.getCorrespondId()) &&  record.getCorrespondId().contains(item.getCorrespondId())))
                    .collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(collectReservedNum))
                record.setReservedNum(collectReservedNum.stream().mapToInt(StockBean::getReservedNum).sum());
            else
                record.setReservedNum(0);
        }
        return stockBeanToDayIPage;
    }

    public IPage<StockBeanCustomerToDay> listStockToDayCustomerV2(ZfireParamBean zfireParamBean) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        zfireParamBean = FieldUtils.supplyParam(zfireParamBean);

        List<AdminUserCategoryRela> listCategory = adminUserCategoryRelaService.lambdaQuery().eq(AdminUserCategoryRela::getAdminUserId, adminUser.getAdminUserId()).list();
        List<String> categoryList = listCategory.stream().map(AdminUserCategoryRela::getK3CategoryId).collect(Collectors.toList());

        IPage<StockBeanCustomerToDay> stockBeanToDayIPage = stockCommonMapper.listStockToDayCustomerV2(new Page(zfireParamBean.getPageNum(), zfireParamBean.getPageSize()), zfireParamBean,
                adminUser.getAdminUserId(),categoryList);

        List<String> correspondId = stockBeanToDayIPage.getRecords().stream().filter(item -> !StringUtils.isEmpty(item.getCorrespondId())).map(item -> item.getCorrespondId())
                .collect(Collectors.toList()).stream().distinct().collect(Collectors.toList());

        List<StockBean> integer = stockCommonMapper.sumKingDeeNumberList(correspondId);
        List<StockBean> adequate = stockCommonMapper.sumKingDeeNumberAdequateList(correspondId);
        List<StockBean> temporay = stockCommonMapper.selectInvoiceCountList(correspondId);
        List<StockBean> num = stockCommonMapper.countAllList(correspondId);
        List<StockBean> reservedNum = stockCommonMapper.countReservedList(correspondId);
        for (StockBeanCustomerToDay record : stockBeanToDayIPage.getRecords()) {
            //可用数量
            List<StockBean> collectAdequate = adequate.stream()
                    .filter(item -> (item.getMaterialId().equals(record.getMaterialId()) && StringUtils.isNotEmpty(record.getCorrespondId()) &&  item.getCorrespondId().equals(record.getCorrespondId())) )
                    .collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(collectAdequate))
                record.setStockAdequate(collectAdequate.stream().mapToInt(StockBean::getStockAdequate).sum());
            else
                record.setStockAdequate(0);
            //总库存数量
            List<StockBean> collect = integer.stream()
                    .filter(item -> (item.getMaterialId().equals(record.getMaterialId()) && StringUtils.isNotEmpty(record.getCorrespondId()) &&  item.getCorrespondId().equals(record.getCorrespondId())) )
                    .collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(collect))
                record.setStockQty(collect.stream().mapToInt(StockBean::getStockQty).sum());
            else
                record.setStockQty(0);

            //经销商暂扣库存
            List<StockBean> collectTemporay = temporay.stream()
                    .filter(item -> (item.getMaterialId().equals(record.getMaterialId()) && StringUtils.isNotEmpty(record.getCorrespondId()) &&  item.getCorrespondId().equals(record.getCorrespondId())))
                    .collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(collectTemporay))
                record.setTemporaryNum(collectTemporay.stream().mapToInt(StockBean::getTemporaryNum).sum());
            else
                record.setTemporaryNum(0);
            //开单未提数量
            List<StockBean> collectNum = num.stream()
                    .filter(item -> (item.getMaterialId().equals(record.getMaterialId()) && StringUtils.isNotEmpty(record.getCorrespondId()) &&  item.getCorrespondId().equals(record.getCorrespondId())))
                    .collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(collectNum))
                record.setNum(collectNum.stream().mapToInt(StockBean::getNum).sum());
            else
                record.setNum(0);
            //经销商预留库存
            List<StockBean> collectReservedNum = reservedNum.stream()
                    .filter(item -> (item.getMaterialId().equals(record.getMaterialId()) && StringUtils.isNotEmpty(record.getCorrespondId()) &&  item.getCorrespondId().equals(record.getCorrespondId())))
                    .collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(collectReservedNum))
                record.setReservedNum(collectReservedNum.stream().mapToInt(StockBean::getReservedNum).sum());
            else
                record.setReservedNum(0);
            //可开数量
            record.setOpenNumber(record.getStockAdequate() - record.getNum() - record.getTemporaryNum() - record.getReservedNum());
        }

        return stockBeanToDayIPage;
    }

    public IPage<StockVO> listV2(ZfireParamBean zfireParamBean) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        zfireParamBean = FieldUtils.supplyParam(zfireParamBean);
        IPage<StockVO> list = stockCommonMapper.listV2(new Page(zfireParamBean.getPageNum(), zfireParamBean.getPageSize()), zfireParamBean);
        if (CollectionUtils.isEmpty(list.getRecords()))
            return list;

        List<StockVO> records = list.getRecords();

        List<Object> correspondIds = zfireParamBean.getParams().stream().filter(item -> item.getParam().equals("scp.correspond_id")).map(item -> item.getValue())
                .collect(Collectors.toList()).stream().distinct().collect(Collectors.toList());

        List<String> correspondId = new ArrayList<>();
        if (!CollectionUtils.isEmpty(correspondIds)){

            String[] split = Convert.toStr(correspondIds.get(0)).replaceAll("\\[","").replaceAll("]","").split(",");
            for (String s : split) {
                String trim = s.trim();
                correspondId.add(trim);
            }
        }


        List<StockBean> integer = stockCommonMapper.sumKingDeeNumberList(correspondId);
        List<StockBean> adequate = stockCommonMapper.sumKingDeeNumberAdequateList(correspondId);
        List<StockBean> temporay = stockCommonMapper.selectInvoiceCountList(correspondId);
        List<StockBean> num = stockCommonMapper.countAllList(correspondId);
        List<StockBean> reservedNum = stockCommonMapper.countReservedList(correspondId);
        for (StockVO record : records) {
            //可用数量
            List<StockBean> collectAdequate = adequate.stream()
                    .filter(item -> (item.getMaterialId().equals(record.getMaterialId()) && CollectionUtils.isEmpty(correspondId)) ||
                            (item.getMaterialId().equals(record.getMaterialId()) && CollectionUtils.isNotEmpty(correspondId) &&  correspondId.contains(item.getCorrespondId())) )
                    .collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(collectAdequate))
                record.setStockAdequate(collectAdequate.stream().mapToInt(StockBean::getStockAdequate).sum());
            else
                record.setStockAdequate(0);
            //总库存数量
            List<StockBean> collect = integer.stream()
                    .filter(item -> (item.getMaterialId().equals(record.getMaterialId()) && CollectionUtils.isEmpty(correspondId)) ||
                            (item.getMaterialId().equals(record.getMaterialId()) && CollectionUtils.isNotEmpty(correspondId) &&  correspondId.contains(item.getCorrespondId())) )
                    .collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(collect))
                record.setStockQty(collect.stream().mapToInt(StockBean::getStockQty).sum());
            else
                record.setStockQty(0);

            //经销商暂扣库存
            List<StockBean> collectTemporay = temporay.stream()
                    .filter(item -> (item.getMaterialId().equals(record.getMaterialId()) && CollectionUtils.isEmpty(correspondId)) ||
                            (item.getMaterialId().equals(record.getMaterialId()) && CollectionUtils.isNotEmpty(correspondId) &&  correspondId.contains(item.getCorrespondId())))
                    .collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(collectTemporay))
                record.setTemporaryNum(collectTemporay.stream().mapToInt(StockBean::getTemporaryNum).sum());
            else
                record.setTemporaryNum(0);
            //开单未提数量
            List<StockBean> collectNum = num.stream()
                    .filter(item -> (item.getMaterialId().equals(record.getMaterialId()) && CollectionUtils.isEmpty(correspondId)) ||
                            (item.getMaterialId().equals(record.getMaterialId()) && CollectionUtils.isNotEmpty(correspondId) &&  correspondId.contains(item.getCorrespondId())))
                    .collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(collectNum))
                record.setNum(collectNum.stream().mapToInt(StockBean::getNum).sum());
            else
                record.setNum(0);
            //经销商预留库存
            List<StockBean> collectReservedNum = reservedNum.stream()
                    .filter(item -> (item.getMaterialId().equals(record.getMaterialId()) && CollectionUtils.isEmpty(correspondId)) ||
                            (item.getMaterialId().equals(record.getMaterialId()) && CollectionUtils.isNotEmpty(correspondId) &&  correspondId.contains(item.getCorrespondId())))
                    .collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(collectReservedNum))
                record.setReservedNum(collectReservedNum.stream().mapToInt(StockBean::getReservedNum).sum());
            else
                record.setReservedNum(0);
            //可开数量
            record.setOpenNumber(record.getStockAdequate() - record.getNum() - record.getTemporaryNum() - record.getReservedNum());


        }
        list.setRecords(records);
        return list;
    }

    public IPage<StockCustomerReserved> listCustomerV2(ZfireParamBean zfireParamBean) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        String customerId = adminUser.getIsCustomer() ? adminUser.getCustomerId() : "";
        zfireParamBean = FieldUtils.supplyParam(zfireParamBean);
        IPage<StockCustomerReserved> stockBeanToDayIPage = stockCommonMapper.listCustomerV2(new Page(zfireParamBean.getPageNum(),
                zfireParamBean.getPageSize()), zfireParamBean,customerId);
        return stockBeanToDayIPage;
    }

    public List<StockPrice> allPrice(List<String> correspondId) {

        List<StockPrice> stockPrices = new ArrayList<>();

        List<String> collect = stockCorrespondPositionService.lambdaQuery()
                .in(!CollectionUtils.isEmpty(correspondId),StockCorrespondPosition::getCorrespondId, correspondId)
                .select(StockCorrespondPosition::getStockId).list()
                .stream().map(StockCorrespondPosition::getStockId).collect(Collectors.toList());

        List<KingDeeCategory> kingDeeCategories = kingDeeCategoryService.lambdaQuery().list();

        List<MaterialReferPrice> materialReferPrices = materialReferPriceService.lambdaQuery().list();

        List<String> numbers = materialReferPrices.stream().map(MaterialReferPrice::getMaterialNumber).collect(Collectors.toList());

        List<KingDeeMaterial> kingDeeMaterials = !CollectionUtils.isEmpty(numbers)?kingDeeMaterialService.lambdaQuery().list():new ArrayList<>();

        List<String> mIds = kingDeeMaterials.stream().map(KingDeeMaterial::getId).collect(Collectors.toList());
        List<Stock> stocks = !CollectionUtils.isEmpty(kingDeeMaterials)?stockService.lambdaQuery().in(!CollectionUtils.isEmpty(mIds),Stock::getMaterialId,mIds)
                .in(!CollectionUtils.isEmpty(correspondId),Stock::getStockId,collect)
                .list():new ArrayList<>();


        //开单未提数量
        List<StockBean> num = stockCommonMapper.countAllList(null);

        for (KingDeeCategory kingDeeCategory : kingDeeCategories) {
            List<KingDeeMaterial> kingDeeMaterialList = kingDeeMaterials.stream().filter(item ->
                    item.getCategoryNumber().equals(kingDeeCategory.getNumber()))
                    .collect(Collectors.toList());

            StockPrice stockPrice = new StockPrice();
            if (CollectionUtils.isEmpty(kingDeeMaterialList)){
                stockPrice.setAllPrice(Convert.toBigDecimal("0"));
                stockPrice.setCategoryName(kingDeeCategory.getName());
                stockPrice.setQty(Convert.toBigDecimal("0"));
                stockPrices.add(stockPrice);
                continue;
            }

            List<String> ids = kingDeeMaterialList.stream().map(KingDeeMaterial::getId).collect(Collectors.toList());

            List<Stock> stockList = stocks.stream().filter(item -> ids.contains(item.getMaterialId())).collect(Collectors.toList());

            BigDecimal price = new BigDecimal("0");
            BigDecimal qty = new BigDecimal("0");
            for (Stock stock : stockList) {
                List<KingDeeMaterial> kingDeeMaterialsUp = kingDeeMaterialList.stream().filter(item -> item.getId().equals(stock.getMaterialId()))
                        .collect(Collectors.toList());
                KingDeeMaterial kingDeeMaterial = kingDeeMaterialsUp.get(0);

                List<MaterialReferPrice> materialReferPriceList = materialReferPrices.stream()
                        .filter(item -> item.getMaterialNumber().equals(kingDeeMaterial.getNumber()))
                        .collect(Collectors.toList());

                if (!CollectionUtils.isEmpty(materialReferPriceList)) {
                    MaterialReferPrice materialReferPrice = materialReferPriceList.get(0);

                    price = price.add(stock.getStockQty().multiply(materialReferPrice.getCostPrice()));
                }

                qty = qty.add(stock.getStockQty());
            }


            List<StockBean> collectNum = num.stream()
                    .filter(item ->  ids.contains(item.getMaterialId()))
                    .collect(Collectors.toList());

            for (StockBean stockBean : collectNum) {

                if (!CollectionUtils.isEmpty(correspondId)) {
                    if (!correspondId.contains(stockBean.getCorrespondId())) {
                        continue;
                    }
                }

                List<KingDeeMaterial> kingDeeMaterialsUp = kingDeeMaterialList.stream().filter(item -> item.getId().equals(stockBean.getMaterialId()))
                        .collect(Collectors.toList());
                KingDeeMaterial kingDeeMaterial = kingDeeMaterialsUp.get(0);

                List<MaterialReferPrice> materialReferPriceList = materialReferPrices.stream()
                        .filter(item -> item.getMaterialNumber().equals(kingDeeMaterial.getNumber()))
                        .collect(Collectors.toList());

                if (!CollectionUtils.isEmpty(materialReferPriceList)) {
                    MaterialReferPrice materialReferPrice = materialReferPriceList.get(0);

                    price = price.subtract(Convert.toBigDecimal(stockBean.getNum()).multiply(materialReferPrice.getCostPrice()));
                }



                qty = qty.subtract(Convert.toBigDecimal(stockBean.getNum()));
            }

            stockPrice.setAllPrice(price);
            stockPrice.setCategoryName(kingDeeCategory.getName());
            stockPrice.setQty(qty);
            stockPrices.add(stockPrice);
        }


        return stockPrices;
    }

    public IPage<StockBeanToCostPrice> listStockToCostPriceV2(ZfireParamBean zfireParamBean) {
        AdminUserCom adminUser = commonLogic.getAdminUser();
        zfireParamBean = FieldUtils.supplyParam(zfireParamBean);
        IPage<StockBeanToCostPrice> stockBeanToDayIPage = stockCommonMapper.listStockToCostPriceV2(new Page(zfireParamBean.getPageNum(), zfireParamBean.getPageSize()), zfireParamBean, adminUser.getAdminUserId());
        List<String> collect = stockBeanToDayIPage.getRecords().stream().map(StockBeanToCostPrice::getCorrespondId).collect(Collectors.toList());

        List<StockBean> num = stockCommonMapper.countAllList(null);
        List<StockBean> reservedNum = stockCommonMapper.countReservedList(collect);
        for (StockBeanToCostPrice record : stockBeanToDayIPage.getRecords()) {
            //开单未提数量
            //开单未提数量
            List<StockBean> collectNum = num.stream()
                    .filter(item -> (item.getMaterialId().equals(record.getMaterialId()) && StringUtils.isNotEmpty(record.getCorrespondId()) &&  item.getCorrespondId().equals(record.getCorrespondId())))
                    .collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(collectNum))
                record.setNum(collectNum.stream().mapToInt(StockBean::getNum).sum());
            else
                record.setNum(0);
            record.setStockAdequate(record.getBalanceNumber() - record.getNum());

            //经销商预留库存
            List<StockBean> collectReservedNum = reservedNum.stream()
                    .filter(item -> (item.getMaterialId().equals(record.getMaterialId()) && StringUtils.isEmpty(record.getCorrespondId())) ||
                            (item.getMaterialId().equals(record.getMaterialId()) && StringUtils.isNotEmpty(record.getCorrespondId()) &&  record.getCorrespondId().contains(item.getCorrespondId())))
                    .collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(collectReservedNum))
                record.setReservedNum(collectReservedNum.stream().mapToInt(StockBean::getReservedNum).sum());
            else
                record.setReservedNum(0);

            record.setCostPriceAll(record.getCostPrice().multiply(Convert.toBigDecimal(record.getStockAdequate())));
        }
        return stockBeanToDayIPage;
    }
}
