using iWareSda_QQJF.SRM.SrmService; using iWareSda_QQJF.SRMTRAN.SrmTranService; using iWareSda_QQJF.SrmTranModel; using iWareSda_QQJF.WCSNEW.EDM; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Data.Entity; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace iWareSda_QQJF.WCSNEW.生成主任务 { public static class CreateMainTask { public static Dictionary InErrorMsg = new Dictionary() { {47,""}, {48,""}, {61,""}, {65,""}, {32,""}, {15,""}, }; public static bool[] needMove = { false, false, false, false, false, false, false, false, false }; static Dictionary oldContainerName = new Dictionary(); static Dictionary times = new Dictionary(); /// /// 生成入库任务 /// /// public static void CreatInTask(object obj) { try { while (true) { string erromsg = ""; #region 准备数据 int tranObj = (int)obj; int tranId = 0; //int tranObj = 0; SRMTRAN.SrmTranService.SrmTranService srv = new SRMTRAN.SrmTranService.SrmTranService(); //for (int i = 0; i < 6; i++) //{ //tranObj = i; List hasGoodList = srv.HasTranGoods(); if (hasGoodList == null || hasGoodList.Count == 0) { continue; } if (hasGoodList[tranObj] == 1) { switch (tranObj) { case 0: tranId = 47; break; case 1: tranId = 48; break; case 2: tranId = 61; break; case 3: tranId = 65; break; case 4: tranId = 32; break; case 5: tranId = 15; break; default: break; } } else { continue; } //} if (tranId == 0) { continue; } //srv.GetSrmConveyorStationInfo(tranId); EntitySrmTranView TranInfo = JsonConvert.DeserializeObject(srv.GetSrmConveyorStationInfo(tranId)); string containerName = TranInfo.Code;//扫码扫到的 decimal weightGet = (decimal)TranInfo.weihgt; if (oldContainerName.ContainsKey(tranId) && times.ContainsKey(tranId)) { if (containerName != oldContainerName[tranId]) { oldContainerName[tranId] = containerName; times[tranId] = 0; continue; } else { times[tranId]++; if (times[tranId] < 10) { continue; } else { times[tranId] = 0; } } } else { if (!oldContainerName.ContainsKey(tranId)) { oldContainerName.Add(tranId, containerName); } if (!times.ContainsKey(tranId)) { times.Add(tranId, 0); } continue; } #endregion using (Model db = new Model()) { var container = db.BASE_CONTAINER.FirstOrDefault(x => x.CONTAINERNAME == containerName && x.ENABLE == 1); decimal totalWeightAll = 0; decimal difference = 0; if (container == null || container.ISLOCK == 1) { Helper.Speaking("输送线" + tranId.ToString() + "号器具不可用"); InErrorMsg[tranId] = "器具不可用"; Thread.Sleep(5000); WZ.Useful.Commons.LogTextHelper.WriteLine("WCS", "生成入库任务", "输送线" + tranId.ToString() + "号器具不可用"); continue; } if (container != null) { //判断是否已入库 BASE_PLACE_VS_CONTAINER pvcOfContainer = db.BASE_PLACE_VS_CONTAINER.FirstOrDefault(x => x.CONTAINERID == container.ID && x.ENABLE == 1); TASK_TASK taskOfContainer = db.TASK_TASK.FirstOrDefault(x => x.CONTAINERID == container.ID && x.ENABLE == 1 && x.HASFINISHED == 0); if (pvcOfContainer != null || taskOfContainer != null) { //重复入库 Helper.Speaking("输送线" + tranId.ToString() + "号重复入库"); InErrorMsg[tranId] = "重复入库"; Thread.Sleep(5000); WZ.Useful.Commons.LogTextHelper.WriteLine("WCS", "生成入库任务", "输送线" + tranId.ToString() + "号重复入库"); continue; } List cviList = container.BASE_CONTAINER_VS_ITEM.Where(x => x.ENABLE == 1).ToList(); ////最大库容 //bool needContinue = false; //foreach (var i in cviList) //{ // int num = db.View_BASE_PLACE_VS_CONTAINER.Where(x => x.itemName == i.BASE_ITEM.ITEMNAME).Sum(x => (x.itemNum ?? 0)); // if ((i.BASE_ITEM.MAXSTORAGE ?? 0) < num) // { // Helper.Speaking("零件" + i.BASE_ITEM.ITEMNAME + "超出最大库容"); // Thread.Sleep(5000); // needContinue = true; // break; // } //} //if (needContinue) //{ // continue; //} //称重 totalWeightAll = totalWeightAll + container.WEIGHT ?? 0; difference = difference + container.WEIGHTDIFFERENCE ?? 0; foreach (var i in cviList) { totalWeightAll = totalWeightAll + i.TOTALWEIGHT ?? 0;//计算理论重量 difference = difference + (i.ITEMNUM ?? 0) * (i.BASE_ITEM.WEIGHTDIFFERENCE ?? 0);//理论总公差 } if (totalWeightAll + difference > weightGet && totalWeightAll - difference < weightGet)//符合称重 { WZ.Useful.Commons.LogTextHelper.WriteLine("重量:" + weightGet, "器具:" + container.CONTAINERNAME, "输送线:" + tranId.ToString()); } else { //超重 //WZ.Useful.Commons.LogTextHelper.WriteLine("超重", "器具:"+ container.CONTAINERNAME, "输送线:"+tranId.ToString()); Helper.Speaking("输送线" + tranId.ToString() + "号超重" + "器具" + container.CONTAINERNAME + "称重" + weightGet.ToString()); InErrorMsg[tranId] = "超重"; Thread.Sleep(5000); WZ.Useful.Commons.LogTextHelper.WriteLine("WCS", "生成入库任务", "输送线" + tranId.ToString() + "号超重" + "器具" + container.CONTAINERNAME + "称重" + weightGet.ToString()); continue; } BASE_PLACE to_place = CreateIn(container.CONTAINERNAME); BASE_CONTAINER_VS_ITEM cvi = db.BASE_CONTAINER_VS_ITEM.FirstOrDefault(x => (x.CONTAINERID ?? 0) == container.ID && x.ENABLE == 1); int userId = 1; if (cvi != null) { userId = cvi.CREATEUSERID ?? 1; } if (to_place != null) { WZ.Useful.Commons.LogTextHelper.WriteLine("满入记录日志:第一次找库位" + to_place.PLACE + ";器具号-" + container.CONTAINERNAME); TASK_TASK task = new TASK_TASK() { CONTAINERID = container.ID, CREATETIME = DateTime.Now, CREATEUSERID = userId, ENABLE = 1, ERRORDEVICEID = 0, ERRORMSG = 0, HASFINISHED = 0, HASREADED = 0, ISERROR = 0, OUTTYPE = 0, ISNEEDREDIRECT = 0, TASKLEVEL = 0, //ORDERID = 0, TASKSTATUS = "新建", TASKTYPE = 1,//入库 SOURCEPLACE = tranId.ToString(),//待填,根据扫码枪扫的位置口确定入库口 TOPLACE = to_place.PLACE, LASTWEIGHT = weightGet.ToString(), }; db.TASK_TASK.Add(task); if (db.SaveChanges() > 0) { InErrorMsg[tranId] = ""; CreateTaskRecord(task); srv.ClearTranGoods(tranId);//复位 } } else { erromsg = "没有充足的空库位!"; InErrorMsg[tranId] = "没有充足的空库位"; WZ.Useful.Commons.LogTextHelper.WriteLine("WCS", "生成入库任务", container.CONTAINERNAME + "没有充足的空库位"); } } else { erromsg = "未识别到该托盘号!"; InErrorMsg[tranId] = "未识别到该托盘号"; WZ.Useful.Commons.LogTextHelper.WriteLine("WCS", "生成入库任务", container.CONTAINERNAME + "未识别到该托盘号"); } } Thread.Sleep(1000); } } catch (Exception ex) { WZ.Useful.Commons.LogTextHelper.WriteLine("WCS", "生成入库任务", ex.ToString()); throw; } } /// /// 根据出库单确定要出库库位并生成主任务 /// 任务分解 /// /// public static void CreatOutTask(object obj) { while (true) { try { using (Model db = new Model()) { var outOrdePlan = db.ORDER_OUTORDER.OrderBy(x => x.DOTIME).FirstOrDefault(x => (x.CHECKOUTNUM ?? 0) < x.TOTALOUTNUM && x.ENABLE == 1 && x.ORDERSTATUS == "执行中"); if (outOrdePlan != null) { if (outOrdePlan.ORDERTYPE != "空器具出库") { string itemname = outOrdePlan.BASE_ITEM.ITEMNAME; int planeOutCount = (int)outOrdePlan.TOTALOUTNUM - (int)outOrdePlan.CHECKOUTNUM; int errorCount = 0; int taskCount = 0; View_BASE_PLACE_VS_CONTAINER pvcOut = CreateOut(itemname, planeOutCount, outOrdePlan.ORDERTYPE, out errorCount, out taskCount); if (pvcOut != null) { WZ.Useful.Commons.LogTextHelper.WriteLine("", pvcOut.place, (pvcOut.isLock ?? 0).ToString()); BASE_CONTAINER_VS_ITEM cvi = db.BASE_CONTAINER_VS_ITEM.FirstOrDefault(x => x.BASE_CONTAINER.CONTAINERNAME == pvcOut.containerName && x.ENABLE == 1 && x.BASE_ITEM.ITEMNAME == pvcOut.itemName); if (CreateTask(db, pvcOut, outOrdePlan)) { cvi.ORDER_OUTORDER = outOrdePlan; outOrdePlan.CHECKOUTNUM = outOrdePlan.CHECKOUTNUM + pvcOut.itemNum; if (outOrdePlan.CHECKOUTNUM >= outOrdePlan.TOTALOUTNUM) { //outOrdePlan.ORDERSTATUS = "完成"; outOrdePlan.ISFINISH = 1; } } db.SaveChanges(); } else { string status = "库存不足 "; //无可用库位 if (errorCount != 9) { status = status + "设备异常 "; } if (taskCount != 0) { status = status + "任务占用 "; } outOrdePlan.ISFINISH = 1; outOrdePlan.ORDERSTATUS = status; db.SaveChanges(); } } else {//表示 该出库计划是 空器具出库类型的 try { List taskList = db.TASK_TASK.Where(x => x.HASFINISHED == 0 && x.ENABLE == 1).ToList(); List containerNameList = new List(); foreach (var i in taskList) { containerNameList.Add(i.BASE_CONTAINER.CONTAINERNAME); } //排除故障设备的库位 List errorList = new List(); SrmService srmService = new SrmService(); for (int i = 0; i < 9; i++) { if (srmService.IsNotAlarm(i + 1)) { errorList.Add(i + 1); } } var list = outOrdePlan.BASE_ITEM.USECONTAINERTYPE.Split(',').ToList(); List pvcList = db.BASE_PLACE_VS_CONTAINER.Where(x => list.Contains(x.BASE_CONTAINER.CONTAINERTYPE) && x.ENABLE == 1 && x.BASE_CONTAINER.BASE_CONTAINER_VS_ITEM.Count() == 0 && !containerNameList.Contains(x.BASE_CONTAINER.CONTAINERNAME) && errorList.Contains((x.BASE_PLACE.SRMID ?? 0)) && (x.BASE_PLACE.ISLOCK ?? 0) != 1).ToList(); var group = pvcList.GroupBy(x => x.BASE_PLACE.SRMID); int srmid = 0; int count = 0; foreach (var i in group) { if (i.Count() > count || srmid == 0) { count = i.Count(); srmid = i.Key ?? 0; } } BASE_PLACE_VS_CONTAINER pvc = pvcList.OrderByDescending(x => x.BASE_PLACE.PLACELEVEL).FirstOrDefault(x => x.BASE_PLACE.SRMID == srmid); if (pvc != null) { WZ.Useful.Commons.LogTextHelper.WriteLine("", pvc.BASE_PLACE.PLACE, (pvc.BASE_PLACE.ISLOCK ?? 0).ToString()); if (CreateTask(db, pvc, outOrdePlan)) { //cvi.ORDER_OUTORDER = outOrdePlan; outOrdePlan.CHECKOUTNUM = outOrdePlan.CHECKOUTNUM + 1; if (outOrdePlan.CHECKOUTNUM >= outOrdePlan.TOTALOUTNUM) { //outOrdePlan.ORDERSTATUS = "完成"; outOrdePlan.ISFINISH = 1; } } } else { string status = "库存不足 "; //无可用库位 if (errorList.Count != 9) { status = status + "设备异常 "; } if (taskList.Count != 0) { status = status + "任务占用 "; } outOrdePlan.ISFINISH = 1; outOrdePlan.ORDERSTATUS = status; db.SaveChanges(); } db.SaveChanges(); } catch (Exception ex) { WZ.Useful.Commons.LogTextHelper.WriteLine("WCS", "生成空器具出库任务", ex.ToString()); } } } } } catch (Exception ex) { WZ.Useful.Commons.LogTextHelper.WriteLine("WCS", "生成出库任务", ex.ToString()); } Thread.Sleep(1000); } } /// /// 创建主任务 /// /// /// /// private static bool CreateTask(Model db, View_BASE_PLACE_VS_CONTAINER pvcvi, ORDER_OUTORDER order) { try { string tranLine = (order.TRANLINE ?? 0).ToString(); if (string.IsNullOrEmpty(tranLine) || tranLine == "0") { tranLine = "67"; } using (Model edm = new Model()) { //获取每个口的任务占用数量 int tranNum1 = edm.TASK_TASK.Where(x => x.TOPLACE == "67" && x.HASFINISHED == 0).Count();//东分拣 int tranNum2 = edm.TASK_TASK.Where(x => x.TOPLACE == "51" && x.HASFINISHED == 0).Count();//东冲压1 int tranNum3 = edm.TASK_TASK.Where(x => x.TOPLACE == "64" && x.HASFINISHED == 0).Count();//东冲压2 int tranNum4 = edm.TASK_TASK.Where(x => x.TOPLACE == "34" && x.HASFINISHED == 0).Count();//西分拣 int tranNum5 = edm.TASK_TASK.Where(x => x.TOPLACE == "12" && x.HASFINISHED == 0).Count();//西空托盘 int tranNum6 = edm.TASK_TASK.Where(x => x.TOPLACE == "19" && x.HASFINISHED == 0).Count();//西焊装1 int tranNum7 = edm.TASK_TASK.Where(x => x.TOPLACE == "30" && x.HASFINISHED == 0).Count();//西焊装2 if ((order.TRANLINE ?? 0) == 999) { //if (tranNum6 <= tranNum7) if (int.Parse(pvcvi.place.Substring(0, 1)) > 5)//5号巷道以上走19 { tranLine = "19"; } else { tranLine = "30"; } } else if ((order.TRANLINE ?? 0) == 997) { //if (tranNum2 <= tranNum3 && tranNum2 <= tranNum1) if (int.Parse(pvcvi.place.Substring(0, 1)) >= 5)//5号巷道以上走51 { tranLine = "51"; } //else if (tranNum3 <= tranNum1) //{ // tranLine = "64"; //} //else //{ // tranLine = "67"; //} else { tranLine = "64"; } } } if (pvcvi != null) { var container = db.BASE_CONTAINER.FirstOrDefault(x => x.CONTAINERNAME == pvcvi.containerName); //创建叉车任务 TASK_TASK task = new TASK_TASK() { CONTAINERID = container.ID, CREATETIME = DateTime.Now, CREATEUSERID = order.CREATORID, ENABLE = 1, ERRORDEVICEID = 0, ERRORMSG = 0, HASFINISHED = 0, HASREADED = 0, ISERROR = 0, OUTTYPE = 0, ISNEEDREDIRECT = 0, TASKLEVEL = 0, ORDERID = order.ID, TASKSTATUS = "新建", TASKTYPE = 2,//出库 SOURCEPLACE = pvcvi.place, TOPLACE = tranLine,//待填根据ordertype是焊装还是调价,在选择出库口的位置 }; db.TASK_TASK.Add(task); db.SaveChanges(); CreateTaskRecord(task); } return true; } catch (Exception ex) { WZ.Useful.Commons.LogTextHelper.WriteLine("WCS", "CreateTask", ex.ToString()); return false; } } /// /// 创建主任务 /// /// /// /// private static bool CreateTask(Model db, BASE_PLACE_VS_CONTAINER pvc, ORDER_OUTORDER order) { try { string tranLine = order.TRANLINE.ToString(); using (Model edm = new Model()) { //获取每个口的任务占用数量 int tranNum1 = edm.TASK_TASK.Where(x => x.TOPLACE == "67" && x.HASFINISHED == 0).Count();//东分拣 int tranNum2 = edm.TASK_TASK.Where(x => x.TOPLACE == "51" && x.HASFINISHED == 0).Count();//东冲压1 int tranNum3 = edm.TASK_TASK.Where(x => x.TOPLACE == "64" && x.HASFINISHED == 0).Count();//东冲压2 int tranNum4 = edm.TASK_TASK.Where(x => x.TOPLACE == "34" && x.HASFINISHED == 0).Count();//西分拣 int tranNum5 = edm.TASK_TASK.Where(x => x.TOPLACE == "12" && x.HASFINISHED == 0).Count();//西空托盘 int tranNum6 = edm.TASK_TASK.Where(x => x.TOPLACE == "19" && x.HASFINISHED == 0).Count();//西焊装1 int tranNum7 = edm.TASK_TASK.Where(x => x.TOPLACE == "30" && x.HASFINISHED == 0).Count();//西焊装2 int tranNum8 = edm.TASK_TASK.Where(x => x.TOPLACE == "68" && x.HASFINISHED == 0).Count();//东冲压3,[Editby kejj,20230614] if ((order.TRANLINE ?? 0) == 999) { //if (tranNum6 <= tranNum7) if (int.Parse(pvc.BASE_PLACE.PLACE.Substring(0, 1)) > 5)//5号巷道以上走19 { tranLine = "19"; } else { tranLine = "30"; } } else if ((order.TRANLINE ?? 0) == 997) { //if (tranNum2 <= tranNum3 && tranNum2 <= tranNum1) if (int.Parse(pvc.BASE_PLACE.PLACE.Substring(0, 1)) >= 5)//5号巷道以上走51 { tranLine = "51"; } //else if (tranNum3 <= tranNum1) //{ // tranLine = "64"; //} //else //{ // tranLine = "67"; //} else { tranLine = "64"; } } //else if ((order.TRANLINE ?? 0) == 1000) //{ // tranLine = "68"; //} } if (pvc != null) { var container = pvc.BASE_CONTAINER; TASK_TASK task = new TASK_TASK() { CONTAINERID = container.ID, CREATETIME = DateTime.Now, CREATEUSERID = order.CREATORID, ENABLE = 1, ERRORDEVICEID = 0, ERRORMSG = 0, HASFINISHED = 0, HASREADED = 0, ISERROR = 0, OUTTYPE = 0, ISNEEDREDIRECT = 0, TASKLEVEL = 0, ORDERID = order.ID, TASKSTATUS = "新建", TASKTYPE = 2,//出库 SOURCEPLACE = pvc.BASE_PLACE.PLACE, TOPLACE = tranLine,//待填根据ordertype是焊装还是调价,在选择出库口的位置 }; db.TASK_TASK.Add(task); //创建叉车任务 //去掉验证PDA上选择目的地才能生成叉车任务的限制 【Editby shaocx,2023-06-07】 //我靠,还不能直接 去掉验证PDA上选择目的地才能生成叉车任务的限制,因为会在这一行报错 carTask.TODESTINATION = order.BASE_PRODUCTIONLINE.PRODUCTIONLINENAME; 【Editby shaocx,2023-06-11】 //if ((order.TOLINEID ?? 0) != 0)[Editby kejj,20230621] //{ //CAR_CARTASK carTask = new CAR_CARTASK(); ////通过出库口找目的地 //BASE_PRODUCTIONLINE pl = db.BASE_PRODUCTIONLINE.FirstOrDefault(x => x.PRODUCTIONLINECODE == task.TOPLACE); //string detail = ""; //foreach (var i in task.BASE_CONTAINER.BASE_CONTAINER_VS_ITEM) //{ // if (!string.IsNullOrEmpty(i.BASE_ITEM.ITEMDES)) // { // detail = detail + i.BASE_ITEM.ITEMNAME + " " + i.BASE_ITEM.ITEMDES + ":" + i.ITEMNUM + "个;\n"; // } //} //if (pl != null) //{ // carTask.CARTASKNAME = IWareDataAccess.Car.CARTASK.CarTaskSqlFunc.GetCode(); // carTask.FROMDESTINATION = pl.PRODUCTIONLINENAME; // carTask.TODESTINATION = order.BASE_PRODUCTIONLINE?.PRODUCTIONLINENAME; // carTask.CONTAINERID = task.CONTAINERID; // carTask.TASKSTATUS = "新建"; // carTask.ENABLE = 1; // carTask.UPDATETIME = DateTime.Now; // carTask.CREATORID = order.CREATORID; // carTask.ORDER_OUTORDER = order; // carTask.ITEMDETAIL = detail; // db.CAR_CARTASK.Add(carTask); //} //} db.SaveChanges(); //创建任务记录 CreateTaskRecord(task); return true; } return false; } catch (Exception ex) { WZ.Useful.Commons.LogTextHelper.WriteLine("WCS", "CreateTask", ex.ToString()); return false; } } /// /// 找出出库库存 /// /// /// /// public static View_BASE_PLACE_VS_CONTAINER CreateOut(string itemName, int itemNum, string type, out int errorCount, out int taskCount) { errorCount = 0; taskCount = 0; using (Model edm = new Model()) { //筛选任务中的 List taskList = edm.TASK_TASK.Where(x => x.HASFINISHED == 0 && x.ENABLE == 1).ToList(); List containerNameList = new List(); foreach (var i in taskList) { containerNameList.Add(i.BASE_CONTAINER.CONTAINERNAME); } //排除故障设备的库位 List errorList = new List(); SrmService srmService = new SrmService(); for (int i = 1; i < 10; i++) { if (srmService.IsNotAlarm(i)) { errorList.Add((i).ToString()); } //*/ //模拟,暂时写死 [Editby shaocx,2022-10-08] //errorList.Add((i).ToString()); } List pvcList = new List(); if (type != null && (type.Contains("冲压待返修") || type.Contains("焊装待返修"))) { pvcList = edm.View_BASE_PLACE_VS_CONTAINER.Where(x => x.itemName == itemName && x.enable == 1 && x.status == "IN" && !containerNameList.Contains(x.containerName) && (x.isLock ?? 0) == 0 && errorList.Contains(x.place.Substring(0, 1)) && (x.inType != null && x.inType == type)).ToList(); } else { pvcList = edm.View_BASE_PLACE_VS_CONTAINER.Where(x => x.itemName == itemName && x.enable == 1 && x.status == "IN" && !containerNameList.Contains(x.containerName) && (x.isLock ?? 0) == 0 && errorList.Contains(x.place.Substring(0, 1)) && (x.inType == null || !x.inType.Contains("返修"))).ToList(); } //优先余料回库 List pvcReturnList = pvcList.Where(x => x.inType == "余料回库").ToList(); if (pvcReturnList.Count != 0)//存在 { View_BASE_PLACE_VS_CONTAINER pvcReturnOut = pvcReturnList.OrderBy(x => x.itemNum).ThenByDescending(x => x.placeLevel).FirstOrDefault(); return pvcReturnOut; } //选择零件数量大的巷道 var group = pvcList.GroupBy(x => x.place.Substring(0, 1)).ToList(); string srmid = ""; int count = 0; foreach (var i in group) { if (i.Count() < count || srmid == "") { count = i.Count(); srmid = i.Key; } } //判断是否故障 List pvcSrmList = edm.View_BASE_PLACE_VS_CONTAINER.Where(x => x.place.Substring(0, 1) == srmid && x.itemName == itemName && x.enable == 1 && (x.isLock ?? 0) == 0 && (x.isFull ?? 0) == 1 && !containerNameList.Contains(x.containerName)).ToList(); //View_BASE_PLACE_VS_CONTAINER pvcOut = pvcSrmList.OrderByDescending(x => x.placeLevel).FirstOrDefault(x => x.itemNum >= itemNum); //if (pvcOut != null) //{ // //存在一箱满足 //} //else //{ // //不存在一箱满足,则出最少 // pvcOut = pvcSrmList.OrderByDescending(x => x.itemNum).ThenByDescending(x => x.placeLevel).FirstOrDefault(); //} //优先出少的 DateTime timeNow = DateTime.Now; View_BASE_PLACE_VS_CONTAINER pvcOut = pvcSrmList.OrderBy(x => x.CVIUpdateTime).ThenBy(x => x.itemNum).ThenByDescending(x => x.placeLevel).FirstOrDefault(x => (timeNow - (x.CVIUpdateTime ?? DateTime.Now)).TotalDays > 5); if (pvcOut == null) { pvcOut = pvcSrmList.OrderBy(x => x.itemNum).ThenByDescending(x => x.placeLevel).FirstOrDefault(); } errorCount = errorList.Count; taskCount = taskList.Count; return pvcOut; } } #region 寻找空库位,原先的方法 /// /// 找出入库库位(寻找空库位) /// //public static BASE_PLACE CreateIn(string containerName) //{ // using (Model edm = new Model()) // { // BASE_CONTAINER container = edm.BASE_CONTAINER.FirstOrDefault(x => x.CONTAINERNAME == containerName); // //排除故障设备的库位 // List goodSrmList = new List();//可用的堆垛机集合 [Editby shaocx,2022-10-08] // SrmService srmService = new SrmService(); // for (int i = 1; i < 10; i++) // { // if (srmService.IsNotAlarm(i)) // { // goodSrmList.Add(i); // } // } // //注意:表BASE_PALLET的PALLETTYPE 要对应 表BASE_PLACETYPE的PlaceType字段 // //下面是根据托盘类型去寻找 能存放该托盘类型的库区 // //例如:2巷道和4巷道,都是能存放托盘类型 G和H的 // List placeList = edm.BASE_PLACE.Where(x => container.BASE_PALLET.PALLETTYPE.Contains(x.BASE_PLACETYPE.PLACETYPE) && (x.ISLOCK ?? 0) == 0 && (x.ISFULL ?? 0) == 0 && goodSrmList.Contains((x.SRMID ?? 0))).ToList(); // //记录任务中的占用数量 // List taskList = edm.TASK_TASK.Where(x => x.HASFINISHED == 0 && x.TASKTYPE == 1 && x.BASE_CONTAINER.BASE_PALLET.PALLETTYPE == container.BASE_PALLET.PALLETTYPE && x.TASKTYPE == 1).ToList(); // var groupTask = taskList.GroupBy(x => x.TOPLACE.Substring(0, 1)).ToList();//当前未结束的、指定托盘类型的入库任务目标位置的分组集合 // //计算此种的数量 // BASE_CONTAINER_VS_ITEM cvi = edm.BASE_CONTAINER_VS_ITEM.FirstOrDefault(x => x.BASE_CONTAINER.CONTAINERNAME == containerName); // List placeFullList = new List(); // if (cvi == null)//空器具 // { // placeFullList = edm.View_BASE_PLACE_VS_CONTAINER.Where(x => x.containerName.Contains(container.CONTAINERTYPE) && string.IsNullOrEmpty(x.itemName)).ToList(); // } // else // { // placeFullList = edm.View_BASE_PLACE_VS_CONTAINER.Where(x => x.itemName == cvi.BASE_ITEM.ITEMNAME).ToList(); // } // //数量少的先 // var groupFull = placeFullList.GroupBy(x => x.place.Substring(0, 1)).ToList(); // var groupSrmList = placeList.GroupBy(x => x.SRMID).ToList();//按照可用的堆垛机分组的库位集合 // int srmid = 0;//要寻找空库位的堆垛机区域 // List fullPlaceList = new List(); // int count = 0; // int countFull = 0; // foreach (var groupSrm in groupSrmList) // { // int placeCount = 0;//可用的 库位数量 // var task = groupTask.FirstOrDefault(x => x.Key == groupSrm.Key.ToString()); // if (task != null) // { // placeCount = groupSrm.Count() - task.Count(); // foreach (var z in task) // { // fullPlaceList.Add(z.TOPLACE); // } // } // else // { // placeCount = groupSrm.Count(); // } // if (placeCount > 2)//避免满库 // { // //器具=数量比较 // var groupFullOne = groupFull.FirstOrDefault(x => x.Key == (groupSrm.Key ?? 0).ToString()); // int fullPlaceCount = 0; // if (groupFullOne != null) // { // fullPlaceCount = groupFullOne.Count(); // } // //int fullPlaceCount = groupFull[(i.Key ?? 0)].Count(); // if (fullPlaceCount < countFull || srmid == 0) // { // if (fullPlaceCount == countFull) // { // if (placeCount > count) // { // countFull = fullPlaceCount; // srmid = groupSrm.Key ?? 0; // count = placeCount; // } // } // else // { // countFull = fullPlaceCount; // srmid = groupSrm.Key ?? 0; // count = placeCount; // } // } // ////空库位比较 // //if (placeCount > count || srmid == 0) // //{ // // count = placeCount; // // srmid = i.Key ?? 0; // //} // } // } // ////兼容 // BASE_PLACE finPlace = placeList.OrderBy(x => x.PLACELEVEL).ThenBy(x => x.LAYER).ThenBy(x => System.Math.Abs((x.COL ?? 0) - 9)).FirstOrDefault(x => x.SRMID == srmid && !fullPlaceList.Contains(x.PLACE)); // if (finPlace == null) // { // if (container.BASE_PALLET.PALLETTYPE.Contains("H")) // { // List placeList2 = edm.BASE_PLACE.Where(x => x.BASE_PLACETYPE.PLACETYPE.Contains("G") && (x.ISLOCK ?? 0) == 0 && (x.ISFULL ?? 0) == 0 && goodSrmList.Contains((x.SRMID ?? 0))).ToList(); // //记录任务中的占用数量 // List taskList2 = edm.TASK_TASK.Where(x => x.HASFINISHED == 0 && x.TASKTYPE == 1 && x.BASE_CONTAINER.BASE_PALLET.PALLETTYPE == container.BASE_PALLET.PALLETTYPE && x.TASKTYPE == 1).ToList(); // var groupTask2 = taskList2.GroupBy(x => x.TOPLACE.Substring(0, 1)).ToList(); // var group2 = placeList2.GroupBy(x => x.SRMID).ToList(); // int srmid2 = 0; // List fullPlaceList2 = new List(); // count = 0; // countFull = 0; // foreach (var i in group2) // { // int placeCount = 0; // var task = groupTask2.FirstOrDefault(x => x.Key == i.Key.ToString()); // if (task != null) // { // placeCount = i.Count() - task.Count(); // foreach (var z in task) // { // fullPlaceList2.Add(z.TOPLACE); // } // } // else // { // placeCount = i.Count(); // } // if (placeCount > 2)//避免满库 // { // //器具=数量比较 // var groupFullOne = groupFull.FirstOrDefault(x => x.Key == (i.Key ?? 0).ToString()); // int fullPlaceCount = 0; // if (groupFullOne != null) // { // fullPlaceCount = groupFullOne.Count(); // } // //int fullPlaceCount = groupFull[(i.Key ?? 0)].Count(); // if (fullPlaceCount < countFull || srmid2 == 0) // { // if (fullPlaceCount == countFull) // { // if (placeCount > count) // { // countFull = fullPlaceCount; // srmid2 = i.Key ?? 0; // count = placeCount; // } // } // else // { // countFull = fullPlaceCount; // srmid2 = i.Key ?? 0; // count = placeCount; // } // } // ////空库位比较 // //if (placeCount > count || srmid2 == 0) // //{ // // count = placeCount; // // srmid2 = i.Key ?? 0; // //} // } // } // finPlace = placeList2.OrderBy(x => x.PLACELEVEL).ThenBy(x => x.LAYER).ThenBy(x => System.Math.Abs((x.COL ?? 0) - 9)).FirstOrDefault(x => x.SRMID == srmid2 && !fullPlaceList2.Contains(x.PLACE)); // } // } // return finPlace; // } //} #endregion #region 寻找空库位,现在的方法 /// /// 找出入库库位(寻找空库位) /// public static BASE_PLACE CreateIn(string containerName, int iSrm = 0) { using (Model edm = new Model()) { #region 组织数据 BASE_CONTAINER container = edm.BASE_CONTAINER.FirstOrDefault(x => x.CONTAINERNAME == containerName); //排除故障设备的库位 List goodSrmList = new List();//可用的堆垛机集合 [Editby shaocx,2022-10-08] SrmService srmService = new SrmService(); if (iSrm == 0) { for (int i = 1; i < 10; i++) { if (srmService.IsNotAlarm(i)) { goodSrmList.Add(i); } //*/ //模拟,暂时写死 [Editby shaocx,2022-10-08] //goodSrmList.Add(i); } } else { goodSrmList.Add(iSrm); } //计算此种的数量 BASE_CONTAINER_VS_ITEM cvi = edm.BASE_CONTAINER_VS_ITEM.FirstOrDefault(x => x.BASE_CONTAINER.CONTAINERNAME == containerName); List pvcList = new List();//PVC列表 if (cvi == null) {//表示该托盘没有被物料绑定 //寻找 库存中,托盘类型一致,并且没有绑定物料的 PVC列表 pvcList = edm.View_BASE_PLACE_VS_CONTAINER.Where(x => x.containerName.Contains(container.CONTAINERTYPE) && string.IsNullOrEmpty(x.itemName)).ToList(); } else {//表示该托盘已经被物料绑定 //寻找 库存中,绑定该中物料的 PVC列表 pvcList = edm.View_BASE_PLACE_VS_CONTAINER.Where(x => x.itemName == cvi.BASE_ITEM.ITEMNAME).ToList(); } //数量少的先 var groupPvcList = pvcList.GroupBy(x => x.place.Substring(0, 1)).ToList();//按照巷道分组的PVC分组 //记录任务中的占用数量 List doingTaskList = edm.TASK_TASK.Where(x => x.HASFINISHED == 0 && x.TASKTYPE == 1 && x.BASE_CONTAINER.BASE_PALLET.PALLETTYPE == container.BASE_PALLET.PALLETTYPE && x.TASKTYPE == 1).ToList(); var groupDoingTask = doingTaskList.GroupBy(x => x.TOPLACE.Substring(0, 1)).ToList();//当前未结束的、指定托盘类型的入库任务目标位置的分组集合 #endregion //第一次获取空库位 //注意:表BASE_PALLET的PALLETTYPE 要对应 表BASE_PLACETYPE的PlaceType字段 //下面是根据托盘类型去寻找 能存放该托盘类型的库区 //例如:2巷道和4巷道,都是能存放托盘类型 G和H的 List emptyPlaceList = edm.BASE_PLACE.Where(x => container.BASE_PALLET.PALLETTYPE.Contains(x.BASE_PLACETYPE.PLACETYPE) && (x.ISLOCK ?? 0) == 0 && (x.ISFULL ?? 0) == 0 && goodSrmList.Contains((x.SRMID ?? 0))).ToList(); BASE_PLACE finPlace = null; bool isContainsH = container.BASE_PALLET.PALLETTYPE.Contains("H"); finPlace = CommonGetEmptyPlace(emptyPlaceList, groupDoingTask, groupPvcList); if (finPlace == null) { if (isContainsH) { List emptyPlaceList2 = edm.BASE_PLACE.Where(x => x.BASE_PLACETYPE.PLACETYPE.Contains("G") && (x.ISLOCK ?? 0) == 0 && (x.ISFULL ?? 0) == 0 && goodSrmList.Contains((x.SRMID ?? 0))).ToList(); finPlace = CommonGetEmptyPlace(emptyPlaceList2, groupDoingTask, groupPvcList); } } return finPlace; } } /// /// 通用获取空库位方法 /// /// /// /// /// private static BASE_PLACE CommonGetEmptyPlace(List emptyPlaceList, List> groupDoingTask, List> groupPvcList) { var groupEmptyPlaceList = emptyPlaceList.GroupBy(x => x.SRMID).ToList();//按照可用的堆垛机分组的库位集合 int srmid = 0;//要寻找空库位的堆垛机区域 List fullPlaceList = new List(); int last_empty_placeCount = 0;//循环的上个巷道的可用空库位的个数 int last_fullPlaceCount = 0;//循环的上个巷道的满库位个数 foreach (var groupEmptyPlace in groupEmptyPlaceList) { int empty_placeCount = 0;//可用的 库位数量 int fullPlaceCount = 0;//本巷道的已经有托盘占用的个数 //获取剩余空闲库位数 CommonGetEmpty_placeCount(ref empty_placeCount, ref fullPlaceList, ref fullPlaceCount, groupDoingTask, groupEmptyPlace, groupPvcList); if (empty_placeCount > 4)//避免满库,由2修改为4,2024/1/9 {//这里为什么要判断必须空库位数量大于2,因为必须要留2个位置用于 双伸位的,转运功能! //if (fullPlaceCount == 0) //{//说明该巷道没有满库位的情况啊,要优先入他 【Editby shaocx,2022-11-8】 // CommonSetCountValue(fullPlaceCount, groupEmptyPlace, empty_placeCount, ref last_fullPlaceCount, ref srmid, ref last_empty_placeCount); // break;//终止循环 //} //int fullPlaceCount = groupFull[(i.Key ?? 0)].Count(); if (srmid == 0) {//第一次循环 CommonSetCountValue(fullPlaceCount, groupEmptyPlace, empty_placeCount, ref last_fullPlaceCount, ref srmid, ref last_empty_placeCount); continue; } if (empty_placeCount > last_empty_placeCount) {//如果本巷道可用空库位的数量 大于 循环的上个巷道的可用空库位的个数 //即一个原则:哪个巷道的空库位多,就放哪个巷道! CommonSetCountValue(fullPlaceCount, groupEmptyPlace, empty_placeCount, ref last_fullPlaceCount, ref srmid, ref last_empty_placeCount); } //if (fullPlaceCount < last_fullPlaceCount) //{//如果是第一次循环 或者是 本巷道的满库位的个数 小于 循环的上个巷道的满库位个数 // if (fullPlaceCount == last_fullPlaceCount) // {//如果本次巷道的满库位个数 等于 循环的上个巷道的满库位个数 // if (empty_placeCount > last_empty_placeCount) // {//如果本巷道可用空库位的数量 大于 循环的上个巷道的可用空库位的个数 // //last_countFull = fullPlaceCount; // //srmid = groupSrm.Key ?? 0; // //last_count = placeCount; // CommonSetCountValue(fullPlaceCount, groupEmptyPlace, empty_placeCount, ref last_fullPlaceCount, ref srmid, ref last_empty_placeCount); // } // } // else // { // //last_countFull = fullPlaceCount; // //srmid = groupSrm.Key ?? 0; // //last_count = placeCount; // CommonSetCountValue(fullPlaceCount, groupEmptyPlace, empty_placeCount, ref last_fullPlaceCount, ref srmid, ref last_empty_placeCount); // } //} ////空库位比较 //if (placeCount > count || srmid == 0) //{ // count = placeCount; // srmid = i.Key ?? 0; //} } } //优先查询 指定srmid的库区 BASE_PLACE finPlace = CommonQueryPlace(emptyPlaceList, srmid, fullPlaceList); return finPlace; } /// /// 获取空库位数 /// /// /// /// /// /// /// private static void CommonGetEmpty_placeCount(ref int empty_placeCount, ref List fullPlaceList, ref int fullPlaceCount, List> groupDoingTask, IGrouping groupEmptyPlace, List> groupPvcList) { //此处再增加筛选,去掉有库存的、和正在有任务占用的,防止满入 【EditBy shaocx,2022-11-09】 var doingTasks = groupDoingTask.FirstOrDefault(x => x.Key == groupEmptyPlace.Key.ToString()); if (doingTasks != null) { empty_placeCount = groupEmptyPlace.Count() - doingTasks.Count(); foreach (var z in doingTasks) { fullPlaceList.Add(z.TOPLACE);//正在有任务占用的 } } else { empty_placeCount = groupEmptyPlace.Count(); } //过滤有PVC数据的 var groupFullOne = groupPvcList.FirstOrDefault(x => x.Key == (groupEmptyPlace.Key ?? 0).ToString());//寻找该巷道的PVC分组 if (groupFullOne != null) { foreach (var z in groupFullOne) { fullPlaceList.Add(z.place);//有库存的 } //empty_placeCount = empty_placeCount - groupFullOne.Count(); fullPlaceCount = groupFullOne.Count(); } } private static BASE_PLACE CommonQueryPlace(List placeList, int srmid, List fullPlaceList) { BASE_PLACE finPlace = placeList.OrderBy(x => x.PLACELEVEL).ThenBy(x => x.LAYER).ThenBy(x => System.Math.Abs((x.COL ?? 0) - 9)).FirstOrDefault(x => x.SRMID == srmid && !fullPlaceList.Contains(x.PLACE)); return finPlace; } /// /// 统一设置数值 /// /// /// /// /// /// /// private static void CommonSetCountValue(int fullPlaceCount, IGrouping groupEmptyPlace, int empty_placeCount, ref int last_fullPlaceCount, ref int srmid, ref int last_empty_placeCount) { last_fullPlaceCount = fullPlaceCount; srmid = groupEmptyPlace.Key ?? 0; last_empty_placeCount = empty_placeCount; } #endregion /// /// 创建任务记录 /// /// /// /// public static bool CreateTaskRecord(TASK_TASK task) { using (Model edm = new Model()) { if (task.BASE_CONTAINER.BASE_CONTAINER_VS_ITEM.Count != 0) { foreach (var i in task.BASE_CONTAINER.BASE_CONTAINER_VS_ITEM) { ORDER_OUTORDER order = edm.ORDER_OUTORDER.FirstOrDefault(x => x.ID == (task.ORDERID ?? 0)); TASK_RECORD taskRecord = new TASK_RECORD() { TYPE = task.TASKTYPE ?? 0, CREATETIME = DateTime.Now, ITEMID = i.BASE_ITEM.ID, CONTAINERID = task.BASE_CONTAINER.ID, TASKID = task.ID, ENABLE = 1, ITEMCOUNT = i.ITEMNUM ?? 0, ISMAINOUT = 0, CREATEUSERID = task.CREATEUSERID ?? 1 }; if (order != null) { taskRecord.OUTORDERCODE = order.OUTORDERCODE; if (order.ITEMID == taskRecord.ITEMID) { taskRecord.ISMAINOUT = 1;//属于主要出库零件 } } edm.TASK_RECORD.Add(taskRecord); } } else { ORDER_OUTORDER order = edm.ORDER_OUTORDER.FirstOrDefault(x => x.ID == (task.ORDERID ?? 0)); TASK_RECORD taskRecord = new TASK_RECORD() { TYPE = task.TASKTYPE ?? 0, CREATETIME = DateTime.Now, CONTAINERID = task.BASE_CONTAINER.ID, TASKID = task.ID, ENABLE = 1, ISMAINOUT = 0, CREATEUSERID = task.CREATEUSERID ?? 1 }; if (order != null) { taskRecord.OUTORDERCODE = order.OUTORDERCODE; } edm.TASK_RECORD.Add(taskRecord); } if (edm.SaveChanges() > 0) { return true; } else { return false; } } } /// /// 闲时优化 /// public static void CreateMove(object obj) { SrmService srmService = new SrmService(); while (true) { Thread.Sleep(5000); int srmId = (int)obj; if (needMove[srmId - 1] && srmService.IsNotUse(srmId)) { using (Model edm = new Model()) { if (srmId == 2 || srmId == 3 || srmId == 4 || srmId == 6 || srmId == 7 || srmId == 8 || srmId == 9) { BASE_PLACE_VS_CONTAINER pvcFrom = edm.BASE_PLACE_VS_CONTAINER.FirstOrDefault(x => x.BASE_PLACE.ROW == 2 || x.BASE_PLACE.ROW == 3); if (pvcFrom != null) { BASE_PLACE nextPlace = pvcFrom.BASE_PLACE; if (nextPlace != null && nextPlace.ISFULL == 1)//需要移库 { TASK_TASK task = new TASK_TASK(); task.SOURCEPLACE = nextPlace.PLACE; BASE_PLACE newPlace = edm.BASE_PLACE.OrderBy(x => x.PLACELEVEL).ThenBy(x => x.LAYER).ThenBy(x => x.COL).FirstOrDefault(x => x.SRMID == srmId && (x.ISFULL ?? 0) == 0 && (x.ISLOCK ?? 0) == 0 && x.BASE_PLACETYPE.PLACETYPE == nextPlace.BASE_PLACETYPE.PLACETYPE); if (newPlace != null) { task.TOPLACE = newPlace.PLACE; task.HASREADED = 0; task.HASFINISHED = 0; task.TASKTYPE = 3; //task.CREATEUSERID = 1; task.TASKSTATUS = "新建"; task.TASKLEVEL = 0; task.CONTAINERID = pvcFrom.CONTAINERID; task.ENABLE = 1; BASE_PLACE_VS_CONTAINER nextPvc = edm.BASE_PLACE_VS_CONTAINER.FirstOrDefault(x => x.BASE_PLACE.PLACE == nextPlace.PLACE && x.ENABLE == 1); if (nextPvc == null) { nextPlace.ISFULL = 0; edm.SaveChanges(); continue;//自动校正 } edm.TASK_TASK.Add(task); edm.SaveChanges(); continue; } else { //无库位可移库 continue; } } } } } } } } public static void UpdateCarTask() { while (true) { try { using (Model model = new Model()) { var carTaskList = model.CAR_CARTASK.Where(u => DbFunctions.DiffHours(u.UPDATETIME, DateTime.Now) > 23 && u.TASKSTATUS == "新建").ToList(); foreach (var item in carTaskList) { item.TASKSTATUS = "完成"; } model.SaveChanges(); } } catch (Exception ex) { WZ.Useful.Commons.LogTextHelper.WriteLine("更新叉车任务异常", "UpdateCarTask", ex.ToString()); } Thread.Sleep(20000); } } } }