All pastes #16271 Raw Edit

Mine

public text v1 · immutable
#16271 ·published 2005-06-29 06:27 UTC
rendered paste body
-- 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;