using JdeScoping.DataAccess.Models; using SqlKata.Compilers; namespace JdeScoping.DataAccess.QueryBuilders; /// /// Builds MIS extraction queries for work order step matching. /// public sealed class MisQueryBuilder { private readonly SqlServerCompiler _compiler; /// /// Initializes a new instance of MisQueryBuilder. /// /// The SqlKata SQL Server compiler. public MisQueryBuilder(SqlServerCompiler compiler) { _compiler = compiler; } /// /// Builds the complete MIS extraction SQL including temp table setup and data population. /// /// The search model containing filter criteria. /// The SQL statements for MIS extraction. public IReadOnlyList BuildMisExtractionSql(SearchModel model) { var statements = new List(); // Create #TempMisData temp table statements.Add(BuildTempMisDataTableSql()); // Build and execute MIS CTE query to populate temp table statements.Add(BuildMisCteSql(model)); return statements; } private static string BuildTempMisDataTableSql() { return """ IF OBJECT_ID('tempdb.dbo.#TempMisData', 'U') IS NOT NULL BEGIN DROP TABLE #TempMisData; END CREATE TABLE #TempMisData ( WorkOrderNumber BIGINT, ItemNumber VARCHAR(25), ItemDescription VARCHAR(30), BranchCode VARCHAR(12), WorkCenterCode VARCHAR(12), StepTimestamp DATETIME, SequenceNumber DECIMAL(7, 2), FunctionCode VARCHAR(15), FunctionOperationDescription VARCHAR(80), MatchedSequenceNumber DECIMAL(7, 2), RoutingMatch BIT, MasterMatch BIT, MisNumber VARCHAR(32), RevID VARCHAR(32), CharNumber VARCHAR(32), MisSequenceNumber VARCHAR(32), TestDescription VARCHAR(2000), SamplingType VARCHAR(32), SamplingValue VARCHAR(32), ToolsGauges VARCHAR(2000), WorkInstructions VARCHAR(2000), Status VARCHAR(32), ReleaseDate DATETIME ); """; } private string BuildMisCteSql(SearchModel model) { var joins = BuildMisJoins(model); var whereClause = BuildMisWhereClause(model); return $""" WITH MIS_CTE AS( SELECT DISTINCT wo.WorkOrderNumber, wo.ItemNumber, wo.BranchCode, wo.RoutingType, wo.IssueDate, wos.WorkCenterCode, wos.StepNumber, wos.EndDT, wos.FunctionCode, wos.FunctionOperationDescription FROM dbo.WorkOrderStep AS wos INNER JOIN dbo.WorkOrder AS wo ON (wos.WorkOrderNumber = wo.WorkOrderNumber AND LTRIM(wos.BranchCode) = wo.BranchCode) LEFT OUTER JOIN dbo.WorkOrderTime AS wot ON (wos.WorkOrderNumber = wot.WorkOrderNumber AND LTRIM(wos.BranchCode) = wot.BranchCode AND wos.StepNumber = wot.StepNumber){joins}{whereClause} ) INSERT INTO #TempMISData ( WorkOrderNumber, ItemNumber, ItemDescription, BranchCode, WorkCenterCode, StepTimestamp, SequenceNumber, FunctionCode, FunctionOperationDescription, MatchedSequenceNumber, RoutingMatch, MasterMatch, MisNumber, RevID, CharNumber, MisSequenceNumber, TestDescription, SamplingType, SamplingValue, ToolsGauges, WorkInstructions, Status, ReleaseDate ) SELECT mm.WorkOrderNumber, mm.ItemNumber, mm.ItemDescription, mm.BranchCode, mm.WorkCenterCode, mm.StepTimestamp, mm.SequenceNumber, mm.FunctionCode, mm.FunctionOperationDescription, mm.MatchedSequenceNumber, mm.RoutingMatch, mm.MasterMatch, mm.MisNumber, mm.RevID, mm.CharNumber, mm.MisSequenceNumber, mm.TestDescription, mm.SamplingType, mm.SamplingValue, mm.ToolsGauges, mm.WorkInstructions, mm.Status, mm.ReleaseDate FROM MIS_CTE c CROSS APPLY dbo.MatchMIS(c.WorkOrderNumber, c.ItemNumber, c.BranchCode, c.RoutingType, c.IssueDate, c.WorkCenterCode, c.StepNumber, c.EndDT, c.FunctionCode, c.FunctionOperationDescription) AS mm; """; } private static string BuildMisJoins(SearchModel model) { var joins = new List(); if (model.ItemNumberFilterEnabled) { joins.Add(" INNER JOIN\r\n #P_ItemNumbers p_in ON (wo.ItemNumber = p_in.ItemNumber)"); } if (model.ProfitCenterFilterEnabled || model.WorkCenterFilterEnabled) { joins.Add(" INNER JOIN \r\n #P_WorkCenters p_wc ON (wos.WorkCenterCode = p_wc.Code)"); } if (model.OperatorFilterEnabled) { joins.Add(" INNER JOIN \r\n #P_OperatorIDs p_oi ON (wot.AddressNumber = p_oi.AddressNumber)"); } return string.Join("", joins); } private static string BuildMisWhereClause(SearchModel model) { if (model.MinimumDt.HasValue && model.MaximumDt.HasValue) { return """ WHERE (((wos.EndDT <= @p_MaximumDT) AND (wos.EndDT >= @p_MinimumDT)) OR ((wot.GlDate <= @p_MaximumDT) AND (wot.GlDate >= @p_MinimumDT))) """; } if (model.MinimumDt.HasValue && !model.MaximumDt.HasValue) { return """ WHERE (wos.EndDT >= @p_MinimumDT OR wot.GlDate >= @p_MinimumDT) """; } if (!model.MinimumDt.HasValue && model.MaximumDt.HasValue) { return """ WHERE (wos.EndDT <= @p_MaximumDT OR wot.GlDate <= @p_MaximumDT) """; } return ""; } }