USP_CREDIT_ADDREFUND
Creates a refund.
Parameters
Parameter | Parameter Type | Mode | Description |
---|---|---|---|
@ID | uniqueidentifier | INOUT | |
@CHANGEAGENTID | uniqueidentifier | IN | |
@CONTEXTID | uniqueidentifier | IN | |
@COMMENT | nvarchar(500) | IN | |
@ITEMS | xml | IN | |
@CREDITREASONCODEID | uniqueidentifier | IN | |
@REFUNDAMOUNT | money | IN | |
@TRANSACTIONDATE | datetime | IN | |
@CURRENTAPPUSERID | uniqueidentifier | IN | |
@REFUNDMETHODS | xml | IN | |
@TAXES | xml | IN | |
@TOTAL | money | IN | |
@ORDERDISCOUNTS | money | IN | |
@CONTEXTTYPE | tinyint | IN | |
@TRANSACTIONID | uniqueidentifier | IN | |
@TIMESTAMP | bigint | IN | |
@ADDRESSID | uniqueidentifier | IN |
Definition
Copy
CREATE procedure dbo.USP_CREDIT_ADDREFUND
(
@ID uniqueidentifier = null output,
@CHANGEAGENTID uniqueidentifier = null,
@CONTEXTID uniqueidentifier,
@COMMENT nvarchar(500) = null,
@ITEMS xml = null,
@CREDITREASONCODEID uniqueidentifier = null,
@REFUNDAMOUNT money = null,
@TRANSACTIONDATE datetime = null,
@CURRENTAPPUSERID uniqueidentifier = null,
@REFUNDMETHODS xml = null,
@TAXES xml = null,
@TOTAL money = null,
@ORDERDISCOUNTS money = null,
@CONTEXTTYPE tinyint = null, -- 0 is order, 1 is membership, 2 is event registration
@TRANSACTIONID uniqueidentifier = null,
@TIMESTAMP bigint = null,
@ADDRESSID uniqueidentifier = null
)
as
set nocount on;
if @ID is null
set @ID = newid()
if @CHANGEAGENTID is null
exec dbo.USP_CHANGEAGENT_GETORCREATECHANGEAGENT @CHANGEAGENTID output
declare @CURRENTDATE datetime
set @CURRENTDATE = getdate()
declare @POSTSTATUSCODE tinyint
--Make sure nobody else has done a refund since the form was opened.
if @CONTEXTTYPE = 0 begin --it's an order
if @TIMESTAMP <> coalesce((select [TSLONG] from dbo.[SALESORDER] where [ID] = @TRANSACTIONID), -1) begin
if @TRANSACTIONID is null or @TRANSACTIONID = '00000000-0000-0000-0000-000000000000'
raiserror('ERR_TRANSACTIONID_ORDERNOTSELECTED', 13, 1);
else
raiserror('ERR_CREDITITEMS_CONFLICTINGREFUND', 13, 1);
return 1;
end
else begin
update dbo.[SALESORDER] set [DATECHANGED] = @CURRENTDATE, [CHANGEDBYID] = @CHANGEAGENTID
where [ID] = @TRANSACTIONID;
select @POSTSTATUSCODE = FT.POSTSTATUSCODE
from dbo.SALESORDER SO
inner join dbo.FINANCIALTRANSACTION FT on FT.ID = SO.REVENUEID
where SO.ID = @TRANSACTIONID;
end
end
-- it's a membership refund
else if @CONTEXTTYPE = 1 begin
if @TIMESTAMP <> coalesce((select [TSLONG] from dbo.[MEMBERSHIPTRANSACTION] where [ID] = @TRANSACTIONID), -1) begin
if @TRANSACTIONID is null or @TRANSACTIONID = '00000000-0000-0000-0000-000000000000'
raiserror('ERR_TRANSACTIONID_MEMBERSHIPNOTSELECTED', 13, 1);
else
raiserror('ERR_ITEMS_ORDERREFUND_HASNEWERMEMBERSHIPTRANSACTIONS', 13, 1);
return 1;
end
else begin
update dbo.[MEMBERSHIPTRANSACTION] set [DATECHANGED] = getdate(), [CHANGEDBYID] = @CHANGEAGENTID
where [ID] = @TRANSACTIONID
select @POSTSTATUSCODE = LI.POSTSTATUSCODE
from dbo.MEMBERSHIPTRANSACTION MT
inner join dbo.FINANCIALTRANSACTIONLINEITEM LI on LI.ID = MT.REVENUESPLITID
where MT.ID = @TRANSACTIONID;
end
end
-- it's an event registraion refund
else if @CONTEXTTYPE = 2 begin
if @TIMESTAMP <> coalesce((select [TSLONG] from dbo.[REGISTRANT] where [ID] = @TRANSACTIONID), -1) begin
if @TRANSACTIONID is null or @TRANSACTIONID = '00000000-0000-0000-0000-000000000000'
raiserror('ERR_TRANSACTIONID_EVENTREGISTRATIONNOTSELECTED', 13, 1);
else
raiserror('ERR_CREDITITEMS_CONFLICTINGEVENTREGISTRAIONREFUND', 13, 1);
return 1;
end
else begin
update dbo.[REGISTRANT] set [DATECHANGED] = getdate(), [CHANGEDBYID] = @CHANGEAGENTID
where [ID] = @TRANSACTIONID
select @POSTSTATUSCODE = LI.POSTSTATUSCODE
from dbo.EVENTREGISTRANTPAYMENT RP
inner join dbo.FINANCIALTRANSACTIONLINEITEM LI on LI.ID = RP.PAYMENTID
where RP.REGISTRANTID = @TRANSACTIONID;
end
end
--A special note about REVENUESPLITID:
--This is the FINANCIALTRANSACITONLINEITEM.SOURCELINEITEMID for a given refund ftli.
--Previously we only stored this for back office memberships and back office event registrations,
--however there is nothing preventing us from storing this info in the future for items that we can.
--Perhaps someday a dev will magically even find time (given time even?) to update client data
--so this is stored for all items. For now though, it's only for back office membership,
--back office event registrations, and all membership addons.
--Please update this comment if you change this.
-- Get refund items from input parameter @ITEMS
declare @CREDITITEMS table(
[ID] uniqueidentifier,
[SALESORDERITEMID] uniqueidentifier,
[QUANTITYREFUNDING] int,
[QUANTITY] int,
[PRICE] money,
[FEES] money,
[DISCOUNTS] money,
[TYPECODE] int,
[DESCRIPTION] nvarchar(255),
[REFUNDINGTOTAL] money,
[GROUPID] uniqueidentifier,
[GROUPTYPECODE] tinyint,
[ITEMID] uniqueidentifier,
[REVENUESPLITID] uniqueidentifier
);
insert into @CREDITITEMS
select
newid(),
case when T.item.value('(SALESORDERITEMID)[1]','uniqueidentifier') = '00000000-0000-0000-0000-000000000000' then
null
else
T.item.value('(SALESORDERITEMID)[1]','uniqueidentifier')
end [SALESORDERITEMID],
T.item.value('(QUANTITYREFUNDING)[1]','decimal(10, 4)'),
T.item.value('(QUANTITY)[1]','decimal(10, 4)'),
T.item.value('(PRICE)[1]','money'),
round( T.item.value('(FEES)[1]','money') * T.item.value('(QUANTITYREFUNDING)[1]','decimal(10, 4)'), 2),
T.item.value('(DISCOUNTS)[1]','money'),
T.item.value('(TYPECODE)[1]','integer'),
case @CONTEXTTYPE
when 0 then
(select [DESCRIPTION] from dbo.[SALESORDERITEM] where [ID] = T.item.value('(SALESORDERITEMID)[1]','uniqueidentifier'))
when 1 then
T.item.value('(DESCRIPTION)[1]','nvarchar(100)')
end,
T.item.value('(REFUNDINGTOTAL)[1]','money'),
case when T.item.value('(GROUPID)[1]','uniqueidentifier') = '00000000-0000-0000-0000-000000000000' then
null
else
T.item.value('(GROUPID)[1]','uniqueidentifier')
end [GROUPID],
T.item.value('(GROUPTYPECODE)[1]','tinyint'),
case when T.item.value('(ITEMID)[1]','uniqueidentifier') = '00000000-0000-0000-0000-000000000000' then
null
else
T.item.value('(ITEMID)[1]','uniqueidentifier')
end [ITEMID],
case when T.item.value('(REVENUESPLITID)[1]','uniqueidentifier') = '00000000-0000-0000-0000-000000000000' then
null
else
T.item.value('(REVENUESPLITID)[1]','uniqueidentifier')
end [REVENUESPLITID]
from @ITEMS.nodes('/ITEMS/ITEM') T(item)
--Error if the quantity refunding is less than zero for any of the items
if exists (select SALESORDERITEMID from @CREDITITEMS where QUANTITYREFUNDING < 0) begin
raiserror('ERR_ITEMS_NEGATIVEQUANTITY', 13, 1);
return 1;
end
--Now that we've checked to make sure no negative quantities have been entered,
--get rid of all the ones that weren't selected to return
delete from @CREDITITEMS
where [QUANTITYREFUNDING] <= 0
-- If there are combination items to refund,
-- get the same type of the tickets of all the programs in the combination.
if exists (
select [ITEMS].[SALESORDERITEMID]
from @CREDITITEMS [ITEMS]
inner join dbo.[SALESORDERITEMTICKET] [TICKETS] on [ITEMS].[SALESORDERITEMID] = [TICKETS].[ID]
inner join dbo.[SALESORDERITEMTICKETCOMBINATION] [COMBO] on [TICKETS].[ID] = [COMBO].[ID]
) begin
-- Update the price, fees, of the item already in @CREDITITEMS
-- the price returned from input parameter is the price for the whole combo,
-- not the price for the individual program.
update @CREDITITEMS set
[PRICE] = [TICKETS].[PRICE],
[FEES] = dbo.UFN_SALESORDERITEM_GETFEES([ITEMS].[SALESORDERITEMID]) * [ITEMS].[QUANTITYREFUNDING]
from @CREDITITEMS [ITEMS]
inner join dbo.[SALESORDERITEMTICKET] [TICKETS] on [ITEMS].[SALESORDERITEMID] = [TICKETS].[ID]
inner join dbo.[SALESORDERITEMTICKETCOMBINATION] [COMBO] on [TICKETS].[ID] = [COMBO].[ID]
--update price for applying tickets to membership
update @CREDITITEMS set
[PRICE] = [SALESORDERITEM].[PRICE],
[FEES] = dbo.UFN_SALESORDERITEM_GETFEES([ITEMS].[SALESORDERITEMID]) * [ITEMS].[QUANTITYREFUNDING]
from @CREDITITEMS [ITEMS]
inner join dbo.[SALESORDERITEM] on [ITEMS].[SALESORDERITEMID] = [SALESORDERITEM].[ID]
inner join dbo.[SALESORDERITEMMEMBERSHIPITEMPROMOTION] on [SALESORDERITEM].[ID] = [SALESORDERITEMMEMBERSHIPITEMPROMOTION].[SALESORDERITEMID]
insert into @CREDITITEMS
select
newid() as [ID],
[SALESORDERITEM].[ID],
(
select [QUANTITYREFUNDING]
from @CREDITITEMS [ITEMS]
inner join dbo.[SALESORDERITEMTICKET] [TICKETS] on [ITEMS].[SALESORDERITEMID] = [TICKETS].[ID]
inner join dbo.[SALESORDERITEMTICKETCOMBINATION] [COMBO] on [TICKETS].[ID] = [COMBO].[ID]
where
[TICKETS].[PRICETYPECODEID] = [SALESORDERITEMTICKET].[PRICETYPECODEID] and
[COMBO].[COMBINATIONID] = [SALESORDERITEMTICKETCOMBINATION].[COMBINATIONID] and
[COMBO].[TICKETCOMBINATIONID] = [SALESORDERITEMTICKETCOMBINATION].[TICKETCOMBINATIONID]
) as [QUANTITYREFUNDING],
(
select [QUANTITY]
from @CREDITITEMS [ITEMS]
inner join dbo.[SALESORDERITEMTICKET] [TICKETS] on [ITEMS].[SALESORDERITEMID] = [TICKETS].[ID]
inner join dbo.[SALESORDERITEMTICKETCOMBINATION] [COMBO] on [TICKETS].[ID] = [COMBO].[ID]
where
[TICKETS].[PRICETYPECODEID] = [SALESORDERITEMTICKET].[PRICETYPECODEID] and
[COMBO].[COMBINATIONID] = [SALESORDERITEMTICKETCOMBINATION].[COMBINATIONID] and
[COMBO].[TICKETCOMBINATIONID] = [SALESORDERITEMTICKETCOMBINATION].[TICKETCOMBINATIONID]
) as [QUANTITY],
[SALESORDERITEM].[PRICE],
dbo.UFN_SALESORDERITEM_GETFEES([SALESORDERITEM].[ID]) * (
select [QUANTITYREFUNDING]
from @CREDITITEMS [ITEMS]
inner join dbo.[SALESORDERITEMTICKET] [TICKETS] on [ITEMS].[SALESORDERITEMID] = [TICKETS].[ID]
inner join dbo.[SALESORDERITEMTICKETCOMBINATION] [COMBO] on [TICKETS].[ID] = [COMBO].[ID]
where
[TICKETS].[PRICETYPECODEID] = [SALESORDERITEMTICKET].[PRICETYPECODEID] and
[COMBO].[COMBINATIONID] = [SALESORDERITEMTICKETCOMBINATION].[COMBINATIONID] and
[COMBO].[TICKETCOMBINATIONID] = [SALESORDERITEMTICKETCOMBINATION].[TICKETCOMBINATIONID]
) as [FEES],
0 as [DISCOUNTS],
0 as [TYPECODE],
[SALESORDERITEM].[DESCRIPTION],
0 as [REFUNDINGTOTAL],
null as [GROUPID],
0 as [GROUPTYPECODE],
null as [ITEMID],
LI.ID as [REVENUESPLITID]
from dbo.[SALESORDERITEM]
inner join dbo.[SALESORDERITEMTICKET] on [SALESORDERITEM].[ID] = [SALESORDERITEMTICKET].[ID]
inner join dbo.[SALESORDERITEMTICKETCOMBINATION] on [SALESORDERITEMTICKET].[ID] = [SALESORDERITEMTICKETCOMBINATION].[ID]
inner join dbo.SALESORDER on SALESORDER.ID = SALESORDERITEM.SALESORDERID
inner join dbo.FINANCIALTRANSACTIONLINEITEM as LI on LI.FINANCIALTRANSACTIONID = SALESORDER.REVENUEID
inner join dbo.REVENUESPLITORDER on REVENUESPLITORDER.ID = LI.ID
where
[SALESORDERITEM].[ID] not in (select [SALESORDERITEMID] from @CREDITITEMS)
and [SALESORDERITEMTICKETCOMBINATION].[TICKETCOMBINATIONID] in (
select [COMBO].[TICKETCOMBINATIONID]
from @CREDITITEMS [ITEMS]
inner join dbo.[SALESORDERITEMTICKET] [TICKETS] on [ITEMS].[SALESORDERITEMID] = [TICKETS].[ID]
inner join dbo.[SALESORDERITEMTICKETCOMBINATION] [COMBO] on [TICKETS].[ID] = [COMBO].[ID]
)
and [SALESORDERITEMTICKET].[PRICETYPECODEID] in (
select [TICKETS].[PRICETYPECODEID] from @CREDITITEMS [ITEMS]
inner join dbo.[SALESORDERITEMTICKET] [TICKETS] on [ITEMS].[SALESORDERITEMID] = [TICKETS].[ID]
inner join dbo.[SALESORDERITEMTICKETCOMBINATION] [COMBO] on [TICKETS].[ID] = [COMBO].[ID]
where
[COMBO].[COMBINATIONID] = [SALESORDERITEMTICKETCOMBINATION].[COMBINATIONID] and
[COMBO].[TICKETCOMBINATIONID] = [SALESORDERITEMTICKETCOMBINATION].[TICKETCOMBINATIONID]
)
and (
REVENUESPLITORDER.PROGRAMID = SALESORDERITEMTICKET.PROGRAMID
and (SALESORDERITEMTICKET.EVENTID is null or SALESORDERITEMTICKET.EVENTID = REVENUESPLITORDER.EVENTID)
)
end
if exists
(
select 1
from @CREDITITEMS ITEMS
where ITEMS.TYPECODE = 2
) begin
-- check for matching gifts
if exists
(
select 1
from dbo.REVENUEMATCHINGGIFT
inner join @REFUNDMETHODS.nodes('/REFUNDMETHODS/ITEM') T(item) on
T.item.value('(REVENUEID)[1]', 'uniqueidentifier') = REVENUEMATCHINGGIFT.MGSOURCEREVENUEID
) begin
raiserror('ERR_REFUNDMETHODS_DONATIONMATCHINGGIFTS', 13, 1);
return 1;
end
delete
from dbo.REVENUERECOGNITION
where REVENUERECOGNITION.REVENUESPLITID in
(
select
SOID.REVENUESPLITID
from dbo.SALESORDERITEMDONATION SOID
inner join @CREDITITEMS ITEMS on
ITEMS.SALESORDERITEMID = SOID.ID
)
end
/********Validate refund items*******/
--Error if no items were selected
if not exists (select [SALESORDERITEMID] from @CREDITITEMS) begin
raiserror('ERR_ITEMS_NONESELECTED', 13, 1);
return 1;
end
--Error if the quantity refunding for any item is greater than the quantity available
if exists(select [SALESORDERITEMID] from @CREDITITEMS where [QUANTITYREFUNDING] > [QUANTITY]) begin
raiserror('ERR_ITEMS_EXCEEDSQUANTITYAVAILABLE', 13, 1);
return 1;
end
--Error if the payments do not add up to the refund total
if coalesce((select sum(T.item.value('(AMOUNTREFUNDING)[1]','money')) from @REFUNDMETHODS.nodes('/REFUNDMETHODS/ITEM') T(item)),0) <> @REFUNDAMOUNT begin
raiserror('ERR_REFUNDMETHODS_DIFFERENTFROMTOTALAMOUNT', 13, 1);
return 1;
end
--Error if the refund amount is greater than the order total
if @REFUNDAMOUNT > @TOTAL begin
raiserror('ERR_REFUNDAMOUNT_EXCEEDSLIMIT', 13, 1);
return 1;
end
declare @PAYMENTGROUPID uniqueidentifier = null;
select top(1)
@PAYMENTGROUPID = [PAYMENTGROUPID]
from (
select
T.item.value('(AMOUNTREFUNDING)[1]','money') as [AMOUNTPAID],
T.item.value('(PAYMENTGROUPID)[1]','uniqueidentifier') as [PAYMENTGROUPID],
T.item.value('(PAYMENTGROUPMAXAMOUNT)[1]','money') as [PAYMENTGROUPMAXAMOUNT]
from @REFUNDMETHODS.nodes('/REFUNDMETHODS/ITEM') T(item)
) [PAYMENTS]
group by [PAYMENTGROUPID], [PAYMENTGROUPMAXAMOUNT]
having sum([AMOUNTPAID]) > [PAYMENTGROUPMAXAMOUNT]
if (@PAYMENTGROUPID is not null) and (@PAYMENTGROUPID <> '00000000-0000-0000-0000-000000000000') begin
declare @PAYMENTSLIST nvarchar(1000)
declare @PAYMENTGROUPMAXAMOUNT nvarchar(25)
select
@PAYMENTSLIST = dbo.UDA_BUILDLIST(T.item.value('(DESCRIPTION)[1]','nvarchar(1000)'))
from @REFUNDMETHODS.nodes('/REFUNDMETHODS/ITEM') T(item)
where T.item.value('(PAYMENTGROUPID)[1]','uniqueidentifier') = @PAYMENTGROUPID
select top(1)
@PAYMENTGROUPMAXAMOUNT = convert(nvarchar(25), T.item.value('(PAYMENTGROUPMAXAMOUNT)[1]','money'))
from @REFUNDMETHODS.nodes('/REFUNDMETHODS/ITEM') T(item)
where T.item.value('(PAYMENTGROUPID)[1]','uniqueidentifier') = @PAYMENTGROUPID
set @PAYMENTSLIST = 'The original transaction includes multiple payment methods, so you cannot return the full transaction amount as one refund payment. You may return up to $' + @PAYMENTGROUPMAXAMOUNT + ' among the following payments: ' + @PAYMENTSLIST + '.'
raiserror(@PAYMENTSLIST, 13, 1);
return 1;
end
if exists(
select
CREDITCARDPAYMENTMETHODDETAIL.ID
from dbo.CREDITCARDPAYMENTMETHODDETAIL
inner join dbo.REVENUEPAYMENTMETHOD on REVENUEPAYMENTMETHOD.ID = CREDITCARDPAYMENTMETHODDETAIL.ID
where REVENUEPAYMENTMETHOD.REVENUEID in (
select
case when T.item.value('(REVENUEID)[1]','uniqueidentifier') = '00000000-0000-0000-0000-000000000000'
then (select FINANCIALTRANSACTIONID from dbo.FINANCIALTRANSACTIONLINEITEM where ID = T.item.value('(REVENUESPLITID)[1]','uniqueidentifier'))
else T.item.value('(REVENUEID)[1]','uniqueidentifier')
end
from @REFUNDMETHODS.nodes('/REFUNDMETHODS/ITEM') T(item)
where T.item.value('(PAYMENTTYPECODE)[1]','integer') = 2
)
and CREDITCARDPAYMENTMETHODDETAIL.TRANSACTIONID is null
)
raiserror('BBERR_REFUNDCREDITCARDPAYMENT_MUSTBEPROCESSED', 16, 1);
-- 256291: Removing refund form's 60-day limit. Not all processors have a 60-day limit.
-- Instead, we will error on the form if the first credit card payment refund fails and rollback this procedure.
-- We must complete the refund after the first credit card is processed because we cannot reverse the refund
-- That means, if a refund has more than one payment, it's possible to complete a refund and have 'unrefundable' payments (which was also the case before this change)
--if exists(
-- select
-- CREDITCARDPAYMENTMETHODDETAIL.ID
-- from dbo.CREDITCARDPAYMENTMETHODDETAIL
-- inner join dbo.REVENUEPAYMENTMETHOD on REVENUEPAYMENTMETHOD.ID = CREDITCARDPAYMENTMETHODDETAIL.ID
-- where REVENUEPAYMENTMETHOD.REVENUEID in (
-- select
-- case when T.item.value('(REVENUEID)[1]','uniqueidentifier') = '00000000-0000-0000-0000-000000000000'
-- then (select REVENUEID from dbo.REVENUESPLIT where ID = T.item.value('(REVENUESPLITID)[1]','uniqueidentifier'))
-- else T.item.value('(REVENUEID)[1]','uniqueidentifier')
-- end
-- from @REFUNDMETHODS.nodes('/REFUNDMETHODS/ITEM') T(item)
-- where T.item.value('(PAYMENTTYPECODE)[1]','integer') = 2
-- )
-- and dateadd(day, 60, CREDITCARDPAYMENTMETHODDETAIL.DATEADDED) <= convert(date, getdate())
--)
-- raiserror('BBERR_REFUNDCREDITCARDPAYMENT_TRANSACTIONTOOOLD', 16, 1);
--Throw an error if we're refunding a membership, but all the add-ons
--have not been refunded.
if exists(
select
MEMBERSHIPITEM.ID
from @CREDITITEMS MEMBERSHIPITEM
inner join dbo.MEMBERSHIPADDON
on MEMBERSHIPADDON.MEMBERSHIPTRANSACTIONID = MEMBERSHIPITEM.ITEMID
left join @CREDITITEMS CREDITADDONS
on CREDITADDONS.ITEMID = MEMBERSHIPADDON.ID
left join
(
select FTLI.SOURCELINEITEMID, FTLI.QUANTITY
from dbo.FINANCIALTRANSACTIONLINEITEM FTLI
inner join dbo.FINANCIALTRANSACTION
on FINANCIALTRANSACTION.ID = FTLI.FINANCIALTRANSACTIONID
inner join dbo.CREDITITEM_EXT
on CREDITITEM_EXT.ID = FTLI.ID
where FINANCIALTRANSACTION.TYPECODE = 23 --refund
and CREDITITEM_EXT.TYPECODE = 16 --membershipaddon
) PREVIOUSLYREFUNDEDADDONREFUNDITEMS
on PREVIOUSLYREFUNDEDADDONREFUNDITEMS.SOURCELINEITEMID = MEMBERSHIPADDON.REVENUESPLITID
where MEMBERSHIPITEM.TYPECODE = 1
and MEMBERSHIPITEM.QUANTITYREFUNDING = 1
group by
CREDITADDONS.ID,
CREDITADDONS.QUANTITY,
CREDITADDONS.QUANTITYREFUNDING,
MEMBERSHIPADDON.QUANTITY,
MEMBERSHIPITEM.ID,
MEMBERSHIPADDON.ID
having (CREDITADDONS.ID is not null and CREDITADDONS.QUANTITY <> CREDITADDONS.QUANTITYREFUNDING)
or (CREDITADDONS.ID is null and sum(coalesce(PREVIOUSLYREFUNDEDADDONREFUNDITEMS.QUANTITY, 0)) <> MEMBERSHIPADDON.QUANTITY)
)
raiserror('BBERR_ITEMS_REFUNDINGMEMBERSHIPWITHOUTADDONS', 16, 1);
declare @CURRENTDATETIMEOFFSET datetimeoffset
set @CURRENTDATETIMEOFFSET = dbo.UFN_TIMEZONEENTRY_GETSYSTEMDEFAULTDATEWITHTIMEOFFSET(getutcdate(), 1)
-- Bug #167166 - MDC
set @TRANSACTIONDATE = dbo.UFN_TIMEZONEENTRY_GETSYSTEMDEFAULTDATEFROMUTC(getutcdate());
if cast(@TRANSACTIONDATE as date) < (select cast(S.TRANSACTIONDATE as date) from dbo.SALESORDER S where S.ID = @CONTEXTID) begin
raiserror('ERR_REFUNDDATE_BEFORE_ORDERDATE', 13, 1);
return 1;
end
declare @LATESTTRANSACTIONID uniqueidentifier
declare @MEMBERSHIPID uniqueidentifier
begin try
-- JustinMe 10/21/2009 Bug#61958
-- get the constituent id from either sales order or membership revenue
declare @CONSTITUENTID uniqueidentifier
select @CONSTITUENTID =
case @CONTEXTTYPE
when 0 then (select [CONSTITUENTID] from dbo.[SALESORDER] where [ID] = @CONTEXTID)
when 1 then
(
select
top 1 FINANCIALTRANSACTION.CONSTITUENTID
from dbo.MEMBERSHIPTRANSACTION
inner join dbo.FINANCIALTRANSACTIONLINEITEM
on FINANCIALTRANSACTIONLINEITEM.ID = MEMBERSHIPTRANSACTION.REVENUESPLITID
inner join dbo.FINANCIALTRANSACTION
on FINANCIALTRANSACTION.ID = FINANCIALTRANSACTIONLINEITEM.FINANCIALTRANSACTIONID
where MEMBERSHIPTRANSACTION.MEMBERSHIPID = @CONTEXTID
order by MEMBERSHIPTRANSACTION.TRANSACTIONDATE, MEMBERSHIPTRANSACTION.DATEADDED desc
)
else
(select [REGISTRANT].[CONSTITUENTID] from dbo.[REGISTRANT] where [ID] = @CONTEXTID)
end
-- LeeCh, 12/04/2009 Bug#69430
-- Get sales order ID for refunded item if it is in a sales order
declare @SALESORDERID uniqueidentifier
declare @MEMBERSHIPREFUNDHASMEMBERSHIP bit = 1;
if @CONTEXTTYPE = 0 begin
set @SALESORDERID = @CONTEXTID
end
else begin
if @CONTEXTTYPE = 1 begin
select @SALESORDERID = [SALESORDER].[ID]
from @CREDITITEMS [CREDITITEMS]
inner join dbo.[SALESORDERITEM]
on [CREDITITEMS].[SALESORDERITEMID] = [SALESORDERITEM].[ID]
inner join dbo.[SALESORDER]
on [SALESORDERITEM].[SALESORDERID] = [SALESORDER].[ID]
--We only want to refund the membership if it was selected
--(you can select just add-ons)
if exists(select ID from @CREDITITEMS where TYPECODE = 16 and QUANTITYREFUNDING > 0) and not exists (select ID from @CREDITITEMS where TYPECODE = 1 and QUANTITYREFUNDING > 0)
set @MEMBERSHIPREFUNDHASMEMBERSHIP = 0;
end
else
begin
declare @EVENTREGISTRATIONREVENUEID uniqueidentifier
select top 1 @EVENTREGISTRATIONREVENUEID = (T.item.value('(REVENUEID)[1]','uniqueidentifier')) from @REFUNDMETHODS.nodes('/REFUNDMETHODS/ITEM') T(item)
if @EVENTREGISTRATIONREVENUEID <> '00000000-0000-0000-0000-000000000000'
begin
select top 1 @SALESORDERID = [SALESORDERPAYMENT].[SALESORDERID]
from dbo.[SALESORDERPAYMENT]
where [PAYMENTID] = @EVENTREGISTRATIONREVENUEID
end
end
end
-- handle inserting the data
declare @CURRENCYID uniqueidentifier;
select @CURRENCYID = ID from dbo.CURRENCY where ISORGANIZATIONCURRENCY = 1;
declare @PDACCOUNTSYSTEMID uniqueidentifier;
declare @ALLOWGLDISTRIBUTIONS bit;
select
@PDACCOUNTSYSTEMID = ID,
@ALLOWGLDISTRIBUTIONS = ALLOWGLDISTRIBUTIONS
from
dbo.UFN_PDACCOUNTSYSTEM_DEFAULTORSYSTEM();
declare @INS table(
ID uniqueidentifier
,CREDITID uniqueidentifier
,SALESORDERITEMID uniqueidentifier
,QUANTITY int
,PRICE money
,FEES money
,DISCOUNTS money
,TYPECODE tinyint
,DESCRIPTION nvarchar(700)
,GROUPID uniqueidentifier
,GROUPTYPECODE tinyint
,SOURCELINEITEMID uniqueidentifier
,CONTRIBUTEDREVENUE money
,ISCONTRIBUTEDREVENUE bit
,TOTALAMOUNT money)
insert into dbo.FINANCIALTRANSACTION(
ID
,TRANSACTIONAMOUNT
,BASEAMOUNT
,ORGAMOUNT
,TRANSACTIONCURRENCYID
,TYPECODE
,PDACCOUNTSYSTEMID
,DESCRIPTION
,DATE
,POSTDATE
,POSTSTATUSCODE
,PARENTID
,APPUSERID
,CONSTITUENTID
---- Boilerplate
,DATEADDED ,DATECHANGED ,ADDEDBYID ,CHANGEDBYID)
values(
@ID
,@REFUNDAMOUNT
,@REFUNDAMOUNT
,@REFUNDAMOUNT
,@CURRENCYID
,23 --Refund
,@PDACCOUNTSYSTEMID
,@COMMENT
,@TRANSACTIONDATE
,case when @ALLOWGLDISTRIBUTIONS = 1 and isnull(@POSTSTATUSCODE, 1) != 3 then cast(@TRANSACTIONDATE as date) else null end
,case when @ALLOWGLDISTRIBUTIONS = 1 and isnull(@POSTSTATUSCODE, 1) != 3 then 1 else 3 end
,(select REVENUEID from dbo.SALESORDER where ID = @SALESORDERID)
,@CURRENTAPPUSERID
,@CONSTITUENTID
,@CURRENTDATE, @CURRENTDATE, @CHANGEAGENTID, @CHANGEAGENTID
)
insert into dbo.CREDIT_EXT(
ID
,SALESORDERID
,CREDITREASONCODEID
---- Boilerplate
,DATEADDED ,DATECHANGED ,ADDEDBYID ,CHANGEDBYID)
values (
@ID
,@SALESORDERID
,case @CREDITREASONCODEID
when '00000000-0000-0000-0000-000000000000' then null
else @CREDITREASONCODEID
end
,@CURRENTDATE, @CURRENTDATE, @CHANGEAGENTID, @CHANGEAGENTID
)
insert into dbo.CREDITPAYMENT
(
[ID],
[CREDITID],
[APPUSERID],
[CREDITPAYMENTDATEWITHTIMEOFFSET],
[AMOUNT],
[PAYMENTMETHODCODE],
[OTHERPAYMENTMETHODCODEID],
[REVENUEID],
[REVENUESPLITID],
[REFUNDPROCESSED],
[STATUS],
[ADDEDBYID],
[CHANGEDBYID],
[DATEADDED],
[DATECHANGED]
)
select
T.item.value('(CREDITPAYMENTID)[1]','uniqueidentifier'),
@ID,
@CURRENTAPPUSERID,
@CURRENTDATETIMEOFFSET,
T.item.value('(AMOUNTREFUNDING)[1]','money'),
T.item.value('(PAYMENTTYPECODE)[1]','tinyint'),
case when T.item.value('(PAYMENTTYPECODE)[1]','tinyint') = 10 then
T.item.value('(OTHERPAYMENTMETHODCODEID)[1]','uniqueidentifier')
else
null
end,
case when T.item.value('(REVENUEID)[1]','uniqueidentifier') = '00000000-0000-0000-0000-000000000000' then
null
else
T.item.value('(REVENUEID)[1]','uniqueidentifier')
end,
case when T.item.value('(REVENUESPLITID)[1]','uniqueidentifier') = '00000000-0000-0000-0000-000000000000' then
null
else
T.item.value('(REVENUESPLITID)[1]','uniqueidentifier')
end,
case T.item.value('(PAYMENTTYPECODE)[1]','tinyint')
when 2 then 0
else 1
end,
T.item.value('(STATUS)[1]','nvarchar(255)'),
@CHANGEAGENTID,
@CHANGEAGENTID,
@CURRENTDATE,
@CURRENTDATE
from @REFUNDMETHODS.nodes('/REFUNDMETHODS/ITEM') T(item);
if @ADDRESSID = '00000000-0000-0000-0000-000000000000'
set @ADDRESSID = null;
insert into dbo.CREDITPAYMENTCHECKPAYMENTMETHODDETAIL
(
[ID],
[ADDRESSID],
[ADDEDBYID],
[CHANGEDBYID],
[DATEADDED],
[DATECHANGED]
)
select
T.item.value('(CREDITPAYMENTID)[1]','uniqueidentifier'),
@ADDRESSID,
@CHANGEAGENTID,
@CHANGEAGENTID,
@CURRENTDATE,
@CURRENTDATE
from
@REFUNDMETHODS.nodes('/REFUNDMETHODS/ITEM') T(item)
where
T.item.value('(PAYMENTTYPECODE)[1]','tinyint') = 1;
--If it's an order refund
if @CONTEXTTYPE = 0 begin
insert into @INS(
ID
,CREDITID
,SALESORDERITEMID
,QUANTITY
,PRICE
,FEES
,DISCOUNTS
,TYPECODE
,DESCRIPTION
,GROUPID
,GROUPTYPECODE
,SOURCELINEITEMID)
select distinct
[ID],
@ID,
[SALESORDERITEMID],
[QUANTITYREFUNDING],
[PRICE],
[FEES],
[DISCOUNTS],
[TYPECODE],
[DESCRIPTION],
[GROUPID],
[GROUPTYPECODE],
[REVENUESPLITID]
from @CREDITITEMS
where
[SALESORDERITEMID] is not null
--taxes
union all
select
newid(),
@ID,
T.item.value('(TAXID)[1]','uniqueidentifier'),
1,
round(T.item.value('(CURRENTTAX)[1]','money'), 2),
0,
0,
4,
(select [DESCRIPTION] from dbo.[SALESORDERITEM] where [ID] = T.item.value('(TAXID)[1]','uniqueidentifier')),
null,
0,
T.item.value('(REVENUESPLITID)[1]','uniqueidentifier')
from @TAXES.nodes('/TAXES/ITEM') T(item)
where T.item.value('(CURRENTTAX)[1]','money') > 0
--item level fees
union all
select
newid(),
@ID,
FEES.ID,
1,
FEES.AMOUNT,
0,
0,
3,
CREDITITEMS.DESCRIPTION,
null,
0,
REVENUESPLIT.ID
from
@CREDITITEMS as CREDITITEMS
cross apply
dbo.UFN_SPLITS_GETPRORATEDSPLITS(
(
select
coalesce(sum(SALESORDERITEM.TOTAL), 0) - coalesce(sum((LI.QUANTITY * LI.UNITVALUE) - EXT.DISCOUNTS), 0)
from dbo.SALESORDERITEMFEE
inner join dbo.SALESORDERITEM on SALESORDERITEMFEE.ID = SALESORDERITEM.ID
left outer join dbo.CREDITITEM_EXT as EXT on EXT.SALESORDERITEMID = SALESORDERITEM.ID
left outer join dbo.FINANCIALTRANSACTIONLINEITEM as LI on LI.ID = EXT.ID
where SALESORDERITEMFEE.SALESORDERITEMID = CREDITITEMS.SALESORDERITEMID
),
CREDITITEMS.FEES,
(
select
SALESORDERITEM.ID as ID,
SALESORDERITEM.TOTAL - coalesce(sum((LI.QUANTITY * LI.UNITVALUE) - EXT.DISCOUNTS) , 0) as AMOUNT
from dbo.SALESORDERITEMFEE
inner join SALESORDERITEM on SALESORDERITEMFEE.ID = SALESORDERITEM.ID
left outer join dbo.CREDITITEM_EXT as EXT on EXT.SALESORDERITEMID = SALESORDERITEM.ID
left outer join dbo.FINANCIALTRANSACTIONLINEITEM as LI on LI.ID = EXT.ID
where SALESORDERITEMFEE.SALESORDERITEMID = CREDITITEMS.SALESORDERITEMID
group by SALESORDERITEM.ID, SALESORDERITEM.TOTAL
FOR XML RAW('ITEM'),TYPE,ELEMENTS,root('AMOUNTSTOPRORATE'),binary base64
)
) as FEES
left outer join dbo.SALESORDERITEMFEE
on FEES.ID = SALESORDERITEMFEE.ID
left outer join dbo.SALESORDERITEM
on SALESORDERITEMFEE.ID = SALESORDERITEM.ID
left outer join dbo.SALESORDER
on SALESORDER.ID = SALESORDERITEM.SALESORDERID
left outer join dbo.FINANCIALTRANSACTION REVENUE
on REVENUE.ID = SALESORDER.REVENUEID
left outer join dbo.FINANCIALTRANSACTIONLINEITEM REVENUESPLIT
on REVENUESPLIT.FINANCIALTRANSACTIONID = REVENUE.ID
left outer join dbo.REVENUESPLITORDER
on REVENUESPLITORDER.ID = REVENUESPLIT.ID
where CREDITITEMS.FEES > 0
and FEES.AMOUNT > 0
and SALESORDER.ID = @SALESORDERID
and REVENUESPLITORDER.FEEID = SALESORDERITEMFEE.FEEID
--Contributed revenue
insert into @INS(
ID
,CREDITID
,SALESORDERITEMID
,QUANTITY
,PRICE
,FEES
,DISCOUNTS
,TYPECODE
,DESCRIPTION
,GROUPID
,GROUPTYPECODE
,SOURCELINEITEMID
,ISCONTRIBUTEDREVENUE
,TOTALAMOUNT)
select
newid(),
@ID,
null, --SALESORDERITEMID
1, --QUANTITYREFUNDING
FTLI.ORGAMOUNT,
0, --FEES
case when FTLI.ORGAMOUNT >= sum(isnull(I.DISCOUNTS, 0)) then sum(isnull(I.DISCOUNTS, 0)) else FTLI.ORGAMOUNT end,--DISCOUNTS
case
when REVENUESPLIT_EXT.APPLICATIONCODE = 1 then 6
else 2
end, --TYPECODE
FTLI.DESCRIPTION, --DESCRIPTION
null, --GROUPID
0, --GROUPTYPECODE
FTLI.ID,
1,
sum(PAYMENTLI.ORGAMOUNT)
from FINANCIALTRANSACTIONLINEITEM FTLI
inner join REVENUESPLIT_EXT on REVENUESPLIT_EXT.ID = FTLI.ID
inner join @INS I on I.SOURCELINEITEMID = FTLI.SOURCELINEITEMID
--I.SOURCELINEITEM is the membership source FTLI for the refunds, FTLI's SOURCELINEITEM is the membership FTLI that caused the donation FTLI
inner join dbo.FINANCIALTRANSACTIONLINEITEM PAYMENTLI on PAYMENTLI.SOURCELINEITEMID = FTLI.ID
inner join dbo.FINANCIALTRANSACTION PAYMENTFT on PAYMENTFT.ID = PAYMENTLI.FINANCIALTRANSACTIONID
where revenuesplit_ext.TYPECODE = 0 and (REVENUESPLIT_EXT.APPLICATIONCODE = 0 or REVENUESPLIT_EXT.APPLICATIONCODE = 1)
and FTLI.TYPECODE = 0
and PAYMENTFT.TYPECODE = 0
group by FTLI.ID, FTLI.DESCRIPTION, FTLI.ORGAMOUNT, REVENUESPLIT_EXT.APPLICATIONCODE
--update the contributed revenue amount for memberships
;with CTE_CONTRIBUTEDREVENUE as
(
select
sum(FTLI.TRANSACTIONAMOUNT)AMOUNT,
I.SOURCELINEITEMID,
SUM(isnull(I.DISCOUNTS, 0)) DISCOUNTS
from @INS I
inner join dbo.FINANCIALTRANSACTIONLINEITEM FTLI on FTLI.SOURCELINEITEMID = I.SOURCELINEITEMID
inner join dbo.REVENUESPLIT_EXT on REVENUESPLIT_EXT.ID = FTLI.ID
where REVENUESPLIT_EXT.TYPECODE = 0 and REVENUESPLIT_EXT.APPLICATIONCODE = 0 --only donations
and FTLI.TYPECODE = 0 --only standard ft line items
group by I.SOURCELINEITEMID
)
update @INS
set I.CONTRIBUTEDREVENUE = CT.AMOUNT
,I.DISCOUNTS = isnull(I.DISCOUNTS, 0) - CT.DISCOUNTS
from @INS I
inner join CTE_CONTRIBUTEDREVENUE CT on CT.SOURCELINEITEMID = I.SOURCELINEITEMID
--update final amount with discounts and contributed revenue
update @INS
set TOTALAMOUNT =
case
when isnull(CONTRIBUTEDREVENUE, 0) > DISCOUNTS then --the discount is only taken out of the contributed revenue
(PRICE * QUANTITY) - isnull(CONTRIBUTEDREVENUE, 0)
when ISCONTRIBUTEDREVENUE = 1 then --this is the contributed revenue and the appropriate amount was set when it was inserted into @INS
TOTALAMOUNT
else
(PRICE * QUANTITY) - isnull(DISCOUNTS, 0)
end
--earned income needs to reflect the FTLI table entry, not the SOI table entry for events that have designations on fees.
update @INS
set TOTALAMOUNT = (select TRANSACTIONAMOUNT from dbo.FINANCIALTRANSACTIONLINEITEM LI where LI.ID = I.SOURCELINEITEMID)
from
@INS I
inner join
dbo.SALESORDERITEM SOI on SOI.ID = I.SALESORDERITEMID
inner join
dbo.SALESORDERITEMEVENTREGISTRATION ER on ER.ID = SOI.ID
inner join
dbo.REGISTRANT R on R.ID = ER.REGISTRANTID
inner join
dbo.EVENT E on E.ID = R.EVENTID
where
E.DESIGNATIONSONFEES = 1;
insert into dbo.FINANCIALTRANSACTIONLINEITEM(
ID
,FINANCIALTRANSACTIONID
,UNITVALUE
,QUANTITY
,DESCRIPTION
,TRANSACTIONAMOUNT
,BASEAMOUNT
,ORGAMOUNT
,POSTDATE
,POSTSTATUSCODE
,TYPECODE
,SOURCELINEITEMID
,ADDEDBYID, CHANGEDBYID, DATEADDED, DATECHANGED)
select
I.ID
,I.CREDITID
,I.PRICE
,I.QUANTITY
,I.DESCRIPTION
,TOTALAMOUNT
,TOTALAMOUNT
,TOTALAMOUNT
,FT.POSTDATE
,FT.POSTSTATUSCODE
,CASE I.TYPECODE
WHEN 3 then 7 --Fee
WHEN 4 then 8 --Tax
WHEN 5 then 5 --Discount
ELSE 0 end
,I.SOURCELINEITEMID
,@CHANGEAGENTID, @CHANGEAGENTID, @CURRENTDATE, @CURRENTDATE
from @INS I
inner join dbo.FINANCIALTRANSACTION FT on FT.ID = I.CREDITID;
insert into dbo.CREDITITEM_EXT(
ID
,CREDITID
,DISCOUNTS
,FEES
,GROUPID
,GROUPTYPECODE
,SALESORDERITEMID
,TYPECODE
,ADDEDBYID, CHANGEDBYID, DATEADDED, DATECHANGED)
select
I.ID
,I.CREDITID
,I.DISCOUNTS
,I.FEES
,I.GROUPID
,I.GROUPTYPECODE
,I.SALESORDERITEMID
,I.TYPECODE
,@CHANGEAGENTID, @CHANGEAGENTID, @CURRENTDATE, @CURRENTDATE
from @INS I;
--update ticket status for returned tickets
with TICKETIDS_CTE as(
select
[TICKET].[ID],
row_number() over(partition by [TICKET].[SALESORDERITEMTICKETID] order by [TICKET].[ID]) as [ROWNUMBER],
[CREDITITEMS].[QUANTITYREFUNDING]
from dbo.[TICKET]
inner join @CREDITITEMS [CREDITITEMS] on
[TICKET].[SALESORDERITEMTICKETID] = [CREDITITEMS].[SALESORDERITEMID]
where
[TICKET].[SALESORDERITEMTICKETID] = [CREDITITEMS].[SALESORDERITEMID] and
[TICKET].[STATUSCODE] in (0, 1) and
[TICKET].[APPLIEDTOMEMBERSHIP] = 0
)
update
dbo.[TICKET]
set
[TICKET].[STATUSCODE] = 2
from
dbo.[TICKET]
inner join
TICKETIDS_CTE as [TICKETIDS] on [TICKET].[ID] = [TICKETIDS].[ID]
where
[TICKETIDS].[ROWNUMBER] <= [TICKETIDS].[QUANTITYREFUNDING]
-- Update on hand quantity for returned merchandise items
update dbo.[MERCHANDISEPRODUCTINSTANCE]
set [ONHANDQUANTITY] = [ONHANDQUANTITY] + [CI].[QUANTITYREFUNDING]
from @CREDITITEMS [CI]
inner join dbo.[SALESORDERITEM] [SOI] on [SOI].[ID] = [CI].[SALESORDERITEMID]
inner join dbo.[SALESORDERITEMMERCHANDISE] [SOIM] on [SOIM].[ID] = [SOI].[ID]
where [MERCHANDISEPRODUCTINSTANCE].[ID] = [SOIM].[MERCHANDISEPRODUCTINSTANCEID]
--update ticket applied to membership field
update
dbo.[TICKET]
set
[TICKET].[APPLIEDTOMEMBERSHIP] = 0,
[TICKET].[APPLIEDTOMEMBERSHIPSALESORDERID] = null
from dbo.[TICKET]
inner join dbo.[SALESORDERITEMMEMBERSHIPITEMPROMOTIONAPPLIEDITEMTICKET] [APPLIEDTICKETS] on
[TICKET].[ID] = [APPLIEDTICKETS].[TICKETID]
inner join dbo.[SALESORDERITEMMEMBERSHIPITEMPROMOTIONAPPLIEDITEM] [APPLIEDITEM] on
APPLIEDTICKETS.SALESORDERITEMMEMBERSHIPITEMPROMOTIONAPPLIEDITEMID = [APPLIEDITEM].[ID]
inner join dbo.[SALESORDERITEMMEMBERSHIPITEMPROMOTION] [PROMOTION] on
[APPLIEDITEM].[SALESORDERITEMMEMBERSHIPITEMPROMOTIONID] = [PROMOTION].[ID]
inner join @CREDITITEMS [CREDITITEMS] on
[PROMOTION].[SALESORDERITEMID] = [CREDITITEMS].[SALESORDERITEMID]
--Add credit membership items
insert into dbo.[CREDITITEMMEMBERSHIP]
(
[ID],
[MEMBERSHIPID],
[MEMBERSHIPPROGRAMID],
[MEMBERSHIPPROGRAMNAME],
[MEMBERSHIPLEVELID],
[MEMBERSHIPLEVELTERMID],
[MEMBERSHIPLEVELTYPECODEID],
[NUMBEROFCHILDREN],
[COMMENTS],
[ISGIFT],
[GIVENBYID],
[EXPIRATIONDATE],
[MEMBERS],
[ACTIONCODE],
[ADDEDBYID],
[CHANGEDBYID],
[DATEADDED],
[DATECHANGED]
)
select
[CREDITITEMS].[ID],
[SALESORDERITEMMEMBERSHIP].[MEMBERSHIPID],
[SALESORDERITEMMEMBERSHIP].[MEMBERSHIPPROGRAMID],
[SALESORDERITEMMEMBERSHIP].[MEMBERSHIPPROGRAMNAME],
[SALESORDERITEMMEMBERSHIP].[MEMBERSHIPLEVELID],
[SALESORDERITEMMEMBERSHIP].[MEMBERSHIPLEVELTERMID],
[SALESORDERITEMMEMBERSHIP].[MEMBERSHIPLEVELTYPECODEID],
[SALESORDERITEMMEMBERSHIP].[NUMBEROFCHILDREN],
[SALESORDERITEMMEMBERSHIP].[COMMENTS],
[SALESORDERITEMMEMBERSHIP].[ISGIFT],
[SALESORDERITEMMEMBERSHIP].[GIVENBYID],
[SALESORDERITEMMEMBERSHIP].[EXPIRATIONDATE],
(
select dbo.UFN_CONSTITUENT_BUILDNAME([SOIM].[CONSTITUENTID]) [MEMBERNAME]
from dbo.[SALESORDERITEMMEMBER] as [SOIM]
inner join dbo.[SALESORDERITEMMEMBERSHIP] as [SOIMS]
on [SOIM].[SALESORDERITEMMEMBERSHIPID] = [SOIMS].[ID]
inner join dbo.[MEMBER]
on [MEMBER].[CONSTITUENTID] = [SOIM].[CONSTITUENTID]
and [MEMBER].[MEMBERSHIPID] = [SOIMS].[MEMBERSHIPID]
where [SALESORDERITEMMEMBERSHIP].[ID] = [SOIM].[SALESORDERITEMMEMBERSHIPID] and [MEMBER].[ISDROPPED] = 0
for xml raw('ITEM'),type,elements,root('MEMBERSHIPMEMBERS'),binary base64
),
coalesce(
[MEMBERSHIPTRANSACTION].[ACTIONCODE],
(select [MEMBERSHIPTRANSACTION].[ACTIONCODE] from dbo.[MEMBERSHIPTRANSACTION] where [ID] = dbo.UFN_MEMBERSHIP_GETLASTMEMBERSHIPTRANSACTIONID([SALESORDERITEMMEMBERSHIP].[MEMBERSHIPID]))
),
@CHANGEAGENTID,
@CHANGEAGENTID,
@CURRENTDATE,
@CURRENTDATE
from @CREDITITEMS as [CREDITITEMS]
inner join dbo.[SALESORDERITEM]
on [CREDITITEMS].[SALESORDERITEMID] = [SALESORDERITEM].[ID]
inner join dbo.[SALESORDERITEMMEMBERSHIP]
on [SALESORDERITEM].[ID] = [SALESORDERITEMMEMBERSHIP].[ID]
left join dbo.[MEMBERSHIPTRANSACTION]
on [SALESORDERITEMMEMBERSHIP].[MEMBERSHIPTRANSACTIONID] = [MEMBERSHIPTRANSACTION].[ID]
--Add credit event registration items
insert into dbo.[CREDITITEMEVENTREGISTRATION]
(
[ID],
[REGISTRANTID],
[EVENTNAME],
[ADDEDBYID],
[CHANGEDBYID],
[DATEADDED],
[DATECHANGED]
)
select
[CREDITITEMS].[ID],
[SALESORDERITEMEVENTREGISTRATION].[REGISTRANTID],
[SALESORDERITEMEVENTREGISTRATION].[EVENTNAME],
@CHANGEAGENTID,
@CHANGEAGENTID,
@CURRENTDATE,
@CURRENTDATE
from @CREDITITEMS as [CREDITITEMS]
inner join dbo.[SALESORDERITEM]
on [CREDITITEMS].[SALESORDERITEMID] = [SALESORDERITEM].[ID]
inner join dbo.[SALESORDERITEMEVENTREGISTRATION]
on [SALESORDERITEM].[ID] = [SALESORDERITEMEVENTREGISTRATION].[ID]
--Order level discounts
--order discounts are 'all or none'... we don't currently
--refund part of an order discount
if @ORDERDISCOUNTS > 0 begin
insert into dbo.[CREDITITEM]
(
[CREDITID],
[SALESORDERITEMID],
[QUANTITY],
[PRICE],
[FEES],
[DISCOUNTS],
[TYPECODE],
[DESCRIPTION],
[GROUPID],
[GROUPTYPECODE],
[REVENUESPLITID],
[ADDEDBYID],
[CHANGEDBYID],
[DATEADDED],
[DATECHANGED]
)
select distinct
@ID,
[ID],
[QUANTITY],
-[PRICE],
0,
0,
[SALESORDERITEM].[TYPECODE],
[SALESORDERITEM].[DESCRIPTION],
null,
0,
null [REVENUESPLITID],
@CHANGEAGENTID,
@CHANGEAGENTID,
@CURRENTDATE,
@CURRENTDATE
from dbo.[SALESORDERITEM] where [TYPECODE] = 5 and [SALESORDERID] = @CONTEXTID
end
--Add item level discounts
insert into dbo.CREDITITEMITEMDISCOUNT
(
CREDITITEMID,
SALESORDERITEMITEMDISCOUNTID,
AMOUNT,
ADDEDBYID,
CHANGEDBYID,
DATEADDED,
DATECHANGED
)
select distinct
LI.ID,
SALESORDERITEMITEMDISCOUNT.ID,
SALESORDERITEMITEMDISCOUNT.AMOUNT, --Right now, the entire discount has to be returned
@CHANGEAGENTID,
@CHANGEAGENTID,
@CURRENTDATE,
@CURRENTDATE
from
dbo.SALESORDERITEMITEMDISCOUNT
inner join
dbo.CREDITITEM_EXT as EXT on EXT.SALESORDERITEMID = SALESORDERITEMITEMDISCOUNT.SALESORDERITEMID
inner join
dbo.FINANCIALTRANSACTIONLINEITEM as LI on LI.ID = EXT.ID
where
LI.FINANCIALTRANSACTIONID = @ID;
--Add item membership promotions
insert into dbo.CREDITITEMMEMBERSHIPITEMPROMOTION
(
CREDITITEMID,
SALESORDERITEMMEMBERSHIPITEMPROMOTIONID,
AMOUNT,
ADDEDBYID,
CHANGEDBYID,
DATEADDED,
DATECHANGED
)
select distinct
LI.ID,
SALESORDERITEMMEMBERSHIPITEMPROMOTION.ID,
SALESORDERITEMMEMBERSHIPITEMPROMOTION.AMOUNT, --Right now, the entire promotion has to be returned
@CHANGEAGENTID,
@CHANGEAGENTID,
@CURRENTDATE,
@CURRENTDATE
from
dbo.SALESORDERITEMMEMBERSHIPITEMPROMOTION
inner join
dbo.CREDITITEM_EXT as EXT on EXT.SALESORDERITEMID = SALESORDERITEMMEMBERSHIPITEMPROMOTION.SALESORDERITEMID
inner join
dbo.FINANCIALTRANSACTIONLINEITEM as LI on LI.ID = EXT.ID
where
LI.FINANCIALTRANSACTIONID = @ID;
update LI set
QUANTITY = CREDITITEMTICKETCOUNTS.NUMOFTICKETS,
CHANGEDBYID = @CHANGEAGENTID,
DATECHANGED = @CURRENTDATE
from
dbo.FINANCIALTRANSACTIONLINEITEM as LI
inner join
dbo.FINANCIALTRANSACTION as FT on FT.ID = LI.FINANCIALTRANSACTIONID
inner join
dbo.CREDIT_EXT on CREDIT_EXT.ID = FT.ID
inner join (
select
CREDITITEMTICKET.CREDITITEMID,
count(*) as NUMOFTICKETS
from dbo.CREDITITEMTICKET
group by CREDITITEMTICKET.CREDITITEMID
) as CREDITITEMTICKETCOUNTS on CREDITITEMTICKETCOUNTS.CREDITITEMID = LI.ID
left outer join
dbo.SALESORDER on SALESORDER.REVENUEID = FT.PARENTID
where
@CONTEXTID in (SALESORDER.ID, CREDIT_EXT.SALESORDERID);
end
--If it's a membership refund
else if @CONTEXTTYPE = 1 begin
--Error if there are any later membership transactions
set @LATESTTRANSACTIONID =
(select top(1)
[ID]
from dbo.[MEMBERSHIPTRANSACTION]
where [MEMBERSHIPID] = @MEMBERSHIPID order by [DATEADDED] desc)
if @TRANSACTIONID <> @LATESTTRANSACTIONID begin
raiserror('ERR_ITEMS_MEMBERSHIPREFUND_HASNEWERMEMBERSHIPTRANSACTIONS', 13, 1);
end
insert into @INS(
ID
,CREDITID
,SALESORDERITEMID
,QUANTITY
,PRICE
,FEES
,DISCOUNTS
,TYPECODE
,DESCRIPTION
,GROUPID
,GROUPTYPECODE
,SOURCELINEITEMID)
select
[ID],
@ID,
[SALESORDERITEMID],
[QUANTITYREFUNDING],
case
when DISCOUNTS > 0 or TYPECODE <> 1 then -- cannot partially refund discounted membership
[PRICE] -- so we want the full price of the membership, no the discounted price
else -- if it's possibly a partial refund, we want just the partial portion
[REFUNDINGTOTAL]
end [PRICE],
0 as [FEES],
coalesce([DISCOUNTS],0),
[TYPECODE],
[DESCRIPTION],
null as [GROUPID],
0 as [GROUPTYPECODE],
[REVENUESPLITID]
from @CREDITITEMS [CREDITITEMS]
where [QUANTITYREFUNDING] > 0
--Add contributed revenue
insert into @INS(
ID
,CREDITID
,SALESORDERITEMID
,QUANTITY
,PRICE
,FEES
,DISCOUNTS
,TYPECODE
,DESCRIPTION
,GROUPID
,GROUPTYPECODE
,SOURCELINEITEMID
,ISCONTRIBUTEDREVENUE
,TOTALAMOUNT)
select
newid(),
@ID,
null, --SALESORDERITEMID
1, --QUANTITYREFUNDING
FTLI.ORGAMOUNT,
0, --FEES
case when FTLI.ORGAMOUNT >= sum(isnull(I.DISCOUNTS, 0)) then sum(isnull(I.DISCOUNTS, 0)) else FTLI.ORGAMOUNT end,--DISCOUNTS
2, --TYPECODE
FTLI.DESCRIPTION, --DESCRIPTION
null, --GROUPID
0, --GROUPTYPECODE
FTLI.ID,
1,
sum(PAYMENTLI.ORGAMOUNT)
from FINANCIALTRANSACTIONLINEITEM FTLI
inner join REVENUESPLIT_EXT on REVENUESPLIT_EXT.ID = FTLI.ID
inner join @INS I on I.SOURCELINEITEMID = FTLI.SOURCELINEITEMID
--I.SOURCELINEITEM is the membership source FTLI for the refunds, FTLI's SOURCELINEITEM is the membership FTLI that caused the donation FTLI
inner join dbo.FINANCIALTRANSACTIONLINEITEM PAYMENTLI on PAYMENTLI.SOURCELINEITEMID = FTLI.ID
inner join dbo.FINANCIALTRANSACTION PAYMENTFT on PAYMENTFT.ID = PAYMENTLI.FINANCIALTRANSACTIONID
where revenuesplit_ext.TYPECODE = 0 and revenuesplit_ext.APPLICATIONCODE = 0
and FTLI.TYPECODE = 0
and PAYMENTFT.TYPECODE = 0
group by FTLI.ID, FTLI.DESCRIPTION, FTLI.ORGAMOUNT
--update the contributed revenue amount for memberships
;with CTE_CONTRIBUTEDREVENUE as
(
select
sum(FTLI.TRANSACTIONAMOUNT)AMOUNT,
I.SOURCELINEITEMID,
SUM(isnull(I.DISCOUNTS, 0)) DISCOUNTS
from @INS I
inner join dbo.FINANCIALTRANSACTIONLINEITEM FTLI on FTLI.SOURCELINEITEMID = I.SOURCELINEITEMID
inner join dbo.REVENUESPLIT_EXT on REVENUESPLIT_EXT.ID = FTLI.ID
where REVENUESPLIT_EXT.TYPECODE = 0 and REVENUESPLIT_EXT.APPLICATIONCODE = 0 --only donations
and FTLI.TYPECODE = 0 --only standard ft line items
group by I.SOURCELINEITEMID
)
update @INS
set I.CONTRIBUTEDREVENUE = CT.AMOUNT
,I.DISCOUNTS = isnull(I.DISCOUNTS, 0) - CT.DISCOUNTS
from @INS I
inner join CTE_CONTRIBUTEDREVENUE CT on CT.SOURCELINEITEMID = I.SOURCELINEITEMID
--update final amount with discounts and contributed revenue
update @INS
set TOTALAMOUNT =
case
when SALESORDERITEMID is not null and isnull(CONTRIBUTEDREVENUE, 0) > DISCOUNTS then --the discount is only taken out of the contributed revenue
(PRICE * QUANTITY) - isnull(CONTRIBUTEDREVENUE, 0)
when SALESORDERITEMID is not null and ISCONTRIBUTEDREVENUE = 1 then --this is the contributed revenue and the appropriate amount was set when it was inserted into @INS
TOTALAMOUNT
else
(PRICE * QUANTITY) - isnull(DISCOUNTS, 0)
end
insert into dbo.FINANCIALTRANSACTIONLINEITEM(
ID
,FINANCIALTRANSACTIONID
,UNITVALUE
,QUANTITY
,DESCRIPTION
,TRANSACTIONAMOUNT
,BASEAMOUNT
,ORGAMOUNT
,POSTDATE
,POSTSTATUSCODE
,TYPECODE
,SOURCELINEITEMID
,ADDEDBYID, CHANGEDBYID, DATEADDED, DATECHANGED)
select
I.ID
,I.CREDITID
,I.PRICE
,I.QUANTITY
,I.DESCRIPTION
,TOTALAMOUNT
,TOTALAMOUNT
,TOTALAMOUNT
,FT.POSTDATE
,FT.POSTSTATUSCODE
,CASE I.TYPECODE
WHEN 3 then 7 --Fee
WHEN 4 then 8 --Tax
WHEN 5 then 5 --Discount
ELSE 0 end
,SOURCELINEITEMID
,@CHANGEAGENTID, @CHANGEAGENTID, @CURRENTDATE, @CURRENTDATE
from @INS I
inner join dbo.FINANCIALTRANSACTION FT on FT.ID = I.CREDITID;
insert into dbo.CREDITITEM_EXT(
ID
,CREDITID
,DISCOUNTS
,FEES
,GROUPID
,GROUPTYPECODE
,SALESORDERITEMID
,TYPECODE
,ADDEDBYID, CHANGEDBYID, DATEADDED, DATECHANGED)
select
I.ID
,I.CREDITID
,I.DISCOUNTS
,I.FEES
,I.GROUPID
,I.GROUPTYPECODE
,I.SALESORDERITEMID
,I.TYPECODE
,@CHANGEAGENTID, @CHANGEAGENTID, @CURRENTDATE, @CURRENTDATE
from @INS I;
insert into dbo.[CREDITITEMMEMBERSHIP]
(
[ID],
[MEMBERSHIPID],
[MEMBERSHIPPROGRAMID],
[MEMBERSHIPPROGRAMNAME],
[MEMBERSHIPLEVELID],
[MEMBERSHIPLEVELTERMID],
[MEMBERSHIPLEVELTYPECODEID],
[NUMBEROFCHILDREN],
[COMMENTS],
[ISGIFT],
[GIVENBYID],
[EXPIRATIONDATE],
[MEMBERS],
[ACTIONCODE],
[ADDEDBYID],
[CHANGEDBYID],
[DATEADDED],
[DATECHANGED]
)
select
[CREDITITEMS].[ID],
[MEMBERSHIPTRANSACTION].[MEMBERSHIPID],
[MEMBERSHIP].[MEMBERSHIPPROGRAMID],
(select [NAME] from dbo.[MEMBERSHIPPROGRAM] where [ID] = [MEMBERSHIP].[MEMBERSHIPPROGRAMID]),
[MEMBERSHIPTRANSACTION].[MEMBERSHIPLEVELID],
[MEMBERSHIPTRANSACTION].[MEMBERSHIPLEVELTERMID],
[MEMBERSHIPTRANSACTION].[MEMBERSHIPLEVELTYPECODEID],
[MEMBERSHIPTRANSACTION].[NUMBEROFCHILDREN],
[MEMBERSHIPTRANSACTION].[COMMENTS],
[MEMBERSHIPTRANSACTION].[ISGIFT],
[MEMBERSHIPTRANSACTION].[DONORID],
[MEMBERSHIPTRANSACTION].[EXPIRATIONDATE],
(
select dbo.[UFN_CONSTITUENT_BUILDNAME]([MEMBER].[CONSTITUENTID]) [MEMBERNAME]
from dbo.[MEMBER]
where [MEMBER].[MEMBERSHIPID] = [MEMBERSHIP].[ID]
for xml raw('ITEM'),type,elements,root('MEMBERSHIPMEMBERS'),binary base64
),
[MEMBERSHIPTRANSACTION].[ACTIONCODE],
@CHANGEAGENTID,
@CHANGEAGENTID,
@CURRENTDATE,
@CURRENTDATE
from dbo.[MEMBERSHIPTRANSACTION]
inner join dbo.[MEMBERSHIP]
on [MEMBERSHIPTRANSACTION].[MEMBERSHIPID] = [MEMBERSHIP].[ID]
inner join @CREDITITEMS [CREDITITEMS] on [CREDITITEMS].[ITEMID] = [MEMBERSHIPTRANSACTION].[ID]
where [MEMBERSHIPTRANSACTION].[ID] = @TRANSACTIONID
--update ticket applied to membership field
update
dbo.[TICKET]
set
[TICKET].[APPLIEDTOMEMBERSHIP] = 0,
[TICKET].[APPLIEDTOMEMBERSHIPSALESORDERID] = null
from dbo.[TICKET]
inner join dbo.[SALESORDERITEMMEMBERSHIPITEMPROMOTIONAPPLIEDITEMTICKET] [APPLIEDTICKETS] on
[TICKET].[ID] = [APPLIEDTICKETS].[TICKETID]
inner join dbo.[SALESORDERITEMMEMBERSHIPITEMPROMOTIONAPPLIEDITEM] [APPLIEDITEM] on
[APPLIEDTICKETS].[SALESORDERITEMMEMBERSHIPITEMPROMOTIONAPPLIEDITEMID] = [APPLIEDITEM].[ID]
inner join dbo.[SALESORDERITEMMEMBERSHIPITEMPROMOTION] [PROMOTION] on
[APPLIEDITEM].[SALESORDERITEMMEMBERSHIPITEMPROMOTIONID] = [PROMOTION].[ID]
inner join @CREDITITEMS [CREDITITEMS] on
[PROMOTION].[SALESORDERITEMID] = [CREDITITEMS].[SALESORDERITEMID]
--Add item membership promotions
insert into dbo.CREDITITEMMEMBERSHIPITEMPROMOTION
(
CREDITITEMID,
SALESORDERITEMMEMBERSHIPITEMPROMOTIONID,
AMOUNT,
ADDEDBYID,
CHANGEDBYID,
DATEADDED,
DATECHANGED
)
select distinct
LI.ID,
SALESORDERITEMMEMBERSHIPITEMPROMOTION.ID,
SALESORDERITEMMEMBERSHIPITEMPROMOTION.AMOUNT, --Right now, the entire promotion has to be returned
@CHANGEAGENTID,
@CHANGEAGENTID,
@CURRENTDATE,
@CURRENTDATE
from
dbo.SALESORDERITEMMEMBERSHIPITEMPROMOTION
inner join
dbo.CREDITITEM_EXT as EXT on EXT.SALESORDERITEMID = SALESORDERITEMMEMBERSHIPITEMPROMOTION.SALESORDERITEMID
inner join
dbo.FINANCIALTRANSACTIONLINEITEM as LI on LI.ID = EXT.ID
where
LI.FINANCIALTRANSACTIONID = @ID
end
--If it's an event registration refund
else if @CONTEXTTYPE = 2 begin
delete from @INS
--Save to the credit item structure
insert into @INS(
ID
,CREDITID
,SALESORDERITEMID
,QUANTITY
,PRICE
,FEES
,DISCOUNTS
,TYPECODE
,DESCRIPTION
,GROUPID
,GROUPTYPECODE
,SOURCELINEITEMID)
select
newid(), -- 2013-07-10 SW: account for multiple backoffice payment methods
@ID,
[CREDITPAYMENTS].[SALESORDERITEMID],
1 as [QUANTITY],
coalesce([CREDITPAYMENTS].[AMOUNT],0), -- switch to refund amount
0 as [FEES],
0 as [DISCOUNTS],
6 as [TYPECODE],
dbo.UFN_CONSTITUENT_BUILDNAME([REGISTRANT].[CONSTITUENTID]) + ' - ' + EVENT.NAME,
[CREDITITEMS].[GROUPID],
coalesce([CREDITPAYMENTS].[GROUPTYPECODE],1),
[CREDITPAYMENTS].[REVENUESPLITID]
from @CREDITITEMS [CREDITITEMS]
inner join dbo.[REGISTRANT]
on [CREDITITEMS].[GROUPID] = [REGISTRANT].[ID]
inner join dbo.[EVENT] on [REGISTRANT].[EVENTID] = [EVENT].[ID]
outer apply (
--Backoffice payments
select
[CREDITPAYMENT].[AMOUNT],
1 as [GROUPTYPECODE],
null as [SALESORDERITEMID]
,[CREDITPAYMENT].[REVENUESPLITID]
from dbo.[CREDITPAYMENT]
inner join dbo.[EVENTREGISTRANTPAYMENT] on [CREDITPAYMENT].[REVENUESPLITID] = [EVENTREGISTRANTPAYMENT].[PAYMENTID]
where [CREDITPAYMENT].[REVENUESPLITID] is not null
and [CREDITPAYMENT].[CREDITID] = @ID
--Order payments
union all
select
sum([CREDITPAYMENT].[AMOUNT]) AMOUNT,
[CREDITITEMS].[GROUPTYPECODE],
[SALESORDERITEM].[ID] as [SALESORDERITEMID],
PAYMENTSPLIT.ID
from dbo.[CREDITPAYMENT]
inner join dbo.[SALESORDERPAYMENT] on [SALESORDERPAYMENT].[PAYMENTID] = [CREDITPAYMENT].[REVENUEID]
inner join dbo.SALESORDER on SALESORDER.ID = SALESORDERPAYMENT.SALESORDERID
inner join dbo.[SALESORDERITEM] on [SALESORDERITEM].[SALESORDERID] = [SALESORDERPAYMENT].[SALESORDERID]
inner join dbo.[SALESORDERITEMEVENTREGISTRATION] on [SALESORDERITEM].[ID] = [SALESORDERITEMEVENTREGISTRATION].[ID]
inner join dbo.[REGISTRANT] on [SALESORDERITEMEVENTREGISTRATION].[REGISTRANTID] = [REGISTRANT].[ID]
left join dbo.EVENTREGISTRANTPAYMENT on EVENTREGISTRANTPAYMENT.REGISTRANTID = REGISTRANT.ID
left join dbo.FINANCIALTRANSACTIONLINEITEM PAYMENTSPLIT on PAYMENTSPLIT.ID = EVENTREGISTRANTPAYMENT.PAYMENTID
left join dbo.REVENUESPLIT_EXT on REVENUESPLIT_EXT.ID = PAYMENTSPLIT.ID
left join dbo.FINANCIALTRANSACTION on FINANCIALTRANSACTION.ID = PAYMENTSPLIT.FINANCIALTRANSACTIONID
where [SALESORDERITEMEVENTREGISTRATION].[REGISTRANTID] = @TRANSACTIONID
and [CREDITPAYMENT].[CREDITID] = @ID
and FINANCIALTRANSACTION.ID = SALESORDER.REVENUEID
and REVENUESPLIT_EXT.APPLICATIONCODE = 1 and REVENUESPLIT_EXT.TYPECODE = 1
group by [SALESORDERITEM].[ID], PAYMENTSPLIT.ID
) [CREDITPAYMENTS]
--Add contributed revenue
insert into @INS(
ID
,CREDITID
,SALESORDERITEMID
,QUANTITY
,PRICE
,FEES
,DISCOUNTS
,TYPECODE
,DESCRIPTION
,GROUPID
,GROUPTYPECODE
,SOURCELINEITEMID
,ISCONTRIBUTEDREVENUE
,TOTALAMOUNT)
select
newid(),
@ID,
null, --SALESORDERITEMID
1, --QUANTITYREFUNDING
FTLI.ORGAMOUNT,
0, --FEES
0,--DISCOUNTS
6, --TYPECODE
FTLI.DESCRIPTION, --DESCRIPTION
null, --GROUPID
0, --GROUPTYPECODE
FTLI.ID,
1,
sum(PAYMENTLI.ORGAMOUNT)
from FINANCIALTRANSACTIONLINEITEM FTLI
inner join REVENUESPLIT_EXT on REVENUESPLIT_EXT.ID = FTLI.ID
inner join @INS I on I.SOURCELINEITEMID = FTLI.SOURCELINEITEMID
inner join dbo.FINANCIALTRANSACTIONLINEITEM PAYMENTLI on PAYMENTLI.SOURCELINEITEMID = FTLI.ID
inner join dbo.FINANCIALTRANSACTION PAYMENTFT on PAYMENTFT.ID = PAYMENTLI.FINANCIALTRANSACTIONID
where revenuesplit_ext.TYPECODE = 0 and revenuesplit_ext.APPLICATIONCODE = 1
and FTLI.TYPECODE = 0
and PAYMENTFT.TYPECODE = 0
group by FTLI.ID, FTLI.DESCRIPTION, FTLI.ORGAMOUNT
--update the contributed revenue amount for event registration
;with CTE_CONTRIBUTEDREVENUE as
(
select
sum(FTLI.TRANSACTIONAMOUNT)AMOUNT,
I.SOURCELINEITEMID
from @INS I
inner join dbo.FINANCIALTRANSACTIONLINEITEM FTLI on FTLI.SOURCELINEITEMID = I.SOURCELINEITEMID
inner join dbo.REVENUESPLIT_EXT on REVENUESPLIT_EXT.ID = FTLI.ID
where REVENUESPLIT_EXT.TYPECODE = 0 and REVENUESPLIT_EXT.APPLICATIONCODE = 1 --only donations
and FTLI.TYPECODE = 0 --only standard ft line items
group by I.SOURCELINEITEMID
)
update @INS
set I.CONTRIBUTEDREVENUE = CT.AMOUNT
from @INS I
inner join CTE_CONTRIBUTEDREVENUE CT on CT.SOURCELINEITEMID = I.SOURCELINEITEMID
--update final amount with discounts and contributed revenue
update @INS
set TOTALAMOUNT =
case
when SALESORDERITEMID is not null then
(PRICE * QUANTITY) - isnull(CONTRIBUTEDREVENUE, 0)
else
TOTALAMOUNT
end
--earned income needs to reflect the FTLI table entry, not the SOI table entry for events that have designations on fees.
update @INS
set TOTALAMOUNT = (select TRANSACTIONAMOUNT from dbo.FINANCIALTRANSACTIONLINEITEM LI where LI.ID = I.SOURCELINEITEMID)
from
@INS I
inner join
dbo.SALESORDERITEM SOI on SOI.ID = I.SALESORDERITEMID
inner join
dbo.SALESORDERITEMEVENTREGISTRATION ER on ER.ID = SOI.ID
inner join
dbo.REGISTRANT R on R.ID = ER.REGISTRANTID
inner join
dbo.EVENT E on E.ID = R.EVENTID
where
E.DESIGNATIONSONFEES = 1;
insert into dbo.FINANCIALTRANSACTIONLINEITEM(
ID
,FINANCIALTRANSACTIONID
,UNITVALUE
,QUANTITY
,DESCRIPTION
,TRANSACTIONAMOUNT
,BASEAMOUNT
,ORGAMOUNT
,POSTDATE
,POSTSTATUSCODE
,TYPECODE
,SOURCELINEITEMID
,ADDEDBYID, CHANGEDBYID, DATEADDED, DATECHANGED)
select
I.ID
,I.CREDITID
,I.PRICE
,I.QUANTITY
,I.DESCRIPTION
,isnull(TOTALAMOUNT, (I.PRICE * I.QUANTITY) - isnull(I.DISCOUNTS, 0))
,isnull(TOTALAMOUNT, (I.PRICE * I.QUANTITY) - isnull(I.DISCOUNTS, 0))
,isnull(TOTALAMOUNT, (I.PRICE * I.QUANTITY) - isnull(I.DISCOUNTS, 0))
,FT.POSTDATE
,FT.POSTSTATUSCODE
,CASE I.TYPECODE
WHEN 3 then 7 --Fee
WHEN 4 then 8 --Tax
WHEN 5 then 5 --Discount
ELSE 0 end
,I.SOURCELINEITEMID
,@CHANGEAGENTID, @CHANGEAGENTID, @CURRENTDATE, @CURRENTDATE
from @INS I
inner join dbo.FINANCIALTRANSACTION FT on FT.ID = I.CREDITID;
insert into dbo.CREDITITEM_EXT(
ID
,CREDITID
,DISCOUNTS
,FEES
,GROUPID
,GROUPTYPECODE
,SALESORDERITEMID
,TYPECODE
,ADDEDBYID, CHANGEDBYID, DATEADDED, DATECHANGED)
select
I.ID
,I.CREDITID
,I.DISCOUNTS
,I.FEES
,I.GROUPID
,I.GROUPTYPECODE
,I.SALESORDERITEMID
,I.TYPECODE
,@CHANGEAGENTID, @CHANGEAGENTID, @CURRENTDATE, @CURRENTDATE
from @INS I;
--Save to the credit item event registration structure
insert into dbo.CREDITITEMEVENTREGISTRATION
(
ID,
REGISTRANTID,
EVENTNAME,
ADDEDBYID,
CHANGEDBYID,
DATEADDED,
DATECHANGED
)
select
ID, -- 2013-07-10 SW: @INS.ID is not the same as @CREDITITEMS.ID
GROUPID,
DESCRIPTION,
@CHANGEAGENTID,
@CHANGEAGENTID,
@CURRENTDATE,
@CURRENTDATE
from @INS
end
--If there are extra-member type add-ons, we might need to drop some members.
if exists (
select
FINANCIALTRANSACTIONLINEITEM.ID
from dbo.FINANCIALTRANSACTIONLINEITEM
inner join dbo.MEMBERSHIPADDON
on MEMBERSHIPADDON.REVENUESPLITID = FINANCIALTRANSACTIONLINEITEM.SOURCELINEITEMID
inner join dbo.ADDON
on ADDON.ID = MEMBERSHIPADDON.ADDONID
where FINANCIALTRANSACTIONLINEITEM.FINANCIALTRANSACTIONID = @ID
and ADDON.ADDONTYPECODE = 1
) begin
declare @MEMBERSTODROP dbo.UDT_GENERICID;
--To figure out how many to drop, we have to calculate the total number of members allowed.
--That is the number of members the level allows, plus the number of extra member
--add-ons sold, minus previously refunded add-ons. Once we know this, we see if there's
--a difference between the number of members allowed and the current number of members.
--If there's no difference, we drop a number of members equal to the number of extra member
--add-ons we're refunding. If there is a difference, we take that into account and drop fewer.
--Note: we can assume that there will only ever be one membershiptransaction
--in the refund form for each membership
;with CTE_ADDONINFO as
(
select
MEMBERSHIPADDON.MEMBERSHIPTRANSACTIONID,
sum(FINANCIALTRANSACTIONLINEITEM.QUANTITY) as NUMBEROFADDONSREFUNDING,
(
select
count(MEMBER.ID)
from dbo.MEMBERSHIPTRANSACTION
inner join dbo.MEMBERSHIP
on MEMBERSHIP.ID = MEMBERSHIPTRANSACTION.MEMBERSHIPID
inner join dbo.MEMBER
on MEMBER.MEMBERSHIPID = MEMBERSHIP.ID
where MEMBERSHIPTRANSACTION.ID = MEMBERSHIPADDON.MEMBERSHIPTRANSACTIONID
and MEMBER.ISDROPPED = 0
) as TOTALNUMBEROFMEMBERS,
(
select
MEMBERSHIPLEVEL.MEMBERSALLOWED + sum(MA.QUANTITY)
from dbo.MEMBERSHIPTRANSACTION
inner join dbo.MEMBERSHIP
on MEMBERSHIP.ID = MEMBERSHIPTRANSACTION.MEMBERSHIPID
inner join dbo.MEMBERSHIPLEVEL
on MEMBERSHIPLEVEL.ID = MEMBERSHIP.MEMBERSHIPLEVELID
inner join dbo.MEMBERSHIPADDON MA
on MA.MEMBERSHIPTRANSACTIONID = MEMBERSHIPTRANSACTION.ID
inner join dbo.ADDON
on addon.ID = MA.ADDONID
where MEMBERSHIPTRANSACTION.ID = MEMBERSHIPADDON.MEMBERSHIPTRANSACTIONID
and ADDON.ADDONTYPECODE = 1
group by MEMBERSHIPTRANSACTION.ID, MEMBERSHIPLEVEL.MEMBERSALLOWED
) as NUMBERMEMBERSALLOWED, --level + add-ons sold. We'll subtract out previously refunded ones in the next cte.
(
select
coalesce(sum(FINANCIALTRANSACTIONLINEITEM.QUANTITY), 0)
from dbo.MEMBERSHIPTRANSACTION
inner join dbo.MEMBERSHIPADDON MA
on MA.MEMBERSHIPTRANSACTIONID = MEMBERSHIPTRANSACTION.ID
inner join dbo.ADDON
on addon.ID = MA.ADDONID
inner join dbo.FINANCIALTRANSACTIONLINEITEM
on FINANCIALTRANSACTIONLINEITEM.SOURCELINEITEMID = MA.REVENUESPLITID
inner join dbo.FINANCIALTRANSACTION FT
on FINANCIALTRANSACTIONLINEITEM.FINANCIALTRANSACTIONID = FT.ID
inner join dbo.CREDITITEM_EXT
on CREDITITEM_EXT.ID = FINANCIALTRANSACTIONLINEITEM.ID
where MEMBERSHIPTRANSACTION.ID = MEMBERSHIPADDON.MEMBERSHIPTRANSACTIONID
and ADDON.ADDONTYPECODE = 1
and FT.TYPECODE = 23 --refund
and CREDITITEM_EXT.TYPECODE = 16 --membershipaddon
and FINANCIALTRANSACTIONLINEITEM.FINANCIALTRANSACTIONID <> @ID
) as NUMBERPREVIOUSLYREFUNDED
from dbo.FINANCIALTRANSACTION
inner join dbo.FINANCIALTRANSACTIONLINEITEM
on FINANCIALTRANSACTIONLINEITEM.FINANCIALTRANSACTIONID = FINANCIALTRANSACTION.id
inner join dbo.MEMBERSHIPADDON
on FINANCIALTRANSACTIONLINEITEM.SOURCELINEITEMID = MEMBERSHIPADDON.REVENUESPLITID
inner join dbo.ADDON
on ADDON.ID = MEMBERSHIPADDON.ADDONID
where FINANCIALTRANSACTION.ID = @ID
and ADDON.ADDONTYPECODE = 1
group by MEMBERSHIPTRANSACTIONID, MEMBERSHIPADDON.MEMBERSHIPID
),
CTE_MEMBERINFO as
(
select
MEMBER.ID as MEMBERID,
row_number() over (partition by MEMBERSHIPTRANSACTION.ID order by MEMBER.DATEADDED desc) as ROWNUMBER,
ADDONINFO.NUMBEROFADDONSREFUNDING - (ADDONINFO.NUMBERMEMBERSALLOWED - ADDONINFO.NUMBERPREVIOUSLYREFUNDED - ADDONINFO.TOTALNUMBEROFMEMBERS) as NUMBERTODROP
from CTE_ADDONINFO as ADDONINFO
inner join dbo.MEMBERSHIPTRANSACTION
on MEMBERSHIPTRANSACTION.ID = addoninfo.MEMBERSHIPTRANSACTIONID
inner join dbo.MEMBER
on member.MEMBERSHIPID = MEMBERSHIPTRANSACTION.MEMBERSHIPID
where MEMBER.ISPRIMARY = 0
and MEMBER.ISDROPPED = 0
)
insert into @MEMBERSTODROP (ID)
select MEMBERINFO.MEMBERID
from CTE_MEMBERINFO MEMBERINFO
where MEMBERINFO.ROWNUMBER <= MEMBERINFO.NUMBERTODROP;
update dbo.MEMBER set
ISDROPPED = 1,
CHANGEDBYID = @CHANGEAGENTID,
DATECHANGED = @CURRENTDATE
where
ID in (select ID from @MEMBERSTODROP);
update dbo.MEMBERSHIPCARD set
STATUSCODE = 2, -- Cancelled
CHANGEDBYID = @CHANGEAGENTID,
DATECHANGED = @CURRENTDATE
where
MEMBERID in (select ID from @MEMBERSTODROP)
and STATUSCODE <> 2; -- Cancelled
end
if @ALLOWGLDISTRIBUTIONS=1 and isnull(@POSTSTATUSCODE, 1) != 3 begin
--create GL Distributions
exec dbo.USP_REFUND_CREATEGLDISTRIBUTION @ID, @CHANGEAGENTID, @CURRENTDATE
exec dbo.USP_REFUND_CREATEDISCOUNTGLDISTRIBUTION @ID, @CHANGEAGENTID, @CURRENTDATE
end
--Refunding memberships. This happens after GL since refunding the membership might delete the last membership transaction and that transaction is the path to the revenue split for sales order item memberships
if @CONTEXTTYPE = 0 begin
--Refund all memberships in the items grid
declare @SALESORDERITEMMEMBERSHIPID uniqueidentifier;
declare @MEMBERSHIPTRANSACTIONID uniqueidentifier
declare memberships_cursor cursor LOCAL FAST_FORWARD for
select [SALESORDERITEMMEMBERSHIP].[ID]
from @CREDITITEMS [CREDITITEMS]
inner join dbo.[SALESORDERITEMMEMBERSHIP]
on [CREDITITEMS].[SALESORDERITEMID] = [SALESORDERITEMMEMBERSHIP].[ID];
open memberships_cursor
fetch next from memberships_cursor
into @SALESORDERITEMMEMBERSHIPID
while @@FETCH_STATUS = 0 begin
select
@MEMBERSHIPID = [SALESORDERITEMMEMBERSHIP].[MEMBERSHIPID],
@MEMBERSHIPTRANSACTIONID = [SALESORDERITEMMEMBERSHIP].[MEMBERSHIPTRANSACTIONID]
from dbo.[SALESORDERITEMMEMBERSHIP]
where [SALESORDERITEMMEMBERSHIP].[ID] = @SALESORDERITEMMEMBERSHIPID
set @LATESTTRANSACTIONID =
(select top(1)
[ID]
from dbo.[MEMBERSHIPTRANSACTION]
where [MEMBERSHIPID] = @MEMBERSHIPID order by [DATEADDED] desc)
-- Before 6.14.10 ... The membership was $0 and no split was created for it
if @MEMBERSHIPTRANSACTIONID is null begin
--See if the last membership transaction was a drop. If it wasn't a drop and it was also for $0, assume the last one is the one for this order
--Worst that can happen: We cancel a membership the patron wanted to cancel anyway, but we don't mark the sales order item that was used in the last transaction as having been refunded
if exists (
select 1
from dbo.[MEMBERSHIPTRANSACTION]
where
[MEMBERSHIPTRANSACTION].[ID] = @LATESTTRANSACTIONID and
[MEMBERSHIPTRANSACTION].[ACTIONCODE] <> 4 and
[MEMBERSHIPTRANSACTION].[REVENUESPLITID] is null
) begin
set @MEMBERSHIPTRANSACTIONID = @LATESTTRANSACTIONID
end
end
--End no membership transaction handling (pre-6.14.10)
--Error if there are any later membership transactions
if @MEMBERSHIPTRANSACTIONID is null or (@MEMBERSHIPTRANSACTIONID <> @LATESTTRANSACTIONID) begin
raiserror('ERR_ITEMS_ORDERREFUND_HASNEWERMEMBERSHIPTRANSACTIONS', 13, 1);
end
exec dbo.USP_CREDIT_REFUNDMEMBERSHIP @ID = @MEMBERSHIPID, @CHANGEAGENTID = @CHANGEAGENTID, @MEMBERSHIPTRANSACTIONID = @MEMBERSHIPTRANSACTIONID
fetch next from memberships_cursor
into @SALESORDERITEMMEMBERSHIPID
end
close memberships_cursor
deallocate memberships_cursor
end
else if @CONTEXTTYPE = 1 and @MEMBERSHIPREFUNDHASMEMBERSHIP = 1 begin
set @MEMBERSHIPID = (select [MEMBERSHIPID] from dbo.[MEMBERSHIPTRANSACTION] where ID = @TRANSACTIONID)
exec dbo.USP_CREDIT_REFUNDMEMBERSHIP @ID = @MEMBERSHIPID, @CHANGEAGENTID = @CHANGEAGENTID, @MEMBERSHIPTRANSACTIONID = @TRANSACTIONID
end
end try
begin catch
exec dbo.USP_RAISE_ERROR
return 1
end catch
return 0;