package com.junmp.jyzb.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.junmp.junmpProcess.common.utils.HttpStatus;
import com.junmp.junmpProcess.common.utils.ResponseResult;
import com.junmp.junmpProcess.common.utils.ReturnMsg;
import com.junmp.junmpProcess.dto.AttachmentDTO;
import com.junmp.junmpProcess.dto.HandleDataDTO;
import com.junmp.junmpProcess.dto.StartProcessInstanceDTO;
import com.junmp.junmpProcess.service.IFlowInstanceService;
import com.junmp.jyzb.api.bean.dto.*;
import com.junmp.jyzb.api.bean.query.*;
import com.junmp.jyzb.api.bean.query.inAndOutRecordReq.DetailJsonReq;
import com.junmp.jyzb.api.bean.req.UpdateOrderDetailReq;
import com.junmp.jyzb.api.bean.req.UpdateOrderReq;
import com.junmp.jyzb.api.bean.vo.InOrderInfoVo;
import com.junmp.jyzb.api.constant.JYZBConstant;
import com.junmp.jyzb.api.exception.JYZBAppException;
import com.junmp.jyzb.api.exception.enums.InventoryExceptionEnum;
import com.junmp.jyzb.api.exception.enums.OrderExceptionEnum;
import com.junmp.jyzb.api.exception.enums.PolicemanExceptionEnum;
import com.junmp.jyzb.api.exception.enums.WarehouseExceptionEnum;
import com.junmp.jyzb.cache.MsgRedisCache;
import com.junmp.jyzb.cache.OutInRecordRedisCache;
import com.junmp.jyzb.entity.*;
import com.junmp.jyzb.jyzbthirdparty.service.ThirdPartyService;
import com.junmp.jyzb.mapper.*;
import com.junmp.jyzb.service.*;
import com.junmp.jyzb.utils.DateTimeUtil;
import com.junmp.jyzb.utils.RabbitMQSendMsg;
import com.junmp.v2.auth.api.bean.login.LoginUser;
import com.junmp.v2.auth.api.context.LoginContext;
import com.junmp.v2.common.exception.base.ServiceException;
import com.junmp.v2.common.util.BeanPlusUtil;
import com.junmp.v2.common.util.HttpServletUtil;
import com.junmp.v2.db.api.factory.PageFactory;
import com.junmp.v2.db.api.factory.PageResultFactory;
import com.junmp.v2.db.api.page.PageResult;
import com.junmp.v2.dict.entity.SysDict;
import com.junmp.v2.dict.entity.SysDictItem;
import com.junmp.v2.dict.service.SysDictItemService;
import com.junmp.v2.dict.service.SysDictService;
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 com.junmp.v2.message.api.MessageApi;
import com.junmp.v2.message.api.bean.req.MessageSendReq;
import com.junmp.v2.office.api.OfficeExcelApi;
import com.junmp.v2.office.api.bean.ExcelExportParam;
import com.junmp.v2.sys.user.entity.SysUser;
import com.junmp.v2.sys.user.service.SysUserService;
import org.apache.commons.lang3.StringUtils;
import org.flowable.common.engine.impl.identity.Authentication;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.task.api.Task;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Exchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
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 javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static com.junmp.junmpProcess.common.CommonConstants.FORM_VAR;
import static com.junmp.junmpProcess.common.CommonConstants.TASK_STATUS_1;


@Service
@Transactional
public class OrderMainServiceImpl extends ServiceImpl<OrderMainMapper, OrderMain> implements OrderMainService {

    @Resource
    private OrderDetailService orderDetailService;
    @Resource
    private RabbitTemplate rabbitTemplate;
    @Resource
    private RabbitAdmin rabbitAdmin;

    @Resource
    private OrderNumService orderNumService;

    @Resource
    private MessageApi messageApi;
    @Resource
    private MsgRedisCache redisCache;
    @Resource
    private OrderMainMapper orderMainMapper;

    @Resource
    private SysDictItemService sysDictItemService;

    @Resource
    private OrderLogService orderLogService;
    @Resource
    private IFlowInstanceService FlowInstanceService;
    @Resource
    private OfficeExcelApi officeExcelApi;

    @Resource
    private InventorySummaryService inventorySummaryService;

    @Resource
    private InventoryService inventoryService;
    @Resource
    private WarehouseService warehouseService;
    @Resource
    private BusFormService busFormService;

    @Resource
    private BussinessInventoryService bussinessInventoryService;

    @Resource
    private BussinessInventoryDetailService bussinessInventoryDetailService;

    @Resource
    private ReassignmentService reassignmentService;

    @Resource
    private PoliceEquipmentService policeEquipmentService;

    @Resource
    private SysDictService sysDictService;

    @Resource
    protected TaskService taskService;

    @Resource
    private PubOrgService pubOrgService;

    @Resource
    private PolicemanService policemanService;

    @Resource
    private SysUserService sysUserService;
    @Resource
    private LogSummaryService logSummaryService;
    @Resource
    private LogDetailService logDetailService;

    @Resource
    private InventoryMapper inventoryMapper;

    @Resource
    private InventorySummaryMapper inventorySummaryMapper;
    @Autowired
    private RabbitMQSendMsg MQ;


    @Resource
    private WarehouseInventoryService warehouseInventoryService;

    @Resource
    private OutInRecordRedisCache outInRecordRedisCache;

    @Resource
    protected RuntimeService runtimeService;

    @Resource
    private PlanInitiationItemMapper planInitiationItemMapper;

    @Resource
    private PoliceEquipmentDetailService policeEquipmentDetailService;

    @Resource
    private OrderPrintNumService orderPrintNumService;

    @Resource
    private ThirdPartyService thirdPartyService;

    @Resource
    private SysFileInfoService sysFileInfoService;



    @Transactional(rollbackFor = Exception.class)
    @Override
    public List<String> AddOrder(UpdateOrderReq req) {
        //返回结果
        List<String> list=new ArrayList<>();
        //判断单据是否需要上传附件
        if (ObjectUtil.isNotNull(req.getId()) && ObjectUtil.isNotEmpty(req.getIsUploadAttachment()) && req.getIsUploadAttachment().equals("1")){
            OrderMain orderMain = orderMainExist(req.getId());
            orderMain.setAttachmentLocation(req.getAttachmentLocation());
            updateById(orderMain);
            list.add(orderMain.getId());
            return list;
        }
        //修改单据使用次数状态，判断数据库是否有该单据，如果有，那么就判断当前单号是否一致，如果不一致，修改单据使用次数
        Long orgId = req.getOrderType().equals("in")?req.getEndOrgId():Long.parseLong(req.getStartOrgId());
        OrderMain one =null ;
        //修改业务单可用次数
        if (ObjectUtil.isNotNull(req.getBussinessCode()) && req.getBussinessCode().charAt(1) != 'K'){
            one = setBusFormState(req, one, orgId);
        }
        //绑定出库单据(归还入库使用)
        if (ObjectUtil.isNotNull(req.getBussinessCode()) && req.getBussinessCode().charAt(0) == 'C' && req.getBussinessCode().charAt(1) == 'K'
                && !req.getBussinessType().equals("return")){
            update(new LambdaUpdateWrapper<OrderMain>().set(OrderMain::getOrderCurrentState,0)
                    .eq(OrderMain::getOrderCode,req.getBussinessCode())
                    .eq(OrderMain::getStartOrgId,req.getEndOrgId()));
        }

        if (one!=null){
            //判断该单据是否可以进行修改(如果审核中则不允许修改)
            if (ObjectUtil.isNotNull(one.getExamineState()) && one.getExamineState().equals("working")){
                throw new ServiceException(OrderExceptionEnum.ORDER_CAN_NOT_UPDATE);
            }
        }

        //判断是否有工作流id，如果有则将状态进行修改
        String examineState = req.getExamineState();
        if (ObjectUtil.isEmpty(req.getProcessDefinitionId())) {
            req.setExamineState("none");
        } else {
            req.setExamineState("working");
        }
        if (ObjectUtil.isNotEmpty(examineState) && examineState.equals("finished")){
            req.setExamineState("working");

        }
        OrderMain order = new OrderMain();
        BeanPlusUtil.copyProperties(req, order);

        //先判断该单据id是否存在，如果存在，进行更新操作即可
        if (ObjectUtil.isNotNull(req.getId()) && ! req.getId().trim().isEmpty()){
            //删除子单据
            orderDetailService.remove(new LambdaQueryWrapper<OrderDetail>()
                    .eq(ObjectUtil.isNotNull(req.getId()),OrderDetail::getOrderId,req.getId()));
        }else {
            //设置id
            String id=UUID.randomUUID().toString();
            order.setId(id);
            //设置单据单号
            OrderNum orderNum = setOrderCode(req);
            long time = new Date().getTime() % 10000;
            String codeValue=String.format("%04d",orderNum.getNum());
            order.setOrderCode(orderNum.getBussinessType()+String.format("%04d",time)+orderNum.getYear()+
                    String.format("%02d",LocalDateTime.now().getMonth().getValue())+
                    String.format("%02d",LocalDateTime.now().getDayOfMonth())+codeValue);
        }

        //设置总价格和应出入库数量
        Integer sumNum=0;
        BigDecimal priceTotal=new BigDecimal(0);
        List<OrderDetail> detailList = new ArrayList<>();
        //通过遍历批量保存详细信息
        String s="";
        if (req.getLogSummaryId() !=null){
            if (req.getOrderType().equals("in")){
                Long dictId = sysDictService.getOne(new LambdaQueryWrapper<SysDict>()
                        .eq(SysDict::getDictCode, "bussiness_type")).getDictId();
                String itemText = sysDictItemService.getOne(new LambdaQueryWrapper<SysDictItem>()
                        .eq(SysDictItem::getDictId, dictId)
                        .eq(SysDictItem::getItemValue, req.getBussinessType())).getItemText();
                s=s+itemText+"单：";
            }else {
                Long dictId = sysDictService.getOne(new LambdaQueryWrapper<SysDict>()
                        .eq(SysDict::getDictCode, "out_type")).getDictId();
                String itemText = sysDictItemService.getOne(new LambdaQueryWrapper<SysDictItem>()
                        .eq(SysDictItem::getDictId, dictId)
                        .eq(SysDictItem::getItemValue, req.getBussinessType())).getItemText();
                s=s+itemText+"单：";
            }
        }

        List<Warehouse> warehouseList = warehouseService.list(new LambdaQueryWrapper<Warehouse>().eq(Warehouse::getOrgIdInt, orgId));
        String warehouseId="";
        String warehouseName="";
        if (req.getOrderType().equals("in") && CollectionUtil.isEmpty(warehouseList)){
            throw new ServiceException(WarehouseExceptionEnum.WAREHOUSE_NOT_EXIST);
        }else {
            Warehouse warehouse = warehouseList.get(0);
            warehouseId=warehouse.getId();
            warehouseName=warehouse.getName();
        }
        for (UpdateOrderDetailReq listReq:req.getDetailList()) {
            OrderDetail detail=new OrderDetail();
            if (ObjectUtil.isEmpty(listReq.getProductionDate())|| listReq.getProductionDate().trim().isEmpty()){
                listReq.setProductionDate(null);
            }
            BeanPlusUtil.copyProperties(listReq, detail);
            if (req.getOrderType().equals("in")){

                detail.setWarehouseId(warehouseId);
                detail.setWarehouseName(warehouseName);
            }
            detail.setOrderId(order.getId());
            //设置单据类型
            detail.setType(order.getOrderType());
            //将数量和价格进行累加
            sumNum += detail.getPlanNum();
            detail.setSupplierId(req.getSupplierId());
            detail.setSupplierName(req.getSupplierName());
            priceTotal = priceTotal.add(detail.getTotalPrice()) ;
            detail.setCreateTime(DateTimeUtil.getCurrentDateTime());
            String productionDate = listReq.getProductionDate();
            if (ObjectUtil.isNotNull(productionDate) && !productionDate.trim().isEmpty()){
                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
                try {
                    detail.setProductionDate(format.parse(productionDate));
                } catch (ParseException e) {
                    throw new RuntimeException(e);
                }
            }
            //添加日志记录
            if (ObjectUtil.isNull(req.getLogSummaryId()) || req.getLogSummaryId()==null){
                s=s+"【"+listReq.getTypeName()+"--"+listReq.getSizeName()+"】预计数量："+listReq.getPlanNum()+"\n";
            }
            detailList.add(detail);

        }
        orderDetailService.saveBatch(detailList);
        //设置总价格和总数量
        order.setPrice(priceTotal);
        order.setInventoryQuantity(sumNum);
        order.setCreateTime(DateTimeUtil.getCurrentDateTime());
        String processInstanceId = null;
       if (req.getExamineState().equals("working")){
           //执行工作流
           StartProcessInstanceDTO startProcessInstanceDTO=new StartProcessInstanceDTO();

           //设置参数
           startProcessInstanceDTO = setParams(startProcessInstanceDTO, req,order);

           if (!req.getBussinessType().equals("quick") && req.getExamineState().equals("working"))//其他出入库单
           {
               startProcessInstanceDTO.setTypeOrder("workOrder");
               processInstanceId= FlowInstanceService.startProcessInstanceById(startProcessInstanceDTO);
               

           }else if (req.getBussinessType().equals("quick") && req.getExamineState().equals("working")){//快速移库单
               startProcessInstanceDTO.setTypeOrder("quickOrder");
               processInstanceId= FlowInstanceService.startProcessInstanceById(startProcessInstanceDTO);

           }else if (ObjectUtil.isNotNull(req.getLogSummaryId()) && req.getExamineState().equals("working")){
               startProcessInstanceDTO.setTypeOrder("normalOrder");
               processInstanceId= FlowInstanceService.startProcessInstanceById(startProcessInstanceDTO);
           }
       }


        //list返回数据
        String userId="";
        //当前审核是否跳过
        if (processInstanceId!=null && processInstanceId.substring(0,4).equals("skip") ){
            String substring = processInstanceId.substring(4);
            order.setProcessId(substring);
            if (ObjectUtil.isNotNull(req.getId()) && !req.getId().trim().isEmpty()) {
                updateById(order);
            } else {
                //保存
                //将创建人员添加（为的是将审核员创建的单子，审核员能看见）
                //将该组织机构下的所有审核人员进行查询，并添加到historyAssign中
                String userIds=policemanService.searchUserByRoleId(orgId, JYZBConstant.GL_ROLR_ID);
                String userIdsList=policemanService.searchUserByRoleId(orgId, JYZBConstant.SH_ROLR_ID);

                if (ObjectUtil.isNotEmpty(req.getUserId())){
                    userId=req.getUserId()+","+userIds;
                    userId=userId+","+userIdsList;
                }else {
                    userId=userIds;
                    userId=userId+","+userIdsList;
                }
                order.setHistoryAssign(userId);
                if (req.getBussinessType().equals("use")){
                    order.setOrderCurrentState(1);
                }
                this.save(order);
            }
            Task currentTask = taskService.createTaskQuery().processInstanceId(substring).singleResult();
            // 直接完成当前任务
            taskService.complete(currentTask.getId());
        }else {
            order.setProcessId(processInstanceId);
            if (ObjectUtil.isNotNull(req.getId()) && !req.getId().trim().isEmpty()) {
                updateById(order);
            } else {
                //保存
                //将创建人员添加（为的是将审核员创建的单子，审核员能看见）
                //将该组织机构下的所有仓管人员进行查询，并添加到historyAssign中
                String userIds=policemanService.searchUserByRoleId(orgId,JYZBConstant.GL_ROLR_ID);
                String userIdsList=policemanService.searchUserByRoleId(orgId,JYZBConstant.SH_ROLR_ID);

                if (ObjectUtil.isNotEmpty(req.getUserId())){
                    userId=req.getUserId()+","+userIds;
                    userId=userId+","+userIdsList;
                }else {
                    userId=userIds;
                    userId=userId+","+userIdsList;
                }
                order.setHistoryAssign(userId);
                this.save(order);
            }
        }
        list.add(order.getId());
        for (OrderDetail orderDetail:detailList) {
            list.add(Long.toString(orderDetail.getId()));
        }
        //判断orderId在orderLog表中是否存在，如果存在，则直接替换
        //判断是否有流程id，如果有，则进行添加
        if ((order.getProcessId()!=null && ObjectUtil.isNull(req.getLogSummaryId())) ||
                (ObjectUtil.isNotEmpty(req.getExamineState()) && req.getExamineState().equals("finished") && order.getProcessId()==null)){
            boolean b = addOrderLog(req,order.getId(),order.getOrderCode(),s);
        }

        String objJson= redisCache.get(order.getProcessId());
        redisCache.remove(order.getProcessId());
        List<MessageSendReq> msgs= JSONObject.parseArray(objJson,MessageSendReq.class);
        if (CollectionUtil.isNotEmpty(msgs)){
            msgs.forEach(msg->
                    {
                        messageApi.sendMessageNoToken(msg);
                    }

            );
        }
        String assigneeList= redisCache.get(order.getProcessId()+"assigneeList");
        redisCache.remove(order.getProcessId()+"assigneeList");
        OrderMain orderMain = getById(order.getId());
        orderMain.setCurrentAssign(assigneeList);
        updateById(orderMain);

        //如果是无单据转业务
        if (ObjectUtil.isNotNull(req.getLogSummaryId())){
            logSummaryService.update(new LambdaUpdateWrapper<LogSummary>()
                    .set(LogSummary::getOrderMainId,order.getId())
                    .set(LogSummary::getOrderCode,order.getOrderCode())
                    .set(LogSummary::getBussinessType,order.getBussinessType())
                    .eq(LogSummary::getId,req.getLogSummaryId()));

        }
        if ((ObjectUtil.isNotEmpty(req.getProcessDefinitionId()) || ObjectUtil.isNotEmpty(processInstanceId))
                && req.getBussinessType().equals("allocate")){
            outInRecordRedisCache.addProcessDefinitionId(order.getId(),req.getProcessDefinitionId(),DateTimeUtil.TimeDateToLong(DateTimeUtil.getCurrentDateTime()));
            outInRecordRedisCache.addOrderDetailList(order.getId(),req.getDetailList(),DateTimeUtil.TimeDateToLong(DateTimeUtil.getCurrentDateTime()));
        }

        return list;
    }

    @Transactional
    public Boolean addAllocateOrderAndMsg(OrderMain order){
//        调拨出库自动生成调拨入库单
        String processDefinitionId = outInRecordRedisCache.getProcessDefinitionIds(order.getId());
        List<UpdateOrderDetailReq> orderDetailList = outInRecordRedisCache.getOrderDetailList(order.getId());
        //再将detailList进行取值；
        if (ObjectUtil.isNotEmpty(processDefinitionId) || !processDefinitionId.equals("")){

            List<String> strings = addAllocateOrder(processDefinitionId,order,orderDetailList);
            if (strings.size()>0){
                redisCache.remove("processId:"+order.getId());
                redisCache.remove("detailList:"+order.getId());
            }
            OrderMain one = getById(strings.get(0));

            //将审核人查询出来之后推送消息
            List<MessageSendReq> msgList=new ArrayList<>();
            List<String> assigneeList = Arrays.stream(one.getHistoryAssign().split(",")).collect(Collectors.toList());
            List<String> uniqueAssigneeList = assigneeList.stream()
                    .distinct()
                    .collect(Collectors.toList());
            uniqueAssigneeList.forEach(id->//为相应的用户推送消息
            {
                if (id!=LoginContext.getContext().getLoginUser().getUserId().toString())//非本人审核单据
                {
                    MessageSendReq sendReq = new MessageSendReq();
                    sendReq.setReceiveUserIds(String.valueOf(id));
                    sendReq.setMsgTitle("调拨入库单待办任务");
                    sendReq.setBizType("assign/"+"allocateOrder");
                    sendReq.setBizId(Long.valueOf(one.getProcessId()));
                    sendReq.setMsgContent(one.getStartOrgName()+"-"+one.getStartOrgUserName()+"发起的调拨出库单，系统已经创建了对应调拨入库单，单号为"+one.getOrderCode()+"，请及时处理");
                    sendReq.setPriority("0");
                    sendReq.setSendTime(DateTime.now());
                    msgList.add(sendReq);

                }

            });

            if (CollectionUtil.isNotEmpty(msgList)){
                msgList.forEach(msg->
                        {
                            messageApi.sendMessageNoToken(msg);
                        }
                );
            }

        }
        return true;
    }

//    @Transactional
    public List<String> addAllocateOrder(String processDefinitionId,OrderMain order,List<UpdateOrderDetailReq> orderDetailList){
        UpdateOrderReq updateOrderReq = new UpdateOrderReq();
        BeanPlusUtil.copyProperties(order,updateOrderReq);
        updateOrderReq.setOrderCode(null);
        updateOrderReq.setId(null);
        updateOrderReq.setProcessDefinitionId(processDefinitionId);
        //如果出库单关联业务单，那么直接绑定业务单的单据
        //如果出库单不关联业务单，那么直接绑定入库单的单据
        updateOrderReq.setBussinessCode(ObjectUtil.isNotEmpty(order.getBussinessCode())?order.getBussinessCode():order.getOrderCode());
        updateOrderReq.setOrderType("in");
        updateOrderReq.setOrderState("ready");
        updateOrderReq.setExamineState("working");
        updateOrderReq.setNote("系统自动生成");
        updateOrderReq.setDetailList(orderDetailList);
        return AddOrder(updateOrderReq);
    }


    @Transactional
    public Boolean addAllocateOutOrderAndMsg(OrderMain order){
//        调拨入库自动生成调拨出库单
        String processDefinitionId = outInRecordRedisCache.getProcessDefinitionIds(order.getId());
        List<UpdateOrderDetailReq> orderDetailList = outInRecordRedisCache.getOrderDetailList(order.getId());
        //再将detailList进行取值；
        if (ObjectUtil.isNotEmpty(processDefinitionId) || !processDefinitionId.equals("")){

            List<String> strings = addAllocateOutOrder(processDefinitionId,order,orderDetailList);
            if (strings.size()>0){
                redisCache.remove("processId:"+order.getId());
                redisCache.remove("detailList:"+order.getId());
            }
            OrderMain one = getById(strings.get(0));

            //将审核人查询出来之后推送消息
            List<MessageSendReq> msgList=new ArrayList<>();
            List<String> assigneeList = Arrays.stream(one.getHistoryAssign().split(",")).collect(Collectors.toList());
            List<String> uniqueAssigneeList = assigneeList.stream()
                    .distinct()
                    .collect(Collectors.toList());
            uniqueAssigneeList.forEach(id->//为相应的用户推送消息
            {
                if (id!=LoginContext.getContext().getLoginUser().getUserId().toString())//非本人审核单据
                {
                    MessageSendReq sendReq = new MessageSendReq();
                    sendReq.setReceiveUserIds(String.valueOf(id));
                    sendReq.setMsgTitle("调拨出库单待办任务");
                    sendReq.setBizType("assign/"+"allocateOrder");
                    sendReq.setBizId(Long.valueOf(one.getProcessId()));
                    sendReq.setMsgContent(one.getEndOrgName()+"-"+one.getEndOrgUserName()+"发起的调拨入库单，系统已经创建了对应调拨出库单，单号为"+one.getOrderCode()+"，请及时处理");
                    sendReq.setPriority("0");
                    sendReq.setSendTime(DateTime.now());
                    msgList.add(sendReq);

                }

            });

            if (CollectionUtil.isNotEmpty(msgList)){
                msgList.forEach(msg->
                        {
                            messageApi.sendMessageNoToken(msg);
                        }
                );
            }

        }
        return true;
    }

    @Transactional
    public List<String> addAllocateOutOrder(String processDefinitionId,OrderMain order,List<UpdateOrderDetailReq> orderDetailList){
        UpdateOrderReq updateOrderReq = new UpdateOrderReq();
        BeanPlusUtil.copyProperties(order,updateOrderReq);
        updateOrderReq.setOrderCode(null);
        updateOrderReq.setId(null);
        updateOrderReq.setProcessDefinitionId(processDefinitionId);
        //如果出库单关联业务单，那么直接绑定业务单的单据
        //如果出库单不关联业务单，那么直接绑定入库单的单据
        updateOrderReq.setBussinessCode(ObjectUtil.isNotEmpty(order.getBussinessCode())?order.getBussinessCode():order.getOrderCode());
        updateOrderReq.setOrderType("out");
        updateOrderReq.setOrderState("ready");
        updateOrderReq.setExamineState("working");
        updateOrderReq.setNote("系统自动生成");
        updateOrderReq.setDetailList(orderDetailList);
        return AddOrder(updateOrderReq);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean delToSubmitOrder(UpdateOrderReq req) {
        //入库单
        OrderMain one = getById(req.getId());
        if (ObjectUtil.isNull(one)){
            throw new ServiceException(OrderExceptionEnum.ORDER_NOT_EXIST);
        }
        if (!one.getExamineState().equals("none")){
            throw new ServiceException(OrderExceptionEnum.ORDER_DEL_ERROR);
        }
        //如果关联业务单据，那么需要将业务单据状态重新设置回来
        Long orgId = one.getOrderType().equals("in")?one.getEndOrgId():one.getStartOrgId();
        if (ObjectUtil.isNotNull(one.getBussinessCode())  && one.getBussinessCode().charAt(1) != 'K'){
            BusForm busForm = setState(one.getOrderType(),orgId, one.getBussinessCode(),false);
            busFormService.updateById(busForm);
        }
        //归还入库解绑单据
        if (ObjectUtil.isNotNull(one.getBussinessCode()) && one.getBussinessCode().charAt(0) == 'C' && one.getBussinessCode().charAt(1) == 'K'){
            update(new LambdaUpdateWrapper<OrderMain>().set(OrderMain::getOrderCurrentState,1)
                    .eq(OrderMain::getOrderCode,one.getBussinessCode())
                    .eq(OrderMain::getStartOrgId,one.getEndOrgId()));
        }

        return removeById(one.getId());
    }


    /**
     * 设置工作流参数
     * @param startProcessInstanceDTO
     * @param req
     * @param order
     * @return
     */
    @Override
    public StartProcessInstanceDTO setParams(StartProcessInstanceDTO startProcessInstanceDTO,UpdateOrderReq req,OrderMain order){

        //业务单走审核流
        startProcessInstanceDTO.setProcessDefinitionId(req.getProcessDefinitionId());
        startProcessInstanceDTO.setOrderId(order.getId());
        startProcessInstanceDTO.setUserId(req.getUserId());
        if (ObjectUtil.isNotEmpty(req.getNote())){
            startProcessInstanceDTO.setNote(req.getNote());
        }
        //装备列表
        startProcessInstanceDTO.setInvList(req.getInvList());
        startProcessInstanceDTO.setOutInState(req.getOrderType());
        startProcessInstanceDTO.setType("orderDto");
        startProcessInstanceDTO.setBussinessType(req.getBussinessType());
        if (req.getOrderType().equals("in")){
            //发物单位和收物单位
            switch (req.getBussinessType()){
                case "purchase":
                case "gift":
                case "repair":
                case "other":
                    startProcessInstanceDTO.setStartOrgName(req.getSupplierName());
                    startProcessInstanceDTO.setEndOrgName(req.getEndOrgName());
                    break;
                case "return":
                    startProcessInstanceDTO.setEndOrgName(req.getEndOrgName());
                    startProcessInstanceDTO.setStartUserName(req.getReturnUser());
                case "allocate":
                    startProcessInstanceDTO.setStartOrgName(req.getStartOrgName());
                    startProcessInstanceDTO.setEndOrgName(req.getEndOrgName());
                    break;
            }
        }else {
            //发物单位和收物单位
            switch (req.getBussinessType()){
                case "use":
                    startProcessInstanceDTO.setStartOrgName(req.getStartOrgName());
                    startProcessInstanceDTO.setEndUserName(req.getReturnUser());
                    break;
                case "allocate":
                    startProcessInstanceDTO.setStartOrgName(req.getStartOrgName());
                    startProcessInstanceDTO.setEndOrgName(req.getEndOrgName());
                    break;
                case "repair":
                case "destruction":
                case "other":
                    startProcessInstanceDTO.setStartOrgName(req.getStartOrgName());
                    startProcessInstanceDTO.setEndOrgName(req.getSupplierName());
                    break;
            }
        }
        Object A= JSON.toJSONString(req, SerializerFeature.WriteDateUseDateFormat);
        JSONObject jsonObject = JSON.parseObject(A.toString());

        startProcessInstanceDTO.setFormData(jsonObject);
        return startProcessInstanceDTO;
    }

    @Override
    //纪录日志
    public Boolean addOrderLog(UpdateOrderReq req,String orderId,String orderCode,String s){

        //我要的是detail的明细存入到history—msg中
        OrderLog orderLog = new OrderLog();
        orderLog.setId(UUID.randomUUID().toString());
        orderLog.setHistoryMsg(s);
        orderLog.setOrderCode(orderCode);
        orderLog.setBussinessType(req.getBussinessType());
        orderLog.setOrderType(req.getOrderType());
        if (ObjectUtil.isNotNull(req.getStartOrgUserName())){
            orderLog.setCreateUser(req.getStartOrgUserName());
        }else {
            orderLog.setCreateUser(req.getEndOrgUserName());
        }
        orderLog.setProcessType("createOrder");
        if (req.getOrderType().equals("in")){
            orderLog.setOrgId(req.getEndOrgId());
            orderLog.setOrgName(req.getEndOrgName());
        }else {
            orderLog.setOrgId(Long.parseLong(req.getStartOrgId()));
            orderLog.setOrgName(req.getStartOrgName());
        }
        orderLog.setOrderId(orderId);
        orderLog.setCreateTime(DateTimeUtil.getCurrentDateTime());

        return orderLogService.save(orderLog);
    }
    //修改业务单据可用次数
    private OrderMain setBusFormState(UpdateOrderReq req,OrderMain one,Long orgId){
        if (ObjectUtil.isNotNull(req.getId())){
            one = orderMainExist(req.getId());
            //如果入参与库存的bussiness_code都不为空则进一步进行判断
            if (ObjectUtil.isNotNull(req.getBussinessCode()) && ObjectUtil.isNotNull(one.getBussinessCode())) {
                //如果两个状态不相等，将原来数据绑定的单子恢复成上一次的状态，并且将入参的新单子的状态进行改动
                if (!one.getBussinessCode().equals(req.getBussinessCode())) {

                    //新绑定的单据修改状态(修改为true)
                    BusForm one1 = setState(req.getOrderType(),orgId, req.getBussinessCode(),true);
                    busFormService.updateById(one1);

                    //库存内的单据还原之前的状态（恢复为false）
                    BusForm one2 = setState(req.getOrderType(),orgId, one.getBussinessCode(),false);
                    busFormService.updateById(one2);

                }
            }
            //入参不为空，库里为空（表示之前没有绑定数据，现在入参绑定了一张单子）
            else if (ObjectUtil.isNotNull(req.getBussinessCode()) && ObjectUtil.isNull(one.getBussinessCode())){
                //只需要改一条数据
                //入参
                BusForm one1 = setState(req.getOrderType(),orgId, req.getBussinessCode(),true);
                busFormService.updateById(one1);
            }
            //入参为空，库里不为空（之前绑定了单子，现在入参取消绑定了）
            else if (ObjectUtil.isNull(req.getBussinessCode()) && ObjectUtil.isNotNull(one.getBussinessCode())){
                //只需要改一条数据
                //库存
                BusForm one2 = setState(req.getOrderType(),orgId, one.getBussinessCode(),false);
                busFormService.updateById(one2);
            }
            return one;
        }else {
            //表示直接绑定
            if (ObjectUtil.isNotNull(req.getBussinessCode())){
                //只需要更改一条单据
                //入参
                BusForm one1 = setState(req.getOrderType(),orgId, req.getBussinessCode(),true);
                busFormService.updateById(one1);
            }
            return one;
        }
    }

    //还原上次状态
    private BusForm setState(String orderType,Long orgId,String bussinessCode,boolean bindFlag){
        BusForm busform = new BusForm();
        if (bussinessCode.startsWith("DB") && orderType.equals("in")){
            busform = busFormService.list(new LambdaQueryWrapper<BusForm>()
                    .eq(BusForm::getEndOrgId, orgId)
                    .in(BusForm::getBussinessCode, bussinessCode)).get(0);
        } else if (bussinessCode.startsWith("DB") && orderType.equals("out")) {
            busform = busFormService.list(new LambdaQueryWrapper<BusForm>()
                    .eq(BusForm::getStartOrgId, orgId)
                    .in(BusForm::getBussinessCode, bussinessCode)).get(0);
        } else {
            busform = busFormService.list(new LambdaQueryWrapper<BusForm>()
                    .eq(BusForm::getOrgId, orgId)
                    .in(BusForm::getBussinessCode, bussinessCode)).get(0);
        }
        if (bindFlag && orderType.equals("in")){
            switch (busform.getOrderCurrentState()){
                case "bothuseing":
                    busform.setOrderCurrentState("outgoing");
                    break;
                case "outgoing":
                    busform.setOrderCurrentState("forbidden");
                    break;

            }
        } else if (bindFlag && orderType.equals("out")) {
            switch (busform.getOrderCurrentState()){
                case "bothuseing":
                    busform.setOrderCurrentState("incoming");
                    break;
                case "incoming":
                    busform.setOrderCurrentState("forbidden");
                    break;

            }
        } else if (!bindFlag && orderType.equals("in")){
            switch (busform.getOrderCurrentState()){

                case "forbidden":
                    busform.setOrderCurrentState("outgoing");
                    break;
                case "outgoing":
                    busform.setOrderCurrentState("bothuseing");
                    break;
            }
        }else {
            switch (busform.getOrderCurrentState()){
                case "forbidden":
                    busform.setOrderCurrentState("incoming");
                    break;
                case "incoming":
                    busform.setOrderCurrentState("bothuseing");
                    break;
            }
        }
        return busform;
    }


    //设置单据单号（并且对order_num表进行新增或者更新）
    public OrderNum setOrderCode(UpdateOrderReq req){
        //设置采购单号，需要先判断该组织机构的采购单号是否存在，如果存在则将数量进行增加，如果不存在则新增一条对应的数据
        OrderNum orderNum = new OrderNum();
        //获取年,月，日，获取业务出入状态，获取组织机构id，获取业务类型
        orderNum.setYear(LocalDateTime.now().getYear());
        //将业务类型转为中文简写(CK出库，RK入库)
        Long sysDictId = sysDictService.getOne(new LambdaQueryWrapper<SysDict>()
                .eq(SysDict::getDictCode, "order_chinese_setting")).getDictId();
        String itemValue = sysDictItemService.getOne(new LambdaQueryWrapper<SysDictItem>()
                .eq(SysDictItem::getItemText, req.getOrderType())
                .eq(SysDictItem::getDictId,sysDictId)).getItemValue();
        orderNum.setBussinessType(itemValue);
        //出入业务状态
        orderNum.setOutInType(req.getOrderType());
        //判断是出库还是入库，出库为发物单位，入库为收物单位
        OrderNum one = new OrderNum();
        if (req.getOrderType().equals("in")){
            orderNum.setEndOrgId(req.getEndOrgId());
            one = orderNumService.getOne(new LambdaQueryWrapper<OrderNum>()
                    .eq(OrderNum::getEndOrgId, orderNum.getEndOrgId())
                    .eq(OrderNum::getBussinessType, orderNum.getBussinessType())
                    .eq(OrderNum::getYear, orderNum.getYear())
                    .eq(OrderNum::getOutInType, orderNum.getOutInType()));
        }else {
            orderNum.setStartOrgId(Long.valueOf(req.getStartOrgId()));
            one = orderNumService.getOne(new LambdaQueryWrapper<OrderNum>()
                    .eq(OrderNum::getStartOrgId, orderNum.getStartOrgId())
                    .eq(OrderNum::getBussinessType,orderNum.getBussinessType())
                    .eq(OrderNum::getYear, orderNum.getYear())
                    .eq(OrderNum::getOutInType, orderNum.getOutInType()));
        }
        
        //设置num的数量
        if (ObjectUtil.isNull(one)){
            orderNum.setNum(1);
            orderNumService.save(orderNum);
            return orderNum;
        }else {
            one.setNum(one.getNum()+1);
            orderNumService.updateById(one);
            return one;
        }

    }




    //新增默认审核通过的任务单（可以没有工作流）
    @Transactional(rollbackFor = Exception.class)
    @Override
    public String AddFinishOrder(UpdateOrderReq req) {

        //添加到数据库中(如果该单据没有审批流，那么就直接存入数据库)
        if (ObjectUtil.isNull(req.getProcessDefinitionId()) && ObjectUtil.isNull(req.getProcessId())){
            List<String> strings = AddOrder(req);
            OrderMain orderMain = getById(strings.get(0));
            orderMain.setExamineState("finished");
            updateById(orderMain);

        }else {
            //单据类型，分发单据
            req.setApi("DistributeOrder");
            //将完成的任务单直接推送到消息队列rabbitmq中（需要判断是入库单还是出库单，入库单传发物单位id，出库单传收物单位id）
            //方法2：一个交换机，多个队列。动态创建队列
            String exchangeName="orderExchange";
            //需要判断是入库单还是出库单，入库单传收物单位id，出库单传发物单位id

            if(req.getOrderType().equals("in")){

                MQ.SendMsg(exchangeName,req.getEndOrgId().toString(),req);
            }else {
                MQ.SendMsg(exchangeName,req.getStartOrgId().toString(),req);
            }

        }

        return req.getId();
    }



    //更新任务单（进入工作流中之后不能进行更改）
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean  ChangeOrderState(UpdateOrderReq req) {
        OrderMain order = orderMainExist(req.getId());

        order.setExamineState(req.getExamineState());
        order.setOrderState(req.getOrderState());
        return this.updateById(order);
    }
    public boolean hasCommonElements(List<?> list1, List<?> list2) {
        for (Object item1 : list1) {
            if (list2.contains(item1)) {
                return true; // 找到相同值
            }
        }
        return false; // 没有相同值
    }

    //查询任务列表(根据组织机构id)
    @Override
    public PageResult<OrderMainDto> getOrderPage(OrderMainReq req) {
        Page<OrderMain> page = new Page<>();
        //排序字段处理，将驼峰改成和数据库同步的字段名(如果传其他不是数据库字段参数或者排序规则不是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());
        }
        //根据查询条件得到单据
        LoginUser loginUser = LoginContext.getContext().getLoginUser();
        String startOrgId=ObjectUtil.isNotEmpty(req.getStartOrgId())?req.getStartOrgId().toString():null;
        String endOrgId=ObjectUtil.isNotEmpty(req.getEndOrgId())?req.getEndOrgId().toString():null;
        IPage<OrderMain> outOrderPage = orderMainMapper.getOrderPage(PageFactory.getDefaultPage(req.getPageNo(), req.getPageSize()),req,loginUser.getUserId(),startOrgId,endOrgId);
        page.setRecords(outOrderPage.getRecords());
        page.setTotal(outOrderPage.getTotal());

        List<OrderMainDto> orderMainDtoList = page.getRecords().stream().map(orderMain -> {
            OrderMainDto orderMainDto = new OrderMainDto();
            BeanPlusUtil.copyProperties(orderMain,orderMainDto);
            return orderMainDto;
        }).collect(Collectors.toList());
        Page<OrderMainDto> page1 = PageFactory.getDefaultPage(req.getPageNo(), req.getPageSize());
        page1.setTotal(page.getTotal());
        page1.setRecords(orderMainDtoList);
        return PageResultFactory.createPageResult(page1);
    }



    //根据任务单id查看业务明细
    @Override
    public OrderDto GetDetailById(OrderMainReq req) {
        //判断任务单是否存在
        OrderMain orderMain=new OrderMain();
        if (ObjectUtil.isNotEmpty(req.getId())){

            orderMain = orderMainExist(req.getId());
        } else if (ObjectUtil.isNotEmpty(req.getProcessId())) {
            orderMain=orderMainExistByProcessId(req.getProcessId());
        }
        OrderDto orderDto = new OrderDto();
        BeanPlusUtil.copyProperties(orderMain,orderDto);
        List<OrderDetail> list=new ArrayList<>();
        //排序字段处理，将驼峰改成和数据库同步的字段名
        //将详细信息存入列表属性中
        //通过任务单id查询对应的详细信息
        if (ObjectUtil.isNotNull(req.getColumn()) && !req.getColumn().trim().isEmpty() &&
                (req.getOrder().equalsIgnoreCase("asc")|| req.getOrder().equalsIgnoreCase("desc")) && !req.getOrder().trim().isEmpty()) {
            //修改字段，和数据库字段进行统一
            req.setColumn(req.getColumn().replaceAll("[A-Z]", "_$0").toLowerCase());
            list=orderDetailService.list(new LambdaQueryWrapper<OrderDetail>()
                    .eq(OrderDetail::getOrderId, orderMain.getId())
                    .last("order by "+req.getColumn() +" "+req.getOrder()));

        } else {
            list = orderDetailService.list(new LambdaQueryWrapper<OrderDetail>()
                    .eq(OrderDetail::getOrderId, orderMain.getId())
                    .orderByDesc(OrderDetail::getCreateTime));
        }

        List<OrderDetailDto> orderDetailDtoList=new ArrayList<>();
        for (OrderDetail orderDetail:list) {
            OrderDetailDto orderDetailDto = new OrderDetailDto();
            BeanPlusUtil.copyProperties(orderDetail,orderDetailDto);
            String detailJson = orderDetail.getDetailJson();
            List<DetailJsonReq> detailJsonReqs = JSONObject.parseArray(detailJson, DetailJsonReq.class);
            if (CollectionUtil.isEmpty(detailJsonReqs)|| ObjectUtil.isNull(detailJsonReqs)){
                orderDetailDto.setChildJson(new ArrayList<>());
            }else {

                orderDetailDto.setChildJson(detailJsonReqs);
            }
            orderDetailDtoList.add(orderDetailDto);
        }


        orderDto.setDetailList(orderDetailDtoList);
        return orderDto;
    }

    //单据状态上报
    @Override
    public boolean PushState(OrderUploadReq req) {
        OrderMain orderMain = orderMainExist(req.getId());
        //获取单据的出入库，获取发物单位id或者收物单位id
        String orderType = orderMain.getOrderType();
        String exchangeName="OrderStateExchange";
        //推送到rabbitmq中去
        if (orderType.equals("in")){
            Long endOrgId = orderMain.getEndOrgId();
            Queue queue=new Queue(Long.toString(endOrgId),true,false,false);
            Exchange exchange = new DirectExchange(exchangeName, true, false);
            rabbitAdmin.declareQueue(queue);
            rabbitAdmin.declareExchange(exchange);
            rabbitAdmin.declareBinding(BindingBuilder.bind(queue).to(exchange).with(Long.toString(endOrgId)).noargs());
            rabbitTemplate.convertAndSend(exchangeName, Long.toString(endOrgId), req);

        }else {
            Long startOrgId = orderMain.getStartOrgId();
            Queue queue = new Queue(Long.toString(startOrgId), true, false, false);
            Exchange exchange = new DirectExchange(exchangeName, true, false);
            rabbitAdmin.declareQueue(queue);
            rabbitAdmin.declareExchange(exchange);
            rabbitAdmin.declareBinding(BindingBuilder.bind(queue).to(exchange).with(Long.toString(startOrgId)).noargs());
            rabbitTemplate.convertAndSend(exchangeName, Long.toString(startOrgId), req);
        }
        return true;
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean Accounting(UpdateOrderReq req) {
        //将组织机构下面的所有仓库进行查询
        //判断传递的订单主id是否存在
        OrderMain orderMain = orderMainExist(req.getId());
        //需要判断是否是下发到半山的单子，如果是则另一种记账方式，如果不是则用原来的单据记账方式
        if (ObjectUtil.isNotNull(orderMain.getSyncFlag()) && orderMain.getSyncFlag()==1){
            //判断单据是否存在正在执行的任务，如果存在则直接提示报错
            Long orgId= orderMain.getOrderType().equals("in")?orderMain.getEndOrgId():orderMain.getStartOrgId();
            SysDictItem one = sysDictItemService.getOne(new LambdaQueryWrapper<SysDictItem>()
                    .eq(SysDictItem::getItemText, orgId.toString()));
            Boolean flag =thirdPartyService.getTaskWokingState(orderMain.getOrderCode(),one.getItemValue());
            if (!flag){
                throw new ServiceException(OrderExceptionEnum.ORDER_IS_RUNNING_ERROR);
            }
            //判断是否是最新的出入库数据，如果是最新的进行下一步，如果不是最新的返回报错让前端进行弹窗后更新最新接口
            Boolean orderInfoResult =thirdPartyService.getLasterOrderInfo(orderMain.getId(),orderMain.getOrderType(),orderMain.getOrderCode(),one.getItemValue());
            if (!orderInfoResult){
                throw new ServiceException(OrderExceptionEnum.ORDER_IS_NOT_LASTER_ERROR);
            }

            //判断记账下发给半山是否能返回true，如果是不行则记账失败
            Boolean accountingResult = false;
            try {
                accountingResult = thirdPartyService.editOrderStatus(orderMain.getOrderCode(),one.getItemValue());
            } catch (Exception e) {
                throw new RuntimeException(e.getMessage());
            }
            if (!accountingResult){
                throw new ServiceException(OrderExceptionEnum.ORDER_IS_NOT_LASTER_ERROR);
            }

            //如果都顺利则直接开始记账操作
            Boolean reslut=false;
            if (orderMain.getOrderType().equals("in")){
                reslut=accountingBySyncInOrder(orderMain.getId(),req,orgId);

            }else {
                reslut=accountingBySyncOutOrder(orderMain.getId(),req,orgId);

            }
            return reslut;
        }

        //自动识别的epc
        List<Inventory> inventoryList = outInRecordRedisCache.addInventory("addInvRecord:" + orderMain.getId());
        //如果是调拨出库记账，那么默认创建一张调拨入库单
        if (orderMain.getBussinessType().equals("allocate") && orderMain.getOrderType().equals("out")){
            //需要判断一下该单据是否已经存在，如果存在则不进行创建
            if (ObjectUtil.isNull(orderMain.getBussinessCode())){
                addAllocateOrderAndMsg(orderMain);
            }
        }
        //如果是调拨入库记账，那么默认创建一张调拨出库单
        if (orderMain.getBussinessType().equals("allocate") && orderMain.getOrderType().equals("in")){
            //需要判断一下该单据是否已经存在，如果存在则不进行创建
            if (ObjectUtil.isNull(orderMain.getBussinessCode())){
                addAllocateOutOrderAndMsg(orderMain);
            }
        }
        String orgName=orderMain.getOrderType().equals("in") ? orderMain.getEndOrgName() : orderMain.getStartOrgName();
        Long orgId=orderMain.getOrderType().equals("in") ? orderMain.getEndOrgId() : orderMain.getStartOrgId();
        List<Warehouse> warehouseList = warehouseService.list(new LambdaQueryWrapper<Warehouse>().eq(Warehouse::getOrgIdInt,orgId));
        //获取组织机构下的所有仓库id
        Map<String,Warehouse> warehouseMap=new HashMap<>();
        warehouseList.forEach(warehouse -> warehouseMap.put(warehouse.getId(), warehouse));
        LoginUser loginUser = LoginContext.getContext().getLoginUser();
        //记账子单据不能传空
        if (req.getDetailList().size()==0){
            throw new ServiceException(OrderExceptionEnum.ORDERDETAIL_ISNOT_NULL);
        }
        //前端传递的子单数据
        List<UpdateOrderDetailReq> detailList = req.getDetailList();

        //将记账数量进行相加
        Integer updateQuantity=0;
        //获取子单据
        List<OrderDetail> list = orderDetailService.list(new LambdaQueryWrapper<OrderDetail>()
                .eq(OrderDetail::getOrderId,req.getId()));
        //获取所有传递的子单据id
        Set<Long> collect = req.getDetailList().stream().map(UpdateOrderDetailReq::getId).collect(Collectors.toSet());
        //获取所有数据库的子单据id
        Set<Long> existingIds = list.stream().map(OrderDetail::getId).collect(Collectors.toSet());
        //创建一个操作记录(用于在记账log表中记录)
        //存放更新数据库中的子单据
        List<OrderDetail> orderDetailList=new ArrayList<>();
        //创建一个列表用于修改summary数据库表中数据。
        List<UpdateOrderDetailReq> orderDetailReqList=new ArrayList<>();
        String stringtext="";
        Map<String,LogSummaryReq> logMap=new HashMap<>();
        List<LogSummaryReq> logList=new ArrayList<>();
        //将redis中的出入库记录一起存入数据库表中（根据orderMainId获取数据）
        //开始时间戳为2000年1月1日 00：00：00
        List<Object> dataByTimestampRange = outInRecordRedisCache.getDataByTimestampRange(orderMain.getId());
        List<String> epcList=new ArrayList<>();
        if (CollectionUtil.isNotEmpty(dataByTimestampRange)){

            List<LogSummaryReq> collect1 = dataByTimestampRange.stream().map(obj -> (LogSummaryReq) obj).collect(Collectors.toList());
            collect1.forEach(n ->
                    n.getLogList().forEach(x->
                    {
                        epcList.add(x.getEpc());
                    } )
            );
            logList.addAll(collect1);
        }
        //新增空装备（入库）
        List<Inventory> addInvList=new ArrayList<>();
        List<InventoryReq> addReqInvList=new ArrayList<>();
        List<WarehouseInventory> addWareInvList=new ArrayList<>();
        //编辑装备(出库)
        List<Inventory> updateInvList=new ArrayList<>();
        List<Inventory> updateInvStateList=new ArrayList<>();
        List<WarehouseInventory> updateWareInvStateList=new ArrayList<>();
        //比较两个子单id完全一致,判断传递的子单据id在数据库中是否存在，如果不存在则抛出子单据不存在异常
        if (collect.size() == existingIds.size() && collect.containsAll(existingIds) && existingIds.containsAll(collect)){

            //用于判断是否是空账(如果是false，则表示记空账)
            boolean flag=false;
            Map<String,InvSumSelectDto> invMap=new HashMap<>();
            //遍历子单
            for (UpdateOrderDetailReq uploadDetailReq : detailList) {
                OrderDetail orderDetail = new OrderDetail();
                BeanPlusUtil.copyProperties(uploadDetailReq,orderDetail);
                //记空账（识别0，记账0）
                if ((ObjectUtil.isNull(uploadDetailReq.getActualNum()) ||uploadDetailReq.getActualNum()==0)
                        && (ObjectUtil.isNull(uploadDetailReq.getModifyQuantity()) || uploadDetailReq.getModifyQuantity()==0)){
                    //添加出入库日志记录
                    if (orderMain.getOrderType().equals("in")){

                        stringtext = stringtext+uploadDetailReq.getTypeName()+"【"+
                                uploadDetailReq.getSizeName()+"】，单价："+uploadDetailReq.getPrice()
                                +"，数量实入：0，记账：0"+"\n";
                    }else {
                        stringtext = stringtext+uploadDetailReq.getTypeName()+"【"+
                                uploadDetailReq.getSizeName()+"】，单价："+uploadDetailReq.getPrice()
                                +"，数量实出：0，记账：0"+"\n";

                    }
                    orderDetail.setModifyQuantity(0);
                    orderDetail.setUpdateTime(DateTimeUtil.getCurrentDateTime());
                    orderDetailList.add(orderDetail);
                    updateQuantity+=orderDetail.getModifyQuantity();
                    continue;
                }
                flag=true;
                List<DetailJsonReq> JsonList = uploadDetailReq.getChildJson();
                String jsonString = JSONObject.toJSONString(JsonList);
                orderDetail.setDetailJson(jsonString);
                if (ObjectUtil.isNull(uploadDetailReq.getActualNum())){
                    uploadDetailReq.setActualNum(0);
                }
                //获取修改后的数量并且记录(modifyQuantity表示有记账数量)
                if (ObjectUtil.isNull(uploadDetailReq.getModifyQuantity())){
                    throw new ServiceException(OrderExceptionEnum.ORDER_NUM_IS_NULL);
                }
                if (uploadDetailReq.getModifyQuantity() >= 0 ){
                    Map<String,VieDestoryGroup> destoryGroupMap=new HashMap<>();
                    //遍历子单据下面的详细记账信息
                    for (DetailJsonReq detailJsonReq:JsonList) {

                        if (!warehouseMap.isEmpty()){
                            //判断是否有key存在，如果没有直接报错
                            boolean b = warehouseMap.containsKey(detailJsonReq.getLocationId());
                            if (b){
                                //判断改仓库是否处于锁库状态，如果是提示错误仓库正在锁库中
                                Warehouse warehouse = warehouseMap.get(detailJsonReq.getLocationId());
                                if (ObjectUtil.isNotNull(warehouse.getIsLocked())&& warehouse.getIsLocked()==1){
                                    throw new ServiceException(WarehouseExceptionEnum.WAREHOUSE_IS_LOCKED);
                                }
                            }
                        }

                        if (ObjectUtil.isNull(detailJsonReq.getModifyQuantity())){
                            detailJsonReq.setModifyQuantity(uploadDetailReq.getModifyQuantity());
                        }
                        //记账差值
                        int subNum=detailJsonReq.getModifyQuantity()-(ObjectUtil.isNull(detailJsonReq.getNum())?0:detailJsonReq.getNum());

                        //添加list为修改库存Summary
                        UpdateOrderDetailReq data = new UpdateOrderDetailReq();
                        data.setActualNum(ObjectUtil.isNull(detailJsonReq.getNum())?0:detailJsonReq.getNum());
                        data.setWarehouseId(detailJsonReq.getLocationId());
                        data.setOldLocationId(detailJsonReq.getOldLocationId());
                        data.setWarehouseName(detailJsonReq.getLocationName());
                        data.setSizeId(ObjectUtil.isNull(detailJsonReq.getSizeId())? uploadDetailReq.getSizeId():detailJsonReq.getSizeId());
                        data.setTypeId(ObjectUtil.isNull(detailJsonReq.getTypeId())? uploadDetailReq.getTypeId():detailJsonReq.getTypeId());
                        BigDecimal price=BigDecimal.ZERO;
                        if (ObjectUtil.isNull(detailJsonReq.getPrice()) && ObjectUtil.isNull(detailJsonReq.getUnitPrice())){
                            if (uploadDetailReq.getPrice().contains("/")) {
                                // 获取第一个斜杠前面的值
                                String firstPart = uploadDetailReq.getPrice().substring(0, uploadDetailReq.getPrice().indexOf("/"));

                                price=new BigDecimal(firstPart);
                            } else {
                                // 如果没有斜杠，则直接使用原始值
                                price=new BigDecimal(uploadDetailReq.getPrice());

                            }
                        }
                        data.setPrice((ObjectUtil.isNull(detailJsonReq.getPrice())  && ObjectUtil.isNull(detailJsonReq.getUnitPrice()))
                                ? price.toString() :ObjectUtil.isNull(detailJsonReq.getPrice() )?detailJsonReq.getUnitPrice().toString():detailJsonReq.getPrice().toString());
                        data.setProperty(ObjectUtil.isNull(detailJsonReq.getProperty())?0:detailJsonReq.getProperty());
                        data.setSizeName(ObjectUtil.isNotEmpty(detailJsonReq.getSizeName())?detailJsonReq.getSizeName():uploadDetailReq.getSizeName());
                        data.setTypeName(ObjectUtil.isNotEmpty(detailJsonReq.getTypeName())?detailJsonReq.getTypeName():uploadDetailReq.getTypeName());
                        data.setModifyQuantity(detailJsonReq.getModifyQuantity());
                        orderDetailReqList.add(data);
                        //设置childJson的必要参数
                        detailJsonReq.setSizeName(ObjectUtil.isNotEmpty(detailJsonReq.getSizeName())?detailJsonReq.getSizeName():uploadDetailReq.getSizeName());
                        detailJsonReq.setTypeName(ObjectUtil.isNotEmpty(detailJsonReq.getTypeName())?detailJsonReq.getTypeName():uploadDetailReq.getTypeName());
                        detailJsonReq.setSizeId(data.getSizeId());
                        detailJsonReq.setTypeId(data.getTypeId());
                        //添加出入库日志记录
                        if (orderMain.getOrderType().equals("in")){

                            stringtext = stringtext+detailJsonReq.getLocationName()+"--"+detailJsonReq.getTypeName()+"【"+
                                    detailJsonReq.getSizeName()+"】，单价："+((ObjectUtil.isNull(detailJsonReq.getPrice())  && ObjectUtil.isNull(detailJsonReq.getUnitPrice()))
                                    ? price.toString() :ObjectUtil.isNull(detailJsonReq.getPrice() )?detailJsonReq.getUnitPrice().toString():detailJsonReq.getPrice().toString())
                                    +"，数量实入："+(ObjectUtil.isNull(detailJsonReq.getNum())?0:detailJsonReq.getNum())+"，记账："+ detailJsonReq.getModifyQuantity()+"\n";
                        }else {
                            stringtext = stringtext+detailJsonReq.getLocationName()+"--"+detailJsonReq.getTypeName()+"【"+
                                    detailJsonReq.getSizeName()+"】，单价："+((ObjectUtil.isNull(detailJsonReq.getPrice())  && ObjectUtil.isNull(detailJsonReq.getUnitPrice()))
                                    ? price.toString() :ObjectUtil.isNull(detailJsonReq.getPrice() )?detailJsonReq.getUnitPrice().toString():detailJsonReq.getPrice().toString())
                                    +"，数量实出："+(ObjectUtil.isNull(detailJsonReq.getNum())?0:detailJsonReq.getNum())+"，记账："+ detailJsonReq.getModifyQuantity()+"\n";

                        }

                        Date productionDate=ObjectUtil.isNull(detailJsonReq.getProductionDate())?DateTimeUtil.DateByDays():DateTimeUtil.DaysToZero(detailJsonReq.getProductionDate());
                        String sizeId=ObjectUtil.isNull(detailJsonReq.getSizeId())? uploadDetailReq.getSizeId():detailJsonReq.getSizeId();
                        String typeId=ObjectUtil.isNull(detailJsonReq.getTypeId())? uploadDetailReq.getTypeId():detailJsonReq.getTypeId();
                        BigDecimal unitPrice=(ObjectUtil.isNull(detailJsonReq.getPrice())  && ObjectUtil.isNull(detailJsonReq.getUnitPrice()))
                                ? price :ObjectUtil.isNull(detailJsonReq.getPrice() )?detailJsonReq.getUnitPrice():detailJsonReq.getPrice();
                        //销毁单独处理重新计算销毁出库的汇总接口
//                        if (orderMain.getBussinessType().equals("destruction")){
//                            String key=orgId+detailJsonReq.getLocationId()+typeId+sizeId;
//                            destoryGroupMap=vieDestoryGroupService.createMap(destoryGroupMap,key,orgId,detailJsonReq,sizeId,typeId,orgName);
//                        }
                        if (subNum>0){
                            //判断是否存在仓库id的key，如果存在直接获取并且修改后再次添加，如果不存在则直接put
                            logMap=logSummaryService.setLogSummaryToMap(logMap,loginUser.getUserInfo().getRealName(),loginUser.getOrgName(),detailJsonReq.getLocationId(),req.getBussinessType(),
                                    uploadDetailReq.getTypeName(),detailJsonReq.getLocationName(),orderMain.getId(),
                                    orderMain.getOrderCode(),orgId,orderMain.getOrderType(),4,subNum,"0",null,null,null);
                            //如果没有绑定单子并且是归还单子的情况
                            if (ObjectUtil.isEmpty(orderMain.getBussinessCode()) && req.getBussinessType().equals("return")){
                                String locationId="";
                                if (ObjectUtil.isNotNull(detailJsonReq.getOldLocationId())){
                                    locationId=detailJsonReq.getOldLocationId();
                                }else {
                                    locationId=detailJsonReq.getLocationId();

                                }

                                String time=ObjectUtil.isNull(detailJsonReq.getProductionDate())?"null":DateTimeUtil.TimeDateToString(detailJsonReq.getProductionDate(),"yyyy-MM-dd HH:mm:ss");
                                String warrantyPeriod=ObjectUtil.isNull(detailJsonReq.getWarrantyPeriod())?"null":detailJsonReq.getWarrantyPeriod().toString();
                                String key=orgId+locationId+typeId+sizeId+unitPrice+time+detailJsonReq.getWarrantyPeriod();
                                if (invMap.containsKey(key)){
                                    InvSumSelectDto invSumSelectDto = invMap.get(key);
                                    invSumSelectDto.setSum(invSumSelectDto.getSum()+subNum);
                                    invMap.put(key,invSumSelectDto);
                                }else {
                                    InvSumSelectDto invSumSelectDto = new InvSumSelectDto();
                                    invSumSelectDto.setOrgId(orgId);
                                    invSumSelectDto.setLocationId(locationId);
                                    invSumSelectDto.setTypeId(typeId);
                                    invSumSelectDto.setSizeId(sizeId);
                                    invSumSelectDto.setUnitPrice(unitPrice);
                                    invSumSelectDto.setSum(subNum);
                                    invSumSelectDto.setProductionDate(time);
                                    invSumSelectDto.setWarrantyPeriod(warrantyPeriod);
                                    invMap.put(key,invSumSelectDto);
                                }
                            }
                            //实际出库或者入库数量大于实际数量，则对空数据进行增删改查
//                            if (orderMain.getOrderType().equals("in") && !req.getBussinessType().equals("allocate")){ //入库(排除调拨入库)
                            if (orderMain.getOrderType().equals("in")){ //入库
                                Random random = new Random();
                                for (int i=0;i<subNum;i++) {
                                    String epc="000000"+DateTimeUtil.getCurrentDateTime().getTime()+(random.nextInt(999999 - 100000 + 1) + 100000);
                                    InventoryReq inventoryReq = new InventoryReq();
                                    Inventory invInfo = createInvInfo(epc, orderMain, detailJsonReq, sizeId, typeId,
                                            price, productionDate, req.getBussinessType(), uploadDetailReq);
                                    addInvList.add(invInfo);
                                    BeanPlusUtil.copyProperties(invInfo,inventoryReq);
                                    addReqInvList.add(inventoryReq);
                                    WarehouseInventory warehouseInventory = createWareInvInfo(orderMain,epc,typeId,sizeId,orgName,detailJsonReq,uploadDetailReq);
                                    addWareInvList.add(warehouseInventory);
                                }

                            }
//                            else if (orderMain.getOrderType().equals("in") && req.getBussinessType().equals("allocate")) {//入库（调拨入库）
                                //如果是调拨入库，那么直接在调拨出库的基础上进行操作，调出什么epc，就直接把调出的epc的组织机构和仓库id进行修改
                                //根据组织机构和单据号进行查询出调拨出库的单子
                                //再将出入库信息查询出来


                            else {//出库
                                String startTime="";
                                String endTime="";
                                if (ObjectUtil.isNotNull(detailJsonReq.getProductionDate())){
                                    startTime= DateUtil.format(detailJsonReq.getProductionDate(), "yyyy-MM-dd HH:mm:ss");
                                    endTime= DateUtil.format(DateTimeUtil.setTimeToMax(detailJsonReq.getProductionDate()), "yyyy-MM-dd HH:mm:ss");

                                }
                                //需要先根据创建的单子进行查询，再随机将两个进行设置为出库
                                List<Inventory> eqsList=inventoryMapper.getEqsInfo(orgId,detailJsonReq.getLocationId(),typeId,
                                        sizeId,detailJsonReq.getUnitPrice(),detailJsonReq.getWarrantyPeriod(),
                                        startTime,endTime,orderMain.getBussinessType());
                                if (eqsList.size()>0){

                                    for (int i = 0; i < subNum; i++) {

                                        Inventory inventory = eqsList.get(i);
                                        updateInvList.add(inventory);

                                    }
                                }
                            }

                        }

                    }
//                    if (orderMain.getBussinessType().equals("destruction")){
//
//                        //如果单子是销毁出库，那么需要在更新vieDestoryGroup表
//                        vieDestoryGroupService.updateNum(destoryGroupMap);
//                    }
                    //修改单子数量数量
                    orderDetail.setModifyQuantity(uploadDetailReq.getModifyQuantity());
                    orderDetail.setUpdateTime(DateTimeUtil.getCurrentDateTime());
                    orderDetailList.add(orderDetail);
                    updateQuantity+=orderDetail.getModifyQuantity();

                }else {
                    throw new ServiceException(OrderExceptionEnum.ORDERDETAIL_ERROR);
                }
            }
            //记账0
            //用于判断是否是空账(如果是false，则表示记空账)
            if (!flag){
                orderMain.setActualQuantity(updateQuantity);
                orderMain.setOrderState("finished");
                //修改记账状态，0未记账，1已记账
                orderMain.setManualState(1);
                orderMain.setUpdateTime(DateTimeUtil.getCurrentDateTime());
                boolean a = orderDetailService.updateBatchById(orderDetailList);
                boolean b = updateById(orderMain);
                boolean c = saveAccountingLog(req, stringtext, updateQuantity);
                return a && b && c;
            }

            //入库添加虚拟装备(仅限于采购，其他以及赠与)
            if (CollectionUtil.isNotEmpty(addInvList) && !orderMain.getBussinessType().equals("return") &&!orderMain.getBussinessType().equals("repair")){
                inventoryService.saveBatch(addInvList);
            }
            //入库添加虚拟装备(仅限于采购，其他以及赠与)
            if (CollectionUtil.isNotEmpty(addWareInvList)&& !orderMain.getBussinessType().equals("return") &&!orderMain.getBussinessType().equals("repair")){
                warehouseInventoryService.saveBatch(addWareInvList);
            }

            //针对于归还入库和维修入库

            if (orderMain.getOrderType().equals("in") && (orderMain.getBussinessType().equals("return") || req.getBussinessType().equals("repair"))){
                //如果有单据，那么直接获取单子里面的装备；否则直接随机见
                //需要根据ordermain将业务单据里的出库单子找出来,现将虚拟物资的装备还原回来

                if (ObjectUtil.isNotEmpty(orderMain.getBussinessCode())){
                    List<LogSummaryReq> logSummaryList=logSummaryService.selectByOrderCode(orderMain.getBussinessCode(),orgId,epcList);
                    //如果查询到epcList是在库的那么直接替换别的epc
                    if (CollectionUtil.isNotEmpty(addReqInvList)){

                        Set<String> usedEpcs = new HashSet<>();

                        for (LogSummaryReq logSummaryReq : logSummaryList) {
                            String sizeId = logSummaryReq.getSizeId();
                            String typeId = logSummaryReq.getTypeId();
                            String epc = logSummaryReq.getEpc();

                            // 查找匹配的 sizeId 和 typeId 在 list2 中的位置
                            int index = findInvIndexForEpc(addReqInvList, sizeId, typeId, usedEpcs);

                            // 如果找到了可用的位置，则将 epc 赋值给该位置的元素
                            if (index != -1) {
                                InventoryReq inventoryReq = addReqInvList.get(index);
                                inventoryReq.setEpc(epc);
                                usedEpcs.add(epc);
                            }
                        }

                        LambdaUpdateWrapper<Inventory> wp1 = Wrappers.<Inventory>lambdaUpdate();
                        wp1.set(Inventory::getBussinessState,req.getBussinessType())
                                .set(Inventory::getLocationState, req.getOrderType())
                                .set(Inventory::getPoliceId,"0");
                        LambdaUpdateWrapper<WarehouseInventory> wp2 = Wrappers.<WarehouseInventory>lambdaUpdate();
                        wp2.set(WarehouseInventory::getLocationState, req.getOrderType());
                        for (int i = 0; i < addReqInvList.size(); i++) {
                            wp1.set(Inventory::getLocationId,addReqInvList.get(i).getLocationId())
                                    .eq(Inventory::getEpc, addReqInvList.get(i).getEpc())
                                    .eq(Inventory::getOrgId,addReqInvList.get(i).getOrgId());
                            wp2.set(WarehouseInventory::getLocationName,addReqInvList.get(i).getLocationName())
                                    .set(WarehouseInventory::getLocationId,addReqInvList.get(i).getLocationId())
                                    .eq(WarehouseInventory::getEpc, addReqInvList.get(i).getEpc())
                                    .eq(WarehouseInventory::getOrgId,addReqInvList.get(i).getOrgId());
                            if (i < addReqInvList.size()-1){
                                wp1.or();
                                wp2.or();
                            }
                            epcList.add(addReqInvList.get(i).getEpc());
                        }
                        inventoryService.update(wp1);
                        warehouseInventoryService.update(wp2);
                    }
                }
                else {
                    //没有绑定单子的情况
                    // 如果没有则直接随机挑选装备将其设置为在库状态
                    if (!invMap.isEmpty()){
                        List<InvSumSelectDto> collect1 = new ArrayList<>(invMap.values());
                        List<String> epcsInvList = inventoryList.stream().map(Inventory::getEpc).collect(Collectors.toList());
                        //原来仓库下的装备
                        updateInvStateList=inventoryMapper.getInvsExceptUseState(collect1,epcsInvList);
                        List<String> updateEpcList = updateInvStateList.stream().map(Inventory::getEpc).collect(Collectors.toList());
                        updateWareInvStateList = warehouseInventoryService.list(new LambdaQueryWrapper<WarehouseInventory>()
                                .eq(WarehouseInventory::getOrgId, orgId)
                                .eq(WarehouseInventory::getLocationState,"out")
                                .in(CollectionUtil.isNotEmpty(updateEpcList),WarehouseInventory::getEpc, updateEpcList));

                        Set<String> usedInvEpcs = new HashSet<>();
                        Set<String> usedWareInvEpcs = new HashSet<>();
                        for (Inventory inventory : updateInvStateList) {
                            String sizeId = inventory.getSizeId();
                            String typeId = inventory.getTypeId();
                            String epc = inventory.getEpc();

                            // 查找匹配的 sizeId 和 typeId 在 list2 中的位置
                            int index = findInvIndexForEpc(addReqInvList, sizeId, typeId, usedInvEpcs);

                            // 如果找到了可用的位置，则将 epc 赋值给该位置的元素
                            if (index != -1) {
                                InventoryReq inventoryReq = addReqInvList.get(index);
                                inventoryReq.setEpc(epc);
                                usedInvEpcs.add(epc);
                            }
                        }
                        for (WarehouseInventory warehouseInventory : updateWareInvStateList) {
                            String sizeId = warehouseInventory.getSizeId();
                            String typeId = warehouseInventory.getTypeId();
                            String epc = warehouseInventory.getEpc();

                            // 查找匹配的 sizeId 和 typeId 在 list2 中的位置
                            int index = findWareInvIndexForEpc(addWareInvList, sizeId, typeId, usedWareInvEpcs);

                            // 如果找到了可用的位置，则将 epc 赋值给该位置的元素
                            if (index != -1) {
                                WarehouseInventory wareInv = addWareInvList.get(index);
                                wareInv.setEpc(epc);
                                usedWareInvEpcs.add(epc);
                            }
                        }

                        for(Inventory inv:updateInvStateList){
                            for (InventoryReq invReq:addReqInvList){
                                if (inv.getEpc().equals(invReq.getEpc())){
                                    inv.setLocationId(invReq.getLocationId());
                                    inv.setLocationState("in");
                                    inv.setBussinessState("normal");
                                    break;
                                }
                            }
                        }


                        for (WarehouseInventory wareInv:updateWareInvStateList) {
                            for (WarehouseInventory wareInvReq:addWareInvList) {
                                if (wareInv.getEpc().equals(wareInvReq.getEpc())){
                                    wareInv.setLocationId(wareInvReq.getLocationId());
                                    wareInv.setLocationName(wareInvReq.getLocationName());
                                    wareInv.setLocationState("in");
                                    break;
                                }
                            }
                        }
                        boolean b = inventoryService.updateBatchById(updateInvStateList);
                        System.out.println("b = " + b);
                        boolean c = warehouseInventoryService.updateBatchById(updateWareInvStateList);
                        System.out.println("c = " + c);
                    }

                }

            }
            //入库记账logdetail
            if (CollectionUtil.isNotEmpty(addReqInvList)){

                logMap= logSummaryService.setLogDetailToMap(addReqInvList, logMap, orderMain.getBussinessType());
            }

            //出库记账logDetail
            if (CollectionUtil.isNotEmpty(updateInvList)){

                for (Inventory inv:updateInvList){
                    LogSummaryReq lsReq = logMap.get(inv.getLocationId()+orderMain.getOrderType());
                    List<LogDetailReq> logDetailList = lsReq.getLogList();
                    LogDetailReq logDetailReq = new LogDetailReq();
                    BeanPlusUtil.copyProperties(inv,logDetailReq);
                    logDetailReq.setOutInState(req.getOrderType());
                    logDetailReq.setBussinessType(orderMain.getBussinessType());
                    logDetailReq.setCreateTime(DateTimeUtil.getCurrentDateTime());
                    if (CollectionUtil.isEmpty(logDetailList)) {
                        lsReq.setLogList(new ArrayList<>());
                        logDetailList = lsReq.getLogList();
                    }
                    logDetailList.add(logDetailReq);
                    lsReq.setLogList(logDetailList);
                    logMap.put(inv.getLocationId()+orderMain.getOrderType(),lsReq);
                }
            }
            //出库更新装备状态和出库状态
            //出库记账
            if (CollectionUtil.isNotEmpty(updateInvList)){
                //更新数据库中实体类的状态
                LambdaUpdateWrapper<Inventory> wp1 = Wrappers.<Inventory>lambdaUpdate();
                LambdaUpdateWrapper<WarehouseInventory> wp2 = Wrappers.<WarehouseInventory>lambdaUpdate();
                String state="";
                if (orderMain.getBussinessType().equals("destruction")){
                    state="destory";
                    wp1.set(Inventory::getState, state)
                            .set(Inventory::getBussinessState,req.getBussinessType())
                            .set(Inventory::getLocationState, req.getOrderType());
                    wp2.set(WarehouseInventory::getLocationState, req.getOrderType());

                } else if (orderMain.getBussinessType().equals("allocate")) {
                    wp1.set(Inventory::getBussinessState, req.getBussinessType())
                            .set(Inventory::getLocationState, req.getOrderType())
                            .set(Inventory::getOrgId,null)
                            .set(Inventory::getLocationId,null);
                    wp2.set(WarehouseInventory::getLocationId,null)
                            .set(WarehouseInventory::getOrgId,null)
                            .set(WarehouseInventory::getLocationState, req.getOrderType());
                } else if (orderMain.getBussinessType().equals("quick")) {
                    //不做任何操作
                } else {
                    wp1.set(Inventory::getBussinessState, req.getBussinessType())
                            .set(Inventory::getLocationState, req.getOrderType());
                    wp2.set(WarehouseInventory::getLocationState, req.getOrderType());

                }
                //将快速移库不进行操作，后面单独操作
                if (!orderMain.getBussinessType().equals("quick")){

                    for (int i = 0; i < updateInvList.size(); i++) {
                        Inventory updateInv = updateInvList.get(i);
                        wp1.eq(Inventory::getId, updateInv.getId());
                        wp2.eq(WarehouseInventory::getId, updateInv.getWiId());
                        if (i < updateInvList.size()-1){
                            wp1.or();
                            wp2.or();
                        }
                    }
                    inventoryService.update(wp1);
                    warehouseInventoryService.update(wp2);
                }
            }
        }else {
            throw new ServiceException(OrderExceptionEnum.ORDERDETAIL_ERROR);
        }
        //批量更新子单据数量
        boolean a=false;
        if (orderDetailList.size()!=0){
            a = orderDetailService.updateBatchById(orderDetailList);
        }
        //更新主单据的数量和价格
        orderMain.setActualQuantity(updateQuantity);
        orderMain.setOrderState("finished");
        //修改记账状态，0未记账，1已记账
        orderMain.setManualState(1);
        orderMain.setUpdateTime(DateTimeUtil.getCurrentDateTime());
        boolean b = updateById(orderMain);


        //修改装备汇总表中的数据 inventory_summary

        PubOrg pubOrg = pubOrgService.PubOrgExist(orgId);



//        取了之后再进行将东西添加到出入库记录
//        将人工记账的数据一起存入logList;
        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);

        }
        //String为仓库id，List<String> 为epcList
        Map<String, List<String>> map=new HashMap<>();
        if (CollectionUtil.isNotEmpty(logList)){
            map= logSummaryService.addLogSummaryByClass(logList, req.getBussinessType());
            redisCache.remove("orderMainId:"+orderMain.getId());
        }
        //如果是快速移库，记账完成之后新增入库单并且该单据不走审核流，但是审核状态和入库状态显示已完成
        boolean d = true;
        if (!req.getBussinessType().equals("quick")){
            d=updateSummaryInfo(req,orderMain, orderDetailReqList, pubOrg.getOrgId(), pubOrg.getOrgCode(),pubOrg.getOrgName());
        }
        boolean g=true;
        if (orderMain.getBussinessType().equals("quick")){
            g = handleQuickOrder(orderMain,detailList,map);
        }
        //记账结束之后往消息队列中推送一条消息
//        String exchangeName="orderExchange";
        MQReturnMsgDto mqReturnMsgDto = new MQReturnMsgDto();
        mqReturnMsgDto.setApi("SettlementOrder");
        mqReturnMsgDto.setId(req.getId());
        mqReturnMsgDto.setOrderType(req.getOrderType());
        //需要判断是入库单还是出库单，入库单传收物单位id，出库单传发物单位id
        if(req.getOrderType().equals("in")){
            MQ.SendMsg("orderExchange",req.getEndOrgId().toString(),mqReturnMsgDto);
        }else {
            MQ.SendMsg("orderExchange",req.getStartOrgId().toString(),mqReturnMsgDto);
        }

        boolean e=true;
        //领用出库
        if (req.getBussinessType().equals("use")){
            //如果是领用出库，那记账结束以后将装备挂到警员名下（存储到policemanEquipment表中）
            Policeman policeman = policemanService.getOne(new LambdaQueryWrapper<Policeman>().eq(Policeman::getUserId, req.getReturnUserId()));
            if (ObjectUtil.isNull(policeman)){
                throw new ServiceException(PolicemanExceptionEnum.POLICEMAN_NOT_EXIST);
            }
            e = policeBindEqs(policeman,req, orderDetailReqList, orgId);
            e= policeBindEqsDetail(policeman,logList,orgId);
        }
//        //如果是归还入库，将警员下面的装备进行处理
        boolean f=true;
        if (req.getBussinessType().equals("return")){
            Policeman policeman = policemanService.getOne(new LambdaQueryWrapper<Policeman>().eq(Policeman::getUserId, req.getReturnUserId()));
            if (ObjectUtil.isNull(policeman)){
                throw new ServiceException(PolicemanExceptionEnum.POLICEMAN_NOT_EXIST);
            }
            f = policeUnBindEqs(policeman,req, orderDetailReqList, orgId);
            f= policeUnBindEqsDetail(policeman,epcList,updateInvStateList);
        }
        //添加日志

        //更新主单据
        String name="largeScreen_exchange";
        //记账后推送消息给大屏，大屏收到消息之后会自动重新调取接口
        rabbitTemplate.convertAndSend(name, "", "message");
        changePlanState();
        //将修改内容存储记录（历史操作，数量，单据，价格，组织机构）
        //创建记账操作记录并且记录到数据表order_log中
//        boolean c = saveAccountingLog(req, s, updateQuantity);
        boolean c = saveAccountingLog(req, stringtext, updateQuantity);

        //将记录进行修改存入
        if (orderMain.getBussinessType().equals("purchase") ||orderMain.getBussinessType().equals("gift")) {
            List<Inventory> inventories = outInRecordRedisCache.addInventory("addInvRecord:" + orderMain.getId());
            if (CollectionUtil.isNotEmpty(inventories)){
                boolean b1 = inventoryService.saveBatch(inventories);
                System.out.println("b1 = " + b1);
                redisCache.remove("addInvRecord:" + orderMain.getId());
            }
            List<WarehouseInventory> inventories1 = outInRecordRedisCache.addWareInventory("addInvWareRecord:" + orderMain.getId());
            if (CollectionUtil.isNotEmpty(inventories1)){
                boolean b1 = warehouseInventoryService.saveBatch(inventories1);
                System.out.println("b1 = " + b1);
                redisCache.remove("addInvWareRecord:" + orderMain.getId());
            }
        }else {//其他
            if (CollectionUtil.isNotEmpty(inventoryList)){

                updateInvsState(inventoryList,orderMain);
            }
        }
        return (a && b && c && d && e && f && g);

    }


    public Boolean accountingBySyncOutOrder(String orderMainId, UpdateOrderReq req, Long orgId) {

        OrderMain orderMain = getById(orderMainId);
        List<OrderDetail> orderDetailList = orderDetailService.list(new LambdaQueryWrapper<OrderDetail>()
                .eq(OrderDetail::getOrderId, orderMainId));
        //多的记账数进行记账后插入出入库日志
        PubOrg orgInfo = pubOrgService.getById(orgId);
        Map<Long, UpdateOrderDetailReq> orderDetailMap = new HashMap<>();
        Map<String,Object[]> invMap=new HashMap<>();
        Map<String,Object[]> searchMap=new HashMap<>();
        String stringtext = "";
        Integer updateQuantity=0;
        List<UpdateOrderDetailReq> detailReqList = req.getDetailList();
        for (OrderDetail orderDetail:orderDetailList){
            for (UpdateOrderDetailReq detailReq:detailReqList){
                if (orderDetail.getId().equals(detailReq.getId())){
                    if (detailReq.getModifyQuantity()>orderDetail.getModifyQuantity()){
                        List<DetailJsonReq> jsonList = detailReq.getChildJson();
                        detailReq.setWarehouseId(jsonList.get(0).getLocationId());
                        detailReq.setWarehouseName(jsonList.get(0).getLocationName());
                        detailReq.setSubNum(detailReq.getModifyQuantity()-orderDetail.getModifyQuantity());
                        orderDetailMap.put(detailReq.getId(),detailReq);
                        orderDetail.setWarehouseId(jsonList.get(0).getLocationId());
                        orderDetail.setWarehouseName(jsonList.get(0).getLocationName());
                        orderDetail.setModifyQuantity(detailReq.getModifyQuantity());
                        orderDetail.setUpdateTime(new Date());

                        //将人工记账的数据存入Log
                        stringtext = stringtext+detailReq.getWarehouseName()+"--"+orderDetail.getTypeName()+"【"+
                                orderDetail.getSizeName()+"】，"+"数量实出："+orderDetail.getActualNum()+"，记账："+ orderDetail.getModifyQuantity()+"\n";
                    }
                    updateQuantity=updateQuantity+orderDetail.getModifyQuantity();

                    //存入map为了方便查询InvList（进行统计数量）
                    String valuekey=createValueKey(orgInfo.getOrgCode(), orderDetail.getWarehouseId(), orderDetail.getTypeId(), orderDetail.getSizeId(), "0","0");
                    if (invMap.containsKey(valuekey)){
                        Object[] objects = invMap.get(valuekey);
                        objects[4]=(int)objects[4]+detailReq.getModifyQuantity();
                        invMap.put(valuekey,objects);
                    }else {
                        Object[] item=new Object[]{orgInfo.getOrgId(),orderDetail.getWarehouseId(),orderDetail.getTypeId(),orderDetail.getSizeId(),detailReq.getModifyQuantity()};
                        invMap.put(valuekey,item);
                    }

                }
            }
        }
        //手动记账将记账日志存入
        req.setActualQuantity(orderMain.getActualQuantity());
        Boolean result=saveAccountingLog(req, stringtext, updateQuantity);

        orderMain.setActualQuantity(updateQuantity);
        orderMain.setManualState(1);
        orderMain.setOrderState("finished");
        updateById(orderMain);

        //单据日志更新
        List<LogSummary> addLogSummaryList = createLogSummary(orderMain, orderDetailMap, orgInfo);

        List<Inventory> invList=new ArrayList<>();

        if (!invMap.isEmpty()){
            List<Object[]> itemList=new ArrayList<>(invMap.values());
            invList=inventoryMapper.getInfoList(itemList);
            for (Inventory inventory:invList) {
                String key=inventory.getOrgId()+inventory.getLocationId()+inventory.getTypeId()+inventory.getSizeId()+inventory.getPrice();
                if (searchMap.containsKey(key)){
                    Object[] objects = searchMap.get(key);
                    objects[5]=(Integer)objects[5]+1;
                    searchMap.put(key,objects);
                }else {
                    Object[] item=new Object[]{inventory.getOrgId(),inventory.getLocationId(),inventory.getTypeId(),inventory.getSizeId(),inventory.getPrice(),1};
                    searchMap.put(key,item);
                }

            }
        }
        //更新库存汇总
        List<InventorySummary> delList=new ArrayList<>();
        List<InventorySummary> inventorySummaryList = inventoryMapper.selectInvSum(new ArrayList<>(searchMap.values()));
        for (String key:searchMap.keySet()) {
            for (InventorySummary invSummary:inventorySummaryList) {
                String sumKey=invSummary.getOrgId()+invSummary.getLocationId()+invSummary.getTypeId()+invSummary.getSizeId()+invSummary.getUnitPrice();
                if (key.equals(sumKey)){
                    Object[] objects = searchMap.get(key);
                    if (orderMain.getBussinessType().equals("use")){
                        invSummary.setOutboundNumber(invSummary.getOutboundNumber()+(int)objects[5]);
                        invSummary.setStockNumber(Math.max(invSummary.getStockNumber()-(int)objects[5],0));
                        invSummary.setUseCount(invSummary.getUseCount()+(int)objects[5]);
                    }else {
                        invSummary.setNumber(Math.max(invSummary.getNumber()-(int)objects[5],0));
                        invSummary.setStockNumber(Math.max(invSummary.getStockNumber()-(int)objects[5],0));
                    }
                    if (invSummary.getNumber()==0 && invSummary.getStockNumber()==0){
                        delList.add(invSummary);
                    }
                }
            }
        }
        if (CollectionUtil.isNotEmpty(delList)){
            inventorySummaryService.removeBatchByIds(delList);
        }
        inventorySummaryService.updateBatchById(inventorySummaryList);

        orderDetailService.updateBatchById(orderDetailList);
        return true;
    }

    /**
     * 半山记账接口
     * @return
     */
    public Boolean accountingBySyncInOrder(String orderMainId, UpdateOrderReq req, Long orgId) {
        OrderMain orderMain = getById(orderMainId);
        List<OrderDetail> orderDetailList = orderDetailService.list(new LambdaQueryWrapper<OrderDetail>()
                .eq(OrderDetail::getOrderId, orderMainId));
        //多的记账数进行记账后插入出入库日志
        Map<Long, UpdateOrderDetailReq> orderDetailMap = new HashMap<>();
        Map<String,OrderDetail> summaryMap=new HashMap<>();
        PubOrg orgInfo = pubOrgService.getById(orgId);
        List<UpdateOrderDetailReq> detailReqList = req.getDetailList();
        String stringtext = "";
        Integer updateQuantity=0;
        for (OrderDetail orderDetail:orderDetailList){
            for (UpdateOrderDetailReq detailReq:detailReqList){
                if (orderDetail.getId().equals(detailReq.getId())){
                    if (ObjectUtil.isNull(orderDetail.getModifyQuantity())){
                        orderDetail.setModifyQuantity(0);
                    }
                    if (detailReq.getModifyQuantity()>orderDetail.getModifyQuantity()){
                        List<DetailJsonReq> jsonList = detailReq.getChildJson();
                        detailReq.setWarehouseId(jsonList.get(0).getLocationId());
                        detailReq.setWarehouseName(jsonList.get(0).getLocationName());
                        detailReq.setSubNum(detailReq.getModifyQuantity()-orderDetail.getModifyQuantity());
                        orderDetailMap.put(detailReq.getId(),detailReq);
                        orderDetail.setModifyQuantity(detailReq.getModifyQuantity());
                        orderDetail.setUpdateTime(new Date());
                        //将人工记账的数据存入Log
                        stringtext = stringtext+detailReq.getWarehouseName()+"--"+orderDetail.getTypeName()+"【"+
                                    orderDetail.getSizeName()+"】，单价："+ orderDetail.getPrice()
                                    +"，数量实入："+orderDetail.getActualNum()+"，记账："+ orderDetail.getModifyQuantity()+"\n";
                    }
                    updateQuantity=updateQuantity+orderDetail.getModifyQuantity();
                    String valuekey=createValueKey(orgInfo.getOrgCode(), detailReq.getWarehouseId(), orderDetail.getTypeId(), orderDetail.getSizeId(), orderDetail.getPrice(),"0");
                    if (summaryMap.containsKey(valuekey)){
                        OrderDetail detail = summaryMap.get(valuekey);
                        Integer modifyQty = detail.getModifyQuantity()+detailReq.getModifyQuantity();
                        detail.setModifyQuantity(modifyQty);
                        summaryMap.put(valuekey,detail);
                    }else {
                        summaryMap.put(valuekey,orderDetail);
                    }
                }
            }
        }
        //手动记账将记账日志存入
        req.setActualQuantity(orderMain.getActualQuantity());
        Boolean result=saveAccountingLog(req, stringtext, updateQuantity);
        List<OrderDetail> list1 = orderDetailService.list(new LambdaQueryWrapper<OrderDetail>().eq(OrderDetail::getOrderId, orderMain.getId()));
        System.out.println("list1 = " + list1);
        orderMain.setActualQuantity(updateQuantity);
        orderMain.setManualState(1);
        orderMain.setOrderState("finished");
        updateById(orderMain);
        //更新库存汇总
        List<String> valuekeyList = new ArrayList<>(summaryMap.keySet());
        List<InventorySummary> list = inventorySummaryService.list(new LambdaQueryWrapper<InventorySummary>().in(InventorySummary::getValuekey, valuekeyList));
        List<InventorySummary> addList=new ArrayList<>();
        for (InventorySummary invSummary : list) {
            Integer integer = summaryMap.get(invSummary.getValuekey()).getModifyQuantity();
            if (orderMain.getBussinessType().equals("return")){
                invSummary.setOutboundNumber(invSummary.getStockNumber() - integer);
                invSummary.setStockNumber(invSummary.getStockNumber() + integer);
            }else {
                invSummary.setStockNumber(invSummary.getStockNumber() + integer);
                invSummary.setNumber(invSummary.getNumber() + integer);
            }
            summaryMap.remove(invSummary.getValuekey());
        }
        if (!summaryMap.isEmpty()){
            //添加新的装备
            for (String valuekey:summaryMap.keySet()) {
                OrderDetail orderDetail = summaryMap.get(valuekey);
                if (ObjectUtil.isNotNull(orderDetail.getModifyQuantity()) || orderDetail.getModifyQuantity()!=0){

                    InventorySummary inventorySummary = createInventorySummary(orgInfo.getOrgId(),orgInfo.getOrgName(),orgInfo.getOrgCode(),
                            orderDetail.getTypeId(),orderDetail.getTypeName(),orderDetail.getSizeId(),orderDetail.getSizeName(),
                            orderDetail.getWarehouseId(),orderDetail.getWarehouseName(),orderDetail.getModifyQuantity(),
                            orderDetail.getModifyQuantity(),valuekey,new BigDecimal(orderDetail.getPrice()));
                    addList.add(inventorySummary);
                }
            }
        }
        if (CollectionUtil.isNotEmpty(addList)){
            inventorySummaryService.saveBatch(addList);
        }
        inventorySummaryService.updateBatchById(list);
        boolean b = orderDetailService.updateBatchById(orderDetailList);
        return  true;
    }

    public List<LogSummary> createLogSummary(OrderMain orderMain, Map<Long, UpdateOrderDetailReq> orderDetailMap,PubOrg orgInfo){
        List<LogSummary> addLogSummaryList=new ArrayList<>();
        for (Long orderId:orderDetailMap.keySet()) {
            LogSummary logSummary = new LogSummary();
            logSummary.setOrgId(orgInfo.getOrgId());
            logSummary.setOrgName(orgInfo.getOrgName());
            logSummary.setOrderMainId(orderMain.getId());
            logSummary.setOrderCode(orderMain.getOrderCode());
            logSummary.setDeviceType(4);
            logSummary.setLocationId(orderDetailMap.get(orderId).getWarehouseId());
            logSummary.setLocationName(orderDetailMap.get(orderId).getWarehouseName());
            logSummary.setLocationType(0);
            logSummary.setEquipmentList(orderDetailMap.get(orderId).getTypeName());
            logSummary.setOutInState(orderMain.getOrderType());
            logSummary.setNumber(orderDetailMap.get(orderId).getSubNum());
            logSummary.setCreateTime(new Date());
            logSummary.setUseTime(new Date());
            logSummary.setUpdateTime(new Date());
            logSummary.setBussinessType(orderMain.getBussinessType());
            logSummary.setUserName(LoginContext.getContext().getLoginUser().getUserInfo().getRealName());
            addLogSummaryList.add(logSummary);

        }
        logSummaryService.saveBatch(addLogSummaryList);
        return addLogSummaryList;
    }

    public InventorySummary createInventorySummary(Long orgId, String orgName, String orgCode, String typeId, String typeName,
                                               String sizeId, String sizeName, String locationId, String locationName,
                                               Integer stockNumber, Integer number, String valueKey,BigDecimal unitPrice) {
        InventorySummary inventorySummary = new InventorySummary();
        inventorySummary.setOrgId(orgId);
        inventorySummary.setTypeId(typeId);
        inventorySummary.setTypeName(typeName);
        inventorySummary.setSizeId(sizeId);
        inventorySummary.setSizeName(sizeName);
        inventorySummary.setLocationId(locationId);
        inventorySummary.setLocationName(locationName);
        inventorySummary.setValuekey(valueKey);
        inventorySummary.setOrgName(orgName);
        inventorySummary.setLocationName(locationName);
        inventorySummary.setOrgCode(orgCode);
        inventorySummary.setStockNumber(stockNumber);
        inventorySummary.setOutboundNumber(0);
        inventorySummary.setNumber(number);
        inventorySummary.setLocationType("0");
        inventorySummary.setUnitPrice(unitPrice);
        inventorySummary.setPrice(inventorySummary.getUnitPrice().multiply(BigDecimal.valueOf(inventorySummary.getNumber())));
        inventorySummary.setDestructionNumber(0);
        inventorySummary.setDestructionPrice(BigDecimal.ZERO);
        inventorySummary.setBrokenNumber(0);
        inventorySummary.setExpireNumber(0);
        inventorySummary.setUseNumber(0);
        inventorySummary.setUseCount(0);
        inventorySummary.setFixNumber(0);
        inventorySummary.setProperty(0);
        inventorySummary.setCreateTime(new Date());
        inventorySummary.setUpdateTime(new Date());
        return inventorySummary;
    }


    private Inventory createInvInfo(String epc,OrderMain orderMain,DetailJsonReq detailJsonReq,String sizeId,
                                    String typeId,BigDecimal price,Date productionDate,String bussinessType,UpdateOrderDetailReq uploadDetailReq){
        Inventory inventory = new Inventory();
        inventory.setEpc(epc);
        inventory.setLocationId(detailJsonReq.getLocationId());
        inventory.setSizeId(sizeId);
        inventory.setTypeId(typeId);
        inventory.setOrgId(orderMain.getEndOrgId());
        inventory.setLocationType(0);
        inventory.setPrice((ObjectUtil.isNull(detailJsonReq.getPrice())  && ObjectUtil.isNull(detailJsonReq.getUnitPrice()))
                ? price :ObjectUtil.isNull(detailJsonReq.getPrice() )?detailJsonReq.getUnitPrice():detailJsonReq.getPrice());
        inventory.setProperty(0);
        inventory.setEpcType(1);
        inventory.setState("normal");
        inventory.setBussinessState("normal");
        inventory.setCreateTime(DateTimeUtil.getCurrentDateTime());
        inventory.setProductionDate(productionDate);
        inventory.setWarrantyPeriod(ObjectUtil.isNull(detailJsonReq.getWarrantyPeriod())?
                12:detailJsonReq.getWarrantyPeriod());
        inventory.setMaintenancePeriod(ObjectUtil.isNull(detailJsonReq.getMaintenancePeriod())?
                12:detailJsonReq.getMaintenancePeriod());
        inventory.setTypeName(uploadDetailReq.getTypeName());
        inventory.setSizeName(uploadDetailReq.getSizeName());
        inventory.setLocationName(detailJsonReq.getLocationName());
        inventory.setBussinessType(bussinessType);
        inventory.setLocationState("in");
        inventory.setSupplierId(orderMain.getBussinessType().equals("purchase")?
                orderMain.getSupplierId():null);
        inventory.setSupplierName(orderMain.getBussinessType().equals("purchase")?
                orderMain.getSupplierName():null);
        inventory.setOldLocationId(detailJsonReq.getOldLocationId());
        return inventory;
    }

    private Inventory createInvInfo(String epc,Long orgId,String supplierId,String supplierName,String locationId,String locationName,
                                    Integer warrantyPeriod,Integer maintenancePeriod,String sizeId,String typeId,
                                    BigDecimal price,Date productionDate,String bussinessType,String typeName,String sizeName){
        Inventory inventory = new Inventory();
        inventory.setEpc(epc);
        inventory.setLocationId(locationId);
        inventory.setSizeId(sizeId);
        inventory.setTypeId(typeId);
        inventory.setOrgId(orgId);
        inventory.setLocationType(0);
        inventory.setPrice(price);
        inventory.setProperty(0);
        inventory.setEpcType(1);
        inventory.setState("normal");
        inventory.setBussinessState("normal");
        inventory.setCreateTime(DateTimeUtil.getCurrentDateTime());
        inventory.setProductionDate(productionDate);
        inventory.setWarrantyPeriod(warrantyPeriod);
        inventory.setMaintenancePeriod(maintenancePeriod);
        inventory.setTypeName(typeName);
        inventory.setSizeName(sizeName);
        inventory.setLocationName(locationName);
        inventory.setBussinessType(bussinessType);
        inventory.setLocationState("in");
        inventory.setSupplierId(supplierId);
        inventory.setSupplierName(supplierName);
        inventory.setOldLocationId(locationId);
        return inventory;
    }

    private WarehouseInventory createWareInvInfo(OrderMain orderMain,String epc,String typeId,String sizeId,String orgName,
                                                 DetailJsonReq detailJsonReq,UpdateOrderDetailReq uploadDetailReq){
        WarehouseInventory warehouseInventory = new WarehouseInventory();
        warehouseInventory.setOrgId(orderMain.getEndOrgId());
        warehouseInventory.setEpc(epc);
        warehouseInventory.setLocationId(detailJsonReq.getLocationId());
        warehouseInventory.setOldLocationId(detailJsonReq.getOldLocationId());
        warehouseInventory.setTypeId(typeId);
        warehouseInventory.setSizeId(sizeId);
        warehouseInventory.setLocationType("0");
        warehouseInventory.setLocationState("in");
        warehouseInventory.setCreateTime(DateTimeUtil.getCurrentDateTime());
        warehouseInventory.setOrgName(orgName);
        warehouseInventory.setEpcType(1);
        warehouseInventory.setTypeName(uploadDetailReq.getTypeName());
        warehouseInventory.setSizeName(uploadDetailReq.getSizeName());
        warehouseInventory.setLocationName(detailJsonReq.getLocationName());
        return warehouseInventory;
    }

    private WarehouseInventory createWareInvInfo(Long orgId,String epc,String typeId,String sizeId,String orgName,
                                                 String locationId,String locationName,String typeName,String sizeName){
        WarehouseInventory warehouseInventory = new WarehouseInventory();
        warehouseInventory.setOrgId(orgId);
        warehouseInventory.setEpc(epc);
        warehouseInventory.setLocationId(locationId);
        warehouseInventory.setOldLocationId(locationId);
        warehouseInventory.setTypeId(typeId);
        warehouseInventory.setSizeId(sizeId);
        warehouseInventory.setLocationType("0");
        warehouseInventory.setLocationState("in");
        warehouseInventory.setCreateTime(DateTimeUtil.getCurrentDateTime());
        warehouseInventory.setOrgName(orgName);
        warehouseInventory.setEpcType(1);
        warehouseInventory.setTypeName(typeName);
        warehouseInventory.setSizeName(sizeName);
        warehouseInventory.setLocationName(locationName);
        return warehouseInventory;
    }

    private void updateInvsState(List<Inventory> inventoryList,OrderMain orderMain){
        LambdaUpdateWrapper<Inventory> updateStateWrapper1 = Wrappers.lambdaUpdate();
        LambdaUpdateWrapper<Inventory> allocateInWrapper1 = Wrappers.lambdaUpdate();
        LambdaUpdateWrapper<WarehouseInventory> updateStateWrapper2 = Wrappers.lambdaUpdate();
        LambdaUpdateWrapper<WarehouseInventory> allocateInWrapper2 = Wrappers.lambdaUpdate();
        for (Inventory inventory:inventoryList) {
            if (inventory.getBussinessType().equals("allocate") && inventory.getLocationState().equals("in")){
                //调拨入库
                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")){
                //调拨出库，不操作
                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");
                updateStateWrapper2.or().eq(WarehouseInventory::getEpc,inventory.getEpc())
                        .set(WarehouseInventory::getLocationState,"out");
            }else if (inventory.getBussinessType().equals("quick")){
                //不做操作，等记账统一替换

            }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);
        }
        redisCache.remove("addInvRecord:" + orderMain.getId());
    }

    public void changePlanState(){
        //根据单子查询出所有预案发起的调拨单子，如果有则直接判断并进行更新，如果没有直接跳过
        planInitiationItemMapper.getPlanInfoByOrderId();

    }


    private boolean policeUnBindEqsDetail(Policeman policeman, List<String> epcList,List<Inventory> updateStateList) {
        List<String> collect = updateStateList.stream().map(Inventory::getEpc).collect(Collectors.toList());
        if (CollectionUtil.isNotEmpty(epcList)){
            List<PoliceEquipmentDetail> list = policeEquipmentDetailService.list(new LambdaQueryWrapper<PoliceEquipmentDetail>()
                    .eq(PoliceEquipmentDetail::getPoliceId, policeman.getId())
                    .in(CollectionUtil.isNotEmpty(epcList),PoliceEquipmentDetail::getEpc, epcList));
            if (CollectionUtil.isNotEmpty(list)){
                return policeEquipmentDetailService.removeBatchByIds(list);
            }
        }else {
            List<PoliceEquipmentDetail> list = policeEquipmentDetailService.list(new LambdaQueryWrapper<PoliceEquipmentDetail>()
                    .eq(PoliceEquipmentDetail::getPoliceId, policeman.getId())
                    .in(CollectionUtil.isNotEmpty(collect),PoliceEquipmentDetail::getEpc, collect));
            if (CollectionUtil.isNotEmpty(list)){
                return policeEquipmentDetailService.removeBatchByIds(list);
            }
        }
        return true;
    }

    private boolean policeBindEqsDetail(Policeman policeman, List<LogSummaryReq> logList, Long orgId) {

        List<PoliceEquipmentDetail> list=new ArrayList<>();
        for (LogSummaryReq ls:logList) {
            if (ls.getLogList().size()>0){

                for (LogDetailReq ld:ls.getLogList()) {
                    PoliceEquipmentDetail detail = new PoliceEquipmentDetail();
                    BeanPlusUtil.copyProperties(ld,detail);
                    detail.setPoliceId(policeman.getId());
                    detail.setOrgId(orgId.toString());
                    detail.setLocationId(ls.getLocationId());
                    detail.setLocationState(ld.getOutInState());
                    list.add(detail);
                }
            }
        }
        return policeEquipmentDetailService.saveBatch(list);

    }


    @Transactional
    public boolean policeUnBindEqs(Policeman policeman,UpdateOrderReq req,List<UpdateOrderDetailReq> orderDetailReqList,Long orgId){
        //根据传递的装备信息对警员进行解绑操作(判断警员下面是否有装备信息，如果有则直接进行修改或者删除，如果没有则跳过不处理)

        List<PoliceEquipment> list = policeEquipmentService.list(new LambdaQueryWrapper<PoliceEquipment>()
                .eq(ObjectUtil.isNotNull(req.getReturnUserId()), PoliceEquipment::getPoliceId, policeman.getId())
                .eq(PoliceEquipment::getOrgId,orgId));
        List<PoliceEquipment> delList=new ArrayList<>();
        List<PoliceEquipment> updateList=new ArrayList<>();
        if (list.size()>0){
            for (UpdateOrderDetailReq upReq:orderDetailReqList) {
                String locationId=ObjectUtil.isNotEmpty(upReq.getOldLocationId()) || ObjectUtil.isNotNull(upReq.getOldLocationId())?upReq.getOldLocationId():upReq.getWarehouseId();
                for (PoliceEquipment pEqs:list ) {
                    if (locationId.equals(pEqs.getLocationId()) && upReq.getSizeId().equals(pEqs.getSizeId()) && upReq.getTypeId().equals(pEqs.getTypeId())
                            && new BigDecimal(upReq.getPrice()).compareTo(pEqs.getPrice())==0){
                        //如果数量大于等于的情况下直接将该条数据进行删除，否则直接修改数量并且更新
                        if (upReq.getModifyQuantity()>=pEqs.getNum()){
                            delList.add(pEqs);
                        }else {
                            pEqs.setNum(pEqs.getNum()-upReq.getModifyQuantity());
                            pEqs.setOutNum(pEqs.getOutNum()-upReq.getModifyQuantity());
                            updateList.add(pEqs);
                        }
                        break;
                    }
                }
            }
            boolean a=true;
            if (delList.size()>0){
                a=policeEquipmentService.removeBatchByIds(delList);
            }
            boolean b=true;
            if (updateList.size()>0){
                b=policeEquipmentService.updateBatchById(updateList);
            }
            return a && b;
        }else {
            return  true;
        }
    }

    @Transactional
    public boolean policeBindEqs(Policeman policeman,UpdateOrderReq req,List<UpdateOrderDetailReq> orderDetailReqList,Long orgId){
        List<PoliceEquipment> list = policeEquipmentService.list(new LambdaQueryWrapper<PoliceEquipment>()
                .eq(ObjectUtil.isNotNull(req.getReturnUserId()), PoliceEquipment::getPoliceId, policeman.getId())
                .eq(PoliceEquipment::getOrgId,orgId));
        List<PoliceEquipment> addList=new ArrayList<>();
        List<PoliceEquipment> updateList=new ArrayList<>();
        if (list.size()>0){
            for (UpdateOrderDetailReq upReq:orderDetailReqList) {
                boolean flag=false;
                for (PoliceEquipment pEqs:list) {
                    if (upReq.getWarehouseId().equals(pEqs.getLocationId()) && upReq.getSizeId().equals(pEqs.getSizeId()) && upReq.getTypeId().equals(pEqs.getTypeId())
                            && new BigDecimal(upReq.getPrice()).compareTo(pEqs.getPrice())==0){
                        pEqs.setNum(pEqs.getNum()+upReq.getModifyQuantity());
                        pEqs.setOutNum(pEqs.getOutNum()+upReq.getModifyQuantity());
                        updateList.add(pEqs);
                        flag=true;
                        break;
                    }
                }
                if (!flag){
                    PoliceEquipment policeEquipment = new PoliceEquipment();
                    policeEquipment.setPoliceId(policeman.getId());
                    policeEquipment.setPoliceName(policeman.getName());
                    policeEquipment.setSizeId(upReq.getSizeId());
                    policeEquipment.setSizeName(upReq.getSizeName());
                    policeEquipment.setTypeId(upReq.getTypeId());
                    policeEquipment.setTypeName(upReq.getTypeName());
                    policeEquipment.setNum(upReq.getModifyQuantity());
                    policeEquipment.setInNum(0);
                    policeEquipment.setOutNum(upReq.getModifyQuantity());
                    policeEquipment.setOrgId(orgId);
                    policeEquipment.setPrice(new BigDecimal(upReq.getPrice()));
                    policeEquipment.setLocationId(upReq.getWarehouseId());
                    policeEquipment.setCreateTime(DateTimeUtil.getCurrentDateTime());
                    addList.add(policeEquipment);
                }
            }

        }else {
            List<PoliceEquipment> collect1 = orderDetailReqList.stream().map(updateOrderDetailReq -> {
                PoliceEquipment policeEquipment = new PoliceEquipment();
                policeEquipment.setPoliceId(policeman.getId());
                policeEquipment.setPoliceName(policeman.getName());
                policeEquipment.setSizeId(updateOrderDetailReq.getSizeId());
                policeEquipment.setSizeName(updateOrderDetailReq.getSizeName());
                policeEquipment.setTypeId(updateOrderDetailReq.getTypeId());
                policeEquipment.setTypeName(updateOrderDetailReq.getTypeName());
                policeEquipment.setNum(updateOrderDetailReq.getModifyQuantity());
                policeEquipment.setInNum(0);
                policeEquipment.setOutNum(updateOrderDetailReq.getModifyQuantity());
                policeEquipment.setOrgId(orgId);
                policeEquipment.setPrice(new BigDecimal(updateOrderDetailReq.getPrice()));
                policeEquipment.setLocationId(updateOrderDetailReq.getWarehouseId());
                policeEquipment.setCreateTime(DateTimeUtil.getCurrentDateTime());
                return policeEquipment;
            }).collect(Collectors.toList());
            addList.addAll(collect1);
        }
        if (CollectionUtil.isNotEmpty(addList)){
            policeEquipmentService.saveBatch(addList);
        }
        if (CollectionUtil.isNotEmpty(updateList)){
            policeEquipmentService.updateBatchById(updateList);
        }
        return true;

    }

    //将修改内容存储记录（历史操作，数量，单据，价格，组织机构）
    //创建记账操作记录并且记录到数据表order_log中
//    @Transactional
    public boolean saveAccountingLog (UpdateOrderReq req,String s,Integer updateQuantity){

        OrderLog orderLog = new OrderLog();
        BeanPlusUtil.copyProperties(req,orderLog);
        orderLog.setId(UUID.randomUUID().toString());
        orderLog.setHistoryMsg(s);
        orderLog.setInventoryQuantity(req.getInventoryQuantity());
        orderLog.setActualQuantity(req.getActualQuantity());
        orderLog.setUpdateQuantity(updateQuantity);
        if (req.getOrderType().equals("in")){
            orderLog.setOrgId(req.getEndOrgId());
            orderLog.setOrgName(req.getEndOrgName());
        }else {
            orderLog.setOrgId(Long.parseLong(req.getStartOrgId()));
            orderLog.setOrgName(req.getStartOrgName());
        }
        orderLog.setOrderId(req.getId());
        String userId="";
        if (ObjectUtil.isNotNull(req.getUserId())){
            userId=req.getUserId();
        }else {
            LoginUser loginUser = LoginContext.getContext().getLoginUser();
            userId=loginUser.getUserId().toString();
        }
        SysUser sysUser = sysUserService.getById(userId);
        orderLog.setCreateUser(sysUser.getNickName());
        orderLog.setCreateTime(DateTimeUtil.getCurrentDateTime());
        orderLog.setProcessType("accounting");
        //将记账记录保存
        return orderLogService.save(orderLog);
    }

    //修改装备汇总表中的数据inventory_summary
    @Transactional
    public boolean updateSummaryInfo(UpdateOrderReq req,OrderMain orderMain,List<UpdateOrderDetailReq> orderDetailReqList,
                                     Long orgId,String orgCode,String orgName){
        //将库存summary表中数据进行查询出来一一进行比较，如果说sizeId，typeId，warehouseId相同则对该数据进行修改，如果说该数据不存在的话则在summary表中添加一条数据

        //将子单据进行汇总
        //加一个具体的list最终去遍历
        Map<String,UpdateOrderDetailReq> map=new HashMap<>();
        Map<String,UpdateOrderDetailReq> oldMap=new HashMap<>();

        List<InventorySummary> delList=new ArrayList<>();

        for (UpdateOrderDetailReq detailReq:orderDetailReqList) {
            if (ObjectUtil.isNotNull(detailReq.getOldLocationId()) && !detailReq.getOldLocationId().equals(detailReq.getWarehouseId())){
                //做删除操作，将原来出库数减少，库存总数减少
                String oldKey=orgId+detailReq.getOldLocationId()+detailReq.getTypeId()+detailReq.getSizeId()+detailReq.getPrice()+detailReq.getProperty();
                if (oldMap.containsKey(oldKey)){
                    UpdateOrderDetailReq updateReq = oldMap.get(oldKey);
                    updateReq.setModifyQuantity(updateReq.getModifyQuantity()+detailReq.getModifyQuantity());
                    updateReq.setActualNum(updateReq.getActualNum()+detailReq.getActualNum());
                    oldMap.put(oldKey,updateReq);

                }else {
                    UpdateOrderDetailReq updateReq = new UpdateOrderDetailReq();
                    BeanPlusUtil.copyProperties(detailReq,updateReq);
                    oldMap.put(oldKey,updateReq);
                }
                detailReq.setAddFlag(true);
                //表示入库，原库存的出库数不变，只新增在库数，因为归还入库的新仓库应该保持他原来的出库数量
                detailReq.setReturnNumber(detailReq.getModifyQuantity());
            }else {
                detailReq.setAddFlag(false);
            }
            String key=orgId+detailReq.getWarehouseId()+detailReq.getTypeId()+detailReq.getSizeId()+detailReq.getPrice()+detailReq.getProperty();
            if (map.containsKey(key)){
                UpdateOrderDetailReq updateReq = map.get(key);
                updateReq.setModifyQuantity(updateReq.getModifyQuantity()+detailReq.getModifyQuantity());
                updateReq.setActualNum(updateReq.getActualNum()+detailReq.getActualNum());
                map.put(key,updateReq);

            }else {
                UpdateOrderDetailReq updateReq = new UpdateOrderDetailReq();
                BeanPlusUtil.copyProperties(detailReq,updateReq);
                map.put(key,updateReq);
            }

        }
        //查询库存汇总
        List<Object[]> searchCriteria=new ArrayList<>();
        for (String key : map.keySet()) {
            UpdateOrderDetailReq value = map.get(key);
            Object[] criteria=new Object[]{orgId,value.getWarehouseId(),value.getTypeId(),value.getSizeId(),value.getPrice(),value.getProperty()};
            searchCriteria.add(criteria);
        }

        //如果不选仓库直接是0记账那么默认直接记账结束
        if(CollectionUtil.isEmpty(searchCriteria)){
            return true;
        }
        //库存信息
        //先把需要删除的库存汇总进行计算并且更新（以防止后面新增时数据混乱）
        List<Object[]> searchOldCriteria=new ArrayList<>();
        for (String key : oldMap.keySet()) {
            UpdateOrderDetailReq value = oldMap.get(key);
            Object[] criteria=new Object[]{orgId,value.getOldLocationId(),value.getTypeId(),value.getSizeId(),value.getPrice(),value.getProperty()};
            searchOldCriteria.add(criteria);
        }
        if (CollectionUtil.isNotEmpty(searchOldCriteria)){
            List<InventorySummary> inventoryOldSummaryList = inventorySummaryMapper.selectSum(searchOldCriteria);
            for (String key : oldMap.keySet()) {
                UpdateOrderDetailReq upReq = oldMap.get(key);
                Integer subNum=0;
                boolean flag=false;
                for (InventorySummary is:inventoryOldSummaryList) {
                    if (upReq.getWarehouseId().equals(is.getLocationId()) && upReq.getSizeId().equals(is.getSizeId())
                            && upReq.getTypeId().equals(is.getTypeId()) && new BigDecimal(upReq.getPrice()).compareTo(is.getUnitPrice())==0){
                        is.setUpdateTime(DateTimeUtil.getCurrentDateTime());
                        subNum=is.getOutboundNumber()-upReq.getModifyQuantity();
                        is.setNumber(subNum>0?is.getNumber()-upReq.getModifyQuantity():is.getNumber()-is.getOutboundNumber());
                        is.setOutboundNumber(Math.max(is.getOutboundNumber()-upReq.getModifyQuantity(),0));
                        //如果库存数为0，那么直接删除该条记录
                        if (is.getNumber()==0 && is.getStockNumber()==0 && is.getOutboundNumber()==0 && is.getBrokenNumber()==0 && is.getDestructionNumber()==0){
                            delList.add(is);
                            inventoryOldSummaryList.remove(is);
                        }
                        flag=true;
                        break;
                    }
                }

                List<Object[]> criteria=new ArrayList<>();
                Object[] item=new Object[]{orgId,upReq.getWarehouseId(),upReq.getTypeId(),upReq.getSizeId(),upReq.getPrice(),"1"};
                criteria.add(item);
                if (!flag){
                    List<InventorySummary> inventorySummaryList = inventorySummaryMapper.selectSum(searchOldCriteria);
                    InventorySummary is = inventorySummaryList.get(0);
                    is.setUpdateTime(DateTimeUtil.getCurrentDateTime());
                    is.setNumber(is.getNumber()-upReq.getModifyQuantity());
                    is.setOutboundNumber(Math.max(is.getOutboundNumber()-upReq.getModifyQuantity(),0));
                    //如果库存数为0，那么直接删除该条记录
                    if (is.getNumber()==0 && is.getStockNumber()==0 && is.getOutboundNumber()==0 && is.getBrokenNumber()==0 && is.getDestructionNumber()==0){
                        delList.add(is);
                        inventoryOldSummaryList.remove(is);
                    }
                    inventoryOldSummaryList.addAll(inventorySummaryList);
                } else if (flag && subNum<0) {
                    List<InventorySummary> inventorySummaryList = inventorySummaryMapper.selectSum(criteria);
                    InventorySummary is = inventorySummaryList.get(0);
                    is.setUpdateTime(DateTimeUtil.getCurrentDateTime());
                    is.setNumber(is.getNumber()-Math.abs(subNum));
                    is.setOutboundNumber(Math.max(is.getOutboundNumber()-Math.abs(subNum),0));
                    //如果库存数为0，那么直接删除该条记录
                    if (is.getNumber()==0 && is.getStockNumber()==0 && is.getOutboundNumber()==0 && is.getBrokenNumber()==0 && is.getDestructionNumber()==0){
                        delList.add(is);
                        inventoryOldSummaryList.remove(is);
                    }
                    inventoryOldSummaryList.addAll(inventorySummaryList);
                }
            }
            inventorySummaryService.updateBatchById(inventoryOldSummaryList);
        }


        List<InventorySummary> inventorySummaryList = inventorySummaryMapper.selectSum(searchCriteria);
        List<InventorySummary> addList=new ArrayList<>();
        List<InventorySummary> updateList=new ArrayList<>();


        Integer subNum=0;
        for (String key : map.keySet()) {
            UpdateOrderDetailReq upReq = map.get(key);

            boolean flag=false;
            for (InventorySummary is:inventorySummaryList) {
                if (upReq.getWarehouseId().equals(is.getLocationId()) && upReq.getSizeId().equals(is.getSizeId())
                        && upReq.getTypeId().equals(is.getTypeId()) && new BigDecimal(upReq.getPrice()).compareTo(is.getUnitPrice())==0){
                    is.setUpdateTime(DateTimeUtil.getCurrentDateTime());
                    //修改各种数量和价格

                    if (req.getOrderType().equals("in")){
                        subNum=is.getOutboundNumber()-upReq.getModifyQuantity();
                        switch (orderMain.getBussinessType()){
                            case "purchase":
                            case "allocate":
                            case "gift":
                            case "other":
                                is.setStockNumber(is.getStockNumber()+upReq.getModifyQuantity());
                                is.setNumber(is.getNumber()+upReq.getModifyQuantity());
                                is.setPrice(is.getUnitPrice().multiply(BigDecimal.valueOf(is.getNumber())));
                                break;
                            case "return":
                                //如果入库数大于实际出库数，那么在库数和总数进行添加，出库数为0
                                if (upReq.getAddFlag()){
                                    is.setNumber(is.getStockNumber()+upReq.getModifyQuantity());
                                    is.setStockNumber(is.getStockNumber()+upReq.getModifyQuantity());
                                }else {
                                    if (is.getOutboundNumber()-upReq.getModifyQuantity()<0){
                                        is.setOutboundNumber(0);
                                        is.setStockNumber(is.getStockNumber()+is.getOutboundNumber());
                                        is.setUseNumber(is.getUseNumber()-is.getOutboundNumber());
                                    }else {
                                        is.setOutboundNumber(is.getOutboundNumber()-upReq.getModifyQuantity());
                                        is.setStockNumber(is.getStockNumber()+upReq.getModifyQuantity());
                                        is.setUseNumber(is.getUseNumber()-upReq.getModifyQuantity());
                                    }
                                }
                                break;
                            case "repair":
                                //如果入库数大于实际出库数，那么在库数和总数进行添加，出库数为0
                                if (is.getOutboundNumber()-upReq.getModifyQuantity()<0){
                                    is.setOutboundNumber(0);
                                    is.setStockNumber(is.getStockNumber()+is.getOutboundNumber());
                                    is.setFixNumber(is.getFixNumber()-is.getOutboundNumber());
                                }else {
                                    is.setOutboundNumber(is.getOutboundNumber()-upReq.getModifyQuantity());
                                    is.setStockNumber(is.getStockNumber()+upReq.getModifyQuantity());
                                    is.setFixNumber(is.getFixNumber()-upReq.getModifyQuantity());
                                }
                                break;
                        }
                    }
                    else {
                        subNum=is.getStockNumber()-upReq.getModifyQuantity();
                        switch (orderMain.getBussinessType()){
                            case "destruction":
                                //直接减去库存数量
                                is.setNumber(Math.max(is.getNumber() - upReq.getModifyQuantity(), 0));
                                is.setPrice(is.getUnitPrice().multiply(BigDecimal.valueOf(is.getNumber())));
                                is.setDestructionNumber(is.getDestructionNumber()+upReq.getModifyQuantity());
                                is.setDestructionPrice(is.getUnitPrice().multiply(BigDecimal.valueOf(is.getDestructionNumber())));
                                //需要优先将报废的装备进行处理
                                if (is.getBrokenNumber()>0){
                                    Integer moreNumber=is.getBrokenNumber()-upReq.getModifyQuantity();
                                    is.setBrokenNumber(moreNumber>0?upReq.getModifyQuantity()-is.getBrokenNumber():0);
                                    //如果是小于0那么直接相加即可
                                    is.setStockNumber(moreNumber>0?is.getStockNumber():is.getStockNumber()+moreNumber);
                                }else {
                                    is.setStockNumber(Math.max(is.getStockNumber() - upReq.getModifyQuantity(), 0));
                                }

                                break;
                            case "allocate":
                                is.setNumber(Math.max(is.getNumber() - upReq.getModifyQuantity(), 0));
                                is.setStockNumber(Math.max(is.getStockNumber() - upReq.getModifyQuantity(), 0));
                                is.setPrice(is.getPrice().subtract(BigDecimal.valueOf(upReq.getModifyQuantity()).multiply(new BigDecimal(upReq.getPrice()))) );
                                //如果库存数为0，那么直接删除该条记录
                                if (is.getNumber()==0 && is.getStockNumber()==0 && is.getOutboundNumber()==0 && is.getDestructionNumber()==0){
                                    delList.add(is);
                                }
                                break;
                            case "use":

                                Integer stockNumber = is.getStockNumber();
                                is.setStockNumber(Math.max(is.getStockNumber() - upReq.getModifyQuantity(), 0));
                                if (is.getStockNumber() == 0) {
                                    is.setOutboundNumber(is.getOutboundNumber() + stockNumber);
                                } else {
                                    is.setOutboundNumber(is.getOutboundNumber() + upReq.getModifyQuantity());
                                }
                                if (ObjectUtil.isNull(is.getUseCount())){
                                    is.setUseCount(0);
                                }
                                is.setUseCount(is.getUseCount()+upReq.getModifyQuantity());
                                if(ObjectUtil.isNull(is.getUseNumber())){
                                    is.setUseNumber(0);
                                }
                                is.setUseNumber(is.getUseNumber()+upReq.getModifyQuantity());
                                break;
                            case "repair":
                                Integer stockNum = is.getStockNumber();
                                is.setStockNumber(Math.max(is.getStockNumber() - upReq.getModifyQuantity(), 0));
                                if (is.getStockNumber() == 0) {
                                    is.setOutboundNumber(is.getOutboundNumber() + stockNum);
                                } else {
                                    is.setOutboundNumber(is.getOutboundNumber() + upReq.getModifyQuantity());
                                }
                                if (ObjectUtil.isNull(is.getFixCount())){
                                    is.setFixCount(0);
                                }
                                is.setFixCount(is.getFixCount()+upReq.getModifyQuantity());
                                if (ObjectUtil.isNull(is.getFixNumber())){
                                    is.setFixNumber(0);
                                }
                                is.setFixNumber(is.getFixNumber()+upReq.getModifyQuantity());
                                break;
                            case "other":
                                Integer stockNum1 = is.getStockNumber();
                                is.setStockNumber(Math.max(is.getStockNumber() - upReq.getModifyQuantity(), 0));
                                if (is.getStockNumber() == 0) {
                                    is.setOutboundNumber(is.getOutboundNumber() +stockNum1);
                                } else {
                                    is.setOutboundNumber(is.getOutboundNumber() + upReq.getModifyQuantity());
                                }
                                break;
                            default:
                                break;
                        }
                    }
                    updateList.add(is);
                    flag=true;
                    break;
                }
            }
            //表示库存中没有，那么插入数据
            if (!flag && req.getOrderType().equals("in")){
                List<Object[]> searchItem=new ArrayList<>();
                Object[] criteria=new Object[]{orgId,upReq.getWarehouseId(),upReq.getTypeId(),upReq.getSizeId(),upReq.getPrice(),"1"};
                searchItem.add(criteria);
                List<InventorySummary> invSumList = inventorySummaryMapper.selectSum(searchItem);
                InventorySummary is = null;
                if (CollectionUtil.isNotEmpty(invSumList)){
                    is = invSumList.get(0);
                }
                switch (orderMain.getBussinessType()){
                    case "purchase":
                    case "allocate":
                    case "gift":
                        //创建新的汇总类
                        InventorySummary inventorySummary = inventorySummaryService.createInventorySummary(orgId, orgName, orgCode, upReq.getTypeId(),
                                upReq.getTypeName(), upReq.getSizeId(), upReq.getSizeName(), upReq.getWarehouseId(),
                                upReq.getWarehouseName(), upReq.getModifyQuantity(), 0,
                                new BigDecimal(upReq.getPrice()), 0, 0, 0,
                                0, 0,0, 0, "0");
                        addList.add(inventorySummary);
                        break;
                    case "other":
                        is.setStockNumber(is.getStockNumber()+upReq.getModifyQuantity());
                        is.setOutboundNumber(Math.max(is.getOutboundNumber() - upReq.getModifyQuantity(), 0));
                        updateList.add(is);
                        break;
                    case "return":
                        if (is != null){
                            //如果入库数大于实际出库数，那么在库数和总数进行添加，出库数为0
                            if (upReq.getAddFlag()){
                                is.setStockNumber(is.getStockNumber()+upReq.getModifyQuantity());
                                is.setNumber(is.getNumber()+upReq.getModifyQuantity());
                            }else {
                                if (is.getOutboundNumber()-upReq.getModifyQuantity()<0){
                                    is.setOutboundNumber(0);
                                    is.setStockNumber(is.getStockNumber()+is.getOutboundNumber());
                                    is.setUseNumber(is.getUseNumber()-is.getOutboundNumber());
                                }else {
                                    is.setOutboundNumber(is.getOutboundNumber()-upReq.getModifyQuantity());
                                    is.setStockNumber(is.getStockNumber()+upReq.getModifyQuantity());
                                    is.setUseNumber(is.getUseNumber()-upReq.getModifyQuantity());
                                }
                            }
                            updateList.add(is);
                        }else {
                            InventorySummary invSum = inventorySummaryService.createInventorySummary(orgId, orgName, orgCode, upReq.getTypeId(),
                                    upReq.getTypeName(), upReq.getSizeId(), upReq.getSizeName(), upReq.getWarehouseId(),
                                    upReq.getWarehouseName(), upReq.getModifyQuantity(), 0,
                                    new BigDecimal(upReq.getPrice()), 0, 0, 0,
                                    0, 0, 0,0, "0");

                            addList.add(invSum);
                        }
                        break;
                    case "repair":
                        //如果入库数大于实际出库数，那么在库数和总数进行添加，出库数为0
                        if (is.getOutboundNumber()-upReq.getModifyQuantity()<0){
                            is.setOutboundNumber(0);
                            is.setStockNumber(is.getStockNumber()+upReq.getModifyQuantity()-is.getOutboundNumber());
                            is.setNumber(is.getNumber()+upReq.getModifyQuantity()-is.getOutboundNumber());
                        }else {
                            is.setOutboundNumber(is.getOutboundNumber()-upReq.getModifyQuantity());
                            is.setStockNumber(is.getStockNumber()+upReq.getModifyQuantity());
                        }
                        is.setFixNumber(Math.max((ObjectUtil.isNull(is.getFixNumber())?0:is.getFixNumber())-upReq.getModifyQuantity(),0));
                        updateList.add(is);
                        break;

                }
            }
            else if (flag && subNum<0 && req.getOrderType().equals("in")) {
                List<Object[]> searchItem=new ArrayList<>();
                Object[] criteria=new Object[]{orgId,upReq.getWarehouseId(),upReq.getTypeId(),upReq.getSizeId(),upReq.getPrice(),"1"};
                searchItem.add(criteria);
                List<InventorySummary> invSumList = inventorySummaryMapper.selectSum(searchItem);
                InventorySummary is = null;
                if (CollectionUtil.isNotEmpty(invSumList)){
                    is = invSumList.get(0);
                }
                switch (orderMain.getBussinessType()){
                    case "other":
                        is.setStockNumber(is.getStockNumber()+Math.abs(subNum));
                        is.setOutboundNumber(Math.max(is.getNumber() - Math.abs(subNum), 0));
                        updateList.add(is);
                        break;
                    case "return":
                        //如果入库数大于实际出库数，那么在库数和总数进行添加，出库数为0
                        if (!upReq.getAddFlag()){
                            if (is.getOutboundNumber()-Math.abs(subNum)<0){
                                is.setOutboundNumber(0);
                                is.setStockNumber(is.getStockNumber()+is.getOutboundNumber());
                                is.setUseNumber(is.getUseNumber()-is.getOutboundNumber());
                            }else {
                                is.setOutboundNumber(is.getOutboundNumber()-Math.abs(subNum));
                                is.setStockNumber(is.getStockNumber()+Math.abs(subNum));
                                is.setUseNumber(is.getUseNumber()-Math.abs(subNum));
                            }
                            updateList.add(is);
                        }

                        break;
                    case "repair":
                        //如果入库数大于实际出库数，那么在库数和总数进行添加，出库数为0
                        if (is.getOutboundNumber()-Math.abs(subNum)<0){
                            is.setOutboundNumber(0);
                            is.setStockNumber(is.getStockNumber()+is.getOutboundNumber());
                            is.setFixNumber(is.getFixNumber()-is.getOutboundNumber());
                        }else {
                            is.setOutboundNumber(is.getOutboundNumber()-Math.abs(subNum));
                            is.setStockNumber(is.getStockNumber()+Math.abs(subNum));
                            is.setFixNumber(is.getFixNumber()-Math.abs(subNum));
                        }
                        updateList.add(is);
                        break;
                }
            }
            else if (!flag && req.getOrderType().equals("out")) {
                List<Object[]> searchItem=new ArrayList<>();
                Object[] criteria=new Object[]{orgId,upReq.getWarehouseId(),upReq.getTypeId(),upReq.getSizeId(),upReq.getPrice(),"1"};
                searchItem.add(criteria);
                List<InventorySummary> invSumList = inventorySummaryMapper.selectSum(searchItem);
                if (CollectionUtil.isNotEmpty(invSumList)){
                    InventorySummary is = invSumList.get(0);
                    switch (orderMain.getBussinessType()){
                        case "destruction":
                            //直接减去库存数量
                            is.setNumber(Math.max(is.getNumber() - upReq.getModifyQuantity(), 0));
                            is.setPrice(is.getUnitPrice().multiply(BigDecimal.valueOf(is.getNumber())));
                            is.setStockNumber(Math.max(is.getStockNumber()-upReq.getModifyQuantity(),0));
                            is.setDestructionNumber(is.getDestructionNumber()+upReq.getModifyQuantity());
                            is.setDestructionPrice(is.getUnitPrice().multiply(BigDecimal.valueOf(is.getDestructionNumber())));
                            break;
                        case "allocate":
                            is.setNumber(Math.max(is.getNumber() - upReq.getModifyQuantity(), 0));
                            is.setStockNumber(Math.max(is.getStockNumber() - upReq.getModifyQuantity(), 0));
                            is.setPrice(is.getUnitPrice().multiply(BigDecimal.valueOf(is.getNumber())));
                            //如果库存数为0，那么直接删除该条记录
                            if (is.getNumber()==0 && is.getStockNumber()==0 && is.getOutboundNumber()==0 && is.getBrokenNumber()==0 && is.getDestructionNumber()==0){
                                delList.add(is);
                            }
                            break;
                        case "use":
                            Integer stockNumber = is.getStockNumber();
                            is.setStockNumber(Math.max(is.getStockNumber() - upReq.getModifyQuantity(), 0));
                            if (is.getStockNumber() == 0) {
                                is.setOutboundNumber(is.getOutboundNumber() + stockNumber);
                            } else {
                                is.setOutboundNumber(is.getOutboundNumber() + upReq.getModifyQuantity());
                            }
                            if (ObjectUtil.isNull(is.getUseCount())){
                                is.setUseCount(0);
                            }
                            is.setUseCount(is.getUseCount()+upReq.getModifyQuantity());
                            if(ObjectUtil.isNull(is.getUseNumber())){
                                is.setUseNumber(0);
                            }
                            is.setUseNumber(is.getUseNumber()+upReq.getModifyQuantity());
                            break;
                        case "repair":
                            Integer stockNum = is.getStockNumber();
                            is.setStockNumber(Math.max(is.getStockNumber() - upReq.getModifyQuantity(), 0));
                            if (is.getStockNumber() == 0) {
                                is.setOutboundNumber(is.getOutboundNumber() + stockNum);
                            } else {
                                is.setOutboundNumber(is.getOutboundNumber() + upReq.getModifyQuantity());
                            }
                            if (ObjectUtil.isNull(is.getFixCount())){
                                is.setFixCount(0);
                            }
                            is.setFixCount(is.getFixCount()+upReq.getModifyQuantity());
                            if (ObjectUtil.isNull(is.getFixNumber())){
                                is.setFixNumber(0);
                            }
                            is.setFixNumber(is.getFixNumber()+upReq.getModifyQuantity());
                            break;
                        case "other":
                            is.setOutboundNumber(is.getOutboundNumber()+upReq.getModifyQuantity());
                            is.setStockNumber(Math.max(is.getStockNumber() - upReq.getModifyQuantity(), 0));
                            break;

                    }
                    updateList.add(is);
                }

            }
            else if (flag && subNum<0 && req.getOrderType().equals("out")) {
                List<Object[]> searchItem=new ArrayList<>();
                Object[] criteria=new Object[]{orgId,upReq.getWarehouseId(),upReq.getTypeId(),upReq.getSizeId(),upReq.getPrice(),"1"};
                searchItem.add(criteria);
                List<InventorySummary> invSumList = inventorySummaryMapper.selectSum(searchItem);
                if (CollectionUtil.isNotEmpty(invSumList)){
                    InventorySummary is = invSumList.get(0);
                    switch (orderMain.getBussinessType()){
                        case "destruction":
                            //直接减去库存数量
                            is.setNumber(Math.max(is.getNumber() - Math.abs(subNum), 0));
                            is.setPrice(is.getUnitPrice().multiply(BigDecimal.valueOf(is.getNumber())));
                            is.setStockNumber(Math.max(is.getStockNumber()-Math.abs(subNum),0));
                            is.setDestructionNumber(is.getDestructionNumber()+Math.abs(subNum));
                            is.setDestructionPrice(is.getUnitPrice().multiply(BigDecimal.valueOf(is.getDestructionNumber())));
                            break;
                        case "allocate":
                            is.setNumber(Math.max(is.getNumber() - Math.abs(subNum), 0));
                            is.setStockNumber(Math.max(is.getStockNumber() - Math.abs(subNum), 0));
                            is.setPrice(is.getUnitPrice().multiply(BigDecimal.valueOf(is.getNumber())));
                            //如果库存数为0，那么直接删除该条记录
                            if (is.getNumber()==0 && is.getStockNumber()==0 && is.getOutboundNumber()==0 && is.getBrokenNumber()==0 && is.getDestructionNumber()==0){
                                delList.add(is);
                            }
                            break;
                        case "use":
                            Integer stockNumber = is.getStockNumber();
                            is.setStockNumber(Math.max(is.getStockNumber() - Math.abs(subNum), 0));
                            if (is.getStockNumber() == 0) {
                                is.setOutboundNumber(is.getOutboundNumber() + stockNumber);
                            } else {
                                is.setOutboundNumber(is.getOutboundNumber() + Math.abs(subNum));
                            }
                            if (ObjectUtil.isNull(is.getUseCount())){
                                is.setUseCount(0);
                            }
                            is.setUseCount(is.getUseCount()+Math.abs(subNum));
                            if(ObjectUtil.isNull(is.getUseNumber())){
                                is.setUseNumber(0);
                            }
                            is.setUseNumber(is.getUseNumber()+Math.abs(subNum));
                            break;
                        case "repair":
                            Integer stockNum = is.getStockNumber();
                            is.setStockNumber(Math.max(is.getStockNumber() - Math.abs(subNum), 0));
                            if (is.getStockNumber() == 0) {
                                is.setOutboundNumber(is.getOutboundNumber() + stockNum);
                            } else {
                                is.setOutboundNumber(is.getOutboundNumber() + Math.abs(subNum));
                            }
                            if (ObjectUtil.isNull(is.getFixCount())){
                                is.setFixCount(0);
                            }
                            is.setFixCount(is.getFixCount()+Math.abs(subNum));
                            if (ObjectUtil.isNull(is.getFixNumber())){
                                is.setFixNumber(0);
                            }
                            is.setFixNumber(is.getFixNumber()+Math.abs(subNum));
                           break;
                        case "other":
                            is.setOutboundNumber(is.getOutboundNumber()+Math.abs(subNum));
                            is.setStockNumber(Math.max(is.getStockNumber() - Math.abs(subNum), 0));
                            break;

                    }
                    updateList.add(is);
                }

            }

        }


        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;
        }
        if (delList.size()>0){
            inventorySummaryService.removeBatchByIds(delList);
        }


        return a;

    }

    /**
     * 查看记账列表
     * @param req
     * @return
     */
    @Override
    public PageResult<OrderLog> ShowAccountingPage(QueryOrderLogReq req) {
        LambdaQueryWrapper<OrderLog> eq = new LambdaQueryWrapper<OrderLog>()
                .eq(ObjectUtil.isNotNull(req.getBussinessType()), OrderLog::getBussinessType, req.getBussinessType())
                .eq(ObjectUtil.isNotNull(req.getOrderType()), OrderLog::getOrderType, req.getOrderType())
                .eq(ObjectUtil.isNotNull(req.getOrderId()), OrderLog::getOrgId, req.getOrgId())
                .ge(ObjectUtil.isNotNull(req.getStartTime()), OrderLog::getCreateTime, req.getStartTime())
                .le(ObjectUtil.isNotNull(req.getEndTime()), OrderLog::getCreateTime, req.getEndTime());
        Page<OrderLog> page = orderLogService.page(PageFactory.getDefaultPage(req.getPageNo(), req.getPageSize()), eq);
        return PageResultFactory.createPageResult(page);
    }


    /**
     * 入库单导出功能
     * @param req
     */
    @Override
    public void InOrderExport(OrderMainReq req) {
        LambdaQueryWrapper<OrderMain> wrapper = createWrapper(req);
        List<InOrderInfoVo> collect = list(wrapper).stream().map(orderMain -> {
            InOrderInfoVo inOrderInfoVo = new InOrderInfoVo();
            BeanPlusUtil.copyProperties(orderMain, inOrderInfoVo);
            //装备名称
            String inventoryName = "";
//            List<OrderDetail> orderDetailList = orderDetailService.QueryList(orderMain.getId());
            List<OrderDetail> orderDetailList = orderDetailService.list(new LambdaQueryWrapper<OrderDetail>()
                    .eq(OrderDetail::getOrderId, orderMain.getId()));
            for (OrderDetail orderDetail : orderDetailList) {
                inventoryName = inventoryName + orderDetail.getTypeName() + "/";
            }
            String substring = inventoryName.substring(0, inventoryName.length() - 1);
            inOrderInfoVo.setInventoryName(substring);
            //查询字典表设置入库类型
//            List<SysDictItem> list = sysDictItemService.list(new LambdaQueryWrapper<SysDictItem>()
//                    .eq(SysDictItem::getItemValue, orderMain.getBussinessType()));
////            inOrderInfo.setOrderType(itemText);
//            System.out.println("list = " + list);
            return inOrderInfoVo;

        }).collect(Collectors.toList());
        //设置导出的单据序号
        for (int i = 1; i <= collect.size() ; i++) {
            collect.get(i-1).setNumId(i);
        }
        HttpServletResponse response = HttpServletUtil.getResponse();
        ExcelExportParam param = new ExcelExportParam();
        param.setDataList(collect);
        param.setClazz(InOrderInfoVo.class);
        param.setResponse(response);
        param.setFileName("入库单据列表.xls");
        //对数据进行导出
        officeExcelApi.easyExportDownload(param);

    }

    @Override
    public void OutOrderExport(OrderMainReq req) {
        LambdaQueryWrapper<OrderMain> wrapper = createWrapper(req);
        List<InOrderInfoVo> collect = list(wrapper).stream().map(orderMain -> {
            InOrderInfoVo inOrderInfoVo = new InOrderInfoVo();
            BeanPlusUtil.copyProperties(orderMain, inOrderInfoVo);
            //装备名称
            String inventoryName = "";
//            List<OrderDetail> orderDetailList = orderDetailService.QueryList(orderMain.getId());
            List<OrderDetail> orderDetailList = orderDetailService.list(new LambdaQueryWrapper<OrderDetail>()
                    .eq(OrderDetail::getOrderId, orderMain.getId()));
            for (OrderDetail orderDetail : orderDetailList) {
                inventoryName = inventoryName + orderDetail.getTypeName() + "/";
            }
            String substring = inventoryName.substring(0, inventoryName.length() - 1);
            inOrderInfoVo.setInventoryName(substring);
            //查询字典表设置出库类型
//            List<SysDictItem> list = sysDictItemService.list(new LambdaQueryWrapper<SysDictItem>()
//                    .eq(SysDictItem::getItemValue, orderMain.getBussinessType()));
////            inOrderInfo.setOrderType(itemText);
//            System.out.println("list = " + list);
            return inOrderInfoVo;

        }).collect(Collectors.toList());
        //设置导出的单据序号
        for (int i = 1; i <= collect.size() ; i++) {
            collect.get(i-1).setNumId(i);
        }
        HttpServletResponse response = HttpServletUtil.getResponse();
        ExcelExportParam param = new ExcelExportParam();
        param.setDataList(collect);
        param.setClazz(InOrderInfoVo.class);
        param.setResponse(response);
        param.setFileName("出库单据列表.xls");
        //对数据进行导出
        officeExcelApi.easyExportDownload(param);
    }


    //判断任务单是否存在
    @Override
    public OrderMain orderMainExist(String id) {
        OrderMain order = this.getById(id);
        if (ObjectUtil.isNull(order)) {
            throw new ServiceException(OrderExceptionEnum.ORDER_NOT_EXIST);
        }
        return order;
    }
    public OrderMain orderMainExistByProcessId(String processId) {
        OrderMain order = this.getOne(new LambdaQueryWrapper<OrderMain>().eq(OrderMain::getProcessId,processId));
        if (ObjectUtil.isNull(order)) {
            throw new ServiceException(OrderExceptionEnum.ORDER_NOT_EXIST);
        }
        return order;
    }


    private LambdaQueryWrapper<OrderMain> createWrapper(OrderMainReq req) {
        LambdaQueryWrapper<OrderMain> wrapper = new LambdaQueryWrapper<>();
        if (ObjectUtil.isEmpty(req)) {
            return wrapper;
        }
        //单据类型（in入库，out出库）
        wrapper.eq(ObjectUtil.isNotEmpty(req.getOrderType()),OrderMain::getOrderType,req.getOrderType());
        //单据状态 ready待入/出库，finished已入/出库，working入/出库中
        wrapper.eq(ObjectUtil.isNotEmpty(req.getOrderState()), OrderMain::getOrderState, req.getOrderState());
//        //审核状态:none,未接入审核流，working审批中，finished已完成
        wrapper.eq(ObjectUtil.isNotEmpty(req.getExamineState()), OrderMain::getExamineState, req.getExamineState());
        //业务类型
        wrapper.eq(ObjectUtil.isNotEmpty(req.getBussinessType()), OrderMain::getBussinessType, req.getBussinessType());
        //组织机构id(入库单)
        wrapper.eq(ObjectUtil.isNotEmpty(req.getEndOrgId()),OrderMain::getEndOrgId,req.getEndOrgId());
        //组织机构id（出库单）
        wrapper.ge(ObjectUtil.isNotNull(req.getStartTime()),OrderMain::getCreateTime,req.getStartTime());
        wrapper.le(ObjectUtil.isNotNull(req.getEndTime()),OrderMain::getCreateTime,req.getEndTime());
        wrapper.orderByDesc(OrderMain::getCreateTime);

        return wrapper;

    }


    /**
     * 根据流程id和单据类型查询出该单子据的信息
     * @param req
     * @return
     */
    @Override
    public ProcessOrderDto GetByProcessId(OrderMainReq req) {
        String receiveUser="";
        if (req.getReceiveUserId()!=null)//
        {
            receiveUser = req.getReceiveUserId();
        }
        else
        {
            receiveUser= LoginContext.getContext().getLoginUser().getUserId().toString();
        }

        ProcessOrderDto processOrderDto = new ProcessOrderDto();
        if (req.getOrderType().equals("null")|| ObjectUtil.isNull(req.getOrderType())) {
            return processOrderDto;
        }

//        //点击后消除已读消息,暂时不用，依赖前端处理
//        MessageReq reqmsg=new MessageReq();
//        reqmsg.setBizId(Long.valueOf(req.getProcessInstanceId()));
//        reqmsg.setReceiveUserId(Long.valueOf(receiveUser));
//        reqmsg.setReadFlag(0);
//        List<MessageRes> msgRes= messageApi.queryList(reqmsg);
//        if (msgRes.size()>0)
//        {
//            // 使用流将 id 取出，并用逗号拼接成字符串
//            String ids = msgRes.stream()
//                    .map(MessageRes::getMsgId)
//                    .map(String::valueOf) // 将 id 转换为字符串
//                    .collect(Collectors.joining(","));
//            messageApi.batchReadFlagByMessageIds(ids, MsgReadStateEnum.READ);
//        }
        if (req.getOrderType().equals("workOrder")){
            OrderDto orderDto = new OrderDto();
            OrderMain one = getOne(new LambdaQueryWrapper<OrderMain>()
                    .eq(OrderMain::getProcessId, req.getProcessId()));
            if (ObjectUtil.isNull(one)){
                return processOrderDto;
            }
            BeanPlusUtil.copyProperties(one,orderDto);

            List<OrderDetailDto> collect = orderDetailService.list(new LambdaQueryWrapper<OrderDetail>()
                    .eq(OrderDetail::getOrderId, one.getId())).stream().map(orderDetail -> {
                OrderDetailDto orderDetailDto = new OrderDetailDto();
                BeanPlusUtil.copyProperties(orderDetail, orderDetailDto);
                return orderDetailDto;
            }).collect(Collectors.toList());
            orderDto.setDetailList(collect);
            processOrderDto.setOrderDto(orderDto);
        } else if (req.getOrderType().equals("bussinessOrder")) {
            BusFormDto busFormDto = new BusFormDto();
            BusForm one = busFormService.getOne(new LambdaQueryWrapper<BusForm>()
                    .eq(BusForm::getProcessId, req.getProcessId()));
            BeanPlusUtil.copyProperties(one,busFormDto);
            processOrderDto.setBusFormDto(busFormDto);
        } else if (req.getOrderType().equals("stacktakeOrder")) {
            BussinessInventoryDto bussinessInventoryDto = new BussinessInventoryDto();
            BussinessInventory one = bussinessInventoryService.getOne(new LambdaQueryWrapper<BussinessInventory>()
                    .eq(BussinessInventory::getProcessId, req.getProcessId()));
            List<EquipmentListDto> collect = bussinessInventoryDetailService.list(new LambdaQueryWrapper<BussinessDetail>()
                    .eq(BussinessDetail::getInventoryId, one.getId())).stream().map(bussinessDetail -> {
                EquipmentListDto equipmentListDto = new EquipmentListDto();
                BeanPlusUtil.copyProperties(bussinessDetail, equipmentListDto);
                return equipmentListDto;
            }).collect(Collectors.toList());
            bussinessInventoryDto.setEquipmentList(collect);
            processOrderDto.setBussinessInventoryDto(bussinessInventoryDto);
        } else if (req.getOrderType().equals("reassigment")) {
            ReassignmentDto reassignmentDto = new ReassignmentDto();
            Reassignment one = reassignmentService.getOne(new LambdaQueryWrapper<Reassignment>()
                    .eq(Reassignment::getProcessId, req.getProcessId()));
            BeanPlusUtil.copyProperties(one,reassignmentDto);
            processOrderDto.setReassignmentDto(reassignmentDto);
        }
        return processOrderDto;
    }


    /**
     * 处理快速移库记账
     * 1.将移出仓库的装备数量汇总减少
     * 2.创建移入仓库的快速移库入库单 √
     * 3.修改装备的位置状态
     * 4.修改移入仓库的装备数量汇总增加
     * 5.添加移出、移入装备的日志（单据日志，出入库日志）
     * @param existOrder
     * @param detailList
     * @param map
     * @return
     */
    @Transactional
    public boolean handleQuickOrder(OrderMain existOrder,List<UpdateOrderDetailReq> detailList,Map<String, List<String>> map) {

        //2.创建新的orderMain入库单
        OrderMain orderMain = new OrderMain();
        BeanPlusUtil.copyProperties(existOrder,orderMain);
        orderMain.setEndOrgId(existOrder.getStartOrgId());
        orderMain.setEndOrgName(existOrder.getStartOrgName());
        orderMain.setOrderType("in");
        orderMain.setId(UUID.randomUUID().toString());
        //工作流流程设为空
        orderMain.setProcessId(null);
        //修改订单编号，设置为入库的单号
        UpdateOrderReq req = new UpdateOrderReq();
        BeanPlusUtil.copyProperties(orderMain,req);
        OrderNum orderNum = setOrderCode(req);
        long time = new Date().getTime() % 10000;
        String codeValue=String.format("%04d",orderNum.getNum());
        orderMain.setOrderCode(orderNum.getBussinessType()+String.format("%04d",time)+orderNum.getYear()+
                String.format("%02d",LocalDateTime.now().getMonth().getValue())+
                String.format("%02d",LocalDateTime.now().getDayOfMonth())+codeValue);
        //保存入库单
        save(orderMain);
        //查询出库子单用于赋值到入库单中
        List<OrderDetail> list = orderDetailService.list(new LambdaQueryWrapper<OrderDetail>()
                .eq(OrderDetail::getOrderId, existOrder.getId()));
        //移入仓库id
        String locationId = orderMain.getLocationId();
        String locationName = orderMain.getLocationName();
        //创建入库单子单
        List<OrderDetail> collect = list.stream().map(orderDetail -> {

            OrderDetail orderDetail1 = new OrderDetail();
            BeanPlusUtil.copyProperties(orderDetail, orderDetail1);
            List<DetailJsonReq> detailJsonReqs = JSONObject.parseArray(orderDetail.getDetailJson(), DetailJsonReq.class);
            if (CollectionUtil.isNotEmpty(detailJsonReqs)){
                for (DetailJsonReq a:detailJsonReqs) {
                    a.setLocationId(locationId);
                    a.setLocationName(locationName);
                }
            }
            orderDetail1.setDetailJson(JSONObject.toJSONString(detailJsonReqs));
            orderDetail1.setId(null);
            //修改主单据id
            orderDetail1.setOrderId(orderMain.getId());
            //修改单据出入状态
            orderDetail1.setType("in");
            //修改移入仓库id
            orderDetail1.setWarehouseId(locationId);
            orderDetail1.setWarehouseName(locationName);

            return orderDetail1;
        }).collect(Collectors.toList());
        orderDetailService.saveBatch(collect);

        //1.原来出库单的查询条件list（根据条件查询库存汇总表中包含有相同条件的数据）
        List<Object[]> searchCriteria=new ArrayList<>();
        //4.新建的入库单查询条件list（根据条件查询库存汇总表中是否包含有相同条件的数据）
        List<Object[]> updateCriteria=new ArrayList<>();
        Map<String,String> listMap=new HashMap<>();
        //查询条件，将所有查询条件放在searchCriteria中，用于修改库存表中的装备的仓库位置
        //循环记账子单
        List<DetailJsonReq> jsonCollect =new ArrayList<>();
        for (UpdateOrderDetailReq detailReq:detailList) {
            List<DetailJsonReq> childJson = detailReq.getChildJson();
            jsonCollect.addAll(childJson);
            for (DetailJsonReq jsonReq:childJson) {
                //1、移出仓库
                Object[] criteria=new Object[]{existOrder.getStartOrgId(),jsonReq.getLocationId(),detailReq.getTypeId(),detailReq.getSizeId(),jsonReq.getUnitPrice(),0,jsonReq.getModifyQuantity()};
                searchCriteria.add(criteria);
                //4.移入仓库
                String key=orderMain.getEndOrgId()+locationId+detailReq.getTypeId()+detailReq.getSizeId()+jsonReq.getUnitPrice()+"0";
                if (!listMap.containsKey(key)){
                    Object[] update=new Object[]{orderMain.getEndOrgId(),locationId,detailReq.getTypeId(),detailReq.getSizeId(),jsonReq.getUnitPrice(),0};
                    updateCriteria.add(update);
                    listMap.put(key,key);
                }
            }
        }




        //将summary汇总表中数据进行修改(修改该组织机构下的装备汇总信息将库存信息的在库数，库存总数，总价还有其他数据数量进行修改)
        //1.那么首先将原来的仓库下的装备汇总信息进行查询出来，对其进行修改（移出）
        List<InventorySummary> oldSummaryList = inventorySummaryMapper.selectSum(searchCriteria);


        //1.创建删除列表用于将没用的数据汇总信息进行删除
        List<InventorySummary> deleteList=new ArrayList<>();


        //4.将修改的信息直接保存(需要的只是各种数量方便计算)
        List<InventorySummary> saveList=new ArrayList<>();
        Map<String,InventorySummary> summaryMap=new HashMap<>();
        for (DetailJsonReq json: jsonCollect ) {
            for (InventorySummary oldSum : oldSummaryList) {
                Integer property=0;
                //如果组织机构、仓库id、sizeId、typeId、unitPrice相同，那么修改其各项数值（
                // 不会存在两个列表长度不对等的情况，一定是一对一的，只不过是顺序问题，所以需要进行遍历）
                BigDecimal unitPrice=ObjectUtil.isNotNull(json.getPrice())?json.getPrice():json.getUnitPrice();
                if (json.getLocationId().equals(oldSum.getLocationId()) &&
                        json.getSizeId().equals(oldSum.getSizeId())
                        && json.getTypeId().equals(oldSum.getTypeId())
                        && unitPrice.compareTo(oldSum.getUnitPrice()) == 0
                        && property.equals(oldSum.getProperty())) {
                    //为入库做准备
                    InventorySummary inventorySummary = new InventorySummary();
                    BeanPlusUtil.copyProperties(oldSum,inventorySummary);
                    inventorySummary.setLocationId(locationId);
                    inventorySummary.setLocationName(locationName);
                    //在库数量进行修改并且报废数设为0
                    inventorySummary.setBrokenNumber(0);
                    inventorySummary.setOutboundNumber(0);
                    inventorySummary.setNumber(json.getModifyQuantity());
                    inventorySummary.setPrice(unitPrice.multiply(BigDecimal.valueOf(json.getModifyQuantity())));
                    inventorySummary.setStockNumber(json.getModifyQuantity());
                    inventorySummary.setDestructionNumber(0);
                    inventorySummary.setDestructionPrice(BigDecimal.ZERO);
                    inventorySummary.setId(null);
                    //设置valuekey
                    String valueKey = createValueKey(oldSum.getOrgCode(), locationId, oldSum.getTypeId(),
                            oldSum.getSizeId(), unitPrice.toString(), oldSum.getProperty().toString());
                    inventorySummary.setValuekey(valueKey);
                    saveList.add(inventorySummary);
                    InventorySummary invSum = new InventorySummary();
                    BeanPlusUtil.copyProperties(inventorySummary,invSum);
                    if (!summaryMap.containsKey(valueKey)){
                        summaryMap.put(valueKey,invSum);
                    }else {
                        InventorySummary inventorySummary1 = summaryMap.get(valueKey);
                        inventorySummary1.setNumber(inventorySummary1.getNumber()+inventorySummary.getNumber());
                        inventorySummary1.setPrice(inventorySummary1.getPrice().add(inventorySummary.getPrice()));
                        inventorySummary1.setStockNumber(inventorySummary1.getStockNumber()+inventorySummary.getStockNumber());
                        summaryMap.put(valueKey,inventorySummary1);
                    }

                    oldSum.setNumber(Math.max(oldSum.getNumber()-json.getModifyQuantity(),0));
                    oldSum.setPrice(unitPrice.multiply(BigDecimal.valueOf(oldSum.getNumber())));
                    oldSum.setStockNumber(Math.max(oldSum.getStockNumber()-json.getModifyQuantity(),0));

                    //如果存在删减数量完成之后所有的数量值都是0的情况，那么将这一条数据进行删除操作
                    if (oldSum.getNumber()==0 && oldSum.getBrokenNumber()==0 &&  oldSum.getDestructionNumber() == 0) {
                        deleteList.add(oldSum);
                        oldSummaryList.remove(oldSum);
                    }
                    break;//查询到直接跳过该循环进入下一循环
                }
            }
        }
        //如果删除list不为空，那么进行批量删除
        boolean b=true;
        if (deleteList.size()>0){
            b=inventorySummaryService.removeBatchByIds(deleteList);
        }
        if (CollectionUtil.isNotEmpty(oldSummaryList)){

            inventorySummaryService.updateBatchById(oldSummaryList);
        }


        //4.其次查询出修改后的仓库下面的汇总信息，判断该仓库下是否已经存在该号型、类型、单价相同的装备数据（移入）
        List<InventorySummary> newSummaryList = inventorySummaryMapper.selectSum(updateCriteria);


        //判断查询到的newList是否有值，如果有值直接进行修改即可，但是如果不存在，则默认新增一条数据
        //修改的是移入仓库的值
        if (newSummaryList.size()>0){
            for (int i = 0; i < saveList.size(); i++) {
                for (int j = 0; j <newSummaryList.size() ; j++) {
                    InventorySummary save = saveList.get(i);
                    InventorySummary newsum = newSummaryList.get(j);
                    if (save.getLocationId().equals(newsum.getLocationId())&&
                            save.getSizeId().equals(newsum.getSizeId())
                            && save.getTypeId().equals(newsum.getTypeId())
                            && save.getUnitPrice().compareTo(newsum.getUnitPrice()) == 0
                            && save.getProperty().equals(newsum.getProperty())){
                        newsum.setNumber(save.getNumber()+newsum.getNumber());
                        newsum.setStockNumber(save.getStockNumber()+newsum.getStockNumber());
                        newsum.setPrice(newsum.getPrice().multiply(BigDecimal.valueOf(newsum.getNumber())));
                        //remove表示该仓库下面存在数量，数量加减完之后直接在新增的list中进行移出x
                        saveList.remove(save);
                        i--;
                        break;
                    }
                }
            }
        }

        //如果saveList不为空则save
        boolean a=true;
        if(saveList.size()>0){
            List<InventorySummary> collect1 = summaryMap.values().stream().collect(Collectors.toList());
            a=inventorySummaryService.saveBatch(collect1);
        }

        //将orderSum和newSum两个列表进行拼接，最终得到一个更新的list进行更新

        boolean c =inventorySummaryService.updateBatchById(newSummaryList);

        //5.添加移入移出日志

        //出库记录 -->  入库记录 / Map<String 仓库id, List<String>  epc列表> map    existOrder 出库单据
//        List<String> locationIds=new ArrayList<>(map.keySet());
//        List<Inventory> invList=inventoryMapper.searchEqs(searchCriteria);

        List<String> epcList=new ArrayList<>();
        for (String key : map.keySet()) {
            List<String> marValue = map.get(key);
            epcList.addAll(marValue);
        }
//        List<Inventory> invList = inventoryService.list(new LambdaQueryWrapper<Inventory>().in(Inventory::getEpc, epcList));
        List<Inventory> invList=inventoryMapper.searchEqs(epcList);

        Map<String, Inventory> inventoryDic = invList.stream().collect(Collectors.toMap(Inventory::getEpc, inventory -> inventory));

        List<LogSummary> logSummaryInList = new ArrayList<>();
        Map<String, List<LogDetail>> logDetailInMap = new HashMap<>();

        List<Inventory> updateInvList = new ArrayList<>();//更新的物资

        List<LogDetail> thisDetailList = new ArrayList<>();
        
        for (String key : map.keySet()) {
            LogSummary thisSummary = new LogSummary();

            List<String> marValue = map.get(key);
            if (marValue.size() < 1) continue;

            for (String thisEpc : marValue) {
                Inventory thisInv = inventoryDic.get(thisEpc);
                //入库
                LogDetail thisDetail = new LogDetail();
                thisDetail.setEpc(thisEpc);
                thisDetail.setBussinessType("quick");
                thisDetail.setCreateTime(DateTimeUtil.getCurrentDateTime());
                thisDetail.setErrorState(0);
                thisDetail.setProperty(thisInv.getProperty());
                thisDetail.setPrice(thisInv.getPrice());
                thisDetail.setTypeId(thisInv.getTypeId());
                thisDetail.setTypeName(thisInv.getTypeName());
                thisDetail.setSizeId(thisInv.getSizeId());
                thisDetail.setSizeName(thisInv.getSizeName());
                thisDetail.setSupplierId(thisInv.getSupplierId());
                thisDetail.setSupplierName(thisInv.getSupplierName());
                thisDetail.setInventoryId(thisInv.getId());
                thisDetail.setOutInState("in");
                thisDetail.setOrgId(orderMain.getEndOrgId());
                thisDetailList.add(thisDetail);

                //装备
                thisInv.setLocationId(locationId);
                thisInv.setUpdateTime(new Date());

                updateInvList.add(thisInv);
            }

            thisSummary.setLocationId(locationId);
            thisSummary.setLocationName(locationName);
            thisSummary.setLocationType(0);
            thisSummary.setUserName(orderMain.getEndOrgUserName());
            thisSummary.setOrgId(orderMain.getEndOrgId());
            thisSummary.setOrgName(orderMain.getEndOrgName());
            thisSummary.setOrderMainId(orderMain.getId());
            thisSummary.setOrderCode(orderMain.getOrderCode());
            thisSummary.setDeviceType(4);
            thisSummary.setBussinessType("quick");
            thisSummary.setOutInState("in");
            thisSummary.setUserName(existOrder.getStartOrgUserName());
            thisSummary.setCreateTime(new Date());
            thisSummary.setUpdateTime(new Date());
            thisSummary.setNumber(thisDetailList.size());
            thisSummary.setEquipmentList(String.join(",", thisDetailList
                    .stream()
                    .collect(Collectors.groupingBy(LogDetail::getTypeName))
                    .keySet()
                    .stream()
                    .distinct()
                    .collect(Collectors.toList())));


            logSummaryInList.add(thisSummary);
        }
            //执行数据库操作
        logDetailInMap.put(locationId, thisDetailList);
            //入库 logSummaryInList logDetailInMap
            logSummaryService.saveBatch(logSummaryInList);
            List<LogDetail> inDetails = new ArrayList<>();
            for (LogSummary summary : logSummaryInList) {
                List<LogDetail> des = logDetailInMap.get(summary.getLocationId());
                des.forEach(s -> {s.setSummaryId(summary.getId());
                    s.setCreateTime(DateTimeUtil.getCurrentDateTime());});

                inDetails.addAll(des);
            }
            logDetailService.saveBatch(inDetails);

            //装备 updateInvList
            inventoryService.updateBatchById(updateInvList);

            //更新WarehouseInventory
            warehouseInventoryService.update(new LambdaUpdateWrapper<WarehouseInventory>()
                    .set(WarehouseInventory::getLocationId, locationId)
                    .set(WarehouseInventory::getLocationName, locationName)
                    .in(WarehouseInventory::getEpc,
                            updateInvList.stream().map(Inventory::getEpc).collect(Collectors.toList())));

        return true;
    }
    //设置生成keyValue
    @Override
    public String createValueKey(String orgCode,String locationId,String typeId,String sizeId,String unitPrice,String property){
        orgCode = (orgCode != null) ? orgCode : "--0000";
        locationId = (locationId != null) ? locationId : "--0000";
        typeId = (typeId != null) ? typeId : "--0000";
        sizeId = (sizeId != null) ? sizeId : "--0000";
        unitPrice = (unitPrice != null) ? unitPrice : "--0000";
        property = (property != null) ? property : "--0";
        String key=orgCode+locationId+typeId+sizeId+unitPrice+property;
        return key;
    }

    /**
     * 判断单据是否需要开启
     * @param req
     * @return
     */
    @Override
    public Map<String,Boolean> updateOrderOpenState(UpdateOrderReq req) {
        Map<String, Boolean> map=new HashMap<>();
        Long orgId = req.getOrgId();
        List<OrderMain> one = list(new LambdaQueryWrapper<OrderMain>()
                .eq(OrderMain::getIsOpen, 1)
                .and(qw -> qw
                        .eq(OrderMain::getStartOrgId, orgId)
                        .or()
                        .eq(OrderMain::getEndOrgId, orgId)
                )
        );
        if (ObjectUtil.isEmpty(req.getId())){
            if (CollectionUtil.isNotEmpty(one)){
                map.put("openOrderSuccess",false);
                return map;
            }
        }else {
            OrderMain orderMain = orderMainExist(req.getId());
            if (one == null && req.getIsOpen()==1 ){
                orderMain.setIsOpen(1);
                updateById(orderMain);
            }
            if (one != null){
                one.forEach(s -> { s.setIsOpen(0); });
                updateBatchById(one);

                if(req.getIsOpen().equals(1)){
                    orderMain.setIsOpen(1);
                    updateById(orderMain);
                }
            }
        }
        map.put("openOrderSuccess",true);
        return map;
    }


    private Integer findInvIndexForEpc(List<InventoryReq> list, String sizeId, String typeId, Set<String> usedEpcs) {
        for (int i = 0; i < list.size(); i++) {
            InventoryReq inventoryReq = list.get(i);
            if (sizeId.equals(inventoryReq.getSizeId()) && typeId.equals(inventoryReq.getTypeId()) && !usedEpcs.contains(inventoryReq.getEpc())) {
                return i;
            }
        }
        return -1;
    }

    private Integer findWareInvIndexForEpc(List<WarehouseInventory> list, String sizeId, String typeId, Set<String> usedEpcs) {
        for (int i = 0; i < list.size(); i++) {
            WarehouseInventory warehouseInventory = list.get(i);
            if (sizeId.equals(warehouseInventory.getSizeId()) && typeId.equals(warehouseInventory.getTypeId()) && !usedEpcs.contains(warehouseInventory.getEpc())) {
                return i;
            }
        }
        return -1;
    }

    @Override
    public List<String> getInvsListByOrder(OrderMainReq req) {
        //根据查询条件得到单据
        LoginUser loginUser = LoginContext.getContext().getLoginUser();

        return orderMainMapper.getInvsListByOrder(req,loginUser.getUserId());
    }

    @Override
    public ResponseResult agree(HandleDataDTO handleDataDTO) {
        SysUser StartUser=new SysUser();
        if (handleDataDTO.getCurrentUserInfo().getUserId()!=null)//优先拿接口中的信息，方便调试
        {
            StartUser = sysUserService.getById(handleDataDTO.getCurrentUserInfo().getUserId());

        }
        else
        {
            StartUser= sysUserService.getById(LoginContext.getContext().getLoginUser());
        }
        List<AttachmentDTO> attachments = handleDataDTO.getAttachments();
        String comments = handleDataDTO.getComments();
        JSONObject formData = handleDataDTO.getFormData();
        String taskId = handleDataDTO.getTaskId();
        String processInstanceId=handleDataDTO.getProcessInstanceId();

        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        if (task!=null)//task为空则说明当前任务可能已结束
        {
            taskService.setVariableLocal(taskId,"taskStatusWrapper", TASK_STATUS_1);//设置当前节点任务状态

            Map<String, Object> map = new HashMap<>();
            if (formData != null && formData.size() > 0) {
                Map formValue = JSONObject.parseObject(formData.toJSONString(), new TypeReference<Map>() {
                });
                map.putAll(formValue);
                map.put(FORM_VAR, formData);
            }

            runtimeService.setVariables(task.getProcessInstanceId(), map);//设置进入当前流程
            Authentication.setAuthenticatedUserId(StartUser.getUserId().toString());
            if (StringUtils.isNotBlank(comments)) {
                taskService.addComment(task.getId(), task.getProcessInstanceId(), "opinion", comments);
            }else {
                //默认同意
                taskService.addComment(task.getId(), task.getProcessInstanceId(), "opinion", "同意");
            }
            if (attachments != null && attachments.size() > 0) {
                for (AttachmentDTO attachment : attachments) {
                    taskService.createAttachment("option", taskId, task.getProcessInstanceId(), attachment.getName(), attachment.getName(), attachment.getUrl());
                }
            }

            taskService.complete(task.getId());

            return new ResponseResult(HttpStatus.SUCCESS, ReturnMsg.PASS,ReturnMsg.PASS);
        }
        else {
            return new ResponseResult(HttpStatus.PROCESS_WAS_END,ReturnMsg.PROCESS_WAS_END,"");

        }
    }

    /**
     * 创建打印单号
     * @param
     * @return
     */
    @Override
    @Transactional
    public OrderPrintNumDto getPrintCode(OrderMainReq req) {
        OrderPrintNumDto orderPrintNumDto = new OrderPrintNumDto();
        if (ObjectUtil.isNotNull(req.getOrderCode()) && (req.getOrderCode().charAt(0) != 'B' || req.getOrderCode().charAt(1) != 'F')){
            //出入库单打印
            //判断单子是否已经存在打印单据，如果不存在直接添加，如果存在则直接返回单子中的打印单号，不再创建新的
            OrderMain one = orderMainExist(req.getId());
            if (ObjectUtil.isEmpty(one.getPrintCode())){
                //创建打印单号
                //更新出入库单据的打印单号
                OrderPrintNum orderPrintNum = setOrderPrintCode(req.getOrgId(),req.getOrderType());
                String codeValue=String.format("%05d",orderPrintNum.getOrderCount());
                one.setPrintCode(orderPrintNum.getOrderType()+"-"+orderPrintNum.getOrderYear()+"-"+codeValue);
                one.setPrintCodeTime(DateTimeUtil.getCurrentDateTime());
                updateById(one);

            }
            orderPrintNumDto.setPrintOrderCode(one.getPrintCode());
            orderPrintNumDto.setPrintOrderTime(DateTimeUtil.TimeDateToString(one.getPrintCodeTime(),"yyyy年MM月dd日"));

        }else {
            //报废业务单打印
            //创建打印单号
            //更新报废业务单单据的打印单号
            BusForm one = busFormService.getById(req.getId());
            if (ObjectUtil.isEmpty(one.getPrintCode())){
                //创建打印单号
                //更新出入库单据的打印单号
                OrderPrintNum orderPrintNum = setOrderPrintCode(req.getOrgId(),req.getOrderType());
                String codeValue=String.format("%05d",orderPrintNum.getOrderCount());
                one.setPrintCode(orderPrintNum.getOrderType()+"-"+orderPrintNum.getOrderYear()+"-"+codeValue);
                one.setPrintCodeTime(DateTimeUtil.getCurrentDateTime());
                busFormService.updateById(one);

            }
            orderPrintNumDto.setPrintOrderCode(one.getPrintCode());
            orderPrintNumDto.setPrintOrderTime(DateTimeUtil.TimeDateToString(one.getPrintCodeTime(),"yyyy年MM月dd日"));
        }
        return orderPrintNumDto;
    }

    private OrderPrintNum setOrderPrintCode(Long orgId,String orderType){
        //设置单号，需要先判断该组织机构的单号是否存在，如果存在则将数量进行增加，如果不存在则新增一条对应的数据
        //判断是出库还是入库，出库为发物单位，入库为收物单位
        OrderPrintNum one = orderPrintNumService.getOne(new LambdaQueryWrapper<OrderPrintNum>()
                .eq(OrderPrintNum::getOrgId, orgId)
                .eq(OrderPrintNum::getOrderType,orderType)
                .eq(OrderPrintNum::getOrderYear, LocalDateTime.now().getYear()));
        if (ObjectUtil.isNull(one)){
            one = new OrderPrintNum();
            one.setOrderYear(LocalDateTime.now().getYear());
            one.setOrderCount(1);
            one.setOrgId(orgId);
            one.setOrderType(orderType);
            one.setCreateTime(DateTimeUtil.getCurrentDateTime());
            orderPrintNumService.save(one);
            return one;
        }else {
            one.setOrderCount(one.getOrderCount()+1);
            orderPrintNumService.updateById(one);
            return one;
        }

    }


    /**
     * 记账接口重写重构
     * @param req
     * @return
     */
    @Override
    public boolean testAccounting(UpdateOrderReq req) {
        //判断单据是否存在
        OrderMain orderMain = orderMainExist(req.getId());
        //记账子单据不能传空
        if (req.getDetailList().size()==0){
            throw new ServiceException(OrderExceptionEnum.ORDERDETAIL_ISNOT_NULL);
        }
        //获取子单据
        List<OrderDetail> orderDetailList = orderDetailService.list(new LambdaQueryWrapper<OrderDetail>()
                .eq(OrderDetail::getOrderId,req.getId()));
        //获取所有传递的子单据id
        Set<Long> collect = req.getDetailList().stream().map(UpdateOrderDetailReq::getId).collect(Collectors.toSet());
        //获取所有数据库的子单据id
        Set<Long> existingIds = orderDetailList.stream().map(OrderDetail::getId).collect(Collectors.toSet());
        //比较两个子单id完全一致,判断传递的子单据id在数据库中是否存在，如果不存在则抛出子单据不存在异常
        if (!collect.containsAll(existingIds) || !existingIds.containsAll(collect)){
            throw new ServiceException(OrderExceptionEnum.ORDERDETAIL_ERROR);
        }
        LoginUser loginUser = LoginContext.getContext().getLoginUser();
        Long orgId=orderMain.getOrderType().equals("in") ? orderMain.getEndOrgId() : orderMain.getStartOrgId();
        List<Warehouse> warehouseList = warehouseService.list(new LambdaQueryWrapper<Warehouse>().eq(Warehouse::getOrgIdInt,orgId));
        //获取组织机构下的所有仓库id
        Map<String,Warehouse> warehouseMap=new HashMap<>();
        warehouseList.forEach(warehouse -> warehouseMap.put(warehouse.getId(), warehouse));
        //前端传递的子单数据
        String stringtext="";//记录记账日志内容json
        //总记账数量，用于记录主单据所有的记账数量，从而更新主单据
        Integer quantityTotal=0;
        List<OrderDetail> updateDetailList=new ArrayList<>();
        List<UpdateOrderDetailReq> detailList = req.getDetailList();
        //用于统计logSummary的存放map
        Map<String,LogSummaryReq> logMap=new HashMap<>();
        //用于统计invSummary的存放list
        List<UpdateOrderDetailReq> orderDetailReqList=new ArrayList<>();

        //半山的记账功能
        //1.需要判断是否是下发到半山的单子，如果是则另一种记账方式，如果不是则用原来的单据记账方式
        if (ObjectUtil.isNotNull(orderMain.getSyncFlag()) && orderMain.getSyncFlag()==1){
            return handleKFOrder(orderMain,req);
        }
        //2.修改单据（包括单据详情信息）
        boolean emptyOrderFlag=false;
        boolean result = updateOrderModifyQuantity(emptyOrderFlag,stringtext, orderMain, detailList, quantityTotal, updateDetailList,
                req,logMap,loginUser,warehouseMap,orgId,orderDetailReqList);
        //表示记空账，故直接返回
        if (!emptyOrderFlag){
            return result;
        }
        //3.判断单据类型，不同单据的处理方式不同，处理装备，分开写更容易看懂
        //自动识别的epc
        boolean InvUpdateResult = updateInventoryList(orderMain);

        //4.添加装备单据记账信息日志（orderLog）--空记账已经单独处理，故不需要管
        boolean orderLogResult = saveAccountingLog(req, stringtext, quantityTotal);

        //5.添加装备出入库日志汇总（logSummary）
        List<LogSummary> addLogSumList=new ArrayList<>();
        if (!logMap.isEmpty()){
            List<LogSummaryReq> collect1 = new ArrayList<>(logMap.values());
            collect1.forEach(ls ->{
                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());
                }else {
                    logSummary.setPicture(ls.getPhoto());
                }
                //判断是否是快速移库
                logSummary.setCreateTime(ObjectUtil.isNotNull(logSummary.getCreateTime())?logSummary.getCreateTime():new Date());
                addLogSumList.add(logSummary);
            });
        }
        if (!addLogSumList.isEmpty()){
            logSummaryService.saveBatch(addLogSumList);
        }

        //6.根据单据信息进行修改库存汇总
        PubOrg pubOrg = pubOrgService.PubOrgExist(orgId);
        boolean invSumResult=false;
        //除移库操作
        if (!req.getBussinessType().equals("quick")){
            invSumResult = updateInvSumInfo(orderMain,orderDetailReqList,pubOrg);
        }else {
            //移库操作
            invSumResult = handleQuickOrder(orderMain,detailList);
        }


        //7.记账结束之后往消息队列中推送一条消息
        MQReturnMsgDto mqReturnMsgDto = new MQReturnMsgDto();
        mqReturnMsgDto.setApi("SettlementOrder");
        mqReturnMsgDto.setId(req.getId());
        mqReturnMsgDto.setOrderType(req.getOrderType());
        //需要判断是入库单还是出库单，入库单传收物单位id，出库单传发物单位id
        if(req.getOrderType().equals("in")){
            MQ.SendMsg("orderExchange",req.getEndOrgId().toString(),mqReturnMsgDto);
        }else {
            MQ.SendMsg("orderExchange",req.getStartOrgId().toString(),mqReturnMsgDto);
        }
        //8.给大屏推送消息
        String name="largeScreen_exchange";
        //记账后推送消息给大屏，大屏收到消息之后会自动重新调取接口
        rabbitTemplate.convertAndSend(name, "", "message");
        //修改预案的单据
        changePlanState();

        //9.其他逻辑处理
        //领用出库
        boolean otherResult=true;
        if (req.getBussinessType().equals("use")){
            //如果是领用出库，那记账结束以后将装备挂到警员名下（存储到policemanEquipment表中）
            Policeman policeman = policemanService.getOne(new LambdaQueryWrapper<Policeman>().eq(Policeman::getUserId, req.getReturnUserId()));
            if (ObjectUtil.isNull(policeman)){
                throw new ServiceException(PolicemanExceptionEnum.POLICEMAN_NOT_EXIST);
            }
            otherResult = policeBindEqs(policeman,req, orderDetailReqList, orgId);
        }
        //如果是归还入库，将警员下面的装备进行处理
        if (req.getBussinessType().equals("return")){
            Policeman policeman = policemanService.getOne(new LambdaQueryWrapper<Policeman>().eq(Policeman::getUserId, req.getReturnUserId()));
            if (ObjectUtil.isNull(policeman)){
                throw new ServiceException(PolicemanExceptionEnum.POLICEMAN_NOT_EXIST);
            }
            otherResult = policeUnBindEqs(policeman,req, orderDetailReqList, orgId);
        }

        return InvUpdateResult && orderLogResult && invSumResult && otherResult;
    }

    private Boolean handleKFOrder(OrderMain orderMain,UpdateOrderReq req){
        //判断单据是否存在正在执行的任务，如果存在则直接提示报错
        Long orgId= orderMain.getOrderType().equals("in")?orderMain.getEndOrgId():orderMain.getStartOrgId();
        SysDictItem one = sysDictItemService.getOne(new LambdaQueryWrapper<SysDictItem>()
                .eq(SysDictItem::getItemText, orgId.toString()));
        Boolean flag =thirdPartyService.getTaskWokingState(orderMain.getOrderCode(),one.getItemValue());
        if (!flag){
            throw new ServiceException(OrderExceptionEnum.ORDER_IS_RUNNING_ERROR);
        }
        //判断是否是最新的出入库数据，如果是最新的进行下一步，如果不是最新的返回报错让前端进行弹窗后更新最新接口
        Boolean orderInfoResult =thirdPartyService.getLasterOrderInfo(orderMain.getId(),orderMain.getOrderType(),orderMain.getOrderCode(),one.getItemValue());
        if (!orderInfoResult){
            throw new ServiceException(OrderExceptionEnum.ORDER_IS_NOT_LASTER_ERROR);
        }

        //判断记账下发给半山是否能返回true，如果是不行则记账失败
        Boolean accountingResult = false;
        try {
            accountingResult = thirdPartyService.editOrderStatus(orderMain.getOrderCode(),one.getItemValue());
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
        if (!accountingResult){
            throw new ServiceException(OrderExceptionEnum.ORDER_IS_NOT_LASTER_ERROR);
        }

        //如果都顺利则直接开始记账操作
        Boolean reslut=false;
        if (orderMain.getOrderType().equals("in")){
            reslut=accountingBySyncInOrder(orderMain.getId(),req,orgId);

        }else {
            reslut=accountingBySyncOutOrder(orderMain.getId(),req,orgId);

        }
        return reslut;
    }

    /**
     * 正常出入库库存汇总增加、删除或修改
     */
    private Boolean updateInvSumInfo(OrderMain orderMain,List<UpdateOrderDetailReq> orderDetailReqList,PubOrg pubOrg){
        //1.根据记账的实际情况进行汇总装备map，为修改库存做准备
        Map<String,UpdateOrderDetailReq> map=new HashMap<>();
        //归还入库使用（为了确认归还入库的和领用出去的是否是同一个，如果不是，那么原来的出库数量就应该减少，新的入库数量增多）
        Map<String,UpdateOrderDetailReq> oldMap=new HashMap<>();

        for (UpdateOrderDetailReq detailReq:orderDetailReqList) {
            //如果归还入库和出库的不是同一个地方
            if (ObjectUtil.isNotNull(detailReq.getOldLocationId()) && !detailReq.getOldLocationId().equals(detailReq.getWarehouseId())){
                //做删除操作，将原来出库数减少，库存总数减少
                String oldKey=pubOrg.getOrgId()+detailReq.getOldLocationId()+detailReq.getTypeId()+detailReq.getSizeId()+detailReq.getPrice()+"0";
                if (oldMap.containsKey(oldKey)){
                    UpdateOrderDetailReq updateReq = oldMap.get(oldKey);
                    updateReq.setModifyQuantity(updateReq.getModifyQuantity()+detailReq.getModifyQuantity());
                    oldMap.put(oldKey,updateReq);

                }else {
                    UpdateOrderDetailReq updateReq = new UpdateOrderDetailReq();
                    BeanPlusUtil.copyProperties(detailReq,updateReq);
                    oldMap.put(oldKey,updateReq);
                }
                detailReq.setAddFlag(true);
            }else {
                detailReq.setAddFlag(false);
            }
            String key=pubOrg.getOrgId()+detailReq.getWarehouseId()+detailReq.getTypeId()+detailReq.getSizeId()+detailReq.getPrice()+"0";
            if (map.containsKey(key)){
                UpdateOrderDetailReq updateReq = map.get(key);
                updateReq.setModifyQuantity(updateReq.getModifyQuantity()+detailReq.getModifyQuantity());
                map.put(key,updateReq);

            }else {
                UpdateOrderDetailReq updateReq = new UpdateOrderDetailReq();
                BeanPlusUtil.copyProperties(detailReq,updateReq);
                map.put(key,updateReq);
            }

        }

        //2.根据汇总信息将装备汇总进行查询。
        //先把需要删除的库存汇总进行计算并且更新（以防止后面新增时数据混乱）
        List<Object[]> searchOldCriteria=new ArrayList<>();
        for (String key : oldMap.keySet()) {
            UpdateOrderDetailReq value = oldMap.get(key);
            Object[] criteria=new Object[]{pubOrg.getOrgId(),value.getOldLocationId(),value.getTypeId(),value.getSizeId(),value.getPrice(),"0"};
            searchOldCriteria.add(criteria);
        }

        //查询库存汇总
        List<Object[]> searchCriteria=new ArrayList<>();
        for (String key : map.keySet()) {
            UpdateOrderDetailReq value = map.get(key);
            Object[] criteria=new Object[]{pubOrg.getOrgId(),value.getWarehouseId(),value.getTypeId(),value.getSizeId(),value.getPrice(),"0"};
            searchCriteria.add(criteria);
        }
        //3.将需要进行删除、修改的装备汇总信息进行处理
        //删除List
        List<InventorySummary> delList=new ArrayList<>();
        if (CollectionUtil.isNotEmpty(searchOldCriteria)){
            List<InventorySummary> invOldSummaryList = inventorySummaryMapper.selectSum(searchOldCriteria);
            for (String key : oldMap.keySet()){
                UpdateOrderDetailReq upReq = oldMap.get(key);
                for (InventorySummary is:invOldSummaryList) {
                    if (upReq.getWarehouseId().equals(is.getLocationId()) && upReq.getSizeId().equals(is.getSizeId())
                            && upReq.getTypeId().equals(is.getTypeId()) && new BigDecimal(upReq.getPrice()).compareTo(is.getUnitPrice())==0){
                        is.setUpdateTime(DateTimeUtil.getCurrentDateTime());
                        is.setOutboundNumber(Math.max(is.getOutboundNumber()-upReq.getModifyQuantity(),0));
                        //如果库存数为0，那么直接删除该条记录
                        if (is.getNumber()==0 && is.getDestructionNumber()==0){
                            delList.add(is);
                            invOldSummaryList.remove(is);
                        }
                    }
                }
            }
            if (CollectionUtil.isNotEmpty(invOldSummaryList)){
                inventorySummaryService.updateBatchById(invOldSummaryList);
            }
        }
        List<InventorySummary> inventorySummaryList = inventorySummaryMapper.selectSum(searchCriteria);
        List<InventorySummary> addList=new ArrayList<>();
        List<InventorySummary> updateList=new ArrayList<>();

        //4.根据查询出来的汇总信息和实际记账汇总信息map进行循环，判断单据类型（orderType）以及单据业务类型（bussinessType）后对具体的装备汇总数进行修改
        for (String key : map.keySet()) {
            UpdateOrderDetailReq upReq = map.get(key);
            boolean flag=false;
            for (InventorySummary is:inventorySummaryList) {
                if (upReq.getWarehouseId().equals(is.getLocationId()) && upReq.getSizeId().equals(is.getSizeId())
                        && upReq.getTypeId().equals(is.getTypeId()) && new BigDecimal(upReq.getPrice()).compareTo(is.getUnitPrice())==0){
                    if (orderMain.getOrderType().equals("in")){
                        switch (orderMain.getBussinessType()){
                            case "purchase":
                            case "allocate":
                            case "gift":
                                is.setStockNumber(is.getStockNumber()+upReq.getModifyQuantity());
                                is.setNumber(is.getNumber()+upReq.getModifyQuantity());
                                is.setPrice(is.getUnitPrice().multiply(BigDecimal.valueOf(is.getNumber())));
                                break;
                            case "return":
                                is.setOutboundNumber(is.getOutboundNumber()-upReq.getModifyQuantity());
                                is.setStockNumber(is.getStockNumber()+upReq.getModifyQuantity());
                                is.setUseNumber(is.getUseNumber()-upReq.getModifyQuantity());
                                break;
                        }
                    }else {
                        switch (orderMain.getBussinessType()){
                            case "destruction":
                                is.setNumber(Math.max(is.getNumber() - upReq.getModifyQuantity(), 0));
                                is.setPrice(is.getUnitPrice().multiply(BigDecimal.valueOf(is.getNumber())));
                                is.setDestructionNumber(is.getDestructionNumber()+upReq.getModifyQuantity());
                                is.setDestructionPrice(is.getUnitPrice().multiply(BigDecimal.valueOf(is.getDestructionNumber())));
                                break;
                            case "allocate":
                                is.setNumber(Math.max(is.getNumber() - upReq.getModifyQuantity(), 0));
                                is.setStockNumber(Math.max(is.getStockNumber() - upReq.getModifyQuantity(), 0));
                                is.setPrice(is.getPrice().subtract(BigDecimal.valueOf(upReq.getModifyQuantity()).multiply(new BigDecimal(upReq.getPrice()))) );
                                //如果库存数为0，那么直接删除该条记录
                                if (is.getNumber()==0 && is.getDestructionNumber()==0){
                                    delList.add(is);
                                }
                                break;
                            case "use":
                                Integer stockNumber = is.getStockNumber();
                                is.setStockNumber(Math.max(is.getStockNumber() - upReq.getModifyQuantity(), 0));
                                if (is.getStockNumber() == 0) {
                                    is.setOutboundNumber(is.getOutboundNumber() + stockNumber);
                                } else {
                                    is.setOutboundNumber(is.getOutboundNumber() + upReq.getModifyQuantity());
                                }
                                if (ObjectUtil.isNull(is.getUseCount())){
                                    is.setUseCount(0);
                                }
                                is.setUseCount(is.getUseCount()+upReq.getModifyQuantity());
                                if(ObjectUtil.isNull(is.getUseNumber())){
                                    is.setUseNumber(0);
                                }
                                is.setUseNumber(is.getUseNumber()+upReq.getModifyQuantity());
                                break;
                        }
                    }
                }
                updateList.add(is);
                flag=true;
                break;
            }
            if (!flag){//新增（调拨入库、采购入库、赠与入库有，出库没有 ）
                InventorySummary inventorySummary = inventorySummaryService.createInventorySummary(pubOrg.getOrgId(),
                        pubOrg.getOrgName(), pubOrg.getOrgCode(), upReq.getTypeId(), upReq.getTypeName(), upReq.getSizeId(),
                        upReq.getSizeName(), upReq.getWarehouseId(), upReq.getWarehouseName(), upReq.getModifyQuantity(),
                        0, new BigDecimal(upReq.getPrice()), 0, 0, 0,
                        0, 0,0, 0, "0");
                addList.add(inventorySummary);
            }
        }


        //5.根据最终装备汇总数进行新增、修改、删除
        boolean result=true;
        if (addList.size()>0){
            boolean addResult = inventorySummaryService.saveBatch(addList);
            result = addResult;
        }
        if (updateList.size()>0){
            boolean updateResult = inventorySummaryService.updateBatchById(updateList);
            result = result && updateResult;
        }
        if (delList.size()>0){
            inventorySummaryService.removeBatchByIds(delList);
        }
        return result;
    }

    /**
     * 处理快速出入库单
     * @return
     */
    public boolean handleQuickOrder(OrderMain existOrder,List<UpdateOrderDetailReq> detailList){
        //1.创建新的入库单并且更新
        OrderMain quickInOrder = createQuickInOrder(existOrder);
        //2.修改原来的库存汇总
        //3.修改新的库存汇总
        updateInvSumByQucikOrder(existOrder,detailList,quickInOrder);
        //4.添加入库单的入库汇总记录
        createLogSumByQuickOrder(quickInOrder,detailList);

        //5.判断是否有装备识别，如果有则直接将绑定关系进行修改，如果没有则忽略
        List<WarehouseInventory> wareInventoryList = outInRecordRedisCache.addWareInventory("addInvWareRecord:" + existOrder.getId());
        if (ObjectUtil.isNotEmpty(wareInventoryList)){
            List<String> epcList = wareInventoryList.stream().map(WarehouseInventory::getEpc).collect(Collectors.toList());
            warehouseInventoryService.update(new LambdaUpdateWrapper<WarehouseInventory>()
                    .set(WarehouseInventory::getLocationId,quickInOrder.getLocationId())
                    .set(WarehouseInventory::getLocationName,quickInOrder.getLocationName())
                    .set(WarehouseInventory::getLocationState,"in")
                    .in(WarehouseInventory::getEpc,epcList));
        }
        return true;
    }

    /**
     * 创建快速入库单入库流水汇总
     * @return
     */
    private boolean createLogSumByQuickOrder(OrderMain quickInOrder, List<UpdateOrderDetailReq> detailList){
        LogSummary addLogSummary=new LogSummary();
        addLogSummary.setOrgId(quickInOrder.getEndOrgId());
        addLogSummary.setOrgName(quickInOrder.getEndOrgName());
        addLogSummary.setOrderMainId(quickInOrder.getId());
        addLogSummary.setOrderCode(quickInOrder.getOrderCode());
        addLogSummary.setDeviceType(4);
        addLogSummary.setLocationId(quickInOrder.getLocationId());
        addLogSummary.setLocationName(quickInOrder.getLocationName());
        addLogSummary.setLocationType(0);
        addLogSummary.setUseTime(new Date());
        addLogSummary.setBussinessType(quickInOrder.getBussinessType());
        addLogSummary.setUserName(LoginContext.getContext().getLoginUser().getUserInfo().getRealName());
        addLogSummary.setCreateTime(new Date());
        addLogSummary.setUpdateTime(new Date());
        addLogSummary.setUploadType(1);
        Integer number=0;
        List<String> types = new ArrayList<>();
        for (UpdateOrderDetailReq detailReq:detailList){
            number+=detailReq.getModifyQuantity();
            if (detailReq.getTypeName() != null && !types.contains(detailReq.getTypeName())) {
                types.add(detailReq.getTypeName());
            }
        }
        addLogSummary.setNumber(number);
        addLogSummary.setEquipmentList(String.join(",",types));
        return logSummaryService.save(addLogSummary);
    }

    /**
     * 更新快速输入库单据库存汇总数
     * @param existOrder
     * @param detailList
     * @param quickInOrder
     * @return
     */
    private boolean updateInvSumByQucikOrder(OrderMain existOrder,List<UpdateOrderDetailReq> detailList,
                                             OrderMain quickInOrder){
        //1.原来出库单的查询条件list（根据条件查询库存汇总表中包含有相同条件的数据）
        Map<String,Object[]> oldCriteria=new HashMap<>();
        //2.新建的入库单查询条件list（根据条件查询库存汇总表中是否包含有相同条件的数据）
        Map<String,Object[]> newCriteria=new HashMap<>();
        //查询条件，将所有查询条件放在searchCriteria中，用于修改库存表中的装备的仓库位置
        //循环记账子单
        for (UpdateOrderDetailReq detailReq:detailList) {
            List<DetailJsonReq> childJson = detailReq.getChildJson();
            for (DetailJsonReq jsonReq:childJson) {
                //移出仓库
                BigDecimal unitPirce=ObjectUtil.isNull(jsonReq.getUnitPrice())?jsonReq.getPrice():jsonReq.getUnitPrice();
                String removeKey=existOrder.getStartOrgId()+jsonReq.getLocationId()+detailReq.getTypeId()+detailReq.getSizeId()+unitPirce;
                if (!oldCriteria.containsKey(removeKey)){
                    Object[] objects = oldCriteria.get(removeKey);
                    objects[6]=(Integer)objects[6]+jsonReq.getModifyQuantity();
                    oldCriteria.put(removeKey,objects);
                }else {
                    Object[] criteria=new Object[]{existOrder.getStartOrgId(),jsonReq.getLocationId(),detailReq.getTypeId(),detailReq.getSizeId(),unitPirce,0,jsonReq.getModifyQuantity()};
                    oldCriteria.put(removeKey,criteria);
                }

                //移入仓库
                String addKey=quickInOrder.getEndOrgId()+quickInOrder.getLocationId()+detailReq.getTypeId()+detailReq.getSizeId()+unitPirce;
                if (!oldCriteria.containsKey(addKey)){
                    Object[] objects = oldCriteria.get(addKey);
                    newCriteria.put(removeKey,objects);
                }
            }
        }

        //将summary汇总表中数据进行修改(修改该组织机构下的装备汇总信息将库存信息的在库数，库存总数，总价还有其他数据数量进行修改)
        //3首先将原来的仓库下的装备汇总信息进行查询出来，对其进行修改（移出）
        List<Object[]> objects = new ArrayList<>(oldCriteria.values());
        List<InventorySummary> oldSummaryList = inventorySummaryMapper.selectSum(objects);


        //4.创建删除列表用于将没用的数据汇总信息进行删除
        List<InventorySummary> deleteList=new ArrayList<>();


        //5.将修改的信息直接保存(需要的只是各种数量方便计算)
        List<InventorySummary> saveList=new ArrayList<>();
        Map<String,InventorySummary> summaryMap=new HashMap<>();
        for (Object[] json: objects ) {
            for (InventorySummary oldSum : oldSummaryList) {
                //如果组织机构、仓库id、sizeId、typeId、unitPrice相同，那么修改其各项数值（
                // 不会存在两个列表长度不对等的情况，一定是一对一的，只不过是顺序问题，所以需要进行遍历）
                if (json[1].equals(oldSum.getLocationId()) &&
                        json[2].equals(oldSum.getTypeId())
                        && json[3].equals(oldSum.getSizeId())
                        && ((BigDecimal) json[4]).compareTo(oldSum.getUnitPrice()) == 0) {
                    //为入库做准备
                    InventorySummary invSumByQuickIn = createInvSumByQuickIn(oldSum, quickInOrder.getLocationId(), quickInOrder.getLocationName(),(Integer) json[6], (BigDecimal) json[4]);
                    saveList.add(invSumByQuickIn);
                    if (!summaryMap.containsKey(invSumByQuickIn.getValuekey())){
                        summaryMap.put(invSumByQuickIn.getValuekey(),invSumByQuickIn);
                    }else {
                        InventorySummary inventorySummary1 = summaryMap.get(invSumByQuickIn.getValuekey());
                        inventorySummary1.setNumber(inventorySummary1.getNumber()+invSumByQuickIn.getNumber());
                        inventorySummary1.setPrice(inventorySummary1.getPrice().add(invSumByQuickIn.getPrice()));
                        inventorySummary1.setStockNumber(inventorySummary1.getStockNumber()+invSumByQuickIn.getStockNumber());
                        summaryMap.put(invSumByQuickIn.getValuekey(),inventorySummary1);
                    }

                    oldSum.setNumber(Math.max(oldSum.getNumber()-(Integer) json[6],0));
                    oldSum.setPrice(((BigDecimal) json[4]).multiply(BigDecimal.valueOf(oldSum.getNumber())));
                    oldSum.setStockNumber(Math.max(oldSum.getStockNumber()-(Integer) json[6],0));

                    //如果存在删减数量完成之后所有的数量值都是0的情况，那么将这一条数据进行删除操作
                    if (oldSum.getNumber()==0 && oldSum.getBrokenNumber()==0 &&  oldSum.getDestructionNumber() == 0) {
                        deleteList.add(oldSum);
                        oldSummaryList.remove(oldSum);
                    }
                    break;//查询到直接跳过该循环进入下一循环
                }
            }
        }
        //如果删除list不为空，那么进行批量删除
        if (deleteList.size()>0){
            inventorySummaryService.removeBatchByIds(deleteList);
        }
        if (CollectionUtil.isNotEmpty(oldSummaryList)){
            inventorySummaryService.updateBatchById(oldSummaryList);
        }


        //6.查询出修改后的仓库下面的汇总信息，判断该仓库下是否已经存在该号型、类型、单价相同的装备数据（移入）
        List<InventorySummary> newSummaryList = inventorySummaryMapper.selectSum(new ArrayList<>(newCriteria.values()));

        //判断查询到的newList是否有值，如果有值直接进行修改即可，但是如果不存在，则默认新增一条数据
        //修改的是移入仓库的值
        if (newSummaryList.size()>0){
            for (int i = 0; i < saveList.size(); i++) {
                for (InventorySummary inventorySummary : newSummaryList) {
                    InventorySummary save = saveList.get(i);
                    if (save.getLocationId().equals(inventorySummary.getLocationId()) &&
                            save.getSizeId().equals(inventorySummary.getSizeId())
                            && save.getTypeId().equals(inventorySummary.getTypeId())
                            && save.getUnitPrice().compareTo(inventorySummary.getUnitPrice()) == 0) {
                        inventorySummary.setNumber(save.getNumber() + inventorySummary.getNumber());
                        inventorySummary.setStockNumber(save.getStockNumber() + inventorySummary.getStockNumber());
                        inventorySummary.setPrice(inventorySummary.getPrice().multiply(BigDecimal.valueOf(inventorySummary.getNumber())));
                        //remove表示该仓库下面存在数量，数量加减完之后直接在新增的list中进行移出x
                        saveList.remove(save);
                        i--;
                        break;
                    }
                }
            }
        }

        //如果saveList不为空则save

        if(saveList.size()>0){
            List<InventorySummary> collect1 = new ArrayList<>(summaryMap.values());
            inventorySummaryService.saveBatch(collect1);
        }

        inventorySummaryService.updateBatchById(newSummaryList);
        return true;
    }

    /**
     * 创建快速入库单据inventorySummary
     */
    private InventorySummary createInvSumByQuickIn(InventorySummary oldSum, String locationId, String locationName, Integer modifyQuantity, BigDecimal unitPrice) {
        InventorySummary inventorySummary = new InventorySummary();
        BeanPlusUtil.copyProperties(oldSum,inventorySummary);
        inventorySummary.setLocationId(locationId);
        inventorySummary.setLocationName(locationName);
        //在库数量进行修改并且报废数设为0
        inventorySummary.setBrokenNumber(0);
        inventorySummary.setOutboundNumber(0);
        inventorySummary.setNumber(modifyQuantity);
        inventorySummary.setPrice(unitPrice.multiply(BigDecimal.valueOf(modifyQuantity)));
        inventorySummary.setStockNumber(modifyQuantity);
        inventorySummary.setDestructionNumber(0);
        inventorySummary.setDestructionPrice(BigDecimal.ZERO);
        inventorySummary.setId(null);
        //设置valuekey
        String unitPriceStr="";
        if (unitPrice.toString().endsWith(".00")) {
            unitPriceStr=unitPrice.toString().substring(0, unitPrice.toString().length() - 3);
        }
        // 再处理末尾是 0 的情况（如 .60 -> .6）
        else if (unitPrice.toString().contains(".") && unitPrice.toString().endsWith("0")) {
            unitPriceStr=unitPrice.toString().substring(0, unitPrice.toString().length() - 1);
        }
        String valueKey = createValueKey(oldSum.getOrgCode(), locationId, oldSum.getTypeId(),
                oldSum.getSizeId(), unitPriceStr, oldSum.getProperty().toString());
        inventorySummary.setValuekey(valueKey);
        return inventorySummary;
    }

    /**
     * 创建快速入库单
     * @param existOrder
     * @return
     */
    private OrderMain createQuickInOrder(OrderMain existOrder){
        OrderMain orderMain = new OrderMain();
        BeanPlusUtil.copyProperties(existOrder,orderMain);
        orderMain.setEndOrgId(existOrder.getStartOrgId());
        orderMain.setEndOrgName(existOrder.getStartOrgName());
        orderMain.setOrderType("in");
        orderMain.setId(UUID.randomUUID().toString());
        //工作流流程设为空
        orderMain.setProcessId(null);
        //修改订单编号，设置为入库的单号
        UpdateOrderReq req = new UpdateOrderReq();
        BeanPlusUtil.copyProperties(orderMain,req);
        OrderNum orderNum = setOrderCode(req);
        long time = new Date().getTime() % 10000;
        String codeValue=String.format("%04d",orderNum.getNum());
        orderMain.setOrderCode(orderNum.getBussinessType()+String.format("%04d",time)+orderNum.getYear()+
                String.format("%02d",LocalDateTime.now().getMonth().getValue())+
                String.format("%02d",LocalDateTime.now().getDayOfMonth())+codeValue);
        //保存入库单
        save(orderMain);
        //查询出库子单用于赋值到入库单中
        List<OrderDetail> list = orderDetailService.list(new LambdaQueryWrapper<OrderDetail>()
                .eq(OrderDetail::getOrderId, existOrder.getId()));
        //移入仓库id
        String locationId = orderMain.getLocationId();
        String locationName = orderMain.getLocationName();
        //创建入库单子单
        List<OrderDetail> collect = list.stream().map(orderDetail -> {

            OrderDetail orderDetail1 = new OrderDetail();
            BeanPlusUtil.copyProperties(orderDetail, orderDetail1);
            List<DetailJsonReq> detailJsonReqs = JSONObject.parseArray(orderDetail.getDetailJson(), DetailJsonReq.class);
            if (CollectionUtil.isNotEmpty(detailJsonReqs)){
                for (DetailJsonReq a:detailJsonReqs) {
                    a.setLocationId(locationId);
                    a.setLocationName(locationName);
                }
            }
            orderDetail1.setDetailJson(JSONObject.toJSONString(detailJsonReqs));
            orderDetail1.setId(null);
            //修改主单据id
            orderDetail1.setOrderId(orderMain.getId());
            //修改单据出入状态
            orderDetail1.setType("in");
            //修改移入仓库id
            orderDetail1.setWarehouseId(locationId);
            orderDetail1.setWarehouseName(locationName);

            return orderDetail1;
        }).collect(Collectors.toList());
        orderDetailService.saveBatch(collect);
        return orderMain;
    }
    /**
     * 更新装备epc详情
     * @param orderMain
     * @return
     */
    private boolean updateInventoryList(OrderMain orderMain){
        List<Inventory> inventoryList = outInRecordRedisCache.addInventory("addInvRecord:" + orderMain.getId());
        if (inventoryList.size()>0){
            //需要先判断是否在epc池里，如果在则不仅添加，否则需要添加
            List<String> invEpcList = inventoryList.stream().map(Inventory::getEpc).collect(Collectors.toList());
            List<Inventory> existInvList = inventoryService.list(new LambdaQueryWrapper<Inventory>().in(Inventory::getEpc, invEpcList));
            if (existInvList.size()>0){
                List<String> existInvEpcList = existInvList.stream().map(Inventory::getEpc).collect(Collectors.toList());
                inventoryList=inventoryList.stream().filter(inventory -> !existInvEpcList.contains(inventory.getEpc())).collect(Collectors.toList());
            }
            if (inventoryList.size()>0){
                inventoryService.saveBatch(inventoryList);
            }

        }
        List<WarehouseInventory> wareInventoryList = outInRecordRedisCache.addWareInventory("addInvWareRecord:" + orderMain.getId());
        List<String> wareEpcList = wareInventoryList.stream().map(WarehouseInventory::getEpc).collect(Collectors.toList());
        if (wareInventoryList.size()>0){

            if (orderMain.getOrderType().equals("in")){
                warehouseInventoryService.saveBatch(wareInventoryList);

            }else {
                if (!orderMain.getBussinessType().equals("quick")){
                    warehouseInventoryService.remove(new LambdaQueryWrapper<WarehouseInventory>()
                            .eq(WarehouseInventory::getEpc, wareEpcList)
                            .eq(WarehouseInventory::getOrgId, orderMain.getStartOrgId()));
                }
            }
        }
        redisCache.remove("addInvRecord:" + orderMain.getId());
        redisCache.remove("addInvWareRecord:" + orderMain.getId());
        return true;
    }

    /**
     * 修改主单据和子单据的记账数据
     * @param stringtext
     * @param orderMain
     * @param detailList
     * @param quantityTotal
     * @param updateDetailList
     * @param req
     * @return
     */
    private boolean updateOrderModifyQuantity(Boolean emptyOrderFlag,String stringtext,OrderMain orderMain,List<UpdateOrderDetailReq> detailList,
                                              Integer quantityTotal,List<OrderDetail> updateDetailList,UpdateOrderReq req,
                                              Map<String,LogSummaryReq> logMap,LoginUser loginUser,
                                              Map<String,Warehouse> warehouseMap,Long orgId,
                                              List<UpdateOrderDetailReq> orderDetailReqList){
        for (UpdateOrderDetailReq uploadDetailReq : detailList){
            OrderDetail orderDetail = new OrderDetail();
            BeanPlusUtil.copyProperties(uploadDetailReq,orderDetail);
            //记空账（识别0，记账0）
            if ((ObjectUtil.isNull(uploadDetailReq.getActualNum()) ||uploadDetailReq.getActualNum()==0)
                    && (ObjectUtil.isNull(uploadDetailReq.getModifyQuantity()) || uploadDetailReq.getModifyQuantity()==0)){
                //添加出入库日志记录
                if (orderMain.getOrderType().equals("in")){

                    stringtext = stringtext+uploadDetailReq.getTypeName()+"【"+
                            uploadDetailReq.getSizeName()+"】，单价："+uploadDetailReq.getPrice()
                            +"，数量实入：0，记账：0"+"\n";
                }else {
                    stringtext = stringtext+uploadDetailReq.getTypeName()+"【"+
                            uploadDetailReq.getSizeName()+"】，单价："+uploadDetailReq.getPrice()
                            +"，数量实出：0，记账：0"+"\n";

                }
                orderDetail.setModifyQuantity(0);
                orderDetail.setUpdateTime(DateTimeUtil.getCurrentDateTime());
                updateDetailList.add(orderDetail);
                quantityTotal+=orderDetail.getModifyQuantity();
                continue;
            }else {
                //正常记账，识别数量和记账数据进行比较后存储
                List<DetailJsonReq> JsonList = uploadDetailReq.getChildJson();
                for (DetailJsonReq detailJsonReq:JsonList) {
                    //判断仓库是否为空
                    if (!warehouseMap.isEmpty()){
                        //判断是否有key存在，如果没有直接报错
                        boolean b = warehouseMap.containsKey(detailJsonReq.getLocationId());
                        if (b){
                            //判断改仓库是否处于锁库状态，如果是提示错误仓库正在锁库中
                            Warehouse warehouse = warehouseMap.get(detailJsonReq.getLocationId());
                            if (ObjectUtil.isNotNull(warehouse.getIsLocked())&& warehouse.getIsLocked()==1){
                                throw new ServiceException(WarehouseExceptionEnum.WAREHOUSE_IS_LOCKED);
                            }
                        }
                    }
                    //单价
                    BigDecimal price=BigDecimal.ZERO;
                    if (ObjectUtil.isNull(detailJsonReq.getPrice()) && ObjectUtil.isNull(detailJsonReq.getUnitPrice())){
                        if (uploadDetailReq.getPrice().contains("/")) {
                            // 获取第一个斜杠前面的值
                            String firstPart = uploadDetailReq.getPrice().substring(0, uploadDetailReq.getPrice().indexOf("/"));

                            price=new BigDecimal(firstPart);
                        } else {
                            // 如果没有斜杠，则直接使用原始值
                            price=new BigDecimal(uploadDetailReq.getPrice());

                        }
                    }

                    //添加出入库日志记录
                    if (orderMain.getOrderType().equals("in")){

                        stringtext = stringtext+detailJsonReq.getLocationName()+"--"+detailJsonReq.getTypeName()+"【"+
                                detailJsonReq.getSizeName()+"】，单价："+((ObjectUtil.isNull(detailJsonReq.getPrice())  && ObjectUtil.isNull(detailJsonReq.getUnitPrice()))
                                ? price.toString() :ObjectUtil.isNull(detailJsonReq.getPrice() )?detailJsonReq.getUnitPrice().toString():detailJsonReq.getPrice().toString())
                                +"，数量实入："+(ObjectUtil.isNull(detailJsonReq.getNum())?0:detailJsonReq.getNum())+"，记账："+ detailJsonReq.getModifyQuantity()+"\n";
                    }else {
                        stringtext = stringtext+detailJsonReq.getLocationName()+"--"+detailJsonReq.getTypeName()+"【"+
                                detailJsonReq.getSizeName()+"】，单价："+((ObjectUtil.isNull(detailJsonReq.getPrice())  && ObjectUtil.isNull(detailJsonReq.getUnitPrice()))
                                ? price.toString() :ObjectUtil.isNull(detailJsonReq.getPrice() )?detailJsonReq.getUnitPrice().toString():detailJsonReq.getPrice().toString())
                                +"，数量实出："+(ObjectUtil.isNull(detailJsonReq.getNum())?0:detailJsonReq.getNum())+"，记账："+ detailJsonReq.getModifyQuantity()+"\n";

                    }

                    //添加list为修改库存Summary
                    addOrderInvSumList(orderDetailReqList, uploadDetailReq, detailJsonReq,price);

                    //添加到出入库汇总map中，为后续的出入库记录汇总进行存储
                    logSummaryService.setLogSummaryToMap(logMap,loginUser.getUserInfo().getRealName(),loginUser.getOrgName(),detailJsonReq.getLocationId(),req.getBussinessType(),
                            uploadDetailReq.getTypeName(),detailJsonReq.getLocationName(),orderMain.getId(),
                            orderMain.getOrderCode(),orgId,orderMain.getOrderType(),4,detailJsonReq.getModifyQuantity(),"0",null,null,null);
                }


                emptyOrderFlag=true;
            }
            List<DetailJsonReq> JsonList = uploadDetailReq.getChildJson();
            String jsonString = JSONObject.toJSONString(JsonList);
            orderDetail.setDetailJson(jsonString);
            if (ObjectUtil.isNull(uploadDetailReq.getActualNum())){
                uploadDetailReq.setActualNum(0);
            }
            //获取修改后的数量并且记录(modifyQuantity表示有记账数量)
            //个别记账为0已经被过来掉
            if (uploadDetailReq.getModifyQuantity()>=0){
                //修改单子数量数量
                orderDetail.setModifyQuantity(uploadDetailReq.getModifyQuantity());
                orderDetail.setUpdateTime(DateTimeUtil.getCurrentDateTime());
                updateDetailList.add(orderDetail);
                quantityTotal+=orderDetail.getModifyQuantity();
            }else {
                //记账数量不满足条件，直接报错
                throw new ServiceException(OrderExceptionEnum.ORDER_MODIFYQUANTITY_ERROR);
            }

        }
        //记账0
        //用于判断是否是空账(如果是false，则表示记空账)
        if (!emptyOrderFlag){
            orderMain.setActualQuantity(quantityTotal);
            orderMain.setOrderState("finished");
            //修改记账状态，0未记账，1已记账
            orderMain.setManualState(1);
            orderMain.setUpdateTime(DateTimeUtil.getCurrentDateTime());
            boolean a = orderDetailService.updateBatchById(updateDetailList);
            boolean b = updateById(orderMain);
            boolean c = saveAccountingLog(req, stringtext, quantityTotal);
            return a && b && c;
        }
        //更新主单据的数量和价格
        orderMain.setActualQuantity(quantityTotal);
        orderMain.setOrderState("finished");
        //修改记账状态，0未记账，1已记账
        orderMain.setManualState(1);
        orderMain.setUpdateTime(DateTimeUtil.getCurrentDateTime());
        updateById(orderMain);
        return true;
    }


    private List<UpdateOrderDetailReq>  addOrderInvSumList(List<UpdateOrderDetailReq> orderDetailReqList, UpdateOrderDetailReq uploadDetailReq, DetailJsonReq detailJsonReq,BigDecimal price){
        UpdateOrderDetailReq data = new UpdateOrderDetailReq();
        data.setActualNum(ObjectUtil.isNull(detailJsonReq.getNum())?0:detailJsonReq.getNum());
        data.setWarehouseId(detailJsonReq.getLocationId());
        data.setOldLocationId(detailJsonReq.getOldLocationId());
        data.setWarehouseName(detailJsonReq.getLocationName());
        data.setSizeId(ObjectUtil.isNull(detailJsonReq.getSizeId())? uploadDetailReq.getSizeId():detailJsonReq.getSizeId());
        data.setTypeId(ObjectUtil.isNull(detailJsonReq.getTypeId())? uploadDetailReq.getTypeId():detailJsonReq.getTypeId());
        data.setPrice((ObjectUtil.isNull(detailJsonReq.getPrice())  && ObjectUtil.isNull(detailJsonReq.getUnitPrice()))
                ? price.toString() :ObjectUtil.isNull(detailJsonReq.getPrice() )?detailJsonReq.getUnitPrice().toString():detailJsonReq.getPrice().toString());
        data.setProperty(0);
        data.setSizeName(ObjectUtil.isNotEmpty(detailJsonReq.getSizeName())?detailJsonReq.getSizeName():uploadDetailReq.getSizeName());
        data.setTypeName(ObjectUtil.isNotEmpty(detailJsonReq.getTypeName())?detailJsonReq.getTypeName():uploadDetailReq.getTypeName());
        data.setModifyQuantity(detailJsonReq.getModifyQuantity());
        orderDetailReqList.add(data);
        return orderDetailReqList;
    }

}


