1 PACKAGE BODY qa_ss_results AS
2 /* $Header: qltssreb.plb 120.29 2011/04/11 18:21:16 ntungare ship $ */
3
4
5 g_message_table mesg_table;
6
7
8 PROCEDURE populate_message_table IS
9
10 BEGIN
11
12 g_message_table(qa_validation_api.not_enabled_error) :=
13 'QA_API_NOT_ENABLED';
14 g_message_table(qa_validation_api.no_values_error) := 'QA_API_NO_VALUES';
15 g_message_table(qa_validation_api.mandatory_error) := 'QA_API_MANDATORY';
16 g_message_table(qa_validation_api.not_revision_controlled_error) :=
17 'QA_API_REVISION_CONTROLLED';
18 g_message_table(qa_validation_api.mandatory_revision_error) :=
19 'QA_API_MANDATORY_REVISION';
20 g_message_table(qa_validation_api.no_values_error) := 'QA_API_NO_VALUES';
21 g_message_table(qa_validation_api.keyflex_error) := 'QA_API_KEYFLEX';
22 g_message_table(qa_validation_api.id_not_found_error) :=
23 'QA_API_ID_NOT_FOUND';
24 g_message_table(qa_validation_api.spec_limit_error) := 'QA_API_SPEC_LIMIT';
25 g_message_table(qa_validation_api.immediate_action_error) :=
26 'QA_API_IMMEDIATE_ACTION';
27 g_message_table(qa_validation_api.lower_limit_error) :=
28 'QA_API_LOWER_LIMIT';
29 g_message_table(qa_validation_api.upper_limit_error) :=
30 'QA_API_UPPER_LIMIT';
31 g_message_table(qa_validation_api.value_not_in_sql_error) :=
32 'QA_API_VALUE_NOT_IN_SQL';
33 g_message_table(qa_validation_api.sql_validation_error) :=
34 'QA_API_SQL_VALIDATION';
35 g_message_table(qa_validation_api.date_conversion_error) :=
36 'QA_API_INVALID_DATE';
37 g_message_table(qa_validation_api.data_type_error) := 'QA_API_DATA_TYPE';
38 g_message_table(qa_validation_api.number_conversion_error) :=
39 'QA_API_INVALID_NUMBER';
40 g_message_table(qa_validation_api.no_data_found_error) :=
41 'QA_API_NO_DATA_FOUND';
42 g_message_table(qa_validation_api.not_locator_controlled_error) :=
43 'QA_API_NOT_LOCATOR_CONTROLLED';
44 g_message_table(qa_validation_api.item_keyflex_error) :=
45 'QA_API_ITEM_KEYFLEX';
46 g_message_table(qa_validation_api.comp_item_keyflex_error) :=
47 'QA_API_COMP_ITEM_KEYFLEX';
48 g_message_table(qa_validation_api.comp_locator_keyflex_error) :=
49 'QA_API_COMP_LOCATOR_KEYFLEX';
50 g_message_table(qa_validation_api.invalid_number_error) :=
51 'QA_API_INVALID_NUMBER';
52 g_message_table(qa_validation_api.invalid_date_error) :=
53 'QA_API_INVALID_DATE';
54 g_message_table(qa_validation_api.spec_error) := 'QA_API_SPEC';
55 g_message_table(qa_validation_api.ok) := 'QA_API_NO_ERROR';
56 g_message_table(qa_validation_api.unknown_error) := 'QA_API_UNKNOWN';
57 g_message_table(qa_validation_api.reject_an_entry_error) :=
58 'QA_API_REJECT_AN_ENTRY';
59
60 -- Bug 3679762.Initialising the message array for the missing assign a value target
61 -- column error message.
62 -- srhariha.Wed Jun 16 06:54:06 PDT 2004
63
64 g_message_table(qa_validation_api.missing_assign_column) :=
65 'QA_MISSING_ASSIGN_COLUMN';
66
67
68 END populate_message_table;
69
70 --
71 -- Bug 5932426
72 -- New Procedure to check if the data entered in a
73 -- collection element during an update Txn has been
74 -- changed, in which case the validation is not to be
75 -- performed and so the action on that element wont
76 -- refire.
77 -- ntungare Sat Apr 14 00:51:48 PDT 2007
78 --
79 PROCEDURE update_validation_flg(elements IN OUT NOCOPY qa_validation_api.ElementsArray,
80 p_plan_id IN NUMBER,
81 p_collection_id IN NUMBER,
82 p_occurrence IN NUMBER) AS
83
84 char_id INTEGER;
85 input_val VARCHAR2(32767);
86 saved_val VARCHAR2(32767);
87 --
88 -- bug 6266477
89 -- Variable declaration
90 -- skolluku Sun Oct 14 03:26:31 PDT 2007
91 --
92 l_append BOOLEAN := FALSE;
93 l_rescol VARCHAR2(30);
94 l_rescol_val VARCHAR2(32767);
95 l_sql_string VARCHAR2(32767);
96 elements_db qa_validation_api.ElementsArray;
97
98 -- Bug 9582246
99 -- New variables for obtaining COMMENTS result String.
100 -- skolluku
101 l_comments_rescol_val VARCHAR2(32767);
102 l_comments_sql_string VARCHAR2(32767);
103 l_comments_result_string VARCHAR2(32767);
104
105 BEGIN
106 char_id:= elements.first;
107
108 -- Looping through the elements
109 --
110 --
111 -- bug 6266477
112 -- Loop through all the char_id and get their
113 -- result_column_names to build the select clause
114 -- for fetching their values from QA_RESULTS_FULL_V
115 -- skolluku Sun Oct 14 03:26:31 PDT 2007
116 --
117 WHILE char_id <= elements.last
118 LOOP
119 --input_val := elements(char_id).value;
120
121 -- Getting the result_column_name stored in QA_PLAN_CHARS,
122 -- for the collection and append it to the string.
123 --
124 l_rescol := QA_ERES_PKG.get_result_column_name(p_plan_id, char_id);
125 --
126 -- bug 7194013
127 -- Check if the derived result column name is NULL in which
128 -- case the collection element needs to be removed from the
129 -- elements array since it does not exist in the Collection
130 -- plan
131 -- ntungare
132 --
133 IF (l_rescol IS NOT NULL) THEN
134 -- Bug 9582246
135 -- Condition required because separate processing would be done for COMMENTS elements.
136 -- skolluku
137 IF (l_rescol NOT LIKE 'COMMENT%') THEN
138 IF(l_append) THEN
139 l_sql_string := l_sql_string || ' || ''@';
140 l_sql_string := l_sql_string || char_id || '='' || ' || 'replace(' || l_rescol || ', ''@'', ''@@'')';
141 ELSE
142 l_sql_string := l_sql_string || '''' || char_id || '='' || ' || 'replace(' || l_rescol || ', ''@'', ''@@'')';
143 END IF;
144 -- Bug 9743010.
145 -- Added this condition as it should be within the
146 -- check for Non-Comments elements. Its previous
147 -- occurrence below has been commented out.
148 -- skolluku
149 l_append := TRUE;
150 ELSE
151 -- Bug 9582246
152 -- Here we will build result string for each COMMENT type element in the plan, separately
153 -- and concatenate them together to form a single COMMENTS result string to be used later in the code.
154 -- This is needed because of the limit in SQL output of 4000 characters.
155 -- skolluku
156 l_comments_sql_string := 'SELECT ''' || char_id || '='' || ' || 'replace(' || l_rescol || ', ''@'', ''@@'') FROM QA_RESULTS_FULL_V WHERE plan_id = :2 and collection_id = :3 and occurrence = :4';
157 EXECUTE IMMEDIATE l_comments_sql_string INTO l_comments_result_string USING p_plan_id, p_collection_id, p_occurrence;
158 IF l_comments_rescol_val IS NULL THEN -- First time.
159 l_comments_rescol_val := l_comments_result_string;
160 ELSE
161 l_comments_rescol_val := l_comments_rescol_val || '@' || l_comments_result_string;
162 END IF;
163 END IF; -- Bug 9582246
164 -- Bug 9743010. Moved this to above IF-ELSE block. skolluku
165 --l_append := TRUE;
166 ELSE
167 elements.delete(char_id);
168 END IF;
169
170 char_id:= elements.next(char_id);
171 END LOOP;
172
173 -- Execute the statement and fetch the values into an array
174 -- using result_to_array.
175 -- Bug 9582246
176 -- In case only COMMENTS elements are present, skip this part.
177 -- skolluku
178 IF l_sql_string IS NOT NULL THEN
179 l_sql_string := 'SELECT ' || l_sql_string || ' FROM QA_RESULTS_FULL_V WHERE plan_id = :2 and collection_id = :3 and occurrence = :4';
180 EXECUTE IMMEDIATE l_sql_string INTO l_rescol_val USING p_plan_id, p_collection_id, p_occurrence;
181 END IF;
182
183 -- Bug 9582246
184 -- Append the COMMENTS result string obtained earlier to the other result string.
185 -- skolluku
186 IF l_comments_rescol_val IS NOT NULL THEN
187 IF l_rescol_val IS NULL THEN
188 l_rescol_val := l_comments_rescol_val;
189 ELSE
190 l_rescol_val := l_rescol_val || '@' || l_comments_rescol_val;
191 END IF;
192 END IF; -- End changes for bug 9582246
193 elements_db := qa_validation_api.result_to_array(l_rescol_val);
194
195 -- Reinitialize the char_id variable since, the comparison
196 -- needs to be done here. So, looping again...
197 char_id:= elements.first;
198 -- Looping through the elements
199 --
200 WHILE char_id <= elements.last
201 LOOP
202 input_val := elements(char_id).value;
203 --
204 -- bug 6266477
205 -- Commented the call to get_result_column_value since,
206 -- it fetches one value at a time from QA_RESULTS_FULL_V
207 -- resulting in performance issues. To avoid this the hit
208 -- to QA_RESULTS_FULL_V is done just once and collected
209 -- into the array elements_db in the earlier processing.
210 -- skolluku Sun Oct 14 03:26:31 PDT 2007
211 --
212 -- Getting the value stored in QA_RESULTS, for the collection
213 -- element being processed
214 --
215 /*
216 saved_val := QA_ERES_PKG.get_result_column_value(
217 p_plan_id => p_plan_id,
218 p_collection_id => p_collection_id,
219 p_occurrence => p_occurrence,
220 p_char_id => char_id);
221 */
222 saved_val := elements_db(char_id).value;
223 -- If the input value is the same as the
224 -- value already existing in QA_RESULTS, it means that
225 -- the element has not been updated, in which case the
226 -- actions based on it are not to be fired. So setting
227 -- the validation flag for this element accordingly
228 --
229 If NVL(input_val,'0') = NVL(saved_val,'0') THEN
230 elements(char_id).validation_flag := qa_validation_api.action_fired;
231 --
232 -- Bug 10431717
233 -- Since the element values are the same hence setting the element as
234 -- valid.
235 --
236 elements(char_id).validation_flag := 'valid';
237 End If;
238
239 char_id:= elements.next(char_id);
240 END LOOP;
241 END update_validation_flg;
242
243
244 FUNCTION get_error_code(code IN NUMBER) RETURN VARCHAR2 IS
245 BEGIN
246 --
247 -- Should figure out the error message from dictionary.
248 --
249 RETURN qa_validation_api.get_error_message (code);
250 END get_error_code;
251
252
253 --
254 -- Get the error messages and append them into an @-separated
255 -- string.
256 --
257 PROCEDURE get_error_messages(
258 p_errors IN qa_validation_api.ErrorArray,
259 p_plan_id IN NUMBER,
260 x_messages OUT NOCOPY VARCHAR2) IS
261
262 separator CONSTANT VARCHAR2(1) := '@';
263 name qa_chars.prompt%TYPE;
264 code VARCHAR2(2000);
265
266 -- Bug 5307450
267 -- Cursor to get the message entered by the user for the
268 -- 'Reject the input' action in the collection plan.
269 -- ntungare Tue Mar 28 08:02:43 PST 2006.
270 --
271 CURSOR cur_mesg(p_plan_id NUMBER,p_char_id NUMBER) IS
272 SELECT message
273 FROM qa_plan_char_actions
274 WHERE plan_char_action_trigger_id IN
275 (SELECT plan_char_action_trigger_id
276 FROM qa_plan_char_action_triggers
277 WHERE plan_id = p_plan_id
278 AND char_id = p_char_id)
279 AND action_id = 2;
280 BEGIN
281 x_messages := '';
282
283 --
284 -- This bug is discovered during bug fix for 3402251.
285 -- In some rare situation, this proc can be called when
286 -- error stack is actually empty. Should return
287 -- immediately.
288 -- bso Mon Feb 9 22:06:09 PST 2004
289 --
290 IF p_errors.count = 0 then
291 RETURN;
292 END IF;
293
294 FOR i IN p_errors.FIRST .. p_errors.LAST LOOP
295 name := qa_plan_element_api.get_prompt(p_plan_id,
296 p_errors(i).element_id);
297 --
298 -- Just in case the prompt contains @
299 --
300 name := replace(name, separator, separator||separator);
301
302 -- Bug 5307450
303 -- In QWB if the action is 'Reject the input' we were displaying the
304 -- seeded error message 'QA_API_REJECT_AN_ENTRY' and not the message
305 -- added in the collection plan setup by the user. Now the following
306 -- condition would get the 'Reject the input' action message
307 -- from the collection plan and put in the variable code. If the action
308 -- is not 'Reject the input' then the existing code is used.
309 -- ntunagre Tue Mar 28 08:04:54 PST 2006.
310 --
311 If p_errors(i).error_code = qa_validation_api.reject_an_entry_error then
312 OPEN cur_mesg(p_plan_id, p_errors(i).element_id);
313 FETCH cur_mesg INTO code;
314 CLOSE cur_mesg;
315 else
316 code := get_error_code(p_errors(i).error_code);
317 End If;
318
319 x_messages := x_messages || name || ': ' || code;
320 IF i < p_errors.LAST THEN
321 x_messages := x_messages || separator;
322 END IF;
323 END LOOP;
324 END get_error_messages;
325
326
327 --
328 -- Get the action messages and append them into an @-separated
329 -- string.
330 --
331 PROCEDURE get_action_messages(
332 msg_array IN qa_validation_api.MessageArray,
333 plan_id IN NUMBER,
334 messages OUT NOCOPY VARCHAR2) IS
335
336 separator CONSTANT VARCHAR2(1) := '@';
337 name qa_chars.prompt%TYPE;
338 code VARCHAR2(2000);
339 BEGIN
340
341 messages := '';
342
343 IF msg_array.COUNT <> 0 THEN
344 FOR i IN msg_array.FIRST .. msg_array.LAST LOOP
345 --ilawler - bug #3340004 - Mon Feb 16 18:53:29 2004
346 --According to bso, the message should always be <target> = <value>
347
348 /*
349 name := qa_plan_element_api.get_prompt(plan_id, msg_array(i).element_id);
350
351 --
352 -- Just in case the prompt contains @
353 --
354 name := replace(name, separator, separator||separator);
355 messages := messages || name || ':' || msg_array(i).message;
356 */
357 messages := messages || msg_array(i).message;
358
359 IF i < msg_array.LAST THEN
360 messages := messages || separator;
361 END IF;
362 END LOOP;
363 END IF;
364
365 END get_action_messages;
366
367 --
368 -- Post a result to the database. This is a wrapper to the QA API
369 -- qa_results_api.insert_row
370 --
371 -- This function is used by
372 --
373 -- CMRO/QA Integration /ahldev/ahl/12.0/patch/115/sql/AHLVQARB.pls
374 --
375 -- MQA DDE /qadev/qa/12.0/patch/115/sql/qaresb.pls
376 --
377 -- Return 0 if OK
378 -- Return -1 if error.
379 --
380 FUNCTION nontxn_post_result(
381 x_occurrence OUT NOCOPY NUMBER,
382 x_org_id IN NUMBER,
383 x_plan_id IN NUMBER,
384 x_spec_id IN NUMBER,
385 x_collection_id IN NUMBER,
386 x_result IN VARCHAR2,
387 x_result1 IN VARCHAR2, -- R12 Project MOAC 4637896, ID passing
388 x_result2 IN VARCHAR2, -- not used yet, for future expansion
389 x_enabled IN INTEGER,
390 x_committed IN INTEGER,
391 x_messages OUT NOCOPY VARCHAR2)
392 RETURN INTEGER IS
393 elements qa_validation_api.ElementsArray;
394 error_array qa_validation_api.ErrorArray;
395 message_array qa_validation_api.MessageArray;
396 return_status VARCHAR2(1);
397 action_result VARCHAR2(1);
398 msg_count NUMBER;
399 msg_data VARCHAR2(2000);
400 y_spec_id NUMBER;
401 y_collection_id NUMBER;
402 y_committed VARCHAR2(1);
403 BEGIN
404
405 --
406 -- Bug 2617638
407 -- The original statement returns if x_result IS NULL.
408 -- Undesirable if caller passes all validated IDs in x_result1.
409 -- Added AND x_result1 IS NULL
410 -- bso Tue Oct 8 18:34:38 PDT 2002
411 --
412 IF x_result IS NULL AND x_result1 IS NULL THEN
413 RETURN -1;
414 END IF;
415
416 IF x_committed = 1 THEN
417 y_committed := fnd_api.g_true;
418 ELSE
419 y_committed := fnd_api.g_false;
420 END IF;
421
422 --
423 -- Some input can be -1, if that's the case, set to null
424 --
425 IF x_collection_id = -1 THEN
426 y_collection_id := NULL;
427 ELSE
428 y_collection_id := x_collection_id;
429 END IF;
430 IF x_spec_id = -1 THEN
431 y_spec_id := NULL;
432 ELSE
433 y_spec_id := x_spec_id;
434 END IF;
435
436 --
437 -- The flatten string is a representation that looks like this:
438 --
439 -- 10=Item@101=Defected@102=20 ...
440 --
441 -- namely, it is an @ separated list of charID=value. In case
442 -- value contains @, then it is doubly encoded.
443 --
444 -- First task is to decode this string into the row_element
445 -- array.
446 --
447 elements := qa_validation_api.result_to_array(x_result);
448 elements := qa_validation_api.id_to_array(x_result1, elements);
449 qa_validation_api.set_validation_flag(elements);
450
451 --
452 -- Bug 2617638
453 -- The follow statement is needed to process x_result1.
454 -- This has been included in function post_result but
455 -- was missed out in this procedure.
456 -- bso Tue Oct 8 18:37:00 PDT 2002
457 --
458
459 qa_results_pub.insert_row(
460 p_api_version => 1.0,
461 p_init_msg_list => fnd_api.g_true,
462 p_org_id => x_org_id,
463 p_plan_id => x_plan_id,
464 p_spec_id => y_spec_id,
465 p_transaction_number => null,
466 p_transaction_id => null,
467 p_enabled_flag => x_enabled,
468 p_commit => y_committed,
469 x_collection_id => y_collection_id,
470 x_occurrence => x_occurrence,
471 x_row_elements => elements,
472 x_msg_count => msg_count,
473 x_msg_data => msg_data,
474 x_error_array => error_array,
475 x_message_array => message_array,
476 x_return_status => return_status,
477 x_action_result => action_result);
478
479 IF qa_validation_api.no_errors(error_array) AND
480 return_status <> FND_API.G_RET_STS_ERROR AND
481 return_status <> FND_API.G_RET_STS_UNEXP_ERROR THEN
482 RETURN 0;
483 ELSE
484 get_error_messages(error_array, x_plan_id, x_messages);
485 END IF;
486
487 RETURN -1;
488 END nontxn_post_result;
489
490 --
491 -- Bug 5955808
492 -- New procedure to initalize the Sequence Type
493 -- Collection elements with the default value of
494 -- Automatic, using which the Sequence generation
495 -- program will generate sequences. This is very
496 -- important in case of Background result collection
497 -- ntungare Mon Mar 26 06:20:05 PDT 2007
498 --
499 PROCEDURE initialize_seq_elements(x_plan_id IN NUMBER,
500 elements IN OUT NOCOPY qa_validation_api.ElementsArray)
501 IS
502 TYPE seq_charid_tab_typ IS TABLE OF qa_chars.char_id%TYPE INDEX BY BINARY_INTEGER;
503 seq_charid_tab seq_charid_tab_typ;
504
505 def_seq_val VARCHAR2(100);
506 BEGIN
507 SELECT qc.char_id
508 BULK COLLECT INTO seq_charid_tab
509 FROM qa_chars qc, qa_plan_chars qpc
510 WHERE qpc.plan_id = x_plan_id
511 AND qc.char_id = qpc.char_id
512 AND qc.datatype = 5;
513
514 IF seq_charid_tab.COUNT <> 0 THEN
515 def_seq_val := QA_SEQUENCE_API.get_sequence_default_value();
516 END IF;
517
518 FOR cntr IN 1..seq_charid_tab.COUNT
519 LOOP
520 If elements(seq_charid_tab(cntr)).VALUE IS NULL THEN
521 elements(seq_charid_tab(cntr)).VALUE := def_seq_val;
522 End If;
523 END LOOP;
524 END initialize_seq_elements;
525
526 --
527 -- This overloaded method is for transaction only
528 -- Post a result to the database. This is a wrapper to the QA API
529 -- qa_results_api.insert_row
530 --
531 -- This function is used by
532 --
533 -- iSP /qadev/qa/12.0/java/dde/eam/server/QaResultsVORowImpl.java
534 --
535 -- EAM /qadev/qa/12.0/java/selfservice/server/QaResultsVORowImpl.java
536 --
537 -- MQA Txn /qadev/qa/12.0/patch/115/sql/qaresb.pls
538 --
539 -- Return 0 if OK
540 -- Return -1 if error.
541 --
542 FUNCTION post_result(
543 x_occurrence IN OUT NOCOPY NUMBER,
544 x_org_id IN NUMBER,
545 x_plan_id IN NUMBER,
546 x_spec_id IN NUMBER,
547 x_collection_id IN NUMBER,
548 x_result IN VARCHAR2,
549 x_result1 IN VARCHAR2, -- R12 Project MOAC 4637896, ID passing
550 x_result2 IN VARCHAR2, -- not used yet, for future expansion
551 x_enabled IN INTEGER,
552 x_committed IN INTEGER,
553 x_transaction_number IN NUMBER,
554 x_messages OUT NOCOPY VARCHAR2)
555 RETURN INTEGER IS
556 elements qa_validation_api.ElementsArray;
557 error_array qa_validation_api.ErrorArray;
558 message_array qa_validation_api.MessageArray;
559 return_status VARCHAR2(1);
560 action_result VARCHAR2(1);
561 msg_count NUMBER;
562 msg_data VARCHAR2(2000);
563 y_spec_id NUMBER;
564 y_collection_id NUMBER;
565 y_committed VARCHAR2(1);
566 BEGIN
567
568 --
569 -- Bug 2617638
570 -- The original statement returns if x_result IS NULL.
571 -- Undesirable if caller passes all validated IDs in x_result1.
572 -- Added AND x_result1 IS NULL
573 -- bso Tue Oct 8 18:34:38 PDT 2002
574 --
575 IF x_result IS NULL AND x_result1 IS NULL THEN
576 RETURN -1;
577 END IF;
578
579 IF x_transaction_number IS NULL THEN
580 RETURN -1;
581 END IF;
582
583 IF x_committed = 1 THEN
584 y_committed := fnd_api.g_true;
585 ELSE
586 y_committed := fnd_api.g_false;
587 END IF;
588
589 --
590 -- Some input can be -1, if that's the case, set to null
591 --
592 IF x_collection_id = -1 THEN
593 y_collection_id := NULL;
594 ELSE
595 y_collection_id := x_collection_id;
596 END IF;
597 IF x_spec_id = -1 THEN
598 y_spec_id := NULL;
599 ELSE
600 y_spec_id := x_spec_id;
601 END IF;
602 --
603 -- The flatten string is a representation that looks like this:
604 --
605 -- 10=Item@101=Defected@102=20 ...
606 --
607 -- namely, it is an @ separated list of charID=value. In case
608 -- value contains @, then it is doubly encoded.
609 --
610 -- First task is to decode this string into the row_element
611 -- array.
612 --
613 elements := qa_validation_api.result_to_array(x_result);
614 elements := qa_validation_api.id_to_array(x_result1, elements);
615
616 IF (x_transaction_number IS NOT NULL) AND (x_transaction_number > 0) THEN
617 qa_validation_api.set_validation_flag_txn(
618 x_elements => elements,
619 p_plan_id => x_plan_id,
620 p_transaction_number => x_transaction_number,
621 p_plan_transaction_id => NULL);
622 END IF;
623
624 --
625 -- bug 5955808
626 -- Making a call to the proc which would initialize
627 -- the seq type collection elements with the value
628 -- automatic
629 -- Mon Mar 26 06:21:43 PDT 2007
630 --
631 initialize_seq_elements(x_plan_id, elements);
632
633 qa_results_pub.insert_row(
634 p_api_version => 1.0,
635 p_init_msg_list => fnd_api.g_true,
636 p_org_id => x_org_id,
637 p_plan_id => x_plan_id,
638 p_spec_id => y_spec_id,
639 p_transaction_number => x_transaction_number,
640 p_transaction_id => null,
641 p_enabled_flag => x_enabled,
642 p_commit => y_committed,
643 x_collection_id => y_collection_id,
644 x_occurrence => x_occurrence,
645 x_row_elements => elements,
646 x_msg_count => msg_count,
647 x_msg_data => msg_data,
648 x_error_array => error_array,
649 x_message_array => message_array,
650 x_return_status => return_status,
651 x_action_result => action_result);
652
653 IF qa_validation_api.no_errors(error_array) AND
654 return_status <> FND_API.G_RET_STS_ERROR AND
655 return_status <> FND_API.G_RET_STS_UNEXP_ERROR THEN
656 get_action_messages(message_array, x_plan_id, x_messages);
657 RETURN 0;
658 ELSE
659 get_error_messages(error_array, x_plan_id, x_messages);
660 --
661 -- Remove commit; completely. The insert_row API
662 -- will take care of committing according to the
663 -- x_committed flag.
664 --
665 END IF;
666
667
668 RETURN -1;
669 END post_result;
670
671 --
672 -- This overloaded method is for ssqr
673 -- Same as post_result. In addition, it inserts pc history and automatic records.
674 --
675 -- Used only by QWB and Fwk Integration
676 -- /qadev/qa/12.0/java/ssqr/server/QualityResultsEOImpl.java
677 --
678 -- Pass -1 to x_transaction_number when using standalone.
679 --
680 -- Return 0 if OK
681 -- Return -1 if error.
682 --
683 -- 12.1 QWB Usability Improvements
684 -- Added 2 new parameters x_agg_elements and x_agg_val
685 -- to ensure that the value aggregated for any of the parent
686 -- collection elements is pushed into the JAVA layer for
687 -- assigned to the appropriate EO attributes.
688 --
689 --
690 -- bug 11896067
691 -- Added a new parameter, p_background_flag
692 --
693 FUNCTION ssqr_post_result(
694 x_occurrence IN OUT NOCOPY NUMBER,
695 x_org_id IN NUMBER,
696 x_plan_id IN NUMBER,
697 x_spec_id IN NUMBER,
698 x_collection_id IN NUMBER,
699 x_txn_header_id IN NUMBER,
700 x_par_plan_id IN NUMBER,
701 x_par_col_id IN NUMBER,
702 x_par_occ IN NUMBER,
703 x_result IN VARCHAR2,
704 x_result1 IN VARCHAR2, -- R12 Project MOAC 4637896, ID passing
705 x_result2 IN VARCHAR2, -- not used yet, for future expansion
706 x_enabled IN INTEGER,
707 x_committed IN INTEGER,
708 x_transaction_number IN NUMBER,
709 x_messages OUT NOCOPY VARCHAR2,
710 x_agg_elements OUT NOCOPY VARCHAR2,
711 x_agg_val OUT NOCOPY VARCHAR2,
712 p_last_update_date IN DATE DEFAULT SYSDATE,
713 p_background_flag IN NUMBER DEFAULT 0)
714 RETURN INTEGER IS
715 elements qa_validation_api.ElementsArray;
716 error_array qa_validation_api.ErrorArray;
717 message_array qa_validation_api.MessageArray;
718 return_status VARCHAR2(1);
719 action_result VARCHAR2(1);
720 msg_count NUMBER;
721 msg_data VARCHAR2(2000);
722 y_spec_id NUMBER;
723 y_collection_id NUMBER;
724 y_committed VARCHAR2(1);
725
726 -- anagarwa Wed May 26 17:07:29 PDT 2004
727 -- bug 3667449
728 l_ret_value VARCHAR2(1);
729
730 -- bug 4658275
731 -- for supporting Eres functionality
732 l_esig_status BOOLEAN ;
733
734 -- 12.1 QWB Usability Improvements
735 --
736 agg_elements VARCHAR2(4000);
737 agg_vals VARCHAR2(4000);
738
739 l_ssqr_operation NUMBER;
740
741 l_dummy VARCHAR2(1);
742
743 BEGIN
744
745 --messages should be cleared everytime a Submit is clicked on client
746 fnd_msg_pub.Initialize();
747 fnd_msg_pub.reset();
748
749 --
750 -- Bug 2617638
751 -- The original statement returns if x_result IS NULL.
752 -- Undesirable if caller passes all validated IDs in x_result1.
753 -- Added AND x_result1 IS NULL
754 -- bso Tue Oct 8 18:34:38 PDT 2002
755 --
756 IF x_result IS NULL AND x_result1 IS NULL THEN
757 RETURN -1;
758 END IF;
759
760 /*
761 IF x_transaction_number IS NULL THEN
762 RETURN -1;
763 END IF;
764 */
765 IF x_committed = 1 THEN
766 y_committed := fnd_api.g_true;
767 ELSE
768 y_committed := fnd_api.g_false;
769 END IF;
770
771 --
772 -- Some input can be -1, if that's the case, set to null
773 --
774 IF x_collection_id = -1 THEN
775 y_collection_id := NULL;
776 ELSE
777 y_collection_id := x_collection_id;
778 END IF;
779 IF x_spec_id = -1 THEN
780 y_spec_id := NULL;
781 ELSE
782 y_spec_id := x_spec_id;
783 END IF;
784
785 -- Bug 4658275. eres support in QWB
786 -- check for the collection id of parent and child
787 -- if collection Id is same then we are entering
788 -- child row immediately in the same session
789 -- check is only required when parent row is
790 -- already in database in status 2
791 IF ( x_par_col_id <> x_collection_id ) THEN
792 l_esig_status := validate_esig_for_insert(p_plan_id => x_par_plan_id,
793 p_plan_collection_id => x_par_col_id,
794 p_plan_occurrence => x_par_occ );
795 IF NOT l_esig_status THEN
796 RETURN -1;
797 END IF;
798 END IF; -- x_par_col_id <> x_collection_id
799
800 --
801 -- The flatten string is a representation that looks like this:
802 --
803 -- 10=Item@101=Defected@102=20 ...
804 --
805 -- namely, it is an @ separated list of charID=value. In case
806 -- value contains @, then it is doubly encoded.
807 --
808 -- First task is to decode this string into the row_element
809 -- array.
810 --
811 elements := qa_validation_api.result_to_array(x_result);
812 elements := qa_validation_api.id_to_array(x_result1, elements);
813
814 IF (x_transaction_number IS NOT NULL) AND (x_transaction_number > 0) THEN
815 qa_validation_api.set_validation_flag_txn(
816 x_elements => elements,
817 p_plan_id => x_plan_id,
818 p_transaction_number => x_transaction_number,
819 p_plan_transaction_id => NULL);
820 END IF;
821
822 -- If the Txn number is 0 or -1 then it means that the
823 -- txn is not an OAF Txn so set the value as 1 else 2
824 -- The difference is that for the OAF Txns (stauts 2)
825 -- the validation needs to be done again to derive the
826 -- Id values for the context elements.
827 -- This is not needed in case of Standalone entry in QWB
828 --
829 If x_transaction_number IN (0, -1) then
830 l_ssqr_operation := 1;
831 Else
832 l_ssqr_operation := 2;
833 End If;
834
835 --
836 -- bug 11896067
837 -- If the background flag is 1 then the
838 -- l_ssqr_operation flag is made NULL so
839 -- that all the actions fire even if the
840 -- txn were and MES txn.
841 --
842 If p_background_flag = 1 THEN
843 l_ssqr_operation := NULL;
844 END If;
845
846 -- 12.1 QWB Usability Improvements
847 -- Passing a new parameter p_ssqr_operation to indicate
848 -- that the processing is being done for QWB application
849 -- that would ensure that the Row Validation is not done
850 -- again at the time of the data insertion
851 --
852 qa_results_pub.insert_row(
853 p_api_version => 1.0,
854 p_init_msg_list => fnd_api.g_true,
855 p_org_id => x_org_id,
856 p_plan_id => x_plan_id,
857 p_spec_id => y_spec_id,
858 p_transaction_number => x_transaction_number,
859 p_transaction_id => null,
860 p_txn_header_id => x_txn_header_id,
861 p_enabled_flag => x_enabled,
862 p_commit => y_committed,
863 x_collection_id => y_collection_id,
864 x_occurrence => x_occurrence,
865 x_row_elements => elements,
866 x_msg_count => msg_count,
867 x_msg_data => msg_data,
868 x_error_array => error_array,
869 x_message_array => message_array,
870 x_return_status => return_status,
871 x_action_result => action_result,
872 p_ssqr_operation => l_ssqr_operation,
873 p_last_update_date => p_last_update_date);
874
875 IF qa_validation_api.no_errors(error_array) AND
876 return_status <> FND_API.G_RET_STS_ERROR AND
877 return_status <> FND_API.G_RET_STS_UNEXP_ERROR THEN
878 get_action_messages(message_array, x_plan_id, x_messages);
879
880 --create relationship with parent
881
882 -- Bug 4343758. OA Framework Integration project.
883 -- Shouldnt create relationship if parent plan is null.
884 -- srhariha. Wed May 18 04:34:53 PDT 2005.
885 -- 12.1 QWB Usability Improvements
886 -- Get the aggregated values for tge Parent plan elements
887 --
888
889 if(x_par_plan_id is not null) then
890 --
891 -- bug 7046071
892 -- Passing the p_ssqr_operation parameter to check if the
893 -- call is done from the OAF application or from Forms
894 -- In case of the OAF application, the COMMIT that is
895 -- executed in the aggregate_parent must not be called
896 -- ntungare
897 --
898 qa_parent_child_pkg.relate(x_par_plan_id, x_par_col_id,
899 x_par_occ, x_plan_id,
900 x_collection_id, x_occurrence,
901 x_txn_header_id,
902 agg_elements,
903 agg_vals,
904 l_ssqr_operation);
905 -- If the parent Collection id is not equal to the child collection
906 -- Id it means that the Child record is being added to an existing
907 -- parent record in which case the Aggregation processing needs to
908 -- be done
909 --
910 -- Bug 6729769
911 -- This check is no longer needed since OAF will always call
912 -- the update API for the parent when a Child record is inserted.
913 -- The History record would be inserted when the update for parent is
914 -- called. If a Hist record is already present for the parent record
915 -- for the txn then it would be updated
916 -- ntungare
917 --
918 --if (x_par_col_id <> x_collection_id) THEN
919 x_agg_elements := RTRIM(LTRIM(agg_elements,','),',');
920 x_agg_val := RTRIM(LTRIM(agg_vals,','),',');
921 -- else if both the parent and the child records are being
922 -- inserted anew then History child records need to be explicitly
923 -- updated if the aggregation has happened
924 --
925 /*
926 else
927 if (agg_elements IS NOT NULL) THEN
928 l_dummy := QA_PARENT_CHILD_PKG.update_hist_children(
929 p_parent_plan_id => x_par_plan_id,
930 p_parent_collection_id => x_par_col_id,
931 p_parent_occurrence => x_par_occ);
932 end if;
933 end if;
934 */
935 end if;
936
937 -- Bug 3536025. Calling new procedure insert_history_auto_rec_QWB
938 -- instead of insert_history_auto_rec. The new procedure is same as
939 -- the old one except it doesnot changes child plan's txn_header_id
940 -- and doesnot fire actions for child plans.
941 -- srhariha. Wed May 26 22:31:28 PDT 2004
942
943
944 /*
945 qa_parent_child_pkg.insert_history_auto_rec_QWB(x_plan_id,
946 x_txn_header_id,
947 1,
948 2);
949 qa_parent_child_pkg.insert_history_auto_rec_QWB(x_plan_id,
950 x_txn_header_id,
951 1,
952 4);
953 */
954
955 -- Bug 4343758. OA Framework Integration project.
956 -- Shouldnt create history and automatic for txn scenario.
957 -- srhariha. Wed May 18 04:34:53 PDT 2005.
958
959 -- Bug 3681815. Changing the call to proc below as the signature got
960 -- changed due to the bug.
961 -- commenting the previous calls to proc above.
962 -- saugupta Tue, 15 Jun 2004 05:51:00 -0700 PDT
963
964 -- insert automatic records
965 if (x_enabled = 2 or x_enabled is null) then
966
967 qa_parent_child_pkg.insert_history_auto_rec_QWB(p_plan_id => x_plan_id,
968 p_collection_id => y_collection_id,
969 p_occurrence => x_occurrence,
970 p_organization_id => x_org_id,
971 p_txn_header_id => x_txn_header_id,
972 p_relationship_type => 1,
973 p_data_entry_mode => 2,
974 x_status => return_status);
975 -- insert history records
976 qa_parent_child_pkg.insert_history_auto_rec_QWB(p_plan_id => x_plan_id,
977 p_collection_id => y_collection_id,
978 p_occurrence => x_occurrence,
979 p_organization_id => x_org_id,
980 p_txn_header_id => x_txn_header_id,
981 p_relationship_type => 1,
982 p_data_entry_mode => 4,
983 x_status => return_status);
984 end if;
985
986
987
988 -- Bug 4343758. OA Framework Integration project.
989 -- Shouldnt update parent if parent plan is null.
990 -- srhariha. Wed May 18 04:34:53 PDT 2005.
991
992 -- Bug 5355933. Do not call update if Insert has not happened
993 -- saugupta Wed, 26 Jul 2006 05:55:14 -0700 PDT
994 if(x_par_plan_id is not null and return_status = 'T' ) then
995 -- anagarwa Wed May 26 17:07:29 PDT 2004
996 -- bug 3667449
997 -- if parent copy source element is updated, then update the
998 -- child too.
999 l_ret_value:= QA_PARENT_CHILD_PKG.update_child(x_par_plan_id,
1000 x_par_col_id,
1001 x_par_occ, x_plan_id,
1002 x_collection_id, x_occurrence);
1003 end if;
1004
1005 RETURN 0;
1006 ELSE
1007 get_error_messages(error_array, x_plan_id, x_messages);
1008 --
1009 -- Remove commit; completely. The insert_row API
1010 -- will take care of committing according to the
1011 -- x_committed flag.
1012 --
1013 END IF;
1014
1015 RETURN -1;
1016 END ssqr_post_result;
1017
1018
1019 --
1020 -- This seems to be used only by EAM transactions.
1021 -- /qadev/qa/12.0/java/dde/eam/server/QaResultsVORowImpl.java
1022 --
1023 FUNCTION update_result(
1024 x_occurrence IN NUMBER,
1025 x_org_id IN NUMBER,
1026 x_plan_id IN NUMBER,
1027 x_spec_id IN NUMBER,
1028 x_collection_id IN NUMBER,
1029 x_result IN VARCHAR2,
1030 x_result1 IN VARCHAR2, -- R12 Project MOAC 4637896, ID passing
1031 x_result2 IN VARCHAR2, -- not used yet, for future expansion
1032 x_enabled IN INTEGER,
1033 x_committed IN INTEGER,
1034 x_transaction_number IN NUMBER,
1035 x_messages OUT NOCOPY VARCHAR2)
1036 RETURN INTEGER IS
1037 elements qa_validation_api.ElementsArray;
1038 error_array qa_validation_api.ErrorArray;
1039 message_array qa_validation_api.MessageArray;
1040 return_status VARCHAR2(1);
1041 action_result VARCHAR2(1);
1042 msg_count NUMBER;
1043 msg_data VARCHAR2(2000);
1044 y_spec_id NUMBER;
1045 y_collection_id NUMBER;
1046 y_committed VARCHAR2(1);
1047
1048 -- esig status boolean variable
1049 l_esig_status BOOLEAN;
1050 BEGIN
1051 IF x_result IS NULL AND x_result1 IS NULL THEN
1052 RETURN -1;
1053 END IF;
1054
1055 --IF x_transaction_number IS NULL THEN
1056 -- RETURN -1;
1057 --END IF;
1058
1059 IF x_committed = 1 THEN
1060 y_committed := fnd_api.g_true;
1061 ELSE
1062 y_committed := fnd_api.g_false;
1063 END IF;
1064
1065 --
1066 -- Some input can be -1, if that's the case, set to null
1067 --
1068 IF x_collection_id = -1 THEN
1069 y_collection_id := NULL;
1070 ELSE
1071 y_collection_id := x_collection_id;
1072 END IF;
1073 IF x_spec_id = -1 THEN
1074 y_spec_id := NULL;
1075 ELSE
1076 y_spec_id := x_spec_id;
1077 END IF;
1078
1079
1080 --
1081 -- The flatten string is a representation that looks like this:
1082 --
1083 -- 10=Item@101=Defected@102=20 ...
1084 --
1085 -- namely, it is an @ separated list of charID=value. In case
1086 -- value contains @, then it is doubly encoded.
1087 --
1088 -- First task is to decode this string into the row_element
1089 -- array.
1090 --
1091
1092 elements := qa_validation_api.result_to_array(x_result);
1093 elements := qa_validation_api.id_to_array(x_result1, elements);
1094
1095 IF (x_transaction_number IS NOT NULL) AND (x_transaction_number > 0) THEN
1096 qa_validation_api.set_validation_flag_txn(
1097 x_elements => elements,
1098 p_plan_id => x_plan_id,
1099 p_transaction_number => x_transaction_number,
1100 p_plan_transaction_id => NULL);
1101 END IF;
1102
1103 qa_results_pub.update_row(
1104 p_api_version => 1.0,
1105 p_init_msg_list => fnd_api.g_true,
1106 p_commit => y_committed,
1107 p_plan_id => x_plan_id,
1108 p_spec_id => y_spec_id,
1109 p_org_id => x_org_id,
1110 p_transaction_number => x_transaction_number,
1111 p_transaction_id => null,
1112 p_enabled_flag => x_enabled,
1113 p_collection_id => y_collection_id,
1114 p_occurrence => x_occurrence,
1115 x_row_elements => elements,
1116 x_msg_count => msg_count,
1117 x_msg_data => msg_data,
1118 x_error_array => error_array,
1119 x_message_array => message_array,
1120 x_return_status => return_status,
1121 x_action_result => action_result);
1122
1123 IF qa_validation_api.no_errors(error_array) THEN
1124
1125 -- Bug 4057388. Display a message action was not firing in eam.
1126 -- message_array returned from qa_results_pub.update_row was
1127 -- not converted to output string x_mesasges.
1128 -- srhariha.Thu Dec 30 22:32:00 PST 2004
1129
1130 get_action_messages(message_array, x_plan_id, x_messages);
1131
1132
1133 RETURN 0;
1134 ELSIF return_status <> FND_API.G_RET_STS_ERROR AND
1135 return_status <> FND_API.G_RET_STS_UNEXP_ERROR THEN
1136 get_error_messages(error_array, x_plan_id, x_messages);
1137 END IF;
1138
1139 RETURN -1;
1140 END update_result;
1141
1142
1143 PROCEDURE post_error_messages (p_errors IN qa_validation_api.ErrorArray,
1144 plan_id NUMBER) IS
1145
1146 l_message_name VARCHAR2(30);
1147 l_char_prompt VARCHAR2(100);
1148
1149 -- bug 5307450
1150 -- Cursor to get the message entered by the user for the
1151 -- 'Reject the input' action in the collection plan.
1152 -- ntungare Tue Mar 28 08:07:05 PST 2006.
1153 --
1154 CURSOR cur_mesg(p_plan_id NUMBER,p_char_id NUMBER) IS
1155 SELECT message
1156 FROM qa_plan_char_actions
1157 WHERE plan_char_action_trigger_id IN
1158 (SELECT plan_char_action_trigger_id
1159 FROM qa_plan_char_action_triggers
1160 WHERE plan_id = p_plan_id
1161 AND char_id = p_char_id)
1162 AND action_id = 2;
1163
1164 l_mesg varchar2(2000);
1165
1166 BEGIN
1167
1168
1169 --messages should be cleared everytime a Submit is clicked on client
1170 fnd_msg_pub.Initialize();
1171 fnd_msg_pub.reset();
1172
1173 FOR i IN p_errors.FIRST .. p_errors.LAST LOOP
1174 -- Bug 5307450
1175 -- In QWB if the action is 'Reject the input' we were displaying the
1176 -- seeded error message 'QA_API_REJECT_AN_ENTRY' and not the message
1177 -- added in the collection plan setup by the user. Now the following
1178 -- IF condition would get the 'Reject the input' action message from
1179 -- the collection plan and pass it to the token of a seeded meesage.
1180 -- If the action is not 'Reject the input' then the existing code is
1181 -- used.
1182 -- Also a new seeded message has been created with a token as the message
1183 -- description. This token would be replaced with the message added by
1184 -- the user in the collection plan setup for 'Reject the input' action.
1185 -- ntungare Tue Mar 28 08:10:23 PST 2006.
1186 --
1187 IF p_errors(i).error_code = qa_validation_api.reject_an_entry_error then
1188 OPEN cur_mesg(plan_id,p_errors(i).element_id);
1189 FETCH cur_mesg INTO l_mesg;
1190 CLOSE cur_mesg;
1191
1192 l_message_name := g_message_table(p_errors(i).error_code);
1193 l_char_prompt := qa_plan_element_api.get_prompt(plan_id, p_errors(i).element_id);
1194
1195 fnd_message.set_name('QA','QA_API_REJECT_INPUT');
1196 fnd_message.set_token('CHAR_PROMPT', l_char_prompt);
1197 fnd_message.set_token('REJECT_MESSAGE', l_mesg);
1198 fnd_msg_pub.add();
1199 ELSE
1200 l_message_name := g_message_table(p_errors(i).error_code);
1201 l_char_prompt := qa_plan_element_api.get_prompt(plan_id, p_errors(i).element_id);
1202
1203 fnd_message.set_name('QA', l_message_name);
1204 fnd_message.set_token('CHAR_ID', p_errors(i).element_id);
1205 fnd_message.set_token('CHAR_PROMPT', l_char_prompt);
1206 fnd_msg_pub.add();
1207 End If;
1208 END LOOP;
1209
1210 END post_error_messages;
1211
1212 --
1213 -- Used only by QWB and Fwk Integration
1214 -- /qadev/qa/12.0/java/ssqr/server/QualityResultsEOImpl.java
1215 --
1216 -- Pass -1 to p_transaction_number when using standalone.
1217 --
1218 --
1219 -- Bug 6881303
1220 -- added 2 new elements, one a comma separated list of the
1221 -- Parent collection elements that would receive aggregated
1222 -- values and the other a comma separated list of the
1223 -- aggregated values.
1224 -- ntungare Fri Mar 21 01:19:03 PDT 2008
1225 --
1226 FUNCTION ssqr_update_result(
1227 x_occurrence IN NUMBER,
1228 x_org_id IN NUMBER,
1229 x_plan_id IN NUMBER,
1230 x_spec_id IN NUMBER,
1231 x_collection_id IN NUMBER,
1232 x_txn_header_id IN NUMBER,
1233 x_par_plan_id IN NUMBER,
1234 x_par_col_id IN NUMBER,
1235 x_par_occ IN NUMBER,
1236 x_result IN VARCHAR2,
1237 x_result1 IN VARCHAR2, -- R12 Project MOAC 4637896, ID passing
1238 x_result2 IN VARCHAR2, -- not used yet, for future expansion
1239 x_enabled IN INTEGER,
1240 x_committed IN INTEGER,
1241 x_transaction_number IN NUMBER,
1242 x_messages OUT NOCOPY VARCHAR2,
1243 x_agg_elements OUT NOCOPY VARCHAR2,
1244 x_agg_val OUT NOCOPY VARCHAR2,
1245 p_last_update_date IN DATE DEFAULT SYSDATE)
1246 RETURN INTEGER IS
1247 elements qa_validation_api.ElementsArray;
1248 error_array qa_validation_api.ErrorArray;
1249 message_array qa_validation_api.MessageArray;
1250 return_status VARCHAR2(1);
1251 action_result VARCHAR2(1);
1252 msg_count NUMBER;
1253 msg_data VARCHAR2(2000);
1254 y_spec_id NUMBER;
1255 y_collection_id NUMBER;
1256 y_committed VARCHAR2(1);
1257
1258 -- anagarwa Wed May 26 17:07:29 PDT 2004
1259 -- bug 3667449
1260 l_ret_value VARCHAR2(1);
1261
1262 l_esig_status BOOLEAN;
1263
1264 --
1265 -- bug 6729769
1266 -- Record and a collection to get the details of History Child
1267 -- Plan plans for which data has been collected in a Txn
1268 -- ntungare
1269 --
1270 TYPE hist_plan_rec IS RECORD (plan_id NUMBER,
1271 collection_id NUMBER,
1272 occurrence NUMBER);
1273 TYPE hist_plan_tab_typ IS TABLE OF hist_plan_rec INDEX BY binary_integer;
1274 hist_plan_tab hist_plan_tab_typ ;
1275 BEGIN
1276 --messages should be cleared everytime a Submit is clicked on client
1277 fnd_msg_pub.Initialize();
1278 fnd_msg_pub.reset();
1279
1280 --
1281 -- Bug 2617638
1282 -- The original statement returns if x_result IS NULL.
1283 -- Undesirable if caller passes all validated IDs in x_result1.
1284 -- Added AND x_result1 IS NULL
1285 -- bso Tue Oct 8 18:34:38 PDT 2002
1286 --
1287 IF x_result IS NULL AND x_result1 IS NULL THEN
1288 RETURN -1;
1289 END IF;
1290
1291 IF x_committed = 1 THEN
1292 y_committed := fnd_api.g_true;
1293 ELSE
1294 y_committed := fnd_api.g_false;
1295 END IF;
1296
1297 --
1298 -- Some input can be -1, if that's the case, set to null
1299 --
1300 IF x_collection_id = -1 THEN
1301 y_collection_id := NULL;
1302 ELSE
1303 y_collection_id := x_collection_id;
1304 END IF;
1305 IF x_spec_id = -1 THEN
1306 y_spec_id := NULL;
1307 ELSE
1308 y_spec_id := x_spec_id;
1309 END IF;
1310
1311
1312 -- Bug 4502450. esig status support for multirow uqr
1313 -- check for validation before update
1314 -- saugupta Wed, 24 Aug 2005 08:49:45 -0700 PDT
1315 l_esig_status :=
1316 validate_esig_for_update(p_plan_id => x_plan_id,
1317 p_plan_collection_id => x_collection_id,
1318 p_plan_occurrence => x_occurrence);
1319 IF ( NOT l_esig_status ) THEN
1320 RETURN -1;
1321 END IF;
1322
1323
1324 --
1325 -- The flatten string is a representation that looks like this:
1326 --
1327 -- 10=Item@101=Defected@102=20 ...
1328 --
1329 -- namely, it is an @ separated list of charID=value. In case
1330 -- value contains @, then it is doubly encoded.
1331 --
1332 -- First task is to decode this string into the row_element
1333 -- array.
1334 --
1335 elements := qa_validation_api.result_to_array(x_result);
1336 elements := qa_validation_api.id_to_array(x_result1, elements);
1337
1338 IF (x_transaction_number IS NOT NULL) AND (x_transaction_number > 0) THEN
1339 qa_validation_api.set_validation_flag_txn(
1340 x_elements => elements,
1341 p_plan_id => x_plan_id,
1342 p_transaction_number => x_transaction_number,
1343 p_plan_transaction_id => NULL);
1344 END IF;
1345
1346 -- 12.1 QWB Usability Improvements
1347 -- Passing a new parameter p_ssqr_operation to indicate
1348 -- that the processing is being done for QWB application
1349 -- that would ensure that the Row Validation is not done
1350 -- again at the time of the data updation
1351 --
1352 qa_results_pub.update_row(
1353 p_api_version => 1.0,
1354 p_init_msg_list => fnd_api.g_true,
1355 p_commit => y_committed,
1356 p_plan_id => x_plan_id,
1357 p_spec_id => y_spec_id,
1358 p_org_id => x_org_id,
1359 p_transaction_number => x_transaction_number,
1360 p_transaction_id => null,
1361 p_txn_header_id => x_txn_header_id,
1362 p_enabled_flag => x_enabled,
1363 p_collection_id => y_collection_id,
1364 p_occurrence => x_occurrence,
1365 x_row_elements => elements,
1366 x_msg_count => msg_count,
1367 x_msg_data => msg_data,
1368 x_error_array => error_array,
1369 x_message_array => message_array,
1370 x_return_status => return_status,
1371 x_action_result => action_result,
1372 p_ssqr_operation => 1,
1373 p_last_update_date => p_last_update_date);
1374
1375 IF qa_validation_api.no_errors(error_array) THEN
1376
1377 -- anagarwa Fri Jan 23 12:10:04 PST 2004
1378 -- Bug 3384986 Actions for CAR master not fired when child is updated
1379 -- update parent and also update parent txn id so that the actions like
1380 -- sending an email can be fired.
1381 -- NOTE: In SsqrAMImpl.processEqrApply we already call
1382 -- setParentAttributes that recursively updates parent rows with the
1383 -- current txn header id. However, that is done only to set the
1384 -- completed status and it exits once it finds the completed flag for
1385 -- parent row. The following update parent causes some
1386 -- backward relationships to be fired and if there are actions associated
1387 -- with those then they should be fired too. So we set txn header id
1388 -- of the parent records so that actions get fired in
1389 -- qapcb.ssqr_post_commit
1390 IF(QA_PARENT_CHILD_PKG.update_parent(
1391 x_par_plan_id,
1392 x_par_col_id,
1393 x_par_occ,
1394 x_plan_id,
1395 x_collection_id,
1396 x_occurrence,
1397 x_txn_header_id,
1398 x_agg_elements,
1399 x_agg_val
1400 ) = 'T') THEN
1401 NULL;
1402 -- 12.1 QWB Usabiility Improvements
1403 -- Insert the History for Parent if it has been updated
1404 --
1405 -- bug 6936302
1406 -- This is not needed since OAF now calls the update
1407 -- method for the parent row whenever a child record
1408 -- is changed since R12.1 XBuid4 which automatically
1409 -- creates a History child for the parent
1410 -- ntungare
1411 --
1412 /*
1413 if ((x_enabled = 2 or x_enabled is null) AND
1414 x_agg_elements IS NOT NULL) then
1415 qa_parent_child_pkg.insert_history_auto_rec_QWB(
1416 p_plan_id => x_par_plan_id,
1417 p_collection_id => x_par_col_id,
1418 p_occurrence => x_par_occ,
1419 p_organization_id => x_org_id,
1420 p_txn_header_id => x_txn_header_id,
1421 p_relationship_type => 1,
1422 p_data_entry_mode => 4,
1423 x_status => return_status);
1424 end If;
1425 */
1426 END IF;
1427
1428 get_action_messages(message_array, x_plan_id, x_messages);
1429
1430 -- Bug 3536025. Calling new procedure insert_history_auto_rec_QWB
1431 -- instead of insert_history_auto_rec. The new procedure is same as
1432 -- the old one except it doesnot changes child plan's txn_header_id
1433 -- and doesnot fire actions for child plans.
1434 -- srhariha. Wed May 26 22:31:28 PDT 2004.
1435
1436 /*
1437 qa_parent_child_pkg.insert_history_auto_rec_QWB(x_plan_id,
1438 x_txn_header_id,
1439 1,
1440 4);
1441 */
1442
1443 -- Bug 4343758. OA Framework Integration project.
1444 -- Shouldnt create history and automatic for txn scenario.
1445 -- srhariha. Wed May 18 04:34:53 PDT 2005.
1446
1447 -- Bug 3681815. Changing the call to proc below as the signature got
1448 -- changed due to the bug.
1449 -- commenting the previous calls to proc above.
1450 -- saugupta Tue, 15 Jun 2004 05:51:00 -0700 PDT
1451
1452 -- insert history records
1453
1454 if (x_enabled = 2 or x_enabled is null) then
1455 --
1456 -- bug 6729769
1457 -- Check if History Child records already
1458 -- exist for this Txn in which case a new
1459 -- record is not to be created. The existing
1460 -- hist records would be updated.
1461 -- ntungare
1462 --
1463 SELECT b.child_plan_id,
1464 b.child_collection_id,
1465 b.child_occurrence
1466 BULK COLLECT INTO hist_plan_tab
1467 FROM qa_pc_results_relationship b, qa_pc_plan_relationship a
1468 WHERE a.parent_plan_id = x_plan_id
1469 AND a.parent_plan_id = b.parent_plan_id
1470 AND a.child_plan_id = b.child_plan_id
1471 AND a.data_entry_mode = 4
1472 AND b.parent_collection_id = y_collection_id
1473 AND b.parent_occurrence = x_occurrence
1474 AND b.child_txn_header_id = x_txn_header_id;
1475
1476 -- If the Hist plan data not collected then
1477 -- insert the history records
1478 IF (hist_plan_tab.count = 0) THEN
1479 qa_parent_child_pkg.insert_history_auto_rec_QWB(p_plan_id => x_plan_id,
1480 p_collection_id => y_collection_id,
1481 p_occurrence => x_occurrence,
1482 p_organization_id => x_org_id,
1483 p_txn_header_id => x_txn_header_id,
1484 p_relationship_type => 1,
1485 p_data_entry_mode => 4,
1486 x_status => return_status);
1487 ELSE
1488 --
1489 -- bug 6729769
1490 -- for history records that are present we need to
1491 -- update them to ensure that the aggregated values
1492 -- reflect in them
1493 -- ntungare
1494 FOR hist_plan_cntr in 1..hist_plan_tab.count
1495 LOOP
1496 l_ret_value:= QA_PARENT_CHILD_PKG.update_child(x_plan_id,
1497 y_collection_id,
1498 x_occurrence,
1499 hist_plan_tab(hist_plan_cntr).plan_id,
1500 hist_plan_tab(hist_plan_cntr).collection_id,
1501 hist_plan_tab(hist_plan_cntr).occurrence);
1502 END LOOP;
1503 END IF;
1504 end if;
1505
1506
1507
1508 -- anagarwa Wed May 26 17:07:29 PDT 2004
1509 -- bug 3667449
1510 -- if parent copy source element is updated, then update the
1511 -- child too.
1512 -- we need to check and call both the methods because of following
1513 -- scenario. A is parent of B is parent of C is parent of D.
1514 -- Element X is copied from B to C to D. If D is updated and
1515 -- X is updated in B , we want both C and D to be updated.
1516
1517 IF (x_par_occ > 0 ) THEN
1518 l_ret_value:= QA_PARENT_CHILD_PKG.update_child(x_par_plan_id,
1519 x_par_col_id,
1520 x_par_occ,
1521 x_plan_id,
1522 x_collection_id,
1523 x_occurrence);
1524 ELSE
1525 l_ret_value := QA_PARENT_CHILD_PKG.update_all_children(x_plan_id,
1526 x_collection_id, x_occurrence);
1527 END IF;
1528
1529 RETURN 0;
1530 ELSIF return_status <> FND_API.G_RET_STS_ERROR AND
1531 return_status <> FND_API.G_RET_STS_UNEXP_ERROR THEN
1532 get_error_messages(error_array, x_plan_id, x_messages);
1533 END IF;
1534
1535 RETURN -1;
1536
1537 END ssqr_update_result;
1538
1539 -- bug 5306909
1540 -- Added p_last_update_date parameter. This parameter is used
1541 -- to check whether the record which the user is trying to
1542 -- update has been updated already by some other user.
1543 -- ntungare Mon Apr 10 07:03:13 PDT 2006
1544 --
1545 FUNCTION ssqr_lock_row (
1546 p_occurrence IN NUMBER,
1547 p_plan_id IN NUMBER,
1548 p_last_update_date IN DATE,
1549 x_status OUT NOCOPY VARCHAR2)
1550 RETURN INTEGER IS
1551
1552 l_occurrence NUMBER;
1553
1554 -- Bug 5306909
1555 -- Modified the cursor definition to fetch the
1556 -- last_update_date
1557 -- ntungare Mon Apr 10 07:03:13 PDT 2006
1558 --
1559 CURSOR upd_cur IS
1560 SELECT occurrence, last_update_date
1561 FROM qa_results
1562 WHERE occurrence = p_occurrence
1563 AND plan_id = p_plan_id
1564 FOR UPDATE NOWAIT;
1565
1566 -- Bug 5306909
1567 -- New variable to get the last_update_date
1568 -- ntungare Mon Apr 10 07:03:13 PDT 2006
1569 --
1570 l_last_update_date DATE;
1571
1572 BEGIN
1573
1574 x_status := '1';
1575 OPEN upd_cur;
1576
1577 --
1578 -- Bug 5306909
1579 -- Modified the Fetch statement to fetch
1580 -- the last_update_date
1581 -- ntungare Mon Apr 10 07:15:42 PDT 2006
1582 --
1583 FETCH upd_cur INTO l_occurrence, l_last_update_date;
1584
1585 IF (upd_cur%NOTFOUND) THEN
1586 RETURN -1;
1587 END IF;
1588
1589 CLOSE upd_cur;
1590
1591 -- bug 5306909
1592 -- If the p_last_update_date is not equal to what is
1593 -- there in the database (l_last_update_date) then it
1594 -- means the record has been updated by some other user.
1595 -- So we return -1, to QualityResultsEOImpl.java which
1596 -- would display the seeded QA_SSQR_LOCK_FAILED error
1597 -- message.
1598 -- ntungare Mon Apr 10 07:06:39 PDT 2006
1599 --
1600 IF (p_last_update_date <> l_last_update_date) THEN
1601 RETURN -1;
1602 END IF;
1603
1604 RETURN 1;
1605
1606 EXCEPTION when others then
1607 IF upd_cur%ISOPEN THEN
1608 CLOSE upd_cur;
1609 RETURN -1;
1610 ELSE
1611 RETURN -1;
1612 END IF;
1613 --raise;
1614
1615 END ssqr_lock_row;
1616
1617
1618 --
1619 -- Removed procedure wb_set_valid_flag entirely because
1620 -- the new qa_validation_api.set_validation_flag_txn is a superset.
1621 --
1622
1623 --
1624 -- Used only by QWB and Fwk Integration
1625 -- /qadev/qa/12.0/java/ssqr/server/QualityResultsEOImpl.java
1626 --
1627 -- Pass -1 to p_transaction_number when using standalone.
1628 --
1629 -- 12.1 QWB Usability Improvement
1630 -- Added 2 new parameters x_charid_str and x_id_str
1631 -- TO return the list of Id values for the HC elements
1632 --
1633 FUNCTION ssqr_validate_row (
1634 p_occurrence IN OUT NOCOPY NUMBER,
1635 p_org_id IN NUMBER,
1636 p_plan_id IN NUMBER,
1637 p_spec_id IN NUMBER,
1638 p_collection_id IN NUMBER,
1639 p_result IN VARCHAR2,
1640 p_result1 IN VARCHAR2, -- R12 Project MOAC 4637896, ID passing
1641 p_result2 IN VARCHAR2, -- not used yet, for future expansion
1642 p_enabled IN INTEGER,
1643 p_committed IN INTEGER,
1644 p_transaction_number IN NUMBER,
1645 p_transaction_id IN NUMBER DEFAULT 0,
1646 x_messages OUT NOCOPY VARCHAR2,
1647 x_charid_str OUT NOCOPY VARCHAR2,
1648 x_id_str out NOCOPY VARCHAR2)
1649 RETURN INTEGER IS
1650
1651 elements qa_validation_api.ElementsArray;
1652 error_array qa_validation_api.ErrorArray;
1653 l_results_array qa_validation_api.ResultRecordArray;
1654 l_message_array qa_validation_api.MessageArray;
1655
1656 --
1657 -- Bug 5932426
1658 -- Checing if the Txn is an update Txn or an
1659 -- Insert Txn. If the txn is update, then the
1660 -- Plan_id - Collection_id - Occurrence combination
1661 -- would be present in the QA_RESULTS table.
1662 -- ntungare Sat Apr 14 00:53:40 PDT 2007
1663 --
1664 Cursor C1 is
1665 Select 1 from QA_RESULTS
1666 WHERE plan_id = p_plan_id
1667 and collection_id = p_collection_id
1668 and occurrence = p_occurrence;
1669
1670 update_txn PLS_INTEGER := 0;
1671
1672 -- 12.1 QWB Usability Improvements
1673 --
1674 id_ctr Number;
1675 charid_str VARCHAR2(4000);
1676 id_str VARCHAR2(4000);
1677
1678
1679 BEGIN
1680
1681 --clearing cache so that errors are not shown over and over again.
1682 fnd_msg_pub.Initialize();
1683 fnd_msg_pub.reset();
1684 elements := qa_validation_api.result_to_array(p_result);
1685 elements := qa_validation_api.id_to_array(p_result1, elements);
1686
1687 --
1688 -- Bug 5932426
1689 -- Updating the validation flag only if the
1690 -- Txn is an update txn
1691 -- ntungare Sat Apr 14 00:55:08 PDT 2007
1692 --
1693 Open C1;
1694 Fetch C1 into update_txn;
1695 Close C1;
1696
1697 If update_txn = 1 then
1698 update_validation_flg(elements,
1699 p_plan_id,
1700 p_collection_id,
1701 p_occurrence);
1702 update_txn := 0;
1703 End If;
1704
1705 --
1706 -- Replaced the following by set_validation_flag_txn which
1707 -- is a superset of wb_set_valid_flag.
1708 --
1709 -- Bug 4519558. OA Framework Integration project. UT bug fix.
1710 -- Set validation flag.
1711 -- srhariha. Tue Aug 2 22:38:59 PDT 2005.
1712 -- wb_set_valid_flag(p_elements => elements,
1713 -- p_transaction_number => p_transaction_number);
1714 --
1715 IF (p_transaction_number IS NOT NULL) AND (p_transaction_number > 0) THEN
1716 qa_validation_api.set_validation_flag_txn(
1717 x_elements => elements,
1718 p_plan_id => p_plan_id,
1719 p_transaction_number => p_transaction_number,
1720 p_plan_transaction_id => NULL);
1721 END IF;
1722
1723 -- 12.1 QWB Usability Improvements
1724 -- Passing the value for the P_ssqr_operation flag as
1725 -- 1 to indicate that the online actions firing is
1726 -- not be done
1727 --
1728 error_array := qa_validation_api.validate_row(p_plan_id,
1729 p_spec_id, p_org_id, fnd_global.user_id, p_transaction_number,
1730 p_transaction_id, l_results_array, l_message_array,
1731 elements, 1);
1732
1733 -- 12.1 QWB Usability Improvements
1734 -- If the IDs values are present for HC elements then
1735 -- the build a string of the Id elements
1736 id_ctr := l_results_array.first;
1737 while id_ctr <= l_results_array.last
1738 loop
1739 If l_results_array(id_ctr).id IS NOT NULL THEN
1740 -- Append the HC element column name to the char id string
1741 charid_str := charid_str ||
1742 qa_chars_api.hardcoded_column(l_results_array(id_ctr).element_id)||
1743 ',';
1744 -- Append the Id value to Normalized id string
1745 id_str := id_str || l_results_array(id_ctr).id||',';
1746 End If;
1747 id_ctr := l_results_array.next(id_ctr);
1748 end loop;
1749
1750 If charid_str IS NOT NULL THEN
1751 charid_str := LTRIM(RTRIM(charid_str,','),',');
1752 id_str := LTRIM(RTRIM(id_str,','),',');
1753 End If;
1754
1755 x_charId_str := charid_str;
1756 x_Id_str := id_str;
1757
1758 -- End of 12.1 QWB Usability Improvements
1759
1760 IF qa_validation_api.no_errors(error_array) THEN
1761 get_action_messages(l_message_array, p_plan_id, x_messages);
1762 RETURN 0;
1763 ELSE
1764 get_error_messages(error_array, p_plan_id, x_messages);
1765 post_error_messages(error_array, p_plan_id);
1766 END IF;
1767
1768 RETURN -1;
1769 END ssqr_validate_row;
1770
1771 --
1772 -- Delete a result.
1773 --
1774 PROCEDURE delete_result(
1775 x_plan_id IN NUMBER,
1776 x_collection_id IN NUMBER,
1777 x_occurrence IN NUMBER) IS
1778 BEGIN
1779 DELETE FROM qa_results
1780 WHERE plan_id = x_plan_id AND
1781 collection_id = x_collection_id AND
1782 occurrence = x_occurrence;
1783 END delete_result;
1784
1785 --
1786 -- Batch delete a set of results (supply occurrences in
1787 -- comma-separated list.)
1788 --
1789 PROCEDURE delete_results(
1790 x_plan_id IN NUMBER,
1791 x_collection_id IN NUMBER,
1792 x_occurrences IN VARCHAR2) IS
1793
1794 c_key CONSTANT VARCHAR2(30) := 'QA_SS_RESULTS.DELETE_RESULTS';
1795
1796 BEGIN
1797 --
1798 -- For SQL Bind Compliance, change dynamic SQL to
1799 -- static using qa_performance_temp table
1800 -- bso Sat Oct 1 13:03:17 PDT 2005
1801 --
1802 qa_performance_temp_pkg.add_ids(c_key, x_occurrences);
1803
1804 DELETE FROM qa_results
1805 WHERE plan_id = x_plan_id AND
1806 collection_id = x_collection_id AND
1807 occurrence IN
1808 (SELECT id
1809 FROM qa_performance_temp
1810 WHERE key = c_key);
1811
1812 qa_performance_temp_pkg.purge(c_key);
1813 END delete_results;
1814
1815 --
1816 -- Perform database commit. Do not use in transaction integration,
1817 -- otherwise we will be committing the parent's data without their
1818 -- knowing! Actions will be fired in the background.
1819 --
1820 PROCEDURE commit_results IS
1821 BEGIN
1822 commit;
1823 --
1824 -- work on action later.
1825 --
1826 END commit_results;
1827
1828 PROCEDURE wrapper_fire_action (
1829 q_collection_id IN NUMBER,
1830 q_return_status OUT NOCOPY VARCHAR2,
1831 q_msg_count OUT NOCOPY NUMBER,
1832 q_msg_data OUT NOCOPY VARCHAR2)
1833 IS
1834
1835 BEGIN
1836
1837 qa_results_pub.enable_and_fire_action (
1838 p_api_version => 1.0,
1839 p_commit => FND_API.G_TRUE,
1840 p_collection_id => q_collection_id,
1841 x_return_status => q_return_status,
1842 x_msg_count => q_msg_count,
1843 x_msg_data => q_msg_data);
1844
1845 END wrapper_fire_action;
1846
1847
1848 PROCEDURE GET_COLLECTION_ID (x_collection_id OUT NOCOPY NUMBER)
1849 IS
1850 CURSOR cid_cur IS
1851 SELECT QA_COLLECTION_ID_S.NEXTVAL FROM DUAL;
1852 BEGIN
1853 OPEN cid_cur;
1854 FETCH cid_cur INTO x_collection_id;
1855 CLOSE cid_cur;
1856
1857 EXCEPTION when others then
1858 IF cid_cur%ISOPEN THEN
1859 CLOSE cid_cur;
1860 END IF;
1861 raise;
1862 END GET_COLLECTION_ID;
1863
1864
1865 -- Bug 4502450. R12 eSig Status functionality for PENDING Status
1866 -- function checks for eSignature elements present for current
1867 -- plan as well as for all the parent plans
1868 -- if status is not pending i.e if update is allowed by any means
1869 -- returns TRUE else returns FALSE
1870 -- sets the message if eSig Status is PENDING for any row for
1871 -- the current plan relationship
1872 -- saugupta Wed, 24 Aug 2005 08:50:00 -0700 PDT
1873 --
1874 -- Reformatted indentation and cases to make it easier
1875 -- to read. Syntactically equivalent to previous revision.
1876 -- bso Sat Oct 1 13:16:08 PDT 2005
1877
1878 FUNCTION validate_esig_for_update(
1879 p_plan_id IN NUMBER,
1880 p_plan_collection_id IN NUMBER,
1881 p_plan_occurrence IN NUMBER)
1882 RETURN BOOLEAN
1883 IS
1884 l_eres_profile VARCHAR2(3);
1885 l_esig_status VARCHAR(20);
1886 l_par_esig_status VARCHAR(20);
1887 l_ancestors_exists VARCHAR(1);
1888 i NUMBER;
1889 parent_plan_ids dbms_sql.number_table;
1890 parent_collection_ids dbms_sql.number_table;
1891 parent_occurrences dbms_sql.number_table;
1892
1893 BEGIN
1894
1895 l_eres_profile := fnd_profile.value('EDR_ERES_ENABLED');
1896 -- Check if the profile is on if not return TRUE
1897 IF ( l_eres_profile IS NULL OR l_eres_profile = 'N' ) THEN
1898 RETURN TRUE;
1899 END IF;
1900
1901
1902 -- check if eSig Status is pending for current plan
1903 l_esig_status := qa_eres_util.is_esig_status_pending(
1904 p_plan_id => p_plan_id ,
1905 p_collection_id => p_plan_collection_id,
1906 p_occurrence => p_plan_occurrence);
1907
1908
1909 IF ( l_esig_status = 'T' ) THEN
1910 -- current plan has eSig status as PENDING
1911 -- fill the error array and return
1912 fnd_message.set_name('QA', 'QA_ERES_CANNOT_UPDATE_RESULT');
1913 fnd_msg_pub.add();
1914 RETURN FALSE;
1915 END IF; -- l_esig_status = T
1916 -- esig status is false for child plan
1917 -- check esig status in ancestor plans
1918 -- before check if ancestor plans exists
1919
1920 l_ancestors_exists := qa_parent_child_pkg.get_ancestors(
1921 p_child_plan_id => p_plan_id,
1922 p_child_occurrence => p_plan_occurrence,
1923 p_child_collection_id => p_plan_collection_id,
1924 x_parent_plan_ids => parent_plan_ids,
1925 x_parent_collection_ids => parent_collection_ids,
1926 x_parent_occurrences => parent_occurrences);
1927 -- if ancestors does not exists, meaning record is updateable
1928 IF ( l_ancestors_exists = 'F' ) THEN
1929 RETURN TRUE;
1930 END IF;
1931
1932 -- if not, we need to check esig Status for all ancestors
1933 i := parent_occurrences.FIRST;
1934 l_par_esig_status := 'F';
1935 WHILE i IS NOT NULL LOOP
1936 l_par_esig_status := qa_eres_util.is_esig_status_pending(
1937 p_plan_id => parent_plan_ids(i) ,
1938 p_collection_id => parent_collection_ids(i),
1939 p_occurrence => parent_occurrences(i));
1940 EXIT WHEN l_par_esig_status = 'T';
1941 i := parent_occurrences.NEXT(i);
1942 END LOOP; -- while i is not null
1943
1944 IF ( l_par_esig_status = 'F' ) THEN -- no parent has status pending
1945 RETURN TRUE;
1946 END IF;
1947 -- current plan ancestors has eSig status as PENDING
1948 -- fill the error array and return
1949 fnd_message.set_name('QA', 'QA_ERES_CANNOT_UPDATE_RESULT');
1950 fnd_msg_pub.add();
1951 return FALSE;
1952
1953 END validate_esig_for_update;
1954
1955 -- bug 4658275. eSig functionality support in QWB
1956 -- this new method checks if user can insert a new
1957 -- child row if ERES is enables
1958 -- saugupta Tue, 18 Oct 2005 02:55:19 -0700 PDT
1959 FUNCTION validate_esig_for_insert(p_plan_id IN NUMBER,
1960 p_plan_collection_id IN NUMBER,
1961 p_plan_occurrence IN NUMBER)
1962 RETURN BOOLEAN
1963 IS
1964 l_eres_profile VARCHAR2(3);
1965 l_esig_status VARCHAR(20);
1966 l_par_esig_status VARCHAR(20);
1967 l_ancestors_exists VARCHAR(1);
1968 i NUMBER;
1969 parent_plan_ids dbms_sql.number_table;
1970 parent_collection_ids dbms_sql.number_table;
1971 parent_occurrences dbms_sql.number_table;
1972
1973 BEGIN
1974
1975 l_eres_profile := FND_PROFILE.VALUE('EDR_ERES_ENABLED');
1976 -- Check if the profile is on if not return TRUE
1977 IF ( l_eres_profile IS NULL OR l_eres_profile = 'N' ) THEN
1978 return TRUE;
1979 END IF;
1980
1981 -- check if eSig Status is pending for parent plan
1982 -- in the method we are passing the parent plan id's
1983 -- as we can add a new row with eSignature status
1984 -- is pending but not when eSig Status is pending
1985 -- for the parnet plan
1986
1987 l_esig_status :=
1988 QA_ERES_UTIL.is_esig_status_pending(p_plan_id => p_plan_id ,
1989 p_collection_id => p_plan_collection_id,
1990 p_occurrence => p_plan_occurrence);
1991
1992
1993 IF ( l_esig_status = 'T' ) THEN
1994 -- current plan has eSig status as PENDING
1995 -- fill the error array and return
1996 fnd_message.set_name('QA', 'QA_ERES_CANNOT_ENTER_CHILD');
1997 fnd_msg_pub.add();
1998 return FALSE;
1999 END IF; -- l_esig_status = T
2000
2001
2002 -- esig status is false for child plan
2003 -- check esig status in ancestor plans
2004 -- before check if ancestor plans exists
2005 l_ancestors_exists :=
2006 QA_PARENT_CHILD_PKG.get_ancestors(p_child_plan_id => p_plan_id,
2007 p_child_occurrence => p_plan_occurrence,
2008 p_child_collection_id => p_plan_collection_id,
2009 x_parent_plan_ids => parent_plan_ids,
2010 x_parent_collection_ids => parent_collection_ids,
2011 x_parent_occurrences => parent_occurrences);
2012 -- if ancestors does not exists, meaning record can be inserted
2013
2014 IF ( l_ancestors_exists = 'F' ) THEN
2015 return TRUE;
2016 END IF;
2017
2018 -- if not, we need to check esig Status for all ancestors
2019 i := parent_occurrences.FIRST;
2020 l_par_esig_status := 'F';
2021 WHILE i IS NOT NULL
2022 LOOP
2023 l_par_esig_status :=
2024 QA_ERES_UTIL.is_esig_status_pending(p_plan_id => parent_plan_ids(i) ,
2025 p_collection_id => parent_collection_ids(i),
2026 p_occurrence => parent_occurrences(i));
2027 EXIT WHEN l_par_esig_status = 'T';
2028 i := parent_occurrences.NEXT(i);
2029 END LOOP; -- while i is not null
2030
2031 IF ( l_par_esig_status = 'F' ) THEN -- no parent has status pending
2032 return TRUE;
2033 END IF;
2034 -- current plan ancestors has eSig status as PENDING
2035 -- fill the error array and return
2036 fnd_message.set_name('QA', 'QA_ERES_CANNOT_ENTER_CHILD');
2037 fnd_msg_pub.add();
2038 return FALSE;
2039
2040 END validate_esig_for_insert;
2041
2042 -- R12.1 QWB Usability Improvements project
2043 -- Function to perform deletetion of rows
2044 --
2045 FUNCTION delete_row(p_plan_id IN NUMBER,
2046 p_collection_id IN NUMBER,
2047 p_occurrence IN NUMBER,
2048 p_org_id IN NUMBER,
2049 p_txn_header_id IN NUMBER,
2050 p_par_plan_id IN NUMBER DEFAULT -1,
2051 p_par_col_id IN NUMBER DEFAULT -1,
2052 p_par_occ IN NUMBER DEFAULT -1)
2053 RETURN VARCHAR2 AS
2054 delete_api_ret_val VARCHAR2(1);
2055 insert_api_ret_val VARCHAR2(1);
2056 CURSOR check_agg_rel_cur IS
2057 SELECT 1
2058 FROM qa_pc_result_columns_v
2059 WHERE parent_plan_id = p_par_plan_id
2060 AND child_plan_id = p_plan_id
2061 AND element_relationship_type in (2,3,4,5,6,7,8)
2062 AND parent_enabled_flag = 1
2063 AND child_enabled_flag = 1;
2064
2065 agg_rel_flag NUMBER;
2066 BEGIN
2067 delete_api_ret_val := QA_PARENT_CHILD_PKG.delete_row (
2068 p_plan_id => p_plan_id,
2069 p_collection_id => p_collection_id,
2070 p_occurrence => p_occurrence);
2071
2072 -- Check for successful deletion
2073 IF (delete_api_ret_val = 'T') THEN
2074 -- Check if a parent record exists for the current record
2075 -- and if an aggregate relationship exists between then in which
2076 -- case History record needs to be created for the parent
2077 --
2078 IF (p_par_plan_id <> -1 AND
2079 p_par_col_id <> -1 AND
2080 p_par_occ <> -1) THEN
2081
2082 OPEN check_agg_rel_cur;
2083 FETCH check_agg_rel_cur INTO agg_rel_flag;
2084 CLOSE check_agg_rel_cur;
2085
2086 IF (agg_rel_flag = 1) THEN --Aggregate relation exists
2087 -- Hence insert history record for the parent
2088 -- as the deletion of the child record would
2089 -- impact the aggregated value on the parent.
2090 qa_parent_child_pkg.insert_history_auto_rec_QWB(
2091 p_plan_id => p_par_plan_id,
2092 p_collection_id => p_par_col_id,
2093 p_occurrence => p_par_occ,
2094 p_organization_id => p_org_id,
2095 p_txn_header_id => p_txn_header_id,
2096 p_relationship_type => 1,
2097 p_data_entry_mode => 4,
2098 x_status => insert_api_ret_val);
2099 END IF;
2100 END IF;
2101 END IF;
2102
2103 RETURN 'T';
2104 END;
2105
2106 --anagarwa 3197700 Wed Oct 15 17:38:56 PDT 2003
2107
2108 BEGIN
2109
2110 populate_message_table;
2111 END qa_ss_results;