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.service.ServiceException;
import com.huaheng.common.support.Convert;
import com.huaheng.common.utils.StringUtils;
import com.huaheng.common.utils.security.ShiroUtils;
import com.huaheng.framework.web.domain.AjaxResult;
import com.huaheng.framework.web.service.ConfigService;
import com.huaheng.pc.config.configValue.domain.ConfigValue;
import com.huaheng.pc.config.configValue.service.ConfigValueService;
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.service.ContainerCapacityService;
import com.huaheng.pc.config.cycleCountPreference.domain.CycleCountPreference;
import com.huaheng.pc.config.cycleCountPreference.service.CycleCountPreferenceService;
import com.huaheng.pc.config.location.domain.Location;
import com.huaheng.pc.config.location.service.LocationService;
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.service.InventoryTransactionService;
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.service.ReceiptDetailService;
import com.huaheng.pc.receipt.receiptHeader.service.ReceiptHeaderService;
import com.huaheng.pc.receipt.receiving.service.ReceivingService;
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.service.ShipmentDetailService;
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.TaskHeader;
import com.huaheng.pc.task.taskHeader.mapper.TaskHeaderMapper;
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 ReceiptContainerDetailService receiptContainerDetailService;
    @Resource
    private CycleCountDetailService cycleCountDetailService;
    @Resource
    private CycleCountPreferenceService cycleCountPreferenceService;
    @Resource
    private CycleCountTaskService cycleCountTaskService;
    @Resource
    private ReceiptContainerHeaderService receiptContainerHeaderService;
    @Resource
    private TaskHeaderMapper taskHeaderMapper;
    @Autowired
    private TaskAssignService taskAssignService;
    @Resource
    private ReceiptTaskService receiptTaskService;
    @Resource
    private ShipmentTaskService shipmentTaskService;
    @Resource
    private WorkTaskService workTaskService;
    @Resource
    private TransferTaskService transferTaskService;
    @Resource
    private ReceivingService receivingService;
    @Resource
    private ConfigService configService;



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


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


    /**
     * 盘点任务首选项
     *
     * @param taskHeaderList
     * @return
     */
    @Override
    public List<TaskHeader> preferenceRealize(List<TaskHeader> taskHeaderList) {
        //盘点任务头,默认不显示库位,容器。
        List<TaskHeader> taskHeaders = new ArrayList<>();
        for (TaskHeader item:taskHeaderList){
            //盘点明细
            CycleCountDetail cycleCountDetailtemp = new CycleCountDetail();
            cycleCountDetailtemp.setWarehouseCode(item.getWarehouseCode());
            cycleCountDetailtemp.setCycleCountHeadCode(item.getReferenceCode());
            cycleCountDetailtemp.setId(item.getAllocationHeadId());  //明细ID
            LambdaQueryWrapper<CycleCountDetail> detailLambdaQueryWrapper = Wrappers.lambdaQuery(cycleCountDetailtemp);
            CycleCountDetail cycleCountDetail = cycleCountDetailService.getOne(detailLambdaQueryWrapper);
            if(StringUtils.isNull(cycleCountDetail)){
                throw new SecurityException("没有找到子任务对应的盘点明细!");
            }
            //找盘点首选项
            CycleCountPreference cycleCountPreferenceTemp = new CycleCountPreference();
            cycleCountPreferenceTemp.setCode(cycleCountDetail.getPreferenceCode());
            cycleCountPreferenceTemp.setWarehouseCode(cycleCountDetail.getWarehouseCode());
            LambdaQueryWrapper<CycleCountPreference> preferenceLambdaQueryWrapper = Wrappers.lambdaQuery(cycleCountPreferenceTemp);
            CycleCountPreference cycleCountPreference = cycleCountPreferenceService.getOne(preferenceLambdaQueryWrapper);
            if(StringUtils.isNull(cycleCountPreference)){
                throw new SecurityException("没有找到盘点首选项!");
            }
            //根据首选项判断数据
            if(!cycleCountPreference.getPromptLocation()){
                //库位
                item.setFromLocation("");
                item.setToLocation("");
            }
            if(!cycleCountPreference.getPromptLpn()){
                //容器
                item.setContainerCode("");
            }
            taskHeaders.add(item);
        }
        return taskHeaders;
    }

    /**
     * 取消任务
     */
    @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 = null;
            if(taskDetailList != null && taskDetailList.size() > 0) {
                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.getTaskType().equals(QuantityConstant.TASK_TYPE_WHOLERECEIPT) ||
                    taskHeader.getTaskType().equals(QuantityConstant.TASK_TYPE_SUPPLEMENTRECEIPT)) {
                receiptContainerHeaderService.cancelReceipt(taskHeader.getAllocationHeadId());
            }
            //根据任务类型来更新货箱状态
            //修改关联的货箱状态
            if (taskHeader.getInternalTaskType().equals(QuantityConstant.TASK_INTENERTYPE_SHIPMENT)) {
                ShipmentContainerHeader shipmentContainerHeader = new ShipmentContainerHeader();
                shipmentContainerHeader.setId(taskHeader.getAllocationHeadId());
                shipmentContainerHeader.setStatus(QuantityConstant.SHIPMENT_CONTAINER_BUILD);
                shipmentContainerHeaderService.updateById(shipmentContainerHeader);
            }
            //盘点取消任务,恢复明细状态为1
            int taskType = taskHeader.getTaskType().intValue();
            switch (taskType) {
                case QuantityConstant.TASK_TYPE_WHOLERECEIPT:
                case QuantityConstant.TASK_TYPE_SUPPLEMENTRECEIPT:
                    LambdaQueryWrapper<ReceiptContainerHeader> lambda = Wrappers.lambdaQuery();
                    lambda.eq(ReceiptContainerHeader::getContainerCode, taskHeader.getContainerCode())
                            .ne(ReceiptContainerHeader::getStatus, QuantityConstant.RECEIPT_CONTAINER_FINISHED)
                            .eq(ReceiptContainerHeader::getWarehouseCode, ShiroUtils.getWarehouseCode());
                    ReceiptContainerHeader receiptContainerHeader = receiptContainerHeaderService.getOne(lambda);
                    String value = configService.getKey(QuantityConstant.RULE_TASK_LOCATION);
                    int taskLocationRule = Integer.parseInt(value);
                    if (taskLocationRule == QuantityConstant.RULE_TASK_NOT_LOCATION) {
                        receiptContainerHeader.setToLocation("");
                        receiptContainerHeaderService.update(receiptContainerHeader, lambda);
                    }
                    LambdaQueryWrapper<ReceiptContainerDetail> receiptContainerDetailLambdaQueryWrapper = Wrappers.lambdaQuery();
                    receiptContainerDetailLambdaQueryWrapper.eq(ReceiptContainerDetail::getReceiptContainerId, receiptContainerHeader.getId());
                    List<ReceiptContainerDetail> receiptContainerDetailList = receiptContainerDetailService.list(receiptContainerDetailLambdaQueryWrapper);
                    for(ReceiptContainerDetail receiptContainerDetail : receiptContainerDetailList) {
                        LambdaQueryWrapper<ReceiptContainerDetail> receiptContainerDetailLambdaQueryWrapper1 = Wrappers.lambdaQuery();
                        receiptContainerDetailLambdaQueryWrapper1.eq(ReceiptContainerDetail::getId, receiptContainerDetail.getId());
                        receiptContainerDetail.setLocationCode("");
                        receiptContainerDetailService.update(receiptContainerDetail, receiptContainerDetailLambdaQueryWrapper1);
                    }
                    break;
                case QuantityConstant.TASK_TYPE_WHOLESHIPMENT:
                case QuantityConstant.TASK_TYPE_SORTINGSHIPMENT:

                    break;
                case QuantityConstant.TASK_TYPE_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);
                    }
                    break;
                default:
                    break;
            }
            cancelLocationAndContainerStatus(taskHeader);
        }
        return AjaxResult.success("取消任务成功!");
    }

    private void cancelLocationAndContainerStatus(TaskHeader taskHeader) {
        if (taskHeader.getFromLocation() != null) {
            //更新托盘、库位状态
            locationService.updateStatus(taskHeader.getFromLocation(), QuantityConstant.STATUS_LOCATION_EMPTY);
        }
        if (taskHeader.getToLocation() != null) {
            //更新托盘、库位状态
            locationService.updateStatus(taskHeader.getToLocation(), QuantityConstant.STATUS_LOCATION_EMPTY);
        }
        LambdaQueryWrapper<InventoryHeader> inventoryHeaderLambdaQueryWrapper = Wrappers.lambdaQuery();
        inventoryHeaderLambdaQueryWrapper.eq(InventoryHeader::getContainerCode, taskHeader.getContainerCode());
        InventoryHeader inventoryHeader = inventoryHeaderService.getOne(inventoryHeaderLambdaQueryWrapper);
        Container container = new Container();
        container.setStatus(QuantityConstant.STATUS_CONTAINER_EMPTY);
        if(inventoryHeader != null) {
            if(QuantityConstant.STATUS_CONTAINER_SOME.equals(inventoryHeader.getContainerStatus())) {
                container.setStatus(QuantityConstant.STATUS_CONTAINER_SOME);
            }
        }
        container.setLocationCode(taskHeader.getFromLocation());
        LambdaUpdateWrapper<Container> containerUpdateWrapper = Wrappers.lambdaUpdate();
        containerUpdateWrapper.eq(Container::getCode, taskHeader.getContainerCode());
        containerService.update(container, containerUpdateWrapper);
    }

    /**
     * 下发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 + "已经下发,请不要重复下发,操作中止");
            }

            String value = configService.getKey(QuantityConstant.RULE_CONNECT_WCS);
            int connectWCS = Integer.parseInt(value);
            if(connectWCS == QuantityConstant.RULE_WCS_CONNECT) {
                // 给wcs传递任务
                AjaxResult ajaxResult = taskAssignService.wcsTaskAssign(task);
                if (ajaxResult != null && ajaxResult.hasErr()) {
                    return AjaxResult.error(ajaxResult.getMsg());
                }
            }
            //修改任务头表
            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);
    }

    /**
     * WMS完成任务
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    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) {
        int taskType = task.getTaskType().intValue();
        //区分任务类型
        switch(taskType) {
            //整盘入库、补充入库
            case QuantityConstant.TASK_TYPE_WHOLERECEIPT:
            case QuantityConstant.TASK_TYPE_SUPPLEMENTRECEIPT:
                receiptTaskService.completeReceiptTask(task);
                combineInventory(task);
                break;
            //整盘出库、分拣出库
            case QuantityConstant.TASK_TYPE_WHOLESHIPMENT:
            case QuantityConstant.TASK_TYPE_SORTINGSHIPMENT:
                shipmentTaskService.completeShipmentTask(task);
                combineInventory(task);
                break;
            //空托入库
            case QuantityConstant.TASK_TYPE_EMPTYRECEIPT:
                workTaskService.completeEmptyIn(task);
                break;
            //空托出库
            case QuantityConstant.TASK_TYPE_EMPTYSHIPMENT:
                workTaskService.completeEmptyOut(task);
                break;
            case QuantityConstant.TASK_TYPE_CYCLECOUNT:
                cycleCountTaskService.completeCycleCountTask(task);
                break;
            case QuantityConstant.TASK_TYPE_TRANSFER:
                transferTaskService.completeTransferTask(task);
                break;
            case QuantityConstant.TASK_TYPE_VIEW:
                workTaskService.completeCheckOutTask(task);
                break;
            default:
                throw new ServiceException("不支持的任务类型");
        }
    }

    /**
     * 根据库位完成任务
     *
     * @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)
                .lt(TaskHeader::getStatus, QuantityConstant.TASK_STATUS_COMPLETED);
        List<TaskHeader> list = this.list(taskQueryWrapper);
        if (list.isEmpty()) {
            throw new ServiceException("库位(" + locationCode + ")没有任务!");
        } else if(list.get(0).getStatus().equals(QuantityConstant.TASK_STATUS_COMPLETED)) {
            //如果已完成则不管
            throw new ServiceException("库位(" + locationCode + ")任务已经完成!");
        }
        TaskHeader taskHeader = list.get(0);
        int taskType = taskHeader.getTaskType().intValue();
        if(taskType == QuantityConstant.TASK_TYPE_WHOLERECEIPT
                || taskType == QuantityConstant.TASK_TYPE_SUPPLEMENTRECEIPT){
            //入库任务
            return receiptTaskService.completeReceiptTask(taskHeader);
        } 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;
    }

    /**
     * 容器收货上架
     *
     * @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("生成入库任务失败");
    }




    @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.getToLocation())
                    .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--) {
                    InventoryDetail inventoryDetail = inventoryDetailList.get(i);
                    InventoryDetail inventoryDetail2 = inventoryDetailList.get(j);
                    if(inventoryDetail.getMaterialCode().equals(inventoryDetail2.getMaterialCode())
                            && inventoryDetail.getBatch().equals(inventoryDetail2.getBatch())
                            && inventoryDetail.getLot().equals(inventoryDetail2.getLot())
                            && inventoryDetail.getProjectNo().equals(inventoryDetail2.getProjectNo())) {
                        BigDecimal totalQty = inventoryDetailList.get(i).getQty().add(inventoryDetailList.get(j).getQty());
                        inventoryDetailList.get(i).setQty(totalQty);
                        LambdaQueryWrapper<InventoryDetail> wrapper = Wrappers.lambdaQuery();
                        wrapper.eq(InventoryDetail::getId, inventoryDetailList.get(i).getId());
                        inventoryDetailService.update(inventoryDetailList.get(i), wrapper);
                        LambdaQueryWrapper<InventoryDetail> wrapper2 = Wrappers.lambdaQuery();
                        wrapper2.eq(InventoryDetail::getId, inventoryDetailList.get(j).getId());
                        inventoryDetailService.remove(wrapper2);
                        inventoryDetailList.remove(j);
                    }
                }
            }
            BigDecimal totalQty = new BigDecimal(0);
            int totalLines = 0;
            for(InventoryDetail inventoryDetail : inventoryDetailList) {
                totalQty = totalQty.add(inventoryDetail.getQty());
                totalLines++;
            }
            header.setTotalQty(totalQty);
            header.setTotalLines(totalLines);
            header.setContainerStatus(QuantityConstant.STATUS_CONTAINER_SOME);
            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().equals(ShiroUtils.getWarehouseCode())) {
            throw new ServiceException("容器不在当前仓库!");
        }
        List<Integer> idList = new ArrayList<>();
        idList.add(receiptContainerHeader.getId());
        receiptTaskService.createReceiptTask(idList);

        return AjaxResult.success(receiptContainerHeader);
    }

    /**
     * 自动空托出库
     * */
    @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,QuantityConstant.STATUS_LOCATION_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(), QuantityConstant.STATUS_LOCATION_LOCK);
        //给组盘分配库位

        int internalTaskType = taskHeader.getInternalTaskType();
        if(internalTaskType == QuantityConstant.TASK_TYPE_WHOLERECEIPT || internalTaskType == QuantityConstant.TASK_TYPE_SUPPLEMENTRECEIPT) {
            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);
            List<TaskDetail> taskDetailList = taskDetailService.list(taskDetailLambdaQueryWrapper);
            if(taskDetailList != null && taskDetailList.size() > 0) {
                for(TaskDetail taskDetail : taskDetailList) {
                    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());

    }

    @Override
    public int getUncompleteTaskInNear(Location location) {
        Location location1 = locationService.getNear(location);
        if(location1 == null) {
            return  0;
        }
        String locationCode = location1.getCode();
        LambdaQueryWrapper<TaskHeader> taskHeaderLambdaQueryWrapper = Wrappers.lambdaQuery();
        taskHeaderLambdaQueryWrapper.eq(TaskHeader::getToLocation, locationCode)
                                    .lt(TaskHeader::getStatus, QuantityConstant.TASK_STATUS_COMPLETED);
        List<TaskHeader> taskHeaderList = taskHeaderService.list(taskHeaderLambdaQueryWrapper);
        if(taskHeaderList == null || taskHeaderList.size() == 0) {
            taskHeaderLambdaQueryWrapper = Wrappers.lambdaQuery();
            taskHeaderLambdaQueryWrapper.eq(TaskHeader::getFromLocation, locationCode)
                    .lt(TaskHeader::getStatus, QuantityConstant.TASK_STATUS_COMPLETED);
            taskHeaderList = taskHeaderService.list(taskHeaderLambdaQueryWrapper);
            if(taskHeaderList == null || taskHeaderList.size() == 0) {
                return 0;
            }
        }
        return taskHeaderList.size();
    }

    @Override
    public List<TaskHeader> remoteList(){
        LambdaQueryWrapper<TaskHeader> wrapper = Wrappers.lambdaQuery();
        wrapper.ge(TaskHeader::getStatus,QuantityConstant.TASK_STATUS_RELEASE)
                .lt(TaskHeader::getStatus,QuantityConstant.TASK_STATUS_COMPLETED);
        return list(wrapper);
    }
}