USP_REVENUEUPDATEBATCH_BUILDINSTALLMENTS
Generates the installments xml to be used for pledge updates in revenue update batch.
Parameters
Parameter | Parameter Type | Mode | Description |
---|---|---|---|
@REVENUEID | uniqueidentifier | IN | |
@AMOUNT | money | IN | |
@PREVIOUSAMOUNT | money | IN | |
@FREQUENCYCODE | tinyint | IN | |
@NUMBEROFINSTALLMENTS | int | IN | |
@TRANSACTIONCURRENCYID | uniqueidentifier | IN | |
@SPLITS | xml | IN | |
@INSTALLMENTS | xml | INOUT | |
@DATE | datetime | IN | |
@PREVIOUSDATE | datetime | IN |
Definition
Copy
CREATE procedure dbo.USP_REVENUEUPDATEBATCH_BUILDINSTALLMENTS
(
@REVENUEID uniqueidentifier,
@AMOUNT money,
@PREVIOUSAMOUNT money,
@FREQUENCYCODE tinyint,
@NUMBEROFINSTALLMENTS int,
@TRANSACTIONCURRENCYID uniqueidentifier,
@SPLITS xml,
@INSTALLMENTS xml = null output,
@DATE datetime,
@PREVIOUSDATE datetime
)
as
begin
declare @APPLIEDAMOUNT money;
declare @LASTINSTALLMENTPAID uniqueidentifier;
declare @TOTALNUMBERINSTALLMENTS int;
declare @i int;
declare @TYPICALAMOUNT money;
declare @INSTALLMENTSPLITS xml;
declare @PREVIOUSFREQUENCYCODE tinyint;
declare @PREVIOUSNUMBEROFINSTALLMENTS int;
declare @OUTSTANDINGAMOUNT money;
declare @INSTALLMENTTABLE table
(
ID uniqueidentifier,
DATE datetime,
AMOUNT money,
RECEIPTAMOUNT money,
BALANCE money,
APPLIED money,
SEQUENCE int,
TRANSACTIONCURRENCYID uniqueidentifier
);
select
@PREVIOUSFREQUENCYCODE = REVENUESCHEDULE.FREQUENCYCODE,
@PREVIOUSNUMBEROFINSTALLMENTS = REVENUESCHEDULE.NUMBEROFINSTALLMENTS
from dbo.REVENUESCHEDULE
where ID = @REVENUEID;
-- load the existing installments
insert into @INSTALLMENTTABLE (ID, DATE, AMOUNT, BALANCE, APPLIED, SEQUENCE, TRANSACTIONCURRENCYID)
select INSTALLMENT.ID,
INSTALLMENT.DATE,
INSTALLMENT.AMOUNT,
INSTALLMENT.BALANCE,
INSTALLMENT.APPLIED,
INSTALLMENT.SEQUENCE,
INSTALLMENT.TRANSACTIONCURRENCYID
from dbo.UFN_INSTALLMENT_GETINSTALLMENTS_2(@REVENUEID) INSTALLMENT
order by INSTALLMENT.DATE, INSTALLMENT.SEQUENCE;
set @TOTALNUMBERINSTALLMENTS = (select count(*) from @INSTALLMENTTABLE);
set @APPLIEDAMOUNT = dbo.UFN_PLEDGE_GETAMOUNTPAID(@REVENUEID)
-- set the amount to the balance
if @AMOUNT > 0
begin
set @OUTSTANDINGAMOUNT = @AMOUNT - @APPLIEDAMOUNT;
end
-- only update the @INSTALLMENTTABLE if the amount or frequency or number of installments or pledge date has changed
if @PREVIOUSAMOUNT <> @AMOUNT or @PREVIOUSFREQUENCYCODE <> @FREQUENCYCODE or @PREVIOUSNUMBEROFINSTALLMENTS <> @NUMBEROFINSTALLMENTS or @DATE <> @PREVIOUSDATE
begin
declare @NEXTTRANSACTIONDATE datetime;
declare @NEXTSEQUENCE int;
declare @NUMBERINSTALLMENTSAPPLIED int;
select @NUMBERINSTALLMENTSAPPLIED = count(*)
from @INSTALLMENTTABLE
where applied <> 0;
select top 1
@NEXTTRANSACTIONDATE = DATE,
@NEXTSEQUENCE = SEQUENCE
from @INSTALLMENTTABLE
where APPLIED = 0
order by DATE, SEQUENCE
if @DATE <> @PREVIOUSDATE
begin
set @NEXTTRANSACTIONDATE = @DATE
end
set @TOTALNUMBERINSTALLMENTS = @NUMBERINSTALLMENTSAPPLIED + @NUMBEROFINSTALLMENTS;
set @AMOUNT = @OUTSTANDINGAMOUNT;
set @i = 0;
set @TYPICALAMOUNT = ROUND(@AMOUNT / @NUMBEROFINSTALLMENTS, 2);
if @AMOUNT > 0
begin
if @AMOUNT - (@TYPICALAMOUNT * (@NUMBEROFINSTALLMENTS - 1)) < 0
set @TYPICALAMOUNT = @TYPICALAMOUNT - power(10, -2);
end
--
-- remove the installments that have not been paid
--
delete from @INSTALLMENTTABLE
where APPLIED = 0;
--
-- for the remaining records, set the installment amount to what was applied to it.
--
update @INSTALLMENTTABLE
set AMOUNT = APPLIED;
-- loop through and create the new installments if amount > 0
if @AMOUNT > 0
begin
while @i < @NUMBEROFINSTALLMENTS
begin
if @NEXTSEQUENCE = @TOTALNUMBERINSTALLMENTS
set @TYPICALAMOUNT = @AMOUNT - (@TYPICALAMOUNT * (@NUMBEROFINSTALLMENTS - 1));
if @FREQUENCYCODE = 0
insert into @INSTALLMENTTABLE (ID, DATE, AMOUNT, BALANCE, SEQUENCE, TRANSACTIONCURRENCYID)
values (newid(), dateadd(yy, @i, @NEXTTRANSACTIONDATE), @TYPICALAMOUNT, @TYPICALAMOUNT, @NEXTSEQUENCE, @TRANSACTIONCURRENCYID);
else if @FREQUENCYCODE = 1
insert into @INSTALLMENTTABLE (ID, DATE, AMOUNT, BALANCE, SEQUENCE, TRANSACTIONCURRENCYID)
values (newid(), dateadd(mm, @i * 6, @NEXTTRANSACTIONDATE), @TYPICALAMOUNT, @TYPICALAMOUNT, @NEXTSEQUENCE, @TRANSACTIONCURRENCYID);
else if @FREQUENCYCODE = 2
insert into @INSTALLMENTTABLE (ID, DATE, AMOUNT, BALANCE, SEQUENCE, TRANSACTIONCURRENCYID)
values (newid(), dateadd(qq, @i, @NEXTTRANSACTIONDATE), @TYPICALAMOUNT, @TYPICALAMOUNT, @NEXTSEQUENCE, @TRANSACTIONCURRENCYID);
else if @FREQUENCYCODE = 3
insert into @INSTALLMENTTABLE (ID, DATE, AMOUNT, BALANCE, SEQUENCE, TRANSACTIONCURRENCYID)
values (newid(), dateadd(mm, @i, @NEXTTRANSACTIONDATE), @TYPICALAMOUNT, @TYPICALAMOUNT, @NEXTSEQUENCE, @TRANSACTIONCURRENCYID);
else if @FREQUENCYCODE = 5
insert into @INSTALLMENTTABLE (ID, DATE, AMOUNT, BALANCE, SEQUENCE, TRANSACTIONCURRENCYID)
values (newid(), @NEXTTRANSACTIONDATE, @TYPICALAMOUNT, @TYPICALAMOUNT, @NEXTSEQUENCE, @TRANSACTIONCURRENCYID);
else if @FREQUENCYCODE = 7
begin
-- This is based on the algorithm for calculating semi-monthly dates found in RecurringGiftScheduleDataList.vb
declare @NUMMONTHS int;
declare @NEXTDATE datetime;
set @NUMMONTHS = @i / 2;
set @NEXTDATE = dateadd(mm,@NUMMONTHS,@NEXTTRANSACTIONDATE);
if @i % 2 <> 0
begin
declare @NEXTDATE2 datetime;
if datepart(dd,@NEXTTRANSACTIONDATE) <= 15
begin
set @NEXTDATE2 = dateadd(dd,15,@NEXTDATE);
if datepart(mm,@NEXTDATE2) > datepart(mm,@NEXTDATE)
set @NEXTDATE2 = dbo.UFN_DATE_THISMONTH_LASTDAY(@NEXTDATE,0)
set @NEXTDATE = @NEXTDATE2;
end
else
begin
if datepart(dd,@NEXTTRANSACTIONDATE) > 15
begin
set @NEXTDATE2 = dateadd(dd,15,@NEXTDATE);
if datepart(mm,@NEXTDATE2) = datepart(mm,@NEXTDATE) and datepart(dd,@NEXTDATE2) = 31
set @NEXTDATE2 = dateadd(dd,1,@NEXTDATE2);
set @NEXTDATE = @NEXTDATE2;
end
else
begin
set @NEXTDATE = dateadd(dd,15,@NEXTDATE);
end
end
end
insert into @INSTALLMENTTABLE (ID, DATE, AMOUNT, BALANCE, SEQUENCE, TRANSACTIONCURRENCYID)
values (newid(),@NEXTDATE, @TYPICALAMOUNT, @TYPICALAMOUNT, @NEXTSEQUENCE, @TRANSACTIONCURRENCYID);
end
else if @FREQUENCYCODE = 8
insert into @INSTALLMENTTABLE (ID, DATE, AMOUNT, BALANCE, SEQUENCE, TRANSACTIONCURRENCYID)
values (newid(), dateadd(ww, @i * 2, @NEXTTRANSACTIONDATE), @TYPICALAMOUNT, @TYPICALAMOUNT, @NEXTSEQUENCE, @TRANSACTIONCURRENCYID);
set @i = @i + 1;
set @NEXTSEQUENCE = @NEXTSEQUENCE + 1;
end
end -- installments > 0
end -- installment fields changed
else
begin
set @AMOUNT = @OUTSTANDINGAMOUNT;
end
--
-- build installment xml to pass to installment splits function.
--
set @INSTALLMENTS = (
select
INSTALLMENT.ID,
INSTALLMENT.AMOUNT,
INSTALLMENT.RECEIPTAMOUNT,
INSTALLMENT.SEQUENCE,
INSTALLMENT.TRANSACTIONCURRENCYID
from @INSTALLMENTTABLE INSTALLMENT
for xml raw('ITEM'),type,elements,root('INSTALLMENTS'),BINARY BASE64
);
--
-- set up the installment splits
--
select @INSTALLMENTSPLITS = dbo.UFN_REVENUEUPDATEBATCH_BUILDINSTALLMENTSPLITS
(@REVENUEID, @AMOUNT, @SPLITS, @TOTALNUMBERINSTALLMENTS, @INSTALLMENTS, @TRANSACTIONCURRENCYID, @TOTALNUMBERINSTALLMENTS)
set @INSTALLMENTS = (
select
INSTALLMENT.ID,
INSTALLMENT.DATE,
INSTALLMENT.AMOUNT,
INSTALLMENT.RECEIPTAMOUNT,
INSTALLMENT.BALANCE,
INSTALLMENT.APPLIED,
INSTALLMENT.SEQUENCE,
(select
T.c.value('(ID)[1]','uniqueidentifier') AS 'ID',
T.c.value('(INSTALLMENTID)[1]','uniqueidentifier') AS 'INSTALLMENTID',
T.c.value('(DESIGNATIONID)[1]','uniqueidentifier') AS 'DESIGNATIONID',
T.c.value('(AMOUNT)[1]','money') AS 'AMOUNT',
T.c.value('(APPLIED)[1]','money') AS 'APPLIED',
T.c.value('(TRANSACTIONCURRENCYID)[1]','uniqueidentifier') AS 'TRANSACTIONCURRENCYID'
from @INSTALLMENTSPLITS.nodes('/ITEM') T(c)
where T.c.value('(INSTALLMENTID)[1]','uniqueidentifier') = INSTALLMENT.ID
for xml raw('ITEM'),type,elements,BINARY BASE64
) as INSTALLMENTSPLITS,
INSTALLMENT.TRANSACTIONCURRENCYID
from @INSTALLMENTTABLE INSTALLMENT
order by INSTALLMENT.DATE
for xml raw('ITEM'),type,elements,root('INSTALLMENTS'),BINARY BASE64
);
end