USP_RESCHEDULETICKETS_COMPLETE
Parameters
Parameter | Parameter Type | Mode | Description |
---|---|---|---|
@SALESORDERID | uniqueidentifier | IN | |
@ITEMS | xml | IN | |
@CHANGEAGENTID | uniqueidentifier | IN | |
@CURRENTAPPUSERID | uniqueidentifier | IN | |
@TIMESTAMP | bigint | IN |
Definition
Copy
CREATE procedure dbo.USP_RESCHEDULETICKETS_COMPLETE
(
@SALESORDERID uniqueidentifier,
@ITEMS xml,
@CHANGEAGENTID uniqueidentifier,
@CURRENTAPPUSERID uniqueidentifier,
@TIMESTAMP bigint = null
)
as
begin
declare @CURRENTTIME datetime = getdate();
-- Make sure nobody else has rescheduled this order since the form was opened.
if @TIMESTAMP <> (select TSLONG from dbo.SALESORDER where ID = @SALESORDERID) begin
raiserror('ERR_CREDITITEMS_CONFLICTINGRESCHEDULE', 13, 1);
return 1;
end
else begin
update dbo.SALESORDER
set DATECHANGED = @CURRENTTIME, CHANGEDBYID = @CHANGEAGENTID
where ID = @SALESORDERID;
end
declare @TICKETSTORESCHEDULE table (
TICKETID uniqueidentifier,
PRICETYPECODEID uniqueidentifier,
PRICE money,
ORIGINALSALESORDERITEMID uniqueidentifier,
NEWSALESORDERITEMID uniqueidentifier,
ORIGINALEVENTID uniqueidentifier,
NEWEVENTID uniqueidentifier,
REGISTRANTID uniqueidentifier -- For preregistrants.
);
insert into @TICKETSTORESCHEDULE
select
TICKET.ID,
TICKET.PRICETYPECODEID,
TICKET.PRICE,
TICKET.SALESORDERITEMTICKETID,
null,
TICKET.EVENTID,
T.item.value('(@NEWEVENTID)[1]','uniqueidentifier'),
case when T.item.value('(@REGISTRANTID)[1]','uniqueidentifier') = '00000000-0000-0000-0000-000000000000' then null else T.item.value('(@REGISTRANTID)[1]','uniqueidentifier') end
from @ITEMS.nodes('/ITEMS/ITEM') T(item)
inner join dbo.TICKET on TICKET.ID = T.item.value('(@TICKETID)[1]','uniqueidentifier')
where TICKET.EVENTID <> T.item.value('(@NEWEVENTID)[1]','uniqueidentifier')
and T.item.value('(@NEWEVENTID)[1]','uniqueidentifier') <> '00000000-0000-0000-0000-000000000000';
if not exists (select 1 from @TICKETSTORESCHEDULE)
return 0;
if exists (
select 1
from @TICKETSTORESCHEDULE RESCHEDULES
inner join dbo.TICKET on TICKET.ID = RESCHEDULES.TICKETID
where TICKET.STATUSCODE = 2
or TICKET.ISREFUNDED = 1
)
begin
raiserror('BBERR_RESCHEDULE_REFUNDEDTICKET', 13, 1);
return 1;
end
-- These tables contain all of the SALESORDERITEM.* details that will need to be updated, inserted, or deleted as a result of the ticket changes.
-- Each entry in any of the tables represents the original and final values for that record (original price/amount/quantity of 0 means it's a new record, and final 0 means it will be deleted).
-- This makes the final insert/update/delete clauses much simpler because no further aggregation will be necessary.
declare @UPDATEDTICKETITEMS table (ID uniqueidentifier, PRICETYPECODEID uniqueidentifier, EVENTID uniqueidentifier, PRICE money, OLDQUANTITY decimal, NEWQUANTITY decimal);
declare @UPDATEDFEEITEMS table (ID uniqueidentifier, ORIGINALPRICE money, NEWPRICE money, [PERCENT] decimal(7,4), [DESCRIPTION] nvarchar(max), APPLIEDTOITEMID uniqueidentifier, FEEID uniqueidentifier, FEENAME nvarchar(max));
declare @UPDATEDTAXITEMS table (APPLIEDTOITEMID uniqueidentifier, TAXID uniqueidentifier, TAXITEMID uniqueidentifier, TOTALTAX decimal(7,4), TAXNAME nvarchar(max));
declare @UPDATEDITEMDISCOUNTS table (ID uniqueidentifier, ORIGINALAMOUNT money, NEWAMOUNT money, NUMBEROFTIMESAPPLIED int, APPLIEDTOITEMID uniqueidentifier, DISCOUNTID uniqueidentifier, DISCOUNTNAME nvarchar(max));
declare @UPDATEDORDERDISCOUNTDETAILS table (ID uniqueidentifier, ORIGINALAMOUNT money, NEWAMOUNT money, DISCOUNTID uniqueidentifier, APPLIEDTOITEMID uniqueidentifier, SALESORDERITEMORDERDISCOUNTID uniqueidentifier);
-- Ticket items
with TICKETITEMS as (
select TICKETITEM.ID, TICKETITEM.PRICETYPECODEID, TICKETITEM.PROGRAMID, TICKETITEM.EVENTID, SALESORDERITEM.PRICE, SALESORDERITEM.QUANTITY, COMBOITEM.TICKETCOMBINATIONID
from dbo.SALESORDERITEM
inner join dbo.SALESORDERITEMTICKET TICKETITEM on TICKETITEM.ID = SALESORDERITEM.ID
left join dbo.SALESORDERITEMTICKETCOMBINATION COMBOITEM on COMBOITEM.ID = TICKETITEM.ID
where SALESORDERITEM.SALESORDERID = @SALESORDERID
and SALESORDERITEM.TYPECODE = 0
),
ORIGINALEVENTS as (
select ORIGINALSALESORDERITEMID, count(TICKETID) NUM
from @TICKETSTORESCHEDULE RESCHEDULE
group by ORIGINALSALESORDERITEMID
),
NEWEVENTS as (
select PRICETYPECODEID, NEWEVENTID, PRICE, count(TICKETID) NUM
from @TICKETSTORESCHEDULE RESCHEDULE
group by PRICETYPECODEID, NEWEVENTID, PRICE
)
insert into @UPDATEDTICKETITEMS
select
coalesce(SOURCETICKETITEMS.ID, newid()),
coalesce(SOURCETICKETITEMS.PRICETYPECODEID, NEWEVENTS.PRICETYPECODEID),
coalesce(SOURCETICKETITEMS.EVENTID, NEWEVENTS.NEWEVENTID),
coalesce(SOURCETICKETITEMS.PRICE, NEWEVENTS.PRICE),
coalesce(SOURCETICKETITEMS.QUANTITY, 0),
coalesce(SOURCETICKETITEMS.QUANTITY, 0) - coalesce(ORIGINALEVENTS.NUM, 0) + coalesce(NEWEVENTS.NUM, 0)
from TICKETITEMS SOURCETICKETITEMS
left join ORIGINALEVENTS on ORIGINALEVENTS.ORIGINALSALESORDERITEMID = SOURCETICKETITEMS.ID -- Left join here so that the full join below can match already-existing ticket items (e.g. 2/2 to 1/3)
full join NEWEVENTS
on (NEWEVENTS.NEWEVENTID = SOURCETICKETITEMS.EVENTID and NEWEVENTS.PRICETYPECODEID = SOURCETICKETITEMS.PRICETYPECODEID
and (SOURCETICKETITEMS.TICKETCOMBINATIONID is null or NEWEVENTS.NEWEVENTID is null)) -- Do not reschedule to a combo item, even if rescheduling from a combo item.
where (ORIGINALEVENTS.ORIGINALSALESORDERITEMID is not null or NEWEVENTS.NEWEVENTID is not null)
and (NEWEVENTS.NEWEVENTID is not null or SOURCETICKETITEMS.EVENTID is not null);
update RESCHEDULES
set NEWSALESORDERITEMID = UPDATEDITEMS.ID
from @TICKETSTORESCHEDULE RESCHEDULES
inner join @UPDATEDTICKETITEMS UPDATEDITEMS on UPDATEDITEMS.EVENTID = RESCHEDULES.NEWEVENTID and UPDATEDITEMS.PRICETYPECODEID = RESCHEDULES.PRICETYPECODEID;
-- TODO: Can skip a lot of this when all tickets on the salesorderitem are being rescheduled to the same event.
-- Fee items
with FEEITEMS as (
select FEEITEM.ID, FEEITEM.FEEID, FEEITEM.FEENAME, FEEITEM.SALESORDERITEMID APPLIEDTOITEMID, SALESORDERITEM.PRICE, SALESORDERITEM.[PERCENT], SALESORDERITEM.[DESCRIPTION]
from dbo.SALESORDERITEM
inner join dbo.SALESORDERITEMFEE FEEITEM on FEEITEM.ID = SALESORDERITEM.ID
where SALESORDERITEM.SALESORDERID = @SALESORDERID
and SALESORDERITEM.TYPECODE = 3
and FEEITEM.APPLIESTOCODE = 1 -- Only include item-level fees; otherwise, the NEWPRICE will be calculated as $0 for order-level fee items, and they will be deleted.
),
GROUPEDTICKETFEEAMOUNTS as (
select
TICKETFEE.SALESORDERITEMFEEID,
FEEITEMS.FEEID,
coalesce(RESCHEDULES.NEWSALESORDERITEMID, FEEITEMS.APPLIEDTOITEMID) NEWAPPLIEDTOITEMID,
sum(TICKETFEE.AMOUNT) as AMOUNT
from FEEITEMS
inner join dbo.SALESORDERITEMTICKETFEE TICKETFEE on TICKETFEE.SALESORDERITEMFEEID = FEEITEMS.ID
left join @TICKETSTORESCHEDULE RESCHEDULES on RESCHEDULES.TICKETID = TICKETFEE.TICKETID
group by TICKETFEE.SALESORDERITEMFEEID, FEEITEMS.FEEID, FEEITEMS.APPLIEDTOITEMID, RESCHEDULES.NEWSALESORDERITEMID
)
insert into @UPDATEDFEEITEMS
select
coalesce(UPDATEDFEEITEMS.ID, newid()),
coalesce(UPDATEDFEEITEMS.PRICE, 0),
sum(coalesce(GROUPEDTICKETFEEAMOUNTS.AMOUNT, 0)),
coalesce(UPDATEDFEEITEMS.[PERCENT], SOURCEFEEITEMS.[PERCENT]),
coalesce(UPDATEDFEEITEMS.[DESCRIPTION], SOURCEFEEITEMS.[DESCRIPTION]),
coalesce(UPDATEDFEEITEMS.APPLIEDTOITEMID, GROUPEDTICKETFEEAMOUNTS.NEWAPPLIEDTOITEMID),
coalesce(UPDATEDFEEITEMS.FEEID, SOURCEFEEITEMS.FEEID),
coalesce(UPDATEDFEEITEMS.FEENAME, SOURCEFEEITEMS.FEENAME)
from GROUPEDTICKETFEEAMOUNTS
inner join FEEITEMS SOURCEFEEITEMS on SOURCEFEEITEMS.ID = GROUPEDTICKETFEEAMOUNTS.SALESORDERITEMFEEID
full join FEEITEMS UPDATEDFEEITEMS on (UPDATEDFEEITEMS.APPLIEDTOITEMID = GROUPEDTICKETFEEAMOUNTS.NEWAPPLIEDTOITEMID and UPDATEDFEEITEMS.FEEID = GROUPEDTICKETFEEAMOUNTS.FEEID)
group by UPDATEDFEEITEMS.ID, UPDATEDFEEITEMS.PRICE, UPDATEDFEEITEMS.[PERCENT], UPDATEDFEEITEMS.[DESCRIPTION], UPDATEDFEEITEMS.APPLIEDTOITEMID, UPDATEDFEEITEMS.FEEID, UPDATEDFEEITEMS.FEENAME,
SOURCEFEEITEMS.[PERCENT], SOURCEFEEITEMS.[DESCRIPTION], SOURCEFEEITEMS.FEEID, SOURCEFEEITEMS.FEENAME,
GROUPEDTICKETFEEAMOUNTS.NEWAPPLIEDTOITEMID;
-- Tax items. Taxes are nice; they don't store how much applies to each item, just the fact that they apply, so we don't need any fancy dollar sums.
insert into @UPDATEDTAXITEMS
select distinct -- distinct is needed for cases when tickets coming from multiple origin events are rescheduled to the same target event.
TAXEDTICKETS.NEWSALESORDERITEMID,
SALESORDERITEMTAX.TAXID,
SALESORDERITEMTAX.TAXITEMID,
SALESORDERITEMTAX.TOTALTAX,
SALESORDERITEMTAX.TAXNAME
from dbo.SALESORDERITEMTAX
cross apply (
select distinct NEWSALESORDERITEMID
from @TICKETSTORESCHEDULE
where ORIGINALSALESORDERITEMID = SALESORDERITEMTAX.SALESORDERITEMID
) TAXEDTICKETS;
-- Item-level discounts
-- TODO: this is a bit too accepting, in that discounts that don't change may still show up (for example, when discount applies to ticket A, but only ticket B is rescheduled).
-- It shouldn't cause any erroneous outcomes, but if time permits later, do look into cleaning that up.
with ITEMDISCOUNTS as (
select ITEMDISCOUNT.ID, ITEMDISCOUNT.AMOUNT, ITEMDISCOUNT.DISCOUNTID, ITEMDISCOUNT.DISCOUNTNAME, ITEMDISCOUNT.SALESORDERITEMID APPLIEDTOITEMID, ITEMDISCOUNT.NUMBEROFDISCOUNTEDITEMS
from SALESORDERITEMITEMDISCOUNT ITEMDISCOUNT
inner join dbo.SALESORDERITEM on SALESORDERITEM.ID = ITEMDISCOUNT.SALESORDERITEMID
where SALESORDERITEM.SALESORDERID = @SALESORDERID
),
GROUPEDITEMDISCOUNTAMOUNTS as (
select
ITEMDISCOUNTS.ID ITEMDISCOUNTID,
ITEMDISCOUNTS.DISCOUNTID,
coalesce(RESCHEDULES.NEWSALESORDERITEMID, ITEMDISCOUNTS.APPLIEDTOITEMID) NEWAPPLIEDTOITEMID,
sum(TICKET.ITEMLEVELDISCOUNTSAPPLIED) as AMOUNT,
count(TICKET.ID) NUMBEROFDISCOUNTEDTICKETS
from ITEMDISCOUNTS
inner join dbo.TICKET on TICKET.SALESORDERITEMTICKETID = ITEMDISCOUNTS.APPLIEDTOITEMID
left join @TICKETSTORESCHEDULE RESCHEDULES on RESCHEDULES.TICKETID = TICKET.ID
where TICKET.ITEMLEVELDISCOUNTSAPPLIED > 0
group by ITEMDISCOUNTS.ID, ITEMDISCOUNTS.DISCOUNTID, ITEMDISCOUNTS.APPLIEDTOITEMID, RESCHEDULES.NEWSALESORDERITEMID
)
insert into @UPDATEDITEMDISCOUNTS
select
coalesce(UPDATEDITEMDISCOUNTS.ID, newid()),
coalesce(UPDATEDITEMDISCOUNTS.AMOUNT, 0),
coalesce(sum(GROUPEDITEMDISCOUNTAMOUNTS.AMOUNT), 0),
coalesce(sum(GROUPEDITEMDISCOUNTAMOUNTS.NUMBEROFDISCOUNTEDTICKETS), 0),
coalesce(UPDATEDITEMDISCOUNTS.APPLIEDTOITEMID, GROUPEDITEMDISCOUNTAMOUNTS.NEWAPPLIEDTOITEMID),
coalesce(UPDATEDITEMDISCOUNTS.DISCOUNTID, SOURCEITEMDISCOUNTS.DISCOUNTID),
coalesce(UPDATEDITEMDISCOUNTS.DISCOUNTNAME, SOURCEITEMDISCOUNTS.DISCOUNTNAME)
from GROUPEDITEMDISCOUNTAMOUNTS
inner join ITEMDISCOUNTS SOURCEITEMDISCOUNTS on SOURCEITEMDISCOUNTS.ID = GROUPEDITEMDISCOUNTAMOUNTS.ITEMDISCOUNTID
full join ITEMDISCOUNTS UPDATEDITEMDISCOUNTS on (UPDATEDITEMDISCOUNTS.APPLIEDTOITEMID = GROUPEDITEMDISCOUNTAMOUNTS.NEWAPPLIEDTOITEMID and UPDATEDITEMDISCOUNTS.DISCOUNTID = GROUPEDITEMDISCOUNTAMOUNTS.DISCOUNTID)
group by UPDATEDITEMDISCOUNTS.ID, UPDATEDITEMDISCOUNTS.AMOUNT, UPDATEDITEMDISCOUNTS.APPLIEDTOITEMID, UPDATEDITEMDISCOUNTS.DISCOUNTID, UPDATEDITEMDISCOUNTS.DISCOUNTNAME,
SOURCEITEMDISCOUNTS.DISCOUNTID, SOURCEITEMDISCOUNTS.DISCOUNTNAME,
GROUPEDITEMDISCOUNTAMOUNTS.NEWAPPLIEDTOITEMID;
-- Order-level discounts.
-- We'll need the DISCOUNTID and CREDITID when we make the CREDITITEM_EXT records for the new discounts, after all the sales updates are complete.
declare @NUMORDERLEVELDISCOUNTS tinyint = (select count(*) from dbo.SALESORDERITEM where SALESORDERID = @SALESORDERID and TYPECODE = 5);
if @NUMORDERLEVELDISCOUNTS = 1
begin
-- Only one order-level discount was applied, so we can use TICKET.ORDERLEVELDISCOUNTSAPPLIED as the per-ticket amount (regardless of whether the discount is standard or adjustable).
with ORDERDISCOUNTS as (
select ORDERDISCOUNTDETAIL.ID, ORDERDISCOUNTDETAIL.SALESORDERITEMORDERDISCOUNTID, ORDERDISCOUNTDETAIL.AMOUNT, ORDERDISCOUNT.DISCOUNTID, ORDERDISCOUNTDETAIL.SALESORDERITEMID APPLIEDTOITEMID
from SALESORDERITEMORDERDISCOUNT ORDERDISCOUNT
inner join dbo.SALESORDERITEMORDERDISCOUNTDETAIL ORDERDISCOUNTDETAIL on ORDERDISCOUNTDETAIL.SALESORDERITEMORDERDISCOUNTID = ORDERDISCOUNT.ID
inner join dbo.SALESORDERITEM on SALESORDERITEM.ID = ORDERDISCOUNT.ID
where SALESORDERITEM.SALESORDERID = @SALESORDERID
),
GROUPEDORDERDISCOUNTAMOUNTS as (
select
ORDERDISCOUNTS.ID ORDERDISCOUNTDETAILID,
TICKET.SALESORDERITEMTICKETID ORIGINALAPPLIEDTOITEMID,
coalesce(RESCHEDULES.NEWSALESORDERITEMID, TICKET.SALESORDERITEMTICKETID) NEWAPPLIEDTOITEMID,
sum(TICKET.ORDERLEVELDISCOUNTSAPPLIED) as ORDERLEVELDISCOUNTAMOUNT
from ORDERDISCOUNTS
inner join dbo.TICKET on TICKET.SALESORDERITEMTICKETID = ORDERDISCOUNTS.APPLIEDTOITEMID
left join @TICKETSTORESCHEDULE RESCHEDULES on RESCHEDULES.TICKETID = TICKET.ID
group by ORDERDISCOUNTS.ID, TICKET.SALESORDERITEMTICKETID, RESCHEDULES.NEWSALESORDERITEMID
)
insert into @UPDATEDORDERDISCOUNTDETAILS
select
coalesce(UPDATEDORDERDISCOUNTS.ID, newid()),
coalesce(UPDATEDORDERDISCOUNTS.AMOUNT, 0),
coalesce(sum(GROUPEDORDERDISCOUNTAMOUNTS.ORDERLEVELDISCOUNTAMOUNT), 0),
coalesce(UPDATEDORDERDISCOUNTS.DISCOUNTID, SOURCEORDERDISCOUNTS.DISCOUNTID),
coalesce(UPDATEDORDERDISCOUNTS.APPLIEDTOITEMID, GROUPEDORDERDISCOUNTAMOUNTS.NEWAPPLIEDTOITEMID),
SOURCEORDERDISCOUNTS.SALESORDERITEMORDERDISCOUNTID
from GROUPEDORDERDISCOUNTAMOUNTS
inner join ORDERDISCOUNTS SOURCEORDERDISCOUNTS on SOURCEORDERDISCOUNTS.APPLIEDTOITEMID = GROUPEDORDERDISCOUNTAMOUNTS.ORIGINALAPPLIEDTOITEMID
full join ORDERDISCOUNTS UPDATEDORDERDISCOUNTS on UPDATEDORDERDISCOUNTS.APPLIEDTOITEMID = GROUPEDORDERDISCOUNTAMOUNTS.NEWAPPLIEDTOITEMID
group by UPDATEDORDERDISCOUNTS.ID, UPDATEDORDERDISCOUNTS.AMOUNT, UPDATEDORDERDISCOUNTS.DISCOUNTID, UPDATEDORDERDISCOUNTS.APPLIEDTOITEMID, SOURCEORDERDISCOUNTS.DISCOUNTID, SOURCEORDERDISCOUNTS.SALESORDERITEMORDERDISCOUNTID, GROUPEDORDERDISCOUNTAMOUNTS.NEWAPPLIEDTOITEMID;
end
else if @NUMORDERLEVELDISCOUNTS = 2 -- Has both "standard" order-level and adjustable discounts.
begin
-- To avoid rounding errors, we have to re-prorate the standard order-level discount across all tickets, and then subtract that from the total order-level amount to get the per-ticket adjustable amount.
-- TODO: Verify that the proration works for very small discount values (fewer cents than tickets).
with ORDERDISCOUNTS as (
select ORDERDISCOUNTDETAIL.ID, ORDERDISCOUNTDETAIL.SALESORDERITEMORDERDISCOUNTID, ORDERDISCOUNTDETAIL.AMOUNT, ORDERDISCOUNT.DISCOUNTID, ORDERDISCOUNTDETAIL.SALESORDERITEMID APPLIEDTOITEMID, ORDERDISCOUNT.ISADJUSTABLEDISCOUNT
from SALESORDERITEMORDERDISCOUNT ORDERDISCOUNT
inner join dbo.SALESORDERITEMORDERDISCOUNTDETAIL ORDERDISCOUNTDETAIL on ORDERDISCOUNTDETAIL.SALESORDERITEMORDERDISCOUNTID = ORDERDISCOUNT.ID
inner join dbo.SALESORDERITEM on SALESORDERITEM.ID = ORDERDISCOUNT.ID
where SALESORDERITEM.SALESORDERID = @SALESORDERID
),
TICKETSWITHDIVIDEDDISCOUNTS as (
select
TICKET.ID,
TICKET.SALESORDERITEMTICKETID,
coalesce(PRORATEDSTANDARDDISCOUNTAMOUNTS.AMOUNT,0) as ORDERLEVELDISCOUNTAMOUNT,
TICKET.ORDERLEVELDISCOUNTSAPPLIED - coalesce(PRORATEDSTANDARDDISCOUNTAMOUNTS.AMOUNT,0) as ADJUSTABLEDISCOUNTAMOUNT
from dbo.TICKET
inner join dbo.SALESORDERITEM on SALESORDERITEM.ID = TICKET.SALESORDERITEMTICKETID
left join ORDERDISCOUNTS on (ORDERDISCOUNTS.APPLIEDTOITEMID = TICKET.SALESORDERITEMTICKETID and ORDERDISCOUNTS.ISADJUSTABLEDISCOUNT = 0)
outer apply dbo.UFN_SPLITS_PRORATEAMOUNTS (
(select sum(ORDERLEVELDISCOUNTSAPPLIED) from dbo.TICKET where SALESORDERITEMTICKETID = ORDERDISCOUNTS.APPLIEDTOITEMID),
ORDERDISCOUNTS.AMOUNT,
2,
(select ID, ORDERLEVELDISCOUNTSAPPLIED as AMOUNT from dbo.TICKET where SALESORDERITEMTICKETID = ORDERDISCOUNTS.APPLIEDTOITEMID for xml raw('ITEM'),type,elements,root('AMOUNTSTOPRORATE'),binary base64)
) PRORATEDSTANDARDDISCOUNTAMOUNTS
where SALESORDERITEM.SALESORDERID = @SALESORDERID
and (PRORATEDSTANDARDDISCOUNTAMOUNTS.ID = TICKET.ID or PRORATEDSTANDARDDISCOUNTAMOUNTS.ID is null)
),
GROUPEDORDERDISCOUNTAMOUNTS as (
select
ORDERDISCOUNTS.ID ORDERDISCOUNTDETAILID,
TICKETSWITHDIVIDEDDISCOUNTS.SALESORDERITEMTICKETID ORIGINALAPPLIEDTOITEMID,
coalesce(RESCHEDULES.NEWSALESORDERITEMID, TICKETSWITHDIVIDEDDISCOUNTS.SALESORDERITEMTICKETID) NEWAPPLIEDTOITEMID,
case
when ORDERDISCOUNTS.ISADJUSTABLEDISCOUNT = 0
then sum(TICKETSWITHDIVIDEDDISCOUNTS.ORDERLEVELDISCOUNTAMOUNT)
else sum(TICKETSWITHDIVIDEDDISCOUNTS.ADJUSTABLEDISCOUNTAMOUNT)
end as ORDERLEVELDISCOUNTAMOUNT,
ORDERDISCOUNTS.ISADJUSTABLEDISCOUNT
from ORDERDISCOUNTS
inner join TICKETSWITHDIVIDEDDISCOUNTS on TICKETSWITHDIVIDEDDISCOUNTS.SALESORDERITEMTICKETID = ORDERDISCOUNTS.APPLIEDTOITEMID
left join @TICKETSTORESCHEDULE RESCHEDULES on RESCHEDULES.TICKETID = TICKETSWITHDIVIDEDDISCOUNTS.ID
group by ORDERDISCOUNTS.ID, TICKETSWITHDIVIDEDDISCOUNTS.SALESORDERITEMTICKETID, RESCHEDULES.NEWSALESORDERITEMID, ORDERDISCOUNTS.ISADJUSTABLEDISCOUNT
)
insert into @UPDATEDORDERDISCOUNTDETAILS
select
coalesce(UPDATEDORDERDISCOUNTS.ID, newid()),
coalesce(UPDATEDORDERDISCOUNTS.AMOUNT, 0),
coalesce(sum(GROUPEDORDERDISCOUNTAMOUNTS.ORDERLEVELDISCOUNTAMOUNT), 0),
coalesce(UPDATEDORDERDISCOUNTS.DISCOUNTID, SOURCEORDERDISCOUNTS.DISCOUNTID),
coalesce(UPDATEDORDERDISCOUNTS.APPLIEDTOITEMID, GROUPEDORDERDISCOUNTAMOUNTS.NEWAPPLIEDTOITEMID),
SOURCEORDERDISCOUNTS.SALESORDERITEMORDERDISCOUNTID
from GROUPEDORDERDISCOUNTAMOUNTS
inner join ORDERDISCOUNTS SOURCEORDERDISCOUNTS on (SOURCEORDERDISCOUNTS.APPLIEDTOITEMID = GROUPEDORDERDISCOUNTAMOUNTS.ORIGINALAPPLIEDTOITEMID and SOURCEORDERDISCOUNTS.ISADJUSTABLEDISCOUNT = GROUPEDORDERDISCOUNTAMOUNTS.ISADJUSTABLEDISCOUNT)
full join ORDERDISCOUNTS UPDATEDORDERDISCOUNTS on (UPDATEDORDERDISCOUNTS.APPLIEDTOITEMID = GROUPEDORDERDISCOUNTAMOUNTS.NEWAPPLIEDTOITEMID and UPDATEDORDERDISCOUNTS.ISADJUSTABLEDISCOUNT = GROUPEDORDERDISCOUNTAMOUNTS.ISADJUSTABLEDISCOUNT)
group by UPDATEDORDERDISCOUNTS.ID, UPDATEDORDERDISCOUNTS.AMOUNT, UPDATEDORDERDISCOUNTS.DISCOUNTID, UPDATEDORDERDISCOUNTS.APPLIEDTOITEMID, SOURCEORDERDISCOUNTS.DISCOUNTID, SOURCEORDERDISCOUNTS.SALESORDERITEMORDERDISCOUNTID, GROUPEDORDERDISCOUNTAMOUNTS.NEWAPPLIEDTOITEMID;
end
-- Get the SALESORDERNOTEs that need to be updated.
-- Taxes and discounts don't get new sales order items, so we don't have to include them.
declare @SALESORDERNOTESTOCOPY table (
ID uniqueidentifier,
DATEENTERED date,
TITLE nvarchar(50),
AUTHORID uniqueidentifier,
TEXTNOTE nvarchar(max),
SALESORDERNOTETYPECODEID uniqueidentifier,
HTMLNOTE nvarchar(max),
NEWSALESORDERITEMID uniqueidentifier,
DELETEORIGINAL bit
);
with NOTABLESALESORDERITEMSTOUPDATE as
(
-- Ticket items
select distinct
RESCHEDULE.ORIGINALSALESORDERITEMID,
RESCHEDULE.NEWSALESORDERITEMID,
case when UPDATEDTICKETITEMS.NEWQUANTITY = 0 then 1 else 0 end DELETEORIGINAL
from @TICKETSTORESCHEDULE RESCHEDULE
inner join @UPDATEDTICKETITEMS UPDATEDTICKETITEMS on UPDATEDTICKETITEMS.ID = RESCHEDULE.ORIGINALSALESORDERITEMID
union all
-- Fee items
select distinct
ORIGINALFEEITEM.ID as ORIGINALSALESORDERITEMID,
NEWFEEITEM.ID as NEWSALESORDERITEMID,
case when ORIGINALFEEITEM.NEWPRICE = 0 then 1 else 0 end DELETEORIGINAL
from @TICKETSTORESCHEDULE RESCHEDULE
inner join @UPDATEDFEEITEMS ORIGINALFEEITEM on ORIGINALFEEITEM.APPLIEDTOITEMID = RESCHEDULE.ORIGINALSALESORDERITEMID
inner join @UPDATEDFEEITEMS NEWFEEITEM on NEWFEEITEM.APPLIEDTOITEMID = RESCHEDULE.NEWSALESORDERITEMID
)
insert into @SALESORDERNOTESTOCOPY
select
SALESORDERNOTE.ID,
SALESORDERNOTE.DATEENTERED,
SALESORDERNOTE.TITLE,
SALESORDERNOTE.AUTHORID,
SALESORDERNOTE.TEXTNOTE,
SALESORDERNOTE.SALESORDERNOTETYPECODEID,
SALESORDERNOTE.HTMLNOTE,
NOTABLESALESORDERITEMSTOUPDATE.NEWSALESORDERITEMID,
NOTABLESALESORDERITEMSTOUPDATE.DELETEORIGINAL
from dbo.SALESORDERNOTE
inner join NOTABLESALESORDERITEMSTOUPDATE on NOTABLESALESORDERITEMSTOUPDATE.ORIGINALSALESORDERITEMID = SALESORDERNOTE.SALESORDERITEMID
where SALESORDERNOTE.SALESORDERID = @SALESORDERID;
begin try
-- Add and update ticket items.
insert into dbo.SALESORDERITEM
(ID, PRICE, QUANTITY, SALESORDERID, TYPECODE, [DESCRIPTION], ADDEDBYID, CHANGEDBYID, DATEADDED, DATECHANGED)
select
NEWITEMS.ID, PRICE, NEWQUANTITY, @SALESORDERID, 0, EVENT.NAME + ' - ' + PRICETYPECODE.[DESCRIPTION], @CHANGEAGENTID, @CHANGEAGENTID, @CURRENTTIME, @CURRENTTIME
from @UPDATEDTICKETITEMS NEWITEMS
inner join dbo.EVENT on EVENT.ID = NEWITEMS.EVENTID
inner join dbo.PRICETYPECODE on PRICETYPECODE.ID = NEWITEMS.PRICETYPECODEID
where OLDQUANTITY = 0;
insert into dbo.SALESORDERITEMTICKET
(ID, PRICE, PROGRAMID, PROGRAMNAME, PROGRAMCATEGORYNAME, EVENTID, PRICETYPECODEID, ADDEDBYID, CHANGEDBYID, DATEADDED, DATECHANGED)
select
NEWITEMS.ID, NEWITEMS.PRICE, PROGRAM.ID, PROGRAM.NAME, coalesce(PROGRAMCATEGORYCODE.[DESCRIPTION],''), EVENT.ID, NEWITEMS.PRICETYPECODEID, @CHANGEAGENTID, @CHANGEAGENTID, @CURRENTTIME, @CURRENTTIME
from @UPDATEDTICKETITEMS NEWITEMS
inner join dbo.EVENT on EVENT.ID = NEWITEMS.EVENTID
inner join dbo.PROGRAM on PROGRAM.ID = EVENT.PROGRAMID
left join dbo.PROGRAMCATEGORYCODE on PROGRAMCATEGORYCODE.ID = PROGRAM.PROGRAMCATEGORYCODEID
where OLDQUANTITY = 0
and NEWQUANTITY <> 0;
-- Remove the combination grouping data from all items in a combo if any one of the items is being rescheduled.
delete dbo.SALESORDERITEMTICKETCOMBINATION
where TICKETCOMBINATIONID in (
select RESCHEDULEDCOMBOITEM.TICKETCOMBINATIONID
from @UPDATEDTICKETITEMS UPDATEDTICKETITEMS
inner join SALESORDERITEMTICKETCOMBINATION RESCHEDULEDCOMBOITEM on RESCHEDULEDCOMBOITEM.ID = UPDATEDTICKETITEMS.ID
);
update dbo.SALESORDERITEM
set QUANTITY = NEWQUANTITY, CHANGEDBYID = @CHANGEAGENTID, DATECHANGED = @CURRENTTIME
from @UPDATEDTICKETITEMS UPDATEDITEMS
where SALESORDERITEM.ID = UPDATEDITEMS.ID
and OLDQUANTITY <> 0
and NEWQUANTITY <> 0
and NEWQUANTITY <> OLDQUANTITY;
-- Move tickets to new ticket items.
update dbo.TICKET
set EVENTID = RESCHEDULES.NEWEVENTID, SALESORDERITEMTICKETID = UPDATEDTICKETITEMS.ID, CHANGEDBYID = @CHANGEAGENTID, DATECHANGED = @CURRENTTIME
from @TICKETSTORESCHEDULE RESCHEDULES
inner join @UPDATEDTICKETITEMS UPDATEDTICKETITEMS on (UPDATEDTICKETITEMS.EVENTID = RESCHEDULES.NEWEVENTID and UPDATEDTICKETITEMS.PRICETYPECODEID = RESCHEDULES.PRICETYPECODEID)
where TICKET.ID = RESCHEDULES.TICKETID;
-- Update link between order item and registrant.
update dbo.SALESORDERITEMTICKETREGISTRANT
set SALESORDERITEMTICKETID = RESCHEDULES.NEWSALESORDERITEMID, CHANGEDBYID = @CHANGEAGENTID, DATECHANGED = @CURRENTTIME
from @TICKETSTORESCHEDULE RESCHEDULES
where SALESORDERITEMTICKETREGISTRANT.REGISTRANTID = RESCHEDULES.REGISTRANTID
and RESCHEDULES.REGISTRANTID is not null;
update dbo.RESCHEDULETICKETSHISTORY
set SALESORDERITEMTICKETID = UPDATEDTICKETITEMS.ID
from @TICKETSTORESCHEDULE RESCHEDULES
inner join @UPDATEDTICKETITEMS UPDATEDTICKETITEMS on (UPDATEDTICKETITEMS.EVENTID = RESCHEDULES.NEWEVENTID and UPDATEDTICKETITEMS.PRICETYPECODEID = RESCHEDULES.PRICETYPECODEID)
where RESCHEDULETICKETSHISTORY.SALESORDERITEMTICKETID = RESCHEDULES.ORIGINALSALESORDERITEMID
and RESCHEDULETICKETSHISTORY.TICKETID = RESCHEDULES.TICKETID;
insert into dbo.RESCHEDULETICKETSHISTORY(
SALESORDERITEMTICKETID,
TICKETID,
PREVIOUSEVENTID,
RESCHEDULEDDATE,
RESCHEDULEDBYID,
ADDEDBYID,
CHANGEDBYID,
DATEADDED,
DATECHANGED
)
select distinct
UPDATEDTICKETITEMS.ID,
RESCHEDULES.TICKETID,
RESCHEDULES.ORIGINALEVENTID,
@CURRENTTIME,
@CURRENTAPPUSERID,
@CHANGEAGENTID,
@CHANGEAGENTID,
@CURRENTTIME,
@CURRENTTIME
from @TICKETSTORESCHEDULE RESCHEDULES
inner join @UPDATEDTICKETITEMS UPDATEDTICKETITEMS on (UPDATEDTICKETITEMS.EVENTID = RESCHEDULES.NEWEVENTID and UPDATEDTICKETITEMS.PRICETYPECODEID = RESCHEDULES.PRICETYPECODEID);
-- Add and update fee items.
insert into dbo.SALESORDERITEM
(ID, PRICE, QUANTITY, [PERCENT], SALESORDERID, TYPECODE, [DESCRIPTION], ADDEDBYID, CHANGEDBYID, DATEADDED, DATECHANGED)
select
ID, NEWPRICE, 1, [PERCENT], @SALESORDERID, 3, [DESCRIPTION], @CHANGEAGENTID, @CHANGEAGENTID, @CURRENTTIME, @CURRENTTIME
from @UPDATEDFEEITEMS NEWFEEITEMS
where ORIGINALPRICE = 0;
insert into dbo.SALESORDERITEMFEE
(ID, SALESORDERITEMID, TYPECODE, FEEID, FEENAME, APPLIESTOCODE, ADDEDBYID, CHANGEDBYID, DATEADDED, DATECHANGED)
select
ID, APPLIEDTOITEMID, 2, FEEID, FEENAME, 1, @CHANGEAGENTID, @CHANGEAGENTID, @CURRENTTIME, @CURRENTTIME
from @UPDATEDFEEITEMS NEWFEEITEMS
where ORIGINALPRICE = 0;
update dbo.SALESORDERITEM
set PRICE = NEWPRICE, CHANGEDBYID = @CHANGEAGENTID, DATECHANGED = @CURRENTTIME
from @UPDATEDFEEITEMS UPDATEDFEEITEMS
where SALESORDERITEM.ID = UPDATEDFEEITEMS.ID
and UPDATEDFEEITEMS.ORIGINALPRICE <> 0
and UPDATEDFEEITEMS.NEWPRICE <> 0
and UPDATEDFEEITEMS.ORIGINALPRICE <> UPDATEDFEEITEMS.NEWPRICE;
-- Update all TICKETFEEs to point to the new SALESORDERITEMFEEs (none need to be added or removed, since they're at the ticket level)
update dbo.SALESORDERITEMTICKETFEE
set SALESORDERITEMFEEID = UPDATEDFEEITEMS.ID, CHANGEDBYID = @CHANGEAGENTID, DATECHANGED = @CURRENTTIME
from dbo.SALESORDERITEMTICKETFEE
inner join dbo.SALESORDERITEMFEE ORIGINALFEEITEM on ORIGINALFEEITEM.ID = SALESORDERITEMTICKETFEE.SALESORDERITEMFEEID
inner join @TICKETSTORESCHEDULE RESCHEDULES on RESCHEDULES.TICKETID = SALESORDERITEMTICKETFEE.TICKETID
inner join @UPDATEDFEEITEMS UPDATEDFEEITEMS on (UPDATEDFEEITEMS.APPLIEDTOITEMID = RESCHEDULES.NEWSALESORDERITEMID and UPDATEDFEEITEMS.FEEID = ORIGINALFEEITEM.FEEID);
-- Add new tax items.
insert into dbo.SALESORDERITEMTAX
(ID, SALESORDERITEMID, TAXID, TAXNAME, TAXITEMID, TOTALTAX, ADDEDBYID, CHANGEDBYID, DATEADDED, DATECHANGED)
select
newid(), APPLIEDTOITEMID, TAXID, TAXNAME, TAXITEMID, TOTALTAX, @CHANGEAGENTID, @CHANGEAGENTID, @CURRENTTIME, @CURRENTTIME
from @UPDATEDTAXITEMS;
-- Add and update item discount records.
insert into dbo.SALESORDERITEMITEMDISCOUNT
(ID, SALESORDERITEMID, AMOUNT, DISCOUNTID, DISCOUNTNAME, NUMBEROFDISCOUNTEDITEMS, ADDEDBYID, CHANGEDBYID, DATEADDED, DATECHANGED)
select
ID, APPLIEDTOITEMID, NEWAMOUNT, DISCOUNTID, DISCOUNTNAME, NUMBEROFTIMESAPPLIED, @CHANGEAGENTID, @CHANGEAGENTID, @CURRENTTIME, @CURRENTTIME
from @UPDATEDITEMDISCOUNTS
where ORIGINALAMOUNT = 0;
update dbo.SALESORDERITEMITEMDISCOUNT
set AMOUNT = NEWAMOUNT, NUMBEROFDISCOUNTEDITEMS = NUMBEROFTIMESAPPLIED, CHANGEDBYID = @CHANGEAGENTID, DATECHANGED = @CURRENTTIME
from @UPDATEDITEMDISCOUNTS UPDATEDITEMDISCOUNTS
where SALESORDERITEMITEMDISCOUNT.ID = UPDATEDITEMDISCOUNTS.ID
and ORIGINALAMOUNT <> 0
and NEWAMOUNT <> 0
and ORIGINALAMOUNT <> NEWAMOUNT;
-- Add and update order discount detail records.
insert into dbo.SALESORDERITEMORDERDISCOUNTDETAIL
(ID, SALESORDERITEMID, AMOUNT, SALESORDERITEMORDERDISCOUNTID, ADDEDBYID, CHANGEDBYID, DATEADDED, DATECHANGED)
select
ID, APPLIEDTOITEMID, NEWAMOUNT, SALESORDERITEMORDERDISCOUNTID, @CHANGEAGENTID, @CHANGEAGENTID, @CURRENTTIME, @CURRENTTIME
from @UPDATEDORDERDISCOUNTDETAILS
where ORIGINALAMOUNT = 0;
update dbo.SALESORDERITEMORDERDISCOUNTDETAIL
set AMOUNT = NEWAMOUNT, CHANGEDBYID = @CHANGEAGENTID, DATECHANGED = @CURRENTTIME
from @UPDATEDORDERDISCOUNTDETAILS UPDATEDORDERDISCOUNTDETAILS
where SALESORDERITEMORDERDISCOUNTDETAIL.ID = UPDATEDORDERDISCOUNTDETAILS.ID
and ORIGINALAMOUNT <> 0
and NEWAMOUNT <> 0
and ORIGINALAMOUNT <> NEWAMOUNT;
-- Copy SALESORDERNOTEs that need to be copied before we start deleting data.
-- TODO: possibly check for existing identical notes before inserting to protect against rampant duplication after multiple reschedules (not urgent).
insert into dbo.SALESORDERNOTE
(ID, DATEENTERED, TITLE, AUTHORID, TEXTNOTE, SALESORDERNOTETYPECODEID, SALESORDERID, HTMLNOTE, SALESORDERITEMID, ADDEDBYID, CHANGEDBYID, DATEADDED, DATECHANGED)
select
newid(), DATEENTERED, TITLE, AUTHORID, TEXTNOTE, SALESORDERNOTETYPECODEID, @SALESORDERID, HTMLNOTE, NEWSALESORDERITEMID, @CHANGEAGENTID, @CHANGEAGENTID, @CURRENTTIME, @CURRENTTIME
from @SALESORDERNOTESTOCOPY;
-- Delete discounts that apply to the items we're about to remove
if exists (select 1 from @UPDATEDITEMDISCOUNTS where NEWAMOUNT = 0)
delete from dbo.SALESORDERITEMITEMDISCOUNT
where ID in (select ID from @UPDATEDITEMDISCOUNTS where NEWAMOUNT = 0);
if exists (select 1 from @UPDATEDORDERDISCOUNTDETAILS where NEWAMOUNT = 0)
delete from dbo.SALESORDERITEMORDERDISCOUNTDETAIL
where ID in (select ID from @UPDATEDORDERDISCOUNTDETAILS where NEWAMOUNT = 0);
-- Delete SALESORDERNOTEs for the sales order items that we are about to delete so we
-- don't run into any foreign key constraint errors
delete from dbo.SALESORDERNOTE
where ID in (
select ID
from @SALESORDERNOTESTOCOPY NOTESTOCOPY
where DELETEORIGINAL = 1
);
-- Delete items whose new quantity or price is now zero (SALESORDERITEM cascades to SALESORDERITEMFEE when it's a fee and SALESORDERITEMTAX when it's a ticket item).
delete from dbo.SALESORDERITEM
where ID in (
select ID from @UPDATEDTICKETITEMS where NEWQUANTITY = 0
union all
select ID from @UPDATEDFEEITEMS where NEWPRICE = 0
);
-- Everything in the Sales domain should now be correctly updated; now adjust the tickets' line items.
-- The only reason we need to do this is because we have REVENUESPLITORDER instead of an explicit link from the SALESORDERITEM to its FINANCIALTRANSACTIONLINEITEM.
-- Since we join through EVENTID, and changing EVENTID is the whole point of this operation, we have to adjust the (otherwise completely irrelevant) financial records.
declare @ORDERREVENUEID uniqueidentifier = (select REVENUEID from dbo.SALESORDER where ID = @SALESORDERID);
declare @DEFAULTPOSTSTATUSCODE tinyint = (select case when ALLOWGLDISTRIBUTIONS = 1 then 1 else 3 end from dbo.PDACCOUNTSYSTEM);
declare @ORDERPOSTDATE date = null;
if @DEFAULTPOSTSTATUSCODE = 1 set @ORDERPOSTDATE = (select POSTDATE from dbo.FINANCIALTRANSACTION where ID = @ORDERREVENUEID);
declare @UPDATEDORDERLINEITEMS table (ID uniqueidentifier, FINANCIALTRANSACTIONID uniqueidentifier, EVENTID uniqueidentifier, DISCOUNTID uniqueidentifier, CREDITID uniqueidentifier, SOURCELINEITEMID uniqueidentifier, ORIGINALAMOUNT money, NEWAMOUNT money, POSTSTATUSCODE tinyint);
with ORIGINALTICKETSPLITS as (
select TICKETLI.ID, TICKETLI.BASEAMOUNT, TICKETLI.POSTSTATUSCODE, RSO.EVENTID
from dbo.FINANCIALTRANSACTIONLINEITEM TICKETLI
inner join dbo.REVENUESPLITORDER RSO on RSO.ID = TICKETLI.ID
where TICKETLI.FINANCIALTRANSACTIONID = @ORDERREVENUEID
and RSO.EVENTID is not null
and TICKETLI.DELETEDON is null
),
UPDATEDTICKETSPLITS as (
select
coalesce(ORIGINALTICKETSPLITS.ID, newid()) ID,
UPDATEDTICKETITEMS.EVENTID,
coalesce(ORIGINALTICKETSPLITS.BASEAMOUNT, 0) ORIGINALAMOUNT,
coalesce(ORIGINALTICKETSPLITS.BASEAMOUNT, 0) + sum(UPDATEDTICKETITEMS.NEWQUANTITY * UPDATEDTICKETITEMS.PRICE) - sum(UPDATEDTICKETITEMS.OLDQUANTITY * UPDATEDTICKETITEMS.PRICE) NEWAMOUNT,
coalesce(ORIGINALTICKETSPLITS.POSTSTATUSCODE, @DEFAULTPOSTSTATUSCODE) POSTSTATUSCODE
from @UPDATEDTICKETITEMS UPDATEDTICKETITEMS
left join ORIGINALTICKETSPLITS on UPDATEDTICKETITEMS.EVENTID = ORIGINALTICKETSPLITS.EVENTID
group by ORIGINALTICKETSPLITS.ID, UPDATEDTICKETITEMS.EVENTID, ORIGINALTICKETSPLITS.BASEAMOUNT, ORIGINALTICKETSPLITS.POSTSTATUSCODE
)
insert into @UPDATEDORDERLINEITEMS
select ID, @ORDERREVENUEID, EVENTID, null, null, null, ORIGINALAMOUNT, NEWAMOUNT, POSTSTATUSCODE
from UPDATEDTICKETSPLITS
where ORIGINALAMOUNT <> NEWAMOUNT;
with ORIGINALDISCOUNTSPLITS as (
select DISCOUNTLI.ID, DISCOUNTLI.BASEAMOUNT, DISCOUNTLI.POSTSTATUSCODE, DISCOUNTLI.SOURCELINEITEMID, EXT.DISCOUNTID, EXT.CREDITID
from dbo.FINANCIALTRANSACTIONLINEITEM DISCOUNTLI
inner join dbo.CREDITITEM_EXT EXT on EXT.ID = DISCOUNTLI.ID
inner join @UPDATEDORDERLINEITEMS TICKETLINEITEMS on TICKETLINEITEMS.ID = DISCOUNTLI.SOURCELINEITEMID
where DISCOUNTLI.FINANCIALTRANSACTIONID = @ORDERREVENUEID
and DISCOUNTLI.TYPECODE = 5
and DISCOUNTLI.DELETEDON is null
)
insert into @UPDATEDORDERLINEITEMS
-- Item discounts
select
coalesce(UPDATEDDISCOUNTSPLITS.ID, newid()) ID,
@ORDERREVENUEID,
null,
UPDATEDITEMDISCOUNTS.DISCOUNTID,
(select top 1 CREDITID from ORIGINALDISCOUNTSPLITS where DISCOUNTID = UPDATEDITEMDISCOUNTS.DISCOUNTID),
UPDATEDTICKETSPLITS.ID SOURCELINEITEMID,
coalesce(UPDATEDDISCOUNTSPLITS.BASEAMOUNT, 0) ORIGINALAMOUNT,
sum(UPDATEDITEMDISCOUNTS.NEWAMOUNT) NEWAMOUNT,
coalesce(UPDATEDDISCOUNTSPLITS.POSTSTATUSCODE, @DEFAULTPOSTSTATUSCODE) POSTSTATUSCODE
from @UPDATEDITEMDISCOUNTS UPDATEDITEMDISCOUNTS
inner join @UPDATEDTICKETITEMS UPDATEDTICKETITEMS on UPDATEDTICKETITEMS.ID = UPDATEDITEMDISCOUNTS.APPLIEDTOITEMID
inner join @UPDATEDORDERLINEITEMS UPDATEDTICKETSPLITS on UPDATEDTICKETSPLITS.EVENTID = UPDATEDTICKETITEMS.EVENTID
left join ORIGINALDISCOUNTSPLITS UPDATEDDISCOUNTSPLITS on (UPDATEDDISCOUNTSPLITS.SOURCELINEITEMID = UPDATEDTICKETSPLITS.ID and UPDATEDDISCOUNTSPLITS.DISCOUNTID = UPDATEDITEMDISCOUNTS.DISCOUNTID)
group by UPDATEDDISCOUNTSPLITS.ID, UPDATEDDISCOUNTSPLITS.BASEAMOUNT, UPDATEDTICKETSPLITS.ID, UPDATEDITEMDISCOUNTS.DISCOUNTID, UPDATEDDISCOUNTSPLITS.CREDITID, UPDATEDDISCOUNTSPLITS.POSTSTATUSCODE
having coalesce(UPDATEDDISCOUNTSPLITS.BASEAMOUNT, 0) <> sum(UPDATEDITEMDISCOUNTS.NEWAMOUNT)
union all
-- Order discounts
select
coalesce(UPDATEDDISCOUNTSPLITS.ID, newid()) ID,
@ORDERREVENUEID,
null,
UPDATEDORDERDISCOUNTDETAILS.DISCOUNTID,
(select top 1 CREDITID from ORIGINALDISCOUNTSPLITS where DISCOUNTID = UPDATEDORDERDISCOUNTDETAILS.DISCOUNTID or (DISCOUNTID is null and UPDATEDORDERDISCOUNTDETAILS.DISCOUNTID is null)),
UPDATEDTICKETSPLITS.ID SOURCELINEITEMID,
coalesce(UPDATEDDISCOUNTSPLITS.BASEAMOUNT, 0) ORIGINALAMOUNT,
sum(UPDATEDORDERDISCOUNTDETAILS.NEWAMOUNT) NEWAMOUNT,
coalesce(UPDATEDDISCOUNTSPLITS.POSTSTATUSCODE, @DEFAULTPOSTSTATUSCODE) POSTSTATUSCODE
from @UPDATEDORDERDISCOUNTDETAILS UPDATEDORDERDISCOUNTDETAILS
inner join @UPDATEDTICKETITEMS UPDATEDTICKETITEMS on UPDATEDTICKETITEMS.ID = UPDATEDORDERDISCOUNTDETAILS.APPLIEDTOITEMID
inner join @UPDATEDORDERLINEITEMS UPDATEDTICKETSPLITS on UPDATEDTICKETSPLITS.EVENTID = UPDATEDTICKETITEMS.EVENTID
left join ORIGINALDISCOUNTSPLITS UPDATEDDISCOUNTSPLITS on (UPDATEDDISCOUNTSPLITS.SOURCELINEITEMID = UPDATEDTICKETSPLITS.ID and (UPDATEDDISCOUNTSPLITS.DISCOUNTID = UPDATEDORDERDISCOUNTDETAILS.DISCOUNTID or (UPDATEDDISCOUNTSPLITS.DISCOUNTID is null and UPDATEDORDERDISCOUNTDETAILS.DISCOUNTID is null)))
group by UPDATEDDISCOUNTSPLITS.ID, UPDATEDDISCOUNTSPLITS.BASEAMOUNT, UPDATEDTICKETSPLITS.ID, UPDATEDORDERDISCOUNTDETAILS.DISCOUNTID, UPDATEDDISCOUNTSPLITS.CREDITID, UPDATEDDISCOUNTSPLITS.POSTSTATUSCODE
having coalesce(UPDATEDDISCOUNTSPLITS.BASEAMOUNT, 0) <> sum(UPDATEDORDERDISCOUNTDETAILS.NEWAMOUNT)
-- Determine which line items to adjust. We'll reduce their value or delete them, and then add new line items for the new events.
-- Some may be posted and some not yet posted in the same reschedule operation (for example, if they reschedule twice in a row with a different group of tickets).
declare @ORDERADJUSTMENTID uniqueidentifier;
declare @POSTEDORDERLINEITEMS dbo.UDT_GENERICID;
declare @NOTPOSTEDORDERLINEITEMS dbo.UDT_GENERICID;
insert into @POSTEDORDERLINEITEMS
select ID from @UPDATEDORDERLINEITEMS
where POSTSTATUSCODE = 2 and ORIGINALAMOUNT <> 0;
insert into @NOTPOSTEDORDERLINEITEMS
select ID from @UPDATEDORDERLINEITEMS
where POSTSTATUSCODE <> 2 and ORIGINALAMOUNT <> 0;
if exists (select 1 from @POSTEDORDERLINEITEMS)
begin
-- Create the "Adjustment" record and the reversal line items
exec dbo.USP_SAVE_ADJUSTMENT_FOR_SPECIFIC_LINEITEMS @ORDERREVENUEID, @POSTEDORDERLINEITEMS, @ORDERADJUSTMENTID output, @CHANGEAGENTID, @CURRENTTIME, @CURRENTTIME, @ORDERPOSTDATE, 'Ticket Reschedule';
end
else begin
-- If this is not the first reschedule on the posted order, we may already have an adjustment ID that we want to link the new line items to.
set @ORDERADJUSTMENTID = (
select top 1 FINANCIALTRANSACTIONLINEITEMADJUSTMENTID
from dbo.FINANCIALTRANSACTIONLINEITEM
where FINANCIALTRANSACTIONID = @ORDERREVENUEID
and POSTSTATUSCODE = 1
and FINANCIALTRANSACTIONLINEITEMADJUSTMENTID is not null
);
end
if exists (select 1 from @NOTPOSTEDORDERLINEITEMS)
begin
-- Non-posted line items don't get adjusted (the adjustment SP will actually throw an error if you try to adjust non-posted line items)
-- However, we need to delete their GL, or else it won't be recreated by USP_SAVE_REVENUEGLDISTRIBUTION.
delete from dbo.JOURNALENTRY where FINANCIALTRANSACTIONLINEITEMID in (select ID from @NOTPOSTEDORDERLINEITEMS);
end
-- Update existing order line items. We can't delete the $0 ones yet because they are still referenced by payment line items, but we have to set them to $0 to regenerate payment LIs correctly.
update dbo.FINANCIALTRANSACTIONLINEITEM
set BASEAMOUNT = UPDATEDORDERLINEITEMS.NEWAMOUNT, TRANSACTIONAMOUNT = UPDATEDORDERLINEITEMS.NEWAMOUNT, ORGAMOUNT = UPDATEDORDERLINEITEMS.NEWAMOUNT, UNITVALUE = case when UPDATEDORDERLINEITEMS.EVENTID is null then UPDATEDORDERLINEITEMS.NEWAMOUNT else 0 end
from @UPDATEDORDERLINEITEMS UPDATEDORDERLINEITEMS
where FINANCIALTRANSACTIONLINEITEM.ID = UPDATEDORDERLINEITEMS.ID
and ORIGINALAMOUNT <> 0
and NEWAMOUNT <> ORIGINALAMOUNT;
-- Ticket line items
insert into dbo.FINANCIALTRANSACTIONLINEITEM
(ID, FINANCIALTRANSACTIONID, TYPECODE, BASEAMOUNT, TRANSACTIONAMOUNT, ORGAMOUNT, POSTSTATUSCODE, POSTDATE, FINANCIALTRANSACTIONLINEITEMADJUSTMENTID, ADDEDBYID, CHANGEDBYID, DATEADDED, DATECHANGED)
select
ID, FINANCIALTRANSACTIONID, 0, NEWAMOUNT, NEWAMOUNT, NEWAMOUNT, @DEFAULTPOSTSTATUSCODE, @ORDERPOSTDATE, @ORDERADJUSTMENTID, @CHANGEAGENTID, @CHANGEAGENTID, @CURRENTTIME, @CURRENTTIME
from @UPDATEDORDERLINEITEMS
where EVENTID is not null
and ORIGINALAMOUNT = 0;
-- Discount line items
insert into dbo.FINANCIALTRANSACTIONLINEITEM
(ID, FINANCIALTRANSACTIONID, TYPECODE, SOURCELINEITEMID, BASEAMOUNT, TRANSACTIONAMOUNT, ORGAMOUNT, UNITVALUE, POSTSTATUSCODE, POSTDATE, FINANCIALTRANSACTIONLINEITEMADJUSTMENTID, ADDEDBYID, CHANGEDBYID, DATEADDED, DATECHANGED)
select
ID, FINANCIALTRANSACTIONID, 5, SOURCELINEITEMID, NEWAMOUNT, NEWAMOUNT, NEWAMOUNT, NEWAMOUNT, @DEFAULTPOSTSTATUSCODE, @ORDERPOSTDATE, @ORDERADJUSTMENTID, @CHANGEAGENTID, @CHANGEAGENTID, @CURRENTTIME, @CURRENTTIME
from @UPDATEDORDERLINEITEMS
where EVENTID is null
and ORIGINALAMOUNT = 0;
insert into dbo.REVENUESPLIT_EXT
(ID, TYPECODE, APPLICATIONCODE, ADDEDBYID, CHANGEDBYID, DATEADDED, DATECHANGED)
select
ID, 5, 10, @CHANGEAGENTID, @CHANGEAGENTID, @CURRENTTIME, @CURRENTTIME
from @UPDATEDORDERLINEITEMS
where EVENTID is not null
and ORIGINALAMOUNT = 0;
insert into dbo.CREDITITEM_EXT
(ID, CREDITID, TYPECODE, DISCOUNTID, ADDEDBYID, CHANGEDBYID, DATEADDED, DATECHANGED)
select
ID, CREDITID, 0, DISCOUNTID, @CHANGEAGENTID, @CHANGEAGENTID, @CURRENTTIME, @CURRENTTIME
from @UPDATEDORDERLINEITEMS DISCOUNTLIS
where EVENTID is null -- Can't use "DISCOUNTID is not null" because it's also null for Adjustable discounts.
and ORIGINALAMOUNT = 0;
insert into dbo.REVENUESPLITORDER
(ID, PROGRAMID, EVENTID, ADDEDBYID, CHANGEDBYID, DATEADDED, DATECHANGED)
select
UPDATEDORDERLINEITEMS.ID, EVENT.PROGRAMID, EVENT.ID, @CHANGEAGENTID, @CHANGEAGENTID, @CURRENTTIME, @CURRENTTIME
from @UPDATEDORDERLINEITEMS UPDATEDORDERLINEITEMS
inner join dbo.EVENT on EVENT.ID = UPDATEDORDERLINEITEMS.EVENTID
where UPDATEDORDERLINEITEMS.ORIGINALAMOUNT = 0;
if @DEFAULTPOSTSTATUSCODE <> 3
begin
exec dbo.USP_SAVE_REVENUEGLDISTRIBUTION @ORDERREVENUEID, @CHANGEAGENTID, @CURRENTTIME;
declare @CREDITID uniqueidentifier;
declare discount_cursor cursor local fast_forward for (select distinct CREDITID from @UPDATEDORDERLINEITEMS);
open discount_cursor;
fetch next from discount_cursor into @CREDITID;
while @@FETCH_STATUS = 0
begin
exec dbo.USP_SALESORDER_CREATEDISCOUNTGLDISTRIBUTION @CREDITID, @CHANGEAGENTID, @CURRENTTIME;
fetch next from discount_cursor into @CREDITID;
end
close discount_cursor;
deallocate discount_cursor;
end
declare @PAYMENTS table (ID uniqueidentifier, POSTDATE date, DEPOSITID uniqueidentifier, ADJUSTMENTID uniqueidentifier);
insert into @PAYMENTS (ID, POSTDATE, DEPOSITID)
select FT.ID, FT.POSTDATE, DEPOSITPAYMENT.DEPOSITID
from dbo.FINANCIALTRANSACTION FT
inner join dbo.SALESORDERPAYMENT SOP on SOP.PAYMENTID = FT.ID
left join dbo.BANKACCOUNTDEPOSITPAYMENT DEPOSITPAYMENT on DEPOSITPAYMENT.ID = FT.ID
where SOP.SALESORDERID = @SALESORDERID
and FT.TYPECODE = 0;
declare @PAYMENTID uniqueidentifier, @PAYMENTPOSTDATE date;
declare payment_cursor cursor local fast_forward for (
select ID, POSTDATE from @PAYMENTS
);
-- TODO: find a way to reallocate the line items that apply to tickets, without redoing all the payments every time.
open payment_cursor;
fetch next from payment_cursor into @PAYMENTID, @PAYMENTPOSTDATE;
while @@FETCH_STATUS = 0
begin
declare @PAYMENTADJUSTMENTID uniqueidentifier;
declare @POSTEDPAYMENTLINEITEMS dbo.UDT_GENERICID;
declare @NOTPOSTEDPAYMENTLINEITEMS dbo.UDT_GENERICID;
insert into @POSTEDPAYMENTLINEITEMS
select ID from dbo.FINANCIALTRANSACTIONLINEITEM
where FINANCIALTRANSACTIONID = @PAYMENTID
and POSTSTATUSCODE = 2
and TYPECODE = 0
and DELETEDON is null;
insert into @NOTPOSTEDPAYMENTLINEITEMS
select ID from dbo.FINANCIALTRANSACTIONLINEITEM
where FINANCIALTRANSACTIONID = @PAYMENTID
and POSTSTATUSCODE <> 2
and TYPECODE = 0
and DELETEDON is null;
if exists (select 1 from @POSTEDPAYMENTLINEITEMS)
begin
-- Create the "Adjustment" record and the reversal line items
exec dbo.USP_SAVE_ADJUSTMENT_FOR_SPECIFIC_LINEITEMS @PAYMENTID, @POSTEDPAYMENTLINEITEMS, @PAYMENTADJUSTMENTID output, @CHANGEAGENTID, @CURRENTTIME, @CURRENTTIME, @PAYMENTPOSTDATE, 'Ticket Reschedule';
end
else begin
-- If this is not the first reschedule on the posted order, we may already have a payment adjustment ID that we want to link the new line items to.
set @PAYMENTADJUSTMENTID = (
select top 1 FINANCIALTRANSACTIONLINEITEMADJUSTMENTID
from dbo.FINANCIALTRANSACTIONLINEITEM
where FINANCIALTRANSACTIONID = @PAYMENTID
and POSTSTATUSCODE = 1
and FINANCIALTRANSACTIONLINEITEMADJUSTMENTID is not null
);
end
if @PAYMENTADJUSTMENTID is not null
update @PAYMENTS set ADJUSTMENTID = @PAYMENTADJUSTMENTID where ID = @PAYMENTID;
if exists (select 1 from @NOTPOSTEDPAYMENTLINEITEMS)
begin
-- Non-posted line items don't get adjusted (the adjustment SP will actually throw an error if you try to adjust non-posted line items)
-- However, we need to delete their GL, or else it won't be recreated by USP_SAVE_REVENUEGLDISTRIBUTION.
delete from dbo.JOURNALENTRY where FINANCIALTRANSACTIONLINEITEMID in (select ID from @NOTPOSTEDPAYMENTLINEITEMS);
end
-- Currently have to delete all of the original line items after adjusting so that ADDPAYMENTREVENUE will recreate them.
update dbo.FINANCIALTRANSACTIONLINEITEM
set REVERSEDLINEITEMID = null, CHANGEDBYID = @CHANGEAGENTID, DATECHANGED = @CURRENTTIME
where REVERSEDLINEITEMID in (select ID from @POSTEDPAYMENTLINEITEMS);
delete from dbo.FINANCIALTRANSACTIONLINEITEM
where FINANCIALTRANSACTIONID = @PAYMENTID
and TYPECODE = 0
and POSTSTATUSCODE <> 2
and DELETEDON is null;
fetch next from payment_cursor into @PAYMENTID, @PAYMENTPOSTDATE;
end
close payment_cursor;
deallocate payment_cursor;
-- Prepare to delete $0 order line items by eliminating FKs.
update dbo.FINANCIALTRANSACTIONLINEITEM
set REVERSEDLINEITEMID = null, CHANGEDBYID = @CHANGEAGENTID, DATECHANGED = @CURRENTTIME
where REVERSEDLINEITEMID in (select ID from @UPDATEDORDERLINEITEMS where NEWAMOUNT = 0);
update dbo.FINANCIALTRANSACTIONLINEITEM
set SOURCELINEITEMID = null, CHANGEDBYID = @CHANGEAGENTID, DATECHANGED = @CURRENTTIME
where SOURCELINEITEMID in (select ID from @UPDATEDORDERLINEITEMS where NEWAMOUNT = 0);
update dbo.JOURNALENTRY_EXT
set CREDITITEMID = null, CHANGEDBYID = @CHANGEAGENTID, DATECHANGED = @CURRENTTIME
where CREDITITEMID in (select ID from @UPDATEDORDERLINEITEMS where EVENTID is null and NEWAMOUNT = 0);
-- Delete $0 order line items before recreating payment line items. First discounts, then tickets (due to the same table reference).
delete from dbo.FINANCIALTRANSACTIONLINEITEM
where FINANCIALTRANSACTIONID = @ORDERREVENUEID
and ID in (select ID from @UPDATEDORDERLINEITEMS where EVENTID is null and NEWAMOUNT = 0);
delete from dbo.FINANCIALTRANSACTIONLINEITEM
where FINANCIALTRANSACTIONID = @ORDERREVENUEID
and ID in (select ID from @UPDATEDORDERLINEITEMS where EVENTID is not null and NEWAMOUNT = 0);
-- Recreate all payment line items.
exec dbo.USP_SALESORDER_ADDPAYMENTREVENUE @SALESORDERID, @ORDERREVENUEID, @CHANGEAGENTID, @CURRENTTIME;
-- Update adjustment IDs on new line items where needed.
update dbo.FINANCIALTRANSACTIONLINEITEM
set FINANCIALTRANSACTIONLINEITEMADJUSTMENTID = PAYMENT.ADJUSTMENTID,
POSTDATE = PAYMENT.POSTDATE,
CHANGEDBYID = @CHANGEAGENTID,
DATECHANGED = @CURRENTTIME
from @PAYMENTS PAYMENT
where FINANCIALTRANSACTIONID = PAYMENT.ID
and PAYMENT.ADJUSTMENTID is not null
and POSTSTATUSCODE = 1
and TYPECODE = 0
and FINANCIALTRANSACTIONLINEITEMADJUSTMENTID is null;
-- Fix debit GL distributions for deposited payments.
declare @PAYMENTDEPOSITID uniqueidentifier;
declare deposit_cursor cursor local fast_forward for (
select ID, DEPOSITID from @PAYMENTS where DEPOSITID is not null
);
open deposit_cursor;
fetch next from deposit_cursor into @PAYMENTID, @PAYMENTDEPOSITID;
while @@FETCH_STATUS = 0
begin
exec dbo.USP_BANKACCOUNTDEPOSIT_OVERWRITEPAYMENTDEBITACCOUNTS @PAYMENTID, @PAYMENTDEPOSITID;
fetch next from deposit_cursor into @PAYMENTID, @PAYMENTDEPOSITID;
end
end try
begin catch
exec dbo.USP_RAISE_ERROR;
return 1;
end catch
return 0;
end