using HH.WCS.JuShi.device; using HH.WCS.JuShi.process; using HH.WCS.JuShi.util; using HH.WCS.JuShi.wms; using Newtonsoft.Json; using SqlSugar; using System; using System.Collections.Generic; using System.Linq; using System.Threading; using static HH.WCS.JuShi.api.ApiModel; using static HH.WCS.JuShi.api.OtherModel; namespace HH.WCS.JuShi.api { /// /// api接口辅助类 /// public class ApiHelper { static ApiHelper() { } /// /// 找终点空货位 /// /// /// internal static Location FindEndcolByLocList(List locations, string itemcode) { try { var db = new SqlHelper().GetInstance(); Location end = null; //根据终点货位找空闲货位 var rows = locations.Select(a => a.N_COL).Distinct().ToList(); for (int i = 0; i < rows.Count; i++) { var rowList = locations.Where(r => r.N_COL == rows[i]).ToList(); if (rowList.Count(a => a.N_CURRENT_NUM == 0) > 0) { Location other = null; //当前排没有锁并且有空位置 //先找满位,然后后面一层要么是空,要么不存在 other = rowList.OrderByDescending(a => a.N_LAYER).Where(a => a.N_CURRENT_NUM == 0).FirstOrDefault(); //if (full == null) //{ // //没有满位,那就找最小的空位 // other = rowList.OrderBy(a => a.N_LAYER).FirstOrDefault(); //} //else //{ // other = rowList.OrderBy(a => a.N_LAYER).Where(a => a.N_LAYER > full.N_LAYER).FirstOrDefault(); //} //if (other != null && (!string.IsNullOrEmpty(other.C_ENABLE) && other.C_ENABLE == "禁用")) //{ // //禁用了选择后面一个货位 // other = db.Queryable().OrderBy(a => a.N_LAYER).Where(a => (string.IsNullOrEmpty(a.C_ENABLE) || a.C_ENABLE.Trim() != "禁用") && a.S_AREA_CODE == other.S_AREA_CODE && a.N_ROW == other.N_ROW && a.N_COL > other.N_COL).First(); // //LogHelper.Info($"禁用选择后一个货位{result}", "成品"); //} if (other != null) { end = other; break; } } } return end; } catch (Exception) { throw; } } /// /// 找起点满货位 /// /// /// internal static Location FindStartcolByLoclist(List locations) { try { Location start = null; var rowsStart = locations.Select(a => a.N_ROW).Distinct().ToList(); for (int i = 0; i < rowsStart.Count; i++) { var rowList = locations.Where(r => r.N_ROW == rowsStart[i]).ToList().OrderByDescending(a => a.N_COL); //当前排没有锁并且有满货位 if (rowList.Count(a => a.S_LOCK_STATE.Trim() != "无") == 0 && rowList.Count(a => a.N_CURRENT_NUM == 1) > 0) { Location other = null; //找到最大的满位,如果有就直接出 var full = rowList.OrderByDescending(a => a.N_COL).Where(a => a.N_CURRENT_NUM == 1).FirstOrDefault(); if (full != null) { other = full; } if (other != null) { start = other; break; } } } return start; } catch (Exception) { throw; } } private static int GetLocTrayNum(List locNum, int num) { int trayNum = locNum.Count(); switch (trayNum) { case 0: num = 0; break; case 1: num = 1; break; case 2: num = 1; break; case 3: num = 2; break; case 4: num = 2; break; } return num; } internal static SimpleResult ShippingOrderExecute(ShippingOrderCheck model) { var result = new SimpleResult(); //检查库存,更新发货单,生成分拣单,自动合并波次 //这个后台做比较麻烦,mobox3库存在内存中,任务完成的时候无法增加,还是用c#直接管内存,计算比较方便 WMSHelper.CreateSortingOrder(model.out_nos.Split(',').ToList()); return result; } /// /// 后面要把方法放到wmsHelper中 /// /// /// internal static SimpleResult SortingResultCheck(List models) { //生成分拣结果,更新分拣明细状态 var result = new SimpleResult(); WMSHelper.SortingConfrim(models); return result; } /// /// 后面要把方法放到wmsHelper中 /// /// /// internal static SimpleResult Instock(InstockInfo model) { var result = new SimpleResult(); //pda入库,目前人工放货在巷道口,扫托盘,后台只能计算当前巷道的终点,单深位立库 //1,判断托盘信息,一种是码盘后的,默认enable是N,另一种是分拣回的 var cntr = ContainerHelper.GetCntr(model.cntr); if (cntr != null) { var sortingInfo = WMSHelper.GetSortingDetailByCntr(model.cntr); if (cntr.C_ENABLE == "Y" && sortingInfo != null && sortingInfo.Count > 0) { result.resultCode = 2; result.resultMsg = $"托盘{model.cntr}未分拣完成"; } } else { result.resultCode = 1; result.resultMsg = $"托盘{model.cntr}不存在"; } if (result.resultCode == 0) { //获取接驳位所在的巷道, 查找功能区,入库接驳位找逻辑库区(每个巷道一个逻辑库区) var fa = LocationHelper.GetFunctionAreaByCode(model.start, 2, 10); if (fa != null) { //创建入库作业,简单判断一下是否有可入货位,如果不判断,人工货放上去一直不能入,也不知道原因 var end = LocationHelper.GetZoneLoc(fa.S_MASTER_CODE); if (end != null) { //判断托盘是否已经生成任务,如果没有则生成 var wmsTask = WMSHelper.GetWmsTaskByCntr(model.cntr); if (wmsTask != null) { result.resultCode = 3; result.resultMsg = $"起点{model.start} 托盘{model.cntr}已经创建任务,请勿重复申请"; } else { wmsTask = new WMSTask { S_CNTR_CODE = model.cntr, S_CODE = WMSHelper.GenerateTaskNo(), S_START_LOC = model.start, S_END_LOC = end.S_LOC_CODE, N_TYPE = 1, S_TYPE = WMSTask.GetTypeStr(1), S_OP_DEF_CODE = "", S_OP_DEF_NAME = "pda入立库" }; if (WMSHelper.CreateWmsTask(wmsTask)) { LocationHelper.LockLoc(end.S_LOC_CODE, 1); result.resultMsg = $"创建作业成功,作业号{wmsTask.S_CODE}"; } } } else { result.resultCode = 3; result.resultMsg = $"起点{model.start}对应的逻辑库区{fa.S_MASTER_CODE}没有可用货位,请更换巷道"; } } else { result.resultCode = 3; result.resultMsg = $"起点{model.start}没有对应的逻辑库区,请在逻辑库区设置功能区-入库接驳位"; } } return result; } internal static SimpleResult SortingOrderExecute(SortingOrderCheck model) { var result = new SimpleResult(); //分拣单配货执行 WMSHelper.CreateSortingOrderDetail(model.s_no); return result; } internal static SimpleResult CheckSortingWholeCntr(CheckSortingWholeCntr model) { var result = new SimpleResult(); if (WMSHelper.CheckSortingWholeCntr(model.cntr, model.autoSort == 1)) { result.resultCode = 1; result.resultMsg = "整托分拣"; } return result; } internal static CodeInfo GetCodeInfo(string code, string org) { //return new CodeInfo { Fitemid_XK=code, FSourceNo="123456"}; CodeInfo result = null; try { var db = new SqlHelper().GetInstance(Settings.SqlServer1); var nameP = new SugarParameter("@FBarCode", code); var orgP = new SugarParameter("@Forg", org); //var ageP = new SugarParameter("@age", null, true);//设置为output //var dt = db.Ado.UseStoredProcedure().GetDataTable("sp_school", nameP, ageP);//返回dt result = db.Ado.UseStoredProcedure().SqlQuery("WMS_FBarCode", nameP, orgP).First();//返回List Console.WriteLine($"读存储过程成功,result={result}"); } catch (Exception ex) { Console.WriteLine(ex.Message); } return result; } //internal static SimpleResult PalletSorting1(PalletSorting1 model) //{ // var result = new SimpleResult(); // //校验入库单数量,不可以超,成功后插入托盘物料表,更新入库单累计数量 // //也可以直接lua查询入库单数量,做校验 // //先用bar_code读存储过程获取信息 // var codeInfo = GetCodeInfo(model.bar_code, model.org); // var info = WMSHelper.GetPutawayOrderDetail(model.bar_code); // if (info != null) // { // if (info.F_QTY - info.F_ACC_B_QTY >= model.qty) // { // // 插入到托盘明细表 // var cntr = ContainerHelper.GetCntr(model.cntr_code, true); // if (cntr != null) // { // ContainerHelper.BindCntrItem(cntr, model.bar_code, info.S_BATCH_NO, model.qty, info.S_BATCH_NO); // //更新入库单累计绑定数量 // info.F_ACC_B_QTY += model.qty; // WMSHelper.UpdatePutawayOrderDetailQty(info); // } // else // { // result.resultCode = 2; // result.resultMsg = "获取托盘信息失败"; // } // } // else // { // result.resultCode = 1; // result.resultMsg = "累计码盘数量超出入库单数量"; // } // } // else // { // result.resultCode = 3; // result.resultMsg = $"未获取到该物料{model.bar_code}的入库单明细信息"; // } // return result; //} public class AddTaskModel { public string From { get; set; } public string To { get; set; } public string No { get; set; } } public class TN_LocationModel { public string TN_Location { get; set; } } public class CodeInfo { /// /// 生产订单内码 /// public string FInterID { get; set; } /// /// 生产订单编号 /// public string FSourceNo { get; set; } /// /// 批号 /// public string FGMPBatchNo { get; set; } public string FState { get; set; } /// /// 物料编码(内码就是编码) /// public string Fitemid_XK { get; set; } /// /// 分录id /// public string Fentryid { get; set; } } public class NoteInfo : CodeInfo { public string WmsBillNo { get; set; } } } }