USP_ITINERARY_INSERTITEMS
Attempts to clear an itinerary and insert new itinerary items.
Parameters
Parameter | Parameter Type | Mode | Description |
---|---|---|---|
@ID | uniqueidentifier | IN | |
@ITINERARYITEMS | xml | IN | |
@CHANGEAGENTID | uniqueidentifier | IN | |
@CLEAREXISTINGITEMS | bit | IN |
Definition
Copy
CREATE procedure dbo.USP_ITINERARY_INSERTITEMS
(
@ID uniqueidentifier,
@ITINERARYITEMS xml,
@CHANGEAGENTID uniqueidentifier = null,
@CLEAREXISTINGITEMS bit = 1
)
as
begin
declare @CURRENTDATE datetime;
set @CURRENTDATE = getdate();
if @CHANGEAGENTID is null
exec dbo.USP_CHANGEAGENT_GETORCREATECHANGEAGENT @CHANGEAGENTID output
declare @RESERVATIONID uniqueidentifier
select @RESERVATIONID = RESERVATIONID
from dbo.ITINERARY where ID = @ID
declare @ITEMS table
(
ID uniqueidentifier,
COPYITINERARYITEMID uniqueidentifier,
TRACKITEMID uniqueidentifier,
EVENTID uniqueidentifier,
PROGRAMID uniqueidentifier,
NAME nvarchar(100),
NOTES nvarchar(500),
BLOCKEVENT bit,
STARTTIME dbo.UDT_HOURMINUTE,
ENDTIME dbo.UDT_HOURMINUTE,
STARTDATE datetime,
ENDDATE datetime,
EVENTLOCATIONID uniqueidentifier,
ITEMTYPECODE tinyint,
INVALIDREASON tinyint,
STARTDATETIME datetime,
ENDDATETIME datetime
)
insert into @ITEMS
(
ID,
COPYITINERARYITEMID,
TRACKITEMID,
EVENTID,
PROGRAMID,
NAME,
NOTES,
BLOCKEVENT,
STARTTIME,
ENDTIME,
STARTDATE,
ENDDATE,
EVENTLOCATIONID,
ITEMTYPECODE,
INVALIDREASON
)
select
newid(),
T.items.value('(COPYITINERARYITEMID)[1]','uniqueidentifier'),
T.items.value('(TRACKITEMID)[1]','uniqueidentifier'),
T.items.value('(EVENTID)[1]','uniqueidentifier'),
T.items.value('(PROGRAMID)[1]','uniqueidentifier'),
T.items.value('(NAME)[1]','nvarchar(100)'),
T.items.value('(NOTES)[1]','nvarchar(500)'),
T.items.value('(BLOCKEVENT)[1]','bit'),
T.items.value('(STARTTIME)[1]','dbo.UDT_HOURMINUTE'),
T.items.value('(ENDTIME)[1]','dbo.UDT_HOURMINUTE'),
T.items.value('(STARTDATE)[1]','date'),
T.items.value('(ENDDATE)[1]','date'),
T.items.value('(EVENTLOCATIONID)[1]','uniqueidentifier'),
T.items.value('(ITEMTYPECODE)[1]','tinyint'),
0
from @ITINERARYITEMS.nodes('/ITINERARYITEMS/ITEM') T(items)
update @ITEMS set
STARTDATETIME = dbo.UFN_DATE_ADDHOURMINUTE([@ITEMS].STARTDATE,[@ITEMS].STARTTIME),
ENDDATETIME = dbo.UFN_DATE_ADDHOURMINUTE([@ITEMS].ENDDATE,[@ITEMS].ENDTIME)
-- Get the total number of people in the itinerary
declare @QUANTITY int
select @QUANTITY = isnull(sum(QUANTITY),0)
from dbo.ITINERARYATTENDEE
where ITINERARYID = @ID
declare @VALIDEVENTSFORITEMTIME table
(
EVENTID uniqueidentifier,
ITEMID uniqueidentifier,
QUANTITY int
)
insert into @VALIDEVENTSFORITEMTIME
select
EVENT.ID,
ITEMS.ID,
EVENTAVAILABILITY.QUANTITY
from dbo.EVENT
inner join @ITEMS ITEMS on ITEMS.PROGRAMID = EVENT.PROGRAMID
inner join dbo.UFN_EVENT_GETAVAILABILITYWITHEVENTS() as EVENTAVAILABILITY on EVENTAVAILABILITY.EVENTID = EVENT.ID
where
(
ITEMS.STARTDATETIME >= EVENT.STARTDATETIME and
ITEMS.STARTDATETIME < EVENT.ENDDATETIME
) or
(
ITEMS.ENDDATETIME > EVENT.STARTDATETIME and
ITEMS.ENDDATETIME <= EVENT.ENDDATETIME
) or
(
ITEMS.STARTDATETIME < EVENT.STARTDATETIME and
ITEMS.ENDDATETIME > EVENT.ENDDATETIME
)
-- Get valid events for the date of this itinerary
update @ITEMS set
EVENTID = EVENT.ID,
PROGRAMID = null
from dbo.EVENT
inner join dbo.PROGRAM on
EVENT.PROGRAMID = PROGRAM.ID
inner join @VALIDEVENTSFORITEMTIME as VALIDEVENTS on VALIDEVENTS.EVENTID = EVENT.ID
inner join dbo.UFN_EVENT_GETONSALEINFOWITHEVENTS() EVENTONSALE on
EVENTONSALE.EVENTID = EVENT.ID
where
[@ITEMS].ITEMTYPECODE = 0 and
[@ITEMS].PROGRAMID = PROGRAM.ID and
PROGRAM.ISACTIVE = 1 and
EVENT.ISACTIVE = 1 and
[@ITEMS].ID = VALIDEVENTS.ITEMID and
VALIDEVENTS.QUANTITY >= @QUANTITY and
not exists (select 1
from dbo.ITINERARYITEM with (nolock)
inner join dbo.ITINERARY on ITINERARY.ID = ITINERARYITEM.ITINERARYID
inner join dbo.SALESORDER on ITINERARY.RESERVATIONID = SALESORDER.ID
where SALESORDER.STATUSCODE <> 5 -- MDC - Ignore cancelled
and ITINERARYITEM.BLOCKEVENT = 1
and ITINERARYITEM.EVENTID = EVENT.ID) and
not exists
(
select 1 from dbo.ITINERARYATTENDEE
where
ITINERARYID = @ID and
not exists
(
select 1 from dbo.PROGRAMEVENTPRICE
where PROGRAMEVENTPRICE.EVENTID = EVENT.ID and
PROGRAMEVENTPRICE.PRICETYPECODEID = ITINERARYATTENDEE.PRICETYPECODEID
)
and
not exists
(
select 1 from dbo.PROGRAMPRICE
where
PROGRAMPRICE.PROGRAMID = PROGRAM.ID and
ITINERARYATTENDEE.PRICETYPECODEID = PROGRAMPRICE.PRICETYPECODEID and
not exists
(
select 1 from dbo.PROGRAMEVENTPRICE
where PROGRAMEVENTPRICE.EVENTID = EVENT.ID
)
)
) and
(
EVENTONSALE.SALESMETHODTYPECODE = 3 and
@CURRENTDATE >= EVENTONSALE.ONSALEDATETIME
)
-- Remove events that do not have a valid time
update @ITEMS set
ITEMTYPECODE = 3
where
ITEMTYPECODE = 0 and
EVENTID is null
-- Retrieve reasons why the event is invalid for invalid items
-- Validate items on all other reasons and remove on condition to narrow
-- the reason why an event is invalid.
-- Once we remove a condition, that condition can remain removed
-- because it is no longer needed to check against whether an item is invalid
if exists (select 1 from @ITEMS where ITEMTYPECODE = 3)
begin
-- No events at the time of the item
update @ITEMS set
INVALIDREASON = 5
where
[@ITEMS].ITEMTYPECODE = 3 and
not exists
(
select 1 from @VALIDEVENTSFORITEMTIME
where [@VALIDEVENTSFORITEMTIME].ITEMID = [@ITEMS].ID
)
-- Invalid price types, because all other validation passed
update @ITEMS set
INVALIDREASON = 4
from dbo.EVENT
inner join dbo.PROGRAM on
EVENT.PROGRAMID = PROGRAM.ID
inner join @VALIDEVENTSFORITEMTIME as VALIDEVENTS on VALIDEVENTS.EVENTID = EVENT.ID
inner join dbo.UFN_EVENT_GETONSALEINFOWITHEVENTS() EVENTONSALE on
EVENTONSALE.EVENTID = EVENT.ID
where
[@ITEMS].ITEMTYPECODE = 3 and
[@ITEMS].INVALIDREASON = 0 and
[@ITEMS].PROGRAMID = PROGRAM.ID and
PROGRAM.ISACTIVE = 1 and
EVENT.ISACTIVE = 1 and
[@ITEMS].ID = VALIDEVENTS.ITEMID and
VALIDEVENTS.QUANTITY >= @QUANTITY and
not exists (select 1 from dbo.ITINERARYITEM with (nolock) where ITINERARYITEM.BLOCKEVENT = 1 and ITINERARYITEM.EVENTID = EVENT.ID) and
(
EVENTONSALE.SALESMETHODTYPECODE = 3 and
@CURRENTDATE >= EVENTONSALE.ONSALEDATETIME
)
-- Event is blocked, because all other validation passed
update @ITEMS set
INVALIDREASON = 3
from dbo.EVENT
inner join dbo.PROGRAM on
EVENT.PROGRAMID = PROGRAM.ID
inner join @VALIDEVENTSFORITEMTIME as VALIDEVENTS on VALIDEVENTS.EVENTID = EVENT.ID
inner join dbo.UFN_EVENT_GETONSALEINFOWITHEVENTS() EVENTONSALE on
EVENTONSALE.EVENTID = EVENT.ID
where
[@ITEMS].ITEMTYPECODE = 3 and
[@ITEMS].INVALIDREASON = 0 and
[@ITEMS].PROGRAMID = PROGRAM.ID and
PROGRAM.ISACTIVE = 1 and
EVENT.ISACTIVE = 1 and
[@ITEMS].ID = VALIDEVENTS.ITEMID and
VALIDEVENTS.QUANTITY >= @QUANTITY and
(
EVENTONSALE.SALESMETHODTYPECODE = 3 and
@CURRENTDATE >= EVENTONSALE.ONSALEDATETIME
)
-- Invalid quantity, because all other validation passed
update @ITEMS set
INVALIDREASON = 2
from dbo.EVENT
inner join dbo.PROGRAM on
EVENT.PROGRAMID = PROGRAM.ID
inner join @VALIDEVENTSFORITEMTIME as VALIDEVENTS on VALIDEVENTS.EVENTID = EVENT.ID
inner join dbo.UFN_EVENT_GETONSALEINFOWITHEVENTS() EVENTONSALE on
EVENTONSALE.EVENTID = EVENT.ID
where
[@ITEMS].ITEMTYPECODE = 3 and
[@ITEMS].INVALIDREASON = 0 and
[@ITEMS].PROGRAMID = PROGRAM.ID and
PROGRAM.ISACTIVE = 1 and
EVENT.ISACTIVE = 1 and
[@ITEMS].ID = VALIDEVENTS.ITEMID and
VALIDEVENTS.QUANTITY < @QUANTITY and
(
EVENTONSALE.SALESMETHODTYPECODE = 3 and
@CURRENTDATE >= EVENTONSALE.ONSALEDATETIME
)
-- Event is not on sale
update @ITEMS set
INVALIDREASON = 8
from dbo.EVENT
inner join dbo.PROGRAM on
EVENT.PROGRAMID = PROGRAM.ID
inner join @VALIDEVENTSFORITEMTIME as VALIDEVENTS on VALIDEVENTS.EVENTID = EVENT.ID
where
[@ITEMS].ITEMTYPECODE = 3 and
[@ITEMS].INVALIDREASON = 0 and
[@ITEMS].PROGRAMID = PROGRAM.ID and
PROGRAM.ISACTIVE = 1 and
EVENT.ISACTIVE = 1 and
[@ITEMS].ID = VALIDEVENTS.ITEMID
-- Inactive program/event, because all other validation passed
update @ITEMS set
INVALIDREASON = 1
from dbo.EVENT
inner join dbo.PROGRAM on
EVENT.PROGRAMID = PROGRAM.ID
inner join @VALIDEVENTSFORITEMTIME as VALIDEVENTS on VALIDEVENTS.EVENTID = EVENT.ID
where
[@ITEMS].ITEMTYPECODE = 3 and
[@ITEMS].INVALIDREASON = 0 and
[@ITEMS].PROGRAMID = PROGRAM.ID and
[@ITEMS].ID = VALIDEVENTS.ITEMID
end
-- Remove inactive daily admission programs
update @ITEMS set
ITEMTYPECODE = 3,
INVALIDREASON = 6
from dbo.PROGRAM
where
[@ITEMS].ITEMTYPECODE = 1 and
[@ITEMS].PROGRAMID = PROGRAM.ID and
PROGRAM.ISACTIVE = 0
-- Remove daily admission programs that are not on sale
update @ITEMS set
ITEMTYPECODE = 3,
INVALIDREASON = 9
where
ITEMTYPECODE = 1 and
dbo.UFN_PROGRAMDAILYADMISSION_ISONSALE(PROGRAMID,@CURRENTDATE,3) = 0
-- Remove blocks on items/locations that cannot block
update @ITEMS set
BLOCKEVENT = 0
where
(
[@ITEMS].BLOCKEVENT = 1 and
[@ITEMS].ITEMTYPECODE = 0 and
exists (select 1 from dbo.ITINERARYITEM with (nolock) where ITINERARYITEM.EVENTID = [@ITEMS].EVENTID)
)
or
(
[@ITEMS].ITEMTYPECODE = 2 and
dbo.UFN_ITINERARYITEM_CANBLOCK([@ITEMS].EVENTLOCATIONID,[@ITEMS].STARTDATE,[@ITEMS].ENDDATE,[@ITEMS].STARTTIME,[@ITEMS].ENDTIME) = 0
)
-- Remove programs that don't have price types that are in the itinerary
update @ITEMS set
ITEMTYPECODE = 3,
INVALIDREASON = 11
from dbo.ITINERARYATTENDEE
where
ITINERARYID = @ID and
ITEMTYPECODE = 1 and
not exists
(select 1 from dbo.PROGRAMPRICE
where PROGRAMPRICE.PROGRAMID = [@ITEMS].PROGRAMID and
ITINERARYATTENDEE.PRICETYPECODEID = PROGRAMPRICE.PRICETYPECODEID)
-- Get name for events that are now scheduled
update @ITEMS set
NAME = dbo.UFN_TRANSLATIONFUNCTION_EVENT_GETNAME(EVENTID)
where
ITEMTYPECODE = 0 or
(
ITEMTYPECODE = 3 and
EVENTID is not null
)
-- Before we insert items, update Reservation Arrival Time
-- to be the earliest item in the itinerary
declare @RESERVATIONARRIVALDATE date
declare @RESERVATIONARRIVALTIME dbo.UDT_HOURMINUTE
select
@RESERVATIONARRIVALDATE = ARRIVALDATE,
@RESERVATIONARRIVALTIME = ARRIVALTIME
from dbo.RESERVATION
where
ID = @RESERVATIONID
if @RESERVATIONARRIVALDATE is not null and @RESERVATIONARRIVALTIME is not null
begin
declare @MINITINERARYDATE date
declare @MINITINERARYTIME dbo.UDT_HOURMINUTE
select @MINITINERARYDATE = min([@ITEMS].STARTDATE)
from @ITEMS
select @MINITINERARYTIME = min([@ITEMS].STARTTIME)
from @ITEMS
where [@ITEMS].STARTDATE = @MINITINERARYDATE
if @RESERVATIONARRIVALDATE = @MINITINERARYDATE and @RESERVATIONARRIVALTIME > @MINITINERARYTIME
begin
update dbo.RESERVATION set
ARRIVALTIME = @MINITINERARYTIME,
CHANGEDBYID = @CHANGEAGENTID,
DATECHANGED = @CURRENTDATE
where ID = @RESERVATIONID
end
end
-- Now add charged locations
declare @ITINERARYITEMLOCATIONS table
(
ITINERARYITEMID uniqueidentifier,
EVENTLOCATIONID uniqueidentifier,
PRICE money,
SALESORDERITEMID uniqueidentifier,
NAME nvarchar(100)
)
insert into @ITINERARYITEMLOCATIONS
(
ITINERARYITEMID,
EVENTLOCATIONID,
PRICE,
SALESORDERITEMID,
NAME
)
select
ITEMS.ID,
ITEMS.EVENTLOCATIONID,
[SALESORDERITEM].[TOTAL],
newid(),
ITEMS.NAME
from @ITEMS ITEMS
inner join dbo.ITINERARYITEMLOCATION on
ITEMS.COPYITINERARYITEMID = ITINERARYITEMLOCATION.ID
inner join dbo.SALESORDERITEM on
SALESORDERITEM.ID = ITINERARYITEMLOCATION.SALESORDERITEMID
-- Now add track items that have locations that have a default price
insert into @ITINERARYITEMLOCATIONS
(
ITINERARYITEMID,
EVENTLOCATIONID,
PRICE,
SALESORDERITEMID,
NAME
)
select
ITEMS.ID,
ITEMS.EVENTLOCATIONID,
FACILITY.PRICE,
newid(),
ITEMS.NAME
from @ITEMS ITEMS
inner join dbo.FACILITY on
ITEMS.EVENTLOCATIONID = FACILITY.ID
where
ITEMS.COPYITINERARYITEMID is null
-- insert new itinerary items
insert into dbo.ITINERARYITEM
(
ID,
EVENTID,
PROGRAMID,
NAME,
NOTES,
STARTTIME,
ENDTIME,
STARTDATE,
ENDDATE,
BLOCKEVENT,
EVENTLOCATIONID,
ITEMTYPECODE,
INVALIDREASONCODE,
ITINERARYID,
ADDEDBYID, CHANGEDBYID, DATEADDED, DATECHANGED
)
select
ID,
EVENTID,
PROGRAMID,
NAME,
NOTES,
STARTTIME,
ENDTIME,
STARTDATE,
ENDDATE,
BLOCKEVENT,
EVENTLOCATIONID,
ITEMTYPECODE,
INVALIDREASON,
@ID,
@CHANGEAGENTID, @CHANGEAGENTID, @CURRENTDATE, @CURRENTDATE
from @ITEMS
-- Now add the itinerary item resources
-- First from tracks
insert into dbo.ITINERARYITEMRESOURCE
(
ITINERARYITEMID,
RESOURCEID,
QUANTITYNEEDED,
PRICE,
PRICINGSTRUCTURECODE,
PERTICKETQUANTITY,
PERTICKETDIVISOR,
ADDEDBYID, CHANGEDBYID, DATEADDED, DATECHANGED
)
select
ITEMS.ID,
TRACKITEMRESOURCE.RESOURCEID,
TRACKITEMRESOURCE.QUANTITYNEEDED,
COALESCE(RESOURCEPRICING.PRICE, 0),
COALESCE(RESOURCEPRICING.PRICINGSTRUCTURECODE,0),
PERTICKETQUANTITY = RESOURCE.PERTICKETQUANTITY,
PERTICKETDIVISOR = RESOURCE.PERTICKETDIVISOR,
@CHANGEAGENTID, @CHANGEAGENTID, @CURRENTDATE, @CURRENTDATE
from @ITEMS as ITEMS
inner join TRACKITEMRESOURCE on ITEMS.TRACKITEMID = TRACKITEMRESOURCE.TRACKITEMID
inner join RESOURCE on TRACKITEMRESOURCE.RESOURCEID = RESOURCE.ID
left join dbo.RESOURCEPRICING on RESOURCE.ID = RESOURCEPRICING.ID;
-- Second from itinerary items
insert into dbo.ITINERARYITEMRESOURCE
(
ITINERARYITEMID,
RESOURCEID,
QUANTITYNEEDED,
PRICE,
PRICINGSTRUCTURECODE,
PERTICKETQUANTITY,
PERTICKETDIVISOR,
ADDEDBYID, CHANGEDBYID, DATEADDED, DATECHANGED
)
select
ITEMS.ID,
ITINERARYITEMRESOURCE.RESOURCEID,
ITINERARYITEMRESOURCE.QUANTITYNEEDED,
COALESCE(RESOURCEPRICING.PRICE, 0),
COALESCE(RESOURCEPRICING.PRICINGSTRUCTURECODE,0),
PERTICKETQUANTITY = RESOURCE.PERTICKETQUANTITY,
PERTICKETDIVISOR = RESOURCE.PERTICKETDIVISOR,
@CHANGEAGENTID, @CHANGEAGENTID, @CURRENTDATE, @CURRENTDATE
from @ITEMS as ITEMS
inner join ITINERARYITEMRESOURCE on ITEMS.COPYITINERARYITEMID = ITINERARYITEMRESOURCE.ITINERARYITEMID
inner join RESOURCE on ITINERARYITEMRESOURCE.RESOURCEID = RESOURCE.ID
left join dbo.RESOURCEPRICING on RESOURCE.ID = RESOURCEPRICING.ID;
-- Now add staff resources
-- First create jobs for any of the track items that do not have a job associated.
-- Create a map table so we can set the job ids on the track items as well
declare @JOBMAP table
(
TRACKITEMSTAFFRESOURCEID uniqueidentifier,
JOBID uniqueidentifier,
JOBNAME nvarchar(100),
JOBDESCRIPTION nvarchar(255),
VOLUNTEERTYPEID uniqueidentifier,
FILLEDBYCODE tinyint
);
insert into @JOBMAP
(TRACKITEMSTAFFRESOURCEID, JOBNAME, JOBDESCRIPTION, VOLUNTEERTYPEID, FILLEDBYCODE)
select
TRACKITEMSTAFFRESOURCE.ID,
TRACKITEMSTAFFRESOURCE.JOBNAME,
TRACKITEMSTAFFRESOURCE.JOBDESCRIPTION,
TRACKITEMSTAFFRESOURCE.VOLUNTEERTYPEID,
TRACKITEMSTAFFRESOURCE.FILLEDBYCODE
from @ITEMS as ITEMS
inner join TRACKITEMSTAFFRESOURCE on ITEMS.TRACKITEMID = TRACKITEMSTAFFRESOURCE.TRACKITEMID
where
TRACKITEMSTAFFRESOURCE.JOBID is null and
TRACKITEMSTAFFRESOURCE.FILLEDBYCODE = 0;
-- update the ids with any existing jobs
update @JOBMAP set
JOBID = JOB.ID
from dbo.JOB
inner join @JOBMAP as STAFFRESOURCESTABLE on
STAFFRESOURCESTABLE.JOBNAME = JOB.NAME and
STAFFRESOURCESTABLE.VOLUNTEERTYPEID = JOB.VOLUNTEERTYPEID
where
(JOBID is null or JOBID = '00000000-0000-0000-0000-000000000000') and
FILLEDBYCODE = 0
-- Finally check that there is only one new job that is going to be created per job name and volunteer type combo
update @JOBMAP set
JOBDESCRIPTION = TOPJOBNAME.JOBDESCRIPTION
from @JOBMAP as STAFFRESOURCESTABLE
inner join
(
select
DISTINCTJOBDESCRIPTION.JOBNAME,
DISTINCTJOBDESCRIPTION.VOLUNTEERTYPEID,
(
select top 1 TOPJOBDESCRIPTION.JOBDESCRIPTION
from @JOBMAP as TOPJOBDESCRIPTION
where
TOPJOBDESCRIPTION.JOBNAME = DISTINCTJOBDESCRIPTION.JOBNAME and
TOPJOBDESCRIPTION.VOLUNTEERTYPEID = DISTINCTJOBDESCRIPTION.VOLUNTEERTYPEID
) as JOBDESCRIPTION
from @JOBMAP as DISTINCTJOBDESCRIPTION
) as TOPJOBNAME on
TOPJOBNAME.JOBNAME = STAFFRESOURCESTABLE.JOBNAME and
TOPJOBNAME.VOLUNTEERTYPEID = STAFFRESOURCESTABLE.VOLUNTEERTYPEID
where
(STAFFRESOURCESTABLE.JOBID is null or STAFFRESOURCESTABLE.JOBID = '00000000-0000-0000-0000-000000000000') and
STAFFRESOURCESTABLE.FILLEDBYCODE = 0
declare @DISTINCTJOB table
(
JOBID uniqueidentifier,
JOBNAME nvarchar(100),
JOBDESCRIPTION nvarchar(255)
);
insert into @DISTINCTJOB (JOBNAME, JOBDESCRIPTION)
select distinct
JOBNAME,
JOBDESCRIPTION
from @JOBMAP as STAFFRESOURCESTABLE
where
(STAFFRESOURCESTABLE.JOBID is null or STAFFRESOURCESTABLE.JOBID = '00000000-0000-0000-0000-000000000000') and
STAFFRESOURCESTABLE.FILLEDBYCODE = 0
update @DISTINCTJOB set JOBID = NEWID();
update @JOBMAP set
JOBID = DISTINCTJOB.JOBID
from @JOBMAP as STAFFRESOURCESTABLE
inner join @DISTINCTJOB as DISTINCTJOB on
STAFFRESOURCESTABLE.JOBNAME = DISTINCTJOB.JOBNAME and
STAFFRESOURCESTABLE.JOBDESCRIPTION = DISTINCTJOB.JOBDESCRIPTION;
-- Create the jobs.
-- Left outer join on Job is to make sure JOBID is not already an existing job.
insert into dbo.JOB
(
ID,
NAME,
DESCRIPTION,
VOLUNTEERTYPEID,
ADDEDBYID, CHANGEDBYID, DATEADDED, DATECHANGED
)
select distinct
JOBMAP.JOBID,
JOBMAP.JOBNAME,
JOBMAP.JOBDESCRIPTION,
JOBMAP.VOLUNTEERTYPEID,
@CHANGEAGENTID, @CHANGEAGENTID, @CURRENTDATE, @CURRENTDATE
from @JOBMAP as JOBMAP
left outer join dbo.JOB on JOBMAP.JOBID = JOB.ID
where
JOB.ID is null and
JOBMAP.FILLEDBYCODE = 0
-- Update the track item staff resources to have the correct jobs
update dbo.TRACKITEMSTAFFRESOURCE set
JOBID = JOBMAP.JOBID,
JOBNAME = JOB.NAME,
JOBDESCRIPTION = JOB.DESCRIPTION,
CHANGEDBYID = @CHANGEAGENTID,
DATECHANGED = @CURRENTDATE
from @JOBMAP as JOBMAP
inner join dbo.JOB on JOBMAP.JOBID = JOB.ID
where JOBMAP.TRACKITEMSTAFFRESOURCEID = TRACKITEMSTAFFRESOURCE.ID
/* Get the total attendees for the itinerary */
declare @ATTENDEECOUNT decimal;
select
@ATTENDEECOUNT = sum(ITINERARYATTENDEE.QUANTITY)
from dbo.ITINERARYATTENDEE
where ITINERARYATTENDEE.ITINERARYID = @ID
/* Now that all track items have a job create the itinerary item staff resources */
insert into dbo.ITINERARYITEMSTAFFRESOURCE
(
ITINERARYITEMID,
VOLUNTEERTYPEID,
QUANTITYNEEDED,
JOBID,
FILLEDBYCODE,
PRICE,
PRICINGSTRUCTURECODE,
ADDEDBYID, CHANGEDBYID, DATEADDED, DATECHANGED
)
select
ITEMS.ID,
TRACKITEMSTAFFRESOURCE.VOLUNTEERTYPEID,
case
when VOLUNTEERTYPE.CAPACITYPERRESOURCE > 0 then
ceiling(@ATTENDEECOUNT / VOLUNTEERTYPE.CAPACITYPERRESOURCE)
else TRACKITEMSTAFFRESOURCE.QUANTITYNEEDED
end,
TRACKITEMSTAFFRESOURCE.JOBID,
TRACKITEMSTAFFRESOURCE.FILLEDBYCODE,
COALESCE(VOLUNTEERTYPEPRICING.PRICE, 0),
COALESCE(VOLUNTEERTYPEPRICING.PRICINGSTRUCTURECODE,0),
@CHANGEAGENTID, @CHANGEAGENTID, @CURRENTDATE, @CURRENTDATE
from @ITEMS as ITEMS
inner join TRACKITEMSTAFFRESOURCE on
ITEMS.TRACKITEMID = TRACKITEMSTAFFRESOURCE.TRACKITEMID
left join dbo.VOLUNTEERTYPEPRICING on
TRACKITEMSTAFFRESOURCE.VOLUNTEERTYPEID = VOLUNTEERTYPEPRICING.ID
inner join dbo.VOLUNTEERTYPE on
TRACKITEMSTAFFRESOURCE.VOLUNTEERTYPEID = VOLUNTEERTYPE.ID;
/* Second from itinerary items, these always have jobs associated with them */
insert into dbo.ITINERARYITEMSTAFFRESOURCE
(
ITINERARYITEMID,
VOLUNTEERTYPEID,
QUANTITYNEEDED,
JOBID,
FILLEDBYCODE,
PRICE,
PRICINGSTRUCTURECODE,
ADDEDBYID, CHANGEDBYID, DATEADDED, DATECHANGED
)
select
ITEMS.ID,
ITINERARYITEMSTAFFRESOURCE.VOLUNTEERTYPEID,
case when VOLUNTEERTYPE.CAPACITYPERRESOURCE > 0 then ceiling(@ATTENDEECOUNT / VOLUNTEERTYPE.CAPACITYPERRESOURCE) else ITINERARYITEMSTAFFRESOURCE.QUANTITYNEEDED end,
ITINERARYITEMSTAFFRESOURCE.JOBID,
ITINERARYITEMSTAFFRESOURCE.FILLEDBYCODE,
COALESCE(VOLUNTEERTYPEPRICING.PRICE, 0),
COALESCE(VOLUNTEERTYPEPRICING.PRICINGSTRUCTURECODE,0),
@CHANGEAGENTID, @CHANGEAGENTID, @CURRENTDATE, @CURRENTDATE
from @ITEMS as ITEMS
inner join ITINERARYITEMSTAFFRESOURCE on ITEMS.COPYITINERARYITEMID = ITINERARYITEMSTAFFRESOURCE.ITINERARYITEMID
left join dbo.VOLUNTEERTYPEPRICING on ITINERARYITEMSTAFFRESOURCE.VOLUNTEERTYPEID = VOLUNTEERTYPEPRICING.ID
inner join dbo.VOLUNTEERTYPE on ITINERARYITEMSTAFFRESOURCE.VOLUNTEERTYPEID = VOLUNTEERTYPE.ID
-- JLM 3/1/2012 : WI 125730
/*
With a large number of events in the system, conflict checking
causes a significant loss in performance. This is due to the
fact that we are calling 3 separate scalar functions per entry
in @ITEMS to check for conflicts that each query the entire
event table for conflicts. If we filter the events such that we
only check events that fall into the applicable time frame, we
gain much of that performance back since we no longer have to do
6 datetime comparisons per event, per function, per @ITEM.
We send in this smaller set of events so that the costly comparisons
in the scalar functions are only done on events that could possibly
conflict.
I had to choose between sending in XML and populating a persisted table
(can't use # type temp tables in a function), and the performance difference
was negligible considering how small this set will be since group visits
generally span 1 day.
This improvement should serve it's purpose until conflict checking gets some
much needed refactoring.
*/
declare @MINSTART datetime, @MAXEND datetime;
set @MINSTART = (select min(STARTDATETIME) from @ITEMS);
set @MAXEND = (select max(ENDDATETIME) from @ITEMS);
declare @FILTEREDEVENTS xml = (
select
ID,
PROGRAMID,
EVENTLOCATIONID,
STARTDATETIME,
ENDDATETIME
from dbo.EVENT with (nolock)
where
(
(
@MINSTART >= EVENT.STARTDATETIME and
@MINSTART < EVENT.ENDDATETIME
) or
(
@MAXEND > EVENT.STARTDATETIME and
@MAXEND <= EVENT.ENDDATETIME
) or
(
@MINSTART < EVENT.STARTDATETIME and
@MAXEND > EVENT.ENDDATETIME
)
)for xml raw('ITEM'),type,elements,root('CONFLICTEVENTS'),BINARY BASE64
)
-- Now we can check for conflicts with the itinerary items
-- Doing conflict checking before Update on Itinerary Item table for some deadlock prevention
delete from @ITEMS
where
not exists
(
select 1 from dbo.ITINERARYITEM with (nolock)
where
ITINERARYITEM.ITINERARYID = @ID and
ITINERARYITEM.ID = [@ITEMS].ID and
ITINERARYITEM.INVALIDREASONCODE = 0 and
dbo.UFN_CONFLICTCHECK_CONFLICTSEXIST_WITHFILTEREDEVENTS
(
[@ITEMS].STARTDATETIME,
[@ITEMS].ENDDATETIME,
case
when ITINERARYITEM.EVENTLOCATIONID is null then ''
else '<LOCATIONS><ITEM><EVENTLOCATIONID>' + cast(ITINERARYITEM.EVENTLOCATIONID as nvarchar(36)) + '</EVENTLOCATIONID></ITEM></LOCATIONS>'
end,
dbo.UFN_ITINERARYITEMRESOURCE_GETRESOURCES_TOITEMLISTXML(ITINERARYITEM.ID),
dbo.UFN_ITINERARYITEM_GETSTAFFRESOURCES_TOITEMLISTXML(ITINERARYITEM.ID),
null,
ITINERARYITEM.ITINERARYID,
ITINERARYITEM.ID,
0, -- Do not ignore super record
0, -- Ignore record
1, -- Ignore sub record
0, -- Do not ignore subrecords of record
@FILTEREDEVENTS
) = 1
)
update dbo.ITINERARYITEM set
INVALIDREASONCODE = 10, -- Invalid reason 10 for conflicts
ITEMTYPECODE = 3, --Make sure the event is marked as unscheduled
CHANGEDBYID = @CHANGEAGENTID,
DATECHANGED = @CURRENTDATE
from @ITEMS as ITEMS
where
ITINERARYITEM.ITINERARYID = @ID and
ITEMS.ID = ITINERARYITEM.ID
-- Insert sales order items for locations that have a price and are not unscheduled
if (select count(1) from @ITINERARYITEMLOCATIONS) > 0
begin
-- Insert sales order items for locations that have a price and are not unscheduled
delete from @ITINERARYITEMLOCATIONS
from dbo.ITINERARYITEM
where
ITINERARYITEM.ID = [@ITINERARYITEMLOCATIONS].ITINERARYITEMID and
ITINERARYITEM.ITEMTYPECODE = 3
insert into dbo.SALESORDERITEM
(
ID,
SALESORDERID,
TYPECODE,
DESCRIPTION,
QUANTITY,
FLATRATEPRICE,
PRICINGSTRUCTURECODE,
ADDEDBYID, CHANGEDBYID, DATEADDED, DATECHANGED
)
select
SALESORDERITEMID,
@RESERVATIONID,
7,
LOCATIONS.NAME + ' - ' + coalesce(EVENTLOCATION.NAME, ''),
1,
LOCATIONS.PRICE,
2,
@CHANGEAGENTID, @CHANGEAGENTID, @CURRENTDATE, @CURRENTDATE
from @ITINERARYITEMLOCATIONS LOCATIONS
inner join dbo.EVENTLOCATION on
LOCATIONS.EVENTLOCATIONID = EVENTLOCATION.ID
insert into dbo.SALESORDERITEMFACILITY
(
ID,
EVENTLOCATIONID,
EVENTLOCATIONNAME,
ADDEDBYID, CHANGEDBYID, DATEADDED, DATECHANGED
)
select
[@ITINERARYITEMLOCATIONS].SALESORDERITEMID,
[@ITINERARYITEMLOCATIONS].EVENTLOCATIONID,
EVENTLOCATION.NAME,
@CHANGEAGENTID, @CHANGEAGENTID, @CURRENTDATE, @CURRENTDATE
from @ITINERARYITEMLOCATIONS
inner join dbo.EVENTLOCATION on
EVENTLOCATION.ID = [@ITINERARYITEMLOCATIONS].EVENTLOCATIONID
insert into dbo.ITINERARYITEMLOCATION
(
ID,
SALESORDERITEMID,
ADDEDBYID, CHANGEDBYID, DATEADDED, DATECHANGED
)
select
ITINERARYITEMID,
SALESORDERITEMID,
@CHANGEAGENTID, @CHANGEAGENTID, @CURRENTDATE, @CURRENTDATE
from @ITINERARYITEMLOCATIONS
end
-- update Sales order items for the resources
exec dbo.USP_ITINERARY_RESOURCES_SALESORDERSYNC @ID, @RESERVATIONID, @CHANGEAGENTID
exec dbo.USP_ITINERARY_STAFFRESOURCES_SALESORDERSYNC @ID, @RESERVATIONID, @CHANGEAGENTID
-- call the bulk versions to update all itinerary item records
exec dbo.USP_ITINERARYITEMS_RESOURCES_SALESORDERSYNC @ID, @RESERVATIONID, @CHANGEAGENTID
exec dbo.USP_ITINERARYITEMS_STAFFRESOURCES_SALESORDERSYNC @ID, @RESERVATIONID, @CHANGEAGENTID
-- update Sales order Items for Itinerary items (Includes taxes for resource line items, flat rate calculations, etc)
exec dbo.USP_ITINERARY_UPDATEITEMQUANTITIES @ID, @CHANGEAGENTID, @CURRENTDATE;
end