USP_REFUND_CREATEGLDISTRIBUTION
Generates the GL distribution for a refund.
Parameters
Parameter | Parameter Type | Mode | Description |
---|---|---|---|
@CREDITID | uniqueidentifier | IN | |
@CHANGEAGENTID | uniqueidentifier | IN | |
@CHANGEDATE | datetime | IN | |
@CREDITPAYMENTID | uniqueidentifier | IN |
Definition
Copy
CREATE procedure dbo.USP_REFUND_CREATEGLDISTRIBUTION
(
@CREDITID uniqueidentifier,
@CHANGEAGENTID uniqueidentifier = null,
@CHANGEDATE datetime = null,
@CREDITPAYMENTID uniqueidentifier = null
)
as
begin
set nocount on;
if @CHANGEAGENTID is null
exec dbo.USP_CHANGEAGENT_GETORCREATECHANGEAGENT @CHANGEAGENTID output;
if @CHANGEDATE is null
set @CHANGEDATE = getdate();
declare @POSTDATE datetime;
select @POSTDATE = POSTDATE
from dbo.FINANCIALTRANSACTION where ID = @CREDITID;
--first, go get the distributions that we need to reverse...
declare @SOURCESPLITS table (
REVENUESPLITID uniqueidentifier,
FINANCIALTRANSACTIONID uniqueidentifier,
[TYPE] nvarchar(100),
REFUNDPAYMENTTOTAL money,
REFUNDSPLITAMOUNT money,
CREDITAMOUNT money,
CREDITPAYMENTID uniqueidentifier,
TYPECODE tinyint,
PAYMENTMETHODCODE tinyint,
CREDITITEMID uniqueidentifier
);
insert into @SOURCESPLITS
select
REVENUESPLITID,
FINANCIALTRANSACTIONID,
[TYPE],
REFUNDPAYMENTTOTAL,
REFUNDSPLITAMOUNT,
CREDITAMOUNT,
CREDITPAYMENTID,
TYPECODE,
PAYMENTMETHODCODE,
CREDITITEMID
from UFN_REFUND_GETITEMAMOUNTSFORGL(@CREDITID);
-- Prorate the credit payments across the items. TODO: a top-down distribution would probably be cleaner.
declare @PRORATEDSPLITS table (
AMOUNT money,
ID uniqueidentifier,
CREDITITEMID uniqueidentifier,
CREDITPAYMENTID uniqueidentifier
);
declare @CURRENTCREDITPAYMENTID uniqueidentifier, @CREDITAMOUNT money, @REFUNDPAYMENTTOTAL money;
declare cp_cur cursor local fast_forward for (select distinct CREDITPAYMENTID, CREDITAMOUNT, REFUNDPAYMENTTOTAL from @SOURCESPLITS);
open cp_cur;
fetch next from cp_cur into @CURRENTCREDITPAYMENTID, @CREDITAMOUNT, @REFUNDPAYMENTTOTAL;
while @@FETCH_STATUS = 0
begin
declare @AMOUNTSTOPRORATE xml = (
select
REVENUESPLITID as [@ID],
REFUNDSPLITAMOUNT as [@AMOUNT],
CREDITITEMID as [@CREDITITEMID]
from @SOURCESPLITS
where CREDITPAYMENTID = @CURRENTCREDITPAYMENTID
for xml path('ITEM'), type, elements, root('AMOUNTSTOPRORATE'), binary base64
);
-- Changed to a procedure due to a bug in SQL Server's optimization for insert-select from XML.
-- The bug does not affect "select into", but that's DDL, so the whole call chain needs to be converted to procedures.
insert into @PRORATEDSPLITS
exec dbo.USP_SPLITS_GETPRORATEDSPLITS @CREDITAMOUNT, @REFUNDPAYMENTTOTAL, @AMOUNTSTOPRORATE, @CURRENTCREDITPAYMENTID;
fetch next from cp_cur into @CURRENTCREDITPAYMENTID, @CREDITAMOUNT, @REFUNDPAYMENTTOTAL;
--When a cursor is used, it should be explicitly closed/deallocated in case of blocking or USP running long
close cp_cur;
deallocate cp_cur;
end
declare @DISTRIBUTIONS table(
REVENUESPLITID uniqueidentifier,
REVENUEID uniqueidentifier,
GLTRANSACTIONID uniqueidentifier,
ACCOUNT nvarchar(100),
AMOUNT money,
PROJECT nvarchar(100),
TRANSACTIONTYPECODE tinyint,
REFERENCE nvarchar(255),
POSTDATE datetime,
GLPAYMENTMETHODREVENUETYPEMAPPINGID uniqueidentifier,
ACCOUNTID uniqueidentifier,
CREDITPAYMENTID uniqueidentifier,
ERRORMESSAGE nvarchar(255),
MAPPEDVALUES xml,
CREDITITEMID uniqueidentifier
);
declare @PDACCOUNTSYSTEMID uniqueidentifier;
declare @DEFAULTACCOUNT nvarchar(100);
declare @DEFAULTACCOUNTID uniqueidentifier;
select
@PDACCOUNTSYSTEMID = PDACCOUNTSYSTEM.ID,
@DEFAULTACCOUNTID = GLACCOUNT.ID,
@DEFAULTACCOUNT = GLACCOUNT.ACCOUNTNUMBER
from
dbo.UFN_PDACCOUNTSYSTEM_DEFAULTORSYSTEM() as PDACCOUNTSYSTEM
left join
dbo.GLACCOUNT on GLACCOUNT.ID = PDACCOUNTSYSTEM.DEFAULTGLACCOUNTID;
-- Generate GL distributions for the discount record.
insert into @DISTRIBUTIONS(GLTRANSACTIONID, REVENUESPLITID, REVENUEID, ACCOUNT, AMOUNT, TRANSACTIONTYPECODE, REFERENCE, POSTDATE, GLPAYMENTMETHODREVENUETYPEMAPPINGID, ACCOUNTID, CREDITPAYMENTID, CREDITITEMID)
select
newid()
,SPLITS.REVENUESPLITID
,LI.FINANCIALTRANSACTIONID [REVENUEID]
,case when JE.TRANSACTIONTYPECODE = 0 then
dbo.UFN_REFUND_GETCREDITACCOUNT(JE.GLACCOUNTID,SPLITS.CREDITPAYMENTID,SPLITS.REVENUESPLITID)
else
A.ACCOUNTNUMBER
end
,PRORATEDSPLITS.AMOUNT
,case when JE.TRANSACTIONTYPECODE = 0 then 1 else 0 end
,'Refund-' + SPLITS.[TYPE] as REFERENCE
,@POSTDATE
,JEX.GLPAYMENTMETHODREVENUETYPEMAPPINGID
,case when JE.TRANSACTIONTYPECODE = 0 then
null
else
JE.GLACCOUNTID
end
,SPLITS.CREDITPAYMENTID
,SPLITS.CREDITITEMID
from @SOURCESPLITS as SPLITS
inner join @PRORATEDSPLITS as PRORATEDSPLITS on PRORATEDSPLITS.CREDITPAYMENTID = SPLITS.CREDITPAYMENTID and PRORATEDSPLITS.CREDITITEMID = SPLITS.CREDITITEMID
inner join dbo.FINANCIALTRANSACTIONLINEITEM LI on LI.ID = SPLITS.REVENUESPLITID
inner join dbo.JOURNALENTRY JE on JE.FINANCIALTRANSACTIONLINEITEMID = LI.ID
inner join dbo.JOURNALENTRY_EXT JEX on JE.ID = JEX.ID
inner join dbo.GLACCOUNT A on A.ID = JE.GLACCOUNTID
where (@CREDITPAYMENTID is null or SPLITS.CREDITPAYMENTID = @CREDITPAYMENTID)
and LI.TYPECODE != 1 and LI.DELETEDON is null
and JEX.TABLENAMECODE = 1
update @DISTRIBUTIONS set ACCOUNTID = (select GLACCOUNT.ID from dbo.GLACCOUNT where GLACCOUNT.ACCOUNTNUMBER = ACCOUNT and GLACCOUNT.PDACCOUNTSYSTEMID = @PDACCOUNTSYSTEMID)
where ACCOUNTID is null;
declare @ERRORMESSAGE nvarchar(255);
if exists(select 1 from @DISTRIBUTIONS where ACCOUNTID is null)
begin
set @ERRORMESSAGE = 'An account code has not been mapped for one or more payment methods.';
declare @MAPPEDVALUES xml;
set @MAPPEDVALUES = (select tv1.*, @ERRORMESSAGE as ERRORMESSAGE, 1 as ERRORCODE from dbo.UFN_GETGENERICACCOUNTMAPPINGSTRUCTURE(@PDACCOUNTSYSTEMID, 2, null, null, null, null) tv1 for XML raw('ROW'), type, elements, root('MAPPEDVALUES'), BINARY BASE64)
if @DEFAULTACCOUNTID is null
raiserror(@ERRORMESSAGE, 13, 1);
else
begin
update @DISTRIBUTIONS set
ACCOUNT = @DEFAULTACCOUNT
,ACCOUNTID = @DEFAULTACCOUNTID
,ERRORMESSAGE = @ERRORMESSAGE
,MAPPEDVALUES = convert(nvarchar(max), @MAPPEDVALUES)
where ACCOUNTID is null;
insert into dbo.GLACCOUNTMAPPINGERROR ([TRANSACTIONID],[TRANSACTIONTYPECODE],[ERRORMESSAGE], [MAPPEDVALUES],[ADDEDBYID],[CHANGEDBYID],[DATEADDED],[DATECHANGED])
select distinct
@CREDITID
,103
,D.ERRORMESSAGE
,convert(nvarchar(max), D.MAPPEDVALUES)
,@CHANGEAGENTID
,@CHANGEAGENTID
,@CHANGEDATE
,@CHANGEDATE
from @DISTRIBUTIONS D
where nullif(D.ERRORMESSAGE, '') is not null and D.ERRORMESSAGE not in (select ERRORMESSAGE from dbo.GLACCOUNTMAPPINGERROR where TRANSACTIONID = @CREDITID and DELETED = 0)
end
end
set @ERRORMESSAGE = dbo.UFN_GLDISTRIBUTION_VALIDPOSTDATE(@POSTDATE);
if @ERRORMESSAGE <> ''
raiserror(@ERRORMESSAGE, 13, 1);
declare @JOURNAL nvarchar(50);
set @JOURNAL = 'Blackbaud Enterprise';
declare @CURRENCYID uniqueidentifier;
select @CURRENCYID = ID from dbo.CURRENCY where ISORGANIZATIONCURRENCY = 1;
insert into dbo.JOURNALENTRY (
ID
,FINANCIALTRANSACTIONLINEITEMID
,TRANSACTIONTYPECODE
,CLASSCODE
,SEQUENCE
,TRANSACTIONAMOUNT
,COMMENT
,POSTDATE
,GLACCOUNTID
,SUBLEDGERTYPECODE
,BASEAMOUNT
,ORGAMOUNT
,TYPECODE
,TRANSACTIONCURRENCYID
,ADDEDBYID, CHANGEDBYID, DATEADDED, DATECHANGED)
select
GLTRANSACTIONID
,CREDITITEMID
,TRANSACTIONTYPECODE
,0
,row_number() over (partition by CREDITITEMID order by AMOUNT)
,AMOUNT
,REFERENCE
,POSTDATE
,ACCOUNTID
,TRANSACTIONTYPECODE
,AMOUNT
,AMOUNT
,0
,@CURRENCYID
,@CHANGEAGENTID, @CHANGEAGENTID, @CHANGEDATE, @CHANGEDATE
from @DISTRIBUTIONS;
insert into dbo.JOURNALENTRY_EXT(
ID
,TABLENAMECODE
,OUTDATED
,CREDITITEMID
,CREDITPAYMENTID
,JOURNAL
,ACCOUNT
,ADDEDBYID, CHANGEDBYID, DATEADDED, DATECHANGED)
select
GLTRANSACTIONID
,6
,0
,CREDITITEMID
,CREDITPAYMENTID
,@JOURNAL
,ACCOUNT
,@CHANGEAGENTID, @CHANGEAGENTID, @CHANGEDATE, @CHANGEDATE
from @DISTRIBUTIONS;
declare @REVENUESPLITIDS UDT_GENERICID;
insert into @REVENUESPLITIDS (ID)
select distinct REVENUESPLITID from @DISTRIBUTIONS;
exec dbo.USP_REFUND_ADDBENEFITREVERSALS @REVENUESPLITIDS, @CREDITID, @POSTDATE, @CHANGEAGENTID, @CHANGEDATE;
end