package com.junmp.jyzb.service.impl;

import cn.hutool.core.util.ObjectUtil;
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.CabinetLogsRecordReq;
import com.junmp.jyzb.api.bean.query.InAndOutRecordReq.*;
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.service.*;
import com.junmp.jyzb.mapper.LogSummaryMapper;
import com.junmp.jyzb.utils.DateTimeUtil;
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 LogSummarySecondService logSummarySecondService;

    @Resource
    private WarehouseInventoryService warehouseInventoryService;

    @Resource
    private SysFileInfoService sysFileInfoService;

    @Resource
    private LogSummaryMapper logSummaryMapper;

    @Resource
    private OutInRecordRedisCache outInRecordRedisCache;

    //根据条件查询出入库记录(子单的记录)
    @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");
        }

        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())
                .eq(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());

        Page<LogSummary> page = logSummaryService.page(PageFactory.getDefaultPage(req.getPageNo(), req.getPageSize()), eq);
        return PageResultFactory.createPageResult(page);
    }

    @Override
    public LogSummary 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");
        }

        LogSummary logSummary = logSummaryMapper.ShowInOutRecordsByItemsCount(req);

        return ObjectUtil.isNull(logSummary)?new LogSummary():logSummary ;
    }

    //根据条件查询出入库记录(整个单子的汇总记录)
    @Override
    public PageResult<LogSummaryDto> RecordSumByOrderId(LogSummaryReq req) {
        Page<LogSummaryDto> page = PageFactory.getDefaultPage(req.getPageNo(), req.getPageSize());
        List<LogSummaryDto> logSummaryList=logSummaryMapper.RecordSumByOrderId(req,(req.getPageNo()-1)*req.getPageSize(), req.getPageSize());
        int size=logSummaryMapper.RecordSumByOrderIdSum(req);
        page.setTotal(size);
        page.setRecords(logSummaryList);
        return PageResultFactory.createPageResult(page);
    }


    //本地主机返回出入库结果
    @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()));
            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){
                    orderDetail.setActualNum(0);
                    orderDetail.setModifyQuantity(0);
                    orderDetail.setActualTotalPrice(BigDecimal.ZERO);
                    orderDetail.setUpdateTime(DateTimeUtil.getCurrentDateTime());
                }
            }
            b=orderDetailService.updateBatchById(detailList);

            //2.判断业务类型,如果是采购，更新装备库存表
            if (order.getBussinessType().equals("purchase")){
                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 {
                            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
                            inventory.setProductionDate(format.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.setOrgId(order.getOrgId());
                    warehouseInventory.setFlag(0);
                    warehouseInventory.setCreateTime(DateTimeUtil.getCurrentDateTime());
                    warehouseInventory.setUpdateTime(DateTimeUtil.getCurrentDateTime());
                    warehouseInventoryList.add(warehouseInventory);

                    inventory.setEpc(eqsReq.getEpc());
                    inventory.setTypeId(eqsReq.getTypeId());
                    inventory.setSizeId(eqsReq.getSizeId());
                    inventory.setMaintenancePeriod(eqsReq.getMaintenancePeriod());
                    inventory.setWarrantyPeriod(eqsReq.getWarranyPeriod());
                    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.setOrgId(order.getOrgId());
                    collect1.add(inventory);
                }
                c1 = warehouseInventoryService.saveBatch(warehouseInventoryList);
                c=inventoryService.saveBatch(collect1);
            }


        }

        //3.处理出入库记录对象
        //判断出入库记录是否为空
        List<NormalInOutDto> normalInOutDtos=new ArrayList<>();
        if(ObjectUtil.isNotNull(req.getLogList()) && req.getLogList().size()>0){
//            normalInOutDtos = saveInOutRecords(req);
            normalInOutDtos = 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 Boolean processOutInRecords(CabinetLogsRecordReq req) {
        //根据单警柜
        return null;
    }

    @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);
    }



    //    对出入库记录进行分类汇总存储()
//    public List<NormalInOutDto> saveInOutRecords(OutInLogsReq req) {
//
//        //返回结果，用于日常出入库时计算更新库存汇总表
//        List<SummaryLogReq> logSummaryList = req.getLogList();
//
//        //遍历logSummaryList查询出没有单据的作为日常出入库，并再次存放到list中，后面用于进行修改库存汇总
//        //返回returnList结果，用于日常出入库时计算更新库存汇总表
//        List<NormalInOutDto> returnList=new ArrayList<>();
//        //存一个list用于修改库存inventory表的数据(采购时那么这个inventoryList就为空)
//        List<Inventory> inventoryList=new ArrayList<>();
//        //存一个list用于修改库存warehosuseInventory表的数据(采购时那么这个wInventoryList就为空)
//        List<WarehouseInventory> wInbentoryList=new ArrayList<>();
//        List<OrderLog> orderLogList=new ArrayList<>();
//        String orderMainId="";
//
//        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("OutInPrice/"+logreq.getOrgId()+"/");
//                SysFileInfoResp sysFileInfoResp = sysFileInfoService.uploadFile(picture, sysFileInfoReq);
//                logreq.setPicture(sysFileInfoResp.getAccessUrl());
//            }
//
//            if (ObjectUtil.isNotNull(logreq.getOrderMainId())){
//                orderMainId=logreq.getOrderMainId();
//            }
//
//            if (ObjectUtil.isNotEmpty(orderMainId)){
//                ordermain = orderMainService.getById(orderMainId);
//            }
//            //如果类型为normal，那么则表示作为日常出入库的记录，否则则作为单据的出入库记录
//            List<DetailLogReq> logList = logreq.getLogDetailList();
//
//            //出入库list
//            List<LogDetail> collect = new ArrayList<>();
//            LogSummary logSummary = saveLogSummary(logreq,logreq.getLocationId(),logreq.getLocationName(),logreq.getOutInState());
//
//            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";
//            }
//            LogSummary logSummaryQuick=new LogSummary();
//            if (logreq.getBussinessType().equals("quick")){//如果是快速出库的同时需要创建快速入库
//                logSummaryQuick= saveLogSummary(logreq,ordermain.getLocationId(),ordermain.getLocationName(),"in");
//                sumList.add(logSummaryQuick);
//                stringQuick=stringQuick+logSummaryQuick.getLocationName()+"：入库【"+logSummaryQuick.getEquipmentList()+"】，数量："+logSummary.getNumber()+"\n";
//            }
//            sumList.add(logSummary);
//            logSummaryService.saveBatch(sumList);
//            sumList.clear();
//            Map<String, String> map = setState(logreq.getOutInState(), logreq.getBussinessType());
//
//
//            for (DetailLogReq detailLogReq : logList) {
//                //将所有装备信息进行存放（为后面计算汇总信息）
//                if (logreq.getBussinessType().equals("normal")) {
//                    NormalInOutDto normalInOutDto = new NormalInOutDto();
//                    BeanPlusUtil.copyProperties(detailLogReq, normalInOutDto);
//                    normalInOutDto.setLocationId(logSummary.getLocationId());
//                    normalInOutDto.setLocationName(logSummary.getLocationName());
//                    normalInOutDto.setOrgId(logSummary.getOrgId());
//                    normalInOutDto.setOrgName(logSummary.getOrgName());
//                    normalInOutDto.setNumber(1);
//                    normalInOutDto.setOutInState(logSummary.getOutInState());
//                    returnList.add(normalInOutDto);
//                }
//                //判断logSummary是否为采购,快速移库，和领用出库
//                //如果是采购则不处理，因为采购的inventory是跟着单子来处理的，其他的单子直接根据出入库记录来处理
//                if (!logreq.getBussinessType().equals("purchase") && !logreq.getBussinessType().equals("quick") ){
////                    if (logreq.getOutInState().equals("in")){
//                        Inventory inventory = saveInventory(logreq.getOrgId(),logreq.getLocationId(),logreq,detailLogReq, map, logSummary.getOutInState());
//                        inventoryList.add(inventory);
//
//                }
////                //如果是快速移库，那么直接将物资的locationId进行修改
//                if(logreq.getBussinessType().equals("quick")){
//                    Inventory inventory = saveInventory(logreq.getOrgId(),ordermain.getLocationId(),logreq,detailLogReq, map, "in");
//                    inventoryList.add(inventory);
//                }
//                //存放logdetail信息
//                LogDetail logDetail = new LogDetail();
//                LogDetail logDetailQuick=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 (logreq.getBussinessType().equals("quick")){
//                    BeanPlusUtil.copyProperties(logDetail,logDetailQuick);
//                    logDetailQuick.setSummaryId(logSummaryQuick.getId());
//                    logDetailQuick.setOutInState("in");
//                    collect.add(logDetailQuick);
//                }
//                collect.add(logDetail);
//
//            }
//
//            boolean b = logDetailService.saveBatch(collect);
//            //创建出入库日志
//            if (ObjectUtil.isNotNull(logSummary.getOrderMainId())){
//                OrderLog orderLog = addLog(logSummary,string);
//                OrderLog qucik = new OrderLog();
//                if (logreq.getBussinessType().equals("quick")){
//                    qucik=addLog(logSummaryQuick,stringQuick);
//                    orderLogList.add(qucik);
//                }
//                orderLogList.add(orderLog);
//            }
//        }
//        //判断是否有orderId的单子出入库，如果有则直接添加
//        if (orderLogList.size()>0){
//            boolean b = orderLogService.saveBatch(orderLogList);
//        }
//
//        //修改inventory表中的数据（如果不为空则表示不是采购单或者已经将采购单的信息过滤掉）
//
//        if (inventoryList.size()>0){
//
//            LambdaUpdateWrapper<Inventory> updateStateWrapper1 = Wrappers.lambdaUpdate();
//            LambdaUpdateWrapper<Inventory> allocateInWrapper1 = Wrappers.lambdaUpdate();
//            LambdaUpdateWrapper<WarehouseInventory> updateStateWrapper2 = Wrappers.lambdaUpdate();
//            LambdaUpdateWrapper<WarehouseInventory> allocateInWrapper2 = Wrappers.lambdaUpdate();
//            LambdaQueryWrapper<WarehouseInventory> destroyOutWrapper =Wrappers.lambdaQuery();
//            for (Inventory inventory:inventoryList) {
//                if (inventory.getBussinessType().equals("allocate") && inventory.getLocationState().equals("in") && !ObjectUtil.isNull(ordermain)){
//                    //调拨入库
//                    allocateInWrapper1.or().eq(Inventory::getEpc,inventory.getEpc())
//                            .set(Inventory::getOrgId,inventory.getOrgId())
//                            .set(Inventory::getLocationId,inventory.getLocationId())
//                            .set(Inventory::getLocationState,"in");
//                    allocateInWrapper2.or().eq(WarehouseInventory::getEpc,inventory.getEpc())
//                            .set(WarehouseInventory::getOrgId,inventory.getOrgId())
//                            .set(WarehouseInventory::getLocationId,inventory.getLocationId())
//                            .set(WarehouseInventory::getLocationState,"in");
//
//                } else if (inventory.getBussinessType().equals("allocate") && inventory.getLocationState().equals("out") && !ObjectUtil.isNull(ordermain)){
//                    //调拨出库，不操作
//                    allocateInWrapper1.or().eq(Inventory::getEpc,inventory.getEpc())
//                            .set(Inventory::getOrgId,null)
//                            .set(Inventory::getLocationId,null)
//                            .set(Inventory::getLocationState,"out");
//                    allocateInWrapper2.or().eq(WarehouseInventory::getEpc,inventory.getEpc())
//                            .set(WarehouseInventory::getOrgId,null)
//                            .set(WarehouseInventory::getLocationId,null)
//                            .set(WarehouseInventory::getLocationState,"out");
//                }else if (inventory.getBussinessType().equals("destruction")){
//                    updateStateWrapper1.or().eq(Inventory::getEpc,inventory.getEpc())
//                            .set(Inventory::getLocationState,"out")
//                            .set(Inventory::getBussinessState,"destruction")
//                            .set(Inventory::getLocationId,inventory.getLocationId())
//                            .set(Inventory::getState,"destory");
//                    destroyOutWrapper.or().eq(WarehouseInventory::getEpc,inventory.getEpc());
//                }else{
//                    //其他情况
//                    if (inventory.getBussinessType().equals("quick")){
//                        updateStateWrapper1.or().eq(Inventory::getEpc,inventory.getEpc())
//                                .set(Inventory::getLocationState,"in")
//                                .set(Inventory::getBussinessState,"normal")
//                                .set(Inventory::getLocationId,inventory.getLocationId())
//                                .set(Inventory::getState,"normal");
//
//                        updateStateWrapper2.or().eq(WarehouseInventory::getEpc,inventory.getEpc())
//                                .set(WarehouseInventory::getLocationId,inventory.getLocationId())
//                                .set(WarehouseInventory::getLocationState,"in");
//                    }else {
//                        updateStateWrapper1.or().eq(Inventory::getEpc,inventory.getEpc())
//                                .set(Inventory::getLocationState,inventory.getLocationState())
//                                .set(Inventory::getBussinessState,inventory.getBussinessState())
//                                .set(Inventory::getState,inventory.getState());
//
//                        updateStateWrapper2.or().eq(WarehouseInventory::getEpc,inventory.getEpc())
//                                .set(WarehouseInventory::getLocationState,inventory.getLocationState());
//
//                    }
//
//
//                }
//
//            }
//
//            if (!updateStateWrapper1.isEmptyOfWhere()){
//
//                inventoryService.update(updateStateWrapper1);
//
//                warehouseInventoryService.update(updateStateWrapper2);
//            }
//
//            if (!allocateInWrapper1.isEmptyOfWhere()){
//
//                inventoryService.update(allocateInWrapper1);
//                warehouseInventoryService.update(allocateInWrapper2);
//            }
//
//        }
//
//        return returnList;
//    }

    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,String locationId,String locationName,String outInState){
        LogSummary logSummary = new LogSummary();
        BeanPlusUtil.copyProperties(req,logSummary);
        logSummary.setOutInState(outInState);
        logSummary.setLocationId(locationId);
        logSummary.setLocationName(locationName);
        logSummary.setCreateTime(DateTimeUtil.getCurrentDateTime());
        logSummary.setUpdateTime(DateTimeUtil.getCurrentDateTime());
        logSummary.setBussinessType(req.getBussinessType());
        logSummary.setOrgId(req.getOrgId());
        logSummary.setOrgName(req.getOrgName());
        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("bussinessType"));
        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="";
        String bussinessState="";
        if (outInState.equals("in")){
            switch (bussinessType){
                case "return":
                case "gift":
                case "other":
                case "repair":
                    state="normal";
                    bussinessState="normal";
                    break;
                case "allocate":
                    state="normal";
                    bussinessState="allocate";
                    break;

            }
        }else {
            switch (bussinessType){
                case "use":
                    state="normal";
                    bussinessState="use";
                    break;
                case "allocate":
                    state="normal";
                    bussinessState="allocate";
                    break;
                case "repair":
                    state="fix";
                    bussinessState="repair";
                    break;
                case "destruction":
                    state="destory";
                    bussinessState="destruction";
                    break;
                case "other":
                    state="normal";
                    bussinessState="normal";
                    break;
                case "quick":
                    state="normal";
                    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.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);
                inventorySummary.setPrice(BigDecimal.valueOf(outDto.getNumber()).multiply(outDto.getPrice()));
                inventorySummary.setLocationType("0");
                inventorySummary.setUnitPrice(outDto.getPrice());
                inventorySummary.setBrokenNumber(0);
                inventorySummary.setExpireNumber(0);
                inventorySummary.setDestructionNumber(0);
                inventorySummary.setFixNumber(0);
                inventorySummary.setCreateTime(DateTimeUtil.getCurrentDateTime());
                if (outInState.equals("in")){
                    inventorySummary.setOutboundNumber(0);
                    inventorySummary.setUseNumber(0);
                    inventorySummary.setUseCount(0);
                    inventorySummary.setStockNumber(outDto.getNumber());
                }else {
                    inventorySummary.setOutboundNumber(outDto.getNumber());
                    inventorySummary.setStockNumber(0);
                    inventorySummary.setUseNumber(outDto.getNumber());
                    inventorySummary.setUseCount(outDto.getNumber());
                }
                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 List<NormalInOutDto> 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<>();
        String orderMainId="";

        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("OutInPrice/"+logreq.getOrgId()+"/");
                SysFileInfoResp sysFileInfoResp = sysFileInfoService.uploadFile(picture, sysFileInfoReq);
                logreq.setPicture(sysFileInfoResp.getAccessUrl());
            }

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

                ordermain = orderMainService.getById(logreq.getOrderMainId());
            }

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

            //出入库list
            List<LogDetail> collect = new ArrayList<>();
            LogSummary logSummary = saveLogSummary(logreq,logreq.getLocationId(),logreq.getLocationName(),logreq.getOutInState());

            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";
            }
            LogSummary logSummaryQuick=new LogSummary();
            if (logreq.getBussinessType().equals("quick")){//如果是快速出库的同时需要创建快速入库
                logSummaryQuick= saveLogSummary(logreq,ordermain.getLocationId(),ordermain.getLocationName(),"in");
                sumList.add(logSummaryQuick);
                stringQuick=stringQuick+logSummaryQuick.getLocationName()+"：入库【"+logSummaryQuick.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) {
                //将所有装备信息进行存放（为后面计算汇总信息）
                if (logreq.getBussinessType().equals("normal")) {
                    NormalInOutDto normalInOutDto = new NormalInOutDto();
                    BeanPlusUtil.copyProperties(detailLogReq, normalInOutDto);
                    normalInOutDto.setLocationId(logSummary.getLocationId());
                    normalInOutDto.setLocationName(logSummary.getLocationName());
                    normalInOutDto.setOrgId(logSummary.getOrgId());
                    normalInOutDto.setOrgName(logSummary.getOrgName());
                    normalInOutDto.setNumber(1);
                    normalInOutDto.setOutInState(logSummary.getOutInState());
                    returnList.add(normalInOutDto);
                }
                //判断logSummary是否为采购,快速移库，和领用出库
                //如果是采购则不处理，因为采购的inventory是跟着单子来处理的，其他的单子直接根据出入库记录来处理
                if (!logreq.getBussinessType().equals("purchase") && !logreq.getBussinessType().equals("quick") ){
//                    if (logreq.getOutInState().equals("in")){
                    Inventory inventory = saveInventory(logreq.getOrgId(),logreq.getLocationId(),logreq,detailLogReq, map, logSummary.getOutInState());
                    inventoryList.add(inventory);

                }
//                //如果是快速移库，那么直接将物资的locationId进行修改
                if(logreq.getBussinessType().equals("quick")){
                    Inventory inventory = saveInventory(logreq.getOrgId(),ordermain.getLocationId(),logreq,detailLogReq, map, "in");
                    inventoryList.add(inventory);
                }
                //存放logdetail信息
                LogDetail logDetail = new LogDetail();
                LogDetail logDetailQuick=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 (logreq.getBussinessType().equals("quick")){
                    BeanPlusUtil.copyProperties(logDetail,logDetailQuick);
                    logDetailQuick.setSummaryId(logSummaryQuick.getId());
                    logDetailQuick.setOutInState("in");
                    collect.add(logDetailQuick);
                }
                //无单据的直接创建批量保存
                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);
                OrderLog qucik = new OrderLog();
                if (logreq.getBussinessType().equals("quick")){
                    qucik=addLog(logSummaryQuick,stringQuick);
                    OrderLogReq quickOrderLogReq = new OrderLogReq();
                    BeanPlusUtil.copyProperties(qucik,quickOrderLogReq);
                    orderLogReqList.add(quickOrderLogReq);
                }
                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){

            LambdaUpdateWrapper<Inventory> updateStateWrapper1 = Wrappers.lambdaUpdate();
            LambdaUpdateWrapper<Inventory> allocateInWrapper1 = Wrappers.lambdaUpdate();
            LambdaUpdateWrapper<WarehouseInventory> updateStateWrapper2 = Wrappers.lambdaUpdate();
            LambdaUpdateWrapper<WarehouseInventory> allocateInWrapper2 = Wrappers.lambdaUpdate();
            LambdaQueryWrapper<WarehouseInventory> destroyOutWrapper =Wrappers.lambdaQuery();
            for (Inventory inventory:inventoryList) {
                if (inventory.getBussinessType().equals("allocate") && inventory.getLocationState().equals("in") && !ObjectUtil.isNull(ordermain)){
                    //调拨入库
                    allocateInWrapper1.or().eq(Inventory::getEpc,inventory.getEpc())
                            .set(Inventory::getOrgId,inventory.getOrgId())
                            .set(Inventory::getLocationId,inventory.getLocationId())
                            .set(Inventory::getLocationState,"in");
                    allocateInWrapper2.or().eq(WarehouseInventory::getEpc,inventory.getEpc())
                            .set(WarehouseInventory::getOrgId,inventory.getOrgId())
                            .set(WarehouseInventory::getLocationId,inventory.getLocationId())
                            .set(WarehouseInventory::getLocationState,"in");

                } else if (inventory.getBussinessType().equals("allocate") && inventory.getLocationState().equals("out") && !ObjectUtil.isNull(ordermain)){
                    //调拨出库，不操作
                    allocateInWrapper1.or().eq(Inventory::getEpc,inventory.getEpc())
                            .set(Inventory::getOrgId,null)
                            .set(Inventory::getLocationId,null)
                            .set(Inventory::getLocationState,"out");
                    allocateInWrapper2.or().eq(WarehouseInventory::getEpc,inventory.getEpc())
                            .set(WarehouseInventory::getOrgId,null)
                            .set(WarehouseInventory::getLocationId,null)
                            .set(WarehouseInventory::getLocationState,"out");
                }else if (inventory.getBussinessType().equals("destruction")){
                    updateStateWrapper1.or().eq(Inventory::getEpc,inventory.getEpc())
                            .set(Inventory::getLocationState,"out")
                            .set(Inventory::getBussinessState,"destruction")
                            .set(Inventory::getLocationId,inventory.getLocationId())
                            .set(Inventory::getState,"destory");
                    destroyOutWrapper.or().eq(WarehouseInventory::getEpc,inventory.getEpc());
                }else{
                    //其他情况
                    if (inventory.getBussinessType().equals("quick")){
                        updateStateWrapper1.or().eq(Inventory::getEpc,inventory.getEpc())
                                .set(Inventory::getLocationState,"in")
                                .set(Inventory::getBussinessState,"normal")
                                .set(Inventory::getLocationId,inventory.getLocationId())
                                .set(Inventory::getState,"normal");

                        updateStateWrapper2.or().eq(WarehouseInventory::getEpc,inventory.getEpc())
                                .set(WarehouseInventory::getLocationId,inventory.getLocationId())
                                .set(WarehouseInventory::getLocationState,"in");
                    }else {
                        updateStateWrapper1.or().eq(Inventory::getEpc,inventory.getEpc())
                                .set(Inventory::getLocationState,inventory.getLocationState())
                                .set(Inventory::getBussinessState,inventory.getBussinessState())
                                .set(Inventory::getState,inventory.getState());

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

                    }


                }

            }

            if (!updateStateWrapper1.isEmptyOfWhere()){

                inventoryService.update(updateStateWrapper1);

                warehouseInventoryService.update(updateStateWrapper2);
            }

            if (!allocateInWrapper1.isEmptyOfWhere()){

                inventoryService.update(allocateInWrapper1);
                warehouseInventoryService.update(allocateInWrapper2);
            }

        }

        return returnList;
    }

}




