DBA Data[Home] [Help]

PACKAGE BODY: APPS.FFDBITEM

Source


1 package body ffdbitem as
2 /* $Header: ffdbitem.pkb 115.0 99/07/16 02:02:17 porting ship $ */
3 --
4 --
5 --   Copyright (c) Oracle Corporation (UK) Ltd 1994.
6 --   All Rights Reserved.
7 --
8 --   PRODUCT
9 --     Oracle*FastFormula
10 --
11 --   NAME
12 --     ffdbitem
13 --
14 --   NOTES
15 --     Contains utility functions and procedures for accessing database
16 --     item SQL and values
17 --
18 --   MODIFIED
19 --   pgowers         09-FEB-94    Created
20 --   rneale	     19-MAY-94	  Added exit(G699)
21 --   jthuring        11-OCT-95    Removed spurious start of comment marker
22 --   mfender	     11-JUN-97	  Create package statement to standard for
23 --                                release 11.
24 --
25 -- PRIVATE CODE
26 --
27 -------------------------------- execute_error --------------------------------
28 --
29 -- NAME
30 --  execute_error
31 --
32 -- DESCRIPTION
33 --   Set error message and raise exception when called with error details
34 --
35 procedure execute_error (p_error_name in varchar2,
36                          p_token1 in varchar2,
37                          p_token2 in varchar2,
38                          p_token3 in varchar2) is
39 begin
40   hr_utility.set_location('ffdbitem.execute_error',1);
41   hr_utility.set_message (802, p_error_name);
42   hr_utility.set_message_token ('1', p_token1);
43   hr_utility.set_message_token ('2', p_token2);
44   hr_utility.set_message_token ('3', p_token3);
45   hr_utility.raise_error;
46 end execute_error;
47 
48 -------------------------- process_route_parameters --------------------------
49 --
50 -- NAME
51 --  process_route_parameters
52 --
53 -- DESCRIPTION
54 --   Replace route parameters where their equivalent values for the user
55 --   entity being processed
56 --
57 procedure process_route_parameters (p_item_name in varchar2,
58                                     p_route_text in out varchar2,
59                                     p_user_entity_id in number,
60                                     p_route_id in number) is
61   cursor route_parms is
62   SELECT RP.SEQUENCE_NO,
63          RP.PARAMETER_NAME,
64          UPPER(RP.DATA_TYPE),
65          RPV.VALUE
66   FROM   FF_ROUTE_PARAMETERS RP,
67          FF_ROUTE_PARAMETER_VALUES RPV
68   WHERE  RP.ROUTE_ID = p_route_id
69   AND    RP.ROUTE_PARAMETER_ID = RPV.ROUTE_PARAMETER_ID
70   AND    RPV.USER_ENTITY_ID = p_user_entity_id
71   ORDER  BY RP.SEQUENCE_NO;
72 --
73   l_sequence_no FF_ROUTE_PARAMETERS.SEQUENCE_NO%TYPE;
74   l_parameter_name FF_ROUTE_PARAMETERS.PARAMETER_NAME%TYPE;
75   l_data_type FF_ROUTE_PARAMETERS.DATA_TYPE%TYPE;
76   l_value FF_ROUTE_PARAMETER_VALUES.VALUE%TYPE;
77 --
78 begin
79   hr_utility.set_location('ffdbitem.process_route_parameters',1);
80   open route_parms;
81   hr_utility.set_location('ffdbitem.process_route_parameters',2);
82   loop
83     fetch route_parms into l_sequence_no, l_parameter_name, l_data_type,
84                            l_value;
85     hr_utility.set_location('ffdbitem.process_route_parameters',3);
86     if route_parms%notfound then
87       close route_parms;
88       exit;
89     end if;
90     -- Check that a placeholder exists, error if it doesn't
91     if (instr(p_route_text, '&U'||to_char(l_sequence_no)) = 0) then
92       hr_utility.set_message (802, 'FFT76_NO_MATCHING_U');
93       hr_utility.set_message_token ('1',p_item_name);
94       hr_utility.set_message_token ('2',l_parameter_name);
95       hr_utility.raise_error;
96     end if;
97     hr_utility.set_location('ffdbitem.process_route_parameters',4);
98     -- replace all instances of placeholder with route parameter value
99     p_route_text := replace (p_route_text,
100                              '&U'||to_char(l_sequence_no),
101                              l_value);
102     hr_utility.set_location('ffdbitem.process_route_parameters',5);
103 
104   end loop;
105   hr_utility.set_location('ffdbitem.process_route_parameters',6);
106   -- Check if there are any remaining &U placeholders remaining
107   -- there should be none left
108   if (instr(p_route_text, '&U') > 0) then
109     hr_utility.set_message (802, 'FFT78_PLACEHOLDERS_REMAIN');
110     hr_utility.set_message_token ('1',p_item_name);
111     hr_utility.raise_error;
112   end if;
113   hr_utility.set_location('ffdbitem.process_route_parameters',7);
114 exception
115 when others then
116   if route_parms%isopen then
117     close route_parms;
118   end if;
119   raise;
120 end process_route_parameters;
121 --
122 ------------------------------ process_contexts ------------------------------
123 --
124 -- NAME
125 --  process_contexts
126 --
127 -- DESCRIPTION
128 --   Replace context placeholders in route with bind variable references
129 --   and add context details into output context information structure
130 --
131 procedure process_contexts (p_item_name in varchar2,
132                             p_route_text in out varchar2,
133                             p_route_id in number,
134                             p_contexts out FFCONTEXTS_T) is
135   cursor route_contexts is
136   SELECT RCU.SEQUENCE_NO,
137          FC.CONTEXT_NAME,
138          UPPER(FC.DATA_TYPE)
139   FROM   FF_CONTEXTS FC,
140          FF_ROUTE_CONTEXT_USAGES RCU
141   WHERE  FC.CONTEXT_ID = RCU.CONTEXT_ID
142   AND    RCU.ROUTE_ID = p_route_id
143   ORDER BY RCU.SEQUENCE_NO;
144 --
145   l_sequence_no FF_ROUTE_CONTEXT_USAGES.SEQUENCE_NO%TYPE;
146   l_context_name FF_CONTEXTS.CONTEXT_NAME%TYPE;
147   l_data_type FF_CONTEXTS.DATA_TYPE%TYPE;
148 --
149 begin
150   hr_utility.set_location('ffdbitem.process_contexts',1);
151   open route_contexts;
152   hr_utility.set_location('ffdbitem.process_contexts',2);
153   loop
154     fetch route_contexts into l_sequence_no, l_context_name, l_data_type;
155     hr_utility.set_location('ffdbitem.process_contexts',3);
156     if route_contexts%notfound then
157       close route_contexts;
158       exit;
159     end if;
160     -- Check that a placeholder exists, error if it doesn't
161     if (instr(p_route_text, '&B'||to_char(l_sequence_no)) = 0) then
162       hr_utility.set_message (802, 'FFT77_NO_MATCHING_B');
163       hr_utility.set_message_token ('1',p_item_name);
164       hr_utility.set_message_token ('2','B'||to_char(l_sequence_no));
165       hr_utility.raise_error;
166     end if;
167     hr_utility.set_location('ffdbitem.process_contexts',4);
168     -- replace all instances of placeholder with context bind name
169     p_route_text := replace (p_route_text,
170                              '&B'||to_char(l_sequence_no),
171                              ':B'||to_char(l_sequence_no));
172     hr_utility.set_location('ffdbitem.process_contexts',5);
173     p_contexts.context_count := l_sequence_no;
174     p_contexts.context_names(l_sequence_no) := l_context_name;
175     p_contexts.bind_names(l_sequence_no) := 'B'||to_char(l_sequence_no);
176     p_contexts.context_types(l_sequence_no) := l_data_type;
177   end loop;
178   -- Check if there are any remaining &B placeholders remaining
179   -- there should be none left
180   hr_utility.set_location('ffdbitem.process_contexts',6);
181   if (instr(p_route_text, '&B') > 0) then
182     hr_utility.set_message (802, 'FFT78_PLACEHOLDERS_REMAIN');
183     hr_utility.set_message_token ('1',p_item_name);
184     hr_utility.raise_error;
185   end if;
186   hr_utility.set_location('ffdbitem.process_contexts',7);
187 exception
188 when others then
189   if route_contexts%isopen then
190     close route_contexts;
191   end if;
192   raise;
193 end process_contexts;
194 --
195 ------------------------------- get_dbitem_info -------------------------------
196 --
197 -- NAME
198 --  get_dbitem_info
199 --
200 -- DESCRIPTION
201 --   Returns all information for a database item required to fetch it's value
202 --   including SQL, context requirements, data type in FFITEM_INFO_T
203 --   given the database item name, formula type id, business group id
204 --   and legislation code
205 --
206 procedure get_dbitem_info (p_item_name in varchar2,
207                            p_formula_type_id in number,
208                            p_bg_id in number,
209                            p_leg_code in varchar2,
210                            p_item_info out FFITEM_INFO_T) is
211 --
212 l_data_type FF_DATABASE_ITEMS.DATA_TYPE%type;
213 l_user_entity_id FF_USER_ENTITIES.USER_ENTITY_ID%type;
214 l_null_allowed FF_DATABASE_ITEMS.NULL_ALLOWED_FLAG%type;
215 l_notfound_allowed FF_USER_ENTITIES.NOTFOUND_ALLOWED_FLAG%type;
216 l_route_id FF_ROUTES.ROUTE_ID%type;
217 l_definition_text FF_DATABASE_ITEMS.DEFINITION_TEXT%type;
218 l_route_text varchar2(8000);
219 cursor c1 is
220 SELECT DI.DATA_TYPE,
221        UE.USER_ENTITY_ID,
222        UPPER(DI.NULL_ALLOWED_FLAG),
223        UPPER(UE.NOTFOUND_ALLOWED_FLAG),
224        FR.ROUTE_ID,
225        DI.DEFINITION_TEXT,
226        FR.TEXT
227 FROM   FF_DATABASE_ITEMS DI,
228        FF_USER_ENTITIES UE,
229        FF_ROUTES FR
230 WHERE  DI.USER_ENTITY_ID = UE.USER_ENTITY_ID
231 AND    UE.ROUTE_ID = FR.ROUTE_ID
232 AND    DI.USER_NAME = p_item_name
233 AND (   (UE.LEGISLATION_CODE IS NULL AND UE.BUSINESS_GROUP_ID IS NULL)
234      OR (UE.BUSINESS_GROUP_ID IS NULL AND p_leg_code = UE.LEGISLATION_CODE )
235      OR (p_bg_id = UE.BUSINESS_GROUP_ID)
236     )
237 AND NOT EXISTS (
238                SELECT CONTEXT_ID FROM FF_ROUTE_CONTEXT_USAGES IFRCU
239                WHERE IFRCU.ROUTE_ID = FR.ROUTE_ID
240                MINUS
241                SELECT CONTEXT_ID FROM FF_FTYPE_CONTEXT_USAGES
242                WHERE FORMULA_TYPE_ID = p_formula_type_id
243                );
244 begin
245   hr_utility.set_location('ffdbitem.get_dbitem_info',1);
246   open c1;
247   hr_utility.set_location('ffdbitem.get_dbitem_info',2);
248   fetch c1 into l_data_type, l_user_entity_id, l_null_allowed,
249                 l_notfound_allowed, l_route_id, l_definition_text,
250                 l_route_text;
251   hr_utility.set_location('ffdbitem.get_dbitem_info',3);
252   if c1%notfound then
253     raise_application_error(-20001,
254                              'Item '||p_item_name||' could not be found');
255   end if;
256   hr_utility.set_location('ffdbitem.get_dbitem_info',4);
257   -- Check that route text is present
258   if (l_route_text is null) then
259     hr_utility.set_message (802, 'FFTBFC785_BAD_ROUTE_LENGTH');
260     hr_utility.set_message_token ('1',p_item_name);
261     hr_utility.set_message_token ('2','0');
262     hr_utility.raise_error;
263   end if;
264   hr_utility.set_location('ffdbitem.get_dbitem_info',5);
265 
266 -- Process route parameters
267   process_route_parameters (p_item_name, l_route_text,
268                             l_user_entity_id, l_route_id);
269 
270   hr_utility.set_location('ffdbitem.get_dbitem_info',6);
271 -- Process contexts
272   process_contexts (p_item_name, l_route_text, l_route_id,
273                     p_item_info.contexts);
274   hr_utility.set_location('ffdbitem.get_dbitem_info',7);
275 --
276   l_route_text := 'select '||l_definition_text||' from '||l_route_text;
277   hr_utility.set_location('ffdbitem.get_dbitem_info',8);
278 --
282   p_item_info.data_type := l_data_type;
279   -- copy the results into the output structure
280   p_item_info.item_name := p_item_name;
281   p_item_info.item_sql  := l_route_text;
283 --
284   if l_null_allowed = 'Y' then
285     hr_utility.set_location('ffdbitem.get_dbitem_info',8);
286     p_item_info.null_ok := TRUE;
287   else
288     p_item_info.null_ok := FALSE;
289     hr_utility.set_location('ffdbitem.get_dbitem_info',9);
290   end if;
291 --
292   if l_notfound_allowed = 'Y' then
293     p_item_info.notfound_ok := TRUE;
294     hr_utility.set_location('ffdbitem.get_dbitem_info',10);
295   else
296     p_item_info.notfound_ok := FALSE;
297     hr_utility.set_location('ffdbitem.get_dbitem_info',11);
298   end if;
299 exception
300 when others then
301   if c1%isopen then
302     close c1;
303   end if;
304   -- re raise original exception
305   raise;
306 end get_dbitem_info;
307 --
308 ------------------------------ get_dbitem_value ------------------------------
309 --
310 -- NAME
311 --  get_dbitem_value
312 --
313 -- DESCRIPTION
314 --   Returns the value of a database item given the item details
315 --   currently returns the varchar2 version of the value, so for dates
316 --   this will be in the format DD-MON-YYYY
317 --
318 function get_dbitem_value (p_item_info in FFITEM_INFO_T) return varchar2 is
319 dbitem_cursor integer;
320 dbitem_text_value varchar2(255);
321 dbitem_date_value date;
322 dbitem_number_value number;
323 execute_status integer;
324 rows_fetched integer;
325 begin
326   hr_utility.set_location('ffdbitem.get_dbitem_value',1);
327   -- open a new cursor for the DB item select statement
328   dbitem_cursor := dbms_sql.open_cursor;
329   hr_utility.set_location('ffdbitem.get_dbitem_value',2);
330   hr_utility.trace(p_item_info.item_sql);
331   -- parse the SQL passed in
332   dbms_sql.parse(dbitem_cursor, p_item_info.item_sql, dbms_sql.v7);
333   --
334   hr_utility.set_location('ffdbitem.get_dbitem_value',3);
335   for i in 1..p_item_info.contexts.context_count loop
336     hr_utility.set_location('ffdbitem.get_dbitem_value',4);
337     hr_utility.trace(p_item_info.contexts.bind_names(i));
338     dbms_sql.bind_variable(dbitem_cursor,
339                            p_item_info.contexts.bind_names(i),
340                            p_item_info.contexts.bind_values(i));
341   end loop;
342   hr_utility.set_location('ffdbitem.get_dbitem_value',5);
343   -- Define an appropriately typed variable
344   if (p_item_info.data_type = 'T') then
345     hr_utility.set_location('ffdbitem.get_dbitem_value',6);
346     -- Define the (single) select list item as a varchar2
347     dbms_sql.define_column(dbitem_cursor, 1, dbitem_text_value, 255);
348   elsif (p_item_info.data_type = 'N') then
349     hr_utility.set_location('ffdbitem.get_dbitem_value',7);
350     -- Define the (single) select list item as a number
351     dbms_sql.define_column(dbitem_cursor, 1, dbitem_number_value);
352   elsif (p_item_info.data_type = 'D') then
353     hr_utility.set_location('ffdbitem.get_dbitem_value',8);
354     -- Define the (single) select list item as a date
355     dbms_sql.define_column(dbitem_cursor, 1, dbitem_date_value);
356   else
357     hr_utility.set_message (802, 'BAD_DATA_TYPE');
358     hr_utility.set_message_token ('1',p_item_info.item_name);
359     hr_utility.raise_error;
360   end if;
361   hr_utility.set_location('ffdbitem.get_dbitem_value',9);
362   --
363   -- Execute the cursor
364   execute_status := dbms_sql.execute(dbitem_cursor);
365   --
366   hr_utility.set_location('ffdbitem.get_dbitem_value',10);
367   -- Fetch the rows (only 1 row should be fetched for database items)
368   rows_fetched := dbms_sql.fetch_rows(dbitem_cursor);
369   hr_utility.set_location('ffdbitem.get_dbitem_value',11);
370   if (rows_fetched = 1) then
371     hr_utility.set_location('ffdbitem.get_dbitem_value',12);
372     -- get column value according to data type of item
373     if (p_item_info.data_type = 'T') then
374       hr_utility.set_location('ffdbitem.get_dbitem_value',13);
375       -- Define the (single) select list item as a varchar2
376       dbms_sql.column_value(dbitem_cursor, 1, dbitem_text_value);
377       hr_utility.set_location('ffdbitem.get_dbitem_value',14);
378       if (dbitem_text_value is null and not p_item_info.null_ok) then
379         execute_error('FFX00_NULL_VALUE', p_item_info.item_name, '1', '');
380       end if;
381     elsif (p_item_info.data_type = 'N') then
382       hr_utility.set_location('ffdbitem.get_dbitem_value',15);
383       -- Define the (single) select list item as a number
384       dbms_sql.column_value(dbitem_cursor, 1, dbitem_number_value);
385       hr_utility.set_location('ffdbitem.get_dbitem_value',16);
386       if (dbitem_number_value is null and not p_item_info.null_ok) then
387         execute_error('FFX00_NULL_VALUE', p_item_info.item_name, '1', '');
388       end if;
389       dbitem_text_value := to_char(dbitem_number_value);
390     else
391       hr_utility.set_location('ffdbitem.get_dbitem_value',17);
392       -- Define the (single) select list item as a date
393       dbms_sql.column_value(dbitem_cursor, 1, dbitem_date_value);
394       hr_utility.set_location('ffdbitem.get_dbitem_value',18);
395       if (dbitem_date_value is null and not p_item_info.null_ok ) then
396         execute_error('FFX00_NULL_VALUE', p_item_info.item_name, '1', '');
397       end if;
398       dbitem_text_value := to_char(dbitem_date_value,'DD-MON-YYYY');
399     end if;
400   elsif (rows_fetched = 0) then
401     hr_utility.set_location('ffdbitem.get_dbitem_value',19);
402     -- No rows found, so if 'notfound' is not OK, then raise no_data_found
403     if not p_item_info.notfound_ok then
404       execute_error('FFX00_DATA_NOT_FOUND', p_item_info.item_name, '1', '');
405     end if;
406   else
410   -- Close cursor
407     -- >1 row, so this is an error
408     execute_error('FFX00_TOO_MANY_ROWS', p_item_info.item_name, '1', '');
409   end if;
411   hr_utility.set_location('ffdbitem.get_dbitem_value',20);
412   dbms_sql.close_cursor(dbitem_cursor);
413   hr_utility.set_location('ffdbitem.get_dbitem_value',21);
414   -- return value
415   return dbitem_text_value;
416 exception
417 when others then
418   -- Close cursor if it is open
419   if dbms_sql.is_open(dbitem_cursor) then
420     dbms_sql.close_cursor(dbitem_cursor);
421   end if;
422   -- re-raise the exception
423   raise;
424 end get_dbitem_value;
425 
426 end ffdbitem;