use [test1_AlplaPROD2.0_Read]

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); 
