DBA Data[Home] [Help]

PACKAGE BODY: APPS.HZ_HIERARCHY_PUB

Source


1 PACKAGE BODY HZ_HIERARCHY_PUB AS
2 /*$Header: ARHHINSB.pls 120.14.12010000.2 2008/09/18 10:27:39 rgokavar ship $ */
3 
4 -----------------------------------------
5 -- declaration of private global varibles
6 -----------------------------------------
7 
8 --G_DEBUG             BOOLEAN := FALSE;
9 
10 TYPE start_date_list is table of date index by binary_integer;
11 TYPE end_date_list is table of date index by binary_integer;
12 TYPE parent_child_list is table of VARCHAR2(1) index by binary_integer;
13 
14 l_bool BOOLEAN;
15 l_status_owner VARCHAR2(255);
16 l_table_owner VARCHAR2(255);
17 l_tmp           VARCHAR2(2000);
18 l_line_number   NUMBER;
19 
20 l_module_prefix CONSTANT VARCHAR2(30) := 'HZ:ARHHINSB:HZ_HIERARCHY_PUB ';
21 l_module        CONSTANT VARCHAR2(30) := 'HIERARCHY_NODE';
22 l_debug_prefix           VARCHAR2(30) ;
23 
24 --------------------------------------------------
25 -- declaration of private procedures and functions
26 --------------------------------------------------
27 
28 procedure get_table_owner
29 is
30 begin
31  l_bool := fnd_installation.GET_APP_INFO('AR',l_status_owner,l_tmp,l_table_owner);
32 end;
33 
34 /*PROCEDURE enable_debug;
35 
36 PROCEDURE disable_debug;
37 */
38 
39 PROCEDURE do_create_link(
40     p_hierarchy_node_rec      IN     HIERARCHY_NODE_REC_TYPE,
41     x_return_status           IN OUT NOCOPY VARCHAR2
42 );
43 
44 PROCEDURE do_update_link(
45     p_hierarchy_node_rec      IN     HIERARCHY_NODE_REC_TYPE,
46     x_return_status           IN OUT NOCOPY VARCHAR2
47 );
48 
49 PROCEDURE do_update_link_pvt(
50     p_hierarchy_node_rec      IN     HIERARCHY_NODE_REC_TYPE
51 );
52 
53 -----------------------------------
54 -- private procedures and functions
55 -----------------------------------
56 
57 /**
58  * PRIVATE PROCEDURE enable_debug
59  *
60  * DESCRIPTION
61  *     Turn on debug mode.
62  *
63  * EXTERNAL PROCEDURES/FUNCTIONS ACCESSED
64  *     HZ_UTILITY_V2PUB.enable_debug
65  *
66  * MODIFICATION HISTORY
67  *
68  *   31-Oct-2001    Anupam Bordia       o Created.
69  *
70  */
71 
72 /*PROCEDURE enable_debug IS
73 
74 BEGIN
75 
76     IF FND_PROFILE.value( 'HZ_API_FILE_DEBUG_ON' ) = 'Y' OR
77        FND_PROFILE.value( 'HZ_API_DBMS_DEBUG_ON' ) = 'Y'
78     THEN
79         HZ_UTILITY_V2PUB.enable_debug;
80         G_DEBUG := TRUE;
81     END IF;
82 
83 END enable_debug;
84 */
85 
86 /**
87  * PRIVATE PROCEDURE disable_debug
88  *
89  * DESCRIPTION
90  *     Turn off debug mode.
91  *
92  * EXTERNAL PROCEDURES/FUNCTIONS ACCESSED
93  *     HZ_UTILITY_V2PUB.disable_debug
94  *
95  * MODIFICATION HISTORY
96  *
97  *   31-Oct-2001    Anupam Bordia       o Created.
98  *
99  */
100 
101 /*PROCEDURE disable_debug IS
102 
103 BEGIN
104 
105     IF G_DEBUG THEN
106         HZ_UTILITY_V2PUB.disable_debug;
107         G_DEBUG := FALSE;
108     END IF;
109 
110 END disable_debug;
111 */
112 
113 
114 /**
115  *  Table sort routine
116  **/
117 PROCEDURE sort (
118     p_d1                          in out nocopy start_date_list,
119     p_d2                          in out nocopy end_date_list,
120     p_pc                          in out nocopy parent_child_list
121 ) IS PRAGMA AUTONOMOUS_TRANSACTION;
122 
123     j                             number :=1;
124 
125     CURSOR c IS
126     SELECT *
127     FROM   hz_temp_rel_gt
128     ORDER BY date1,date2;
129 
130 BEGIN
131 
132     if l_bool is null or l_bool=false then
133       get_table_owner;
134       l_line_number := 1;
135     end if;
136 
137     if l_bool then
138       execute immediate  'truncate table '||l_table_owner||'.hz_temp_rel_gt';
139       l_line_number := 2;
140 
141       forall i in 1..p_d1.count
142         insert into hz_temp_rel_gt(date1,date2,pc_flag) values(p_d1(i),p_d2(i),p_pc(i));
143 
144       l_line_number := 3;
145 
146 
147       open c;
148       fetch c bulk collect into p_d1, p_d2, p_pc;
149       close c;
150 
151       l_line_number := 4;
152       commit;
153     end if;
154 
155 END sort;
156 
157 
158 /**
159  *  MAINTAIN SELF NODES PROCEDURE
160  **/
161 
162 procedure maintain_self_node
163 (    p_node_id            number,
164     p_hierarchy_type     varchar2,
165     p_table_name         VARCHAR2,
166     p_object_type        VARCHAR2,
167     p_actual_content_source VARCHAR2
168 )
169 
170 is
171 
172 l_rowid rowid;
173 l_tp VARCHAR2(1) := 'N';
174 l_lc VARCHAR2(1) := 'N';
175 l_upper_date date;
176 l_lower_date date;
177 j number :=1;
178 i number :=1;
179 process_flag boolean :=true;
180 l_temp_flag VARCHAR2(1);
181 l_const number := 1/(24*3600);
182 l_debug_prefix		       VARCHAR2(30) := '';
183 
184 l_start_date start_date_list;
185 l_end_date end_date_list;
186 l_pc_flag parent_child_list;
187 
188 -- Bug 7260677
189 /*
190 cursor c_dates(p_id number,p_table_name varchar2,p_object_type varchar2,p_hierarchy_type varchar2) is
191 select effective_start_date,effective_end_date,'P' parent_child_flag
192 from hz_hierarchy_nodes
193 where parent_id=p_id
194 and parent_table_name=p_table_name
195 and parent_object_type=p_object_type
196 and hierarchy_type=p_hierarchy_type
197 and level_number=1
198 union
199 select effective_start_date,effective_end_date,'C' parent_child_flag
200 from hz_hierarchy_nodes
201 where child_id=p_id
202 and child_table_name=p_table_name
203 and child_object_type=p_object_type
204 and hierarchy_type=p_hierarchy_type
205 and level_number=1;
206 */
207 cursor c_dates(p_id number,p_table_name varchar2,p_object_type varchar2,p_hierarchy_type varchar2) is
208  select to_date(to_char(effective_start_date,'dd/mm/yyyy')||'12:00:00 AM','dd/mm/yyyy hh:mi:ss AM'),
209         to_date(to_char(effective_end_date,  'dd/mm/yyyy')||'11:59:59 PM','dd/mm/yyyy hh:mi:ss PM'),
210         'P' parent_child_flag
211  from hz_hierarchy_nodes
212  where parent_id=p_id
213  and parent_table_name=p_table_name
214  and parent_object_type=p_object_type
215  and hierarchy_type=p_hierarchy_type
216  and level_number=1
217  union
218  select to_date(to_char(effective_start_date,'dd/mm/yyyy')||'00:00:00','dd/mm/yyyy hh24:mi:ss'),
219         to_date(to_char(effective_end_date,  'dd/mm/yyyy')||'23:59:59','dd/mm/yyyy hh24:mi:ss'),
220         'C' parent_child_flag
221  from hz_hierarchy_nodes
222  where child_id=p_id
223  and child_table_name=p_table_name
224  and child_object_type=p_object_type
225  and hierarchy_type=p_hierarchy_type
226  and level_number=1;
227  -- End of  Bug 7260677
228 
229 begin
230 
231 -- Debug info.
232     IF fnd_log.level_procedure>=fnd_log.g_current_runtime_level THEN
233 	hz_utility_v2pub.debug(p_message=>'maintain_self_node (+) node_id = '||p_node_id||' p_hierarchy_type = '||p_hierarchy_type ,
234 	                       p_prefix=>l_debug_prefix,
235 			       p_msg_level=>fnd_log.level_procedure);
236     END IF;
237 
238 delete from hz_hierarchy_nodes
239 where parent_id=p_node_id
240 and parent_table_name=p_table_name
241 and parent_object_type=p_object_type
242 and hierarchy_type=p_hierarchy_type
243 and level_number=0;
244 
245 open c_dates(p_node_id,p_table_name,p_object_type,p_hierarchy_type);
246 fetch c_dates bulk collect into l_start_date,l_end_date,l_pc_flag;
247 close c_dates;
248 
249 -- Debug info.
250     IF fnd_log.level_procedure>=fnd_log.g_current_runtime_level THEN
251 	hz_utility_v2pub.debug(p_message=>'l_start_date.count = '||l_start_date.count ,
252 	                       p_prefix=>l_debug_prefix,
253 			       p_msg_level=>fnd_log.level_procedure);
254     END IF;
255 
256 
257 if l_start_date.count=1
258 then
259 -- Since the node is being inserted for the first time in the hierarchy it can
260 -- just be a parent or a child and cant be both.
261 
262   if l_pc_flag(1)='P'
263   then l_tp:='Y';
264   else l_lc:='Y';
265   end if;
266 
267   -- Debug info.
268     IF fnd_log.level_procedure>=fnd_log.g_current_runtime_level THEN
269 	hz_utility_v2pub.debug(p_message=>'HZ_HIERARCHY_NODES_PKG.insert_row (+) l_tp = '||l_tp||' l_lc = '||l_lc ,
270 	                       p_prefix=>l_debug_prefix,
271 			       p_msg_level=>fnd_log.level_procedure);
272     END IF;
273 
274     HZ_HIERARCHY_NODES_PKG.Insert_Row(
275                 X_ROWID                      => l_rowid,
276                 X_HIERARCHY_TYPE             => p_hierarchy_type,
277                 X_PARENT_ID                  => p_node_id,
278                 X_PARENT_TABLE_NAME          => p_table_name,
279                 X_PARENT_OBJECT_TYPE         => p_object_type,
280                 X_CHILD_ID                   => p_node_id,
281                 X_CHILD_TABLE_NAME           => p_table_name,
282                 X_CHILD_OBJECT_TYPE          => p_object_type,
283                 X_LEVEL_NUMBER               => 0,
284                 X_TOP_PARENT_FLAG            => l_tp,
285                 X_LEAF_CHILD_FLAG            => l_lc,
286                 X_EFFECTIVE_START_DATE       => l_start_date(1),
287                 X_EFFECTIVE_END_DATE         => l_end_date(1),
288                 X_STATUS                     => NULL,
289                 X_RELATIONSHIP_ID            => NULL,
290                 X_ACTUAL_CONTENT_SOURCE      => p_actual_content_source
291             );
292 else -- multiple nodes present
293 
294 
295   -- Debug info.
296     IF fnd_log.level_procedure>=fnd_log.g_current_runtime_level THEN
297 	hz_utility_v2pub.debug(p_message=> 'before the initial sort ...' ,
298 	                       p_prefix=>l_debug_prefix,
299 			       p_msg_level=>fnd_log.level_procedure);
300     END IF;
301 
302 
303   l_line_number := 5;
304 
305 -- sort the nodes
306   sort(l_start_date,l_end_date,l_pc_flag);
307 
308   -- Debug info.
309     IF fnd_log.level_procedure>=fnd_log.g_current_runtime_level THEN
310     for n in 1..l_start_date.count loop
311 	hz_utility_v2pub.debug(p_message=>'l_start_date = '||l_start_date(n)||' '||
312         'l_end_date = '||l_end_date(n)||' '||
313         'l_pc_flag = '||l_pc_flag(n),
314 	                       p_prefix=>l_debug_prefix,
315 			       p_msg_level=>fnd_log.level_procedure);
316     end loop;
317     END IF;
318 
319   l_line_number := 6;
320 
321 -- 4 values of pc_flag are possible
322 -- 'B' indicates that the node is both a child and a parent during a period
323 -- 'C' indicates that the node is just a child during a period
324 -- 'P' indicates that the node is just a parent during the period
325 -- 'D' indicates that the node is not to be inserted.
326 
327 while (process_flag = true)
328   loop
329 
330   if l_pc_flag(i)='B'
331      and l_end_date(i) between l_start_date(i+1) and l_end_date(i+1)
332   then
333      l_line_number := 7;
334 
335      -- Debug info.
336     IF fnd_log.level_procedure>=fnd_log.g_current_runtime_level THEN
337 	hz_utility_v2pub.debug(p_message=> 'l_pc_flag(i) = B' ,
338 	                       p_prefix=>l_debug_prefix,
339 			       p_msg_level=>fnd_log.level_procedure);
340     END IF;
341 
342      l_start_date(i+1):=l_end_date(i);
343      if l_start_date.exists(i+2) and l_start_date(i+1)>l_start_date(i+2)
344      then
345         l_line_number := 8;
346 
347         sort(l_start_date,l_end_date,l_pc_flag);
348 
349         l_line_number := 9;
350      end if;
351 
352   elsif l_pc_flag(i)=l_pc_flag(i+1)
353       then
354         l_line_number := 10;
355 
356         -- Debug info.
357     IF fnd_log.level_procedure>=fnd_log.g_current_runtime_level THEN
358 	hz_utility_v2pub.debug(p_message=> 'l_pc_flag(i)=l_pc_flag(i+1)' ,
359 	                       p_prefix=>l_debug_prefix,
360 			       p_msg_level=>fnd_log.level_procedure);
361     END IF;
362 
363 
364         if (l_end_date(i) between l_start_date(i+1) and l_end_date(i+1))
365         then
366            l_line_number := 11;
367 
368            l_end_date(i) := l_start_date(i+1);
369         elsif l_end_date(i+1)<l_end_date(i)
370         then
371            l_line_number := 12;
372 
373            l_start_date(i+1):=l_start_date(i); l_end_date(i+1) := l_end_date(i);
374            l_pc_flag(i+1):=l_pc_flag(i); l_pc_flag(i):='D';
375         end if;
376   elsif (l_start_date(i)=l_start_date(i+1)
377          and l_end_date(i)=l_end_date(i+1)
378          and l_pc_flag(i)<>l_pc_flag(i+1))
379          then
380               l_line_number := 13;
381 
382               l_pc_flag(i):='D';
383               l_pc_flag(i+1) :='B';
384   elsif (l_end_date(i) between l_start_date(i+1) and l_end_date(i+1))
385       OR (l_end_date(i)>l_end_date(i+1))
386       then
387         l_line_number := 14;
388 
389         -- Debug info.
390     IF fnd_log.level_procedure>=fnd_log.g_current_runtime_level THEN
391 	hz_utility_v2pub.debug(p_message=> 'l_end_date(i) between ...' ,
392 	                       p_prefix=>l_debug_prefix,
393 			       p_msg_level=>fnd_log.level_procedure);
394     END IF;
395 
396 
397         if l_end_date(i+1)>l_end_date(i)
398         then l_upper_date:=l_end_date(i+1); l_lower_date:=l_end_date(i); l_temp_flag:=l_pc_flag(i+1);
399         else l_upper_date:=l_end_date(i); l_lower_date:=l_end_date(i+1); l_temp_flag:=l_pc_flag(i);
400         end if;
401 
402         j:=i+2;
403 
404         l_end_date(i):=l_start_date(i+1);
405         l_end_date(i+1) := l_lower_date; l_pc_flag(i+1):='B';
406 
407         l_line_number := 15;
408 
409         if l_start_date.exists(i+2) then
410         for k in reverse j..l_end_date.last
411         loop
412             l_start_date(k+1):=l_start_date(k);
413             l_end_date(k+1):=l_end_date(k);
414             l_pc_flag(k+1):=l_pc_flag(k);
415         end loop;
416         end if;
417 
418         l_line_number := 16;
419 
420         l_start_date(i+2):=l_lower_date;
421         l_end_Date(i+2) := l_upper_Date;
422         l_pc_flag(i+2) := l_temp_flag;
423 
424         if l_start_date.exists(i+3) then
425         if(l_start_date(i+3)<l_start_date(i+2) )
426            or (l_start_date(i+3)=l_start_date(i+2)
427                and l_end_date(i+3)<l_end_date(i+2))
428         then
429           sort(l_start_date,l_end_date,l_pc_flag);
430         end if;
431         end if;
432 
433         l_line_number := 17;
434    end if;
435    i:=i+1;
439 
436    if (i=l_start_date.count) then process_flag:=false;
437    end if;
438    end loop;
440    l_line_number := 18;
441 
442    for i in l_start_date.first..l_start_date.last
443    loop
444    if (l_pc_flag(i)<>'D' and l_start_date(i)<>l_end_date(i))
445    then
446     l_tp:='N'; l_lc:='N';
447 
448     if l_pc_flag(i)='P'
449     then l_tp:='Y';
450     elsif l_pc_flag(i)='C'
451     then  l_lc:='Y';
452     end if;
453 
454     l_line_number := 19;
455 
456     -- Debug info.
457     IF fnd_log.level_procedure>=fnd_log.g_current_runtime_level THEN
458 	hz_utility_v2pub.debug(p_message=> 'HZ_HIERARCHY_NODES_PKG.insert_row (+) l_tp = '||l_tp||' l_lc = '||l_lc,
459 	                       p_prefix=>l_debug_prefix,
460 			       p_msg_level=>fnd_log.level_procedure);
461     END IF;
462 
463 
464     HZ_HIERARCHY_NODES_PKG.Insert_Row(
465                 X_ROWID                      => l_rowid,
466                 X_HIERARCHY_TYPE             => p_hierarchy_type,
467                 X_PARENT_ID                  => p_node_id,
468                 X_PARENT_TABLE_NAME          => p_table_name,
469                 X_PARENT_OBJECT_TYPE         => p_object_type,
470                 X_CHILD_ID                   => p_node_id,
471                 X_CHILD_TABLE_NAME           => p_table_name,
472                 X_CHILD_OBJECT_TYPE          => p_object_type,
473                 X_LEVEL_NUMBER               => 0,
474                 X_TOP_PARENT_FLAG            => l_tp,
475                 X_LEAF_CHILD_FLAG            => l_lc,
476                 X_EFFECTIVE_START_DATE       => l_start_date(i)+l_const,
477                 X_EFFECTIVE_END_DATE         => l_end_date(i),
478                 X_STATUS                     => NULL,
479                 X_RELATIONSHIP_ID            => NULL,
480                 X_ACTUAL_CONTENT_SOURCE      => p_actual_content_source
481             );
482    end if;
483    end loop;
484 
485 end if;
486 
487 -- Debug info.
488     IF fnd_log.level_procedure>=fnd_log.g_current_runtime_level THEN
489 	hz_utility_v2pub.debug(p_message=>'maintain_self_node (-)' ,
490 	                       p_prefix=>l_debug_prefix,
491 			       p_msg_level=>fnd_log.level_procedure);
492     END IF;
493 
494 end maintain_self_node;
495 
496 /*===========================================================================+
497  | PROCEDURE
498  |              do_create_link
499  |
500  | DESCRIPTION
501  |              Creates hierarchial link
502  |
503  | SCOPE - PRIVATE
504  |
505  | EXETERNAL PROCEDURES/FUNCTIONS ACCESSED
506  |
507  | ARGUMENTS  : IN:
508  |              OUT:
509  |
510  |          IN/ OUT:
511  |                    p_hierarchy_node_rec
512  |                    x_return_status
513  |
514  | RETURNS    : NONE
515  |
516  | NOTES
517  |
518  | MODIFICATION HISTORY
519  |
520  +===========================================================================*/
521 
522 PROCEDURE do_create_link(
523     p_hierarchy_node_rec                IN     HIERARCHY_NODE_REC_TYPE,
524     x_return_status                     IN OUT NOCOPY VARCHAR2
525 ) IS
526     tmp_child_id                        NUMBER(15);
527     tmp_child_level_number              NUMBER(3);
528     tmp_parent_id                       NUMBER(15);
529     tmp_parent_level_number             NUMBER(3);
530     tmp_top_parent_flag                 VARCHAR2(1);
531     tmp_leaf_child_flag                 VARCHAR2(1);
532     parent_exists                       NUMBER(5);
533     child_exists                        NUMBER(5);
534     l_level_number                      NUMBER := 0;
535     l_top_parent_flag                   VARCHAR2(1) := 'N';
536     l_leaf_child_flag                   VARCHAR2(1) := 'N';
537     l_effective_start_date              DATE := p_hierarchy_node_rec.effective_start_date;
538     l_effective_end_date                DATE := p_hierarchy_node_rec.effective_end_date;
539     l_effective_start_date_tp           DATE;
540     l_effective_end_date_tp             DATE;
541     l_effective_start_date_lc           DATE;
542     l_effective_end_date_lc             DATE;
543     l_temp_start_date                   DATE;
544     l_temp_end_date                     DATE;
545     l_status                            VARCHAR2(1) := p_hierarchy_node_rec.status;
546     l_relationship_id                   NUMBER;
547     l_parent_in_hierarchy               VARCHAR2(1);
548     l_child_in_hierarchy                VARCHAR2(1);
549     l_parent_is_top_parent              VARCHAR2(1) := 'Y';
550     l_child_is_top_parent               VARCHAR2(1) := 'N';
551     l_parent_is_leaf_child              VARCHAR2(1) := 'N';
552     l_child_is_leaf_child               VARCHAR2(1) := 'Y';
553     l_return                            NUMBER;
554     l_dummy                             VARCHAR2(1);
555     l_direct_link_rowid                 ROWID;
556     l_rowid                             ROWID;
557     l_parent_sr_rowid                   ROWID;
558     l_child_sr_rowid                    ROWID;
559 
560     l_existing_start_date               DATE;
561     l_existing_end_date                 DATE;
562 
563     -- this cursor retrieves all the parents of the parent node passed.
564     -- the or condition for the where clause is such to cover any parent
568         SELECT UNIQUE PARENT_ID,
565     -- existance with the current relationships time period and any parent's
566     -- time period.
567     CURSOR c_get_all_parents IS
569                PARENT_TABLE_NAME,
570                PARENT_OBJECT_TYPE,
571                LEVEL_NUMBER
572 /*
573                TOP_PARENT_FLAG,
574                EFFECTIVE_START_DATE,
575                EFFECTIVE_END_DATE
576 */
577         FROM   HZ_HIERARCHY_NODES
578         WHERE  CHILD_ID = p_hierarchy_node_rec.parent_id
579         AND    CHILD_TABLE_NAME = p_hierarchy_node_rec.parent_table_name
580         AND    CHILD_OBJECT_TYPE = p_hierarchy_node_rec.parent_object_type
581         AND    HIERARCHY_TYPE = p_hierarchy_node_rec.hierarchy_type
582 
583         AND    (EFFECTIVE_START_DATE BETWEEN l_existing_start_date AND l_existing_end_date
584                 OR
585                 EFFECTIVE_END_DATE BETWEEN l_existing_start_date AND l_existing_end_date
586                 OR
587                 l_existing_start_date BETWEEN EFFECTIVE_START_DATE AND EFFECTIVE_END_DATE
588                 OR
589                 l_existing_end_date BETWEEN EFFECTIVE_START_DATE AND EFFECTIVE_END_DATE
590                )
591         AND    NVL(status,'A') = 'A'
592         ORDER BY LEVEL_NUMBER ASC;
593 
594     r_get_all_parents     c_get_all_parents%ROWTYPE;
595 
596     -- this cursor retrieves all the children of the child node passed.
597     -- the or condition for the where clause is such to cover any parent
598     -- existance with the current relationships time period and any parent's
599     -- time period.
600     CURSOR c_get_all_children IS
601         SELECT UNIQUE CHILD_ID,
602                CHILD_TABLE_NAME,
603                CHILD_OBJECT_TYPE,
604                LEVEL_NUMBER
605 /*
606                LEAF_CHILD_FLAG,
607                EFFECTIVE_START_DATE,
608                EFFECTIVE_END_DATE
609 */
610         FROM   HZ_HIERARCHY_NODES
611         WHERE  PARENT_ID = p_hierarchy_node_rec.child_id
612         AND    PARENT_TABLE_NAME = p_hierarchy_node_rec.child_table_name
613         AND    PARENT_OBJECT_TYPE = p_hierarchy_node_rec.child_object_type
614         AND    HIERARCHY_TYPE = p_hierarchy_node_rec.hierarchy_type
615 
616         AND    (EFFECTIVE_START_DATE BETWEEN l_existing_start_date AND l_existing_end_date
617                 OR
618                 EFFECTIVE_END_DATE BETWEEN l_existing_start_date AND l_existing_end_date
619                 OR
620                 l_existing_start_date BETWEEN EFFECTIVE_START_DATE AND EFFECTIVE_END_DATE
621                 OR
622                 l_existing_end_date BETWEEN EFFECTIVE_START_DATE AND EFFECTIVE_END_DATE
623                )
624         AND    NVL(status,'A') = 'A'
625         ORDER BY LEVEL_NUMBER ASC;
626 
627     r_get_all_children     c_get_all_children%ROWTYPE;
628 
629     -- this cursor returns the immediate parent information
630     CURSOR c_immediate_parent (p_child_id NUMBER,
631                                p_child_table_name VARCHAR2,
632                                p_child_object_type VARCHAR2) IS
633         SELECT PARENT_ID,
634                PARENT_TABLE_NAME,
635                PARENT_OBJECT_TYPE,
636                EFFECTIVE_START_DATE,
637                EFFECTIVE_END_DATE
638         FROM   HZ_HIERARCHY_NODES a
639         WHERE  CHILD_ID = p_child_id
640         AND    CHILD_TABLE_NAME = p_child_table_name
641         AND    CHILD_OBJECT_TYPE = p_child_object_type
642         AND    HIERARCHY_TYPE = p_hierarchy_node_rec.hierarchy_type
643         AND    (EFFECTIVE_START_DATE BETWEEN l_existing_start_date AND l_existing_end_date
644                 OR
645                 EFFECTIVE_END_DATE BETWEEN l_existing_start_date AND l_existing_end_date
646                 OR
647                 l_existing_start_date BETWEEN EFFECTIVE_START_DATE AND EFFECTIVE_END_DATE
648                 OR
649                 l_existing_end_date BETWEEN EFFECTIVE_START_DATE AND EFFECTIVE_END_DATE
650                )
651         AND    NVL(status,'A') = 'A'
652         AND    LEVEL_NUMBER = 1
653         -- Fix for Bug 5662272
654         -- Filter out end dated records, if there is a future record existing
655         AND    NOT EXISTS (SELECT NULL FROM HZ_HIERARCHY_NODES b
656                            WHERE b.PARENT_ID = a.PARENT_ID
657                            AND   b.PARENT_TABLE_NAME = a.PARENT_TABLE_NAME
658                            AND   b.PARENT_OBJECT_TYPE = a.PARENT_OBJECT_TYPE
659                            AND   b.CHILD_ID = a.CHILD_ID
660                            AND   b.CHILD_TABLE_NAME = a.CHILD_TABLE_NAME
661                            AND   b.CHILD_OBJECT_TYPE = a.CHILD_OBJECT_TYPE
662                            AND   b.HIERARCHY_TYPE = a.HIERARCHY_TYPE
663                            AND   b.LEVEL_NUMBER = a.LEVEL_NUMBER
664                            AND   NVL(b.status,'A') = 'A'
665                            AND   b.EFFECTIVE_END_DATE > a.EFFECTIVE_END_DATE
666                )
667         ORDER BY RELATIONSHIP_ID DESC;
668 
669     r_immediate_parent     c_immediate_parent%ROWTYPE;
670 
671     CURSOR c_get_link_info (p_parent_id NUMBER,
672                             p_parent_table_name VARCHAR2,
673                             p_parent_object_type VARCHAR2,
674                             p_child_id NUMBER,
675                             p_child_table_name VARCHAR2,
676                             p_child_object_type VARCHAR2) IS
680                EFFECTIVE_START_DATE,
677         SELECT LEVEL_NUMBER,
678                TOP_PARENT_FLAG,
679                LEAF_CHILD_FLAG,
681                EFFECTIVE_END_DATE
682         FROM   HZ_HIERARCHY_NODES a
683         WHERE  PARENT_ID = p_parent_id
684         AND    PARENT_TABLE_NAME = p_parent_table_name
685         AND    PARENT_OBJECT_TYPE = p_parent_object_type
686         AND    CHILD_ID = p_child_id
687         AND    CHILD_TABLE_NAME = p_child_table_name
688         AND    CHILD_OBJECT_TYPE = p_child_object_type
689         AND    (EFFECTIVE_START_DATE BETWEEN l_existing_start_date AND l_existing_end_date
690                 OR
691                 EFFECTIVE_END_DATE BETWEEN l_existing_start_date AND l_existing_end_date
692                 OR
693                 l_existing_start_date BETWEEN EFFECTIVE_START_DATE AND EFFECTIVE_END_DATE
694                 OR
695                 l_existing_end_date BETWEEN EFFECTIVE_START_DATE AND EFFECTIVE_END_DATE
696                )
697         AND    NVL(status,'A') = 'A'
698         -- Fix for Bug 5662272
699         -- For the same level, if there are 2 records, then take the latest one and filter out
700         -- record with lower end date. That record may have been end dated and a new one is created
701         AND    NOT EXISTS (SELECT NULL FROM HZ_HIERARCHY_NODES b
702                            WHERE b.PARENT_ID = a.PARENT_ID
703                            AND   b.PARENT_TABLE_NAME = a.PARENT_TABLE_NAME
704                            AND   b.PARENT_OBJECT_TYPE = a.PARENT_OBJECT_TYPE
705                            AND   b.CHILD_ID = a.CHILD_ID
706                            AND   b.CHILD_TABLE_NAME = a.CHILD_TABLE_NAME
707                            AND   b.CHILD_OBJECT_TYPE = a.CHILD_OBJECT_TYPE
708                            AND   b.HIERARCHY_TYPE = a.HIERARCHY_TYPE
709                            AND   b.LEVEL_NUMBER = a.LEVEL_NUMBER
710                            AND   NVL(b.status,'A') = 'A'
711                            AND   b.EFFECTIVE_END_DATE > a.EFFECTIVE_END_DATE
712                )
713 		;
714 
715     r_get_link_info     c_get_link_info%ROWTYPE;
716 
717 BEGIN
718 
719   	  -- Debug info.
720       IF fnd_log.level_procedure >= fnd_log.g_current_runtime_level THEN
721 	    hz_utility_v2pub.debug(p_message=>'do_create_link (+)',
722 	                           p_prefix=> '',
723 	 		                   p_msg_level=>fnd_log.level_procedure);
724       END IF;
725 
726     -- when this procedure is called, the request is to incorporate a relation
727     -- between AAA and BBB in a hierarchy (defined by relationship type) where
728     -- AAA is parent of BBB
729     --                AAA (Parent)
730     --                 |
731     --                 |
732     --                 |
733     --                \|/
734     --                BBB (Child)
735 
736     -------------------------
737     -- INSERT THE DIRECT LINK
738     -------------------------
739 
740     -- Insert the direct link between AAA->BBB.
741     -- Since no duplicate record will be sent to this API, there is no need to check for the
742     -- existance of a record with same parent/child, even if there is one, it will have a
743     -- different period of time.
744     HZ_HIERARCHY_NODES_PKG.Insert_Row(
745         X_ROWID                      => l_direct_link_rowid,
746         X_HIERARCHY_TYPE             => p_hierarchy_node_rec.hierarchy_type,
747         X_PARENT_ID                  => p_hierarchy_node_rec.parent_id,
748         X_PARENT_TABLE_NAME          => p_hierarchy_node_rec.parent_table_name,
749         X_PARENT_OBJECT_TYPE         => p_hierarchy_node_rec.parent_object_type,
750         X_CHILD_ID                   => p_hierarchy_node_rec.child_id,
751         X_CHILD_TABLE_NAME           => p_hierarchy_node_rec.child_table_name,
752         X_CHILD_OBJECT_TYPE          => p_hierarchy_node_rec.child_object_type,
753         X_LEVEL_NUMBER               => 1,
754         X_TOP_PARENT_FLAG            => NULL,
755         X_LEAF_CHILD_FLAG            => NULL,
756         X_EFFECTIVE_START_DATE       => p_hierarchy_node_rec.effective_start_date,
757         X_EFFECTIVE_END_DATE         => p_hierarchy_node_rec.effective_end_date,
758         X_STATUS                     => p_hierarchy_node_rec.status,
759         X_RELATIONSHIP_ID            => p_hierarchy_node_rec.relationship_id,
760         X_ACTUAL_CONTENT_SOURCE      => p_hierarchy_node_rec.actual_content_source
761     );
762 
763     ---------------------------------
764     -- PARENT'S SELF NODE MAINTENANCE
765     ---------------------------------
766 	-- Debug info.
767      IF fnd_log.level_procedure >= fnd_log.g_current_runtime_level THEN
768 	    hz_utility_v2pub.debug(p_message=>'maintain_self_node for Parent(+)',
769 	                           p_prefix=> '',
770 	 		                   p_msg_level=>fnd_log.level_procedure);
771      END IF;
772 
773     maintain_self_node (
774         p_node_id            => p_hierarchy_node_rec.parent_id,
775         p_hierarchy_type     => p_hierarchy_node_rec.hierarchy_type,
776         p_table_name         => p_hierarchy_node_rec.parent_table_name,
777         p_object_type        => p_hierarchy_node_rec.parent_object_type,
778         p_actual_content_source => p_hierarchy_node_rec.actual_content_source
779     );
780 
781 	-- Debug info.
782      IF fnd_log.level_procedure >= fnd_log.g_current_runtime_level THEN
783 	    hz_utility_v2pub.debug(p_message=>'maintain_self_node for Parent(-)',
784 	                           p_prefix=> '',
788     --------------------------------
785 	 		                   p_msg_level=>fnd_log.level_procedure);
786      END IF;
787 
789     -- CHILD'S SELF NODE MAINTENANCE
790     --------------------------------
791 	-- Debug info.
792      IF fnd_log.level_procedure >= fnd_log.g_current_runtime_level THEN
793 	    hz_utility_v2pub.debug(p_message=>'maintain_self_node for Child(+)',
794 	                           p_prefix=> '',
795 	 		                   p_msg_level=>fnd_log.level_procedure);
796      END IF;
797 
798     maintain_self_node (
799         p_node_id            => p_hierarchy_node_rec.child_id,
800         p_hierarchy_type     => p_hierarchy_node_rec.hierarchy_type,
801         p_table_name         => p_hierarchy_node_rec.child_table_name,
802         p_object_type        => p_hierarchy_node_rec.child_object_type,
803         p_actual_content_source => p_hierarchy_node_rec.actual_content_source
804     );
805 
806 	-- Debug info.
807      IF fnd_log.level_procedure >= fnd_log.g_current_runtime_level THEN
808 	    hz_utility_v2pub.debug(p_message=>'maintain_self_node for child (-)',
809 	                           p_prefix=> '',
810 	 		                   p_msg_level=>fnd_log.level_procedure);
811      END IF;
812 
813     -- Bug 4902909.
814     -- we'll get the parents and children of the relationship,
815     -- based on the existing start dates.
816     -- This is because, if the new dates are used, the data will be picked up
817     -- in to the cursor only if there is some overlap between the old and new dates.
818     -- If the old and new date ranges are mutually exclusive, then the where
819     -- used for the cursors will prevent any data from being picked up.
820     -- Also the relationship API will not pass the existing dates.
821     -- these are picked up from the HZ_HIERARCHY_NODES table itself,
822     -- from the level 1 recordusing the parent_id, child_i and relationship_id
823     -- passed through the  p_hierarchy_node_rec.
824     -- once obtained, these current dates will be used to pickup data in to the cursors.
825 
826     -- fetch existing effective start and end dates for relationship id
827     BEGIN
828       SELECT EFFECTIVE_START_DATE, EFFECTIVE_END_DATE
829       INTO   l_existing_start_date, l_existing_end_date
830       FROM   HZ_HIERARCHY_NODES
831       WHERE  PARENT_ID = p_hierarchy_node_rec.parent_id
832         AND  CHILD_ID = p_hierarchy_node_rec.child_id
833         AND  LEVEL_NUMBER = 1
834         AND  RELATIONSHIP_ID = p_hierarchy_node_rec.relationship_id ;
835     EXCEPTION WHEN OTHERS THEN
836       l_existing_start_date := p_hierarchy_node_rec.effective_start_date;
837       l_existing_end_date   := p_hierarchy_node_rec.effective_end_date;
838 
839   	  -- Debug info.
840       IF fnd_log.level_exception >= fnd_log.g_current_runtime_level THEN
841 	    hz_utility_v2pub.debug(p_message=>'Local Exception:'||SQLERRM,
842 	                           p_prefix=> '',
843 	 		                   p_msg_level=>fnd_log.level_procedure);
844       END IF;
845 
846     END;
847 
848 
849     --------------------------------
850     -- MAINTENANCE OF INDIRECT LINKS
851     --------------------------------
852 	-- Debug info.
853      IF fnd_log.level_procedure >= fnd_log.g_current_runtime_level THEN
854 	    hz_utility_v2pub.debug(p_message=>'maintain indirect links (+)',
855 	                           p_prefix=> '',
856 	 		                   p_msg_level=>fnd_log.level_procedure);
857      END IF;
858 
859     -- first we'll get all the parents of AAA (this will include AAA itself)
860     OPEN c_get_all_parents;
861     FETCH c_get_all_parents INTO r_get_all_parents;
862 
863 
864     WHILE c_get_all_parents%FOUND
865     -- at this point we have got at least one parent for AAA, let's call it XXX
866     LOOP
867         -- we open the cursor to get all the children of BBB (this will include BBB itself)
868         OPEN c_get_all_children;
869         FETCH c_get_all_children INTO r_get_all_children;
870 
871         WHILE c_get_all_children%FOUND
872         -- let's call it YYY
873         LOOP
874             -- we need to create a link XXX --> YYY
875             -- get the immediate parent of YYY, let's call it III
876             OPEN c_immediate_parent (r_get_all_children.child_id,
877                                      r_get_all_children.child_table_name,
878                                      r_get_all_children.child_object_type);
879             FETCH c_immediate_parent INTO r_immediate_parent;
880             CLOSE c_immediate_parent;
881 
882             -- get the link information between XXX and III
883             OPEN c_get_link_info (r_get_all_parents.parent_id,
884                                   r_get_all_parents.parent_table_name,
885                                   r_get_all_parents.parent_object_type,
886                                   r_immediate_parent.parent_id,
887                                   r_immediate_parent.parent_table_name,
888                                   r_immediate_parent.parent_object_type);
889             FETCH c_get_link_info INTO r_get_link_info;
890             CLOSE c_get_link_info;
891 
892             -- we need to find out
893             --     level : level of XXX->YYY is level of XXX->III plus 1
894             l_level_number := r_get_link_info.level_number + 1;
895 
896             --     effective dates : that would be
897             --                       1. start date later of the two start dates of XXX->III and III->YYY
901             ELSE
898             --                       2. end date earlier of the two end dates of XXX->III and III->YYY
899             IF r_get_link_info.effective_start_date <= r_immediate_parent.effective_start_date THEN
900                 l_effective_start_date := r_immediate_parent.effective_start_date;
902                 l_effective_start_date := r_get_link_info.effective_start_date;
903             END IF;
904 
905             IF r_get_link_info.effective_end_date <= r_immediate_parent.effective_end_date THEN
906                 l_effective_end_date := r_get_link_info.effective_end_date;
907             ELSE
908                 l_effective_end_date := r_immediate_parent.effective_end_date;
909             END IF;
910 
911             --     top parent : top parent status of XXX remains as it is
912             -- l_top_parent_flag := r_get_all_parents.top_parent_flag;
913 
914             IF l_level_number > 1 THEN
915             -- now insert the XXX->YYY link
916                 HZ_HIERARCHY_NODES_PKG.Insert_Row(
917                     X_ROWID                      => l_rowid,
918                     X_HIERARCHY_TYPE             => p_hierarchy_node_rec.hierarchy_type,
919                     X_PARENT_ID                  => r_get_all_parents.parent_id,
920                     X_PARENT_TABLE_NAME          => r_get_all_parents.parent_table_name,
921                     X_PARENT_OBJECT_TYPE         => r_get_all_parents.parent_object_type,
922                     X_CHILD_ID                   => r_get_all_children.child_id,
923                     X_CHILD_TABLE_NAME           => r_get_all_children.child_table_name,
924                     X_CHILD_OBJECT_TYPE          => r_get_all_children.child_object_type,
925                     X_LEVEL_NUMBER               => l_level_number,
926                     X_TOP_PARENT_FLAG            => NULL,
927                     X_LEAF_CHILD_FLAG            => NULL,
928                     X_EFFECTIVE_START_DATE       => l_effective_start_date,
929                     X_EFFECTIVE_END_DATE         => l_effective_end_date,
930                     X_STATUS                     => NULL,
931                     X_RELATIONSHIP_ID            => NULL,
932                     X_ACTUAL_CONTENT_SOURCE      => p_hierarchy_node_rec.actual_content_source
933                 );
934             END IF;
935 
936             -- get the next child
937             FETCH c_get_all_children INTO r_get_all_children;
938         END LOOP;
939         CLOSE c_get_all_children;
940         -- get the next parent of AAA
941         FETCH c_get_all_parents INTO r_get_all_parents;
942 
943     END LOOP;
944     CLOSE c_get_all_parents;
945 
946 
947 	-- Debug info.
948      IF fnd_log.level_procedure >= fnd_log.g_current_runtime_level THEN
949 	    hz_utility_v2pub.debug(p_message=>'maintain indirect links (-)',
950 	                           p_prefix=> '',
951 	 		                   p_msg_level=>fnd_log.level_procedure);
952      END IF;
953 
954     l_temp_start_date := l_effective_start_date_lc;
955     l_temp_end_date := l_effective_end_date_lc;
956 
957   	  -- Debug info.
958       IF fnd_log.level_procedure >= fnd_log.g_current_runtime_level THEN
959 	    hz_utility_v2pub.debug(p_message=>'do_create_link (-)',
960 	                           p_prefix=> '',
961 	 		                   p_msg_level=>fnd_log.level_procedure);
962       END IF;
963 
964 END do_create_link;
965 
966 /*------------------------------------------------------------------------------+
967  Created By Nishant on 03-Apr-2006 for Bug 4662744. Modified logic of
968  Do_update_link procedure to traverse the tree recursively to figure out parents
969  at each step and then update the hierarchy nodes dates
970 ------------------------------------------------------------------------------+*/
971 PROCEDURE do_update_link_pvt(
972     p_hierarchy_node_rec      IN     HIERARCHY_NODE_REC_TYPE
973 ) IS
974 
975   l_debug_prefix		CONSTANT VARCHAR2(30) := '';
976 
977   l_parent_id            NUMBER;
978   l_parent_type          VARCHAR2(100);
979   l_child_id             NUMBER;
980   l_child_type           VARCHAR2(100);
981   l_level                NUMBER;
982   l_hierarchy_type       VARCHAR2(30);
983   l_parent_table         VARCHAR2(30);
984   l_child_table          VARCHAR2(30);
985 
986     -- Bug 4902909.
987     -- we'll get the parents and children of the relationship,
988     -- based on the existing start dates.
989     -- This is because, if the new dates are used, the data will be picked up
990     -- in to the cursor only if there is some overlap between the old and new dates.
991     -- If the old and new date ranges are mutually exclusive, then the where
992     -- used for the cursors will prevent any data from being picked up.
993     -- Also the relationship API will not pass the existing dates.
994     -- these are picked up from the HZ_HIERARCHY_NODES table itself,
995     -- from the level 1 recordusing the parent_id, child_i and relationship_id
996     -- passed through the  p_hierarchy_node_rec.
997     -- once obtained, these current dates will be used to pickup data in to the cursors.
998   l_existing_start_date               DATE;
999   l_existing_end_date                 DATE;
1000   l_LAST_UPDATED_BY                   NUMBER;
1001   l_LAST_UPDATE_DATE                  DATE;
1002   l_LAST_UPDATE_LOGIN                 NUMBER;
1003 
1004   TYPE parent_list_rec_type IS RECORD
1005   ( parent_id      NUMBER,
1006     parent_type    VARCHAR2(100),
1010 
1007     parent_table   VARCHAR2(100),
1008     level_number   NUMBER
1009   );
1011   TYPE parent_list_tbl_type IS TABLE OF parent_list_rec_type INDEX BY BINARY_INTEGER;
1012 
1013   parent_list_tbl parent_list_tbl_type;
1014 
1015     CURSOR c_get_all_children (ll_child_id NUMBER, ll_child_object_type IN VARCHAR2,
1016 	                           ll_child_table IN VARCHAR2)
1017 	IS
1018         SELECT CHILD_ID,
1019                CHILD_OBJECT_TYPE,
1020                CHILD_TABLE_NAME
1021         FROM   HZ_HIERARCHY_NODES
1022         WHERE  PARENT_ID = ll_child_id
1023         AND    PARENT_TABLE_NAME = ll_child_table
1024         AND    PARENT_OBJECT_TYPE = ll_child_object_type
1025         AND    HIERARCHY_TYPE = l_hierarchy_type
1026         AND    (EFFECTIVE_START_DATE BETWEEN l_existing_start_date AND l_existing_end_date
1027                 OR
1028                 EFFECTIVE_END_DATE BETWEEN l_existing_start_date AND l_existing_end_date
1029                 OR
1030                 l_existing_start_date BETWEEN EFFECTIVE_START_DATE AND EFFECTIVE_END_DATE
1031                 OR
1032                 l_existing_end_date BETWEEN EFFECTIVE_START_DATE AND EFFECTIVE_END_DATE
1033                )
1034         AND    NVL(status,'A') = 'A'
1035         ORDER BY LEVEL_NUMBER ASC;
1036 
1037      CURSOR c_match_par_child (l_parent_id IN NUMBER,l_parent_object_type IN VARCHAR2,
1038                                l_parent_table IN VARCHAR2,
1039 		                       l_child_id IN NUMBER, l_child_object_type IN VARCHAR2,
1040 							   l_child_table IN VARCHAR2)
1041 		IS
1042         SELECT PARENT_ID, PARENT_OBJECT_TYPE, CHILD_ID, CHILD_OBJECT_TYPE, rowid
1043         FROM  HZ_HIERARCHY_NODES a
1044         WHERE PARENT_ID = l_parent_id
1045         AND   PARENT_TABLE_NAME = l_parent_table
1046         AND   PARENT_OBJECT_TYPE = l_parent_object_type
1047         AND   CHILD_ID = l_child_id
1048         AND   CHILD_TABLE_NAME = l_child_table
1049         AND   CHILD_OBJECT_TYPE = l_child_object_type
1050         AND   HIERARCHY_TYPE = l_hierarchy_type
1051         AND   (EFFECTIVE_START_DATE BETWEEN l_existing_start_date AND l_existing_end_date
1052                OR
1053                EFFECTIVE_END_DATE BETWEEN l_existing_start_date AND l_existing_end_date
1054                OR
1055                l_existing_start_date BETWEEN EFFECTIVE_START_DATE AND EFFECTIVE_END_DATE
1056                OR
1057                l_existing_end_date BETWEEN EFFECTIVE_START_DATE AND EFFECTIVE_END_DATE
1058               )
1059         AND   NVL(status,'A') = 'A'
1060         -- Fix for Bug 5662272
1061         -- Here problem is, it will pick up any 1 record in random and update end date for that
1062         -- This way it may inactivae end dated record and leave active record unchanged.
1063         -- Change it pick up the records for which start date and end date for level 1 relationship
1064         -- matches (most likely that will be the date for this link also.). If No such record
1065         -- exists, then pick up the greatest effective_end_date rec (most linkely will be the active one)
1066         -- and execute cursor only once
1067         AND   NOT  EXISTS (SELECT NULL FROM HZ_HIERARCHY_NODES b
1068                            WHERE b.PARENT_ID = a.PARENT_ID
1069                            AND   b.PARENT_TABLE_NAME = a.PARENT_TABLE_NAME
1070                            AND   b.PARENT_OBJECT_TYPE = a.PARENT_OBJECT_TYPE
1071                            AND   b.CHILD_ID = a.CHILD_ID
1072                            AND   b.CHILD_TABLE_NAME = a.CHILD_TABLE_NAME
1073                            AND   b.CHILD_OBJECT_TYPE = a.CHILD_OBJECT_TYPE
1074                            AND   b.HIERARCHY_TYPE = a.HIERARCHY_TYPE
1075                            AND   b.LEVEL_NUMBER = a.LEVEL_NUMBER
1076                            AND   NVL(b.status,'A') = 'A'
1077                            AND   b.EFFECTIVE_START_DATE = l_existing_start_date
1078                            AND   b.EFFECTIVE_END_DATE = l_existing_end_date
1079                            AND   a.ROWID <> b.ROWID
1080               )
1081       -- Move this condition inside cursor loop
1082       --AND  ROWNUM = 1
1083       ORDER BY effective_end_date desc;
1084 
1085 
1086 	PROCEDURE do_recursive_parent_fetch (p_child_id IN NUMBER,
1087 	                                     p_child_type IN VARCHAR2,
1088 	                                     p_child_table IN VARCHAR2,
1089 	                                     p_child_level IN NUMBER) IS
1090 
1091 
1092 	    CURSOR get_parent_id_cur (l_child_id IN NUMBER, l_child_object_type IN VARCHAR2,
1093 		                          l_child_table IN VARCHAR2) IS
1094 	    SELECT parent_id, parent_object_type, parent_table_name
1095 	    FROM   hz_hierarchy_nodes
1096 	    WHERE  hierarchy_type = l_hierarchy_type
1097 	    AND    child_table_name = l_child_table
1098 	    AND    child_object_type = l_child_object_type
1099 	    AND    child_id = l_child_id
1100 	    AND    level_number = 1
1101 	    AND    SYSDATE+0.0001 BETWEEN effective_start_date AND effective_end_date
1102         AND    NVL(status,'A') = 'A'
1103 	    ;
1104 
1105 	  l_parent_id          NUMBER;
1106 	  l_parent_type        VARCHAR2(100);
1107 	  l_parent_level       NUMBER;
1108 	  l_parent_table       VARCHAR2(100);
1109 	  l_counter            NUMBER;
1110 	BEGIN
1111       -- FND Logging for debug purpose
1112       IF (fnd_log.level_statement >= fnd_log.g_current_runtime_level) THEN
1113            hz_utility_v2pub.debug
1114 	               (p_message      => 'Input : '||p_child_id||' : '||p_child_type||' : '||p_child_level,
1115 		           p_prefix        => l_debug_prefix,
1119 		          );
1116 		           p_msg_level     => fnd_log.level_statement,
1117 		           p_module_prefix => l_module_prefix,
1118 		           p_module        => l_module
1120       END IF;
1121 
1122 	  OPEN get_parent_id_cur (p_child_id, p_child_type, p_child_table);
1123 
1124          -- FND Logging for debug purpose
1125     	 IF (fnd_log.level_statement >= fnd_log.g_current_runtime_level) THEN
1126            hz_utility_v2pub.debug
1127 	               (p_message      => 'Open get_parent_id_cur for id : '||p_child_id,
1128 		           p_prefix        => l_debug_prefix,
1129 		           p_msg_level     => fnd_log.level_statement,
1130 		           p_module_prefix => l_module_prefix,
1131 		           p_module        => l_module
1132 		          );
1133          END IF;
1134 
1135 	    LOOP
1136 	      FETCH get_parent_id_cur INTO l_parent_id, l_parent_type, l_parent_table;
1137 	      IF (get_parent_id_cur%FOUND) THEN
1138 
1139 	        l_counter := parent_list_tbl.COUNT+1;
1140 	        parent_list_tbl(l_counter).parent_id := l_parent_id;
1141 	        parent_list_tbl(l_counter).parent_type := l_parent_type;
1142 	        parent_list_tbl(l_counter).parent_table := l_parent_table;
1143 	        parent_list_tbl(l_counter).level_number := p_child_level;
1144 
1145             -- Fix for Bug 5204188 (Parent Id and Child Id same at level =1, so it goes
1146 			-- infinite recursion). Break out if parent and child id are same.
1147 			IF (p_child_id = l_parent_id) THEN
1148                -- FND Logging for debug purpose
1149            	   IF (fnd_log.level_statement >= fnd_log.g_current_runtime_level) THEN
1150                   hz_utility_v2pub.debug
1151 	               (p_message      => 'Exit loop because parent child matched for level 1',
1152 		           p_prefix        => l_debug_prefix,
1153 		           p_msg_level     => fnd_log.level_statement,
1154 		           p_module_prefix => l_module_prefix,
1155 		           p_module        => l_module
1156 		           );
1157                END IF;
1158 
1159 			   EXIT;
1160 
1161 			ELSE
1162 
1163 			   -- FND Logging for debug purpose
1164            	   IF (fnd_log.level_statement >= fnd_log.g_current_runtime_level) THEN
1165                   hz_utility_v2pub.debug
1166 	               (p_message      => 'Fetched for recursion : '||l_parent_id||' : '||l_parent_type||' : '||TO_CHAR(TO_NUMBER(p_child_level+1)),
1167 		           p_prefix        => l_debug_prefix,
1168 		           p_msg_level     => fnd_log.level_statement,
1169 		           p_module_prefix => l_module_prefix,
1170 		           p_module        => l_module
1171 		           );
1172                END IF;
1173 
1174 			  do_recursive_parent_fetch(l_parent_id, l_parent_type,l_parent_table, p_child_level+1);
1175             END IF;
1176 
1177 	      ELSE
1178 
1179 			 -- FND Logging for debug purpose
1180            	 IF (fnd_log.level_statement >= fnd_log.g_current_runtime_level) THEN
1181                   hz_utility_v2pub.debug
1182 	               (p_message      => 'Exit Loop...',
1183 		           p_prefix        => l_debug_prefix,
1184 		           p_msg_level     => fnd_log.level_statement,
1185 		           p_module_prefix => l_module_prefix,
1186 		           p_module        => l_module
1187 		           );
1188              END IF;
1189 
1190 	        EXIT;
1191 	      END IF;
1192 
1193 	    END LOOP;
1194 
1195   	    -- FND Logging for debug purpose
1196        	IF (fnd_log.level_statement >= fnd_log.g_current_runtime_level) THEN
1197               hz_utility_v2pub.debug
1198                (p_message      => 'Close get_parent_id_cur for id : '||p_child_id,
1199 	           p_prefix        => l_debug_prefix,
1200 	           p_msg_level     => fnd_log.level_statement,
1201 	           p_module_prefix => l_module_prefix,
1202 	           p_module        => l_module
1203 	           );
1204         END IF;
1205 
1206 	  CLOSE get_parent_id_cur;
1207 
1208 	END do_recursive_parent_fetch;
1209 
1210 BEGIN
1211   -- Debug info.
1212   IF fnd_log.level_procedure>=fnd_log.g_current_runtime_level THEN
1213      hz_utility_v2pub.debug(p_message=>'do_update_link_pvt (+)',
1214 	                       p_prefix=>l_debug_prefix,
1215 	 		               p_msg_level=>fnd_log.level_procedure);
1216   END IF;
1217 
1218   -- initialize variables
1219   l_parent_id           := p_hierarchy_node_rec.parent_id;
1220   l_parent_type         := p_hierarchy_node_rec.parent_object_type;
1221   l_child_id            := p_hierarchy_node_rec.child_id;
1222   l_child_type          := p_hierarchy_node_rec.child_object_type;
1223   l_level               := 1;
1224   l_hierarchy_type      := p_hierarchy_node_rec.hierarchy_type;
1225   l_parent_table        := p_hierarchy_node_rec.parent_table_name;
1226   l_child_table         := p_hierarchy_node_rec.child_table_name;
1227 
1228   l_LAST_UPDATED_BY     := HZ_UTILITY_V2PUB.last_updated_by;
1229   l_LAST_UPDATE_DATE    := HZ_UTILITY_V2PUB.last_update_date;
1230   l_LAST_UPDATE_LOGIN   := HZ_UTILITY_V2PUB.last_update_login;
1231 
1232 
1233   -- fetch existing effective start and end dates for relationship id
1234   BEGIN
1235     SELECT EFFECTIVE_START_DATE,EFFECTIVE_END_DATE
1236     INTO   l_existing_start_date,l_existing_end_date
1237     FROM   HZ_HIERARCHY_NODES
1238     WHERE  PARENT_ID = p_hierarchy_node_rec.parent_id
1239       AND  CHILD_ID = p_hierarchy_node_rec.child_id
1240       AND  LEVEL_NUMBER = 1
1244     l_existing_end_date   := p_hierarchy_node_rec.effective_end_date;
1241       AND  RELATIONSHIP_ID = p_hierarchy_node_rec.relationship_id ;
1242   EXCEPTION WHEN OTHERS THEN
1243     l_existing_start_date := p_hierarchy_node_rec.effective_start_date;
1245 
1246 	-- Debug info.
1247     IF fnd_log.level_exception >= fnd_log.g_current_runtime_level THEN
1248 	hz_utility_v2pub.debug(p_message=>'Local Exception:'||SQLERRM,
1249 	                       p_prefix=>l_debug_prefix,
1250 	 		               p_msg_level=>fnd_log.level_procedure);
1251     END IF;
1252 
1253   END;
1254 
1255   -- Add self record for parent
1256   parent_list_tbl(1).parent_id    := l_parent_id;
1257   parent_list_tbl(1).parent_type  := l_parent_type;
1258   parent_list_tbl(1).parent_table  := l_parent_table;
1259   parent_list_tbl(1).level_number := 0;
1260 
1261   -- Debug info.
1262   IF fnd_log.level_procedure>=fnd_log.g_current_runtime_level THEN
1263 	hz_utility_v2pub.debug(p_message=>'do_recursive_parent_fetch (+)',
1264 	                       p_prefix=>l_debug_prefix,
1265 	 		               p_msg_level=>fnd_log.level_procedure);
1266   END IF;
1267 
1268   do_recursive_parent_fetch(l_parent_id, l_parent_type, l_parent_table, l_level);
1269 
1270   -- Debug info.
1271   IF fnd_log.level_procedure>=fnd_log.g_current_runtime_level THEN
1272 	hz_utility_v2pub.debug(p_message=>'do_recursive_parent_fetch (-)',
1273 	                       p_prefix=>l_debug_prefix,
1274 	 		               p_msg_level=>fnd_log.level_procedure);
1275   END IF;
1276 
1277   -- dbms_output.put_line('Table data:');
1278   IF (parent_list_tbl IS NOT NULL) THEN
1279     IF (parent_list_tbl.COUNT > 0) THEN
1280       FOR i IN parent_list_tbl.FIRST..parent_list_tbl.LAST LOOP
1281       /*  dbms_output.put_line(i||':'||parent_list_tbl(i).parent_id
1282 		                      ||':'||parent_list_tbl(i).parent_type
1283 							  ||':'||parent_list_tbl(i).level_number);
1284 		*/
1285 		-- put the child cursor here
1286 		FOR c_child_rec IN c_get_all_children (l_child_id, l_child_type, l_child_table) LOOP
1287            FOR c_par_child_rec IN c_match_par_child (parent_list_tbl(i).parent_id, parent_list_tbl(i).parent_type,
1288 		                          parent_list_tbl(i).parent_table,
1289 		                          c_child_rec.child_id, c_child_rec.CHILD_OBJECT_TYPE, c_child_rec.CHILD_TABLE_NAME
1290 								  ) LOOP
1291 		     /* dbms_output.put_line(c_par_child_rec.parent_id||':'||c_par_child_rec.parent_object_type||':'||
1292 			                      c_par_child_rec.child_id||':'||c_par_child_rec.child_object_type||':'||
1293 								  c_par_child_rec.rowid);
1294 			 */
1295               UPDATE HZ_HIERARCHY_NODES
1296               SET EFFECTIVE_START_DATE = NVL(p_hierarchy_node_rec.effective_start_date, EFFECTIVE_START_DATE),
1297                   EFFECTIVE_END_DATE = NVL(p_hierarchy_node_rec.effective_end_date, EFFECTIVE_END_DATE),
1298                   -- added for Bug 5662272 (This will update Status values for I which help in
1299 				  -- eleminating deleted rows from all the cursors
1300                   STATUS = NVL(p_hierarchy_node_rec.status, STATUS),
1301                   LAST_UPDATED_BY = l_last_updated_by,
1302   		          LAST_UPDATE_DATE = l_last_update_date,
1303                   LAST_UPDATE_LOGIN = l_last_update_login
1304               WHERE ROWID = c_par_child_rec.ROWID;
1305 
1306 			  -- exit after 1 execution for each parent child pair for 1 level
1307 			  -- proviously rownum = 1 logic in cursor but because of sorting req. (latest rec)
1308 			  -- moved 1 rec logic here (Fix for Bug 5662272)
1309 			  EXIT;
1310 
1311 		   END LOOP;
1312 		END LOOP;
1313       END LOOP;
1314     END IF;
1315   END IF;
1316 
1317     -- Debug info.
1318     IF fnd_log.level_procedure>=fnd_log.g_current_runtime_level THEN
1319 	hz_utility_v2pub.debug(p_message=>'do_update_link_pvt (-)',
1320 	                       p_prefix=>l_debug_prefix,
1321 	 		               p_msg_level=>fnd_log.level_procedure);
1322     END IF;
1323 
1324 END do_update_link_pvt;
1325 ------------------------------------------------------------------------------+
1326 
1327 /*===========================================================================+
1328  | PROCEDURE
1329  |              do_update_link
1330  |
1331  | DESCRIPTION
1332  |              updates hierarchial relationship between two nodes and corrosponding links.
1333  |
1334  | SCOPE - PRIVATE
1335  |
1336  | EXETERNAL PROCEDURES/FUNCTIONS ACCESSED
1337  |
1338  | ARGUMENTS  : IN:
1339  |              OUT:
1340  |          IN/ OUT:
1341  |                    p_hierarchy_node_rec
1342  |                    x_return_status
1343  |
1344  | RETURNS    : NONE
1345  |
1346  | NOTES
1347  |
1348  | MODIFICATION HISTORY
1349  |
1350  +===========================================================================*/
1351 
1352 PROCEDURE do_update_link(
1353     p_hierarchy_node_rec                IN     HIERARCHY_NODE_REC_TYPE,
1354     x_return_status                     IN OUT NOCOPY VARCHAR2
1355 ) IS
1356 /*  -- Moved below logic into procedure do_update_link_pvt for Bug 4662744 (Nishant 30-Mar-2006)
1357     -- End dating of hierarchy in case of multiple parents was not correct
1358 
1359     -- Bug 4902909.
1360     -- we'll get the parents and children of the relationship,
1361     -- based on the existing start dates.
1362     -- This is because, if the new dates are used, the data will be picked up
1363     -- in to the cursor only if there is some overlap between the old and new dates.
1367     -- these are picked up from the HZ_HIERARCHY_NODES table itself,
1364     -- If the old and new date ranges are mutually exclusive, then the where
1365     -- used for the cursors will prevent any data from being picked up.
1366     -- Also the relationship API will not pass the existing dates.
1368     -- from the level 1 recordusing the parent_id, child_i and relationship_id
1369     -- passed through the  p_hierarchy_node_rec.
1370     -- once obtained, these current dates will be used to pickup data in to the cursors.
1371     l_existing_start_date               DATE;
1372     l_existing_end_date                 DATE;
1373     -- this cursor retrieves all the parents of the parent node passed.
1374     -- the or condition for the where clause is such to cover any parent
1375     -- existance with the current relationships time period and any parent's
1376     -- time period.
1377     CURSOR c_get_all_parents IS
1378         SELECT PARENT_ID,
1379                PARENT_TABLE_NAME,
1380                PARENT_OBJECT_TYPE,
1381                LEVEL_NUMBER,
1382                TOP_PARENT_FLAG,
1383                EFFECTIVE_START_DATE,
1384                EFFECTIVE_END_DATE
1385         FROM   HZ_HIERARCHY_NODES
1386         WHERE  CHILD_ID = p_hierarchy_node_rec.parent_id
1387         AND    CHILD_TABLE_NAME = p_hierarchy_node_rec.parent_table_name
1388         AND    CHILD_OBJECT_TYPE = p_hierarchy_node_rec.parent_object_type
1389         AND    HIERARCHY_TYPE = p_hierarchy_node_rec.hierarchy_type
1390         AND    (EFFECTIVE_START_DATE BETWEEN l_existing_start_date AND l_existing_end_date
1391                 OR
1392                 EFFECTIVE_END_DATE BETWEEN l_existing_start_date AND l_existing_end_date
1393                 OR
1394                 l_existing_start_date BETWEEN EFFECTIVE_START_DATE AND EFFECTIVE_END_DATE
1395                 OR
1396                 l_existing_end_date BETWEEN EFFECTIVE_START_DATE AND EFFECTIVE_END_DATE
1397                )
1398         -- AND    NVL(RELATIONSHIP_ID, p_hierarchy_node_rec.relationship_id) = p_hierarchy_node_rec.relationship_id
1399         ORDER BY LEVEL_NUMBER ASC;
1400 
1401     r_get_all_parents     c_get_all_parents%ROWTYPE;
1402 
1403     -- this cursor retrieves all the children of the child node passed.
1404     -- the or condition for the where clause is such to cover any parent
1405     -- existance with the current relationships time period and any parent's
1406     -- time period.
1407     CURSOR c_get_all_children IS
1408         SELECT CHILD_ID,
1409                CHILD_TABLE_NAME,
1410                CHILD_OBJECT_TYPE,
1411                LEVEL_NUMBER,
1412                LEAF_CHILD_FLAG,
1413                EFFECTIVE_START_DATE,
1414                EFFECTIVE_END_DATE
1415         FROM   HZ_HIERARCHY_NODES
1416         WHERE  PARENT_ID = p_hierarchy_node_rec.child_id
1417         AND    PARENT_TABLE_NAME = p_hierarchy_node_rec.child_table_name
1418         AND    PARENT_OBJECT_TYPE = p_hierarchy_node_rec.child_object_type
1419         AND    HIERARCHY_TYPE = p_hierarchy_node_rec.hierarchy_type
1420         AND    (EFFECTIVE_START_DATE BETWEEN l_existing_start_date AND l_existing_end_date
1421                 OR
1422                 EFFECTIVE_END_DATE BETWEEN l_existing_start_date AND l_existing_end_date
1423                 OR
1424                 l_existing_start_date BETWEEN EFFECTIVE_START_DATE AND EFFECTIVE_END_DATE
1425                 OR
1426                 l_existing_end_date BETWEEN EFFECTIVE_START_DATE AND EFFECTIVE_END_DATE
1427                )
1428         -- AND    NVL(RELATIONSHIP_ID, p_hierarchy_node_rec.relationship_id) = p_hierarchy_node_rec.relationship_id
1429         ORDER BY LEVEL_NUMBER ASC;
1430 
1431     r_get_all_children     c_get_all_children%ROWTYPE;
1432     l_child_rec_count_p    NUMBER;
1433     l_child_rec_count_c    NUMBER;
1434     l_parent_rec_count_p   NUMBER;
1435     l_parent_rec_count_c   NUMBER;
1436 */
1437 
1438 BEGIN
1439 
1440 /* -- Moved below logic into procedure do_update_link_pvt for Bug 4662744 (Nishant 30-Mar-2006)
1441    -- End dating of hierarchy in case of multiple parents was not correct
1442 
1443   Select EFFECTIVE_START_DATE,EFFECTIVE_END_DATE into l_existing_start_date,l_existing_end_date
1444       from HZ_HIERARCHY_NODES
1445       where PARENT_ID=p_hierarchy_node_rec.parent_id
1446          AND CHILD_ID=p_hierarchy_node_rec.child_id
1447          AND LEVEL_NUMBER=1
1448          AND RELATIONSHIP_ID=p_hierarchy_node_rec.relationship_id ;
1449 
1450     -- let's assume the effective dates of AAA->BBB are being updated
1451     -- assumption : start_date and end_date is always passed by relationship api
1452 
1453     -------------------
1454     -- LINK MAINTENANCE
1455     -------------------
1456 
1457     -- get all the parents of AAA including itself
1458     OPEN c_get_all_parents;
1459     FETCH c_get_all_parents INTO r_get_all_parents;
1460 
1461     -- loop through all the parents
1462     WHILE c_get_all_parents%FOUND
1463     LOOP
1464         -- we open the cursor to get all the children of BBB (this will include BBB itself)
1465         OPEN c_get_all_children;
1466         FETCH c_get_all_children INTO r_get_all_children;
1467 
1468         WHILE c_get_all_children%FOUND
1469         -- let's call it YYY
1470         LOOP
1471             UPDATE HZ_HIERARCHY_NODES
1472             SET EFFECTIVE_START_DATE = NVL(p_hierarchy_node_rec.effective_start_date, EFFECTIVE_START_DATE),
1473                 EFFECTIVE_END_DATE = NVL(p_hierarchy_node_rec.effective_end_date, EFFECTIVE_END_DATE),
1474                 LAST_UPDATED_BY = HZ_UTILITY_V2PUB.last_updated_by,
1478             AND   PARENT_TABLE_NAME = r_get_all_parents.parent_table_name
1475 		LAST_UPDATE_DATE = HZ_UTILITY_V2PUB.last_update_date,
1476                 LAST_UPDATE_LOGIN = HZ_UTILITY_V2PUB.last_update_login
1477             WHERE PARENT_ID = r_get_all_parents.parent_id
1479             AND   PARENT_OBJECT_TYPE = r_get_all_parents.parent_object_type
1480             AND   CHILD_ID = r_get_all_children.child_id
1481             AND   CHILD_TABLE_NAME = r_get_all_children.child_table_name
1482             AND   CHILD_OBJECT_TYPE = r_get_all_children.child_object_type
1483             AND   HIERARCHY_TYPE = p_hierarchy_node_rec.hierarchy_type
1484             AND   (EFFECTIVE_START_DATE BETWEEN l_existing_start_date AND l_existing_end_date
1485                    OR
1486                    EFFECTIVE_END_DATE BETWEEN l_existing_start_date AND l_existing_end_date
1487                    OR
1488                    l_existing_start_date BETWEEN EFFECTIVE_START_DATE AND EFFECTIVE_END_DATE
1489                    OR
1490                    l_existing_end_date BETWEEN EFFECTIVE_START_DATE AND EFFECTIVE_END_DATE
1491                   );
1492 
1493             FETCH c_get_all_children INTO r_get_all_children;
1494         END LOOP;
1495         CLOSE c_get_all_children;
1496         FETCH c_get_all_parents INTO r_get_all_parents;
1497     END LOOP;
1498     CLOSE c_get_all_parents;
1499 */
1500 
1501     -------------------
1502     -- LINK MAINTENANCE
1503     -- Replaced above code with procedure do_update_link_pvt (Bug 4662744 (Nishant 30-Mar-2006))
1504     -------------------
1505      do_update_link_pvt(p_hierarchy_node_rec);
1506 
1507 
1508     ---------------------------------
1509     -- PARENT'S SELF NODE MAINTENANCE
1510     ---------------------------------
1511     maintain_self_node (
1512         p_node_id            => p_hierarchy_node_rec.parent_id,
1513         p_hierarchy_type     => p_hierarchy_node_rec.hierarchy_type,
1514         p_table_name         => p_hierarchy_node_rec.parent_table_name,
1515         p_object_type        => p_hierarchy_node_rec.parent_object_type,
1516         p_actual_content_source => p_hierarchy_node_rec.actual_content_source
1517     );
1518 
1519 
1520     --------------------------------
1521     -- CHILD'S SELF NODE MAINTENANCE
1522     --------------------------------
1523     maintain_self_node (
1524         p_node_id            => p_hierarchy_node_rec.child_id,
1525         p_hierarchy_type     => p_hierarchy_node_rec.hierarchy_type,
1526         p_table_name         => p_hierarchy_node_rec.child_table_name,
1527         p_object_type        => p_hierarchy_node_rec.child_object_type,
1528         p_actual_content_source => p_hierarchy_node_rec.actual_content_source
1529     );
1530 
1531 
1532 END do_update_link;
1533 
1534 
1535 /**********************************
1536 ******   Public Procedures ********
1537 ***********************************/
1538 
1539 /**
1540  * PROCEDURE create_link
1541  *
1542  * DESCRIPTION
1543  *     Creates a hierarchial relationship between two nodes.
1544  *
1545  * EXTERNAL PROCEDURES/FUNCTIONS ACCESSED
1546  *
1547  * ARGUMENTS
1548  *   IN:
1549  *     p_init_msg_list                Initialize message stack if it is set to
1550  *                                    FND_API.G_TRUE. Default is FND_API.G_FALSE.
1551  *     p_hierarchy_node_rec           Hierarchy node record.
1552  *   IN/OUT:
1553  *   OUT:
1554  *     x_return_status                Return status after the call. The status can
1555  *                                    be FND_API.G_RET_STS_SUCCESS (success),
1556  *                                    FND_API.G_RET_STS_ERROR (error),
1557  *                                    FND_API.G_RET_STS_UNEXP_ERROR (unexpected error).
1558  *     x_msg_count                    Number of messages in message stack.
1559  *     x_msg_data                     Message text if x_msg_count is 1.
1560  *
1561  * NOTES
1562  *
1563  * MODIFICATION HISTORY
1564  *
1565  *    31-JAN-00  Indrajit Sen   o Created
1566  *
1567  */
1568 
1569 PROCEDURE create_link(
1570     p_init_msg_list                         IN         VARCHAR2 := FND_API.G_FALSE,
1571     p_hierarchy_node_rec                    IN         HIERARCHY_NODE_REC_TYPE,
1572     x_return_status                         OUT NOCOPY VARCHAR2,
1573     x_msg_count                             OUT NOCOPY NUMBER,
1574     x_msg_data                              OUT NOCOPY VARCHAR2
1575 ) IS
1576 l_debug_prefix		       VARCHAR2(30) := '';
1577 BEGIN
1578     -- standard start of API savepoint
1579     SAVEPOINT create_link;
1580     -- Check if API is called in debug mode. If yes, enable debug.
1581     --enable_debug;
1582 
1583     -- Debug info.
1584     IF fnd_log.level_procedure>=fnd_log.g_current_runtime_level THEN
1585 	hz_utility_v2pub.debug(p_message=>'create_link (+)',
1586 	                       p_prefix=>l_debug_prefix,
1587 			       p_msg_level=>fnd_log.level_procedure);
1588     END IF;
1589 
1590     -- initialize message list if p_init_msg_list is set to TRUE.
1591     IF FND_API.to_Boolean(p_init_msg_list) THEN
1592         FND_MSG_PUB.initialize;
1593     END IF;
1594 
1595     -- initialize API return status to success.
1596     x_return_status := FND_API.G_RET_STS_SUCCESS;
1597 
1598     do_create_link(p_hierarchy_node_rec,
1599                    x_return_status);
1600 
1601      --Standard call to get message count and if count is 1, get message info.
1602     FND_MSG_PUB.Count_And_Get(
1606 
1603         p_encoded => FND_API.G_FALSE,
1604         p_count => x_msg_count,
1605         p_data  => x_msg_data);
1607     -- Debug info.
1608     IF fnd_log.level_exception>=fnd_log.g_current_runtime_level THEN
1609 	 hz_utility_v2pub.debug_return_messages(p_msg_count=>x_msg_count,
1610 	                       p_msg_data=>x_msg_data,
1611 			       p_msg_type=>'WARNING',
1612 			       p_msg_level=>fnd_log.level_exception);
1613     END IF;
1614     IF fnd_log.level_procedure>=fnd_log.g_current_runtime_level THEN
1615 	hz_utility_v2pub.debug(p_message=>'create_link (-)',
1616 	                       p_prefix=>l_debug_prefix,
1617 			       p_msg_level=>fnd_log.level_procedure);
1618     END IF;
1619 
1620 
1621     -- Check if API is called in debug mode. If yes, disable debug.
1622     --disable_debug;
1623 
1624 EXCEPTION
1625     WHEN FND_API.G_EXC_ERROR THEN
1626         ROLLBACK TO create_link;
1627         x_return_status := FND_API.G_RET_STS_ERROR;
1628         FND_MSG_PUB.Count_And_Get(
1629             p_encoded => FND_API.G_FALSE,
1630             p_count => x_msg_count,
1631             p_data  => x_msg_data);
1632 
1633         -- Debug info.
1634       IF fnd_log.level_error >= fnd_log.g_current_runtime_level THEN
1635         hz_utility_v2pub.debug_return_messages(p_msg_count=>x_msg_count,
1636                                p_msg_data=>x_msg_data,
1637                                p_msg_type=>'ERROR',
1638                                p_msg_level=>fnd_log.level_error);
1639       END IF;
1640 
1641     IF fnd_log.level_procedure>=fnd_log.g_current_runtime_level THEN
1642 	hz_utility_v2pub.debug(p_message=> 'l_line_number = '||l_line_number||' create_link (-)' ,
1643 	                       p_prefix=>l_debug_prefix,
1644 			       p_msg_level=>fnd_log.level_procedure);
1645     END IF;
1646 
1647 
1648     WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
1649         ROLLBACK TO create_link;
1650         x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
1651         FND_MSG_PUB.Count_And_Get(
1652             p_encoded => FND_API.G_FALSE,
1653             p_count => x_msg_count,
1654             p_data  => x_msg_data);
1655 
1656         -- Debug info.
1657         IF fnd_log.level_error >= fnd_log.g_current_runtime_level THEN
1658         hz_utility_v2pub.debug_return_messages(p_msg_count=>x_msg_count,
1659                                p_msg_data=>x_msg_data,
1660                                p_msg_type=>'ERROR',
1661                                p_msg_level=>fnd_log.level_error);
1662         END IF;
1663 
1664         IF fnd_log.level_procedure>=fnd_log.g_current_runtime_level THEN
1665 	hz_utility_v2pub.debug(p_message=> 'l_line_number = '||l_line_number||' create_link (-)' ,
1666 	                       p_prefix=>l_debug_prefix,
1667 			       p_msg_level=>fnd_log.level_procedure);
1668         END IF;
1669 
1670 
1671     WHEN OTHERS THEN
1672         ROLLBACK TO create_link;
1673         x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
1674         FND_MESSAGE.SET_NAME('AR', 'HZ_API_OTHERS_EXCEP');
1675         FND_MESSAGE.SET_TOKEN('ERROR' ,SQLERRM);
1676         FND_MSG_PUB.ADD;
1677         FND_MSG_PUB.Count_And_Get(
1678             p_encoded => FND_API.G_FALSE,
1679             p_count => x_msg_count,
1680             p_data  => x_msg_data);
1681 
1682         -- Debug info.
1683         IF fnd_log.level_error >= fnd_log.g_current_runtime_level THEN
1684         hz_utility_v2pub.debug_return_messages(p_msg_count=>x_msg_count,
1685                                p_msg_data=>x_msg_data,
1686                                p_msg_type=>'ERROR',
1687                                p_msg_level=>fnd_log.level_error);
1688         END IF;
1689 
1690         IF fnd_log.level_procedure>=fnd_log.g_current_runtime_level THEN
1691 	hz_utility_v2pub.debug(p_message=> 'l_line_number = '||l_line_number||' create_link (-)' ,
1692 	                       p_prefix=>l_debug_prefix,
1693 			       p_msg_level=>fnd_log.level_procedure);
1694         END IF;
1695 
1696 
1697 END create_link;
1698 
1699 
1700 /**
1701  * PROCEDURE update_link
1702  *
1703  * DESCRIPTION
1704  *     Updates a hierarchial relationship between two nodes.
1705  *
1706  * EXTERNAL PROCEDURES/FUNCTIONS ACCESSED
1707  *
1708  * ARGUMENTS
1709  *   IN:
1710  *     p_init_msg_list                Initialize message stack if it is set to
1711  *                                    FND_API.G_TRUE. Default is FND_API.G_FALSE.
1712  *     p_hierarchy_node_rec           Hierarchy node record.
1713  *   IN/OUT:
1714  *   OUT:
1715  *     x_return_status                Return status after the call. The status can
1716  *                                    be FND_API.G_RET_STS_SUCCESS (success),
1717  *                                    FND_API.G_RET_STS_ERROR (error),
1718  *                                    FND_API.G_RET_STS_UNEXP_ERROR (unexpected error).
1719  *     x_msg_count                    Number of messages in message stack.
1720  *     x_msg_data                     Message text if x_msg_count is 1.
1721  *
1722  * NOTES
1723  *
1724  * MODIFICATION HISTORY
1725  *
1726  *    31-JAN-00  Indrajit Sen   o Created
1727  *
1728  */
1729 
1730 PROCEDURE update_link(
1731     p_init_msg_list                         IN         VARCHAR2 := FND_API.G_FALSE,
1732     p_hierarchy_node_rec                    IN         HIERARCHY_NODE_REC_TYPE,
1736 ) IS
1733     x_return_status                         OUT NOCOPY VARCHAR2,
1734     x_msg_count                             OUT NOCOPY NUMBER,
1735     x_msg_data                              OUT NOCOPY VARCHAR2
1737 l_debug_prefix		       VARCHAR2(30) := '';
1738 BEGIN
1739     -- standard start of API savepoint
1740     SAVEPOINT update_link;
1741 
1742     -- Check if API is called in debug mode. If yes, enable debug.
1743     --enable_debug;
1744 
1745     -- Debug info.
1746     IF fnd_log.level_procedure>=fnd_log.g_current_runtime_level THEN
1747 	hz_utility_v2pub.debug(p_message=>'update_link (+)',
1748 	                       p_prefix=>l_debug_prefix,
1749 			       p_msg_level=>fnd_log.level_procedure);
1750     END IF;
1751 
1752     -- initialize message list if p_init_msg_list is set to TRUE.
1753     IF FND_API.to_Boolean(p_init_msg_list) THEN
1754         FND_MSG_PUB.initialize;
1755     END IF;
1756 
1757     -- initialize API return status to success.
1758     x_return_status := FND_API.G_RET_STS_SUCCESS;
1759 
1760     do_update_link(p_hierarchy_node_rec,
1761                    x_return_status);
1762 
1763      --Standard call to get message count and if count is 1, get message info.
1764     FND_MSG_PUB.Count_And_Get(
1765         p_encoded => FND_API.G_FALSE,
1766         p_count => x_msg_count,
1767         p_data  => x_msg_data);
1768 
1769     -- Debug info.
1770     IF fnd_log.level_exception>=fnd_log.g_current_runtime_level THEN
1771 	 hz_utility_v2pub.debug_return_messages(p_msg_count=>x_msg_count,
1772 	                       p_msg_data=>x_msg_data,
1773 			       p_msg_type=>'WARNING',
1774 			       p_msg_level=>fnd_log.level_exception);
1775     END IF;
1776     IF fnd_log.level_procedure>=fnd_log.g_current_runtime_level THEN
1777 	hz_utility_v2pub.debug(p_message=>'update_link (-)',
1778 	                       p_prefix=>l_debug_prefix,
1779 			       p_msg_level=>fnd_log.level_procedure);
1780     END IF;
1781 
1782     -- Check if API is called in debug mode. If yes, disable debug.
1783     --disable_debug;
1784 
1785 EXCEPTION
1786     WHEN FND_API.G_EXC_ERROR THEN
1787         ROLLBACK TO update_link;
1788         x_return_status := FND_API.G_RET_STS_ERROR;
1789         FND_MSG_PUB.Count_And_Get(
1790             p_encoded => FND_API.G_FALSE,
1791             p_count => x_msg_count,
1792             p_data  => x_msg_data);
1793 
1794         -- Debug info.
1795         IF fnd_log.level_error >= fnd_log.g_current_runtime_level THEN
1796         hz_utility_v2pub.debug_return_messages(p_msg_count=>x_msg_count,
1797                                p_msg_data=>x_msg_data,
1798                                p_msg_type=>'ERROR',
1799                                p_msg_level=>fnd_log.level_error);
1800         END IF;
1801 
1802         IF fnd_log.level_procedure>=fnd_log.g_current_runtime_level THEN
1803 	hz_utility_v2pub.debug(p_message=> 'l_line_number = '||l_line_number||' update_link (-)' ,
1804 	                       p_prefix=>l_debug_prefix,
1805 			       p_msg_level=>fnd_log.level_procedure);
1806 
1807         END IF;
1808 
1809     WHEN FND_API.G_EXC_UNEXPECTED_ERROR THEN
1810         ROLLBACK TO update_link;
1811         x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
1812         FND_MSG_PUB.Count_And_Get(
1813             p_encoded => FND_API.G_FALSE,
1814             p_count => x_msg_count,
1815             p_data  => x_msg_data);
1816 
1817         -- Debug info.
1818         IF fnd_log.level_error >= fnd_log.g_current_runtime_level THEN
1819         hz_utility_v2pub.debug_return_messages(p_msg_count=>x_msg_count,
1820                                p_msg_data=>x_msg_data,
1821                                p_msg_type=>'ERROR',
1822                                p_msg_level=>fnd_log.level_error);
1823         END IF;
1824 
1825         IF fnd_log.level_procedure>=fnd_log.g_current_runtime_level THEN
1826 	hz_utility_v2pub.debug(p_message=> 'l_line_number = '||l_line_number||' update_link (-)' ,
1827 	                       p_prefix=>l_debug_prefix,
1828 			       p_msg_level=>fnd_log.level_procedure);
1829         END IF;
1830 
1831 
1832     WHEN OTHERS THEN
1833         ROLLBACK TO update_link;
1834         x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
1835         FND_MESSAGE.SET_NAME('AR', 'HZ_API_OTHERS_EXCEP');
1836         FND_MESSAGE.SET_TOKEN('ERROR' ,SQLERRM);
1837         FND_MSG_PUB.ADD;
1838         FND_MSG_PUB.Count_And_Get(
1839             p_encoded => FND_API.G_FALSE,
1840             p_count => x_msg_count,
1841             p_data  => x_msg_data);
1842 
1843         -- Debug info.
1844         IF fnd_log.level_error >= fnd_log.g_current_runtime_level THEN
1845         hz_utility_v2pub.debug_return_messages(p_msg_count=>x_msg_count,
1846                                p_msg_data=>x_msg_data,
1847                                p_msg_type=>'ERROR',
1848                                p_msg_level=>fnd_log.level_error);
1849         END IF;
1850 
1851         IF fnd_log.level_procedure>=fnd_log.g_current_runtime_level THEN
1852 	hz_utility_v2pub.debug(p_message=> 'l_line_number = '||l_line_number||' update_link (-)' ,
1853 	                       p_prefix=>l_debug_prefix,
1854 			       p_msg_level=>fnd_log.level_procedure);
1855 
1856         END IF;
1857 
1858 END update_link;
1859 
1860 /**
1861  * PROCEDURE
1865  *     Procedure to convert a particular relationship type
1862  *     convert_rel_type
1863  *
1864  * DESCRIPTION
1866  *     to a hierarchical relationship type
1867  *
1868  * SCOPE - Public
1869  *
1870  * ARGUMENTS  : IN:
1871  *                       p_rel_type
1872  *                       p_multi_parent_allowed
1873  *                       p_incl_unrelated_entities
1874  *              OUT:
1875  *          IN/ OUT:
1876  *
1877  * RETURNS    :
1878  *                       Errbuf
1879  *                       Retcode
1880  *
1881  * NOTES      : p_rel_type can be non-hierarchical relationship type
1882  *              p_multi_parent_allowed is Y/N
1883  *              p_incl_unrelated_entities is Y/N
1884  *
1885  * MODIFICATION HISTORY
1886  *
1887  *    31-JAN-00  Indrajit Sen   o Created
1888 
1889  *
1890  */
1891 
1892 PROCEDURE convert_rel_type(
1893     errbuf                                  OUT NOCOPY VARCHAR2,
1894     Retcode                                 OUT NOCOPY VARCHAR2,
1895     p_rel_type                              IN         VARCHAR2,
1896     p_multi_parent_allowed                  IN         VARCHAR2,
1897     p_incl_unrelated_entities               IN         VARCHAR2
1898 )
1899 IS
1900     CURSOR c1 IS
1901     SELECT a.ROWID row_id, a.*
1902     FROM   HZ_RELATIONSHIPS a
1903     WHERE  RELATIONSHIP_TYPE = p_rel_type
1904     ORDER BY RELATIONSHIP_ID;
1905 
1906     CURSOR c2 (p_rel_type       VARCHAR2,
1907                p_forward_rel_code    VARCHAR2,
1908                p_subject_type        VARCHAR2,
1909                p_object_type         VARCHAR2)
1910     IS
1911     SELECT *
1912     FROM   HZ_RELATIONSHIP_TYPES
1913     WHERE  RELATIONSHIP_TYPE = p_rel_type
1914     AND    FORWARD_REL_CODE = p_forward_rel_code
1915     AND    SUBJECT_TYPE = p_subject_type
1916     AND    OBJECT_TYPE = p_object_type;
1917 
1918     -- this cursor retrieves a parent for a given child in a particular hierarchy.
1919     -- it will be used for circularity check.
1920     CURSOR c_parent (p_child_id NUMBER, p_child_table_name VARCHAR2, p_child_object_type VARCHAR2,
1921                      p_rel_type VARCHAR2, p_start_date DATE, p_end_date DATE)
1922     IS
1923     SELECT SUBJECT_ID,
1924            SUBJECT_TABLE_NAME,
1925            SUBJECT_TYPE
1926     FROM   HZ_RELATIONSHIPS
1927     WHERE  OBJECT_ID = p_child_id
1928     AND    OBJECT_TABLE_NAME = p_child_table_name
1929     AND    OBJECT_TYPE = p_child_object_type
1930     AND    RELATIONSHIP_TYPE = p_rel_type
1931     AND    DIRECTION_CODE = 'P'
1932     AND    (START_DATE BETWEEN NVL(p_start_date, SYSDATE)
1933                           AND NVL(p_end_date, TO_DATE('31-12-4712 00:00:01', 'DD-MM-YYYY HH24:MI:SS'))
1934            OR
1935            END_DATE BETWEEN NVL(p_start_date, SYSDATE)
1936                           AND NVL(p_end_date, TO_DATE('31-12-4712 00:00:01', 'DD-MM-YYYY HH24:MI:SS'))
1937            OR
1938            NVL(p_start_date, SYSDATE) BETWEEN START_DATE AND END_DATE
1939            OR
1940            NVL(p_end_date, TO_DATE('31-12-4712 00:00:01', 'DD-MM-YYYY HH24:MI:SS')) BETWEEN START_DATE AND END_DATE
1941            );
1942 
1943     r1                                c1%ROWTYPE;
1944     r2                                c2%ROWTYPE;
1945     r_parent                          c_parent%ROWTYPE;
1946     l_hierarchy_rec                   HZ_HIERARCHY_PUB.HIERARCHY_NODE_REC_TYPE;
1947     l_return_status                   VARCHAR2(1);
1948     l_msg_count                       NUMBER;
1949     l_msg_data                        VARCHAR2(2000);
1950     l_count                           NUMBER;
1951     l_parent_id                       NUMBER;
1952     l_parent_object_type              VARCHAR2(30);
1953     l_parent_table_name               VARCHAR2(30);
1954     l_child_id                        NUMBER;
1955     l_child_object_type               VARCHAR2(30);
1956     l_child_table_name                VARCHAR2(30);
1957     l_temp_parent_id                  NUMBER;
1958     l_temp_parent_table_name          VARCHAR2(30);
1959     l_temp_parent_object_type         VARCHAR2(30);
1960     l_parent_flag                     VARCHAR2(1);
1961     l_conc_status                     VARCHAR2(1) := 'S';
1962 
1963 
1964 
1965 BEGIN
1966 
1967     FND_FILE.PUT_LINE (FND_FILE.LOG, 'Concurrent program ARHCRTHI - Convert relationship type to hierarchical.');
1968     FND_FILE.PUT_LINE (FND_FILE.LOG, ' ');
1969     FND_FILE.PUT_LINE (FND_FILE.LOG, 'Options - ');
1970     FND_FILE.PUT_LINE (FND_FILE.LOG, 'Relationship type : '||p_rel_type);
1971     FND_FILE.PUT_LINE (FND_FILE.LOG, 'Multiple parent allowed : '||p_multi_parent_allowed);
1972     FND_FILE.PUT_LINE (FND_FILE.LOG, 'Include unrelated entities : '||p_incl_unrelated_entities);
1973     FND_FILE.PUT_LINE (FND_FILE.LOG, ' ');
1974 
1975     -- get all the relationships for this relationship type
1976     OPEN c1;
1977     FETCH c1 INTO r1;
1978 
1979     WHILE c1%FOUND LOOP
1980         -- get the relationship type to determine parent/child
1981         OPEN c2(r1.relationship_type, r1.relationship_code, r1.subject_type, r1.object_type);
1982         FETCH c2 INTO r2;
1983 
1984         -- decide who is parent and who is child in this relationship.
1985         -- if relationship type record is 'P' type, then subject is parent, else object
1986         IF r2.direction_code = 'P' THEN
1990             l_child_id := r1.object_id;
1987             l_parent_id := r1.subject_id;
1988             l_parent_table_name := r1.subject_table_name;
1989             l_parent_object_type := r1.subject_type;
1991             l_child_table_name := r1.object_table_name;
1992             l_child_object_type := r1.object_type;
1993         ELSIF r2.direction_code = 'C' THEN
1994             l_parent_id := r1.object_id;
1995             l_parent_table_name := r1.object_table_name;
1996             l_parent_object_type := r1.object_type;
1997             l_child_id := r1.subject_id;
1998             l_child_table_name := r1.subject_table_name;
1999             l_child_object_type := r1.subject_type;
2000         END IF;
2001 
2002         IF p_multi_parent_allowed = 'N' THEN
2003             BEGIN
2004                 SELECT 1 INTO l_count
2005                 FROM   HZ_RELATIONSHIPS
2006                 WHERE  OBJECT_ID = l_child_id
2007                 AND    OBJECT_TABLE_NAME = l_child_table_name
2008                 AND    OBJECT_TYPE = l_child_object_type
2009                 AND    RELATIONSHIP_TYPE = r1.relationship_type
2010                 AND    DIRECTION_CODE = 'P'
2011                 AND    (START_DATE BETWEEN NVL(r1.start_date, SYSDATE)
2012                                       AND NVL(r1.end_date, TO_DATE('31-12-4712 00:00:01', 'DD-MM-YYYY HH24:MI:SS'))
2013                        OR
2014                        END_DATE BETWEEN NVL(r1.start_date, SYSDATE)
2015                                       AND NVL(r1.end_date, TO_DATE('31-12-4712 00:00:01', 'DD-MM-YYYY HH24:MI:SS'))
2016                        OR
2017                        NVL(r1.start_date, SYSDATE) BETWEEN START_DATE AND END_DATE
2018                        OR
2019                        NVL(r1.end_date, TO_DATE('31-12-4712 00:00:01', 'DD-MM-YYYY HH24:MI:SS')) BETWEEN START_DATE AND END_DATE
2020                        );
2021 
2022             EXCEPTION
2023                 WHEN NO_DATA_FOUND THEN
2024                     -- no parent found, proceed
2025                     NULL;
2026                 WHEN TOO_MANY_ROWS then
2027                     -- there is already a parent, so raise error
2028                     FND_FILE.PUT_LINE (FND_FILE.LOG, ' ');
2029                     FND_FILE.PUT_LINE (FND_FILE.LOG, 'Multiple parent found for the following child :');
2030                     FND_FILE.PUT_LINE (FND_FILE.LOG, 'Child ID : '||l_child_id);
2031                     FND_FILE.PUT_LINE (FND_FILE.LOG, 'Chiild Type : '||l_child_object_type);
2032                     FND_FILE.PUT_LINE (FND_FILE.LOG, ' ');
2033                     l_conc_status := 'E';
2034                     EXIT;
2035             END;
2036         END IF;
2037 
2038         -- Check for circular relationships in the hierarchy.
2039         -- If circularity is found, reported as error.
2040         l_parent_flag := 'Y';
2041         l_temp_parent_id := l_parent_id;
2042         l_temp_parent_table_name := l_parent_table_name;
2043         l_temp_parent_object_type := l_parent_object_type;
2044         WHILE l_parent_flag <> 'N' LOOP
2045             OPEN c_parent (l_temp_parent_id, l_temp_parent_table_name, l_temp_parent_object_type, r1.relationship_type, r1.start_date, r1.end_date);
2046             FETCH c_parent INTO r_parent;
2047             IF c_parent%NOTFOUND THEN
2048                 l_parent_flag := 'N';
2049             ELSE
2050                 l_temp_parent_id := r_parent.subject_id;
2051                 l_temp_parent_table_name := r_parent.subject_table_name;
2052                 l_temp_parent_object_type := r_parent.subject_type;
2053             END IF;
2054             IF l_temp_parent_id = l_child_id THEN
2055                 FND_FILE.PUT_LINE (FND_FILE.LOG, ' ');
2056                 FND_FILE.PUT_LINE (FND_FILE.LOG, 'Circularity exists for the following relationship record : ');
2057                 FND_FILE.PUT_LINE (FND_FILE.LOG, 'Subject ID : '||r1.subject_id);
2058                 FND_FILE.PUT_LINE (FND_FILE.LOG, 'Subject Type : '||r1.subject_type);
2059                 FND_FILE.PUT_LINE (FND_FILE.LOG, 'Object ID : '||r1.object_id);
2060                 FND_FILE.PUT_LINE (FND_FILE.LOG, 'Object Type : '||r1.object_type);
2061                 FND_FILE.PUT_LINE (FND_FILE.LOG, 'Relationship Code : '||r1.relationship_code);
2062                 FND_FILE.PUT_LINE (FND_FILE.LOG, ' ');
2063                 l_conc_status := 'E';
2064                 CLOSE c_parent;
2065                 EXIT;
2066             END IF;
2067             CLOSE c_parent;
2068         END LOOP;
2069 
2070         IF r2.direction_code = 'P' THEN
2071             -- record is the parent record
2072             -- assign the subject to parent for hierarchy
2073             l_hierarchy_rec.hierarchy_type := r1.relationship_type;
2074             l_hierarchy_rec.parent_id := r1.subject_id;
2075             l_hierarchy_rec.parent_table_name := r1.subject_table_name;
2076             l_hierarchy_rec.parent_object_type := r1.subject_type;
2077             l_hierarchy_rec.child_id := r1.object_id;
2078             l_hierarchy_rec.child_table_name := r1.object_table_name;
2079             l_hierarchy_rec.child_object_type := r1.object_type;
2080             l_hierarchy_rec.effective_start_date := r1.start_date;
2081             l_hierarchy_rec.effective_end_date := NVL(r1.end_date, TO_DATE('31-12-4712 00:00:01', 'DD-MM-YYYY HH24:MI:SS'));
2082             l_hierarchy_rec.relationship_id := r1.relationship_id;
2083             l_hierarchy_rec.status := NVL(r1.status, 'A');
2084         ELSE
2085             -- record is the child record
2086             -- assign the object to parent
2087             l_hierarchy_rec.hierarchy_type := r1.relationship_type;
2088             l_hierarchy_rec.parent_id := r1.object_id;
2089             l_hierarchy_rec.parent_table_name := r1.object_table_name;
2090             l_hierarchy_rec.parent_object_type := r1.object_type;
2091             l_hierarchy_rec.child_id := r1.subject_id;
2092             l_hierarchy_rec.child_table_name := r1.subject_table_name;
2093             l_hierarchy_rec.child_object_type := r1.subject_type;
2094             l_hierarchy_rec.effective_start_date := r1.start_date;
2095             l_hierarchy_rec.effective_end_date := NVL(r1.end_date, TO_DATE('31-12-4712 00:00:01', 'DD-MM-YYYY HH24:MI:SS'));
2096             l_hierarchy_rec.relationship_id := r1.relationship_id;
2097             l_hierarchy_rec.status := NVL(r1.status, 'A');
2098         END IF;
2099 
2100         HZ_HIERARCHY_PUB.create_link(
2101             p_init_msg_list           => FND_API.G_FALSE,
2102             p_hierarchy_node_rec      => l_hierarchy_rec,
2103             x_return_status           => l_return_status,
2104             x_msg_count               => l_msg_count,
2105             x_msg_data                => l_msg_data
2106            );
2107 
2108         CLOSE c2;
2109 
2110         IF r2.direction_code = 'P' THEN
2111             UPDATE HZ_RELATIONSHIPS SET DIRECTION_CODE = 'P' WHERE ROWID = r1.row_id;
2112         ELSE
2113             UPDATE HZ_RELATIONSHIPS SET DIRECTION_CODE = 'C' WHERE ROWID = r1.row_id;
2114         END IF;
2115 
2116         -- one call is to by-pass the second record which is identical but reverse one.
2117         FETCH c1 INTO r1;
2118         IF r2.direction_code = 'P' THEN
2119             UPDATE HZ_RELATIONSHIPS SET DIRECTION_CODE = 'C' WHERE ROWID = r1.row_id;
2120         ELSE
2121             UPDATE HZ_RELATIONSHIPS SET DIRECTION_CODE = 'P' WHERE ROWID = r1.row_id;
2122         END IF;
2123 
2124         FETCH c1 INTO r1;
2125 
2126     END LOOP;
2127 
2128     CLOSE c1;
2129 
2130     IF l_conc_status = 'E' THEN
2131         ROLLBACK;
2132         FND_FILE.PUT_LINE (FND_FILE.LOG, ' ');
2133         FND_FILE.PUT_LINE (FND_FILE.LOG, 'Conversion of relationship type to hierarchical failed. ');
2134         FND_FILE.PUT_LINE (FND_FILE.LOG, ' ');
2135     ELSE
2136         UPDATE HZ_RELATIONSHIP_TYPES
2137         SET HIERARCHICAL_FLAG = 'Y',
2138             MULTIPLE_PARENT_ALLOWED = NVL(p_multi_parent_allowed, 'N'),
2139             INCL_UNRELATED_ENTITIES = NVL(p_incl_unrelated_entities, 'N')
2140         WHERE RELATIONSHIP_TYPE = p_rel_type;
2141 
2142         FND_FILE.PUT_LINE (FND_FILE.LOG, ' ');
2143         FND_FILE.PUT_LINE (FND_FILE.LOG, 'Successfully converted relationship type to hierarchical. ');
2144         FND_FILE.PUT_LINE (FND_FILE.LOG, ' ');
2145         COMMIT;
2146     END IF;
2147 
2148 END convert_rel_type;
2149 
2150 END HZ_HIERARCHY_PUB;