From 6a14bab30c66f01a3b732138ebbcf6005cde6ed7 Mon Sep 17 00:00:00 2001 From: Blake Matthes Date: Tue, 16 Jun 2026 18:52:58 -0500 Subject: [PATCH] refactor(psi): rebuilt the delivery and planning data to 2.0 data --- backend/datamart/datamart.controller.ts | 6 +- .../queries/datamart.deliveryByDateRange.sql | 119 +++++++++--------- .../queries/datamart.psiDeliveryData.sql | 79 ------------ .../queries/datamart.psiPlanningData.sql | 102 ++++++++++----- 4 files changed, 133 insertions(+), 173 deletions(-) delete mode 100644 backend/prodSql/queries/datamart.psiDeliveryData.sql diff --git a/backend/datamart/datamart.controller.ts b/backend/datamart/datamart.controller.ts index 42b5de0..30eec2f 100644 --- a/backend/datamart/datamart.controller.ts +++ b/backend/datamart/datamart.controller.ts @@ -275,10 +275,10 @@ export const runDatamartQuery = async (data: Data) => { .replace("[startDate]", `${data.options.startDate}`) .replace("[endDate]", `${data.options.endDate}`) .replace( - "and p.IdArtikelvarianten in ([articles])", + "and pl.ArticleHumanReadableId IN ([articles]) ", data.options.articles - ? `and p.IdArtikelvarianten in (${data.options.articles})` - : "--and p.IdArtikelvarianten in ([articles])", + ? `and pl.ArticleHumanReadableId IN (${data.options.articles})` + : "--and pl.ArticleHumanReadableId IN ([articles])", ); break; default: diff --git a/backend/prodSql/queries/datamart.deliveryByDateRange.sql b/backend/prodSql/queries/datamart.deliveryByDateRange.sql index af11aa8..e6bd0fb 100644 --- a/backend/prodSql/queries/datamart.deliveryByDateRange.sql +++ b/backend/prodSql/queries/datamart.deliveryByDateRange.sql @@ -1,74 +1,73 @@ use [test1_AlplaPROD2.0_Read] -DECLARE @StartDate DATE = '[startDate]' -- 2025-1-1 -DECLARE @EndDate DATE = '[endDate]' -- 2025-1-31 -SELECT -r.[ArticleHumanReadableId] - ,[ReleaseNumber] - ,h.CustomerOrderNumber - ,x.CustomerLineItemNumber - ,[CustomerReleaseNumber] - ,[ReleaseState] - ,[DeliveryState] - ,ea.JournalNummer as BOL_Number - ,[ReleaseConfirmationState] - ,[PlanningState] +DECLARE @StartDate DATE = '[startDate]' +DECLARE @EndDate DATE = '[endDate]' + +;WITH bol_20 AS ( -- 2.0 BOL, one per release (newest doc wins) + SELECT pos.ReleaseId, + dd.JournalNumber, + ROW_NUMBER() OVER (PARTITION BY pos.ReleaseId + ORDER BY dd.ShippingDate DESC) AS rn + FROM [outboundDelivery].[DeliveryDocumentPosition] (nolock) pos + JOIN [outboundDelivery].[DeliveryDocument] (nolock) dd + ON dd.Id = pos.DeliveryDocumentId + -- WHERE dd.DocumentType = -- see note below +) +SELECT + r.[ArticleHumanReadableId] + ,[ReleaseNumber] + ,h.CustomerOrderNumber + ,x.CustomerLineItemNumber + ,[CustomerReleaseNumber] + ,[ReleaseState] + ,[DeliveryState] + ,COALESCE(ea.JournalNummer, bol_20.JournalNumber) AS BOL_Number -- 1.0 or 2.0 + ,[ReleaseConfirmationState] + ,[PlanningState] ,format(r.[OrderDate], 'yyyy-MM-dd HH:mm') as OrderDate --,r.[OrderDate] ,FORMAT(r.[DeliveryDate], 'yyyy-MM-dd HH:mm') as DeliveryDate --,r.[DeliveryDate] ,FORMAT(r.[LoadingDate], 'yyyy-MM-dd HH:mm') as LoadingDate --,r.[LoadingDate] - ,[Quantity] - ,[DeliveredQuantity] - ,r.[AdditionalInformation1] - ,r.[AdditionalInformation2] - ,[TradeUnits] - ,[LoadingUnits] - ,[Trucks] - ,[LoadingToleranceType] - ,[SalesPrice] - ,[Currency] - ,[QuantityUnit] - ,[SalesPriceRemark] - ,r.[Remark] - ,[Irradiated] - ,r.[CreatedByEdi] - ,[DeliveryAddressHumanReadableId] - ,DeliveryAddressDescription - ,[CustomerArtNo] - ,[TotalPrice] - ,r.[ArticleAlias] + ,[Quantity] + ,[DeliveredQuantity] + ,r.[AdditionalInformation1] + ,r.[AdditionalInformation2] + ,[TradeUnits] + ,[LoadingUnits] + ,[Trucks] + ,[LoadingToleranceType] + ,[SalesPrice] + ,[Currency] + ,[QuantityUnit] + ,[SalesPriceRemark] + ,r.[Remark] + ,[Irradiated] + ,r.[CreatedByEdi] + ,[DeliveryAddressHumanReadableId] + ,DeliveryAddressDescription + ,[CustomerArtNo] + ,[TotalPrice] + ,r.[ArticleAlias] +FROM [order].[Release] (nolock) AS r +LEFT JOIN [order].LineItem AS x ON r.LineItemId = x.id +LEFT JOIN [order].Header AS h ON x.HeaderId = h.id - FROM [order].[Release] (nolock) as r +-- 1.0 BOL (legacy) — unchanged +LEFT JOIN AlplaPROD_test1.dbo.V_LadePlanungenLadeAuftragAbruf (nolock) AS zz + ON zz.AbrufIdAuftragsAbruf = r.ReleaseNumber +LEFT JOIN ( + SELECT * FROM ( + SELECT ROW_NUMBER() OVER (PARTITION BY IdJournal ORDER BY add_date DESC) AS RowNum, * + FROM [AlplaPROD_test1].[dbo].[T_Lieferungen] (nolock) + ) t WHERE RowNum = 1 +) AS ea ON zz.IdLieferschein = ea.IdJournal - left join - [order].LineItem as x on +-- 2.0 BOL (new) +LEFT JOIN bol_20 ON bol_20.ReleaseId = r.Id AND bol_20.rn = 1 - r.LineItemId = x.id - - left join - [order].Header as h on - x.HeaderId = h.id - - --bol stuff - left join - AlplaPROD_test1.dbo.V_LadePlanungenLadeAuftragAbruf (nolock) as zz - on zz.AbrufIdAuftragsAbruf = r.ReleaseNumber - - left join -(select * from (SELECT -ROW_NUMBER() OVER (PARTITION BY IdJournal ORDER BY add_date DESC) AS RowNum -,* - FROM [AlplaPROD_test1].[dbo].[T_Lieferungen] (nolock)) x - - where RowNum = 1) as ea on - zz.IdLieferschein = ea.IdJournal - -where ---r.ReleaseNumber = 1452 - -r.DeliveryDate between @StartDate AND @EndDate +WHERE r.DeliveryDate BETWEEN @StartDate AND @EndDate and DeliveredQuantity > 0 --and r.ArticleHumanReadableId in ([articles]) --and Journalnummer = 169386 \ No newline at end of file diff --git a/backend/prodSql/queries/datamart.psiDeliveryData.sql b/backend/prodSql/queries/datamart.psiDeliveryData.sql deleted file mode 100644 index 32c8c1c..0000000 --- a/backend/prodSql/queries/datamart.psiDeliveryData.sql +++ /dev/null @@ -1,79 +0,0 @@ -use AlplaPROD_test1 -/** - -move this over to the delivery date range query once we have the shift data mapped over correctly. - -update the psi stuff on this as well. -**/ -DECLARE @StartDate DATE = '[startDate]' -- 2025-1-1 -DECLARE @EndDate DATE = '[endDate]' -- 2025-1-31 -SELECT -r.[ArticleHumanReadableId] - ,[ReleaseNumber] - ,h.CustomerOrderNumber - ,x.CustomerLineItemNumber - ,[CustomerReleaseNumber] - ,[ReleaseState] - ,[DeliveryState] - ,ea.JournalNummer as BOL_Number - ,[ReleaseConfirmationState] - ,[PlanningState] - --,format(r.[OrderDate], 'yyyy-MM-dd HH:mm') as OrderDate - ,r.[OrderDate] - --,FORMAT(r.[DeliveryDate], 'yyyy-MM-dd HH:mm') as DeliveryDate - ,r.[DeliveryDate] - --,FORMAT(r.[LoadingDate], 'yyyy-MM-dd HH:mm') as LoadingDate - ,r.[LoadingDate] - ,[Quantity] - ,[DeliveredQuantity] - ,r.[AdditionalInformation1] - ,r.[AdditionalInformation2] - ,[TradeUnits] - ,[LoadingUnits] - ,[Trucks] - ,[LoadingToleranceType] - ,[SalesPrice] - ,[Currency] - ,[QuantityUnit] - ,[SalesPriceRemark] - ,r.[Remark] - ,[Irradiated] - ,r.[CreatedByEdi] - ,[DeliveryAddressHumanReadableId] - ,DeliveryAddressDescription - ,[CustomerArtNo] - ,[TotalPrice] - ,r.[ArticleAlias] - - FROM [order].[Release] (nolock) as r - - left join - [order].LineItem as x on - - r.LineItemId = x.id - - left join - [order].Header as h on - x.HeaderId = h.id - - --bol stuff - left join - AlplaPROD_test1.dbo.V_LadePlanungenLadeAuftragAbruf (nolock) as zz - on zz.AbrufIdAuftragsAbruf = r.ReleaseNumber - - left join -(select * from (SELECT -ROW_NUMBER() OVER (PARTITION BY IdJournal ORDER BY add_date DESC) AS RowNum -,* - FROM [AlplaPROD_test1].[dbo].[T_Lieferungen] (nolock)) x - - where RowNum = 1) as ea on - zz.IdLieferschein = ea.IdJournal - -where -r.ArticleHumanReadableId in ([articles]) ---r.ReleaseNumber = 1452 - -and r.DeliveryDate between @StartDate AND @EndDate ---and DeliveredQuantity > 0 ---and Journalnummer = 169386 diff --git a/backend/prodSql/queries/datamart.psiPlanningData.sql b/backend/prodSql/queries/datamart.psiPlanningData.sql index 65b5b65..ae5d6fb 100644 --- a/backend/prodSql/queries/datamart.psiPlanningData.sql +++ b/backend/prodSql/queries/datamart.psiPlanningData.sql @@ -1,32 +1,72 @@ - use AlplaPROD_test1 - declare @start_date nvarchar(30) = '[startDate]' --'2025-01-01' - declare @end_date nvarchar(30) = '[endDate]' --'2025-08-09' - /* - articles will need to be passed over as well as the date structure we want to see - */ +use [test1_AlplaPROD2.0_Read] - select x.IdArtikelvarianten As Article, - ProduktionAlias as Description, - standort as MachineId, - MaschinenBezeichnung as MachineName, - --MaschZyklus as PlanningCycleTime, - x.IdProdPlanung as LotNumber, - FORMAT(ProdTag, 'MM/dd/yyyy') as ProductionDay, - x.planMenge as TotalPlanned, - ProduktionMenge as QTYPerDay, - round(ProduktionMengeVPK, 2) PalDay, - Status as finished - --MaschStdAuslastung as nee - - from dbo.V_ProdLosProduktionJeProdTag_PLANNING (nolock) as x - - left join - dbo.V_ProdPlanung (nolock) as p on - x.IdProdPlanung = p.IdProdPlanung - - where ProdTag between @start_date and @end_date - and p.IdArtikelvarianten in ([articles]) - --and V_ProdLosProduktionJeProdTag_PLANNING.IdKunde = 10 - --and IdProdPlanung = 18442 - - order by ProdTag desc \ No newline at end of file +DECLARE @start_date date = '[startDate]'; --'2025-01-01' +DECLARE @end_date date = '[endDate]'; --'2025-08-09' +DECLARE @tz sysname = 'Eastern Standard Time'; -- usday1; use 'Central Standard Time' for usksc1 +DECLARE @shiftSeconds int = 7*3600; -- 07:00 production-day anchor +--TODO: add in the proper time zone based on the env, get correcr shift time as well +;WITH src AS ( + SELECT + pl.RunningNumber, pl.ArticleHumanReadableId, pl.ArticleAlias, pl.ArticleDescription, + pl.MachineLocation, pl.MachineDescription, pl.ProductionLotState, pl.ProductionInterrupt, + pl.PlanQuantityPieces, pl.PlanQuantityLoadingUnit, + CAST(pl.ProdStart AT TIME ZONE @tz AS datetime2(0)) AS StartLocal, + CAST(pl.PlanEnd AT TIME ZONE @tz AS datetime2(0)) AS EndLocal + FROM productionScheduling.ProductionLot AS pl + WHERE pl.PlanEnd > pl.ProdStart + and pl.publishState = 1 + and pl.ArticleHumanReadableId IN ([articles]) -- <-- article filter (was IdArtikelvarianten) + --AND pl.RunningNumber = 28094 -- <-- lot filter (was IdProdPlanung); comment out for all +), +calc AS ( + SELECT *, + DATEADD(SECOND, @shiftSeconds, + CAST(CASE WHEN DATEDIFF(SECOND, CAST(StartLocal AS date), StartLocal) >= @shiftSeconds + THEN CAST(StartLocal AS date) + ELSE DATEADD(DAY,-1, CAST(StartLocal AS date)) END AS datetime2(0))) AS FirstBoundary + FROM src +), +days AS ( -- one row per production day the lot touches + SELECT RunningNumber, ArticleHumanReadableId, ArticleAlias, ArticleDescription, MachineLocation, + MachineDescription, ProductionLotState, PlanQuantityPieces, PlanQuantityLoadingUnit, + StartLocal, EndLocal, FirstBoundary AS DayStart + FROM calc + UNION ALL + SELECT RunningNumber, ArticleHumanReadableId, ArticleAlias, ArticleDescription, MachineLocation, + MachineDescription, ProductionLotState, PlanQuantityPieces, PlanQuantityLoadingUnit, + StartLocal, EndLocal, DATEADD(DAY,1,DayStart) + FROM days + WHERE DATEADD(DAY,1,DayStart) < EndLocal +), +seg AS ( -- working seconds inside each production day + SELECT *, + DATEDIFF(SECOND, + CASE WHEN StartLocal > DayStart THEN StartLocal ELSE DayStart END, + CASE WHEN EndLocal < DATEADD(DAY,1,DayStart) THEN EndLocal ELSE DATEADD(DAY,1,DayStart) END + ) AS SegSec + FROM days +), +cum AS ( -- cumulative seconds for telescoping round + SELECT *, + SUM(SegSec) OVER (PARTITION BY RunningNumber ORDER BY DayStart ROWS UNBOUNDED PRECEDING) AS CumEnd, + SUM(SegSec) OVER (PARTITION BY RunningNumber ORDER BY DayStart ROWS UNBOUNDED PRECEDING) - SegSec AS CumStart, + SUM(SegSec) OVER (PARTITION BY RunningNumber) AS DenomSec + FROM seg +) +SELECT + ArticleHumanReadableId AS Article, + ArticleAlias AS Description, + MachineLocation AS MachineId, + MachineDescription AS MachineName, + RunningNumber AS LotNumber, + FORMAT(DayStart, 'MM/dd/yyyy') AS ProductionDay, + PlanQuantityPieces AS TotalPlanned, + ROUND(PlanQuantityPieces * 1.0 * CumEnd / DenomSec, 0) + - ROUND(PlanQuantityPieces * 1.0 * CumStart / DenomSec, 0) AS QTYPerDay, + ROUND(PlanQuantityLoadingUnit * CumEnd / DenomSec, 2) + - ROUND(PlanQuantityLoadingUnit * CumStart / DenomSec, 2) AS PalDay, + ProductionLotState AS finished +FROM cum +WHERE CAST(DayStart AS date) BETWEEN @start_date AND @end_date -- filter AFTER cumulative calc +ORDER BY RunningNumber, DayStart DESC +OPTION (MAXRECURSION 366);