package com.junmp.jyzb.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.junmp.jyzb.api.bean.dto.PeriodAndDateDto;
import com.junmp.jyzb.api.bean.dto.*;
import com.junmp.jyzb.api.bean.dto.fetchingDataDto.EquipmentDto;
import com.junmp.jyzb.api.bean.query.*;
import com.junmp.jyzb.api.bean.req.BatchEditingInvsReq;
import com.junmp.jyzb.api.bean.req.UpdateEqsBoxReq;
import com.junmp.jyzb.api.bean.vo.InventoryVo;
import com.junmp.jyzb.api.exception.JYZBAppException;
import com.junmp.jyzb.api.exception.enums.*;
import com.junmp.jyzb.entity.*;

import com.junmp.jyzb.mapper.*;
import com.junmp.jyzb.service.*;
import com.junmp.jyzb.utils.DateTimeUtil;
import com.junmp.v2.auth.api.bean.login.LoginUser;
import com.junmp.v2.auth.api.context.LoginContext;
import com.junmp.v2.common.exception.base.ServiceException;
import com.junmp.v2.common.util.BeanPlusUtil;
import com.junmp.v2.common.util.HttpServletUtil;
import com.junmp.v2.db.api.factory.PageFactory;
import com.junmp.v2.db.api.factory.PageResultFactory;
import com.junmp.v2.db.api.page.PageResult;
import com.junmp.v2.dict.entity.SysDictItem;
import com.junmp.v2.dict.service.SysDictItemService;
import com.junmp.v2.office.api.OfficeExcelApi;
import com.junmp.v2.office.api.bean.ExcelExportParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;

import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;


@Service
@Slf4j
public class InventoryServiceImpl extends ServiceImpl<InventoryMapper, Inventory> implements InventoryService {
    @Resource
    private InventoryMapper inventoryMapper;
    @Resource
    private EquipmentTypeService equipmentTypeService;
    @Resource
    private EquipmentSizeService equipmentSizeService;
    @Resource
    private WarehouseService warehouseService;
    @Resource
    private PubOrgService PubOrgService;

    @Resource
    private CabinetBoxService cabinetBoxService;

    @Resource
    private PubOrgService pubOrgService;

    @Resource
    private CabinetService cabinetService;

    @Resource
    private SupplierService supplierService;
    @Resource
    private ShelfService shelfService;
    @Resource
    private WarehouseAreaService warehouseAreaService;


    @Resource
    private OfficeExcelApi officeExcelApi;


    @Resource
    private InventorySummaryService inventorySummaryService;

    @Resource
    private SysDictItemService sysDictItemService;

    @Resource
    private InventorySummaryMapper inventorySummaryMapper;

    @Resource
    private WarehouseInventoryService warehouseInventoryService;
    @Resource
    private WarehouseInventoryMapper warehouseInventoryMapper;

    @Resource
    private PoliceEquipmentService policeEquipmentService;
    @Resource
    private PoliceEquipmentDetailService policeEquipmentDetailService;

//    @Resource
//    private CabinetBoxEquipmentService cabinetBoxEquipmentService;

    @Resource
    private LogDetailService logDetailService;

    @Resource
    private OrderMainService orderMainService;

    @Resource
    private LogSummaryService logSummaryService;


    //根据装备id查询出装备的详细信息
    @Override
    public InventoryDto getInventoryDetail(InventoryReq req) {
        Inventory inventory = InventoryExist(req.getId());
        InventoryDto bean = BeanUtil.toBean(inventory, InventoryDto.class);
        // 查询与库存表关联的其他数据
        String orgName = PubOrgService.getById(inventory.getOrgId()).getOrgName();
        String TypeName = equipmentTypeService.getById(inventory.getTypeId()).getName();
        String SizeName = equipmentSizeService.getById(inventory.getSizeId()).getName();
        // 创建并填充对象
        bean.setSizeName(SizeName);
        bean.setTypeName(TypeName);
        bean.setOrgName(orgName);
        return bean;
    }


    //设置仓库库存数量（总数，在库数，出库数，价格）
    @Override
    public boolean UpdateWarehouseInsNum(WarehouseReq req) {
        Warehouse warehouse = warehouseService.WarehoustExist(req.getId());
        boolean b = warehouseService.SetInventoryInfo(warehouse.getId());
        return b;
    }

    //设置单警柜库存数量（总数，在库数，出库数，价格）
    @Override
    public boolean UpdateCabinetInsNum(CabinetReq req) {
        Cabinet cabinet = cabinetService.CabinetExist(req.getId());
        boolean b = cabinetService.SetInventoryInfo(cabinet.getId());
        return b;
    }


    //根据Epc查询装备信息
    @Override
    public List<InventoryDto> GetInvInfoByEpc(List<String> epcList) {
        //判断传入的是否为空
        if (epcList.size() == 0) {
            throw new ServiceException(CabinetExceptionEnum.PARAMETER_ERROR);
        }

        return inventoryMapper.GetInvInfoByEpc(epcList);
    }


    //查询箱门（cabinetBox下）所有装备简要信息列表（传递cabinetBoxId）
    @Override
    public List<EqsBriefDto> searchEqsByBoxId(CabinetBoxReq req) {
        List<Inventory> list = list(new LambdaQueryWrapper<Inventory>()
                .eq(Inventory::getLocationId, req.getId())
                .orderByDesc(Inventory::getTypeId)
                .orderByDesc(Inventory::getSizeId));
        if (list.size() == 0) {
            throw new ServiceException(CabinetBoxExceptionEnum.CABINETBOX_ISNOT_EXISTS);
        }
        List<EqsBriefDto> eqsBriefDtoList = new ArrayList<>();
        Iterator<Inventory> iterator = list.iterator();
        while (iterator.hasNext()) {
            Inventory next = iterator.next();
            EqsBriefDto eqsBriefDto = new EqsBriefDto();
            BeanPlusUtil.copyProperties(next, eqsBriefDto);
            Map<String, String> map = setNames(eqsBriefDto.getTypeId(), eqsBriefDto.getSizeId(), eqsBriefDto.getSupplierId());
            //设置typeName
            eqsBriefDto.setTypeName(map.get("typeName"));
            //设置sizeName
            eqsBriefDto.setSizeName(map.get("sizeName"));
            //如果有供应商id的前提下，设置supplierName
            if (ObjectUtil.isNotNull(eqsBriefDto.getSupplierId())) {
                eqsBriefDto.setSupplierName(map.get("supplierName"));
            }
            eqsBriefDtoList.add(eqsBriefDto);
        }
        return eqsBriefDtoList;
    }

    //查询箱门（cabinetBox下）所有装备简要信息列表page（传递cabinetBoxId）
    @Override
    public PageResult<EqsBriefDto> searchEqsByBoxIdPage(CabinetBoxReq req) {
//        List<EqsBriefDto> eqsBriefDtoList = searchEqsByBoxId(req);
        LambdaQueryWrapper<Inventory> eq = new LambdaQueryWrapper<Inventory>()
                .eq(Inventory::getLocationId, req.getId())
                .orderByDesc(Inventory::getTypeId)
                .orderByDesc(Inventory::getSizeId);
        List<Inventory> list = list(eq);
        long size = list.size();
        Page<Inventory> page = page(PageFactory.getDefaultPage(req.getPageNo(), req.getPageSize()), eq);
        List<Inventory> records = page.getRecords();
        List<EqsBriefDto> eqsBriefDtoList = records.parallelStream()
                .map(inventory -> {
                    EqsBriefDto eqsBriefDto = new EqsBriefDto();
                    BeanPlusUtil.copyProperties(inventory, eqsBriefDto);
                    Map<String, String> map = setNames(eqsBriefDto.getTypeId(), eqsBriefDto.getSizeId(), eqsBriefDto.getSupplierId());
                    //设置typeName
                    eqsBriefDto.setTypeName(map.get("typeName"));
                    //设置sizeName
                    eqsBriefDto.setSizeName(map.get("sizeName"));
                    //如果有供应商id的前提下，设置supplierName
                    if (ObjectUtil.isNotNull(eqsBriefDto.getSupplierId())) {
                        eqsBriefDto.setSupplierName(map.get("supplierName"));
                    }
                    return eqsBriefDto;
                }).collect(Collectors.toList());
        Page<EqsBriefDto> page1 = PageFactory.getDefaultPage(req.getPageNo(), req.getPageSize());
        page1.setRecords(eqsBriefDtoList);
        page1.setTotal(size);
        return PageResultFactory.createPageResult(page1);
    }


    public PageResult<InventoryDto> GetDetailByTerms(InventoryReq req) {
//        //根据条件查询仓库下的所有装备
        int size = inventorySummaryMapper.selectSumByItemsCount(req);

        Page<InventoryDto> page1 = PageFactory.getDefaultPage(req.getPageNo(), req.getPageSize());
        Long a = (req.getPageNo() - 1) * req.getPageSize();
        req.setPageNo((req.getPageNo() - 1) * req.getPageSize());

        List<InventoryDto> returnList = inventorySummaryMapper.GetDetailByTerms(req);
        page1.setRecords(returnList);
        page1.setTotal(size);
        return PageResultFactory.createPageResult(page1);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean BatchEditingInvsInfo(BatchEditingInvsReq req) {
        List<Inventory> collect = new ArrayList<>();
        //查询inventory表中数据，对响应数据进行修改
        //判断是对整一类的装备进行修改还是说对个别几个装备进行批量修改
//        if (req.getInventoryIdList().size()!=0){
        List<InventorySummary> delList = new ArrayList<>();
        PubOrg pubOrg = pubOrgService.PubOrgExist(req.getOrgId());
        List<Object[]> searchItem = new ArrayList<>();
        //（判断出库几条，入库几条）
        List<InventorySummary> addSumList = new ArrayList<>();
        Map<String, InventoryReq> map = new HashMap<>();
        List<String> epcList = req.getInventoryList().stream().map(InventoryReq::getEpc).collect(Collectors.toList());
        List<Inventory> list = inventoryMapper.selectInventoryByEpcList(epcList, pubOrg.getOrgId().toString());
        if (req.getPrice().compareTo(req.getOriginalPrice()) != 0) {
            //需要去重之后查询
            for (Inventory inventory : list) {
                InventoryReq inv = new InventoryReq();
                BeanPlusUtil.copyProperties(inventory,inv);
                boolean flag = false;
                if (ObjectUtil.isNotNull(inv.getProductionDate()) && req.getWarrantyPeriod() != inv.getWarrantyPeriod() && req.getWarrantyPeriod() != 0) {

                    Date productionDate = DateTimeUtil.TimeStringToDate(inventory.getProductionDate().toString(),"yyyy-MM-dd HH:mm:ss");
                    int warrantyMonths = req.getWarrantyPeriod();
                    // 创建 Calendar 对象，用于进行日期计算
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTime(productionDate);
                    // 将质保期加到生产日期上
                    calendar.add(Calendar.MONTH, warrantyMonths);
                    Date time = calendar.getTime();
                    if (time.compareTo(DateTimeUtil.getCurrentDateTime()) <= 0) {
                        flag = true;
                    }
                }


                String key = inv.getLocationId() + inv.getTypeId() + inv.getSizeId() + req.getPrice() + inv.getProperty();
                String key2 = inv.getLocationId() + inv.getTypeId() + inv.getSizeId() + req.getOriginalPrice() + inv.getProperty();
                if (map.containsKey(key)) {
                    InventoryReq inventoryReq = map.get(key);
                    inventoryReq.setStockNum(inv.getLocationState().equals("in") ? inventoryReq.getStockNum() + 1 : inventoryReq.getStockNum());
                    inventoryReq.setStockExpireNum(inv.getLocationState().equals("in") ? inventoryReq.getStockExpireNum() + 1 : inventoryReq.getStockExpireNum());
                    inventoryReq.setOutboundExpireNum(inv.getLocationState().equals("out") ? inventoryReq.getOutboundExpireNum() + 1 : inventoryReq.getOutboundExpireNum());
                    inventoryReq.setOutBoundNum(inv.getLocationState().equals("out") ? inventoryReq.getOutBoundNum() + 1 : inventoryReq.getOutBoundNum());
                    map.put(key, inventoryReq);
                } else {
                    InventoryReq inventoryReq = new InventoryReq();
                    BeanPlusUtil.copyProperties(inv, inventoryReq);
                    inventoryReq.setStockNum(ObjectUtil.isNull(inv.getStockNum()) ?
                            (inv.getLocationState().equals("in") ? 1 : 0)
                            : (inv.getLocationState().equals("in") ? inv.getStockNum() + 1 : inv.getStockNum()));
                    inventoryReq.setStockExpireNum(ObjectUtil.isNull(inv.getStockExpireNum()) ?
                            (inv.getLocationState().equals("in") && flag ? 1 : 0)//将质保日期和生产日期进行计算，如果过质保则直接加1，否则为0
                            : (inv.getLocationState().equals("in") && flag ? inv.getStockExpireNum() + 1 : inv.getStockExpireNum()));
                    inventoryReq.setOutboundExpireNum(ObjectUtil.isNull(inv.getOutboundExpireNum()) ?
                            (inv.getLocationState().equals("out") && flag ? 1 : 0)
                            : (inv.getLocationState().equals("out") && flag ? inv.getOutboundExpireNum() + 1 : inv.getOutboundExpireNum()));
                    inventoryReq.setOutBoundNum(ObjectUtil.isNull(inv.getOutBoundNum()) ?
                            (inv.getLocationState().equals("out") ? 1 : 0)
                            : (inv.getLocationState().equals("out") ? inv.getOutBoundNum() + 1 : inv.getOutBoundNum()));
                    inventoryReq.setPrice(req.getPrice());
                    map.put(key, inventoryReq);
                }
                if (map.containsKey(key2)) {
                    InventoryReq inventoryReq = map.get(key2);
                    inventoryReq.setStockNum(inv.getLocationState().equals("in") ? inventoryReq.getStockNum() + 1 : inventoryReq.getStockNum());
                    inventoryReq.setOutBoundNum(inv.getLocationState().equals("out") ? inventoryReq.getOutBoundNum() + 1 : inventoryReq.getOutBoundNum());
                    inventoryReq.setStockExpireNum(inv.getLocationState().equals("in") ? inventoryReq.getStockExpireNum() + 1 : inventoryReq.getStockExpireNum());
                    inventoryReq.setOutboundExpireNum(inv.getLocationState().equals("out") ? inventoryReq.getOutboundExpireNum() + 1 : inventoryReq.getOutboundExpireNum());
                    map.put(key2, inventoryReq);
                } else {
                    InventoryReq inventoryReq = new InventoryReq();
                    BeanPlusUtil.copyProperties(inv, inventoryReq);
                    inventoryReq.setStockNum(ObjectUtil.isNull(inv.getStockNum()) ?
                            (inv.getLocationState().equals("in") ? 1 : 0)
                            : (inv.getLocationState().equals("in") ? inv.getStockNum() + 1 : inv.getStockNum()));
                    inventoryReq.setStockExpireNum(ObjectUtil.isNull(inv.getStockExpireNum()) ?
                            (inv.getLocationState().equals("in") && flag ? 1 : 0)//将质保日期和生产日期进行计算，如果过质保则直接加1，否则为0
                            : (inv.getLocationState().equals("in") && flag ? inv.getStockExpireNum() + 1 : inv.getStockExpireNum()));
                    inventoryReq.setOutboundExpireNum(ObjectUtil.isNull(inv.getOutboundExpireNum()) ?
                            (inv.getLocationState().equals("out") && flag ? 1 : 0)
                            : (inv.getLocationState().equals("out") && flag ? inv.getOutboundExpireNum() + 1 : inv.getOutboundExpireNum()));
                    inventoryReq.setOutBoundNum(ObjectUtil.isNull(inv.getOutBoundNum()) ?
                            (inv.getLocationState().equals("out") ? 1 : 0)
                            : (inv.getLocationState().equals("out") ? inv.getOutBoundNum() + 1 : inv.getOutBoundNum()));
                    inventoryReq.setPrice(req.getOriginalPrice());
                    map.put(key2, inventoryReq);
                }

            }
            for (String key : map.keySet()) {
                InventoryReq inv = map.get(key);
                Object[] item = new Object[]{req.getOrgId(), inv.getLocationId(), inv.getTypeId(), inv.getSizeId(), inv.getPrice(), inv.getProperty()};
                searchItem.add(item);

            }
            List<InventorySummary> inventorySummaryList = inventorySummaryMapper.selectSum(searchItem);
            for (String key : map.keySet()) {
                boolean flag = false;
                InventoryReq inv = map.get(key);
                for (InventorySummary is : inventorySummaryList) {
                    if (is.getUnitPrice().toString().equalsIgnoreCase(inv.getPrice().toString()) &&
                            req.getOriginalPrice().toString().equalsIgnoreCase(inv.getPrice().toString()) &&
                            inv.getLocationId().equals(is.getLocationId())) {

                        is.setStockNumber(is.getStockNumber() - inv.getStockNum());
                        is.setOutboundNumber(is.getOutboundNumber() - inv.getOutBoundNum());
                        is.setNumber(is.getNumber() - inv.getStockNum() - inv.getOutBoundNum());
                        is.setPrice(is.getUnitPrice().multiply(BigDecimal.valueOf(is.getNumber())));
                        is.setExpireNumber(ObjectUtil.isNotNull(is.getExpireNumber()) ? is.getExpireNumber() - inv.getOutboundExpireNum() - inv.getStockExpireNum() : 0);
                        is.setExpireNumberPrice(is.getUnitPrice().multiply(BigDecimal.valueOf(is.getExpireNumber())));
                        if (is.getNumber() == 0 && is.getStockNumber() == 0 && is.getOutboundNumber() == 0
                                && is.getBrokenNumber()==0 && is.getDestructionNumber() == 0) {
                            delList.add(is);
                            inventorySummaryList.remove(is);
                        }
                        flag = true;
                        break;

                    }
                    if (is.getUnitPrice().toString().equalsIgnoreCase(inv.getPrice().toString()) &&
                            req.getPrice().toString().equalsIgnoreCase(inv.getPrice().toString()) &&
                            inv.getLocationId().equals(is.getLocationId())) {
                        is.setStockNumber(is.getStockNumber() + inv.getStockNum());
                        is.setOutboundNumber(is.getOutboundNumber() + inv.getOutBoundNum());
                        is.setNumber(is.getNumber() + inv.getStockNum() + inv.getOutBoundNum());
                        is.setPrice(is.getUnitPrice().multiply(BigDecimal.valueOf(is.getNumber())));
                        is.setExpireNumber(ObjectUtil.isNotNull(is.getExpireNumber()) ? is.getExpireNumber() + inv.getOutboundExpireNum() + inv.getStockExpireNum() : 0);
                        is.setExpireNumberPrice(is.getUnitPrice().multiply(BigDecimal.valueOf(is.getExpireNumber())));
                        flag = true;
                        break;
                    }

                }
                if (!flag) {
                    //新增一条数据
                    InventorySummary inventorySummary = inventorySummaryService.createInventorySummary(inv.getOrgId(),
                            pubOrg.getOrgName(),pubOrg.getOrgCode(),inv.getTypeId(),inv.getTypeName(),inv.getSizeId(),
                            inv.getSizeName(),inv.getLocationId(),inv.getLocationName(),inv.getStockNum(),
                            inv.getOutBoundNum(),inv.getPrice(),inv.getStockExpireNum()+inv.getOutboundExpireNum(),
                            0,0,0,0,
                            0,0,"0");
                    addSumList.add(inventorySummary);
                }

            }

            if (CollectionUtil.isNotEmpty(delList)) {
                inventorySummaryService.removeBatchByIds(delList);
            }
            if (CollectionUtil.isNotEmpty(addSumList)) {
                inventorySummaryService.saveBatch(addSumList);
            }
            if (CollectionUtil.isNotEmpty(inventorySummaryList)) {
                inventorySummaryService.updateBatchById(inventorySummaryList);
            }

            collect = list.stream().map(inventory1 -> {
                Inventory inventory = new Inventory();
                BeanPlusUtil.copyProperties(inventory1, inventory);
                inventory.setLocationState(null);
                inventory.setWarrantyPeriod(ObjectUtil.isNull(req.getWarrantyPeriod()) ? inventory1.getWarrantyPeriod() : req.getWarrantyPeriod());
                inventory.setMaintenancePeriod(ObjectUtil.isNull(req.getMaintenancePeriod()) ? inventory1.getMaintenancePeriod() : req.getMaintenancePeriod());
                inventory.setPrice(req.getPrice());
                return inventory;
            }).collect(Collectors.toList());

        } else {
            //批量修改个别装备
            collect = list.stream().map(inventory1 -> {
                Inventory inventory = new Inventory();
                BeanPlusUtil.copyProperties(inventory1, inventory);
                inventory.setLocationState(null);
                inventory.setWarrantyPeriod(ObjectUtil.isNull(req.getWarrantyPeriod()) ? inventory1.getWarrantyPeriod() : req.getWarrantyPeriod());
                inventory.setMaintenancePeriod(ObjectUtil.isNull(req.getMaintenancePeriod()) ? inventory1.getMaintenancePeriod() : req.getMaintenancePeriod());
                return inventory;
            }).collect(Collectors.toList());

        }

        updateBatchById(collect);

        //批量修改装备信息执行函数
        new Thread(()->{
            inventorySummaryService.setWarrantyGroupAction(pubOrg.getOrgId());
        }).start();
        return true;
    }



    //修改库存信息汇总
    @Transactional(rollbackFor = Exception.class)
    public boolean setInventorySummary(BatchEditingInvsReq req) {
        //查询字典表中的临近报废天数
        SysDictItem sysDictItem = sysDictItemService.getOne(new LambdaQueryWrapper<SysDictItem>()
                .eq(SysDictItem::getItemText, "nearBrokenNumber"));
        //如果配置找不到，那就默认设置为15天为临近报废（如果装备的质保期小于15天了，就是为临近报废）
        Integer nearBrokenNumberDays;
        if (ObjectUtil.isNotNull(sysDictItem)) {
            nearBrokenNumberDays = 15;
        } else {
            nearBrokenNumberDays = Integer.parseInt(sysDictItem.getItemValue());
        }
        //先将其删除再全部重新添加计算
        List<InventorySummary> list = inventorySummaryService.list(new LambdaQueryWrapper<InventorySummary>()
                .eq(ObjectUtil.isNotNull(req.getOrgId()), InventorySummary::getOrgId, req.getOrgId())
                .eq(ObjectUtil.isNotNull(req.getLocationId()), InventorySummary::getLocationId, req.getLocationId())
                .eq(ObjectUtil.isNotNull(req.getSizeId()), InventorySummary::getSizeId, req.getSizeId())
                .eq(ObjectUtil.isNotNull(req.getTypeId()), InventorySummary::getTypeId, req.getTypeId()));
        boolean b = inventorySummaryService.removeBatchByIds(list);
        boolean a = inventoryMapper.insertInventorySummary(req, nearBrokenNumberDays);
        return (a && b);
    }

    //根据货架id获取装备列表汇总信息(list)
    @Override
    public List<InventorySummary> ShelfInventoryList(ShelfReq req) {
        //判断货架是否存在
        Shelf shelf = shelfService.ShelfExist(req.getShelfId());
        warehouseService.WarehoustExist(shelf.getWarehouseId());
        //通过货架id获取装备列表汇总
        return inventoryMapper.getSumByShelf(req.getShelfId());
    }

    //根据货架id获取装备列表汇总信息(page)
    @Override
    public PageResult<InventorySummary> ShelfInventoryPage(ShelfReq req) {
        //判断货架是否存在
        Shelf shelf = shelfService.ShelfExist(req.getShelfId());
        warehouseService.WarehoustExist(shelf.getWarehouseId());
        Page<InventorySummary> page = PageFactory.getDefaultPage(req.getPageNo(), req.getPageSize());
        IPage<InventorySummary> pages = inventoryMapper.ShelfInventoryPage(page, req.getShelfId());
        page.setRecords(pages.getRecords());
        return PageResultFactory.createPageResult(page);
    }

    //通过货架id查询装备简要信息（list）
    @Override
    public List<EqsBriefDto> ShelfInventoryDetail(InventoryReq req) {
        //判断货架是否存在
        Shelf shelf = shelfService.ShelfExist(req.getShelfId());
        warehouseService.WarehoustExist(shelf.getWarehouseId());
        List<Inventory> list = list(new LambdaQueryWrapper<Inventory>()
                .eq(Inventory::getShelfId, req.getShelfId())
                .orderByDesc(Inventory::getTypeId)
                .orderByDesc(Inventory::getSizeId));
        List<EqsBriefDto> eqsBriefDtoList = list.parallelStream()
                .map(inventory -> {
                    EqsBriefDto eqsBriefDto = new EqsBriefDto();
                    BeanPlusUtil.copyProperties(inventory, eqsBriefDto);
                    Map<String, String> map = setNames(eqsBriefDto.getTypeId(), eqsBriefDto.getSizeId(), eqsBriefDto.getSupplierId());
                    //设置typeName
                    eqsBriefDto.setTypeName(map.get("typeName"));
                    //设置sizeName
                    eqsBriefDto.setSizeName(map.get("sizeName"));
                    //如果有供应商id的前提下，设置supplierName
                    if (ObjectUtil.isNotNull(eqsBriefDto.getSupplierId())) {
                        eqsBriefDto.setSupplierName(map.get("supplierName"));
                    }
                    return eqsBriefDto;
                }).collect(Collectors.toList());
        return eqsBriefDtoList;
    }

    //通过货架id查询装备简要信息（page）
    @Override
    public PageResult<EqsBriefDto> ShelfInventoryPage(InventoryReq req) {
        Shelf shelf = shelfService.ShelfExist(req.getShelfId());
        warehouseService.WarehoustExist(shelf.getWarehouseId());
        LambdaQueryWrapper<Inventory> eq = new LambdaQueryWrapper<Inventory>()
                .eq(Inventory::getShelfId, req.getShelfId())
                .orderByDesc(Inventory::getTypeId)
                .orderByDesc(Inventory::getSizeId);
        List<Inventory> list = list(eq);
        long size = list.size();
        Page<Inventory> page = page(PageFactory.getDefaultPage(req.getPageNo(), req.getPageSize()), eq);
        List<Inventory> records = page.getRecords();
        List<EqsBriefDto> eqsBriefDtoList = records.parallelStream()
                .map(inventory -> {
                    EqsBriefDto eqsBriefDto = new EqsBriefDto();
                    BeanPlusUtil.copyProperties(inventory, eqsBriefDto);
                    Map<String, String> map = setNames(eqsBriefDto.getTypeId(), eqsBriefDto.getSizeId(), eqsBriefDto.getSupplierId());
                    //设置typeName
                    eqsBriefDto.setTypeName(map.get("typeName"));
                    //设置sizeName
                    eqsBriefDto.setSizeName(map.get("sizeName"));
                    //如果有供应商id的前提下，设置supplierName
                    if (ObjectUtil.isNotNull(eqsBriefDto.getSupplierId())) {
                        eqsBriefDto.setSupplierName(map.get("supplierName"));
                    }
                    return eqsBriefDto;
                }).collect(Collectors.toList());
        Page<EqsBriefDto> page1 = PageFactory.getDefaultPage(req.getPageNo(), req.getPageSize());
        page1.setRecords(eqsBriefDtoList);
        page1.setTotal(size);
        return PageResultFactory.createPageResult(page1);
    }


    /**
     * 通过区域id查询装备汇总信息
     *
     * @param req
     * @return
     */
    @Override
    public List<InventorySummary> AreaInventoryList(WarehouseAreaReq req) {
        //判断区域是否存在
        WarehouseArea warehouseArea = warehouseAreaService.WarehouseAreaExist(req.getId());
        warehouseService.WarehoustExist(warehouseArea.getWarehouseId());
        //通过区域id获取装备列表汇总
        return inventoryMapper.getSumByArea(req.getId());
    }

    @Override
    public PageResult<InventorySummary> AreaInventoryPage(WarehouseAreaReq req) {
        //判断区域是否存在
        WarehouseArea warehouseArea = warehouseAreaService.WarehouseAreaExist(req.getId());
        warehouseService.WarehoustExist(warehouseArea.getWarehouseId());
        Page<InventorySummary> page = PageFactory.getDefaultPage(req.getPageNo(), req.getPageSize());
        IPage<InventorySummary> pages = inventoryMapper.AreaInventoryPage(page, req.getId());
        page.setRecords(pages.getRecords());
        return PageResultFactory.createPageResult(page);
    }


    //通过单警柜箱门id获取箱门下的装备汇总信息(list)
    @Override
    public List<InventorySummary> EqsByCabinetBoxId(CabinetBoxReq req) {
        cabinetBoxService.CabinetBoxExist(req.getId());
        return inventoryMapper.getSumByCabinetBox(req.getId());
    }

    //通过单警柜箱门id获取箱门下的装备汇总信息(page)
    @Override
    public PageResult<InventorySummary> EqsByCabinetBoxIdPage(CabinetBoxReq req) {
        cabinetBoxService.CabinetBoxExist(req.getId());
        Page<InventorySummary> page = new Page<>(req.getPageNo(), req.getPageSize());
        IPage<InventorySummary> pages = inventoryMapper.EqsByCabinetBoxIdPage(page, req.getId());
        page.setRecords(pages.getRecords());
        return PageResultFactory.createPageResult(page);
    }

    //通过组织机构id将该组织下的装备进行导出
    @Override
    public void ExportInventoryExcel(InventoryReq req) {
        //判断组织机构是否存在
        pubOrgService.PubOrgExist(req.getOrgId());
        //查询该组织机构下的所有装备信息
        List<InventoryVo> list = inventoryMapper.selectListByOrg(req.getOrgId());
        HttpServletResponse response = HttpServletUtil.getResponse();
        ExcelExportParam param = new ExcelExportParam();
        param.setDataList(list);
        param.setClazz(Inventory.class);
        param.setResponse(response);
        param.setFileName("装备列表.xls");
        //对数据进行导出
        officeExcelApi.easyExportDownload(param);
    }


    //查询装备数量报表
    @Override
    public List<EqsSumDto> GetListEquipment(InventoryReq req) {
        //通过获取传递的查询条件进行查询，得到最终的装备数量报表
        return inventoryMapper.GetListEquipment(req);
    }


    //通过id判断装备是否存在
    @Override
    public Inventory InventoryExist(String id) {
        Inventory invMap = this.getById(id);
        if (ObjectUtil.isNull(invMap)) {
            throw new ServiceException(InventoryExceptionEnum.INVENTORY_NOT_EXIST);
        }
        return invMap;
    }

    //通用方法，用于设置对象的typeName属性，sizeName属性和supplierName属性
    public Map<String, String> setNames(String typeId, String sizeId, String supplierId) {
        Map<String, String> map = new HashMap<>();
        EquipmentSize one = equipmentSizeService.getOne(new LambdaQueryWrapper<EquipmentSize>()
                .eq(EquipmentSize::getId, sizeId));
        String sizeName = one.getName();
        String photo = one.getPhoto();
        String typeName = equipmentTypeService.getOne(new LambdaQueryWrapper<EquipmentType>()
                .eq(EquipmentType::getId, typeId)).getName();
        //如果有供应商id的前提下，设置supplierName
        if (ObjectUtil.isNotNull(supplierId) && !supplierId.trim().isEmpty()) {
            String supplierName = supplierService.getOne(new LambdaQueryWrapper<Supplier>()
                    .eq(Supplier::getId, supplierId)).getName();
            map.put("supplierName", supplierName);
        }
        map.put("sizeName", sizeName);
        map.put("typeName", typeName);
        map.put("photo", photo);
        return map;
    }

    //创建条件查询
    public LambdaQueryWrapper<Inventory> createWrapper(BatchEditingInvsReq req) {
        LambdaQueryWrapper<Inventory> wrapper = new LambdaQueryWrapper<>();
        if (ObjectUtil.isEmpty(req)) {
            return wrapper;
        }
        wrapper.eq(ObjectUtil.isNotNull(req.getOrgId()), Inventory::getOrgId, req.getOrgId());
        wrapper.eq(ObjectUtil.isNotNull(req.getLocationId()), Inventory::getLocationId, req.getLocationId());
        wrapper.eq(ObjectUtil.isNotNull(req.getSizeId()), Inventory::getSizeId, req.getSizeId());
        wrapper.eq(ObjectUtil.isNotNull(req.getTypeId()), Inventory::getTypeId, req.getTypeId());
        return wrapper;
    }


    //判断epc是否存在
    @Override
    public List<String> checkEPCList(EpcCheckReq req) {
        return inventoryMapper.checkEPCList(req.getEpcList());
    }


    @Override
    public List<EquipmentDto> alignInventoryInfo(InventoryReq req) {
        String date = DateTimeUtil.TimeLongToString(req.getUpdateTime());
        List<EquipmentDto> equipmentDtos = inventoryMapper.alignInventoryInfo(req.getOrgId(), req.getWarehouseId(), date, req.getTypeIdList(), req.getSizeIdList());
        return equipmentDtos;
    }

    //生成供应商代码
    private static String GenerateSupplierCode(Map<String, String> dictionary){
        String code = Integer.toString(100000000 + new Random().nextInt(900000000));
        if(dictionary.containsKey(code)){
            return GenerateSupplierCode(dictionary);
        }else {
            return code;
        }
    }

    //装备导入（判断导入的数据是否存在redis中，如果不存在，则判断数据库是否存在相同的epc，如果存在提示报错，并且讲该次导入的数据存储到redis中，为下一次进行作比较）
    @Override
    @Transactional
    public Boolean EqsImport(InventoryReq req) {
        LoginUser loginUser = LoginContext.getContext().getLoginUser();

        List<InventoryReq> eqsList = req.getEqsList();
        //判断组织机构是否存在
        PubOrg pubOrg = pubOrgService.getOne(new LambdaQueryWrapper<PubOrg>().eq(PubOrg::getDName, eqsList.get(0).getOrgName())
                .or()
                .eq(PubOrg::getOrgName, eqsList.get(0).getOrgName()));
        if (!pubOrg.getOrgCode().equals(loginUser.getOrgCode())){
            throw new ServiceException(PubOrgExceptionEnum.ORG_IS_NOT_MATCH);
        }
        if (ObjectUtil.isNull(pubOrg)) {
            throw new JYZBAppException(PubOrgExceptionEnum.ORG_NOT_EXIST,"组织机构不存在，请确保组织机构名称正确");
        }
        //判断仓库是都存在
        Warehouse warehouse = warehouseService.getOne(new LambdaQueryWrapper<Warehouse>()
                .eq(Warehouse::getName, eqsList.get(0).getLocationName())
                .eq(Warehouse::getOrgIdInt, pubOrg.getOrgId()));
        if (ObjectUtil.isNull(warehouse)) {
            throw new JYZBAppException(WarehouseExceptionEnum.WAREHOUSE_NAME_NOT_EXIST,"仓库不存在，请确保仓库名称正确或先新增仓库");
        }
        //将该组织机构，仓库下面已经导入的装备删除
        //        LambdaQueryWrapper<WarehouseInventory> queryWrapper = new LambdaQueryWrapper<>();
        //        queryWrapper.eq(WarehouseInventory::getLocationId, warehouse.getId());

//        inventoryMapper.deleteByEpcs1(pubOrg.getOrgId(), warehouse.getId());
//        warehouseInventoryMapper.deleteBylocationId(pubOrg.getOrgId(), warehouse.getId());
//        //将summary表进行删除
//        inventorySummaryMapper.deleteByOrgId(pubOrg.getOrgId(), warehouse.getId());
        //        remove(new LambdaQueryWrapper<Inventory>().eq(Inventory::getNote,"equipmentImport"));
        //        warehouseInventoryService.remove(new LambdaQueryWrapper<WarehouseInventory>().eq(WarehouseInventory::getFlag,2));


        List<Inventory> addInvList = new ArrayList<>();
        List<WarehouseInventory> addWareList = new ArrayList<>();
        //判断导入的装备库存里面是否存在，如果不存在则直接报错失败
        Map<String, String> orgMap = new HashMap<>();
        Map<String, String> warehouseMap = new HashMap<>();
        Map<String, String> typeNameMap = new HashMap<>();
        Map<String, String> sizeNameMap = new HashMap<>();
        Map<String, String> supplierNameMap = new HashMap<>();
        for (InventoryReq inv : eqsList) {
            String[] patterns = {"yyyy-MM-dd HH:mm:ss", "yyyy/MM/dd HH:mm:ss"};
            DateTimeUtil.TimeStringToDateWithFormat(inv.getProductionDate(),patterns);
            String orgName=inv.getOrgName();
            String warehouseName=inv.getLocationName();
            String typeName = inv.getTypeName();
            String sizeName = inv.getSizeName();
            String supplierName = inv.getSupplierName();
            if (!orgMap.containsKey(orgName)) {
                orgMap.put(orgName, orgName);
            }
            if (!warehouseMap.containsKey(warehouseName)) {
                warehouseMap.put(warehouseName, warehouseName);
            }
            if (!typeNameMap.containsKey(typeName)) {
                typeNameMap.put(typeName, typeName);
            }
            if (!sizeNameMap.containsKey(typeName + "||" + sizeName)) {
                sizeNameMap.put(sizeName + "||" + typeName, sizeName);
            }
            if (!supplierNameMap.containsKey(supplierName)) {
                supplierNameMap.put(supplierName, supplierName);
            }

        }

        if (orgMap.values().size()>1){
            throw new ServiceException(PubOrgExceptionEnum.ORG_OVER_TRICE);
        }
        if (warehouseMap.values().size()>1){
            throw new ServiceException(WarehouseExceptionEnum.WAREHOUSE_NAME_OVER_TRICE);
        }

        //判断类型是否全部存在
//        List<EquipmentType> types = equipmentTypeService.list(new LambdaQueryWrapper<EquipmentType>()
//                .eq(EquipmentType::getType,1).in(EquipmentType::getName, typeNameMap.keySet()));
        List<EquipmentType> types = equipmentTypeService.list(new LambdaQueryWrapper<EquipmentType>()
                        .eq(EquipmentType::getType, 1).in(EquipmentType::getName, typeNameMap.keySet()))
                .stream()
                .distinct()
                .collect(Collectors.toList());

        Map<String, String> typeInfo = types.stream().collect(Collectors.toMap(EquipmentType::getName, EquipmentType::getId));
        if (typeInfo.size() < typeNameMap.keySet().size()) {
            List<String> missingElements = typeNameMap.keySet().stream()
                    .filter(element -> !types.stream().map(EquipmentType::getName).collect(Collectors.toList())
                            .contains(element))
                    .collect(Collectors.toList());

            String msg = "请检查装备名称是否存在，以下装备名称不存在：" + String.join(",", missingElements);
            throw new JYZBAppException(EquipmentExceptionEnum.TYPE_NAME_NOT_EXIST, msg);
        }

        //判断供应商是否全部存在
        Collection<String> supplierList = supplierNameMap.keySet();

        Map<String, String> supplierCodeMap = supplierService //供应商code
                .list(new LambdaQueryWrapper<Supplier>())
                .stream()
                .collect(Collectors.toMap(Supplier::getCode, s -> ""));

//        Map<String, String> supplierInfoMap = supplierService //供应商name--id
//                .list(new LambdaQueryWrapper<Supplier>().eq(Supplier::getAgencyType,0).in(Supplier::getName, supplierNameMap.keySet()))
//                .stream()
//                .collect(Collectors.toMap(s -> s.getName(), Supplier::getId));
        Map<String, String> supplierInfoMap = supplierService
                .list(new LambdaQueryWrapper<Supplier>().eq(Supplier::getAgencyType, 0).in(Supplier::getName, supplierNameMap.keySet()))
                .stream()
                .collect(Collectors.toMap(Supplier::getName, Supplier::getId, (existing, replacement) -> existing));
        List<Supplier> addSupplierList = new ArrayList<>();

        //新增供应商
        for (String thisSupplier :
                supplierList.stream().filter(s -> !supplierInfoMap.keySet().contains(s)).collect(Collectors.toList()) )
        {
            Supplier supplier = new Supplier();
            supplier.setName(thisSupplier);
            String newCode = GenerateSupplierCode(supplierCodeMap);
            supplierCodeMap.put(newCode, "");
            supplier.setCode(newCode);
            supplier.setCreateTime(DateTimeUtil.getCurrentDateTime());
            supplier.setUpdateTime(DateTimeUtil.getCurrentDateTime());
            supplier.setState(1);
            supplier.setAgencyType(0);

            addSupplierList.add(supplier);
        }
        supplierService.saveBatch(addSupplierList);

        supplierInfoMap.putAll(addSupplierList.stream().collect(Collectors.toMap(Supplier::getName, Supplier::getId)));


        //新增不存在的号型
        Collection<String> sizeList = sizeNameMap.keySet();

        List<EquipmentSize> addSizeList = new ArrayList<>();

        List<EquipmentSize> baseSizeInfo = equipmentSizeService.list(new LambdaQueryWrapper<EquipmentSize>().in(EquipmentSize::getTypeId, typeInfo.values()));

        Map<String, Integer> typeMaxCodeDic = new HashMap<>();//类型最大编号
        for (String thisSize : sizeList) {
            String[] splitStrings = thisSize.split("\\|\\|");

            String thisTypeId = typeInfo.get(splitStrings[1]);

            List<EquipmentSize> thisTypeToSize = baseSizeInfo.stream()
                    .filter(s -> s.getTypeId().equals(thisTypeId))
                    .collect(Collectors.toList());

            List<EquipmentSize> selectSize = thisTypeToSize.stream()
                    .filter(s -> s.getName().equals(splitStrings[0]))
                    .collect(Collectors.toList());

            if (selectSize.size() == 0) {
                Integer tryGetMaxCode = typeMaxCodeDic.get(thisTypeId);
                String maxCode = "0";
                if (tryGetMaxCode == null) {
                    Optional<EquipmentSize> maxCodeSize = baseSizeInfo.stream()
                            .max((s1, s2) -> Integer.compare(Integer.parseInt(s1.getCode()), Integer.parseInt(s2.getCode())));

                    maxCode = maxCodeSize.isPresent() ? String.valueOf((Integer.parseInt(maxCodeSize.get().getCode()) + 1)) : "0";

                    typeMaxCodeDic.put(thisTypeId, Integer.parseInt(maxCode));
                } else {
                    maxCode = String.valueOf(tryGetMaxCode);
                    typeMaxCodeDic.put(thisTypeId, tryGetMaxCode + 1);
                }

                EquipmentSize addSize = new EquipmentSize();

                addSize.setName(splitStrings[0]);
                addSize.setTypeId(thisTypeId);
                addSize.setCode(maxCode);
                addSize.setCreateTime(DateTimeUtil.getCurrentDateTime());
                addSize.setUpdateTime(DateTimeUtil.getCurrentDateTime());

                addSizeList.add(addSize);
            }
        }

        equipmentSizeService.saveBatch(addSizeList);

        baseSizeInfo.addAll(addSizeList);

        //号型数据baseSizeInfo    类型数据types   name--id  typeInfo

        eqsList.forEach(inv ->
        {
            String thisTypeId = typeInfo.get(inv.getTypeName());
            inv.setTypeId(thisTypeId);

            Optional<EquipmentSize> thisSize = baseSizeInfo.stream()
                    .filter(s -> s.getName().equals(inv.getSizeName()) && s.getTypeId().equals(thisTypeId))
                    .findFirst();
            if (thisSize.isPresent()) {
                inv.setSizeId(thisSize.get().getId());
            }
        });

        Map<String,Object[]> map=new HashMap<>();
        for (InventoryReq inv : eqsList) {
            String key=pubOrg.getOrgId()+warehouse.getId()+inv.getTypeId()+inv.getSizeId()+inv.getPrice()+0;
            if (!map.containsKey(key)){
                Object[] item=new Object[]{pubOrg.getOrgId(),warehouse.getId(),inv.getTypeId(),inv.getSizeId(),inv.getPrice(),0,inv.getNumber(),inv.getTypeName(),inv.getSizeName()};
                map.put(key,item);
            }else {
                Object[] objects = map.get(key);
                objects[6]=(Integer)objects[6]+inv.getNumber();
                map.put(key,objects);
            }
            if (ObjectUtil.isNull(inv.getNumber()) || inv.getNumber()<0){
                throw new JYZBAppException(InventoryExceptionEnum.PARAMETER_ERROR,"数量不合法");
            }
            for (int i = 0; i < inv.getNumber(); i++) {
                //每次遍历inv，获取inv中的数量，对应创建对象并且进行添加至list从而最终插入数据库

                Random random = new Random();
                String epc = "000000" + DateTimeUtil.getCurrentDateTime().getTime() + (random.nextInt(999999 - 100000 + 1) + 100000);
                Inventory inventory = new Inventory();
                BeanPlusUtil.copyProperties(inv, inventory);
                inventory.setNote("equipmentImport");
                inventory.setCreateTime(DateTimeUtil.getCurrentDateTime());
                inventory.setEpc(epc);
                inventory.setSizeId(inv.getSizeId());
                inventory.setTypeId(inv.getTypeId());
                inventory.setOrgId(pubOrg.getOrgId());
                inventory.setLocationId(warehouse.getId());
                inventory.setLocationType(0);
                inventory.setState("normal");
                inventory.setLocationState("normal");
                inventory.setProperty(0);
                inventory.setEpcType(1);
                inventory.setLocationState("in");
                inventory.setSupplierName(inv.getSupplierName());
                inventory.setSupplierId(supplierInfoMap.get(inv.getSupplierName()));
                if (inv.getWarrantyPeriod()>240){
                    inventory.setWarrantyPeriod(0);
                }
                addInvList.add(inventory);
                WarehouseInventory warehouseInventory = new WarehouseInventory();
                BeanPlusUtil.copyProperties(inv, warehouseInventory);
                warehouseInventory.setOrgId(pubOrg.getOrgId());
                //2表示装备导入
                warehouseInventory.setSizeId(inv.getSizeId());
                warehouseInventory.setTypeId(inv.getTypeId());
                warehouseInventory.setFlag(2);
                warehouseInventory.setEpc(epc);
                warehouseInventory.setEpcType(1);
                warehouseInventory.setOrgId(pubOrg.getOrgId());
                warehouseInventory.setLocationId(warehouse.getId());
                warehouseInventory.setLocationType("0");
                warehouseInventory.setLocationName(warehouse.getName());
                warehouseInventory.setOrgName(inv.getOrgName());
                warehouseInventory.setLocationState("in");
                warehouseInventory.setCreateTime(DateTimeUtil.getCurrentDateTime());
                addWareList.add(warehouseInventory);
            }
        }

        if (CollectionUtil.isNotEmpty(addInvList)) {
            saveBatch(addInvList);
        }
        if (CollectionUtil.isNotEmpty(addWareList)) {
            warehouseInventoryService.saveBatch(addWareList);
        }
        List<Object[]> list = new ArrayList<>(map.values());
        List<InventorySummary> addList=new ArrayList<>();
        List<InventorySummary> updateList=new ArrayList<>();
        List<InventorySummary> inventorySummaryList = inventorySummaryMapper.selectSum(list);
        for (Object[] obj:list) {
            boolean flag=false;
            for (InventorySummary is:inventorySummaryList) {
                if (obj[2].equals(is.getTypeId())
                        && obj[3].equals(is.getSizeId()) && is.getUnitPrice().compareTo((BigDecimal) obj[4])==0 && obj[5].equals(is.getProperty())){
                    is.setNumber(is.getStockNumber()+(Integer) obj[6]);
                    is.setStockNumber(is.getStockNumber()+(Integer) obj[6]);
                    is.setPrice(is.getUnitPrice().multiply(BigDecimal.valueOf(is.getNumber())));
                    updateList.add(is);
                    flag=true;
                    break;
                }
            }
            if (!flag){
                InventorySummary inventorySummary = inventorySummaryService.createInventorySummary((Long)obj[0],
                        pubOrg.getOrgName(),pubOrg.getOrgCode(),(String) obj[2],(String) obj[7],(String) obj[3],
                        (String) obj[8],warehouse.getId(),warehouse.getName(),(Integer) obj[6],0,
                        (BigDecimal) obj[4],0,0,0,0,0,0, 0,"0");
                addList.add(inventorySummary);
            }
        }
        if (CollectionUtil.isNotEmpty(updateList)){
            inventorySummaryService.updateBatchById(updateList);
        }
        if (CollectionUtil.isNotEmpty(addList)){
            inventorySummaryService.saveBatch(addList);
        }

//        inventoryMapper.updateEqsInfo(addInvList, DateTimeUtil.getCurrentDateTime());
//        warehouseInventoryMapper.updateWareInfo(addWareList, DateTimeUtil.getCurrentDateTime());
        //重新计算summary表中的数据
//        inventorySummaryService.updateSummaryInsImport(pubOrg.getOrgId(), warehouse.getId());

        return true;
    }

    @Override
    public PageResult<InventoryDto> EqsByState(InventoryReq req) {
        List<InventoryDto> list = inventoryMapper.EqsByState(req, (req.getPageNo() - 1) * req.getPageSize(), req.getPageSize());
        int size = inventoryMapper.EqsByStateSum(req);
        Page<InventoryDto> page = PageFactory.getDefaultPage(req.getPageNo(), req.getPageSize());
        page.setRecords(list);
        page.setTotal(size);
        return PageResultFactory.createPageResult(page);
    }

    @Override
    public List<PeriodAndDateDto> GetByPeriodAndDate(InventoryReq req) {
        if (ObjectUtil.isNull(req.getSizeId()) ||ObjectUtil.isEmpty(req.getSizeId()) ||
                StrUtil.isEmpty(req.getSizeId()) || req.getSizeId().trim().isEmpty()){
            req.setSizeId(null);
        }
        //预案没有sizeId和sizeName
        List<PeriodAndDateDto> list = inventoryMapper.GetByPeriodAndDate(req);
        if (CollectionUtil.isEmpty(list)) {
            return new ArrayList<>();
        }
        return list;
    }

    @Override
    public List<Inventory> selectSum(List<Object[]> searchItem, Integer epcType) {
        return inventoryMapper.selectSum(searchItem, epcType);
    }



    @Override
    @Transactional
    public String EqsBindOrUnbindCabinet(PoliceEquipmentDetailReq req) {
        PubOrg pubOrg = pubOrgService.PubOrgCodeExist(req.getOrgCode());
        Cabinet cabinet=cabinetBoxService.getCabByBoxId(req.getLocationId());
        CabinetBox one = cabinetBoxService.getById(req.getLocationId());
        if (ObjectUtil.isNotNull(one) && (ObjectUtil.isEmpty(one.getBoxLocalId()) || !req.getBoxLocalId().equals(one.getBoxLocalId()))){
            one.setBoxLocalId(req.getBoxLocalId());
            cabinetBoxService.updateById(one);
        }

        EqsBindOrUnBind(req.getEpcsList(),cabinet,pubOrg,one,null);

        return req.getBoxLocalId();
    }

    @Override
    public List<Inventory> EqsBindOrUnBind(List<String> epcList, Cabinet cabinet, PubOrg pubOrg, CabinetBox cabinetBox,Policeman policeman) {
        List<Inventory> returnList=new ArrayList<>();
        //获取到该单警柜下面是否存在装备，如果存在且已经解绑，那么该单警柜的装备的出库状态就设置出库，在库数减少，出库数增加
        List<Inventory> list=inventoryMapper.getInvByCabinetBox(cabinetBox.getId());

        //解绑的装备epc
        List<Inventory> delEpcList = list.stream().filter(s -> !epcList.contains(s.getEpc())).collect(Collectors.toList());

        //新增的绑定的装备epc
        List<String> existEpcList = list.stream().map(Inventory::getEpc).collect(Collectors.toList());
        List<String> addEpcList =epcList.stream().filter(s -> !existEpcList.contains(s)).collect(Collectors.toList());

        List<Inventory> InventoryList=new ArrayList<>();
        //1.判断epc位置是否所属仓库，如果属于仓库,那么将仓库库存进行修改
        if (CollectionUtil.isNotEmpty(addEpcList)){
            //查询新增的绑定epc的位置（如果状态是use和out那么直接选择，否则就随便取一条）
            List<Inventory> list1 =inventoryMapper.selectInventoryByEpcList(addEpcList,null);
//            List<Inventory> list1 = list(new LambdaQueryWrapper<Inventory>().in(Inventory::getEpc, addEpcList));
            //去重的epcList(和绑定箱门的epc相同的)
            InventoryList = list1.stream()
                    .collect(Collectors.toMap(
                            Inventory::getEpc,
                            inv -> inv,
                            (existing, replacement) -> {
                                if (existing.getBussinessState().equals("use") && existing.getLocationState().equals("out")) {
                                    return existing;
                                } else if (replacement.getBussinessState().equals("use") && replacement.getLocationState().equals("out")) {
                                    return replacement;
                                } else {
                                    return existing;
                                }
                            }
                    ))
                    .values()
                    .stream()
                    .collect(Collectors.toList());
            List<Inventory> boxInvList=new ArrayList<>();
            List<Inventory> warehouseInvList=new ArrayList<>();
            for (Inventory inventory:InventoryList) {
                if (inventory.getLocationType()==1){//所属单警柜
                    boxInvList.add(inventory);
                }else {//所属仓库
                    warehouseInvList.add(inventory);
                }
            }
            if (CollectionUtil.isNotEmpty(warehouseInvList)) {
                warehouseEqsBind(warehouseInvList, cabinet, pubOrg, cabinetBox.getId(), addEpcList);

                //更新人员装备绑定关系
            }
            // 如果位置属于单警柜，那么直接将原来的单警柜的库存位置进行修改；
            // 如果两个箱门的所属单警柜一致，那单警柜库存汇总不进行改变，否则原来的单警柜的库存进行减少，现绑定的单警柜库存进行增加
            if (CollectionUtil.isNotEmpty(boxInvList)){
                //箱门中存在的装备，获取到原来的装备
                //原来装备进行修改之后，修改单警柜的位置信息库存
                cabinetEqsBind(boxInvList,cabinet,pubOrg,cabinet.getId());

                //更新人员装备绑定关系

            }
        }
        //解绑
        if (CollectionUtil.isNotEmpty(delEpcList)){
            //状态设置为出柜状态，并进行标记，下次如果需要归还优先归还解绑的epc
            unBind(delEpcList,cabinet,pubOrg);

            //更新人员装备绑定关系(先获取人员下的装备)
            unBindPoliceEquipment(policeman,delEpcList.stream().map(Inventory::getEpc).collect(Collectors.toList()));
        }
        //创建出入库日志
        if (CollectionUtil.isNotEmpty(delEpcList)){
            List<Inventory> outList = delEpcList.stream().map(inventory -> {
                inventory.setLocationState("out");
                return inventory;
            }).collect(Collectors.toList());
            returnList.addAll(outList);
            List<InventoryReq> beanList = BeanPlusUtil.toBeanList(outList, InventoryReq.class);
            if (ObjectUtil.isNotNull(policeman)){
                logSummaryService.addLogSummaryByInv(beanList,null,null,"normal",1,"1",policeman.getName(),pubOrg.getOrgName(),cabinet.getDevSn());
            }else {

                logSummaryService.addLogSummaryByInv(beanList,null,null,"normal",1,"1",null,pubOrg.getOrgName(),cabinet.getDevSn());
            }
        }
        if (CollectionUtil.isNotEmpty(InventoryList)){
            List<Inventory> inList = InventoryList.stream().map(inventory -> {
                inventory.setLocationState("in");
                return inventory;
            }).collect(Collectors.toList());
            returnList.addAll(inList);
            List<InventoryReq> beanList = BeanPlusUtil.toBeanList(inList, InventoryReq.class);
            if (ObjectUtil.isNotNull(policeman)){
                logSummaryService.addLogSummaryByInv(beanList,null,null,"normal",1,"1",policeman.getName(),pubOrg.getOrgName(),cabinet.getDevSn());
            }else {

                logSummaryService.addLogSummaryByInv(beanList,null,null,"normal",1,"1",null,pubOrg.getOrgName(),cabinet.getDevSn());
            }
        }


        return returnList;
    }



    public Boolean bindPoliceEquipmentBox(Policeman policeman,List<String> epcList){
        //拿到警员下面的所有装备
        //如果装备是单警柜出柜且绑定状态为0，那么直接替换为单警柜在柜，
        List<PoliceEquipment> list = policeEquipmentService.list(new LambdaQueryWrapper<PoliceEquipment>().eq(PoliceEquipment::getPoliceId, policeman.getId()));
        List<PoliceEquipmentDetail> boxInvList = policeEquipmentDetailService.list(new LambdaQueryWrapper<PoliceEquipmentDetail>().in(PoliceEquipmentDetail::getEpc, epcList));

        Map<String,Integer> unBindMap=new HashMap<>();
        for (PoliceEquipmentDetail equ:boxInvList) {
            String key=equ.getOrgId()+equ.getPoliceId()+equ.getLocationId()+equ.getTypeId()+equ.getSizeId()+equ.getPrice();
            if (!unBindMap.containsKey(key)){
                Integer outNum=1;
                unBindMap.put(key,outNum);
            }else {
                Integer outNum = unBindMap.get(key);
                outNum+=1;
                unBindMap.put(key,outNum);
            }
            equ.setLocationState("out");
        }
        return true;
        

    }

    //装备解绑修改警员对应装备
    public Boolean unBindPoliceEquipment(Policeman policeman,List<String> unBindEpcList){
        //更新人员装备绑定关系(先获取人员下的装备)
        List<PoliceEquipment> list = policeEquipmentService.list(new LambdaQueryWrapper<PoliceEquipment>().eq(PoliceEquipment::getPoliceId, policeman.getId()));
        List<PoliceEquipmentDetail> unBindInvList = policeEquipmentDetailService.list(new LambdaQueryWrapper<PoliceEquipmentDetail>().in(PoliceEquipmentDetail::getEpc, unBindEpcList));
        Map<String,Integer> unBindMap=new HashMap<>();
        for (PoliceEquipmentDetail equ:unBindInvList) {
            String key=equ.getOrgId()+equ.getPoliceId()+equ.getLocationId()+equ.getTypeId()+equ.getSizeId()+equ.getPrice();
            if (!unBindMap.containsKey(key)){
                Integer outNum=1;
                unBindMap.put(key,outNum);
            }else {
                Integer outNum = unBindMap.get(key);
                outNum+=1;
                unBindMap.put(key,outNum);
            }
            equ.setLocationState("out");
        }
        for (PoliceEquipment equipment:list) {
            String key=equipment.getOrgId()+equipment.getPoliceId()+equipment.getLocationId()+equipment.getTypeId()+equipment.getSizeId()+equipment.getPrice();
            Integer outNum = unBindMap.get(key);
            equipment.setInNum(equipment.getInNum()-outNum);
            equipment.setOutNum(equipment.getInNum()+outNum);
        }
        policeEquipmentDetailService.updateBatchById(unBindInvList);
        policeEquipmentService.updateBatchById(list);
        return true;
    }



    /**
     * 仓库据位置绑定
     * 原来存在于仓库，将库存中的在库装备进行修改为领用出库，同时如果领用出去的epc进行恢复，日志进行替换
     * 仓库出库数减少，单警柜在库数增多（修改库存汇总数）
     */
    @Transactional
    public List<String> warehouseEqsBind(List<Inventory> warehouseInvList,Cabinet cabinet,PubOrg pubOrg,String locationId,List<String> addEpcList){
        // 2.(判断绑定的装备是否是领用出去的装备，如果是则直接进行计算，如果不是，将领用出去的装备的epc进行修正)
        //如果查询出来的装备存在，且状态是use和out，那么我直接存起来（用于计算库存删减）
        List<Inventory> collect = warehouseInvList.stream().filter(s -> addEpcList.contains(s.getEpc())
                && s.getBussinessState().equals("use")
                && s.getLocationState().equals("out")).collect(Collectors.toList());//获取到就是领用出去的epcList
        List<Inventory> notExistCollect = warehouseInvList.stream().filter(s -> !addEpcList.contains(s.getEpc())//绑定的epc但是未被领用出去
                && !s.getBussinessState().equals("use")
                && !s.getLocationState().equals("out")
        ).collect(Collectors.toList());
        //根据不存在的collect去查询领用出去除了epc和价格以外其他都相同的epc那么我优先选择单价相同的进行选择
        Map<String,Map<String,Inventory>> map=new HashMap<>();
        //一一替换的epc存入map中用key表示，然后values中的map的key为绑定的epc
        for (Inventory inventory : notExistCollect) {
            //需要除去一一对应领用出去的epc
            List<Inventory> outList = list(new LambdaQueryWrapper<Inventory>()
                    .eq(Inventory::getOrgId, inventory.getOrgId())
                    .eq(Inventory::getLocationId, inventory.getLocationId())
                    .eq(Inventory::getTypeId, inventory.getTypeId())
                    .eq(Inventory::getSizeId, inventory.getSizeId())
                    .eq(Inventory::getLocationState, "out")
                    .eq(Inventory::getBussinessState, "use")
                    .notIn(CollectionUtil.isNotEmpty(collect), Inventory::getEpc, collect.stream().map(Inventory::getEpc).collect(Collectors.toList()))
                    .orderByAsc(Inventory::getPrice));
            boolean flag = false;
            for (Inventory outInv : outList) {
//                    for (int j=0;j<outList.size();j++) {
                //优先获取价位相等的epc进行调节
                if (outInv.getPrice().compareTo(inventory.getPrice()) == 0) {
                    if (!map.containsKey(outInv.getEpc())) {
                        Map<String, Inventory> newMap = new HashMap<>();
                        newMap.put(inventory.getEpc(), outInv);
                        //map中的key为数据库中领用出去的不同于绑定epc的epc，
                        //newMap中的key为单警柜识别到的需要绑定的epc，value则是领用出去的epc（需要被替换回来的）
                        map.put(outInv.getEpc(), newMap);
                        flag = true;
                        break;
                    }
                }
            }
            //如果flag=false 表示没有价位相等的epc，那么直接获取列表的未被选中的数据作为
            if (!flag) {
                Inventory inventory1 = new Inventory();
                for (Inventory ooo : outList) {
                    if (!map.containsKey(ooo.getEpc())) {
                        inventory1 = ooo;
                        break;
                    }
                }
                Map<String, Inventory> newMap = new HashMap<>();
                newMap.put(inventory.getEpc(), inventory1);
                map.put(inventory1.getEpc(), newMap);

            }

        }
        //获取到需要替换的epc（领用出库的）的装备汇总（将出库数减少，在库数增多）
        //领用和绑定的装备epc相同
        if (CollectionUtil.isNotEmpty(collect)){

            updateInventorySummary(collect,"useBind",null,null);
        }
        //绑定的不同于领用装备的epc
        if (CollectionUtil.isNotEmpty(notExistCollect)){

            updateInventorySummary(notExistCollect,"bind",null,null);
        }
        //领用的epc相等于绑定的epc
        List<Inventory> useBindInvLIst = new ArrayList<>();
        for (Map<String, Inventory> stringInventoryMap : map.values()) {
            useBindInvLIst.addAll(stringInventoryMap.values());
        }
        if (CollectionUtil.isNotEmpty(useBindInvLIst)){

            updateInventorySummary(useBindInvLIst,"use",null,null);
        }
        if (CollectionUtil.isNotEmpty(warehouseInvList)){

            //修改状态
            updateInventorysState(warehouseInvList,pubOrg,locationId,1);
        }

        //查询单警柜库存并进行修改
        if (CollectionUtil.isNotEmpty(warehouseInvList)){

            updateInventorySummary(warehouseInvList,"boxBind",cabinet,pubOrg);
        }
        //需要将日志信息进行替换处理一一对应替换（用到map）
        Map<String,String> epcMap=new HashMap<>();
        for (String key:map.keySet()) {
            Map<String, Inventory> stringInventoryMap = map.get(key);
            List<String> collect1 = stringInventoryMap.keySet().stream().collect(Collectors.toList());
            String s = collect1.get(0);
            epcMap.put(key,s);
        }
        //查询领用出去的epc（取最新时间的epc）
        List<String> collect1 = map.keySet().stream().collect(Collectors.toList());
        List<String> changeEpcList=new ArrayList<>();
        if (CollectionUtil.isNotEmpty(collect1)){

            List<LogDetail> logDetailList=logDetailService.getRecordsByEpc(collect1);
            for (LogDetail logDetail:logDetailList) {
                if (epcMap.containsKey(logDetail.getEpc())){
                    String epc = epcMap.get(logDetail.getEpc());
                    changeEpcList.add(epc);
                    logDetail.setEpc(epc);
                }
            }
            if (CollectionUtil.isNotEmpty(logDetailList)){

                logDetailService.updateBatchById(logDetailList);
            }
        }

        return changeEpcList;
    }


    /**
     * 单警柜位置绑定
     * （原来位置存在于单警柜，直接将原来单警柜里的装备进行默认解绑删除库存汇总之后，
     * 将新的单警柜进行绑定并且重新计算新的单警柜所有的库存汇总）
     * @param boxInvList
     * @param cabinet
     * @param pubOrg
     * @return
     */
    @Transactional
    public Boolean cabinetEqsBind(List<Inventory> boxInvList,Cabinet cabinet,PubOrg pubOrg,String boxId){
        List<String> collect = boxInvList.stream().map(Inventory::getLocationId).collect(Collectors.toList());
        List<CabinetBox> boxList = cabinetBoxService.list(new LambdaQueryWrapper<CabinetBox>().in(CabinetBox::getId, collect));
        Map<String, String> collect1 = boxList.stream().collect(Collectors.toMap(CabinetBox::getId, CabinetBox::getCabinetId));
        Map<String,Object[]> searchMap=new HashMap<>();
        for (Inventory useBindInv:boxInvList) {//找到原来位置进行修改
            String key="";
            String locationId = collect1.get(useBindInv.getLocationId());
            if (ObjectUtil.isNotEmpty(locationId)){
                key=useBindInv.getOrgId()+locationId+useBindInv.getSizeId()+useBindInv.getPrice()+useBindInv.getProperty();
            }
            if (!searchMap.containsKey(key)){
                if (useBindInv.getLocationState().equals("in")){
                    Object[] item=new Object[]{useBindInv.getOrgId(),locationId,useBindInv.getTypeId(),useBindInv.getSizeId(),useBindInv.getPrice(),useBindInv.getProperty(),1,0};
                    searchMap.put(key,item);
                }else {
                    Object[] item=new Object[]{useBindInv.getOrgId(),locationId,useBindInv.getTypeId(),useBindInv.getSizeId(),useBindInv.getPrice(),useBindInv.getProperty(),0,1};
                    searchMap.put(key,item);
                }
            }else {
                Object[] objects = searchMap.get(key);
                if (useBindInv.getLocationState().equals("in")){
                    objects[6]=(Integer)objects[6]+1;

                }else {
                    objects[7]=(Integer)objects[7]+1;
                }
                searchMap.put(key,objects);
            }

        }

        List<Object[]> searchItem=new ArrayList<>(searchMap.values());
        //原来位置进行删除库存
        List<InventorySummary> inventorySummaryList = inventorySummaryMapper.selectSum(searchItem);
        List<InventorySummary> delSummaryList=new ArrayList<>();
        for (Object[] obj:searchItem) {

            for (InventorySummary is:inventorySummaryList) {
                if (obj[0].equals(is.getOrgId())
                        && obj[1].equals(is.getLocationId())
                        && obj[2].equals(is.getTypeId())
                        && obj[3].equals(is.getSizeId())
                        && is.getUnitPrice().compareTo((BigDecimal) obj[4])==0
                        && obj[5].equals(is.getProperty())){
                    if ((Integer)obj[6]!=0){
                        is.setStockNumber(Math.max(is.getStockNumber()-(Integer)obj[6],0));
                        is.setNumber(Math.max(is.getNumber()-(Integer) obj[6],0));
                        is.setPrice(is.getUnitPrice().multiply(BigDecimal.valueOf(is.getNumber())));
                    }
                    if ((Integer)obj[7]!=0){
                        is.setOutboundNumber(Math.max(is.getOutboundNumber()-(Integer)obj[7],0));
                        is.setNumber(Math.max(is.getNumber()-(Integer) obj[7],0));
                        is.setPrice(is.getUnitPrice().multiply(BigDecimal.valueOf(is.getNumber())));
                    }
                    if (is.getNumber() == 0 && is.getStockNumber() == 0 && is.getOutboundNumber() == 0
                            && is.getBrokenNumber()==0 && is.getDestructionNumber() == 0) {
                        delSummaryList.add(is);
                        inventorySummaryList.remove(is);
                    }
                }
                break;
            }
        }
        if (CollectionUtil.isNotEmpty(inventorySummaryList)){

            inventorySummaryService.updateBatchById(inventorySummaryList);
        }
        if (CollectionUtil.isNotEmpty(delSummaryList)){
            inventorySummaryService.removeBatchByIds(delSummaryList);
        }
        //新增绑定装备
        updateInventorySummary(boxInvList,"boxBind",cabinet,pubOrg);

        //修改状态
        updateInventorysState(boxInvList,pubOrg,boxId,1);
        return true;
    }

    /**
     * 解绑更新库存汇总以及更新两张库存表的状态
     * @param delEpcList
     * @param cabinet
     * @param pubOrg
     * @return
     */
    @Transactional
    public Boolean unBind(List<Inventory> delEpcList,Cabinet cabinet,PubOrg pubOrg){
        updateInventorySummary(delEpcList,"boxUnBind",cabinet,pubOrg);
        //将状态改为解绑状态，且出库
        LambdaUpdateWrapper<Inventory> invUseBindWrapper = new LambdaUpdateWrapper<>();
        LambdaUpdateWrapper<WarehouseInventory> wareInvUseBindWrapper = new LambdaUpdateWrapper<>();
        invUseBindWrapper.set(Inventory::getLocationState,"out")
                .set(Inventory::getEqsBindState,0);
        wareInvUseBindWrapper.set(WarehouseInventory::getLocationState,"out");
        for (int i=0;i<delEpcList.size();i++) {
            invUseBindWrapper.eq(Inventory::getEpc,delEpcList.get(i).getEpc());
            wareInvUseBindWrapper.eq(WarehouseInventory::getEpc,delEpcList.get(i).getEpc());
            if (i<delEpcList.size()-1){
                invUseBindWrapper.or();
                wareInvUseBindWrapper.or();
            }
        }
        update(invUseBindWrapper);
        warehouseInventoryService.update(wareInvUseBindWrapper);
        //更新人员与单警柜的装备关系

        return true;
    }





    //获取绑定装备的最新出入库状态以及更新库存汇总数量
    @Override
    @Transactional
    public Boolean getEqsState(PoliceEquipmentDetailReq req) {
        //获取箱门下绑定的epc信息以及对应的装备信息（遍历装备的epc）
        Cabinet cabinet = cabinetService.CabinetExistByNum(req.getDevSn());

        List<PoliceEquipmentDetailReq> detailList = req.getDetailList();
        List<Inventory> inventoryList=new ArrayList<>();
        List<WarehouseInventory> warehouseInvList=new ArrayList<>();
        Map<String,String> map=new HashMap<>();
        for (PoliceEquipmentDetailReq detailReq:detailList) {
            List<String> collect = detailReq.getEpcList().stream().map(InventoryReq::getEpc).collect(Collectors.toList());
            //epc和出入状态的map
            Map<String, String> stateMap = detailReq.getEpcList().stream().collect(Collectors.toMap(InventoryReq::getEpc, InventoryReq::getLocationState));
            map.putAll(stateMap);
            //库存的查询绑定的epc
            List<Inventory> list = list(new LambdaQueryWrapper<Inventory>()
                    .eq(Inventory::getLocationId, detailReq.getLocationId())
                    .in(Inventory::getEpc, collect));
            inventoryList.addAll(list);
            List<WarehouseInventory> wareInvlist = warehouseInventoryService.list(new LambdaQueryWrapper<WarehouseInventory>()
                    .eq(WarehouseInventory::getLocationId, detailReq.getLocationId())
                    .in(WarehouseInventory::getEpc, collect));
            warehouseInvList.addAll(wareInvlist);
        }
        //直接修改状态
        for (Inventory inv:inventoryList) {
            if (map.containsKey(inv.getEpc()) && !map.get(inv.getEpc()).equals(inv.getLocationState())){
                inv.setLocationState(map.get(inv.getEpc()));
            }
        }
        updateBatchById(inventoryList);
        for (WarehouseInventory wareInv:warehouseInvList) {
            if (map.containsKey(wareInv.getEpc()) && !map.get(wareInv.getEpc()).equals(wareInv.getLocationState())){
                wareInv.setLocationState(map.get(wareInv.getEpc()));
            }
        }
        warehouseInventoryService.updateBatchById(warehouseInvList);
        //查询出库存
        Map<String,Object[]> invMap=new HashMap<>();
        for (Inventory inv:inventoryList){
            String key=inv.getOrgId()+cabinet.getId()+inv.getTypeId()+inv.getSizeId()+inv.getPrice()+inv.getProperty();
            if (!invMap.containsKey(key)){
                if (inv.getLocationState().equals("in")){
                    Object[] item=new Object[]{inv.getOrgId(),cabinet.getId(),inv.getTypeId(),inv.getSizeId(),inv.getPrice(),inv.getProperty(),1,0};
                    invMap.put(key,item);
                }else {
                    Object[] item=new Object[]{inv.getOrgId(),cabinet.getId(),inv.getTypeId(),inv.getSizeId(),inv.getPrice(),inv.getProperty(),0,1};
                    invMap.put(key,item);
                }
            }else {
                Object[] objects = invMap.get(key);
                if (inv.getLocationState().equals("in")){
                    objects[6]=(Integer)objects[6]+1;

                }else {
                    objects[7]=(Integer)objects[7]+1;
                }
                invMap.put(key,objects);
            }
        }
        List<Object[]> searchItem=new ArrayList<>(invMap.values());
        //库存的epc汇总查询
        if (CollectionUtil.isNotEmpty(searchItem)){
            List<InventorySummary> inventorySummaryList = inventorySummaryMapper.selectSum(searchItem);
            for (Object[] obj:searchItem) {
                for (InventorySummary is:inventorySummaryList) {
                    if (obj[0].equals(is.getOrgId())
                            && obj[1].equals(is.getLocationId())
                            && obj[2].equals(is.getTypeId())
                            && obj[3].equals(is.getSizeId())
                            && is.getUnitPrice().compareTo((BigDecimal) obj[4])==0
                            && obj[5].equals(is.getProperty())){
                        is.setNumber(0);
                        if ((Integer)obj[6]!=0){
                            is.setStockNumber((Integer)obj[6]);
                            is.setNumber((Integer)obj[6]);

                        }
                        if ((Integer)obj[7]!=0){
                            is.setOutboundNumber((Integer)obj[7]);
                            is.setNumber(is.getNumber()+(Integer)obj[7]);
                        }

                        is.setPrice(is.getUnitPrice().multiply(BigDecimal.valueOf(is.getNumber())));
                    }
                    break;
                }
            }
            inventorySummaryService.updateBatchById(inventorySummaryList);
        }else {
            return false;
        }

        return true;
    }


    @Transactional
    public void updateInventorySummary(List<Inventory> collect,String type,Cabinet cabinet,PubOrg pubOrg){
        Map<String,Object[]> searchMap=new HashMap<>();
        for (Inventory useBindInv:collect) {
            String key="";
            if (ObjectUtil.isNotNull(cabinet)){
                key=useBindInv.getOrgId()+cabinet.getId()+useBindInv.getTypeId()+useBindInv.getSizeId()+useBindInv.getPrice()+useBindInv.getProperty();
            }else {
                key=useBindInv.getOrgId()+useBindInv.getLocationId()+useBindInv.getTypeId()+useBindInv.getSizeId()+useBindInv.getPrice()+useBindInv.getProperty();
            }
            if (!searchMap.containsKey(key) && ObjectUtil.isNull(cabinet)){
                Object[] item=new Object[]{useBindInv.getOrgId(),useBindInv.getLocationId(),useBindInv.getTypeId(),useBindInv.getSizeId(),useBindInv.getPrice(),useBindInv.getProperty(),1};
                searchMap.put(key,item);
            } else if (!searchMap.containsKey(key) && ObjectUtil.isNotNull(cabinet)) {
                Object[] item=new Object[]{useBindInv.getOrgId(),cabinet.getId(),useBindInv.getTypeId(),useBindInv.getSizeId(),useBindInv.getPrice(),useBindInv.getProperty(),1,
                        useBindInv.getTypeName(),useBindInv.getSizeName()};
                searchMap.put(key,item);
            } else {
                Object[] objects = searchMap.get(key);
                objects[6]=(Integer)objects[6]+1;
                searchMap.put(key,objects);
            }
        }
        List<Object[]> searchItem=new ArrayList<>(searchMap.values());
        List<InventorySummary> inventorySummaryList = inventorySummaryMapper.selectSum(searchItem);
        List<InventorySummary> addList=new ArrayList<>();
        List<InventorySummary> delList=new ArrayList<>();
        for (Object[] obj:searchItem) {
            boolean flag=false;
            for (InventorySummary is:inventorySummaryList) {
                if (obj[0].equals(is.getOrgId())
                        && obj[1].equals(is.getLocationId())
                        && obj[2].equals(is.getTypeId())
                        && obj[3].equals(is.getSizeId())
                        && is.getUnitPrice().compareTo((BigDecimal) obj[4])==0
                        && obj[5].equals(is.getProperty())){

                    if (type.equals("useBind")){
                        is.setOutboundNumber(Math.max(is.getOutboundNumber()-(Integer) obj[6],0));
                        is.setNumber(Math.max(is.getNumber()-(Integer) obj[6],0));
                        is.setPrice(is.getUnitPrice().multiply(BigDecimal.valueOf(is.getNumber())));
                        if (is.getNumber() == 0 && is.getStockNumber() == 0 && is.getOutboundNumber() == 0
                                && is.getBrokenNumber()==0 && is.getDestructionNumber() == 0) {
                            delList.add(is);
                        }
                    } else if (type.equals("use")) {
                        is.setStockNumber(is.getStockNumber()+(Integer) obj[6]);
                        is.setOutboundNumber(Math.max(is.getOutboundNumber()-(Integer) obj[6],0));
                    } else if (type.equals("bind")) {
                        is.setStockNumber(Math.max(is.getStockNumber()-(Integer) obj[6],0));
                    } else if (type.equals("boxUnBind")) {
                        is.setOutboundNumber(is.getOutboundNumber()+(Integer) obj[6]);
                        is.setStockNumber(Math.max(is.getStockNumber()-(Integer) obj[6],0));
                        is.setPrice(is.getUnitPrice().multiply(BigDecimal.valueOf(is.getNumber())));
                    } else {//单警柜新增信息(boxBind)
                        is.setStockNumber(is.getStockNumber()+(Integer) obj[6]);
                        is.setNumber(is.getNumber()+(Integer) obj[6]);
                        is.setPrice(is.getUnitPrice().multiply(BigDecimal.valueOf(is.getNumber())));
                    }
                    flag=true;
                    break;
                }
            }
            if (!flag){
                //单警柜不存在，需要新增
                InventorySummary inventorySummary = inventorySummaryService.createInventorySummary(pubOrg.getOrgId(),
                        pubOrg.getOrgName(),pubOrg.getOrgCode(),(String) obj[2],(String) obj[7],(String) obj[3],
                        (String) obj[8],cabinet.getId(),cabinet.getName(),(Integer) obj[6],0,
                        (BigDecimal) obj[4],0,0,(Integer) obj[5],0,0,0,0,"1");

                addList.add(inventorySummary);
            }
        }
        if (CollectionUtil.isNotEmpty(delList)){
            inventorySummaryService.removeBatchByIds(delList);
        }
        if (CollectionUtil.isNotEmpty(addList)){
            inventorySummaryService.saveBatch(addList);
        }
        inventorySummaryService.updateBatchById(inventorySummaryList);
    }


    @Transactional
    public void updateInventorysState(List<Inventory> collect,PubOrg pubOrg,String locationId,Integer eqsBindState){
        if (CollectionUtil.isNotEmpty(collect)){
            LambdaUpdateWrapper<Inventory> invUseBindWrapper = new LambdaUpdateWrapper<>();
            LambdaUpdateWrapper<WarehouseInventory> wareInvUseBindWrapper = new LambdaUpdateWrapper<>();
            invUseBindWrapper.set(Inventory::getOrgId,pubOrg.getOrgId())
                    .set(Inventory::getLocationState,"in")
                    .set(Inventory::getLocationType,1)
                    .set(Inventory::getEqsBindState,eqsBindState)
                    .set(Inventory::getBussinessState,"normal");
            wareInvUseBindWrapper.set(WarehouseInventory::getOrgId,pubOrg.getOrgId())
                    .set(WarehouseInventory::getLocationState,"in")
                    .set(WarehouseInventory::getLocationType,1);
            for (int i=0;i<collect.size();i++) {
                invUseBindWrapper.set(Inventory::getLocationId,locationId);
                invUseBindWrapper.eq(Inventory::getEpc,collect.get(i).getEpc());
                wareInvUseBindWrapper.set(WarehouseInventory::getLocationId,locationId);
                wareInvUseBindWrapper.eq(WarehouseInventory::getEpc,collect.get(i).getEpc());
                if (i<collect.size()-1){
                    invUseBindWrapper.or();
                    wareInvUseBindWrapper.or();
                }
            }
            update(invUseBindWrapper);
            warehouseInventoryService.update(wareInvUseBindWrapper);
        }
    }

    }
