CREATE OR REPLACE PACKAGE BODY efno_contracts IS -- Single point of finding Contract rules in the correct order. CURSOR c_rules( cp_cont_id IN NUMBER ) RETURN contract_rules_rec IS SELECT display_sequence , rule_name , rule_type , coru_id , rule_id , inherited FROM ( SELECT coru.display_sequence display_sequence , rule.rule_name rule_name , coru.coru_type rule_type , coru.coru_id coru_id , coru.rule_id rule_id , coru.inherited inherited FROM contract_rules coru , rules rule WHERE rule.rule_id = coru.rule_id AND coru.cont_id = cp_cont_id UNION ALL SELECT display_sequence , rule_name , coru_type , coru_id , rule_id , inherited FROM contract_rules WHERE cont_id = cp_cont_id AND rule_id IS NULL ) ORDER BY rule_type DESC -- SHEET rules first (contract specific) , inherited DESC -- Inherited (Y) first , display_sequence ASC , rule_name ASC; -- -- FUNCTION invalidate_inty( p_contract_id IN contracts.cont_id%TYPE) RETURN BOOLEAN IS CURSOR c_inty IS SELECT inty_id FROM interruption_types WHERE cate_id IN (SELECT cate_id FROM contract_categories WHERE cont_id = p_contract_id) AND status = 'A' AND expiry_date > SYSDATE; -- l_success BOOLEAN := TRUE; -- BEGIN SAVEPOINT before_upd_inty; -- <> FOR r IN c_inty LOOP -- BEGIN -- UPDATE interruption_types SET status = 'I' WHERE inty_id = r.inty_id; -- EXCEPTION WHEN others THEN l_success := FALSE; caco_debug.putline('efno_contracts.invalidate_inty: ' ||'Update of interruption types failed: ' ||sqlerrm(sqlcode)); -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => 'Failed updating INTY: '||sqlerrm(sqlcode) , p_source => 'efno_contracts.invalidate_inty'); -- ROLLBACK TO SAVEPOINT before_upd_inty; EXIT upd_inty_loop; END; END LOOP; -- RETURN l_success; -- END invalidate_inty; /** -- FUNCTION contract_active -- -- Determines whether a given contract ID is active and current -- -- %param p_cont_id The unique identifier for a contract -- -- %return BOOLEAN Indicates whether the contract is active */ FUNCTION contract_active ( p_cont_id IN contracts.cont_id%TYPE ) RETURN BOOLEAN IS -- l_return BOOLEAN := FALSE; -- BEGIN -- FOR cont IN ( SELECT NULL FROM contracts cont WHERE cont.cont_id = p_cont_id AND cont.status = 'O' AND TRUNC(SYSDATE) BETWEEN cont.valid_from AND cont.valid_until ) LOOP -- -- will only retuen one row as unique key lookup -- l_return := TRUE; -- END LOOP; -- RETURN l_return; -- END contract_active; -- -- /** -- FUNCTION validate_nomination -- Fairly Simplistic function that will just return TRUE or FALSE -- to indicate if the given nomination is valid for the contract as it stands -- -- %param p_contract_id The Unique identifier of a Contract -- %param p_nomination_id The Unique identifier of a Nomination -- %param p_return_error OUT: Message giving brief reason why the rule is invalid if indeed it is -- -- %return BOOLEAN TRUE indicating that the nomination is valid */ FUNCTION validate_nomination( p_contract_id IN contracts.cont_id%TYPE , p_nomination_id IN nominations.nomi_id%TYPE , p_return_error OUT VARCHAR2 ) RETURN BOOLEAN IS -- -- Cursor to get the contract details CURSOR c_contract IS SELECT * FROM contracts WHERE cont_id = p_contract_id; -- -- Cursor to get the nomination identifier and the min and max days of the nom -- this is required to ensure that the nominations fall within the contract validity period CURSOR c_nomination IS SELECT nomi.identifier identifier , MIN(nnpcv.gas_day) gas_day_from , MAX(nnpcv.gas_day) gas_day_to FROM nominations nomi , nom_net_point_cat_vals nnpcv WHERE nnpcv.nomi_id = nomi.nomi_id AND nomi.nomi_id = p_nomination_id GROUP BY nomi.identifier; -- -- l_contract_row c_contract%ROWTYPE; l_nom_row c_nomination%ROWTYPE; l_rule_id NUMBER := 0; l_nnpcv_tab efno_confirmations.nnpcv_tab; l_nom_validation_table efno_rules.nom_validation_table; -- rule_valid BOOLEAN := TRUE; -- l_success BOOLEAN := TRUE; -- BEGIN -- -- Check we have permission to be using this module. -- Only called from the Create commercial confirmation screen IF NOT caco_security.security_check('efnow095$') THEN RETURN FALSE; END IF; -- -- Get the Contract row OPEN c_contract; FETCH c_contract INTO l_contract_row; IF c_contract%NOTFOUND THEN -- problem - no contract! l_success := FALSE; p_return_error := caco_utilities.get_module_text(2235); -- Contract not found END IF; CLOSE c_contract; -- IF l_success THEN -- Get the nomination details OPEN c_nomination; FETCH c_nomination INTO l_nom_row; IF c_nomination%NOTFOUND THEN -- no nomination! How can this happen? l_success := FALSE; p_return_error := caco_utilities.get_module_text(2288); -- Nomination not found END IF; CLOSE c_nomination; -- END IF; -- IF l_success THEN -- Lets check that the nomination gas days are within the contract period IF l_contract_row.valid_from > l_nom_row.gas_day_from OR l_contract_row.valid_until < l_nom_row.gas_day_to THEN l_success := FALSE; p_return_error := caco_utilities.get_module_text(2285); -- Nomination Gas Days are not within the Contract validity period END IF; END IF; -- IF l_success THEN -- Lets loop through all the rules for the contract and check that the -- nomination data is valid for them <> FOR r IN c_rules( p_contract_id ) LOOP -- l_nom_validation_table.DELETE; rule_valid := FALSE; l_rule_id := 0; -- IF r.rule_type = 'SHEET' THEN l_rule_id := r.coru_id; ELSE l_rule_id := r.rule_id; END IF; -- rule_valid := efno_rules.validate_rule( p_rule_id => l_rule_id , p_rule_type => r.rule_type , p_parse_only => FALSE , p_nnpcv_tab => l_nnpcv_tab , p_nom_table => l_nom_validation_table , p_contract_id => p_contract_id , p_nomination_id => p_nomination_id ); -- IF rule_valid THEN -- We now need to check that all of the data satisified the conditions of the rule -- just need to check nr_valid in the validation_table IF NVL(l_nom_validation_table.COUNT,0) > 0 THEN -- FOR i IN 1..l_nom_validation_table.COUNT LOOP -- IF NOT l_nom_validation_table(i).nr_valid THEN l_success := FALSE; p_return_error := caco_utilities.get_module_text(2284); -- Nomination Data failed Contract Rule validation EXIT nom_rule_loop; END IF; END LOOP; -- END IF; -- ELSE -- The nommination failed rule validation l_success := FALSE; p_return_error := caco_utilities.get_module_text(2234); -- Contract Rule is invalid EXIT nom_rule_loop; END IF; -- END LOOP nom_rule_loop; -- -- END IF; -- RETURN l_success; -- END validate_nomination; PROCEDURE find_passed_net_points( p_nepo_array IN owa_util.vc_arr , p_network_point_array OUT network_point_array ) IS l_count NUMBER := 0; BEGIN -- IF NVL(p_nepo_array.COUNT,0) > 0 THEN FOR i IN p_nepo_array.FIRST .. p_nepo_array.LAST LOOP -- l_count := l_count + 1; p_network_point_array(l_count) := TO_NUMBER(p_nepo_array(i)); -- END LOOP; END IF; -- END find_passed_net_points; PROCEDURE find_passed_categories( p_cate_array IN owa_util.vc_arr , p_category_array OUT category_array ) IS l_count NUMBER := 0; BEGIN -- IF NVL(p_cate_array.COUNT,0) > 0 THEN FOR i IN p_cate_array.FIRST .. p_cate_array.LAST LOOP -- l_count := l_count + 1; -- p_category_array(l_count).cate_id := TO_NUMBER(p_cate_array(i)); p_category_array(l_count).inherited := 'N'; -- -- Set sequence to added sequence rather than inherited sequence -- p_category_array(l_count).display_sequence := l_count; -- END LOOP; END IF; -- END find_passed_categories; PROCEDURE find_passed_parameters( p_pars_array IN owa_util.vc_arr , p_parameter_array OUT parameter_array ) IS l_count NUMBER := 0; BEGIN -- IF NVL(p_pars_array.COUNT,0) > 0 THEN FOR i IN p_pars_array.FIRST .. p_pars_array.LAST LOOP -- l_count := l_count + 1; -- p_parameter_array(l_count).pars_id := TO_NUMBER(p_pars_array(i)); p_parameter_array(l_count).inherited := 'N'; -- default value - replace it later (for contracts) -- END LOOP; END IF; -- END find_passed_parameters; -- Function to check if the nomination gate closure has occured for a given date FUNCTION check_gate_closure ( p_cont_id IN contracts.cont_id%TYPE , p_date IN DATE ) RETURN BOOLEAN IS -- l_return BOOLEAN := TRUE; l_deadline VARCHAR2(5) := NULL; l_active_date DATE := NULL; l_date DATE := NULL; l_cust_id NUMBER := NULL; -- FUNCTION in_a_renom_window RETURN BOOLEAN IS -- l_return BOOLEAN := FALSE; -- BEGIN -- FOR i IN ( SELECT NULL FROM nomination_windows nw ,nom_window_contracts nwc WHERE nw.nowi_id = nwc.nowi_id AND nwc.cont_id = p_cont_id AND nw.gas_day = TRUNC(SYSDATE - cout_system_configuration.get_configuration_item('GAS_DAY_OFFSET')/24) + cout_system_configuration.get_configuration_item('GAS_DAY_OFFSET')/24 AND SYSDATE BETWEEN nw.window_start AND nw.window_end ) LOOP -- l_return := TRUE; -- EXIT; -- END LOOP; -- RETURN l_return; -- END in_a_renom_window; -- FUNCTION get_deadline ( p_cust_id IN customers.cust_id%TYPE ) RETURN VARCHAR2 IS -- l_return VARCHAR2(5) := NULL; -- BEGIN -- SELECT cust.ind_deadline_for_nom_submit INTO l_return FROM customers cust WHERE cust.cust_id = p_cust_id; -- IF l_return IS NULL THEN -- l_return := cout_system_configuration.get_configuration_item('G_SUBMISSION_DEADLINE'); -- END IF; -- RETURN l_return; -- END get_deadline; -- BEGIN -- -- get the cust_id from contracts table SELECT cust_id INTO l_cust_id FROM contracts WHERE cont_id = p_cont_id; -- l_date := TRUNC(SYSDATE - cout_system_configuration.get_configuration_item('GAS_DAY_OFFSET')/24)+ NVL(cout_system_configuration.get_configuration_item('G_NOM_DATE_OFFSET'),1); IF l_date = p_date THEN -- -- There is a nomination for tomorrow, need to check gate closure -- l_deadline := get_deadline(p_cust_id => l_cust_id); -- IF l_deadline IS NOT NULL THEN -- IF TO_NUMBER(RTRIM(SUBSTR(l_deadline,1,2),':')) < cout_system_configuration.get_configuration_item(p_parameter => 'GAS_DAY_OFFSET') THEN -- -- Is tomorrow, add one to the date -- l_active_date := TO_DATE(TO_CHAR(TRUNC(SYSDATE - cout_system_configuration.get_configuration_item('GAS_DAY_OFFSET')/24),'DD/MM/YYYY')||l_deadline, 'DD/MM/YYYYHH24:MI')+1; -- ELSE -- -- same calendar date, OK -- l_active_date := TO_DATE(TO_CHAR(TRUNC(SYSDATE - cout_system_configuration.get_configuration_item('GAS_DAY_OFFSET')/24),'DD/MM/YYYY')||l_deadline, 'DD/MM/YYYYHH24:MI'); -- END IF; -- -- Determined what the deadline is, now check it -- IF SYSDATE > l_active_date THEN -- l_return := FALSE; -- END IF; -- p_date > l_active_date -- END IF; -- l_deadline not null -- END IF; -- nominating for tomorrow -- -- Renom window check -- IF l_date > p_date THEN -- -- Nominating for today, check for renom window -- IF NOT in_a_renom_window THEN -- l_return := FALSE; -- END IF; -- END IF; -- RETURN l_return; -- END check_gate_closure; -- FUNCTION recalc_emo_noms -- -- recalculate any nominations for the entry mandatory offer contract which are before gate closure -- -- %param p_cont_id The unique identifier for a contract -- %param p_err_msg to return an error message to calling program -- %return BOOLEAN Indicates whether the function succeeded FUNCTION recalc_emo_noms ( p_cont_id IN contracts.cont_id%TYPE ,p_err_msg OUT VARCHAR2 ) RETURN BOOLEAN IS -- l_success BOOLEAN := TRUE; l_tot_perc_split NUMBER := 0; -- CURSOR c_vnepo_coca (cp_nomi_id NUMBER ,cp_gas_day DATE) IS SELECT nnpcv.coca_id , nnpcv.value value FROM nom_net_point_cat_vals nnpcv , contracts cont , cont_network_points conp , network_points nepo WHERE nnpcv.nomi_id = cp_nomi_id AND nnpcv.gas_day = cp_gas_day AND cont.cont_id = p_cont_id AND nnpcv.conp_id = conp.conp_id AND conp.nepo_id = nepo.nepo_id AND nepo.nepo_type = 'V' ORDER BY 1; -- BEGIN caco_debug.putline('efno_contracts.recalc_emo_noms - start'); -- get the total of the percentage split values OPEN efnow098$.c_tot_perc_split(p_cont_id); FETCH efnow098$.c_tot_perc_split INTO l_tot_perc_split; CLOSE efnow098$.c_tot_perc_split; -- -- loop round all active nominations for the contract to see if they need recalculating -- starting with two days back to be safe. FOR nom IN ( SELECT nomi.nomi_id ,nnpcv.gas_day FROM nominations nomi ,nom_net_point_cat_vals nnpcv WHERE nomi.nomi_id = nnpcv.nomi_id AND nomi.cont_id = p_cont_id AND nomi.status = 'A' GROUP BY nnpcv.gas_day ,nomi.nomi_id HAVING nnpcv.gas_day > trunc(SYSDATE) - 2 ORDER BY gas_day ) LOOP -- -- check nomination gate closure for the gas day IF check_gate_closure(p_cont_id,nom.gas_day) THEN -- loop round the virtual network point nomination categories for the gas day FOR v IN c_vnepo_coca(nom.nomi_id ,nom.gas_day) LOOP -- loop round each non virtual network point assigned to the contract -- retrieving the percentage split parameters FOR i IN efnow098$.c_conp(p_cont_id) LOOP -- update the existing nominated values caco_debug.putline('efno_contracts.recalc_emo_noms - updating nominations'); UPDATE nom_net_point_cat_vals nnpcv SET value = ROUND((i.perc_split/l_tot_perc_split)*v.value) WHERE nnpcv.nomi_id = nom.nomi_id AND nnpcv.gas_day = nom.gas_day AND nnpcv.coca_id = v.coca_id AND nnpcv.conp_id = i.conp_id; -- END LOOP; END LOOP; -- save new spreadsheet for updated nomination amfr_excel.get_template(p_id => p_cont_id ,p_type => amfr_excel.gc_nomination ,p_nomi_conf_id => nom.nomi_id ,p_mode => 'INSERT' ); END IF; -- END LOOP; -- caco_debug.putline('efno_contracts.recalc_emo_noms - end'); RETURN l_success; -- EXCEPTION WHEN others THEN caco_debug.putline('efno_contracts.recalc_emo_noms failed'); l_success := FALSE; p_err_msg := caco_utilities.get_module_text(3918); RETURN l_success; -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => sqlerrm(sqlcode) , p_source => 'efno_contracts.recalc_emo_noms'); -- END recalc_emo_noms; -- -- For returning the number of network points assigned to a contract FUNCTION nepo_count( p_contract_id IN NUMBER ) RETURN NUMBER IS CURSOR c_conp IS SELECT count(*) FROM cont_network_points WHERE cont_id = p_contract_id; -- l_count NUMBER := 0; -- BEGIN OPEN c_conp; FETCH c_conp INTO l_count; CLOSE c_conp; RETURN l_count; END nepo_count; PROCEDURE upd_cnppv_records( p_contract_id IN NUMBER , p_page_no IN NUMBER DEFAULT 1 , p_cnppv_id IN owa_util.vc_arr DEFAULT g_vc_arr , p_value IN owa_util.vc_arr DEFAULT g_vc_arr ) IS -- Cursor used to find the appropriate Number Format for the given id/value pair CURSOR c_cnppv( cp_cnppv_id IN NUMBER ) IS SELECT cate.number_format num_format ,cate.interuptible interruptible ,cate.cate_id cate_id ,cnppv.conp_id conp_id FROM cont_net_point_param_vals cnppv , contract_parameters copa , parameters pars , categories cate WHERE cnppv.cnppv_id = cp_cnppv_id AND cnppv.copa_id = copa.copa_id AND copa.pars_id = pars.pars_id AND pars.cate_id = cate.cate_id; -- -- Find the category parameter type (if it is one!) CURSOR c_cate_par_type( cp_cnppv_id IN NUMBER ) IS SELECT SUBSTR(pars.code,-3) code FROM parameters pars , contract_parameters copa , cont_net_point_param_vals cnppv WHERE cnppv.cnppv_id = cp_cnppv_id AND cnppv.copa_id = copa.copa_id AND copa.pars_id = pars.pars_id AND pars.cate_id IS NOT NULL; -- -- Find if contract has Percentage Split parameter CURSOR c_copa IS SELECT copa.copa_id copa_id FROM parameters pars , contract_parameters copa , contracts cont WHERE cont.cont_id = p_contract_id AND copa.cont_id = cont.cont_id AND copa.pars_id = pars.pars_id AND pars.name IN (g_perc_split_en, g_perc_split_hu); -- -- Find the Percentage Split total CURSOR c_perc_split(cp_vnepo IN VARCHAR2) IS SELECT NVL(SUM(cnppv.value),0) FROM parameters pars , contract_parameters copa , cont_net_point_param_vals cnppv , contracts cont , cont_network_points conp , network_points nepo WHERE cont.cont_id = p_contract_id AND copa.cont_id = cont.cont_id AND cnppv.copa_id = copa.copa_id AND copa.pars_id = pars.pars_id AND cnppv.conp_id = conp.conp_id AND conp.nepo_id = nepo.nepo_id AND ((nepo.nepo_type IN ('N','X') AND cp_vnepo = 'N') OR (nepo.nepo_type = 'V' AND cp_vnepo = 'Y')) AND pars.name IN (g_perc_split_en, g_perc_split_hu); -- -- Find the Percentage Split values from cnppv table CURSOR c_cnppv_per_split IS SELECT cnppv.conp_id conp_id , cnppv.value value FROM parameters pars , contract_parameters copa , cont_net_point_param_vals cnppv WHERE copa.cont_id = p_contract_id AND copa.pars_id = pars.pars_id AND copa.copa_id = cnppv.copa_id AND pars.name IN (g_perc_split_en, g_perc_split_hu) order by 1; -- l_number_format categories.number_format%TYPE; l_cate_int categories.interuptible%TYPE; l_cate_id categories.cate_id%TYPE; l_conp_id cont_network_points.conp_id%TYPE; l_current_type VARCHAR2(3) := NULL; prev_valid_num BOOLEAN := TRUE; prev2_valid_num BOOLEAN := TRUE; curr_valid_num BOOLEAN := TRUE; l_temp_number NUMBER := 0; l_prev_value NUMBER := 0; -- l_array_length NUMBER := 0; l_data_error owa_util.vc_arr; -- l_error_message VARCHAR2(400) := NULL; l_success BOOLEAN := TRUE; l_invalid_number BOOLEAN := FALSE; l_invalid_format BOOLEAN := FALSE; l_update_error BOOLEAN := FALSE; l_negatives BOOLEAN := FALSE; l_min_gt_max BOOLEAN := FALSE; l_ctr_lt_min BOOLEAN := FALSE; l_ctr_gt_max BOOLEAN := FALSE; -- l_copa_id NUMBER; l_tot_per_split NUMBER := 0; l_vnepo_per_split NUMBER := 0; l_perc_split_array perc_split_array; l_count NUMBER := 0; recalc_noms BOOLEAN := FALSE; -- -- array to contain p_value array contents with no thousand separators l_val_no_thou_sep owa_util.vc_arr; -- BEGIN -- Check we have permission to be using this module. -- Only called from the Create contracts screen IF NOT caco_security.security_check('efnow050$') THEN RETURN; END IF; -- SAVEPOINT before_upd_cnppv; -- -- remove thousand separators from p_value array -- l_val_no_thou_sep := caco_utilities.thousand_separated_to_char(p_value); -- Check that the number of values in the arrays is consistent IF NVL(p_cnppv_id.COUNT,0) > 0 AND NVL(l_val_no_thou_sep.COUNT,0) > 0 AND NVL(p_cnppv_id.COUNT,0) = NVL(l_val_no_thou_sep.COUNT,0) THEN -- We are on good ground l_array_length := p_cnppv_id.COUNT; ELSE -- l_success := FALSE; -- IF NVL(p_cnppv_id.COUNT,0) = 0 AND NVL(l_val_no_thou_sep.COUNT,0) = 0 THEN l_error_message := caco_utilities.get_module_text(2278); -- No Data passed to update routine -- ELSE l_error_message := caco_utilities.get_module_text(2275); -- Mismatched Id and Value arrays. Check contract details before returning to this page END IF; -- END IF; -- Check if contract has Percentage Split parameter assigned to it OPEN c_copa; FETCH c_copa INTO l_copa_id; CLOSE c_copa; -- IF l_copa_id IS NOT NULL THEN -- put the current saved percentage split parameters into an array OPEN c_cnppv_per_split; FETCH c_cnppv_per_split BULK COLLECT INTO l_perc_split_array; CLOSE c_cnppv_per_split; -- END IF; -- -- Lets check all the passed data; IF l_success THEN FOR i IN 1..l_array_length LOOP -- l_temp_number := 0; l_number_format := NULL; l_current_type := NULL; prev2_valid_num := prev_valid_num; prev_valid_num := curr_valid_num; curr_valid_num := TRUE; l_data_error(i) := 'N'; -- IF NVL(l_val_no_thou_sep(i),'#~^!$') != '#~^!$' THEN -- should this be IS NOT NULL -- OPEN c_cnppv( p_cnppv_id(i) ); FETCH c_cnppv INTO l_number_format ,l_cate_int ,l_cate_id ,l_conp_id; IF c_cnppv%FOUND THEN -- we need to check that the entered value matches the number format found BEGIN SELECT TO_NUMBER(l_val_no_thou_sep(i),l_number_format) INTO l_temp_number FROM dual; -- -- Check to ensure that the data is gte zero IF l_val_no_thou_sep(i) < 0 THEN -- An error -- ALL values must be positive (including zero) l_success := FALSE; l_negatives := TRUE; l_data_error(i) := 'Y'; END IF; -- EXCEPTION WHEN others THEN l_success := FALSE; l_data_error(i) := 'Y'; l_invalid_format := TRUE; curr_valid_num := FALSE; END; -- ELSE -- Just ensure that the data is numeric BEGIN SELECT TO_NUMBER(l_val_no_thou_sep(i)) INTO l_temp_number FROM dual; -- -- Check to ensure that the data is gte zero IF l_val_no_thou_sep(i) < 0 THEN -- An error -- ALL values must be positive (or zero) l_success := FALSE; l_negatives := TRUE; l_data_error(i) := 'Y'; END IF; -- EXCEPTION WHEN others THEN l_success := FALSE; l_data_error(i) := 'Y'; l_invalid_number := TRUE; curr_valid_num := FALSE; END; -- END IF; CLOSE c_cnppv; -- ELSE l_success := FALSE; l_data_error(i) := 'Y'; l_invalid_number := TRUE; curr_valid_num := FALSE; END IF; -- -- If numeric and correct format - ensure that max is greater than min -- min is less than max and contracted is between the two. -- Slightly easier than it sounds as we know that these three values are consecutive -- we just need to know which one this is.... -- We should only do the checks when we have found the CTR amount otherwise we wont know -- if all the values are numeric... -- Find out if we are a category parameter (dont check standalone parameters) OPEN c_cate_par_type(p_cnppv_id(i)); FETCH c_cate_par_type INTO l_current_type; IF c_cate_par_type%FOUND THEN IF l_current_type = 'CTR' THEN -- lets check MIN, MAX and CTR are valid together. IF prev_valid_num AND prev2_valid_num AND TO_NUMBER(l_val_no_thou_sep(i-2)) > TO_NUMBER(l_val_no_thou_sep(i-1)) THEN -- Min > Max l_success := FALSE; l_min_gt_max := TRUE; l_data_error(i-2) := 'Y'; l_data_error(i-1) := 'Y'; END IF; IF curr_valid_num AND prev2_valid_num AND TO_NUMBER(l_val_no_thou_sep(i)) < TO_NUMBER(l_val_no_thou_sep(i-2)) THEN -- CTR < MIN l_success := FALSE; l_ctr_lt_min := TRUE; l_data_error(i) := 'Y'; END IF; IF curr_valid_num AND prev_valid_num AND TO_NUMBER(l_val_no_thou_sep(i)) > TO_NUMBER(l_val_no_thou_sep(i-1)) THEN -- CTR > MAX l_success := FALSE; l_ctr_gt_max := TRUE; l_data_error(i) := 'Y'; END IF; END IF; END IF; CLOSE c_cate_par_type; -- -- If the above is ok and no previous error has been found - update the DB IF l_success THEN -- BEGIN -- IF l_current_type = 'MAX' THEN -- -- If the current value is a maximum value, lookup the current value before updating -- SELECT value INTO l_prev_value FROM cont_net_point_param_vals cnppv WHERE cnppv.cnppv_id = p_cnppv_id(i); -- END IF; -- UPDATE cont_net_point_param_vals SET value = l_temp_number WHERE cnppv_id = p_cnppv_id(i); -- EXCEPTION WHEN others THEN caco_debug.putline('efno_contracts.upd_cnppv_records : Failed Update - CNPPV_ID : ' ||p_cnppv_id(i)||' : Value : '||l_val_no_thou_sep(i)); l_success := FALSE; l_update_error := TRUE; -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => sqlerrm(sqlcode) , p_source => 'efno_contracts.upd_cnppv_records'); -- END; -- END IF; -- -- Addition to activate/deactive inty_conp_params -- IF l_success THEN -- -- Check that the contract is active and current -- IF contract_active(p_contract_id) THEN -- -- If we're looking at a maximum value -- IF l_current_type = 'MAX' THEN -- -- And the previous value was 0 and the new value isn't, or the -- IF (l_temp_number = 0 AND l_prev_value <> 0) OR (l_prev_value = 0 AND l_temp_number <> 0) THEN -- -- And the category is classified as interruptible -- IF l_cate_int = 'Y' THEN -- -- Finally, check for an active interruption type -- FOR inty IN ( SELECT inty.inty_id FROM interruption_types inty WHERE inty.status = 'A' AND inty.cate_id = l_cate_id ) LOOP -- -- Now update/insert inty_conp_params -- /* -- problem with merge statement and table API MERGE INTO inty_conp_params incp USING (SELECT inty.inty_id inty_id , l_conp_id conp_id , 0 max_int , 0 max_days , 0 max_len , DECODE(l_temp_number, 0, 'N', 'Y') flag FROM DUAL) sq1 ON ( incp.inty_id = sq1.inty_id AND incp.conp_id = sq1.conp_id ) WHEN MATCHED THEN UPDATE SET incp.limits_enabled = sq1.flag WHEN NOT MATCHED THEN INSERT (icp_id ,inty_id ,conp_id ,max_interruptions ,max_interruption_days ,max_interruption_length ,limits_enabled ) VALUES ( icp_seq.NEXTVAL , sq1.inty_id , sq1.conp_id , sq1.max_int , sq1.max_days , sq1.max_len , sq1.flag ) WHERE DECODE(l_temp_number, 0, 'N', 'Y') = 'Y'; */ UPDATE inty_conp_params incp SET incp.limits_enabled = DECODE(l_temp_number, 0, 'N', 'Y') WHERE incp.inty_id = inty.inty_id AND incp.conp_id = l_conp_id; -- IF SQL%NOTFOUND THEN -- INSERT INTO inty_conp_params incp ( icp_id , inty_id , conp_id , max_interruptions , max_interruption_days , max_interruption_length , limits_enabled ) VALUES ( icp_seq.NEXTVAL , inty.inty_id , l_conp_id , 0 , 0 , 0 , DECODE(l_temp_number, 0, 'N', 'Y') ); -- END IF; -- END LOOP; -- END IF; -- category interruptable -- END IF; -- last number zero, new number not OR new number zero, last number not -- END IF; -- Maximum Value -- END IF; -- contract active -- END IF; -- if l_success -- END LOOP; END IF; -- IF l_success THEN -- IF l_copa_id IS NOT NULL THEN -- Validate Percentage Split values -- get the percentage split of the virtual network point OPEN c_perc_split('Y'); FETCH c_perc_split INTO l_vnepo_per_split; CLOSE c_perc_split; -- -- get the percentage split total of the network points OPEN c_perc_split('N'); FETCH c_perc_split INTO l_tot_per_split; CLOSE c_perc_split; -- -- check that all of the network points are displayed on one page IF nepo_count(p_contract_id) <= 25 THEN IF l_vnepo_per_split <> l_tot_per_split THEN -- l_success := FALSE; -- l_error_message := caco_utilities.get_module_text(3924); -- Percentage Split values of network points must add up to the Percentage Split value of the virtual network point END IF; ELSE -- there are more than 25 network points so we have to be more lenient on the percentage -- split validation as the network points are displayed on multiple pages IF l_vnepo_per_split < l_tot_per_split THEN -- l_success := FALSE; -- l_error_message := caco_utilities.get_module_text(3915); -- Percentage Split values of network points must add up to less than or equal to the Percentage Split value of the virtual network point END IF; END IF; -- Check if the contract is an entry mandatory offer contract IF l_success THEN IF efno_contracts.emo_contract(p_contract_id) = 'Y' THEN -- check if the percentage split values have changed FOR i IN c_cnppv_per_split LOOP l_count := l_count + 1; caco_debug.putline('comparing '||i.value||' with '||l_perc_split_array(l_count).value); IF i.value <> l_perc_split_array(l_count).value THEN recalc_noms := TRUE; EXIT; END IF; END LOOP; IF recalc_noms THEN -- recalculate any nominations for the contract which are before gate closure caco_debug.putline('recalculating noms'); l_success := recalc_emo_noms(p_contract_id, l_error_message); END IF; END IF; END IF; END IF; END IF; -- IF l_success THEN -- -- Call the values screen with just the contract id and the success flag efnow092$.contract_values_p2( p_contract_id => p_contract_id , p_page_no => p_page_no , p_success => 'Y' ); -- ELSE ROLLBACK TO SAVEPOINT before_upd_cnppv; -- -- If the supplied values had invalid formats IF l_error_message IS NULL THEN IF l_update_error THEN l_error_message := caco_utilities.get_module_text(2210); -- An error occurred whilst updating the contract values. Please contact support stating Contract Number END IF; IF l_invalid_format THEN l_error_message := l_error_message||' '||caco_utilities.get_module_text(2240)||'.'; -- Data supplied with invalid number formats END IF; IF l_invalid_number THEN l_error_message := l_error_message||' '||caco_utilities.get_module_text(2289)||'.'; -- Non numeric data supplied END IF; IF l_min_gt_max THEN l_error_message := l_error_message||' '||caco_utilities.get_module_text(2354)||'.'; -- Minimum greater than Maximum END IF; IF l_ctr_lt_min THEN l_error_message := l_error_message||' '||caco_utilities.get_module_text(2355)||'.'; -- Contracted less than Minimum END IF; IF l_ctr_gt_max THEN l_error_message := l_error_message||' '||caco_utilities.get_module_text(2356)||'.'; -- Contracted greater than Maximum END IF; IF l_negatives THEN l_error_message := l_error_message||' '||caco_utilities.get_module_text(2357); -- All values must be zero or greater END IF; END IF; -- -- pass the data back... efnow092$.contract_values_p2( p_contract_id => p_contract_id , p_page_no => p_page_no , p_error => 'Y' , p_err_msg => l_error_message , p_cnppv_id => p_cnppv_id , p_value => l_val_no_thou_sep , p_data_error => l_data_error ); -- END IF; -- -- END upd_cnppv_records; PROCEDURE upd_cotc ( p_cote_id IN contract_templates.cote_id%TYPE , p_cate_id IN categories.cate_id%TYPE , p_display_sequence IN NUMBER ) IS BEGIN -- -- Update the template category -- UPDATE contract_template_categories ctc SET ctc.display_sequence = p_display_sequence WHERE ctc.cote_id = p_cote_id AND ctc.cate_id = p_cate_id; -- -- Now update the related contract categories -- UPDATE contract_categories cc SET cc.display_sequence = p_display_sequence WHERE cc.cate_id = p_cate_id AND cc.cont_id IN ( SELECT cont_id FROM contracts c WHERE c.cote_id = p_cote_id ); -- END upd_cotc; -- Insert or Update Contract Rules inherited from a Contract Template -- needs to be called immediately after insert of a new contract -- or immediately before update of an existing contract -- (otherwise the template id will already be changed!) FUNCTION ins_or_upd_inh_rules( p_ins_or_upd IN VARCHAR2 , p_contract_id IN NUMBER , p_template_id IN NUMBER , p_err_message OUT VARCHAR2 ) RETURN BOOLEAN IS CURSOR c_cont IS SELECT cote_id FROM contracts WHERE cont_id = p_contract_id; -- -- Cursor to list the inherited rules for the new contract template CURSOR c_inh_rules IS SELECT rule_id , display_sequence FROM contract_template_rules WHERE cote_id = p_template_id; -- l_temp_cote_id contracts.cote_id%TYPE := NULL; -- l_success BOOLEAN := TRUE; -- BEGIN -- SAVEPOINT before_inh_rules; -- IF p_ins_or_upd = 'UPDATE' THEN -- Firstly, lets check that the contract template has changed -- if not - we have no work to do! OPEN c_cont; FETCH c_cont INTO l_temp_cote_id; CLOSE c_cont; -- ELSE -- Inserting - just set to zero l_temp_cote_id := 0; END IF; -- IF NVL(l_temp_cote_id,0) != NVL(p_template_id,0) THEN -- -- The Template has been changed -- We need to remove the existing inherited contract rules -- and add the new ones from the new contract template IF p_ins_or_upd = 'UPDATE' AND NVL(l_temp_cote_id,0) != 0 THEN -- If we are updating and the old template is not null then -- we need to remove the existing inherited rules from contract_rules BEGIN DELETE contract_rules WHERE cont_id = p_contract_id AND NVL(inherited,'N') = 'Y'; EXCEPTION WHEN others THEN l_success := FALSE; p_err_message := caco_utilities.get_module_text(2293); -- Removal of old template inherited rules failed. Please contact support caco_debug.putline('efno_contracts.ins_or_upd_inh_rules failed deleting inherited rules : ' ||sqlerrm(sqlcode)); -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => 'Failed deleting inherited rules: '||sqlerrm(sqlcode) , p_source => 'efno_contracts.ins_or_upd_inh_rules'); -- END; -- END IF; -- IF l_success THEN -- We can insert the inherited rules <> FOR r IN c_inh_rules LOOP -- BEGIN INSERT INTO contract_rules ( coru_id , display_sequence , inherited , cont_id , coru_type , rule_id ) VALUES ( coru_seq.NEXTVAL , r.display_sequence , 'Y' , p_contract_id , 'ROW' , r.rule_id ); EXCEPTION WHEN others THEN l_success := FALSE; caco_debug.putline('efno_contracts.ins_or_upd_inh_rules failed inserting inherited rules : ' ||sqlerrm(sqlcode)); -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => 'Failed inserting inherited rules: '||sqlerrm(sqlcode) , p_source => 'efno_contracts.ins_or_upd_inh_rules'); -- EXIT ins_inh_rules_loop; END; -- END LOOP ins_inh_rules_loop; -- END IF; -- END IF; -- IF NOT l_success THEN ROLLBACK TO SAVEPOINT before_inh_rules; END IF; -- RETURN l_success; -- END ins_or_upd_inh_rules; FUNCTION del_conp_cnppv( p_conp_id IN cont_network_points.conp_id%TYPE , p_return_error OUT VARCHAR2 ) RETURN BOOLEAN IS -- l_success BOOLEAN := TRUE; -- BEGIN SAVEPOINT before_del_cnppv; -- BEGIN DELETE cont_net_point_param_vals WHERE conp_id = p_conp_id; EXCEPTION WHEN others THEN l_success := FALSE; p_return_error := caco_utilities.get_module_text(2213); -- An unexpected error has occurred while deleting contract network point. Please contact support caco_debug.putline('efno_contracts.del_conp_cnppv : ' ||'Delete of contract network point parameter values failed : ' ||sqlerrm(sqlcode)); -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => 'Failed deleting cnppv: '||sqlerrm(sqlcode) , p_source => 'efno_contracts.del_conp_cnppv'); -- END; -- IF NOT l_success THEN ROLLBACK TO SAVEPOINT before_del_cnppv; END IF; -- RETURN l_success; -- END del_conp_cnppv; FUNCTION del_conp_icp( p_conp_id IN cont_network_points.conp_id%TYPE , p_return_error OUT VARCHAR2 ) RETURN BOOLEAN IS -- l_success BOOLEAN := TRUE; -- BEGIN -- SAVEPOINT before_del_icp; -- BEGIN DELETE inty_conp_params WHERE conp_id = p_conp_id; EXCEPTION WHEN OTHERS THEN l_success := FALSE; p_return_error := caco_utilities.get_module_text(2213); -- An unexpected error has occurred while deleting contract network point. Please contact support caco_debug.putline('efno_contracts.del_conp_icp: ' ||'Delete of interruption type contract network point parameter values failed : ' ||SQLERRM(SQLCODE)); -- Write an error and carry on cout_err.report_and_go( p_exception_number => SQLCODE , p_exception_message => 'Failed deleting icp: '||SQLERRM(SQLCODE) , p_source => 'efno_contracts.del_conp_icp'); -- END; -- IF NOT l_success THEN ROLLBACK TO SAVEPOINT before_del_icp; END IF; -- RETURN l_success; -- END del_conp_icp; FUNCTION ins_conp_cnppv( p_contract_id IN contracts.cont_id%TYPE , p_conp_id IN cont_network_points.conp_id%TYPE , p_return_error OUT VARCHAR2 ) RETURN BOOLEAN IS -- Cursor to list all parameters stored for this contract CURSOR c_copa IS SELECT copa_id FROM contract_parameters WHERE cont_id = p_contract_id; -- l_success BOOLEAN := TRUE; -- BEGIN SAVEPOINT before_ins_cnppv; -- <> FOR r IN c_copa LOOP -- BEGIN INSERT INTO cont_net_point_param_vals ( cnppv_id , value , conp_id , copa_id ) VALUES ( cnppv_seq.NEXTVAL , 0 , p_conp_id , r.copa_id ); EXCEPTION WHEN others THEN ROLLBACK TO SAVEPOINT before_ins_cnppv; l_success := FALSE; p_return_error := caco_utilities.get_module_text(2215); -- An unexpected error has occurred while inserting contract network point. Please contact support caco_debug.putline('efno_contracts.ins_conp_cnppv : ' ||'Insert of contract network point parameter values failed : ' ||sqlerrm(sqlcode)); -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => 'Failed inserting cnppv: '||sqlerrm(sqlcode) , p_source => 'efno_contracts.ins_conp_cnppv'); -- EXIT ins_cnppv_loop; END; -- END LOOP ins_cnppv_loop; -- RETURN l_success; -- END ins_conp_cnppv; FUNCTION insert_cont_nepo( p_contract_id IN contracts.cont_id%TYPE , p_network_point_array IN network_point_array , p_return_error OUT VARCHAR2 ) RETURN BOOLEAN IS -- l_conp_id cont_network_points.conp_id%TYPE := 0; l_success BOOLEAN := TRUE; -- BEGIN SAVEPOINT before_ins_cont_nepo; -- <> FOR i IN 1..p_network_point_array.COUNT LOOP -- BEGIN INSERT INTO cont_network_points ( conp_id , display_sequence , nepo_id , cont_id ) VALUES ( conp_seq.NEXTVAL , ( SELECT NVL(MAX(display_sequence),0)+10 FROM cont_network_points WHERE cont_id = p_contract_id ) , p_network_point_array(i) , p_contract_id ) RETURNING conp_id INTO l_conp_id; EXCEPTION WHEN others THEN l_success := FALSE; p_return_error := caco_utilities.get_module_text(2327); -- An unexpected error has occurred while inserting new contract. Please contact support caco_debug.putline('efno_contracts.insert_cont_nepo : ' ||'Insert of new contract network points failed : '||sqlerrm(sqlcode)); -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => 'Failed inserting new CONP: '||sqlerrm(sqlcode) , p_source => 'efno_contracts.insert_conp_nepo'); -- ROLLBACK TO SAVEPOINT before_ins_cont_nepo; EXIT ins_net_point_loop; END; -- l_success := ins_conp_cnppv( p_contract_id , l_conp_id , p_return_error ); IF NOT l_success THEN EXIT ins_net_point_loop; END IF; -- END LOOP ins_net_point_loop; -- -- Invalidate any interruption types related to this contract -- IF p_network_point_array.COUNT > 0 THEN -- -- l_success := invalidate_inty(p_contract_id); -- -- END IF; -- removed as part of INT027 RETURN l_success; -- END insert_cont_nepo; FUNCTION ins_copa_cnppv( p_contract_id IN contracts.cont_id%TYPE , p_copa_id IN contract_parameters.copa_id%TYPE , p_return_error OUT VARCHAR2 ) RETURN BOOLEAN IS -- Cursor to loop through all network points for the given contract CURSOR c_conp IS SELECT conp_id FROM cont_network_points WHERE cont_id = p_contract_id; -- l_success BOOLEAN := TRUE; -- BEGIN SAVEPOINT before_ins_cnppv; -- <> FOR r IN c_conp LOOP -- BEGIN INSERT INTO cont_net_point_param_vals ( cnppv_id , value , conp_id , copa_id ) VALUES ( cnppv_seq.NEXTVAL , 0 , r.conp_id , p_copa_id ); EXCEPTION WHEN others THEN ROLLBACK TO SAVEPOINT before_ins_cnppv; caco_debug.putline('efno_contracts.ins_copa_cnppv failed : ' ||sqlerrm(sqlcode)); -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => 'Failed inserting cnppv: '||sqlerrm(sqlcode) , p_source => 'efno_contracts.ins_copa_cnppv'); -- l_success := FALSE; p_return_error := caco_utilities.get_module_text(2265); -- Inserting Contract values failed. Please contact support EXIT ins_cnppv_loop; END; -- END LOOP ins_cnppv_loop; -- RETURN l_success; -- END ins_copa_cnppv; FUNCTION ins_contract_pars( p_contract_id IN contracts.cont_id%TYPE , p_pars_id IN parameters.pars_id%TYPE , p_inherited IN VARCHAR2 , p_return_error OUT VARCHAR2 ) RETURN BOOLEAN IS -- l_copa_id contract_parameters.copa_id%TYPE := 0; l_success BOOLEAN := TRUE; -- BEGIN SAVEPOINT before_ins_cont_pars; -- BEGIN INSERT INTO contract_parameters ( copa_id , inherited , display_sequence , cont_id , pars_id ) VALUES ( copa_seq.NEXTVAL , p_inherited , 0 -- parameters are not inherited from a category , p_contract_id , p_pars_id ) RETURNING copa_id INTO l_copa_id; EXCEPTION WHEN others THEN l_success := FALSE; p_return_error := caco_utilities.get_module_text(2216); -- An unexpected error has occurred while inserting contract parameter. Please contact support caco_debug.putline('efno_contracts.ins_contract_pars: ' ||'Insert of contract parameter failed : ' ||sqlerrm(sqlcode)); -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => 'Failed inserting contract parameters: '||sqlerrm(sqlcode) , p_source => 'efno_contracts.ins_contract_pars'); -- END; -- IF l_success THEN -- insert the relevant contract network point parameter values l_success := ins_copa_cnppv( p_contract_id , l_copa_id , p_return_error ); -- END IF; -- IF NOT l_success THEN ROLLBACK TO SAVEPOINT before_ins_cont_pars; END IF; -- RETURN l_success; -- END ins_contract_pars; FUNCTION upd_contract_cate( p_contract_id IN contracts.cont_id%TYPE , p_cate_id IN categories.cate_id%TYPE , p_inherited IN VARCHAR2 , p_return_error OUT VARCHAR2 ) RETURN BOOLEAN IS -- l_success BOOLEAN := TRUE; -- BEGIN SAVEPOINT before_upd_cont_cate; -- -- But if the category DOES exist - make sure it is correctly inherited BEGIN UPDATE contract_categories coca SET inherited = p_inherited WHERE cont_id = p_contract_id AND cate_id = p_cate_id; EXCEPTION WHEN others THEN l_success := FALSE; p_return_error := caco_utilities.get_module_text(2221); -- An unexpected error has occurred while updating contract category. Please contact support caco_debug.putline('efno_contracts.upd_contract_cae: ' ||'Update of contract category failed : ' ||sqlerrm(sqlcode)); -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => 'Failed updating contract categories: '||sqlerrm(sqlcode) , p_source => 'efno_contracts.upd_contract_cate'); -- END; -- IF l_success THEN -- Also check the parameters.... BEGIN UPDATE contract_parameters copa SET inherited = p_inherited WHERE cont_id = p_contract_id AND copa.copa_id IN ( SELECT copa2.copa_id FROM contract_parameters copa2 , parameters pars WHERE copa2.pars_id = pars.pars_id AND copa2.cont_id = p_contract_id AND pars.cate_id = p_cate_id ); EXCEPTION WHEN others THEN l_success := FALSE; p_return_error := caco_utilities.get_module_text(2221); -- An unexpected error has occurred while updating contract category. Please contact support caco_debug.putline('efno_contracts.upd_contract_cate: ' ||'Update of contract category failed (updating parameters): ' ||sqlerrm(sqlcode)); -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => 'Failed updating contract category related parameters: '||sqlerrm(sqlcode) , p_source => 'efno_contracts.upd_contract_cate'); -- END; -- END IF; -- IF NOT l_success THEN ROLLBACK TO SAVEPOINT before_upd_cont_cate; END IF; -- RETURN l_success; -- END upd_contract_cate; FUNCTION del_contract_cate( p_contract_id IN contracts.cont_id%TYPE , p_cate_id IN categories.cate_id%TYPE , p_return_error OUT VARCHAR2 ) RETURN BOOLEAN IS -- l_success BOOLEAN := TRUE; -- BEGIN SAVEPOINT before_del_cont_cate; -- -- Delete contract parameter values for this category BEGIN DELETE cont_net_point_param_vals cnppv WHERE cnppv.copa_id IN ( SELECT copa.copa_id FROM contract_parameters copa , parameters pars WHERE copa.cont_id = p_contract_id AND copa.pars_id = pars.pars_id AND pars.cate_id = p_cate_id ); EXCEPTION WHEN others THEN l_success := FALSE; p_return_error := caco_utilities.get_module_text(2329); -- An unexpected error has occurred while updating contract. Please contact support caco_debug.putline('efno_contracts.del_contract_cate: ' ||'Update of contract category failed ' ||'(deleting associated parameter values) : ' ||sqlerrm(sqlcode)); -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => 'Failed deleting cnppv: '||sqlerrm(sqlcode) , p_source => 'efno_contracts.del_contract_cate'); -- END; -- IF l_success THEN -- Delete contract parameters inherited from this category BEGIN DELETE contract_parameters copa WHERE copa.cont_id = p_contract_id AND copa.pars_id IN ( SELECT pars.pars_id FROM parameters pars WHERE pars.cate_id = p_cate_id ); EXCEPTION WHEN others THEN l_success := FALSE; p_return_error := caco_utilities.get_module_text(2329); -- An unexpected error has occurred while updating contract. Please contact support caco_debug.putline('efno_contracts.del_contract_cate: ' ||'Update of contract category failed ' ||'(deleting associated parameters) : ' ||sqlerrm(sqlcode)); -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => 'Failed deleting COPA: '||sqlerrm(sqlcode) , p_source => 'efno_contracts.del_contract_cate'); -- END; END IF; -- IF l_success THEN -- Delete the given contract category BEGIN DELETE contract_categories WHERE cont_id = p_contract_id AND cate_id = p_cate_id; EXCEPTION WHEN others THEN l_success := FALSE; p_return_error := caco_utilities.get_module_text(2329); -- An unexpected error has occurred while updating contract. Please contact support caco_debug.putline('efno_contracts.del_contract_cate: ' ||'Update of contract category failed (deleting category): ' ||sqlerrm(sqlcode)); -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => 'Failed deleting COCA: '||sqlerrm(sqlcode) , p_source => 'efno_contracts.del_contract_cate'); -- END; END IF; -- IF NOT l_success THEN ROLLBACK TO SAVEPOINT before_del_cont_cate; END IF; -- RETURN l_success; -- END del_contract_cate; FUNCTION ins_contract_cate( p_contract_id IN contracts.cont_id%TYPE , p_cate_id IN categories.cate_id%TYPE , p_display_sequence IN categories.display_sequence%TYPE DEFAULT NULL , p_inherited IN VARCHAR2 , p_return_error OUT VARCHAR2 ) RETURN BOOLEAN IS -- Cursor to get associated parameters for INSERTed categories CURSOR c_cate_pars IS SELECT pars.pars_id pars_id , cate.display_sequence display_sequence FROM parameters pars , categories cate WHERE pars.cate_id = p_cate_id AND pars.cate_id = cate.cate_id; -- l_copa_id contract_parameters.copa_id%TYPE := 0; l_success BOOLEAN := TRUE; -- BEGIN -- SAVEPOINT before_ins_cont_cate; -- BEGIN IF p_display_sequence IS NULL THEN INSERT INTO contract_categories ( coca_id , inherited , display_sequence , cont_id , cate_id ) VALUES ( coca_seq.NEXTVAL , p_inherited , ( SELECT cate.display_sequence FROM categories cate WHERE cate.cate_id = p_cate_id ) , p_contract_id , p_cate_id ); ELSE INSERT INTO contract_categories ( coca_id , inherited , display_sequence , cont_id , cate_id ) VALUES ( coca_seq.NEXTVAL , p_inherited , p_display_sequence , p_contract_id , p_cate_id ); END IF; EXCEPTION WHEN others THEN l_success := FALSE; p_return_error := caco_utilities.get_module_text(2214); -- An unexpected error has occurred while inserting contract category. Please contact support caco_debug.putline('efno_contracts.ins_contract_cate: ' ||'Insert of contract category failed : ' ||sqlerrm(sqlcode)); -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => 'Failed inserting COCA: '||sqlerrm(sqlcode) , p_source => 'efno_contracts.ins_contract_cate'); -- END; -- -- We also need to insert any parameters associated with this category IF l_success THEN -- <> FOR r IN c_cate_pars LOOP -- l_copa_id := 0; -- BEGIN INSERT INTO contract_parameters ( copa_id , display_sequence , inherited , cont_id , pars_id ) VALUES ( copa_seq.NEXTVAL , r.display_sequence , p_inherited , p_contract_id , r.pars_id ) RETURNING copa_id INTO l_copa_id; EXCEPTION WHEN others THEN l_success := FALSE; p_return_error := caco_utilities.get_module_text(2214); -- An unexpected error has occurred while inserting contract category. Please contact support caco_debug.putline('efno_contracts.ins_contract_cate: ' ||'Update of contract category associated parameters failed : ' ||sqlerrm(sqlcode)); -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => 'Failed inserting COCA associated COPA'||sqlerrm(sqlcode) , p_source => 'efno_contracts.ins_contract_cate'); -- EXIT cont_cate_loop; END; -- IF l_success THEN -- insert the relevant contract network point parameter values l_success := ins_copa_cnppv( p_contract_id , l_copa_id , p_return_error ); -- IF NOT l_success THEN EXIT cont_cate_loop; END IF; -- END IF; -- END LOOP cont_cate_loop; -- end of inserting associated parameters -- END IF; -- IF NOT l_success THEN ROLLBACK TO SAVEPOINT before_ins_cont_cate; END IF; -- RETURN l_success; -- END ins_contract_cate; -- For Updating Contract Network Points - to enable delete of those no longer attached FUNCTION nepo_in_array( p_id IN NUMBER , p_nepo_array IN network_point_array ) RETURN BOOLEAN IS l_success BOOLEAN := FALSE; BEGIN IF NVL(p_nepo_array.COUNT,0) > 0 THEN FOR i IN p_nepo_array.FIRST..p_nepo_array.LAST LOOP IF p_nepo_array(i) = p_id THEN l_success := TRUE; END IF; END LOOP; END IF; RETURN l_success; END nepo_in_array; -- -- For Updating Contract Network Points - to determine if we need to insert into DB FUNCTION nepo_in_db( p_nepo_id IN NUMBER , p_contract_id IN NUMBER ) RETURN BOOLEAN IS CURSOR c_nepo IS SELECT 'Y' FROM cont_network_points WHERE cont_id = p_contract_id AND nepo_id = p_nepo_id; -- l_success BOOLEAN := FALSE; l_dummy VARCHAR2(1) := 'X'; -- BEGIN OPEN c_nepo; FETCH c_nepo INTO l_dummy; IF c_nepo%FOUND THEN l_success := TRUE; END IF; CLOSE c_nepo; RETURN l_success; END nepo_in_db; -- -- For Updating Contract Categories - to enable delete of those no longer attached FUNCTION coca_in_array( p_id IN NUMBER , p_cate_array IN category_array ) RETURN BOOLEAN IS l_success BOOLEAN := FALSE; BEGIN IF NVL(p_cate_array.COUNT,0) > 0 THEN FOR i IN p_cate_array.FIRST..p_cate_array.LAST LOOP IF p_cate_array(i).cate_id = p_id THEN l_success := TRUE; END IF; END LOOP; END IF; RETURN l_success; END coca_in_array; -- -- Function to check if an virtual network point exists in an array of nepo_ids FUNCTION vnepo_count( p_network_point_array IN network_point_array ) RETURN NUMBER IS -- CURSOR c_vnepo(cp_nepo_id network_points.nepo_id%TYPE) IS SELECT nepo.nepo_type FROM network_points nepo WHERE nepo_id = cp_nepo_id; -- l_count NUMBER := 0; l_nepo_type network_points.nepo_type%TYPE; -- BEGIN FOR i IN 1..p_network_point_array.COUNT LOOP OPEN c_vnepo(p_network_point_array(i)); FETCH c_vnepo INTO l_nepo_type; CLOSE c_vnepo; -- IF l_nepo_type = 'V' THEN l_count := l_count + 1; END IF; -- END LOOP; RETURN l_count; END vnepo_count; -- -- Function to check if a template is an Entry Mandatory Offer template FUNCTION emo_template( p_template_id IN NUMBER ) RETURN BOOLEAN IS -- CURSOR c_emo IS SELECT cote.entry_mandatory_offer FROM contract_templates cote WHERE cote_id = p_template_id; -- l_return BOOLEAN := FALSE; l_emo contract_templates.entry_mandatory_offer%TYPE; -- BEGIN OPEN c_emo; FETCH c_emo INTO l_emo; CLOSE c_emo; -- IF l_emo = 'Y' THEN l_return := TRUE; END IF; -- RETURN l_return; END emo_template; -- Function to check if a contract is an Entry Mandatory Offer contract FUNCTION emo_contract( p_contract_id IN NUMBER ) RETURN VARCHAR2 IS -- CURSOR c_emo IS SELECT cote.entry_mandatory_offer FROM contract_templates cote ,contracts cont WHERE cote.cote_id = cont.cote_id AND cont.cont_id = p_contract_id; -- l_return VARCHAR2(1) := 'N'; l_emo contract_templates.entry_mandatory_offer%TYPE; -- BEGIN OPEN c_emo; FETCH c_emo INTO l_emo; CLOSE c_emo; -- IF l_emo = 'Y' THEN l_return := 'Y'; END IF; -- RETURN l_return; END emo_contract; -- Function to check if a contract network point is a virtual network point FUNCTION virtual_nepo( p_conp_id IN NUMBER ) RETURN BOOLEAN IS -- CURSOR c_nepo IS SELECT nepo.nepo_type FROM network_points nepo ,cont_network_points conp WHERE nepo.nepo_id = conp.nepo_id AND conp.conp_id = p_conp_id; -- l_return BOOLEAN := FALSE; l_nepo_type network_points.nepo_type%TYPE; -- BEGIN OPEN c_nepo; FETCH c_nepo INTO l_nepo_type; CLOSE c_nepo; -- IF l_nepo_type = 'V' THEN l_return := TRUE; END IF; -- RETURN l_return; END virtual_nepo; /** -- FUNCTION nepo_in_contract -- -- Determines whether a given network point ID is being used in a contract -- -- used in EFNOW030 - maintain network points -- -- %param p_nepo_id The unique identifier for a network point -- -- %return BOOLEAN Indicates whether the network point is being used */ FUNCTION nepo_in_contract ( p_nepo_id IN network_points.nepo_id%TYPE ) RETURN BOOLEAN IS -- l_return BOOLEAN := FALSE; -- BEGIN -- FOR cont IN ( SELECT NULL FROM cont_network_points conp, network_points nepo WHERE conp.nepo_id = nepo.nepo_id AND nepo.nepo_id = p_nepo_id ) LOOP -- l_return := TRUE; -- END LOOP; -- RETURN l_return; -- END nepo_in_contract; -- -- For Updating Contract Categories - to determine if we need to insert into DB FUNCTION coca_in_db( p_cate_id IN NUMBER , p_contract_id IN NUMBER ) RETURN BOOLEAN IS CURSOR c_coca IS SELECT 'Y' FROM contract_categories WHERE cont_id = p_contract_id AND cate_id = p_cate_id; -- l_success BOOLEAN := FALSE; l_dummy VARCHAR2(1) := 'X'; -- BEGIN OPEN c_coca; FETCH c_coca INTO l_dummy; IF c_coca%FOUND THEN l_success := TRUE; END IF; CLOSE c_coca; RETURN l_success; END coca_in_db; -- For Updating Contract Parameters - to enable delete of those no longer attached FUNCTION copa_in_array( p_id IN NUMBER , p_pars_array IN parameter_array ) RETURN BOOLEAN IS l_success BOOLEAN := FALSE; BEGIN IF NVL(p_pars_array.COUNT,0) > 0 THEN FOR i IN p_pars_array.FIRST..p_pars_array.LAST LOOP IF p_pars_array(i).pars_id = p_id THEN l_success := TRUE; END IF; END LOOP; END IF; RETURN l_success; END copa_in_array; -- For Updating Contract Parameters - to determine if we need to insert into DB -- Note: We are relying on the contract screen to only show those parameters -- that are NOT associated with categories FUNCTION copa_in_db( p_pars_id IN NUMBER , p_contract_id IN NUMBER ) RETURN BOOLEAN IS CURSOR c_copa IS SELECT 'Y' FROM contract_parameters WHERE cont_id = p_contract_id AND pars_id = p_pars_id; -- l_success BOOLEAN := FALSE; l_dummy VARCHAR2(1) := 'X'; -- BEGIN OPEN c_copa; FETCH c_copa INTO l_dummy; IF c_copa%FOUND THEN l_success := TRUE; END IF; CLOSE c_copa; RETURN l_success; END copa_in_db; PROCEDURE del_redundant_nepo( p_contract_id IN contracts.cont_id%TYPE , p_network_point_array IN network_point_array , p_success OUT BOOLEAN , p_return_error OUT VARCHAR2 ) IS -- l_dummy NUMBER := 0; -- CURSOR c_cont_nepo( cp_cont_id IN NUMBER) IS SELECT nepo_id , conp_id FROM cont_network_points WHERE cont_id = cp_cont_id FOR UPDATE; -- BEGIN p_success := TRUE; -- <> FOR r IN c_cont_nepo( p_contract_id ) LOOP -- IF NOT nepo_in_array( r.nepo_id , p_network_point_array ) THEN -- -- This network point doesn't exist in the new set, needs to be removed if possible -- Check for any nominations for this network point -- SELECT COUNT(*) INTO l_dummy FROM nom_net_point_cat_vals n WHERE n.conp_id = r.conp_id; -- IF l_dummy > 0 THEN -- p_success := FALSE; p_return_error := caco_utilities.get_module_text(2520); -- a nomination exists -- EXIT upd_del_net_point_loop; -- END IF; -- -- Check for any interruptions for this network point -- SELECT COUNT(*) INTO l_dummy FROM int_conp_coca_vals iccv WHERE iccv.conp_id = r.conp_id; -- IF l_dummy > 0 THEN -- p_success := FALSE; p_return_error := caco_utilities.get_module_text(3857); -- an interruption exists -- EXIT upd_del_net_point_loop; -- END IF; -- -- delete the associated CNPPV records -- p_success := del_conp_cnppv( r.conp_id , p_return_error ); -- IF NOT p_success THEN EXIT upd_del_net_point_loop; END IF; -- -- Remove any interruption types -- p_success := del_conp_icp( r.conp_id , p_return_error ); -- IF NOT p_success THEN EXIT upd_del_net_point_loop; END IF; -- -- Finally, remove the conp record -- BEGIN DELETE cont_network_points WHERE CURRENT OF c_cont_nepo; EXCEPTION WHEN others THEN p_success := FALSE; p_return_error := caco_utilities.get_module_text(2329); -- An unexpected error has occurred while updating contract. Please contact support caco_debug.putline('efno_contracts.ins_or_upd_contract_p1: ' ||'Update of contract network points failed (delete): '||sqlerrm(sqlcode)); -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => 'Failed deleting CONP: '||sqlerrm(sqlcode) , p_source => 'efno_contracts.del_redundant_nepo'); -- EXIT upd_del_net_point_loop; END; END IF; -- END LOOP upd_del_net_point_loop; -- END del_redundant_nepo; PROCEDURE ins_required_nepo( p_contract_id IN contracts.cont_id%TYPE , p_network_point_array IN network_point_array , p_success OUT BOOLEAN , p_return_error OUT VARCHAR2 ) IS l_conp_id cont_network_points.conp_id%TYPE; BEGIN SAVEPOINT before_ins_nepo; -- p_success := TRUE; -- <> FOR i IN 1..p_network_point_array.COUNT LOOP -- IF NOT nepo_in_db( p_network_point_array(i) , p_contract_id ) THEN l_conp_id := 0; -- BEGIN INSERT INTO cont_network_points ( conp_id , display_sequence , nepo_id , cont_id ) VALUES ( conp_seq.NEXTVAL , ( SELECT NVL(MAX(display_sequence),0)+10 FROM cont_network_points WHERE cont_id = p_contract_id ) , p_network_point_array(i) , p_contract_id ) RETURNING conp_id INTO l_conp_id; EXCEPTION WHEN others THEN p_success := FALSE; p_return_error := caco_utilities.get_module_text(2329); -- An unexpected error has occurred while updating contract. Please contact support caco_debug.putline('efno_contracts.ins_or_upd_contract_p1: ' ||'Update of contract network points failed (insert): ' ||sqlerrm(sqlcode)); -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => 'Failed inserting CONP: '||sqlerrm(sqlcode) , p_source => 'efno_contracts.ins_required_nepov'); -- ROLLBACK TO SAVEPOINT before_ins_nepo; EXIT upd_ins_net_point_loop; END; -- -- Now insert the relevant CNPPV records p_success := ins_conp_cnppv( p_contract_id , l_conp_id , p_return_error ); -- IF NOT p_success THEN EXIT upd_ins_net_point_loop; END IF; -- END IF; -- END LOOP upd_ins_net_point_loop; -- -- Invalidate any interruption types related to this contract -- IF p_network_point_array.COUNT > 0 THEN -- -- p_success := invalidate_inty(p_contract_id); -- -- END IF; -- INT027 -- END ins_required_nepo; PROCEDURE del_redundant_cate( p_contract_id IN contracts.cont_id%TYPE , p_category_array IN category_array , p_success OUT BOOLEAN , p_return_error OUT VARCHAR2 ) IS -- CURSOR c_cont_cate( cp_cont_id IN NUMBER ) IS SELECT cate_id FROM contract_categories WHERE cont_id = cp_cont_id FOR UPDATE; -- BEGIN p_success := TRUE; -- <> FOR r IN c_cont_cate( p_contract_id ) LOOP -- IF NOT coca_in_array( r.cate_id , p_category_array ) THEN -- This Category doesn't exist in the new set p_success := del_contract_cate( p_contract_id , r.cate_id , p_return_error ); -- IF NOT p_success THEN EXIT upd_del_coca_loop; END IF; -- END IF; -- END LOOP upd_del_coca_loop; -- END del_redundant_cate; PROCEDURE ins_required_cate( p_contract_id IN contracts.cont_id%TYPE , p_template_id IN contract_templates.cote_id%TYPE , p_category_array IN category_array , p_success OUT BOOLEAN , p_return_error OUT VARCHAR2 ) IS -- CURSOR c_cotc( cp_cote_id IN NUMBER , cp_cate_id IN NUMBER ) IS SELECT 'Y' FROM contract_template_categories WHERE cote_id = cp_cote_id AND cate_id = cp_cate_id; -- l_inherited VARCHAR2(1) := 'N'; -- BEGIN p_success := TRUE; -- <> FOR i IN 1..p_category_array.COUNT LOOP -- l_inherited := 'N'; -- Test if this category was inherited OPEN c_cotc( p_template_id, p_category_array(i).cate_id ); FETCH c_cotc INTO l_inherited; CLOSE c_cotc; -- IF NOT coca_in_db( p_category_array(i).cate_id , p_contract_id ) THEN -- -- Current category does not exist in the DB so we need to INSERT p_success := ins_contract_cate( p_contract_id , p_category_array(i).cate_id , NULL , l_inherited , p_return_error ); -- IF NOT p_success THEN EXIT upd_ins_coca_loop; END IF; -- ELSE -- But if the category DOES exist - make sure it is correctly inherited p_success := upd_contract_cate( p_contract_id , p_category_array(i).cate_id , l_inherited , p_return_error ); -- IF NOT p_success THEN EXIT upd_ins_coca_loop; END IF; -- END IF; -- end of if contract category not already in DB END LOOP upd_ins_coca_loop; -- END ins_required_cate; PROCEDURE del_redundant_pars( p_contract_id IN contracts.cont_id%TYPE , p_parameter_array IN parameter_array , p_success OUT BOOLEAN , p_return_error OUT VARCHAR2 ) IS -- CURSOR c_cont_pars( cp_cont_id IN NUMBER ) IS SELECT copa.pars_id pars_id , copa.copa_id copa_id FROM contract_parameters copa , parameters pars WHERE copa.pars_id = pars.pars_id AND copa.cont_id = cp_cont_id AND pars.cate_id IS NULL; -- BEGIN SAVEPOINT before_del_pars; p_success := TRUE; -- <> FOR r IN c_cont_pars( p_contract_id ) LOOP -- IF NOT copa_in_array( r.pars_id , p_parameter_array ) THEN -- This Parameter doesn't exist in the new set -- We need to delete the parameter after deleting the contract net point param values -- can use WHERE CURRENT OF cursor for deleting the COPA BEGIN DELETE cont_net_point_param_vals WHERE copa_id = r.copa_id; -- DELETE contract_parameters WHERE copa_id = r.copa_id; EXCEPTION WHEN others THEN p_success := FALSE; p_return_error := caco_utilities.get_module_text(2329); -- An unexpected error has occurred while updating contract. Please contact support caco_debug.putline('efno_contracts.ins_or_upd_contract_p1: ' ||'Update of contract parameters failed (deleting parameter): ' ||sqlerrm(sqlcode)); -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => 'Failed deleting CNPPV or COPA: '||sqlerrm(sqlcode) , p_source => 'efno_contracts.del_redundant_pars'); -- ROLLBACK TO SAVEPOINT before_del_pars; EXIT upd_del_copa_loop; END; -- END IF; -- end when the parameter has been removed from the contract -- END LOOP upd_del_copa_loop; -- END del_redundant_pars; PROCEDURE ins_required_pars( p_contract_id IN contracts.cont_id%TYPE , p_template_id IN contract_templates.cote_id%TYPE , p_parameter_array IN parameter_array , p_success OUT BOOLEAN , p_return_error OUT VARCHAR2 ) IS -- CURSOR c_cotp( cp_cote_id IN NUMBER , cp_pars_id IN NUMBER ) IS SELECT 'Y' FROM contract_template_params WHERE cote_id = cp_cote_id AND pars_id = cp_pars_id; -- l_inherited VARCHAR2(1) := 'N'; BEGIN SAVEPOINT before_ins_pars; -- p_success := TRUE; -- <> FOR i IN 1..p_parameter_array.COUNT LOOP -- l_inherited := 'N'; -- Test if this parameter was inherited OPEN c_cotp( p_template_id, p_parameter_array(i).pars_id ); FETCH c_cotp INTO l_inherited; CLOSE c_cotp; -- IF NOT copa_in_db( p_parameter_array(i).pars_id , p_contract_id ) THEN -- Current Parameter does not exist in the DB so we need to INSERT p_success := ins_contract_pars( p_contract_id , p_parameter_array(i).pars_id , l_inherited , p_return_error ); -- IF NOT p_success THEN EXIT upd_ins_copa_loop; END IF; -- ELSE -- But if the parameter DOES exist - make sure it has the correct contract template id -- in case there has been a change of contract template.... BEGIN UPDATE contract_parameters SET inherited = l_inherited WHERE cont_id = p_contract_id AND pars_id = p_parameter_array(i).pars_id; EXCEPTION WHEN others THEN p_success := FALSE; p_return_error := caco_utilities.get_module_text(2222); -- An unexpected error has occurred while updating contract parameters. Please contact support caco_debug.putline('efno_contracts.ins_or_upd_contract_p1: ' ||'Update of contract parameters failed (update): ' ||sqlerrm(sqlcode)); -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => 'Failed inserting COPA: '||sqlerrm(sqlcode) , p_source => 'efno_contracts.ins_required_pars'); -- ROLLBACK TO SAVEPOINT before_ins_pars; EXIT upd_ins_copa_loop; END; -- END IF; -- end of parameter doesnt exist in DB END LOOP upd_ins_copa_loop; -- END ins_required_pars; PROCEDURE ins_or_upd_cont_opt(p_cont_id IN contract_options.cont_id%TYPE, p_ind_deadline_for_nom_submit IN contract_options.ind_deadline_for_nom_submit%TYPE, p_shipper IN contract_options.shipper%TYPE, p_auto_gen_conf IN contract_options.auto_gen_conf%TYPE, p_conf_type IN contract_options.conf_type%TYPE, p_com_conf_subject IN contract_options.com_conf_subject%TYPE, p_com_conf_content IN contract_options.com_conf_content%TYPE, p_nom_conf_subject IN contract_options.nom_conf_subject%TYPE, p_nom_conf_content IN contract_options.nom_conf_content%TYPE, p_ind_deadline_hr IN contract_options.ind_deadline_for_nom_submit%TYPE, p_ind_deadline_mi IN contract_options.ind_deadline_for_nom_submit%TYPE, p_int_subject IN contract_options.int_subject%TYPE, p_int_content IN contract_options.int_content%TYPE, p_int_sms_content IN contract_options.int_sms_content%TYPE) IS -- l_error VARCHAR2(1); l_return_error VARCHAR2(250); -- If the insert or update fails - put an error message in here. l_success BOOLEAN := TRUE; -- Used to track how well we are doing in this code.. l_success_char VARCHAR2(1) := NULL; l_contract_exists VARCHAR2(1) := 'N'; l_conf_type_found BOOLEAN := FALSE; -- l_cont_id contract_options.cont_id%TYPE; l_ind_deadline_for_nom_submit contract_options.ind_deadline_for_nom_submit%TYPE; l_shipper contract_options.shipper%TYPE; l_auto_gen_conf contract_options.auto_gen_conf%TYPE; --not null l_conf_type contract_options.conf_type%TYPE; --not null l_com_conf_subject contract_options.com_conf_subject%TYPE; --not null l_com_conf_content contract_options.com_conf_content%TYPE; --not null l_nom_conf_subject contract_options.nom_conf_subject%TYPE; --not null l_nom_conf_content contract_options.nom_conf_content%TYPE; --not null l_ind_deadline_hr contract_options.ind_deadline_for_nom_submit%TYPE; l_ind_deadline_mi contract_options.ind_deadline_for_nom_submit%TYPE; l_int_subject contract_options.int_subject%TYPE; l_int_content contract_options.int_content%TYPE; l_int_sms_content contract_options.int_sms_content%TYPE; -- CURSOR c_cont(cp_contract_id IN NUMBER) IS SELECT 'Y' FROM contract_options WHERE cont_id = cp_contract_id; -- CURSOR c_conf_type IS SELECT rv_low_value, rv_meaning FROM cg_ref_codes WHERE rv_domain = 'CONTRACT_OPTIONS.CONF_TYPE' ORDER BY rv_meaning; BEGIN -- Check we have permission to be using this module. -- Only called from the Create contracts screen IF NOT caco_security.security_check('efnow050$') THEN RETURN; END IF; -- -- Validation -- Valid Contract ID OPEN c_cont(p_cont_id); FETCH c_cont INTO l_contract_exists; CLOSE c_cont; IF l_contract_exists != 'Y' THEN l_success := FALSE; l_return_error := caco_utilities.get_module_text(3969); -- Data is not linked to a valid contract number. Please contact support END IF; -- IF l_success THEN l_cont_id := p_cont_id; l_ind_deadline_for_nom_submit := p_ind_deadline_for_nom_submit; l_shipper := p_shipper; l_auto_gen_conf := p_auto_gen_conf; l_conf_type := p_conf_type; l_com_conf_subject := TRIM(p_com_conf_subject); l_com_conf_content := TRIM(p_com_conf_content); l_nom_conf_subject := TRIM(p_nom_conf_subject); l_nom_conf_content := TRIM(p_nom_conf_content); l_ind_deadline_hr := TRIM(p_ind_deadline_hr); l_ind_deadline_mi := TRIM(p_ind_deadline_mi); l_int_subject := p_int_subject; l_int_content := p_int_content; l_int_sms_content := p_int_sms_content; END IF; -- -- Mandatory Fields -- --Auto Generate Confirm - must be Y or N IF l_auto_gen_conf != 'Y' AND l_auto_gen_conf != 'N' AND l_success THEN l_success := FALSE; l_return_error := caco_utilities.get_module_text(3970); -- Auto Generate Confirm is a mandatory field END IF; --Confirmation Type - is it in the list? IF l_success THEN FOR r IN c_conf_type LOOP IF r.rv_low_value = l_conf_type THEN l_conf_type_found := TRUE; END IF; END LOOP; IF NOT l_conf_type_found THEN l_success := FALSE; l_return_error := caco_utilities.get_module_text(3971); -- Confirmation Format is a mandatory field END IF; END IF; --Com Confirmation Subject IF (l_com_conf_subject IS NULL OR l_com_conf_subject = '') AND l_success THEN l_success := FALSE; l_return_error := caco_utilities.get_module_text(3972); -- Com Confirmation Subject is a mandatory field END IF; --Com Confirmation Content IF (l_com_conf_content IS NULL OR l_com_conf_content = '') AND l_success THEN l_success := FALSE; l_return_error := caco_utilities.get_module_text(3973); -- Com Confirmation Content is a mandatory field END IF; --Nom Confirmation Subject IF (l_nom_conf_subject IS NULL OR l_nom_conf_subject = '') AND l_success THEN l_success := FALSE; l_return_error := caco_utilities.get_module_text(3974); -- Nom Confirmation Subject is a mandatory field END IF; --Nom Confirmation Content IF (l_nom_conf_content IS NULL OR l_nom_conf_content = '') AND l_success THEN l_success := FALSE; l_return_error := caco_utilities.get_module_text(3975); -- Nom Confirmation Content is a mandatory field END IF; -- -- Making sense of the Ind Sub Deadline IF l_success THEN IF length(l_ind_deadline_hr) = 2 AND length(l_ind_deadline_mi) = 2 THEN l_ind_deadline_for_nom_submit := l_ind_deadline_hr || ':' || l_ind_deadline_mi; ELSIF length(l_ind_deadline_hr) < 2 AND length(l_ind_deadline_mi) = 2 THEN l_ind_deadline_for_nom_submit := '00:' || l_ind_deadline_mi; ELSIF length(l_ind_deadline_hr) = 2 AND length(l_ind_deadline_mi) < 2 THEN l_ind_deadline_for_nom_submit := l_ind_deadline_hr || ':00'; ELSE l_ind_deadline_for_nom_submit := ''; END IF; END IF; -- -- If we are happy and we know it update the table IF l_success THEN BEGIN UPDATE contract_options SET nom_conf_subject = l_nom_conf_subject, nom_conf_content = l_nom_conf_content, com_conf_subject = l_com_conf_subject, com_conf_content = l_com_conf_content, auto_gen_conf = l_auto_gen_conf, conf_type = l_conf_type, ind_deadline_for_nom_submit = l_ind_deadline_for_nom_submit, shipper = l_shipper, int_subject = l_int_subject, int_content = l_int_content, int_sms_content = l_int_sms_content WHERE cont_id = l_cont_id; EXCEPTION WHEN OTHERS THEN l_success := FALSE; l_return_error := caco_utilities.get_module_text(3976); -- An unexpected error has occurred while updating contract options. Please contact support caco_debug.putline('efno_contracts.ins_or_upd_contract_p1: ' || 'Insert of new contract failed : ' || SQLERRM(SQLCODE)); -- Write an error and carry on cout_err.report_and_go(p_exception_number => SQLCODE, p_exception_message => 'Failed updating contract options: ' || SQLERRM(SQLCODE), p_source => 'efno_contracts.ins_or_upd_cont_opt'); -- END; IF l_success THEN -- Commit the changes COMMIT; -- l_success_char := 'Y'; l_error := NULL; l_return_error := NULL; -- ELSE -- Failed somewhere -- Rollback any partially made inserts/updates ROLLBACK; -- l_success_char := NULL; l_error := 'Y'; -- END IF; -- -- Call the contract options screen efnow050$.contract_options_p(p_contract_id => l_cont_id, p_success => l_success_char, p_error => l_error, p_err_msg => l_return_error); -- END IF; END ins_or_upd_cont_opt; PROCEDURE ins_or_upd_contract_p1( p_ins_or_upd IN VARCHAR2 DEFAULT 'INSERT' , p_contract_id IN contracts.cont_id%TYPE DEFAULT 0 , p_contract_number IN VARCHAR2 DEFAULT NULL , p_pre_contract_id IN contracts.prev_cont_id%TYPE DEFAULT 0 , p_customer_id IN customers.cust_id%TYPE DEFAULT 0 , p_template_id IN contract_templates.cote_id%TYPE DEFAULT 0 , p_spte_id IN spreadsheet_templates.spte_id%TYPE DEFAULT 0 , p_ops_contact IN VARCHAR2 DEFAULT NULL , p_bus_contact IN VARCHAR2 DEFAULT NULL , p_status IN contracts.status%TYPE DEFAULT NULL , p_days_before IN VARCHAR2 DEFAULT NULL , p_date_from IN VARCHAR2 DEFAULT NULL , p_date_to IN VARCHAR2 DEFAULT NULL , p_val_window IN VARCHAR2 DEFAULT NULL , p_val_action IN contracts.validation_action%TYPE DEFAULT NULL , p_val_exception IN contracts.validation_exception%TYPE DEFAULT NULL , p_lookback_action IN contracts.lookback_action%TYPE DEFAULT NULL , p_nepo_id IN owa_util.vc_arr DEFAULT g_vc_arr , p_cate_id IN owa_util.vc_arr DEFAULT g_vc_arr , p_pars_id IN owa_util.vc_arr DEFAULT g_vc_arr ) IS -- CURSOR c_cont (cp_contract_id IN NUMBER) IS SELECT * FROM contracts WHERE cont_id = cp_contract_id; -- CURSOR c_cotc( cp_cote_id IN NUMBER , cp_cate_id IN NUMBER ) IS SELECT 'Y' FROM contract_template_categories WHERE cote_id = cp_cote_id AND cate_id = cp_cate_id; -- CURSOR c_cotp( cp_cote_id IN NUMBER , cp_pars_id IN NUMBER ) IS SELECT 'Y' FROM contract_template_params WHERE cote_id = cp_cote_id AND pars_id = cp_pars_id; -- -- Cursor to determine if the contract number has been used previously for the customer TYPE CURSOR c_unique_cont_num( cp_cont_num IN VARCHAR2 ) IS SELECT 'X' FROM contracts cont , customers cust WHERE cust.cust_id = cont.cust_id AND cust.cuty_id = caco_utilities.cuty_id_for_user AND cont.contract_number = cp_cont_num AND cont.cont_id != NVL(p_contract_id,0); -- -- Cursor to check if there are any open contracts for this customer -- for the date range given CURSOR c_active_cont_check( cp_date_from IN DATE , cp_date_to IN DATE ) IS SELECT 'X' FROM contracts WHERE cust_id = p_customer_id -- this customer AND cont_id != NVL(p_contract_id,0) -- Not this contract (if updating) AND status = 'O' -- Open AND ( valid_from BETWEEN cp_date_from AND cp_date_to OR valid_until BETWEEN cp_date_from AND cp_date_to OR cp_date_from BETWEEN valid_from AND valid_until ); -- -- Cursor to check if the previous contract is consistent following -- a change of valid_from date CURSOR c_pre_cont(cp_pre_cont_id in number, cp_date_from IN DATE) IS SELECT 'X' FROM contracts WHERE cont_id = cp_pre_cont_id AND valid_until < cp_date_from; -- l_error VARCHAR2(1); l_return_error VARCHAR2(250); -- If the insert or update fails - put an error message in here. -- l_contract_id contracts.cont_id%TYPE := 0; l_pre_contract_id contracts.prev_cont_id%TYPE := 0; l_contract_number VARCHAR2(2000) := NULL; l_template_id contracts.cote_id%TYPE := NULL; l_customer_id contracts.cust_id%TYPE := 0; l_spte_id contracts.spte_id%TYPE := 0; l_ops_contact VARCHAR2(2000) := NULL; l_bus_contact VARCHAR2(2000) := NULL; l_status contracts.status%TYPE := NULL; l_days_before VARCHAR2(2000) := NULL; l_date_from VARCHAR2(2000) := NULL; l_date_to VARCHAR2(2000) := NULL; l_val_window VARCHAR2(2000) := NULL; l_val_action contracts.validation_action%TYPE := NUlL; l_val_exception contracts.validation_exception%TYPE := NULL; l_lookback_action contracts.lookback_action%TYPE := NULL; -- l_inherited VARCHAR2(1) := 'N'; -- l_network_point_array network_point_array; l_category_array category_array; l_parameter_array parameter_array; -- l_dummy_date_from DATE; l_dummy_date_to DATE; l_dummy_char VARCHAR2(1); -- l_nepo_id owa_util.vc_arr; l_cate_id owa_util.vc_arr; l_pars_id owa_util.vc_arr; -- l_success BOOLEAN := TRUE; -- Used to track how well we are doing in this code.. l_success_char VARCHAR2(1) := NULL; -- l_code_position VARCHAR2(4) := '0000'; -- l_contract contracts%ROWTYPE; -- BEGIN -- Check we have permission to be using this module. -- Only called from the Create contracts screen IF NOT caco_security.security_check('efnow050$') THEN RETURN; END IF; -- -- Look for whether we are inserting or updating IF p_ins_or_upd IS NULL AND l_success OR ( UPPER(p_ins_or_upd) != 'INSERT' AND UPPER(p_ins_or_upd) != 'UPDATE' ) THEN -- Cannot tell if we should be inserting or updating. Well, we could -- but it's easier to enforce this on the calling prog instead of Assuming. -- and you know the old adage about ASSUME eh? l_success := FALSE; l_return_error := caco_utilities.get_module_text(2331); -- Could not determine if Inserting or Updating -- END IF; -- -- Only check contract id if updating IF l_success AND p_ins_or_upd = 'UPDATE' AND ( p_contract_id IS NULL OR p_contract_id = 0 ) THEN l_success := FALSE; l_return_error := caco_utilities.get_module_text(2317); -- Update of Contract failed - No Contract Id was provided END IF; -- -- Get Contract Template Id (do this first in case no contract number provided. -- (for re-creating the maintain contract screen correctly with error message) IF l_success AND ( p_template_id IS NULL OR p_template_id = 0 ) THEN l_template_id := NULL; -- ELSIF l_success THEN l_template_id := p_template_id; END IF; -- -- Get Contract Number IF l_success AND ( p_contract_number IS NULL OR LENGTH(p_contract_number) > 30 ) THEN l_success := FALSE; l_return_error := caco_utilities.get_module_text(2236); -- Contract number must be present with a maximum length of 30 characters -- ELSIF l_success THEN -- Need to ensure that the contract number is unique within OMT or PUW OPEN c_unique_cont_num( p_contract_number ); FETCH c_unique_cont_num INTO l_dummy_char; IF c_unique_cont_num%FOUND THEN l_success := FALSE; l_return_error := caco_utilities.get_module_text(2252); -- Duplicate Contract Number already exists END IF; CLOSE c_unique_cont_num; -- END IF; -- -- Get Customer ID IF l_success AND ( p_customer_id IS NULL OR p_customer_id = 0 ) THEN l_success := FALSE; l_return_error := caco_utilities.get_module_text(2325); -- You must select a Customer for this Contract END IF; -- -- Get Spreadsheet Template IF l_success AND ( p_spte_id IS NULL OR p_spte_id = 0 ) THEN l_success := FALSE; l_return_error := caco_utilities.get_module_text(2207); -- A Spreadsheet Template must be selected END IF; -- -- Get Ops Contact IF l_success AND ( p_ops_contact IS NULL OR LENGTH(p_ops_contact) > 25 ) THEN l_success := FALSE; l_return_error := caco_utilities.get_module_text(2291); -- Ops Contact must be present with a maximum length of 25 characters END IF; -- -- Get Business Contact IF l_success AND ( p_bus_contact IS NULL OR LENGTH(p_bus_contact) > 25 ) THEN l_success := FALSE; l_return_error := caco_utilities.get_module_text(2227); -- Bus Contact must be present with a maximum length of 25 characters END IF; -- -- Get Status IF l_success AND ( p_status IS NULL OR ( p_status != 'O' AND p_status != 'C' ) ) THEN l_success := FALSE; l_return_error := caco_utilities.get_module_text(2300); -- Status must be present as either OPEN or CLOSED END IF; -- -- Get Days Before IF l_success AND p_days_before IS NULL THEN l_success := FALSE; l_return_error := caco_utilities.get_module_text(2247); -- Days Before must be entered ELSIF l_success THEN BEGIN SELECT TO_NUMBER(p_days_before) INTO l_days_before FROM dual; -- IF l_days_before < 1 THEN l_success := FALSE; l_return_error := caco_utilities.get_module_text(2516); -- Days Before must be greater than 0 (zero) END IF; EXCEPTION WHEN others THEN l_success := FALSE; l_return_error := caco_utilities.get_module_text(2416); -- Days Before must be a valid number END; END IF; -- l_code_position := '0200'; -- -- Get Date From IF l_success AND p_date_from IS NOT NULL THEN BEGIN SELECT TO_DATE(p_date_from, cout_system_configuration.get_configuration_item('G_DATE_FORMAT')) INTO l_dummy_date_from FROM dual; EXCEPTION WHEN others THEN l_success := FALSE; -- Date From must be a valid date l_return_error := caco_utilities.get_module_text(2242); END; ELSIF l_success AND p_date_from IS NULL THEN l_success := FALSE; l_return_error := caco_utilities.get_module_text(2243); -- Date From must be entered END IF; -- -- Get Date To IF l_success AND p_date_to IS NOT NULL THEN BEGIN SELECT TO_DATE(p_date_to, cout_system_configuration.get_configuration_item('G_DATE_FORMAT')) INTO l_dummy_date_to FROM dual; EXCEPTION WHEN others THEN l_success := FALSE; l_return_error := caco_utilities.get_module_text(2245); -- Date To must be a valid date END; ELSIF l_success AND p_date_to IS NULL THEN l_success := FALSE; l_return_error := caco_utilities.get_module_text(2246); -- Date To must be entered END IF; -- -- Check that Date from is before Date To IF l_success AND l_dummy_date_to <= l_dummy_date_from THEN l_success := FALSE; l_return_error := caco_utilities.get_module_text(2417); -- Date To must be after Date From END IF; -- Check that Date From is consistent with the named Previous Contract IF l_success AND p_pre_contract_id <> 0 AND p_pre_contract_id is not null THEN open c_pre_cont(p_pre_contract_id, l_dummy_date_from); fetch c_pre_cont into l_dummy_char; if c_pre_cont%notfound then l_success := FALSE; l_return_error := caco_utilities.get_module_text(3962); -- Date From must be after Previous Contract Date To end if; END IF; -- -- AWG October 2010 - Change Requests August 2010 Section 3.1 -- This validation will be removed so that a customer can have more than one open -- contract for a date period. /* -- -- Can create a CLOSED contract at any time -- but need to check for open contracts when creating or updating to OPEN IF l_success AND p_status = 'O' THEN -- Need to ensure that there is only ever one OPEN contract for the customer for a date period -- An OPEN contract CAN overlap a CLOSED one OPEN c_active_cont_check( l_dummy_date_from , l_dummy_date_to ); FETCH c_active_cont_check INTO l_dummy_char; IF c_active_cont_check%FOUND THEN -- An existing contract is open for part (or all) of the period specified for this contract l_success := FALSE; l_return_error := caco_utilities.get_module_text(2434); -- Open contracts exist for this date period -- END IF; CLOSE c_active_cont_check; -- END IF; */ -- -- Get validation window IF l_success AND p_val_window IS NULL THEN l_success := FALSE; l_return_error := caco_utilities.get_module_text(2323); -- Validation Window must be a number with a value between 0 and 365 ELSIF l_success THEN BEGIN SELECT TO_NUMBER(p_val_window) INTO l_val_window FROM dual; -- IF l_val_window < 0 OR l_val_window > 365 THEN l_success := FALSE; l_return_error := caco_utilities.get_module_text(2323); -- Validation Window must be a number with a value between 0 and 365 END IF; EXCEPTION WHEN others THEN l_success := FALSE; l_return_error := caco_utilities.get_module_text(2323); -- Validation Window must be a number with a value between 0 and 365 END; END IF; -- -- Get validation action IF l_success AND ( p_val_action IS NULL OR p_val_action NOT IN ('I','T','B') ) THEN l_success := FALSE; l_return_error := caco_utilities.get_module_text(2319); -- Validation action must be selected END IF; -- -- Get validation exception IF l_success AND ( p_val_exception IS NULL OR p_val_exception NOT IN ('CO','MI','MA') ) THEN l_success := FALSE; l_return_error := caco_utilities.get_module_text(2321); -- Validation Exception must be selected END IF; -- -- Get lookback action IF l_success AND ( p_lookback_action IS NULL OR p_lookback_action NOT IN ('T','A') ) THEN l_success := FALSE; l_return_error := caco_utilities.get_module_text(2321); -- Validation Exception must be selected END IF; -- -- Check that the virtual network point is only selected for entry mandatory offer contracts l_code_position := '0300'; IF l_success THEN find_passed_net_points( p_nepo_id , l_network_point_array ); IF vnepo_count(l_network_point_array) > 0 AND NOT emo_template(l_template_id) THEN l_success := FALSE; l_return_error := caco_utilities.get_module_text(3913); -- Virtual Network Point can only be assigned to an Entry Mandatory Offer Contract ELSIF vnepo_count(l_network_point_array) = 0 AND emo_template(l_template_id) THEN l_success := FALSE; l_return_error := caco_utilities.get_module_text(3914); -- An Entry Mandatory Offer Contract must have a Virtual Network Point assigned ELSIF vnepo_count(l_network_point_array) > 1 AND emo_template(l_template_id) THEN l_success := FALSE; l_return_error := caco_utilities.get_module_text(3922); -- A contract can only contain one Virtual Network Point END IF; END IF; -- -- Hokey Cokey. Insert or Update the basic part of the contract/template -- and then the network points, categories and parameters -- Remember - for each category, add its associated parameters. -- l_code_position := '0900'; -- IF l_success THEN l_code_position := '1000'; -- Lets look at Inserting the contract first... IF p_ins_or_upd = 'INSERT' THEN BEGIN INSERT INTO contracts ( cont_id , contract_number , spte_id , operations_contact , business_contact , receive_before_start , valid_from , valid_until , status , cote_id , cust_id , validation_window , validation_action , validation_exception , lookback_action , prev_cont_id ) VALUES ( cont_seq.NEXTVAL , p_contract_number , p_spte_id , p_ops_contact , p_bus_contact , p_days_before , TO_DATE(p_date_from, cout_system_configuration.get_configuration_item('G_DATE_FORMAT')) , TO_DATE(p_date_to, cout_system_configuration.get_configuration_item('G_DATE_FORMAT')) , p_status , l_template_id , p_customer_id , p_val_window , p_val_action , p_val_exception , p_lookback_action , p_pre_contract_id ) RETURNING cont_id INTO l_contract_id; EXCEPTION WHEN others THEN l_success := FALSE; l_return_error := caco_utilities.get_module_text(2327); -- An unexpected error has occurred while inserting new contract. Please contact support caco_debug.putline('efno_contracts.ins_or_upd_contract_p1: ' ||'Insert of new contract failed : '||sqlerrm(sqlcode)); -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => 'Failed inserting new contract: '||sqlerrm(sqlcode) , p_source => 'efno_contracts.ins_or_upd_contract_p1'); -- END; -- IF l_success THEN l_success := ins_or_upd_inh_rules( p_ins_or_upd , l_contract_id , l_template_id , l_return_error ); END IF; -- ELSE l_code_position := '1100'; -- l_success := ins_or_upd_inh_rules( p_ins_or_upd , p_contract_id , l_template_id , l_return_error ); -- -- Only want to update the contract if the inherited rules have updated correctly IF l_success THEN -- get the currect contract values before updating so we can check for changes OPEN c_cont(p_contract_id); FETCH c_cont INTO l_contract; CLOSE c_cont; -- Update BEGIN UPDATE contracts SET contract_number = p_contract_number , spte_id = p_spte_id , operations_contact = p_ops_contact , business_contact = p_bus_contact , receive_before_start = p_days_before , valid_from = TO_DATE(p_date_from, cout_system_configuration.get_configuration_item('G_DATE_FORMAT')) , valid_until = TO_DATE(p_date_to, cout_system_configuration.get_configuration_item('G_DATE_FORMAT')) , status = p_status , cote_id = l_template_id , cust_id = p_customer_id , validation_window = p_val_window , validation_action = p_val_action , validation_exception = p_val_exception , lookback_action = p_lookback_action , prev_cont_id = p_pre_contract_id WHERE cont_id = p_contract_id; -- EXCEPTION WHEN others THEN l_success := FALSE; l_return_error := caco_utilities.get_module_text(2329); -- An unexpected error has occurred while updating contract. Please contact support caco_debug.putline('efno_contracts.ins_or_upd_contract_p1: ' ||'Update of contract failed : '||sqlerrm(sqlcode)); -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => 'Failed updating contract (ID = '||p_contract_id||'): '||sqlerrm(sqlcode) , p_source => 'efno_contracts.ins_or_upd_contract_p1'); -- END; -- -- Invalidate any related interruption types if key column values have changed IF l_contract.valid_from <> TO_DATE(p_date_from, cout_system_configuration.get_configuration_item('G_DATE_FORMAT')) OR l_contract.valid_until <> TO_DATE(p_date_to, cout_system_configuration.get_configuration_item('G_DATE_FORMAT')) OR l_contract.status <> p_status THEN -- l_success := invalidate_inty(p_contract_id); -- END IF; -- l_contract_id := p_contract_id; -- END IF; END IF; -- Insert or Update of contract END IF; -- End of basic insert -- l_code_position := '1200'; -- -- Get Network Points IF l_success THEN l_code_position := '2000'; -- Find passed network points -- SP 7/7/09 find_passed_net_points is now done in validation so no longer required here /* find_passed_net_points( p_nepo_id , l_network_point_array );*/ -- IF p_ins_or_upd = 'INSERT' THEN l_code_position := '2100'; -- Insert all Network Points l_success := insert_cont_nepo( l_contract_id , l_network_point_array , l_return_error ); -- ELSE l_code_position := '2200'; -- Update -- This is easier to get to grips with as a two pass process -- First, zip through the existing DB data for the contract and delete existing rows not in our array del_redundant_nepo( l_contract_id , l_network_point_array , l_success , l_return_error ); -- l_code_position := '2250'; -- Second time around go through the passed array and insert those that dont exist. IF l_success THEN -- ins_required_nepo( l_contract_id , l_network_point_array , l_success , l_return_error ); -- END IF; -- end of if successful delete of existing cont net points -- END IF; -- end of insert or update contract network points END IF; -- end of network points -- l_code_position := '2900'; -- -- Get Categories IF l_success THEN find_passed_categories( p_cate_id , l_category_array ); -- IF p_ins_or_upd = 'INSERT' THEN -- <> FOR i IN 1..l_category_array.COUNT LOOP -- l_inherited := 'N'; -- Test if this category was inherited OPEN c_cotc( l_template_id, l_category_array(i).cate_id ); FETCH c_cotc INTO l_inherited; CLOSE c_cotc; -- l_success := ins_contract_cate( l_contract_id , l_category_array(i).cate_id , NULL , l_inherited , l_return_error ); -- IF NOT l_success THEN EXIT ins_coca_loop; END IF; -- END LOOP ins_coca_loop; -- ELSE -- This is easier to get to grips with as a two pass process -- First, zip through the existing DB data for the contract and delete existing rows not in our array del_redundant_cate( l_contract_id , l_category_array , l_success , l_return_error ); -- -- Second, go through the passed array and insert those categories that dont already exist. IF l_success THEN -- ins_required_cate( l_contract_id , l_template_id , l_category_array , l_success , l_return_error ); -- END IF; -- END IF; -- contract categories insert or update END IF; -- end of categories -- l_code_position := '3990'; -- IF l_success THEN l_code_position := '4000'; -- Get Parameters find_passed_parameters( p_pars_id , l_parameter_array ); -- IF p_ins_or_upd = 'INSERT' THEN l_code_position := '4010'; -- Easy, just insert all passed parameters once you know if it is inherited or not. -- <> FOR i IN 1..l_parameter_array.COUNT LOOP -- l_inherited := 'N'; -- Test if this parameter was inherited OPEN c_cotp( l_template_id, l_parameter_array(i).pars_id ); FETCH c_cotp INTO l_inherited; CLOSE c_cotp; -- l_success := ins_contract_pars( l_contract_id , l_parameter_array(i).pars_id , l_inherited , l_return_error ); -- IF NOT l_success THEN EXIT ins_copa_loop; END IF; -- END LOOP ins_copa_loop; -- end of inserting new parameters -- ELSE l_code_position := '4100'; -- UPDATE. This is easier to get to grips with as a two pass process -- First, zip through the existing DB data for the contract -- and delete existing rows not in our array del_redundant_pars( l_contract_id , l_parameter_array , l_success , l_return_error ); -- l_code_position := '4150'; -- Second, go through the passed array and insert those parameters that dont already exist. -- IF l_success THEN -- ins_required_pars( l_contract_id , l_template_id , l_parameter_array , l_success , l_return_error ); -- END IF; -- END IF; -- contract template insert or update parameter. -- END IF; -- end of parameters -- -- IF l_success THEN -- Commit the changes COMMIT; -- l_code_position := '9010'; -- l_success_char := 'Y'; l_error := NULL; l_return_error := NULL; l_contract_number := NULL; l_customer_id := 0; l_spte_id := 0; l_ops_contact := NULL; l_bus_contact := NULL; l_status := NULL; l_days_before := NULL; l_date_from := NULL; l_date_to := NULL; l_val_window := NULL; l_val_action := NULL; l_val_exception := NULL; l_lookback_action := NULL; l_nepo_id := g_vc_arr; l_cate_id := g_vc_arr; l_pars_id := g_vc_arr; -- ELSE l_code_position := '9020'; -- -- Failed somewhere -- Rollback any partially made inserts/updates ROLLBACK; -- IF l_contract_id = 0 AND p_ins_or_upd = 'UPDATE' THEN l_contract_id := p_contract_id; END IF; -- l_success_char := NULL; l_error := 'Y'; l_contract_number := p_contract_number; l_customer_id := p_customer_id; l_spte_id := p_spte_id; l_ops_contact := p_ops_contact; l_bus_contact := p_bus_contact; l_status := p_status; l_days_before := p_days_before; l_date_from := p_date_from; l_date_to := p_date_to; l_val_window := p_val_window; l_val_action := p_val_action; l_val_exception := p_val_exception; l_lookback_action := p_lookback_action; l_nepo_id := p_nepo_id; l_cate_id := p_cate_id; l_pars_id := p_pars_id; -- END IF; -- l_code_position := '9100'; -- caco_debug.putline('efno_contracts.ins_or_upd_contract_p1: '||chr(10) ||chr(10)||'p_ins_or_upd : '||p_ins_or_upd ||chr(10)||'p_success : '||l_success_char ||chr(10)||'p_error : '|| l_error ||chr(10)||'p_err_msg : '||l_return_error ||chr(10)||'p_contract_id : '||l_contract_id ||chr(10)||'p_contract_number : '||l_contract_number ||chr(10)||'p_template_id : '||l_template_id ||chr(10)||'p_customer_id : '||l_customer_id ||chr(10)||'p_spte_id : '||l_spte_id ||chr(10)||'p_ops_contact : '||l_ops_contact ||chr(10)||'p_bus_contact : '||l_bus_contact ||chr(10)||'p_status : '||l_status ||chr(10)||'p_days_before : '||l_days_before ||chr(10)||'p_date_from : '||l_date_from ||chr(10)||'p_date_to : '||l_date_to ||chr(10)||'p_val_window : '||l_val_window ||chr(10)||'p_val_action : '||l_val_action ||chr(10)||'p_val_exception : '||l_val_exception ||chr(10)||'p_lookback_action : '||l_lookback_action ); -- -- Call the contracts screen efnow050$.contract_startup( p_screen_type => 'CONTRACT' , p_ins_or_upd => p_ins_or_upd , p_success => l_success_char , p_error => l_error , p_err_msg => l_return_error , p_contract_id => l_contract_id , p_contract_number => l_contract_number , p_template_id => l_template_id , p_customer_id => l_customer_id , p_spte_id => l_spte_id , p_ops_contact => l_ops_contact , p_bus_contact => l_bus_contact , p_status => l_status , p_days_before => l_days_before , p_date_from => l_date_from , p_date_to => l_date_to , p_val_window => l_val_window , p_val_action => l_val_action , p_val_exception => l_val_exception , p_lookback_action => l_lookback_action , p_nepo_id => l_nepo_id , p_cate_id => l_cate_id , p_pars_id => l_pars_id ); -- EXCEPTION WHEN others THEN caco_debug.debug_on; caco_debug.putline('efno_contracts.ins_or_upd_contract_p1: ' ||'Position in Code : '||l_code_position||' : '||chr(10) ||sqlerrm(sqlcode)); -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => 'Failed at position : '||l_code_position||' : '||sqlerrm(sqlcode) , p_source => 'efno_contracts.ins_or_upd_contract_p1'); -- ROLLBACK; RAISE; END ins_or_upd_contract_p1; FUNCTION del_template_pars( p_template_id IN contract_templates.cote_id%TYPE , p_pars_id IN parameters.pars_id%TYPE , p_contracts_exist IN BOOLEAN , p_return_error OUT VARCHAR2 ) RETURN BOOLEAN IS -- Cursor to loop through all contracts that have the specified contract template CURSOR c_cont IS SELECT cont_id FROM contracts WHERE cote_id = p_template_id; -- l_success BOOLEAN := TRUE; -- BEGIN SAVEPOINT before_del_cotp; -- IF p_contracts_exist THEN -- <> FOR r IN c_cont LOOP -- Delete contract parameter values BEGIN DELETE cont_net_point_param_vals cnppv WHERE cnppv.copa_id IN ( SELECT copa.copa_id FROM contract_parameters copa , parameters pars WHERE copa.cont_id = r.cont_id AND copa.pars_id = p_pars_id ); EXCEPTION WHEN others THEN l_success := FALSE; p_return_error := caco_utilities.get_module_text(2328); -- An unexpected error has occurred while updating contract template. Please contact support caco_debug.putline('efno_contracts.del_template_pars: ' ||'Update of contract template parameters failed ' ||'(deleting associated parameters values from contracts) : ' ||sqlerrm(sqlcode)); -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => 'Failed deleting template parameters associated contract parameter values: ' ||chr(10)||sqlerrm(sqlcode) , p_source => 'efno_contracts.delete_template_pars'); -- EXIT cont_pars_loop; END; -- -- Delete contract parameters BEGIN DELETE contract_parameters WHERE cont_id = r.cont_id AND pars_id = p_pars_id; EXCEPTION WHEN others THEN l_success := FALSE; p_return_error := caco_utilities.get_module_text(2328); -- An unexpected error has occurred while updating contract template. Please contact support caco_debug.putline('efno_contracts.del_template_pars: ' ||'Update of contract template parameters failed ' ||'(deleting contract parameters): ' ||sqlerrm(sqlcode)); -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => 'Failed deleting template parameters from associated contracts: ' ||chr(10)||sqlerrm(sqlcode) , p_source => 'efno_contracts.delete_template_pars'); -- EXIT cont_pars_loop; END; -- END LOOP cont_pars_loop; -- END IF; -- IF l_success THEN -- BEGIN DELETE contract_template_params WHERE cote_id = p_template_id AND pars_id = p_pars_id; EXCEPTION WHEN others THEN l_success := FALSE; p_return_error := caco_utilities.get_module_text(2328); -- An unexpected error has occurred while updating contract template. Please contact support caco_debug.putline('efno_contracts.ins_or_upd_template_p1: ' ||'Update of contract template parameters failed (deleting parameter): ' ||sqlerrm(sqlcode)); -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => 'Failed deleting contract template parameters: ' ||chr(10)||sqlerrm(sqlcode) , p_source => 'efno_contracts.delete_template_pars'); -- END; -- END IF; -- IF NOT l_success THEN ROLLBACK TO SAVEPOINT before_del_cotp; END IF; -- RETURN l_success; -- END del_template_pars; FUNCTION ins_template_pars( p_template_id IN contract_templates.cote_id%TYPE , p_pars_id IN parameters.pars_id%TYPE , p_contracts_exist IN BOOLEAN , p_return_error OUT VARCHAR2 ) RETURN BOOLEAN IS -- Cursor to loop through all contracts that have the specified contract template CURSOR c_cont IS SELECT cont_id FROM contracts WHERE cote_id = p_template_id; -- l_success BOOLEAN := TRUE; -- l_copa_id contract_parameters.copa_id%TYPE; -- BEGIN SAVEPOINT before_ins_cotp; -- -- Insert the parameter to all contracts that have the specified contract template IF p_contracts_exist THEN -- <> FOR r IN c_cont LOOP -- BEGIN INSERT INTO contract_parameters ( copa_id , display_sequence , inherited , cont_id , pars_id ) VALUES ( copa_seq.NEXTVAL , 0 -- these parameters are not from a category , 'Y' , r.cont_id , p_pars_id ) RETURNING copa_id INTO l_copa_id; -- -- Now insert the values as we know it can be a little fragile without... -- l_success := ins_copa_cnppv ( p_contract_id => r.cont_id , p_copa_id => l_copa_id , p_return_error => p_return_error ); -- IF NOT l_success THEN -- EXIT cont_pars_loop; -- END IF; -- EXCEPTION WHEN others THEN l_success := FALSE; p_return_error := caco_utilities.get_module_text(2217); -- An unexpected error has occurred while inserting contract template parameters. Please contact support caco_debug.putline('efno_contracts.ins_template_pars: ' ||'Insert of contract template parameters failed ' ||'(inserting parameter to associated contracts) : ' ||sqlerrm(sqlcode)); -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => 'Failed inserting parameters into associated contracts: ' ||chr(10)||sqlerrm(sqlcode) , p_source => 'efno_contracts.ins_template_pars'); -- EXIT cont_pars_loop; END; -- END LOOP cont_pars_loop; -- END IF; -- contracts exist -- -- Insert the template parameter. IF l_success THEN BEGIN INSERT INTO contract_template_params ( cotp_id , display_sequence , inherited , cote_id , pars_id ) VALUES ( cotp_seq.NEXTVAL , ( SELECT NVL(MAX(cotp2.display_sequence),0)+10 FROM contract_template_params cotp2 WHERE cotp2.cote_id = p_template_id ) , 'N' , p_template_id , p_pars_id ); EXCEPTION WHEN others THEN l_success := FALSE; p_return_error := caco_utilities.get_module_text(2217); -- An unexpected error has occurred while inserting contract template parameters. Please contact support caco_debug.putline('efno_contracts.ins_or_upd_template_p1: ' ||'Insert of contract template parameters failed : '||sqlerrm(sqlcode)); -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => 'Failed inserting contract template parameters: ' ||chr(10)||sqlerrm(sqlcode) , p_source => 'efno_contracts.ins_or_upd_contract_p1'); -- END; END IF; -- IF NOT l_success THEN ROLLBACK TO SAVEPOINT before_ins_cotp; END IF; -- RETURN l_success; -- END ins_template_pars; FUNCTION del_template_cate( p_template_id IN contract_templates.cote_id%TYPE , p_cate_id IN categories.cate_id%TYPE , p_contracts_exist IN BOOLEAN , p_return_error OUT VARCHAR2 ) RETURN BOOLEAN IS -- Cursor to loop through all contracts that have the specified contract template CURSOR c_cont IS SELECT cont_id FROM contracts WHERE cote_id = p_template_id; -- l_success BOOLEAN := TRUE; -- BEGIN SAVEPOINT before_del_cotc; -- -- Delete the categories and their associated parameters from all -- contracts that have the specified contract template IF p_contracts_exist THEN -- <> FOR r IN c_cont LOOP -- l_success := del_contract_cate( r.cont_id , p_cate_id , p_return_error ); -- IF NOT l_success THEN EXIT cont_cate_loop; END IF; -- END LOOP cont_cate_loop; -- END IF; -- contracts exist -- -- Delete the parameters inherited from the category for this template IF l_success THEN BEGIN DELETE contract_template_params cotp WHERE cotp.cote_id = p_template_id AND cotp.pars_id IN ( SELECT pars.pars_id FROM parameters pars WHERE pars.cate_id = p_cate_id ); EXCEPTION WHEN others THEN l_success := FALSE; p_return_error := caco_utilities.get_module_text(2328); -- An unexpected error has occurred while updating contract template. Please contact support caco_debug.putline('efno_contracts.del_template_cate: ' ||'Update of contract template categories failed (deleting associated parameters): ' ||sqlerrm(sqlcode)); -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => 'Failed deleting contract template categories associated parameters: ' ||chr(10)||sqlerrm(sqlcode) , p_source => 'efno_contracts.del_template_cate'); -- END; END IF; -- -- IF l_success THEN -- Now we need to delete the category from the template BEGIN DELETE contract_template_categories WHERE cote_id = p_template_id AND cate_id = p_cate_id; EXCEPTION WHEN others THEN l_success := FALSE; p_return_error := caco_utilities.get_module_text(2328); -- An unexpected error has occurred while updating contract template. Please contact support caco_debug.putline('efno_contracts.del_template_cate: ' ||'Update of contract template categories failed (deleting category): ' ||sqlerrm(sqlcode)); -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => 'Failed deleting contract template categories: ' ||chr(10)||sqlerrm(sqlcode) , p_source => 'efno_contracts.del_template_cate'); -- END; -- END IF; -- IF NOT l_success THEN ROLLBACK TO SAVEPOINT before_del_cotc; END IF; -- RETURN l_success; -- END del_template_cate; FUNCTION ins_template_cate( p_template_id IN contract_templates.cote_id%TYPE , p_cate_id IN categories.cate_id%TYPE , p_display_sequence IN categories.display_sequence%TYPE , p_contracts_exist IN BOOLEAN , p_return_error OUT VARCHAR2 ) RETURN BOOLEAN IS -- -- Cursor to loop through all contracts that have the specified contract template -- CURSOR c_cont IS SELECT cont_id FROM contracts WHERE cote_id = p_template_id; -- -- Cursor to get associated parameters for INSERTed categories CURSOR c_cate_pars IS SELECT pars.pars_id pars_id , cate.display_sequence display_sequence FROM parameters pars , categories cate WHERE pars.cate_id = p_cate_id AND pars.cate_id = cate.cate_id; -- l_success BOOLEAN := TRUE; -- -- For Updating Contract Categories - to determine if we need to insert into DB FUNCTION coca_in_db( p_cate_id IN NUMBER , p_contract_id IN NUMBER ) RETURN BOOLEAN IS CURSOR c_coca IS SELECT 'Y' FROM contract_categories WHERE cont_id = p_contract_id AND cate_id = p_cate_id; -- l_success BOOLEAN := FALSE; l_dummy VARCHAR2(1) := 'X'; -- BEGIN OPEN c_coca; FETCH c_coca INTO l_dummy; IF c_coca%FOUND THEN l_success := TRUE; END IF; CLOSE c_coca; RETURN l_success; END coca_in_db; -- BEGIN SAVEPOINT before_ins_cotc; -- -- Insert the category and its associated parameters to all -- contracts that have the specified contract template IF p_contracts_exist THEN -- <> FOR r IN c_cont LOOP -- IF NOT coca_in_db( p_cate_id , r.cont_id ) THEN -- l_success := ins_contract_cate( r.cont_id , p_cate_id , p_display_sequence , 'Y' -- inherited , p_return_error ); -- IF NOT l_success THEN EXIT cont_cate_loop; END IF; -- ELSE -- Already in the DB for this contract BEGIN UPDATE contract_categories SET inherited = 'Y' ,display_sequence = p_display_sequence WHERE cate_id = p_cate_id AND cont_id = r.cont_id; EXCEPTION WHEN others THEN l_success := FALSE; p_return_error := caco_utilities.get_module_text(2223); -- An unexpected error has occurred while updating contract template categories. Please contact support caco_debug.putline('efno_contracts.ins_template_cate : ' ||'Update of contract template categories failed ' ||'(updating existing contract categories) : ' ||sqlerrm(sqlcode)); -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => 'Failed updating contract categories to be inherited: ' ||chr(10)||sqlerrm(sqlcode) , p_source => 'efno_contracts.ins_template_cate'); -- EXIT cont_cate_loop; END; -- we dont need to touch the parameters as they are "inherited" from the category -- END IF; -- already in DB or not -- END LOOP cont_cate_loop; -- END IF; -- contracts exist -- IF l_success THEN BEGIN INSERT INTO contract_template_categories ( cotc_id , display_sequence , cote_id , cate_id ) VALUES ( cotc_seq.NEXTVAL , p_display_sequence , p_template_id , p_cate_id ); EXCEPTION WHEN others THEN l_success := FALSE; p_return_error := caco_utilities.get_module_text(2223); -- An unexpected error has occurred while updating contract template categories. Please contact support caco_debug.putline('efno_contracts.ins_or_upd_template_p1: ' ||'Update of contract template categories failed : ' ||sqlerrm(sqlcode)); -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => 'Failed inserting contract template categories: ' ||chr(10)||sqlerrm(sqlcode) , p_source => 'efno_contracts.ins_template_cate'); -- END; END IF; -- -- We also need to insert any parameters associated with this category IF l_success THEN FOR r IN c_cate_pars LOOP BEGIN INSERT INTO contract_template_params ( cotp_id , display_sequence , inherited , cote_id , pars_id ) VALUES ( cotp_seq.NEXTVAL , r.display_sequence , 'Y' , p_template_id , r.pars_id ); EXCEPTION WHEN others THEN l_success := FALSE; p_return_error := caco_utilities.get_module_text(2223); -- An unexpected error has occurred while updating contract template categories. Please contact support caco_debug.putline('efno_contracts.ins_or_upd_template_p1: ' ||'Update of contract template categories associated parameters failed : ' ||sqlerrm(sqlcode)); -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => 'Failed inserting contract template categories associated parameters: ' ||chr(10)||sqlerrm(sqlcode) , p_source => 'efno_contracts.ins_template_cate'); -- END; END LOOP; -- end of inserting associated parameters END IF; -- IF NOT l_success THEN ROLLBACK TO SAVEPOINT before_ins_cotc; END IF; -- RETURN l_success; -- END ins_template_cate; -- For Updating Contract Template Categories - to enable delete of those no longer attached FUNCTION cotc_in_array( p_id IN NUMBER , p_cate_array IN category_array ) RETURN BOOLEAN IS l_success BOOLEAN := FALSE; BEGIN IF NVL(p_cate_array.COUNT,0) > 0 THEN FOR i IN p_cate_array.FIRST..p_cate_array.LAST LOOP IF p_cate_array(i).cate_id = p_id THEN l_success := TRUE; END IF; END LOOP; END IF; RETURN l_success; END cotc_in_array; -- For Updating Contract Template Categories - to determine if we need to insert into DB FUNCTION cotc_in_db( p_cate_id IN NUMBER , p_template_id IN NUMBER ) RETURN BOOLEAN IS CURSOR c_cotc IS SELECT 'Y' FROM contract_template_categories WHERE cote_id = p_template_id AND cate_id = p_cate_id; -- l_success BOOLEAN := FALSE; l_dummy VARCHAR2(1) := 'X'; -- BEGIN OPEN c_cotc; FETCH c_cotc INTO l_dummy; IF c_cotc%FOUND THEN l_success := TRUE; END IF; CLOSE c_cotc; RETURN l_success; END cotc_in_db; -- For Updating Contract Template Parameters - to enable delete of those no longer attached FUNCTION cotp_in_array( p_id IN NUMBER , p_pars_array IN parameter_array ) RETURN BOOLEAN IS l_success BOOLEAN := FALSE; BEGIN IF NVL(p_pars_array.COUNT,0) > 0 THEN FOR i IN p_pars_array.FIRST..p_pars_array.LAST LOOP IF p_pars_array(i).pars_id = p_id THEN l_success := TRUE; END IF; END LOOP; END IF; RETURN l_success; END cotp_in_array; -- For Updating Contract Template Parameters - to determine if we need to insert into DB -- Note: We are relying on the contract template screen to only show those parameters -- that are NOT associated with categories FUNCTION cotp_in_db( p_pars_id IN NUMBER , p_template_id IN NUMBER ) RETURN BOOLEAN IS CURSOR c_cotp IS SELECT 'Y' FROM contract_template_params WHERE cote_id = p_template_id AND pars_id = p_pars_id; -- l_success BOOLEAN := FALSE; l_dummy VARCHAR2(1) := 'X'; -- BEGIN OPEN c_cotp; FETCH c_cotp INTO l_dummy; IF c_cotp%FOUND THEN l_success := TRUE; END IF; CLOSE c_cotp; RETURN l_success; END cotp_in_db; PROCEDURE ins_or_upd_template_p1( p_ins_or_upd IN VARCHAR2 DEFAULT NULL , p_template_id IN NUMBER DEFAULT 0 , p_template_name IN VARCHAR2 DEFAULT NULL , p_template_desc IN VARCHAR2 DEFAULT NULL , p_emo IN VARCHAR2 DEFAULT NULL , p_cate_id IN owa_util.vc_arr DEFAULT g_vc_arr , p_pars_id IN owa_util.vc_arr DEFAULT g_vc_arr ) IS -- Cursor to list all contracts using the given template CURSOR c_cont IS SELECT cont_id FROM contracts WHERE cote_id = p_template_id; -- CURSOR c_cote_cate( cp_cote_id IN NUMBER ) IS SELECT cate_id FROM contract_template_categories WHERE cote_id = cp_cote_id FOR UPDATE; -- CURSOR c_cote_pars( cp_cote_id IN NUMBER ) IS SELECT pars_id FROM contract_template_params WHERE cote_id = cp_cote_id AND NVL(inherited,'N') = 'N' FOR UPDATE; -- l_error VARCHAR2(1); l_return_error VARCHAR2(250); -- If the insert or update fails - put an error message in here. -- l_template_id NUMBER := 0; l_template_name contract_templates.name%TYPE := NULL; l_template_desc contract_templates.description%TYPE := NULL; l_emo_flag contract_templates.entry_mandatory_offer%TYPE := NULL; l_dummy_cont_id contracts.cont_id%TYPE := 0; -- l_cate_id owa_util.vc_arr; l_pars_id owa_util.vc_arr; -- l_category_array category_array; l_parameter_array parameter_array; -- l_success BOOLEAN := TRUE; -- Used to track how well we are doing in this code.. l_success_char VARCHAR2(1); contracts_exist BOOLEAN := FALSE; -- l_code_position VARCHAR2(4) := '0000'; -- BEGIN -- Check we have permission to be using this module. -- Only called from the Create contracts screen IF NOT caco_security.security_check('efnow050$') THEN RETURN; END IF; -- l_code_position := '0010'; -- IF p_ins_or_upd IS NULL OR ( UPPER(p_ins_or_upd) != 'INSERT' AND UPPER(p_ins_or_upd) != 'UPDATE' ) THEN -- Cannot tell if we should be inserting or updating. Well, we could -- but it's easier to enforce this on the calling prog instead of Assuming. l_code_position := '0015'; l_success := FALSE; l_return_error := caco_utilities.get_module_text(2331); -- Could not determine if Inserting or Updating -- END IF; -- IF l_success THEN l_code_position := '0020'; -- IF UPPER(p_ins_or_upd) = 'UPDATE' AND ( p_template_id IS NULL OR p_template_id = 0 ) THEN l_success := FALSE; l_return_error := caco_utilities.get_module_text(2316); -- Update of Contract Template failed - No Template ID was provided END IF; -- l_code_position := '0030'; -- IF l_success AND ( p_template_name IS NULL OR LENGTH(p_template_name) > 50 ) THEN -- l_success := FALSE; l_return_error := caco_utilities.get_module_text(2304); -- Template Name must be present with a maximum length of 50 characters -- END IF; -- l_code_position := '0040'; -- IF l_success AND ( p_template_desc IS NULL OR LENGTH(p_template_desc) > 250 ) THEN -- l_success := FALSE; l_return_error := caco_utilities.get_module_text(2303); -- Template Description must be present with a maximum length of 250 characters -- END IF; -- -- Hokey Cokey. Insert or Update the basic part of the template -- and then the categories and parameters -- Remember - for each category, add its associated parameters. -- l_code_position := '0050'; -- IF l_success THEN -- Lets look at Inserting the contract template first... IF p_ins_or_upd = 'INSERT' THEN -- l_code_position := '0060'; -- BEGIN INSERT INTO contract_templates ( cote_id , name , description , entry_mandatory_offer ) VALUES ( cote_seq.NEXTVAL , p_template_name , p_template_desc , p_emo ) RETURNING cote_id INTO l_template_id; EXCEPTION WHEN dup_val_on_index THEN l_success := FALSE; l_return_error := caco_utilities.get_module_text(2253); -- Duplicate Contract Template Name already exists WHEN others THEN l_success := FALSE; l_return_error := caco_utilities.get_module_text(2219); -- An unexpected error has occurred while inserting new contract template. Please contact support caco_debug.putline('efno_contracts.ins_or_upd_template_p1: ' ||'Insert of new contract template failed : '||sqlerrm(sqlcode)); -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => 'Failed inserting contract template: ' ||chr(10)||sqlerrm(sqlcode) , p_source => 'efno_contracts.ins_or_upd_template_p1'); -- END; -- ELSE l_code_position := '0070'; -- Update BEGIN UPDATE contract_templates SET name = p_template_name , description = p_template_desc , entry_mandatory_offer = p_emo WHERE cote_id = p_template_id; EXCEPTION WHEN dup_val_on_index THEN l_success := FALSE; l_return_error := caco_utilities.get_module_text(2253); -- Duplicate Contract Template Name already exists WHEN others THEN l_success := FALSE; l_return_error := caco_utilities.get_module_text(2328); -- An unexpected error has occurred while updating contract template. Please contact support caco_debug.putline('efno_contracts.ins_or_upd_template_p1: ' ||'Update of contract template failed : '||sqlerrm(sqlcode)); -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => 'Failed updating contract template: ' ||chr(10)||sqlerrm(sqlcode) , p_source => 'efno_contracts.ins_or_upd_template_p1'); -- END; -- -- Do we have any contracts for the given template id? IF l_success THEN OPEN c_cont; FETCH c_cont INTO l_dummy_cont_id; IF c_cont%FOUND THEN contracts_exist := TRUE; END IF; CLOSE c_cont; END IF; -- END IF; -- end of "if insert or update contract template" -- END IF; -- End of basic insert -- l_code_position := '0080'; -- -- Get Categories IF l_success THEN l_code_position := '1000'; -- l_template_name := p_template_name; l_template_desc := p_template_desc; l_emo_flag := p_emo; -- find_passed_categories( p_cate_id , l_category_array ); -- IF p_ins_or_upd = 'INSERT' THEN -- l_code_position := '1010'; -- <> FOR i IN 1..l_category_array.COUNT LOOP -- l_code_position := '1020'; -- l_success := ins_template_cate( l_template_id , l_category_array(i).cate_id , i+1 , FALSE , l_return_error ); -- IF NOT l_success THEN EXIT ins_cotc_loop; END IF; -- END LOOP ins_cotc_loop; -- end of inserting new categories -- ELSE -- Update l_code_position := '1200'; -- l_template_id := p_template_id; -- -- This is easier to get to grips with as a two pass process -- First, zip through the existing DB data for the contract and delete existing rows not in our array <> FOR r IN c_cote_cate( p_template_id ) LOOP -- IF NOT cotc_in_array( r.cate_id , l_category_array ) THEN l_code_position := '1210'; -- This Category doesn't exist in the new set -- So we need to delete any parameters associated with this category and then -- delete the category itself. If any contracts have this template - we need -- to remove the parameters and categories from those also. -- l_success := del_template_cate( p_template_id , r.cate_id , contracts_exist , l_return_error ); -- IF NOT l_success THEN EXIT upd_del_cotc_loop; END IF; -- END IF; -- END LOOP upd_del_cotc_loop; -- l_code_position := '1300'; -- -- Second, go through the passed array and insert those categories that dont already exist. -- <> FOR i IN 1..l_category_array.COUNT LOOP -- IF NOT cotc_in_db( l_category_array(i).cate_id , p_template_id ) THEN l_code_position := '1310'; -- -- Current category does not exist in the DB so we need to INSERT -- Also need to add the category and associated parameters to all contracts -- that have this contract template -- l_success := ins_template_cate( p_template_id , l_category_array(i).cate_id , i+1 , contracts_exist , l_return_error ); -- IF NOT l_success THEN EXIT upd_ins_cotc_loop; END IF; -- ELSE -- -- Contract template category DOES exist, just update it's sequence -- upd_cotc( p_template_id , l_category_array(i).cate_id , i+1); -- END IF; -- END LOOP upd_ins_cotc_loop; -- END IF; -- contract template insert or update categories. -- END IF; -- End of categories -- l_code_position := '2000'; -- IF l_success THEN l_code_position := '2010'; -- -- Get Parameters find_passed_parameters( p_pars_id , l_parameter_array ); -- IF p_ins_or_upd = 'INSERT' THEN l_code_position := '2020'; -- -- Easy, just insert all passed parameters. <> FOR i IN 1..l_parameter_array.COUNT LOOP -- l_success := ins_template_pars( l_template_id , l_parameter_array(i).pars_id , contracts_exist , l_return_error ); -- IF NOT l_success THEN EXIT ins_cotp_loop; END IF; -- END LOOP ins_cotp_loop; -- end of inserting new parameters -- ELSE l_code_position := '2300'; -- UPDATE. This is easier to get to grips with as a two pass process -- First, zip through the existing DB data for the contract template -- and delete existing rows not in our array <> FOR r IN c_cote_pars( p_template_id ) LOOP -- IF NOT cotp_in_array( r.pars_id , l_parameter_array ) THEN -- This Parameterory doesn't exist in the new set -- We need to delete the parameter -- l_success := del_template_pars( p_template_id , r.pars_id , contracts_exist , l_return_error ); -- IF NOT l_success THEN EXIT upd_del_cotp_loop; END IF; -- END IF; -- end when the parameter has been removed from the contract template -- END LOOP upd_del_cotp_loop; -- l_code_position := '2310'; -- -- Second, go through the passed array and insert those parameters that dont already exist. <> FOR i IN 1..l_parameter_array.COUNT LOOP -- l_code_position := '2320'; -- IF NOT cotp_in_db( l_parameter_array(i).pars_id , p_template_id ) THEN l_code_position := '2330'; -- Current Parameter does not exist in the DB so we need to INSERT l_success := ins_template_pars( p_template_id , l_parameter_array(i).pars_id , contracts_exist , l_return_error ); -- IF NOT l_success THEN EXIT upd_ins_cotp_loop; END IF; -- END IF; -- end of parameter doesnt exist in DB -- END LOOP upd_ins_cotp_loop; -- END IF; -- contract template insert or update parameter. -- END IF; -- end of contract template parameters -- END IF; -- l_code_position := '9000'; -- IF l_success THEN -- Commit the changes COMMIT; -- l_success_char := 'Y'; l_error := NULL; l_return_error := NULL; -- l_code_position := '9010'; -- l_cate_id := g_vc_arr; l_pars_id := g_vc_arr; -- ELSE l_code_position := '9020'; -- l_success_char := NULL; l_error := 'Y'; -- -- Failed somewhere -- Rollback any partially made inserts/updates ROLLBACK; -- l_cate_id := p_cate_id; l_pars_id := p_pars_id; -- END IF; -- l_code_position := '9100'; -- Call the contracts screen efnow050$.contract_startup( p_screen_type => 'TEMPLATE' , p_ins_or_upd => p_ins_or_upd , p_success => l_success_char , p_error => l_error , p_err_msg => l_return_error , p_template_id => l_template_id , p_template_name => l_template_name , p_template_desc => l_template_desc , p_emo => l_emo_flag , p_cate_id => l_cate_id , p_pars_id => l_pars_id ); -- EXCEPTION WHEN others THEN ROLLBACK; caco_debug.putline('efno_contracts.ins_or_upd_template_p1: ' ||'Position in Code : '||l_code_position||' : '||chr(10) ||sqlerrm(sqlcode)); -- Write an error and carry on cout_err.report_and_go( p_exception_number => sqlcode , p_exception_message => 'Unexpected error: Position in Code :'||l_code_position ||chr(10)||sqlerrm(sqlcode) , p_source => 'efno_contracts.ins_or_upd_template_p1'); -- RAISE; END ins_or_upd_template_p1; -- PROCEDURE copy_contract_opts(p_cont_id_from IN contracts.cont_id%TYPE, p_cont_id_to IN contracts.cont_id%TYPE) IS -- Cursor to collect current options exist CURSOR c_options_from IS SELECT * FROM contract_options WHERE cont_id = p_cont_id_from; -- Cursor to see if new options already exist CURSOR c_options_to IS SELECT cont_id FROM contract_options WHERE cont_id = p_cont_id_to; l_contract_opt_record contract_options%ROWTYPE; l_contract_id contract_options.cont_id%TYPE; l_success BOOLEAN := TRUE; BEGIN IF p_cont_id_from IS NOT NULL AND p_cont_id_from > 0 THEN OPEN c_options_from; FETCH c_options_from INTO l_contract_opt_record; IF c_options_from%NOTFOUND THEN l_success := FALSE; END IF; CLOSE c_options_from; ELSE l_success := FALSE; END IF; -- IF l_success AND p_cont_id_to IS NOT NULL AND p_cont_id_to > 0 THEN OPEN c_options_to; FETCH c_options_to INTO l_contract_id; IF c_options_to%FOUND THEN l_success := FALSE; UPDATE contract_options SET nom_conf_subject = l_contract_opt_record.nom_conf_subject, nom_conf_content = l_contract_opt_record.nom_conf_content, com_conf_subject = l_contract_opt_record.com_conf_subject, com_conf_content = l_contract_opt_record.com_conf_content, auto_gen_conf = l_contract_opt_record.auto_gen_conf, conf_type = l_contract_opt_record.conf_type, ind_deadline_for_nom_submit = l_contract_opt_record.ind_deadline_for_nom_submit, shipper = l_contract_opt_record.shipper, int_subject = l_contract_opt_record.int_subject, int_content = l_contract_opt_record.int_content, int_sms_content = l_contract_opt_record.int_sms_content WHERE cont_id = p_cont_id_to; END IF; CLOSE c_options_to; ELSE l_success := FALSE; END IF; -- Copy contract options across IF l_success THEN INSERT INTO contract_options (cont_id, nom_conf_subject, nom_conf_content, com_conf_subject, com_conf_content, auto_gen_conf, conf_type, ind_deadline_for_nom_submit, shipper, int_subject, int_content, int_sms_content) VALUES (p_cont_id_to, l_contract_opt_record.nom_conf_subject, l_contract_opt_record.nom_conf_content, l_contract_opt_record.com_conf_subject, l_contract_opt_record.com_conf_content, l_contract_opt_record.auto_gen_conf, l_contract_opt_record.conf_type, l_contract_opt_record.ind_deadline_for_nom_submit, l_contract_opt_record.shipper, l_contract_opt_record.int_subject, l_contract_opt_record.int_content, l_contract_opt_record.int_sms_content); END IF; END copy_contract_opts; PROCEDURE copy_contract ( p_cont_id_from contracts.cont_id%TYPE , p_cont_number_to contracts.contract_number%TYPE ) IS -- l_contract_row contracts%ROWTYPE; l_old_cont_id contracts.cont_id%TYPE; -- l_nepo_array owa_util.vc_arr; l_cate_array owa_util.vc_arr; l_pars_array owa_util.vc_arr; -- BEGIN -- -- Security check (Only called from the Create contracts screen) -- IF NOT caco_security.security_check('efnow050$') THEN RETURN; END IF; -- -- OK, get the contract values -- SELECT c.* INTO l_contract_row FROM contracts c WHERE c.cont_id = p_cont_id_from; -- SELECT cnp.nepo_id BULK COLLECT INTO l_nepo_array FROM cont_network_points cnp WHERE cnp.cont_id = p_cont_id_from; -- SELECT cc.cate_id BULK COLLECT INTO l_cate_array FROM contract_categories cc WHERE cc.cont_id = p_cont_id_from; -- SELECT cp.pars_id BULK COLLECT INTO l_pars_array FROM contract_parameters cp WHERE cp.cont_id = p_cont_id_from AND cp.pars_id IN (SELECT pars_id FROM parameters p WHERE p.cate_id IS NULL); -- AND cp.inherited = 'N'; -- 31/07/07 SP Commented out above line so all parameters are copied including parameters inherited from template. -- 31/08/07 SP Commented back in as caused duplicate columns on contract set values screen for copied contracts. -- 19/09/07 SP Replaced with new AND clause to allow copying without duplication. -- -- Override specific settings - new contract must be closed -- l_contract_row.status := 'C'; -- SELECT cont_seq.nextval INTO l_old_cont_id FROM DUAL; -- commit; -- -- AWG Dec 2010 Requested modification to the copied contract -- The new contract will have the original as its previous contract to -- start the day after and last for 30 days. ins_or_upd_contract_p1 ( p_ins_or_upd => 'INSERT' , p_contract_id => 0 , p_contract_number => p_cont_number_to --, p_pre_contract_id => l_contract_row.prev_cont_id , p_pre_contract_id => l_contract_row.cont_id , p_customer_id => l_contract_row.cust_id , p_template_id => l_contract_row.cote_id , p_spte_id => l_contract_row.spte_id , p_ops_contact => l_contract_row.operations_contact , p_bus_contact => l_contract_row.business_contact , p_status => l_contract_row.status , p_days_before => l_contract_row.receive_before_start --, p_date_from => TO_CHAR(l_contract_row.valid_from, cout_system_configuration.get_configuration_item('G_DATE_FORMAT')) --, p_date_to => TO_CHAR(l_contract_row.valid_until, cout_system_configuration.get_configuration_item('G_DATE_FORMAT')) , p_date_from => TO_CHAR(l_contract_row.valid_until + 1, cout_system_configuration.get_configuration_item('G_DATE_FORMAT')) , p_date_to => TO_CHAR(l_contract_row.valid_until + 31, cout_system_configuration.get_configuration_item('G_DATE_FORMAT')) , p_val_window => l_contract_row.validation_window , p_val_action => l_contract_row.validation_action , p_val_exception => l_contract_row.validation_exception , p_lookback_action => l_contract_row.lookback_action , p_nepo_id => l_nepo_array , p_cate_id => l_cate_array , p_pars_id => l_pars_array ); -- SELECT cont_seq.currval INTO l_contract_row.cont_id FROM DUAL; -- IF l_contract_row.cont_id > l_old_cont_id THEN -- -- Copy the contract options -- copy_contract_opts(p_cont_id_from, l_contract_row.cont_id); -- -- Copy The network point group parameters -- INSERT INTO network_point_gp_params ( nepg_id , cont_id , name , code , value ) SELECT nepg_id , l_contract_row.cont_id , name , code , value FROM network_point_gp_params npgp WHERE npgp.cont_id = p_cont_id_from; -- -- Now copy the rules -- INSERT INTO contract_rules ( coru_id , display_sequence , inherited , cont_id , coru_type , rule_name , left_side , rule_relation , right_side , error_message_hu , error_message_en , rule_id ) SELECT coru_seq.NEXTVAL , cr.display_sequence , cr.inherited , l_contract_row.cont_id , cr.coru_type , cr.rule_name , cr.left_side , cr.rule_relation , cr.right_side , cr.error_message_hu , cr.error_message_en , cr.rule_id FROM contract_rules cr WHERE cr.cont_id = p_cont_id_from AND cr.inherited = 'N'; -- -- Finally copy the values -- MERGE INTO cont_net_point_param_vals cnppv USING ( SELECT cnppv2.value ,cnpt.conp_id ,cpt.copa_id FROM cont_net_point_param_vals cnppv2 ,contract_parameters cpf ,contract_parameters cpt ,cont_network_points cnpf ,cont_network_points cnpt WHERE cnppv2.copa_id = cpf.copa_id AND cnppv2.conp_id = cnpf.conp_id AND cpf.cont_id = p_cont_id_from AND cpf.pars_id = cpt.pars_id AND cnpf.nepo_id = cnpt.nepo_id AND cpt.cont_id = l_contract_row.cont_id AND cnpt.cont_id = l_contract_row.cont_id ) cnppv_sq1 ON ( cnppv.conp_id = cnppv_sq1.conp_id AND cnppv.copa_id = cnppv_sq1.copa_id ) WHEN MATCHED THEN UPDATE SET cnppv.value = cnppv_sq1.value WHEN NOT MATCHED THEN INSERT ( cnppv.cnppv_id , cnppv.value , cnppv.conp_id , cnppv.copa_id ) VALUES ( cnppv_seq.NEXTVAL , cnppv_sq1.value , cnppv_sq1.conp_id , cnppv_sq1.copa_id ); -- END IF; -- END copy_contract; -- PROCEDURE efnow050$copy ( p_contract_id IN NUMBER DEFAULT NULL , p_contract_name IN VARCHAR2 DEFAULT NULL , p_action IN VARCHAR2 DEFAULT NULL ) IS -- l_in_error BOOLEAN := FALSE; -- BEGIN -- -- Security check (Only called from the Create contracts screen) -- IF NOT caco_security.security_check('efnow050$') THEN RETURN; END IF; -- -- Build the screen -- IF p_contract_name IS NOT NULL THEN -- FOR i IN ( SELECT NULL FROM contracts c WHERE c.contract_number = p_contract_name ) LOOP -- l_in_error := TRUE; EXIT; -- END LOOP; -- END IF; -- IF p_action IS NULL OR l_in_error THEN -- -- OK, let's build the form. -- wsgl.openpagehead(caco_utilities.get_module_text(2099)); -- Maintain Contract Template Rules caco_system.content_type; htp.p(''); wsgl.closepagehead; wsgl.openpagebody(FALSE); htp.p(caco_system.menu); htp.header( nsize => 1 , cheader => caco_utilities.get_module_text(3549) ); -- IF l_in_error THEN -- wsgl.displaymessage(p_type => WSGL.MESS_ERROR ,p_mess => caco_utilities.get_module_text(2252) ); -- END IF; -- htp.p('
'); -- htp.p('
'); -- htp.p(''); htp.p(''); htp.p(''); htp.p(''); htp.p('
'||caco_utilities.get_module_text(3552)||':
'||caco_utilities.get_module_text(3553)||':
'); -- htp.p('
'); -- htp.p(''); -- htp.p('
'); -- caco_system.footer(p_closebody => TRUE); -- ELSE -- -- Otherwise, copy the contract -- efno_contracts.copy_contract ( p_cont_id_from => p_contract_id , p_cont_number_to => p_contract_name ); -- END IF; -- END efnow050$copy; -- /** -- 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_contracts; /