1 PACKAGE BODY ENG_NIR_UTIL_PKG AS
2 /* $Header: ENGNIRB.pls 120.20 2007/07/16 12:12:06 sdarbha ship $ */
3 PROCEDURE set_nir_item_approval_status (
4 p_change_id IN NUMBER,
5 p_approval_status IN NUMBER,
6 x_return_status OUT NOCOPY VARCHAR2,
7 x_msg_count OUT NOCOPY NUMBER,
8 x_msg_data OUT NOCOPY VARCHAR2) IS
9
10 type item_id_col is table of NUMBER;
11 type appr_status_col is table of VARCHAR2(1);
12 type org_id_col is table of NUMBER;
13
14 l_items_array item_id_col;
15 l_appr_statuses_array appr_status_col;
16 l_org_id_array org_id_col ;
17 l_approval_status VARCHAR2(1);
18 l_ret_item_app_st INTEGER;
19
20 BEGIN
21 x_return_status := FND_API.G_RET_STS_SUCCESS;
22 IF p_approval_status = 1 THEN
23 l_approval_status := 'N';
24 ELSIF p_approval_status = 3 THEN
25 l_approval_status := 'S';
26 ELSIF p_approval_status IN (4, 8) THEN
27 l_approval_status := 'R';
28 ELSIF p_approval_status IN (5) THEN
29 l_approval_status := 'A';
30 END IF;
31 --IF p_approval_status IN (1,3,4, 8) THEN
32
33 Select sub.pk1_value,
34 sub.pk2_value
35 BULK COLLECT into l_items_array,
36 l_org_id_array
37 from eng_change_subjects sub ,
38 eng_change_lines lines
39 where lines.change_id = p_change_id
40 and lines.change_id = sub.change_id
41 and lines.change_line_id = sub.change_line_id
42 and lines.STATUS_CODE not in (G_ENG_NEW_ITEM_REJECTED, G_ENG_NEW_ITEM_CANCELLED)
43 and entity_name='EGO_ITEM';
44 -- ELSIF p_approval_status = 5 THEN
45
46 /* Select sub.pk1_value,
47 sub.pk2_value
48 BULK COLLECT into l_items_array,
49 l_org_id_array
50 -- l_appr_statuses_array
51 from eng_change_subjects sub ,
52 eng_change_lines lines
53 where lines.change_id = p_change_id
54 and lines.change_id = sub.change_id
55 and lines.STATUS_CODE not in (5, 14)
56 and entity_name='EGO_ITEM';*/
57
58 -- END IF;
59 for i in l_items_array.FIRST .. l_items_array.LAST
60 LOOP
61 --IF p_approval_status IN (1,3,4, 8) then
62
63 -- l_ret_item_app_st := EGO_ITEM_PUB.UPDATE_ITEM_APPROVAL_STATUS(l_items_array(i),
64 EGO_ITEM_PUB.UPDATE_ITEM_APPROVAL_STATUS(l_items_array(i),
65 l_org_id_array(i),
66 l_approval_status,
67 p_change_id);
68 IF p_approval_status IN (4,8) THEN
69 UPDATE eng_change_lines
70 SET STATUS_CODE = G_ENG_NEW_ITEM_REJECTED
71 WHERE change_id = p_change_id
72 AND status_CODE not in(G_ENG_NEW_ITEM_REJECTED,G_ENG_NEW_ITEM_CANCELLED);
73 ELSIF p_approval_status = 3 THEN
74 UPDATE eng_change_lines
75 SET STATUS_CODE = G_ENG_NEW_ITEM_SFA
76 WHERE change_id = p_change_id
77 AND status_CODE not in(G_ENG_NEW_ITEM_REJECTED,G_ENG_NEW_ITEM_CANCELLED);
78 ELSIF p_approval_status IN (5) THEN
79 UPDATE eng_change_lines
80 SET STATUS_CODE = G_ENG_NEW_ITEM_APPROVED
81 WHERE change_id = p_change_id
82 AND status_CODE not in(G_ENG_NEW_ITEM_REJECTED,G_ENG_NEW_ITEM_CANCELLED);
83
84 END IF;
85
86 /* ELSIF p_approval_status = 5 THEN
87
88 UPDATE_ITEM_APPROVAL_STATUS(l_items_array(i),
89 l_org_id_array(i),
90 l_approval_status); */
91
92 -- END IF;
93 END LOOP;
94
95
96 EXCEPTION WHEN others THEN
97
98 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR ;
99 /*FND_MESSAGE.Set_Name('ENG','ENG_ERROR_CALLING_PS_API');
100 FND_MESSAGE.Set_Token('OBJECT_NAME', 'EGO_ITEM_PUB.UPDATE_ITEM_APPROVAL_STATUS '||'itemId: '||l_item_id||' OrgId: '||l_organization_id|| ' approvalStstus: '||l_approval_status);
101 FND_MSG_PUB.Add;*/
102
103 END set_nir_item_approval_status;
104
105 PROCEDURE Cancel_NIR(
106 p_change_id IN NUMBER,
107 p_org_id IN NUMBER,
108 p_change_notice IN VARCHAR2,
109 p_auto_commit IN VARCHAR2,
110 -- p_item_action IN VARCHAR2 DEFAULT NULL,
111 p_wf_user_id IN NUMBER,
112 p_fnd_user_id IN NUMBER,
113 p_cancel_comments IN VARCHAR2,
114 p_check_security IN BOOLEAN DEFAULT TRUE,
115 x_nir_cancel_status OUT NOCOPY VARCHAR2
116 )
117 IS
118 l_wf_item_type VARCHAR2(8);
119 l_wf_item_key VARCHAR2(240);
120 l_wf_process_name VARCHAR2(30);
121 l_return_status VARCHAR2(1);
122 l_msg_count NUMBER ;
123 l_msg_data VARCHAR2(200);
124 l_action_id eng_change_actions.action_id%TYPE;
125 l_chk_fn_ret_val VARCHAR2(10);
126 l_party_id NUMBER;
127 l_inventory_item_id VARCHAR2(100); -- ENG_CHANGE_SUBJECTS.PK1_VALUE
128 l_organization_id VARCHAR2(100); -- ENG_CHANGE_SUBJECTS.PK2_VALUE
129
130 BEGIN
131
132 x_nir_cancel_status := 'TRUE';
133 -- First check whether user has edit privilege on this change or not.
134 SELECT PERSON_ID into l_party_id FROM EGO_PEOPLE_V WHERE USER_ID = p_wf_user_id;
135 /*
136 IF p_check_security = TRUE THEN
137 l_chk_fn_ret_val := EGO_DATA_SECURITY.check_function
138 (
139 p_api_version=>1.0,
140 p_function => 'ENG_EDIT_CHANGE',
141 p_object_name => 'ENG_CHANGE',
142 p_instance_pk1_value => p_change_id,
143 -- p_instance_pk2_value => p_instance_pk2_value,
144 -- p_instance_pk3_value => p_instance_pk3_value,
145 -- p_instance_pk4_value => p_instance_pk4_value,
146 -- p_instance_pk5_value => p_instance_pk5_value,
147 p_user_name => 'HZ_PARTY:' || l_party_id
148 );
149
150 -- If the User does not have direct roles for Editing this NIR, We have to check for Inherited roles.
151 IF NOT 'T' = l_chk_fn_ret_val THEN
152 -- Get the Inventory Item Id and Organization Id of the Item
153 SELECT PK1_VALUE, PK2_VALUE INTO l_inventory_item_id, l_organization_id
154 FROM ENG_CHANGE_SUBJECTS
155 WHERE ENTITY_NAME = 'EGO_ITEM' AND CHANGE_ID = p_change_id;
156
157 l_chk_fn_ret_val := EGO_DATA_SECURITY.check_inherited_function
158 (
159 p_api_version => 1.0,
160 p_function => 'ENG_EDIT_CHANGE',
161 p_object_name => 'ENG_CHANGE',
162 p_instance_pk1_value => p_change_id,
163 -- p_instance_pk2_value => p_org_id,
164 -- p_instance_pk3_value => p_instance_pk3_value,
165 -- p_instance_pk4_value => p_instance_pk4_value,
166 -- p_instance_pk5_value => p_instance_pk5_value,
167 p_user_name => 'HZ_PARTY:' || l_party_id,
168 p_object_type => 'NEW_ITEM_REQUEST',
169 p_parent_object_name => 'EGO_ITEM',
170 p_parent_instance_pk1_value => l_inventory_item_id,
171 p_parent_instance_pk2_value => l_organization_id
172 -- p_parent_instance_pk3_value => p_parent_instance_pk3_value,
173 -- p_parent_instance_pk4_value => p_parent_instance_pk4_value,
174 -- p_parent_instance_pk5_value => p_parent_instance_pk5_value
175 );
176 END IF;
177 ELSE
178 l_chk_fn_ret_val := 'T';
179 END IF;
180
181 IF NOT 'T' = l_chk_fn_ret_val THEN
182 x_nir_cancel_status := 'ACCESS_DENIED';
183 RETURN;
184 END IF;
185 */
186 BEGIN
187 -- First check whether any workflow is running for this NIR.
188 -- If running, then abort the workflow.
189 SELECT WF_ITEM_TYPE, WF_ITEM_KEY, WF_PROCESS_NAME
190 INTO l_wf_item_type, l_wf_item_key, l_wf_process_name
191 FROM ENG_CHANGE_ROUTES WHERE OBJECT_ID1 = p_change_id AND status_code = 'IN_PROGRESS';
192
193 IF SQL%FOUND THEN
194
195 Eng_Workflow_Util.AbortWorkflow
196 (
197 p_api_version => 1.0
198 , p_init_msg_list => FND_API.G_FALSE
199 , p_commit => p_auto_commit
200 , p_validation_level => FND_API.G_VALID_LEVEL_FULL
201 , x_return_status => l_return_status
202 , x_msg_count => l_msg_count
203 , x_msg_data => l_msg_data
204 , p_item_type => l_wf_item_type
205 , p_item_key => l_wf_item_key
206 , p_process_name => l_wf_process_name
207 , p_wf_user_id => p_wf_user_id
208 , p_debug => FND_API.G_FALSE
209 , p_output_dir => NULL
210 , p_debug_filename => 'Eng_ChangeWF_Abort.log'
211 );
212
213 END IF;
214
215 EXCEPTION
216 WHEN NO_DATA_FOUND THEN
217 NULL;
218 END;
219 -- Cancel the NIR
220 ENG_CANCEL_ECO.Cancel_Eco
221 (
222 org_id => p_org_id,
223 change_order => p_change_notice,
224 user_id => p_wf_user_id,
225 login => p_fnd_user_id
226 );
227
228 -- We need to set the status of the NIR Manually. Even in the UI flow it is set manually.
229 UPDATE ENG_ENGINEERING_CHANGES
230 SET STATUS_TYPE = 5, STATUS_CODE = 5, CANCELLATION_DATE = sysdate, CANCELLATION_COMMENTS = p_cancel_comments
231 WHERE CHANGE_ID = p_change_id;
232
233 x_nir_cancel_status := 'TRUE';
234
235 -- Create action log entries for the Cancel action.
236 ENG_CHANGE_ACTIONS_UTIL.Create_Change_Action
237 (
238 p_api_version => 1.0,
239 p_init_msg_list => FND_API.G_TRUE,
240 p_commit => FND_API.G_FALSE,
241 p_validation_level => FND_API.G_VALID_LEVEL_FULL,
242 p_debug => FND_API.G_FALSE,
243 p_output_dir => '',
244 p_debug_filename => '',
245 x_return_status => l_return_status,
246 x_msg_count => l_msg_count,
247 x_msg_data => l_msg_data,
248 p_object_id1 => p_change_id,
249 p_object_id2 => NULL,
250 p_object_name => 'ENG_CHANGE',
251 p_action_type => 'CANCEL',
252 p_parent_action_id => -1,
253 p_change_description => p_cancel_comments,
254 x_change_action_id => l_action_id
255 );
256
257 EXCEPTION
258 WHEN OTHERS THEN
259 x_nir_cancel_status := 'FALSE';
260
261 END Cancel_NIR;
262
263
264 PROCEDURE Cancel_NIR_FOR_ITEM(
265 p_item_id IN NUMBER,
266 p_org_id IN NUMBER,
267 -- p_item_number IN VARCHAR2,
268 p_auto_commit IN VARCHAR2,
269 -- p_mode IN VARCHAR2,
270 p_wf_user_id IN NUMBER,
271 p_fnd_user_id IN NUMBER,
272 p_cancel_comments IN VARCHAR2,
273 p_check_security IN BOOLEAN DEFAULT TRUE,
274 x_nir_cancel_status OUT NOCOPY VARCHAR2
275 )
276
277 IS
278 l_uncancelled_change_id NUMBER;
279 CURSOR c_nirs_for_this_item IS
280 SELECT A.CHANGE_ID, B.CHANGE_NOTICE
281 FROM ENG_CHANGE_SUBJECTS A,
282 ENG_ENGINEERING_CHANGES B,
283 ENG_CHANGE_LINES LINES
284 WHERE A.PK1_VALUE = p_item_id
285 AND A.PK2_VALUE = p_org_id
286 AND A.ENTITY_NAME = 'EGO_ITEM'
287 AND A.CHANGE_LINE_ID = LINES.CHANGE_LINE_ID
288 AND LINES.CHANGE_ID = B.CHANGE_ID
289 AND A.CHANGE_ID = B.CHANGE_ID
290 AND LINES.STATUS_CODE NOT IN (G_ENG_NEW_ITEM_CANCELLED, G_ENG_NEW_ITEM_REJECTED);
291
292 l_chk_fn_ret_val VARCHAR2(10);
293 l_party_id NUMBER;
294 l_cancel_comments VARCHAR2(32767);
295
296 BEGIN
297 -- p_check_security := TRUE;
298 SELECT PERSON_ID into l_party_id FROM EGO_PEOPLE_V WHERE USER_ID = p_wf_user_id;
299
300 -- Query all the NIRs for this Item in this Organization and Cancel them.
301 FOR nirs IN c_nirs_for_this_item
302 LOOP
303
304 -- First check whether the user has cancel/edit privilege to cancel the line or NIR
305 IF p_check_security = TRUE THEN
306 l_chk_fn_ret_val := EGO_DATA_SECURITY.check_function
307 (
308 p_api_version=>1.0,
309 p_function => 'ENG_EDIT_CHANGE',
310 p_object_name => 'ENG_CHANGE',
311 p_instance_pk1_value => nirs.change_id,
312 -- p_instance_pk2_value => p_instance_pk2_value,
313 -- p_instance_pk3_value => p_instance_pk3_value,
314 -- p_instance_pk4_value => p_instance_pk4_value,
315 -- p_instance_pk5_value => p_instance_pk5_value,
316 p_user_name => 'HZ_PARTY:' || l_party_id
317 );
318
319 -- If the User does not have direct roles for Editing this NIR, We have to check for Inherited roles.
320 IF NOT 'T' = l_chk_fn_ret_val THEN
321 -- Get the Inventory Item Id and Organization Id of the Item
322 l_chk_fn_ret_val := EGO_DATA_SECURITY.check_inherited_function
323 (
324 p_api_version => 1.0,
325 p_function => 'ENG_EDIT_CHANGE',
326 p_object_name => 'ENG_CHANGE',
327 p_instance_pk1_value => nirs.change_id,
328 -- p_instance_pk2_value => p_org_id,
329 -- p_instance_pk3_value => p_instance_pk3_value,
330 -- p_instance_pk4_value => p_instance_pk4_value,
331 -- p_instance_pk5_value => p_instance_pk5_value,
332 p_user_name => 'HZ_PARTY:' || l_party_id,
333 p_object_type => 'NEW_ITEM_REQUEST',
334 p_parent_object_name => 'EGO_ITEM',
335 p_parent_instance_pk1_value => p_item_id,
336 p_parent_instance_pk2_value => p_org_id
337 -- p_parent_instance_pk3_value => p_parent_instance_pk3_value,
338 -- p_parent_instance_pk4_value => p_parent_instance_pk4_value,
339 -- p_parent_instance_pk5_value => p_parent_instance_pk5_value
340 );
341 END IF;
342 ELSE
343 l_chk_fn_ret_val := 'T';
344 END IF;
345 IF NOT 'T' = l_chk_fn_ret_val THEN
346 x_nir_cancel_status := 'ACCESS_DENIED';
347 RETURN;
348 END IF;
349 Cancel_NIR_Line_Item( p_change_id => nirs.change_id,
350 p_item_id => p_item_id,
351 p_org_id => p_org_id,
352 -- p_mode => p_item_action, -- (DELETE/CHANGE_ICC)
353 p_wf_user_id => p_wf_user_id,
354 p_fnd_user_id => p_fnd_user_id,
355 p_cancel_comments => p_cancel_comments,
356 P_COMMIT => FND_API.G_FALSE,
357 x_return_status => x_nir_cancel_status
358 );
359 select count(change_id) into l_uncancelled_change_id
360 from eng_change_lines where change_id = nirs.change_id
361 and status_code <> 5;
362 if l_uncancelled_change_id = 0
363 then
364
365 FND_MESSAGE.SET_NAME('ENG', 'ENG_NIR_CANCELLED_COMMENT');
366 l_cancel_comments := FND_MESSAGE.GET;
367
368 Cancel_NIR(p_change_id => nirs.CHANGE_ID,
369 p_org_id => p_org_id,
370 p_change_notice => nirs.CHANGE_NOTICE,
371 p_auto_commit => p_auto_commit,
372 p_wf_user_id => p_wf_user_id,
373 p_fnd_user_id => p_fnd_user_id,
374 p_cancel_comments => l_cancel_comments,
375 -- p_check_security => p_check_security,
376 p_check_security => TRUE,
377 x_nir_cancel_status => x_nir_cancel_status
378 );
379 end if;
380 END LOOP;
381
382 END Cancel_NIR_FOR_ITEM;
383
384 PROCEDURE Delete_Child_Associations(
385 p_parent_icc_id IN NUMBER,
386 p_item_catalog_group_ids IN VARCHAR2,
387 p_route_people_id IN NUMBER DEFAULT NULL,
388 p_attribute_group_id IN NUMBER DEFAULT NULL,
389 p_commit IN VARCHAR2
390 )
391 IS
392 l_delete_assocs_stmt VARCHAR2(32767);
393 i NUMBER;
394 l_child_item_catalog_group_id VARCHAR2(80);
395 l_parent_item_catalog_group_id VARCHAR2(1000);
396 l_parent_assoc_creation_date VARCHAR2(1000);
397 l_parent_route_people_id NUMBER;
398 l_parent_attr_group_id NUMBER;
399
400 CURSOR cur_child_icc_assocs IS
401 SELECT assoc_obj_pk1_value, route_people_id, object_id1, To_Char(CREATION_DATE, 'DD-MON-YYYY HH24:MI:SS') creation_date
402 FROM ENG_CHANGE_ROUTE_ASSOCS WHERE ASSOC_OBJ_PK1_VALUE = p_parent_icc_id;
403
404 BEGIN
405 IF p_parent_icc_id IS NOT NULL THEN
406 -- Following code will be called when the AG association is deleted from the ICC directly
407 IF p_route_people_id IS NOT NULL AND p_attribute_group_id IS NOT NULL THEN
408 i := 1;
409 LOOP
410 l_child_item_catalog_group_id := Tokenize( p_item_catalog_group_ids, i , ',') ;
411 EXIT WHEN l_child_item_catalog_group_id IS NULL ;
412
413 -- We need to check whether the same AG is not associated for the Child ICC directly
414 -- If AG is associated directly to the Child ICC then the creation date will be different as parent's
415 -- else creation date will be same as parent's
416 SELECT To_Char(CREATION_DATE, 'DD-MON-YYYY HH24:MI:SS') INTO l_parent_assoc_creation_date FROM ENG_CHANGE_ROUTE_ASSOCS
417 WHERE ASSOC_OBJ_PK1_VALUE = p_parent_icc_id
418 AND ROUTE_PEOPLE_ID = p_route_people_id
419 AND OBJECT_ID1 = p_attribute_group_id;
420
421 DELETE FROM ENG_CHANGE_ROUTE_ASSOCS
422 WHERE ASSOC_OBJ_PK1_VALUE = l_child_item_catalog_group_id
423 AND ASSOC_OBJ_PK1_VALUE <> p_parent_icc_id
424 AND ROUTE_PEOPLE_ID = p_route_people_id
425 AND OBJECT_ID1 = p_attribute_group_id
426 AND To_Char(CREATION_DATE, 'DD-MON-YYYY HH24:MI:SS') = l_parent_assoc_creation_date; -- Delete only if AG assoc is inherited : if inherited then the creation date will be same
427 -- AND CREATION_DATE = l_parent_assoc_creation_date;
428 -- AND ADHOC_ASSOC_FLAG = 'N'; -- Child ICCs can add more associations, those should not be deleted
429
430 i := i + 1;
431 END LOOP;
432 -- EXECUTE IMMEDIATE l_delete_assocs_stmt USING p_item_catalog_group_ids, p_route_people_id, p_attribute_group_id;
433 ELSE
434 -- Following code will be called from API when the ICC NIR setp is changed
435 FOR rec IN cur_child_icc_assocs
436 LOOP
437 DELETE FROM ENG_CHANGE_ROUTE_ASSOCS WHERE ROUTE_ASSOCIATION_ID IN (
438 SELECT ROUTE_ASSOCIATION_ID FROM (
439 SELECT a.route_association_id,
440 b.item_catalog_group_id,
441 b.parent_catalog_group_id,
442 b.NEW_ITEM_REQUEST_REQD
443 FROM eng_change_route_assocs a, mtl_item_catalog_groups_v b
444 WHERE a.assoc_obj_pk1_value = b.item_catalog_group_id
445 AND a.object_id1= rec.object_id1
446 AND To_Char(a.CREATION_DATE, 'DD-MON-YYYY HH24:MI:SS') = rec.creation_date
447 ) CONNECT BY PRIOR item_catalog_group_id = parent_catalog_group_id AND NEW_ITEM_REQUEST_REQD = 'I'
448 START WITH item_catalog_group_id = rec.assoc_obj_pk1_value );
449 END LOOP;
450 END IF;
451 END IF;
452
453 -- IF p_commit = 'TRUE' THEN
454 -- commit;
455 -- END IF;
456
457 EXCEPTION
458 WHEN OTHERS THEN
459 NULL;
460
461 END Delete_Child_Associations;
462
463 -- Duplicate Validation still to be done while creating the associations like this. Done
464 /*
465 First Part of the Following API will be called when the ICC NIR setup is changed
466 This will do a mass creation of the AG Associations for all the Child ICCs given
467 Second Part of the Following API will be created when an attribute group association is created for an ICC
468 It will propagate the association to all the ICC's child ICCs.
469
470 */
471 PROCEDURE Create_Child_Associations(
472 p_source_item_catalog_group_id IN VARCHAR2,
473 p_parent_item_catalog_group_id IN VARCHAR2,
474 p_child_item_catalog_group_ids IN VARCHAR2,
475 -- following parameters will be used while calling only when the AG is associated to ICC directly
476 p_route_people_id IN NUMBER DEFAULT NULL,
477 p_attribute_group_id IN NUMBER DEFAULT NULL,
478 p_assoc_creation_date IN DATE DEFAULT NULL,
479 p_assoc_created_by IN NUMBER DEFAULT NULL,
480 p_assoc_last_update_date IN DATE DEFAULT NULL,
481 p_assoc_last_update_login IN NUMBER DEFAULT NULL,
482 p_assoc_last_updated_by IN NUMBER DEFAULT NULL,
483 p_commit IN VARCHAR2
484 )
485 IS
486 l_create_assocs_stmt VARCHAR2(32767);
487 l_child_item_catalog_group_id VARCHAR2(1000);
488 i NUMBER;
489 k NUMBER;
490 l_route_association_id ENG_CHANGE_ROUTE_ASSOCS.ROUTE_ASSOCIATION_ID%TYPE;
491 l_source_icc_id VARCHAR2(1000);
492 l_child_icc_ids VARCHAR2(32767);
493
494 CURSOR cur_parent_icc_ag_associations IS
495 SELECT
496 ROUTE_PEOPLE_ID, ASSOC_OBJECT_NAME, ASSOC_OBJ_PK1_VALUE, ASSOC_OBJ_PK2_VALUE, ASSOC_OBJ_PK3_VALUE, ASSOC_OBJ_PK4_VALUE,
497 ASSOC_OBJ_PK5_VALUE, ADHOC_ASSOC_FLAG, OBJECT_NAME, OBJECT_ID1, OBJECT_ID2, OBJECT_ID3, OBJECT_ID4, OBJECT_ID5, CREATION_DATE,
498 CREATED_BY, LAST_UPDATE_DATE, LAST_UPDATED_BY, LAST_UPDATE_LOGIN, REQUEST_ID, PROGRAM_ID, PROGRAM_APPLICATION_ID,
499 PROGRAM_UPDATE_DATE, ORIGINAL_SYSTEM_REFERENCE
500 FROM ENG_CHANGE_ROUTE_ASSOCS
501 WHERE ASSOC_OBJ_PK1_VALUE = l_source_icc_id;
502
503 BEGIN
504 IF p_source_item_catalog_group_id IS NOT NULL THEN
505 -- p_source_item_catalog_group_id This will not be null when an ICC NIR setup is set to Inherit From Parent and
506 -- it has a Parent ICC with some associations and some child ICCs. Then the Parent's associations should be copied
507 -- to it and its Children
508 l_source_icc_id := p_source_item_catalog_group_id;
509 l_child_icc_ids := p_child_item_catalog_group_ids;
510 -- Check if there are child ICCs for which the association to be propagated, if so append
511 /*
512 IF p_child_item_catalog_group_ids IS NULL OR p_child_item_catalog_group_ids = '' THEN
513 l_child_icc_ids := p_parent_item_catalog_group_id;
514 ELSE
515 l_child_icc_ids := p_child_item_catalog_group_ids || ',' || p_parent_item_catalog_group_id;
516 END IF;
517 */
518 ELSE
519 l_source_icc_id := p_parent_item_catalog_group_id;
520 l_child_icc_ids := p_child_item_catalog_group_ids;
521 END IF;
522 -- First Part : Mass Update
523 IF l_child_icc_ids IS NOT NULL THEN
524
525 i := 1;
526 -- Query all the Parent ICC Associations.
527 IF p_route_people_id IS NULL AND p_attribute_group_id IS NULL THEN
528 FOR ag_association IN cur_parent_icc_ag_associations LOOP
529 i := 1;
530 LOOP
531 -- For each Child ICC, create the attribute groups associations.
532 l_child_item_catalog_group_id := Tokenize( l_child_icc_ids, i , ',') ;
533 EXIT WHEN l_child_item_catalog_group_id IS NULL ;
534 IF ag_association.object_id1 IS NOT NULL THEN
535 -- First check if there is already an association for this AG at the Child ICC.
536 -- Association Unique combination (ASSOC_OBJ_PK1_VALUE, ROUTE_PEOPLE_ID, OBJECT_ID1)
537 SELECT count(route_association_id) INTO k
538 FROM ENG_CHANGE_ROUTE_ASSOCS
539 WHERE ASSOC_OBJ_PK1_VALUE = l_child_item_catalog_group_id
540 AND ROUTE_PEOPLE_ID = ag_association.route_people_id
541 AND OBJECT_ID1 = ag_association.object_id1;
542 IF k = 0 OR k IS NULL THEN -- Create association only if it already does not exist
543 -- Get the Association Id from Sequence.
544 SELECT ENG_CHANGE_ROUTE_ASSOCS_S.NEXTVAL INTO l_route_association_id FROM DUAL;
545 -- For each Parent ICC's association, create an association in the Child ICC.
546 INSERT INTO ENG_CHANGE_ROUTE_ASSOCS (ROUTE_ASSOCIATION_ID, ROUTE_PEOPLE_ID, ASSOC_OBJECT_NAME, ASSOC_OBJ_PK1_VALUE,
547 ASSOC_OBJ_PK2_VALUE, ASSOC_OBJ_PK3_VALUE, ASSOC_OBJ_PK4_VALUE, ASSOC_OBJ_PK5_VALUE, ADHOC_ASSOC_FLAG,
548 OBJECT_NAME, OBJECT_ID1, OBJECT_ID2, OBJECT_ID3, OBJECT_ID4, OBJECT_ID5, CREATION_DATE, CREATED_BY,
549 LAST_UPDATE_DATE, LAST_UPDATED_BY, LAST_UPDATE_LOGIN, REQUEST_ID, PROGRAM_ID, PROGRAM_APPLICATION_ID,
550 PROGRAM_UPDATE_DATE, ORIGINAL_SYSTEM_REFERENCE)
551 VALUES (l_route_association_id, ag_association.route_people_id, ag_association.assoc_object_name,
552 l_child_item_catalog_group_id, ag_association.assoc_obj_pk2_value, ag_association.assoc_obj_pk3_value,
553 ag_association.assoc_obj_pk4_value, ag_association.assoc_obj_pk5_value, 'N',
554 ag_association.object_name, ag_association.object_id1, ag_association.object_id2, ag_association.object_id3,
555 ag_association.object_id4, ag_association.object_id5, ag_association.creation_date, ag_association.created_by,
556 ag_association.last_update_date, ag_association.last_updated_by, ag_association.last_update_login,
557 ag_association.request_id, ag_association.program_id, ag_association.program_application_id,
558 ag_association.program_update_date, ag_association.original_system_reference);
559 END IF; -- if k = 0 then
560 END IF;
561 i := i + 1;
562 k := 0;
563 END LOOP; -- Child ICCs
564 END LOOP ; -- Parent's associations : For Cursor Loop
565 END IF;
566
567 -- Second Part : Single Attribute group creation propagation
568 -- Will be called when an attribute group is associated for the parent ICC
569 IF p_route_people_id IS NOT NULL AND p_attribute_group_id IS NOT NULL THEN
570 i := 1;
571 LOOP
572 l_child_item_catalog_group_id := Tokenize( l_child_icc_ids, i , ',') ;
573 EXIT WHEN l_child_item_catalog_group_id IS NULL ;
574 -- First check if there is already an association for this AG at the Child ICC.
575 -- Association Unique combination (ASSOC_OBJ_PK1_VALUE, ROUTE_PEOPLE_ID, OBJECT_ID1)
576 SELECT count(route_association_id) INTO k
577 FROM ENG_CHANGE_ROUTE_ASSOCS
578 WHERE ASSOC_OBJ_PK1_VALUE = l_child_item_catalog_group_id
579 AND ROUTE_PEOPLE_ID = p_route_people_id
580 AND OBJECT_ID1 = p_attribute_group_id;
581 IF (k = 0 OR k IS NULL) AND p_parent_item_catalog_group_id <> l_child_item_catalog_group_id THEN -- Create association only if it already does not exist
582 SELECT ENG_CHANGE_ROUTE_ASSOCS_S.NEXTVAL INTO l_route_association_id FROM DUAL;
583 -- For each Parent ICC's association, create an association in the Child ICC.
584 INSERT INTO ENG_CHANGE_ROUTE_ASSOCS (ROUTE_ASSOCIATION_ID, ROUTE_PEOPLE_ID, ASSOC_OBJECT_NAME, ASSOC_OBJ_PK1_VALUE,
585 ADHOC_ASSOC_FLAG, OBJECT_NAME, OBJECT_ID1, OBJECT_ID2, OBJECT_ID3, OBJECT_ID4, OBJECT_ID5,
586 CREATION_DATE , CREATED_BY , LAST_UPDATE_DATE,
587 LAST_UPDATED_BY, LAST_UPDATE_LOGIN)
588 VALUES (l_route_association_id, p_route_people_id, 'EGO_CATALOG_GROUP', l_child_item_catalog_group_id, 'N',
589 'EGO_ITEM_ATTR_GROUP', p_attribute_group_id, 0,0,0,0, p_assoc_creation_date, p_assoc_created_by,
590 p_assoc_last_update_date, p_assoc_last_update_login, p_assoc_last_updated_by);
591 END IF;
592 i := i + 1;
593 k := 0;
594 END LOOP;
595 END IF;
596 END IF;
597 EXCEPTION
598 WHEN OTHERS THEN
599 NULL;
600 END Create_Child_Associations;
601
602 PROCEDURE Update_Child_Associations(
603 p_parent_item_catalog_group_id IN VARCHAR2,
604 p_child_item_catalog_group_ids IN VARCHAR2,
605 p_route_people_id IN NUMBER DEFAULT NULL,
606 p_attribute_group_id IN NUMBER DEFAULT NULL,
607 p_route_association_id IN NUMBER,
608 p_commit IN VARCHAR2
609 )
610 IS
611 l_old_attr_group_id NUMBER;
612 i NUMBER;
613 l_child_item_catalog_group_id VARCHAR2(1000);
614 BEGIN
615 -- Get the old attribute groups associated
616 SELECT object_id1 INTO l_old_attr_group_id FROM ENG_CHANGE_ROUTE_ASSOCS WHERE route_association_id = p_route_association_id;
617 i := 1;
618 LOOP
619 l_child_item_catalog_group_id := Tokenize( p_child_item_catalog_group_ids, i , ',') ;
620 EXIT WHEN l_child_item_catalog_group_id IS NULL ;
621
622 IF p_attribute_group_id IS NULL THEN -- When attribute group association lov field is cleared
623 DELETE FROM ENG_CHANGE_ROUTE_ASSOCS
624 WHERE ASSOC_OBJ_PK1_VALUE = l_child_item_catalog_group_id
625 AND ASSOC_OBJ_PK1_VALUE <> p_parent_item_catalog_group_id
626 AND ROUTE_PEOPLE_ID = p_route_people_id
627 AND OBJECT_ID1 = l_old_attr_group_id;
628 ELSE
629 UPDATE ENG_CHANGE_ROUTE_ASSOCS
630 SET OBJECT_ID1 = p_attribute_group_id
631 WHERE ASSOC_OBJ_PK1_VALUE = l_child_item_catalog_group_id
632 AND ASSOC_OBJ_PK1_VALUE <> p_parent_item_catalog_group_id
633 AND ROUTE_PEOPLE_ID = p_route_people_id;
634 END IF;
635
636 i := i + 1;
637 END LOOP;
638
639 END Update_Child_Associations;
640
641
642 FUNCTION Tokenize
643 (
644 p_string IN VARCHAR2, -- input string
645 p_start_position IN NUMBER, -- token number
646 p_seperator IN VARCHAR2 DEFAULT ',' -- separator character
647 )
648 RETURN VARCHAR2
649 IS
650 l_string VARCHAR2(32767) := p_seperator || p_string ;
651 l_position NUMBER ;
652 l_position2 NUMBER ;
653 BEGIN
654 l_position := INSTR( l_string, p_seperator, 1, p_start_position ) ;
655 IF l_position > 0 THEN
656 l_position2 := INSTR( l_string, p_seperator, 1, p_start_position + 1) ;
657 IF l_position2 = 0 THEN
658 l_position2 := LENGTH( l_string ) + 1 ;
659 END IF ;
660 RETURN( SUBSTR( l_string, l_position+1, l_position2 - l_position-1 ) ) ;
661 ELSE
662 RETURN NULL ;
663 END IF ;
664 END;
665
666
667 PROCEDURE Cancel_NIR_Line_Item(
668 p_change_id NUMBER,
669 p_item_id NUMBER,
670 p_org_id NUMBER,
671 -- p_mode VARCHAR2, -- (DELETE/CHANGE_ICC)
672 p_wf_user_id IN NUMBER,
673 p_fnd_user_id IN NUMBER,
674 p_cancel_comments IN VARCHAR2,
675 p_commit IN VARCHAR2 := FND_API.G_FALSE,
676 x_return_status OUT NOCOPY VARCHAR2
677 )
678 IS
679 l_change_line_id NUMBER;
680 l_lines_count NUMBER;
681 l_change_notice ENG_ENGINEERING_CHANGES.CHANGE_NOTICE%TYPE;
682 l_return_status VARCHAR2(1);
683 l_msg_count NUMBER ;
684 l_msg_data VARCHAR2(200);
685 l_action_id eng_change_actions.action_id%TYPE;
686 l_change_status_code eng_engineering_changes.status_code%TYPE;
687 BEGIN
688 -- First check whether the change(NIR) is in Draft status. If so the remove the line and subjects
689 SELECT status_code INTO l_change_status_code FROM eng_engineering_changes WHERE change_id = p_change_id;
690
691 IF l_change_status_code = 0 THEN -- If Draft then
692 -- Delete the line and subject in the NIR since it is in draft
693 SELECT change_line_id INTO l_change_line_id FROM eng_change_subjects
694 WHERE change_id = p_change_id
695 AND pk1_value = p_item_id
696 AND pk2_value = p_org_id
697 AND entity_name = 'EGO_ITEM';
698
699 DELETE FROM eng_change_subjects WHERE change_id = p_change_id ;
700 -- AND pk1_value = p_item_id
701 -- AND pk2_value = p_org_id
702 -- AND entity_name = 'EGO_ITEM';
703
704 DELETE FROM eng_change_lines WHERE change_id = p_change_id and change_line_id = l_change_line_id;
705 DELETE FROM eng_change_lines_tl WHERE change_line_id = l_change_line_id;
706 ELSE
707 -- Query change line id
708 SELECT change_line_id INTO l_change_line_id FROM eng_change_subjects
709 WHERE change_id = p_change_id
710 AND pk1_value = p_item_id
711 AND pk2_value = p_org_id
712 AND entity_name = 'EGO_ITEM';
713 -- Set change line status to Cancelled
714 UPDATE ENG_CHANGE_LINES SET status_code = 5 -- Cancelled
715 WHERE change_id = p_change_id AND change_line_id = l_change_line_id;
716 -- Update the Action Log of the NIR.
717 ENG_CHANGE_ACTIONS_UTIL.Create_Change_Action
718 (
719 p_api_version => 1.0,
720 p_init_msg_list => FND_API.G_TRUE,
721 p_commit => FND_API.G_FALSE,
722 p_validation_level => FND_API.G_VALID_LEVEL_FULL,
723 p_debug => FND_API.G_FALSE,
724 p_output_dir => '',
725 p_debug_filename => '',
726 x_return_status => l_return_status,
727 x_msg_count => l_msg_count,
728 x_msg_data => l_msg_data,
729 p_object_id1 => p_change_id,
730 p_object_id2 => l_change_line_id,
731 p_object_name => 'ENG_NEW_ITEM_REQUEST_LINES',
732 p_action_type => 'CANCEL',
733 p_status_code => 5, -- Cancelled
734 p_parent_action_id => -1,
735 p_change_description => p_cancel_comments,
736 x_change_action_id => l_action_id
737 );
738 -- Check if this is the only Line in the NIR.
739 END IF;
740
741 x_return_status := 'TRUE';
742
743 EXCEPTION
744 WHEN OTHERS THEN
745 x_return_status := 'FALSE';
746
747 END Cancel_NIR_Line_Item;
748
749 /*
750 Added for R12C Enhancements
751 Now, since there can be more than one line items in an NIR, we have to query the item using change_line_id.
752 This method is called when the Line Item in an NIR is Rejected.
753 This method calls the Items API to change the Approval Status of the Item.
754 */
755 PROCEDURE Update_Item_Approval_Status (
756 p_change_id IN NUMBER,
757 p_change_line_id IN NUMBER,
758 p_approval_status IN NUMBER,
759 x_return_status OUT NOCOPY VARCHAR2)
760 IS
761 l_item_id NUMBER;
762 l_organization_id NUMBER;
763 l_approval_status VARCHAR2(1);
764 l_ret_item_app_st INTEGER;
765 BEGIN
766 x_return_status := FND_API.G_RET_STS_SUCCESS;
767 IF p_approval_status = 1 THEN
768 l_approval_status := 'N';
769 ELSIF p_approval_status = 3 THEN
770 l_approval_status := 'S';
771 ELSIF p_approval_status IN (4, 8, 14) THEN -- 14 = Rejected
772 l_approval_status := 'R';
773 ELSIF p_approval_status = 5 THEN
774 l_approval_status := 'A';
775 END IF;
776 /* if p_change_line_ids is not null
777 then
778 for i in p_change_line_ids.FIRST .. p_change_line_ids.LAST
779 LOOP
780 /* get item_id and organization_id */
781 SELECT to_number(pk1_value), to_number(pk2_value)
782 INTO l_item_id, l_organization_id
783 FROM eng_change_subjects
784 WHERE change_line_id = p_change_line_id
785 AND entity_name='EGO_ITEM';
786 /* call API to update approval status on the Item to approved*/
787
788 -- l_ret_item_app_st := EGO_ITEM_PUB.UPDATE_ITEM_APPROVAL_STATUS(l_item_id,l_organization_id, l_approval_status);
789 EGO_ITEM_PUB.UPDATE_ITEM_APPROVAL_STATUS(l_item_id,l_organization_id, l_approval_status, p_change_id);
790 --END LOOP;
791 -- end if;
792
793 EXCEPTION WHEN others THEN
794
795 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR ;
796 FND_MESSAGE.Set_Name('ENG','ENG_ERROR_CALLING_PS_API');
797 FND_MESSAGE.Set_Token('OBJECT_NAME', 'EGO_ITEM_PUB.UPDATE_ITEM_APPROVAL_STATUS '||'itemId: '||l_item_id||' OrgId: '||l_organization_id|| ' approvalStstus: '||l_approval_status || ' changeId: ' || p_change_id);
798 FND_MSG_PUB.Add;
799
800 END Update_Item_Approval_Status;
801
802 FUNCTION checkNIRValidForApproval( p_change_id IN NUMBER)
803 return boolean
804 is
805 l_change_line_id number;
806 BEGIN
807 select change_line_id
808 into l_change_line_id
809 from eng_change_lines
810 where change_id = p_change_id
811 and status_code in( 1,3)
812 and rownum=1;
813
814 return ( l_change_line_id is not null);
815
816 EXCEPTION WHEN NO_DATA_FOUND THEN
817 return false;
818
819 END checkNIRValidForApproval;
820
821 /*
822 This method will be called from ENG_CHANGE_LIFECYCLE_UTIL.Update_Header_Appr_Status() procedure
823 This method should be called when the Workflow is aborted in the Approval phase and when the NIR is demoted to Approval phase
824 All the Lines and Line Items status and approval status respectively should be reset to Open and Submitted for Approval respectively.
825 This method will reset the Approval Status of Items and Status of Lines which are Rejected using the NIR.
826
827 Spl Test Case : If there is another NIR with one of the line items and submitted since it is rejected in previous NIR,
828 and if the previous NIR Workflow is restarted, then the Line Status and Item Approval status will not be reset because it has to
829 be tracked with the other NIR.
830 Test Case :
831 SNIR_277 (Line1 - Item1)
832 Line is Rejected
833 NIR is Approved
834 SNIR_279 (Line1 - Item1) Submitted, Item - SFA
835 SNIR_277 Wf is Restarted
836 Result : Should not update the Item App Status and Line Status in SNIR_277. SNIR_279 should be used to track the Item1.
837 */
838 PROCEDURE Update_Line_Items_App_St(
839 p_change_id IN NUMBER,
840 p_item_approval_status IN NUMBER,
841 x_sfa_line_items_exists OUT NOCOPY VARCHAR2
842 )
843 IS
844 CURSOR cur_line_items_in_nir IS
845 SELECT change_line_id, pk1_value, pk2_value, pk3_value FROM ENG_CHANGE_SUBJECTS WHERE change_id = p_change_id
846 AND ENTITY_NAME='EGO_ITEM';
847
848 l_ret_status VARCHAR2(10);
849 l_change_line_id ENG_CHANGE_SUBJECTS.change_line_id%TYPE;
850 l_pk1_value ENG_CHANGE_SUBJECTS.pk1_value%TYPE;
851 l_pk2_value ENG_CHANGE_SUBJECTS.pk2_value%TYPE;
852 l_pk3_value ENG_CHANGE_SUBJECTS.pk3_value%TYPE;
853 l_item_approval_status MTL_SYSTEM_ITEMS.approval_status%TYPE;
854 l_sfa_item VARCHAR2(1000);
855
856 BEGIN
857 x_sfa_line_items_exists := '';
858 -- Get all the Line Items in the NIR
859 FOR line_items IN cur_line_items_in_nir
860 LOOP
861 l_change_line_id := line_items.change_line_id;
862 l_pk1_value := line_items.pk1_value;
863 l_pk2_value := line_items.pk2_value;
864 l_pk3_value := line_items.pk3_value;
865
866 BEGIN
867 -- We need to reset the Line status and Item approval status only for the Lines rejected in the NIR.
868 SELECT approval_status INTO l_item_approval_status FROM MTL_SYSTEM_ITEMS WHERE inventory_item_id = l_pk1_value AND organization_id = l_pk2_value;
869 IF 'R' = l_item_approval_status THEN
870 -- Update Item Approval Status
871 Update_Item_Approval_Status(p_change_id, line_items.change_line_id, p_item_approval_status, l_ret_status);
872 -- Update Line Item Status
873 UPDATE eng_change_lines SET STATUS_CODE = 1 WHERE change_line_id = l_change_line_id;
874 ELSE
875 SELECT CONCATENATED_SEGMENTS INTO l_sfa_item
876 FROM MTL_SYSTEM_ITEMS_KFV
877 WHERE inventory_item_id = l_pk1_value
878 AND organization_id = l_pk2_value
879 AND LAST_SUBMITTED_NIR_ID <> p_change_id;
880
881 IF x_sfa_line_items_exists IS NOT NULL AND l_sfa_item IS NOT NULL THEN
882 x_sfa_line_items_exists := x_sfa_line_items_exists || ' , ';
883 END IF;
884 x_sfa_line_items_exists := x_sfa_line_items_exists || l_sfa_item;
885 END IF;
886
887 EXCEPTION
888 WHEN OTHERS THEN
889 NULL;
890 END;
891 END LOOP;
892
893 END Update_Line_Items_App_St;
894
895 END ENG_NIR_UTIL_PKG;