CREATE OR REPLACE PACKAGE BODY efno_rules AS
--
--
PROCEDURE evaluate_rule_sql( p_sql IN VARCHAR2
, p_success IN OUT BOOLEAN
, p_no_data OUT BOOLEAN
, p_return_value OUT NUMBER )
IS
-- Dynamic SQL local variables
l_cursor INTEGER;
l_cursor_count INTEGER;
l_cursor_dummy INTEGER;
--
BEGIN
--
-- htp.p(p_sql);
--caco_debug.putline('SP: efno_rules.evaluate_rule_sql p_sql: '||p_sql);
--
p_no_data := FALSE;
--
l_cursor := DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE( l_cursor, p_sql, DBMS_SQL.NATIVE );
DBMS_SQL.DEFINE_COLUMN( l_cursor, 1, p_return_value );
--
l_cursor_dummy := DBMS_SQL.EXECUTE( l_cursor );
--
-- Get the number of rows returned - one is good - all else is bad
l_cursor_count := DBMS_SQL.FETCH_ROWS( l_cursor );
--
IF l_cursor_count = 1 THEN
-- Put the column value into the return value
DBMS_SQL.COLUMN_VALUE( l_cursor, 1, p_return_value );
--
ELSIF l_cursor_count = 0 THEN
p_success := FALSE;
p_no_data := TRUE;
caco_debug.putline('efno_rules.evaluate_rule_sql : Error : '||chr(10)
||'No data found'||chr(10)||'SQL: '||p_sql);
ELSE
p_success := FALSE;
caco_debug.putline('efno_rules.evaluate_rule_sql : Error : '||chr(10)
||'Too Many Rows');
END IF;
--
-- Close the cursor
DBMS_SQL.CLOSE_CURSOR( l_cursor );
--
EXCEPTION
WHEN others THEN
p_success := FALSE;
caco_debug.putline('efno_rules.evaluate_rule_sql : Error : '
||chr(10)||p_sql||chr(10)
||sqlerrm(sqlcode));
-- Write an error and carry on
cout_err.report_and_go( p_exception_number => sqlcode
, p_exception_message => sqlerrm(sqlcode)
, p_source => 'efno_rules.evaluate_rule_sql');
--
END evaluate_rule_sql;
--
--
--
--
FUNCTION valid_category( p_template_id IN NUMBER
, p_contract_id IN NUMBER
, p_temp_code IN VARCHAR2
, p_category_id OUT NUMBER )
RETURN BOOLEAN
IS
--
-- Ensure that the category exists
CURSOR c_category IS
SELECT cate_id
FROM categories
WHERE UPPER( code ) = UPPER( p_temp_code );
--
-- Ensure that that the category exists for the given contract
CURSOR c_contract_cat IS
SELECT cate.cate_id
FROM categories cate
, contract_categories coca
WHERE cate.cate_id = coca.cate_id
AND UPPER(cate.code) = UPPER(p_temp_code)
AND coca.cont_id = p_contract_id;
--
-- Ensure that that the category exists for the given contract template
CURSOR c_template_cat IS
SELECT cate.cate_id
FROM categories cate
, contract_template_categories cotc
WHERE cate.cate_id = cotc.cate_id
AND UPPER(cate.code) = UPPER(p_temp_code)
AND cotc.cote_id = p_template_id;
--
--
l_success BOOLEAN := TRUE;
--
BEGIN
--
IF p_template_id IS NOT NULL AND p_template_id > 0 THEN
--
-- Check that the code exists for the template
OPEN c_template_cat;
FETCH c_template_cat INTO p_category_id;
--
IF c_template_cat%NOTFOUND THEN
l_success := FALSE;
END IF;
CLOSE c_template_cat;
--
ELSIF p_contract_id IS NOT NULL AND p_contract_id > 0 THEN
--
-- Check that the code exists for the contract
OPEN c_contract_cat;
FETCH c_contract_cat INTO p_category_id;
--
IF c_contract_cat%NOTFOUND THEN
l_success := FALSE;
END IF;
CLOSE c_contract_cat;
--
ELSE
--
-- Check that the code exists
OPEN c_category;
FETCH c_category INTO p_category_id;
--
IF c_category%NOTFOUND THEN
l_success := FALSE;
END IF;
CLOSE c_category;
--
END IF;
--
RETURN l_success;
--
END valid_category;
FUNCTION valid_parameter( p_template_id IN NUMBER
, p_contract_id IN NUMBER
, p_temp_code IN VARCHAR2
, p_parameter_id OUT NUMBER )
RETURN BOOLEAN
IS
--
-- Ensure that the Parameter Exists
CURSOR c_parameter IS
SELECT pars_id
FROM parameters
WHERE UPPER( code ) = UPPER( p_temp_code );
--
-- Ensure that that the parameter exists for the given contract
CURSOR c_contract_par IS
SELECT pars.pars_id
FROM parameters pars
, contract_parameters copa
WHERE pars.pars_id = copa.pars_id
AND UPPER(pars.code) = UPPER(p_temp_code)
AND copa.cont_id = p_contract_id;
--
-- Ensure that that the parameter exists for the given contract template
CURSOR c_template_par IS
SELECT pars.pars_id
FROM parameters pars
, contract_template_params cotp
WHERE pars.pars_id = cotp.pars_id
AND UPPER(pars.code) = UPPER(p_temp_code)
AND cotp.cote_id = p_template_id;
--
-- If not a standalone parameter - is the parameter automatically inherited from a category?
CURSOR c_template_cate_par IS
SELECT pars.pars_id
FROM parameters pars
, categories cate
, contract_template_categories cotc
WHERE cotc.cote_id = p_template_id
AND cotc.cate_id = cate.cate_id
AND pars.cate_id = cate.cate_id
AND UPPER(pars.code) = UPPER(p_temp_code);
--
--
l_success BOOLEAN := TRUE;
--
BEGIN
--
IF p_template_id IS NOT NULL AND p_template_id > 0 THEN
--
-- Check that the code exists for the template
-- Firstly see if this will be an automatically inherited parameter (from a category)
--
OPEN c_template_cate_par;
FETCH c_template_cate_par INTO p_parameter_id;
--
IF c_template_cate_par%NOTFOUND THEN
l_success := FALSE;
END IF;
CLOSE c_template_cate_par;
--
-- If it isn't automatically inherited - check if it is a standalone parameter
IF NOT l_success THEN
--
OPEN c_template_par;
FETCH c_template_par INTO p_parameter_id;
--
IF c_template_par%FOUND THEN
l_success := TRUE;
END IF;
CLOSE c_template_par;
--
END IF;
--
--
ELSIF p_contract_id IS NOT NULL AND p_contract_id > 0 THEN
--
-- Check that the code exists for the contract
OPEN c_contract_par;
FETCH c_contract_par INTO p_parameter_id;
--
IF c_contract_par%NOTFOUND THEN
l_success := FALSE;
END IF;
CLOSE c_contract_par;
--
ELSE
--
-- Check that the code exists
OPEN c_parameter;
FETCH c_parameter INTO p_parameter_id;
--
IF c_parameter%NOTFOUND THEN
l_success := FALSE;
END IF;
CLOSE c_parameter;
--
END IF;
--
RETURN l_success;
--
END valid_parameter;
FUNCTION valid_npgp(p_contract_id IN NUMBER
,p_temp_code IN VARCHAR2)
RETURN BOOLEAN
IS
--
-- Ensure that that the network point group parameter exists for the given contract
CURSOR c_npgp IS
SELECT 'X'
FROM network_point_gp_params npgp
WHERE UPPER(npgp.code) = UPPER(p_temp_code)
AND npgp.cont_id = p_contract_id;
--
l_success BOOLEAN := FALSE;
l_dummy VARCHAR2(1);
--
BEGIN
--
IF p_contract_id IS NOT NULL AND p_contract_id > 0 THEN
--
-- Check that the network point group parameter exists for the contract
OPEN c_npgp;
FETCH c_npgp INTO l_dummy;
--
IF c_npgp%FOUND THEN
l_success := TRUE;
END IF;
CLOSE c_npgp;
--
END IF;
--
RETURN l_success;
--
END valid_npgp;
--
/**
-- FUNCTION rule_text --
-- Validates one side of a rule defined through the EFT Nominations Web interface
-- and optionally returns the various parts of the required SQL statement for running the rules
-- Note : Once passed back to the calling routine, if the hours_in_gas_day function has
-- been included in the text, a further substitution to replace 'p_gas_day' must take place
--
-- %param p_text The stored text of one side of the rule to be evaluated
-- %param p_rule_type SHEET or ROW rule (changes how it is validated)
-- %param p_select The evaluated SQL for the first part of the SQL select statement
-- %param p_from The evaluated SQL for the FROM clause
-- %param p_where The evaluated SQL for the WHERE clause
-- %param p_nnpcv_tab Table of Nom Net Point Cat Vals - ID and COCA and CONP id
-- %param p_contract_id The unique identifier of the the contract for which this nomination is for
-- %param p_conf_id The Unique Identifier of the specific confirmation being validated for this rule
-- %param p_nomination_id The unique identifier for the specific nomination being validated for this rule
-- %param p_net_point_id The Unique Identifier of a Network Point - for ROW rules
-- %param p_gas_day For Row Rules, Each Network point requires a category value for each gas day
-- %param p_parse_only TRUE if we only want to see if the rule is syntactically valid
-- %param p_force_conf TRUE if the rule_text function is being called whilst forcing a confirmation
-- Will ensure that a list of nnpcv items are returned in p_nnpcv_tab
-- %param p_return_error OUT parameter containing an error message if things have gone wrong
--
-- %return BOOLEAN TRUE indicating that the passed text is valid syntactically
*/
FUNCTION rule_text ( p_text IN VARCHAR2
, p_rule_type IN VARCHAR2
, p_select OUT VARCHAR2
, p_from OUT VARCHAR2
, p_where OUT VARCHAR2
, p_nnpcv_tab IN OUT NOCOPY efno_confirmations.nnpcv_tab
, p_template_id IN contract_templates.cote_id%TYPE DEFAULT 0
, p_contract_id IN contracts.cont_id%TYPE DEFAULT 0
, p_conf_id IN confirmations.conf_id%TYPE DEFAULT 0
, p_nomination_id IN nominations.nomi_id%TYPE DEFAULT 0
, p_net_point_id IN network_points.nepo_id%TYPE DEFAULT 0
, p_gas_day IN DATE DEFAULT NULL
, p_parse_only IN BOOLEAN DEFAULT FALSE -- MUST NOT be TRUE if p_force_conf is TRUE
, p_force_conf IN BOOLEAN DEFAULT FALSE -- MUST NOT be TRUE if p_parse_only is TRUE
, p_return_error OUT VARCHAR2 )
RETURN BOOLEAN
IS
-- Network point ID finder
CURSOR c_network_point( cp_code IN VARCHAR2 ) IS
SELECT nepo_id
FROM network_points
WHERE UPPER( code ) = UPPER( cp_code );
--
-- Network point group ID finder
CURSOR c_network_point_group( cp_code IN VARCHAR2 ) IS
SELECT nepg_id
FROM network_point_groups
WHERE UPPER( code ) = UPPER( cp_code );
--
-- Cursor to find the Contract Network Point ID
CURSOR c_conp( cp_cont_id IN NUMBER
, cp_nepo_id IN NUMBER )
IS
SELECT conp_id
FROM cont_network_points
WHERE cont_id = cp_cont_id
AND nepo_id = cp_nepo_id;
--
-- Cursor to find the active Contract Network Point IDs for an active network point group
CURSOR c_conp_nepg( cp_cont_id IN NUMBER
, cp_nepg_id IN NUMBER )
IS
SELECT conp_id
FROM cont_network_points conp,
network_point_mappings nepm,
network_point_groups nepg,
network_points nepo
WHERE conp.cont_id = cp_cont_id
AND nepm.nepg_id = cp_nepg_id
AND nepm.nepo_id = conp.nepo_id
AND conp.nepo_id = nepo.nepo_id
AND nepg.nepg_id = cp_nepg_id
AND nepo.status = 'A'
AND nepg.status = 'A';
--
-- Cursor to find the Contract Category ID
CURSOR c_coca( cp_cont_id IN NUMBER
, cp_cate_id IN NUMBER )
IS
SELECT coca_id
FROM contract_categories
WHERE cont_id = cp_cont_id
AND cate_id = cp_cate_id;
--
-- Cursor to find the Contract Parameter ID
CURSOR c_copa( cp_cont_id IN NUMBER
, cp_pars_id IN NUMBER )
IS
SELECT copa_id
FROM contract_parameters
WHERE cont_id = cp_cont_id
AND pars_id = cp_pars_id;
--
-- Cursor to get the conf_net_point_cat_val ID
CURSOR c_nnpcv( cp_coca_id IN NUMBER
, cp_conp_id IN NUMBER )
IS
SELECT nnpcv_id
FROM conf_net_point_cat_vals
WHERE conf_id = p_conf_id
AND coca_id = cp_coca_id
AND conp_id = cp_conp_id;
--
-- Cursor to the conf_net_point_cat_val ID for the given gas day..
CURSOR c_nnpcv_row( cp_coca_id IN NUMBER
, cp_conp_id IN NUMBER
, cp_gas_day IN DATE )
IS
SELECT nnpcv_id
FROM conf_net_point_cat_vals
WHERE conf_id = p_conf_id
AND coca_id = cp_coca_id
AND conp_id = cp_conp_id
AND gas_day = cp_gas_day;
--
l_success BOOLEAN := TRUE;
l_code_pos VARCHAR2(4) := '0000';
--
l_text_length NUMBER := LENGTH(p_text);
l_position NUMBER := 0;
l_token_type VARCHAR2(1) := 'X';
l_token_close_pos NUMBER := 0;
l_token_code VARCHAR2(70) := NULL;
l_temp_code parameters.code%TYPE := NULL;
l_tokens_found NUMBER := 0;
l_brace_counter NUMBER := 0;
l_count_nnpcv NUMBER := 0;
l_nnpcv_id nom_net_point_cat_vals.nnpcv_id%TYPE;
--
l_parameter_id NUMBER := 0;
l_category_id NUMBER := 0;
l_network_point_id NUMBER := 0;
l_temp_alias VARCHAR2(50) := NULL;
l_conp_id cont_network_points.conp_id%TYPE;
l_coca_id contract_categories.coca_id%TYPE;
l_copa_id contract_parameters.copa_id%TYPE;
l_nepg_id NUMBER := 0;
--
previous_was_token BOOLEAN := FALSE;
previous_was_open_brace BOOLEAN := FALSE;
previous_was_close_brace BOOLEAN := FALSE;
previous_was_operator BOOLEAN := FALSE;
previous_was_value BOOLEAN := FALSE;
previous_was_period BOOLEAN := FALSE;
space_encountered BOOLEAN := FALSE;
first_item_found BOOLEAN := TRUE;
valid_token BOOLEAN := TRUE;
missing_nnpcv BOOLEAN := FALSE;
--
l_current_char VARCHAR2(1);
--
l_conp_nepg_count NUMBER := 0;
l_conp_ids VARCHAR2(2000) := NULL;
l_npgp_code VARCHAR2(50) := NULL;
--
BEGIN
--
--caco_debug.putline('SP: efno_rules.rule_text START');
IF l_text_length > 0 THEN
--
--caco_debug.putline('Text Length '||l_text_length||' : '||p_text);
p_select := NULL;
l_count_nnpcv := NVL(p_nnpcv_tab.COUNT,0);
l_position := 1;
l_code_pos := '0010';
--
<>
WHILE l_position <= l_text_length LOOP
--
valid_token := FALSE;
l_temp_alias := NULL;
l_token_type := 'X';
l_token_code := NULL;
l_token_close_pos := 0;
l_category_id := 0;
l_parameter_id := 0;
l_network_point_id := 0;
l_temp_code := NULL;
l_conp_id := 0;
l_coca_id := 0;
l_copa_id := 0;
l_current_char := SUBSTR( p_text, l_position, 1 );
--
l_nepg_id := 0;
l_conp_nepg_count := 0;
l_conp_ids := NULL;
l_npgp_code := NULL;
--
l_code_pos := '0020';
--
<>
CASE
WHEN l_current_char = ' ' THEN
l_code_pos := '0030';
l_position := l_position + 1;
space_encountered := TRUE;
--
IF NOT p_parse_only THEN
p_select := p_select||l_current_char;
END IF;
--
WHEN l_current_char = '$' THEN
--
l_code_pos := '0040';
--
l_nnpcv_id := 0;
--
-- Ensure that the previous found item was not a token
IF previous_was_token
OR previous_was_value
OR previous_was_period
OR previous_was_close_brace
THEN
caco_debug.putline('efno_rules.rule_text: Position in text: '||l_position
||' : Case : Previous item was a token');
l_success := FALSE;
p_select := NULL;
EXIT rule_text_loop;
END IF;
--
-- We have the start of a token - get the rest of it.
--
IF SUBSTR( p_text, l_position + 1, 1 ) != '<' THEN
caco_debug.putline('efno_rules.rule_text: Position in text: '||l_position
||' : Case : < (doesnt exist - illformed token)');
-- Not a well formed token
l_success := FALSE;
p_select := NULL;
EXIT rule_text_loop;
END IF;
--
-- Get the next '>' symbol (closure of the token)
l_token_close_pos := INSTR( p_text, '>', 1, l_tokens_found + 1);
l_token_code := SUBSTR( p_text, l_position + 2, l_token_close_pos - l_position - 2 );
--caco_debug.putline('l_token_code: '||l_token_code);
--
IF l_token_code = 'hours_in_gas_day' THEN
IF NOT p_parse_only THEN
-- Just add call to common utility function to the return SQL text
p_select := p_select||'cout_dates.hours_in_gas_day(p_gas_day)';
END IF;
ELSE
--
l_code_pos := '0050';
--
-- All other substitutable tokens - must check for "Network Point" and apply alias
-- to additional nomination or Network Point Parameters table if necessary
IF UPPER(p_rule_type) = 'SHEET' THEN
--
-- This should be a specific Network Point with concatenated token
-- Check the name in network Points table
--caco_debug.putline('SP: efno_rules.rule_text 010');
OPEN c_network_point( SUBSTR( l_token_code, 1, INSTR( l_token_code, '.' ) - 1 ) );
FETCH c_network_point INTO l_network_point_id;
IF c_network_point%FOUND THEN
--
CLOSE c_network_point;
--
-- get the CONP_ID for the given network point and contract
OPEN c_conp( p_contract_id
, l_network_point_id );
FETCH c_conp INTO l_conp_id;
IF c_conp%FOUND THEN
CLOSE c_conp;
ELSE
-- Bit of a strange problem.
CLOSE c_conp;
caco_debug.putline('efno_rules.rule_text: Position in text: '||l_position
||' : Case : SHEET rule '
||' Network Point not found for Contract');
l_success := FALSE;
p_select := NULL;
EXIT rule_text_loop;
END IF;
--
ELSE
CLOSE c_network_point;
-- not a network point so check the name in the network point groups table
OPEN c_network_point_group( SUBSTR( l_token_code, 1, INSTR( l_token_code, '.' ) - 1 ) );
FETCH c_network_point_group INTO l_nepg_id;
IF c_network_point_group%FOUND THEN
CLOSE c_network_point_group;
-- get the CONP_IDs in a string for the given network point group and contract
FOR r IN c_conp_nepg( p_contract_id
, l_nepg_id ) LOOP
IF l_conp_nepg_count = 0 THEN
l_conp_ids := r.conp_id;
ELSE
l_conp_ids := l_conp_ids||','||r.conp_id;
END IF;
l_conp_nepg_count := l_conp_nepg_count + 1;
END LOOP;
-- if no network points found for contract/nepg then add dummy conp_id so evalution will be 0
-- and the rule will be redundant
IF l_conp_nepg_count = 0 THEN
l_conp_ids := '0';
END IF;
--caco_debug.putline('SP: l_conp_ids: '||l_conp_ids);
--
ELSE
CLOSE c_network_point_group;
-- Network point/network point group does not exist so the text is invalid
caco_debug.putline('efno_rules.rule_text: Position in text: '||l_position
||' : Case : SHEET rule - invalid network point/nepg : ~'||l_token_code||'~');
l_success := FALSE;
p_select := NULL;
EXIT rule_text_loop;
END IF;
END IF;
l_temp_code := SUBSTR( l_token_code, INSTR( l_token_code, '.' ) + 1 );
--
ELSE -- ROW
--caco_debug.putline('SP: efno_rules.rule_text 020');
-- get the CONP_ID for the given network point and contract
IF p_net_point_id IS NOT NULL
AND p_net_point_id > 0
THEN
--caco_debug.putline('Network Point: '||p_net_point_id);
OPEN c_conp( p_contract_id
, p_net_point_id );
FETCH c_conp INTO l_conp_id;
IF c_conp%FOUND THEN
CLOSE c_conp;
--caco_debug.putline('conp: '||l_conp_id);
ELSE
-- Bit of a strange problem.
CLOSE c_conp;
caco_debug.putline('efno_rules.rule_text: Position in text: '||l_position
||' : Case : ROW rule '
||' Network Point not found for Contract'
||chr(10)||p_contract_id
||chr(10)||p_net_point_id);
l_success := FALSE;
p_select := NULL;
EXIT rule_text_loop;
END IF;
--
ELSIF NOT p_parse_only OR p_force_conf THEN
-- What to do here - we weren't given a network point so we are stuck
-- A ROW rule can only be evaluated for a given Network Point
caco_debug.putline('efno_rules.rule_text: Position in text: '||l_position
||' : Case : ROW rule (not parsing) :'
||' Network Point not provided for ROW rule for Contract'
||chr(10)||p_contract_id );
l_success := FALSE;
p_select := NULL;
EXIT rule_text_loop;
--
END IF;
--
l_temp_code := l_token_code;
END IF;
--
--
--caco_debug.putline('SP: efno_rules.rule_text 040');
-- Check if the token is a valid category for the given contract/template (or none)
IF efno_rules.valid_category( p_template_id
, p_contract_id
, l_temp_code
, l_category_id )
THEN
--
--caco_debug.putline('SP: efno_rules.rule_text 050');
l_token_type := 'C';
--
IF NOT p_parse_only
AND NVL(p_contract_id,0) > 0
THEN
-- Need to get the COCA_ID for the Contract
OPEN c_coca( p_contract_id
, l_category_id );
FETCH c_coca INTO l_coca_id;
IF c_coca%FOUND THEN
CLOSE c_coca;
ELSE
CLOSE c_coca;
caco_debug.putline('efno_rules.rule_text: Position in text: '||l_position
||' : Case : Unable to find Contract Category : '||l_temp_code);
l_success := FALSE;
p_select := NULL;
EXIT rule_text_loop;
END IF;
END IF;
--
valid_token := TRUE;
--
ELSE
-- Check if it is a parameter
IF efno_rules.valid_parameter( p_template_id
, p_contract_id
, l_temp_code
, l_parameter_id )
THEN
--caco_debug.putline('Parameter found: '||l_parameter_id);
--
--caco_debug.putline('SP: efno_rules.rule_text 070');
l_token_type := 'P';
--
IF NOT p_parse_only
AND NVL(p_contract_id,0) > 0
THEN
--caco_debug.putline('Looking for copa!');
-- Need to get the COPA_ID for the contract
OPEN c_copa( p_contract_id
, l_parameter_id );
FETCH c_copa INTO l_copa_id;
IF c_copa%FOUND THEN
CLOSE c_copa;
--caco_debug.putline('Found copa: '||l_copa_id);
ELSE
CLOSE c_copa;
caco_debug.putline('efno_rules.rule_text: Position in text: '||l_position
||' : Case : Unable to find Contract Parameter : '||l_temp_code);
l_success := FALSE;
p_select := NULL;
EXIT rule_text_loop;
END IF;
END IF;
--
valid_token := TRUE;
--
ELSE
--
--Check if it is a network point group parameter
IF valid_npgp(p_contract_id
,l_temp_code)
THEN
l_token_type := 'N';
valid_token := TRUE;
l_npgp_code := l_temp_code;
END IF;
--
END IF;
--
--
END IF;
--
--
--caco_debug.putline('SP: efno_rules.rule_text 080');
IF ( valid_token AND NOT p_parse_only ) -- If its a valid token and we are NOT parsing
OR ( valid_token AND p_force_conf ) -- valid token and forcing a confirmation
THEN
--caco_debug.putline('SP: efno_rules.rule_text 090');
--
IF l_token_type = 'C' THEN
--caco_debug.putline('SP: efno_rules.rule_text 091');
--
l_code_pos := '0060';
--
-- Apply network point alias
IF p_force_conf THEN
--
--caco_debug.putline('SP: efno_rules.rule_text 092');
-- forcing a confirmation (due to errors)
--
l_temp_alias := 'cnpcv'||l_conp_id||'x'||l_coca_id;
IF l_conp_ids IS NOT NULL THEN
p_from := 'dual';
ELSE
p_from := p_from ||' , conf_net_point_cat_vals '||l_temp_alias;
p_where := p_where||' AND '||l_temp_alias||'.conf_id = '||p_conf_id;
END IF;
--
-- Lets get the nnpcv_id as we will need this to return
l_count_nnpcv := l_count_nnpcv + 1;
--
IF p_rule_type = 'SHEET' THEN
IF l_conp_ids IS NULL THEN
OPEN c_nnpcv( l_coca_id, l_conp_id );
FETCH c_nnpcv INTO l_nnpcv_id;
IF c_nnpcv%NOTFOUND THEN
-- Houston we have a problem - Contract must have changed.
-- Now we need the conp and coca but should indicate that the data is missing
caco_debug.putline('efno_rules.rule_text: Position in text: '||l_position
||'l_coca_id: '||l_coca_id||' l_conp_id: '||l_conp_id||' : Case : Unable to find Nom Net Point Cat Val ID');
l_success := FALSE;
missing_nnpcv := TRUE;
p_nnpcv_tab(l_count_nnpcv).missing := 'Y';
--
END IF;
CLOSE c_nnpcv;
END IF;
ELSE
OPEN c_nnpcv_row( l_coca_id, l_conp_id, p_gas_day );
FETCH c_nnpcv_row INTO l_nnpcv_id;
IF c_nnpcv_row%NOTFOUND THEN
-- Houston we have a problem - Contract must have changed.
-- Now we need the conp and coca but should indicate that the data is missing
caco_debug.putline('efno_rules.rule_text: Position in text: '||l_position
||' : Case : Unable to find Nom Net Point Cat Val ID');
l_success := FALSE;
missing_nnpcv := TRUE;
p_nnpcv_tab(l_count_nnpcv).missing := 'Y';
--
END IF;
CLOSE c_nnpcv_row;
END IF;
--
p_nnpcv_tab(l_count_nnpcv).nnpcv_id := l_nnpcv_id;
p_nnpcv_tab(l_count_nnpcv).coca_id := l_coca_id;
p_nnpcv_tab(l_count_nnpcv).conp_id := l_conp_id;
p_nnpcv_tab(l_count_nnpcv).gas_day := p_gas_day;
--
ELSE
-- validating a nomination
--caco_debug.putline('SP: efno_rules.rule_text 093');
l_temp_alias := 'nnpcv'||l_conp_id||'x'||l_coca_id;
-- check if there is a nepg involved
IF l_conp_ids IS NOT NULL THEN
p_from := 'dual';
ELSE
p_from := p_from ||' , nom_net_point_cat_vals '||l_temp_alias;
--
-- Add additional tables to translate nominations accross contracts
--
p_from := p_from || ' , cont_network_points cnp1_'||l_conp_id||'x'||l_coca_id||' , cont_network_points cnp2_'||l_conp_id||'x'||l_coca_id||' , contract_categories cc1_'||l_conp_id||'x'||l_coca_id||' , contract_categories cc2_'||l_conp_id||'x'||l_coca_id||' ';
--
END IF;
p_nnpcv_tab(l_count_nnpcv).coca_id := l_coca_id;
-- p_nnpcv_tab(l_count_nnpcv).conp_id := l_conp_id;
p_nnpcv_tab(l_count_nnpcv).gas_day := p_gas_day;
--
END IF;
--
IF p_from NOT LIKE '% cnp1_%' THEN
IF p_nomination_id IS NOT NULL THEN
--caco_debug.putline('SP: efno_rules.rule_text 094');
-- check if there is a nepg involved
IF l_conp_ids IS NOT NULL THEN
p_where := NULL;
ELSE
p_where := p_where||' AND '||l_temp_alias||'.conp_id = '||l_conp_id
||' AND '||l_temp_alias||'.coca_id = '||l_coca_id
||' AND '||l_temp_alias||'.nomi_id = '||p_nomination_id
||' AND '||l_temp_alias||'.gas_day = p_gas_day';
END IF;
--
ELSE
--caco_debug.putline('SP: efno_rules.rule_text 095');
-- check if there is a nepg involved
IF l_conp_ids IS NOT NULL THEN
p_where := NULL;
ELSE
p_where := p_where||' AND '||l_temp_alias||'.conp_id = '||l_conp_id
||' AND '||l_temp_alias||'.coca_id = '||l_coca_id
||' AND '||l_temp_alias||'.gas_day = p_gas_day';
END IF;
--
END IF;
ELSE
--caco_debug.putline('SP: efno_rules.rule_text 096');
-- check if there is a nepg involved
IF l_conp_ids IS NOT NULL THEN
p_where := NULL;
ELSE
p_where := p_where || 'AND cc1_'||l_conp_id||'x'||l_coca_id||'.cate_id = cc2_'||l_conp_id||'x'||l_coca_id||'.cate_id
AND cnp1_'||l_conp_id||'x'||l_coca_id||'.nepo_id = cnp2_'||l_conp_id||'x'||l_coca_id||'.nepo_id
AND cc1_'||l_conp_id||'x'||l_coca_id||'.coca_id = '||l_coca_id||'
AND cc2_'||l_conp_id||'x'||l_coca_id||'.coca_id = '||l_temp_alias||'.coca_id
AND cnp1_'||l_conp_id||'x'||l_coca_id||'.conp_id = '||l_conp_id||'
AND cnp2_'||l_conp_id||'x'||l_coca_id||'.conp_id = '||l_temp_alias||'.conp_id
AND '||l_temp_alias||'.nomi_id = '||p_nomination_id||'
AND '||l_temp_alias||'.gas_day = p_gas_day';
END IF;
END IF;
-- check if there is a nepg involved
IF l_conp_ids IS NOT NULL THEN
p_select := p_select||'efno_rules.get_nepg_value('||NVL(p_nomination_id,0)||', '||l_nepg_id||' ,'||l_coca_id||' ,'||p_conf_id||' ,p_gas_day)';
ELSE
p_select := p_select||l_temp_alias||'.value';
END IF;
--
ELSIF l_token_type = 'P' THEN -- token is parameter
--caco_debug.putline('SP: efno_rules.rule_text 099');
--
l_code_pos := '0070';
--
l_temp_alias := 'cnppv'||l_conp_id||'x'||l_copa_id;
p_from := p_from ||' , cont_net_point_param_vals '||l_temp_alias;
--
p_where := p_where||' AND '||l_temp_alias||'.conp_id = '||l_conp_id
||' AND '||l_temp_alias||'.copa_id = '||l_copa_id;
--
p_select := p_select||'efno_interruption.get_int_val('||l_temp_alias||'.value, '||l_conp_id||', '||l_copa_id||', p_gas_day)';
--
ELSE -- token is a network point group parameter(npgp)
--caco_debug.putline('SP: efno_rules.rule_text 100');
--
l_code_pos := '0075';
--
p_from := 'dual';
--
p_where := NULL;
p_select := p_select||'efno_rules.get_npgp_value('||p_contract_id||', '||l_nepg_id||')';
--
END IF;
--
ELSIF p_parse_only
AND valid_token
THEN
--caco_debug.putline('SP: efno_rules.rule_text 105');
-- Just parsing, token is Valid, move on
NULL;
ELSE -- Not a valid token
--
caco_debug.putline('efno_rules.rule_text: Position in text: '||l_position
||' : Case : invalid token : ~'||l_temp_code||'~');
l_success := FALSE;
p_select := NULL;
EXIT rule_text_loop;
--
END IF;
END IF;
--
--caco_debug.putline('SP: efno_rules.rule_text 110');
l_code_pos := '0080';
--
previous_was_open_brace := FALSE;
previous_was_close_brace := FALSE;
previous_was_token := TRUE;
previous_was_operator := FALSE;
previous_was_value := FALSE;
previous_was_period := FALSE;
space_encountered := FALSE;
--
IF first_item_found THEN
first_item_found := FALSE;
END IF;
--
l_tokens_found := l_tokens_found + 1;
l_position := l_position + ( l_token_close_pos - l_position ) + 1;
--
WHEN l_current_char IN ('0','1','2','3','4','5','6','7','8','9','0') THEN
--
l_code_pos := '0100';
--
IF ( ( previous_was_value OR previous_was_period ) AND space_encountered )
OR previous_was_token
OR previous_was_close_brace
THEN
-- Cant have a value followed by a space followed by a value
caco_debug.putline('efno_rules.rule_text: Position in text: '||l_position||' : Case : invalid value');
l_success := FALSE;
p_select := NULL;
EXIT rule_text_loop;
END IF;
--
previous_was_open_brace := FALSE;
previous_was_close_brace := FALSE;
previous_was_token := FALSE;
previous_was_operator := FALSE;
previous_was_value := TRUE;
previous_was_period := FALSE;
space_encountered := FALSE;
--
IF first_item_found THEN
first_item_found := FALSE;
END IF;
--
IF NOT p_parse_only THEN
p_select := p_select||l_current_char;
END IF;
--
l_position := l_position + 1;
--
WHEN l_current_char = '.' THEN
--
l_code_pos := '0110';
--
IF previous_was_token
OR previous_was_close_brace
OR previous_was_period
OR ( previous_was_value AND space_encountered )
THEN
-- Period can only be preceded by a space, an open brace or an operator
caco_debug.putline('efno_rules.rule_text: Position in text: '||l_position
||' : Case : badly positioned period');
l_success := FALSE;
p_select := NULL;
EXIT rule_text_loop;
END IF;
--
previous_was_open_brace := FALSE;
previous_was_close_brace := FALSE;
previous_was_token := FALSE;
previous_was_operator := FALSE;
previous_was_value := FALSE;
previous_was_period := TRUE;
space_encountered := FALSE;
--
IF first_item_found THEN
first_item_found := FALSE;
END IF;
--
p_select := p_select||l_current_char;
l_position := l_position + 1;
--
WHEN l_current_char IN ('+','-','*','/') THEN
--
l_code_pos := '0120';
--
-- Operator (excluding braces)
IF previous_was_operator
OR previous_was_open_brace
OR first_item_found
THEN
-- Operator must be preceded by a token or a value or a closing brace
caco_debug.putline('efno_rules.rule_text: Position in text: '||l_position
||' : Case : badly positioned operator');
l_success := FALSE;
p_select := NULL;
EXIT rule_text_loop;
END IF;
--
previous_was_open_brace := FALSE;
previous_was_close_brace := FALSE;
previous_was_token := FALSE;
previous_was_operator := TRUE;
previous_was_value := FALSE;
previous_was_period := FALSE;
space_encountered := FALSE;
--
IF first_item_found THEN
first_item_found := FALSE;
END IF;
--
IF NOT p_parse_only THEN
p_select := p_select||l_current_char;
END IF;
--
l_position := l_position + 1;
--
WHEN l_current_char = '(' THEN
--
l_code_pos := '0130';
--
IF previous_was_token
OR previous_was_close_brace
OR previous_was_value
THEN
-- This is a problem - require an operator before the brace
-- or a previous open brace - or nothing (start of text)
caco_debug.putline('efno_rules.rule_text: Position in text: '||l_position
||' : Case : ( - badly positioned open brace');
l_success := FALSE;
p_select := NULL;
EXIT rule_text_loop;
END IF;
--
l_brace_counter := l_brace_counter + 1;
--
previous_was_open_brace := TRUE;
previous_was_close_brace := FALSE;
previous_was_token := FALSE;
previous_was_operator := FALSE;
previous_was_value := FALSE;
previous_was_period := FALSE;
space_encountered := FALSE;
--
IF first_item_found THEN
first_item_found := FALSE;
END IF;
--
IF NOT p_parse_only THEN
p_select := p_select||l_current_char;
END IF;
--
l_position := l_position + 1;
--
WHEN l_current_char = ')' THEN
--
l_code_pos := '0140';
--
IF previous_was_operator
OR previous_was_open_brace
OR first_item_found
THEN
-- This is a problem - require a value or token before the brace
-- Or possibly a close brace
caco_debug.putline('efno_rules.rule_text: Position in text: '||l_position
||' : Case : ) - badly positioned close brace');
l_success := FALSE;
p_select := NULL;
EXIT rule_text_loop;
END IF;
--
l_brace_counter := l_brace_counter - 1;
--
IF l_brace_counter < 0 THEN
-- This is a problem - didn't open enough braces to close this many...
caco_debug.putline('efno_rules.rule_text: Position in text: '||l_position
||' : Case : Too many close braces');
l_success := FALSE;
p_select := NULL;
EXIT rule_text_loop;
END IF;
--
previous_was_open_brace := FALSE;
previous_was_close_brace := TRUE;
previous_was_token := FALSE;
previous_was_operator := FALSE;
previous_was_value := FALSE;
previous_was_period := FALSE;
space_encountered := FALSE;
--
IF first_item_found THEN
first_item_found := FALSE;
END IF;
--
IF NOT p_parse_only THEN
p_select := p_select||l_current_char;
END IF;
--
l_position := l_position + 1;
--
ELSE
--
l_code_pos := '0150';
--
caco_debug.putline('efno_rules.rule_text: Position in text: '||l_position
||' : Case : invalid character ~'||l_current_char||'~');
l_success := FALSE;
p_select := NULL;
EXIT rule_text_loop;
--
END CASE my_case;
--
END LOOP rule_text_loop;
--
IF l_brace_counter > 0
AND l_success
THEN
-- Didn't close all the brace pairs
caco_debug.putline('efno_rules.rule_text: Position in text: '||l_position
||' : Case : All brace pairs not closed');
l_success := FALSE;
p_select := NULL;
END IF;
--
IF l_success THEN
IF LENGTH(p_from) > 0 AND p_from NOT LIKE 'dual%' THEN
-- TRIM first comma
p_from := SUBSTR( p_from, 3 );
END IF;
IF LENGTH(p_where) > 0 THEN
-- Trim the first AND
p_where := SUBSTR( p_where, 5 );
END IF;
--
ELSIF NOT missing_nnpcv THEN
p_return_error := caco_utilities.get_module_text(2270);
-- Invalid Rule and/or Data
END IF;
--
END IF;
--
--caco_debug.putline('SP: p_select: '||p_select);
--caco_debug.putline('SP: p_from: '||p_from);
--caco_debug.putline('SP: p_where: '||p_where);
--caco_debug.putline('SP: efno_rules.rule_text END');
RETURN l_success;
--caco_debug.putline('SP: efno_rules.rule_text END');
--
EXCEPTION
WHEN others THEN
caco_debug.putline('efno_rules.rule_text: Position in Code : '||l_code_pos);
caco_debug.putline('Position in TEXT : '||l_position);
caco_debug.putline(sqlerrm(sqlcode));
-- Write an error and carry on
cout_err.report_and_go( p_exception_number => sqlcode
, p_exception_message => 'Position in code '||l_code_pos
||' Position in TEXT : '||l_position
||' '||sqlerrm(sqlcode)
, p_source => 'efno_rules.rule_text');
--
RAISE;
END rule_text;
FUNCTION rule_test_passed ( p_left_value IN VARCHAR2
, p_right_value IN VARCHAR2
, p_relation IN VARCHAR2 )
RETURN BOOLEAN
IS
l_success BOOLEAN := FALSE;
l_test_sql VARCHAR2(4000);
l_test_valid VARCHAR2(5) := 'FALSE';
BEGIN
--
-- Now check to see if the values satisfy the rule_relation
--
l_test_sql := 'SELECT CASE WHEN '||p_left_value
||' '||p_relation
||' '||p_right_value
||' THEN ''TRUE'''
||' ELSE ''FALSE'''
||' END'
||' FROM dual';
--
EXECUTE IMMEDIATE l_test_sql INTO l_test_valid;
--
--caco_debug.putline(l_test_sql);
--
-- This return boolean in the nom_record will allow us to hightlight
-- specific rows to the user that are in error (done in calling program)
-- Plus that is where any related error messages will be dealt with.
--
IF l_test_valid = 'TRUE' THEN
l_success := TRUE;
ELSE
l_success := FALSE;
END IF;
--
RETURN l_success;
--
END rule_test_passed;
/**
-- FUNCTION validate_rule
-- Validates a single EXISTING rule previously defined through the EFT Nominations Web interface
-- and optionally validates the data stored
--
-- Examples
-- To just parse an existing ROW rule (not assigned to a contract or contract template)
-- l_boolean := validate_rule( 12, 'ROW', TRUE, l_dummy_nnpcv_tab, l_dummy_nom_data_table );
--
-- To parse a Rule for a specified contract template
-- l_boolean := validate_rule( 12, 'ROW', TRUE, l_dummy_nnpcv_tab, l_dummy_nom_data_table, 1 );
--
-- To parse a Rule for a specified contract
-- l_boolean := validate_rule( 12, 'ROW', TRUE, l_dummy_nnpcv_tab, l_dummy_nom_data_table, p_contract_id => 2 );
-- OR l_boolean := validate_rule( 12, 'ROW', TRUE, l_dummy_nnpcv_tab, l_dummy_nom_data_table, NULL, 2 );
--
-- To parse a Rule for a contract AND validate the data for a nomination
-- l_boolean := validate_rule( 12, 'ROW', FALSE, l_nnpcv_tab, l_nom_data_table, p_contract_id => 2, p_nomination_id => 3 );
-- OR l_boolean := validate_rule( 12, 'ROW', FALSE, l_nnpcv_tab l_nom_data_table, NULL, 2, 3 );
--
-- %param p_rule_id The Unique identifier of the ROW or SHEET rule
-- %param p_rule_type ROW or SHEET
-- %param p_parse_only TRUE indicates that only syntax checking is required
-- %param p_nnpcv_tab Will return a table of CONP and COCA id's used in the rule when NOT parsing
-- %param p_nom_table Table of resulting values passed out to the calling routine for evaluation
-- %param p_template_id Unique identifier of a contract template
-- %param p_contract_id Unique identifier of a contract
-- %param p_nomination_id Unique identifier of a Nomination - used if not parsing
--
-- %return BOOLEAN TRUE indicating that the rule is valid syntactically if parse only or that the data passed the test
-- and values have been returned for further checking
*/
FUNCTION validate_rule ( p_rule_id IN NUMBER
, p_rule_type IN VARCHAR2
, p_parse_only IN BOOLEAN
, p_nnpcv_tab OUT efno_confirmations.nnpcv_tab
, p_nom_table OUT nom_validation_table
, p_template_id IN NUMBER DEFAULT 0
, p_contract_id IN NUMBER DEFAULT 0
, p_nomination_id IN NUMBER DEFAULT 0 )
RETURN BOOLEAN
IS
--
-- Cursor to grab the parts of the row rule required
--
CURSOR c_row_rule IS
SELECT left_side
, right_side
, rule_relation
, error_message_hu
, error_message_en
FROM rules
WHERE rule_id = p_rule_id;
--
-- Cursor to grab sheet based rule information
--
CURSOR c_sheet_rule IS
SELECT left_side
, right_side
, rule_relation
, error_message_hu
, error_message_en
FROM contract_rules
WHERE coru_id = p_rule_id;
--
-- Cursor to get the date from a SHEET based nomination
-- (sheet based rules can only work against a single day nomination)
CURSOR c_sheet_nom IS
SELECT gas_day
FROM nom_net_point_cat_vals
WHERE nomi_id = p_nomination_id
AND ROWNUM = 1;
--
-- Cursor to get the specific Network Points for the given nomination
-- 8/10/2009 SP for entry mandatory offer contracts we only need to
-- select the virtual network point for row based rules
--
CURSOR c_row_nom IS
SELECT DISTINCT conp.nepo_id network_point
, nnpcv.gas_day gas_day
, conp.display_sequence display_sequence
FROM nom_net_point_cat_vals nnpcv
, cont_network_points conp
, nominations nomi
, network_points nepo
WHERE nomi.cont_id = conp.cont_id
AND nomi.nomi_id = nnpcv.nomi_id
AND nnpcv.nomi_id = p_nomination_id
--AND nomi.cont_id = p_contract_id
AND nepo.nepo_id = conp.nepo_id
AND ((efno_contracts.emo_contract(p_contract_id) = 'Y' AND nepo.nepo_type = 'V')
OR efno_contracts.emo_contract(p_contract_id) = 'N')
ORDER BY nnpcv.gas_day ASC
, conp.display_sequence ASC;
--
--
l_success BOOLEAN := TRUE;
--
l_rule_row c_row_rule%ROWTYPE;
left_is_valid BOOLEAN := FALSE;
right_is_valid BOOLEAN := FALSE;
--
--
l_left_sql VARCHAR2(32767) := NULL;
l_left_select VARCHAR2(32767) := NULL;
l_left_from VARCHAR2(32767) := NULL;
l_left_where VARCHAR2(32767) := NULL;
--
l_right_sql VARCHAR2(32767) := NULL;
l_right_select VARCHAR2(32767) := NULL;
l_right_from VARCHAR2(32767) := NULL;
l_right_where VARCHAR2(32767) := NULL;
--
l_return_error VARCHAR2(255) := NULL;
--
l_gas_day DATE := NULL;
l_gas_day_char VARCHAR2(40) := NULL;
--
rule_found BOOLEAN := FALSE;
l_no_data BOOLEAN := FALSE;
l_nom_sites_count NUMBER := 0;
--
BEGIN
-- Get the rule information
--
IF UPPER(p_rule_type) = 'ROW' THEN
--
OPEN c_row_rule;
FETCH c_row_rule INTO l_rule_row;
IF c_row_rule%FOUND THEN
rule_found := TRUE;
END IF;
CLOSE c_row_rule;
--
ELSIF UPPER(p_rule_type) = 'SHEET' THEN
--
OPEN c_sheet_rule;
FETCH c_sheet_rule INTO l_rule_row;
IF c_sheet_rule%FOUND THEN
rule_found := TRUE;
END IF;
CLOSE c_sheet_rule;
--
END IF;
--
IF rule_found THEN
--
IF p_parse_only THEN
--
-- Process/validate the left side
left_is_valid := rule_text( p_text => l_rule_row.left_side
, p_rule_type => p_rule_type
, p_select => l_left_select
, p_from => l_left_from
, p_where => l_left_where
, p_nnpcv_tab => p_nnpcv_tab
, p_template_id => p_template_id
, p_contract_id => p_contract_id
, p_parse_only => p_parse_only
, p_return_error => l_return_error );
--
-- Process/validate the Right side
right_is_valid := rule_text( p_text => l_rule_row.right_side
, p_rule_type => p_rule_type
, p_select => l_right_select
, p_from => l_right_from
, p_where => l_right_where
, p_nnpcv_tab => p_nnpcv_tab
, p_template_id => p_template_id
, p_contract_id => p_contract_id
, p_parse_only => p_parse_only
, p_return_error => l_return_error );
--
IF NOT ( left_is_valid AND right_is_valid ) THEN
l_success := FALSE;
END IF;
--
ELSE
-- Not just parsing. We have to be checking against a nomination.
-- Need to fully evaluate the rule against the nomination data as we are not just parsing
IF p_nomination_id IS NOT NULL AND p_nomination_id > 0
AND p_contract_id IS NOT NULL AND p_contract_id > 0
THEN
--
-- Find the specific gas day if the rule is a sheet based rule
IF UPPER(p_rule_type) = 'SHEET' THEN
--
-- Process/validate the left side - output used specifically for SHEET rules
left_is_valid := rule_text( p_text => l_rule_row.left_side
, p_rule_type => p_rule_type
, p_select => l_left_select
, p_from => l_left_from
, p_where => l_left_where
, p_nnpcv_tab => p_nnpcv_tab
, p_template_id => p_template_id
, p_contract_id => p_contract_id
, p_nomination_id => p_nomination_id
, p_parse_only => p_parse_only
, p_return_error => l_return_error );
--
-- Process/validate the Right side
right_is_valid := rule_text( p_text => l_rule_row.right_side
, p_rule_type => p_rule_type
, p_select => l_right_select
, p_from => l_right_from
, p_where => l_right_where
, p_nnpcv_tab => p_nnpcv_tab
, p_template_id => p_template_id
, p_contract_id => p_contract_id
, p_nomination_id => p_nomination_id
, p_parse_only => p_parse_only
, p_return_error => l_return_error );
--
IF left_is_valid AND right_is_valid THEN
-- Ensure that the FROMs and the WHEREs are not null
IF l_left_from IS NULL THEN
l_left_from := 'dual';
END IF;
IF l_right_from IS NULL THEN
l_right_from := 'dual';
END IF;
IF l_left_where IS NOT NULL THEN
l_left_where := ' WHERE '||l_left_where;
END IF;
IF l_right_where IS NOT NULL THEN
l_right_where := ' WHERE '||l_right_where;
END IF;
--
-- We need to get the values - build the sql statements
l_left_sql := 'SELECT ('||l_left_select||') sql_value FROM '||l_left_from||l_left_where;
--
l_right_sql := 'SELECT ('||l_right_select||') sql_value FROM '||l_right_from||l_right_where;
--
OPEN c_sheet_nom;
FETCH c_sheet_nom INTO l_gas_day;
--
IF c_sheet_nom%FOUND THEN
CLOSE c_sheet_nom;
--
p_nom_table(1).nr_gas_day := l_gas_day;
p_nom_table(1).nr_rule_id := p_rule_id;
p_nom_table(1).nr_rule_type := 'SHEET';
--
-- We will have to replace any p_gas_day token with a TO_DATE conversion of the gas day
-- due to needing to submit a text SQL statement to DBMS_SQL
l_gas_day_char := 'TO_DATE('''||TO_CHAR(l_gas_day, 'DD-MON-YYYY')||''',''DD-MON-YYYY'')';
--
l_left_sql := REPLACE( l_left_sql, 'p_gas_day', l_gas_day_char );
--
l_right_sql := REPLACE( l_right_sql, 'p_gas_day', l_gas_day_char );
--
--
-- For form based rules, there should be only a single returned value from each side of the rule
--
evaluate_rule_sql( l_left_sql
, l_success
, l_no_data
, p_nom_table(1).nr_left_side_value );
IF l_success THEN
-- Not worth doing this unless the left side was a success!
evaluate_rule_sql( l_right_sql
, l_success
, l_no_data
, p_nom_table(1).nr_right_side_value );
END IF;
--
-- Success variable has already been set on result of evaluating each side of the SQL
-- So see if the values satisfy the relation
IF l_success THEN
--
IF rule_test_passed( p_nom_table(1).nr_left_side_value
, p_nom_table(1).nr_right_side_value
, l_rule_row.rule_relation )
THEN
p_nom_table(1).nr_valid := TRUE;
ELSE
p_nom_table(1).nr_valid := FALSE;
END IF;
--
ELSE
-- Delete any values from the nom_table
p_nom_table.DELETE;
END IF;
--
ELSE
CLOSE c_sheet_nom;
--
-- No gas day found - not good - can't complete our work here.
l_success := FALSE;
--
END IF;
--
ELSE
-- either the left or right side of the rule is invalid
l_success := FALSE;
--
END IF;
--
ELSE
-- We need to run the rule for each and every site of the nomination...
-- So we need to construct an array of left side values and the result
-- of the comparsion with the rule relation
<>
FOR r IN c_row_nom LOOP
-- caco_debug.putline('Validate rule: '||r.network_point);
--
l_nom_sites_count := l_nom_sites_count + 1;
left_is_valid := FALSE;
right_is_valid := FALSE;
--
l_left_sql := NULL;
l_right_sql := NULL;
--
-- Process/validate the Left side
left_is_valid := rule_text( p_text => l_rule_row.left_side
, p_rule_type => p_rule_type
, p_select => l_left_select
, p_from => l_left_from
, p_where => l_left_where
, p_nnpcv_tab => p_nnpcv_tab
, p_contract_id => p_contract_id
, p_nomination_id => p_nomination_id
, p_net_point_id => r.network_point
, p_gas_day => r.gas_day
, p_parse_only => p_parse_only
, p_return_error => l_return_error );
--
-- Process/validate the Right side
right_is_valid := rule_text( p_text => l_rule_row.right_side
, p_rule_type => p_rule_type
, p_select => l_right_select
, p_from => l_right_from
, p_where => l_right_where
, p_nnpcv_tab => p_nnpcv_tab
, p_contract_id => p_contract_id
, p_nomination_id => p_nomination_id
, p_net_point_id => r.network_point
, p_gas_day => r.gas_day
, p_parse_only => p_parse_only
, p_return_error => l_return_error );
--
IF left_is_valid AND right_is_valid THEN
--
-- Ensure that the FROMs and the WHEREs are not null
IF l_left_from IS NULL THEN
l_left_from := 'dual';
END IF;
IF l_right_from IS NULL THEN
l_right_from := 'dual';
END IF;
IF l_left_where IS NOT NULL THEN
l_left_where := ' WHERE '||l_left_where;
END IF;
IF l_right_where IS NOT NULL THEN
l_right_where := ' WHERE '||l_right_where;
END IF;
--
-- We need to get the values so lets build the sql statements
l_left_sql := 'SELECT ('||l_left_select||') sql_value FROM '||l_left_from||l_left_where;
--
l_right_sql := 'SELECT ('||l_right_select||') sql_value FROM '||l_right_from||l_right_where;
--
--
-- We will have to replace any p_gas_day token with a TO_DATE conversion of the gas day
-- due to needing to submit a text SQL statement to DBMS_SQL
l_gas_day_char := 'TO_DATE('''||TO_CHAR(r.gas_day, 'DD-MON-YYYY')||''',''DD-MON-YYYY'')';
--
l_left_sql := REPLACE( l_left_sql, 'p_gas_day', l_gas_day_char );
l_right_sql := REPLACE( l_right_sql, 'p_gas_day', l_gas_day_char );
--
p_nom_table(l_nom_sites_count).nr_nepo_id := r.network_point;
p_nom_table(l_nom_sites_count).nr_gas_day := r.gas_day;
p_nom_table(l_nom_sites_count).nr_rule_id := p_rule_id;
p_nom_table(l_nom_sites_count).nr_rule_type := 'ROW';
--
--
-- Get the fully evaluated Numeric Value of each side of the rule
-- for the given information and this specific network point
--
evaluate_rule_sql( l_left_sql
, l_success
, l_no_data
, p_nom_table(l_nom_sites_count).nr_left_side_value );
--
IF l_success THEN
-- Not worth doing this unless the left side was a success!
evaluate_rule_sql( l_right_sql
, l_success
, l_no_data
, p_nom_table(l_nom_sites_count).nr_right_side_value );
END IF;
--
IF NOT l_success THEN
-- Exit Loop as the rule won't validate...
p_nom_table.DELETE;
l_success := FALSE;
EXIT row_nom_loop;
END IF;
--
--
IF rule_test_passed( p_nom_table(l_nom_sites_count).nr_left_side_value
, p_nom_table(l_nom_sites_count).nr_right_side_value
, l_rule_row.rule_relation )
THEN
p_nom_table(l_nom_sites_count).nr_valid := TRUE;
-- caco_debug.putline('Rule is valid'||p_nom_table(l_nom_sites_count).nr_left_side_value||l_rule_row.rule_relation||p_nom_table(l_nom_sites_count).nr_right_side_value);
ELSE
p_nom_table(l_nom_sites_count).nr_valid := FALSE;
-- caco_debug.putline('Rule is invalid'||p_nom_table(l_nom_sites_count).nr_left_side_value||l_rule_row.rule_relation||p_nom_table(l_nom_sites_count).nr_right_side_value);
END IF;
--
--
ELSE
-- Exit Loop as the rule won't validate...
p_nom_table.DELETE;
l_success := FALSE;
EXIT row_nom_loop;
--
END IF;
--
END LOOP row_nom_loop;
--
IF c_row_nom%ISOPEN THEN
CLOSE c_row_nom;
END IF;
--
END IF;
--
ELSE
-- To evaluate the rule - we need the nomination id and contract id so this fails
l_success := FALSE;
--
END IF;
--
END IF; -- End of validating against a nomination
--
ELSE
-- No rule found
l_success := FALSE;
--
END IF;
--
RETURN l_success;
--
END validate_rule;
FUNCTION validate_rule_conf ( p_gas_day IN DATE
, p_rule_id IN NUMBER
, p_rule_type IN VARCHAR2
, p_parse_only IN BOOLEAN
, p_nnpcv_tab IN OUT efno_confirmations.nnpcv_tab
, p_nom_table OUT nom_validation_table
, p_template_id IN NUMBER DEFAULT 0
, p_contract_id IN NUMBER DEFAULT 0
, p_nomination_id IN NUMBER DEFAULT 0 )
RETURN BOOLEAN
IS
--
--
--
--
-- Cursor to grab the parts of the row rule required
--
CURSOR c_row_rule IS
SELECT left_side
, right_side
, rule_relation
, error_message_hu
, error_message_en
FROM rules
WHERE rule_id = p_rule_id;
--
-- Cursor to grab sheet based rule information
--
CURSOR c_sheet_rule IS
SELECT left_side
, right_side
, rule_relation
, error_message_hu
, error_message_en
FROM contract_rules
WHERE coru_id = p_rule_id;
--
-- Cursor to get the date from a SHEET based nomination
-- (sheet based rules can only work against a single day nomination)
CURSOR c_sheet_nom IS
SELECT gas_day
FROM nom_net_point_cat_vals
WHERE nomi_id = p_nomination_id
AND ROWNUM = 1;
--
-- Cursor to get the specific Network Points for the given nomination
CURSOR c_row_nom IS
SELECT DISTINCT conp.nepo_id network_point
, nnpcv.gas_day gas_day
, conp.display_sequence display_sequence
FROM nom_net_point_cat_vals nnpcv
, cont_network_points conp
, nominations nomi
WHERE nomi.cont_id = conp.cont_id
AND nomi.nomi_id = nnpcv.nomi_id
AND nnpcv.nomi_id = p_nomination_id
--AND nomi.cont_id = p_contract_id
ORDER BY nnpcv.gas_day ASC
, conp.display_sequence ASC;
--
--
l_success BOOLEAN := TRUE;
--
l_rule_row c_row_rule%ROWTYPE;
left_is_valid BOOLEAN := FALSE;
right_is_valid BOOLEAN := FALSE;
--
--
l_left_sql VARCHAR2(32767) := NULL;
l_left_select VARCHAR2(32767) := NULL;
l_left_from VARCHAR2(32767) := NULL;
l_left_where VARCHAR2(32767) := NULL;
--
l_right_sql VARCHAR2(32767) := NULL;
l_right_select VARCHAR2(32767) := NULL;
l_right_from VARCHAR2(32767) := NULL;
l_right_where VARCHAR2(32767) := NULL;
--
l_return_error VARCHAR2(255) := NULL;
--
l_gas_day DATE := NULL;
l_gas_day_char VARCHAR2(40) := NULL;
l_int_gas_day_char VARCHAR2(40) := NULL;
--
rule_found BOOLEAN := FALSE;
l_no_data BOOLEAN := FALSE;
l_nom_sites_count NUMBER := 0;
--
FUNCTION array_invalid ( p_nepo_id IN network_points.nepo_id%TYPE ) RETURN BOOLEAN IS
l_return BOOLEAN := FALSE;
BEGIN
--
-- caco_debug.putline('Array count: '||p_nnpcv_tab.COUNT||' looking for nepo: ');
--
<>
FOR i IN 1..p_nnpcv_tab.COUNT LOOP
--
-- caco_debug.putline(i||' : conp :'||p_nnpcv_tab(i).conp_id||' nepo: '||P_NEPO_ID);
--
FOR j IN (SELECT NULL FROM cont_network_points c WHERE c.conp_id = p_nnpcv_tab(i).conp_id AND c.nepo_id = p_nepo_id) LOOP
--
-- CACO_DEBUG.PUTLINE('found!!!!!!!!!!!!!');
--
IF p_nnpcv_tab(i).in_error THEN
l_return := TRUE;
END IF;
EXIT outer;
--
END LOOP;
--
END LOOP;
--
RETURN l_return;
--
END;
--
BEGIN
-- Get the rule information
--
IF UPPER(p_rule_type) = 'ROW' THEN
--
OPEN c_row_rule;
FETCH c_row_rule INTO l_rule_row;
IF c_row_rule%FOUND THEN
rule_found := TRUE;
END IF;
CLOSE c_row_rule;
--
ELSIF UPPER(p_rule_type) = 'SHEET' THEN
--
OPEN c_sheet_rule;
FETCH c_sheet_rule INTO l_rule_row;
IF c_sheet_rule%FOUND THEN
rule_found := TRUE;
END IF;
CLOSE c_sheet_rule;
--
END IF;
--
IF rule_found THEN
--
IF p_parse_only THEN
--
-- Process/validate the left side
left_is_valid := rule_text( p_text => l_rule_row.left_side
, p_rule_type => p_rule_type
, p_select => l_left_select
, p_from => l_left_from
, p_where => l_left_where
, p_nnpcv_tab => p_nnpcv_tab
, p_template_id => p_template_id
, p_contract_id => p_contract_id
, p_parse_only => p_parse_only
, p_return_error => l_return_error );
--
-- Process/validate the Right side
right_is_valid := rule_text( p_text => l_rule_row.right_side
, p_rule_type => p_rule_type
, p_select => l_right_select
, p_from => l_right_from
, p_where => l_right_where
, p_nnpcv_tab => p_nnpcv_tab
, p_template_id => p_template_id
, p_contract_id => p_contract_id
, p_parse_only => p_parse_only
, p_return_error => l_return_error );
--
IF NOT ( left_is_valid AND right_is_valid ) THEN
l_success := FALSE;
END IF;
--
ELSE
-- Not just parsing. We have to be checking against a nomination.
-- Need to fully evaluate the rule against the nomination data as we are not just parsing
IF p_nomination_id IS NOT NULL AND p_nomination_id > 0
AND p_contract_id IS NOT NULL AND p_contract_id > 0
THEN
--
-- Find the specific gas day if the rule is a sheet based rule
IF UPPER(p_rule_type) = 'SHEET' THEN
--
-- Process/validate the left side - output used specifically for SHEET rules
left_is_valid := rule_text( p_text => l_rule_row.left_side
, p_rule_type => p_rule_type
, p_select => l_left_select
, p_from => l_left_from
, p_where => l_left_where
, p_nnpcv_tab => p_nnpcv_tab
, p_template_id => p_template_id
, p_contract_id => p_contract_id
, p_nomination_id => p_nomination_id
, p_parse_only => p_parse_only
, p_return_error => l_return_error );
--
-- Process/validate the Right side
right_is_valid := rule_text( p_text => l_rule_row.right_side
, p_rule_type => p_rule_type
, p_select => l_right_select
, p_from => l_right_from
, p_where => l_right_where
, p_nnpcv_tab => p_nnpcv_tab
, p_template_id => p_template_id
, p_contract_id => p_contract_id
, p_nomination_id => p_nomination_id
, p_parse_only => p_parse_only
, p_return_error => l_return_error );
--
IF left_is_valid AND right_is_valid THEN
-- Ensure that the FROMs and the WHEREs are not null
IF l_left_from IS NULL THEN
l_left_from := 'dual';
END IF;
IF l_right_from IS NULL THEN
l_right_from := 'dual';
END IF;
IF l_left_where IS NOT NULL THEN
l_left_where := ' WHERE '||l_left_where;
END IF;
IF l_right_where IS NOT NULL THEN
l_right_where := ' WHERE '||l_right_where;
END IF;
--
-- We need to get the values - build the sql statements
l_left_sql := 'SELECT ('||l_left_select||') sql_value FROM '||l_left_from||l_left_where;
--
l_right_sql := 'SELECT ('||l_right_select||') sql_value FROM '||l_right_from||l_right_where;
--
OPEN c_sheet_nom;
FETCH c_sheet_nom INTO l_gas_day;
--
IF c_sheet_nom%FOUND THEN
CLOSE c_sheet_nom;
--
p_nom_table(1).nr_gas_day := l_gas_day;
p_nom_table(1).nr_rule_id := p_rule_id;
p_nom_table(1).nr_rule_type := 'SHEET';
--
-- We will have to replace any p_gas_day token with a TO_DATE conversion of the gas day
-- due to needing to submit a text SQL statement to DBMS_SQL
l_gas_day_char := 'TO_DATE('''||TO_CHAR(l_gas_day, 'DD-MON-YYYY')||''',''DD-MON-YYYY'')';
--
l_left_sql := REPLACE( l_left_sql, 'p_gas_day', l_gas_day_char );
--
l_right_sql := REPLACE( l_right_sql, 'p_gas_day', l_gas_day_char );
--
--
-- For form based rules, there should be only a single returned value from each side of the rule
--
evaluate_rule_sql( l_left_sql
, l_success
, l_no_data
, p_nom_table(1).nr_left_side_value );
IF l_success THEN
-- Not worth doing this unless the left side was a success!
evaluate_rule_sql( l_right_sql
, l_success
, l_no_data
, p_nom_table(1).nr_right_side_value );
END IF;
--
-- Success variable has already been set on result of evaluating each side of the SQL
-- So see if the values satisfy the relation
IF l_success THEN
--
IF rule_test_passed( p_nom_table(1).nr_left_side_value
, p_nom_table(1).nr_right_side_value
, l_rule_row.rule_relation )
THEN
p_nom_table(1).nr_valid := TRUE;
ELSE
p_nom_table(1).nr_valid := FALSE;
END IF;
--
ELSE
-- Delete any values from the nom_table
p_nom_table.DELETE;
END IF;
--
ELSE
CLOSE c_sheet_nom;
--
-- No gas day found - not good - can't complete our work here.
l_success := FALSE;
--
END IF;
--
ELSE
-- either the left or right side of the rule is invalid
l_success := FALSE;
--
END IF;
--
ELSE
-- We need to run the rule for each and every site of the nomination...
-- So we need to construct an array of left side values and the result
-- of the comparsion with the rule relation
<>
FOR r IN c_row_nom LOOP
--
-- caco_debug.putline('efno_rules.nom row nepo is:'||r.network_point);
IF array_invalid(r.network_point) THEN
-- caco_debug.putline('Network point: '||r.network_point||' invalid.');
--
l_nom_sites_count := l_nom_sites_count + 1;
left_is_valid := FALSE;
right_is_valid := FALSE;
--
l_left_sql := NULL;
l_right_sql := NULL;
--
-- Process/validate the Left side
left_is_valid := rule_text( p_text => l_rule_row.left_side
, p_rule_type => p_rule_type
, p_select => l_left_select
, p_from => l_left_from
, p_where => l_left_where
, p_nnpcv_tab => p_nnpcv_tab
, p_contract_id => p_contract_id
, p_nomination_id => p_nomination_id
, p_net_point_id => r.network_point
, p_gas_day => r.gas_day
, p_parse_only => p_parse_only
, p_return_error => l_return_error );
--
-- Process/validate the Right side
right_is_valid := rule_text( p_text => l_rule_row.right_side
, p_rule_type => p_rule_type
, p_select => l_right_select
, p_from => l_right_from
, p_where => l_right_where
, p_nnpcv_tab => p_nnpcv_tab
, p_contract_id => p_contract_id
, p_nomination_id => p_nomination_id
, p_net_point_id => r.network_point
, p_gas_day => r.gas_day
, p_parse_only => p_parse_only
, p_return_error => l_return_error );
--
IF left_is_valid AND right_is_valid THEN
--
-- Ensure that the FROMs and the WHEREs are not null
IF l_left_from IS NULL THEN
l_left_from := 'dual';
END IF;
IF l_right_from IS NULL THEN
l_right_from := 'dual';
END IF;
IF l_left_where IS NOT NULL THEN
l_left_where := ' WHERE '||l_left_where;
END IF;
IF l_right_where IS NOT NULL THEN
l_right_where := ' WHERE '||l_right_where;
END IF;
--
-- We need to get the values so lets build the sql statements
l_left_sql := 'SELECT ('||l_left_select||') sql_value FROM '||l_left_from||l_left_where;
--
l_right_sql := 'SELECT ('||l_right_select||') sql_value FROM '||l_right_from||l_right_where;
--
--
-- We will have to replace any p_gas_day token with a TO_DATE conversion of the gas day
-- due to needing to submit a text SQL statement to DBMS_SQL
-- l_gas_day_char := 'TO_DATE('''||TO_CHAR(r.gas_day, 'DD-MON-YYYY')||''',''DD-MON-YYYY'')';
l_gas_day_char := 'TO_DATE('''||TO_CHAR(p_gas_day, 'DD-MON-YYYY')||''',''DD-MON-YYYY'')';
caco_debug.putline('l_gas_day_char: '||l_gas_day_char);
--
l_left_sql := REPLACE( l_left_sql, 'p_gas_day', l_gas_day_char );
l_right_sql := REPLACE( l_right_sql, 'p_gas_day', l_gas_day_char );
--
--caco_debug.putline(l_right_sql);
--
p_nom_table(l_nom_sites_count).nr_nepo_id := r.network_point;
p_nom_table(l_nom_sites_count).nr_gas_day := r.gas_day;
p_nom_table(l_nom_sites_count).nr_rule_id := p_rule_id;
p_nom_table(l_nom_sites_count).nr_rule_type := 'ROW';
--
--
-- Get the fully evaluated Numeric Value of each side of the rule
-- for the given information and this specific network point
--
evaluate_rule_sql( l_left_sql
, l_success
, l_no_data
, p_nom_table(l_nom_sites_count).nr_left_side_value );
--
IF l_success THEN
-- Not worth doing this unless the left side was a success!
evaluate_rule_sql( l_right_sql
, l_success
, l_no_data
, p_nom_table(l_nom_sites_count).nr_right_side_value );
END IF;
--
IF NOT l_success THEN
-- Exit Loop as the rule won't validate...
p_nom_table.DELETE;
l_success := FALSE;
EXIT row_nom_loop;
END IF;
--
--
caco_debug.putline('EVAL: '||p_nom_table(l_nom_sites_count).nr_left_side_value||l_rule_row.rule_relation||p_nom_table(l_nom_sites_count).nr_right_side_value);
IF rule_test_passed( p_nom_table(l_nom_sites_count).nr_left_side_value
, p_nom_table(l_nom_sites_count).nr_right_side_value
, l_rule_row.rule_relation )
THEN
p_nom_table(l_nom_sites_count).nr_valid := TRUE;
ELSE
p_nom_table(l_nom_sites_count).nr_valid := FALSE;
END IF;
--
--
ELSE
-- Exit Loop as the rule won't validate...
p_nom_table.DELETE;
l_success := FALSE;
EXIT row_nom_loop;
--
END IF;
--
END IF; -- if network point invalid
--
END LOOP row_nom_loop;
--
IF c_row_nom%ISOPEN THEN
CLOSE c_row_nom;
END IF;
--
END IF;
--
ELSE
-- To evaluate the rule - we need the nomination id and contract id so this fails
l_success := FALSE;
--
END IF;
--
END IF; -- End of validating against a nomination
--
ELSE
-- No rule found
l_success := FALSE;
--
END IF;
--
RETURN l_success;
--
END validate_rule_conf;
FUNCTION insert_row_rule( p_rule_id OUT NUMBER
, p_rule_name IN VARCHAR2
, p_left_side IN VARCHAR2
, p_rule_relation IN VARCHAR2
, p_right_side IN VARCHAR2
, p_err_message_hu IN VARCHAR2
, p_err_message_en IN VARCHAR2
, p_return_error OUT VARCHAR2 )
RETURN BOOLEAN
IS
l_success BOOLEAN := TRUE;
BEGIN
--
BEGIN
INSERT INTO rules
( rule_id
, rule_name
, left_side
, rule_relation
, right_side
, error_message_hu
, error_message_en )
VALUES
( rule_seq.nextval
, p_rule_name
, p_left_side
, p_rule_relation
, p_right_side
, p_err_message_hu
, p_err_message_en )
RETURNING rule_id INTO p_rule_id;
--
EXCEPTION
WHEN others THEN
l_success := FALSE;
--
-- Return message
p_return_error := caco_utilities.get_module_text(2330);
-- An unexpected error has occurred. Please contact support
-- Write an error and carry on
cout_err.report_and_go( p_exception_number => sqlcode
, p_exception_message => sqlerrm(sqlcode)
, p_source => 'efno_rules.insert_row_rule');
--
END;
--
RETURN l_success;
--
END insert_row_rule;
FUNCTION update_row_rule( p_rule_id IN NUMBER
, p_rule_name IN VARCHAR2
, p_left_side IN VARCHAR2
, p_rule_relation IN VARCHAR2
, p_right_side IN VARCHAR2
, p_err_message_hu IN VARCHAR2
, p_err_message_en IN VARCHAR2
, p_return_error OUT VARCHAR2 )
RETURN BOOLEAN
IS
l_success BOOLEAN := TRUE;
BEGIN
--
BEGIN
UPDATE rules
SET rule_name = p_rule_name
, left_side = p_left_side
, rule_relation = p_rule_relation
, right_side = p_right_side
, error_message_hu = p_err_message_hu
, error_message_en = p_err_message_en
WHERE rule_id = p_rule_id;
--
EXCEPTION
WHEN others THEN
l_success := FALSE;
--
-- Return message
p_return_error := caco_utilities.get_module_text(2330);
-- An unexpected error has occurred. Please contact support
-- Write an error and carry on
cout_err.report_and_go( p_exception_number => sqlcode
, p_exception_message => sqlerrm(sqlcode)
, p_source => 'efno_rules.update_row_rule');
--
END;
--
RETURN l_success;
--
END update_row_rule;
PROCEDURE upd_cotr_seq( p_template_id IN NUMBER
, p_cotr_id IN NUMBER
, p_sequence IN VARCHAR2 )
IS
--
l_err_message VARCHAR2(255) := NULL;
l_success BOOLEAN := TRUE;
--
BEGIN
-- Check we have permission to be using this module.
-- Only called from efnow092$ - in turn called from screen efnow050$
IF NOT caco_security.security_check('efnow050$') THEN
RETURN;
END IF;
--
BEGIN
UPDATE contract_template_rules
SET display_sequence = p_sequence
WHERE cotr_id = p_cotr_id;
EXCEPTION
WHEN invalid_number THEN
l_success := FALSE;
l_err_message := caco_utilities.get_module_text(2335);
-- Invalid Number entered. Please try again.
WHEN others THEN
l_success := FALSE;
l_err_message := caco_utilities.get_module_text(2338);
-- Unable to update sequence number. Please contact support
caco_debug.putline('efno_rules.upd_cotr_seq : Error : '||sqlerrm(sqlcode));
-- Write an error and carry on
cout_err.report_and_go( p_exception_number => sqlcode
, p_exception_message => sqlerrm(sqlcode)
, p_source => 'efno_rules.upd_cotr_seq');
--
END;
--
IF l_success THEN
--
COMMIT;
efnow092$.template_rules( p_template_id => p_template_id
, p_success => 'Y' );
--
ELSE
--
efnow092$.template_rules( p_template_id => p_template_id
, p_error => 'Y'
, p_err_msg => l_err_message );
--
END IF;
--
END upd_cotr_seq;
PROCEDURE delete_template_rule( p_template_id IN NUMBER
, p_cotr_id IN NUMBER )
IS
-- Cursor to list all contracts with the given template
CURSOR c_contracts IS
SELECT cont_id
FROM contracts
WHERE cote_id = p_template_id;
--
CURSOR c_cotr_rule IS
SELECT rule_id
FROM contract_template_rules
WHERE cotr_id = p_cotr_id;
--
l_rule_id contract_template_rules.rule_id%TYPE;
l_err_message VARCHAR2(255) := NULL;
l_success BOOLEAN := TRUE;
--
BEGIN
-- Check we have permission to be using this module.
-- Only called from efnow092$ - in turn called from screen efnow050$
IF NOT caco_security.security_check('efnow050$') THEN
RETURN;
END IF;
--
SAVEPOINT before_del_cotr;
--
OPEN c_cotr_rule;
FETCH c_cotr_rule INTO l_rule_id;
CLOSE c_cotr_rule;
--
-- Delete the rule from all contracts with the template
<>
FOR r IN c_contracts LOOP
--
BEGIN
DELETE contract_rules
WHERE NVL(rule_id,0) = l_rule_id
AND cont_id = r.cont_id
AND NVL(inherited,'N') = 'Y';
EXCEPTION
WHEN others THEN
l_success := FALSE;
l_err_message := caco_utilities.get_module_text(2251);
-- Deleting template rule from existing contracts failed. Please contact support
caco_debug.putline('efno_rules.delete_template_rule : Error deleting rule from contracts: '
||sqlerrm(sqlcode));
-- Write an error and carry on
cout_err.report_and_go( p_exception_number => sqlcode
, p_exception_message => sqlerrm(sqlcode)
, p_source => 'efno_rules.delete_template_rule');
--
EXIT contract_loop;
END;
--
END LOOP contract_loop;
--
-- Delete rule from the template
IF l_success THEN
BEGIN
DELETE contract_template_rules
WHERE cotr_id = p_cotr_id
AND cote_id = p_template_id;
EXCEPTION
WHEN others THEN
l_success := FALSE;
l_err_message := caco_utilities.get_module_text(2250);
-- Deleting contract template rule failed. Please contact support
caco_debug.putline('efno_rules.delete_template_rule : Error : '||sqlerrm(sqlcode));
-- Write an error and carry on
cout_err.report_and_go( p_exception_number => sqlcode
, p_exception_message => sqlerrm(sqlcode)
, p_source => 'efno_rules.delete_template_rule');
--
END;
END IF;
--
IF l_success THEN
--
COMMIT;
efnow050$.template_rules( p_template_id => p_template_id
, p_success => 'Y' );
--
ELSE
ROLLBACK TO SAVEPOINT before_del_cotr;
--
efnow050$.template_rules( p_template_id => p_template_id
, p_error => 'Y'
, p_err_msg => l_err_message );
--
END IF;
--
END delete_template_rule;
FUNCTION add_cote_rule_to_cont( p_template_id IN NUMBER
, p_rule_id IN NUMBER
, p_display_sequence IN NUMBER
, p_return_error OUT VARCHAR2 )
RETURN BOOLEAN
IS
-- Cursor to list all contracts with the given template
CURSOR c_contracts IS
SELECT cont_id
FROM contracts
WHERE cote_id = p_template_id;
--
-- Cursor to see if the rule already exists for a contract with this template
CURSOR c_coru_exists( cp_cont_id IN NUMBER
, cp_rule_id IN NUMBER )
IS
SELECT coru_id
FROM contract_rules
WHERE cont_id = cp_cont_id
AND rule_id = cp_rule_id;
--
l_coru_id contract_rules.coru_id%TYPE := 0;
l_success BOOLEAN := TRUE;
--
BEGIN
SAVEPOINT before_add_to_cont;
--
IF NVL(p_rule_id,-1) != -1 THEN
<>
FOR r IN c_contracts LOOP
--
OPEN c_coru_exists( r.cont_id, p_rule_id );
FETCH c_coru_exists INTO l_coru_id;
IF c_coru_exists%FOUND THEN
CLOSE c_coru_exists;
-- Already have this rule - so make it inherited
BEGIN
UPDATE contract_rules
SET inherited = 'Y'
WHERE coru_id = l_coru_id;
EXCEPTION
WHEN others THEN
l_success := FALSE;
p_return_error := caco_utilities.get_module_text(2333);
-- Failed to insert rule. Please contact support
caco_debug.putline('efno_rules.add_cote_rule_to_cont : Error updating existing contract rule: '
||sqlerrm(sqlcode));
-- Write an error and carry on
cout_err.report_and_go( p_exception_number => sqlcode
, p_exception_message => sqlerrm(sqlcode)
, p_source => 'efno_rules.add_cote_rule_to_cont');
--
END;
ELSE
CLOSE c_coru_exists;
-- Need to insert this one
BEGIN
INSERT INTO contract_rules
( coru_id
, display_sequence
, inherited
, cont_id
, coru_type
, rule_id )
VALUES
( coru_seq.NEXTVAL
, NVL(p_display_sequence,10)
, 'Y'
, r.cont_id
, 'ROW'
, p_rule_id );
EXCEPTION
WHEN others THEN
l_success := FALSE;
p_return_error := caco_utilities.get_module_text(2333);
-- Failed to insert rule. Please contact support
caco_debug.putline('efno_rules.add_cote_rule_to_cont : Error inserting rule for existing contract : '
||sqlerrm(sqlcode));
-- Write an error and carry on
cout_err.report_and_go( p_exception_number => sqlcode
, p_exception_message => sqlerrm(sqlcode)
, p_source => 'efno_rules.add_cote_rule_to_cont');
--
END;
END IF;
--
END LOOP contracts_loop;
END IF;
--
IF NOT l_success THEN
ROLLBACK TO SAVEPOINT before_add_to_cont;
END IF;
--
RETURN l_success;
--
END add_cote_rule_to_cont;
PROCEDURE add_template_rule( p_template_id IN NUMBER
, p_rule_id IN NUMBER )
IS
--
-- Cursor for checking if rule already exists for this contract template
CURSOR c_rule IS
SELECT 'X'
FROM contract_template_rules
WHERE cote_id = p_template_id
AND NVL(rule_id,0) = p_rule_id;
--
l_dummy VARCHAR2(1) := 'X';
l_err_message VARCHAR2(255) := NULL;
l_valid_rule BOOLEAN := TRUE;
--
l_dummy_nnpcv_tab efno_confirmations.nnpcv_tab;
l_dummy_nom_data_table nom_validation_table;
l_display_sequence contract_template_rules.display_sequence%TYPE := 0;
--
l_success BOOLEAN := TRUE;
l_duplicate_submission BOOLEAN := FALSE;
--
BEGIN
-- Check we have permission to be using this module.
-- Only called from efnow092$ - in turn called from screen efnow050$
IF NOT caco_security.security_check('efnow050$') THEN
RETURN;
END IF;
--
SAVEPOINT before_ins_cotr;
--
l_dummy_nom_data_table := g_empty_nom_val_table;
--
-- First, test if this contract has the correct parameters to add this rule
--
l_valid_rule := validate_rule( p_rule_id => p_rule_id
, p_rule_type => 'ROW'
, p_parse_only => TRUE
, p_nnpcv_tab => l_dummy_nnpcv_tab
, p_nom_table => l_dummy_nom_data_table
, p_template_id => p_template_id );
--
IF l_valid_rule THEN
--
-- Check to ensure that we dont already have this rule...
-- Could happen if user presses back on the browser screen and refreshes
OPEN c_rule;
FETCH c_rule INTO l_dummy;
IF c_rule%FOUND THEN
l_success := FALSE;
l_duplicate_submission := TRUE;
END IF;
CLOSE c_rule;
--
IF NOT l_duplicate_submission THEN
--
BEGIN
INSERT INTO contract_template_rules
( cotr_id
, display_sequence
, cote_id
, rule_id )
VALUES
( cotr_seq.NEXTVAL
, ( SELECT NVL(MAX(cotr2.display_sequence),0)+10
FROM contract_template_rules cotr2
WHERE cotr2.cote_id = p_template_id )
, p_template_id
, p_rule_id )
RETURNING display_sequence INTO l_display_sequence;
EXCEPTION
WHEN others THEN
l_success := FALSE;
l_err_message := caco_utilities.get_module_text(2333);
-- Failed to insert rule. Please contact support
caco_debug.putline('efno_rules.add_template_rule : Error : '||sqlerrm(sqlcode));
-- Write an error and carry on
cout_err.report_and_go( p_exception_number => sqlcode
, p_exception_message => sqlerrm(sqlcode)
, p_source => 'efno_rules.add_template_rule');
--
END;
--
-- Now we can try to add this rule to every contract with this template
IF l_success THEN
--
l_success := add_cote_rule_to_cont( p_template_id
, p_rule_id
, l_display_sequence
, l_err_message );
--
END IF;
--
END IF; -- Not duplicate submission
--
ELSE
--
l_err_message := caco_utilities.get_module_text(2297);
-- Selected Rule is not valid for this contract template.
l_success := FALSE;
--
END IF;
--
IF l_success THEN
--
COMMIT;
efnow050$.template_rules( p_template_id => p_template_id
, p_success => 'Y' );
--
ELSIF l_duplicate_submission THEN
--
ROLLBACK TO SAVEPOINT before_ins_cotr;
--
efnow050$.template_rules( p_template_id => p_template_id );
--
ELSE
--
ROLLBACK TO SAVEPOINT before_ins_cotr;
--
efnow050$.template_rules( p_template_id => p_template_id
, p_error => 'Y'
, p_err_msg => l_err_message );
--
END IF;
--
END add_template_rule;
PROCEDURE upd_coru_seq( p_contract_id IN NUMBER
, p_coru_id IN NUMBER
, p_sequence IN VARCHAR2 )
IS
--
l_err_message VARCHAR2(255) := NULL;
l_success BOOLEAN := TRUE;
--
BEGIN
-- Check we have permission to be using this module.
-- Only called from efnow092$ - in turn called from screen efnow050$
IF NOT caco_security.security_check('efnow050$') THEN
RETURN;
END IF;
--
BEGIN
UPDATE contract_rules
SET display_sequence = p_sequence
WHERE coru_id = p_coru_id;
EXCEPTION
WHEN invalid_number THEN
l_success := FALSE;
l_err_message := caco_utilities.get_module_text(2335);
-- Invalid Number entered. Please try again.
WHEN others THEN
l_success := FALSE;
l_err_message := caco_utilities.get_module_text(2338);
-- Unable to update sequence number. Please contact support
caco_debug.putline('efno_rules.upd_coru_seq : Error : '||sqlerrm(sqlcode));
-- Write an error and carry on
cout_err.report_and_go( p_exception_number => sqlcode
, p_exception_message => sqlerrm(sqlcode)
, p_source => 'efno_rules.upd_coru_seq');
--
END;
--
IF l_success THEN
--
COMMIT;
efnow092$.contract_rules( p_contract_id => p_contract_id
, p_success => 'Y' );
--
ELSE
--
efnow092$.contract_rules( p_contract_id => p_contract_id
, p_error => 'Y'
, p_err_msg => l_err_message );
--
END IF;
--
END upd_coru_seq;
PROCEDURE delete_contract_rule( p_contract_id IN NUMBER
, p_coru_id IN NUMBER )
IS
--
l_err_message VARCHAR2(255) := NULL;
l_success BOOLEAN := TRUE;
--
BEGIN
-- Check we have permission to be using this module.
-- Only called from efnow092$ - in turn called from screen efnow050$
IF NOT caco_security.security_check('efnow050$') THEN
RETURN;
END IF;
--
BEGIN
DELETE contract_rules
WHERE coru_id = p_coru_id
AND cont_id = p_contract_id;
EXCEPTION
WHEN others THEN
l_success := FALSE;
l_err_message := caco_utilities.get_module_text(2249);
-- Deleting contract rule failed. Please contact support
caco_debug.putline('efno_rules.delete_contract_rule : Error : '||sqlerrm(sqlcode));
-- Write an error and carry on
cout_err.report_and_go( p_exception_number => sqlcode
, p_exception_message => sqlerrm(sqlcode)
, p_source => 'efno_rules.delete_contract_rule');
--
END;
--
IF l_success THEN
--
COMMIT;
efnow050$.contract_rules( p_contract_id => p_contract_id
, p_success => 'Y' );
--
ELSE
--
efnow050$.contract_rules( p_contract_id => p_contract_id
, p_error => 'Y'
, p_err_msg => l_err_message );
--
END IF;
--
END delete_contract_rule;
PROCEDURE add_contract_row_rule( p_contract_id IN NUMBER
, p_rule_id IN NUMBER )
IS
-- Cursor for checking if rule already exists.
CURSOR c_rule IS
SELECT 'X'
FROM contract_rules
WHERE cont_id = p_contract_id
AND NVL(rule_id,0) = p_rule_id;
--
l_dummy VARCHAR2(1) := 'X';
l_err_message VARCHAR2(255) := NULL;
l_valid_rule BOOLEAN := TRUE;
l_dummy_nnpcv_tab efno_confirmations.nnpcv_tab;
l_dummy_nom_data_table nom_validation_table;
l_success BOOLEAN := TRUE;
l_duplicate_submission BOOLEAN := FALSE;
--
BEGIN
-- Check we have permission to be using this module.
-- Only called from efnow092$ - in turn called from screen efnow050$
IF NOT caco_security.security_check('efnow050$') THEN
RETURN;
END IF;
--
l_dummy_nom_data_table := g_empty_nom_val_table;
--
-- First, test if this contract has the correct parameters to add this rule
--
l_valid_rule := validate_rule( p_rule_id => p_rule_id
, p_rule_type => 'ROW'
, p_parse_only => TRUE
, p_nnpcv_tab => l_dummy_nnpcv_tab
, p_nom_table => l_dummy_nom_data_table
, p_contract_id => p_contract_id );
--
IF l_valid_rule THEN
--
-- Check to ensure that we dont already have this rule...
-- Could happen if user presses back on the browser screen and refreshes
OPEN c_rule;
FETCH c_rule INTO l_dummy;
IF c_rule%FOUND THEN
l_success := FALSE;
l_duplicate_submission := TRUE;
END IF;
CLOSE c_rule;
--
IF NOT l_duplicate_submission THEN
BEGIN
INSERT INTO contract_rules
( coru_id
, display_sequence
, inherited
, cont_id
, coru_type
, rule_id )
VALUES
( coru_seq.NEXTVAL
, ( SELECT NVL(MAX(coru2.display_sequence),0)+10
FROM contract_rules coru2
WHERE coru2.cont_id = p_contract_id )
, 'N'
, p_contract_id
, 'ROW'
, p_rule_id );
EXCEPTION
WHEN others THEN
l_success := FALSE;
l_err_message := caco_utilities.get_module_text(2333);
-- Failed to insert rule. Please contact support
caco_debug.putline('efno_rules.add_contract_row_rule : Error : '||sqlerrm(sqlcode));
-- Write an error and carry on
cout_err.report_and_go( p_exception_number => sqlcode
, p_exception_message => sqlerrm(sqlcode)
, p_source => 'efno_rules.add_contract_row_rule');
--
END;
END IF;
--
ELSE
--
l_err_message := caco_utilities.get_module_text(2298);
-- Selected Rule is not valid for this contract.
l_success := FALSE;
--
END IF;
--
IF l_success THEN
--
COMMIT;
efnow050$.contract_rules( p_contract_id => p_contract_id
, p_success => 'Y' );
--
ELSIF l_duplicate_submission THEN
--
efnow050$.contract_rules( p_contract_id => p_contract_id );
--
ELSE
--
efnow050$.contract_rules( p_contract_id => p_contract_id
, p_error => 'Y'
, p_err_msg => l_err_message );
--
END IF;
--
END add_contract_row_rule;
/**
-- PROCEDURE insert_or_update_rule
-- As it says on the tin
-- validates the data stored passed and then inserts new rule or updates existing one
--
-- %param p_ins_or_upd INSERT or UPDATE
-- %param p_template_id Unique Identifier of a Contract Template
-- %param p_contract_id Unique Identifier of a Contract
-- %param p_rule_type Rule type - ROW or SHEET
-- %param p_coru_id Unique identifier of the SHEET based rule (optional)
-- %param p_rule_id Unique identifier of the ROW based rule (optional)
-- %param p_rule_name Descriptive name of the rule
-- %param p_left_side The text of the rule to the left hand side of the relation
-- %param p_right_side The text of the rule to the right hand side of the relation
-- %param p_rule_relation <, <=, >, >=, =, !=
-- %param p_err_message_hu Error message to display if values fail this rule
-- %param p_err_message_en Error message in English
*/
PROCEDURE insert_or_update_rule( p_ins_or_upd IN VARCHAR2 DEFAULT NULL
, p_template_id IN NUMBER DEFAULT NULL
, p_contract_id IN NUMBER DEFAULT NULL
, p_coru_id IN NUMBER DEFAULT NULL
, p_rule_id IN NUMBER DEFAULT NULL
, p_rule_name IN VARCHAR2 DEFAULT NULL
, p_rule_type IN VARCHAR2 DEFAULT NULL
, p_err_message_hu IN VARCHAR2 DEFAULT NULL
, p_err_message_en IN VARCHAR2 DEFAULT NULL
, p_left_side IN VARCHAR2 DEFAULT NULL
, p_rule_relation IN VARCHAR2 DEFAULT NULL
, p_right_side IN VARCHAR2 DEFAULT NULL )
IS
--
CURSOR c_rule_name( cp_name IN VARCHAR2
, cp_rule IN NUMBER
, cp_coru IN NUMBER )
IS
SELECT 'X'
FROM rules
WHERE UPPER(rule_name) = UPPER(cp_name)
AND rule_id != cp_rule
UNION ALL
SELECT 'X'
FROM contract_rules
WHERE NVL(UPPER(rule_name),'&^%"?(') = UPPER(cp_name)
AND coru_id != cp_coru;
--
l_new_rule_id NUMBER := NULL;
l_new_coru_id NUMBER := NULL;
--
l_error_message VARCHAR2(250) := NULL;
l_display_sequence contract_rules.display_sequence%TYPE;
--
l_dummy_char VARCHAR2(1);
l_dummy_select VARCHAR2(1);
l_dummy_from VARCHAR2(1);
l_dummy_where VARCHAR2(1);
l_dummy_nnpcv_tab efno_confirmations.nnpcv_tab;
l_return_error VARCHAR2(255) := NULL;
--
left_side_valid BOOLEAN := FALSE;
right_side_valid BOOLEAN := FALSE;
--
p_item_name_array owa_util.vc_arr;
p_item_value_array owa_util.vc_arr;
--
l_success BOOLEAN := TRUE; -- Used to track how well we are doing in this code..
--
BEGIN
caco_debug.putline('SP: efno_rules.insert_or_update_rule START');
-- Check we have permission to be using this module.
-- Only called from efnow093$ - in turn called from screen efnow080$
IF NOT caco_security.security_check('efnow080$') THEN
RETURN;
END IF;
--
-- Check that the correct information has been passed from the screen
-- Pop up a warning message if details have not been received / are invalid
-- Remember to make this multilingual....
--
IF p_rule_name IS NULL
OR LENGTH(p_rule_name) > 50
THEN
-- Need a rule name - and one within the column limits
l_success := FALSE;
--
-- Popup message to alert User to error
l_error_message := caco_utilities.get_module_text(2208);
-- A valid Rule Name is required. Maximum length 50 characters
--
ELSIF ( p_err_message_hu IS NULL
OR LENGTH(p_err_message_hu) > 250 )
THEN
--
l_success := FALSE;
--
-- Popup message to alert User to error
l_error_message := caco_utilities.get_module_text(2263);
-- Hungarian error message must be present with a maximum length of 250 characters
--
ELSIF p_err_message_en IS NULL
OR LENGTH(p_err_message_en) > 250
THEN
--
l_success := FALSE;
--
-- Popup message to alert User to error
l_error_message := caco_utilities.get_module_text(2256);
-- English error message must be present with a maximum length of 250 characters
--
ELSIF p_left_side IS NULL
OR LENGTH(p_left_side) > 4000
THEN
--
l_success := FALSE;
--
-- Popup message to alert User to error
l_error_message := caco_utilities.get_module_text(2305);
-- The left side of the rule must be present with a maximum length of 4000 characters
--
ELSIF p_right_side IS NULL
OR LENGTH(p_right_side) > 4000
THEN
--
l_success := FALSE;
--
-- Popup message to alert User to error
l_error_message := caco_utilities.get_module_text(2306);
-- The right side of the rule must be present with a maximum length of 4000 characters
--
END IF;
--
--
IF l_success THEN
-- Check that the rule name is not a duplicate (exclude current rule for update)
--
OPEN c_rule_name( p_rule_name
, NVL(p_rule_id,0)
, NVL(p_coru_id,0) );
FETCH c_rule_name INTO l_dummy_char;
IF c_rule_name%FOUND THEN
-- Rule name already used. Cant have a duplicate
l_success := FALSE;
--
-- Return Error message - Duplicate RULE_NAME
l_error_message := caco_utilities.get_module_text(2254);
-- Duplicate Rule Name encountered. Please change the Rule Name and retry
END IF;
CLOSE c_rule_name;
--
END IF;
--
--
IF l_success THEN
-- Soldier on to validate the given rule
IF ( p_template_id IS NULL OR p_template_id = 0 )
AND ( p_contract_id IS NULL OR p_contract_id = 0 )
THEN
-- Standalone rule - MUST be a ROW type rule
IF p_rule_type = 'ROW' THEN
--
left_side_valid := rule_text( p_text => p_left_side
, p_rule_type => p_rule_type
, p_select => l_dummy_select
, p_from => l_dummy_from
, p_where => l_dummy_where
, p_nnpcv_tab => l_dummy_nnpcv_tab
, p_parse_only => TRUE
, p_return_error => l_return_error );
--
right_side_valid := rule_text( p_text => p_right_side
, p_rule_type => p_rule_type
, p_select => l_dummy_select
, p_from => l_dummy_from
, p_where => l_dummy_where
, p_nnpcv_tab => l_dummy_nnpcv_tab
, p_parse_only => TRUE
, p_return_error => l_return_error );
--
ELSE
-- Not valid to have a SHEET based rule that isn't attached to a contract
l_success := FALSE;
--
-- Popup error message - "Invalid Rule Type specified"
l_error_message := caco_utilities.get_module_text(2269);
-- Invalid Rule Type specified. Valid values are ROW and SHEET
--
END IF;
--
ELSIF p_template_id IS NOT NULL
AND p_template_id > 0
AND ( p_contract_id IS NULL OR p_contract_id = 0 )
THEN
-- Template based rule - must also be a ROW type rule
IF p_rule_type = 'ROW' THEN
--
left_side_valid := rule_text( p_text => p_left_side
, p_rule_type => p_rule_type
, p_select => l_dummy_select
, p_from => l_dummy_from
, p_where => l_dummy_where
, p_nnpcv_tab => l_dummy_nnpcv_tab
, p_template_id => p_template_id
, p_parse_only => TRUE
, p_return_error => l_return_error );
--
right_side_valid := rule_text( p_text => p_right_side
, p_rule_type => p_rule_type
, p_select => l_dummy_select
, p_from => l_dummy_from
, p_where => l_dummy_where
, p_nnpcv_tab => l_dummy_nnpcv_tab
, p_template_id => p_template_id
, p_parse_only => TRUE
, p_return_error => l_return_error );
--
ELSE
-- Not valid to have a SHEET based rule that isn't attached to a contract
l_success := FALSE;
--
-- Popup error message - "Invalid Rule Type specified"
l_error_message := caco_utilities.get_module_text(2268);
-- Invalid Rule Type specified. Valid value is ROW
--
END IF;
--
ELSIF p_contract_id IS NOT NULL
AND p_contract_id > 0
AND ( p_template_id IS NULL OR p_template_id = 0 )
THEN
-- Contract based rule
--
caco_debug.putline('SP: efno_rules.insert_or_update_rule 010');
left_side_valid := rule_text( p_text => p_left_side
, p_rule_type => p_rule_type
, p_select => l_dummy_select
, p_from => l_dummy_from
, p_where => l_dummy_where
, p_nnpcv_tab => l_dummy_nnpcv_tab
, p_contract_id => p_contract_id
, p_parse_only => TRUE
, p_return_error => l_return_error );
--
caco_debug.putline('SP: efno_rules.insert_or_update_rule 020');
right_side_valid := rule_text( p_text => p_right_side
, p_rule_type => p_rule_type
, p_select => l_dummy_select
, p_from => l_dummy_from
, p_where => l_dummy_where
, p_nnpcv_tab => l_dummy_nnpcv_tab
, p_contract_id => p_contract_id
, p_parse_only => TRUE
, p_return_error => l_return_error );
--
END IF;
--
--
IF l_success THEN
-- Check that the left and right sides validated correctly
--
IF left_side_valid AND right_side_valid THEN
--
-- Need to insert or update
-- Deal with the most complicated first - contract rules
IF p_contract_id IS NOT NULL
AND p_contract_id > 0
THEN
-- Check the rule type
IF p_rule_type = 'SHEET' THEN
--
IF p_ins_or_upd = 'INSERT' THEN
--
-- Just Insert the data into CONTRACT_RULES
BEGIN
INSERT INTO contract_rules
( coru_id
, display_sequence
, inherited
, cont_id
, coru_type
, rule_name
, left_side
, rule_relation
, right_side
, error_message_hu
, error_message_en )
VALUES
( coru_seq.nextval
, ( SELECT NVL(MAX(r2.display_sequence),0) + 10
FROM contract_rules r2
WHERE r2.cont_id = p_contract_id )
, 'N'
, p_contract_id
, 'SHEET'
, p_rule_name
, p_left_side
, p_rule_relation
, p_right_side
, p_err_message_hu
, p_err_message_en )
RETURNING coru_id INTO l_new_coru_id;
--
EXCEPTION
WHEN others THEN
l_success := FALSE;
--
-- Popup Error message
l_error_message := caco_utilities.get_module_text(2330);
-- An unexpected error has occurred. Please contact support
-- Write an error and carry on
cout_err.report_and_go( p_exception_number => sqlcode
, p_exception_message => sqlerrm(sqlcode)
, p_source => 'efno_rules.insert_or_update_rule');
--
END;
ELSE
-- Update SHEET rule
BEGIN
UPDATE contract_rules
SET rule_name = p_rule_name
, left_side = p_left_side
, rule_relation = p_rule_relation
, right_side = p_right_side
, error_message_hu = p_err_message_hu
, error_message_en = p_err_message_en
WHERE coru_id = p_coru_id;
--
EXCEPTION
WHEN others THEN
l_success := FALSE;
--
-- Popup Error message
l_error_message := caco_utilities.get_module_text(2330);
-- An unexpected error has occurred. Please contact support
caco_debug.putline('efno_rules.insert_or_update_rule : '||sqlerrm(sqlcode));
-- Write an error and carry on
cout_err.report_and_go( p_exception_number => sqlcode
, p_exception_message => sqlerrm(sqlcode)
, p_source => 'efno_rules.insert_or_update_rule');
--
END;
--
END IF; -- Insert or update SHEET
--
ELSE
-- ROW rule
--
IF p_ins_or_upd = 'INSERT' THEN
--
l_success := insert_row_rule( l_new_rule_id
, p_rule_name
, p_left_side
, p_rule_relation
, p_right_side
, p_err_message_hu
, p_err_message_en
, l_error_message );
--
IF l_success THEN
-- Just Insert the data into CONTRACT_RULES
BEGIN
INSERT INTO contract_rules
( coru_id
, display_sequence
, inherited
, cont_id
, coru_type
, rule_id )
VALUES
( coru_seq.nextval
, ( SELECT NVL(MAX(r2.display_sequence),0) + 10
FROM contract_rules r2
WHERE r2.cont_id = p_contract_id )
, 'N'
, p_contract_id
, 'ROW'
, l_new_rule_id );
--
EXCEPTION
WHEN others THEN
l_success := FALSE;
--
-- Popup Error message
l_error_message := caco_utilities.get_module_text(2330);
-- An unexpected error has occurred. Please contact support
caco_debug.putline('efno_rules.insert_or_update_rule : '||sqlerrm(sqlcode));
-- Write an error and carry on
cout_err.report_and_go( p_exception_number => sqlcode
, p_exception_message => sqlerrm(sqlcode)
, p_source => 'efno_rules.insert_or_update_rule');
--
END;
END IF;
--
ELSE
-- Update contract ROW rule
l_success := update_row_rule( p_rule_id
, p_rule_name
, p_left_side
, p_rule_relation
, p_right_side
, p_err_message_hu
, p_err_message_en
, l_error_message );
--
END IF; -- Insert or update ROW contract rule
--
END IF;
--
-- Now build the Rule screen URL as a query with the appropriate created values
IF l_success THEN
--
p_item_name_array(2) := 'P_CATEGORY';
p_item_value_array(2) := 'CONTRACT';
p_item_name_array(3) := 'P_CONTRACT_ID';
p_item_value_array(3) := p_contract_id;
--
IF p_rule_type = 'SHEET' THEN
p_item_name_array(4) := 'P_CORU_ID';
p_item_value_array(4) := NVL(l_new_coru_id, p_coru_id);
ELSE
p_item_name_array(4) := 'P_RULE_ID';
p_item_value_array(4) := NVL(l_new_rule_id, p_rule_id);
END IF;
--
END IF;
--
ELSIF p_template_id IS NOT NULL
AND p_template_id > 0
THEN
--
IF p_ins_or_upd = 'INSERT' THEN
--
-- First INSERT the data into the RULES table returning the new RULE_ID
-- New ROW rule for a specific template
l_success := insert_row_rule( l_new_rule_id
, p_rule_name
, p_left_side
, p_rule_relation
, p_right_side
, p_err_message_hu
, p_err_message_en
, l_error_message );
--
IF l_success THEN
-- Insert a link record into CONTRACT_TEMPLATE_RULES
BEGIN
INSERT INTO contract_template_rules
( cotr_id
, display_sequence
, cote_id
, rule_id )
VALUES
( cotr_seq.nextval
, ( SELECT NVL(MAX(t2.display_sequence),0) + 10
FROM contract_template_rules t2
WHERE t2.cote_id = p_template_id )
, p_template_id
, l_new_rule_id )
RETURNING display_sequence INTO l_display_sequence;
--
EXCEPTION
WHEN others THEN
l_success := FALSE;
--
-- Popup Error message
l_error_message := caco_utilities.get_module_text(2330);
-- An unexpected error has occurred. Please contact support
caco_debug.putline('efno_rules.insert_or_update_rule : '||sqlerrm(sqlcode));
-- Write an error and carry on
cout_err.report_and_go( p_exception_number => sqlcode
, p_exception_message => sqlerrm(sqlcode)
, p_source => 'efno_rules.insert_or_update_rule');
--
END;
END IF;
--
ELSE
-- Update Template ROW rule
l_success := update_row_rule( p_rule_id
, p_rule_name
, p_left_side
, p_rule_relation
, p_right_side
, p_err_message_hu
, p_err_message_en
, l_error_message );
--
END IF; -- Insert or Update Template Rule
--
-- Now build the Rule screen URL as a query with the appropriate created values
IF l_success THEN
--
p_item_name_array(2) := 'P_CATEGORY';
p_item_value_array(2) := 'TEMPLATE';
p_item_name_array(3) := 'P_TEMPLATE_ID';
p_item_value_array(3) := p_template_id;
p_item_name_array(4) := 'P_RULE_ID';
p_item_value_array(4) := NVL(l_new_rule_id, p_rule_id);
--
END IF;
--
ELSE
--
IF p_ins_or_upd = 'INSERT' THEN
--
-- New ROW rule not attached to a contract or a template
l_success := insert_row_rule( l_new_rule_id
, p_rule_name
, p_left_side
, p_rule_relation
, p_right_side
, p_err_message_hu
, p_err_message_en
, l_error_message );
--
ELSE
-- Update standalone ROW rule
l_success := update_row_rule( p_rule_id
, p_rule_name
, p_left_side
, p_rule_relation
, p_right_side
, p_err_message_hu
, p_err_message_en
, l_error_message );
--
END IF; -- Insert or Update standalone Rule
--
-- Now build the Rule screen URL as a query with the appropriate created values
IF l_success THEN
--
p_item_name_array(2) := 'P_RULE_ID';
p_item_value_array(2) := NVL(l_new_rule_id, p_rule_id);
--
END IF;
--
END IF;
--
ELSIF left_side_valid THEN
--
-- Right side is invalid - Popup error message
--
l_success := FALSE;
l_error_message := caco_utilities.get_module_text(2296);
-- Rule right side is invalid
--
ELSIF right_side_valid THEN
--
-- Left side is invalid - Popup error message
--
l_success := FALSE;
l_error_message := caco_utilities.get_module_text(2295);
-- Rule left side is invalid
--
ELSE
--
-- both sides invalid - Popup error message
--
l_success := FALSE;
l_error_message := caco_utilities.get_module_text(2226);
-- Both sides of the rule are invalid
--
END IF;
--
END IF;
--
END IF; -- IF l_success
--
IF l_success
AND p_template_id IS NOT NULL
AND p_template_id > 0
THEN
-- need to add the rule to all the associated contracts too.
l_success := add_cote_rule_to_cont( p_template_id
, l_new_rule_id
, l_display_sequence
, l_error_message );
END IF;
--
-- If all is still well, call the RULE screen with the values
IF l_success THEN
-- Set the success message as the first item
p_item_name_array(1) := 'P_SUCCESS';
p_item_value_array(1) := 'Y';
--
efnow080$.rule_startup( p_item_name_array
, p_item_value_array );
--
ELSE
-- Clear the name/value pair arrays
p_item_name_array.DELETE;
p_item_value_array.DELETE;
--
-- Send back the originally submitted values and the appropriate warning message
--
p_item_name_array(1) := 'P_ERROR';
p_item_value_array(1) := 'Y';
p_item_name_array(2) := 'P_ERR_MSG';
p_item_value_array(2) := l_error_message;
p_item_name_array(3) := 'P_INS_OR_UPD';
p_item_value_array(3) := p_ins_or_upd;
p_item_name_array(4) := 'P_TEMPLATE_ID';
p_item_value_array(4) := p_template_id;
p_item_name_array(5) := 'P_CONTRACT_ID';
p_item_value_array(5) := p_contract_id;
p_item_name_array(6) := 'P_CORU_ID';
p_item_value_array(6) := p_coru_id;
p_item_name_array(7) := 'P_RULE_ID';
p_item_value_array(7) := p_rule_id;
p_item_name_array(8) := 'P_RULE_NAME';
p_item_value_array(8) := p_rule_name;
p_item_name_array(9) := 'P_RULE_TYPE';
p_item_value_array(9) := p_rule_type;
p_item_name_array(10) := 'P_ERR_MESSAGE_HU';
p_item_value_array(10) := p_err_message_hu;
p_item_name_array(11) := 'P_ERR_MESSAGE_EN';
p_item_value_array(11) := p_err_message_en;
p_item_name_array(12) := 'P_LEFT_SIDE';
p_item_value_array(12) := p_left_side;
p_item_name_array(13) := 'P_RULE_RELATION';
p_item_value_array(13) := p_rule_relation;
p_item_name_array(14) := 'P_RIGHT_SIDE';
p_item_value_array(14) := p_right_side;
--
efnow080$.rule_startup( p_item_name_array
, p_item_value_array );
--
END IF;
--
END insert_or_update_rule;
FUNCTION get_nepg_value(p_nomi_id IN NUMBER,
p_nepg_id IN NUMBER,
p_coca_id IN NUMBER,
p_conf_id IN NUMBER,
p_gas_day IN nom_net_point_cat_vals.gas_day%TYPE)
RETURN NUMBER IS
--
CURSOR cu_nepg_nnpcv IS
SELECT NVL(SUM(nnpcv.value),0)
FROM nominations nomi,
nom_net_point_cat_vals nnpcv,
cont_network_points conp,
contract_categories coca,
network_point_groups nepg,
network_point_mappings nepm
WHERE nomi.nomi_id = p_nomi_id
AND nomi.nomi_id = nnpcv.nomi_id
AND coca.coca_id = p_coca_id
AND nepg.nepg_id = p_nepg_id
AND nepg.nepg_id = nepm.nepg_id
AND nepm.nepo_id = conp.nepo_id
AND nnpcv.coca_id = coca.coca_id
AND nnpcv.conp_id = conp.conp_id
AND nnpcv.gas_day = p_gas_day;
--
CURSOR cu_nepg_cnpcv IS
SELECT NVL(SUM(cnpcv.value),0)
FROM conf_net_point_cat_vals cnpcv,
network_point_groups nepg,
network_point_mappings nepm,
cont_network_points conp
WHERE cnpcv.conf_id = p_conf_id
AND (cnpcv.nomi_id = p_nomi_id OR p_nomi_id = 0)
AND cnpcv.coca_id = p_coca_id
AND nepg.nepg_id = p_nepg_id
AND nepg.nepg_id = nepm.nepg_id
AND nepm.nepo_id = conp.nepo_id
AND cnpcv.conp_id = conp.conp_id
AND cnpcv.gas_day = p_gas_day;
--
l_value NUMBER := 0;
--
BEGIN
--
IF p_conf_id = 0 THEN
--caco_debug.putline('get_nepg_value 010: cu_nepg_nnpcv');
OPEN cu_nepg_nnpcv;
FETCH cu_nepg_nnpcv INTO l_value;
CLOSE cu_nepg_nnpcv;
ELSE
--caco_debug.putline('get_nepg_value 020: cu_nepg_cnpcv');
OPEN cu_nepg_cnpcv;
FETCH cu_nepg_cnpcv INTO l_value;
CLOSE cu_nepg_cnpcv;
END IF;
--
RETURN l_value;
--
END;
FUNCTION get_npgp_value(p_cont_id IN NUMBER,
p_nepg_id IN NUMBER)
RETURN NUMBER IS
--
CURSOR cu_npgp IS
SELECT NVL(npgp.value,0)
FROM network_point_gp_params npgp
WHERE npgp.cont_id = p_cont_id
AND npgp.nepg_id = p_nepg_id;
--
l_value NUMBER := 0;
--
BEGIN
--
OPEN cu_npgp;
FETCH cu_npgp INTO l_value;
CLOSE cu_npgp;
--
RETURN l_value;
--
END;
/**
-- FUNCTION about --
-- Returns the version number and VSS header for this package
--
-- %return The version number and VSS header for this package
*/
FUNCTION about RETURN VARCHAR2 IS
BEGIN
RETURN ( g_revision || CHR(10) || g_header );
END about;
BEGIN
-- Package intitialisation
NULL;
END efno_rules;
/