using ServiceCenter.Extensions; using ServiceCenter.SqlSugars; using SqlSugar; using System.ComponentModel; using WCS.Core; using WCS.Entity; using WCS.Entity.Protocol.Station; using WCS.WorkEngineering.Extensions; using WCS.WorkEngineering.WebApi.Controllers; using WCS.WorkEngineering.WebApi.Models.WMS.Response; using WCS.WorkEngineering.Worlds; using DeviceFlags = WCS.WorkEngineering.Extensions.DeviceFlags; using TaskStatus = WCS.Entity.TaskStatus; namespace WCS.WorkEngineering.Systems { /// /// 环形库码垛区补空托盘任务生成 /// [BelongTo(typeof(PalletizingWorld))] [Description("码垛区域生成空托盘任务")] public class 码垛区域生成空托盘任务 : DeviceSystem> { protected override bool ParallelDo => true; public override void Do(Device objDev) { var lastIsTruss = objDev.Entity.GetFlag("LastIsTruss"); if (lastIsTruss == 0) //桁架用空托 { objDev.Entity.SetFlag("LastIsTruss", 1); WCS_Palletizing palletizing = null; SqlSugarHelper.Do(_db => { var db = _db.Default; //取一个时间最靠前的,没有绑定码垛工位的码垛记录 var palletizingInfoList = db.Queryable().Where(x => x.PalletizingStation == null && !x.Finish && !x.isItHalf).OrderBy(x => x.AddTime).ToList(); if (!palletizingInfoList.Any()) { World.Log("桁架没有码垛信息可用!"); return; } foreach (var palletizingInfo in palletizingInfoList) { if (palletizing != null) continue; //获取可以使用的放货站台信息 var taskAddNext = Device.All.FirstOrDefault(x => x.Code == palletizingInfo.TaskAddNext)?.Targets.FirstOrDefault()?.Targets.Where(x => x.HasFlag(DeviceFlags.桁架码垛位)); if (taskAddNext == null) { World.Log($"未找到可去的码垛工位:未找到{palletizingInfo.TaskAddNext}可去的码垛工位:{palletizingInfo.Id}"); continue; } var devs = Device.All.Where(x => taskAddNext.Contains(x)).Select(x => new Device(x, World)).ToList(); //获取所有的未结束且有码垛工位的码垛记录 var palletizingStation = db.Queryable().Where(x => !x.Finish && x.PalletizingStation != null).Select(x => x.PalletizingStation).ToList(); //取一个可用用于码垛的地方 var dev = devs.Where(x => !palletizingStation.Contains(x.Entity.Code)).FirstOrDefault(x => !x.Data3.Status.HasFlag(StationStatus.PH_Status)); if (dev == null) { World.Log($"没有可用码垛工:{palletizingInfo.Id}"); continue; } var addrFromCode = palletizingInfo.WarehouseCode switch { "1N" => "1602", "1S" => "1612", "2N" => "1622", "2S" => "1632", "3N" => "1642", "3S" => "1652", _ => "9999" }; var endDev = Device.All.Where(x => x.Code == addrFromCode).Select(x => new Device(x, World)).FirstOrDefault(); if (endDev.Data.TaskNumber != 0 /*|| endDev.Data.GoodsEnd != 0*/) { World.Log($"拆盘机残留任务信息:{endDev.Entity.Code}有残留任务信息{endDev.Data.TaskNumber}-{endDev.Data.GoodsEnd},请确认处理!"); continue; } palletizingInfo.PalletizingStation = dev.Entity.Code; db.UpdateableRowLock(palletizingInfo).UpdateColumns(x => new { x.PalletizingStation }).ExecuteCommand(); palletizing = palletizingInfo; } }); if (palletizing == null) return; var addrFromCode = palletizing.WarehouseCode switch { "1N" => "1602", "1S" => "1612", "2N" => "1622", "2S" => "1632", "3N" => "1642", "3S" => "1652", _ => "9999" }; var dev = Device.All.Where(x => x.Code == addrFromCode).Select(x => new Device(x, World)).FirstOrDefault(); dev.Data.TaskNumber = palletizing.Id; dev.Data.GoodsEnd = palletizing.PalletizingStation!.ToShort(); } else if (lastIsTruss == 1)//芯股用空托 { objDev.Entity.SetFlag("LastIsTruss", 2); SqlSugarHelper.Do(db => { var taskInfo = db.Default.Queryable().RowLock().Where(x => x.Status == TaskStatus.NewBuild && x.BusType == "芯股用空托盘入库").ToList(); var isEnd = false; foreach (var info in taskInfo) { if (isEnd) continue; try { //通过仓库号获取对应的拆盘机位置 info.AddrFrom = info.WarehouseCode switch { "1N" => "1602", "1S" => "1612", "2N" => "1622", "2S" => "1632", "3N" => "1642", "3S" => "1652", _ => "9999" }; info.Device = info.WarehouseCode switch { "1N" => "SRM1", "1S" => "SRM2", "2N" => "SRM3", "2S" => "SRM4", "3N" => "SRM5", "3S" => "SRM6", _ => info.Device }; info.AddrNext = info.WarehouseCode switch { "1N" => "1604", "1S" => "1614", "2N" => "1624", "2S" => "1634", "3N" => "1644", "3S" => "1654", _ => info.AddrNext }; info.SrmStation = info.WarehouseCode switch { "1N" => "1603", "1S" => "1613", "2N" => "1623", "2S" => "1633", "3N" => "1643", "3S" => "1653", _ => info.SrmStation }; var dev = Device.All.Where(x => x.Code == info.AddrFrom).Select(x => new Device(x, World)).FirstOrDefault(); if (dev.Data.TaskNumber != 0 || dev.Data.GoodsEnd != 0) { World.Log($"拆盘机残留任务信息:{dev.Entity.Code}有残留任务信息 {dev.Data.TaskNumber} - {dev.Data.GoodsEnd} ,请确认处理!"); continue; } info.AddrTo = "SRM"; info.Height = 1; info.Status = TaskStatus.WaitingToExecute; db.Default.UpdateableRowLock(info).UpdateColumns(x => new { x.AddrFrom, x.Device, x.AddrNext, x.SrmStation, x.Status, x.AddrTo, x.Height }).ExecuteCommand(); info.AddWCS_TASK_DTL(db.Default, info.Device, $"初始化芯股用空托盘入库任务信息"); dev.Data.TaskNumber = info.ID; dev.Data.GoodsEnd = info.AddrNext.ToShort(); isEnd = true; } catch (Exception e) { World.Log(e.Message); } } }); } else //机械臂用空托 { objDev.Entity.SetFlag("LastIsTruss", 0); var devs = Device.All.Where(x => x.HasFlag(DeviceFlags.环形库码垛工位)).Select(x => new Device(x, World)); devs = devs.Where(x => !x.Data3.Status.HasFlag(StationStatus.PH_Status)); WCS_TaskInfo deliveryTask = null; foreach (var obj in devs) { if (deliveryTask != null) { continue; } SqlSugarHelper.Do(_db => { var db = _db.Default; //检查是否有待执行状态放货点是自己的出库任务 var ringTask = db.Queryable().NoLock().First(x => x.Type == TaskType.OutDepot && x.Status <= TaskStatus.WaitingToExecute && x.SrmStation == obj.Entity.Code); if (ringTask == null) { var code = obj.Entity.Code.GetWareCode(); var wareHouse = db.Queryable().First(x => x.Code == code); if (wareHouse == null) { World.Log($"无对应仓库--[{code}]"); return; } //检查是否有满跺记录 var ringPalletizingInfo = db.Queryable().Where(x => x.WareHouseId == wareHouse.Id && x.HaveQty > 0 && !x.Out).ToList() .OrderBy(x => x.AddTime).FirstOrDefault(x => x.HaveQty == x.HWCountQty || x.AddTime < DateTime.Now.AddHours(-6)); if (ringPalletizingInfo == null) { World.Log("无满跺码垛信息"); return; } //开始申请码垛任务 var resData = WmsApi.ApplyPalletizingStockOut(obj.Entity.Code, obj.Entity.Sources.Single(x => x.HasFlag(DeviceFlags.Robot)).Code); if (resData.ResCode != ResponseStatusCodeEnum.Sucess) { World.Log(resData.ResMsg, ServiceCenter.Logs.LogLevelEnum.Mid); } return; } var task = db.Queryable().NoLock().First(x => x.Type == TaskType.Delivery && x.AddrTo == obj.Entity.Code && x.Status < TaskStatus.Finish); if (task != null) return; //开始获取当前地址上个设备的上一个设备中的非零九托盘拆机 var addrFrom = obj.Entity.Sources.SelectMany(x => x.Sources).Single(x => x.HasFlag(DeviceFlags.拆盘机)); var dev = Device.All.Where(x => x.Code == addrFrom.Code).Select(x => new Device(x, World)).FirstOrDefault(); if (dev.Data.TaskNumber != 0 /*|| dev.Data.GoodsEnd != 0*/) { World.Log($"拆盘机残留任务信息: {dev.Entity.Code}有残留任务信息 {dev.Data.TaskNumber} - {dev.Data.GoodsEnd} ,请确认处理!"); return; } //开始创建搬运任务 task = new WCS_TaskInfo() { AddrFrom = addrFrom.Code, AddrTo = obj.Entity.Code, BarCode = "码垛托盘搬运-" + obj.Entity.Code, Status = Entity.TaskStatus.NewBuild, PalletType = ringTask.PalletType, FullQty = ringTask.FullQty, Type = TaskType.Delivery, AddWho = "WCS", AddTime = DateTime.Now }; var res = db.InsertableRowLock(task).ExecuteReturnEntity(); var taskOld = res.Mapper(); taskOld.Id = res.ID; taskOld.AddTime = DateTime.Now; db.InsertableRowLock(taskOld).SplitTable().ExecuteCommand(); res.AddWCS_TASK_DTL(db, obj.Entity.Code, task.AddrTo, "初始化码垛托盘搬运任务"); deliveryTask = res; }); } if (deliveryTask == null) return; var dev = Device.All.Where(x => x.Code == deliveryTask.AddrFrom).Select(x => new Device(x, World)).FirstOrDefault(); dev.Data.TaskNumber = deliveryTask.ID; dev.Data.GoodsEnd = deliveryTask.AddrTo.ToShort(); } } public override bool Select(Device dev) { return dev.Code == nameof(PalletizCreateEmptyTray); } } // // 摘要: // 环形库码垛缓存信息 [Tenant("fj")] [SugarTable("Bill_RingPalletizingInfo")] public class BillRingPalletizingInfo : BaseModel { // // 摘要: // 仓库ID [SugarColumn(IsNullable = false, ColumnDescription = "仓库ID")] public long WareHouseId { get; set; } // // 摘要: // 任务 [Navigate(NavigateType.OneToOne, "WareHouseId")] public BaseWarehouse WareHouse { get; set; } // // 摘要: // 垛形主表ID [SugarColumn(IsNullable = false, ColumnDescription = "垛形主表ID")] public long BomSetGrpId { get; set; } // // 摘要: // 工字轮个数 [SugarColumn(ColumnDataType = "int", IsNullable = false, ColumnDescription = "工字轮个数")] public int HWCountQty { get; set; } // // 摘要: // BomCode(投料信息)/物料号 [SugarColumn(ColumnDataType = "nvarchar", Length = 200, IsNullable = false, ColumnDescription = "BomCode(投料信息)")] public string BomCode { get; set; } // // 摘要: // 已有工字轮个数 [SugarColumn(ColumnDataType = "int", IsNullable = false, ColumnDescription = "已有工字轮个数")] public int HaveQty { get; set; } // // 摘要: // 是否出库 [SugarColumn(IsNullable = false, ColumnDescription = "是否出库")] public bool Out { get; set; } // // 摘要: // 上一次分配时的放置位信息 [SugarColumn(ColumnDataType = "int", IsNullable = true)] public int LastXYNO { get; set; } } // // 摘要: // 仓库表 [Tenant("fj")] [SugarTable("Base_Warehouse")] public class BaseWarehouse : BaseModel { // // 摘要: // 是否停用 [SugarColumn(ColumnDataType = "int", IsNullable = false)] public int IsStop { get; set; } // // 摘要: // 编号 [SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = false)] public string Code { get; set; } // // 摘要: // 名称 [SugarColumn(ColumnDataType = "nvarchar", Length = 100, IsNullable = false)] public string Name { get; set; } //// //// 摘要: //// 类型 //[SugarColumn(IsNullable = false)] //public FjLocationType TypeNum { get; set; } // // 摘要: // ConfigId [SugarColumn(ColumnName = "ConfigId", ColumnDescription = "ConfigId")] public long ConfigId { get; set; } } }