USP_DATALIST_LOCATIONAVAILABILITY

Parameters

Parameter Parameter Type Mode Description
@LOCATIONSSELECTED xml IN
@STARTDATE date IN
@ENDDATE date IN
@STARTTIME time IN
@ENDTIME time IN
@AVAIL_UNAVAIL tinyint IN

Definition

Copy


CREATE procedure dbo.USP_DATALIST_LOCATIONAVAILABILITY (
    @LOCATIONSSELECTED xml = null,
    @STARTDATE date = null,
    @ENDDATE date = null,
    @STARTTIME time(0) = null,
    @ENDTIME time(0) = null,
    @AVAIL_UNAVAIL tinyint = 0
)
as
    set nocount on;

    declare @LOCATIONLIST as table 
    (
        ID uniqueidentifier
    );

    insert into @LOCATIONLIST 
    select
        T.c.value('(ID)[1]','uniqueidentifier') as 'ID'
    from @LOCATIONSSELECTED.nodes('/LOCATIONSSELECTED/ITEM') T(c)
    where T.c.value('(SELECTED)[1]','bit')='TRUE';

    declare @LOCATIONUSAGE table (
        PROGRAM nvarchar(100),
        LOCATIONID uniqueidentifier,
        LOCATION nvarchar(100),
        STARTDATE date,
        ENDDATE date,
        STARTTIME time,
        ENDTIME time,
        QUANTITY int,
        EVENTCAPACITY int,
        LOCATIONCAPACITY int
    );

    --populate @LOCATIONUSAGE with all booked location information from Sales and Events

    with event_cte as (
        select 
            ID,
            NAME,
            PROGRAMID,
            EVENTLOCATIONID,
            CAPACITY,
            d.[DAY] STARTDATE,
            d.[DAY] ENDDATE,
            case 
                when d.[DAY] = STARTDATE then
                    case STARTTIME
                        when '' then convert(time(0), '00:00:00')
                        else convert(time(0), STARTDATETIME)
                    end
                else convert(time(0), '00:00:00')
            end as STARTTIME,
            case 
                when d.[DAY] = ENDDATE then
                    case ENDTIME
                        when '' then convert(time(0), '23:59:59')
                        else convert(time(0), ENDDATETIME)
                    end
                else
                convert(time(0), '23:59:59')
            end as ENDTIME
        from dbo.EVENT
            inner join 
            (
                select DATEADD(D,NUM, @STARTDATE) as [DAY] from NUMBERS
            ) as D on D.[DAY] <= ENDDATE and D.[DAY] >= STARTDATE
    )
    --Sales
    insert into @LOCATIONUSAGE (      
        PROGRAM,
        LOCATIONID,
        lOCATION,
        STARTDATE,
        ENDDATE,
        STARTTIME,
        ENDTIME,
        QUANTITY,
        EVENTCAPACITY,
        LOCATIONCAPACITY
    )
    select 
        p.NAME,
        el.id,
        el.NAME,
        e.STARTDATE,
        e.ENDDATE,
        e.STARTTIME,
        e.ENDTIME,
        coalesce(sum(ticketSold.QUANTITYSOLD), 0),
        max(e.CAPACITY),
        max(el.CAPACITY)
    from  @LOCATIONLIST ll
        inner join dbo.EVENTLOCATION el on el.ID = ll.ID
        inner join dbo.PROGRAMEVENTLOCATION pel on pel.EVENTLOCATIONID = el.ID
        inner join event_cte e on e.ID = pel.EVENTID
        inner join dbo.PROGRAM p on p.ID = e.PROGRAMID
        left join (
            select
                e.ID as EVENTID,
                sum(si.QUANTITY - coalesce(refunds.QUANTITY, 0)) as QUANTITYSOLD
            from dbo.SALESORDERITEM si
                inner join dbo.SALESORDERITEMTICKET ticket on si.ID = ticket.ID
                inner join dbo.SALESORDER so on si.SALESORDERID = so.ID
                inner join dbo.EVENT e on ticket.EVENTID = e.ID
                left join (
                    select 
                        ci.SALESORDERITEMID,
                        SUM(li.QUANTITY) QUANTITY
                    from dbo.CREDITITEM_EXT ci 
                        inner join dbo.FINANCIALTRANSACTIONLINEITEM li on li.ID = ci.ID
                    group by ci.SALESORDERITEMID
                ) refunds on refunds.SALESORDERITEMID = si.ID
            where so.STATUSCODE <> 5
            group by e.ID) ticketSold on ticketSold.EVENTID = e.ID
        where 
            (e.STARTDATE     >= @STARTDATE or @STARTDATE is null)
            and (e.ENDDATE   <= @ENDDATE or @ENDDATE is null)
            and (e.STARTTIME >= @STARTTIME or @STARTTIME is null)
            and (e.ENDTIME   <= @ENDTIME or @ENDTIME is null)
    group by 
        p.NAME,
        el.id,
        el.NAME,
        e.STARTDATE,
        e.ENDDATE,
        e.STARTTIME,
        e.ENDTIME
    union

    --Events
    select 
        e.NAME,
        el.ID,
        el.NAME,
        e.STARTDATE,
        e.ENDDATE,
        e.STARTTIME,
        e.ENDTIME,
        count(r.ID) [QUANTITY],
        max(e.CAPACITY),
        max(el.CAPACITY)
    from @LOCATIONLIST ll
        inner join dbo.EVENTLOCATION el on el.ID = ll.ID
        inner join event_cte e on e.EVENTLOCATIONID = el.ID
        left join dbo.REGISTRANT r ON r.EVENTID = e.ID and r.WILLNOTATTEND = 0 and r.ISCANCELLED = 0
    where
        (e.STARTDATE     >= @STARTDATE or @STARTDATE is null)
        and (e.ENDDATE   <= @ENDDATE or @ENDDATE is null)
        and (e.STARTTIME >= @STARTTIME or @STARTTIME is null)
        and (e.ENDTIME   <= @ENDTIME or @ENDTIME is null)
    group by 
        e.NAME,
        el.ID, 
        el.NAME,
        e.STARTDATE,
        e.ENDDATE,
        e.STARTTIME,
        e.ENDTIME;

    declare @LOCATIONAVAILABILIY table (        --temp table to hold Available dates and times
        [DATE] date,
        [LOCATIONID] uniqueidentifier,
        [LOCATION] nvarchar(100),
        [EVENTCAPACITY] int,
        [LOCATIONCAPACITY] int,
        [AVAILFROM] time,
        [AVAILTO] time
    );

    declare
        @LOCID uniqueidentifier,
        @LOC nvarchar(100),--Location
        @STARTD date,
        @ENDD date,
        @STARTT time,
        @ENDT time,
        @EVENTCAP int, --Capacity
        @LOCATIONCAP int,
        @AVAILFROM time,
        @AVAILTO time,
        @NEWDATE bit, --tells if still working on the same date between rows
        @LASTENDTIME time, --End time from the previous row
        @LASTSTARTDATE date, --Start Date from the previous row
        @LASTLOCATIONID uniqueidentifier,--Location from the previous row
        @LASTLOCATION nvarchar(100),
        @LASTENDDATE date, --End Date from previous row
        @LASTEVENTCAP int, --Capacity from previous row
        @LASTLOCATIONCAP int,
        @NEWLOCATION bit = 1, --Indicates that we have moved to a new location
        @WORKINGDATE date --Variable used in While clause;

    set @WORKINGDATE = @STARTDATE;                
    set @NEWDATE = 1;
    set @LASTLOCATIONID = null;
    set @LASTLOCATION = '';
    set @AVAILFROM = '00:00:00';
    set @AVAILTO = '23:59:59';

    if @AVAIL_UNAVAIL = 0
        begin
            declare @SELECTEDID uniqueidentifier  = null;

            --Cursor loops through selected locations
            declare crsSELECTED cursor for select ID from @LOCATIONLIST;
            open crsSELECTED;
            fetch next from crsSELECTED into @SELECTEDID;

            while @@FETCH_STATUS = 0
                begin
                    while @WORKINGDATE <= @ENDDATE
                        begin
                            if not exists (select top(1) LU.STARTDATE from @LOCATIONUSAGE LU where  LU.LOCATIONID = @SELECTEDID and LU.STARTDATE = @WORKINGDATE)
                                begin
                                    set @AVAILFROM = '00:00:00';
                                    set    @AVAILTO = '23:59:59';
                                    insert into @LOCATIONAVAILABILIY (
                                        [DATE],
                                        [LOCATIONID],
                                        [LOCATION],
                                        [EVENTCAPACITY],
                                        [LOCATIONCAPACITY],
                                        [AVAILFROM],
                                        [AVAILTO]
                                    )
                                    select 
                                        @WORKINGDATE,
                                        el.ID,
                                        el.NAME,
                                        e.CAPACITY, 
                                        el.CAPACITY,
                                        @AVAILFROM,
                                        @AVAILTO
                                    from DBO.EVENTLOCATION el
                                        inner join @LOCATIONLIST ll on el.ID = ll.ID
                                        left join dbo.EVENT e on e.EVENTLOCATIONID = el.ID

                                end;
                            else
                                begin
                                    declare crsLOCAVAIL cursor for
                                        select 
                                            LOCATION,
                                            LOCATIONID,
                                            STARTDATE,
                                            ENDDATE,
                                            STARTTIME,
                                            ENDTIME,
                                            EVENTCAPACITY,
                                            LOCATIONCAPACITY  
                                        from @LOCATIONUSAGE 
                                        where STARTDATE = @WORKINGDATE;

                                    open crsLOCAVAIL;
                                    fetch next from crsLOCAVAIL into @LOC, @LOCID, @STARTD, @ENDD, @STARTT, @ENDT, @EVENTCAP, @LOCATIONCAP;    
                                    while @@FETCH_STATUS = 0
                                        begin
                                            --set flag when a new location is encountered
                                            if @LASTLOCATIONID <> @LOCID and @LASTLOCATIONID is not null  
                                                begin 
                                                    set @NEWLOCATION = 1
                                                end;
                                            else 
                                                begin 
                                                    set @NEWLOCATION = 0;
                                                end;

                                            --set flag for same date different times for the same location
                                            if (@LASTSTARTDATE = @STARTD and  @NEWLOCATION = 0) or @LASTSTARTDATE is null  
                                                begin 
                                                    set @NEWDATE = 0;
                                                end
                                            else 
                                                begin 
                                                    set @NEWDATE = 1;
                                                end;        


                                            if (@NEWLOCATION = 1 or @NEWDATE = 1) and @LASTENDDATE is not null
                                                begin
                                                    set @LASTLOCATION = (select EL.NAME from DBO.EVENTLOCATION EL where EL.ID = @LASTLOCATIONID);
                                                    set @AVAILFROM = @LASTENDTIME;
                                                    set    @AVAILTO = '23:59:59';

                                                    --only insert if location bookings are not back to back
                                                    if @AVAILFROM <> @AVAILTO
                                                        begin
                                                            insert into @LOCATIONAVAILABILIY (
                                                                [DATE],
                                                                [LOCATIONID],
                                                                [LOCATION],
                                                                [EVENTCAPACITY],
                                                                [LOCATIONCAPACITY],
                                                                [AVAILFROM],
                                                                [AVAILTO]
                                                            )
                                                            select 
                                                                @LASTENDDATE
                                                                @LASTLOCATIONID
                                                                @LASTLOCATION
                                                                @LASTEVENTCAP
                                                                @LASTLOCATIONCAP
                                                                @AVAILFROM
                                                                @AVAILTO;    
                                                        end;
                                                end;        

                                            if @STARTT >= '00:00:00' and @NEWDATE = 1 
                                                begin 
                                                    set @AVAILFROM='00:00:00';
                                                end;

                                            if @LASTLOCATIONID = @LOCID and @STARTD = @LASTSTARTDATE
                                                begin
                                                    set @AVAILFROM = @LASTENDTIME;
                                                end;

                                            set @AVAILTO = @STARTT;
                                            set @LASTENDTIME = @ENDT;
                                            set @LASTSTARTDATE = @STARTD;
                                            set @LASTENDDATE = @ENDD;
                                            set @LASTEVENTCAP = @EVENTCAP
                                            set @LASTLOCATIONCAP = @LOCATIONCAP;

                                            --only insert if location bookings are not back to back
                                            if @AVAILFROM <> @AVAILTO 
                                                begin 
                                                    insert into @LOCATIONAVAILABILIY (
                                                        [DATE],
                                                        [LOCATIONID],
                                                        [LOCATION],
                                                        [EVENTCAPACITY],
                                                        [LOCATIONCAPACITY],
                                                        [AVAILFROM],
                                                        [AVAILTO]
                                                    )
                                                    select 
                                                        @STARTD,
                                                        @LOCID,
                                                        @LOC,
                                                        @EVENTCAP,
                                                        @LOCATIONCAP,
                                                        @AVAILFROM,
                                                        @AVAILTO;
                                                end;

                                            set @LASTLOCATIONID = @LOCID;

                                            fetch next from crsLOCAVAIL into @LOC, @LOCID, @STARTD, @ENDD, @STARTT, @ENDT, @EVENTCAP, @LOCATIONCAP;

                                            if @@FETCH_STATUS = -1 
                                                begin
                                                    --last row was just processed so need to insert availability from last end time to 11:59
                                                    set @LASTLOCATION = (select EL.NAME from DBO.EVENTLOCATION EL where EL.ID = @LASTLOCATIONID);
                                                    set @AVAILFROM = @LASTENDTIME;
                                                    set    @AVAILTO = '23:59:59';

                                                    --only insert if location bookings are not back to back
                                                    if @AVAILFROM <> @AVAILTO
                                                        begin
                                                            insert into @LOCATIONAVAILABILIY (
                                                                [DATE],
                                                                [LOCATIONID],
                                                                [LOCATION],
                                                                [EVENTCAPACITY],
                                                                [LOCATIONCAPACITY],
                                                                [AVAILFROM],
                                                                [AVAILTO]
                                                            )
                                                            select 
                                                                @LASTENDDATE,
                                                                @LASTLOCATIONID,
                                                                @LASTLOCATION,
                                                                @LASTEVENTCAP,
                                                                @LASTLOCATIONCAP,
                                                                @AVAILFROM,
                                                                @AVAILTO;        
                                                        end;
                                                end;
                                        end;
                                    close crsLOCAVAIL;
                                    deallocate crsLOCAVAIL;
                                end;

                            set @WORKINGDATE = DATEADD(day, 1, @WORKINGDATE);
                        end;

                        declare @LASTSELECTEDID uniqueidentifier;
                        set @LASTSELECTEDID = @SELECTEDID;

                        fetch next from crsSELECTED into @SELECTEDID;
                        if @LASTSELECTEDID <> @SELECTEDID 
                            begin 
                                set @WORKINGDATE = @STARTDATE;
                            end;
                end;

            close crsSELECTED;
            deallocate crsSELECTED;
        end;

if @AVAIL_UNAVAIL = 0 
    begin
        select 
            la.LOCATION [LOCATION],
            ''  [PROGRAMNAME],
            la.[DATE] [DATE],
            la.AVAILFROM [STARTTIME],
            min(la.AVAILTO) [ENDTIME],
            0 [USED],
            max(la.LOCATIONCAPACITY) [AVAILABLE],
            max(la.EVENTCAPACITY) [EVENTCAPACTIY],
            max(la.LOCATIONCAPACITY) [LOCATIONCAPACITY]
        from @LOCATIONAVAILABILIY la
        group by 
            la.LOCATIONID,
            la.LOCATION,
            la.[DATE],
            la.AVAILFROM
        order by 
            [LOCATION],
            [DATE],
            [STARTTIME];
    end;

else if @AVAIL_UNAVAIL = 1
    begin
        select
            lu.LOCATION [LOCATION],
            lu.PROGRAM [PROGRAMNAME],
            lu.STARTDATE,
            lu.STARTTIME,
            lu.ENDTIME,
            lu.QUANTITY [USED],
            case 
                when lu.QUANTITY > lu.EVENTCAPACITY then 0 
                else lu.EVENTCAPACITY - lu.QUANTITY
            end [AVAILABLE],
            lu.EVENTCAPACITY [EVENTCAPACITY],
            lu.LOCATIONCAPACITY [LOCATIONCAPACITY]
        from @LOCATIONUSAGE lu
        order by 
            [LOCATION],
            [STARTDATE],
            [STARTTIME];
    end;