﻿<?xml version="1.0" encoding="utf-8"?>
<ReportsExport>
  <Reports>
    <Report id="c0daca67-c856-47b1-bcf5-0e98127c1d7e" codekey="PassAndBackDateWBT" categoryCodekey="Testing" name="Set past green status for WBT and users" description="This will create a green status for the selected users and any required prior status at the &quot;Green status date&quot; provided.  If there are reasons this cannot be done (e.g. user not assigned to the item) this will be shown in the Notes column of the output.">
      <MetaData created="2012-04-12T12:53:11" createdBy="Administrator, VIWIS (Administrator)" createdBy_user_id="3" modified="2022-12-05T15:26:19" modifiedBy="Rolle, Administrator (Administrator)" modifiedBy_user_id="12" />
      <ExecutionDetails format="TableResult" commandType="SqlCommandOrQuery" exportHandler="" adminControl="" exportMultipleTablesToSheets="False" datesWithTime="False" extraParams="" />
      <Mandators mandatorMode="IncludeMandators" mandator_id="96ba2868-8baf-4e69-b1fb-d2cc6d6832e8" isStandard="False" isUsedByMenu="False">
        <Mandator mandatorName="ERGO_e-Campus" />
        <Mandator mandatorName="TestAllFeatures" />
      </Mandators>
      <Parameters>
        <Parameter id="a3916c66-34e4-4a8c-a399-12e038af0e93" isRequired="True" allowMultiSelect="False" name="Lernprogramm" contextName="Lernprogramm" defaultValue="" renderHint="Undefined" disableParameter="DontDisable" />
        <Parameter id="45d11fc6-23fc-4236-8b62-1c7c1ddee5b3" isRequired="True" allowMultiSelect="True" name="Users" contextName="Users" defaultValue="" renderHint="Undefined" disableParameter="DontDisable" />
        <Parameter id="a623a20e-a41f-48a3-be9b-e627c4a80595" isRequired="True" allowMultiSelect="False" name="BeforeDate" contextName="Green status date" defaultValue="" renderHint="Undefined" disableParameter="DontDisable" />
        <Parameter id="7a721121-2d2e-4a3d-b9e6-c6aa238e7ab2" isRequired="True" allowMultiSelect="False" name="Auswahl (ja/nein)" contextName="Change data (ja/nein)" defaultValue="0" renderHint="Undefined" disableParameter="DontDisable" />
      </Parameters>
      <Roles />
      <command>-- Start test variable area
 --DECLARE @current_mandator_id UNIQUEIDENTIFIER;
 --SELECT @current_mandator_id = id FROM tblMandators WHERE [name] = 'TestAllFeatures';
 --DECLARE @user_ids dbo.typeIntList;
 --INSERT INTO @user_ids VALUES (12), (43662), (44162), (44164);
 --DECLARE @theme_id UNIQUEIDENTIFIER = '5f1ed444-cdc9-45df-acbe-031b99c020e8';
 --DECLARE @beforeDate DATETIME = '2022-05-01 08:31:42'
 ---- 1 = Yes = Update the data, 0 = No = Just select the data
 --DECLARE @selection_yesno BIT = 1
-- End test variable area

DECLARE @scriptStartDate DATETIME = GETDATE();
DECLARE @todaysDate DATE = CAST(GETDATE() AS DATE);

-- Get a list of the statuses that need to be updated
IF OBJECT_ID('tempdb.dbo.#UserStatuses') IS NOT NULL 
BEGIN
    DROP TABLE #UserStatuses;
END

CREATE TABLE #UserStatuses
(
    UserId INT PRIMARY KEY,
    StatusId UNIQUEIDENTIFIER,
    ThemeSessionId UNIQUEIDENTIFIER,
    [Status] INT,
    IsAssigned BIT,
    HasExistingScormSession BIT
)

INSERT INTO
    #UserStatuses
SELECT
    u.value as userId,
    suih.id,
    suih.session_id,
    suih.status,
    IIF(EXISTS
        (
            SELECT  *
            FROM    tblStatusUserItemOverride
            WHERE   [user_id] = u.value
                AND item_id = @theme_id
        ), 1, 0) as IsAssigned,
    IIF(EXISTS
        (
            SELECT  *
            FROM    tblSCORMSessions
            WHERE   UserID = u.value
                AND theme_id = @theme_id
        ), 1, 0) as HasExistingScormSession
FROM
    @user_ids u
    LEFT JOIN  tblStatusUserItemHistory suih
        ON  suih.user_id = u.value
        AND suih.item_id = @theme_id
        AND suih.endDate IS NULL


SELECT
    u.intUserCn as userId, u.FullUserName, suih.[status] as PreUpdateStatus, suih.startDate, suih.endDate,
    CASE
        WHEN IsAssigned = 0
            THEN 'No update: user item assignment not present in DB, assignment job run?'
        WHEN s.[Status] = 2
            THEN 'No update: user already has a green status'
        WHEN s.HasExistingScormSession = 1
            THEN 'No update: user has an open SCORM session'
        ELSE ''
    END as Notes
FROM
    #UserStatuses s
    JOIN v_Users u
        ON  u.intUserCn = s.UserId
    LEFT JOIN tblStatusUserItemHistory suih
        ON  s.StatusId = suih.id
ORDER BY
    u.intUserCn

-- Now that we've messaged, remove the rows we're not interested in
DELETE FROM
    #UserStatuses
WHERE
    IsAssigned = 0
    OR [Status] = 2
    OR HasExistingScormSession = 1

IF @selection_yesno = 1
BEGIN
    -- Prepare some data we will need for all users

    -- Get a list of the SCOs that we need to set a value for
    IF OBJECT_ID('tempdb.dbo.#RequiredScos') IS NOT NULL 
    BEGIN
        DROP TABLE #RequiredScos;
    END

    CREATE TABLE #RequiredScos
    (
        identifier NVARCHAR(256),
        masteryscore INT
    )
    
    INSERT INTO #RequiredScos
        (identifier, masteryscore)
    SELECT
        identifier COLLATE DATABASE_DEFAULT,
        masteryscore
    FROM
        tblThemeStructures
    WHERE
        theme_id = @theme_id
        AND trackable = 1
        AND visible = 1

    DECLARE @lessonStatusVarId UNIQUEIDENTIFIER;
    SELECT
        @lessonStatusVarId = ID
    FROM
        [dbo].[tblSCORMVariable]
    WHERE
        Name = 'cmi.core.lesson_status'
    
    DECLARE @rawScoreVarId UNIQUEIDENTIFIER;
    DECLARE @IsScoreRequired BIT = 0;
    
    IF EXISTS
    (
        SELECT  *
        FROM    #RequiredScos
        WHERE   masteryscore IS NOT NULL
    )
    BEGIN
        SET @IsScoreRequired = 1;

        SELECT
            @rawScoreVarId = ID
        FROM
            [dbo].[tblSCORMVariable]
        WHERE
            Name = 'cmi.core.score.raw'
    END


    -- End data preparation

    -- Now for each user pass the WBT
    DECLARE @userCursor CURSOR 
    DECLARE @UserId INT;
    DECLARE @ThemeSessionId UNIQUEIDENTIFIER;

    SET @userCursor = CURSOR LOCAL FAST_FORWARD FOR
        SELECT
            UserId, ThemeSessionId
        FROM
            #UserStatuses

    OPEN @userCursor
    FETCH NEXT FROM @userCursor INTO @UserId, @ThemeSessionId

    WHILE (@@FETCH_status &lt;&gt; -1)
    BEGIN
		DECLARE @StatsThemeSessionId UNIQUEIDENTIFIER;
        DECLARE @IgnoredImportPath NVARCHAR(255);

        -- Start a stats theme session and initialize the user item status if necessary
        EXEC sp_StatsThemeSessionStart @UserId, @theme_id, 11, @StatsThemeSessionId OUTPUT, @IgnoredImportPath OUTPUT;

        -- If there was no open theme session then the returned StatsThemeSessionId will have the same
        -- value as the newly created ThemeSessionId and we can use this to update our table
        IF @ThemeSessionId IS NULL
        BEGIN
            UPDATE #UserStatuses
            SET
                ThemeSessionId = @StatsThemeSessionId
            WHERE
                UserId = @UserId

            print 'For user ' + CAST(@UserId AS NVARCHAR(50)) + ' setting ThemeSessionId to ''' + IIF(@StatsThemeSessionId IS NULL, '&lt;NULL&gt;', CAST(@StatsThemeSessionId AS NVARCHAR(50))) + '''';
        END

        -- Generate the SCORM sessions, one for each required SCO
        INSERT INTO
            tblSCORMSessions
            (
                SessionID,
                UserID,
                theme_id,
                RefID
            )
        SELECT
            NEWID(),
            @UserId,
            @theme_id,
            rs.identifier
        FROM
            #RequiredScos rs

        -- Generate the SCORM session data, first the lesson status
        INSERT INTO
            [dbo].[tblSCORMSessionValues]
            (
                [SessionID]
               ,[Name]
               ,[VariableID]
               ,[Data]
               ,[bDirty]
               ,[bSetBySCO]
            )
        SELECT
            ss.SessionID,
            'cmi.core.lesson_status' COLLATE DATABASE_DEFAULT,
            @lessonStatusVarId,
            'completed' COLLATE DATABASE_DEFAULT,
            1,
            1
        FROM
            tblSCORMSessions ss
            JOIN #RequiredScos rs
                ON  rs.identifier = ss.RefID COLLATE DATABASE_DEFAULT
        WHERE
            ss.theme_id = @theme_id
            AND ss.UserID = @UserId

        -- Then if necessary the score
        IF @IsScoreRequired = 1
        BEGIN
            INSERT INTO
                [dbo].[tblSCORMSessionValues]
                (
                    [SessionID]
                   ,[Name]
                   ,[VariableID]
                   ,[Data]
                   ,[bDirty]
                   ,[bSetBySCO]
                )
            SELECT
                ss.SessionID,
                'cmi.core.score.raw',
                @lessonStatusVarId,
                rs.masteryscore,
                1,
                1
            FROM
                tblSCORMSessions ss
                JOIN #RequiredScos rs
                    ON  rs.identifier = ss.RefID COLLATE DATABASE_DEFAULT
            WHERE
                ss.theme_id = @theme_id
                AND ss.UserID = @UserId
                AND rs.masteryscore IS NOT NULL
        END

        DECLARE @sessionCursor CURSOR 
        DECLARE @ScormSessionId UNIQUEIDENTIFIER

        -- Get all SCORM sessions for our user and the specified theme
        SET @sessionCursor = CURSOR LOCAL FAST_FORWARD FOR
            SELECT
                ss.SessionID
            FROM
                tblSCORMSessions ss
            WHERE
                ss.theme_id = @theme_id
                AND ss.UserID = @UserId

        OPEN @sessionCursor
        FETCH NEXT FROM @sessionCursor INTO @ScormSessionId

        WHILE (@@FETCH_status &lt;&gt; -1)
        BEGIN
		    EXEC sp_ScormLMSFinish @ScormSessionId, @beforeDate, 14

            FETCH NEXT FROM @sessionCursor INTO @ScormSessionId
        END

        CLOSE @sessionCursor;

        FETCH NEXT FROM @userCursor INTO @UserId, @ThemeSessionId
    END

    CLOSE @userCursor;

    --- Now that the statuses are created we need to back date them
    UPDATE
        suih
    SET
        startDate = 
        CASE
            WHEN us.StatusId IS NULL OR suih.[status] &gt; us.[Status]
                THEN @beforeDate
            ELSE    suih.startDate
        END,
        endDate =
        CASE
            WHEN suih.status != 2 AND (us.StatusId IS NULL OR suih.[status] &gt;= us.[Status])
                THEN @beforeDate
            ELSE suih.endDate
        END,
        created = @beforeDate
    FROM
        #UserStatuses us
        JOIN tblStatusUserItemHistory suih
            ON  us.UserId = suih.user_id
    WHERE
        suih.item_id = @theme_id
        AND suih.session_id = us.ThemeSessionId
        AND
        (
            us.StatusId IS NULL
            OR
            suih.status &gt;= us.Status
        )

    UPDATE
        tblThemeSessions
    SET
        startDate = @beforeDate
    FROM
        tblThemeSessions ts
        JOIN #UserStatuses us
            ON  us.UserId = ts.user_id
            AND us.ThemeSessionId = ts.id

    UPDATE
        tblStatsThemeSessions
    SET
        startTime = @beforeDate,
        lastPingTime = @beforeDate,
        durationSeconds = 1
    FROM
        tblStatsThemeSessions sts
        JOIN #UserStatuses us
            ON  sts.user_id = us.UserId
    WHERE
        sts.theme_id = @theme_id
        AND sts.startTime &gt; @scriptStartDate
    
    UPDATE
        tblThemeSessionSCORMData
    SET
        [timeStamp] = @beforeDate
    FROM
        tblThemeSessionSCORMData tssd
        JOIN #UserStatuses us
            ON  us.UserId = tssd.user_id
            AND us.ThemeSessionId = tssd.themeSession_id

    UPDATE
        tblSCORMData
    SET
        [TimeStamp] = @beforeDate
    FROM
        tblSCORMData sd
        JOIN tblThemeSessionSCORMData tssd
            ON  tssd.session_id = sd.SessionID
            AND tssd.user_id = sd.UserID
            AND tssd.theme_id = sd.theme_id
        JOIN #UserStatuses us
            ON  us.UserId = tssd.user_id 
            AND us.ThemeSessionId = tssd.themeSession_id

    UPDATE
        tblStatusUserCourse
    SET
        BestCompleteDate = 
        CASE
            WHEN CAST(BestCompleteDate AS date) = @todaysDate
                THEN @beforeDate
            ELSE
                BestCompleteDate
        END,
        [BestExercisesDate] = 
        CASE
            WHEN CAST([BestExercisesDate] AS date) = @todaysDate
                THEN @beforeDate
            ELSE
                [BestExercisesDate]
        END,
        [BestExamsDate] = 
        CASE
            WHEN CAST([BestExamsDate] AS date) = @todaysDate
                THEN @beforeDate
            ELSE
                [BestExamsDate]
        END
    FROM
        tblStatusUserCourse suc
        JOIN #UserStatuses us
            ON  us.UserId = suc.userId
    WHERE
        suc.theme_id = @theme_id


    -- As we set the duration of the theme session to 1 second (to avoid weird calculations between past dates and the present)
    -- the entry for tblStatusUserCourseHistory is not created
    INSERT INTO tblStatusUserCourseHistory
    (
        user_id, 
        theme_id, 
        theme_version,
        themeSession_id, 
        themeSessionStartTime, 
        complete, 
        inProgress, 
        exercises, 
        exams
    )
    SELECT
        sts.user_id, 
        sts.theme_id, 
        sts.theme_version, 
        sts.id, 
        sts.startTime, 
        suc.Complete, 
        suc.InProgress, 
        suc.Exercises, 
        suc.Exams
    FROM
        tblStatusUserCourse suc
        JOIN tblStatsThemeSessions sts
            ON  sts.theme_id = suc.theme_id
            AND sts.user_id = suc.UserId
        JOIN #UserStatuses us
            ON  us.UserId = sts.user_id
    WHERE
        suc.theme_id = @theme_id
        AND NOT EXISTS
        (
            SELECT
                *
            FROM
                tblStatusUserCourseHistory AS es
            WHERE
                es.user_id = suc.UserId
                AND es.theme_id = suc.theme_id
                AND es.themeSession_id = sts.id
                AND es.themeSessionStartTime = sts.startTime
        )   
    
    UPDATE
        tblUserItemCertificate
    SET
        received = @beforeDate
    FROM
        tblUserItemCertificate uic
        JOIN tblStatusUserItemHistory suih
            ON  suih.id = uic.status_id
        JOIN #UserStatuses us
            ON  us.UserId = suih.user_id
            AND us.ThemeSessionId = suih.session_id
    WHERE
        suih.status = 2

    UPDATE
        tblUserItemScores
    SET
        created = @beforeDate,
        -- Start date for the score should be the start date of the grey status
        startDate = (
            SELECT
                startDate
            FROM
                tblStatusUserItemHistory
            WHERE
                USER_ID = us.UserId
                AND item_id = @theme_id
                AND [status] = 0
                AND session_id = us.ThemeSessionId
        ),
        endDate = @beforeDate,
        readyForNewCreditPointsDate = NULL
    FROM
        tblUserItemScores uis
        JOIN tblStatusUserItemHistory suih
            ON  suih.id = uis.status_id
        JOIN #UserStatuses us
            ON  us.UserId = suih.user_id
            AND us.ThemeSessionId = suih.session_id
    WHERE
        suih.status = 2

    UPDATE
        tblStatusUserItemOverride
    SET
        readyForNewCreditPointsDate = NULL,
        periodStart = CAST(@beforeDate as date)
    FROM
        tblStatusUserItemOverride suio
        JOIN #UserStatuses us
            ON  us.UserId = suio.user_id
    WHERE
        suio.item_id = @theme_id

    -- Update period history, it will have been created with todays date as the period start
    UPDATE
        tblUserItemPeriodHistory
    SET
        periodStart = CAST(@beforeDate as date)
    FROM
        tblUserItemPeriodHistory uiph
        JOIN #UserStatuses us
            ON  us.UserId = uiph.user_id
    WHERE
        uiph.periodStart = @todaysDate
        AND uiph.item_id = @theme_id

    SELECT
        u.intUserCn as userId, u.FullUserName, suih.status as PostUpdateStatus, suih.startDate, suih.endDate
    FROM
        tblStatusUserItemHistory suih
        JOIN #UserStatuses us
            ON  us.UserId = suih.user_id
            AND us.ThemeSessionId = suih.session_id
        JOIN v_Users u
            ON  u.intUserCn = us.UserId
    WHERE
        suih.item_id = @theme_id
        AND suih.status = 2
    ORDER BY
        u.intUserCn
END</command>
    </Report>
  </Reports>
  <Parameters>
    <Parameter id="a3916c66-34e4-4a8c-a399-12e038af0e93" isSystem="True" name="Lernprogramm" reportParameterType_id="9b1ab1b2-f839-433b-8da7-02781b96def7" queryParameterName="@theme_id" />
    <Parameter id="45d11fc6-23fc-4236-8b62-1c7c1ddee5b3" isSystem="True" name="Users" reportParameterType_id="58877430-6b09-48f6-96c8-c7cf305ae405" queryParameterName="@user_ids" />
    <Parameter id="a623a20e-a41f-48a3-be9b-e627c4a80595" isSystem="True" name="BeforeDate" reportParameterType_id="0ba091dc-d92d-482a-bf93-a2a17e41e56c" queryParameterName="@beforeDate" />
    <Parameter id="7a721121-2d2e-4a3d-b9e6-c6aa238e7ab2" isSystem="True" name="Auswahl (ja/nein)" reportParameterType_id="411ec93b-ab23-41ba-91d6-e7dc0235b5af" queryParameterName="@selection_yesno" />
  </Parameters>
  <ParameterTypes>
    <ParameterType id="9b1ab1b2-f839-433b-8da7-02781b96def7" isSystem="True" name="Theme" datatype="Theme" dataValueField="" dataTextField="" />
    <ParameterType id="58877430-6b09-48f6-96c8-c7cf305ae405" isSystem="True" name="Alle Benutzer" datatype="IntegerDDL" dataValueField="intUserCn" dataTextField="FullUserName">
      <query>SELECT intUserCn, FullUserName
FROM  v_Users
WHERE mandator_id = @current_mandator_id
ORDER BY FullUserName</query>
    </ParameterType>
    <ParameterType id="0ba091dc-d92d-482a-bf93-a2a17e41e56c" isSystem="True" name="BeforeDate" datatype="Date" dataValueField="" dataTextField="" />
    <ParameterType id="411ec93b-ab23-41ba-91d6-e7dc0235b5af" isSystem="True" name="Boolean" datatype="StringDDL" dataValueField="Value" dataTextField="Text">
      <query>
        SELECT 0 AS Value, 'Nein' AS Text
        UNION
        SELECT 1 AS Value, 'Ja' AS Text
      </query>
    </ParameterType>
  </ParameterTypes>
</ReportsExport>