DBA Data[Home] [Help]

PACKAGE BODY: APPS.FND_CONC_RELEASE_CLASS_UTILS

Source


1 package body FND_CONC_RELEASE_CLASS_UTILS as
2 /* $Header: AFCPCRCB.pls 120.2 2006/02/09 23:08:42 nsugguna noship $ */
3 
4 
5 
6 
7 -- Name
8 --  calc_specific_startdate
9 -- Purpose
10 --  Given a requested start date and the class info for a Specific schedule,
11 --  return the next date that a request should run according to this schedule.
12 --  May return null if no valid date found.
13 --
14 function calc_specific_startdate(req_sdate in date,
15                                  class_info in varchar2) return date is
16 
17   found        number;
18   offset       number;
19   temp_date    date;
20   dow          number; -- day of week 1 for Sun, 7 for Sat
21   dom          number; -- day of month between 1 to 31
22   nextdom      number;
23   weekno       number; -- no of week in month
24   moy          number; -- month of year between 1 to 12
25   datespec     boolean; -- true if some date is specified
26   dayspec      boolean; -- true if some week day is specified
27 begin
28     found := 0;
29     offset := 0;
30 
31     /* find first schedule time after sysdate then subtract a day */
32 
33     temp_date := req_sdate + floor(trunc(sysdate - req_sdate));
34 
35       -- handle 56 bits code for advance scheduling
36       if (LENGTH(class_info) = 56) then
37 
38           -- check if any of date is specified
39           -- ie if either of bit from 1 to 32 is set
40           if (SUBSTR(class_info, 1, 32) = 0) then
41               datespec := false;
42           else
43               datespec := true;
44           end if;
45 
46           -- check if any of the day is specified
47           -- ie if either of bit from 33 to 39 is set
48           if (SUBSTR(class_info, 33, 7) = 0) then
49               dayspec := false;
50           else
51               dayspec := true;
52           end if;
53       end if;
54 
55 
56     /* find next day where day of week or month is executable.
57        Day of week complexity is to avoid problems with calendars
58        where weekday numbering is different.  Nextdom is for finding
59        if its the last day of the month.  Class info in this case is a
60        bitfield: first 31 are for dom, 32 is last dom, 33-39 is dow */
61 
62     while (offset < 31) and (found = 0) loop
63       offset := offset + 1;
64       dow := MOD(trunc(TO_NUMBER(TO_CHAR(temp_date+1+offset,'J'))),7) + 1;
65       dom := TO_NUMBER(TO_CHAR(temp_date+offset,'DD'));
66       nextdom := TO_NUMBER(TO_CHAR(temp_date+1+offset,'DD'));
67 
68       -- handle 56 bits code
69       if (LENGTH(class_info) = 56) then
70       begin
71           moy := TO_NUMBER(TO_CHAR(temp_date + offset,'MM'));
72           weekno := TO_NUMBER(TO_CHAR(temp_date + offset,'W'));
73 
74           if (SUBSTR(class_info,44 + moy,1) = '1') /* if month is specified */ then
75           begin
76           -- see if there is some matching schedule
77           -- either day of month is matched OR (its last day of month and week is current week
78              if ( ((SUBSTR(class_info,dom,1) = '1') or ((SUBSTR(class_info,32,1) = '1') and (nextdom = 1)))
79              or ( (SUBSTR(class_info,dow + 32,1) = '1') and (SUBSTR(class_info,weekno + 39,1) = '1')) ) then
80                  found := 1;
81              end if;
82           end;
83           end if;
84       end;
85       else
86       -- handle 39 bits code as usual for backward compatibility
87           if (SUBSTR(class_info,dom,1) = '1') or /* if date matches */
88              ((SUBSTR(class_info,32,1) = '1') and (nextdom = 1)) or
89              (SUBSTR(class_info,dow + 32,1) = '1') then
90                   found := 1;
91           end if;
92       end if;
93     end loop;
94 
95     /* the bitfield must be all zeros...we don't have to take this abuse */
96     if found = 0 then return null;
97     else return greatest(req_sdate, temp_date + offset);
98     end if;
99 
100 end calc_specific_startdate;
101 
102 
103 -- Name
104 --  parse_named_periodic_schedule
105 -- Purpose
106 --  Given an application name and a Periodic schedule name,
107 --  return the interval, interval unit, interval type, start_date and end date
108 --  for this schedule.
109 --  Values will be null if the schedule is not found or an error occurs.
110 --
111 procedure parse_named_periodic_schedule(p_application 	 in varchar2,
112 			                p_class_name 	 in varchar2,
113                                         p_repeat_interval      out nocopy number,
114                                         p_repeat_interval_unit out nocopy varchar2,
115                                         p_repeat_interval_type out nocopy varchar2,
116                                         p_start_date           out nocopy date,
117                                         p_repeat_end           out nocopy date) is
118 
119    p_rel_class_app_id    number;
120    p_rel_class_id        number;
121 begin
122    p_repeat_interval      := null;
123    p_repeat_interval_unit := null;
124    p_repeat_interval_type := null;
125    p_repeat_end           := null;
126    p_start_date           := null;
127 
128    select a.application_id, c.release_class_id
129    into   p_rel_class_app_id, p_rel_class_id
130    from   fnd_conc_release_classes c, fnd_application a
131    where  upper(release_class_name)       = upper(p_class_name)
132    and    c.application_id                = a.application_id
133    and    a.application_short_name = upper(p_application);
134 
135    parse_periodic_schedule(p_rel_class_app_id, p_rel_class_id,
136                            p_repeat_interval,
137                            p_repeat_interval_unit,
138                            p_repeat_interval_type,
139                            p_start_date,
140                            p_repeat_end);
141 
142 
143 exception
144    when no_data_found then
145      return;
146 
147 end parse_named_periodic_schedule;
148 
149 
150 
151 -- Name
152 --  parse_periodic_schedule
153 -- Purpose
154 --  Given an application id and a Periodic schedule id,
155 --  return the interval, interval unit, interval type, start_date and end date
156 --  for this schedule.
157 --  Values will be null if the schedule is not found or an error occurs.
158 --
159 procedure parse_periodic_schedule(p_rel_class_app_id in number,
160                                   p_rel_class_id     in number,
161                                   p_repeat_interval      out nocopy number,
162                                   p_repeat_interval_unit out nocopy varchar2,
163                                   p_repeat_interval_type out nocopy varchar2,
164                                   p_start_date           out nocopy date,
165                                   p_repeat_end           out nocopy date) is
166 
167    c1            number;
168    c2            number;
169    sch_type      varchar2(1);
170    curr_info     varchar2(64);
171    req_date      date;
172    tmp_interval  number;
173 begin
174    p_repeat_interval      := null;
175    p_repeat_interval_unit := null;
176    p_repeat_interval_type := null;
177    p_repeat_end           := null;
178    p_start_date           := null;
179 
180    select class_info, class_type, date1, date2
181      into curr_info, sch_type, req_date, p_repeat_end
182      from fnd_conc_release_classes
183      where application_id = p_rel_class_app_id
184      and   release_class_id = p_rel_class_id;
185 
186    if sch_type <> 'P' then
187       return;
188    end if;
189 
190    c1 := instr(curr_info, ':', 1, 1);
191    c2 := instr(curr_info, ':', 1, 2);
192 
193    -- interval is the first field
194    p_repeat_interval := to_number(substr(curr_info, 1, (c1-1)));
195 
196    -- interval unit
197    select decode(substr(curr_info, c1+1, 1),
198                  'M', 'MONTHS', 'D', 'DAYS', 'H', 'HOURS', 'N', 'MINUTES')
199      into p_repeat_interval_unit
200      from dual;
201 
202    -- interval type
203    select decode(substr(curr_info, (c2+1), 1), 'C', 'END', 'START')
204      into p_repeat_interval_type
205      from dual;
206 
207 
208    -- now figure out the correct requested start date
209    select floor((sysdate - req_date) / DECODE(p_repeat_interval_unit,
210 		 'MINUTES', GREATEST(p_repeat_interval,1) / 1440,
211                  'HOURS', GREATEST(p_repeat_interval,1/60) / 24,
212                  'DAYS', GREATEST(p_repeat_interval,1/1440),
213                  'MONTHS', GREATEST(p_repeat_interval,1) * 31,1))
214    into tmp_interval
215    from dual;
216 
217    if (tmp_interval > 0)  then
218      select req_date +
219             DECODE(p_repeat_interval_unit,
220 		   'MINUTES', tmp_interval * GREATEST(p_repeat_interval,1) / 1440,
221                    'HOURS', tmp_interval * GREATEST(p_repeat_interval,1/60) / 24,
222                    'DAYS', tmp_interval * GREATEST(p_repeat_interval,1/1440),
223                    'MONTHS', ADD_MONTHS(req_date, tmp_interval * p_repeat_interval)-req_date,
224 		   1)
225      into req_date
226      from dual;
227    end if;
228 
229    while (req_date < sysdate) loop
230        select req_date +
231                 DECODE(p_repeat_interval_unit,
232 		 'MINUTES', GREATEST(p_repeat_interval,1) / 1440,
233                  'HOURS', GREATEST(p_repeat_interval,1/60) / 24,
234                  'DAYS', GREATEST(p_repeat_interval,1/1440),
235                  'MONTHS', ADD_MONTHS(req_date,p_repeat_interval)-req_date,
236 		 1)
237        into req_date
238        from dual;
239      end loop;
240 
241 
242    p_start_date := req_date;
243 
244 exception
245    when no_data_found then
246       null;
247 
248 end parse_periodic_schedule;
249 
250 -- Name
251 --  assign_specific_sch
252 -- Purpose
253 --  this function assigns specific schedule to a request
254 --  return true if successful
255 --  May return false if unsuccessful
256 --
257 function assign_specific_sch (req_id in number,
258                               class_info in varchar2,
259                               start_date in date,
260                               end_date in date) return boolean is
261 
262   relseqno              number;
263   relclassname          varchar2(20);
264   relclass_insert_error exception;
265   dual_no_rows	        exception;
266   dual_too_many_rows    exception;
267 
268 begin
269 
270     begin
271         Select Fnd_Conc_Release_Classes_S.nextval
272         Into relseqno
273         From Sys.Dual;
274 
275         exception
276             when no_data_found then
277                 raise dual_no_rows;
278             when too_many_rows then
279                 raise dual_too_many_rows;
280             when others then
281                 raise;
282     end;
283 
284     relclassname := 'RSRUN:0-' || TO_CHAR(relseqno);
285 
286     Insert Into fnd_conc_release_classes (application_id, release_class_id, release_class_name, owner_req_id, enabled_flag,
287     creation_date, created_by, last_update_date, last_updated_by, last_update_login, updated_flag, date1, date2, class_type,
288     class_info)
289     Values (0 , relseqno, relclassname, req_id, 'Y', Sysdate, FND_GLOBAL.conc_login_id, Sysdate,
290     FND_GLOBAL.conc_login_id, FND_GLOBAL.conc_login_id, 'N', start_date, end_date, 'S', class_info);
291 
292     if (sql%rowcount = 0) then
293         raise relclass_insert_error;
294     end if;
295 
296     INSERT INTO Fnd_Conc_Release_Classes_TL (application_id, release_class_id, language, source_lang,
297     user_release_class_name,last_update_date, last_updated_by, last_update_login, creation_date, created_by)
298     Select 0, relseqno, L.LANGUAGE_CODE, userenv('LANG'), relclassname,
299     Sysdate, FND_GLOBAL.conc_login_id, FND_GLOBAL.conc_login_id, Sysdate, FND_GLOBAL.conc_login_id from FND_LANGUAGES L
300     where L.INSTALLED_FLAG in ('I', 'B');
301 
302     if (sql%rowcount = 0) then
303         raise relclass_insert_error;
304     end if;
305 
306     -- modify FND_CONCURRENT_REQUESTS to set the release class id for this request
307     update Fnd_Concurrent_Requests set release_class_id=relseqno, release_class_app_id=0 where request_id=req_id;
308 
309     if (sql%rowcount = 0) then
310         raise relclass_insert_error;
311     end if;
312 
313     return (true);
314 
315     exception
316     when relclass_insert_error then
317         fnd_message.set_name ('FND', 'CONC-RelClass insert failed');
318         fnd_message.set_token ('APPLICATION', 0, FALSE);
319         fnd_message.set_token ('CLASS', relseqno, FALSE);
320         return (false);
321     when dual_no_rows then
322         fnd_message.set_name ('FND', 'No Rows in Dual');
323         return (false);
324     when dual_too_many_rows then
325         fnd_message.set_name ('FND', 'Too many rows in Dual');
326         return (false);
327     when others then
328         fnd_message.set_name ('FND', 'SQL-Generic error');
329         fnd_message.set_token ('ERRNO', sqlcode, FALSE);
330         fnd_message.set_token ('REASON', sqlerrm, FALSE);
331         fnd_message.set_token ('ROUTINE', 'assign_specific_sch: others', FALSE);
332         return (false);
333 
334 end assign_specific_sch;
335 
336 
337 end FND_CONC_RELEASE_CLASS_UTILS;