package com.huaheng.pc.task.taskHeader.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huaheng.api.wcs.service.taskAssignService.TaskAssignService;
import com.huaheng.common.constant.QuantityConstant;
import com.huaheng.common.exception.BusinessException;
import com.huaheng.common.exception.service.ServiceException;
import com.huaheng.common.support.Convert;
import com.huaheng.common.utils.DataUtils;
import com.huaheng.common.utils.StringUtils;
import com.huaheng.common.utils.security.ShiroUtils;
import com.huaheng.framework.web.domain.AjaxResult;
import com.huaheng.mobile.download.Constant;
import com.huaheng.pc.config.configWarning.service.ConfigWarningService;
import com.huaheng.pc.config.container.domain.Container;
import com.huaheng.pc.config.container.service.ContainerService;
import com.huaheng.pc.config.containerCapacity.domain.ContainerCapacity;
import com.huaheng.pc.config.containerCapacity.service.ContainerCapacityService;
import com.huaheng.pc.config.location.domain.Location;
import com.huaheng.pc.config.location.service.LocationService;
import com.huaheng.pc.config.sendMail.service.MailService;
import com.huaheng.pc.config.sendMail.service.SendMailService;
import com.huaheng.pc.inventory.cycleCountDetail.domain.CycleCountDetail;
import com.huaheng.pc.inventory.cycleCountDetail.service.CycleCountDetailService;
import com.huaheng.pc.inventory.cycleCountHeader.service.CycleCountHeaderService;
import com.huaheng.pc.inventory.inventoryDetail.domain.InventoryDetail;
import com.huaheng.pc.inventory.inventoryDetail.service.InventoryDetailService;
import com.huaheng.pc.inventory.inventoryHeader.domain.InventoryHeader;
import com.huaheng.pc.inventory.inventoryHeader.service.InventoryHeaderService;
import com.huaheng.pc.inventory.inventoryTransaction.domain.InventoryTransaction;
import com.huaheng.pc.inventory.inventoryTransaction.service.InventoryTransactionService;
import com.huaheng.pc.monitor.message.service.BrokerMessageLogService;
import com.huaheng.pc.receipt.receiptContainerDetail.domain.ReceiptContainerDetail;
import com.huaheng.pc.receipt.receiptContainerDetail.service.ReceiptContainerDetailService;
import com.huaheng.pc.receipt.receiptContainerHeader.domain.ReceiptContainerHeader;
import com.huaheng.pc.receipt.receiptContainerHeader.service.ReceiptContainerHeaderService;
import com.huaheng.pc.receipt.receiptDetail.domain.ReceiptDetail;
import com.huaheng.pc.receipt.receiptDetail.service.ReceiptDetailService;
import com.huaheng.pc.receipt.receiptHeader.domain.ReceiptHeader;
import com.huaheng.pc.receipt.receiptHeader.service.ReceiptHeaderService;
import com.huaheng.pc.receipt.receiving.service.ReceivingService;
import com.huaheng.pc.shipment.shipmentContainerDetail.domain.ShipmentContainerDetail;
import com.huaheng.pc.shipment.shipmentContainerDetail.service.ShipmentContainerDetailService;
import com.huaheng.pc.shipment.shipmentContainerHeader.domain.ShipmentContainerHeader;
import com.huaheng.pc.shipment.shipmentContainerHeader.service.ShipmentContainerHeaderService;
import com.huaheng.pc.shipment.shipmentDetail.domain.ShipmentDetail;
import com.huaheng.pc.shipment.shipmentDetail.service.ShipmentDetailService;
import com.huaheng.pc.shipment.shipmentHeader.domain.ShipmentHeader;
import com.huaheng.pc.shipment.shipmentHeader.service.ShipmentHeaderService;
import com.huaheng.pc.task.taskDetail.domain.TaskDetail;
import com.huaheng.pc.task.taskDetail.service.TaskDetailService;
import com.huaheng.pc.task.taskHeader.domain.MobileTask;
import com.huaheng.pc.task.taskHeader.domain.ShipmentTaskCreateModel;
import com.huaheng.pc.task.taskHeader.domain.TaskHeader;
import com.huaheng.pc.task.taskHeader.mapper.TaskHeaderMapper;
import io.swagger.models.auth.In;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;

@Service
public class TaskHeaderServiceImpl extends ServiceImpl<TaskHeaderMapper, TaskHeader> implements TaskHeaderService {

    @Resource
    private ShipmentContainerHeaderService shipmentContainerHeaderService;
    @Resource
    private ShipmentContainerDetailService shipmentContainerDetailService;
    @Resource
    private LocationService locationService;
    @Resource
    private ContainerService containerService;
    @Resource
    private TaskDetailService taskDetailService;
    @Resource
    private TaskHeaderService taskHeaderService;
    @Resource
    private InventoryHeaderService inventoryHeaderService;
    @Resource
    private InventoryDetailService inventoryDetailService;
    @Resource
    private InventoryTransactionService inventoryTransactionService;
    @Resource
    private ReceiptHeaderService receiptHeaderService;
    @Resource
    private ReceiptDetailService receiptDetailService;
    @Resource
    private ReceiptContainerDetailService receiptContainerDetailService;
    @Resource
    private ShipmentHeaderService shipmentHeaderService;
    @Resource
    private ShipmentDetailService shipmentDetailService;
    @Resource
    private CycleCountDetailService cycleCountDetailService;
    @Resource
    private CycleCountHeaderService cycleCountHeaderService;
    @Resource
    private ReceiptContainerHeaderService receiptContainerHeaderService;
    @Resource
    private TaskHeaderMapper taskHeaderMapper;
    @Autowired
    private TaskAssignService taskAssignService;
    @Resource
    private ContainerCapacityService containerCapacityService;
    @Resource
    private ConfigWarningService configWarningService;
    @Resource
    private ReceivingService receivingService;

    @Resource
    private CreateTaskMessage createTaskMessage;

    /**
     * 盘点任务首选项
     *
     * @param taskHeaderList
     * @return
     */
    @Override
    public List<TaskHeader> preferenceRealize(List<TaskHeader> taskHeaderList) {
        //盘点任务头,默认不显示库位,容器。
        List<TaskHeader> taskHeaders = new ArrayList<>();
        for (TaskHeader item : taskHeaderList) {
            item.setFromLocation("");
            item.setToLocation("");
            item.setContainerCode("");
            taskHeaders.add(item);
        }
        return taskHeaders;
    }

    @Override
    public List<TaskHeader> getTasksStatus(Short lastStatus) {
        return taskHeaderMapper.getTasksStatus(lastStatus);
    }

    /**
     * 根据库位完成任务
     *
     * @param locationCode
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult completeTask(String locationCode) {
        LambdaQueryWrapper<TaskHeader> taskQueryWrapper = Wrappers.lambdaQuery();
        taskQueryWrapper.eq(TaskHeader::getToLocation, locationCode);
        List<TaskHeader> list = this.list(taskQueryWrapper);
        if (list.size() < 1) {
            throw new ServiceException("库位(" + locationCode + ")没有任务!");
        } else if(list.get(0).getStatus() == 100) {
            //如果已完成则不管
            throw new ServiceException("库位(" + locationCode + ")任务已经完成!");
        }
        if(list.get(0).getTaskType()==100 || list.get(0).getTaskType()==200){
            //入库任务
            return  completeReceiptTask((list.get(0)));
        } else {
            throw new ServiceException("库位(" + locationCode + ")的任务不是上架,不能完成!");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult createReplenishTask(String containerCode, Short taskStatus) {
        LambdaQueryWrapper<ReceiptContainerHeader> headerQueryWrapper = Wrappers.lambdaQuery();
        headerQueryWrapper.eq(ReceiptContainerHeader::getContainerCode, containerCode)
                .eq(ReceiptContainerHeader::getStatus, QuantityConstant.RECEIPT_CONTAINER_BUILD);

        List<ReceiptContainerHeader> receiptContainerHeaderList = receiptContainerHeaderService.list(headerQueryWrapper);
        if (receiptContainerHeaderList.isEmpty()) {
            throw new ServiceException("该容器没有任务!");
        }
        if (receiptContainerHeaderList.size() > 1){
            throw new ServiceException("该容器存在多条任务");
        }
        if (receiptContainerHeaderList.get(0).getWarehouseCode() != ShiroUtils.getWarehouseCode()) {
            throw new ServiceException("容器不在当前仓库!");
        }
        LambdaQueryWrapper<ReceiptContainerDetail> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(ReceiptContainerDetail::getReceiptContainerId, receiptContainerHeaderList.get(0).getId());
        List<ReceiptContainerDetail> containerDetailList = receiptContainerDetailService.list(lambdaQueryWrapper);
        ReceiptContainerHeader containerHeader = receiptContainerHeaderList.get(0);
        if (containerDetailList.isEmpty()){
            throw new ServiceException("没有组盘明细,请先组盘!");
        }
        if (containerHeader.getStatus().equals(QuantityConstant.TASK_STATUS_BUILD)) {
            if (containerHeader.getStatus().intValue() != taskStatus.intValue()) {
                containerHeader.setStatus(taskStatus);
                receiptContainerHeaderService.updateById(containerHeader);
            }
        }
        List<Integer> ids = new ArrayList<>();
        ids.add(containerHeader.getId());
        this.createReceiptTask(ids);
        return AjaxResult.success("成功!");
    }

    /**
     * 移动端根据容器编码获取盘点任务
     * @param containerCode 容器编码
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<MobileTask> mobileFindTransferTask(String containerCode) {
        /* 查询该容器未完成的盘点任务明细*/
        LambdaQueryWrapper<TaskDetail> detailLambdaQueryWrapper = Wrappers.lambdaQuery();
        detailLambdaQueryWrapper.eq(TaskDetail::getContainerCode, containerCode)
                .eq(TaskDetail::getTaskType, QuantityConstant.TASK_TYPE_CYCLECOUNT)
                .ne(TaskDetail::getStatus, QuantityConstant.TASK_STATUS_COMPLETED);
        List<TaskDetail> taskDetailList = taskDetailService.list(detailLambdaQueryWrapper);

        /* 获取任务明细中的任务头id*/
        List<Integer> headerIdList = taskDetailList.stream().map(TaskDetail::getTaskId).collect(Collectors.toList());
        List<MobileTask> mobileTasks = new ArrayList<>();

        /* 遍历id查询出盘点任务*/
        for (Integer id : headerIdList) {
            TaskHeader taskHeader = taskHeaderService.getById(id);
            MobileTask mobileTask = new MobileTask();
            mobileTask.setTaskHeader(taskHeader);
            LambdaQueryWrapper<TaskDetail> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.eq(TaskDetail::getTaskId, id)
                    .eq(TaskDetail::getContainerCode, containerCode);
            List<TaskDetail> taskDetails = taskDetailService.list(queryWrapper);
            mobileTask.setTaskDetail(taskDetails);
            mobileTasks.add(mobileTask);
        }
        return mobileTasks;
    }

    /**
     * 查询容器有无任务
     */
    @Override
    public Integer UncompleteCount(String ContainerCode) {
        return taskHeaderMapper.UncompleteCount(ContainerCode, ShiroUtils.getWarehouseCode());
    }

    /**
     * 取消任务
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult cancelTask(Integer[] taskIds) {
        for (int taskId : taskIds) {
            TaskHeader taskHeader = taskHeaderService.getById(taskId);
            if (taskHeader == null) {
                return AjaxResult.error("任务" + taskId + "未找到,操作中止");
            }
            if (taskHeader.getStatus() >= QuantityConstant.TASK_STATUS_RELEASE) {
                return AjaxResult.error("存在任务" + taskHeader.getId() + "已下发或执行,操作中止");
            }
            //查出任务明细
            TaskDetail taskDetail1 = new TaskDetail();
            taskDetail1.setTaskId(taskHeader.getId());
            taskDetail1.setWarehouseCode(taskHeader.getWarehouseCode());
            taskDetail1.setCompanyCode(taskHeader.getCompanyCode());
            LambdaQueryWrapper<TaskDetail> td = Wrappers.lambdaQuery(taskDetail1);
            List<TaskDetail> taskDetailList = taskDetailService.list(td);
            TaskDetail taskDetail = taskDetailList.get(0);
            if (taskDetail == null) {
                throw new ServiceException("任务明细条目错误");
            }
            //删除子任务
            LambdaQueryWrapper<TaskDetail> lambdaQueryWrapper = Wrappers.lambdaQuery();
            lambdaQueryWrapper.eq(TaskDetail::getTaskId, taskHeader.getId());
            taskDetailService.remove(lambdaQueryWrapper);
            //删除主任务
            taskHeaderService.removeById(taskHeader.getId());
            // 更改库位状态(整盘入库任务除外)
            if (taskHeader.getInternalTaskType().equals(QuantityConstant.TASK_INTENERTYPE_SHELF)) {
                receiptContainerHeaderService.cancelReceipt(taskHeader.getAllocationHeadId());
            }
            //根据任务类型来更新货箱状态
            //修改关联的货箱状态
            if (taskHeader.getInternalTaskType().equals(QuantityConstant.TASK_INTENERTYPE_PICKING)) {
                ShipmentContainerHeader shipmentContainerHeader = new ShipmentContainerHeader();
                shipmentContainerHeader.setId(taskHeader.getAllocationHeadId());
                shipmentContainerHeader.setStatus(QuantityConstant.SHIPMENT_CONTAINER_BUILD);
                shipmentContainerHeaderService.updateById(shipmentContainerHeader);
            }
            //盘点取消任务,恢复明细状态为1
            if (taskHeader.getInternalTaskType().equals(QuantityConstant.TASK_INTENERTYPE_CYCLECOUNT)) {

                CycleCountDetail cycleCountDetail = new CycleCountDetail();
                cycleCountDetail.setCompanyCode(taskDetail.getCompanyCode());
                cycleCountDetail.setWarehouseCode(taskDetail.getWarehouseCode());
                cycleCountDetail.setLocationCode(taskDetail.getFromLocation());
                cycleCountDetail.setContainerCode(taskDetail.getContainerCode());
                cycleCountDetail.setCycleCountHeadCode(taskDetail.getBillCode());//盘点单Code
                cycleCountDetail.setId(taskDetail.getBillDetailId());//盘点细单ID
                LambdaQueryWrapper<CycleCountDetail> lam = Wrappers.lambdaQuery(cycleCountDetail);
                List<CycleCountDetail> cycleCountDetailList = cycleCountDetailService.list(lam);//
                for (CycleCountDetail item : cycleCountDetailList) {
                    item.setTaskHeaderId(null);
                    item.setTaskHeaderId(null);
                    item.setLastUpdated(new Date());
                    item.setLastUpdatedBy(ShiroUtils.getLoginName());
                    item.setEnableStatus(1);
                    cycleCountDetailService.saveOrUpdate(item);
                }

            }
            if (taskHeader.getInternalTaskType().equals(QuantityConstant.TASK_INTENERTYPE_SHELF) || taskHeader.getInternalTaskType().equals(QuantityConstant.TASK_INTENERTYPE_PICKING)) {
                if (taskHeader.getToLocation() != null) {
                    //更新托盘、库位状态
                    locationService.updateStatus(taskHeader.getToLocation(), "empty");
                }
                Container container = new Container();
                container.setStatus("empty");
                LambdaUpdateWrapper<Container> containerUpdateWrapper = Wrappers.lambdaUpdate();
                containerUpdateWrapper.eq(Container::getCode, taskHeader.getContainerCode());
                containerService.update(container, containerUpdateWrapper);
            }
//            if(task.getType()==900){
//                //出库查看任务没有关联的货箱,不做处理
//            }
        }

        return AjaxResult.success("取消任务成功!");
    }

    /**
     * 创建空托入库
     *
     * @param containerCode       容器编码
     * @param destinationLocation 目的库位
     * @param companyCode         货主编码
     * @return
     */
    @Override
    public AjaxResult createEmptyIn(String containerCode, String destinationLocation, String companyCode) {
        return inventoryHeaderService.createEmptyIn(containerCode, destinationLocation);
    }

    /**
     * 容器收货上架
     *
     * @param containerCode
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult createQuickTask(String containerCode) {
        LambdaQueryWrapper<ReceiptContainerHeader> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(ReceiptContainerHeader::getContainerCode, containerCode)
                .eq(ReceiptContainerHeader::getStatus, QuantityConstant.RECEIPT_CONTAINER_BUILD)
                .eq(ReceiptContainerHeader::getWarehouseCode, ShiroUtils.getWarehouseCode());
        ReceiptContainerHeader receiptContainerHeader = receiptContainerHeaderService.getOne(queryWrapper);
        if (receiptContainerHeader == null) {
            throw new ServiceException("该容器没有任务!");
        }

        LambdaQueryWrapper<ReceiptContainerDetail> containerDetailQueryWrapper = Wrappers.lambdaQuery();
        containerDetailQueryWrapper.eq(ReceiptContainerDetail::getReceiptContainerId, receiptContainerHeader.getId())
                .eq(ReceiptContainerDetail::getStatus, QuantityConstant.RECEIPT_CONTAINER_BUILD)
                .eq(ReceiptContainerDetail::getContainerCode, containerCode);
        List<ReceiptContainerDetail> containerDetailList = receiptContainerDetailService.list(containerDetailQueryWrapper);
        if (containerDetailList.isEmpty()) {
            throw new SecurityException("没有组盘明细,请先组盘");
        }
        if (receiptContainerHeader.getStatus() == QuantityConstant.RECEIPT_HEADER_BUILD.shortValue()) {
            String ids = String.valueOf(receiptContainerHeader.getId());
            if (StringUtils.isEmpty(ids)){
                return AjaxResult.error("id不能为空");
            }
            List<Integer> idList = Arrays.asList(Convert.toIntArray(ids));
//            for (int i = 0; i<idList.size(); i++){
//                LambdaQueryWrapper<ReceiptContainerDetail> lambda = Wrappers.lambdaQuery();
//                lambda.eq(ReceiptContainerDetail::getReceiptContainerId, idList.get(i));
//                List<ReceiptContainerDetail> receiptContainerDetails = receiptContainerDetailService.list(lambda);
//                for (ReceiptContainerDetail receiptContainerDetail : receiptContainerDetails){
//                    receivingService.position(receiptContainerDetail);
//                }
//
//            }
            if (StringUtils.isEmpty(ids)){
                return AjaxResult.error("id不能为空");
            }
//            for (int i = 0; i<idList.size(); i++){
//                LambdaQueryWrapper<ReceiptContainerDetail> lambda = Wrappers.lambdaQuery();
//                lambda.eq(ReceiptContainerDetail::getReceiptContainerId, idList.get(i));
//                List<ReceiptContainerDetail> receiptContainerDetails = receiptContainerDetailService.list(lambda);
//                for (ReceiptContainerDetail receiptContainerDetail : receiptContainerDetails){
//                    receivingService.position(receiptContainerDetail);
//                }
//
//            }

            Integer maxId = idList.stream().max(Comparator.comparing(Integer::intValue)).orElse(null);

            LambdaQueryWrapper<ReceiptContainerHeader> lambda = Wrappers.lambdaQuery();
            lambda.select(ReceiptContainerHeader::getId)
                    .lt(ReceiptContainerHeader::getStatus, 10)
                    .le(ReceiptContainerHeader::getId, maxId);
            return taskHeaderService.createReceiptTask(idList);
        }
        return AjaxResult.error("生成入库任务失败");
    }

    /**
     * 生成出库任务
     *
     * @param shipmentTaskCreateModel
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult createTaskFromShipmentContainers(ShipmentTaskCreateModel shipmentTaskCreateModel) {
        Boolean flag = true;
        Integer shipmentContainerHeaderId = shipmentTaskCreateModel.getShipmentContainerHeaderIds();
        //获取表头
        ShipmentContainerHeader shipmentContainerHeader = shipmentContainerHeaderService.getById(shipmentContainerHeaderId);
        if (shipmentContainerHeader == null) {
            return AjaxResult.error("出库货箱" + shipmentContainerHeaderId + "未找到,操作中止");
        }
        if (shipmentContainerHeader.getStatus() >= QuantityConstant.SHIPMENT_CONTAINER_TASK) {
            return AjaxResult.error("出库货箱" + shipmentContainerHeader.getContainerCode() + "已经生成任务,请不要重复生成,操作中止");
        }
        //获取所有子货箱
        LambdaQueryWrapper<ShipmentContainerDetail> lambdaQueryWrapper = Wrappers.lambdaQuery();
        lambdaQueryWrapper.eq(ShipmentContainerDetail::getShippingContainerId, shipmentContainerHeader.getId());
        List<ShipmentContainerDetail> shipmentContainerDetails = shipmentContainerDetailService.list(lambdaQueryWrapper);
        if (shipmentContainerDetails == null || shipmentContainerDetails.size() == 0) {
            return AjaxResult.error("货箱" + shipmentContainerHeader.getContainerCode() + "没有子任务,操作中止");
        }
        //检测库位
        LambdaQueryWrapper<Location> locationLambdaQueryWrapper = Wrappers.lambdaQuery();
        locationLambdaQueryWrapper.eq(Location::getCode, shipmentContainerHeader.getLocationCode())
                .eq(Location::getWarehouseCode, ShiroUtils.getWarehouseCode())
                .eq(Location::getDeleted, false);
        Location location = locationService.getOne(locationLambdaQueryWrapper);
        if (location == null) {
            return AjaxResult.error("库位禁用或不存在!");
        }
        //创建任务头
        TaskHeader task = new TaskHeader();
        //分拣出库
        task.setTaskType(QuantityConstant.TASK_TYPE_SORTINGSHIPMENT);
        task.setFromLocation(shipmentContainerHeader.getLocationCode());
        task.setToLocation(shipmentContainerHeader.getLocationCode());
        //判断是否整出任务,钱柜和AGV不能整出

        //表示整出优先
        //判断当前子货箱所有数量是否等于该托盘对应的所有库存的数量,
        //这里必须与库存的在库数量对比,后期可能存在一个配盘在执行任务,后一个配盘又在配这个的情况(这个时候不能整出)
        // 如果相等,则说明这个货箱包含了所有的数量,则可以整出,否则,创建拣选任务;
        //查询所有库存
        LambdaQueryWrapper<InventoryDetail> inventoryDetailLambdaQueryWrapper = Wrappers.lambdaQuery();
        inventoryDetailLambdaQueryWrapper.eq(InventoryDetail::getLocationCode, shipmentContainerHeader.getLocationCode())
                .eq(InventoryDetail::getWarehouseCode, ShiroUtils.getWarehouseCode());
        List<InventoryDetail> inventories = inventoryDetailService.list(inventoryDetailLambdaQueryWrapper);
        BigDecimal inventoryTotal = new BigDecimal("0");
        for (InventoryDetail item : inventories) {
            inventoryTotal = inventoryTotal.add(item.getQty());
        }
        BigDecimal containerTotal = new BigDecimal("0");
        for (ShipmentContainerDetail item : shipmentContainerDetails) {
            containerTotal = containerTotal.add(item.getQty());
        }
        if (inventoryTotal.compareTo(containerTotal) == 0) {
            task.setTaskType(QuantityConstant.TASK_TYPE_WHOLESHIPMENT);//整盘出库
            task.setToLocation("");
        }

        task.setInternalTaskType(QuantityConstant.TASK_INTENERTYPE_PICKING);
        task.setAllocationHeadId(shipmentContainerHeader.getId());
        task.setWarehouseCode(shipmentContainerHeader.getWarehouseCode());
        task.setCompanyCode(shipmentContainerHeader.getCompanyCode());
        task.setAssignedUser(ShiroUtils.getLoginName());
        task.setConfirmedBy(ShiroUtils.getLoginName());
        task.setStatus(QuantityConstant.TASK_STATUS_BUILD);
        task.setContainerCode(shipmentContainerHeader.getContainerCode());
        task.setCreatedBy(ShiroUtils.getLoginName());
        task.setCreated(new Date());
        task.setLastUpdatedBy(ShiroUtils.getLoginName());
        task.setLastUpdated(null);
        this.save(task);
        //遍历子货箱创建子任务
        for (ShipmentContainerDetail shipmentContainerDetail : shipmentContainerDetails) {
            TaskDetail taskDetail = new TaskDetail();
            taskDetail.setTaskId(task.getId());
            taskDetail.setInternalTaskType(task.getInternalTaskType());
            taskDetail.setWarehouseCode(task.getWarehouseCode());
            taskDetail.setCompanyCode(task.getCompanyCode());
            taskDetail.setTaskType(task.getTaskType());
            taskDetail.setToInventoryId(shipmentContainerDetail.getInventoryId());
            taskDetail.setAllocationId(shipmentContainerDetail.getId());
            taskDetail.setBillCode(shipmentContainerDetail.getShipmentCode());
            taskDetail.setBillDetailId(shipmentContainerDetail.getShipmentDetailId());
            taskDetail.setMaterialCode(shipmentContainerDetail.getMaterialCode());
            taskDetail.setMaterialName(shipmentContainerDetail.getMaterialName());
            taskDetail.setMaterialSpec(shipmentContainerDetail.getMaterialSpec());
            taskDetail.setMaterialUnit(shipmentContainerDetail.getMaterialUnit());
            taskDetail.setFromInventoryId(shipmentContainerDetail.getInventoryId());
            taskDetail.setQty(shipmentContainerDetail.getQty());
            taskDetail.setContainerCode(task.getContainerCode());
            taskDetail.setFromLocation(task.getFromLocation());
            taskDetail.setToLocation(task.getToLocation());
            taskDetail.setLot(shipmentContainerDetail.getLot());
            taskDetail.setBatch(shipmentContainerDetail.getBatch());
            taskDetail.setProjectNo(shipmentContainerDetail.getProjectNo());
            taskDetail.setStatus(QuantityConstant.TASK_STATUS_BUILD);
            taskDetail.setWaveId(shipmentContainerDetail.getWaveId());
            taskDetail.setInventorySts(shipmentContainerDetail.getInventorySts());
            taskDetail.setCreatedBy(ShiroUtils.getLoginName());
            taskDetail.setLastUpdatedBy(ShiroUtils.getLoginName());
            flag = taskDetailService.save(taskDetail);
            if (flag == false) {
                throw new ServiceException("新建任务明细失败,sql报错");
            }
            shipmentContainerDetail.setStatus(QuantityConstant.SHIPMENT_CONTAINER_TASK);
        }
        //更新货位状态
        shipmentContainerHeader.setStatus(QuantityConstant.SHIPMENT_CONTAINER_TASK);
        flag = shipmentContainerHeaderService.updateById(shipmentContainerHeader);
        if (flag == false) {
            throw new ServiceException("修改组盘头状态失败,sql报错");
        }

        flag = shipmentContainerDetailService.updateBatchById(shipmentContainerDetails);
        if (flag == false) {
            throw new ServiceException("修改组盘明细状态明细失败,sql报错");
        }
        return AjaxResult.success(task.getId());
    }

    /**
     * 下发WCS执行任务
     * 执行任务
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult<TaskHeader> sendTaskToWcs(Integer[] taskIds) {
        TaskHeader task = null;
        for (Integer taskId : taskIds) {
            task = taskHeaderService.getById(taskId);

            if (task.getStatus() >= QuantityConstant.TASK_STATUS_RELEASE) {
                return AjaxResult.error("任务" + taskId + "已经下发,请不要重复下发,操作中止");
            }
            // 给wcs传递任务
            try {
                createTaskMessage.createTask(task);
            } catch (Exception e) {
                e.printStackTrace();
            }

            //修改任务头表
            task.setId(taskId);
            task.setStatus(QuantityConstant.TASK_STATUS_RELEASE);
            task.setStartPickDateTime(new Date());   //生成时间
            task.setLastUpdated(new Date());
            task.setLastUpdatedBy(ShiroUtils.getLoginName());
            taskHeaderService.saveOrUpdate(task);
            //修改任务明细状态
            LambdaQueryWrapper<TaskDetail> lambdaWrapper = Wrappers.lambdaQuery();
            lambdaWrapper.eq(TaskDetail::getTaskId, task.getId());
            List<TaskDetail> taskDetailList = taskDetailService.list(lambdaWrapper);
            List<TaskDetail> taskDetails = new ArrayList<>();
            for (TaskDetail item : taskDetailList) {
                item.setStatus(QuantityConstant.TASK_STATUS_RELEASE);
                item.setLastUpdated(new Date());
                item.setLastUpdatedBy(ShiroUtils.getLoginName());
                item.setProcessStamp("100");
                taskDetails.add(item);
                //盘点执行修改盘点单据状态为10
                if (task.getTaskType().equals(QuantityConstant.TASK_TYPE_CYCLECOUNT)) {
                    cycleCountDetailService.updataDetailStatus(item.getBillDetailId(), QuantityConstant.CYCLECOUNT_STATUS_EXECUTING);
                }
            }
            if(taskDetails != null && taskDetails.size() > 0) {
                if (!taskDetailService.saveOrUpdateBatch(taskDetails)) {
                    throw new ServiceException("更新任务明细失败");
                }
            }

//            //修改入库明细
//            if (task.getInternalTaskType()==100){
//                ReceiptDetail receiptDetail = receiptDetailService.queryflow(receiptDetailService.getById(record.getId()));
//                if (!receiptDetailService.updateById(receiptDetail)){
//                    throw new ServiceException("更新状态失败");
//                }
//                receiptDetailService.updateReceiptHeaderLastStatus(receiptDetail.getReceiptId());
//
//                //修改组盘表状态为20
//                ReceiptContainerDetail receiptContainerDetail = new ReceiptContainerDetail();
//                receiptContainerDetail.setStatus(20);
//                receiptContainerDetail.setLastUpdated(new Date());
//                receiptContainerDetail.setLastUpdatedBy(ShiroUtils.getLoginName());
//                LambdaUpdateWrapper<ReceiptContainerDetail> receiptContainerDetailLambdaUpdateWrapper = Wrappers.lambdaUpdate();
//                receiptContainerDetailLambdaUpdateWrapper.eq(ReceiptContainerDetail::getReceiptId,receiptDetail.getReceiptId());
//                if (! receiptContainerDetailService.update(receiptContainerDetail, receiptContainerDetailLambdaUpdateWrapper))
//                    throw new ServiceException("更新组盘状态失败");
//            }
//
//            //修改出库单状态
//            if (task.getInternalTaskType()==200){
//                LambdaQueryWrapper<TaskDetail> taskDetailLambdaQueryWrapper = Wrappers.lambdaQuery();
//                taskDetailLambdaQueryWrapper.eq(TaskDetail::getTaskId,task.getId());
//               List<TaskDetail> taskDetailList = taskDetailService.list(taskDetailLambdaQueryWrapper);
//
//                for (TaskDetail taskDeatails: taskDetailList) {
//                    LambdaQueryWrapper<ShipmentDetail> shipmentDetailLambdaQueryWrapper = Wrappers.lambdaQuery();
//                    shipmentDetailLambdaQueryWrapper.eq(ShipmentDetail::getId,taskDeatails.getBillDetailId());
//
//                    ShipmentHeader shipmentHeader =new ShipmentHeader();
//                    shipmentHeader.setId(shipmentDetailService.getOne(shipmentDetailLambdaQueryWrapper).getShipmentId());
//                    shipmentHeader.setFirstStatus(100);
//                    shipmentHeader.setLastStatus(100);
//                    shipmentHeader.setLastUpdatedBy(ShiroUtils.getLoginName());
//                    shipmentHeader.setLastUpdated(new Date());
//                    shipmentHeaderService.updateById(shipmentHeader);
//                }
//            }

        }
        return AjaxResult.success("执行下发任务成功", task);
    }

    @Override
    public AjaxResult completeTaskByWMS(Integer[] taskIds, String[] weightConvert) {
        for (int i = 0;i<taskIds.length;i++) {
            TaskHeader task = taskHeaderService.getById(taskIds[i]);

            if (task == null) {
                throw new ServiceException("任务" + taskIds[i] + "未找到,执行中止");
            }
            //任务写入重量
            String weight = "";
            if (StringUtils.isNotNull(weightConvert)) {
                weight = weightConvert[i];
            }
            task.setWeight(weight);
            //如果已完成则不管
            if (task.getStatus().equals(QuantityConstant.TASK_STATUS_COMPLETED)) {
                return AjaxResult.success("任务(" + taskIds[i] + ")任务已经是完成的!");

            }
            //整盘入库,空托入库库位自动分配
            //整盘入库手动完成分配库位,已分配则略过
            if(task.getTaskType().equals(QuantityConstant.TASK_TYPE_WHOLERECEIPT) || task.getTaskType().equals(QuantityConstant.TASK_TYPE_EMPTYRECEIPT)){
                if(StringUtils.isEmpty(task.getToLocation())){
                    //自动分配库位
                   AjaxResult ajaxResult = this.setLocationCode(task.getId(),0 );
                   task.setToLocation((String)ajaxResult.getData());
                }
            }
            //如果没有库位不能完成
            if (StringUtils.isEmpty(task.getFromLocation()) && StringUtils.isEmpty(task.getToLocation())) {
                throw new ServiceException("任务" + task.getId() + "没有库位,执行中止");
            }

            this.completeTask(task);
        }
        return AjaxResult.success("完成任务成功!");
    }

    /**
     * 完成任务
     *
     * @param task
     */
    public void completeTask(TaskHeader task) {
        //区分任务类型
        if (task.getInternalTaskType().equals(QuantityConstant.TASK_INTENERTYPE_SHELF) ) {
            //入库任务
            this.completeReceiptTask(task);
            combineInventory(task);
        }
        if (task.getInternalTaskType().equals(QuantityConstant.TASK_INTENERTYPE_PICKING) &&
                (task.getTaskType().equals(QuantityConstant.TASK_TYPE_WHOLESHIPMENT) || task.getTaskType().equals(QuantityConstant.TASK_TYPE_SORTINGSHIPMENT))) {
            //出库任务
            this.completeShipmentTask(task);
        }
        // 900 出库查看,空托出库查看
        if (task.getTaskType().equals( QuantityConstant.TASK_TYPE_VIEW)) {
            this.completeSeeOutTask(task);
        }
        // 700 盘点
        if (task.getTaskType().equals(QuantityConstant.TASK_TYPE_CYCLECOUNT)) {
            this.completeCycleCountTask(task);
        }
        if (task.getTaskType().equals( QuantityConstant.TASK_TYPE_TRANSFER)) {
//          //移库
            this.completeTransferTask(task);
        }
        if (task.getTaskType().equals( QuantityConstant.TASK_TYPE_EMPTYRECEIPT)) {
            //空托盘入库
            this.completeEmptyIn(task);
        }
        if (task.getTaskType().equals(QuantityConstant.TASK_TYPE_EMPTYSHIPMENT) ) {
            //空托盘出库
            this.completeEmptyOut(task);
        }
    }


    /**
     * 完成入库任务
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult completeReceiptTask(TaskHeader task) {
        List<Map<String, Object>> taskReceiptContainerDetail = taskHeaderMapper.getReceiptTask(task.getId());
        if (taskReceiptContainerDetail.size() < 1) {
            return AjaxResult.success("未找到对应任务的入库单号!!!");
        }
        LambdaQueryWrapper<InventoryHeader> inventoryHeaderErapper = Wrappers.lambdaQuery();
        inventoryHeaderErapper.eq(InventoryHeader::getWarehouseCode, ShiroUtils.getWarehouseCode())
                .eq(InventoryHeader::getLocationCode, task.getToLocation())
                .eq(InventoryHeader::getContainerCode, task.getContainerCode());
        InventoryHeader header = inventoryHeaderService.getOne(inventoryHeaderErapper);

        if(header == null) {
            //添加库存单
            header = new InventoryHeader();
            header.setWarehouseCode(task.getWarehouseCode());
            header.setCompanyCode(task.getCompanyCode());//货主
            header.setContainerCode(task.getContainerCode());
            header.setContainerStatus("some");
            header.setLocationCode(task.getToLocation());
            header.setLocking(1);
            header.setEnable(1);
            header.setTotalQty(new BigDecimal(0));
            header.setTotalWeight(task.getWeight());
            header.setCreatedBy(ShiroUtils.getLoginName());
            header.setCreated(new Date());
            header.setLastUpdatedBy(ShiroUtils.getLoginName());
            header.setLastUpdated(new Date());
            if (!inventoryHeaderService.save(header)) {
                throw new ServiceException("添加库存单失败");
            }
        }
        for (Map<String, Object> map : taskReceiptContainerDetail) {
            //将未完成的任务数量更新到库存表
            if (DataUtils.getInteger(map.get("status")) < QuantityConstant.TASK_STATUS_COMPLETED) {

                LambdaQueryWrapper<InventoryDetail> inventory = Wrappers.lambdaQuery();
                inventory.eq(InventoryDetail::getWarehouseCode, ShiroUtils.getWarehouseCode())
                        .eq(InventoryDetail::getLocationCode, task.getToLocation())
                        .eq(InventoryDetail::getMaterialCode, DataUtils.getString(map.get("materialCode")))
                        .eq(InventoryDetail::getContainerCode, DataUtils.getString(map.get("containerCode")))
                        .eq(InventoryDetail::getContainerCode, DataUtils.getString(map.get("batch")));
                InventoryDetail detail = inventoryDetailService.getOne(inventory);
                if (detail == null) {
                    //库存明细添加
                    detail = new InventoryDetail();
                    detail.setInventoryHeaderId(header.getId());//库存头ID
                    detail.setWarehouseCode(DataUtils.getString(map.get("warehouseCode")));//仓库
                    detail.setCompanyCode(task.getCompanyCode());//货主
                    detail.setLocationCode(task.getToLocation());//库位号
                    detail.setContainerCode(DataUtils.getString(map.get("containerCode")));//容器号
                    detail.setMaterialCode(DataUtils.getString(map.get("materialCode")));//物料号
                    detail.setMaterialName(DataUtils.getString(map.get("materialName")));//物料名称
                    detail.setMaterialSpec(DataUtils.getString(map.get("materialSpec")));//物料规格
                    detail.setMaterialUnit(DataUtils.getString(map.get("materialUnit")));//物料单位
                    detail.setReceiptCode(DataUtils.getString(map.get("receiptCode")));//入库单编码
                    detail.setReceiptDetailId(DataUtils.getInteger(map.get("receiptDetailId")));//入库单明细ID
                    detail.setBatch(DataUtils.getString(map.get("batch")));//批次
                    detail.setLot(DataUtils.getString(map.get("lot")));//批号
                    detail.setInventorySts(DataUtils.getString(map.get("inventorySts")));//库存状态
//                    detail.setManufactureDate(new SimpleDateFormat("yyyy-MM-dd").parse(map.get("manufactureDate").toString()));//生产日期
//                    detail.setExpirationDate(new SimpleDateFormat("yyyy-MM-dd").parse(map.get("expirationDate").toString()));//失效日期
                    detail.setQty(DataUtils.getBigDecimal(map.get("qty")));//数量
                    detail.setLockedQty(DataUtils.getBigDecimal(0));
                    detail.setTaskQty(DataUtils.getBigDecimal(0));
                    detail.setCreatedBy(ShiroUtils.getLoginName());//创建人
                    detail.setLastUpdatedBy(ShiroUtils.getLoginName());//创建时间
                    if (!inventoryDetailService.save(detail)) {
                        throw new ServiceException("添加库存明细失败");
                    }
                } else {
                    detail.setQty(detail.getQty().add(DataUtils.getBigDecimal(map.get("qty"))));
                    detail.setLastUpdatedBy(ShiroUtils.getLoginName());
                    LambdaUpdateWrapper<InventoryDetail> lambdaUpdateWrapper = Wrappers.lambdaUpdate();
                    lambdaUpdateWrapper.eq(InventoryDetail::getId, detail.getId());
                    if (!inventoryDetailService.update(detail, lambdaUpdateWrapper)){
                        throw new ServiceException("更新库存明细失败");
                    }
                }
                //记录库存交易记录
                InventoryTransaction inventoryTransaction = new InventoryTransaction();
                inventoryTransaction.setTransactionType(QuantityConstant.INVENTORY_TRANSACTION_RECEIPT);
                inventoryTransaction.setWarehouseCode(DataUtils.getString(map.get("warehouseCode")));
                inventoryTransaction.setCompanyCode(task.getCompanyCode());
                inventoryTransaction.setLocationCode(task.getToLocation());
                inventoryTransaction.setContainerCode(DataUtils.getString(map.get("containerCode")));
                inventoryTransaction.setMaterialCode(DataUtils.getString(map.get("materialCode")));
                inventoryTransaction.setMaterialName(DataUtils.getString(map.get("materialName")));
                inventoryTransaction.setMaterialSpec(DataUtils.getString(map.get("materialSpec")));//物料规格
                inventoryTransaction.setMaterialUnit(DataUtils.getString(map.get("materialUnit")));//物料单位
                inventoryTransaction.setBillCode(DataUtils.getString(map.get("receiptCode")));
                inventoryTransaction.setBillDetailId(DataUtils.getInteger(map.get("receiptDetailId")));
                inventoryTransaction.setBatch(DataUtils.getString(map.get("batch")));
                inventoryTransaction.setLot(DataUtils.getString(map.get("lot")));
                inventoryTransaction.setInventorySts(DataUtils.getString((map.get("inventorySts"))));
                inventoryTransaction.setTaskQty(DataUtils.getBigDecimal(map.get("qty")));
                inventoryTransaction.setCreated(new Date());
                inventoryTransaction.setCreatedBy(ShiroUtils.getLoginName());
                if (!inventoryTransactionService.save(inventoryTransaction)) {
                    throw new ServiceException("新增库存记录失败");
                }

                //修改任务明细的状态为完成
                TaskDetail taskDetail = new TaskDetail();
                taskDetail.setStatus(QuantityConstant.TASK_STATUS_COMPLETED);
                taskDetail.setLastUpdatedBy(ShiroUtils.getLoginName());
                taskDetail.setAgingDate(new Date());   //入库时间
                LambdaUpdateWrapper<TaskDetail> lambdaUpdateWrapper = Wrappers.lambdaUpdate();
                lambdaUpdateWrapper.eq(TaskDetail::getTaskId, task.getId());
                taskDetailService.update(taskDetail, lambdaUpdateWrapper);
                if (!taskDetailService.update(taskDetail, lambdaUpdateWrapper)) {
                    throw new ServiceException("修改入库单明细失败");
                }

            }

        }
        //修改任务主表状态,因为立库任务表单头只对应一个货箱,表单详情的任务会同时完成
        task.setStatus(QuantityConstant.TASK_STATUS_COMPLETED);
        task.setLastUpdatedBy(ShiroUtils.getLoginName());
        task.setLastUpdated(new Date());
        LambdaUpdateWrapper<TaskHeader> taskHeaderLambdaUpdateWrapper = Wrappers.lambdaUpdate();
        taskHeaderLambdaUpdateWrapper.eq(TaskHeader::getId, task.getId());
        if (!taskHeaderService.update(task, taskHeaderLambdaUpdateWrapper)){
            throw new ServiceException("更新任务主表失败");
        }
        //修改库位状态和对应的容器
        Location location = new Location();
        location.setContainerCode(task.getContainerCode());
        location.setStatus("empty");
        LambdaUpdateWrapper<Location> locationLambdaUpdateWrapper = Wrappers.lambdaUpdate();
        locationLambdaUpdateWrapper.eq(Location::getCode, task.getToLocation());
        if (!locationService.update(location, locationLambdaUpdateWrapper)){
            throw new ServiceException("更新库位失败");
        }
        //修改容器状态和对应的库位
        Container container = new Container();
        container.setLocationCode(task.getToLocation());
        container.setStatus("some");
        LambdaUpdateWrapper<Container> containerLambdaUpdateWrapper = Wrappers.lambdaUpdate();
        containerLambdaUpdateWrapper.eq(Container::getCode, task.getContainerCode());
        if (!containerService.update(container, containerLambdaUpdateWrapper)) {
            throw new ServiceException("更新容器失败");
        }
        //修改组盘表状态为20
        ReceiptContainerDetail receiptContainerDetail = new ReceiptContainerDetail();
        receiptContainerDetail.setStatus(QuantityConstant.RECEIPT_CONTAINER_REVIEWSUCCESS);
        receiptContainerDetail.setProcessStamp("0");
        receiptContainerDetail.setLastUpdated(new Date());
        receiptContainerDetail.setLastUpdatedBy(ShiroUtils.getLoginName());
        LambdaUpdateWrapper<ReceiptContainerDetail> receiptContainerDetailLambdaUpdateWrapper = Wrappers.lambdaUpdate();
        receiptContainerDetailLambdaUpdateWrapper.eq(ReceiptContainerDetail::getReceiptId, DataUtils.getInteger(taskReceiptContainerDetail.get(0).get("receiptId")));
        if (!receiptContainerDetailService.update(receiptContainerDetail, receiptContainerDetailLambdaUpdateWrapper)){
            throw new ServiceException("更新组盘状态失败");
        }

        //修改入库组盘头表状态

        ReceiptContainerHeader receiptContainerHeader = new ReceiptContainerHeader();
        receiptContainerHeader.setId(task.getAllocationHeadId());
        receiptContainerHeader.setLastUpdated(new Date());
        receiptContainerHeader.setLastUpdatedBy(ShiroUtils.getLoginName());
        receiptContainerHeader.setStatus((short) QuantityConstant.RECEIPT_CONTAINER_FINISHED.intValue());
        if (!receiptContainerHeaderService.updateById(receiptContainerHeader)) {
            throw new ServiceException("更新入库组盘头表状态失败");
        }

        //修改入库单状态
        ReceiptHeader receiptHeader = new ReceiptHeader();
        receiptHeader.setFirstStatus(QuantityConstant.RECEIPT_HEADER_POSTING);
        receiptHeader.setLastStatus(QuantityConstant.RECEIPT_HEADER_POSTING);
        receiptHeader.setLastUpdatedBy(ShiroUtils.getLoginName());
        receiptHeader.setLastUpdated(new Date());
        LambdaUpdateWrapper<ReceiptHeader> receiptHeaderLambdaUpdateWrapper = Wrappers.lambdaUpdate();
        receiptHeaderLambdaUpdateWrapper.eq(ReceiptHeader::getId, DataUtils.getInteger(taskReceiptContainerDetail.get(0).get("receiptId")));
        if (!receiptHeaderService.update(receiptHeader, receiptHeaderLambdaUpdateWrapper)) {
            throw new ServiceException("更新入库头表状态失败");
        }
        return AjaxResult.success("完成入库任务");
    }

    @Transactional(rollbackFor = Exception.class)
    public void combineInventory(TaskHeader task) {
        LambdaQueryWrapper<InventoryHeader> inventoryHeaderErapper = Wrappers.lambdaQuery();
        inventoryHeaderErapper.eq(InventoryHeader::getWarehouseCode, ShiroUtils.getWarehouseCode())
                .eq(InventoryHeader::getLocationCode, task.getToLocation())
                .eq(InventoryHeader::getContainerCode, task.getContainerCode());
        InventoryHeader header = inventoryHeaderService.getOne(inventoryHeaderErapper);
        if(header != null) {
            LambdaQueryWrapper<InventoryDetail> inventory = Wrappers.lambdaQuery();
            inventory.eq(InventoryDetail::getWarehouseCode, ShiroUtils.getWarehouseCode())
                    .eq(InventoryDetail::getLocationCode, task.getFromLocation())
                    .eq(InventoryDetail::getContainerCode, task.getContainerCode());
            List<InventoryDetail> inventoryDetailList = inventoryDetailService.list(inventory);
            for(int i=0; i < inventoryDetailList.size() -1; i++) {
                for(int j = inventoryDetailList.size() - 1; j > i; j--) {
                    if(inventoryDetailList.get(i).getMaterialCode().equals(inventoryDetailList.get(j).getMaterialCode())) {
                        BigDecimal totalQty = inventoryDetailList.get(i).getQty().add(inventoryDetailList.get(j).getQty());
                        inventoryDetailList.get(i).setQty(totalQty);
                        inventoryDetailList.remove(j);
                        LambdaQueryWrapper<InventoryDetail> wrapper = Wrappers.lambdaQuery();
                        wrapper.eq(InventoryDetail::getId, inventoryDetailList.get(i).getId());
                        inventoryDetailService.update(inventoryDetailList.get(i), wrapper);
                    }
                }
            }
            BigDecimal totalQty = new BigDecimal(0);
            for(InventoryDetail inventoryDetail : inventoryDetailList) {
                 totalQty = totalQty.add(inventoryDetail.getQty());
            }
            header.setTotalQty(totalQty);
            LambdaQueryWrapper<InventoryHeader> wrapper = Wrappers.lambdaQuery();
            wrapper.eq(InventoryHeader::getId, header.getId());
            inventoryHeaderService.update(header, wrapper);
        }
    }

    /**
     * 移动端创建入库任务
     *
     * @param containerCode  容器编码
     * @param sourceLocation 目的库位
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult mobileCreateReceiptTask(String containerCode, String sourceLocation) {
        LambdaQueryWrapper<ReceiptContainerHeader> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(ReceiptContainerHeader::getContainerCode, containerCode)
                .eq(ReceiptContainerHeader::getStatus, 0);
        ReceiptContainerHeader receiptContainerHeader = receiptContainerHeaderService.getOne(queryWrapper);
        if (receiptContainerHeader == null) {
            throw new ServiceException("该容器没有任务!");
        }
        if (receiptContainerHeader.getWarehouseCode() != ShiroUtils.getWarehouseCode()) {
            throw new ServiceException("容器不在当前仓库!");
        }
        List<Integer> idList = new ArrayList<>();
        idList.add(receiptContainerHeader.getId());
        createReceiptTask(idList);

        return AjaxResult.success(receiptContainerHeader);
    }

//    @Override
//    public List<Map<String, Object>> getReceiptTask(Integer taskId) {
//        return taskHeaderMapper.getReceiptTask(taskId) ;
//    }

    /**
     * 生成
     * 立库移库
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult createTransferTask(String sourceLocation, String destinationLocation) {

        //源库位校验
        Location temp1 = new Location();
        temp1.setCode(sourceLocation);
        temp1.setWarehouseCode(ShiroUtils.getWarehouseCode());
        temp1.setStatus("empty");
        LambdaQueryWrapper<Location> lambda1 = Wrappers.lambdaQuery(temp1);
        Location loc1 = locationService.getOne(lambda1);
        if (loc1 == null) {
            return AjaxResult.error("源库位:" + sourceLocation + "未找到");
        }
        if (!"empty".equals(loc1.getStatus())) {
            return AjaxResult.error("源库位:" + sourceLocation + "状态非空闲");
        }
        if (StringUtils.isEmpty(loc1.getContainerCode())) {
            return AjaxResult.error("源库位:" + sourceLocation + "不存在托盘");
        }
        //这里增加组盘校验,如果此托盘存在未完成的组盘数据,则不能移库
        //校验入库组盘
        int count1 = inventoryHeaderService.getUncompleteReceiptContainer(sourceLocation, ShiroUtils.getWarehouseCode());
        if (count1 > 0) {
            return AjaxResult.error("源库位:" + sourceLocation + "存在入库组盘,不能移库");
        }
        int count2 = inventoryHeaderService.getUncompleteShipmentContainer(sourceLocation, ShiroUtils.getWarehouseCode());
        if (count2 > 0) {
            return AjaxResult.error("源库位:" + sourceLocation + "存在出库组盘,不能移库");
        }
        //目的库位校验
        Location temp2 = new Location();
        temp2.setWarehouseCode(ShiroUtils.getWarehouseCode());
        temp2.setCode(destinationLocation);
        LambdaQueryWrapper<Location> lambdaQueryWrapper2 = Wrappers.lambdaQuery(temp2);
        Location loc2 = locationService.getOne(lambdaQueryWrapper2);
        if (loc2 == null) {
            return AjaxResult.error("目标库位:" + destinationLocation + "未找到");
        }
        if (!"empty".equals(loc2.getStatus())) {
            return AjaxResult.error("目标库位:" + destinationLocation + "状态非空闲");
        }
        if (StringUtils.isNotEmpty(loc2.getContainerCode())) {
            return AjaxResult.error("目标库位:" + destinationLocation + "已存在托盘");
        }
        int count3 = inventoryHeaderService.getUncompleteReceiptContainer(destinationLocation, ShiroUtils.getWarehouseCode());
        if (count3 > 0) {
            return AjaxResult.error("目标库位:" + sourceLocation + "存在入库组盘,不能移库");
        }
        //写入任务主表和明细表
        TaskHeader taskHeader = new TaskHeader();
        taskHeader.setWarehouseCode(ShiroUtils.getWarehouseCode());
        taskHeader.setCompanyCode(ShiroUtils.getCompanyCodeList().get(0));//获取第一个货主
        taskHeader.setInternalTaskType(QuantityConstant.TASK_INTENERTYPE_TRANSFER);
        taskHeader.setTaskType(QuantityConstant.TASK_TYPE_TRANSFER);
        taskHeader.setContainerCode(loc1.getContainerCode());
        taskHeader.setStatus(QuantityConstant.TASK_STATUS_BUILD);
        taskHeader.setFromLocation(sourceLocation);
        taskHeader.setToLocation(destinationLocation);
        taskHeader.setCreated(new Date());
        taskHeader.setCreatedBy(ShiroUtils.getLoginName());
        taskHeader.setLastUpdatedBy(ShiroUtils.getLoginName());
        taskHeader.setLastUpdated(new Date());
        taskHeaderMapper.insert(taskHeader);

        //写入明细表
        TaskDetail taskDetail = new TaskDetail();
        taskDetail.setTaskId(taskHeader.getId());//主单ID
        taskDetail.setTaskType(taskHeader.getTaskType());
        taskDetail.setInternalTaskType(taskHeader.getTaskType());
        taskDetail.setWarehouseCode(taskHeader.getWarehouseCode());
        taskDetail.setCompanyCode(taskHeader.getCompanyCode());
        taskDetail.setFromLocation(sourceLocation);
        taskDetail.setToLocation(destinationLocation);
        taskDetail.setContainerCode(taskHeader.getContainerCode());
        taskDetail.setCreated(new Date());
        taskDetail.setCreatedBy(ShiroUtils.getLoginName());
        taskDetail.setLastUpdated(new Date());
        taskDetail.setLastUpdatedBy(ShiroUtils.getLoginName());
        taskDetailService.save(taskDetail);

        //更新货位状态为预定
        loc1.setStatus("lock");
        loc2.setStatus("lock");
        locationService.saveOrUpdate(loc1);
        locationService.saveOrUpdate(loc2);
        return AjaxResult.success(taskHeader.getId());

    }

    /**
     * 完成移库任务
     *
     * @param task
     */
    @Transactional(rollbackFor = Exception.class)
    public void completeTransferTask(TaskHeader task) {
        //找到任务明细
        TaskDetail taskDetail = new TaskDetail();
        taskDetail.setTaskId(task.getId());
        taskDetail.setWarehouseCode(task.getWarehouseCode());
        taskDetail.setCompanyCode(task.getCompanyCode());
        taskDetail.setContainerCode(task.getContainerCode());
        LambdaQueryWrapper<TaskDetail> taskDetailLW = Wrappers.lambdaQuery(taskDetail);
        taskDetail = taskDetailService.getOne(taskDetailLW);
        //更新库存主表和明细的库位,更改更新用户和时间
        InventoryHeader inventoryHeader = new InventoryHeader();
        //主表
        inventoryHeader.setWarehouseCode(taskDetail.getWarehouseCode());
        inventoryHeader.setCompanyCode(taskDetail.getCompanyCode());
        inventoryHeader.setContainerCode(taskDetail.getContainerCode());
        inventoryHeader.setLocationCode(taskDetail.getFromLocation());//通过源库位查找库存
        LambdaQueryWrapper<InventoryHeader> inventoryHeaderLambdaQueryWrapper = Wrappers.lambdaQuery(inventoryHeader);
        inventoryHeader = inventoryHeaderService.getOne(inventoryHeaderLambdaQueryWrapper);
        if (StringUtils.isNotNull(inventoryHeader)){
            inventoryHeader.setLocationCode(taskDetail.getToLocation());//把目的库位写入库存
            inventoryHeader.setLastUpdated(new Date());
            inventoryHeader.setLastUpdatedBy(ShiroUtils.getLoginName());
            inventoryHeaderService.saveOrUpdate(inventoryHeader);//修改主表库位

            //明细表
            List<InventoryDetail> inventoryDetails = new ArrayList<>();
            InventoryDetail inventoryDetail = new InventoryDetail();
            inventoryDetail.setWarehouseCode(inventoryHeader.getWarehouseCode());
            inventoryDetail.setCompanyCode(inventoryHeader.getCompanyCode());
            inventoryDetail.setInventoryHeaderId(inventoryHeader.getId());
            LambdaQueryWrapper<InventoryDetail> inventoryDetailLambdaQueryWrapper = Wrappers.lambdaQuery(inventoryDetail);
            List<InventoryDetail> inventoryDetailList = inventoryDetailService.list(inventoryDetailLambdaQueryWrapper);
            /*同时写入库存交易表*/
            List<InventoryTransaction> inventoryTransactionList = new ArrayList<>();
            for (InventoryDetail item : inventoryDetailList) {
                item.setLocationCode(inventoryHeader.getLocationCode());//修改明细表库位
                item.setLastUpdated(new Date());
                item.setLastUpdatedBy(ShiroUtils.getLoginName());
                inventoryDetails.add(item);
                /*----------*/
                InventoryTransaction inventoryTransaction = new InventoryTransaction();
                inventoryTransaction.setWarehouseCode(task.getWarehouseCode());
                inventoryTransaction.setLocationCode(taskDetail.getToLocation());
                inventoryTransaction.setContainerCode(taskDetail.getContainerCode());
                inventoryTransaction.setTransactionType(QuantityConstant.INVENTORY_TRANSACTION_ADJUSTPROPERTIES);
                inventoryTransaction.setMaterialCode(item.getMaterialCode());
                inventoryTransaction.setManufactureDate(item.getManufactureDate());
                inventoryTransaction.setMaterialName(item.getMaterialName());
                inventoryTransaction.setMaterialSpec(item.getMaterialSpec());
                inventoryTransaction.setMaterialUnit(item.getMaterialUnit());
                inventoryTransaction.setTaskQty(BigDecimal.ZERO);
                inventoryTransaction.setInventorySts(item.getInventorySts());
                inventoryTransaction.setCompanyCode(item.getCompanyCode());
                inventoryTransaction.setReferDetailId(item.getId().toString());
                inventoryTransaction.setBatch(item.getBatch());
                inventoryTransaction.setLot(item.getLot());
                inventoryTransaction.setProjectNo(item.getProjectNo());
                inventoryTransaction.setWeight(item.getWeight());
                inventoryTransaction.setManufactureDate(item.getManufactureDate());
                inventoryTransaction.setExpirationDate(item.getExpirationDate());
                inventoryTransaction.setAgingDate(item.getCreated());
                inventoryTransaction.setAttributeId(item.getAttributeId());
                inventoryTransaction.setAttribute1(item.getAttribute1());
                inventoryTransaction.setAttribute2(item.getAttribute2());
                inventoryTransaction.setAttribute3(item.getAttribute3());
                inventoryTransaction.setCreated(new Date());
                inventoryTransaction.setCreatedBy(ShiroUtils.getLoginName());
                //inventoryTransaction.setLockCode();
                inventoryTransaction.setBillCode(item.getInventoryHeaderId().toString());
                inventoryTransaction.setBillDetailId(item.getId());
                inventoryTransaction.setSupplierCode(item.getSupplierCode());
                inventoryTransactionList.add(inventoryTransaction);
            }
            if (inventoryDetailService.saveOrUpdateBatch(inventoryDetails)) {
                //更新库存明细成功后,写入库存交易
                inventoryTransactionService.saveBatch(inventoryTransactionList);
            } else {
                throw new ServiceException("库存明细更新错误!");
            }

        }
        //更新托盘、库位状态
        Location temp1 = new Location(); //源库位
        temp1.setCode(taskDetail.getFromLocation());
        temp1.setWarehouseCode(ShiroUtils.getWarehouseCode());
        LambdaQueryWrapper<Location> lambdaQueryWrapper1 = Wrappers.lambdaQuery(temp1);
        Location loc1 = locationService.getOne(lambdaQueryWrapper1);

        Location temp2 = new Location();//目的库位
        temp2.setCode(taskDetail.getToLocation());
        temp2.setWarehouseCode(ShiroUtils.getWarehouseCode());
        LambdaQueryWrapper<Location> lambdaQueryWrapper2 = Wrappers.lambdaQuery(temp2);
        Location loc2 = locationService.getOne(lambdaQueryWrapper2);
        loc2.setContainerCode(loc1.getContainerCode());
        loc2.setStatus("empty");
        loc1.setContainerCode("");
        loc1.setStatus("empty");
        locationService.saveOrUpdate(loc1);
        locationService.saveOrUpdate(loc2);

        Container container = containerService.findAllByCode(task.getContainerCode());
        container.setLocationCode(task.getToLocation());
        if (!containerService.updateById(container)){
            throw new ServiceException("更新容器失败");
        }

        //更新taskHeader状态
        task.setStatus(QuantityConstant.TASK_STATUS_COMPLETED);
        task.setLastUpdatedBy(ShiroUtils.getLoginName());
        task.setLastUpdated(new Date());
        taskHeaderService.saveOrUpdate(task);
        //更新taskDetail状态
        taskDetail.setStatus(QuantityConstant.TASK_STATUS_COMPLETED);
        taskDetail.setLastUpdatedBy(ShiroUtils.getLoginName());
        taskDetail.setLastUpdated(new Date());
        taskDetailService.saveOrUpdate(taskDetail);
    }

    /**
     * 生成
     * 出库查看
     * 任务
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult createCheckOutTask(String[] ids) {

        for (String id : ids) {
            InventoryHeader inventoryHeader = inventoryHeaderService.getById(Integer.parseInt(id));
            //校验库位是否锁定
            //检查库位容器
            Location temp = new Location();
            temp.setCode(inventoryHeader.getLocationCode());
            temp.setWarehouseCode(inventoryHeader.getWarehouseCode());
            LambdaQueryWrapper<Location> lambdaQueryWrapper = Wrappers.lambdaQuery(temp);
            Location loc = locationService.getOne(lambdaQueryWrapper);
            if (loc == null) {
                throw new ServiceException("库存没有库位!");
            }
            if (!"empty".equals(loc.getStatus())) {
                throw new ServiceException(inventoryHeader.getLocationCode() + "状态非空闲,操作失败");
            }
            if (StringUtils.isEmpty(loc.getContainerCode())) {
                throw new ServiceException(inventoryHeader.getLocationCode() + "没有容器,操作失败");
            }
            //通过库存头,找到库存明细
            InventoryDetail inventoryDetail = new InventoryDetail();
            inventoryDetail.setWarehouseCode(inventoryHeader.getWarehouseCode());
            inventoryDetail.setCompanyCode(inventoryHeader.getCompanyCode());
            inventoryDetail.setInventoryHeaderId(inventoryHeader.getId());
            LambdaQueryWrapper<InventoryDetail> inventoryDetailLambdaQueryWrapper = Wrappers.lambdaQuery(inventoryDetail);
            List<InventoryDetail> inventoryDetailList = inventoryDetailService.list(inventoryDetailLambdaQueryWrapper);

            //写入任务主表
            TaskHeader taskHeader = new TaskHeader();
            taskHeader.setWarehouseCode(inventoryHeader.getWarehouseCode());
            taskHeader.setCompanyCode(inventoryHeader.getCompanyCode());//货主
            taskHeader.setInternalTaskType(QuantityConstant.TASK_INTENERTYPE_WORK);
            taskHeader.setTaskType(QuantityConstant.TASK_TYPE_VIEW);
            taskHeader.setContainerCode(inventoryHeader.getContainerCode());
            taskHeader.setStatus(QuantityConstant.TASK_STATUS_BUILD);
            taskHeader.setFromLocation(inventoryHeader.getLocationCode());
            taskHeader.setToLocation(inventoryHeader.getLocationCode());
            taskHeader.setCreated(new Date());
            taskHeader.setCreatedBy(ShiroUtils.getLoginName());
            taskHeader.setLastUpdatedBy(ShiroUtils.getLoginName());
            taskHeader.setLastUpdated(new Date());
            taskHeaderMapper.insert(taskHeader);
            //分拆库存明细,并写入任务细表
            List<TaskDetail> taskDetails = new ArrayList<>();
            for (InventoryDetail item : inventoryDetailList) {
                item.setLockedQty(item.getQty());
                TaskDetail taskDetail = new TaskDetail();
                taskDetail.setTaskId(taskHeader.getId());//主单ID
                taskDetail.setTaskType(taskHeader.getTaskType());
                taskDetail.setInternalTaskType(taskHeader.getTaskType());
                taskDetail.setWarehouseCode(taskHeader.getWarehouseCode());
                taskDetail.setCompanyCode(item.getCompanyCode());
                taskDetail.setFromLocation(taskHeader.getFromLocation());
                taskDetail.setToLocation(taskHeader.getToLocation());
                taskDetail.setContainerCode(taskHeader.getContainerCode());
                taskDetail.setCreated(new Date());
                taskDetail.setCreatedBy(ShiroUtils.getLoginName());
                taskDetail.setLastUpdated(new Date());
                taskDetail.setLastUpdatedBy(ShiroUtils.getLoginName());
                taskDetails.add(taskDetail);
                if (!inventoryDetailService.updateById(item)) {throw new BusinessException("锁定库存失败");}
            }
            if (taskDetailService.saveBatch(taskDetails)) {
                //锁定库位状态
                locationService.updateStatus(inventoryHeader.getLocationCode(), "lock");
            } else {
                throw new ServiceException("出库查看任务明细生成失败!");
            }

        }
        return AjaxResult.success("出库查看任务生成成功!");
    }

    /**库存监控出库查看*/
    @Override
    @Transactional
    public AjaxResult checkLocationCode(String locationCode){

        Location location = new Location();
        location.setCode(locationCode);
        location.setWarehouseCode(ShiroUtils.getWarehouseCode());
        location.setDeleted(false);
        LambdaQueryWrapper<Location> lambdaQueryWrapper = Wrappers.lambdaQuery(location);
        Location loc = locationService.getOne(lambdaQueryWrapper);
        if(!loc.getStatus().equals("empty")){
            return AjaxResult.error(locationCode+"状态非空闲,操作失败");
        }
        if(StringUtils.isEmpty(loc.getContainerCode())){
            return AjaxResult.error(locationCode+"没有托盘,操作失败");
        }
        //生成出库查看任务
        TaskHeader task = new TaskHeader();
        task.setWarehouseCode(ShiroUtils.getWarehouseCode());
        task.setCompanyCode(ShiroUtils.getCompanyCodeList().get(0));
        //这里默认一个0
        task.setTaskType(900);
//        task.setStation(1);
//        task.setPort(1003);
//        if(loc.getType().equals("L")){
//            task.setZoneCode("LK");
//        }
//        task.setRoadway(loc.getRoadway());
//        task.setContainerCode(loc.getContainerCode());
//        task.setFirstStatus((short)1);
//        task.setLastStatus((short)1);
//        task.setSourceLocation(loc.getCode());
//        task.setDestinationLocation(loc.getCode());
//        task.setCreated(new Date());
//        task.setCreatedBy(ShiroUtils.getLoginName());
//        task.setBeginTime(new Date());
//        insert(task);
//        //出库时先锁库位状态
//        loc.setStatus("lock");
//        locationService.updateByModel(loc);

        return AjaxResult.success(task.getId());

    }

    /**
     * 完成
     * 出库查看
     * 更新状态,解锁库存
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult completeSeeOutTask(TaskHeader taskHeader) {
        taskHeader.setStatus(QuantityConstant.TASK_STATUS_COMPLETED);
        taskHeader.setLastUpdatedBy(ShiroUtils.getLoginName()); //更新用户
        taskHeader.setLastUpdated(new Date());   //更新时间
        //task更新明细单总的状态
        TaskDetail taskDetail = new TaskDetail();
        taskDetail.setWarehouseCode(taskHeader.getWarehouseCode());
        taskDetail.setTaskType(taskHeader.getTaskType());
        taskDetail.setTaskId(taskHeader.getId());
        LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(taskDetail);
        List<TaskDetail> taskDetailList = taskDetailService.list(lambdaQueryWrapper);//查询子单
        List<TaskDetail> list = new CopyOnWriteArrayList<>();
        for (TaskDetail item : taskDetailList) {
            item.setStatus(QuantityConstant.TASK_STATUS_COMPLETED);
            item.setLastUpdatedBy(ShiroUtils.getLoginName()); //更新用户
            item.setLastUpdated(new Date());   //更新时间
            list.add(item);
        }
        if (taskDetailService.saveOrUpdateBatch(list) == false ||
                taskHeaderService.saveOrUpdate(taskHeader) == false) {
            throw new ServiceException("任务单据状态更新失败!");
        }
        //释放库位状态
        locationService.updateStatus(taskHeader.getFromLocation(), "empty");
        LambdaQueryWrapper<InventoryDetail> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(InventoryDetail::getLocationCode, taskHeader.getFromLocation())
                .eq(InventoryDetail::getContainerCode, taskHeader.getContainerCode());
        List<InventoryDetail> inventoryDetailList = inventoryDetailService.list(queryWrapper);
        if (!inventoryDetailList.isEmpty()) {
            for (InventoryDetail inventoryDetail : inventoryDetailList) {
                inventoryDetail.setLockedQty(new BigDecimal(0));
                if (!inventoryDetailService.updateById(inventoryDetail)) {throw new BusinessException("解锁库存失败");}
            }
        }
        return AjaxResult.success("完成出库查看任务");
    }

    /**
     * 盘点完成
     *
     * @param taskHeader
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult completeCycleCountTask(TaskHeader taskHeader) {
        /*盘点完成,传入任务主单,查出任务明细,通过任务明细查找盘点的明细单,
        完成任务同时,修改盘点细单和主单的状态,完成后库存锁复位*/
        //修改任务主单状态
        taskHeader.setStatus(QuantityConstant.TASK_STATUS_COMPLETED);
        taskHeader.setLastUpdatedBy(ShiroUtils.getLoginName()); //更新用户
        taskHeader.setLastUpdated(new Date());   //更新时间
        //task更新明细单状态
        TaskDetail taskDetail = new TaskDetail();
        taskDetail.setWarehouseCode(taskHeader.getWarehouseCode());
        taskDetail.setTaskType(taskHeader.getTaskType());
        taskDetail.setTaskId(taskHeader.getId());
        LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(taskDetail);
        List<TaskDetail> taskDetailList = taskDetailService.list(lambdaQueryWrapper);//查询子单
        List<TaskDetail> list = new CopyOnWriteArrayList<>();
        //修改任务明细状态的同时查找到盘点明细的条目并修改状态,最后修改主单状态
        List<CycleCountDetail> cycleCountDetailList = new CopyOnWriteArrayList<>();
        for (TaskDetail item : taskDetailList) {
            item.setStatus(QuantityConstant.TASK_STATUS_COMPLETED);
            item.setLastUpdatedBy(ShiroUtils.getLoginName()); //更新用户
            item.setLastUpdated(new Date());   //更新时间
            list.add(item);

            CycleCountDetail cycleCountDetail = cycleCountDetailService.getById(item.getBillDetailId());//盘点明细
            cycleCountDetail.setEnableStatus(QuantityConstant.CYCLECOUNT_STATUS_COMPLETED);
            cycleCountDetail.setCompletedBy(ShiroUtils.getLoginName());
            cycleCountDetail.setCompletedAt(new Date());
            cycleCountDetailList.add(cycleCountDetail);
            //取消库存盘点锁
            InventoryDetail inventoryDetail = inventoryDetailService.getById(cycleCountDetail.getInventoryDetailId());
            inventoryDetail.setLockCode("");
            inventoryDetailService.saveOrUpdate(inventoryDetail);
        }
        if (taskHeaderService.saveOrUpdate(taskHeader) == false ||
                taskDetailService.saveOrUpdateBatch(list) == false ||
                cycleCountDetailService.saveOrUpdateBatch(cycleCountDetailList) == false) {
            throw new ServiceException("盘点任务单据状态更新失败!");
        }
        //更新主单状态
        cycleCountHeaderService.updataHeaderStatus(cycleCountDetailList.get(0).getCycleCountHeadCode());
        //释放库位
        locationService.updateStatus(cycleCountDetailList.get(0).getLocationCode(), "empty");
        return AjaxResult.success("完成盘点任务");

    }

    /**
     * 完成空托盘入库任务
     *
     * @param taskHeader
     */
    @Transactional(rollbackFor = Exception.class)
    public void completeEmptyIn(TaskHeader taskHeader) {

        //完成任务,修改主单和明细状态
        taskHeader.setStatus(QuantityConstant.TASK_STATUS_COMPLETED);
        taskHeader.setLastUpdatedBy(ShiroUtils.getLoginName());
        taskHeader.setLastUpdated(new Date());
        //taskHeaderService.saveOrUpdate(taskHeader);
        //taskDetail更新明细单总的状态
        TaskDetail taskDetail = new TaskDetail();
        taskDetail.setWarehouseCode(taskHeader.getWarehouseCode());
        taskDetail.setTaskType(taskHeader.getTaskType());
        taskDetail.setTaskId(taskHeader.getId());
        LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(taskDetail);
        List<TaskDetail> taskDetailList = taskDetailService.list(lambdaQueryWrapper);//查询子单
        for (TaskDetail item : taskDetailList) {
            item.setStatus(QuantityConstant.TASK_STATUS_COMPLETED);
            item.setLastUpdatedBy(ShiroUtils.getLoginName()); //更新用户
            item.setLastUpdated(new Date());   //更新时间
        }
        if (taskDetailService.saveOrUpdateBatch(taskDetailList) == false ||
                taskHeaderService.saveOrUpdate(taskHeader) == false) {
            throw new ServiceException("任务单据状态更新失败!");
        }
        //解锁容器,更新库位
        containerService.updateLocationCodeAndStatus(taskHeader.getContainerCode(), taskHeader.getToLocation(), "empty");
        //解锁库位,更新容器
        locationService.updateContainerCodeAndStatus(taskHeader.getToLocation(), taskHeader.getContainerCode(), "empty");

        //写入库存头表
        InventoryHeader inventoryHeader = new InventoryHeader();
        inventoryHeader.setWarehouseCode(taskHeader.getWarehouseCode());
        inventoryHeader.setLocationCode(taskHeader.getToLocation());
        inventoryHeader.setContainerCode(taskHeader.getContainerCode());
        inventoryHeader.setContainerStatus("empty");
        inventoryHeader.setCompanyCode(taskHeader.getCompanyCode());
        inventoryHeader.setMaterialSkuQty("0");
        inventoryHeader.setTotalWeight("0");
        inventoryHeader.setTotalQty(new BigDecimal(0));
        inventoryHeader.setTotalLines(0);
        inventoryHeader.setProjectNos("");
        inventoryHeader.setBatchs("");
        inventoryHeader.setLots("");
        inventoryHeader.setLockRemark("");
        inventoryHeader.setCreated(new Date());
        inventoryHeader.setCreatedBy(ShiroUtils.getLoginName());
        inventoryHeader.setLastUpdated(new Date());
        inventoryHeader.setLastUpdatedBy(ShiroUtils.getLoginName());
        Boolean j = inventoryHeaderService.save(inventoryHeader);
        if(!j){
            throw new ServiceException("新增空托库存头失败!");

        }
    }

    /**
     * 完成空托盘出库任务
     *
     * @param taskHeader
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult completeEmptyOut(TaskHeader taskHeader) {

        taskHeader.setStatus(QuantityConstant.TASK_STATUS_COMPLETED);
        taskHeader.setLastUpdatedBy(ShiroUtils.getLoginName());
        taskHeader.setLastUpdated(new Date());
        //taskHeaderService.saveOrUpdate(taskHeader);
        //taskDetail更新明细单总的状态
        TaskDetail taskDetail = new TaskDetail();
        taskDetail.setWarehouseCode(taskHeader.getWarehouseCode());
        taskDetail.setTaskType(taskHeader.getTaskType());
        taskDetail.setTaskId(taskHeader.getId());
        LambdaQueryWrapper lambdaQueryWrapper = Wrappers.lambdaQuery(taskDetail);
        List<TaskDetail> taskDetailList = taskDetailService.list(lambdaQueryWrapper);//查询子单
        for (TaskDetail item : taskDetailList) {
            item.setStatus(QuantityConstant.TASK_STATUS_COMPLETED);
            item.setLastUpdatedBy(ShiroUtils.getLoginName()); //更新用户
            item.setLastUpdated(new Date());   //更新时间
        }
        if (taskDetailService.saveOrUpdateBatch(taskDetailList) == false || taskHeaderService.saveOrUpdate(taskHeader) == false) {
            throw new ServiceException("任务单据状态更新失败!");
        }
        //更新货位
        locationService.updateContainerCodeAndStatus(taskHeader.getFromLocation(), "", "empty");
        //更新容器信息
        containerService.updateLocationCodeAndStatus(taskHeader.getContainerCode(), "", "empty");
        //删除库存头表
        InventoryHeader tmp = new InventoryHeader();
        tmp.setContainerStatus("empty");
        tmp.setContainerCode(taskHeader.getContainerCode());
        tmp.setLocationCode(taskHeader.getFromLocation());
        LambdaQueryWrapper<InventoryHeader> inventoryHeaderLambdaQueryWrapper = Wrappers.lambdaQuery(tmp);
        Boolean j = inventoryHeaderService.remove(inventoryHeaderLambdaQueryWrapper);
        if(!j){
            throw new ServiceException("空库位记录删除失败!");
        }
        return AjaxResult.success("空托出库完成");
    }

    /**
     * 创建上架任务
     *
     * @param ids
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult createReceiptTask(List<Integer> ids) {
        for (Integer id : ids) {
            ReceiptContainerHeader receiptContainerHeader = receiptContainerHeaderService.getById(id);
            if (receiptContainerHeader == null) {
                throw new ServiceException("任务不存在!");
            }

            if (!receiptContainerHeader.getWarehouseCode().equals(ShiroUtils.getWarehouseCode())) {
                throw new ServiceException("任务不在当前仓库!");
            }

            //锁定容器
            Container container = new Container();
            container.setStatus("lock");
            LambdaUpdateWrapper<Container> containerUpdateWrapper = Wrappers.lambdaUpdate();
            containerUpdateWrapper.eq(Container::getCode, receiptContainerHeader.getContainerCode());
            containerService.update(container, containerUpdateWrapper);

            //查询入库组盘明细
            LambdaQueryWrapper<ReceiptContainerDetail> containerDetailLambda = Wrappers.lambdaQuery();
            containerDetailLambda.eq(ReceiptContainerDetail::getReceiptContainerId, id);
            List<ReceiptContainerDetail> list = receiptContainerDetailService.list(containerDetailLambda);

            if (list.size() < 1) {
                throw new ServiceException("没有组盘明细,请先组盘!");
            }
            if (receiptContainerHeader.getStatus() == QuantityConstant.RECEIPT_CONTAINER_BUILD.intValue()) {
                if (receiptContainerHeader.getStatus().intValue() < QuantityConstant.RECEIPT_CONTAINER_TASK) {
                    receiptContainerHeader.setStatus((short) QuantityConstant.RECEIPT_CONTAINER_TASK.intValue());
                    receiptContainerHeaderService.updateById(receiptContainerHeader);
                }
                //添加任务主表
                TaskHeader task = new TaskHeader();
                task.setAllocationHeadId(receiptContainerHeader.getId());
                task.setInternalTaskType(QuantityConstant.TASK_INTENERTYPE_SHELF);
                task.setWarehouseCode(receiptContainerHeader.getWarehouseCode());
                task.setCompanyCode(receiptContainerHeader.getCompanyCode());
                task.setTaskType(Integer.valueOf(receiptContainerHeader.getTaskType()));
                task.setFromLocation(receiptContainerHeader.getFromLocation());
                task.setToLocation(receiptContainerHeader.getToLocation());
                task.setContainerCode(receiptContainerHeader.getContainerCode());
                task.setRecvDock(receiptContainerHeader.getRecvDock());
                task.setCreated(new Date());
                task.setCreatedBy(ShiroUtils.getLoginName());
                if (this.save(task)) {
                    //添加任务明细表
                    int conatinQty = 0;
                    for (ReceiptContainerDetail item : list) {
                        LambdaQueryWrapper<ContainerCapacity> lambdaQueryWrapper = Wrappers.lambdaQuery();
                        String[] containCodeSplit = task.getContainerCode().split("\\D");
                        String containType = containCodeSplit[0];
                        lambdaQueryWrapper.eq(ContainerCapacity::getContainerType, task.getContainerCode())
                                .eq(ContainerCapacity::getMaterialCode, item.getMaterialCode())
                                .eq(ContainerCapacity::getWarehouseCode, ShiroUtils.getWarehouseCode())
                                .eq(ContainerCapacity::getEnable, 0);
                        ContainerCapacity containerCapacity = containerCapacityService.getOne(lambdaQueryWrapper);

                        TaskDetail taskDetail = new TaskDetail();
                        taskDetail.setTaskId(task.getId());
                        taskDetail.setTaskType(Integer.valueOf(receiptContainerHeaderService.getById(item.getReceiptContainerId()).getTaskType()));
                        taskDetail.setInternalTaskType(QuantityConstant.TASK_INTENERTYPE_SHELF);
                        taskDetail.setWarehouseCode(task.getWarehouseCode());
                        taskDetail.setAllocationId(item.getReceiptId());
                        taskDetail.setCompanyCode(task.getCompanyCode());
                        taskDetail.setCompanyCode(task.getCompanyCode());
                        taskDetail.setMaterialCode(item.getMaterialCode());
                        taskDetail.setMaterialName(item.getMaterialName());
                        taskDetail.setMaterialSpec(item.getMaterialSpec());
                        taskDetail.setMaterialUnit(item.getMaterialUnit());
                        taskDetail.setBillCode(item.getReceiptCode());
                        taskDetail.setBillDetailId(item.getReceiptDetailId());
                        taskDetail.setBillCode(item.getReceiptCode());
                        taskDetail.setQty(item.getQty());
                        taskDetail.setContainerCode(task.getContainerCode());
                        taskDetail.setFromLocation(task.getFromLocation());
                        taskDetail.setLastUpdatedBy(ShiroUtils.getLoginName());
                        taskDetail.setBatch(item.getBatch());
                        if (containerCapacity != null) {
                            conatinQty += (int) Math.floor(item.getQty().intValue() / containerCapacity.getQty().intValue());
                            taskDetail.setContainQty((int) Math.floor(item.getQty().intValue() / containerCapacity.getQty().intValue()));
                        }
                        if (!taskDetailService.save(taskDetail)) {
                            throw new ServiceException("生成任务明细失败");
                        }

                        //更新入库组盘明细状态
                        item.setStatus(QuantityConstant.RECEIPT_CONTAINER_TASK);
                        if (!receiptContainerDetailService.updateById(item)) {
                            throw new ServiceException("更新入库组盘明细状态出错");
                        }

                        /**
                         * 修改明细状态为上架
                         */
                        ReceiptDetail receiptDetail = receiptDetailService.getById(item.getReceiptDetailId());
                        receiptDetail.setProcessStamp(String.valueOf(QuantityConstant.RECEIPT_HEADER_SHELF));
                        if (!receiptDetailService.updateById(receiptDetail)) {
                            throw new ServiceException("更新入库单详情失败");
                        }
                        //更新头表状态
                        receiptDetailService.updateReceiptHeaderLastStatus(receiptDetail.getReceiptId());

                    }

                    task.setContainQty(conatinQty);
                    if (!taskHeaderService.updateById(task)) {
                        throw new ServiceException("更新任务头表容器数量失败");
                    }
                } else {
                    throw new ServiceException("生成任务头表失败");
                }
            }
        }
        return AjaxResult.success("生成上架任务成功");
    }

    /**
     * 完成出库任务
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void completeShipmentTask(TaskHeader task) {
        //获取所有子任务
        TaskDetail condition = new TaskDetail();
        condition.setTaskId(task.getId());
        LambdaQueryWrapper<TaskDetail> lambdaQueryWrapper = Wrappers.lambdaQuery(condition);
        List<TaskDetail> taskDetails = taskDetailService.list(lambdaQueryWrapper);
        List<Integer> shipmentHeadIds = new ArrayList<>();
        for (TaskDetail taskDetail : taskDetails) {
            if (taskDetail.getStatus() < QuantityConstant.TASK_STATUS_RUNNING) {
                //获取出库子货箱
                ShipmentContainerDetail shipmentContainerDetail = shipmentContainerDetailService.getById(taskDetail.getAllocationId());
                //取出子单据
                ShipmentDetail shipmentDetail = shipmentDetailService.getById(taskDetail.getBillDetailId());
                //暂存id,为更新单据状态准备
                shipmentHeadIds.add(shipmentDetail.getShipmentId());
                //获取对应库存记录
                InventoryDetail inventoryDetail = inventoryDetailService.getById(taskDetail.getToInventoryId());
                if (inventoryDetail == null) {
                    throw new ServiceException("任务明细对应的库存ID【" + taskDetail.getToInventoryId().toString() + "】不存在!");
                }
                BigDecimal orignalQty = inventoryDetail.getQty();
                //减扣库存单
                InventoryHeader inventoryHeader = inventoryHeaderService.getById(inventoryDetail.getInventoryHeaderId());
                inventoryHeader.setTotalQty(inventoryDetail.getQty().subtract(taskDetail.getQty()));
                //扣减库存明细
                inventoryDetail.setTaskQty(inventoryDetail.getTaskQty().subtract(taskDetail.getQty()));
                inventoryDetail.setQty(inventoryDetail.getQty().subtract(taskDetail.getQty()));
                if (inventoryDetail.getQty().compareTo(new BigDecimal("0")) == 0 && inventoryDetail.getTaskQty().compareTo(new BigDecimal("0")) == 0) {
                    //如果库存没有了,就删除这个库存
                    inventoryDetailService.removeById(inventoryDetail.getId());
                    inventoryHeaderService.removeById(inventoryHeader.getId());
                } else {
                    //否则更新这个库存
                    inventoryDetailService.updateById(inventoryDetail);
                    inventoryHeaderService.updateById(inventoryHeader);
                }
                //设置子任务状态为已执行
                taskDetail.setStatus(QuantityConstant.TASK_STATUS_COMPLETED);
                taskDetail.setLastUpdatedBy(ShiroUtils.getLoginName());
                taskDetail.setLastUpdated(new Date());//完成时间
                taskDetailService.updateById(taskDetail);
                //记录库存交易记录
                InventoryTransaction inventoryTransaction = new InventoryTransaction();
                inventoryTransaction.setWarehouseCode(task.getWarehouseCode());
                inventoryTransaction.setCompanyCode(shipmentDetail.getCompanyCode());
                inventoryTransaction.setLocationCode(inventoryDetail.getLocationCode());
                inventoryTransaction.setContainerCode(inventoryDetail.getContainerCode());
                inventoryTransaction.setTransactionType(QuantityConstant.INVENTORY_TRANSACTION_SHIPMENT);
                inventoryTransaction.setMaterialCode(shipmentDetail.getMaterialCode());
                inventoryTransaction.setMaterialName(shipmentDetail.getMaterialName());
                inventoryTransaction.setMaterialSpec(shipmentDetail.getMaterialSpec());
                inventoryTransaction.setMaterialUnit(shipmentDetail.getMaterialUnit());
                inventoryTransaction.setBillCode(taskDetail.getBillCode());
                inventoryTransaction.setBillDetailId(shipmentDetail.getId());
                inventoryTransaction.setBatch(shipmentDetail.getBatch());
                inventoryTransaction.setLot(shipmentDetail.getLot());
                inventoryTransaction.setProjectNo(shipmentDetail.getProjectNo());
                inventoryTransaction.setQcCheck(inventoryDetail.getQcCheck());
                inventoryTransaction.setSupplierCode(inventoryDetail.getSupplierCode());
                inventoryTransaction.setManufactureDate(shipmentDetail.getManufactureDate());
                inventoryTransaction.setExpirationDate(shipmentDetail.getExpirationDate());
                inventoryTransaction.setInventorySts(inventoryDetail.getInventorySts());
                //这里取反,更符合出库的语义,同时方便对记录进行统计
                inventoryTransaction.setTaskQty(taskDetail.getQty());
//                inventoryTransaction.setCostPrice(shipmentDetail.);
                inventoryTransaction.setCreated(null);
                inventoryTransaction.setCreatedBy(ShiroUtils.getLoginName());
                inventoryTransactionService.save(inventoryTransaction);
//                //更新单据状态
//                shipmentHeaderService.updateShipmentStatus(shipmentHeader.getId());
            }
            /* 物料预警*/
//            configWarningService.materialWarning(taskDetail.getMaterialCode(), taskDetail.getMaterialName());
//            /* 空库位剩余数量预警*/
//            configWarningService.emptyLocationWarning();
        }
        //设置主任务为已执行
        task.setStatus(QuantityConstant.TASK_STATUS_COMPLETED);
        task.setLastUpdatedBy(ShiroUtils.getLoginName());
        task.setLastUpdated(new Date());
        taskHeaderService.updateById(task);


        //将库位状态改为空闲,如果是整出的对应的容器也清空
        LambdaQueryWrapper<Location> lam = Wrappers.lambdaQuery();
        lam.eq(Location::getCode, task.getFromLocation());
        Location locationRecord = locationService.getOne(lam);
        if (lam == null) {
            throw new ServiceException("系统没有" + task.getToLocation() + "库位");
        }
        locationRecord.setStatus("empty");
        if (task.getTaskType().equals(QuantityConstant.TASK_TYPE_WHOLESHIPMENT)) {
            locationRecord.setContainerCode("");
        }
        locationService.updateById(locationRecord);
        //如果是整出,删掉这个库位上的这个托盘,否则更改托盘状态
        LambdaQueryWrapper<Container> containerLam = Wrappers.lambdaQuery();
        containerLam.eq(Container::getCode, task.getContainerCode());
        Container ctn = containerService.getOne(containerLam);
        if (ctn == null) {
            throw new ServiceException("系统无此容器");
        }
        if (task.getTaskType().equals(QuantityConstant.TASK_TYPE_WHOLESHIPMENT)) {
            if ("LS".equals(ctn.getContainerType())) {
                Boolean flag = containerService.removeById(ctn.getId());
                if (flag == false) {
                    throw new ServiceException("删除临时容器失败");
                }
            } else {
                containerService.updateLocationCodeAndStatus(task.getContainerCode(), "", "empty");
            }
        } else {
            //查询是否存在关联的库存,入如果没有就修改容器状态为empty
            InventoryDetail inventoryCondition = new InventoryDetail();
            inventoryCondition.setLocationCode(task.getToLocation());
            LambdaQueryWrapper<InventoryDetail> inventoryDetaillambdaQueryWrapper = Wrappers.lambdaQuery();
            inventoryDetaillambdaQueryWrapper.eq(InventoryDetail::getLocationCode, task.getToLocation());
            List<InventoryDetail> detailList = inventoryDetailService.list();
            //库存查询不到该容器就把容器状态改为可用
            if (detailList.size() < 1) {
                Container container = new Container();
                container.setCode(task.getContainerCode());
                condition.setToLocation("");
                LambdaUpdateWrapper<Container> containerLambdaUpdateWrapper = Wrappers.lambdaUpdate();
                containerLambdaUpdateWrapper.eq(Container::getCode, task.getContainerCode());
                containerService.update(container, containerLambdaUpdateWrapper);
            }
        }
        //设置出库货箱状态为拣货任务完成
        for (TaskDetail taskDetail : taskDetails) {
            ShipmentContainerDetail shipmentContainerDetail = new ShipmentContainerDetail();
            shipmentContainerDetail.setStatus(QuantityConstant.SHIPMENT_CONTAINER_REVIEWSUCCESS);
            shipmentContainerDetail.setLastUpdated(new Date());
            shipmentContainerDetail.setLastUpdatedBy(ShiroUtils.getLoginName());
            LambdaUpdateWrapper<ShipmentContainerDetail> shipmentContainerDetailLambdaUpdateWrapper = Wrappers.lambdaUpdate();
            shipmentContainerDetailLambdaUpdateWrapper.eq(ShipmentContainerDetail::getId, taskDetail.getAllocationId());
            if (!shipmentContainerDetailService.update(shipmentContainerDetail, shipmentContainerDetailLambdaUpdateWrapper)) {
                throw new ServiceException("更新组盘明细状态失败");
            }
        }
        //设置出库货箱表头状态为拣货任务完成
        ShipmentContainerHeader shipmentContainerHeader = new ShipmentContainerHeader();
        shipmentContainerHeader.setStatus(QuantityConstant.SHIPMENT_CONTAINER_REVIEWSUCCESS);
        shipmentContainerHeader.setLastUpdated(new Date());
        shipmentContainerHeader.setLastUpdatedBy(ShiroUtils.getLoginName());
        LambdaUpdateWrapper<ShipmentContainerHeader> shipmentContainerHeaderLambdaUpdateWrapper = Wrappers.lambdaUpdate();
        shipmentContainerHeaderLambdaUpdateWrapper.eq(ShipmentContainerHeader::getId, task.getAllocationHeadId());
        if (!shipmentContainerHeaderService.update(shipmentContainerHeader, shipmentContainerHeaderLambdaUpdateWrapper)) {
            throw new ServiceException("更新组盘头状态失败");
        }
        //修改出库单状态
        LambdaQueryWrapper<TaskDetail> taskDetailLambdaQueryWrapper = Wrappers.lambdaQuery();
        taskDetailLambdaQueryWrapper.eq(TaskDetail::getTaskId, task.getId());
        List<TaskDetail> taskDetailList = taskDetailService.list(taskDetailLambdaQueryWrapper);

        HashSet<Integer> ids = new HashSet<>();
        for (TaskDetail taskDeatails : taskDetailList) {
            LambdaQueryWrapper<ShipmentDetail> shipmentDetailLambdaQueryWrapper = Wrappers.lambdaQuery();
            shipmentDetailLambdaQueryWrapper.eq(ShipmentDetail::getId, taskDeatails.getBillDetailId());
            ShipmentDetail shipmentDetail = shipmentDetailService.getOne(shipmentDetailLambdaQueryWrapper);
            if (shipmentDetail == null) {
                throw new ServiceException("查找出库单明细失败");
            }
            if (shipmentDetail.getShipQty().compareTo(shipmentDetail.getRequestQty()) == 0) {
                shipmentDetail.setStatus(QuantityConstant.SHIPMENT_HEADER_COMPLETED);
                shipmentDetailService.updateById(shipmentDetail);
            }
            ids.add(shipmentDetail.getShipmentId());
        }

        for (Integer id : ids) {
            ShipmentHeader shipmentHeader = shipmentHeaderService.getById(id);
            if (shipmentHeader != null) {
                Map<String, Integer> status = shipmentDetailService.selectStatus(shipmentHeader.getId());
                Integer maxStatus = status.get("maxStatus");
                Integer minStatus = status.get("minStatus");
                if (maxStatus.equals(QuantityConstant.SHIPMENT_HEADER_COMPLETED)) {
                    shipmentHeader.setFirstStatus(QuantityConstant.SHIPMENT_HEADER_COMPLETED);
                }
                if (minStatus.equals(QuantityConstant.SHIPMENT_HEADER_COMPLETED)) {
                    shipmentHeader.setLastStatus(QuantityConstant.SHIPMENT_HEADER_COMPLETED);
                }
                shipmentHeader.setLastUpdatedBy(ShiroUtils.getLoginName());
                shipmentHeader.setLastUpdated(new Date());
                shipmentHeaderService.updateById(shipmentHeader);
            }
        }
    }

    /**
     * 自动空托出库
     * */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult createAutoEmptyOut(String warehouseCode){
        /*先查询容器表,选中空托盘,再查询库存核实*/
        //该容器中有库位信息,并且状态是空
        List<Location> locationsList = locationService.selectContainerEmpty(warehouseCode);
        if(locationsList.size() == 0){
            throw new ServiceException("立库中没有空容器!");
        }
        //根据入库顺序正序排列取第一个
        Location location = locationsList.get(0);
        //反查库位
        Container containerTmp = new Container();
        containerTmp.setWarehouseCode(location.getWarehouseCode());
        containerTmp.setCode(location.getContainerCode());
        LambdaQueryWrapper<Container> containerLambda = Wrappers.lambdaQuery(containerTmp);
        Container container = containerService.getOne(containerLambda);
        if(container == null){
            throw new ServiceException("选中的库位容器错误,请确认库位和容器!");
        }
        //生成空容器出库任务
        inventoryHeaderService.createEmptyOut(container.getCode(), location.getCode());
        return AjaxResult.success("空容器出库任务已下发!",container.getCode());
    }

    /**
     * 任务自动分配库位
     *
     * */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String getLocationCode(Integer taskId, String weight){
        String warehouseCode = ShiroUtils.getWarehouseCode();
        TaskHeader task = this.getById(taskId);
        if (task == null) {
            throw new ServiceException("找不到id为"+ taskId +"的任务");
        }
        if (StringUtils.isNotEmpty(task.getToLocation())) {
            throw new ServiceException("任务已经有目的库位");
        }
        if(!warehouseCode.equals(task.getWarehouseCode())){
            throw new ServiceException("仓库错误!");
        }
        /*if(task.getIsDoubleIn() != 1 ){
            if(StringUtils.isNotEmpty(task.getToLocation())){
                return AjaxResult.success("已经存在目的库位不再分配!");
            }
        }*/
        //查询容器,根据容器类型分配库位
        Container tmp = new Container();
        tmp.setCode(task.getContainerCode());
        tmp.setWarehouseCode(warehouseCode);
        LambdaQueryWrapper<Container> containerLambdaQueryWrapper = Wrappers.lambdaQuery(tmp);
        Container container = containerService.getOne(containerLambdaQueryWrapper);
        //库位筛选
        LambdaQueryWrapper<Location> locationLambdaQueryWrapper = Wrappers.lambdaQuery();
        locationLambdaQueryWrapper.eq(Location::getWarehouseCode,task.getWarehouseCode())
                .eq(Location::getContainerCode,"")
                .eq(Location::getStatus,"empty")
                .eq(Location::getDeleted,false);
        /*if(container.getContainerType().equals("L")){
            locationLambdaQueryWrapper.eq(Location::getRoadway,"2")
                    .le(Location::getIColumn,8); //小于等于
        }
        else if(container.getContainerType().equals("M")) {
            locationLambdaQueryWrapper.eq(Location::getRoadway,"2")
                    .gt(Location::getIColumn,8);//大于
        }
        else if(container.getContainerType().equals("S")){
            locationLambdaQueryWrapper.eq(Location::getRoadway,"1");
        }
        else if(container.getContainerType().equals("D")){
            return AjaxResult.success("地面库区不自动分配库位");
        }*/

        List<Location> locations = locationService.list(locationLambdaQueryWrapper);
        if (locations.size() == 0) {
            throw new ServiceException("没有空闲库位!");
        }
        //随机取库位
        Random rand = new Random();
        Location location = locations.get(rand.nextInt(locations.size()));
        if (location == null) {
            throw new ServiceException("库位分配错误!");
        }
        //锁定库位
        locationService.updateStatus(location.getCode(),"lock");
        //给组盘分配库位
        ReceiptContainerHeader receiptContainerHeader = new ReceiptContainerHeader();
        receiptContainerHeader.setId(task.getAllocationHeadId());
        receiptContainerHeader.setToLocation(location.getCode());
        receiptContainerHeader.setContainerCode(container.getCode());
        receiptContainerHeader.setWarehouseCode(ShiroUtils.getWarehouseCode());
        receiptContainerHeader.setCreatedBy(ShiroUtils.getLoginName());
        receiptContainerHeader.setLastUpdatedBy(ShiroUtils.getLoginName());
        //LambdaQueryWrapper<ReceiptContainerHeader> rchlqw = Wrappers.lambdaQuery(receiptContainerHeader);
        receiptContainerHeaderService.saveOrUpdate(receiptContainerHeader);
        //组盘明细分配库位
        ReceiptContainerDetail tmpe = new ReceiptContainerDetail();
        tmpe.setReceiptContainerId(task.getAllocationHeadId());
        tmpe.setWarehouseCode(task.getWarehouseCode());
        LambdaQueryWrapper<ReceiptContainerDetail> receiptContainerDetailLambda = Wrappers.lambdaQuery(tmpe);
        List<ReceiptContainerDetail> receiptContainerDetailList = receiptContainerDetailService.list(receiptContainerDetailLambda);
        //stream修改库位
        receiptContainerDetailList
                .stream()
                .forEach(r -> r.setLocationCode(receiptContainerHeader.getToLocation()));
        receiptContainerDetailService.updateBatchById(receiptContainerDetailList);
        //给子任务分配库位
        TaskDetail tdtmp = new TaskDetail();
        tdtmp.setTaskId(task.getId());
        tdtmp.setWarehouseCode(task.getWarehouseCode());
        tdtmp.setTaskType(task.getTaskType());
        LambdaQueryWrapper<TaskDetail> taskDetailLambdaQueryWrapper = Wrappers.lambdaQuery(tdtmp);
        List<TaskDetail> taskDetails = taskDetailService.list(taskDetailLambdaQueryWrapper);
        taskDetails.stream().forEach(t -> t.setToLocation(task.getToLocation()));
        taskDetailService.updateBatchById(taskDetails);
        //给任务分配库位
        task.setToLocation(location.getCode());
        task.setWeight(weight);
        //task.setFromLocation(location.getCode());
        //LambdaQueryWrapper<TaskHeader> taskHeaderLambdaQueryWrapper = Wrappers.lambdaQuery(task);
        this.saveOrUpdate(task);
        return location.getCode();
    }


    /**
     * 自动分配库位
     * @param taskId  任务号
     * @param high 1是高库位,否则低库位
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult setLocationCode(Integer taskId, Integer high)    {
        TaskHeader taskHeader = this.getById(taskId);
        if (taskHeader == null) {
            throw new ServiceException("找不到id为"+ taskId +"的任务!");
        }
        if (StringUtils.isNotEmpty(taskHeader.getToLocation())) {
            return AjaxResult.success("任务已经有目的库位,不需要再分配");
        }
//        Location location = new Location();
//        location.setWarehouseCode(ShiroUtils.getWarehouseCode());
//
//        location.setContainerCode("");
//        location.setStatus("empty");
//        location.setDeleted(false);
//        if("M".equals(taskHeader.getContainerCode().substring(0,1))){
//            if (high.intValue() == 1) {
//                location.setILayer(5);
//            }
//        }
        LambdaQueryWrapper<Location> locationLambdaQueryWrapper = Wrappers.lambdaQuery();
        locationLambdaQueryWrapper.eq(Location::getWarehouseCode,ShiroUtils.getWarehouseCode())
                .eq(Location::getContainerCode,"")
                .eq(Location::getStatus,"empty")
                .eq(Location::getDeleted,false);
//        location = locationService.getOne(locationLambdaQueryWrapper);
//        if (location == null) {
//            throw new ServiceException("没有对应库位可以分配给容器了!");
//        }
        List<Location> locations = locationService.list(locationLambdaQueryWrapper);
        if (locations.size() == 0) {
            throw new ServiceException("没有空闲库位!");
        }
        //随机取库位
        Random rand = new Random();
        Location location = locations.get(rand.nextInt(locations.size()));
        if (location == null) {
            throw new ServiceException("库位分配错误!");
        }
        //锁定库位
        locationService.updateStatus(location.getCode(),"lock");
        //给组盘分配库位

        int internalTaskType = taskHeader.getInternalTaskType();
        if(internalTaskType == QuantityConstant.TASK_TYPE_WHOLERECEIPT.intValue() || internalTaskType == QuantityConstant.TASK_TYPE_SUPPLEMENTRECEIPT.intValue() ) {
            ReceiptContainerHeader receiptContainerHeader = new ReceiptContainerHeader();
            receiptContainerHeader.setId(taskHeader.getAllocationHeadId());
            receiptContainerHeader.setToLocation(location.getCode());
            LambdaQueryWrapper<ReceiptContainerHeader> receiptContainerHeaderlLambdaQueryWrapper = Wrappers.lambdaQuery(receiptContainerHeader);
            receiptContainerHeaderService.update(receiptContainerHeader, receiptContainerHeaderlLambdaQueryWrapper);
            //给子任务分配库位
            TaskDetail condition = new TaskDetail();
            condition.setWarehouseCode(ShiroUtils.getWarehouseCode());
            condition.setTaskId(taskHeader.getId());
            LambdaQueryWrapper<TaskDetail> taskDetailLambdaQueryWrapper = Wrappers.lambdaQuery(condition);
            TaskDetail taskDetail = taskDetailService.getOne(taskDetailLambdaQueryWrapper);
            if (taskDetail != null) {
                taskDetail.setToLocation(location.getCode());
                taskDetailService.update(taskDetail, taskDetailLambdaQueryWrapper);
            }
        }
        //给任务分配库位
        taskHeader.setToLocation(location.getCode());
        LambdaQueryWrapper<TaskHeader> taskHeaderLambdaQueryWrapper = Wrappers.lambdaQuery(taskHeader);
        this.update(taskHeader, taskHeaderLambdaQueryWrapper);
        return AjaxResult.success("生成库位成功",location.getCode());

    }






}