DBA Data[Home] [Help]

PACKAGE BODY: APPS.OKC_XPRT_RULES_ENGINE_PVT

Source


1 PACKAGE BODY OKC_XPRT_RULES_ENGINE_PVT AS
2 /* $Header: OKCVXRULENGB.pls 120.1.12020000.4 2012/08/22 09:03:02 nbingi noship $ */
3 
4 --global_variables
5 G_PKG_NAME CONSTANT VARCHAR2(200) := 'OKC_XPRT_RULES_ENGINE_PVT';
6 G_MODULE_NAME CONSTANT VARCHAR2(250) := 'okc.plsql.'||G_PKG_NAME||'.';
7 
8 FUNCTION getTemplateId RETURN NUMBER IS
9 BEGIN
10 RETURN p_template_id;
11 END;
12 
13 FUNCTION getDocId RETURN NUMBER IS
14 BEGIN
15 RETURN p_doc_id;
16 END;
17 
18 FUNCTION getDocType RETURN VARCHAR2 IS
19 BEGIN
20 RETURN p_doc_type;
21 END;
22 
23 PROCEDURE init_contract_expert(doc_id IN NUMBER, doc_type IN VARCHAR2, template_id IN NUMBER, x_has_questions OUT NOCOPY VARCHAR2) IS
24 
25 l_api_name CONSTANT VARCHAR2(30) := 'init_contract_expert';
26 l_module VARCHAR2(250) := G_MODULE_NAME||l_api_name;
27 
28 l_template_id NUMBER;
29 BEGIN
30 
31 	IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
32 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: Entering method');
33 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: doc_id : ' || doc_id);
34 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: doc_type : ' || doc_type);
35      		FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: template_id : ' || template_id);
36 	END IF;
37 
38 	p_doc_id := doc_id;
39   	p_doc_type := doc_type;
40   	p_template_id := template_id;
41 
42 	--populating all temp tables and evaluating conditions
43 	populate_rule_cond_eval_table();    --populating okc_xprt_rule_eval_result_t table with all rules and conditions
44   	populate_doc_var_values();	    --populating okc_xprt_rule_eval_condval_t with variables values
45   	populate_doc_questions();	    --populating okc_xprt_rule_eval_condval_t with questions for the VO to render in Questions UI page
46 	populate_rule_cond_dep();		    --populating rule, cond clause lvel dependency into a gt table
47   	evaluate_rules_and_conditions();    --evaluating rules and conditions. evaluate variable based conditions and question based condition if it has a response
48 
49 	x_has_questions := 'N';
50 
51 	BEGIN
52 		SELECT 'Y' INTO x_has_questions FROM dual
53 		WHERE EXISTS (SELECT 1 FROM okc_xprt_rule_eval_condval_t WHERE doc_id = p_doc_id AND doc_type = p_doc_type
54 				    AND object_type = 'QUESTION' AND display_flag = 'Y');
55  	EXCEPTION
56     		WHEN NO_DATA_FOUND THEN
57   		NULL;
58   	END;
59 
60 	IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
61 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '110: x_has_questions : ' || x_has_questions);
62 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '110: Leaving method');
63 	END IF;
64 
65 EXCEPTION
66 WHEN OTHERS THEN
67 	IF (FND_LOG.LEVEL_EXCEPTION >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
68 		FND_LOG.STRING( FND_LOG.LEVEL_EXCEPTION, l_module, '120: Exception occured: ' || sqlerrm);
69 	END IF;
70 	raise;
71 END init_contract_expert;
72 
73 
74 PROCEDURE populate_rule_cond_eval_table IS
75 
76 CURSOR c_rules IS
77 SELECT rule.rule_id, rule.condition_expr_code
78 FROM okc_xprt_template_rules rultmpl, okc_xprt_rule_hdrs_all_v rule
79 WHERE rultmpl.template_id = p_template_id
80 AND rule.rule_id = rultmpl.rule_id
81 UNION ALL
82 SELECT rule.rule_id, rule.condition_expr_code
83 FROM okc_xprt_rule_hdrs_all_v rule
84 WHERE rule.org_id = (SELECT org_id FROM okc_terms_templates_all WHERE template_id = p_template_id)
85 AND rule.intent = (SELECT intent FROM okc_terms_templates_all WHERE template_id = p_template_id)
86 AND rule.org_wide_flag = 'Y';
87 
88 CURSOR c_rule_conditions IS
89 SELECT cond.rule_id, cond.rule_condition_id, cond.object_type condition_type, cond.object_code, rule.condition_expr_code, cond.object_value_type, cond.object_value_code, cond.operator
90 FROM okc_xprt_template_rules rultmpl, okc_xprt_rule_hdrs_all_v rule, okc_xprt_rule_cond_active_v cond
91 WHERE rultmpl.template_id = p_template_id
92 AND rule.rule_id = rultmpl.rule_id
93 AND cond.rule_id = rule.rule_id
94 UNION ALL
95 SELECT cond.rule_id, cond.rule_condition_id, cond.object_type condition_type, cond.object_code, rule.condition_expr_code, cond.object_value_type, cond.object_value_code, cond.operator
96 FROM okc_xprt_rule_hdrs_all_v rule, okc_xprt_rule_cond_active_v cond
97 WHERE rule.org_id = (SELECT org_id FROM okc_terms_templates_all WHERE template_id = p_template_id)
98 AND rule.intent = (SELECT intent FROM okc_terms_templates_all WHERE template_id = p_template_id)
99 AND rule.org_wide_flag = 'Y'
100 AND cond.rule_id = rule.rule_id;
101 
102 rule_ids number_type;
103 cond_ids number_type;
104 
105 TYPE varchar2_30 IS TABLE OF VARCHAR2(30);
106 cond_types varchar2_30;
107 cond_expr_codes varchar2_30;
108 cond_operator varchar2_30;
109 cond_value_type varchar2_30;
110 
111 TYPE varchar2_40 IS TABLE OF VARCHAR2(40);
112 cond_object_codes varchar2_40;
113 
114 TYPE varchar2_1000 IS TABLE OF VARCHAR2(1000);
115 cond_object_value_codes varchar2_1000;
116 
117 l_api_name CONSTANT VARCHAR2(30) := 'populate_rule_cond_eval_table';
118 l_module VARCHAR2(250) := G_MODULE_NAME||l_api_name;
119 
120 BEGIN
121 
122 	IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
123 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: Entering method');
124 	END IF;
125 
126 	DELETE okc_xprt_rule_eval_result_t WHERE doc_id = p_doc_id and doc_type = p_doc_type;
127 
128 	IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
129 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '110: Deleted entries in okc_xprt_rule_eval_result_t for this document before populating');
130 	END IF;
131 
132 	OPEN c_rules;
133 	FETCH c_rules BULK COLLECT INTO rule_ids, cond_expr_codes;
134 	FORALL i IN 1 .. rule_ids.count
135 		INSERT INTO okc_xprt_rule_eval_result_t(rule_condition_result_id, doc_id, doc_type, rule_id, condition_id, condition_type, object_code, rule_expr_type, object_value_type, cond_operator, result)
136 		VALUES(OKC_XPRT_RULE_EVAL_RESULT_S.nextval, p_doc_id, p_doc_type, rule_ids(i), null, null, null, cond_expr_codes(i), null, null, null);
137 	CLOSE c_rules;
138 
139 	OPEN c_rule_conditions;
140 	FETCH c_rule_conditions BULK COLLECT INTO rule_ids, cond_ids, cond_types, cond_object_codes, cond_expr_codes, cond_value_type, cond_object_value_codes, cond_operator;
141 	FORALL i IN 1 .. rule_ids.count
142 		INSERT INTO okc_xprt_rule_eval_result_t(rule_condition_result_id, doc_id, doc_type, rule_id, condition_id, condition_type, object_code, rule_expr_type, object_value_type, object_value_code, cond_operator, result)
143 		VALUES(OKC_XPRT_RULE_EVAL_RESULT_S.nextval, p_doc_id, p_doc_type, rule_ids(i), cond_ids(i), cond_types(i), cond_object_codes(i), cond_expr_codes(i), cond_value_type(i), cond_object_value_codes(i), cond_operator(i), null);
144 	CLOSE c_rule_conditions;
145 
146 	IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
147 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '120: Populated entries in okc_xprt_rule_eval_result_t for this document');
148 		FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '120: No. of rules populated: ' || cond_expr_codes.count);
149 		FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '120: No. of rule conditions populated: ' || cond_ids.count);
150 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '120: Leaving method');
151 	END IF;
152 
153 EXCEPTION
154 WHEN OTHERS THEN
155 	IF (FND_LOG.LEVEL_EXCEPTION >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
156 		FND_LOG.STRING( FND_LOG.LEVEL_EXCEPTION, l_module, '130: Exception occured: ' || sqlerrm);
157 	END IF;
158 	raise;
159 END populate_rule_cond_eval_table;
160 
161 
162 PROCEDURE populate_doc_var_values IS
163 
164 x_return_status VARCHAR(1);
165 x_msg_data  VARCHAR2(4000);
166 x_msg_count  NUMBER;
167 x_hdr_var_value_tbl okc_xprt_xrule_values_pvt.var_value_tbl_type;
168 x_line_sysvar_value_tbl okc_xprt_xrule_values_pvt.line_sys_var_value_tbl_type;
169 x_line_count	NUMBER;
170 x_line_variables_count NUMBER;
171 x_intent VARCHAR2(1);
172 x_org_id NUMBER;
173 
174 TYPE var_val_rec_type IS RECORD (
175   variable_code            VARCHAR2(40),
176   variable_value_id        VARCHAR2(4000)
177 );
178 
179 TYPE var_val_tbl_type IS TABLE OF var_val_rec_type INDEX BY BINARY_INTEGER;
180 variable_values_tbl var_val_tbl_type;
181 
182 l_api_name CONSTANT VARCHAR2(30) := 'populate_doc_var_values';
183 l_module VARCHAR2(250) := G_MODULE_NAME||l_api_name;
184 
185 BEGIN
186 
187 	IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
188 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: Entering method');
189 	END IF;
190 
191 	DELETE okc_xprt_rule_eval_condval_t WHERE doc_id = p_doc_id and doc_type = p_doc_type;
192 
193 	IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
194 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '110: Deleted entries in okc_xprt_rule_eval_condval_t for this document before populating the variable values');
195 	END IF;
196 
197 	okc_xprt_xrule_values_pvt.get_document_values(p_api_version => 1,
198                                               p_init_msg_list => FND_API.G_FALSE,
199                                               p_doc_type    => p_doc_type,
200                                               p_doc_id      => p_doc_id,
201                                               x_return_status => x_return_status,
202                                               x_msg_data    => x_msg_data,
203                                               x_msg_count   => x_msg_count,
204                                               x_hdr_var_value_tbl  => x_hdr_var_value_tbl,
205                                               x_line_sysvar_value_tbl  => x_line_sysvar_value_tbl,
206                                               x_line_count  => x_line_count,
207                                               x_line_variables_count => x_line_variables_count,
208                                               x_intent			=> x_intent,
209                                               x_org_id		  => x_org_id
210                                               );
211 
212 IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
213 	IF x_hdr_var_value_tbl.Count > 0 THEN
214 		FOR j IN x_hdr_var_value_tbl.first..x_hdr_var_value_tbl.LAST LOOP
215 			FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '120: Variable code: ' || x_hdr_var_value_tbl(j).variable_code);
216 			FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '120: Variable value id: ' || x_hdr_var_value_tbl(j).variable_value_id);
217 		END LOOP;
218 	END IF;
219 
220 	IF x_line_sysvar_value_tbl.Count > 0 THEN
221 		FOR j IN x_line_sysvar_value_tbl.first..x_line_sysvar_value_tbl.LAST LOOP
222 			FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '130: Variable code: ' || x_line_sysvar_value_tbl(j).variable_code);
223 			FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '130: Variable value: ' || x_line_sysvar_value_tbl(j).variable_value);
224 		END LOOP;
225 	END IF;
226 END IF;
227 
228 IF x_hdr_var_value_tbl.Count > 0 THEN
229   FOR j IN x_hdr_var_value_tbl.first..x_hdr_var_value_tbl.LAST LOOP
230     IF InStr(x_hdr_var_value_tbl(j).variable_code,'CONSTANT$') > 0 THEN
231       variable_values_tbl(j).variable_code := SubStr(x_hdr_var_value_tbl(j).variable_code,Length('CONSTANT$')+1);
232     ELSIF InStr(x_hdr_var_value_tbl(j).variable_code,'USER$') > 0 THEN
233       variable_values_tbl(j).variable_code := SubStr(x_hdr_var_value_tbl(j).variable_code,Length('USER$')+1);
234     ELSE
235       variable_values_tbl(j).variable_code := x_hdr_var_value_tbl(j).variable_code;
236     END IF;
237     variable_values_tbl(j).variable_value_id := x_hdr_var_value_tbl(j).variable_value_id;
238   END LOOP;
239 
240   FORALL j IN variable_values_tbl.first..variable_values_tbl.last
241   INSERT INTO okc_xprt_rule_eval_condval_t(doc_value_id, doc_id, doc_type, object_type, object_code, value_or_response)
242   VALUES (OKC_XPRT_RULE_EVAL_CONDVAL_S.nextval, p_doc_id, p_doc_type, 'VARIABLE', variable_values_tbl(j).variable_code ,variable_values_tbl(j).variable_value_id);
243 END IF;
244 
245 IF x_line_sysvar_value_tbl.Count > 0 THEN
246   FORALL j IN x_line_sysvar_value_tbl.first..x_line_sysvar_value_tbl.LAST
247   INSERT INTO okc_xprt_rule_eval_condval_t(doc_value_id, doc_id, doc_type, object_type, object_code, value_or_response)
248   VALUES (OKC_XPRT_RULE_EVAL_CONDVAL_S.nextval, p_doc_id, p_doc_type, 'VARIABLE',x_line_sysvar_value_tbl(j).variable_code,x_line_sysvar_value_tbl(j).variable_value);
249 END IF;
250 
251 IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
252      	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '140: Populated entries i.e variable values in okc_xprt_rule_eval_condval_t for this document');
253 	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '140: No. of global variables populated: ' || x_hdr_var_value_tbl.count);
254 	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '140: No. of line variables populated: ' || x_line_sysvar_value_tbl.count);
255      	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '140: Leaving method');
256 END IF;
257 
258 EXCEPTION
259 WHEN OTHERS THEN
260 	IF (FND_LOG.LEVEL_EXCEPTION >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
261 		FND_LOG.STRING( FND_LOG.LEVEL_EXCEPTION, l_module, '150: Exception occured: ' || sqlerrm);
262 	END IF;
263 	raise;
264 END populate_doc_var_values;
265 
266 
267 PROCEDURE populate_doc_questions IS
268 
269 CURSOR c_question is
270 SELECT distinct cond.object_code, q.mandatory_flag display_flag
271 FROM okc_xprt_rule_eval_result_t cond, okc_xprt_question_orders q
272 WHERE cond.doc_id = p_doc_id
273 AND cond.doc_type = p_doc_type
274 AND cond.condition_type = 'QUESTION'
275 AND q.template_id = p_template_id
276 AND cond.object_code = q.question_id
277 UNION
278 SELECT distinct cond.object_value_code, q.mandatory_flag display_flag
279 FROM okc_xprt_rule_eval_result_t cond, okc_xprt_question_orders q
280 WHERE cond.doc_id = p_doc_id
281 AND cond.doc_type = p_doc_type
282 AND cond.object_value_type = 'QUESTION'
283 AND q.template_id = p_template_id
284 AND cond.object_value_code = q.question_id
285 UNION
286 SELECT distinct to_char(outcome.object_value_id), q.mandatory_flag display_flag
287 FROM okc_xprt_template_rules rultmpl, okc_xprt_rule_outcomes_act_v outcome, okc_xprt_question_orders q
288 WHERE rultmpl.template_id = p_template_id
289 AND outcome.rule_id = rultmpl.rule_id
290 AND outcome.object_type = 'QUESTION'
291 AND q.template_id = p_template_id
292 AND outcome.object_value_id = q.question_id
293 UNION
294 SELECT distinct to_char(outcome.object_value_id), q.mandatory_flag display_flag
295 FROM okc_xprt_rule_hdrs_all_v rul, okc_xprt_rule_outcomes_act_v outcome, okc_xprt_question_orders q
296 WHERE rul.org_wide_flag = 'Y'
297 AND outcome.rule_id = rul.rule_id
298 AND outcome.object_type = 'QUESTION'
299 AND q.template_id = p_template_id
300 AND outcome.object_value_id = q.question_id;
301 
302 CURSOR c_question_and_response is
303 SELECT distinct cond.object_code, resp.response, q.mandatory_flag display_flag
304 FROM okc_xprt_rule_eval_result_t cond, okc_xprt_doc_ques_response resp, okc_xprt_question_orders q
305 WHERE cond.doc_id = p_doc_id
306 AND cond.doc_type = p_doc_type
307 AND cond.condition_type = 'QUESTION'
308 AND resp.doc_id (+) = cond.doc_id
309 AND resp.doc_type (+) = cond.doc_type
310 AND resp.question_id (+) = cond.object_code
311 AND q.template_id = p_template_id
312 AND cond.object_code = q.question_id
313 UNION
314 SELECT distinct cond.object_value_code, resp.response, q.mandatory_flag display_flag
315 FROM okc_xprt_rule_eval_result_t cond, okc_xprt_doc_ques_response resp, okc_xprt_question_orders q
316 WHERE cond.doc_id = p_doc_id
317 AND cond.doc_type = p_doc_type
318 AND cond.object_value_type = 'QUESTION'
319 AND resp.doc_id (+) = cond.doc_id
320 AND resp.doc_type (+) = cond.doc_type
321 AND resp.question_id (+) = cond.object_value_code
322 AND q.template_id = p_template_id
323 AND cond.object_value_code = q.question_id
324 UNION
325 SELECT distinct to_char(outcome.object_value_id), resp.response, q.mandatory_flag display_flag
326 FROM  okc_xprt_template_rules rultmpl, okc_xprt_rule_outcomes_act_v outcome, okc_xprt_doc_ques_response resp, okc_xprt_question_orders q
327 WHERE rultmpl.template_id = p_template_id
328 AND outcome.rule_id = rultmpl.rule_id
329 AND outcome.object_type = 'QUESTION'
330 AND resp.doc_id (+) = p_doc_id
331 AND resp.doc_type (+) = p_doc_type
332 AND resp.question_id (+) = outcome.object_value_id
333 AND q.template_id = p_template_id
334 AND outcome.object_value_id = q.question_id
335 UNION
336 SELECT distinct to_char(outcome.object_value_id), resp.response, q.mandatory_flag display_flag
337 FROM  okc_xprt_rule_hdrs_all_v rul, okc_xprt_rule_outcomes_act_v outcome, okc_xprt_doc_ques_response resp, okc_xprt_question_orders q
338 WHERE rul.org_wide_flag = 'Y'
339 AND outcome.rule_id = rul.rule_id
340 AND outcome.object_type = 'QUESTION'
341 AND resp.doc_id (+) = p_doc_id
342 AND resp.doc_type (+) = p_doc_type
343 AND resp.question_id (+) = outcome.object_value_id
344 AND q.template_id = p_template_id
345 AND outcome.object_value_id = q.question_id;
346 
347 TYPE varchar2_1 IS TABLE OF VARCHAR2(1);
348 display_flags varchar2_1;
349 TYPE varchar2_40 IS TABLE OF VARCHAR2(40);
350 question_ids varchar2_40;
351 TYPE varchar2_4000 IS TABLE OF VARCHAR2(4000);
352 responses varchar2_4000;
353 is_contract_expert_run VARCHAR2(1) := 'N';
354 
355 l_api_name CONSTANT VARCHAR2(30) := 'populate_doc_questions';
356 l_module VARCHAR2(250) := G_MODULE_NAME||l_api_name;
357 
358 BEGIN
359 
360 	IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
361 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: Entering method');
362 	END IF;
363 
364 	BEGIN
365 		SELECT 'Y' INTO is_contract_expert_run FROM dual
366 		WHERE EXISTS (SELECT 1 FROM okc_xprt_doc_ques_response WHERE doc_id = p_doc_id AND doc_type = p_doc_type AND response IS NOT NULL);
367 	EXCEPTION
368 	WHEN NO_DATA_FOUND THEN
369 		NULL;
370 	END;
371 
372 	IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
373 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '110: is_contract_expert_run : ' || is_contract_expert_run);
374 	END IF;
375 
376 	IF is_contract_expert_run = 'Y' THEN
377 		OPEN c_question_and_response;
378 		FETCH c_question_and_response BULK COLLECT INTO question_ids, responses, display_flags;
379 		FORALL i IN 1 .. question_ids.count
380 			INSERT INTO okc_xprt_rule_eval_condval_t(doc_value_id, doc_id, doc_type, object_type, object_code, value_or_response, display_flag)
381 			VALUES(OKC_XPRT_RULE_EVAL_CONDVAL_S.nextval, p_doc_id, p_doc_type, 'QUESTION', question_ids(i), responses(i), display_flags(i));
382 		CLOSE c_question_and_response;
383 	ELSE
384 		OPEN c_question;
385 		FETCH c_question BULK COLLECT INTO question_ids, display_flags;
386 		FORALL i IN 1 .. question_ids.count
387 			INSERT INTO okc_xprt_rule_eval_condval_t(doc_value_id, doc_id, doc_type, object_type, object_code, value_or_response, display_flag)
388 			VALUES(OKC_XPRT_RULE_EVAL_CONDVAL_S.nextval, p_doc_id, p_doc_type, 'QUESTION', question_ids(i), null, display_flags(i));
389 		CLOSE c_question;
390 	END IF;
391 
392 	IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
393 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '120: Populated entries i.e questions and responses(if exists) in okc_xprt_rule_eval_condval_t for this document');
394 		FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '120: No. of questions populated: ' || question_ids.count);
395 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '120: Leaving method');
396 	END IF;
397 
398 EXCEPTION
399 WHEN OTHERS THEN
400 	IF (FND_LOG.LEVEL_EXCEPTION >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
401 		FND_LOG.STRING( FND_LOG.LEVEL_EXCEPTION, l_module, '130: Exception occured: ' || sqlerrm);
402 	END IF;
403 	raise;
404 END populate_doc_questions;
405 
406 PROCEDURE populate_rule_cond_dep IS
407 
408 l_api_name CONSTANT VARCHAR2(30) := 'populate_rule_cond_dep';
409 l_module VARCHAR2(250) := G_MODULE_NAME||l_api_name;
410 
411 BEGIN
412 
413 	IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
414 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: Entering method');
415 	END IF;
416 
417 	INSERT INTO okc_xprt_rule_eval_condval_t(doc_value_id, doc_id, doc_type, object_type, object_code, value_or_response, display_flag, dep_clause_cond_id)
418 	SELECT OKC_XPRT_RULE_EVAL_CONDVAL_S.nextval, p_doc_id, p_doc_type, 'RULE', rule_id, null, null, dep_clause_cond_id FROM okc_xprt_rule_dependencies_v;
419 
420 	IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
421 		FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '120: Rule_clause dependency rows populated into okc_xprt_rule_eval_condval_t table from okc_xprt_rule_dependencies_v view');
422 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '120: Leaving method');
423 	END IF;
424 
425 EXCEPTION
426 WHEN OTHERS THEN
427 	IF (FND_LOG.LEVEL_EXCEPTION >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
428 		FND_LOG.STRING( FND_LOG.LEVEL_EXCEPTION, l_module, '130: Exception occured: ' || sqlerrm);
429 	END IF;
430 	raise;
431 END populate_rule_cond_dep;
432 
433 
434 PROCEDURE evaluate_rules_and_conditions IS
435 
436 CURSOR c_rules IS
437 SELECT rule_id, rule_expr_type
438 FROM okc_xprt_rule_eval_result_t
439 WHERE doc_id = p_doc_id
440 AND doc_type = p_doc_type
441 AND condition_id IS NULL;
442 
443 CURSOR c_rule_conditions(c_rule_id NUMBER) IS
444 SELECT cond.condition_id, cond.condition_type, cond.rule_expr_type, cond.object_code, cond.object_value_type, cond.object_value_code, cond.cond_operator,
445 DECODE(cond.condition_type, 'QUESTION', (SELECT value_or_response FROM okc_xprt_rule_eval_condval_t WHERE doc_id = p_doc_id AND doc_type = p_doc_type
446 							   AND object_type = 'QUESTION' AND object_code = cond.object_code),
447 							   NULL) lhs_response,
448 DECODE(cond.object_value_type, 'QUESTION', (SELECT value_or_response FROM okc_xprt_rule_eval_condval_t WHERE doc_id = p_doc_id AND doc_type = p_doc_type
449 								    AND object_type = 'QUESTION' AND object_code = cond.object_value_code),
450 								    NULL) rhs_response
451 FROM okc_xprt_rule_eval_result_t cond
452 WHERE cond.doc_id = p_doc_id
453 AND cond.doc_type = p_doc_type
454 AND cond.condition_id IS NOT NULL
455 AND cond.rule_id = c_rule_id;
456 
457 CURSOR c_dep_rules(c_crules1 OKC_TBL_NUMBER, c_crules2 OKC_TBL_NUMBER) IS
458 SELECT distinct * FROM table(c_crules1)
459 UNION
460 SELECT distinct * FROM table(c_crules2);
461 
462 success_rule_ids OKC_TBL_NUMBER;
463 failure_rule_ids OKC_TBL_NUMBER;
464 reeval_rule_ids OKC_TBL_NUMBER;
465 clause_rules1 OKC_TBL_NUMBER;
466 clause_rules2 OKC_TBL_NUMBER;
467 
468 result_tbl result_tbl_type;
469 is_rule_evaluated VARCHAR2(1);
470 has_clauses VARCHAR2(1) := 'N';
471 l_cond_result BOOLEAN;
472 i NUMBER := 0;
473 s NUMBER := 0;
474 f NUMBER := 0;
475 rows NUMBER := 0;
476 
477 l_api_name CONSTANT VARCHAR2(30) := 'evaluate_rules_and_conditions';
478 l_module VARCHAR2(250) := G_MODULE_NAME||l_api_name;
479 
480 BEGIN
481 
482 	IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
483 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: Entering method');
484 	END IF;
485 
486 	success_rule_ids := OKC_TBL_NUMBER();
487 	failure_rule_ids := OKC_TBL_NUMBER();
488 	reeval_rule_ids := OKC_TBL_NUMBER();
489 	clause_rules1 := OKC_TBL_NUMBER();
490 	clause_rules2 := OKC_TBL_NUMBER();
491 
492 	FOR rule IN c_rules LOOP
493 		is_rule_evaluated := 'N';
494 
495 		FOR rule_cond IN c_rule_conditions(rule.rule_id) LOOP
496 
497 			l_cond_result := NULL;
498 
499 			IF (rule_cond.condition_type = 'CLAUSE' AND (rule_cond.cond_operator = 'IS_NOT' OR rule_cond.cond_operator = 'NOT_IN')) THEN
500 				l_cond_result := TRUE;
501 
502 				IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
503 					FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '110:1 rule_id : ' || rule.rule_id || ' condition_id : ' || rule_cond.condition_id);
504 				END IF;
505 			ELSIF ( (rule_cond.condition_type = 'QUESTION' AND rule_cond.lhs_response IS NULL)
506 				   OR (rule_cond.object_value_type = 'QUESTION' AND rule_cond.rhs_response IS NULL)) THEN
507 				l_cond_result := NULL;
508 
509 				IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
510 					FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '110:2 rule_id : ' || rule.rule_id || ' condition_id : ' || rule_cond.condition_id);
511 				END IF;
512 			ELSIF (rule_cond.condition_type = 'QUESTION' AND rule_cond.lhs_response IS NOT NULL) THEN
513 				l_cond_result := evaluate_condition(rule_cond.condition_id, rule_cond.condition_type, rule_cond.object_code, rule_cond.object_value_type, rule_cond.object_value_code, rule_cond.cond_operator);
514 
515 				IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
516 					FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '110:3 rule_id : ' || rule.rule_id || ' condition_id : ' || rule_cond.condition_id);
517 				END IF;
518 			ELSIF (rule_cond.condition_type = 'VARIABLE') THEN
519 				l_cond_result := evaluate_condition(rule_cond.condition_id, rule_cond.condition_type, rule_cond.object_code, rule_cond.object_value_type, rule_cond.object_value_code, rule_cond.cond_operator);
520 
521 				IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
522 					FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '110:4 rule_id : ' || rule.rule_id || ' condition_id : ' || rule_cond.condition_id);
523 				END IF;
524 			ELSE
525 				IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
526 					FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '110:5 rule_id : ' || rule.rule_id || ' condition_id : ' || rule_cond.condition_id);
527 				END IF;
528 			END IF;
529 
530 			IF l_cond_result THEN
531 				IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
532 					FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '110: l_cond_result : TRUE');
533 				END IF;
534 
535 				i := i + 1;
536 				result_tbl(i).rule_id := rule.rule_id;
537 				result_tbl(i).condition_id := rule_cond.condition_id;
538 				result_tbl(i).result := 'Y';
539 
540 				IF rule.rule_expr_type = 'ANY' THEN
541 					i := i + 1;
542 					result_tbl(i).rule_id := rule.rule_id;
543 					result_tbl(i).condition_id := null;
544 					result_tbl(i).result := 'Y';
545 					is_rule_evaluated := 'Y';
546 					success_rule_ids.extend(1);
547 					s := s + 1;
548 					success_rule_ids(s) := rule.rule_id;
549 					EXIT;
550 				END IF;
551 			ELSIF l_cond_result IS NULL THEN
552 				IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
553 					FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '110: l_cond_result : NULL');
554 				END IF;
555 
556 				is_rule_evaluated := 'L';   -- atleast one of the rule condition cannot be evaluated now.
557 			ELSE
558 				-- if the condition result is false
559 				IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
560 					FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '110: l_cond_result : FALSE');
561 				END IF;
562 
563 				i := i + 1;
564 				result_tbl(i).rule_id := rule.rule_id;
565 				result_tbl(i).condition_id :=  rule_cond.condition_id;
566 				result_tbl(i).result := 'N';
567 
568 				IF rule.rule_expr_type = 'ALL' THEN
569 					i := i + 1;
570 					result_tbl(i).rule_id := rule.rule_id;
571 					result_tbl(i).condition_id := null;
572 					result_tbl(i).result := 'N';
573 					is_rule_evaluated := 'Y';
574 					failure_rule_ids.extend(1);
575 					f := f + 1;
576 					failure_rule_ids(f) := rule.rule_id;
577 					EXIT;
578 				END IF;
579 			END IF;
580 
581 		END LOOP;
582 
583 		IF is_rule_evaluated = 'N' AND rule.rule_expr_type = 'ANY' THEN  --all the condition results are false for this rule
584 			i := i + 1;
585 			result_tbl(i).rule_id := rule.rule_id;
586 			result_tbl(i).condition_id := null;
587 			result_tbl(i).result := 'N';
588 			failure_rule_ids.extend(1);
589 			f := f + 1;
590 			failure_rule_ids(f) := rule.rule_id;
591 		END IF;
592 
593 		IF is_rule_evaluated = 'N' AND rule.rule_expr_type = 'ALL' THEN --all the condition results are success for this rule.
594 			i := i + 1;
595 			result_tbl(i).rule_id := rule.rule_id;
596 			result_tbl(i).condition_id := null;
597 			result_tbl(i).result := 'Y';
598 			success_rule_ids.extend(1);
599 			s := s + 1;
600 			success_rule_ids(s) := rule.rule_id;
601 		END IF;
602 	END LOOP;
603 
604 	IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
605 		FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '120: result_tbl.count: ' || result_tbl.count);
606 		FOR a IN 1 .. result_tbl.count LOOP
607 		FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '120: result_tbl rule_id: ' || result_tbl(a).rule_id || ' condition_id: ' || result_tbl(a).condition_id || ' result: ' || result_tbl(a).result); END LOOP;
608 
609 		FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '130: success_rule_ids.count: ' || success_rule_ids.count);
610 		FOR a IN 1 .. success_rule_ids.count LOOP
611 		FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '130: success_rule_id: ' || success_rule_ids(a)); END LOOP;
612 
613 		FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '140: failure_rule_ids.count: ' || failure_rule_ids.count);
614 		FOR a IN 1 .. failure_rule_ids.count LOOP
615 		FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '140: failure_rule_id: ' || failure_rule_ids(a)); END LOOP;
616 	END IF;
617 
618     	FORALL k IN 1 .. result_tbl.count
619       	UPDATE okc_xprt_rule_eval_result_t result_tmp
620       	SET result = result_tbl(k).result
621       	WHERE result_tmp.rule_id = result_tbl(k).rule_id
622      	AND nvl(result_tmp.condition_id, -999) = nvl(result_tbl(k).condition_id, -999)
623       	AND result_tmp.doc_id = p_doc_id
624       	AND result_tmp.doc_type = p_doc_type;
625 
626   	BEGIN
627     		SELECT 'Y' INTO has_clauses FROM dual
628     		WHERE EXISTS (SELECT 1 FROM okc_xprt_rule_eval_result_t WHERE doc_id = p_doc_id AND doc_type = p_doc_type AND condition_type = 'CLAUSE');
629  	EXCEPTION
630     		WHEN NO_DATA_FOUND THEN
631   	NULL;
632   	END;
633 
634 	IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
635 		FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '150: has_clauses: ' || has_clauses);
636 	END IF;
637 
638 	--Step I: Additional Questions handling:
639 	--Updating the display_flag to 'Y' if the rule_id has any additional questions
640 	--For the first run, update of display_flag to 'N' for failure_rule_ids is not needed, as all additional question are marked as 'N' by default
641 	IF success_rule_ids.count > 0 THEN
642 		UPDATE okc_xprt_rule_eval_condval_t
643 		SET display_flag = 'Y'
644 		WHERE doc_id = p_doc_id
645 		AND doc_type = p_doc_type
646 		AND object_type = 'QUESTION'
647 		AND display_flag <> 'Y'
648 		AND object_code IN (SELECT object_value_id FROM okc_xprt_rule_outcomes_act_v WHERE rule_id IN (SELECT * FROM table(success_rule_ids)) and object_type = 'QUESTION');
649 		rows := sql%rowcount;
650 		IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
651 			FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '160: No. of questions updated with display_flag = Y: ' || rows);
652 		END IF;
653 	END IF;
654 
655 	--Step II: Dependent Clause based conditions handling:
656 	IF has_clauses = 'Y' THEN
657 		IF success_rule_ids.count > 0 THEN
658 			UPDATE okc_xprt_rule_eval_result_t cond
659 			SET result = decode(cond_operator, 'IS', 'Y', 'IN', 'Y', 'N')
660 			WHERE doc_id = p_doc_id
661 			AND doc_type = p_doc_type
662 			AND condition_type = 'CLAUSE'
663 			AND ((cond_operator IN ('IS', 'IN') and nvl(result, '*') <> 'Y') OR (cond_operator IN ('IS_NOT', 'NOT_IN') and nvl(result, '*') = 'Y')) --to avoid non-updatable statements
664 			AND condition_id IN (SELECT distinct dep_clause_cond_id FROM okc_xprt_rule_eval_condval_t WHERE doc_id = cond.doc_id and doc_type = cond.doc_type
665 					     and object_type = 'RULE' and object_code IN (SELECT * FROM table(success_rule_ids)))
666 			RETURNING rule_id BULK COLLECT INTO clause_rules1;
667 
668 			IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
669 				FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '170: No. of clause based conditions updated with result: ' || clause_rules1.count);
670 
671 				FOR a IN 1 .. clause_rules1.count LOOP
672 				FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '170: clause_rules1 rule_id: ' || clause_rules1(a));	END LOOP;
673 			END IF;
674 		END IF;
675 
676 		IF failure_rule_ids.count > 0 THEN
677 			UPDATE okc_xprt_rule_eval_result_t cond
678 			SET cond.result = 'N'
679 			WHERE cond.doc_id = p_doc_id
680 			AND cond.doc_type = p_doc_type
681 			AND condition_type = 'CLAUSE'
682 			AND cond.cond_operator IN ('IS', 'IN') --as the condition result wont change in other cases
683 			AND cond.result IS NULL --if the result is Y, then it wont change and the result will not be N in any case
684 			AND cond.condition_id IN (SELECT distinct dep_clause_cond_id FROM okc_xprt_rule_eval_condval_t WHERE doc_id = cond.doc_id and doc_type = cond.doc_type
685 						  and object_type = 'RULE' and object_code IN (SELECT * FROM table(failure_rule_ids)))
686 			AND NOT EXISTS (SELECT 1 FROM okc_xprt_rule_eval_result_t t, okc_xprt_rule_eval_condval_t d WHERE d.doc_id = cond.doc_id AND d.doc_type = cond.doc_type
687 					AND d.object_type = 'RULE' AND d.dep_clause_cond_id = cond.condition_id
688 					AND t.doc_id = d.doc_id AND t.doc_type = d.doc_type AND t.condition_id IS NULL
689 					AND t.result IS NULL AND d.object_code = t.rule_id)
690 			RETURNING cond.rule_id BULK COLLECT INTO clause_rules2;
691 
692 			IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
693 				FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '180: No. of clause based conditions updated with result: ' || clause_rules2.count);
694 
695 				FOR a IN 1 .. clause_rules2.count LOOP
696 				FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '180: clause_rules2 rule_id: ' || clause_rules2(a));	END LOOP;
697 			END IF;
698 		END IF;
699 
700 		--Step III: Finding dependent rules for all the above changes and reevaluating them
701 		IF clause_rules1.count > 0 OR clause_rules2.count > 0 THEN
702 			OPEN c_dep_rules(clause_rules1, clause_rules2);
703 			FETCH c_dep_rules BULK COLLECT INTO reeval_rule_ids;
704 			CLOSE c_dep_rules;
705 
706 			IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
707 				FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '190: reeval_rule_ids.count: ' || reeval_rule_ids.count);
708 
709 				FOR a IN 1 .. reeval_rule_ids.count LOOP
710 				FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '190: reeval_rule_ids rule_id: ' || reeval_rule_ids(a)); END LOOP;
711 			END IF;
712 		END IF;
713 	END IF;
714 
715   	IF reeval_rule_ids.count > 0 THEN
716   		reevaluate_rules(reeval_rule_ids);
717   	END IF;
718 
719 	IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
720 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '200: Leaving method');
721 	END IF;
722 
723 EXCEPTION
724 WHEN OTHERS THEN
725 	IF (FND_LOG.LEVEL_EXCEPTION >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
726 		FND_LOG.STRING( FND_LOG.LEVEL_EXCEPTION, l_module, '210: Exception occured: ' || sqlerrm);
727 	END IF;
728 	raise;
729 END evaluate_rules_and_conditions;
730 
731 
732 FUNCTION op_is RETURN BOOLEAN IS
733 BEGIN
734 
735 IF lhs_values_tbl.Count > 0 AND rhs_values_tbl.Count > 0 THEN
736   FOR k IN lhs_values_tbl.FIRST..lhs_values_tbl.LAST LOOP
737     FOR m IN rhs_values_tbl.FIRST..rhs_values_tbl.LAST LOOP
738       IF lhs_values_tbl(k) = rhs_values_tbl(m) THEN
739         RETURN TRUE;
740       END IF;
741     END LOOP;
742   END LOOP;
743 END IF;
744   RETURN FALSE;
745 END op_is;
746 
747 FUNCTION op_in RETURN  BOOLEAN IS
748 BEGIN
749 IF lhs_values_tbl.Count > 0 AND rhs_values_tbl.Count > 0 THEN
750   FOR k IN lhs_values_tbl.FIRST..lhs_values_tbl.LAST LOOP
751     FOR m IN rhs_values_tbl.FIRST..rhs_values_tbl.LAST LOOP
752       IF lhs_values_tbl(k) = rhs_values_tbl(m) THEN
753         RETURN TRUE;
754       END IF;
755     END LOOP;
756   END LOOP;
757 END IF;
758   RETURN FALSE;
759 END op_in;
760 
761 FUNCTION op_is_not return BOOLEAN IS
762 BEGIN
763 IF lhs_values_tbl.Count > 0 AND rhs_values_tbl.Count > 0 THEN
764   FOR k IN lhs_values_tbl.FIRST..lhs_values_tbl.LAST LOOP
765     FOR m IN rhs_values_tbl.FIRST..rhs_values_tbl.LAST LOOP
766       IF lhs_values_tbl(k) = rhs_values_tbl(m) THEN
767         RETURN FALSE;
768       END IF;
769     END LOOP;
770   END LOOP;
771 END IF;
772   RETURN TRUE;
773 END op_is_not;
774 
775 FUNCTION op_not_in return BOOLEAN IS
776 BEGIN
777 IF lhs_values_tbl.Count > 0 AND rhs_values_tbl.Count > 0 THEN
778   FOR k IN lhs_values_tbl.FIRST..lhs_values_tbl.LAST LOOP
779     FOR m IN rhs_values_tbl.FIRST..rhs_values_tbl.LAST LOOP
780       IF lhs_values_tbl(k) = rhs_values_tbl(m) THEN
781         RETURN FALSE;
782       END IF;
783     END LOOP;
784   END LOOP;
785 END IF;
786   RETURN TRUE;
787 END op_not_in;
788 
789 FUNCTION op_numeric(op VARCHAR2) return BOOLEAN IS
790 BEGIN
791 IF op = '<' THEN
792 IF lhs_values_tbl.Count > 0 AND rhs_values_tbl.Count > 0 THEN
793   FOR k IN lhs_values_tbl.FIRST..lhs_values_tbl.LAST LOOP
794     FOR m IN rhs_values_tbl.FIRST..rhs_values_tbl.LAST LOOP
795       IF lhs_values_tbl(k) < rhs_values_tbl(m) THEN
796       RETURN TRUE;
797       END IF;
798     END LOOP;
799   END LOOP;
800 END IF;
801 ELSIF op = '>' THEN
802 IF lhs_values_tbl.Count > 0 AND rhs_values_tbl.Count > 0 THEN
803   FOR k IN lhs_values_tbl.FIRST..lhs_values_tbl.LAST LOOP
804     FOR m IN rhs_values_tbl.FIRST..rhs_values_tbl.LAST LOOP
805       IF lhs_values_tbl(k) > rhs_values_tbl(m) THEN
806       	RETURN TRUE;
807       END IF;
808     END LOOP;
809   END LOOP;
810 END IF;
811 ELSIF op = '>=' THEN
812 IF lhs_values_tbl.Count > 0 AND rhs_values_tbl.Count > 0 THEN
813   FOR k IN lhs_values_tbl.FIRST..lhs_values_tbl.LAST LOOP
814     FOR m IN rhs_values_tbl.FIRST..rhs_values_tbl.LAST LOOP
815       IF lhs_values_tbl(k) >= rhs_values_tbl(m) THEN
816       	RETURN TRUE;
817       END IF;
818     END LOOP;
819   END LOOP;
820 END IF;
821 ELSIF op = '<=' THEN
822 IF lhs_values_tbl.Count > 0 AND rhs_values_tbl.Count > 0 THEN
823   FOR k IN lhs_values_tbl.FIRST..lhs_values_tbl.LAST LOOP
824     FOR m IN rhs_values_tbl.FIRST..rhs_values_tbl.LAST LOOP
825       IF lhs_values_tbl(k) <= rhs_values_tbl(m) THEN
826      	RETURN TRUE;
827       END IF;
828     END LOOP;
829   END LOOP;
830 END IF;
831 
832 END IF;
833 RETURN FALSE;
834 END op_numeric;
835 
836 FUNCTION evaluate_condition(p_cond_id NUMBER, p_cond_type VARCHAR2, p_object_code VARCHAR2, p_object_value_type VARCHAR2, p_object_value_code VARCHAR2, p_operator VARCHAR2) RETURN BOOLEAN IS
837 
838 CURSOR c_lhsvalues IS
839 SELECT value_or_response
840 FROM okc_xprt_rule_eval_condval_t
841 WHERE doc_id = p_doc_id
842 AND doc_type = p_doc_type
843 AND object_code = p_object_code
844 AND object_type = p_cond_type;
845 
846 -- FOR object_value_type of 'QUESTION', 'CONSTANT', 'VARIABLE'
847 CURSOR c_rhsvalues IS
848 SELECT value_or_response
849 FROM okc_xprt_rule_eval_condval_t
850 WHERE doc_id = p_doc_id
851 AND doc_type = p_doc_type
852 AND object_code = p_object_value_code
853 AND object_type = p_object_value_type;
854 
855 --FOR object_value_type of 'VALUE'
856 CURSOR c_rhsvalues_stored IS
857 SELECT object_value_code
858 FROM okc_xprt_rule_cond_vals_act_v
859 WHERE rule_condition_id = p_cond_id;
860 
861 l_op_result BOOLEAN := FALSE;
862 
863 l_api_name CONSTANT VARCHAR2(30) := 'evaluate_condition';
864 l_module VARCHAR2(250) := G_MODULE_NAME||l_api_name;
865 
866 BEGIN
867 
868 	IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
869 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: Entering method');
870 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: p_cond_id : ' || p_cond_id);
871 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: p_cond_type : ' || p_cond_type);
872      		FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: p_object_code : ' || p_object_code);
873      		FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: p_object_value_type : ' || p_object_value_type);
874      		FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: p_object_value_code : ' || p_object_value_code);
875      		FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: p_operator : ' || p_operator);
876 	END IF;
877 
878 	OPEN c_lhsvalues;
879 	FETCH c_lhsvalues BULK COLLECT INTO lhs_values_tbl;
880 	CLOSE c_lhsvalues;
881 
882 	IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
883 		FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '110: No. of lhs values: ' || lhs_values_tbl.count);
884 
885 		FOR a IN 1 .. lhs_values_tbl.count LOOP
886 		FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '110: lhs value: ' || lhs_values_tbl(a)); END LOOP;
887 	END IF;
888 
889   	IF p_object_value_type = 'VALUE' THEN
890     		OPEN c_rhsvalues_stored;
891     		FETCH c_rhsvalues_stored BULK COLLECT INTO rhs_values_tbl;
892     		CLOSE c_rhsvalues_stored;
893   	ELSE
894     		OPEN c_rhsvalues;
895     		FETCH c_rhsvalues BULK COLLECT INTO rhs_values_tbl;
896     		CLOSE c_rhsvalues;
897  	END IF;
898 
899 	IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
900 		FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '120: No. of rhs values: ' || rhs_values_tbl.count);
901 
902 		FOR a IN 1 .. rhs_values_tbl.count LOOP
903 		FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '120: rhs value: ' || rhs_values_tbl(a)); END LOOP;
904 	END IF;
905 
906 	IF p_operator = 'IS' THEN l_op_result := op_is();
907 	ELSIF p_operator = 'IS_NOT' THEN l_op_result := op_is_not();
908 	ELSIF p_operator = 'IN' THEN l_op_result := op_in();
909 	ELSIF p_operator = 'NOT_IN' THEN l_op_result := op_not_in();
910 	ELSIF p_operator IN ('=') THEN l_op_result := op_is();
911 	ELSIF p_operator IN ('<>') THEN l_op_result := op_is_not();
912 	ELSIF p_operator IN ('<=','>=','<','>') THEN l_op_result := op_numeric(p_operator);
913 	END IF;
914 
915 	IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
916 		IF l_op_result THEN
917 			FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '130: l_op_result: TRUE');
918 		ELSE
919 			FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '130: l_op_result: FALSE');
920 		END IF;
921 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '130: Leaving method');
922 	END IF;
923 
924 	RETURN l_op_result;
925 
926 EXCEPTION
927 WHEN OTHERS THEN
928 	IF (FND_LOG.LEVEL_EXCEPTION >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
929 		FND_LOG.STRING( FND_LOG.LEVEL_EXCEPTION, l_module, '140: Exception occured: ' || sqlerrm);
930 	END IF;
931 	raise;
932 END evaluate_condition;
933 
934 
935 PROCEDURE reevaluate_rules(reeval_rules OKC_TBL_NUMBER) IS
936 
937 CURSOR c_dep_rules(c_crules1 OKC_TBL_NUMBER, c_crules2 OKC_TBL_NUMBER, c_crules3 OKC_TBL_NUMBER, c_qrules OKC_TBL_NUMBER) IS
938 SELECT distinct * FROM table(c_qrules)
939 UNION
940 SELECT distinct * FROM table(c_crules1)
941 UNION
942 SELECT distinct * FROM table(c_crules2)
943 UNION
944 SELECT distinct * FROM table(c_crules3);
945 
946 new_reevalrule_ids OKC_TBL_NUMBER;
947 rule_ids1 OKC_TBL_NUMBER;
948 rule_ids2 OKC_TBL_NUMBER;
949 rule_ids3 OKC_TBL_NUMBER;
950 clause_rules1 OKC_TBL_NUMBER;
951 clause_rules2 OKC_TBL_NUMBER;
952 clause_rules3 OKC_TBL_NUMBER;
953 ques_rules OKC_TBL_NUMBER;
954 question_ids OKC_TBL_NUMBER;
955 has_clauses VARCHAR2(1) := 'N';
956 rows1 NUMBER := 0;
957 rows2 NUMBER := 0;
958 no_of_questions NUMBER := 0;
959 
960 i NUMBER := 1;
961 n NUMBER := 1;
962 k NUMBER := 1;
963 l NUMBER := 1;
964 
965 l_api_name CONSTANT VARCHAR2(30) := 'reevaluate_rules';
966 l_module VARCHAR2(250) := G_MODULE_NAME||l_api_name;
967 
968 BEGIN
969 
970 	IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
971 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: Entering method');
972 		FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '110: No. of reeval_rules rule_ids: ' || reeval_rules.count);
973 
974 		FOR a IN 1 .. reeval_rules.count LOOP
975 		FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '110: reeval_rules rule_id: ' || reeval_rules(a)); END LOOP;
976 	END IF;
977 
978 	rule_ids1 := OKC_TBL_NUMBER();
979 	rule_ids2 := OKC_TBL_NUMBER();
980 	rule_ids3 := OKC_TBL_NUMBER();
981 	clause_rules1 := OKC_TBL_NUMBER();
982 	clause_rules2 := OKC_TBL_NUMBER();
983 	clause_rules3 := OKC_TBL_NUMBER();
984 	ques_rules := OKC_TBL_NUMBER();
985 	question_ids := OKC_TBL_NUMBER();
986 	new_reevalrule_ids := OKC_TBL_NUMBER();
987 	rule_ids1.extend(reeval_rules.count);
988 	rule_ids2.extend(reeval_rules.count);
989 	rule_ids3.extend(reeval_rules.count);
990 
991 	FOR j IN 1 .. reeval_rules.count LOOP
992 		UPDATE okc_xprt_rule_eval_result_t result_tmp
993 		SET result = 'Y'
994 		WHERE result_tmp.rule_id = reeval_rules(j)
995 		AND result_tmp.condition_id IS NULL
996 		AND result_tmp.doc_id = p_doc_id
997 		AND result_tmp.doc_type = p_doc_type
998       		AND nvl(result_tmp.result, '*') <> 'Y'
999 		AND ((result_tmp.rule_expr_type = 'ALL' AND NOT EXISTS (SELECT 1 FROM okc_xprt_rule_eval_result_t WHERE nvl(result, '*') <> 'Y'
1000 								      AND rule_id = reeval_rules(j) AND condition_id IS NOT NULL
1001 								      AND doc_id = p_doc_id AND doc_type = p_doc_type AND rownum = 1))
1002 		     OR (result_tmp.rule_expr_type = 'ANY' AND EXISTS (SELECT 1 FROM okc_xprt_rule_eval_result_t WHERE nvl(result, '*') = 'Y'
1003 								      AND rule_id = reeval_rules(j) AND condition_id IS NOT NULL
1004 								      AND doc_id = p_doc_id AND doc_type = p_doc_type AND rownum = 1)))
1005       		RETURNING n + 1, result_tmp.rule_id INTO n, rule_ids1(n);
1006 		IF SQL%FOUND THEN
1007 			IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1008 				FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '120: No. of rules updated with result = Y based on condition evaluation: ' || (n-1));
1009 
1010 				FOR a IN 1 .. rule_ids1.count LOOP
1011 				FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '120: rule_ids1 rule_id: ' || rule_ids1(a)); END LOOP;
1012 			END IF;
1013 			continue;
1014 		END IF;
1015 
1016 
1017 		UPDATE okc_xprt_rule_eval_result_t result_tmp
1018 		SET result = decode(result_tmp.rule_expr_type, 'ANY', (SELECT result FROM (SELECT result FROM okc_xprt_rule_eval_result_t
1019 								      WHERE rule_id = reeval_rules(j) AND condition_id IS NOT NULL
1020 								      AND doc_id = p_doc_id AND doc_type = p_doc_type ORDER BY
1021 								      decode(result, NULL, 1, 2)) WHERE rownum = 1),
1022 							       'ALL', (SELECT result FROM (SELECT result FROM okc_xprt_rule_eval_result_t
1023 								      WHERE rule_id = reeval_rules(j) AND condition_id IS NOT NULL
1024 								      AND doc_id = p_doc_id AND doc_type = p_doc_type ORDER BY
1025 								      decode(result, 'N', 1, NULL, 2, 3)) WHERE rownum = 1))
1026 		WHERE result_tmp.rule_id = reeval_rules(j)
1027       		AND result_tmp.condition_id IS NULL
1028 		AND result_tmp.doc_id = p_doc_id
1029 		AND result_tmp.doc_type = p_doc_type
1030       		AND nvl(result_tmp.result, '*') = 'Y'
1031 		AND ((result_tmp.rule_expr_type = 'ALL' AND EXISTS (SELECT 1 FROM okc_xprt_rule_eval_result_t WHERE nvl(result, '*') <> 'Y'
1032 								   AND rule_id = reeval_rules(j) AND condition_id IS NOT NULL
1033 								   AND doc_id = p_doc_id AND doc_type = p_doc_type AND rownum = 1))
1034 		     OR (result_tmp.rule_expr_type = 'ANY' AND NOT EXISTS (SELECT 1 FROM okc_xprt_rule_eval_result_t WHERE nvl(result, '*') = 'Y'
1035 								      AND rule_id = reeval_rules(j) AND condition_id IS NOT NULL
1036 								      AND doc_id = p_doc_id AND doc_type = p_doc_type AND rownum = 1)))
1037       		RETURNING k + 1, result_tmp.rule_id INTO k, rule_ids2(k);
1038 		IF SQL%FOUND THEN
1039 			IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1040 				FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '130: No. of rules updated with result based on condition evaluation: ' || (k-1));
1041 
1042 				FOR a IN 1 .. rule_ids2.count LOOP
1043 				FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '130: rule_ids2 rule_id: ' || rule_ids2(a)); END LOOP;
1044 			END IF;
1045 			continue;
1046 		END IF;
1047 
1048 		--there is not need to consider nul to success and failure to success case as they will be already handled in first update statement
1049 		UPDATE okc_xprt_rule_eval_result_t result_tmp
1050 		SET result = decode(result_tmp.rule_expr_type, 'ANY', (SELECT result FROM (SELECT result FROM okc_xprt_rule_eval_result_t
1051 								      WHERE rule_id = reeval_rules(j) AND condition_id IS NOT NULL
1052 								      AND doc_id = p_doc_id AND doc_type = p_doc_type ORDER BY
1053 								      decode(result, NULL, 1, 2)) WHERE rownum = 1),
1054 							       'ALL', (SELECT result FROM (SELECT result FROM okc_xprt_rule_eval_result_t
1055 								      WHERE rule_id = reeval_rules(j) AND condition_id IS NOT NULL
1056 								      AND doc_id = p_doc_id AND doc_type = p_doc_type ORDER BY
1057 								      decode(result, 'N', 1, NULL, 2, 3)) WHERE rownum = 1))
1058 		WHERE result_tmp.rule_id = reeval_rules(j)
1059       		AND result_tmp.condition_id IS NULL
1060 		AND result_tmp.doc_id = p_doc_id
1061 		AND result_tmp.doc_type = p_doc_type
1062      		AND nvl(result_tmp.result, '*') <> 'Y'
1063 		AND ((result_tmp.rule_expr_type = 'ALL' AND result_tmp.result IS NULL AND EXISTS (SELECT 1 FROM okc_xprt_rule_eval_result_t WHERE nvl(result, '*') = 'N'
1064 												AND rule_id = reeval_rules(j) AND condition_id IS NOT NULL
1065 												AND doc_id = p_doc_id AND doc_type = p_doc_type AND rownum = 1))
1066 		     OR (result_tmp.rule_expr_type = 'ALL' AND nvl(result_tmp.result, '*') = 'N' AND NOT EXISTS (SELECT 1 FROM okc_xprt_rule_eval_result_t WHERE nvl(result, '*') = 'N'
1067 												AND rule_id = reeval_rules(j) AND condition_id IS NOT NULL
1068 												AND doc_id = p_doc_id AND doc_type = p_doc_type AND rownum = 1))
1069 		     OR (result_tmp.rule_expr_type = 'ANY' AND result_tmp.result IS NULL AND NOT EXISTS (SELECT 1 FROM okc_xprt_rule_eval_result_t WHERE nvl(result, '*') IS NULL
1070 												AND rule_id = reeval_rules(j) AND condition_id IS NOT NULL
1071 												AND doc_id = p_doc_id AND doc_type = p_doc_type AND rownum = 1))
1072 		     OR (result_tmp.rule_expr_type = 'ANY' AND nvl(result_tmp.result, '*') = 'N' AND EXISTS (SELECT 1 FROM okc_xprt_rule_eval_result_t WHERE nvl(result, '*') <> 'N'
1073 												AND rule_id = reeval_rules(j) AND condition_id IS NOT NULL
1074 												AND doc_id = p_doc_id AND doc_type = p_doc_type AND rownum = 1)))
1075       		RETURNING l + 1, result_tmp.rule_id INTO l, rule_ids3(l);
1076 		IF SQL%FOUND THEN
1077 			IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1078 				FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '140: No. of rules updated with result based on condition evaluation: ' || (l-1));
1079 
1080 				FOR a IN 1 .. rule_ids3.count LOOP
1081 				FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '140: rule_ids3 rule_id: ' || rule_ids3(a)); END LOOP;
1082 			END IF;
1083 			continue;
1084 		END IF;
1085 	END LOOP;
1086 
1087 	rule_ids1.trim(reeval_rules.count - (n - 1));
1088 	rule_ids2.trim(reeval_rules.count - (k - 1));
1089 	rule_ids3.trim(reeval_rules.count - (l - 1));
1090 
1091   	BEGIN
1092     		SELECT 'Y' INTO has_clauses FROM dual
1093     		WHERE EXISTS (SELECT 1 FROM okc_xprt_rule_eval_result_t WHERE doc_id = p_doc_id AND doc_type = p_doc_type AND condition_type = 'CLAUSE');
1094   	EXCEPTION
1095     		WHEN NO_DATA_FOUND THEN
1096   		NULL;
1097   	END;
1098 
1099 	IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1100 		FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '150: has_clauses: ' || has_clauses);
1101 	END IF;
1102 
1103 ---------------------------------------------------------------------------------------------------------------------------------------------------
1104 	--Step I: Additional Questions handling:
1105 	--Updating the display_flag to 'Y' if the rule_id has any additional questions
1106 
1107 	--A) rule_ids1--- which have changed their result from null to Y or N to Y
1108 	--updated additional questions display flag to Y if not updated already
1109 	--reevaluation of rule_ids1 is not needed..
1110 	IF rule_ids1.count > 0 THEN
1111 		UPDATE okc_xprt_rule_eval_condval_t
1112 		SET display_flag = 'Y'
1113 		WHERE doc_id = p_doc_id
1114 		AND doc_type = p_doc_type
1115 		AND object_type = 'QUESTION'
1116 		AND display_flag <> 'Y'   --it won't update if it is already Y, so that the rows1 count will not be included if there is no updation
1117 		AND object_code IN (SELECT object_value_id FROM okc_xprt_rule_outcomes_act_v WHERE rule_id IN (SELECT * FROM table(rule_ids1)) and object_type = 'QUESTION');
1118 		rows1 := sql%rowcount;
1119 
1120 		IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1121 			FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '160: No. of additional questions which are getting displayed based on the new rules that are evaluated: ' || rows1);
1122 		END IF;
1123 	END IF;
1124 
1125 
1126 	--B) rule_ids2--- which have changed their result from Y to N or Y to null
1127 	--updated additional questions display flag to N, if and only if all the the rules with outcome as this question doesnt have their as Y
1128 	--reevaluation of rule_ids2 is needed.. i.e the reason we collect the rule_ids to ques_rules for re-evalaution.
1129 	IF rule_ids2.count > 0 THEN
1130 
1131 		FORALL i IN 1 .. rule_ids2.count
1132 			UPDATE okc_xprt_rule_eval_condval_t ques
1133 			SET ques.display_flag = 'N'
1134 			WHERE ques.doc_id = p_doc_id
1135 			AND ques.doc_type = p_doc_type
1136 			AND ques.object_type = 'QUESTION'
1137 			AND ques.display_flag <> 'N'
1138 			AND ques.object_code IN (SELECT object_value_id FROM okc_xprt_rule_outcomes_act_v WHERE rule_id = rule_ids2(i) and object_type = 'QUESTION')
1139 			AND NOT EXISTS (SELECT 1 FROM okc_xprt_rule_outcomes_act_v d, okc_xprt_rule_eval_result_t t
1140 					WHERE d.rule_id = t.rule_id AND t.doc_id = ques.doc_id AND t.doc_type = ques.doc_type AND nvl(t.result, '*') = 'Y' AND t.condition_id IS NULL
1141 					AND to_char(d.object_value_id) = ques.object_code AND d.object_type = 'QUESTION');
1142 			IF SQL%FOUND AND rule_ids2.count > 0 THEN
1143 				rows2 := sql%rowcount;
1144 				IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1145 					FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '170: No. of additional questions which will getting displayed from the UI based on the new rules that are evaluated: ' || rows2);
1146 				END IF;
1147 			END IF;
1148 
1149 
1150 		--updated additional questions response to null, if and only if all the the rules with outcome as this question doesnt have their as Y..
1151 		--if response is made to null from any value then only we need to re-evaluate the rule status that is the reason seperation of updating the
1152 		-- response and display_flag is needed.
1153 		FORALL i IN 1 .. rule_ids2.count
1154 			UPDATE okc_xprt_rule_eval_condval_t ques
1155 			SET ques.value_or_response = NULL
1156 			WHERE ques.doc_id = p_doc_id
1157 			AND ques.doc_type = p_doc_type
1158 			AND ques.object_type = 'QUESTION'
1159 			AND ques.value_or_response IS NOT NULL   --it won't update if it is already NULL, so that re-evaluation of rules for additional questions take place only when it is an actual update
1160 			AND ques.object_code IN (SELECT object_value_id FROM okc_xprt_rule_outcomes_act_v WHERE rule_id = rule_ids2(i) and object_type = 'QUESTION')
1161 			AND NOT EXISTS (SELECT 1 FROM okc_xprt_rule_outcomes_act_v d, okc_xprt_rule_eval_result_t t
1162 					WHERE d.rule_id = t.rule_id AND t.doc_id = ques.doc_id AND t.doc_type = ques.doc_type AND nvl(t.result, '*') = 'Y' AND t.condition_id IS NULL
1163 					AND to_char(d.object_value_id) = ques.object_code AND d.object_type = 'QUESTION')
1164 			RETURNING ques.object_code BULK COLLECT INTO question_ids;
1165 
1166 			IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1167 				FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '180: No. of additional questions which are updated the result to Y based on the new rules that are evaluated: ' || question_ids.count);
1168 
1169 				FOR a IN 1 .. question_ids.count LOOP
1170 				FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '180: question_ids question_id: ' || question_ids(a)); END LOOP;
1171 			END IF;
1172 
1173 		--updating the result of all the conditions to null which contains this additional question
1174 		--question_ids will have unique question ids
1175 		--question_rules can have duplicate rule_ids as it can have two questions updated to result Null so it comes twice in the question_rules
1176 		IF question_ids.count > 0 THEN
1177 			UPDATE okc_xprt_rule_eval_result_t
1178 			SET result = NULL
1179 			WHERE object_code IN (SELECT * FROM table(question_ids))
1180 			AND doc_id = p_doc_id
1181 			AND doc_type = p_doc_type
1182 			AND condition_type = 'QUESTION'
1183 			RETURNING rule_id BULK COLLECT INTO ques_rules;
1184 
1185 			IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1186 				FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '190: No. of question based conditions rule_ids which are updated the result to null as the resposne is made to null: ' || ques_rules.count);
1187 
1188 				FOR a IN 1 .. ques_rules.count LOOP
1189 				FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '190: ques_rules rule_id: ' || ques_rules(a)); END LOOP;
1190 			END IF;
1191 		END IF;
1192 	END IF;
1193 
1194 	--C) rule_ids3--- which have changed their result from null to N or N to null
1195 	--updation of  additional questions display flag is not required
1196 	--reevaluation of rule_ids3 is not needed..
1197 	IF rows1 > 0 OR rows2 > 0 THEN
1198 		questions_display_changed := 'Y';
1199 	END IF;
1200 
1201 	IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1202 		FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '200: questions_display_changed: ' || questions_display_changed);
1203 	END IF;
1204 
1205 ---------------------------------------------------------------------------------------------------------------------------------------------------
1206 	--Step II: Dependent Clause based conditions evaluation:
1207 	--Updating the result of dependent clause based conditions
1208 
1209 	--A) rule_ids1--- which have changed their result from null to Y or N to Y
1210 	--updated dependent clause questions display flag to Y if op IN (IS IN) OR N if op IN (IS_NOT NOT_IN)
1211 
1212 	IF has_clauses = 'Y' THEN
1213 
1214 		--A) rule_ids1--- which have changed their result from null to Y or N to Y
1215 		--updated dependent clause conditions result to Y if op IN (IS,IN) OR N if op IN (IS_NOT,NOT_IN)
1216 
1217 		IF rule_ids1.count > 0 THEN
1218 			UPDATE okc_xprt_rule_eval_result_t cond
1219 			SET result = decode(cond_operator, 'IS', 'Y', 'IN', 'Y', 'N')
1220 			WHERE doc_id = p_doc_id
1221 			AND doc_type = p_doc_type
1222 			AND condition_type = 'CLAUSE'
1223 			AND ((cond_operator IN ('IS', 'IN') and nvl(result, '*') <> 'Y') OR (cond_operator IN ('IS_NOT', 'NOT_IN') and nvl(result, '*') = 'Y')) --to avoid non-updatable statements
1224 			AND condition_id IN (SELECT distinct dep_clause_cond_id FROM okc_xprt_rule_eval_condval_t d WHERE d.doc_id = cond.doc_id and d.doc_type = cond.doc_type
1225 					     and d.object_type = 'RULE' and d.object_code IN (SELECT * FROM table(rule_ids1)))
1226 			RETURNING rule_id BULK COLLECT INTO clause_rules1;
1227 
1228 			IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1229 				FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '210: No. of clause based questions which are updated the result based on the new rules that are evaluated: ' || clause_rules1.count);
1230 
1231 				FOR a IN 1 .. clause_rules1.count LOOP
1232 				FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '210: clause_rules1 rule_id: ' || clause_rules1(a)); END LOOP;
1233 			END IF;
1234 		END IF;
1235 
1236 		--B) rule_ids2--- which have changed their result from Y to N or Y to null
1237 		--updated dependent clause conditions  result by considering all the other rules result
1238 
1239 		IF rule_ids2.count > 0 THEN
1240 			UPDATE okc_xprt_rule_eval_result_t cond
1241 			SET cond.result = decode(cond.cond_operator, 'IS_NOT', 'Y', 'NOT_IN', 'Y', decode((SELECT nvl(t.result, 1) FROM okc_xprt_rule_eval_result_t t, okc_xprt_rule_eval_condval_t d
1242 													   WHERE d.doc_id = cond.doc_id and d.doc_type = cond.doc_type AND d.object_type = 'RULE'
1243 													   AND d.dep_clause_cond_id = cond.condition_id AND d.object_code = t.rule_id AND t.doc_id = d.doc_id
1244 													   AND t.doc_type = d.doc_type AND t.condition_id IS NULL AND t.result IS NULL AND ROWNUM = 1),
1245 												           1, NULL, 'N'))
1246 			WHERE cond.doc_id = p_doc_id
1247 			AND cond.doc_type = p_doc_type
1248 			AND condition_type = 'CLAUSE'
1249 			AND cond.condition_id IN (SELECT distinct dep_clause_cond_id FROM okc_xprt_rule_eval_condval_t d WHERE d.doc_id = cond.doc_id AND d.doc_type = cond.doc_type
1250 						  AND d.object_type = 'RULE' AND d.object_code IN (SELECT * FROM table(rule_ids2)))
1251 			AND NOT EXISTS (SELECT 1 FROM okc_xprt_rule_eval_result_t t, okc_xprt_rule_eval_condval_t d WHERE d.doc_id = cond.doc_id AND d.doc_type = cond.doc_type
1252 					 AND d.object_type = 'RULE' AND d.dep_clause_cond_id = cond.condition_id AND d.object_code = t.rule_id
1253 					 AND t.doc_id = d.doc_id AND t.doc_type = d.doc_type AND t.condition_id IS NULL AND nvl(t.result, '*') = 'Y')
1254 					 --it their exists a sucess condition, then the result of the rule reamins same i.e T in case of IN,IS operator and F in case of IS_NOT, NOT_IN operator
1255 			RETURNING cond.rule_id BULK COLLECT INTO clause_rules2;
1256 
1257 			IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1258 				FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '220: No. of clause based questions which are updated the result based on the new rules that are evaluated: ' || clause_rules2.count);
1259 
1260 				FOR a IN 1 .. clause_rules2.count LOOP
1261 				FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '220: clause_rules2 rule_id: ' || clause_rules2(a)); END LOOP;
1262 			END IF;
1263 		END IF;
1264 
1265 		--C) rule_ids3--- which have changed their result from null to N or N to null
1266 		--updated dependent clause conditions  result by considering all the other rules result
1267 		--for this case (null to N or N to null), when the clasue condition operator is IS_NOT or NOT_IN, the condition result wont change
1268 		--for operator 'IS' or 'IN', the result wont change if it is already 'y'
1269 
1270 		IF rule_ids3.count > 0 THEN
1271 			UPDATE okc_xprt_rule_eval_result_t cond
1272 			SET cond.result = decode((SELECT nvl(t.result, 1) FROM okc_xprt_rule_eval_result_t t, okc_xprt_rule_eval_condval_t d
1273 						  WHERE d.doc_id = cond.doc_id and d.doc_type = cond.doc_type AND d.object_type = 'RULE'
1274 						  AND d.dep_clause_cond_id = cond.condition_id AND d.object_code = t.rule_id AND t.doc_id = d.doc_id
1275 						  AND t.doc_type = d.doc_type AND t.condition_id IS NULL AND t.result IS NULL AND ROWNUM = 1),
1276 						  1, NULL, 'N')
1277 			WHERE cond.doc_id = p_doc_id
1278 			AND cond.doc_type = p_doc_type
1279 			AND condition_type = 'CLAUSE'
1280 			AND cond.cond_operator IN ('IS', 'IN') --as the condition result wont change in other cases
1281 			AND nvl(cond.result, '*') <> 'Y'  --if the result is already Y, then it wont change
1282 			AND cond.condition_id IN (SELECT distinct dep_clause_cond_id FROM okc_xprt_rule_eval_condval_t d WHERE d.doc_id = cond.doc_id and d.doc_type = cond.doc_type
1283 						  AND d.object_type = 'RULE' and d.object_code IN (SELECT * FROM table(rule_ids3)))
1284 			AND NOT EXISTS (SELECT 1 FROM okc_xprt_rule_eval_result_t t, okc_xprt_rule_eval_condval_t d WHERE d.doc_id = cond.doc_id AND d.doc_type = cond.doc_type
1285 					 AND d.object_type = 'RULE' AND d.dep_clause_cond_id = cond.condition_id AND t.doc_id = d.doc_id
1286 					AND t.doc_type = d.doc_type AND d.object_code = t.rule_id AND t.condition_id IS NULL AND t.result IS NULL AND cond.result IS NULL)
1287 			RETURNING cond.rule_id BULK COLLECT INTO clause_rules3;
1288 
1289 			IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1290 				FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '230: No. of clause based questions which are updated the result based on the new rules that are evaluated: ' || clause_rules3.count);
1291 
1292 				FOR a IN 1 .. clause_rules3.count LOOP
1293 				FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '230: clause_rules3 rule_id: ' || clause_rules3(a)); END LOOP;
1294 			END IF;
1295 		END IF;
1296 
1297 	END IF;
1298 	--clause_rules1 OR clause_rules2 OR clause_rules3 can have duplicate rule_ids as a rule can be updated twice when it have as two clause based conditions
1299 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1300 
1301 	--Step III: Finding dependent rules for all the above changes and reevaluating them
1302 	IF (has_clauses = 'Y' AND (clause_rules1.count > 0 OR clause_rules2.count > 0 OR clause_rules3.count > 0)) OR (ques_rules.count > 0) THEN
1303 		OPEN c_dep_rules(clause_rules1, clause_rules2, clause_rules3, ques_rules);
1304 		FETCH c_dep_rules BULK COLLECT INTO new_reevalrule_ids;
1305 		CLOSE c_dep_rules;
1306 	END IF;
1307 
1308 	IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1309 		FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '240: No. of rules that have to be re-evaluated based on changes done: ' || new_reevalrule_ids.count);
1310 
1311 		FOR a IN 1 .. new_reevalrule_ids.count LOOP
1312 		FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '240: new_reevalrule_ids rule_id: ' || new_reevalrule_ids(a)); END LOOP;
1313 	END IF;
1314 
1315   	IF new_reevalrule_ids.count > 0 THEN
1316 		IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1317 			FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '250: calling reevaluate_rules method.');
1318 		END IF;
1319 
1320   		reevaluate_rules(new_reevalrule_ids);
1321   	END IF;
1322 
1323 	IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1324 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '260: Leaving method');
1325 	END IF;
1326 
1327 EXCEPTION
1328 WHEN OTHERS THEN
1329 	IF (FND_LOG.LEVEL_EXCEPTION >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1330 		FND_LOG.STRING( FND_LOG.LEVEL_EXCEPTION, l_module, '270: Exception occured: ' || sqlerrm);
1331 	END IF;
1332 	raise;
1333 END reevaluate_rules;
1334 
1335 
1336 FUNCTION evaluate_user_response(doc_id NUMBER, doc_type VARCHAR2, template_id NUMBER, p_question_id VARCHAR2, p_response VARCHAR2) RETURN VARCHAR2 IS
1337 
1338 CURSOR c_rule_conditions IS
1339 SELECT rule_id, condition_id, condition_type, rule_expr_type, object_code, cond_operator, result, object_value_type, object_value_code,
1340 (SELECT value_or_response FROM okc_xprt_rule_eval_condval_t WHERE doc_id = p_doc_id AND doc_type = p_doc_type
1341  AND object_type = 'QUESTION' AND object_code = cond.object_code) lhs_response,
1342 DECODE(cond.object_value_type, 'QUESTION', (SELECT value_or_response FROM okc_xprt_rule_eval_condval_t WHERE doc_id = p_doc_id AND doc_type = p_doc_type
1343 								    AND object_type = 'QUESTION' AND object_code = cond.object_value_code),
1344 								    NULL) rhs_response
1345 FROM okc_xprt_rule_eval_result_t cond
1346 WHERE doc_id = p_doc_id
1347 AND doc_type = p_doc_type
1348 AND object_code = p_question_id
1349 AND condition_type = 'QUESTION'
1350 
1351 UNION
1352 
1353 SELECT rule_id, condition_id, condition_type, rule_expr_type, object_code, cond_operator, result, object_value_type, object_value_code,
1354 DECODE(cond.condition_type, 'QUESTION', (SELECT value_or_response FROM okc_xprt_rule_eval_condval_t WHERE doc_id = p_doc_id AND doc_type = p_doc_type
1355 							      AND object_type = 'QUESTION' AND object_code = cond.object_code),
1356 							      NULL) lhs_response,
1357 (SELECT value_or_response FROM okc_xprt_rule_eval_condval_t WHERE doc_id = p_doc_id AND doc_type = p_doc_type
1358  AND object_type = 'QUESTION' AND object_code = cond.object_value_code) rhs_response
1359 FROM okc_xprt_rule_eval_result_t cond
1360 WHERE doc_id = p_doc_id
1361 AND doc_type = p_doc_type
1362 AND object_value_code = p_question_id
1363 AND object_value_type = 'QUESTION';
1364 
1365 result_tbl result_tbl_type;
1366 rule_ids OKC_TBL_NUMBER;
1367 
1368 l_cond_result BOOLEAN;
1369 i NUMBER := 0;
1370 
1371 l_api_name CONSTANT VARCHAR2(30) := 'evaluate_user_response';
1372 l_module VARCHAR2(250) := G_MODULE_NAME||l_api_name;
1373 
1374 BEGIN
1375 	IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1376 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: Entering method');
1377 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: doc_id : ' || doc_id);
1378 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: doc_type : ' || doc_type);
1379      		FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: template_id : ' || template_id);
1380      		FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: p_question_id : ' || p_question_id);
1381      		FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: p_response : ' || p_response);
1382 	END IF;
1383 
1384 	p_doc_id := doc_id;
1385 	p_doc_type := doc_type;
1386   	p_template_id := template_id;
1387 
1388 	UPDATE okc_xprt_rule_eval_condval_t
1389 	SET value_or_response  = p_response
1390 	WHERE object_code = p_question_id
1391 	AND object_type = 'QUESTION'
1392  	AND doc_id = p_doc_id
1393 	AND doc_type = p_doc_type;
1394 
1395 	questions_display_changed := 'N';
1396 	rule_ids := OKC_TBL_NUMBER();
1397 
1398 	IF p_response IS NULL THEN
1399 		FOR rule_cond IN c_rule_conditions LOOP
1400 			--if both lhs and rhs are questions then atleast one of the response should not be null, then only we will ahve a change in the result of the condition
1401 			IF ((rule_cond.condition_type = 'QUESTION' AND rule_cond.object_value_type = 'QUESTION') AND (rule_cond.lhs_response IS NOT NULL OR rule_cond.rhs_response IS NOT NULL)) THEN
1402 				i := i + 1;
1403 				result_tbl(i).rule_id := rule_cond.rule_id;
1404 				result_tbl(i).condition_id := rule_cond.condition_id;
1405 				result_tbl(i).result := NULL;
1406 				rule_ids.extend(1);
1407 				rule_ids(i) := rule_cond.rule_id;
1408 			END IF;
1409 			--if only one of the rhs or lhs is a question then set the result to N of that condition as the response of the question is null
1410 			IF (rule_cond.condition_type <> 'QUESTION' OR rule_cond.object_value_type <> 'QUESTION') THEN
1411 				i := i + 1;
1412 				result_tbl(i).rule_id := rule_cond.rule_id;
1413 				result_tbl(i).condition_id := rule_cond.condition_id;
1414 				result_tbl(i).result := NULL;
1415 				rule_ids.extend(1);
1416 				rule_ids(i) := rule_cond.rule_id;
1417 			END IF;
1418 		END LOOP;
1419 	ELSE
1420 		FOR rule_cond IN c_rule_conditions LOOP
1421 			IF ((rule_cond.condition_type = 'QUESTION' AND rule_cond.object_value_type = 'QUESTION') AND (rule_cond.lhs_response IS NULL OR rule_cond.rhs_response IS NULL)) THEN
1422 				l_cond_result := NULL;
1423 			ELSE
1424 				l_cond_result := evaluate_condition(rule_cond.condition_id, rule_cond.condition_type, rule_cond.object_code, rule_cond.object_value_type, rule_cond.object_value_code, rule_cond.cond_operator);
1425 			END IF;
1426 
1427 			IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1428 	     			FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '110: condition_id : ' || rule_cond.condition_id);
1429 				IF l_cond_result IS NULL THEN
1430 		     			FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '110: l_cond_result : NULL');
1431 				ELSIF l_cond_result THEN
1432 		     			FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '110: l_cond_result : TRUE');
1433 				ELSE
1434 		     			FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '110: l_cond_result : FALSE');
1435 				END IF;
1436 			END IF;
1437 
1438 			IF l_cond_result IS NULL AND rule_cond.result IS NOT NULL THEN
1439 				i := i + 1;
1440 				result_tbl(i).rule_id := rule_cond.rule_id;
1441 				result_tbl(i).condition_id := rule_cond.condition_id;
1442 				result_tbl(i).result := NULL;
1443 				rule_ids.extend(1);
1444 				rule_ids(i) := rule_cond.rule_id;
1445 			ELSIF l_cond_result = FALSE AND nvl(rule_cond.result, '*') <> 'N' THEN
1446 				i := i + 1;
1447 				result_tbl(i).rule_id := rule_cond.rule_id;
1448 				result_tbl(i).condition_id := rule_cond.condition_id;
1449 				result_tbl(i).result := 'N';
1450 				rule_ids.extend(1);
1451 				rule_ids(i) := rule_cond.rule_id;
1452 			ELSIF l_cond_result = TRUE AND nvl(rule_cond.result, '*') <> 'Y' THEN
1453 				i := i + 1;
1454 				result_tbl(i).rule_id := rule_cond.rule_id;
1455 				result_tbl(i).condition_id := rule_cond.condition_id;
1456 				result_tbl(i).result := 'Y';
1457 				rule_ids.extend(1);
1458 				rule_ids(i) := rule_cond.rule_id;
1459 			END IF;
1460 		END LOOP;
1461 	END IF;
1462 
1463 	IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1464 		FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '120: : result_tbl count' || result_tbl.count);
1465 
1466 		FOR a IN 1 .. result_tbl.count LOOP
1467 		FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '120: result_tbl rule_id: ' || result_tbl(a).rule_id || ' condition_id: ' || result_tbl(a).condition_id || ' result: ' || result_tbl(a).result); END LOOP;
1468 	END IF;
1469 
1470 	IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1471 		FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '130: rule_ids count: ' || rule_ids.count);
1472 
1473 		FOR a IN 1 .. rule_ids.count LOOP
1474 		FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '130: rule_ids rule_id: ' || rule_ids(a)); END LOOP;
1475 	END IF;
1476 
1477 	FORALL j IN 1 .. result_tbl.count
1478 		UPDATE okc_xprt_rule_eval_result_t result_tmp
1479 		SET result = result_tbl(j).result
1480 		WHERE result_tmp.rule_id = result_tbl(j).rule_id
1481 		AND result_tmp.condition_id = result_tbl(j).condition_id
1482 		AND result_tmp.doc_id = p_doc_id
1483 		AND result_tmp.doc_type = p_doc_type;
1484 
1485 	IF result_tbl.count > 0 THEN
1486 		IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1487 			FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '140: calling reevaluate_rules method.');
1488 		END IF;
1489 		reevaluate_rules(rule_ids);
1490 	END IF;
1491 
1492 	IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1493 		FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '150: questions_display_changed: ' || questions_display_changed);
1494 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '150: Leaving method');
1495 	END IF;
1496 
1497 	RETURN questions_display_changed;
1498 
1499 EXCEPTION
1500 WHEN OTHERS THEN
1501 	IF (FND_LOG.LEVEL_EXCEPTION >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1502 		FND_LOG.STRING( FND_LOG.LEVEL_EXCEPTION, l_module, '160: Exception occured: ' || sqlerrm);
1503 	END IF;
1504 	raise;
1505 END evaluate_user_response;
1506 
1507 PROCEDURE save_responses(doc_id IN NUMBER, doc_type IN VARCHAR2, p_lock_xprt_yn IN VARCHAR2, x_return_status OUT NOCOPY VARCHAR2) IS
1508 
1509 CURSOR c_base_table_dtls IS
1510 SELECT orig_system_reference_code, orig_system_reference_id1
1511 FROM okc_template_usages
1512 WHERE document_type = p_doc_type
1513 AND document_id = p_doc_id;
1514 
1515 l_src_document_type okc_template_usages.orig_system_reference_code%TYPE;
1516 l_src_document_id okc_template_usages.orig_system_reference_id1%TYPE;
1517 x_msg_data VARCHAR2(2000);
1518 x_msg_count NUMBER;
1519 
1520 l_api_name CONSTANT VARCHAR2(30) := 'save_responses';
1521 l_module VARCHAR2(250) := G_MODULE_NAME||l_api_name;
1522 
1523 BEGIN
1524 	IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1525 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: Entering method');
1526 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: doc_id : ' || doc_id);
1527 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: doc_type : ' || doc_type);
1528      		FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: p_lock_xprt_yn : ' || p_lock_xprt_yn);
1529 	END IF;
1530 
1531 	p_doc_id := doc_id;
1532 	p_doc_type := doc_type;
1533 
1534 	--  Initialize API return status to success
1535 	x_return_status := FND_API.G_RET_STS_SUCCESS;
1536 
1537 	--concurrent mod changes start
1538 	-- Read the base table details
1539     	OPEN c_base_table_dtls;
1540       	FETCH c_base_table_dtls INTO l_src_document_type,l_src_document_id;
1541     	CLOSE c_base_table_dtls;
1542 
1543 	IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1544 		FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '110: l_src_document_type: ' || l_src_document_type);
1545 		FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '110: l_src_document_id: ' || l_src_document_id);
1546 	END IF;
1547 
1548     	IF p_lock_xprt_yn = 'Y' THEN
1549      	IF l_src_document_type IS NOT NULL AND l_src_document_id IS NOT NULL THEN
1550                  -- Lock base table.
1551                   okc_k_entity_locks_grp.lock_entity
1552                               ( p_api_version     => 1,
1553                               p_init_msg_list    => FND_API.G_FALSE ,
1554                               p_commit           => FND_API.G_FALSE,
1555                               p_entity_name      => okc_k_entity_locks_grp.G_XPRT_ENTITY,
1556                               p_entity_pk1       =>  To_Char(l_src_document_id),
1557                               p_entity_pk2       =>  To_Char(l_src_document_type),
1558                               p_LOCK_BY_DOCUMENT_TYPE => p_doc_type,
1559                               p_LOCK_BY_DOCUMENT_ID => p_doc_id,
1560                               X_RETURN_STATUS => X_RETURN_STATUS,
1561                               X_MSG_COUNT => X_MSG_COUNT,
1562                               X_MSG_DATA => X_MSG_DATA
1563                               );
1564                 --------------------------------------------
1565                 IF (x_return_status = FND_API.G_RET_STS_UNEXP_ERROR) THEN
1566                   RAISE FND_API.G_EXC_UNEXPECTED_ERROR ;
1567                 ELSIF (x_return_status = FND_API.G_RET_STS_ERROR) THEN
1568                   RAISE FND_API.G_EXC_ERROR ;
1569                 END IF;
1570               --------------------------------------------
1571 		ELSE
1572               NULL;
1573               -- throw error;
1574           END IF;
1575     	END IF; -- p_create_lock_for_xprt = 'Y'
1576 	--concurrent mod chanegs end
1577 
1578 	--deleting the responses and copying the new responses into okc_xprt_doc_ques_response table
1579 	DELETE okc_xprt_doc_ques_response WHERE doc_id = p_doc_id AND doc_type = p_doc_type;
1580 
1581 	--copying the responses to okc_xprt_doc_ques_response
1582 	INSERT INTO okc_xprt_doc_ques_response (doc_question_response_id, doc_id, doc_type, question_id, response)
1583 	(SELECT OKC_XPRT_DOC_QUES_RESPONSE_S.nextval, p_doc_id, p_doc_type, object_code, value_or_response FROM okc_xprt_rule_eval_condval_t
1584 	 WHERE doc_id = p_doc_id AND doc_type = p_doc_type AND object_type = 'QUESTION' AND display_flag = 'Y');
1585 
1586 	--updating contract_expert_finish_flag to N to say that the process of contract expert is not finished
1587 	UPDATE okc_template_usages
1588 	SET contract_expert_finish_flag = 'N'
1589 	WHERE document_id = p_doc_id
1590 	AND document_type = p_doc_type;
1591 
1592 	commit;
1593 
1594 	IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1595 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '120: Commit done');
1596 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '120: Leaving method');
1597 	END IF;
1598 
1599 EXCEPTION
1600 WHEN OTHERS THEN
1601 	IF (FND_LOG.LEVEL_EXCEPTION >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1602 		FND_LOG.STRING( FND_LOG.LEVEL_EXCEPTION, l_module, '130: Exception occured: ' || sqlerrm);
1603 	END IF;
1604 	raise;
1605 END save_responses;
1606 
1607 FUNCTION has_all_questions_answered(doc_id NUMBER, doc_type VARCHAR2) RETURN VARCHAR2 IS
1608 
1609 has_all_ques_answered VARCHAR2(1) := 'Y';
1610 
1611 l_api_name CONSTANT VARCHAR2(30) := 'has_all_questions_answered';
1612 l_module VARCHAR2(250) := G_MODULE_NAME||l_api_name;
1613 
1614 BEGIN
1615 	IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1616 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: Entering method');
1617 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: doc_id : ' || doc_id);
1618 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: doc_type : ' || doc_type);
1619 	END IF;
1620 
1621 	p_doc_id := doc_id;
1622 	p_doc_type := doc_type;
1623 
1624   	BEGIN
1625     		SELECT 'N' INTO has_all_ques_answered FROM dual
1626     		WHERE EXISTS (SELECT 1 FROM okc_xprt_rule_eval_condval_t WHERE doc_id = p_doc_id AND doc_type = p_doc_type
1627 				AND object_type = 'QUESTION' AND display_flag = 'Y' AND value_or_response IS NULL);
1628  	EXCEPTION
1629     		WHEN NO_DATA_FOUND THEN
1630   		NULL;
1631   	END;
1632 
1633 	IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1634 		FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '110: has_all_ques_answered: ' || has_all_ques_answered);
1635 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '110: Leaving method');
1636 	END IF;
1637 
1638 	RETURN has_all_ques_answered;
1639 
1640 EXCEPTION
1641 WHEN OTHERS THEN
1642 	IF (FND_LOG.LEVEL_EXCEPTION >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1643 		FND_LOG.STRING( FND_LOG.LEVEL_EXCEPTION, l_module, '120: Exception occured: ' || sqlerrm);
1644 	END IF;
1645 	raise;
1646 END has_all_questions_answered;
1647 
1648 
1649 PROCEDURE create_xprt_responses_version(doc_id IN NUMBER, doc_type IN VARCHAR2, p_major_version IN NUMBER) IS
1650 
1651 l_api_name CONSTANT VARCHAR2(30) := 'create_xprt_responses_version';
1652 l_module VARCHAR2(250) := G_MODULE_NAME||l_api_name;
1653 
1654 BEGIN
1655 
1656 	IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1657 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: Entering create_xprt_responses_version method');
1658 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: doc_id : ' || doc_id);
1659 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: doc_type : ' || doc_type);
1660      		FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: p_major_version : ' || p_major_version);
1661 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: Saving responses into history table');
1662 	END IF;
1663 
1664 	p_doc_id := doc_id;
1665   	p_doc_type := doc_type;
1666 
1667 	--copying the responses to okc_xprt_doc_ques_response_h
1668 	INSERT INTO okc_xprt_doc_ques_response_h (doc_question_response_id, doc_id, doc_type, major_version, question_id, response)
1669 	(SELECT doc_question_response_id, p_doc_id, p_doc_type, p_major_version, question_id, response FROM okc_xprt_doc_ques_response
1670 	 WHERE doc_id = p_doc_id AND doc_type = p_doc_type);
1671 
1672 	IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1673 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '110: no. of rows copied : ' || sql%rowcount);
1674 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '110: Leaving method');
1675 	END IF;
1676 
1677 EXCEPTION
1678 WHEN OTHERS THEN
1679 	IF (FND_LOG.LEVEL_EXCEPTION >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1680 		FND_LOG.STRING( FND_LOG.LEVEL_EXCEPTION, l_module, '120: Exception occured: ' || sqlerrm);
1681 	END IF;
1682 	raise;
1683 END create_xprt_responses_version;
1684 
1685 
1686 PROCEDURE restore_xprt_responses_version(doc_id IN NUMBER, doc_type IN VARCHAR2, p_major_version IN NUMBER) IS
1687 
1688 l_api_name CONSTANT VARCHAR2(30) := 'restore_xprt_responses_version';
1689 l_module VARCHAR2(250) := G_MODULE_NAME||l_api_name;
1690 
1691 BEGIN
1692 
1693 	IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1694 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: Entering restore_xprt_responses_version method');
1695 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: doc_id : ' || doc_id);
1696 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: doc_type : ' || doc_type);
1697      		FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: p_major_version : ' || p_major_version);
1698 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: Restoring responses from history table to the main table');
1699 	END IF;
1700 
1701 	p_doc_id := doc_id;
1702   	p_doc_type := doc_type;
1703 
1704 	--copying the responses to okc_xprt_doc_ques_response from okc_xprt_doc_ques_response_h table
1705 	INSERT INTO okc_xprt_doc_ques_response(doc_question_response_id, doc_id, doc_type, question_id, response)
1706 	(SELECT doc_question_response_id, p_doc_id, p_doc_type, question_id, response FROM okc_xprt_doc_ques_response_h
1707 	 WHERE doc_id = p_doc_id AND doc_type = p_doc_type AND major_version = p_major_version);
1708 
1709 	IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1710 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '110: no. of rows copied : ' || sql%rowcount);
1711 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '110: Leaving restore_xprt_responses_version method');
1712 	END IF;
1713 
1714 EXCEPTION
1715 WHEN OTHERS THEN
1716 	IF (FND_LOG.LEVEL_EXCEPTION >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1717 		FND_LOG.STRING( FND_LOG.LEVEL_EXCEPTION, l_module, '120: Exception occured: ' || sqlerrm);
1718 	END IF;
1719 	raise;
1720 END restore_xprt_responses_version;
1721 
1722 
1723 PROCEDURE delete_xprt_responses_version(doc_id IN NUMBER, doc_type IN VARCHAR2, p_major_version IN NUMBER) IS
1724 
1725 l_api_name CONSTANT VARCHAR2(30) := 'delete_xprt_responses_version';
1726 l_module VARCHAR2(250) := G_MODULE_NAME||l_api_name;
1727 
1728 BEGIN
1729 
1730 	IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1731 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: Entering delete_xprt_responses_version method');
1732 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: doc_id : ' || doc_id);
1733 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: doc_type : ' || doc_type);
1734      		FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: p_major_version : ' || p_major_version);
1735 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '100: Deleting responses from history table');
1736 	END IF;
1737 
1738 	p_doc_id := doc_id;
1739   	p_doc_type := doc_type;
1740 
1741 	--deleting the responses from okc_xprt_doc_ques_response_h history table as the revision is deleted.
1742 	DELETE FROM okc_xprt_doc_ques_response_h
1743 	WHERE doc_id = p_doc_id AND doc_type = p_doc_type AND major_version = p_major_version;
1744 
1745 	IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1746 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '110: no. of rows deleted : ' || sql%rowcount);
1747 	     	FND_LOG.STRING( FND_LOG.LEVEL_STATEMENT, l_module, '110: Leaving delete_xprt_responses_version method');
1748 	END IF;
1749 
1750 EXCEPTION
1751 WHEN OTHERS THEN
1752 	IF (FND_LOG.LEVEL_EXCEPTION >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1753 		FND_LOG.STRING( FND_LOG.LEVEL_EXCEPTION, l_module, '120: Exception occured: ' || sqlerrm);
1754 	END IF;
1755 	raise;
1756 END delete_xprt_responses_version;
1757 
1758 END OKC_XPRT_RULES_ENGINE_PVT;