DBA Data[Home] [Help]

PACKAGE BODY: APPS.FEM_MAPPING_PREVIEW_UTIL_PKG

Source


1 PACKAGE BODY FEM_MAPPING_PREVIEW_UTIL_PKG AS
2 /* $Header: fem_mapping_preview_util_pkg.plb 120.5 2008/02/08 22:06:54 gcheng ship $ */
3 
4 -------------------------------------------------------------------------------
5 -- PRIVATE CONSTANTS
6 -------------------------------------------------------------------------------
7 
8 G_PKG_NAME           CONSTANT VARCHAR2(30) := 'FEM_MAPPING_PREVIEW_UTIL_PKG';
9 G_FACT_ALIAS         CONSTANT VARCHAR2(1)  := 'F';
10 G_DIM_ALIAS          CONSTANT VARCHAR2(1)  := 'D';
11 G_STAT_ALIAS         CONSTANT VARCHAR2(1) := 'S';
12 G_MATCH_ALIAS        CONSTANT VARCHAR2(1)  := 'M';
13 G_DIM_TEMPLATE_TABLE CONSTANT VARCHAR2(30) := 'FEM_DIM_TEMPLATE';
14 G_SOURCE             CONSTANT FEM_ALLOC_PREVIEW_STATS.preview_row_group%TYPE
15                                 := 'SOURCE';
16 G_DRIVER             CONSTANT FEM_ALLOC_PREVIEW_STATS.preview_row_group%TYPE
17                                 := 'DRIVER';
18 G_DEBIT              CONSTANT FEM_ALLOC_PREVIEW_STATS.preview_row_group%TYPE
19                                 := 'DEBIT';
20 G_CREDIT             CONSTANT FEM_ALLOC_PREVIEW_STATS.preview_row_group%TYPE
21                                 := 'CREDIT';
22 G_ACCT_TRANS_TYPE    CONSTANT VARCHAR2(30) := 'ACCOUNT_TRANS';
23 G_LEDGER_TYPE        CONSTANT VARCHAR2(30) := 'LEDGER';
24 G_OTHER_TABLE_TYPE   CONSTANT VARCHAR2(30) := 'OTHER_TABLE_TYPE';
25 G_RETRIEVE_STAT      CONSTANT FEM_ALLOC_BR_OBJECTS.map_rule_type_code%TYPE
26                                 := 'RETRIEVE_STATISTICS';
27 G_BY_DIMENSION       CONSTANT FEM_ALLOC_BR_OBJECTS.map_rule_type_code%TYPE
28                                 := 'DIMENSION';
29 G_FACTOR_TABLE       CONSTANT FEM_ALLOC_BR_OBJECTS.map_rule_type_code%TYPE
30                                 := 'FACTOR_TABLE';
31 G_NUMBER_TYPE        CONSTANT VARCHAR2(15) := 'NUMBER';
32 G_VARCHAR_TYPE       CONSTANT VARCHAR2(15) := 'VARCHAR';
33 G_UNSUPPORTED_TYPE   CONSTANT VARCHAR2(15) := 'UNSUPPORTED';
34 G_LEDGER_AMOUNT_COL  CONSTANT VARCHAR2(30) := 'XTD_BALANCE_F';
35 
36 -------------------------------------------------------------------------------
37 -- PRIVATE SPECIFICATIONS
38 -------------------------------------------------------------------------------
39 
40 PROCEDURE GetSelectClause(
41   p_preview_obj_def_id     IN NUMBER,
42   p_preview_obj_id         IN NUMBER,
43   p_request_id             IN NUMBER,
44   p_preview_row_group      IN VARCHAR2,
45   p_fact_table_name        IN VARCHAR2,
46   x_select_clause          OUT NOCOPY VARCHAR2);
47 
48 PROCEDURE GetMapTableType(
49   p_table_name             IN VARCHAR2,
50   x_map_table_type         OUT NOCOPY VARCHAR2);
51 
52 PROCEDURE GetOutputMatchingTable(
53   p_preview_obj_def_id      IN NUMBER,
54   x_output_match_temp_table OUT NOCOPY VARCHAR2,
55   x_output_match_fact_table OUT NOCOPY VARCHAR2);
56 
57 PROCEDURE GetFromClause(
58   p_fact_table_name         IN VARCHAR2,
59   x_from_clause             OUT NOCOPY VARCHAR2);
60 
61 PROCEDURE GetWhereClause(
62   p_preview_obj_def_id      IN NUMBER,
63   p_preview_row_group       IN VARCHAR2,
64   p_map_obj_def_id          IN NUMBER,
65   p_map_rule_type           IN VARCHAR2,
66   p_function_cd             IN VARCHAR2,
67   p_sub_obj_id              IN NUMBER,
68   p_fact_table_name         IN VARCHAR2,
69   p_request_id              IN NUMBER,
70   p_preview_obj_id          IN NUMBER,
71   x_map_where_clause        OUT NOCOPY VARCHAR2,
72   x_where_clause            OUT NOCOPY VARCHAR2);
73 
74 PROCEDURE GetInputWhereClause(
75   p_preview_obj_def_id      IN NUMBER,
76   p_preview_row_group       IN VARCHAR2,
77   p_map_obj_def_id          IN NUMBER,
78   p_map_rule_type           IN VARCHAR2,
79   p_fact_table_name         IN VARCHAR2,
80   p_sub_obj_id              IN NUMBER,
81   p_request_id              IN NUMBER,
82   p_preview_obj_id          IN NUMBER,
83   x_map_where_clause        OUT NOCOPY VARCHAR2,
84   x_where_clause            OUT NOCOPY VARCHAR2);
85 
86 PROCEDURE GetOutputWhereClause(
87   p_preview_obj_def_id      IN NUMBER,
88   p_map_obj_def_id          IN NUMBER,
89   p_function_cd             IN VARCHAR2,
90   p_fact_table_name         IN VARCHAR2,
91   x_where_clause            OUT NOCOPY VARCHAR2);
92 
93 PROCEDURE CreateTempTable(
94   p_temp_table_seq      IN NUMBER,
95   p_preview_obj_def_id  IN NUMBER,
96   p_preview_obj_id      IN NUMBER,
97   p_preview_row_group   IN VARCHAR2,
98   p_preview_display_seq IN NUMBER,
99   p_request_id          IN NUMBER,
100   p_map_obj_id          IN VARCHAR2,
101   p_map_obj_def_id      IN VARCHAR2,
102   p_map_rule_type       IN VARCHAR2,
103   p_fact_table_name     IN VARCHAR2,
104   p_function_cd         IN VARCHAR2,
105   p_sub_obj_id          IN NUMBER,
106   x_map_where_clause    OUT NOCOPY VARCHAR2,
107   x_temp_table_name     OUT NOCOPY VARCHAR2);
108 
109 PROCEDURE CreatePreviewStats(
110   p_preview_obj_def_id     IN NUMBER,
111   p_preview_row_group      IN VARCHAR2,
112   p_preview_display_seq    IN NUMBER,
113   p_fact_table_name        IN VARCHAR2,
114   p_temp_table_name        IN VARCHAR2,
115   p_map_where_clause       IN VARCHAR2,
116   p_preview_obj_id         IN NUMBER,
117   p_request_id             IN NUMBER);
118 
119 PROCEDURE CreatePreviewMaps(
120   p_preview_obj_def_id     IN NUMBER,
121   p_preview_row_group      IN VARCHAR2,
122   p_fact_table_name        IN VARCHAR2,
123   p_preview_obj_id         IN NUMBER,
124   p_request_id             IN NUMBER);
125 
126 PROCEDURE UpdatePreviewStats(
127   p_preview_obj_def_id      IN NUMBER,
128   p_preview_row_group       IN VARCHAR2,
129   p_temp_table_name         IN VARCHAR2,
130   p_map_table_type          IN VARCHAR2,
131   p_map_obj_def_id          IN NUMBER,
132   p_ledger_id               IN NUMBER,
133   p_cal_period_id           IN NUMBER);
134 
135 PROCEDURE GetPreviewAmount(
136   p_preview_obj_def_id      IN NUMBER,
137   p_preview_row_group       IN VARCHAR2,
138   p_temp_table_name         IN VARCHAR2,
139   p_map_table_type          IN VARCHAR2,
140   p_map_obj_def_id          IN NUMBER,
141   p_ledger_id               IN NUMBER,
142   p_cal_period_id           IN NUMBER,
143   x_functional_currency     OUT NOCOPY VARCHAR2,
144   x_preview_amount_total    OUT NOCOPY NUMBER);
145 
146 PROCEDURE GetPreviewRowCount(
147   p_temp_table_name         IN VARCHAR2,
148   x_preview_row_count       OUT NOCOPY NUMBER);
149 
150 PROCEDURE CleanOutputTable(
151   p_temp_table_name         IN VARCHAR2,
152   p_fact_table_name         IN VARCHAR2,
153   p_map_table_type          IN VARCHAR2,
154   p_preview_row_group       IN VARCHAR2,
155   p_preview_obj_id          IN NUMBER,
156   p_request_id              IN NUMBER);
157 
158 PROCEDURE PopulateDimensionNames(
159   p_preview_obj_def_id      IN NUMBER,
160   p_preview_row_group       IN VARCHAR2,
161   p_temp_table_name         IN VARCHAR2,
162   p_fact_table_name         IN VARCHAR2,
163   p_ledger_id               IN NUMBER);
164 
165 PROCEDURE GetByDimParams(
166   p_preview_obj_def_id      IN NUMBER,
167   p_preview_row_group       IN VARCHAR2,
168   p_map_obj_def_id          IN NUMBER,
169   p_map_rule_type           IN VARCHAR2,
170   p_fact_table_name         IN VARCHAR2,
171   x_by_dimension_column     OUT NOCOPY VARCHAR2,
172   x_by_dimension_id         OUT NOCOPY VARCHAR2,
173   x_by_dimension_value      OUT NOCOPY VARCHAR2);
174 
175 -------------------------------------------------------------------------------
176 -- PUBLIC BODIES
177 -------------------------------------------------------------------------------
178 
179 -------------------------------------------------------------------------------
180 --
181 -- PROCEDURE
182 --   Remove_Results
183 --
184 -- DESCRIPTION
185 --   This procedure removes the results generated by a Preview execution.
186 --   It deletes data from the FEM_ALLOC_PREVIEW_STATS and
187 --   FEM_ALLOC_PREVIEW_MAPS tables.  It also calls
188 --   FEM_UD_PKG.Remove_Process_Locks to remove the Process Lock
189 --   registration data, and along with it the Preview temporary tables.
190 --
191 --   The Preview UI and FEM_BR_MAPPING_PREVIEW_PVT.DeleteObjectDefinition
192 --   call this API to remove existing Preview results.
193 --
194 -- IN
195 --   p_object_id    -  Preview rule identifier
196 --
197 -------------------------------------------------------------------------------
198 PROCEDURE Remove_Results(
199   p_api_version         IN  NUMBER,
200   p_init_msg_list       IN  VARCHAR2   DEFAULT FND_API.G_FALSE,
201   p_commit              IN  VARCHAR2   DEFAULT FND_API.G_FALSE,
202   p_encoded             IN  VARCHAR2   DEFAULT FND_API.G_TRUE,
203   x_return_status       OUT NOCOPY VARCHAR2,
204   x_msg_count           OUT NOCOPY NUMBER,
205   x_msg_data            OUT NOCOPY VARCHAR2,
206   p_preview_obj_def_id  IN  NUMBER)
207 -------------------------------------------------------------------------------
208 IS
209 
210   C_MODULE            CONSTANT FND_LOG_MESSAGES.module%TYPE :=
211      'fem.plsql.fem_mapping_preview_util_pkg.remove_results';
212   C_API_NAME          CONSTANT VARCHAR2(30) := 'Remove_Results';
213   C_API_VERSION       CONSTANT NUMBER := 1.0;
214 --
215   e_api_error         EXCEPTION;
216   v_request_id        NUMBER;
217   v_preview_obj_id    FEM_OBJECT_DEFINITION_B.object_id%TYPE;
218 --
219   -- Gets all object executions for a given preview rule.
220   -- In some cases, only fem_pl_requests gets registered and so
221   -- in that case, cannot rely on fem_pl_object_executions - hence the UNION.
222   CURSOR c_prvw_execs(cv_obj_def_id NUMBER, cv_request_id NUMBER) IS
223     SELECT request_id
224     FROM fem_pl_object_executions
225     WHERE exec_object_definition_id = cv_obj_def_id
226     UNION
227     SELECT cv_request_id
228     FROM dual
229     ORDER BY request_id;
230 --
231 BEGIN
232 --
233   -- Standard Start of API savepoint
234   SAVEPOINT  remove_results_pub;
235 
236   IF FND_LOG.level_procedure >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
237     FEM_ENGINES_PKG.TECH_MESSAGE(
238       p_severity => FND_LOG.level_procedure,
239       p_module   => C_MODULE,
240       p_msg_text => 'Begin Procedure');
241   END IF;
242 
243   -- Initialize return status to unexpected error
244   x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
245 
246   -- Check for call compatibility.
247   IF NOT FND_API.Compatible_API_Call (C_API_VERSION,
248                 p_api_version,
249                 C_API_NAME,
250                 G_PKG_NAME)
251   THEN
252     IF FND_LOG.level_unexpected >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
253       FEM_ENGINES_PKG.TECH_MESSAGE(
254         p_severity => FND_LOG.level_unexpected,
255         p_module   => C_MODULE,
256         p_msg_text => 'INTERNAL ERROR: API Version ('||C_API_VERSION
257                     ||') not compatible with '
258                     ||'passed in version ('||p_api_version||')');
259     END IF;
260     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
261   END IF;
262 
263   -- Initialize FND message queue
264   IF p_init_msg_list = FND_API.G_TRUE then
265     FND_MSG_PUB.Initialize;
266   END IF;
267 
268   -- Log procedure param values
269   IF FND_LOG.level_statement >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
270     FEM_ENGINES_PKG.TECH_MESSAGE(
271       p_severity => FND_LOG.level_statement,
272       p_module   => C_MODULE,
273       p_msg_text => 'p_preview_obj_def_id = '||to_char(p_preview_obj_def_id));
274   END IF;
275 
276   -- See if Preview has run yet
277   BEGIN
278     SELECT request_id
279     INTO v_request_id
280     FROM fem_alloc_previews
281     WHERE preview_obj_def_id = p_preview_obj_def_id;
282   EXCEPTION
283     WHEN no_data_found THEN
284       v_request_id := -1;
285   END;
286 
287   -- If Preview has been run, remove the last execution, as well as
288   -- any straglers out there due to errors or what not.
289   IF v_request_id > -1 THEN
290     -- get preview object id
291     v_preview_obj_id := FEM_BUSINESS_RULE_PVT.GetObjectId(
292                           p_obj_def_id => p_preview_obj_def_id);
293 
294     -- Loop through all preview executions for a given preview version
295     FOR prvw_execs IN c_prvw_execs(cv_obj_def_id => p_preview_obj_def_id,
296                                    cv_request_id => v_request_id) LOOP
297 
298       -- Remove process locks and temporary tables created by Preview execution
299       FEM_UD_PKG.Remove_Process_Locks(
300         p_api_version      => 1.0,
301         p_init_msg_list    => FND_API.G_FALSE,
302         p_commit           => FND_API.G_FALSE,
303         p_encoded          => p_encoded,
304         x_return_status    => x_return_status,
305         x_msg_count        => x_msg_count,
306         x_msg_data         => x_msg_data,
307         p_request_id       => prvw_execs.request_id,
308         p_object_id        => v_preview_obj_id);
309 
310       IF x_return_status <> FND_API.G_RET_STS_SUCCESS THEN
311         IF FND_LOG.level_unexpected >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
312           FEM_ENGINES_PKG.TECH_MESSAGE(
313             p_severity => FND_LOG.level_unexpected,
314             p_module   => C_MODULE,
315             p_msg_text => 'INTERNAL ERROR: Call to'
316                         ||' FEM_UD_PKG.Remove_Process_Locks'
317                         ||' failed with return status: '||x_return_status);
318         END IF;
319 
320         RAISE e_api_error;
321       END IF;
322 
323     END LOOP; -- FOR prvw_execs...
324 
325   END IF;  -- IF v_request_id > -1 THEN
326 
327   -- Now delete all data created by the preview execution in the
328   -- persistent preview output tables
329 
330   DELETE FROM fem_alloc_preview_stats
331   WHERE preview_obj_def_id = p_preview_obj_def_id;
332 
333   IF FND_LOG.level_statement >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
334     FEM_ENGINES_PKG.TECH_MESSAGE(
335       p_severity => FND_LOG.level_statement,
336       p_module   => C_MODULE,
337       p_msg_text => 'Deleted '||SQL%ROWCOUNT
338                   ||' rows from FEM_ALLOC_PREVIEW_STATS');
339   END IF;
340 
341   DELETE FROM fem_alloc_preview_maps
342   WHERE preview_obj_def_id = p_preview_obj_def_id;
343 
344   IF FND_LOG.level_statement >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
345     FEM_ENGINES_PKG.TECH_MESSAGE(
346       p_severity => FND_LOG.level_statement,
347       p_module   => C_MODULE,
348       p_msg_text => 'Deleted '||SQL%ROWCOUNT
349                   ||' rows from FEM_ALLOC_PREVIEW_MAPS');
350   END IF;
351 
352   FND_MSG_PUB.Count_And_Get(p_encoded => p_encoded,
353                               p_count => x_msg_count,
354                               p_data => x_msg_data);
355 
356   x_return_status := FND_API.G_RET_STS_SUCCESS;
357 
358   IF (p_commit = FND_API.G_TRUE) THEN
359     COMMIT;
360   END IF;
361 
362   IF FND_LOG.level_procedure >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
363     FEM_ENGINES_PKG.TECH_MESSAGE(
364       p_severity => FND_LOG.level_procedure,
365       p_module   => C_MODULE,
366       p_msg_text => 'End Procedure');
367   END IF;
368 --
369 EXCEPTION
370   -- Since this procedure drops temp tables, rollback segments are lost
371   -- and so instead of rolling back to specific save point, just rollback
372   -- completely.
373   WHEN e_api_error THEN
374     -- When a call to an API fails, just exit because all return params
375     -- have already been set by the API itself.
376     ROLLBACK;
377   WHEN others THEN
378     ROLLBACK;
379 
380     IF FND_LOG.level_unexpected >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
381       FEM_ENGINES_PKG.TECH_MESSAGE(
382         p_severity => FND_LOG.level_unexpected,
383         p_module   => C_MODULE,
384         p_msg_text => 'Unexpected error: '||SQLERRM);
385     END IF;
386     IF FND_LOG.level_procedure >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
387       FEM_ENGINES_PKG.TECH_MESSAGE(
388         p_severity => FND_LOG.level_procedure,
389         p_module   => C_MODULE,
390         p_msg_text => 'End Procedure');
391     END IF;
392 
393     -- Log the Oracle error message to the stack.
394     FEM_ENGINES_PKG.USER_MESSAGE(
395       p_app_name =>'FEM',
396       p_msg_name => 'FEM_UNEXPECTED_ERROR',
397       p_token1 => 'ERR_MSG',
398       p_value1 => SQLERRM);
399 
400     FND_MSG_PUB.Count_And_Get(p_encoded => p_encoded,
401                               p_count => x_msg_count,
402                               p_data => x_msg_data);
403 
404     x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
405 --
406 END Remove_Results;
407 -------------------------------------------------------------------------------
408 
409 -------------------------------------------------------------------------------
410 --
411 -- PROCEDURE
412 --   Pre_Process
413 --
414 -- DESCRIPTION
415 --   This procedure is responsible for the pre-processing steps
416 --   to prepare for CCE to run in preview mode.
417 --   For each "preview row group", e.g. SOURCE, DRIVER, CREDIT, DEBIT,
418 --   create a temporary table that mirrors the corresponding fact table
419 --   and store those table names in the FEM_ALLOC_PREVIEW_STATS table.
420 --
421 -- IN
422 --   p_obj_def_id    -  Preview rule ID
423 --   p_request_id    -  Preview execution concurrent request ID
424 --
425 -------------------------------------------------------------------------------
426 PROCEDURE Pre_Process(
427   p_api_version         IN  NUMBER,
428   p_init_msg_list       IN  VARCHAR2   DEFAULT FND_API.G_FALSE,
429   p_commit              IN  VARCHAR2   DEFAULT FND_API.G_FALSE,
430   p_encoded             IN  VARCHAR2   DEFAULT FND_API.G_TRUE,
431   x_return_status       OUT NOCOPY VARCHAR2,
432   x_msg_count           OUT NOCOPY NUMBER,
433   x_msg_data            OUT NOCOPY VARCHAR2,
434   p_preview_obj_def_id  IN  NUMBER,
435   p_request_id          IN  NUMBER)
436 -------------------------------------------------------------------------------
437 IS
438 
439   C_MODULE            CONSTANT FND_LOG_MESSAGES.module%TYPE :=
440      'fem.plsql.fem_mapping_preview_util_pkg.pre_process';
441   C_API_NAME          CONSTANT VARCHAR2(30) := 'Pre_Process';
442   C_API_VERSION       CONSTANT NUMBER := 1.0;
443 --
444   v_preview_obj_id    FEM_OBJECT_DEFINITION_B.object_id%TYPE;
445   v_map_obj_def_id    FEM_OBJECT_DEFINITION_B.object_definition_id%TYPE;
446   v_map_obj_id        FEM_OBJECT_DEFINITION_B.object_id%TYPE;
447   v_stat_obj_def_id   FEM_OBJECT_DEFINITION_B.object_definition_id%TYPE;
448   v_fact_table_name   FEM_ALLOC_PREVIEW_STATS.fact_table_name%TYPE;
449   v_temp_table_name   FEM_ALLOC_PREVIEW_STATS.temp_table_name%TYPE;
450   v_map_rule_type     FEM_ALLOC_BR_OBJECTS.map_rule_type_code%TYPE;
451   v_temp_table_seq    NUMBER;
452   v_map_where_clause  VARCHAR2(16000);
453   v_create_temp_table BOOLEAN;
454   v_debit_table_name  FEM_ALLOC_PREVIEW_STATS.fact_table_name%TYPE;
455 --
456   -- Gets information related to each preview row group needed to
457   -- create the temporary tables.
458   -- p_obj_def_id is the rule version of the parent mapping rule.
459   CURSOR c_row_group_info (cv_obj_def_id NUMBER) IS
460     SELECT f.table_name, f.function_cd, f.sub_object_id,
461            m.preview_row_group, m.preview_row_group_display_seq
462     FROM fem_alloc_br_formula f, fem_function_cd_mapping m
463     WHERE f.function_cd = m.function_cd
464     AND f.object_definition_id = cv_obj_def_id
465     AND nvl(f.enable_flg,'Y') = 'Y'
466     ORDER BY m.preview_row_group_process_seq;
467 --
468 BEGIN
469 --
470   -- Standard Start of API savepoint
471   SAVEPOINT  pre_process_pub;
472 
473   IF FND_LOG.level_procedure >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
474     FEM_ENGINES_PKG.TECH_MESSAGE(
475       p_severity => FND_LOG.level_procedure,
476       p_module   => C_MODULE,
477        p_msg_text => 'Begin Procedure');
478   END IF;
479 
480   -- Initialize return status to unexpected error
481   x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
482 
483   -- Check for call compatibility.
484   IF NOT FND_API.Compatible_API_Call (C_API_VERSION,
485                 p_api_version,
486                 C_API_NAME,
487                 G_PKG_NAME)
488   THEN
489     IF FND_LOG.level_unexpected >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
490       FEM_ENGINES_PKG.TECH_MESSAGE(
491         p_severity => FND_LOG.level_unexpected,
492         p_module   => C_MODULE,
493         p_msg_text => 'INTERNAL ERROR: API Version ('||C_API_VERSION
494                     ||') not compatible with '
495                     ||'passed in version ('||p_api_version||')');
496     END IF;
497     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
498   END IF;
499 
500   -- Initialize FND message queue
501   IF p_init_msg_list = FND_API.G_TRUE then
502     FND_MSG_PUB.Initialize;
503   END IF;
504 
505   -- Log procedure param values
506   IF FND_LOG.level_statement >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
507     FEM_ENGINES_PKG.TECH_MESSAGE(
508       p_severity => FND_LOG.level_statement,
509       p_module   => C_MODULE,
510       p_msg_text => 'p_preview_obj_def_id = '||to_char(p_preview_obj_def_id));
511     FEM_ENGINES_PKG.TECH_MESSAGE(
512       p_severity => FND_LOG.level_statement,
513       p_module   => C_MODULE,
514       p_msg_text => 'p_request_id = '||to_char(p_request_id));
515   END IF;
516 
517   -- Get preview object_id
518   v_preview_obj_id := FEM_BUSINESS_RULE_PVT.GetObjectId(
519                           p_obj_def_id => p_preview_obj_def_id);
520 
521   -- Get mapping object definition id
522   SELECT object_definition_id, object_id
523   INTO v_map_obj_def_id, v_map_obj_id
524   FROM fem_objdef_helper_rules
525   WHERE helper_obj_def_id = p_preview_obj_def_id
526   AND helper_object_type_code = 'MAPPING_PREVIEW';
527 
528   IF FND_LOG.level_statement >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
529     FEM_ENGINES_PKG.TECH_MESSAGE(
530       p_severity => FND_LOG.level_statement,
531       p_module   => C_MODULE,
532       p_msg_text => 'v_map_obj_id = '||to_char(v_map_obj_id));
533     FEM_ENGINES_PKG.TECH_MESSAGE(
534       p_severity => FND_LOG.level_statement,
535       p_module   => C_MODULE,
536       p_msg_text => 'v_map_obj_def_id = '||to_char(v_map_obj_def_id));
537   END IF;
538 
539   -- Get map rule type
540   SELECT map_rule_type_code
541   INTO v_map_rule_type
542   FROM fem_alloc_br_objects
543   WHERE map_rule_object_id = v_map_obj_id;
544 
545   IF FND_LOG.level_statement >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
546     FEM_ENGINES_PKG.TECH_MESSAGE(
547       p_severity => FND_LOG.level_statement,
548       p_module   => C_MODULE,
549       p_msg_text => 'v_map_rule_type = '||v_map_rule_type);
550   END IF;
551 
552   -- Preview does not support Factor Table rules yet...
553   IF (v_map_rule_type = G_FACTOR_TABLE) THEN
554     IF FND_LOG.level_unexpected >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
555       FEM_ENGINES_PKG.TECH_MESSAGE(
556         p_severity => FND_LOG.level_unexpected,
557         p_module   => C_MODULE,
558         p_msg_text => 'Preview does not support Factor Table rules!');
559     END IF;
560     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
561   END IF;
562 
563   -- Counter for number of temp objects being created
564   v_temp_table_seq := 0;
565 
566   -- For each preview group, create the temporary table
567   -- and insert the temporary table information in FEM_ALLOC_PREVIEW_STATS.
568   FOR row_group IN c_row_group_info(cv_obj_def_id => v_map_obj_def_id) LOOP
569 
570     -- If the Mapping Rule Type is By Dimension and
571     -- Preview Row Group is DRIVER, do nothing.  By Dimension rule
572     -- does not have a DRIVER from the Preview perspective.
573     --
574     -- The reason is that CCE only looks at the "SOURCE" table when processing
575     -- the By Dimension rule type.  It issues a
576     --   SUM(DECODE(by_dim_col, by_dim_val, 0, balances_f)),
577     --   SUM(DECODE(by_dim_col, by_dim_val, balances_f, 0))
578     -- statement to get the non-By Dim value and the By Dim value in one SQL
579     -- Therefore, the By Dimension temporary source table needs to contain
580     -- both By Dim and non-By Dim value.
581 
582     IF (v_map_rule_type = G_BY_DIMENSION) AND
583        (row_group.preview_row_group = G_DRIVER) THEN
584 
585       null;
586 
587     ELSE
588 
589       v_temp_table_seq := v_temp_table_seq + 1;
590 
591       -- First, assume fact table name is from FEM_ALLOC_BR_FORMULA.TABLE_NAME
592       v_fact_table_name := row_group.table_name;
593 
594       -- If this is the driver and the mapping rule type is Retrieve Stats,
595       -- get the fact table name from FEM_STAT_LOOKUPS.STAT_LOOKUP_TABLE
596       -- instead of FEM_ALLOC_BR_FORMULA.TABLE_NAME.
597       IF row_group.preview_row_group = G_DRIVER AND
598          v_map_rule_type = G_RETRIEVE_STAT THEN
599 
600         -- First get Stat Lookup obj def id
601         SELECT object_definition_id
602         INTO v_stat_obj_def_id
603         FROM fem_object_definition_b
604         WHERE object_id = row_group.sub_object_id;
605 
606         SELECT stat_lookup_table
607         INTO v_fact_table_name
608         FROM fem_stat_lookups
609         WHERE stat_lookup_obj_def_id = v_stat_obj_def_id;
610 
611       END IF;
612 
613       CreatePreviewMaps(
614         p_preview_obj_def_id   => p_preview_obj_def_id,
615         p_preview_row_group    => row_group.preview_row_group,
616         p_fact_table_name      => v_fact_table_name,
617         p_preview_obj_id       => v_preview_obj_id,
618         p_request_id           => p_request_id);
619 
620       -- Only create one temp table for each target fact table because
621       -- if the same fact table is designated for both credit and debit,
622       -- it does not make sense to write out to separate temp tables.
623       --
624       -- Since we know from
625       -- FEM_FUNCTION_CD_MAPPING.preview_row_group_process_seq
626       -- that DEBIT is processed first, we will only check if CREDIT table
627       -- is the same as the DEBIT table.  If there was no DEBIT table,
628       -- then we automatically need to create a CREDIT table.
629       v_create_temp_table := FALSE;
630       IF (row_group.preview_row_group = G_DEBIT) THEN
631         v_debit_table_name := v_fact_table_name;
632         v_create_temp_table := TRUE;
633       ELSIF (row_group.preview_row_group = G_CREDIT) THEN
634         IF ((v_debit_table_name IS NOT NULL) AND
635             (v_fact_table_name = v_debit_table_name)) THEN
636           v_create_temp_table := FALSE;
637         ELSE
638           v_create_temp_table := TRUE;
639         END IF;
640       ELSE
641         v_create_temp_table := TRUE;
642       END IF;
643 
644       IF (v_create_temp_table) THEN
645         CreateTempTable(
646           p_temp_table_seq       => v_temp_table_seq,
647           p_preview_obj_def_id   => p_preview_obj_def_id,
648           p_preview_obj_id       => v_preview_obj_id,
649           p_preview_row_group    => row_group.preview_row_group,
650           p_preview_display_seq  => row_group.preview_row_group_display_seq,
651           p_request_id           => p_request_id,
652           p_map_obj_id           => v_map_obj_id,
653           p_map_obj_def_id       => v_map_obj_def_id,
654           p_map_rule_type        => v_map_rule_type,
655           p_fact_table_name      => v_fact_table_name,
656           p_function_cd          => row_group.function_cd,
657           p_sub_obj_id           => row_group.sub_object_id,
658           x_map_where_clause     => v_map_where_clause,
659           x_temp_table_name      => v_temp_table_name);
660       END IF;
661 
662       CreatePreviewStats(
663         p_preview_obj_def_id   => p_preview_obj_def_id,
664         p_preview_row_group    => row_group.preview_row_group,
665         p_preview_display_seq  => row_group.preview_row_group_display_seq,
666         p_fact_table_name      => v_fact_table_name,
667         p_temp_table_name      => v_temp_table_name,
668         p_map_where_clause     => v_map_where_clause,
669         p_preview_obj_id       => v_preview_obj_id,
670         p_request_id           => p_request_id);
671 
672     END IF; -- IF (v_map_rule_tyep = G_BY_DIMENSION) AND ...
673 
674   END LOOP;
675 
676   FND_MSG_PUB.Count_And_Get(p_encoded => p_encoded,
677                               p_count => x_msg_count,
678                               p_data => x_msg_data);
679 
680   x_return_status := FND_API.G_RET_STS_SUCCESS;
681 
682   IF (p_commit = FND_API.G_TRUE) THEN
683     COMMIT;
684   END IF;
685 
686   IF FND_LOG.level_procedure >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
687     FEM_ENGINES_PKG.TECH_MESSAGE(
688       p_severity => FND_LOG.level_procedure,
689       p_module   => C_MODULE,
690       p_msg_text => 'End Procedure');
691   END IF;
692 --
693 EXCEPTION
694   -- Since this procedure drops temp tables, rollback segments are lost
695   -- and so instead of rolling back to specific save point, just rollback
696   -- completely.
697   WHEN others THEN
698     ROLLBACK;
699 
700     IF FND_LOG.level_unexpected >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
701       FEM_ENGINES_PKG.TECH_MESSAGE(
702         p_severity => FND_LOG.level_unexpected,
703         p_module   => C_MODULE,
704         p_msg_text => 'Unexpected error: '||SQLERRM);
705     END IF;
706     IF FND_LOG.level_procedure >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
707       FEM_ENGINES_PKG.TECH_MESSAGE(
708         p_severity => FND_LOG.level_procedure,
709         p_module   => C_MODULE,
710         p_msg_text => 'End Procedure');
711     END IF;
712 
713     -- Log the Oracle error message to the stack.
714     FEM_ENGINES_PKG.USER_MESSAGE(
715       p_app_name =>'FEM',
716       p_msg_name => 'FEM_UNEXPECTED_ERROR',
717       p_token1 => 'ERR_MSG',
718       p_value1 => SQLERRM);
719 
720     FND_MSG_PUB.Count_And_Get(p_encoded => p_encoded,
721                               p_count => x_msg_count,
722                               p_data => x_msg_data);
723 
724     x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
725 --
726 END Pre_Process;
727 -------------------------------------------------------------------------------
728 
729 -------------------------------------------------------------------------------
730 --
731 -- PROCEDURE
732 --   Post_Process
733 --
734 -- DESCRIPTION
735 --   This procedure is responsible for the post-processing steps of:
736 --   1. generating the preview statistics
737 --   2. populating the dimension name columns in the temporary tables
738 --
739 -- IN
740 --   p_preview_obj_def_id    -  Preview rule ID
741 --   p_request_id    -  Preview execution concurrent request ID
742 --
743 -------------------------------------------------------------------------------
744 PROCEDURE Post_Process(
745   p_api_version         IN  NUMBER,
746   p_init_msg_list       IN  VARCHAR2   DEFAULT FND_API.G_FALSE,
747   p_commit              IN  VARCHAR2   DEFAULT FND_API.G_FALSE,
748   p_encoded             IN  VARCHAR2   DEFAULT FND_API.G_TRUE,
749   x_return_status       OUT NOCOPY VARCHAR2,
750   x_msg_count           OUT NOCOPY NUMBER,
751   x_msg_data            OUT NOCOPY VARCHAR2,
752   p_preview_obj_def_id  IN  NUMBER,
753   p_request_id          IN  NUMBER)
754 -------------------------------------------------------------------------------
755 IS
756 
757   C_MODULE            CONSTANT FND_LOG_MESSAGES.module%TYPE :=
758      'fem.plsql.fem_mapping_preview_util_pkg.post_process';
759   C_API_NAME          CONSTANT VARCHAR2(30) := 'Post_Process';
760   C_API_VERSION       CONSTANT NUMBER := 1.0;
761   v_map_obj_def_id    FEM_OBJECT_DEFINITION_B.object_definition_id%TYPE;
762   v_map_obj_id        FEM_OBJECT_DEFINITION_B.object_id%TYPE;
763   v_preview_obj_id    FEM_OBJECT_DEFINITION_B.object_id%TYPE;
764   v_ledger_id         FEM_ALLOC_PREVIEWS.ledger_id%TYPE;
765   v_cal_period_id     FEM_ALLOC_PREVIEWS.cal_period_id%TYPE;
766   v_map_table_type    VARCHAR2(30);
767 --
768   -- Gets information related to each preview row group needed to
769   -- update the Preview Stats and populate the dimension names.
770   CURSOR c_row_group_info (cv_preview_obj_def_id NUMBER) IS
771     SELECT fact_table_name, temp_table_name, preview_row_group
772     FROM fem_alloc_preview_stats
773     WHERE preview_obj_def_id = cv_preview_obj_def_id
774     ORDER BY preview_row_group_display_seq;
775 --
776 BEGIN
777 --
778   -- Standard Start of API savepoint
779   SAVEPOINT  post_process_pub;
780 
781   IF FND_LOG.level_procedure >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
782     FEM_ENGINES_PKG.TECH_MESSAGE(
783       p_severity => FND_LOG.level_procedure,
784       p_module   => C_MODULE,
785       p_msg_text => 'Begin Procedure');
786   END IF;
787 
788   -- Initialize return status to unexpected error
789   x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
790 
791   -- Check for call compatibility.
792   IF NOT FND_API.Compatible_API_Call (C_API_VERSION,
793                 p_api_version,
794                 C_API_NAME,
795                 G_PKG_NAME)
796   THEN
797     IF FND_LOG.level_unexpected >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
798       FEM_ENGINES_PKG.TECH_MESSAGE(
799         p_severity => FND_LOG.level_unexpected,
800         p_module   => C_MODULE,
801         p_msg_text => 'INTERNAL ERROR: API Version ('||C_API_VERSION
802                     ||') not compatible with '
803                     ||'passed in version ('||p_api_version||')');
804     END IF;
805     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
806   END IF;
807 
808   -- Initialize FND message queue
809   IF p_init_msg_list = FND_API.G_TRUE then
810     FND_MSG_PUB.Initialize;
811   END IF;
812 
813   -- Log procedure param values
814   IF FND_LOG.level_statement >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
815     FEM_ENGINES_PKG.TECH_MESSAGE(
816       p_severity => FND_LOG.level_statement,
817       p_module   => C_MODULE,
818       p_msg_text => 'p_preview_obj_def_id = '||to_char(p_preview_obj_def_id));
819   END IF;
820 
821   -- Get the corresponding Mapping object id and object definition id
822   SELECT object_id, object_definition_id
823   INTO v_map_obj_id, v_map_obj_def_id
824   FROM fem_objdef_helper_rules
825   WHERE helper_obj_def_id = p_preview_obj_def_id
826   AND helper_object_type_code = 'MAPPING_PREVIEW';
827 
828   IF FND_LOG.level_statement >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
829     FEM_ENGINES_PKG.TECH_MESSAGE(
830       p_severity => FND_LOG.level_statement,
831       p_module   => C_MODULE,
832       p_msg_text => 'v_map_obj_def_id = '||to_char(v_map_obj_def_id));
833   END IF;
834 
835   -- Get the preview object id
836   v_preview_obj_id := FEM_BUSINESS_RULE_PVT.GetObjectId(
837                         p_obj_def_id => p_preview_obj_def_id);
838 
839   -- Get preview parameter values
840   SELECT ledger_id, cal_period_id
841   INTO v_ledger_id, v_cal_period_id
842   FROM fem_alloc_previews
843   WHERE preview_obj_def_id = p_preview_obj_def_id;
844 
845   FOR row_group IN c_row_group_info(p_preview_obj_def_id) LOOP
846 
847     GetMapTableType(
848       p_table_name       => row_group.fact_table_name,
849       x_map_table_type   => v_map_table_type);
850 
851     CleanOutputTable(
852       p_temp_table_name         => row_group.temp_table_name,
853       p_fact_table_name         => row_group.fact_table_name,
854       p_map_table_type          => v_map_table_type,
855       p_preview_row_group       => row_group.preview_row_group,
856       p_preview_obj_id          => v_preview_obj_id,
857       p_request_id              => p_request_id);
858 
859     UpdatePreviewStats(
860       p_preview_obj_def_id      => p_preview_obj_def_id,
861       p_preview_row_group       => row_group.preview_row_group,
862       p_temp_table_name         => row_group.temp_table_name,
863       p_map_table_type          => v_map_table_type,
864       p_map_obj_def_id          => v_map_obj_def_id,
865       p_ledger_id               => v_ledger_id,
866       p_cal_period_id           => v_cal_period_id);
867 
868     PopulateDimensionNames(
869       p_preview_obj_def_id      => p_preview_obj_def_id,
870       p_preview_row_group       => row_group.preview_row_group,
871       p_temp_table_name         => row_group.temp_table_name,
872       p_fact_table_name         => row_group.fact_table_name,
873       p_ledger_id               => v_ledger_id);
874 
875   END LOOP;
876 
877   FND_MSG_PUB.Count_And_Get(p_encoded => p_encoded,
878                               p_count => x_msg_count,
879                               p_data => x_msg_data);
880 
881   x_return_status := FND_API.G_RET_STS_SUCCESS;
882 
883   IF (p_commit = FND_API.G_TRUE) THEN
884     COMMIT;
885   END IF;
886 
887   IF FND_LOG.level_procedure >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
888     FEM_ENGINES_PKG.TECH_MESSAGE(
889       p_severity => FND_LOG.level_procedure,
890       p_module   => C_MODULE,
891       p_msg_text => 'End Procedure');
892   END IF;
893 --
894 EXCEPTION
895   -- Since this procedure drops temp tables, rollback segments are lost
896   -- and so instead of rolling back to specific save point, just rollback
897   -- completely.
898   WHEN others THEN
899     ROLLBACK;
900 
901     IF FND_LOG.level_unexpected >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
902       FEM_ENGINES_PKG.TECH_MESSAGE(
903         p_severity => FND_LOG.level_unexpected,
904         p_module   => C_MODULE,
905         p_msg_text => 'Unexpected error: '||SQLERRM);
906     END IF;
907     IF FND_LOG.level_procedure >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
908       FEM_ENGINES_PKG.TECH_MESSAGE(
909         p_severity => FND_LOG.level_procedure,
910         p_module   => C_MODULE,
911         p_msg_text => 'End Procedure');
912     END IF;
913 
914     -- Log the Oracle error message to the stack.
915     FEM_ENGINES_PKG.USER_MESSAGE(
916       p_app_name =>'FEM',
917       p_msg_name => 'FEM_UNEXPECTED_ERROR',
918       p_token1 => 'ERR_MSG',
919       p_value1 => SQLERRM);
920 
921     FND_MSG_PUB.Count_And_Get(p_encoded => p_encoded,
922                               p_count => x_msg_count,
923                               p_data => x_msg_data);
924 
925     x_return_status := FND_API.G_RET_STS_UNEXP_ERROR;
926 --
927 END Post_Process;
928 -------------------------------------------------------------------------------
929 
930 -------------------------------------------------------------------------------
931 -- PRIVATE BODIES
932 -------------------------------------------------------------------------------
933 
934 -------------------------------------------------------------------------------
935 --
936 -- PROCEDURE
937 --   CreateTempTable
938 --
939 -- DESCRIPTION
940 --   Creates the temporary table based on the fact table being passed in.
941 --   Also create an index on the temporary table based on the
942 --   fact table processing key.
943 --
944 -------------------------------------------------------------------------------
945 PROCEDURE CreateTempTable(
946   p_temp_table_seq      IN NUMBER,
947   p_preview_obj_def_id  IN NUMBER,
948   p_preview_obj_id      IN NUMBER,
949   p_preview_row_group   IN VARCHAR2,
950   p_preview_display_seq IN NUMBER,
951   p_request_id          IN NUMBER,
952   p_map_obj_id          IN VARCHAR2,
953   p_map_obj_def_id      IN VARCHAR2,
954   p_map_rule_type       IN VARCHAR2,
955   p_fact_table_name     IN VARCHAR2,
956   p_function_cd         IN VARCHAR2,
957   p_sub_obj_id          IN NUMBER,
958   x_map_where_clause    OUT NOCOPY VARCHAR2,
959   x_temp_table_name     OUT NOCOPY VARCHAR2
960 )
961 -------------------------------------------------------------------------------
962 IS
963 --
964   C_MODULE             CONSTANT FND_LOG_MESSAGES.module%TYPE :=
965      'fem.plsql.fem_mapping_preview_util_pkg.CreateTempTable';
966   v_select_clause      VARCHAR2(16383);
967   v_from_clause        VARCHAR2(4095);
968   v_where_clause       VARCHAR2(32767);
969   v_return_status      VARCHAR2(1);
970   v_msg_count          NUMBER;
971   v_msg_data           VARCHAR2(4000);
972   v_index_name         VARCHAR2(30);
973   v_index_columns      VARCHAR2(4000);
974 --
975   CURSOR c_index_cols (cv_table_name VARCHAR2) IS
976     SELECT c.column_name
977     FROM dba_ind_columns c, user_synonyms s, fem_tables_b t
978     WHERE t.table_name = cv_table_name
979     AND t.table_name = s.synonym_name
980     AND s.table_name = c.table_name
981     AND t.proc_key_index_owner = c.table_owner
982     AND t.proc_key_index_name = c.index_name
983     AND t.proc_key_index_owner = c.index_owner
984     ORDER BY column_position;
985 --
986 BEGIN
987 --
988   IF FND_LOG.level_procedure >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
989     FEM_ENGINES_PKG.TECH_MESSAGE(
990       p_severity => FND_LOG.level_procedure,
991       p_module   => C_MODULE,
992       p_msg_text => 'Begin Procedure');
993   END IF;
994 
995   IF FND_LOG.level_statement >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
996     FEM_ENGINES_PKG.TECH_MESSAGE(
997       p_severity => FND_LOG.level_statement,
998       p_module   => C_MODULE,
999       p_msg_text => 'p_fact_table_name = '||p_fact_table_name);
1000     FEM_ENGINES_PKG.TECH_MESSAGE(
1001       p_severity => FND_LOG.level_statement,
1002       p_module   => C_MODULE,
1003       p_msg_text => 'p_preview_row_group = '||p_preview_row_group);
1004     FEM_ENGINES_PKG.TECH_MESSAGE(
1005       p_severity => FND_LOG.level_statement,
1006       p_module   => C_MODULE,
1007       p_msg_text => 'p_function_cd = '||p_function_cd);
1008     FEM_ENGINES_PKG.TECH_MESSAGE(
1009       p_severity => FND_LOG.level_statement,
1010       p_module   => C_MODULE,
1011       p_msg_text => 'p_sub_obj_id = '||p_sub_obj_id);
1012 
1013   END IF;
1014 
1015   -- First get a unique temp table name
1016   FEM_DATABASE_UTIL_PKG.Get_Unique_Temp_Name(
1017     p_api_version           => 1.0,
1018     p_init_msg_list         => FND_API.G_FALSE,
1019     p_commit                => FND_API.G_FALSE,
1020     p_encoded               => FND_API.G_TRUE,
1021     x_return_status         => v_return_status,
1022     x_msg_count             => v_msg_count,
1023     x_msg_data              => v_msg_data,
1024     p_temp_type             => 'TABLE',
1025     p_request_id            => p_request_id,
1026     p_object_id             => p_preview_obj_id,
1027     p_table_seq             => p_temp_table_seq,
1028     x_temp_name             => x_temp_table_name);
1029 
1030   IF v_return_status <> FND_API.G_RET_STS_SUCCESS THEN
1031     IF FND_LOG.level_unexpected >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
1032       FEM_ENGINES_PKG.TECH_MESSAGE(
1033         p_severity => FND_LOG.level_unexpected,
1034         p_module   => C_MODULE,
1035         p_msg_text => 'INTERNAL ERROR: Call to'
1036                     ||' FEM_DATABASE_UTIL_PKG.Get_Unique_Temp_Name'
1037                     ||' failed with return status: '||v_return_status);
1038     END IF;
1039 
1040     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1041   END IF;
1042 
1043   -- Then build the SQL to create the temporary SQL
1044   GetSelectClause(
1045     p_preview_obj_def_id    => p_preview_obj_def_id,
1046     p_preview_obj_id        => p_preview_obj_id,
1047     p_request_id            => p_request_id,
1048     p_preview_row_group     => p_preview_row_group,
1049     p_fact_table_name       => p_fact_table_name,
1050     x_select_clause         => v_select_clause);
1051 
1052   GetFromClause(
1053     p_fact_table_name         => p_fact_table_name,
1054     x_from_clause             => v_from_clause);
1055 
1056   GetWhereClause(
1057     p_preview_obj_def_id      => p_preview_obj_def_id,
1058     p_preview_row_group       => p_preview_row_group,
1059     p_map_obj_def_id          => p_map_obj_def_id ,
1060     p_map_rule_type           => p_map_rule_type,
1061     p_function_cd             => p_function_cd,
1062     p_sub_obj_id              => p_sub_obj_id,
1063     p_fact_table_name         => p_fact_table_name ,
1064     p_request_id              => p_request_id,
1065     p_preview_obj_id          => p_preview_obj_id,
1066     x_map_where_clause        => x_map_where_clause,
1067     x_where_clause            => v_where_clause);
1068 
1069   -- Create the temp table
1070   FEM_DATABASE_UTIL_PKG.Create_Temp_Table(
1071     p_api_version           => 1.0,
1072     p_init_msg_list         => FND_API.G_FALSE,
1073     p_commit                => FND_API.G_FALSE,
1074     p_encoded               => FND_API.G_TRUE,
1075     x_return_status         => v_return_status,
1076     x_msg_count             => v_msg_count,
1077     x_msg_data              => v_msg_data,
1078     p_request_id            => p_request_id,
1079     p_object_id             => p_preview_obj_id,
1080     p_pb_object_id          => p_map_obj_id,
1081     p_table_name            => x_temp_table_name,
1082     p_table_def             => 'AS '||v_select_clause||' '
1083                              ||v_from_clause||' '||v_where_clause);
1084 
1085   IF v_return_status <> FND_API.G_RET_STS_SUCCESS THEN
1086     IF FND_LOG.level_unexpected >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
1087       FEM_ENGINES_PKG.TECH_MESSAGE(
1088         p_severity => FND_LOG.level_unexpected,
1089         p_module   => C_MODULE,
1090         p_msg_text => 'INTERNAL ERROR: Call to'
1091                     ||' FEM_DATABASE_UTIL_PKG.Create_Temp_Table'
1092                     ||' failed with return status: '||v_return_status);
1093     END IF;
1094 
1095     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1096   END IF;
1097 
1098   -- First see if there are any index columns
1099   FOR index_col IN c_index_cols(cv_table_name => p_fact_table_name) LOOP
1100     IF v_index_columns IS NULL THEN
1101       v_index_columns := index_col.column_name;
1102     ELSE
1103       v_index_columns := v_index_columns||','||index_col.column_name;
1104     END IF;
1105   END LOOP;
1106 
1107   IF v_index_columns IS NOT NULL THEN
1108 
1109     -- Get a unique temp index name before creating it
1110     FEM_DATABASE_UTIL_PKG.Get_Unique_Temp_Name(
1111       p_api_version           => 1.0,
1112       p_init_msg_list         => FND_API.G_FALSE,
1113       p_commit                => FND_API.G_FALSE,
1114       p_encoded               => FND_API.G_TRUE,
1115       x_return_status         => v_return_status,
1116       x_msg_count             => v_msg_count,
1117       x_msg_data              => v_msg_data,
1118       p_temp_type             => 'INDEX',
1119       p_request_id            => p_request_id,
1120       p_object_id             => p_preview_obj_id,
1121       p_table_seq             => p_temp_table_seq,
1122       x_temp_name             => v_index_name);
1123 
1124     IF v_return_status <> FND_API.G_RET_STS_SUCCESS THEN
1125       IF FND_LOG.level_unexpected >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
1126         FEM_ENGINES_PKG.TECH_MESSAGE(
1127           p_severity => FND_LOG.level_unexpected,
1128           p_module   => C_MODULE,
1129           p_msg_text => 'INTERNAL ERROR: Call to'
1130                       ||' FEM_DATABASE_UTIL_PKG.Get_Unique_Temp_Name'
1131                       ||' failed with return status: '||v_return_status);
1132       END IF;
1133 
1134       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1135     END IF;
1136 
1137     FEM_DATABASE_UTIL_PKG.Create_Temp_Index(
1138       p_api_version           => 1.0,
1139       p_init_msg_list         => FND_API.G_FALSE,
1140       p_commit                => FND_API.G_FALSE,
1141       p_encoded               => FND_API.G_TRUE,
1142       x_return_status         => v_return_status,
1143       x_msg_count             => v_msg_count,
1144       x_msg_data              => v_msg_data,
1145       p_request_id            => p_request_id,
1146       p_object_id             => p_preview_obj_id,
1147       p_pb_object_id          => p_map_obj_id,
1148       p_table_name            => x_temp_table_name,
1149       p_index_name            => v_index_name,
1150       p_index_columns         => v_index_columns,
1151       p_unique_flag           => 'Y');
1152 
1153     IF v_return_status <> FND_API.G_RET_STS_SUCCESS THEN
1154       IF FND_LOG.level_unexpected >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
1155         FEM_ENGINES_PKG.TECH_MESSAGE(
1156           p_severity => FND_LOG.level_unexpected,
1157           p_module   => C_MODULE,
1158           p_msg_text => 'INTERNAL ERROR: Call to'
1159                       ||' FEM_DATABASE_UTIL_PKG.Create_Temp_Index'
1160                       ||' failed with return status: '||v_return_status);
1161       END IF;
1162 
1163       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1164     END IF;
1165 
1166   END IF; -- IF v_index_columns IS NOT NULL
1167 
1168 
1169   IF FND_LOG.level_procedure >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
1170     FEM_ENGINES_PKG.TECH_MESSAGE(
1171       p_severity => FND_LOG.level_procedure,
1172       p_module   => C_MODULE,
1173       p_msg_text => 'End Procedure');
1174   END IF;
1175 --
1176 END CreateTemptable;
1177 -------------------------------------------------------------------------------
1178 
1179 -------------------------------------------------------------------------------
1180 --
1181 -- PROCEDURE
1182 --   CreatePreviewStats
1183 --
1184 -- DESCRIPTION
1185 --   Inserts a row into FEM_ALLOC_PREVIEW_STATS with the temp table
1186 --   information.  In Post_Process, the stats rows will be updated with
1187 --   the preview statistics.
1188 --
1189 -------------------------------------------------------------------------------
1190 PROCEDURE CreatePreviewStats(
1191   p_preview_obj_def_id     IN NUMBER,
1192   p_preview_row_group      IN VARCHAR2,
1193   p_preview_display_seq    IN NUMBER,
1194   p_fact_table_name        IN VARCHAR2,
1195   p_temp_table_name        IN VARCHAR2,
1196   p_map_where_clause       IN VARCHAR2,
1197   p_preview_obj_id         IN NUMBER,
1198   p_request_id             IN NUMBER
1199 )
1200 -------------------------------------------------------------------------------
1201 IS
1202 --
1203   C_MODULE            CONSTANT FND_LOG_MESSAGES.module%TYPE :=
1204      'fem.plsql.fem_mapping_preview_util_pkg.CreatePreviewStats';
1205   v_row_count         NUMBER;
1206   v_sql               VARCHAR2(32767);
1207 --
1208 BEGIN
1209 --
1210   IF FND_LOG.level_procedure >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
1211     FEM_ENGINES_PKG.TECH_MESSAGE(
1212       p_severity => FND_LOG.level_procedure,
1213       p_module   => C_MODULE,
1214       p_msg_text => 'Begin Procedure');
1215   END IF;
1216 
1217   -- Determine the value to store in the ESTIMATED_ROWS column.
1218   -- It represents the number of rows that CCE would pull into the
1219   -- calculations if the mapping rule were running in a normal execution
1220   -- (i.e. not Preview mode).  This only applies to source and driver data.
1221   IF p_preview_row_group IN (G_SOURCE, G_DRIVER) THEN
1222 
1223     IF FND_LOG.level_statement >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
1224       FEM_ENGINES_PKG.TECH_MESSAGE(
1225         p_severity => FND_LOG.level_statement,
1226         p_module   => C_MODULE,
1227         p_msg_text => 'p_map_where_clause = '||p_map_where_clause);
1228     END IF;
1229 
1230     v_sql := 'SELECT count(*)'
1231            ||' FROM '||p_fact_table_name||' '||G_FACT_ALIAS;
1232 
1233     IF (p_map_where_clause IS NOT NULL) THEN
1234       v_sql := v_sql || ' WHERE '||p_map_where_clause;
1235     END IF;
1236 
1237     EXECUTE IMMEDIATE v_sql INTO v_row_count;
1238 
1239   END IF;
1240 
1241   -- Insert the temp table information into FEM_ALLOC_PREVIEW_STATS
1242   INSERT INTO fem_alloc_preview_stats (
1243     preview_obj_def_id, preview_row_group, preview_row_group_display_seq,
1244     fact_table_name, temp_table_name, estimated_rows, created_by_request_id,
1245     created_by_object_id, last_updated_by_request_id, last_updated_by_object_id)
1246   VALUES (
1247     p_preview_obj_def_id, p_preview_row_group, p_preview_display_seq,
1248     p_fact_table_name, p_temp_table_name, v_row_count, p_request_id,
1249     p_preview_obj_id, p_request_id, p_preview_obj_id);
1250 
1251 
1252   IF FND_LOG.level_procedure >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
1253     FEM_ENGINES_PKG.TECH_MESSAGE(
1254       p_severity => FND_LOG.level_procedure,
1255       p_module   => C_MODULE,
1256       p_msg_text => 'End Procedure');
1257   END IF;
1258 --
1259 END CreatePreviewStats;
1260 -------------------------------------------------------------------------------
1261 
1262 -------------------------------------------------------------------------------
1263 --
1264 -- PROCEDURE
1265 --   CreatePreviewMaps
1266 --
1267 -- DESCRIPTION
1268 --   Inserts the dimension member column and dimension
1269 --   member name column names in FEM_ALLOC_PREVIEW_MAPS.
1270 --
1271 -------------------------------------------------------------------------------
1272 PROCEDURE CreatePreviewMaps(
1273   p_preview_obj_def_id     IN NUMBER,
1274   p_preview_row_group      IN VARCHAR2,
1275   p_fact_table_name        IN VARCHAR2,
1276   p_preview_obj_id         IN NUMBER,
1277   p_request_id             IN NUMBER
1278 )
1279 -------------------------------------------------------------------------------
1280 IS
1281 --
1282   C_MODULE            CONSTANT FND_LOG_MESSAGES.module%TYPE :=
1283      'fem.plsql.fem_mapping_preview_util_pkg.CreatePreviewMaps';
1284   v_row_count         NUMBER;
1285   v_sql               VARCHAR2(32767);
1286 --
1287 BEGIN
1288 --
1289   IF FND_LOG.level_procedure >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
1290     FEM_ENGINES_PKG.TECH_MESSAGE(
1291       p_severity => FND_LOG.level_procedure,
1292       p_module   => C_MODULE,
1293       p_msg_text => 'Begin Procedure');
1294   END IF;
1295 
1296   -- Insert the dimension member column and dimension
1297   -- member name column names in FEM_ALLOC_PREVIEW_MAPS.
1298   INSERT INTO fem_alloc_preview_maps(
1299       preview_obj_def_id, preview_row_group, dim_member_column_name,
1300       dim_name_column_name, created_by_request_id, created_by_object_id,
1301       last_updated_by_request_id, last_updated_by_object_id)
1302     SELECT p_preview_obj_def_id, p_preview_row_group, tc.column_name,
1303            substr('FEM'||rownum||'_'||p_request_id, 1, 30),
1304            p_request_id, p_preview_obj_id,
1305            p_request_id, p_preview_obj_id
1306     FROM fem_tab_columns_v tc
1307     WHERE tc.table_name = p_fact_table_name
1308     AND tc.fem_data_type_code = 'DIMENSION'
1309     AND tc.column_name IN
1310       (SELECT tcp.column_name
1311        FROM fem_tab_column_prop tcp
1312        WHERE tcp.table_name = tc.table_name
1313        AND tcp.column_property_code IN
1314          ('MAPPING_UI_INPUT', 'PROCESSING_KEY'))
1315     AND tc.column_name <> 'LEDGER_ID';
1316 
1317 
1318   IF FND_LOG.level_procedure >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
1319     FEM_ENGINES_PKG.TECH_MESSAGE(
1320       p_severity => FND_LOG.level_procedure,
1321       p_module   => C_MODULE,
1322       p_msg_text => 'End Procedure');
1323   END IF;
1324 --
1325 END CreatePreviewMaps;
1326 -------------------------------------------------------------------------------
1327 
1328 -------------------------------------------------------------------------------
1329 --
1330 -- PROCEDURE
1331 --   GetSelectClause
1332 --
1333 -- DESCRIPTION
1334 --   Constructs the SELECT clause to create the temporary table.
1335 --   The structure of the SELECT clause is the same irrespective
1336 --   of the mapping rule type or whether it is for an input or output table:
1337 --     SELECT F.*, D.template_dim_name AS fem1_1234567,
1338 --                 D.template_dim_name AS fem2_1234567, ...
1339 --
1340 -------------------------------------------------------------------------------
1341 PROCEDURE GetSelectClause(
1342   p_preview_obj_def_id     IN NUMBER,
1343   p_preview_obj_id         IN NUMBER,
1344   p_request_id             IN NUMBER,
1345   p_preview_row_group      IN VARCHAR2,
1346   p_fact_table_name        IN VARCHAR2,
1347   x_select_clause          OUT NOCOPY VARCHAR2
1348 )
1349 -------------------------------------------------------------------------------
1350 IS
1351 --
1352   C_MODULE            CONSTANT FND_LOG_MESSAGES.module%TYPE :=
1353      'fem.plsql.fem_mapping_preview_util_pkg.GetSelectClause';
1354 --
1355   CURSOR c_dim (cv_preview_obj_def_id IN NUMBER,
1356                 cv_preview_row_group IN VARCHAR2) IS
1357     SELECT dim_name_column_name
1358     FROM fem_alloc_preview_maps
1359     WHERE preview_obj_def_id = cv_preview_obj_def_id
1360     AND preview_row_group = cv_preview_row_group;
1361 --
1362 BEGIN
1363 --
1364   IF FND_LOG.level_procedure >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
1365     FEM_ENGINES_PKG.TECH_MESSAGE(
1366       p_severity => FND_LOG.level_procedure,
1367       p_module   => C_MODULE,
1368       p_msg_text => 'Begin Procedure');
1369   END IF;
1370 
1371 
1372   -- Start off the SELECT clause.
1373   -- i.e. 'SELECT F.*'
1374   x_select_clause := 'SELECT '||G_FACT_ALIAS||'.*';
1375 
1376   -- Then loop through FEM_ALLOC_PREVIEW_MAPS to get the
1377   -- dimension member name column names to append to the SELECT clause.
1378   -- i.e. ||', D.template_dim_name AS fem1_1234567'
1379   FOR dims IN c_dim(cv_preview_obj_def_id => p_preview_obj_def_id,
1380                     cv_preview_row_group  => p_preview_row_group) LOOP
1381 
1382     x_select_clause := x_select_clause||', '||G_DIM_ALIAS||'.'
1383                      ||'template_dim_name AS '
1384                      ||dims.dim_name_column_name;
1385 
1386   END LOOP;
1387 
1388 
1389   IF FND_LOG.level_statement >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
1390     FEM_ENGINES_PKG.TECH_MESSAGE(
1391       p_severity => FND_LOG.level_statement,
1392       p_module   => C_MODULE,
1393       p_msg_text => 'x_select_clause = '||x_select_clause);
1394   END IF;
1395 
1396   IF FND_LOG.level_procedure >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
1397     FEM_ENGINES_PKG.TECH_MESSAGE(
1398       p_severity => FND_LOG.level_procedure,
1399       p_module   => C_MODULE,
1400       p_msg_text => 'End Procedure');
1401   END IF;
1402 --
1403 END GetSelectClause;
1404 -------------------------------------------------------------------------------
1405 
1406 -------------------------------------------------------------------------------
1407 --
1408 -- PROCEDURE
1409 --   GetMapTableType
1410 --
1411 -- DESCRIPTION
1412 --   Gets the Mapping Table Type given a fact table.
1413 --   The possibilities are:
1414 --     Ledger type (G_LEDGER_TYPE)
1415 --     Account or Transaction type (G_ACCT_TRANS_TYPE)
1416 --     Other type (G_OTHER_TABLE_TYPE), such as statistic or factor table
1417 -------------------------------------------------------------------------------
1418 PROCEDURE GetMapTableType(
1419   p_table_name             IN VARCHAR2,
1420   x_map_table_type         OUT NOCOPY VARCHAR2
1421 )
1422 -------------------------------------------------------------------------------
1423 IS
1424 --
1425   C_MODULE            CONSTANT FND_LOG_MESSAGES.module%TYPE :=
1426      'fem.plsql.fem_mapping_preview_util_pkg.GetMapTableType';
1427   v_is_ledger         VARCHAR2(1);
1428   v_is_acct_trans     VARCHAR2(1);
1429 --
1430   -- Returns T if table is a "ledger" table and F otherwise
1431   CURSOR c_is_ledger(cv_table_name VARCHAR2) IS
1432     SELECT decode(count(*),0,'F','T')
1433     FROM fem_table_class_assignmt_v
1434     WHERE table_name = cv_table_name
1435     AND substr(table_classification_code,-6) = 'LEDGER';
1436 
1437   -- Returns T if table is an "account or transaction" table and F otherwise
1438   CURSOR c_is_acct_trans(cv_table_name VARCHAR2) IS
1439     SELECT decode(count(*),0,'F','T')
1440     FROM fem_table_class_assignmt_v
1441     WHERE table_name = cv_table_name
1442     AND table_classification_code IN ('ACCOUNT_PROFITABILITY',
1443                                       'TRANSACTION_PROFITABILITY');
1444 --
1445 BEGIN
1446 --
1447   IF FND_LOG.level_procedure >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
1448     FEM_ENGINES_PKG.TECH_MESSAGE(
1449       p_severity => FND_LOG.level_procedure,
1450       p_module   => C_MODULE,
1451       p_msg_text => 'Begin Procedure');
1452   END IF;
1453 
1454   -- See if table is a ledger table first
1455   OPEN c_is_ledger(p_table_name);
1456   FETCH c_is_ledger INTO v_is_ledger;
1457   CLOSE c_is_ledger;
1458 
1459   IF v_is_ledger = 'T' THEN
1460     x_map_table_type := G_LEDGER_TYPE;
1461   ELSE
1462     -- If table is not a ledger table,
1463     -- see if table is an account or transaction table.
1464     OPEN c_is_acct_trans(p_table_name);
1465     FETCH c_is_acct_trans INTO v_is_acct_trans;
1466     CLOSE c_is_acct_trans;
1467 
1468     IF v_is_acct_trans = 'T' THEN
1469       x_map_table_type := G_ACCT_TRANS_TYPE;
1470     ELSE
1471       -- Since it is not an account or transaction table,
1472       -- it must be some other type that we don't care about yet...
1473       x_map_table_type := G_OTHER_TABLE_TYPE;
1474     END IF;
1475   END IF;
1476 
1477   IF FND_LOG.level_statement >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
1478     FEM_ENGINES_PKG.TECH_MESSAGE(
1479       p_severity => FND_LOG.level_statement,
1480       p_module   => C_MODULE,
1481       p_msg_text => 'x_map_table_type = '||x_map_table_type);
1482   END IF;
1483 
1484   IF FND_LOG.level_procedure >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
1485     FEM_ENGINES_PKG.TECH_MESSAGE(
1486       p_severity => FND_LOG.level_procedure,
1487       p_module   => C_MODULE,
1488       p_msg_text => 'End Procedure');
1489   END IF;
1490 --
1491 END GetMapTableType;
1492 -------------------------------------------------------------------------------
1493 
1494 -------------------------------------------------------------------------------
1495 --
1496 -- PROCEDURE
1497 --   GetOutputMatchingTable
1498 --
1499 -- BACKGROUND
1500 --   Unlike ledger tables, if the output table is an account or transaction
1501 --   table, the corresponding temporary table needs to be created with data
1502 --   from the output fact table already populated in it.  The reason why
1503 --   data needs to exist in the temporary output table before Preview
1504 --   begins processing is that CCE only performs updates on the output table
1505 --   if it is an account or transaction table.  In contrast, CCE always
1506 --   inserts into ledger tables.  Therefore, if the output table is
1507 --   a ledger table, the temporary table does not need to be created with
1508 --   data already populated in it.
1509 --
1510 --   Instead of creating a complete copy of the output fact table when
1511 --   creating the corresponding temporary table, only preload the temporary
1512 --   output table with the set of data that will be updated.
1513 --   However, since determining the exact set of output data that will be
1514 --   updated is rewriting a good portion of the CCE, the preloaded data
1515 --   will just be based on the data that match with the corresponding
1516 --   input account or transaction table, or the "output matching table".
1517 --
1518 -- DESCRIPTION
1519 --   The purpose of this procedure is to determine the "output matching table".
1520 --   The "output matching table" is the temporary driver table,
1521 --   unless the driver is a ledger table or there is no driver table.
1522 --   Otherwise, the "output matching table" is the temporary source table.
1523 --   The statistic table is not considered a driver table for the purpose
1524 --   of determining the "output matching table".  In other words,
1525 --   for a Retrieve Statistic rule type, the "output matching table"
1526 --   is the temporary source table.
1527 --
1528 -- ASSUMPTION
1529 --   Before this API can be called, the temporary tables for the source
1530 --   and driver tables have to be first created.  That is the purpose
1531 --   of the FEM_FUNCTION_CD_MAPPING.PREVIEW_ROW_GROUP_PROCESS_SEQ column.
1532 --   The Pre_Process procedure relies on that column to determine the
1533 --   order in which to create the temporary tables.
1534 --
1535 -------------------------------------------------------------------------------
1536 PROCEDURE GetOutputMatchingTable(
1537   p_preview_obj_def_id      IN NUMBER,
1538   x_output_match_temp_table OUT NOCOPY VARCHAR2,
1539   x_output_match_fact_table OUT NOCOPY VARCHAR2
1540 )
1541 -------------------------------------------------------------------------------
1542 IS
1543 --
1544   C_MODULE            CONSTANT FND_LOG_MESSAGES.module%TYPE :=
1545      'fem.plsql.fem_mapping_preview_util_pkg.GetOutputMatchingTable';
1546   v_map_rule_type     FEM_ALLOC_BR_OBJECTS.map_rule_type_code%TYPE;
1547   v_fact_table_name   FEM_ALLOC_PREVIEW_STATS.fact_table_name%TYPE;
1548   v_temp_table_name   FEM_ALLOC_PREVIEW_STATS.temp_table_name%TYPE;
1549   v_map_table_type    VARCHAR2(30);
1550   v_temp_table_group  FEM_ALLOC_PREVIEW_STATS.preview_row_group%TYPE;
1551 --
1552   -- Retrieves the temporary and fact table names
1553   -- given the Preview Row Group and Preview rule version
1554   CURSOR c_preview_tables (cv_preview_obj_def_id IN NUMBER,
1555                            cv_preview_row_group IN VARCHAR2) IS
1556     SELECT s.temp_table_name, s.fact_table_name
1557     FROM fem_alloc_preview_stats s
1558     WHERE s.preview_obj_def_id = cv_preview_obj_def_id
1559     AND s.preview_row_group = cv_preview_row_group;
1560 --
1561 BEGIN
1562 --
1563   IF FND_LOG.level_procedure >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
1564     FEM_ENGINES_PKG.TECH_MESSAGE(
1565       p_severity => FND_LOG.level_procedure,
1566       p_module   => C_MODULE,
1567       p_msg_text => 'Begin Procedure');
1568   END IF;
1569 
1570   -- First assume the temp table group is DRIVER
1571   v_temp_table_group := G_DRIVER;
1572 
1573   -- See if a driver table exists
1574   OPEN c_preview_tables(p_preview_obj_def_id, v_temp_table_group);
1575   FETCH c_preview_tables INTO v_temp_table_name, v_fact_table_name;
1576   CLOSE c_preview_tables;
1577 
1578   IF v_temp_table_name IS NULL THEN
1579     -- If no driver, then output match table must be the TEMP SOURCE table
1580     v_temp_table_group := G_SOURCE;
1581   ELSE
1582     -- If a driver table exists, check the mapping table type.
1583     GetMapTableType(
1584       p_table_name       => v_fact_table_name,
1585       x_map_table_type   => v_map_table_type);
1586 
1587     -- If driver table type is not account/trans, then output match table
1588     -- is the TEMP SOURCE table.
1589     IF v_map_table_type <> G_ACCT_TRANS_TYPE THEN
1590       v_temp_table_group := G_SOURCE;
1591     END IF;
1592   END IF;
1593 
1594   IF FND_LOG.level_statement >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
1595     FEM_ENGINES_PKG.TECH_MESSAGE(
1596       p_severity => FND_LOG.level_statement,
1597       p_module   => C_MODULE,
1598       p_msg_text => 'v_temp_table_group = '||v_temp_table_group);
1599   END IF;
1600 
1601   -- If the temp table group is no longer DRIVER, then get the
1602   -- temp table name associated with the new temp table group.
1603   IF v_temp_table_group <> G_DRIVER THEN
1604     OPEN c_preview_tables(p_preview_obj_def_id, v_temp_table_group);
1605     FETCH c_preview_tables INTO v_temp_table_name, v_fact_table_name;
1606     CLOSE c_preview_tables;
1607   END IF;
1608 
1609   x_output_match_temp_table := v_temp_table_name;
1610   x_output_match_fact_table := v_fact_table_name;
1611 
1612   IF FND_LOG.level_statement >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
1613     FEM_ENGINES_PKG.TECH_MESSAGE(
1614       p_severity => FND_LOG.level_statement,
1615       p_module   => C_MODULE,
1616       p_msg_text => 'x_output_match_temp_table = '||x_output_match_temp_table);
1617     FEM_ENGINES_PKG.TECH_MESSAGE(
1618       p_severity => FND_LOG.level_statement,
1619       p_module   => C_MODULE,
1620       p_msg_text => 'x_output_match_fact_table = '||x_output_match_fact_table);
1621   END IF;
1622 
1623   -- An output match table should always be found.
1624   -- If not, then raise unexpected error...
1625   IF x_output_match_temp_table IS NULL THEN
1626     IF FND_LOG.level_unexpected >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
1627       FEM_ENGINES_PKG.TECH_MESSAGE(
1628         p_severity => FND_LOG.level_unexpected,
1629         p_module   => C_MODULE,
1630         p_msg_text => 'x_output_match_temp_table should NOT be NULL!');
1631     END IF;
1632     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1633   END IF;
1634 
1635   IF FND_LOG.level_procedure >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
1636     FEM_ENGINES_PKG.TECH_MESSAGE(
1637       p_severity => FND_LOG.level_procedure,
1638       p_module   => C_MODULE,
1639       p_msg_text => 'End Procedure');
1640   END IF;
1641 --
1642 END GetOutputMatchingTable;
1643 -------------------------------------------------------------------------------
1644 
1645 -------------------------------------------------------------------------------
1646 --
1647 -- PROCEDURE
1648 --   GetFromClause
1649 --
1650 -- DESCRIPTION
1651 --   Constructs the FROM clause to create the temporary table.
1652 --   The FROM clause looks like this for all table types:
1653 --     FROM <fact table> F, fem_dim_template D
1654 --
1655 -------------------------------------------------------------------------------
1656 PROCEDURE GetFromClause(
1657   p_fact_table_name         IN VARCHAR2,
1658   x_from_clause             OUT NOCOPY VARCHAR2
1659 )
1660 -------------------------------------------------------------------------------
1661 IS
1662 --
1663   C_MODULE            CONSTANT FND_LOG_MESSAGES.module%TYPE :=
1664      'fem.plsql.fem_mapping_preview_util_pkg.GetFromClause';
1665 --
1666 BEGIN
1667 --
1668   IF FND_LOG.level_procedure >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
1669     FEM_ENGINES_PKG.TECH_MESSAGE(
1670       p_severity => FND_LOG.level_procedure,
1671       p_module   => C_MODULE,
1672       p_msg_text => 'Begin Procedure');
1673   END IF;
1674 
1675   -- Set the FROM clause in the form of:
1676   --   FROM <output fact table> a, fem_dim_template b
1677   x_from_clause := ' FROM '||p_fact_table_name||' '||G_FACT_ALIAS||', '
1678                  ||G_DIM_TEMPLATE_TABLE||' '||G_DIM_ALIAS;
1679 
1680   IF FND_LOG.level_statement >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
1681     FEM_ENGINES_PKG.TECH_MESSAGE(
1682       p_severity => FND_LOG.level_statement,
1683       p_module   => C_MODULE,
1684       p_msg_text => 'x_from_clause = '||x_from_clause);
1685   END IF;
1686 
1687   IF FND_LOG.level_procedure >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
1688     FEM_ENGINES_PKG.TECH_MESSAGE(
1689       p_severity => FND_LOG.level_procedure,
1690       p_module   => C_MODULE,
1691       p_msg_text => 'End Procedure');
1692   END IF;
1693 --
1694 END GetFromClause;
1695 -------------------------------------------------------------------------------
1696 
1697 -------------------------------------------------------------------------------
1698 --
1699 -- PROCEDURE
1700 --   GetInputWhereClause
1701 --
1702 -- DESCRIPTION
1703 --   Constructs the WHERE clause to create the temporary input table.
1704 --   The general structure of the WHERE clause is:
1705 --      WHERE <condition filter in mapping rule>
1706 --      AND <parameter filter>
1707 --      AND <preview filter>
1708 --      AND rownum <= <maximum number of rows parameter>
1709 --   If the table is a Statistic table and the row group is DRIVER,
1710 --   then the WHERE CLAUSE looks like:
1711 --      WHERE <statistic condition filter>
1712 --      AND <constant columns>
1713 --      AND <preview filter>
1714 --      AND rownum <= <maximum number of rows parameter>
1715 --
1716 -------------------------------------------------------------------------------
1717 PROCEDURE GetInputWhereClause(
1718   p_preview_obj_def_id     IN NUMBER,
1719   p_preview_row_group      IN VARCHAR2,
1720   p_map_obj_def_id         IN NUMBER,
1721   p_map_rule_type          IN VARCHAR2,
1722   p_fact_table_name        IN VARCHAR2,
1723   p_sub_obj_id             IN NUMBER,
1724   p_request_id             IN NUMBER,
1725   p_preview_obj_id         IN NUMBER,
1726   x_map_where_clause       OUT NOCOPY VARCHAR2,
1727   x_where_clause           OUT NOCOPY VARCHAR2
1728 )
1729 -------------------------------------------------------------------------------
1730 IS
1731 --
1732   C_MODULE            CONSTANT FND_LOG_MESSAGES.module%TYPE :=
1733      'fem.plsql.fem_mapping_preview_util_pkg.GetInputWhereClause';
1734   v_map_table_type    VARCHAR2(30);
1735   v_condition_filter  VARCHAR2(16000);
1736   v_return_status     VARCHAR2(1);
1737   v_msg_count         NUMBER;
1738   v_msg_data          VARCHAR2(4000);
1739   v_effective_date    VARCHAR2(30);
1740   v_ledger_id         FEM_ALLOC_PREVIEWS.ledger_id%TYPE;
1741   v_cal_period_id     FEM_ALLOC_PREVIEWS.cal_period_id %TYPE;
1742   v_dsg_obj_def_id    FEM_ALLOC_PREVIEWS.dsg_obj_def_id%TYPE;
1743   v_query_row_limit   FEM_ALLOC_PREVIEWS.query_row_limit%TYPE;
1744   v_stat_obj_def_id   FEM_OBJECT_DEFINITION_B.object_definition_id%TYPE;
1745   v_stat_cond_obj_def_id FEM_STAT_LOOKUPS.condition_obj_def_id%TYPE;
1746   v_preview_cond_obj_id  FEM_ALLOC_PREVIEWS.source_condition_obj_id%TYPE;
1747   v_by_dimension_column  FEM_ALLOC_BR_DIMENSIONS.alloc_dim_col_name%TYPE;
1748   v_by_dimension_id      FEM_DIMENSIONS_B.dimension_id%TYPE;
1749   v_by_dimension_value   VARCHAR2(38);  -- max size of number
1750 --
1751   CURSOR c_stat_cols (cv_stat_obj_def_id NUMBER) IS
1752     SELECT stat_lookup_tbl_col, relational_operand, value
1753     FROM fem_stat_lookup_rel s
1754     WHERE s.stat_lookup_obj_def_id = cv_stat_obj_def_id
1755     AND s.value IS NOT NULL;
1756 --
1757 BEGIN
1758 --
1759   IF FND_LOG.level_procedure >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
1760     FEM_ENGINES_PKG.TECH_MESSAGE(
1761       p_severity => FND_LOG.level_procedure,
1762       p_module   => C_MODULE,
1763       p_msg_text => 'Begin Procedure');
1764   END IF;
1765 
1766   -- Get various preview attributes
1767   SELECT FND_DATE.Date_To_Canonical(effective_date),
1768          ledger_id, cal_period_id, dsg_obj_def_id, query_row_limit,
1769          decode(p_preview_row_group, G_SOURCE, source_condition_obj_id,
1770                                                driver_condition_obj_id)
1771   INTO   v_effective_date, v_ledger_id, v_cal_period_id, v_dsg_obj_def_id,
1772          v_query_row_limit, v_preview_cond_obj_id
1773   FROM   fem_alloc_previews
1774   WHERE  preview_obj_def_id = p_preview_obj_def_id;
1775 
1776   -- The general structure of the WHERE clause is:
1777   --   WHERE <condition filter in mapping rule>
1778   --   AND <parameter filter>
1779   --   AND <preview filter>
1780   --   AND rownum <= <maximum number of rows parameter>
1781   IF (p_map_rule_type <> G_RETRIEVE_STAT) OR
1782      (p_preview_row_group <> G_DRIVER) THEN
1783 
1784     -- Set the by dimension parameters to pass into the Predicate procedure
1785     GetByDimParams(
1786       p_preview_obj_def_id      => p_preview_obj_def_id,
1787       p_preview_row_group       => p_preview_row_group,
1788       p_map_obj_def_id          => p_map_obj_def_id,
1789       p_map_rule_type           => p_map_rule_type,
1790       p_fact_table_name         => p_fact_table_name,
1791       x_by_dimension_column     => v_by_dimension_column,
1792       x_by_dimension_id         => v_by_dimension_id,
1793       x_by_dimension_value      => v_by_dimension_value);
1794 
1795     -- Get <condition filter + parameter filter>
1796     FEM_ASSEMBLER_PREDICATE_API.Generate_Assembler_Predicate(
1797       x_predicate_string     => x_where_clause,
1798       x_return_status        => v_return_status,
1799       x_msg_count            => v_msg_count,
1800       x_msg_data             => v_msg_data,
1801       p_condition_obj_id     => p_sub_obj_id,
1802       p_rule_effective_date  => v_effective_date,
1803       p_DS_IO_Def_ID         => v_dsg_obj_def_id,
1804       p_Output_Period_ID     => v_cal_period_id,
1805       p_Request_ID           => p_request_id,
1806       p_Object_ID            => p_preview_obj_id,
1807       p_Ledger_ID            => v_ledger_id,
1808       p_by_dimension_column  => v_by_dimension_column,
1809       p_by_dimension_id      => v_by_dimension_id,
1810       p_by_dimension_value   => v_by_dimension_value,
1811       p_fact_table_name      => p_fact_table_name,
1812       p_table_alias          => G_FACT_ALIAS,
1813       p_Ledger_Flag          => 'N',
1814       p_api_version          => 1.0,
1815       p_init_msg_list        => FND_API.G_FALSE,
1816       p_commit               => FND_API.G_FALSE,
1817       p_encoded              => FND_API.G_TRUE);
1818 
1819     IF v_return_status <> FND_API.G_RET_STS_SUCCESS THEN
1820       IF FND_LOG.level_statement >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
1821         FEM_ENGINES_PKG.TECH_MESSAGE(
1822           p_severity => FND_LOG.level_statement,
1823           p_module   => C_MODULE,
1824           p_msg_text => 'INTERNAL ERROR: Call to'
1825                       ||' FEM_ASSEMBLER_PREDICATE_API.Generate_Assembler_Predicate'
1826                       ||' failed with return status: '||v_return_status);
1827       END IF;
1828     END IF;
1829 
1830     -- Assembler API should always generate some WHERE clause
1831     IF x_where_clause IS NULL THEN
1832       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1833     END IF;
1834 
1835   ELSE
1836   -- If the table is a Statistic table and the row group is DRIVER,
1837   -- then the WHERE CLAUSE looks like:
1838   --   WHERE <statistic condition filter>
1839   --   AND <constant columns>
1840   --   AND <preview filter>
1841   --   AND rownum <= <maximum number of rows parameter>
1842 
1843     -- First get Stat Lookup obj def id
1844     SELECT object_definition_id
1845     INTO v_stat_obj_def_id
1846     FROM fem_object_definition_b
1847     WHERE object_id = p_sub_obj_id;
1848 
1849     -- Then build the WHERE clause for the stat columns that is bound to
1850     -- defined values as part of the stat definition.
1851     FOR stat_col IN c_stat_cols(cv_stat_obj_def_id => v_stat_obj_def_id) LOOP
1852 
1853       IF x_where_clause IS NOT NULL THEN
1854         x_where_clause := x_where_clause||' AND ';
1855       END IF;
1856 
1857       x_where_clause := x_where_clause||G_FACT_ALIAS||'.'
1858                       ||stat_col.stat_lookup_tbl_col
1859                       ||stat_col.relational_operand||''''
1860                       ||stat_col.value||'''';
1861 
1862     END LOOP;
1863 
1864      -- Get <statistic condition filter> if one exists
1865     SELECT condition_obj_def_id
1866     INTO v_stat_cond_obj_def_id
1867     FROM fem_stat_lookups
1868     WHERE stat_lookup_obj_def_id = v_stat_obj_def_id;
1869 
1870     IF v_stat_cond_obj_def_id IS NOT NULL THEN
1871       FEM_CONDITIONS_API.generate_condition_predicate(
1872         p_api_version            => 1.0,
1873         p_init_msg_list          => FND_API.G_FALSE,
1874         p_commit                 => FND_API.G_FALSE,
1875         p_encoded                => FND_API.G_TRUE,
1876         p_condition_obj_id       => FEM_BUSINESS_RULE_PVT.GetObjectId(
1877                                       p_obj_def_id => v_stat_cond_obj_def_id),
1878         p_rule_effective_date    => v_effective_date,
1879         p_input_fact_table_name  => p_fact_table_name,
1880         p_table_alias            => G_FACT_ALIAS,
1881         p_display_predicate      => 'N',
1882         p_return_predicate_type  => 'BOTH',
1883         p_logging_turned_on      => 'Y',
1884         x_return_status          => v_return_status,
1885         x_msg_count              => v_msg_count,
1886         x_msg_data               => v_msg_data,
1887         x_predicate_string       => v_condition_filter);
1888 
1889       IF v_return_status <> FND_API.G_RET_STS_SUCCESS THEN
1890         IF FND_LOG.level_statement >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
1891           FEM_ENGINES_PKG.TECH_MESSAGE(
1892             p_severity => FND_LOG.level_statement,
1893             p_module   => C_MODULE,
1894             p_msg_text => 'INTERNAL ERROR: Call to'
1895                         ||' FEM_CONDITIONS_API.generate_condition_predicate'
1896                         ||' failed with return status: '||v_return_status);
1897         END IF;
1898 
1899         -- Only raise error if return status is Unexpected Error because
1900         -- the Condition API can return with error even if the issue
1901         -- is that a dimension/column does not exist on the table that
1902         -- the condition applied to.  This is not an error condition from
1903         -- the CCE perspective.
1904         IF v_return_status = FND_API.G_RET_STS_UNEXP_ERROR THEN
1905           RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1906         END IF;
1907       END IF;
1908 
1909       -- Only append if condition filter is not null
1910       IF v_condition_filter IS NOT NULL THEN
1911         x_where_clause := x_where_clause||' AND '||v_condition_filter;
1912       END IF;
1913     END IF; -- IF v_stat_cond_obj_def_id IS NOT NULL THEN
1914 
1915   END IF;  -- IF p_map_rule_type <> G_RETRIEVE_STAT THEN
1916 
1917   -- Before appending the additional preview filter, store the
1918   -- WHERE clause just based on the parameters and mapping rule definition.
1919   -- This will be used later when creating the Preview Statistics
1920   -- to get the number of rows that CCE would pull into the calculations
1921   -- if the mapping rule were running in a normal execution
1922   -- (i.e. not Preview mode).
1923   x_map_where_clause := x_where_clause;
1924 
1925   -- Get <preview filter> if one exists
1926   IF v_preview_cond_obj_id IS NOT NULL THEN
1927     FEM_CONDITIONS_API.generate_condition_predicate(
1928       p_api_version            => 1.0,
1929       p_init_msg_list          => FND_API.G_FALSE,
1930       p_commit                 => FND_API.G_FALSE,
1931       p_encoded                => FND_API.G_TRUE,
1932       p_condition_obj_id       => v_preview_cond_obj_id,
1933       p_rule_effective_date    => v_effective_date,
1934       p_input_fact_table_name  => p_fact_table_name,
1935       p_table_alias            => G_FACT_ALIAS,
1936       p_display_predicate      => 'N',
1937       p_return_predicate_type  => 'BOTH',
1938       p_logging_turned_on      => 'Y',
1939       x_return_status          => v_return_status,
1940       x_msg_count              => v_msg_count,
1941       x_msg_data               => v_msg_data,
1942       x_predicate_string       => v_condition_filter);
1943 
1944     IF v_return_status <> FND_API.G_RET_STS_SUCCESS THEN
1945       IF FND_LOG.level_statement >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
1946         FEM_ENGINES_PKG.TECH_MESSAGE(
1947           p_severity => FND_LOG.level_statement,
1948           p_module   => C_MODULE,
1949           p_msg_text => 'INTERNAL ERROR: Call to'
1950                       ||' FEM_CONDITIONS_API.generate_condition_predicate'
1951                       ||' failed with return status: '||v_return_status);
1952       END IF;
1953 
1954       -- Only raise error if return status is Unexpected Error because
1955       -- the Condition API can return with error even if the issue
1956       -- is that a dimension/column does not exist on the table that
1957       -- the condition applied to.  This is not an error condition from
1958       -- the CCE perspective.
1959       IF v_return_status = FND_API.G_RET_STS_UNEXP_ERROR THEN
1960         RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
1961       END IF;
1962     END IF;
1963 
1964     -- Only append if condition filter is not null
1965     IF v_condition_filter IS NOT NULL THEN
1966       x_where_clause := x_where_clause||' AND '||v_condition_filter;
1967     END IF;
1968 
1969   END IF; -- IF p_preview_cond_obj_id IS NOT NULL THEN
1970 
1971   -- Finally, add the WHERE keyword and query row limit
1972   IF x_where_clause IS NULL THEN
1973     x_where_clause := 'WHERE '||'rownum <= '||v_query_row_limit;
1974   ELSE
1975     x_where_clause := 'WHERE '||x_where_clause
1976                     ||' AND '||'rownum <= '||v_query_row_limit;
1977   END IF;
1978 
1979   IF FND_LOG.level_procedure >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
1980     FEM_ENGINES_PKG.TECH_MESSAGE(
1981       p_severity => FND_LOG.level_procedure,
1982       p_module   => C_MODULE,
1983       p_msg_text => 'End Procedure');
1984   END IF;
1985 --
1986 END GetInputWhereClause;
1987 -------------------------------------------------------------------------------
1988 
1989 -------------------------------------------------------------------------------
1990 --
1991 -- PROCEDURE
1992 --   GetOutputWhereClause
1993 --
1994 -- DESCRIPTION
1995 --   Constructs the WHERE clause to create the temporary output table.
1996 --   If the table is a Ledger table, the WHERE clause is:
1997 --     	WHERE 1=0
1998 --   If the table is an account/transaction table,
1999 --   then the WHERE clause looks like:
2000 --      WHERE <same as value filter>
2001 --      AND <matching table filter>
2002 --
2003 --   Matching table filter:
2004 --      (PK_COL1, PK_COL2, ... ) IN (SELECT PK_COL1, PK_COL2, ...
2005 --                                   FROM <output matching table>)
2006 -------------------------------------------------------------------------------
2007 PROCEDURE GetOutputWhereClause(
2008   p_preview_obj_def_id      IN NUMBER,
2009   p_map_obj_def_id          IN NUMBER,
2010   p_function_cd             IN VARCHAR2,
2011   p_fact_table_name         IN VARCHAR2,
2012   x_where_clause            OUT NOCOPY VARCHAR2
2013 )
2014 -------------------------------------------------------------------------------
2015 IS
2016 --
2017   C_MODULE            CONSTANT FND_LOG_MESSAGES.module%TYPE :=
2018      'fem.plsql.fem_mapping_preview_util_pkg.GetOutputWhereClause';
2019   v_map_table_type    VARCHAR2(30);
2020   v_output_match_temp_table VARCHAR2(30);
2021   v_output_match_fact_table VARCHAR2(30);
2022   v_output_pk_sql     VARCHAR2(8000);
2023   v_match_pk_sql      VARCHAR2(8000);
2024 --
2025   CURSOR c_value_cols (cv_map_obj_def_id NUMBER, cv_function_cd VARCHAR2) IS
2026     SELECT alloc_dim_col_name, nvl(to_char(dimension_value),
2027                                    dimension_value_char) dim_value
2028     FROM fem_alloc_br_dimensions
2029     WHERE object_definition_id = cv_map_obj_def_id
2030     AND function_cd = cv_function_cd
2031     AND alloc_dim_usage_code = 'VALUE';
2032 
2033   CURSOR c_match_cols (cv_fact_table VARCHAR2, cv_match_fact_table VARCHAR2,
2034                        cv_map_obj_def_id NUMBER, cv_function_cd VARCHAR) IS
2035     SELECT o.column_name output_col, m.column_name match_col
2036     FROM fem_tab_column_prop o, fem_tab_columns_v m
2037     WHERE o.table_name = cv_fact_table
2038     AND o.column_property_code = 'PROCESSING_KEY'
2039     AND m.table_name = cv_match_fact_table
2040     AND o.column_name = m.column_name
2041     AND o.column_name NOT IN
2042       (SELECT alloc_dim_col_name
2043        FROM fem_alloc_br_dimensions
2044        WHERE object_definition_id = cv_map_obj_def_id
2045        AND function_cd = cv_function_cd
2046        AND alloc_dim_usage_code = 'VALUE');
2047 
2048 --
2049 BEGIN
2050 --
2051   IF FND_LOG.level_procedure >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
2052     FEM_ENGINES_PKG.TECH_MESSAGE(
2053       p_severity => FND_LOG.level_procedure,
2054       p_module   => C_MODULE,
2055       p_msg_text => 'Begin Procedure');
2056   END IF;
2057 
2058   -- First get mapping table type
2059   GetMapTableType(
2060     p_table_name       => p_fact_table_name,
2061     x_map_table_type   => v_map_table_type);
2062 
2063   IF v_map_table_type = G_LEDGER_TYPE THEN
2064 
2065     x_where_clause := '1=0';
2066 
2067   ELSIF v_map_table_type = G_ACCT_TRANS_TYPE THEN
2068 
2069     -- First restrict based on those columns with values already defined
2070     FOR value_col IN c_value_cols(cv_map_obj_def_id => p_map_obj_def_id,
2071                                   cv_function_cd    => p_function_cd) LOOP
2072       IF value_col.dim_value IS NOT NULL THEN
2073 
2074         IF x_where_clause IS NOT NULL THEN
2075           x_where_clause := x_where_clause||' AND ';
2076         END IF;
2077 
2078         x_where_clause := x_where_clause||G_FACT_ALIAS||'.'
2079                         ||value_col.alloc_dim_col_name
2080                         ||'='''||value_col.dim_value||'''';
2081       END IF;
2082     END LOOP;
2083 
2084     -- Get matching output table information
2085     GetOutputMatchingTable(
2086       p_preview_obj_def_id      => p_preview_obj_def_id,
2087       x_output_match_temp_table => v_output_match_temp_table,
2088       x_output_match_fact_table => v_output_match_fact_table);
2089 
2090     -- Then restrict based on matching processing key columns between
2091     -- output table and matching output table.
2092     FOR match_col IN c_match_cols(cv_fact_table  => p_fact_table_name,
2093                              cv_match_fact_table => v_output_match_fact_table,
2094                              cv_map_obj_def_id   => p_map_obj_def_id,
2095                              cv_function_cd      => p_function_cd) LOOP
2096 
2097       IF v_output_pk_sql IS NOT NULL THEN
2098         v_output_pk_sql := v_output_pk_sql||',';
2099         v_match_pk_sql := v_match_pk_sql||',';
2100       END IF;
2101 
2102       v_output_pk_sql := v_output_pk_sql
2103                        ||G_FACT_ALIAS||'.'||match_col.output_col;
2104       v_match_pk_sql := v_match_pk_sql
2105                        ||G_MATCH_ALIAS||'.'||match_col.match_col;
2106 
2107     END LOOP;
2108 
2109     -- Create <matching table filter>:
2110     --      (PK_COL1, PK_COL2, ... ) IN (SELECT PK_COL1, PK_COL2, ...
2111     --                                   FROM <output matching table>)
2112     IF v_output_pk_sql IS NOT NULL THEN
2113       IF x_where_clause IS NOT NULL THEN
2114         x_where_clause := x_where_clause||' AND ';
2115       END IF;
2116 
2117       x_where_clause := x_where_clause||'('||v_output_pk_sql||')'
2118                       ||' IN (SELECT '||v_match_pk_sql||' FROM '
2119                       ||v_output_match_temp_table||' '||G_MATCH_ALIAS||')';
2120     END IF;
2121 
2122   ELSE
2123 
2124     IF FND_LOG.level_unexpected >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
2125       FEM_ENGINES_PKG.TECH_MESSAGE(
2126         p_severity => FND_LOG.level_unexpected,
2127         p_module   => C_MODULE,
2128         p_msg_text => 'Unsupported output table type: '||v_map_table_type);
2129     END IF;
2130 
2131     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2132 
2133   END IF;
2134 
2135   -- Finally, add the WHERE keyword
2136   IF x_where_clause IS NOT NULL THEN
2137     x_where_clause := 'WHERE '||x_where_clause;
2138   END IF;
2139 
2140   IF FND_LOG.level_procedure >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
2141     FEM_ENGINES_PKG.TECH_MESSAGE(
2142       p_severity => FND_LOG.level_procedure,
2143       p_module   => C_MODULE,
2144       p_msg_text => 'End Procedure');
2145   END IF;
2146 --
2147 END GetOutputWhereClause;
2148 -------------------------------------------------------------------------------
2149 
2150 -------------------------------------------------------------------------------
2151 --
2152 -- PROCEDURE
2153 --   GetWhereClause
2154 --
2155 -- DESCRIPTION
2156 --   Constructs the WHERE clause to create the temporary table.
2157 --   The structure of the WHERE clause differs depending on the
2158 --   mapping rule type or whether it is for an input or output table.
2159 --
2160 -------------------------------------------------------------------------------
2161 PROCEDURE GetWhereClause(
2162   p_preview_obj_def_id      IN NUMBER,
2163   p_preview_row_group       IN VARCHAR2,
2164   p_map_obj_def_id          IN NUMBER,
2165   p_map_rule_type           IN VARCHAR2,
2166   p_function_cd             IN VARCHAR2,
2167   p_sub_obj_id              IN NUMBER,
2168   p_fact_table_name         IN VARCHAR2,
2169   p_request_id              IN NUMBER,
2170   p_preview_obj_id          IN NUMBER,
2171   x_map_where_clause        OUT NOCOPY VARCHAR2,
2172   x_where_clause            OUT NOCOPY VARCHAR2
2173 )
2174 -------------------------------------------------------------------------------
2175 IS
2176 --
2177   C_MODULE            CONSTANT FND_LOG_MESSAGES.module%TYPE :=
2178      'fem.plsql.fem_mapping_preview_util_pkg.GetWhereClause';
2179   v_map_table_type    VARCHAR2(30);
2180 --
2181 BEGIN
2182 --
2183   IF FND_LOG.level_procedure >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
2184     FEM_ENGINES_PKG.TECH_MESSAGE(
2185       p_severity => FND_LOG.level_procedure,
2186       p_module   => C_MODULE,
2187       p_msg_text => 'Begin Procedure');
2188   END IF;
2189 
2190   IF p_preview_row_group IN (G_SOURCE, G_DRIVER) THEN
2191 
2192     GetInputWhereClause(
2193       p_preview_obj_def_id   => p_preview_obj_def_id,
2194       p_preview_row_group    => p_preview_row_group,
2195       p_map_obj_def_id       => p_map_obj_def_id,
2196       p_map_rule_type        => p_map_rule_type,
2197       p_fact_table_name      => p_fact_table_name ,
2198       p_sub_obj_id           => p_sub_obj_id,
2199       p_request_id           => p_request_id,
2200       p_preview_obj_id       => p_preview_obj_id,
2201       x_map_where_clause     => x_map_where_clause,
2202       x_where_clause         => x_where_clause);
2203 
2204   ELSE
2205 
2206     GetOutputWhereClause(
2207       p_preview_obj_def_id      => p_preview_obj_def_id,
2208       p_map_obj_def_id          => p_map_obj_def_id,
2209       p_function_cd             => p_function_cd,
2210       p_fact_table_name         => p_fact_table_name,
2211       x_where_clause            => x_where_clause);
2212 
2213   END IF;
2214 
2215   IF FND_LOG.level_statement >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
2216     FEM_ENGINES_PKG.TECH_MESSAGE(
2217       p_severity => FND_LOG.level_statement,
2218       p_module   => C_MODULE,
2219       p_msg_text => 'x_where_clause = '||x_where_clause);
2220   END IF;
2221 
2222   IF FND_LOG.level_procedure >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
2223     FEM_ENGINES_PKG.TECH_MESSAGE(
2224       p_severity => FND_LOG.level_procedure,
2225       p_module   => C_MODULE,
2226       p_msg_text => 'End Procedure');
2227   END IF;
2228 --
2229 END GetWhereClause;
2230 -------------------------------------------------------------------------------
2231 
2232 -------------------------------------------------------------------------------
2233 --
2234 -- PROCEDURE
2235 --   UpdatePreviewStats
2236 --
2237 -- DESCRIPTION
2238 --   Populate the following columns in FEM_ALLOC_PREVIEW_STATS:
2239 --   1. PREVIEW_AMOUNT_TOTAL: Sum of the source, driver, debit and credit
2240 --        amounts that CCE used or generated during the Preview run.
2241 --   2. PREVIEW_ROWS: Number of rows for the source and driver data that
2242 --        CCE used during the Preview run.
2243 --
2244 -------------------------------------------------------------------------------
2245 PROCEDURE UpdatePreviewStats(
2246   p_preview_obj_def_id      IN NUMBER,
2247   p_preview_row_group       IN VARCHAR2,
2248   p_temp_table_name         IN VARCHAR2,
2249   p_map_table_type          IN VARCHAR2,
2250   p_map_obj_def_id          IN NUMBER,
2251   p_ledger_id               IN NUMBER,
2252   p_cal_period_id           IN NUMBER
2253 )
2254 -------------------------------------------------------------------------------
2255 IS
2256 --
2257   C_MODULE                  CONSTANT FND_LOG_MESSAGES.module%TYPE :=
2258      'fem.plsql.fem_mapping_preview_util_pkg.UpdatePreviewStats';
2259   v_functional_currency     FEM_ALLOC_PREVIEW_STATS.amount_currency_code%TYPE;
2260   v_amount_total            FEM_ALLOC_PREVIEW_STATS.preview_amount_total%TYPE;
2261   v_row_count               FEM_ALLOC_PREVIEW_STATS.preview_rows%TYPE;
2262 --
2263 BEGIN
2264 --
2265   IF FND_LOG.level_procedure >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
2266     FEM_ENGINES_PKG.TECH_MESSAGE(
2267       p_severity => FND_LOG.level_procedure,
2268       p_module   => C_MODULE,
2269       p_msg_text => 'Begin Procedure');
2270   END IF;
2271 
2272   GetPreviewAmount(
2273     p_preview_obj_def_id      => p_preview_obj_def_id,
2274     p_preview_row_group       => p_preview_row_group,
2275     p_temp_table_name         => p_temp_table_name,
2276     p_map_table_type          => p_map_table_type,
2277     p_map_obj_def_id          => p_map_obj_def_id,
2278     p_ledger_id               => p_ledger_id,
2279     p_cal_period_id           => p_cal_period_id,
2280     x_functional_currency     => v_functional_currency,
2281     x_preview_amount_total    => v_amount_total);
2282 
2283   GetPreviewRowCount(
2284     p_temp_table_name         => p_temp_table_name,
2285     x_preview_row_count       => v_row_count);
2286 
2287   UPDATE fem_alloc_preview_stats
2288   SET preview_amount_total = v_amount_total,
2289       amount_currency_code = v_functional_currency,
2290       preview_rows = v_row_count
2291   WHERE preview_obj_def_id = p_preview_obj_def_id
2292   AND preview_row_group = p_preview_row_group;
2293 
2294   IF FND_LOG.level_procedure >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
2295     FEM_ENGINES_PKG.TECH_MESSAGE(
2296       p_severity => FND_LOG.level_procedure,
2297       p_module   => C_MODULE,
2298       p_msg_text => 'End Procedure');
2299   END IF;
2300 --
2301 END UpdatePreviewStats;
2302 -------------------------------------------------------------------------------
2303 
2304 -------------------------------------------------------------------------------
2305 --
2306 -- PROCEDURE
2307 --   GetPreviewAmount
2308 --
2309 -- DESCRIPTION
2310 --   Returns the summed amount and its associated currency for a given
2311 --   temporary table.  If the individual amounts are represented in
2312 --   currencies other than the functional currency, this procedure will
2313 --   convert those amounts to the functional currency amount before
2314 --   summing them.
2315 --
2316 -------------------------------------------------------------------------------
2317 PROCEDURE GetPreviewAmount(
2318   p_preview_obj_def_id      IN NUMBER,
2319   p_preview_row_group       IN VARCHAR2,
2320   p_temp_table_name         IN VARCHAR2,
2321   p_map_table_type          IN VARCHAR2,
2322   p_map_obj_def_id          IN NUMBER,
2323   p_ledger_id               IN NUMBER,
2324   p_cal_period_id           IN NUMBER,
2325   x_functional_currency     OUT NOCOPY VARCHAR2,
2326   x_preview_amount_total    OUT NOCOPY NUMBER
2327 )
2328 -------------------------------------------------------------------------------
2329 IS
2330 --
2331   C_MODULE            CONSTANT FND_LOG_MESSAGES.module%TYPE :=
2332      'fem.plsql.fem_mapping_preview_util_pkg.GetPreviewAmount';
2333   v_dim_id            FEM_DIMENSIONS_B.dimension_id%TYPE;
2334   v_dim_attr_id       FEM_DIM_ATTRIBUTES_B.attribute_id%TYPE;
2335   v_dim_attr_ver_id   FEM_DIM_ATTR_VERSIONS_B.version_id%TYPE;
2336   v_return_code       NUMBER;
2337   v_cal_per_end_date  FEM_CAL_PERIODS_ATTR.date_assign_value%TYPE;
2338   v_amount_column     FEM_ALLOC_BR_FORMULA.column_name%TYPE;
2339   v_sql               VARCHAR2(4000);
2340   v_amount            NUMBER;
2341   v_conv_amount       NUMBER;
2342   v_amount_currency   FEM_BALANCES.currency_code%TYPE;
2343   v_denom             NUMBER;
2344   v_numer             NUMBER;
2345   v_rate              NUMBER;
2346 
2347   TYPE RefCurTyp IS REF CURSOR;  -- define weak REF CURSOR type
2348   amount_cv       RefCurTyp;
2349 --
2350 BEGIN
2351 --
2352   IF FND_LOG.level_procedure >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
2353     FEM_ENGINES_PKG.TECH_MESSAGE(
2354       p_severity => FND_LOG.level_procedure,
2355       p_module   => C_MODULE,
2356       p_msg_text => 'Begin Procedure');
2357   END IF;
2358 
2359   -- Amount total does not make sense for DRIVER data.
2360   -- Therefore, this procedure will simply set the amount and currency
2361   -- OUT params to NULL and return when preview row group is DRIVER.
2362   IF p_preview_row_group = G_DRIVER THEN
2363     x_functional_currency := NULL;
2364     x_preview_amount_total := NULL;
2365     RETURN;
2366   END IF;
2367 
2368   --
2369   -- First get functional currency
2370   --
2371   SELECT dimension_id
2372   INTO v_dim_id
2373   FROM fem_dimensions_b
2374   WHERE dimension_varchar_label = 'LEDGER';
2375 
2376   FEM_DIMENSION_UTIL_PKG.get_dim_attr_id_ver_id
2377            (p_dim_id      => v_dim_id,
2378             p_attr_label  => 'LEDGER_FUNCTIONAL_CRNCY_CODE',
2379             x_attr_id     => v_dim_attr_id,
2380             x_ver_id      => v_dim_attr_ver_id,
2381             x_err_code    => v_return_code);
2382 
2383   IF v_return_code <> 0 THEN  -- if not success
2384     IF FND_LOG.level_unexpected >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
2385       FEM_ENGINES_PKG.TECH_MESSAGE(
2386         p_severity => FND_LOG.level_unexpected,
2387         p_module   => C_MODULE,
2388         p_msg_text => 'INTERNAL ERROR: Call to'
2389                     ||' FEM_DIMENSION_UTIL_PKG.get_dim_attr_id_ver_id'
2390                     ||' to get LEDGER_FUNCTIONAL_CRNCY_CODE attribute'
2391                     ||' information failed with return code: '||v_return_code);
2392     END IF;
2393     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2394   END IF;
2395 
2396   SELECT dim_attribute_varchar_member
2397   INTO x_functional_currency
2398   FROM fem_ledgers_attr
2399   WHERE attribute_id  = v_dim_attr_id
2400   AND version_id    = v_dim_attr_ver_id
2401   AND ledger_id     = p_ledger_id;
2402 
2403   IF x_functional_currency IS NULL THEN
2404     IF FND_LOG.level_unexpected >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
2405       FEM_ENGINES_PKG.TECH_MESSAGE(
2406         p_severity => FND_LOG.level_unexpected,
2407         p_module   => C_MODULE,
2408         p_msg_text => 'Functional currency does not exist for the ledger'
2409                     ||' id: '||p_ledger_id);
2410     END IF;
2411     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2412   END IF;
2413 
2414   --
2415   -- Then get calendar period end date.
2416   --
2417   SELECT dimension_id
2418   INTO v_dim_id
2419   FROM fem_dimensions_b
2420   WHERE dimension_varchar_label = 'CAL_PERIOD';
2421 
2422   FEM_DIMENSION_UTIL_PKG.get_dim_attr_id_ver_id
2423            (p_dim_id      => v_dim_id,
2424             p_attr_label  => 'CAL_PERIOD_END_DATE',
2425             x_attr_id     => v_dim_attr_id,
2426             x_ver_id      => v_dim_attr_ver_id,
2427             x_err_code    => v_return_code);
2428 
2429   IF v_return_code <> 0 THEN  -- if not success
2430     IF FND_LOG.level_unexpected >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
2431       FEM_ENGINES_PKG.TECH_MESSAGE(
2432         p_severity => FND_LOG.level_unexpected,
2433         p_module   => C_MODULE,
2434         p_msg_text => 'INTERNAL ERROR: Call to'
2435                     ||' FEM_DIMENSION_UTIL_PKG.get_dim_attr_id_ver_id'
2436                     ||' to get CAL_PERIOD_END_DATE attribute'
2437                     ||' information failed with return code: '||v_return_code);
2438     END IF;
2439     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2440   END IF;
2441 
2442   SELECT date_assign_value
2443   INTO v_cal_per_end_date
2444   FROM fem_cal_periods_attr
2445   WHERE attribute_id  = v_dim_attr_id
2446   AND version_id    = v_dim_attr_ver_id
2447   AND cal_period_id = p_cal_period_id;
2448 
2449   IF v_cal_per_end_date IS NULL THEN
2450     IF FND_LOG.level_unexpected >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
2451       FEM_ENGINES_PKG.TECH_MESSAGE(
2452         p_severity => FND_LOG.level_unexpected,
2453         p_module   => C_MODULE,
2454         p_msg_text => 'Calendar Period End Date does not exist for this'
2455                     ||' calendar period: '||p_cal_period_id);
2456     END IF;
2457     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2458   END IF;
2459 
2460   IF FND_LOG.level_statement >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
2461     FEM_ENGINES_PKG.Tech_Message(
2462       p_severity => FND_LOG.level_statement,
2463       p_module   => C_MODULE,
2464       p_msg_text => 'The Calendar Period End Date is '
2465          ||FND_DATE.date_to_displayDT(v_cal_per_end_date));
2466   END IF;
2467 
2468 
2469   --
2470   -- Find the amount column for the table.
2471   --
2472 
2473   -- For Ledger tables, the amount column is always XTD_BALANCE_F.
2474   -- For Account/Transaction tables, the amount column is stored in
2475   -- FEM_ALLOC_BR_FORMULA.column_name
2476   IF p_map_table_type = G_LEDGER_TYPE THEN
2477 
2478     v_amount_column := G_LEDGER_AMOUNT_COL;
2479 
2480   ELSIF p_map_table_type = G_ACCT_TRANS_TYPE THEN
2481 
2482     SELECT f.column_name
2483     INTO v_amount_column
2484     FROM fem_alloc_br_formula f, fem_function_cd_mapping m
2485     WHERE f.object_definition_id = p_map_obj_def_id
2486     AND f.function_cd = m.function_cd
2487     AND m.preview_row_group = p_preview_row_group;
2488 
2489     IF v_amount_column IS NULL THEN
2490       IF FND_LOG.level_unexpected >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
2491         FEM_ENGINES_PKG.TECH_MESSAGE(
2492           p_severity => FND_LOG.level_unexpected,
2493           p_module   => C_MODULE,
2494           p_msg_text => 'Amount column is null for this preview group: '
2495                       ||p_preview_row_group);
2496       END IF;
2497       RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2498     END IF;
2499 
2500   ELSE
2501 
2502     IF FND_LOG.level_unexpected >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
2503       FEM_ENGINES_PKG.TECH_MESSAGE(
2504         p_severity => FND_LOG.level_unexpected,
2505         p_module   => C_MODULE,
2506         p_msg_text => 'Unexpected table classification type: '
2507                     ||p_map_table_type);
2508     END IF;
2509     RAISE FND_API.G_EXC_UNEXPECTED_ERROR;
2510 
2511   END IF; -- IF p_map_table_type = G_LEDGER_TYPE THEN
2512 
2513   --
2514   -- Sum amount column, grouped by currency
2515   --
2516   v_sql := 'SELECT SUM('||v_amount_column||'), currency_code'
2517         ||' FROM '||p_temp_table_name
2518         ||' GROUP BY currency_code';
2519 
2520   IF FND_LOG.level_statement >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
2521     FEM_ENGINES_PKG.TECH_MESSAGE(
2522       p_severity => FND_LOG.level_statement,
2523       p_module   => C_MODULE,
2524       p_msg_text => 'Preview amount SQL = '||v_sql);
2525   END IF;
2526 
2527   -- Initialize amount
2528   x_preview_amount_total := 0;
2529 
2530   OPEN amount_cv FOR v_sql;
2531 
2532   LOOP
2533 
2534     FETCH amount_cv INTO v_amount, v_amount_currency;
2535     EXIT WHEN amount_cv%NOTFOUND;
2536 
2537     -- If the amount is NULL for some reason, take that to mean zero.
2538     IF v_amount IS NULL THEN
2539       v_amount := 0;
2540     END IF;
2541 
2542     BEGIN
2543       GL_CURRENCY_API.Convert_Closest_Amount(
2544 	x_from_currency	     => v_amount_currency,
2545 	x_to_currency        => x_functional_currency,
2546 	x_conversion_date    => v_cal_per_end_date,
2547 	x_conversion_type    => 'CORPORATE',
2548 	x_user_rate          => null,
2549 	x_amount             => v_amount,
2550 	x_max_roll_days	     => 730, -- based on hardcoded value in CCE
2551 	x_converted_amount   => v_conv_amount,
2552 	x_denominator        => v_denom,
2553 	x_numerator  	     => v_numer,
2554 	x_rate		     => v_rate);
2555     EXCEPTION
2556       -- If there are any issues getting the rate,
2557       -- do no conversion and push a warning message in the message stack.
2558       WHEN others THEN
2559         FEM_ENGINES_PKG.PUT_MESSAGE(
2560           p_app_name     => 'FEM',
2561           p_msg_name     => 'NO_XLATE_RATE_FOUND',
2562           p_token1       => 'FROM_CURRENCY',
2563           p_value1       => v_amount_currency,
2564           p_token2       => 'TO_CURRENCY',
2565           p_value2       => x_functional_currency);
2566 
2567         v_conv_amount := v_amount;
2568     END;
2569 
2570     x_preview_amount_total := x_preview_amount_total + v_conv_amount;
2571 
2572   END LOOP;
2573 
2574   IF FND_LOG.level_procedure >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
2575     FEM_ENGINES_PKG.TECH_MESSAGE(
2576       p_severity => FND_LOG.level_procedure,
2577       p_module   => C_MODULE,
2578       p_msg_text => 'End Procedure');
2579   END IF;
2580 --
2581 END GetPreviewAmount;
2582 -------------------------------------------------------------------------------
2583 
2584 -------------------------------------------------------------------------------
2585 --
2586 -- PROCEDURE
2587 --   GetPreviewRowCount
2588 --
2589 -- DESCRIPTION
2590 --   Gets the row count for a Preview Row Group.  Instead of passing in
2591 --   the row group, pass in the temporary table associated with the
2592 --   row group.  This way, this API just needs to perform a SELECT count(*)
2593 --   against it to obtain the row count.
2594 --   No additional WHERE clause is needed because whatever is in the
2595 --   temporary table is what is part of the Preview execution.
2596 --
2597 --   Caveat: For output data (debit/credit), if the table is an
2598 --   account or transaction table, this API needs to first clear out
2599 --   all rows that the CCE did not update as part of its processing.
2600 --   The reason this is needed is because initially, when the output
2601 --   temporary tables were created (by the Pre_Process procedure),
2602 --   the initial data populated was most likely more than what CCE
2603 --   was going to write out to (actually, update).  It was done to
2604 --   simplify the logic in the Pre_Process procedure.  Without that
2605 --   simplification, the Pre_Process procedure would need to basically
2606 --   implement the logic in CCE to determine exactly which rows CCE
2607 --   was going to update --- way too big a task.
2608 --
2609 -------------------------------------------------------------------------------
2610 PROCEDURE GetPreviewRowCount(
2611   p_temp_table_name         IN VARCHAR2,
2612   x_preview_row_count       OUT NOCOPY NUMBER
2613 )
2614 -------------------------------------------------------------------------------
2615 IS
2616 --
2617   C_MODULE            CONSTANT FND_LOG_MESSAGES.module%TYPE :=
2618      'fem.plsql.fem_mapping_preview_util_pkg.GetPreviewRowCount';
2619   v_sql               VARCHAR2(4000);
2620 --
2621 BEGIN
2622 --
2623   IF FND_LOG.level_procedure >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
2624     FEM_ENGINES_PKG.TECH_MESSAGE(
2625       p_severity => FND_LOG.level_procedure,
2626       p_module   => C_MODULE,
2627       p_msg_text => 'Begin Procedure');
2628   END IF;
2629 
2630   -- Get row count
2631   v_sql := 'SELECT count(*) FROM '||p_temp_table_name;
2632 
2633   IF FND_LOG.level_statement >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
2634     FEM_ENGINES_PKG.TECH_MESSAGE(
2635       p_severity => FND_LOG.level_statement,
2636       p_module   => C_MODULE,
2637       p_msg_text => 'Preview Row Count SQL = '||v_sql);
2638   END IF;
2639 
2640   EXECUTE IMMEDIATE v_sql INTO x_preview_row_count;
2641 
2642   IF FND_LOG.level_procedure >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
2643     FEM_ENGINES_PKG.TECH_MESSAGE(
2644       p_severity => FND_LOG.level_procedure,
2645       p_module   => C_MODULE,
2646       p_msg_text => 'End Procedure');
2647   END IF;
2648 --
2649 END GetPreviewRowCount;
2650 -------------------------------------------------------------------------------
2651 
2652 -------------------------------------------------------------------------------
2653 --
2654 -- PROCEDURE
2655 --   CleanOutputTable
2656 --
2657 -- DESCRIPTION
2658 --   If the output table is an account or transaction table, this procedure
2659 --   needs to first clear out all rows that the CCE did not update as
2660 --   part of its processing.
2661 --
2662 --   The reason this is needed is initially, when the output
2663 --   temporary tables were created (by the Pre_Process procedure),
2664 --   the initial data populated was most likely more than what CCE
2665 --   was going to write out to (actually, update).  It was done to
2666 --   simplify the logic in the Pre_Process procedure.  Without that
2667 --   simplification, the Pre_Process procedure would need to basically
2668 --   implement the logic in CCE to determine exactly which rows CCE
2669 --   was going to update --- way too big a task.
2670 --
2671 -------------------------------------------------------------------------------
2672 PROCEDURE CleanOutputTable(
2673   p_temp_table_name         IN VARCHAR2,
2674   p_fact_table_name         IN VARCHAR2,
2675   p_map_table_type          IN VARCHAR2,
2676   p_preview_row_group       IN VARCHAR2,
2677   p_preview_obj_id          IN NUMBER,
2678   p_request_id              IN NUMBER
2679 )
2680 -------------------------------------------------------------------------------
2681 IS
2682 --
2683   C_MODULE            CONSTANT FND_LOG_MESSAGES.module%TYPE :=
2684      'fem.plsql.fem_mapping_preview_util_pkg.CleanOutputTable';
2685   v_sql               VARCHAR2(4000);
2686   v_map_table_type    VARCHAR2(30);
2687 --
2688 BEGIN
2689 --
2690   IF FND_LOG.level_procedure >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
2691     FEM_ENGINES_PKG.TECH_MESSAGE(
2692       p_severity => FND_LOG.level_procedure,
2693       p_module   => C_MODULE,
2694       p_msg_text => 'Begin Procedure');
2695   END IF;
2696 
2697   -- If this is an output table and account/transaction table,
2698   -- delete data from the temporary table that the CCE did not process.
2699   IF ((p_preview_row_group IN (G_DEBIT, G_CREDIT)) AND
2700       (p_map_table_type = G_ACCT_TRANS_TYPE)) THEN
2701 
2702     v_sql := 'DELETE FROM '||p_temp_table_name
2703           ||' WHERE last_updated_by_request_id <> :1'
2704           ||' AND last_updated_by_object_id <> :2';
2705 
2706     IF FND_LOG.level_statement >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
2707       FEM_ENGINES_PKG.TECH_MESSAGE(
2708         p_severity => FND_LOG.level_statement,
2709         p_module   => C_MODULE,
2710         p_msg_text => 'Delete unprocessed data SQL = '||v_sql);
2711     END IF;
2712 
2713     EXECUTE IMMEDIATE v_sql USING p_request_id, p_preview_obj_id;
2714 
2715   END IF;
2716 
2717   IF FND_LOG.level_procedure >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
2718     FEM_ENGINES_PKG.TECH_MESSAGE(
2719       p_severity => FND_LOG.level_procedure,
2720       p_module   => C_MODULE,
2721       p_msg_text => 'End Procedure');
2722   END IF;
2723 --
2724 END CleanOutputTable;
2725 -------------------------------------------------------------------------------
2726 
2727 -------------------------------------------------------------------------------
2728 --
2729 -- PROCEDURE
2730 --   PopulateDimensionNames
2731 --
2732 -- DESCRIPTION
2733 --   The temporary tables contain not just the dimension id/code columns
2734 --   but also the dimension name columns for each of those dimension
2735 --   id/code columns.  After CCE has gone through processing (and
2736 --   we have cleaned out the output tables via CleanOutputTable),
2737 --   the temporary tables are close to its final state.  All that needs
2738 --   to be done is to populate those empty dimension name columns.
2739 --
2740 --   This procedure populates those columns by issue one large update
2741 --   statement that looks like this:
2742 --    UPDATE <temporary_table> t
2743 --    SET
2744 --     t.<dim1_name_column> =
2745 --      Nvl((SELECT d1.<dim_name>
2746 --           FROM <dim1_vl_view> d1
2747 --           WHERE d1.<dim_member_column> = t.<dim1_member_column>
2748 --           -- only needed for VSR dimensions
2749 --           AND d1.value_set_id = <dim1_value_set_id>),
2750 --          DECODE(t.<dim1_member_column>,NULL,NULL,
2751 --            REPLACE('Dimension name missing: FEMDIMNAMETOKEN',
2752 --                    'FEMDIMNAMETOKEN', t.<dim1_member_column>))
2753 --          ),
2754 --     t.<dim2_name_column> =
2755 --      Nvl((SELECT d2.<dim_name>
2756 --           FROM <dim2_vl_view> d2
2757 --           WHERE d2.<dim_member_column> = t.<dim2_member_column>),
2758 --          DECODE(t.<dim2_member_column>,NULL,NULL,
2759 --            REPLACE('Dimension name missing: FEMDIMNAMETOKEN',
2760 --                    'FEMDIMNAMETOKEN', t.<dim2_member_column>))
2761 --          ),
2762 --     <etc>
2763 --
2764 -------------------------------------------------------------------------------
2765 PROCEDURE PopulateDimensionNames(
2766   p_preview_obj_def_id      IN NUMBER,
2767   p_preview_row_group       IN VARCHAR2,
2768   p_temp_table_name         IN VARCHAR2,
2769   p_fact_table_name         IN VARCHAR2,
2770   p_ledger_id               IN NUMBER
2771 )
2772 -------------------------------------------------------------------------------
2773 IS
2774 --
2775   C_MODULE                  CONSTANT FND_LOG_MESSAGES.module%TYPE :=
2776      'fem.plsql.fem_mapping_preview_util_pkg.PopulateDimensionNames';
2777   C_TOKEN                   CONSTANT VARCHAR2(20) := 'FEMDIMNAMETOKEN';
2778   v_return_status           VARCHAR2(1);
2779   v_msg_count               NUMBER;
2780   v_msg_data                VARCHAR2(4000);
2781   v_global_vs_combo_id      FEM_GLOBAL_VS_COMBO_DEFS.global_vs_combo_id%TYPE;
2782   v_warning                 FEM_DIM_TEMPLATE.template_dim_name%TYPE;
2783   v_sql                     VARCHAR2(32767);
2784 --
2785   CURSOR c_dim_info (cv_preview_obj_def_id NUMBER,
2786                      cv_preview_row_group VARCHAR2,
2787                      cv_fact_table VARCHAR2,
2788                      cv_global_vs_combo_id NUMBER) IS
2789     SELECT pm.dim_member_column_name, pm.dim_name_column_name,
2790            xd.member_name_col, xd.member_vl_object_name, xd.member_col,
2791            gv.value_set_id
2792     FROM fem_alloc_preview_maps pm, fem_tab_columns_v tc,
2793          fem_xdim_dimensions xd, fem_global_vs_combo_defs gv
2794     WHERE pm.preview_obj_def_id = cv_preview_obj_def_id
2795       AND pm.preview_row_group = cv_preview_row_group
2796       AND pm.dim_member_column_name = tc.column_name
2797       AND tc.table_name = cv_fact_table
2798       AND xd.dimension_id  = tc.dimension_id
2799       AND xd.dimension_id  = gv.dimension_id (+)
2800       AND gv.global_vs_combo_id (+) = cv_global_vs_combo_id;
2801 --
2802 BEGIN
2803 --
2804   IF FND_LOG.level_procedure >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
2805     FEM_ENGINES_PKG.TECH_MESSAGE(
2806       p_severity => FND_LOG.level_procedure,
2807       p_module   => C_MODULE,
2808       p_msg_text => 'Begin Procedure');
2809   END IF;
2810 
2811   -- lookup the global value set combination id tied to the ledger
2812   v_global_vs_combo_id := FEM_DIMENSION_UTIL_PKG.global_vs_combo_id
2813                            (p_encoded        => FND_API.G_FALSE,
2814                             x_return_status  => v_return_status,
2815                             x_msg_count      => v_msg_count,
2816                             x_msg_data       => v_msg_data,
2817                             p_ledger_id      => p_ledger_id);
2818 
2819   IF v_return_status <> FND_API.G_RET_STS_SUCCESS THEN
2820     IF FND_LOG.level_statement >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
2821       FEM_ENGINES_PKG.TECH_MESSAGE(
2822         p_severity => FND_LOG.level_statement,
2823         p_module   => C_MODULE,
2824          p_msg_text => 'INTERNAL ERROR: Call to'
2825                      ||' FEM_DIMENSION_UTIL_PKG.global_vs_combo_id'
2826                      ||' failed with return status: '||v_return_status);
2827     END IF;
2828   END IF;
2829 
2830   -- Get the text to store in the dimension name column if
2831   -- no dimension name was found.
2832   FND_MESSAGE.set_name('FEM','FEM_PREVIEW_DIM_NAME_MISSING');
2833   v_warning := FND_MESSAGE.get;
2834 
2835   -- Start building the repeating section of the UPDATE sql to
2836   -- popluate the dimension names.
2837   FOR dim IN c_dim_info(cv_preview_obj_def_id => p_preview_obj_def_id,
2838                         cv_preview_row_group  => p_preview_row_group,
2839                         cv_fact_table         => p_fact_table_name,
2840                         cv_global_vs_combo_id => v_global_vs_combo_id) LOOP
2841 
2842     -- Add the comma separate between columns being updated if this is
2843     -- not the first column being updated.
2844     IF v_sql IS NOT NULL THEN
2845       v_sql := v_sql||',';
2846     END IF;
2847 
2848     v_sql := v_sql||G_FACT_ALIAS||'.'||dim.dim_name_column_name||'='
2849            ||'NVL((SELECT '||G_DIM_ALIAS||'.'||dim.member_name_col
2850            ||' FROM '||dim.member_vl_object_name||' '||G_DIM_ALIAS
2851            ||' WHERE '||G_DIM_ALIAS||'.'||dim.member_col||'='
2852            ||G_FACT_ALIAS||'.'||dim.dim_member_column_name;
2853 
2854     -- Add the value set filter if it applies to the dimension
2855     IF dim.value_set_id IS NOT NULL THEN
2856       v_sql := v_sql||' AND '||G_DIM_ALIAS||'.value_set_id='||dim.value_set_id;
2857     END IF;
2858 
2859     v_sql := v_sql||'),'
2860            ||'DECODE('||G_FACT_ALIAS||'.'||dim.dim_member_column_name
2861            ||',NULL,NULL,'
2862            ||'REPLACE('''||v_warning||''','''||C_TOKEN||''','
2863            ||G_FACT_ALIAS||'.'||dim.dim_member_column_name||')))';
2864 
2865   END LOOP;
2866 
2867   -- Only run SQL if there are dimensions to be updated
2868   IF v_sql IS NOT NULL THEN
2869 
2870     -- Add the beginning part of the UPDATE sql to popluate the dimension names
2871     v_sql := 'UPDATE '||p_temp_table_name||' '||G_FACT_ALIAS||' SET '||v_sql;
2872 
2873     IF FND_LOG.level_statement >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
2874       FEM_ENGINES_PKG.TECH_MESSAGE(
2875         p_severity => FND_LOG.level_statement,
2876         p_module   => C_MODULE,
2877         p_msg_text => v_sql);
2878     END IF;
2879 
2880     EXECUTE IMMEDIATE v_sql;
2881 
2882   END IF;
2883 
2884   IF FND_LOG.level_procedure >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
2885     FEM_ENGINES_PKG.TECH_MESSAGE(
2886       p_severity => FND_LOG.level_procedure,
2887       p_module   => C_MODULE,
2888       p_msg_text => 'End Procedure');
2889   END IF;
2890 --
2891 END PopulateDimensionNames;
2892 -------------------------------------------------------------------------------
2893 
2894 -------------------------------------------------------------------------------
2895 --
2896 -- PROCEDURE
2897 --   GetByDimParams
2898 --
2899 -- DESCRIPTION
2900 --   Get the three By Dimension specific parameters that needs to
2901 --   passed into FEM_ASSEMBLER_PREDICATE_API.Generate_Assembler_Predicate.
2902 --
2903 --   If mapping rule type is not By Dimension or preview group is not Source,
2904 --   set all parameters to NULL.
2905 --
2906 --   If mapping rule type is By Dimension and preview group is Source,
2907 --   then get the parameter values from these tables:
2908 --   FEM_ALLOC_BR_DIMENSIONS, FEM_TAB_COLUMNS_B, and FEM_XDIM_DIMENSIONS
2909 --
2910 -------------------------------------------------------------------------------
2911 PROCEDURE GetByDimParams(
2912   p_preview_obj_def_id      IN NUMBER,
2913   p_preview_row_group       IN VARCHAR2,
2914   p_map_obj_def_id          IN NUMBER,
2915   p_map_rule_type           IN VARCHAR2,
2916   p_fact_table_name         IN VARCHAR2,
2917   x_by_dimension_column     OUT NOCOPY VARCHAR2,
2918   x_by_dimension_id         OUT NOCOPY VARCHAR2,
2919   x_by_dimension_value      OUT NOCOPY VARCHAR2
2920 )
2921 -------------------------------------------------------------------------------
2922 IS
2923 --
2924   C_MODULE                  CONSTANT FND_LOG_MESSAGES.module%TYPE :=
2925      'fem.plsql.fem_mapping_preview_util_pkg.GetByDimParams';
2926   C_BYDIM_FUNCIONCD         CONSTANT VARCHAR2(10) := 'LEAFFUNC';
2927 --
2928 BEGIN
2929 --
2930   IF FND_LOG.level_procedure >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
2931     FEM_ENGINES_PKG.TECH_MESSAGE(
2932       p_severity => FND_LOG.level_procedure,
2933       p_module   => C_MODULE,
2934       p_msg_text => 'Begin Procedure');
2935   END IF;
2936 
2937   -- If mapping rule type is By Dimensions, get by dim param values.
2938   -- Else, set them to null.
2939   IF ((p_map_rule_type = G_BY_DIMENSION) AND
2940       (p_preview_row_group = G_SOURCE)) THEN
2941     SELECT abd.alloc_dim_col_name, xd.dimension_id,
2942            decode(xd.member_data_type_code,'NUMBER',abd.dimension_value,
2943                                            abd.dimension_value_char)
2944     INTO x_by_dimension_column, x_by_dimension_id, x_by_dimension_value
2945     FROM fem_alloc_br_dimensions abd, fem_tab_columns_b tc,
2946          fem_xdim_dimensions xd
2947     WHERE abd.object_definition_id = p_map_obj_def_id
2948     AND abd.function_cd = C_BYDIM_FUNCIONCD
2949     AND tc.table_name = p_fact_table_name
2950     AND abd.alloc_dim_col_name = tc.column_name
2951     AND tc.dimension_id = xd.dimension_id;
2952   ELSE
2953     x_by_dimension_column := NULL;
2954     x_by_dimension_id     := NULL;
2955     x_by_dimension_value  := NULL;
2956   END IF;
2957 
2958   IF FND_LOG.level_procedure >= FND_LOG.G_CURRENT_RUNTIME_LEVEL THEN
2959     FEM_ENGINES_PKG.TECH_MESSAGE(
2960       p_severity => FND_LOG.level_procedure,
2961       p_module   => C_MODULE,
2962       p_msg_text => 'End Procedure');
2963   END IF;
2964 --
2965 END GetByDimParams;
2966 -------------------------------------------------------------------------------
2967 
2968 -------------------------------------------------------------------------------
2969 
2970 END FEM_MAPPING_PREVIEW_UTIL_PKG;