UFN_SPLITS_PRORATEAMOUNTS
Prorates splits across a new total
Return
Return Type |
---|
table |
Parameters
Parameter | Parameter Type | Mode | Description |
---|---|---|---|
@ORIGINALAMOUNT | money | IN | |
@NEWAMOUNT | money | IN | |
@DECIMALDIGITSFORCURRENCY | int | IN | |
@AMOUNTSTOPRORATE | xml | IN |
Definition
Copy
CREATE function dbo.UFN_SPLITS_PRORATEAMOUNTS(
@ORIGINALAMOUNT money,
@NEWAMOUNT money,
@DECIMALDIGITSFORCURRENCY int,
@AMOUNTSTOPRORATE xml
)
returns @PRORATEDAMOUNTS table
(
ID uniqueidentifier,
AMOUNT money
)
as
BEGIN
------
-- This function will pro-rate the splits from an original total to a new total while taking into
-- account the number of decimal digits in the currency.
-- Parameters:
-- @ORIGINALAMOUNT : the original total. It is the caller's responsibility to make sure this is
-- equal to the SUM of the AMOUNT fields in the @AMOUNTSTOPRORATE xml parameter
-- @NEWAMOUNT : the new total among which the splits will be distributed. This function has the responsibility
-- of ensuring that the SUM of the AMOUNT fields in the returned table is equal to the @NEWAMOUNT parameter.
-- @DECIMALDIGITSFORCURRENCY : the number of decimal digits in the currency. Should be in the range 0 to 4.
-- @AMOUNTSTOPRORATE : represents the splits for the original total amount, and should be in the following format:
-- <AMOUNTSTOPRORATE>
-- <ITEM>
-- <AMOUNT>100</AMOUNT>
-- <ID>A Guid</ID>
-- </ITEM>
-- <!-- other ITEMS in the split -->
-- </AMOUNTSTOPRORATE>
------
-- adjust splits for new amount
declare @IDEALAMOUNT decimal(30, 5);
declare @ORIGINALAMOUNTDISTRIBUTEDIDEAL decimal(30, 5);
declare @ORIGINALAMOUNTDISTRIBUTED decimal(30, 5);
declare @WEIGHTAMOUNT decimal(30, 10);
declare @ID uniqueidentifier;
set @ORIGINALAMOUNTDISTRIBUTEDIDEAL = 0;
set @ORIGINALAMOUNTDISTRIBUTED = 0;
-- Loop through and calculate new split amounts
declare AMOUNTSTOPRORATECURSOR cursor local fast_forward for
select
T.c.value('ID[1]', 'uniqueidentifier'),
T.c.value('AMOUNT[1]', 'money')
from
@AMOUNTSTOPRORATE.nodes('/AMOUNTSTOPRORATE/ITEM') T(c)
where
T.c.value('ID[1]', 'CHAR(36)') <> ''
and isnumeric(T.c.value('AMOUNT[1]', 'money')) = 1;
open AMOUNTSTOPRORATECURSOR;
fetch next from AMOUNTSTOPRORATECURSOR into @ID, @WEIGHTAMOUNT;
while @@FETCH_STATUS = 0
begin
if @ORIGINALAMOUNT <> 0
set @IDEALAMOUNT = (@WEIGHTAMOUNT / @ORIGINALAMOUNT) * @NEWAMOUNT;
else
set @IDEALAMOUNT = 0;
set @WEIGHTAMOUNT = ROUND(@IDEALAMOUNT + @ORIGINALAMOUNTDISTRIBUTEDIDEAL - @ORIGINALAMOUNTDISTRIBUTED, @DECIMALDIGITSFORCURRENCY);
insert into @PRORATEDAMOUNTS (ID, AMOUNT)
values (@ID, @WEIGHTAMOUNT);
set @ORIGINALAMOUNTDISTRIBUTEDIDEAL = @ORIGINALAMOUNTDISTRIBUTEDIDEAL + @IDEALAMOUNT;
set @ORIGINALAMOUNTDISTRIBUTED = @ORIGINALAMOUNTDISTRIBUTED + @WEIGHTAMOUNT;
fetch next from AMOUNTSTOPRORATECURSOR into @ID, @WEIGHTAMOUNT;
end
close AMOUNTSTOPRORATECURSOR;
deallocate AMOUNTSTOPRORATECURSOR;
return
END