1 PACKAGE BODY AHL_UC_TREE_PVT AS
2 /* $Header: AHLVUCTB.pls 120.2.12010000.2 2008/11/06 10:55:52 sathapli ship $ */
3
4 -- Define global internal variables and cursors
5 G_PKG_NAME VARCHAR2(30) := 'AHL_UC_TREE_PVT';
6
7 -- Added by rbhavsar on July 25, 2007 to remap IB Tree Nodes to fix FP bug 6276991
8 TYPE T_ID_TBL IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
9
10 PROCEDURE Remap_IB_Tree(p_instance_id IN NUMBER,
11 p_relationship_id IN NUMBER);
12
13 PROCEDURE Process_instances(p_x_extra_instances_tbl IN OUT NOCOPY T_ID_TBL,
14 p_x_relations_tbl IN OUT NOCOPY T_ID_TBL);
15
16 -- Define procedure get_immediate_children
17 -- This API is used to draw the UC tree. For a given node, it will list all of its
18 -- immediate children nodes.
19 /*
20 PROCEDURE get_immediate_children(
21 p_api_version IN NUMBER := 1.0,
22 p_init_msg_list IN VARCHAR2 := FND_API.G_FALSE,
23 --p_commit IN VARCHAR2 := FND_API.G_FALSE,
24 p_validation_level IN NUMBER := FND_API.G_VALID_LEVEL_FULL,
25 x_return_status OUT NOCOPY VARCHAR2,
26 x_msg_count OUT NOCOPY NUMBER,
27 x_msg_data OUT NOCOPY VARCHAR2,
28 p_uc_parent_rec IN uc_child_rec_type,
29 x_uc_child_tbl OUT NOCOPY uc_child_tbl_type)
30 IS
31 l_api_name CONSTANT VARCHAR2(30) := 'get_immediate_children';
32 l_api_version CONSTANT NUMBER := 1.0;
33 l_return_status VARCHAR2(1);
34 l_msg_count NUMBER;
35 l_relationship_id NUMBER;
36 l_children_no NUMBER;
37 l_dummy VARCHAR2(1);
38 i NUMBER;
39 CURSOR check_installed_instance IS
40 SELECT 'x'
41 FROM ahl_unit_config_headers U,
42 ahl_mc_relationships R
43 WHERE U.master_config_id = R.mc_header_id
44 AND R.parent_relationship_id IS NULL
45 AND U.csi_item_instance_id = p_uc_parent_rec.instance_id
46 AND R.relationship_id = p_uc_parent_rec.relationship_id
47 AND nvl(trunc(U.active_end_date), trunc(SYSDATE)+1) > trunc(SYSDATE)
48 UNION
49 SELECT 'x'
50 FROM csi_ii_relationships
51 WHERE subject_id = p_uc_parent_rec.instance_id
52 AND position_reference = to_char(p_uc_parent_rec.relationship_id)
53 AND nvl(trunc(active_end_date), trunc(SYSDATE)+1) > trunc(SYSDATE);
54 CURSOR check_relationship IS
55 SELECT 'x'
56 FROM ahl_mc_relationships
57 WHERE relationship_id = p_uc_parent_rec.relationship_id;
58 CURSOR check_instance IS
59 SELECT 'x'
60 FROM csi_item_instances
61 WHERE instance_id = p_uc_parent_rec.instance_id;
62 CURSOR get_top_position(c_instance_id number) IS
63 SELECT B.relationship_id
64 FROM ahl_unit_config_headers A,
65 ahl_mc_relationships B
66 WHERE A.master_config_id = B.mc_header_id
67 AND B.parent_relationship_id IS NULL
68 AND A.csi_item_instance_id = c_instance_id;
69 -- get immediate children for installed node
70 CURSOR get_child_nodes_i(c_instance_id number, c_relationship_id number) IS
71 SELECT 'X' node_type, subject_id instance_id, NULL relationship_id
72 FROM csi_ii_relationships
73 WHERE object_id = c_instance_id
74 AND position_reference IS NULL
75 UNION
76 SELECT 'I' node_type, subject_id instance_id, to_number(position_reference) relationship_id
77 FROM csi_ii_relationships
78 WHERE object_id = c_instance_id
79 AND position_reference IS NOT NULL
80 AND nvl(trunc(active_end_date), trunc(SYSDATE)+1) > trunc(SYSDATE)
81 UNION
82 SELECT 'E' node_type, NULL instance_id, relationship_id
83 FROM ahl_mc_relationships
84 WHERE parent_relationship_id = c_relationship_id
85 AND relationship_id NOT IN (SELECT position_reference
86 FROM csi_ii_relationships
87 WHERE object_id = c_instance_id
88 AND position_reference IS NOT NULL
89 AND nvl(trunc(active_end_date), trunc(SYSDATE)+1) > trunc(SYSDATE));
90 l_get_child_nodes_i get_child_nodes_i%ROWTYPE;
91 -- get immediate children for empty node
92 CURSOR get_child_nodes_m(c_relationship_id number) IS
93 SELECT 'E' node_type, NULL instance_id, relationship_id
94 FROM ahl_mc_relationships
95 WHERE parent_relationship_id = c_relationship_id;
96 -- get immediate children for extra node
97 CURSOR get_child_nodes_x(c_instance_id number) IS
98 SELECT 'X' node_type, subject_id instance_id, to_number(position_reference) relationship_id
99 FROM csi_ii_relationships
100 WHERE object_id = c_instance_id
101 AND nvl(trunc(active_end_date), trunc(SYSDATE)+1) > trunc(SYSDATE);
102 BEGIN
103 -- Initialize API return status to success
104 x_return_status := FND_API.G_RET_STS_SUCCESS;
105
106 -- Standard call to check for call compatibility.
107 IF NOT FND_API.compatible_api_call(
108 l_api_version,
109 p_api_version,
110 l_api_name,
111 G_PKG_NAME)
112 THEN
113 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
114 END IF;
115
116 -- Initialize message list if p_init_msg_list is set to TRUE.
117 IF FND_API.to_boolean( p_init_msg_list ) THEN
118 FND_MSG_PUB.initialize;
119 END IF;
120
121 IF (FND_LOG.LEVEL_PROCEDURE >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
122 FND_LOG.STRING(FND_LOG.LEVEL_PROCEDURE,
123 'ahl.plsql.'||G_PKG_NAME||'.'||l_api_name||': Begin API',
124 'At the start of the procedure');
125 END IF;
126
127 -- Validate the input parameter
128 IF (p_uc_parent_rec.node_type IS NULL OR p_uc_parent_rec.node_type NOT IN ('I', 'E', 'X') OR
129 (p_uc_parent_rec.instance_id IS NULL AND p_uc_parent_rec.relationship_id IS NULL))THEN
130 FND_MESSAGE.set_name( 'AHL','AHL_UC_NODE_INVALID' );
131 FND_MSG_PUB.add;
132 END IF;
133 IF p_uc_parent_rec.node_type = 'I' THEN
134 IF p_uc_parent_rec.instance_id IS NULL OR p_uc_parent_rec.relationship_id IS NULL THEN
135 FND_MESSAGE.set_name( 'AHL','AHL_UC_NODE_INVALID' );
136 FND_MSG_PUB.add;
137 ELSE
138 OPEN check_installed_instance;
139 FETCH check_installed_instance INTO l_dummy;
140 IF check_installed_instance%NOTFOUND THEN
141 FND_MESSAGE.set_name( 'AHL','AHL_UC_NODE_INVALID' );
142 FND_MSG_PUB.add;
143 END IF;
144 CLOSE check_installed_instance;
145 END IF;
146 ELSIF p_uc_parent_rec.node_type = 'M' THEN
147 IF p_uc_parent_rec.instance_id IS NOT NULL OR p_uc_parent_rec.relationship_id IS NULL THEN
148 FND_MESSAGE.set_name( 'AHL','AHL_UC_NODE_INVALID' );
149 FND_MSG_PUB.add;
150 ELSE
151 OPEN check_relationship;
152 FETCH check_relationship INTO l_dummy;
153 IF check_relationship%NOTFOUND THEN
154 FND_MESSAGE.set_name( 'AHL','AHL_UC_NODE_INVALID' );
155 FND_MSG_PUB.add;
156 END IF;
157 CLOSE check_relationship;
158 END IF;
159 ELSIF p_uc_parent_rec.node_type = 'X' THEN
160 IF p_uc_parent_rec.instance_id IS NULL THEN
161 FND_MESSAGE.set_name( 'AHL','AHL_UC_NODE_INVALID' );
162 FND_MSG_PUB.add;
163 ELSE
164 OPEN check_instance;
165 FETCH check_instance INTO l_dummy;
166 IF check_instance%NOTFOUND THEN
167 FND_MESSAGE.set_name( 'AHL','AHL_UC_NODE_INVALID' );
168 FND_MSG_PUB.add;
169 END IF;
170 CLOSE check_instance;
171 END IF;
172 END IF;
173 -- If the node is a sub-UC's top node, then replace the relationship_id (leaf node
174 -- of its parent UC) with its own relationship_id (sub-UC's top node)
175 OPEN get_top_position(p_uc_parent_rec.instance_id);
176 FETCH get_top_position INTO l_relationship_id;
177 IF get_top_position%NOTFOUND THEN
178 l_relationship_id := p_uc_parent_rec.relationship_id;
179 END IF;
180 CLOSE get_top_position;
181 i := 1;
182 IF p_uc_parent_rec.node_type = 'I' THEN
183 FOR l_get_child_nodes IN get_child_nodes_i(p_uc_parent_rec.instance_id, l_relationship_id) LOOP
184 x_uc_child_tbl(i).node_type := l_get_child_nodes.node_type;
185 x_uc_child_tbl(i).instance_id := l_get_child_nodes.instance_id;
186 x_uc_child_tbl(i).relationship_id := l_get_child_nodes.relationship_id;
187 i := i+1;
188 END LOOP;
189 ELSIF p_uc_parent_rec.node_type = 'M' THEN
190 FOR l_get_child_nodes IN get_child_nodes_m(l_relationship_id) LOOP
191 x_uc_child_tbl(i).node_type := l_get_child_nodes.node_type;
192 x_uc_child_tbl(i).instance_id := l_get_child_nodes.instance_id;
193 x_uc_child_tbl(i).relationship_id := l_get_child_nodes.relationship_id;
194 i := i+1;
195 END LOOP;
196 ELSIF p_uc_parent_rec.node_type = 'X' THEN
197 FOR l_get_child_nodes IN get_child_nodes_x(p_uc_parent_rec.instance_id) LOOP
198 x_uc_child_tbl(i).node_type := l_get_child_nodes.node_type;
199 x_uc_child_tbl(i).instance_id := l_get_child_nodes.instance_id;
200 x_uc_child_tbl(i).relationship_id := l_get_child_nodes.relationship_id;
201 i := i+1;
202 END LOOP;
203 END IF;
204 IF x_uc_child_tbl.COUNT >0 THEN
205 FOR j IN x_uc_child_tbl.FIRST .. x_uc_child_tbl.LAST LOOP
206 IF x_uc_child_tbl(j).node_type = 'I' THEN
207 x_uc_child_tbl(j).has_subconfig_flag := 'N';
208 OPEN get_top_position(x_uc_child_tbl(j).instance_id);
209 FETCH get_top_position INTO l_relationship_id;
210 IF get_top_position%NOTFOUND THEN
211 l_relationship_id := x_uc_child_tbl(j).relationship_id;
212 END IF;
213 CLOSE get_top_position;
214 OPEN get_child_nodes_i(x_uc_child_tbl(j).instance_id, l_relationship_id);
215 FETCH get_child_nodes_i INTO l_get_child_nodes_i;
216 IF get_child_nodes_i%FOUND THEN
217 x_uc_child_tbl(j).leaf_node_flag := 'Y';
218 ELSE
219 x_uc_child_tbl(j).leaf_node_flag := 'N';
220 END IF;
221 ELSIF x_uc_child_tbl(j).node_type = 'M' THEN
222 SELECT count(relationship_id) INTO l_children_no
223 FROM ahl_mc_relationships
224 WHERE parent_relationship_id = x_uc_child_tbl(j).relationship_id;
225 IF l_children_no > 0 THEN
226 x_uc_child_tbl(j).has_subconfig_flag := 'N';
227 x_uc_child_tbl(j).leaf_node_flag := 'N';
228 ELSE
229 x_uc_child_tbl(j).leaf_node_flag := 'Y';
230 SELECT count(mc_header_id) INTO l_children_no
231 FROM ahl_mc_config_relations
232 WHERE relationship_id = x_uc_child_tbl(j).relationship_id;
233 IF l_children_no > 0 THEN
234 x_uc_child_tbl(j).has_subconfig_flag := 'Y';
235 ELSE
236 x_uc_child_tbl(j).has_subconfig_flag := 'N';
237 END IF;
238 END IF;
239 ELSIF x_uc_child_tbl(j).node_type = 'X' THEN
240 x_uc_child_tbl(j).has_subconfig_flag := 'N';
241 SELECT count(subject_id) INTO l_children_no
242 FROM csi_ii_relationships
243 WHERE object_id = x_uc_child_tbl(j).instance_id;
244 IF l_children_no > 0 THEN
245 x_uc_child_tbl(j).leaf_node_flag := 'Y';
246 ELSE
247 x_uc_child_tbl(j).leaf_node_flag := 'N';
248 END IF;
249 END IF;
250 END LOOP;
251 END IF;
252
253 IF (FND_LOG.LEVEL_PROCEDURE >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
254 FND_LOG.STRING(FND_LOG.LEVEL_PROCEDURE,
255 'ahl.plsql.'||G_PKG_NAME||'.'||l_api_name||': After normal execution',
256 'At the end of the procedure');
257 END IF;
258
259 -- Get all the error messages from the previous steps (if any) and raise the appropriate Exception
260 l_msg_count := FND_MSG_PUB.count_msg;
261 IF l_msg_count > 0 THEN
262 x_msg_count := l_msg_count;
263 RAISE FND_API.G_EXC_ERROR;
264 END IF;
265 -- Count and Get messages (optional)
266 FND_MSG_PUB.count_and_get(
267 p_encoded => FND_API.G_FALSE,
268 p_count => x_msg_count,
269 p_data => x_msg_data);
270
271 EXCEPTION
272 WHEN FND_API.G_EXC_ERROR THEN
273 x_return_status := FND_API.G_RET_STS_ERROR ;
274 FND_MSG_PUB.count_and_get(
275 p_encoded => FND_API.G_FALSE,
276 p_count => x_msg_count,
277 p_data => x_msg_data);
278
279 WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
280 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR ;
281 FND_MSG_PUB.count_and_get(
282 p_encoded => FND_API.G_FALSE,
283 p_count => x_msg_count,
284 p_data => x_msg_data);
285
286 WHEN OTHERS THEN
287 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR ;
288 IF FND_MSG_PUB.check_msg_level(FND_MSG_PUB.G_MSG_LVL_UNEXP_ERROR)
289 THEN
290 FND_MSG_PUB.add_exc_msg(
291 p_pkg_name => G_PKG_NAME,
292 p_procedure_name => l_api_name,
293 p_error_text => SUBSTRB(SQLERRM,1,240));
294 END IF;
295 FND_MSG_PUB.count_and_get(
296 p_encoded => FND_API.G_FALSE,
297 p_count => x_msg_count,
298 p_data => x_msg_data);
299
300 END get_immediate_children;
301 */
302
303 PROCEDURE get_whole_uc_tree(
304 p_api_version IN NUMBER := 1.0,
305 p_init_msg_list IN VARCHAR2 := FND_API.G_FALSE,
306 --p_commit IN VARCHAR2 := FND_API.G_FALSE,
307 p_validation_level IN NUMBER := FND_API.G_VALID_LEVEL_FULL,
308 x_return_status OUT NOCOPY VARCHAR2,
309 x_msg_count OUT NOCOPY NUMBER,
310 x_msg_data OUT NOCOPY VARCHAR2,
311 p_uc_header_id IN NUMBER,
312 x_uc_descendant_tbl OUT NOCOPY uc_descendant_tbl_type)
313 IS
314 -- rbhavsar::FP Bug# 6268202, performance tuning
315 -- use PL/SQL tables for BULK COLLECT instead of looping through the cursor records
316 /*
317 TYPE l_uc_children_rec_type IS RECORD (
318 instance_id NUMBER,
319 relationship_id NUMBER,
320 matched_flag VARCHAR2(1));
321 TYPE l_uc_children_tbl_type IS TABLE OF l_uc_children_rec_type INDEX BY BINARY_INTEGER;*/
322
323 TYPE t_id_tbl IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
324 TYPE t_flag_tbl IS TABLE OF VARCHAR2(1) INDEX BY BINARY_INTEGER;
325 TYPE t_partinfo_tbl IS TABLE OF VARCHAR2(80) INDEX BY BINARY_INTEGER;
326
327 l_api_name CONSTANT VARCHAR2(30) := 'get_whole_uc_tree';
328 l_api_version CONSTANT NUMBER := 1.0;
329 l_return_status VARCHAR2(1);
330 l_msg_count NUMBER;
331 l_relationship_id NUMBER;
332 l_mc_header_id NUMBER;
333 l_root_instance_id NUMBER;
334 l_root_relationship_id NUMBER;
335 l_dummy VARCHAR2(1);
336 l_dummy_num NUMBER;
337 i NUMBER;
338 -- l_uc_children_tbl l_uc_children_tbl_type;
339 l_child_inst_tbl t_id_tbl;
340 l_child_rel_tbl t_id_tbl;
341 l_child_matchflag_tbl t_flag_tbl;
342 l_child_partinfo_tbl t_partinfo_tbl;
343 l_pos_ref FND_LOOKUPS.meaning%TYPE;
344 l_root_mc_hdr_id NUMBER;
345 l_root_mc_part BOOLEAN;
346 l_root_ata_code AHL_MC_RELATIONSHIPS.ATA_CODE%TYPE; -- SATHAPLI::Enigma code changes, 02-Sep-2008
347
348 l_matched boolean;
349 total_i NUMBER; --index of output table
350 i_uc_child NUMBER; --index of MC siblings
351 l_uc_header_id NUMBER;
352
353 --Check the given uc_heder_id is valid and if yes, get the UC top node's instance_id
354 --and relationship_id
355 -- rbhavsar::FP Bug# 6268202, performance tuning
356 -- fetch the root UC's mc_header_id too
357 -- SATHAPLI::Enigma code changes, 02-Sep-2008 - fetch the ata_code as well
358 CURSOR get_uc_header_attr(c_uc_header_id NUMBER) IS
359 SELECT A.csi_item_instance_id instance_id,
360 A.master_config_id,
361 B.relationship_id,
362 B.ata_code
363 FROM ahl_unit_config_headers A,
364 ahl_mc_relationships B
365 WHERE A.unit_config_header_id = c_uc_header_id
366 AND A.master_config_id = B.mc_header_id
367 AND B.parent_relationship_id IS NULL;
368
369 --Given an instance_id, get all of its immediate children from csi_ii_relationships
370 -- rbhavsar::FP Bug# 6268202, performance tuning
371 -- Object_id is not used in the code, so removing it.
372 -- Also, no need for ORDER BY for extra nodes.
373 CURSOR get_csi_children(c_instance_id NUMBER) IS
374 SELECT R.subject_id instance_id,
375 to_number(R.position_reference) relationship_id,
376 M.concatenated_segments||'-'||NVL(C.serial_number, C.instance_number) part_info,
377 'N'
378 FROM csi_ii_relationships R,
379 csi_item_instances C,
380 mtl_system_items_kfv M
381 WHERE R.object_id = c_instance_id
382 AND R.subject_id = C.instance_id
383 AND C.inventory_item_id = M.inventory_item_id
384 AND C.inv_master_organization_id = M.organization_id
385 AND R.relationship_type_code = 'COMPONENT-OF'
386 AND trunc(nvl(R.active_start_date,SYSDATE)) <= trunc(SYSDATE)
387 AND trunc(nvl(R.active_end_date, SYSDATE+1)) > trunc(SYSDATE);
388
389 -- rbhavsar::FP Bug# 6268202, performance tuning
390 -- cursor to check if the instance is leaf node or not
391 CURSOR chk_csi_leaf_node_csr(c_instance_id NUMBER) IS
392 SELECT 'X'
393 FROM csi_ii_relationships
394 WHERE object_id = c_instance_id
395 AND relationship_type_code = 'COMPONENT-OF'
396 AND trunc(nvl(active_start_date,SYSDATE)) <= trunc(SYSDATE)
397 AND trunc(nvl(active_end_date, SYSDATE+1)) > trunc(SYSDATE);
398
399 --Given an relationship_id, get all of its immediate children from MC
400 --display_order will determine the sequence of installed and empty sibling nodes
401 -- rbhavsar::FP Bug# 6268202, performance tuning
402 -- Fetch the mc_header_id.
403 -- Fetch the position reference meaning and necessity from fnd_lookups too.
404 -- SATHAPLI::Enigma code changes, 02-Sep-2008 - fetch the ata_code as well
405 CURSOR get_mc_children(c_relationship_id NUMBER) IS
406 SELECT rel.mc_header_id,
407 rel.parent_relationship_id parent_rel_id,
408 rel.relationship_id,
409 rel.display_order,
410 rel.ata_code,
411 (SELECT fnd.meaning
412 FROM fnd_lookups fnd
413 WHERE fnd.lookup_type = 'AHL_POSITION_REFERENCE'
414 AND fnd.lookup_code = rel.position_ref_code
415 AND trunc(nvl(fnd.start_date_active, SYSDATE)) <= trunc(SYSDATE)
416 AND trunc(nvl(fnd.end_date_active, SYSDATE+1)) > trunc(SYSDATE)
417 ) pos_ref_meaning,
418 (SELECT fnd.meaning
419 FROM fnd_lookups fnd
420 WHERE fnd.lookup_type = 'AHL_POSITION_NECESSITY'
421 AND fnd.lookup_code = rel.position_necessity_code
422 AND trunc(nvl(fnd.start_date_active, SYSDATE)) <= trunc(SYSDATE)
423 AND trunc(nvl(fnd.end_date_active, SYSDATE+1)) > trunc(SYSDATE)
424 ) pos_necessity
425 FROM ahl_mc_relationships rel
426 WHERE rel.parent_relationship_id = c_relationship_id
427 AND trunc(nvl(rel.active_start_date,SYSDATE)) <= trunc(SYSDATE)
428 AND trunc(nvl(rel.active_end_date, SYSDATE+1)) > trunc(SYSDATE)
429 ORDER BY display_order;
430
431 -- rbhavsar::FP Bug# 6268202, performance tuning
432 -- cursor to check if the position is leaf node or not
433 CURSOR chk_mc_leaf_node_csr(c_relationship_id NUMBER) IS
434 SELECT 'X'
435 FROM ahl_mc_relationships
436 WHERE parent_relationship_id = c_relationship_id
437 AND trunc(nvl(active_start_date,SYSDATE)) <= trunc(SYSDATE)
438 AND trunc(nvl(active_end_date, SYSDATE+1)) > trunc(SYSDATE);
439
440 --Given an relationship_id, get all of its descendants from MC
441 -- rbhavsar::FP Bug# 6268202, performance tuning
442 -- fetch the position reference meaning and necessity from fnd_lookups too
443 -- SATHAPLI::Enigma code changes, 02-Sep-2008 - fetch the ata_code as well
444 CURSOR get_mc_descendants(c_relationship_id NUMBER) IS
445 SELECT rel.parent_relationship_id parent_rel_id,
446 rel.relationship_id,
447 rel.display_order,
448 rel.ata_code,
449 (SELECT fnd.meaning
450 FROM fnd_lookups fnd
451 WHERE fnd.lookup_type = 'AHL_POSITION_REFERENCE'
452 AND fnd.lookup_code = rel.position_ref_code
453 AND trunc(nvl(fnd.start_date_active, SYSDATE)) <= trunc(SYSDATE)
454 AND trunc(nvl(fnd.end_date_active, SYSDATE+1)) > trunc(SYSDATE)
455 ) pos_ref_meaning,
456 (SELECT fnd.meaning
457 FROM fnd_lookups fnd
458 WHERE fnd.lookup_type = 'AHL_POSITION_NECESSITY'
459 AND fnd.lookup_code = rel.position_necessity_code
460 AND trunc(nvl(fnd.start_date_active, SYSDATE)) <= trunc(SYSDATE)
461 AND trunc(nvl(fnd.end_date_active, SYSDATE+1)) > trunc(SYSDATE)
462 ) pos_necessity
463 FROM ahl_mc_relationships rel
464 START WITH rel.parent_relationship_id = c_relationship_id
465 AND trunc(nvl(rel.active_start_date,SYSDATE)) <= trunc(SYSDATE)
466 AND trunc(nvl(rel.active_end_date, SYSDATE+1)) > trunc(SYSDATE)
467 CONNECT BY rel.parent_relationship_id = PRIOR rel.relationship_id
468 AND trunc(nvl(rel.active_start_date,SYSDATE)) <= trunc(SYSDATE)
469 AND trunc(nvl(rel.active_end_date, SYSDATE+1)) > trunc(SYSDATE)
470 ORDER BY LEVEL, display_order;
471 -- keyword SIBLINGS is not supported in 8i, so we replace it with level
472 -- ORDER SIBLINGS BY display_order;
473
474
475 --Check whether an instance in UC is the top node of a sub UC, if yes, then get the
476 --relationship of the sub UC's top node
477 CURSOR check_sub_uc(c_instance_id NUMBER) IS
478 SELECT A.unit_config_header_id,
479 A.master_config_id,
480 B.relationship_id
481 FROM ahl_unit_config_headers A,
482 ahl_mc_relationships B
483 WHERE A.csi_item_instance_id = c_instance_id
484 AND trunc(nvl(A.active_end_date, SYSDATE+1)) > trunc(SYSDATE)
485 AND B.mc_header_id = A.master_config_id
486 AND B.parent_relationship_id IS NULL
487 AND trunc(nvl(B.active_start_date,SYSDATE)) <= trunc(SYSDATE)
488 AND trunc(nvl(B.active_end_date, SYSDATE+1)) > trunc(SYSDATE);
489
490 -- rbhavsar:: FP Bug# 6268202, performance tuning
491 -- check if the MC has sub MCs or not
492 CURSOR has_sub_mc_csr(c_relationship_id NUMBER) IS
493 SELECT 'X'
494 FROM ahl_mc_config_relations
495 WHERE relationship_id = c_relationship_id
496 AND trunc(nvl(active_start_date,SYSDATE)) <= trunc(SYSDATE)
497 AND trunc(nvl(active_end_date, SYSDATE+1)) > trunc(SYSDATE)
498 AND rownum = 1;
499
500 -- rbhavsar:: FP Bug# 6268202, performance tuning
501 -- Cursor to get the position reference for a given relationship id.
502 CURSOR get_pos_ref_csr(c_relationship_id NUMBER) IS
503 SELECT fnd.meaning
504 FROM ahl_mc_relationships rel, fnd_lookups fnd
505 WHERE rel.relationship_id = c_relationship_id AND
506 fnd.lookup_code = rel.position_ref_code AND
507 fnd.lookup_type = 'AHL_POSITION_REFERENCE' AND
508 TRUNC(NVL(fnd.start_date_active, SYSDATE)) <= TRUNC(SYSDATE) AND
509 TRUNC(NVL(fnd.end_date_active, SYSDATE+1)) > TRUNC(SYSDATE);
510
511 --Based on the UC, list all of the non leaf nodes(including the root node) and the leaf nodes
512 --in UC but are non-leaf nodes in MC
513 -- rbhavsar::FP Bug# 6268202, performance tuning
514 CURSOR get_non_leaf_nodes(c_instance_id NUMBER) IS
515 SELECT TO_NUMBER(NULL) PARENT_INSTANCE_ID,
516 B.CSI_ITEM_INSTANCE_ID INSTANCE_ID,
517 A.RELATIONSHIP_ID,
518 'I' NODE_TYPE,
519 0 OWN_LEVEL
520 FROM AHL_UNIT_CONFIG_HEADERS B,
521 AHL_MC_RELATIONSHIPS A
522 WHERE B.UNIT_CONFIG_HEADER_ID = p_uc_header_id /*UC header id*/
523 AND B.CSI_ITEM_INSTANCE_ID = c_instance_id /*root instance id*/
524 AND A.MC_HEADER_ID = B.MASTER_CONFIG_ID
525 AND A.PARENT_RELATIONSHIP_ID IS NULL
526 UNION ALL
527 SELECT OBJECT_ID PARENT_INSTANCE_ID,
528 SUBJECT_ID INSTANCE_ID,
529 TO_NUMBER(POSITION_REFERENCE) RELATIONSHIP_ID,
530 DECODE(POSITION_REFERENCE, NULL, 'X', 'I') NODE_TYPE,
531 LEVEL OWN_LEVEL
532 FROM CSI_II_RELATIONSHIPS A
533 WHERE (
534 EXISTS (SELECT 'x'
535 FROM CSI_II_RELATIONSHIPS B
536 WHERE B.OBJECT_ID = A.SUBJECT_ID
537 AND B.RELATIONSHIP_TYPE_CODE = 'COMPONENT-OF'
538 AND TRUNC(NVL(B.ACTIVE_START_DATE,SYSDATE)) <= TRUNC(SYSDATE)
539 AND TRUNC(NVL(B.ACTIVE_END_DATE, SYSDATE+1)) > TRUNC(SYSDATE)
540 )
541 )
542 OR
543 (
544 EXISTS (SELECT 'x'
545 FROM AHL_MC_RELATIONSHIPS D
546 WHERE D.PARENT_RELATIONSHIP_ID = TO_NUMBER(A.POSITION_REFERENCE)
547 AND TRUNC(NVL(D.ACTIVE_START_DATE,SYSDATE)) <= TRUNC(SYSDATE)
548 AND TRUNC(NVL(D.ACTIVE_END_DATE, SYSDATE+1)) > TRUNC(SYSDATE)
549 )
550 OR
551 EXISTS (SELECT 'x'
552 FROM AHL_MC_RELATIONSHIPS D
553 WHERE D.RELATIONSHIP_ID = TO_NUMBER(A.POSITION_REFERENCE)
554 AND EXISTS (SELECT 'x'
555 FROM AHL_UNIT_CONFIG_HEADERS E
556 WHERE CSI_ITEM_INSTANCE_ID = A.SUBJECT_ID
557 AND TRUNC(NVL(E.ACTIVE_END_DATE, SYSDATE+1)) > TRUNC(SYSDATE)
558 )
559 AND TRUNC(NVL(D.ACTIVE_START_DATE,SYSDATE)) <= TRUNC(SYSDATE)
560 AND TRUNC(NVL(D.ACTIVE_END_DATE, SYSDATE+1)) > TRUNC(SYSDATE)
561 )
562 )
563 START WITH OBJECT_ID = c_instance_id /*root instance id*/
564 AND RELATIONSHIP_TYPE_CODE = 'COMPONENT-OF'
565 AND TRUNC(NVL(ACTIVE_START_DATE,SYSDATE)) <= TRUNC(SYSDATE)
566 AND TRUNC(NVL(ACTIVE_END_DATE, SYSDATE+1)) > TRUNC(SYSDATE)
567 CONNECT BY OBJECT_ID = PRIOR SUBJECT_ID
568 AND RELATIONSHIP_TYPE_CODE = 'COMPONENT-OF'
569 AND TRUNC(NVL(ACTIVE_START_DATE,SYSDATE)) <= TRUNC(SYSDATE)
570 AND TRUNC(NVL(ACTIVE_END_DATE, SYSDATE+1)) > TRUNC(SYSDATE)
571 ORDER BY OWN_LEVEL, NODE_TYPE;
572
573 l_get_csi_child get_csi_children%ROWTYPE;
574 l_get_mc_child get_mc_children%ROWTYPE;
575
576 --Function to get position_necessity meaning for a given relationship_id
577 FUNCTION position_necessity(p_relationship_id NUMBER) RETURN VARCHAR2 IS
578 l_pos_necessity_meaning fnd_lookups.meaning%TYPE;
579 CURSOR get_position_necessity(c_relationship_id NUMBER) IS
580 SELECT F.meaning
581 FROM ahl_mc_relationships A,
582 fnd_lookup_values_vl F
583 WHERE A.relationship_id = c_relationship_id
584 AND A.position_necessity_code = F.lookup_code (+)
585 AND F.lookup_type (+) = 'AHL_POSITION_NECESSITY';
586 BEGIN
587 IF p_relationship_id IS NULL THEN
588 l_pos_necessity_meaning := NULL;
589 ELSE
590 OPEN get_position_necessity(p_relationship_id);
591 FETCH get_position_necessity INTO l_pos_necessity_meaning;
592 IF get_position_necessity%NOTFOUND THEN
593 FND_MESSAGE.set_name( 'AHL','AHL_UC_POSITION_INVALID' );
594 FND_MESSAGE.set_token('POSITION', p_relationship_id);
595 FND_MSG_PUB.add;
596 CLOSE get_position_necessity;
597 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
598 ELSE
599 CLOSE get_position_necessity;
600 END IF;
601 END IF;
602 RETURN l_pos_necessity_meaning;
603 END;
604
605 --Function to get instance information(part number plus serial number or
606 --instance number for a given instance_id
607 FUNCTION part_info(p_instance_id NUMBER) RETURN VARCHAR2 IS
608 l_part_info VARCHAR2(80);
609 CURSOR get_part_info(c_instance_id NUMBER) IS
610 SELECT M.concatenated_segments||'-'||NVL(C.serial_number, C.instance_number) part_info
611 FROM mtl_system_items_kfv M,
612 csi_item_instances C
613 WHERE C.instance_id = c_instance_id
614 AND C.inventory_item_id = M.inventory_item_id
615 AND C.inv_master_organization_id = M.organization_id;
616 BEGIN
617 OPEN get_part_info(p_instance_id);
618 FETCH get_part_info INTO l_part_info;
619 IF get_part_info%NOTFOUND THEN
620 FND_MESSAGE.set_name( 'AHL','AHL_UC_INSTANCE_INVALID' );
621 FND_MESSAGE.set_token('INSTANCE', p_instance_id);
622 FND_MSG_PUB.add;
623 CLOSE get_part_info;
624 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
625 ELSE
626 CLOSE get_part_info;
627 END IF;
628 RETURN l_part_info;
629 END;
630
631
632 BEGIN
633 --Initialize API return status to success
634 x_return_status := FND_API.G_RET_STS_SUCCESS;
635
636 --Standard call to check for call compatibility.
637 IF NOT FND_API.compatible_api_call(
638 l_api_version,
639 p_api_version,
640 l_api_name,
641 G_PKG_NAME)
642 THEN
643 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
644 END IF;
645 --Initialize message list if p_init_msg_list is set to TRUE.
646 IF FND_API.to_boolean( p_init_msg_list ) THEN
647 FND_MSG_PUB.initialize;
648 END IF;
649
650 IF (FND_LOG.LEVEL_PROCEDURE >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
651 FND_LOG.STRING(FND_LOG.LEVEL_PROCEDURE,
652 'ahl.plsql.'||G_PKG_NAME||'.'||l_api_name||': Begin API',
653 'At the start of the procedure');
654 END IF;
655 --Validate the input parameter and get the root instance_id and relationship_id
656 -- SATHAPLI::Enigma code changes, 02-Sep-2008 - fetch the ata_code as well
657 OPEN get_uc_header_attr(p_uc_header_id);
658 FETCH get_uc_header_attr INTO l_root_instance_id, l_root_mc_hdr_id, l_root_relationship_id, l_root_ata_code;
659 IF get_uc_header_attr%NOTFOUND THEN
660 FND_MESSAGE.set_name( 'AHL','AHL_UC_HEADER_ID_INVALID' );
661 FND_MESSAGE.set_token('UC_HEADER_ID', p_uc_header_id);
662 FND_MSG_PUB.add;
663 CLOSE get_uc_header_attr;
664 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
665 ELSE
666 CLOSE get_uc_header_attr;
667 END IF;
668
669 --Initialize l_uc_header_id
670 l_uc_header_id := p_uc_header_id;
671
672 --add the root node to the output table
673 total_i := 1; --index of the output table
674 x_uc_descendant_tbl(total_i).instance_id := l_root_instance_id;
675 x_uc_descendant_tbl(total_i).relationship_id := l_root_relationship_id;
676 x_uc_descendant_tbl(total_i).parent_instance_id := NULL;
677 x_uc_descendant_tbl(total_i).parent_rel_id := NULL;
678 x_uc_descendant_tbl(total_i).node_type := 'I';
679 x_uc_descendant_tbl(total_i).leaf_node_flag := 'N'; --might be 'Y' very seldomly?
680 x_uc_descendant_tbl(total_i).has_subconfig_flag := 'N'; --not applicable for root node
681
682 -- SATHAPLI::Enigma code changes, 02-Sep-2008 - populate the ata_code for the root
683 x_uc_descendant_tbl(total_i).ata_code := l_root_ata_code;
684
685 -- rbhavsar::FP Bug# 6268202, performance tuning
686 -- API ahl_mc_path_position_pvt.get_posref_for_uc need not be called for root
687 -- x_uc_descendant_tbl(total_i).position_reference := ahl_mc_path_position_pvt.get_posref_for_uc(l_uc_header_id, l_root_relationship_id);
688 OPEN get_pos_ref_csr(l_root_relationship_id);
689 FETCH get_pos_ref_csr INTO l_pos_ref;
690 CLOSE get_pos_ref_csr;
691 x_uc_descendant_tbl(total_i).position_reference := l_pos_ref;
692
693 --Even if p_uc_header_id is a subunit(installed or extra), when displaying its own tree, we pass its own
694 --p_uc_header_id instead of its parent_uc_header_id
695 x_uc_descendant_tbl(total_i).position_necessity := position_necessity(l_root_relationship_id);
696 x_uc_descendant_tbl(total_i).part_info := part_info(l_root_instance_id);
697 total_i := total_i + 1;
698
699 --Loop through all of the non leaf nodes of the UC tree, including the root node and extra node
700 FOR l_non_leaf_node IN get_non_leaf_nodes(l_root_instance_id) LOOP
701
702 --dbms_output.put_line('rel_id='||l_non_leaf_node.relationship_id||' uc_instance='||l_root_instance_id);
703 IF (l_non_leaf_node.relationship_id IS NOT NULL AND
704 NOT ahl_util_uc_pkg.extra_node(l_non_leaf_node.instance_id, l_root_instance_id)) THEN
705
706 --If the UC instance happens to be the top node of a sub UC, then when getting the
707 --MC descendants, the sub UC top node's relationship_id(got from uc headers table)
708 --instead of the relationship_id(got from position_reference in csi_ii_relationships)
709 --should be used. For UC root instance, the following cursor is also applicable.
710 OPEN check_sub_uc(l_non_leaf_node.instance_id);
711 FETCH check_sub_uc INTO l_uc_header_id, l_mc_header_id, l_relationship_id;
712
713 IF check_sub_uc%NOTFOUND THEN --not a sub UC's top node
714 l_relationship_id := l_non_leaf_node.relationship_id;
715 ahl_util_uc_pkg.get_parent_uc_header(l_non_leaf_node.instance_id, l_uc_header_id, l_dummy_num);
716
717 IF l_uc_header_id IS NULL THEN
718 l_uc_header_id := p_uc_header_id;
719 END IF;
720 END IF;
721 CLOSE check_sub_uc;
722
723 --Get all the immediate children of the corresponding UC node
724
725 --This is used to reset the l_uc_children_tbl and it is required, otherwise the elements
726 --left in the previous loop especially when the previous loop has more elements than the
727 --current loop, then these elements belonging to the previous loop will be inherited to
728 --the current loop.
729 -- rbhavsar::FP Bug# 6268202, performance tuning
730 -- use PL/SQL tables for BULK COLLECT instead of looping through the cursor records
731 /*
732 IF l_uc_children_tbl.COUNT > 0 THEN
733 l_uc_children_tbl.DELETE;
734 END IF;
735
736
737 i_uc_child := 0;
738 FOR l_get_csi_child IN get_csi_children(l_non_leaf_node.instance_id) LOOP
739 i_uc_child := i_uc_child + 1;
740 l_uc_children_tbl(i_uc_child).instance_id := l_get_csi_child.instance_id;
741 l_uc_children_tbl(i_uc_child).relationship_id := l_get_csi_child.relationship_id;
742 l_uc_children_tbl(i_uc_child).matched_flag := 'N'; -- default to 'N'
743 END LOOP;
744 */
745
746 IF l_child_inst_tbl.COUNT > 0 THEN
747 l_child_inst_tbl.DELETE;
748 l_child_rel_tbl.DELETE;
749 l_child_matchflag_tbl.DELETE;
750 l_child_partinfo_tbl.DELETE;
751 END IF;
752
753 OPEN get_csi_children(l_non_leaf_node.instance_id);
754 FETCH get_csi_children BULK COLLECT INTO l_child_inst_tbl,
755 l_child_rel_tbl,
756 l_child_partinfo_tbl,
757 l_child_matchflag_tbl;
758 CLOSE get_csi_children;
759
760 --Loop through all the immediate children of the MC node
761 FOR l_get_mc_child IN get_mc_children(l_relationship_id) LOOP
762 l_matched := FALSE;
763 IF l_child_inst_tbl.COUNT > 0 THEN
764 FOR i IN l_child_inst_tbl.FIRST..l_child_inst_tbl.LAST LOOP
765 IF (l_child_matchflag_tbl(i) = 'N' AND
766 l_get_mc_child.relationship_id = l_child_rel_tbl(i)) THEN
767 --Add these installed nodes to the output table
768 x_uc_descendant_tbl(total_i).instance_id := l_child_inst_tbl(i);
769 x_uc_descendant_tbl(total_i).relationship_id := l_child_rel_tbl(i);
770 x_uc_descendant_tbl(total_i).parent_instance_id := l_non_leaf_node.instance_id;
771 x_uc_descendant_tbl(total_i).parent_rel_id := l_non_leaf_node.relationship_id;
772 x_uc_descendant_tbl(total_i).node_type := 'I';
773
774 -- SATHAPLI::Enigma code changes, 02-Sep-2008 - populate the ata_code for the non-extra node
775 x_uc_descendant_tbl(total_i).ata_code := l_get_mc_child.ata_code;
776
777 -- rbhavsar::FP Bug# 6268202, performance tuning
778 -- API ahl_mc_path_position_pvt.get_posref_for_uc need not be called if
779 -- this relationship belongs to the root MC.
780 IF (l_get_mc_child.mc_header_id = l_root_mc_hdr_id) THEN
781 x_uc_descendant_tbl(total_i).position_reference := l_get_mc_child.pos_ref_meaning;
782 ELSE
783 x_uc_descendant_tbl(total_i).position_reference :=
784 ahl_mc_path_position_pvt.get_posref_for_uc(l_uc_header_id, l_child_rel_tbl(i));
785 END IF;
786
787 x_uc_descendant_tbl(total_i).position_necessity := l_get_mc_child.pos_necessity;
788 x_uc_descendant_tbl(total_i).part_info := l_child_partinfo_tbl(i);
789
790 --Leaf_node_flag is for front end display purpose, so we have to
791 --First check to see wether this installed node is a leaf node in CSI, if it is
792 --then we need to check whether the corresponding relationship_id is a leaf node
793 --in MC. Again we need to check whether this installed node happens to be a sub UC top node.
794 OPEN check_sub_uc(x_uc_descendant_tbl(total_i).instance_id);
795 FETCH check_sub_uc INTO l_dummy_num, l_mc_header_id, l_relationship_id;
796 IF check_sub_uc%NOTFOUND THEN --not a sub UC's top node
797 l_relationship_id := x_uc_descendant_tbl(total_i).relationship_id;
798 x_uc_descendant_tbl(total_i).has_subconfig_flag := 'N';
799 ELSE
800 x_uc_descendant_tbl(total_i).has_subconfig_flag := 'Y';
801 END IF;
802 CLOSE check_sub_uc;
803
804 -- rbhavsar::FP Bug# 6268202, performance tuning
805 OPEN chk_csi_leaf_node_csr(x_uc_descendant_tbl(total_i).instance_id);
806 FETCH chk_csi_leaf_node_csr INTO l_dummy;
807 IF chk_csi_leaf_node_csr%FOUND THEN
808 x_uc_descendant_tbl(total_i).leaf_node_flag := 'N';
809 ELSE
810 -- check from the MC
811 OPEN chk_mc_leaf_node_csr(l_relationship_id);
812 FETCH chk_mc_leaf_node_csr INTO l_dummy;
813 IF chk_mc_leaf_node_csr%FOUND THEN
814 x_uc_descendant_tbl(total_i).leaf_node_flag := 'N';
815 ELSE
816 x_uc_descendant_tbl(total_i).leaf_node_flag := 'Y';
817 END IF;
818 CLOSE chk_mc_leaf_node_csr;
819 END IF;
820 CLOSE chk_csi_leaf_node_csr;
821
822 total_i := total_i + 1;
823 l_matched := TRUE;
824 l_child_matchflag_tbl(i) := 'Y';
825 EXIT;
826 END IF; --whether relationship_id match condition
827 END LOOP; --l_uc_children_tbl
828 END IF; --whether table l_uc_children_tbl is empty
829
830 --dbms_output.put_line('Not installed node...');
831 IF NOT l_matched THEN -- empty node
832 --Add this empty node and all of its descendants to the output table
833 --dbms_output.put_line('i='||to_char(i)||':l_mc_children_table(i).installed_flag='||l_mc_children_tbl(i).installed_flag);
834 x_uc_descendant_tbl(total_i).instance_id := NULL;
835 x_uc_descendant_tbl(total_i).relationship_id := l_get_mc_child.relationship_id;
836 x_uc_descendant_tbl(total_i).parent_instance_id := l_non_leaf_node.instance_id;
837 x_uc_descendant_tbl(total_i).parent_rel_id := l_non_leaf_node.relationship_id;
838 x_uc_descendant_tbl(total_i).node_type := 'E';
839
840 -- SATHAPLI::Enigma code changes, 02-Sep-2008 - populate the ata_code for the non-extra node
841 x_uc_descendant_tbl(total_i).ata_code := l_get_mc_child.ata_code;
842
843 -- rbhavsar::FP Bug# 6268202, performance tuning
844 -- API ahl_mc_path_position_pvt.get_posref_for_uc need not be called if
845 -- this relationship belongs to the root MC.
846 IF (l_get_mc_child.mc_header_id = l_root_mc_hdr_id) THEN
847 l_root_mc_part := TRUE;
848 x_uc_descendant_tbl(total_i).position_reference := l_get_mc_child.pos_ref_meaning;
849 ELSE
850 l_root_mc_part := FALSE;
851 x_uc_descendant_tbl(total_i).position_reference :=
852 ahl_mc_path_position_pvt.get_posref_for_uc(l_uc_header_id, l_get_mc_child.relationship_id);
853 END IF;
854
855 x_uc_descendant_tbl(total_i).position_necessity := l_get_mc_child.pos_necessity;
856 x_uc_descendant_tbl(total_i).part_info := NULL;
857
858 -- rbhavsar::FP Bug# 6268202, performance tuning
859 OPEN chk_mc_leaf_node_csr(x_uc_descendant_tbl(total_i).relationship_id);
860 FETCH chk_mc_leaf_node_csr INTO l_dummy;
861 IF chk_mc_leaf_node_csr%FOUND THEN
862 x_uc_descendant_tbl(total_i).leaf_node_flag := 'N';
863 ELSE
864 x_uc_descendant_tbl(total_i).leaf_node_flag := 'Y';
865 END IF;
866 CLOSE chk_mc_leaf_node_csr;
867
868 OPEN has_sub_mc_csr(x_uc_descendant_tbl(total_i).relationship_id);
869 FETCH has_sub_mc_csr INTO l_dummy;
870 IF has_sub_mc_csr%FOUND THEN
871 x_uc_descendant_tbl(total_i).has_subconfig_flag := 'Y';
872 ELSE
873 x_uc_descendant_tbl(total_i).has_subconfig_flag := 'N';
874 END IF;
875 CLOSE has_sub_mc_csr;
876
877 total_i := total_i + 1;
878 FOR l_get_mc_descendant IN get_mc_descendants(l_get_mc_child.relationship_id) LOOP
879 x_uc_descendant_tbl(total_i).instance_id := NULL;
880 x_uc_descendant_tbl(total_i).relationship_id := l_get_mc_descendant.relationship_id;
881
882 --Changed on 02/04/2004 per Cheng's requirement. Actually using parent_instance_id to
883 --represent the lowest ancestor instance for the empty node
884 x_uc_descendant_tbl(total_i).parent_instance_id := l_non_leaf_node.instance_id;
885 --x_uc_descendant_tbl(total_i).parent_instance_id := NULL;
886
887 x_uc_descendant_tbl(total_i).parent_rel_id := l_get_mc_descendant.parent_rel_id;
888 x_uc_descendant_tbl(total_i).node_type := 'E';
889
890 -- SATHAPLI::Enigma code changes, 02-Sep-2008 - populate the ata_code for the non-extra node
891 x_uc_descendant_tbl(total_i).ata_code := l_get_mc_descendant.ata_code;
892
893 -- rbhavsar::FP Bug# 6268202, performance tuning
894 -- API ahl_mc_path_position_pvt.get_posref_for_uc need not be called if
895 -- the ancestor relationship belongs to the root MC.
896 IF (l_root_mc_part) THEN
897 x_uc_descendant_tbl(total_i).position_reference := l_get_mc_descendant.pos_ref_meaning;
898 ELSE
899 x_uc_descendant_tbl(total_i).position_reference :=
900 ahl_mc_path_position_pvt.get_posref_for_uc(l_uc_header_id, l_get_mc_descendant.relationship_id);
901 END IF;
902
903 x_uc_descendant_tbl(total_i).position_necessity := l_get_mc_descendant.pos_necessity;
904 x_uc_descendant_tbl(total_i).part_info := NULL;
905
906 -- rbhavsar::FP Bug# 6268202, performance tuning
907 OPEN chk_mc_leaf_node_csr(x_uc_descendant_tbl(total_i).relationship_id);
908 FETCH chk_mc_leaf_node_csr INTO l_dummy;
909 IF chk_mc_leaf_node_csr%FOUND THEN
910 x_uc_descendant_tbl(total_i).leaf_node_flag := 'N';
911 x_uc_descendant_tbl(total_i).has_subconfig_flag := 'N';
912 ELSE
913 x_uc_descendant_tbl(total_i).leaf_node_flag := 'Y';
914 --Only if it is empty leaf node in MC then it is necessary to check whether there
915 --are some sub MCs can be associated to this node
916 OPEN has_sub_mc_csr(x_uc_descendant_tbl(total_i).relationship_id);
917 FETCH has_sub_mc_csr INTO l_dummy;
918 IF has_sub_mc_csr%FOUND THEN
919 x_uc_descendant_tbl(total_i).has_subconfig_flag := 'Y';
920 ELSE
921 x_uc_descendant_tbl(total_i).has_subconfig_flag := 'N';
922 END IF;
923 CLOSE has_sub_mc_csr;
924 END IF;
925 CLOSE chk_mc_leaf_node_csr;
926
927 total_i := total_i + 1;
928 END LOOP; --loop of get_mc_descendants
929 END IF; --l_matched condition
930 END LOOP; --loop of get_mc_children
931
932 --dbms_output.put_line('After empty node...');
933 --Check each instance in the temporary UC children table, if it is not matched,
934 --then it is an extra node. Add this extra node's immediate children to the output table
935 IF l_child_inst_tbl.COUNT > 0 THEN
936 FOR i IN l_child_inst_tbl.FIRST..l_child_inst_tbl.LAST LOOP
937 IF l_child_matchflag_tbl(i) = 'N' THEN
938 x_uc_descendant_tbl(total_i).instance_id := l_child_inst_tbl(i);
939 x_uc_descendant_tbl(total_i).relationship_id := l_child_rel_tbl(i);
940 x_uc_descendant_tbl(total_i).parent_instance_id := l_non_leaf_node.instance_id;
941 x_uc_descendant_tbl(total_i).parent_rel_id := l_non_leaf_node.relationship_id;
942 x_uc_descendant_tbl(total_i).node_type := 'X';
943 x_uc_descendant_tbl(total_i).position_reference := NULL;
944 -- ahl_mc_path_position_pvt.get_posref_for_uc(l_uc_header_id, l_uc_children_tbl(i).relationship_id);
945 x_uc_descendant_tbl(total_i).position_necessity := NULL;
946 x_uc_descendant_tbl(total_i).part_info := l_child_partinfo_tbl(i);
947
948 -- rbhavsar::FP Bug# 6268202, performance tuning
949 OPEN chk_csi_leaf_node_csr(x_uc_descendant_tbl(total_i).instance_id);
950 FETCH chk_csi_leaf_node_csr INTO l_dummy;
951 IF chk_csi_leaf_node_csr%FOUND THEN
952 x_uc_descendant_tbl(total_i).leaf_node_flag := 'N';
953 ELSE
954 x_uc_descendant_tbl(total_i).leaf_node_flag := 'Y';
955 END IF;
956 CLOSE chk_csi_leaf_node_csr;
957
958 OPEN check_sub_uc(x_uc_descendant_tbl(total_i).instance_id);
959 FETCH check_sub_uc INTO l_uc_header_id, l_mc_header_id, l_relationship_id;
960 IF check_sub_uc%NOTFOUND THEN --not a sub UC's top node
961 x_uc_descendant_tbl(total_i).has_subconfig_flag := 'N';
962 ELSE
963 x_uc_descendant_tbl(total_i).has_subconfig_flag := 'Y';
964 END IF;
965 CLOSE check_sub_uc;
966
967 total_i := total_i + 1;
968 END IF; --matched_flag condition
969 END LOOP; --loop of l_uc_children_tbl
970 END IF; --whether table l_uc_children_tbl is empty
971
972 ELSE --an extra node in all non leaf nodes
973 --add this node's immediate children instead of itself into the output table,
974 --because this node has already been added into the output table when processing its
975 --parent node.
976 FOR l_get_csi_child IN get_csi_children(l_non_leaf_node.instance_id) LOOP
977 x_uc_descendant_tbl(total_i).node_type := 'X';
978 x_uc_descendant_tbl(total_i).instance_id := l_get_csi_child.instance_id;
979 x_uc_descendant_tbl(total_i).relationship_id := l_get_csi_child.relationship_id;
980 x_uc_descendant_tbl(total_i).parent_instance_id := l_non_leaf_node.instance_id;
981 x_uc_descendant_tbl(total_i).parent_rel_id := NULL;
982 x_uc_descendant_tbl(total_i).position_reference := NULL;
983 -- ahl_mc_path_position_pvt.get_posref_for_uc(l_uc_header_id, l_get_csi_child.relationship_id);
984 x_uc_descendant_tbl(total_i).position_necessity := NULL;
985 x_uc_descendant_tbl(total_i).part_info := l_get_csi_child.part_info;
986
987 -- rbhavsar::FP Bug# 6268202, performance tuning
988 OPEN chk_csi_leaf_node_csr(x_uc_descendant_tbl(total_i).instance_id);
989 FETCH chk_csi_leaf_node_csr INTO l_dummy;
990 IF chk_csi_leaf_node_csr%FOUND THEN
991 x_uc_descendant_tbl(total_i).leaf_node_flag := 'N';
992 ELSE
993 x_uc_descendant_tbl(total_i).leaf_node_flag := 'Y';
994 END IF;
995 CLOSE chk_csi_leaf_node_csr;
996
997 OPEN check_sub_uc(x_uc_descendant_tbl(total_i).instance_id);
998 FETCH check_sub_uc INTO l_uc_header_id, l_mc_header_id, l_relationship_id;
999 IF check_sub_uc%NOTFOUND THEN --not a sub UC's top node
1000 x_uc_descendant_tbl(total_i).has_subconfig_flag := 'N';
1001 ELSE
1002 x_uc_descendant_tbl(total_i).has_subconfig_flag := 'Y';
1003 END IF;
1004 CLOSE check_sub_uc;
1005
1006 total_i := total_i + 1;
1007 END LOOP;
1008 END IF; --whether l_non_leaf_node is extra node
1009 END LOOP; --loop of get_non_leaf_nodes
1010
1011 IF (FND_LOG.LEVEL_PROCEDURE >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1012 FND_LOG.STRING(FND_LOG.LEVEL_PROCEDURE,
1013 'ahl.plsql.'||G_PKG_NAME||'.'||l_api_name||': After normal execution',
1014 'At the end of the procedure');
1015 END IF;
1016 -- Get all the error messages from the previous steps (if any) and raise the appropriate Exception
1017 l_msg_count := FND_MSG_PUB.count_msg;
1018 IF l_msg_count > 0 THEN
1019 x_msg_count := l_msg_count;
1020 RAISE FND_API.G_EXC_ERROR;
1021 END IF;
1022 -- Count and Get messages (optional)
1023 FND_MSG_PUB.count_and_get(
1024 p_encoded => FND_API.G_FALSE,
1025 p_count => x_msg_count,
1026 p_data => x_msg_data);
1027
1028 EXCEPTION
1029 WHEN FND_API.G_EXC_ERROR THEN
1030 x_return_status := FND_API.G_RET_STS_ERROR ;
1031 FND_MSG_PUB.count_and_get(
1032 p_encoded => FND_API.G_FALSE,
1033 p_count => x_msg_count,
1034 p_data => x_msg_data);
1035
1036 WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
1037 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR ;
1038 FND_MSG_PUB.count_and_get(
1039 p_encoded => FND_API.G_FALSE,
1040 p_count => x_msg_count,
1041 p_data => x_msg_data);
1042
1043 WHEN OTHERS THEN
1044 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR ;
1045 IF FND_MSG_PUB.check_msg_level(FND_MSG_PUB.G_MSG_LVL_UNEXP_ERROR)
1046 THEN
1047 FND_MSG_PUB.add_exc_msg(
1048 p_pkg_name => G_PKG_NAME,
1049 p_procedure_name => l_api_name,
1050 p_error_text => SUBSTRB(SQLERRM,1,240));
1051 END IF;
1052 FND_MSG_PUB.count_and_get(
1053 p_encoded => FND_API.G_FALSE,
1054 p_count => x_msg_count,
1055 p_data => x_msg_data);
1056 END;
1057
1058 -- Define Procedure migrate_uc_tree --
1059 -- This API is used to migrate a UC tree to a new MC revision or copy
1060 PROCEDURE migrate_uc_tree(
1061 p_api_version IN NUMBER,
1062 p_init_msg_list IN VARCHAR2 := FND_API.G_FALSE,
1063 p_commit IN VARCHAR2 := FND_API.G_FALSE,
1064 p_validation_level IN NUMBER := FND_API.G_VALID_LEVEL_FULL,
1065 x_return_status OUT NOCOPY VARCHAR2,
1066 x_msg_count OUT NOCOPY NUMBER,
1067 x_msg_data OUT NOCOPY VARCHAR2,
1068 p_uc_header_id IN NUMBER,
1069 p_mc_header_id IN NUMBER)
1070 IS
1071 TYPE l_mc_children_rec_type IS RECORD(
1072 relationship_id NUMBER,
1073 position_key NUMBER,
1074 position_ref_code VARCHAR2(30),
1075 item_group_id NUMBER,
1076 matched_flag VARCHAR2(1));
1077 TYPE l_mc_children_tbl_type IS TABLE OF l_mc_children_rec_type INDEX BY BINARY_INTEGER;
1078 l_mc_children_tbl l_mc_children_tbl_type;
1079 l_api_name CONSTANT VARCHAR2(30) := 'migrate_uc_tree';
1080 l_api_version CONSTANT NUMBER := 1.0;
1081 l_return_status VARCHAR2(1);
1082 l_evaluation_status VARCHAR2(1);
1083 l_msg_count NUMBER;
1084 l_msg_data VARCHAR2(2000);
1085 l_relationship_id NUMBER;
1086 l_mc_header_id NUMBER;
1087 l_mc_name ahl_mc_headers_b.name%TYPE;
1088 l_mc_revision ahl_mc_headers_b.revision%TYPE;
1089 l_mc_status_code FND_LOOKUP_VALUES.lookup_code%TYPE;
1090 l_root_instance_id NUMBER;
1091 l_root_relationship_id NUMBER;
1092 l_mc_top_rel_id NUMBER;
1093 l_parent_uc_header_id NUMBER;
1094 l_parent_instance_id NUMBER;
1095 l_sub_top_rel_id NUMBER;
1096 l_sub_mc_header_id NUMBER;
1097 l_boolean_var BOOLEAN;
1098 l_dummy NUMBER;
1099 i NUMBER;
1100 i_mc_child NUMBER;
1101 l_item_match BOOLEAN;
1102 l_matched BOOLEAN;
1103 l_return_value BOOLEAN;
1104 l_transaction_type_id NUMBER;
1105 l_version_no NUMBER;
1106 l_uc_header_all ahl_unit_config_headers%ROWTYPE;
1107 l_csi_relationship_rec csi_datastructures_pub.ii_relationship_rec;
1108 l_csi_relationship_tbl csi_datastructures_pub.ii_relationship_tbl;
1109 l_csi_transaction_rec csi_datastructures_pub.transaction_rec;
1110 l_root_uc_header_id NUMBER;
1111 l_root_uc_status_code FND_LOOKUP_VALUES.lookup_code%TYPE;
1112 l_root_active_uc_status_code FND_LOOKUP_VALUES.lookup_code%TYPE;
1113 l_root_uc_ovn NUMBER;
1114 l_new_relationship_id NUMBER;
1115 --In order to check whether the instance belongs to a sub unit or an extra node branch
1116 CURSOR check_subuc_extra(c_instance_id NUMBER, c_top_instance_id NUMBER) IS
1117 SELECT object_id, subject_id, position_reference
1118 FROM csi_ii_relationships
1119 WHERE subject_id IN (SELECT csi_item_instance_id
1120 FROM ahl_unit_config_headers
1121 WHERE trunc(nvl(active_end_date, SYSDATE+1)) > trunc(SYSDATE))
1122 OR position_reference IS NULL
1123 START WITH subject_id = c_instance_id
1124 AND relationship_type_code = 'COMPONENT-OF'
1125 AND trunc(nvl(active_start_date,SYSDATE)) <= trunc(SYSDATE)
1126 AND trunc(nvl(active_end_date, SYSDATE+1)) > trunc(SYSDATE)
1127 CONNECT BY subject_id = PRIOR object_id
1128 AND relationship_type_code = 'COMPONENT-OF'
1129 AND trunc(nvl(active_start_date,SYSDATE)) <= trunc(SYSDATE)
1130 AND trunc(nvl(active_end_date, SYSDATE+1)) > trunc(SYSDATE)
1131 AND subject_id <> c_top_instance_id;
1132 l_check_subuc_extra check_subuc_extra%ROWTYPE;
1133 --Check the given uc_heder_id is existing and if yes, get its status and other information
1134 CURSOR check_uc_header IS
1135 SELECT U.unit_config_status_code uc_status_code,
1136 U.active_uc_status_code,
1137 U.csi_item_instance_id instance_id,
1138 U.master_config_id mc_header_id,
1139 U.object_version_number,
1140 C.inventory_item_id inventory_item_id,
1141 C.inv_master_organization_id inventory_org_id,
1142 C.inventory_revision,
1143 C.quantity,
1144 C.unit_of_measure
1145 FROM ahl_unit_config_headers U,
1146 csi_item_instances C
1147 WHERE U.unit_config_header_id = p_uc_header_id
1148 AND trunc(nvl(U.active_end_date, SYSDATE+1)) > trunc(SYSDATE)
1149 AND U.csi_item_instance_id = C.instance_id;
1150 l_uc_header_attr check_uc_header%ROWTYPE;
1151 CURSOR check_mc_header IS
1152 SELECT H.mc_header_id,
1153 H.config_status_code,
1154 R.relationship_id,
1155 H.name,
1156 H.revision
1157 FROM ahl_mc_headers_b H,
1158 ahl_mc_relationships R
1159 WHERE H.mc_header_id = p_mc_header_id
1160 AND R.mc_header_id = H.mc_header_id
1161 AND R.parent_relationship_id IS NULL
1162 AND trunc(nvl(R.active_start_date,SYSDATE)) <= trunc(SYSDATE)
1163 AND trunc(nvl(R.active_end_date, SYSDATE+1)) > trunc(SYSDATE);
1164 CURSOR get_mc_header_items(c_mc_header_id NUMBER) IS
1165 SELECT M.relationship_id,
1166 I.inventory_item_id,
1167 I.inventory_org_id
1168 FROM ahl_mc_relationships M,
1169 ahl_item_associations_b I
1170 WHERE M.mc_header_id = c_mc_header_id
1171 AND M.parent_relationship_id IS NULL
1172 AND M.item_group_id = I.item_group_id;
1173 /*
1174 CURSOR get_associated_items(c_item_group_id NUMBER) IS
1175 SELECT inventory_item_id,
1176 inventory_org_id
1177 FROM ahl_item_associations_b
1178 WHERE item_group_id = c_item_group_id;
1179 l_get_associated_item get_associated_items%ROWTYPE;
1180 */
1181
1182 --Given an instance_id, get all of its immediate children from csi_ii_relationships
1183 CURSOR get_csi_children(c_instance_id NUMBER) IS
1184 SELECT C.relationship_id csi_ii_relationship_id,
1185 C.object_version_number csi_ii_relationship_ovn,
1186 C.object_id parent_instance_id,
1187 C.subject_id instance_id,
1188 to_number(C.position_reference) relationship_id,
1189 M.position_key,
1190 M.position_ref_code,
1191 I.inventory_item_id,
1192 I.inv_master_organization_id inventory_org_id,
1193 I.inventory_revision,
1194 I.quantity,
1195 I.unit_of_measure
1196 FROM csi_ii_relationships C,
1197 ahl_mc_relationships M,
1198 csi_item_instances I
1199 WHERE to_number(C.position_reference) = M.relationship_id (+)
1200 AND C.subject_id = I.instance_id
1201 AND C.object_id = c_instance_id
1202 AND C.relationship_type_code = 'COMPONENT-OF'
1203 AND trunc(nvl(C.active_start_date,SYSDATE)) <= trunc(SYSDATE)
1204 AND trunc(nvl(C.active_end_date, SYSDATE+1)) > trunc(SYSDATE);
1205 --Given an relationship_id, get all of its immediate children from MC
1206 CURSOR get_mc_children(c_relationship_id NUMBER) IS
1207 SELECT parent_relationship_id parent_rel_id,
1208 relationship_id,
1209 position_key,
1210 position_ref_code,
1211 item_group_id
1212 FROM ahl_mc_relationships
1213 WHERE parent_relationship_id = c_relationship_id
1214 AND trunc(nvl(active_start_date,SYSDATE)) <= trunc(SYSDATE)
1215 AND trunc(nvl(active_end_date, SYSDATE+1)) > trunc(SYSDATE);
1216 --Check whether an instance in UC is the top node of a sub UC, if yes, then get the
1217 --relationship of the sub UC's top node
1218 CURSOR check_sub_uc(c_instance_id NUMBER) IS
1219 SELECT A.master_config_id mc_header_id,
1220 B.relationship_id
1221 FROM ahl_unit_config_headers A,
1222 ahl_mc_relationships B
1223 WHERE A.csi_item_instance_id = c_instance_id
1224 AND trunc(nvl(A.active_end_date, SYSDATE+1)) > trunc(SYSDATE)
1225 AND B.mc_header_id = A.master_config_id
1226 AND B.parent_relationship_id IS NULL
1227 AND trunc(nvl(B.active_start_date,SYSDATE)) <= trunc(SYSDATE)
1228 AND trunc(nvl(B.active_end_date, SYSDATE+1)) > trunc(SYSDATE);
1229 l_check_sub_uc check_sub_uc%ROWTYPE;
1230 --Given a position(leaf) in MC, get all the sub MCs which can be associated to this position
1231 CURSOR get_sub_mcs(c_relationship_id NUMBER) IS
1232 SELECT mc_header_id
1233 FROM ahl_mc_config_relations
1234 WHERE relationship_id = c_relationship_id
1235 AND trunc(nvl(active_start_date,SYSDATE)) <= trunc(SYSDATE)
1236 AND trunc(nvl(active_end_date, SYSDATE+1)) > trunc(SYSDATE);
1237 --Based on the UC, list all of the non leaf nodes including the root node
1238 CURSOR get_non_leaf_nodes(c_instance_id NUMBER) IS
1239 SELECT TO_NUMBER(NULL) parent_instance_id, --just include the root uc node
1240 B.csi_item_instance_id instance_id,
1241 A.relationship_id
1242 FROM ahl_unit_config_headers B,
1243 ahl_mc_relationships A
1244 WHERE B.csi_item_instance_id = c_instance_id
1245 AND trunc(nvl(B.active_end_date, SYSDATE+1)) > trunc(SYSDATE)
1246 AND A.mc_header_id = B.master_config_id
1247 AND A.parent_relationship_id IS NULL
1248 UNION ALL
1249 SELECT object_id parent_instance_id,
1250 subject_id instance_id,
1251 to_number(position_reference) relationship_id
1252 FROM csi_ii_relationships A
1253 --remove all of the leaf node after finishing the hierarchical query
1254 WHERE EXISTS (SELECT 'x'
1255 FROM csi_ii_relationships B
1256 WHERE B.object_id = A.subject_id
1257 AND relationship_type_code = 'COMPONENT-OF'
1258 AND trunc(nvl(active_start_date,SYSDATE)) <= trunc(SYSDATE)
1259 AND trunc(nvl(active_end_date, SYSDATE+1)) > trunc(SYSDATE))
1260 START WITH object_id = c_instance_id
1261 AND relationship_type_code = 'COMPONENT-OF'
1262 AND trunc(nvl(active_start_date,SYSDATE)) <= trunc(SYSDATE)
1263 AND trunc(nvl(active_end_date, SYSDATE+1)) > trunc(SYSDATE)
1264 CONNECT BY object_id = PRIOR subject_id
1265 AND relationship_type_code = 'COMPONENT-OF'
1266 AND trunc(nvl(active_start_date,SYSDATE)) <= trunc(SYSDATE)
1267 AND trunc(nvl(active_end_date, SYSDATE+1)) > trunc(SYSDATE);
1268
1269 CURSOR get_position_reference(c_object_id NUMBER, c_subject_id NUMBER) IS
1270 SELECT relationship_id csi_ii_relationship_id,
1271 object_version_number csi_ii_relationship_ovn,
1272 to_number(position_reference) relationship_id
1273 FROM csi_ii_relationships
1274 WHERE object_id = c_object_id
1275 AND subject_id = c_subject_id
1276 AND relationship_type_code = 'COMPONENT-OF'
1277 AND trunc(nvl(active_start_date,SYSDATE)) <= trunc(SYSDATE)
1278 AND trunc(nvl(active_end_date, SYSDATE+1)) > trunc(SYSDATE);
1279 l_position_info get_position_reference%ROWTYPE;
1280
1281 BEGIN
1282 --Initialize API return status to success
1283 x_return_status := FND_API.G_RET_STS_SUCCESS;
1284
1285 -- Standard Start of API savepoint
1286 SAVEPOINT migrate_uc_tree;
1287
1288 --Standard call to check for call compatibility.
1289 IF NOT FND_API.compatible_api_call(
1290 l_api_version,
1291 p_api_version,
1292 l_api_name,
1293 G_PKG_NAME)
1294 THEN
1295 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1296 END IF;
1297
1298 --Initialize message list if p_init_msg_list is set to TRUE.
1299 IF FND_API.to_boolean( p_init_msg_list ) THEN
1300 FND_MSG_PUB.initialize;
1301 END IF;
1302
1303 IF (FND_LOG.LEVEL_PROCEDURE >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1304 FND_LOG.STRING(FND_LOG.LEVEL_PROCEDURE,
1305 'ahl.plsql.'||G_PKG_NAME||'.'||l_api_name||': Begin API',
1306 'At the start of the procedure');
1307 END IF;
1308
1309 --Validate the input parameter p_uc_header_id and its status
1310 --Validate input parameter p_uc_header_id, its two status
1311 OPEN check_uc_header;
1312 FETCH check_uc_header INTO l_uc_header_attr;
1313 IF check_uc_header%NOTFOUND THEN
1314 FND_MESSAGE.set_name( 'AHL','AHL_UC_API_PARAMETER_INVALID');
1315 FND_MESSAGE.set_token('NAME', 'uc_header_id');
1316 FND_MESSAGE.set_token('VALUE', p_uc_header_id);
1317 FND_MSG_PUB.add;
1318 CLOSE check_uc_header;
1319 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1320 ELSE
1321
1322 -- ACL :: Changes for R12
1323 IF (ahl_util_uc_pkg.IS_UNIT_QUARANTINED(p_unit_header_id => p_uc_header_id , p_instance_id => null) = FND_API.G_TRUE) THEN
1324 FND_MESSAGE.set_name( 'AHL','AHL_UC_INVALID_Q_ACTION' );
1325 FND_MSG_PUB.add;
1326 CLOSE check_uc_header;
1327 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1328 END IF;
1329
1330 ahl_util_uc_pkg.get_root_uc_attr(p_uc_header_id,
1331 l_root_uc_header_id,
1332 l_root_instance_id,
1333 l_root_uc_status_code,
1334 l_root_active_uc_status_code,
1335 l_root_uc_ovn);
1336 IF (l_root_uc_status_code = 'APPROVAL_PENDING' OR
1337 l_root_active_uc_status_code = 'APPROVAL_PENDING') THEN
1338 FND_MESSAGE.set_name( 'AHL','AHL_UC_STATUS_PENDING' );
1339 FND_MESSAGE.set_token('UC_HEADER_ID', l_root_uc_header_id);
1340 FND_MSG_PUB.add;
1341 CLOSE check_uc_header;
1342 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1343 ELSE
1344 CLOSE check_uc_header;
1345 END IF;
1346 END IF;
1347
1348 --Validate the input parameter p_mc_header_id and get its status
1349 OPEN check_mc_header;
1350 FETCH check_mc_header INTO l_mc_header_id,
1351 l_mc_status_code,
1352 l_mc_top_rel_id,
1353 l_mc_name,
1354 l_mc_revision;
1355 IF check_mc_header%NOTFOUND THEN
1356 FND_MESSAGE.set_name( 'AHL','AHL_UC_API_PARAMETER_INVALID');
1357 FND_MESSAGE.set_token('NAME', 'mc_header_id');
1358 FND_MESSAGE.set_token('VALUE', p_mc_header_id);
1359 FND_MSG_PUB.add;
1360 CLOSE check_mc_header;
1361 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1362 ELSE
1363 IF l_mc_status_code <> 'COMPLETE' THEN
1364 FND_MESSAGE.set_name( 'AHL','AHL_UC_MC_NOT_COMPLETE' );
1365 FND_MESSAGE.set_token('NAME', l_mc_name);
1366 FND_MESSAGE.set_token('REVISION', l_mc_revision);
1367 FND_MSG_PUB.add;
1368 CLOSE check_mc_header;
1369 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1370 ELSIF l_mc_header_id = l_uc_header_attr.mc_header_id THEN
1371 FND_MESSAGE.set_name( 'AHL','AHL_UC_MC_MIGRATE_SAME' );
1372 FND_MESSAGE.set_token('NAME', l_mc_name);
1373 FND_MESSAGE.set_token('REVISION', l_mc_revision);
1374 FND_MSG_PUB.add;
1375 CLOSE check_mc_header;
1376 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1377 ELSE
1378 CLOSE check_mc_header;
1379 END IF;
1380 END IF;
1381
1382 --The following lines are used to update the position_reference column in csi_ii_relationships
1383 --First, get transaction_type_id .
1384 AHL_UTIL_UC_PKG.getcsi_transaction_id('UC_UPDATE',l_transaction_type_id, l_return_value);
1385 IF NOT l_return_value THEN
1386 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1387 END IF;
1388
1389 --For UC root node, only need to ensure item matches, no need to check position key
1390 --and position_reference
1391 IF p_uc_header_id = l_root_uc_header_id THEN
1392 --Standalone UC or UC installed in a CSI instance, only need to check whether
1393 --item match for the top node
1394 l_item_match := AHL_UTIL_UC_PKG.item_match(l_mc_top_rel_id,
1395 l_uc_header_attr.inventory_item_id,
1396 l_uc_header_attr.inventory_org_id,
1397 l_uc_header_attr.inventory_revision,
1398 l_uc_header_attr.quantity,
1399 l_uc_header_attr.unit_of_measure);
1400 IF NOT l_item_match THEN
1401 --dbms_output.put_line('l_root_uc_header_id='||l_root_uc_header_id||' l_mc_top_rel_id='||l_mc_top_rel_id);
1402 --dbms_output.put_line('inventory_item_id='||l_uc_header_attr.inventory_item_id||' inventory_org_id='||l_uc_header_attr.inventory_org_id);
1403 --dbms_output.put_line('revision='||l_uc_header_attr.inventory_revision||' quantity='||l_uc_header_attr.quantity);
1404 --dbms_output.put_line('uom='||l_uc_header_attr.unit_of_measure);
1405 FND_MESSAGE.set_name( 'AHL','AHL_UC_HEADER_NOT_MATCH' );
1406 FND_MSG_PUB.add;
1407 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1408 ELSE
1409 --Item matches, can be migrated and thus change the mc_header_id of the UC header
1410 NULL;
1411 END IF;
1412 ELSIF (p_uc_header_id <> l_root_uc_header_id) THEN
1413 --Sub unit installed on another unit, either extra node or non extra node
1414 ahl_util_uc_pkg.get_parent_uc_header(l_uc_header_attr.instance_id,
1415 l_parent_uc_header_id,
1416 l_parent_instance_id);
1417 --Get its parent_instance_id in order to check whether it is an extra node within
1418 --the context of its parent UC
1419 IF NOT ahl_util_uc_pkg.extra_node(l_uc_header_attr.instance_id, l_parent_instance_id) THEN
1420 --Non extra sub unit within the context of its parent unit
1421 --Get its position_reference
1422 OPEN get_position_reference(l_parent_instance_id, l_uc_header_attr.instance_id);
1423 FETCH get_position_reference INTO l_position_info;
1424 IF get_position_reference%NOTFOUND THEN
1425 FND_MESSAGE.set_name( 'AHL','AHL_UC_UNIT_UNINSTALLED' );
1426 FND_MESSAGE.set_token('CHILD',l_uc_header_attr.instance_id);
1427 FND_MESSAGE.set_token('PARENT',l_parent_instance_id);
1428 FND_MSG_PUB.add;
1429 CLOSE get_position_reference;
1430 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1431 END IF;
1432 CLOSE get_position_reference;
1433 --Check whether the new mc_header_id to which to be migrated could be an alternate sub MC
1434 --in position
1435 l_boolean_var := FALSE;
1436 FOR l_get_sub_mcs IN get_sub_mcs(l_position_info.relationship_id) LOOP
1437 l_sub_mc_header_id := l_get_sub_mcs.mc_header_id;
1438 IF l_sub_mc_header_id = p_mc_header_id THEN
1439 l_boolean_var := TRUE;
1440 EXIT;
1441 END IF;
1442 END LOOP;
1443 IF NOT l_boolean_var THEN
1444 --Again check whether item match
1445 l_item_match := AHL_UTIL_UC_PKG.item_match(l_mc_top_rel_id,
1446 l_uc_header_attr.inventory_item_id,
1447 l_uc_header_attr.inventory_org_id,
1448 l_uc_header_attr.inventory_revision,
1449 l_uc_header_attr.quantity,
1450 l_uc_header_attr.unit_of_measure);
1451 IF NOT l_item_match THEN
1452 FND_MESSAGE.set_name( 'AHL','AHL_UC_HEADER_NOT_MATCH' );
1453 FND_MSG_PUB.add;
1454 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1455 ELSE
1456 --Make the sub unit an extra node in its parent unit context and
1457 --update its own mc_header_id to the new p_mc_header_id
1458
1459 --Set the CSI transaction record
1460 l_csi_transaction_rec.source_transaction_date := SYSDATE;
1461 l_csi_transaction_rec.transaction_type_id := l_transaction_type_id;
1462 --Set CSI relationship record
1463 l_csi_relationship_rec.relationship_id := l_position_info.csi_ii_relationship_id;
1464 l_csi_relationship_rec.object_version_number := l_position_info.csi_ii_relationship_ovn;
1465 l_csi_relationship_rec.position_reference := NULL;
1466 l_csi_relationship_rec.relationship_type_code := 'COMPONENT-OF';
1467 l_csi_relationship_rec.object_id := l_parent_instance_id;
1468 l_csi_relationship_rec.subject_id := l_uc_header_attr.instance_id;
1469 l_csi_relationship_tbl(1) := l_csi_relationship_rec;
1470 CSI_II_RELATIONSHIPS_PUB.update_relationship(
1471 p_api_version => 1.0,
1472 p_relationship_tbl => l_csi_relationship_tbl,
1473 p_txn_rec => l_csi_transaction_rec,
1474 x_return_status => l_return_status,
1475 x_msg_count => l_msg_count,
1476 x_msg_data => l_msg_data);
1477 IF (l_return_status = FND_API.G_RET_STS_ERROR) THEN
1478 RAISE FND_API.G_EXC_ERROR;
1479 ELSIF (l_return_status = FND_API.G_RET_STS_UNEXP_ERROR) THEN
1480 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1481 END IF;
1482 --Could be migrated and thus change the mc_header_id of the UC header
1483 NULL;
1484 END IF;
1485 ELSE
1486 --The sub unit is still an alternate sub unit so only need to update
1487 --its own mc_header_id to the new p_mc_header_id
1488 NULL;
1489 END IF;
1490 ELSE
1491 --Extra node and check whether item match
1492 l_item_match := AHL_UTIL_UC_PKG.item_match(l_mc_top_rel_id,
1493 l_uc_header_attr.inventory_item_id,
1494 l_uc_header_attr.inventory_org_id,
1495 l_uc_header_attr.inventory_revision,
1496 l_uc_header_attr.quantity,
1497 l_uc_header_attr.unit_of_measure);
1498 IF NOT l_item_match THEN
1499 FND_MESSAGE.set_name( 'AHL','AHL_UC_HEADER_NOT_MATCH' );
1500 FND_MSG_PUB.add;
1501 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1502 ELSE
1503 --Could be migrated but will be still extra node to its parent unit
1504 --Not necessary to update position_reference to NULL because it is already an
1505 --extra node to its parent unit
1506 NULL;
1507 END IF;
1508 END IF;
1509 END IF;
1510 --Update the master_config_id of p_uc_header_id to the new p_mc_header_id
1511 IF p_uc_header_id = l_root_uc_header_id THEN
1512 --For standalone no object_version_number change here because we have to update the
1513 --status for the same record after migration
1514 UPDATE ahl_unit_config_headers
1515 SET master_config_id = p_mc_header_id,
1516 last_updated_by = fnd_global.user_id,
1517 last_update_date = SYSDATE,
1518 last_update_login = fnd_global.login_id
1519 WHERE unit_config_header_id = p_uc_header_id
1520 AND object_version_number = l_uc_header_attr.object_version_number;
1521 ELSE
1522 UPDATE ahl_unit_config_headers
1523 SET master_config_id = p_mc_header_id,
1524 object_version_number = object_version_number + 1,
1525 last_updated_by = fnd_global.user_id,
1526 last_update_date = SYSDATE,
1527 last_update_login = fnd_global.login_id
1528 WHERE unit_config_header_id = p_uc_header_id
1529 AND object_version_number = l_uc_header_attr.object_version_number;
1530 END IF;
1531 IF SQL%ROWCOUNT = 0 THEN
1532 FND_MESSAGE.set_name( 'AHL','AHL_COM_RECORD_CHANGED' );
1533 FND_MSG_PUB.add;
1534 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1535 END IF;
1536
1537 --Copy the change to UC history table
1538 ahl_util_uc_pkg.copy_uc_header_to_history(p_uc_header_id, l_return_status);
1539 --IF history copy failed, then don't raise exception, just add the messageto the message stack
1540 IF l_return_status <> FND_API.G_RET_STS_SUCCESS THEN
1541 FND_MESSAGE.set_name('AHL', 'AHL_UC_HISTORY_COPY_FAILED');
1542 FND_MSG_PUB.add;
1543 END IF;
1544
1545 IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1546 FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT,
1547 'ahl.plsql.'||G_PKG_NAME||'.'||l_api_name||':Within API',
1548 'After updating the master_config_id');
1549 END IF;
1550
1551 --Loop through all the non leaf nodes including the root node
1552 FOR l_get_non_leaf_node IN get_non_leaf_nodes(l_uc_header_attr.instance_id) LOOP
1553 --Make sure the node doesn't belong to a sub unit or extra node branch, because for
1554 --all the nodes in the sub unit or extra node branch including the top most extra node
1555 --it is not necessary to process them and the sub unit top node is processed in the loop
1556 --of its parent node
1557 OPEN check_subuc_extra(l_get_non_leaf_node.instance_id, l_uc_header_attr.instance_id);
1558 FETCH check_subuc_extra INTO l_check_subuc_extra;
1559 IF check_subuc_extra%NOTFOUND THEN
1560 --Get all the immediate children of the corresponding MC node
1561 --First get the non leaf node's new relationship_id to which it has been migrated
1562 --This is a bug fix found by Barry on Nov 6, 2003
1563 IF l_uc_header_attr.instance_id = l_get_non_leaf_node.instance_id THEN
1564 l_new_relationship_id := l_get_non_leaf_node.relationship_id;
1565 ELSE
1566 SELECT to_number(position_reference) into l_new_relationship_id
1567 FROM csi_ii_relationships
1568 WHERE subject_id = l_get_non_leaf_node.instance_id
1569 AND relationship_type_code='COMPONENT-OF'
1570 AND trunc(nvl(active_start_date, sysdate)) <= trunc(sysdate)
1571 AND trunc(nvl(active_end_date, sysdate+1)) > trunc(sysdate);
1572 END IF;
1573
1574 i_mc_child := 1;
1575 FOR l_get_mc_child IN get_mc_children(l_new_relationship_id) LOOP
1576 l_mc_children_tbl(i_mc_child).relationship_id := l_get_mc_child.relationship_id;
1577 l_mc_children_tbl(i_mc_child).position_key := l_get_mc_child.position_key;
1578 l_mc_children_tbl(i_mc_child).position_ref_code := l_get_mc_child.position_ref_code;
1579 l_mc_children_tbl(i_mc_child).item_group_id := l_get_mc_child.item_group_id;
1580 l_mc_children_tbl(i_mc_child).matched_flag := 'N'; -- default to 'N'
1581 i_mc_child := i_mc_child + 1;
1582 END LOOP;
1583 FOR l_get_csi_child IN get_csi_children(l_get_non_leaf_node.instance_id) LOOP
1584 --No processing for the extra node
1585 IF l_get_csi_child.relationship_id IS NOT NULL THEN
1586 l_matched := FALSE;
1587 l_relationship_id := NULL;
1588 IF l_mc_children_tbl.COUNT > 0 THEN
1589 <<OUTER>>
1590 FOR i IN l_mc_children_tbl.FIRST..l_mc_children_tbl.LAST LOOP
1591 IF l_mc_children_tbl(i).matched_flag <> 'Y' THEN
1592 IF l_get_csi_child.position_key = l_mc_children_tbl(i).position_key OR
1593 l_get_csi_child.position_ref_code = l_mc_children_tbl(i).position_ref_code THEN
1594 --Check whether this node is a sub unit top node, if YES compare the sub
1595 --mc_header_id, otherwise compare item
1596 OPEN check_sub_uc(l_get_csi_child.instance_id);
1597 FETCH check_sub_uc INTO l_check_sub_uc;
1598 IF check_sub_uc%FOUND THEN
1599 FOR l_get_sub_mc IN get_sub_mcs(l_mc_children_tbl(i).relationship_id) LOOP
1600 IF l_check_sub_uc.mc_header_id = l_get_sub_mc.mc_header_id THEN
1601 l_matched := TRUE;
1602 l_mc_children_tbl(i).matched_flag := 'Y';
1603 l_relationship_id := l_mc_children_tbl(i).relationship_id;
1604 CLOSE check_sub_uc;
1605 EXIT OUTER;
1606 END IF;
1607 END LOOP;
1608 ELSE
1609 l_matched := AHL_UTIL_UC_PKG.item_match(l_mc_children_tbl(i).relationship_id,
1610 l_get_csi_child.inventory_item_id,
1611 l_get_csi_child.inventory_org_id,
1612 l_get_csi_child.inventory_revision,
1613 l_get_csi_child.quantity,
1614 l_get_csi_child.unit_of_measure);
1615 IF l_matched THEN
1616 l_mc_children_tbl(i).matched_flag := 'Y';
1617 l_relationship_id := l_mc_children_tbl(i).relationship_id;
1618 CLOSE check_sub_uc;
1619 EXIT OUTER;
1620 END IF;
1621 /*
1622 FOR l_get_associated_item IN get_associated_items(l_mc_children_tbl(i).item_group_id) LOOP
1623 IF l_get_csi_child.inventory_item_id = l_get_associated_item.inventory_item_id AND
1624 l_get_csi_child.inventory_org_id = l_get_associated_item.inventory_org_id THEN
1625 l_matched := TRUE;
1626 l_relationship_id := l_mc_children_tbl(i).relationship_id;
1627 EXIT OUTER;
1628 END IF;
1629 END LOOP;
1630 */
1631
1632 END IF;
1633 CLOSE check_sub_uc;
1634 END IF; --whether position_key or position_ref_code matches
1635 END IF; --whether the MC chilren node has already been matched
1636 END LOOP; --of all the MC children
1637 END IF;
1638
1639 --Set the CSI transaction record
1640 l_csi_transaction_rec.source_transaction_date := SYSDATE;
1641 l_csi_transaction_rec.transaction_type_id := l_transaction_type_id;
1642 --Set CSI relationship record
1643 l_csi_relationship_rec.relationship_id := l_get_csi_child.csi_ii_relationship_id;
1644 l_csi_relationship_rec.object_version_number := l_get_csi_child.csi_ii_relationship_ovn;
1645 l_csi_relationship_rec.position_reference := to_char(l_relationship_id);
1646 l_csi_relationship_rec.relationship_type_code := 'COMPONENT-OF';
1647 l_csi_relationship_rec.object_id := l_get_csi_child.parent_instance_id;
1648 l_csi_relationship_rec.subject_id := l_get_csi_child.instance_id;
1649 l_csi_relationship_tbl(1) := l_csi_relationship_rec;
1650 CSI_II_RELATIONSHIPS_PUB.update_relationship(
1651 p_api_version => 1.0,
1652 p_relationship_tbl => l_csi_relationship_tbl,
1653 p_txn_rec => l_csi_transaction_rec,
1654 x_return_status => l_return_status,
1655 x_msg_count => l_msg_count,
1656 x_msg_data => l_msg_data);
1657 IF (l_return_status = FND_API.G_RET_STS_ERROR) THEN
1658 RAISE FND_API.G_EXC_ERROR;
1659 ELSIF (l_return_status = FND_API.G_RET_STS_UNEXP_ERROR) THEN
1660 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1661 END IF;
1662 END IF; --whether the UC node is an extra node
1663 END LOOP; --of all the UC children
1664 END IF; --whether it is a node belonging to subuc or extra node branch
1665 CLOSE check_subuc_extra;
1666 END LOOP; --of all non leaf nodes
1667
1668 IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1669 FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT,
1670 'ahl.plsql.'||G_PKG_NAME||'.'||l_api_name||':Within API',
1671 'After migration the whole UC tree');
1672 END IF;
1673
1674 --Call check_completeness API to check the completeness of the root UC
1675 IF (l_root_uc_status_code IN ('COMPLETE', 'INCOMPLETE')) THEN
1676 AHL_UC_VALIDATION_PUB.check_completeness(
1677 p_api_version => 1.0,
1678 p_init_msg_list => FND_API.G_FALSE,
1679 p_commit => FND_API.G_FALSE,
1680 p_validation_level => FND_API.G_VALID_LEVEL_FULL,
1681 x_return_status => l_return_status,
1682 x_msg_count => l_msg_count,
1683 x_msg_data => l_msg_data,
1684 p_unit_header_id => l_root_uc_header_id,
1685 x_evaluation_status => l_evaluation_status);
1686 IF (l_return_status = FND_API.G_RET_STS_ERROR) THEN
1687 RAISE FND_API.G_EXC_ERROR;
1688 ELSIF (l_return_status = FND_API.G_RET_STS_UNEXP_ERROR) THEN
1689 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1690 END IF;
1691 END IF;
1692 --dbms_output.put_line('l_root_uc_ovn(a)='||l_root_uc_ovn);
1693 select object_version_number into l_root_uc_ovn
1694 from ahl_unit_config_headers
1695 where unit_config_header_id = l_root_uc_header_id;
1696 --dbms_output.put_line('l_root_uc_ovn(b)='||l_root_uc_ovn);
1697
1698 --After migration, UC(root) status change should be made.
1699 IF (l_evaluation_status = 'T' AND l_root_uc_status_code = 'INCOMPLETE') THEN
1700 UPDATE ahl_unit_config_headers
1701 SET unit_config_status_code = 'COMPLETE',
1702 active_uc_status_code = 'UNAPPROVED',
1703 object_version_number = object_version_number + 1,
1704 last_updated_by = fnd_global.user_id,
1705 last_update_date = SYSDATE,
1706 last_update_login = fnd_global.login_id
1707 WHERE unit_config_header_id = l_root_uc_header_id
1708 AND object_version_number = l_root_uc_ovn;
1709 IF SQL%ROWCOUNT = 0 THEN
1710 FND_MESSAGE.set_name( 'AHL','AHL_COM_RECORD_CHANGED' );
1711 FND_MSG_PUB.add;
1712 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1713 END IF;
1714
1715 --Copy the change to UC history table
1716 ahl_util_uc_pkg.copy_uc_header_to_history(l_root_uc_header_id, l_return_status);
1717 --IF history copy failed, then don't raise exception, just add the messageto the message stack
1718 IF l_return_status <> FND_API.G_RET_STS_SUCCESS THEN
1719 FND_MESSAGE.set_name('AHL', 'AHL_UC_HISTORY_COPY_FAILED');
1720 FND_MSG_PUB.add;
1721 END IF;
1722 ELSIF (l_evaluation_status = 'F' AND l_root_uc_status_code = 'COMPLETE') THEN
1723 UPDATE ahl_unit_config_headers
1724 SET unit_config_status_code = 'INCOMPLETE',
1725 active_uc_status_code = 'UNAPPROVED',
1726 object_version_number = object_version_number + 1,
1727 last_updated_by = fnd_global.user_id,
1728 last_update_date = SYSDATE,
1729 last_update_login = fnd_global.login_id
1730 WHERE unit_config_header_id = l_root_uc_header_id
1731 AND object_version_number = l_root_uc_ovn;
1732 IF SQL%ROWCOUNT = 0 THEN
1733 FND_MESSAGE.set_name( 'AHL','AHL_COM_RECORD_CHANGED' );
1734 FND_MSG_PUB.add;
1735 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1736 END IF;
1737
1738 --Copy the change to UC history table
1739 ahl_util_uc_pkg.copy_uc_header_to_history(l_root_uc_header_id, l_return_status);
1740 --IF history copy failed, then don't raise exception, just add the messageto the message stack
1741 IF l_return_status <> FND_API.G_RET_STS_SUCCESS THEN
1742 FND_MESSAGE.set_name('AHL', 'AHL_UC_HISTORY_COPY_FAILED');
1743 FND_MSG_PUB.add;
1744 END IF;
1745 ELSIF (l_root_uc_status_code IN ('COMPLETE', 'INCOMPLETE') AND
1746 (l_root_active_uc_status_code IS NULL OR
1747 l_root_active_uc_status_code <> 'UNAPPROVED')) THEN
1748 UPDATE ahl_unit_config_headers
1749 SET active_uc_status_code = 'UNAPPROVED',
1750 object_version_number = object_version_number + 1,
1751 last_updated_by = fnd_global.user_id,
1752 last_update_date = SYSDATE,
1753 last_update_login = fnd_global.login_id
1754 WHERE unit_config_header_id = l_root_uc_header_id
1755 AND object_version_number = l_root_uc_ovn;
1756 IF SQL%ROWCOUNT = 0 THEN
1757 FND_MESSAGE.set_name( 'AHL','AHL_COM_RECORD_CHANGED' );
1758 FND_MSG_PUB.add;
1759 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1760 END IF;
1761
1762 --Copy the change to UC history table
1763 ahl_util_uc_pkg.copy_uc_header_to_history(l_root_uc_header_id, l_return_status);
1764 --IF history copy failed, then don't raise exception, just add the messageto the message stack
1765 IF l_return_status <> FND_API.G_RET_STS_SUCCESS THEN
1766 FND_MESSAGE.set_name('AHL', 'AHL_UC_HISTORY_COPY_FAILED');
1767 FND_MSG_PUB.add;
1768 END IF;
1769 END IF;
1770
1771 IF (FND_LOG.LEVEL_PROCEDURE >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
1772 FND_LOG.STRING(FND_LOG.LEVEL_PROCEDURE,
1773 'ahl.plsql.'||G_PKG_NAME||'.'||l_api_name||':After normal execution',
1774 'Status changed and at the end of the procedure');
1775 END IF;
1776
1777 -- Get all the error messages from the previous steps (if any) and raise the appropriate Exception
1778 l_msg_count := FND_MSG_PUB.count_msg;
1779 IF l_msg_count > 0 THEN
1780 x_msg_count := l_msg_count;
1781 RAISE FND_API.G_EXC_ERROR;
1782 END IF;
1783
1784 -- Perform the Commit (if requested)
1785 IF FND_API.to_boolean(p_commit) THEN
1786 COMMIT;
1787 END IF;
1788
1789 -- Count and Get messages (optional)
1790 FND_MSG_PUB.count_and_get(
1791 p_encoded => FND_API.G_FALSE,
1792 p_count => x_msg_count,
1793 p_data => x_msg_data);
1794
1795 EXCEPTION
1796 WHEN FND_API.G_EXC_ERROR THEN
1797 ROLLBACK TO migrate_uc_tree;
1798 x_return_status := FND_API.G_RET_STS_ERROR ;
1799 FND_MSG_PUB.count_and_get(
1800 p_encoded => FND_API.G_FALSE,
1801 p_count => x_msg_count,
1802 p_data => x_msg_data);
1803 WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
1804 ROLLBACK TO migrate_uc_tree;
1805 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR ;
1806 FND_MSG_PUB.count_and_get(
1807 p_encoded => FND_API.G_FALSE,
1808 p_count => x_msg_count,
1809 p_data => x_msg_data);
1810 WHEN OTHERS THEN
1811 ROLLBACK TO migrate_uc_tree;
1812 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR ;
1813 IF FND_MSG_PUB.check_msg_level(FND_MSG_PUB.G_MSG_LVL_UNEXP_ERROR)
1814 THEN
1815 FND_MSG_PUB.add_exc_msg(
1816 p_pkg_name => G_PKG_NAME,
1817 p_procedure_name => l_api_name,
1818 p_error_text => SUBSTRB(SQLERRM,1,240));
1819 END IF;
1820 FND_MSG_PUB.count_and_get(
1821 p_encoded => FND_API.G_FALSE,
1822 p_count => x_msg_count,
1823 p_data => x_msg_data);
1824 END;
1825
1826 -- Define Procedure remap_uc_subtree --
1827 -- This API is used to remap a UC subtree (not a sub-unit) to a MC branch. It is called
1828 -- by ahl_uc_instnace_pvt.install_existing_instance.
1829 PROCEDURE remap_uc_subtree (
1830 p_api_version IN NUMBER,
1831 p_init_msg_list IN VARCHAR2 := FND_API.G_FALSE,
1832 p_commit IN VARCHAR2 := FND_API.G_FALSE,
1833 p_validation_level IN NUMBER := FND_API.G_VALID_LEVEL_FULL,
1834 x_return_status OUT NOCOPY VARCHAR2,
1835 x_msg_count OUT NOCOPY NUMBER,
1836 x_msg_data OUT NOCOPY VARCHAR2,
1837 p_instance_id IN NUMBER,
1838 p_relationship_id IN NUMBER)
1839 IS
1840 TYPE l_mc_children_rec_type IS RECORD(
1841 relationship_id NUMBER,
1842 position_key NUMBER,
1843 position_ref_code VARCHAR2(30),
1844 item_group_id NUMBER,
1845 matched_flag VARCHAR2(1));
1846 TYPE l_mc_children_tbl_type IS TABLE OF l_mc_children_rec_type INDEX BY BINARY_INTEGER;
1847 l_mc_children_tbl l_mc_children_tbl_type;
1848 l_api_name CONSTANT VARCHAR2(30) := 'remap_uc_subtree';
1849 l_api_version CONSTANT NUMBER := 1.0;
1850 l_return_status VARCHAR2(1);
1851 l_msg_count NUMBER;
1852 l_msg_data VARCHAR2(2000);
1853 l_relationship_id NUMBER;
1854 l_mc_header_id NUMBER;
1855 l_root_instance_id NUMBER;
1856 l_root_relationship_id NUMBER;
1857 l_dummy NUMBER;
1858 i NUMBER;
1859 i_mc_child NUMBER;
1860 l_item_match BOOLEAN;
1861 l_matched BOOLEAN;
1862 l_return_value BOOLEAN;
1863 l_transaction_type_id NUMBER;
1864 l_version_no NUMBER;
1865 l_csi_relationship_rec csi_datastructures_pub.ii_relationship_rec;
1866 l_csi_relationship_tbl csi_datastructures_pub.ii_relationship_tbl;
1867 l_csi_transaction_rec csi_datastructures_pub.transaction_rec;
1868 l_new_relationship_id NUMBER;
1869 --In order to check whether the instance belongs to a sub unit or an extra node branch
1870 CURSOR check_subuc_extra(c_instance_id NUMBER, c_top_instance_id NUMBER) IS
1871 SELECT object_id, subject_id, position_reference
1872 FROM csi_ii_relationships
1873 WHERE subject_id IN (SELECT csi_item_instance_id
1874 FROM ahl_unit_config_headers
1875 WHERE trunc(nvl(active_end_date, SYSDATE+1)) > trunc(SYSDATE))
1876 OR position_reference IS NULL
1877 START WITH subject_id = c_instance_id
1878 AND relationship_type_code = 'COMPONENT-OF'
1879 AND trunc(nvl(active_start_date,SYSDATE)) <= trunc(SYSDATE)
1880 AND trunc(nvl(active_end_date, SYSDATE+1)) > trunc(SYSDATE)
1881 CONNECT BY subject_id = PRIOR object_id
1882 AND subject_id <> c_top_instance_id
1883 --This hierarchy query is from bottom up and the top node is not a UC root node, so we
1884 --have to discontinue the hierarchy query when it comes to the given node
1885 AND relationship_type_code = 'COMPONENT-OF'
1886 AND trunc(nvl(active_start_date,SYSDATE)) <= trunc(SYSDATE)
1887 AND trunc(nvl(active_end_date, SYSDATE+1)) > trunc(SYSDATE);
1888 l_check_subuc_extra check_subuc_extra%ROWTYPE;
1889 --Check the given instance_id is existing, with children instances and not a unit's or sub-unit's top node. But doesn't check whether this instance is installed or not, which is checked in get_available_instances and install_existing_instance.
1890 CURSOR check_uc_instance IS
1891 SELECT R.object_id instance_id,
1892 to_number(R.position_reference) relationship_id,
1893 C.inventory_item_id inventory_item_id,
1894 C.inv_master_organization_id inventory_org_id,
1895 C.inventory_revision,
1896 C.quantity,
1897 C.unit_of_measure
1898 FROM csi_ii_relationships R,
1899 csi_item_instances C
1900 WHERE R.object_id = p_instance_id
1901 AND R.object_id = C.instance_id
1902 AND R.relationship_type_code = 'COMPONENT-OF'
1903 AND trunc(nvl(R.active_start_date,SYSDATE)) <= trunc(SYSDATE)
1904 AND trunc(nvl(R.active_end_date, SYSDATE+1)) > trunc(SYSDATE)
1905 AND NOT EXISTS (SELECT 'X'
1906 FROM ahl_unit_config_headers
1907 WHERE csi_item_instance_id = R.object_id
1908 AND trunc(nvl(active_end_date, SYSDATE+1)) > trunc(SYSDATE));
1909 l_check_uc_instance check_uc_instance%ROWTYPE;
1910 --Check the given relationship_id exists and also get its item
1911 CURSOR check_mc_relationship IS
1912 SELECT M.relationship_id,
1913 I.inventory_item_id,
1914 I.inventory_org_id
1915 FROM ahl_mc_relationships M,
1916 ahl_item_associations_b I
1917 WHERE M.relationship_id = p_relationship_id
1918 AND M.item_group_id = I.item_group_id
1919 AND trunc(nvl(M.active_start_date,SYSDATE)) <= trunc(SYSDATE)
1920 AND trunc(nvl(M.active_end_date, SYSDATE+1)) > trunc(SYSDATE);
1921 l_check_mc_relationship check_mc_relationship%ROWTYPE;
1922 --Get the associated items for a given item_group_id
1923 /*
1924 CURSOR get_associated_items(c_item_group_id NUMBER) IS
1925 SELECT inventory_item_id,
1926 inventory_org_id
1927 FROM ahl_item_associations_b
1928 WHERE item_group_id = c_item_group_id;
1929 l_get_associated_item get_associated_items%ROWTYPE;
1930 */
1931 --Given an instance_id, get all of its immediate children from csi_ii_relationships
1932 CURSOR get_csi_children(c_instance_id NUMBER) IS
1933 SELECT C.relationship_id csi_ii_relationship_id,
1934 C.object_version_number csi_ii_relationship_ovn,
1935 C.object_id parent_instance_id,
1936 C.subject_id instance_id,
1937 to_number(C.position_reference) relationship_id,
1938 M.position_key,
1939 M.position_ref_code,
1940 I.inventory_item_id,
1941 I.inv_master_organization_id inventory_org_id,
1942 I.inventory_revision,
1943 I.quantity,
1944 I.unit_of_measure
1945 FROM csi_ii_relationships C,
1946 ahl_mc_relationships M,
1947 csi_item_instances I
1948 WHERE to_number(C.position_reference) = M.relationship_id (+)
1949 AND C.subject_id = I.instance_id
1950 AND C.object_id = c_instance_id
1951 AND C.relationship_type_code = 'COMPONENT-OF'
1952 AND trunc(nvl(C.active_start_date,SYSDATE)) <= trunc(SYSDATE)
1953 AND trunc(nvl(C.active_end_date, SYSDATE+1)) > trunc(SYSDATE);
1954 --Given an relationship_id, get all of its immediate children from MC
1955 CURSOR get_mc_children(c_relationship_id NUMBER) IS
1956 SELECT parent_relationship_id parent_rel_id,
1957 relationship_id,
1958 position_key,
1959 position_ref_code,
1960 item_group_id
1961 FROM ahl_mc_relationships
1962 WHERE parent_relationship_id = c_relationship_id
1963 AND trunc(nvl(active_start_date,SYSDATE)) <= trunc(SYSDATE)
1964 AND trunc(nvl(active_end_date, SYSDATE+1)) > trunc(SYSDATE);
1965 --Check whether an instance in UC is the top node of a sub UC, if yes, then get the
1966 --relationship of the sub UC's top node
1967 CURSOR check_sub_uc(c_instance_id NUMBER) IS
1968 SELECT A.master_config_id mc_header_id,
1969 B.relationship_id
1970 FROM ahl_unit_config_headers A,
1971 ahl_mc_relationships B
1972 WHERE A.csi_item_instance_id = c_instance_id
1973 AND trunc(nvl(A.active_end_date, SYSDATE+1)) > trunc(SYSDATE)
1974 AND B.mc_header_id = A.master_config_id
1975 AND B.parent_relationship_id IS NULL
1976 AND trunc(nvl(B.active_start_date,SYSDATE)) <= trunc(SYSDATE)
1977 AND trunc(nvl(B.active_end_date, SYSDATE+1)) > trunc(SYSDATE);
1978 l_check_sub_uc check_sub_uc%ROWTYPE;
1979 --Given a position(leaf) in MC, get all the sub MCs which can be associated to this position
1980 CURSOR get_sub_mcs(c_relationship_id NUMBER) IS
1981 SELECT mc_header_id
1982 FROM ahl_mc_config_relations
1983 WHERE relationship_id = c_relationship_id
1984 AND trunc(nvl(active_start_date,SYSDATE)) <= trunc(SYSDATE)
1985 AND trunc(nvl(active_end_date, SYSDATE+1)) > trunc(SYSDATE);
1986 --Based on the UC, list all of the non leaf nodes including the root node
1987 CURSOR get_non_leaf_nodes(c_instance_id NUMBER) IS
1988 SELECT object_id parent_instance_id,
1989 subject_id instance_id,
1990 to_number(position_reference) relationship_id
1991 FROM csi_ii_relationships A
1992 --remove all of the leaf node after finishing the hierarchical query
1993 WHERE EXISTS (SELECT 'X'
1994 FROM csi_ii_relationships B
1995 WHERE B.object_id = A.subject_id
1996 AND relationship_type_code = 'COMPONENT-OF'
1997 AND trunc(nvl(active_start_date,SYSDATE)) <= trunc(SYSDATE)
1998 AND trunc(nvl(active_end_date, SYSDATE+1)) > trunc(SYSDATE))
1999 START WITH subject_id = c_instance_id
2000 AND relationship_type_code = 'COMPONENT-OF'
2001 AND trunc(nvl(active_start_date,SYSDATE)) <= trunc(SYSDATE)
2002 AND trunc(nvl(active_end_date, SYSDATE+1)) > trunc(SYSDATE)
2003 CONNECT BY object_id = PRIOR subject_id
2004 AND relationship_type_code = 'COMPONENT-OF'
2005 AND trunc(nvl(active_start_date,SYSDATE)) <= trunc(SYSDATE)
2006 AND trunc(nvl(active_end_date, SYSDATE+1)) > trunc(SYSDATE);
2007 BEGIN
2008 --Initialize API return status to success
2009 x_return_status := FND_API.G_RET_STS_SUCCESS;
2010
2011 -- Standard Start of API savepoint
2012 SAVEPOINT remap_uc_subtree;
2013
2014 --Standard call to check for call compatibility.
2015 IF NOT FND_API.compatible_api_call(
2016 l_api_version,
2017 p_api_version,
2018 l_api_name,
2019 G_PKG_NAME)
2020 THEN
2021 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2022 END IF;
2023 --Initialize message list if p_init_msg_list is set to TRUE.
2024 IF FND_API.to_boolean( p_init_msg_list ) THEN
2025 FND_MSG_PUB.initialize;
2026 END IF;
2027 IF (FND_LOG.LEVEL_PROCEDURE >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2028 FND_LOG.STRING(FND_LOG.LEVEL_PROCEDURE,
2029 'ahl.plsql.'||G_PKG_NAME||'.'||l_api_name||'.begin',
2030 'At the start of the procedure, p_instance_id = ' || p_instance_id || ', p_relationship_id = ' || p_relationship_id);
2031 END IF;
2032 --Validate the input parameter p_instance_id
2033 OPEN check_uc_instance;
2034 FETCH check_uc_instance INTO l_check_uc_instance;
2035 IF check_uc_instance%NOTFOUND THEN
2036 FND_MESSAGE.set_name('AHL','AHL_UC_API_PARAMETER_INVALID');
2037 FND_MESSAGE.set_token('NAME', 'instance_id');
2038 FND_MESSAGE.set_token('VALUE', p_instance_id);
2039 FND_MSG_PUB.add;
2040 CLOSE check_uc_instance;
2041 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2042 ELSE
2043 CLOSE check_uc_instance;
2044 END IF;
2045
2046 --Validate the input parameter p_relationship_id
2047 OPEN check_mc_relationship;
2048 FETCH check_mc_relationship INTO l_check_mc_relationship;
2049 IF check_mc_relationship%NOTFOUND THEN
2050 FND_MESSAGE.set_name('AHL','AHL_UC_API_PARAMETER_INVALID');
2051 FND_MESSAGE.set_token('NAME', 'relationship_id');
2052 FND_MESSAGE.set_token('VALUE', p_relationship_id);
2053 FND_MSG_PUB.add;
2054 CLOSE check_mc_relationship;
2055 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2056 ELSE
2057 CLOSE check_mc_relationship;
2058 END IF;
2059
2060 --For UC branch top node, only need to ensure item matches, no need to check position key
2061 --and position_reference
2062 l_item_match := AHL_UTIL_UC_PKG.item_match(p_relationship_id,
2063 l_check_uc_instance.inventory_item_id,
2064 l_check_uc_instance.inventory_org_id,
2065 l_check_uc_instance.inventory_revision,
2066 l_check_uc_instance.quantity,
2067 l_check_uc_instance.unit_of_measure);
2068 /*
2069 FOR l_check_mc_relationship IN check_mc_relationship LOOP
2070 IF l_check_uc_instance.inventory_item_id = l_check_mc_relationship.inventory_item_id AND
2071 l_check_uc_instance.inventory_org_id = l_check_mc_relationship.inventory_org_id THEN
2072 l_item_match := TRUE;
2073 EXIT;
2074 END IF;
2075 END LOOP;
2076 */
2077 IF NOT l_item_match THEN
2078 FND_MESSAGE.set_name( 'AHL','AHL_UC_INSTANCE_NOT_MATCH' );
2079 FND_MESSAGE.set_token('INSTANCE', p_instance_id);
2080 FND_MSG_PUB.add;
2081 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2082 END IF;
2083
2084 --Loop through all the non leaf nodes including the top node
2085 FOR l_get_non_leaf_node IN get_non_leaf_nodes(p_instance_id) LOOP
2086 --Make sure the node doesn't belong to a sub unit or extra node branch, because for
2087 --all the nodes in the sub unit or extra node branch including the top most extra node
2088 --it is not necessary to process them and the sub unit top node itself has been processed in the loop
2089 --of its parent node
2090 OPEN check_subuc_extra(l_get_non_leaf_node.instance_id, p_instance_id);
2091 FETCH check_subuc_extra INTO l_check_subuc_extra;
2092 IF check_subuc_extra%NOTFOUND THEN
2093 --Get all the immediate children of the corresponding MC node
2094 --First get the non leaf node's new relationship_id to which it has been migrated
2095 --This is a bug fix found by Barry on Nov 6, 2003
2096 IF p_instance_id = l_get_non_leaf_node.instance_id THEN
2097 l_new_relationship_id := p_relationship_id;
2098 ELSE
2099 SELECT to_number(position_reference) into l_new_relationship_id
2100 FROM csi_ii_relationships
2101 WHERE subject_id = l_get_non_leaf_node.instance_id
2102 AND relationship_type_code='COMPONENT-OF'
2103 AND trunc(nvl(active_start_date, sysdate)) <= trunc(sysdate)
2104 AND trunc(nvl(active_end_date, sysdate+1)) > trunc(sysdate);
2105 END IF;
2106
2107 i_mc_child := 1;
2108 FOR l_get_mc_child IN get_mc_children(l_new_relationship_id) LOOP
2109 l_mc_children_tbl(i_mc_child).relationship_id := l_get_mc_child.relationship_id;
2110 l_mc_children_tbl(i_mc_child).position_key := l_get_mc_child.position_key;
2111 l_mc_children_tbl(i_mc_child).position_ref_code := l_get_mc_child.position_ref_code;
2112 l_mc_children_tbl(i_mc_child).item_group_id := l_get_mc_child.item_group_id;
2113 l_mc_children_tbl(i_mc_child).matched_flag := 'N'; -- default to 'N'
2114 i_mc_child := i_mc_child + 1;
2115 END LOOP;
2116 FOR l_get_csi_child IN get_csi_children(l_get_non_leaf_node.instance_id) LOOP
2117 --No processing for the extra node
2118 IF l_get_csi_child.relationship_id IS NOT NULL THEN
2119 l_matched := FALSE;
2120 l_relationship_id := NULL;
2121 <<OUTER>>
2122 FOR i IN l_mc_children_tbl.FIRST..l_mc_children_tbl.LAST LOOP
2123 IF l_mc_children_tbl(i).matched_flag <> 'Y' THEN
2124 IF l_get_csi_child.position_key = l_mc_children_tbl(i).position_key OR
2125 l_get_csi_child.position_ref_code = l_mc_children_tbl(i).position_ref_code THEN
2126 --Check whether this node is a sub unit top node, if YES compare the sub
2127 --mc_header_id(not necessary to compare the top node's item), otherwise compare item
2128 OPEN check_sub_uc(l_get_csi_child.instance_id);
2129 FETCH check_sub_uc INTO l_check_sub_uc;
2130 IF check_sub_uc%FOUND THEN
2131 FOR l_get_sub_mc IN get_sub_mcs(l_mc_children_tbl(i).relationship_id) LOOP
2132 IF l_check_sub_uc.mc_header_id = l_get_sub_mc.mc_header_id THEN
2133 l_matched := TRUE;
2134 l_mc_children_tbl(i).matched_flag := 'Y';
2135 l_relationship_id := l_mc_children_tbl(i).relationship_id;
2136 CLOSE check_sub_uc;
2137 EXIT OUTER;
2138 END IF;
2139 END LOOP;
2140 ELSE
2141 l_matched := AHL_UTIL_UC_PKG.item_match(l_mc_children_tbl(i).relationship_id,
2142 l_get_csi_child.inventory_item_id,
2143 l_get_csi_child.inventory_org_id,
2144 l_get_csi_child.inventory_revision,
2145 l_get_csi_child.quantity,
2146 l_get_csi_child.unit_of_measure);
2147 /*
2148 FOR l_get_associated_item IN get_associated_items(l_mc_children_tbl(i).item_group_id) LOOP
2149 IF l_get_csi_child.inventory_item_id = l_get_associated_item.inventory_item_id AND
2150 l_get_csi_child.inventory_org_id = l_get_associated_item.inventory_org_id THEN
2151 l_matched := TRUE;
2152 l_relationship_id := l_mc_children_tbl(i).relationship_id;
2153 EXIT OUTER;
2154 END IF;
2155 END LOOP;
2156 */
2157 IF l_matched THEN
2158 l_mc_children_tbl(i).matched_flag := 'Y';
2159 l_relationship_id := l_mc_children_tbl(i).relationship_id;
2160 CLOSE check_sub_uc;
2161 EXIT OUTER;
2162 END IF;
2163 END IF;
2164 CLOSE check_sub_uc;
2165 --Positions match but items or sub-configs don't match, then we define it as a hard failure
2166 --in Part Change but still an extra node in migration. Both position_key and position_ref_code
2167 --are unique across siblings.
2168 IF NOT l_matched THEN
2169 FND_MESSAGE.set_name( 'AHL','AHL_UC_INSTANCE_HARD_FAIL' );
2170 FND_MESSAGE.set_token('INSTANCE', l_get_csi_child.instance_id);
2171 FND_MSG_PUB.add;
2172 RAISE FND_API.G_EXC_ERROR;
2173 END IF;
2174 END IF; --whether position_key or position_ref_code matches
2175 END IF; --whether the MC chilren node has already been matched
2176 END LOOP; --of all the MC children
2177 --The following lines are used to update the position_reference column in csi_ii_relationships
2178 --First, get transaction_type_id .
2179 AHL_UTIL_UC_PKG.getcsi_transaction_id('UC_UPDATE',l_transaction_type_id, l_return_value);
2180 IF NOT l_return_value THEN
2181 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2182 END IF;
2183 --Set the CSI transaction record
2184 l_csi_transaction_rec.source_transaction_date := SYSDATE;
2185 l_csi_transaction_rec.transaction_type_id := l_transaction_type_id;
2186 --Set CSI relationship record
2187 l_csi_relationship_rec.relationship_id := l_get_csi_child.csi_ii_relationship_id;
2188 l_csi_relationship_rec.object_version_number := l_get_csi_child.csi_ii_relationship_ovn;
2189 l_csi_relationship_rec.position_reference := to_char(l_relationship_id);
2190 l_csi_relationship_rec.relationship_type_code := 'COMPONENT-OF';
2191 l_csi_relationship_rec.object_id := l_get_csi_child.parent_instance_id;
2192 l_csi_relationship_rec.subject_id := l_get_csi_child.instance_id;
2193 l_csi_relationship_tbl(1) := l_csi_relationship_rec;
2194 CSI_II_RELATIONSHIPS_PUB.update_relationship(
2195 p_api_version => 1.0,
2196 p_relationship_tbl => l_csi_relationship_tbl,
2197 p_txn_rec => l_csi_transaction_rec,
2198 x_return_status => l_return_status,
2199 x_msg_count => l_msg_count,
2200 x_msg_data => l_msg_data);
2201 IF (l_return_status = FND_API.G_RET_STS_ERROR) THEN
2202 RAISE FND_API.G_EXC_ERROR;
2203 ELSIF (l_return_status = FND_API.G_RET_STS_UNEXP_ERROR) THEN
2204 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2205 END IF;
2206 END IF; --whether the UC node is an extra node
2207 END LOOP; --of all the UC children
2208 END IF; --whether it is a node belonging to subuc or extra node branch
2209 CLOSE check_subuc_extra;
2210 END LOOP; --of all non leaf nodes
2211
2212 -- Added by rbhavsar on July 25, 2007 to remap IB Tree Nodes to fix FP bug 6276991
2213 Remap_IB_Tree(p_instance_id, p_relationship_id);
2214
2215 IF (FND_LOG.LEVEL_PROCEDURE >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2216 FND_LOG.STRING(FND_LOG.LEVEL_PROCEDURE,
2217 'ahl.plsql.'||G_PKG_NAME||'.'||l_api_name||'.end',
2218 'At the end of the procedure');
2219 END IF;
2220 -- Get all the error messages from the previous steps (if any) and raise the appropriate Exception
2221 l_msg_count := FND_MSG_PUB.count_msg;
2222 IF l_msg_count > 0 THEN
2223 x_msg_count := l_msg_count;
2224 RAISE FND_API.G_EXC_ERROR;
2225 END IF;
2226 -- Perform the Commit (if requested)
2227 IF FND_API.to_boolean(p_commit) THEN
2228 COMMIT;
2229 END IF;
2230 -- Count and Get messages (optional)
2231 FND_MSG_PUB.count_and_get(
2232 p_encoded => FND_API.G_FALSE,
2233 p_count => x_msg_count,
2234 p_data => x_msg_data);
2235
2236 EXCEPTION
2237 WHEN FND_API.G_EXC_ERROR THEN
2238 ROLLBACK TO remap_uc_subtree;
2239 x_return_status := FND_API.G_RET_STS_ERROR ;
2240 FND_MSG_PUB.count_and_get(
2241 p_encoded => FND_API.G_FALSE,
2242 p_count => x_msg_count,
2243 p_data => x_msg_data);
2244 WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
2245 ROLLBACK TO remap_uc_subtree;
2246 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR ;
2247 FND_MSG_PUB.count_and_get(
2248 p_encoded => FND_API.G_FALSE,
2249 p_count => x_msg_count,
2250 p_data => x_msg_data);
2251 WHEN OTHERS THEN
2252 ROLLBACK TO remap_uc_subtree;
2253 x_return_status := FND_API.G_RET_STS_UNEXP_ERROR ;
2254 IF FND_MSG_PUB.check_msg_level(FND_MSG_PUB.G_MSG_LVL_UNEXP_ERROR)
2255 THEN
2256 FND_MSG_PUB.add_exc_msg(
2257 p_pkg_name => G_PKG_NAME,
2258 p_procedure_name => l_api_name,
2259 p_error_text => SUBSTRB(SQLERRM,1,240));
2260 END IF;
2261 FND_MSG_PUB.count_and_get(
2262 p_encoded => FND_API.G_FALSE,
2263 p_count => x_msg_count,
2264 p_data => x_msg_data);
2265 END;
2266
2267 -- Following two procedures added by rbhavsar on July 25, 2007
2268 -- to remap IB Tree Nodes to fix FP bug 6276991
2269 PROCEDURE Remap_IB_Tree(p_instance_id IN NUMBER,
2270 p_relationship_id IN NUMBER)
2271 IS
2272
2273 -- Get all the children of the current instance that are extra nodes
2274 CURSOR get_extra_children_csr IS
2275 SELECT subject_id
2276 FROM csi_ii_relationships
2277 WHERE object_id = p_instance_id
2278 AND relationship_type_code = 'COMPONENT-OF'
2279 AND position_reference IS NULL
2280 AND trunc(nvl(active_start_date,SYSDATE)) <= trunc(SYSDATE)
2281 AND trunc(nvl(active_end_date, SYSDATE+1)) > trunc(SYSDATE)
2282 AND NOT EXISTS (SELECT 'X'
2283 FROM ahl_unit_config_headers
2284 WHERE csi_item_instance_id = subject_id
2285 AND trunc(nvl(active_end_date, SYSDATE+1)) > trunc(SYSDATE));
2286
2287 -- Get all the children of the current instance that are NOT extra nodes
2288 CURSOR get_premapped_instances_csr IS
2289 SELECT subject_id, position_reference
2290 FROM csi_ii_relationships
2291 WHERE object_id = p_instance_id
2292 AND relationship_type_code = 'COMPONENT-OF'
2293 AND position_reference IS NOT NULL
2294 AND trunc(nvl(active_start_date,SYSDATE)) <= trunc(SYSDATE)
2295 AND trunc(nvl(active_end_date, SYSDATE+1)) > trunc(SYSDATE)
2296 AND NOT EXISTS (SELECT 'X'
2297 FROM ahl_unit_config_headers
2298 WHERE csi_item_instance_id = subject_id
2299 AND trunc(nvl(active_end_date, SYSDATE+1)) > trunc(SYSDATE));
2300
2301 -- Validate that the child position is still valid under the parent position
2302 CURSOR validate_position_csr(c_child_relationship_id IN NUMBER) IS
2303 SELECT 1 from ahl_mc_relationships
2304 where relationship_id = c_child_relationship_id
2305 AND parent_relationship_id = p_relationship_id
2306 AND trunc(nvl(active_start_date,SYSDATE)) <= trunc(SYSDATE)
2307 AND trunc(nvl(active_end_date, SYSDATE+1)) > trunc(SYSDATE);
2308
2309 -- Get all children of current position that are empty positions
2310 CURSOR get_all_empty_positions_csr IS
2311 SELECT relationship_id
2312 FROM ahl_mc_relationships
2313 WHERE parent_relationship_id = p_relationship_id
2314 AND trunc(nvl(active_start_date,SYSDATE)) <= trunc(SYSDATE)
2315 AND trunc(nvl(active_end_date, SYSDATE+1)) > trunc(SYSDATE)
2316 MINUS
2317 SELECT to_number(position_reference) relationship_id
2318 FROM csi_ii_relationships relationship_id
2319 WHERE object_id = p_instance_id
2320 AND relationship_type_code = 'COMPONENT-OF'
2321 AND position_reference IS NOT NULL
2322 AND trunc(nvl(active_start_date,SYSDATE)) <= trunc(SYSDATE)
2323 AND trunc(nvl(active_end_date, SYSDATE+1)) > trunc(SYSDATE);
2324
2325 CURSOR get_ii_rel_dtls_csr(c_instance_id NUMBER) IS
2326 SELECT C.relationship_id,
2327 C.object_version_number,
2328 C.object_id,
2329 C.subject_id
2330 FROM csi_ii_relationships C
2331 WHERE C.subject_id = c_instance_id
2332 AND C.relationship_type_code = 'COMPONENT-OF'
2333 AND trunc(nvl(C.active_start_date,SYSDATE)) <= trunc(SYSDATE)
2334 AND trunc(nvl(C.active_end_date, SYSDATE+1)) > trunc(SYSDATE);
2335
2336 L_DEBUG_KEY CONSTANT VARCHAR2(150) := 'ahl.plsql.AHL_UC_TREE_PVT.Remap_IB_Tree';
2337 l_extra_instances_tbl T_ID_TBL;
2338 l_relations_tbl T_ID_TBL;
2339 l_premapped_instances_tbl T_ID_TBL;
2340 l_temp NUMBER;
2341 l_csi_relationship_rec csi_datastructures_pub.ii_relationship_rec;
2342 l_csi_relationship_tbl csi_datastructures_pub.ii_relationship_tbl;
2343 l_csi_transaction_rec csi_datastructures_pub.transaction_rec;
2344 l_ii_rel_dtls get_ii_rel_dtls_csr%ROWTYPE;
2345 l_return_status VARCHAR2(1);
2346 l_msg_count NUMBER;
2347 l_msg_data VARCHAR2(2000);
2348 l_return_value BOOLEAN;
2349 l_transaction_type_id NUMBER;
2350
2351 BEGIN
2352 IF (FND_LOG.LEVEL_PROCEDURE >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2353 FND_LOG.STRING(FND_LOG.LEVEL_PROCEDURE, L_DEBUG_KEY || '.begin',
2354 'At the start of the procedure, p_instance_id = ' || p_instance_id || ', p_relationship_id = ' || p_relationship_id);
2355 END IF;
2356
2357 -- Get the transaction_type_id for use later by the CSI_II_RELATIONSHIPS_PUB.update_relationship API
2358 AHL_UTIL_UC_PKG.getcsi_transaction_id('UC_UPDATE', l_transaction_type_id, l_return_value);
2359 IF NOT l_return_value THEN
2360 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2361 END IF;
2362 l_csi_transaction_rec.transaction_type_id := l_transaction_type_id;
2363 l_csi_transaction_rec.source_transaction_date := SYSDATE;
2364 l_csi_relationship_rec.relationship_type_code := 'COMPONENT-OF';
2365
2366 -- Get all nodes that are non-extra nodes
2367 FOR l_nonextra_instances IN get_premapped_instances_csr LOOP
2368 -- Validate if the instance still matches the position
2369 -- Check if l_nonextra_instances.position_reference is under the position p_relationship_id
2370 IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2371 FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY,
2372 'Non Extra Node: l_nonextra_instances.subject_id = ' || l_nonextra_instances.subject_id ||
2373 ', l_nonextra_instances.position_reference = ' || l_nonextra_instances.position_reference);
2374 END IF;
2375 OPEN validate_position_csr(TO_NUMBER(l_nonextra_instances.position_reference));
2376 FETCH validate_position_csr INTO l_temp;
2377 IF (validate_position_csr%NOTFOUND) THEN
2378 -- Reset the position reference so that the instance becomes an extra node node
2379 OPEN get_ii_rel_dtls_csr( l_nonextra_instances.subject_id);
2380 FETCH get_ii_rel_dtls_csr INTO l_ii_rel_dtls;
2381 CLOSE get_ii_rel_dtls_csr;
2382 --Set CSI relationship record
2383 l_csi_relationship_rec.relationship_id := l_ii_rel_dtls.relationship_id;
2384 l_csi_relationship_rec.object_version_number := l_ii_rel_dtls.object_version_number;
2385 l_csi_relationship_rec.position_reference := null; -- Nullify the relationship
2386 l_csi_relationship_rec.object_id := l_ii_rel_dtls.object_id;
2387 l_csi_relationship_rec.subject_id := l_ii_rel_dtls.subject_id;
2388 l_csi_relationship_tbl(1) := l_csi_relationship_rec;
2389 IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2390 FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY,
2391 'About to call CSI_II_RELATIONSHIPS_PUB.update_relationship to update CSI II relationship with id ' ||
2392 l_ii_rel_dtls.relationship_id || ' between ' ||
2393 l_ii_rel_dtls.object_id || ' (object) and ' ||
2394 l_ii_rel_dtls.subject_id || '(subject) with NULL position_reference ');
2395 END IF;
2396 CSI_II_RELATIONSHIPS_PUB.update_relationship(
2397 p_api_version => 1.0,
2398 p_relationship_tbl => l_csi_relationship_tbl,
2399 p_txn_rec => l_csi_transaction_rec,
2400 x_return_status => l_return_status,
2401 x_msg_count => l_msg_count,
2402 x_msg_data => l_msg_data);
2403 IF (l_return_status = FND_API.G_RET_STS_ERROR) THEN
2404 RAISE FND_API.G_EXC_ERROR;
2405 ELSIF (l_return_status = FND_API.G_RET_STS_UNEXP_ERROR) THEN
2406 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2407 END IF;
2408 ELSE
2409 -- Position Matches at current level: Drill down by calling Remap_IB_Tree recursively
2410 IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2411 FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY,
2412 'About to recursively call Remap_IB_Tree with p_instance_id = ' || l_nonextra_instances.subject_id ||
2413 ', p_relationship_id =' || l_nonextra_instances.position_reference);
2414 END IF;
2415 Remap_IB_Tree(p_instance_id => l_nonextra_instances.subject_id,
2416 p_relationship_id => TO_NUMBER(l_nonextra_instances.position_reference));
2417 IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2418 FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY,
2419 'Returned from recursive call to Remap_IB_Tree.');
2420 END IF;
2421 END IF;
2422 CLOSE validate_position_csr;
2423 END LOOP; -- All non-extra nodes
2424
2425 -- Get all the children of the current instance that are extra nodes
2426 OPEN get_extra_children_csr;
2427 FETCH get_extra_children_csr BULK COLLECT INTO l_extra_instances_tbl;
2428 CLOSE get_extra_children_csr;
2429
2430 IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2431 FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY,
2432 'Number of extra nodes: ' || l_extra_instances_tbl.COUNT ||
2433 ', Number of non-extra nodes: ' || l_premapped_instances_tbl.COUNT);
2434 END IF;
2435 IF (l_extra_instances_tbl.COUNT > 0) THEN
2436 -- There are child nodes present
2437 -- Get all children of current position that are empty positions
2438 OPEN get_all_empty_positions_csr;
2439 FETCH get_all_empty_positions_csr BULK COLLECT INTO l_relations_tbl;
2440 CLOSE get_all_empty_positions_csr;
2441
2442 IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2443 FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY,
2444 'Number of empty positions: ' || l_relations_tbl.COUNT);
2445 END IF;
2446 IF (l_relations_tbl.COUNT > 0) THEN
2447 -- Analyse and process instances with matching positions
2448 Process_Instances(p_x_extra_instances_tbl => l_extra_instances_tbl,
2449 p_x_relations_tbl => l_relations_tbl);
2450 IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2451 FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY,
2452 'Number of extra nodes after processing: ' || l_extra_instances_tbl.COUNT ||
2453 ', Number of empty positions after processing: ' || l_relations_tbl.COUNT);
2454 END IF;
2455 END IF;
2456 END IF; -- There are child nodes
2457
2458 IF (FND_LOG.LEVEL_PROCEDURE >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2459 FND_LOG.STRING(FND_LOG.LEVEL_PROCEDURE, L_DEBUG_KEY || '.end',
2460 'At the end of the procedure.');
2461 END IF;
2462 END Remap_IB_Tree;
2463
2464 -------
2465 -- This procedure is called by Remap_IB_Tree and checks if an instance matches an unique
2466 -- relationship and if so, sets the position_reference. All relations are searched and
2467 -- if multiple are matching, position_reference is not set.
2468 -- This procedure also calls Remap_IB_Tree (mutual recursion) to process children.
2469 PROCEDURE Process_instances(p_x_extra_instances_tbl IN OUT NOCOPY T_ID_TBL,
2470 p_x_relations_tbl IN OUT NOCOPY T_ID_TBL) IS
2471
2472 CURSOR get_instance_dtls_csr(c_instance_id IN NUMBER) IS
2473 SELECT inventory_item_id,
2474 inv_master_organization_id,
2475 inventory_revision,
2476 quantity,
2477 unit_of_measure
2478 FROM csi_item_instances
2479 WHERE instance_id = c_instance_id;
2480
2481 CURSOR get_ii_rel_dtls_csr(c_instance_id NUMBER) IS
2482 SELECT C.relationship_id,
2483 C.object_version_number,
2484 C.object_id,
2485 C.subject_id
2486 FROM csi_ii_relationships C
2487 WHERE C.subject_id = c_instance_id
2488 AND C.relationship_type_code = 'COMPONENT-OF'
2489 AND trunc(nvl(C.active_start_date,SYSDATE)) <= trunc(SYSDATE)
2490 AND trunc(nvl(C.active_end_date, SYSDATE+1)) > trunc(SYSDATE);
2491
2492 l_instance_dtls get_instance_dtls_csr%ROWTYPE;
2493 l_ii_rel_dtls get_ii_rel_dtls_csr%ROWTYPE;
2494 L_DEBUG_KEY CONSTANT VARCHAR2(150) := 'ahl.plsql.AHL_UC_TREE_PVT.Process_instances';
2495 l_map_tbl T_ID_TBL;
2496 l_item_match BOOLEAN;
2497 l_csi_relationship_rec csi_datastructures_pub.ii_relationship_rec;
2498 l_csi_relationship_tbl csi_datastructures_pub.ii_relationship_tbl;
2499 l_csi_transaction_rec csi_datastructures_pub.transaction_rec;
2500 l_return_value BOOLEAN;
2501 l_transaction_type_id NUMBER;
2502 l_return_status VARCHAR2(1);
2503 l_msg_count NUMBER;
2504 l_msg_data VARCHAR2(2000);
2505 i NUMBER;
2506 j NUMBER;
2507 k NUMBER;
2508 l_matched_flag BOOLEAN;
2509 l_current_position NUMBER;
2510
2511 BEGIN
2512 IF (FND_LOG.LEVEL_PROCEDURE >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2513 FND_LOG.STRING(FND_LOG.LEVEL_PROCEDURE, L_DEBUG_KEY || '.begin',
2514 'At the start of the procedure, p_x_extra_instances_tbl.count = ' || p_x_extra_instances_tbl.count || ',p_x_relations_tbl.count = ' ||p_x_relations_tbl.count);
2515 END IF;
2516
2517 -- Get the transaction_type_id for use later by the CSI_II_RELATIONSHIPS_PUB.update_relationship API
2518 AHL_UTIL_UC_PKG.getcsi_transaction_id('UC_UPDATE', l_transaction_type_id, l_return_value);
2519 IF NOT l_return_value THEN
2520 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2521 END IF;
2522 l_csi_transaction_rec.transaction_type_id := l_transaction_type_id;
2523 l_csi_transaction_rec.source_transaction_date := SYSDATE;
2524 l_csi_relationship_rec.relationship_type_code := 'COMPONENT-OF';
2525
2526 -- There are extra nodes present
2527 i := p_x_extra_instances_tbl.FIRST;
2528 WHILE (i IS NOT NULL) LOOP
2529 IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2530 FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY,
2531 'i = ' || i || ', p_x_extra_instances_tbl(i) = ' || p_x_extra_instances_tbl(i));
2532 END IF;
2533 -- Initialize associative array
2534 l_map_tbl(p_x_extra_instances_tbl(i)) := 0;
2535 OPEN get_instance_dtls_csr(p_x_extra_instances_tbl(i));
2536 FETCH get_instance_dtls_csr INTO l_instance_dtls;
2537 CLOSE get_instance_dtls_csr;
2538 j := p_x_relations_tbl.FIRST;
2539 WHILE (j IS NOT NULL) LOOP
2540 -- See if instance i matches position j
2541 l_item_match := AHL_UTIL_UC_PKG.item_match(p_x_relations_tbl(j),
2542 l_instance_dtls.inventory_item_id,
2543 l_instance_dtls.inv_master_organization_id,
2544 l_instance_dtls.inventory_revision,
2545 l_instance_dtls.quantity,
2546 l_instance_dtls.unit_of_measure);
2547 IF (l_item_match) THEN
2548 IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2549 FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY,
2550 'Instance ' || p_x_extra_instances_tbl(i) || ' fits position ' || p_x_relations_tbl(j));
2551 END IF;
2552 IF (l_map_tbl(p_x_extra_instances_tbl(i))) <> 0 THEN
2553 -- More than one match
2554 l_map_tbl(p_x_extra_instances_tbl(i)) := -1;
2555 EXIT; -- No need to check more positions: go to the next instance
2556 ELSE
2557 -- First Match
2558 l_map_tbl(p_x_extra_instances_tbl(i)) := p_x_relations_tbl(j);
2559 END IF;
2560 END IF; -- l_item_match is true
2561 j := p_x_relations_tbl.NEXT(j);
2562 END LOOP; -- For all Positions
2563 i := p_x_extra_instances_tbl.NEXT(i);
2564 END LOOP; -- For all instances (Extra Nodes)
2565
2566 -- Now that analysis is done, process the instances
2567 i := p_x_extra_instances_tbl.FIRST;
2568 WHILE (i IS NOT NULL) LOOP
2569 IF (l_map_tbl(p_x_extra_instances_tbl(i))) = 0 THEN
2570 -- No Matching position found: Delete and Ignore this instance
2571 -- Instance will continue to remain an extra node.
2572 p_x_extra_instances_tbl.DELETE(i);
2573 ELSIF (l_map_tbl(p_x_extra_instances_tbl(i))) > 0 THEN
2574 -- Exactly one matching position has been found: Check if this matched relationship
2575 -- is also a match for any other instance
2576 l_current_position := l_map_tbl(p_x_extra_instances_tbl(i));
2577 k := p_x_extra_instances_tbl.NEXT(i);
2578 l_matched_flag := FALSE;
2579 WHILE (k IS NOT NULL) LOOP
2580 IF (l_map_tbl(p_x_extra_instances_tbl(k)) = l_current_position) THEN
2581 -- Another instance also has been matched to this position: Ignore that instance
2582 l_map_tbl(p_x_extra_instances_tbl(k)) := -1;
2583 l_matched_flag := TRUE;
2584 END IF;
2585 k := p_x_extra_instances_tbl.NEXT(k);
2586 END LOOP;
2587 IF (l_matched_flag = TRUE) THEN
2588 -- One or more instance also has been matched to this instance's position:
2589 -- Ignore the current instance. Let the user associate manually.
2590 l_map_tbl(p_x_extra_instances_tbl(i)) := -1;
2591 ELSE
2592 -- Exactly one matching position has been found
2593 -- Set the Position reference for the csi_ii_relationship
2594 OPEN get_ii_rel_dtls_csr(p_x_extra_instances_tbl(i));
2595 FETCH get_ii_rel_dtls_csr INTO l_ii_rel_dtls;
2596 CLOSE get_ii_rel_dtls_csr;
2597 --Set CSI relationship record
2598 l_csi_relationship_rec.relationship_id := l_ii_rel_dtls.relationship_id;
2599 l_csi_relationship_rec.object_version_number := l_ii_rel_dtls.object_version_number;
2600 l_csi_relationship_rec.position_reference := to_char(l_current_position);
2601 l_csi_relationship_rec.object_id := l_ii_rel_dtls.object_id;
2602 l_csi_relationship_rec.subject_id := l_ii_rel_dtls.subject_id;
2603 l_csi_relationship_tbl(1) := l_csi_relationship_rec;
2604 IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2605 FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY,
2606 'About to call CSI_II_RELATIONSHIPS_PUB.update_relationship to update CSI II relationship with id ' ||
2607 l_ii_rel_dtls.relationship_id || ' between ' ||
2608 l_ii_rel_dtls.object_id || ' (object) and ' ||
2609 l_ii_rel_dtls.subject_id || '(subject) with position_reference ' ||
2610 to_char(l_current_position));
2611 END IF;
2612 CSI_II_RELATIONSHIPS_PUB.update_relationship(
2613 p_api_version => 1.0,
2614 p_relationship_tbl => l_csi_relationship_tbl,
2615 p_txn_rec => l_csi_transaction_rec,
2616 x_return_status => l_return_status,
2617 x_msg_count => l_msg_count,
2618 x_msg_data => l_msg_data);
2619 IF (l_return_status = FND_API.G_RET_STS_ERROR) THEN
2620 RAISE FND_API.G_EXC_ERROR;
2621 ELSIF (l_return_status = FND_API.G_RET_STS_UNEXP_ERROR) THEN
2622 RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2623 END IF;
2624 -- Now recursively match all the children of the current instance/position
2625 IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2626 FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY,
2627 'About to recursively call Remap_IB_Tree');
2628 END IF;
2629 Remap_IB_Tree(p_instance_id => p_x_extra_instances_tbl(i),
2630 p_relationship_id => l_current_position);
2631 IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2632 FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, L_DEBUG_KEY,
2633 'Returned from recursive call to Remap_IB_Tree');
2634 END IF;
2635 -- Now delete the matched relationship
2636 j := p_x_relations_tbl.FIRST;
2637 WHILE (j IS NOT NULL) LOOP
2638 IF p_x_relations_tbl(j) = l_current_position THEN
2639 p_x_relations_tbl.DELETE(j);
2640 EXIT;
2641 END IF;
2642 j := p_x_relations_tbl.NEXT(j);
2643 END LOOP;
2644 -- Now delete the matched instance
2645 p_x_extra_instances_tbl.DELETE(i);
2646 END IF; -- l_matched_flag is TRUE or FALSE
2647 ELSE
2648 -- Multiple matching positions found: Do nothing and let the user associate manually
2649 null;
2650 END IF;
2651 i := p_x_extra_instances_tbl.NEXT(i);
2652 END LOOP;
2653 l_map_tbl.DELETE; -- Clear up the temporary Associative Array
2654
2655 IF (FND_LOG.LEVEL_PROCEDURE >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2656 FND_LOG.STRING(FND_LOG.LEVEL_PROCEDURE, L_DEBUG_KEY || '.end',
2657 'At the end of the procedure. Remaining Instances: ' || p_x_extra_instances_tbl.count);
2658 END IF;
2659 END Process_instances;
2660
2661
2662 END AHL_UC_TREE_PVT; -- Package body