CREATE OR REPLACE PACKAGE BODY efno_confirmations IS -- g_auto_gen BOOLEAN := FALSE; -- PROCEDURE output_nnpcv_tab (p_nnpcv_tab IN nnpcv_tab) IS BEGIN caco_debug.putline('------SP_CONF: output_nnpcv_tab 001------'); FOR i IN 1..p_nnpcv_tab.COUNT LOOP caco_debug.putline('nnpcv_tab '||i||' nnpcv_id = '||p_nnpcv_tab(i).nnpcv_id); caco_debug.putline('nnpcv_tab '||i||' coca_id = '||p_nnpcv_tab(i).coca_id); caco_debug.putline('nnpcv_tab '||i||' conp_id = '||p_nnpcv_tab(i).conp_id); caco_debug.putline('nnpcv_tab '||i||' coru_id = '||p_nnpcv_tab(i).coru_id); caco_debug.putline('nnpcv_tab '||i||' value = '||p_nnpcv_tab(i).value); caco_debug.putline('nnpcv_tab '||i||' nomi_id = '||p_nnpcv_tab(i).nomi_id); caco_debug.putline('nnpcv_tab '||i||' nomi_received = '||p_nnpcv_tab(i).nomi_received); caco_debug.putline('nnpcv_tab '||i||' defaulted = '||p_nnpcv_tab(i).defaulted); caco_debug.putline('nnpcv_tab '||i||' missing = '||p_nnpcv_tab(i).missing); caco_debug.putline('nnpcv_tab '||i||' gas_day = '||p_nnpcv_tab(i).gas_day); caco_debug.putline('nnpcv_tab '||i||' in_error = '||sys.diutil.bool_to_int(p_nnpcv_tab(i).in_error)); END LOOP; caco_debug.putline('------SP_CONF: output_nnpcv_tab 999------'); END output_nnpcv_tab; -- PROCEDURE output_nnpcv_rec (p_nnpcv_rec IN nnpcv_rec) IS BEGIN caco_debug.putline('------SP_CONF: output_nnpcv_rec 001------'); caco_debug.putline('nnpcv_rec nnpcv_id = '||p_nnpcv_rec.nnpcv_id); caco_debug.putline('nnpcv_tab coca_id = '||p_nnpcv_rec.coca_id); caco_debug.putline('nnpcv_tab conp_id = '||p_nnpcv_rec.conp_id); caco_debug.putline('nnpcv_tab coru_id = '||p_nnpcv_rec.coru_id); caco_debug.putline('nnpcv_tab value = '||p_nnpcv_rec.value); caco_debug.putline('nnpcv_tab nomi_id = '||p_nnpcv_rec.nomi_id); caco_debug.putline('nnpcv_tab nomi_received = '||p_nnpcv_rec.nomi_received); caco_debug.putline('nnpcv_tab defaulted = '||p_nnpcv_rec.defaulted); caco_debug.putline('nnpcv_tab missing = '||p_nnpcv_rec.missing); caco_debug.putline('nnpcv_tab gas_day = '||p_nnpcv_rec.gas_day); caco_debug.putline('nnpcv_tab in_error = '||sys.diutil.bool_to_int(p_nnpcv_rec.in_error)); caco_debug.putline('------SP_CONF: output_nnpcv_rec 999------'); END output_nnpcv_rec; /** -- PROCEDURE upd_conf_timestamp -- Autonomous Transaction -- Updates the confirmation timestamp with the given date -- Used by the timestamping functions when a RETRY has been required -- -- %param p_conf_id Unique Identifier of the confirmation to be updated -- %param p_timestamp Successful timestamp information -- */ PROCEDURE upd_conf_timestamp( p_conf_id IN confirmations.conf_id%TYPE , p_timestamp IN DATE ) IS PRAGMA AUTONOMOUS_TRANSACTION; BEGIN -- --caco_debug.debug_on('Enter upd_conf_timestamp'); -- Check we have permission to be using this module. IF NOT g_auto_gen THEN -- IF NOT caco_security.security_check('efnow095$') THEN RETURN; END IF; -- END IF; -- BEGIN -- UPDATE confirmations SET confirmation_sent = p_timestamp , approved = 'Y' WHERE conf_id = p_conf_id; -- COMMIT; -- --caco_debug.debug_on('Exit upd_conf_timestamp'); -- EXCEPTION WHEN others THEN -- Need to log an error and email system support... NULL; END; -- END upd_conf_timestamp; -- -- FUNCTION get_interrupted_value (p_conp_id IN NUMBER, p_coca_id IN NUMBER, p_gas_day IN DATE) RETURN NUMBER IS -- CURSOR c_int IS SELECT icv.interrupted_value FROM int_conp_coca_vals icv WHERE icv.coca_id = p_coca_id AND icv.conp_id = p_conp_id AND icv.send_to_customer = 'Y' AND EXISTS ( SELECT 'x' FROM interruptions int WHERE int.int_id = icv.int_id AND p_gas_day >= int.gas_day_start AND (p_gas_day <= int.gas_day_end OR int.gas_day_end IS NULL)); -- l_interrupted_value NUMBER := NULL; -- BEGIN -- OPEN c_int; FETCH c_int INTO l_interrupted_value; IF c_int%NOTFOUND THEN l_interrupted_value := NULL; END IF; CLOSE c_int; -- RETURN l_interrupted_value; -- END get_interrupted_value; -- -- FUNCTION ins_lookback_cnpcv_vals( p_conf_id IN confirmations.conf_id%TYPE , p_nnpcv_tab IN OUT nnpcv_tab , p_nomi_id IN nominations.nomi_id%TYPE , p_nomi_date IN nominations.created_on%TYPE , p_return_error OUT VARCHAR2 ) RETURN BOOLEAN IS PRAGMA AUTONOMOUS_TRANSACTION; -- -- Cursor to get the value for the given previous nomination and CONP COCA pair from the nnpcv_tab CURSOR c_nnpcv( cp_conp_id IN NUMBER , cp_coca_id IN NUMBER ) IS SELECT nnpcv1.nnpcv_id nnpcv_id , nnpcv1.value value , nnpcv1.gas_day gas_day , cnp2.nepo_id nepo_id FROM nom_net_point_cat_vals nnpcv1 ,cont_network_points cnp1 ,cont_network_points cnp2 ,contract_categories cc1 ,contract_categories cc2 WHERE nnpcv1.nomi_id = p_nomi_id AND cc1.cate_id = cc2.cate_id AND cc1.coca_id = cp_coca_id AND cc2.coca_id = nnpcv1.coca_id AND cnp1.nepo_id = cnp2.nepo_id AND cnp1.conp_id = cp_conp_id AND cnp2.conp_id = nnpcv1.conp_id AND nnpcv1.gas_day = ( SELECT MAX( nnpcv2.gas_day ) FROM nom_net_point_cat_vals nnpcv2 WHERE nnpcv2.nomi_id = p_nomi_id ); -- l_nnpcv_id nom_net_point_cat_vals.nnpcv_id%TYPE; l_value nom_net_point_cat_vals.value%TYPE; l_int_value nom_net_point_cat_vals.value%TYPE; l_lb_value nom_net_point_cat_vals.value%TYPE; l_gas_day nom_net_point_cat_vals.gas_day%TYPE; l_success BOOLEAN := TRUE; l_nepo_id network_points.nepo_id%TYPE; l_interrupted conf_net_point_cat_vals.interrupted%TYPE; -- BEGIN caco_debug.putline('SP_CONF: ins_lookback_cnpcv_vals 001'); -- caco_debug.putline('Enter ins_lookback_cnpcv_vals with '||NVL(p_nnpcv_tab.COUNT,0)||' elements'); -- SAVEPOINT before_ins_cnpcv; -- -- Loop through the nnpcv tab and update CNPCV with the nom values IF NVL(p_nnpcv_tab.COUNT,0) > 0 THEN -- <> FOR i IN 1..p_nnpcv_tab.COUNT LOOP -- check if there is an interruption active l_int_value := get_interrupted_value( p_nnpcv_tab(i).conp_id , p_nnpcv_tab(i).coca_id , p_nnpcv_tab(i).gas_day ); IF l_int_value IS NOT NULL THEN caco_debug.putline('l_int_value: '||l_int_value); END IF; -- -- Get the value for the specific conp and coca for the given nomination -- for the latest gas day in the valid nomination -- OPEN c_nnpcv( p_nnpcv_tab(i).conp_id , p_nnpcv_tab(i).coca_id ); FETCH c_nnpcv INTO l_nnpcv_id, l_lb_value, l_gas_day, l_nepo_id; IF c_nnpcv%NOTFOUND THEN l_success := FALSE; END IF; CLOSE c_nnpcv; -- Compare the lookback value and the interrupted value and go with the lowest value IF l_int_value IS NULL THEN l_interrupted := 'N'; ELSE l_interrupted := 'Y'; END IF; -- l_value := l_lb_value; -- IF l_success THEN -- caco_debug.putline('Inserting values'); -- --output_nnpcv_rec(p_nnpcv_tab(i)); BEGIN INSERT INTO conf_net_point_cat_vals ( nnpcv_id , conf_id , nomi_id , value , gas_day , conp_id , coca_id , valid , last_nomi_id , last_nom_received , last_gas_day , defaulted , interrupted ) VALUES ( l_nnpcv_id , p_conf_id , p_nomi_id , l_value , p_nnpcv_tab(i).gas_day , p_nnpcv_tab(i).conp_id , p_nnpcv_tab(i).coca_id , 'Y' , p_nomi_id , p_nomi_date , l_gas_day , 'N' , l_interrupted ); -- EXCEPTION WHEN dup_val_on_index THEN NULL; WHEN others THEN ROLLBACK TO SAVEPOINT before_ins_cnpcv; l_success := FALSE; p_return_error := caco_utilities.get_module_text(2311); -- Unable to force confirm invalid nomination. Please contact support caco_debug.putline('efno_confirmations.ins_lookback_cnpcv_vals:' ||' Failed to insert lookback confirmation value: ' ||' CONP_ID : '||p_nnpcv_tab(i).conp_id||' and ' ||' COCA_ID : '||p_nnpcv_tab(i).coca_id||' on ' ||TO_CHAR(p_nnpcv_tab(i).gas_day,'DD-MON-YYYY') ||chr(10)||'SQLERRM : '||sqlerrm(sqlcode) ); -- -- Write an error and carry on -- cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => ' Failed to insert lookback confirmation value: ' ||' CONP_ID : '||p_nnpcv_tab(i).conp_id||' and ' ||' COCA_ID : '||p_nnpcv_tab(i).coca_id||' on ' ||TO_CHAR(p_nnpcv_tab(i).gas_day,'DD-MON-YYYY') ||chr(10)||'SQLERRM : '||sqlerrm(sqlcode) , p_source => 'efno_confirmations.ins_lookback_cnpcv_vals'); -- EXIT cnpcv_insert_loop; END; -- END IF; -- END LOOP cnpcv_insert_loop; -- COMMIT; -- END IF; -- caco_debug.putline('SP_CONF: ins_lookback_cnpcv_vals 999'); RETURN l_success; -- END ins_lookback_cnpcv_vals; -- -- FUNCTION default_lookback( p_conf_id IN confirmations.conf_id%TYPE , p_nomi_id IN nominations.nomi_id%TYPE , p_contract_id IN contracts.cont_id%TYPE , p_lookback_date IN DATE , p_lookback_action IN contracts.lookback_action%TYPE , p_nnpcv_tab IN nnpcv_tab , p_return_error OUT VARCHAR2 ) RETURN BOOLEAN IS -- Require a cursor to list all "tip" nominations for the contract CURSOR c_nominations(cp_lookback_action IN VARCHAR2) IS SELECT nomi.nomi_id , nomi.created_on , nomi.status , cont1.cust_id FROM nominations nomi ,contracts cont1 WHERE nomi.cont_id = cont1.cont_id AND cont1.cont_id IN (SELECT cont2.cont_id FROM contracts cont2 CONNECT BY PRIOR cont2.prev_cont_id = cont2.cont_id START WITH cont2.cont_id = p_contract_id) AND ( nomi.nomi_id < p_nomi_id OR p_nomi_id IS NULL ) AND EXISTS ( SELECT NULL FROM nom_net_point_cat_vals nnpcv WHERE nnpcv.nomi_id = nomi.nomi_id GROUP BY nnpcv.gas_day HAVING MIN(nnpcv.gas_day) <= (SELECT gas_day FROM confirmations WHERE conf_id = p_conf_id) AND MIN(nnpcv.gas_day) >= p_lookback_date ) -- AND ( ( nomi.status = 'A' -- 'A' will be the TIP each day AND ( cp_lookback_action = 'T' AND ( nomi_id IN ((SELECT nomi_id FROM ( SELECT DISTINCT n.nomi_id, n.gas_day, no.created_on, RANK() OVER (partition by gas_day ORDER BY gas_day, no.created_on DESC) nom_rank FROM nom_net_point_cat_vals n ,nominations no ,contracts c WHERE n.nomi_id = no.nomi_id AND no.cont_id = c.cont_id AND no.status = 'A' -- SP 19/10/2009 moved here to improve performance AND c.cont_id IN (SELECT c2.cont_id FROM contracts c2 CONNECT BY PRIOR c2.prev_cont_id = c2.cont_id START WITH c2.cont_id = p_contract_id) ) WHERE nom_rank = 1)) ) -- ) OR ( cp_lookback_action = 'A' ) ) ORDER BY ( SELECT MAX(nnpcv.gas_day) FROM nom_net_point_cat_vals nnpcv WHERE nnpcv.nomi_id = nomi.nomi_id ) DESC, nomi.created_on DESC; /* SELECT nomi.nomi_id , nomi.created_on , nomi.status , cont1.cust_id FROM nominations nomi ,contracts cont1 ,contracts cont2 WHERE nomi.cont_id = cont1.cont_id AND cont1.cust_id = cont2.cust_id AND cont2.cont_id = p_contract_id AND ( nomi.nomi_id < p_nomi_id OR p_nomi_id IS NULL ) AND EXISTS ( SELECT NULL FROM nom_net_point_cat_vals nnpcv WHERE nnpcv.nomi_id = nomi.nomi_id GROUP BY nnpcv.gas_day HAVING MIN(nnpcv.gas_day) <= (SELECT gas_day FROM confirmations WHERE conf_id = p_conf_id) AND MIN(nnpcv.gas_day) >= p_lookback_date ) -- AND ( ( nomi.status = 'A' -- 'A' will be the TIP each day AND ( cp_lookback_action = 'T' AND ( nomi_id IN ((SELECT nomi_id FROM ( SELECT DISTINCT n.nomi_id, n.gas_day, no.created_on, RANK() OVER (partition by gas_day ORDER BY gas_day, no.created_on DESC) nom_rank FROM nom_net_point_cat_vals n ,nominations no ,contracts c ,contracts c2 WHERE n.nomi_id = no.nomi_id AND no.cont_id = c.cont_id AND no.status = 'A' -- SP 19/10/2009 moved here to improve performance AND c.cust_id = c2.cust_id AND c2.cont_id = p_contract_id ) WHERE nom_rank = 1)) ) -- ) OR ( cp_lookback_action = 'A' ) ) ORDER BY ( SELECT MAX(nnpcv.gas_day) FROM nom_net_point_cat_vals nnpcv WHERE nnpcv.nomi_id = nomi.nomi_id ) DESC, nomi.created_on DESC; */ -- l_nnpcv_tab nnpcv_tab; -- l_success BOOLEAN := FALSE; -- BEGIN -- caco_debug.putline('SP_CONF: default_lookback 001'); caco_debug.putline('p_conf_id: '||p_conf_id|| ' p_nomi_id: '||p_nomi_id|| ' p_contract_id: '||p_contract_id|| ' p_lookback_date: '||p_lookback_date|| ' p_lookback_action: '||p_lookback_action|| ' p_return_error: '||p_return_error); -- l_nnpcv_tab := p_nnpcv_tab; -- <> FOR r IN c_nominations(NVL(p_lookback_action, 'A')) LOOP -- l_success := TRUE; caco_debug.putline('we have a nom to look back at: nomi_id = '||r.nomi_id); -- -- caco_debug.putline('Update nominated values'); -- l_success := ins_lookback_cnpcv_vals( p_conf_id => p_conf_id , p_nnpcv_tab => l_nnpcv_tab , p_nomi_id => r.nomi_id , p_nomi_date => r.created_on , p_return_error => p_return_error ); -- -- Exit the loop - we got values for the cnpcv_id's.. -- so there is no point looking back any further. -- EXIT nom_lookback_loop; -- END LOOP nom_lookback_loop; -- caco_debug.putline('SP_CONF: default_lookback 999'); RETURN l_success; -- EXCEPTION WHEN others THEN -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => ' Failed in default_lookback: ' ||' Error : '||sqlerrm(sqlcode) , p_source => 'efno_confirmations.default_lookback' ); -- caco_debug.putline('SP_CONF: error in default_lookback: '||sqlerrm); l_success := FALSE; -- An unexpected error has occurred while creating confirmation. Please contact support p_return_error := caco_utilities.get_module_text(2212); END default_lookback; -- -- /** -- FUNCTION remove_surplus_cnpcv RETURN BOOLEAN -- Autonomous Transaction -- Returns TRUE if successful -- If the contract has been amended between nomination and confirmation this -- Ensures that the confirmation contains only network points and categories -- that are valid for the contract at point of confirmation -- -- %param p_conf_id Unique Identifier of the confirmation to be updated -- %param p_cont_id Unique identifier of the contract to which this confirmation relates -- %param p_return_error OUT: Error message in the case of an unexpected error -- */ FUNCTION remove_surplus_cnpcv( p_conf_id IN confirmations.conf_id%TYPE , p_cont_id IN contracts.cont_id%TYPE , p_return_error OUT VARCHAR2 ) RETURN BOOLEAN IS PRAGMA AUTONOMOUS_TRANSACTION; -- l_success BOOLEAN := TRUE; l_tmpstr VARCHAR2(1000); -- BEGIN -- p_return_error := NULL; -- SAVEPOINT before_delete; -- Anonymous block to handle exceptions BEGIN -- -- Remove invalid network points -- DELETE conf_net_point_cat_vals WHERE conf_id = p_conf_id AND conp_id NOT IN ( SELECT conp.conp_id FROM cont_network_points conp WHERE conp.cont_id = p_cont_id ); -- -- Remove invalid categories -- DELETE conf_net_point_cat_vals WHERE conf_id = p_conf_id AND coca_id NOT IN ( SELECT coca.coca_id FROM contract_categories coca WHERE coca.cont_id = p_cont_id ); -- COMMIT; -- EXCEPTION WHEN others THEN ROLLBACK TO SAVEPOINT before_delete; -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => ' Failed to delete surplus cnppv: ' ||' CONF_ID : '||p_conf_id||chr(10) ||' CONT_ID : '||p_cont_id||chr(10) ||' Error : '||sqlerrm(sqlcode) , p_source => 'efno_confirmations.remove_surplus_cnpcv' ); -- l_success := FALSE; -- An unexpected error has occurred while creating confirmation. Please contact support p_return_error := caco_utilities.get_module_text(2212); -- END; -- RETURN l_success; -- END remove_surplus_cnpcv; -- -- Function to calculate the exception value based on the percentage split and virtual network point values -- FUNCTION get_cnppv_emo_exp_value (p_conp_id IN NUMBER , p_coca_id IN NUMBER , p_exception IN VARCHAR2 , p_cont_id IN contracts.cont_id%TYPE , p_success OUT BOOLEAN , p_return_error OUT VARCHAR2 ) RETURN NUMBER IS -- -- Cursor to get the Percentage Split value of the virtual network point from cnppv table CURSOR c_vnp_per_split IS SELECT cnppv.value value FROM parameters pars , cont_network_points conp , contract_parameters copa , network_points nepo , cont_net_point_param_vals cnppv WHERE copa.pars_id = pars.pars_id AND copa.copa_id = cnppv.copa_id AND conp.conp_id = cnppv.conp_id AND conp.cont_id = p_cont_id AND conp.nepo_id = nepo.nepo_id AND nepo.nepo_type = 'V' AND pars.name IN (g_perc_split_en, g_perc_split_hu); -- -- Cursor to get the Percentage Split values from cnppv table CURSOR c_cnppv_per_split(cp_conp_id IN NUMBER) IS SELECT cnppv.value value FROM parameters pars , cont_network_points conp , contract_parameters copa , cont_net_point_param_vals cnppv WHERE copa.pars_id = pars.pars_id AND copa.copa_id = cnppv.copa_id AND conp.conp_id = cnppv.conp_id AND conp.conp_id = cp_conp_id AND conp.cont_id = p_cont_id AND pars.name IN (g_perc_split_en, g_perc_split_hu); -- -- Cursor to get the exception value for the virtual network point of a given -- contract category CURSOR c_cnppv_emo_exp(cp_coca_id IN NUMBER, cp_exception IN VARCHAR2) IS SELECT cnppv.value FROM cont_net_point_param_vals cnppv , contract_parameters copa , parameters pars , contract_categories coca , cont_network_points conp , network_points nepo WHERE cnppv.copa_id = copa.copa_id AND copa.pars_id = pars.pars_id AND SUBSTR(UPPER(pars.code),-3) = cp_exception AND pars.cate_id = coca.cate_id AND coca.coca_id = cp_coca_id AND conp.cont_id = p_cont_id AND cnppv.conp_id = conp.conp_id AND nepo.nepo_id = conp.nepo_id AND nepo.nepo_type = 'V'; -- l_perc_split cont_net_point_param_vals.value%TYPE; l_emo_exp_value cont_net_point_param_vals.value%TYPE; l_tot_perc_split cont_net_point_param_vals.value%TYPE; l_cont_value cont_net_point_param_vals.value%TYPE := 0; l_success BOOLEAN := TRUE; -- BEGIN caco_debug.putline('SP_CONF: get_cnppv_emo_exp_value 001'); -- get the Percentage Split value of the virtual network point from cnppv table OPEN c_vnp_per_split; FETCH c_vnp_per_split INTO l_tot_perc_split; CLOSE c_vnp_per_split; -- -- get the percentage split value of the network point OPEN c_cnppv_per_split(p_conp_id); FETCH c_cnppv_per_split INTO l_perc_split; IF c_cnppv_per_split%NOTFOUND THEN CLOSE c_cnppv_per_split; -- l_success := FALSE; p_return_error := caco_utilities.get_module_text(2337); -- Unable to find contracted value for invalid nomination. Please contact support caco_debug.putline('efno_confirmations.create_missing_cnpcv: Unable to locate Percentage Split parameter for: ' ||' CONP_ID : '||p_conp_id); -- END IF; CLOSE c_cnppv_per_split; -- get the virtual network point validation exception value IF l_success THEN OPEN c_cnppv_emo_exp(p_coca_id, p_exception); FETCH c_cnppv_emo_exp INTO l_emo_exp_value; IF c_cnppv_emo_exp%NOTFOUND THEN CLOSE c_cnppv_emo_exp; -- l_success := FALSE; p_return_error := caco_utilities.get_module_text(2337); -- Unable to find contracted value for invalid nomination. Please contact support caco_debug.putline('efno_confirmations.create_missing_cnpcv: Unable to locate VNP CTR value for: ' ||' COCA_ID : '||p_coca_id); -- END IF; CLOSE c_cnppv_emo_exp; -- calculate the exception value based on the percentage split and virtual network point values l_cont_value := ROUND((l_perc_split/l_tot_perc_split)*l_emo_exp_value); -- END IF; p_success := l_success; caco_debug.putline('SP_CONF: get_cnppv_emo_exp_value 999'); RETURN l_cont_value; -- END get_cnppv_emo_exp_value; -- -- -- /** -- FUNCTION create_missing_cnpcv RETURN BOOLEAN -- Autonomous Transaction -- Returns TRUE if successful -- If the contract has been amended between nomination and confirmation this -- Ensures that the confirmation contains any additional network points and categories -- that have been added -- -- %param p_conf_id Unique Identifier of the confirmation to be updated -- %param p_nomi_id Unique identifier of the nomination to which this confirmation relates -- %param p_nnpcv_tab -- %param p_return_error OUT: Error message in the case of an unexpected error -- */ PROCEDURE create_missing_cnpcv( p_conf_id IN confirmations.conf_id%TYPE , p_nomi_id IN nominations.nomi_id%TYPE , p_nnpcv_tab IN OUT nnpcv_tab , p_exception IN contracts.validation_exception%TYPE , p_validation_action IN contracts.validation_action%TYPE , p_success OUT BOOLEAN , p_return_error OUT VARCHAR2 , p_defaulted IN VARCHAR2 DEFAULT 'Y' , p_cont_id IN contracts.cont_id%TYPE , p_lookback_date IN DATE , p_lookback_action IN contracts.lookback_action%TYPE) IS PRAGMA AUTONOMOUS_TRANSACTION; -- -- Cursor to get the minimum value for a given CONP and COCA pair CURSOR c_cnppv_min( cp_conp_id IN NUMBER , cp_coca_id IN NUMBER ) IS SELECT cnppv.value FROM cont_net_point_param_vals cnppv , contract_parameters copa , parameters pars , contract_categories coca WHERE cnppv.conp_id = cp_conp_id AND cnppv.copa_id = copa.copa_id AND copa.pars_id = pars.pars_id AND SUBSTR(UPPER(pars.code),-3) = 'MIN' -- Need the MIN parameter AND pars.cate_id = coca.cate_id AND coca.coca_id = cp_coca_id; -- -- Cursor to get the contracted value for a given CONP and COCA pair CURSOR c_cnppv_ctr( cp_conp_id IN NUMBER , cp_coca_id IN NUMBER ) IS SELECT cnppv.value FROM cont_net_point_param_vals cnppv , contract_parameters copa , parameters pars , contract_categories coca WHERE cnppv.conp_id = cp_conp_id AND cnppv.copa_id = copa.copa_id AND copa.pars_id = pars.pars_id AND SUBSTR(UPPER(pars.code),-3) = 'CTR' -- Need the CTR parameter AND pars.cate_id = coca.cate_id AND coca.coca_id = cp_coca_id; -- -- Cursor to get the maximum value for a given CONP and COCA pair CURSOR c_cnppv_max( cp_conp_id IN NUMBER , cp_coca_id IN NUMBER ) IS SELECT cnppv.value FROM cont_net_point_param_vals cnppv , contract_parameters copa , parameters pars , contract_categories coca WHERE cnppv.conp_id = cp_conp_id AND cnppv.copa_id = copa.copa_id AND copa.pars_id = pars.pars_id AND SUBSTR(UPPER(pars.code),-3) = 'MAX' -- Need the MAX parameter AND pars.cate_id = coca.cate_id AND coca.coca_id = cp_coca_id; -- l_value conf_net_point_cat_vals.value%TYPE; l_int_value conf_net_point_cat_vals.value%TYPE; l_cont_value conf_net_point_cat_vals.value%TYPE; l_success BOOLEAN := TRUE; l_interrupted conf_net_point_cat_vals.interrupted%TYPE; -- BEGIN caco_debug.putline('SP_CONF: create_missing_cnpcv 001'); SAVEPOINT before_create_missing; p_success := TRUE; p_return_error := NULL; -- --output_nnpcv_tab(p_nnpcv_tab); IF NVL(p_nnpcv_tab.COUNT,0) > 0 THEN IF p_validation_action = 'B' THEN l_success := default_lookback( p_conf_id , p_nomi_id , p_cont_id , p_lookback_date , p_lookback_action , p_nnpcv_tab , p_return_error ); END IF; /* if sub OR lookback failed ...existing code, remove +10 end if; */ IF NOT l_success OR p_validation_action = 'T' THEN caco_debug.putline('SP_CONF: create_missing_cnpcv 555: using contract vals'); <> FOR i IN 1..p_nnpcv_tab.COUNT LOOP IF NVL(p_nnpcv_tab(i).missing, 'N') = 'Y' THEN -- -- Get the interrupted value if there is one l_int_value := get_interrupted_value( p_nnpcv_tab(i).conp_id , p_nnpcv_tab(i).coca_id , p_nnpcv_tab(i).gas_day ); -- -- Get the contract value depending on the validation exception IF p_exception = 'CO' THEN -- IF efno_contracts.emo_contract(p_cont_id) = 'Y' THEN -- -- calculate the exception value based on the percentage split and -- virtual network point values l_cont_value := get_cnppv_emo_exp_value(p_nnpcv_tab(i).conp_id , p_nnpcv_tab(i).coca_id , 'CTR' , p_cont_id , p_success , p_return_error); IF NOT p_success THEN EXIT cnppv_loop; END IF; ELSE OPEN c_cnppv_ctr( p_nnpcv_tab(i).conp_id , p_nnpcv_tab(i).coca_id ); FETCH c_cnppv_ctr INTO l_cont_value; IF c_cnppv_ctr%NOTFOUND THEN CLOSE c_cnppv_ctr; -- p_success := FALSE; p_return_error := caco_utilities.get_module_text(2337); -- Unable to find contracted value for invalid nomination. Please contact support caco_debug.putline('efno_confirmations.create_missing_cnpcv: Unable to locate Contract parameter CTR for: ' ||' CONP_ID : '||p_nnpcv_tab(i).conp_id||' and ' ||' COCA_ID : '||p_nnpcv_tab(i).coca_id ); -- EXIT cnppv_loop; END IF; CLOSE c_cnppv_ctr; END IF; -- ELSIF p_exception = 'MI' THEN -- Minimum -- IF efno_contracts.emo_contract(p_cont_id) = 'Y' THEN -- -- calculate the exception value based on the percentage split and -- virtual network point values l_cont_value := get_cnppv_emo_exp_value(p_nnpcv_tab(i).conp_id , p_nnpcv_tab(i).coca_id , 'MIN' , p_cont_id , p_success , p_return_error); IF NOT p_success THEN EXIT cnppv_loop; END IF; ELSE OPEN c_cnppv_min( p_nnpcv_tab(i).conp_id , p_nnpcv_tab(i).coca_id ); FETCH c_cnppv_min INTO l_cont_value; IF c_cnppv_min%NOTFOUND THEN CLOSE c_cnppv_min; -- p_success := FALSE; p_return_error := caco_utilities.get_module_text(2310); -- Unable to find minimum value for invalid nomination. Please contact support caco_debug.putline('efno_confirmations.create_missing_cnpcv: Unable to locate Contract parameter MIN for: ' ||' CONP_ID : '||p_nnpcv_tab(i).conp_id||' and ' ||' COCA_ID : '||p_nnpcv_tab(i).coca_id ); -- EXIT cnppv_loop; END IF; CLOSE c_cnppv_min; END IF; -- ELSIF p_exception IN ('MA', 'EX') THEN -- Maximum -- IF efno_contracts.emo_contract(p_cont_id) = 'Y' THEN -- -- calculate the exception value based on the percentage split and -- virtual network point values l_cont_value := get_cnppv_emo_exp_value(p_nnpcv_tab(i).conp_id , p_nnpcv_tab(i).coca_id , 'MAX' , p_cont_id , p_success , p_return_error); IF NOT p_success THEN EXIT cnppv_loop; END IF; ELSE OPEN c_cnppv_max( p_nnpcv_tab(i).conp_id , p_nnpcv_tab(i).coca_id ); FETCH c_cnppv_max INTO l_cont_value; IF c_cnppv_max%NOTFOUND THEN CLOSE c_cnppv_max; -- p_success := FALSE; p_return_error := caco_utilities.get_module_text(2310); -- Unable to find minimum value for invalid nomination. Please contact support caco_debug.putline('efno_confirmations.create_missing_cnpcv: Unable to locate Contract parameter MAX for: ' ||' CONP_ID : '||p_nnpcv_tab(i).conp_id||' and ' ||' COCA_ID : '||p_nnpcv_tab(i).coca_id ); -- EXIT cnppv_loop; END IF; CLOSE c_cnppv_max; END IF; -- /* IF p_exception = 'EX' THEN caco_debug.putline('SP_CONF: create_missing_cnpcv (adding + 10) 500'); l_value := l_value + 10; END IF;*/ -- END IF; -- Compare the contract value and the interrupted value and go with the lowest value IF l_int_value IS NULL THEN l_value := l_cont_value; l_interrupted := 'N'; ELSE IF l_int_value > l_cont_value THEN l_value := l_cont_value; ELSE l_value := l_int_value; END IF; l_interrupted := 'Y'; END IF; -- --output_nnpcv_rec(p_nnpcv_tab(i)); BEGIN INSERT INTO conf_net_point_cat_vals ( conf_id , nomi_id , value , gas_day , conp_id , coca_id , valid , defaulted , interrupted , last_gas_day ) VALUES ( p_conf_id , p_nomi_id , l_value , p_nnpcv_tab(i).gas_day , p_nnpcv_tab(i).conp_id , p_nnpcv_tab(i).coca_id , 'Y' -- , p_defaulted --05/03/08 SP replaced with 'Y' to repress nom date on confirmation , 'Y' , l_interrupted , NULL ); EXCEPTION WHEN dup_val_on_index THEN NULL; WHEN others THEN ROLLBACK TO SAVEPOINT before_create_missing; p_success := FALSE; p_return_error := caco_utilities.get_module_text(2311); -- Unable to force confirm invalid nomination. Please contact support caco_debug.putline('efno_confirmations.create_missing_cnpcv:' ||' Failed to insert default confirmation value: ' ||' CONP_ID : '||p_nnpcv_tab(i).conp_id||' and ' ||' COCA_ID : '||p_nnpcv_tab(i).coca_id||' on ' ||TO_CHAR(p_nnpcv_tab(i).gas_day,'DD-MON-YYYY') ||chr(10)||'SQLERRM : '||sqlerrm(sqlcode) ); -- -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => ' Failed to insert default confirmation value: ' ||' CONP_ID : '||p_nnpcv_tab(i).conp_id||' and ' ||' COCA_ID : '||p_nnpcv_tab(i).coca_id||' on ' ||TO_CHAR(p_nnpcv_tab(i).gas_day,'DD-MON-YYYY') ||chr(10)||'SQLERRM : '||sqlerrm(sqlcode) , p_source => 'efno_confirmations.create_missing_cnpcv'); -- EXIT cnppv_loop; END; -- END IF; -- END LOOP cnppv_loop; END IF; -- -- IF p_success THEN COMMIT; END IF; -- END IF; -- caco_debug.putline('SP_CONF: create_missing_cnpcv 999'); END create_missing_cnpcv; -- -- FUNCTION add_missing_cnpcv( p_conf_id IN confirmations.conf_id%TYPE , p_nomi_id IN nominations.nomi_id%TYPE , p_contract_row IN contracts%ROWTYPE , p_gas_day IN DATE , p_return_error OUT VARCHAR2 , p_defaulted IN VARCHAR2 DEFAULT 'Y' ) RETURN BOOLEAN IS l_success BOOLEAN := TRUE; -- l_cnpcv_tab nnpcv_tab; l_counter NUMBER := 0; l_lookback_date DATE; -- l_only_short_day VARCHAR2(1) := 'N'; l_cont_long_day VARCHAR2(1) := 'N'; -- BEGIN caco_debug.putline('SP_CONF: add_missing_cnpcv 001'); p_return_error := NULL; l_lookback_date := p_gas_day - p_contract_row.validation_window; -- Check to see if the gas day we are looking at is a long or short day IF cout_dates.hours_in_gas_day(p_gas_day) = 25 THEN l_cont_long_day := 'Y'; END IF; IF cout_dates.hours_in_gas_day(p_gas_day) = 23 THEN l_only_short_day := 'Y'; END IF; -- -- Check if there are missing Network Points caco_debug.putline('Enter add missing'||p_contract_row.cont_id||':'||p_conf_id); FOR r IN ( SELECT DISTINCT conp.conp_id conp_id FROM cont_network_points conp WHERE conp.cont_id = p_contract_row.cont_id AND NOT EXISTS ( SELECT 'x' FROM conf_net_point_cat_vals cnpcv WHERE cnpcv.conf_id = p_conf_id AND cnpcv.conp_id = conp.conp_id ) ) LOOP caco_debug.putline('In nepo: '||r.conp_id); -- Add a missing entry for each network point for all categories FOR r2 IN ( SELECT coca.coca_id coca_id FROM contract_categories coca ,categories cate WHERE coca.cont_id = p_contract_row.cont_id AND cate.cate_id = coca.cate_id AND ((cate.display_cond = 'LO' AND l_cont_long_day = 'Y') OR (cate.display_cond = 'SH' AND l_only_short_day = 'N') OR cate.display_cond = 'AL')) LOOP l_counter := l_counter + 1; -- l_cnpcv_tab(l_counter).conp_id := r.conp_id; l_cnpcv_tab(l_counter).coca_id := r2.coca_id; l_cnpcv_tab(l_counter).gas_day := p_gas_day; l_cnpcv_tab(l_counter).missing := 'Y'; -- END LOOP; -- END LOOP; -- IF l_counter > 0 THEN -- create the missing entries caco_debug.putline('SP_CONF: add_missing_cnpcv missing nepo 100'); create_missing_cnpcv( p_conf_id => p_conf_id , p_nomi_id => p_nomi_id , p_nnpcv_tab => l_cnpcv_tab , p_exception => p_contract_row.validation_exception , p_validation_action => p_contract_row.validation_action , p_success => l_success , p_return_error => p_return_error , p_defaulted => p_defaulted , p_cont_id => p_contract_row.cont_id , p_lookback_date => l_lookback_date , p_lookback_action => p_contract_row.lookback_action ); -- END IF; -- IF l_success THEN -- l_counter := 0; l_cnpcv_tab.DELETE; -- -- Now check for missing Categories FOR r IN ( SELECT DISTINCT coca.coca_id coca_id FROM contract_categories coca ,categories cate WHERE coca.cont_id = p_contract_row.cont_id AND cate.cate_id = coca.cate_id AND ((cate.display_cond = 'LO' AND l_cont_long_day = 'Y') OR (cate.display_cond = 'SH' AND l_only_short_day = 'N') OR cate.display_cond = 'AL') AND NOT EXISTS ( SELECT 'x' FROM conf_net_point_cat_vals cnpcv WHERE cnpcv.conf_id = p_conf_id AND cnpcv.coca_id = coca.coca_id ) ) LOOP caco_debug.putline('In coca: '||r.coca_id); -- Add a missing entry for each category for all network point FOR r2 IN ( SELECT conp.conp_id conp_id FROM cont_network_points conp WHERE conp.cont_id = p_contract_row.cont_id ) LOOP l_counter := l_counter + 1; -- l_cnpcv_tab(l_counter).conp_id := r2.conp_id; l_cnpcv_tab(l_counter).coca_id := r.coca_id; l_cnpcv_tab(l_counter).gas_day := p_gas_day; l_cnpcv_tab(l_counter).missing := 'Y'; -- END LOOP; -- END LOOP; -- IF l_counter > 0 THEN -- create the missing entries caco_debug.putline('SP_CONF: add_missing_cnpcv missing cate 200'); create_missing_cnpcv( p_conf_id => p_conf_id , p_nomi_id => p_nomi_id , p_nnpcv_tab => l_cnpcv_tab , p_exception => p_contract_row.validation_exception , p_validation_action => p_contract_row.validation_action , p_success => l_success , p_return_error => p_return_error , p_defaulted => p_defaulted , p_cont_id => p_contract_row.cont_id , p_lookback_date => l_lookback_date , p_lookback_action => p_contract_row.lookback_action ); -- END IF; -- END IF; -- caco_debug.putline('SP_CONF: add_missing_cnpcv 999'); RETURN l_success; -- END add_missing_cnpcv; -- FUNCTION replace_cnpcv( p_conf_id IN confirmations.conf_id%TYPE , p_nnpcv_tab IN nnpcv_tab , p_exception IN contracts.validation_exception%TYPE , p_return_error OUT VARCHAR2 ) RETURN BOOLEAN IS PRAGMA AUTONOMOUS_TRANSACTION; -- Cursor to select the Contract Category Maximum CURSOR c_contract_val( cp_conp_id IN NUMBER , cp_coca_id IN NUMBER , cp_type IN VARCHAR2 ) IS SELECT cnppv.value FROM cont_net_point_param_vals cnppv , contract_parameters copa , parameters pars , contract_categories coca , categories cate , contracts cont WHERE cnppv.conp_id = cp_conp_id AND cnppv.copa_id = copa.copa_id AND cont.cont_id = coca.cont_id AND copa.pars_id = pars.pars_id AND SUBSTR(UPPER(pars.code),-3) = NVL(DECODE(cont.validation_exception, 'CO','CTR','MI','MIN','MA','MAX'),'MAX') AND pars.cate_id = cate.cate_id AND coca.cate_id = cate.cate_id AND coca.coca_id = cp_coca_id; -- -- Cursor to get the correct row from CNPCV table CURSOR c_cnpcv( cp_conp_id IN NUMBER , cp_coca_id IN NUMBER , cp_gas_day IN DATE ) IS SELECT cnpcv.* FROM conf_net_point_cat_vals cnpcv WHERE conf_id = p_conf_id AND conp_id = cp_conp_id AND coca_id = cp_coca_id AND gas_day = cp_gas_day FOR UPDATE; -- l_cnpcv_row c_cnpcv%ROWTYPE; l_contract_value NUMBER := 0; -- l_success BOOLEAN := TRUE; -- BEGIN caco_debug.putline('SP_CONF: replace_cnpcv 001'); -- SAVEPOINT before_replace; -- IF NVL(p_nnpcv_tab.COUNT,0) > 0 THEN -- <> FOR i IN 1..p_nnpcv_tab.COUNT LOOP -- Reset temp variables l_cnpcv_row := NULL; l_contract_value := 0; -- IF p_nnpcv_tab(i).in_error THEN -- caco_debug.putline('REPLACE(conp|coca) '||p_exception||': '||p_nnpcv_tab(i).conp_id||':'||p_nnpcv_tab(i).coca_id||':-'||sys.diutil.bool_to_int(p_nnpcv_tab(i).in_error)); -- OPEN c_contract_val( p_nnpcv_tab(i).conp_id , p_nnpcv_tab(i).coca_id , p_exception ); FETCH c_contract_val INTO l_contract_value; IF c_contract_val%NOTFOUND THEN -- CLOSE c_contract_val; -- bit of a problem - contract is messaed up somewhere... -- don't know what to do here - no guidance. ROLLBACK TO SAVEPOINT before_replace; l_success := FALSE; p_return_error := caco_utilities.get_module_text(2313); -- Unable to locate contract parameter maximum. Please contact support caco_debug.putline('efno_confirmations.replace_cnpcv: Unable to locate Contract parameter '||p_exception||' for: ' ||' CONP_ID : '||p_nnpcv_tab(i).conp_id||' and ' ||' COCA_ID : '||p_nnpcv_tab(i).coca_id ); EXIT replace_loop; -- ELSE CLOSE c_contract_val; END IF; -- OPEN c_cnpcv( p_nnpcv_tab(i).conp_id , p_nnpcv_tab(i).coca_id --con_val.coca_id --p_nnpcv_tab(i).coca_id , p_nnpcv_tab(i).gas_day ); FETCH c_cnpcv INTO l_cnpcv_row; IF c_cnpcv%FOUND THEN -- caco_debug.putline('DEBUG1'); UPDATE conf_net_point_cat_vals cnpcv SET cnpcv.value = l_contract_value ,cnpcv.defaulted = 'Y' ,cnpcv.last_nomi_id = NULL ,cnpcv.last_nom_received = NULL WHERE CURRENT OF c_cnpcv; -- caco_debug.putline('Updated conf_id: '||l_cnpcv_row.conf_id||' conp_id: '||l_cnpcv_row.conp_id||' coca_id: '||l_cnpcv_row.coca_id); -- -- Now update the others that are for the same network point -- caco_debug.putline('DEBUG2'); UPDATE conf_net_point_cat_vals cnpcvz SET ( cnpcvz.value , cnpcvz.defaulted , cnpcvz.last_nomi_id , cnpcvz.last_nom_received ) = ( SELECT cnppv.value , 'Y' , NULL , NULL FROM cont_net_point_param_vals cnppv , contract_parameters copa , parameters pars , contract_categories coca , categories cate , contracts cont WHERE cnppv.conp_id = p_nnpcv_tab(i).conp_id AND cnppv.copa_id = copa.copa_id AND cont.cont_id = coca.cont_id AND copa.pars_id = pars.pars_id AND SUBSTR(UPPER(pars.code),-3) = NVL(DECODE(cont.validation_exception, 'CO','CTR','MI','MIN','MA','MAX'),'MAX') AND pars.cate_id = cate.cate_id AND coca.cate_id = cate.cate_id AND coca.coca_id = cnpcvz.coca_id ) WHERE cnpcvz.conf_id = p_conf_id AND cnpcvz.conp_id = p_nnpcv_tab(i).conp_id AND cnpcvz.coca_id <> p_nnpcv_tab(i).coca_id; -- CLOSE c_cnpcv; ELSE CLOSE c_cnpcv; -- Problem - couldnt find the nnpcv_id in the CNPCV table ROLLBACK TO SAVEPOINT before_replace; -- l_success := FALSE; p_return_error := caco_utilities.get_module_text(2314); -- Unable to locate data. Please contact support caco_debug.putline('efno_confirmations.replace_cnpcv: Unable to locate data in conf_net_point_cat_vals: ' ||' CONF_ID : '||p_conf_id ||' CONP_ID : '||p_nnpcv_tab(i).conp_id ||' COCA_ID : '||p_nnpcv_tab(i).coca_id ||' GAS_DAY : '||TO_DATE(p_nnpcv_tab(i).gas_day,'DD-MON-YYYY') ); EXIT replace_loop; -- END IF; -- END IF; -- END LOOP truncate_to_max_loop; -- IF l_success THEN -- COMMIT; -- END IF; -- END IF; -- caco_debug.putline('SP_CONF: replace_cnpcv 999'); -- RETURN l_success; -- EXCEPTION WHEN OTHERS THEN ROLLBACK TO SAVEPOINT before_replace; caco_debug.putline('efno_confirmations.truncate_cnpcv_to_max: Unexpected Error ' ||' CONF_ID : '||p_conf_id ||CHR(10)||' Error Msg : '||sqlerrm(sqlcode) ); -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => 'Unexpected Error ' ||' CONF_ID : '||p_conf_id ||chr(10)||' Error Msg : '||sqlerrm(sqlcode) , p_source => 'efno_confirmations.truncate_cnpcv_to_max'); -- RETURN FALSE; -- END replace_cnpcv; -- FUNCTION default_cnpcv_values( p_gas_day IN DATE , p_conf_id IN confirmations.conf_id%TYPE , p_nnpcv_tab IN nnpcv_tab , p_exception IN contracts.validation_exception%TYPE , p_return_error OUT VARCHAR2 , p_check IN BOOLEAN DEFAULT FALSE ) RETURN BOOLEAN IS PRAGMA AUTONOMOUS_TRANSACTION; -- -- Cursor to get the minimum value for a given CONP and COCA pair CURSOR c_cnppv_min( cp_conp_id IN NUMBER , cp_coca_id IN NUMBER ) IS SELECT cnppv.value FROM cont_net_point_param_vals cnppv , contract_parameters copa , parameters pars , contract_categories coca WHERE cnppv.conp_id = cp_conp_id AND cnppv.copa_id = copa.copa_id AND copa.pars_id = pars.pars_id AND SUBSTR(pars.code,-3) = 'MIN' -- Need the MIN parameter AND pars.cate_id = coca.cate_id AND coca.coca_id = cp_coca_id; -- -- Cursor to get the contracted value for a given CONP and COCA pair CURSOR c_cnppv_ctr( cp_conp_id IN NUMBER , cp_coca_id IN NUMBER ) IS SELECT cnppv.value FROM cont_net_point_param_vals cnppv , contract_parameters copa , parameters pars , contract_categories coca WHERE cnppv.conp_id = cp_conp_id AND cnppv.copa_id = copa.copa_id AND copa.pars_id = pars.pars_id AND SUBSTR(pars.code,-3) = 'CTR' -- Need the CTR parameter AND pars.cate_id = coca.cate_id AND coca.coca_id = cp_coca_id; -- -- Cursor to get the contracted value for a given CONP and COCA pair CURSOR c_cnppv_max( cp_conp_id IN NUMBER , cp_coca_id IN NUMBER ) IS SELECT cnppv.value FROM cont_net_point_param_vals cnppv , contract_parameters copa , parameters pars , contract_categories coca WHERE cnppv.conp_id = cp_conp_id AND cnppv.copa_id = copa.copa_id AND copa.pars_id = pars.pars_id AND SUBSTR(pars.code,-3) = 'MAX' -- Need the CTR parameter AND pars.cate_id = coca.cate_id AND coca.coca_id = cp_coca_id; -- l_value cont_net_point_param_vals.value%TYPE; l_int_value conf_net_point_cat_vals.value%TYPE; l_cont_value conf_net_point_cat_vals.value%TYPE; l_cont_id NUMBER; -- l_success BOOLEAN := TRUE; l_interrupted conf_net_point_cat_vals.interrupted%TYPE; -- BEGIN caco_debug.putline('SP_CONF: default_cnpcv_values 001'); SAVEPOINT before_default; -- quite simply, we should loop through the table of given nnpcv and update the values -- to the Minimum or Contracted values for the contract -- IF NVL(p_nnpcv_tab.COUNT,0) > 0 THEN -- -- get the contract id SELECT conp.cont_id INTO l_cont_id FROM cont_network_points conp WHERE conp.conp_id = p_nnpcv_tab(1).conp_id; -- caco_debug.putline('SP_CONF: default_cnpcv_values cont_id: '||l_cont_id); -- <> FOR i IN 1..p_nnpcv_tab.COUNT LOOP -- IF NOT p_check OR (p_check AND p_nnpcv_tab(i).in_error) THEN -- l_value := 0; -- Get the interrupted value if there is one l_int_value := get_interrupted_value( p_nnpcv_tab(i).conp_id , p_nnpcv_tab(i).coca_id -- , p_nnpcv_tab(i).gas_day ); , p_gas_day ); -- -- IF p_exception = 'CO' THEN -- IF efno_contracts.emo_contract(l_cont_id) = 'Y' THEN -- -- calculate the exception value based on the percentage split and -- virtual network point values l_cont_value := get_cnppv_emo_exp_value(p_nnpcv_tab(i).conp_id , p_nnpcv_tab(i).coca_id , 'CTR' , l_cont_id , l_success , p_return_error); IF NOT l_success THEN EXIT cnppv_loop; END IF; ELSE OPEN c_cnppv_ctr( p_nnpcv_tab(i).conp_id , p_nnpcv_tab(i).coca_id ); FETCH c_cnppv_ctr INTO l_cont_value; IF c_cnppv_ctr%NOTFOUND THEN CLOSE c_cnppv_ctr; -- l_success := FALSE; p_return_error := caco_utilities.get_module_text(2337); -- Unable to find contracted value for invalid nomination. Please contact support caco_debug.putline('efno_confirmations.default_gtcv_values: Unable to locate Contract parameter CTR for: ' ||' CONP_ID : '||p_nnpcv_tab(i).conp_id||' and ' ||' COCA_ID : '||p_nnpcv_tab(i).coca_id ); -- EXIT cnppv_loop; END IF; CLOSE c_cnppv_ctr; END IF; -- ELSIF p_exception = 'MI' THEN -- must be MI (minimum) -- IF efno_contracts.emo_contract(l_cont_id) = 'Y' THEN -- -- calculate the exception value based on the percentage split and -- virtual network point values l_cont_value := get_cnppv_emo_exp_value(p_nnpcv_tab(i).conp_id , p_nnpcv_tab(i).coca_id , 'MIN' , l_cont_id , l_success , p_return_error); IF NOT l_success THEN EXIT cnppv_loop; END IF; ELSE OPEN c_cnppv_min( p_nnpcv_tab(i).conp_id , p_nnpcv_tab(i).coca_id ); FETCH c_cnppv_min INTO l_cont_value; IF c_cnppv_min%NOTFOUND THEN CLOSE c_cnppv_min; -- l_success := FALSE; p_return_error := caco_utilities.get_module_text(2310); -- Unable to find minimum value for invalid nomination. Please contact support caco_debug.putline('efno_confirmations.default_gtcv_values: Unable to locate Contract parameter MIN for: ' ||' CONP_ID : '||p_nnpcv_tab(i).conp_id||' and ' ||' COCA_ID : '||p_nnpcv_tab(i).coca_id ); -- EXIT cnppv_loop; ELSE CLOSE c_cnppv_min; END IF; END IF; -- ELSIF p_exception = 'MA' THEN -- must be MA (Maximum) -- IF efno_contracts.emo_contract(l_cont_id) = 'Y' THEN -- -- calculate the exception value based on the percentage split and -- virtual network point values l_cont_value := get_cnppv_emo_exp_value(p_nnpcv_tab(i).conp_id , p_nnpcv_tab(i).coca_id , 'MIN' , l_cont_id , l_success , p_return_error); IF NOT l_success THEN EXIT cnppv_loop; END IF; ELSE OPEN c_cnppv_max( p_nnpcv_tab(i).conp_id , p_nnpcv_tab(i).coca_id ); FETCH c_cnppv_max INTO l_cont_value; IF c_cnppv_max%NOTFOUND THEN CLOSE c_cnppv_max; -- l_success := FALSE; p_return_error := caco_utilities.get_module_text(2310); -- Unable to find minimum value for invalid nomination. Please contact support caco_debug.putline('efno_confirmations.default_gtcv_values: Unable to locate Contract parameter MAX for: ' ||' CONP_ID : '||p_nnpcv_tab(i).conp_id||' and ' ||' COCA_ID : '||p_nnpcv_tab(i).coca_id ); -- EXIT cnppv_loop; ELSE CLOSE c_cnppv_max; END IF; END IF; -- END IF; -- Compare the contract value and the interrupted value and go with the lowest value caco_debug.putline('l_int_value: '||l_int_value); caco_debug.putline('l_cont_value: '||l_cont_value); IF l_int_value IS NULL THEN l_value := l_cont_value; l_interrupted := 'N'; ELSE IF l_int_value > l_cont_value THEN l_value := l_cont_value; ELSE l_value := l_int_value; END IF; l_interrupted := 'Y'; END IF; caco_debug.putline('l_value: '||l_value); caco_debug.putline('l_interrupted: '||l_interrupted); -- BEGIN -- So now update the value in conf_ and set the defaulted flag caco_debug.putline('DEBUG3'); UPDATE conf_net_point_cat_vals SET last_nom_received = NULL , last_nomi_id = NULL , last_gas_day = NULL , last_coru_id = NULL , defaulted = 'Y' , valid = 'Y' , value = l_value , interrupted = l_interrupted WHERE conf_id = p_conf_id AND conp_id = p_nnpcv_tab(i).conp_id AND coca_id = p_nnpcv_tab(i).coca_id; -- caco_debug.putline('Valu: '||l_value||' : '||p_nnpcv_tab(i).coca_id); -- SP 3/3/08 - commented update back in and now setting last_gas_day to null to stop -- nomination date appearing on confirmation UPDATE conf_net_point_cat_vals SET defaulted = 'Y', last_gas_day = NULL WHERE conf_id = p_conf_id AND conp_id = p_nnpcv_tab(i).conp_id; -- EXCEPTION WHEN others THEN l_success := FALSE; p_return_error := caco_utilities.get_module_text(2257); -- Error defaulting invalid nomination values. Please contact support caco_debug.putline('efno_confirmations.default_gtcv_values: Update failed : ' ||' CONP_ID : '||p_nnpcv_tab(i).conp_id||' and ' ||' COCA_ID : '||p_nnpcv_tab(i).coca_id ||chr(10)||' Error Msg : '||sqlerrm(sqlcode) ); -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => 'Update failed : ' ||' CONP_ID : '||p_nnpcv_tab(i).conp_id||' and ' ||' COCA_ID : '||p_nnpcv_tab(i).coca_id ||chr(10)||' Error Msg : '||sqlerrm(sqlcode) , p_source => 'efno_confirmations.default_cnpcv_values'); -- END; -- END IF; -- END LOOP cnppv_loop; -- END IF; -- IF NOT l_success THEN ROLLBACK TO SAVEPOINT before_default; ELSE COMMIT; END IF; -- caco_debug.putline('SP_CONF: default_cnpcv_values 999'); -- RETURN l_success; -- END default_cnpcv_values; -- FUNCTION upd_cnpcv_vals_with_nom( p_conf_id IN confirmations.conf_id%TYPE , p_nnpcv_tab IN OUT nnpcv_tab , p_coru_id IN contract_rules.coru_id%TYPE , p_nomi_id IN nominations.nomi_id%TYPE , p_nomi_date IN nominations.created_on%TYPE , p_return_error OUT VARCHAR2 , p_nom_table IN efno_rules.nom_validation_table ) RETURN BOOLEAN IS PRAGMA AUTONOMOUS_TRANSACTION; -- -- Cursor to get the value for the given previous nomination and CONP COCA pair from the nnpcv_tab CURSOR c_nnpcv( cp_conp_id IN NUMBER , cp_coca_id IN NUMBER ) IS SELECT nnpcv1.value value , nnpcv1.gas_day gas_day , cnp2.nepo_id nepo_id FROM nom_net_point_cat_vals nnpcv1 ,cont_network_points cnp1 ,cont_network_points cnp2 ,contract_categories cc1 ,contract_categories cc2 WHERE nnpcv1.nomi_id = p_nomi_id AND cc1.cate_id = cc2.cate_id AND cc1.coca_id = cp_coca_id AND cc2.coca_id = nnpcv1.coca_id AND cnp1.nepo_id = cnp2.nepo_id AND cnp1.conp_id = cp_conp_id AND cnp2.conp_id = nnpcv1.conp_id AND nnpcv1.gas_day = ( SELECT MAX( nnpcv2.gas_day ) FROM nom_net_point_cat_vals nnpcv2 WHERE nnpcv2.nomi_id = p_nomi_id ); -- l_value nom_net_point_cat_vals.value%TYPE; l_gas_day nom_net_point_cat_vals.gas_day%TYPE; l_success BOOLEAN := TRUE; l_nepo_id network_points.nepo_id%TYPE; -- BEGIN -- caco_debug.putline('SP_CONF: upd_cnpcv_vals_with_nom 001'); -- SAVEPOINT before_upd_cnpcv; -- -- Loop through the nnpcv tab and update CNPCV with the nom values IF NVL(p_nnpcv_tab.COUNT,0) > 0 THEN -- <> FOR i IN 1..p_nnpcv_tab.COUNT LOOP -- IF p_nnpcv_tab(i).in_error THEN -- -- Only update if the row is in error -- l_value := 0; -- -- Get the value for the specific conp and coca for the given nomination -- for the latest gas day in the valid nomination -- OPEN c_nnpcv( p_nnpcv_tab(i).conp_id , p_nnpcv_tab(i).coca_id ); FETCH c_nnpcv INTO l_value, l_gas_day, l_nepo_id; IF c_nnpcv%NOTFOUND THEN CLOSE c_nnpcv; -- NULL; -- ELSE -- CLOSE c_nnpcv; -- IF p_nom_table.COUNT > 0 THEN -- <> FOR n IN 1..p_nom_table.COUNT LOOP -- IF p_nom_table(n).nr_nepo_id = l_nepo_id AND p_nom_table(n).nr_valid THEN -- -- Update the conf_net_point_cat_vals table with the found and provided values -- caco_debug.putline('Update confimation for: '||p_nnpcv_tab(i).conp_id); -- caco_debug.putline('UPDATE!'||l_value); -- caco_debug.putline('DEBUG4'); UPDATE conf_net_point_cat_vals SET last_nom_received = p_nomi_date , last_nomi_id = p_nomi_id , last_coru_id = p_coru_id , last_gas_day = l_gas_day , value = l_value WHERE conf_id = p_conf_id AND conp_id = p_nnpcv_tab(i).conp_id AND coca_id = p_nnpcv_tab(i).coca_id; -- IF SQL%ROWCOUNT = 0 THEN -- l_success := FALSE; p_return_error := caco_utilities.get_module_text(2212); -- An unexpected error has occurred while creating confirmation. Please contact support caco_debug.putline('efno_confirmations.upd_cnpcv_vals_with_nom: Unable to UPDATE conf_net_point_cat_vals : ' ||' CONF_ID : '||p_conf_id ||' CONP_ID : '||p_nnpcv_tab(i).conp_id ||' COCA_ID : '||p_nnpcv_tab(i).coca_id ||sqlerrm(sqlcode)); -- ROLLBACK TO SAVEPOINT before_upd_cnpcv; EXIT cnpcv_update_loop; -- ELSE -- p_nnpcv_tab(i).in_error := FALSE; -- END IF; -- -- Update the rest of the values -- caco_debug.putline('DEBUG5'); UPDATE conf_net_point_cat_vals c SET ( last_nom_received , last_nomi_id , last_coru_id , last_gas_day , value ) = ( SELECT p_nomi_date ,p_nomi_id ,p_coru_id ,l_gas_day ,nn.value FROM nominations n ,nom_net_point_cat_vals nn ,cont_network_points cnp1 ,cont_network_points cnp2 ,contract_categories cc1 ,contract_categories cc2 WHERE nn.nomi_id = n.nomi_id AND n.nomi_id = p_nomi_id AND nn.coca_id = cc1.coca_id AND nn.conp_id = cnp1.conp_id AND c.coca_id = cc2.coca_id AND c.conp_id = cnp2.conp_id AND cnp1.nepo_id = cnp2.nepo_id AND cc1.cate_id = cc2.cate_id AND nn.gas_day = ( SELECT MAX( nnpcv2.gas_day ) FROM nom_net_point_cat_vals nnpcv2 WHERE nnpcv2.nomi_id = p_nomi_id ) ) WHERE c.conf_id = p_conf_id AND c.coca_id <> p_nnpcv_tab(i).coca_id AND c.conp_id = p_nnpcv_tab(i).conp_id AND EXISTS ( SELECT NULL FROM nom_net_point_cat_vals nz1 ,cont_network_points cnpz1 ,cont_network_points cnpz2 ,contract_categories ccz1 ,contract_categories ccz2 WHERE nz1.nomi_id = p_nomi_id AND nz1.coca_id = ccz1.coca_id AND nz1.conp_id = cnpz1.conp_id AND cnpz1.nepo_id = cnpz2.nepo_id AND ccz1.cate_id = ccz2.cate_id AND cnpz2.conp_id = c.conp_id AND ccz2.coca_id = c.coca_id AND nz1.value IS NOT NULL); -- -- Now we need to update all other values to zero -- caco_debug.putline('DEBUG7'); UPDATE conf_net_point_cat_vals SET last_nom_received = p_nomi_date , last_nomi_id = p_nomi_id , last_coru_id = p_coru_id , last_gas_day = l_gas_day , value = 0 , defaulted = 'N' WHERE conf_id = p_conf_id AND conp_id = p_nnpcv_tab(i).conp_id AND last_nom_received IS NULL; -- END IF; -- END LOOP; -- END IF; -- END IF; -- END IF; -- END LOOP cnpcv_update_loop; -- -- END IF; -- COMMIT; caco_debug.putline('SP_CONF: upd_cnpcv_vals_with_nom 999'); RETURN l_success; -- END upd_cnpcv_vals_with_nom; -- -- -- -- /** -- FUNCTION evaluate_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_nom_data_table ); -- -- To parse a Rule for a specified contract template -- l_boolean := validate_rule( 12, 'ROW', TRUE, l_dummy_nom_data_table, 1 ); -- -- To parse a Rule for a specified contract -- l_boolean := validate_rule( 12, 'ROW', TRUE, l_dummy_nom_data_table, p_contract_id => 2 ); -- OR l_boolean := validate_rule( 12, 'ROW', TRUE, 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_nom_data_table, p_contract_id => 2, p_nomination_id => 3 ); -- OR l_boolean := validate_rule( 12, 'ROW', FALSE, 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_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 evaluate_rule ( p_rule_id IN rules.rule_id%TYPE , p_rule_type IN VARCHAR2 , p_conf_id IN confirmations.conf_id%TYPE , p_gas_day IN DATE , p_nnpcv_tab OUT nnpcv_tab , p_contract_id IN contracts.cont_id%TYPE DEFAULT 0 , p_nomination_id IN nominations.nomi_id%TYPE DEFAULT 0 , p_return_error OUT VARCHAR2 ) 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 (our Confirmation copy of it) -- (sheet based rules can only work against a single day nomination) CURSOR c_sheet_nom IS SELECT gas_day FROM conf_net_point_cat_vals WHERE conf_id = p_conf_id AND ROWNUM = 1; -- -- Cursor to get the specific Network Points for the given nomination confirmation -- 9/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 , conp.display_sequence display_sequence , conp.conp_id FROM conf_net_point_cat_vals cnpcv , cont_network_points conp , network_points nepo WHERE cnpcv.conf_id = p_conf_id AND cnpcv.conp_id = conp.conp_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 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_left_side_value NUMBER := 0; l_left_error VARCHAR2(255) := 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_right_side_value NUMBER := 0; l_right_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; invalid_row_rules BOOLEAN := FALSE; -- l_element_count NUMBER := 0; -- l_nom_sites_count NUMBER := 0; -- BEGIN -- -- Get the rule information caco_debug.putline('SP_CONF: evaluate_rule 001'); -- l_element_count := NVL(p_nnpcv_tab.COUNT, 0); -- 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; -- -- Get the specific gas day for the SHEET rule OPEN c_sheet_nom; FETCH c_sheet_nom INTO l_gas_day; -- IF c_sheet_nom%NOTFOUND THEN l_success := FALSE; p_return_error := caco_utilities.get_module_text(2267); -- Invalid Nomination - Gas Day not found. Please contact support END IF; CLOSE c_sheet_nom; -- END IF; -- IF rule_found AND l_success THEN -- -- 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 := efno_rules.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_conf_id => p_conf_id , p_force_conf => TRUE , p_return_error => l_left_error ); -- -- Process/validate the Right side right_is_valid := efno_rules.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_conf_id => p_conf_id , p_force_conf => TRUE , p_return_error => l_right_error ); -- IF l_left_error IS NOT NULL THEN p_return_error := l_left_error; ELSIF l_right_error IS NOT NULL THEN p_return_error := l_right_error; END IF; -- IF left_is_valid AND right_is_valid AND p_return_error IS NULL 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; -- -- 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 ); -- -- There should be only a single returned value from each side of the rule efno_rules.evaluate_rule_sql( l_left_sql , l_success , l_no_data , l_left_side_value ); -- IF l_success THEN -- -- Not worth doing this unless the left side was a success! efno_rules.evaluate_rule_sql( l_right_sql , l_success , l_no_data , l_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 NOT efno_rules.rule_test_passed( l_left_side_value , l_right_side_value , l_rule_row.rule_relation ) THEN -- l_success := FALSE; -- END IF; -- END IF; -- ELSE -- Either the left side or the right side of the rule is invalid - how much should we report? -- If p_return_error is NULL then we have missing nnpcv records (contract changed) -- Need to check for this in the calling package. -- -- Set the gas day in the nnpcv_tab for sheet nominations -- (Row rules automatically have to do this) IF NVL(p_nnpcv_tab.COUNT,0) > 0 THEN FOR i IN 1..p_nnpcv_tab.COUNT LOOP p_nnpcv_tab(i).gas_day := l_gas_day; END LOOP; END IF; -- l_success := FALSE; -- END IF; -- ELSE -- Row Rules -- 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('Row Nom Loop: '||r.network_point); END LOOP; <> FOR r IN c_row_nom LOOP -- caco_debug.putline('c_row_nom'); -- l_nom_sites_count := l_nom_sites_count + 1; left_is_valid := FALSE; right_is_valid := FALSE; -- l_no_data := FALSE; l_left_sql := NULL; l_right_sql := NULL; l_left_error := NULL; l_right_error := NULL; -- left_is_valid := efno_rules.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_conf_id => p_conf_id , p_nomination_id => p_nomination_id , p_net_point_id => r.network_point , p_gas_day => p_gas_day , p_force_conf => TRUE , p_return_error => l_left_error ); -- -- Process/validate the Right side right_is_valid := efno_rules.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_conf_id => p_conf_id , p_nomination_id => p_nomination_id , p_net_point_id => r.network_point , p_gas_day => p_gas_day , p_force_conf => TRUE , p_return_error => l_right_error ); -- IF l_left_error IS NOT NULL THEN p_return_error := l_left_error; ELSIF l_right_error IS NOT NULL THEN p_return_error := l_right_error; END IF; -- IF left_is_valid AND right_is_valid AND p_return_error IS NULL 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(p_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 ); -- -- Get the fully evaluated Numeric Value of each side of the rule -- for the given information and this specific network point efno_rules.evaluate_rule_sql( l_left_sql , l_success , l_no_data , l_left_side_value ); -- -- IF l_success THEN -- Not worth doing this unless the left side was a success! efno_rules.evaluate_rule_sql( l_right_sql , l_success , l_no_data , l_right_side_value ); -- END IF; -- IF NOT l_success THEN -- Exit Loop as the rule won't validate... caco_debug.putline('EXIT 1'); -- EXIT row_nom_loop2; END IF; -- IF NOT efno_rules.rule_test_passed( l_left_side_value , l_right_side_value , l_rule_row.rule_relation ) THEN -- l_success := FALSE; -- FOR i IN l_element_count+1..p_nnpcv_tab.COUNT LOOP -- IF p_nnpcv_tab(i).conp_id = r.conp_id THEN p_nnpcv_tab(i).in_error := TRUE; caco_debug.putline('Element '||i||' in error'); END IF; -- IF p_nnpcv_tab(i).in_error IS NULL THEN -- p_nnpcv_tab(i).in_error := FALSE; -- END IF; -- END LOOP; -- END IF; -- -- ELSIF p_return_error IS NULL THEN -- Dont want to Exit Loop even though the rule won't validate... -- we need to check for every network point before failing invalid_row_rules := TRUE; -- ELSE -- Exit the loop - something went wrong that we havent dealt with l_success := FALSE; caco_debug.putline('EXIT 2'); EXIT row_nom_loop2; -- 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 -- caco_debug.putline('Eval without nomination'); -- IF p_nomination_id IS NULL 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 := efno_rules.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_conf_id => p_conf_id , p_force_conf => TRUE , p_return_error => l_left_error ); -- -- Process/validate the Right side right_is_valid := efno_rules.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_conf_id => p_conf_id , p_force_conf => TRUE , p_return_error => l_right_error ); -- IF l_left_error IS NOT NULL THEN p_return_error := l_left_error; ELSIF l_right_error IS NOT NULL THEN p_return_error := l_right_error; END IF; -- IF left_is_valid AND right_is_valid AND p_return_error IS NULL 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; -- -- 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 ); -- -- There should be only a single returned value from each side of the rule efno_rules.evaluate_rule_sql( l_left_sql , l_success , l_no_data , l_left_side_value ); -- IF l_success THEN -- -- Not worth doing this unless the left side was a success! efno_rules.evaluate_rule_sql( l_right_sql , l_success , l_no_data , l_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 NOT efno_rules.rule_test_passed( l_left_side_value , l_right_side_value , l_rule_row.rule_relation ) THEN -- l_success := FALSE; -- END IF; -- END IF; -- ELSE -- Either the left side or the right side of the rule is invalid - how much should we report? -- If p_return_error is NULL then we have missing nnpcv records (contract changed) -- Need to check for this in the calling package. -- -- Set the gas day in the nnpcv_tab for sheet nominations -- (Row rules automatically have to do this) IF NVL(p_nnpcv_tab.COUNT,0) > 0 THEN FOR i IN 1..p_nnpcv_tab.COUNT LOOP p_nnpcv_tab(i).gas_day := l_gas_day; END LOOP; END IF; -- l_success := FALSE; -- END IF; -- ELSE -- Row Rules -- 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('c_row_nom2 nepo:'||r.network_point); -- l_nom_sites_count := l_nom_sites_count + 1; left_is_valid := FALSE; right_is_valid := FALSE; -- l_no_data := FALSE; l_left_sql := NULL; l_right_sql := NULL; l_left_error := NULL; l_right_error := NULL; -- left_is_valid := efno_rules.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_conf_id => p_conf_id , p_nomination_id => p_nomination_id , p_net_point_id => r.network_point , p_gas_day => p_gas_day , p_force_conf => TRUE , p_return_error => l_left_error ); -- -- Process/validate the Right side right_is_valid := efno_rules.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_conf_id => p_conf_id , p_nomination_id => p_nomination_id , p_net_point_id => r.network_point , p_gas_day => p_gas_day , p_force_conf => TRUE , p_return_error => l_right_error ); -- IF l_left_error IS NOT NULL THEN p_return_error := l_left_error; ELSIF l_right_error IS NOT NULL THEN p_return_error := l_right_error; END IF; -- IF left_is_valid AND right_is_valid AND p_return_error IS NULL 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(p_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 ); --caco_debug.putline('Right: '|| l_right_sql); --caco_debug.putline('Left: '|| l_left_sql); -- -- Get the fully evaluated Numeric Value of each side of the rule -- for the given information and this specific network point efno_rules.evaluate_rule_sql( l_left_sql , l_success , l_no_data , l_left_side_value ); -- -- IF l_success THEN -- Not worth doing this unless the left side was a success! caco_debug.putline('Eval right'); efno_rules.evaluate_rule_sql( l_right_sql , l_success , l_no_data , l_right_side_value ); -- END IF; -- IF NOT l_success THEN -- Exit Loop as the rule won't validate... caco_debug.putline('Rule not valid - EXIT1'); -- EXIT row_nom_loop; END IF; -- caco_debug.putline(l_left_side_value||l_rule_row.rule_relation||l_right_side_value); IF NOT efno_rules.rule_test_passed( l_left_side_value , l_right_side_value , l_rule_row.rule_relation ) THEN -- -- Leave this in as it doesn't work without -- l_success := FALSE; -- FOR i IN l_element_count+1..p_nnpcv_tab.COUNT LOOP -- IF p_nnpcv_tab(i).conp_id = r.conp_id THEN p_nnpcv_tab(i).in_error := TRUE; caco_debug.putline('Element '||i||' in error'); END IF; -- END LOOP; -- END IF; -- ELSIF p_return_error IS NULL THEN -- Dont want to Exit Loop even though the rule won't validate... -- we need to check for every network point before failing invalid_row_rules := TRUE; caco_debug.putline('**INVALID ROW RULES**'); -- ELSE -- Exit the loop - something went wrong that we havent dealt with l_success := FALSE; caco_debug.putline('EXIT2'); 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; -- END IF; END IF; -- ELSIF NOT rule_found THEN -- No rule found l_success := FALSE; p_return_error := caco_utilities.get_module_text(2433); -- Rule not found. Please contact support -- END IF; -- IF invalid_row_rules THEN l_success := FALSE; END IF; -- caco_debug.putline('SP_CONF: evaluate_rule 999'); RETURN l_success; -- EXCEPTION WHEN others THEN l_success := FALSE; p_return_error := caco_utilities.get_module_text(3581); -- Error caco_debug.putline('efno_confirmations.evaluate_rule - : Error : '||sqlerrm(sqlcode)); -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => 'Unexpected Error: '||sqlerrm(sqlcode) ||chr(10)||'NOMI_ID: '||p_nomination_id ||'Failed evaluating rules ' ||'for gas day : '||TO_CHAR(p_gas_day,'DD-MON-YYYY') , p_source => 'efno_confirmations.evaluate_rule'); -- END evaluate_rule; -- -- -- -- FUNCTION fix_nom_with_lookback( p_conf_id IN confirmations.conf_id%TYPE , p_gas_day IN DATE , p_nomination_row IN nominations%ROWTYPE , p_contract_id IN contracts.cont_id%TYPE , p_rule_record IN efno_contracts.contract_rules_rec , p_lookback_date IN DATE , p_exception IN contracts.validation_exception%TYPE , p_lookback_action IN contracts.lookback_action%TYPE , p_nnpcv_tab IN nnpcv_tab , p_return_error OUT VARCHAR2 ) RETURN BOOLEAN IS -- Require a cursor to list all "tip" nominations for the contract CURSOR c_nominations( cp_last_nomi_date IN DATE , cp_lookback_action IN VARCHAR2 ) IS SELECT nomi.nomi_id , nomi.created_on , nomi.status , cont1.cust_id FROM nominations nomi ,contracts cont1 WHERE nomi.cont_id = cont1.cont_id AND cont1.cont_id IN (SELECT cont2.cont_id FROM contracts cont2 CONNECT BY PRIOR cont2.prev_cont_id = cont2.cont_id START WITH cont2.cont_id = p_contract_id) AND ( nomi.nomi_id < p_nomination_row.nomi_id OR p_nomination_row.nomi_id IS NULL ) AND EXISTS ( SELECT NULL FROM nom_net_point_cat_vals nnpcv WHERE nnpcv.nomi_id = nomi.nomi_id GROUP BY nnpcv.gas_day HAVING MIN(nnpcv.gas_day) <= (SELECT gas_day FROM confirmations WHERE conf_id = p_conf_id) AND MIN(nnpcv.gas_day) >= p_lookback_date ) AND ( ( nomi.status = 'A' -- 'A' will be the TIP each day AND cp_lookback_action = 'T' AND ( nomi_id IN ((SELECT nomi_id FROM ( SELECT DISTINCT n.nomi_id, n.gas_day, no.created_on, RANK() OVER (partition by gas_day ORDER BY gas_day, no.created_on DESC) nom_rank FROM nom_net_point_cat_vals n ,nominations no ,contracts c WHERE n.nomi_id = no.nomi_id AND no.cont_id = c.cont_id AND c.cont_id IN (SELECT c2.cont_id FROM contracts c2 CONNECT BY PRIOR c2.prev_cont_id = c2.cont_id START WITH c2.cont_id = p_contract_id) ) WHERE nom_rank = 1)) ) ) OR ( cp_lookback_action = 'A' ) ) ORDER BY ( SELECT MIN(nnpcv.gas_day) FROM nom_net_point_cat_vals nnpcv WHERE nnpcv.nomi_id = nomi.nomi_id ) DESC, nomi.created_on DESC; /* SELECT nomi.nomi_id , nomi.created_on , nomi.status , cont1.cust_id FROM nominations nomi ,contracts cont1 ,contracts cont2 WHERE nomi.cont_id = cont1.cont_id AND cont1.cust_id = cont2.cust_id AND cont2.cont_id = p_contract_id AND ( nomi.nomi_id < p_nomination_row.nomi_id OR p_nomination_row.nomi_id IS NULL ) AND EXISTS ( SELECT NULL FROM nom_net_point_cat_vals nnpcv WHERE nnpcv.nomi_id = nomi.nomi_id GROUP BY nnpcv.gas_day HAVING MIN(nnpcv.gas_day) <= (SELECT gas_day FROM confirmations WHERE conf_id = p_conf_id) AND MIN(nnpcv.gas_day) >= p_lookback_date ) AND ( ( nomi.status = 'A' -- 'A' will be the TIP each day AND cp_lookback_action = 'T' AND ( nomi_id IN ((SELECT nomi_id FROM ( SELECT DISTINCT n.nomi_id, n.gas_day, no.created_on, RANK() OVER (partition by gas_day ORDER BY gas_day, no.created_on DESC) nom_rank FROM nom_net_point_cat_vals n ,nominations no ,contracts c ,contracts c2 WHERE n.nomi_id = no.nomi_id AND no.cont_id = c.cont_id AND c.cust_id = c2.cust_id AND c2.cont_id = p_contract_id ) WHERE nom_rank = 1)) ) ) OR ( cp_lookback_action = 'A' ) ) ORDER BY ( SELECT MIN(nnpcv.gas_day) FROM nom_net_point_cat_vals nnpcv WHERE nnpcv.nomi_id = nomi.nomi_id ) DESC, nomi.created_on DESC; */ -- -- Cursor to lookup the current status of the CNPCV value CURSOR c_cnpcv_val( cp_conp_id IN NUMBER , cp_coca_id IN NUMBER , cp_gas_day IN DATE ) IS SELECT cnpcv.* FROM conf_net_point_cat_vals cnpcv ,cont_network_points t ,cont_network_points t2 ,contract_categories c ,contract_categories c2 WHERE cnpcv.conf_id = p_conf_id AND t2.conp_id = cnpcv.conp_id AND t.conp_id = cp_conp_id AND t.nepo_id = t2.nepo_id AND c.cate_id = c2.cate_id AND c2.coca_id = cnpcv.coca_id AND c.coca_id = cp_coca_id AND gas_day = cp_gas_day; -- -- Cursor to get the days before figure that the nominations can be input CURSOR c_days_before IS SELECT receive_before_start FROM contracts WHERE cont_id = p_contract_id; -- l_cnpcv_val_rec c_cnpcv_val%ROWTYPE; -- l_temp_rule_id rules.rule_id%TYPE; -- l_nom_table efno_rules.nom_validation_table; l_dummy_nnpcv_tab nnpcv_tab; l_nnpcv_tab nnpcv_tab; l_days_before NUMBER := 0; l_oldest_nom_date DATE; -- values_defaulted BOOLEAN := FALSE; found_valid_nom BOOLEAN := FALSE; -- l_success BOOLEAN := TRUE; -- BEGIN -- -- Get local copy to allow valid/invalid to be updated -- --caco_debug.debug_on; caco_debug.putline('SP_CONF: fix_nom_with_lookback 001'); l_nnpcv_tab := p_nnpcv_tab; -- FOR i IN 1..l_nnpcv_tab.COUNT LOOP caco_debug.putline('*'||l_nnpcv_tab(i).conp_id||'-'||sys.diutil.bool_to_int(l_nnpcv_tab(i).in_error)); END LOOP; -- caco_debug.putline('Enter fix with lookback'); -- -- Work out the temp_rule (to pass to "evaluate_rule" -- IF p_rule_record.rule_type = 'SHEET' THEN l_temp_rule_id := p_rule_record.coru_id; ELSE l_temp_rule_id := p_rule_record.rule_id; END IF; -- -- Get the Days before figure to add to sysdate to default the "oldest Nom date" -- OPEN c_days_before; FETCH c_days_before INTO l_days_before; CLOSE c_days_before; -- l_oldest_nom_date := SYSDATE + l_days_before; -- -- We know the current nomination is invalid - and that it affects the given -- nomination categories values within the p_nnpcv_tab. -- So we need to find a previous nomination that still satisfies the given rule -- If we cant find a previous nomination within the lookback window that satisifies -- the given rule then we need to default the category values to the validation_exception -- type - which will be the contracted value or the minimum. -- -- The values that satisfy the given rule should be placed onto the conf_net_point_cat_vals table -- -- We need to check if we have already updated the nom values previously -- Get the oldest nomination id and date created for each of the items -- IF NVL(l_nnpcv_tab.COUNT,0) > 0 THEN -- <> FOR i IN 1..l_nnpcv_tab.COUNT LOOP -- OPEN c_cnpcv_val( l_nnpcv_tab(i).conp_id , l_nnpcv_tab(i).coca_id , l_nnpcv_tab(i).gas_day ); FETCH c_cnpcv_val INTO l_cnpcv_val_rec; IF c_cnpcv_val%NOTFOUND THEN CLOSE c_cnpcv_val; -- problem -- cant fix the value if it isn't found - this should never happen. l_success := FALSE; p_return_error := caco_utilities.get_module_text(2315); -- Unable to locate required data. Please contact support caco_debug.putline('efno_confirmations.fix_nom_with_lookback: Unable to locate data in conf_net_point_cat_vals: ' ||' CONF_ID : '||p_conf_id ||' CONP_ID : '||l_nnpcv_tab(i).conp_id ||' COCA_ID : '||l_nnpcv_tab(i).coca_id ); EXIT cnpcv_lookup_loop; -- ELSE CLOSE c_cnpcv_val; -- -- Check to see if the CNPCV value has already been defaulted IF l_cnpcv_val_rec.defaulted = 'Y' THEN -- caco_debug.putline('values have been defaulted'); values_defaulted := TRUE; -- ELSIF NVL(l_cnpcv_val_rec.last_nom_received, SYSDATE + l_days_before) < l_oldest_nom_date THEN -- caco_debug.putline('oldest nom date : '||to_char(l_oldest_nom_date,'DD-MON-YYYY HH24:MI:SS') ||' : Last nom received : ' ||to_char(l_cnpcv_val_rec.last_nom_received,'DD-MON-YYYY HH24:MI:SS')); -- Set the oldest nom date to be the oldest date already used to set a value l_oldest_nom_date := l_cnpcv_val_rec.last_nom_received; -- END IF; -- END IF; END LOOP cnpcv_lookup_loop; -- END IF; -- IF l_success THEN -- now we can loop through the previous tip nominations and see if any of them are valid IF values_defaulted THEN -- -- We should just default each of the categories in the list as at least one of them -- has already been defaulted to either the MIN or CTR value -- Call the routine to default the values for the categories in our table l_success := default_cnpcv_values( p_gas_day , p_conf_id , l_nnpcv_tab , p_exception , p_return_error ); -- ELSE caco_debug.putline('cp_last_nomi_date: '||l_oldest_nom_date||' lookback_date: '||p_lookback_date||' action: '||NVL(p_lookback_action, 'A')); caco_debug.putline('Contract: '||p_contract_id||' Nomi : '||p_nomination_row.nomi_id||' conf: '||p_conf_id); -- We should look back for a valid value from a previous nomination if there is one... <> FOR r IN c_nominations( l_oldest_nom_date , NVL(p_lookback_action, 'A')) LOOP -- caco_debug.putline('we have a nom to look back at: nomi_id = '||r.nomi_id); -- l_nom_table.DELETE; -- -- We want to validate the nomination - not force the confirmation here..... -- <> FOR rec_nom_lookback_gas_day IN (SELECT gas_day FROM (SELECT gas_day FROM nom_net_point_cat_vals WHERE nomi_id = r.nomi_id GROUP BY gas_day) ORDER BY gas_day DESC) LOOP found_valid_nom := efno_rules.validate_rule_conf( p_gas_day => rec_nom_lookback_gas_day.gas_day -- p_gas_day , p_rule_id => l_temp_rule_id , p_rule_type => p_rule_record.rule_type , p_parse_only => FALSE , p_nnpcv_tab => l_nnpcv_tab , p_nom_table => l_nom_table , p_contract_id => p_contract_id , p_nomination_id => r.nomi_id); -- IF found_valid_nom THEN EXIT nom_lookback_gas_day_loop; END IF; END LOOP; -- --caco_debug.debug_on; FOR i IN 1..l_nnpcv_tab.COUNT LOOP caco_debug.putline('*'||l_nnpcv_tab(i).conp_id||'-'||sys.diutil.bool_to_int(l_nnpcv_tab(i).in_error)); END LOOP; -- caco_debug.putline('RETURN FROM efno_rules.evaluate_rules:'||l_nom_table.COUNT||':'||l_nnpcv_tab.COUNT); -- IF NVL(l_nom_table.COUNT,0) > 0 THEN -- found_valid_nom := FALSE; -- <> FOR i IN 1..l_nom_table.COUNT LOOP -- caco_debug.putline('Value returned: '||l_nom_table(i).nr_nepo_id||':'||sys.diutil.bool_to_int(l_nom_table(i).nr_valid)); -- IF l_nom_table(i).nr_valid THEN found_valid_nom := TRUE; EXIT nom_loop; END IF; -- END LOOP nom_loop; -- END IF; -- IF found_valid_nom THEN -- caco_debug.putline('Update nominated values'); -- -- Put the details of this nomination (l_lookback_nnpcv_tab) onto the p_nnpcv_tab entries -- l_success := upd_cnpcv_vals_with_nom( p_conf_id => p_conf_id , p_nnpcv_tab => l_nnpcv_tab , p_coru_id => p_rule_record.coru_id , p_nomi_id => r.nomi_id , p_nomi_date => r.created_on , p_return_error => p_return_error , p_nom_table => l_nom_table ); -- -- Exit the loop - we got good values for the cnpcv_id's.. -- so there is no point looking back any further. -- -- EXIT nom_lookback_loop; -- END IF; -- END LOOP nom_lookback_loop; -- -- Now look to see if we still have any invalid values left over -- IF l_nnpcv_tab.COUNT > 0 THEN -- <> FOR j IN 1..l_nnpcv_tab.COUNT LOOP -- IF l_nnpcv_tab(j).in_error THEN -- found_valid_nom := FALSE; -- EXIT l_nnpcv_loop; -- END IF; -- END LOOP; -- END IF; -- -- Did we find a valid nomination? If not, we need to default the values -- IF NOT found_valid_nom THEN -- caco_debug.putline('No valid nominations'); -- Call the routine to default the values for the categories in our table l_success := default_cnpcv_values( p_gas_day , p_conf_id , l_nnpcv_tab , p_exception , p_return_error , TRUE ); -- END IF; -- END IF; -- values defaulted or not -- END IF; --successful GTT lookups -- caco_debug.putline('SP_CONF: fix_nom_with_lookback 999'); RETURN l_success; -- END fix_nom_with_lookback; -- FUNCTION fetch_contract_number( p_nomi_id IN nominations.nomi_id%TYPE ) RETURN VARCHAR2 IS CURSOR c_cont IS SELECT cont.contract_number FROM contracts cont , nominations nomi WHERE nomi.cont_id = cont.cont_id AND nomi.nomi_id = p_nomi_id; -- l_contract_number contracts.contract_number%TYPE := NULL; -- BEGIN -- OPEN c_cont; FETCH c_cont INTO l_contract_number; CLOSE c_cont; -- RETURN l_contract_number; -- END fetch_contract_number; -- FUNCTION fetch_nom_identifier( p_nomi_id IN nominations.nomi_id%TYPE ) RETURN VARCHAR2 IS CURSOR c_nomi IS SELECT identifier FROM nominations WHERE nomi_id = p_nomi_id; -- l_identifier nominations.identifier%TYPE := NULL; -- BEGIN -- OPEN c_nomi; FETCH c_nomi INTO l_identifier; CLOSE c_nomi; -- RETURN l_identifier; -- END fetch_nom_identifier; -- FUNCTION force_validate_cnpcv_nom( p_conf_id IN confirmations.conf_id%TYPE , p_nomination_row IN nominations%ROWTYPE , p_contract_id IN contracts.cont_id%TYPE , p_gas_day IN DATE , p_replace IN BOOLEAN DEFAULT FALSE , p_ignore IN BOOLEAN DEFAULT FALSE , p_window IN contracts.validation_window%TYPE DEFAULT 0 , p_exception IN contracts.validation_exception%TYPE DEFAULT NULL , p_lookback_action IN contracts.lookback_action%TYPE DEFAULT NULL , p_validation_action IN contracts.validation_action%TYPE DEFAULT NULL , p_return_error OUT VARCHAR2 ) RETURN BOOLEAN IS -- l_lookback_date DATE; l_rule_record efno_contracts.contract_rules_rec; l_temp_rule rules.rule_id%TYPE; l_nnpcv_tab nnpcv_tab; rule_valid BOOLEAN := TRUE; nom_invalid BOOLEAN := FALSE; missing_nnpcv BOOLEAN := FALSE; -- l_success BOOLEAN := TRUE; -- l_count_rules NUMBER := 0; -- BEGIN caco_debug.putline('SP_CONF: force_validate_cnpcv_nom 001'); -- Check we have permission to be using this module. /* IF NOT caco_security.security_check('efnow095$') THEN p_return_error := caco_utilities.get_module_text(960); -- You do not have permission to use this application RETURN FALSE; END IF; */ -- -- The full lookback date is the confirmation gas day minus the lookback window l_lookback_date := p_gas_day - p_window; -- caco_debug.putline('Lookback window date is : '||to_char(l_lookback_date,'DD-MON-YYYY')); -- -- Need to loop through the contract rules and validate the nomination held in the global temporary table -- If a rule fails, we need to perform the appropriate action as depicted by the received parameters -- If we are truncating values to Max then we complete all rules -- If we are looking back for a validation window, we fix the failed rule and exit -- OPEN efno_contracts.c_rules( p_contract_id ); FETCH efno_contracts.c_rules INTO l_rule_record; -- <> WHILE efno_contracts.c_rules%FOUND LOOP -- l_count_rules := l_count_rules + 1; l_temp_rule := 0; l_nnpcv_tab.DELETE; -- IF l_rule_record.rule_type = 'SHEET' THEN l_temp_rule := l_rule_record.coru_id; ELSE l_temp_rule := l_rule_record.rule_id; END IF; -- rule_valid := evaluate_rule( l_temp_rule , l_rule_record.rule_type , p_conf_id , p_gas_day , l_nnpcv_tab , p_contract_id , p_nomination_row.nomi_id , p_return_error ); -- caco_debug.putline('Z0 post evaluate rule: '||p_return_error||':bool:'||sys.diutil.bool_to_int(rule_valid)); -- IF NOT rule_valid AND p_return_error IS NULL THEN -- Check to see if any of the nnpcv values were missing IF NVL(l_nnpcv_tab.COUNT,0) > 0 THEN <> FOR i IN 1..l_nnpcv_tab.COUNT LOOP -- IF l_nnpcv_tab(i).missing = 'Y' THEN missing_nnpcv := TRUE; EXIT missing_nnpcv_loop; END IF; -- END LOOP missing_nnpcv_loop; END IF; -- IF missing_nnpcv THEN -- caco_debug.putline('Have missing nnpcv so must create them : rule_type :' ||l_rule_record.rule_type||': rule/coru number : '||l_temp_rule); -- create_missing_cnpcv( p_conf_id => p_conf_id , p_nomi_id => p_nomination_row.nomi_id , p_nnpcv_tab => l_nnpcv_tab , p_exception => p_exception , p_validation_action => p_validation_action , p_success => l_success , p_return_error => p_return_error , p_cont_id => p_contract_id , p_lookback_date => l_lookback_date , p_lookback_action => p_lookback_action ); -- END IF; -- caco_debug.putline('Pre-lookback'); -- IF l_success THEN -- IF p_replace THEN -- caco_debug.putline('about to replace'); -- l_success := replace_cnpcv( p_conf_id , l_nnpcv_tab , p_exception , p_return_error ); -- IF NOT l_success THEN EXIT contract_rules_loop; END IF; -- ELSIF p_ignore THEN -- NULL; -- ELSE -- caco_debug.putline('about to fix nom with lookback'); -- l_success := fix_nom_with_lookback( p_conf_id , p_gas_day , p_nomination_row , p_contract_id , l_rule_record , l_lookback_date , p_exception , p_lookback_action , l_nnpcv_tab , p_return_error ); -- IF NOT l_success THEN EXIT contract_rules_loop; END IF; -- nom_invalid := TRUE; -- EXIT contract_rules_loop; -- commented 05/06 AG, not sure if this should be here? -- END IF; -- ELSIF p_return_error IS NOT NULL THEN -- Something went wrong in creating the missing cnpcv records -- We have to abandon the attempt nom_invalid := TRUE; EXIT contract_rules_loop; END IF; -- ELSIF p_return_error IS NOT NULL THEN -- Something went wrong in the force of the nomination -- We have to abandon the attempt nom_invalid := TRUE; EXIT contract_rules_loop; -- END IF; -- -- Fetch the next rule record FETCH efno_contracts.c_rules INTO l_rule_record; -- END LOOP contract_rules_loop; -- CLOSE efno_contracts.c_rules; -- caco_debug.putline('SP_CONF: force_validate_cnpcv_nom 999'); RETURN nom_invalid; -- END force_validate_cnpcv_nom; -- -- FUNCTION insert_comm_conf( p_nomi_id IN nominations.nomi_id%TYPE , p_cont_id IN contracts.cont_id%TYPE , p_gas_day IN DATE , p_conf_id OUT confirmations.conf_id%TYPE , p_return_error OUT VARCHAR2 ) RETURN BOOLEAN IS PRAGMA AUTONOMOUS_TRANSACTION; -- l_success BOOLEAN := TRUE; -- BEGIN -- caco_debug.putline('SP_CONF: insert_comm_conf 001'); -- SAVEPOINT before_insert; -- BEGIN INSERT INTO confirmations ( conf_id , confirmation_type , nomi_id , approved , cont_id , gas_day ) VALUES ( conf_seq.NEXTVAL , 'CO' , p_nomi_id , 'N' , p_cont_id , p_gas_day ) RETURNING conf_id INTO p_conf_id; -- COMMIT; -- EXCEPTION WHEN others THEN ROLLBACK TO SAVEPOINT before_insert; l_success := FALSE; p_return_error := caco_utilities.get_module_text(2330); -- An unexpected error has occurred. Please contact support caco_debug.putline('efno_confirmations.insert_comm_conf : NOMI_ID :' ||p_nomi_id||' : Error : '||sqlerrm(sqlcode)); -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => 'Insert failed : ' ||'NOMI_ID :'||p_nomi_id ||' : Error : '||sqlerrm(sqlcode) , p_source => 'efno_confirmations.insert_comm_conf'); -- END; -- caco_debug.putline('SP_CONF: insert_comm_conf 999'); RETURN l_success; -- END insert_comm_conf; -- -- -- -- FUNCTION update_comm_conf( p_conf_id IN confirmations.conf_id%TYPE , p_spreadsheet IN BLOB , p_conf_text IN CLOB , p_conf_type IN contract_options.conf_type%TYPE , p_return_error OUT VARCHAR2 ) RETURN BOOLEAN IS PRAGMA AUTONOMOUS_TRANSACTION; -- l_success BOOLEAN := TRUE; -- BEGIN SAVEPOINT before_update; -- BEGIN -- UPDATE confirmations conf SET conf.confirmation = p_spreadsheet , conf.confirmation_text = p_conf_text , conf.conf_file_type = p_conf_type WHERE conf_id = p_conf_id; -- COMMIT; -- EXCEPTION WHEN others THEN ROLLBACK TO SAVEPOINT before_update; l_success := FALSE; p_return_error := caco_utilities.get_module_text(2330); -- An unexpected error has occurred. Please contact support caco_debug.putline('efno_confirmations.update_comm_conf : CONF_ID :'||p_conf_id ||chr(10)||' : Error : '||sqlerrm(sqlcode)); -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => 'Update failed : ' ||'CONF_ID :'||p_conf_id||chr(10) ||' : Error : '||sqlerrm(sqlcode) , p_source => 'efno_confirmations.update_comm_conf'); -- END; -- RETURN l_success; -- END update_comm_conf; -- -- -- -- PROCEDURE clearup_failed_comm_conf( p_conf_id IN confirmations.conf_id%TYPE ) IS PRAGMA AUTONOMOUS_TRANSACTION; BEGIN -- DELETE conf_net_point_cat_vals WHERE conf_id = p_conf_id; -- DELETE confirmations WHERE conf_id = p_conf_id; -- COMMIT; -- EXCEPTION WHEN others THEN ROLLBACK; caco_debug.putline('efno_confirmations.clearup_failed_comm_conf : CONF_ID :'||p_conf_id ||chr(10)||' : Error : '||sqlerrm(sqlcode)); -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => 'Failed to clear up commercial confirmation - this needs to be done manually : ' ||chr(10)||'CONF_ID :'||p_conf_id ||chr(10)||': Error : '||sqlerrm(sqlcode) , p_source => 'efno_confirmations.clearup_failed_comm_conf'); -- RAISE; END clearup_failed_comm_conf; -- -- -- -- -- -- FUNCTION copy_nom_to_cnpcv( p_conf_id IN confirmations.conf_id%TYPE , p_nomi_id IN nominations.nomi_id%TYPE , p_cont_id IN contracts.cont_id%TYPE , p_gas_day IN DATE , p_return_error OUT VARCHAR2 ) RETURN BOOLEAN IS PRAGMA AUTONOMOUS_TRANSACTION; -- CURSOR c_cnpcv IS SELECT p_conf_id conf_id , nnpcv_id nnpcv_id , value value , gas_day gas_day , c.coca_id coca_id , nomi_id nomi_id , t.conp_id conp_id FROM nom_net_point_cat_vals n ,cont_network_points t ,cont_network_points t2 ,contract_categories c ,contract_categories c2 WHERE n.nomi_id = p_nomi_id AND t.cont_id = p_cont_id AND t.nepo_id = t2.nepo_id AND t2.conp_id = n.conp_id AND c.cont_id = p_cont_id AND c.cate_id = c2.cate_id AND c2.coca_id = n.coca_id AND gas_day = p_gas_day; -- l_success BOOLEAN := TRUE; l_dummy VARCHAR2(100); l_value conf_net_point_cat_vals.value%TYPE; l_interrupted conf_net_point_cat_vals.interrupted%TYPE; -- BEGIN caco_debug.putline('SP_CONF: copy_nom_to_cnpcv 001'); caco_debug.putline('p_conf_id: '||p_conf_id); caco_debug.putline('p_nomi_id: '||p_nomi_id); caco_debug.putline('p_cont_id: '||p_cont_id); caco_debug.putline('p_gas_day: '||p_gas_day); SAVEPOINT before_insert; -- FOR r IN c_cnpcv LOOP -- check for an active interruption l_value := get_interrupted_value( r.conp_id , r.coca_id , r.gas_day ); -- /* IF l_value IS NULL THEN l_value := r.value; l_interrupted := 'N'; ELSE IF l_value > r.value THEN l_value := r.value; END IF; l_interrupted := 'Y'; END IF; */ -- removed 13/02 to stop interruptions taking priority IF l_value IS NOT NULL THEN l_interrupted := 'Y'; END IF; -- l_value := r.value; -- BEGIN INSERT INTO conf_net_point_cat_vals ( conf_id , nnpcv_id , value , gas_day , coca_id , nomi_id , conp_id , interrupted ) VALUES ( p_conf_id , r.nnpcv_id , l_value , r.gas_day , r.coca_id , r.nomi_id , r.conp_id , l_interrupted ); EXCEPTION WHEN others THEN ROLLBACK TO SAVEPOINT before_insert; l_success := FALSE; p_return_error := caco_utilities.get_module_text(2266); -- Internal error copying nomination detail records for confirmation. Please contact support caco_debug.putline('efno_confirmations.copy_nom_to_cnpcv - : NOMI_ID :'||p_nomi_id ||' : Error : '||sqlerrm(sqlcode)); -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => 'Unexpected Error: '||sqlerrm(sqlcode) ||chr(10)||'NOMI_ID: '||p_nomi_id ||'Failed inserting into conf_net_point_cat_vals ' ||'for gas day : '||TO_CHAR(p_gas_day,'DD-MON-YYYY') , p_source => 'efno_confirmations.copy_nom_to_cnpcv'); -- END; -- END LOOP; COMMIT; -- caco_debug.putline('SP_CONF: copy_nom_to_cnpcv 999'); RETURN l_success; -- END copy_nom_to_cnpcv; -- FUNCTION force_comm_conf( p_conf_id IN confirmations.conf_id%TYPE , p_nomination_row IN nominations%ROWTYPE , p_contract_row IN contracts%ROWTYPE , p_gas_day IN DATE , p_return_error OUT VARCHAR2 ) RETURN BOOLEAN IS -- nom_invalid BOOLEAN := TRUE; l_success BOOLEAN := TRUE; l_tip_nomi_id nominations.nomi_id%TYPE; l_cont_id_used contracts.cont_id%TYPE; l_nnpcv_tab nnpcv_tab; l_contract_row contracts%ROWTYPE; -- BEGIN caco_debug.putline('SP_CONF: force_comm_conf 001'); -- We know that the nomination didn't fully validate as we are having to force the confirmation -- Copy the nomination category values to a global temporary table IF p_nomination_row.nomi_id IS NOT NULL THEN -- -- -- l_success := copy_nom_to_cnpcv( p_conf_id , p_nomination_row.nomi_id , p_contract_row.cont_id , p_gas_day , p_return_error ); -- l_success := remove_surplus_cnpcv ( p_conf_id => p_conf_id , p_cont_id => p_contract_row.cont_id , p_return_error => p_return_error ); -- l_contract_row := p_contract_row; -- l_contract_row.validation_exception := 'EX'; -- l_success := add_missing_cnpcv ( p_conf_id => p_conf_id , p_nomi_id => p_nomination_row.nomi_id , p_contract_row => l_contract_row , p_gas_day => p_gas_day , p_return_error => p_return_error , p_defaulted => 'N' ); -- ELSE -- -- No nomination found, precreate the confirmation details (perhaps invalid?) -- IF p_contract_row.validation_action = 'B' THEN -- l_contract_row := p_contract_row; --caco_debug.putline('SP_CONF: force_comm_conf(setting to EX) 500'); -- l_contract_row.validation_exception := 'EX'; l_success := add_missing_cnpcv ( p_conf_id => p_conf_id , p_nomi_id => NULL , p_contract_row => l_contract_row , p_gas_day => p_gas_day , p_return_error => p_return_error , p_defaulted => 'N' ); -- END IF; -- END IF; --- -- Look below, if didn't have a nomi_id nothing happened -- as previously the condition above switches l_success to FALSE -- now we should have a nomi_id so the remainder should handle all the -- pitfalls of validating a nomination entered on one contract -- against another contract! --- -- -- Now we need to validate the nomination and mark the invalid category/ies IF l_success THEN -- -- So what here? -- We need to know what fails. -- -- IF l_contract_row.validation_action = 'I' -- I - leave Invalid -- Leave the nomination invalid - so nothing to do -- otherwise.... IF p_contract_row.validation_action = 'T' THEN -- T - Replace (with exception value) -- nom_invalid is throwaway here as we wont try to make the nomination valid -- we will just replace those values that are invalid to the specified value IF p_nomination_row.nomi_id IS NULL THEN -- -- If no nom, might as well do as we did before as there is nothing to look back at today -- nom_invalid := force_validate_cnpcv_nom( p_conf_id => p_conf_id , p_nomination_row => p_nomination_row , p_contract_id => p_contract_row.cont_id , p_gas_day => p_gas_day , p_replace => TRUE , p_return_error => p_return_error ); ELSE -- -- Fix with lookback for today only -- -- caco_debug.debug_on; caco_debug.putline('Lookback 0 days'); nom_invalid := force_validate_cnpcv_nom( p_conf_id => p_conf_id , p_nomination_row => p_nomination_row , p_contract_id => p_contract_row.cont_id , p_gas_day => p_gas_day , p_window => 0 , p_exception => p_contract_row.validation_exception , p_lookback_action => 'A' , p_validation_action => p_contract_row.validation_action , p_return_error => p_return_error ); -- END IF; -- IF p_return_error IS NOT NULL THEN -- Have been unable to force the nomination to validate (or unable to fix missing nnpcv) -- Has to be a serious error! l_success := FALSE; -- END IF; -- ELSIF p_contract_row.validation_action = 'B' THEN -- B - lookBack -- Look back - use a loop to keep recalling the validate routine -- until we have either got a valid nomination or have used min or contracted values -- <> -- WHILE nom_invalid LOOP -- nom_invalid := force_validate_cnpcv_nom( p_conf_id => p_conf_id , p_nomination_row => p_nomination_row , p_contract_id => p_contract_row.cont_id , p_gas_day => p_gas_day , p_window => p_contract_row.validation_window , p_exception => p_contract_row.validation_exception , p_lookback_action => p_contract_row.lookback_action , p_validation_action => p_contract_row.validation_action , p_return_error => p_return_error ); -- IF p_return_error IS NOT NULL THEN -- Have been unable to force the nomination to validate -- Has to be a serious error! l_success := FALSE; -- EXIT lookback_loop; -- END IF; --EXIT lookback_loop; -- -- END LOOP lookback_loop; -- ELSE -- -- Ignore - replace with eith min, max or contracted, do not attempt lookback. -- nom_invalid := force_validate_cnpcv_nom( p_conf_id => p_conf_id , p_nomination_row => p_nomination_row , p_contract_id => p_contract_row.cont_id , p_gas_day => p_gas_day , p_ignore => TRUE , p_return_error => p_return_error ); -- IF p_return_error IS NOT NULL THEN -- Have been unable to force the nomination to validate (or unable to fix missing nnpcv) -- Has to be a serious error! l_success := FALSE; -- END IF; -- END IF; -- END IF; -- caco_debug.putline('SP_CONF: force_comm_conf 999'); RETURN l_success; -- END force_comm_conf; -- -- -- -- -- FUNCTION create_comm_conf( p_nomi_id IN nominations.nomi_id%TYPE , p_force IN VARCHAR2 , p_gas_day IN DATE , p_cont_id IN contracts.cont_id%TYPE , p_conf_id OUT confirmations.conf_id%TYPE , p_return_error OUT VARCHAR2 ) RETURN BOOLEAN IS -- CURSOR c_contract IS SELECT * FROM contracts WHERE cont_id = p_cont_id; -- CURSOR c_contract_options IS SELECT * FROM contract_options WHERE cont_id = p_cont_id; -- CURSOR c_customer( cp_cust_id IN NUMBER ) IS SELECT * FROM customers WHERE cust_id = cp_cust_id; -- CURSOR c_nomination IS SELECT * FROM nominations WHERE nomi_id = p_nomi_id; -- -- l_contract_row c_contract%ROWTYPE; l_cont_opt_row c_contract_options%ROWTYPE; l_nomination_row c_nomination%ROWTYPE; l_customer_row c_customer%ROWTYPE; -- l_confirmation_id confirmations.conf_id%TYPE; l_spreadsheet BLOB; l_conf_text_clob CLOB; l_conf_text VARCHAR2(32767); l_timestamp DATE; -- l_success BOOLEAN := TRUE; -- BEGIN caco_debug.putline('SP_CONF: create_comm_conf 001: '||P_NOMI_ID); -- Default the conf_id p_conf_id := -1; -- -- Get the required details IF p_nomi_id IS NOT NULL THEN -- OPEN c_nomination; FETCH c_nomination INTO l_nomination_row; IF c_nomination%NOTFOUND THEN -- l_success := FALSE; p_return_error := caco_utilities.get_module_text(2261); -- Failed to find Nomination Details -- END IF; CLOSE c_nomination; -- END IF; -- IF l_success THEN -- OPEN c_contract; FETCH c_contract INTO l_contract_row; IF c_contract%NOTFOUND THEN -- l_success := FALSE; p_return_error := caco_utilities.get_module_text(2260); -- Failed to find Contract details for nomination -- END IF; CLOSE c_contract; -- END IF; -- IF l_success THEN -- OPEN c_contract_options; FETCH c_contract_options INTO l_cont_opt_row; IF c_contract_options%NOTFOUND THEN -- l_success := FALSE; p_return_error := caco_utilities.get_module_text(2260); -- Failed to find Contract details for nomination -- END IF; CLOSE c_contract_options; -- END IF; -- IF l_success THEN -- OPEN c_customer( l_contract_row.cust_id ); FETCH c_customer INTO l_customer_row; IF c_customer%NOTFOUND THEN -- l_success := FALSE; p_return_error := caco_utilities.get_module_text(2239); -- Customer not found -- END IF; CLOSE c_customer; -- END IF; -- -- If everything went well so far then we should create a "stub" of a confirmation IF l_success THEN -- l_success := insert_comm_conf( p_nomi_id , p_cont_id , p_gas_day , l_confirmation_id , p_return_error ); -- END IF; -- -- IF l_success THEN -- -- Create the confirmation text as a combination of various bits l_conf_text := l_cont_opt_row.com_conf_subject; l_conf_text := l_conf_text||chr(10)||chr(10); l_conf_text := l_cont_opt_row.com_conf_content; -- Replace any tokens within the text l_conf_text := REPLACE(l_conf_text, '{NOMINATION_IDENTIFIER}', l_nomination_row.identifier); l_conf_text := REPLACE(l_conf_text, '{GAS_DAY}', TO_CHAR(p_gas_day, cout_system_configuration.get_configuration_item('G_DATE_FORMAT'))); l_conf_text := REPLACE(l_conf_text, '{CONFIRMATION_IDENTIFIER}', l_confirmation_id ); -- -- Add this to the temporary CLOB l_conf_text_clob := NVL(l_conf_text,' '); -- IF p_force = 'N' THEN -- Copy the nomination to the confirmation detail table l_success := copy_nom_to_cnpcv( l_confirmation_id , p_nomi_id , p_cont_id , p_gas_day , p_return_error ); -- ELSIF p_force = 'Y' THEN -- -- Need to create a temporary table of the nomination l_success := force_comm_conf( l_confirmation_id , l_nomination_row -- currently will be empty if no nomination found (e.g. contract closed) , l_contract_row , p_gas_day , p_return_error ); -- ELSE -- l_success := FALSE; p_return_error := caco_utilities.get_module_text(2330); -- An unexpected error has occurred. Please contact support -- END IF; -- -- If the contract has changed and removed a Network Point or Category -- then we need to remove those nominated network points or categories -- (it is theoretically possible that the rules wont check everything) IF l_success THEN -- l_success := remove_surplus_cnpcv( l_confirmation_id , l_contract_row.cont_id , p_return_error ); -- END IF; -- -- Final check for the created Confirmation. -- If the contract has changed and Added a Network Point or Category -- then we need to add the default values for those nepo or cate -- (it is theoretically possible that the rules wont check everything) IF l_success THEN -- l_success := add_missing_cnpcv( l_confirmation_id , l_nomination_row.nomi_id , l_contract_row , p_gas_day , p_return_error ); -- END IF; -- IF l_success THEN -- Create the spreadsheet from the confirmation (conf_net_point_cat_vals) BEGIN l_spreadsheet := amfr_excel.return_conf(p_conf_id => l_confirmation_id); EXCEPTION WHEN OTHERS THEN l_success := FALSE; p_return_error := caco_utilities.get_module_text(2212); -- An unexpected error has occurred while creating confirmation. Please contact support END; END IF; -- IF l_success THEN -- -- Finally, Insert it all into the confirmations table l_success := update_comm_conf( l_confirmation_id , l_spreadsheet , l_conf_text_clob , l_customer_row.conf_type , p_return_error ); -- IF l_success THEN -- Set the return confirmation id p_conf_id := l_confirmation_id; END IF; -- ELSE -- clear up after a failure clearup_failed_comm_conf( p_conf_id => l_confirmation_id ); -- END IF; -- END IF; -- caco_debug.putline('SP_CONF: create_comm_conf 999'); RETURN l_success; -- EXCEPTION WHEN OTHERS THEN caco_debug.putline('efno_confirmations.create_comm_conf - Error : '||sqlerrm(sqlcode)); -- END create_comm_conf; -- -- -- -- PROCEDURE send_comm_conf( p_gas_day IN VARCHAR2 , p_nomi_id IN owa_util.vc_arr DEFAULT g_vc_arr , p_cont_id IN owa_util.vc_arr DEFAULT g_vc_arr , p_accept IN owa_util.vc_arr DEFAULT g_vc_arr , p_force IN owa_util.vc_arr DEFAULT g_vc_arr ) IS -- l_s_conf_id owa_util.vc_arr; l_f_nomi_id owa_util.vc_arr; l_f_nom_identifier owa_util.vc_arr; l_f_cont_num owa_util.vc_arr; l_f_conf_error owa_util.vc_arr; l_conf_id confirmations.conf_id%TYPE; l_conf_error VARCHAR2(255); -- l_gas_day DATE; l_count_nom NUMBER := 0; l_successful_nom NUMBER := 0; l_failed_comm_con NUMBER := 0; successful_comm_conf BOOLEAN := TRUE; process_this_nom BOOLEAN := TRUE; l_success BOOLEAN := TRUE; -- BEGIN -- -- caco_debug.debug_on; -- caco_debug.putline('SP_CONF: send_comm_conf 001'); -- Check we have permission to be using this module. IF NOT caco_security.security_check('efnow095$') THEN RETURN; END IF; -- -- Check that we have had some data delivered l_count_nom := NVL(p_nomi_id.COUNT,0); -- IF l_count_nom = 0 OR NVL(p_accept.COUNT,0) != l_count_nom OR NVL(p_force.COUNT,0) != l_count_nom THEN -- Either no data was passed to the routine or there is a mismatch in the number -- of data items presented in the three arrays -- Either way we shouldnt continue as something has gone wrong l_success := FALSE; -- END IF; -- -- Ensure that the passed VARCHAR date converts to DATE IF l_success THEN -- BEGIN SELECT TO_DATE(p_gas_day, cout_system_configuration.get_configuration_item('G_DATE_FORMAT')) INTO l_gas_day FROM dual; EXCEPTION WHEN others THEN l_success := FALSE; END; -- END IF; -- IF l_success THEN -- FOR i IN 1..p_nomi_id.COUNT LOOP -- -- Reset any variables successful_comm_conf := TRUE; process_this_nom := TRUE; l_conf_error := NULL; -- -- Lets deal with simplicity first. IF p_accept(i) = 'Y' THEN -- -- We just need to create the commercial confirmation spreadsheet directly from -- the nomination as we know that the nomination was correct (can only 'accept' if it was valid) -- this saves us from revalidating the entire nomination successful_comm_conf := create_comm_conf( p_nomi_id(i) , 'N' , l_gas_day , p_cont_id(i) , l_conf_id , l_conf_error ); -- ELSIF p_force(i) = 'Y' THEN -- -- In this scenario, the nomination is not valid -- We have to revalidate every nominated category against the contract -- For those items that are invalid, we have to attempt to find valid values either -- by traversing through all previous tip nominations until we find a valid value - -- if one is not found then we have to take the contracted or minimum amount from the -- contract parameter values - or we truncate the value to the contracted or minimum -- -- If we cannot find a value due to missing nnpcv entries, we should create one based -- upon the Validation Exception of the Contract - i.e. create a cnpcv entry specifically -- for the confirmation (only stored in cnpcv - not in nnpcv). -- caco_debug.putline('efno_confirmation point A10'); successful_comm_conf := create_comm_conf( p_nomi_id(i) , 'Y' , l_gas_day , p_cont_id(i) , l_conf_id , l_conf_error ); caco_debug.putline('efno_confirmation point A20'); -- ELSE -- -- Dont want to process this one - not accepted and not forced. -- process_this_nom := FALSE; -- END IF; -- -- IF NOT successful_comm_conf AND process_this_nom THEN -- -- We need to record details to pass back to the user - use some arrays l_failed_comm_con := l_failed_comm_con + 1; -- -- Get the Nomination Identifier and Contract number l_f_nomi_id(l_failed_comm_con) := p_nomi_id(i); l_f_nom_identifier(l_failed_comm_con) := fetch_nom_identifier( p_nomi_id(i) ); l_f_cont_num(l_failed_comm_con) := p_cont_id(i); l_f_conf_error(l_failed_comm_con) := l_conf_error; -- ELSIF process_this_nom THEN -- -- Successful - store info for showing as a mini report l_successful_nom := l_successful_nom + 1; -- l_s_conf_id(l_successful_nom) := l_conf_id; -- END IF; -- END LOOP; -- -- need to call the send confirmation screen with appropriate success and failure report. -- probably better to be a different screen within the efnow095$ package -- efnow095$.approve_confirmations( 'CREATED' , l_s_conf_id , l_f_nomi_id , l_f_nom_identifier , l_f_cont_num , l_f_conf_error ); -- ELSE -- We should just report an error back to the Send Confirmation screen efnow095$.startup( p_error => 'Y' , p_error_text => caco_utilities.get_module_text(2330) ); -- An unexpected error has occurred. Please contact support -- END IF; -- caco_debug.putline('SP_CONF: send_comm_conf 999'); -- END send_comm_conf; -- -- -- -- PROCEDURE app_or_del_comm_conf( p_conf_id IN owa_util.vc_arr DEFAULT g_vc_arr , p_approve IN owa_util.vc_arr DEFAULT g_vc_arr , p_delete IN owa_util.vc_arr DEFAULT g_vc_arr ) IS -- -- Cursor to get Commercial confirmation details CURSOR c_conf( cp_conf_id IN NUMBER ) IS SELECT conf.confirmation , conf.confirmation_text , nomi.identifier , cont.cust_id , coop.com_conf_subject , conf.gas_day , cust.code , conf.conf_file_type FROM confirmations conf , nominations nomi , contracts cont , customers cust , contract_options coop WHERE conf.conf_id = cp_conf_id AND conf.nomi_id = nomi.nomi_id (+) AND conf.cont_id = cont.cont_id AND cust.cust_id = cont.cust_id AND coop.cont_id = cont.cont_id; -- l_conf_rec c_conf%ROWTYPE; l_timestamp DATE; l_sms_msg_en VARCHAR2(160); l_sms_msg_hu VARCHAR2(160); -- l_document_name documents.name%TYPE; -- BEGIN -- -- Check we have permission to be using this module. IF NOT g_auto_gen THEN -- IF NOT caco_security.security_check('efnow095$') THEN RETURN; END IF; -- END IF; -- IF NVL(p_conf_id.COUNT,0) > 0 AND NVL(p_conf_id.COUNT,0) = NVL(p_approve.COUNT,0) AND NVL(p_conf_id.COUNT,0) = NVL(p_delete.COUNT,0) THEN -- We have some data to deal with. FOR i IN 1..p_conf_id.COUNT LOOP -- l_conf_rec := NULL; l_timestamp := NULL; -- IF p_approve(i) = 'Y' AND p_delete(i) = 'N' THEN -- OPEN c_conf( p_conf_id(i) ); FETCH c_conf INTO l_conf_rec; IF c_conf%FOUND THEN -- -- Timestamping l_timestamp := amfr_timestamp.timestamp_document( p_identifier => p_conf_id(i) , p_doctype => amfr_timestamp.c_confirmation , p_file_for_hash => l_conf_rec.confirmation ); -- upd_conf_timestamp( p_conf_id(i) , l_timestamp ); -- -- Confirmation Acceptance for Nomination sent at -- Define the English SMS content l_sms_msg_en := caco_utilities.get_module_text( p_text_number => 2233 , p_language => 'EN' ); l_sms_msg_en := REPLACE( l_sms_msg_en, '', l_conf_rec.identifier ); l_sms_msg_en := REPLACE( l_sms_msg_en, '', TO_CHAR(l_timestamp, cout_system_configuration.get_configuration_item('G_DATE_FORMAT')||' HH24:MI:SS') ); -- -- Define the Hungarian SMS content l_sms_msg_hu := caco_utilities.get_module_text( p_text_number => 2233 , p_language => 'HU' ); l_sms_msg_hu := REPLACE( l_sms_msg_hu, '', l_conf_rec.identifier ); l_sms_msg_hu := REPLACE( l_sms_msg_hu, '', TO_CHAR(l_timestamp, cout_system_configuration.get_configuration_item('G_DATE_FORMAT')||' HH24:MI:SS') ); -- -- Replace the tags in the SMS content -- l_conf_rec.com_conf_subject := REPLACE(l_conf_rec.com_conf_subject, '{NOMINATION_IDENTIFIER}', l_conf_rec.identifier); l_conf_rec.com_conf_subject := REPLACE(l_conf_rec.com_conf_subject, '{GAS_DAY}', TO_CHAR(l_conf_rec.gas_day, cout_system_configuration.get_configuration_item('G_DATE_FORMAT'))); l_conf_rec.com_conf_subject := REPLACE(l_conf_rec.com_conf_subject, '{CONFIRMATION_IDENTIFIER}', p_conf_id(i) ); -- l_document_name := REPLACE(l_conf_rec.code,' ','_')||'_'||TO_CHAR(l_conf_rec.gas_day, 'YYYYMMDD')||'_'||TO_CHAR(p_conf_id(i)); -- IF l_conf_rec.conf_file_type = 'E' THEN -- l_document_name := l_document_name||'.xls'; -- ELSIF l_conf_rec.conf_file_type = 'X' THEN -- l_document_name := l_document_name||'.xml'; -- END IF; -- efno_msgsubs.send_messages( p_cust_id => l_conf_rec.cust_id , p_suca_id => efno_msgsubs.get_suca_id( p_suca_group => 'CONFIRMATION' , p_suca_name => 'ACCEPTANCE' ) , p_email_content_en => DBMS_LOB.SUBSTR(l_conf_rec.confirmation_text,32767,1) , p_email_subject_en => l_conf_rec.com_conf_subject , p_sms_content_en => l_sms_msg_en , p_sms_content_hu => l_sms_msg_hu , p_file => l_conf_rec.confirmation , p_filename => l_document_name , p_file_mime_type => 'application/vnd.ms-excel' ); -- END IF; CLOSE c_conf; -- ELSIF p_approve(i) = 'N' AND p_delete(i) = 'Y' THEN -- clearup_failed_comm_conf( p_conf_id(i) ); -- END IF; -- END LOOP; -- END IF; -- -- Finally just recall the approve confirmations screen with no values -- (if nothing was passed - nothing will have happened) -- Only call if proc was called from the screen and not through auto generation of confirmations IF NOT g_auto_gen THEN efnow095$.approve_confirmations; END IF; -- END app_or_del_comm_conf; -- -- /** -- PROCEDURE auto_gen_confirmations -- Automatically generate confirmations for the given gas day. -- and Customer type (if provided otherwaise all customers) -- -- %param p_gas_day Gas Day that Commercial confirmations shuold be created for -- %param p_cuty_id Customer Type ID. All customer if excluded -- */ PROCEDURE auto_gen_confirmations( p_gas_day IN DATE , p_cuty_id IN customer_types.cuty_id%TYPE , p_cnrt_id IN conf_run_times.cnrt_id%TYPE DEFAULT NULL ) IS -- l_found_nomination BOOLEAN; l_nomination_valid BOOLEAN; l_nomi_id nominations.nomi_id%TYPE; l_dummy VARCHAR2(255); l_success BOOLEAN; -- l_conf_id confirmations.conf_id%TYPE; l_return_error VARCHAR2(255); -- l_conf_id_arr owa_util.vc_arr; l_conf_a_arr owa_util.vc_arr; l_conf_d_arr owa_util.vc_arr; -- l_cfrl_id conf_run_log.cfrl_id%TYPE; -- l_cont_count NUMBER := 0; l_nom_count NUMBER := 0; l_force_count NUMBER := 0; l_conf_sent NUMBER := 0; l_log_details VARCHAR2(1000); l_run_date DATE := SYSDATE; -- BEGIN -- -- Set global flag to indicate to other confirmation processes we are being called by a job -- g_auto_gen := TRUE; -- -- Loop around all active contracts for the cuty -- caco_debug.putline('Entered efno_confirmation.auto_gen_confirmation with:'); caco_debug.putline('p_gas_day '||p_gas_day); caco_debug.putline('p_cuty_id '||p_cuty_id); caco_debug.putline('p_cnrt_id '||p_cnrt_id); -- IF p_cnrt_id IS NOT NULL THEN -- INSERT INTO conf_run_log ( cnrt_id , start_time ) VALUES ( p_cnrt_id , SYSDATE ) RETURNING cfrl_id INTO l_cfrl_id; -- END IF; -- FOR cont_rec IN ( SELECT cont.cont_id ,coop.auto_gen_conf FROM contracts cont ,customers cust ,contract_options coop WHERE cont.cust_id = cust.cust_id AND cust.cuty_id = p_cuty_id AND cont.cont_id = coop.cont_id AND p_gas_day BETWEEN cont.valid_from AND cont.valid_until AND cont.status = 'O' ) LOOP -- l_found_nomination := FALSE; l_nomination_valid := FALSE; l_nomi_id := NULL; l_cont_count := l_cont_count + 1; -- -- Now look for an active nomination -- FOR nomi_rec IN ( SELECT nomi.nomi_id FROM nominations nomi , nom_net_point_cat_vals nnpcv WHERE nomi.cont_id = cont_rec.cont_id AND nnpcv.nomi_id = nomi.nomi_id AND nomi.status = 'A' GROUP BY nomi.nomi_id HAVING p_gas_day BETWEEN MIN(nnpcv.gas_day) AND MAX(nnpcv.gas_day) ) LOOP -- l_found_nomination := TRUE; l_nomi_id := nomi_rec.nomi_id; -- EXIT; -- END LOOP; -- IF l_found_nomination THEN -- -- We have a nomination, lets check that its valid -- l_nomination_valid := efno_contracts.validate_nomination( cont_rec.cont_id , l_nomi_id , l_dummy ); -- END IF; -- -- If a nomination was found which is valid, no need to force, otherwise force the commercial confirmation -- IF l_found_nomination AND l_nomination_valid THEN -- l_nom_count := l_nom_count + 1; -- l_success := create_comm_conf( l_nomi_id , 'N' , p_gas_day , cont_rec.cont_id , l_conf_id , l_return_error ); -- ELSE -- l_force_count := l_force_count + 1; -- l_success := create_comm_conf( NULL , 'Y' , p_gas_day , cont_rec.cont_id , l_conf_id , l_return_error ); -- END IF; -- IF l_success AND cont_rec.auto_gen_conf = 'Y' THEN -- l_conf_sent := l_conf_sent + 1; -- l_conf_id_arr.DELETE; l_conf_a_arr.DELETE; l_conf_d_arr.DELETE; -- l_conf_id_arr(1):= l_conf_id; l_conf_a_arr(1) := 'Y'; l_conf_d_arr(1) := 'N'; -- app_or_del_comm_conf( p_conf_id => l_conf_id_arr , p_approve => l_conf_a_arr , p_delete => l_conf_d_arr ); -- ELSIF NOT l_success THEN -- cout_err.report_and_go( p_exception_number => 20001 , p_exception_message => 'Unable to create confirmation for : ' ||' CONT_ID : ' ||cont_rec.cont_id ||' : NOMI_ID : ' ||l_nomi_id ||CHR(10) ||' Error Msg : ' ||l_return_error , p_source => 'efno_confirmations.auto_gen_confirmations' ); -- END IF; -- END LOOP; -- l_log_details := TO_CHAR(l_cont_count)||' contracts processed, '||TO_CHAR(l_nom_count)||' valid nominations, '||TO_CHAR(l_force_count)||' confirmations forced and '||TO_CHAR(l_conf_sent)||' confirmations automatically sent.'; -- IF p_cnrt_id IS NOT NULL THEN -- UPDATE conf_run_log SET end_time = SYSDATE ,log_details = l_log_details WHERE cfrl_id = l_cfrl_id; -- END IF; -- caco_debug.putline('End auto_gen_confirmations'); -- EXCEPTION -- WHEN OTHERS THEN -- -- Write an error and stop -- cout_err.report_and_stop( p_exception_number => SQLCODE , p_exception_message => 'Automatic Generation of confirmations failed : ' ||' Gas Day : ' ||TO_CHAR(p_gas_day,'DD-MON-YYYY') ||CHR(10) ||' Error Msg : ' ||SQLERRM(SQLCODE) , p_source => 'efno_confirmations.auto_gen_confirmations' ); -- END auto_gen_confirmations; -- -- -- -- /** -- 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 -- Initialization NULL; -- END efno_confirmations; /