using System; using System.Collections; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Reflection; using Infrastructure.Attribute; using SqlSugar; using ZR.Model; using ZR.Model.MES.pro; using ZR.Model.MES.qc; using ZR.Model.MES.qc.DTO; using ZR.Model.MES.qu; using ZR.Model.MES.wms; using ZR.Service.mes.qc.IService; using ZR.Service.Utils; using static System.Runtime.InteropServices.JavaScript.JSType; namespace ZR.Service.mes.qc { [AppService(ServiceType = typeof(ICommonFQCService), ServiceLifetime = LifeTime.Transient)] public class CommonFQCService : BaseService, ICommonFQCService { public int CheckPackageWorkOrderStatus(string workOrderId) { try { // 检查对应工单是否存在 ProWorkorder_v2 proWorkorder = Context .Queryable() .Where(it => it.ClientWorkorder == workOrderId) .First(); if (proWorkorder == null) { return -1; } return proWorkorder.Status; } catch (Exception ex) { return -1; } } /// /// 根据年周日生成当日全部工单列表 /// /// 年 /// 周 /// 日 /// 0-不读取status 1-读取status 2- 查询status为1,2时 /// -1-全部 0-初态 1-上线 2-包装完成 /// public List GenerateWorkOrderListUtil( int year, int week, int date, int type = 0, int status = -1 ) { try { var predicate = Expressionable .Create() .And(it => it.Year == year) .And(it => it.Week == week) .And(it => it.Date == date) .And(it => it.Remark3 == "是") .AndIF(type == 1, it => it.Status == status) .AndIF(type == 2, it => it.Status == 1 || it.Status == 2) .ToExpression(); return Context .Queryable() .Where(predicate) .OrderBy(it => it.Sort) .ToList(); } catch (Exception ex) { return null; } } public int CheckPackageWorkOrderInListStatus(string workOrderId) { try { // 检查对应工单是否存在 ProWorkorder_v2 proWorkOrder = Context .Queryable() .Where(it => it.ClientWorkorder == workOrderId) .First(); if (proWorkOrder == null) { return -1; } // 提取工单年周日,组成数组 int year = proWorkOrder.Year; int week = proWorkOrder.Week; int date = proWorkOrder.Date; List proWorkorders = GenerateWorkOrderListUtil( year, week, date, 2 ); if (proWorkorders == null) { return -1; } // 提取目标工单号所在工单列表的位置 int index = -1; for (int i = 0; i < proWorkorders.Count; i++) { if (workOrderId == proWorkorders[i].ClientWorkorder) { index = i; break; } } if (index == 0) { return 2; } for (int i = 0; i < index; i++) { if (proWorkorders[i].Status == 1) { return 1; } } if (index == proWorkorders.Count - 1) { return 3; } return 0; } catch (Exception ex) { return -1; } } public int[] CheckWorkOrderInDayListNum(string workOrderId) { try { int[] result = new int[4]; // 工单总数 int workOrderTotal = 0; // 当前位置 int index = 0; // 已完成 int finishNum = 0; // 未完成 int noFinishNum = 0; // 检查对应工单是否存在 ProWorkorder_v2 proWorkOrder = Context .Queryable() .Where(it => it.ClientWorkorder == workOrderId) .First(); if (proWorkOrder == null) { return result; } // 提取工单年周日,组成数组 int year = proWorkOrder.Year; int week = proWorkOrder.Week; int date = proWorkOrder.Date; List proWorkorders = GenerateWorkOrderListUtil( year, week, date, 2 ); if (proWorkorders == null) { return result; } workOrderTotal = proWorkorders.Count; // 提取目标工单号所在工单列表的位置 for (int i = 0; i < proWorkorders.Count; i++) { if (workOrderId == proWorkorders[i].ClientWorkorder) { index = i + 1; break; } } List finishWorkorders = GenerateWorkOrderListUtil( year, week, date, 1, 2 ); if (finishWorkorders == null) { return result; } finishNum = finishWorkorders.Count; noFinishNum = workOrderTotal - finishNum; // 最终赋值 result.SetValue(index, 0); result.SetValue(workOrderTotal, 1); result.SetValue(finishNum, 2); result.SetValue(noFinishNum, 3); return result; } catch (Exception ex) { return null; } } /// /// 工单需要打印标签总数 /// /// 工单号 /// 上件数 /// public int GetWorkOrderNeedPackingTotal(string workOrderId) { try { ProWorkorder_v2 workOrder = Context .Queryable() .Where(it => it.ClientWorkorder == workOrderId) .First(); var res = Context .Queryable() .Where(it => it.FKWorkorderId.Equals(workOrderId)) .GroupBy(it => it.FKWorkorderId) .Select(it => new { sum = SqlFunc.AggregateSum(it.Counter ?? 0) }) .First(); if (res == null) { return workOrder.PreviousNumber; } else { return workOrder.PreviousNumber - res.sum; } } catch (Exception ex) { return 0; } } /// /// 工单已打印标签数 /// /// /// public int GetWorkOrderPackingrecordCount(string workOrderId) { try { string[] Machines = new string[] { "0", "1", "2", "3" }; return Context .Queryable() .Where(it => it.WorkOrderNum == workOrderId) .Where(it => Machines.Contains(it.Machine)) .Where(it => it.Standby3 == null) .OrderBy(it => it.Id) .Count(); } catch (Exception ex) { return 0; } } public QcCommonFqcBoardDto GetWorkOrderBoardData(string workOrderId) { try { // 检查对应工单是否存在 ProWorkorder_v2 proWorkOrder = Context .Queryable() .Where(it => it.ClientWorkorder == workOrderId) .First(); if (proWorkOrder == null) { throw new Exception("未在生产工单中找到该工单!"); } // QcCommonFqcBoardDto boardData = new QcCommonFqcBoardDto(); boardData.WorkOrderId = workOrderId; // 提取工单年周日,组成数组 int year = proWorkOrder.Year; int week = proWorkOrder.Week; int date = proWorkOrder.Date; List proWorkorders = GenerateWorkOrderListUtil( year, week, date, 2 ); if (proWorkorders == null) { return null; } boardData.WorkOrderDayListCount = proWorkorders.Count; // 提取目标工单号所在工单列表的位置 for (int i = 0; i < proWorkorders.Count; i++) { if (workOrderId == proWorkorders[i].ClientWorkorder) { boardData.WorkOrderIndex = i + 1; break; } } boardData.WorkOrderPackageCount = GetWorkOrderNeedPackingTotal(workOrderId); boardData.WorkOrderFinishPackageNum = GetWorkOrderPackingrecordCount(workOrderId); boardData.WorkOrderNotFinishPackageNum = boardData.WorkOrderPackageCount - boardData.WorkOrderFinishPackageNum; // 如果不是第一个工单,找到上一个工单号 if (boardData.WorkOrderIndex > 1) { boardData.LastWorkOrderId = proWorkorders[ (boardData.WorkOrderIndex - 2) ?? 0 ].ClientWorkorder; boardData.LastWorkOrderPackageCount = GetWorkOrderNeedPackingTotal( boardData.LastWorkOrderId ); boardData.LastWorkOrderFinishPackageNum = GetWorkOrderPackingrecordCount( boardData.LastWorkOrderId ); boardData.LastWorkOrderNotFinishPackageNum = boardData.LastWorkOrderPackageCount - boardData.LastWorkOrderFinishPackageNum; } List finishWorkorders = GenerateWorkOrderListUtil( year, week, date, 1, 2 ); if (finishWorkorders == null) { return null; } boardData.WorkOrderFinishNum = finishWorkorders.Count; boardData.WorkOrderNotFinishNum = boardData.WorkOrderDayListCount - boardData.WorkOrderFinishNum; boardData.UpdatedTime = DateTime.Now; return boardData; } catch (Exception ex) { throw new Exception(ex.Message); } } public PagedInfo GetWorkOrderFqcData( QcCommonFqcWorkerOrderDataQuery query ) { try { // 时间解析 年 周(第几周) 日(星期) 转换 int year = -1; int week = -1; int date = -1; if (query.StartTime != null) { DateTime dateTime = query.StartTime ?? DateTime.Now; GregorianCalendar gregorianCalendar = new GregorianCalendar(); year = gregorianCalendar.GetYear(dateTime); week = gregorianCalendar.GetWeekOfYear( dateTime, CalendarWeekRule.FirstDay, DayOfWeek.Monday ); date = (int)gregorianCalendar.GetDayOfWeek(dateTime); if (date == 0) { date = 7; } } // 获取当天全部工单数据 bool isCheckData = true; if (!string.IsNullOrEmpty(query.WorkOrderId)) { isCheckData = false; } var predicate = Expressionable .Create() .AndIF(isCheckData, it => it.Year == year) .AndIF(isCheckData, it => it.Week == week) .AndIF(isCheckData, it => it.Date == date) .And(it => it.Remark3 == "是") .AndIF(query.Status > -1, it => it.Status == query.Status) .AndIF( !string.IsNullOrEmpty(query.WorkOrderId), it => it.ClientWorkorder.Contains(query.WorkOrderId) ) .AndIF( !string.IsNullOrEmpty(query.Partnumber), it => it.FinishedPartNumber.Contains(query.Partnumber) ) .AndIF( !string.IsNullOrEmpty(query.Description), it => it.ProductDescription.Contains(query.Description) || it.Colour.Contains(query.Description) || it.Specifications.Contains(query.Description) ) .ToExpression(); List orderList = Context .Queryable() .Where(predicate) .OrderBy(it => it.Sort) .ToList(); //TODO 分页暂不实现 //转换数据 PagedInfo resultPage = new PagedInfo(); List resultList = new List(); foreach (var item in orderList) { if (item != null) { string Remark = ""; WmMaterial material = Context .Queryable() .Where(it => it.Partnumber == item.FinishedPartNumber) .First(); string Description = ""; string Color = ""; string Specification = ""; if (material != null) { Description = material.Description; Color = material.Color; Specification = material.Specification; } else { Remark += "物料不在清单内 "; } // 首检报表数据拉取 QcQualityStatisticsFirst QcFirstData = Context .Queryable() .Where(it => it.WorkorderId == item.ClientWorkorder) .First(); string Team = ""; DateTime? startTime = null; DateTime? endTime = null; if (QcFirstData != null) { Team = QcFirstData.Team; startTime = QcFirstData.StartTime; endTime = QcFirstData.EndTime; if (startTime == null) { Remark += "工单开始时间为空 "; } } int WorkOrderPackageCount = GetWorkOrderNeedPackingTotal( item.ClientWorkorder ); int WorkOrderFinishPackageNum = GetWorkOrderPackingrecordCount( item.ClientWorkorder ); int WorkOrderNotFinishPackageNum = WorkOrderPackageCount - WorkOrderFinishPackageNum; if (WorkOrderNotFinishPackageNum < 0) { WorkOrderNotFinishPackageNum = 0; } bool IsFinish = WorkOrderNotFinishPackageNum == 0; QcCommonFqcWorkerOrderDataDto newItem = new() { WorkOrderId = item.ClientWorkorder, Partnumber = item.FinishedPartNumber, Description = Description, Color = Color, Specification = Specification, Team = Team, StartTime = startTime, EndTime = endTime, Status = item.Status, Remark = Remark, IsFinish = IsFinish, WorkOrderPackageCount = WorkOrderPackageCount, WorkOrderFinishPackageNum = WorkOrderFinishPackageNum, WorkOrderNotFinishPackageNum = WorkOrderNotFinishPackageNum }; resultList.Add(newItem); } } resultPage.Result = resultList; resultPage.TotalNum = resultPage.Result.Count; resultPage.PageSize = query.PageSize; resultPage.PageIndex = query.PageNum; return resultPage; } catch (Exception ex) { throw new Exception(ex.Message); } } /// /// 获取产线相关数据 /// /// /// /// public QcProductAndPolishAndOneTimeFqcBoardDto GetProductTotal( QcProductAndPolishAndOneTimeFqcBoardDto boardData, QcProductAndPolishAndOneTimeFqcBoardQuery query ) { // 投入数 var predicate1 = Expressionable .Create() .AndIF( !string.IsNullOrEmpty(query.Partnumber), it => it.FinishedPartNumber == query.Partnumber ) .AndIF( query.StartTime != null, it => it.StartTime >= query.StartTime.Value.ToLocalTime() ) .AndIF( query.EndTime != null, it => it.StartTime <= query.EndTime.Value.ToLocalTime() ) .ToExpression(); // 门把手提取 string[] checkStrArray = { "门把手", "面盖", "T22", "T26", "A58", "A60", "C01", "B02", "V71", "T1EJ" }; var DoorknobPartNumberCheck = Expressionable.Create(); foreach (string checkStr in checkStrArray) { DoorknobPartNumberCheck.Or(it => it.Description.Contains(checkStr)); } ; DoorknobPartNumberCheck.And(it => it.Type == 1).And(it => it.Status == 1); List DoorknobPartNumberList = Context .Queryable() .Where(DoorknobPartNumberCheck.ToExpression()) .Select(it => it.Partnumber) .ToList(); var predicate2 = Expressionable .Create() .And(it => DoorknobPartNumberList.Contains(it.FinishedPartNumber)) .AndIF( !string.IsNullOrEmpty(query.Partnumber), it => it.FinishedPartNumber == query.Partnumber ) .AndIF( query.StartTime != null, it => it.StartTime >= query.StartTime.Value.ToLocalTime() ) .AndIF( query.EndTime != null, it => it.StartTime <= query.EndTime.Value.ToLocalTime() ) .ToExpression(); // 倒车雷达提取 string[] checkStrArray2 = { "倒车雷达" }; var ParkingSensorPartNumberCheck = Expressionable.Create(); foreach (string checkStr in checkStrArray2) { ParkingSensorPartNumberCheck.Or(it => it.Description.Contains(checkStr)); } ; ParkingSensorPartNumberCheck.And(it => it.Type == 1).And(it => it.Status == 1); List ParkingSensorPartNumberList = Context .Queryable() .Where(ParkingSensorPartNumberCheck.ToExpression()) .Select(it => it.Partnumber) .ToList(); var predicateParkingSensor = Expressionable .Create() .And(it => ParkingSensorPartNumberList.Contains(it.FinishedPartNumber)) .AndIF( !string.IsNullOrEmpty(query.Partnumber), it => it.FinishedPartNumber == query.Partnumber ) .AndIF( query.StartTime != null, it => it.StartTime >= query.StartTime.Value.ToLocalTime() ) .AndIF( query.EndTime != null, it => it.StartTime <= query.EndTime.Value.ToLocalTime() ) .ToExpression(); boardData.ProductRequireTotal = Context .Queryable() .Where(predicate1) .Sum(it => it.RequireNumber) ?? 0; boardData.ProductQualifiedTotal = Context .Queryable() .Where(predicate1) .Sum(it => it.QualifiedNumber) ?? 0; // 门把手合格 boardData.ProductDoorknobQualifiedTotal = Context .Queryable() .Where(predicate2) .Sum(it => it.QualifiedNumber) ?? 0; // 倒车雷达合格 boardData.ProductParkingSensorbQualifiedTotal = Context .Queryable() .Where(predicateParkingSensor) .Sum(it => it.QualifiedNumber) ?? 0; boardData.ProductPolishTotal = Context .Queryable() .Where(predicate1) .Sum(it => it.PaoguangTotal) ?? 0; boardData.ProductSandingTotal = Context .Queryable() .Where(predicate1) .Sum(it => it.DamoTotal) ?? 0; boardData.ProductDiscardTotal = Context .Queryable() .Where(predicate1) .Sum(it => it.BaofeiTotal) ?? 0; // 除三优化 boardData.ProductRequireTotal = boardData.ProductRequireTotal / 3; boardData.ProductQualifiedTotal = boardData.ProductQualifiedTotal / 3; boardData.ProductDoorknobQualifiedTotal = boardData.ProductDoorknobQualifiedTotal / 3; boardData.ProductParkingSensorbQualifiedTotal = boardData.ProductParkingSensorbQualifiedTotal / 3; boardData.ProductPolishTotal = boardData.ProductPolishTotal / 3; boardData.ProductSandingTotal = boardData.ProductSandingTotal / 3; boardData.ProductDiscardTotal = boardData.ProductDiscardTotal / 3; // 投入数,合格数补正(合格数 = 总合格数 - 倒车雷达)[倒车雷达不参与合格率统计] boardData.ProductRequireTotal -= boardData.ProductParkingSensorbQualifiedTotal; boardData.ProductQualifiedTotal -= boardData.ProductParkingSensorbQualifiedTotal; if (boardData.ProductRequireTotal > 0) { double passRate = ((double)boardData.ProductQualifiedTotal / boardData.ProductRequireTotal) * 100; boardData.ProductQualifiePassRate = passRate.ToString("0") + "%"; } return boardData; } // 获取抛光相关数据 public QcProductAndPolishAndOneTimeFqcBoardDto GetPolishTotal( QcProductAndPolishAndOneTimeFqcBoardDto boardData, QcProductAndPolishAndOneTimeFqcBoardQuery query ) { var predicateInventory = Expressionable .Create() .AndIF( !string.IsNullOrEmpty(query.Partnumber), it => it.Partnumber == query.Partnumber ) .ToExpression(); var predicate1 = Expressionable .Create() .AndIF( !string.IsNullOrEmpty(query.Partnumber), it => it.Partnumber == query.Partnumber ) .AndIF( query.StartTime != null, it => it.StartTime >= query.StartTime.Value.ToLocalTime() ) .AndIF( query.EndTime != null, it => it.StartTime <= query.EndTime.Value.ToLocalTime() ) .ToExpression(); var predicate2 = Expressionable .Create() .AndIF( !string.IsNullOrEmpty(query.Partnumber), it => it.Partnumber == query.Partnumber ) .AndIF( query.StartTime != null, it => it.StartTime >= query.StartTime.Value.ToLocalTime() ) .AndIF( query.EndTime != null, it => it.StartTime <= query.EndTime.Value.ToLocalTime() ) .ToExpression(); string[] checkStrArray = { "门把手", "面盖", "T22", "T26", "A58", "A60", "C01", "B02", "V71", "T1EJ" }; var DoorknobPartNumberCheck = Expressionable.Create(); foreach (string checkStr in checkStrArray) { DoorknobPartNumberCheck.Or(it => it.Description.Contains(checkStr)); } ; DoorknobPartNumberCheck.And(it => it.Type == 1).And(it => it.Status == 1); List DoorknobPartNumberList = Context .Queryable() .Where(DoorknobPartNumberCheck.ToExpression()) .Select(it => it.Partnumber) .ToList(); // 倒车雷达提取 string[] checkStrArray2 = { "倒车雷达" }; var ParkingSensorPartNumberCheck = Expressionable.Create(); foreach (string checkStr in checkStrArray2) { ParkingSensorPartNumberCheck.Or(it => it.Description.Contains(checkStr)); } ; ParkingSensorPartNumberCheck.And(it => it.Type == 1).And(it => it.Status == 1); List ParkingSensorPartNumberList = Context .Queryable() .Where(ParkingSensorPartNumberCheck.ToExpression()) .Select(it => it.Partnumber) .ToList(); var predicateParkingSensor1 = Expressionable .Create() .And(it => ParkingSensorPartNumberList.Contains(it.Partnumber)) .AndIF( !string.IsNullOrEmpty(query.Partnumber), it => it.Partnumber == query.Partnumber ) .AndIF( query.StartTime != null, it => it.StartTime >= query.StartTime.Value.ToLocalTime() ) .AndIF( query.EndTime != null, it => it.StartTime <= query.EndTime.Value.ToLocalTime() ) .ToExpression(); var predicateParkingSensor2 = Expressionable .Create() .And(it => ParkingSensorPartNumberList.Contains(it.Partnumber)) .AndIF( !string.IsNullOrEmpty(query.Partnumber), it => it.Partnumber == query.Partnumber ) .AndIF( query.StartTime != null, it => it.StartTime >= query.StartTime.Value.ToLocalTime() ) .AndIF( query.EndTime != null, it => it.StartTime <= query.EndTime.Value.ToLocalTime() ) .ToExpression(); var predicate3 = Expressionable .Create() .And(it => DoorknobPartNumberList.Contains(it.Partnumber)) .AndIF( !string.IsNullOrEmpty(query.Partnumber), it => it.Partnumber == query.Partnumber ) .AndIF( query.StartTime != null, it => it.StartTime >= query.StartTime.Value.ToLocalTime() ) .AndIF( query.EndTime != null, it => it.StartTime <= query.EndTime.Value.ToLocalTime() ) .ToExpression(); var predicate4 = Expressionable .Create() .And(it => DoorknobPartNumberList.Contains(it.Partnumber)) .AndIF( !string.IsNullOrEmpty(query.Partnumber), it => it.Partnumber == query.Partnumber ) .AndIF( query.StartTime != null, it => it.StartTime >= query.StartTime.Value.ToLocalTime() ) .AndIF( query.EndTime != null, it => it.StartTime <= query.EndTime.Value.ToLocalTime() ) .ToExpression(); boardData.PolishWarehouseTotal = Context .Queryable() .Where(predicateInventory) .Sum(it => it.Quantity) ?? 0; boardData.PolishRequireTotal = Context .Queryable() .Where(predicate1) .Sum(it => it.RequireNumber) ?? 0; // 抛光合格 boardData.PolishQualifiedTotal = Context .Queryable() .Where(predicate1) .Sum(it => it.QualifiedNumber) ?? 0; // 抛光门把手 boardData.PolishDoorknobQualifiedTotal = Context .Queryable() .Where(predicate4) .Sum(it => it.QualifiedNumber) ?? 0; // 抛光倒车雷达 boardData.PolishParkingSensorbQualifiedTotal = Context .Queryable() .Where(predicateParkingSensor1) .Sum(it => it.QualifiedNumber) ?? 0; boardData.PolishSandingTotal = Context .Queryable() .Where(predicate1) .Sum(it => it.DamoTotal) ?? 0; boardData.PolishDiscardTotal = Context .Queryable() .Where(predicate1) .Sum(it => it.BaofeiTotal) ?? 0; boardData.AfterPolishRequireTotal = Context .Queryable() .Where(predicate2) .Sum(it => it.RequireNumber) ?? 0; // 后道合格 boardData.AfterPolishQualifiedTotal = Context .Queryable() .Where(predicate2) .Sum(it => it.QualifiedNumber) ?? 0; // 后道门把手合格数 boardData.AfterPolishDoorknobQualifiedTotal = Context .Queryable() .Where(predicate3) .Sum(it => it.QualifiedNumber) ?? 0; // 后道倒车雷达合格数 boardData.AfterPolishParkingSensorbQualifiedTotal = Context .Queryable() .Where(predicateParkingSensor2) .Sum(it => it.QualifiedNumber) ?? 0; boardData.AfterPolishPolishTotal = Context .Queryable() .Where(predicate2) .Sum(it => it.PaoguangTotal) ?? 0; boardData.AfterPolishSandingTotal = Context .Queryable() .Where(predicate2) .Sum(it => it.DamoTotal) ?? 0; boardData.AfterPolishDiscardTotal = Context .Queryable() .Where(predicate2) .Sum(it => it.BaofeiTotal) ?? 0; // 合格数修正 去掉倒车雷达 boardData.PolishRequireTotal -= boardData.PolishParkingSensorbQualifiedTotal; boardData.PolishQualifiedTotal -= boardData.PolishParkingSensorbQualifiedTotal; boardData.AfterPolishQualifiedTotal -= boardData.AfterPolishParkingSensorbQualifiedTotal; boardData.AfterPolishRequireTotal -= boardData.AfterPolishParkingSensorbQualifiedTotal; if (boardData.PolishRequireTotal > 0) { double passRate = ((double)boardData.PolishQualifiedTotal / boardData.PolishRequireTotal) * 100; boardData.PolishQualifiePassRate = passRate.ToString("0") + "%"; } if (boardData.AfterPolishRequireTotal > 0) { double passRate = ( (double)boardData.AfterPolishQualifiedTotal / boardData.AfterPolishRequireTotal ) * 100; boardData.AfterPolishQualifiePassRate = passRate.ToString("0") + "%"; } return boardData; } // 获取一次合格品相关数据 public QcProductAndPolishAndOneTimeFqcBoardDto GetOneTimeTotal( QcProductAndPolishAndOneTimeFqcBoardDto boardData, QcProductAndPolishAndOneTimeFqcBoardQuery query ) { var predicate1 = Expressionable .Create() .AndIF( !string.IsNullOrEmpty(query.Partnumber), it => it.Partnumber == query.Partnumber ) .ToExpression(); var predicate2 = Expressionable .Create() .AndIF( !string.IsNullOrEmpty(query.Partnumber), it => it.Partnumber == query.Partnumber ) .AndIF( query.StartTime != null, it => it.StartTime >= query.StartTime.Value.ToLocalTime() ) .AndIF( query.EndTime != null, it => it.StartTime <= query.EndTime.Value.ToLocalTime() ) .ToExpression(); // 门把手提取 string[] checkStrArray = { "门把手", "面盖", "T22", "T26", "A58", "A60", "C01", "B02", "V71", "T1EJ" }; var DoorknobPartNumberCheck = Expressionable.Create(); foreach (string checkStr in checkStrArray) { DoorknobPartNumberCheck.Or(it => it.Description.Contains(checkStr)); } ; DoorknobPartNumberCheck.And(it => it.Type == 1).And(it => it.Status == 1); List DoorknobPartNumberList = Context .Queryable() .Where(DoorknobPartNumberCheck.ToExpression()) .Select(it => it.Partnumber) .ToList(); var predicate3 = Expressionable .Create() .And(it => DoorknobPartNumberList.Contains(it.Partnumber)) .AndIF( !string.IsNullOrEmpty(query.Partnumber), it => it.Partnumber == query.Partnumber ) .AndIF( query.StartTime != null, it => it.StartTime >= query.StartTime.Value.ToLocalTime() ) .AndIF( query.EndTime != null, it => it.StartTime <= query.EndTime.Value.ToLocalTime() ) .ToExpression(); // 倒车雷达提取 string[] checkStrArray2 = { "倒车雷达" }; var ParkingSensorPartNumberCheck = Expressionable.Create(); foreach (string checkStr in checkStrArray2) { ParkingSensorPartNumberCheck.Or(it => it.Description.Contains(checkStr)); } ; ParkingSensorPartNumberCheck.And(it => it.Type == 1).And(it => it.Status == 1); List ParkingSensorPartNumberList = Context .Queryable() .Where(ParkingSensorPartNumberCheck.ToExpression()) .Select(it => it.Partnumber) .ToList(); var predicateParkingSensor = Expressionable .Create() .And(it => ParkingSensorPartNumberList.Contains(it.Partnumber)) .AndIF( !string.IsNullOrEmpty(query.Partnumber), it => it.Partnumber == query.Partnumber ) .AndIF( query.StartTime != null, it => it.StartTime >= query.StartTime.Value.ToLocalTime() ) .AndIF( query.EndTime != null, it => it.StartTime <= query.EndTime.Value.ToLocalTime() ) .ToExpression(); boardData.OneTimeWarehouseTotal = Context.Queryable().Where(predicate1).Sum(it => it.Quantity) ?? 0; boardData.GP12RequireTotal = Context .Queryable() .Where(predicate2) .Sum(it => it.RequireNumber) ?? 0; // GP12合格数 boardData.GP12QualifiedTotal = Context .Queryable() .Where(predicate2) .Sum(it => it.QualifiedNumber) ?? 0; // GP12门把手 boardData.GP12DoorknobQualifiedTotal = Context .Queryable() .Where(predicate3) .Sum(it => it.QualifiedNumber) ?? 0; // GP12倒车雷达 boardData.GP12ParkingSensorQualifiedTotal = Context .Queryable() .Where(predicateParkingSensor) .Sum(it => it.QualifiedNumber) ?? 0; boardData.GP12PolishTotal = Context .Queryable() .Where(predicate2) .Sum(it => it.PaoguangTotal) ?? 0; boardData.GP12SandingTotal = Context .Queryable() .Where(predicate2) .Sum(it => it.DamoTotal) ?? 0; boardData.GP12DiscardTotal = Context .Queryable() .Where(predicate2) .Sum(it => it.BaofeiTotal) ?? 0; // 倒车雷达去除 boardData.GP12QualifiedTotal -= boardData.GP12ParkingSensorQualifiedTotal; boardData.GP12RequireTotal -= boardData.GP12ParkingSensorQualifiedTotal; if (boardData.GP12RequireTotal > 0) { double passRate = ((double)boardData.GP12QualifiedTotal / boardData.GP12RequireTotal) * 100; boardData.GP12QualifiePassRate = passRate.ToString("0") + "%"; } return boardData; } // 获取成品仓库相关数据 public QcProductAndPolishAndOneTimeFqcBoardDto GetFinishProductTotal( QcProductAndPolishAndOneTimeFqcBoardDto boardData, QcProductAndPolishAndOneTimeFqcBoardQuery query ) { var predicate1 = Expressionable .Create() .AndIF( !string.IsNullOrEmpty(query.Partnumber), it => it.Partnumber == query.Partnumber ) .AndIF( query.StartTime != null, it => it.EntryWarehouseTime >= query.StartTime.Value.ToLocalTime() ) .AndIF( query.EndTime != null, it => it.EntryWarehouseTime <= query.EndTime.Value.ToLocalTime() ) .ToExpression(); var predicate2 = Expressionable .Create() .AndIF( !string.IsNullOrEmpty(query.Partnumber), it => it.Partnumber == query.Partnumber ) .AndIF( query.StartTime != null, it => it.OutTime >= query.StartTime.Value.ToLocalTime() ) .AndIF(query.EndTime != null, it => it.OutTime <= query.EndTime.Value.ToLocalTime()) .ToExpression(); boardData.FinishProductPartTotal = Context .Queryable() .Where(predicate1) .Sum(it => it.GoodsNumAction) ?? 0; boardData.FinishProductPackageTotal = Context .Queryable() .Where(predicate1) .Count(); boardData.FinishProductPartOutTotal = Context.Queryable().Where(predicate2).Sum(it => it.GoodsNumAction) ?? 0; boardData.FinishProductPackageOutTotal = Context .Queryable() .Where(predicate2) .Count(); return boardData; } /// /// 获取二次统计数据 /// /// /// /// public QcProductAndPolishAndOneTimeFqcBoardDto GetStatisticsTotal( QcProductAndPolishAndOneTimeFqcBoardDto boardData, QcProductAndPolishAndOneTimeFqcBoardQuery query ) { var predicate1 = Expressionable .Create() .AndIF( !string.IsNullOrEmpty(query.Partnumber), it => it.Partnumber == query.Partnumber ) .AndIF( query.StartTime != null, it => it.StartTime >= query.StartTime.Value.ToLocalTime() ) .AndIF( query.EndTime != null, it => it.StartTime <= query.EndTime.Value.ToLocalTime() ) .And(it => it.Type == 1) .ToExpression(); var predicate2 = Expressionable .Create() .AndIF( !string.IsNullOrEmpty(query.Partnumber), it => it.Partnumber == query.Partnumber ) .AndIF( query.StartTime != null, it => it.StartTime >= query.StartTime.Value.ToLocalTime() ) .AndIF( query.EndTime != null, it => it.StartTime <= query.EndTime.Value.ToLocalTime() ) .And(it => it.Type == 1) .ToExpression(); boardData.AfterPolishInTotal = Context .Queryable() .Where(predicate1) .Sum(it => it.QualifiedNumber) ?? 0; boardData.AfterPolishOutTotal = Context .Queryable() .Where(predicate1) .Sum(it => it.RequireNumber) ?? 0; boardData.StatisticsPolishQualifiedTotal = ( Context .Queryable() .Where(predicate1) .Sum(it => it.QualifiedNumber) ?? 0 ) + ( Context .Queryable() .Where(predicate2) .Sum(it => it.QualifiedNumber) ?? 0 ); boardData.StatisticsProductAndPolishQualifiedTotal = boardData.StatisticsPolishQualifiedTotal + boardData.ProductQualifiedTotal; // 盘点后库存计算值 // 抛光库盘点时间 boardData.PolishStockTime = Context .Queryable() .Where(it => it.Status == 1) .Select(it => it.CreatedTime) .First() ?? new DateTime(2024, 10, 19, 0, 0, 0); // 抛光盘点库存 int polishWarehouseTotal = Context .Queryable() .WhereIF( !string.IsNullOrEmpty(query.Partnumber), it => it.Partnumber == query.Partnumber ) .Sum(it => it.Quantity) ?? 0; boardData.StockPolishWarehouseCount = polishWarehouseTotal; // 产线抛光 int productPolishTotal = ( Context .Queryable() .WhereIF( !string.IsNullOrEmpty(query.Partnumber), it => it.FinishedPartNumber == query.Partnumber ) .Where(it => it.StartTime >= boardData.PolishStockTime) .Sum(it => it.PaoguangTotal) ?? 0 ) / 3; // 后道反抛 int afterPolishPolishTotal = Context .Queryable() .WhereIF( !string.IsNullOrEmpty(query.Partnumber), it => it.Partnumber == query.Partnumber ) .Where(it => it.StartTime >= boardData.PolishStockTime) .Sum(it => it.PaoguangTotal) ?? 0; // GP12反抛 int gP12PolishTotal = Context .Queryable() .WhereIF( !string.IsNullOrEmpty(query.Partnumber), it => it.Partnumber == query.Partnumber ) .Where(it => it.StartTime >= boardData.PolishStockTime) .Sum(it => it.PaoguangTotal) ?? 0; // 抛光总投入数 int polishRequireTotal = Context .Queryable() .WhereIF( !string.IsNullOrEmpty(query.Partnumber), it => it.Partnumber == query.Partnumber ) .Where(it => it.StartTime >= boardData.PolishStockTime) .Sum(it => it.RequireNumber) ?? 0; // 抛光实际库存 boardData.RealPolishWarehouseCount = polishWarehouseTotal + productPolishTotal + afterPolishPolishTotal + gP12PolishTotal - polishRequireTotal; // 一次合格库盘点时间 boardData.OneTimeStockTime = Context .Queryable() .Where(it => it.Status == 1) .Select(it => it.CreatedTime) .First() ?? new DateTime(2024, 10, 19, 0, 0, 0); // 一次合格盘点库存 int oneTimeWarehouseTotal = Context .Queryable() .WhereIF( !string.IsNullOrEmpty(query.Partnumber), it => it.Partnumber == query.Partnumber ) .Sum(it => it.Quantity) ?? 0; boardData.StockOneTimeWarehouseCount = oneTimeWarehouseTotal; // 产线合格 int productQualifiedTotal = Context .Queryable() .WhereIF( !string.IsNullOrEmpty(query.Partnumber), it => it.FinishedPartNumber == query.Partnumber ) .Where(it => it.StartTime >= boardData.OneTimeStockTime) .Sum(it => it.QualifiedNumber) ?? 0; // 倒车雷达 string[] checkStrArray2 = { "倒车雷达" }; var ParkingSensorPartNumberCheck = Expressionable.Create(); foreach (string checkStr in checkStrArray2) { ParkingSensorPartNumberCheck.Or(it => it.Description.Contains(checkStr)); } ; ParkingSensorPartNumberCheck.And(it => it.Type == 1).And(it => it.Status == 1); List ParkingSensorPartNumberList = Context .Queryable() .Where(ParkingSensorPartNumberCheck.ToExpression()) .Select(it => it.Partnumber) .ToList(); var predicateParkingSensor = Expressionable .Create() .And(it => ParkingSensorPartNumberList.Contains(it.FinishedPartNumber)) .AndIF( !string.IsNullOrEmpty(query.Partnumber), it => it.FinishedPartNumber == query.Partnumber ) .And(it => it.StartTime >= boardData.OneTimeStockTime) .ToExpression(); // 倒车雷达 int productParkingSensorbQualifiedTotal = Context .Queryable() .Where(predicateParkingSensor) .Sum(it => it.QualifiedNumber) ?? 0; // 产线合格 - 倒车雷达 productQualifiedTotal = (productQualifiedTotal - productParkingSensorbQualifiedTotal) / 3; // 抛光合格 int polishQualifiedTotal = Context .Queryable() .WhereIF( !string.IsNullOrEmpty(query.Partnumber), it => it.Partnumber == query.Partnumber ) .Where(it => it.StartTime >= boardData.OneTimeStockTime) .Sum(it => it.QualifiedNumber) ?? 0; // GP12总投入 int gP12RequireTotal = Context .Queryable() .WhereIF( !string.IsNullOrEmpty(query.Partnumber), it => it.Partnumber == query.Partnumber ) .Where(it => it.StartTime >= boardData.OneTimeStockTime) .Sum(it => it.RequireNumber) ?? 0; // 后道直接出库 int afterPolishOutTotal = Context .Queryable() .WhereIF( !string.IsNullOrEmpty(query.Partnumber), it => it.Partnumber == query.Partnumber ) .Where(it => it.Type == 1) .Where(it => it.StartTime >= boardData.OneTimeStockTime) .Sum(it => it.RequireNumber) ?? 0; boardData.RealOneTimeWarehouseCount = oneTimeWarehouseTotal + productQualifiedTotal + polishQualifiedTotal - gP12RequireTotal - afterPolishOutTotal; return boardData; } /// /// 获取产线,抛光,一次合格品质量报表看板数据 /// /// public QcProductAndPolishAndOneTimeFqcBoardDto GetProductAndPolishAndOneTimeFqcBoardData( QcProductAndPolishAndOneTimeFqcBoardQuery query ) { QcProductAndPolishAndOneTimeFqcBoardDto result = new(); result = GetProductTotal(result, query); result = GetPolishTotal(result, query); result = GetOneTimeTotal(result, query); result = GetFinishProductTotal(result, query); result = GetStatisticsTotal(result, query); result.SandingTotal = result.ProductSandingTotal + result.PolishSandingTotal + result.AfterPolishSandingTotal + result.GP12SandingTotal; result.DiscardTotal = result.ProductDiscardTotal + result.PolishDiscardTotal + result.AfterPolishDiscardTotal + result.GP12DiscardTotal; result.UpdatedTime = DateTime.Now.ToLocalTime(); return result; } // 获取抛光报表变动后 每个零件 的实际库存 startTime 必填 public Dictionary GetBatchPolishPartRealStock( List partNumbers, DateTime startTime ) { var result = new Dictionary(); try { foreach (var partNumber in partNumbers) { startTime = Context .Queryable() .Where(it => it.Partnumber == partNumber) .Select(it => it.CreatedTime) .First() ?? startTime; // 盘点数 int polishWarehouseTotal = Context .Queryable() .Where(it => it.Partnumber == partNumber) .Sum(it => it.Quantity) ?? 0; // 产线抛光 int productPolishTotal = Context .Queryable() .Where(it => it.FinishedPartNumber == partNumber) .Where(it => it.StartTime >= startTime) .Sum(it => it.PaoguangTotal) ?? 0; productPolishTotal = productPolishTotal / 3; // 后道反抛 int afterPolishPolishTotal = Context .Queryable() .Where(it => it.Partnumber == partNumber) .Where(it => it.StartTime >= startTime) .Sum(it => it.PaoguangTotal) ?? 0; // GP12 反抛 int gP12PolishTotal = Context .Queryable() .Where(it => it.Partnumber == partNumber) .Where(it => it.StartTime >= startTime) .Sum(it => it.PaoguangTotal) ?? 0; // 抛光出库 int polishRequireTotal = Context .Queryable() .Where(it => it.Partnumber == partNumber) .Where(it => it.StartTime >= startTime) .Sum(it => it.RequireNumber) ?? 0; int realStock = polishWarehouseTotal + productPolishTotal + afterPolishPolishTotal + gP12PolishTotal - polishRequireTotal; result.Add(partNumber, realStock); } return result; } catch (Exception ex) { // 此处应记录日志而不是直接抛出异常或返回0,否则调用者无法区别正常0库存与错误 Console.WriteLine($"An error occurred: {ex.Message}"); throw; // 重新抛出异常以告知调用者 } } // 获取GP12报表变动后 一次合格品 每个零件 的实际库存 startTime 必填 public Dictionary GetBatchOneTimePartRealStock( List partNumbers, DateTime startTime ) { var result = new Dictionary(); try { foreach (var partNumber in partNumbers) { startTime = Context .Queryable() .Where(it => it.Partnumber == partNumber) .Select(it => it.CreatedTime) .First() ?? startTime; // 基本值 int oneTimeWarehouseTotal = Context .Queryable() .Where(it => it.Partnumber == partNumber) .Sum(it => it.Quantity) ?? 0; // 产线倒车雷达 // 倒车雷达剔除数据 string[] checkStrArray2 = { "倒车雷达" }; var ParkingSensorPartNumberCheck = Expressionable.Create(); foreach (string checkStr in checkStrArray2) { ParkingSensorPartNumberCheck.Or(it => it.Description.Contains(checkStr)); } ; ParkingSensorPartNumberCheck.And(it => it.Type == 1).And(it => it.Status == 1); List ParkingSensorPartNumberList = Context .Queryable() .Where(ParkingSensorPartNumberCheck.ToExpression()) .Select(it => it.Partnumber) .ToList(); /* var predicateParkingSensor = Expressionable .Create() .And(it => ParkingSensorPartNumberList.Contains(it.FinishedPartNumber)) .And(it => it.FinishedPartNumber == partNumber) .And(it => it.StartTime >= startTime.ToLocalTime()) .ToExpression(); int productParkingSensorbQualifiedTotal = Context .Queryable() .Where(predicateParkingSensor) .Sum(it => it.QualifiedNumber) ?? 0; productParkingSensorbQualifiedTotal = productParkingSensorbQualifiedTotal / 3;*/ // 产线合格 int productQualifiedTotal = Context .Queryable() .Where(it => !ParkingSensorPartNumberList.Contains(it.FinishedPartNumber) ) .Where(it => it.FinishedPartNumber == partNumber) .Where(it => it.StartTime >= startTime) .Sum(it => it.QualifiedNumber) ?? 0; productQualifiedTotal = productQualifiedTotal / 3; // 抛光合格 int polishQualifiedTotal = Context .Queryable() .Where(it => it.Partnumber == partNumber) .Where(it => it.StartTime >= startTime) .Sum(it => it.QualifiedNumber) ?? 0; // gp12投入 int gP12RequireTotal = Context .Queryable() .Where(it => it.Partnumber == partNumber) .Where(it => it.StartTime >= startTime) .Sum(it => it.RequireNumber) ?? 0; // 后道直接出库 int afterPolishOutTotal = Context .Queryable() .Where(it => it.Partnumber == partNumber) .Where(it => it.StartTime >= startTime) .Where(it => it.Type == 1) .Sum(it => it.RequireNumber) ?? 0; int realStock = oneTimeWarehouseTotal + productQualifiedTotal + polishQualifiedTotal - gP12RequireTotal - afterPolishOutTotal; result.Add(partNumber, realStock); } return result; } catch (Exception ex) { // 此处应记录日志而不是直接抛出异常或返回0,否则调用者无法区别正常0库存与错误 Console.WriteLine($"An error occurred: {ex.Message}"); throw; // 重新抛出异常以告知调用者 } } /// /// 检查零件号是否是门把手 /// /// public bool CheckIsDoorknob(string partnumber) { string[] checkStrArray = { "门把手", "面盖", "T22", "T26", "A58", "A60", "C01", "B02", "V71", "T1EJ", "倒车雷达" }; var isDoorknobCheck = Expressionable.Create(); foreach (string checkStr in checkStrArray) { isDoorknobCheck.Or(it => it.Description.Contains(checkStr)); } ; isDoorknobCheck .And(it => it.Partnumber == partnumber) .And(it => it.Type == 1) .And(it => it.Status == 1); return Context.Queryable().Where(isDoorknobCheck.ToExpression()).Any(); } } }