USP_FINANCIALTRANSACTIONLINEITEMS_REVERSE
Creates a reversal for a given set of line items.
Parameters
Parameter | Parameter Type | Mode | Description |
---|---|---|---|
@CHANGEAGENTID | uniqueidentifier | IN | |
@LINEITEMIDS | UDT_GENERICID | IN | |
@REVERSALPOSTDATE | datetime | IN | |
@REVERSALDATE | datetime | IN | |
@DELETEUNPOSTED | bit | IN |
Definition
Copy
CREATE procedure dbo.USP_FINANCIALTRANSACTIONLINEITEMS_REVERSE
(
@CHANGEAGENTID uniqueidentifier
,@LINEITEMIDS UDT_GENERICID readonly
,@REVERSALPOSTDATE datetime
,@REVERSALDATE datetime
,@DELETEUNPOSTED bit
)
as
begin
set nocount on;
/*
*
* NOTE: Rules about transaction types, line item types, and subledger specific details should be handled in a
* line item or subledger reversal sproc that calls this sproc.
*
* Some subledgers will use the ability of reversing unposted items for tracking purposes. We support that.
*
*/
begin try
-- Cannot reverse a deleted line item
if (exists (select FINANCIALTRANSACTIONLINEITEM.ID
from dbo.FINANCIALTRANSACTIONLINEITEM
inner join @LINEITEMIDS as LIDS
on FINANCIALTRANSACTIONLINEITEM.ID = LIDS.ID
where (not FINANCIALTRANSACTIONLINEITEM.DELETEDON is null)))
raiserror('ERR_LINEITEMREVERSAL_CANNOTREVERSEDELETEDLINEITEM', 13,1);
-- Cannot reverse a reversal line item
if (exists (select FINANCIALTRANSACTIONLINEITEM.ID
from dbo.FINANCIALTRANSACTIONLINEITEM
inner join @LINEITEMIDS as LIDS
on FINANCIALTRANSACTIONLINEITEM.ID = LIDS.ID
where (FINANCIALTRANSACTIONLINEITEM.TYPECODE = 1)))
raiserror('ERR_LINEITEMREVERSAL_CANNOTREVERSEREVERSEDLINEITEM', 13,1);
-- Otherwise create the reversal
-- Get the change agent
if @CHANGEAGENTID is null
exec dbo.USP_CHANGEAGENT_GETORCREATECHANGEAGENT @CHANGEAGENTID output;
-- Get the current date
declare @CURRENTDATE datetime;
set @CURRENTDATE = getdate();
-- Otherwise delete line items that are not posted instead of reversing
declare @CONTEXTCACHE varbinary(128) = CONTEXT_INFO();
set CONTEXT_INFO @CHANGEAGENTID;
-- We need to change the financial transaction amount before deleting to keep the totals correct
update dbo.FINANCIALTRANSACTION
set TRANSACTIONAMOUNT = isnull((select sum(FINANCIALTRANSACTIONLINEITEM.TRANSACTIONAMOUNT)
from dbo.FINANCIALTRANSACTION as FINANCIALTRANSACTION_INNER
inner join dbo.FINANCIALTRANSACTIONLINEITEM
on FINANCIALTRANSACTION_INNER.ID = FINANCIALTRANSACTIONLINEITEM.FINANCIALTRANSACTIONID
left outer join @LINEITEMIDS as LINEITEMSTOREVERSE
on FINANCIALTRANSACTIONLINEITEM.ID = LINEITEMSTOREVERSE.ID
where (FINANCIALTRANSACTIONLINEITEM.TYPECODE = 0) and
((LINEITEMSTOREVERSE.ID is null) or (FINANCIALTRANSACTIONLINEITEM.POSTSTATUSCODE = 2)) and
FINANCIALTRANSACTION_INNER.ID = FINANCIALTRANSACTION.ID),0)
from dbo.FINANCIALTRANSACTION
where (FINANCIALTRANSACTION.ID in (select FINANCIALTRANSACTION.ID
from dbo.FINANCIALTRANSACTION
inner join dbo.FINANCIALTRANSACTIONLINEITEM
on FINANCIALTRANSACTIONLINEITEM.FINANCIALTRANSACTIONID = FINANCIALTRANSACTION.ID
inner join @LINEITEMIDS as LINEITEMSTOREVERSE
on FINANCIALTRANSACTIONLINEITEM.ID = LINEITEMSTOREVERSE.ID))
;
if @DELETEUNPOSTED=1
begin
delete from dbo.FINANCIALTRANSACTIONLINEITEM
from dbo.FINANCIALTRANSACTIONLINEITEM
inner join @LINEITEMIDS as LINEITEMSTOREVERSE
on FINANCIALTRANSACTIONLINEITEM.ID = LINEITEMSTOREVERSE.ID
where FINANCIALTRANSACTIONLINEITEM.POSTSTATUSCODE != 2
;
end;
if @CONTEXTCACHE is not null
set CONTEXT_INFO @CONTEXTCACHE;
-- Mark the reversed line item as deleted
update dbo.FINANCIALTRANSACTIONLINEITEM
set DELETEDON = isnull(@REVERSALDATE,@CURRENTDATE),
DATECHANGED = @CURRENTDATE,
CHANGEDBYID = @CHANGEAGENTID
from dbo.FINANCIALTRANSACTIONLINEITEM
inner join @LINEITEMIDS as LINEITEMSTOREVERSE
on FINANCIALTRANSACTIONLINEITEM.ID = LINEITEMSTOREVERSE.ID
--If the wanted to delete unposted, they are now gone. The ones left must be 2 if they desire to do so.
--where (FINANCIALTRANSACTIONLINEITEM.POSTSTATUSCODE = 2)
--;
declare @REVERSALS table ( ORIGINALID uniqueidentifier, REVERSALID uniqueidentifier);
-- Create the reversal line items
insert into dbo.FINANCIALTRANSACTIONLINEITEM (
ID
,FINANCIALTRANSACTIONID
,TRANSACTIONAMOUNT
,BASEAMOUNT
,ORGAMOUNT
,VISIBLE
,[DESCRIPTION]
,SEQUENCE
,TYPECODE
,DELETEDON
,REVERSEDLINEITEMID
,POSTDATE
,POSTSTATUSCODE
,QUANTITY
,UNITVALUE
-- Boilerplate
,DATEADDED,DATECHANGED,ADDEDBYID,CHANGEDBYID
)
output
inserted.ID
,inserted.REVERSEDLINEITEMID ORIGINALID
into @REVERSALS (
REVERSALID
, ORIGINALID
)
select
NEWID()
,FTLI.FINANCIALTRANSACTIONID
,FTLI.TRANSACTIONAMOUNT
,FTLI.BASEAMOUNT
,FTLI.ORGAMOUNT
,0 -- Visible
,'' -- Description
,FTLI.SEQUENCE
,1 -- Reversal
,NULL -- Deletedon
,FTLI.ID
,isnull(@REVERSALPOSTDATE, FTLI.POSTDATE) -- PostDate
,case when FTLI.POSTSTATUSCODE = 3 then 3 else 1 end -- POSTSTATUSCODE
,FTLI.QUANTITY
,FTLI.UNITVALUE
-- Boilerplate
,@CURRENTDATE,@CURRENTDATE,@CHANGEAGENTID,@CHANGEAGENTID
from
@LINEITEMIDS as LIDS
inner join dbo.FINANCIALTRANSACTIONLINEITEM as FTLI
on LIDS.ID = FTLI.ID
;
-- Create the reversal distributions here
declare @JEREVERSALS table ( ORIGINALID uniqueidentifier, REVERSALID uniqueidentifier, REVERSALLINEITEMID uniqueidentifier );
insert into @JEREVERSALS (
ORIGINALID
,REVERSALID
,REVERSALLINEITEMID
)
select
JE.ID
,NEWID()
,REVS.REVERSALID
from
dbo.JOURNALENTRY as JE
inner join dbo.FINANCIALTRANSACTIONLINEITEM as FTLI
on JE.FINANCIALTRANSACTIONLINEITEMID = FTLI.ID
inner join @REVERSALS as REVS
on REVS.ORIGINALID = FTLI.ID
;
-- Copy and reverse line item distributions
insert into dbo.JOURNALENTRY (
ID
,FINANCIALTRANSACTIONLINEITEMID
,TRANSACTIONTYPECODE
,SUBLEDGERTYPECODE
,CLASSCODE
,SEQUENCE
,TRANSACTIONAMOUNT
,BASEAMOUNT
,ORGAMOUNT
,PERCENTAGE
,DATAELEMENT1ID,DATAELEMENT2ID,DATAELEMENT3ID,DATAELEMENT4ID,DATAELEMENT5ID,DATAELEMENT6ID,DATAELEMENT7ID,DATAELEMENT8ID,DATAELEMENT9ID,DATAELEMENT10ID
,DATAELEMENT11ID,DATAELEMENT12ID,DATAELEMENT13ID,DATAELEMENT14ID,DATAELEMENT15ID,DATAELEMENT16ID,DATAELEMENT17ID,DATAELEMENT18ID,DATAELEMENT19ID,DATAELEMENT20ID
,DATAELEMENT21ID,DATAELEMENT22ID,DATAELEMENT23ID,DATAELEMENT24ID,DATAELEMENT25ID,DATAELEMENT26ID,DATAELEMENT27ID,DATAELEMENT28ID,DATAELEMENT29ID,DATAELEMENT30ID
,COMMENT
,POSTDATE
,GLACCOUNTID
,TRANSACTIONCURRENCYID
,TYPECODE
-- Boilerplate
,DATEADDED, DATECHANGED, ADDEDBYID, CHANGEDBYID
)
select
JER.REVERSALID
,JER.REVERSALLINEITEMID
,1-JE.TRANSACTIONTYPECODE -- Opposite transaction side
,1-JE.SUBLEDGERTYPECODE
,JE.CLASSCODE
,JE.SEQUENCE
,JE.TRANSACTIONAMOUNT
,JE.BASEAMOUNT
,JE.ORGAMOUNT
,JE.PERCENTAGE
,DATAELEMENT1ID,DATAELEMENT2ID,DATAELEMENT3ID,DATAELEMENT4ID,DATAELEMENT5ID,DATAELEMENT6ID,DATAELEMENT7ID,DATAELEMENT8ID,DATAELEMENT9ID,DATAELEMENT10ID
,DATAELEMENT11ID,DATAELEMENT12ID,DATAELEMENT13ID,DATAELEMENT14ID,DATAELEMENT15ID,DATAELEMENT16ID,DATAELEMENT17ID,DATAELEMENT18ID,DATAELEMENT19ID,DATAELEMENT20ID
,DATAELEMENT21ID,DATAELEMENT22ID,DATAELEMENT23ID,DATAELEMENT24ID,DATAELEMENT25ID,DATAELEMENT26ID,DATAELEMENT27ID,DATAELEMENT28ID,DATAELEMENT29ID,DATAELEMENT30ID
,COMMENT
,ISNULL(@REVERSALPOSTDATE,JE.POSTDATE)
,GLACCOUNTID
,TRANSACTIONCURRENCYID
,JE.TYPECODE
-- Boilerplate
,@CURRENTDATE,@CURRENTDATE,@CHANGEAGENTID,@CHANGEAGENTID
from
dbo.JOURNALENTRY as JE
inner join @JEREVERSALS as JER
on JE.ID = JER.ORIGINALID
;
-- Is this the price to pay for backwards compatibility?
insert into dbo.JOURNALENTRY_EXT
(
ID
,ACCOUNT
,JOURNAL
,OUTDATED
,PRECALCBASEEXCHANGERATEID
,PRECALCORGANIZATIONEXCHANGERATEID
,PROJECT
,REVERSEDGLTRANSACTIONID
,TABLENAMECODE
-- Boilerplate
,DATEADDED, DATECHANGED, ADDEDBYID, CHANGEDBYID
)
select
JER.REVERSALID
,JEXT.ACCOUNT
,'Blackbaud Enterprise'
,0
,JEXT.PRECALCBASEEXCHANGERATEID
,JEXT.PRECALCORGANIZATIONEXCHANGERATEID
,JEXT.PROJECT
,JER.ORIGINALID
,0
-- Boilerplate
,@CURRENTDATE, @CURRENTDATE, @CHANGEAGENTID, @CHANGEAGENTID
from @JEREVERSALS as JER
inner join dbo.JOURNALENTRY_EXT as JEXT
on JER.ORIGINALID = JEXT.ID
;
update dbo.JOURNALENTRY_EXT
set
REVERSEDATE = @CURRENTDATE
,OUTDATED = 1
-- Boilerplate
,DATECHANGED = @CURRENTDATE
,CHANGEDBYID = @CHANGEAGENTID
from dbo.JOURNALENTRY_EXT as JEXT
inner join @JEREVERSALS as JER
on JEXT.ID = JER.ORIGINALID
;
select ORIGINALID
, REVERSALID from @REVERSALS;
end try
begin catch
exec dbo.USP_RAISE_ERROR;
return 1;
end catch
return 0;
end