码垛区域生成空托盘任务.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. using ServiceCenter.Extensions;
  2. using ServiceCenter.SqlSugars;
  3. using SqlSugar;
  4. using System.ComponentModel;
  5. using WCS.Core;
  6. using WCS.Entity;
  7. using WCS.Entity.Protocol.Station;
  8. using WCS.WorkEngineering.Extensions;
  9. using WCS.WorkEngineering.WebApi.Controllers;
  10. using WCS.WorkEngineering.WebApi.Models.WMS.Response;
  11. using WCS.WorkEngineering.Worlds;
  12. using DeviceFlags = WCS.WorkEngineering.Extensions.DeviceFlags;
  13. using TaskStatus = WCS.Entity.TaskStatus;
  14. namespace WCS.WorkEngineering.Systems
  15. {
  16. /// <summary>
  17. /// 环形库码垛区补空托盘任务生成
  18. /// </summary>
  19. [BelongTo(typeof(PalletizingWorld))]
  20. [Description("码垛区域生成空托盘任务")]
  21. public class 码垛区域生成空托盘任务 : DeviceSystem<Device<IStation520>>
  22. {
  23. protected override bool ParallelDo => true;
  24. public override void Do(Device<IStation520> objDev)
  25. {
  26. var lastIsTruss = objDev.Entity.GetFlag<bool>("LastIsTruss");
  27. objDev.Entity.SetFlag("LastIsTruss", !lastIsTruss);
  28. if (lastIsTruss)
  29. {
  30. WCS_Palletizing palletizing = null;
  31. SqlSugarHelper.Do(_db =>
  32. {
  33. var db = _db.Default;
  34. //取一个时间最靠前的,没有绑定码垛工位的码垛记录
  35. var palletizingInfoList = db.Queryable<WCS_Palletizing>().Where(x => x.PalletizingStation == null && !x.Finish && !x.isItHalf).OrderBy(x => x.AddTime).ToList();
  36. if (!palletizingInfoList.Any())
  37. {
  38. World.Log("没有码垛信息可用!");
  39. return;
  40. }
  41. foreach (var palletizingInfo in palletizingInfoList)
  42. {
  43. if (palletizing != null) continue;
  44. //获取可以使用的放货站台信息
  45. var taskAddNext = Device.All.FirstOrDefault(x => x.Code == palletizingInfo.TaskAddNext)?.Targets.FirstOrDefault()?.Targets.Where(x => x.HasFlag(DeviceFlags.桁架码垛位));
  46. if (taskAddNext == null)
  47. {
  48. World.Log($"未找到{palletizingInfo.TaskAddNext}可去的码垛工位:{palletizingInfo.Id}");
  49. continue;
  50. }
  51. var devs = Device.All.Where(x => taskAddNext.Contains(x)).Select(x => new Device<IStation520, IStation521, IStation523>(x, World)).ToList();
  52. //获取所有的未结束且有码垛工位的码垛记录
  53. var palletizingStation = db.Queryable<WCS_Palletizing>().Where(x => !x.Finish && x.PalletizingStation != null).Select(x => x.PalletizingStation).ToList();
  54. //取一个可用用于码垛的地方
  55. var dev = devs.Where(x => !palletizingStation.Contains(x.Entity.Code)).FirstOrDefault(x => !x.Data3.Status.HasFlag(StationStatus.PH_Status));
  56. if (dev == null)
  57. {
  58. World.Log("没有可用码垛工");
  59. continue;
  60. }
  61. var addrFromCode = palletizingInfo.WarehouseCode switch
  62. {
  63. "1N" => "1602",
  64. "1S" => "1612",
  65. "2N" => "1622",
  66. "2S" => "1632",
  67. "3N" => "1642",
  68. "3S" => "1652",
  69. _ => "9999"
  70. };
  71. var endDev = Device.All.Where(x => x.Code == addrFromCode).Select(x => new Device<IStation520>(x, World)).FirstOrDefault();
  72. if (endDev.Data.TaskNumber != 0 || endDev.Data.GoodsEnd != 0)
  73. {
  74. World.Log($"{endDev.Entity.Code}有残留任务信息{endDev.Data.TaskNumber}-{endDev.Data.GoodsEnd},请确认处理!");
  75. continue;
  76. }
  77. palletizingInfo.PalletizingStation = dev.Entity.Code;
  78. db.UpdateableRowLock(palletizingInfo).UpdateColumns(x => new { x.PalletizingStation }).ExecuteCommand();
  79. palletizing = palletizingInfo;
  80. }
  81. });
  82. if (palletizing == null) return;
  83. var addrFromCode = palletizing.WarehouseCode switch
  84. {
  85. "1N" => "1602",
  86. "1S" => "1612",
  87. "2N" => "1622",
  88. "2S" => "1632",
  89. "3N" => "1642",
  90. "3S" => "1652",
  91. _ => "9999"
  92. };
  93. var dev = Device.All.Where(x => x.Code == addrFromCode).Select(x => new Device<IStation520>(x, World)).FirstOrDefault();
  94. dev.Data.TaskNumber = palletizing.Id;
  95. dev.Data.GoodsEnd = palletizing.PalletizingStation!.ToShort();
  96. }
  97. else
  98. {
  99. var devs = Device.All.Where(x => x.HasFlag(DeviceFlags.环形库码垛工位)).Select(x => new Device<IStation520, IStation521, IStation523>(x, World));
  100. devs = devs.Where(x => !x.Data3.Status.HasFlag(StationStatus.PH_Status));
  101. WCS_TaskInfo deliveryTask = null;
  102. foreach (var obj in devs)
  103. {
  104. if (deliveryTask != null)
  105. {
  106. continue;
  107. }
  108. SqlSugarHelper.Do(_db =>
  109. {
  110. var db = _db.Default;
  111. //检查是否有待执行状态放货点是自己的出库任务
  112. var ringTask = db.Queryable<WCS_TaskInfo>().NoLock().First(x => x.Type == TaskType.OutDepot && x.Status <= TaskStatus.WaitingToExecute && x.SrmStation == obj.Entity.Code);
  113. if (ringTask == null)
  114. {
  115. var code = obj.Entity.Code.GetWareCode();
  116. var wareHouse = db.Queryable<BaseWarehouse>().First(x => x.Code == code);
  117. if (wareHouse == null)
  118. {
  119. World.Log($"无对应仓库--[{code}]");
  120. return;
  121. }
  122. //检查是否有满跺记录
  123. var ringPalletizingInfo = db.Queryable<BillRingPalletizingInfo>().Where(x => x.WareHouseId == wareHouse.Id && x.HaveQty > 0 && !x.Out).ToList()
  124. .OrderBy(x => x.AddTime).FirstOrDefault(x => x.HaveQty == x.HWCountQty || x.AddTime < DateTime.Now.AddHours(-6));
  125. if (ringPalletizingInfo == null)
  126. {
  127. World.Log("无满跺码垛信息");
  128. return;
  129. }
  130. //开始申请码垛任务
  131. var resData = WmsApi.ApplyPalletizingStockOut(obj.Entity.Code, obj.Entity.Sources.Single(x => x.HasFlag(DeviceFlags.Robot)).Code);
  132. if (resData.ResCode != ResponseStatusCodeEnum.Sucess)
  133. {
  134. World.Log(resData.ResMsg,ServiceCenter.Logs.LogLevelEnum.Mid);
  135. }
  136. return;
  137. }
  138. var task = db.Queryable<WCS_TaskInfo>().NoLock().First(x => x.Type == TaskType.Delivery && x.AddrTo == obj.Entity.Code && x.Status < TaskStatus.Finish);
  139. if (task != null) return;
  140. //开始获取当前地址上个设备的上一个设备中的非零九托盘拆机
  141. var addrFrom = obj.Entity.Sources.SelectMany(x => x.Sources).Single(x => x.HasFlag(DeviceFlags.拆盘机));
  142. var dev = Device.All.Where(x => x.Code == addrFrom.Code).Select(x => new Device<IStation520>(x, World)).FirstOrDefault();
  143. if (dev.Data.TaskNumber != 0 || dev.Data.GoodsEnd != 0)
  144. {
  145. World.Log($"{dev.Entity.Code}有残留任务信息 {dev.Data.TaskNumber} - {dev.Data.GoodsEnd} ,请确认处理!");
  146. return;
  147. }
  148. //开始创建搬运任务
  149. task = new WCS_TaskInfo()
  150. {
  151. AddrFrom = addrFrom.Code,
  152. AddrTo = obj.Entity.Code,
  153. BarCode = "码垛托盘搬运-" + obj.Entity.Code,
  154. Status = Entity.TaskStatus.NewBuild,
  155. PalletType = ringTask.PalletType,
  156. FullQty = ringTask.FullQty,
  157. Type = TaskType.Delivery,
  158. AddWho = "WCS",
  159. AddTime = DateTime.Now
  160. };
  161. var res = db.InsertableRowLock(task).ExecuteReturnEntity();
  162. var taskOld = res.Mapper<WCS_TaskOld, WCS_TaskInfo>();
  163. taskOld.Id = res.ID;
  164. taskOld.AddTime = DateTime.Now;
  165. db.InsertableRowLock(taskOld).SplitTable().ExecuteCommand();
  166. res.AddWCS_TASK_DTL(db, obj.Entity.Code, task.AddrTo, "初始化码垛托盘搬运任务");
  167. deliveryTask = res;
  168. });
  169. }
  170. if (deliveryTask == null) return;
  171. var dev = Device.All.Where(x => x.Code == deliveryTask.AddrFrom).Select(x => new Device<IStation520>(x, World)).FirstOrDefault();
  172. dev.Data.TaskNumber = deliveryTask.ID;
  173. dev.Data.GoodsEnd = deliveryTask.AddrTo.ToShort();
  174. }
  175. }
  176. public override bool Select(Device dev)
  177. {
  178. return dev.Code == nameof(PalletizCreateEmptyTray);
  179. }
  180. }
  181. //
  182. // 摘要:
  183. // 环形库码垛缓存信息
  184. [Tenant("fj")]
  185. [SugarTable("Bill_RingPalletizingInfo")]
  186. public class BillRingPalletizingInfo : BaseModel
  187. {
  188. //
  189. // 摘要:
  190. // 仓库ID
  191. [SugarColumn(IsNullable = false, ColumnDescription = "仓库ID")]
  192. public long WareHouseId { get; set; }
  193. //
  194. // 摘要:
  195. // 任务
  196. [Navigate(NavigateType.OneToOne, "WareHouseId")]
  197. public BaseWarehouse WareHouse { get; set; }
  198. //
  199. // 摘要:
  200. // 垛形主表ID
  201. [SugarColumn(IsNullable = false, ColumnDescription = "垛形主表ID")]
  202. public long BomSetGrpId { get; set; }
  203. //
  204. // 摘要:
  205. // 工字轮个数
  206. [SugarColumn(ColumnDataType = "int", IsNullable = false, ColumnDescription = "工字轮个数")]
  207. public int HWCountQty { get; set; }
  208. //
  209. // 摘要:
  210. // BomCode(投料信息)/物料号
  211. [SugarColumn(ColumnDataType = "nvarchar", Length = 200, IsNullable = false, ColumnDescription = "BomCode(投料信息)")]
  212. public string BomCode { get; set; }
  213. //
  214. // 摘要:
  215. // 已有工字轮个数
  216. [SugarColumn(ColumnDataType = "int", IsNullable = false, ColumnDescription = "已有工字轮个数")]
  217. public int HaveQty { get; set; }
  218. //
  219. // 摘要:
  220. // 是否出库
  221. [SugarColumn(IsNullable = false, ColumnDescription = "是否出库")]
  222. public bool Out { get; set; }
  223. //
  224. // 摘要:
  225. // 上一次分配时的放置位信息
  226. [SugarColumn(ColumnDataType = "int", IsNullable = true)]
  227. public int LastXYNO { get; set; }
  228. }
  229. //
  230. // 摘要:
  231. // 仓库表
  232. [Tenant("fj")]
  233. [SugarTable("Base_Warehouse")]
  234. public class BaseWarehouse : BaseModel
  235. {
  236. //
  237. // 摘要:
  238. // 是否停用
  239. [SugarColumn(ColumnDataType = "int", IsNullable = false)]
  240. public int IsStop { get; set; }
  241. //
  242. // 摘要:
  243. // 编号
  244. [SugarColumn(ColumnDataType = "nvarchar", Length = 50, IsNullable = false)]
  245. public string Code { get; set; }
  246. //
  247. // 摘要:
  248. // 名称
  249. [SugarColumn(ColumnDataType = "nvarchar", Length = 100, IsNullable = false)]
  250. public string Name { get; set; }
  251. ////
  252. //// 摘要:
  253. //// 类型
  254. //[SugarColumn(IsNullable = false)]
  255. //public FjLocationType TypeNum { get; set; }
  256. //
  257. // 摘要:
  258. // ConfigId
  259. [SugarColumn(ColumnName = "ConfigId", ColumnDescription = "ConfigId")]
  260. public long ConfigId { get; set; }
  261. }
  262. }