UFN_CREDIT_GETSALESORDERITEMS2
Return
Return Type |
---|
table |
Parameters
Parameter | Parameter Type | Mode | Description |
---|---|---|---|
@SALESORDERID | uniqueidentifier | IN |
Definition
Copy
CREATE function dbo.UFN_CREDIT_GETSALESORDERITEMS2
(
@SALESORDERID uniqueidentifier
)
returns @SALESORDERITEMS table
(
SALESORDERITEMID uniqueidentifier,
[DESCRIPTION] nvarchar(510),
PRICE money,
DISCOUNTS money,
AMOUNTPAID money,
TYPECODE tinyint,
PROGRAMID uniqueidentifier, --program id for tickets, merchandise department id for merch
ISCOMBINATION bit,
EVENTREGISTRANTID uniqueidentifier, -- special event registrant id (not for preregistered)
ITEMID uniqueidentifier, -- represents TICKET.ID, MERCHANDISEUNIT.ID, SALESORDERITEMTICKETFEE.ID, MEMBERSHIPTRANSACTION.ID, or MEMBERSHIPADDON.ID.
REVENUESPLITID uniqueidentifier,
HASCONTRIBUTEDREVENUE bit,
TICKETNUMBER bigint,
SORTFIELD nvarchar(200),
PARENTITEMID uniqueidentifier
)
begin
-- Adding this table to save some performance tax later on when linking back to the revenue split for the item
declare @ITEMS table
(
SALESORDERITEMID uniqueidentifier,
[DESCRIPTION] nvarchar(510),
PRICE money,
DISCOUNTS money,
AMOUNTPAID money,
TYPECODE tinyint,
PROGRAMID uniqueidentifier,
ISCOMBINATION bit,
ITEMID uniqueidentifier,
REVENUESPLITID uniqueidentifier,
MEMBERSHIPTRANSACTIONID uniqueidentifier,
/*
Fields used to link back to the order split for the item for
the cases that we have to get it from REVENUESPLITORDER
*/
EVENTID uniqueidentifier,
DESIGNATIONID uniqueidentifier,
FEEID uniqueidentifier,
MERCHANDISEPRODUCTINSTANCEID uniqueidentifier,
EVENTREGISTRANTID uniqueidentifier,
/*
end REVENUESPLITORDER link fields
*/
HASCONTRIBUTEDREVENUE bit,
APPLIESTOITEMSORTCRITERIA nvarchar(300), -- Used only in the final select to group item-level fees with the items they apply to.
TICKETNUMBER bigint,
PARENTITEMID uniqueidentifier -- Each membership addon item will include the MEMBERSHIPTRANSACTIONID for the transaction being refunded (in case the order includes multiple memberships).
);
declare @CALCULATEDFIELDS table (
SALESORDERITEMID uniqueidentifier,
DISCOUNTS money,
PROGRAMID uniqueidentifier, -- program id for tickets, merchandise department id for merch
ITEMID uniqueidentifier,
TICKETNUMBER bigint
);
-- We get order-level fees from this table variable, but not item-level. Really, we shouldn't be inserting the item-level fees.
insert into @CALCULATEDFIELDS
select
SALESORDERITEM.ID,
case SALESORDERITEM.TYPECODE
when 0 then TICKET.ITEMLEVELDISCOUNTSAPPLIED + TICKET.ORDERLEVELDISCOUNTSAPPLIED
when 1 then isnull(MEMBERSHIPPROMOAMOUNT.AMOUNT, 0) + SALESORDERITEMMEMBERSHIPITEMPROMOTIONAMOUNT.AMOUNT
when 14 then MERCHUNIT.ITEMLEVELDISCOUNTSAPPLIED + MERCHUNIT.ORDERLEVELDISCOUNTSAPPLIED
else 0
end as DISCOUNTS,
case SALESORDERITEM.TYPECODE
when 0 then SALESORDERITEMTICKET.PROGRAMID -- tickets
when 14 then SALESORDERITEMMERCHANDISE.MERCHANDISEDEPARTMENTID -- merchandise
else null
end PROGRAMID,
case
when SALESORDERITEM.TYPECODE = 0 then TICKET.ID
when SALESORDERITEM.TYPECODE = 14 then MERCHUNIT.ID
when SALESORDERITEM.TYPECODE = 1 then SALESORDERITEMMEMBERSHIP.MEMBERSHIPTRANSACTIONID
when SALESORDERITEM.TYPECODE = 16 then SALESORDERITEMMEMBERSHIPADDON.MEMBERSHIPADDONID
else null
end ITEMID,
TICKET.TICKETNUMBER
from dbo.SALESORDERITEM
left join dbo.SALESORDERITEMTICKET on SALESORDERITEM.ID = SALESORDERITEMTICKET.ID
left join dbo.TICKET on TICKET.SALESORDERITEMTICKETID = SALESORDERITEMTICKET.ID
left join dbo.SALESORDERITEMMERCHANDISE on SALESORDERITEM.ID = SALESORDERITEMMERCHANDISE.ID
left join dbo.SALESORDERITEMMERCHANDISEUNIT MERCHUNIT on MERCHUNIT.SALESORDERITEMMERCHANDISEID = SALESORDERITEMMERCHANDISE.ID
left join dbo.SALESORDERITEMMEMBERSHIP on SALESORDERITEMMEMBERSHIP.ID = SALESORDERITEM.ID
left join dbo.SALESORDERITEMMEMBERSHIPADDON on SALESORDERITEMMEMBERSHIPADDON.ID = SALESORDERITEM.ID
outer apply (
select SALESORDERITEM.QUANTITY - coalesce((
select sum(FTLI.QUANTITY)
from dbo.FINANCIALTRANSACTIONLINEITEM FTLI
inner join dbo.CREDITITEM_EXT EXT on EXT.ID = FTLI.ID
where EXT.SALESORDERITEMID = SALESORDERITEM.ID
),0)
as QUANTITY
) QUANTITYREMAINING
left join dbo.NUMBERS on (SALESORDERITEMMEMBERSHIPADDON.ID is not null and NUMBERS.NUM < QUANTITYREMAINING.QUANTITY)
outer apply (
select
case
when MEMBERSHIPPROMOITEM.[PERCENT] > 0 then SALESORDERITEM.TOTAL * MEMBERSHIPPROMOITEM.[PERCENT] * 0.01
else MEMBERSHIPPROMOITEM.PRICE
end AMOUNT
from dbo.SALESORDERITEM as MEMBERSHIPPROMOITEM
inner join dbo.SALESORDERITEMMEMBERSHIPPROMO on SALESORDERITEMMEMBERSHIPPROMO.ID = SALESORDERITEM.ID
where
MEMBERSHIPPROMOITEM.SALESORDERID = @SALESORDERID
and MEMBERSHIPPROMOITEM.PRICE > 0
and SALESORDERITEMMEMBERSHIPPROMO.INUSE = 1
) as MEMBERSHIPPROMOAMOUNT
outer apply (
select isnull(sum(SALESORDERITEMMEMBERSHIPITEMPROMOTION.AMOUNT), 0) as AMOUNT
from dbo.SALESORDERITEMMEMBERSHIPITEMPROMOTION
where SALESORDERITEMMEMBERSHIPITEMPROMOTION.SALESORDERITEMID = SALESORDERITEM.ID
) as SALESORDERITEMMEMBERSHIPITEMPROMOTIONAMOUNT
where
SALESORDERITEM.SALESORDERID = @SALESORDERID
and QUANTITYREMAINING.QUANTITY > 0
and (TICKET.ID is null or (TICKET.ISREFUNDED = 0 and TICKET.APPLIEDTOMEMBERSHIP = 0)) -- Don't include refunded, or applied tickets.
and (MERCHUNIT.ID is null or MERCHUNIT.REFUNDEDAMOUNT = 0) -- Don't include refunded merchandise items
and SALESORDERITEM.TYPECODE <> 5; -- Don't include discounts
insert into @ITEMS
select
SALESORDERITEM.ID SALESORDERITEMID,
-- Combo tickets have the same description as regular tickets, but with a prefix indicating the combo name and ticket grouping
case
when SALESORDERITEMTICKETCOMBINATION.ID is not null
then COMBINATION.NAME + ' ' + cast(COMBOTICKETNUMBERS.TICKETGROUPNUMBER as nvarchar(3)) + ' - '
else ''
end + case
when SALESORDERITEM.TYPECODE = 0 and SALESORDERITEMTICKET.EVENTID is not null
then SALESORDERITEM.[DESCRIPTION] + ' - ' + convert(nvarchar(8),[EVENT].STARTDATE, 1) + ' ' + dbo.UFN_HOURMINUTE_DISPLAYTIME([EVENT].STARTTIME)
when SALESORDERITEM.TYPECODE = 6
then dbo.UFN_CONSTITUENT_BUILDNAME(REGISTRANT.CONSTITUENTID) + ' - ' + SALESORDERITEM.[DESCRIPTION]
else
SALESORDERITEM.[DESCRIPTION]
end [DESCRIPTION],
SALESORDERITEM.PRICE,
CALCULATEDFIELDS.DISCOUNTS,
SALESORDERITEM.PRICE - CALCULATEDFIELDS.DISCOUNTS as AMOUNTPAID,
SALESORDERITEM.TYPECODE,
CALCULATEDFIELDS.PROGRAMID,
case when COMBINATION.ID is not null then 1 else 0 end ISCOMBINATION,
CALCULATEDFIELDS.ITEMID,
-- We already have the addon/transaction, so grab the revenuesplitid now for memberships/addons
case
when SALESORDERITEM.TYPECODE = 16 then MEMBERSHIPADDON.REVENUESPLITID
when SALESORDERITEM.TYPECODE = 1 then MEMBERSHIPTRANSACTION.REVENUESPLITID
else null
end REVENUESPLITID,
case
when SALESORDERITEM.TYPECODE = 16 then MEMBERSHIPADDON.MEMBERSHIPTRANSACTIONID
else SALESORDERITEMMEMBERSHIP.MEMBERSHIPTRANSACTIONID
end MEMBERSHIPTRANSACTIONID,
SALESORDERITEMTICKET.EVENTID,
SALESORDERITEMDONATION.DESIGNATIONID,
SALESORDERITEMFEE.FEEID,
SALESORDERITEMMERCHANDISE.MERCHANDISEPRODUCTINSTANCEID,
SALESORDERITEMEVENTREGISTRATION.REGISTRANTID EVENTREGISTRANTID,
0 HASCONTRIBUTEDREVENUE,
null APPLIESTOITEMSORTCRITERIA,
CALCULATEDFIELDS.TICKETNUMBER,
MEMBERSHIPADDON.MEMBERSHIPTRANSACTIONID as PARENTITEMID
from dbo.SALESORDERITEM
inner join @CALCULATEDFIELDS as CALCULATEDFIELDS on SALESORDERITEM.ID = CALCULATEDFIELDS.SALESORDERITEMID
left join dbo.SALESORDERITEMTICKET on SALESORDERITEM.ID = SALESORDERITEMTICKET.ID
left join dbo.SALESORDERITEMTICKETCOMBINATION SALESORDERITEMTICKETCOMBINATION on SALESORDERITEMTICKET.ID = SALESORDERITEMTICKETCOMBINATION.ID
left join dbo.COMBINATION on SALESORDERITEMTICKETCOMBINATION.COMBINATIONID = COMBINATION.ID
left join dbo.UFN_SALESORDER_GETDETERMINISTICCOMBOTICKETNUMBERS(@SALESORDERID) as COMBOTICKETNUMBERS on COMBOTICKETNUMBERS.TICKETID = CALCULATEDFIELDS.ITEMID
left join dbo.[EVENT] on SALESORDERITEMTICKET.EVENTID = [EVENT].ID
left join dbo.SALESORDERITEMFEE on dbo.SALESORDERITEMFEE.ID = dbo.SALESORDERITEM.ID
left join dbo.SALESORDERITEMEVENTREGISTRATION on SALESORDERITEM.ID = SALESORDERITEMEVENTREGISTRATION.ID
left join dbo.REGISTRANT on REGISTRANT.ID = SALESORDERITEMEVENTREGISTRATION.REGISTRANTID
left join dbo.SALESORDERITEMMEMBERSHIPADDON on SALESORDERITEMMEMBERSHIPADDON.ID = SALESORDERITEM.ID
left join dbo.MEMBERSHIPADDON on MEMBERSHIPADDON.ID = SALESORDERITEMMEMBERSHIPADDON.MEMBERSHIPADDONID
left join dbo.SALESORDERITEMMEMBERSHIP on SALESORDERITEMMEMBERSHIP.ID = SALESORDERITEM.ID
left join dbo.MEMBERSHIPTRANSACTION on SALESORDERITEMMEMBERSHIP.MEMBERSHIPTRANSACTIONID = MEMBERSHIPTRANSACTION.ID
left join dbo.SALESORDERITEMDONATION on SALESORDERITEMDONATION.ID = SALESORDERITEM.ID
left join dbo.SALESORDERITEMMERCHANDISE on SALESORDERITEMMERCHANDISE.ID = SALESORDERITEM.ID
where
SALESORDERITEM.SALESORDERID = @SALESORDERID
and (SALESORDERITEM.TYPECODE in (0, 1, 2, 6, 14, 16) or (SALESORDERITEM.TYPECODE = 3 and SALESORDERITEMFEE.APPLIESTOCODE = 0));
insert into @ITEMS -- itemized item-level fees, which as of 10/2013 only apply to ticket items.
select
ITEM.ID SALESORDERITEMID,
ITEM.[DESCRIPTION],
SALESORDERITEMTICKETFEE.AMOUNT PRICE,
0 DISCOUNTS,
SALESORDERITEMTICKETFEE.AMOUNT AMOUNTPAID,
3 TYPECODE,
null PROGRAMID,
case when COMBOITEM.ID is null then 0 else 1 end ISCOMBINATION, -- Mark the fees applied to combos as also combos (for ordering purposes only)
SALESORDERITEMTICKETFEE.ID ITEMID,
null REVENUESPLITID,
null MEMBERSHIPTRANSACTIONID,
null EVENTID,
null DESIGNATIONID,
FEEITEM.FEEID,
null MERCHANDISEPRODUCTINSTANCEID,
null EVENTREGISTRANTID,
0 HASCONTRIBUTEDREVENUE,
coalesce((select [DESCRIPTION] + cast(ITEMID as nvarchar(36)) from @ITEMS where ITEMID = SALESORDERITEMTICKETFEE.TICKETID),'Z') APPLIESTOITEMSORTCRITERIA,
null TICKETNUMBER,
null PARENTITEMID
from dbo.SALESORDERITEMTICKETFEE
inner join dbo.SALESORDERITEMFEE FEEITEM on FEEITEM.ID = SALESORDERITEMTICKETFEE.SALESORDERITEMFEEID
inner join dbo.SALESORDERITEM ITEM on ITEM.ID = FEEITEM.ID
left join dbo.SALESORDERITEMTICKETCOMBINATION COMBOITEM on COMBOITEM.ID = FEEITEM.SALESORDERITEMID
where ITEM.SALESORDERID = @SALESORDERID
and SALESORDERITEMTICKETFEE.REFUNDEDAMOUNT = 0; -- Under current design, if the fee has been partially refunded we won't show it.
/*
Update the revenuesplitid field in a separate step since $0 sales order items don't
generate a revenue split if they are the only item of that category (ie only ticket
for that program). Due to this behavior, the above query would require more complex
logic to detect this case. The performance impact is less strenuous if the revenue
split field is updated here for items that do have an associated split.
*/
update ITEMS
set
REVENUESPLITID = FTLI.ID
from @ITEMS ITEMS
inner join dbo.SALESORDERITEM on SALESORDERITEM.ID = ITEMS.SALESORDERITEMID
inner join dbo.SALESORDER on SALESORDER.ID = SALESORDERITEM.SALESORDERID
left join dbo.EVENTREGISTRANTPAYMENT on ITEMS.EVENTREGISTRANTID = EVENTREGISTRANTPAYMENT.REGISTRANTID
left join dbo.FINANCIALTRANSACTIONLINEITEM FTLI on FTLI.FINANCIALTRANSACTIONID = SALESORDER.REVENUEID
left join dbo.REVENUESPLIT_EXT on FTLI.ID = REVENUESPLIT_EXT.ID
left join dbo.REVENUESPLITORDER on FTLI.ID = REVENUESPLITORDER.ID
-- Membership addons and memberships have already had their revenuesplits populated
where ITEMS.REVENUESPLITID is null
and (
-- Tickets
SALESORDERITEM.TYPECODE <> 0
or (
REVENUESPLITORDER.PROGRAMID = ITEMS.PROGRAMID
and (ITEMS.EVENTID is null or REVENUESPLITORDER.EVENTID = ITEMS.EVENTID)
)
)
and (
-- Donations
SALESORDERITEM.TYPECODE <> 2 or REVENUESPLIT_EXT.DESIGNATIONID = ITEMS.DESIGNATIONID
)
and (
-- Fees
SALESORDERITEM.TYPECODE <> 3 or REVENUESPLITORDER.FEEID = ITEMS.FEEID
)
and (
-- Event registration
SALESORDERITEM.TYPECODE <> 6 or EVENTREGISTRANTPAYMENT.PAYMENTID = FTLI.ID
)
and (
-- Merchandise
SALESORDERITEM.TYPECODE <> 14 or REVENUESPLITORDER.MERCHANDISEPRODUCTINSTANCEID = ITEMS.MERCHANDISEPRODUCTINSTANCEID
);
--Update it if it has contributed revenue
with CONTRIBUTEDREVENUE_CTE as
(
select
case
when sum(FTLI.TRANSACTIONAMOUNT) > 0 then 1
else 0
end HASCONTRIBUTEDREVENUE,
I.REVENUESPLITID as ID
from @ITEMS I
inner join dbo.FINANCIALTRANSACTIONLINEITEM FTLI on FTLI.SOURCELINEITEMID = I.REVENUESPLITID
inner join dbo.REVENUESPLIT_EXT on REVENUESPLIT_EXT.ID = FTLI.ID
where REVENUESPLIT_EXT.TYPECODE = 0
and REVENUESPLIT_EXT.TYPECODE = 0 -- Gift type
and REVENUESPLIT_EXT.APPLICATIONCODE in (0,1) -- Gift or Event Registration application (membership contributions apply to "Donation", ER contributions apply to "Event Registration")
and FTLI.TYPECODE = 0 -- Standard line items (exclude reversals, etc.)
group by I.REVENUESPLITID
)
update @ITEMS
set HASCONTRIBUTEDREVENUE = CTE.HASCONTRIBUTEDREVENUE
from CONTRIBUTEDREVENUE_CTE CTE where CTE.ID = REVENUESPLITID;
insert into @SALESORDERITEMS
select
SALESORDERITEMID,
[DESCRIPTION],
PRICE,
-DISCOUNTS,
AMOUNTPAID,
TYPECODE,
PROGRAMID,
ISCOMBINATION,
EVENTREGISTRANTID,
ITEMID,
REVENUESPLITID,
HASCONTRIBUTEDREVENUE,
TICKETNUMBER,
left(case
when TYPECODE = 3 and ITEMID is not null then '00' -- group item-level fees with tickets
when TYPECODE = 3 and ITEMID is null then '99' -- order-level fees come last
when TYPECODE = 16 then '01' -- group add-ons with memberships
else right('0' + cast(TYPECODE as nvarchar(2)), 2)
end + case
when ISCOMBINATION = 1 and TYPECODE = 0 then left([DESCRIPTION], 40) + cast(ITEMID as nvarchar(36)) + '0'
when ISCOMBINATION = 1 and TYPECODE = 3 then APPLIESTOITEMSORTCRITERIA + '1'
else 'Z'
end + case -- Combo and regular ticket sort clauses have to be separate so they don't intermingle.
when ISCOMBINATION = 0 and TYPECODE = 0 then left([DESCRIPTION], 40) + cast(ITEMID as nvarchar(36)) + '0'
when ISCOMBINATION = 0 and TYPECODE = 3 and ITEMID is not null then APPLIESTOITEMSORTCRITERIA + '1' -- group each item-level fee with the specific ticket it applies to
else 'Z'
end + case
when MEMBERSHIPTRANSACTIONID is not null then cast(MEMBERSHIPTRANSACTIONID as nvarchar(36))
else 'Z'
end + case
-- list memberships before add-ons
when TYPECODE = 1 then '1'
when TYPECODE = 16 then '2'
else '0'
end + left([DESCRIPTION], 40), 200) as SORTFIELD,
PARENTITEMID
from @ITEMS;
return;
end