WCS
dengjunjie
2024-10-17 a38b50675f2cf8e813bd337ca2f9d9456cc421d3
ÏîÄ¿´úÂë/WMS/WIDESEA_WMSServer/WIDESEA_BusinessServices/Dt_InboundOrderService.cs
@@ -1,7 +1,5 @@
using log4net.Layout;
using SkiaSharp;
using SqlSugar.SplitTableExtensions;
using System.Data;
using System.Data;
using System.Text;
using WIDESEA_Core;
using WIDESEA_Core.BaseRepository;
using WIDESEA_Core.BaseServices;
@@ -9,14 +7,15 @@
using WIDESEA_DTO;
using WIDESEA_IBusinessesRepository;
using WIDESEA_IBusinessServices;
using WIDESEA_IStorageBasicRepository;
using WIDESEA_IStorageTaskRepository;
using WIDESEA_Model.Models;
using WIDESEA_Repository;
namespace WIDESEA_BusinessServices
{
    public class Dt_InboundOrderService : ServiceBase<Dt_InboundOrder, IDt_InboundOrderRepository>, IDt_InboundOrderService
    {
        #region éœ€æ³¨å…¥æŽ¥å£
        #region æŽ¥å£
        private readonly IUnitOfWorkManage _unitOfWorkManage;
        private readonly IDt_InboundOrderDetailRepository _dt_InboundOrderDetailRepository;
        private readonly IDt_InboundOrderProductionRepository _dt_InboundOrderProductionRepository;
@@ -30,9 +29,11 @@
        private readonly IDt_MaterielInfoRepository _dt_MaterielInfoRepository;
        private readonly IDt_WareAreaInfoRepository _dt_WareAreaInfoRepository;
        private readonly IDt_StrategyRepository _dt_StrategyRepository;
        private readonly IDt_LocationInfoRepository _dt_LocationInfoRepository;
        private readonly IDt_LocationRepository _dt_LocationInfoRepository;
        private readonly IDt_TaskRepository _dt_TaskRepository;
        private readonly IDt_Task_HtyRepository _dt_Task_HtyRepository;
        private readonly IDt_TaskExecuteDetailRepository _dt_TaskExecuteDetailRepository;
        private readonly IDt_TypeMappingRepository _dt_TypeMappingRepository;
        private readonly IDt_RoadWayInfoRepository _dt_RoadWayInfoRepository;
        #endregion
@@ -41,9 +42,9 @@
            IDt_InboundOrderProductionService dt_InboundOrderProductionService, IDt_InboundOrderProductionRepository dt_InboundOrderProductionRepository,
            IDt_InboundOrderPurchaseRepository dt_InboundOrderPurchaseRepository, IDt_InboundOrderPurchaseService dt_InboundOrderPurchaseService,
            IDt_BillGroupStockDetailRepository dt_BillGroupStockDetailRepository, IDt_MaterielInfoRepository dt_MaterielInfoRepository,
            IDt_WareAreaInfoRepository dt_WareAreaInfoRepository, IDt_StrategyRepository dt_StrategyRepository, IDt_LocationInfoRepository dt_LocationInfoRepository,
            IDt_BillGroupStockRepository dt_BillGroupStockRepository, IDt_TaskRepository dt_TaskRepository, IDt_TaskExecuteDetailRepository dt_TaskExecuteDetailRepository
            , IDt_RoadWayInfoRepository dt_RoadWayInfoRepository) : base(BaseDal)
            IDt_WareAreaInfoRepository dt_WareAreaInfoRepository, IDt_StrategyRepository dt_StrategyRepository, IDt_LocationRepository dt_LocationInfoRepository,
            IDt_BillGroupStockRepository dt_BillGroupStockRepository, IDt_TaskRepository dt_TaskRepository, IDt_TaskExecuteDetailRepository dt_TaskExecuteDetailRepository,
            IDt_RoadWayInfoRepository dt_RoadWayInfoRepository, IDt_TypeMappingRepository dt_TypeMappingRepository, IDt_Task_HtyRepository dt_Task_HtyRepository) : base(BaseDal)
        {
            _unitOfWorkManage = unitOfWorkManage;
            _dt_InboundOrderDetailRepository = dt_InboundOrderDetailRepository;
@@ -60,6 +61,8 @@
            _dt_TaskRepository = dt_TaskRepository;
            _dt_TaskExecuteDetailRepository = dt_TaskExecuteDetailRepository;
            _dt_RoadWayInfoRepository = dt_RoadWayInfoRepository;
            _dt_TypeMappingRepository = dt_TypeMappingRepository;
            _dt_Task_HtyRepository = dt_Task_HtyRepository;
        }
        /// <summary>
        /// åŒæ­¥ç”Ÿäº§å…¥åº“原始单据到本系统入库单表,并更新原始单据的同步标志
@@ -68,7 +71,7 @@
        /// <returns></returns>
        public async Task<WebResponseContent> GetInboundOrderFromProductionOrigin()
        {
            WebResponseContent content = new WebResponseContent();
            WebResponseContent webResponseContent = new WebResponseContent();
            new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "生产入库单同步-GetInboundOrderFromProductionOrigin", "请求", "无参数");
            List<Dt_InboundOrderProduction> Dt_InboundOrderProductionList = await _dt_InboundOrderProductionService.GetDt_InboundOrderProduction((int)SynchronizationFlagEmun.未同步);
@@ -83,8 +86,7 @@
                    #region å…¥åº“原始单据主表校验,单据转换为本系统入库单主表
                    //todo:此处做原始单据主表字段校验
                    Dt_InboundOrder dt_InboundOrder = new Dt_InboundOrder();
                    dt_InboundOrder.OrderId = Guid.NewGuid();
                    dt_InboundOrder.InboundNo = dt_InboundOrder.OrderId.ToString();//todo:调用自动生成单号方法
                    dt_InboundOrder.InboundNo = GenerateOrderNumber("R",DateTime.Now);
                    dt_InboundOrder.InboundUpperNo = mainItem.ProductionNo;
                    dt_InboundOrder.BatchNo = mainItem.BatchNo;
                    dt_InboundOrder.InboundDate = mainItem.CreateDate;
@@ -99,7 +101,7 @@
                    {
                        //todo:此处做原始单据明细字段校验
                        Dt_InboundOrderDetail dt_InboundOrderDetail = new Dt_InboundOrderDetail();
                        dt_InboundOrderDetail.OrderDetailId = Guid.NewGuid();
                        //dt_InboundOrderDetail.OrderDetailId = Guid.NewGuid();
                        dt_InboundOrderDetail.OrderId = mainItem.OrderId;
                        dt_InboundOrderDetail.InboundNo = dt_InboundOrder.InboundNo;
                        dt_InboundOrderDetail.BatchNo = dt_InboundOrder.BatchNo;
@@ -123,6 +125,7 @@
                        //提交事务
                        _unitOfWorkManage.CommitTran();
                        new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "生产入库单同步-GetInboundOrderFromProductionOrigin", "响应", "同步成功");
                        webResponseContent.Error($"同步成功");
                    }
                    catch (Exception)
                    {
@@ -136,11 +139,12 @@
                    mainItem.Remark = ex.Message;//记录失败原因
                    _dt_InboundOrderProductionRepository.UpdateData(mainItem);
                    new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "生产入库单同步-GetInboundOrderFromProductionOrigin", "响应", $"同步失败{ex.ToString()}");
                    webResponseContent.Error($"同步失败{ex.ToString()}");
                }
            }
            return WebResponseContent.Instance.OK();
            return webResponseContent;
        }
@@ -152,7 +156,7 @@
        /// <returns></returns>
        public async Task<WebResponseContent> GetInboundOrderFromPurchaseOrigin()
        {
            WebResponseContent content = new WebResponseContent();
            WebResponseContent webResponseContent = new WebResponseContent();
            new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "采购入库单同步-GetInboundOrderFromProductionOrigin", "请求", "无参数");
            List<Dt_InboundOrderPurchase> Dt_InboundOrderPurchaseList = await _dt_InboundOrderPurchaseService.GetDt_InboundOrderPurchase((int)SynchronizationFlagEmun.未同步);
@@ -166,8 +170,8 @@
                    #region å…¥åº“原始单据主表校验,单据转换为本系统入库单主表
                    //todo:此处做原始单据主表字段校验
                    Dt_InboundOrder dt_InboundOrder = new Dt_InboundOrder();
                    dt_InboundOrder.OrderId = Guid.NewGuid();
                    dt_InboundOrder.InboundNo = dt_InboundOrder.OrderId.ToString();//todo:调用自动生成单号方法
                    //dt_InboundOrder.OrderId = Guid.NewGuid();
                    dt_InboundOrder.InboundNo = GenerateOrderNumber("R", DateTime.Now);
                    dt_InboundOrder.InboundUpperNo = mainItem.PurchaseNo;
                    dt_InboundOrder.BatchNo = mainItem.BatchNo;
                    dt_InboundOrder.InboundDate = mainItem.CreateDate;
@@ -182,15 +186,14 @@
                    {
                        //todo:此处做原始单据明细字段校验
                        Dt_InboundOrderDetail dt_InboundOrderDetail = new Dt_InboundOrderDetail();
                        dt_InboundOrderDetail.OrderDetailId = Guid.NewGuid();
                        dt_InboundOrderDetail.OrderId = mainItem.OrderId;
                        dt_InboundOrderDetail.InboundNo = dt_InboundOrder.InboundNo;
                        dt_InboundOrderDetail.BatchNo = dt_InboundOrder.BatchNo;
                        dt_InboundOrderDetail.InboundType = dt_InboundOrder.InboundType;
                        dt_InboundOrderDetail.InboundState = dt_InboundOrder.InboundState;
                        dt_InboundOrderDetail.MaterialNo = detailItem.ProductionMatcode;
                        dt_InboundOrderDetail.MaterialName = detailItem.ProductionName;
                        dt_InboundOrderDetail.PreInboundQuantity = detailItem.ReceivableQuantity;
                        dt_InboundOrderDetail.MaterialNo = detailItem.PurchaseMatcode;
                        dt_InboundOrderDetail.MaterialName = detailItem.PurchaseName;
                        dt_InboundOrderDetail.PreInboundQuantity = detailItem.PurchaseQty;
                        Dt_InboundOrderDetailList.Add(dt_InboundOrderDetail);
                    }
                    #endregion
@@ -205,6 +208,8 @@
                        _dt_InboundOrderPurchaseRepository.UpdateData(mainItem);
                        //提交事务
                        _unitOfWorkManage.CommitTran();
                        new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "采购入库单同步-GetInboundOrderFromPurchaseOrigin", "响应", "同步成功");
                        webResponseContent.Error($"同步成功");
                    }
                    catch (Exception)
                    {
@@ -218,17 +223,16 @@
                    mainItem.Remark = ex.Message;//记录失败原因
                    _dt_InboundOrderPurchaseRepository.UpdateData(mainItem);
                    new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "采购入库单同步-GetInboundOrderFromProductionOrigin", "响应", $"同步失败{ex.ToString()}");
                    webResponseContent.Error($"同步失败{ex.ToString()}");
                }
            }
            return WebResponseContent.Instance.OK();
            return webResponseContent;
        }
        /// äº§ç”Ÿå…¥åº“任务 åˆ†é…å··é“
        /// 1,根据物料属性指定库区
        /// 2,查询满足条件的空闲货位的巷道:空闲货位占比 ç‰©æ–™åº“存占比
        /// <summary>
        /// ç”Ÿæˆå…¥åº“任务 åˆ†é…å··é“
        /// </summary>
        /// <param name="plateCode">托盘条码</param>
        /// <param name="SourceAddress">起始地址</param>
@@ -238,117 +242,95 @@
            WebResponseContent webResponseContent = new WebResponseContent();
            try
            {
               //任务号不能重复
               List<Dt_Task> dttasks  =_dt_TaskRepository.QueryData(x => x.PalletCode == plateCode && x.TaskState != (int)InTaskStatusEnum.InFinish && x.TaskType >= 200 && x.TaskType <= 203);
                if(dttasks!=null&& dttasks.Count > 0)
                {
                    webResponseContent.OK("托盘号存在重复的入库任务!");
                }
                new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "产生入库任务并分配巷道-GenerateInboundTask", "请求", $"plateCode:{plateCode}-SourceAddress:{SourceAddress}");
                List<RoadWayDTO> roadWays = new List<RoadWayDTO>();
                //根据托盘码查询物料编码
                List<Dt_BillGroupStock> billGroup = _dt_BillGroupStockRepository.QueryData(x => x.PalletCode == plateCode && x.State == StockStateEmun.组盘暂存.ToString());
                List<Dt_InboundOrder> inboundOrders = new List<Dt_InboundOrder>();
                if (billGroup != null && billGroup.Count == 1)
                Dt_BillGroupStock billGroupStock = new Dt_BillGroupStock();
                //1,根据托盘号查询组盘信息
                List<Dt_BillGroupStock> billGroup = Db.Queryable<Dt_BillGroupStock>().Includes(x => x.Dt_BillGroupStockDetailList).Where(x => x.PalletCode == plateCode && x.State == (int)StockStateEmun.组盘暂存).ToList();
                if (billGroup != null && billGroup.Count > 0)
                {
                    //根据物料编码,查询物料属性
                    List<Dt_MaterielInfo> masterielInfoList = _dt_MaterielInfoRepository.QueryData(x => x.MaterielCode == billGroup[0].MaterialNo);
                    if (masterielInfoList != null && masterielInfoList.Count > 0)
                    billGroupStock = billGroup[0];
                    //根据物料编码,查询物料信息(所属库区)
                    List<Dt_MaterielInfo> masterielInfos = _dt_MaterielInfoRepository.QueryData(x => x.MaterielCode == billGroupStock.MaterialNo);
                    if (masterielInfos != null && masterielInfos.Count > 0)
                    {
                        //查询巷道分配策略
                        List<Dt_Strategy> strategyList = _dt_StrategyRepository.QueryData(x => x.StrategyType == "InboundRoadway" && x.IsPreset == true);
                        if (strategyList != null && strategyList.Count > 0)
                        //获取空闲货位列表 todo:需考虑货位禁用的情况
                        var roadWayList = _dt_LocationInfoRepository.QueryData(x => x.Status == (int)LocationEnum.Free && x.WareAreaCode == masterielInfos[0].WareAreaCode.ToString()).GroupBy(x => x.Roadway).OrderByDescending(group => group.Count()).ToList();
                        foreach (var item in roadWayList)
                        {
                            string strategyName = strategyList[0].StrategyName;
                            if (strategyName == "空闲货位占比")//todo:策略名称,这里可以在数据库中配置策略后,在这里根据不同的策略来处理
                            //去掉禁用的巷道
                            Dt_RoadWayInfo roadway = _dt_RoadWayInfoRepository.QueryData(x => x.RoadWayNO == item.Key).FirstOrDefault();
                            if (roadway != null && roadway.IsEnable == false)
                            {
                                //获取空闲货位降序列表
                                var roadWayList = _dt_LocationInfoRepository.QueryData(x => x.Status == (int)LocationStatus.空闲 && x.WareAreaCode == masterielInfoList[0].WareAreaCode.ToString()).GroupBy(x => x.Roadway).OrderByDescending(group => group.Count()).ToList(); // è®¡ç®—每个分组的数量
                                foreach (var item in roadWayList)
                                {
                                    //去掉禁用的巷道
                                   Dt_RoadWayInfo roadway=  _dt_RoadWayInfoRepository.QueryData(x => x.RoadWayNO == item.Key).FirstOrDefault();
                                    if (roadway != null&&roadway.IsEnable==false)
                                    {
                                        continue;
                                    }
                                    //查询巷道任务数
                                    int taskCount = _dt_TaskRepository.QueryData(x => x.Roadway == item.Key && (x.TaskState == TaskStatusEmun.新建入库任务.ToString() || x.TaskState == TaskStatusEmun.AGV入库执行中.ToString() || x.TaskState == TaskStatusEmun.输送线入库执行中.ToString())).Count();
                                    RoadWayDTO roadWayDTO = new RoadWayDTO();
                                    roadWayDTO.RoadWayNO = item.Key;
                                    roadWayDTO.FreeLocationCount = item.Count();
                                    roadWayDTO.TaskCount = taskCount;
                                    roadWays.Add(roadWayDTO);
                                }
                                //按空闲货大到小排序,优先取任务数为0的,再选任务数小于平均数的的巷道,最后默认取第一条空闲货位最多的
                                decimal taskSum = roadWays.Sum(x => x.TaskCount);
                                decimal avgQTY = roadWays.Count() == 0 ? 0 : taskSum / roadWays.Count();
                                string roadWay = "";
                                //todo:根据巷道任务数和空闲数返回巷道号
                                foreach (var item in roadWays)
                                {
                                    if (item.TaskCount == 0)
                                    {
                                        roadWay = item.RoadWayNO;
                                        break;
                                    }
                                    else if (item.TaskCount <= avgQTY)
                                    {
                                        roadWay = item.RoadWayNO;
                                        break;
                                    }
                                    else
                                    {
                                        roadWay = roadWays[0].RoadWayNO;
                                        break;
                                    }
                                }
                                //查询对应的入库单,用于取值入库单类型
                                inboundOrders = BaseDal.QueryData(x => x.InboundNo == billGroup[0].InboundNo);
                                try
                                {
                                    //开启事物
                                    _unitOfWorkManage.BeginTran();
                                    //生成任务,并返回任务
                                    Dt_Task dt_Task = new Dt_Task();
                                    dt_Task.TaskId = Guid.NewGuid();
                                    dt_Task.TaskNum = GetTaskNo();
                                    dt_Task.PalletCode = plateCode;
                                    dt_Task.InboundNo = billGroup[0].InboundNo;
                                    dt_Task.Roadway = roadWay;
                                    dt_Task.TaskType = inboundOrders[0].InboundType;
                                    dt_Task.TaskState = TaskStatusEmun.新建入库任务.ToString();
                                    dt_Task.MaterialNo = billGroup[0].MaterialNo;
                                    dt_Task.SourceAddress = SourceAddress;
                                    dt_Task.Dispatchertime = DateTime.Now;
                                    _dt_TaskRepository.AddData(dt_Task);
                                    //初始化任务执行明细
                                    List<Dt_TaskExecuteDetail> dt_TaskExecuteDetails = new List<Dt_TaskExecuteDetail>();
                                    Dt_TaskExecuteDetail dt_TaskExecuteDetail = new Dt_TaskExecuteDetail();
                                    dt_TaskExecuteDetail.TaskDetailId = Guid.NewGuid();
                                    dt_TaskExecuteDetail.TaskId = dt_Task.TaskId;
                                    dt_TaskExecuteDetail.TaskNum = dt_Task.TaskNum.ToString();
                                    dt_TaskExecuteDetail.TaskState = dt_Task.TaskState;
                                    dt_TaskExecuteDetail.IsManual = false;
                                    dt_TaskExecuteDetails.Add(dt_TaskExecuteDetail);
                                    _dt_TaskExecuteDetailRepository.AddData(dt_TaskExecuteDetail);
                                    dt_Task.Dt_TaskExecuteDetailList = dt_TaskExecuteDetails;
                                    //提交事物
                                    _unitOfWorkManage.CommitTran();
                                    webResponseContent.OK("获取巷道号成功!", dt_Task);
                                }
                                catch (Exception)
                                {
                                    _unitOfWorkManage.RollbackTran();
                                    throw;
                                }
                                continue;
                            }
                            //查询巷道新建的和正在执行中的任务数
                            int taskCount = _dt_TaskRepository.QueryData(x => x.Roadway == item.Key && (x.TaskState == (int)InTaskStatusEnum.InNew || x.TaskState == (int)InTaskStatusEnum.AGV_InExecuting || x.TaskState == (int)InTaskStatusEnum.Line_InExecuting || x.TaskState == (int)InTaskStatusEnum.SC_InExecuting)).Count();
                            RoadWayDTO roadWayDTO = new RoadWayDTO();
                            roadWayDTO.RoadWayNO = item.Key;
                            roadWayDTO.FreeLocationCount = item.Count();
                            roadWayDTO.TaskCount = taskCount;
                            roadWayDTO.PreFreeLocationCount = roadWayDTO.FreeLocationCount - roadWayDTO.TaskCount;
                            roadWays.Add(roadWayDTO);
                        }
                        else
                        if(roadWays.Count == 0)
                        {
                            new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "产生入库任务并分配巷道-GenerateInboundTask", "响应", $"plateCode:{plateCode}-无此物料基本信息,请配置分配巷道策略!");
                            webResponseContent.Error($"plateCode:{plateCode}-无此物料基本信息,请配置分配巷道策略!");
                            webResponseContent.OK("未获取到巷道号列表!");
                        }
                        //根据预计货位空闲数(货位空闲数-巷道当前任务数),获取项道号
                        string roadWay = roadWays.OrderByDescending(roadway => roadway.PreFreeLocationCount).FirstOrDefault().RoadWayNO;
                        //查询对应的入库单,用于取值入库单类型
                        inboundOrders = BaseDal.QueryData(x => x.InboundNo == billGroupStock.OrderNo);
                        if (inboundOrders.Count == 0)
                        {
                            return webResponseContent.Error($"未查询到当前拖盘号为{plateCode} å¯¹åº”的入库单!");
                        }
                        //通过单据类型获取任务类型
                        List<Dt_TypeMapping> typeMappings = _dt_TypeMappingRepository.QueryData(x => x.OrderType == inboundOrders[0].InboundType).ToList();
                        if (typeMappings.Count == 0)
                        {
                            return webResponseContent.Error($"未配置单据类型对应的任务类型!");
                        }
                        try
                        {
                            //生成任务
                            Dt_Task dt_Task = new Dt_Task();
                            #region ç”Ÿæˆä»»åŠ¡
                            dt_Task.TaskNum = GetTaskNo();
                            dt_Task.PalletCode = plateCode;
                            dt_Task.GroupID = billGroupStock.GroupId;
                            dt_Task.InboundNo = billGroupStock.OrderNo;
                            dt_Task.Roadway = roadWay;
                            dt_Task.TaskType = typeMappings[0].OrderType;
                            dt_Task.TaskState = (int)InTaskStatusEnum.InNew;
                            dt_Task.MaterialNo = billGroupStock.MaterialNo;
                            dt_Task.SourceAddress = SourceAddress;
                            dt_Task.Dispatchertime = DateTime.Now;
                            #endregion
                            _dt_TaskRepository.AddData(dt_Task);
                            //开启事物
                            _unitOfWorkManage.BeginTran();
                            _dt_TaskRepository.AddData(dt_Task);
                            //库存状态 æ”¹ä¸º å…¥åº“确认状态
                            billGroupStock.State = (int)StockStateEmun.入库确认;
                            _dt_BillGroupStockRepository.UpdateData(billGroupStock);
                            //提交事物
                            _unitOfWorkManage.CommitTran();
                            webResponseContent.OK("获取巷道号成功!", dt_Task);
                        }
                        catch (Exception)
                        {
                            _unitOfWorkManage.RollbackTran();
                            throw;
                        }
                    }
                    else
@@ -358,19 +340,188 @@
                    }
                }
            }
            catch(Exception ex)
            catch (Exception ex)
            {
                new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "产生入库任务并分配巷道-GenerateInboundTask", "响应", $"当前拖盘号为{plateCode}获取失败{ex.ToString()}");
                webResponseContent.Error($"当前拖盘号为{plateCode}获取失败{ex.ToString()}");
            }
            return webResponseContent.OK();
            return webResponseContent;
        }
        /// <summary>
        /// ç”Ÿæˆå…¥åº“任务(入库确认)
        /// </summary>
        /// <param name="plateCode">托盘条码</param>
        /// <param name="SourceAddress">起始地址</param>
        /// <returns></returns>
        public WebResponseContent GenerateInboundTask(string plateCode)
        {
            WebResponseContent webResponseContent = new WebResponseContent();
            try
            {
                new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "产生入库任务-GenerateInboundTask", "请求", $"plateCode:{plateCode}");
                List<RoadWayDTO> roadWays = new List<RoadWayDTO>();
                List<Dt_InboundOrder> inboundOrders = new List<Dt_InboundOrder>();
                Dt_BillGroupStock billGroupStock = new Dt_BillGroupStock();
                //1,根据托盘号查询组盘信息
                List<Dt_BillGroupStock> billGroup = Db.Queryable<Dt_BillGroupStock>().Includes(x => x.Dt_BillGroupStockDetailList).Where(x => x.PalletCode == plateCode && x.State == (int)StockStateEmun.组盘暂存).ToList();
                if (billGroup != null && billGroup.Count > 0)
                {
                    //查询对应的入库单,用于取值入库单类型
                    inboundOrders = BaseDal.QueryData(x => x.InboundNo == billGroupStock.OrderNo);
                    if(inboundOrders.Count == 0)
                    {
                       return  webResponseContent.Error($"未查询到当前拖盘号为{plateCode} å¯¹åº”的入库单!");
                    }
                    //通过单据类型获取任务类型
                    List<Dt_TypeMapping> typeMappings= _dt_TypeMappingRepository.QueryData(x => x.OrderType == inboundOrders[0].InboundType).ToList();
                    if (typeMappings.Count == 0)
                    {
                       return  webResponseContent.Error($"未配置单据类型对应的任务类型!");
                    }
                    try
                    {
                        //生成任务
                        Dt_Task dt_Task = new Dt_Task();
                        dt_Task.TaskNum = GetTaskNo();
                        dt_Task.PalletCode = plateCode;
                        dt_Task.GroupID = billGroupStock.GroupId;
                        dt_Task.InboundNo = billGroupStock.OrderNo;
                        dt_Task.TaskType = typeMappings[0].OrderType;
                        dt_Task.TaskState = (int)InTaskStatusEnum.InNew;
                        dt_Task.MaterialNo = billGroupStock.MaterialNo;
                        dt_Task.Dispatchertime = DateTime.Now;
                        _dt_TaskRepository.AddData(dt_Task);
                        //开启事物
                        _unitOfWorkManage.BeginTran();
                        _dt_TaskRepository.AddData(dt_Task);
                        //库存状态 æ”¹ä¸º å…¥åº“确认状态
                        billGroupStock.State = (int)StockStateEmun.入库确认;
                        _dt_BillGroupStockRepository.UpdateData(billGroupStock);
                        //提交事物
                        _unitOfWorkManage.CommitTran();
                        webResponseContent.OK("生成任务成功!", dt_Task);
                    }
                    catch (Exception)
                    {
                        _unitOfWorkManage.RollbackTran();
                        throw;
                    }
                }
            }
            catch (Exception ex)
            {
                new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "产生入库任务-GenerateInboundTask", "响应", $"当前拖盘号为{plateCode}获取失败{ex.ToString()}");
                webResponseContent.Error($"当前拖盘号为{plateCode} ç”Ÿæˆä»»åŠ¡å¤±è´¥ï¼š{ex.ToString()}");
            }
            return webResponseContent;
        }
        /// <summary>
        /// ç”³è¯·åˆ†é…é¡¹é“
        /// </summary>
        /// <param name="plateCode">托盘条码</param>
        /// <param name="SourceAddress">起始地址</param>
        /// <returns></returns>
        public WebResponseContent GetInboundRoadway(string plateCode, string SourceAddress)
        {
            WebResponseContent webResponseContent = new WebResponseContent();
            try
            {
                new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "申请分配项道-GetInboundRoadway", "请求", $"plateCode:{plateCode}-SourceAddress:{SourceAddress}");
                List<RoadWayDTO> roadWays = new List<RoadWayDTO>();
                List<Dt_InboundOrder> inboundOrders = new List<Dt_InboundOrder>();
                Dt_BillGroupStock billGroupStock = new Dt_BillGroupStock();
                Dt_Task dt_Task = new Dt_Task();
                List<Dt_Task> dt_TaskList = _dt_TaskRepository.QueryData(x => x.PalletCode == plateCode&&x.TaskState== (int)InTaskStatusEnum.InNew);
                if (dt_TaskList != null && dt_TaskList.Count == 0)
                {
                   return  webResponseContent.OK("未查询到相关任务!");
                }
                else
                {
                    dt_Task = dt_TaskList.FirstOrDefault();
                }
                  //1,根据托盘号查询组盘信息
                List<Dt_BillGroupStock> billGroup = Db.Queryable<Dt_BillGroupStock>().Includes(x => x.Dt_BillGroupStockDetailList).Where(x => x.PalletCode == plateCode && x.State == (int)StockStateEmun.组盘暂存).ToList();
                if (billGroup != null && billGroup.Count > 0)
                {
                    billGroupStock = billGroup[0];
                    //根据物料编码,查询物料信息(所属库区)
                    List<Dt_MaterielInfo> masterielInfos = _dt_MaterielInfoRepository.QueryData(x => x.MaterielCode == billGroupStock.MaterialNo);
                    if (masterielInfos != null && masterielInfos.Count > 0)
                    {
                        //获取空闲货位列表
                        var roadWayList = _dt_LocationInfoRepository.QueryData(x => x.Status == (int)LocationEnum.Free && x.WareAreaCode == masterielInfos[0].WareAreaCode.ToString()).GroupBy(x => x.Roadway).OrderByDescending(group => group.Count()).ToList();
                        foreach (var item in roadWayList)
                        {
                            //去掉禁用的巷道
                            Dt_RoadWayInfo roadway = _dt_RoadWayInfoRepository.QueryData(x => x.RoadWayNO == item.Key).FirstOrDefault();
                            if (roadway != null && roadway.IsEnable == false)
                            {
                                continue;
                            }
                            //查询巷道新建的和正在执行中的任务数
                            int taskCount = _dt_TaskRepository.QueryData(x => x.Roadway == item.Key && (x.TaskState == (int)InTaskStatusEnum.InNew || x.TaskState == (int)InTaskStatusEnum.AGV_InExecuting || x.TaskState == (int)InTaskStatusEnum.Line_InExecuting || x.TaskState == (int)InTaskStatusEnum.SC_InExecuting)).Count();
                            RoadWayDTO roadWayDTO = new RoadWayDTO();
                            roadWayDTO.RoadWayNO = item.Key;
                            roadWayDTO.FreeLocationCount = item.Count();
                            roadWayDTO.TaskCount = taskCount;
                            roadWayDTO.PreFreeLocationCount = roadWayDTO.FreeLocationCount - roadWayDTO.TaskCount;
                            roadWays.Add(roadWayDTO);
                        }
                        if (roadWays.Count == 0)
                        {
                           return webResponseContent.OK("未获取到满足条件的巷道号列表!");
                        }
                        //根据预计货位空闲数(货位空闲数-巷道当前任务数),获取项道号
                        string roadWay = roadWays.OrderByDescending(roadway => roadway.PreFreeLocationCount).FirstOrDefault().RoadWayNO;
                        //查询对应的入库单,用于取值入库单类型
                        inboundOrders = BaseDal.QueryData(x => x.InboundNo == billGroupStock.OrderNo);
                        try
                        {
                            //更新任务状态、巷道号
                            dt_Task.TaskState = (int)InTaskStatusEnum.AGV_InExecuting;
                            dt_Task.SourceAddress = SourceAddress;
                            dt_Task.Roadway = roadWay;
                            _dt_TaskRepository.Update(dt_Task);
                            webResponseContent.OK("获取巷道号成功!", dt_Task);
                        }
                        catch (Exception)
                        {
                            _unitOfWorkManage.RollbackTran();
                            throw;
                        }
                    }
                    else
                    {
                        new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "申请分配项道-GetInboundRoadway", "响应", $"plateCode:{plateCode}-无此物料基本信息,物料编号:{billGroup[0].MaterialNo}");
                        webResponseContent.Error($"plateCode:{plateCode}-无此物料基本信息,物料编号:{billGroup[0].MaterialNo}");
                    }
                }
            }
            catch (Exception ex)
            {
                new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "产生入库任务并分配巷道-GenerateInboundTask", "响应", $"当前拖盘号为{plateCode}获取失败{ex.ToString()}");
                webResponseContent.Error($"当前拖盘号为{plateCode}获取巷道号失败{ex.ToString()}");
            }
            return webResponseContent;
        }
        /// <summary>
        /// æ ¹æ®ä»»åŠ¡å·èŽ·å–è´§ä½å·
        /// ç”³è¯·åˆ†é…è´§ä½
        /// </summary>
        /// <param name="taskNo">任务号</param>
        /// <returns></returns>
@@ -384,15 +535,15 @@
                if (dt_TaskList != null && dt_TaskList.Count > 0)
                {
                    //根据巷道查询货位号
                    List<Dt_LocationInfo> dt_LocationInfoList = _dt_LocationInfoRepository.QueryData(x => x.Roadway == dt_TaskList[0].Roadway && x.Status == (int)LocationStatus.空闲).ToList();
                    //查询符合要求的货位号
                    #region æŸ¥è¯¢å¯ç”¨è´§ä½
                    List<Dt_LocationInfo> dt_LocationInfoList = _dt_LocationInfoRepository.QueryData(x => x.Roadway == dt_TaskList[0].Roadway && x.Status == (int)LocationEnum.Free).ToList();
                    List<Dt_LocationInfo> dt_LocationInfoResult = new List<Dt_LocationInfo>();
                    foreach (Dt_LocationInfo dt_LocationInfo in dt_LocationInfoList)
                    {
                        //如果深度为2,则需判断对应的1深位(列,层一样,排为奇数,当前排数-1),如果1深位空闲,则符合要求
                        if (dt_LocationInfo.Depth == "2")
                        {
                            Dt_LocationInfo locationItem = _dt_LocationInfoRepository.QueryData(x => x.Layer == dt_LocationInfo.Layer && x.Column == dt_LocationInfo.Column && x.Line == (int.Parse(dt_LocationInfo.Line.ToString()) - 1).ToString() && x.Status == (int)LocationStatus.空闲).FirstOrDefault();
                            Dt_LocationInfo locationItem = _dt_LocationInfoRepository.QueryData(x => x.Layer == dt_LocationInfo.Layer && x.Column == dt_LocationInfo.Column && x.Line == (int.Parse(dt_LocationInfo.Line.ToString()) - 1).ToString() && x.Status == (int)(int)LocationEnum.Free).FirstOrDefault();
                            if (locationItem != null)
                            {
                                dt_LocationInfoResult.Add(dt_LocationInfo);
@@ -400,14 +551,20 @@
                        }
                        else//如果深度为1,则需判断对应的2深位(列,层一样,排为偶数,当前排数+1),如果2深位有货,则符合要求
                        {
                            Dt_LocationInfo locationItem = _dt_LocationInfoRepository.QueryData(x => x.Layer == dt_LocationInfo.Layer && x.Column == dt_LocationInfo.Column && x.Line == (int.Parse(dt_LocationInfo.Line.ToString()) + 1).ToString() && x.Status == (int)LocationStatus.有货).FirstOrDefault();
                            Dt_LocationInfo locationItem = _dt_LocationInfoRepository.QueryData(x => x.Layer == dt_LocationInfo.Layer && x.Column == dt_LocationInfo.Column && x.Line == (int.Parse(dt_LocationInfo.Line.ToString()) + 1).ToString() && x.Status == (int)LocationEnum.InStock).FirstOrDefault();
                            if (locationItem != null)
                            {
                                dt_LocationInfoResult.Add(dt_LocationInfo);
                            }
                        }
                    }
                    //todo:对符合要求的货位,进行筛选,先按深度降序(深度优先),再按排升序(就近原则),再按层数(先下后上)
                    #endregion
                    //对符合要求的货位,进行筛选,先按深度降序(深度优先),再按列升序(就近原则),再按层数(先下后上)
                    //todo: åŠ åˆ¤æ–­ dt_LocationInfoResult>=2 å°äºŽç›´æŽ¥æç¤ºå½“前空闲货位不足
                    if(dt_LocationInfoResult.Count<2)
                    {
                        return webResponseContent.OK("当前空闲货位不足!");
                    }
                    dt_LocationInfoResult.OrderByDescending(x => x.Depth).ThenBy(x => x.Column).ThenBy(x => x.Layer).ToList();
                    List<Dt_LocationInfo> dt_Locations = new List<Dt_LocationInfo>();
                    Dt_Task dt_task = dt_TaskList[0];
@@ -420,17 +577,16 @@
                            if (locationResult.Depth == "2")
                            {
                                locationResult.IsLocked = true;
                                locationResult.Status = (int)LocationStatus.锁定;
                                locationResult.Status = (int)LocationEnum.Lock;
                                //获取对应的1深位货位信息
                                Dt_LocationInfo location = _dt_LocationInfoRepository.QueryData(x => x.Layer == locationResult.Layer && x.Column == locationResult.Column && x.Line == (int.Parse(locationResult.Line.ToString()) - 1).ToString() && x.Status == (int)LocationStatus.空闲).FirstOrDefault();
                                Dt_LocationInfo location = dt_LocationInfoResult.Where(x => x.Layer == locationResult.Layer && x.Column == locationResult.Column && x.Line == (int.Parse(locationResult.Line.ToString()) - 1).ToString() && x.Status == (int)LocationEnum.Free).FirstOrDefault();
                                if (location != null)
                                {
                                    location.IsLocked = true;
                                    location.Status = (int)LocationStatus.锁定;
                                    location.Status = (int)LocationEnum.Lock;
                                    dt_Locations.Add(locationResult);//1深位
                                    dt_Locations.Add(location);//2深位
                                    dt_task.LocationCode = locationResult.LocationCode;
                                    dt_task.LocationCode = locationResult.LocationCode;//分配对应的货位
                                    break;
                                }
                                else
@@ -442,9 +598,10 @@
                            else
                            {
                                locationResult.IsLocked = true;
                                locationResult.Status = (int)LocationStatus.锁定;
                                locationResult.Status = (int)LocationEnum.Lock;
                                dt_Locations.Add(locationResult);
                                dt_task.LocationCode = locationResult.LocationCode;
                                dt_task.LocationCode = locationResult.LocationCode;// åˆ†é…å¯¹åº”的货位
                                break;
                            }
@@ -463,6 +620,7 @@
                        }
                        catch (Exception)
                        {
                            _unitOfWorkManage.RollbackTran();
                            throw;
                        }
@@ -493,7 +651,7 @@
        /// <summary>
        /// å…¥åº“任务完成处理
        /// å…¥åº“任务完成
        /// </summary>
        /// <returns></returns>
        public WebResponseContent FinishInboundTask(int taskNum)
@@ -501,9 +659,10 @@
            WebResponseContent webResponseContent = new WebResponseContent();
            try
            {
                //1,修改货位状态
                //修改货位状态
                new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "入库任务完成处理-FinishInboundTask", "请求", $"taskNum-{taskNum}");
                List<Dt_LocationInfo> dt_Locations = new List<Dt_LocationInfo>();
                List<Dt_InboundOrderDetail> dt_InboundOrderDetails = new List<Dt_InboundOrderDetail>();
                List<Dt_Task> dt_TaskList = _dt_TaskRepository.QueryData(x => x.TaskNum == taskNum);
                if (dt_TaskList != null && dt_TaskList.Count > 0)
                {
@@ -515,12 +674,12 @@
                        if (locationinfo != null && locationinfo.Depth == "2")
                        {
                            //获取对应的1深位货位信息
                            Dt_LocationInfo location = _dt_LocationInfoRepository.QueryData(x => x.Layer == locationinfo.Layer && x.Column == locationinfo.Column && x.Line == (int.Parse(locationinfo.Line.ToString()) - 1).ToString() && x.Status == (int)LocationStatus.锁定).FirstOrDefault();
                            Dt_LocationInfo location = _dt_LocationInfoRepository.QueryData(x => x.Layer == locationinfo.Layer && x.Column == locationinfo.Column && x.Line == (int.Parse(locationinfo.Line.ToString()) - 1).ToString() && x.Status == (int)LocationEnum.Lock).FirstOrDefault();
                            if (location != null)
                            {
                                locationinfo.Status = (int)LocationStatus.空闲;
                                locationinfo.Status = (int)LocationEnum.Free;
                                locationinfo.IsLocked = false;
                                location.Status = (int)LocationStatus.空闲;
                                location.Status = (int)LocationEnum.Free;
                                location.IsLocked = false;
                                locationinfos.Add(locationinfo);
                                locationinfos.Add(location);
@@ -528,13 +687,72 @@
                        }
                        else
                        {
                            locationinfo.Status = (int)LocationStatus.空闲;
                            locationinfo.Status = (int)LocationEnum.Free;
                            locationinfo.IsLocked = false;
                            locationinfos.Add(locationinfo);
                        }
                    }
                    dt_TaskList[0].TaskState = TaskStatusEmun.入库任务完成.ToString();
                    //更新任务状态
                    dt_TaskList[0].TaskState =(int) InTaskStatusEnum.InFinish;
                }
                else
                {
                   return  webResponseContent.Error($"未查询到该入库任务记录!任务号:{taskNum}");
                }
                //更新库存信息(货位与托盘号绑定),状态改为入库完成
                Dt_BillGroupStock billGroupStock = _dt_BillGroupStockRepository.QueryData(x => x.GroupId == dt_TaskList[0].GroupID).FirstOrDefault();
                decimal? palletQuantity = null;
                if (billGroupStock != null)
                {
                    billGroupStock.LocationCode = dt_TaskList[0].LocationCode;
                    billGroupStock.State = (int)StockStateEmun.入库完成;
                }
                Dt_InboundOrder inboundOrder = BaseDal.QueryData(x => x.InboundNo == billGroupStock.OrderNo).FirstOrDefault();
                if (inboundOrder != null)
                {
                    if (billGroupStock.Dt_BillGroupStockDetailList != null && billGroupStock.Dt_BillGroupStockDetailList.Count > 0)
                    {
                        //当前任务完成入库数量(当前托盘明细数量)
                        //多个明细入库单据分组统计
                        var billStockGroups = billGroupStock.Dt_BillGroupStockDetailList.GroupBy(x => x.OrderDetailId).Select(g => new { OrderDetailId = g.Key, PalletQuantity = g.Sum(x => x.PalletQuantity) }).ToList();
                        foreach (var kvp in billStockGroups)
                        {
                            //查询入库单明细
                            Dt_InboundOrderDetail inboundOrderDetail = new Dt_InboundOrderDetail();
                            inboundOrderDetail = _dt_InboundOrderDetailRepository.QueryFirst(x => x.OrderDetailId == kvp.OrderDetailId);
                            if (inboundOrderDetail != null)
                            {
                                palletQuantity = kvp.PalletQuantity;
                                //更新入库单明细入库数量(累加)
                                inboundOrderDetail.ActualInboundQuantity = string.IsNullOrEmpty(inboundOrderDetail.ActualInboundQuantity) ? palletQuantity.ToString() : (Convert.ToDecimal(inboundOrderDetail.ActualInboundQuantity) + palletQuantity).ToString();
                                //更新入库单明细状态为已入库
                                if (Convert.ToDecimal(inboundOrderDetail.ActualInboundQuantity) == Convert.ToDecimal(inboundOrderDetail.PreInboundQuantity))
                                {
                                    inboundOrderDetail.InboundState = (int)InboundStateEmun.入库完成;
                                }
                                else
                                {
                                    inboundOrderDetail.InboundState = (int)InboundStateEmun.入库中;//一条入库单据明细可能会对应多个托盘,所有的任务完成后,再改状态为入库中。
                                }
                                dt_InboundOrderDetails.Add(inboundOrderDetail);
                            }
                            else
                            {
                                return webResponseContent.Error($"未查询到对应的入库明细!入库明细ID:{kvp.OrderDetailId}");
                            }
                        }
                    }
                }
                if (dt_Locations.Count > 0)
                {
@@ -544,13 +762,26 @@
                        _unitOfWorkManage.BeginTran();
                        //1,更新货位状态   
                        _dt_LocationInfoRepository.UpdateData(dt_Locations);
                        //2,更新任务状态
                        //2,更新任务状态(todo:直接插入历史表中,不用再更新任务表中的状态)
                        _dt_TaskRepository.UpdateData(dt_TaskList[0]);
                        //3,更新库存信息(货位与托盘号绑定),状态改为入库完成
                        _dt_BillGroupStockRepository.UpdateData(billGroupStock);
                        //4,更新入库明细单据信息,已入库数量和状态  Dt_InboundOrderDetail  ä¸­çš„ActualInboundQuantity(实际入库数量)
                        _dt_InboundOrderDetailRepository.UpdateData(dt_InboundOrderDetails);
                        //5,更新入库单据主表状态 Dt_InboundOrder æ‰€æœ‰çš„入库明细完成入库后,整个单据主表改为入库完成。
                        List<Dt_InboundOrderDetail> inboundOrders = inboundOrder.Dt_InboundOrderDetailList.Where(x => x.InboundState != (int)InboundStateEmun.入库完成).ToList();
                        if(inboundOrders.Count == 0)
                        {
                            inboundOrder.InboundState =(int)InboundStateEmun.入库完成;
                        }
                        BaseDal.UpdateData(inboundOrder);
                        _unitOfWorkManage.CommitTran();//提交事物
                        webResponseContent.OK("获取成功", dt_TaskList[0]);
                    }
                    catch (Exception)
                    {
                        _unitOfWorkManage.RollbackTran();
                        throw;
                    }
@@ -571,6 +802,156 @@
        }
        /// <summary>
        /// å…¥åº“任务取消
        /// </summary>
        /// <param name="taskNum"></param>
        /// <returns></returns>
        public WebResponseContent CancelInboundTask(int taskNum)
        {
            WebResponseContent webResponseContent = new WebResponseContent();
            try
            {
                new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "入库任务取消-CancelInboundTask", "请求", $"taskNum-{taskNum}");
                Dt_BillGroupStock dt_billGroupStock = new Dt_BillGroupStock();
                Dt_Task_Hty dt_Task_Hty = new Dt_Task_Hty();
                Dt_LocationInfo dt_locationInfo = new Dt_LocationInfo();
                //1,查询是否存在该任务,并且任务状态是:200 æ–°å»ºå…¥åº“任务
                Dt_Task dt_Task = _dt_TaskRepository.QueryFirst(x => x.TaskNum == taskNum&&x.TaskState==(int) InTaskStatusEnum.InNew);
                if (dt_Task != null)
                {
                    //2,还原组盘状态为:1 ç»„盘暂存
                    dt_billGroupStock = _dt_BillGroupStockRepository.QueryFirst(x => x.GroupId == dt_Task.GroupID);
                    if (dt_billGroupStock != null)
                    {
                        dt_billGroupStock.State = (int)StockStateEmun.组盘暂存;
                        dt_billGroupStock.LocationCode = "";
                    }
                    else
                    {
                        new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "入库任务取消-CancelInboundTask", "响应", $"未查询到该任务号的组盘信息:{taskNum}");
                        return webResponseContent.Error($"未查询到该任务号的组盘信息:{taskNum}");
                    }
                    //3,移到历史任务表中
                    #region ç”ŸæˆåŽ†å²ä»»åŠ¡è®°å½•
                    dt_Task_Hty.TaskNum = taskNum;
                    dt_Task_Hty.TaskId = dt_Task.TaskId;
                    dt_Task_Hty.PalletCode = dt_Task.PalletCode;
                    dt_Task_Hty.InboundNo = dt_Task.InboundNo;
                    dt_Task_Hty.GroupID = dt_Task.GroupID;
                    dt_Task_Hty.Roadway = dt_Task.Roadway;
                    dt_Task_Hty.LocationCode = dt_Task.LocationCode;
                    dt_Task_Hty.TaskType = dt_Task.TaskType;
                    dt_Task_Hty.TaskState = (int)InTaskStatusEnum.InCancel;
                    dt_Task_Hty.MaterialNo = dt_Task.MaterialNo;
                    dt_Task_Hty.SourceAddress = dt_Task.SourceAddress;
                    dt_Task_Hty.TargetAddress = dt_Task.TargetAddress;
                    dt_Task_Hty.CurrentAddress = dt_Task.CurrentAddress;
                    dt_Task_Hty.NextAddress = dt_Task.NextAddress;
                    dt_Task_Hty.Grade = dt_Task.Grade;
                    dt_Task_Hty.Dispatchertime = dt_Task.Dispatchertime;
                    dt_Task_Hty.Remark = dt_Task.Remark;
                    dt_Task_Hty.CreateID = dt_Task.CreateID;
                    dt_Task_Hty.Creater = dt_Task.Creater;
                    dt_Task_Hty.CreateDate = dt_Task.CreateDate;
                    dt_Task_Hty.ModifyID = dt_Task.ModifyID;
                    dt_Task_Hty.Modifier = dt_Task.Modifier;
                    dt_Task_Hty.ModifyDate = dt_Task.ModifyDate;
                    #endregion
                    //4,任务表中删除任务
                    //5,释放货位
                    dt_locationInfo = _dt_LocationInfoRepository.QueryFirst(x => x.LocationCode == dt_Task.LocationCode);
                    dt_locationInfo.Status = (int)LocationEnum.Free;
                }
                else
                {
                    new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "入库任务取消-CancelInboundTask", "响应", $"该任务号不存在:{taskNum}");
                    return webResponseContent.Error($"该任务号不存在:{taskNum}");
                }
                try
                {
                    //开启事物
                    _unitOfWorkManage.BeginTran();
                    //2,更新任务状态为:270 å…¥åº“任务取消
                    _dt_Task_HtyRepository.AddData(dt_Task_Hty);
                    //3,还原组盘状态为:1 ç»„盘暂存
                    _dt_BillGroupStockRepository.UpdateData(dt_billGroupStock);
                    //4,删除任务
                    _dt_TaskRepository.DeleteDataById(dt_Task.TaskId);
                    //5,货位表释放货位
                    _dt_LocationInfoRepository.UpdateData(dt_locationInfo);
                    //提交事物
                    _unitOfWorkManage.CommitTran();
                }
                catch (Exception)
                {
                    _unitOfWorkManage.RollbackTran();
                    throw;
                }
            }
            catch (Exception ex)
            {
                new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "入库任务取消-CancelInboundTask", "响应", $"任务号:{taskNum}任务取消失败,异常{ex.ToString()}");
                return webResponseContent.Error($"任务号:{taskNum}任务取消失败,异常{ex.ToString()}");
            }
            return webResponseContent;
        }
        /// <summary>
        /// å…¥åº“任务更新
        /// </summary>
        /// <param name="taskNum"></param>
        /// <returns></returns>
        public WebResponseContent UpdateInboundTask(int taskNum, string currentAddress, string nextAddress, string ErrorMessage)
        {
            WebResponseContent webResponseContent = new WebResponseContent();
            new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "入库任务更新-UpdateInboundTask", "请求", $"taskNum-{taskNum} currentAddress-{currentAddress} nextAddress-{nextAddress} ErrorMessage-{ErrorMessage}");
            //1,查询是否存在该任务
            try
            {
                Dt_Task dt_Task = _dt_TaskRepository.QueryFirst(x => x.TaskNum == taskNum);
                if (dt_Task != null)
                {
                    if (string.IsNullOrEmpty(currentAddress))
                    {
                        dt_Task.CurrentAddress = currentAddress;
                    }
                    if (string.IsNullOrEmpty(nextAddress))
                    {
                        dt_Task.NextAddress = nextAddress;
                    }
                    if (string.IsNullOrEmpty(ErrorMessage))
                    {
                        dt_Task.ErrorMessage = ErrorMessage;
                    }
                    dt_Task.ModifyDate = DateTime.Now;
                    dt_Task.Modifier = App.User.UserId.ToString();
                    //2,更新任务信息
                    _dt_TaskRepository.UpdateData(dt_Task);
                }
                else
                {
                    new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "入库任务更新-UpdateInboundTask", "响应", $"任务号:{taskNum} ä»»åŠ¡ä¸å­˜åœ¨");
                    return webResponseContent.Error($"任务号:{taskNum} ä»»åŠ¡ä¸å­˜åœ¨");
                }
            }
            catch (Exception ex)
            {
                new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "入库任务更新-UpdateInboundTask", "响应", $"任务号:{taskNum}任务更新失败,异常{ex.ToString()}");
                return webResponseContent.Error($"任务号:{taskNum}任务更新失败,异常{ex.ToString()}");
            }
             return webResponseContent;
        }
        /// <summary>
        /// èŽ·å–ä»»åŠ¡ç¼–å·
        /// </summary>
        /// <returns></returns>
@@ -580,6 +961,34 @@
            return int.Parse(dt.Rows[0][0].ToString());
        }
        /// <summary>
        /// è‡ªåŠ¨ç”Ÿæˆå…¥åº“å•å·
        /// </summary>
        /// <param name="prefix">R</param>
        /// <param name="date"></param>
        /// <returns></returns>
        public  string GenerateOrderNumber(string prefix, DateTime date)
        {
            // æ ¼å¼åŒ–日期为 "YYYYMMDD"
            string dateString = date.ToString("yyyyMMdd");
            int sn = 1;//流水号从1开始
            //递增流水号
            List<Dt_InboundOrder> inboundOrders = BaseDal.QueryData().OrderByDescending(x => x.InboundNo.Substring(x.InboundNo.Length - 5)).ToList();
            if(inboundOrders.Count > 0 )
            {
                Dt_InboundOrder dt_InboundOrder = new Dt_InboundOrder();
                sn = int.Parse(dt_InboundOrder.InboundNo.Substring(dt_InboundOrder.InboundNo.Length - 5)) + 1;
            }
            // ç»„合前缀、日期和流水号
            StringBuilder orderNumber = new StringBuilder();
            orderNumber.Append(prefix);
            orderNumber.Append(dateString);
            orderNumber.Append(sn.ToString().PadLeft(5, '0'));
            return orderNumber.ToString();
        }
    }
}