-- Function: sp_processcdr()
-- DROP FUNCTION sp_processcdr();
CREATE OR REPLACE FUNCTION sp_processcdr()
RETURNS int8 AS
$BODY$
DECLARE
result bigint;
billCostDivider float8;
BEGIN
-- cost divider to convert whole integer costs to actual values.
billCostDivider := 100000;
-- Create temporary table
CREATE TEMP TABLE tmp_Cust_CDR (
cdrid int8,
account varchar(75),
src varchar(75),
dst varchar(75),
startdate timestamp,
isocode varchar(5),
region varchar(20),
minimum int8,
"increment" int8,
minimumcost int8,
incrementcost int8,
billsec int8,
BilledSeconds int8,
BilledCost float8,
a int2);
-- Get all the new cdrs
INSERT INTO tmp_Cust_CDR (cdrid, account, src, dst, startdate, billsec, a)
SELECT cdrid, account, src, dst, startdate, billsec, 0
FROM CDR_info
WHERE len(dst) > 5
AND cdrid NOT IN (SELECT cdrid FROM customer_cdr);
-- Local numbers
UPDATE tmp_Cust_CDR SET isocode = '1', dst = '705' || dst, region = 'LOCAL', a = 1 WHERE len(dst) < 10;
-- For the unlikely scenario where there's still 11 digit numbers ie: 1800whatever
UPDATE tmp_Cust_CDR SET isocode = '1', dst = right(dst, len(dst) - 1), region = 'NORTHAMERICA', a = 11 WHERE a = 0 AND len(dst) = 11 AND left(dst,1) = 1;
-- Any remaining 10 digit dsts would be North American
UPDATE tmp_Cust_CDR SET isocode = 1, region = 'NORTHAMERICA', a = 11 WHERE a = 0 AND len(dst) = 10;
-- International only - Get the iso code from remaining CDRs (a = 0) that match an International ISO Code from rate_info
UPDATE tmp_Cust_CDR SET
dst = inat.i_dst,
isocode = inat.i_isocode,
a = 2
FROM ( SELECT DISTINCT cdrid AS i_cdrid,
right(cdr.dst, len(cdr.dst) - len(ri.isocode)) AS i_dst,
ri.isocode AS i_isocode
FROM tmp_Cust_CDR AS cdr
LEFT OUTER JOIN rate_info AS rA ON rA.isocode <> 1
LEFT OUTER JOIN rate_info AS ri ON left(cdr.dst, len(rA.isocode)) = ri.isocode
WHERE cdr.a=0
AND len(cdr.dst) > 10
AND isnull(cdr.isocode,'') = '' ) AS inat
WHERE cdrid = inat.i_cdrid;
-- Get the regions
UPDATE tmp_Cust_CDR SET
region = isnull(rgn.region, 'NOREGION')
FROM ( SELECT DISTINCT cdrid AS l_cdrid,
ri.region,
len(ri.region),
cdr.dst
FROM tmp_Cust_CDR AS cdr
LEFT OUTER JOIN rate_info AS ri ON (ri.isocode = cdr.isocode AND left(cdr.dst, len(ri.region)) = ri.region)
ORDER BY cdrid, len(ri.region) DESC
) AS rgn
WHERE cdrid = rgn.l_cdrid;
-- If the region isn't in rate_info then it must default to the empty region for the isocode
UPDATE tmp_Cust_CDR SET
region = 'NOREGION'
WHERE region NOT IN (SELECT region FROM rate_info);
-- Get the rate info where the parsed out isocode and regions match exactly in rate_info
UPDATE tmp_Cust_CDR SET
minimum = T.i_min,
"increment" = T.i_inc,
minimumcost = T.i_mincost,
incrementcost = T.i_inccost
FROM ( SELECT t.cdrid AS i_cdrid, ri.minimum AS i_min, ri.increment AS i_inc, ri.minimumcost AS i_mincost, ri.incrementcost AS i_inccost
FROM tmp_Cust_CDR AS t
LEFT OUTER JOIN ( SELECT t.cdrid, min(ri.incrementcost) AS mincost
FROM tmp_Cust_CDR AS t
LEFT OUTER JOIN rate_info AS ri ON (ri.isocode = t.isocode AND isnull(ri.region, 'NOREGION') = t.region)
group by t.cdrid
) AS dbl ON dbl.cdrid = t.cdrid
LEFT OUTER JOIN rate_info AS ri ON (ri.isocode = t.isocode AND isnull(ri.region, 'NOREGION') = t.region)
WHERE isnull(ri.incrementcost, -99::bigint) = CASE WHEN isnull(dbl.mincost, -99::bigint) = -99 THEN ri.incrementcost
WHEN isnull(ri.incrementcost, -99::bigint) = -99 THEN -99
ELSE dbl.mincost END
) AS T
WHERE cdrid = T.i_cdrid;
-- calculate the actual billable seconds and the billed cost
UPDATE tmp_Cust_CDR SET
BilledSeconds = CASE WHEN billsec - minimum <= 0 THEN
minimum
ELSE
CASE WHEN (billsec - minimum) % "increment" = 0 THEN
billsec
ELSE
minimum + ( ( ( (billsec - minimum) / "increment" ) + 1 ) * "increment" )
END
END,
BilledCost = (CASE WHEN len(dst) >= 10 THEN
CASE WHEN billsec - minimum <= 0 THEN
minimumCost
ELSE
CASE WHEN (billsec - minimum) % "increment" = 0 THEN
minimumCost + ( ( (billsec - minimum) / "increment" ) * incrementcost )
ELSE
minimumCost + ( ( ( (billsec - minimum) / "increment" ) + 1 ) * incrementcost)
END
END
ELSE
0
END)::float8 / billCostDivider
WHERE "increment" > 0;
UPDATE tmp_Cust_CDR SET BilledSeconds = BillSec, BilledCost = 0 WHERE "increment" = 0;
-- Add to customer_cdr table
INSERT INTO customer_cdr (cdrid, account, startdate, src, dst, billsec, callcost)
SELECT cdrid, account, startdate, src, dst, BilledSeconds, BilledCost
FROM tmp_Cust_CDR
ORDER BY cdrid;
-- Get the number of records inserted
result := count(cdrid) FROM tmp_Cust_CDR;
return result;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE;
ALTER FUNCTION sp_processcdr() OWNER TO voctel;