UFN_REVENUE_GETNEXTTRANSACTIONDATE_BYID_1_1
Returns the next transaction date for a recurring gift. If @ASOFDATE is null, the current NEXTTRANSACTIONDATE will be used.
Return
Return Type |
---|
datetime |
Parameters
Parameter | Parameter Type | Mode | Description |
---|---|---|---|
@REVENUEID | uniqueidentifier | IN | |
@ASOFDATE | datetime | IN |
Definition
Copy
CREATE function dbo.UFN_REVENUE_GETNEXTTRANSACTIONDATE_BYID_1_1
(
@REVENUEID uniqueidentifier,
@ASOFDATE datetime
)
returns datetime
as
begin
declare @STARTDATE datetime;
declare @FREQUENCYCODE tinyint;
declare @NEXTTRANSACTIONDATE datetime;
declare @ISLASTDAYOFMONTH bit;
select
@STARTDATE = case when SCHEDULESEEDDATE > STARTDATE and SCHEDULESEEDDATE > NEXTTRANSACTIONDATE then dbo.UFN_DATE_GETEARLIESTTIME(coalesce(NEXTTRANSACTIONDATE, SCHEDULESEEDDATE)) else dbo.UFN_DATE_GETEARLIESTTIME(coalesce(SCHEDULESEEDDATE, STARTDATE)) end,
@FREQUENCYCODE = FREQUENCYCODE,
@NEXTTRANSACTIONDATE = dbo.UFN_DATE_GETEARLIESTTIME(coalesce(@ASOFDATE, NEXTTRANSACTIONDATE))
from dbo.REVENUESCHEDULE
where ID = @REVENUEID;
declare @DAYSINSTARTMONTH tinyint;
declare @STARTMONTH tinyint;
declare @STARTYEAR smallint;
declare @STARTDAY tinyint;
select
@STARTMONTH = datepart(month, @STARTDATE),
@STARTYEAR = datepart(year, @STARTDATE),
@STARTDAY = datepart(day, @STARTDATE)
set @DAYSINSTARTMONTH = dbo.UFN_DAYSINMONTH(@STARTMONTH, @STARTYEAR)
select
@ISLASTDAYOFMONTH = case when @STARTDAY >= @DAYSINSTARTMONTH then 1 else 0 end;
declare @POTENTIALDATE datetime;
set @POTENTIALDATE = @STARTDATE;
-- counter for number of skipped monthly installments
declare @NUMSKIPPEDINSTALLMENTS int;
set @NUMSKIPPEDINSTALLMENTS = 0;
while @POTENTIALDATE <= @NEXTTRANSACTIONDATE
begin
if @FREQUENCYCODE = 0 --Annually
set @POTENTIALDATE = dateadd(year, 1, @POTENTIALDATE);
else if @FREQUENCYCODE = 1 --Semi-annually
set @POTENTIALDATE = dateadd(month, 6, @POTENTIALDATE);
else if @FREQUENCYCODE = 2 --Quarterly
set @POTENTIALDATE = dateadd(quarter, 1, @POTENTIALDATE);
else if @FREQUENCYCODE = 3 --Monthly
begin
-- increment counter then add counter number of months to original start date
-- incrementing from start date keeps the day part the same (except for short months)
set @NUMSKIPPEDINSTALLMENTS = @NUMSKIPPEDINSTALLMENTS + 1;
-- if start date is at the end of the month, use the eomonth to increment the potential date
if eomonth(@STARTDATE) = @STARTDATE
set @POTENTIALDATE = eomonth(@STARTDATE, @NUMSKIPPEDINSTALLMENTS);
else
set @POTENTIALDATE = dateadd(month, @NUMSKIPPEDINSTALLMENTS, @STARTDATE);
end
else if @FREQUENCYCODE = 6 --Bimonthly
set @POTENTIALDATE = dateadd(month, 2, @POTENTIALDATE);
else if @FREQUENCYCODE = 7 --Semi-monthly
begin
if datepart(day, @POTENTIALDATE) < 15
set @POTENTIALDATE = dateadd(day, (15 - datepart(day, @POTENTIALDATE)), @POTENTIALDATE);
else
begin
set @POTENTIALDATE = dateadd(month, 1, @POTENTIALDATE)
set @POTENTIALDATE = dateadd(day, (-1 * datepart(day, @POTENTIALDATE)) + 1, @POTENTIALDATE);
end
end
else if @FREQUENCYCODE = 8 --Biweekly
set @POTENTIALDATE = dateadd(day, 14, @POTENTIALDATE);
else if @FREQUENCYCODE = 9 --Weekly
set @POTENTIALDATE = dateadd(week, 1, @POTENTIALDATE);
else if @FREQUENCYCODE = 10 --Every4Weeks
set @POTENTIALDATE = dateadd(day, 28, @POTENTIALDATE);
else
set @POTENTIALDATE = dateadd(day, 1, @NEXTTRANSACTIONDATE) --Don't know how to handle the frequency. Just use the day after @NEXTTRANSACTIONDATE so it'll break out of the loop
end
return @POTENTIALDATE;
end