DBA Data[Home] [Help]

PACKAGE BODY: APPS.AHL_MC_PATH_POSITION_PVT

Source


1 PACKAGE BODY AHL_MC_PATH_POSITION_PVT AS
2 /* $Header: AHLVPOSB.pls 120.5.12020000.2 2012/12/07 08:05:07 sareepar ship $ */
3 G_PKG_NAME          CONSTANT VARCHAR2(30) := 'Ahl_MC_Path_Position_Pvt';
4 
5 --Generic separators for the fields.
6 G_ID_SEPARATOR      CONSTANT VARCHAR2(1) := ':';
7 G_NODE_SEPARATOR    CONSTANT VARCHAR2(1) := '/';
8 
9 
10 
11 --------------------------------
12 -- Start of Comments --
13 --  Procedure name    : Create_Position_ID
14 --  Type        : Private
15 --  Function    : API to create the new path position or if matches
16 --    existing one, return the existing path_position_id
17 --  Pre-reqs    :
18 --  Parameters  :
19 --
20 --  Create_Position_ID Parameters:
21 --   p_path_position_tbl IN   AHL_MC_PATH_POSITION_PVT.Path_Position_Tbl_Type Required
22 --   p_pos_ref_meaning      IN VARCHAR2 Optional. Position ref for the path
23 --
24 --  End of Comments.
25 
26 PROCEDURE Create_Position_ID (
27     p_api_version         IN           NUMBER,
28     p_init_msg_list       IN           VARCHAR2  := FND_API.G_FALSE,
29     p_commit              IN           VARCHAR2  := FND_API.G_FALSE,
30     p_validation_level    IN           NUMBER    := FND_API.G_VALID_LEVEL_FULL,
31     x_return_status       OUT  NOCOPY    VARCHAR2,
32     x_msg_count           OUT  NOCOPY    NUMBER,
33     x_msg_data            OUT  NOCOPY    VARCHAR2,
34     p_path_position_tbl   IN       AHL_MC_PATH_POSITION_PVT.Path_Position_Tbl_Type,
35     p_position_ref_meaning  IN      VARCHAR2,
36     p_position_ref_code  IN         VARCHAR2,
37    x_position_id      OUT  NOCOPY    NUMBER)
38 IS
39 --
40 --Check that all 3 ids are valid.
41 CURSOR check_mc_ids_csr (p_mc_id  IN  NUMBER,
42               p_ver_num IN NUMBER,
43               p_pos_key IN NUMBER) IS
44    SELECT  'X'
45      FROM    ahl_mc_headers_b hd, ahl_mc_relationships rel
46      WHERE  hd.mc_header_id = rel.mc_header_id
47      AND    hd.mc_id = p_mc_id
48      AND    hd.version_number = nvl(p_ver_num, hd.version_number)
49      AND    rel.position_key = p_pos_key;
50 --
51 --Check that the config/subconfig mapping is valid.
52 CURSOR check_mc_relationships_csr (p_mc_id  IN  NUMBER,
53                        p_ver_num IN NUMBER,
54                        p_pos_key IN NUMBER,
55                    p_child_mc_id IN NUMBER,
56                    p_child_ver_num IN NUMBER) IS
57    SELECT  'X'
58      FROM   ahl_mc_config_relations rel, ahl_mc_headers_b hd
59      WHERE  rel.mc_header_id = hd.mc_header_id
60      AND    hd.mc_id = p_child_mc_id
61      AND    hd.version_number = nvl(p_child_ver_num, hd.version_number)
62      AND    rel.relationship_id IN
63       (SELECT r.relationship_id
64          FROM ahl_mc_relationships r, ahl_mc_headers_b h
65         WHERE h.mc_header_id = r.mc_header_id
66           AND    h.mc_id = p_mc_id
67           AND    h.version_number = nvl(p_ver_num, h.version_number)
68           AND    r.position_key = p_pos_key);
69 --
70 --Check the encoded path position csr
71 CURSOR get_position_id_csr (p_encoded_path IN VARCHAR2) IS
72 SELECT pos.path_position_id
73   FROM ahl_mc_path_positions pos
74  WHERE pos.encoded_path_position = p_encoded_path;
75 --
76 CURSOR get_sibling_poskey_csr(p_mc_id IN NUMBER, p_poskey IN NUMBER) IS
77 SELECT distinct r2.position_key
78 FROM ahl_mc_relationships r1, ahl_mc_relationships r2, ahl_mc_headers_b hdr
79 WHERE r1.parent_relationship_id = r2.parent_relationship_id
80 AND r1.position_key <> r2.position_key
81 AND r1.position_key = p_poskey
82 AND r1.mc_header_id = hdr.mc_header_id
83 AND hdr.mc_id = p_mc_id;
84 --
85 CURSOR get_pos_common_id_csr (p_encoded_path IN VARCHAR2, p_size IN NUMBER) IS
86 SELECT pos.path_pos_common_id
87 FROM  AHL_MC_PATH_POSITIONS pos
88 WHERE pos.encoded_path_position like p_encoded_path
89 AND p_size = (select COUNT(path_position_node_id) from
90 AHL_MC_PATH_POSITION_NODES where path_position_id = pos.path_position_id);
91 --
92 CURSOR get_next_path_pos_id_csr IS
93 SELECT ahl_mc_path_positions_s.nextval
94 FROM dual;
95 --
96 l_junk         VARCHAR2(1);
97 l_api_version      CONSTANT NUMBER       := 1.0;
98 l_api_name         CONSTANT VARCHAR2(30) := 'Create_Position_ID';
99 l_pos_rec          AHL_MC_PATH_POSITION_PVT.Path_Position_Rec_Type;
100 l_position_id      NUMBER;
101 l_encoded_path     AHL_MC_PATH_POSITIONS.ENCODED_PATH_POSITION%TYPE;
102 l_position_ref_code     VARCHAR2(30);
103 l_path_tbl         AHL_MC_PATH_POSITION_PVT.Path_Position_Tbl_Type;
104 l_msg_count    NUMBER;
105 l_return_val       BOOLEAN;
106 l_index            NUMBER;
107 l_sib_pos_ref_code  VARCHAR2(30);
108 l_poskey           NUMBER;
109 l_no_ver_path_tbl  AHL_MC_PATH_POSITION_PVT.Path_Position_Tbl_Type;
110 l_common_id        NUMBER;
111 l_ver_spec_score   NUMBER;
112 l_count            NUMBER;
113 --
114 BEGIN
115   -- Standard start of API savepoint
116   SAVEPOINT Create_Position_ID_pvt;
117 
118   -- Initialize Procedure return status to success
119   x_return_status := FND_API.G_RET_STS_SUCCESS;
120   -- Standard call to check for call compatibility
121   IF NOT FND_API.Compatible_API_Call(l_api_version, p_api_version, l_api_name,
122                                      G_PKG_NAME) THEN
123     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
124   END IF;
125 
126   -- Initialize message list if p_init_msg_list is set to TRUE
127   IF FND_API.To_Boolean(p_init_msg_list) THEN
128     FND_MSG_PUB.Initialize;
129   END IF;
130 
131   --initialize ver spec score;
132   l_ver_spec_score := 0;
133   l_count :=0;
134 
135   --Do id validations
136   FOR i IN p_path_position_tbl.FIRST..p_path_position_tbl.LAST  LOOP
137    l_pos_rec := p_path_position_tbl(i);
138    l_path_tbl(i) := l_pos_rec;
139    l_no_ver_path_tbl(i) := l_pos_rec;
140    l_no_ver_path_tbl(i).version_number := NULL;
141    l_count := l_count +1;
142 
143    OPEN check_mc_ids_csr(l_pos_rec.mc_id, l_pos_rec.version_number,
144              l_pos_rec.position_key);
145    FETCH check_mc_ids_csr INTO l_junk;
146    IF (check_mc_ids_csr%NOTFOUND) THEN
147        FND_MESSAGE.Set_Name('AHL','AHL_MC_PATH_NODE_INV');
148        FND_MESSAGE.Set_Token('MC_ID',l_pos_rec.mc_id);
149        FND_MESSAGE.Set_Token('VER',l_pos_rec.version_number);
150        FND_MESSAGE.Set_Token('POS_KEY',l_pos_rec.position_key);
151        FND_MSG_PUB.ADD;
152    END IF;
153    CLOSE check_mc_ids_csr;
154 
155    IF (l_pos_rec.version_number IS NOT NULL AND
156        l_count <= p_path_position_tbl.COUNT ) THEN
157      l_ver_spec_score := l_ver_spec_score + POWER(2,(p_path_position_tbl.COUNT-l_count));
158    END IF;
159 
160    IF (i< p_path_position_tbl.LAST) THEN
161      OPEN check_mc_relationships_csr(l_pos_rec.mc_id,
162              l_pos_rec.version_number,
163              l_pos_rec.position_key,
164              p_path_position_tbl(i+1).mc_id,
165              p_path_position_tbl(i+1).version_number);
166      FETCH check_mc_relationships_csr INTO l_junk;
167      IF (check_mc_relationships_csr%NOTFOUND) THEN
168        FND_MESSAGE.Set_Name('AHL','AHL_MC_PATH_RELNSHIP_INV');
169        FND_MESSAGE.Set_Token('MC_ID',p_path_position_tbl(i+1).mc_id);
170        FND_MESSAGE.Set_Token('VER',p_path_position_tbl(i+1).version_number);
171        FND_MESSAGE.Set_Token('POS_KEY',l_pos_rec.position_key);
172        FND_MSG_PUB.ADD;
173      END IF;
174      CLOSE check_mc_relationships_csr;
175    END IF;
176 
177   END LOOP;
178 
179   --Convert the position ref meaning only if position ref code is undefined.
180   IF (p_position_ref_code = FND_API.G_MISS_CHAR) THEN
181     IF (p_position_ref_meaning = FND_API.G_MISS_CHAR) THEN
182        l_position_ref_code := NULL;
183     ELSIF (p_position_ref_meaning IS NULL) THEN
184        l_position_ref_code := NULL;
185     ELSIF (p_position_ref_meaning <> FND_API.G_MISS_CHAR) THEN
186        AHL_UTIL_MC_PKG.Convert_To_LookupCode('AHL_POSITION_REFERENCE',
187                                            p_position_ref_meaning,
188                                            l_position_ref_code,
189                                            l_return_val);
190        IF NOT(l_return_val) THEN
191          FND_MESSAGE.Set_Name('AHL','AHL_MC_POSREF_INVALID');
192          FND_MESSAGE.Set_Token('POSREF',p_position_ref_meaning);
193          FND_MSG_PUB.ADD;
194        END IF;
195      END IF;
196    ELSE
197     l_position_ref_code := p_position_ref_code;
198    END IF;
199 
200    -- Check Error Message stack.
201    l_msg_count := FND_MSG_PUB.count_msg;
202    IF l_msg_count > 0 THEN
203      RAISE  FND_API.G_EXC_ERROR;
204    END IF;
205 
206    --Convert to find all same level paths
207    IF (l_position_ref_code <> FND_API.G_MISS_CHAR AND
208        l_position_ref_code IS NOT NULL) THEN
209      l_poskey := l_path_tbl(l_path_tbl.LAST).position_key;
210      OPEN get_sibling_poskey_csr(l_path_tbl(l_path_tbl.LAST).mc_id,
211                 l_poskey);
212      LOOP
213       FETCH get_sibling_poskey_csr INTO l_path_tbl(l_path_tbl.LAST).position_key;
214       EXIT WHEN get_sibling_poskey_csr%NOTFOUND;
215       l_sib_pos_ref_code := get_posref_by_path(l_path_tbl, FND_API.G_TRUE);
216       IF (l_sib_pos_ref_code = l_position_ref_code) THEN
217         FND_MESSAGE.Set_Name('AHL','AHL_MC_POSREF_DUPLICATE');
218         FND_MESSAGE.Set_Token('POSREF',l_position_ref_code);
219         FND_MSG_PUB.ADD;
220       END IF;
221      END LOOP;
222      CLOSE get_sibling_poskey_csr;
223    END IF;
224 
225    -- Check Error Message stack.
226    l_msg_count := FND_MSG_PUB.count_msg;
227    IF l_msg_count > 0 THEN
228      RAISE  FND_API.G_EXC_ERROR;
229    END IF;
230 
231    --Encode the path_position_tbl
232    l_encoded_path := Encode(p_path_position_tbl);
233    l_index :=0;
234 
235 
236    --Compare and find matching path_position
237    OPEN get_position_id_csr(l_encoded_path);
238    FETCH get_position_id_csr INTO x_position_id;
239    IF (get_position_id_csr%FOUND) THEN
240      /* Changed by jaramana on 16-FEB-2012 to avoid unnecessary attempts
241       * to UPDATE which cause race conditions during Bulk Part Change.
242       * Update only if the new pos ref code is not null and the existing value is
243       * null.
244       */
245      /*
246       IF (l_position_ref_code <> FND_API.G_MISS_CHAR OR
247           l_position_ref_code IS NULL) THEN
248       */
249        IF (l_position_ref_code IS NOT NULL) THEN
250         UPDATE ahl_mc_path_positions SET
251       OBJECT_VERSION_NUMBER = OBJECT_VERSION_NUMBER+1,
252           LAST_UPDATE_DATE      = sysdate,
253           LAST_UPDATED_BY       = fnd_global.USER_ID,
254           LAST_UPDATE_LOGIN     = fnd_global.LOGIN_ID,
255       POSITION_REF_CODE     = l_position_ref_code
256          WHERE PATH_POSITION_ID = x_position_id
257            AND POSITION_REF_CODE IS NULL;
258        END IF;
259    ELSE
260 
261      OPEN get_next_path_pos_id_csr;
262      FETCH get_next_path_pos_id_csr INTO l_position_id;
263      CLOSE get_next_path_pos_id_csr;
264 
265      --Determine the path_position_common_id
266      OPEN get_pos_common_id_csr(Encode(l_no_ver_path_tbl),
267                 p_path_position_tbl.COUNT);
268      FETCH get_pos_common_id_csr INTO l_common_id;
269      --If not found, generate new common id
270      IF (get_pos_common_id_csr%NOTFOUND OR l_common_id IS NULL) THEN
271         l_common_id := l_position_id;
272      END IF;
273      CLOSE get_pos_common_id_csr;
274 
275     --Do inserts
276     INSERT INTO ahl_mc_path_positions(
277         PATH_POSITION_ID,
278         PATH_POS_COMMON_ID,
279     OBJECT_VERSION_NUMBER,
280         LAST_UPDATE_DATE,
281         LAST_UPDATED_BY,
282         CREATION_DATE,
283         CREATED_BY,
284         LAST_UPDATE_LOGIN,
285     ENCODED_PATH_POSITION,
286     POSITION_REF_CODE,
287         VER_SPEC_SCORE,
288         ATTRIBUTE_CATEGORY,
289         ATTRIBUTE1,
290         ATTRIBUTE2,
291         ATTRIBUTE3,
292         ATTRIBUTE4,
293         ATTRIBUTE5,
294         ATTRIBUTE6,
295         ATTRIBUTE7,
296         ATTRIBUTE8,
297         ATTRIBUTE9,
298         ATTRIBUTE10,
299         ATTRIBUTE11,
300         ATTRIBUTE12,
301         ATTRIBUTE13,
302         ATTRIBUTE14,
303         ATTRIBUTE15
304         ) VALUES (
305         l_position_id,
306         l_common_id,
307     1,
308         sysdate,
309         fnd_global.user_id,
310         sysdate,
311         fnd_global.user_id,
312         fnd_global.login_id,
313         l_encoded_path,
314     l_position_ref_code,
315         l_ver_spec_score,
316     NULL,
317     NULL,   NULL,   NULL,   NULL,   NULL,
318     NULL,   NULL,   NULL,   NULL,   NULL,
319     NULL,   NULL,   NULL,   NULL,   NULL
320        )
321       RETURNING path_position_id INTO x_position_id;
322 
323     --Insert the path position nodes
324     FOR i IN p_path_position_tbl.FIRST..p_path_position_tbl.LAST LOOP
325      INSERT INTO ahl_mc_path_position_nodes(
326         PATH_POSITION_NODE_ID,
327     OBJECT_VERSION_NUMBER,
328         LAST_UPDATE_DATE,
329         LAST_UPDATED_BY,
330         CREATION_DATE,
331         CREATED_BY,
332         LAST_UPDATE_LOGIN,
333     PATH_POSITION_ID,
334     SEQUENCE,
335     MC_ID,
336     VERSION_NUMBER,
337     POSITION_KEY,
338         ATTRIBUTE_CATEGORY,
339         ATTRIBUTE1,
340         ATTRIBUTE2,
341         ATTRIBUTE3,
342         ATTRIBUTE4,
343         ATTRIBUTE5,
344         ATTRIBUTE6,
345         ATTRIBUTE7,
346         ATTRIBUTE8,
347         ATTRIBUTE9,
348         ATTRIBUTE10,
349         ATTRIBUTE11,
350         ATTRIBUTE12,            ATTRIBUTE13,
351         ATTRIBUTE14,
352         ATTRIBUTE15
353         ) VALUES (
354         ahl_mc_path_position_nodes_s.nextval,
355     1,
356         sysdate,
357         fnd_global.user_id,
358         sysdate,
359         fnd_global.user_id,
360         fnd_global.login_id,
361     x_position_id,
362     l_index,
363         p_path_position_tbl(i).mc_id,
364     p_path_position_tbl(i).version_number,
365     p_path_position_tbl(i).position_key,
366     p_path_position_tbl(i).attribute_category ,
367     p_path_position_tbl(i).attribute1 ,
368     p_path_position_tbl(i).attribute2 ,
369     p_path_position_tbl(i).attribute3 ,
370     p_path_position_tbl(i).attribute4 ,
371     p_path_position_tbl(i).attribute5 ,
372     p_path_position_tbl(i).attribute6 ,
373     p_path_position_tbl(i).attribute7 ,
374     p_path_position_tbl(i).attribute8 ,
375     p_path_position_tbl(i).attribute9 ,
376     p_path_position_tbl(i).attribute10 ,
377     p_path_position_tbl(i).attribute11 ,
378     p_path_position_tbl(i).attribute12 ,
379     p_path_position_tbl(i).attribute13 ,
380     p_path_position_tbl(i).attribute14 ,
381     p_path_position_tbl(i).attribute15 );
382       l_index := l_index +1;
383     END LOOP;
384    END IF;
385    CLOSE get_position_id_csr;
386 
387   -- Standard check of p_commit
388   IF FND_API.TO_BOOLEAN(p_commit) THEN
389       COMMIT WORK;
390   END IF;
391   -- Standard call to get message count and if count is 1, get message info
392   FND_MSG_PUB.Count_And_Get
393     ( p_count => x_msg_count,
394       p_data  => x_msg_data,
395       p_encoded => fnd_api.g_false
396     );
397 EXCEPTION
398  WHEN FND_API.G_EXC_ERROR THEN
399    Rollback to Create_Position_ID_pvt;
400    x_return_status := FND_API.G_RET_STS_ERROR;
401    FND_MSG_PUB.count_and_get( p_count => x_msg_count,
402                               p_data  => x_msg_data,
403                               p_encoded => fnd_api.g_false);
404  WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
405    Rollback to Create_Position_ID_pvt;
406    x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
407    FND_MSG_PUB.count_and_get( p_count => x_msg_count,
408                               p_data  => x_msg_data,
409                               p_encoded => fnd_api.g_false);
410  WHEN OTHERS THEN
411    Rollback to Create_Position_ID_pvt;
412    x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
413    Fnd_Msg_Pub.add_exc_msg( p_pkg_name       => G_PKG_NAME,
414                              p_procedure_name => l_api_name,
415                              p_error_text     => SQLERRM);
416     FND_MSG_PUB.count_and_get( p_count => x_msg_count,
417                               p_data  => x_msg_data,
418                               p_encoded => fnd_api.g_false);
419 
420 END Create_Position_ID;
421 
422 -----------------------------
423 -- Start of Comments --
424 --  Procedure name    : Map_Instance_To_Positions
425 --  Type        : Private
426 --  Function    : Writes a list of positions that maps to instance
427 --     into AHL_APPLICABLE_INSTANCES
428 --  Pre-reqs    :
429 --  Parameters  :
430 --
431 --  Map_Instance_To_Positions Parameters:
432 --       p_csi_item_instance_id  IN NUMBER  Required. instance for the path
433 --
434 --  End of Comments.
435 
436 PROCEDURE Map_Instance_To_Positions (
437     p_api_version         IN           NUMBER,
438     p_init_msg_list       IN           VARCHAR2  := FND_API.G_FALSE,
439     p_commit              IN           VARCHAR2  := FND_API.G_FALSE,
440     p_validation_level    IN           NUMBER    := FND_API.G_VALID_LEVEL_FULL,
441     x_return_status       OUT  NOCOPY    VARCHAR2,
442     x_msg_count           OUT  NOCOPY    NUMBER,
443     x_msg_data            OUT  NOCOPY    VARCHAR2,
444     p_csi_item_instance_id   IN         NUMBER)
445 IS
446 --
447 --Fetch the unit and unit header info for instance
448 CURSOR get_uc_headers_csr (p_csi_instance_id IN NUMBER) IS
449 SELECT up.parent_mc_id, up.parent_version_number, up.parent_position_key
450 FROM  ahl_uc_header_paths_v up
451 WHERE up.csi_instance_id = p_csi_instance_id;
452 --
453 CURSOR get_unit_instance_csr  (p_csi_instance_id IN NUMBER) IS
454 SELECT csi.object_id
455   FROM csi_ii_relationships csi
456 WHERE csi.object_id IN
457       ( SELECT csi_item_instance_id
458      FROM ahl_unit_config_headers
459         WHERE trunc(nvl(active_start_date,sysdate)) <= trunc(sysdate)
460           AND trunc(sysdate) < trunc(nvl(active_end_date, sysdate+1)))
461 START WITH csi.subject_id = p_csi_instance_id
462     AND CSI.RELATIONSHIP_TYPE_CODE  = 'COMPONENT-OF'
463     AND TRUNC(nvl(CSI.ACTIVE_START_DATE, sysdate)) <= TRUNC(sysdate)
464     AND TRUNC(nvl(CSI.ACTIVE_END_DATE, sysdate+1)) > TRUNC(sysdate)
465 CONNECT BY csi.subject_id = PRIOR csi.object_id
466     AND CSI.RELATIONSHIP_TYPE_CODE  = 'COMPONENT-OF'
467     AND TRUNC(nvl(CSI.ACTIVE_START_DATE, sysdate)) <= TRUNC(sysdate)
468     AND TRUNC(nvl(CSI.ACTIVE_END_DATE, sysdate+1)) > TRUNC(sysdate)
469     AND CSI.POSITION_REFERENCE IS NOT NULL;
470 --
471 --Fetches lowest level info
472 CURSOR get_last_uc_rec_csr (p_csi_instance_id IN NUMBER) IS
473 SELECT hdr.mc_id, hdr.version_number, rel.position_key
474 FROM ahl_mc_headers_b hdr, ahl_mc_relationships rel,
475     csi_ii_relationships csi_ii
476 WHERE csi_ii.subject_id = p_csi_instance_id
477     AND CSI_II.RELATIONSHIP_TYPE_CODE  = 'COMPONENT-OF'
478     AND TRUNC(nvl(CSI_II.ACTIVE_START_DATE, sysdate)) <= TRUNC(sysdate)
479     AND TRUNC(nvl(CSI_II.ACTIVE_END_DATE, sysdate+1)) > TRUNC(sysdate)
480     AND TO_NUMBER(CSI_II.POSITION_REFERENCE) = REL.RELATIONSHIP_ID
481     AND REL.mc_header_id = HDR.mc_header_id;
482 --
483 CURSOR get_top_unit_inst_csr (p_csi_instance_id IN NUMBER) IS
484 SELECT hdr.mc_id, hdr.version_number, rel.position_key
485 FROM ahl_mc_headers_b hdr, ahl_mc_relationships rel,
486   ahl_unit_config_headers uch, csi_unit_instances_v csi_u
487 WHERE uch.csi_item_instance_id = p_csi_instance_id
488   AND TRUNC(nvl(uch.ACTIVE_START_DATE, sysdate)) <= TRUNC(sysdate)
489   AND TRUNC(nvl(uch.ACTIVE_END_DATE, sysdate+1)) > TRUNC(sysdate)
490   AND hdr.mc_header_id = uch.master_config_id
491   AND rel.mc_header_id = hdr.mc_header_id
492   AND rel.parent_relationship_id IS NULL
493   AND uch.csi_item_instance_id = csi_u.instance_id;
494 
495 --
496 --Fetch all encoded path positions like the generated path
497 CURSOR get_matching_pos_csr (p_encoded_path IN VARCHAR2, p_size IN NUMBER) IS
498 SELECT pos.path_position_id
499 FROM  AHL_MC_PATH_POSITIONS pos
500 -- Query modified by jaramana on 12-JUN-2012 to fix perf bug 13629335
501 -- The first predicate ensures that any index on encoded_path_position is used for improved performance
502 -- The second predicate (with the variable in the LHS and the table column value having embedded wild card characters in the RHS)
503 -- does the wild card comparison correctly
504 WHERE pos.encoded_path_position LIKE SUBSTR (p_encoded_path, 1, INSTR (p_encoded_path, ':')) || '%'
505 AND p_encoded_path LIKE pos.encoded_path_position
506 AND p_size = (select COUNT(path_position_node_id) from
507 AHL_MC_PATH_POSITION_NODES where path_position_id = pos.path_position_id);
508 --
509 
510 --modification by jrotich on 10/02/2012 for fixing bug 13472472 BEGIN
511 --returns details of the current instance if it is itself an mc within another MC
512 CURSOR get_current_mc_rec_csr(c_instance_id IN NUMBER) IS
513 SELECT amh.mc_id, amh.version_number, amr.position_key
514 FROM ahl_unit_config_headers auch,
515   ahl_mc_headers_b amh,
516   ahl_mc_relationships amr
517 WHERE auch.csi_item_instance_id = c_instance_id
518 AND amh.mc_header_id = auch.master_config_id
519 AND amr.mc_header_id = amh.mc_header_id
520 AND amr.parent_relationship_id is null;
521 --modification by jrotich end
522 --
523 
524 l_path_tbl        AHL_MC_PATH_POSITION_PVT.Path_Position_Tbl_Type;
525 l_path_rec        AHL_MC_PATH_POSITION_PVT.Path_Position_Rec_Type;
526 l_index            NUMBER;
527 l_encoded_path     AHL_MC_PATH_POSITIONS.ENCODED_PATH_POSITION%TYPE;
528 l_api_version      CONSTANT NUMBER       := 1.0;
529 l_api_name         CONSTANT VARCHAR2(30) := 'Map_Instance_To_Positions';
530 l_position_id      NUMBER;
531 l_unit_csi_id      NUMBER;
532 --l_mc_path_tbl added by jrotich to fix bug 13472472
533 l_mc_path_tbl     AHL_MC_PATH_POSITION_PVT.Path_Position_Tbl_Type;
534 
535 --
536 BEGIN
537   -- Standard start of API savepoint
538   SAVEPOINT Map_Instance_To_Positions_pvt;
539 
540   -- Initialize Procedure return status to success
541   x_return_status := FND_API.G_RET_STS_SUCCESS;
542   -- Standard call to check for call compatibility
543   IF NOT FND_API.Compatible_API_Call(l_api_version, p_api_version, l_api_name,
544                                      G_PKG_NAME) THEN
545     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
546   END IF;
547 
548   -- Initialize message list if p_init_msg_list is set to TRUE
549   IF FND_API.To_Boolean(p_init_msg_list) THEN
550     FND_MSG_PUB.Initialize;
551   END IF;
552 
553   --Fetch the position informations for the instance
554   OPEN get_last_uc_rec_csr(p_csi_item_instance_id);
555   FETCH get_last_uc_rec_csr INTO l_path_rec.mc_id,
556                  l_path_rec.version_number,
557                  l_path_rec.position_key;
558   IF (get_last_uc_rec_csr%NOTFOUND) THEN
559 
560     --Fetch the position informations for the unit instance
561     OPEN get_top_unit_inst_csr(p_csi_item_instance_id);
562     FETCH get_top_unit_inst_csr INTO l_path_rec.mc_id,
563                  l_path_rec.version_number,
564                  l_path_rec.position_key;
565     --Check top node only
566     IF (get_top_unit_inst_csr%FOUND) THEN
567         --Sunil found the following line was missing and was added on 12/08/2004
568         l_path_tbl(1) := l_path_rec;
569         --Encode the path_position_tbl
570         l_encoded_path := Encode(l_path_tbl);
571 
572        OPEN get_matching_pos_csr(l_encoded_path, l_path_tbl.COUNT);
573        LOOP
574          FETCH get_matching_pos_csr INTO l_position_id;
575          EXIT WHEN get_matching_pos_csr%NOTFOUND;
576          INSERT INTO AHL_APPLICABLE_INSTANCES (csi_item_instance_id,
577                     position_id)
578         VALUES (p_csi_item_instance_id, l_position_id);
579        END LOOP;
580        CLOSE get_matching_pos_csr;
581 
582      END IF;
583      CLOSE get_top_unit_inst_csr;
584 
585    ELSE
586      l_path_tbl(1) := l_path_rec;
587 
588      --Add positions matching lowest level
589      l_encoded_path := Encode(l_path_tbl);
590 
591      OPEN get_matching_pos_csr(l_encoded_path, l_path_tbl.COUNT);
592      LOOP
593          FETCH get_matching_pos_csr INTO l_position_id;
594          EXIT WHEN get_matching_pos_csr%NOTFOUND;
595          INSERT INTO AHL_APPLICABLE_INSTANCES (csi_item_instance_id,
596                     position_id)
597         VALUES (p_csi_item_instance_id, l_position_id);
598      END LOOP;
599      CLOSE get_matching_pos_csr;
600 
601 
602     --Now fetch the position paths which match at higher levels.
603     l_index := 0;
604     --Fetch the header rec info for the instance
605     OPEN get_unit_instance_csr(p_csi_item_instance_id);
606     LOOP
607       FETCH get_unit_instance_csr INTO l_unit_csi_id;
608       EXIT WHEN get_unit_instance_csr%NOTFOUND;
609 
610       OPEN get_uc_headers_csr(l_unit_csi_id);
611       FETCH get_uc_headers_csr INTO l_path_rec.mc_id,
612                    l_path_rec.version_number,
613                    l_path_rec.position_key;
614       CLOSE get_uc_headers_csr;
615       IF (l_path_rec.mc_id is not null AND
616          l_path_rec.position_key is not null) THEN
617        l_path_tbl(l_index) := l_path_rec;
618        l_index := l_index - 1;
619 
620        --Encode the modified with new params path_position_tbl
621        l_encoded_path := Encode(l_path_tbl);
622 
623        --dbms_output.put_line (l_encoded_path);
624 
625        OPEN get_matching_pos_csr(l_encoded_path, l_path_tbl.COUNT);
626        LOOP
627         FETCH get_matching_pos_csr INTO l_position_id;
628         EXIT WHEN get_matching_pos_csr%NOTFOUND;
629         INSERT INTO AHL_APPLICABLE_INSTANCES (csi_item_instance_id,
630                     position_id)
631         VALUES (p_csi_item_instance_id, l_position_id);
632        END LOOP;
633        CLOSE get_matching_pos_csr;
634 
635       END IF;
636    END LOOP;
637    CLOSE get_unit_instance_csr;
638 
639    --modification by jrotich on 10/02/2012 to fix bug 13472472 begin
640    OPEN get_current_mc_rec_csr(p_csi_item_instance_id);
641    FETCH get_current_mc_rec_csr INTO l_path_rec.mc_id, l_path_rec.version_number, l_path_rec.position_key;
642 
643    IF get_current_mc_rec_csr%FOUND THEN
644      l_mc_path_tbl(0) := l_path_rec;
645 
646      --Encode the modified with new params path_position_tbl
647      l_encoded_path := Encode(l_mc_path_tbl);
648 
649      OPEN get_matching_pos_csr(l_encoded_path, l_mc_path_tbl.COUNT);
650        LOOP
651         FETCH get_matching_pos_csr INTO l_position_id;
652         EXIT WHEN get_matching_pos_csr%NOTFOUND;
653         INSERT INTO AHL_APPLICABLE_INSTANCES (csi_item_instance_id, position_id)
654           VALUES (p_csi_item_instance_id, l_position_id);
655        END LOOP;
656      CLOSE get_matching_pos_csr;
657    END IF;
658    CLOSE get_current_mc_rec_csr;
659    --modification by jrotich on 10/02/2012 to fix bug 13472472
660 
661   END IF;
662   CLOSE get_last_uc_rec_csr;
663 
664   -- Standard call to get message count and if count is 1, get message info
665   FND_MSG_PUB.Count_And_Get
666     ( p_count => x_msg_count,
667       p_data  => x_msg_data,
668       p_encoded => fnd_api.g_false
669     );
670 EXCEPTION
671  WHEN FND_API.G_EXC_ERROR THEN
672    Rollback to Map_Instance_To_Positions_pvt;
673    x_return_status := FND_API.G_RET_STS_ERROR;
674    FND_MSG_PUB.count_and_get( p_count => x_msg_count,
675                               p_data  => x_msg_data,
676                               p_encoded => fnd_api.g_false);
677  WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
678    Rollback to Map_Instance_To_Positions_pvt;
679    x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
680    FND_MSG_PUB.count_and_get( p_count => x_msg_count,
681                               p_data  => x_msg_data,
682                               p_encoded => fnd_api.g_false);
683  WHEN OTHERS THEN
684    Rollback to Map_Instance_To_Positions_pvt;
685    x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
686    Fnd_Msg_Pub.add_exc_msg( p_pkg_name       => G_PKG_NAME,
687                              p_procedure_name => l_api_name,
688                              p_error_text     => SQLERRM);
689     FND_MSG_PUB.count_and_get( p_count => x_msg_count,
690                               p_data  => x_msg_data,
691                               p_encoded => fnd_api.g_false);
692 END Map_Instance_To_Positions;
693 
694 
695 -----------------------------
696 -- Start of Comments --
697 --  Procedure name    : Map_Position_To_Instance
698 --  Type        : Private
699 --  Function    : Writes a list of instances that maps to position path
700 --into AHL_APPLICABLE_INSTANCES
701 --  Pre-reqs    :
702 --  Parameters  :
703 --
704 --  Map_Position_To_Instances Parameters:
705 --       p_position_id      IN  NUMBER  Required
706 --
707 --  End of Comments.
708 
709 PROCEDURE Map_Position_To_Instances (
710     p_api_version         IN           NUMBER,
711     p_init_msg_list       IN           VARCHAR2  := FND_API.G_FALSE,
712     p_commit              IN           VARCHAR2  := FND_API.G_FALSE,
713     p_validation_level    IN           NUMBER    := FND_API.G_VALID_LEVEL_FULL,
714     x_return_status       OUT  NOCOPY    VARCHAR2,
715     x_msg_count           OUT  NOCOPY    NUMBER,
716     x_msg_data            OUT  NOCOPY    VARCHAR2,
717     p_position_id         IN            NUMBER)
718 IS
719 --
720 --Fetch all the position path information for given position_id
721 CURSOR get_position_path_csr (p_position_id IN NUMBER) IS
722 SELECT path.sequence, path.mc_id, path.version_number, path.position_key
723 FROM  AHL_MC_PATH_POSITION_NODES path
724 WHERE path.path_position_id = p_position_id
725 order by sequence;
726 --
727 --Determine if position_key maps to top node of the configuration
728 CURSOR check_pos_key_top_csr(p_mc_id    IN NUMBER,
729                  p_ver_num  IN NUMBER,
730                  p_position_key IN NUMBER) IS
731 SELECT 'X'
732 FROM AHL_MC_RELATIONSHIPS rel, AHL_MC_HEADERS_B HDR
733 WHERE  HDR.mc_header_id = REL.mc_header_id
734   AND REL.parent_relationship_id is NULL
735   AND REL.position_key = p_position_key
736   AND HDR.mc_id = p_mc_id
737   AND HDR.version_number = nvl(p_ver_num, HDR.version_number);
738 
739 --
740 
741 l_api_version      CONSTANT NUMBER       := 1.0;
742 l_api_name         CONSTANT VARCHAR2(30) := 'map_position_to_instances';
743 l_full_name        CONSTANT    VARCHAR2(60)    := 'ahl.plsql.' || g_pkg_name || '.' || l_api_name;
744 l_index            NUMBER;
745 l_dummy            VARCHAR2(1);
746 l_top_flag         BOOLEAN;
747 l_path_tbl         AHL_MC_PATH_POSITION_PVT.Path_Position_Tbl_Type;
748 l_path_rec         AHL_MC_PATH_POSITION_PVT.Path_Position_Rec_Type;
749 v_CursorID         NUMBER;
750 v_Stmt             VARCHAR2(4000);
751 v_Select           VARCHAR2(4000);
752 v_From             VARCHAR2(4000);
753 v_Where            VARCHAR2(4000);
754 v_RowsInserted            INTEGER;
755 
756 --
757 BEGIN
758 
759   IF (fnd_log.level_procedure >= fnd_log.g_current_runtime_level)THEN
760       fnd_log.string(fnd_log.level_procedure,L_FULL_NAME||'.begin','At the start of PLSQL procedure');
761   END IF;
762 
763   -- Standard start of API savepoint
764   SAVEPOINT map_position_to_instances_pvt;
765 
766   -- Initialize Procedure return status to success
767   x_return_status := FND_API.G_RET_STS_SUCCESS;
768   -- Standard call to check for call compatibility
769   IF NOT FND_API.Compatible_API_Call(l_api_version, p_api_version, l_api_name,
770                                      G_PKG_NAME) THEN
771     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
772   END IF;
773 
774   -- Initialize message list if p_init_msg_list is set to TRUE
775   IF FND_API.To_Boolean(p_init_msg_list) THEN
776     FND_MSG_PUB.Initialize;
777   END IF;
778 
779   IF (fnd_log.level_statement >= fnd_log.g_current_runtime_level)THEN
780       fnd_log.string(fnd_log.level_statement,l_full_name,'-- p_position_id --'||p_position_id);
781       fnd_log.string(fnd_log.level_statement,l_full_name,'--Populate position path info--');
782   END IF;
783 
784   l_index :=0;
785   --Populate position path info starting at index =0
786   OPEN get_position_path_csr(p_position_id);
787   LOOP
788      FETCH get_position_path_csr INTO l_path_rec.sequence,
789                        l_path_rec.mc_id,
790                        l_path_rec.version_number,
791                        l_path_rec.position_key;
792       EXIT WHEN get_position_path_csr%NOTFOUND;
793       l_path_tbl(l_index):= l_path_rec;
794       l_index := l_index +1;
795   END LOOP;
796   CLOSE get_position_path_csr;
797 
798   IF (fnd_log.level_statement >= fnd_log.g_current_runtime_level)THEN
799       fnd_log.string(fnd_log.level_statement,l_full_name,'-- Opening Cursor check_pos_key_top_csr --');
800   END IF;
801 
802   OPEN check_pos_key_top_csr(l_path_tbl(l_path_tbl.LAST).mc_id,
803                  l_path_tbl(l_path_tbl.LAST).version_number,
804                  l_path_tbl(l_path_tbl.LAST).position_key);
805   FETCH check_pos_key_top_csr INTO l_dummy;
806   IF (check_pos_key_top_csr%FOUND) THEN
807      l_top_flag := true;
808      IF (fnd_log.level_statement >= fnd_log.g_current_runtime_level)THEN
809          fnd_log.string(fnd_log.level_statement,l_full_name,'-- Set Top FLag to True --');
810      END IF;
811   ELSE
812      l_top_flag := false;
813      IF (fnd_log.level_statement >= fnd_log.g_current_runtime_level)THEN
814          fnd_log.string(fnd_log.level_statement,l_full_name,'-- Set Top FLag to False --');
815      END IF;
816   END IF;
817   CLOSE check_pos_key_top_csr;
818 
819 
820    v_Select := ' SELECT v'||l_path_tbl.LAST||'.csi_instance_id ';
821    v_From  := ' FROM AHL_UC_HEADER_PATHS_V v0 ';
822    v_Where := ' WHERE  v0.mc_id = :mc_id0 ' ||
823           ' AND  v0.mc_version_number = nvl(:ver0,v0.mc_version_number) ';
824 
825    IF (fnd_log.level_statement >= fnd_log.g_current_runtime_level)THEN
826        fnd_log.string(fnd_log.level_statement,l_full_name,'-- v_Select --'||v_Select);
827        fnd_log.string(fnd_log.level_statement,l_full_name,'-- v_From -1-'||v_From);
828        fnd_log.string(fnd_log.level_statement,l_full_name,'-- v_Where -1-'||v_Where);
829    END IF;
830 
831    --Build the dynamic sql statement
832    FOR i IN l_path_tbl.FIRST+1..l_path_tbl.LAST  LOOP
833        v_From := v_From || ', AHL_UC_HEADER_PATHS_V v'||TO_CHAR(i)||' ';
834 
835        -- R12 Dev changes : Modified Function Call to CHECK_POS_REF_PATH_CHAR and
836        -- modified where clause join between uc_header_id and parent_uc_header_id
837 
838        v_Where := v_Where ||
839           ' AND v'||TO_CHAR(i)||'.mc_id = :mc_id'||TO_CHAR(i)||' ' ||
840           ' AND  v'||TO_CHAR(i)||'.mc_version_number = '||
841           '  nvl(:ver'||TO_CHAR(i)||', v'||TO_CHAR(i)||'.mc_version_number) ' ||
842           ' AND v'||TO_CHAR(i-1)||'.uc_header_id = v'||TO_CHAR(i)||'.parent_uc_header_id '
843             ||' AND v'||TO_CHAR(i)||'.parent_position_key = :pos_key'||TO_CHAR(i-1)||'  '
844             ||' AND AHL_MC_PATH_POSITION_PVT.CHECK_POS_REF_PATH_CHAR(v'||TO_CHAR(i)||'.csi_instance_id, v'||TO_CHAR(i)||'.parent_instance_id) = ''T''  ';
845 
846    END LOOP;
847 
848    IF (fnd_log.level_statement >= fnd_log.g_current_runtime_level)THEN
849        fnd_log.string(fnd_log.level_statement,l_full_name,'-- v_From -2-'||v_From);
850        fnd_log.string(fnd_log.level_statement,l_full_name,'-- v_Where -2-'||v_Where);
851    END IF;
852 
853   IF (l_top_flag) THEN
854    v_Stmt := 'INSERT INTO AHL_APPLICABLE_INSTANCES '||
855          ' SELECT uch.csi_instance_id ,'|| p_position_id ||
856          ' FROM AHL_UC_HEADER_PATHS_V uch '||
857          ' WHERE uch.position_key = :pos_key'||l_path_tbl.LAST
858        ||' AND uch.csi_instance_id in ( '
859            || v_Select || v_From || v_Where || ' ) ';
860 
861   ELSE
862    v_Stmt := 'INSERT INTO AHL_APPLICABLE_INSTANCES '||
863          ' SELECT csi_ii.subject_id ,'|| p_position_id ||
864          ' FROM ahl_mc_relationships rel, csi_ii_relationships csi_ii '||
865          ' WHERE TO_NUMBER(CSI_II.POSITION_REFERENCE)=REL.RELATIONSHIP_ID '
866            ||' AND REL.position_key = :pos_key'||l_path_tbl.LAST
867        ||' START WITH csi_ii.object_id IN ( '
868            || v_Select || v_From || v_Where || ' ) '
869            --jrotich changes for bug 14397817 8/6/2012 Begin
870            ||' AND TRUNC(nvl(CSI_II.ACTIVE_START_DATE, sysdate)) <= TRUNC(sysdate) '
871            ||' AND TRUNC(nvl(CSI_II.ACTIVE_END_DATE, sysdate+1)) > TRUNC(sysdate) '
872            --jrotich changes for bug 14397817 8/6/2012 End
873            || ' CONNECT BY PRIOR csi_ii.subject_id = csi_ii.object_id '
874            ||' AND CSI_II.RELATIONSHIP_TYPE_CODE  = ''COMPONENT-OF'' '
875        ||' AND CSI_II.POSITION_REFERENCE IS NOT NULL '
876            ||' AND TRUNC(nvl(CSI_II.ACTIVE_START_DATE, sysdate)) <= TRUNC(sysdate) '
877            ||' AND TRUNC(nvl(CSI_II.ACTIVE_END_DATE, sysdate+1)) > TRUNC(sysdate) ';
878 
879    END IF;
880 
881    IF (fnd_log.level_statement >= fnd_log.g_current_runtime_level)THEN
882        fnd_log.string(fnd_log.level_statement,l_full_name,'-- v_Stmt --'||v_Stmt);
883    END IF;
884 
885    /*for i in 0..(length(v_Stmt)/255) LOOP
886      dbms_output.put_line(substr(v_Stmt,i*255,255));
887    end loop;
888    */
889    ----------------------------------------
890    --Due to performance considerations, doing dynamic sql
891    --------------------------------------
892    v_CursorID := DBMS_SQL.OPEN_CURSOR;
893 
894    IF (fnd_log.level_statement >= fnd_log.g_current_runtime_level)THEN
895        fnd_log.string(fnd_log.level_statement,l_full_name,'-- Parsing Sql --');
896    END IF;
897 
898    DBMS_SQL.PARSE(v_CursorID, v_Stmt, DBMS_SQL.V7);
899 
900    IF (fnd_log.level_statement >= fnd_log.g_current_runtime_level)THEN
901        fnd_log.string(fnd_log.level_statement,l_full_name,'-- Binding Params Sql --');
902    END IF;
903 
904    --Bind the dynamic sql statement
905    FOR i IN l_path_tbl.FIRST..l_path_tbl.LAST  LOOP
906        DBMS_SQL.BIND_VARIABLE (v_CursorID, ':mc_id'||i, l_path_tbl(i).mc_id);
907        DBMS_SQL.BIND_VARIABLE (v_CursorID, ':ver'||i, l_path_tbl(i).version_number);
908        DBMS_SQL.BIND_VARIABLE (v_CursorID, ':pos_key'||i, l_path_tbl(i).position_key);
909    END LOOP;
910 
911    IF (fnd_log.level_statement >= fnd_log.g_current_runtime_level)THEN
912        fnd_log.string(fnd_log.level_statement,l_full_name,'-- After Binding - Before Executing Sql --');
913    END IF;
914 
915    --Execute the dynamic sql
916    v_RowsInserted := DBMS_SQL.EXECUTE(v_CursorID);
917 
918    IF (fnd_log.level_statement >= fnd_log.g_current_runtime_level)THEN
919        fnd_log.string(fnd_log.level_statement,l_full_name,'-- After Executing Sql --');
920        fnd_log.string(fnd_log.level_statement,l_full_name,'-- v_RowsInserted --'||v_RowsInserted);
921    END IF;
922 
923    DBMS_SQL.CLOSE_CURSOR(v_CursorID);
924 
925   -- Standard check of p_commit
926   IF FND_API.TO_BOOLEAN(p_commit) THEN
927       COMMIT WORK;
928   END IF;
929 
930   -- Standard call to get message count and if count is 1, get message info
931   FND_MSG_PUB.Count_And_Get
932     ( p_count => x_msg_count,
933       p_data  => x_msg_data,
934       p_encoded => fnd_api.g_false
935     );
936 
937   IF (fnd_log.level_procedure >= fnd_log.g_current_runtime_level)THEN
938       fnd_log.string(fnd_log.level_procedure,L_FULL_NAME||'.end','At the end of PLSQL procedure');
939   END IF;
940 
941 EXCEPTION
942  WHEN FND_API.G_EXC_ERROR THEN
943    Rollback to map_position_to_instances_pvt;
944    x_return_status := FND_API.G_RET_STS_ERROR;
945    FND_MSG_PUB.count_and_get( p_count => x_msg_count,
946                               p_data  => x_msg_data,
947                               p_encoded => fnd_api.g_false);
948  WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
949    Rollback to map_position_to_instances_pvt;
950    x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
951    FND_MSG_PUB.count_and_get( p_count => x_msg_count,
952                               p_data  => x_msg_data,
953                               p_encoded => fnd_api.g_false);
954  WHEN OTHERS THEN
955    Rollback to map_position_to_instances_pvt;
956    x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
957    Fnd_Msg_Pub.add_exc_msg( p_pkg_name       => G_PKG_NAME,
958                              p_procedure_name => l_api_name,
959                              p_error_text     => SQLERRM);
960     FND_MSG_PUB.count_and_get( p_count => x_msg_count,
961                               p_data  => x_msg_data,
962                               p_encoded => fnd_api.g_false);
963 END Map_Position_To_Instances;
964 
965 -----------------------------
966 -- Start of Comments --
967 --  Procedure name    : Get_Pos_Instance
968 --  Type        : Private
969 --  Function    : Returns the instance that maps to position path
970 --  Pre-reqs    :
971 --  Parameters  :
972 --
973 --  Get_Pos_Instance Parameters:
974 --       p_position_id      IN  NUMBER  Required
975 --       p_csi_item_instance_id  IN NUMBER  Required starting instance
976 --
977 --     x_item_instance_id the instance that the position_id + instance maps to
978 --            Returns the parent instance_id if the position is empty
979 --     x_relationship_id  returns the position relationship id for empty positions
980 --     x_lowest_uc_csi_id returns the leaf level UC id
981 --      x_mapping_status OUT VARCHAR2 Returns either NA (Not applicable),
982 --         EMPTY (Empty position) or MATCH (if matching instance found)
983 --  End of Comments.
984 
985 PROCEDURE Get_Pos_Instance (
986     p_api_version         IN           NUMBER,
987     p_init_msg_list       IN           VARCHAR2  := FND_API.G_FALSE,
988     p_commit              IN           VARCHAR2  := FND_API.G_FALSE,
989     p_validation_level    IN           NUMBER    := FND_API.G_VALID_LEVEL_FULL,
990     x_return_status       OUT  NOCOPY    VARCHAR2,
991     x_msg_count           OUT  NOCOPY    NUMBER,
992     x_msg_data            OUT  NOCOPY    VARCHAR2,
993     p_position_id        IN            NUMBER,
994     p_csi_item_instance_id   IN         NUMBER,
995     x_parent_instance_id  OUT NOCOPY   NUMBER,
996     x_item_instance_id   OUT  NOCOPY    NUMBER,
997     x_relationship_id      OUT NOCOPY     NUMBER,
998     x_lowest_uc_csi_id       OUT NOCOPY     NUMBER,
999     x_mapping_status     OUT NOCOPY     VARCHAR2)
1000 IS
1001 --
1002 --Step 0) Check instance is defined in uc headers
1003 CURSOR check_instance_top_csr(p_instance_id IN NUMBER) IS
1004 SELECT 'X'
1005 FROM  AHL_UNIT_CONFIG_HEADERS uch
1006 WHERE uch.csi_item_instance_id = p_instance_id;
1007 
1008 --
1009 --Step 1) Build the path Position table object
1010 --Fetch all the position path information for given position_id
1011 CURSOR get_position_path_csr (p_position_id IN NUMBER) IS
1012 SELECT path.sequence, path.mc_id, path.version_number, path.position_key
1013 FROM  AHL_MC_PATH_POSITION_NODES path
1014 WHERE path.path_position_id = p_position_id
1015 order by sequence;
1016 
1017 --
1018 --Step 2a) Validate if the top instance matches the
1019 -- initial path position mc_id and version number (mc_header_id)
1020 CURSOR check_top_mc_csr (p_csi_ii_id IN NUMBER, p_mc_id IN NUMBER,
1021             p_ver_num IN NUMBER) IS
1022 SELECT 'X'
1023 FROM AHL_MC_HEADERS_B hdr, AHL_UNIT_CONFIG_HEADERS uch
1024 WHERE uch.csi_item_instance_id = p_csi_ii_id
1025   AND uch.master_config_id = hdr.mc_header_id
1026   AND HDR.mc_id = p_mc_id
1027   AND HDR.version_number = nvl(p_ver_num, HDR.version_number);
1028 
1029 --Step 2b) Fetch the subunit tree for given unit.
1030 CURSOR get_subunit_csi_id_csr (p_start_csi_ii_id IN NUMBER,
1031                p_parent_pos_key IN NUMBER,
1032                p_child_mc_id  IN NUMBER,
1033                p_child_mc_ver_num IN NUMBER) IS
1034 SELECT csi_instance_id
1035 FROM  AHL_UC_HEADER_PATHS_V
1036 WHERE parent_instance_id = p_start_csi_ii_id
1037 AND parent_position_key = p_parent_pos_key
1038 AND mc_id = p_child_mc_id
1039 AND mc_version_number = nvl(p_child_mc_ver_num, mc_version_number);
1040 
1041 --
1042 --Step 3a) Derive the instance that maps to unit or subunit
1043 --Fetch the final csi id given starting subunit. Could be subunit
1044 -- top node or a subnode.
1045 CURSOR get_last_csi_id_csr (p_lowest_uc_ii_id IN NUMBER,
1046                             p_position_key IN NUMBER) IS
1047 SELECT csi_ii.subject_id, csi_ii.object_id, TO_NUMBER(csi_ii.position_reference)
1048 FROM csi_ii_relationships csi_ii
1049 WHERE  TO_NUMBER(CSI_II.POSITION_REFERENCE) in (select REL.RELATIONSHIP_ID
1050                                                   from ahl_mc_relationships rel
1051                                                  where REL.position_key = p_position_key)
1052 START WITH csi_ii.object_id = p_lowest_uc_ii_id
1053     AND CSI_II.RELATIONSHIP_TYPE_CODE  = 'COMPONENT-OF'
1054     AND TRUNC(nvl(CSI_II.ACTIVE_START_DATE, sysdate)) <= TRUNC(sysdate)
1055     AND TRUNC(nvl(CSI_II.ACTIVE_END_DATE, sysdate+1)) > TRUNC(sysdate)
1056 --Jerry 03/03/2005 Added the following  condition for fixing bug 4090856
1057     AND CSI_II.POSITION_REFERENCE IS NOT NULL
1058 CONNECT BY PRIOR csi_ii.subject_id = csi_ii.object_id
1059     AND CSI_II.RELATIONSHIP_TYPE_CODE  = 'COMPONENT-OF'
1060     AND TRUNC(nvl(CSI_II.ACTIVE_START_DATE, sysdate)) <= TRUNC(sysdate)
1061     AND TRUNC(nvl(CSI_II.ACTIVE_END_DATE, sysdate+1)) > TRUNC(sysdate)
1062     AND CSI_II.POSITION_REFERENCE IS NOT NULL
1063  UNION ALL
1064 SELECT uch.csi_item_instance_id, csi_ii.object_id, TO_NUMBER(csi_ii.position_reference)
1065 FROM AHL_MC_RELATIONSHIPS rel, AHL_UNIT_CONFIG_HEADERS UCH, CSI_II_RELATIONSHIPS csi_ii
1066 WHERE  UCH.master_config_id = REL.mc_header_id
1067   AND REL.parent_relationship_id is NULL
1068   AND REL.position_key = p_position_key
1069   AND uch.csi_item_instance_id = p_lowest_uc_ii_id
1070   AND uch.csi_item_instance_id  = csi_ii.subject_id (+)
1071   AND CSI_II.RELATIONSHIP_TYPE_CODE (+) = 'COMPONENT-OF'
1072 -- Changed by jaramana on July 13, 2006 to fix FP of bug 5368714
1073 -- Make the active start date and active end date clauses also to be outer joins
1074 --  AND TRUNC(nvl(CSI_II.ACTIVE_START_DATE, sysdate)) <= TRUNC(sysdate)
1075 --  AND TRUNC(nvl(CSI_II.ACTIVE_END_DATE, sysdate+1)) > TRUNC(sysdate);
1076   AND TRUNC(nvl(CSI_II.ACTIVE_START_DATE(+), sysdate)) <= TRUNC(sysdate)
1077   AND TRUNC(nvl(CSI_II.ACTIVE_END_DATE(+), sysdate+1)) > TRUNC(sysdate);
1078 
1079 --Step 4)
1080 --Get the parent relationship information for empty node search
1081 CURSOR get_parent_poskey_csr (p_mc_id IN NUMBER,
1082                                        p_version_number IN NUMBER,
1083                                        p_position_key IN NUMBER)
1084 IS
1085 SELECT rel.relationship_id, prel.position_key
1086 FROM AHL_MC_RELATIONSHIPS rel, AHL_MC_HEADERS_B hdr, AHL_MC_RELATIONSHIPS prel
1087 WHERE prel.relationship_id = rel.parent_relationship_id
1088 AND rel.position_key = p_position_key
1089 AND hdr.mc_header_id = rel.mc_header_id
1090 AND hdr.mc_id = p_mc_id
1091 AND hdr.version_number = nvl(p_version_number, hdr.version_number)
1092 ORDER BY hdr.version_number desc;
1093 
1094 --
1095 --Step 5) Check that the path from instance to top has position key each step
1096 -- and that position key is not null for all relnships.
1097 CURSOR check_pos_ref_csr (p_csi_instance_id IN NUMBER,
1098               p_to_csi_instance_id IN NUMBER) IS
1099 SELECT 'X'
1100 FROM csi_ii_relationships csi_ii
1101 WHERE csi_ii.object_id = p_to_csi_instance_id
1102 START WITH csi_ii.subject_id = p_csi_instance_id
1103     AND CSI_II.RELATIONSHIP_TYPE_CODE  = 'COMPONENT-OF'
1104     AND TRUNC(nvl(CSI_II.ACTIVE_START_DATE, sysdate)) <= TRUNC(sysdate)
1105     AND TRUNC(nvl(CSI_II.ACTIVE_END_DATE, sysdate+1)) > TRUNC(sysdate)
1106 --Jerry 03/03/2005 Added the following  condition for fixing bug 4090856
1107     AND CSI_II.POSITION_REFERENCE IS NOT NULL
1108 CONNECT BY csi_ii.subject_id = PRIOR csi_ii.object_id
1109     AND CSI_II.RELATIONSHIP_TYPE_CODE  = 'COMPONENT-OF'
1110     AND TRUNC(nvl(CSI_II.ACTIVE_START_DATE, sysdate)) <= TRUNC(sysdate)
1111     AND TRUNC(nvl(CSI_II.ACTIVE_END_DATE, sysdate+1)) > TRUNC(sysdate)
1112     AND CSI_II.POSITION_REFERENCE IS NOT NULL;
1113 --
1114 l_api_version      CONSTANT NUMBER       := 1.0;
1115 l_api_name         CONSTANT VARCHAR2(30) := 'Get_Pos_Instance';
1116 l_csi_ii_id        NUMBER;
1117 l_index            NUMBER;
1118 l_path_tbl         AHL_MC_PATH_POSITION_PVT.Path_Position_Tbl_Type;
1119 l_path_rec         AHL_MC_PATH_POSITION_PVT.Path_Position_Rec_Type;
1120 l_dummy            VARCHAR2(1);
1121 l_dummy_id         NUMBER;
1122 l_top_flag         BOOLEAN;
1123 l_found_flag       BOOLEAN;
1124 l_child_rel_id     NUMBER;
1125 l_parent_pos_key    NUMBER;
1126 l_full_name        CONSTANT    VARCHAR2(60)    := 'ahl.plsql.' || g_pkg_name || '.' || l_api_name;
1127 
1128 --
1129 BEGIN
1130   -- Standard start of API savepoint
1131   SAVEPOINT Get_Pos_Empty_Instance_pvt;
1132 
1133   IF (fnd_log.level_procedure >= fnd_log.g_current_runtime_level)THEN
1134     fnd_log.string(fnd_log.level_procedure, l_full_name||'.begin', 'At the start of PLSQL procedure. p_csi_item_instance_id = ' || p_csi_item_instance_id ||
1135                                                                    ', p_position_id = ' || p_position_id);
1136   END IF;
1137   -- Initialize Procedure return status to success
1138   x_return_status := FND_API.G_RET_STS_SUCCESS;
1139   x_mapping_status := 'NULL';
1140 
1141   -- Standard call to check for call compatibility
1142   IF NOT FND_API.Compatible_API_Call(l_api_version, p_api_version, l_api_name,
1143                                      G_PKG_NAME) THEN
1144     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1145   END IF;
1146 
1147   -- Initialize message list if p_init_msg_list is set to TRUE
1148   IF FND_API.To_Boolean(p_init_msg_list) THEN
1149     FND_MSG_PUB.Initialize;
1150   END IF;
1151 
1152   --Step 0) Validate that p_csi_item_instance is not null and valid
1153   IF (p_csi_item_instance_id IS NULL) THEN
1154        FND_MESSAGE.Set_Name('AHL','AHL_MC_POS_INSTANCE_ID_NULL');
1155        FND_MSG_PUB.ADD;
1156        RAISE  FND_API.G_EXC_ERROR;
1157   END IF;
1158   --Validate that the input instance is a unit
1159   OPEN check_instance_top_csr (p_csi_item_instance_id);
1160   FETCH check_instance_top_csr INTO l_dummy;
1161   IF (check_instance_top_csr%NOTFOUND) THEN
1162        FND_MESSAGE.Set_Name('AHL','AHL_MC_POS_INSTANCE_ID_INV');
1163        FND_MSG_PUB.ADD;
1164        RAISE  FND_API.G_EXC_ERROR;
1165   END IF;
1166   CLOSE check_instance_top_csr;
1167 
1168   --Step 1) Build the path position table object based on path position id
1169   l_index :=0;
1170   OPEN get_position_path_csr(p_position_id);
1171   LOOP
1172       FETCH get_position_path_csr INTO l_path_rec.sequence,
1173                        l_path_rec.mc_id,
1174                        l_path_rec.version_number,
1175                        l_path_rec.position_key;
1176       EXIT WHEN get_position_path_csr%NOTFOUND;
1177       l_path_tbl(l_index):= l_path_rec;
1178       l_index := l_index +1;
1179   END LOOP;
1180   CLOSE get_position_path_csr;
1181 
1182   --Step 2) Traverse the table if there are multiple levels.
1183   -- Populate the lowest level instance id based on this query.
1184   --If table is less than 1 in size, this is invalid path
1185   IF (l_path_tbl.COUNT<1) THEN
1186        FND_MESSAGE.Set_Name('AHL','AHL_MC_POS_PATH_ID_INV');
1187        FND_MSG_PUB.ADD;
1188        RAISE  FND_API.G_EXC_ERROR;
1189 
1190   --If there is only 1 row, then lowest level UC = p_csi_instance_id
1191   ELSIF (l_path_tbl.COUNT =1) THEN
1192     OPEN check_top_mc_csr ( p_csi_item_instance_id,
1193                l_path_tbl(l_path_tbl.FIRST).mc_id,
1194                l_path_tbl(l_path_tbl.FIRST).version_number);
1195     FETCH check_top_mc_csr INTO l_dummy;
1196     IF (check_top_mc_csr%FOUND) THEN
1197        x_lowest_uc_csi_id := p_csi_item_instance_id;
1198     ELSE
1199        x_mapping_status := 'NA';
1200     END IF;
1201     CLOSE check_top_mc_csr;
1202 
1203   --If there are multiple rows, then need to verify multiple levels.
1204   ELSE
1205     l_csi_ii_id := p_csi_item_instance_id;
1206     OPEN check_top_mc_csr (l_csi_ii_id,
1207                l_path_tbl(l_path_tbl.FIRST).mc_id,
1208                l_path_tbl(l_path_tbl.FIRST).version_number);
1209     FETCH check_top_mc_csr INTO l_dummy;
1210 
1211     --If the top mc and top instance are valid match
1212     IF (check_top_mc_csr%FOUND) THEN
1213       l_found_flag := true;
1214       --Traverse down the path tree.Starting with the 1st subconfig. since
1215       -- top config is not relevant for traversal..
1216       FOR i IN l_path_tbl.FIRST+1..l_path_tbl.LAST  LOOP
1217          OPEN get_subunit_csi_id_csr(l_csi_ii_id,
1218                    l_path_tbl(i-1).position_key,
1219                    l_path_tbl(i).mc_id,
1220                    l_path_tbl(i).version_number);
1221          FETCH get_subunit_csi_id_csr INTO l_csi_ii_id;
1222          IF (get_subunit_csi_id_csr%NOTFOUND) THEN
1223              l_found_flag := false;
1224              CLOSE get_subunit_csi_id_csr;
1225              EXIT;
1226          END IF;
1227          CLOSE get_subunit_csi_id_csr;
1228       END LOOP;
1229 
1230       --If l_found_flag Meaning all MCs  are correct in traversal down MC path.
1231       IF (l_found_flag ) THEN
1232          x_lowest_uc_csi_id := l_csi_ii_id;
1233       ELSE
1234          x_mapping_status := 'NA';
1235       END IF;
1236     ELSE
1237       l_found_flag := false;
1238       x_mapping_status := 'NA';
1239     END IF;
1240     CLOSE check_top_mc_csr;
1241    END IF;
1242 
1243   --Step 3) If we are able to derive the lowest Unit
1244   IF (x_lowest_uc_csi_id IS NOT NULL
1245     AND nvl(x_mapping_status,'NULL') <>'NA') THEN
1246      --Fetch the child instance that matches
1247      OPEN get_last_csi_id_csr (x_lowest_uc_csi_id,
1248                                l_path_tbl(l_path_tbl.LAST).position_key);
1249      FETCH get_last_csi_id_csr INTO x_item_instance_id,
1250                                     x_parent_instance_id,
1251                                     x_relationship_id;
1252      IF (get_last_csi_id_csr%FOUND) THEN
1253          x_mapping_status := 'MATCH';
1254      ELSE
1255          x_mapping_status := 'EMPTY';
1256      END IF;
1257      CLOSE get_last_csi_id_csr;
1258 
1259      IF (x_mapping_status ='EMPTY') THEN
1260          --Step 4) Do the empty position parent instance + relationship_id search
1261          --For empty position try to find parent instance's position key
1262          OPEN get_parent_poskey_csr (l_path_tbl(l_path_tbl.LAST).mc_id,
1263                                              l_path_tbl(l_path_tbl.LAST).version_number,
1264                                              l_path_tbl(l_path_tbl.LAST).position_key);
1265          FETCH get_parent_poskey_csr INTO l_child_rel_id, l_parent_pos_key;
1266 
1267          --If parent instance is found, try to map it to an instance.
1268          IF (get_parent_poskey_csr%FOUND) THEN
1269             --map the parent position key to an instance in the lowest unit
1270             OPEN get_last_csi_id_csr (x_lowest_uc_csi_id, l_parent_pos_key);
1271             FETCH get_last_csi_id_csr INTO x_parent_instance_id,
1272                                            l_dummy_id,
1273                                            l_dummy_id;
1274 
1275             --Check if parent instance is found or not.
1276             IF (get_last_csi_id_csr%FOUND) THEN
1277                    x_mapping_status := 'EMPTY';
1278                    x_item_instance_id := null;
1279                    x_relationship_id := l_child_rel_id;
1280             ELSE
1281                     --Parent position has no matching instance. Position not considered empty
1282                     x_mapping_status := 'PARENT_EMPTY';
1283             END IF;
1284             CLOSE get_last_csi_id_csr;
1285 
1286          ELSE
1287                --parent position is not defined. This is not correct.
1288                x_mapping_status := 'NA';
1289          END IF;
1290          CLOSE get_parent_poskey_csr;
1291         END IF;
1292       END IF;  --If empty
1293 
1294       --Step 5) Check the position reference is valid for entire path
1295       IF (x_item_instance_id <> p_csi_item_instance_id) THEN
1296         OPEN check_pos_ref_csr (x_item_instance_id,
1297             p_csi_item_instance_id);
1298         FETCH check_pos_ref_csr INTO l_dummy;
1299         IF (check_pos_ref_csr%NOTFOUND) THEN
1300               x_item_instance_id:= null;
1301               x_mapping_status := 'NA';
1302         END IF;
1303         CLOSE check_pos_ref_csr;
1304       END IF;
1305 
1306   IF (fnd_log.level_procedure >= fnd_log.g_current_runtime_level)THEN
1307       fnd_log.string(fnd_log.level_procedure, l_full_name||'.end', 'At the end of PLSQL procedure. About to count and get error messages.');
1308   END IF;
1309   -- Standard call to get message count and if count is 1, get message info
1310   FND_MSG_PUB.Count_And_Get
1311     ( p_count => x_msg_count,
1312       p_data  => x_msg_data,
1313       p_encoded => fnd_api.g_false
1314     );
1315 EXCEPTION
1316  WHEN FND_API.G_EXC_ERROR THEN
1317    Rollback to Get_Pos_Empty_Instance_pvt;
1318    x_return_status := FND_API.G_RET_STS_ERROR;
1319    FND_MSG_PUB.count_and_get( p_count => x_msg_count,
1320                               p_data  => x_msg_data,
1321                               p_encoded => fnd_api.g_false);
1322  WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
1323    Rollback to Get_Pos_Empty_Instance_pvt;
1324    x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
1325    FND_MSG_PUB.count_and_get( p_count => x_msg_count,
1326                               p_data  => x_msg_data,
1327                               p_encoded => fnd_api.g_false);
1328  WHEN OTHERS THEN
1329    Rollback to Get_Pos_Empty_Instance_pvt;
1330    x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
1331    Fnd_Msg_Pub.add_exc_msg( p_pkg_name       => G_PKG_NAME,
1332                              p_procedure_name => l_api_name,
1333                              p_error_text     => SQLERRM);
1334     FND_MSG_PUB.count_and_get( p_count => x_msg_count,
1335                               p_data  => x_msg_data,
1336                               p_encoded => fnd_api.g_false);
1337 END Get_Pos_Instance;
1338 
1339 ----------------------------
1340 -- Start of Comments --
1341 --  Procedure name    : Get_Pos_Instance
1342 --  Type        : Private
1343 --  Function    : Returns the instance that maps to position path
1344 --  Pre-reqs    :
1345 --  Parameters  :
1346 --
1347 --  Map_Position_To_Instances Parameters:
1348 --       p_position_id      IN  NUMBER  Required
1349 --       p_csi_item_instance_id  IN NUMBER  Required starting instance
1350 --
1351 --     x_item_instance_id the instance that the position_id + instance maps to
1352 --     x_lowest_uc_csi_id returns the leaf level UC id
1353 --      x_mapping_status OUT VARCHAR2 Returns either NA (Not applicable),
1354 --         EMPTY (Empty position) or MATCH (if matching instance found)
1355 --  End of Comments.
1356 
1357 PROCEDURE Get_Pos_Instance (
1358     p_api_version         IN           NUMBER,
1359     p_init_msg_list       IN           VARCHAR2  := FND_API.G_FALSE,
1360     p_commit              IN           VARCHAR2  := FND_API.G_FALSE,
1361     p_validation_level    IN           NUMBER    := FND_API.G_VALID_LEVEL_FULL,
1362     x_return_status       OUT  NOCOPY    VARCHAR2,
1363     x_msg_count           OUT  NOCOPY    NUMBER,
1364     x_msg_data            OUT  NOCOPY    VARCHAR2,
1365     p_position_id        IN            NUMBER,
1366     p_csi_item_instance_id   IN         NUMBER,
1367     x_item_instance_id   OUT  NOCOPY    NUMBER,
1368     x_lowest_uc_csi_id       OUT NOCOPY     NUMBER,
1369     x_mapping_status     OUT  NOCOPY     VARCHAR2)
1370 IS
1371 --
1372 l_instance_id NUMBER;
1373 l_relationship_id NUMBER;
1374 l_parent_instance_id   NUMBER;
1375 --
1376 BEGIN
1377 
1378  Get_Pos_Instance (
1379         p_api_version       => 1.0,
1380         p_position_id          => p_position_id,
1381         p_csi_item_instance_id  => p_csi_item_instance_id,
1382         x_parent_instance_id   => l_parent_instance_id,
1383         x_item_instance_id     => l_instance_id,
1384         x_relationship_id     => l_relationship_id,
1385         x_lowest_uc_csi_id    => x_lowest_uc_csi_id,
1386         x_mapping_status      => x_mapping_status,
1387         x_return_status       => x_return_status,
1388         x_msg_count           => x_msg_count,
1389         x_msg_data            => x_msg_data);
1390 
1391   --Remaps the instance to null or no match
1392   IF (x_mapping_status <> 'MATCH') THEN
1393     x_item_instance_id := null;
1394 
1395     --Remap the PARENT_EMPTY status to NA. Bad code due to need of extra type in
1396     --overloaded Get_Pos_Instance method
1397     IF (x_mapping_status = 'PARENT_EMPTY') THEN
1398       x_mapping_status := 'NA';
1399     END IF;
1400   ELSE
1401     x_item_instance_id := l_instance_id;
1402   END IF;
1403 
1404 END Get_Pos_Instance;
1405 
1406 
1407 
1408 -----------------------------
1409 -- Start of Comments --
1410 --  Procedure name    : Copy_Positions_For_MC
1411 --  Type        : Private
1412 --  Function    : Copies all path positions for 1 MC to another MC
1413 --  Pre-reqs    :
1414 --  Parameters  :
1415 --
1416 --  Copy_Positions_For_MC Parameters:
1417 --       p_from_mc_header_id      IN  NUMBER  Required
1418 --   p_to_mc_header_id    IN NUMBER   Required
1419 --
1420 --  End of Comments.
1421 
1422 PROCEDURE Copy_Positions_For_MC (
1423     p_api_version         IN           NUMBER,
1424     p_init_msg_list       IN           VARCHAR2  := FND_API.G_FALSE,
1425     p_commit              IN           VARCHAR2  := FND_API.G_FALSE,
1426     p_validation_level    IN           NUMBER    := FND_API.G_VALID_LEVEL_FULL,
1427     x_return_status       OUT  NOCOPY    VARCHAR2,
1428     x_msg_count           OUT  NOCOPY    NUMBER,
1429     x_msg_data            OUT  NOCOPY    VARCHAR2,
1430     p_from_mc_header_id       IN           NUMBER,
1431     p_to_mc_header_id         IN           NUMBER)
1432 IS
1433 --
1434 CURSOR check_mc_status_csr (p_header_id  IN  NUMBER) IS
1435    SELECT  header.config_status_code, header.config_status_meaning
1436      FROM    ahl_mc_headers_v header
1437      WHERE  header.mc_header_id = p_header_id;
1438 --
1439 CURSOR get_mc_id_csr (p_mc_header_id  IN  NUMBER) IS
1440    SELECT  mc_id
1441      FROM    ahl_mc_headers_b
1442      WHERE  mc_header_id = p_mc_header_id;
1443 --
1444 CURSOR get_ver_position_ids_csr (p_header_id  IN  NUMBER) IS
1445    SELECT  pnodes.path_position_id
1446      FROM   ahl_mc_path_position_nodes pnodes, ahl_mc_headers_b hdr
1447      WHERE  pnodes.sequence = 0
1448      AND    pnodes.mc_id = hdr.mc_id
1449      AND    pnodes.version_number = hdr.version_number
1450      AND    hdr.mc_header_id = p_header_id;
1451 --
1452 CURSOR get_nover_position_ids_csr(p_header_id IN NUMBER) IS
1453    SELECT  pnodes.path_position_id
1454      FROM   ahl_mc_path_position_nodes pnodes, ahl_mc_headers_b hdr
1455      WHERE  pnodes.sequence = 0
1456      AND    pnodes.mc_id = hdr.mc_id
1457      AND    pnodes.version_number IS NULL
1458      AND    hdr.mc_header_id = p_header_id;
1459 --
1460 l_api_version      CONSTANT NUMBER       := 1.0;
1461 l_api_name         CONSTANT VARCHAR2(30) := 'Copy_Positions_For_Mc';
1462 l_from_mc_id       NUMBER;
1463 l_to_mc_id         NUMBER;
1464 l_status_code      VARCHAR2(30);
1465 l_status           VARCHAR2(80);
1466 l_position_id      NUMBER;
1467 l_new_position_id  NUMBER;
1468 l_msg_count        NUMBER;
1469 --
1470 BEGIN
1471   -- Standard start of API savepoint
1472   SAVEPOINT Copy_Positions_For_Mc_pvt;
1473 
1474   -- Initialize Procedure return status to success
1475   x_return_status := FND_API.G_RET_STS_SUCCESS;
1476   -- Standard call to check for call compatibility
1477   IF NOT FND_API.Compatible_API_Call(l_api_version, p_api_version, l_api_name,
1478                                      G_PKG_NAME) THEN
1479     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1480   END IF;
1481 
1482   -- Initialize message list if p_init_msg_list is set to TRUE
1483   IF FND_API.To_Boolean(p_init_msg_list) THEN
1484     FND_MSG_PUB.Initialize;
1485   END IF;
1486 
1487   --Check Status of MC allows for editing
1488   OPEN check_mc_status_csr(p_to_mc_header_id);
1489   FETCH check_mc_status_csr INTO l_status_code, l_status;
1490   IF (check_mc_status_csr%NOTFOUND) THEN
1491        FND_MESSAGE.Set_Name('AHL','AHL_UC_MC_HEADER_ID_INVALID');
1492        FND_MESSAGE.Set_Token('MC_HEADER_ID',p_to_mc_header_id);
1493        FND_MSG_PUB.ADD;
1494        CLOSE check_mc_status_csr;
1495        RAISE  FND_API.G_EXC_ERROR;
1496   ELSIF ( l_status_code <> 'DRAFT' AND
1497       l_status_code <> 'APPROVAL_REJECTED') THEN
1498        FND_MESSAGE.Set_Name('AHL','AHL_MC_EDIT_INV_MC');
1499        FND_MESSAGE.Set_Token('STATUS', l_status);
1500        FND_MSG_PUB.ADD;
1501        CLOSE check_mc_status_csr;
1502        RAISE  FND_API.G_EXC_ERROR;
1503   END IF;
1504   CLOSE check_mc_status_csr;
1505 
1506   --Copy all version specific paths
1507   OPEN get_ver_position_ids_csr(p_from_mc_header_id);
1508   LOOP
1509      FETCH get_ver_position_ids_csr INTO l_position_id;
1510      EXIT WHEN get_ver_position_ids_csr%NOTFOUND;
1511 
1512      Copy_Position (
1513             p_api_version       => 1.0,
1514         p_commit            => FND_API.G_FALSE,
1515             p_position_id       =>   l_position_id,
1516             p_to_mc_header_id   => p_to_mc_header_id,
1517             x_position_id       => l_new_position_id,
1518         x_return_status       => x_return_status,
1519                 x_msg_count           => x_msg_count,
1520                 x_msg_data            => x_msg_data);
1521     -- Check return status.
1522     IF x_return_status = FND_API.G_RET_STS_ERROR THEN
1523       RAISE FND_API.G_EXC_ERROR;
1524     ELSIF x_return_status = FND_API.G_RET_STS_UNEXP_ERROR THEN
1525       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1526     END IF;
1527   END LOOP;
1528   CLOSE get_ver_position_ids_csr;
1529 
1530   OPEN get_mc_id_csr(p_to_mc_header_id);
1531   FETCH get_mc_id_csr INTO l_to_mc_id;
1532   CLOSE get_mc_id_csr;
1533 
1534   OPEN get_mc_id_csr(p_from_mc_header_id);
1535   FETCH get_mc_id_csr INTO l_from_mc_id;
1536   CLOSE get_mc_id_csr;
1537 
1538   IF (l_to_mc_id <> l_from_mc_id) THEN
1539     --Copy the non version specific paths as well
1540     OPEN get_nover_position_ids_csr(p_from_mc_header_id);
1541     LOOP
1542        FETCH get_nover_position_ids_csr INTO l_position_id;
1543        EXIT WHEN get_nover_position_ids_csr%NOTFOUND;
1544 
1545        Copy_Position (
1546             p_api_version       => 1.0,
1547         p_commit            => FND_API.G_FALSE,
1548             p_position_id       =>   l_position_id,
1549             p_to_mc_header_id   => p_to_mc_header_id,
1550             x_position_id       => l_new_position_id,
1551         x_return_status       => x_return_status,
1552                 x_msg_count           => x_msg_count,
1553                 x_msg_data            => x_msg_data);
1554      -- Check return status.
1555      IF x_return_status = FND_API.G_RET_STS_ERROR THEN
1556        RAISE FND_API.G_EXC_ERROR;
1557      ELSIF x_return_status = FND_API.G_RET_STS_UNEXP_ERROR THEN
1558        RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1559      END IF;
1560    END LOOP;
1561    CLOSE get_nover_position_ids_csr;
1562   END IF;
1563 
1564    -- Check return status.
1565   IF x_return_status = FND_API.G_RET_STS_ERROR THEN
1566     RAISE FND_API.G_EXC_ERROR;
1567   ELSIF x_return_status = FND_API.G_RET_STS_UNEXP_ERROR THEN
1568     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1569   END IF;
1570 
1571 
1572   -- Standard check of p_commit
1573   IF FND_API.TO_BOOLEAN(p_commit) THEN
1574       COMMIT WORK;
1575   END IF;
1576   -- Standard call to get message count and if count is 1, get message info
1577   FND_MSG_PUB.Count_And_Get
1578     ( p_count => x_msg_count,
1579       p_data  => x_msg_data,
1580       p_encoded => fnd_api.g_false
1581     );
1582 EXCEPTION
1583  WHEN FND_API.G_EXC_ERROR THEN
1584    Rollback to Copy_Positions_For_Mc_pvt;
1585    x_return_status := FND_API.G_RET_STS_ERROR;
1586    FND_MSG_PUB.count_and_get( p_count => x_msg_count,
1587                               p_data  => x_msg_data,
1588                               p_encoded => fnd_api.g_false);
1589  WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
1590    Rollback to Copy_Positions_For_Mc_pvt;
1591    x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
1592    FND_MSG_PUB.count_and_get( p_count => x_msg_count,
1593                               p_data  => x_msg_data,
1594                               p_encoded => fnd_api.g_false);
1595  WHEN OTHERS THEN
1596    Rollback to Copy_Positions_For_Mc_pvt;
1597    x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
1598    Fnd_Msg_Pub.add_exc_msg( p_pkg_name       => G_PKG_NAME,
1599                              p_procedure_name => l_api_name,
1600                              p_error_text     => SQLERRM);
1601     FND_MSG_PUB.count_and_get( p_count => x_msg_count,
1602                               p_data  => x_msg_data,
1603                               p_encoded => fnd_api.g_false);
1604 END Copy_Positions_For_MC;
1605 
1606 -----------------------------
1607 -- Start of Comments --
1608 --  Procedure name    : Copy_Position
1609 --  Type        : Private
1610 --  Function    : Copies 1 path positions to 1 MC
1611 --  Pre-reqs    :
1612 --  Parameters  :
1613 --
1614 --  Copy_Position
1615 --       p_position_id      IN  NUMBER  Required
1616 --   p_to_mc_header_id    IN NUMBER   Required
1617 --   x_positioN_id       OUT NUMBER
1618 --
1619 --  End of Comments.
1620 
1621 PROCEDURE Copy_Position (
1622     p_api_version         IN           NUMBER,
1623     p_init_msg_list       IN           VARCHAR2  := FND_API.G_FALSE,
1624     p_commit              IN           VARCHAR2  := FND_API.G_FALSE,
1625     p_validation_level    IN           NUMBER    := FND_API.G_VALID_LEVEL_FULL,
1626     x_return_status       OUT  NOCOPY    VARCHAR2,
1627     x_msg_count           OUT  NOCOPY    NUMBER,
1628     x_msg_data            OUT  NOCOPY    VARCHAR2,
1629     p_position_id         IN           NUMBER,
1630     p_to_mc_header_id         IN           NUMBER,
1631     x_position_id         OUT  NOCOPY    NUMBER)
1632 IS
1633 --
1634 CURSOR get_mc_id_ver_csr (p_mc_header_id  IN  NUMBER) IS
1635    SELECT  mc_id, version_number
1636      FROM    ahl_mc_headers_b
1637      WHERE  mc_header_id = p_mc_header_id;
1638 --
1639 CURSOR get_mc_path_position_nodes_csr (p_position_id  IN  NUMBER) IS
1640    SELECT  *
1641      FROM   ahl_mc_path_position_nodes
1642     WHERE  path_position_id = p_position_id
1643      order by sequence;
1644 --
1645 CURSOR get_path_position_ref_csr (p_position_id  IN  NUMBER) IS
1646    SELECT  position_ref_code
1647      FROM   ahl_mc_path_positions
1648     WHERE  path_position_id = p_position_id;
1649 --
1650 l_api_version      CONSTANT NUMBER       := 1.0;
1651 l_api_name         CONSTANT VARCHAR2(30) := 'Copy_Position';
1652 l_position_node    get_mc_path_position_nodes_csr%ROWTYPE;
1653 l_pos_tbl          AHL_MC_PATH_POSITION_PVT.Path_Position_Tbl_Type;
1654 l_pos_rec          AHL_MC_PATH_POSITION_PVT.Path_Position_Rec_Type;
1655 l_mc_id            NUMBER;
1656 l_version_number   NUMBER;
1657 l_pos_ref_code     VARCHAR2(30);
1658 l_index       NUMBER;
1659 l_return_status  VARCHAR2(1);
1660 l_msg_count      NUMBER;
1661 l_msg_data       varchar2(2000);
1662 --
1663 BEGIN
1664   -- Standard start of API savepoint
1665   SAVEPOINT Copy_Position_pvt;
1666 
1667   -- Initialize Procedure return status to success
1668   x_return_status := FND_API.G_RET_STS_SUCCESS;
1669   -- Standard call to check for call compatibility
1670   IF NOT FND_API.Compatible_API_Call(l_api_version, p_api_version, l_api_name,
1671                                      G_PKG_NAME) THEN
1672     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1673   END IF;
1674 
1675   -- Initialize message list if p_init_msg_list is set to TRUE
1676   IF FND_API.To_Boolean(p_init_msg_list) THEN
1677     FND_MSG_PUB.Initialize;
1678   END IF;
1679 
1680   --Fetch the to mc_header_id information
1681   OPEN get_mc_id_ver_csr(p_to_mc_header_id);
1682   FETCH get_mc_id_ver_csr INTO l_mc_id, l_version_number;
1683   IF (get_mc_id_ver_csr%NOTFOUND) THEN
1684        FND_MESSAGE.Set_Name('AHL','AHL_MC_HEADER_ID_INVALID');
1685        FND_MESSAGE.Set_Token('NAME','');
1686        FND_MESSAGE.Set_Token('MC_HEADER_ID',p_to_mc_header_id);
1687        FND_MSG_PUB.ADD;
1688        CLOSE get_mc_id_ver_csr;
1689        RAISE  FND_API.G_EXC_ERROR;
1690   END IF;
1691   CLOSE get_mc_id_ver_csr;
1692 
1693   --Fetch the position path information
1694   l_index:=0;
1695   OPEN get_mc_path_position_nodes_csr(p_position_id);
1696   LOOP
1697      FETCH get_mc_path_position_nodes_csr INTO l_position_node;
1698      EXIT WHEN get_mc_path_position_nodes_csr%NOTFOUND;
1699 
1700      --Copy to our table record
1701      IF (l_position_node.sequence = 0) THEN
1702     l_pos_rec.mc_id := l_mc_id;
1703         IF (l_position_node.version_number IS NOT NULL) THEN
1704           l_pos_rec.version_number := l_version_number;
1705     ELSE
1706           l_pos_rec.version_number := NULL;
1707         END IF;
1708      ELSE
1709         l_pos_rec.mc_id := l_position_node.mc_id;
1710         l_pos_rec.version_number := l_position_node.version_number  ;
1711      END IF;
1712 
1713      l_pos_rec.position_key := l_position_node.position_key  ;
1714      l_pos_rec.attribute_category  := l_position_node.attribute_category  ;
1715      l_pos_rec.attribute1  := l_position_node.attribute1  ;
1716      l_pos_rec.attribute2  := l_position_node.attribute2  ;
1717      l_pos_rec.attribute3  := l_position_node.attribute3  ;
1718      l_pos_rec.attribute4  := l_position_node.attribute4  ;
1719      l_pos_rec.attribute5  := l_position_node.attribute5  ;
1720      l_pos_rec.attribute6  := l_position_node.attribute6  ;
1721      l_pos_rec.attribute7  := l_position_node.attribute7  ;
1722      l_pos_rec.attribute8  := l_position_node.attribute8  ;
1723      l_pos_rec.attribute9  := l_position_node.attribute9  ;
1724      l_pos_rec.attribute10  := l_position_node.attribute10  ;
1725      l_pos_rec.attribute11  := l_position_node.attribute11  ;
1726      l_pos_rec.attribute12  := l_position_node.attribute12  ;
1727      l_pos_rec.attribute13  := l_position_node.attribute13  ;
1728      l_pos_rec.attribute14  := l_position_node.attribute14  ;
1729      l_pos_rec.attribute15 := l_position_node.attribute15  ;
1730      l_pos_tbl(l_index) := l_pos_rec;
1731      l_index:= l_index+1;
1732 
1733   END LOOP;
1734   CLOSE get_mc_path_position_nodes_csr;
1735 
1736   OPEN get_path_position_ref_csr(p_position_id);
1737   FETCH get_path_position_ref_csr INTO l_pos_ref_code;
1738   CLOSE get_path_position_ref_csr;
1739 
1740   -- Check Error Message stack.
1741   x_msg_count := FND_MSG_PUB.count_msg;
1742   IF x_msg_count > 0 THEN
1743     RAISE  FND_API.G_EXC_ERROR;
1744   END IF;
1745 
1746   --Create position with new error message stack.
1747   --This stack will not be useful
1748   Create_Position_ID (
1749             p_api_version       => 1.0,
1750                 p_init_msg_list     => FND_API.G_TRUE,
1751         p_commit            => FND_API.G_FALSE,
1752             p_path_position_tbl     =>   l_pos_tbl,
1753             p_position_ref_meaning  => FND_API.G_MISS_CHAR,
1754             p_position_ref_code    => l_pos_ref_code,
1755         x_position_id         => x_position_id,
1756         x_return_status       => l_return_status,
1757                 x_msg_count           => l_msg_count,
1758                 x_msg_data            => l_msg_data);
1759 
1760   -- Suppress the validation errors from Create API.
1761   IF (l_return_status = FND_API.G_RET_STS_ERROR) THEN
1762     --Suppress the expected errors
1763     --Clean out the messages
1764     FND_MSG_PUB.Initialize;
1765     x_position_id := null;
1766     x_return_status := FND_API.G_RET_STS_SUCCESS;
1767     x_msg_count := 0;
1768     x_msg_data := null;
1769   ELSE
1770    --Use normal error handling
1771    x_return_status := l_return_status;
1772    x_msg_count := l_msg_count;
1773    x_msg_data := l_msg_data;
1774   END IF;
1775 
1776   -- Check return status.
1777   IF x_return_status = FND_API.G_RET_STS_ERROR THEN
1778     RAISE FND_API.G_EXC_ERROR;
1779   ELSIF x_return_status = FND_API.G_RET_STS_UNEXP_ERROR THEN
1780     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1781   END IF;
1782 
1783   -- Standard check of p_commit
1784   IF FND_API.TO_BOOLEAN(p_commit) THEN
1785       COMMIT WORK;
1786   END IF;
1787 
1788   -- Standard call to get message count and if count is 1, get message info
1789   FND_MSG_PUB.Count_And_Get
1790     ( p_count => x_msg_count,
1791       p_data  => x_msg_data,
1792       p_encoded => fnd_api.g_false
1793     );
1794 EXCEPTION
1795  WHEN FND_API.G_EXC_ERROR THEN
1796    Rollback to Copy_Position_pvt;
1797    x_return_status := FND_API.G_RET_STS_ERROR;
1798    FND_MSG_PUB.count_and_get( p_count => x_msg_count,
1799                               p_data  => x_msg_data,
1800                               p_encoded => fnd_api.g_false);
1801  WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
1802    Rollback to Copy_Position_pvt;
1803    x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
1804    FND_MSG_PUB.count_and_get( p_count => x_msg_count,
1805                               p_data  => x_msg_data,
1806                               p_encoded => fnd_api.g_false);
1807  WHEN OTHERS THEN
1808    Rollback to Copy_Position_pvt;
1809    x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
1810    Fnd_Msg_Pub.add_exc_msg( p_pkg_name       => G_PKG_NAME,
1811                              p_procedure_name => l_api_name,
1812                              p_error_text     => SQLERRM);
1813     FND_MSG_PUB.count_and_get( p_count => x_msg_count,
1814                               p_data  => x_msg_data,
1815                               p_encoded => fnd_api.g_false);
1816 END Copy_Position;
1817 
1818 -----------------------------
1819 -- Start of Comments --
1820 --  Procedure name    : Delete_Positions_For_MC
1821 --  Type        : Private
1822 --  Function    : Deletes the Positions corresponding to 1 MC
1823 --  Pre-reqs    :
1824 --  Parameters  :
1825 --
1826 --  Delete_Positions_For_MC Parameters:
1827 --       p_mc_header_id      IN  NUMBER  Required
1828 --
1829 --  End of Comments.
1830 
1831 PROCEDURE Delete_Positions_For_MC (
1832     p_api_version         IN           NUMBER,
1833     p_init_msg_list       IN           VARCHAR2  := FND_API.G_FALSE,
1834     p_commit              IN           VARCHAR2  := FND_API.G_FALSE,
1835     p_validation_level    IN           NUMBER    := FND_API.G_VALID_LEVEL_FULL,
1836     x_return_status       OUT  NOCOPY    VARCHAR2,
1837     x_msg_count           OUT  NOCOPY    NUMBER,
1838     x_msg_data            OUT  NOCOPY    VARCHAR2,
1839   p_mc_header_id      IN           NUMBER)
1840 IS
1841 --
1842 CURSOR check_mc_status_csr (p_header_id  IN  NUMBER) IS
1843    SELECT  config_status_code, config_status_meaning
1844      FROM    ahl_mc_headers_v header
1845      WHERE  header.mc_header_id = p_header_id;
1846 --
1847 CURSOR get_num_of_version_csr (p_header_id  IN  NUMBER) IS
1848    SELECT  count(*)
1849      FROM    ahl_mc_headers_b header
1850      WHERE  header.mc_id = (select mc_id FROM ahl_mc_headers_b
1851     where mc_header_id = p_header_id);
1852 --
1853 --Fetch all version specific path positions
1854 CURSOR get_ver_position_ids_csr (p_mc_header_id IN NUMBER) IS
1855 SELECT path.path_position_id
1856 FROM  AHL_MC_PATH_POSITION_NODES path, AHL_MC_HEADERS_B headers
1857 WHERE path.MC_ID = headers.mc_id
1858 AND  path.sequence = 0
1859 AND  path.version_number = headers.version_number
1860 AND  headers.mc_header_id = p_mc_header_id;
1861 --
1862 --Fetch all non-version specific path positions
1863 CURSOR get_nover_position_ids_csr (p_mc_header_id IN NUMBER) IS
1864 SELECT path.path_position_id
1865 FROM  AHL_MC_PATH_POSITION_NODES path, AHL_MC_HEADERS_B headers
1866 WHERE path.MC_ID = headers.mc_id
1867 AND  path.sequence = 0
1868 AND  path.version_number IS NULL
1869 AND  headers.mc_header_id = p_mc_header_id;
1870 --
1871 --Fetch all version specific path positions
1872 CURSOR check_posid_in_rstmts_csr (p_position_id IN NUMBER) IS
1873 SELECT 'X'
1874 FROM  AHL_MC_RULE_STATEMENTS
1875 WHERE (subject_ID = p_position_id
1876 AND  subject_type = 'POSITION')
1877 OR (object_id = p_position_id
1878  AND (object_type = 'ITEM_AS_POSITION'
1879     OR object_type = 'CONFIG_AS_POSITION'));
1880 --
1881 --
1882 l_api_version      CONSTANT NUMBER       := 1.0;
1883 l_api_name         CONSTANT VARCHAR2(30) := 'Delete_Positions_For_Mc';
1884 l_position_id      NUMBER;
1885 l_junk         VARCHAR2(1);
1886 l_status_code      VARCHAR2(30);
1887 l_status           VARCHAR2(80);
1888 l_num_of_version  NUMBER;
1889 --
1890 BEGIN
1891   -- Standard start of API savepoint
1892   SAVEPOINT Delete_Positions_For_Mc_pvt;
1893 
1894   -- Initialize Procedure return status to success
1895   x_return_status := FND_API.G_RET_STS_SUCCESS;
1896   -- Standard call to check for call compatibility
1897   IF NOT FND_API.Compatible_API_Call(l_api_version, p_api_version, l_api_name,
1898                                      G_PKG_NAME) THEN
1899     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1900   END IF;
1901 
1902   -- Initialize message list if p_init_msg_list is set to TRUE
1903   IF FND_API.To_Boolean(p_init_msg_list) THEN
1904     FND_MSG_PUB.Initialize;
1905   END IF;
1906 
1907    --Check Status of MC allows for editing
1908   OPEN check_mc_status_csr(p_mc_header_id);
1909   FETCH check_mc_status_csr INTO l_status_code, l_status;
1910   IF (check_mc_status_csr%NOTFOUND) THEN
1911        FND_MESSAGE.Set_Name('AHL','AHL_MC_HEADER_ID_INVALID');
1912        FND_MESSAGE.Set_Token('NAME','');
1913        FND_MESSAGE.Set_Token('MC_HEADER_ID',p_mc_header_id);
1914        FND_MSG_PUB.ADD;
1915        CLOSE check_mc_status_csr;
1916        RAISE  FND_API.G_EXC_ERROR;
1917   ELSIF ( l_status_code <> 'DRAFT' AND
1918       l_status_code <> 'APPROVAL_REJECTED') THEN
1919        FND_MESSAGE.Set_Name('AHL','AHL_MC_EDIT_INV_MC');
1920        FND_MESSAGE.Set_Token('STATUS', l_status);
1921        FND_MSG_PUB.ADD;
1922        CLOSE check_mc_status_csr;
1923        RAISE  FND_API.G_EXC_ERROR;
1924   END IF;
1925   CLOSE check_mc_status_csr;
1926 
1927   --Delete version specific positions
1928   OPEN get_ver_position_ids_csr(p_mc_header_id);
1929   LOOP
1930      FETCH get_ver_position_ids_csr INTO l_position_id;
1931      EXIT WHEN get_ver_position_ids_csr%NOTFOUND;
1932 
1933      --Validate position_id is not used in other tables.
1934      --Only need to validate MC rules since other paths are only in
1935      -- complete MCs, which can not delete position paths or rules.
1936      OPEN check_posid_in_rstmts_csr(l_position_id);
1937      FETCH check_posid_in_rstmts_csr INTO l_junk;
1938      IF (check_posid_in_rstmts_csr%NOTFOUND) THEN
1939 
1940       --Delete the position_id
1941       DELETE FROM AHL_MC_PATH_POSITION_NODES
1942        WHERE path_position_id = l_position_id;
1943 
1944       DELETE FROM AHL_MC_PATH_POSITIONS
1945        WHERE path_position_id = l_position_id;
1946      END IF;
1947      CLOSE check_posid_in_rstmts_csr;
1948 
1949   END LOOP;
1950   CLOSE get_ver_position_ids_csr;
1951 
1952   --Delete non-version specific positions
1953   OPEN get_num_of_version_csr(p_mc_header_id);
1954   FETCH get_num_of_version_csr INTO l_num_of_version;
1955   CLOSE get_num_of_version_csr;
1956 
1957   IF (l_num_of_version = 1) THEN
1958    OPEN get_nover_position_ids_csr(p_mc_header_id);
1959    LOOP
1960      FETCH get_nover_position_ids_csr INTO l_position_id;
1961      EXIT WHEN get_nover_position_ids_csr%NOTFOUND;
1962 
1963      --Validate position_id is not used in other tables.
1964      --Only need to validate MC rules since other paths are only in
1965      -- complete MCs, which can not delete position paths or rules.
1966      OPEN check_posid_in_rstmts_csr(l_position_id);
1967      FETCH check_posid_in_rstmts_csr INTO l_junk;
1968      IF (check_posid_in_rstmts_csr%NOTFOUND) THEN
1969 
1970        --Delete the position_id
1971        DELETE FROM AHL_MC_PATH_POSITION_NODES
1972         WHERE path_position_id = l_position_id;
1973 
1974        DELETE FROM AHL_MC_PATH_POSITIONS
1975         WHERE path_position_id = l_position_id;
1976 
1977      END IF;
1978      CLOSE check_posid_in_rstmts_csr;
1979 
1980    END LOOP;
1981    CLOSE get_nover_position_ids_csr;
1982   END IF;
1983 
1984   -- Standard check of p_commit
1985   IF FND_API.TO_BOOLEAN(p_commit) THEN
1986       COMMIT WORK;
1987   END IF;
1988   -- Standard call to get message count and if count is 1, get message info
1989   FND_MSG_PUB.Count_And_Get
1990     ( p_count => x_msg_count,
1991       p_data  => x_msg_data,
1992       p_encoded => fnd_api.g_false
1993     );
1994 EXCEPTION
1995  WHEN FND_API.G_EXC_ERROR THEN
1996    Rollback to Delete_Positions_For_Mc_pvt;
1997    x_return_status := FND_API.G_RET_STS_ERROR;
1998    FND_MSG_PUB.count_and_get( p_count => x_msg_count,
1999                               p_data  => x_msg_data,
2000                               p_encoded => fnd_api.g_false);
2001  WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
2002    Rollback to Delete_Positions_For_Mc_pvt;
2003    x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
2004    FND_MSG_PUB.count_and_get( p_count => x_msg_count,
2005                               p_data  => x_msg_data,
2006                               p_encoded => fnd_api.g_false);
2007  WHEN OTHERS THEN
2008    Rollback to Delete_Positions_For_Mc_pvt;
2009    x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
2010    Fnd_Msg_Pub.add_exc_msg( p_pkg_name       => G_PKG_NAME,
2011                              p_procedure_name => l_api_name,
2012                              p_error_text     => SQLERRM);
2013     FND_MSG_PUB.count_and_get( p_count => x_msg_count,
2014                               p_data  => x_msg_data,
2015                               p_encoded => fnd_api.g_false);
2016 END Delete_Positions_For_MC;
2017 
2018 
2019 ---------------------------------------------------------------------
2020 -- Start of Comments --
2021 --  Function name: get_posref_by_id
2022 --  Type        : Private
2023 --  Function    : Fetches the position path position ref code
2024 --  Pre-reqs    :
2025 --  Parameters  :
2026 --
2027 --  get_position_ref_code Parameters:
2028 --       p_position_id IN NUMBER the path position id
2029 --       p_code_flag IN VARHCAR2 If Equal to FND_API.G_TRUE, then return
2030 -- pos ref code, else return pos ref meaning. Default to False.
2031 --
2032 FUNCTION get_posref_by_id(
2033    p_path_position_ID    IN  NUMBER,
2034    p_code_flag           IN  VARCHAR2 := FND_API.G_FALSE)
2035 RETURN VARCHAR2  -- Position Ref Code or Meaning
2036 IS
2037 --
2038 CURSOR get_pos_ref_csr (p_position_id IN NUMBER) IS
2039 SELECT position_ref_code
2040 FROM  AHL_MC_PATH_POSITIONS
2041 WHERE path_position_id = p_position_id;
2042 --
2043 --Select the default position reference.
2044 CURSOR get_def_pos_ref_csr (p_position_id IN NUMBER) IS
2045 SELECT rel.position_ref_code
2046 FROM  AHL_MC_HEADERS_B hd, AHL_MC_RELATIONSHIPS rel,
2047       AHL_MC_PATH_POSITION_NODES pnodes
2048 WHERE hd.mc_header_id = rel.mc_header_id
2049 AND  rel.position_key = pnodes.position_key
2050 AND  hd.mc_id = pnodes.mc_id
2051 AND pnodes.sequence = (SELECT MAX(sequence) FROM AHL_MC_PATH_POSITION_NODES
2052 WHERE path_position_id = p_position_id)
2053 AND pnodes.path_position_id = p_position_id
2054 order by hd.version_number desc;
2055 --
2056 l_pos_ref_code    VARCHAR2(30);
2057 l_pos_ref_meaning VARCHAR2(80);
2058 l_return_val      BOOLEAN;
2059 --
2060 BEGIN
2061 
2062    OPEN get_pos_ref_csr(p_path_position_ID);
2063    FETCH get_pos_ref_csr INTO l_pos_ref_code;
2064 
2065    --If there are no pos ref defined for path
2066    IF (l_pos_ref_code IS NULL) OR
2067       (l_pos_ref_code = FND_API.G_MISS_CHAR)  THEN
2068       OPEN get_def_pos_ref_csr(p_path_position_ID);
2069       FETCH get_def_pos_ref_csr INTO l_pos_ref_code;
2070       CLOSE get_def_pos_ref_csr;
2071    END IF;
2072    CLOSE get_pos_ref_csr;
2073 
2074    IF (p_code_flag = FND_API.G_TRUE) THEN
2075        RETURN l_pos_ref_code;
2076    ELSE
2077      --Convert to meaning.
2078      AHL_UTIL_MC_PKG.Convert_To_LookupMeaning('AHL_POSITION_REFERENCE',
2079                                            l_pos_ref_code,
2080                                            l_pos_ref_meaning,
2081                                            l_return_val);
2082 
2083      Return l_pos_ref_meaning;
2084    END IF;
2085 END Get_Posref_By_ID;
2086 
2087 ---------------------------------------------------------------------
2088 -- Start of Comments --
2089 --  Function name: get_posref_by_path
2090 --  Type        : Private
2091 --  Function    : Fetches the position path position ref code
2092 --  Pre-reqs    :
2093 --  Parameters  :
2094 --
2095 --  get_position_ref_code Parameters:
2096 --       p_position_path_tbl IN AHL_MC_PATH_POSITION_PVT.Path_Position_Tbl_Type Required
2097 --       p_code_flag IN VARHCAR2 If Equal to FND_API.G_TRUE, then return
2098 -- pos ref code, else return pos ref meaning. Default to False.
2099 --
2100 FUNCTION get_posref_by_path(
2101    p_path_position_tbl   IN AHL_MC_PATH_POSITION_PVT.Path_Position_Tbl_Type,
2102    p_code_flag           IN VARCHAR2 := FND_API.G_FALSE
2103 )
2104 RETURN VARCHAR2  -- Position Ref Meaning/Code
2105 IS
2106 --
2107 CURSOR get_path_pos_ref_csr (p_encoded_path IN VARCHAR2) IS
2108 SELECT position_ref_code
2109 FROM  AHL_MC_PATH_POSITIONS
2110 WHERE encoded_path_position = p_encoded_path;
2111 --
2112 --Select the default position reference.
2113 CURSOR get_def_path_pos_ref_csr (p_mc_id IN NUMBER,
2114             p_version_number IN NUMBER,
2115             p_position_key IN NUMBER) IS
2116 SELECT rel.position_ref_code
2117 FROM  AHL_MC_HEADERS_B hd, AHL_MC_RELATIONSHIPS rel
2118 WHERE rel.position_key = p_position_key
2119 AND   hd.mc_header_id = rel.mc_header_id
2120 AND  hd.mc_id = p_mc_id
2121 AND  hd.version_number = nvl(p_version_number, hd.version_number)
2122 order by hd.version_number desc;
2123 --
2124 l_pos_ref_code    VARCHAR2(30);
2125 l_pos_ref_meaning VARCHAR2(80);
2126 l_pos_tbl         AHL_MC_PATH_POSITION_PVT.Path_Position_Tbl_Type;
2127 l_encoded_path     AHL_MC_PATH_POSITIONS.ENCODED_PATH_POSITION%TYPE;
2128 l_return_val      BOOLEAN;
2129 --
2130 BEGIN
2131    --Remove the version numbers if any.
2132    FOR i IN p_path_position_tbl.FIRST..p_path_position_tbl.LAST  LOOP
2133       l_pos_tbl(i) := p_path_position_tbl(i);
2134       l_pos_tbl(i).version_number := NULL;
2135    END LOOP;
2136 
2137     --Encode the path_position_tbl
2138    l_encoded_path := Encode(l_pos_tbl);
2139 
2140    OPEN get_path_pos_ref_csr(l_encoded_path);
2141    FETCH get_path_pos_ref_csr INTO l_pos_ref_code;
2142 
2143    --If there are no pos ref defined for path
2144    IF (l_pos_ref_code IS NULL) THEN
2145       OPEN get_def_path_pos_ref_csr(
2146     p_path_position_tbl(p_path_position_tbl.LAST).mc_id,
2147     p_path_position_tbl(p_path_position_tbl.LAST).version_number,
2148     p_path_position_tbl(p_path_position_tbl.LAST).position_key);
2149       FETCH get_def_path_pos_ref_csr INTO l_pos_ref_code;
2150       CLOSE get_def_path_pos_ref_csr;
2151    END IF;
2152    CLOSE get_path_pos_ref_csr;
2153 
2154    IF (p_code_flag = FND_API.G_TRUE) THEN
2155        RETURN l_pos_ref_code;
2156    ELSE
2157      --Convert to meaning.
2158      AHL_UTIL_MC_PKG.Convert_To_LookupMeaning('AHL_POSITION_REFERENCE',
2159                                            l_pos_ref_code,
2160                                            l_pos_ref_meaning,
2161                                            l_return_val);
2162 
2163      Return l_pos_ref_meaning;
2164    END IF;
2165 
2166 END Get_Posref_By_Path;
2167 
2168 
2169 ---------------------------------------------------------------------
2170 -- Start of Comments --
2171 --  Function name: get_posref_for_uc
2172 --  Type        : Private
2173 --  Function    : Fetches the position path position ref code
2174 --  Pre-reqs    :
2175 --  Parameters  :
2176 --
2177 --  get_position_ref_code Parameters:
2178 --       p_uc_header_id IN NUMBER UNIT CONFIG header id
2179 --       p_relationship_id IN NUMBER position of subunit
2180 --
2181 FUNCTION get_posref_for_uc(
2182    p_uc_header_id        IN NUMBER,
2183    p_relationship_id     IN NUMBER
2184 )
2185 RETURN VARCHAR2  -- Position Ref Meaning
2186 IS
2187 --
2188 --Fetch the unit and unit header info for instance
2189 CURSOR get_uc_headers_csr (p_uc_header_id IN NUMBER) IS
2190 SELECT unit_config_header_id
2191 FROM  ahl_unit_config_headers
2192 START WITH unit_config_header_id = p_uc_header_id
2193 CONNECT BY PRIOR parent_uc_header_id = unit_config_header_id;
2194 --
2195 CURSOR get_header_details_csr (p_uc_header_id IN NUMBER) IS
2196 SELECT parent_mc_id, parent_position_key
2197 FROM  ahl_uc_header_paths_v
2198 WHERE uc_header_id = p_uc_header_id;
2199 --
2200 CURSOR get_rel_info_csr (p_rel_id IN VARCHAR2) IS
2201 SELECT a.mc_id, b.position_key
2202 FROM  AHL_MC_HEADERS_B a, AHL_MC_RELATIONSHIPS b
2203 WHERE a.mc_header_id = b.mc_header_id
2204 AND b.relationship_id = p_rel_id;
2205 --
2206 CURSOR get_path_pos_ref_csr (p_encoded_path IN VARCHAR2) IS
2207 SELECT position_ref_code
2208 FROM  AHL_MC_PATH_POSITIONS
2209 WHERE encoded_path_position = p_encoded_path;
2210 --
2211 --Select the default position reference.
2212 CURSOR get_def_path_pos_ref_csr (p_relationship_id IN NUMBER) IS
2213 SELECT rel.position_ref_code
2214 FROM  AHL_MC_RELATIONSHIPS rel
2215 WHERE rel.relationship_id = p_relationship_id;
2216 --
2217 l_pos_ref_code    VARCHAR2(30);
2218 l_pos_ref_meaning VARCHAR2(80);
2219 l_path_tbl        AHL_MC_PATH_POSITION_PVT.Path_Position_Tbl_Type;
2220 l_path_rec        AHL_MC_PATH_POSITION_PVT.Path_Position_Rec_Type;
2221 l_index           NUMBER;
2222 l_encoded_path     AHL_MC_PATH_POSITIONS.ENCODED_PATH_POSITION%TYPE;
2223 l_return_val      BOOLEAN;
2224 l_uc_header     NUMBER;
2225 --
2226 BEGIN
2227 
2228   l_index := 0;
2229 
2230   -- Construct the position path table
2231   OPEN get_uc_headers_csr(p_uc_header_id);
2232   LOOP
2233      FETCH get_uc_headers_csr INTO l_uc_header;
2234      EXIT WHEN get_uc_headers_csr%NOTFOUND;
2235 
2236      OPEN get_header_details_csr(l_uc_header);
2237      FETCH get_header_details_csr INTO  l_path_rec.mc_id,
2238                         l_path_rec.position_key;
2239      CLOSE get_header_details_csr;
2240 
2241      --Make it nonversion specific
2242      l_path_rec.version_number := null;
2243 
2244      IF (l_path_rec.mc_id is not null AND
2245          l_path_rec.position_key is not null) THEN
2246         l_path_tbl(l_index) := l_path_rec;
2247         l_index := l_index - 1;
2248      END IF;
2249 
2250   END LOOP;
2251   CLOSE get_uc_headers_csr;
2252   --If subunit definition
2253   IF (l_path_tbl.COUNT>0) THEN
2254 
2255    OPEN get_rel_info_csr(p_relationship_id);
2256    FETCH get_rel_info_csr INTO l_path_rec.mc_id, l_path_rec.position_key;
2257    IF (get_rel_info_csr%FOUND) THEN
2258       l_path_tbl(l_path_tbl.LAST+1) := l_path_rec;
2259    END IF;
2260    CLOSE get_rel_info_csr;
2261 
2262     --Encode the modified with new params path_position_tbl
2263     l_encoded_path := Encode(l_path_tbl);
2264 
2265     OPEN get_path_pos_ref_csr(l_encoded_path);
2266     FETCH get_path_pos_ref_csr INTO l_pos_ref_code;
2267     CLOSE get_path_pos_ref_csr;
2268 
2269     --If there are no pos ref defined for path
2270     IF (l_pos_ref_code IS NULL) THEN
2271        OPEN get_def_path_pos_ref_csr(p_relationship_id);
2272        FETCH get_def_path_pos_ref_csr INTO l_pos_ref_code;
2273        CLOSE get_def_path_pos_ref_csr;
2274     END IF;
2275 
2276   ELSE
2277        OPEN get_def_path_pos_ref_csr(p_relationship_id);
2278        FETCH get_def_path_pos_ref_csr INTO l_pos_ref_code;
2279        CLOSE get_def_path_pos_ref_csr;
2280   END IF;
2281 
2282     --Convert to meaning.
2283     AHL_UTIL_MC_PKG.Convert_To_LookupMeaning('AHL_POSITION_REFERENCE',
2284                                            l_pos_ref_code,
2285                                            l_pos_ref_meaning,
2286                                            l_return_val);
2287     Return l_pos_ref_meaning;
2288 
2289 END Get_Posref_For_UC;
2290 
2291 ----------------
2292 ----------------
2293 FUNCTION Encode(
2294      p_path_position_tbl   IN  AHL_MC_PATH_POSITION_PVT.Path_Position_Tbl_Type
2295 )
2296 RETURN VARCHAR2
2297 IS
2298 --
2299 l_path      AHL_MC_PATH_POSITIONS.ENCODED_PATH_POSITION%TYPE;
2300 l_path_pos_rec  AHL_MC_PATH_POSITION_PVT.Path_Position_Rec_Type;
2301 --
2302 BEGIN
2303   l_path := '';
2304 
2305   FOR i IN p_path_position_tbl.FIRST..p_path_position_tbl.LAST  LOOP
2306      l_path_pos_rec := p_path_position_tbl(i);
2307 
2308      --Append the ids.
2309      l_path := l_path || to_char(l_path_pos_rec.mc_id) || G_ID_SEPARATOR;
2310      IF (l_path_pos_rec.version_number IS NULL) THEN
2311         l_path := l_path || '%';
2312      ELSE
2313         l_path := l_path || to_char(l_path_pos_rec.version_number);
2314      END IF;
2315      l_path :=l_path ||G_ID_SEPARATOR ||to_char(l_path_pos_rec.position_key);
2316 
2317      --Append the node separators.
2318      IF (i < p_path_position_tbl.LAST) THEN
2319        l_path := l_path || G_NODE_SEPARATOR;
2320      END IF;
2321   END LOOP;
2322 
2323   RETURN l_path;
2324 
2325 END Encode;
2326 
2327 ---------------------------------------------------------------------
2328 -- Start of Comments --
2329 --  Function name: get_encoded_path
2330 --  Type        : Private
2331 --  Function    : Fetches the position path encoding based on input
2332 --  Pre-reqs    :
2333 --  Parameters  :
2334 --
2335 --  get_encoded_path Parameters:
2336 --       p_parent_path IN VARCHAR2. encoded parent position path
2337 --       p_mc_id       IN NUMBER.
2338 --       p_ver_num     IN NUMBER.
2339 --       p_position_key IN NUMBER.
2340 --       p_subconfig_flag IN BOOLEAN indicates whether this is new subconfig
2341 --
2342 FUNCTION get_encoded_path(
2343    p_parent_path    IN VARCHAR2,
2344    p_mc_id          IN NUMBER,
2345    p_ver_num        IN NUMBER,
2346    p_position_key   IN NUMBER,
2347    p_subconfig_flag IN VARCHAR2
2348 )
2349 RETURN VARCHAR2
2350 IS
2351 BEGIN
2352 
2353   IF (p_subconfig_flag IS NOT NULL AND
2354       p_subconfig_flag = 'T') THEN
2355     RETURN p_parent_path||G_NODE_SEPARATOR||TO_CHAR(p_mc_id) ||G_ID_SEPARATOR||NVL(TO_CHAR(p_ver_num), '%')||G_ID_SEPARATOR|| TO_CHAR(p_position_key);
2356   ELSE
2357     RETURN SUBSTR(p_parent_path,0,INSTR(p_parent_path,G_ID_SEPARATOR,-1)) || p_position_key;
2358   END IF;
2359 
2360 END get_encoded_path;
2361 
2362 
2363 ---------------------------------------------------------------------
2364 -- Start of Comments --
2365 --  Function name: check_pos_ref_path
2366 --  Type        : Private
2367 --  Function    :
2368 -- Check that the path from instance to to instance has position ref each step
2369 -- and that position ref is not null for all relnships.
2370 --  Pre-reqs    :
2371 --  Parameters  : p_from_csi_id NUMBER the from instance id
2372 --                p_to_csi_id NUMBER the instance id that it reaches
2373 --
2374 FUNCTION check_pos_ref_path(
2375    p_from_csi_id    IN NUMBER,
2376    p_to_csi_id      IN NUMBER)
2377 RETURN BOOLEAN
2378 IS
2379 --
2380 CURSOR check_pos_ref_csr (p_csi_instance_id IN NUMBER,
2381               p_to_csi_instance_id IN NUMBER) IS
2382 SELECT 'X'
2383 FROM csi_ii_relationships csi_ii
2384 WHERE csi_ii.object_id = p_to_csi_instance_id
2385 START WITH csi_ii.subject_id = p_csi_instance_id
2386     AND CSI_II.RELATIONSHIP_TYPE_CODE  = 'COMPONENT-OF'
2387     AND TRUNC(nvl(CSI_II.ACTIVE_START_DATE, sysdate)) <= TRUNC(sysdate)
2388     AND TRUNC(nvl(CSI_II.ACTIVE_END_DATE, sysdate+1)) > TRUNC(sysdate)
2389 CONNECT BY csi_ii.subject_id = PRIOR csi_ii.object_id
2390     AND CSI_II.RELATIONSHIP_TYPE_CODE  = 'COMPONENT-OF'
2391     AND TRUNC(nvl(CSI_II.ACTIVE_START_DATE, sysdate)) <= TRUNC(sysdate)
2392     AND TRUNC(nvl(CSI_II.ACTIVE_END_DATE, sysdate+1)) > TRUNC(sysdate)
2393     AND CSI_II.POSITION_REFERENCE IS NOT NULL;
2394 --
2395 l_dummy VARCHAR2(1);
2396 BEGIN
2397      --Check the position reference is valid for entire path
2398      OPEN check_pos_ref_csr (p_from_csi_id,
2399                  p_to_csi_id);
2400      FETCH check_pos_ref_csr INTO l_dummy;
2401      IF (check_pos_ref_csr%NOTFOUND) THEN
2402         CLOSE check_pos_ref_csr;
2403     RETURN false;
2404      ELSE
2405         CLOSE check_pos_ref_csr;
2406     RETURN true;
2407      END IF;
2408 
2409 END Check_pos_ref_path;
2410 
2411 ---------------------------------------------------------------------
2412 -- Start of Comments --
2413 --  Function name: check_pos_ref_path_char
2414 --  Type        : Private
2415 --  Function    : Calls private function Check_pos_ref_path and returns
2416 --                value as FND_API.G_TRUE for Boolean TRUE and
2417 --                FND_API.G_FALSE for Boolean False.
2418 --  Pre-reqs    :
2419 --  Parameters  : p_from_csi_id NUMBER the from instance id
2420 --                p_to_csi_id NUMBER the instance id that it reaches
2421 --
2422 FUNCTION check_pos_ref_path_char(
2423    p_from_csi_id    IN NUMBER,
2424    p_to_csi_id      IN NUMBER)
2425 RETURN VARCHAR2 IS
2426 BEGIN
2427      IF (AHL_MC_PATH_POSITION_PVT.CHECK_POS_REF_PATH(p_from_csi_id,p_to_csi_id)) THEN
2428         RETURN 'T';
2429      ELSE
2430         RETURN 'F';
2431      END IF;
2432 END check_pos_ref_path_char;
2433 
2434 -----------------------------
2435 -- Start of Comments --
2436 --  Procedure name    : Map_Instance_To_Pos_id
2437 --  Type        : Private
2438 --  Function    : For an instance map the position path and return
2439 --     version specific path_pos_id. Reverse of the Get_Pos_Instance function
2440 --  Pre-reqs    :
2441 --  Parameters  :
2442 --
2443 --  Map_Instance_To_Pos_id Parameters:
2444 --       p_csi_item_instance_id  IN NUMBER  Required. instance for the pos
2445 --       p_relationship_id IN NUMBER Optional. Used for empty position
2446 --       x_path_position_id   OUT NUMBER  the existing or new path pos id
2447 --
2448 --  End of Comments.
2449 
2450 PROCEDURE Map_Instance_To_Pos_ID (
2451     p_api_version         IN           NUMBER,
2452     p_init_msg_list       IN           VARCHAR2  := FND_API.G_FALSE,
2453     p_commit              IN           VARCHAR2  := FND_API.G_FALSE,
2454     p_validation_level    IN           NUMBER    := FND_API.G_VALID_LEVEL_FULL,
2455     x_return_status       OUT  NOCOPY    VARCHAR2,
2456     x_msg_count           OUT  NOCOPY    NUMBER,
2457     x_msg_data            OUT  NOCOPY    VARCHAR2,
2458     p_csi_item_instance_id   IN         NUMBER,
2459     p_relationship_id        IN   NUMBER := FND_API.G_MISS_NUM,
2460     x_path_position_id    OUT NOCOPY  NUMBER)
2461 IS
2462 --
2463 --Fetch the unit and unit header info for each instance
2464 CURSOR get_uc_headers_csr (p_csi_instance_id IN NUMBER) IS
2465 SELECT up.parent_mc_id, up.parent_version_number, up.parent_position_key
2466 FROM  ahl_uc_header_paths_v up
2467 WHERE up.csi_instance_id = p_csi_instance_id;
2468 --
2469 --Traverse up and fetch all unit instance ids
2470 CURSOR get_unit_instance_csr  (p_csi_instance_id IN NUMBER) IS
2471 SELECT csi.object_id
2472   FROM csi_ii_relationships csi
2473 WHERE csi.object_id IN
2474       ( SELECT csi_item_instance_id
2475      FROM ahl_unit_config_headers
2476         WHERE trunc(nvl(active_start_date,sysdate)) <= trunc(sysdate)
2477           AND trunc(sysdate) < trunc(nvl(active_end_date, sysdate+1)))
2478 START WITH csi.subject_id = p_csi_instance_id
2479     AND CSI.RELATIONSHIP_TYPE_CODE  = 'COMPONENT-OF'
2480     AND TRUNC(nvl(CSI.ACTIVE_START_DATE, sysdate)) <= TRUNC(sysdate)
2481     AND TRUNC(nvl(CSI.ACTIVE_END_DATE, sysdate+1)) > TRUNC(sysdate)
2482 CONNECT BY csi.subject_id = PRIOR csi.object_id
2483     AND CSI.RELATIONSHIP_TYPE_CODE  = 'COMPONENT-OF'
2484     AND TRUNC(nvl(CSI.ACTIVE_START_DATE, sysdate)) <= TRUNC(sysdate)
2485     AND TRUNC(nvl(CSI.ACTIVE_END_DATE, sysdate+1)) > TRUNC(sysdate)
2486     AND CSI.POSITION_REFERENCE IS NOT NULL;
2487 --
2488 --Fetches lowest level info
2489 CURSOR get_last_uc_rec_csr (p_csi_instance_id IN NUMBER) IS
2490 SELECT hdr.mc_id, hdr.version_number, rel.position_key
2491 FROM ahl_mc_headers_b hdr, ahl_mc_relationships rel,
2492     csi_ii_relationships csi_ii
2493 WHERE csi_ii.subject_id = p_csi_instance_id
2494     AND CSI_II.RELATIONSHIP_TYPE_CODE  = 'COMPONENT-OF'
2495     AND TRUNC(nvl(CSI_II.ACTIVE_START_DATE, sysdate)) <= TRUNC(sysdate)
2496     AND TRUNC(nvl(CSI_II.ACTIVE_END_DATE, sysdate+1)) > TRUNC(sysdate)
2497     AND TO_NUMBER(CSI_II.POSITION_REFERENCE) = REL.RELATIONSHIP_ID
2498     AND REL.mc_header_id = HDR.mc_header_id;
2499 --
2500 -- Changed by jaramana on July 13, 2006 to fix FP of bug 5368714
2501 -- Do not join with csi_unit_instances_v for filtering out non top level nodes
2502 -- since it does not take dates into consideration
2503 /*
2504 CURSOR get_top_unit_inst_csr (p_csi_instance_id IN NUMBER) IS
2505 SELECT hdr.mc_id, hdr.version_number, rel.position_key
2506 FROM ahl_mc_headers_b hdr, ahl_mc_relationships rel,
2507   ahl_unit_config_headers uch, csi_unit_instances_v csi_u
2508 WHERE uch.csi_item_instance_id = p_csi_instance_id
2509   AND TRUNC(nvl(uch.ACTIVE_START_DATE, sysdate)) <= TRUNC(sysdate)
2510   AND TRUNC(nvl(uch.ACTIVE_END_DATE, sysdate+1)) > TRUNC(sysdate)
2511   AND hdr.mc_header_id = uch.master_config_id
2512   AND rel.mc_header_id = hdr.mc_header_id
2513   AND rel.parent_relationship_id IS NULL
2514   AND uch.csi_item_instance_id = csi_u.instance_id;
2515 */
2516 CURSOR get_top_unit_inst_csr (p_csi_instance_id IN NUMBER) IS
2517 SELECT hdr.mc_id, hdr.version_number, rel.position_key
2518 FROM ahl_mc_headers_b hdr, ahl_mc_relationships rel,
2519   ahl_unit_config_headers uch
2520 WHERE uch.csi_item_instance_id = p_csi_instance_id
2521   AND TRUNC(nvl(uch.ACTIVE_START_DATE, sysdate)) <= TRUNC(sysdate)
2522   AND TRUNC(nvl(uch.ACTIVE_END_DATE, sysdate+1)) > TRUNC(sysdate)
2523   AND hdr.mc_header_id = uch.master_config_id
2524   AND rel.mc_header_id = hdr.mc_header_id
2525   AND rel.parent_relationship_id IS NULL
2526   AND NOT EXISTS (SELECT 'X' FROM CSI_II_RELATIONSHIPS CIR
2527                   WHERE CIR.SUBJECT_ID = uch.csi_item_instance_id AND
2528                         CIR.RELATIONSHIP_TYPE_CODE = 'COMPONENT-OF' AND
2529                         TRUNC(nvl(CIR.ACTIVE_START_DATE, sysdate)) <= TRUNC(sysdate) AND
2530                         TRUNC(nvl(CIR.ACTIVE_END_DATE, sysdate+1)) > TRUNC(sysdate));
2531 
2532 --
2533 --Fetch relationship_id's params
2534 --Making sure that the relationship_id is direct child of the parent instance
2535 -- position.
2536 CURSOR get_mc_relationship_csr (p_relationships_id IN NUMBER,
2537                                 p_parent_instance_id IN NUMBER) IS
2538 SELECT hdr.mc_id, hdr.version_number, rel.position_key
2539 FROM  ahl_mc_headers_b hdr, ahl_mc_relationships rel
2540 WHERE hdr.mc_header_id = rel.mc_header_id
2541  AND rel.relationship_id = p_relationship_id
2542 --Jerry rewrite the following condition on 03/03/2005 in order to fix bug 4090856
2543 --after verifying the bug fix on scmtsb2
2544  AND rel.relationship_id IN (SELECT relationship_id
2545                              FROM ahl_mc_relationships
2546                              WHERE mc_header_id = (SELECT mc_header_id
2547                                                    FROM ahl_mc_relationships
2548                                                    WHERE relationship_id = (SELECT to_number(position_reference)
2549                                                                              FROM csi_ii_relationships
2550                                                                              WHERE subject_id = p_parent_instance_id
2551                                                                              AND RELATIONSHIP_TYPE_CODE  = 'COMPONENT-OF'
2552                                                                              AND TRUNC(nvl(ACTIVE_START_DATE, sysdate)) <= TRUNC(sysdate)
2553                                                                              AND TRUNC(nvl(ACTIVE_END_DATE, sysdate+1)) > TRUNC(sysdate)))
2554                                OR mc_header_id = (SELECT master_config_id
2555                                                     FROM ahl_unit_config_headers
2556                                                    WHERE csi_item_instance_id = p_parent_instance_id
2557                                                      AND TRUNC(nvl(ACTIVE_END_DATE, sysdate+1)) > TRUNC(sysdate)));
2558 
2559 /*
2560  AND rel.parent_relationship_id IN
2561  ( SELECT r.relationship_id
2562    FROM AHL_MC_RELATIONSHIPS r, AHL_UNIT_CONFIG_HEADERS uch
2563    WHERE uch.csi_item_instance_id = p_parent_instance_id
2564      AND uch.master_config_id = r.mc_header_id
2565      --AND r.parent_relationship_id IS NULL
2566      --Jerry commented out the above condition on 01/14/2005 to fix bug 4090856
2567      AND TRUNC(nvl(uch.active_end_date, sysdate+1)) > TRUNC(sysdate)
2568      UNION ALL
2569    SELECT TO_NUMBER(CSI_II.POSITION_REFERENCE)
2570    FROM csi_ii_relationships csi_ii
2571    WHERE csi_ii.subject_id = p_parent_instance_id
2572    AND CSI_II.RELATIONSHIP_TYPE_CODE  = 'COMPONENT-OF'
2573    AND TRUNC(nvl(CSI_II.ACTIVE_START_DATE, sysdate)) <= TRUNC(sysdate)
2574    AND TRUNC(nvl(CSI_II.ACTIVE_END_DATE, sysdate+1)) > TRUNC(sysdate)
2575      UNION ALL
2576    SELECT subrel.relationship_id
2577    FROM ahl_mc_config_relations crel, ahl_mc_relationships subrel,
2578    csi_ii_relationships csi_ii
2579    WHERE csi_ii.subject_id = p_parent_instance_id
2580    AND CSI_II.RELATIONSHIP_TYPE_CODE  = 'COMPONENT-OF'
2581    AND TRUNC(nvl(CSI_II.ACTIVE_START_DATE, sysdate)) <= TRUNC(sysdate)
2582    AND TRUNC(nvl(CSI_II.ACTIVE_END_DATE, sysdate+1)) > TRUNC(sysdate)
2583    AND crel.relationship_id = TO_NUMBER(CSI_II.POSITION_REFERENCE)
2584    AND crel.mc_header_id = subrel.mc_header_id
2585    AND subrel.parent_relationship_id IS NULL);
2586 */
2587 
2588 l_path_tbl        AHL_MC_PATH_POSITION_PVT.Path_Position_Tbl_Type;
2589 l_path_rec        AHL_MC_PATH_POSITION_PVT.Path_Position_Rec_Type;
2590 l_index            NUMBER;
2591 l_api_version      CONSTANT NUMBER       := 1.0;
2592 l_api_name         CONSTANT VARCHAR2(30) := 'Map_Instance_To_Pos_Id';
2593 l_unit_csi_id      NUMBER;
2594 l_full_name        CONSTANT    VARCHAR2(60)    := 'ahl.plsql.' || g_pkg_name || '.' || l_api_name;
2595 
2596 --
2597 BEGIN
2598   -- Standard start of API savepoint
2599   SAVEPOINT Map_Instance_To_Pos_ID_pvt;
2600 
2601   IF (fnd_log.level_procedure >= fnd_log.g_current_runtime_level)THEN
2602       fnd_log.string(fnd_log.level_procedure, l_full_name||'.begin', 'At the start of PLSQL procedure. p_csi_item_instance_id = ' || p_csi_item_instance_id ||
2603                                                                    ', p_relationship_id = ' || p_relationship_id);
2604   END IF;
2605   -- Initialize Procedure return status to success
2606   x_return_status := FND_API.G_RET_STS_SUCCESS;
2607   x_path_position_id := null;
2608 
2609   -- Standard call to check for call compatibility
2610   IF NOT FND_API.Compatible_API_Call(l_api_version, p_api_version, l_api_name,
2611                                      G_PKG_NAME) THEN
2612     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2613   END IF;
2614 
2615   -- Initialize message list if p_init_msg_list is set to TRUE
2616   IF FND_API.To_Boolean(p_init_msg_list) THEN
2617     FND_MSG_PUB.Initialize;
2618   END IF;
2619 
2620   --Fetch the position informations for the instance
2621   OPEN get_last_uc_rec_csr(p_csi_item_instance_id);
2622   FETCH get_last_uc_rec_csr INTO l_path_rec.mc_id,
2623                  l_path_rec.version_number,
2624                  l_path_rec.position_key;
2625   IF (get_last_uc_rec_csr%FOUND) THEN
2626     l_path_tbl(1) := l_path_rec;
2627 
2628     --Now fetch the position paths which match at higher levels.
2629     l_index := 0;
2630     --Fetch the header rec info for the instance
2631     OPEN get_unit_instance_csr(p_csi_item_instance_id);
2632     LOOP
2633       FETCH get_unit_instance_csr INTO l_unit_csi_id;
2634       EXIT WHEN get_unit_instance_csr%NOTFOUND;
2635 
2636       OPEN get_uc_headers_csr(l_unit_csi_id);
2637       FETCH get_uc_headers_csr INTO l_path_rec.mc_id,
2638                    l_path_rec.version_number,
2639                    l_path_rec.position_key;
2640       CLOSE get_uc_headers_csr;
2641 
2642       --Add the path up the tree, decrementing index for each node.
2643       IF (l_path_rec.mc_id is not null AND
2644          l_path_rec.position_key is not null) THEN
2645          l_path_tbl(l_index) := l_path_rec;
2646          l_index := l_index - 1;
2647       END IF;
2648    END LOOP;
2649    CLOSE get_unit_instance_csr;
2650 
2651   --if not position node then check if instance is the top unit node
2652   ELSE
2653     --Fetch the position informations for the unit instance
2654     OPEN get_top_unit_inst_csr(p_csi_item_instance_id);
2655     FETCH get_top_unit_inst_csr INTO l_path_rec.mc_id,
2656                  l_path_rec.version_number,
2657                  l_path_rec.position_key;
2658     IF (get_top_unit_inst_csr%FOUND) THEN
2659       l_path_tbl(1) := l_path_rec;
2660     END IF;
2661     CLOSE get_top_unit_inst_csr;
2662   END IF;
2663   CLOSE get_last_uc_rec_csr;
2664 
2665 
2666   --For the empty position, build path information for last node of path.
2667   IF (p_relationship_id <> FND_API.G_MISS_NUM AND
2668       p_relationship_id IS NOT NULL) THEN
2669       OPEN get_mc_relationship_csr (p_relationship_id,  p_csi_item_instance_id);
2670       FETCH get_mc_relationship_csr INTO l_path_rec.mc_id,
2671                    l_path_rec.version_number,
2672                    l_path_rec.position_key;
2673       IF (get_mc_relationship_csr%FOUND) THEN
2674 
2675         --Either add a new row or replace position key of last row.
2676         IF (l_path_rec.mc_id = l_path_tbl(l_path_tbl.LAST).mc_id AND
2677             l_path_rec.version_number =
2678         NVL(l_path_tbl(l_path_tbl.LAST).version_number,
2679             l_path_rec.version_number)) THEN
2680             l_path_tbl(l_path_tbl.LAST) := l_path_rec;
2681         ELSE
2682             l_path_tbl(l_path_tbl.LAST+1) := l_path_rec;
2683         END IF;
2684       END IF;
2685       CLOSE get_mc_relationship_csr;
2686   END IF;
2687 
2688   IF (l_path_tbl.COUNT > 0) THEN
2689    --Create position with generated instance path position id
2690     IF (fnd_log.level_event >= fnd_log.g_current_runtime_level)THEN
2691       fnd_log.string(fnd_log.level_event, l_full_name, 'About to call Create_Position_ID API. l_path_tbl.COUNT = ' || l_path_tbl.COUNT);
2692     end if;
2693 
2694     -- SATHAPLI::FP OGMA Issue# 105 - Non-Serialized Item Maintenance, 21-Dec-2007
2695     -- There is no need to call the API Create_Position_ID, if there are pending validation errors.
2696     x_msg_count := FND_MSG_PUB.count_msg;
2697     IF x_msg_count > 0 THEN
2698       RAISE  FND_API.G_EXC_ERROR;
2699     END IF;
2700 
2701    Create_Position_ID (
2702             p_api_version       => 1.0,
2703                 p_init_msg_list     => FND_API.G_TRUE,
2704         p_commit            => FND_API.G_FALSE,
2705             p_path_position_tbl     =>   l_path_tbl,
2706             p_position_ref_meaning  => FND_API.G_MISS_CHAR,
2707             p_position_ref_code    => FND_API.G_MISS_CHAR,
2708         x_position_id         => x_path_position_id,
2709         x_return_status       => x_return_status,
2710                 x_msg_count           => x_msg_count,
2711                 x_msg_data            => x_msg_data);
2712     IF (fnd_log.level_event >= fnd_log.g_current_runtime_level)THEN
2713       fnd_log.string(fnd_log.level_event, l_full_name, 'Returned from call to Create_Position_ID API. x_return_status = ' || x_return_status ||
2714                                                        ', x_position_id = ' || x_path_position_id);
2715     end if;
2716   END IF;
2717 
2718   IF (fnd_log.level_procedure >= fnd_log.g_current_runtime_level)THEN
2719       fnd_log.string(fnd_log.level_procedure, l_full_name||'.end', 'At the end of PLSQL procedure. About to commit work.');
2720   END IF;
2721   -- Standard check of p_commit
2722   IF FND_API.TO_BOOLEAN(p_commit) THEN
2723       COMMIT WORK;
2724   END IF;
2725 
2726   -- Standard call to get message count and if count is 1, get message info
2727   FND_MSG_PUB.Count_And_Get
2728     ( p_count => x_msg_count,
2729       p_data  => x_msg_data,
2730       p_encoded => fnd_api.g_false
2731     );
2732 EXCEPTION
2733  WHEN FND_API.G_EXC_ERROR THEN
2734    Rollback to Map_Instance_To_Pos_ID_pvt;
2735    x_return_status := FND_API.G_RET_STS_ERROR;
2736    FND_MSG_PUB.count_and_get( p_count => x_msg_count,
2737                               p_data  => x_msg_data,
2738                               p_encoded => fnd_api.g_false);
2739  WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
2740    Rollback to Map_Instance_To_Pos_ID_pvt;
2741    x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
2742    FND_MSG_PUB.count_and_get( p_count => x_msg_count,
2743                               p_data  => x_msg_data,
2744                               p_encoded => fnd_api.g_false);
2745  WHEN OTHERS THEN
2746    Rollback to Map_Instance_To_Pos_ID_pvt;
2747    x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
2748    Fnd_Msg_Pub.add_exc_msg( p_pkg_name       => G_PKG_NAME,
2749                              p_procedure_name => l_api_name,
2750                              p_error_text     => SQLERRM);
2751     FND_MSG_PUB.count_and_get( p_count => x_msg_count,
2752                               p_data  => x_msg_data,
2753                               p_encoded => fnd_api.g_false);
2754 
2755 END Map_Instance_To_Pos_Id;
2756 
2757 ---------------------------------------------------------------------
2758 -- Start of Comments --
2759 --  Function name: Is_Position_Serial_Controlled
2760 --  Type         : Private
2761 --  Function     : Cretaed for FP OGMA Issue# 105 - Non-Serialized Item Maintenance.
2762 --                 Checks whether a position accepts a serialized item instance or not.
2763 --                 Returns 'Y' if item group attached to the position has first associated item as serialized.
2764 --                 Returns 'N' otherwise.
2765 --  Pre-reqs     :
2766 --  Parameters   : p_relationship_id  NUMBER relationship id
2767 --                 p_path_position_id NUMBER path posiiton id
2768 --
2769 --                 If relationship id is passed, it will be taken to determine the result.
2770 --                 Position id will be used only when relationship id is NULL.
2771 --
2772 
2773 FUNCTION Is_Position_Serial_Controlled(
2774     p_relationship_id    IN    NUMBER,
2775     p_path_position_id   IN    NUMBER
2776 ) RETURN VARCHAR2 IS
2777 --
2778     -- for a given path position id, get the mc id and version no from ahl_mc_path_position_nodes
2779     -- from the mc id and version no, get the mc header id from ahl_mc_headers_b
2780     -- from the mc header id and position key (from ahl_mc_path_position_nodes), get the relationship id from ahl_mc_relationships
2781     CURSOR get_rel_id_csr (p_path_position_id NUMBER) IS
2782         SELECT mcr.relationship_id
2783         FROM   ahl_mc_path_position_nodes mpn, ahl_mc_headers_b mch,
2784                ahl_mc_relationships mcr
2785         WHERE  mpn.path_position_id = p_path_position_id
2786         AND    mpn.sequence         = (
2787                                        SELECT MAX(sequence)
2788                                        FROM   ahl_mc_path_position_nodes
2789                                        WHERE  path_position_id = mpn.path_position_id
2790                                       )
2791         AND    mpn.mc_id            = mch.mc_id
2792         AND    mch.version_number   = NVL(mpn.version_number, mch.version_number)
2793         AND    mcr.mc_header_id     = mch.mc_header_id
2794         AND    mcr.position_key     = mpn.position_key;
2795 
2796     -- for a given relationship id, get the item group id from ahl_mc_relationships
2797     CURSOR get_item_group_id_csr (p_relationship_id NUMBER) IS
2798         SELECT item_group_id
2799         FROM   ahl_mc_relationships
2800         WHERE  relationship_id = p_relationship_id;
2801 
2802     -- for a given item group id, get the serial control code of the associated items
2803     CURSOR get_serial_cntrl_code_csr (p_item_group_id NUMBER) IS
2804         SELECT mtl.serial_number_control_code
2805         FROM   ahl_item_associations_b aia, mtl_system_items_b mtl
2806         WHERE  aia.item_group_id         = p_item_group_id
2807         AND    aia.inventory_item_id     = mtl.inventory_item_id
2808         AND    aia.inventory_org_id      = mtl.organization_id
2809         AND    aia.interchange_type_code IN ('1-WAY INTERCHANGEABLE', '2-WAY INTERCHANGEABLE')
2810         ORDER BY aia.item_association_id;
2811 
2812 --
2813     l_api_name       CONSTANT    VARCHAR2(30) := 'Is_Position_Serial_Controlled';
2814     l_full_name      CONSTANT    VARCHAR2(70) := 'ahl.plsql.'||G_PKG_NAME||'.'||l_api_name;
2815 
2816     l_ret_val                    VARCHAR2(1)  := 'Y';
2817     l_relationship_id            NUMBER       := p_relationship_id;
2818     l_item_group_id              NUMBER;
2819     l_serial_number_control_code NUMBER;
2820 --
2821 BEGIN
2822     IF (FND_LOG.level_procedure >= FND_LOG.g_current_runtime_level) THEN
2823         FND_LOG.string(FND_LOG.level_procedure,l_full_name||'.begin','Start of the API.'||
2824                        ' Input parameters p_relationship_id => '||p_relationship_id||
2825                        ', p_path_position_id => '||p_path_position_id);
2826     END IF;
2827 
2828     IF (l_relationship_id IS NULL) THEN
2829         -- get the relationship id from the given path position id
2830         OPEN get_rel_id_csr(p_path_position_id);
2831         FETCH get_rel_id_csr INTO l_relationship_id;
2832         CLOSE get_rel_id_csr;
2833 
2834         IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2835             FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, l_full_name,
2836                            ' After cursor call l_relationship_id => '||l_relationship_id);
2837         END IF;
2838     END IF;
2839 
2840     -- do the rest only if relationship id is not NULL
2841     IF (l_relationship_id IS NOT NULL) THEN
2842         -- get the item group id
2843         OPEN get_item_group_id_csr(l_relationship_id);
2844         FETCH get_item_group_id_csr INTO l_item_group_id;
2845 
2846         IF (get_item_group_id_csr%NOTFOUND) THEN
2847             -- relationship id is invalid
2848             IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2849                 FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, l_full_name,
2850                                ' Relationship id is invalid.');
2851             END IF;
2852         END IF;
2853 
2854         CLOSE get_item_group_id_csr;
2855 
2856         -- check for the fetched item group id
2857         IF (l_item_group_id IS NOT NULL) THEN
2858             IF (FND_LOG.LEVEL_STATEMENT >= FND_LOG.G_CURRENT_RUNTIME_LEVEL) THEN
2859                 FND_LOG.STRING(FND_LOG.LEVEL_STATEMENT, l_full_name,
2860                                ' Fetched item group id => '||l_item_group_id);
2861             END IF;
2862 
2863             -- the MC position doesn't have subconfigurations attached
2864             -- get the serial control code for the first associated item
2865             OPEN get_serial_cntrl_code_csr(l_item_group_id);
2866             FETCH get_serial_cntrl_code_csr INTO l_serial_number_control_code;
2867             CLOSE get_serial_cntrl_code_csr;
2868 
2869             -- check for the fetched serial control_code
2870             IF (l_serial_number_control_code IS NOT NULL) THEN
2871                 -- if 1, then it is non-serialized; else serialized
2872                 IF (l_serial_number_control_code = 1) THEN
2873                     l_ret_val := 'N';
2874                 END IF;
2875             END IF;
2876         END IF;
2877     END IF; -- relationship id check
2878 
2879     IF (FND_LOG.level_procedure >= FND_LOG.g_current_runtime_level) THEN
2880         FND_LOG.string(FND_LOG.level_procedure,l_full_name||'.end','End of the API with return value => '||l_ret_val);
2881     END IF;
2882 
2883     RETURN l_ret_val;
2884 END Is_Position_Serial_Controlled;
2885 
2886 End AHL_MC_PATH_POSITION_PVT;