11
cjs
1 天以前 06747ef981873358950982e7a53c6d221ef93ac3
HH.WCS.Mobox3.NongFuLinZhi/core/Monitor.cs
@@ -2,12 +2,15 @@
using HH.WCS.Mobox3.NFLZ.process;
using HH.WCS.Mobox3.NFLZ.util;
using HH.WCS.Mobox3.NFLZ.wms;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using static HH.WCS.Mobox3.NFLZ.wms.WMSHelper.AddChangeModel;
using static System.Runtime.CompilerServices.RuntimeHelpers;
namespace HH.WCS.Mobox3.NFLZ.core
@@ -46,82 +49,430 @@
        }
        /// <summary>
        /// 瓶盖转运
        /// 转运任务
        /// </summary>
        internal static void BottleBlankTransportation()
        {
            var db = new SqlHelper<object>().GetInstance();
            var jbwInfo = Settings.areaInfos.Where(a => a.areaName == "瓶盖入库接驳位" && a.enable == 1).FirstOrDefault();
            if(jbwInfo != null)
            #region 瓶盖空托入库
            var areaInfo = Settings.areaInfos.Where(a => a.areaName == "瓶盖非即产空框" && a.enable == 1).FirstOrDefault();
            if(areaInfo != null)
            {
                var locInfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == jbwInfo.areaCode && a.N_CURRENT_NUM > 0 && a.S_LOCK_STATE == "无").Includes(a => a.LocCntrRel).First();
                var locInfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_CURRENT_NUM == a.N_CAPACITY && a.S_LOCK_STATE == "无").First();
                if(locInfo != null)
                {
                    LogHelper.Info($"【瓶盖转运】瓶坯接驳位查询到需入库的瓶坯,货位编码:{locInfo.S_CODE}");
                    if(locInfo.LocCntrRel != null)
                    string cntrCode = getCntrCode(db, locInfo);
                    if (string.IsNullOrEmpty(cntrCode))
                    {
                        //创建作业
                        WMSHelper.CreateOpTask(locInfo.S_CODE, "", "入库", "瓶盖转运", locInfo.LocCntrRel.S_CNTR_CODE,"瓶盖");
                        WMSHelper.CreateOpTask(locInfo.S_CODE, "", "入库", "瓶盖空托入库", cntrCode, "瓶盖");
                    }
                    else
                    {
                        LogHelper.Info($"【瓶盖转运】当前货位未绑定托盘码,货位编码:{locInfo.S_CODE}");
                        LogHelper.Info($"【瓶盖空托转运】当前货位未绑定托盘码,货位编码:{locInfo.S_CODE}");
                    }
                }
            }
            else
            {
                LogHelper.Info("【瓶盖转运】瓶坯接驳位未配置");
                LogHelper.Info("【瓶盖空托转运】瓶盖非即产空框 未配置");
            }
            #endregion
            #region 瓶坯满托入库
            areaInfo = Settings.areaInfos.Where(a => a.areaName == "瓶坯入库接驳" && a.enable == 1).FirstOrDefault();
            if (areaInfo != null)
            {
                var locInfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_CURRENT_NUM == a.N_CAPACITY && a.S_LOCK_STATE == "无").First();
                if (locInfo != null)
                {
                    string cntrCode = getCntrCode(db, locInfo);
                    if (!string.IsNullOrEmpty(cntrCode))
                    {
                        //创建作业
                        WMSHelper.CreateOpTask(locInfo.S_CODE, "", "入库", "瓶坯接驳位入库", cntrCode, "瓶坯");
                    }
                    else
                    {
                        LogHelper.Info($"【瓶坯满托转运】当前货位未绑定托盘码,货位编码:{locInfo.S_CODE}");
                    }
                }
            }
            else
            {
                LogHelper.Info("【瓶坯满托转运】瓶坯入库接驳 未配置");
            }
            #endregion
        }
        /// <summary>
        /// 瓶坯翻斗机非即产满框区补满托
        /// </summary>
        internal static void PPFDFullIn()
        {
            //产线号 : 农夫林芝-1号瓶坯翻斗机
            var db = new SqlHelper<object>().GetInstance();
            var bcpWorkList = db.Queryable<LinZhiBCPWorkOrder>().Where(a => a.S_PLineNo.Contains("瓶坯翻斗机") && a.S_UsingNow == "N" && a.S_WorkState == "执行中").ToList();
            if(bcpWorkList.Count > 0)
            {
                bcpWorkList.ForEach(a =>
                {
                    string areaName = a.S_PLineNo.Split('-')[1].Substring(0, 1) + "号瓶坯翻斗机非即产满框";
                    LogHelper.Info($"PPFDFullIn area:{areaName}");
                    var areaInfo = Settings.areaInfos.Where(b => b.areaName == areaName && b.enable == 1).FirstOrDefault();
                    if(areaInfo != null)
                    {
                        var locInfo = db.Queryable<Location>().Where(b => b.S_AREA_CODE == areaInfo.areaCode && b.N_CURRENT_NUM == 0 && b.S_LOCK_STATE == "无").First();
                        if(locInfo != null)
                        {
                            //生成任务
                            Location location = TaskProcess.BCPInOrOutTwo(db, "瓶坯库区", a.S_ItemCode);
                            if(location != null)
                            {
                                string cntrCode = getCntrCode(db,location);
                                //创建作业
                                WMSHelper.CreateOpTask(location.S_CODE, locInfo.S_CODE, "入库", "瓶坯非即产补满框", cntrCode, "瓶坯");
                            }
                        }
                    }
                    else
                    {
                        LogHelper.Info($"{areaName}未配置");
                    }
                });
            }
        }
        private static string getCntrCode(SqlSugar.SqlSugarClient db, Location location)
        {
            string cntr = "";
            var cntrList = db.Queryable<LocCntrRel>().Where(a => a.S_LOC_CODE == location.S_CODE).OrderBy(a => a.T_CREATE).ToList();
            if(cntrList.Count > 0)
            {
                foreach(var a in cntrList)
                {
                    cntr = cntr + a.S_CNTR_CODE + ",";
                }
            }
            cntr = cntr.TrimEnd(',');
            return cntr;
        }
        internal static void PGFDFullIn()
        {
            //产线号 : 农夫林芝-1号瓶盖翻斗机
            //瓶盖翻斗机共用一个库区,需要区分几种情况(注:现场已确认,三个翻斗机不会有三种物料)
            //1、如果三个翻斗机物料相同,则 瓶盖非即产满框 有空货位就补
            //2、如果三个翻斗机有两种不同的物料,则 瓶盖非即产满框 有空位的补充 改库区没有的物料
            var db = new SqlHelper<object>().GetInstance();
            string itemList = "";
            var bcpWorkList = db.Queryable<LinZhiBCPWorkOrder>().Where(a => a.S_PLineNo.Contains("瓶盖翻斗机") && a.S_UsingNow == "N" && a.S_WorkState == "执行中").ToList();
            if (bcpWorkList.Count > 0)
            {
                bcpWorkList.ForEach(a =>
                {
                    if (string.IsNullOrEmpty(itemList))
                    {
                        itemList = itemList + a.S_ItemCode + ",";
                    }
                    else
                    {
                        if (!itemList.Contains(a.S_ItemCode))
                        {
                            itemList = itemList + a.S_ItemCode + ",";
                        }
                    }
                });
            }
            if (!string.IsNullOrEmpty(itemList))
            {
                itemList = itemList.TrimEnd(',');
                List<string> itemCount = itemList.Split(',').ToList();
                if(itemCount.Count > 0)
                {
                    var areaInfo = Settings.areaInfos.Where(b => b.areaName == "瓶盖非即产满框" && b.enable == 1).FirstOrDefault();
                    if (areaInfo != null)
                    {
                        var locInfo = db.Queryable<Location>().Where(b => b.S_AREA_CODE == areaInfo.areaCode && b.N_CURRENT_NUM == 0 && b.S_LOCK_STATE == "无").First();
                        if (locInfo != null)
                        {
                            if (itemCount.Count == 1)
                            {
                                //只有一种物料
                                //生成任务
                                Location location = TaskProcess.BCPInOrOut(db, false, "瓶盖库区", itemCount[0]);
                                if (location != null)
                                {
                                    string cntrCode = getCntrCode(db, location);
                                    //创建作业
                                    WMSHelper.CreateOpTask(location.S_CODE, locInfo.S_CODE, "入库", "瓶盖非即产补满框大包装", cntrCode, "瓶盖");
                                }
                            }
                            if (itemCount.Count == 2)
                            {
                                //两种物料
                                //判断库区是否有货位数量大于0或者有入库锁的,如果有,则判断物料,如果没有,则生成第一个物料的任务
                                var locInfo2 = db.Queryable<Location>().Where(b => b.S_AREA_CODE == areaInfo.areaCode && (b.N_CURRENT_NUM > 0 || b.S_LOCK_STATE == "入库锁")).First();
                                if(locInfo2 != null)
                                {
                                    string itemCode = "";
                                    if(locInfo2.N_CURRENT_NUM > 0)
                                    {
                                        var cntrInfo = db.Queryable<LocCntrRel>().Where(b => b.S_LOC_CODE == locInfo2.S_CODE).First();
                                        if(cntrInfo != null)
                                        {
                                            var itemInfo = db.Queryable<CntrItemRel>().Where(b => b.S_CNTR_CODE == cntrInfo.S_CNTR_CODE).First();
                                            if(itemInfo != null)
                                            {
                                                itemCode = itemInfo.S_ITEM_CODE;
                                            }
                                        }
                                    }
                                    if(locInfo2.S_LOCK_STATE == "入库锁")
                                    {
                                        var taskInfo = db.Queryable<WMSTask>().Where(b => b.S_END_LOC == locInfo2.S_CODE && b.S_STATE != "完成" && b.S_STATE != "取消").First();
                                        if(taskInfo != null)
                                        {
                                            string cntrCode = taskInfo.S_CNTR_CODE.Split(',')[0];
                                            var itemInfo = db.Queryable<CntrItemRel>().Where(b => b.S_CNTR_CODE == cntrCode).First();
                                            if (itemInfo != null)
                                            {
                                                itemCode = itemInfo.S_ITEM_CODE;
                                            }
                                        }
                                    }
                                    if (itemCode != "")
                                    {
                                        itemCode = itemCode == itemCount[0] ? itemCount[1] : itemCount[0];
                                        Location location = TaskProcess.BCPInOrOut(db, false, "瓶盖库区", itemCode);
                                        if (location != null)
                                        {
                                            string cntrCode = getCntrCode(db, location);
                                            //创建作业
                                            WMSHelper.CreateOpTask(location.S_CODE, locInfo.S_CODE, "入库", "瓶盖非即产补满框大包装", cntrCode, "瓶盖");
                                        }
                                    }
                                }
                                else
                                {
                                    Location location = TaskProcess.BCPInOrOut(db, false, "瓶盖库区", itemCount[0]);
                                    if (location != null)
                                    {
                                        string cntrCode = getCntrCode(db, location);
                                        //创建作业
                                        WMSHelper.CreateOpTask(location.S_CODE, locInfo.S_CODE, "入库", "瓶盖非即产补满框大包装", cntrCode, "瓶盖");
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        LogHelper.Info($"瓶盖非即产满框 未配置");
                    }
                }
            }
        }
        /// <summary>
        /// 半成品工单监控
        /// 瓶坯非即产即用库托库区补空托
        /// </summary>
        /// <exception cref="NotImplementedException"></exception>
        internal static void BCPWorkSurveillance()
        internal static void PPFDFullInEmpty()
        {
            //判断当前半成品工单是否有执行中的任务,如果没有,则讲线边库的物料入库
            var db = new SqlHelper<object>().GetInstance();
            var workList = db.Queryable<LinZhiBCPWorkOrder>().Where(a => a.S_WorkState == "执行中").ToList();
            if(workList.Count == 0)
            {
                var taskInfo = db.Queryable<WCSTask>().Where(a => a.S_TYPE == "接驳位移库" && a.S_B_STATE != "完成" && a.S_B_STATE != "取消" && a.S_B_STATE != "卸货完成" && a.S_B_STATE != "开始卸货" && a.S_B_STATE != "取货完成").First();
                if(taskInfo == null)
                {
                    var areaInfo = Settings.areaInfos.Where(a => (a.areaName == "瓶坯非即产即用" || a.areaName == "瓶坯即产即用A") && a.enable == 1).ToList();
                    if (areaInfo.Count > 0)
                    {
                        foreach (var a in areaInfo)
                        {
                            var locInfo = db.Queryable<Location>().Where(b => b.S_AREA_CODE == a.areaCode && b.N_CURRENT_NUM > 0 && b.S_LOCK_STATE == "无").Includes(b => b.LocCntrRel).First();
                            if (locInfo != null)
                            {
                                //创建作业
                                WMSHelper.CreateOpTask(locInfo.S_CODE, "", "入库", "接驳位移库", locInfo.LocCntrRel.S_CNTR_CODE);
                            }
            //瓶坯非即产空框区堆叠库区一共四个货位,如果有三个货位是满的,就开始转运到瓶坯库区
            //如果满货位小于等于一就开始从满框缓存区空框区域转运,如果满框缓存区空框区域无空托,则从瓶坯库转运
            var db = new SqlHelper<object>().GetInstance();
            var areaInfo = Settings.areaInfos.Where(a => a.areaName == "瓶坯非即产空框" && a.enable == 1).FirstOrDefault();
            if (areaInfo != null)
            {
                var LocList = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_CURRENT_NUM > 0).ToList();
                if(LocList.Count <= 1)
                {
                    LogHelper.Info($"瓶坯非即产补空框 {JsonConvert.SerializeObject(LocList)}");
                    var taskInfo = db.Queryable<WCSTask>().Where(a => a.S_TYPE == "瓶坯非即产补空框" && a.S_B_STATE != "完成" && a.S_B_STATE != "取消").First();
                    if(taskInfo == null)
                    {
                        var wmsTask = db.Queryable<WMSTask>().Where(a => a.S_OP_DEF_NAME == "瓶坯非即产补空框" && (a.N_B_STATE == 0 || a.N_B_STATE == 1)).First();
                        if(wmsTask == null)
                        {
                            //需要从库区补充空托
                            Location location = TaskProcess.FJCKTLoc();
                            var locInfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_CURRENT_NUM < a.N_CAPACITY && a.S_LOCK_STATE == "无").OrderBy(a => a.N_ROW).First();
                            if (location != null && locInfo != null)
                            {
                                string cntrCode = getCntrCode(db, location);
                                //创建作业
                                WMSHelper.CreateOpTask(location.S_CODE, locInfo.S_CODE, "入库", "瓶坯非即产补空框", cntrCode, "瓶坯");
                            }
                        }
                    }
                }
                    var areaInfoTwo = Settings.areaInfos.Where(a => a.areaName == "瓶坯即产即用B" && a.enable == 1).First();
                    if (areaInfoTwo != null)
                LocList = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_CURRENT_NUM == a.N_CAPACITY).ToList();
                if (LocList.Count > 2)
                {
                    //判断任务是否存在
                    LogHelper.Info($"瓶坯非即产空托入库 {JsonConvert.SerializeObject(LocList)}");
                    var taskInfo = db.Queryable<WCSTask>().Where(a => a.S_TYPE == "瓶坯非即产空框入库" && a.S_B_STATE != "完成" && a.S_B_STATE != "取消" && a.S_B_STATE != "卸货完成" && a.S_B_STATE != "开始卸货" && a.S_B_STATE != "取货完成").First();
                    if(taskInfo == null)
                    {
                        var locInfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaInfoTwo.areaCode && a.N_CURRENT_NUM > 0).OrderBy(a => a.N_ROW).OrderByDescending(a => a.N_COL).Take(1).PartitionBy(a => a.N_ROW).Includes(a => a.LocCntrRel).ToList();
                        if(locInfo.Count > 0)
                        //判断作业是否存在
                        var wmsTask = db.Queryable<WMSTask>().Where(a => a.S_OP_DEF_NAME == "瓶坯非即产空框入库" && (a.N_B_STATE == 0 || a.N_B_STATE == 1)).First();
                        if(wmsTask == null)
                        {
                            foreach(var a in locInfo)
                            //需要将空托转运到库区
                            foreach (var a in LocList)
                            {
                                if(a.S_LOCK_STATE == "无")
                                if (a.S_LOCK_STATE == "无")
                                {
                                    //生成任务
                                    string cntrCode = getCntrCode(db, a);
                                    //创建作业
                                    WMSHelper.CreateOpTask(a.S_CODE, "", "入库", "接驳位移库", a.LocCntrRel.S_CNTR_CODE,"瓶坯");
                                    WMSHelper.CreateOpTask(a.S_CODE, "", "入库", "瓶坯非即产空框入库", cntrCode, "瓶坯");
                                    break;
                                }
                            }
                        }
                    }
                }
            }
            #region
            //var workInfo = db.Queryable<LinZhiBCPWorkOrder>().Where(a => a.S_PLineNo == "农夫林芝-瓶坯机" && a.S_UsingNow == "N" && a.S_WorkState == "执行中").First();
            //if(workInfo != null)
            //{
            //    var areaInfo = Settings.areaInfos.Where(a => a.areaName == "瓶坯非即产空框" && a.enable == 1).FirstOrDefault();
            //    if(areaInfo != null)
            //    {
            //        var locInfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_CURRENT_NUM == 0 && a.S_LOCK_STATE == "无").First();
            //        if(locInfo != null)
            //        {
            //            //生成任务
            //            Location location = TaskProcess.BCPInOrOut(db, false, "瓶坯库区", "");
            //            if (location != null)
            //            {
            //                string cntrCode = getCntrCode(db, location);
            //                //创建作业
            //                WMSHelper.CreateOpTask(location.S_CODE, locInfo.S_CODE, "入库", "瓶坯非即产补空框", cntrCode, "瓶坯");
            //            }
            //        }
            //    }
            //    else
            //    {
            //        LogHelper.Info("瓶坯非即产空框 未配置");
            //    }
            //}
            #endregion
        }
        internal static void PPFDFullInJC()
        {
            var db = new SqlHelper<object>().GetInstance();
            var workInfo = db.Queryable<LinZhiBCPWorkOrder>().Where(a => a.S_PLineNo.Contains("瓶坯翻斗机") && a.S_UsingNow == "Y" && a.S_WorkState == "执行中").First();
            if(workInfo != null)
            {
                var areaInfo = Settings.areaInfos.Where(a => a.areaName == "瓶坯即产满框" && a.enable == 1).FirstOrDefault();
                if(areaInfo != null)
                {
                    //如果库区是空的,并且没有有锁的就补充空托
                    var locInfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_CURRENT_NUM == 0 && a.S_LOCK_STATE == "无").First();
                    if (locInfo != null)
                    {
                        //开始转运
                        Location startLoca = TaskProcess.BCPInOrOut(db, false, "瓶坯即产满框缓存", workInfo.S_ItemCode);
                        if (startLoca != null)
                        {
                            //创建作业
                            string cntrCode = getCntrCode(db, startLoca);
                            WMSHelper.CreateOpTask(startLoca.S_CODE, locInfo.S_CODE, "出库", "瓶坯即产补满框", cntrCode, "");
                        }
                    }
                }
                areaInfo = Settings.areaInfos.Where(a => a.areaName == "瓶坯即产空框" && a.enable == 1).FirstOrDefault();
                if (areaInfo != null)
                {
                    var locInfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_CURRENT_NUM == 0 && a.S_LOCK_STATE == "无").ToList();
                    if (locInfo.Count == 2)
                    {
                        //开始转运
                        Location startLoca = TaskProcess.BCPInOrOut(db, false, "瓶坯即产满框缓存", "");
                        if (startLoca != null)
                        {
                            //创建作业
                            string cntrCode = getCntrCode(db, startLoca);
                            WMSHelper.CreateOpTask(startLoca.S_CODE, locInfo[0].S_CODE, "出库", "瓶坯即产补空框", cntrCode, "");
                        }
                    }
                }
            }
        }
        /// <summary>
        /// 瓶盖小包装盖转运
        /// </summary>
        /// <exception cref="NotImplementedException"></exception>
        internal static void PGXBZZY()
        {
            var db = new SqlHelper<object>().GetInstance();
            Location endLoca = null;
            var workInfo = db.Queryable<LinZhiBCPWorkOrder>().Where(a => a.S_PLineNo.Contains("瓶盖") && a.S_ITEM_TYPE == "小包装盖" && a.S_WorkState == "执行中").ToList();
            if(workInfo.Count > 0)
            {
                foreach(var it in workInfo)
                {
                    LogHelper.Info($"瓶盖小包装盖转运: 查询产线号:{it.S_PLineNo},物料编码:{it.S_ItemCode}");
                    //查询终点货位
                    string endAreaName = it.S_PLineNo.Split('-')[1].Substring(0, 1) + "号瓶盖翻斗机小包装";
                    var areaInfo = Settings.areaInfos.Where(b => b.areaName == endAreaName && b.enable == 1).FirstOrDefault();
                    if(areaInfo != null)
                    {
                        var taskInfo = db.Queryable<WCSTask>().Where(a => a.S_END_AREA == areaInfo.areaCode && a.S_B_STATE != "完成" && a.S_B_STATE != "取消").First();
                        if(taskInfo != null)
                        {
                            //控制一个库区只能一次一条任务
                            return;
                        }
                        var locInfo = db.Queryable<Location>().Where(b => b.S_AREA_CODE == areaInfo.areaCode && b.N_CURRENT_NUM == 0).OrderBy(b => b.N_ROW).OrderBy(b => b.N_COL).Take(1).PartitionBy(b => b.N_ROW).ToList();
                        if(locInfo.Count > 0)
                        {
                            foreach(var endloc in locInfo)
                            {
                                var rowInfo = db.Queryable<RowLock>().Where(a => a.S_AREA_CODE == endloc.S_AREA_CODE && a.S_ROW == endloc.S_ROW).First();
                                LogHelper.Info($"瓶盖小包装盖转运:查询锁信息,货位锁:{endloc.S_LOCK_STATE},排锁:{JsonConvert.SerializeObject(rowInfo)}");
                                if(rowInfo != null && rowInfo.S_LOCK_STATE == "无" && endloc.S_LOCK_STATE == "无")
                                {
                                    endLoca = endloc;
                                    break;
                                }
                            }
                        }
                    }
                    else
                    {
                        LogHelper.Info($"{endAreaName} 未配置");
                    }
                    //查询起点货位
                    LogHelper.Info($"瓶盖小包装盖转运:获取到终点货位信息:{JsonConvert.SerializeObject(endLoca)}");
                    if (endLoca != null)
                    {
                        Location startLoca = TaskProcess.BCPInOrOut(db,true,"瓶盖库区",it.S_ItemCode + it.S_ITEM_TYPE);
                        if (startLoca != null)
                        {
                            string cntrCode = getCntrCode(db, startLoca);
                            WMSHelper.CreateOpTask(startLoca.S_CODE, endLoca.S_CODE, "出库", "瓶盖非即产补满框小包装", cntrCode, "");
                        }
                    }
                }
            }
        }
    }