DBA Data[Home] [Help]

PACKAGE BODY: APPS.BSC_AW_CALENDAR

Source


1 package body BSC_AW_CALENDAR AS
2 /*$Header: BSCAWCAB.pls 120.18 2006/05/31 20:52:09 vsurendr ship $*/
3 
4 /*
5 given a calendar id, create the aw objects for the calendar.
6 This module will directly read the BSC calendars. will not go through bsc_metadata package
7 This procedure is called when the calendar has to be created...this is first time
8 or when there is a change to the calendar structure itself.
9 if the calendar is extended or the start date changes, this procedure is not called. we simply refresh the
10 calendar load program
11 */
12 procedure create_calendar(p_calendar number,p_options varchar2) is
13 l_affected_kpi dbms_sql.varchar2_table;
14 Begin
15   create_calendar(p_calendar,p_options,l_affected_kpi);
16 Exception when others then
17   log_n('Exception in create_calendar '||sqlerrm);
18   raise;
19 End;
20 
21 procedure create_calendar(
22 p_calendar number,
23 p_options varchar2,
24 p_affected_kpi out nocopy dbms_sql.varchar2_table
25 ) is
26 Begin
27   if p_options is not null then
28     bsc_aw_utility.parse_parameter_values(p_options,',',bsc_aw_utility.g_options);
29     bsc_aw_utility.open_file('TEST');
30     bsc_aw_utility.dmp_g_options(bsc_aw_utility.g_options);
31   end if;
32   init_all;
33   attach_workspace(p_options);
34   create_calendar(p_calendar,p_affected_kpi);
35   --
36   bsc_aw_management.commit_aw;
37   commit;
38   if nvl(bsc_aw_utility.get_parameter_value('NO DETACH WORKSPACE'),'N')='N' then
39     bsc_aw_management.detach_workspace;
40   end if;
41 Exception when others then
42   bsc_aw_management.detach_workspace;
43   log_n('Exception in create_calendar '||sqlerrm);
44   raise;
45 End;
46 
47 procedure create_calendar(p_calendar number,p_affected_kpi out nocopy dbms_sql.varchar2_table) is
48 l_calendar calendar_r;
49 l_create_objects boolean;
50 l_create_program boolean;
51 l_recreate varchar2(40);
52 Begin
53   l_create_objects:=false;
54   l_create_program:=false;
55   l_calendar.calendar_id:=p_calendar;
56   get_bsc_calendar_data(l_calendar);
57   set_aw_object_names(l_calendar);
58   normalize_per_relation(l_calendar);
59   get_kpi_for_calendar(l_calendar);
60   set_calendar_properties(l_calendar);
61   if g_debug then
62     dmp_calendar(l_calendar);
63   end if;
64   check_calendar_create(l_calendar,l_recreate,p_affected_kpi);
65   --if there is no change, then l_recreate is null
66   if l_recreate='create all' then
67     l_create_objects:=true;
68     l_create_program:=true;
69   elsif l_recreate='create program' then
70     l_create_program:=true;
71   end if;
72   bsc_aw_utility.add_sqlerror(-34340,'ignore',null);
73   bsc_aw_utility.add_sqlerror(-36656,'ignore',null);
74   if l_create_objects then
75     create_calendar_objects(l_calendar);
76   end if;
77   if l_create_objects or l_create_program then
78     create_calendar_program(l_calendar);
79   end if;
80   if l_create_objects then
81     create_calendar_metadata(l_calendar);--create in bsc_olap metadata
82   end if;
83   bsc_aw_utility.remove_sqlerror(-34340,'ignore');
84   bsc_aw_utility.remove_sqlerror(-36656,'ignore');
85 Exception when others then
86   log_n('Exception in create_calendar '||sqlerrm);
87   raise;
88 End;
89 
90 /*
91 this sets the properties like dim type=time, multi level etc
92 */
93 procedure set_calendar_properties(p_calendar in out nocopy calendar_r) is
94 Begin
95   p_calendar.property:='calendar='||p_calendar.calendar_id||',dimension type=time,multi level,relation name='||
96   p_calendar.relation_name||',denorm relation name='||p_calendar.denorm_relation_name||
97   ',end period relation name='||p_calendar.end_period_relation_name||',level name dim='||p_calendar.levels_name;
98 Exception when others then
99   log_n('Exception in set_calendar_properties '||sqlerrm);
100   raise;
101 End;
102 
103 procedure get_bsc_calendar_data(
104 p_calendar in out nocopy calendar_r) is
105 --
106 cursor c1(p_calendar number) is
107 select db_column_name,periodicity_id,periodicity_type,source from bsc_sys_periodicities where calendar_id=p_calendar
108 and periodicity_type not in (11,12);
109 --
110 l_count number;
111 Begin
112   l_count:=1;
113   open c1(p_calendar.calendar_id);
114   loop
115     fetch c1 into p_calendar.periodicity(l_count).db_column_name,
116     p_calendar.periodicity(l_count).periodicity_id,p_calendar.periodicity(l_count).periodicity_type,
117     p_calendar.periodicity(l_count).source;
118     exit when c1%notfound;
119     l_count:=l_count+1;
120   end loop;
121 Exception when others then
122   log_n('Exception in get_bsc_calendar_data '||sqlerrm);
123   raise;
124 End;
125 
126 procedure set_aw_object_names(p_calendar in out nocopy calendar_r) is
127 Begin
128   for i in 1..p_calendar.periodicity.count loop
129     p_calendar.periodicity(i).dim_name:=nvl(lower(p_calendar.periodicity(i).db_column_name),'per')||'_'||
130     p_calendar.periodicity(i).periodicity_id||'_cal_'||p_calendar.calendar_id;
131   end loop;
132   --concat dim
133   p_calendar.dim_name:=get_calendar_name(p_calendar.calendar_id);
134   p_calendar.relation_name:=get_calendar_name(p_calendar.calendar_id)||'.rel';
135   p_calendar.denorm_relation_name:=p_calendar.relation_name||'.denorm';
136   p_calendar.end_period_relation_name:=get_calendar_name(p_calendar.calendar_id)||'.rel.end_period';
137   p_calendar.levels_name:=get_calendar_name(p_calendar.calendar_id)||'.levels';
138   p_calendar.end_period_levels_name:=get_calendar_name(p_calendar.calendar_id)||'.end_period_levels';
139   --we create the relations between the bsc periodicities and std periodicities
140   for i in 1..p_calendar.periodicity.count loop
141     if p_calendar.periodicity(i).periodicity_type=9 then
142       p_calendar.periodicity(i).aw_time_dim_name:='aw_day_cal_'||p_calendar.calendar_id;
143       p_calendar.periodicity(i).aw_bsc_aw_rel_name:=p_calendar.periodicity(i).dim_name||'.aw_day.rel'; --given bsc, what is aw?
144       p_calendar.periodicity(i).aw_aw_bsc_rel_name:='aw_day.bsc_calendar_'||p_calendar.calendar_id||'.rel';--given aw, what is bsc time?
145     elsif p_calendar.periodicity(i).periodicity_type=7 then
146       p_calendar.periodicity(i).aw_time_dim_name:='aw_week_cal_'||p_calendar.calendar_id;
147       p_calendar.periodicity(i).aw_bsc_aw_rel_name:=p_calendar.periodicity(i).dim_name||'.aw_week.rel'; --given bsc, what is aw?
148       p_calendar.periodicity(i).aw_aw_bsc_rel_name:='aw_week.bsc_calendar_'||p_calendar.calendar_id||'.rel';--given aw, what is bsc time?
149     elsif p_calendar.periodicity(i).periodicity_type=5 then
150       p_calendar.periodicity(i).aw_time_dim_name:='aw_month_cal_'||p_calendar.calendar_id;
151       p_calendar.periodicity(i).aw_bsc_aw_rel_name:=p_calendar.periodicity(i).dim_name||'.aw_month.rel'; --given bsc, what is aw?
152       p_calendar.periodicity(i).aw_aw_bsc_rel_name:='aw_month.bsc_calendar_'||p_calendar.calendar_id||'.rel';--given aw, what is bsc time?
153     elsif p_calendar.periodicity(i).periodicity_type=3 then
154       p_calendar.periodicity(i).aw_time_dim_name:='aw_quarter_cal_'||p_calendar.calendar_id;
155       p_calendar.periodicity(i).aw_bsc_aw_rel_name:=p_calendar.periodicity(i).dim_name||'.aw_quarter.rel'; --given bsc, what is aw?
156       p_calendar.periodicity(i).aw_aw_bsc_rel_name:='aw_quarter.bsc_calendar_'||p_calendar.calendar_id||'.rel';--given aw, what is bsc time?
157     elsif p_calendar.periodicity(i).periodicity_type=1 then
158       p_calendar.periodicity(i).aw_time_dim_name:='aw_year_cal_'||p_calendar.calendar_id;
159       p_calendar.periodicity(i).aw_bsc_aw_rel_name:=p_calendar.periodicity(i).dim_name||'.aw_year.rel'; --given bsc, what is aw?
160       p_calendar.periodicity(i).aw_aw_bsc_rel_name:='aw_year.bsc_calendar_'||p_calendar.calendar_id||'.rel';--given aw, what is bsc time?
161     end if;
162   end loop;
163   --define cal.period and cal.year. this will be used in the olap table function views
164   p_calendar.misc_object(p_calendar.misc_object.count+1).object_name:='period_cal_'||p_calendar.calendar_id;
165   p_calendar.misc_object(p_calendar.misc_object.count).object_type:='variable';
166   p_calendar.misc_object(p_calendar.misc_object.count).datatype:='number';
167   --
168   p_calendar.misc_object(p_calendar.misc_object.count+1).object_name:='year_cal_'||p_calendar.calendar_id;
169   p_calendar.misc_object(p_calendar.misc_object.count).object_type:='variable';
170   p_calendar.misc_object(p_calendar.misc_object.count).datatype:='number';
171   --
172   p_calendar.misc_object(p_calendar.misc_object.count+1).object_name:='periodicity_cal_'||p_calendar.calendar_id;
173   p_calendar.misc_object(p_calendar.misc_object.count).object_type:='variable';
174   p_calendar.misc_object(p_calendar.misc_object.count).datatype:='number';
175   --
176 Exception when others then
177   log_n('Exception in set_aw_object_names '||sqlerrm);
178   raise;
179 End;
180 
181 procedure create_calendar_objects(
182 p_calendar in out nocopy calendar_r) is
183 --
184 Begin
185   --create the objects
186   --create the aw std periodicities
187   g_stmt:='dfn aw_day_cal_'||p_calendar.calendar_id||' dimension day';
188   bsc_aw_dbms_aw.execute(g_stmt);
189   g_stmt:='dfn aw_week_cal_'||p_calendar.calendar_id||' dimension week ending sunday';
190   bsc_aw_dbms_aw.execute(g_stmt);
191   g_stmt:='dfn aw_month_cal_'||p_calendar.calendar_id||' dimension month';
192   bsc_aw_dbms_aw.execute(g_stmt);
193   g_stmt:='dfn aw_quarter_cal_'||p_calendar.calendar_id||' dimension quarter';
194   bsc_aw_dbms_aw.execute(g_stmt);
195   g_stmt:='dfn aw_year_cal_'||p_calendar.calendar_id||' dimension year';
196   bsc_aw_dbms_aw.execute(g_stmt);
197   --
198   for i in 1..p_calendar.periodicity.count loop
199     g_stmt:='dfn '||p_calendar.periodicity(i).dim_name||' dimension text';
200     bsc_aw_dbms_aw.execute(g_stmt);
201   end loop;
202   --
203   g_stmt:='dfn '||p_calendar.dim_name||' dimension concat(';
204   for i in 1..p_calendar.periodicity.count loop
205     g_stmt:=g_stmt||p_calendar.periodicity(i).dim_name||',';
206   end loop;
207   g_stmt:=substr(g_stmt,1,length(g_stmt)-1)||')';
208   bsc_aw_dbms_aw.execute(g_stmt);
209   --to merge new periodicities
210   for i in 1..p_calendar.periodicity.count loop
211     g_stmt:='CHGDFN '||p_calendar.dim_name||' base add '||p_calendar.periodicity(i).dim_name;
212     bsc_aw_dbms_aw.execute(g_stmt); --we have added ORA-36656 to ignore list
213   end loop;
214   g_stmt:='dfn '||p_calendar.levels_name||' dimension text';
215   bsc_aw_dbms_aw.execute(g_stmt);
216   --we need to add levels names as parent.child
217   for i in 1..p_calendar.parent_child.count loop
218     if p_calendar.parent_child(i).parent is not null and p_calendar.parent_child(i).child is not null then
219       g_stmt:='maintain '||p_calendar.levels_name||' merge '''||p_calendar.parent_child(i).parent_dim_name||'.'||
220       p_calendar.parent_child(i).child_dim_name||'''';
221       bsc_aw_dbms_aw.execute(g_stmt);
222     end if;
223   end loop;
224   --
225   g_stmt:='dfn '||p_calendar.end_period_levels_name||' dimension text';
226   bsc_aw_dbms_aw.execute(g_stmt);
227   for i in 1..p_calendar.periodicity.count loop
228     g_stmt:='maintain '||p_calendar.end_period_levels_name||' merge '''||
229     p_calendar.periodicity(i).dim_name||'''';
230     bsc_aw_dbms_aw.execute(g_stmt);
231   end loop;
232   --
233   g_stmt:='dfn '||p_calendar.relation_name||' relation '||p_calendar.dim_name||' <'||p_calendar.dim_name||' '||p_calendar.levels_name||'>';
234   bsc_aw_dbms_aw.execute(g_stmt);
235   g_stmt:='dfn '||p_calendar.denorm_relation_name||' relation '||p_calendar.dim_name||' <'||p_calendar.dim_name||' '||
236   p_calendar.end_period_levels_name||'>'; --end_period_levels_name is simply the level dim names
237   bsc_aw_dbms_aw.execute(g_stmt);
238   g_stmt:='dfn '||p_calendar.end_period_relation_name||' relation '||p_calendar.dim_name||' <'||p_calendar.dim_name||' '||
239   p_calendar.end_period_levels_name||'>';
240   bsc_aw_dbms_aw.execute(g_stmt);
241   --also define a temp variable that all aggregations with balance type measures will use
242   g_stmt:='dfn '||p_calendar.end_period_relation_name||'.temp TEXT <'||p_calendar.dim_name||' '||p_calendar.end_period_levels_name||'>';
243   bsc_aw_dbms_aw.execute(g_stmt);
244   --
245   for i in 1..p_calendar.periodicity.count loop
246     if p_calendar.periodicity(i).aw_time_dim_name is not null then
247       g_stmt:='dfn '||p_calendar.periodicity(i).aw_bsc_aw_rel_name||' relation '||p_calendar.periodicity(i).aw_time_dim_name||
248       '<'||p_calendar.periodicity(i).dim_name||'>';
249       bsc_aw_dbms_aw.execute(g_stmt);
250       g_stmt:='dfn '||p_calendar.periodicity(i).aw_aw_bsc_rel_name||' relation bsc_calendar_'||p_calendar.calendar_id||
251       '<'||p_calendar.periodicity(i).aw_time_dim_name||'>';
252       bsc_aw_dbms_aw.execute(g_stmt);
253     end if;
254   end loop;
255   --
256   for i in 1..p_calendar.misc_object.count loop
257     g_stmt:='dfn '||p_calendar.misc_object(i).object_name||' '||p_calendar.misc_object(i).datatype||' <'||p_calendar.dim_name||'>';
258     bsc_aw_dbms_aw.execute(g_stmt);
259   end loop;
260 Exception when others then
261   log_n('Exception in create_calendar_objects '||sqlerrm);
262   raise;
263 End;
264 
265 procedure create_calendar_program(
266 p_calendar in out nocopy calendar_r
267 ) is
268 --
269 l_name varchar2(300);
270 l_lower_periodicities periodicity_tb;
271 l_upper_periodicities periodicity_tb;
272 --
273 Begin
274   --
275   p_calendar.load_program:='load_cal_'||p_calendar.calendar_id;
276   g_commands.delete;
277   bsc_aw_utility.add_g_commands(g_commands,'dfn '||p_calendar.load_program||' program');
278   bsc_aw_utility.add_g_commands(g_commands,'allstat');
279   for i in 1..p_calendar.periodicity.count loop
280     --to populate end_period_relation_name
281     l_name:='prev_'||p_calendar.periodicity(i).db_column_name;
282     bsc_aw_utility.add_g_commands(g_commands,'if exists(\'''||l_name||'\'') eq false');
283     bsc_aw_utility.add_g_commands(g_commands,'then do');
284     bsc_aw_utility.add_g_commands(g_commands,'dfn prev_'||p_calendar.periodicity(i).db_column_name||' TEXT session');
285     bsc_aw_utility.add_g_commands(g_commands,'doend');
286   end loop;
287   --4566074 : these variables must be initialized since sessions are used, else old values get pulled in
288   for i in 1..p_calendar.periodicity.count loop
289     bsc_aw_utility.add_g_commands(g_commands,'prev_'||p_calendar.periodicity(i).db_column_name||'=NA');
290   end loop;
291   --
292   for i in 1..p_calendar.periodicity.count loop
293     if p_calendar.periodicity(i).aw_time_dim_name is not null then
294       bsc_aw_utility.add_g_commands(g_commands,'maintain '||p_calendar.periodicity(i).aw_time_dim_name||' merge arg(1)');
295       bsc_aw_utility.add_g_commands(g_commands,'maintain '||p_calendar.periodicity(i).aw_time_dim_name||' merge arg(2)');
296     end if;
297   end loop;
298   --
299   bsc_aw_utility.add_g_commands(g_commands,'sql declare c1 cursor for select --');
300   for i in 1..p_calendar.periodicity.count loop
301     bsc_aw_utility.add_g_commands(g_commands,p_calendar.periodicity(i).db_column_name||'||\''.\''||year, --');
302   end loop;
303   for i in 1..p_calendar.periodicity.count loop
304     if p_calendar.periodicity(i).periodicity_type=1 then --this is yearly. then we  hardcode 0 this is what iviewer wants to see
305       bsc_aw_utility.add_g_commands(g_commands,'0 '||p_calendar.periodicity(i).db_column_name||', --');
306     else
307       bsc_aw_utility.add_g_commands(g_commands,p_calendar.periodicity(i).db_column_name||', --');
308     end if;
309   end loop;
310   for i in 1..p_calendar.periodicity.count loop
311     bsc_aw_utility.add_g_commands(g_commands,'year year'||i||', --');
312   end loop;
313   for i in 1..p_calendar.periodicity.count loop
314     bsc_aw_utility.add_g_commands(g_commands,p_calendar.periodicity(i).periodicity_id||' per_'||
315     p_calendar.periodicity(i).periodicity_id||', --');
316   end loop;
317   /*
318   earlier we were using month||\'' \''||day30||\'' \''||year. got error
319   Exception in load_calendar ORA-35758: (VCTODT03) '2 29 1997' is not a valid date because 29 is out of range for a day of the month.
320   this is because month is fiscal month, not calendar month. so corrected to calendar month, day and year
321   */
322   for i in 1..p_calendar.periodicity.count loop
323     if p_calendar.periodicity(i).aw_time_dim_name is not null then
324       if bsc_aw_utility.get_db_version>=10 then
325         bsc_aw_utility.add_g_commands(g_commands,'to_date(calendar_month||\'' \''||calendar_day||\'' \''||calendar_year,\''MM DD YYYY\'') aw_day_'||p_calendar.periodicity(i).db_column_name||', --');
326       else
327         bsc_aw_utility.add_g_commands(g_commands,'calendar_month||\'' \''||calendar_day||\'' \''||calendar_year aw_day_'||p_calendar.periodicity(i).db_column_name||', --');
328       end if;
329     end if;
330   end loop;
331   bsc_aw_utility.trim_g_commands(g_commands,4,' --');
332   bsc_aw_utility.add_g_commands(g_commands,'from bsc_db_calendar where calendar_id='||p_calendar.calendar_id||' order by calendar_year,calendar_month,calendar_day');
333   bsc_aw_utility.add_g_commands(g_commands,'sql open c1');
334   bsc_aw_utility.add_g_commands(g_commands,'sql fetch c1 loop into --');
335   for i in 1..p_calendar.periodicity.count loop
336     bsc_aw_utility.add_g_commands(g_commands,':append '||p_calendar.periodicity(i).dim_name||' --');
337   end loop;
338   for i in 1..p_calendar.periodicity.count loop
339     bsc_aw_utility.add_g_commands(g_commands,':period_cal_'||p_calendar.calendar_id||'('||p_calendar.dim_name||' '||
340     p_calendar.periodicity(i).dim_name||') --');
341   end loop;
342   for i in 1..p_calendar.periodicity.count loop
343     bsc_aw_utility.add_g_commands(g_commands,':year_cal_'||p_calendar.calendar_id||'('||p_calendar.dim_name||' '||
344     p_calendar.periodicity(i).dim_name||') --');
345   end loop;
346   for i in 1..p_calendar.periodicity.count loop
347     bsc_aw_utility.add_g_commands(g_commands,':periodicity_cal_'||p_calendar.calendar_id||'('||p_calendar.dim_name||' '||
348     p_calendar.periodicity(i).dim_name||') --');
349   end loop;
350   for i in 1..p_calendar.periodicity.count loop
351     if p_calendar.periodicity(i).aw_time_dim_name is not null then
352       bsc_aw_utility.add_g_commands(g_commands,':'||p_calendar.periodicity(i).aw_bsc_aw_rel_name||' --');
353     end if;
354   end loop;
355   bsc_aw_utility.add_g_commands(g_commands,'then --');
356   --
357   --add the code for populating end_period_relation_name
358   for i in 1..p_calendar.periodicity.count loop
359     bsc_aw_utility.add_g_commands(g_commands,'if prev_'||p_calendar.periodicity(i).db_column_name||' EQ NA --');
360     bsc_aw_utility.add_g_commands(g_commands,'then do --');
361     bsc_aw_utility.add_g_commands(g_commands,'prev_'||p_calendar.periodicity(i).db_column_name||' = '||p_calendar.periodicity(i).dim_name||' --');
362     bsc_aw_utility.add_g_commands(g_commands,'doend --');
363     --if this is not the lowest level , ie. day level then...
364     --for day, source is null
365     if p_calendar.periodicity(i).source is not null then
366       --get all the lower periodicities
367       l_lower_periodicities.delete;
368       get_all_lower_periodicities(p_calendar.periodicity(i),p_calendar,l_lower_periodicities);
369       if l_lower_periodicities.count>0 then
370         bsc_aw_utility.add_g_commands(g_commands,'else do --');
371         bsc_aw_utility.add_g_commands(g_commands,'if prev_'||p_calendar.periodicity(i).db_column_name||' NE '||p_calendar.periodicity(i).dim_name||' --');
372         bsc_aw_utility.add_g_commands(g_commands,'then do --');
373         for j in 1..l_lower_periodicities.count loop
374           bsc_aw_utility.add_g_commands(g_commands,p_calendar.end_period_relation_name||'('||p_calendar.periodicity(i).dim_name||' '||
375           'prev_'||p_calendar.periodicity(i).db_column_name||' '||p_calendar.end_period_levels_name||' \'''||l_lower_periodicities(j).dim_name||'\'')='||
376           p_calendar.dim_name||'('||l_lower_periodicities(j).dim_name||' prev_'||l_lower_periodicities(j).db_column_name||') --');
377         end loop;
378         bsc_aw_utility.add_g_commands(g_commands,'doend --');
379         bsc_aw_utility.add_g_commands(g_commands,'doend --');
380       end if;
381     end if;
382   end loop;
383   for i in 1..p_calendar.periodicity.count loop
384     bsc_aw_utility.add_g_commands(g_commands,'if prev_'||p_calendar.periodicity(i).db_column_name||' NE '||p_calendar.periodicity(i).dim_name||' --');
385     bsc_aw_utility.add_g_commands(g_commands,'then do --');
386     bsc_aw_utility.add_g_commands(g_commands,'prev_'||p_calendar.periodicity(i).db_column_name||' = '||p_calendar.periodicity(i).dim_name||' --');
387     bsc_aw_utility.add_g_commands(g_commands,'doend --');
388   end loop;
389   ----------
390   --code to populate denorm relation
391   for i in 1..p_calendar.periodicity.count loop
392     l_upper_periodicities.delete;
393     get_all_upper_periodicities(p_calendar.periodicity(i),p_calendar,l_upper_periodicities);
394     if l_upper_periodicities.count>0 then
395       for j in 1..l_upper_periodicities.count loop
396         bsc_aw_utility.add_g_commands(g_commands,p_calendar.denorm_relation_name||'('||p_calendar.dim_name||' '||p_calendar.periodicity(i).dim_name||
397         ' '||p_calendar.end_period_levels_name||' \'''||l_upper_periodicities(j).dim_name||'\'')='||p_calendar.dim_name||'('||
398         p_calendar.dim_name||' '||l_upper_periodicities(j).dim_name||') --');
399       end loop;
400     end if;
401   end loop;
402   ----------
403   --code to populate the other relations
404   for i in 1..p_calendar.parent_child.count loop
405     if p_calendar.parent_child(i).parent is not null and p_calendar.parent_child(i).child is not null then
406       l_name:=p_calendar.parent_child(i).child_dim_name;
407       bsc_aw_utility.add_g_commands(g_commands,p_calendar.relation_name||'('||p_calendar.dim_name||' '||l_name||' '||
408       p_calendar.levels_name||' \'''||p_calendar.parent_child(i).parent_dim_name||'.'||p_calendar.parent_child(i).child_dim_name
409       ||'\'')='||
410       p_calendar.dim_name||'('||p_calendar.dim_name||' '||p_calendar.parent_child(i).parent_dim_name||') --');
411     end if;
412   end loop;
413   for i in 1..p_calendar.periodicity.count loop
414     if p_calendar.periodicity(i).aw_time_dim_name is not null then
415       bsc_aw_utility.add_g_commands(g_commands,p_calendar.periodicity(i).aw_aw_bsc_rel_name||'('||p_calendar.periodicity(i).aw_time_dim_name||' '||
416       p_calendar.periodicity(i).aw_bsc_aw_rel_name||')='||p_calendar.dim_name||'('||p_calendar.periodicity(i).dim_name||' '||
417       p_calendar.periodicity(i).dim_name||') --');
418     end if;
419   end loop;
420   bsc_aw_utility.trim_g_commands(g_commands,3,null);
421   bsc_aw_utility.add_g_commands(g_commands,'sql close c1');
422   bsc_aw_utility.add_g_commands(g_commands,'sql cleanup');
423   --part II----------------------
424   /*
425   we have an issue where if 2004 is the last year, then data in calendar will not go to 2005. this means for the last periods in 2004,
426   like year 2004, qtr 4 2004, semester 2 2004, we will not have if prev_YEAR NE year_1_cal_1 - so we are not populating end period rel
427   for relation. we have to add this last data to the relation. pick the last row in the calendar, then assign it as the end period rel
428   for year 2004, day 366.2004 is the end period rel etc
429   */
430   bsc_aw_utility.add_g_commands(g_commands,'sql declare c1 cursor for select --');
431   for i in 1..p_calendar.periodicity.count loop
432     bsc_aw_utility.add_g_commands(g_commands,p_calendar.periodicity(i).db_column_name||'||\''.\''||year, --');
433   end loop;
434   bsc_aw_utility.trim_g_commands(g_commands,4,' --');
435   bsc_aw_utility.add_g_commands(g_commands,'from (select * from bsc_db_calendar where calendar_id='||p_calendar.calendar_id||
436   ' order by calendar_year desc,calendar_month desc,calendar_day desc) where rownum=1');
437   bsc_aw_utility.add_g_commands(g_commands,'sql open c1');
438   bsc_aw_utility.add_g_commands(g_commands,'sql fetch c1 loop into --');
439   for i in 1..p_calendar.periodicity.count loop
440     bsc_aw_utility.add_g_commands(g_commands,':match '||p_calendar.periodicity(i).dim_name||' --');
441   end loop;
442   --add the code for populating end_period_relation_name
443   for i in 1..p_calendar.periodicity.count loop
444     if p_calendar.periodicity(i).source is not null then
445       --get all the lower periodicities
446       l_lower_periodicities.delete;
447       get_all_lower_periodicities(p_calendar.periodicity(i),p_calendar,l_lower_periodicities);
448       if l_lower_periodicities.count>0 then
449         for j in 1..l_lower_periodicities.count loop
450           bsc_aw_utility.add_g_commands(g_commands,p_calendar.end_period_relation_name||'('||p_calendar.periodicity(i).dim_name||' '||
451           p_calendar.periodicity(i).dim_name||' '||p_calendar.end_period_levels_name||' \'''||l_lower_periodicities(j).dim_name||'\'')='||
452           p_calendar.dim_name||'('||l_lower_periodicities(j).dim_name||' '||l_lower_periodicities(j).dim_name||') --');
453         end loop;
454       end if;
455     end if;
456   end loop;
457   bsc_aw_utility.trim_g_commands(g_commands,3,null);
458   --
459   bsc_aw_utility.exec_program_commands(p_calendar.load_program,g_commands);
460 Exception when others then
461   log_n('Exception in create_calendar_program '||sqlerrm);
462   raise;
463 End;
464 
465 /*
466 given a periodicity, gets all the lower periodicities, ie denormalizes
467 used to fill in end_period_relation_name in create_calendar_program
468 called recursively
469 */
470 procedure get_all_lower_periodicities(
471 p_periodicity periodicity_r,
472 p_calendar calendar_r,
473 p_lower_periodicities in out nocopy periodicity_tb
474 ) is
475 --
476 l_lower_periodicities periodicity_tb;
477 l_flag boolean;
478 Begin
479   get_child_periodicities(p_periodicity,p_calendar,l_lower_periodicities);
480   for i in 1..l_lower_periodicities.count loop
481     get_all_lower_periodicities(l_lower_periodicities(i),p_calendar,p_lower_periodicities);
482   end loop;
483   for i in 1..l_lower_periodicities.count loop
484     --must add only distinct list
485     l_flag:=false;
486     for j in 1..p_lower_periodicities.count loop
487       if p_lower_periodicities(j).periodicity_id=l_lower_periodicities(i).periodicity_id then
488         l_flag:=true;
489         exit;
490       end if;
491     end loop;
492     if l_flag=false then
493       p_lower_periodicities(p_lower_periodicities.count+1):=l_lower_periodicities(i);
494     end if;
495   end loop;
496 Exception when others then
497   log_n('Exception in get_all_lower_periodicities '||sqlerrm);
498   raise;
499 End;
500 
501 /*
502 given a periodicity, gets all the upper periodicities, ie denormalizes
503 used to fill in denorm_relation in create_calendar_program called recursively
504 */
505 procedure get_all_upper_periodicities(
506 p_periodicity periodicity_r,
507 p_calendar calendar_r,
508 p_upper_periodicities in out nocopy periodicity_tb
509 ) is
510 --
511 l_upper_periodicities periodicity_tb;
512 l_flag boolean;
513 Begin
514   get_parent_periodicities(p_periodicity,p_calendar,l_upper_periodicities);
515   for i in 1..l_upper_periodicities.count loop
516     get_all_upper_periodicities(l_upper_periodicities(i),p_calendar,p_upper_periodicities);
517   end loop;
518   for i in 1..l_upper_periodicities.count loop
519     --must add only distinct list
520     l_flag:=false;
521     for j in 1..p_upper_periodicities.count loop
522       if p_upper_periodicities(j).periodicity_id=l_upper_periodicities(i).periodicity_id then
523         l_flag:=true;
524         exit;
525       end if;
526     end loop;
527     if l_flag=false then
528       p_upper_periodicities(p_upper_periodicities.count+1):=l_upper_periodicities(i);
529     end if;
530   end loop;
531 Exception when others then
532   log_n('Exception in get_all_upper_periodicities '||sqlerrm);
533   raise;
534 End;
535 
536 /*given a calendar name, it reads cal info from olap metadata. NOTE...not all info is read
537 */
538 procedure get_calendar(p_calendar_name varchar2,p_calendar out nocopy calendar_r) is
539 l_oo bsc_aw_md_wrapper.bsc_olap_object_tb;
540 l_oor bsc_aw_md_wrapper.bsc_olap_object_relation_tb;
541 Begin
542   bsc_aw_md_api.get_bsc_olap_object(null,null,p_calendar_name,'dimension',l_oo);
543   bsc_aw_md_api.get_bsc_olap_object_relation(null,null,null,p_calendar_name,'dimension',l_oor);
544   --
545   p_calendar.dim_name:=p_calendar_name;
546   for i in 1..l_oo.count loop
547     if l_oo(i).object=p_calendar_name and l_oo(i).object_type='dimension' then
548       p_calendar.calendar_id:=bsc_aw_utility.get_parameter_value(l_oo(i).property1,'calendar',',');
549       p_calendar.property:=l_oo(i).property1;
550     elsif l_oo(i).object_type='relation' then
551       p_calendar.relation_name:=l_oo(i).object;
552     elsif l_oo(i).object_type='denorm relation' then
553       p_calendar.denorm_relation_name:=l_oo(i).object;
554     elsif l_oo(i).object_type='end period relation' then
555       p_calendar.end_period_relation_name:=l_oo(i).object;
556     elsif l_oo(i).object_type='level name dim' then
557       p_calendar.levels_name:=l_oo(i).object;
558     elsif l_oo(i).object_type='end period level name dim' then
559       p_calendar.end_period_levels_name:=l_oo(i).object;
560     --
561     elsif l_oo(i).object_type='dimension level' then
562       p_calendar.periodicity(p_calendar.periodicity.count+1).dim_name:=l_oo(i).object;
563       p_calendar.periodicity(p_calendar.periodicity.count).periodicity_id:=bsc_aw_utility.get_parameter_value(l_oo(i).property1,'periodicity',',');
564       p_calendar.periodicity(p_calendar.periodicity.count).db_column_name:=bsc_aw_utility.get_parameter_value(l_oo(i).property1,'db_column_name',',');
565     end if;
566   end loop;
567   --parent child relation
568   for i in 1..l_oor.count loop
569     if l_oor(i).relation_type='parent level' then
570       p_calendar.parent_child(p_calendar.parent_child.count+1).parent_dim_name:=l_oor(i).relation_object;
571       p_calendar.parent_child(p_calendar.parent_child.count).parent:=to_number(bsc_aw_utility.get_parameter_value(l_oor(i).property1,'parent periodicity',','));
572       p_calendar.parent_child(p_calendar.parent_child.count).child_dim_name:=l_oor(i).object;
573       p_calendar.parent_child(p_calendar.parent_child.count).child:=to_number(bsc_aw_utility.get_parameter_value(l_oor(i).property1,'child periodicity',','));
574     end if;
575   end loop;
576 Exception when others then
577   log_n('Exception in get_calendar '||sqlerrm);
578   raise;
579 End;
580 
581 /*
582 given a periodicity, gets all the child periodicities
583  main procedure get_all_lower_periodicities
584 */
585 procedure get_child_periodicities(
586 p_periodicity periodicity_r,
587 p_calendar calendar_r,
588 p_lower_periodicities out nocopy periodicity_tb
589 ) is
590 Begin
591   for i in 1..p_calendar.parent_child.count loop
592     if p_calendar.parent_child(i).parent=p_periodicity.periodicity_id and p_calendar.parent_child(i).child is not null then
593       p_lower_periodicities(p_lower_periodicities.count+1):=get_periodicity_r(p_calendar.parent_child(i).child,p_calendar.periodicity);
594     end if;
595   end loop;
596 Exception when others then
597   log_n('Exception in get_child_periodicities '||sqlerrm);
598   raise;
599 End;
600 
601 procedure get_parent_periodicities(
602 p_periodicity periodicity_r,
603 p_calendar calendar_r,
604 p_upper_periodicities out nocopy periodicity_tb
605 ) is
606 Begin
607   for i in 1..p_calendar.parent_child.count loop
608     if p_calendar.parent_child(i).child=p_periodicity.periodicity_id and p_calendar.parent_child(i).parent is not null then
609       p_upper_periodicities(p_upper_periodicities.count+1):=get_periodicity_r(p_calendar.parent_child(i).parent,p_calendar.periodicity);
610     end if;
611   end loop;
612 Exception when others then
613   log_n('Exception in get_parent_periodicities '||sqlerrm);
614   raise;
615 End;
616 
617 /*
618 given a periodicity_id, get the periodicity_r object
619 */
620 function get_periodicity_r(
621 p_periodicity_id number,
622 p_periodicities periodicity_tb
623 ) return periodicity_r is
624 Begin
625   for i in 1..p_periodicities.count loop
626     if p_periodicities(i).periodicity_id=p_periodicity_id then
627       return p_periodicities(i);
628     end if;
629   end loop;
630   return null;
631 Exception when others then
632   log_n('Exception in get_periodicity_r '||sqlerrm);
633   raise;
634 End;
635 
636 
637 --given a periodicity_id, what is the name of the corresponding aw dim?
638 function get_periodicity_dim_name(p_periodicity periodicity_tb, p_periodicity_id number) return varchar2 is
639 Begin
640   for i in 1..p_periodicity.count loop
641     if p_periodicity(i).periodicity_id=p_periodicity_id then
642       return p_periodicity(i).dim_name;
643     end if;
644   end loop;
645   return null;
646 Exception when others then
647   log_n('Exception in get_periodicity_dim_name '||sqlerrm);
648   raise;
649 End;
650 
651 
652 /*
653 this api will normalize a denorm relation of the periodicities
654 first parse the source periodicities out.
655 then normalize them
656 */
657 procedure normalize_per_relation(p_calendar in out nocopy calendar_r) is
658 l_relation bsc_aw_utility.parent_child_tb;
659 l_source bsc_aw_utility.value_tb;
660 l_count number;
661 Begin
662   l_count:=0;
663   for i in 1..p_calendar.periodicity.count loop
664     if p_calendar.periodicity(i).source is not null then
665       --we are just reusing bsc_aw_utility.parse_parameter_values
666       l_source.delete;
667       bsc_aw_utility.parse_parameter_values(p_calendar.periodicity(i).source,',',l_source);
668       for j in 1..l_source.count loop
669         l_count:=l_count+1;
670         l_relation(l_count).parent:=p_calendar.periodicity(i).periodicity_id;
671         l_relation(l_count).child:=l_source(j).parameter;
672       end loop;
673     else
674       l_count:=l_count+1;
675       l_relation(l_count).parent:=p_calendar.periodicity(i).periodicity_id;
676     end if;
677   end loop;
678   bsc_aw_utility.normalize_denorm_relation(l_relation);
679   --l_relation is now normalized
680   for i in 1..l_relation.count loop
681     p_calendar.parent_child(i).parent:=to_number(l_relation(i).parent);
682     p_calendar.parent_child(i).parent_dim_name:=get_periodicity_dim_name(p_calendar.periodicity,
683     p_calendar.parent_child(i).parent);
684     p_calendar.parent_child(i).child:=to_number(l_relation(i).child);
685     p_calendar.parent_child(i).child_dim_name:=get_periodicity_dim_name(p_calendar.periodicity,
686     p_calendar.parent_child(i).child);
687   end loop;
688 Exception when others then
689   log_n('Exception in normalize_per_relation '||sqlerrm);
690   raise;
691 End;
692 
693 procedure dmp_calendar(p_calendar calendar_r) is
694 Begin
695   log_n('Calendar Dmp :-');
696   log(p_calendar.calendar_id);
697   log('Periodicity:-');
698   for i in 1..p_calendar.periodicity.count loop
699     log(p_calendar.periodicity(i).db_column_name||' perid='||p_calendar.periodicity(i).periodicity_id||' pertype='||
700     p_calendar.periodicity(i).periodicity_type||' source='||p_calendar.periodicity(i).source||' '||
701     'property='||p_calendar.periodicity(i).property);
702   end loop;
703   log('Periodicity Relations:-');
704   for i in 1..p_calendar.parent_child.count loop
705     log(p_calendar.parent_child(i).parent||' '||p_calendar.parent_child(i).child);
706   end loop;
707 Exception when others then
708   log_n('Exception in dmp_calendar '||sqlerrm);
709   raise;
710 End;
711 
712 procedure create_calendar_metadata(p_calendar calendar_r) is
713 Begin
714   bsc_aw_md_api.delete_calendar(p_calendar);
715   bsc_aw_md_api.create_calendar(p_calendar);
716 Exception when others then
717   log_n('Exception in create_calendar_metadata '||sqlerrm);
718   raise;
719 End;
720 
721 procedure get_kpi_for_calendar(p_calendar in out nocopy calendar_r) is
722 Begin
723   bsc_aw_bsc_metadata.get_kpi_for_calendar(p_calendar);
724 Exception when others then
725   log_n('Exception in get_kpi_for_calendar '||sqlerrm);
726   raise;
727 End;
728 
729 procedure attach_workspace(p_options varchar2) is
730 l_options varchar2(8000);
731 Begin
732   l_options:='create workspace,'||p_options;
733   bsc_aw_management.get_workspace_lock('rw',l_options);
734 Exception when others then
735   log_n('Exception in attach_workspace '||sqlerrm);
736   raise;
737 End;
738 
739 /*
740 returns the current year of this calendar
741 */
742 procedure get_calendar_current_year(p_calendar number,p_year out nocopy number) is
743 --
744 cursor c1 is select current_year from bsc_sys_calendars_b where calendar_id=p_calendar;
745 Begin
746   open c1;
747   fetch c1 into p_year;
748   close c1;
749 Exception when others then
750   log_n('Exception in get_calendar_current_year '||sqlerrm);
751   raise;
752 End;
753 
754 /*
755 see if the calendar is already loaded in AW
756 */
757 function check_calendar_loaded(p_calendar number) return varchar2 is
758 --
759 l_dim varchar2(300);
760 l_bsc_olap_object bsc_aw_md_wrapper.bsc_olap_object_tb;
761 Begin
762   l_dim:=get_calendar_name(p_calendar);
763   bsc_aw_md_api.get_bsc_olap_object(l_dim,'dimension',l_dim,'dimension',l_bsc_olap_object);
764   if l_bsc_olap_object(1).operation_flag is not null and l_bsc_olap_object(1).operation_flag='loaded' then
765     return 'Y';
766   else
767     return 'N';
768   end if;
769 Exception when others then
770   log_n('Exception in check_calendar_loaded '||sqlerrm);
771   raise;
772 End;
773 
774 procedure load_calendar(p_calendar number,p_options varchar2) is
775 Begin
776   bsc_aw_utility.g_options.delete;
777   bsc_aw_utility.parse_parameter_values(p_options,',',bsc_aw_utility.g_options);
778   bsc_aw_utility.open_file('TEST');
779   bsc_aw_utility.dmp_g_options(bsc_aw_utility.g_options);
780   init_all;
781   lock_calendar_objects(p_calendar);
782   load_calendar(p_calendar);
783   --
784   bsc_aw_management.commit_aw;
785   commit;
786   bsc_aw_management.detach_workspace;
787 Exception when others then
788   bsc_aw_management.detach_workspace;
789   log_n('Exception in load_calendar '||sqlerrm);
790   raise;
791 End;
792 
793 --in bsc_aw_load_kpi, we have a call to this procedure from load_calendar_if_needed
794 procedure load_calendar(p_calendar number) is
795 --
796 --4604538 we select min and max of calendar year
797 cursor c1 is select min(calendar_year)-1,max(calendar_year)+1 from bsc_db_calendar where calendar_id=p_calendar;
798 l_min number;
799 l_max number;
800 --
801 l_pgm varchar2(300);
802 l_dim varchar2(300);
803 l_bsc_olap_object bsc_aw_md_wrapper.bsc_olap_object_tb;
804 l_stmt varchar2(3000);
805 Begin
806   --
807   open c1;
808   fetch c1 into l_min,l_max;
809   close c1;
810   --
811   l_dim:=get_calendar_name(p_calendar);
812   --purge_calendar(p_calendar); there is no need to purge the calendar when loading it
813   l_bsc_olap_object.delete;
814   bsc_aw_md_api.get_bsc_olap_object(null,'dml program',l_dim,'dimension',l_bsc_olap_object);
815   for i in 1..l_bsc_olap_object.count loop
816     if l_bsc_olap_object(i).olap_object_type='dml program initial load' then
817       l_pgm:=l_bsc_olap_object(i).object;
818       exit;
819     end if;
820   end loop;
821   l_stmt:='call '||l_pgm||'(''01 01 '||l_min||''',''01 01 '||l_max||''')';
822   if g_debug then
823     log_n(l_stmt||bsc_aw_utility.get_time);
824   end if;
825   bsc_aw_dbms_aw.execute(l_stmt);
826   if g_debug then
827     log('Finished '||bsc_aw_utility.get_time);
828   end if;
829   --update bsc_olap_object saying operation_flag='loaded'
830   bsc_aw_md_api.update_olap_object(l_dim,'dimension',l_dim,'dimension',null,null,'operation_flag','loaded');
831 Exception when others then
832   log_n('Exception in load_calendar '||sqlerrm);
833   raise;
834 End;
835 
836 /*
837 clean up
838 aw time dim level
839 dim level
840 dimension
841 */
842 procedure purge_calendar(p_calendar number,p_options varchar2) is
843 Begin
844   purge_calendar(p_calendar);
845   bsc_aw_management.commit_aw;
846   commit;
847 Exception when others then
848   log_n('Exception in purge_calendar '||sqlerrm);
849   raise;
850 End;
851 
852 procedure purge_calendar(p_calendar number) is
853 --
854 l_dim varchar2(300);
855 l_olap_object bsc_aw_md_wrapper.bsc_olap_object_tb;
856 Begin
857   l_dim:=get_calendar_name(p_calendar);
858   bsc_aw_md_api.get_bsc_olap_object(null,null,l_dim,'dimension',l_olap_object);
859   --
860   for i in 1..l_olap_object.count loop
861     if l_olap_object(i).object_type='aw time dim level' then
862       bsc_aw_dbms_aw.execute('maintain '||l_olap_object(i).object||' delete all');
863     end if;
864   end loop;
865   --
866   for i in 1..l_olap_object.count loop
867     if l_olap_object(i).object_type='dimension level' then
868       bsc_aw_dbms_aw.execute('maintain '||l_olap_object(i).object||' delete all');
869     end if;
870   end loop;
871   --update bsc_olap_object saying operation_flag='purged'
872   bsc_aw_md_api.update_olap_object(l_dim,'dimension',l_dim,'dimension',null,null,'operation_flag','purged');
873 Exception when others then
874   log_n('Exception in purge_calendar '||sqlerrm);
875   raise;
876 End;
877 
878 procedure check_calendar_create(
879 p_calendar calendar_r,
880 p_recreate out nocopy varchar2,
881 p_affected_kpi out nocopy dbms_sql.varchar2_table) is
882 --
883 Begin
884   if bsc_aw_md_api.is_dim_present(p_calendar.dim_name) then
885     --check to see if the calendar matches the calendar in the olap metadata
886     if bsc_aw_utility.get_parameter_value('RECREATE CALENDAR')='Y' then
887       if g_debug then
888         log('RECREATE CALENDAR specified. Drop and recreate');
889       end if;
890       p_recreate:='create all';
891       drop_calendar_objects(p_calendar.dim_name,null,p_affected_kpi);
892     elsif bsc_aw_utility.get_parameter_value('REIMPLEMENT CALENDAR')='Y' then
893       if g_debug then
894         log('REIMPLEMENT CALENDAR specified. Merge create all');
895       end if;
896       p_recreate:='create all';
897     elsif bsc_aw_utility.get_parameter_value('RECREATE PROGRAM')='Y' then
898       if g_debug then
899         log('RECREATE PROGRAM specified');
900       end if;
901       p_recreate:='create program';
902     else
903       correct_calendar(p_calendar,p_recreate);
904     end if;
905   else --cal not present
906     if g_debug then
907       log('New Calendar '||p_calendar.dim_name);
908     end if;
909     p_recreate:='create all';
910   end if;
911   if g_debug then
912     log('For calendar '||p_calendar.dim_name||', recreate option='||p_recreate);
913   end if;
914 Exception when others then
915   log_n('Exception in check_calendar_create '||sqlerrm);
916   raise;
917 End;
918 
919 /*
920 check to see if the olap metadata and the current calendar metadata are in sync
921 right now, see if there are new periodicities or dropped periodicities
922 */
923 procedure correct_calendar(p_calendar calendar_r,p_recreate out nocopy varchar2) is
924 l_oo bsc_aw_md_wrapper.bsc_olap_object_tb;
925 l_oor bsc_aw_md_wrapper.bsc_olap_object_relation_tb;
926 l_periodicities dbms_sql.varchar2_table;
927 l_olap_periodicities dbms_sql.varchar2_table;
928 l_level_name_dim varchar(200);
929 l_olap_periodicity_dim dbms_sql.varchar2_table;
930 l_pc parent_child_tb;
931 --
932 Begin
933   bsc_aw_md_api.get_bsc_olap_object(null,null,p_calendar.dim_name,'dimension',l_oo);
934   bsc_aw_md_api.get_bsc_olap_object_relation(null,null,null,p_calendar.dim_name,'dimension',l_oor);
935   if l_oo.count=0 then
936     return;
937   end if;
938   for i in 1..p_calendar.periodicity.count loop
939     l_periodicities(l_periodicities.count+1):=p_calendar.periodicity(i).periodicity_id;
940   end loop;
941   for i in 1..l_oo.count loop
942     if l_oo(i).object_type='dimension level' then
943       l_olap_periodicities(l_olap_periodicities.count+1):=bsc_aw_utility.get_parameter_value(l_oo(i).property1,'periodicity',',');
944       l_olap_periodicity_dim(l_olap_periodicity_dim.count+1):=l_oo(i).object;
945     elsif l_oo(i).object_type='level name dim' then
946       l_level_name_dim:=l_oo(i).object;
947     end if;
948   end loop;
949   --level name dim
950   for i in 1..l_olap_periodicities.count loop
951     if bsc_aw_utility.in_array(l_periodicities,l_olap_periodicities(i))=false then
952       p_recreate:='create all';
953       for j in 1..l_oor.count loop
954         if l_oor(j).relation_type='parent level' then
955           if l_oor(j).object=l_olap_periodicity_dim(i) or l_oor(j).relation_object=l_olap_periodicity_dim(i) then
956             bsc_aw_dbms_aw.execute('maintain '||l_level_name_dim||' delete '''||l_oor(j).relation_object||'.'||l_oor(j).object||'''');
957           end if;
958         end if;
959       end loop;
960     end if;
961   end loop;
962   --see if there are new periodicities we need to add
963   if p_recreate is null then
964     for i in 1..l_periodicities.count loop
965       if bsc_aw_utility.in_array(l_olap_periodicities,l_periodicities(i))=false then
966         p_recreate:='create all';
967         exit;
968       end if;
969     end loop;
970   end if;
971   --see if any existing relation changed. 4602290
972   if p_recreate is null then
973     l_pc.delete;
974     for i in 1..l_oor.count loop
975       if l_oor(i).relation_type='parent level' then
976         l_pc(l_pc.count+1).parent_dim_name:=l_oor(i).relation_object;
977         l_pc(l_pc.count).child_dim_name:=l_oor(i).object;
978       end if;
979     end loop;
980     if compare_pc_relations(p_calendar.parent_child,l_pc)<>0 then
981       if g_debug then
982         log('Parent child relation diff between old and new');
983       end if;
984       p_recreate:='create all';
985     end if;
986   end if;
987   --recreate the program
988   if p_recreate is null then
989     p_recreate:='create program';
990   end if;
991 Exception when others then
992   log_n('Exception in correct_calendar '||sqlerrm);
993   raise;
994 End;
995 
996 function compare_pc_relations(p_pc_1 parent_child_tb,p_pc_2 parent_child_tb) return number is
997 --
998 l_pc_1 bsc_aw_utility.parent_child_tb;
999 l_pc_2 bsc_aw_utility.parent_child_tb;
1000 Begin
1001   for i in 1..p_pc_1.count loop
1002     l_pc_1(i).parent:=p_pc_1(i).parent_dim_name;
1003     l_pc_1(i).child:=p_pc_1(i).child_dim_name;
1004   end loop;
1005   for i in 1..p_pc_2.count loop
1006     l_pc_2(i).parent:=p_pc_2(i).parent_dim_name;
1007     l_pc_2(i).child:=p_pc_2(i).child_dim_name;
1008   end loop;
1009   return bsc_aw_utility.compare_pc_relations(l_pc_1,l_pc_2);
1010 Exception when others then
1011   log_n('Exception in compare_pc_relations '||sqlerrm);
1012   raise;
1013 End;
1014 
1015 --p_object_type is null or all or dml program
1016 procedure drop_calendar_objects(p_calendar_name varchar2,p_object_type varchar2,p_affected_kpi out nocopy dbms_sql.varchar2_table) is
1017 --
1018 l_bsc_olap_object bsc_aw_md_wrapper.bsc_olap_object_tb;
1019 l_flag dbms_sql.varchar2_table;
1020 Begin
1021   --first drop all dependent kpi ... if needed
1022   if p_object_type is null or p_object_type='all' then
1023     bsc_aw_md_api.get_kpi_for_dim(p_calendar_name,p_affected_kpi);
1024     for i in 1..p_affected_kpi.count loop
1025       bsc_aw_adapter_kpi.drop_kpi_objects(p_affected_kpi(i));
1026     end loop;
1027   end if;
1028   bsc_aw_md_api.get_bsc_olap_object(null,p_object_type,p_calendar_name,'dimension',l_bsc_olap_object);
1029   --order : drop all relations, variables etc, drop concat dim, then all others
1030   for i in 1..l_bsc_olap_object.count loop
1031     l_flag(i):='N';
1032   end loop;
1033   if l_bsc_olap_object.count>0 then
1034     for i in 1..l_bsc_olap_object.count loop
1035       if l_flag(i)='N' and (l_bsc_olap_object(i).olap_object_type ='relation' or l_bsc_olap_object(i).olap_object_type ='variable') then
1036         bsc_aw_utility.delete_aw_object(l_bsc_olap_object(i).olap_object);
1037         l_flag(i):='Y';
1038       end if;
1039     end loop;
1040     for i in 1..l_bsc_olap_object.count loop
1041       if l_flag(i)='N' and l_bsc_olap_object(i).olap_object_type='concat dimension' then
1042         bsc_aw_utility.delete_aw_object(l_bsc_olap_object(i).olap_object);
1043         l_flag(i):='Y';
1044       end if;
1045     end loop;
1046     for i in 1..l_bsc_olap_object.count loop
1047       if l_flag(i)='N' and l_bsc_olap_object(i).olap_object_type='dimension' then
1048         bsc_aw_utility.delete_aw_object(l_bsc_olap_object(i).olap_object);
1049         l_flag(i):='Y';
1050       end if;
1051     end loop;
1052     --all other objects
1053     for i in 1..l_bsc_olap_object.count loop
1054       if l_flag(i)='N' then
1055         bsc_aw_utility.delete_aw_object(l_bsc_olap_object(i).olap_object);
1056         l_flag(i):='Y';
1057       end if;
1058     end loop;
1059   end if;
1060 Exception when others then
1061   log_n('Exception in drop_calendar_objects '||sqlerrm);
1062   raise;
1063 End;
1064 
1065 function get_calendar_name(p_calendar number) return varchar2 is
1066 Begin
1067   return 'bsc_calendar_'||p_calendar;
1068 Exception when others then
1069   log_n('Exception in get_calendar_name '||sqlerrm);
1070   raise;
1071 End;
1072 
1073 /*
1074 this procedure finds out the missing levels. it also marks lowest level.
1075 input : periodicity dims
1076 output : missing periodicity dim added.
1077 also : lowest periodicity marked
1078 
1079 logic:
1080 for each level, see if a child level is present. if yes, this is not a hanging level
1081 if no child, 2 possibilities
1082 1. lowest level
1083 2. hanging level : must find missing level
1084 find out like this: drill down and see if at any time, a periodicity of the kpi is showing up. if yes, stop.
1085 if no, lowest level
1086 II
1087 then do the same for parent levels
1088 for each child, see if any immediate parent is present. if no, either top level or missing levels
1089 */
1090 procedure get_missing_periodicity(
1091 p_calendar_dim varchar2,
1092 p_periodicity_dim in out nocopy dbms_sql.varchar2_table,
1093 p_lowest_level out nocopy dbms_sql.varchar2_table
1094 ) is
1095 --
1096 l_missing_levels dbms_sql.varchar2_table;
1097 l_found boolean;
1098 l_parent_child_calendar parent_child_tb;
1099 Begin
1100   --get calendar properties
1101   get_calendar_parent_child(p_calendar_dim,l_parent_child_calendar);
1102   --see if a child level is present for the kpi periodicities
1103   for i in 1..p_periodicity_dim.count loop
1104     p_lowest_level(i):='N';
1105     if is_child_present(p_periodicity_dim(i),p_periodicity_dim,l_parent_child_calendar)=false then
1106       --lowest level or hanging level
1107       --drill down hier. if any of the children is present in p_periodicity_dim, this is hanging level
1108       l_missing_levels.delete;
1109       l_found:=false;
1110       get_missing_level_down(p_periodicity_dim(i),p_periodicity_dim,l_parent_child_calendar,l_missing_levels,l_missing_levels,l_found); --false is starting seed value
1111       if l_found and l_missing_levels.count>0 then
1112         for j in 1..l_missing_levels.count loop
1113           if bsc_aw_utility.in_array(p_periodicity_dim,l_missing_levels(j))=false then
1114             p_periodicity_dim(p_periodicity_dim.count+1):=l_missing_levels(j);
1115             p_lowest_level(p_periodicity_dim.count):='N';
1116           end if;
1117         end loop;
1118       else
1119         p_lowest_level(i):='Y';
1120       end if;
1121     end if;
1122   end loop;
1123   --
1124   for i in 1..p_periodicity_dim.count loop
1125     if is_parent_present(p_periodicity_dim(i),p_periodicity_dim,l_parent_child_calendar)=false then
1126       --lowest level or hanging level
1127       --drill down hier. if any of the children is present in p_periodicity_dim, this is hanging level
1128       l_missing_levels.delete;
1129       l_found:=false;
1130       get_missing_level_up(p_periodicity_dim(i),p_periodicity_dim,l_parent_child_calendar,l_missing_levels,l_missing_levels,l_found); --false is starting seed value
1131       if l_found and l_missing_levels.count>0 then
1132         for j in 1..l_missing_levels.count loop
1133           if bsc_aw_utility.in_array(p_periodicity_dim,l_missing_levels(j))=false then
1134             p_periodicity_dim(p_periodicity_dim.count+1):=l_missing_levels(j);
1135             p_lowest_level(p_periodicity_dim.count):='N';
1136           end if;
1137         end loop;
1138       end if;
1139     end if;
1140   end loop;
1141 Exception when others then
1142   log_n('Exception in get_missing_periodicity '||sqlerrm);
1143   raise;
1144 End;
1145 
1146 function is_child_present(
1147 p_parent varchar2,
1148 p_periodicity_dim dbms_sql.varchar2_table,
1149 p_parent_child parent_child_tb) return boolean is
1150 Begin
1151   for i in 1..p_parent_child.count loop
1152     if p_parent_child(i).parent_dim_name=p_parent and bsc_aw_utility.in_array(p_periodicity_dim,p_parent_child(i).child_dim_name) then
1153       return true;
1154     end if;
1155   end loop;
1156   return false;
1157 Exception when others then
1158   log_n('Exception in is_child_present '||sqlerrm);
1159   raise;
1160 End;
1161 
1162 function is_parent_present(
1163 p_child varchar2,
1164 p_periodicity_dim dbms_sql.varchar2_table,
1165 p_parent_child parent_child_tb) return boolean is
1166 Begin
1167   for i in 1..p_parent_child.count loop
1168     if p_parent_child(i).child_dim_name=p_child and bsc_aw_utility.in_array(p_periodicity_dim,p_parent_child(i).parent_dim_name) then
1169       return true;
1170     end if;
1171   end loop;
1172   return false;
1173 Exception when others then
1174   log_n('Exception in is_parent_present '||sqlerrm);
1175   raise;
1176 End;
1177 
1178 --recursively called
1179 procedure get_missing_level_down(
1180 p_parent varchar2,
1181 p_periodicity_dim dbms_sql.varchar2_table,
1182 p_parent_child parent_child_tb,
1183 p_missing_levels_in dbms_sql.varchar2_table,
1184 p_missing_levels_out out nocopy dbms_sql.varchar2_table,
1185 p_found in out nocopy boolean --indicates if child is found and its time to stop
1186 ) is
1187 --
1188 l_missing_levels dbms_sql.varchar2_table;
1189 Begin
1190   if p_found=false then
1191     if is_child_present(p_parent,p_periodicity_dim,p_parent_child) then
1192       p_missing_levels_out:=p_missing_levels_in;
1193       p_found:=true;
1194     else
1195       for i in 1..p_parent_child.count loop
1196         if p_parent_child(i).parent_dim_name=p_parent then
1197           l_missing_levels.delete;
1198           l_missing_levels:=p_missing_levels_in;
1199           l_missing_levels(l_missing_levels.count+1):=p_parent_child(i).child_dim_name;
1200           get_missing_level_down(p_parent_child(i).child_dim_name,p_periodicity_dim,p_parent_child,l_missing_levels,p_missing_levels_out,p_found);
1201           if p_found then --stop
1202             exit;
1203           end if;
1204         end if;
1205       end loop;
1206     end if;
1207   end if;
1208 Exception when others then
1209   log_n('Exception in get_missing_level_down '||sqlerrm);
1210   raise;
1211 End;
1212 
1213 --recursively called
1214 procedure get_missing_level_up(
1215 p_child varchar2,
1216 p_periodicity_dim dbms_sql.varchar2_table,
1217 p_parent_child parent_child_tb,
1218 p_missing_levels_in dbms_sql.varchar2_table,
1219 p_missing_levels_out out nocopy dbms_sql.varchar2_table,
1220 p_found in out nocopy boolean --indicates if child is found and its time to stop
1221 ) is
1222 --
1223 l_missing_levels dbms_sql.varchar2_table;
1224 Begin
1225   if p_found=false then
1226     if is_parent_present(p_child,p_periodicity_dim,p_parent_child) then
1227       p_missing_levels_out:=p_missing_levels_in;
1228       p_found:=true;
1229     else
1230       for i in 1..p_parent_child.count loop
1231         if p_parent_child(i).child_dim_name=p_child then
1232           l_missing_levels.delete;
1233           l_missing_levels:=p_missing_levels_in;
1234           l_missing_levels(l_missing_levels.count+1):=p_parent_child(i).parent_dim_name;
1235           get_missing_level_up(p_parent_child(i).parent_dim_name,p_periodicity_dim,p_parent_child,l_missing_levels,p_missing_levels_out,p_found);
1236           if p_found then --stop
1237             exit;
1238           end if;
1239         end if;
1240       end loop;
1241     end if;
1242   end if;
1243 Exception when others then
1244   log_n('Exception in get_missing_level_up '||sqlerrm);
1245   raise;
1246 End;
1247 
1248 procedure get_calendar_parent_child(p_calendar_dim varchar2,p_parent_child out nocopy parent_child_tb) is
1249 l_calendar calendar_r;
1250 Begin
1251   get_calendar(p_calendar_dim,l_calendar);
1252   for i in 1..l_calendar.parent_child.count loop
1253     p_parent_child(p_parent_child.count+1):=l_calendar.parent_child(i);
1254   end loop;
1255 Exception when others then
1256   log_n('Exception in get_calendar_parent_child '||sqlerrm);
1257   raise;
1258 End;
1259 
1260 procedure get_calendar_periodicities(p_calendar_dim varchar2,p_periodicity out nocopy periodicity_tb) is
1261 l_calendar calendar_r;
1262 Begin
1263   get_calendar(p_calendar_dim,l_calendar);
1264   for i in 1..l_calendar.periodicity.count loop
1265     p_periodicity(p_periodicity.count+1):=l_calendar.periodicity(i);
1266   end loop;
1267 Exception when others then
1268   log_n('Exception in get_calendar_periodicities '||sqlerrm);
1269   raise;
1270 End;
1271 
1272 procedure lock_calendar_objects(p_calendar number) is
1273 --
1274 l_lock_objects dbms_sql.varchar2_table;
1275 Begin
1276   get_calendar_objects_to_lock(p_calendar,l_lock_objects);
1277   bsc_aw_management.get_workspace_lock(l_lock_objects,null);
1278 Exception when others then
1279   log_n('Exception in lock_calendar_objects '||sqlerrm);
1280   raise;
1281 End;
1282 
1283 /*
1284 in 10g, when calendar is loaded, we want to lock only the calendar objects, not get an exclusive lock on the system
1285 we cannot lock concat dim. got error
1286 acquire BSC_CCDIM_100_101_102_103  (S: 04/13/2005 17:34:10
1287 Exception in execute acquire BSC_CCDIM_100_101_102_103 ORA-37018:Multiwriter operations are not supported for object BSC_AW!BSC_CCDIM_100_101_102_103.
1288 --
1289 we have to acquire locks and update in a certain order . else we get
1290 ORA-37023: (XSMLTUPD01) Object workspace object cannot be updated without dimension workspace object.
1291 we cannot update a relation before a dim. so when we get locks, we first get dim, then relations, then variables
1292 */
1293 procedure get_calendar_objects_to_lock(p_calendar number,p_lock_objects out nocopy dbms_sql.varchar2_table) is
1294 l_dim varchar2(300);
1295 l_bsc_olap_object bsc_aw_md_wrapper.bsc_olap_object_tb;
1296 l_objects dbms_sql.varchar2_table;
1297 Begin
1298   l_dim:=get_calendar_name(p_calendar);
1299   bsc_aw_md_api.get_bsc_olap_object(null,null,l_dim,'dimension',l_bsc_olap_object);
1300   for i in 1..l_bsc_olap_object.count loop
1301     if l_bsc_olap_object(i).olap_object_type is not null and l_bsc_olap_object(i).olap_object_type='dimension' then
1302       l_objects(l_objects.count+1):=l_bsc_olap_object(i).olap_object;
1303     end if;
1304   end loop;
1305   for i in 1..l_bsc_olap_object.count loop
1306     if l_bsc_olap_object(i).olap_object_type is not null and l_bsc_olap_object(i).olap_object_type='relation' then
1307       l_objects(l_objects.count+1):=l_bsc_olap_object(i).olap_object;
1308     end if;
1309   end loop;
1310   for i in 1..l_bsc_olap_object.count loop
1311     if l_bsc_olap_object(i).olap_object_type is not null and l_bsc_olap_object(i).olap_object_type='variable' then
1312       l_objects(l_objects.count+1):=l_bsc_olap_object(i).olap_object;
1313     end if;
1314   end loop;
1315   --there are no limit cubes here like dim.?
1316   --
1317   for i in 1..l_objects.count loop
1318     if bsc_aw_utility.in_array(p_lock_objects,l_objects(i))=false then
1319       p_lock_objects(p_lock_objects.count+1):=l_objects(i);
1320     end if;
1321   end loop;
1322 Exception when others then
1323   log_n('Exception in get_calendar_objects_to_lock '||sqlerrm);
1324   raise;
1325 End;
1326 
1327 /*upgrade
1328 we start from latest version and move downwards. actions already done are marked off as false
1329 if p_new_version>=2 then
1330   if action('1') then
1331     ...
1332     action('1')=false
1333   end if;
1334   if action('2') then
1335   ...
1336 ...
1337 end if;
1338 if p_new_version>=1 then
1339   if action('2') then
1340     ...
1341     action('2')=false
1342   end if;
1343   if action('3') then
1344     ...
1345 end if;*/
1346 procedure upgrade(p_new_version number,p_old_version number) is
1347 l_action bsc_aw_utility.boolean_table;
1348 Begin
1349   if g_debug then
1350     log('Calendar upgrade New='||p_new_version||', Old='||p_old_version||bsc_aw_utility.get_time);
1351   end if;
1352   init_all;
1353   if p_new_version>p_old_version then
1354     /*init all actions */
1355     l_action('reimplement calendar'):=true;
1356     /*version by version inc upgrade */
1357     if p_old_version<3 then
1358       if l_action('reimplement calendar') then
1359         reimplement_all_calendars;
1360         l_action('reimplement calendar'):=false;
1361       end if;
1362     end if;
1363   end if;
1364   if g_debug then
1365     log('End upgrade calendar '||bsc_aw_utility.get_time);
1366   end if;
1367 Exception when others then
1368   log_n('Exception in upgrade '||sqlerrm);
1369   raise;
1370 End;
1371 
1372 procedure reimplement_all_calendars is
1373 l_oo bsc_aw_md_wrapper.bsc_olap_object_tb;
1374 l_calendar dbms_sql.number_table;
1375 l_year number;
1376 l_cal_id number;
1377 Begin
1378   bsc_aw_md_api.get_bsc_olap_object(null,'dimension',null,'dimension',l_oo);
1379   for i in 1..l_oo.count loop
1380     if instr(l_oo(i).property1,'dimension type=time')>0 then
1381       /*5017796. see if this calendar is still a valid implemented calendar in BSC */
1382       l_cal_id:=null;
1383       l_year:=null;
1384       l_cal_id:=to_number(bsc_aw_utility.get_parameter_value(l_oo(i).property1,'calendar',','));
1385       get_calendar_current_year(l_cal_id,l_year);
1386       if l_year is not null then
1387         bsc_aw_utility.merge_value(l_calendar,l_cal_id);
1388       end if;
1389     end if;
1390   end loop;
1391   bsc_aw_utility.add_option('REIMPLEMENT CALENDAR',null,',');
1392   for i in 1..l_calendar.count loop
1393     reimplement_calendar(l_calendar(i));
1394   end loop;
1395 Exception when others then
1396   log_n('Exception in reimplement_all_calendars '||sqlerrm);
1397   raise;
1398 End;
1399 
1400 procedure reimplement_calendar(p_calendar_id number) is
1401 l_affected_kpi dbms_sql.varchar2_table;
1402 l_dim varchar2(100);
1403 Begin
1404   if g_debug then
1405     log('Reimplement calendar '||p_calendar_id||bsc_aw_utility.get_time);
1406   end if;
1407   create_calendar(p_calendar_id,l_affected_kpi);
1408   l_dim:=get_calendar_name(p_calendar_id);
1409   bsc_aw_md_api.update_olap_object(l_dim,'dimension',l_dim,'dimension',null,null,'operation_flag','empty');
1410 Exception when others then
1411   log_n('Exception in reimplement_all_calendars '||sqlerrm);
1412   raise;
1413 End;
1414 
1415 ------------------------------
1416 procedure init_all is
1417 Begin
1418   if g_init is null or g_init=false then
1419     g_init:=true;
1420     /*5258418 we need to see if the temp tables and perm tables are created. serialize entry here */
1421     bsc_aw_utility.get_db_lock('bsc_aw_table_create_lock');
1422     bsc_aw_utility.create_temp_tables;
1423     bsc_aw_utility.create_perm_tables;
1424     bsc_aw_utility.release_db_lock('bsc_aw_table_create_lock');
1425     /* */
1426     if bsc_aw_utility.get_parameter_value(bsc_aw_utility.g_options,'DEBUG LOG')='Y'
1427     or bsc_aw_utility.g_log_level>=FND_LOG.G_CURRENT_RUNTIME_LEVEL then
1428       g_debug:=true;
1429     else
1430       g_debug:=false;
1431     end if;
1432     bsc_aw_utility.init_all(g_debug);
1433     bsc_aw_dbms_aw.init_all;
1434     bsc_aw_md_api.init_all;
1435     bsc_aw_md_wrapper.init_all;
1436     bsc_aw_bsc_metadata.init_all;
1437     bsc_metadata.init_all;
1438     bsc_aw_management.init_all;
1439   end if;
1440 Exception when others then
1441   log_n('Exception in init_all '||sqlerrm);
1442   raise;
1443 End;
1444 
1445 procedure log(p_message varchar2) is
1446 Begin
1447   bsc_aw_utility.log(p_message);
1448 Exception when others then
1449   null;
1450 End;
1451 
1452 procedure log_n(p_message varchar2) is
1453 Begin
1454   log('  ');
1455   log(p_message);
1456 Exception when others then
1457   null;
1458 End;
1459 
1460 END BSC_AW_CALENDAR;