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 LocationService locationService;
    @Resource
    private ContainerService containerService;
    @Resource
    private TaskDetailService taskDetailService;
    @Resource
    private TaskHeaderService taskHeaderService;
    @Resource
    private InventoryHeaderService inventoryHeaderService;
    @Resource
    private InventoryDetailService inventoryDetailService;

    @Resource
    private TransferTaskService transferTaskService;
    @Resource
    private ReceiptContainerDetailService receiptContainerDetailService;
    @Resource
    private CycleCountDetailService cycleCountDetailService;
    @Resource
    private CycleCountHeaderService cycleCountHeaderService;
    @Resource
    private ReceiptContainerHeaderService receiptContainerHeaderService;
    @Resource
    private TaskHeaderMapper taskHeaderMapper;
    @Resource
    private TaskAssignService taskAssignService;
    @Resource
    private CreateTaskMessage createTaskMessage;
    @Resource
    private ReceiptTaskService receiptTaskService;
    @Resource
    private ShipmentTaskService shipmentTaskService;
    @Resource
    private WorkTaskService workTaskService;

    /**
     * 盘点任务首选项
     *
     * @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 receiptTaskService.completeReceiptTask((list.get(0)));
        } else {
            throw new ServiceException("库位(" + locationCode + ")的任务不是上架,不能完成!");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult createReplenishTask(String containerCode, Integer 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());
        receiptTaskService.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
     * @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));
            if (StringUtils.isEmpty(ids)){
                return AjaxResult.error("id不能为空");
            }

            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 receiptTaskService.createReceiptTask(idList);
        }
        return AjaxResult.error("生成入库任务失败");
    }

    /**
     * 下发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传递任务
            taskAssignService.wcsTaskAssign(task);

            //修改任务头表
            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("更新任务明细失败");
                }
            }

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

    @Override
    @Transactional
    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) ) {
            //入库任务
            receiptTaskService.completeReceiptTask(task);
        }
        if (task.getInternalTaskType().equals(QuantityConstant.TASK_INTENERTYPE_PICKING) &&
                (task.getTaskType().equals(QuantityConstant.TASK_TYPE_WHOLESHIPMENT) || task.getTaskType().equals(QuantityConstant.TASK_TYPE_SORTINGSHIPMENT))) {
            //出库任务
            shipmentTaskService.completeShipmentTask(task);
        }
        // 900 出库查看,空托出库查看
        if (task.getTaskType().equals( QuantityConstant.TASK_TYPE_VIEW)) {
            workTaskService.completeCheckOutTask(task);
        }
        // 700 盘点
        if (task.getTaskType().equals(QuantityConstant.TASK_TYPE_CYCLECOUNT)) {
            this.completeCycleCountTask(task);
        }
        if (task.getTaskType().equals( QuantityConstant.TASK_TYPE_TRANSFER)) {
//          //移库
            transferTaskService.completeTransferTask(task);
        }
        if (task.getTaskType().equals( QuantityConstant.TASK_TYPE_EMPTYRECEIPT)) {
            //空托盘入库
            workTaskService.completeEmptyIn(task);
        }
        if (task.getTaskType().equals(QuantityConstant.TASK_TYPE_EMPTYSHIPMENT) ) {
            //空托盘出库
            workTaskService.completeEmptyOut(task);
        }
    }

    /**
     * 移动端创建入库任务
     *
     * @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());
        receiptTaskService.createReceiptTask(idList);

        return AjaxResult.success(receiptContainerHeader);
    }

    /**
     * 盘点完成
     *
     * @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("完成盘点任务");

    }

    /**
     * 自动空托出库
     * */
    @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());
    }

    /**
     * 自动分配库位
     * @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("任务已经有目的库位,不需要再分配");
        }
        LambdaQueryWrapper<Location> locationLambdaQueryWrapper = Wrappers.lambdaQuery();
        locationLambdaQueryWrapper.eq(Location::getWarehouseCode,ShiroUtils.getWarehouseCode())
                .eq(Location::getContainerCode,"")
                .eq(Location::getStatus,"empty")
                .eq(Location::getDeleted,false);
        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());

    }

}