AgvCallBLL.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. using SqlSugar;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using WMS.Core._02Entity;
  6. using WMS.Info;
  7. using WMS.Info.Models;
  8. using WMS.Util;
  9. namespace WMS.Core.APPBLL
  10. {
  11. public class AgvCallBLL : AppCoreBLL
  12. {
  13. /// <summary>
  14. /// agv扫码入库
  15. /// </summary>
  16. /// <param name="reqData"></param>
  17. /// <returns></returns>
  18. public ResInfo AgvIn(AgvCallRequest reqData)
  19. {
  20. SqlSugarClient ctx = SysDbCore.GetDbCtx();
  21. try
  22. {
  23. if (string.IsNullOrWhiteSpace(reqData?.TrayNo) || string.IsNullOrWhiteSpace(reqData.LocationNo))
  24. throw SysExCore.ThrowFailException("参数不能为空");
  25. ctx.BeginTran();
  26. //生产wms任务
  27. WMS_TASK task = new WMS_TASK
  28. {
  29. F_addTime = DateTime.Now,
  30. F_addUserNo = LoginUser.UserNo,
  31. F_posidFrom = reqData.LocationNo,
  32. F_posidcur = reqData.LocationNo,
  33. F_posidNext = reqData.LocationNo,
  34. //F_posidTo = ,
  35. F_priority = (int)EPriority.NotUrgent,
  36. F_taskStatus = (int)ETaskStatus.NotIssued,
  37. F_taskType = (int)ETaskComType.InStock,
  38. F_trayNo = reqData.TrayNo,
  39. F_EquipmentType = (int)EEquipmentType.AGV
  40. };
  41. //根据位置码盘点判断成品或原料
  42. var point = GetPointInfo(reqData.LocationNo);
  43. if (point == null)
  44. throw SysExCore.ThrowFailException("该点位数据无效!");
  45. //整盘生产入库单
  46. if (reqData.FullPlate)
  47. {
  48. if (ctx.Queryable<BILL_ENTRYORDER>().Any(a => a.F_trayNo == reqData.TrayNo && a.F_orderStatus != (int)EOrderState.Executed))
  49. throw SysExCore.ThrowFailException($"托盘号{reqData.TrayNo}已存在入库信息!");
  50. BILL_ENTRYORDER entryOrder = new BILL_ENTRYORDER
  51. {
  52. F_no = SerialNumberProvider.Instance.OrderNumber("wms", "RK"),
  53. F_addTime = DateTime.Now,
  54. F_addUserNo = LoginUser.UserNo,
  55. F_editTime = DateTime.Now,
  56. F_fullPlate = reqData.FullPlate,
  57. //F_locationNo = reqData.LocationNo,
  58. F_orderStatus = (int)EOrderState.New,
  59. F_trayNo = reqData.TrayNo,
  60. F_isBonded = reqData.TrayNo.StartsWith("B"),
  61. F_warehouseNo = SysSetCore.GetSysSet().DefaultWarehouseNo
  62. };
  63. List<BILL_INVENTORY> lstInv = new List<BILL_INVENTORY>();
  64. switch ((EPointType)point.F_type)
  65. {
  66. case EPointType.YLAGV:
  67. #region 原料
  68. var mInfos = FxDbCore.GetData<FX_ld_det>($"select ld_domain,ld_site,ld_loc,ld_part,ld_ref,ld_lot,ld_qty_oh from pub.ld_det where ld_domain='AFCN' and ld_site='SUZ' and ld_loc='{reqData.TrayNo}'");
  69. if (mInfos.Count < 1)
  70. throw SysExCore.ThrowFailException($"未获取到托盘号{reqData.TrayNo}组盘信息");
  71. mInfos.ToList().ForEach(orderLine =>
  72. {
  73. var mat = CacheFacade.GetMatInfo(orderLine.ld_part, EMatType.Mat);
  74. ctx.Insertable(new BILL_ENTRYORDERLINEDETAIL
  75. {
  76. F_addTime = DateTime.Now,
  77. F_addUserNo = LoginUser.UserNo,
  78. F_batchNo = orderLine.ld_loc,
  79. F_matNo = orderLine.ld_part,
  80. F_matName = mat?.F_matName,
  81. F_matType = (int)EMatType.Mat,
  82. F_quantity = orderLine.ld_qty_oh,
  83. F_pNo = entryOrder.F_no,
  84. F_trayNo = reqData.TrayNo,
  85. F_UID = orderLine.ld_ref,
  86. }).ExecuteCommand();
  87. lstInv.Add(new BILL_INVENTORY
  88. {
  89. F_addTime = DateTime.Now,
  90. F_addUserNo = LoginUser.UserNo,
  91. F_editTime = DateTime.Now,
  92. F_matNo = orderLine.ld_part,
  93. F_matType = (int)EMatType.Mat,
  94. F_projectNo = mat.F_projectNo,
  95. F_quantity = orderLine.ld_qty_oh,
  96. F_uid = orderLine.ld_ref,
  97. F_batchNo = orderLine.ld_lot,
  98. F_unit = mat.F_unit,
  99. F_matName = mat?.F_matName,
  100. F_trayNo = reqData.TrayNo,
  101. F_warehouseNo = SysSetCore.GetSysSet().DefaultWarehouseNo
  102. });
  103. });
  104. #region 原料入库直接覆盖当前托盘库存,不存在则清理
  105. var trayInv = ctx.Queryable<BILL_INVENTORY>().Where(a => a.F_trayNo == reqData.TrayNo).ToList();
  106. if (trayInv.Any())
  107. {
  108. trayInv.ForEach(inv =>
  109. {
  110. if (!mInfos.Any(orderLine => inv.F_trayNo == orderLine.ld_loc && inv.F_uid == orderLine.ld_ref && inv.F_matNo == orderLine.ld_part && inv.F_batchNo == orderLine.ld_lot))
  111. {
  112. ctx.Deleteable<BILL_INVENTORY>().Where(c => c.F_no == inv.F_no).ExecuteCommand();
  113. ctx.Insertable(new BILL_INVENTORYTRANSACTION
  114. {
  115. F_addTime = DateTime.Now,
  116. F_addUserNo = LoginUser.UserNo,
  117. F_batchNo = inv.F_batchNo,
  118. F_boxNo = inv.F_boxNo,
  119. F_matName = inv.F_matName,
  120. F_matNo = inv.F_matNo,
  121. F_matType = inv.F_matType,
  122. F_sourceLockQty = inv.F_lockQty,
  123. F_targetLockQty = 0,
  124. F_memo = inv.F_memo,
  125. F_projectNo = inv.F_projectNo,
  126. F_sourceTrayNo = inv.F_trayNo,
  127. F_targetTrayNo = string.Empty,
  128. F_warehouseNo = inv.F_warehouseNo,
  129. F_UID = string.Empty,
  130. F_sourceQuantity = inv.F_quantity,
  131. F_targetQuantity = 0
  132. }).ExecuteCommand();
  133. }
  134. });
  135. }
  136. #endregion
  137. task.F_orderType = (int)EEntryOrderType.EntryOrderTypeMaterial;
  138. entryOrder.F_relatedOrderNo = mInfos.FirstOrDefault().ld_ref;
  139. entryOrder.F_orderType = (int)ETaskOrderType.EntryOrderTypeMaterial;
  140. entryOrder.F_totalOrderLines = mInfos.Count;
  141. #endregion
  142. break;
  143. case EPointType.CPAGV:
  144. #region 成品
  145. if (ctx.Queryable<BILL_ENTRYORDER>().Any(a => a.F_trayNo == reqData.TrayNo && a.F_orderStatus != (int)EOrderState.Executed))
  146. throw SysExCore.ThrowFailException($"托盘号{reqData.TrayNo}已存在入库信息!");
  147. var pInfos = ctx.Queryable<FX_wo_mstr, FX_wo_mstr_info>((wo, info) => new object[] { JoinType.Inner, wo.order_code == info.order_code })
  148. .Where((wo, info) => info.tray_no == reqData.TrayNo).Select<FX_wo_mstr_info>().ToList();
  149. if (!pInfos.Any())
  150. throw SysExCore.ThrowFailException("根据托盘未获取到有效的组盘信息");
  151. entryOrder.F_orderType = (int)EEntryOrderType.EntryOrderTypeProduct;
  152. pInfos.ForEach(orderLine =>
  153. {
  154. var mat = CacheFacade.GetMatInfo(orderLine.wo_part, EMatType.Product);
  155. ctx.Insertable(new BILL_ENTRYORDERLINEDETAIL
  156. {
  157. F_addTime = DateTime.Now,
  158. F_addUserNo = LoginUser.UserNo,
  159. F_quantity = orderLine.qty,
  160. F_matNo = orderLine.wo_part,
  161. F_matName = mat?.F_matName,
  162. F_matType = (int)EMatType.Product,
  163. F_boxNo = orderLine.box_code,
  164. F_trayNo = orderLine.tray_no,
  165. F_pNo = entryOrder.F_no,
  166. }).ExecuteCommand();
  167. lstInv.Add(new BILL_INVENTORY
  168. {
  169. F_addTime = DateTime.Now,
  170. F_addUserNo = LoginUser.UserNo,
  171. F_editTime = DateTime.Now,
  172. F_matNo = orderLine.wo_part,
  173. F_matType = (int)EMatType.Mat,
  174. F_projectNo = mat.F_projectNo,
  175. F_quantity = orderLine.qty,
  176. F_unit = mat.F_unit,
  177. F_matName = mat?.F_matName,
  178. F_trayNo = reqData.TrayNo,
  179. F_warehouseNo = SysSetCore.GetSysSet().DefaultWarehouseNo
  180. });
  181. });
  182. entryOrder.F_totalOrderLines = pInfos.Count;
  183. entryOrder.F_relatedOrderNo = pInfos.FirstOrDefault()?.order_code;
  184. entryOrder.F_orderType = (int)EEntryOrderType.EntryOrderTypeProduct;
  185. task.F_orderType = (int)ETaskOrderType.EntryOrderTypeProduct;
  186. #endregion
  187. break;
  188. case EPointType.DPJ:
  189. #region 空托盘组
  190. ctx.Insertable(new BILL_ENTRYORDERLINEDETAIL
  191. {
  192. F_addTime = DateTime.Now,
  193. F_addUserNo = LoginUser.UserNo,
  194. F_quantity = 1,
  195. F_matNo = SysSetCore.GetSysSet().DefaultEmptyTrayGroupNo,
  196. F_matName = SysSetCore.GetSysSet().DefaultEmptyTrayGroupName,
  197. F_matType = (int)EMatType.Tary,
  198. F_trayNo = reqData.TrayNo,
  199. F_pNo = entryOrder.F_no
  200. }).ExecuteCommand();
  201. lstInv.Add(new BILL_INVENTORY
  202. {
  203. F_addTime = DateTime.Now,
  204. F_addUserNo = LoginUser.UserNo,
  205. F_editTime = DateTime.Now,
  206. F_matNo = nameof(EMatType.Tary),
  207. F_matType = (int)EMatType.Mat,
  208. //F_projectNo = mat.F_projectNo,
  209. F_quantity = 1,
  210. //F_unit = mat.F_unit,
  211. //F_matName = mat?.F_matName,
  212. F_trayNo = reqData.TrayNo,
  213. F_warehouseNo = SysSetCore.GetSysSet().DefaultWarehouseNo
  214. });
  215. entryOrder.F_orderType = (int)EEntryOrderType.EntryOrderTypeTray;
  216. task.F_orderType = (int)ETaskOrderType.EntryOrderTypeTrayGroup;
  217. #endregion
  218. break;
  219. default:
  220. throw SysExCore.ThrowFailException("请扫描正确的货位码!");
  221. }
  222. task.F_orderNo = entryOrder.F_no;
  223. task.F_posidNext = GetFreePointInfoByType((int)EPointType.SSXRK)?.F_no;
  224. UpdateInventory(lstInv, ctx);
  225. ctx.Insertable(entryOrder).ExecuteCommand();
  226. }
  227. else
  228. {
  229. var pointTo = GetFreePointInfoByType(point.F_type == (int)EPointType.YLAGV ? (int)EPointType.YLRKJXK : (int)EPointType.CPRKJXK);
  230. task.F_posidTo = pointTo.F_agv;
  231. task.F_posidNext = pointTo.F_agv;
  232. task.F_orderType = (int)ETaskOrderType.EntryOrderTypeOther;
  233. }
  234. var taskReturn = ctx.Insertable(task).ExecuteReturnEntity();
  235. ctx.CommitTran();
  236. return SysExCore.GetResSucc("AGV任务已生成");
  237. }
  238. catch (Exception ex)
  239. {
  240. ctx.RollbackTran();
  241. throw ex;
  242. }
  243. finally
  244. {
  245. ctx.Dispose();
  246. }
  247. }
  248. /// <summary>
  249. /// agv扫码出库
  250. /// </summary>
  251. /// <param name="reqData"></param>
  252. /// <returns></returns>
  253. public ResInfo AgvOut(AgvCarryRequest reqData)
  254. {
  255. if (string.IsNullOrWhiteSpace(reqData.LocationNo))
  256. throw SysExCore.ThrowFailException("请扫码正确的agv点位!");
  257. using (var ctx = SysDbCore.GetDbCtx())
  258. {
  259. ctx.BeginTran();
  260. if (!ctx.Queryable<BASE_POINT>().Any(a => (a.F_no == reqData.LocationNo ||a.F_agv==reqData.LocationNo) && (a.F_type == (int)EPointType.YLCKJXK || a.F_type == (int)EPointType.CPCKJXK || a.F_type == (int)EPointType.CPRKJXK || a.F_type == (int)EPointType.YLRKJXK)))
  261. throw SysExCore.ThrowFailException("请扫码正确的agv点位!");
  262. var pointFrom = ctx.Queryable<BASE_POINT>().Where(c => c.F_no == reqData.LocationNo).First();
  263. ///获取存储区AGV点位
  264. var pointTo = ctx.Queryable<BASE_POINT>().Where(c => c.F_type == (int)EPointType.CPAGV && c.F_status == (int)EPointSatus.Idle).OrderBy(o => o.F_sort).First();
  265. if (pointTo == null)
  266. throw SysExCore.ThrowFailException("没有闲置的存储区点位!");
  267. if (ctx.Queryable<WMS_TASK>().Any(t => t.F_posidFrom == reqData.LocationNo && t.F_taskStatus < (int)ETaskStatus.TaskFinish))
  268. throw SysExCore.ThrowFailException("已存在当前点位AGV任务,请勿重复创建!");
  269. //生产wms任务
  270. WMS_TASK task = new WMS_TASK
  271. {
  272. F_addTime = DateTime.Now,
  273. F_addUserNo = LoginUser.UserNo,
  274. F_posidFrom = pointFrom.F_agv,
  275. F_posidcur = pointFrom.F_agv,
  276. F_posidNext = pointTo.F_no,
  277. F_posidTo = pointTo.F_no,
  278. F_priority = (int)EPriority.NotUrgent,
  279. F_taskStatus = (int)ETaskStatus.NotIssued,
  280. F_taskType = (int)ETaskComType.OutStock,
  281. F_EquipmentType = (int)EEquipmentType.AGV,
  282. F_orderType = (int)ETaskOrderType.StockOutOrderTypeOther,
  283. };
  284. ctx.Insertable(task).ExecuteCommand();
  285. //ctx.Updateable(point).UpdateColumns(it => it.F_status).WhereColumns(it => it.F_no== point.F_no).ExecuteCommand();
  286. ctx.Updateable<BASE_POINT>().SetColumns(it => new BASE_POINT()
  287. {
  288. F_status = (int)EPointSatus.Occupied,
  289. F_editTime = DateTime.Now,
  290. F_editUserNo = LoginUser.UserNo,
  291. //F_isBonded = reqData.IsBonded
  292. }).Where(w => w.F_no == pointTo.F_no).ExecuteCommand();
  293. return SysExCore.GetResSucc("AGV任务已生成");
  294. }
  295. }
  296. }
  297. }