using System.Data; using System.Text; using WIDESEA_Core; using WIDESEA_Core.BaseRepository; using WIDESEA_Core.BaseServices; using WIDESEA_Core.Enums; using WIDESEA_DTO; using WIDESEA_IBusinessesRepository; using WIDESEA_IBusinessServices; using WIDESEA_IStorageBasicRepository; using WIDESEA_IStorageTaskRepository; using WIDESEA_Model.Models; namespace WIDESEA_BusinessServices { public class Dt_InboundOrderService : ServiceBase, IDt_InboundOrderService { #region 接口 private readonly IUnitOfWorkManage _unitOfWorkManage; private readonly IDt_InboundOrderDetailRepository _dt_InboundOrderDetailRepository; private readonly IDt_InboundOrderProductionRepository _dt_InboundOrderProductionRepository; private readonly IDt_InboundOrderProductionService _dt_InboundOrderProductionService; private readonly IDt_InboundOrderPurchaseRepository _dt_InboundOrderPurchaseRepository; private readonly IDt_InboundOrderPurchaseService _dt_InboundOrderPurchaseService; private readonly IDt_BillGroupStockDetailRepository _dt_BillGroupStockDetailRepository; private readonly IDt_BillGroupStockRepository _dt_BillGroupStockRepository; private readonly IDt_MaterielInfoRepository _dt_MaterielInfoRepository; private readonly IDt_WareAreaInfoRepository _dt_WareAreaInfoRepository; private readonly IDt_StrategyRepository _dt_StrategyRepository; 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 public Dt_InboundOrderService(IDt_InboundOrderRepository BaseDal, IUnitOfWorkManage unitOfWorkManage, IDt_InboundOrderDetailRepository dt_InboundOrderDetailRepository, 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_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; _dt_InboundOrderProductionService = dt_InboundOrderProductionService; _dt_InboundOrderProductionRepository = dt_InboundOrderProductionRepository; _dt_InboundOrderPurchaseService = dt_InboundOrderPurchaseService; _dt_InboundOrderPurchaseRepository = dt_InboundOrderPurchaseRepository; _dt_BillGroupStockDetailRepository = dt_BillGroupStockDetailRepository; _dt_MaterielInfoRepository = dt_MaterielInfoRepository; _dt_WareAreaInfoRepository = dt_WareAreaInfoRepository; _dt_StrategyRepository = dt_StrategyRepository; _dt_LocationInfoRepository = dt_LocationInfoRepository; _dt_BillGroupStockRepository = dt_BillGroupStockRepository; _dt_TaskRepository = dt_TaskRepository; _dt_TaskExecuteDetailRepository = dt_TaskExecuteDetailRepository; _dt_RoadWayInfoRepository = dt_RoadWayInfoRepository; _dt_TypeMappingRepository = dt_TypeMappingRepository; _dt_Task_HtyRepository = dt_Task_HtyRepository; } /// /// 同步生产入库原始单据到本系统入库单表,并更新原始单据的同步标志 /// 同步标志 SynchronizationFlag 0:未同步 1:同步成功 2:同步失败 /// /// public async Task GetInboundOrderFromProductionOrigin() { WebResponseContent webResponseContent = new WebResponseContent(); new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "生产入库单同步-GetInboundOrderFromProductionOrigin", "请求", "无参数"); List Dt_InboundOrderProductionList = await _dt_InboundOrderProductionService.GetDt_InboundOrderProduction((int)SynchronizationFlagEmun.未同步); foreach (var mainItem in Dt_InboundOrderProductionList) { try { List Dt_InboundOrderList = new List(); List Dt_InboundOrderDetailList = new List(); #region 入库原始单据主表校验,单据转换为本系统入库单主表 //todo:此处做原始单据主表字段校验 Dt_InboundOrder dt_InboundOrder = new Dt_InboundOrder(); dt_InboundOrder.InboundNo = GenerateOrderNumber("R",DateTime.Now); dt_InboundOrder.InboundUpperNo = mainItem.ProductionNo; dt_InboundOrder.BatchNo = mainItem.BatchNo; dt_InboundOrder.InboundDate = mainItem.CreateDate; dt_InboundOrder.InboundType = mainItem.ProductionType; dt_InboundOrder.InboundState = mainItem.ProductionState; dt_InboundOrder.Remark = mainItem.Remark; Dt_InboundOrderList.Add(dt_InboundOrder); #endregion #region 入库原始单据明细表校验,单据转换为本系统入库单明细 foreach (var detailItem in mainItem.Dt_InboundOrderProductionDetailList) { //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_InboundOrderDetailList.Add(dt_InboundOrderDetail); } #endregion try { //开启事物 _unitOfWorkManage.BeginTran(); BaseDal.AddData(Dt_InboundOrderList);//保存主表 _dt_InboundOrderDetailRepository.AddData(Dt_InboundOrderDetailList);//保存明细 mainItem.SynchronizationFlag = (int)SynchronizationFlagEmun.同步成功; //更新原单据同步标识为:1:同步成功 _dt_InboundOrderProductionRepository.UpdateData(mainItem); //提交事务 _unitOfWorkManage.CommitTran(); new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "生产入库单同步-GetInboundOrderFromProductionOrigin", "响应", "同步成功"); webResponseContent.Error($"同步成功"); } catch (Exception) { _unitOfWorkManage.RollbackTran(); throw; } } catch (Exception ex) { mainItem.SynchronizationFlag = (int)SynchronizationFlagEmun.同步失败; //更新原单据同步标识为:2:同步失败 mainItem.Remark = ex.Message;//记录失败原因 _dt_InboundOrderProductionRepository.UpdateData(mainItem); new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "生产入库单同步-GetInboundOrderFromProductionOrigin", "响应", $"同步失败{ex.ToString()}"); webResponseContent.Error($"同步失败{ex.ToString()}"); } } return webResponseContent; } /// /// 同步采购入库原始单据到本系统入库单表,并更新原始单据的同步标志 /// 同步标志 SynchronizationFlag 0:未同步 1:同步成功 2:同步失败 /// /// public async Task GetInboundOrderFromPurchaseOrigin() { WebResponseContent webResponseContent = new WebResponseContent(); new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "采购入库单同步-GetInboundOrderFromProductionOrigin", "请求", "无参数"); List Dt_InboundOrderPurchaseList = await _dt_InboundOrderPurchaseService.GetDt_InboundOrderPurchase((int)SynchronizationFlagEmun.未同步); foreach (var mainItem in Dt_InboundOrderPurchaseList) { try { List Dt_InboundOrderList = new List(); List Dt_InboundOrderDetailList = new List(); #region 入库原始单据主表校验,单据转换为本系统入库单主表 //todo:此处做原始单据主表字段校验 Dt_InboundOrder dt_InboundOrder = new Dt_InboundOrder(); //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; dt_InboundOrder.InboundType = mainItem.PurchaseType; dt_InboundOrder.InboundState = mainItem.PurchaseState; dt_InboundOrder.Remark = mainItem.Remark; Dt_InboundOrderList.Add(dt_InboundOrder); #endregion #region 入库原始单据明细表校验,单据转换为本系统入库单明细 foreach (var detailItem in mainItem.Dt_InboundOrderPurchaseDetailList) { //todo:此处做原始单据明细字段校验 Dt_InboundOrderDetail dt_InboundOrderDetail = new Dt_InboundOrderDetail(); 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.PurchaseMatcode; dt_InboundOrderDetail.MaterialName = detailItem.PurchaseName; dt_InboundOrderDetail.PreInboundQuantity = detailItem.PurchaseQty; Dt_InboundOrderDetailList.Add(dt_InboundOrderDetail); } #endregion try { //开启事物 _unitOfWorkManage.BeginTran(); BaseDal.AddData(Dt_InboundOrderList);//保存主表 _dt_InboundOrderDetailRepository.AddData(Dt_InboundOrderDetailList);//保存明细 mainItem.SynchronizationFlag = (int)SynchronizationFlagEmun.同步成功; //更新原单据同步标识为:1:同步成功 _dt_InboundOrderPurchaseRepository.UpdateData(mainItem); //提交事务 _unitOfWorkManage.CommitTran(); new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "采购入库单同步-GetInboundOrderFromPurchaseOrigin", "响应", "同步成功"); webResponseContent.Error($"同步成功"); } catch (Exception) { _unitOfWorkManage.RollbackTran(); throw; } } catch (Exception ex) { mainItem.SynchronizationFlag = (int)SynchronizationFlagEmun.同步失败; //更新原单据同步标识为:2:同步失败 mainItem.Remark = ex.Message;//记录失败原因 _dt_InboundOrderPurchaseRepository.UpdateData(mainItem); new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "采购入库单同步-GetInboundOrderFromProductionOrigin", "响应", $"同步失败{ex.ToString()}"); webResponseContent.Error($"同步失败{ex.ToString()}"); } } return webResponseContent; } /// /// 生成入库任务 分配巷道 /// /// 托盘条码 /// 起始地址 /// public WebResponseContent GenerateInboundTask(string plateCode, string SourceAddress) { WebResponseContent webResponseContent = new WebResponseContent(); try { //任务号不能重复 List 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 roadWays = new List(); List inboundOrders = new List(); Dt_BillGroupStock billGroupStock = new Dt_BillGroupStock(); //1,根据托盘号查询组盘信息 List billGroup = Db.Queryable().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 masterielInfos = _dt_MaterielInfoRepository.QueryData(x => x.MaterielCode == billGroupStock.MaterialNo); if (masterielInfos != null && masterielInfos.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) { //去掉禁用的巷道 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) { 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 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 { new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "产生入库任务并分配巷道-GenerateInboundTask", "响应", $"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; } /// /// 生成入库任务(入库确认) /// /// 托盘条码 /// 起始地址 /// public WebResponseContent GenerateInboundTask(string plateCode) { WebResponseContent webResponseContent = new WebResponseContent(); try { new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "产生入库任务-GenerateInboundTask", "请求", $"plateCode:{plateCode}"); List roadWays = new List(); List inboundOrders = new List(); Dt_BillGroupStock billGroupStock = new Dt_BillGroupStock(); //1,根据托盘号查询组盘信息 List billGroup = Db.Queryable().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 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; } /// /// 申请分配项道 /// /// 托盘条码 /// 起始地址 /// 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 roadWays = new List(); List inboundOrders = new List(); Dt_BillGroupStock billGroupStock = new Dt_BillGroupStock(); Dt_Task dt_Task = new Dt_Task(); List 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 billGroup = Db.Queryable().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 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; } /// /// 申请分配货位 /// /// 任务号 /// public WebResponseContent GetInboundLocation(int taskNum) { WebResponseContent webResponseContent = new WebResponseContent(); try { new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "根据任务号获取货位号-GetInboundLocation", "请求", $"taskNum-{taskNum}"); List dt_TaskList = _dt_TaskRepository.QueryData(x => x.TaskNum == taskNum); if (dt_TaskList != null && dt_TaskList.Count > 0) { //根据巷道查询货位号 #region 查询可用货位 List dt_LocationInfoList = _dt_LocationInfoRepository.QueryData(x => x.Roadway == dt_TaskList[0].Roadway && x.Status == (int)LocationEnum.Free).ToList(); List dt_LocationInfoResult = new List(); 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)(int)LocationEnum.Free).FirstOrDefault(); if (locationItem != null) { dt_LocationInfoResult.Add(dt_LocationInfo); } } 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)LocationEnum.InStock).FirstOrDefault(); if (locationItem != null) { dt_LocationInfoResult.Add(dt_LocationInfo); } } } #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_Locations = new List(); Dt_Task dt_task = dt_TaskList[0]; foreach (var locationResult in dt_LocationInfoResult) { if (locationResult != null) { //1,锁定货位状态,如果是2深位,需同时锁定1,2深位;1深位,只需锁定当前货位 //2,添加当前任务的货位号 if (locationResult.Depth == "2") { locationResult.IsLocked = true; locationResult.Status = (int)LocationEnum.Lock; //获取对应的1深位货位信息 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)LocationEnum.Lock; dt_Locations.Add(locationResult);//1深位 dt_Locations.Add(location);//2深位 dt_task.LocationCode = locationResult.LocationCode;//分配对应的货位 break; } else { continue; } } else { locationResult.IsLocked = true; locationResult.Status = (int)LocationEnum.Lock; dt_Locations.Add(locationResult); dt_task.LocationCode = locationResult.LocationCode;// 分配对应的货位 break; } } } if (dt_Locations.Count > 0) { try { //开启事物 _unitOfWorkManage.BeginTran(); _dt_TaskRepository.UpdateData(dt_task);//更新货位编号LocationCode _dt_LocationInfoRepository.UpdateData(dt_Locations);//更新货位状态 _unitOfWorkManage.CommitTran();//提交事物 webResponseContent.OK("获取成功",dt_task); } catch (Exception) { _unitOfWorkManage.RollbackTran(); throw; } } else { new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "根据任务号获取货位号-GetInboundLocation", "响应", $"当前任务号:{taskNum} 未分配到合适的货位!"); webResponseContent.Error($"当前任务号:{taskNum} 未分配到合适的货位!"); } } else { new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "根据任务号获取货位号-GetInboundLocation", "响应", $"未查询到当前任务号:{taskNum}"); webResponseContent.Error($"未查询到当前任务号:{taskNum}"); } } catch (Exception ex) { new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "根据任务号获取货位号-GetInboundLocation", "响应", $"当前任务号为{taskNum}获取失败{ex.ToString()}"); webResponseContent.Error($"当前任务号为{taskNum}获取失败{ex.ToString()}"); } return webResponseContent; } /// /// 入库任务完成 /// /// public WebResponseContent FinishInboundTask(int taskNum) { WebResponseContent webResponseContent = new WebResponseContent(); try { //修改货位状态 new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "入库任务完成处理-FinishInboundTask", "请求", $"taskNum-{taskNum}"); List dt_Locations = new List(); List dt_InboundOrderDetails = new List(); List dt_TaskList = _dt_TaskRepository.QueryData(x => x.TaskNum == taskNum); if (dt_TaskList != null && dt_TaskList.Count > 0) { List locationinfos = _dt_LocationInfoRepository.QueryData(x => x.LocationCode == dt_TaskList[0].LocationCode).ToList(); if (locationinfos != null && locationinfos.Count > 0) { Dt_LocationInfo locationinfo = locationinfos[0]; //如果是2深位,连1深位状态一起释放 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)LocationEnum.Lock).FirstOrDefault(); if (location != null) { locationinfo.Status = (int)LocationEnum.Free; locationinfo.IsLocked = false; location.Status = (int)LocationEnum.Free; location.IsLocked = false; locationinfos.Add(locationinfo); locationinfos.Add(location); } } else { locationinfo.Status = (int)LocationEnum.Free; locationinfo.IsLocked = false; locationinfos.Add(locationinfo); } } //更新任务状态 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) { try { //开启事物 _unitOfWorkManage.BeginTran(); //1,更新货位状态 _dt_LocationInfoRepository.UpdateData(dt_Locations); //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 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; } } else { new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "入库任务完成处理-FinishInboundTask", "响应", $"当前任务号:{taskNum} 未找到当前任务号关联的货位!"); webResponseContent.Error($"当前任务号:{taskNum} 未找到当前任务号关联的货位!"); } } catch(Exception ex) { new LogLibrary.Log.LogFactory().GetLog("接口").InfoFormat(true, "入库任务完成处理-FinishInboundTask", "响应", $"当前任务号为{taskNum}入库完成处理失败{ex.ToString()}"); webResponseContent.Error($"当前任务号为{taskNum}入库完成处理失败{ex.ToString()}"); } return webResponseContent; } /// /// 入库任务取消 /// /// /// 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; } /// /// 入库任务更新 /// /// /// 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; } /// /// 获取任务编号 /// /// public int GetTaskNo() { DataTable dt = BaseDal.QueryTable("select next value for dbo.seqTaskNum"); return int.Parse(dt.Rows[0][0].ToString()); } /// /// 自动生成入库单号 /// /// R /// /// public string GenerateOrderNumber(string prefix, DateTime date) { // 格式化日期为 "YYYYMMDD" string dateString = date.ToString("yyyyMMdd"); int sn = 1;//流水号从1开始 //递增流水号 List 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(); } } }