package com.junmp.jyzb.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.junmp.jyzb.api.bean.dto.LogSummaryDto;
import com.junmp.jyzb.api.bean.dto.NormalInOutDto;
import com.junmp.jyzb.api.bean.query.inAndOutRecordReq.*;
import com.junmp.jyzb.api.bean.query.InventoryReq;
import com.junmp.jyzb.api.bean.query.LogDetailReq;
import com.junmp.jyzb.api.bean.query.LogSummaryReq;
import com.junmp.jyzb.api.bean.query.OrderLogReq;
import com.junmp.jyzb.cache.OutInRecordRedisCache;
import com.junmp.jyzb.entity.*;
import com.junmp.jyzb.mapper.InventorySummaryMapper;
import com.junmp.jyzb.mapper.LogSummaryMapper;
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.util.BeanPlusUtil;
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.file.api.bean.req.SysFileInfoReq;
import com.junmp.v2.file.api.bean.res.SysFileInfoResp;
import com.junmp.v2.file.biz.service.SysFileInfoService;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
* @author lxh专属坐骑
* @description 针对表【base_log_summary】的数据库操作Service实现
* @createDate 2023-10-13 08:29:36
*/
@Service
public class LogSummaryServiceImpl extends ServiceImpl<LogSummaryMapper, LogSummary>
    implements LogSummaryService{

    @Resource
    private LogSummaryService logSummaryService;

    @Resource
    private InventoryService inventoryService;

    @Resource
    private OrderMainService orderMainService;

    @Resource
    private OrderDetailService orderDetailService;

    @Resource
    private LogDetailService logDetailService;

    @Resource
    private InventorySummaryService inventorySummaryService;

    @Resource
    private InventorySummaryMapper inventorySummaryMapper;

    @Resource
    private OrderLogService orderLogService;


    @Resource
    private WarehouseInventoryService warehouseInventoryService;

    @Resource
    private SysFileInfoService sysFileInfoService;

    @Resource
    private LogSummaryMapper logSummaryMapper;

    @Resource
    private OutInRecordRedisCache outInRecordRedisCache;

    @Resource
    private PubOrgService pubOrgService;

    //根据条件查询出入库记录(子单的记录)
    @Override
    public PageResult<LogSummary> ShowInOutRecordsByItems(LogSummaryReq req) {
        //(如果传其他不是数据库字段参数或者排序规则不是deac或者asc可能会出现错误)
        if (ObjectUtil.isNotNull(req.getColumn()) && !req.getColumn().trim().isEmpty() &&
                (req.getOrder().equalsIgnoreCase("asc")|| req.getOrder().equalsIgnoreCase("desc")) &&
                ObjectUtil.isNotNull(req.getOrder()) && !req.getOrder().trim().isEmpty()) {
            //修改字段，和数据库字段进行统一
            req.setColumn(req.getColumn().replaceAll("[A-Z]", "_$0").toLowerCase());
            req.setOrder(req.getOrder().toLowerCase());
        }else {
            req.setColumn("create_time");
            req.setOrder("desc");
        }
        List<LogSummary> list=logSummaryMapper.ShowInOutRecordsByItems(req,(req.getPageNo()-1)*req.getPageSize(), req.getPageSize());
        LogSummaryDto logSummary = logSummaryMapper.ShowInOutRecordsByItemsCount(req);
        Page page=PageFactory.getDefaultPage(req.getPageNo(), req.getPageSize());
        page.setRecords(list);
        page.setTotal(logSummary.getCount());
//        LambdaQueryWrapper<LogSummary> eq = createWrapper(req);
//
//        Page<LogSummary> page = logSummaryService.page(PageFactory.getDefaultPage(req.getPageNo(), req.getPageSize()), eq);

        return PageResultFactory.createPageResult(page);
    }

    @Override
    public LogSummaryDto ShowInOutRecordsByItemsCount(LogSummaryReq req) {
        if (ObjectUtil.isNotNull(req.getColumn()) && !req.getColumn().trim().isEmpty() &&
                (req.getOrder().equalsIgnoreCase("asc")|| req.getOrder().equalsIgnoreCase("desc")) &&
                ObjectUtil.isNotNull(req.getOrder()) && !req.getOrder().trim().isEmpty()) {
            //修改字段，和数据库字段进行统一
            req.setColumn(req.getColumn().replaceAll("[A-Z]", "_$0").toLowerCase());
            req.setOrder(req.getOrder().toLowerCase());
        }else {
            req.setColumn("create_time");
            req.setOrder("desc");
        }

        LogSummaryDto logSummary = logSummaryMapper.ShowInOutRecordsByItemsCount(req);
        return ObjectUtil.isNull(logSummary)?new LogSummaryDto():logSummary ;

    }

    //根据条件查询出入库记录(整个单子的汇总记录)
    @Override
    public PageResult<LogSummaryDto> RecordSumByOrderId(LogSummaryReq req) {
        if (ObjectUtil.isNotNull(req.getColumn()) && !req.getColumn().trim().isEmpty() &&
                (req.getOrder().equalsIgnoreCase("asc")|| req.getOrder().equalsIgnoreCase("desc")) &&
                ObjectUtil.isNotNull(req.getOrder()) && !req.getOrder().trim().isEmpty()) {
            //修改字段，和数据库字段进行统一
            req.setColumn(req.getColumn().replaceAll("[A-Z]", "_$0").toLowerCase());
            req.setOrder(req.getOrder().toLowerCase());
        }
        Page<LogSummaryDto> page = PageFactory.getDefaultPage(req.getPageNo(), req.getPageSize());

        List<LogSummaryDto> logSummaryList=logSummaryMapper.RecordSumByOrderId(req,(req.getPageNo()-1)*req.getPageSize(), req.getPageSize());
        LogSummaryDto dto=logSummaryMapper.RecordSumByOrderIdSum(req);
        page.setTotal(dto.getCount());
        page.setRecords(logSummaryList);
        return PageResultFactory.createPageResult(page);
    }

    @Override
    public LogSummaryDto RecordSumByOrderIdCount(LogSummaryReq req) {
        if (ObjectUtil.isNotNull(req.getColumn()) && !req.getColumn().trim().isEmpty() &&
                (req.getOrder().equalsIgnoreCase("asc")|| req.getOrder().equalsIgnoreCase("desc")) &&
                ObjectUtil.isNotNull(req.getOrder()) && !req.getOrder().trim().isEmpty()) {
            //修改字段，和数据库字段进行统一
            req.setColumn(req.getColumn().replaceAll("[A-Z]", "_$0").toLowerCase());
            req.setOrder(req.getOrder().toLowerCase());
        }
//        Calendar calendarBegin = DateUtil.parseByPatterns(DateUtil.endOfYear(DateTimeUtil.getCurrentDateTime()).toString(), "yyyy-MM-dd hh:mm:ss");
//        Date time = calendarBegin.getTime();
//        Calendar calendarEnd = DateUtil.parseByPatterns(DateUtil.beginOfYear(DateTimeUtil.getCurrentDateTime()).toString(), "yyyy-MM-dd hh:mm:ss");
//        Date time1 = calendarEnd.getTime();
//        req.setStartTime(DateTimeUtil.TimeDateToString(time));
//        req.setEndTime(DateTimeUtil.TimeDateToString(time1));
        LogSummaryDto dto=logSummaryMapper.RecordSumByOrderIdSum(req);
        return dto;
    }




    //本地主机返回出入库结果
    @Transactional(rollbackFor = Exception.class)
    public Boolean processInventoryRecords(OutInLogsReq req) {
        //前提条件：判断单子是否记账，如果记账之后则直接忽略掉

        //1.判断是否有单据，order对象是否为空，如果不为空则进行处理
        OrderReq order = req.getOrder();
        boolean a=true;
        boolean b=true;
        boolean c=true;
        boolean c1=true;
        if (ObjectUtil.isNotNull(order)){

            //设置出入库仓库以及出入库数量
//            List<DetailJsonReq> detailJson = order.getDetailJson();
//            String jsonString = JSONObject.toJSONString(detailJson);
            List<DetailOrderReq> orderDetailList = order.getOrderDetail();
            OrderMain one = orderMainService.getOne(new LambdaQueryWrapper<OrderMain>()
                    .eq(OrderMain::getId, order.getId()));
            if (ObjectUtil.isNotNull(one.getManualState()) && one.getManualState()==1){
                return true;
            }
            //获取组织机构id，获取组织机构名称
            Long orgId=one.getOrderType().equals("in")? one.getEndOrgId():one.getStartOrgId();
            PubOrg pubOrg = pubOrgService.PubOrgExist(orgId);
            one.setPrice(order.getPrice());
            if (ObjectUtil.isNull(one.getActualQuantity())){
                one.setActualQuantity(0);
            }
//            one.setActualQuantity(order.getActualQuantity()+one.getActualQuantity());
//            one.setDetailJson(jsonString);
            one.setActualQuantity(order.getActualQuantity());
            one.setOrderState(one.getOrderState());
            one.setOrderState("finished");
            one.setUpdateTime(DateTimeUtil.getCurrentDateTime());
            a=orderMainService.updateById(one);
            List<OrderDetail> detailList = orderDetailService
                    .list(new LambdaQueryWrapper<OrderDetail>().eq(OrderDetail::getOrderId, one.getId()));
            for (OrderDetail orderDetail:detailList) {
                boolean flag=false;
                for (DetailOrderReq detailReq:orderDetailList) {
                    if (detailReq.getId().equals(String.valueOf(orderDetail.getId()))){
                        if (ObjectUtil.isNull(orderDetail.getActualNum())){
                            orderDetail.setActualNum(0);
                        }
                        List<DetailJsonReq> detailJson = detailReq.getDetailJson();
                        detailJson.forEach(detailJsonReq -> detailJsonReq.setModifyQuantity(detailJsonReq.getNum()));

//                        orderDetail.setModifyQuantity(orderDetail.getActualNum()+detailReq.getActualNum());
                        orderDetail.setDetailJson(JSONObject.toJSONString(detailJson));
                        orderDetail.setModifyQuantity(detailReq.getActualNum());
                        orderDetail.setActualNum(detailReq.getActualNum());
                        orderDetail.setActualTotalPrice(detailReq.getPrice());
                        orderDetail.setUpdateTime(DateTimeUtil.getCurrentDateTime());
                        flag=true;
                        break;
                    }
                }
                if (!flag && ObjectUtil.isNull(orderDetail.getActualNum())){
                    orderDetail.setActualNum(0);
                    orderDetail.setModifyQuantity(0);
                    orderDetail.setActualTotalPrice(BigDecimal.ZERO);
                    orderDetail.setUpdateTime(DateTimeUtil.getCurrentDateTime());
                }
            }
            b=orderDetailService.updateBatchById(detailList);

            //2.判断业务类型,如果是采购，更新装备库存表
            if (order.getBussinessType().equals("purchase") ||order.getBussinessType().equals("gift")){
                List<PurchaseEqsReq> purchaseList = order.getPurchaseList();
                List<Inventory> collect1=new ArrayList<>();
                List<WarehouseInventory> warehouseInventoryList=new ArrayList<>();
                for (PurchaseEqsReq eqsReq:purchaseList) {
                    Inventory inventory = new Inventory();
                    if (ObjectUtil.isNotNull(eqsReq.getProductionDate()) && !eqsReq.getProductionDate().trim().isEmpty()){
                        try {
                            if (eqsReq.getProductionDate().contains("-")){
                                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
                                inventory.setProductionDate(format.parse(eqsReq.getProductionDate()));
                            }else {
                                SimpleDateFormat sdf = new SimpleDateFormat("E MMM dd HH:mm:ss z yyyy", Locale.ENGLISH);
                                inventory.setProductionDate(sdf.parse(eqsReq.getProductionDate()));
                            }
                        } catch (ParseException e) {
                            throw new RuntimeException(e);
                        }
                    }
                    WarehouseInventory warehouseInventory = new WarehouseInventory();
                    BeanPlusUtil.copyProperties(eqsReq,warehouseInventory);
                    warehouseInventory.setLocationState("in");
                    warehouseInventory.setLocationType("0");
                    warehouseInventory.setOrgName(ObjectUtil.isNotNull(pubOrg.getDName())?pubOrg.getDName():pubOrg.getOrgName());
                    warehouseInventory.setOrgId(order.getOrgId());
                    warehouseInventory.setFlag(0);
                    warehouseInventory.setEpcType(0);
                    warehouseInventory.setCreateTime(DateTimeUtil.getCurrentDateTime());
                    warehouseInventory.setUpdateTime(DateTimeUtil.getCurrentDateTime());

                    if (ObjectUtil.isNotNull(eqsReq.getShelfRow())&& ObjectUtil.isNotNull(eqsReq.getShelfColumn()) && ObjectUtil.isNotNull(eqsReq.getShelfRange())){
                        String shelfLocation= eqsReq.getShelfRow()+"/"+eqsReq.getShelfColumn()+"/"+eqsReq.getShelfRange();
                        warehouseInventory.setShelfLocation(shelfLocation);
                        warehouseInventory.setShelfColumn(eqsReq.getShelfColumn());
                        warehouseInventory.setShelfRow(eqsReq.getShelfRow());
                        warehouseInventory.setShelfRange(eqsReq.getShelfRange());
                    }
                    warehouseInventoryList.add(warehouseInventory);

                    inventory.setEpc(eqsReq.getEpc());
                    inventory.setTypeId(eqsReq.getTypeId());
                    inventory.setSizeId(eqsReq.getSizeId());
                    inventory.setEpcType(0);
                    inventory.setMaintenancePeriod(eqsReq.getMaintenancePeriod());
                    inventory.setWarrantyPeriod(eqsReq.getWarrantyPeriod());
                    inventory.setProperty(eqsReq.getProperty());
                    inventory.setLocationId(eqsReq.getLocationId());
                    inventory.setSupplierId(eqsReq.getSupplierId());
                    inventory.setPrice(eqsReq.getPrice());
//                    BeanPlusUtil.copyProperties(eqsReq, inventory);
                    inventory.setId(UUID.randomUUID().toString());
                    inventory.setCreateTime(DateTimeUtil.getCurrentDateTime());
                    inventory.setState("normal");
                    inventory.setBussinessState("normal");
                    inventory.setLocationState("in");
                    inventory.setLocationType(0);
                    inventory.setTypeName(eqsReq.getTypeName());
                    inventory.setSizeName(eqsReq.getSizeName());
                    inventory.setSupplierName(eqsReq.getSupplierName());
                    inventory.setLocationName(eqsReq.getLocationName());
                    inventory.setShelfId(eqsReq.getShelfId());
                    inventory.setInstantiationState(eqsReq.getInstantiationState());

                    if (ObjectUtil.isNotNull(eqsReq.getBoxMarkId()) || !StrUtil.isEmpty(eqsReq.getBoxMarkId())){
                        inventory.setBoxMarkId(eqsReq.getBoxMarkId());
                        inventory.setIsInBox(1);
                    }
                    if (ObjectUtil.isNotNull(eqsReq.getShelfRow())&& ObjectUtil.isNotNull(eqsReq.getShelfColumn()) && ObjectUtil.isNotNull(eqsReq.getShelfRange())){
                        String shelfLocation= eqsReq.getShelfRow()+"/"+eqsReq.getShelfColumn()+"/"+eqsReq.getShelfRange();
                        inventory.setShelfLocation(shelfLocation);
                        inventory.setShelfColumn(eqsReq.getShelfColumn());
                        inventory.setShelfRow(eqsReq.getShelfRow());
                        inventory.setShelfRange(eqsReq.getShelfRange());
                    }
                    inventory.setOrgId(order.getOrgId());
                    collect1.add(inventory);
                }
//                c1 = warehouseInventoryService.saveBatch(warehouseInventoryList);
//                c=inventoryService.saveBatch(collect1);
                //将新增装备存入redis中，在记账的时候取出来直接进行记账
                outInRecordRedisCache.addInvRecord(order.getId(),collect1,DateTimeUtil.TimeDateToLong(new Date()));
                outInRecordRedisCache.addInvWareRecord(order.getId(),warehouseInventoryList,DateTimeUtil.TimeDateToLong(new Date()));

            }


        }

        //3.处理出入库记录对象
        //判断出入库记录是否为空
//        List<NormalInOutDto> normalInOutDtos=new ArrayList<>();
                boolean d=true;
        if(ObjectUtil.isNotNull(req.getLogList()) && req.getLogList().size()>0){
//            normalInOutDtos = saveInOutRecords(req);
            d = saveInOutRecordsToRedis(req);
        }

        //4.对日常出入库记录进行装备汇总统计
//        boolean d=true;
//        if (normalInOutDtos.size()>0){
//            String outInState = normalInOutDtos.get(0).getOutInState();
//            d = updateNumToSum(outInState, normalInOutDtos);
//        }

        return a && b && c && c1 && d;
    }


    @Override
    public PageResult<LogSummary> ShowInOutRecords(LogSummaryReq req) {
        int size=logSummaryMapper.ShowInOutRecordsSum(req.getOrgId(), req.getSizeId(),
                req.getTypeId(),req.getPrice());
        Page<LogSummary> page = PageFactory.getDefaultPage(req.getPageNo(), req.getPageSize());
        List<LogSummary> list=logSummaryMapper.ShowInOutRecords(req.getOrgId(), req.getSizeId(),
                req.getTypeId(),req.getPrice(),(req.getPageNo()-1)*req.getPageSize(),req.getPageSize());
        page.setRecords(list);
        page.setTotal(size);
        return PageResultFactory.createPageResult(page);
    }


    private OrderLog addLog(LogSummary logSummary,String string){
        OrderLog orderLog = new OrderLog();
        orderLog.setId(UUID.randomUUID().toString());
        orderLog.setHistoryMsg(string);
        orderLog.setOrderCode(logSummary.getOrderCode());
        orderLog.setBussinessType(logSummary.getBussinessType());
        orderLog.setOrderType(logSummary.getOutInState());
        orderLog.setProcessType("OutAndIn");
        orderLog.setOrgId(logSummary.getOrgId());
        orderLog.setOrgName(logSummary.getOrgName());
        orderLog.setOrderId(logSummary.getOrderMainId());
        orderLog.setCreateTime(DateTimeUtil.getCurrentDateTime());
        return orderLog;
    }
//    创建logsummary
    private LogSummary saveLogSummary(SummaryLogReq req){
        LogSummary logSummary = new LogSummary();
        BeanPlusUtil.copyProperties(req,logSummary);
        logSummary.setOutInState(req.getOutInState());
        logSummary.setLocationId(req.getLocationId());
        logSummary.setLocationName(req.getLocationName());
        logSummary.setCreateTime(DateTimeUtil.getCurrentDateTime());
        logSummary.setUpdateTime(DateTimeUtil.getCurrentDateTime());
        logSummary.setBussinessType(req.getBussinessType());
        logSummary.setOrgId(req.getOrgId());
        logSummary.setOrgName(req.getOrgName());
        logSummary.setDeviceType(req.getDeviceType());
        logSummary.setLocationType(req.getLocationType());
        return logSummary;
    }

    private Inventory saveInventory(Long orgId,String locationId,SummaryLogReq logreq,DetailLogReq req,Map<String, String> map,String outInState){
        Inventory inventory = new Inventory();
        BeanPlusUtil.copyProperties(req,inventory);
        inventory.setId(req.getInventoryId());
        inventory.setLocationState(outInState);
        inventory.setLocationId(locationId);
        inventory.setEpc(req.getEpc());
        inventory.setState(map.get("state"));
        inventory.setOrgId(orgId);
        inventory.setBussinessState(map.get("bussinessState"));
        inventory.setBussinessType(logreq.getBussinessType());
        return inventory;
    }
    private WarehouseInventory saveWarehouseInventory(Long orgId,String locationId,SummaryLogReq logreq,DetailLogReq req,Map<String, String> map,String outInState){
        WarehouseInventory warehouseInventory=new WarehouseInventory();
        BeanPlusUtil.copyProperties(req,warehouseInventory);
        warehouseInventory.setLocationState(outInState);
        warehouseInventory.setLocationId(locationId);
        warehouseInventory.setEpc(req.getEpc());
        warehouseInventory.setOrgId(orgId);
        return warehouseInventory;
    }

    private Map<String,String> setState(String outInState,String bussinessType){
        Map<String,String> map=new HashMap<>();
        String state="normal";
        String bussinessState="";
        if (outInState.equals("in")){
            switch (bussinessType){
                case "return":
                case "gift":
                case "other":
                case "repair":
                    bussinessState="normal";
                    break;
                case "allocate":
                    bussinessState="allocate";
                    break;

            }
        }else {
            switch (bussinessType){
                case "use":
                    bussinessState="use";
                    break;
                case "allocate":
                    bussinessState="allocate";
                    break;
                case "repair":
                    bussinessState="repair";
                    break;
                case "destruction":
                    state="destory";
                    bussinessState="destruction";
                    break;
                case "other":
                    bussinessState="normal";
                    break;
                case "quick":
                    bussinessState="quick";
                    break;
            }
        }
        map.put("state",state);
        map.put("bussinessState",bussinessState);
        return map;
    }


//    对库存汇总表进行更新（只限于日常出入库）
    public boolean updateNumToSum(String outInState,List<NormalInOutDto> inventorySumDtos) {

        List<NormalInOutDto> groupedResult = inventorySumDtos.stream()
                .collect(Collectors.groupingBy(dto -> dto.getOrgId() + "_" + dto.getLocationId() + "_" +
                                dto.getSizeId() + "_" + dto.getTypeId() + "_" + dto.getPrice(),
                        Collectors.collectingAndThen(Collectors.toList(), group -> {
                            NormalInOutDto result = new NormalInOutDto();
                            result.setOrgId(group.get(0).getOrgId());
                            result.setOrgName(group.get(0).getOrgName());
                            result.setOrgCode(group.get(0).getOrgCode());
                            result.setSizeName(group.get(0).getSizeName());
                            result.setTypeName(group.get(0).getTypeName());
                            result.setLocationId(group.get(0).getLocationId());
                            result.setSizeId(group.get(0).getSizeId());
                            result.setTypeId(group.get(0).getTypeId());
                            result.setPrice(group.get(0).getPrice());
                            result.setValuekey(result.getOrgCode()+result.getLocationId()+result.getTypeId()+result.getSizeId()+result.getPrice());
                            result.setNumber(group.stream().mapToInt(NormalInOutDto::getNumber).sum());
                            return result;
                        })))
                .values().stream()
                .collect(Collectors.toList());
        //将查询条件存入searchCriteria中一次性查询出满足条件的数据
        List<Object[]> searchCriteria = new ArrayList<>();
        for (NormalInOutDto groupedDto : groupedResult) {
            Object[] criteria = new Object[]{groupedDto.getOrgId(), groupedDto.getLocationId(),
                    groupedDto.getTypeId(),groupedDto.getSizeId(), groupedDto.getPrice()};
            searchCriteria.add(criteria);
        }
        //满足条件的数据
        List<InventorySummary> inventorySummaryList = inventorySummaryMapper.selectSumByItems(searchCriteria);
        List<InventorySummary> addList=new ArrayList<>();
        List<InventorySummary> updateList=new ArrayList<>();
        //遍历两者，判断数据库中是否全部存在，如果不存在，则进行增加数据操作，如果存在，则更新数据即可
        for (NormalInOutDto outDto:groupedResult) {
            boolean flag=false;
            for (InventorySummary is:inventorySummaryList) {
                if (outDto.getOrgId().equals(is.getOrgId()) && outDto.getLocationId().equals(is.getLocationId())
                        && outDto.getSizeId().equals(is.getSizeId()) && outDto.getTypeId().equals(is.getTypeId())
                        && outDto.getPrice().compareTo(is.getUnitPrice())==0){
                    if (outInState.equals("in")){
                        is.setOutboundNumber(is.getOutboundNumber()-outDto.getNumber());
                        is.setStockNumber(is.getStockNumber()+outDto.getNumber());
                        is.setPrice(is.getPrice().add(BigDecimal.valueOf(outDto.getNumber()).multiply(outDto.getPrice())) );
                    }else {
                        is.setOutboundNumber(is.getOutboundNumber()+outDto.getNumber());
                        is.setStockNumber(is.getStockNumber()-outDto.getNumber());
                        is.setPrice(is.getPrice().subtract(BigDecimal.valueOf(outDto.getNumber()).multiply(outDto.getPrice())) );
                    }
                    updateList.add(is);
                    flag=true;
                    break;
                }
            }
            if (!flag){
                InventorySummary inventorySummary = new InventorySummary();
                BeanPlusUtil.copyProperties(outDto,inventorySummary);
                if (outInState.equals("in")){
                    inventorySummary=inventorySummaryService.createInventorySummary(outDto.getOrgId(),outDto.getOrgName(),outDto.getOrgCode(),
                            outDto.getTypeId(),outDto.getTypeName(),outDto.getSizeId(),outDto.getSizeName(),
                            outDto.getLocationId(),outDto.getLocationName(),outDto.getNumber(),0,
                            outDto.getPrice(),0,0,0,0,0,0,0,"0");

                }else {
                    inventorySummary=inventorySummaryService.createInventorySummary(outDto.getOrgId(),outDto.getOrgName(),outDto.getOrgCode(),
                            outDto.getTypeId(),outDto.getTypeName(),outDto.getSizeId(),outDto.getSizeName(),
                            outDto.getLocationId(),outDto.getLocationName(),0,outDto.getNumber(),
                            outDto.getPrice(),0,0,0,outDto.getNumber(),outDto.getNumber(),0,0,"0");

                }
                addList.add(inventorySummary);
            }
        }
        boolean a=true;
        if (addList.size()>0){
            boolean b = inventorySummaryService.saveBatch(addList);
            a = b;
        }
        if (updateList.size()>0){
            boolean b = inventorySummaryService.updateBatchById(updateList);
            a = a && b;
        }
        return a;
    }


    public boolean saveInOutRecordsToRedis(OutInLogsReq req) {

        //返回结果，用于日常出入库时计算更新库存汇总表
        List<SummaryLogReq> logSummaryList = req.getLogList();

        //遍历logSummaryList查询出没有单据的作为日常出入库，并再次存放到list中，后面用于进行修改库存汇总
        //返回returnList结果，用于日常出入库时计算更新库存汇总表
//        List<NormalInOutDto> returnList=new ArrayList<>();
        //存一个list用于修改库存inventory表的数据(采购时那么这个inventoryList就为空)
        List<Inventory> inventoryList=new ArrayList<>();
        List<OrderLog> orderLogList=new ArrayList<>();

        List<LogSummary> sumList=new ArrayList<>();
        OrderMain ordermain=null;
        for (SummaryLogReq logreq:logSummaryList) {
            if (ObjectUtil.isNotNull(logreq.getPicture())){
                byte[] imageBytes = Base64.getDecoder().decode(logreq.getPicture());
                MultipartFile picture = new MockMultipartFile("sample", imageBytes);
                // 图片文件保存路径和文件名
                SysFileInfoReq sysFileInfoReq = new SysFileInfoReq();
                sysFileInfoReq.setFileBucket("jyzb");
                sysFileInfoReq.setFileLocation(3);
                sysFileInfoReq.setFileObjectName("OutInPhoto/"+logreq.getOrgId()+"/");
                SysFileInfoResp sysFileInfoResp = sysFileInfoService.uploadFile(picture, sysFileInfoReq);
                logreq.setPicture(sysFileInfoResp.getAccessUrl());
            }

            if (ObjectUtil.isNotNull(logreq.getOrderMainId())){

                ordermain = orderMainService.getById(logreq.getOrderMainId());
                if (ObjectUtil.isNotNull(ordermain.getManualState()) && ordermain.getManualState()==1){
                    continue;
                }
            }

            //如果类型为normal，那么则表示作为日常出入库的记录，否则则作为单据的出入库记录
            List<DetailLogReq> logList = logreq.getLogDetailList();

            //出入库list
            List<LogDetail> collect = new ArrayList<>();
            logreq.setLocationType(0);
            logreq.setDeviceType(ObjectUtil.isNotNull(logreq.getDeviceType())?logreq.getDeviceType():3);
            LogSummary logSummary = saveLogSummary(logreq);

            String string="";
            String stringQuick="";
            if (logSummary.getOutInState().equals("in")){
                string=string+logSummary.getLocationName()+"：入库【"+logSummary.getEquipmentList()+"】，数量："+logSummary.getNumber()+"\n";
            }else {
                string=string+logSummary.getLocationName()+"：出库【"+logSummary.getEquipmentList()+"】，数量："+logSummary.getNumber()+"\n";
            }

            //如果是有单据id的，先不存数据库，直接存入redis中
            LogSummaryReq logSummaryReq = new LogSummaryReq();
            if (ObjectUtil.isNull(logreq.getOrderMainId()) || ObjectUtil.isEmpty(logreq.getOrderMainId())){

                sumList.add(logSummary);
                logSummaryService.saveBatch(sumList);
                sumList.clear();
            }else {
                BeanPlusUtil.copyProperties(logSummary,logSummaryReq);
            }

            Map<String, String> map = setState(logreq.getOutInState(), logreq.getBussinessType());

            List<LogDetailReq> detailReqList=new ArrayList<>();
            for (DetailLogReq detailLogReq : logList) {
                //将所有装备信息进行存放（为后面计算汇总信息）
                //判断logSummary是否为采购,快速移库，和领用出库
                //如果是采购则不处理，因为采购的inventory是跟着单子来处理的，其他的单子直接根据出入库记录来处理
                if (!logreq.getBussinessType().equals("purchase") && !logreq.getBussinessType().equals("gift") && !logreq.getBussinessType().equals("quick") ){
//                    if (logreq.getOutInState().equals("in")){
                    Inventory inventory = saveInventory(logreq.getOrgId(),logreq.getLocationId(),logreq,detailLogReq, map, logSummary.getOutInState());
                    inventoryList.add(inventory);
                }
                //存放logdetail信息
                LogDetail logDetail = new LogDetail();
                BeanPlusUtil.copyProperties(detailLogReq, logDetail);
                logDetail.setSummaryId(logSummary.getId());
                logDetail.setOrgId(logSummary.getOrgId());
                logDetail.setCreateTime(DateTimeUtil.getCurrentDateTime());
                logDetail.setBussinessType(logreq.getBussinessType());
                logDetail.setOutInState(logreq.getOutInState());

                //无单据的直接创建批量保存
                if (ObjectUtil.isNull(logreq.getOrderMainId()) || ObjectUtil.isEmpty(logreq.getOrderMainId())){
                    collect.add(logDetail);
                }else {
                    LogDetailReq logDetailReq = new LogDetailReq();
                    BeanPlusUtil.copyProperties(logDetail,logDetailReq);
                    detailReqList.add(logDetailReq);
                }

            }
            logSummaryReq.setLogList(detailReqList);
            boolean b = logDetailService.saveBatch(collect);
            //创建出入库日志
            List<OrderLogReq> orderLogReqList=new ArrayList<>();

            if (ObjectUtil.isNull(logreq.getOrderMainId()) || ObjectUtil.isEmpty(logreq.getOrderMainId())){
                OrderLog orderLog = addLog(logSummary,string);
                orderLogList.add(orderLog);
            }else {
                OrderLog orderLog = addLog(logSummary,string);
                OrderLogReq orderLogReq = new OrderLogReq();
                BeanPlusUtil.copyProperties(orderLog,orderLogReq);
                orderLogReqList.add(orderLogReq);
                logSummaryReq.setOrderLogList(orderLogReqList);
            }
            if (ObjectUtil.isNotNull(logreq.getOrderMainId())){
                //添加到redis中去（key是orderMainId）
                outInRecordRedisCache.addRecord(logreq.getOrderMainId(),logSummaryReq,DateTimeUtil.TimeDateToLong(DateTimeUtil.getCurrentDateTime()));
            }
        }

        if (orderLogList.size()>0){
            boolean b = orderLogService.saveBatch(orderLogList);
        }

        //修改inventory表中的数据（判断是否记账）

        if (inventoryList.size()>0){
            if (ObjectUtil.isNotNull(ordermain) && (ObjectUtil.isNull(ordermain.getManualState()) || ordermain.getManualState()!=1)){
                outInRecordRedisCache.addInvRecord(ordermain.getId(),inventoryList,DateTimeUtil.TimeDateToLong(DateTimeUtil.getCurrentDateTime()));
            }else {
                LambdaUpdateWrapper<Inventory> normalInWrapper1 = Wrappers.lambdaUpdate();
                LambdaUpdateWrapper<WarehouseInventory> normalInWrapper2 = Wrappers.lambdaUpdate();
                for (Inventory inventory:inventoryList) {
                    if (inventory.getBussinessType().equals("normal")) {
                        normalInWrapper1.or().eq(Inventory::getEpc,inventory.getEpc())
                                .set(Inventory::getLocationState,inventory.getLocationState())
                                .set(Inventory::getBussinessState,inventory.getBussinessState())
                                .set(Inventory::getState,inventory.getState());

                        normalInWrapper2.or().eq(WarehouseInventory::getEpc,inventory.getEpc())
                                .set(WarehouseInventory::getLocationState,inventory.getLocationState());

                    }

                }
                if (!normalInWrapper1.isEmptyOfWhere()){
                    inventoryService.update(normalInWrapper1);
                    warehouseInventoryService.update(normalInWrapper2);
                }
            }

        }

        return true;
    }

    private LambdaQueryWrapper<LogSummary> createWrapper(LogSummaryReq req) {
        LambdaQueryWrapper<LogSummary> eq = new LambdaQueryWrapper<LogSummary>()
                .eq(ObjectUtil.isNotNull(req.getOrgId()),LogSummary::getOrgId,req.getOrgId())
                .eq(LogSummary::getLocationType,req.getLocationType())
                .eq(ObjectUtil.isNotNull(req.getOrderMainId()),LogSummary::getOrderMainId,req.getOrderMainId())
                .eq(ObjectUtil.isNotNull(req.getBussinessType()) && !req.getBussinessType().trim().isEmpty(),LogSummary::getBussinessType,req.getBussinessType())
                .eq(ObjectUtil.isNotNull(req.getOutInState()) && !req.getOutInState().trim().isEmpty(),LogSummary::getOutInState,req.getOutInState())
                .eq(ObjectUtil.isNotNull(req.getLocationId()),LogSummary::getLocationId,req.getLocationId())
                .like(ObjectUtil.isNotNull(req.getUserName()),LogSummary::getUserName,req.getUserName())
                .ge(ObjectUtil.isNotNull(req.getStartTime()),LogSummary::getUseTime,req.getStartTime())
                .le(ObjectUtil.isNotNull(req.getEndTime()),LogSummary::getUseTime,req.getEndTime())
                .like(ObjectUtil.isNotNull(req.getTypeName()),LogSummary::getEquipmentList,req.getTypeName())
                .last("order by " + req.getColumn() + " " + req.getOrder());
        return eq;
    }



    @Override
    @Transactional
    public Boolean addLogSummaryByInv(List<InventoryReq> list,String orderId,String orderCode,String bussinessType,Integer deviceType,String locationType,String userName,String orgName,String device) {
        List<LogSummaryReq> logList=new ArrayList<>();

        Map<String,LogSummaryReq> logMap=new HashMap<>();
        for (InventoryReq inv:list) {

            logMap=setLogSummaryToMap(logMap,userName,orgName,inv.getLocationId(),bussinessType,inv.getTypeName(),
                    inv.getLocationName(),orderId,orderCode,inv.getOrgId(),inv.getLocationState(),deviceType,1,locationType,inv.getCreateTime(),inv.getPhoto(),device);
        }
        logMap = setLogDetailToMap(list, logMap, bussinessType);

        List<String> keys = new ArrayList<>(logMap.keySet());
        if (CollectionUtil.isNotEmpty(keys)){
            // 根据 key 获取对应的 value 并存入 List 中
            List<LogSummaryReq> values = new ArrayList<>();
            for (String key : keys) {
                LogSummaryReq value = logMap.get(key);
                values.add(value);
            }
            logList.addAll(values);

        }
        if (CollectionUtil.isNotEmpty(logList)){
            addLogSummaryByClass(logList,bussinessType);
        }


        return true;
    }

    @Override
    public Map<String, LogSummaryReq> setLogSummaryToMap(Map<String,LogSummaryReq> logMap,String userName,
                                                         String orgName,String locationId,String bussinessType,
                                                         String typeName,String locationName, String orderId,
                                                         String orderCode,Long orgId,String locationState,
                                                         Integer deviceType,Integer sumNum,String locationType,
                                                         Date createTime,String photo,String device) {
        if (logMap.containsKey(locationId+locationState)){
            LogSummaryReq logSummaryReq = logMap.get(locationId+locationState);
            logSummaryReq.setNumber(logSummaryReq.getNumber()+sumNum);
            List<String> list = Arrays.asList(logSummaryReq.getEquipmentList().split(","));
            List<String> collect = list.stream().distinct().collect(Collectors.toList());
            if (!collect.contains(typeName)){
                logSummaryReq.setEquipmentList(logSummaryReq.getEquipmentList()+","+typeName);
            }
            logSummaryReq.setBussinessType(bussinessType);
//            logSummaryReq.setTypeName(logSummaryReq.getTypeName()+","+typeName);
            logMap.put(locationId+locationState,logSummaryReq);
        }else {
            //创建汇总map
            LogSummaryReq logSummaryReq = setLogSummary(userName,orgName,typeName,locationId,locationName,
                    sumNum,orderId,orderCode,bussinessType,orgId,locationState,deviceType,locationType,createTime,photo,device);
            logMap.put(locationId+locationState,logSummaryReq);
        }
        return logMap;
    }

    @Override
    public Map<String,LogSummaryReq> setLogDetailToMap (List<InventoryReq> list,Map<String,LogSummaryReq> logMap,String bussinessType){
        for (InventoryReq inv:list){
            //查询仓库map并且将记账记录添加
            LogSummaryReq lsReq = logMap.get(inv.getLocationId()+inv.getLocationState());
            List<LogDetailReq> logDetailList = lsReq.getLogList();
            LogDetailReq logDetailReq = new LogDetailReq();
            BeanPlusUtil.copyProperties(inv,logDetailReq);
            logDetailReq.setOutInState(inv.getLocationState());
            logDetailReq.setPicture(ObjectUtil.isNotEmpty(inv.getPhoto())?inv.getPhoto():null);
            logDetailReq.setBussinessType(bussinessType);
            logDetailReq.setCreateTime(ObjectUtil.isNotNull(inv.getCreateTime())?inv.getCreateTime():DateTimeUtil.getCurrentDateTime());
            if (CollectionUtil.isEmpty(logDetailList)) {
                lsReq.setLogList(new ArrayList<>());
                logDetailList = lsReq.getLogList();
            }
            logDetailList.add(logDetailReq);
            lsReq.setLogList(logDetailList);
            logMap.put(inv.getLocationId()+inv.getLocationState(),lsReq);
        }
        return logMap;
    }



    public Map<String,List<String>> addLogSummaryByClass(List<LogSummaryReq> list,String bussinessType){
        //创建一个List，存放EPC，快速移库时需要，并且返回
        Map<String,List<String>> map=new HashMap<>();
        List<LogDetail> logDetailList=new ArrayList<>();
        List<OrderLog> orderLogList=new ArrayList<>();
        for (LogSummaryReq ls:list) {

            //判断ls中的location是否存在，如果存在则
            LogSummary logSummary = new LogSummary();
            BeanPlusUtil.copyProperties(ls,logSummary);

            if (ObjectUtil.isNotNull(ls.getPicture()) && ObjectUtil.isNotEmpty(ls.getPhoto())){
                byte[] imageBytes = Base64.getDecoder().decode(ls.getPicture());
                MultipartFile picture = new MockMultipartFile("sample", imageBytes);
                // 图片文件保存路径和文件名
                SysFileInfoReq sysFileInfoReq = new SysFileInfoReq();
                sysFileInfoReq.setFileBucket("jyzb");
                sysFileInfoReq.setFileLocation(3);
                sysFileInfoReq.setFileObjectName("OutInPrice/"+ls.getOrgId()+"/");
                SysFileInfoResp sysFileInfoResp = sysFileInfoService.uploadFile(picture, sysFileInfoReq);
                logSummary.setPicture(sysFileInfoResp.getAccessUrl());
//                ls.setPicture("111");
            }else {
                logSummary.setPicture(ls.getPhoto());
            }
            //判断是否是快速移库
            logSummary.setCreateTime(ObjectUtil.isNotNull(logSummary.getCreateTime())?logSummary.getCreateTime():DateTimeUtil.getCurrentDateTime());
            logSummaryService.save(logSummary);

            //单子记账日志
            if (CollectionUtil.isNotEmpty(ls.getOrderLogList())){

                for (OrderLogReq ol: ls.getOrderLogList()) {
                    OrderLog orderLog = new OrderLog();
                    BeanPlusUtil.copyProperties(ol,orderLog);
                    orderLog.setCreateTime(DateTimeUtil.getCurrentDateTime());
                    orderLogList.add(orderLog);
                }
            }
            //出入库记账日志
            if (CollectionUtil.isNotEmpty(ls.getLogList())){
                List<String> epcList=new ArrayList<>();
                for (LogDetailReq ld:ls.getLogList()) {
                    LogDetail logDetail = new LogDetail();
                    BeanPlusUtil.copyProperties(ld,logDetail);
                    logDetail.setSummaryId(logSummary.getId());
                    logDetail.setCreateTime(DateTimeUtil.getCurrentDateTime());
                    logDetail.setBussinessType(bussinessType);
                    logDetailList.add(logDetail);
                    epcList.add(ld.getEpc());
                }
                //返回数据map
                String key=ls.getLocationId();
                if (map.containsKey(key)){
                    List<String> collect = map.get(key);
                    collect.addAll(epcList);
                    map.put(key,collect);
                }else {
                    map.put(key,epcList);
                }
            }

        }

        if (CollectionUtil.isNotEmpty(orderLogList)){
            orderLogService.saveBatch(orderLogList);
        }
        if (CollectionUtil.isNotEmpty(logDetailList)){
            boolean b = logDetailService.saveBatch(logDetailList);
            System.out.println("b = " + b);
        }

        return map;
    }

    public LogSummaryReq setLogSummary(String userName,String orgName, String typeName,String locationId,
                                       String locationName, Integer subNum,String orderId,String orderCode,
                                       String bussinesstype, Long orgId,String outInState,Integer deviceType,
                                       String locationType,Date createTime,String photo,String device){
        LogSummaryReq logSummaryReq = new LogSummaryReq();
        logSummaryReq.setOrgId(orgId);
        logSummaryReq.setBussinessType(bussinesstype);
        logSummaryReq.setOrgName(orgName);
        logSummaryReq.setOrderMainId(orderId);
        logSummaryReq.setOrderCode(orderCode);
        // 4 人工记账
        logSummaryReq.setDeviceType(deviceType);
        logSummaryReq.setLocationId(locationId);
        logSummaryReq.setLocationName(locationName);
        logSummaryReq.setDevice(device);
        logSummaryReq.setLocationType(locationType);
        logSummaryReq.setUseTime(ObjectUtil.isNotNull(createTime)?createTime:DateTimeUtil.getCurrentDateTime());
        logSummaryReq.setEquipmentList(typeName);
        logSummaryReq.setOutInState(outInState);
        logSummaryReq.setNumber(subNum);
        logSummaryReq.setCreateTime(DateTimeUtil.getCurrentDateTime());
        logSummaryReq.setUserName(userName);
        logSummaryReq.setPicture(photo);
        if (deviceType.equals(1)){
            logSummaryReq.setPhoto(photo);
            logSummaryReq.setPicture(null);
        }
        return logSummaryReq;
    }

    @Override
    public List<LogSummaryReq> selectByOrderCode(String bussinessCode,Long orgId,List<String> epcList) {
        return logSummaryMapper.selectByOrderCode(bussinessCode,orgId,epcList);

    }

    //单警柜出入库日志上传
    @Override
    @Transactional
    public Boolean saveOutAndInLogs(List<SummaryLogReq> req) {

        List<LogDetail> collect = new ArrayList<>();
        for (SummaryLogReq logreq:req) {
            PubOrg pubOrg = pubOrgService.PubOrgCodeExist(logreq.getOrgCode());
//            if (ObjectUtil.isNotNull(logreq.getPicture())){
//                byte[] imageBytes = Base64.getDecoder().decode(logreq.getPicture());
//                MultipartFile picture = new MockMultipartFile("sample", imageBytes);
//                // 图片文件保存路径和文件名
//                SysFileInfoReq sysFileInfoReq = new SysFileInfoReq();
//                sysFileInfoReq.setFileBucket("jyzb");
//                sysFileInfoReq.setFileLocation(3);
//                sysFileInfoReq.setFileObjectName("OutInPhoto/"+logreq.getOrgId()+"/");
//                SysFileInfoResp sysFileInfoResp = sysFileInfoService.uploadFile(picture, sysFileInfoReq);
//                logreq.setPicture(sysFileInfoResp.getAccessUrl());
//            }
            List<DetailLogReq> logList = logreq.getLogDetailList();
            logreq.setLocationType(1);
            logreq.setDeviceType(3);
            //出入库list
            LogSummary logSummary = saveLogSummary(logreq);
            logSummary.setOrgId(pubOrg.getOrgId());
            logSummary.setOrgName(pubOrg.getOrgName());
            save(logSummary);

            for (DetailLogReq detailLogReq : logList) {
                //存放logdetail信息
                LogDetail logDetail = new LogDetail();
                BeanPlusUtil.copyProperties(detailLogReq, logDetail);
                logDetail.setSummaryId(logSummary.getId());
                logDetail.setOrgId(logSummary.getOrgId());
                logDetail.setCreateTime(DateTimeUtil.getCurrentDateTime());
                logDetail.setBussinessType(logreq.getBussinessType());
                logDetail.setOutInState(logreq.getOutInState());
                logDetail.setCabinetboxId(logSummary.getLocationId());
                collect.add(logDetail);

            }

        }
        boolean b = logDetailService.saveBatch(collect);

        return true;
    }


}




