using DOAN.Model.MES.recipe; using DOAN.Model.MES.recipe.Dto; using Infrastructure.Attribute; using MDM.Attribute; using MDM.Model.Material; using MDM.Model.Process; using MDM.Models.Flow; using MDM.Models.Process; using MDM.Models.Session; using MDM.Service; using NPOI.SS.Formula.Functions; namespace MDM.Services.Flows { /// /// 普通流程功能函数 /// // [AppService(ServiceType = typeof(CommonFlowService), ServiceLifetime = LifeTime.Singleton)] public class CommonFlowService : BaseService { /// /// 普通入站流程 /// /// 工序代码 /// 产品序列号 /// 入站结果 [RIZOFlow(FlowType = "common_inbound_flow")] public InStationApplyResult CommonInboundStationFlow(string operationCode, string processCode) { // 参数验证 if (string.IsNullOrWhiteSpace(operationCode)) { return InStationApplyResult.InvalidParameters; } if (string.IsNullOrWhiteSpace(processCode)) { return InStationApplyResult.InvalidParameters; } //1.获取产品是正常件,完成件,返工件 ProductLifecycle productInfo = Context.Queryable() .Where(p => p.ProductSN == processCode) .First(); if (productInfo == null) { // 产品未开工,不得入站 RecordTrace(productInfo, operationCode, 0, ApplyStatusEnum.REJECTED, InStationApplyResult.ProductNotStartWork.ToString(), "产品未开工,不得入站"); return InStationApplyResult.ProductNotStartWork; } if (productInfo.ProductStatus == 2) { // 产品已经生产完成,不得入站 RecordTrace(productInfo, operationCode, 2, ApplyStatusEnum.REJECTED, InStationApplyResult.ProductCompleted.ToString(), "产品已经生产完成,不得入站"); return InStationApplyResult.ProductCompleted; } if (productInfo.ProductStatus == 3) { // 返工件允许入站 RecordTrace(productInfo, operationCode, 3, ApplyStatusEnum.SUCCESS, string.Empty, string.Empty); return InStationApplyResult.Success; } if (productInfo.ProductStatus == 1) { //正常件处理 // 1.检查是否重复进站 bool IsRepeatInStation = Context.Queryable() .Where(it => it.ProductSN == processCode && it.OperationCode == operationCode) .Any(); if (IsRepeatInStation) { // 重复进站禁止入站 RecordTrace(productInfo, operationCode, 3, ApplyStatusEnum.REJECTED, InStationApplyResult.RepeatInStation.ToString(), "重复进站禁止入站"); return InStationApplyResult.RepeatInStation; } // 获取工序信息 ProcessOperation processOperation = Context.Queryable() .Where(it => it.FkRoutingCode == productInfo.RoutingCode && it.OperationCode == operationCode).First(); if (processOperation == null) { return InStationApplyResult.OperationNotFound; } // 可跳过的工序直接允许入站 if (processOperation.IsSkippable == 1) { RecordTrace(productInfo, operationCode, 1, ApplyStatusEnum.SUCCESS, null, null); return InStationApplyResult.Success; } // 检查上一工序状态 if (processOperation.OperationSeq <= 10) { // 当前是第一个工序,无需检查上一工序 RecordTrace(productInfo, operationCode, 1, ApplyStatusEnum.SUCCESS, null, null); return InStationApplyResult.Success; } // 获取上一个工序 var lastOperation = Context.Queryable() .Where(it => it.FkRoutingCode == productInfo.RoutingCode) .Where(it => it.OperationSeq < processOperation.OperationSeq) .OrderByDescending(it => it.OperationSeq) .First(); if (lastOperation == null) { return InStationApplyResult.PreviousOperationNotFound; } // 获取上一工序的通过记录状态 判断上一站是否已经出站 bool lastOperationStatus = Context.Queryable() .Where(it => it.ProductSN == processCode && it.OperationCode == lastOperation.OperationCode) .Where(it => it.ApplyType == ApplyTypeEnum.OUT) .Where(it => it.ApplyStatus == ApplyStatusEnum.SUCCESS) .Any(); if (lastOperationStatus) { // 上一工序已完成,允许入站 RecordTrace(productInfo, operationCode, 1, ApplyStatusEnum.SUCCESS, InStationApplyResult.Success.ToString(), "上一工序已完成,允许入站"); return InStationApplyResult.Success; } else { // 上一工序未完成,禁止入站 RecordTrace(productInfo, operationCode, 1, ApplyStatusEnum.REJECTED, InStationApplyResult.PreviousOperationNotStarted.ToString(), "上一工序未完成,禁止入站"); return InStationApplyResult.PreviousOperationNotStarted; } } return InStationApplyResult.UnknownStatus; } /// /// 记录入站操作轨迹 /// /// 产品信息 /// 工序代码 /// 入站结果 /// 拒绝原因代码 /// 拒绝原因描述 private void RecordTrace(ProductLifecycle product, string operationCode, int ProductionLifeStage, ApplyStatusEnum isPass, string rejectReasonCode, string rejectReasonDesc) { // 更新产品状态 if (product != null) { Context.Updateable() .SetColumns(it => new ProductLifecycle { ProductStatus = 1, // 设置为生产中状态 UpdatedTime = DateTime.Now }) .Where(it => it.ProductSN == product.ProductSN) .ExecuteCommand(); } // 构建入站记录 var passstationRecord = new ProductPassstationRecord { Workorder = product?.Workorder, Routingcode = product?.RoutingCode, ProductSN = product?.ProductSN ?? string.Empty, OperationCode = operationCode, ProductionLifeStage = ProductionLifeStage, // 生产中 ApplyType = ApplyTypeEnum.IN, ApplyStatus = isPass, RejectReasonCode = rejectReasonCode, RejectReasonDesc = rejectReasonDesc, InStationTime = DateTime.Now, CreatedTime = DateTime.Now }; Context.Insertable(passstationRecord).ExecuteCommand(); } //TODO: 下发中间操作流程规则 //public Object MiddleProcessFlowDistribution(string operationCode, string processCode) //{ // //TODO 获取这个工序的中间操作规则 // //1. 获取不同的流程规则 // List MiddleProcessFlowLists = Context.Queryable().Where(it => !it.FlowTypeCode.Contains("bound_flow")).ToList(); // //2.分配处理不同的中间操作规则 // foreach (var flow in MiddleProcessFlowLists) // { // //根据不同的流程类型,调用不同的处理函数 // switch (flow.FlowTypeCode) // { // //扫码流程 // case "Scanningcode_flow": // //调用质量检验流程处理函数 // //QualityInspectionFlow(operationCode, processCode); // break; // //数据采集流程 // case "data_collect_flow": // //调用返工流程处理函数 // //ReworkProcessFlow(operationCode, processCode); // break; // //配方下发流程 // case "recipe_distribute_flow": // //调用返工流程处理函数 // //ReworkProcessFlow(operationCode, processCode); // break; // // 添加更多的流程类型处理 // default: // break; // } // } //} //TODO: 扫码流程 [RIZOFlow(FlowType = "Scanningcode_flow")] public List ScanningcodeFlow(string operationCode, string RoutingCode) { //获取这个工序d的扫码规则 List ScanningFlowList = Context.Queryable().LeftJoin((f, m) => f.FkRoutingCode == m.FkRoutingCode && f.FkOperationCode == m.FkOperationCode && f.FlowCode == m.FkFlowCode) .Where((f, m) => f.FkRoutingCode == RoutingCode && f.FkOperationCode == operationCode && f.FlowTypeCode == "Scanningcode_flow") .Select((f, m) => new ProcessOperationFlowMaterialParamter() { id = f.id, FkRoutingCode = f.FkRoutingCode, FkOperationCode = f.FkOperationCode, FkFlowCode = m.FkFlowCode, MaterialCode = m.MaterialCode, MaterialName = m.MaterialName, UseErrorProofRuleCode = m.UseErrorProofRuleCode, }) .ToList(); return ScanningFlowList; } //TODO: 数采流程 [RIZOFlow(FlowType = "data_collect_flow")] public List DataCollectFlow( string RoutingCode, string operationCode, string ProductlinebodyCode, string WorkstationCode) { //获取这个工序d的扫码规则 List DataCollectFlowList = Context.Queryable().LeftJoin ((f, m) => f.FkRoutingCode == m.FkRoutingCode && f.FkOperationCode == m.FkOperationCode && f.FlowCode == m.FkFlowCode) .Where((f, m) => f.FkRoutingCode == RoutingCode && f.FkOperationCode == operationCode && f.FlowTypeCode == "Scanningcode_flow") .Where((f,m)=>m.FkProductlinebodyCode== ProductlinebodyCode&&m.FkWorkstationCode== WorkstationCode) .Select((f, m) => new ProcessOperationWorkstationFlowCollectParameter() { FkRoutingCode = f.FkRoutingCode, FkOperationCode = f.FkOperationCode, FkProductlinebodyCode = m.FkProductlinebodyCode, FkWorkstationCode = m.FkWorkstationCode, FkFlowCode = m.FkFlowCode, ParameterCode = m.ParameterCode, PlcPoint = m.PlcPoint, ParameterName = m.ParameterName, Description = m.Description, DataType = m.DataType, Unit = m.Unit, StandardValue = m.StandardValue, MinValue = m.MinValue, MaxValue = m.MaxValue, IsControlled = m.IsControlled, IsMonitored = m.IsMonitored, ControlType = m.ControlType, DefaultValue = m.DefaultValue, IsRequired = m.IsRequired, Sequence = m.Sequence, }) .ToList(); return DataCollectFlowList; } //TODO: 配方流程 [RIZOFlow(FlowType = "recipe_distribute_flow")] public List RecipeDistributeFlow(string operationCode, string RoutingCode) { return Context.Queryable() .LeftJoin((refpr, ver) => refpr.RecipeCode == ver.RecipeCode) .LeftJoin((refpr, ver, param) => ver.RecipeCode == param.RecipeCode && ver.Version == param.Version) .Where((refpr, ver, param) => refpr.FkRoutingCode == RoutingCode && refpr.FkOperationCode == operationCode) .Select((refpr, ver, param) => new PfRecipeParametersDto { Id = param.Id, RecipeCode = param.RecipeCode, Version = param.Version, ParamName = param.ParamName, Unit = param.Unit, UpperLimit = param.UpperLimit, LowerLimit = param.LowerLimit, StandardValue = param.StandardValue, Remark = param.Remark }).ToList(); } /// /// 普通出站流程 /// /// /// /// //[RIZOFlow(FlowType = "common_outbound_flow")] //public OutStationApplyResult CommonOutboundStationFlow(string operationCode, string processCode) //{ // // 参数验证 // if (string.IsNullOrWhiteSpace(operationCode) || string.IsNullOrWhiteSpace(processCode)) // { // return OutStationApplyResult.InvalidParameters; // } // // 获取产品是正常件,完成件,返工件 // var product = GetProductBySn(processCode); // if (product == null) // { // // 产品未开工,不得出站 // return OutStationApplyResult.ProductNotStartWork; // } // if (product.ProductStatus == 2) // { // // 产品已经生产完成,不得出站 // return OutStationApplyResult.ProductCompleted; // } // //如果正常件 // if (product.ProductStatus == 2) // { // // 此工序未入站,禁止出站 // // 此工序未完成中间流程,禁止出站 // //插入出站记录 // ProductPassstationRecord passstationRecord = new ProductPassstationRecord // { // Workorder = product.Workorder, // Routingcode = product.RoutingCode, // ProductSN = product.ProductSN, // OperationCode = operationCode, // ProuductStatus = 3, // 出站状态 // OutStationTime = DateTime.Now, // CreatedTime = DateTime.Now // }; // Context.Insertable(passstationRecord).ExecuteCommand(); // return OutStationApplyResult.Success; // } // //如果,返工件 // if (product.ProductStatus == 3) // { // //插入出站记录 // ProductPassstationRecord passstationRecord = new ProductPassstationRecord // { // Workorder = product.Workorder, // Routingcode = product.RoutingCode, // ProductSN = product.ProductSN, // OperationCode = operationCode, // ProuductStatus = 4, // 出站状态 // OutStationTime = DateTime.Now, // CreatedTime = DateTime.Now // }; // Context.Insertable(passstationRecord).ExecuteCommand(); // return OutStationApplyResult.Success; // } // return OutStationApplyResult.UnknownStatus; //} } }